By: Ramkrishna Swamy, Maziyar Khorasani, Yongjie Liu,
Rejean Lau
Through the LogiCORE module, a Single-Port Block Memory can be generated. This on FPGA memory supports all three Virtex-II write mode options: Read-After-Write, Read-Before-Write and No-Read-On-Write. Also it supports memory depths ranging up to 1M words for Virtex-II. The core is delivered through the Xilinx CORE Generator System and below; the process to integrate it into your design and to use all of its many useful functions is outlined.
There
are several advantages to use the internal Block memory available, rather then
external memory. By using internal
memory, especially a core as in this case, the data can be statically loaded
during programming. The data can be
loaded by indicating a specific COE file during the module generation (more on
this later). This is very useful
for testing purposes, and it simplifies the working with memory process since no
external signals (i.e. pins from outside the FPGA) have to be referenced.
Adding
a Singe Port Block Memory:
To
simply add a Single-Port Block Memory module to your project, follow the below
steps:
1) Add a new source to your project, and select “Ip (CoreGen & Architecture Wizard)”. Provide a name to your core and press “ok”.
2) Under Memories & Storage Elements, RAMs& ROMs, select Single Port Block Memory. Click “next” then “finish.”
3) Provide a name, configure your block memory as you desire and click “Generate.” This will then add the core to your project.
a. Note: if you wish to statically load the block ram, simply select load init file, and select the desired COE file (more on COE files later).
4) Finally, after the core has been generated, you need to create a top level entity for this generated core and instantiate the core as a Black Box (otherwise Xilinx Synthesizer will keep looking for that module during synthesis)
5)
To create the top level entity for this block ram, simply copy and paste
the file: block_ram_toplevel.vhd.
To
create a COE file, that is a static file that you can load into your block ram,
simply follow the below procedure. To
begin however you need to know two pieces of information, the width (number of
bits across) and depth (number of rows down), of your memory.
For example, for a width of 8 bits and a depth of 8 (rows), the following
COE file can be used:
memory_initialization_radix=16;
memory_initialization_vector=
1A,
2B,
3C,
4D,
A1,
B2,
C3,
D4;
Now there are several pieces of information that users of COE file should be aware of. In this example:
1) The memory_initialization_radix (which is 16 in this case) simply identifies the base for the data. That is, whether it is in binary (2), hexadecimal (16), decimal (10), etc. So, you could load your data in almost any base format you want, as long as you specify it in this variable.
2) The memory_initialization_vector is the variable the stores the memory contents. So basically after the ‘=’ sign, anything that follows up to the ‘;’ is assumed to be loaded into the memory.
3) Notice a depth of 8 was achieved by having 8 hexadecimal items separated by commas.
4)
A width of 8 bits was achieved by using 2 hexadecimal values per row,
separated by columns (since each hex is 4 bits long).
Basically then, that is all the information you need to create a Single Port Block Memory and associated COE file. Good luck and have fun!