enso:
That utility program for which I posted the source, Bin2Hex.c, and you got running on your Linux development system is all that you need. The following few code fragments illustrate the way that Verilog will automatically initialize a Block RAM during synthesis.
The following code fragment shows the parameter declaration that sets the file name of the ASCII Hex memory initialization file.
Code:
parameter pBootROM_File = "M65C02_Tst3.txt"
The following code fragment shows the declarations that determine the depth and width of the Block RAM. A parameter,
pROM_AddrWidth (11), determines the size of the address variable and the depth of the ROM,
Boot, itself. The width of the ROM and the output data signal are not parameterized, and are set to 8 bits. You can use a similar approach and set your ROM depth using a constant or as a parameter.
Code:
reg WE_Boot; // Write Enable for the Boot/Monitor ROM
reg [(pROM_AddrWidth-1):0] iAO; // Internal address pipeline register
reg [7:0] Boot [((2**pROM_AddrWidth)-1):0]; // Boot ROM/RAM (2k x 8)
reg [7:0] Boot_DO; // Boot/Monitor ROM output data (absorbed)
The following code fragment demonstrates how to get the synthesizer to generate a block RAM. In this case, the synthesizer generated a single block RAM, but simply changing the parameter
pROM_AddrWidth will let the synthesizer automatically aggregate as many block RAMs as needed to satisfy the specification. The
initial statement's
$readmemh function is a Verilog system function that is recognized by the synthesizer. It informs the synthesizer that the memory
Boot should be initialized with the values represented in ASCII hexadecimal in the file
pBootROM.
Code:
initial
$readmemh(pBootROM_File, Boot, 0, ((2**pROM_AddrWidth)-1));
always @(posedge Clk)
begin
if(WE_Boot)
Boot[iAO] <= #1 DO;
Boot_DO <= #1 Boot[iAO];
end
The following is a small snapshot of the memory initialization file. The first opcode, 0x
4C, is an absolute jump to 0x
F838.
Code:
4C
38
F8
3C
F8
40
F8
00
One reason to use this approach is that the other way to initialize memories using instantiation and initial statements within the instantiation is very tedious. The synthesizer essentially does that operation automatically using the technique demonstrated above.
Hope this helps.