Assignment 0: Hamming Distance Between Two 8-Bit Binary Integers

Hamming distance between two values is simply the number of bit positions that differ in value. There are essentially two little sub-problems. To determine which bits differ, simply take the exclusive-OR of the two values. Counting how many bits differ is then simply adding-up how many 1 bits were in the exclusive-OR result. Your project here is just to write synthesizable Verilog code that computes the Hamming distance using a purely combinatorial circuit.

Here's a really simple way to do this in Verilog for all possible pairs of 8-bit unsigned binary integers:

module demoham;
reg [7:0] a, b, h;
integer difbits, i;
initial begin
  a=0;
  repeat (256) begin
    b=0;
    repeat (256) begin
      difbits = a ^ b;
      h = 0;
      repeat (8) begin
        h = h + difbits[0];
        difbits = difbits >> 1;
      end
      $display("%d\t%d\t%d", a, b, h);
      b=b+1;
    end
    a=a+1;
  end
end
endmodule

Well, that was easy! The catch is that it isn't a synthesizable combinatorial circuit because the values of h and difbits change multiple times in computing a single result. Oh, and in this project you're also not allowed to use Verilog word-level operators like + for addition.

I want you to design a synthesizable, combinatorial logic, 8-bit Hamming distance circuit without using any of the Verilog word-level operators -- you cannot use +, >>, etc. I will allow you to operate on a word at a time, but only using assignment (to copy a value) or bitwise operators (such as ^ for XOR, so you can write something like a^b). That said, you are free to use any bit-level algorithm you wish for your synthesizable, purely combinatorial, circuit design.

Your Project

Your project is about writing a Verilog module called ham, 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:

  1. The definition of a module that starts with module refham(h, a, b); and computes the Hamming distance between the 8-bit values of a and b to give the 4-bit result h. Why is h four bits long? Because from 0 to 8 bits could differ. This module should be derived from the code for demoham above. It MUST use Verilog's + operator and doesn't need to be synthesizable. This is to be as straightforward an implementation as possible; it will serve as your oracle to deliver known correct answers. Incidentally, there are lots of online references for alternative algorithms to compute the Hamming distance; you may use any of them for your refham as long as you author the Verilog code yourself and it is expressed using word-level operators that you are not allowed to use in your ham module.
  2. The definition of a module that starts with module ham(h, a, b); and implements the Hamming distance computation for 8-bit values a and b to give the 4-bit result h. Of course, it may instantiate other combinatorial logic modules to implement its functionality, e.g., you might start with defining a four-bit incrementer module and instantiate eight copies of it within the definition of ham so that you can sum the eight 1-bit bit-position-difference values. Again, you have a free choice of algorithm. However, this module MUST be Verilog code that you author using synthesizable, purely combinatorial, logic -- it is NOT permitted to use word-level Verilog operators (as noted above) in itself nor in anything it instantiates.
  3. The definition of a non-synthesizable module that starts with module testbench; and instantiates a ham which it exhaustively tests for correctness. Note that it is not sufficient to just print what happens for all 65,536 possible combinations of inputs; I don't want just a stimulus module. Who would want to manually check 65,536 lines of output? Your testbench must not only try each possible input combination, but also must check that the answer from your ham matches the answer from refham in each case. Your testbench should only output the combinations of inputs for which the answer from ham was wrong. Further, it should count how many input combinations were correct and how many failed. The last line of text output should be generated by Verilog code like:
    $display("All cases tested; %d correct, %d failed", correct, failed);
    

Place all your verilog code for the above in one file called ham.v. That's the file you need to submit.

Naturally, I also expect you to run that file through a Verilog compiler either using our CGI interface or Icarus Verilog directly:

iverilog -o ham ham.v

And to run the simulation to test it:

vvp ham

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. ;-)

Details For The Implementor's Notes

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 ham module. That can be done as text. I am not requiring you to provide a schematic of your ham 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 I would encourage you to think about generating a VCD file and using gtkwave to visualize it, I don't think there's much point in doing that for a simple combinatorial circuit like ham. If you do find it useful, you may include a screen grab from gtkwave in your implementor's notes.

Due Dates

The recommended due date for this assignment is before class, Friday, January 26, 2018. This submission window will close when class begins on Friday, February 2, 2018. You may submit as many times as you wish, but only the last submission that you make before class begins on Friday, February 2, 2018 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!)

Submission Procedure

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 ham.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).

Submissions are logged using the account name by which you registered for EE480, which generally is 6 or 7 characters long and has uppercase letters.

Your account is .

The password for your account is computed by the formula ((SID / 10000) + SID) % 10000, where SID is your student ID number. The value is padded with leading zeros to be 4 characters long if it had fewer digits.

Your password is


EE480 Advanced Computer Architecture.