aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbryan newbold <bnewbold@leaflabs.com>2013-10-08 23:33:18 -0400
committerbryan newbold <bnewbold@leaflabs.com>2013-10-08 23:48:05 -0400
commit3b13cb7d690ba1891f008d2905fcfb36049c71ff (patch)
tree12ddf94a955c2f8611c43c269d4620629fa3d31c
parentb31c07157b7b8ca7e8823749e140fcab24b787d2 (diff)
downloadbasic-hdl-template-3b13cb7d690ba1891f008d2905fcfb36049c71ff.tar.gz
basic-hdl-template-3b13cb7d690ba1891f008d2905fcfb36049c71ff.zip
clean up test stuff
-rw-r--r--Makefile6
-rw-r--r--README.tb_test12
-rw-r--r--contrib/xilinx.mk3
-rw-r--r--hdl/rot13.v46
-rwxr-xr-xtb/complicated_test.v37
-rwxr-xr-xtb/main_tb.v36
-rwxr-xr-xtb/rot13_tb.v77
-rw-r--r--tb/rot13_tb.wcfg48
-rwxr-xr-xtb/trivial_test.v36
9 files changed, 189 insertions, 112 deletions
diff --git a/Makefile b/Makefile
index e89469b..039004f 100644
--- a/Makefile
+++ b/Makefile
@@ -33,9 +33,9 @@ tbfiles := tb/rot13_tb.v
tbfiles += tb/xula2_tb.v
#tbfiles += tb/sp605_tb.v
-# what gets run
-alltests := test/trivial_test
-alltests += test/rot13_tb
+# what gets run by "make tests"
+alltests := test/rot13_tb
+#tbfiles += tb/yourtest_tb.v
# list of .xco files, eg "cores/bram.xco". do not include DCM files.
xilinx_cores :=
diff --git a/README.tb_test b/README.tb_test
new file mode 100644
index 0000000..3be00d6
--- /dev/null
+++ b/README.tb_test
@@ -0,0 +1,12 @@
+
+"testbenches" are helpful wrappers which exersize a piece of code. they should
+live in ./tb/, end in "_tb.v" or "_tb.vhd", and have a signal file (ending in
+"_tb.wcfg") associated with the same name. update the 'tbfiles' list in
+Makefile. invoke the isim GUI with "make isim/name_tb" (for tb/name_tb.v). if
+you make a source code change and don't want to reload the whole GUI, you can
+do "make resim/name_tb" and then click the "Re-load" button.
+
+testbenches which can act as headless unit tests (reporting pass/fail by
+printing to stdout) should be added to the 'alltests' list in Makefile. run the
+test with 'make test/name_tb'; run all tests with 'make tests'.
+
diff --git a/contrib/xilinx.mk b/contrib/xilinx.mk
index aae76a2..d56b534 100644
--- a/contrib/xilinx.mk
+++ b/contrib/xilinx.mk
@@ -216,6 +216,9 @@ isim/%: tb/%.isim tb/simulate_isim.prj
@uut=`basename $@`; \
bash -c "$(sim_env); cd ../tb; ./$$uut.isim -gui -view $$uut.wcfg &"
+resim/%: tb/%.isim tb/simulate_isim.prj
+ @true
+
test/%: tb/%.isim tb/simulate_isim.prj
@echo "run all" > ./tb/test.tcl
@uut=`basename $@`; \
diff --git a/hdl/rot13.v b/hdl/rot13.v
new file mode 100644
index 0000000..d394407
--- /dev/null
+++ b/hdl/rot13.v
@@ -0,0 +1,46 @@
+/*
+ * rot13.v
+ *
+ * Copyright: (C) 2013 LeafLabs, LLC
+ * License: MIT License (See LICENSE file)
+ * Author: Bryan Newbold <bnewbold@leaflabs.com>
+ * Date: October 2013
+ *
+ * This is a very simple ASCII ROT13 implementation.
+ *
+ * Data on in_char is sampled on the rising edge of clock and updated on
+ * out_char one clock cycle later.
+ *
+ */
+
+module rot13 (
+ input wire clock,
+ input wire reset,
+ input wire [7:0] in_char,
+ output reg [7:0] out_char = 8'd0
+ );
+
+ always @(posedge clock) begin
+ if (reset) begin
+ out_char <= 8'd0;
+ end else begin
+ if (in_char >= 8'd97 && in_char < 8'd110) begin
+ // 'a' through 'm'
+ out_char <= in_char + 8'd13;
+ end else if (in_char >= 8'd110 && in_char < 8'd123) begin
+ // 'n' through 'z'
+ out_char <= in_char - 8'd13;
+ end else if (in_char >= 8'd65 && in_char < 8'd78) begin
+ // 'A' through 'M'
+ out_char <= in_char + 8'd13;
+ end else if (in_char >= 8'd78 && in_char < 8'd91) begin
+ // 'N' through 'Z'
+ out_char <= in_char - 8'd13;
+ end else begin
+ // all other characters
+ out_char <= in_char;
+ end
+ end
+ end
+
+endmodule
diff --git a/tb/complicated_test.v b/tb/complicated_test.v
deleted file mode 100755
index 731c0c7..0000000
--- a/tb/complicated_test.v
+++ /dev/null
@@ -1,37 +0,0 @@
-`timescale 1ps/1ps
-module complicated_test;
-
- reg CLK100;
-always @(CLK100) begin
- #4980.00 CLK100 <= ~CLK100;
-end
-
-initial begin
- #0 CLK100 <= 1'b0; // the first event that sets the clock in motion
-end
-
-
-reg [3:0] Switch_input;
-wire [3:0] LED_output;
-wire FPGA_RESET;
-
-main main_i (
- .PUSH_BUTTON_RESET_RAW(FPGA_RESET),
- .SYSTEMCLOCK(CLK100),
- .gpio_led(LED_output),
- .gpio_switch(Switch_input)
- );
-
-
-initial begin
- #0 Switch_input <= 4'h00;
- $display("FAIL");
- $display("Switch set to zero");
- #1000000 Switch_input <= 4'h01;
- $display("Switch set to one");
- #2000000
- $display("PASS");
- $finish();
-end
-
-endmodule
diff --git a/tb/main_tb.v b/tb/main_tb.v
deleted file mode 100755
index b0f1346..0000000
--- a/tb/main_tb.v
+++ /dev/null
@@ -1,36 +0,0 @@
-`timescale 1ps/1ps
-module main_tb;
-
- reg CLK100;
-always @(CLK100) begin
- #4980.00 CLK100 <= ~CLK100;
-end
-
-initial begin
- #0 CLK100 <= 1'b0; // the first event that sets the clock in motion
-end
-
-
-reg [3:0] Switch_input;
-wire [3:0] LED_output;
-wire FPGA_RESET;
-
-main main_i (
- .PUSH_BUTTON_RESET_RAW(FPGA_RESET),
- .SYSTEMCLOCK(CLK100),
- .gpio_led(LED_output),
- .gpio_switch(Switch_input)
- );
-
-
-initial begin
- #0 Switch_input <= 4'h00;
- $display("Switch set to zero");
- #1000000 Switch_input <= 4'h01;
- $display("Switch set to one");
- #2000000
- $display("PASS");
- $finish();
-end
-
-endmodule
diff --git a/tb/rot13_tb.v b/tb/rot13_tb.v
new file mode 100755
index 0000000..1ec21c4
--- /dev/null
+++ b/tb/rot13_tb.v
@@ -0,0 +1,77 @@
+`timescale 1ns/1ps
+module rot13_tb;
+
+reg synth_clk_12mhz;
+always @(synth_clk_12mhz) begin
+ #41.6665 synth_clk_12mhz <= ~synth_clk_12mhz;
+end
+
+initial begin
+ // the first event that sets the clock in motion
+ #0 synth_clk_12mhz <= 1'b0;
+end
+
+reg reset;
+integer nfail;
+
+reg [7:0] in_char;
+wire [7:0] out_char;
+
+rot13 rot13_inst (
+ .clock(synth_clk_12mhz),
+ .reset(reset),
+ .in_char(in_char),
+ .out_char(out_char)
+);
+
+task check_rot13;
+ input [7:0] a;
+ input [7:0] b;
+ begin
+ in_char <= a;
+ #100 // 100 ns delay
+ if (out_char !== b) begin
+ nfail = nfail + 1;
+ $display("FAIL: '%c' -> '%c' (got '%c')", a, b, out_char);
+ end else begin
+ $display("'%c' -> '%c'", a, out_char);
+ end
+ end
+endtask
+
+initial begin
+ nfail = 0;
+ $display("=================== start %m");
+ #0
+ reset <= 1'b1;
+ #1000
+ reset <= 1'b0;
+ #100
+
+ check_rot13("A", "N");
+ check_rot13("a", "n");
+ check_rot13("N", "A");
+ check_rot13("n", "a");
+ check_rot13("M", "Z");
+ check_rot13("m", "z");
+ check_rot13("Z", "M");
+ check_rot13("z", "m");
+ check_rot13(".", ".");
+ check_rot13("8", "8");
+ check_rot13("@", "@");
+ check_rot13("[", "[");
+ check_rot13("`", "`");
+ check_rot13("{", "{");
+
+ // uncomment the below to ensure failures are caught
+ //check_rot13("a", "a");
+
+ if (nfail !== 0) begin
+ $display("=================== %m: FAIL (%d problems)", nfail);
+ end else begin
+ $display("=================== %m: PASS");
+ end
+ $finish();
+end
+
+endmodule
diff --git a/tb/rot13_tb.wcfg b/tb/rot13_tb.wcfg
new file mode 100644
index 0000000..171de9f
--- /dev/null
+++ b/tb/rot13_tb.wcfg
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wave_config>
+ <wave_state>
+ </wave_state>
+ <db_ref_list>
+ <db_ref path="./isim.wdb" id="1" type="auto">
+ <top_modules>
+ <top_module name="glbl" />
+ <top_module name="rot13_tb" />
+ </top_modules>
+ </db_ref>
+ </db_ref_list>
+ <WVObjectSize size="7" />
+ <wvobject fp_name="/rot13_tb/synth_clk_12mhz" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">synth_clk_12mhz</obj_property>
+ <obj_property name="ObjectShortName">synth_clk_12mhz</obj_property>
+ </wvobject>
+ <wvobject fp_name="/rot13_tb/reset" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">reset</obj_property>
+ <obj_property name="ObjectShortName">reset</obj_property>
+ </wvobject>
+ <wvobject fp_name="/rot13_tb/in_char" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">in_char[7:0]</obj_property>
+ <obj_property name="ObjectShortName">in_char[7:0]</obj_property>
+ <obj_property name="Radix">ASCIIRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/rot13_tb/out_char" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">out_char[7:0]</obj_property>
+ <obj_property name="ObjectShortName">out_char[7:0]</obj_property>
+ <obj_property name="Radix">ASCIIRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="divider7" type="divider">
+ <obj_property name="label">Real Module</obj_property>
+ <obj_property name="DisplayName">label</obj_property>
+ <obj_property name="BkColor">128 128 255</obj_property>
+ <obj_property name="TextColor">230 230 230</obj_property>
+ </wvobject>
+ <wvobject fp_name="/rot13_tb/rot13_inst/in_char" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">in_char[7:0]</obj_property>
+ <obj_property name="ObjectShortName">in_char[7:0]</obj_property>
+ <obj_property name="Radix">ASCIIRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/rot13_tb/rot13_inst/out_char" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">out_char[7:0]</obj_property>
+ <obj_property name="ObjectShortName">out_char[7:0]</obj_property>
+ <obj_property name="Radix">ASCIIRADIX</obj_property>
+ </wvobject>
+</wave_config>
diff --git a/tb/trivial_test.v b/tb/trivial_test.v
deleted file mode 100755
index e12a52f..0000000
--- a/tb/trivial_test.v
+++ /dev/null
@@ -1,36 +0,0 @@
-`timescale 1ps/1ps
-module trivial_test;
-
- reg CLK100;
-always @(CLK100) begin
- #4980.00 CLK100 <= ~CLK100;
-end
-
-initial begin
- #0 CLK100 <= 1'b0; // the first event that sets the clock in motion
-end
-
-
-reg [3:0] Switch_input;
-wire [3:0] LED_output;
-wire FPGA_RESET;
-
-main main_i (
- .PUSH_BUTTON_RESET_RAW(FPGA_RESET),
- .SYSTEMCLOCK(CLK100),
- .gpio_led(LED_output),
- .gpio_switch(Switch_input)
- );
-
-
-initial begin
- #0 Switch_input <= 4'h00;
- $display("Switch set to zero");
- #1000000 Switch_input <= 4'h01;
- $display("Switch set to one");
- #2000000
- $display("PASS");
- $finish();
-end
-
-endmodule