Lab 6: Moving Memory
The purpose of this lab is to give you experience working with both read-only and random-access memory. Reading and writing from memory is a multi-step process and requires setting signals in the proper order and giving the memory sufficient time to respond to the signals.
- Create a new project in a new folder for lab 6 (e.g. romtest).
Create an MIF file for your ROM that has 16 words of 8 bits each. Load
the memory with a set of patterns. You can do this within Quartus or
using any text editor. The format is simple: define the size and radix
of the addresses and data, then define the memory contents. The
example below defines a 16-element memory with 4-bits in each memory
location. Note how the last 8 elements are defined in a single
statement using a range of addresses.
-- program memory file DEPTH = 16; WIDTH = 4; ADDRESS_RADIX = HEX; DATA_RADIX = BIN; CONTENT BEGIN 0 : 1010; 1 : 0101; 2 : 0010; 3 : 0001; 4 : 0000; 5 : 1000; 6 : 0100; 7 : 0010; [8..F] : 1111; -- fill A0 to A1 with all 1s END
- Using the Tools:MegaWizard Plug0in Manager, create a ROM that has 16 words of 8 bits each. We are customizing an existing Megafunction. This will create a VHDL file from which we can copy the component and port map statements. When you are done, open the file and look at it. Note how the generic statements define the size and functionality of the memory circuit in the port map statement.
- Create a top-level VHDL file for your project (e.g. romtest). The entity should have a clock, reset, and an 8-bit std_logic_vector output port. Copy the component statement from the ROM VHDL file and put it in your architecture header section. Copy the port map statement from the ROM VHDL file and put it in your architecture body. Be sure to include the generic parts of these statements in both cases.
- Add internal signals for the ROM address (4-bit unsigned), ROM data (8-bit std_logic_vector), a wire the same size as the ROM data (8-bit std_logic_vector), a 2-bit counter (2-bit unsigned), and a state variable (2-bit std_logic_vector).
- In the ROM port map statement, link the ROM wire to the ROM output (q), link the ROM address variable to the address input, and link the clock signal to the clock input.
Make a process statement that is sensitive to the clock and reset
signals. In the reset case, set the ROM address variable to "0000",
set the counter variable to "00", and set the state to "00".
In the rising edge case, make a state machine with 4 states. The circuit should stay in state 0, incrementing the counter each time, until the counter reaches 3. Then it should move to state "01". In state "01" the circuit should move to state "10". In state "10" the circuit should assign the value on the ROM wire to the ROM data signal, increment the ROM address, and move to state "11". State "11" should move to state "01".
- Outside the process, make a concurrent signal assignment that assigns the ROM data to the output port signal.
Compile and simulate your circuit. You do not need to explicitly make
the netlist since the circuit is all VHDL. Just compile and then
When you simulate the circuit, use a clock signal that has a period of at least 100ps.
When you have completed the lab assignment, go ahead and get started on the current project.