diff options
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | README.tb_test | 12 | ||||
-rw-r--r-- | contrib/xilinx.mk | 3 | ||||
-rw-r--r-- | hdl/rot13.v | 46 | ||||
-rwxr-xr-x | tb/complicated_test.v | 37 | ||||
-rwxr-xr-x | tb/main_tb.v | 36 | ||||
-rwxr-xr-x | tb/rot13_tb.v | 77 | ||||
-rw-r--r-- | tb/rot13_tb.wcfg | 48 | ||||
-rwxr-xr-x | tb/trivial_test.v | 36 |
9 files changed, 189 insertions, 112 deletions
@@ -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 |