Lab 6 - Building an ALU

1 Objectives

Upon completion of this lab you should be able to create and test a design using the Xilinx ISE tools.

2 General

This lab will guide you through building and testing an ALU. We will follow the "Top-down design; bottom-up implementation" approach.

3 Building a 1-bit adder

  1. Start Xilinx ISE 14.7

  2. Select File > New Project... to open the "New Project Wizard."

    1. In the "Create New Project" dialog:

      1. enter "alu" for the "Name",
      2. choose the "Location",
      3. CRITICAL: change the "Working directory" to "the location selected above/work",
      4. select "HDL" as the "Top-Level Source Type", and
      5. click "Next".
    2. In the "Project Settings" dialog, enter the following properties:

      • Family: Spartan3E
      • Device: XC3S500E
      • Package: FG320
      • Speed: -4
      • Synthesis Tool: XST (VHDL/Verilog)
      • Simulator: ISim (VHDL/Verilog)
      • Preferred Language: Verilog

      and click "Next".

    3. Click "Finish" in the "Project Summary" dialog.

    Note: You can change the project properties by right clicking on the device (i.e. xc3s500e-4fg320) in the "Hierarchy" section of the "Design" tab and selecting "Design Properties..."

  3. Add a new source to the project. There are a number of ways that you can do this:

    • Right click on the device in the "Hierarchy" section of the "Design" tab and select "New Source..."
    • Select Project > New Source...
    • Click the "New Source" icon in the toolbar.

    The "New Source Wizard" should appear.

    1. In the "Select Source Type" dialog, select "Verilog Module", enter "add1b" as the "File name:" and click "Next". 2 Your part will have inputs a, b, ci, and output r, co.
  4. In add1b.v implement the following logic:

    $$ r = ci\cdot\overline{a}\cdot\overline{b} + \overline{ci}\cdot a\cdot\overline{b} + \overline{ci}\cdot\overline{a}\cdot b + ci\cdot a\cdot b$$

    and

    $$ co = ci\cdot a + ci\cdot b + a\cdot b$$

    where \(a\) and \(b\) are inputs to the adder, \(ci\) is the carry-in, \(r\) is the result, and \(co\) is the carry-out.

    • You should build the logic using and logic, or logic and, inversion.
    • It's probably easiest to build this part using assign blocks. You will need two assignments: one for r and one for co.
    • To check your code, use the "Check Syntax" option from Processes frame in the design tab.
    • You should verify your design produces a circuit that looks like an adder. In the part Hierarchy, make sure your adder is the "Top Module"; right-click and set it if not. Then, in the processes frame, run Synthesize > View RTL Schematic to explore the circuit.
    • Try to create your own design. However if you get stuck, here's a schematic implementation that might be helpful.
  5. Make sure add1b.v is set as the top level module and synthesize it. Correct any errors.

  6. Create a testbench.

    1. At the top of the "Design" tab, select the "Simulation" view.

    2. Add a new source to the project.

      • For source type select "Verilog Test Fixture" and filename add1b_tb_0.
      • On the "Associate Source" dialog select "add1b" and click "Next".
      • Click "Finish".
    3. In the "Hierarchy" section of the "Design" tab, double-click on add1b_tb_0.v and examine the test bench.

    4. Edit the verilog code to fully test the adder.

      • Feel free to change the module name to something more reasonable. I used add1b_tb_0.

      • Delete the default test sequence between the initial begin and the end. If there is an auto_init section like the following, delete it.

           `ifdef auto_init
                initial begin
                ci = 0;
                b = 0;
                a = 0;
           `endif
      • Add the following section in its place.

           initial begin
              ci = 0;
              b = 0;
              a = 0;
              // Wait 100ns for the simulator to finish initializing
              #100;
              a = 1;
              #1;
              $write("a=%b, b=%b, ci=%b, r=%b, co=%b ", a,b,ci,r,co);
              if ((r == 1) && (co == 0))
                $display(": pass");
              else
                $display(": fail");
           end

        Notes on the verilog code.

        • "ci = 0" initializes the signal ci to 0. Constants are assumed to be decimal integers unless specified otherwise. For example "4'b0101" specifies a 4-bit binary value and "4'h5" specifies the same thing as a 4-bit hexadecimal value.
        • "#100" causes a delay if 100 time units.
        • "$write" will print a message on the simulation console without an ending newline.
        • "$display" will print a message on the simulation console with an ending newline.
        • Both "$write" and "$display" can use printf style syntax to print variable values.
      • Add additional verilog code to the initial block to fully test the adder.

  7. Perform a behavioral simulation of your design (see lab 0 if necessary for instructions on how to perform a behavioral simulation). Verify correct results. Modify your design if necessary

4 Building a 1-bit ALU

  1. Create a new module named alu1b.v. It have the same inputs as the 1-bit adder with the addition of a 3-bit op input which specifies which operation to perform: a, b, ci, op[2:0]. It will have the same outputs as the adder: r, co.

  2. Enter the logic design for your 1bit ALU. You will need to use the 1-bit adder constructed above when building your 1-bit ALU. The ALU should perform the following operations:

    Function op
    and 000
    or 001
    add 010
    subtract 110
    set less than 111

    Subtract should be implemented by taking the 1's complement of \(b\) and setting \(ci\) of the least significant bit to a 1. Support for set less then should be included, but won't actually be implemented until later. Set less then will require an input less and an output set. See Appendix B of your book.

    A sample schematic design without the subtract and slt logic is available in alu1b_schem.pdf. For this design you will need a 4 input 1bit mux. You should use the design from class and modify it to suit your needs. You can also use a verilog if or case statement to control the logic, but these statements sometimes require register variables which may introduce a delay in your design.

  3. Set this ALU as the top module and check the resulting RTL layout to verify your design is reasonable.

  4. Create a new testbench named alu1b_tb_0.v and test your design. Make sure to test your part throughly. It will not be possible to test subtract or slt with only a 1bit ALU. You may want to delay those tests till you have the 4bit module.

  5. Perform a behavioral simulation of your design. Verify correct results. Modify your design if necessary

5 Building a 4-bit ALU

Using the 1-bit alu constructed above, design a 4-bit ALU. In addition to the basic operations performed by the 1-bit ALU, the 4-bit ALU should have an overflow detector and a zero detector. Be sure finish implementing subtract and set less than.

Your 4-bit ALU should have 2, 4-bit inputs, a and b, a 3-bit input op, a 4-bit output r, and 2 1-bit outputs, zero and ovfl.

  1. Create a new module named alu.v and enter your design.
  2. Create a new testbench named alu_tb_0.v to test your design.
  3. Perform a behavioral simulation of your design. Verify correct results. Modify your design if necessary
  4. Demonstrate your 4-bit ALU to your instructor.

6 Turning It In

Demonstrate your working ALU to your instructor.

Submit the instructor verification sheet in hard copy.

Only one lab should be submitted for each project team. Make sure all team member's names are included on your submission.