## 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.

`OPCODE` | value | action |
---|---|---|

000 | `ADDU` | unsigned addition |

001 | `SUBU` | unsigned subtraction |

010 | `ADDS` | signed addition |

011 | `SUBS` | signed subtraction |

100 | `AND` | bit-wise AND |

101 | `OR` | bit-wise OR |

110 | `XOR` | bit-wise XOR |

111 | `LDST` | load 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.

- Bit 2 (most signficant) is the
`Z`

bit. It is one only if the result of an operation is zero. - Bit 1 (the middle) is the
`C`

bit. It is one only the operation generates a carry. - Bit 0 (least significant) is the
`V`

bit. It is one only the operation overflows.

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.

### Clocking

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.

### Reset?

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.

`OPCODE` | `INPUT` |
---|---|

1110001 | 0000000101000000 |

1110010 | 0000000011111111 |

0000110 | 1001001001001001 |

## 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.

- hw5.py —
A Python
*main*problem that parses input, calls a serial ALU class, and prints results - SeriaALU.py —
A Python class,
`SerialALU`

, that implements the serial ALU

Here are two more files that should be of interest.

- hw5test.txt — An input file for testing the Python serial ALU
- hw5out.txt — A corresponding output file

*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 ) ; endmodule

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] ; initial begin register[1] = 16'd320 ; register[2] = 16'hbeef ; register[3] = 16'hfade ; end

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.

#### Solution

### 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.