📖 Scenario: You are designing a simple Read-Only Memory (ROM) module in VHDL for a small digital system. The ROM will store fixed 8-bit data values that do not change during operation.
🎯 Goal: Build a ROM module using a constant array in VHDL that outputs 8-bit data based on a 3-bit address input.
📋 What You'll Learn
Create a constant array to hold 8-bit data values for 8 addresses
Define an input signal addr of 3 bits to select the ROM location
Define an output signal data_out of 8 bits to output the stored data
Use the constant array to assign the output data based on the input address
💡 Why This Matters
🌍 Real World
ROM modules are used in digital systems to store fixed data like lookup tables, font data, or microcode that does not change during operation.
💼 Career
Understanding how to implement ROM using constant arrays in VHDL is essential for FPGA and ASIC designers working on embedded systems and hardware design.
Progress0 / 4 steps
1
Create the ROM data constant array
Create a constant array called rom_data of type array (0 to 7) of std_logic_vector(7 downto 0) with these exact values: "00000001", "00000010", "00000100", "00001000", "00010000", "00100000", "01000000", "10000000"
VHDL
Hint
Use a VHDL package to declare the constant array with the exact values given.
2
Define the ROM entity with address and data signals
Create an entity called rom with an input port addr of type std_logic_vector(2 downto 0) and an output port data_out of type std_logic_vector(7 downto 0).
VHDL
Hint
Define the entity ports exactly as specified for address and data output.
3
Implement the architecture to output ROM data
Create an architecture called behavior for the rom entity. Use the constant array rom_data from rom_pkg to assign data_out based on the integer value of addr. Use to_integer(unsigned(addr)) to convert the address.
VHDL
Hint
Use the numeric_std package to convert addr to integer and assign data_out from rom_data.
4
Test the ROM output with a simple process
Add a process inside the architecture behavior that prints the value of data_out for each address from 0 to 7. Use a loop with variable i from 0 to 7, assign addr to std_logic_vector of i, wait for 10 ns, and print data_out using report statement.
VHDL
Hint
Use a process with a for loop to assign addr and print data_out with report.
Practice
(1/5)
1. What is the main purpose of using a constant array to implement ROM in VHDL?
easy
A. To generate random data values dynamically
B. To create a writable memory block for data storage
C. To perform arithmetic operations on data
D. To store fixed data that can be read by address during simulation or synthesis
Solution
Step 1: Understand ROM functionality
ROM (Read-Only Memory) stores fixed data that does not change during operation.
Step 2: Role of constant array in VHDL
A constant array holds fixed values accessible by address, perfect for ROM implementation.
Final Answer:
To store fixed data that can be read by address during simulation or synthesis -> Option D
Quick Check:
ROM = fixed data storage [OK]
Hint: ROM stores fixed data accessed by address only [OK]
Common Mistakes:
Confusing ROM with writable RAM
Thinking ROM can be changed during runtime
Using variable arrays instead of constant arrays
2. Which of the following is the correct way to declare a ROM using a constant array of 8-bit std_logic_vector in VHDL?
easy
A. constant ROM : array (0 to 3) of std_logic_vector(7 downto 0) := (x"01", x"02", x"04", x"08");
B. constant ROM : array (0 to 3) of std_logic_vector(7 downto 0) := ("0000001", "0000010", "0000100", "0001000");
C. constant ROM : array (0 to 3) of std_logic_vector(7 downto 0) := ("x01", "x02", "x04", "x08");
D. constant ROM : array (0 to 3) of std_logic_vector(7 downto 0) := (1, 2, 4, 8);
Solution
Step 1: Check array declaration syntax
In VHDL, constant arrays must be declared with proper type and range, here 0 to 3 for 4 elements.
Step 2: Check value format for std_logic_vector
Values must be std_logic_vector literals; hex notation x".." is correct for 8-bit vectors.
Final Answer:
constant ROM : array (0 to 3) of std_logic_vector(7 downto 0) := (x"01", x"02", x"04", x"08"); -> Option A
Quick Check:
Hex literals with x".." for std_logic_vector [OK]
Hint: Use x".." for hex std_logic_vector constants [OK]
Common Mistakes:
Using double quotes for hex values incorrectly
Assigning integers directly to std_logic_vector
Incorrect array type or syntax
3. Given the following VHDL ROM declaration and read process, what is the output on data_out when addr = "10" (binary 2)?
constant ROM : array (0 to 3) of std_logic_vector(7 downto 0) := (x"0A", x"1B", x"2C", x"3D");
process(addr) begin
data_out <= ROM(to_integer(unsigned(addr)));
end process;
medium
A. x"2C"
B. x"1B"
C. x"0A"
D. x"3D"
Solution
Step 1: Convert address to integer
Address "10" in binary equals decimal 2.
Step 2: Access ROM at index 2
ROM(2) is x"2C" as per the constant array declaration.
Final Answer:
x"2C" -> Option A
Quick Check:
addr 2 accesses ROM(2) = x"2C" [OK]
Hint: Convert binary address to integer to index ROM [OK]
Common Mistakes:
Confusing binary "10" as decimal 10
Using unsigned conversion incorrectly
Accessing wrong ROM index
4. Identify the error in this VHDL ROM constant array declaration:
constant ROM : array (0 to 3) of std_logic_vector(7 downto 0) := (x"01", x"02", x"03");
medium
A. Hex values must be in single quotes, not double quotes
B. ROM array size does not match the number of elements assigned
C. std_logic_vector cannot be used in constant arrays
D. ROM must be declared as a variable, not constant
Solution
Step 1: Check array range and element count
Array declared from 0 to 3 means 4 elements expected.
Step 2: Count assigned elements
Only 3 elements are assigned, causing a size mismatch error.
Final Answer:
ROM array size does not match the number of elements assigned -> Option B
Quick Check:
Array size must equal element count [OK]
Hint: Match array range with number of elements exactly [OK]
Common Mistakes:
Assigning fewer elements than declared range
Misusing quotes for hex literals
Thinking constants can be variables
5. You want to create a 16-word ROM with 4-bit addresses and 8-bit data using a constant array in VHDL. Which of the following code snippets correctly implements this ROM and reads data based on the address input addr?
hard
A. constant ROM : array (0 to 15) of std_logic_vector(7 downto 0) := (others => (others => '0'));
process(addr) begin
data_out <= ROM(addr);
end process;
B. constant ROM : array (0 to 15) of std_logic_vector(7 downto 0);
process(addr) begin
data_out <= ROM(addr);
end process;
C. constant ROM : array (0 to 15) of std_logic_vector(7 downto 0) := (x"00", x"01", x"02", x"03", x"04", x"05", x"06", x"07", x"08", x"09", x"0A", x"0B", x"0C", x"0D", x"0E", x"0F");
process(addr) begin
data_out <= ROM(to_integer(unsigned(addr)));
end process;
D. constant ROM : array (0 to 15) of std_logic_vector(7 downto 0) := (x"00", x"01", x"02", x"03");
process(addr) begin
data_out <= ROM(to_integer(unsigned(addr)));
end process;
Solution
Step 1: Check ROM declaration size and initialization
ROM must have 16 elements (0 to 15) each 8-bit wide, fully initialized.
Step 2: Verify address conversion and data read
Address is 4-bit std_logic_vector, converted to integer with to_integer(unsigned(addr)) to index ROM correctly.
Step 3: Validate code correctness
constant ROM : array (0 to 15) of std_logic_vector(7 downto 0) := (x"00", x"01", x"02", x"03", x"04", x"05", x"06", x"07", x"08", x"09", x"0A", x"0B", x"0C", x"0D", x"0E", x"0F");
process(addr) begin
data_out <= ROM(to_integer(unsigned(addr)));
end process; correctly initializes all 16 elements and reads data using proper address conversion.
Final Answer:
constant ROM : array (0 to 15) of std_logic_vector(7 downto 0) := (x"00", x"01", x"02", x"03", x"04", x"05", x"06", x"07", x"08", x"09", x"0A", x"0B", x"0C", x"0D", x"0E", x"0F");
process(addr) begin
data_out <= ROM(to_integer(unsigned(addr)));
end process; -> Option C
Quick Check:
Full initialization + correct address indexing = constant ROM : array (0 to 15) of std_logic_vector(7 downto 0) := (x"00", x"01", x"02", x"03", x"04", x"05", x"06", x"07", x"08", x"09", x"0A", x"0B", x"0C", x"0D", x"0E", x"0F");
process(addr) begin
data_out <= ROM(to_integer(unsigned(addr)));
end process; [OK]
Hint: Initialize all ROM elements and convert address to integer [OK]
Common Mistakes:
Not initializing all ROM elements
Using addr directly without conversion
Declaring ROM without initialization
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.