Memory Usage Guide For Ice 40 Devices
Memory Usage Guide For Ice 40 Devices
Memory Usage Guide For Ice 40 Devices
iCE40 Devices
June 2016 Technical Note TN1250
Introduction
This technical note discusses memory usage for the iCE40™ device family (iCE40 LP/HX, iCE40LM, iCE40 Ultra™,
iCE40 UltraLite™, iCE40 UltraPlus™). It is intended to be used as a guide to the high-speed synchronous RAM
Blocks and the iCE40 sysMEM™ Embedded Block RAM (EBR). The EBR is the embedded block RAM of the device,
each 4 Kbit in size.
The iCE40 device architecture provides resources for memory-intensive applications. Single-Port RAM, Dual-Port
RAM and FIFO can be constructed using the EBRs. The EBRs can be utilized by instantiating software primitives
as described later in this document. Apart from primitive instantiation, the iCECube2™ design software infers
generic codes as EBRs.
Figure 1 shows the placement of EBRs in a typical iCE40 device (does not represent true numbers of design ele-
ments).
sysMEM
Embedded Block
RAM (EBR)
sysCLOCK PLL
© 2016 Lattice Semiconductor Corp. All Lattice trademarks, registered trademarks, patents, and disclaimers are as listed at www.latticesemi.com/legal. All other brand
or product names are trademarks or registered trademarks of their respective holders. The specifications and information herein are subject to change without notice.
www.latticesemi.com 1 TN1250_1.5
Memory Usage Guide
for iCE40 Devices
WDATA[15:0] RDATA[15:0]
MASK[15:0]
WADDR[7:0] RADDR[7:0]
iCE40 sysMEM
Embedded Block RAM
WE RE
(256x16)
WCLKE RCLKE
WCLK RCLK
Using programmable logic resources, an EBR implements a variety of logic functions, each with configurable input
and output data widths.
As shown in Figure 2, an EBR has separate write and read ports, each with independent control signals. Table 1
lists the signals for both ports. Additionally, the write port has an active-low bit-line write-enable control; optionally
mask write operations on individual bits. By default, input and output data is 16 bits wide, although the data width is
configurable using programmable logic and, if needed, multiple EBRs.
The WCLK and RCLK inputs optionally connect to one of the following clock sources:
2
Memory Usage Guide
for iCE40 Devices
Signals
Table 1 lists the signal names, direction, and function of each connection to the EBR block.
3
Memory Usage Guide
for iCE40 Devices
Timing Diagram
Figure 3 shows the timing diagram for the EBR memory module.
WCLK
WE
tSUWE_EBR tHWE_EBR
WCLKE
tSUWCLKE_EBR tHWCLKE_EBR
tSUADDR_EBR tHADDR_EBR
tSUDATA_EBR tHDATA_EBR
RCLK
RE
tSURE_EBR tHRE_EBR
RCLKE
tSURCLKE_EBR tHRCLKE_EBR
tSUADDR_EBR tHADDR_EBR
tCO_EBR
1. Internal timing values are considered in the iCEcube2 software’s place and route.
4
Memory Usage Guide
for iCE40 Devices
Memory Initialization
sysMEM memories can be initialized as needed. The initialization can be achieved through HDL (Verilog or VHDL)
by specifying the initial values or through an initialization file (.mem file).
Refer to the iCEcube2 User Guide (under the Help menu) for more information on initializing memories. The Initial-
izing Inferred RAM section covers the process of initializing memory by providing initial values or using mem file.
the Memory Initializer section provides the DOS commands that can be used to initialize various memories using
.mem files.
Write Operations
By default, all EBR write operations are synchronized to the rising edge of WCLK although the clock is invertible as
shown in Figure 2.When the WCLKE signal is low, the clock to the EBR block is disabled, keeping the EBR in its
lowest power mode.
To write data into the EBR block, perform the following operations:
Read Operations
By default, all EBR read operations are synchronized to the rising edge of RCLK although the clock is invertible as
shown in Figure 2.
To read data from the EBR block, perform the following operations:
5
Memory Usage Guide
for iCE40 Devices
EBR Considerations
Read Data Register Undefined Immediately After Configuration
Unlike the flip-flops in the Programmable Logic Blocks and Programmable I/O pins, the RDATA port is not automat-
ically reset after configuration. Consequently, immediately following configuration and before the first valid Read
Data operation, the initial RDATA read value is undefined.
Low-Power Setting
To place an EBR block in its lowest power mode, keep WCLKE = 0 and RCLKE = 0. In other words, when not
actively using an EBR block, disable the clock inputs.
Table 2 lists the supported dual port synchronous RAM configurations, each of 4Kbits in size. The RAM blocks can
be directly instantiated in the top module and taken through the iCube2 software flow.
Block RAM
Block RAM Configuration WADDR Port WDATA Port RADDR Port RDATA Port MASK Port
Configuration and Size Size (Bits) Size (Bits) Size (Bits) Size (Bits) Size (Bits)
SB_RAM256x16
SB_RAM256x16NR
256 x 16 (4K) 8 [7:0] 16 [15:0] 8 [7:0] 16 [15:0] 16 [15:0]
SB_RAM256x16NW
SB_RAM256x16NRNW
SB_RAM512x8
SB_RAM512x8NR
512 x 8 (4K) 9 [8:0] 8 [7:0] 9 [8:0] 8 [7:0] No Mask Port
SB_RAM512x8NW
SB_RAM512x8NRNW
SB_RAM1024x4
SB_RAM1024x4NR
1024 x 4 (4K) 10 [9:0] 4 [3:0] 10 [9:0] 4 [3:0] No Mask Port
SB_RAM1024x4NW
SB_RAM1024x4NRNW
SB_RAM2048x2
SB_RAM2048x2NR
2048 x 2 (4K) 11 [10:0] 2 [1:0] 11 [10:0] 2 [1:0] No Mask Port
SB_RAM2048x2NW
SB_RAM2048x2NRNW
For iCE40 EBR primitives with a negative-edged read or write clock, the base primitive name is appended with a ‘N’
and a ‘R’ or ‘W’ depending on the clock that is affected (see Table 3 for the 256x16 RAM block configuration).
6
Memory Usage Guide
for iCE40 Devices
SB_RAM256x16
Figure 4. SB_RAM256x16 Primitive
SB_RAM256x16
WDATA[15:0] RDATA[15:0]
MASK[15:0]
WADDR[7:0] RADDR[7:0]
WE RE
WCLKE RCLKE
WCLK RCLK
Verilog Instantiation
SB_RAM256x16 ram256x16_inst (
.RDATA(RDATA_c[15:0]),
.RADDR(RADDR_c[7:0]),
.RCLK(RCLK_c),
.RCLKE(RCLKE_c),
.RE(RE_c),
.WADDR(WADDR_c[7:0]),
.WCLK(WCLK_c),
.WCLKE(WCLKE_c),
.WDATA(WDATA_c[15:0]),
.WE(WE_c),
.MASK(MASK_c[15:0])
);
defparam ram256x16_inst.INIT_0 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram256x16_inst.INIT_1 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram256x16_inst.INIT_2 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram256x16_inst.INIT_3 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram256x16_inst.INIT_4 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram256x16_inst.INIT_5 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram256x16_inst.INIT_6 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
7
Memory Usage Guide
for iCE40 Devices
defparam ram256x16_inst.INIT_7 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram256x16_inst.INIT_8 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram256x16_inst.INIT_9 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram256x16_inst.INIT_A =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram256x16_inst.INIT_B =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram256x16_inst.INIT_C =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram256x16_inst.INIT_D =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram256x16_inst.INIT_E =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram256x16_inst.INIT_F =
256'h0000000000000000000000000000000000000000000000000000000000000000;
VHDL Instantiation
ram256x16_inst : SB_RAM256x16
generic map (
INIT_0 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_4 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_5 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_6 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_7 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_8 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_9 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_F => X"0000000000000000000000000000000000000000000000000000000000000000"
)
port map (
RDATA => RDATA_c,
RADDR => RADDR_c,
RCLK => RCLK_c,
RCLKE => RCLKE_c,
RE => RE_c,
WADDR => WADDR_c,
WCLK=> WCLK_c,
WCLKE => WCLKE_c,
WDATA => WDATA_c,
MASK => MASK_c,
WE => WE_c
);
8
Memory Usage Guide
for iCE40 Devices
SB_RAM512x8
Figure 5. SB_RAM512x8 Primitive
SB_RAM512x8
WDATA[7:0] RDATA[7:0]
WADDR[8:0] RADDR[8:0]
WE RE
WCLKE RCLKE
WCLK RCLK
Verilog Instantiation
SB_RAM512x8 ram512X8_inst (
.RDATA(RDATA_c[7:0]),
.RADDR(RADDR_c[8:0]),
.RCLK(RCLK_c),
.RCLKE(RCLKE_c),
.RE(RE_c),
.WADDR(WADDR_c[8:0]),
.WCLK(WCLK_c),
.WCLKE(WCLKE_c),
.WDATA(WDATA_c[7:0]),
.WE(WE_c)
);
defparam ram512x8_inst.INIT_0 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram512x8_inst.INIT_1 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram512x8_inst.INIT_2 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram512x8_inst.INIT_3 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
9
Memory Usage Guide
for iCE40 Devices
defparam ram512x8_inst.INIT_4 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram512x8_inst.INIT_5 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram512x8_inst.INIT_6 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram512x8_inst.INIT_7 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram512x8_inst.INIT_8 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram512x8_inst.INIT_9 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram512x8_inst.INIT_A =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram512x8_inst.INIT_B =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram512x8_inst.INIT_C =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram512x8_inst.INIT_D =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram512x8_inst.INIT_E =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram512x8_inst.INIT_F =
256'h0000000000000000000000000000000000000000000000000000000000000000;
VHDL Instantiation
ram512x8_inst : SB_RAM512x8
generic map (
INIT_0 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_4 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_5 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_6 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_7 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_8 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_9 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_F => X"0000000000000000000000000000000000000000000000000000000000000000"
)
port map (
RDATA => RDATA_c,
RADDR => RADDR_c,
RCLK => RCLK_c,
RCLKE => RCLKE_c,
RE => RE_c,
WADDR => WADDR_c,
WCLK=> WCLK_c,
10
Memory Usage Guide
for iCE40 Devices
SB_RAM1024x4
Figure 6. SB_RAM1024x4 Primitive
SB_RAM1024x4
WDATA[3:0] RDATA[3:0]
WADDR[9:0] RADDR[9:0]
WE RE
WCLKE RCLKE
WCLK RCLK
Verilog Instantiation
SB_RAM1024x4 ram1024x4_inst (
.RDATA(RDATA_c[3:0]),
.RADDR(RADDR_c[9:0]),
.RCLK(RCLK_c),
.RCLKE(RCLKE_c),
.RE(RE_c),
.WADDR(WADDR_c[9:0]),
.WCLK(WCLK_c),
.WCLKE(WCLKE_c),
.WDATA(WDATA_c[3:0]),
.WE(WE_c)
);
defparam ram1024x4_inst.INIT_0 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
11
Memory Usage Guide
for iCE40 Devices
defparam ram1024x4_inst.INIT_1 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram1024x4_inst.INIT_2 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram1024x4_inst.INIT_3 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram1024x4_inst.INIT_4 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram1024x4_inst.INIT_5 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram1024x4_inst.INIT_6 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram1024x4_inst.INIT_7 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram1024x4_inst.INIT_8 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram1024x4_inst.INIT_9 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram1024x4_inst.INIT_A =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram1024x4_inst.INIT_B =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram1024x4_inst.INIT_C =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram1024x4_inst.INIT_D =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram1024x4_inst.INIT_E =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram1024x4_inst.INIT_F =
256'h0000000000000000000000000000000000000000000000000000000000000000;
VHDL Instantiation
Ram1024X4_inst : SB_RAM1024x4
generic map (
INIT_0 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_4 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_5 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_6 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_7 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_8 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_9 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_F => X"0000000000000000000000000000000000000000000000000000000000000000"
)
port map (
RDATA => RDATA_c,
12
Memory Usage Guide
for iCE40 Devices
SB_RAM2048x2
Figure 7. SB_RAM2048x2
SB_RAM2048x2
WDATA[1:0] RDATA[1:0]
WADDR[10:0] RADDR[10:0]
WE RE
WCLKE RCLKE
WCLK RCLK
Verilog Instantiation
SB_RAM2048x2 ram2048x2_inst (
.RDATA(RDATA_c[1:0]),
.RADDR(RADDR_c[10:0]),
.RCLK(RCLK_c),
.RCLKE(RCLKE_c),
.RE(RE_c),
.WADDR(WADDR_c[1:0]),
.WCLK(WCLK_c),
.WCLKE(WCLKE_c),
.WDATA(WDATA_c[10:0]),
13
Memory Usage Guide
for iCE40 Devices
.WE(WE_c)
);
defparam ram2048x2_inst.INIT_0 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram2048x2_inst .INIT_1 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram2048x2_inst .INIT_2 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram2048x2_inst .INIT_3 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram2048x2_inst .INIT_4 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram2048x2_inst .INIT_5 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram2048x2_inst .INIT_6 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram2048x2_inst .INIT_7 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram2048x2_inst .INIT_8 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram2048x2_inst .INIT_9 =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram2048x2_inst .INIT_A =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram2048x2_inst .INIT_B =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram2048x2_inst .INIT_C =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram2048x2_inst .INIT_D =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram2048x2_inst .INIT_E =
256'h0000000000000000000000000000000000000000000000000000000000000000;
defparam ram2048x2_inst .INIT_F =
256'h0000000000000000000000000000000000000000000000000000000000000000;
VHDL Instantiation
Ram2048x2_inst : SB_RAM2048x2
generic map (
INIT_0 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_4 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_5 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_6 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_7 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_8 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_9 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_C => X"0000000000000000000000000000000000000000000000000000000000000000",
14
Memory Usage Guide
for iCE40 Devices
port map (
RDATA => RDATA_c,
RADDR => RADDR_c,
RCLK => RCLK_c,
RCLKE => RCLKE_c,
RE => RE_c,
WADDR => WADDR_c,
WCLK=> WCLK_c,
WCLKE => WCLKE_c,
WDATA => WDATA_c,
WE => WE_c
);
SB_RAM40_4K
SB_RAM40_4K is the basic physical RAM primitive which can be instantiated and configured to different depths
and data ports. The SB_RAM40_4K block has a size of 4 Kbits with separate write and read ports, each with inde-
pendent control signals. By default, input and output data is 16 bits wide, although the data width is configurable
using the READ_MODE and WRITE_MODE parameters. The data contents of the SB_RAM40_4K block are
optionally pre-loaded during iCE device configuration.
15
Memory Usage Guide
for iCE40 Devices
Figure 8. SB_RAM40_4K
SB_RAM40_4K
WDATA[15:0] RDATA[15:0]
MASK[15:0]
WADDR[7:0] RADDR[7:0]
WE RE
WCLKE RCLKE
WCLK RCLK
Table 10 describes the parameter values to infer the desired RAM configuration.
16
Memory Usage Guide
for iCE40 Devices
Verilog Instantiation
// Physical RAM Instance without Pre Initialization
SB_RAM40_4K ram40_4kinst_physical (
.RDATA(RDATA),
.RADDR(RADDR),
.WADDR(WADDR),
.MASK(MASK),
.WDATA(WDATA)
.RCLKE(RCLKE),
.RCLK(RCLK),
.RE(RE),
.WCLKE(WCLKE),
.WCLK(WCLK),
.WE(WE)
);
defparam ram40_4kinst_physical.READ_MODE=0;
defparam ram40_4kinst_physical.WRITE_MODE=0;
VHDL Instantiation
-- Physical RAM Instance without Pre Initialization
ram40_4kinst_physical : SB_RAM40_4K
generic map (
READ_MODE => 0,
WRITE_MODE= >0
)
port map (
RDATA=>RDATA,
RADDR=>RADDR,
WADDR=>WADDR,
MASK=>MASK,
WDATA=>WDATA,
RCLKE=>RCLKE,
RCLK=>RCLK,
RE=>RE,
WCLKE=>WCLKE,
WCLK=>WCLK,
WE=>WE
);
17
Memory Usage Guide
for iCE40 Devices
18
Memory Usage Guide
for iCE40 Devices
Revision History
Date Version Change Summary
June 2016 1.5 Updated Introduction section. Added iCE40 UltraPlus to introductory
paragraph.
Updated Signals section. Added footnote to RE signal in Table 1, EBR
Signal Descriptions.
Updated Timing Diagram section. Revised Figure 3, EBR Module Tim-
ing Diagram.
Added Memory Initialization section.
Updated SB_RAM512x8 section. Minor correction in Verilog Instantia-
tion and VHDL Instantiation.
Updated SB_RAM1024x4 section. Minor correction in VHDL Instantia-
tion.
Updated iCE40 sysMEM Embedded Block RAM Memory Primitives
section.
— Revised SB_RAM512x8 Verilog Instantiation and VHDL Instantia-
tion.
— Revised SB_RAM1024x4 Verilog Instantiation and VHDL Instantia-
tion.
— Revised SB_RAM2048x2 Verilog Instantiation.
Updated Technical Support Assistance section.
January 2015 1.4 Added support for iCE40 UltraLite.
June 2014 01.3 Added support for iCE40 Ultra.
December 2013 01.2 Added information to EBR Signal Descriptions table.
October 2013 01.1 Removed iCE40 Family EBRs table.
Updated Technical Support Assistance information.
September 2012 01.0 Initial release.
19
Memory Usage Guide
for iCE40 Devices
Single-Port RAM
Verilog
module ram (din, addr, write_en, clk, dout);// 512x8
parameter addr_width = 9;
parameter data_width = 8;
input [addr_width-1:0] addr;
input [data_width-1:0] din;
input write_en, clk;
output [data_width-1:0] dout;
reg [data_width-1:0] dout; // Register for output.
reg [data_width-1:0] mem [(1<<addr_width)-1:0];
VHDL
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity ram is
generic (
addr_width : natural := 9;--512x8
data_width : natural := 8);
port (
addr : in std_logic_vector (addr_width - 1 downto 0);
write_en : in std_logic;
clk : in std_logic;
din : in std_logic_vector (data_width - 1 downto 0);
dout : out std_logic_vector (data_width - 1 downto 0));
end ram;
20
Memory Usage Guide
for iCE40 Devices
VHDL
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity ram is
generic (
addr_width : natural := 9;--512x8
data_width : natural := 8);
port (
write_en : in std_logic;
waddr : in std_logic_vector (addr_width - 1 downto 0);
wclk : in std_logic;
raddr : in std_logic_vector (addr_width - 1 downto 0);
rclk : in std_logic;
din : in std_logic_vector (data_width - 1 downto 0);
dout : out std_logic_vector (data_width - 1 downto 0));
end ram;
21
Memory Usage Guide
for iCE40 Devices
begin
process (wclk)
-- Write memory.
begin
if (wclk'event and wclk = '1') then
if (write_en = '1') then
mem(conv_integer(waddr)) <= din;
-- Using write address bus.
end if;
end if;
end process;
process (rclk) -- Read memory.
begin
if (rclk'event and rclk = '1') then
dout <= mem(conv_integer(raddr));
-- Using read address bus.
end if;
end process;
end rtl;
22