Altera_Forum
Honored Contributor
10 years agoAvalon MM slave custom component: register reading/writing issue
Hi all!
I'm having some trouble designing an Avalon MM slave component. I’m new with FPGA and probably is something really easy to fix. I’m using Quartus prime (15.1) and a Max10 FPGA development kit. I’d like to understand the right way to implement a custom Avalon MM salve component and to integrate it into Qsys to read/write registers from NIOS processor. At moment I can write and read the registers from the processor but something strange is happening into the memory. The component is using 8 bits address and 4 test registers LED0, LED1, LED2, LED3. When I try to write the registers with 4 different values it seems that the values are shifted by 1 location (a word) and the last value is written in all the rest of the memory space allocated to the component. The component address assigned in Qsys is 0x9400 and the picture attached shows the content of the memory in debug mode in Eclipse. Verilog code and C code are also attached. Does anybody have a good idea about a solution? Thanks Verilog component code: // testSlave.v `timescale 1 ps / 1 ps module testSlave ( input [7:0] avs_testSlave_address, // testslave.address input avs_testSlave_read, // .read output [31:0] avs_testSlave_readdata, // .readdata input avs_testSlave_write, // .write input [31:0] avs_testSlave_writedata, // .writedata output avs_testSlave_waitrequest, // .waitrequest input clock_testSlave_clk, // clock_testSlave.clk input reset_testSlave_reset // reset_testSlave.reset ); reg [31:0] LED0,LED1,LED2,LED3; reg [31:0] avs_testSlave_readdata_; assign avs_testSlave_readdata = avs_testSlave_readdata_; always @(posedge clock_testSlave_clk or posedge reset_testSlave_reset) begin //write if(reset_testSlave_reset == 1) //if(!reset_testSlave_reset) begin LED0 <= 0; LED1 <= 0; LED2 <= 0; LED3 <= 0; end else if(avs_testSlave_write) begin case(avs_testSlave_address) 0: begin LED0 <= avs_testSlave_writedata; end 1: begin LED1 <= avs_testSlave_writedata; end 2: begin LED2 <= avs_testSlave_writedata; end 3: begin LED3 <= avs_testSlave_writedata; end endcase end end always @(posedge clock_testSlave_clk or posedge reset_testSlave_reset) begin //read if (reset_testSlave_reset == 1) begin avs_testSlave_readdata_ <= 0; end else if(avs_testSlave_read) begin case(avs_testSlave_address) 0: begin avs_testSlave_readdata_ <= LED0; end 1: begin avs_testSlave_readdata_ <= LED1; end 2: begin avs_testSlave_readdata_ <= LED2; end 3: begin avs_testSlave_readdata_ <= LED3; end endcase end end endmodule Nios C code: while(1) { if(alt_timestamp() > 50000000) { printf("* %u \n", alt_timestamp()); printf("* %u \n", counter); counter++; alt_timestamp_start(); if(counter %2 == 0) { testValue = 0x0A; IOWR(TESTSLAVE_0_BASE, 0, testValue); printf("\n write0 %u \n", testValue); testValue = 0x0B; IOWR(TESTSLAVE_0_BASE, 1, testValue); printf("\n write1 %u \n", testValue); testValue = 0x0C; IOWR(TESTSLAVE_0_BASE, 2, testValue); printf("\n write2 %u \n", testValue); testValue = 0x0D; IOWR(TESTSLAVE_0_BASE, 3, testValue); printf("\n write3 %u \n", testValue); } else { ledRegValue0 = IORD(TESTSLAVE_0_BASE, 0); printf("\n read led0 %u \n", (ledRegValue0)); ledRegValue1 = IORD(TESTSLAVE_0_BASE, 1); printf("\n read led1 %u \n", (ledRegValue1)); ledRegValue2 = IORD(TESTSLAVE_0_BASE, 2); printf("\n read led2 %u \n", (ledRegValue2)); ledRegValue3 = IORD(TESTSLAVE_0_BASE, 3); printf("\n read led3 %u \n", (ledRegValue3)); } } } http://www.alteraforum.com/forum/attachment.php?attachmentid=11459&stc=1