Lab 1 - ALU

CIS 371 (Spring 2013): Computer Organization and Design

Instructor:Prof. Milo Martin
Demo Due:Although we encourage you to demo early, your demo must be completed by Thursday, February 7th (you must demo it in the KLab by 6pm)
Writeup Due:Friday, February 8th (turn in PDF via Canvas)
Instructions:This lab should be done in groups of three



In this lab, you'll create a key component of the processor: the ALU for the LC4. We're providing the Verilog module definitions and testing harness to help you test your designs in ISim. The testbench code uses Verilog file I/O and other advanced features of Verilog, which is why we've provided it to you.


ISim is the software we'll use for simulating and debugging Verilog. You'll want to work through the ISim tutorial.

Part A: DIV/MOD Module

LC4 contains the DIV (divide) and MOD (modulo) instructions. To complete the ALU that you will use in your single-cycle design, the first step is to create the logic fo a single-cycle DIV/MOD calculation. This is the same calculation as the multi-cycle DIV/MOD given below, but done in a single cycle using combinational logic only.

DIV/MOD Specification

The DIV/MOD module will be in the file lc4_divider.v.

`timescale 1ns / 1ps

module lc4_divider(dividend_in, divisor_in, remainder_out, quotient_out);
   input [15:0] dividend_in, divisor_in;
   output [15:0] remainder_out, quotient_out;

   /*** YOUR CODE HERE ***/


The module takes as input two 16-bit data values (dividend and divisor) and outputs two 16-bit values (remainder and quotient). It calculates using the following algorithm:

int divide(int dividend, int divisor)
  int quotient = 0;
  int remainder = 0;

  if (divisor == 0) {
    return 0;

  for (int i = 0; i < 16; i++) {
    remainder = (remainder << 1) | ((dividend >> 15) & 0x1);
    if (remainder < divisor) {
      quotient = (quotient << 1) | 0x0;
    } else {
      quotient = (quotient << 1) | 0x1;
      remainder = remainder - divisor;
    dividend = dividend << 1;

  return quotient;


I suggest that you create a module that does one "iteration" of the division operation. You can then instantiate 16 copies of this module to form the full divider.

`timescale 1ns / 1ps

module lc4_divider_one_iter(dividend_in, divisor_in, remainder_in, quotient_in, 
                            dividend_out, remainder_out, quotient_out);
   input [15:0] dividend_in, divisor_in, remainder_in, quotient_in;
   output [15:0] dividend_out, remainder_out, quotient_out;
   /*** YOUR CODE HERE ***/

DIV/MOD Testing

The testbench for the DIV/MOD unit is

Part B: ALU Module

The LC4 ALU module performs all of the arithmetic and logical operations for the various instructions. In this lab you'll build a self-contained ALU datapath with the corresponding control signals.

ALU Specification

The ALU module will be in the file lc4_alu.v.

`timescale 1ns / 1ps

module lc4_alu(insn, pc, r1data, r2data, out);
   input [15:0] insn, pc, r1data, r2data;
   output [15:0] out;
   /*** YOUR CODE HERE ***/


The module takes as inputs two 16-bit data values, a 16-bit instruction, the 16-bit PC value, and it generates a single 16-bit output. The two data inputs correspond to the two register values coming directly out of the register file. The output will be:

  • For basic ALU operations (ADD, MUL, SUB, AND, NOT, OR, XOR, SLL, SRA, SLA, CONST, HICONST, etc.) the output of the ALU is the value the instruction will write back to the register file.
  • For memory operations (LDR, STR) the output of the ALU is the generated effective memory address that will be later used as the address input into the data memory.
  • For comparison instructions (CMP, CMPU, CMPI, CMPIU), the output will be zero (00000000000000), one (00000000000001), or negative one (1111111111111111), depending on the result of the comparison. This output value will then later be used to set the NZP bits.
  • For branch instructions (JSRR, JMPR, BR, JMP, TRAP, RTI), the output should be the "taken" branch target (that is, the PC of the next instruction). For conditional branches (BR), this ALU module does not know the state of the condition codes (NZP), so the ALU calculates the target of the branch if the branch is indeed taken.
  • For DIV and MOD, use the module described above that computes the quotient and remainder of the inputs. Do not use the built in '/' and '%' operators; they will not synthesize.
  • For all other instructions (NOP), the output should be all zeros.

If any of the cases are ambiguous, please let us know and we'll clarify.

ALU Schematic

First draw a detailed schematic (by hand or computerized) of the hardware design, including signal names, sub-modules, etc. Only once you have the design on paper in schematic form, then translate it directly to Verilog. That is, your Verilog should correspond to the schematic exactly.

ALU Implementation

To implement the basic operations of the ALU, including + and *, use the built in Verilog operators. To implement the shifter, I suggest implementing a barrel shifter as described in lecture. For signed and unsigned comparisons, consider extending the 16-bit values into 17-bit values (with either zero extend or sign extend, as appropriate), performing the subtraction, and then setting the output accordingly.


Let me repeat, you do not need to write your own adder or multiplier. Just use the builtin + and * operators. Division and modulo, however, does need its own implementation.

ALU Testing

The testbench for the ALU is and the input trace is test_lc4_alu.input.

Verilog Restrictions

This synthesizable part of this lab should be implemented using the structural and behavioral Verilog subset as in presented in the class notes. In this lab, you should use only combinational logic (no state elements). If you're not sure if you're allowed to use a certain Verilog construct, just ask (post a message on the forums).


You'll show the TAs your schematics, your code, and demonstrate that your design works using the simulation testbenches.


All group members should be present at the demo.

What to Turn In

Turn in a single PDF via Canvas that contains all of the following: