Lab 7 - Memory and Control

1 Objectives

Upon completion of this lab you should be able to create and test a design using the Xilinx ISE tools.

2 General

This lab will guide you through building and testing instruction memory and a small control unit. We will follow the "Top-down design; bottom-up implementation" approach.

This lab is completed by your project group. You only need to have 1 or 2 people work on this lab those people will become your team's "memory experts". They are expected to read the FULL "resources" page on the course website, it will make this lab (and the project) much easier.

The earlier you do this lab the better, delaying it until the due date leads to many debugging issues later with your design.

You will use Xilinx to create a testbench that simulates the PC, supplying addresses to a memory unit. A memory unit representing instruction memory will responds to input addresses, outputting instructions. Finally, a control unit receives the instruction and sets control bits appropriately. In this exercise, only the opcode bits of the instruction are needed; the remaining bits can be 0.

>Control bits>

3 Building Block Memory in Xilinx

In this section, you will build a block memory module.

  1. Start Xilinx ISE 14.7

  2. Select File > New Project... to open the "New Project Wizard."

    1. In the "Create New Project" dialog:

      1. enter "memory" for the "Name",
      2. choose the "Location",
      3. CRITICAL: change the "Working directory" to "the location selected above/work",
      4. select "Schematic" as the "Top-Level Source Type", and
      5. click "Next".
    2. In the "Project Settings" dialog, enter the following properties:

      • Family: Spartan3E
      • Device: XC3S500E
      • Package: FG320
      • Speed: -4
      • Synthesis Tool: XST (VHDL/Verilog)
      • Simulator: ISim (VHDL/Verilog)
      • Prefered Language: Verilog

      and click "Next".

    3. Click "Finish" in the "Project Summary" dialog.

  3. Select Project > New Source and select IP(Core Generator & Architecture Wizard) in the New Source Wizard. Enter blockmemory16kx1 for the name of the new source.

  4. Select Memories & Storage Element > RAMs & ROMs > Block Memory Generator. Verify that version 6.3 is being used. If not, check the "All IP Versions" checkbox. Several more units should be shown; select version 6.3 of the Block Memory Generator. Select Click Next then Finish.

  5. After a bit, a new dialog will pop up. The diagram on the left shows the current memory configuration. Click next, then select the memory type as Single Port RAM and the Algorithm as Minimum Area. Click Next.

  6. Select the Write Width as 16 and the Write depth as 1024. The FPGA board imposes a limit on the depth allowed, but 1024 should be enough for this lab and your actual processor. Select the Write First operating mode and leave the Enable option as Always Enabled. Click Next.

  7. At this point, your memory diagram should have the following inputs and outputs:

    1. ADDRA[9:0]: address to be read from/written to
    2. DINA[15:0]: data in
    3. WEA[0:0]: write enable line
    4. CLKA: clock
    5. DOUTA[15:0]: data out
  8. You can specify the contents of memory on this screen. The memory content file has a .coe extension; the values in memory will be initialized to the values in the file. Here's an example file memory_small.coe. Examine the sample file then assign it to your memory module. Click Next.

  9. Leave the Power Estimate Options as is and Click Next. Click Generate. Generating the memory block can take a minute or so.

At this point, you have generated a memory module. For further information on the various options on the Block Memory Generator see the Block Memory Documentation.

4 Testing Your Block Memory

Create a new testbench in Xilinx.

  1. Click Project > New Source.
  2. Select Verilog Test Fixture and enter "blockmemory16kx1_tb" in the File name: textbox.
  3. Select the blockmemory16kx1 component to associate with this new testbench. Click Finish.
  4. Create a testbench for this module. Refer to Lab0 for a refresher on writing testbenches. Your testbench should do the job of the PC block of the datapath: supply instruction addresses to instruction memory. Send various memory addresses to your memory block and verify that the output data is what you expect. Pay attention to the addressing mode!

5 Control

Download BlockMemoryControl.v and add it to your project. Modify BlockMemoryControl.v file so that it sets the correct controls (RegDst, RegWrite, MemRead, MemWrite, Branch, ALUSrc, MemToReg) for the four main instruction types in MIPS (R-types, lw, sw, beq). For example, if the opcode is 0x23 the output should be RegDst=0, ALUsrc=1, MemtoReg=1, RegWrite=1, MemRead=1, MemWrite=0, Branch=0.

Similar to your memory unit, you will need to unit test for the control unit. Write a testbench to verify your control unit works properly.

6 Connecting the Two Components

Create a symbol for your control unit. The symbol for your memory is build automatically. Refer to the ALU lab on how to generate symbols. Add a new schematic to your project and connect the two parts you've created together so that an instruction from the memory is decoded using the control module. Enter an instruction for each instruction type into the memory using your .coe file. Ensure that your control prints the correct output.

7 Turning It In

Demonstrate your working memory and control module to your instructor. There is no submission to gradescope for this lab.

Submit the instructor verification sheet in hard copy.

Only one lab should be submitted for each project team. Make sure all team member's names are included on your submission.