CS 341L Computer Architecture - Lab 3

CS 341L Computer Architecture, Spring 2019

Lab 3 - due Friday April 26 @ midnight

Please get started on the lab as soon as possible. In general, in this class you will have about 3 weeks from the lab release date until the due date.

Accessing Your Repository for this Lab

You will submit your work by pushing it to your repository on LoboGit. Details about how to access your repository are found on the course webpage.

Setting Up the Tools

First, install some tools: Xilinx ISE WebPack and ModelSim SE. The total space required will be about 30 GB (total download size is about 8 GB). You have two options here.

Option 1 - Install on Your Personal Windows Machine

I do not recommend this option, and I cannot provide you with much help if you try this option and it doesn't work.

Here's where to get the tools for Windows:

Option 2 - Install on Your Personal Linux Machine (or Linux VM)

You cannot install this software on the lab machines, since you don't have sudo permissions there.

NOTE: these install instructions were tested on Ubuntu 16.04 and 18.04.

The following outlines how to install ModelSim on Linux.

wget http://download.altera.com/akdlm/software/acdsinst/13.1/162/ib_installers/ModelSimSetup-13.1.0.162.run
chmod +x ModelSimSetup-13.1.0.162.run
sudo apt-get install build-essential gcc-multilib g++-multilib lib32z1 lib32stdc++6 lib32gcc1 expat:i386 fontconfig:i386 libfreetype6:i386 libexpat1:i386 libc6:i386 libgtk-3-0:i386 libcanberra0:i386 libice6:i386 libsm6:i386 libncurses5:i386 zlib1g:i386 libx11-6:i386 libxau6:i386 libxdmcp6:i386 libxext6:i386 libxft2:i386 libxrender1:i386 libxt6:i386 libxtst6:i386
# sudo apt-get install libpng12-0:i386
# sudo apt-get install libpng16-16:i386
sudo ./ModelSimSetup-13.1.0.162.run

After you have installed ModelSim in /opt/altera/13.1, you then need to do the following:

wget http://download.savannah.gnu.org/releases/freetype/freetype-2.4.12.tar.bz2
tar -xvf freetype-2.4.12.tar.bz2
cd freetype-2.4.12
./configure --build=i686-pc-linux-gnu "CFLAGS=-m32" "CXXFLAGS=-m32" "LDFLAGS=-m32"
make -j8
sudo mkdir /opt/altera/13.1/modelsim_ase/lib32
sudo cp objs/.libs/libfreetype.so* /opt/altera/13.1/modelsim_ase/lib32
cd /opt/altera/13.1/modelsim_ase/
sudo pico bin/vsim

This should open the ModelSim startup script. You need to go to the line that looks like

dir=`dirname $arg0`

and insert the following on the next line:

export LD_LIBRARY_PATH=${dir}/lib32

Additionally, search for the word linux_rh60 in the file, and change it to linuxaloem. Now, if you exit the editor, and type bin/vsim, you should see ModelSim start up.

Next, add the following at the end of your ~/.bashrc file:

export PATH=$PATH:/opt/altera/13.1/modelsim_ase/bin
alias xilinx="source /opt/Xilinx/14.7/ISE_DS/settings64.sh"
export MODELSIM="/opt/altera/13.1/modelsim_ase/modelsim.ini"
export WD_MGC="/opt/altera/13.1/modelsim_ase/"
export MODEL_TECH="/opt/altera/13.1/modelsim_ase/linuxaloem"

and type source ~/.bashrc to apply your changes.

Finally, install Xilinx ISE Webpack.

  • Download the Full Installer for Linux.
  • You will be asked to first create a Xilinx account. You'll need to use your UNM email address.
  • The download is about 7 GB, so will take quite a while to download (it took about 45 minutes for me).
  • Once the download is finished, do the following:
tar -xvf Xilinx_ISE_DS_Lin_14.7_1015_1.tar
cd Xilinx_ISE_DS_Lin_14.7_1015_1
sudo ./xsetup
  • The graphical installer should let you install Xilinx ISE Webpack in /opt/Xilinx.
  • After the install is complete, you should go to the Xilinx license site and download a Xilinx ISE Webpack license.
  • You should be able to start Xilinx by typing
xilinx
ise

Xilinx will ask for a license, and you should click "manage licenses", and then "load license" and select your downloaded license file (Xilinx.lic).

Overview of the Lab

In the first lab, we learned about how the MIPS instruction set works by implementing a basic MIPS CPU in software. In the second lab, we learned how to implement a single-cycle MIPS CPU in hardware. In this lab, we will think a bit more about the hardware CPU implementation.

In the second lab, we added support for the following 12 MIPS instructions: add, addi, sub, and, or, nor, lw, sw, slt, beq, j, nop.

Reminder: the course textbook provides a very useful MIPS Cheat Sheet. You can also check out the other MIPS Assembly Reference which shows the syntax of the MIPS assembly language instructions (the order of the arguments can sometimes be a bit confusing). We will again utilize these references throughout this lab.

Recall the following basic MIPS assembly code:

# this program computes $t1 * $t2 and places the result in $t0

.globl c_entry
c_entry: nop
# initialize registers
addi $t1, $zero, 5
addi $t2, $zero, 4
addi $t0, $zero, 0

loop: beq $t2, $zero, done
add $t0, $t0, $t1
addi $t2, $t2, -1
j loop

.globl done
done: nop

We saw that this code can be assembled into the following machine code:

address block offset machine instruction assembly code explanation
0x00000000 c_entry+0 00 00 00 00 nop no-operation (left-shift by zero places)
0x00000004 c_entry+4 20 09 00 05 addi $t1, $zero, 5 add immediate
0x00000008 c_entry+8 20 0a 00 04 addi $t2, $zero, 4 add immediate
0x0000000c c_entry+12 20 08 00 00 addi $t0, $zero, 0 add immediate
0x00000010 loop+0 11 40 00 03 beq $t2, $zero, 0x00000020 <done> branch to done (3 words from next PC)
0x00000014 loop+4 01 09 40 20 add $t0, $t0, $t1 add
0x00000018 loop+8 21 4a ff ff addi $t2, $t2, -1 add immediate
0x0000001c loop+12 08 00 00 04 j 0x00000010 <loop> jump to loop (byte address 0x10 is word address 0x04)
0x00000020 done+0 00 00 00 00 nop no-operation (left-shift by zero places)

In particular, the "machine instruction" column contains a list of 32-bit words that represents the MIPS program.

In Lab 2, we built hardware which can execute such a list of instructions. An instructor-provided VHDL implementation is provided for this lab. You can either use your Lab 2 implementation, or the instructor-provided implementation for this lab.

Creating a New Project in Xilinx

  • Click on "New Project", name your project lab2, select a location where your project should be stored, and select HDL as the top-level source type, and click "Next".
  • Change "Preferred Language" to VHDL, and change "Simulator" to Modelsim-SE VHDL, and click "Next", and then "Finish".
  • Click on the "New Source" icon on the left, select "VHDL Module", and type full_adder as the filename.
  • Create the following ports: a (in), b (in), carry_in (in), sum (out), carry_out (out), and click "Next"/"Finish".
  • This should add a file full_adder.vhd (VHDL module) to your project, that looks like this:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity full_adder is
    Port ( a : in  STD_LOGIC;
           b : in  STD_LOGIC;
           carry_in : in  STD_LOGIC;
           sum : out  STD_LOGIC;
           carry_out : out  STD_LOGIC );
end full_adder;

architecture Behavioral of full_adder is
begin
-- PUT YOUR VHDL CODE HERE
end Behavioral;

To build a test bench for your VHDL module using ModelSim, click on the "Simulator" checkbox at the top, and then do the following:

  • Select full_adder in the list.

  • In the "Processes" list, open the "ModelSim Simulator" item, right-click on "Simulate Behavioral Model", select "Ignore Pre-Compiled Library Warning Check", and press "Ok".

  • Double-click on "Simulate Behavioral Model".

  • In the "Wave" section, select signals a, b, carry_in, right-click, and select "Edit" and then "Delete".

  • In the "Objects" section, select signal carry_in, right-click, select "Modify" and then "Apply Wave", and change the period to 200 ps.

  • This should create a new signal carry_in in the "Wave" section, with the corresponding waveform.

  • Repeat the above two steps for signal a, except set the period to 100 ps.

  • Do the same for b, except set the period to 50 ps.

  • Select your input signals in the "Wave" section, and click on "File", then "Export", then "Waveform".

  • Select "VHDL Testbench", click "Browse", and name your file full_adder_tb.vhd.

  • In Xilinx ISE, click the "Add Source" button, select your testbench full_adder_tb.vhd, and press "Ok".

  • Double-click on full_adder_tb.vhd in the "Design" section.

  • Make the following substitutions in the VHDL file (and then save):

    • \full_adder_tb.vhd\ --> full_adder_tb
    • \full_adder_tb.vhd_arch\ --> full_adder_tb_arch

Now that you have a VHDL test bench, you can run it using ModelSim:

  • In the "Design" section, change to the "Simulation" view, select full_adder_tb, and double-click "Simulate Behavioral Model".
  • In ModelSim, press the "Restart" button, and then the "Run All" button.
  • Click in the "Wave" section, and press the "Zoom Full" button.
  • You should see your waveforms for the adder inputs, and a red line (undefined value) for the outputs. This is because you haven't yet connected the outputs to anyting. Try modifying your full_adder.vhd in the following simple way:
-- PUT YOUR VHDL CODE HERE
sum <= a and b;
carry_out <= a or b or carry_in;
-- NOTE - this is not the correct definition of the outputs for a full adder - we're just using it for a test.
  • Save and repeat the process of running the testbench in ModelSim.

Basic Digital Logic / VHDL

We will use a fairly basic subset of VHDL in this class. We will use only structural (not behavioral) VHDL to model digital logic.

The CD that accompanies the textbook contains a VHDL Tutorial that you may find useful. There is a VHDL Primer that also may be useful. To refresh your memory on digital logic, please see Appendix C from the textbook CD.

It is relatively easy to produce a logical function from a truth table, but it can be tricky to produce a minimal function. Fortunately, the Espresso tool makes this easy. You can download the Espresso logic minimization tool, and it should work on Linux or Windows. There is a nice Espresso tutorial which shows an example. The following is a simplified version, using the truth table for a half adder.

Once you have downloaded the Espresso program, and added its location to your system path, type the following command:

espresso -o eqntott

Espresso will wait for input. Paste the following and press Enter:

.i 2      # number of inputs 
.o 2      # number of outputs 
.ilb A B  # names of inputs 
.ob C SUM # names of outputs
00 00     # input bits, followed by space, followed by output bits 
01 01     # (use a dash "-" character for "don't care")
10 01     # THIS IS THE TRUTH TABLE FOR A HALF ADDER
11 10 
.e        # end of file

Espresso will produce the following output:

C = (A&B);
SUM = (A&!B) | (!A&B);

Note that this shows that the carry out for a full adder is simply the logical and of the input bits, and the sum is the logical xor of the input bits.

Part 1 - Branch Functionality (20 points)

Remember that we ignored the bne (branch on not-equals) instruction in lab 2. For this part of the lab, you should modify your Lab 2 VHDL code to add support for the bne instruction.

Part 2 - Multiplication Functionality (50 points)

Modify the VHDL code for your single-cycle MIPS CPU to add support for the mult, mfhi, mflo instructions. You should use the multiplier hardware we discussed in class (using a single 64-bit register to store the intermediate results). Note that the multiplication can take up to 32 clock cycles, so you will need to modify the Control hardware to allow the processor to stall while the the multiplication is being performed.

Part 3 - Caching (20 points)

Modify the VHDL code for the main memory of your single-cycle CPU to contain a basic direct-mapped cache. For simplicity, the cache should have between 8 and 32 entries.

Part 4 - Documentation (10 points)

Clearly document (using source-code comments) all of your work. Also fill in the README.md file (preferably using Markdown syntax) with a brief writeup about the design choices you made in your code.

Make sure that you have named your source code files exactly as requested in the lab assignment! (If for some reason you need to use a different naming convention, make sure to carefully explain the mapping between your source code files and the requirements in the lab assignment).

Providing adequate documentation helps us see that you understand the code you've written.

Part 5 - Pipelining (20 points EXTRA CREDIT)

Modify your VHDL code to follow a basic pipelined architecture, using the 5 pipeline stages discussed in class. You can assume that the code to be executed within the CPU will have no hazards, i.e., you do not need to implement functionality to do forwarding or stalling.

Submission Instructions

We will automatically grab a snapshot of the master branch of your lab repository at the deadline. Make a new directory in your repository for this lab.

Make sure you push all of your work before the deadline!