`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 (
assign CO = (I0 && I1) || ((I0 || I1) && CI);
endmodule
-(* abc_box_id = 1, abc_carry="CI,CO", lib_whitebox *)
-module \$__ICE40_FULL_ADDER (output CO, O, input A, B, CI);
+(* 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),
.CO(CO)
);
SB_LUT4 #(
- // I0: 1010 1010 1010 1010
- // I1: 1100 1100 1100 1100
- // I2: 1111 0000 1111 0000
- // I3: 1111 1111 0000 0000
- .LUT_INIT(16'b 0110_1001_1001_0110)
+ .LUT_INIT(LUT)
) adder (
- .I0(1'b0),
+ .I0(I0),
.I1(A),
.I2(B),
- .I3(CI),
+ .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);
+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;
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;
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;
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;
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;
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)
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;
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)
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;
// 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;
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;
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;
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;
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)
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;
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)
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;
// 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,
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,
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,
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,
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;
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
);
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;
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;