Improve iCE40 SB_MAC16 model
authorClifford Wolf <clifford@clifford.at>
Wed, 20 Feb 2019 11:55:20 +0000 (12:55 +0100)
committerClifford Wolf <clifford@clifford.at>
Wed, 20 Feb 2019 11:55:20 +0000 (12:55 +0100)
Signed-off-by: Clifford Wolf <clifford@clifford.at>
techlibs/ice40/cells_sim.v
techlibs/ice40/tests/.gitignore
techlibs/ice40/tests/test_dsp_model.gtkw [deleted file]
techlibs/ice40/tests/test_dsp_model.sh
techlibs/ice40/tests/test_dsp_model.v

index 4a92fccdfc9aad88fefa397203478a173375a286..2041693cc6c213fd577e0b6a4952219559272e84 100644 (file)
@@ -1283,7 +1283,7 @@ module SB_MAC16 (
 
        // Regs B and D
        reg [15:0] rB, rD;
-       always @(posedge clock, posedge IRSTTOP) begin
+       always @(posedge clock, posedge IRSTBOT) begin
                if (IRSTBOT) begin
                        rB <= 0;
                        rD <= 0;
@@ -1298,10 +1298,10 @@ module SB_MAC16 (
        // Multiplier Stage
        wire [15:0] p_Ah_Bh, p_Al_Bh, p_Ah_Bl, p_Al_Bl;
        wire [15:0] Ah, Al, Bh, Bl;
-       assign Ah = A_SIGNED ? {{8{iA[15]}}, iA[15: 8]} : iA[15: 8];
-       assign Al = A_SIGNED ? {{8{iA[ 7]}}, iA[ 7: 0]} : iA[15: 8];
-       assign Bh = B_SIGNED ? {{8{iB[15]}}, iB[15: 8]} : iB[15: 8];
-       assign Bl = B_SIGNED ? {{8{iB[ 7]}}, iB[ 7: 0]} : iB[15: 8];
+       assign Ah = {A_SIGNED ? {8{iA[15]}} : 8'b0, iA[15: 8]};
+       assign Al = {A_SIGNED ? {8{iA[ 7]}} : 8'b0, iA[ 7: 0]};
+       assign Bh = {B_SIGNED ? {8{iB[15]}} : 8'b0, iB[15: 8]};
+       assign Bl = {B_SIGNED ? {8{iB[ 7]}} : 8'b0, iB[ 7: 0]};
        assign p_Ah_Bh = Ah * Bh;
        assign p_Al_Bh = Al * Bh;
        assign p_Ah_Bl = Ah * Bl;
@@ -1336,17 +1336,10 @@ module SB_MAC16 (
        assign iG = BOT_8x8_MULT_REG ? rG : p_Al_Bl;
 
        // Adder Stage
-       reg [31:0] P;
-       always @* begin
-               P = iG[7:0];
-               P = P + (iG[15:8] + iK[7:0]) << 8;
-               P = P + (iK[15:8] + iJ[7:0]) << 16;
-               P = P + (iJ[15:8] + iF[7:0]) << 24;
-       end
-       assign iL = P;
+       assign iL = iG + (iK << 8) + (iJ << 8) + (iF << 16);
 
        // Reg H
-       reg [15:0] rH;
+       reg [31:0] rH;
        always @(posedge clock, posedge IRSTBOT) begin
                if (IRSTBOT) begin
                        rH <= 0;
@@ -1359,7 +1352,7 @@ module SB_MAC16 (
        // Hi Output Stage
        wire [15:0] XW, Oh;
        reg [15:0] rQ;
-       assign iW = TOPADDSUB_UPPERINPUT ? iC : iQ[31:16];
+       assign iW = TOPADDSUB_UPPERINPUT ? iC : iQ;
        assign iX = (TOPADDSUB_LOWERINPUT == 0) ? iA : (TOPADDSUB_LOWERINPUT == 1) ? iF : (TOPADDSUB_LOWERINPUT == 2) ? iH[31:16] : {16{iZ[15]}};
        assign {ACCUMCO, XW} = iX + (iW ^ {16{ADDSUBTOP}}) + HCI;
        assign CO = ACCUMCO ^ ADDSUBTOP;
@@ -1379,7 +1372,7 @@ module SB_MAC16 (
        // Lo Output Stage
        wire [15:0] YZ, Ol;
        reg [15:0] rS;
-       assign iY = BOTADDSUB_UPPERINPUT ? iD : iQ[15:0];
+       assign iY = BOTADDSUB_UPPERINPUT ? iD : iS;
        assign iZ = (BOTADDSUB_LOWERINPUT == 0) ? iB : (BOTADDSUB_LOWERINPUT == 1) ? iG : (BOTADDSUB_LOWERINPUT == 2) ? iH[15:0] : {16{SIGNEXTIN}};
        assign {LCO, YZ} = iZ + (iY ^ {16{ADDSUBBOT}}) + LCI;
        assign iR = OLOADBOT ? iD : YZ ^ {16{ADDSUBBOT}};
@@ -1387,7 +1380,7 @@ module SB_MAC16 (
                if (ORSTBOT) begin
                        rS <= 0;
                end else if (CE) begin
-                       if (!OHOLDTOP) rS <= iR;
+                       if (!OHOLDBOT) rS <= iR;
                end
        end
        assign iS = rS;
index b58f9ad4afacb8ea0d6cc6d67781f8588ebad27b..9795152c2fe35a21faddfe5026a10aa31968a0a3 100644 (file)
@@ -1,2 +1,6 @@
-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
diff --git a/techlibs/ice40/tests/test_dsp_model.gtkw b/techlibs/ice40/tests/test_dsp_model.gtkw
deleted file mode 100644 (file)
index dafe891..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-[*]
-[*] GTKWave Analyzer v3.3.86 (w)1999-2017 BSI
-[*] Tue Feb 19 13:33:31 2019
-[*]
-[dumpfile] "/home/clifford/Work/yosys/techlibs/ice40/tests/test_dsp_model.vcd"
-[dumpfile_mtime] "Tue Feb 19 13:29:34 2019"
-[dumpfile_size] 119605
-[savefile] "/home/clifford/Work/yosys/techlibs/ice40/tests/test_dsp_model.gtkw"
-[timestart] 0
-[size] 1850 1362
-[pos] 1816 32
-*-16.399944 42300 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-[sst_width] 223
-[signals_width] 142
-[sst_expanded] 1
-[sst_vpaned_height] 420
-@28
-testbench.CLK
-testbench.CE
-@200
--
-@28
-testbench.REF_ACCUMCO
-testbench.UUT_ACCUMCO
-@200
--
-@28
-testbench.REF_CO
-testbench.UUT_CO
-@200
--
-@22
-testbench.REF_O[31:0]
-testbench.UUT_O[31:0]
-@200
--
-@28
-testbench.REF_SIGNEXTOUT
-testbench.UUT_SIGNEXTOUT
-@200
--
-@22
-testbench.A[15:0]
-testbench.B[15:0]
-testbench.C[15:0]
-testbench.D[15:0]
-@200
--
-@28
-testbench.AHOLD
-testbench.BHOLD
-testbench.CHOLD
-testbench.DHOLD
-@200
--
-@28
-testbench.SIGNEXTIN
-testbench.ACCUMCI
-testbench.CI
-@200
--
-@28
-testbench.ADDSUBTOP
-testbench.ADDSUBBOT
-@200
--
-@28
-testbench.IRSTTOP
-testbench.IRSTBOT
-@200
--
-@29
-testbench.OHOLDTOP
-@28
-testbench.OHOLDBOT
-@200
--
-@28
-testbench.OLOADTOP
-testbench.OLOADBOT
-@200
--
-@28
-testbench.ORSTTOP
-testbench.ORSTBOT
-[pattern_trace] 1
-[pattern_trace] 0
index ad079b2b63e44e3bfc782ba6395cdd76b937cb24..1bc0cc68830a95d82f6bcd333916e7c678f7a50f 100644 (file)
@@ -2,5 +2,10 @@
 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
-iverilog -s testbench -o test_dsp_model test_dsp_model.v test_dsp_model_uut.v test_dsp_model_ref.v
-./test_dsp_model
+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
index 919bb791704b61165820a69cce234c3b204251af..594bd4ad3a35f53a4fc9dda38b6eece55e131296 100644 (file)
@@ -11,13 +11,13 @@ module testbench;
        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 = 2;
+       parameter [1:0] TOPADDSUB_LOWERINPUT = 0;
        parameter [0:0] TOPADDSUB_UPPERINPUT = 1;
-       parameter [1:0] TOPADDSUB_CARRYSELECT = 2;
+       parameter [1:0] TOPADDSUB_CARRYSELECT = 0;
        parameter [1:0] BOTOUTPUT_SELECT = 0;
-       parameter [1:0] BOTADDSUB_LOWERINPUT = 2;
+       parameter [1:0] BOTADDSUB_LOWERINPUT = 0;
        parameter [0:0] BOTADDSUB_UPPERINPUT = 1;
-       parameter [1:0] BOTADDSUB_CARRYSELECT = 2;
+       parameter [1:0] BOTADDSUB_CARRYSELECT = 0;
        parameter [0:0] MODE_8x8 = 0;
        parameter [0:0] A_SIGNED = 0;
        parameter [0:0] B_SIGNED = 0;
@@ -46,7 +46,7 @@ module testbench;
                        CLK = ~CLK;
                        #2;
                        if (REF_O !== UUT_O) begin
-                               $display("ERROR at %1t: REF_O=%b UUT_O=%b", $time, REF_O, UUT_O);
+                               $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
@@ -69,29 +69,47 @@ module testbench;
                $dumpfile("test_dsp_model.vcd");
                $dumpvars(0, testbench);
 
-               #5;
+               #2;
                CLK = NEG_TRIGGER;
                CE = 1;
                {C, A, B, D} = 0;
                {AHOLD, BHOLD, CHOLD, DHOLD} = 0;
-               {IRSTTOP, IRSTBOT} = 0;
-               {ORSTTOP, ORSTBOT} = 0;
                {OLOADTOP, OLOADBOT} = 0;
                {ADDSUBTOP, ADDSUBBOT} = 0;
                {OHOLDTOP, OHOLDBOT} = 0;
                {CI, ACCUMCI, SIGNEXTIN} = 0;
 
-               // C = 10;
-               // A = 15;
-               // B = 22;
-               // D = 27;
+               {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;
 
-               repeat (10) clkcycle;
+                       {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
 
@@ -197,3 +215,128 @@ module testbench;
                .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