An 8-bit unsigned number can hold any value from 0 to 255. That means subtracting one such value from another can result in a value from -255 to 255... and many of those possible result values do not fit in 8 bits. Let's take a particular example. What is 0-1? Well, recall that a-b is formally equivalent to a+(~b)+1, which means 0-1 is (8'b00000000 + (8'b11111110)) + 8'b00000001, or 8'b11111111. The catch is, despite representing -1, it looks exactly like 255. This unfortunate wrap-around of values can cause serious problems for "natural data types" -- values representing pixel color data, audio samples, etc. So, the answer we really want is that the result should be 0 because in the 0 to 255 range, the representable value closest to -1 is 0.
The fix is pretty simple. Conventional computer arithmetic is technically known as modular arithmetic: the result for an out-of-range value is simply the low bits of the correct value. What we need instead is saturation arithmetic: the result for an out-of-range value is the limit value in that direction. For unsigned 8-bit numbers, that means 0 for the low and 127 for the high. Here's a little Verilog program to compute the unsigned saturation values for subtracting on 8-bit number from another:
module demosatsub8; reg [7:0] t, a, b; initial begin a=0; repeat (256) begin b=0; repeat (256) begin if (a < b) t = 0; else t = a - b; $display("%d\t%d\t%d", a, b, t); b=b+1; end a=a+1; end end endmodule
Well, that was easy! Yeah, but that's not what I want you to do. I want you to design a synthesizable, combinatorial logic, 8-bit unsigned saturation subtractor without using the Verilog +, -, or < operator -- or anything else that automatically builds the subtract or less than comparison for you. The constraint is basically that you cannot use any word-level Verilog operators that do not function on each bit independently: for example, copying a value, bitwise AND, shift by a constant, and even the ?: operator are allowed. Of course, you don't need to write any Verilog assignments; the whole thing could be implemented by instantiating gates. Speed and gate-count of your design is not an issue; feel free to use whatever algorithm you wish -- or whatever seems easiest. Incidentally, if you think about it, there is a fairly obvious algorithm you could use to implement this without needing a < operation....
Your project is about writing a Verilog module called satsub, but there are actually two other chunks of Verilog code you need in order to test it. The three required modules of Verilog code are:
$display("All cases tested; %d correct, %d failed", correct, failed);
Place all your verilog code for the above in one file called satsub.v. That's the file you need to submit.
Naturally, I also expect you to run that file through a Verilog compiler. You can use either the WWW form version made for this course or Icarus Verilog directly:
iverilog -o satsub satsub.v
And to run the simulation to test it:
vvp satsub
Which will hopefully result in it printing just:
All cases tested; 65536 correct, 0 failed
If not, and you can't figure-out how to fix it, as Ricky Ricardo would say, you got some splainin to do. ;-)
You should be submitting an implementor's notes document with your project. Just a couple of quick comments about that....
Your implementor's notes certainly should describe the logic used to implement your satsub module. That can be done as text. I am not requiring you to provide a schematic of your satsub module... but practice creating schematics is certainly a good thing (i.e., a skill you will need in this course) and it wouldn't hurt to include a schematic.
Although you could generate a VCD file and using gtkwave to visualize it, I don't think there's much point in doing that for satsub. If you do find it useful, you may include a screen grab from gtkwave in your implementor's notes.
The recommended due date for this assignment is before class, Friday, February 7, 2020. This submission window will close when class begins on Feb 10, 2020. You may submit as many times as you wish, and all submissions are archived (although the only confirmation you'll get is a response WWW page), but only the last submission that you make before class begins on Feb. 10, 2020 will be counted toward your course grade.
Note that you can ensure that you get at least half credit for this project by simply submitting a tar of an "implementor's notes" document explaining that your project doesn't work because you have not done it yet. Given that, perhaps you should start by immediately making and submitting your implementor's notes document? (I would!)
For each project, you will be submitting a tarball (i.e., a file with the name ending in .tar or .tgz) that contains all things relevant to your work on the project. Minimally, each project tarball includes the source code for the project and a semi-formal "implementors notes" document as a PDF named notes.pdf. It also may include test cases, sample output, a make file, etc., but should not include any files that are built by your Makefile (e.g., no binary executables). For this particular project, name the Verilog source file satsub.v.
Submit your tarball below. The file can be either an ordinary .tar file created using tar cvf file.tar yourprojectfiles or a compressed .tgz file file created using tar zcvf file.tgz yourprojectfiles. Be careful about using * as a shorthand in listing yourprojectfiles on the command line, because if the output tar file is listed in the expansion, the result can be an infinite file (which is not ok).