Altera_Forum
Honored Contributor
11 years agoSimple interfacing between Avalon MM Slave and ARM HPS
Hi all,
I'm trying to create a simple example of a master-slave communication between the onboard HPS (running Linux) and the FPGA fabric using a Cyclone V. The method I've followed so far is this: Firmware: - instantiate the HPS in Qsys with nothing but a LWH2F bridge - write a simple verilog module (flash_led.v) as an Avalon MM Slave (i.e. it has read, readdata, write, and writedata signals) and connect it to the HPS in Qsys - connect everything in a simple top-level verilog module and set the LED output pins to display whatever shows up on the writedata signal Software: - write a simple c program that deals with memory mapping via:int fd = open("/dev/mem", (O_RDWR|O_SYNC));
void* slave_base = mmap(NULL, ALT_LWFPGASLVS_SPAN, (PROT_READ|PROT_WRITE), MAP_SHARED, fd, (off_t)ALT_LWFPGASLVS_ADDR); - also deal with writing to the slave peripheral via: volatile unsigned char* slave_addr = (unsigned char*)slave_base; // the offset of my flash_led component in Qsys is 0x0 so it can be ignored
*slave_addr = some_value; This works for writing to the slave module (I see the LEDs set correctly), but I'm unable to read from it when I try things like "read_value = *slave_addr;" I've seen a few examples online which use the alt_write_word() and alt_read_word() functions, but I haven't been able to get these to do anything for me thus far... Do I need to be doing more with my Verilog module? Is the "address" signal necessary when reading and writing from an Avalon MM slave? I suspect I may have a conceptual misunderstanding of this whole bridging process... Can anyone help me out or point me in the right direction? For reference, here's the simple flash_led.v verilog module I've been using: module flash_led
(
input clock,
input reset_n,
input write,
input writedata,
input read,
output readdata,
output led
);
reg led_internal;
reg stupidconstant = 8'b01010101;
assign led = led_internal;
assign readdata = stupidconstant;
always @(posedge clock) begin
if (!reset_n)
led_internal <= 4'b0000;
else if (write) begin
led_internal <= writedata;
end
end
endmodule John