📖 Scenario: You are designing a simple digital system that needs to store fixed data values. This data will not change during operation, so you decide to use a Read-Only Memory (ROM) module in Verilog to hold these values.
🎯 Goal: Build a ROM module in Verilog that stores 8 fixed 4-bit values. You will create the ROM data, set up the address input, implement the ROM logic, and finally output the stored data based on the address.
📋 What You'll Learn
Create a ROM data array with 8 entries, each 4 bits wide, with exact values
Create an address input variable to select which data to output
Implement the ROM logic using a case statement to output data based on the address
Print the output data for a given address
💡 Why This Matters
🌍 Real World
ROM modules are used in digital systems to store fixed data like lookup tables, font data, or configuration constants that do not change during operation.
💼 Career
Understanding ROM design in Verilog is important for hardware engineers working on FPGA or ASIC designs where fixed data storage is required.
Progress0 / 4 steps
1
Create ROM data array
Create a reg [3:0] rom_data [0:7] array and initialize it with these exact values: 4'b1000, 4'b0111, 4'b0110, 4'b0101, 4'b0100, 4'b0011, 4'b0010, 4'b0001.
Verilog
Hint
Use a reg array with 8 elements, each 4 bits wide. Initialize with the exact binary values in the order given.
2
Create address input
Create a reg [2:0] address variable to select the ROM data index.
Verilog
Hint
The address should be 3 bits wide to select 8 locations (0 to 7).
3
Implement ROM output logic
Create a reg [3:0] data_out and use a case statement inside an always @(*) block to assign data_out the value from rom_data at the given address.
Verilog
Hint
Use a combinational always block with a case statement to select the output based on address.
4
Display ROM output for a given address
Set address = 3'd3 and use $display to print data_out in binary format.
Verilog
Hint
Set the address to 3 and use $display to print the 4-bit output in binary.
Practice
(1/5)
1. What is the primary purpose of a ROM (Read-Only Memory) in Verilog?
easy
A. To store fixed data that cannot be changed during simulation or operation
B. To store data that can be written and read dynamically
C. To perform arithmetic operations
D. To generate clock signals
Solution
Step 1: Understand ROM functionality
ROM is designed to hold data that is fixed and cannot be modified during operation.
Step 2: Compare with other memory types
Unlike RAM, ROM data is read-only and does not support writing during runtime.
Final Answer:
To store fixed data that cannot be changed during simulation or operation -> Option A
Quick Check:
ROM = fixed data storage [OK]
Hint: ROM stores fixed data only, no writes allowed [OK]
Common Mistakes:
Confusing ROM with RAM (read-write memory)
Thinking ROM can perform operations
Assuming ROM generates signals
2. Which of the following is the correct way to declare a ROM using an array and initial block in Verilog?
easy
A. integer rom_mem; always @(posedge clk) rom_mem = 8'hAA;
5. You want to implement a 4-word ROM in Verilog that outputs the square of the address value (0, 1, 4, 9). Which of the following code snippets correctly implements this ROM?
hard
A. always @(addr) begin case(addr) 2'b00: data_out=8'd0; 2'b01: data_out=8'd1; 2'b10: data_out=8'd4; 2'b11: data_out=8'd9; default: data_out=8'd0; endcase end
B. reg [7:0] rom [0:3]; initial begin rom[0]=8'd0; rom[1]=8'd1; rom[2]=8'd4; rom[3]=8'd9; end always data_out = rom[addr];
C. reg [7:0] rom [0:3]; assign rom[0]=0; assign rom[1]=1; assign rom[2]=4; assign rom[3]=9; assign data_out=rom[addr];
D. reg [7:0] rom [0:3]; always @(posedge clk) begin rom[0]<=0; rom[1]<=1; rom[2]<=4; rom[3]<=9; end assign data_out=rom[addr];
Solution
Step 1: Analyze each code snippet for ROM implementation
reg [7:0] rom [0:3]; initial begin rom[0]=8'd0; rom[1]=8'd1; rom[2]=8'd4; rom[3]=8'd9; end always @(*) data_out = rom[addr]; lacks module and always block structure; data_out assignment is incomplete. always @(addr) begin case(addr) 2'b00: data_out=8'd0; 2'b01: data_out=8'd1; 2'b10: data_out=8'd4; 2'b11: data_out=8'd9; default: data_out=8'd0; endcase end uses a case statement to output fixed squares based on addr, which is a valid ROM implementation. reg [7:0] rom [0:3]; assign rom[0]=0; assign rom[1]=1; assign rom[2]=4; assign rom[3]=9; assign data_out=rom[addr]; tries to assign values to wire array elements, which is illegal. reg [7:0] rom [0:3]; always @(posedge clk) begin rom[0]<=0; rom[1]<=1; rom[2]<=4; rom[3]<=9; end assign data_out=rom[addr]; tries to assign ROM values inside a clocked always block, which is not suitable for ROM initialization.
Step 2: Confirm correct ROM behavior
always @(addr) begin case(addr) 2'b00: data_out=8'd0; 2'b01: data_out=8'd1; 2'b10: data_out=8'd4; 2'b11: data_out=8'd9; default: data_out=8'd0; endcase end correctly outputs squares for each address using a combinational case statement, matching ROM behavior.
Final Answer:
always @(addr) begin case(addr) 2'b00: data_out=8'd0; 2'b01: data_out=8'd1; 2'b10: data_out=8'd4; 2'b11: data_out=8'd9; default: data_out=8'd0; endcase end -> Option A
Quick Check:
ROM as combinational case statement = always @(addr) begin case(addr) 2'b00: data_out=8'd0; 2'b01: data_out=8'd1; 2'b10: data_out=8'd4; 2'b11: data_out=8'd9; default: data_out=8'd0; endcase end [OK]
Hint: Use case statement for fixed ROM outputs [OK]
Common Mistakes:
Assigning to wire arrays
Initializing ROM inside clocked always block
Not using combinational logic for ROM output
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.