You are correct that you should use $readmemh
inside an initial block. In order to make it so different instances of the module can have different initialization files, you should use a parameter like so:
parameter MEM_INIT_FILE = "";
...
initial begin
if (MEM_INIT_FILE != "") begin
$readmemh(MEM_INIT_FILE, ram);
end
end
The format is described in Section 21.4 of the IEEE1800-2012 specification; typically the file is just a bunch of lines containing hex numbers of the correct bit-length, like so:
0001
1234
3FFF
1B34
...
Note that there is no "0x" prefix and each line represents an adjacent address (or any separating whitespace). In the example above, $readmemh
would put 14'h0001
into ram[0]
, 14'h1234
into ram[1]
, 14'h3FFF
into ram[2]
and so on. You can also include comments in the hex file using //
or /* */
. Finally, you can use the @
symbol to designate an address for the following numbers to be located at, like so:
@0002
0101
0A0A
...
In the above file, ram[0]
and ram[1]
would be uninitialized and ram[2]
would get 14'h0101
. Those are all the major constructs of the hex file format, though you can also use _
, x
and z
as you would in other Verilog numbers and theres a few more rules you can read in the section sited above.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…