diff options
Diffstat (limited to 'tests/xilinx')
-rw-r--r-- | tests/xilinx/.gitignore | 1 | ||||
-rw-r--r-- | tests/xilinx/dsp_simd.ys | 25 | ||||
-rw-r--r-- | tests/xilinx/macc.sh | 3 | ||||
-rw-r--r-- | tests/xilinx/macc.v | 84 | ||||
-rw-r--r-- | tests/xilinx/macc.ys | 31 | ||||
-rw-r--r-- | tests/xilinx/macc_tb.v | 96 | ||||
-rw-r--r-- | tests/xilinx/mul_unsigned.v | 30 | ||||
-rw-r--r-- | tests/xilinx/mul_unsigned.ys | 10 |
8 files changed, 280 insertions, 0 deletions
diff --git a/tests/xilinx/.gitignore b/tests/xilinx/.gitignore index b48f808a1..54733fb71 100644 --- a/tests/xilinx/.gitignore +++ b/tests/xilinx/.gitignore @@ -1,3 +1,4 @@ /*.log /*.out /run-test.mk +/*_uut.v diff --git a/tests/xilinx/dsp_simd.ys b/tests/xilinx/dsp_simd.ys new file mode 100644 index 000000000..956952327 --- /dev/null +++ b/tests/xilinx/dsp_simd.ys @@ -0,0 +1,25 @@ +read_verilog <<EOT +module simd(input [12*4-1:0] a, input [12*4-1:0] b, (* use_dsp="simd" *) output [7*12-1:0] o12, (* use_dsp="simd" *) output [2*24-1:0] o24); +generate + genvar i; + // 4 x 12-bit adder + for (i = 0; i < 4; i++) + assign o12[i*12+:12] = a[i*12+:12] + b[i*12+:12]; + // 2 x 24-bit subtract + for (i = 0; i < 2; i++) + assign o24[i*24+:24] = a[i*24+:24] - b[i*24+:24]; +endgenerate +reg [3*12-1:0] ro; +always @* begin + ro[0*12+:12] = a[0*10+:10] + b[0*10+:10]; + ro[1*12+:12] = a[1*10+:10] + b[1*10+:10]; + ro[2*12+:12] = a[2*8+:8] + b[2*8+:8]; +end +assign o12[4*12+:3*12] = ro; +endmodule +EOT + +proc +equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx +design -load postopt +select -assert-count 3 t:DSP48E1 diff --git a/tests/xilinx/macc.sh b/tests/xilinx/macc.sh new file mode 100644 index 000000000..86e4c2bb6 --- /dev/null +++ b/tests/xilinx/macc.sh @@ -0,0 +1,3 @@ +../../yosys -qp "synth_xilinx -top macc2; rename -top macc2_uut" macc.v -o macc_uut.v +iverilog -o test_macc macc_tb.v macc_uut.v macc.v ../../techlibs/xilinx/cells_sim.v +vvp -N ./test_macc diff --git a/tests/xilinx/macc.v b/tests/xilinx/macc.v new file mode 100644 index 000000000..e36b2bab1 --- /dev/null +++ b/tests/xilinx/macc.v @@ -0,0 +1,84 @@ +// Signed 40-bit streaming accumulator with 16-bit inputs +// File: HDL_Coding_Techniques/multipliers/multipliers4.v +// +// Source: +// https://www.xilinx.com/support/documentation/sw_manuals/xilinx2014_2/ug901-vivado-synthesis.pdf p.90 +// +module macc # (parameter SIZEIN = 16, SIZEOUT = 40) ( + input clk, ce, sload, + input signed [SIZEIN-1:0] a, b, + output signed [SIZEOUT-1:0] accum_out +); +// Declare registers for intermediate values +reg signed [SIZEIN-1:0] a_reg, b_reg; +reg sload_reg; +reg signed [2*SIZEIN-1:0] mult_reg; +reg signed [SIZEOUT-1:0] adder_out, old_result; +always @* /*(adder_out or sload_reg)*/ begin // Modification necessary to fix sim/synth mismatch + if (sload_reg) + old_result <= 0; + else + // 'sload' is now active (=low) and opens the accumulation loop. + // The accumulator takes the next multiplier output in + // the same cycle. + old_result <= adder_out; +end + +always @(posedge clk) + if (ce) + begin + a_reg <= a; + b_reg <= b; + mult_reg <= a_reg * b_reg; + sload_reg <= sload; + // Store accumulation result into a register + adder_out <= old_result + mult_reg; + end + +// Output accumulation result +assign accum_out = adder_out; + +endmodule + +// Adapted variant of above +module macc2 # (parameter SIZEIN = 16, SIZEOUT = 40) ( + input clk, + input ce, + input rst, + input signed [SIZEIN-1:0] a, b, + output signed [SIZEOUT-1:0] accum_out, + output overflow +); +// Declare registers for intermediate values +reg signed [SIZEIN-1:0] a_reg, b_reg, a_reg2, b_reg2; +reg signed [2*SIZEIN-1:0] mult_reg = 0; +reg signed [SIZEOUT:0] adder_out = 0; +reg overflow_reg; +always @(posedge clk) begin + //if (ce) + begin + a_reg <= a; + b_reg <= b; + a_reg2 <= a_reg; + b_reg2 <= b_reg; + mult_reg <= a_reg2 * b_reg2; + // Store accumulation result into a register + adder_out <= adder_out + mult_reg; + overflow_reg <= overflow; + end + if (rst) begin + a_reg <= 0; + a_reg2 <= 0; + b_reg <= 0; + b_reg2 <= 0; + mult_reg <= 0; + adder_out <= 0; + overflow_reg <= 1'b0; + end +end +assign overflow = (adder_out >= 2**(SIZEOUT-1)) | overflow_reg; + +// Output accumulation result +assign accum_out = overflow ? 2**(SIZEOUT-1)-1 : adder_out; + +endmodule diff --git a/tests/xilinx/macc.ys b/tests/xilinx/macc.ys new file mode 100644 index 000000000..417a3b21b --- /dev/null +++ b/tests/xilinx/macc.ys @@ -0,0 +1,31 @@ +read_verilog macc.v +design -save read + +proc +hierarchy -top macc +#equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx ### TODO +equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -seq 10 -show-inputs -show-outputs miter +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd macc # Constrain all select calls below inside the top module +select -assert-count 1 t:BUFG +select -assert-count 1 t:FDRE +select -assert-count 1 t:DSP48E1 +select -assert-none t:BUFG t:FDRE t:DSP48E1 %% t:* %D + +design -load read +proc +hierarchy -top macc2 +#equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx ### TODO +equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -seq 10 -show-inputs -show-outputs miter +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd macc2 # Constrain all select calls below inside the top module +select -assert-count 1 t:BUFG +select -assert-count 1 t:DSP48E1 +select -assert-count 1 t:FDRE +select -assert-count 1 t:LUT2 +select -assert-count 41 t:LUT3 +select -assert-none t:BUFG t:DSP48E1 t:FDRE t:LUT2 t:LUT3 %% t:* %D diff --git a/tests/xilinx/macc_tb.v b/tests/xilinx/macc_tb.v new file mode 100644 index 000000000..64aed05c4 --- /dev/null +++ b/tests/xilinx/macc_tb.v @@ -0,0 +1,96 @@ +`timescale 1ns / 1ps + +module testbench; + + parameter SIZEIN = 16, SIZEOUT = 40; + reg clk, ce, rst; + reg signed [SIZEIN-1:0] a, b; + output signed [SIZEOUT-1:0] REF_accum_out, accum_out; + output REF_overflow, overflow; + + integer errcount = 0; + + reg ERROR_FLAG = 0; + + task clkcycle; + begin + #5; + clk = ~clk; + #10; + clk = ~clk; + #2; + ERROR_FLAG = 0; + if (REF_accum_out !== accum_out) begin + $display("ERROR at %1t: REF_accum_out=%b UUT_accum_out=%b DIFF=%b", $time, REF_accum_out, accum_out, REF_accum_out ^ accum_out); + errcount = errcount + 1; + ERROR_FLAG = 1; + end + if (REF_overflow !== overflow) begin + $display("ERROR at %1t: REF_overflow=%b UUT_overflow=%b DIFF=%b", $time, REF_overflow, overflow, REF_overflow ^ overflow); + errcount = errcount + 1; + ERROR_FLAG = 1; + end + #3; + end + endtask + + initial begin + //$dumpfile("test_macc.vcd"); + //$dumpvars(0, testbench); + + #2; + clk = 1'b0; + ce = 1'b0; + a = 0; + b = 0; + + rst = 1'b1; + repeat (10) begin + #10; + clk = 1'b1; + #10; + clk = 1'b0; + #10; + clk = 1'b1; + #10; + clk = 1'b0; + end + rst = 1'b0; + + repeat (10000) begin + clkcycle; + ce = 1; //$urandom & $urandom; + //rst = $urandom & $urandom & $urandom & $urandom & $urandom & $urandom; + a = $urandom & ~(1 << (SIZEIN-1)); + b = $urandom & ~(1 << (SIZEIN-1)); + end + + if (errcount == 0) begin + $display("All tests passed."); + $finish; + end else begin + $display("Caught %1d errors.", errcount); + $stop; + end + end + + macc2 ref ( + .clk(clk), + .ce(ce), + .rst(rst), + .a(a), + .b(b), + .accum_out(REF_accum_out), + .overflow(REF_overflow) + ); + + macc2_uut uut ( + .clk(clk), + .ce(ce), + .rst(rst), + .a(a), + .b(b), + .accum_out(accum_out), + .overflow(overflow) + ); +endmodule diff --git a/tests/xilinx/mul_unsigned.v b/tests/xilinx/mul_unsigned.v new file mode 100644 index 000000000..e3713a642 --- /dev/null +++ b/tests/xilinx/mul_unsigned.v @@ -0,0 +1,30 @@ +/* +Example from: https://www.xilinx.com/support/documentation/sw_manuals/xilinx2019_1/ug901-vivado-synthesis.pdf [p. 89]. +*/ + +// Unsigned 16x24-bit Multiplier +// 1 latency stage on operands +// 3 latency stage after the multiplication +// File: multipliers2.v +// +module mul_unsigned (clk, A, B, RES); +parameter WIDTHA = /*16*/ 6; +parameter WIDTHB = /*24*/ 9; +input clk; +input [WIDTHA-1:0] A; +input [WIDTHB-1:0] B; +output [WIDTHA+WIDTHB-1:0] RES; +reg [WIDTHA-1:0] rA; +reg [WIDTHB-1:0] rB; +reg [WIDTHA+WIDTHB-1:0] M [3:0]; +integer i; +always @(posedge clk) + begin + rA <= A; + rB <= B; + M[0] <= rA * rB; + for (i = 0; i < 3; i = i+1) + M[i+1] <= M[i]; + end +assign RES = M[3]; +endmodule diff --git a/tests/xilinx/mul_unsigned.ys b/tests/xilinx/mul_unsigned.ys new file mode 100644 index 000000000..77990bd68 --- /dev/null +++ b/tests/xilinx/mul_unsigned.ys @@ -0,0 +1,10 @@ +read_verilog mul_unsigned.v +proc +hierarchy -top mul_unsigned +equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd mul_unsigned # Constrain all select calls below inside the top module +select -assert-count 1 t:BUFG +select -assert-count 1 t:DSP48E1 +select -assert-count 30 t:FDRE +select -assert-none t:DSP48E1 t:FDRE t:BUFG %% t:* %D |