A generic SystemVerilog ROM with content initialisation from a file
This post describes how to code a technology-independent SystemVerilog ROM memory with parameters to set the data width and memory depth (i.e. number of locations) and the use of an external file for setting the initial contents.
- module spROM
- #(parameter int unsigned width = 8,
- parameter int unsigned depth = 8,
- parameter intFile = "dummy.mif",
- localparam int unsigned addrBits = $clog2(depth)
- )
- (
- input logic CLK,
- input logic [addrBits-1:0] ADDRESS,
- output logic [width-1:0] DATAOUT
- );
- logic [width-1:0] rom [0:depth-1];
- // initialise ROM contents
- initial begin
- $readmemh(intFile,rom);
- end
- always_ff @ (posedge CLK)
- begin
- DATAOUT <= rom[ADDRESS];
- end
- endmodule : spROM
Listing 2
The $readmemh task reads a hex file to the rom array which is effectively the memory. The name of the hex file is passed to the
spROM module as a parameter. The number of bits required for the address bus is calculated from the depth parameter using the $clog2 function.
The spROM module can then be instantiated in a higher-level SystemVerilog file like this:
- module top_mem (
- input logic CLK,
- input logic [3:0] ADDRESS,
- output logic [15:0] DATA
- );
- /*----------------------------------------------------
- Single port ROM: 16 words x 16bit
- ----------------------------------------------------*/
- spROM #(16, 16, "my_init_file.mif") U0 (
- .CLK (CLK ),
- .ADDRESS (ADDRESS ),
- .DATAOUT (DATA )
- );
- endmodule : top_mem
Listing 3
A zip archive that includes the SystemVerilog source files and an example memory initialisation file is available here.