I am trying to figure out how to use the block RAM on my iCE40HX-8K Breakout Board. I would like to access it in a 512x8 configuration, which as far as I can tell from the documentation is supported by project IceStorm, but I haven't been able to get it to work like I expected.
If I understand correctly, initializing an SB_RAM40_4K primitive with the READ_MODE parameter set to 1 should set the block up in 512x8 read mode, which uses a 9 bit read address, and reads 8 bits of data at each address.
Here is the simplest example I could think of. It sets up an SB_RAM40_4K with some pre-initialized memory and reads straight to the pins of the on-board LED's.
hx8kboard.pcf
set_io leds[0] B5
set_io leds[1] B4
set_io leds[2] A2
set_io leds[3] A1
set_io leds[4] C5
set_io leds[5] C4
set_io leds[6] B3
set_io leds[7] C3
set_io clk J3
top.v
module top (
output [7:0] leds,
input clk
);
//reg [8:0] raddr = 8'd0;
reg [8:0] raddr = 8'd1;
SB_RAM40_4K #(
.INIT_0(256'h00000000000000000000000000000000000000000000000000000000_44_33_22_11),
.WRITE_MODE(1),
.READ_MODE(1)
) ram40_4k_512x8 (
.RDATA(leds),
.RADDR(raddr),
.RCLK(clk),
.RCLKE(1'b1),
.RE(1'b1),
.WADDR(8'b0),
.WCLK(1'b0),
.WCLKE(1'b0),
.WDATA(8'b0),
.WE(1'b0)
);
endmodule
LED output when raddr == 0
\|/ \|/
O O O O O O O O
LED output when raddr == 1
\|/ \|/ \|/ \|/
O O O O O O O O
I would think that address 1 in 512x8 mode would be the second 8 bits from RAM, which is 8'h22
or 8'b0010010
. Instead I get 8'h33
or 8'b00110011
. After a little experimentation, this seems to be the lower 8 bits of a 16 bit read.
I'm not sure where I went wrong. Any help understanding what's going on here would be appreciated. Thanks!
This question is not really about Yosys or Project IceStorm. The format used for the
SB_RAM40_4K
INIT_*
parameters is the same for the IceStorm flow and the Lattice iCEcube2 flow. However, Lattice has done a very very bad job at documenting this format. Otherwise I'd just point you to the right Lattice document.. :)You are interested in the 512x8 mode. First you need to know that in 512x8 mode only the even bits of
.RDATA()
and.WDATA()
are used (not the 8 LSB bits, as your code suggests!).The data in
.INIT_*
is stored as 16 16-bit words per parameter. The lowest 16-bit word in.INIT_0()
contains the 8-bit word at addr 0 in its even bits and the 8-bit word at addr 256 in its odd bits.The next 16-bit word in
.INIT_0()
contains words 1 and 257. The lowest 16-bits in.INIT_1()
contain words 16 and 272, and so forth.The easiest way to investigate this kind of stuff is probably to either read the
SB_RAM40_4K
simulation model in/usr/local/share/yosys/ice40/cells_sim.v
, or simply let Yosys infer the memory and observe what yosys does. For example the following design:Will produce the following output when run through
yosys -p 'synth_ice40; write_verilog' test.v
:(Scroll all the way to the right to see the initialization pattern generated for the
mem[0] = 255
initialization.)