Applications 8
A random access memory is an address based data storage block, with a highly regular structure, which may be logically defined either as a bidimensional array of bits, or a unidimensional list of data words. Each row of the array, or each item of the list has a unique address. The addresses form a contiguous set of integers, starting from zero and running up to the highest address which defines the size of the address space, usually a power of 2. The memory capacity is therefore the number of address locations, N, times the width of the memory location (or of the memory word), W. These two numbers are the main parameters of any memory:
- N - the number of address locations, also the number of words;
- W - the number of bits for each location, or the data word width;
The storage capacity is N x W bits, but the memory capacity may also be given in bytes.
Being a vector of words or a bidimensional array of bits, the memory could be described using a single bidimensional variable, usually declared as
reg [W-1: 0] memory [0: N-1];
Memories can also be classified by their synchronous or asynchronous character:
- asynchronous - reading is done as soon as the order is presented;
- synchronous - all operations are synchronized by one of the clock signal fronts.
For physical implementation considerations, writing is always synchronous.
Exercise 1
ROM - Read-Only Memory
Memory initialization task
Memory arrays may be initialized with predefined values from a text file using verilog system tasks $readmemb and $readmemh. $readmemb reads predefined values given in binary, while $readmemh is used if values are given in hexadecimal. These verilog system tasks have two mandatory arguments and two optional arguments, in the following order:
- initialization filename, given as a string (between double quotes)
- the memory array variable name
- the start address (optional)
- the end address (optional)
If the start and end addresses are not given, the memory array is initialized from the first address (address zero) until the last address or until the end of initialization file is reached.
If the memory initialization file, meminit.txt, resides in the project's folder, and the memory array to be initialized is mem inside the memory instance dut, the testbench may initialize the memory right at the beginning of the simulation:
initial $readmemb("../../meminit.txt", dut.mem);
If the initialization is intended to be done for the implemented memory, the initialization process must be placed inside the memory module, in which case the memory array name is just the variable array to be initialized:
initial $readmemb("../../meminit.txt", mem);
Memory initialization file
The initialization file is a text file with values written in binary (using 0 and 1 symbols) or in hexadecimal (using digits and letters a to f, either uppercase of lowercase). Values are separated by white spaces, tabs or newlines. Comments (started with // as in verilog) are ignored. An example of a binary initialization file:
// four values in binary text format
00000011
00001111
00111111
11111111
The same initialization sequence, but given as a hexadecimal text file:
// four values in hexadecimal text format
03
0f
3f
ff