Comment out SB_MAC16 arrival time for now, need to handle all its modes
[yosys.git] / techlibs / ice40 / cells_sim.v
index 317ae2c1f77c7c5b5bfa70b641d9a99021d6fc43..8e5e0358e33e0d80b9a3f7616ab1a1cd688eef79 100644 (file)
@@ -2,6 +2,10 @@
 `define SB_DFF_REG reg Q = 0
 // `define SB_DFF_REG reg Q
 
+`define ABC_ARRIVAL_HX(TIME) `ifdef ICE40_HX (* abc_arrival=TIME *) `endif
+`define ABC_ARRIVAL_LP(TIME) `ifdef ICE40_LP (* abc_arrival=TIME *) `endif
+`define ABC_ARRIVAL_U(TIME)  `ifdef ICE40_U (* abc_arrival=TIME *) `endif
+
 // SiliconBlue IO Cells
 
 module SB_IO (
@@ -127,7 +131,7 @@ endmodule
 
 // SiliconBlue Logic Cells
 
-(* abc_box_id = 2, lib_whitebox *)
+(* lib_whitebox *)
 module SB_LUT4 (output O, input I0, I1, I2, I3);
        parameter [15:0] LUT_INIT = 0;
        wire [7:0] s3 = I3 ? LUT_INIT[15:8] : LUT_INIT[7:0];
@@ -136,29 +140,75 @@ module SB_LUT4 (output O, input I0, I1, I2, I3);
        assign O = I0 ? s1[1] : s1[0];
 endmodule
 
-(* abc_box_id = 1, abc_carry, lib_whitebox *)
-module SB_CARRY ((* abc_carry_out *) output CO, input I0, I1, (* abc_carry_in *) input CI);
+(* lib_whitebox *)
+module SB_CARRY (output CO, input I0, I1, CI);
        assign CO = (I0 && I1) || ((I0 || I1) && CI);
 endmodule
 
+(* abc_box_id = 1, lib_whitebox *)
+module \$__ICE40_CARRY_WRAPPER (
+       (* abc_carry *)
+       output CO,
+       output O,
+       input A, B,
+       (* abc_carry *)
+       input CI,
+       input I0, I3
+);
+       parameter LUT = 0;
+       SB_CARRY carry (
+               .I0(A),
+               .I1(B),
+               .CI(CI),
+               .CO(CO)
+       );
+       SB_LUT4 #(
+               .LUT_INIT(LUT)
+       ) adder (
+               .I0(I0),
+               .I1(A),
+               .I2(B),
+               .I3(I3),
+               .O(O)
+       );
+endmodule
+
+// Max delay from: https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90
+//                 https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90
+//                 https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102
+
 // Positive Edge SiliconBlue FF Cells
 
-module SB_DFF (output `SB_DFF_REG, input C, D);
-`ifndef _ABC
+module SB_DFF (
+       `ABC_ARRIVAL_HX(540)
+       `ABC_ARRIVAL_LP(796)
+       `ABC_ARRIVAL_U(1391)
+       output `SB_DFF_REG,
+       input C, D
+);
        always @(posedge C)
                Q <= D;
-`else
-    always @* Q <= D;
-`endif
 endmodule
 
-module SB_DFFE (output `SB_DFF_REG, input C, E, D);
+module SB_DFFE (
+       `ABC_ARRIVAL_HX(540)
+       `ABC_ARRIVAL_LP(796)
+       `ABC_ARRIVAL_U(1391)
+       output `SB_DFF_REG,
+       input C, E, D
+);
        always @(posedge C)
                if (E)
                        Q <= D;
 endmodule
 
-module SB_DFFSR (output `SB_DFF_REG, input C, R, D);
+module SB_DFFSR (
+       `ABC_ARRIVAL_HX(540)
+       `ABC_ARRIVAL_LP(796)
+       `ABC_ARRIVAL_U(1391)
+       output `SB_DFF_REG,
+       input C, R, D
+);
        always @(posedge C)
                if (R)
                        Q <= 0;
@@ -166,7 +216,13 @@ module SB_DFFSR (output `SB_DFF_REG, input C, R, D);
                        Q <= D;
 endmodule
 
-module SB_DFFR (output `SB_DFF_REG, input C, R, D);
+module SB_DFFR (
+       `ABC_ARRIVAL_HX(540)
+       `ABC_ARRIVAL_LP(796)
+       `ABC_ARRIVAL_U(1391)
+       output `SB_DFF_REG,
+       input C, R, D
+);
        always @(posedge C, posedge R)
                if (R)
                        Q <= 0;
@@ -174,7 +230,13 @@ module SB_DFFR (output `SB_DFF_REG, input C, R, D);
                        Q <= D;
 endmodule
 
-module SB_DFFSS (output `SB_DFF_REG, input C, S, D);
+module SB_DFFSS (
+       `ABC_ARRIVAL_HX(540)
+       `ABC_ARRIVAL_LP(796)
+       `ABC_ARRIVAL_U(1391)
+       output `SB_DFF_REG,
+       input C, S, D
+);
        always @(posedge C)
                if (S)
                        Q <= 1;
@@ -182,7 +244,13 @@ module SB_DFFSS (output `SB_DFF_REG, input C, S, D);
                        Q <= D;
 endmodule
 
-module SB_DFFS (output `SB_DFF_REG, input C, S, D);
+module SB_DFFS (
+       `ABC_ARRIVAL_HX(540)
+       `ABC_ARRIVAL_LP(796)
+       `ABC_ARRIVAL_U(1391)
+       output `SB_DFF_REG,
+       input C, S, D
+);
        always @(posedge C, posedge S)
                if (S)
                        Q <= 1;
@@ -190,7 +258,13 @@ module SB_DFFS (output `SB_DFF_REG, input C, S, D);
                        Q <= D;
 endmodule
 
-module SB_DFFESR (output `SB_DFF_REG, input C, E, R, D);
+module SB_DFFESR (
+       `ABC_ARRIVAL_HX(540)
+       `ABC_ARRIVAL_LP(796)
+       `ABC_ARRIVAL_U(1391)
+       output `SB_DFF_REG,
+       input C, E, R, D
+);
        always @(posedge C)
                if (E) begin
                        if (R)
@@ -200,7 +274,13 @@ module SB_DFFESR (output `SB_DFF_REG, input C, E, R, D);
                end
 endmodule
 
-module SB_DFFER (output `SB_DFF_REG, input C, E, R, D);
+module SB_DFFER (
+       `ABC_ARRIVAL_HX(540)
+       `ABC_ARRIVAL_LP(796)
+       `ABC_ARRIVAL_U(1391)
+       output `SB_DFF_REG,
+       input C, E, R, D
+);
        always @(posedge C, posedge R)
                if (R)
                        Q <= 0;
@@ -208,7 +288,13 @@ module SB_DFFER (output `SB_DFF_REG, input C, E, R, D);
                        Q <= D;
 endmodule
 
-module SB_DFFESS (output `SB_DFF_REG, input C, E, S, D);
+module SB_DFFESS (
+       `ABC_ARRIVAL_HX(540)
+       `ABC_ARRIVAL_LP(796)
+       `ABC_ARRIVAL_U(1391)
+       output `SB_DFF_REG,
+       input C, E, S, D
+);
        always @(posedge C)
                if (E) begin
                        if (S)
@@ -218,7 +304,13 @@ module SB_DFFESS (output `SB_DFF_REG, input C, E, S, D);
                end
 endmodule
 
-module SB_DFFES (output `SB_DFF_REG, input C, E, S, D);
+module SB_DFFES (
+       `ABC_ARRIVAL_HX(540)
+       `ABC_ARRIVAL_LP(796)
+       `ABC_ARRIVAL_U(1391)
+       output `SB_DFF_REG,
+       input C, E, S, D
+);
        always @(posedge C, posedge S)
                if (S)
                        Q <= 1;
@@ -228,18 +320,36 @@ endmodule
 
 // Negative Edge SiliconBlue FF Cells
 
-module SB_DFFN (output `SB_DFF_REG, input C, D);
+module SB_DFFN (
+       `ABC_ARRIVAL_HX(540)
+       `ABC_ARRIVAL_LP(796)
+       `ABC_ARRIVAL_U(1391)
+       output `SB_DFF_REG,
+       input C, D
+);
        always @(negedge C)
                Q <= D;
 endmodule
 
-module SB_DFFNE (output `SB_DFF_REG, input C, E, D);
+module SB_DFFNE (
+       `ABC_ARRIVAL_HX(540)
+       `ABC_ARRIVAL_LP(796)
+       `ABC_ARRIVAL_U(1391)
+       output `SB_DFF_REG,
+       input C, E, D
+);
        always @(negedge C)
                if (E)
                        Q <= D;
 endmodule
 
-module SB_DFFNSR (output `SB_DFF_REG, input C, R, D);
+module SB_DFFNSR (
+       `ABC_ARRIVAL_HX(540)
+       `ABC_ARRIVAL_LP(796)
+       `ABC_ARRIVAL_U(1391)
+       output `SB_DFF_REG,
+       input C, R, D
+);
        always @(negedge C)
                if (R)
                        Q <= 0;
@@ -247,7 +357,13 @@ module SB_DFFNSR (output `SB_DFF_REG, input C, R, D);
                        Q <= D;
 endmodule
 
-module SB_DFFNR (output `SB_DFF_REG, input C, R, D);
+module SB_DFFNR (
+       `ABC_ARRIVAL_HX(540)
+       `ABC_ARRIVAL_LP(796)
+       `ABC_ARRIVAL_U(1391)
+       output `SB_DFF_REG,
+       input C, R, D
+);
        always @(negedge C, posedge R)
                if (R)
                        Q <= 0;
@@ -255,7 +371,13 @@ module SB_DFFNR (output `SB_DFF_REG, input C, R, D);
                        Q <= D;
 endmodule
 
-module SB_DFFNSS (output `SB_DFF_REG, input C, S, D);
+module SB_DFFNSS (
+       `ABC_ARRIVAL_HX(540)
+       `ABC_ARRIVAL_LP(796)
+       `ABC_ARRIVAL_U(1391)
+       output `SB_DFF_REG,
+       input C, S, D
+);
        always @(negedge C)
                if (S)
                        Q <= 1;
@@ -263,7 +385,13 @@ module SB_DFFNSS (output `SB_DFF_REG, input C, S, D);
                        Q <= D;
 endmodule
 
-module SB_DFFNS (output `SB_DFF_REG, input C, S, D);
+module SB_DFFNS (
+       `ABC_ARRIVAL_HX(540)
+       `ABC_ARRIVAL_LP(796)
+       `ABC_ARRIVAL_U(1391)
+       output `SB_DFF_REG,
+       input C, S, D
+);
        always @(negedge C, posedge S)
                if (S)
                        Q <= 1;
@@ -271,7 +399,13 @@ module SB_DFFNS (output `SB_DFF_REG, input C, S, D);
                        Q <= D;
 endmodule
 
-module SB_DFFNESR (output `SB_DFF_REG, input C, E, R, D);
+module SB_DFFNESR (
+       `ABC_ARRIVAL_HX(540)
+       `ABC_ARRIVAL_LP(796)
+       `ABC_ARRIVAL_U(1391)
+       output `SB_DFF_REG,
+       input C, E, R, D
+);
        always @(negedge C)
                if (E) begin
                        if (R)
@@ -281,7 +415,13 @@ module SB_DFFNESR (output `SB_DFF_REG, input C, E, R, D);
                end
 endmodule
 
-module SB_DFFNER (output `SB_DFF_REG, input C, E, R, D);
+module SB_DFFNER (
+       `ABC_ARRIVAL_HX(540)
+       `ABC_ARRIVAL_LP(796)
+       `ABC_ARRIVAL_U(1391)
+       output `SB_DFF_REG,
+       input C, E, R, D
+);
        always @(negedge C, posedge R)
                if (R)
                        Q <= 0;
@@ -289,7 +429,13 @@ module SB_DFFNER (output `SB_DFF_REG, input C, E, R, D);
                        Q <= D;
 endmodule
 
-module SB_DFFNESS (output `SB_DFF_REG, input C, E, S, D);
+module SB_DFFNESS (
+       `ABC_ARRIVAL_HX(540)
+       `ABC_ARRIVAL_LP(796)
+       `ABC_ARRIVAL_U(1391)
+       output `SB_DFF_REG,
+       input C, E, S, D
+);
        always @(negedge C)
                if (E) begin
                        if (S)
@@ -299,7 +445,13 @@ module SB_DFFNESS (output `SB_DFF_REG, input C, E, S, D);
                end
 endmodule
 
-module SB_DFFNES (output `SB_DFF_REG, input C, E, S, D);
+module SB_DFFNES (
+       `ABC_ARRIVAL_HX(540)
+       `ABC_ARRIVAL_LP(796)
+       `ABC_ARRIVAL_U(1391)
+       output `SB_DFF_REG,
+       input C, E, S, D
+);
        always @(negedge C, posedge S)
                if (S)
                        Q <= 1;
@@ -310,6 +462,9 @@ endmodule
 // SiliconBlue RAM Cells
 
 module SB_RAM40_4K (
+       `ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
+       `ABC_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
+       `ABC_ARRIVAL_U(1179)  // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026
        output [15:0] RDATA,
        input         RCLK, RCLKE, RE,
        input  [10:0] RADDR,
@@ -478,6 +633,9 @@ module SB_RAM40_4K (
 endmodule
 
 module SB_RAM40_4KNR (
+       `ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
+       `ABC_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
+       `ABC_ARRIVAL_U(1179)  // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026
        output [15:0] RDATA,
        input         RCLKN, RCLKE, RE,
        input  [10:0] RADDR,
@@ -543,6 +701,9 @@ module SB_RAM40_4KNR (
 endmodule
 
 module SB_RAM40_4KNW (
+       `ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
+       `ABC_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
+       `ABC_ARRIVAL_U(1179)  // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026
        output [15:0] RDATA,
        input         RCLK, RCLKE, RE,
        input  [10:0] RADDR,
@@ -608,6 +769,9 @@ module SB_RAM40_4KNW (
 endmodule
 
 module SB_RAM40_4KNRNW (
+       `ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
+       `ABC_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
+       `ABC_ARRIVAL_U(1179)  // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026
        output [15:0] RDATA,
        input         RCLKN, RCLKE, RE,
        input  [10:0] RADDR,
@@ -676,7 +840,12 @@ endmodule
 
 module ICESTORM_LC (
        input I0, I1, I2, I3, CIN, CLK, CEN, SR,
-       output LO, O, COUT
+       output LO,
+       `ABC_ARRIVAL_HX(540)
+       `ABC_ARRIVAL_LP(796)
+       `ABC_ARRIVAL_U(1391)
+       output O,
+       output COUT
 );
        parameter [15:0] LUT_INIT = 0;
 
@@ -896,7 +1065,6 @@ module SB_WARMBOOT (
 );
 endmodule
 
-(* nomem2reg *)
 module SB_SPRAM256KA (
        input [13:0] ADDRESS,
        input [15:0] DATAIN,
@@ -1277,6 +1445,7 @@ module SB_MAC16 (
        input ADDSUBTOP, ADDSUBBOT,
        input OHOLDTOP, OHOLDBOT,
        input CI, ACCUMCI, SIGNEXTIN,
+       //`ABC_ARRIVAL_U(1984)  // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026
        output [31:0] O,
        output CO, ACCUMCO, SIGNEXTOUT
 );
@@ -1345,13 +1514,13 @@ module SB_MAC16 (
        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]}} : 8'b0, iA[15: 8]};
-       assign Al = {A_SIGNED ? {8{iA[ 7]}} : 8'b0, iA[ 7: 0]};
+       assign Al = {A_SIGNED && MODE_8x8 ? {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;
-       assign p_Al_Bl = Al * Bl;
+       assign Bl = {B_SIGNED && MODE_8x8 ? {8{iB[ 7]}} : 8'b0, iB[ 7: 0]};
+       assign p_Ah_Bh = Ah * Bh; // F
+       assign p_Al_Bh = {8'b0, Al[7:0]} * Bh; // J
+       assign p_Ah_Bl = Ah * {8'b0, Bl[7:0]}; // K
+       assign p_Al_Bl = Al * Bl; // G
 
        // Regs F and J
        reg [15:0] rF, rJ;
@@ -1382,7 +1551,9 @@ module SB_MAC16 (
        assign iG = BOT_8x8_MULT_REG ? rG : p_Al_Bl;
 
        // Adder Stage
-       assign iL = iG + (iK << 8) + (iJ << 8) + (iF << 16);
+       wire [23:0] iK_e = {A_SIGNED ? {8{iK[15]}} : 8'b0, iK};
+       wire [23:0] iJ_e = {B_SIGNED ? {8{iJ[15]}} : 8'b0, iJ};
+       assign iL = iG + (iK_e << 8) + (iJ_e << 8) + (iF << 16);
 
        // Reg H
        reg [31:0] rH;