Please Log In for full access to the web site.
Note that this link will take you to an external site (https://shimmer.mit.edu) to authenticate, and then you will be redirected back to this page.
Error on line 5 of Python tag (line 6 of source): kerberos = cs_user_info['username'] KeyError: 'username'
Ok for the second part of this lab, we'll implement an ALU (Arithmetic Logic Unit).
The ALU will take in two 8 bit numbers:
- Number 0 (
n0
) is taken from the lower eight bits of the switch array (sw[7:0]
) - Number 1 (
n1
) is taken from the upper eight bits of the switch array (sw[15:8]
)
The buttons btn[2:0]
will be used to select from one of eight operations:
- (
3'b000
): Addition:n1 + n0
- (
3'b001
): Subtraction:n1 - n0
- (
3'b010
): Multiplication:n1 * n0
- (
3'b011
): Division:n1 / n0
(integer division) - (
3'b100
): Remainder:n1 % n0
(modulo) - (
3'b101
): Bitwise AND:n1 & n0
- (
3'b110
): Bitwise OR:n1 | n0
- (
3'b111
): Bitwise XOR:n1 ^ n0
The result of this calculation should be displayed using the 16 green LEDs (led[15:0]
).
In addition two other checks will always be performed:
- Equality:
n1 == n0
with its result presented onrgb0[2]
- Greater than:
n1 > n0
with its result presented onrgb1[0]
Below we've provided a basic testbench for you to locally develop and simulate this ALU. You might say, "I don't need to do a testbench or simulate, I'll just code this up and iMmEdIaTeLy run a Vivado build." These are famous last words. Many an all-nighter has begun with similar thoughts. Test benching/simulating your code sucks because you have to write more code, but it sucks way less than the making miniscule changes and then waiting hours for a hardware build to happen.
A testbench file is still Verilog, but it is not synthesizable Verilog. It is meant for simulation. Consequentely a testbench file should be thought of more as a regular program file that "runs". Starts at the top and goes in order as you go down. There are still rules and things, of course, but it should feel more natural to you coming from a Python/C existence in terms of its ordering/causality.
One of the great difficulties in Verilog is that it was originally meant to be a simulation language and was then bent into the Hardware Description Language role. It isn't the end of the world, but always try to keep track of the two types of files:
- Synthesizable Verilog (files that we use to describe hardware). You will never see any sort of "time" in synthesizable Verilog
- Simulation Verilog (testbenches). This Verilog will have a concept of time, and is meant to run and test in simulation synthesizable Verilog files.
// set the timestep on the internal simulation clock
`timescale 1ns / 1ps
`default_nettype none
//The timescale specifies the timestep size (1ns) and time resolution of rounding (1ps)
//we'll usually use 1ns/1ps in our class
module alu_tb();
//make inputs and outputs of appropriate size for the module testing:
logic [7:0] d0_in;
logic [7:0] d1_in;
logic [2:0] sel_in;
logic [15:0] res_out;
logic gt_out;
logic eq_out;
//create an instance of the module. UUT= unit under test, but call it whatever:
//always use named port convention when declaring (it is much easier to protect from bugs)
alu uut(.d0_in(d0_in), .d1_in(d1_in), .sel_in(sel_in),
.res_out(res_out), .gt_out(gt_out), .eq_out(eq_out));
//All simulations start with the the "initial block's top
// They then run forward in order like regular code.
//lines that are one after the other happen "instaneously together"
//Time passes using the # notation. (#10 is 10 nanoseconds)
// set the initial values of the module inputs
initial begin
d0_in = 0; //set d0_in to 0
d1_in = 0; //same for d1_in
sel_in = 0; //same for sel_in
// Extremely Important!
// Even though the system is combinatorial-only, make sure some simulation time runs before analyzing outputs
#10; //wait 10 ns
//now print something:
$display("\n---------\nStarting Simulation!");
d0_in = 12; //change values!
d1_in = 45;
// run through all operations and monitor outputs
$display("d1_in d0_in sel_in res_out eq_out gt_out");
for(integer i = 0; i < 8; i = i + 1) begin
sel_in = i; //set sel_in
#10; //wait for a bit of time (10 ns)
//then evaluate outputs:
$display("%8b %8b %3b %15b %b %b", d1_in, d0_in, sel_in, res_out, eq_out, gt_out);
end
$display("\n---------\nFinishing Simulation!");
$finish; //finish simulation.
end
endmodule // alu_tb
If you place the testbench file in your sim folder, from the root of your project folder, you can do:
iverilog -g2012 -o sim/alu.out sim/alu_tb.sv hdl/alu.sv
and then
vvp sim/alu.out
and outputs should appear. Use and expand and modify this starting test case above to make sure your module is doing all the right operations when needed. Try a variety of input numbers! During Checkoff 2 you will be required to show your test case is testing your system working with at least the following input pairs of numbers for all eight operations:
d0=0
andd1=0
d0=100
andd1=10
d0=10
andd1=100
d0=42
andd1=42
d0=7
andd1=42
When you feel confident that your module is working, run it in the checker below. Do not just write your code in the checker without testing locally.
If you've done a rigorous job testing your design in simulation, then we should be ready to deploy it onto hardware.
Make an instance of your alu module inside your current top_level
module. Comment out the following three lines that are currently there, since you'll now be controlling those three sets of LEDs from your ALU. directly. :
assign led = sw;
assign rgb0[0] = 1'b1; //red channel of RGB LED 0
assign rgb1[2] = 1'b1; //blue channel of RGB LED 1
In addition, so you don't get distracted by the seven segment LEDs for this stage, change the values of ss0_an
and ss1_an
to all be 1
! This will turn off all the seven segment LEDs. Build, upload and make sure it works like the video below shows. Complete the integration of your ALU module into your FPGA so that it takes inputs and outputs from all the appropriate sinks and sources like shown in the video below.
Show your testbench testing everything. Demonstrate your final stystem working to a staff member.