yosys/techlibs/ice40/cells_sim.v

1579 lines
44 KiB
Verilog

`define SB_DFF_REG reg Q = 0
// `define SB_DFF_REG reg Q
`define ABC9_ARRIVAL_HX(TIME) `ifdef ICE40_HX (* abc9_arrival=TIME *) `endif
`define ABC9_ARRIVAL_LP(TIME) `ifdef ICE40_LP (* abc9_arrival=TIME *) `endif
`define ABC9_ARRIVAL_U(TIME) `ifdef ICE40_U (* abc9_arrival=TIME *) `endif
// SiliconBlue IO Cells
module SB_IO (
inout PACKAGE_PIN,
input LATCH_INPUT_VALUE,
input CLOCK_ENABLE,
input INPUT_CLK,
input OUTPUT_CLK,
input OUTPUT_ENABLE,
input D_OUT_0,
input D_OUT_1,
output D_IN_0,
output D_IN_1
);
parameter [5:0] PIN_TYPE = 6'b000000;
parameter [0:0] PULLUP = 1'b0;
parameter [0:0] NEG_TRIGGER = 1'b0;
parameter IO_STANDARD = "SB_LVCMOS";
`ifndef BLACKBOX
reg dout, din_0, din_1;
reg din_q_0, din_q_1;
reg dout_q_0, dout_q_1;
reg outena_q;
// IO tile generates a constant 1'b1 internally if global_cen is not connected
wire clken_pulled = CLOCK_ENABLE || CLOCK_ENABLE === 1'bz;
reg clken_pulled_ri;
reg clken_pulled_ro;
generate if (!NEG_TRIGGER) begin
always @(posedge INPUT_CLK) clken_pulled_ri <= clken_pulled;
always @(posedge INPUT_CLK) if (clken_pulled) din_q_0 <= PACKAGE_PIN;
always @(negedge INPUT_CLK) if (clken_pulled_ri) din_q_1 <= PACKAGE_PIN;
always @(posedge OUTPUT_CLK) clken_pulled_ro <= clken_pulled;
always @(posedge OUTPUT_CLK) if (clken_pulled) dout_q_0 <= D_OUT_0;
always @(negedge OUTPUT_CLK) if (clken_pulled_ro) dout_q_1 <= D_OUT_1;
always @(posedge OUTPUT_CLK) if (clken_pulled) outena_q <= OUTPUT_ENABLE;
end else begin
always @(negedge INPUT_CLK) clken_pulled_ri <= clken_pulled;
always @(negedge INPUT_CLK) if (clken_pulled) din_q_0 <= PACKAGE_PIN;
always @(posedge INPUT_CLK) if (clken_pulled_ri) din_q_1 <= PACKAGE_PIN;
always @(negedge OUTPUT_CLK) clken_pulled_ro <= clken_pulled;
always @(negedge OUTPUT_CLK) if (clken_pulled) dout_q_0 <= D_OUT_0;
always @(posedge OUTPUT_CLK) if (clken_pulled_ro) dout_q_1 <= D_OUT_1;
always @(negedge OUTPUT_CLK) if (clken_pulled) outena_q <= OUTPUT_ENABLE;
end endgenerate
always @* begin
if (!PIN_TYPE[1] || !LATCH_INPUT_VALUE)
din_0 = PIN_TYPE[0] ? PACKAGE_PIN : din_q_0;
din_1 = din_q_1;
end
// work around simulation glitches on dout in DDR mode
reg outclk_delayed_1;
reg outclk_delayed_2;
always @* outclk_delayed_1 <= OUTPUT_CLK;
always @* outclk_delayed_2 <= outclk_delayed_1;
always @* begin
if (PIN_TYPE[3])
dout = PIN_TYPE[2] ? !dout_q_0 : D_OUT_0;
else
dout = (outclk_delayed_2 ^ NEG_TRIGGER) || PIN_TYPE[2] ? dout_q_0 : dout_q_1;
end
assign D_IN_0 = din_0, D_IN_1 = din_1;
generate
if (PIN_TYPE[5:4] == 2'b01) assign PACKAGE_PIN = dout;
if (PIN_TYPE[5:4] == 2'b10) assign PACKAGE_PIN = OUTPUT_ENABLE ? dout : 1'bz;
if (PIN_TYPE[5:4] == 2'b11) assign PACKAGE_PIN = outena_q ? dout : 1'bz;
endgenerate
`endif
endmodule
module SB_GB_IO (
inout PACKAGE_PIN,
output GLOBAL_BUFFER_OUTPUT,
input LATCH_INPUT_VALUE,
input CLOCK_ENABLE,
input INPUT_CLK,
input OUTPUT_CLK,
input OUTPUT_ENABLE,
input D_OUT_0,
input D_OUT_1,
output D_IN_0,
output D_IN_1
);
parameter [5:0] PIN_TYPE = 6'b000000;
parameter [0:0] PULLUP = 1'b0;
parameter [0:0] NEG_TRIGGER = 1'b0;
parameter IO_STANDARD = "SB_LVCMOS";
assign GLOBAL_BUFFER_OUTPUT = PACKAGE_PIN;
SB_IO #(
.PIN_TYPE(PIN_TYPE),
.PULLUP(PULLUP),
.NEG_TRIGGER(NEG_TRIGGER),
.IO_STANDARD(IO_STANDARD)
) IO (
.PACKAGE_PIN(PACKAGE_PIN),
.LATCH_INPUT_VALUE(LATCH_INPUT_VALUE),
.CLOCK_ENABLE(CLOCK_ENABLE),
.INPUT_CLK(INPUT_CLK),
.OUTPUT_CLK(OUTPUT_CLK),
.OUTPUT_ENABLE(OUTPUT_ENABLE),
.D_OUT_0(D_OUT_0),
.D_OUT_1(D_OUT_1),
.D_IN_0(D_IN_0),
.D_IN_1(D_IN_1)
);
endmodule
module SB_GB (
input USER_SIGNAL_TO_GLOBAL_BUFFER,
output GLOBAL_BUFFER_OUTPUT
);
assign GLOBAL_BUFFER_OUTPUT = USER_SIGNAL_TO_GLOBAL_BUFFER;
endmodule
// SiliconBlue Logic Cells
(* 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];
wire [3:0] s2 = I2 ? s3[ 7:4] : s3[3:0];
wire [1:0] s1 = I1 ? s2[ 3:2] : s2[1:0];
assign O = I0 ? s1[1] : s1[0];
endmodule
(* lib_whitebox *)
module SB_CARRY (output CO, input I0, I1, CI);
assign CO = (I0 && I1) || ((I0 || I1) && CI);
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 (
`ABC9_ARRIVAL_HX(540)
`ABC9_ARRIVAL_LP(796)
`ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, D
);
always @(posedge C)
Q <= D;
endmodule
module SB_DFFE (
`ABC9_ARRIVAL_HX(540)
`ABC9_ARRIVAL_LP(796)
`ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, E, D
);
always @(posedge C)
if (E)
Q <= D;
endmodule
module SB_DFFSR (
`ABC9_ARRIVAL_HX(540)
`ABC9_ARRIVAL_LP(796)
`ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, R, D
);
always @(posedge C)
if (R)
Q <= 0;
else
Q <= D;
endmodule
module SB_DFFR (
`ABC9_ARRIVAL_HX(540)
`ABC9_ARRIVAL_LP(796)
`ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, R, D
);
always @(posedge C, posedge R)
if (R)
Q <= 0;
else
Q <= D;
endmodule
module SB_DFFSS (
`ABC9_ARRIVAL_HX(540)
`ABC9_ARRIVAL_LP(796)
`ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, S, D
);
always @(posedge C)
if (S)
Q <= 1;
else
Q <= D;
endmodule
module SB_DFFS (
`ABC9_ARRIVAL_HX(540)
`ABC9_ARRIVAL_LP(796)
`ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, S, D
);
always @(posedge C, posedge S)
if (S)
Q <= 1;
else
Q <= D;
endmodule
module SB_DFFESR (
`ABC9_ARRIVAL_HX(540)
`ABC9_ARRIVAL_LP(796)
`ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, E, R, D
);
always @(posedge C)
if (E) begin
if (R)
Q <= 0;
else
Q <= D;
end
endmodule
module SB_DFFER (
`ABC9_ARRIVAL_HX(540)
`ABC9_ARRIVAL_LP(796)
`ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, E, R, D
);
always @(posedge C, posedge R)
if (R)
Q <= 0;
else if (E)
Q <= D;
endmodule
module SB_DFFESS (
`ABC9_ARRIVAL_HX(540)
`ABC9_ARRIVAL_LP(796)
`ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, E, S, D
);
always @(posedge C)
if (E) begin
if (S)
Q <= 1;
else
Q <= D;
end
endmodule
module SB_DFFES (
`ABC9_ARRIVAL_HX(540)
`ABC9_ARRIVAL_LP(796)
`ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, E, S, D
);
always @(posedge C, posedge S)
if (S)
Q <= 1;
else if (E)
Q <= D;
endmodule
// Negative Edge SiliconBlue FF Cells
module SB_DFFN (
`ABC9_ARRIVAL_HX(540)
`ABC9_ARRIVAL_LP(796)
`ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, D
);
always @(negedge C)
Q <= D;
endmodule
module SB_DFFNE (
`ABC9_ARRIVAL_HX(540)
`ABC9_ARRIVAL_LP(796)
`ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, E, D
);
always @(negedge C)
if (E)
Q <= D;
endmodule
module SB_DFFNSR (
`ABC9_ARRIVAL_HX(540)
`ABC9_ARRIVAL_LP(796)
`ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, R, D
);
always @(negedge C)
if (R)
Q <= 0;
else
Q <= D;
endmodule
module SB_DFFNR (
`ABC9_ARRIVAL_HX(540)
`ABC9_ARRIVAL_LP(796)
`ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, R, D
);
always @(negedge C, posedge R)
if (R)
Q <= 0;
else
Q <= D;
endmodule
module SB_DFFNSS (
`ABC9_ARRIVAL_HX(540)
`ABC9_ARRIVAL_LP(796)
`ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, S, D
);
always @(negedge C)
if (S)
Q <= 1;
else
Q <= D;
endmodule
module SB_DFFNS (
`ABC9_ARRIVAL_HX(540)
`ABC9_ARRIVAL_LP(796)
`ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, S, D
);
always @(negedge C, posedge S)
if (S)
Q <= 1;
else
Q <= D;
endmodule
module SB_DFFNESR (
`ABC9_ARRIVAL_HX(540)
`ABC9_ARRIVAL_LP(796)
`ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, E, R, D
);
always @(negedge C)
if (E) begin
if (R)
Q <= 0;
else
Q <= D;
end
endmodule
module SB_DFFNER (
`ABC9_ARRIVAL_HX(540)
`ABC9_ARRIVAL_LP(796)
`ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, E, R, D
);
always @(negedge C, posedge R)
if (R)
Q <= 0;
else if (E)
Q <= D;
endmodule
module SB_DFFNESS (
`ABC9_ARRIVAL_HX(540)
`ABC9_ARRIVAL_LP(796)
`ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, E, S, D
);
always @(negedge C)
if (E) begin
if (S)
Q <= 1;
else
Q <= D;
end
endmodule
module SB_DFFNES (
`ABC9_ARRIVAL_HX(540)
`ABC9_ARRIVAL_LP(796)
`ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, E, S, D
);
always @(negedge C, posedge S)
if (S)
Q <= 1;
else if (E)
Q <= D;
endmodule
// SiliconBlue RAM Cells
module SB_RAM40_4K (
`ABC9_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
`ABC9_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
`ABC9_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,
input WCLK, WCLKE, WE,
input [10:0] WADDR,
input [15:0] MASK, WDATA
);
// MODE 0: 256 x 16
// MODE 1: 512 x 8
// MODE 2: 1024 x 4
// MODE 3: 2048 x 2
parameter WRITE_MODE = 0;
parameter READ_MODE = 0;
parameter INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_FILE = "";
`ifndef BLACKBOX
wire [15:0] WMASK_I;
wire [15:0] RMASK_I;
reg [15:0] RDATA_I;
wire [15:0] WDATA_I;
generate
case (WRITE_MODE)
0: assign WMASK_I = MASK;
1: assign WMASK_I = WADDR[ 8] == 0 ? 16'b 1010_1010_1010_1010 :
WADDR[ 8] == 1 ? 16'b 0101_0101_0101_0101 : 16'bx;
2: assign WMASK_I = WADDR[ 9:8] == 0 ? 16'b 1110_1110_1110_1110 :
WADDR[ 9:8] == 1 ? 16'b 1101_1101_1101_1101 :
WADDR[ 9:8] == 2 ? 16'b 1011_1011_1011_1011 :
WADDR[ 9:8] == 3 ? 16'b 0111_0111_0111_0111 : 16'bx;
3: assign WMASK_I = WADDR[10:8] == 0 ? 16'b 1111_1110_1111_1110 :
WADDR[10:8] == 1 ? 16'b 1111_1101_1111_1101 :
WADDR[10:8] == 2 ? 16'b 1111_1011_1111_1011 :
WADDR[10:8] == 3 ? 16'b 1111_0111_1111_0111 :
WADDR[10:8] == 4 ? 16'b 1110_1111_1110_1111 :
WADDR[10:8] == 5 ? 16'b 1101_1111_1101_1111 :
WADDR[10:8] == 6 ? 16'b 1011_1111_1011_1111 :
WADDR[10:8] == 7 ? 16'b 0111_1111_0111_1111 : 16'bx;
endcase
case (READ_MODE)
0: assign RMASK_I = 16'b 0000_0000_0000_0000;
1: assign RMASK_I = RADDR[ 8] == 0 ? 16'b 1010_1010_1010_1010 :
RADDR[ 8] == 1 ? 16'b 0101_0101_0101_0101 : 16'bx;
2: assign RMASK_I = RADDR[ 9:8] == 0 ? 16'b 1110_1110_1110_1110 :
RADDR[ 9:8] == 1 ? 16'b 1101_1101_1101_1101 :
RADDR[ 9:8] == 2 ? 16'b 1011_1011_1011_1011 :
RADDR[ 9:8] == 3 ? 16'b 0111_0111_0111_0111 : 16'bx;
3: assign RMASK_I = RADDR[10:8] == 0 ? 16'b 1111_1110_1111_1110 :
RADDR[10:8] == 1 ? 16'b 1111_1101_1111_1101 :
RADDR[10:8] == 2 ? 16'b 1111_1011_1111_1011 :
RADDR[10:8] == 3 ? 16'b 1111_0111_1111_0111 :
RADDR[10:8] == 4 ? 16'b 1110_1111_1110_1111 :
RADDR[10:8] == 5 ? 16'b 1101_1111_1101_1111 :
RADDR[10:8] == 6 ? 16'b 1011_1111_1011_1111 :
RADDR[10:8] == 7 ? 16'b 0111_1111_0111_1111 : 16'bx;
endcase
case (WRITE_MODE)
0: assign WDATA_I = WDATA;
1: assign WDATA_I = {WDATA[14], WDATA[14], WDATA[12], WDATA[12],
WDATA[10], WDATA[10], WDATA[ 8], WDATA[ 8],
WDATA[ 6], WDATA[ 6], WDATA[ 4], WDATA[ 4],
WDATA[ 2], WDATA[ 2], WDATA[ 0], WDATA[ 0]};
2: assign WDATA_I = {WDATA[13], WDATA[13], WDATA[13], WDATA[13],
WDATA[ 9], WDATA[ 9], WDATA[ 9], WDATA[ 9],
WDATA[ 5], WDATA[ 5], WDATA[ 5], WDATA[ 5],
WDATA[ 1], WDATA[ 1], WDATA[ 1], WDATA[ 1]};
3: assign WDATA_I = {WDATA[11], WDATA[11], WDATA[11], WDATA[11],
WDATA[11], WDATA[11], WDATA[11], WDATA[11],
WDATA[ 3], WDATA[ 3], WDATA[ 3], WDATA[ 3],
WDATA[ 3], WDATA[ 3], WDATA[ 3], WDATA[ 3]};
endcase
case (READ_MODE)
0: assign RDATA = RDATA_I;
1: assign RDATA = {1'b0, |RDATA_I[15:14], 1'b0, |RDATA_I[13:12], 1'b0, |RDATA_I[11:10], 1'b0, |RDATA_I[ 9: 8],
1'b0, |RDATA_I[ 7: 6], 1'b0, |RDATA_I[ 5: 4], 1'b0, |RDATA_I[ 3: 2], 1'b0, |RDATA_I[ 1: 0]};
2: assign RDATA = {2'b0, |RDATA_I[15:12], 3'b0, |RDATA_I[11: 8], 3'b0, |RDATA_I[ 7: 4], 3'b0, |RDATA_I[ 3: 0], 1'b0};
3: assign RDATA = {4'b0, |RDATA_I[15: 8], 7'b0, |RDATA_I[ 7: 0], 3'b0};
endcase
endgenerate
integer i;
reg [15:0] memory [0:255];
initial begin
if (INIT_FILE != "")
$readmemh(INIT_FILE, memory);
else
for (i=0; i<16; i=i+1) begin
memory[ 0*16 + i] = INIT_0[16*i +: 16];
memory[ 1*16 + i] = INIT_1[16*i +: 16];
memory[ 2*16 + i] = INIT_2[16*i +: 16];
memory[ 3*16 + i] = INIT_3[16*i +: 16];
memory[ 4*16 + i] = INIT_4[16*i +: 16];
memory[ 5*16 + i] = INIT_5[16*i +: 16];
memory[ 6*16 + i] = INIT_6[16*i +: 16];
memory[ 7*16 + i] = INIT_7[16*i +: 16];
memory[ 8*16 + i] = INIT_8[16*i +: 16];
memory[ 9*16 + i] = INIT_9[16*i +: 16];
memory[10*16 + i] = INIT_A[16*i +: 16];
memory[11*16 + i] = INIT_B[16*i +: 16];
memory[12*16 + i] = INIT_C[16*i +: 16];
memory[13*16 + i] = INIT_D[16*i +: 16];
memory[14*16 + i] = INIT_E[16*i +: 16];
memory[15*16 + i] = INIT_F[16*i +: 16];
end
end
always @(posedge WCLK) begin
if (WE && WCLKE) begin
if (!WMASK_I[ 0]) memory[WADDR[7:0]][ 0] <= WDATA_I[ 0];
if (!WMASK_I[ 1]) memory[WADDR[7:0]][ 1] <= WDATA_I[ 1];
if (!WMASK_I[ 2]) memory[WADDR[7:0]][ 2] <= WDATA_I[ 2];
if (!WMASK_I[ 3]) memory[WADDR[7:0]][ 3] <= WDATA_I[ 3];
if (!WMASK_I[ 4]) memory[WADDR[7:0]][ 4] <= WDATA_I[ 4];
if (!WMASK_I[ 5]) memory[WADDR[7:0]][ 5] <= WDATA_I[ 5];
if (!WMASK_I[ 6]) memory[WADDR[7:0]][ 6] <= WDATA_I[ 6];
if (!WMASK_I[ 7]) memory[WADDR[7:0]][ 7] <= WDATA_I[ 7];
if (!WMASK_I[ 8]) memory[WADDR[7:0]][ 8] <= WDATA_I[ 8];
if (!WMASK_I[ 9]) memory[WADDR[7:0]][ 9] <= WDATA_I[ 9];
if (!WMASK_I[10]) memory[WADDR[7:0]][10] <= WDATA_I[10];
if (!WMASK_I[11]) memory[WADDR[7:0]][11] <= WDATA_I[11];
if (!WMASK_I[12]) memory[WADDR[7:0]][12] <= WDATA_I[12];
if (!WMASK_I[13]) memory[WADDR[7:0]][13] <= WDATA_I[13];
if (!WMASK_I[14]) memory[WADDR[7:0]][14] <= WDATA_I[14];
if (!WMASK_I[15]) memory[WADDR[7:0]][15] <= WDATA_I[15];
end
end
always @(posedge RCLK) begin
if (RE && RCLKE) begin
RDATA_I <= memory[RADDR[7:0]] & ~RMASK_I;
end
end
`endif
endmodule
module SB_RAM40_4KNR (
`ABC9_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
`ABC9_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
`ABC9_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,
input WCLK, WCLKE, WE,
input [10:0] WADDR,
input [15:0] MASK, WDATA
);
parameter WRITE_MODE = 0;
parameter READ_MODE = 0;
parameter INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_FILE = "";
SB_RAM40_4K #(
.WRITE_MODE(WRITE_MODE),
.READ_MODE (READ_MODE ),
.INIT_0 (INIT_0 ),
.INIT_1 (INIT_1 ),
.INIT_2 (INIT_2 ),
.INIT_3 (INIT_3 ),
.INIT_4 (INIT_4 ),
.INIT_5 (INIT_5 ),
.INIT_6 (INIT_6 ),
.INIT_7 (INIT_7 ),
.INIT_8 (INIT_8 ),
.INIT_9 (INIT_9 ),
.INIT_A (INIT_A ),
.INIT_B (INIT_B ),
.INIT_C (INIT_C ),
.INIT_D (INIT_D ),
.INIT_E (INIT_E ),
.INIT_F (INIT_F ),
.INIT_FILE (INIT_FILE )
) RAM (
.RDATA(RDATA),
.RCLK (~RCLKN),
.RCLKE(RCLKE),
.RE (RE ),
.RADDR(RADDR),
.WCLK (WCLK ),
.WCLKE(WCLKE),
.WE (WE ),
.WADDR(WADDR),
.MASK (MASK ),
.WDATA(WDATA)
);
endmodule
module SB_RAM40_4KNW (
`ABC9_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
`ABC9_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
`ABC9_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,
input WCLKN, WCLKE, WE,
input [10:0] WADDR,
input [15:0] MASK, WDATA
);
parameter WRITE_MODE = 0;
parameter READ_MODE = 0;
parameter INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_FILE = "";
SB_RAM40_4K #(
.WRITE_MODE(WRITE_MODE),
.READ_MODE (READ_MODE ),
.INIT_0 (INIT_0 ),
.INIT_1 (INIT_1 ),
.INIT_2 (INIT_2 ),
.INIT_3 (INIT_3 ),
.INIT_4 (INIT_4 ),
.INIT_5 (INIT_5 ),
.INIT_6 (INIT_6 ),
.INIT_7 (INIT_7 ),
.INIT_8 (INIT_8 ),
.INIT_9 (INIT_9 ),
.INIT_A (INIT_A ),
.INIT_B (INIT_B ),
.INIT_C (INIT_C ),
.INIT_D (INIT_D ),
.INIT_E (INIT_E ),
.INIT_F (INIT_F ),
.INIT_FILE (INIT_FILE )
) RAM (
.RDATA(RDATA),
.RCLK (RCLK ),
.RCLKE(RCLKE),
.RE (RE ),
.RADDR(RADDR),
.WCLK (~WCLKN),
.WCLKE(WCLKE),
.WE (WE ),
.WADDR(WADDR),
.MASK (MASK ),
.WDATA(WDATA)
);
endmodule
module SB_RAM40_4KNRNW (
`ABC9_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
`ABC9_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
`ABC9_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,
input WCLKN, WCLKE, WE,
input [10:0] WADDR,
input [15:0] MASK, WDATA
);
parameter WRITE_MODE = 0;
parameter READ_MODE = 0;
parameter INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_FILE = "";
SB_RAM40_4K #(
.WRITE_MODE(WRITE_MODE),
.READ_MODE (READ_MODE ),
.INIT_0 (INIT_0 ),
.INIT_1 (INIT_1 ),
.INIT_2 (INIT_2 ),
.INIT_3 (INIT_3 ),
.INIT_4 (INIT_4 ),
.INIT_5 (INIT_5 ),
.INIT_6 (INIT_6 ),
.INIT_7 (INIT_7 ),
.INIT_8 (INIT_8 ),
.INIT_9 (INIT_9 ),
.INIT_A (INIT_A ),
.INIT_B (INIT_B ),
.INIT_C (INIT_C ),
.INIT_D (INIT_D ),
.INIT_E (INIT_E ),
.INIT_F (INIT_F ),
.INIT_FILE (INIT_FILE )
) RAM (
.RDATA(RDATA),
.RCLK (~RCLKN),
.RCLKE(RCLKE),
.RE (RE ),
.RADDR(RADDR),
.WCLK (~WCLKN),
.WCLKE(WCLKE),
.WE (WE ),
.WADDR(WADDR),
.MASK (MASK ),
.WDATA(WDATA)
);
endmodule
// Packed IceStorm Logic Cells
module ICESTORM_LC (
input I0, I1, I2, I3, CIN, CLK, CEN, SR,
output LO,
`ABC9_ARRIVAL_HX(540)
`ABC9_ARRIVAL_LP(796)
`ABC9_ARRIVAL_U(1391)
output O,
output COUT
);
parameter [15:0] LUT_INIT = 0;
parameter [0:0] NEG_CLK = 0;
parameter [0:0] CARRY_ENABLE = 0;
parameter [0:0] DFF_ENABLE = 0;
parameter [0:0] SET_NORESET = 0;
parameter [0:0] ASYNC_SR = 0;
parameter [0:0] CIN_CONST = 0;
parameter [0:0] CIN_SET = 0;
wire mux_cin = CIN_CONST ? CIN_SET : CIN;
assign COUT = CARRY_ENABLE ? (I1 && I2) || ((I1 || I2) && mux_cin) : 1'bx;
wire [7:0] lut_s3 = I3 ? LUT_INIT[15:8] : LUT_INIT[7:0];
wire [3:0] lut_s2 = I2 ? lut_s3[ 7:4] : lut_s3[3:0];
wire [1:0] lut_s1 = I1 ? lut_s2[ 3:2] : lut_s2[1:0];
wire lut_o = I0 ? lut_s1[ 1] : lut_s1[ 0];
assign LO = lut_o;
wire polarized_clk;
assign polarized_clk = CLK ^ NEG_CLK;
reg o_reg;
always @(posedge polarized_clk)
if (CEN)
o_reg <= SR ? SET_NORESET : lut_o;
reg o_reg_async;
always @(posedge polarized_clk, posedge SR)
if (SR)
o_reg <= SET_NORESET;
else if (CEN)
o_reg <= lut_o;
assign O = DFF_ENABLE ? ASYNC_SR ? o_reg_async : o_reg : lut_o;
endmodule
// SiliconBlue PLL Cells
(* blackbox *)
module SB_PLL40_CORE (
input REFERENCECLK,
output PLLOUTCORE,
output PLLOUTGLOBAL,
input EXTFEEDBACK,
input [7:0] DYNAMICDELAY,
output LOCK,
input BYPASS,
input RESETB,
input LATCHINPUTVALUE,
output SDO,
input SDI,
input SCLK
);
parameter FEEDBACK_PATH = "SIMPLE";
parameter DELAY_ADJUSTMENT_MODE_FEEDBACK = "FIXED";
parameter DELAY_ADJUSTMENT_MODE_RELATIVE = "FIXED";
parameter SHIFTREG_DIV_MODE = 1'b0;
parameter FDA_FEEDBACK = 4'b0000;
parameter FDA_RELATIVE = 4'b0000;
parameter PLLOUT_SELECT = "GENCLK";
parameter DIVR = 4'b0000;
parameter DIVF = 7'b0000000;
parameter DIVQ = 3'b000;
parameter FILTER_RANGE = 3'b000;
parameter ENABLE_ICEGATE = 1'b0;
parameter TEST_MODE = 1'b0;
parameter EXTERNAL_DIVIDE_FACTOR = 1;
endmodule
(* blackbox *)
module SB_PLL40_PAD (
input PACKAGEPIN,
output PLLOUTCORE,
output PLLOUTGLOBAL,
input EXTFEEDBACK,
input [7:0] DYNAMICDELAY,
output LOCK,
input BYPASS,
input RESETB,
input LATCHINPUTVALUE,
output SDO,
input SDI,
input SCLK
);
parameter FEEDBACK_PATH = "SIMPLE";
parameter DELAY_ADJUSTMENT_MODE_FEEDBACK = "FIXED";
parameter DELAY_ADJUSTMENT_MODE_RELATIVE = "FIXED";
parameter SHIFTREG_DIV_MODE = 1'b0;
parameter FDA_FEEDBACK = 4'b0000;
parameter FDA_RELATIVE = 4'b0000;
parameter PLLOUT_SELECT = "GENCLK";
parameter DIVR = 4'b0000;
parameter DIVF = 7'b0000000;
parameter DIVQ = 3'b000;
parameter FILTER_RANGE = 3'b000;
parameter ENABLE_ICEGATE = 1'b0;
parameter TEST_MODE = 1'b0;
parameter EXTERNAL_DIVIDE_FACTOR = 1;
endmodule
(* blackbox *)
module SB_PLL40_2_PAD (
input PACKAGEPIN,
output PLLOUTCOREA,
output PLLOUTGLOBALA,
output PLLOUTCOREB,
output PLLOUTGLOBALB,
input EXTFEEDBACK,
input [7:0] DYNAMICDELAY,
output LOCK,
input BYPASS,
input RESETB,
input LATCHINPUTVALUE,
output SDO,
input SDI,
input SCLK
);
parameter FEEDBACK_PATH = "SIMPLE";
parameter DELAY_ADJUSTMENT_MODE_FEEDBACK = "FIXED";
parameter DELAY_ADJUSTMENT_MODE_RELATIVE = "FIXED";
parameter SHIFTREG_DIV_MODE = 1'b0;
parameter FDA_FEEDBACK = 4'b0000;
parameter FDA_RELATIVE = 4'b0000;
parameter PLLOUT_SELECT_PORTB = "GENCLK";
parameter DIVR = 4'b0000;
parameter DIVF = 7'b0000000;
parameter DIVQ = 3'b000;
parameter FILTER_RANGE = 3'b000;
parameter ENABLE_ICEGATE_PORTA = 1'b0;
parameter ENABLE_ICEGATE_PORTB = 1'b0;
parameter TEST_MODE = 1'b0;
parameter EXTERNAL_DIVIDE_FACTOR = 1;
endmodule
(* blackbox *)
module SB_PLL40_2F_CORE (
input REFERENCECLK,
output PLLOUTCOREA,
output PLLOUTGLOBALA,
output PLLOUTCOREB,
output PLLOUTGLOBALB,
input EXTFEEDBACK,
input [7:0] DYNAMICDELAY,
output LOCK,
input BYPASS,
input RESETB,
input LATCHINPUTVALUE,
output SDO,
input SDI,
input SCLK
);
parameter FEEDBACK_PATH = "SIMPLE";
parameter DELAY_ADJUSTMENT_MODE_FEEDBACK = "FIXED";
parameter DELAY_ADJUSTMENT_MODE_RELATIVE = "FIXED";
parameter SHIFTREG_DIV_MODE = 1'b0;
parameter FDA_FEEDBACK = 4'b0000;
parameter FDA_RELATIVE = 4'b0000;
parameter PLLOUT_SELECT_PORTA = "GENCLK";
parameter PLLOUT_SELECT_PORTB = "GENCLK";
parameter DIVR = 4'b0000;
parameter DIVF = 7'b0000000;
parameter DIVQ = 3'b000;
parameter FILTER_RANGE = 3'b000;
parameter ENABLE_ICEGATE_PORTA = 1'b0;
parameter ENABLE_ICEGATE_PORTB = 1'b0;
parameter TEST_MODE = 1'b0;
parameter EXTERNAL_DIVIDE_FACTOR = 1;
endmodule
(* blackbox *)
module SB_PLL40_2F_PAD (
input PACKAGEPIN,
output PLLOUTCOREA,
output PLLOUTGLOBALA,
output PLLOUTCOREB,
output PLLOUTGLOBALB,
input EXTFEEDBACK,
input [7:0] DYNAMICDELAY,
output LOCK,
input BYPASS,
input RESETB,
input LATCHINPUTVALUE,
output SDO,
input SDI,
input SCLK
);
parameter FEEDBACK_PATH = "SIMPLE";
parameter DELAY_ADJUSTMENT_MODE_FEEDBACK = "FIXED";
parameter DELAY_ADJUSTMENT_MODE_RELATIVE = "FIXED";
parameter SHIFTREG_DIV_MODE = 2'b00;
parameter FDA_FEEDBACK = 4'b0000;
parameter FDA_RELATIVE = 4'b0000;
parameter PLLOUT_SELECT_PORTA = "GENCLK";
parameter PLLOUT_SELECT_PORTB = "GENCLK";
parameter DIVR = 4'b0000;
parameter DIVF = 7'b0000000;
parameter DIVQ = 3'b000;
parameter FILTER_RANGE = 3'b000;
parameter ENABLE_ICEGATE_PORTA = 1'b0;
parameter ENABLE_ICEGATE_PORTB = 1'b0;
parameter TEST_MODE = 1'b0;
parameter EXTERNAL_DIVIDE_FACTOR = 1;
endmodule
// SiliconBlue Device Configuration Cells
(* blackbox, keep *)
module SB_WARMBOOT (
input BOOT,
input S1,
input S0
);
endmodule
module SB_SPRAM256KA (
input [13:0] ADDRESS,
input [15:0] DATAIN,
input [3:0] MASKWREN,
input WREN, CHIPSELECT, CLOCK, STANDBY, SLEEP, POWEROFF,
output reg [15:0] DATAOUT
);
`ifndef BLACKBOX
`ifndef EQUIV
reg [15:0] mem [0:16383];
wire off = SLEEP || !POWEROFF;
integer i;
always @(negedge POWEROFF) begin
for (i = 0; i <= 16383; i = i+1)
mem[i] = 'bx;
end
always @(posedge CLOCK, posedge off) begin
if (off) begin
DATAOUT <= 0;
end else
if (CHIPSELECT && !STANDBY && !WREN) begin
DATAOUT <= mem[ADDRESS];
end else begin
if (CHIPSELECT && !STANDBY && WREN) begin
if (MASKWREN[0]) mem[ADDRESS][ 3: 0] = DATAIN[ 3: 0];
if (MASKWREN[1]) mem[ADDRESS][ 7: 4] = DATAIN[ 7: 4];
if (MASKWREN[2]) mem[ADDRESS][11: 8] = DATAIN[11: 8];
if (MASKWREN[3]) mem[ADDRESS][15:12] = DATAIN[15:12];
end
DATAOUT <= 'bx;
end
end
`endif
`endif
endmodule
(* blackbox *)
module SB_HFOSC(
input TRIM0,
input TRIM1,
input TRIM2,
input TRIM3,
input TRIM4,
input TRIM5,
input TRIM6,
input TRIM7,
input TRIM8,
input TRIM9,
input CLKHFPU,
input CLKHFEN,
output CLKHF
);
parameter TRIM_EN = "0b0";
parameter CLKHF_DIV = "0b00";
endmodule
(* blackbox *)
module SB_LFOSC(
input CLKLFPU,
input CLKLFEN,
output CLKLF
);
endmodule
(* blackbox *)
module SB_RGBA_DRV(
input CURREN,
input RGBLEDEN,
input RGB0PWM,
input RGB1PWM,
input RGB2PWM,
output RGB0,
output RGB1,
output RGB2
);
parameter CURRENT_MODE = "0b0";
parameter RGB0_CURRENT = "0b000000";
parameter RGB1_CURRENT = "0b000000";
parameter RGB2_CURRENT = "0b000000";
endmodule
(* blackbox *)
module SB_LED_DRV_CUR(
input EN,
output LEDPU
);
endmodule
(* blackbox *)
module SB_RGB_DRV(
input RGBLEDEN,
input RGB0PWM,
input RGB1PWM,
input RGB2PWM,
input RGBPU,
output RGB0,
output RGB1,
output RGB2
);
parameter CURRENT_MODE = "0b0";
parameter RGB0_CURRENT = "0b000000";
parameter RGB1_CURRENT = "0b000000";
parameter RGB2_CURRENT = "0b000000";
endmodule
(* blackbox *)
module SB_I2C(
input SBCLKI,
input SBRWI,
input SBSTBI,
input SBADRI7,
input SBADRI6,
input SBADRI5,
input SBADRI4,
input SBADRI3,
input SBADRI2,
input SBADRI1,
input SBADRI0,
input SBDATI7,
input SBDATI6,
input SBDATI5,
input SBDATI4,
input SBDATI3,
input SBDATI2,
input SBDATI1,
input SBDATI0,
input SCLI,
input SDAI,
output SBDATO7,
output SBDATO6,
output SBDATO5,
output SBDATO4,
output SBDATO3,
output SBDATO2,
output SBDATO1,
output SBDATO0,
output SBACKO,
output I2CIRQ,
output I2CWKUP,
output SCLO, //inout in the SB verilog library, but output in the VHDL and PDF libs and seemingly in the HW itself
output SCLOE,
output SDAO,
output SDAOE
);
parameter I2C_SLAVE_INIT_ADDR = "0b1111100001";
parameter BUS_ADDR74 = "0b0001";
endmodule
(* blackbox *)
module SB_SPI (
input SBCLKI,
input SBRWI,
input SBSTBI,
input SBADRI7,
input SBADRI6,
input SBADRI5,
input SBADRI4,
input SBADRI3,
input SBADRI2,
input SBADRI1,
input SBADRI0,
input SBDATI7,
input SBDATI6,
input SBDATI5,
input SBDATI4,
input SBDATI3,
input SBDATI2,
input SBDATI1,
input SBDATI0,
input MI,
input SI,
input SCKI,
input SCSNI,
output SBDATO7,
output SBDATO6,
output SBDATO5,
output SBDATO4,
output SBDATO3,
output SBDATO2,
output SBDATO1,
output SBDATO0,
output SBACKO,
output SPIIRQ,
output SPIWKUP,
output SO,
output SOE,
output MO,
output MOE,
output SCKO, //inout in the SB verilog library, but output in the VHDL and PDF libs and seemingly in the HW itself
output SCKOE,
output MCSNO3,
output MCSNO2,
output MCSNO1,
output MCSNO0,
output MCSNOE3,
output MCSNOE2,
output MCSNOE1,
output MCSNOE0
);
parameter BUS_ADDR74 = "0b0000";
endmodule
(* blackbox *)
module SB_LEDDA_IP(
input LEDDCS,
input LEDDCLK,
input LEDDDAT7,
input LEDDDAT6,
input LEDDDAT5,
input LEDDDAT4,
input LEDDDAT3,
input LEDDDAT2,
input LEDDDAT1,
input LEDDDAT0,
input LEDDADDR3,
input LEDDADDR2,
input LEDDADDR1,
input LEDDADDR0,
input LEDDDEN,
input LEDDEXE,
input LEDDRST,
output PWMOUT0,
output PWMOUT1,
output PWMOUT2,
output LEDDON
);
endmodule
(* blackbox *)
module SB_FILTER_50NS(
input FILTERIN,
output FILTEROUT
);
endmodule
module SB_IO_I3C (
inout PACKAGE_PIN,
input LATCH_INPUT_VALUE,
input CLOCK_ENABLE,
input INPUT_CLK,
input OUTPUT_CLK,
input OUTPUT_ENABLE,
input D_OUT_0,
input D_OUT_1,
output D_IN_0,
output D_IN_1,
input PU_ENB,
input WEAK_PU_ENB
);
parameter [5:0] PIN_TYPE = 6'b000000;
parameter [0:0] PULLUP = 1'b0;
parameter [0:0] WEAK_PULLUP = 1'b0;
parameter [0:0] NEG_TRIGGER = 1'b0;
parameter IO_STANDARD = "SB_LVCMOS";
`ifndef BLACKBOX
reg dout, din_0, din_1;
reg din_q_0, din_q_1;
reg dout_q_0, dout_q_1;
reg outena_q;
generate if (!NEG_TRIGGER) begin
always @(posedge INPUT_CLK) if (CLOCK_ENABLE) din_q_0 <= PACKAGE_PIN;
always @(negedge INPUT_CLK) if (CLOCK_ENABLE) din_q_1 <= PACKAGE_PIN;
always @(posedge OUTPUT_CLK) if (CLOCK_ENABLE) dout_q_0 <= D_OUT_0;
always @(negedge OUTPUT_CLK) if (CLOCK_ENABLE) dout_q_1 <= D_OUT_1;
always @(posedge OUTPUT_CLK) if (CLOCK_ENABLE) outena_q <= OUTPUT_ENABLE;
end else begin
always @(negedge INPUT_CLK) if (CLOCK_ENABLE) din_q_0 <= PACKAGE_PIN;
always @(posedge INPUT_CLK) if (CLOCK_ENABLE) din_q_1 <= PACKAGE_PIN;
always @(negedge OUTPUT_CLK) if (CLOCK_ENABLE) dout_q_0 <= D_OUT_0;
always @(posedge OUTPUT_CLK) if (CLOCK_ENABLE) dout_q_1 <= D_OUT_1;
always @(negedge OUTPUT_CLK) if (CLOCK_ENABLE) outena_q <= OUTPUT_ENABLE;
end endgenerate
always @* begin
if (!PIN_TYPE[1] || !LATCH_INPUT_VALUE)
din_0 = PIN_TYPE[0] ? PACKAGE_PIN : din_q_0;
din_1 = din_q_1;
end
// work around simulation glitches on dout in DDR mode
reg outclk_delayed_1;
reg outclk_delayed_2;
always @* outclk_delayed_1 <= OUTPUT_CLK;
always @* outclk_delayed_2 <= outclk_delayed_1;
always @* begin
if (PIN_TYPE[3])
dout = PIN_TYPE[2] ? !dout_q_0 : D_OUT_0;
else
dout = (outclk_delayed_2 ^ NEG_TRIGGER) || PIN_TYPE[2] ? dout_q_0 : dout_q_1;
end
assign D_IN_0 = din_0, D_IN_1 = din_1;
generate
if (PIN_TYPE[5:4] == 2'b01) assign PACKAGE_PIN = dout;
if (PIN_TYPE[5:4] == 2'b10) assign PACKAGE_PIN = OUTPUT_ENABLE ? dout : 1'bz;
if (PIN_TYPE[5:4] == 2'b11) assign PACKAGE_PIN = outena_q ? dout : 1'bz;
endgenerate
`endif
endmodule
module SB_IO_OD (
inout PACKAGEPIN,
input LATCHINPUTVALUE,
input CLOCKENABLE,
input INPUTCLK,
input OUTPUTCLK,
input OUTPUTENABLE,
input DOUT1,
input DOUT0,
output DIN1,
output DIN0
);
parameter [5:0] PIN_TYPE = 6'b000000;
parameter [0:0] NEG_TRIGGER = 1'b0;
`ifndef BLACKBOX
reg dout, din_0, din_1;
reg din_q_0, din_q_1;
reg dout_q_0, dout_q_1;
reg outena_q;
generate if (!NEG_TRIGGER) begin
always @(posedge INPUTCLK) if (CLOCKENABLE) din_q_0 <= PACKAGEPIN;
always @(negedge INPUTCLK) if (CLOCKENABLE) din_q_1 <= PACKAGEPIN;
always @(posedge OUTPUTCLK) if (CLOCKENABLE) dout_q_0 <= DOUT0;
always @(negedge OUTPUTCLK) if (CLOCKENABLE) dout_q_1 <= DOUT1;
always @(posedge OUTPUTCLK) if (CLOCKENABLE) outena_q <= OUTPUTENABLE;
end else begin
always @(negedge INPUTCLK) if (CLOCKENABLE) din_q_0 <= PACKAGEPIN;
always @(posedge INPUTCLK) if (CLOCKENABLE) din_q_1 <= PACKAGEPIN;
always @(negedge OUTPUTCLK) if (CLOCKENABLE) dout_q_0 <= DOUT0;
always @(posedge OUTPUTCLK) if (CLOCKENABLE) dout_q_1 <= DOUT1;
always @(negedge OUTPUTCLK) if (CLOCKENABLE) outena_q <= OUTPUTENABLE;
end endgenerate
always @* begin
if (!PIN_TYPE[1] || !LATCHINPUTVALUE)
din_0 = PIN_TYPE[0] ? PACKAGEPIN : din_q_0;
din_1 = din_q_1;
end
// work around simulation glitches on dout in DDR mode
reg outclk_delayed_1;
reg outclk_delayed_2;
always @* outclk_delayed_1 <= OUTPUTCLK;
always @* outclk_delayed_2 <= outclk_delayed_1;
always @* begin
if (PIN_TYPE[3])
dout = PIN_TYPE[2] ? !dout_q_0 : DOUT0;
else
dout = (outclk_delayed_2 ^ NEG_TRIGGER) || PIN_TYPE[2] ? dout_q_0 : dout_q_1;
end
assign DIN0 = din_0, DIN1 = din_1;
generate
if (PIN_TYPE[5:4] == 2'b01) assign PACKAGEPIN = dout ? 1'bz : 1'b0;
if (PIN_TYPE[5:4] == 2'b10) assign PACKAGEPIN = OUTPUTENABLE ? (dout ? 1'bz : 1'b0) : 1'bz;
if (PIN_TYPE[5:4] == 2'b11) assign PACKAGEPIN = outena_q ? (dout ? 1'bz : 1'b0) : 1'bz;
endgenerate
`endif
endmodule
module SB_MAC16 (
input CLK, CE,
input [15:0] C, A, B, D,
input AHOLD, BHOLD, CHOLD, DHOLD,
input IRSTTOP, IRSTBOT,
input ORSTTOP, ORSTBOT,
input OLOADTOP, OLOADBOT,
input ADDSUBTOP, ADDSUBBOT,
input OHOLDTOP, OHOLDBOT,
input CI, ACCUMCI, SIGNEXTIN,
output [31:0] O,
output CO, ACCUMCO, SIGNEXTOUT
);
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 = 0;
parameter [1:0] TOPADDSUB_CARRYSELECT = 0;
parameter [1:0] BOTOUTPUT_SELECT = 0;
parameter [1:0] BOTADDSUB_LOWERINPUT = 0;
parameter [0:0] BOTADDSUB_UPPERINPUT = 0;
parameter [1:0] BOTADDSUB_CARRYSELECT = 0;
parameter [0:0] MODE_8x8 = 0;
parameter [0:0] A_SIGNED = 0;
parameter [0:0] B_SIGNED = 0;
wire clock = CLK ^ NEG_TRIGGER;
// internal wires, compare Figure on page 133 of ICE Technology Library 3.0 and Fig 2 on page 2 of Lattice TN1295-DSP
// http://www.latticesemi.com/~/media/LatticeSemi/Documents/TechnicalBriefs/SBTICETechnologyLibrary201608.pdf
// https://www.latticesemi.com/-/media/LatticeSemi/Documents/ApplicationNotes/AD/DSPFunctionUsageGuideforICE40Devices.ashx
wire [15:0] iA, iB, iC, iD;
wire [15:0] iF, iJ, iK, iG;
wire [31:0] iL, iH;
wire [15:0] iW, iX, iP, iQ;
wire [15:0] iY, iZ, iR, iS;
wire HCI, LCI, LCO;
// Regs C and A
reg [15:0] rC, rA;
always @(posedge clock, posedge IRSTTOP) begin
if (IRSTTOP) begin
rC <= 0;
rA <= 0;
end else if (CE) begin
if (!CHOLD) rC <= C;
if (!AHOLD) rA <= A;
end
end
assign iC = C_REG ? rC : C;
assign iA = A_REG ? rA : A;
// Regs B and D
reg [15:0] rB, rD;
always @(posedge clock, posedge IRSTBOT) begin
if (IRSTBOT) begin
rB <= 0;
rD <= 0;
end else if (CE) begin
if (!BHOLD) rB <= B;
if (!DHOLD) rD <= D;
end
end
assign iB = B_REG ? rB : B;
assign iD = D_REG ? rD : D;
// 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]}} : 8'b0, iA[15: 8]};
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 && 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;
always @(posedge clock, posedge IRSTTOP) begin
if (IRSTTOP) begin
rF <= 0;
rJ <= 0;
end else if (CE) begin
rF <= p_Ah_Bh;
if (!MODE_8x8) rJ <= p_Al_Bh;
end
end
assign iF = TOP_8x8_MULT_REG ? rF : p_Ah_Bh;
assign iJ = PIPELINE_16x16_MULT_REG1 ? rJ : p_Al_Bh;
// Regs K and G
reg [15:0] rK, rG;
always @(posedge clock, posedge IRSTBOT) begin
if (IRSTBOT) begin
rK <= 0;
rG <= 0;
end else if (CE) begin
if (!MODE_8x8) rK <= p_Ah_Bl;
rG <= p_Al_Bl;
end
end
assign iK = PIPELINE_16x16_MULT_REG1 ? rK : p_Ah_Bl;
assign iG = BOT_8x8_MULT_REG ? rG : p_Al_Bl;
// Adder Stage
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;
always @(posedge clock, posedge IRSTBOT) begin
if (IRSTBOT) begin
rH <= 0;
end else if (CE) begin
if (!MODE_8x8) rH <= iL;
end
end
assign iH = PIPELINE_16x16_MULT_REG2 ? rH : iL;
// Hi Output Stage
wire [15:0] XW, Oh;
reg [15:0] rQ;
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;
assign iP = OLOADTOP ? iC : XW ^ {16{ADDSUBTOP}};
always @(posedge clock, posedge ORSTTOP) begin
if (ORSTTOP) begin
rQ <= 0;
end else if (CE) begin
if (!OHOLDTOP) rQ <= iP;
end
end
assign iQ = rQ;
assign Oh = (TOPOUTPUT_SELECT == 0) ? iP : (TOPOUTPUT_SELECT == 1) ? iQ : (TOPOUTPUT_SELECT == 2) ? iF : iH[31:16];
assign HCI = (TOPADDSUB_CARRYSELECT == 0) ? 1'b0 : (TOPADDSUB_CARRYSELECT == 1) ? 1'b1 : (TOPADDSUB_CARRYSELECT == 2) ? LCO : LCO ^ ADDSUBBOT;
assign SIGNEXTOUT = iX[15];
// Lo Output Stage
wire [15:0] YZ, Ol;
reg [15:0] rS;
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}};
always @(posedge clock, posedge ORSTBOT) begin
if (ORSTBOT) begin
rS <= 0;
end else if (CE) begin
if (!OHOLDBOT) rS <= iR;
end
end
assign iS = rS;
assign Ol = (BOTOUTPUT_SELECT == 0) ? iR : (BOTOUTPUT_SELECT == 1) ? iS : (BOTOUTPUT_SELECT == 2) ? iG : iH[15:0];
assign LCI = (BOTADDSUB_CARRYSELECT == 0) ? 1'b0 : (BOTADDSUB_CARRYSELECT == 1) ? 1'b1 : (BOTADDSUB_CARRYSELECT == 2) ? ACCUMCI : CI;
assign O = {Oh, Ol};
endmodule