Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Altera_Forum
Honored Contributor I
802 Views

Access custum module using IOWR

Hello, I am having trouble accessing to my module using niosII IOWR function.:cry: 

my logic is below: 

== 

module test_module( 

input clk, input wren, input[15:0] indata, output reg[15:0] outtdata); 

always @ (posedge clk) begin 

if(wren == 1) outdata = indata; 

end 

initial begin 

outdata = 123; 

end 

endmodule 

== 

my niosii software is below: 

== 

... 

test = IORD(TEST_MODULE_0_BASE, 0); // (1) 

IOWR(TEST_MODULE_0_BASE, 0, 456); 

test = IORD(TEST_MODULE_0_BASE, 0); // (2) 

== 

I can read "123" at (1), but always get "0" at (2) instead of "456". 

My module is an Avalon Memory Mapped Slave, 

wren is "write", indata is "writedata", outdata is "readdata" for signal type 

in SOPC Builder. 

Any suggestion is appreciated!
0 Kudos
9 Replies
Altera_Forum
Honored Contributor I
59 Views

You need to look at the addresses and 'byte enables', the 32bit write of 456 will generate two 16bit writes to your slave. Your slave will be latching the second write. 

If you write 0x12345678 you should read back 0x1234. 

 

Best to make your slave 32bits - ignore the high bits on writes and return 0 to reads.
Altera_Forum
Honored Contributor I
59 Views

Thanks DSL!! 

I don't quite exactly understand what's going on now, 

but like you said, 

I wrote 0x12345678 and got 0x1234.  

I will check more on the documents. thanks!
Altera_Forum
Honored Contributor I
59 Views

Look up 'bus width adapter' ...

Altera_Forum
Honored Contributor I
59 Views

Thanks DSL! I saw your other posts. 

I guess in my situation, this 'bus width adapter' is added automatically 

in my SOPC, as an result, generates 2 cycles into my 16bit slave. 

I will choose to make my slave 32bit.
Altera_Forum
Honored Contributor I
59 Views

I would add byte enables to your slave port and register each byte lane separately. This means more typing but at least your component will work properly with masters of different widths and endianness. I usually do that with something like this: 

always @ (posedge reset or posedge clk) begin if (reset) begin my_register <= 0; end else begin if (byte_en == 1) my_register <= writedata; if (byte_en == 1) my_register <= writedata; if (byte_en == 1) my_register <= writedata; if (byte_en == 1) my_register <= writedata; end end assign byte_en = (write_en == 1) & (byte_enable == 1) & (address == whatever_location_this_decodes); assign byte_en = (write_en == 1) & (byte_enable == 1) & (address == whatever_location_this_decodes); assign byte_en = (write_en == 1) & (byte_enable == 1) & (address == whatever_location_this_decodes); assign byte_en = (write_en == 1) & (byte_enable == 1) & (address == whatever_location_this_decodes);  

 

Doing this you can write to each byte lane independently so you will not be limited to 32-bit masters. If you need all your data to be presented to the rest of the logic in parallel then implementing a shadow register will do the trick (i.e. when byte_en[3] is high then you transfer my_register to a 32-bit shadow register all in one shot). You could also make registers like these little modules if you need to duplicate them multiple times.
Altera_Forum
Honored Contributor I
59 Views

Thanks for the idea, BadOmen! 

Sounds like 'byteenable' would make the slave module much more flexible. 

 

However, my question was much more simple.. 

I just found out that using IOWR_16DIRECT, IORD_16DIRECT would 

solve my problem.
Altera_Forum
Honored Contributor I
59 Views

I forget if Nios II really performs a 16 bit access with IORD_16DIRECT. I know a while back it always asserted all four byte enables no matter the width of the read and it just ignored the unwanted byte lanes. So if you use IORD_16DIRECT with your component it may see two 16-bit accesses and the upper 16 bits get tossed away when the 32-bit data returns to the CPU. IOWR_16DIRECT will only issue the upper or lower two byte enabled depending on the alignment of the access. So those might solve the problem (should for writes at least) I think it would be easier if you just made your slave match the CPU data width (32-bit). The upper 16 bits you can just leave disconnected on the write data and for the read data you can ground them out, shove some random 16-bit value and ignore them in software, etc... 

 

I always use the 'DIRECT' macros just as a preference thing. One thing to keep in mind is that the offset you pass to the macro is a byte offset and not a word offset like it is for IORD and IOWR. So if you wanted to use IOWR_16DIRECT to write to a bunch of registers you would use offsets 0, 2, 4, 6, 8, etc... This is one of the reasons why I stick to the 'DIRECT' macros, I've seen others mix and match IORD/IOWR with the DIRECT macros and ended up messing up the offsets between the two sets of macros.
Altera_Forum
Honored Contributor I
59 Views

Thanks, BadOmen! 

 

> One thing to keep in mind is that the offset you pass 

> to the macro is a byte offset and not a word offset 

> like it is for IORD and IOWR 

 

Yes, I found that out while debugging my slave.. 

I recently added 'address' signal, and also found out that  

offset gets converted when I use 'DIRECT' macros or(and?) non 32bit slave. 

 

I guess using IORD,WR and 32bit slave in pair is the simplest way in my case.
Altera_Forum
Honored Contributor I
59 Views

The nios is certainly documented as always doing 32 bit reads, everything I've seen posted here is consistent with it.

Reply