From 527933b985b92ea57a2f24d1ca4489a01ff300c0 Mon Sep 17 00:00:00 2001 From: Ben Hill Date: Fri, 8 Sep 2017 15:57:02 -0400 Subject: [PATCH] Updated README instructions --- README.md | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++- a.out | 59 +++++++++++++++++++++++++ hw1.t.v | 24 +++++++++++ hw1.v | 24 +++++++++++ results.txt | 5 +++ 5 files changed, 231 insertions(+), 2 deletions(-) create mode 100755 a.out create mode 100644 hw1.t.v create mode 100644 hw1.v create mode 100644 results.txt diff --git a/README.md b/README.md index d3c33f1..551689c 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,119 @@ -# HW1 -HW 0b001: Verilog Tools and DeMorgan's Law +# HW 0b001: Verilog Tools and DeMorgan's Law + +*Due: Friday, September 15* + +## Install tools +For this assignment you will need the [Icarus Verilog](http://iverilog.icarus.com/) simulator (`iverilog`). You can manually install it (fairly easy), or wait for the forthcoming course virtual machine that includes it (along with several other tools you'll need later in the class). + +## Hello, Verilog! + +In your favorite text editor, create a file named `hello.v` with the following contents: + +```verilog +// Simple Verilog test +module hello_test (); +initial begin + $display("Hello, CompArch!"); +end +endmodule +``` + +We can run the test through `iverilog` with the following commands: + +``` +iverilog -o hello hello.v +./hello +``` + +`iverilog` actually creates an executable program based on your Verilog (here, `hello`), which you then run to see the simulation results. If you do not specify `-o `, the executable will be called `a.out` just like for a C compiler. + +## Your first Verilog + +Prove DeMorgan’s Law using the exhaustive proof method. To do so, you will use Verilog to create truth tables for the following 4 equations: + +![DeMorgan's Equations](img/eqn.JPG) + +### Schematic capture +First, draw a schematic of each of the four equations (on paper is fine). To help you get started, here is one for `(~A)*(~B)`: + +![Schematic](img/schem1.jpg) + +Then, give each gate and each wire a name. `A` and `B` are already named. + +![Labeled schematic](img/schem2.jpg) + +### Translate to Verilog +Each element becomes a line of Verilog. Create a new Verilog file called `hw1.v` to contain your module. Here is the schematic above, captured: + +```verilog +module demorgan +( + input A, // Single bit inputs + input B, + output nA, // Output intermediate complemented inputs + output nB, + output nAandnB // Single bit output, (~A)*(~B) +); + + wire nA; + wire nB; + not Ainv(nA, A); // Top inverter is named Ainv, takes signal A as input and produces signal nA + not Binv(nB, B); + and andgate(nAandnB, nA, nB); // AND gate produces nAandnB from nA and nB + +endmodule +``` + +### Create a testbench +The statements above show the structure of the module. We still need to add some stimuli to drive the module for testing. We will write this test code within an Verilog `initial` block. You could put the test code within the module we wrote previously, but it is better practice to separate circuits and their tests. + +Create a new file called `hw1.t.v` with the following contents: + +```verilog +`include "hw1.v" + +module demorgan_test (); + + // Instantiate device/module under test + reg A, B; // Primary test inputs + wire nA, nB, nAandnB; // Test outputs + + demorgan dut(A, B, nA, nB, nAandnB); // Module to be tested + + + // Run sequence of test stimuli + initial begin + $display("A B | ~A ~B | ~A~B "); // Prints header for truth table + A=0;B=0; #1 // Set A and B, wait for update (#1) + $display("%b %b | %b %b | %b ", A,B, nA, nB, nAandnB); + A=0;B=1; #1 // Set A and B, wait for new update + $display("%b %b | %b %b | %b ", A,B, nA, nB, nAandnB); + A=1;B=0; #1 + $display("%b %b | %b %b | %b ", A,B, nA, nB, nAandnB); + A=1;B=1; #1 + $display("%b %b | %b %b | %b ", A,B, nA, nB, nAandnB); + end +endmodule // End demorgan_test +``` + +When you use `iverilog` to run `hw1.t.v`, you should see the following output: + +``` +A B | ~A ~B | ~A~B +0 0 | 1 1 | 1 +0 1 | 1 0 | 0 +1 0 | 0 1 | 0 +1 1 | 0 0 | 0 +``` + +### Add the other 3 equations +Continue in the manner described above to create the remaining three equations. Your final result should exhaustively prove DeMorgan's Laws. + + +## Submission +Create a plain text `results.txt` file containing your completed truth table. Push `results.txt`, `hw1.v`, and `hw1.t.v` to your Github in the HW1 folder. There is no write-up or other deliverable. Note: you should get in the habit of using the exact filenames and module names specified, as we will occasionally use automated grading tools. + +## Tips and Tricks + - If a signal shows up as “z”, it means it is not being driven. Are you sure you wired it? + - The `$display` syntax is similar to what you might find in a `printf` style args function. The first input is a format string. `%b` means "interpret the next argument as a bit and display it here". + - `begin` and `end` are the equivalent of `{` and `}` in C. diff --git a/a.out b/a.out new file mode 100755 index 0000000..a24e658 --- /dev/null +++ b/a.out @@ -0,0 +1,59 @@ +#! /usr/bin/vvp +:ivl_version "0.9.7 " "(v0_9_7)"; +:vpi_time_precision + 0; +:vpi_module "system"; +:vpi_module "v2005_math"; +:vpi_module "va_math"; +S_0x20e1920 .scope module, "demorgan_test" "demorgan_test" 2 3; + .timescale 0 0; +v0x2116b80_0 .var "A", 0 0; +v0x2116c20_0 .var "B", 0 0; +v0x2116cd0_0 .net "nA", 0 0, L_0x2117140; 1 drivers +v0x2116d80_0 .net "nAandnB", 0 0, L_0x21173f0; 1 drivers +v0x2116e60_0 .net "nAornB", 0 0, L_0x2117340; 1 drivers +v0x2116f10_0 .net "nB", 0 0, L_0x2117240; 1 drivers +v0x2116f90_0 .net "n_AandB", 0 0, L_0x21175c0; 1 drivers +v0x2117040_0 .net "n_AorB", 0 0, L_0x2117620; 1 drivers +S_0x20cc690 .scope module, "dut" "demorgan" 2 9, 3 1, S_0x20e1920; + .timescale 0 0; +L_0x2117140 .functor NOT 1, v0x2116b80_0, C4<0>, C4<0>, C4<0>; +L_0x2117240 .functor NOT 1, v0x2116c20_0, C4<0>, C4<0>, C4<0>; +L_0x2117340 .functor AND 1, L_0x2117140, L_0x2117240, C4<1>, C4<1>; +L_0x21173f0 .functor OR 1, L_0x2117140, L_0x2117240, C4<0>, C4<0>; +L_0x21175c0 .functor NOR 1, v0x2116b80_0, v0x2116c20_0, C4<0>, C4<0>; +L_0x2117620 .functor NAND 1, v0x2116b80_0, v0x2116c20_0, C4<1>, C4<1>; +v0x20cc780_0 .net "A", 0 0, v0x2116b80_0; 1 drivers +v0x2116680_0 .net "B", 0 0, v0x2116c20_0; 1 drivers +v0x2116720_0 .alias "nA", 0 0, v0x2116cd0_0; +v0x21167c0_0 .alias "nAandnB", 0 0, v0x2116e60_0; +v0x2116870_0 .alias "nAornB", 0 0, v0x2116d80_0; +v0x2116910_0 .alias "nB", 0 0, v0x2116f10_0; +v0x21169f0_0 .alias "n_AandB", 0 0, v0x2117040_0; +v0x2116a90_0 .alias "n_AorB", 0 0, v0x2116f90_0; + .scope S_0x20e1920; +T_0 ; + %vpi_call 2 14 "$display", "A B | ~A ~B | ~A~B | ~A+~B | ~(AB) | ~(A+B) "; + %set/v v0x2116b80_0, 0, 1; + %set/v v0x2116c20_0, 0, 1; + %delay 1, 0; + %vpi_call 2 16 "$display", "%b %b | %b %b | %b | %b | %b | %b ", v0x2116b80_0, v0x2116c20_0, v0x2116cd0_0, v0x2116f10_0, v0x2116d80_0, v0x2116e60_0, v0x2116f90_0, v0x2117040_0; + %set/v v0x2116b80_0, 0, 1; + %set/v v0x2116c20_0, 1, 1; + %delay 1, 0; + %vpi_call 2 18 "$display", "%b %b | %b %b | %b | %b | %b | %b ", v0x2116b80_0, v0x2116c20_0, v0x2116cd0_0, v0x2116f10_0, v0x2116d80_0, v0x2116e60_0, v0x2116f90_0, v0x2117040_0; + %set/v v0x2116b80_0, 1, 1; + %set/v v0x2116c20_0, 0, 1; + %delay 1, 0; + %vpi_call 2 20 "$display", "%b %b | %b %b | %b | %b | %b | %b ", v0x2116b80_0, v0x2116c20_0, v0x2116cd0_0, v0x2116f10_0, v0x2116d80_0, v0x2116e60_0, v0x2116f90_0, v0x2117040_0; + %set/v v0x2116b80_0, 1, 1; + %set/v v0x2116c20_0, 1, 1; + %delay 1, 0; + %vpi_call 2 22 "$display", "%b %b | %b %b | %b | %b | %b | %b ", v0x2116b80_0, v0x2116c20_0, v0x2116cd0_0, v0x2116f10_0, v0x2116d80_0, v0x2116e60_0, v0x2116f90_0, v0x2117040_0; + %end; + .thread T_0; +# The file index is used to find the file name in the following table. +:file_names 4; + "N/A"; + ""; + "hw1.t.v"; + "./hw1.v"; diff --git a/hw1.t.v b/hw1.t.v new file mode 100644 index 0000000..4f8c17b --- /dev/null +++ b/hw1.t.v @@ -0,0 +1,24 @@ +`include "hw1.v" + +module demorgan_test (); + + // Instantiate device/module under test + reg A, B; // Primary test inputs + wire nA, nB, nAandnB, nAornB, n_AandB, n_AorB; // Test outputs + + demorgan dut(A, B, nA, nB, nAandnB, nAornB, n_AandB, n_AorB); // Module to be tested + + + // Run sequence of test stimuli + initial begin + $display("A B | ~A ~B | ~A~B | ~A+~B | ~(AB) | ~(A+B) "); // Prints header for truth table + A=0;B=0; #1 // Set A and B, wait for update (#1) + $display("%b %b | %b %b | %b | %b | %b | %b ", A,B, nA, nB, nAandnB, nAornB, n_AandB, n_AorB); + A=0;B=1; #1 // Set A and B, wait for new update + $display("%b %b | %b %b | %b | %b | %b | %b ", A,B, nA, nB, nAandnB, nAornB, n_AandB, n_AorB); + A=1;B=0; #1 + $display("%b %b | %b %b | %b | %b | %b | %b ", A,B, nA, nB, nAandnB, nAornB, n_AandB, n_AorB); + A=1;B=1; #1 + $display("%b %b | %b %b | %b | %b | %b | %b ", A,B, nA, nB, nAandnB, nAornB, n_AandB, n_AorB); + end +endmodule // End demorgan_test diff --git a/hw1.v b/hw1.v new file mode 100644 index 0000000..72f85a6 --- /dev/null +++ b/hw1.v @@ -0,0 +1,24 @@ +module demorgan +( + input A, + input B, + output nA, + output nB, + output nAornB, + output nAandnB, + output n_AorB, + output n_AandB +); + + wire nA; + wire nB; + not Ainv(nA, A); //Instantiate a NOT called Ainv + not Binv(nB, B); //Instantiate a NOT called Binv + and andgate(nAandnB, nA, nB); //Instantiate an AND + or orgate(nAornB, nA, nB); + + //NOR and NAND for comparison + nor norgate (n_AorB, A, B); + nand nandgate (n_AandB, A, B); + +endmodule diff --git a/results.txt b/results.txt new file mode 100644 index 0000000..5bb3d85 --- /dev/null +++ b/results.txt @@ -0,0 +1,5 @@ +A B | ~A ~B | ~A~B | ~A+~B | ~(AB) | ~(A+B) +0 0 | 1 1 | 1 | 1 | 1 | 1 +0 1 | 1 0 | 1 | 0 | 0 | 1 +1 0 | 0 1 | 1 | 0 | 0 | 1 +1 1 | 0 0 | 0 | 0 | 0 | 0