2019-10-20 04:24:47 -05:00
|
|
|
`timescale 1ps / 1ps
|
2018-05-17 06:54:40 -05:00
|
|
|
`define SB_DFF_REG reg Q = 0
|
|
|
|
// `define SB_DFF_REG reg Q
|
2015-07-20 06:05:18 -05:00
|
|
|
|
2019-10-04 13:04:10 -05:00
|
|
|
`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
|
2019-08-28 19:21:37 -05:00
|
|
|
|
2015-04-14 06:44:43 -05:00
|
|
|
// 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;
|
2015-07-02 04:14:30 -05:00
|
|
|
parameter [0:0] NEG_TRIGGER = 1'b0;
|
2015-04-14 06:44:43 -05:00
|
|
|
parameter IO_STANDARD = "SB_LVCMOS";
|
|
|
|
|
2015-07-18 04:59:04 -05:00
|
|
|
`ifndef BLACKBOX
|
2015-05-23 03:17:03 -05:00
|
|
|
reg dout, din_0, din_1;
|
|
|
|
reg din_q_0, din_q_1;
|
|
|
|
reg dout_q_0, dout_q_1;
|
2015-05-23 02:30:24 -05:00
|
|
|
reg outena_q;
|
|
|
|
|
2019-04-17 16:56:41 -05:00
|
|
|
// 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;
|
|
|
|
|
2015-05-23 02:30:24 -05:00
|
|
|
generate if (!NEG_TRIGGER) begin
|
2019-04-17 16:56:41 -05:00
|
|
|
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;
|
2015-05-23 02:30:24 -05:00
|
|
|
end else begin
|
2019-04-17 16:56:41 -05:00
|
|
|
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;
|
2015-05-23 02:30:24 -05:00
|
|
|
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
|
|
|
|
|
2016-02-07 04:19:48 -06:00
|
|
|
// 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;
|
|
|
|
|
2015-05-23 02:30:24 -05:00
|
|
|
always @* begin
|
|
|
|
if (PIN_TYPE[3])
|
|
|
|
dout = PIN_TYPE[2] ? !dout_q_0 : D_OUT_0;
|
|
|
|
else
|
2016-02-07 04:19:48 -06:00
|
|
|
dout = (outclk_delayed_2 ^ NEG_TRIGGER) || PIN_TYPE[2] ? dout_q_0 : dout_q_1;
|
2015-05-23 02:30:24 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
assign D_IN_0 = din_0, D_IN_1 = din_1;
|
2015-05-23 03:17:03 -05:00
|
|
|
|
|
|
|
generate
|
|
|
|
if (PIN_TYPE[5:4] == 2'b01) assign PACKAGE_PIN = dout;
|
2015-11-06 10:02:16 -06:00
|
|
|
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;
|
2015-05-23 03:17:03 -05:00
|
|
|
endgenerate
|
2015-07-18 04:59:04 -05:00
|
|
|
`endif
|
2019-10-20 04:24:47 -05:00
|
|
|
`ifdef TIMING
|
|
|
|
specify
|
|
|
|
(INPUT_CLK => D_IN_0) = (0:0:0, 0:0:0);
|
|
|
|
(INPUT_CLK => D_IN_1) = (0:0:0, 0:0:0);
|
|
|
|
(PACKAGE_PIN => D_IN_0) = (0:0:0, 0:0:0);
|
|
|
|
(OUTPUT_CLK => PACKAGE_PIN) = (0:0:0, 0:0:0);
|
|
|
|
(D_OUT_0 => PACKAGE_PIN) = (0:0:0, 0:0:0);
|
|
|
|
(OUTPUT_ENABLE => PACKAGE_PIN) = (0:0:0, 0:0:0);
|
|
|
|
|
|
|
|
$setuphold(posedge OUTPUT_CLK, posedge D_OUT_0, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(posedge OUTPUT_CLK, negedge D_OUT_0, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(negedge OUTPUT_CLK, posedge D_OUT_1, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(negedge OUTPUT_CLK, negedge D_OUT_1, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(negedge OUTPUT_CLK, posedge D_OUT_0, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(negedge OUTPUT_CLK, negedge D_OUT_0, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(posedge OUTPUT_CLK, posedge D_OUT_1, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(posedge OUTPUT_CLK, negedge D_OUT_1, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(posedge INPUT_CLK, posedge CLOCK_ENABLE, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(posedge INPUT_CLK, negedge CLOCK_ENABLE, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(posedge OUTPUT_CLK, posedge CLOCK_ENABLE, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(posedge OUTPUT_CLK, negedge CLOCK_ENABLE, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(posedge INPUT_CLK, posedge PACKAGE_PIN, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(posedge INPUT_CLK, negedge PACKAGE_PIN, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(negedge INPUT_CLK, posedge PACKAGE_PIN, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(negedge INPUT_CLK, negedge PACKAGE_PIN, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(posedge OUTPUT_CLK, posedge OUTPUT_ENABLE, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(posedge OUTPUT_CLK, negedge OUTPUT_ENABLE, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(negedge OUTPUT_CLK, posedge OUTPUT_ENABLE, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(negedge OUTPUT_CLK, negedge OUTPUT_ENABLE, 0:0:0, 0:0:0);
|
|
|
|
endspecify
|
|
|
|
`endif
|
2015-04-14 06:44:43 -05:00
|
|
|
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;
|
2015-07-02 04:14:30 -05:00
|
|
|
parameter [0:0] NEG_TRIGGER = 1'b0;
|
2015-04-14 06:44:43 -05:00
|
|
|
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;
|
2019-10-20 04:24:47 -05:00
|
|
|
`ifdef TIMING
|
|
|
|
specify
|
|
|
|
(USER_SIGNAL_TO_GLOBAL_BUFFER => GLOBAL_BUFFER_OUTPUT) = (0:0:0, 0:0:0);
|
|
|
|
endspecify
|
|
|
|
`endif
|
2015-03-05 13:37:55 -06:00
|
|
|
endmodule
|
|
|
|
|
2015-04-14 06:44:43 -05:00
|
|
|
// SiliconBlue Logic Cells
|
|
|
|
|
2019-07-12 02:52:19 -05:00
|
|
|
(* lib_whitebox *)
|
2015-04-14 06:44:43 -05:00
|
|
|
module SB_LUT4 (output O, input I0, I1, I2, I3);
|
2015-04-16 04:30:56 -05:00
|
|
|
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];
|
2015-04-14 06:44:43 -05:00
|
|
|
assign O = I0 ? s1[1] : s1[0];
|
|
|
|
endmodule
|
|
|
|
|
2019-07-12 02:52:19 -05:00
|
|
|
(* lib_whitebox *)
|
2019-06-27 18:07:14 -05:00
|
|
|
module SB_CARRY (output CO, input I0, I1, CI);
|
2015-04-14 06:44:43 -05:00
|
|
|
assign CO = (I0 && I1) || ((I0 || I1) && CI);
|
|
|
|
endmodule
|
|
|
|
|
2019-08-28 19:21:37 -05:00
|
|
|
// Max delay from: https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90
|
2019-08-28 20:56:25 -05:00
|
|
|
// https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90
|
2019-08-28 21:03:29 -05:00
|
|
|
// https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102
|
2019-08-28 19:21:37 -05:00
|
|
|
|
2015-04-14 06:44:43 -05:00
|
|
|
// Positive Edge SiliconBlue FF Cells
|
|
|
|
|
2019-08-28 19:21:37 -05:00
|
|
|
module SB_DFF (
|
2019-10-04 13:04:10 -05:00
|
|
|
`ABC9_ARRIVAL_HX(540)
|
|
|
|
`ABC9_ARRIVAL_LP(796)
|
|
|
|
`ABC9_ARRIVAL_U(1391)
|
2019-08-28 19:21:37 -05:00
|
|
|
output `SB_DFF_REG,
|
|
|
|
input C, D
|
|
|
|
);
|
2015-04-14 06:44:43 -05:00
|
|
|
always @(posedge C)
|
|
|
|
Q <= D;
|
|
|
|
endmodule
|
|
|
|
|
2019-08-28 19:21:37 -05:00
|
|
|
module SB_DFFE (
|
2019-10-04 13:04:10 -05:00
|
|
|
`ABC9_ARRIVAL_HX(540)
|
|
|
|
`ABC9_ARRIVAL_LP(796)
|
|
|
|
`ABC9_ARRIVAL_U(1391)
|
2019-08-28 19:21:37 -05:00
|
|
|
output `SB_DFF_REG,
|
|
|
|
input C, E, D
|
|
|
|
);
|
2015-04-14 06:44:43 -05:00
|
|
|
always @(posedge C)
|
|
|
|
if (E)
|
|
|
|
Q <= D;
|
|
|
|
endmodule
|
|
|
|
|
2019-08-28 19:21:37 -05:00
|
|
|
module SB_DFFSR (
|
2019-10-04 13:04:10 -05:00
|
|
|
`ABC9_ARRIVAL_HX(540)
|
|
|
|
`ABC9_ARRIVAL_LP(796)
|
|
|
|
`ABC9_ARRIVAL_U(1391)
|
2019-08-28 19:21:37 -05:00
|
|
|
output `SB_DFF_REG,
|
|
|
|
input C, R, D
|
|
|
|
);
|
2015-04-14 06:44:43 -05:00
|
|
|
always @(posedge C)
|
|
|
|
if (R)
|
|
|
|
Q <= 0;
|
|
|
|
else
|
|
|
|
Q <= D;
|
|
|
|
endmodule
|
|
|
|
|
2019-08-28 19:21:37 -05:00
|
|
|
module SB_DFFR (
|
2019-10-04 13:04:10 -05:00
|
|
|
`ABC9_ARRIVAL_HX(540)
|
|
|
|
`ABC9_ARRIVAL_LP(796)
|
|
|
|
`ABC9_ARRIVAL_U(1391)
|
2019-08-28 19:21:37 -05:00
|
|
|
output `SB_DFF_REG,
|
|
|
|
input C, R, D
|
|
|
|
);
|
2015-04-14 06:44:43 -05:00
|
|
|
always @(posedge C, posedge R)
|
|
|
|
if (R)
|
|
|
|
Q <= 0;
|
|
|
|
else
|
|
|
|
Q <= D;
|
|
|
|
endmodule
|
|
|
|
|
2019-08-28 19:21:37 -05:00
|
|
|
module SB_DFFSS (
|
2019-10-04 13:04:10 -05:00
|
|
|
`ABC9_ARRIVAL_HX(540)
|
|
|
|
`ABC9_ARRIVAL_LP(796)
|
|
|
|
`ABC9_ARRIVAL_U(1391)
|
2019-08-28 19:21:37 -05:00
|
|
|
output `SB_DFF_REG,
|
|
|
|
input C, S, D
|
|
|
|
);
|
2015-04-14 06:44:43 -05:00
|
|
|
always @(posedge C)
|
|
|
|
if (S)
|
|
|
|
Q <= 1;
|
|
|
|
else
|
|
|
|
Q <= D;
|
|
|
|
endmodule
|
|
|
|
|
2019-08-28 19:21:37 -05:00
|
|
|
module SB_DFFS (
|
2019-10-04 13:04:10 -05:00
|
|
|
`ABC9_ARRIVAL_HX(540)
|
|
|
|
`ABC9_ARRIVAL_LP(796)
|
|
|
|
`ABC9_ARRIVAL_U(1391)
|
2019-08-28 19:21:37 -05:00
|
|
|
output `SB_DFF_REG,
|
|
|
|
input C, S, D
|
|
|
|
);
|
2015-04-14 06:44:43 -05:00
|
|
|
always @(posedge C, posedge S)
|
|
|
|
if (S)
|
|
|
|
Q <= 1;
|
|
|
|
else
|
|
|
|
Q <= D;
|
|
|
|
endmodule
|
|
|
|
|
2019-08-28 19:21:37 -05:00
|
|
|
module SB_DFFESR (
|
2019-10-04 13:04:10 -05:00
|
|
|
`ABC9_ARRIVAL_HX(540)
|
|
|
|
`ABC9_ARRIVAL_LP(796)
|
|
|
|
`ABC9_ARRIVAL_U(1391)
|
2019-08-28 19:21:37 -05:00
|
|
|
output `SB_DFF_REG,
|
|
|
|
input C, E, R, D
|
|
|
|
);
|
2015-04-14 06:44:43 -05:00
|
|
|
always @(posedge C)
|
|
|
|
if (E) begin
|
|
|
|
if (R)
|
|
|
|
Q <= 0;
|
|
|
|
else
|
|
|
|
Q <= D;
|
|
|
|
end
|
|
|
|
endmodule
|
|
|
|
|
2019-08-28 19:21:37 -05:00
|
|
|
module SB_DFFER (
|
2019-10-04 13:04:10 -05:00
|
|
|
`ABC9_ARRIVAL_HX(540)
|
|
|
|
`ABC9_ARRIVAL_LP(796)
|
|
|
|
`ABC9_ARRIVAL_U(1391)
|
2019-08-28 19:21:37 -05:00
|
|
|
output `SB_DFF_REG,
|
|
|
|
input C, E, R, D
|
|
|
|
);
|
2015-04-14 06:44:43 -05:00
|
|
|
always @(posedge C, posedge R)
|
|
|
|
if (R)
|
|
|
|
Q <= 0;
|
|
|
|
else if (E)
|
|
|
|
Q <= D;
|
|
|
|
endmodule
|
|
|
|
|
2019-08-28 19:21:37 -05:00
|
|
|
module SB_DFFESS (
|
2019-10-04 13:04:10 -05:00
|
|
|
`ABC9_ARRIVAL_HX(540)
|
|
|
|
`ABC9_ARRIVAL_LP(796)
|
|
|
|
`ABC9_ARRIVAL_U(1391)
|
2019-08-28 19:21:37 -05:00
|
|
|
output `SB_DFF_REG,
|
|
|
|
input C, E, S, D
|
|
|
|
);
|
2015-04-14 06:44:43 -05:00
|
|
|
always @(posedge C)
|
|
|
|
if (E) begin
|
|
|
|
if (S)
|
|
|
|
Q <= 1;
|
|
|
|
else
|
|
|
|
Q <= D;
|
|
|
|
end
|
|
|
|
endmodule
|
|
|
|
|
2019-08-28 19:21:37 -05:00
|
|
|
module SB_DFFES (
|
2019-10-04 13:04:10 -05:00
|
|
|
`ABC9_ARRIVAL_HX(540)
|
|
|
|
`ABC9_ARRIVAL_LP(796)
|
|
|
|
`ABC9_ARRIVAL_U(1391)
|
2019-08-28 19:21:37 -05:00
|
|
|
output `SB_DFF_REG,
|
|
|
|
input C, E, S, D
|
|
|
|
);
|
2015-04-14 06:44:43 -05:00
|
|
|
always @(posedge C, posedge S)
|
|
|
|
if (S)
|
|
|
|
Q <= 1;
|
|
|
|
else if (E)
|
|
|
|
Q <= D;
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
// Negative Edge SiliconBlue FF Cells
|
|
|
|
|
2019-08-28 19:21:37 -05:00
|
|
|
module SB_DFFN (
|
2019-10-04 13:04:10 -05:00
|
|
|
`ABC9_ARRIVAL_HX(540)
|
|
|
|
`ABC9_ARRIVAL_LP(796)
|
|
|
|
`ABC9_ARRIVAL_U(1391)
|
2019-08-28 19:21:37 -05:00
|
|
|
output `SB_DFF_REG,
|
|
|
|
input C, D
|
|
|
|
);
|
2015-04-14 06:44:43 -05:00
|
|
|
always @(negedge C)
|
|
|
|
Q <= D;
|
|
|
|
endmodule
|
|
|
|
|
2019-08-28 19:21:37 -05:00
|
|
|
module SB_DFFNE (
|
2019-10-04 13:04:10 -05:00
|
|
|
`ABC9_ARRIVAL_HX(540)
|
|
|
|
`ABC9_ARRIVAL_LP(796)
|
|
|
|
`ABC9_ARRIVAL_U(1391)
|
2019-08-28 19:21:37 -05:00
|
|
|
output `SB_DFF_REG,
|
|
|
|
input C, E, D
|
|
|
|
);
|
2015-04-14 06:44:43 -05:00
|
|
|
always @(negedge C)
|
|
|
|
if (E)
|
|
|
|
Q <= D;
|
|
|
|
endmodule
|
|
|
|
|
2019-08-28 19:21:37 -05:00
|
|
|
module SB_DFFNSR (
|
2019-10-04 13:04:10 -05:00
|
|
|
`ABC9_ARRIVAL_HX(540)
|
|
|
|
`ABC9_ARRIVAL_LP(796)
|
|
|
|
`ABC9_ARRIVAL_U(1391)
|
2019-08-28 19:21:37 -05:00
|
|
|
output `SB_DFF_REG,
|
|
|
|
input C, R, D
|
|
|
|
);
|
2015-04-14 06:44:43 -05:00
|
|
|
always @(negedge C)
|
|
|
|
if (R)
|
|
|
|
Q <= 0;
|
|
|
|
else
|
|
|
|
Q <= D;
|
|
|
|
endmodule
|
|
|
|
|
2019-08-28 19:21:37 -05:00
|
|
|
module SB_DFFNR (
|
2019-10-04 13:04:10 -05:00
|
|
|
`ABC9_ARRIVAL_HX(540)
|
|
|
|
`ABC9_ARRIVAL_LP(796)
|
|
|
|
`ABC9_ARRIVAL_U(1391)
|
2019-08-28 19:21:37 -05:00
|
|
|
output `SB_DFF_REG,
|
|
|
|
input C, R, D
|
|
|
|
);
|
2015-04-14 06:44:43 -05:00
|
|
|
always @(negedge C, posedge R)
|
|
|
|
if (R)
|
|
|
|
Q <= 0;
|
|
|
|
else
|
|
|
|
Q <= D;
|
|
|
|
endmodule
|
|
|
|
|
2019-08-28 19:21:37 -05:00
|
|
|
module SB_DFFNSS (
|
2019-10-04 13:04:10 -05:00
|
|
|
`ABC9_ARRIVAL_HX(540)
|
|
|
|
`ABC9_ARRIVAL_LP(796)
|
|
|
|
`ABC9_ARRIVAL_U(1391)
|
2019-08-28 19:21:37 -05:00
|
|
|
output `SB_DFF_REG,
|
|
|
|
input C, S, D
|
|
|
|
);
|
2015-04-14 06:44:43 -05:00
|
|
|
always @(negedge C)
|
|
|
|
if (S)
|
|
|
|
Q <= 1;
|
|
|
|
else
|
|
|
|
Q <= D;
|
|
|
|
endmodule
|
|
|
|
|
2019-08-28 19:21:37 -05:00
|
|
|
module SB_DFFNS (
|
2019-10-04 13:04:10 -05:00
|
|
|
`ABC9_ARRIVAL_HX(540)
|
|
|
|
`ABC9_ARRIVAL_LP(796)
|
|
|
|
`ABC9_ARRIVAL_U(1391)
|
2019-08-28 19:21:37 -05:00
|
|
|
output `SB_DFF_REG,
|
|
|
|
input C, S, D
|
|
|
|
);
|
2015-04-14 06:44:43 -05:00
|
|
|
always @(negedge C, posedge S)
|
|
|
|
if (S)
|
|
|
|
Q <= 1;
|
|
|
|
else
|
|
|
|
Q <= D;
|
|
|
|
endmodule
|
|
|
|
|
2019-08-28 19:21:37 -05:00
|
|
|
module SB_DFFNESR (
|
2019-10-04 13:04:10 -05:00
|
|
|
`ABC9_ARRIVAL_HX(540)
|
|
|
|
`ABC9_ARRIVAL_LP(796)
|
|
|
|
`ABC9_ARRIVAL_U(1391)
|
2019-08-28 19:21:37 -05:00
|
|
|
output `SB_DFF_REG,
|
|
|
|
input C, E, R, D
|
|
|
|
);
|
2015-04-14 06:44:43 -05:00
|
|
|
always @(negedge C)
|
|
|
|
if (E) begin
|
|
|
|
if (R)
|
|
|
|
Q <= 0;
|
|
|
|
else
|
|
|
|
Q <= D;
|
|
|
|
end
|
|
|
|
endmodule
|
|
|
|
|
2019-08-28 19:21:37 -05:00
|
|
|
module SB_DFFNER (
|
2019-10-04 13:04:10 -05:00
|
|
|
`ABC9_ARRIVAL_HX(540)
|
|
|
|
`ABC9_ARRIVAL_LP(796)
|
|
|
|
`ABC9_ARRIVAL_U(1391)
|
2019-08-28 19:21:37 -05:00
|
|
|
output `SB_DFF_REG,
|
|
|
|
input C, E, R, D
|
|
|
|
);
|
2015-04-14 06:44:43 -05:00
|
|
|
always @(negedge C, posedge R)
|
|
|
|
if (R)
|
|
|
|
Q <= 0;
|
|
|
|
else if (E)
|
|
|
|
Q <= D;
|
|
|
|
endmodule
|
|
|
|
|
2019-08-28 19:21:37 -05:00
|
|
|
module SB_DFFNESS (
|
2019-10-04 13:04:10 -05:00
|
|
|
`ABC9_ARRIVAL_HX(540)
|
|
|
|
`ABC9_ARRIVAL_LP(796)
|
|
|
|
`ABC9_ARRIVAL_U(1391)
|
2019-08-28 19:21:37 -05:00
|
|
|
output `SB_DFF_REG,
|
|
|
|
input C, E, S, D
|
|
|
|
);
|
2015-04-14 06:44:43 -05:00
|
|
|
always @(negedge C)
|
|
|
|
if (E) begin
|
|
|
|
if (S)
|
|
|
|
Q <= 1;
|
|
|
|
else
|
|
|
|
Q <= D;
|
|
|
|
end
|
|
|
|
endmodule
|
|
|
|
|
2019-08-28 19:21:37 -05:00
|
|
|
module SB_DFFNES (
|
2019-10-04 13:04:10 -05:00
|
|
|
`ABC9_ARRIVAL_HX(540)
|
|
|
|
`ABC9_ARRIVAL_LP(796)
|
|
|
|
`ABC9_ARRIVAL_U(1391)
|
2019-08-28 19:21:37 -05:00
|
|
|
output `SB_DFF_REG,
|
|
|
|
input C, E, S, D
|
|
|
|
);
|
2015-04-14 06:44:43 -05:00
|
|
|
always @(negedge C, posedge S)
|
|
|
|
if (S)
|
|
|
|
Q <= 1;
|
|
|
|
else if (E)
|
|
|
|
Q <= D;
|
2015-03-05 13:37:55 -06:00
|
|
|
endmodule
|
2015-04-14 06:44:43 -05:00
|
|
|
|
2015-04-19 14:37:40 -05:00
|
|
|
// SiliconBlue RAM Cells
|
|
|
|
|
|
|
|
module SB_RAM40_4K (
|
2019-10-04 13:04:10 -05:00
|
|
|
`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
|
2019-06-14 12:37:52 -05:00
|
|
|
output [15:0] RDATA,
|
2015-04-25 11:04:57 -05:00
|
|
|
input RCLK, RCLKE, RE,
|
|
|
|
input [10:0] RADDR,
|
|
|
|
input WCLK, WCLKE, WE,
|
|
|
|
input [10:0] WADDR,
|
|
|
|
input [15:0] MASK, WDATA
|
2015-04-19 14:37:40 -05:00
|
|
|
);
|
|
|
|
// 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;
|
|
|
|
|
2019-03-07 16:48:10 -06:00
|
|
|
parameter INIT_FILE = "";
|
|
|
|
|
2015-04-19 14:37:40 -05:00
|
|
|
`ifndef BLACKBOX
|
2015-04-25 13:01:37 -05:00
|
|
|
wire [15:0] WMASK_I;
|
|
|
|
wire [15:0] RMASK_I;
|
|
|
|
|
2015-04-25 11:04:57 -05:00
|
|
|
reg [15:0] RDATA_I;
|
|
|
|
wire [15:0] WDATA_I;
|
|
|
|
|
|
|
|
generate
|
2015-04-25 13:01:37 -05:00
|
|
|
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
|
|
|
|
|
2015-04-25 11:04:57 -05:00
|
|
|
case (WRITE_MODE)
|
|
|
|
0: assign WDATA_I = WDATA;
|
2015-04-25 13:01:37 -05:00
|
|
|
|
|
|
|
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]};
|
2015-04-25 11:04:57 -05:00
|
|
|
endcase
|
2015-04-25 13:01:37 -05:00
|
|
|
|
2015-04-25 11:04:57 -05:00
|
|
|
case (READ_MODE)
|
|
|
|
0: assign RDATA = RDATA_I;
|
2015-04-25 13:01:37 -05:00
|
|
|
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};
|
2015-04-25 11:04:57 -05:00
|
|
|
endcase
|
|
|
|
endgenerate
|
|
|
|
|
2015-04-19 14:37:40 -05:00
|
|
|
integer i;
|
|
|
|
reg [15:0] memory [0:255];
|
|
|
|
|
|
|
|
initial begin
|
2019-03-07 16:48:10 -06:00
|
|
|
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
|
2015-04-19 14:37:40 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
always @(posedge WCLK) begin
|
|
|
|
if (WE && WCLKE) begin
|
2015-04-25 13:01:37 -05:00
|
|
|
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];
|
2015-04-19 14:37:40 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
always @(posedge RCLK) begin
|
|
|
|
if (RE && RCLKE) begin
|
2015-04-25 13:01:37 -05:00
|
|
|
RDATA_I <= memory[RADDR[7:0]] & ~RMASK_I;
|
2015-04-19 14:37:40 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
`endif
|
|
|
|
endmodule
|
2015-04-14 06:44:43 -05:00
|
|
|
|
2015-04-19 14:37:40 -05:00
|
|
|
module SB_RAM40_4KNR (
|
2019-10-04 13:04:10 -05:00
|
|
|
`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
|
2019-06-14 12:37:52 -05:00
|
|
|
output [15:0] RDATA,
|
2015-09-10 10:35:19 -05:00
|
|
|
input RCLKN, RCLKE, RE,
|
2015-04-19 14:37:40 -05:00
|
|
|
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;
|
|
|
|
|
2019-03-07 16:48:10 -06:00
|
|
|
parameter INIT_FILE = "";
|
|
|
|
|
2015-04-19 14:37:40 -05:00
|
|
|
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 ),
|
2019-03-07 16:48:10 -06:00
|
|
|
.INIT_F (INIT_F ),
|
|
|
|
.INIT_FILE (INIT_FILE )
|
2015-04-19 14:37:40 -05:00
|
|
|
) RAM (
|
|
|
|
.RDATA(RDATA),
|
2015-09-10 10:35:19 -05:00
|
|
|
.RCLK (~RCLKN),
|
2015-04-19 14:37:40 -05:00
|
|
|
.RCLKE(RCLKE),
|
|
|
|
.RE (RE ),
|
|
|
|
.RADDR(RADDR),
|
|
|
|
.WCLK (WCLK ),
|
|
|
|
.WCLKE(WCLKE),
|
|
|
|
.WE (WE ),
|
|
|
|
.WADDR(WADDR),
|
|
|
|
.MASK (MASK ),
|
|
|
|
.WDATA(WDATA)
|
|
|
|
);
|
2015-04-14 06:44:43 -05:00
|
|
|
endmodule
|
|
|
|
|
2015-04-19 14:37:40 -05:00
|
|
|
module SB_RAM40_4KNW (
|
2019-10-04 13:04:10 -05:00
|
|
|
`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
|
2019-06-14 12:37:52 -05:00
|
|
|
output [15:0] RDATA,
|
2015-04-19 14:37:40 -05:00
|
|
|
input RCLK, RCLKE, RE,
|
|
|
|
input [10:0] RADDR,
|
2015-09-10 10:35:19 -05:00
|
|
|
input WCLKN, WCLKE, WE,
|
2015-04-19 14:37:40 -05:00
|
|
|
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;
|
|
|
|
|
2019-03-07 16:48:10 -06:00
|
|
|
parameter INIT_FILE = "";
|
|
|
|
|
2015-04-19 14:37:40 -05:00
|
|
|
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 ),
|
2019-03-07 16:48:10 -06:00
|
|
|
.INIT_F (INIT_F ),
|
|
|
|
.INIT_FILE (INIT_FILE )
|
2015-04-19 14:37:40 -05:00
|
|
|
) RAM (
|
|
|
|
.RDATA(RDATA),
|
|
|
|
.RCLK (RCLK ),
|
|
|
|
.RCLKE(RCLKE),
|
|
|
|
.RE (RE ),
|
|
|
|
.RADDR(RADDR),
|
2015-09-10 10:35:19 -05:00
|
|
|
.WCLK (~WCLKN),
|
2015-04-19 14:37:40 -05:00
|
|
|
.WCLKE(WCLKE),
|
|
|
|
.WE (WE ),
|
|
|
|
.WADDR(WADDR),
|
|
|
|
.MASK (MASK ),
|
|
|
|
.WDATA(WDATA)
|
|
|
|
);
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
module SB_RAM40_4KNRNW (
|
2019-10-04 13:04:10 -05:00
|
|
|
`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
|
2019-06-14 12:37:52 -05:00
|
|
|
output [15:0] RDATA,
|
2015-09-10 10:35:19 -05:00
|
|
|
input RCLKN, RCLKE, RE,
|
2015-04-19 14:37:40 -05:00
|
|
|
input [10:0] RADDR,
|
2015-09-10 10:35:19 -05:00
|
|
|
input WCLKN, WCLKE, WE,
|
2015-04-19 14:37:40 -05:00
|
|
|
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;
|
|
|
|
|
2019-03-07 16:48:10 -06:00
|
|
|
parameter INIT_FILE = "";
|
|
|
|
|
2015-04-19 14:37:40 -05:00
|
|
|
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 ),
|
2019-03-07 16:48:10 -06:00
|
|
|
.INIT_F (INIT_F ),
|
|
|
|
.INIT_FILE (INIT_FILE )
|
2015-04-19 14:37:40 -05:00
|
|
|
) RAM (
|
|
|
|
.RDATA(RDATA),
|
2015-09-10 10:35:19 -05:00
|
|
|
.RCLK (~RCLKN),
|
2015-04-19 14:37:40 -05:00
|
|
|
.RCLKE(RCLKE),
|
|
|
|
.RE (RE ),
|
|
|
|
.RADDR(RADDR),
|
2015-09-10 10:35:19 -05:00
|
|
|
.WCLK (~WCLKN),
|
2015-04-19 14:37:40 -05:00
|
|
|
.WCLKE(WCLKE),
|
|
|
|
.WE (WE ),
|
|
|
|
.WADDR(WADDR),
|
|
|
|
.MASK (MASK ),
|
|
|
|
.WDATA(WDATA)
|
|
|
|
);
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
// Packed IceStorm Logic Cells
|
|
|
|
|
2015-04-14 06:44:43 -05:00
|
|
|
module ICESTORM_LC (
|
|
|
|
input I0, I1, I2, I3, CIN, CLK, CEN, SR,
|
2019-08-28 19:21:37 -05:00
|
|
|
output LO,
|
2019-10-04 13:04:10 -05:00
|
|
|
`ABC9_ARRIVAL_HX(540)
|
|
|
|
`ABC9_ARRIVAL_LP(796)
|
|
|
|
`ABC9_ARRIVAL_U(1391)
|
2019-08-28 19:21:37 -05:00
|
|
|
output O,
|
|
|
|
output COUT
|
2015-04-14 06:44:43 -05:00
|
|
|
);
|
|
|
|
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;
|
|
|
|
|
2018-07-13 06:09:18 -05:00
|
|
|
parameter [0:0] CIN_CONST = 0;
|
|
|
|
parameter [0:0] CIN_SET = 0;
|
|
|
|
|
2019-10-20 04:24:47 -05:00
|
|
|
wire I0_pd = (I0 === 1'bz) ? 1'b0 : I0;
|
|
|
|
wire I1_pd = (I1 === 1'bz) ? 1'b0 : I1;
|
|
|
|
wire I2_pd = (I2 === 1'bz) ? 1'b0 : I2;
|
|
|
|
wire I3_pd = (I3 === 1'bz) ? 1'b0 : I3;
|
|
|
|
wire SR_pd = (SR === 1'bz) ? 1'b0 : SR;
|
|
|
|
wire CEN_pu = (CEN === 1'bz) ? 1'b1 : CEN;
|
|
|
|
|
2018-07-13 06:09:18 -05:00
|
|
|
wire mux_cin = CIN_CONST ? CIN_SET : CIN;
|
|
|
|
|
2019-10-20 04:24:47 -05:00
|
|
|
assign COUT = CARRY_ENABLE ? (I1_pd && I2_pd) || ((I1_pd || I2_pd) && mux_cin) : 1'bx;
|
2015-04-14 06:44:43 -05:00
|
|
|
|
2019-10-20 04:24:47 -05:00
|
|
|
wire [7:0] lut_s3 = I3_pd ? LUT_INIT[15:8] : LUT_INIT[7:0];
|
|
|
|
wire [3:0] lut_s2 = I2_pd ? lut_s3[ 7:4] : lut_s3[3:0];
|
|
|
|
wire [1:0] lut_s1 = I1_pd ? lut_s2[ 3:2] : lut_s2[1:0];
|
|
|
|
wire lut_o = I0_pd ? lut_s1[ 1] : lut_s1[ 0];
|
2015-04-14 06:44:43 -05:00
|
|
|
|
2015-12-06 16:24:48 -06:00
|
|
|
assign LO = lut_o;
|
|
|
|
|
2015-04-14 06:44:43 -05:00
|
|
|
wire polarized_clk;
|
|
|
|
assign polarized_clk = CLK ^ NEG_CLK;
|
|
|
|
|
2019-10-20 04:24:47 -05:00
|
|
|
reg o_reg = 1'b0;
|
2015-04-14 06:44:43 -05:00
|
|
|
always @(posedge polarized_clk)
|
2019-10-20 04:24:47 -05:00
|
|
|
if (CEN_pu)
|
|
|
|
o_reg <= SR_pd ? SET_NORESET : lut_o;
|
2015-04-14 06:44:43 -05:00
|
|
|
|
2019-10-20 04:24:47 -05:00
|
|
|
reg o_reg_async = 1'b0;
|
2015-04-19 14:37:40 -05:00
|
|
|
always @(posedge polarized_clk, posedge SR)
|
2019-10-20 04:24:47 -05:00
|
|
|
if (SR_pd)
|
2015-04-14 06:44:43 -05:00
|
|
|
o_reg <= SET_NORESET;
|
2019-10-20 04:24:47 -05:00
|
|
|
else if (CEN_pu)
|
2015-04-14 06:44:43 -05:00
|
|
|
o_reg <= lut_o;
|
|
|
|
|
|
|
|
assign O = DFF_ENABLE ? ASYNC_SR ? o_reg_async : o_reg : lut_o;
|
2019-10-20 04:24:47 -05:00
|
|
|
`ifdef TIMING
|
|
|
|
specify
|
|
|
|
(I0 => O) = (0:0:0, 0:0:0);
|
|
|
|
(I1 => O) = (0:0:0, 0:0:0);
|
|
|
|
(I2 => O) = (0:0:0, 0:0:0);
|
|
|
|
(I3 => O) = (0:0:0, 0:0:0);
|
|
|
|
(I0 => LO) = (0:0:0, 0:0:0);
|
|
|
|
(I1 => LO) = (0:0:0, 0:0:0);
|
|
|
|
(I2 => LO) = (0:0:0, 0:0:0);
|
|
|
|
(I3 => LO) = (0:0:0, 0:0:0);
|
|
|
|
(I1 => COUT) = (0:0:0, 0:0:0);
|
|
|
|
(I2 => COUT) = (0:0:0, 0:0:0);
|
|
|
|
(CIN => COUT) = (0:0:0, 0:0:0);
|
|
|
|
(CLK => O) = (0:0:0, 0:0:0);
|
|
|
|
(SR => O) = (0:0:0, 0:0:0);
|
|
|
|
$setuphold(posedge CLK, posedge I0, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(posedge CLK, negedge I0, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(negedge CLK, posedge I0, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(negedge CLK, negedge I0, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(posedge CLK, posedge I1, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(posedge CLK, negedge I1, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(negedge CLK, posedge I1, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(negedge CLK, negedge I1, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(posedge CLK, posedge I2, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(posedge CLK, negedge I2, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(negedge CLK, posedge I2, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(negedge CLK, negedge I2, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(posedge CLK, posedge I3, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(posedge CLK, negedge I3, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(negedge CLK, posedge I3, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(negedge CLK, negedge I3, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(posedge CLK, posedge CEN, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(posedge CLK, negedge CEN, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(negedge CLK, posedge CEN, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(negedge CLK, negedge CEN, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(posedge CLK, posedge SR, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(posedge CLK, negedge SR, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(negedge CLK, posedge SR, 0:0:0, 0:0:0);
|
|
|
|
$setuphold(negedge CLK, negedge SR, 0:0:0, 0:0:0);
|
|
|
|
endspecify
|
|
|
|
`endif
|
2015-04-14 06:44:43 -05:00
|
|
|
endmodule
|
|
|
|
|
2015-05-31 06:10:43 -05:00
|
|
|
// 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
|
|
|
|
|
2015-08-06 15:58:17 -05:00
|
|
|
// SiliconBlue Device Configuration Cells
|
|
|
|
|
2015-08-12 07:10:14 -05:00
|
|
|
(* blackbox, keep *)
|
2015-08-06 15:58:17 -05:00
|
|
|
module SB_WARMBOOT (
|
|
|
|
input BOOT,
|
|
|
|
input S1,
|
|
|
|
input S0
|
|
|
|
);
|
|
|
|
endmodule
|
2017-11-16 06:24:35 -06:00
|
|
|
|
2018-09-10 04:57:24 -05:00
|
|
|
module SB_SPRAM256KA (
|
2017-11-16 06:24:35 -06:00
|
|
|
input [13:0] ADDRESS,
|
|
|
|
input [15:0] DATAIN,
|
|
|
|
input [3:0] MASKWREN,
|
2018-09-10 04:57:24 -05:00
|
|
|
input WREN, CHIPSELECT, CLOCK, STANDBY, SLEEP, POWEROFF,
|
2019-06-14 12:37:52 -05:00
|
|
|
output reg [15:0] DATAOUT
|
2017-11-16 06:24:35 -06:00
|
|
|
);
|
2018-09-10 04:57:24 -05:00
|
|
|
`ifndef BLACKBOX
|
2018-12-07 10:58:33 -06:00
|
|
|
`ifndef EQUIV
|
2018-09-10 04:57:24 -05:00
|
|
|
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
|
2018-12-07 10:58:33 -06:00
|
|
|
`endif
|
2017-11-16 06:24:35 -06:00
|
|
|
endmodule
|
|
|
|
|
2017-11-18 11:53:21 -06:00
|
|
|
(* blackbox *)
|
2017-11-16 06:24:35 -06:00
|
|
|
module SB_HFOSC(
|
2019-05-13 05:51:06 -05:00
|
|
|
input TRIM0,
|
|
|
|
input TRIM1,
|
|
|
|
input TRIM2,
|
|
|
|
input TRIM3,
|
|
|
|
input TRIM4,
|
|
|
|
input TRIM5,
|
|
|
|
input TRIM6,
|
|
|
|
input TRIM7,
|
|
|
|
input TRIM8,
|
|
|
|
input TRIM9,
|
2017-11-16 06:24:35 -06:00
|
|
|
input CLKHFPU,
|
|
|
|
input CLKHFEN,
|
|
|
|
output CLKHF
|
|
|
|
);
|
2019-05-13 05:51:06 -05:00
|
|
|
parameter TRIM_EN = "0b0";
|
2017-11-16 06:24:35 -06:00
|
|
|
parameter CLKHF_DIV = "0b00";
|
|
|
|
endmodule
|
|
|
|
|
2017-11-18 11:53:21 -06:00
|
|
|
(* blackbox *)
|
2017-11-16 06:24:35 -06:00
|
|
|
module SB_LFOSC(
|
|
|
|
input CLKLFPU,
|
|
|
|
input CLKLFEN,
|
|
|
|
output CLKLF
|
|
|
|
);
|
|
|
|
endmodule
|
|
|
|
|
2017-11-18 11:53:21 -06:00
|
|
|
(* blackbox *)
|
2017-11-16 06:24:35 -06:00
|
|
|
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
|
|
|
|
|
2019-06-10 04:49:08 -05:00
|
|
|
(* 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
|
|
|
|
|
2017-11-28 05:07:49 -06:00
|
|
|
(* 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,
|
2018-03-10 11:59:06 -06:00
|
|
|
input SBRWI,
|
2017-11-28 05:07:49 -06:00
|
|
|
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,
|
2018-03-10 11:59:06 -06:00
|
|
|
input PU_ENB,
|
2017-11-28 05:07:49 -06:00
|
|
|
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,
|
2017-12-09 15:39:20 -06:00
|
|
|
output DIN0
|
2017-11-28 05:07:49 -06:00
|
|
|
);
|
|
|
|
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
|
2017-12-09 15:49:07 -06:00
|
|
|
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;
|
2017-11-28 05:07:49 -06:00
|
|
|
end else begin
|
2017-12-09 15:49:07 -06:00
|
|
|
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;
|
2017-11-28 05:07:49 -06:00
|
|
|
end endgenerate
|
|
|
|
|
|
|
|
always @* begin
|
2017-12-09 15:49:07 -06:00
|
|
|
if (!PIN_TYPE[1] || !LATCHINPUTVALUE)
|
|
|
|
din_0 = PIN_TYPE[0] ? PACKAGEPIN : din_q_0;
|
2017-11-28 05:07:49 -06:00
|
|
|
din_1 = din_q_1;
|
|
|
|
end
|
|
|
|
|
|
|
|
// work around simulation glitches on dout in DDR mode
|
|
|
|
reg outclk_delayed_1;
|
|
|
|
reg outclk_delayed_2;
|
2017-12-09 15:49:07 -06:00
|
|
|
always @* outclk_delayed_1 <= OUTPUTCLK;
|
2017-11-28 05:07:49 -06:00
|
|
|
always @* outclk_delayed_2 <= outclk_delayed_1;
|
|
|
|
|
|
|
|
always @* begin
|
|
|
|
if (PIN_TYPE[3])
|
2017-12-09 15:49:07 -06:00
|
|
|
dout = PIN_TYPE[2] ? !dout_q_0 : DOUT0;
|
2017-11-28 05:07:49 -06:00
|
|
|
else
|
|
|
|
dout = (outclk_delayed_2 ^ NEG_TRIGGER) || PIN_TYPE[2] ? dout_q_0 : dout_q_1;
|
|
|
|
end
|
|
|
|
|
2017-12-09 15:49:07 -06:00
|
|
|
assign DIN0 = din_0, DIN1 = din_1;
|
2017-11-28 05:07:49 -06:00
|
|
|
|
|
|
|
generate
|
2017-12-09 15:49:07 -06:00
|
|
|
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;
|
2017-11-28 05:07:49 -06:00
|
|
|
endgenerate
|
|
|
|
`endif
|
|
|
|
endmodule
|
2019-02-19 06:42:21 -06:00
|
|
|
|
|
|
|
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;
|
2019-02-20 05:55:20 -06:00
|
|
|
always @(posedge clock, posedge IRSTBOT) begin
|
2019-02-19 06:42:21 -06:00
|
|
|
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;
|
2019-02-20 05:55:20 -06:00
|
|
|
assign Ah = {A_SIGNED ? {8{iA[15]}} : 8'b0, iA[15: 8]};
|
2019-07-19 11:13:34 -05:00
|
|
|
assign Al = {A_SIGNED && MODE_8x8 ? {8{iA[ 7]}} : 8'b0, iA[ 7: 0]};
|
2019-02-20 05:55:20 -06:00
|
|
|
assign Bh = {B_SIGNED ? {8{iB[15]}} : 8'b0, iB[15: 8]};
|
2019-07-19 11:13:34 -05:00
|
|
|
assign Bl = {B_SIGNED && MODE_8x8 ? {8{iB[ 7]}} : 8'b0, iB[ 7: 0]};
|
2019-07-19 11:33:41 -05:00
|
|
|
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
|
2019-02-19 06:42:21 -06:00
|
|
|
|
|
|
|
// 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
|
2019-07-19 11:33:41 -05:00
|
|
|
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);
|
2019-02-19 06:42:21 -06:00
|
|
|
|
|
|
|
// Reg H
|
2019-02-20 05:55:20 -06:00
|
|
|
reg [31:0] rH;
|
2019-02-19 06:42:21 -06:00
|
|
|
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;
|
2019-02-20 05:55:20 -06:00
|
|
|
assign iW = TOPADDSUB_UPPERINPUT ? iC : iQ;
|
2019-02-19 06:42:21 -06:00
|
|
|
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;
|
2019-02-20 05:55:20 -06:00
|
|
|
assign iY = BOTADDSUB_UPPERINPUT ? iD : iS;
|
2019-02-19 06:42:21 -06:00
|
|
|
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
|
2019-02-20 05:55:20 -06:00
|
|
|
if (!OHOLDBOT) rS <= iR;
|
2019-02-19 06:42:21 -06:00
|
|
|
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
|