mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-24 01:25:33 +00:00
Merge branch 'master' of https://github.com/YosysHQ/yosys into gowin
This commit is contained in:
commit
69fb3b8db2
275 changed files with 32888 additions and 2694 deletions
|
@ -1,5 +1,5 @@
|
|||
module AL_MAP_SEQ (
|
||||
output q,
|
||||
output reg q,
|
||||
input ce,
|
||||
input clk,
|
||||
input sr,
|
||||
|
@ -9,6 +9,71 @@ module AL_MAP_SEQ (
|
|||
parameter REGSET = "RESET"; //RESET/SET
|
||||
parameter SRMUX = "SR"; //SR/INV
|
||||
parameter SRMODE = "SYNC"; //SYNC/ASYNC
|
||||
|
||||
wire clk_ce;
|
||||
assign clk_ce = ce ? clk : 1'b0;
|
||||
|
||||
wire srmux;
|
||||
generate
|
||||
case (SRMUX)
|
||||
"SR": assign srmux = sr;
|
||||
"INV": assign srmux = ~sr;
|
||||
default: assign srmux = sr;
|
||||
endcase
|
||||
endgenerate
|
||||
|
||||
wire regset;
|
||||
generate
|
||||
case (REGSET)
|
||||
"RESET": assign regset = 1'b0;
|
||||
"SET": assign regset = 1'b1;
|
||||
default: assign regset = 1'b0;
|
||||
endcase
|
||||
endgenerate
|
||||
|
||||
initial q = regset;
|
||||
|
||||
generate
|
||||
if (DFFMODE == "FF")
|
||||
begin
|
||||
if (SRMODE == "ASYNC")
|
||||
begin
|
||||
always @(posedge clk_ce, posedge srmux)
|
||||
if (srmux)
|
||||
q <= regset;
|
||||
else
|
||||
q <= d;
|
||||
end
|
||||
else
|
||||
begin
|
||||
always @(posedge clk_ce)
|
||||
if (srmux)
|
||||
q <= regset;
|
||||
else
|
||||
q <= d;
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
// DFFMODE == "LATCH"
|
||||
if (SRMODE == "ASYNC")
|
||||
begin
|
||||
always @(clk_ce, srmux)
|
||||
if (srmux)
|
||||
q <= regset;
|
||||
else
|
||||
q <= d;
|
||||
end
|
||||
else
|
||||
begin
|
||||
always @(clk_ce)
|
||||
if (srmux)
|
||||
q <= regset;
|
||||
else
|
||||
q <= d;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
module AL_MAP_LUT1 (
|
||||
|
@ -17,7 +82,8 @@ module AL_MAP_LUT1 (
|
|||
);
|
||||
parameter [1:0] INIT = 2'h0;
|
||||
parameter EQN = "(A)";
|
||||
assign o = INIT >> a;
|
||||
|
||||
assign o = a ? INIT[1] : INIT[0];
|
||||
endmodule
|
||||
|
||||
module AL_MAP_LUT2 (
|
||||
|
@ -27,7 +93,9 @@ module AL_MAP_LUT2 (
|
|||
);
|
||||
parameter [3:0] INIT = 4'h0;
|
||||
parameter EQN = "(A)";
|
||||
assign o = INIT >> {b, a};
|
||||
|
||||
wire [1:0] s1 = b ? INIT[ 3:2] : INIT[1:0];
|
||||
assign o = a ? s1[1] : s1[0];
|
||||
endmodule
|
||||
|
||||
module AL_MAP_LUT3 (
|
||||
|
@ -38,7 +106,10 @@ module AL_MAP_LUT3 (
|
|||
);
|
||||
parameter [7:0] INIT = 8'h0;
|
||||
parameter EQN = "(A)";
|
||||
assign o = INIT >> {c, b, a};
|
||||
|
||||
wire [3:0] s2 = c ? INIT[ 7:4] : INIT[3:0];
|
||||
wire [1:0] s1 = b ? s2[ 3:2] : s2[1:0];
|
||||
assign o = a ? s1[1] : s1[0];
|
||||
endmodule
|
||||
|
||||
module AL_MAP_LUT4 (
|
||||
|
@ -50,7 +121,11 @@ module AL_MAP_LUT4 (
|
|||
);
|
||||
parameter [15:0] INIT = 16'h0;
|
||||
parameter EQN = "(A)";
|
||||
assign o = INIT >> {d, c, b, a};
|
||||
|
||||
wire [7:0] s3 = d ? INIT[15:8] : INIT[7:0];
|
||||
wire [3:0] s2 = c ? s3[ 7:4] : s3[3:0];
|
||||
wire [1:0] s1 = b ? s2[ 3:2] : s2[1:0];
|
||||
assign o = a ? s1[1] : s1[0];
|
||||
endmodule
|
||||
|
||||
module AL_MAP_LUT5 (
|
||||
|
@ -100,4 +175,18 @@ module AL_MAP_ADDER (
|
|||
output [1:0] o
|
||||
);
|
||||
parameter ALUTYPE = "ADD";
|
||||
|
||||
generate
|
||||
case (ALUTYPE)
|
||||
"ADD": assign o = a + b + c;
|
||||
"SUB": assign o = a - b - c;
|
||||
"A_LE_B": assign o = a - b - c;
|
||||
|
||||
"ADD_CARRY": assign o = { a, 1'b0 };
|
||||
"SUB_CARRY": assign o = { ~a, 1'b0 };
|
||||
"A_LE_B_CARRY": assign o = { a, 1'b0 };
|
||||
default: assign o = a + b + c;
|
||||
endcase
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -9,12 +9,12 @@ GENFILES += techlibs/common/simcells_help.inc
|
|||
|
||||
techlibs/common/simlib_help.inc: techlibs/common/cellhelp.py techlibs/common/simlib.v
|
||||
$(Q) mkdir -p techlibs/common
|
||||
$(P) python3 $^ > $@.new
|
||||
$(P) $(PYTHON_EXECUTABLE) $^ > $@.new
|
||||
$(Q) mv $@.new $@
|
||||
|
||||
techlibs/common/simcells_help.inc: techlibs/common/cellhelp.py techlibs/common/simcells.v
|
||||
$(Q) mkdir -p techlibs/common
|
||||
$(P) python3 $^ > $@.new
|
||||
$(P) $(PYTHON_EXECUTABLE) $^ > $@.new
|
||||
$(Q) mv $@.new $@
|
||||
|
||||
kernel/register.o: techlibs/common/simlib_help.inc techlibs/common/simcells_help.inc
|
||||
|
@ -28,3 +28,5 @@ $(eval $(call add_share_file,share,techlibs/common/dff2ff.v))
|
|||
$(eval $(call add_share_file,share,techlibs/common/gate2lut.v))
|
||||
$(eval $(call add_share_file,share,techlibs/common/cmp2lut.v))
|
||||
$(eval $(call add_share_file,share,techlibs/common/cells.lib))
|
||||
$(eval $(call add_share_file,share,techlibs/common/mul2dsp.v))
|
||||
$(eval $(call add_share_file,share,techlibs/common/dummy.box))
|
||||
|
|
1
techlibs/common/dummy.box
Normal file
1
techlibs/common/dummy.box
Normal file
|
@ -0,0 +1 @@
|
|||
(dummy) 1 0 0 0
|
296
techlibs/common/mul2dsp.v
Normal file
296
techlibs/common/mul2dsp.v
Normal file
|
@ -0,0 +1,296 @@
|
|||
/*
|
||||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
|
||||
* 2019 Eddie Hung <eddie@fpgeh.com>
|
||||
* 2019 David Shah <dave@ds0.me>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* Tech-mapping rules for decomposing arbitrarily-sized $mul cells
|
||||
* into an equivalent collection of smaller `DSP_NAME cells (with the
|
||||
* same interface as $mul) no larger than `DSP_[AB]_MAXWIDTH, attached
|
||||
* to $shl and $add cells.
|
||||
*
|
||||
*/
|
||||
|
||||
`ifndef DSP_A_MAXWIDTH
|
||||
$fatal(1, "Macro DSP_A_MAXWIDTH must be defined");
|
||||
`endif
|
||||
`ifndef DSP_B_MAXWIDTH
|
||||
$fatal(1, "Macro DSP_B_MAXWIDTH must be defined");
|
||||
`endif
|
||||
`ifndef DSP_B_MAXWIDTH
|
||||
$fatal(1, "Macro DSP_B_MAXWIDTH must be defined");
|
||||
`endif
|
||||
`ifndef DSP_A_MAXWIDTH_PARTIAL
|
||||
`define DSP_A_MAXWIDTH_PARTIAL `DSP_A_MAXWIDTH
|
||||
`endif
|
||||
`ifndef DSP_B_MAXWIDTH_PARTIAL
|
||||
`define DSP_B_MAXWIDTH_PARTIAL `DSP_B_MAXWIDTH
|
||||
`endif
|
||||
|
||||
`ifndef DSP_NAME
|
||||
$fatal(1, "Macro DSP_NAME must be defined");
|
||||
`endif
|
||||
|
||||
`define MAX(a,b) (a > b ? a : b)
|
||||
`define MIN(a,b) (a < b ? a : b)
|
||||
|
||||
(* techmap_celltype = "$mul $__mul" *)
|
||||
module _80_mul (A, B, Y);
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
parameter A_WIDTH = 1;
|
||||
parameter B_WIDTH = 1;
|
||||
parameter Y_WIDTH = 1;
|
||||
|
||||
input [A_WIDTH-1:0] A;
|
||||
input [B_WIDTH-1:0] B;
|
||||
output [Y_WIDTH-1:0] Y;
|
||||
|
||||
parameter _TECHMAP_CELLTYPE_ = "";
|
||||
|
||||
generate
|
||||
if (0) begin end
|
||||
`ifdef DSP_A_MINWIDTH
|
||||
else if (A_WIDTH < `DSP_A_MINWIDTH)
|
||||
wire _TECHMAP_FAIL_ = 1;
|
||||
`endif
|
||||
`ifdef DSP_B_MINWIDTH
|
||||
else if (B_WIDTH < `DSP_B_MINWIDTH)
|
||||
wire _TECHMAP_FAIL_ = 1;
|
||||
`endif
|
||||
`ifdef DSP_Y_MINWIDTH
|
||||
else if (Y_WIDTH < `DSP_Y_MINWIDTH)
|
||||
wire _TECHMAP_FAIL_ = 1;
|
||||
`endif
|
||||
`ifdef DSP_SIGNEDONLY
|
||||
else if (_TECHMAP_CELLTYPE_ == "$mul" && !A_SIGNED && !B_SIGNED)
|
||||
\$mul #(
|
||||
.A_SIGNED(1),
|
||||
.B_SIGNED(1),
|
||||
.A_WIDTH(A_WIDTH + 1),
|
||||
.B_WIDTH(B_WIDTH + 1),
|
||||
.Y_WIDTH(Y_WIDTH)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.A({1'b0, A}),
|
||||
.B({1'b0, B}),
|
||||
.Y(Y)
|
||||
);
|
||||
`endif
|
||||
else if (_TECHMAP_CELLTYPE_ == "$mul" && A_WIDTH < B_WIDTH)
|
||||
\$mul #(
|
||||
.A_SIGNED(B_SIGNED),
|
||||
.B_SIGNED(A_SIGNED),
|
||||
.A_WIDTH(B_WIDTH),
|
||||
.B_WIDTH(A_WIDTH),
|
||||
.Y_WIDTH(Y_WIDTH)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.A(B),
|
||||
.B(A),
|
||||
.Y(Y)
|
||||
);
|
||||
else begin
|
||||
wire [1023:0] _TECHMAP_DO_ = "proc; clean";
|
||||
|
||||
`ifdef DSP_SIGNEDONLY
|
||||
localparam sign_headroom = 1;
|
||||
`else
|
||||
localparam sign_headroom = 0;
|
||||
`endif
|
||||
|
||||
genvar i;
|
||||
if (A_WIDTH > `DSP_A_MAXWIDTH) begin
|
||||
localparam n = (A_WIDTH-`DSP_A_MAXWIDTH+`DSP_A_MAXWIDTH_PARTIAL-sign_headroom-1) / (`DSP_A_MAXWIDTH_PARTIAL-sign_headroom);
|
||||
localparam partial_Y_WIDTH = `MIN(Y_WIDTH, B_WIDTH+`DSP_A_MAXWIDTH_PARTIAL);
|
||||
localparam last_A_WIDTH = A_WIDTH-n*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom);
|
||||
localparam last_Y_WIDTH = B_WIDTH+last_A_WIDTH;
|
||||
if (A_SIGNED && B_SIGNED) begin
|
||||
wire signed [partial_Y_WIDTH-1:0] partial [n-1:0];
|
||||
wire signed [last_Y_WIDTH-1:0] last_partial;
|
||||
wire signed [Y_WIDTH-1:0] partial_sum [n:0];
|
||||
end
|
||||
else begin
|
||||
wire [partial_Y_WIDTH-1:0] partial [n-1:0];
|
||||
wire [last_Y_WIDTH-1:0] last_partial;
|
||||
wire [Y_WIDTH-1:0] partial_sum [n:0];
|
||||
end
|
||||
|
||||
for (i = 0; i < n; i=i+1) begin:sliceA
|
||||
\$__mul #(
|
||||
.A_SIGNED(sign_headroom),
|
||||
.B_SIGNED(B_SIGNED),
|
||||
.A_WIDTH(`DSP_A_MAXWIDTH_PARTIAL),
|
||||
.B_WIDTH(B_WIDTH),
|
||||
.Y_WIDTH(partial_Y_WIDTH)
|
||||
) mul (
|
||||
.A({{sign_headroom{1'b0}}, A[i*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom) +: `DSP_A_MAXWIDTH_PARTIAL-sign_headroom]}),
|
||||
.B(B),
|
||||
.Y(partial[i])
|
||||
);
|
||||
// TODO: Currently a 'cascade' approach to summing the partial
|
||||
// products is taken here, but a more efficient 'binary
|
||||
// reduction' approach also exists...
|
||||
if (i == 0)
|
||||
assign partial_sum[i] = partial[i];
|
||||
else
|
||||
assign partial_sum[i] = (partial[i] << (* mul2dsp *) i*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)) + (* mul2dsp *) partial_sum[i-1];
|
||||
end
|
||||
|
||||
\$__mul #(
|
||||
.A_SIGNED(A_SIGNED),
|
||||
.B_SIGNED(B_SIGNED),
|
||||
.A_WIDTH(last_A_WIDTH),
|
||||
.B_WIDTH(B_WIDTH),
|
||||
.Y_WIDTH(last_Y_WIDTH)
|
||||
) sliceA.last (
|
||||
.A(A[A_WIDTH-1 -: last_A_WIDTH]),
|
||||
.B(B),
|
||||
.Y(last_partial)
|
||||
);
|
||||
assign partial_sum[n] = (last_partial << (* mul2dsp *) n*(`DSP_A_MAXWIDTH_PARTIAL-sign_headroom)) + (* mul2dsp *) partial_sum[n-1];
|
||||
assign Y = partial_sum[n];
|
||||
end
|
||||
else if (B_WIDTH > `DSP_B_MAXWIDTH) begin
|
||||
localparam n = (B_WIDTH-`DSP_B_MAXWIDTH+`DSP_B_MAXWIDTH_PARTIAL-sign_headroom-1) / (`DSP_B_MAXWIDTH_PARTIAL-sign_headroom);
|
||||
localparam partial_Y_WIDTH = `MIN(Y_WIDTH, A_WIDTH+`DSP_B_MAXWIDTH_PARTIAL);
|
||||
localparam last_B_WIDTH = B_WIDTH-n*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom);
|
||||
localparam last_Y_WIDTH = A_WIDTH+last_B_WIDTH;
|
||||
if (A_SIGNED && B_SIGNED) begin
|
||||
wire signed [partial_Y_WIDTH-1:0] partial [n-1:0];
|
||||
wire signed [last_Y_WIDTH-1:0] last_partial;
|
||||
wire signed [Y_WIDTH-1:0] partial_sum [n:0];
|
||||
end
|
||||
else begin
|
||||
wire [partial_Y_WIDTH-1:0] partial [n-1:0];
|
||||
wire [last_Y_WIDTH-1:0] last_partial;
|
||||
wire [Y_WIDTH-1:0] partial_sum [n:0];
|
||||
end
|
||||
|
||||
for (i = 0; i < n; i=i+1) begin:sliceB
|
||||
\$__mul #(
|
||||
.A_SIGNED(A_SIGNED),
|
||||
.B_SIGNED(sign_headroom),
|
||||
.A_WIDTH(A_WIDTH),
|
||||
.B_WIDTH(`DSP_B_MAXWIDTH_PARTIAL),
|
||||
.Y_WIDTH(partial_Y_WIDTH)
|
||||
) mul (
|
||||
.A(A),
|
||||
.B({{sign_headroom{1'b0}}, B[i*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom) +: `DSP_B_MAXWIDTH_PARTIAL-sign_headroom]}),
|
||||
.Y(partial[i])
|
||||
);
|
||||
// TODO: Currently a 'cascade' approach to summing the partial
|
||||
// products is taken here, but a more efficient 'binary
|
||||
// reduction' approach also exists...
|
||||
if (i == 0)
|
||||
assign partial_sum[i] = partial[i];
|
||||
else
|
||||
assign partial_sum[i] = (partial[i] << (* mul2dsp *) i*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)) + (* mul2dsp *) partial_sum[i-1];
|
||||
end
|
||||
|
||||
\$__mul #(
|
||||
.A_SIGNED(A_SIGNED),
|
||||
.B_SIGNED(B_SIGNED),
|
||||
.A_WIDTH(A_WIDTH),
|
||||
.B_WIDTH(last_B_WIDTH),
|
||||
.Y_WIDTH(last_Y_WIDTH)
|
||||
) mul_sliceB_last (
|
||||
.A(A),
|
||||
.B(B[B_WIDTH-1 -: last_B_WIDTH]),
|
||||
.Y(last_partial)
|
||||
);
|
||||
assign partial_sum[n] = (last_partial << (* mul2dsp *) n*(`DSP_B_MAXWIDTH_PARTIAL-sign_headroom)) + (* mul2dsp *) partial_sum[n-1];
|
||||
assign Y = partial_sum[n];
|
||||
end
|
||||
else begin
|
||||
if (A_SIGNED)
|
||||
wire signed [`DSP_A_MAXWIDTH-1:0] Aext = $signed(A);
|
||||
else
|
||||
wire [`DSP_A_MAXWIDTH-1:0] Aext = A;
|
||||
if (B_SIGNED)
|
||||
wire signed [`DSP_B_MAXWIDTH-1:0] Bext = $signed(B);
|
||||
else
|
||||
wire [`DSP_B_MAXWIDTH-1:0] Bext = B;
|
||||
|
||||
`DSP_NAME #(
|
||||
.A_SIGNED(A_SIGNED),
|
||||
.B_SIGNED(B_SIGNED),
|
||||
.A_WIDTH(`DSP_A_MAXWIDTH),
|
||||
.B_WIDTH(`DSP_B_MAXWIDTH),
|
||||
.Y_WIDTH(`MIN(Y_WIDTH,`DSP_A_MAXWIDTH+`DSP_B_MAXWIDTH)),
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.A(Aext),
|
||||
.B(Bext),
|
||||
.Y(Y)
|
||||
);
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
(* techmap_celltype = "$mul $__mul" *)
|
||||
module _90_soft_mul (A, B, Y);
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
parameter A_WIDTH = 1;
|
||||
parameter B_WIDTH = 1;
|
||||
parameter Y_WIDTH = 1;
|
||||
|
||||
input [A_WIDTH-1:0] A;
|
||||
input [B_WIDTH-1:0] B;
|
||||
output [Y_WIDTH-1:0] Y;
|
||||
|
||||
// Indirection necessary since mapping
|
||||
// back to $mul will cause recursion
|
||||
generate
|
||||
if (A_SIGNED && !B_SIGNED)
|
||||
\$__soft_mul #(
|
||||
.A_SIGNED(A_SIGNED),
|
||||
.B_SIGNED(1),
|
||||
.A_WIDTH(A_WIDTH),
|
||||
.B_WIDTH(B_WIDTH+1),
|
||||
.Y_WIDTH(Y_WIDTH)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.A(A),
|
||||
.B({1'b0,B}),
|
||||
.Y(Y)
|
||||
);
|
||||
else if (!A_SIGNED && B_SIGNED)
|
||||
\$__soft_mul #(
|
||||
.A_SIGNED(1),
|
||||
.B_SIGNED(B_SIGNED),
|
||||
.A_WIDTH(A_WIDTH+1),
|
||||
.B_WIDTH(B_WIDTH),
|
||||
.Y_WIDTH(Y_WIDTH)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.A({1'b0,A}),
|
||||
.B(B),
|
||||
.Y(Y)
|
||||
);
|
||||
else
|
||||
\$__soft_mul #(
|
||||
.A_SIGNED(A_SIGNED),
|
||||
.B_SIGNED(B_SIGNED),
|
||||
.A_WIDTH(A_WIDTH),
|
||||
.B_WIDTH(B_WIDTH),
|
||||
.Y_WIDTH(Y_WIDTH)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.A(A),
|
||||
.B(B),
|
||||
.Y(Y)
|
||||
);
|
||||
endgenerate
|
||||
endmodule
|
1
techlibs/ecp5/.gitignore
vendored
1
techlibs/ecp5/.gitignore
vendored
|
@ -6,4 +6,5 @@ bram_conn_2.vh
|
|||
bram_conn_4.vh
|
||||
bram_conn_9.vh
|
||||
bram_conn_18.vh
|
||||
bram_conn_36.vh
|
||||
brams_connect.mk
|
||||
|
|
|
@ -13,22 +13,26 @@ $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/brams_map.v))
|
|||
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/bram.txt))
|
||||
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/arith_map.v))
|
||||
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/latches_map.v))
|
||||
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/dsp_map.v))
|
||||
|
||||
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc_5g.box))
|
||||
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc_5g.lut))
|
||||
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc_5g_nowide.lut))
|
||||
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc9_map.v))
|
||||
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc9_unmap.v))
|
||||
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc9_model.v))
|
||||
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc9_5g.box))
|
||||
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc9_5g.lut))
|
||||
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc9_5g_nowide.lut))
|
||||
|
||||
EXTRA_OBJS += techlibs/ecp5/brams_init.mk techlibs/ecp5/brams_connect.mk
|
||||
.SECONDARY: techlibs/ecp5/brams_init.mk techlibs/ecp5/brams_connect.mk
|
||||
|
||||
techlibs/ecp5/brams_init.mk: techlibs/ecp5/brams_init.py
|
||||
$(Q) mkdir -p techlibs/ecp5
|
||||
$(P) python3 $<
|
||||
$(P) $(PYTHON_EXECUTABLE) $<
|
||||
$(Q) touch $@
|
||||
|
||||
techlibs/ecp5/brams_connect.mk: techlibs/ecp5/brams_connect.py
|
||||
$(Q) mkdir -p techlibs/ecp5
|
||||
$(P) python3 $<
|
||||
$(P) $(PYTHON_EXECUTABLE) $<
|
||||
$(Q) touch $@
|
||||
|
||||
|
||||
|
@ -40,6 +44,7 @@ techlibs/ecp5/bram_conn_2.vh: techlibs/ecp5/brams_connect.mk
|
|||
techlibs/ecp5/bram_conn_4.vh: techlibs/ecp5/brams_connect.mk
|
||||
techlibs/ecp5/bram_conn_9.vh: techlibs/ecp5/brams_connect.mk
|
||||
techlibs/ecp5/bram_conn_18.vh: techlibs/ecp5/brams_connect.mk
|
||||
techlibs/ecp5/bram_conn_36.vh: techlibs/ecp5/brams_connect.mk
|
||||
|
||||
$(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_init_1_2_4.vh))
|
||||
$(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_init_9_18_36.vh))
|
||||
|
@ -49,3 +54,4 @@ $(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_conn_2.vh))
|
|||
$(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_conn_4.vh))
|
||||
$(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_conn_9.vh))
|
||||
$(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_conn_18.vh))
|
||||
$(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_conn_36.vh))
|
||||
|
|
|
@ -15,16 +15,16 @@ CCU2C 1 1 9 3
|
|||
630 379 630 379 526 275 392 141 273
|
||||
516 516 516 516 412 412 278 278 43
|
||||
|
||||
# Box 2 : TRELLIS_DPR16X4 (16x4 dist ram)
|
||||
# Box 2 : TRELLIS_DPR16X4_COMB (16x4 dist ram)
|
||||
# Outputs: DO0, DO1, DO2, DO3
|
||||
# name ID w/b ins outs
|
||||
TRELLIS_DPR16X4 2 0 14 4
|
||||
# name ID w/b ins outs
|
||||
$__ABC9_DPR16X4_COMB 2 0 8 4
|
||||
|
||||
#DI0 DI1 DI2 DI3 RAD0 RAD1 RAD2 RAD3 WAD0 WAD1 WAD2 WAD3 WCK WRE
|
||||
- - - - 141 379 275 379 - - - - - -
|
||||
- - - - 141 379 275 379 - - - - - -
|
||||
- - - - 141 379 275 379 - - - - - -
|
||||
- - - - 141 379 275 379 - - - - - -
|
||||
#A0 A1 A2 A3 RAD0 RAD1 RAD2 RAD3
|
||||
0 0 0 0 141 379 275 379
|
||||
0 0 0 0 141 379 275 379
|
||||
0 0 0 0 141 379 275 379
|
||||
0 0 0 0 141 379 275 379
|
||||
|
||||
# Box 3 : PFUMX (MUX2)
|
||||
# Outputs: Z
|
24
techlibs/ecp5/abc9_map.v
Normal file
24
techlibs/ecp5/abc9_map.v
Normal file
|
@ -0,0 +1,24 @@
|
|||
// ---------------------------------------
|
||||
|
||||
module TRELLIS_DPR16X4 (
|
||||
input [3:0] DI,
|
||||
input [3:0] WAD,
|
||||
input WRE,
|
||||
input WCK,
|
||||
input [3:0] RAD,
|
||||
output [3:0] DO
|
||||
);
|
||||
parameter WCKMUX = "WCK";
|
||||
parameter WREMUX = "WRE";
|
||||
parameter [63:0] INITVAL = 64'h0000000000000000;
|
||||
wire [3:0] \$DO ;
|
||||
|
||||
TRELLIS_DPR16X4 #(
|
||||
.WCKMUX(WCKMUX), .WREMUX(WREMUX), .INITVAL(INITVAL)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.DI(DI), .WAD(WAD), .WRE(WRE), .WCK(WCK),
|
||||
.RAD(RAD), .DO(\$DO )
|
||||
);
|
||||
|
||||
\$__ABC9_DPR16X4_COMB do (.A(\$DO ), .S(RAD), .Y(DO));
|
||||
endmodule
|
5
techlibs/ecp5/abc9_model.v
Normal file
5
techlibs/ecp5/abc9_model.v
Normal file
|
@ -0,0 +1,5 @@
|
|||
// ---------------------------------------
|
||||
|
||||
(* abc9_box_id=2 *)
|
||||
module \$__ABC9_DPR16X4_COMB (input [3:0] A, S, output [3:0] Y);
|
||||
endmodule
|
5
techlibs/ecp5/abc9_unmap.v
Normal file
5
techlibs/ecp5/abc9_unmap.v
Normal file
|
@ -0,0 +1,5 @@
|
|||
// ---------------------------------------
|
||||
|
||||
module \$__ABC9_DPR16X4_COMB (input [3:0] A, S, output [3:0] Y);
|
||||
assign Y = A;
|
||||
endmodule
|
|
@ -1,3 +1,18 @@
|
|||
bram $__ECP5_PDPW16KD
|
||||
init 1
|
||||
|
||||
abits 9
|
||||
dbits 36
|
||||
|
||||
groups 2
|
||||
ports 1 1
|
||||
wrmode 1 0
|
||||
enable 4 1
|
||||
transp 0 0
|
||||
clocks 2 3
|
||||
clkpol 2 3
|
||||
endbram
|
||||
|
||||
bram $__ECP5_DP16KD
|
||||
init 1
|
||||
|
||||
|
@ -22,8 +37,16 @@ bram $__ECP5_DP16KD
|
|||
clkpol 2 3
|
||||
endbram
|
||||
|
||||
match $__ECP5_PDPW16KD
|
||||
min bits 2048
|
||||
min efficiency 5
|
||||
shuffle_enable A
|
||||
make_transp
|
||||
or_next_if_better
|
||||
endmatch
|
||||
|
||||
match $__ECP5_DP16KD
|
||||
min bits 2048
|
||||
min efficiency 5
|
||||
shuffle_enable B
|
||||
shuffle_enable A
|
||||
endmatch
|
||||
|
|
|
@ -10,6 +10,18 @@ def write_bus_ports(f, ada_bits, adb_bits, dia_bits, dob_bits):
|
|||
print(" %s," % ", ".join(dia_conn), file=f)
|
||||
print(" %s," % ", ".join(dob_conn), file=f)
|
||||
|
||||
def write_bus_ports_pdp(f, adw_bits, adr_bits, di_bits, do_bits, be_bits):
|
||||
adw_conn = [".ADW%d(%s)" % (i, adw_bits[i]) for i in range(len(adw_bits))]
|
||||
adr_conn = [".ADR%d(%s)" % (i, adr_bits[i]) for i in range(len(adr_bits))]
|
||||
di_conn = [".DI%d(%s)" % (i, di_bits[i]) for i in range(len(di_bits))]
|
||||
do_conn = [".DO%d(%s)" % (i, do_bits[i]) for i in range(len(do_bits))]
|
||||
be_conn = [".BE%d(%s)" % (i, be_bits[i]) for i in range(len(be_bits))]
|
||||
print(" %s," % ", ".join(adw_conn), file=f)
|
||||
print(" %s," % ", ".join(adr_conn), file=f)
|
||||
print(" %s," % ", ".join(di_conn), file=f)
|
||||
print(" %s," % ", ".join(do_conn), file=f)
|
||||
print(" %s," % ", ".join(be_conn), file=f)
|
||||
|
||||
with open("techlibs/ecp5/bram_conn_1.vh", "w") as f:
|
||||
ada_bits = ["A1ADDR[%d]" % i for i in range(14)]
|
||||
adb_bits = ["B1ADDR[%d]" % i for i in range(14)]
|
||||
|
@ -44,3 +56,11 @@ with open("techlibs/ecp5/bram_conn_18.vh", "w") as f:
|
|||
dia_bits = ["A1DATA[%d]" % i for i in range(18)]
|
||||
dob_bits = ["B1DATA[%d]" % i for i in range(18)]
|
||||
write_bus_ports(f, ada_bits, adb_bits, dia_bits, dob_bits)
|
||||
|
||||
with open("techlibs/ecp5/bram_conn_36.vh", "w") as f:
|
||||
adw_bits = ["A1ADDR[%d]" % i for i in range(9)]
|
||||
adr_bits = ["1'b0", "1'b0", "1'b0", "1'b0", "1'b0"] + ["B1ADDR[%d]" % i for i in range(9)]
|
||||
di_bits = ["A1DATA[%d]" % i for i in range(36)]
|
||||
do_bits = ["B1DATA[%d]" % (i + 18) for i in range(18)] + ["B1DATA[%d]" % i for i in range(18)]
|
||||
be_bits = ["A1EN[%d]" % i for i in range(4)]
|
||||
write_bus_ports_pdp(f, adw_bits, adr_bits, di_bits, do_bits, be_bits)
|
||||
|
|
|
@ -113,3 +113,45 @@ module \$__ECP5_DP16KD (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
|||
wire TECHMAP_FAIL = 1'b1;
|
||||
end endgenerate
|
||||
endmodule
|
||||
|
||||
module \$__ECP5_PDPW16KD (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
||||
parameter CFG_ABITS = 9;
|
||||
parameter CFG_DBITS = 36;
|
||||
parameter CFG_ENABLE_A = 4;
|
||||
|
||||
parameter CLKPOL2 = 1;
|
||||
parameter CLKPOL3 = 1;
|
||||
parameter [18431:0] INIT = 18432'bx;
|
||||
|
||||
input CLK2;
|
||||
input CLK3;
|
||||
|
||||
input [CFG_ABITS-1:0] A1ADDR;
|
||||
input [CFG_DBITS-1:0] A1DATA;
|
||||
input [CFG_ENABLE_A-1:0] A1EN;
|
||||
|
||||
input [CFG_ABITS-1:0] B1ADDR;
|
||||
output [CFG_DBITS-1:0] B1DATA;
|
||||
input B1EN;
|
||||
|
||||
localparam CLKWMUX = CLKPOL2 ? "CLKA" : "INV";
|
||||
localparam CLKRMUX = CLKPOL3 ? "CLKB" : "INV";
|
||||
|
||||
localparam WRITEMODE_A = TRANSP2 ? "WRITETHROUGH" : "READBEFOREWRITE";
|
||||
|
||||
PDPW16KD #(
|
||||
`include "bram_init_9_18_36.vh"
|
||||
.DATA_WIDTH_W(36),
|
||||
.DATA_WIDTH_R(36),
|
||||
.CLKWMUX(CLKWMUX),
|
||||
.CLKRMUX(CLKRMUX),
|
||||
.GSR("AUTO")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
`include "bram_conn_36.vh"
|
||||
.CLKW(CLK2), .CLKR(CLK3),
|
||||
.CEW(1'b1),
|
||||
.CER(B1EN), .OCER(1'b1),
|
||||
.RST(1'b0)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -333,6 +333,13 @@ module ECLKSYNCB(
|
|||
);
|
||||
endmodule
|
||||
|
||||
(* blackbox *)
|
||||
module ECLKBRIDGECS(
|
||||
input CLK0, CLK1, SEL,
|
||||
output ECSOUT
|
||||
);
|
||||
endmodule
|
||||
|
||||
(* blackbox *)
|
||||
module DCCA(
|
||||
input CLKI, CE,
|
||||
|
@ -683,4 +690,98 @@ endmodule
|
|||
module SGSR (
|
||||
input GSR, CLK
|
||||
);
|
||||
endmodule
|
||||
endmodule
|
||||
|
||||
|
||||
(* blackbox *)
|
||||
module PDPW16KD (
|
||||
input DI35, DI34, DI33, DI32, DI31, DI30, DI29, DI28, DI27, DI26, DI25, DI24, DI23, DI22, DI21, DI20, DI19, DI18,
|
||||
input DI17, DI16, DI15, DI14, DI13, DI12, DI11, DI10, DI9, DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0,
|
||||
input ADW8, ADW7, ADW6, ADW5, ADW4, ADW3, ADW2, ADW1, ADW0,
|
||||
input BE3, BE2, BE1, BE0, CEW, CLKW, CSW2, CSW1, CSW0,
|
||||
input ADR13, ADR12, ADR11, ADR10, ADR9, ADR8, ADR7, ADR6, ADR5, ADR4, ADR3, ADR2, ADR1, ADR0,
|
||||
input CER, OCER, CLKR, CSR2, CSR1, CSR0, RST,
|
||||
output DO35, DO34, DO33, DO32, DO31, DO30, DO29, DO28, DO27, DO26, DO25, DO24, DO23, DO22, DO21, DO20, DO19, DO18,
|
||||
output DO17, DO16, DO15, DO14, DO13, DO12, DO11, DO10, DO9, DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0
|
||||
);
|
||||
parameter DATA_WIDTH_W = 36;
|
||||
parameter DATA_WIDTH_R = 36;
|
||||
parameter GSR = "ENABLED";
|
||||
|
||||
parameter REGMODE = "NOREG";
|
||||
|
||||
parameter RESETMODE = "SYNC";
|
||||
parameter ASYNC_RESET_RELEASE = "SYNC";
|
||||
|
||||
parameter CSDECODE_W = "0b000";
|
||||
parameter CSDECODE_R = "0b000";
|
||||
|
||||
parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_20 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_21 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_22 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_23 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_24 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_25 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_26 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_27 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_28 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_29 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_2A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_2B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_2C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_2D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_2E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_2F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_30 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_31 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_32 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_33 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_34 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_35 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_36 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_37 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_38 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_39 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_3A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_3B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_3C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_3D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_3E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INIT_DATA = "STATIC";
|
||||
parameter CLKWMUX = "CLKW";
|
||||
parameter CLKRMUX = "CLKR";
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -23,15 +23,15 @@ module FD1S3JX(input PD, D, CK, output Q); parameter GSR = "ENABLED"; TRELLI
|
|||
// module FL1S3AY(); endmodule
|
||||
|
||||
// Diamond I/O registers
|
||||
module IFS1P3BX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
module IFS1P3DX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
module IFS1P3IX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
module IFS1P3JX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
module IFS1P3BX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="input" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
module IFS1P3DX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="input" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
module IFS1P3IX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="input" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
module IFS1P3JX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="input" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
|
||||
module OFS1P3BX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
module OFS1P3DX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
module OFS1P3IX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
module OFS1P3JX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
module OFS1P3BX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="output" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
module OFS1P3DX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="output" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
module OFS1P3IX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="output" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
module OFS1P3JX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="output" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
|
||||
|
||||
// TODO: Diamond I/O latches
|
||||
// module IFS1S1B(input PD, D, SCLK, output Q); endmodule
|
||||
|
|
|
@ -9,19 +9,19 @@ module LUT4(input A, B, C, D, output Z);
|
|||
endmodule
|
||||
|
||||
// ---------------------------------------
|
||||
(* abc_box_id=4, lib_whitebox *)
|
||||
(* abc9_box_id=4, lib_whitebox *)
|
||||
module L6MUX21 (input D0, D1, SD, output Z);
|
||||
assign Z = SD ? D1 : D0;
|
||||
endmodule
|
||||
|
||||
// ---------------------------------------
|
||||
(* abc_box_id=1, lib_whitebox *)
|
||||
(* abc9_box_id=1, lib_whitebox *)
|
||||
module CCU2C(
|
||||
(* abc_carry *)
|
||||
(* abc9_carry *)
|
||||
input CIN,
|
||||
input A0, B0, C0, D0, A1, B1, C1, D1,
|
||||
output S0, S1,
|
||||
(* abc_carry *)
|
||||
(* abc9_carry *)
|
||||
output COUT
|
||||
);
|
||||
parameter [15:0] INIT0 = 16'h0000;
|
||||
|
@ -103,22 +103,19 @@ module TRELLIS_RAM16X2 (
|
|||
endmodule
|
||||
|
||||
// ---------------------------------------
|
||||
(* abc_box_id=3, lib_whitebox *)
|
||||
(* abc9_box_id=3, lib_whitebox *)
|
||||
module PFUMX (input ALUT, BLUT, C0, output Z);
|
||||
assign Z = C0 ? ALUT : BLUT;
|
||||
endmodule
|
||||
|
||||
// ---------------------------------------
|
||||
//(* abc_box_id=2 *)
|
||||
module TRELLIS_DPR16X4 (
|
||||
(* abc_scc_break *)
|
||||
input [3:0] DI,
|
||||
(* abc_scc_break *)
|
||||
input [3:0] WAD,
|
||||
(* abc_scc_break *)
|
||||
input WRE,
|
||||
input WCK,
|
||||
input [3:0] RAD,
|
||||
/* (* abc9_arrival=<TODO> *) */
|
||||
output [3:0] DO
|
||||
);
|
||||
parameter WCKMUX = "WCK";
|
||||
|
|
17
techlibs/ecp5/dsp_map.v
Normal file
17
techlibs/ecp5/dsp_map.v
Normal file
|
@ -0,0 +1,17 @@
|
|||
module \$__MUL18X18 (input [17:0] A, input [17:0] B, output [35:0] Y);
|
||||
|
||||
parameter A_WIDTH = 18;
|
||||
parameter B_WIDTH = 18;
|
||||
parameter Y_WIDTH = 36;
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
|
||||
MULT18X18D _TECHMAP_REPLACE_ (
|
||||
.A0(A[0]), .A1(A[1]), .A2(A[2]), .A3(A[3]), .A4(A[4]), .A5(A[5]), .A6(A[6]), .A7(A[7]), .A8(A[8]), .A9(A[9]), .A10(A[10]), .A11(A[11]), .A12(A[12]), .A13(A[13]), .A14(A[14]), .A15(A[15]), .A16(A[16]), .A17(A[17]),
|
||||
.B0(B[0]), .B1(B[1]), .B2(B[2]), .B3(B[3]), .B4(B[4]), .B5(B[5]), .B6(B[6]), .B7(B[7]), .B8(B[8]), .B9(B[9]), .B10(B[10]), .B11(B[11]), .B12(B[12]), .B13(B[13]), .B14(B[14]), .B15(B[15]), .B16(B[16]), .B17(B[17]),
|
||||
.C17(1'b0), .C16(1'b0), .C15(1'b0), .C14(1'b0), .C13(1'b0), .C12(1'b0), .C11(1'b0), .C10(1'b0), .C9(1'b0), .C8(1'b0), .C7(1'b0), .C6(1'b0), .C5(1'b0), .C4(1'b0), .C3(1'b0), .C2(1'b0), .C1(1'b0), .C0(1'b0),
|
||||
.SIGNEDA(A_SIGNED), .SIGNEDB(B_SIGNED), .SOURCEA(1'b0), .SOURCEB(1'b0),
|
||||
|
||||
.P0(Y[0]), .P1(Y[1]), .P2(Y[2]), .P3(Y[3]), .P4(Y[4]), .P5(Y[5]), .P6(Y[6]), .P7(Y[7]), .P8(Y[8]), .P9(Y[9]), .P10(Y[10]), .P11(Y[11]), .P12(Y[12]), .P13(Y[13]), .P14(Y[14]), .P15(Y[15]), .P16(Y[16]), .P17(Y[17]), .P18(Y[18]), .P19(Y[19]), .P20(Y[20]), .P21(Y[21]), .P22(Y[22]), .P23(Y[23]), .P24(Y[24]), .P25(Y[25]), .P26(Y[26]), .P27(Y[27]), .P28(Y[28]), .P29(Y[29]), .P30(Y[30]), .P31(Y[31]), .P32(Y[32]), .P33(Y[33]), .P34(Y[34]), .P35(Y[35])
|
||||
);
|
||||
endmodule
|
|
@ -89,6 +89,9 @@ struct SynthEcp5Pass : public ScriptPass
|
|||
log(" generate an output netlist (and BLIF file) suitable for VPR\n");
|
||||
log(" (this feature is experimental and incomplete)\n");
|
||||
log("\n");
|
||||
log(" -nodsp\n");
|
||||
log(" do not map multipliers to MULT18X18D\n");
|
||||
log("\n");
|
||||
log("\n");
|
||||
log("The following commands are executed by this synthesis command:\n");
|
||||
help_script();
|
||||
|
@ -96,7 +99,7 @@ struct SynthEcp5Pass : public ScriptPass
|
|||
}
|
||||
|
||||
string top_opt, blif_file, edif_file, json_file;
|
||||
bool noccu2, nodffe, nobram, nolutram, nowidelut, flatten, retime, abc2, abc9, vpr;
|
||||
bool noccu2, nodffe, nobram, nolutram, nowidelut, flatten, retime, abc2, abc9, nodsp, vpr;
|
||||
|
||||
void clear_flags() YS_OVERRIDE
|
||||
{
|
||||
|
@ -114,6 +117,7 @@ struct SynthEcp5Pass : public ScriptPass
|
|||
abc2 = false;
|
||||
vpr = false;
|
||||
abc9 = false;
|
||||
nodsp = false;
|
||||
}
|
||||
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
|
||||
|
@ -192,6 +196,10 @@ struct SynthEcp5Pass : public ScriptPass
|
|||
abc9 = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-nodsp") {
|
||||
nodsp = true;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
extra_args(args, argidx, design);
|
||||
|
@ -218,17 +226,34 @@ struct SynthEcp5Pass : public ScriptPass
|
|||
run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
|
||||
}
|
||||
|
||||
if (flatten && check_label("flatten", "(unless -noflatten)"))
|
||||
{
|
||||
run("proc");
|
||||
run("flatten");
|
||||
run("tribuf -logic");
|
||||
run("deminout");
|
||||
}
|
||||
|
||||
if (check_label("coarse"))
|
||||
{
|
||||
run("synth -run coarse");
|
||||
run("proc");
|
||||
if (flatten || help_mode)
|
||||
run("flatten");
|
||||
run("tribuf -logic");
|
||||
run("deminout");
|
||||
run("opt_expr");
|
||||
run("opt_clean");
|
||||
run("check");
|
||||
run("opt");
|
||||
run("wreduce");
|
||||
run("peepopt");
|
||||
run("opt_clean");
|
||||
run("share");
|
||||
run("techmap -map +/cmp2lut.v -D LUT_WIDTH=4");
|
||||
run("opt_expr");
|
||||
run("opt_clean");
|
||||
if (!nodsp) {
|
||||
run("techmap -map +/mul2dsp.v -map +/ecp5/dsp_map.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_NAME=$__MUL18X18", "(unless -nodsp)");
|
||||
run("chtype -set $mul t:$__soft_mul", "(unless -nodsp)");
|
||||
}
|
||||
run("alumacc");
|
||||
run("opt");
|
||||
run("fsm");
|
||||
run("opt -fast");
|
||||
run("memory -nomap");
|
||||
run("opt_clean");
|
||||
}
|
||||
|
||||
if (!nobram && check_label("map_bram", "(skip if -nobram)"))
|
||||
|
@ -272,6 +297,7 @@ struct SynthEcp5Pass : public ScriptPass
|
|||
run("simplemap");
|
||||
run("ecp5_ffinit");
|
||||
run("ecp5_gsr");
|
||||
run("attrmvcp -copy -attr syn_useioff");
|
||||
run("opt_clean");
|
||||
}
|
||||
|
||||
|
@ -280,12 +306,18 @@ struct SynthEcp5Pass : public ScriptPass
|
|||
if (abc2 || help_mode) {
|
||||
run("abc", " (only if -abc2)");
|
||||
}
|
||||
run("techmap -map +/ecp5/latches_map.v");
|
||||
std::string techmap_args = "-map +/ecp5/latches_map.v";
|
||||
if (abc9)
|
||||
techmap_args += " -map +/ecp5/abc9_map.v -max_iter 1";
|
||||
run("techmap " + techmap_args);
|
||||
|
||||
if (abc9) {
|
||||
run("read_verilog -icells -lib +/ecp5/abc9_model.v");
|
||||
if (nowidelut)
|
||||
run("abc9 -lut +/ecp5/abc_5g_nowide.lut -box +/ecp5/abc_5g.box -W 200");
|
||||
run("abc9 -lut +/ecp5/abc9_5g_nowide.lut -box +/ecp5/abc9_5g.box -W 200 -nomfs");
|
||||
else
|
||||
run("abc9 -lut +/ecp5/abc_5g.lut -box +/ecp5/abc_5g.box -W 200");
|
||||
run("abc9 -lut +/ecp5/abc9_5g.lut -box +/ecp5/abc9_5g.box -W 200 -nomfs");
|
||||
run("techmap -map +/ecp5/abc9_unmap.v");
|
||||
} else {
|
||||
if (nowidelut)
|
||||
run("abc -lut 4 -dress");
|
||||
|
|
|
@ -17,6 +17,18 @@ module \$_DFF_NP1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE
|
|||
module \$_DFF_PP0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule
|
||||
module \$_DFF_PP1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b1), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule
|
||||
|
||||
module \$_DLATCH_N_ (E, D, Q);
|
||||
wire [1023:0] _TECHMAP_DO_ = "simplemap; opt";
|
||||
input E, D;
|
||||
output Q = !E ? D : Q;
|
||||
endmodule
|
||||
|
||||
module \$_DLATCH_P_ (E, D, Q);
|
||||
wire [1023:0] _TECHMAP_DO_ = "simplemap; opt";
|
||||
input E, D;
|
||||
output Q = E ? D : Q;
|
||||
endmodule
|
||||
|
||||
`ifndef NO_LUT
|
||||
module \$lut (A, Y);
|
||||
parameter WIDTH = 0;
|
||||
|
|
|
@ -5,7 +5,12 @@ module EFX_LUT4(
|
|||
input I2,
|
||||
input I3
|
||||
);
|
||||
parameter LUTMASK = 16'h0000;
|
||||
parameter LUTMASK = 16'h0000;
|
||||
|
||||
wire [7:0] s3 = I3 ? LUTMASK[15:8] : LUTMASK[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
|
||||
|
||||
module EFX_ADD(
|
||||
|
@ -17,10 +22,18 @@ module EFX_ADD(
|
|||
);
|
||||
parameter I0_POLARITY = 1;
|
||||
parameter I1_POLARITY = 1;
|
||||
|
||||
wire i0;
|
||||
wire i1;
|
||||
|
||||
assign i0 = I0_POLARITY ? I0 : ~I0;
|
||||
assign i1 = I1_POLARITY ? I1 : ~I1;
|
||||
|
||||
assign {CO, O} = i0 + i1 + CI;
|
||||
endmodule
|
||||
|
||||
module EFX_FF(
|
||||
output Q,
|
||||
output reg Q,
|
||||
input D,
|
||||
input CE,
|
||||
input CLK,
|
||||
|
@ -33,6 +46,55 @@ module EFX_FF(
|
|||
parameter SR_VALUE = 0;
|
||||
parameter SR_SYNC_PRIORITY = 0;
|
||||
parameter D_POLARITY = 1;
|
||||
|
||||
wire clk;
|
||||
wire ce;
|
||||
wire sr;
|
||||
wire d;
|
||||
wire prio;
|
||||
wire sync;
|
||||
wire async;
|
||||
|
||||
assign clk = CLK_POLARITY ? CLK : ~CLK;
|
||||
assign ce = CE_POLARITY ? CE : ~CE;
|
||||
assign sr = SR_POLARITY ? SR : ~SR;
|
||||
assign d = D_POLARITY ? D : ~D;
|
||||
|
||||
initial Q = 1'b0;
|
||||
|
||||
generate
|
||||
if (SR_SYNC == 1)
|
||||
begin
|
||||
if (SR_SYNC_PRIORITY == 1)
|
||||
begin
|
||||
always @(posedge clk)
|
||||
if (sr)
|
||||
Q <= SR_VALUE;
|
||||
else if (ce)
|
||||
Q <= d;
|
||||
end
|
||||
else
|
||||
begin
|
||||
always @(posedge clk)
|
||||
if (ce)
|
||||
begin
|
||||
if (sr)
|
||||
Q <= SR_VALUE;
|
||||
else
|
||||
Q <= d;
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
always @(posedge clk or posedge sr)
|
||||
if (sr)
|
||||
Q <= SR_VALUE;
|
||||
else if (ce)
|
||||
Q <= d;
|
||||
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
module EFX_GBUFCE(
|
||||
|
@ -41,6 +103,12 @@ module EFX_GBUFCE(
|
|||
output O
|
||||
);
|
||||
parameter CE_POLARITY = 1'b1;
|
||||
|
||||
wire ce;
|
||||
assign ce = CE_POLARITY ? CE : ~CE;
|
||||
|
||||
assign O = I & ce;
|
||||
|
||||
endmodule
|
||||
|
||||
module EFX_RAM_5K(
|
||||
|
|
|
@ -14,7 +14,7 @@ EXTRA_OBJS += techlibs/ice40/brams_init.mk
|
|||
|
||||
techlibs/ice40/brams_init.mk: techlibs/ice40/brams_init.py
|
||||
$(Q) mkdir -p techlibs/ice40
|
||||
$(P) python3 $<
|
||||
$(P) $(PYTHON_EXECUTABLE) $<
|
||||
$(Q) touch techlibs/ice40/brams_init.mk
|
||||
|
||||
techlibs/ice40/brams_init1.vh: techlibs/ice40/brams_init.mk
|
||||
|
@ -27,12 +27,14 @@ $(eval $(call add_share_file,share/ice40,techlibs/ice40/cells_sim.v))
|
|||
$(eval $(call add_share_file,share/ice40,techlibs/ice40/latches_map.v))
|
||||
$(eval $(call add_share_file,share/ice40,techlibs/ice40/brams.txt))
|
||||
$(eval $(call add_share_file,share/ice40,techlibs/ice40/brams_map.v))
|
||||
$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc_hx.box))
|
||||
$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc_hx.lut))
|
||||
$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc_lp.box))
|
||||
$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc_lp.lut))
|
||||
$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc_u.box))
|
||||
$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc_u.lut))
|
||||
$(eval $(call add_share_file,share/ice40,techlibs/ice40/dsp_map.v))
|
||||
$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc9_model.v))
|
||||
$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc9_hx.box))
|
||||
$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc9_hx.lut))
|
||||
$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc9_lp.box))
|
||||
$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc9_lp.lut))
|
||||
$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc9_u.box))
|
||||
$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc9_u.lut))
|
||||
|
||||
$(eval $(call add_gen_share_file,share/ice40,techlibs/ice40/brams_init1.vh))
|
||||
$(eval $(call add_gen_share_file,share/ice40,techlibs/ice40/brams_init2.vh))
|
||||
|
|
27
techlibs/ice40/abc9_model.v
Normal file
27
techlibs/ice40/abc9_model.v
Normal file
|
@ -0,0 +1,27 @@
|
|||
(* abc9_box_id = 1, lib_whitebox *)
|
||||
module \$__ICE40_CARRY_WRAPPER (
|
||||
(* abc9_carry *)
|
||||
output CO,
|
||||
output O,
|
||||
input A, B,
|
||||
(* abc9_carry *)
|
||||
input CI,
|
||||
input I0, I3
|
||||
);
|
||||
parameter LUT = 0;
|
||||
SB_CARRY carry (
|
||||
.I0(A),
|
||||
.I1(B),
|
||||
.CI(CI),
|
||||
.CO(CO)
|
||||
);
|
||||
SB_LUT4 #(
|
||||
.LUT_INIT(LUT)
|
||||
) adder (
|
||||
.I0(I0),
|
||||
.I1(A),
|
||||
.I2(B),
|
||||
.I3(I3),
|
||||
.O(O)
|
||||
);
|
||||
endmodule
|
|
@ -2,6 +2,10 @@
|
|||
`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 (
|
||||
|
@ -141,48 +145,42 @@ module SB_CARRY (output CO, input I0, I1, CI);
|
|||
assign CO = (I0 && I1) || ((I0 || I1) && CI);
|
||||
endmodule
|
||||
|
||||
(* abc_box_id = 1, lib_whitebox *)
|
||||
module \$__ICE40_CARRY_WRAPPER (
|
||||
(* abc_carry *)
|
||||
output CO,
|
||||
output O,
|
||||
input A, B,
|
||||
(* abc_carry *)
|
||||
input CI,
|
||||
input I0, I3
|
||||
);
|
||||
parameter LUT = 0;
|
||||
SB_CARRY carry (
|
||||
.I0(A),
|
||||
.I1(B),
|
||||
.CI(CI),
|
||||
.CO(CO)
|
||||
);
|
||||
SB_LUT4 #(
|
||||
.LUT_INIT(LUT)
|
||||
) adder (
|
||||
.I0(I0),
|
||||
.I1(A),
|
||||
.I2(B),
|
||||
.I3(I3),
|
||||
.O(O)
|
||||
);
|
||||
endmodule
|
||||
// Max delay from: https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90
|
||||
// https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90
|
||||
// https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102
|
||||
|
||||
// Positive Edge SiliconBlue FF Cells
|
||||
|
||||
module SB_DFF (output `SB_DFF_REG, input C, D);
|
||||
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 (output `SB_DFF_REG, input C, E, D);
|
||||
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 (output `SB_DFF_REG, input C, R, D);
|
||||
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;
|
||||
|
@ -190,7 +188,13 @@ module SB_DFFSR (output `SB_DFF_REG, input C, R, D);
|
|||
Q <= D;
|
||||
endmodule
|
||||
|
||||
module SB_DFFR (output `SB_DFF_REG, input C, R, D);
|
||||
module SB_DFFR (
|
||||
`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;
|
||||
|
@ -198,7 +202,13 @@ module SB_DFFR (output `SB_DFF_REG, input C, R, D);
|
|||
Q <= D;
|
||||
endmodule
|
||||
|
||||
module SB_DFFSS (output `SB_DFF_REG, input C, S, D);
|
||||
module SB_DFFSS (
|
||||
`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;
|
||||
|
@ -206,7 +216,13 @@ module SB_DFFSS (output `SB_DFF_REG, input C, S, D);
|
|||
Q <= D;
|
||||
endmodule
|
||||
|
||||
module SB_DFFS (output `SB_DFF_REG, input C, S, D);
|
||||
module SB_DFFS (
|
||||
`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;
|
||||
|
@ -214,7 +230,13 @@ module SB_DFFS (output `SB_DFF_REG, input C, S, D);
|
|||
Q <= D;
|
||||
endmodule
|
||||
|
||||
module SB_DFFESR (output `SB_DFF_REG, input C, E, R, D);
|
||||
module SB_DFFESR (
|
||||
`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)
|
||||
|
@ -224,7 +246,13 @@ module SB_DFFESR (output `SB_DFF_REG, input C, E, R, D);
|
|||
end
|
||||
endmodule
|
||||
|
||||
module SB_DFFER (output `SB_DFF_REG, input C, E, R, D);
|
||||
module SB_DFFER (
|
||||
`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;
|
||||
|
@ -232,7 +260,13 @@ module SB_DFFER (output `SB_DFF_REG, input C, E, R, D);
|
|||
Q <= D;
|
||||
endmodule
|
||||
|
||||
module SB_DFFESS (output `SB_DFF_REG, input C, E, S, D);
|
||||
module SB_DFFESS (
|
||||
`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)
|
||||
|
@ -242,7 +276,13 @@ module SB_DFFESS (output `SB_DFF_REG, input C, E, S, D);
|
|||
end
|
||||
endmodule
|
||||
|
||||
module SB_DFFES (output `SB_DFF_REG, input C, E, S, D);
|
||||
module SB_DFFES (
|
||||
`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;
|
||||
|
@ -252,18 +292,36 @@ endmodule
|
|||
|
||||
// Negative Edge SiliconBlue FF Cells
|
||||
|
||||
module SB_DFFN (output `SB_DFF_REG, input C, D);
|
||||
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 (output `SB_DFF_REG, input C, E, D);
|
||||
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 (output `SB_DFF_REG, input C, R, D);
|
||||
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;
|
||||
|
@ -271,7 +329,13 @@ module SB_DFFNSR (output `SB_DFF_REG, input C, R, D);
|
|||
Q <= D;
|
||||
endmodule
|
||||
|
||||
module SB_DFFNR (output `SB_DFF_REG, input C, R, D);
|
||||
module SB_DFFNR (
|
||||
`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;
|
||||
|
@ -279,7 +343,13 @@ module SB_DFFNR (output `SB_DFF_REG, input C, R, D);
|
|||
Q <= D;
|
||||
endmodule
|
||||
|
||||
module SB_DFFNSS (output `SB_DFF_REG, input C, S, D);
|
||||
module SB_DFFNSS (
|
||||
`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;
|
||||
|
@ -287,7 +357,13 @@ module SB_DFFNSS (output `SB_DFF_REG, input C, S, D);
|
|||
Q <= D;
|
||||
endmodule
|
||||
|
||||
module SB_DFFNS (output `SB_DFF_REG, input C, S, D);
|
||||
module SB_DFFNS (
|
||||
`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;
|
||||
|
@ -295,7 +371,13 @@ module SB_DFFNS (output `SB_DFF_REG, input C, S, D);
|
|||
Q <= D;
|
||||
endmodule
|
||||
|
||||
module SB_DFFNESR (output `SB_DFF_REG, input C, E, R, D);
|
||||
module SB_DFFNESR (
|
||||
`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)
|
||||
|
@ -305,7 +387,13 @@ module SB_DFFNESR (output `SB_DFF_REG, input C, E, R, D);
|
|||
end
|
||||
endmodule
|
||||
|
||||
module SB_DFFNER (output `SB_DFF_REG, input C, E, R, D);
|
||||
module SB_DFFNER (
|
||||
`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;
|
||||
|
@ -313,7 +401,13 @@ module SB_DFFNER (output `SB_DFF_REG, input C, E, R, D);
|
|||
Q <= D;
|
||||
endmodule
|
||||
|
||||
module SB_DFFNESS (output `SB_DFF_REG, input C, E, S, D);
|
||||
module SB_DFFNESS (
|
||||
`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)
|
||||
|
@ -323,7 +417,13 @@ module SB_DFFNESS (output `SB_DFF_REG, input C, E, S, D);
|
|||
end
|
||||
endmodule
|
||||
|
||||
module SB_DFFNES (output `SB_DFF_REG, input C, E, S, D);
|
||||
module SB_DFFNES (
|
||||
`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;
|
||||
|
@ -334,6 +434,9 @@ 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,
|
||||
|
@ -502,6 +605,9 @@ module SB_RAM40_4K (
|
|||
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,
|
||||
|
@ -567,6 +673,9 @@ module SB_RAM40_4KNR (
|
|||
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,
|
||||
|
@ -632,6 +741,9 @@ module SB_RAM40_4KNW (
|
|||
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,
|
||||
|
@ -700,7 +812,12 @@ endmodule
|
|||
|
||||
module ICESTORM_LC (
|
||||
input I0, I1, I2, I3, CIN, CLK, CEN, SR,
|
||||
output LO, O, COUT
|
||||
output LO,
|
||||
`ABC9_ARRIVAL_HX(540)
|
||||
`ABC9_ARRIVAL_LP(796)
|
||||
`ABC9_ARRIVAL_U(1391)
|
||||
output O,
|
||||
output COUT
|
||||
);
|
||||
parameter [15:0] LUT_INIT = 0;
|
||||
|
||||
|
|
34
techlibs/ice40/dsp_map.v
Normal file
34
techlibs/ice40/dsp_map.v
Normal file
|
@ -0,0 +1,34 @@
|
|||
module \$__MUL16X16 (input [15:0] A, input [15:0] B, output [31:0] Y);
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
parameter A_WIDTH = 0;
|
||||
parameter B_WIDTH = 0;
|
||||
parameter Y_WIDTH = 0;
|
||||
|
||||
SB_MAC16 #(
|
||||
.NEG_TRIGGER(1'b0),
|
||||
.C_REG(1'b0),
|
||||
.A_REG(1'b0),
|
||||
.B_REG(1'b0),
|
||||
.D_REG(1'b0),
|
||||
.TOP_8x8_MULT_REG(1'b0),
|
||||
.BOT_8x8_MULT_REG(1'b0),
|
||||
.PIPELINE_16x16_MULT_REG1(1'b0),
|
||||
.PIPELINE_16x16_MULT_REG2(1'b0),
|
||||
.TOPOUTPUT_SELECT(2'b11),
|
||||
.TOPADDSUB_LOWERINPUT(2'b0),
|
||||
.TOPADDSUB_UPPERINPUT(1'b0),
|
||||
.TOPADDSUB_CARRYSELECT(2'b0),
|
||||
.BOTOUTPUT_SELECT(2'b11),
|
||||
.BOTADDSUB_LOWERINPUT(2'b0),
|
||||
.BOTADDSUB_UPPERINPUT(1'b0),
|
||||
.BOTADDSUB_CARRYSELECT(2'b0),
|
||||
.MODE_8x8(1'b0),
|
||||
.A_SIGNED(A_SIGNED),
|
||||
.B_SIGNED(B_SIGNED)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.A(A),
|
||||
.B(B),
|
||||
.O(Y),
|
||||
);
|
||||
endmodule
|
|
@ -238,7 +238,14 @@ struct SynthIce40Pass : public ScriptPass
|
|||
{
|
||||
if (check_label("begin"))
|
||||
{
|
||||
run("read_verilog -icells -lib +/ice40/cells_sim.v");
|
||||
std::string define;
|
||||
if (device_opt == "lp")
|
||||
define = "-D ICE40_LP";
|
||||
else if (device_opt == "u")
|
||||
define = "-D ICE40_U";
|
||||
else
|
||||
define = "-D ICE40_HX";
|
||||
run("read_verilog " + define + " -lib +/ice40/cells_sim.v");
|
||||
run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
|
||||
run("proc");
|
||||
}
|
||||
|
@ -265,8 +272,18 @@ struct SynthIce40Pass : public ScriptPass
|
|||
run("techmap -map +/cmp2lut.v -D LUT_WIDTH=4");
|
||||
run("opt_expr");
|
||||
run("opt_clean");
|
||||
if (help_mode || dsp)
|
||||
run("ice40_dsp", "(if -dsp)");
|
||||
if (help_mode || dsp) {
|
||||
run("techmap -map +/mul2dsp.v -map +/ice40/dsp_map.v -D DSP_A_MAXWIDTH=16 -D DSP_B_MAXWIDTH=16 "
|
||||
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_Y_MINWIDTH=11 "
|
||||
"-D DSP_NAME=$__MUL16X16", "(if -dsp)");
|
||||
run("select a:mul2dsp", " (if -dsp)");
|
||||
run("setattr -unset mul2dsp", " (if -dsp)");
|
||||
run("opt_expr -fine", " (if -dsp)");
|
||||
run("wreduce", " (if -dsp)");
|
||||
run("select -clear", " (if -dsp)");
|
||||
run("ice40_dsp", " (if -dsp)");
|
||||
run("chtype -set $mul t:$__soft_mul", "(if -dsp)");
|
||||
}
|
||||
run("alumacc");
|
||||
run("opt");
|
||||
run("fsm");
|
||||
|
@ -332,6 +349,7 @@ struct SynthIce40Pass : public ScriptPass
|
|||
}
|
||||
if (!noabc) {
|
||||
if (abc == "abc9") {
|
||||
run("read_verilog -icells -lib +/ice40/abc9_model.v");
|
||||
int wire_delay;
|
||||
if (device_opt == "lp")
|
||||
wire_delay = 400;
|
||||
|
@ -339,7 +357,7 @@ struct SynthIce40Pass : public ScriptPass
|
|||
wire_delay = 750;
|
||||
else
|
||||
wire_delay = 250;
|
||||
run(abc + stringf(" -W %d -lut +/ice40/abc_%s.lut -box +/ice40/abc_%s.box", wire_delay, device_opt.c_str(), device_opt.c_str()), "(skip if -noabc)");
|
||||
run(abc + stringf(" -W %d -lut +/ice40/abc9_%s.lut -box +/ice40/abc9_%s.box", wire_delay, device_opt.c_str(), device_opt.c_str()), "(skip if -noabc)");
|
||||
}
|
||||
else
|
||||
run(abc + " -dress -lut 4", "(skip if -noabc)");
|
||||
|
|
|
@ -13,7 +13,7 @@ EXTRA_OBJS += techlibs/xilinx/brams_init.mk
|
|||
|
||||
techlibs/xilinx/brams_init.mk: techlibs/xilinx/brams_init.py
|
||||
$(Q) mkdir -p techlibs/xilinx
|
||||
$(P) python3 $<
|
||||
$(P) $(PYTHON_EXECUTABLE) $<
|
||||
$(Q) touch $@
|
||||
|
||||
techlibs/xilinx/brams_init_36.vh: techlibs/xilinx/brams_init.mk
|
||||
|
@ -25,7 +25,10 @@ techlibs/xilinx/brams_init_8.vh: techlibs/xilinx/brams_init.mk
|
|||
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_sim.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_xtra.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_cells_xtra.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6v_cells_xtra.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_cells_xtra.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xcu_cells_xtra.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_brams.txt))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_brams_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_brams_bb.v))
|
||||
|
@ -35,13 +38,18 @@ $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_brams_bb.v))
|
|||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lutrams.txt))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lutrams_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/arith_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/ff_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_ff_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_ff_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lut_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/mux_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/dsp_map.v))
|
||||
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc_xc7.box))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc_xc7.lut))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc_xc7_nowide.lut))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc9_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc9_unmap.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc9_model.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc9_xc7.box))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc9_xc7.lut))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc9_xc7_nowide.lut))
|
||||
|
||||
$(eval $(call add_gen_share_file,share/xilinx,techlibs/xilinx/brams_init_36.vh))
|
||||
$(eval $(call add_gen_share_file,share/xilinx,techlibs/xilinx/brams_init_32.vh))
|
||||
|
|
447
techlibs/xilinx/abc9_map.v
Normal file
447
techlibs/xilinx/abc9_map.v
Normal file
|
@ -0,0 +1,447 @@
|
|||
/*
|
||||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
|
||||
* 2019 Eddie Hung <eddie@fpgeh.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
|
||||
module RAM32X1D (
|
||||
output DPO, SPO,
|
||||
(* techmap_autopurge *) input D,
|
||||
(* techmap_autopurge *) input WCLK,
|
||||
(* techmap_autopurge *) input WE,
|
||||
(* techmap_autopurge *) input A0, A1, A2, A3, A4,
|
||||
(* techmap_autopurge *) input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4
|
||||
);
|
||||
parameter INIT = 32'h0;
|
||||
parameter IS_WCLK_INVERTED = 1'b0;
|
||||
wire \$DPO , \$SPO ;
|
||||
RAM32X1D #(
|
||||
.INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.DPO(\$DPO ), .SPO(\$SPO ),
|
||||
.D(D), .WCLK(WCLK), .WE(WE),
|
||||
.A0(A0), .A1(A1), .A2(A2), .A3(A3), .A4(A4),
|
||||
.DPRA0(DPRA0), .DPRA1(DPRA1), .DPRA2(DPRA2), .DPRA3(DPRA3), .DPRA4(DPRA4)
|
||||
);
|
||||
\$__ABC9_LUT6 dpo (.A(\$DPO ), .S({1'b0, A0, A1, A2, A3, A4}), .Y(DPO));
|
||||
\$__ABC9_LUT6 spo (.A(\$SPO ), .S({1'b0, A0, A1, A2, A3, A4}), .Y(SPO));
|
||||
endmodule
|
||||
|
||||
module RAM64X1D (
|
||||
output DPO, SPO,
|
||||
(* techmap_autopurge *) input D,
|
||||
(* techmap_autopurge *) input WCLK,
|
||||
(* techmap_autopurge *) input WE,
|
||||
(* techmap_autopurge *) input A0, A1, A2, A3, A4, A5,
|
||||
(* techmap_autopurge *) input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5
|
||||
);
|
||||
parameter INIT = 64'h0;
|
||||
parameter IS_WCLK_INVERTED = 1'b0;
|
||||
wire \$DPO , \$SPO ;
|
||||
RAM64X1D #(
|
||||
.INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.DPO(\$DPO ), .SPO(\$SPO ),
|
||||
.D(D), .WCLK(WCLK), .WE(WE),
|
||||
.A0(A0), .A1(A1), .A2(A2), .A3(A3), .A4(A4), .A5(A5),
|
||||
.DPRA0(DPRA0), .DPRA1(DPRA1), .DPRA2(DPRA2), .DPRA3(DPRA3), .DPRA4(DPRA4), .DPRA5(DPRA5)
|
||||
);
|
||||
\$__ABC9_LUT6 dpo (.A(\$DPO ), .S({A0, A1, A2, A3, A4, A5}), .Y(DPO));
|
||||
\$__ABC9_LUT6 spo (.A(\$SPO ), .S({A0, A1, A2, A3, A4, A5}), .Y(SPO));
|
||||
endmodule
|
||||
|
||||
module RAM128X1D (
|
||||
output DPO, SPO,
|
||||
(* techmap_autopurge *) input D,
|
||||
(* techmap_autopurge *) input WCLK,
|
||||
(* techmap_autopurge *) input WE,
|
||||
(* techmap_autopurge *) input [6:0] A, DPRA
|
||||
);
|
||||
parameter INIT = 128'h0;
|
||||
parameter IS_WCLK_INVERTED = 1'b0;
|
||||
wire \$DPO , \$SPO ;
|
||||
RAM128X1D #(
|
||||
.INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.DPO(\$DPO ), .SPO(\$SPO ),
|
||||
.D(D), .WCLK(WCLK), .WE(WE),
|
||||
.A(A),
|
||||
.DPRA(DPRA)
|
||||
);
|
||||
\$__ABC9_LUT7 dpo (.A(\$DPO ), .S(A), .Y(DPO));
|
||||
\$__ABC9_LUT7 spo (.A(\$SPO ), .S(A), .Y(SPO));
|
||||
endmodule
|
||||
|
||||
module SRL16E (
|
||||
output Q,
|
||||
(* techmap_autopurge *) input A0, A1, A2, A3, CE, CLK, D
|
||||
);
|
||||
parameter [15:0] INIT = 16'h0000;
|
||||
parameter [0:0] IS_CLK_INVERTED = 1'b0;
|
||||
wire \$Q ;
|
||||
SRL16E #(
|
||||
.INIT(INIT), .IS_CLK_INVERTED(IS_CLK_INVERTED)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.Q(\$Q ),
|
||||
.A0(A0), .A1(A1), .A2(A2), .A3(A3), .CE(CE), .CLK(CLK), .D(D)
|
||||
);
|
||||
\$__ABC9_LUT6 q (.A(\$Q ), .S({1'b1, A0, A1, A2, A3, 1'b1}), .Y(Q));
|
||||
endmodule
|
||||
|
||||
module SRLC32E (
|
||||
output Q,
|
||||
output Q31,
|
||||
(* techmap_autopurge *) input [4:0] A,
|
||||
(* techmap_autopurge *) input CE, CLK, D
|
||||
);
|
||||
parameter [31:0] INIT = 32'h00000000;
|
||||
parameter [0:0] IS_CLK_INVERTED = 1'b0;
|
||||
wire \$Q ;
|
||||
SRLC32E #(
|
||||
.INIT(INIT), .IS_CLK_INVERTED(IS_CLK_INVERTED)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.Q(\$Q ), .Q31(Q31),
|
||||
.A(A), .CE(CE), .CLK(CLK), .D(D)
|
||||
);
|
||||
\$__ABC9_LUT6 q (.A(\$Q ), .S({1'b1, A}), .Y(Q));
|
||||
endmodule
|
||||
|
||||
module DSP48E1 (
|
||||
(* techmap_autopurge *) output [29:0] ACOUT,
|
||||
(* techmap_autopurge *) output [17:0] BCOUT,
|
||||
(* techmap_autopurge *) output reg CARRYCASCOUT,
|
||||
(* techmap_autopurge *) output reg [3:0] CARRYOUT,
|
||||
(* techmap_autopurge *) output reg MULTSIGNOUT,
|
||||
(* techmap_autopurge *) output OVERFLOW,
|
||||
(* techmap_autopurge *) output reg signed [47:0] P,
|
||||
(* techmap_autopurge *) output PATTERNBDETECT,
|
||||
(* techmap_autopurge *) output PATTERNDETECT,
|
||||
(* techmap_autopurge *) output [47:0] PCOUT,
|
||||
(* techmap_autopurge *) output UNDERFLOW,
|
||||
(* techmap_autopurge *) input signed [29:0] A,
|
||||
(* techmap_autopurge *) input [29:0] ACIN,
|
||||
(* techmap_autopurge *) input [3:0] ALUMODE,
|
||||
(* techmap_autopurge *) input signed [17:0] B,
|
||||
(* techmap_autopurge *) input [17:0] BCIN,
|
||||
(* techmap_autopurge *) input [47:0] C,
|
||||
(* techmap_autopurge *) input CARRYCASCIN,
|
||||
(* techmap_autopurge *) input CARRYIN,
|
||||
(* techmap_autopurge *) input [2:0] CARRYINSEL,
|
||||
(* techmap_autopurge *) input CEA1,
|
||||
(* techmap_autopurge *) input CEA2,
|
||||
(* techmap_autopurge *) input CEAD,
|
||||
(* techmap_autopurge *) input CEALUMODE,
|
||||
(* techmap_autopurge *) input CEB1,
|
||||
(* techmap_autopurge *) input CEB2,
|
||||
(* techmap_autopurge *) input CEC,
|
||||
(* techmap_autopurge *) input CECARRYIN,
|
||||
(* techmap_autopurge *) input CECTRL,
|
||||
(* techmap_autopurge *) input CED,
|
||||
(* techmap_autopurge *) input CEINMODE,
|
||||
(* techmap_autopurge *) input CEM,
|
||||
(* techmap_autopurge *) input CEP,
|
||||
(* techmap_autopurge *) input CLK,
|
||||
(* techmap_autopurge *) input [24:0] D,
|
||||
(* techmap_autopurge *) input [4:0] INMODE,
|
||||
(* techmap_autopurge *) input MULTSIGNIN,
|
||||
(* techmap_autopurge *) input [6:0] OPMODE,
|
||||
(* techmap_autopurge *) input [47:0] PCIN,
|
||||
(* techmap_autopurge *) input RSTA,
|
||||
(* techmap_autopurge *) input RSTALLCARRYIN,
|
||||
(* techmap_autopurge *) input RSTALUMODE,
|
||||
(* techmap_autopurge *) input RSTB,
|
||||
(* techmap_autopurge *) input RSTC,
|
||||
(* techmap_autopurge *) input RSTCTRL,
|
||||
(* techmap_autopurge *) input RSTD,
|
||||
(* techmap_autopurge *) input RSTINMODE,
|
||||
(* techmap_autopurge *) input RSTM,
|
||||
(* techmap_autopurge *) input RSTP
|
||||
);
|
||||
parameter integer ACASCREG = 1;
|
||||
parameter integer ADREG = 1;
|
||||
parameter integer ALUMODEREG = 1;
|
||||
parameter integer AREG = 1;
|
||||
parameter AUTORESET_PATDET = "NO_RESET";
|
||||
parameter A_INPUT = "DIRECT";
|
||||
parameter integer BCASCREG = 1;
|
||||
parameter integer BREG = 1;
|
||||
parameter B_INPUT = "DIRECT";
|
||||
parameter integer CARRYINREG = 1;
|
||||
parameter integer CARRYINSELREG = 1;
|
||||
parameter integer CREG = 1;
|
||||
parameter integer DREG = 1;
|
||||
parameter integer INMODEREG = 1;
|
||||
parameter integer MREG = 1;
|
||||
parameter integer OPMODEREG = 1;
|
||||
parameter integer PREG = 1;
|
||||
parameter SEL_MASK = "MASK";
|
||||
parameter SEL_PATTERN = "PATTERN";
|
||||
parameter USE_DPORT = "FALSE";
|
||||
parameter USE_MULT = "MULTIPLY";
|
||||
parameter USE_PATTERN_DETECT = "NO_PATDET";
|
||||
parameter USE_SIMD = "ONE48";
|
||||
parameter [47:0] MASK = 48'h3FFFFFFFFFFF;
|
||||
parameter [47:0] PATTERN = 48'h000000000000;
|
||||
parameter [3:0] IS_ALUMODE_INVERTED = 4'b0;
|
||||
parameter [0:0] IS_CARRYIN_INVERTED = 1'b0;
|
||||
parameter [0:0] IS_CLK_INVERTED = 1'b0;
|
||||
parameter [4:0] IS_INMODE_INVERTED = 5'b0;
|
||||
parameter [6:0] IS_OPMODE_INVERTED = 7'b0;
|
||||
|
||||
parameter _TECHMAP_CELLTYPE_ = "";
|
||||
localparam techmap_guard = (_TECHMAP_CELLTYPE_ != "");
|
||||
|
||||
`define DSP48E1_INST(__CELL__) """
|
||||
__CELL__ #(
|
||||
.ACASCREG(ACASCREG),
|
||||
.ADREG(ADREG),
|
||||
.ALUMODEREG(ALUMODEREG),
|
||||
.AREG(AREG),
|
||||
.AUTORESET_PATDET(AUTORESET_PATDET),
|
||||
.A_INPUT(A_INPUT),
|
||||
.BCASCREG(BCASCREG),
|
||||
.BREG(BREG),
|
||||
.B_INPUT(B_INPUT),
|
||||
.CARRYINREG(CARRYINREG),
|
||||
.CARRYINSELREG(CARRYINSELREG),
|
||||
.CREG(CREG),
|
||||
.DREG(DREG),
|
||||
.INMODEREG(INMODEREG),
|
||||
.MREG(MREG),
|
||||
.OPMODEREG(OPMODEREG),
|
||||
.PREG(PREG),
|
||||
.SEL_MASK(SEL_MASK),
|
||||
.SEL_PATTERN(SEL_PATTERN),
|
||||
.USE_DPORT(USE_DPORT),
|
||||
.USE_MULT(USE_MULT),
|
||||
.USE_PATTERN_DETECT(USE_PATTERN_DETECT),
|
||||
.USE_SIMD(USE_SIMD),
|
||||
.MASK(MASK),
|
||||
.PATTERN(PATTERN),
|
||||
.IS_ALUMODE_INVERTED(IS_ALUMODE_INVERTED),
|
||||
.IS_CARRYIN_INVERTED(IS_CARRYIN_INVERTED),
|
||||
.IS_CLK_INVERTED(IS_CLK_INVERTED),
|
||||
.IS_INMODE_INVERTED(IS_INMODE_INVERTED),
|
||||
.IS_OPMODE_INVERTED(IS_OPMODE_INVERTED)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.ACOUT(ACOUT),
|
||||
.BCOUT(BCOUT),
|
||||
.CARRYCASCOUT(CARRYCASCOUT),
|
||||
.CARRYOUT(CARRYOUT),
|
||||
.MULTSIGNOUT(MULTSIGNOUT),
|
||||
.OVERFLOW(OVERFLOW),
|
||||
.P(oP),
|
||||
.PATTERNBDETECT(PATTERNBDETECT),
|
||||
.PATTERNDETECT(PATTERNDETECT),
|
||||
.PCOUT(oPCOUT),
|
||||
.UNDERFLOW(UNDERFLOW),
|
||||
.A(iA),
|
||||
.ACIN(ACIN),
|
||||
.ALUMODE(ALUMODE),
|
||||
.B(iB),
|
||||
.BCIN(BCIN),
|
||||
.C(iC),
|
||||
.CARRYCASCIN(CARRYCASCIN),
|
||||
.CARRYIN(CARRYIN),
|
||||
.CARRYINSEL(CARRYINSEL),
|
||||
.CEA1(CEA1),
|
||||
.CEA2(CEA2),
|
||||
.CEAD(CEAD),
|
||||
.CEALUMODE(CEALUMODE),
|
||||
.CEB1(CEB1),
|
||||
.CEB2(CEB2),
|
||||
.CEC(CEC),
|
||||
.CECARRYIN(CECARRYIN),
|
||||
.CECTRL(CECTRL),
|
||||
.CED(CED),
|
||||
.CEINMODE(CEINMODE),
|
||||
.CEM(CEM),
|
||||
.CEP(CEP),
|
||||
.CLK(CLK),
|
||||
.D(iD),
|
||||
.INMODE(INMODE),
|
||||
.MULTSIGNIN(MULTSIGNIN),
|
||||
.OPMODE(OPMODE),
|
||||
.PCIN(PCIN),
|
||||
.RSTA(RSTA),
|
||||
.RSTALLCARRYIN(RSTALLCARRYIN),
|
||||
.RSTALUMODE(RSTALUMODE),
|
||||
.RSTB(RSTB),
|
||||
.RSTC(RSTC),
|
||||
.RSTCTRL(RSTCTRL),
|
||||
.RSTD(RSTD),
|
||||
.RSTINMODE(RSTINMODE),
|
||||
.RSTM(RSTM),
|
||||
.RSTP(RSTP)
|
||||
);
|
||||
"""
|
||||
|
||||
wire [29:0] iA;
|
||||
wire [17:0] iB;
|
||||
wire [47:0] iC;
|
||||
wire [24:0] iD;
|
||||
|
||||
wire pA, pB, pC, pD, pAD, pM, pP;
|
||||
wire [47:0] oP, mP;
|
||||
wire [47:0] oPCOUT, mPCOUT;
|
||||
|
||||
generate
|
||||
if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin
|
||||
// Disconnect the A-input if MREG is enabled, since
|
||||
// combinatorial path is broken
|
||||
if (AREG == 0 && MREG == 0 && PREG == 0)
|
||||
assign iA = A, pA = 1'bx;
|
||||
else
|
||||
\$__ABC9_REG #(.WIDTH(30)) rA (.I(A), .O(iA), .Q(pA));
|
||||
if (BREG == 0 && MREG == 0 && PREG == 0)
|
||||
assign iB = B, pB = 1'bx;
|
||||
else
|
||||
\$__ABC9_REG #(.WIDTH(18)) rB (.I(B), .O(iB), .Q(pB));
|
||||
if (CREG == 0 && PREG == 0)
|
||||
assign iC = C, pC = 1'bx;
|
||||
else
|
||||
\$__ABC9_REG #(.WIDTH(48)) rC (.I(C), .O(iC), .Q(pC));
|
||||
if (DREG == 0)
|
||||
assign iD = D;
|
||||
else if (techmap_guard)
|
||||
$error("Invalid DSP48E1 configuration: DREG enabled but USE_DPORT == \"FALSE\"");
|
||||
assign pD = 1'bx;
|
||||
if (ADREG == 1 && techmap_guard)
|
||||
$error("Invalid DSP48E1 configuration: ADREG enabled but USE_DPORT == \"FALSE\"");
|
||||
assign pAD = 1'bx;
|
||||
if (PREG == 0) begin
|
||||
if (MREG == 1)
|
||||
\$__ABC9_REG rM (.Q(pM));
|
||||
else
|
||||
assign pM = 1'bx;
|
||||
assign pP = 1'bx;
|
||||
end else begin
|
||||
assign pM = 1'bx;
|
||||
\$__ABC9_REG rP (.Q(pP));
|
||||
end
|
||||
|
||||
if (MREG == 0 && PREG == 0)
|
||||
assign mP = oP, mPCOUT = oPCOUT;
|
||||
else
|
||||
assign mP = 1'bx, mPCOUT = 1'bx;
|
||||
\$__ABC9_DSP48E1_MULT_P_MUX muxP (
|
||||
.Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oP), .Mq(pM), .P(mP), .Pq(pP), .O(P)
|
||||
);
|
||||
\$__ABC9_DSP48E1_MULT_PCOUT_MUX muxPCOUT (
|
||||
.Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oPCOUT), .Mq(pM), .P(mPCOUT), .Pq(pP), .O(PCOUT)
|
||||
);
|
||||
|
||||
`DSP48E1_INST(\$__ABC9_DSP48E1_MULT )
|
||||
end
|
||||
else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") begin
|
||||
// Disconnect the A-input if MREG is enabled, since
|
||||
// combinatorial path is broken
|
||||
if (AREG == 0 && ADREG == 0 && MREG == 0 && PREG == 0)
|
||||
assign iA = A, pA = 1'bx;
|
||||
else
|
||||
\$__ABC9_REG #(.WIDTH(30)) rA (.I(A), .O(iA), .Q(pA));
|
||||
if (BREG == 0 && MREG == 0 && PREG == 0)
|
||||
assign iB = B, pB = 1'bx;
|
||||
else
|
||||
\$__ABC9_REG #(.WIDTH(18)) rB (.I(B), .O(iB), .Q(pB));
|
||||
if (CREG == 0 && PREG == 0)
|
||||
assign iC = C, pC = 1'bx;
|
||||
else
|
||||
\$__ABC9_REG #(.WIDTH(48)) rC (.I(C), .O(iC), .Q(pC));
|
||||
if (DREG == 0 && ADREG == 0)
|
||||
assign iD = D, pD = 1'bx;
|
||||
else
|
||||
\$__ABC9_REG #(.WIDTH(25)) rD (.I(D), .O(iD), .Q(pD));
|
||||
if (PREG == 0) begin
|
||||
if (MREG == 1) begin
|
||||
assign pAD = 1'bx;
|
||||
\$__ABC9_REG rM (.Q(pM));
|
||||
end else begin
|
||||
if (ADREG == 1)
|
||||
\$__ABC9_REG rAD (.Q(pAD));
|
||||
else
|
||||
assign pAD = 1'bx;
|
||||
assign pM = 1'bx;
|
||||
end
|
||||
assign pP = 1'bx;
|
||||
end else begin
|
||||
assign pAD = 1'bx, pM = 1'bx;
|
||||
\$__ABC9_REG rP (.Q(pP));
|
||||
end
|
||||
|
||||
if (MREG == 0 && PREG == 0)
|
||||
assign mP = oP, mPCOUT = oPCOUT;
|
||||
else
|
||||
assign mP = 1'bx, mPCOUT = 1'bx;
|
||||
\$__ABC9_DSP48E1_MULT_DPORT_P_MUX muxP (
|
||||
.Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oP), .Mq(pM), .P(mP), .Pq(pP), .O(P)
|
||||
);
|
||||
\$__ABC9_DSP48E1_MULT_DPORT_PCOUT_MUX muxPCOUT (
|
||||
.Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oPCOUT), .Mq(pM), .P(mPCOUT), .Pq(pP), .O(PCOUT)
|
||||
);
|
||||
|
||||
`DSP48E1_INST(\$__ABC9_DSP48E1_MULT_DPORT )
|
||||
end
|
||||
else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") begin
|
||||
// Disconnect the A-input if MREG is enabled, since
|
||||
// combinatorial path is broken
|
||||
if (AREG == 0 && PREG == 0)
|
||||
assign iA = A, pA = 1'bx;
|
||||
else
|
||||
\$__ABC9_REG #(.WIDTH(30)) rA (.I(A), .O(iA), .Q(pA));
|
||||
if (BREG == 0 && PREG == 0)
|
||||
assign iB = B, pB = 1'bx;
|
||||
else
|
||||
\$__ABC9_REG #(.WIDTH(18)) rB (.I(B), .O(iB), .Q(pB));
|
||||
if (CREG == 0 && PREG == 0)
|
||||
assign iC = C, pC = 1'bx;
|
||||
else
|
||||
\$__ABC9_REG #(.WIDTH(48)) rC (.I(C), .O(iC), .Q(pC));
|
||||
if (DREG == 1 && techmap_guard)
|
||||
$error("Invalid DSP48E1 configuration: DREG enabled but USE_DPORT == \"FALSE\"");
|
||||
assign pD = 1'bx;
|
||||
if (ADREG == 1 && techmap_guard)
|
||||
$error("Invalid DSP48E1 configuration: ADREG enabled but USE_DPORT == \"FALSE\"");
|
||||
assign pAD = 1'bx;
|
||||
if (MREG == 1 && techmap_guard)
|
||||
$error("Invalid DSP48E1 configuration: MREG enabled but USE_MULT == \"NONE\"");
|
||||
assign pM = 1'bx;
|
||||
if (PREG == 1)
|
||||
\$__ABC9_REG rP (.Q(pP));
|
||||
else
|
||||
assign pP = 1'bx;
|
||||
|
||||
if (MREG == 0 && PREG == 0)
|
||||
assign mP = oP, mPCOUT = oPCOUT;
|
||||
else
|
||||
assign mP = 1'bx, mPCOUT = 1'bx;
|
||||
\$__ABC9_DSP48E1_P_MUX muxP (
|
||||
.Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oP), .Mq(pM), .P(mP), .Pq(pP), .O(P)
|
||||
);
|
||||
\$__ABC9_DSP48E1_PCOUT_MUX muxPCOUT (
|
||||
.Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oPCOUT), .Mq(pM), .P(mPCOUT), .Pq(pP), .O(PCOUT)
|
||||
);
|
||||
|
||||
`DSP48E1_INST(\$__ABC9_DSP48E1 )
|
||||
end
|
||||
else
|
||||
$error("Invalid DSP48E1 configuration");
|
||||
endgenerate
|
||||
`undef DSP48E1_INST
|
||||
endmodule
|
190
techlibs/xilinx/abc9_model.v
Normal file
190
techlibs/xilinx/abc9_model.v
Normal file
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
|
||||
* 2019 Eddie Hung <eddie@fpgeh.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
|
||||
// Box containing MUXF7.[AB] + MUXF8,
|
||||
// Necessary to make these an atomic unit so that
|
||||
// ABC cannot optimise just one of the MUXF7 away
|
||||
// and expect to save on its delay
|
||||
(* abc9_box_id = 3, lib_whitebox *)
|
||||
module \$__XILINX_MUXF78 (output O, input I0, I1, I2, I3, S0, S1);
|
||||
assign O = S1 ? (S0 ? I3 : I2)
|
||||
: (S0 ? I1 : I0);
|
||||
endmodule
|
||||
|
||||
// Box to emulate comb/seq behaviour of RAMD{32,64} and SRL{16,32}
|
||||
// Necessary since RAMD* and SRL* have both combinatorial (i.e.
|
||||
// same-cycle read operation) and sequential (write operation
|
||||
// is only committed on the next clock edge).
|
||||
// To model the combinatorial path, such cells have to be split
|
||||
// into comb and seq parts, with this box modelling only the former.
|
||||
(* abc9_box_id=2000 *)
|
||||
module \$__ABC9_LUT6 (input A, input [5:0] S, output Y);
|
||||
endmodule
|
||||
// Box to emulate comb/seq behaviour of RAMD128
|
||||
(* abc9_box_id=2001 *)
|
||||
module \$__ABC9_LUT7 (input A, input [6:0] S, output Y);
|
||||
endmodule
|
||||
|
||||
|
||||
// Modules used to model the comb/seq behaviour of DSP48E1
|
||||
// With abc9_map.v responsible for splicing the below modules
|
||||
// between the combinatorial DSP48E1 box (e.g. disconnecting
|
||||
// A when AREG, MREG or PREG is enabled and splicing in the
|
||||
// "$__ABC9_DSP48E1_REG" blackbox as "REG" in the diagram below)
|
||||
// this acts to first disables the combinatorial path (as there
|
||||
// is no connectivity through REG), and secondly, since this is
|
||||
// blackbox a new PI will be introduced with an arrival time of
|
||||
// zero.
|
||||
// Note: Since these "$__ABC9_DSP48E1_REG" modules are of a
|
||||
// sequential nature, they are not passed as a box to ABC and
|
||||
// (desirably) represented as PO/PIs.
|
||||
//
|
||||
// At the DSP output, we place a blackbox mux ("M" in the diagram
|
||||
// below) to capture the fact that the critical-path could come
|
||||
// from any one of its inputs.
|
||||
// In contrast to "REG", the "$__ABC9_DSP48E1_*_MUX" modules are
|
||||
// combinatorial blackboxes that do get passed to ABC.
|
||||
// The propagation delay through this box (specified in the box
|
||||
// file) captures the arrival time of the register (i.e.
|
||||
// propagation from AREG to P after clock edge), or zero delay
|
||||
// for the combinatorial path from the DSP.
|
||||
//
|
||||
// Doing so should means that ABC is able to analyse the
|
||||
// worst-case delay through to P, regardless of if it was
|
||||
// through any combinatorial paths (e.g. B, below) or an
|
||||
// internal register (A2REG).
|
||||
// However, the true value of being as complete as this is
|
||||
// questionable since if AREG=1 and BREG=0 (as below)
|
||||
// then the worse-case path would very likely be through B
|
||||
// and very unlikely to be through AREG.Q...?
|
||||
//
|
||||
// In graphical form:
|
||||
//
|
||||
// +-----+
|
||||
// +------>> REG >>----+
|
||||
// | +-----+ |
|
||||
// | |
|
||||
// | +---------+ | __
|
||||
// A >>-+X X-| | +--| \
|
||||
// | DSP48E1 |P | M |--->> P
|
||||
// | AREG=1 |-------|__/
|
||||
// B >>------| |
|
||||
// +---------+
|
||||
//
|
||||
`define ABC9_DSP48E1_MUX(__NAME__) """
|
||||
module __NAME__ (input Aq, ADq, Bq, Cq, Dq, input [47:0] I, input Mq, input [47:0] P, input Pq, output [47:0] O);
|
||||
endmodule
|
||||
"""
|
||||
(* abc9_box_id=2100 *) `ABC9_DSP48E1_MUX(\$__ABC9_DSP48E1_MULT_P_MUX )
|
||||
(* abc9_box_id=2101 *) `ABC9_DSP48E1_MUX(\$__ABC9_DSP48E1_MULT_PCOUT_MUX )
|
||||
(* abc9_box_id=2102 *) `ABC9_DSP48E1_MUX(\$__ABC9_DSP48E1_MULT_DPORT_P_MUX )
|
||||
(* abc9_box_id=2103 *) `ABC9_DSP48E1_MUX(\$__ABC9_DSP48E1_MULT_DPORT_PCOUT_MUX )
|
||||
(* abc9_box_id=2104 *) `ABC9_DSP48E1_MUX(\$__ABC9_DSP48E1_P_MUX )
|
||||
(* abc9_box_id=2105 *) `ABC9_DSP48E1_MUX(\$__ABC9_DSP48E1_PCOUT_MUX )
|
||||
|
||||
`define ABC9_DSP48E1(__NAME__) """
|
||||
module __NAME__ (
|
||||
output [29:0] ACOUT,
|
||||
output [17:0] BCOUT,
|
||||
output reg CARRYCASCOUT,
|
||||
output reg [3:0] CARRYOUT,
|
||||
output reg MULTSIGNOUT,
|
||||
output OVERFLOW,
|
||||
output reg signed [47:0] P,
|
||||
output PATTERNBDETECT,
|
||||
output PATTERNDETECT,
|
||||
output [47:0] PCOUT,
|
||||
output UNDERFLOW,
|
||||
input signed [29:0] A,
|
||||
input [29:0] ACIN,
|
||||
input [3:0] ALUMODE,
|
||||
input signed [17:0] B,
|
||||
input [17:0] BCIN,
|
||||
input [47:0] C,
|
||||
input CARRYCASCIN,
|
||||
input CARRYIN,
|
||||
input [2:0] CARRYINSEL,
|
||||
input CEA1,
|
||||
input CEA2,
|
||||
input CEAD,
|
||||
input CEALUMODE,
|
||||
input CEB1,
|
||||
input CEB2,
|
||||
input CEC,
|
||||
input CECARRYIN,
|
||||
input CECTRL,
|
||||
input CED,
|
||||
input CEINMODE,
|
||||
input CEM,
|
||||
input CEP,
|
||||
input CLK,
|
||||
input [24:0] D,
|
||||
input [4:0] INMODE,
|
||||
input MULTSIGNIN,
|
||||
input [6:0] OPMODE,
|
||||
input [47:0] PCIN,
|
||||
input RSTA,
|
||||
input RSTALLCARRYIN,
|
||||
input RSTALUMODE,
|
||||
input RSTB,
|
||||
input RSTC,
|
||||
input RSTCTRL,
|
||||
input RSTD,
|
||||
input RSTINMODE,
|
||||
input RSTM,
|
||||
input RSTP
|
||||
);
|
||||
parameter integer ACASCREG = 1;
|
||||
parameter integer ADREG = 1;
|
||||
parameter integer ALUMODEREG = 1;
|
||||
parameter integer AREG = 1;
|
||||
parameter AUTORESET_PATDET = "NO_RESET";
|
||||
parameter A_INPUT = "DIRECT";
|
||||
parameter integer BCASCREG = 1;
|
||||
parameter integer BREG = 1;
|
||||
parameter B_INPUT = "DIRECT";
|
||||
parameter integer CARRYINREG = 1;
|
||||
parameter integer CARRYINSELREG = 1;
|
||||
parameter integer CREG = 1;
|
||||
parameter integer DREG = 1;
|
||||
parameter integer INMODEREG = 1;
|
||||
parameter integer MREG = 1;
|
||||
parameter integer OPMODEREG = 1;
|
||||
parameter integer PREG = 1;
|
||||
parameter SEL_MASK = "MASK";
|
||||
parameter SEL_PATTERN = "PATTERN";
|
||||
parameter USE_DPORT = "FALSE";
|
||||
parameter USE_MULT = "MULTIPLY";
|
||||
parameter USE_PATTERN_DETECT = "NO_PATDET";
|
||||
parameter USE_SIMD = "ONE48";
|
||||
parameter [47:0] MASK = 48'h3FFFFFFFFFFF;
|
||||
parameter [47:0] PATTERN = 48'h000000000000;
|
||||
parameter [3:0] IS_ALUMODE_INVERTED = 4'b0;
|
||||
parameter [0:0] IS_CARRYIN_INVERTED = 1'b0;
|
||||
parameter [0:0] IS_CLK_INVERTED = 1'b0;
|
||||
parameter [4:0] IS_INMODE_INVERTED = 5'b0;
|
||||
parameter [6:0] IS_OPMODE_INVERTED = 7'b0;
|
||||
endmodule
|
||||
"""
|
||||
(* abc9_box_id=3000 *) `ABC9_DSP48E1(\$__ABC9_DSP48E1_MULT )
|
||||
(* abc9_box_id=3001 *) `ABC9_DSP48E1(\$__ABC9_DSP48E1_MULT_DPORT )
|
||||
(* abc9_box_id=3002 *) `ABC9_DSP48E1(\$__ABC9_DSP48E1 )
|
211
techlibs/xilinx/abc9_unmap.v
Normal file
211
techlibs/xilinx/abc9_unmap.v
Normal file
|
@ -0,0 +1,211 @@
|
|||
/*
|
||||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
|
||||
* 2019 Eddie Hung <eddie@fpgeh.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
|
||||
module \$__ABC9_LUT6 (input A, input [5:0] S, output Y);
|
||||
assign Y = A;
|
||||
endmodule
|
||||
module \$__ABC9_LUT7 (input A, input [6:0] S, output Y);
|
||||
assign Y = A;
|
||||
endmodule
|
||||
|
||||
module \$__ABC9_REG (input [WIDTH-1:0] I, output [WIDTH-1:0] O, output Q);
|
||||
parameter WIDTH = 1;
|
||||
assign O = I;
|
||||
endmodule
|
||||
(* techmap_celltype = "$__ABC9_DSP48E1_MULT_P_MUX $__ABC9_DSP48E1_MULT_PCOUT_MUX $__ABC9_DSP48E1_MULT_DPORT_P_MUX $__ABC9_DSP48E1_MULT_DPORT_PCOUT_MUX $__ABC9_DSP48E1_P_MUX $__ABC9_DSP48E1_PCOUT_MUX" *)
|
||||
module \$__ABC9_DSP48E1_MUX (
|
||||
input Aq, Bq, Cq, Dq, ADq,
|
||||
input [47:0] I,
|
||||
input Mq,
|
||||
input [47:0] P,
|
||||
input Pq,
|
||||
output [47:0] O
|
||||
);
|
||||
assign O = I;
|
||||
endmodule
|
||||
|
||||
(* techmap_celltype = "$__ABC9_DSP48E1_MULT $__ABC9_DSP48E1_MULT_DPORT $__ABC9_DSP48E1" *)
|
||||
module \$__ABC9_DSP48E1 (
|
||||
(* techmap_autopurge *) output [29:0] ACOUT,
|
||||
(* techmap_autopurge *) output [17:0] BCOUT,
|
||||
(* techmap_autopurge *) output reg CARRYCASCOUT,
|
||||
(* techmap_autopurge *) output reg [3:0] CARRYOUT,
|
||||
(* techmap_autopurge *) output reg MULTSIGNOUT,
|
||||
(* techmap_autopurge *) output OVERFLOW,
|
||||
(* techmap_autopurge *) output reg signed [47:0] P,
|
||||
(* techmap_autopurge *) output PATTERNBDETECT,
|
||||
(* techmap_autopurge *) output PATTERNDETECT,
|
||||
(* techmap_autopurge *) output [47:0] PCOUT,
|
||||
(* techmap_autopurge *) output UNDERFLOW,
|
||||
(* techmap_autopurge *) input signed [29:0] A,
|
||||
(* techmap_autopurge *) input [29:0] ACIN,
|
||||
(* techmap_autopurge *) input [3:0] ALUMODE,
|
||||
(* techmap_autopurge *) input signed [17:0] B,
|
||||
(* techmap_autopurge *) input [17:0] BCIN,
|
||||
(* techmap_autopurge *) input [47:0] C,
|
||||
(* techmap_autopurge *) input CARRYCASCIN,
|
||||
(* techmap_autopurge *) input CARRYIN,
|
||||
(* techmap_autopurge *) input [2:0] CARRYINSEL,
|
||||
(* techmap_autopurge *) input CEA1,
|
||||
(* techmap_autopurge *) input CEA2,
|
||||
(* techmap_autopurge *) input CEAD,
|
||||
(* techmap_autopurge *) input CEALUMODE,
|
||||
(* techmap_autopurge *) input CEB1,
|
||||
(* techmap_autopurge *) input CEB2,
|
||||
(* techmap_autopurge *) input CEC,
|
||||
(* techmap_autopurge *) input CECARRYIN,
|
||||
(* techmap_autopurge *) input CECTRL,
|
||||
(* techmap_autopurge *) input CED,
|
||||
(* techmap_autopurge *) input CEINMODE,
|
||||
(* techmap_autopurge *) input CEM,
|
||||
(* techmap_autopurge *) input CEP,
|
||||
(* techmap_autopurge *) input CLK,
|
||||
(* techmap_autopurge *) input [24:0] D,
|
||||
(* techmap_autopurge *) input [4:0] INMODE,
|
||||
(* techmap_autopurge *) input MULTSIGNIN,
|
||||
(* techmap_autopurge *) input [6:0] OPMODE,
|
||||
(* techmap_autopurge *) input [47:0] PCIN,
|
||||
(* techmap_autopurge *) input RSTA,
|
||||
(* techmap_autopurge *) input RSTALLCARRYIN,
|
||||
(* techmap_autopurge *) input RSTALUMODE,
|
||||
(* techmap_autopurge *) input RSTB,
|
||||
(* techmap_autopurge *) input RSTC,
|
||||
(* techmap_autopurge *) input RSTCTRL,
|
||||
(* techmap_autopurge *) input RSTD,
|
||||
(* techmap_autopurge *) input RSTINMODE,
|
||||
(* techmap_autopurge *) input RSTM,
|
||||
(* techmap_autopurge *) input RSTP
|
||||
);
|
||||
parameter integer ACASCREG = 1;
|
||||
parameter integer ADREG = 1;
|
||||
parameter integer ALUMODEREG = 1;
|
||||
parameter integer AREG = 1;
|
||||
parameter AUTORESET_PATDET = "NO_RESET";
|
||||
parameter A_INPUT = "DIRECT";
|
||||
parameter integer BCASCREG = 1;
|
||||
parameter integer BREG = 1;
|
||||
parameter B_INPUT = "DIRECT";
|
||||
parameter integer CARRYINREG = 1;
|
||||
parameter integer CARRYINSELREG = 1;
|
||||
parameter integer CREG = 1;
|
||||
parameter integer DREG = 1;
|
||||
parameter integer INMODEREG = 1;
|
||||
parameter integer MREG = 1;
|
||||
parameter integer OPMODEREG = 1;
|
||||
parameter integer PREG = 1;
|
||||
parameter SEL_MASK = "MASK";
|
||||
parameter SEL_PATTERN = "PATTERN";
|
||||
parameter USE_DPORT = "FALSE";
|
||||
parameter USE_MULT = "MULTIPLY";
|
||||
parameter USE_PATTERN_DETECT = "NO_PATDET";
|
||||
parameter USE_SIMD = "ONE48";
|
||||
parameter [47:0] MASK = 48'h3FFFFFFFFFFF;
|
||||
parameter [47:0] PATTERN = 48'h000000000000;
|
||||
parameter [3:0] IS_ALUMODE_INVERTED = 4'b0;
|
||||
parameter [0:0] IS_CARRYIN_INVERTED = 1'b0;
|
||||
parameter [0:0] IS_CLK_INVERTED = 1'b0;
|
||||
parameter [4:0] IS_INMODE_INVERTED = 5'b0;
|
||||
parameter [6:0] IS_OPMODE_INVERTED = 7'b0;
|
||||
|
||||
DSP48E1 #(
|
||||
.ACASCREG(ACASCREG),
|
||||
.ADREG(ADREG),
|
||||
.ALUMODEREG(ALUMODEREG),
|
||||
.AREG(AREG),
|
||||
.AUTORESET_PATDET(AUTORESET_PATDET),
|
||||
.A_INPUT(A_INPUT),
|
||||
.BCASCREG(BCASCREG),
|
||||
.BREG(BREG),
|
||||
.B_INPUT(B_INPUT),
|
||||
.CARRYINREG(CARRYINREG),
|
||||
.CARRYINSELREG(CARRYINSELREG),
|
||||
.CREG(CREG),
|
||||
.DREG(DREG),
|
||||
.INMODEREG(INMODEREG),
|
||||
.MREG(MREG),
|
||||
.OPMODEREG(OPMODEREG),
|
||||
.PREG(PREG),
|
||||
.SEL_MASK(SEL_MASK),
|
||||
.SEL_PATTERN(SEL_PATTERN),
|
||||
.USE_DPORT(USE_DPORT),
|
||||
.USE_MULT(USE_MULT),
|
||||
.USE_PATTERN_DETECT(USE_PATTERN_DETECT),
|
||||
.USE_SIMD(USE_SIMD),
|
||||
.MASK(MASK),
|
||||
.PATTERN(PATTERN),
|
||||
.IS_ALUMODE_INVERTED(IS_ALUMODE_INVERTED),
|
||||
.IS_CARRYIN_INVERTED(IS_CARRYIN_INVERTED),
|
||||
.IS_CLK_INVERTED(IS_CLK_INVERTED),
|
||||
.IS_INMODE_INVERTED(IS_INMODE_INVERTED),
|
||||
.IS_OPMODE_INVERTED(IS_OPMODE_INVERTED)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.ACOUT(ACOUT),
|
||||
.BCOUT(BCOUT),
|
||||
.CARRYCASCOUT(CARRYCASCOUT),
|
||||
.CARRYOUT(CARRYOUT),
|
||||
.MULTSIGNOUT(MULTSIGNOUT),
|
||||
.OVERFLOW(OVERFLOW),
|
||||
.P(P),
|
||||
.PATTERNBDETECT(PATTERNBDETECT),
|
||||
.PATTERNDETECT(PATTERNDETECT),
|
||||
.PCOUT(PCOUT),
|
||||
.UNDERFLOW(UNDERFLOW),
|
||||
.A(A),
|
||||
.ACIN(ACIN),
|
||||
.ALUMODE(ALUMODE),
|
||||
.B(B),
|
||||
.BCIN(BCIN),
|
||||
.C(C),
|
||||
.CARRYCASCIN(CARRYCASCIN),
|
||||
.CARRYIN(CARRYIN),
|
||||
.CARRYINSEL(CARRYINSEL),
|
||||
.CEA1(CEA1),
|
||||
.CEA2(CEA2),
|
||||
.CEAD(CEAD),
|
||||
.CEALUMODE(CEALUMODE),
|
||||
.CEB1(CEB1),
|
||||
.CEB2(CEB2),
|
||||
.CEC(CEC),
|
||||
.CECARRYIN(CECARRYIN),
|
||||
.CECTRL(CECTRL),
|
||||
.CED(CED),
|
||||
.CEINMODE(CEINMODE),
|
||||
.CEM(CEM),
|
||||
.CEP(CEP),
|
||||
.CLK(CLK),
|
||||
.D(D),
|
||||
.INMODE(INMODE),
|
||||
.MULTSIGNIN(MULTSIGNIN),
|
||||
.OPMODE(OPMODE),
|
||||
.PCIN(PCIN),
|
||||
.RSTA(RSTA),
|
||||
.RSTALLCARRYIN(RSTALLCARRYIN),
|
||||
.RSTALUMODE(RSTALUMODE),
|
||||
.RSTB(RSTB),
|
||||
.RSTC(RSTC),
|
||||
.RSTCTRL(RSTCTRL),
|
||||
.RSTD(RSTD),
|
||||
.RSTINMODE(RSTINMODE),
|
||||
.RSTM(RSTM),
|
||||
.RSTP(RSTP)
|
||||
);
|
||||
endmodule
|
1165
techlibs/xilinx/abc9_xc7.box
Normal file
1165
techlibs/xilinx/abc9_xc7.box
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,58 +0,0 @@
|
|||
# Max delays from https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf
|
||||
|
||||
# NB: Inputs/Outputs must be ordered alphabetically
|
||||
# (with exceptions for carry in/out)
|
||||
|
||||
# Average across F7[AB]MUX
|
||||
# Inputs: I0 I1 S0
|
||||
# Outputs: O
|
||||
F7MUX 1 1 3 1
|
||||
204 208 286
|
||||
|
||||
# Inputs: I0 I1 S0
|
||||
# Outputs: O
|
||||
MUXF8 2 1 3 1
|
||||
104 94 273
|
||||
|
||||
# Inputs: I0 I1 I2 I3 S0 S1
|
||||
# Outputs: O
|
||||
$__MUXF78 3 1 6 1
|
||||
294 297 311 317 390 273
|
||||
|
||||
# CARRY4 + CARRY4_[ABCD]X
|
||||
# Inputs: CYINIT DI0 DI1 DI2 DI3 S0 S1 S2 S3 CI
|
||||
# Outputs: O0 O1 O2 O3 CO0 CO1 CO2 CO3
|
||||
# (NB: carry chain input/output must be last
|
||||
# input/output and the entire bus has been
|
||||
# moved there overriding the otherwise
|
||||
# alphabetical ordering)
|
||||
CARRY4 4 1 10 8
|
||||
482 - - - - 223 - - - 222
|
||||
598 407 - - - 400 205 - - 334
|
||||
584 556 537 - - 523 558 226 - 239
|
||||
642 615 596 438 - 582 618 330 227 313
|
||||
536 379 - - - 340 - - - 271
|
||||
494 465 445 - - 433 469 - - 157
|
||||
592 540 520 356 - 512 548 292 - 228
|
||||
580 526 507 398 385 508 528 378 380 114
|
||||
|
||||
# SLICEM/A6LUT
|
||||
# Inputs: A0 A1 A2 A3 A4 D DPRA0 DPRA1 DPRA2 DPRA3 DPRA4 WCLK WE
|
||||
# Outputs: DPO SPO
|
||||
RAM32X1D 5 0 13 2
|
||||
- - - - - - 631 472 407 238 127 - -
|
||||
631 472 407 238 127 - - - - - - - -
|
||||
|
||||
# SLICEM/A6LUT
|
||||
# Inputs: A0 A1 A2 A3 A4 A5 D DPRA0 DPRA1 DPRA2 DPRA3 DPRA4 DPRA5 WCLK WE
|
||||
# Outputs: DPO SPO
|
||||
RAM64X1D 6 0 15 2
|
||||
- - - - - - - 642 631 472 407 238 127 - -
|
||||
642 631 472 407 238 127 - - - - - - - - -
|
||||
|
||||
# SLICEM/A6LUT + F7[AB]MUX
|
||||
# Inputs: A0 A1 A2 A3 A4 A5 A6 D DPRA0 DPRA1 DPRA2 DPRA3 DPRA4 DPRA5 DPRA6 WCLK WE
|
||||
# Outputs: DPO SPO
|
||||
RAM128X1D 7 0 17 2
|
||||
- - - - - - - - 1009 998 839 774 605 494 450 - -
|
||||
1047 1036 877 812 643 532 478 - - - - - - - - - -
|
|
@ -331,7 +331,6 @@ module \$_MUX16_ (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V, Y)
|
|||
endmodule
|
||||
`endif
|
||||
|
||||
`ifndef _ABC
|
||||
module \$__XILINX_MUXF78 (O, I0, I1, I2, I3, S0, S1);
|
||||
output O;
|
||||
input I0, I1, I2, I3, S0, S1;
|
||||
|
@ -364,4 +363,3 @@ module \$__XILINX_MUXF78 (O, I0, I1, I2, I3, S0, S1);
|
|||
else
|
||||
MUXF8 mux8 (.I0(T0), .I1(T1), .S(S1), .O(O));
|
||||
endmodule
|
||||
`endif
|
||||
|
|
|
@ -38,6 +38,17 @@ module IBUF(
|
|||
assign O = I;
|
||||
endmodule
|
||||
|
||||
module IBUFG(
|
||||
output O,
|
||||
(* iopad_external_pin *)
|
||||
input I);
|
||||
parameter CAPACITANCE = "DONT_CARE";
|
||||
parameter IBUF_DELAY_VALUE = "0";
|
||||
parameter IBUF_LOW_PWR = "TRUE";
|
||||
parameter IOSTANDARD = "DEFAULT";
|
||||
assign O = I;
|
||||
endmodule
|
||||
|
||||
module OBUF(
|
||||
(* iopad_external_pin *)
|
||||
output O,
|
||||
|
@ -60,9 +71,18 @@ module BUFGCTRL(
|
|||
(* clkbuf_driver *)
|
||||
output O,
|
||||
input I0, input I1,
|
||||
input S0, input S1,
|
||||
input CE0, input CE1,
|
||||
input IGNORE0, input IGNORE1);
|
||||
(* invertible_pin = "IS_S0_INVERTED" *)
|
||||
input S0,
|
||||
(* invertible_pin = "IS_S1_INVERTED" *)
|
||||
input S1,
|
||||
(* invertible_pin = "IS_CE0_INVERTED" *)
|
||||
input CE0,
|
||||
(* invertible_pin = "IS_CE1_INVERTED" *)
|
||||
input CE1,
|
||||
(* invertible_pin = "IS_IGNORE0_INVERTED" *)
|
||||
input IGNORE0,
|
||||
(* invertible_pin = "IS_IGNORE1_INVERTED" *)
|
||||
input IGNORE1);
|
||||
|
||||
parameter [0:0] INIT_OUT = 1'b0;
|
||||
parameter PRESELECT_I0 = "FALSE";
|
||||
|
@ -87,6 +107,7 @@ module BUFHCE(
|
|||
(* clkbuf_driver *)
|
||||
output O,
|
||||
input I,
|
||||
(* invertible_pin = "IS_CE_INVERTED" *)
|
||||
input CE);
|
||||
|
||||
parameter [0:0] INIT_OUT = 1'b0;
|
||||
|
@ -174,34 +195,26 @@ module MUXCY(output O, input CI, DI, S);
|
|||
assign O = S ? CI : DI;
|
||||
endmodule
|
||||
|
||||
(* abc_box_id = 1, lib_whitebox *)
|
||||
(* abc9_box_id = 1, lib_whitebox *)
|
||||
module MUXF7(output O, input I0, I1, S);
|
||||
assign O = S ? I1 : I0;
|
||||
endmodule
|
||||
|
||||
(* abc_box_id = 2, lib_whitebox *)
|
||||
(* abc9_box_id = 2, lib_whitebox *)
|
||||
module MUXF8(output O, input I0, I1, S);
|
||||
assign O = S ? I1 : I0;
|
||||
endmodule
|
||||
|
||||
`ifdef _ABC
|
||||
(* abc_box_id = 3, lib_whitebox *)
|
||||
module \$__XILINX_MUXF78 (output O, input I0, I1, I2, I3, S0, S1);
|
||||
assign O = S1 ? (S0 ? I3 : I2)
|
||||
: (S0 ? I1 : I0);
|
||||
endmodule
|
||||
`endif
|
||||
|
||||
module XORCY(output O, input CI, LI);
|
||||
assign O = CI ^ LI;
|
||||
endmodule
|
||||
|
||||
(* abc_box_id = 4, lib_whitebox *)
|
||||
(* abc9_box_id = 4, lib_whitebox *)
|
||||
module CARRY4(
|
||||
(* abc_carry *)
|
||||
(* abc9_carry *)
|
||||
output [3:0] CO,
|
||||
output [3:0] O,
|
||||
(* abc_carry *)
|
||||
(* abc9_carry *)
|
||||
input CI,
|
||||
input CYINIT,
|
||||
input [3:0] DI, S
|
||||
|
@ -236,7 +249,20 @@ endmodule
|
|||
|
||||
`endif
|
||||
|
||||
module FDRE (output reg Q, (* clkbuf_sink *) input C, input CE, D, R);
|
||||
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L238-L250
|
||||
|
||||
module FDRE (
|
||||
(* abc9_arrival=303 *)
|
||||
output reg Q,
|
||||
(* clkbuf_sink *)
|
||||
(* invertible_pin = "IS_C_INVERTED" *)
|
||||
input C,
|
||||
input CE,
|
||||
(* invertible_pin = "IS_D_INVERTED" *)
|
||||
input D,
|
||||
(* invertible_pin = "IS_R_INVERTED" *)
|
||||
input R
|
||||
);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
parameter [0:0] IS_C_INVERTED = 1'b0;
|
||||
parameter [0:0] IS_D_INVERTED = 1'b0;
|
||||
|
@ -248,7 +274,18 @@ module FDRE (output reg Q, (* clkbuf_sink *) input C, input CE, D, R);
|
|||
endcase endgenerate
|
||||
endmodule
|
||||
|
||||
module FDSE (output reg Q, (* clkbuf_sink *) input C, input CE, D, S);
|
||||
module FDSE (
|
||||
(* abc9_arrival=303 *)
|
||||
output reg Q,
|
||||
(* clkbuf_sink *)
|
||||
(* invertible_pin = "IS_C_INVERTED" *)
|
||||
input C,
|
||||
input CE,
|
||||
(* invertible_pin = "IS_D_INVERTED" *)
|
||||
input D,
|
||||
(* invertible_pin = "IS_S_INVERTED" *)
|
||||
input S
|
||||
);
|
||||
parameter [0:0] INIT = 1'b1;
|
||||
parameter [0:0] IS_C_INVERTED = 1'b0;
|
||||
parameter [0:0] IS_D_INVERTED = 1'b0;
|
||||
|
@ -260,7 +297,18 @@ module FDSE (output reg Q, (* clkbuf_sink *) input C, input CE, D, S);
|
|||
endcase endgenerate
|
||||
endmodule
|
||||
|
||||
module FDCE (output reg Q, (* clkbuf_sink *) input C, input CE, D, CLR);
|
||||
module FDCE (
|
||||
(* abc9_arrival=303 *)
|
||||
output reg Q,
|
||||
(* clkbuf_sink *)
|
||||
(* invertible_pin = "IS_C_INVERTED" *)
|
||||
input C,
|
||||
input CE,
|
||||
(* invertible_pin = "IS_D_INVERTED" *)
|
||||
input D,
|
||||
(* invertible_pin = "IS_CLR_INVERTED" *)
|
||||
input CLR
|
||||
);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
parameter [0:0] IS_C_INVERTED = 1'b0;
|
||||
parameter [0:0] IS_D_INVERTED = 1'b0;
|
||||
|
@ -274,7 +322,18 @@ module FDCE (output reg Q, (* clkbuf_sink *) input C, input CE, D, CLR);
|
|||
endcase endgenerate
|
||||
endmodule
|
||||
|
||||
module FDPE (output reg Q, (* clkbuf_sink *) input C, input CE, D, PRE);
|
||||
module FDPE (
|
||||
(* abc9_arrival=303 *)
|
||||
output reg Q,
|
||||
(* clkbuf_sink *)
|
||||
(* invertible_pin = "IS_C_INVERTED" *)
|
||||
input C,
|
||||
input CE,
|
||||
(* invertible_pin = "IS_D_INVERTED" *)
|
||||
input D,
|
||||
(* invertible_pin = "IS_PRE_INVERTED" *)
|
||||
input PRE
|
||||
);
|
||||
parameter [0:0] INIT = 1'b1;
|
||||
parameter [0:0] IS_C_INVERTED = 1'b0;
|
||||
parameter [0:0] IS_D_INVERTED = 1'b0;
|
||||
|
@ -288,38 +347,106 @@ module FDPE (output reg Q, (* clkbuf_sink *) input C, input CE, D, PRE);
|
|||
endcase endgenerate
|
||||
endmodule
|
||||
|
||||
module FDRE_1 (output reg Q, (* clkbuf_sink *) input C, input CE, D, R);
|
||||
module FDRE_1 (
|
||||
(* abc9_arrival=303 *)
|
||||
output reg Q,
|
||||
(* clkbuf_sink *)
|
||||
input C,
|
||||
input CE, D, R
|
||||
);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q <= INIT;
|
||||
always @(negedge C) if (R) Q <= 1'b0; else if(CE) Q <= D;
|
||||
endmodule
|
||||
|
||||
module FDSE_1 (output reg Q, (* clkbuf_sink *) input C, input CE, D, S);
|
||||
module FDSE_1 (
|
||||
(* abc9_arrival=303 *)
|
||||
output reg Q,
|
||||
(* clkbuf_sink *)
|
||||
input C,
|
||||
input CE, D, S
|
||||
);
|
||||
parameter [0:0] INIT = 1'b1;
|
||||
initial Q <= INIT;
|
||||
always @(negedge C) if (S) Q <= 1'b1; else if(CE) Q <= D;
|
||||
endmodule
|
||||
|
||||
module FDCE_1 (output reg Q, (* clkbuf_sink *) input C, input CE, D, CLR);
|
||||
module FDCE_1 (
|
||||
(* abc9_arrival=303 *)
|
||||
output reg Q,
|
||||
(* clkbuf_sink *)
|
||||
input C,
|
||||
input CE, D, CLR
|
||||
);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q <= INIT;
|
||||
always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else if (CE) Q <= D;
|
||||
endmodule
|
||||
|
||||
module FDPE_1 (output reg Q, (* clkbuf_sink *) input C, input CE, D, PRE);
|
||||
module FDPE_1 (
|
||||
(* abc9_arrival=303 *)
|
||||
output reg Q,
|
||||
(* clkbuf_sink *)
|
||||
input C,
|
||||
input CE, D, PRE
|
||||
);
|
||||
parameter [0:0] INIT = 1'b1;
|
||||
initial Q <= INIT;
|
||||
always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D;
|
||||
endmodule
|
||||
|
||||
(* abc_box_id = 5 *)
|
||||
module LDCE (
|
||||
output reg Q,
|
||||
(* invertible_pin = "IS_CLR_INVERTED" *)
|
||||
input CLR,
|
||||
input D,
|
||||
(* invertible_pin = "IS_G_INVERTED" *)
|
||||
input G,
|
||||
input GE
|
||||
);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
parameter [0:0] IS_CLR_INVERTED = 1'b0;
|
||||
parameter [0:0] IS_G_INVERTED = 1'b0;
|
||||
parameter MSGON = "TRUE";
|
||||
parameter XON = "TRUE";
|
||||
initial Q = INIT;
|
||||
wire clr = CLR ^ IS_CLR_INVERTED;
|
||||
wire g = G ^ IS_G_INVERTED;
|
||||
always @*
|
||||
if (clr) Q = 1'b0;
|
||||
else if (GE && g) Q = D;
|
||||
endmodule
|
||||
|
||||
module LDPE (
|
||||
output reg Q,
|
||||
input D,
|
||||
(* invertible_pin = "IS_G_INVERTED" *)
|
||||
input G,
|
||||
input GE,
|
||||
(* invertible_pin = "IS_PRE_INVERTED" *)
|
||||
input PRE
|
||||
);
|
||||
parameter [0:0] INIT = 1'b1;
|
||||
parameter [0:0] IS_G_INVERTED = 1'b0;
|
||||
parameter [0:0] IS_PRE_INVERTED = 1'b0;
|
||||
parameter MSGON = "TRUE";
|
||||
parameter XON = "TRUE";
|
||||
initial Q = INIT;
|
||||
wire g = G ^ IS_G_INVERTED;
|
||||
wire pre = PRE ^ IS_PRE_INVERTED;
|
||||
always @*
|
||||
if (pre) Q = 1'b1;
|
||||
else if (GE && g) Q = D;
|
||||
endmodule
|
||||
|
||||
module RAM32X1D (
|
||||
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957
|
||||
(* abc9_arrival=1153 *)
|
||||
output DPO, SPO,
|
||||
(* abc_scc_break *)
|
||||
input D,
|
||||
(* clkbuf_sink *)
|
||||
(* invertible_pin = "IS_WCLK_INVERTED" *)
|
||||
input WCLK,
|
||||
(* abc_scc_break *)
|
||||
input WE,
|
||||
input A0, A1, A2, A3, A4,
|
||||
input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4
|
||||
|
@ -335,14 +462,14 @@ module RAM32X1D (
|
|||
always @(posedge clk) if (WE) mem[a] <= D;
|
||||
endmodule
|
||||
|
||||
(* abc_box_id = 6 *)
|
||||
module RAM64X1D (
|
||||
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957
|
||||
(* abc9_arrival=1153 *)
|
||||
output DPO, SPO,
|
||||
(* abc_scc_break *)
|
||||
input D,
|
||||
(* clkbuf_sink *)
|
||||
(* invertible_pin = "IS_WCLK_INVERTED" *)
|
||||
input WCLK,
|
||||
(* abc_scc_break *)
|
||||
input WE,
|
||||
input A0, A1, A2, A3, A4, A5,
|
||||
input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5
|
||||
|
@ -358,14 +485,14 @@ module RAM64X1D (
|
|||
always @(posedge clk) if (WE) mem[a] <= D;
|
||||
endmodule
|
||||
|
||||
(* abc_box_id = 7 *)
|
||||
module RAM128X1D (
|
||||
output DPO, SPO,
|
||||
(* abc_scc_break *)
|
||||
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957
|
||||
(* abc9_arrival=1153 *)
|
||||
output DPO, SPO,
|
||||
input D,
|
||||
(* clkbuf_sink *)
|
||||
(* invertible_pin = "IS_WCLK_INVERTED" *)
|
||||
input WCLK,
|
||||
(* abc_scc_break *)
|
||||
input WE,
|
||||
input [6:0] A, DPRA
|
||||
);
|
||||
|
@ -379,9 +506,12 @@ module RAM128X1D (
|
|||
endmodule
|
||||
|
||||
module SRL16E (
|
||||
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905
|
||||
(* abc9_arrival=1472 *)
|
||||
output Q,
|
||||
input A0, A1, A2, A3, CE,
|
||||
(* clkbuf_sink *)
|
||||
(* invertible_pin = "IS_CLK_INVERTED" *)
|
||||
input CLK,
|
||||
input D
|
||||
);
|
||||
|
@ -404,6 +534,7 @@ module SRLC16E (
|
|||
output Q15,
|
||||
input A0, A1, A2, A3, CE,
|
||||
(* clkbuf_sink *)
|
||||
(* invertible_pin = "IS_CLK_INVERTED" *)
|
||||
input CLK,
|
||||
input D
|
||||
);
|
||||
|
@ -423,11 +554,15 @@ module SRLC16E (
|
|||
endmodule
|
||||
|
||||
module SRLC32E (
|
||||
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905
|
||||
(* abc9_arrival=1472 *)
|
||||
output Q,
|
||||
(* abc9_arrival=1114 *)
|
||||
output Q31,
|
||||
input [4:0] A,
|
||||
input CE,
|
||||
(* clkbuf_sink *)
|
||||
(* invertible_pin = "IS_CLK_INVERTED" *)
|
||||
input CLK,
|
||||
input D
|
||||
);
|
||||
|
@ -445,3 +580,466 @@ module SRLC32E (
|
|||
always @(posedge CLK) if (CE) r <= { r[30:0], D };
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
module DSP48E1 (
|
||||
output [29:0] ACOUT,
|
||||
output [17:0] BCOUT,
|
||||
output reg CARRYCASCOUT,
|
||||
output reg [3:0] CARRYOUT,
|
||||
output reg MULTSIGNOUT,
|
||||
output OVERFLOW,
|
||||
output reg signed [47:0] P,
|
||||
output reg PATTERNBDETECT,
|
||||
output reg PATTERNDETECT,
|
||||
output [47:0] PCOUT,
|
||||
output UNDERFLOW,
|
||||
input signed [29:0] A,
|
||||
input [29:0] ACIN,
|
||||
input [3:0] ALUMODE,
|
||||
input signed [17:0] B,
|
||||
input [17:0] BCIN,
|
||||
input [47:0] C,
|
||||
input CARRYCASCIN,
|
||||
input CARRYIN,
|
||||
input [2:0] CARRYINSEL,
|
||||
input CEA1,
|
||||
input CEA2,
|
||||
input CEAD,
|
||||
input CEALUMODE,
|
||||
input CEB1,
|
||||
input CEB2,
|
||||
input CEC,
|
||||
input CECARRYIN,
|
||||
input CECTRL,
|
||||
input CED,
|
||||
input CEINMODE,
|
||||
input CEM,
|
||||
input CEP,
|
||||
(* clkbuf_sink *) input CLK,
|
||||
input [24:0] D,
|
||||
input [4:0] INMODE,
|
||||
input MULTSIGNIN,
|
||||
input [6:0] OPMODE,
|
||||
input [47:0] PCIN,
|
||||
input RSTA,
|
||||
input RSTALLCARRYIN,
|
||||
input RSTALUMODE,
|
||||
input RSTB,
|
||||
input RSTC,
|
||||
input RSTCTRL,
|
||||
input RSTD,
|
||||
input RSTINMODE,
|
||||
input RSTM,
|
||||
input RSTP
|
||||
);
|
||||
parameter integer ACASCREG = 1;
|
||||
parameter integer ADREG = 1;
|
||||
parameter integer ALUMODEREG = 1;
|
||||
parameter integer AREG = 1;
|
||||
parameter AUTORESET_PATDET = "NO_RESET";
|
||||
parameter A_INPUT = "DIRECT";
|
||||
parameter integer BCASCREG = 1;
|
||||
parameter integer BREG = 1;
|
||||
parameter B_INPUT = "DIRECT";
|
||||
parameter integer CARRYINREG = 1;
|
||||
parameter integer CARRYINSELREG = 1;
|
||||
parameter integer CREG = 1;
|
||||
parameter integer DREG = 1;
|
||||
parameter integer INMODEREG = 1;
|
||||
parameter integer MREG = 1;
|
||||
parameter integer OPMODEREG = 1;
|
||||
parameter integer PREG = 1;
|
||||
parameter SEL_MASK = "MASK";
|
||||
parameter SEL_PATTERN = "PATTERN";
|
||||
parameter USE_DPORT = "FALSE";
|
||||
parameter USE_MULT = "MULTIPLY";
|
||||
parameter USE_PATTERN_DETECT = "NO_PATDET";
|
||||
parameter USE_SIMD = "ONE48";
|
||||
parameter [47:0] MASK = 48'h3FFFFFFFFFFF;
|
||||
parameter [47:0] PATTERN = 48'h000000000000;
|
||||
parameter [3:0] IS_ALUMODE_INVERTED = 4'b0;
|
||||
parameter [0:0] IS_CARRYIN_INVERTED = 1'b0;
|
||||
parameter [0:0] IS_CLK_INVERTED = 1'b0;
|
||||
parameter [4:0] IS_INMODE_INVERTED = 5'b0;
|
||||
parameter [6:0] IS_OPMODE_INVERTED = 7'b0;
|
||||
|
||||
initial begin
|
||||
`ifdef __ICARUS__
|
||||
if (AUTORESET_PATDET != "NO_RESET") $fatal(1, "Unsupported AUTORESET_PATDET value");
|
||||
if (SEL_MASK != "MASK") $fatal(1, "Unsupported SEL_MASK value");
|
||||
if (SEL_PATTERN != "PATTERN") $fatal(1, "Unsupported SEL_PATTERN value");
|
||||
if (USE_SIMD != "ONE48" && USE_SIMD != "TWO24" && USE_SIMD != "FOUR12") $fatal(1, "Unsupported USE_SIMD value");
|
||||
if (IS_ALUMODE_INVERTED != 4'b0) $fatal(1, "Unsupported IS_ALUMODE_INVERTED value");
|
||||
if (IS_CARRYIN_INVERTED != 1'b0) $fatal(1, "Unsupported IS_CARRYIN_INVERTED value");
|
||||
if (IS_CLK_INVERTED != 1'b0) $fatal(1, "Unsupported IS_CLK_INVERTED value");
|
||||
if (IS_INMODE_INVERTED != 5'b0) $fatal(1, "Unsupported IS_INMODE_INVERTED value");
|
||||
if (IS_OPMODE_INVERTED != 7'b0) $fatal(1, "Unsupported IS_OPMODE_INVERTED value");
|
||||
`endif
|
||||
end
|
||||
|
||||
wire signed [29:0] A_muxed;
|
||||
wire signed [17:0] B_muxed;
|
||||
|
||||
generate
|
||||
if (A_INPUT == "CASCADE") assign A_muxed = ACIN;
|
||||
else assign A_muxed = A;
|
||||
|
||||
if (B_INPUT == "CASCADE") assign B_muxed = BCIN;
|
||||
else assign B_muxed = B;
|
||||
endgenerate
|
||||
|
||||
reg signed [29:0] Ar1, Ar2;
|
||||
reg signed [24:0] Dr;
|
||||
reg signed [17:0] Br1, Br2;
|
||||
reg signed [47:0] Cr;
|
||||
reg [4:0] INMODEr = 5'b0;
|
||||
reg [6:0] OPMODEr = 7'b0;
|
||||
reg [3:0] ALUMODEr = 4'b0;
|
||||
reg [2:0] CARRYINSELr = 3'b0;
|
||||
|
||||
generate
|
||||
// Configurable A register
|
||||
if (AREG == 2) begin
|
||||
initial Ar1 = 30'b0;
|
||||
initial Ar2 = 30'b0;
|
||||
always @(posedge CLK)
|
||||
if (RSTA) begin
|
||||
Ar1 <= 30'b0;
|
||||
Ar2 <= 30'b0;
|
||||
end else begin
|
||||
if (CEA1) Ar1 <= A_muxed;
|
||||
if (CEA2) Ar2 <= Ar1;
|
||||
end
|
||||
end else if (AREG == 1) begin
|
||||
//initial Ar1 = 30'b0;
|
||||
initial Ar2 = 30'b0;
|
||||
always @(posedge CLK)
|
||||
if (RSTA) begin
|
||||
Ar1 <= 30'b0;
|
||||
Ar2 <= 30'b0;
|
||||
end else begin
|
||||
if (CEA1) Ar1 <= A_muxed;
|
||||
if (CEA2) Ar2 <= A_muxed;
|
||||
end
|
||||
end else begin
|
||||
always @* Ar1 <= A_muxed;
|
||||
always @* Ar2 <= A_muxed;
|
||||
end
|
||||
|
||||
// Configurable B register
|
||||
if (BREG == 2) begin
|
||||
initial Br1 = 25'b0;
|
||||
initial Br2 = 25'b0;
|
||||
always @(posedge CLK)
|
||||
if (RSTB) begin
|
||||
Br1 <= 18'b0;
|
||||
Br2 <= 18'b0;
|
||||
end else begin
|
||||
if (CEB1) Br1 <= B_muxed;
|
||||
if (CEB2) Br2 <= Br1;
|
||||
end
|
||||
end else if (BREG == 1) begin
|
||||
//initial Br1 = 25'b0;
|
||||
initial Br2 = 25'b0;
|
||||
always @(posedge CLK)
|
||||
if (RSTB) begin
|
||||
Br1 <= 18'b0;
|
||||
Br2 <= 18'b0;
|
||||
end else begin
|
||||
if (CEB1) Br1 <= B_muxed;
|
||||
if (CEB2) Br2 <= B_muxed;
|
||||
end
|
||||
end else begin
|
||||
always @* Br1 <= B_muxed;
|
||||
always @* Br2 <= B_muxed;
|
||||
end
|
||||
|
||||
// C and D registers
|
||||
if (CREG == 1) initial Cr = 48'b0;
|
||||
if (CREG == 1) begin always @(posedge CLK) if (RSTC) Cr <= 48'b0; else if (CEC) Cr <= C; end
|
||||
else always @* Cr <= C;
|
||||
|
||||
if (CREG == 1) initial Dr = 25'b0;
|
||||
if (DREG == 1) begin always @(posedge CLK) if (RSTD) Dr <= 25'b0; else if (CED) Dr <= D; end
|
||||
else always @* Dr <= D;
|
||||
|
||||
// Control registers
|
||||
if (INMODEREG == 1) initial INMODEr = 5'b0;
|
||||
if (INMODEREG == 1) begin always @(posedge CLK) if (RSTINMODE) INMODEr <= 5'b0; else if (CEINMODE) INMODEr <= INMODE; end
|
||||
else always @* INMODEr <= INMODE;
|
||||
if (OPMODEREG == 1) initial OPMODEr = 7'b0;
|
||||
if (OPMODEREG == 1) begin always @(posedge CLK) if (RSTCTRL) OPMODEr <= 7'b0; else if (CECTRL) OPMODEr <= OPMODE; end
|
||||
else always @* OPMODEr <= OPMODE;
|
||||
if (ALUMODEREG == 1) initial ALUMODEr = 4'b0;
|
||||
if (ALUMODEREG == 1) begin always @(posedge CLK) if (RSTALUMODE) ALUMODEr <= 4'b0; else if (CEALUMODE) ALUMODEr <= ALUMODE; end
|
||||
else always @* ALUMODEr <= ALUMODE;
|
||||
if (CARRYINSELREG == 1) initial CARRYINSELr = 3'b0;
|
||||
if (CARRYINSELREG == 1) begin always @(posedge CLK) if (RSTCTRL) CARRYINSELr <= 3'b0; else if (CECTRL) CARRYINSELr <= CARRYINSEL; end
|
||||
else always @* CARRYINSELr <= CARRYINSEL;
|
||||
endgenerate
|
||||
|
||||
// A and B cascade
|
||||
generate
|
||||
if (ACASCREG == 1 && AREG == 2) assign ACOUT = Ar1;
|
||||
else assign ACOUT = Ar2;
|
||||
if (BCASCREG == 1 && BREG == 2) assign BCOUT = Br1;
|
||||
else assign BCOUT = Br2;
|
||||
endgenerate
|
||||
|
||||
// A/D input selection and pre-adder
|
||||
wire signed [29:0] Ar12_muxed = INMODEr[0] ? Ar1 : Ar2;
|
||||
wire signed [24:0] Ar12_gated = INMODEr[1] ? 25'b0 : Ar12_muxed;
|
||||
wire signed [24:0] Dr_gated = INMODEr[2] ? Dr : 25'b0;
|
||||
wire signed [24:0] AD_result = INMODEr[3] ? (Dr_gated - Ar12_gated) : (Dr_gated + Ar12_gated);
|
||||
reg signed [24:0] ADr;
|
||||
|
||||
generate
|
||||
if (ADREG == 1) initial ADr = 25'b0;
|
||||
if (ADREG == 1) begin always @(posedge CLK) if (RSTD) ADr <= 25'b0; else if (CEAD) ADr <= AD_result; end
|
||||
else always @* ADr <= AD_result;
|
||||
endgenerate
|
||||
|
||||
// 25x18 multiplier
|
||||
wire signed [24:0] A_MULT;
|
||||
wire signed [17:0] B_MULT = INMODEr[4] ? Br1 : Br2;
|
||||
generate
|
||||
if (USE_DPORT == "TRUE") assign A_MULT = ADr;
|
||||
else assign A_MULT = Ar12_gated;
|
||||
endgenerate
|
||||
|
||||
wire signed [42:0] M = A_MULT * B_MULT;
|
||||
wire signed [42:0] Mx = (CARRYINSEL == 3'b010) ? 43'bx : M;
|
||||
reg signed [42:0] Mr = 43'b0;
|
||||
|
||||
// Multiplier result register
|
||||
generate
|
||||
if (MREG == 1) begin always @(posedge CLK) if (RSTM) Mr <= 43'b0; else if (CEM) Mr <= Mx; end
|
||||
else always @* Mr <= Mx;
|
||||
endgenerate
|
||||
|
||||
wire signed [42:0] Mrx = (CARRYINSELr == 3'b010) ? 43'bx : Mr;
|
||||
|
||||
// X, Y and Z ALU inputs
|
||||
reg signed [47:0] X, Y, Z;
|
||||
|
||||
always @* begin
|
||||
// X multiplexer
|
||||
case (OPMODEr[1:0])
|
||||
2'b00: X = 48'b0;
|
||||
2'b01: begin X = $signed(Mrx);
|
||||
`ifdef __ICARUS__
|
||||
if (OPMODEr[3:2] != 2'b01) $fatal(1, "OPMODEr[3:2] must be 2'b01 when OPMODEr[1:0] is 2'b01");
|
||||
`endif
|
||||
end
|
||||
2'b10: begin X = P;
|
||||
`ifdef __ICARUS__
|
||||
if (PREG != 1) $fatal(1, "PREG must be 1 when OPMODEr[1:0] is 2'b10");
|
||||
`endif
|
||||
end
|
||||
2'b11: X = $signed({Ar2, Br2});
|
||||
default: X = 48'bx;
|
||||
endcase
|
||||
|
||||
// Y multiplexer
|
||||
case (OPMODEr[3:2])
|
||||
2'b00: Y = 48'b0;
|
||||
2'b01: begin Y = 48'b0; // FIXME: more accurate partial product modelling?
|
||||
`ifdef __ICARUS__
|
||||
if (OPMODEr[1:0] != 2'b01) $fatal(1, "OPMODEr[1:0] must be 2'b01 when OPMODEr[3:2] is 2'b01");
|
||||
`endif
|
||||
end
|
||||
2'b10: Y = {48{1'b1}};
|
||||
2'b11: Y = Cr;
|
||||
default: Y = 48'bx;
|
||||
endcase
|
||||
|
||||
// Z multiplexer
|
||||
case (OPMODEr[6:4])
|
||||
3'b000: Z = 48'b0;
|
||||
3'b001: Z = PCIN;
|
||||
3'b010: begin Z = P;
|
||||
`ifdef __ICARUS__
|
||||
if (PREG != 1) $fatal(1, "PREG must be 1 when OPMODEr[6:4] i0s 3'b010");
|
||||
`endif
|
||||
end
|
||||
3'b011: Z = Cr;
|
||||
3'b100: begin Z = P;
|
||||
`ifdef __ICARUS__
|
||||
if (PREG != 1) $fatal(1, "PREG must be 1 when OPMODEr[6:4] is 3'b100");
|
||||
if (OPMODEr[3:0] != 4'b1000) $fatal(1, "OPMODEr[3:0] must be 4'b1000 when OPMODEr[6:4] i0s 3'b100");
|
||||
`endif
|
||||
end
|
||||
3'b101: Z = $signed(PCIN[47:17]);
|
||||
3'b110: Z = $signed(P[47:17]);
|
||||
default: Z = 48'bx;
|
||||
endcase
|
||||
end
|
||||
|
||||
// Carry in
|
||||
wire A24_xnor_B17d = A_MULT[24] ~^ B_MULT[17];
|
||||
reg CARRYINr = 1'b0, A24_xnor_B17 = 1'b0;
|
||||
generate
|
||||
if (CARRYINREG == 1) begin always @(posedge CLK) if (RSTALLCARRYIN) CARRYINr <= 1'b0; else if (CECARRYIN) CARRYINr <= CARRYIN; end
|
||||
else always @* CARRYINr = CARRYIN;
|
||||
|
||||
if (MREG == 1) begin always @(posedge CLK) if (RSTALLCARRYIN) A24_xnor_B17 <= 1'b0; else if (CEM) A24_xnor_B17 <= A24_xnor_B17d; end
|
||||
else always @* A24_xnor_B17 = A24_xnor_B17d;
|
||||
endgenerate
|
||||
|
||||
reg cin_muxed;
|
||||
|
||||
always @(*) begin
|
||||
case (CARRYINSELr)
|
||||
3'b000: cin_muxed = CARRYINr;
|
||||
3'b001: cin_muxed = ~PCIN[47];
|
||||
3'b010: cin_muxed = CARRYCASCIN;
|
||||
3'b011: cin_muxed = PCIN[47];
|
||||
3'b100: cin_muxed = CARRYCASCOUT;
|
||||
3'b101: cin_muxed = ~P[47];
|
||||
3'b110: cin_muxed = A24_xnor_B17;
|
||||
3'b111: cin_muxed = P[47];
|
||||
default: cin_muxed = 1'bx;
|
||||
endcase
|
||||
end
|
||||
|
||||
wire alu_cin = (ALUMODEr[3] || ALUMODEr[2]) ? 1'b0 : cin_muxed;
|
||||
|
||||
// ALU core
|
||||
wire [47:0] Z_muxinv = ALUMODEr[0] ? ~Z : Z;
|
||||
wire [47:0] xor_xyz = X ^ Y ^ Z_muxinv;
|
||||
wire [47:0] maj_xyz = (X & Y) | (X & Z_muxinv) | (Y & Z_muxinv);
|
||||
|
||||
wire [47:0] xor_xyz_muxed = ALUMODEr[3] ? maj_xyz : xor_xyz;
|
||||
wire [47:0] maj_xyz_gated = ALUMODEr[2] ? 48'b0 : maj_xyz;
|
||||
|
||||
wire [48:0] maj_xyz_simd_gated;
|
||||
wire [3:0] int_carry_in, int_carry_out, ext_carry_out;
|
||||
wire [47:0] alu_sum;
|
||||
assign int_carry_in[0] = 1'b0;
|
||||
wire [3:0] carryout_reset;
|
||||
|
||||
generate
|
||||
if (USE_SIMD == "FOUR12") begin
|
||||
assign maj_xyz_simd_gated = {
|
||||
maj_xyz_gated[47:36],
|
||||
1'b0, maj_xyz_gated[34:24],
|
||||
1'b0, maj_xyz_gated[22:12],
|
||||
1'b0, maj_xyz_gated[10:0],
|
||||
alu_cin
|
||||
};
|
||||
assign int_carry_in[3:1] = 3'b000;
|
||||
assign ext_carry_out = {
|
||||
int_carry_out[3],
|
||||
maj_xyz_gated[35] ^ int_carry_out[2],
|
||||
maj_xyz_gated[23] ^ int_carry_out[1],
|
||||
maj_xyz_gated[11] ^ int_carry_out[0]
|
||||
};
|
||||
assign carryout_reset = 4'b0000;
|
||||
end else if (USE_SIMD == "TWO24") begin
|
||||
assign maj_xyz_simd_gated = {
|
||||
maj_xyz_gated[47:24],
|
||||
1'b0, maj_xyz_gated[22:0],
|
||||
alu_cin
|
||||
};
|
||||
assign int_carry_in[3:1] = {int_carry_out[2], 1'b0, int_carry_out[0]};
|
||||
assign ext_carry_out = {
|
||||
int_carry_out[3],
|
||||
1'bx,
|
||||
maj_xyz_gated[23] ^ int_carry_out[1],
|
||||
1'bx
|
||||
};
|
||||
assign carryout_reset = 4'b0x0x;
|
||||
end else begin
|
||||
assign maj_xyz_simd_gated = {maj_xyz_gated, alu_cin};
|
||||
assign int_carry_in[3:1] = int_carry_out[2:0];
|
||||
assign ext_carry_out = {
|
||||
int_carry_out[3],
|
||||
3'bxxx
|
||||
};
|
||||
assign carryout_reset = 4'b0xxx;
|
||||
end
|
||||
|
||||
genvar i;
|
||||
for (i = 0; i < 4; i = i + 1)
|
||||
assign {int_carry_out[i], alu_sum[i*12 +: 12]} = {1'b0, maj_xyz_simd_gated[i*12 +: ((i == 3) ? 13 : 12)]}
|
||||
+ xor_xyz_muxed[i*12 +: 12] + int_carry_in[i];
|
||||
endgenerate
|
||||
|
||||
wire signed [47:0] Pd = ALUMODEr[1] ? ~alu_sum : alu_sum;
|
||||
wire [3:0] CARRYOUTd = (OPMODEr[3:0] == 4'b0101 || ALUMODEr[3:2] != 2'b00) ? 4'bxxxx :
|
||||
((ALUMODEr[0] & ALUMODEr[1]) ? ~ext_carry_out : ext_carry_out);
|
||||
wire CARRYCASCOUTd = ext_carry_out[3];
|
||||
wire MULTSIGNOUTd = Mrx[42];
|
||||
|
||||
generate
|
||||
if (PREG == 1) begin
|
||||
initial P = 48'b0;
|
||||
initial CARRYOUT = carryout_reset;
|
||||
initial CARRYCASCOUT = 1'b0;
|
||||
initial MULTSIGNOUT = 1'b0;
|
||||
always @(posedge CLK)
|
||||
if (RSTP) begin
|
||||
P <= 48'b0;
|
||||
CARRYOUT <= carryout_reset;
|
||||
CARRYCASCOUT <= 1'b0;
|
||||
MULTSIGNOUT <= 1'b0;
|
||||
end else if (CEP) begin
|
||||
P <= Pd;
|
||||
CARRYOUT <= CARRYOUTd;
|
||||
CARRYCASCOUT <= CARRYCASCOUTd;
|
||||
MULTSIGNOUT <= MULTSIGNOUTd;
|
||||
end
|
||||
end else begin
|
||||
always @* begin
|
||||
P = Pd;
|
||||
CARRYOUT = CARRYOUTd;
|
||||
CARRYCASCOUT = CARRYCASCOUTd;
|
||||
MULTSIGNOUT = MULTSIGNOUTd;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign PCOUT = P;
|
||||
|
||||
generate
|
||||
wire PATTERNDETECTd, PATTERNBDETECTd;
|
||||
|
||||
if (USE_PATTERN_DETECT == "PATDET") begin
|
||||
// TODO: Support SEL_PATTERN != "PATTERN" and SEL_MASK != "MASK
|
||||
assign PATTERNDETECTd = &(~(Pd ^ PATTERN) | MASK);
|
||||
assign PATTERNBDETECTd = &((Pd ^ PATTERN) | MASK);
|
||||
end else begin
|
||||
assign PATTERNDETECTd = 1'b1;
|
||||
assign PATTERNBDETECTd = 1'b1;
|
||||
end
|
||||
|
||||
if (PREG == 1) begin
|
||||
reg PATTERNDETECTPAST, PATTERNBDETECTPAST;
|
||||
initial PATTERNDETECT = 1'b0;
|
||||
initial PATTERNBDETECT = 1'b0;
|
||||
initial PATTERNDETECTPAST = 1'b0;
|
||||
initial PATTERNBDETECTPAST = 1'b0;
|
||||
always @(posedge CLK)
|
||||
if (RSTP) begin
|
||||
PATTERNDETECT <= 1'b0;
|
||||
PATTERNBDETECT <= 1'b0;
|
||||
PATTERNDETECTPAST <= 1'b0;
|
||||
PATTERNBDETECTPAST <= 1'b0;
|
||||
end else if (CEP) begin
|
||||
PATTERNDETECT <= PATTERNDETECTd;
|
||||
PATTERNBDETECT <= PATTERNBDETECTd;
|
||||
PATTERNDETECTPAST <= PATTERNDETECT;
|
||||
PATTERNBDETECTPAST <= PATTERNBDETECT;
|
||||
end
|
||||
assign OVERFLOW = &{PATTERNDETECTPAST, ~PATTERNBDETECT, ~PATTERNDETECT};
|
||||
assign UNDERFLOW = &{PATTERNBDETECTPAST, ~PATTERNBDETECT, ~PATTERNDETECT};
|
||||
end else begin
|
||||
always @* begin
|
||||
PATTERNDETECT = PATTERNDETECTd;
|
||||
PATTERNBDETECT = PATTERNBDETECTd;
|
||||
end
|
||||
assign OVERFLOW = 1'bx, UNDERFLOW = 1'bx;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -5,6 +5,7 @@ from io import StringIO
|
|||
from enum import Enum, auto
|
||||
import os.path
|
||||
import sys
|
||||
import re
|
||||
|
||||
|
||||
class Cell:
|
||||
|
@ -14,9 +15,258 @@ class Cell:
|
|||
self.port_attrs = port_attrs
|
||||
|
||||
|
||||
CELLS = [
|
||||
# Design elements types listed in Xilinx UG953
|
||||
Cell('BSCANE2', keep=True),
|
||||
XC6S_CELLS = [
|
||||
# Design elements types listed in Xilinx UG615.
|
||||
|
||||
# Advanced.
|
||||
Cell('MCB'),
|
||||
Cell('PCIE_A1'),
|
||||
|
||||
# Arithmetic functions.
|
||||
Cell('DSP48A1', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
|
||||
# Clock components.
|
||||
# Cell('BUFG', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFGCE', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFGCE_1', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFGMUX', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFGMUX_1', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFH', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFIO2', port_attrs={'IOCLK': ['clkbuf_driver'], 'DIVCLK': ['clkbuf_driver']}),
|
||||
Cell('BUFIO2_2CLK', port_attrs={'IOCLK': ['clkbuf_driver'], 'DIVCLK': ['clkbuf_driver']}),
|
||||
Cell('BUFIO2FB', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFPLL_MCB', port_attrs={'IOCLK0': ['clkbuf_driver'], 'IOCLK1': ['clkbuf_driver']}),
|
||||
Cell('DCM_CLKGEN'),
|
||||
Cell('DCM_SP'),
|
||||
Cell('PLL_BASE'),
|
||||
|
||||
# Config/BSCAN components.
|
||||
Cell('BSCAN_SPARTAN6', keep=True),
|
||||
Cell('DNA_PORT'),
|
||||
Cell('ICAP_SPARTAN6', keep=True),
|
||||
Cell('POST_CRC_INTERNAL'),
|
||||
Cell('STARTUP_SPARTAN6', keep=True),
|
||||
Cell('SUSPEND_SYNC', keep=True),
|
||||
|
||||
# I/O components.
|
||||
Cell('GTPA1_DUAL'),
|
||||
# Cell('IBUF', port_attrs={'I': ['iopad_external_pin']}),
|
||||
Cell('IBUFDS', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('IBUFDS_DIFF_OUT', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
# Cell('IBUFG', port_attrs={'I': ['iopad_external_pin']}),
|
||||
Cell('IBUFGDS', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('IBUFGDS_DIFF_OUT', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('IOBUF', port_attrs={'IO': ['iopad_external_pin']}),
|
||||
Cell('IOBUFDS', port_attrs={'IO': ['iopad_external_pin']}),
|
||||
Cell('IODELAY2', port_attrs={'IOCLK0': ['clkbuf_sink'], 'IOCLK1': ['clkbuf_sink'], 'CLK': ['clkbuf_sink']}),
|
||||
Cell('IODRP2', port_attrs={'IOCLK0': ['clkbuf_sink'], 'IOCLK1': ['clkbuf_sink'], 'CLK': ['clkbuf_sink']}),
|
||||
Cell('IODRP2_MCB', port_attrs={'IOCLK0': ['clkbuf_sink'], 'IOCLK1': ['clkbuf_sink'], 'CLK': ['clkbuf_sink']}),
|
||||
Cell('ISERDES2', port_attrs={
|
||||
'CLK0': ['clkbuf_sink'],
|
||||
'CLK1': ['clkbuf_sink'],
|
||||
'CLKDIV': ['clkbuf_sink'],
|
||||
}),
|
||||
Cell('KEEPER'),
|
||||
# Cell('OBUF', port_attrs={'O': ['iopad_external_pin']}),
|
||||
Cell('OBUFDS', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
|
||||
Cell('OBUFT', port_attrs={'O': ['iopad_external_pin']}),
|
||||
Cell('OBUFTDS', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
|
||||
Cell('OSERDES2', port_attrs={
|
||||
'CLK0': ['clkbuf_sink'],
|
||||
'CLK1': ['clkbuf_sink'],
|
||||
'CLKDIV': ['clkbuf_sink'],
|
||||
}),
|
||||
Cell('PULLDOWN'),
|
||||
Cell('PULLUP'),
|
||||
|
||||
# RAM/ROM.
|
||||
#Cell('RAM128X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# NOTE: not in the official library guide!
|
||||
Cell('RAM128X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM256X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM32M', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
#Cell('RAM32X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM32X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM32X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM32X2S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM64M', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
#Cell('RAM64X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM64X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM64X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# NOTE: not in the official library guide!
|
||||
Cell('RAM64X2S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAMB8BWER', port_attrs={'CLKAWRCLK': ['clkbuf_sink'], 'CLKBRDCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAMB16BWER', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('ROM128X1'),
|
||||
Cell('ROM256X1'),
|
||||
Cell('ROM32X1'),
|
||||
Cell('ROM64X1'),
|
||||
|
||||
# Registers/latches.
|
||||
# Cell('FDCE'),
|
||||
# Cell('FDPE'),
|
||||
# Cell('FDRE'),
|
||||
# Cell('FDSE'),
|
||||
Cell('IDDR2', port_attrs={'C0': ['clkbuf_sink'], 'C1': ['clkbuf_sink']}),
|
||||
# Cell('LDCE'),
|
||||
# Cell('LDPE'),
|
||||
Cell('ODDR2', port_attrs={'C0': ['clkbuf_sink'], 'C1': ['clkbuf_sink']}),
|
||||
|
||||
# Slice/CLB primitives.
|
||||
# Cell('CARRY4'),
|
||||
Cell('CFGLUT5', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
# Cell('LUT1'),
|
||||
# Cell('LUT2'),
|
||||
# Cell('LUT3'),
|
||||
# Cell('LUT4'),
|
||||
# Cell('LUT5'),
|
||||
# Cell('LUT6'),
|
||||
# Cell('LUT6_2'),
|
||||
# Cell('MUXF7'),
|
||||
# Cell('MUXF8'),
|
||||
# Cell('SRL16E', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
# Cell('SRLC32E', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
]
|
||||
|
||||
|
||||
XC6V_CELLS = [
|
||||
# Design elements types listed in Xilinx UG623.
|
||||
|
||||
# Advanced.
|
||||
Cell('PCIE_2_0'),
|
||||
Cell('SYSMON'),
|
||||
|
||||
# Arithmetic functions.
|
||||
#Cell('DSP48E1', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
|
||||
# Clock components.
|
||||
# Cell('BUFG', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFGCE', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFGCE_1', port_attrs={'O': ['clkbuf_driver']}),
|
||||
#Cell('BUFGCTRL', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFGMUX', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFGMUX_1', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFGMUX_CTRL', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFH', port_attrs={'O': ['clkbuf_driver']}),
|
||||
#Cell('BUFHCE', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFIO', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFIODQS', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFR', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('IBUFDS_GTXE1', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('MMCM_ADV'),
|
||||
Cell('MMCM_BASE'),
|
||||
|
||||
# Config/BSCAN components.
|
||||
Cell('BSCAN_VIRTEX6', keep=True),
|
||||
Cell('CAPTURE_VIRTEX6', keep=True),
|
||||
Cell('DNA_PORT'),
|
||||
Cell('EFUSE_USR'),
|
||||
Cell('FRAME_ECC_VIRTEX6'),
|
||||
Cell('ICAP_VIRTEX6', keep=True),
|
||||
Cell('STARTUP_VIRTEX6', keep=True),
|
||||
Cell('USR_ACCESS_VIRTEX6'),
|
||||
|
||||
# I/O components.
|
||||
Cell('DCIRESET', keep=True),
|
||||
Cell('GTHE1_QUAD'),
|
||||
Cell('GTXE1'),
|
||||
# Cell('IBUF', port_attrs={'I': ['iopad_external_pin']}),
|
||||
Cell('IBUFDS', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('IBUFDS_DIFF_OUT', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('IBUFDS_GTHE1', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
# Cell('IBUFG', port_attrs={'I': ['iopad_external_pin']}),
|
||||
Cell('IBUFGDS', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('IBUFGDS_DIFF_OUT', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('IDELAYCTRL', keep=True, port_attrs={'REFCLK': ['clkbuf_sink']}),
|
||||
Cell('IOBUF', port_attrs={'IO': ['iopad_external_pin']}),
|
||||
Cell('IOBUFDS', port_attrs={'IO': ['iopad_external_pin']}),
|
||||
Cell('IODELAYE1', port_attrs={'C': ['clkbuf_sink']}),
|
||||
Cell('ISERDESE1', port_attrs={
|
||||
'CLK': ['clkbuf_sink'],
|
||||
'CLKB': ['clkbuf_sink'],
|
||||
'OCLK': ['clkbuf_sink'],
|
||||
'CLKDIV': ['clkbuf_sink'],
|
||||
}),
|
||||
Cell('KEEPER'),
|
||||
# Cell('OBUF', port_attrs={'O': ['iopad_external_pin']}),
|
||||
Cell('OBUFDS', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
|
||||
Cell('OBUFT', port_attrs={'O': ['iopad_external_pin']}),
|
||||
Cell('OBUFTDS', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
|
||||
Cell('OSERDESE1', port_attrs={'CLK': ['clkbuf_sink'], 'CLKDIV': ['clkbuf_sink']}),
|
||||
Cell('PULLDOWN'),
|
||||
Cell('PULLUP'),
|
||||
Cell('TEMAC_SINGLE'),
|
||||
|
||||
# RAM/ROM.
|
||||
Cell('FIFO18E1', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
|
||||
Cell('FIFO36E1', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
|
||||
#Cell('RAM128X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM128X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM256X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM32M', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
#Cell('RAM32X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM32X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM32X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM32X2S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM64M', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
#Cell('RAM64X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM64X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM64X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# NOTE: not in the official library guide!
|
||||
Cell('RAM64X2S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAMB18E1', port_attrs={'CLKARDCLK': ['clkbuf_sink'], 'CLKBWRCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAMB36E1', port_attrs={'CLKARDCLK': ['clkbuf_sink'], 'CLKBWRCLK': ['clkbuf_sink']}),
|
||||
Cell('ROM128X1'),
|
||||
Cell('ROM256X1'),
|
||||
Cell('ROM32X1'),
|
||||
Cell('ROM64X1'),
|
||||
|
||||
# Registers/latches.
|
||||
# Cell('FDCE'),
|
||||
# Cell('FDPE'),
|
||||
# Cell('FDRE'),
|
||||
# Cell('FDSE'),
|
||||
Cell('IDDR', port_attrs={'C': ['clkbuf_sink']}),
|
||||
Cell('IDDR_2CLK', port_attrs={'C': ['clkbuf_sink'], 'CB': ['clkbuf_sink']}),
|
||||
Cell('LDCE'),
|
||||
Cell('LDPE'),
|
||||
Cell('ODDR', port_attrs={'C': ['clkbuf_sink']}),
|
||||
|
||||
# Slice/CLB primitives.
|
||||
# Cell('CARRY4'),
|
||||
Cell('CFGLUT5', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
# Cell('LUT1'),
|
||||
# Cell('LUT2'),
|
||||
# Cell('LUT3'),
|
||||
# Cell('LUT4'),
|
||||
# Cell('LUT5'),
|
||||
# Cell('LUT6'),
|
||||
# Cell('LUT6_2'),
|
||||
# Cell('MUXF7'),
|
||||
# Cell('MUXF8'),
|
||||
# Cell('SRL16E', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
# Cell('SRLC32E', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
]
|
||||
|
||||
|
||||
XC7_CELLS = [
|
||||
# Design elements types listed in Xilinx UG953.
|
||||
|
||||
# Advanced.
|
||||
Cell('GTHE2_CHANNEL'),
|
||||
Cell('GTHE2_COMMON'),
|
||||
Cell('GTPE2_CHANNEL'),
|
||||
Cell('GTPE2_COMMON'),
|
||||
Cell('GTXE2_CHANNEL'),
|
||||
Cell('GTXE2_COMMON'),
|
||||
Cell('PCIE_2_1'),
|
||||
Cell('PCIE_3_0'),
|
||||
Cell('XADC'),
|
||||
|
||||
# Arithmetic functions.
|
||||
#Cell('DSP48E1', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
|
||||
# Clock components.
|
||||
# Cell('BUFG', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFGCE', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFGCE_1', port_attrs={'O': ['clkbuf_driver']}),
|
||||
|
@ -30,26 +280,23 @@ CELLS = [
|
|||
Cell('BUFMR', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFMRCE', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFR', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('MMCME2_ADV'),
|
||||
Cell('MMCME2_BASE'),
|
||||
Cell('PLLE2_ADV'),
|
||||
Cell('PLLE2_BASE'),
|
||||
|
||||
# Config/BSCAN components.
|
||||
Cell('BSCANE2', keep=True),
|
||||
Cell('CAPTUREE2', keep=True),
|
||||
# Cell('CARRY4'),
|
||||
Cell('CFGLUT5', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
Cell('DCIRESET', keep=True),
|
||||
Cell('DNA_PORT'),
|
||||
Cell('DSP48E1', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
Cell('EFUSE_USR'),
|
||||
# Cell('FDCE'),
|
||||
# Cell('FDPE'),
|
||||
# Cell('FDRE'),
|
||||
# Cell('FDSE'),
|
||||
Cell('FIFO18E1', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
|
||||
Cell('FIFO36E1', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
|
||||
Cell('FRAME_ECCE2'),
|
||||
Cell('GTHE2_CHANNEL'),
|
||||
Cell('GTHE2_COMMON'),
|
||||
Cell('GTPE2_CHANNEL'),
|
||||
Cell('GTPE2_COMMON'),
|
||||
Cell('GTXE2_CHANNEL'),
|
||||
Cell('GTXE2_COMMON'),
|
||||
Cell('ICAPE2', keep=True),
|
||||
Cell('STARTUPE2', keep=True),
|
||||
Cell('USR_ACCESSE2'),
|
||||
|
||||
# I/O components.
|
||||
Cell('DCIRESET', keep=True),
|
||||
# Cell('IBUF', port_attrs={'I': ['iopad_external_pin']}),
|
||||
Cell('IBUF_IBUFDISABLE', port_attrs={'I': ['iopad_external_pin']}),
|
||||
Cell('IBUF_INTERMDISABLE', port_attrs={'I': ['iopad_external_pin']}),
|
||||
|
@ -60,12 +307,9 @@ CELLS = [
|
|||
Cell('IBUFDS_GTE2', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('IBUFDS_IBUFDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('IBUFDS_INTERMDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('IBUFG', port_attrs={'I': ['iopad_external_pin']}),
|
||||
# Cell('IBUFG', port_attrs={'I': ['iopad_external_pin']}),
|
||||
Cell('IBUFGDS', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('IBUFGDS_DIFF_OUT', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('ICAPE2', keep=True),
|
||||
Cell('IDDR', port_attrs={'C': ['clkbuf_sink']}),
|
||||
Cell('IDDR_2CLK', port_attrs={'C': ['clkbuf_sink'], 'CB': ['clkbuf_sink']}),
|
||||
Cell('IDELAYCTRL', keep=True, port_attrs={'REFCLK': ['clkbuf_sink']}),
|
||||
Cell('IDELAYE2', port_attrs={'C': ['clkbuf_sink']}),
|
||||
Cell('IN_FIFO', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
|
||||
|
@ -77,6 +321,7 @@ CELLS = [
|
|||
Cell('IOBUFDS_DIFF_OUT', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
|
||||
Cell('IOBUFDS_DIFF_OUT_DCIEN', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
|
||||
Cell('IOBUFDS_DIFF_OUT_INTERMDISABLE', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
|
||||
Cell('IOBUFDS_INTERMDISABLE', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
|
||||
Cell('ISERDESE2', port_attrs={
|
||||
'CLK': ['clkbuf_sink'],
|
||||
'CLKB': ['clkbuf_sink'],
|
||||
|
@ -86,24 +331,10 @@ CELLS = [
|
|||
'CLKDIVP': ['clkbuf_sink'],
|
||||
}),
|
||||
Cell('KEEPER'),
|
||||
Cell('LDCE'),
|
||||
Cell('LDPE'),
|
||||
# Cell('LUT1'),
|
||||
# Cell('LUT2'),
|
||||
# Cell('LUT3'),
|
||||
# Cell('LUT4'),
|
||||
# Cell('LUT5'),
|
||||
# Cell('LUT6'),
|
||||
#Cell('LUT6_2'),
|
||||
Cell('MMCME2_ADV'),
|
||||
Cell('MMCME2_BASE'),
|
||||
# Cell('MUXF7'),
|
||||
# Cell('MUXF8'),
|
||||
# Cell('OBUF', port_attrs={'O': ['iopad_external_pin']}),
|
||||
Cell('OBUFDS', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
|
||||
Cell('OBUFT', port_attrs={'O': ['iopad_external_pin']}),
|
||||
Cell('OBUFTDS', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
|
||||
Cell('ODDR', port_attrs={'C': ['clkbuf_sink']}),
|
||||
Cell('ODELAYE2', port_attrs={'C': ['clkbuf_sink']}),
|
||||
Cell('OSERDESE2', port_attrs={'CLK': ['clkbuf_sink'], 'CLKDIV': ['clkbuf_sink']}),
|
||||
Cell('OUT_FIFO', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
|
||||
|
@ -113,11 +344,12 @@ CELLS = [
|
|||
Cell('PHASER_OUT_PHY'),
|
||||
Cell('PHASER_REF'),
|
||||
Cell('PHY_CONTROL'),
|
||||
Cell('PLLE2_ADV'),
|
||||
Cell('PLLE2_BASE'),
|
||||
Cell('PS7', keep=True),
|
||||
Cell('PULLDOWN'),
|
||||
Cell('PULLUP'),
|
||||
|
||||
# RAM/ROM.
|
||||
Cell('FIFO18E1', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
|
||||
Cell('FIFO36E1', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
|
||||
#Cell('RAM128X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM128X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM256X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
|
@ -130,6 +362,7 @@ CELLS = [
|
|||
#Cell('RAM64X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM64X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM64X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# NOTE: not in the official library guide!
|
||||
Cell('RAM64X2S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAMB18E1', port_attrs={'CLKARDCLK': ['clkbuf_sink'], 'CLKBWRCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAMB36E1', port_attrs={'CLKARDCLK': ['clkbuf_sink'], 'CLKBWRCLK': ['clkbuf_sink']}),
|
||||
|
@ -137,13 +370,207 @@ CELLS = [
|
|||
Cell('ROM256X1'),
|
||||
Cell('ROM32X1'),
|
||||
Cell('ROM64X1'),
|
||||
#Cell('SRL16E', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
#Cell('SRLC32E', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
Cell('STARTUPE2', keep=True),
|
||||
Cell('USR_ACCESSE2'),
|
||||
Cell('XADC'),
|
||||
|
||||
# Registers/latches.
|
||||
# Cell('FDCE'),
|
||||
# Cell('FDPE'),
|
||||
# Cell('FDRE'),
|
||||
# Cell('FDSE'),
|
||||
Cell('IDDR', port_attrs={'C': ['clkbuf_sink']}),
|
||||
Cell('IDDR_2CLK', port_attrs={'C': ['clkbuf_sink'], 'CB': ['clkbuf_sink']}),
|
||||
Cell('LDCE'),
|
||||
Cell('LDPE'),
|
||||
Cell('ODDR', port_attrs={'C': ['clkbuf_sink']}),
|
||||
|
||||
# Slice/CLB primitives.
|
||||
# Cell('CARRY4'),
|
||||
Cell('CFGLUT5', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
# Cell('LUT1'),
|
||||
# Cell('LUT2'),
|
||||
# Cell('LUT3'),
|
||||
# Cell('LUT4'),
|
||||
# Cell('LUT5'),
|
||||
# Cell('LUT6'),
|
||||
# Cell('LUT6_2'),
|
||||
# Cell('MUXF7'),
|
||||
# Cell('MUXF8'),
|
||||
# Cell('SRL16E', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
# Cell('SRLC32E', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
|
||||
# NOTE: not in the official library guide!
|
||||
Cell('PS7', keep=True),
|
||||
]
|
||||
|
||||
|
||||
XCU_CELLS = [
|
||||
# Design elements types listed in Xilinx UG974.
|
||||
|
||||
# Advanced.
|
||||
Cell('CMAC'),
|
||||
Cell('CMACE4'),
|
||||
Cell('GTHE3_CHANNEL'),
|
||||
Cell('GTHE3_COMMON'),
|
||||
Cell('GTHE4_CHANNEL'),
|
||||
Cell('GTHE4_COMMON'),
|
||||
Cell('GTYE3_CHANNEL'),
|
||||
Cell('GTYE3_COMMON'),
|
||||
Cell('GTYE4_CHANNEL'),
|
||||
Cell('GTYE4_COMMON'),
|
||||
Cell('IBUFDS_GTE3', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('IBUFDS_GTE4', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('ILKN'),
|
||||
Cell('ILKNE4'),
|
||||
Cell('OBUFDS_GTE3', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
|
||||
Cell('OBUFDS_GTE3_ADV', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
|
||||
Cell('OBUFDS_GTE4', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
|
||||
Cell('OBUFDS_GTE4_ADV', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
|
||||
Cell('PCIE40E4'),
|
||||
Cell('PCIE_3_1'),
|
||||
Cell('SYSMONE1'),
|
||||
Cell('SYSMONE4'),
|
||||
|
||||
# Arithmetic functions.
|
||||
Cell('DSP48E2', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
|
||||
# Blockram.
|
||||
Cell('FIFO18E2', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
|
||||
Cell('FIFO36E2', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
|
||||
Cell('RAMB18E2', port_attrs={'CLKARDCLK': ['clkbuf_sink'], 'CLKBWRCLK': ['clkbuf_sink']}),
|
||||
Cell('RAMB36E2', port_attrs={'CLKARDCLK': ['clkbuf_sink'], 'CLKBWRCLK': ['clkbuf_sink']}),
|
||||
Cell('URAM288', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
Cell('URAM288_BASE', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
|
||||
# CLB.
|
||||
# Cell('LUT6_2'),
|
||||
#Cell('RAM128X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM128X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM256X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM256X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM32M', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM32M16', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
#Cell('RAM32X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM32X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM512X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM64M', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM64M8', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
#Cell('RAM64X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM64X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('AND2B1L'),
|
||||
Cell('CARRY8'),
|
||||
Cell('CFGLUT5', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
# Cell('LUT1'),
|
||||
# Cell('LUT2'),
|
||||
# Cell('LUT3'),
|
||||
# Cell('LUT4'),
|
||||
# Cell('LUT5'),
|
||||
# Cell('LUT6'),
|
||||
# Cell('MUXF7'),
|
||||
# Cell('MUXF8'),
|
||||
Cell('MUXF9'),
|
||||
Cell('OR2L'),
|
||||
# Cell('SRL16E', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
# Cell('SRLC32E', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
|
||||
# Clock.
|
||||
# Cell('BUFG', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFG_GT', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFG_GT_SYNC'),
|
||||
Cell('BUFG_PS', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFGCE', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFGCE_1', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFGCE_DIV', port_attrs={'O': ['clkbuf_driver']}),
|
||||
#Cell('BUFGCTRL', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFGMUX', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFGMUX_1', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFGMUX_CTRL', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('MMCME3_ADV'),
|
||||
Cell('MMCME3_BASE'),
|
||||
Cell('MMCME4_ADV'),
|
||||
Cell('MMCME4_BASE'),
|
||||
Cell('PLLE3_ADV'),
|
||||
Cell('PLLE3_BASE'),
|
||||
Cell('PLLE4_ADV'),
|
||||
Cell('PLLE4_BASE'),
|
||||
|
||||
# Configuration.
|
||||
Cell('BSCANE2', keep=True),
|
||||
Cell('DNA_PORTE2'),
|
||||
Cell('EFUSE_USR'),
|
||||
Cell('FRAME_ECCE3'),
|
||||
Cell('ICAPE3', keep=True),
|
||||
Cell('MASTER_JTAG', keep=True),
|
||||
Cell('STARTUPE3', keep=True),
|
||||
Cell('USR_ACCESSE2'),
|
||||
|
||||
# I/O.
|
||||
Cell('BITSLICE_CONTROL', keep=True),
|
||||
Cell('DCIRESET', keep=True),
|
||||
Cell('HPIO_VREF'),
|
||||
# XXX
|
||||
# Cell('IBUF', port_attrs={'I': ['iopad_external_pin']}),
|
||||
Cell('IBUF_ANALOG', port_attrs={'I': ['iopad_external_pin']}),
|
||||
Cell('IBUF_IBUFDISABLE', port_attrs={'I': ['iopad_external_pin']}),
|
||||
Cell('IBUF_INTERMDISABLE', port_attrs={'I': ['iopad_external_pin']}),
|
||||
Cell('IBUFDS', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('IBUFDS_DIFF_OUT', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('IBUFDS_DIFF_OUT_IBUFDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('IBUFDS_DIFF_OUT_INTERMDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('IBUFDS_DPHY', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('IBUFDS_IBUFDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('IBUFDS_INTERMDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('IBUFDSE3', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('IBUFE3', port_attrs={'I': ['iopad_external_pin']}),
|
||||
Cell('IDELAYCTRL', keep=True, port_attrs={'REFCLK': ['clkbuf_sink']}),
|
||||
Cell('IDELAYE3', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
Cell('IOBUF', port_attrs={'IO': ['iopad_external_pin']}),
|
||||
Cell('IOBUF_DCIEN', port_attrs={'IO': ['iopad_external_pin']}),
|
||||
Cell('IOBUF_INTERMDISABLE', port_attrs={'IO': ['iopad_external_pin']}),
|
||||
Cell('IOBUFDS', port_attrs={'IO': ['iopad_external_pin']}),
|
||||
Cell('IOBUFDS_DCIEN', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
|
||||
Cell('IOBUFDS_DIFF_OUT', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
|
||||
Cell('IOBUFDS_DIFF_OUT_DCIEN', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
|
||||
Cell('IOBUFDS_DIFF_OUT_INTERMDISABLE', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
|
||||
Cell('IOBUFDS_INTERMDISABLE', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
|
||||
Cell('IOBUFDSE3', port_attrs={'IO': ['iopad_external_pin']}),
|
||||
Cell('IOBUFE3', port_attrs={'IO': ['iopad_external_pin']}),
|
||||
Cell('ISERDESE3', port_attrs={
|
||||
'CLK': ['clkbuf_sink'],
|
||||
'CLK_B': ['clkbuf_sink'],
|
||||
'FIFO_RD_CLK': ['clkbuf_sink'],
|
||||
'CLKDIV': ['clkbuf_sink'],
|
||||
}),
|
||||
Cell('KEEPER'),
|
||||
# Cell('OBUF', port_attrs={'O': ['iopad_external_pin']}),
|
||||
Cell('OBUFDS', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
|
||||
Cell('OBUFDS_DPHY', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
|
||||
Cell('OBUFT', port_attrs={'O': ['iopad_external_pin']}),
|
||||
Cell('OBUFTDS', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
|
||||
Cell('ODELAYE3', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
Cell('OSERDESE3', port_attrs={'CLK': ['clkbuf_sink'], 'CLKDIV': ['clkbuf_sink']}),
|
||||
Cell('PULLDOWN'),
|
||||
Cell('PULLUP'),
|
||||
Cell('RIU_OR'),
|
||||
Cell('RX_BITSLICE'),
|
||||
Cell('RXTX_BITSLICE'),
|
||||
Cell('TX_BITSLICE'),
|
||||
Cell('TX_BITSLICE_TRI'),
|
||||
|
||||
# Registers.
|
||||
# Cell('FDCE'),
|
||||
# Cell('FDPE'),
|
||||
# Cell('FDRE'),
|
||||
# Cell('FDSE'),
|
||||
Cell('HARD_SYNC', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
Cell('IDDRE1', port_attrs={'C': ['clkbuf_sink'], 'CB': ['clkbuf_sink']}),
|
||||
Cell('LDCE'),
|
||||
Cell('LDPE'),
|
||||
Cell('ODDRE1', port_attrs={'C': ['clkbuf_sink']}),
|
||||
|
||||
# NOTE: not in the official library guide!
|
||||
Cell('PS8', keep=True),
|
||||
]
|
||||
|
||||
|
||||
class State(Enum):
|
||||
OUTSIDE = auto()
|
||||
IN_MODULE = auto()
|
||||
|
@ -159,6 +586,8 @@ def xtract_cell_decl(cell, dirs, outf):
|
|||
state = State.OUTSIDE
|
||||
found = False
|
||||
# Probably the most horrible Verilog "parser" ever written.
|
||||
module_ports = []
|
||||
invertible_ports = set()
|
||||
for l in f:
|
||||
l = l.partition('//')[0]
|
||||
l = l.strip()
|
||||
|
@ -193,6 +622,15 @@ def xtract_cell_decl(cell, dirs, outf):
|
|||
state = State.IN_MODULE
|
||||
elif l == 'endmodule':
|
||||
if state == State.IN_MODULE:
|
||||
for kind, rng, port in module_ports:
|
||||
for attr in cell.port_attrs.get(port, []):
|
||||
outf.write(' (* {} *)\n'.format(attr))
|
||||
if port in invertible_ports:
|
||||
outf.write(' (* invertible_pin = "IS_{}_INVERTED" *)\n'.format(port))
|
||||
if rng is None:
|
||||
outf.write(' {} {};\n'.format(kind, port))
|
||||
else:
|
||||
outf.write(' {} {} {};\n'.format(kind, rng, port))
|
||||
outf.write(l + '\n')
|
||||
outf.write('\n')
|
||||
elif state != State.IN_OTHER_MODULE:
|
||||
|
@ -208,9 +646,11 @@ def xtract_cell_decl(cell, dirs, outf):
|
|||
kind, _, ports = l.partition(' ')
|
||||
for port in ports.split(','):
|
||||
port = port.strip()
|
||||
for attr in cell.port_attrs.get(port, []):
|
||||
outf.write(' (* {} *)\n'.format(attr))
|
||||
outf.write(' {} {};\n'.format(kind, port))
|
||||
if port.startswith('['):
|
||||
rng, port = port.split()
|
||||
else:
|
||||
rng = None
|
||||
module_ports.append((kind, rng, port))
|
||||
elif l.startswith('parameter ') and state == State.IN_MODULE:
|
||||
if 'UNPLACED' in l:
|
||||
continue
|
||||
|
@ -222,6 +662,9 @@ def xtract_cell_decl(cell, dirs, outf):
|
|||
print('Weird parameter line in {} [{}].'.format(fname, l))
|
||||
sys.exit(1)
|
||||
outf.write(' {};\n'.format(l))
|
||||
match = re.search('IS_([a-zA-Z0-9_]+)_INVERTED', l)
|
||||
if match:
|
||||
invertible_ports.add(match[1])
|
||||
if state != State.OUTSIDE:
|
||||
print('endmodule not found in {}.'.format(fname))
|
||||
sys.exit(1)
|
||||
|
@ -235,23 +678,31 @@ def xtract_cell_decl(cell, dirs, outf):
|
|||
sys.exit(1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = ArgumentParser(description='Extract Xilinx blackbox cell definitions from Vivado.')
|
||||
parser = ArgumentParser(description='Extract Xilinx blackbox cell definitions from ISE and Vivado.')
|
||||
parser.add_argument('vivado_dir', nargs='?', default='/opt/Xilinx/Vivado/2018.1')
|
||||
parser.add_argument('ise_dir', nargs='?', default='/opt/Xilinx/ISE/14.7')
|
||||
args = parser.parse_args()
|
||||
|
||||
dirs = [
|
||||
os.path.join(args.vivado_dir, 'data/verilog/src/xeclib'),
|
||||
os.path.join(args.vivado_dir, 'data/verilog/src/retarget'),
|
||||
os.path.join(args.ise_dir, 'ISE_DS/ISE/verilog/xeclib/unisims'),
|
||||
]
|
||||
for dir in dirs:
|
||||
if not os.path.isdir(dir):
|
||||
print('{} is not a directory'.format(dir))
|
||||
|
||||
out = StringIO()
|
||||
for cell in CELLS:
|
||||
xtract_cell_decl(cell, dirs, out)
|
||||
for ofile, cells in [
|
||||
('xc6s_cells_xtra.v', XC6S_CELLS),
|
||||
('xc6v_cells_xtra.v', XC6V_CELLS),
|
||||
('xc7_cells_xtra.v', XC7_CELLS),
|
||||
('xcu_cells_xtra.v', XCU_CELLS),
|
||||
]:
|
||||
out = StringIO()
|
||||
for cell in cells:
|
||||
xtract_cell_decl(cell, dirs, out)
|
||||
|
||||
with open('cells_xtra.v', 'w') as f:
|
||||
f.write('// Created by cells_xtra.py from Xilinx models\n')
|
||||
f.write('\n')
|
||||
f.write(out.getvalue())
|
||||
with open(ofile, 'w') as f:
|
||||
f.write('// Created by cells_xtra.py from Xilinx models\n')
|
||||
f.write('\n')
|
||||
f.write(out.getvalue())
|
||||
|
|
49
techlibs/xilinx/dsp_map.v
Normal file
49
techlibs/xilinx/dsp_map.v
Normal file
|
@ -0,0 +1,49 @@
|
|||
module \$__MUL25X18 (input [24:0] A, input [17:0] B, output [42:0] Y);
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
parameter A_WIDTH = 0;
|
||||
parameter B_WIDTH = 0;
|
||||
parameter Y_WIDTH = 0;
|
||||
|
||||
wire [47:0] P_48;
|
||||
DSP48E1 #(
|
||||
// Disable all registers
|
||||
.ACASCREG(0),
|
||||
.ADREG(0),
|
||||
.A_INPUT("DIRECT"),
|
||||
.ALUMODEREG(0),
|
||||
.AREG(0),
|
||||
.BCASCREG(0),
|
||||
.B_INPUT("DIRECT"),
|
||||
.BREG(0),
|
||||
.CARRYINREG(0),
|
||||
.CARRYINSELREG(0),
|
||||
.CREG(0),
|
||||
.DREG(0),
|
||||
.INMODEREG(0),
|
||||
.MREG(0),
|
||||
.OPMODEREG(0),
|
||||
.PREG(0),
|
||||
.USE_MULT("MULTIPLY"),
|
||||
.USE_SIMD("ONE48"),
|
||||
.USE_DPORT("FALSE")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
//Data path
|
||||
.A({{5{A[24]}}, A}),
|
||||
.B(B),
|
||||
.C(48'b0),
|
||||
.D(25'b0),
|
||||
.P(P_48),
|
||||
|
||||
.INMODE(5'b00000),
|
||||
.ALUMODE(4'b0000),
|
||||
.OPMODE(7'b000101),
|
||||
.CARRYINSEL(3'b000),
|
||||
|
||||
.ACIN(30'b0),
|
||||
.BCIN(18'b0),
|
||||
.PCIN(48'b0),
|
||||
.CARRYIN(1'b0)
|
||||
);
|
||||
assign Y = P_48;
|
||||
endmodule
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// FF mapping
|
||||
|
||||
`ifndef _NO_FFS
|
||||
|
||||
module \$_DFF_N_ (input D, C, output Q); FDRE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0)); endmodule
|
||||
module \$_DFF_P_ (input D, C, output Q); FDRE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0)); endmodule
|
||||
|
||||
module \$_DFFE_NP_ (input D, C, E, output Q); FDRE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0)); endmodule
|
||||
module \$_DFFE_PP_ (input D, C, E, output Q); FDRE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0)); endmodule
|
||||
|
||||
module \$_DFF_NN0_ (input D, C, R, output Q); FDCE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR(!R)); endmodule
|
||||
module \$_DFF_NP0_ (input D, C, R, output Q); FDCE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R)); endmodule
|
||||
module \$_DFF_PN0_ (input D, C, R, output Q); FDCE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR(!R)); endmodule
|
||||
module \$_DFF_PP0_ (input D, C, R, output Q); FDCE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R)); endmodule
|
||||
|
||||
module \$_DFF_NN1_ (input D, C, R, output Q); FDPE_1 #(.INIT(|1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(!R)); endmodule
|
||||
module \$_DFF_NP1_ (input D, C, R, output Q); FDPE_1 #(.INIT(|1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R)); endmodule
|
||||
module \$_DFF_PN1_ (input D, C, R, output Q); FDPE #(.INIT(|1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(!R)); endmodule
|
||||
module \$_DFF_PP1_ (input D, C, R, output Q); FDPE #(.INIT(|1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R)); endmodule
|
||||
|
||||
`endif
|
||||
|
|
@ -46,7 +46,7 @@ struct SynthXilinxPass : public ScriptPass
|
|||
log(" -top <module>\n");
|
||||
log(" use the specified module as top module\n");
|
||||
log("\n");
|
||||
log(" -family {xcup|xcu|xc7|xc6s}\n");
|
||||
log(" -family {xcup|xcu|xc7|xc6v|xc6s}\n");
|
||||
log(" run synthesis for the specified Xilinx architecture\n");
|
||||
log(" generate the synthesis netlist for the specified family.\n");
|
||||
log(" default: xc7\n");
|
||||
|
@ -81,6 +81,9 @@ struct SynthXilinxPass : public ScriptPass
|
|||
log(" -nowidelut\n");
|
||||
log(" do not use MUXF[78] resources to implement LUTs larger than LUT6s\n");
|
||||
log("\n");
|
||||
log(" -nodsp\n");
|
||||
log(" do not use DSP48E1s to implement multipliers and associated logic\n");
|
||||
log("\n");
|
||||
log(" -iopad\n");
|
||||
log(" enable I/O buffer insertion (selected automatically by -ise)\n");
|
||||
log("\n");
|
||||
|
@ -116,7 +119,7 @@ struct SynthXilinxPass : public ScriptPass
|
|||
}
|
||||
|
||||
std::string top_opt, edif_file, blif_file, family;
|
||||
bool flatten, retime, vpr, ise, iopad, noiopad, noclkbuf, nobram, nolutram, nosrl, nocarry, nowidelut, abc9;
|
||||
bool flatten, retime, vpr, ise, iopad, noiopad, noclkbuf, nobram, nolutram, nosrl, nocarry, nowidelut, nodsp, abc9;
|
||||
bool flatten_before_abc;
|
||||
int widemux;
|
||||
|
||||
|
@ -139,6 +142,7 @@ struct SynthXilinxPass : public ScriptPass
|
|||
nosrl = false;
|
||||
nocarry = false;
|
||||
nowidelut = false;
|
||||
nodsp = false;
|
||||
abc9 = false;
|
||||
flatten_before_abc = false;
|
||||
widemux = 0;
|
||||
|
@ -240,11 +244,15 @@ struct SynthXilinxPass : public ScriptPass
|
|||
abc9 = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-nodsp") {
|
||||
nodsp = true;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
extra_args(args, argidx, design);
|
||||
|
||||
if (family != "xcup" && family != "xcu" && family != "xc7" && family != "xc6s")
|
||||
if (family != "xcup" && family != "xcu" && family != "xc7" && family != "xc6v" && family != "xc6s")
|
||||
log_cmd_error("Invalid Xilinx -family setting: '%s'.\n", family.c_str());
|
||||
|
||||
if (widemux != 0 && widemux < 2)
|
||||
|
@ -266,29 +274,46 @@ struct SynthXilinxPass : public ScriptPass
|
|||
|
||||
void script() YS_OVERRIDE
|
||||
{
|
||||
std::string ff_map_file;
|
||||
if (help_mode)
|
||||
ff_map_file = "+/xilinx/{family}_ff_map.v";
|
||||
else if (family == "xc6s")
|
||||
ff_map_file = "+/xilinx/xc6s_ff_map.v";
|
||||
else
|
||||
ff_map_file = "+/xilinx/xc7_ff_map.v";
|
||||
|
||||
if (check_label("begin")) {
|
||||
if (vpr)
|
||||
run("read_verilog -lib -icells -D _ABC -D_EXPLICIT_CARRY +/xilinx/cells_sim.v");
|
||||
run("read_verilog -lib -D_EXPLICIT_CARRY +/xilinx/cells_sim.v");
|
||||
else
|
||||
run("read_verilog -lib -icells -D _ABC +/xilinx/cells_sim.v");
|
||||
run("read_verilog -lib +/xilinx/cells_sim.v");
|
||||
|
||||
run("read_verilog -lib +/xilinx/cells_xtra.v");
|
||||
if (help_mode)
|
||||
run("read_verilog -lib +/xilinx/{family}_cells_xtra.v");
|
||||
else if (family == "xc6s")
|
||||
run("read_verilog -lib +/xilinx/xc6s_cells_xtra.v");
|
||||
else if (family == "xc6v")
|
||||
run("read_verilog -lib +/xilinx/xc6v_cells_xtra.v");
|
||||
else if (family == "xc7")
|
||||
run("read_verilog -lib +/xilinx/xc7_cells_xtra.v");
|
||||
else if (family == "xcu" || family == "xcup")
|
||||
run("read_verilog -lib +/xilinx/xcu_cells_xtra.v");
|
||||
|
||||
if (help_mode) {
|
||||
run("read_verilog -lib +/xilinx/{family}_brams_bb.v");
|
||||
} else if (family == "xc6s") {
|
||||
run("read_verilog -lib +/xilinx/xc6s_brams_bb.v");
|
||||
} else if (family == "xc7") {
|
||||
} else if (family == "xc6v" || family == "xc7") {
|
||||
run("read_verilog -lib +/xilinx/xc7_brams_bb.v");
|
||||
}
|
||||
|
||||
run(stringf("hierarchy -check %s", top_opt.c_str()));
|
||||
}
|
||||
|
||||
if (check_label("coarse")) {
|
||||
if (check_label("prepare")) {
|
||||
run("proc");
|
||||
if (help_mode || flatten)
|
||||
run("flatten", "(if -flatten)");
|
||||
if (flatten || help_mode)
|
||||
run("flatten", "(with '-flatten')");
|
||||
run("opt_expr");
|
||||
run("opt_clean");
|
||||
run("check");
|
||||
|
@ -312,6 +337,30 @@ struct SynthXilinxPass : public ScriptPass
|
|||
}
|
||||
|
||||
run("techmap -map +/cmp2lut.v -D LUT_WIDTH=6");
|
||||
}
|
||||
|
||||
if (check_label("map_dsp", "(skip if '-nodsp')")) {
|
||||
if (!nodsp || help_mode) {
|
||||
// NB: Xilinx multipliers are signed only
|
||||
run("techmap -map +/mul2dsp.v -map +/xilinx/dsp_map.v -D DSP_A_MAXWIDTH=25 "
|
||||
"-D DSP_A_MAXWIDTH_PARTIAL=18 -D DSP_B_MAXWIDTH=18 " // Partial multipliers are intentionally
|
||||
// limited to 18x18 in order to take
|
||||
// advantage of the (PCOUT << 17) -> PCIN
|
||||
// dedicated cascade chain capability
|
||||
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
|
||||
"-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
|
||||
"-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL25X18");
|
||||
run("select a:mul2dsp");
|
||||
run("setattr -unset mul2dsp");
|
||||
run("opt_expr -fine");
|
||||
run("wreduce");
|
||||
run("select -clear");
|
||||
run("xilinx_dsp");
|
||||
run("chtype -set $mul t:$__soft_mul");
|
||||
}
|
||||
}
|
||||
|
||||
if (check_label("coarse")) {
|
||||
run("alumacc");
|
||||
run("share");
|
||||
run("opt");
|
||||
|
@ -329,7 +378,7 @@ struct SynthXilinxPass : public ScriptPass
|
|||
if (family == "xc6s") {
|
||||
run("memory_bram -rules +/xilinx/xc6s_brams.txt");
|
||||
run("techmap -map +/xilinx/xc6s_brams_map.v");
|
||||
} else if (family == "xc7") {
|
||||
} else if (family == "xc6v" || family == "xc7") {
|
||||
run("memory_bram -rules +/xilinx/xc7_brams.txt");
|
||||
run("techmap -map +/xilinx/xc7_brams_map.v");
|
||||
} else {
|
||||
|
@ -408,7 +457,7 @@ struct SynthXilinxPass : public ScriptPass
|
|||
}
|
||||
|
||||
if (check_label("map_cells")) {
|
||||
std::string techmap_args = "-map +/techmap.v -D _ABC -map +/xilinx/cells_map.v";
|
||||
std::string techmap_args = "-map +/techmap.v -map +/xilinx/cells_map.v";
|
||||
if (widemux > 0)
|
||||
techmap_args += stringf(" -D MIN_MUX_INPUTS=%d", widemux);
|
||||
run("techmap " + techmap_args);
|
||||
|
@ -416,11 +465,9 @@ struct SynthXilinxPass : public ScriptPass
|
|||
}
|
||||
|
||||
if (check_label("map_ffs")) {
|
||||
if (abc9 || help_mode) {
|
||||
run("techmap -map +/xilinx/ff_map.v", "('-abc9' only)");
|
||||
run("dffinit -ff FDRE Q INIT -ff FDCE Q INIT -ff FDPE Q INIT -ff FDSE Q INIT "
|
||||
"-ff FDRE_1 Q INIT -ff FDCE_1 Q INIT -ff FDPE_1 Q INIT -ff FDSE_1 Q INIT", "('-abc9' only)");
|
||||
}
|
||||
if (abc9 || help_mode) {
|
||||
run("techmap -map " + ff_map_file, "('-abc9' only)");
|
||||
}
|
||||
}
|
||||
|
||||
if (check_label("map_luts")) {
|
||||
|
@ -428,14 +475,21 @@ struct SynthXilinxPass : public ScriptPass
|
|||
if (flatten_before_abc)
|
||||
run("flatten");
|
||||
if (help_mode)
|
||||
run("abc -luts 2:2,3,6:5[,10,20] [-dff]", "(option for 'nowidelut', option for '-retime')");
|
||||
run("abc -luts 2:2,3,6:5[,10,20] [-dff]", "(option for 'nowidelut'; option for '-retime')");
|
||||
else if (abc9) {
|
||||
if (family != "xc7")
|
||||
log_warning("'synth_xilinx -abc9' currently supports '-family xc7' only.\n");
|
||||
log_warning("'synth_xilinx -abc9' not currently supported for the '%s' family, "
|
||||
"will use timing for 'xc7' instead.\n", family.c_str());
|
||||
run("techmap -map +/xilinx/abc9_map.v -max_iter 1");
|
||||
run("read_verilog -icells -lib +/xilinx/abc9_model.v");
|
||||
std::string abc9_opts = " -box +/xilinx/abc9_xc7.box";
|
||||
abc9_opts += stringf(" -W %d", XC7_WIRE_DELAY);
|
||||
abc9_opts += " -nomfs";
|
||||
if (nowidelut)
|
||||
run("abc9 -lut +/xilinx/abc_xc7_nowide.lut -box +/xilinx/abc_xc7.box -W " + std::to_string(XC7_WIRE_DELAY));
|
||||
abc9_opts += " -lut +/xilinx/abc9_xc7_nowide.lut";
|
||||
else
|
||||
run("abc9 -lut +/xilinx/abc_xc7.lut -box +/xilinx/abc_xc7.box -W " + std::to_string(XC7_WIRE_DELAY));
|
||||
abc9_opts += " -lut +/xilinx/abc9_xc7.lut";
|
||||
run("abc9" + abc9_opts);
|
||||
}
|
||||
else {
|
||||
if (nowidelut)
|
||||
|
@ -449,16 +503,14 @@ struct SynthXilinxPass : public ScriptPass
|
|||
// has performed any necessary retiming
|
||||
if (!nosrl || help_mode)
|
||||
run("xilinx_srl -fixed -minlen 3", "(skip if '-nosrl')");
|
||||
|
||||
std::string techmap_args = "-map +/xilinx/lut_map.v -map +/xilinx/cells_map.v";
|
||||
if (help_mode)
|
||||
techmap_args += " [-map +/xilinx/ff_map.v]";
|
||||
else if (!abc9)
|
||||
techmap_args += " -map +/xilinx/ff_map.v";
|
||||
techmap_args += " [-map " + ff_map_file + "]";
|
||||
else if (abc9)
|
||||
techmap_args += " -map +/xilinx/abc9_unmap.v";
|
||||
else
|
||||
techmap_args += " -map " + ff_map_file;
|
||||
run("techmap " + techmap_args);
|
||||
if (!abc9)
|
||||
run("dffinit -ff FDRE Q INIT -ff FDCE Q INIT -ff FDPE Q INIT -ff FDSE Q INIT "
|
||||
"-ff FDRE_1 Q INIT -ff FDCE_1 Q INIT -ff FDPE_1 Q INIT -ff FDSE_1 Q INIT", "(without '-abc9' only)");
|
||||
run("clean");
|
||||
}
|
||||
|
||||
|
@ -470,8 +522,10 @@ struct SynthXilinxPass : public ScriptPass
|
|||
else
|
||||
run("clkbufmap -buf BUFG O:I");
|
||||
}
|
||||
if (do_iopad)
|
||||
if (help_mode || do_iopad)
|
||||
run("iopadmap -bits -outpad OBUF I:O -inpad IBUF O:I A:top", "(only if '-iopad' or '-ise' and not '-noiopad')");
|
||||
if (help_mode || ise)
|
||||
run("extractinv -inv INV O:I", "(only if '-ise')");
|
||||
}
|
||||
|
||||
if (check_label("check")) {
|
||||
|
|
5
techlibs/xilinx/tests/.gitignore
vendored
5
techlibs/xilinx/tests/.gitignore
vendored
|
@ -4,3 +4,8 @@ bram1_[0-9]*/
|
|||
bram2.log
|
||||
bram2_syn.v
|
||||
bram2_tb
|
||||
dsp_work*/
|
||||
test_dsp_model_ref.v
|
||||
test_dsp_model_uut.v
|
||||
test_dsp_model
|
||||
*.vcd
|
||||
|
|
14
techlibs/xilinx/tests/test_dsp_model.sh
Normal file
14
techlibs/xilinx/tests/test_dsp_model.sh
Normal file
|
@ -0,0 +1,14 @@
|
|||
#!/bin/bash
|
||||
set -ex
|
||||
sed 's/DSP48E1/DSP48E1_UUT/; /DSP48E1_UUT/,/endmodule/ p; d;' < ../cells_sim.v > test_dsp_model_uut.v
|
||||
if [ ! -f "test_dsp_model_ref.v" ]; then
|
||||
cat /opt/Xilinx/Vivado/2019.1/data/verilog/src/unisims/DSP48E1.v > test_dsp_model_ref.v
|
||||
fi
|
||||
for tb in macc_overflow_underflow \
|
||||
simd24_preadd_noreg_nocasc simd12_preadd_noreg_nocasc \
|
||||
mult_allreg_nopreadd_nocasc mult_noreg_nopreadd_nocasc \
|
||||
mult_allreg_preadd_nocasc mult_noreg_preadd_nocasc mult_inreg_preadd_nocasc
|
||||
do
|
||||
iverilog -s $tb -s glbl -o test_dsp_model test_dsp_model.v test_dsp_model_uut.v test_dsp_model_ref.v /opt/Xilinx/Vivado/2019.1/data/verilog/src/glbl.v
|
||||
vvp -N ./test_dsp_model
|
||||
done
|
652
techlibs/xilinx/tests/test_dsp_model.v
Normal file
652
techlibs/xilinx/tests/test_dsp_model.v
Normal file
|
@ -0,0 +1,652 @@
|
|||
`timescale 1ns / 1ps
|
||||
|
||||
module testbench;
|
||||
parameter integer ACASCREG = 1;
|
||||
parameter integer ADREG = 1;
|
||||
parameter integer ALUMODEREG = 1;
|
||||
parameter integer AREG = 1;
|
||||
parameter AUTORESET_PATDET = "NO_RESET";
|
||||
parameter A_INPUT = "DIRECT";
|
||||
parameter integer BCASCREG = 1;
|
||||
parameter integer BREG = 1;
|
||||
parameter B_INPUT = "DIRECT";
|
||||
parameter integer CARRYINREG = 1;
|
||||
parameter integer CARRYINSELREG = 1;
|
||||
parameter integer CREG = 1;
|
||||
parameter integer DREG = 1;
|
||||
parameter integer INMODEREG = 1;
|
||||
parameter integer MREG = 1;
|
||||
parameter integer OPMODEREG = 1;
|
||||
parameter integer PREG = 1;
|
||||
parameter SEL_MASK = "MASK";
|
||||
parameter SEL_PATTERN = "PATTERN";
|
||||
parameter USE_DPORT = "FALSE";
|
||||
parameter USE_MULT = "MULTIPLY";
|
||||
parameter USE_PATTERN_DETECT = "NO_PATDET";
|
||||
parameter USE_SIMD = "ONE48";
|
||||
parameter [47:0] MASK = 48'h3FFFFFFFFFFF;
|
||||
parameter [47:0] PATTERN = 48'h000000000000;
|
||||
parameter [3:0] IS_ALUMODE_INVERTED = 4'b0;
|
||||
parameter [0:0] IS_CARRYIN_INVERTED = 1'b0;
|
||||
parameter [0:0] IS_CLK_INVERTED = 1'b0;
|
||||
parameter [4:0] IS_INMODE_INVERTED = 5'b0;
|
||||
parameter [6:0] IS_OPMODE_INVERTED = 7'b0;
|
||||
|
||||
reg CLK;
|
||||
reg CEA1, CEA2, CEAD, CEALUMODE, CEB1, CEB2, CEC, CECARRYIN, CECTRL;
|
||||
reg CED, CEINMODE, CEM, CEP;
|
||||
reg RSTA, RSTALLCARRYIN, RSTALUMODE, RSTB, RSTC, RSTCTRL, RSTD, RSTINMODE, RSTM, RSTP;
|
||||
reg [29:0] A, ACIN;
|
||||
reg [17:0] B, BCIN;
|
||||
reg [47:0] C;
|
||||
reg [24:0] D;
|
||||
reg [47:0] PCIN;
|
||||
reg [3:0] ALUMODE;
|
||||
reg [2:0] CARRYINSEL;
|
||||
reg [4:0] INMODE;
|
||||
reg [6:0] OPMODE;
|
||||
reg CARRYCASCIN, CARRYIN, MULTSIGNIN;
|
||||
|
||||
output [29:0] ACOUT, REF_ACOUT;
|
||||
output [17:0] BCOUT, REF_BCOUT;
|
||||
output CARRYCASCOUT, REF_CARRYCASCOUT;
|
||||
output [3:0] CARRYOUT, REF_CARRYOUT;
|
||||
output MULTSIGNOUT, REF_MULTSIGNOUT;
|
||||
output OVERFLOW, REF_OVERFLOW;
|
||||
output [47:0] P, REF_P;
|
||||
output PATTERNBDETECT, REF_PATTERNBDETECT;
|
||||
output PATTERNDETECT, REF_PATTERNDETECT;
|
||||
output [47:0] PCOUT, REF_PCOUT;
|
||||
output UNDERFLOW, REF_UNDERFLOW;
|
||||
|
||||
integer errcount = 0;
|
||||
|
||||
reg ERROR_FLAG = 0;
|
||||
|
||||
task clkcycle;
|
||||
begin
|
||||
#5;
|
||||
CLK = ~CLK;
|
||||
#10;
|
||||
CLK = ~CLK;
|
||||
#2;
|
||||
ERROR_FLAG = 0;
|
||||
if (REF_P !== P) begin
|
||||
$display("ERROR at %1t: REF_P=%b UUT_P=%b DIFF=%b", $time, REF_P, P, REF_P ^ P);
|
||||
errcount = errcount + 1;
|
||||
ERROR_FLAG = 1;
|
||||
end
|
||||
if (REF_CARRYOUT !== CARRYOUT) begin
|
||||
$display("ERROR at %1t: REF_CARRYOUT=%b UUT_CARRYOUT=%b", $time, REF_CARRYOUT, CARRYOUT);
|
||||
errcount = errcount + 1;
|
||||
ERROR_FLAG = 1;
|
||||
end
|
||||
if (REF_PATTERNDETECT !== PATTERNDETECT) begin
|
||||
$display("ERROR at %1t: REF_PATTERNDETECT=%b UUT_PATTERNDETECT=%b DIFF=%b REF_P=%b P=%b", $time, REF_PATTERNDETECT, PATTERNDETECT, REF_PATTERNDETECT ^ PATTERNDETECT, REF_P, P);
|
||||
errcount = errcount + 1;
|
||||
ERROR_FLAG = 1;
|
||||
end
|
||||
if (REF_PATTERNBDETECT !== PATTERNBDETECT) begin
|
||||
$display("ERROR at %1t: REF_PATTERNBDETECT=%b UUT_PATTERNBDETECT=%b DIFF=%b", $time, REF_PATTERNBDETECT, PATTERNBDETECT, REF_PATTERNBDETECT ^ PATTERNBDETECT);
|
||||
errcount = errcount + 1;
|
||||
ERROR_FLAG = 1;
|
||||
end
|
||||
if (REF_OVERFLOW !== OVERFLOW) begin
|
||||
$display("ERROR at %1t: REF_OVERFLOW=%b UUT_OVERFLOW=%b DIFF=%b", $time, REF_OVERFLOW, OVERFLOW, REF_OVERFLOW ^ OVERFLOW);
|
||||
errcount = errcount + 1;
|
||||
ERROR_FLAG = 1;
|
||||
end
|
||||
if (REF_UNDERFLOW !== UNDERFLOW) begin
|
||||
$display("ERROR at %1t: REF_UNDERFLOW=%b UUT_UNDERFLOW=%b DIFF=%b", $time, REF_UNDERFLOW, UNDERFLOW, REF_UNDERFLOW ^ UNDERFLOW);
|
||||
errcount = errcount + 1;
|
||||
ERROR_FLAG = 1;
|
||||
end
|
||||
#3;
|
||||
end
|
||||
endtask
|
||||
|
||||
reg config_valid = 0;
|
||||
task drc;
|
||||
begin
|
||||
config_valid = 1;
|
||||
if (AREG != 2 && INMODE[0]) config_valid = 0;
|
||||
if (BREG != 2 && INMODE[4]) config_valid = 0;
|
||||
|
||||
if (USE_SIMD != "ONE48" && OPMODE[3:0] == 4'b0101) config_valid = 0;
|
||||
|
||||
if (OPMODE[1:0] == 2'b10 && PREG != 1) config_valid = 0;
|
||||
if ((OPMODE[3:2] == 2'b01) ^ (OPMODE[1:0] == 2'b01) == 1'b1) config_valid = 0;
|
||||
if ((OPMODE[6:4] == 3'b010 || OPMODE[6:4] == 3'b110) && PREG != 1) config_valid = 0;
|
||||
if ((OPMODE[6:4] == 3'b100) && (PREG != 1 || OPMODE[3:0] != 4'b1000 || ALUMODE[3:2] == 2'b01 || ALUMODE[3:2] == 2'b11)) config_valid = 0;
|
||||
if ((CARRYINSEL == 3'b100 || CARRYINSEL == 3'b101 || CARRYINSEL == 3'b111) && (PREG != 1)) config_valid = 0;
|
||||
if (OPMODE[6:4] == 3'b111) config_valid = 0;
|
||||
if ((OPMODE[3:0] == 4'b0101) && CARRYINSEL == 3'b010) config_valid = 0;
|
||||
if (CARRYINSEL == 3'b000 && OPMODE == 7'b1001000) config_valid = 0;
|
||||
|
||||
if ((ALUMODE[3:2] == 2'b01 || ALUMODE[3:2] == 2'b11) && OPMODE[3:2] != 2'b00 && OPMODE[3:2] != 2'b10) config_valid = 0;
|
||||
|
||||
|
||||
end
|
||||
endtask
|
||||
|
||||
initial begin
|
||||
$dumpfile("test_dsp_model.vcd");
|
||||
$dumpvars(0, testbench);
|
||||
|
||||
#2;
|
||||
CLK = 1'b0;
|
||||
{CEA1, CEA2, CEAD, CEALUMODE, CEB1, CEB2, CEC, CECARRYIN, CECTRL} = 9'b111111111;
|
||||
{CED, CEINMODE, CEM, CEP} = 4'b1111;
|
||||
|
||||
{A, B, C, D} = 0;
|
||||
{ACIN, BCIN, PCIN} = 0;
|
||||
{ALUMODE, CARRYINSEL, INMODE} = 0;
|
||||
{OPMODE, CARRYCASCIN, CARRYIN, MULTSIGNIN} = 0;
|
||||
|
||||
{RSTA, RSTALLCARRYIN, RSTALUMODE, RSTB, RSTC, RSTCTRL, RSTD, RSTINMODE, RSTM, RSTP} = ~0;
|
||||
repeat (10) begin
|
||||
#10;
|
||||
CLK = 1'b1;
|
||||
#10;
|
||||
CLK = 1'b0;
|
||||
#10;
|
||||
CLK = 1'b1;
|
||||
#10;
|
||||
CLK = 1'b0;
|
||||
end
|
||||
{RSTA, RSTALLCARRYIN, RSTALUMODE, RSTB, RSTC, RSTCTRL, RSTD, RSTINMODE, RSTM, RSTP} = 0;
|
||||
|
||||
repeat (10000) begin
|
||||
clkcycle;
|
||||
config_valid = 0;
|
||||
while (!config_valid) begin
|
||||
A = $urandom;
|
||||
ACIN = $urandom;
|
||||
B = $urandom;
|
||||
BCIN = $urandom;
|
||||
C = {$urandom, $urandom};
|
||||
D = $urandom;
|
||||
PCIN = {$urandom, $urandom};
|
||||
|
||||
{CEA1, CEA2, CEAD, CEALUMODE, CEB1, CEB2, CEC, CECARRYIN, CECTRL} = $urandom | $urandom | $urandom;
|
||||
{CED, CEINMODE, CEM, CEP} = $urandom | $urandom | $urandom | $urandom;
|
||||
|
||||
// Otherwise we can accidentally create illegal configs
|
||||
CEINMODE = CECTRL;
|
||||
CEALUMODE = CECTRL;
|
||||
|
||||
{RSTA, RSTALLCARRYIN, RSTALUMODE, RSTB, RSTC, RSTCTRL, RSTD, RSTINMODE, RSTM, RSTP} = $urandom & $urandom & $urandom & $urandom & $urandom & $urandom;
|
||||
{ALUMODE, INMODE} = $urandom;
|
||||
CARRYINSEL = $urandom & $urandom & $urandom;
|
||||
OPMODE = $urandom;
|
||||
if ($urandom & 1'b1)
|
||||
OPMODE[3:0] = 4'b0101; // test multiply more than other modes
|
||||
{CARRYCASCIN, CARRYIN, MULTSIGNIN} = $urandom;
|
||||
|
||||
// So few valid options in these modes, just force one valid option
|
||||
if (CARRYINSEL == 3'b001) OPMODE = 7'b1010101;
|
||||
if (CARRYINSEL == 3'b010) OPMODE = 7'b0001010;
|
||||
if (CARRYINSEL == 3'b011) OPMODE = 7'b0011011;
|
||||
if (CARRYINSEL == 3'b100) OPMODE = 7'b0110011;
|
||||
if (CARRYINSEL == 3'b101) OPMODE = 7'b0011010;
|
||||
if (CARRYINSEL == 3'b110) OPMODE = 7'b0010101;
|
||||
if (CARRYINSEL == 3'b111) OPMODE = 7'b0100011;
|
||||
|
||||
drc;
|
||||
end
|
||||
end
|
||||
|
||||
if (errcount == 0) begin
|
||||
$display("All tests passed.");
|
||||
$finish;
|
||||
end else begin
|
||||
$display("Caught %1d errors.", errcount);
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
|
||||
DSP48E1 #(
|
||||
.ACASCREG (ACASCREG),
|
||||
.ADREG (ADREG),
|
||||
.ALUMODEREG (ALUMODEREG),
|
||||
.AREG (AREG),
|
||||
.AUTORESET_PATDET (AUTORESET_PATDET),
|
||||
.A_INPUT (A_INPUT),
|
||||
.BCASCREG (BCASCREG),
|
||||
.BREG (BREG),
|
||||
.B_INPUT (B_INPUT),
|
||||
.CARRYINREG (CARRYINREG),
|
||||
.CARRYINSELREG (CARRYINSELREG),
|
||||
.CREG (CREG),
|
||||
.DREG (DREG),
|
||||
.INMODEREG (INMODEREG),
|
||||
.MREG (MREG),
|
||||
.OPMODEREG (OPMODEREG),
|
||||
.PREG (PREG),
|
||||
.SEL_MASK (SEL_MASK),
|
||||
.SEL_PATTERN (SEL_PATTERN),
|
||||
.USE_DPORT (USE_DPORT),
|
||||
.USE_MULT (USE_MULT),
|
||||
.USE_PATTERN_DETECT (USE_PATTERN_DETECT),
|
||||
.USE_SIMD (USE_SIMD),
|
||||
.MASK (MASK),
|
||||
.PATTERN (PATTERN),
|
||||
.IS_ALUMODE_INVERTED(IS_ALUMODE_INVERTED),
|
||||
.IS_CARRYIN_INVERTED(IS_CARRYIN_INVERTED),
|
||||
.IS_CLK_INVERTED (IS_CLK_INVERTED),
|
||||
.IS_INMODE_INVERTED (IS_INMODE_INVERTED),
|
||||
.IS_OPMODE_INVERTED (IS_OPMODE_INVERTED)
|
||||
) ref (
|
||||
.ACOUT (REF_ACOUT),
|
||||
.BCOUT (REF_BCOUT),
|
||||
.CARRYCASCOUT (REF_CARRYCASCOUT),
|
||||
.CARRYOUT (REF_CARRYOUT),
|
||||
.MULTSIGNOUT (REF_MULTSIGNOUT),
|
||||
.OVERFLOW (REF_OVERFLOW),
|
||||
.P (REF_P),
|
||||
.PATTERNBDETECT(REF_PATTERNBDETECT),
|
||||
.PATTERNDETECT (REF_PATTERNDETECT),
|
||||
.PCOUT (REF_PCOUT),
|
||||
.UNDERFLOW (REF_UNDERFLOW),
|
||||
.A (A),
|
||||
.ACIN (ACIN),
|
||||
.ALUMODE (ALUMODE),
|
||||
.B (B),
|
||||
.BCIN (BCIN),
|
||||
.C (C),
|
||||
.CARRYCASCIN (CARRYCASCIN),
|
||||
.CARRYINSEL (CARRYINSEL),
|
||||
.CEA1 (CEA1),
|
||||
.CEA2 (CEA2),
|
||||
.CEAD (CEAD),
|
||||
.CEALUMODE (CEALUMODE),
|
||||
.CEB1 (CEB1),
|
||||
.CEB2 (CEB2),
|
||||
.CEC (CEC),
|
||||
.CECARRYIN (CECARRYIN),
|
||||
.CECTRL (CECTRL),
|
||||
.CED (CED),
|
||||
.CEINMODE (CEINMODE),
|
||||
.CEM (CEM),
|
||||
.CEP (CEP),
|
||||
.CLK (CLK),
|
||||
.D (D),
|
||||
.INMODE (INMODE),
|
||||
.MULTSIGNIN (MULTSIGNIN),
|
||||
.OPMODE (OPMODE),
|
||||
.PCIN (PCIN),
|
||||
.RSTA (RSTA),
|
||||
.RSTALLCARRYIN (RSTALLCARRYIN),
|
||||
.RSTALUMODE (RSTALUMODE),
|
||||
.RSTB (RSTB),
|
||||
.RSTC (RSTC),
|
||||
.RSTCTRL (RSTCTRL),
|
||||
.RSTD (RSTD),
|
||||
.RSTINMODE (RSTINMODE),
|
||||
.RSTM (RSTM),
|
||||
.RSTP (RSTP)
|
||||
);
|
||||
|
||||
DSP48E1_UUT #(
|
||||
.ACASCREG (ACASCREG),
|
||||
.ADREG (ADREG),
|
||||
.ALUMODEREG (ALUMODEREG),
|
||||
.AREG (AREG),
|
||||
.AUTORESET_PATDET (AUTORESET_PATDET),
|
||||
.A_INPUT (A_INPUT),
|
||||
.BCASCREG (BCASCREG),
|
||||
.BREG (BREG),
|
||||
.B_INPUT (B_INPUT),
|
||||
.CARRYINREG (CARRYINREG),
|
||||
.CARRYINSELREG (CARRYINSELREG),
|
||||
.CREG (CREG),
|
||||
.DREG (DREG),
|
||||
.INMODEREG (INMODEREG),
|
||||
.MREG (MREG),
|
||||
.OPMODEREG (OPMODEREG),
|
||||
.PREG (PREG),
|
||||
.SEL_MASK (SEL_MASK),
|
||||
.SEL_PATTERN (SEL_PATTERN),
|
||||
.USE_DPORT (USE_DPORT),
|
||||
.USE_MULT (USE_MULT),
|
||||
.USE_PATTERN_DETECT (USE_PATTERN_DETECT),
|
||||
.USE_SIMD (USE_SIMD),
|
||||
.MASK (MASK),
|
||||
.PATTERN (PATTERN),
|
||||
.IS_ALUMODE_INVERTED(IS_ALUMODE_INVERTED),
|
||||
.IS_CARRYIN_INVERTED(IS_CARRYIN_INVERTED),
|
||||
.IS_CLK_INVERTED (IS_CLK_INVERTED),
|
||||
.IS_INMODE_INVERTED (IS_INMODE_INVERTED),
|
||||
.IS_OPMODE_INVERTED (IS_OPMODE_INVERTED)
|
||||
) uut (
|
||||
.ACOUT (ACOUT),
|
||||
.BCOUT (BCOUT),
|
||||
.CARRYCASCOUT (CARRYCASCOUT),
|
||||
.CARRYOUT (CARRYOUT),
|
||||
.MULTSIGNOUT (MULTSIGNOUT),
|
||||
.OVERFLOW (OVERFLOW),
|
||||
.P (P),
|
||||
.PATTERNBDETECT(PATTERNBDETECT),
|
||||
.PATTERNDETECT (PATTERNDETECT),
|
||||
.PCOUT (PCOUT),
|
||||
.UNDERFLOW (UNDERFLOW),
|
||||
.A (A),
|
||||
.ACIN (ACIN),
|
||||
.ALUMODE (ALUMODE),
|
||||
.B (B),
|
||||
.BCIN (BCIN),
|
||||
.C (C),
|
||||
.CARRYCASCIN (CARRYCASCIN),
|
||||
.CARRYINSEL (CARRYINSEL),
|
||||
.CEA1 (CEA1),
|
||||
.CEA2 (CEA2),
|
||||
.CEAD (CEAD),
|
||||
.CEALUMODE (CEALUMODE),
|
||||
.CEB1 (CEB1),
|
||||
.CEB2 (CEB2),
|
||||
.CEC (CEC),
|
||||
.CECARRYIN (CECARRYIN),
|
||||
.CECTRL (CECTRL),
|
||||
.CED (CED),
|
||||
.CEINMODE (CEINMODE),
|
||||
.CEM (CEM),
|
||||
.CEP (CEP),
|
||||
.CLK (CLK),
|
||||
.D (D),
|
||||
.INMODE (INMODE),
|
||||
.MULTSIGNIN (MULTSIGNIN),
|
||||
.OPMODE (OPMODE),
|
||||
.PCIN (PCIN),
|
||||
.RSTA (RSTA),
|
||||
.RSTALLCARRYIN (RSTALLCARRYIN),
|
||||
.RSTALUMODE (RSTALUMODE),
|
||||
.RSTB (RSTB),
|
||||
.RSTC (RSTC),
|
||||
.RSTCTRL (RSTCTRL),
|
||||
.RSTD (RSTD),
|
||||
.RSTINMODE (RSTINMODE),
|
||||
.RSTM (RSTM),
|
||||
.RSTP (RSTP)
|
||||
);
|
||||
endmodule
|
||||
|
||||
module mult_noreg_nopreadd_nocasc;
|
||||
testbench #(
|
||||
.ACASCREG (0),
|
||||
.ADREG (0),
|
||||
.ALUMODEREG (0),
|
||||
.AREG (0),
|
||||
.AUTORESET_PATDET ("NO_RESET"),
|
||||
.A_INPUT ("DIRECT"),
|
||||
.BCASCREG (0),
|
||||
.BREG (0),
|
||||
.B_INPUT ("DIRECT"),
|
||||
.CARRYINREG (0),
|
||||
.CARRYINSELREG (0),
|
||||
.CREG (0),
|
||||
.DREG (0),
|
||||
.INMODEREG (0),
|
||||
.MREG (0),
|
||||
.OPMODEREG (0),
|
||||
.PREG (0),
|
||||
.SEL_MASK ("MASK"),
|
||||
.SEL_PATTERN ("PATTERN"),
|
||||
.USE_DPORT ("FALSE"),
|
||||
.USE_MULT ("DYNAMIC"),
|
||||
.USE_PATTERN_DETECT ("NO_PATDET"),
|
||||
.USE_SIMD ("ONE48"),
|
||||
.MASK (48'h3FFFFFFFFFFF),
|
||||
.PATTERN (48'h000000000000),
|
||||
.IS_ALUMODE_INVERTED(4'b0),
|
||||
.IS_CARRYIN_INVERTED(1'b0),
|
||||
.IS_CLK_INVERTED (1'b0),
|
||||
.IS_INMODE_INVERTED (5'b0),
|
||||
.IS_OPMODE_INVERTED (7'b0)
|
||||
) testbench ();
|
||||
endmodule
|
||||
|
||||
module mult_allreg_nopreadd_nocasc;
|
||||
testbench #(
|
||||
.ACASCREG (1),
|
||||
.ADREG (1),
|
||||
.ALUMODEREG (1),
|
||||
.AREG (2),
|
||||
.AUTORESET_PATDET ("NO_RESET"),
|
||||
.A_INPUT ("DIRECT"),
|
||||
.BCASCREG (1),
|
||||
.BREG (2),
|
||||
.B_INPUT ("DIRECT"),
|
||||
.CARRYINREG (1),
|
||||
.CARRYINSELREG (1),
|
||||
.CREG (1),
|
||||
.DREG (1),
|
||||
.INMODEREG (1),
|
||||
.MREG (1),
|
||||
.OPMODEREG (1),
|
||||
.PREG (1),
|
||||
.SEL_MASK ("MASK"),
|
||||
.SEL_PATTERN ("PATTERN"),
|
||||
.USE_DPORT ("FALSE"),
|
||||
.USE_MULT ("DYNAMIC"),
|
||||
.USE_PATTERN_DETECT ("NO_PATDET"),
|
||||
.USE_SIMD ("ONE48"),
|
||||
.MASK (48'h3FFFFFFFFFFF),
|
||||
.PATTERN (48'h000000000000),
|
||||
.IS_ALUMODE_INVERTED(4'b0),
|
||||
.IS_CARRYIN_INVERTED(1'b0),
|
||||
.IS_CLK_INVERTED (1'b0),
|
||||
.IS_INMODE_INVERTED (5'b0),
|
||||
.IS_OPMODE_INVERTED (7'b0)
|
||||
) testbench ();
|
||||
endmodule
|
||||
|
||||
module mult_noreg_preadd_nocasc;
|
||||
testbench #(
|
||||
.ACASCREG (0),
|
||||
.ADREG (0),
|
||||
.ALUMODEREG (0),
|
||||
.AREG (0),
|
||||
.AUTORESET_PATDET ("NO_RESET"),
|
||||
.A_INPUT ("DIRECT"),
|
||||
.BCASCREG (0),
|
||||
.BREG (0),
|
||||
.B_INPUT ("DIRECT"),
|
||||
.CARRYINREG (0),
|
||||
.CARRYINSELREG (0),
|
||||
.CREG (0),
|
||||
.DREG (0),
|
||||
.INMODEREG (0),
|
||||
.MREG (0),
|
||||
.OPMODEREG (0),
|
||||
.PREG (0),
|
||||
.SEL_MASK ("MASK"),
|
||||
.SEL_PATTERN ("PATTERN"),
|
||||
.USE_DPORT ("TRUE"),
|
||||
.USE_MULT ("DYNAMIC"),
|
||||
.USE_PATTERN_DETECT ("NO_PATDET"),
|
||||
.USE_SIMD ("ONE48"),
|
||||
.MASK (48'h3FFFFFFFFFFF),
|
||||
.PATTERN (48'h000000000000),
|
||||
.IS_ALUMODE_INVERTED(4'b0),
|
||||
.IS_CARRYIN_INVERTED(1'b0),
|
||||
.IS_CLK_INVERTED (1'b0),
|
||||
.IS_INMODE_INVERTED (5'b0),
|
||||
.IS_OPMODE_INVERTED (7'b0)
|
||||
) testbench ();
|
||||
endmodule
|
||||
|
||||
module mult_allreg_preadd_nocasc;
|
||||
testbench #(
|
||||
.ACASCREG (1),
|
||||
.ADREG (1),
|
||||
.ALUMODEREG (1),
|
||||
.AREG (2),
|
||||
.AUTORESET_PATDET ("NO_RESET"),
|
||||
.A_INPUT ("DIRECT"),
|
||||
.BCASCREG (1),
|
||||
.BREG (2),
|
||||
.B_INPUT ("DIRECT"),
|
||||
.CARRYINREG (1),
|
||||
.CARRYINSELREG (1),
|
||||
.CREG (1),
|
||||
.DREG (1),
|
||||
.INMODEREG (1),
|
||||
.MREG (1),
|
||||
.OPMODEREG (1),
|
||||
.PREG (1),
|
||||
.SEL_MASK ("MASK"),
|
||||
.SEL_PATTERN ("PATTERN"),
|
||||
.USE_DPORT ("TRUE"),
|
||||
.USE_MULT ("DYNAMIC"),
|
||||
.USE_PATTERN_DETECT ("NO_PATDET"),
|
||||
.USE_SIMD ("ONE48"),
|
||||
.MASK (48'h3FFFFFFFFFFF),
|
||||
.PATTERN (48'h000000000000),
|
||||
.IS_ALUMODE_INVERTED(4'b0),
|
||||
.IS_CARRYIN_INVERTED(1'b0),
|
||||
.IS_CLK_INVERTED (1'b0),
|
||||
.IS_INMODE_INVERTED (5'b0),
|
||||
.IS_OPMODE_INVERTED (7'b0)
|
||||
) testbench ();
|
||||
endmodule
|
||||
|
||||
module mult_inreg_preadd_nocasc;
|
||||
testbench #(
|
||||
.ACASCREG (1),
|
||||
.ADREG (0),
|
||||
.ALUMODEREG (0),
|
||||
.AREG (1),
|
||||
.AUTORESET_PATDET ("NO_RESET"),
|
||||
.A_INPUT ("DIRECT"),
|
||||
.BCASCREG (1),
|
||||
.BREG (1),
|
||||
.B_INPUT ("DIRECT"),
|
||||
.CARRYINREG (0),
|
||||
.CARRYINSELREG (0),
|
||||
.CREG (1),
|
||||
.DREG (1),
|
||||
.INMODEREG (0),
|
||||
.MREG (0),
|
||||
.OPMODEREG (0),
|
||||
.PREG (0),
|
||||
.SEL_MASK ("MASK"),
|
||||
.SEL_PATTERN ("PATTERN"),
|
||||
.USE_DPORT ("TRUE"),
|
||||
.USE_MULT ("DYNAMIC"),
|
||||
.USE_PATTERN_DETECT ("NO_PATDET"),
|
||||
.USE_SIMD ("ONE48"),
|
||||
.MASK (48'h3FFFFFFFFFFF),
|
||||
.PATTERN (48'h000000000000),
|
||||
.IS_ALUMODE_INVERTED(4'b0),
|
||||
.IS_CARRYIN_INVERTED(1'b0),
|
||||
.IS_CLK_INVERTED (1'b0),
|
||||
.IS_INMODE_INVERTED (5'b0),
|
||||
.IS_OPMODE_INVERTED (7'b0)
|
||||
) testbench ();
|
||||
endmodule
|
||||
|
||||
module simd12_preadd_noreg_nocasc;
|
||||
testbench #(
|
||||
.ACASCREG (0),
|
||||
.ADREG (0),
|
||||
.ALUMODEREG (0),
|
||||
.AREG (0),
|
||||
.AUTORESET_PATDET ("NO_RESET"),
|
||||
.A_INPUT ("DIRECT"),
|
||||
.BCASCREG (0),
|
||||
.BREG (0),
|
||||
.B_INPUT ("DIRECT"),
|
||||
.CARRYINREG (0),
|
||||
.CARRYINSELREG (0),
|
||||
.CREG (0),
|
||||
.DREG (0),
|
||||
.INMODEREG (0),
|
||||
.MREG (0),
|
||||
.OPMODEREG (0),
|
||||
.PREG (0),
|
||||
.SEL_MASK ("MASK"),
|
||||
.SEL_PATTERN ("PATTERN"),
|
||||
.USE_DPORT ("TRUE"),
|
||||
.USE_MULT ("DYNAMIC"),
|
||||
.USE_PATTERN_DETECT ("NO_PATDET"),
|
||||
.USE_SIMD ("FOUR12"),
|
||||
.MASK (48'h3FFFFFFFFFFF),
|
||||
.PATTERN (48'h000000000000),
|
||||
.IS_ALUMODE_INVERTED(4'b0),
|
||||
.IS_CARRYIN_INVERTED(1'b0),
|
||||
.IS_CLK_INVERTED (1'b0),
|
||||
.IS_INMODE_INVERTED (5'b0),
|
||||
.IS_OPMODE_INVERTED (7'b0)
|
||||
) testbench ();
|
||||
endmodule
|
||||
|
||||
|
||||
module simd24_preadd_noreg_nocasc;
|
||||
testbench #(
|
||||
.ACASCREG (0),
|
||||
.ADREG (0),
|
||||
.ALUMODEREG (0),
|
||||
.AREG (0),
|
||||
.AUTORESET_PATDET ("NO_RESET"),
|
||||
.A_INPUT ("DIRECT"),
|
||||
.BCASCREG (0),
|
||||
.BREG (0),
|
||||
.B_INPUT ("DIRECT"),
|
||||
.CARRYINREG (0),
|
||||
.CARRYINSELREG (0),
|
||||
.CREG (0),
|
||||
.DREG (0),
|
||||
.INMODEREG (0),
|
||||
.MREG (0),
|
||||
.OPMODEREG (0),
|
||||
.PREG (0),
|
||||
.SEL_MASK ("MASK"),
|
||||
.SEL_PATTERN ("PATTERN"),
|
||||
.USE_DPORT ("TRUE"),
|
||||
.USE_MULT ("DYNAMIC"),
|
||||
.USE_PATTERN_DETECT ("NO_PATDET"),
|
||||
.USE_SIMD ("TWO24"),
|
||||
.MASK (48'h3FFFFFFFFFFF),
|
||||
.PATTERN (48'h000000000000),
|
||||
.IS_ALUMODE_INVERTED(4'b0),
|
||||
.IS_CARRYIN_INVERTED(1'b0),
|
||||
.IS_CLK_INVERTED (1'b0),
|
||||
.IS_INMODE_INVERTED (5'b0),
|
||||
.IS_OPMODE_INVERTED (7'b0)
|
||||
) testbench ();
|
||||
endmodule
|
||||
|
||||
module macc_overflow_underflow;
|
||||
testbench #(
|
||||
.ACASCREG (0),
|
||||
.ADREG (0),
|
||||
.ALUMODEREG (0),
|
||||
.AREG (0),
|
||||
.AUTORESET_PATDET ("NO_RESET"),
|
||||
.A_INPUT ("DIRECT"),
|
||||
.BCASCREG (0),
|
||||
.BREG (0),
|
||||
.B_INPUT ("DIRECT"),
|
||||
.CARRYINREG (0),
|
||||
.CARRYINSELREG (0),
|
||||
.CREG (0),
|
||||
.DREG (0),
|
||||
.INMODEREG (0),
|
||||
.MREG (0),
|
||||
.OPMODEREG (0),
|
||||
.PREG (1),
|
||||
.SEL_MASK ("MASK"),
|
||||
.SEL_PATTERN ("PATTERN"),
|
||||
.USE_DPORT ("FALSE"),
|
||||
.USE_MULT ("DYNAMIC"),
|
||||
.USE_PATTERN_DETECT ("PATDET"),
|
||||
.USE_SIMD ("ONE48"),
|
||||
.MASK (48'h1FFFFFFFFFFF),
|
||||
.PATTERN (48'h000000000000),
|
||||
.IS_ALUMODE_INVERTED(4'b0),
|
||||
.IS_CARRYIN_INVERTED(1'b0),
|
||||
.IS_CLK_INVERTED (1'b0),
|
||||
.IS_INMODE_INVERTED (5'b0),
|
||||
.IS_OPMODE_INVERTED (7'b0)
|
||||
) testbench ();
|
||||
endmodule
|
|
@ -19,9 +19,13 @@ module RAMB8BWER (
|
|||
input [1:0] WEAWEL,
|
||||
input [1:0] WEBWEU,
|
||||
|
||||
/* (* abc9_arrival=<TODO> *) */
|
||||
output [15:0] DOADO,
|
||||
/* (* abc9_arrival=<TODO> *) */
|
||||
output [15:0] DOBDO,
|
||||
/* (* abc9_arrival=<TODO> *) */
|
||||
output [1:0] DOPADOP,
|
||||
/* (* abc9_arrival=<TODO> *) */
|
||||
output [1:0] DOPBDOP
|
||||
);
|
||||
parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
|
@ -109,9 +113,13 @@ module RAMB16BWER (
|
|||
input [3:0] WEA,
|
||||
input [3:0] WEB,
|
||||
|
||||
/* (* abc9_arrival=<TODO> *) */
|
||||
output [31:0] DOA,
|
||||
/* (* abc9_arrival=<TODO> *) */
|
||||
output [31:0] DOB,
|
||||
/* (* abc9_arrival=<TODO> *) */
|
||||
output [3:0] DOPA,
|
||||
/* (* abc9_arrival=<TODO> *) */
|
||||
output [3:0] DOPB
|
||||
);
|
||||
parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
|
|
1819
techlibs/xilinx/xc6s_cells_xtra.v
Normal file
1819
techlibs/xilinx/xc6s_cells_xtra.v
Normal file
File diff suppressed because it is too large
Load diff
162
techlibs/xilinx/xc6s_ff_map.v
Normal file
162
techlibs/xilinx/xc6s_ff_map.v
Normal file
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// FF mapping for Spartan 6. The primitives used are the same as Series 7,
|
||||
// but with one major difference: the initial value is implied by the
|
||||
// primitive type used (FFs with reset pin must have INIT set to 0 or x, FFs
|
||||
// with set pin must have INIT set to 1 or x). For Yosys primitives without
|
||||
// set/reset, this means we have to pick the primitive type based on the INIT
|
||||
// value.
|
||||
|
||||
`ifndef _NO_FFS
|
||||
|
||||
module \$_DFF_N_ (input D, C, output Q);
|
||||
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
|
||||
FDSE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .S(1'b0));
|
||||
else
|
||||
FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0));
|
||||
endgenerate
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
module \$_DFF_P_ (input D, C, output Q);
|
||||
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
|
||||
FDSE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .S(1'b0));
|
||||
else
|
||||
FDRE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0));
|
||||
endgenerate
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
|
||||
module \$_DFFE_NP_ (input D, C, E, output Q);
|
||||
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
|
||||
FDSE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .S(1'b0));
|
||||
else
|
||||
FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0));
|
||||
endgenerate
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
module \$_DFFE_PP_ (input D, C, E, output Q);
|
||||
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
|
||||
FDSE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .S(1'b0));
|
||||
else
|
||||
FDRE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0));
|
||||
endgenerate
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
|
||||
module \$_DFF_NN0_ (input D, C, R, output Q);
|
||||
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
|
||||
$error("Spartan 6 doesn't support FFs with asynchronous reset initialized to 1");
|
||||
else
|
||||
FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR(!R));
|
||||
endgenerate
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
module \$_DFF_NP0_ (input D, C, R, output Q);
|
||||
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
|
||||
$error("Spartan 6 doesn't support FFs with asynchronous reset initialized to 1");
|
||||
else
|
||||
FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R));
|
||||
endgenerate
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
module \$_DFF_PN0_ (input D, C, R, output Q);
|
||||
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
|
||||
$error("Spartan 6 doesn't support FFs with asynchronous reset initialized to 1");
|
||||
else
|
||||
FDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR(!R));
|
||||
endgenerate
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
module \$_DFF_PP0_ (input D, C, R, output Q);
|
||||
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
|
||||
$error("Spartan 6 doesn't support FFs with asynchronous reset initialized to 1");
|
||||
else
|
||||
FDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R));
|
||||
endgenerate
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
|
||||
module \$_DFF_NN1_ (input D, C, R, output Q);
|
||||
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
generate if (_TECHMAP_WIREINIT_Q_ === 1'b0)
|
||||
$error("Spartan 6 doesn't support FFs with asynchronous set initialized to 0");
|
||||
else
|
||||
FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(!R));
|
||||
endgenerate
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
module \$_DFF_NP1_ (input D, C, R, output Q);
|
||||
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
generate if (_TECHMAP_WIREINIT_Q_ === 1'b0)
|
||||
$error("Spartan 6 doesn't support FFs with asynchronous set initialized to 0");
|
||||
else
|
||||
FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R));
|
||||
endgenerate
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
module \$_DFF_PN1_ (input D, C, R, output Q);
|
||||
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
generate if (_TECHMAP_WIREINIT_Q_ === 1'b0)
|
||||
$error("Spartan 6 doesn't support FFs with asynchronous set initialized to 0");
|
||||
else
|
||||
FDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(!R));
|
||||
endgenerate
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
module \$_DFF_PP1_ (input D, C, R, output Q);
|
||||
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
generate if (_TECHMAP_WIREINIT_Q_ === 1'b0)
|
||||
$error("Spartan 6 doesn't support FFs with asynchronous set initialized to 0");
|
||||
else
|
||||
FDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R));
|
||||
endgenerate
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
|
||||
module \$_DLATCH_N_ (input E, D, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
|
||||
LDPE #(.INIT(_TECHMAP_WIREINIT_Q_), .IS_G_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .PRE(1'b0));
|
||||
else
|
||||
LDCE #(.INIT(_TECHMAP_WIREINIT_Q_), .IS_G_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .CLR(1'b0));
|
||||
endgenerate
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
module \$_DLATCH_P_ (input E, D, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
|
||||
LDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .PRE(1'b0));
|
||||
else
|
||||
LDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .CLR(1'b0));
|
||||
endgenerate
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
|
||||
`endif
|
||||
|
2592
techlibs/xilinx/xc6v_cells_xtra.v
Normal file
2592
techlibs/xilinx/xc6v_cells_xtra.v
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,15 +1,25 @@
|
|||
// Max delays from https://github.com/SymbiFlow/prjxray-db/blob/f8e0364116b2983ac72a3dc8c509ea1cc79e2e3d/artix7/timings/BRAM_L.sdf#L138-L147
|
||||
|
||||
module RAMB18E1 (
|
||||
(* clkbuf_sink *)
|
||||
(* invertible_pin = "IS_CLKARDCLK_INVERTED" *)
|
||||
input CLKARDCLK,
|
||||
(* clkbuf_sink *)
|
||||
(* invertible_pin = "IS_CLKBWRCLK_INVERTED" *)
|
||||
input CLKBWRCLK,
|
||||
(* invertible_pin = "IS_ENARDEN_INVERTED" *)
|
||||
input ENARDEN,
|
||||
(* invertible_pin = "IS_ENBWREN_INVERTED" *)
|
||||
input ENBWREN,
|
||||
input REGCEAREGCE,
|
||||
input REGCEB,
|
||||
(* invertible_pin = "IS_RSTRAMARSTRAM_INVERTED" *)
|
||||
input RSTRAMARSTRAM,
|
||||
(* invertible_pin = "IS_RSTRAMB_INVERTED" *)
|
||||
input RSTRAMB,
|
||||
(* invertible_pin = "IS_RSTREGARSTREG_INVERTED" *)
|
||||
input RSTREGARSTREG,
|
||||
(* invertible_pin = "IS_RSTREGB_INVERTED" *)
|
||||
input RSTREGB,
|
||||
|
||||
input [13:0] ADDRARDADDR,
|
||||
|
@ -21,9 +31,13 @@ module RAMB18E1 (
|
|||
input [1:0] WEA,
|
||||
input [3:0] WEBWE,
|
||||
|
||||
(* abc9_arrival=2454 *)
|
||||
output [15:0] DOADO,
|
||||
(* abc9_arrival=2454 *)
|
||||
output [15:0] DOBDO,
|
||||
(* abc9_arrival=2454 *)
|
||||
output [1:0] DOPADOP,
|
||||
(* abc9_arrival=2454 *)
|
||||
output [1:0] DOPBDOP
|
||||
);
|
||||
parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
|
@ -126,16 +140,24 @@ endmodule
|
|||
|
||||
module RAMB36E1 (
|
||||
(* clkbuf_sink *)
|
||||
(* invertible_pin = "IS_CLKARDCLK_INVERTED" *)
|
||||
input CLKARDCLK,
|
||||
(* clkbuf_sink *)
|
||||
(* invertible_pin = "IS_CLKBWRCLK_INVERTED" *)
|
||||
input CLKBWRCLK,
|
||||
(* invertible_pin = "IS_ENARDEN_INVERTED" *)
|
||||
input ENARDEN,
|
||||
(* invertible_pin = "IS_ENBWREN_INVERTED" *)
|
||||
input ENBWREN,
|
||||
input REGCEAREGCE,
|
||||
input REGCEB,
|
||||
(* invertible_pin = "IS_RSTRAMARSTRAM_INVERTED" *)
|
||||
input RSTRAMARSTRAM,
|
||||
(* invertible_pin = "IS_RSTRAMB_INVERTED" *)
|
||||
input RSTRAMB,
|
||||
(* invertible_pin = "IS_RSTREGARSTREG_INVERTED" *)
|
||||
input RSTREGARSTREG,
|
||||
(* invertible_pin = "IS_RSTREGB_INVERTED" *)
|
||||
input RSTREGB,
|
||||
|
||||
input [15:0] ADDRARDADDR,
|
||||
|
@ -147,9 +169,13 @@ module RAMB36E1 (
|
|||
input [3:0] WEA,
|
||||
input [7:0] WEBWE,
|
||||
|
||||
(* abc9_arrival=2454 *)
|
||||
output [31:0] DOADO,
|
||||
(* abc9_arrival=2454 *)
|
||||
output [31:0] DOBDO,
|
||||
(* abc9_arrival=2454 *)
|
||||
output [3:0] DOPADOP,
|
||||
(* abc9_arrival=2454 *)
|
||||
output [3:0] DOPBDOP
|
||||
);
|
||||
parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
|
|
File diff suppressed because it is too large
Load diff
116
techlibs/xilinx/xc7_ff_map.v
Normal file
116
techlibs/xilinx/xc7_ff_map.v
Normal file
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// FF mapping for Virtex 6, Series 7 and Ultrascale. These families support
|
||||
// the following features:
|
||||
//
|
||||
// - a CLB flip-flop can be used as a latch or as a flip-flop
|
||||
// - a CLB flip-flop has the following pins:
|
||||
//
|
||||
// - data input
|
||||
// - clock (or gate for latches) (with optional inversion)
|
||||
// - clock enable (or gate enable, which is just ANDed with gate — unused by
|
||||
// synthesis)
|
||||
// - either a set or a reset input, which (for FFs) can be either
|
||||
// synchronous or asynchronous (with optional inversion)
|
||||
// - data output
|
||||
//
|
||||
// - a flip-flop also has an initial value, which is set at device
|
||||
// initialization (or whenever GSR is asserted)
|
||||
|
||||
`ifndef _NO_FFS
|
||||
|
||||
module \$_DFF_N_ (input D, C, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0));
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
module \$_DFF_P_ (input D, C, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
FDRE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0));
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
|
||||
module \$_DFFE_NP_ (input D, C, E, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0));
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
module \$_DFFE_PP_ (input D, C, E, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
FDRE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0));
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
|
||||
module \$_DFF_NN0_ (input D, C, R, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR(!R));
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
module \$_DFF_NP0_ (input D, C, R, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R));
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
module \$_DFF_PN0_ (input D, C, R, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
FDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR(!R));
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
module \$_DFF_PP0_ (input D, C, R, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
FDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R));
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
|
||||
module \$_DFF_NN1_ (input D, C, R, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(!R));
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
module \$_DFF_NP1_ (input D, C, R, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R));
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
module \$_DFF_PN1_ (input D, C, R, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
FDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(!R));
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
module \$_DFF_PP1_ (input D, C, R, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
FDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R));
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
|
||||
module \$_DLATCH_N_ (input E, D, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
LDCE #(.INIT(_TECHMAP_WIREINIT_Q_), .IS_G_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .CLR(1'b0));
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
module \$_DLATCH_P_ (input E, D, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
LDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .CLR(1'b0));
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
|
||||
`endif
|
||||
|
11768
techlibs/xilinx/xcu_cells_xtra.v
Normal file
11768
techlibs/xilinx/xcu_cells_xtra.v
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue