CS 232: Project #6

Project 6: Moving Memory

Due 6 April 2015

The purpose of this project is to learn how to make use of a ROM and a RAM memory so that you can use them as part of a larger CPU design.

This is the first part of three coordinated projects. You should demonstrate that you can read and write the memory properly by the end of the first week.


Tasks

The overall task is to create a circuit that has both a ROM and a RAM. Both the ROM and the RAM should be initialized from an MIF file. The circuit should first read through the RAM, displaying the contents on either the 7-segment displays or 8 LEDs. Then it should copy the contents of the ROM into the RAM and repeat the process. The initial contents of the RAM will be displayed only the first time it is read.

  1. Make a new project for lab 6 in a new folder. If you are going to use a 7-segment display to show the contents of memory, then copy over your 7-segment display driver in to the new folder. I'll refer to the project and top-level circuit as ramtest.
  2. Create an MIF file for your ROM that has 16 words of 8 bits each. Load the memory with a set of patterns.
  3. Using the Tools:MegaWizard Plug0in Manager, create a ROM that has 16 words of 8 bits each. Therefore, it should have 4 address bits and 8 data bits. I'll refer to this circuit as MemROM. Tell it to initialize the ROM using the MIF file you created in the prior step. This step will create a VHDL file that you will include in your project.
  4. Create an MIF file for your RAM that has 16 words of 8 bits each. Load the memory with a set of patterns that are different from the ROM.
  5. Using the Tools:MegaWizard Plug0in Manager, create a RAM that has 16 words of 8 bits each. Therefore, it should have 4 address bits and 8 data bits. I'll refer to this circuit as MemRAM, Tell it to initialize the RAM using the MIF file you created in the prior step. This step will create a VHDL file that you will include in your project.
  6. Create a top-level VHDL file with an entity that has the same name as the project (e.g. ramtest). Your ramtest entity will need a clock signal, a reset signal, and an output port for sending signals to either the 7-segment displays or 8 LEDs.

    Create component statements for both the ROM and RAM in the architecture header. Be sure to include the two files created by the Wizard in your project and call them from your top level design. The component statement for the ROM should look like:

    component MemROM  
     PORT
            (
                    address         : IN STD_LOGIC_VECTOR (3 DOWNTO 0);
                    clock           : IN STD_LOGIC;
                    q               : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
            );
    end component;
    

    The port map statement will look something like the following.

      romcircuit: MemROM
      port map ( address => std_logic_vector(ROMADDR), clock >= clk, q => romwire );
    
  7. Create the internal signals you will need to build the state machine and access the ROM and RAM. I would recommend using a model where the address for the ROM is stored in one register (e.g. ROMADDR) and the address for the RAM is stored in a second register (RAMADDR). These will both be internal 4-bit unsigned signals.

    Likewise, you will want an internal asynchronous signal (one not assigned inside a process) that will represent the wires connected to the output (q) of the ROM and RAM. You can call these something like romwire and ramwire and they should be 8-bit std_logic_vector or unsigned types.

    Then you will need clocked registers to hold the contents being uploaded or downloaded from memory. These should be 8-bit std_logic_vector or unsigned internal signals that get assigned only inside a process statement. You could call these ROMDATA and RAMDATA.

    Finally, you will need a state variable (4-bit std_logic_vector), a writeEnable (1-bit std_logic) and a startupcounter variable (2 bits unsigned).

  8. Plan out your state machine. You will need to have at least three clock ticks at startup before trying to use any of the memory circuits to allow it to initialize. A good plan is to have state "0000" be your startup state, increment your startupcounter each time the circuit is in that state, and have the circuit leave the state when the startup counter reaches 3.

    Your state machine will have two parts to it. The first part should read through the RAM and send the contents to the output port by assigning the RAMDATA internal signal to the output port signal outside of the process.

    The second part should read the contents of the ROM and assign them to the RAM. This will be a multistep process. You may be able to compress the process into fewer clock cycles, but the following steps are a good way to start. Both ROMADDR and RAMADDR should start at "0000". From step 5, if ROMADDR is 0 (the circuit has wrapped around) then return to part one where the circuit reads through the contents of the RAM.

    step 1: let the ROMADDR be stable for 1 clock cycle
    step 2: assign the value on the romwire to ROMDATA
    step 3: assign the value of ROMDATA to RAMDATA and increment ROMADDR
    step 4: set write enable to '1'
    step 5: set write enable to '0' and increment RAMADDR

  9. Add a slowclock to your circuit and demonstrate the circuit on the board. Be sure to document your testing for your writeup.

Extensions


Writeup

Create a wiki page with your writeup. For each task, write a short description of the task, in your own words.


Handin

Give your wiki page the label cs232s15project6.

Put your VHDL files in your Private subdirectory on the handin server in folder for this project. If you have any issues with the server, use vpn.colby.edu or send a tgz or zip file to the prof.