Lab reports for Lab 3 due Monday 9/29 at 11:59pm via the submit program.
You will demonstrate your lab to your TA on Friday, 9/26 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. You can
also receive bonus points if you fix your processor to pass the tests within
your section time. Otherwise, the TA will not give you the source code to the
tests until after section, which will leave you the weekend and Monday to fully
debug your processor. Ideally, you will have already tested your processor
thoroughly, so that you will be able to pass these tests on the first try.
This is the first lab to be done in groups. Please review this
with your partners. A formal design document (which we will go over in class)
and a division of labor is due via e-mail to your TA Thursday by 9pm. This will
allow the TAs time to go over your design document with you during section on Friday 9/18. You are
encouraged to finish 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. Like the previous labs, this lab is
rather long, so get started early!!!
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.
Note that all of the simulation in this lab will be done at the high-level (i.e. we will not map things down to gates or do a place-and-route).
The following components are provided for this assignment and future ones. The verilog descriptions of these componenets are located in the cs152 component lib (M:\lab3).
Start by copying these files to your working directory. Look at the top of ramblock2048.v. Make two new top-level ramblocks, called "instmem()" and "datamem()" in the same style of the top-level ramblock2048(). (They will instantiate copies of ranblock2048b()). For your instruction memory, use an initialization file called "instmem.contents" file. For your data memory, use a file called "datamem.contents". Examples on how to make your own contents file are in the LAB3_Help.pdf document. A datamem.contents example has been provided for you. Data from these files will be loaded into your memory at the beginning of the simulation.
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:
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 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,
.....
To get each test case, you could:
0x00000000: addu r3, r4, r5
R[r4]=0x34235432, R[r5]=0x45557322, R[r3]=0x7978C754
0x00000004: <etc>
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. Note that this module is used in simulation only)). $display statements are much like a C printf() statement, allowing fairly extensive formatting.
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 ramblock2048b 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/mem" in ModelSim. Note that the middle "inst" and "mem" pieces are not under your control (they are inside the "ramblock2048b" and "BLKMEMSP_V4_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). This is the file that we will potentially place breakpoints in from ModelSim. For instance, you could do:
always
begin
#clock-half-period
CLK = 1;
#clock-half-period
CLK = 0;
end
Then, set breakpoints at one of the lines that set the clock. This driver will be used to keep your processor running. The processor itself will be grabbing instructions from it's instruction memory.
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.
We have provided one diagnostic program for you to use in the M:\lab3. This is similar to the type of program that we will run in Section to test your processor (although we will use something different).
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.