CS152 Computer Architecture and Engineering

Lab #3: Single Cycle Processor

  Spring 2004, Prof. John Kubiatowicz


Lab reports for Lab 3 due Thursday 3/11 at 11:59pm via the submit program.  You will demonstrate your lab to your TA on Thursday, 3/11 in section. During this demo, the TA will provide you with secret test code. If you are able to pass these tests on your first try, you will receive bonus points. If you fail the first time, then your TA will give you the source code to the tests and you will have until the end of the day to complete the tests for full credit. If you are not done by the end of the day then you will lose points for each additional day that you are late.

This is the first lab to be done in groups.  Like the previous labs, this lab is rather long, so get started early!!!

Homework Policy: Homework assignments are due in class. No late homeworks will be accepted. There will be a short quiz in lecture the day the assignment is due; the quiz will be based on the homework. Study groups are encouraged, but what you turn in must be your own work.

Lab Policy: Labs (including final reports) must be submitted by 11:59pm on the day that your lab is checked off. To Submit your lab report, run m:\bin\submit-spring2004.exe or at command prompt, type "submit-spring2004.exe" then follow the instructions. Make sure you input the correct section number, and directory to submit. Remember that you can only submit once, so make sure to submit only when you're ready. Otherwise your lab/project grade will NOT be correctly recorded. The required format for lab reports is shown on the handouts page. 


Homework 3

Please do the following problems from P&H: 4.44, 4.46, 5.2, 5.11, 5.17, 5.18, 5.20, 5.21, 5.22, 5.24, 5.27, 5.28, 5.29

Lab 3

In this assignment you will build a single-cycle datapath like the one discussed in class and in chapter 5 of the book, and verify that it executes a subset of the MIPS instruction set.  This lab has two goals: (1) getting you more familiar with Verilog and the mixing of Verilog and schematics.  (2) constructing a complete working single-cycle datapath.

This lab assignment is to be completed with your project partners. Each group should elect a spokesperson for this lab, which should be stated in the design document. The responsibility of the spokesperson is to communicate questions to the TA and reply to questions from the TA. For each lab, you will need to select a different spokesperson.

Problem 0.5: Design Document

Please review this assignment with your partners. A formal design document (which we will go over in section) and a division of labor is due via e-mail to your TA Wednesday 2/25 by 9pm. This will allow the TAs time to go over your design document with you during section on Thursday 2/26. You are encouraged to finish this first version of your design document and turn it in as early as possible, so that the TAa can review it earlier, which will allow you to begin working on this lab earlier.

The design doc should be about 2 to 3 pages in length and should be accompanied by some rough schematics of your datapath. Your design doc should also contain a division of labor. Make sure that you discuss your testing methodology as well as potential areas of difficulty in the lab.

A final version of the design document (incorporating changes suggested by the TAs) is due via EMail to your TAs by Thursday 2/26 at midnight.

Problem 0.75: Source Code Control

For this lab (and all future labs) you should use some kind of source code control system. We have included cvs on the instructional machines in M:\bin\cvs.exe (version 1.11.12). (Watch out, there is another version of cvs (1.11.5) that has been compiled for cygwin that is in c:\cygwin\bin. This version will not work if you are not running in the cygwin environment; it will complain about windows-style paths. So make sure that you are running the version in M:\bin.) If there are any other source code control systems that you would like installed (subversion, etc.) then contact John (cs152-tb AT cory DOT eecs DOT berkeley DOT edu). If you have no idea how to use cvs then feel free to look at a couple of tutorials on how to use cvs: one for windows and one for unix (plus general usage).

One other requirement is that you must use keyword substitution in your verilog source files (don't try to use keywords in things like project files or schematics, they will be eliminated when the file is saved). You should place the keywords at the top of the file. I would recommend either $Id$ or $Header$. But you should at least include the author as well as the version number and the checkin time.

Problem 1: Datapath Design

Problem 1a: High-Level components

The following components are provided for this assignment and future ones.  The verilog descriptions of these componenets are located in the lab 3 directory (M:\lab3).

  1. alu: arithmetic logical unit
  2. scram: an asyncronous read, synchronous write memory of capacity 128 words (this module also requires C_REG_FD_V6_0.v)
There is a description of these components in the directory as well, called LAB3_Help.

The new MIPSASM will allow you to generate the files necessary for both simulation and compilation. You can still find information about the old components in OLD_LAB3_Help.pdf.

Start by copying scram.v and C_REG_FD_V6_0.v to your working directory.  Make two new top-level ramblocks, called "instmem()" and "datamem()" as shown in LAB3_Help. For your instruction memory, use an initialization file called "instmem.smallcontents".  For your data memory, use a file called "datamem.smallcontents".  A .smallcontents file consists of upto 128 lines of 8 hexadecimal characters. Each line of the file will be loaded into the memory in the order that it appears in the file. (eg. line 1 will be placed in mem[0], line 2 will be placed in mem[1], etc.) An example file (example.smallcontents) has been placed in M:\lab3 for your perusal. It initializes the ram with ascending numbers beginning at 0.

Note that .smallcontents files are used for simulation only.

Problem 1b: Datapath Components

For this first part of the lab, you should design the following components. Try to divide this work evenly among the various partners in your groups:
  1. bts32: 32-bit tri-state buffer
  2. extend: sign/zero extender
  3. m16x2, m32x2, m32x3, m32x5, m5x2: MUXes with various widths and number of inputs.
  4. reg32: 32-bit register
  5. regfile: register file
  6. shifter: arithmetic logical multibit shifting unit
All the components should be implemented in Verilog. We suggest that you adhere to standards when building your modules -- it will make your life easier.  Make schematic symbols for each of your high-level components.

For instance, you should do the following:

  1. In all the components the label DOUT refers to the data output, and if there is only one data input (e.g., reg32), it is called DIN.
  2. If there is more than one data input, they are labeled A, B, C, ....  MUX output selectors are labeled SEL.  A is routed to the output when the select bits represent 0, B when they represent 1, and so on.
  3. Control signals, such as the write enable on reg32, have a suffix H or L to indicate whether they are active high or active low.
  4. All clock inputs to the modules are called CLK.
All modules that require a clock should be rising-edge triggered (posedge triggered). Please look through the comments at the beginning of the Verilog description for the components you have been given.

Problem 1c: subcomponent test benches

Design test-benches for each of your components.  Your test-bench should test as many cases as you can think of.   Try to imagine strange things that might happen to a real (non-Verilog) implementation of a component.   One possible diagnostic is to have your test-bench output the bad cases to a diagnostic file, using the file I/O primitives (look at section 17.2 of the IEEE spec on the handouts page).

Each component will have its associated test bench.  A test bench for a given component should be written by the same person that wrote that component. The reason for this is because now the person who writes the test bench may think of new cases that the first person did not think of when designing the component.  Note that these test benches are only used during the testing phase of your components and are not wired into your processor.  However, you may reuse the test benches later in the term if you try more complicated implementations of these components.

Turn in the output from your test-benches that illustrate that your components are working.

Problem 1d: assemble the data path

Using the components listed above, build a singlecycle datapath (with schematics) that implement the following subset of MIPS instructions: addu, addiu, subu, ori, lw, lui, sll, srl, slt, sw, jr, beq (these are a subset of the instructions you used in Lab #1--you will implement the remainder during lab 4). Make sure that your design is clean -- you will be breaking it apart to build a pipelined processor in future assignments. In this section, you don't have to put in the PC and instruction memory. Just set the values of the 32-bit instruction and the control signals in the simulator and test your datapath.

Problem 1e: Test your data path

To test your datapath, build a test-bench in the following way.  Build a top-level verilog file that incorporates your datapath and has a single initial block that includes a bunch of test cases.  This module would incorporate your data path and drive each of the control signals and the instruction value, and inputs for some set of result signals (such as the destination register, the equal? signal, etc).   Each of these test cases should be of the form:

initial
    // Test case #1: Make sure that register read works
    A=something; B=somethingelse; CLK = 0;
    #100  // Wait for datapath to settle
    if (Foo!=something|| )
        $display("Failure for Test case #1\n");

    // Test case #2,

    .....
Turn in a copy of your diagnostic program and a log of your simulation showing that the instructions worked. The objective of this question is to make sure that you have all the parts of the datapath in place to execute all the instructions and you have a clear idea of what the control signals have to be for each instruction. The testing need not be exhaustive, but should be complete.
 

Problem 2: Verilog Controller for the Datapath

Problem 2a: the actual controller

Now we are ready to build the controller for the datapath you built in problem 1. You will use Verilog to create the control module. Make this into a module with pins labeled appropriately and connect it to the datapath you built in problem 1. This controller should take the bits from the 32-bit instruction and implement a combinational circuit that generates the control signals. You should also add in the instruction memory, PC and nPC, and the next instruction logic here.

Problem 2b: The disassembly monitor module

Next, build a special Verilog entity that takes as input the clock, the instruction address, the output of the instruction memory, the output of the registers, and the destination register.  This will be a monitor module which will monitor the execution your processor.  It should output information in textual format, using the "$display" statement or using file I/O to output to a diagnostic trace file.  In the interests of making grading and checkoff easier, we are asking everybody to have the exact same monitor module format. Please follow the format below:

    0x00000000: addu $3, $4, $5          $4=0x34235432, $5=0x45557322, $3=0x7978C754
    0x00000004: addiu $6, $7, 100       $6=0x34235432, $7=0x45557322

Your monitor should be able to disassemble the complete set of instructions above and print out the course of execution.  This monitor will show you in graphical form that your processor is "doing the right thing".  It should print a new line at the falling edge of the clock (this is the only thing that should run off the negedge).
$display statements are much like a C printf() statement, allowing fairly extensive formatting.
Note that this module is used in simulation only.

Wire your monitor module into your datapath.  Note that, later in the term, you will have to add some pipelining

Problem 2c: Top-level driver

Wire together your datapath, control path, memory modules, and monitor modules.  Make sure to keep track of the instance names for your memory modules.  These will form a complete path that you can use in the simulator to examine memory during simulation.  For instance, let's say that you called the scram in your instmem() module "tempBlock" and then called the block "MyInstMem" at the data path level.  Then, you will be able to refer to the memory block as "MyInstMem/tempBlock/inst/ram_data" in ModelSim.  Note that the middle "inst" and "ram_data" pieces are not under your control (they are inside the "scram" and " C_DIST_MEM_V6_0" blocks.

Make a top-level module to drive your processor.  It should have a clearly-defined clock generator defined as a an always loop with a delay statement (like #100).  For instance, you could do:

    always
    begin
        #clock-half-period
        CLK = ~CLK;
    end

Problem 2d: debugging your processor

Follow the directions in LAB3_Help for loading your memory blocks into simulation. (Note that there is a bug in the simulation and if the clock that you provide to the simulation module begins at 1 that it may not initialize your memory properly. While we look for a workaround, simply initialize your clock to 0.) Recall that in 1a we made the memory contents be "instmem.smallcontents" and "datamem.smallcontents". You should be able to go into the command mode of ModelSim to set breakpoints at points of your clock cycle and thereby step cycle by cycle. If you are still using the old tools you can find directions on simulating in OLD_LAB3_Help.pdf.

You should write a diagnostic program to test this mini-MIPS processor; this program may be a subset of the program you used for Lab #1 (broken-spim). Remember, a single cycle processor does not have delay slots,  and you have not implemented the complete subset of instructions from Lab #1. (Later on, you will be adding more instructions to your processor and will be able to use the complete diagnostic program.) In general, you will not have access to the contents of the registers like you did in spim (but you can look at waveforms). It is important to write good diagnostic programs to test your hardware because it will simplify your life later on when you have to debug a more complicated processor.

Other types of monitor modules may help you debug your processor.  You can produce a set of modules that simple check for conditions that should "never happen" and output.

Turn in a copy of your Verilog code, processor schematic, diagnostic program(s), a simulation log that shows the correct execution of the program, and your on-line logs.

Problem 3: Pushing to Board

After you have finished debugging your processor it is time to push to board. You will have to generate a special ram file for use on board, see LAB3_Help.pdf for more information on how to do this.

You may be wondering how to determine if your processor actually works on the board. You should use ChipScope to inspect the register file as the program runs to figure out what is happening. In particular your ChipScope module should trigger on the PC and capture the status of registers 1 to 6 in your register file as well as the output from the instruction register. You may use other chipscope modules to debug your processor, but you should have at least one setup in this manner so that you can be checked off.

You should not have to worry about your clock rate because the clock that we are providing you with has a frequency of a couple hundred KHz.

You should use the MIPSASM tool to generate synchronous write / asynchronous read rams for use on the board (you can find these options under "Advanced"). You can copy and paste the output of the program into verilog files that you can add to your processor.

Problem 4: Critical Path

Now that we have a functional datapath, we will investigate the performance of this processor.  Find the critical path for your processor. What would happen if you run your processor such that your clock rate was faster than your critical path?

Problem 5: Write Up

Make sure to structure your laboratory report to be easily readable.  If you have really complicated listings or schematics, you should include them in an appendix.  Make sure to discuss your testing philosophy in detail.  Also, turn in a copy of your laboratory notebook.