Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
10 years ago

Avalon 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

14 Replies