diff options
Diffstat (limited to 'techlibs/ice40/tests')
| -rw-r--r-- | techlibs/ice40/tests/.gitignore | 13 | ||||
| -rw-r--r-- | techlibs/ice40/tests/test_dsp_map.sh | 107 | ||||
| -rw-r--r-- | techlibs/ice40/tests/test_dsp_model.sh | 11 | ||||
| -rw-r--r-- | techlibs/ice40/tests/test_dsp_model.v | 342 | 
4 files changed, 471 insertions, 2 deletions
| diff --git a/techlibs/ice40/tests/.gitignore b/techlibs/ice40/tests/.gitignore index b58f9ad4a..120286550 100644 --- a/techlibs/ice40/tests/.gitignore +++ b/techlibs/ice40/tests/.gitignore @@ -1,2 +1,11 @@ -test_ffs_[01][01][01][01][01]_* -test_bram_[0-9]* +/test_ffs_[01][01][01][01][01]_* +/test_bram_[0-9]* +/test_dsp_model +/test_dsp_model.vcd +/test_dsp_model_ref.v +/test_dsp_model_uut.v +/test_dsp_map +/test_dsp_map.vcd +/test_dsp_map_tb.v +/test_dsp_map_top.v +/test_dsp_map_syn.v diff --git a/techlibs/ice40/tests/test_dsp_map.sh b/techlibs/ice40/tests/test_dsp_map.sh new file mode 100644 index 000000000..3f7f134e4 --- /dev/null +++ b/techlibs/ice40/tests/test_dsp_map.sh @@ -0,0 +1,107 @@ +#!/bin/bash +set -ex + +for iter in {1..100} +do +	SZA=$(( 3 + $RANDOM % 13 )) +	SZB=$(( 3 + $RANDOM % 13 )) +	SZO=$(( 3 + $RANDOM % 29 )) + +	C0=clk$(( $RANDOM & 1)) +	C1=clk$(( $RANDOM & 1)) +	C2=clk$(( $RANDOM & 1)) +	C3=clk$(( $RANDOM & 1)) + +	E0=$( test $(( $RANDOM & 1 )) -eq 0 && echo posedge || echo negedge ) +	E1=$( test $(( $RANDOM & 1 )) -eq 0 && echo posedge || echo negedge ) +	E2=$( test $(( $RANDOM & 1 )) -eq 0 && echo posedge || echo negedge ) +	E3=$( test $(( $RANDOM & 1 )) -eq 0 && echo posedge || echo negedge ) + +	SP=$( test $(( $RANDOM & 1 )) -eq 0 && echo S || echo P ) + +	RC=$( test $(( $RANDOM & 1 )) -eq 0 && echo "reset" || echo "!reset" ) +	RV="32'h$( echo $RANDOM | md5sum | cut -c1-8 )" + +	cat > test_dsp_map_top.v << EOT +module top ( +	input clk0, clk1, reset, +	input  [$SZA:0] A, +	input  [$SZB:0] B, +	output [$SZO:0] O +); +	reg [15:0] AA, BB; +	reg [31:0] P, S; + +	always @($E0 $C0) AA <= A; +	always @($E1 $C1) BB <= B; +	always @($E2 $C2) P <= AA * BB; +	always @($E3 $C3) S <= $RC ? $RV : S + P; +	assign O = $SP; +endmodule +EOT + +	cat > test_dsp_map_tb.v << EOT +\`timescale 1ns / 1ps +module testbench; +	reg clk1, clk0, reset; +	reg [$SZA:0] A; +	reg [$SZB:0] B; + +	wire [$SZO:0] O_top, O_syn; + +	top top_inst (.clk0(clk0), .clk1(clk1), .reset(reset), .A(A), .B(B), .O(O_top)); +	syn syn_inst (.clk0(clk0), .clk1(clk1), .reset(reset), .A(A), .B(B), .O(O_syn)); + +	initial begin +		// \$dumpfile("test_dsp_map.vcd"); +		// \$dumpvars(0, testbench); + +		#2; +		clk0 = 0; +		clk1 = 0; +		reset = 1; +		reset = $RC; +		A = 0; +		B = 0; + +		repeat (3) begin +			#2; clk0 = ~clk0; +			#2; clk0 = ~clk0; +			#2; clk1 = ~clk1; +			#2; clk1 = ~clk1; +		end + +		repeat (100) begin +			#2; +			A = \$urandom; +			B = \$urandom; +			reset = \$urandom & \$urandom & \$urandom & \$urandom; +			if (\$urandom & 1) begin +				#2; clk0 = ~clk0; +				#2; clk0 = ~clk0; +			end else begin +				#2; clk1 = ~clk1; +				#2; clk1 = ~clk1; +			end +			#2; +			if (O_top !== O_syn) begin +				\$display("ERROR: O_top=%b O_syn=%b", O_top, O_syn); +				\$stop; +			end +			// \$display("OK O_top=O_syn=%b", O_top); +		end + +		\$display("Test passed."); +		\$finish; +	end +endmodule +EOT + +	../../../yosys -p 'read_verilog test_dsp_map_top.v; synth_ice40 -dsp; rename top syn; write_verilog test_dsp_map_syn.v' +	iverilog -o test_dsp_map -s testbench test_dsp_map_tb.v test_dsp_map_top.v test_dsp_map_syn.v ../cells_sim.v +	vvp -N test_dsp_map +done + +: "" +: "####  All tests passed.  ####" +: "" diff --git a/techlibs/ice40/tests/test_dsp_model.sh b/techlibs/ice40/tests/test_dsp_model.sh new file mode 100644 index 000000000..1bc0cc688 --- /dev/null +++ b/techlibs/ice40/tests/test_dsp_model.sh @@ -0,0 +1,11 @@ +#!/bin/bash +set -ex +sed 's/SB_MAC16/SB_MAC16_UUT/; /SB_MAC16_UUT/,/endmodule/ p; d;' < ../cells_sim.v > test_dsp_model_uut.v +cat /opt/lscc/iCEcube2.2017.01/verilog/sb_ice_syn.v > test_dsp_model_ref.v +for tb in testbench \ +		testbench_comb_8x8_A testbench_comb_8x8_B testbench_comb_16x16 \ +		testbench_seq_16x16_A testbench_seq_16x16_B +do +	iverilog -s $tb -o test_dsp_model test_dsp_model.v test_dsp_model_uut.v test_dsp_model_ref.v +	vvp -N ./test_dsp_model +done diff --git a/techlibs/ice40/tests/test_dsp_model.v b/techlibs/ice40/tests/test_dsp_model.v new file mode 100644 index 000000000..594bd4ad3 --- /dev/null +++ b/techlibs/ice40/tests/test_dsp_model.v @@ -0,0 +1,342 @@ +`timescale 1ns / 1ps + +module testbench; +	parameter [0:0] NEG_TRIGGER = 0; +	parameter [0:0] C_REG = 0; +	parameter [0:0] A_REG = 0; +	parameter [0:0] B_REG = 0; +	parameter [0:0] D_REG = 0; +	parameter [0:0] TOP_8x8_MULT_REG = 0; +	parameter [0:0] BOT_8x8_MULT_REG = 0; +	parameter [0:0] PIPELINE_16x16_MULT_REG1 = 0; +	parameter [0:0] PIPELINE_16x16_MULT_REG2 = 0; +	parameter [1:0] TOPOUTPUT_SELECT = 0; +	parameter [1:0] TOPADDSUB_LOWERINPUT = 0; +	parameter [0:0] TOPADDSUB_UPPERINPUT = 1; +	parameter [1:0] TOPADDSUB_CARRYSELECT = 0; +	parameter [1:0] BOTOUTPUT_SELECT = 0; +	parameter [1:0] BOTADDSUB_LOWERINPUT = 0; +	parameter [0:0] BOTADDSUB_UPPERINPUT = 1; +	parameter [1:0] BOTADDSUB_CARRYSELECT = 0; +	parameter [0:0] MODE_8x8 = 0; +	parameter [0:0] A_SIGNED = 0; +	parameter [0:0] B_SIGNED = 0; + +	reg CLK, CE; +	reg [15:0] C, A, B, D; +	reg AHOLD, BHOLD, CHOLD, DHOLD; +	reg IRSTTOP, IRSTBOT; +	reg ORSTTOP, ORSTBOT; +	reg OLOADTOP, OLOADBOT; +	reg ADDSUBTOP, ADDSUBBOT; +	reg OHOLDTOP, OHOLDBOT; +	reg CI, ACCUMCI, SIGNEXTIN; + +	output [31:0] REF_O, UUT_O; +	output REF_CO, REF_ACCUMCO, REF_SIGNEXTOUT; +	output UUT_CO, UUT_ACCUMCO, UUT_SIGNEXTOUT; + +	integer errcount = 0; + +	task clkcycle; +		begin +			#5; +			CLK = ~CLK; +			#10; +			CLK = ~CLK; +			#2; +			if (REF_O !== UUT_O) begin +				$display("ERROR at %1t: REF_O=%b UUT_O=%b DIFF=%b", $time, REF_O, UUT_O, REF_O ^ UUT_O); +				errcount = errcount + 1; +			end +			if (REF_CO !== UUT_CO) begin +				$display("ERROR at %1t: REF_CO=%b UUT_CO=%b", $time, REF_CO, UUT_CO); +				errcount = errcount + 1; +			end +			if (REF_ACCUMCO !== UUT_ACCUMCO) begin +				$display("ERROR at %1t: REF_ACCUMCO=%b UUT_ACCUMCO=%b", $time, REF_ACCUMCO, UUT_ACCUMCO); +				errcount = errcount + 1; +			end +			if (REF_SIGNEXTOUT !== UUT_SIGNEXTOUT) begin +				$display("ERROR at %1t: REF_SIGNEXTOUT=%b UUT_SIGNEXTOUT=%b", $time, REF_SIGNEXTOUT, UUT_SIGNEXTOUT); +				errcount = errcount + 1; +			end +			#3; +		end +	endtask + +	initial begin +		$dumpfile("test_dsp_model.vcd"); +		$dumpvars(0, testbench); + +		#2; +		CLK = NEG_TRIGGER; +		CE = 1; +		{C, A, B, D} = 0; +		{AHOLD, BHOLD, CHOLD, DHOLD} = 0; +		{OLOADTOP, OLOADBOT} = 0; +		{ADDSUBTOP, ADDSUBBOT} = 0; +		{OHOLDTOP, OHOLDBOT} = 0; +		{CI, ACCUMCI, SIGNEXTIN} = 0; + +		{IRSTTOP, IRSTBOT} = ~0; +		{ORSTTOP, ORSTBOT} = ~0; + +		#3; +		{IRSTTOP, IRSTBOT} = 0; +		{ORSTTOP, ORSTBOT} = 0; + +		repeat (300) begin +			clkcycle; + +			A = $urandom; +			B = $urandom; +			C = $urandom; +			D = $urandom; + +			{AHOLD, BHOLD, CHOLD, DHOLD} = $urandom & $urandom & $urandom; +			{OLOADTOP, OLOADBOT} = $urandom & $urandom & $urandom; +			{ADDSUBTOP, ADDSUBBOT} = $urandom & $urandom & $urandom; +			{OHOLDTOP, OHOLDBOT} = $urandom & $urandom & $urandom; +			{CI, ACCUMCI, SIGNEXTIN} = $urandom & $urandom & $urandom; + +			{IRSTTOP, IRSTBOT} = $urandom & $urandom & $urandom; +			{ORSTTOP, ORSTBOT} = $urandom & $urandom & $urandom; +		end + +		if (errcount == 0) begin +			$display("All tests passed."); +			$finish; +		end else begin +			$display("Caught %1d errors.", errcount); +			$stop; +		end +	end + +	SB_MAC16 #( +		.NEG_TRIGGER              (NEG_TRIGGER             ), +		.C_REG                    (C_REG                   ), +		.A_REG                    (A_REG                   ), +		.B_REG                    (B_REG                   ), +		.D_REG                    (D_REG                   ), +		.TOP_8x8_MULT_REG         (TOP_8x8_MULT_REG        ), +		.BOT_8x8_MULT_REG         (BOT_8x8_MULT_REG        ), +		.PIPELINE_16x16_MULT_REG1 (PIPELINE_16x16_MULT_REG1), +		.PIPELINE_16x16_MULT_REG2 (PIPELINE_16x16_MULT_REG2), +		.TOPOUTPUT_SELECT         (TOPOUTPUT_SELECT        ), +		.TOPADDSUB_LOWERINPUT     (TOPADDSUB_LOWERINPUT    ), +		.TOPADDSUB_UPPERINPUT     (TOPADDSUB_UPPERINPUT    ), +		.TOPADDSUB_CARRYSELECT    (TOPADDSUB_CARRYSELECT   ), +		.BOTOUTPUT_SELECT         (BOTOUTPUT_SELECT        ), +		.BOTADDSUB_LOWERINPUT     (BOTADDSUB_LOWERINPUT    ), +		.BOTADDSUB_UPPERINPUT     (BOTADDSUB_UPPERINPUT    ), +		.BOTADDSUB_CARRYSELECT    (BOTADDSUB_CARRYSELECT   ), +		.MODE_8x8                 (MODE_8x8                ), +		.A_SIGNED                 (A_SIGNED                ), +		.B_SIGNED                 (B_SIGNED                ) +	) ref ( +		.CLK        (CLK           ), +		.CE         (CE            ), +		.C          (C             ), +		.A          (A             ), +		.B          (B             ), +		.D          (D             ), +		.AHOLD      (AHOLD         ), +		.BHOLD      (BHOLD         ), +		.CHOLD      (CHOLD         ), +		.DHOLD      (DHOLD         ), +		.IRSTTOP    (IRSTTOP       ), +		.IRSTBOT    (IRSTBOT       ), +		.ORSTTOP    (ORSTTOP       ), +		.ORSTBOT    (ORSTBOT       ), +		.OLOADTOP   (OLOADTOP      ), +		.OLOADBOT   (OLOADBOT      ), +		.ADDSUBTOP  (ADDSUBTOP     ), +		.ADDSUBBOT  (ADDSUBBOT     ), +		.OHOLDTOP   (OHOLDTOP      ), +		.OHOLDBOT   (OHOLDBOT      ), +		.CI         (CI            ), +		.ACCUMCI    (ACCUMCI       ), +		.SIGNEXTIN  (SIGNEXTIN     ), +		.O          (REF_O         ), +		.CO         (REF_CO        ), +		.ACCUMCO    (REF_ACCUMCO   ), +		.SIGNEXTOUT (REF_SIGNEXTOUT) +	); + +	SB_MAC16_UUT #( +		.NEG_TRIGGER              (NEG_TRIGGER             ), +		.C_REG                    (C_REG                   ), +		.A_REG                    (A_REG                   ), +		.B_REG                    (B_REG                   ), +		.D_REG                    (D_REG                   ), +		.TOP_8x8_MULT_REG         (TOP_8x8_MULT_REG        ), +		.BOT_8x8_MULT_REG         (BOT_8x8_MULT_REG        ), +		.PIPELINE_16x16_MULT_REG1 (PIPELINE_16x16_MULT_REG1), +		.PIPELINE_16x16_MULT_REG2 (PIPELINE_16x16_MULT_REG2), +		.TOPOUTPUT_SELECT         (TOPOUTPUT_SELECT        ), +		.TOPADDSUB_LOWERINPUT     (TOPADDSUB_LOWERINPUT    ), +		.TOPADDSUB_UPPERINPUT     (TOPADDSUB_UPPERINPUT    ), +		.TOPADDSUB_CARRYSELECT    (TOPADDSUB_CARRYSELECT   ), +		.BOTOUTPUT_SELECT         (BOTOUTPUT_SELECT        ), +		.BOTADDSUB_LOWERINPUT     (BOTADDSUB_LOWERINPUT    ), +		.BOTADDSUB_UPPERINPUT     (BOTADDSUB_UPPERINPUT    ), +		.BOTADDSUB_CARRYSELECT    (BOTADDSUB_CARRYSELECT   ), +		.MODE_8x8                 (MODE_8x8                ), +		.A_SIGNED                 (A_SIGNED                ), +		.B_SIGNED                 (B_SIGNED                ) +	) uut ( +		.CLK        (CLK           ), +		.CE         (CE            ), +		.C          (C             ), +		.A          (A             ), +		.B          (B             ), +		.D          (D             ), +		.AHOLD      (AHOLD         ), +		.BHOLD      (BHOLD         ), +		.CHOLD      (CHOLD         ), +		.DHOLD      (DHOLD         ), +		.IRSTTOP    (IRSTTOP       ), +		.IRSTBOT    (IRSTBOT       ), +		.ORSTTOP    (ORSTTOP       ), +		.ORSTBOT    (ORSTBOT       ), +		.OLOADTOP   (OLOADTOP      ), +		.OLOADBOT   (OLOADBOT      ), +		.ADDSUBTOP  (ADDSUBTOP     ), +		.ADDSUBBOT  (ADDSUBBOT     ), +		.OHOLDTOP   (OHOLDTOP      ), +		.OHOLDBOT   (OHOLDBOT      ), +		.CI         (CI            ), +		.ACCUMCI    (ACCUMCI       ), +		.SIGNEXTIN  (SIGNEXTIN     ), +		.O          (UUT_O         ), +		.CO         (UUT_CO        ), +		.ACCUMCO    (UUT_ACCUMCO   ), +		.SIGNEXTOUT (UUT_SIGNEXTOUT) +	); +endmodule + +module testbench_comb_8x8_A; +	testbench #( +		.NEG_TRIGGER               (0), +		.C_REG                     (0), +		.A_REG                     (0), +		.B_REG                     (0), +		.D_REG                     (0), +		.TOP_8x8_MULT_REG          (0), +		.BOT_8x8_MULT_REG          (0), +		.PIPELINE_16x16_MULT_REG1  (0), +		.PIPELINE_16x16_MULT_REG2  (0), +		.TOPOUTPUT_SELECT          (2),   // 0=P, 1=Q, 2=8x8, 3=16x16 +		.TOPADDSUB_LOWERINPUT      (0),   // 0=A, 1=8x8, 2=16x16, 3=S-EXT +		.TOPADDSUB_UPPERINPUT      (0),   // 0=Q, 1=C +		.TOPADDSUB_CARRYSELECT     (0),   // 0=0, 1=1, 2=ACI, 3=CI +		.BOTOUTPUT_SELECT          (2),   // 0=R, 1=S, 2=8x8, 3=16x16 +		.BOTADDSUB_LOWERINPUT      (0),   // 0=B, 1=8x8, 2=16x16, 3=S-EXT +		.BOTADDSUB_UPPERINPUT      (0),   // 0=S, 1=D +		.BOTADDSUB_CARRYSELECT     (0),   // 0=0, 1=1, 2=ACI, 3=CI +		.MODE_8x8                  (0), +		.A_SIGNED                  (0), +		.B_SIGNED                  (0) +	) testbench (); +endmodule + +module testbench_comb_8x8_B; +	testbench #( +		.NEG_TRIGGER               (0), +		.C_REG                     (0), +		.A_REG                     (0), +		.B_REG                     (0), +		.D_REG                     (0), +		.TOP_8x8_MULT_REG          (0), +		.BOT_8x8_MULT_REG          (0), +		.PIPELINE_16x16_MULT_REG1  (0), +		.PIPELINE_16x16_MULT_REG2  (0), +		.TOPOUTPUT_SELECT          (0),   // 0=P, 1=Q, 2=8x8, 3=16x16 +		.TOPADDSUB_LOWERINPUT      (1),   // 0=A, 1=8x8, 2=16x16, 3=S-EXT +		.TOPADDSUB_UPPERINPUT      (1),   // 0=Q, 1=C +		.TOPADDSUB_CARRYSELECT     (0),   // 0=0, 1=1, 2=ACI, 3=CI +		.BOTOUTPUT_SELECT          (0),   // 0=R, 1=S, 2=8x8, 3=16x16 +		.BOTADDSUB_LOWERINPUT      (1),   // 0=B, 1=8x8, 2=16x16, 3=S-EXT +		.BOTADDSUB_UPPERINPUT      (1),   // 0=S, 1=D +		.BOTADDSUB_CARRYSELECT     (0),   // 0=0, 1=1, 2=ACI, 3=CI +		.MODE_8x8                  (0), +		.A_SIGNED                  (0), +		.B_SIGNED                  (0) +	) testbench (); +endmodule + +module testbench_comb_16x16; +	testbench #( +		.NEG_TRIGGER               (0), +		.C_REG                     (0), +		.A_REG                     (0), +		.B_REG                     (0), +		.D_REG                     (0), +		.TOP_8x8_MULT_REG          (0), +		.BOT_8x8_MULT_REG          (0), +		.PIPELINE_16x16_MULT_REG1  (0), +		.PIPELINE_16x16_MULT_REG2  (0), +		.TOPOUTPUT_SELECT          (0),   // 0=P, 1=Q, 2=8x8, 3=16x16 +		.TOPADDSUB_LOWERINPUT      (2),   // 0=A, 1=8x8, 2=16x16, 3=S-EXT +		.TOPADDSUB_UPPERINPUT      (1),   // 0=Q, 1=C +		.TOPADDSUB_CARRYSELECT     (2),   // 0=0, 1=1, 2=ACI, 3=CI +		.BOTOUTPUT_SELECT          (0),   // 0=R, 1=S, 2=8x8, 3=16x16 +		.BOTADDSUB_LOWERINPUT      (2),   // 0=B, 1=8x8, 2=16x16, 3=S-EXT +		.BOTADDSUB_UPPERINPUT      (1),   // 0=S, 1=D +		.BOTADDSUB_CARRYSELECT     (2),   // 0=0, 1=1, 2=ACI, 3=CI +		.MODE_8x8                  (0), +		.A_SIGNED                  (0), +		.B_SIGNED                  (0) +	) testbench (); +endmodule + +module testbench_seq_16x16_A; +	testbench #( +		.NEG_TRIGGER               (0), +		.C_REG                     (1), +		.A_REG                     (1), +		.B_REG                     (1), +		.D_REG                     (1), +		.TOP_8x8_MULT_REG          (1), +		.BOT_8x8_MULT_REG          (1), +		.PIPELINE_16x16_MULT_REG1  (1), +		.PIPELINE_16x16_MULT_REG2  (1), +		.TOPOUTPUT_SELECT          (0),   // 0=P, 1=Q, 2=8x8, 3=16x16 +		.TOPADDSUB_LOWERINPUT      (2),   // 0=A, 1=8x8, 2=16x16, 3=S-EXT +		.TOPADDSUB_UPPERINPUT      (1),   // 0=Q, 1=C +		.TOPADDSUB_CARRYSELECT     (2),   // 0=0, 1=1, 2=ACI, 3=CI +		.BOTOUTPUT_SELECT          (0),   // 0=R, 1=S, 2=8x8, 3=16x16 +		.BOTADDSUB_LOWERINPUT      (2),   // 0=B, 1=8x8, 2=16x16, 3=S-EXT +		.BOTADDSUB_UPPERINPUT      (1),   // 0=S, 1=D +		.BOTADDSUB_CARRYSELECT     (2),   // 0=0, 1=1, 2=ACI, 3=CI +		.MODE_8x8                  (0), +		.A_SIGNED                  (0), +		.B_SIGNED                  (0) +	) testbench (); +endmodule + +module testbench_seq_16x16_B; +	testbench #( +		.NEG_TRIGGER               (0), +		.C_REG                     (1), +		.A_REG                     (1), +		.B_REG                     (1), +		.D_REG                     (1), +		.TOP_8x8_MULT_REG          (1), +		.BOT_8x8_MULT_REG          (1), +		.PIPELINE_16x16_MULT_REG1  (1), +		.PIPELINE_16x16_MULT_REG2  (0), +		.TOPOUTPUT_SELECT          (1),   // 0=P, 1=Q, 2=8x8, 3=16x16 +		.TOPADDSUB_LOWERINPUT      (2),   // 0=A, 1=8x8, 2=16x16, 3=S-EXT +		.TOPADDSUB_UPPERINPUT      (0),   // 0=Q, 1=C +		.TOPADDSUB_CARRYSELECT     (2),   // 0=0, 1=1, 2=ACI, 3=CI +		.BOTOUTPUT_SELECT          (1),   // 0=R, 1=S, 2=8x8, 3=16x16 +		.BOTADDSUB_LOWERINPUT      (2),   // 0=B, 1=8x8, 2=16x16, 3=S-EXT +		.BOTADDSUB_UPPERINPUT      (0),   // 0=S, 1=D +		.BOTADDSUB_CARRYSELECT     (2),   // 0=0, 1=1, 2=ACI, 3=CI +		.MODE_8x8                  (0), +		.A_SIGNED                  (0), +		.B_SIGNED                  (0) +	) testbench (); +endmodule | 
