Spring 2016 CSCI 320 Homework 5

The assignment

This is a assignment, involving multiple subparts, to create a simple 16-bit serial ALU in SystemVerilog.

The serial ALU has three inputs: a 1-bit CLOCK, a 7-bit INSTRUCTION, and a 16-bit INPUT. It also has three outputs: a 16-bit OUTPUT and a 3-bit STATUS. The serial ALU also has an internal memory of three 16-bit words, which we will call REG1, REG1 and REG3.

The 7-bit ALU instruction has three fields stored in the following order: a 3-bit OPCODE, a 2-bit SOURCE and a 2-bit TARGET. There are eight possible OPCODE values, which are interpretted according to the following table.

000ADDUunsigned addition
001SUBUunsigned subtraction
010ADDSsigned addition
011SUBSsigned subtraction
100ANDbit-wise AND
101ORbit-wise OR
110XORbit-wise XOR
111LDSTload and store

The 2-bit SOURCE and TARGET fields specify registers. The 2-bit values 01 to 11 specify registers REG1 to REG3. The 2-bit value 00 is a bit more special. If the SOURCE is 00, it refers to the INPUT port. If the TARGET is 00, use the INPUT as the argument but don’t store the result in any register. Just send it to the OUTPUT port.

The 3-bit STATUS field is composed of the one-bit fields.

Only the addition and subtraction operations can generate a carry or overflow. (If an unsigned subtraction generates a negative result, the V bit should be set. This makes the problem a little simpler. It means that C and V are the same for unsigned operations.) For all other operations, the C and V bits must be 0.


The INSTRUCTION and INPUT bits are sampled on the positive edge of CLOCK. The related OUTPUT and RESULT bits are generated before the next positive edge. The OUTPUT bits should always contain the result of the last intruction.


There is no reset input. The registers of the serial ALU are initialized with LDST instructions.

An example

The following program adds 320 and 255.


The assignments

It’s a multi-part assignment due on several successive Friday afternoons. Keep up.

Homework 5A

Write a sequence of bits for the following “program.”

REG1 = -17 ;
REG2 = 5 ;
REG3 = REG1 & REG2 ;
output REG1 + REG3 ;
REG2 = (unsigned) REG1 + 14u | 0x23 ;
REG1 = 9000 + 9000 ;

Also give the values of the OUTPUT and STATUS ports after each ALU instruction.

This is due in-class (5:10 PM) on 22 March or may be uploaded to the Homework 5A moodle submission page.

A reference implementation

In order to provide some experimentation at the command line, I am providing a Python implementation of the serial ALU. The implementation is in two parts.

Here are two more files that should be of interest.

The ultimate goal of this homework assignment is to implement the clock method of the SerialALU class in SystemVerilog. This implementation (until corrected by one of you), will also serve as the official reference implementation for the assignment.

Python does not excel at bit level manipulation. Consequently, “translating” the Python into SystemVerilog would be a very bad idea. Furthermore, the clock method of SerialALU has been purposely written with excessive cut-and-paste in the “switch” for the opcodes. This makes it relatively easy to understand, but it also introduces a great deal of redundancy in the code. This is something you will need to improve in your SystemVerilog implementation. One particular expected improvement is creating an implementation with only one adder.

Homework 5B

There are two very different tasks for this assignments.

Task I

There are eight possible values for the STATUS bits. The example output file show how to generate four of the eight possible values.

Just to show off your deep understanding of this problem; expand the test input file so that it generates all eight possible values of the STATUS bits.

Task II

Create a ModelSim project that module interface for the ultimate SystemVerilog implementation for this assignment. This is only two statements: One begins with the keyword module, and the other is just the keyword endmodule.

Turning it in

Upload your expanded test input file and your complete ZIPed ModelSim project to the Homework 5B moodle submission page by 11:55 PM on Tuesday, 29 March.

Do not just download a .sv file!

Homework 5C

The official module header

Now that Homework 5B is done, we need to all adopt a common module header; hence this decree. The official module header for Homework 5 appears below.

module SerialALU
      (input   logic        CLOCK,
       input   logic  [6:0] INSTRUCTION,
       input   logic [15:0] INPUT,
       output  logic  [2:0] STATUS,
       output  logic [15:0] OUTPUT
      ) ;


Because SystemVerilog supports both position and keyword parameters, you should use these exact names in your implementation.

The task

Going directly to a SystemVerilog implementation might be a bit much. Let’s try something a medium-size step.

Rather than worrying about handling the clock and loading registers, add the following to your SystemVerilog program. This little section of code will give some fixed values to the registers.

   logic [15:0] register [1:3] ;
       register[1] = 16'd320 ;
       register[2] = 16'hbeef ;
       register[3] = 16'hfade ;

Repeatedly pulling bits out of INSTRUCTION with SystemVerilog using vector part-selects, such as INSTRUCTION[4:3], will get tiresome quickly. Add the three declarations to your program.

   logic [2:0] OPCODE ;
   logic [1:0] SOURCE ;
   logic [1:0] TARGET ;

Now write one line on your own. Add the one-line statement needed to set OPCODE, SOURCE and TARGET from INSTRUCTION. Use an concatenation expression or aggregate epxression (SystemVerilog terminology is a bit confusing here) on the left-hand side.

Now you’re on a roll. Time to read some registers. Add the following declarations for variables to hold the ALU operands.

   logic [15:0] source_value ;
   logic [15:0] target_value ;

Now, write the SystemVerilog to determine the operands for the ALU. This one is going to require two lines if you use SystemVerilog’s borrowing of C’s conditional operator. (You need the ? : because the ALU sometimes takes it operands from INPUT.)

Finally, just so we can do a little testing, add a SystemVerilog statement to set OUTPUT to the exclusive-or of source_value and target_value.

Turning it in

Once again, upload your complete ZIPed ModelSim project to the Homework 5C moodle submission page by 11:55 PM on Tuesday, 5 April.


Homework 5D

This is a another medium step.

Complete the entire project except for the memory part. All eight instructions must be implemented, probably with some very large case statements inside a always_comb or two. SystemVerilog’s conditional operator which looks like Java’s conditional operator may also be useful. My solution has lots of conditional operators inside of assign statements.

Don’t try to do this in one medium step. Several baby steps can equal one medium step. Start with the non-arithmetic instructions.

Turning it in

Once again, upload your complete ZIPed ModelSim project to the Homework 5D moodle submission page by 11:55 PM on Friday, 15 April.

Homework 5E

This is a another little project.

Complete the entire project except for the memory part.

The only difference from Homework 5D is that the STATUS bits need to be completed. Pay attention to the description. Some parts aren’t that hard. The Z bit is computed the same for all eight instructions. (It’s a one-liner.) The C and V are 0 for all the logical (not arithmetic) operations.

When you add and subtract, store your result in a 17-bit value! The C bit will be the extra bit! (That’s another one-liner.) For unsigned arithmetic operations, the V is the same as the C bit, by assignment definition. For signed arithmetic operations, you may need to do a little review. (It’s another one-liner, but it’s quite a bit longer.)

Turning it in

Once again, upload your complete ZIPed ModelSim project to the Homework 5E moodle submission page by 11:55 PM on Tuesday, 19 April.

Homework 5∞

Complete the entire project and upload it to the Homework 5 moodle submission page by 11:55 PM on Friday, 22 April.

This last step is pretty easy. All you have to do is update the register. It will look something like this.

   always_ff @(posedge CLOCK)
     if (TARGET != 0)
         register[TARGET] = OUTPUT ;

This is a Mealy implementation. It will be a little tricky to debug. A Moore might be harder to debug.