Nand to Tetris in Verilog Part 1 - Icarus

This project contains info I found along the way on implementing the Nand2Tetris's Hack Computer in Verilog for the purpose of running on an FPGA. After completing the two Nand to Tetris classes on Coursera (from Shimon Schocken and Noam Nisan), I wanted to put the neat little computer onto an FPGA.

WARNING - although I might give hints toward the implementation and some code on the test setup, I would like to leave the actual Verilog implementation to the reader (this is an unofficial add on to the class itself). Also, I consider myself just a hobbyist in this area so I'm likely to make quite a few mistakes. The programming code is just a test wrapper, there's likely much better ways to do this. My main interest is to experiment, learn some of this stuff, and share bits of info along the way.

My first step was picking up some Verilog basics, I started with the Verilog Tutorial on Asic World and started using EDA Playground a bit. Eventually I got to the point that I wanted to compare quickly against the .CMP files created by the class and adopted Icarus Verilog for doing quick tests of my implementation via the command line. For that I picked up Icarus Verilog. I also ran into some problems along the way, watched portions of Bruce Land's videos and got some help on the Nand to Tetris forum (thanks Mark!). I think this portion might be taught using Logisim or Modelsim starter edition (part of Xilinx ISE or Vivado and Altera/Intel Quartus installs), but I was curious how far I could go on some of the OpenSource or just smaller tools.


First we take the existing Not.hdl implementation created in the course or following The Elements of Computing Systems - Building a Modern Computer from First Principles.


The original Not gate template - Not.hdl:

// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/01/Not.hdl

/**
 * Not gate:
 * out = not in
 */

CHIP Not {
    IN in;
    OUT out;

    PARTS:
    // Put your code here:
}


The original compare file - Not.cmp:

|  in   |  out  |
|   0   |   1   |
|   1   |   0   |

We then create a new file for the Verilog version that we implement.


Our Verilog design (code removed) - not.v:

module my_not(in, out);
  input in;
  output out;
  //CODE HERE
endmodule



And the corresponding test bench code in Verilog.

Our Verilog test bench - not.tst.v:

module test_not;
  reg in;
  wire out;
  integer notout;
  my_not MY_NOT(.in(in), .out(out));
  initial begin
    notout = $fopen("not.out", "w");
    $fwrite(notout, "|  in   |  out  |\n");
    in = 0; display();
    in = 1; display();
    $fclose(notout);
  end
  task display;
    #1
    $fwrite(notout, "|   %0b   |   %0b   |\n", in, out);
  endtask
endmodule

A small wrapper script can be used to compile the Verilog files (implementation and test bench), run the simulation, then compare against the original compare file given in the course. If we get no output, it's a success!

Our test bash script - not.tst.sh:

iverilog -onot.tst -Wall -g1995 not.v not.tst.v
vvp not.tst -fst
diff --strip-trailing-cr Not.cmp not.out

The idea is that each part from the class would be tested quickly from the command line, the comparison is done via diff (--strip-trailing-cr is helpful if you're using Windows and Mac or Linux interchangibly).


Resources (Nand to Tetris related):
The Elements of Computing Systems - https://www.nand2tetris.org
Build a Modern Computer from First Principles: From Nand to Tetris (Project-Centered Course) - https://www.coursera.org/learn/build-a-computer
Build a Modern Computer from First...

Read more »