Concept Flow - ROM (Read-Only Memory) in Verilog
Start
Address Input
ROM Lookup
Output Data
End
The ROM takes an address input, looks up the stored data at that address, and outputs the data without changing it.
module rom_example( input [1:0] addr, output reg [3:0] data ); always @(*) begin case(addr) 2'b00: data = 4'hA; 2'b01: data = 4'h3; 2'b10: data = 4'hF; 2'b11: data = 4'h0; default: data = 4'h0; endcase end endmodule
| Step | Input addr | Condition checked | Data assigned | Output data |
|---|---|---|---|---|
| 1 | 2'b00 | addr == 2'b00 | 4'hA | 1010 |
| 2 | 2'b01 | addr == 2'b01 | 4'h3 | 0011 |
| 3 | 2'b10 | addr == 2'b10 | 4'hF | 1111 |
| 4 | 2'b11 | addr == 2'b11 | 4'h0 | 0000 |
| 5 | 2'b00 | addr == 2'b00 | 4'hA | 1010 |
| Variable | Start | Step 1 | Step 2 | Step 3 | Step 4 | Step 5 |
|---|---|---|---|---|---|---|
| addr | undefined | 2'b00 | 2'b01 | 2'b10 | 2'b11 | 2'b00 |
| data | undefined | 4'hA | 4'h3 | 4'hF | 4'h0 | 4'hA |
ROM in Verilog stores fixed data accessed by address. Use combinational always block with case statement. Input: address; Output: stored data. Data does not change during simulation. Outputs update immediately on address change.
data_out when addr = 2'b10?
module rom_example(input [1:0] addr, output reg [7:0] data_out);
always @(*) begin
case(addr)
2'b00: data_out = 8'h1A;
2'b01: data_out = 8'h2B;
2'b10: data_out = 8'h3C;
2'b11: data_out = 8'h4D;
default: data_out = 8'h00;
endcase
end
endmodulemodule rom_bug(input [1:0] addr, output reg [7:0] data_out);
reg [7:0] rom_mem [0:3];
initial begin
rom_mem[0] = 8'hAA;
rom_mem[1] = 8'hBB;
rom_mem[2] = 8'hCC;
rom_mem[3] = 8'hDD;
end
always @(*) begin
data_out = rom_mem[addr];
end
endmodulePass the test and this pattern moves unknown