How to Model ROM in Verilog: Syntax and Example
To model
ROM in Verilog, you can use a case statement inside a combinational always block or initialize a reg array with fixed values. The ROM outputs stored data based on the input address without writing capability.Syntax
There are two common ways to model ROM in Verilog:
- Using a case statement: Define an
always @(*)block that outputs data based on the input address. - Using a memory array: Declare a
regarray initialized with fixed values and read from it using the address.
Both methods create read-only memory by not allowing writes.
verilog
module rom_case(
input wire [3:0] addr,
output reg [7:0] data
);
always @(*) begin
case(addr)
4'd0: data = 8'hA1;
4'd1: data = 8'hB2;
4'd2: data = 8'hC3;
4'd3: data = 8'hD4;
default: data = 8'h00;
endcase
end
endmoduleExample
This example shows a ROM modeled as a memory array initialized with fixed values. The output data changes based on the input addr. This simulates a 16x8 ROM.
verilog
module rom_memory(
input wire [3:0] addr,
output reg [7:0] data
);
reg [7:0] rom [0:15];
initial begin
rom[0] = 8'h10;
rom[1] = 8'h20;
rom[2] = 8'h30;
rom[3] = 8'h40;
rom[4] = 8'h50;
rom[5] = 8'h60;
rom[6] = 8'h70;
rom[7] = 8'h80;
rom[8] = 8'h90;
rom[9] = 8'hA0;
rom[10] = 8'hB0;
rom[11] = 8'hC0;
rom[12] = 8'hD0;
rom[13] = 8'hE0;
rom[14] = 8'hF0;
rom[15] = 8'hFF;
end
always @(*) begin
data = rom[addr];
end
endmoduleCommon Pitfalls
Common mistakes when modeling ROM in Verilog include:
- Trying to write to ROM memory, which should be read-only.
- Not initializing the memory array, causing undefined outputs.
- Using blocking assignments (
=) incorrectly in combinational blocks instead of non-blocking (<=) or vice versa. - Forgetting to cover all address cases in a
casestatement, which can cause latches.
verilog
/* Wrong: Missing default case causes latch */ always @(*) begin case(addr) 4'd0: data = 8'hAA; 4'd1: data = 8'hBB; // Missing default endcase end /* Right: Include default to avoid latch */ always @(*) begin case(addr) 4'd0: data = 8'hAA; 4'd1: data = 8'hBB; default: data = 8'h00; endcase end
Quick Reference
Tips for modeling ROM in Verilog:
- Use
regarrays withinitialblocks for fixed data. - Use
always @(*)withcasefor small ROMs. - Never include write logic to keep ROM read-only.
- Always cover all address cases to avoid unintended latches.
Key Takeaways
Model ROM in Verilog using a case statement or initialized memory array without write logic.
Always initialize ROM contents to avoid undefined outputs.
Cover all address cases in combinational logic to prevent latches.
ROM outputs data based solely on input address and does not change during simulation.
Use non-blocking assignments carefully in combinational blocks to ensure correct behavior.