Using Memory in ispXPLD 5000MX Devices

Using Memory in
ispXPLD 5000MX Devices
™
March 2005
Technical Note TN1030
Introduction
This document describes memory usage and flow in the Lattice ispXPLD™ family of devices. A brief overview of
the ispXPLD’s memory resources are presented along with the parameterizable memory elements supported by
Lattice’s ispLEVER™ design tool.
The ispXPLD architecture is built around the Multifunction Block (MFB), which can be configured either as traditional logic or as memory. When it is configured as memory it can function as dual-port SRAM, pseudo-dual port
SRAM, single-port SRAM, FIFO, or CAM memory.
Multifunction Blocks
The ispXPLD architecture allows the MFB to be configured as a variety of memory blocks as detailed in Table 1.
Table 1. MFB Memory Configurations
Memory Mode
Configurations
Dual-port
8,192 x 1
4,096 x 2
2,048 x 4
1,024 x 8
512 x 16
Single-port,
Pseudo Dual Port,
FIFO
16,384 x1
8,192 x 2
4,096 x 4
2048 x 8
1024 x 16
512 x 32
CAM
128 x 48
Once the MFB has been configured as memory, no other logic can be implemented in that block. The one exception is a FIFO block that requires 32 data outputs, as it will need an additional MFB for flag generation. To generate
the control circuitry for the four FIFO flags, four macrocells and six inputs are required. This leaves 28 macrocells
and 62 logic inputs for generic logic implementation in the additional MFB.
Initializing Memory
In each of the memory modes it is possible to specify the power-on state of each bit in the memory array. This
allows the memory to be used as ROM if desired. Each bit in the memory array can have one of four values: 0, 1, X
(always match) or U (never match). Note that X (always match) and U (never match) values only apply for CAM. For
all other memory modes, use ones and zeroes.
Increased Depth And Width
Memory that requires a depth or width that is greater than that supported by a single MFB, can be supported by
cascading multiple blocks. For dual port, single port, and pseudo-dual port memory blocks, additional width is easily provided by sharing address lines. Additional depth is supported, by multiplexing the RAM output. For FIFO and
CAM modes additional width is supported through the cascading of MFBs. For FIFOs up to four MFBs can be cascaded for additional width ranging to 128 bits. The CAM can also cascade up to four MFBs to provide additional
width, allowing the implementation of a CAM to a maximum of 128x192.
Lattice’s ispLEVER design tool automatically combines blocks to support the memory size specified in the user’s
design.
www.latticesemi.com
1
tn1030_05.1
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
Bus Size Matching
All of the memory modes apart from the CAM mode support different widths on each of the ports. The RAM bits are
mapped LSB word 0 to MSB word 0, LSB word 1 to MSB word 1 and so on. Although the word size and number of
words for each port varies this mapping scheme applies to each port.
With CAM memory the port size is 48 bits for a single MFB. Cascading up to three additional MFBs can expand the
width of the CAM to 192 bits. Use of the mask register allows for comparisons of less than 48 bits but the port width
will still be 48 bits. This is more fully explained in the CAM description later in this document.
Different Data Bus Widths on Two Ports
True Dual Port and Pseudo Dual Port modes support different data bus widths. The two ports in the memory can
have different data bus widths. In True Dual Port Mode different widths for read/write port A and read/write port B is
supported. In Pseudo Dual Port mode, different widths for the read and write ports can also be specified.
While the two ports are operating with different data bus widths, the addressing scheme ensures that the RAM
location addressed with each address follow a certain order. Each word written on a wider side can be read as successive multiple words on a narrower port. For example if port A writes 32-bit words, and port B reads 8-bit words,
one word written on port A is read as four consecutive words from port B.
Supported Memory Modes
True Dual-Port SRAM Mode
In Dual-Port SRAM mode, the Read/Write address lines share two independent read/write ports, and can access
up to 8,192-bits of memory. Data widths of 1, 2, 4, 8, and 16 are supported by the MFB. Figure 1 shows the block
diagram of the dual port SRAM.
Write data, address, chip select and read/write signals are always synchronous (registered). The output data signals can be synchronous or asynchronous. Resets are asynchronous. All inputs on the same port share the same
clock, clock enable, and reset selections. All outputs on the same port share the same clock, clock enable, and
reset selections. Port A and Port B are completely independent from a data width and from a control standpoint.
There may be instances when both data ports attempt to write to the memory. This should be avoided as there is
no arbitration logic to control which port controls the writing of data into the memory. Table 2 shows the possible
sources for the clock, clock enable and initialization signals for the various registers.
2
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
Figure 1. Dual-Port SRAM Block Diagram
CLK0
CLK1
CLK2
CLK3
RESET
PORT A
Read/Write Address
RD Data A
(DOA[0:0-15])
(ADA[0:8-12])
Reset A (RSTA)
Clock A (CLKA)
Clk En A (CENA)
Write/Read A (WRA)
68 Inputs
From
Routing
Chip Sel A (CSA [0:1])
Write Data
‘
‘
Dual
Port
SRAM
Array
(DIA[0:0,1,3,7,15])
PORT B
Similar signals
as PORT A:
ADB[0:8-12], RSTB,
CLKB, CENB, WRB,
CSB[0,1], DIB[0:0,1,3,7,15]
RD Data B
(DOB[0:0-15])
Table 2. Register Clock, Clock Enable and Reset in Dual-Port SRAM Mode
Register
Address, Write Data,
Read Data, Read/Write,
and Chip Select
Input
Source
Clock
Selected from CLKA (CLKB) or one of the global clocks (CLK0 - CLK3).
The selected signal can be inverted if desired.
Clock Enable
Selected from CENA (CENB) or two of the global clocks (CLK1 - CLK 2).
The selected signal can be inverted if required.
Reset
Created by the logical OR of the global reset signal and RSTA (RSTB).
RSTA (RSTB) can be inverted if desired.
3
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
Pseudo Dual-Port SRAM Mode
In Pseudo Dual-Port SRAM mode the MFB is configured as an SRAM memory with independent read and write
ports that access the same 16,384-bits of memory. Data widths of 1, 2, 4, 8, 16 and 32 are supported by the MFB.
Figure 2 shows the block diagram of the Pseudo Dual-Port SRAM
Write data, write address, chip select and write enable signals are always synchronous (registered.) The read data
and read address signals can be synchronous or asynchronous. Reset is asynchronous. All write signals share the
same clock, and clock enable. All read signals share the same clock and clock enable. Reset is shared by both the
read and write signals. Table 3 shows the possible sources for the clock, clock enable and initialization signals for
the various registers.
Figure 2. Pseudo Dual-Port SRAM Block Diagram
CLK0
CLK1
CLK2
CLK3
RESET
Read Address
Read Data
(RAD[0:8-13])
(RD[0:0-15])
Write Address
(WAD[0:8-13])
Write Data
16,384 bit
Pseudo
‘
Dual
Write Enable (WE)
‘
Port
Write Clock (WCLK)
SRAM
Write Chip Sel (WCS[0,1])
Array
(WD[0:0,1,3,7,15,31])
68 Inputs
From
Routing
Write Clk Enable (WCEN)
Read Clk Enable (RCEN)
Read Clock (RCLK)
Reset (RST)
Table 3. Register Clock, Clock Enable, and Reset in Pseudo Dual-Port SRAM Mode
Register
Input
Write Address, Write Clock
Data, Write Enable,
and Write Chip Select Clock Enable
Reset
Read Data and Read Clock
Address
Source
Chosen from WCLK or one of the global clocks (CLK0 -CLK3).
The selected signal can be inverted if desired.
Chosen from WCEN or two of the global clocks (CLK0 - CLK3).
The selected signal can be inverted if desired.
Created by the logical OR of the global reset signal and RST.
RST may have inversion if desired.
Chosen from RCLK or one of the global clocks (CLK0 - CLK3).
The selected signal can be inverted if desired.
Clock Enable
Chosen from RCEN or two of the global clocks (CLK1 - CLK2).
The selected signal can be inverted if desired.
Reset
Created by the logical OR of the global reset signal and RST.
RST may have inversion if desired.
4
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
Single-Port SRAM Mode
In Single-Port SRAM mode, one port is shared by the Read/Write address lines, and can access up to 16,384-bits
of memory. Data widths of 1, 2, 4, 8, 16 and 32 are supported by the MFB. Figure 3 shows the block diagram of the
single-port SRAM.
Write data, write address, chip select and write enable signals are always synchronous (registered). The read data
and read address signals can be synchronous or asynchronous. Reset is asynchronous. All signals share a common clock, clock enable, and reset. Table 4 shows the possible sources for the clock, clock enable and reset signals.
Figure 3. Single-Port SRAM Block Diagram
CLK0
CLK1
CLK2
CLK3
RESET
Read Data
Read/Write Address
(DO[0:0-31])
(AD[0:8-13])
Write Data
(DI[0:0,1,3,7,15,31])
Write/Read (WR)
68 Inputs
from
Routing
16,384-Bit
‘
‘SRAM
Array
Clock (CLK)
Chip Select
(CS[0,1])
Clk Enable (CEN)
Reset (RST)
Table 4. Register Clock, Clock Enable, and Reset in Single-Port SRAM Mode
Register
Input
Address, Write Clock
Data, Read
Data,
Clock Enable
Read/Write, and
Chip Select
Reset
Source
CLK or one of the global clocks (CLK0 - CLK3).
Each of these signals can be inverted if required.
CEN or two of the global clocks (CLK1 - CLK 2).
Each of these signals can be inverted if required.
Created by the logical OR of the global reset signal
and RST. RST is routed by the multifunction array
from GRP, with inversion if desired.
5
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
FIFO Mode
In FIFO mode the multifunction array is configured as a FIFO (First In First Out) buffer with built in control. The read
and write clocks are independent of each other but can be tied together if the application requires it. Four flags
show the status of the FIFO: Full, Almost Full, /Empty and /Almost Empty. /Empty and /Almost Empty are negative
true signals. The thresholds for almost full and almost empty are programmable by the user. It is possible to reset
the read pointer, allowing support of frame retransmit in communications applications.
The Almost Full and /Almost Empty flags indicate the status of the stack pointer with respect to Full and /Empty.
Almost Full is an offset subtracted from the highest memory address, and /Almost Empty is an offset added to the
lowest memory address. These flags are defined in the instantiation template via the lpm_amempty_flag and
lpm_amfull_flag parameters. Values for both can range from 1 to the maximum number of address locations.
In this mode one port accesses 16,384-bits of memory. Data widths of 1, 2, 4, 8, 16 and 32 are supported by the
MFB. Figure 4 shows the block diagram of the FIFO. These MFB blocks are cascaded to create FIFO sizes larger
than 16K. Cascading sometimes requires extra logic elements like counters that occupy additional macrocells. For
width cascading, no external logic is required if the depth can fit into the maximum depth of a single block. However, for depth cascading, external counters are needed. For example, in a 16K x 16 (depth x width) FIFO configuration, no extra counters are needed. This is width cascading. For 32K X 1 FIFO, counters will be needed since the
depth (32K) is larger than the depth available in a single MFB (16K). When the configuration needs both width and
depth cascading, the software optimizes it to the maximum depth with width cascading.
Write data, write enable, flag outputs and read enable are synchronous. The Write Data, Almost Full flag and Full
flag share the same clock and clock enables. Read outputs are synchronous. The Read Data, /Empty flag and
/Almost Empty flag share the same clock and clock enables. Reset is shared by all signals. Table 5 shows the possible sources for the clock, clock enable and reset signals for the various registers.
The Full and Almost Full flags are based on the write port. The Full and Almost Full flags change state only on write
clock rising edges. The Empty and Almost Empty flags are based on the read port. The /Empty and /Almost Empty
flags change state only on read clock rising edges. FIFO flag latency is reduced when both read/write clocks are
left running. If the read/write clocks are free running, data is inserted/retrieved by synchronously controlling the
Read/Write Enable strobes.
Once the Full or Empty flag goes active, the internal FIFO pointer is frozen at the last active value, and no operation is performed on the memory. In other words, Writes to the FIFO after the full flag goes active or Reads after the
Empty flag goes active are ignored.
6
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
Figure 4. FIFO Block Diagram
CLK0
CLK1
CLK2
CLK3
RESET
Write Enable (WE)
Write Clock (WCLK)
Reset
FIFO
Control
Logic
(RST)
Read Clock (RCLK)
Reset_RP
(RSTRP)
FIFO
Flags*
Full, Empty,
Almost Full,
Almost Empty
Read Enable (RE)
‘‘
68 Inputs
From
Routing
Write Data
16,384-bit Read Data
(DO[0:0-31])
SRAM
Array
(DI[0:0-31])
*Control logic can be
duplicated in adjacent MFB
in 32-bit mode
Table 5. Register Clocks, Clock Enables, and Initialization in FIFO Mode
Register
Write Data,
Write Enable
Input
Clock
WCLK or one of the global clocks (CLK0 - CLK3).
Each of these signals can be inverted if required.
Clock Enable
WEN or two of the global clocks (CLK1 - CLK 2).
Each of these signals can be inverted if required.
Reset
Full and Almost Clock
Full Flags
Read Data,
Empty and
Almost Empty
Flags
Source
N/A
WCLK or one of the global clocks (CLK0 - CLK3).
Each of these signals can be inverted if required.
Clock Enable
WEN or two of the global clocks (CLK1 - CLK 2).
Each of these signals can be inverted if required.
Reset
Created by the logical OR of the global reset signal and
RST. RST is routed by the multifunction array from GRP,
with inversion if desired
Clock
RCLK or one of the global clocks (CLK0 - CLK3).
Each of these signals can be inverted if required.
Clock Enable
REN or two of the global clocks (CLK1 - CLK 2).
Each of these signals can be inverted if required.
Reset
Created by the logical OR of the global reset signal and
RST. RST is routed by the multifunction array from GRP,
with inversion if desired
CAM Mode
In CAM mode the multifunction array is configured as a ternary Content Addressable Memory (CAM.) CAM
behaves like a reverse memory where the input to the memory is data and the output is an address at which the
input data is located. It can be used to perform a variety of high-performance look-up functions. As such CAM has
two modes of operation. In write or update mode the CAM behaves as a RAM, and the data is written to the supplied address. When reading or comparing, data is supplied to the CAM. If that data matches any of the entries in
the CAM array the Match or Multi-Match (if there is more than one match) flag is set to true, and the lowest address
with matching data is the output. The MFB can be configured as a CAM that contains 128 entries of 48 bits.
Figure 5 shows the block diagram of the CAM
7
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
To further enhance the flexibility of the CAM a mask register is available for both update and compare operations. If
the mask register is enabled during updates, bits corresponding to those set to a ‘1’ in the mask register are not
updated. If it is enabled during compare operations, bits corresponding to those set to a ‘1’ in the mask register are
not included in the compare. A Write Don’t Care signal allows don’t cares to be programmed into the CAM if
desired. As with other write operations, the mask register controls this.
Data is written into the Mask Register by enabling the WrMask (Write Mask) bit. When WrMask is enabled during
write mode, the data written into the CAM array is also automatically stored in the Mask Register. Once the mask is
configured, it can be used during Update and Compare modes by enabling the EnMask (Enable Mask) bit.
The WrDC (Write Don’t Care) bit functions much like the EnMask and WrMask inputs. When in write mode and
WrDC is set to a 1, the data written to the CAM array during the next write operation is stored in the Write Don’t
Care register.
The Write/Comp Data, Write Address, Write Enable, Write Chip Select, and Write Don’t Care signals are synchronous. The CAM Output signals, Match flag, and Multi-Match flag signals can be either synchronous or asynchronous. The Enable mask register input is not latched but must meet setup and hold times relative to the Write Clock.
All inputs must use the same clock and clock enable signals. All outputs must use the same clock, and clock enable
signals. Reset is common for both inputs and outputs. Table 6 shows the allowable sources for clock, clock enable,
and reset for the various CAM registers.
For additional information on the CAM memory in the ispXPLD family of devices please refer to application note
AN8071, Content Addressable Memory Applications for ispXPLD Devices.
Figure 5. CAM Mode
CLK0
CLK1
CLK2
CLK3
RESET
Write/Comp Data
(WD[0:31])
CAM
Output
Write Address
CO[0:6]
(WAD[0:6])
En Mask Reg (EN_MASK)
Write Enable (WE)
Write Chip Sel (WCS[0:1])‘
68 Inputs
From
Routing
‘
WR Mask Reg (WR_MASK)
128X48
CAM
Match
Out
MATCH
WR don’t care (WR_DC)
Reset
(RST)
Multimatch
Out
CLK (CLK)
Clock Enable (CE)
MUL_MATCH
Table 6. Register Clocks, Clock Enables, and Initialization in CAM Mode
Register
Input
Clock
Write data, Write address,
Enable mask register, Write
enable, write chip select, and Clock Enable
write don’t care, CAM Output,
Match, and Multimatch
Reset
Source
CLK or one of the global clocks (CLK0 - CLK3).
Each of these signals can be inverted if required.
WE or two of the global clocks (CLK1 - CLK 2).
Each of these signals can be inverted if required.
Created by the logical OR of the global reset signal
and RST. RST is routed by the multifunction array
from GRP, with inversion if desired
8
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
Including Memory in ispXPLD 5000MX Designs
To use memory in ispXPLD 5000MX designs the desired memory function must be instantiated into the HDL
source code describing the design. This is done in the form of LPM primitives, which are passed through the synthesis tool to Lattice backend design tools. These backend tools then work to implement the memory requested in
the source code. The remainder of this document details the LPM primitives and example templates.
Configurable Memory Primitives
Configurable memory primitives are provided to allow easy configuration of the MFBs. These primitives are added
to your design source. With the addition of parameters these memory primitives can be easily configured to match
your design needs.
This section describes the six types of configurable memory primitives that are supported.
•
•
•
•
•
•
LPM_RAM_DP
LPM_RAM_DP_PSEUDO
LPM_RAM_DQ
LPM_FIFO_DC
LPM_CAM
LPM_ROM
– Dual-Port RAM
– Pseudo Dual Port RAM
– Single-port RAM
– FIFO
– CAM
– ROM
9
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
True Dual-Port Random Access Memory (LPM_RAM_DP)
DataInA
QA
AddressA
ClockA
ClockEnA
WrA
ResetA
LP
LPM_RAM_DP
DataInB
AddressB
QB
ClockB
ClockEnB
WrB
ResetB
Ports
Port
QA
Type
Out
Description
Data out, port A
Comments
Port width is user defined
DataInA
In
Data in, port A
Port width is user defined
AddressA
In
Address, port A
Address depth is user defined
ClockA
In
Clock, port A
ClockEnA
In
Clock Enable, port A
WrA
In
Write Enable, Port A
ResetA
In
Reset, port A
Asynchronous Reset
Data out, port B
Port width is user defined
Data in, port B
Port width is user defined
Address depth is user defined
QB
DataInB
Out
In
AddressB
In
Address, port B
ClockB
In
Clock, port B
ClockEnB
In
Clock Enable, port B
WrB
In
Write Enable, Port B
ResetB
In
Reset, port B
Asynchronous Reset
10
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
Properties
Parameter
Description
Comments
Value
lpm_widtha
Defines data width for port A
User-defined
Number of data bits
lpm_widthada
Defines address width for port A
User-defined
Number of address lines
lpm_numwordsa
Defines memory depth for port A
User-defined
Number of address locations
lpm_widthb
Defines data width for port B
User-defined
Number of data bits
lpm_widthadb
Defines address width for port B
User-defined
Number of address lines
lpm_numwordsb
Defines memory depth for port B
User-defined
Number of address locations
lpm_outdata
Defines read data to be synchronous or asynchronous
User-defined
Registered or Unregistered
lpm_indata
Defines write data to be synchronous
Synchronous
Registered
lpm_addressa_control
Defines that port A address lines will be synchro- Synchronous
nous
Registered
lpm_addressb_control
Defines that port B address lines will be synchro- Synchronous
nous
Registered
lpm_init_file
Defines initialization file
File for initializing Name of the initialization file
data in the RAM
True Dual Port RAM with Asynchronous Read
tDPRWAS
tDPRWAH
Write/ Read A (WRA)
tDPRWBS
tDPRWBH
Write/ Read B (WRB)
tDPCEAS
Clk En A (CENA)
tDPCEAH
Clock A (CLKA)
Clk En B (CENB)
tDPCLKSKEW
tDPCEBS
Clock B (CLKB)
tDPMSAH
tDPMSAS
Chip Sel A (CSA[0:1])
tDPMSBS
Chip Sel B (CSB[0:1])
Read/ Write Address A (ADA[0:8-12])
Read/ Write Address B (ADB[0:8-12])
tDPADDAS
Add_1_A
Add_1_A
Add_0_A
tDPADDAH
Add_1_A
Add_0_B
tDPDATAAS
tDPADDBS
Write Data A (DIA[0:0,1,3,7,15])
tDPADDBH
Data_1_A
Add_1_B
tDPDATAAH
Data_2_A
Write Data B (DIB[0:0,1,3,7,15])
Data_1_B
tDPRCLKAO
tDPDATABS
RD Data A (DOA[0:0-15]) Invalid/ Previous Data
Data_0_A
Data_1_A
tDPDATABH
Data_2_A
tDPRCLKBO
RD Data B (DOB[0:0-15])
Invalid/ Previous Data
Data_0_B
Data_1_A
Data_2_A
Data_1_B
Note: While one port is writing and the other port tries to read or write at the same memory location, there must be a minimum tDPCLKSKEW
between the two clocks.
11
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
True Dual Port RAM with Synchronous Read
tDPRWAS
tDPRWAH
Write/ Read A (WRA)
Write/ Read B (WRB)
tDPCEAH
tDPCEAS
Clk En A (CENA)
Clock A (CLKA)
Clk En B (CENB)
tDPCLKSKEW
tDPCEBS
Clock B (CLKB)
tDPMSAS
tDPMSAH
Chip Sel A (CSA[0:1])
tDPMSBS
Chip Sel B (CSB[0:1])
Read/ Write Address A (ADA[0:8-12])
tDPADDAS
tDPADDAH
Read/ Write Address B (ADB[0:8-12])
Write Data A (DIA[0:0,1,3,7,15])
Add_0_B
tDPADDBS
Add_1_A
tDPDATAAS
tDPADDBH
tDPDATAAH
Data_1_A
Write Data B (DIB[0:0,1,3,7,15])
RD Data A (DOA[0:0-15])
Add_1_A
Add_1_A
Add_0_A
Data_2_A
tDPRCLKAO
Data_0_A
Invalid/ Previous Data
Data_1_A
Data_2_A
tDPRCLKBO
RD Data B (DOB[0:0-15])
Invalid/ Previous Data
Data_0_B
Data_1_A
Data_2_A
Note: While one port is writing and the other port tries to read or write at the same memory location, there must be a minimum tDPCLKSKEW
between the two clocks.
For timing numbers, please refer to the ispXPLD 5000MX Data Sheet.
12
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
Pseudo Dual-Port Random Access Memory (LPM_RAM_PSEUDO)
Data
Q
WrAddress
WrClock
WrClockEN
LPM_RAM_DP
PSEUDO
RdAddress
RdClock
RdClockEN
WE
Reset
Ports
Port
Q
Type
Out
Description
Comments
Data out
Port width is user defined
Data
In
Data in
Port width is user defined
WrAddress
In
Write Address
Address Depth is user defined
WrClock
In
Write Clock
WrClockEN
In
Write Clock Enable
RdAddress
In
Read Address
RdClock
In
Read Clock
RdClockEN
In
Read Clock Enable
WE
In
Write Enable
Reset
In
Reset
Address Depth is user defined
Asynchronous Reset
Properties
Parameter
Description
Comments
User-defined
Value
lpm_widthw
Defines data width for write port
Number of data bits to write
lpm_widthadw
Defines address width for write port
User-defined
Number of write address lines
lpm_numwordsw
Defines memory depth for write
User-defined
Number of address locations
lpm_widthr
Defines data width for read port
User-defined
Number of data bits to read
lpm_widthadr
Defines address width for read port
User-defined
Number of read address lines
lpm_numwordsr
Defines memory depth for read
User-defined
Number of read address locations
lpm_outdata
Defines read data to be synchronous or
asynchronous
User-defined
Registered or unregistered
lpm_addressr_control
Defines that read address lines will be
synchronous
Synchronous
Registered
lpm_addressw_control Defines that write address lines will be
synchronous
Synchronous
Registered
lpm_init_file
File for initializing
data in the RAM
Name of the initialization file
Defines initialization file
13
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
Pseudo Dual Port RAM with Asynchronous Read
tPDPMSH
Write Chip Select (WCS[0,1])
tPDPMSS
tPDPRWS
tPDPRWH
Write Enable (WE)
Write Clock (WCLK)
tPDPWCES
tPDPWCEH
Write Clk Enable (WCEN)
tPDPCLKSKEW
Read Clock (RCLK)
tPDPRCES
tPDPRCEH
Read Clk Enable (RCEN)
tPDPWADDS
tPDPWADDH
Write Address (WAD[0:0,1,3,7,15,31])
Read Address (RAD[0:8-13])
Add_1
Add_1
tPDPRADDH
tPDPRADDS
Add_2
Add_2
tSPADDDATA
Add_0
tPDPDATAS
Write Data (WD[0:0,1,3,7,15,31])
tPDPDATAH
Data_1
Read Data (RD[0:0-15])
Data_3
tPDPRCLKO
Invalid / Previous Data
Data_0
Data_1
Data_2
Data_3
Notes:
While Write port is writing and the Read port tries to read at the same memory location, there must be a minimum tPDPCLKSKEW
between the two clocks. As shown above, if Add_1 is where the the read and write is occurring then there should be a minimum clock
skew of tPDPCLKSKEW between the RCLK and WCLK.
Further, when we read from an address and in the next Write clock cycle, we start writing to that address, then the Read Data gets
updated tSPADDDATA after the address is stable. This is shown, when we are reading Add_2 and the Read Data is Data_2. In the next
write clock cycle, Add_2 is witten with Data_3. The Read Data gets updated tSPADDDATA after the Add_2 is stable. Both Data_2 and
Data_3 are from the same location Add_2.
14
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
Pseudo Dual Port RAM with Synchronous Read
tPDPMSH
Write Chip Select (WCS[0,1])
tPDPMSS
tPDPRWS
tPDPRWH
Write Enable (WE)
Write Clock (WCLK)
tPDPWCES
tPDPWCEH
Write Clk Enable (WCEN)
tPDPCLKSKEW
Read Clock (RCLK)
tPDPRCES
tPDPRCEH
Read Clk Enable (RCEN)
tPDPWADDS
tPDPWADDH
Write Address (WAD[0:0,1,3,7,15,31])
Add_1
tPDPRADDS
Add_2
tPDPRADDH
Read Address (RAD[0:8-13])
Add_1
Add_2
tPDPDATAH
Add_0
tPDPDATAS
Write Data (WD[0:0,1,3,7,15,31])
Read Data (RD[0:0-15])
Data_1
tPDPRCLKO
Invalid / Previous Data
Data_0
Data_3
Data_1
Data_2
Data_3
Notes:
While the Write port is writing and the Read port tries to read at the same memory location, there must be a minimum tPDPCLKSKEW
between the two clocks. As shown above, if Add_1 is where the the read and write is occurring then there should be a minimum clock
skew of tPDPCLKSKEW between the RCLK and WCLK.
Further, when we read from an address and in the next Write clock cycle, we start writing to that address, then the Read Data gets
updated tSPADDDATA after the address is stable. This is shown when we are reading Add_2 and the Read Data is Data_2. In the next
write clock cycle, Add_2 is witten with Data_3. The Read Data gets updated tSPADDDATA after the Add_2 is stable. Both Data_2 and
Data_3 are from the same location, Add_2.
For timing numbers, please refer to the ispXPLD 5000MX Data Sheet.
15
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
Single-Port RAM (LPM_RAM_DQ)
Data
Q
Address
LPM_RAM_DQ
Clock
ClockEN
WE
Reset
Ports
Port
Q
Type
Out
Description
Comments
Data Out
Port width is user defined
Data
In
Data In
Port width is user defined
Address
In
Read/Write Address
Port width is user defined
Clock
In
Clock
ClockEn
In
Clock Enable
WE
In
Write Enable
Reset
In
Reset
Asynchronous Reset
Properties
Parameter
Description
Comments
Value
lpm_width
Defines Data width
User-defined
Number of data bits
lpm_widthad
Defines address width
User-defined
Number of address lines
lpm_numwords
Defines memory depth
User-defined
Number of address locations
lpm_outdata
Defines read data to be synchronous or
asynchronous
User-defined
Registered or unregistered
lpm_address_control Defines the value of the read address
User-defined
lines. In unregistered mode, the output
toggles at each address change. In registered mode, Q is toggled by the clock.
Registered or unregistered
lpm_init_file
Name of the initialization file
Defines initialization file
File for initializing data in
the RAM
16
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
Single Port RAM with Asynchronous Read
tSPRWS
tSPRWH
Write/ Read (WR)
tSPCES
Clk Enable (CEN)
Clock (CLK)
tSPADDS
tSPADDH
Add_0
Read / Write Address (AD[0:8-13])
Add_1
tSPADDDATA
Data_1
Write Data (DI[0:0,1,3,7,15,31])
Read Data (DO[0:0-31])
tSPDATAS
Invalid/ Previous Data
tSPDATAH
Data_1
Data_0
Single Port RAM with Synchronous Read
tSPRWS
tSPRWH
Write/ Read (WR)
tSPCES
Clk Enable (CEN)
Clock (CLK)
Add_1
Add_0
Read / Write Address (AD[0:8-13])
tSPADDS
tSPADDH
Data_1
Write Data (DI[0:0,1,3,7,15,31])
tSPCLKO t
SPDATAS
Read Data (DO[0:0-31])
Invalid/ Previous Data
tSPDATAH
Data_0
For timing numbers, please refer to the ispXPLD 5000MX Data Sheet.
17
Data_1
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
First-In-First-Out Memory (LPM_FIFO)
Data
Q
WrClock
Full
WrEn
RdClock
Empty
LPM_FIFO
RdEN
AmFull
RPReset
AmEmpty
Reset
Ports
Port
Type
Description
Comments
Q
Out
Data Out
Port width is user defined
Full
Out
Flag
Set when FIFO is Full, user defined
Empty
Out
Flag
Clear (logic “0”) when FIFO is empty
AmFull
Out
Flag
Set at user defined value
AmEmpty
Out
Flag
Clear (logic “0”) at user defined value
Data In
Port width is user defined
Data
In
WrClock
In
Write Clock
WrEn
In
Write Enable
RdClock
In
Read Clock
RdEn
In
Read Enable
RPReset
In
Read Control Pointer
Reset
In
Reset
Asynchronous Reset
Properties
Parameter
Description
Comments
Value
lpm_width
Defines data width
User-defined
Number of data bits
lpm_widthu
Defines address width
User-defined
Number of address lines required to access
lpm_numwords FIFO entries
lpm_numwords
Defines memory depth
User-defined
Number of data entries the FIFO can store
lpm_amfull_flag
Almost full flag
User-defined offset
Offset subtracted from lpm_numwords
lpm_amempty_flag
Almost empty flag
User-defined offset
Offset added to address 0
18
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
FIFO
tFIFOWES
tFIFOWEH
Write Enable (WE)
Write Clock (WCLK)
tFIFORES
tFIFOREH
Read Enable (RE)
Read Clock (RCLK)
tFIFOWCLKH
Write Data (DI[0:0-31])
Data_0
Data_1
Data_2
Invalid Data
Read Data (DO[0:0-31])
Data_0
Data_1
Data_2
tFIFOFULL
tFIFORCLKO
Full
tFIFOAFULL
tFIFOCLKSKEW
Almost Full
Empty
tFIFOAEMPTY tFIFOEMPTY
Almost Empty
For timing numbers, please refer to the ispXPLD 5000MX Data Sheet.
19
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
Content Addressable Memory (LPM_CAM)
Data
Address
WAD
Clock
ClockEn
WE
EnMask
WrMask
WrDc
Reset
Match
MulMatch
LPM_CAM
Ports
Port
Type
Description
Comments
Address
Out
Write Address
Port width is user defined
Match
Out
Flag
Set when match
MulMatch
Out
Flag
Set when Multiple matches
Data
In
Data In
Port width is user defined
Port width is user defined
Wad
In
Write Address
Clock
In
Clock
ClockEn
In
Clock Enable
We
In
Write Enable
EnMask
In
Enable Mask Register
Enables use of global mask register
WrMask
In
Write Mask Register
Enables writing to the Mask Register
WrDC
In
Write Don’t Care
Don’t Cares can be written to the CAM
Reset
In
Reset
Asynchronous Reset
Properties
Parameter
Description
Comments
Value
lpm_width
Defines data width
User-defined
Number of data bits
lpm_widthad
Defines address width
User-defined
Number of address lines
lpm_numwords
Defines memory depth
User-defined
Number of address locations
lpm_init_file
Defines initialization file
File for initializing data in the CAM
Name of the initialization file
20
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
CAM with Asynchronous Read
tCAMRWS
tCAMRWH
Write Enable (WE)
tCAMENMSKS
tCAMENMSKH
En Mask Reg (EN_MASK)
tCAMWMSKS
tCAMWMSKH
WR Mask Reg (WR_MASK)
tCAMDCS
tCAMDCH
WR don't care (WR_DC)
tCAMCES
Clock Enable (CE)
CLK (CLK)
Write / Comp Data (WD[0:31])
Data_0
tCAMDATAS
Data_1
Data_2
Data_3
Data_3
Data_4
Address_4
tCAMDATAH
Address_5
Write Address (WAD[0:6])
tCAMADDH
tCAMADDS
tCAMMATCH
Match Out (MATCH)
tCAMMMATCH
Multi-Match Out (MUL_MATCH)
tCAMCO
Invalid Address
CAM Output (CO[0:6])
Address_0
Address_4
Address_2
CAM with Synchronous Read
tCAMRWS
tCAMRWH
Write Enable (WE)
tCAMENMSKS
tCAMENMSKH
En Mask Reg (EN_MASK)
tCAMWMSKS
tCAMWMSKH
WR Mask Reg (WR_MASK)
tCAMDCS
tCAMDCH
WR don’t care (WR_DC)
tCAMCES
Clock Enable (CE)
CLK (CLK)
Write / Comp Data (WD[0:31])
Data_0
tCAMDATAS
Data_1
Data_2
Data_3
Data_3
Address_4
tCAMDATAH
Write Address (WAD[0:6])
tCAMMATCH
tCAMADDS
Data_4
Address_5
tCAMADDH
Match Out (MATCH)
tCAMMMATCH
Multi-Match Out (MUL_MATCH)
tCAMCO
CAM Output (CO[0:6])
Invalid Address
Address_0
For timing numbers, please refer to the ispXPLD 5000MX Data Sheet.
21
Address_2
Address_4
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
Read-Only Memory (LPM_ROM)
Q
Address
OutClock
OutClockEn
Reset
LPM_ROM
Ports
Port
Q
Type
Out
Description
Comments
Data Out
Port width is user defined
Port width is user defined
Address
In
Read Address
OutClock
In
Clock
OutClockEn
In
Clock Enable
Reset
In
Reset
Asynchronous Reset
Properties
Parameter
Description
Comments
Value
lpm_width
Defines data width
User-defined
Number of data bits
lpm_widthad
Defines address width
User-defined
Number of address lines
lpm_numwords
Defines memory depth
User-defined
Number of address locations
lpm_outdata
Defines read data to be synchronous or
asynchronous
User-defined
Registered or unregistered
lpm_address_control Defines the value of the read address
User-defined
lines. In unregistered mode, the output
toggles at each address change. In registered mode, Q is toggled by the clock.
Registered or unregistered
lpm_init_file
Name of the initialization file
Defines initialization file
File for initializing
data in the ROM
ROM with Asynchronous Read
Clk Enable (CEN)
Clock (CLK)
Read Address (AD[0:8-13])
Read Data (DO[0:0-31])
Add_1
Add_0
Invalid/ Previous Data
Data_0
22
Data_1
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
ROM with Synchronous Read
Clk Enable (CEN)
Clock (CLK)
Read Address (AD[0:8-13])
Read Data (DO[0:0-31])
Add_0
Add_1
Data_0
Invalid/ Previous Data
For timing numbers, please refer to the ispXPLD 5000MX Data Sheet.
23
Data_1
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
Appendix A. Memory Primitive Source Examples (Verilog)
Note: The Verilog templates shown here can also be found in the software examples directory:
\<isptools_instalation_directory>\ispcpld\examples\ispXPLD\verilog
True Dual-Port Random Access Memory (LPM_RAM_DP)
module tramdp8kx2x2(
QA,
QB,
DataInA,
AddressA,
DataInB,
AddressB,
ClockA,
ClockEnA,
ClockB,
ClockEnB,
WrA,
WrB,
ResetA,
ResetB);
output [1:0] QA;
output [1:0] QB;
input [1:0] DataInA;
input [12:0] AddressA;
input [1:0] DataInB;
input [12:0] AddressB;
input ClockA,ClockEnA,ClockB,ClockEnB,WrA,WrB,ResetA,ResetB;
L_RAMDP
U0(.QA(QA),.QB(QB),.DataInA(DataInA),.AddressA(AddressA),.DataInB(DataInB),.A
ddressB(AddressB),.ClockA(ClockA),.ClockEnA(ClockEnA),.ClockB(ClockB),.ClockE
nB(ClockEnB),.WrA(WrA),.WrB(WrB),.ResetA(ResetA),.ResetB(ResetB));
defparam
defparam
defparam
defparam
defparam
defparam
defparam
defparam
defparam
defparam
U0.lpm_widtha=2;
U0.lpm_widthada=13;
U0.lpm_numwordsa=8192;
U0.lpm_widthb=2;
U0.lpm_widthadb=13;
U0.lpm_numwordsb=8192;
U0.lpm_outdata
= “REGISTERED”;
U0.lpm_addressa_control = “REGISTERED”;
U0.lpm_addressb_control = “REGISTERED”;
U0.lpm_init_file = “RAM_init”;
endmodule
module L_RAMDP(
QA,
QB,
DataInA,
AddressA,
24
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
DataInB,
AddressB,
ClockA,
ClockEnA,
ClockB,
ClockEnB,
WrA,
WrB,
ResetA,
ResetB);
parameter
parameter
parameter
parameter
parameter
parameter
parameter
parameter
parameter
parameter
parameter
parameter
parameter
lpm_type = “LPM_RAM_DP”;
lpm_widtha
= 1;
lpm_widthada
= 1;
lpm_numwordsa = 1;
lpm_widthb
= 1;
lpm_widthadb
= 1;
lpm_numwordsb = 1;
lpm_indata
= “REGISTERED”;
lpm_outdata
= “UNREGISTERED”;
lpm_addressa_control = “REGISTERED”;
lpm_addressb_control = “REGISTERED”;
lpm_hint = “UNUSED”;
lpm_init_file = “dummy”;
output [lpm_widtha-1:0] QA;
output [lpm_widthb-1:0] QB;
input [lpm_widtha-1:0] DataInA;
input [lpm_widthada-1:0] AddressA;
input [lpm_widthb-1:0] DataInB;
input [lpm_widthadb-1:0] AddressB;
input
ClockA,ClockEnA,ClockB,ClockEnB,WrA,WrB,ResetA,ResetB;
endmodule
//lpm_ramdp
25
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
Pseudo Dual-Port Random Access Memory (LPM_RAM_PSEUDO)
module tramdps16kwx2rx2(
Q,
Data,
WrAddress,
RdAddress,
WrClock,
WrClockEn,
RdClock,
RdClockEn,
WE,
Reset);
output [1:0] Q;
input [1:0] Data;
input [13:0] WrAddress;
input [13:0] RdAddress;
input WrClock,WrClockEn,RdClock,RdClockEn,WE,Reset;
L_RAMDPS
U0(.Q(Q),.Data(Data),.WrAddress(WrAddress),.RdAddress(RdAddress),.WrClock(WrC
lock),.WrClockEn(WrClockEn),.RdClock(RdClock),.RdClockEn(RdClockEn),.WE(WE),.
Reset(Reset));
defparam
defparam
defparam
defparam
defparam
defparam
defparam
defparam
defparam
U0.lpm_widthw=2;
U0.lpm_widthadw=14;
U0.lpm_numwordsw=16384;
U0.lpm_widthr=2;
U0.lpm_widthadr=14;
U0.lpm_numwordsr=16384;
U0.lpm_outdata
= “REGISTERED”;
U0.lpm_addressr_control = “REGISTERED”;
U0.lpm_init_file=”RAM_init”;
endmodule
module L_RAMDPS(
Q,
Data,
WrAddress,
RdAddress,
WrClock,
WrClockEn,
RdClock,
RdClockEn,
WE,
Reset);
parameter
parameter
parameter
parameter
parameter
lpm_type = “LPM_RAM_DP_PSEUDO”;
lpm_widthw
= 1;
lpm_widthr
= 1;
lpm_numwordsw = 1;
lpm_widthadw
= 1;
26
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
parameter
parameter
parameter
parameter
parameter
parameter
parameter
parameter
lpm_widthadr
= 1;
lpm_numwordsr = 1;
lpm_indata
= “REGISTERED”;
lpm_outdata
= “UNREGISTERED”;
lpm_addressw_control = “REGISTERED”;
lpm_addressr_control = “REGISTERED”;
lpm_hint = “UNUSED”;
lpm_init_file = “dummy”;
output [lpm_widthr-1:0] Q;
input [lpm_widthw-1:0] Data;
input [lpm_widthadw-1:0] WrAddress;
input [lpm_widthadr-1:0] RdAddress;
input WrClock,WrClockEn,RdClock,RdClockEn,WE,Reset;
endmodule // lpm_ram_dp_pseudo
27
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
Random Access Memory (LPM_RAM_DQ)
module tramdq16kx2(
Q,
Data,
Address,
Clock,
ClockEn,
WE,
Reset);
output [1:0] Q;
input [1:0] Data;
input [13:0] Address;
input Clock,ClockEn,WE,Reset;
L_RAMDQ
U0(.Q(Q),.Data(Data),.Address(Address),.Clock(Clock),.ClockEn(ClockEn),.WE(WE
),.Reset(Reset));
defparam
defparam
defparam
defparam
defparam
defparam
U0.lpm_width=2;
U0.lpm_widthad=14;
U0.lpm_numwords=16384;
U0.lpm_outdata=”REGISTERED”;
U0.lpm_address_control=”REGISTERED”;
U0.lpm_init_file=”RAM_init”;
endmodule
module L_RAMDQ(
Q,
Data,
Address,
Clock,
ClockEn,
WE,
Reset);
parameter
parameter
parameter
parameter
parameter
parameter
parameter
parameter
parameter
lpm_type = “LPM_RAM_DQ”;
lpm_width
= 1;
lpm_numwords = 1;
lpm_widthad
= 1;
lpm_indata
= “REGISTERED”;
lpm_outdata
= “UNREGISTERED”;
lpm_address_control = “REGISTERED”;
lpm_hint = “UNUSED”;
lpm_init_file = “dummy”;
output [lpm_width-1:0] Q;
input [lpm_width-1:0] Data;
input [lpm_widthad-1:0] Address;
input Clock,ClockEn,WE,Reset;
endmodule // lpm_ram_dq
28
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
First-In-First-Out Memory (LPM_FIFO_DC)
module test_fifo16kx2
(Q,Full,Empty,AlmostFull,AlmostEmpty,Data,WrClock,WrEn,RdClock,RdEn,Reset,RPReset);
output [1:0] Q;
output Full,Empty,AlmostFull,AlmostEmpty;
input [1:0] Data;
input WrClock,WrEn,RdClock,RdEn,Reset,RPReset;
L_FIFO U0(.Q(Q),
.Full(Full),
.Empty(Empty),
.AlmostFull(AlmostFull),
.AlmostEmpty(AlmostEmpty),
.Data(Data),
.WrClock(WrClock),
.WrEn(WrEn),
.RdClock(RdClock),
.RdEn(RdEn),
.Reset(Reset),
.RPReset(RPReset)
);
defparam
defparam
defparam
defparam
defparam
U0.lpm_width=2;
U0.lpm_widthu=14;
U0.lpm_numwords=16384;
U0.lpm_amfull_flag=11;
U0.lpm_amempty_flag=11;
endmodule
module
L_FIFO(Q,Full,Empty,AlmostFull,AlmostEmpty,Data,WrClock,WrEn,RdClock,RdEn,Reset,RPReset) ;
parameter
parameter
parameter
parameter
parameter
parameter
parameter
output
output
output
output
output
input
input
input
input
input
lpm_type = “LPM_FIFO_DC”;
lpm_width = 1;
lpm_widthu = 1;
lpm_numwords = 2;
lpm_amfull_flag=1;
lpm_amempty_flag=1;
lpm_hint = “UNUSED”;
[lpm_width-1:0] Q;
Full;
Empty;
AlmostFull;
AlmostEmpty;
[lpm_width-1:0] Data;
WrClock;
WrEn;
RdClock;
RdEn;
29
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
input
input
Reset;
RPReset;
endmodule // lpm_fifo
30
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
Content Addressable Memory (LPM_CAM)
module
tcam128x48
(Address,Match,MulMatch,Wad,Data,Clock,ClockEn,We,EnMask,WrMask,WrDc,Reset);
output [6:0] Address;
output Match,MulMatch;
input [47:0] Data;
input [6:0] Wad;
input Clock,ClockEn,We,EnMask,WrMask,WrDc,Reset;
L_CAM
U0(.Address(Address),.Match(Match),.MulMatch(MulMatch),.WrAddress(Wad),.Data(
Data),.Clock(Clock),.ClockEn(ClockEn),.WE(We),.EnMask(EnMask),.WrMask(WrMask)
,.WrDC(WrDc),.Reset(Reset));
defparam
defparam
defparam
defparam
U0.lpm_width=48;
U0.lpm_widthad=7;
U0.lpm_numwords=128;
U0.lpm_init_file= “CAM_init”;
endmodule
module
L_CAM(Address,Match,MulMatch,WrAddress,Data,Clock,ClockEn,WE,EnMask,WrMask,WrDC,Reset);
parameter
parameter
parameter
parameter
parameter
parameter
lpm_type = “LPM_CAM”;
lpm_width = 1;
lpm_widthad = 1;
lpm_numwords = 1;
lpm_hint = “UNUSED”;
lpm_init_file = “dummy”;
output [lpm_widthad-1:0] Address;
output Match;
output MulMatch;
input [lpm_widthad-1:0] WrAddress;
input [lpm_width-1:0] Data;
input Clock;
input ClockEn;
input WE;
input EnMask;
input WrMask;
input WrDC;
input Reset;
endmodule // lpm_cam
31
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
Read-Only Memory (LPM_ROM)
module test_rom16kx2(
Q,
Address,
OutClock,
OutClockEn,
Reset);
output [1:0] Q;
input [13:0] Address;
input OutClock,OutClockEn,Reset;
L_ROM
U0(.Q(Q),.Address(Address),.OutClock(OutClock),.OutClockEn(OutClockEn),.Reset(Reset));
defparam
defparam
defparam
defparam
defparam
defparam
U0.lpm_width=2;
U0.lpm_widthad=14;
U0.lpm_numwords=16384;
U0.lpm_outdata=”REGISTERED”;
U0.lpm_address_control=”UNREGISTERED”;
U0.lpm_init_file =”ROM_init”;
endmodule
module L_ROM(
Q,
Address,
OutClock,
OutClockEn,
Reset);
parameter lpm_type = “LPM_ROM”;
parameter lpm_width
= 1;
parameter lpm_numwords = 1;
parameter lpm_widthad
= 1;
parameter lpm_outdata
= “REGISTERED”;
parameter lpm_address_control = “UNREGISTERED”;
parameter lpm_hint = “UNUSED”;
parameter lpm_init_file = “dummy”;
output [lpm_width-1:0] Q;
input [lpm_widthad-1:0] Address;
input OutClock,OutClockEn,Reset;
endmodule // lpm_rom
32
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
Appendix B. Memory Primitive Source Examples (VHDL)
Note: The VHDL templates shown here can also be found in the software examples directory:
\<isptools_instalation_directory>\ispcpld\examples\ispXPLD\VHDL
True Dual-Port Random Access Memory (LPM_RAM_DP)
library IEEE;
use IEEE.std_logic_1164.all;
LIBRARY lc5kmx;
USE lc5kmx.components.all;
entity tramdp8kx2x2 is
port (
DataInA
AddressA
DataInB
AddressB
ClockA
ClockEnA
ClockB
ClockEnB
WrA
WrB
ResetA
ResetB
QA
QB
end tramdp8kx2x2 ;
:
:
:
:
:
:
:
:
:
:
:
:
:
:
in std_logic_vector( 1 downto 0);
in std_logic_vector( 12 downto 0);
in std_logic_vector( 1 downto 0);
in std_logic_vector( 12 downto 0);
in std_logic;
in std_logic;
in std_logic;
in std_logic;
in std_logic;
in std_logic;
in std_logic;
in std_logic;
out std_logic_vector(1 downto 0);
out std_logic_vector(1 downto 0));
architecture behave of tramdp8kx2x2 is
component L_RAMDP
generic(
LPM_TYPE
: string := “LPM_RAM_DP”;
LPM_WIDTHA
: positive := 1;
LPM_WIDTHADA : positive := 1;
LPM_NUMWORDSA : positive := 2;
LPM_WIDTHB
: positive := 1;
LPM_WIDTHADB : positive := 1;
LPM_NUMWORDSB : positive := 2;
LPM_INDATA
: string :=”REGISTERED”;
LPM_OUTDATA
: string :=”UNREGISTERED”;
LPM_ADDRESSA_CONTROL
: string :=”REGISTERED”;
LPM_ADDRESSB_CONTROL
: string :=”REGISTERED”;
LPM_INIT_FILE : string := “dummy”;
LPM_HINT
: string :=”UNUSED”);
port(
DataInA : in std_logic_vector(LPM_WIDTHA-1 downto 0);
AddressA:in std_logic_vector(LPM_WIDTHADA-1 downto 0);
DataInB : in std_logic_vector(LPM_WIDTHB-1 downto 0);
33
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
AddressB:in std_logic_vector(LPM_WIDTHADB-1 downto 0);
ClockA
: in std_logic := ‘0’;
ClockEnA
: in std_logic := ‘0’;
ClockB
: in std_logic := ‘0’;
ClockEnB
: in std_logic := ‘0’;
WrA
: in std_logic;
WrB
: in std_logic;
ResetA
: in std_logic;
ResetB
: in std_logic;
QA
: out std_logic_vector(LPM_WIDTHA-1 downto 0);
QB
: out std_logic_vector(LPM_WIDTHB-1 downto 0));
end component ;
begin
U0: L_RAMDP
generic map (
LPM_WIDTHA
=> 2,
LPM_WIDTHADA => 13,
LPM_NUMWORDSA => 8192,
LPM_WIDTHB
=> 2,
LPM_WIDTHADB => 13,
LPM_NUMWORDSB => 8192,
LPM_INDATA => “REGISTERED”,
LPM_OUTDATA
=> “UNREGISTERED”,
LPM_ADDRESSA_CONTROL => “REGISTERED”,
LPM_ADDRESSB_CONTROL => “REGISTERED”,
LPM_INIT_FILE => “RAM_init”)
port map (
DataInA
=> DataInA,
AddressA
=> AddressA,
DataInB
=> DataInB,
AddressB
=> AddressB,
ClockA
=> ClockA,
ClockEnA
=> ClockEnA,
ClockB
=> ClockB,
ClockEnB
=> ClockEnB,
WrA
=> WrA,
WrB
=> WrB,
ResetA
=> ResetA,
ResetB
=> ResetB,
QA
=> QA,
QB
=> QB);
end behave;
34
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
Pseudo Dual-Port Random Access Memory (LPM_RAM_PSEUDO)
library IEEE;
use IEEE.std_logic_1164.all;
LIBRARY lc5kmx;
USE lc5kmx.components.all;
entity tramdps16kwx2rx2 is
port (
Data
WrAddress
RdAddress
WrClock
WrClockEn
RdClock
RdClockEn
WE
Reset
Q
end tramdps16kwx2rx2 ;
:
:
:
:
:
:
:
:
:
:
in std_logic_vector(1 downto 0);
in std_logic_vector(13 downto 0);
in std_logic_vector(13 downto 0);
in std_logic;
in std_logic;
in std_logic;
in std_logic;
in std_logic;
in std_logic;
out std_logic_vector(1 downto 0));
architecture struct of tramdps16kwx2rx2 is
component L_RAMDPS
generic(
lpm_type
: string := “LPM_RAM_DP_PSEUDO”;
lpm_widthw
: integer := 1;
lpm_widthr
: integer := 1;
lpm_numwordsw
: integer := 1;
lpm_widthadw
: integer := 1;
lpm_widthadr
: integer := 1;
lpm_numwordsr
: integer := 1;
lpm_indata
: string := “REGISTERED”;
lpm_outdata
: string := “UNREGISTERED”;
lpm_addressw_control : string := “REGISTERED”;
lpm_addressr_control : string := “REGISTERED”;
lpm_init_file
: string := “dummy”;
lpm_hint
: string := “UNUSED”);
port(
Data
: in std_logic_vector(lpm_widthw-1 downto 0);
WrAddress:in std_logic_vector(lpm_widthadw-1 downto 0);
RdAddress:in std_logic_vector(lpm_widthadr-1 downto 0);
WrClock
: in std_logic := 0;
WrClockEn
: in std_logic := 0;
RdClock
: in std_logic := 0;
RdClockEn
: in std_logic := 0;
WE
: in std_logic;
Reset
: in std_logic;
Q
: out std_logic_vector(lpm_widthr-1 downto 0));
end component ;
35
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
begin
lpm_gen: L_RAMDPS
generic map (
lpm_widthw
=> 2,
lpm_widthadw => 14,
lpm_numwordsw => 16384,
lpm_widthr
=> 2,
lpm_widthadr => 14,
lpm_numwordsr => 16384,
lpm_indata
=> “REGISTERED”,
lpm_addressr_control => “REGISTERED”,
lpm_init_file => “RAM_init”,
lpm_indata
=> “UNREGISTERED”,
)
port map (
Data
WrAddress
RdAddress
WrClock
WrClockEn
RdClock
RdClockEn
WE
Reset
Q
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
end struct;
36
Data,
WrAddress,
RdAddress,
WrClock,
WrClockEn,
RdClock,
RdClockEn,
WE,
Reset,
Q);
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
Random Access Memory (LPM_RAM_DQ)
library IEEE;
use IEEE.std_logic_1164.all;
LIBRARY lc5kmx;
USE lc5kmx.components.all;
entity tramdq16kx2 is
port (
Data
Address
Clock
ClockEn
WE
Reset
Q
end tramdq16kx2 ;
:
:
:
:
:
:
:
in std_logic_vector( 1 downto 0);
in std_logic_vector( 13 downto 0);
in std_logic;
in std_logic;
in std_logic;
in std_logic;
out std_logic_vector(1 downto 0));
architecture behave of tramdq16kx2 is
component L_RAMDQ
generic (
LPM_TYPE
: string := “LPM_RAM_DQ”;
LPM_WIDTH
: positive := 1;
LPM_WIDTHAD
: positive := 1;
LPM_NUMWORDS : positive := 2;
LPM_INDATA
: string :=”REGISTERED”;
LPM_OUTDATA
: string :=”UNREGISTERED”;
LPM_ADDRESS_CONTROL
: string :=”REGISTERED”;
LPM_INIT_FILE : string := “dummy”;
LPM_HINT
: string :=”UNUSED”);
port (
Data
: in std_logic_vector(LPM_WIDTH-1 downto 0);
Address : in std_logic_vector(LPM_WIDTHAD-1 downto 0);
Clock
: in std_logic := ‘0’;
ClockEn
: in std_logic := ‘0’;
WE
: in std_logic;
Reset
: in std_logic;
Q
: out std_logic_vector(LPM_WIDTH-1 downto 0));
end component ;
begin
U0: L_RAMDQ
generic map (
LPM_WIDTH
=> 2,
LPM_WIDTHAD
=> 14,
LPM_NUMWORDS => 16384,
LPM_ADDRESS_CONTROL => “UNREGISTERED”,
LPM_INIT_FILE => “RAM_init”,
LPM_OUTDATA
=> “UNREGISTERED”)
port map (
Data
=> Data,
37
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
Address
Clock
ClockEn
WE
Reset
Q
=>
=>
=>
=>
=>
=>
end behave;
38
Address,
Clock,
ClockEn,
WE,
Reset,
Q);
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
First-In-First-Out Memory (LPM_FIFO_DC)
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
LIBRARY lc5kmx;
USE lc5kmx.components.all;
entity tfifo4kx4 is
port (
Data
WrClock
WrEn
RdClock
RdEn
Reset
RPReset
Q
Full
Empty
AlmostFull
AlmostEmpty
end tfifo16kx1 ;
:
:
:
:
:
:
:
:
:
:
:
:
in std_logic_vector(3 downto 0);
in std_logic;
in std_logic;
in std_logic;
in std_logic;
in std_logic;
in std_logic;
out std_logic_vector(3 downto 0);
Out std_logic;
Out std_logic;
Out std_logic;
Out std_logic);
architecture struct of
tfifo4kx4
is
component L_FIFO
generic (
lpm_type
: string := “LPM_FIFO_DC”;
lpm_width
: integer := 1;
lpm_widthu
: integer := 1;
lpm_numwords : integer := 2;
lpm_amfull_flag: integer :=1;
lpm_amempty_flag: integer :=1;
lpm_hint
: string := “UNUSED”);
port (
Data
: in std_logic_vector (lpm_width-1 downto 0);
WrClock
: in std_logic;
WrEn
: in std_logic;
RdClock
: in std_logic;
RdEn
: in std_logic;
Reset
: in std_logic;
RPReset
: in std_logic;
Q
: out std_logic_vector (lpm_width-1 downto 0);
Full
: out std_logic;
Empty
: out std_logic;
AlmostFull
: out std_logic;
AlmostEmpty
: out std_logic);
end component ;
begin
U0: L_FIFO
39
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
generic map (LPM_WIDTH
=> 4,
LPM_WIDTHU
=> 12,
LPM_AMFULL_FLAG => 1,
LPM_AMEMPTY_FLAG => 1,
LPM_NUMWORDS => 4096)
port map (
Data
WrClock
WrEn
RdClock
RdEn
Reset
RPReset
Q
Full
Empty
AlmostFull
AlmostEmpty
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
end struct;
40
Data,
WrClock,
WrEn,
RdClock,
RdEn,
Reset,
RPReset,
Q,
FULL,
EMPTY,
AlmostFull,
AlmostEmpty );
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
Content Addressable Memory (LPM_CAM)
library IEEE;
use IEEE.std_logic_1164.all;
LIBRARY lc5kmx;
USE lc5kmx.components.all;
entity tcam128x48 is
port (
Data
WrAddress
ClockEn
Clock
We
EnMask
WrMask
WrDc
Reset
Address
Match
MulMatch
end tcam128x48 ;
:
:
:
:
:
:
:
:
:
:
:
:
in std_logic_vector(47 downto 0);
in std_logic_vector(6 downto 0);
in std_logic;
in std_logic;
in std_logic;
in std_logic;
in std_logic;
in std_logic;
in std_logic;
out std_logic_vector(6 downto 0);
Out std_logic;
Out std_logic);
architecture struct of
tcam128x48 is
component L_CAM
generic (
lpm_type
: string := “LPM_CAM”;
lpm_width
: integer := 1;
lpm_numwords
: integer := 1;
lpm_widthad
: integer := 1;
lpm_init_file
: string := “dummy”;
lpm_init_flag
: integer := 0;
lpm_hint
: string := “UNUSED”);
port(
Data
: in std_logic_vector(lpm_width-1 downto 0);
WrAddress
: in std_logic_vector(6 downto 0);
ClockEn
: in std_logic;
Clock
: in std_logic;
WE
: in std_logic;
EnMask
: in std_logic;
WrMask
: in std_logic;
WrDC
: in std_logic;
Reset
: in std_logic;
Address
: out std_logic_vector(6 downto 0);
Match
: Out std_logic;
MulMatch
: Out std_logic);
end component ;
begin
U0: L_CAM
generic map (LPM_WIDTH
=> 48,
41
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
LPM_WIDTHAD
LPM_NUMWORDS
LPM_INIT_FILE
LPM_INIT_FLAG
port map (
Data
WrAddress
ClockEn
Clock
WE
EnMask
WrMask
WrDC
Reset
Address
Match
MulMatch
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
end struct;
42
7,
128,
“CAM_init”,
1)
Data,
WrAddress,
ClockEn,
Clock,
We,
EnMask,
Wrmask,
WrDc,
Reset,
Address,
Match,
MulMatch);
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
Read-Only Memory (LPM_ROM)
library IEEE;
use IEEE.std_logic_1164.all;
LIBRARY lc5kmx;
USE lc5kmx.components.all;
entity trom16kx2 is
port (
Address
OutClock
OutClockEn
Reset
Q
end trom16kx2 ;
:
:
:
:
:
in std_logic_vector( 13 downto 0);
in std_logic;
in std_logic;
in std_logic;
out std_logic_vector(1 downto 0));
architecture struct of trom16kx2 is
component L_ROM
generic (
lpm_type
lpm_width
lpm_numwords
lpm_widthad
lpm_outdata
lpm_address_control
lpm_init_file
lpm_hint
:
:
:
:
:
:
string := “LPM_ROM”;
integer := 1;
integer := 2;
integer := 1;
string := “UNREGISTERED”;
string := “REGISTERED”;
: string := “dummy”;
: string := “UNUSED”);
port (
Address : in
OutClock
OutClockEn
Reset
Q
: out
end component ;
std_logic_vector (lpm_widthad-1 downto 0);
: in std_logic;
: in std_logic;
: in std_logic;
std_logic_vector (lpm_width-1 downto 0));
attribute syn_black_box: boolean;
attribute syn_black_box of L_ROM: component is true;
begin
U0: L_ROM
generic map (
LPM_WIDTH
=> 2,
LPM_WIDTHAD
=> 14,
LPM_NUMWORDS => 16384,
LPM_OUTDATA
=> “REGISTERED”,
LPM_ADDRESS_CONTROL => “REGISTERED”,
LPM_INIT_FILE => “ROM_init”)
port map (
Address
=> Address,
OutClock
=> OutClock,
43
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
OutClockEn
Reset
Q
=> OutClockEn,
=> Reset,
=> Q);
end struct;
44
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
Appendix C. Initialization File Usage Guide
Introduction
The initialization file is a text file primarily used for preloading user-specified data into the memory array. This file is
mainly used for configuring ROM, but is optional for dual-port, pseudo dual port and single port SRAM, FIFO and
CAM modes.
Figure 6 is an example of an initialization file.
Figure 6. Sample Initialization File (20x32)
11111111111111110000000000010001
11111111111111100000000000010000
11111111111111011111111111111111
11111111111110111111111111111111
11111111111110101111111111111111
11111111111110011111111111111111
11111111111110001111111111111111
11111111111101111111111111110001
11111111111101101111111111110001
11111111111101001111111111110001
11111111111100110000000000100100
11111111111100100000000000100100
11111111111100010000000000100100
11111111111100000000000000100100
11111111111011110000000000100100
11111111111011010000000000000110
00000000000100010000000000000110
00000000000100000000000000000110
00000000000011110000000000000110
00000000000011100000000000000110
Address locations are numbered sequentially from 0 to lpm_numwords -1. The first or topmost entry corresponds
to the initialization data at address 0, and the last entry to address LPM_NUMWORDS-1. Bits are read right to left,
starting from the LSB to MSB. In the initialization file shown above for example, the top right-most bit correlates to
bit 0 of Address 0, while the bottom left-most bit correlates to bit 31 of Address 19. Initialization data can only be
entered in binary format.
Data depth and width are defined by the size of the user instantiated memory. The number of rows corresponds to
the number of address locations in the array (depth), and the number of columns matches the data width. Inputs
are specified in binary format, and each bit can either be a 1, 0, X (don’t care) or a U (undefined). Note that ‘X’ and
‘U’ inputs only apply for CAM. Excess bits and/or undefined characters in the initialization file are flagged as errors
during compilation.
An initialization file can have any name, but it should match the filename specified in the HDL source file. The file
cannot have a trailing three-character extension or file type. Initialization filenames with trailing extensions are not
valid, and therefore flagged as errors during compilation.
To preload memory using an initialization file, simply define the ‘lpm_init_file’ parameter in your top-level HDL
source file and specify the initialization file name. Figure 7 shows an example of a VHDL ROM module using an initialization file. In this case, the ‘lpm_init_file: string: = “ROM_init”;’ declaration was added into the component
instantiation. The same concept applies for Verilog designs. The example shown in Figure 8 has been modified to
include the ‘defparam U0.lpm_init_file=”init1”;’ declaration.
45
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
Figure 7. VHDL ROM instantiation with lpm_init_file defined
entity trom512x121 is
port (
Address
OutClock
OutClockEn
Reset
Q
end trom512x121 ;
:
:
:
:
:
in std_logic_vector( 8 downto 0);
in std_logic;
in std_logic;
in std_logic;
out std_logic_vector(120 downto 0));
architecture struct of trom512x121 is
component L_ROM
generic (
lpm_type
lpm_width
lpm_numwords
lpm_widthad
lpm_outdata
lpm_address_control
lpm_init_file
lpm_hint
port (
Address
OutClock
OutClockEn
Reset
Q
end component ;
:
:
:
:
:
:
:
:
:
:
:
:
:
string
integer
integer
integer
string
string
string
string
in
in
in
in
out
:=
:=
:=
:=
:=
:=
:=
:=
“LPM_ROM”;
1;
1;
1;
“UNREGISTERED”;
“REGISTERED”;
“ROM_init”;
“UNUSED”);
std_logic_vector (lpm_widthad-1 downto 0);
std_logic;
std_logic;
std_logic;
std_logic_vector (lpm_width-1 downto 0));
begin
U0: L_ROM
generic map (
LPM_WIDTH
=> 121,
LPM_WIDTHAD
=> 9,
LPM_NUMWORDS => 512,
LPM_OUTDATA
=> “REGISTERED”,
LPM_ADDRESS_CONTROL => “REGISTERED”,
LPM_INIT_FILE => “ROM_init”)
port map (
Address
=> Address,
OutClock
=> OutClock,
OutClockEn
=> OutClockEn,
Reset
=> Reset,
Q
=> Q);
end struct;
46
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
Figure 8. Verilog ROM instantiation with lpm_init_file defined
module test_rom512x121(
Q,
Address,
OutClock,
OutClockEn,
Reset);
output [120:0] Q;
input [8:0] Address;
input OutClock,OutClockEn,Reset;
L_ROM
U0(.Q(Q),.Address(Address),.OutClock(OutClock),.OutClockEn(OutClockEn),.Reset(Reset));
defparam
defparam
defparam
defparam
defparam
U0.lpm_width=121;
U0.lpm_widthad=9;
U0.lpm_numwords=512;
U0.lpm_outdata=”UNREGISTERED”;
U0.lpm_init_file=”init1”;
endmodule
module L_ROM(
Q,
Address,
OutClock,
OutClockEn,
Reset);
parameter
parameter
parameter
parameter
parameter
parameter
parameter
parameter
lpm_type = “LPM_ROM”;
lpm_width
= 1;
lpm_numwords = 1;
lpm_widthad
= 1;
lpm_outdata
= “UNREGISTERED”;
lpm_address_control = “REGISTERED”;
lpm_hint = “UNUSED”;
lpm_init_file=”dummy”;
output [lpm_width-1:0] Q;
input [lpm_widthad-1:0] Address;
input OutClock,OutClockEn,Reset;
endmodule // lpm_rom
For additional examples, refer to Appendices A and B.
47
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
Common Mistakes and Error Messages
Most initialization file issues are related to the memory file size or the filename format. The most common errors in
generating initialization files are:
1. Specifying an incorrect depth (number of rows) or width (number of columns)
2. Using invalid filenames (i.e. CAM_init.dat)
3. Using invalid characters (i.e. Use of any other character aside from a ‘1’, ‘0’ or ‘X’)
Below are some sample error messages that can help diagnose an initialization file problem. For reference, the following example uses a 96X128 CAM.
Figure 9 shows the error generated when the initialization file data width exceeds the predefined CAM width.
Because the CAM configuration width is set at 96, and the initialization file data has 98 bits, an error is generated
by the compiler.
Figure 9. Error: Data width is greater than the defined memory width
Figure 10 shows an error generated by the compiler when the initialization file data exceeds the total word count in
the CAM array. By definition, the CAM can only hold 128 words. Since the initialization file has 129 words (rows),
the compiler automatically errors out.
48
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
Figure 10. Error: Data depth is greater than the defined number of words
Figure 11 illustrates the error generated when invalid characters are detected in the initialization file. In this case,
invalid ASCII characters are inserted into the file (not shown) to show the error message.
Figure 11. Error: Invalid characters are used in the initialization file
The compiler also flags incorrectly named initialization files. Figure 12 shows an example where the initialization
file is associated with a three-character file extension. In this case the lpm_init_file = “CAM_init.dat” definition is
included in the source file. Upon compilation, the compiler is unable to resolve the ‘.DAT’ file extension and errors
out.
49
Using Memory in
ispXPLD 5000MX Devices
Lattice Semiconductor
Figure 12. Error: Initialization file is associated with a three-character extension or file
Technical Support Assistance
Hotline: 1-800-LATTICE (North America)
+1-408-826-6002 (Outside North America)
e-mail: [email protected]
Internet: www.latticesemi.com
50