aboutsummaryrefslogtreecommitdiffstats
path: root/techlibs/ecp5
diff options
context:
space:
mode:
Diffstat (limited to 'techlibs/ecp5')
-rw-r--r--techlibs/ecp5/Makefile.inc4
-rw-r--r--techlibs/ecp5/abc9_5g.box41
-rw-r--r--techlibs/ecp5/abc9_map.v19
-rw-r--r--techlibs/ecp5/abc9_model.v2
-rw-r--r--techlibs/ecp5/abc9_unmap.v4
-rw-r--r--techlibs/ecp5/brams.txt (renamed from techlibs/ecp5/bram.txt)0
-rw-r--r--techlibs/ecp5/cells_map.v147
-rw-r--r--techlibs/ecp5/cells_sim.v12
-rw-r--r--techlibs/ecp5/lutrams.txt (renamed from techlibs/ecp5/lutram.txt)0
-rw-r--r--techlibs/ecp5/synth_ecp5.cc31
10 files changed, 125 insertions, 135 deletions
diff --git a/techlibs/ecp5/Makefile.inc b/techlibs/ecp5/Makefile.inc
index 46463f510..2c33f23b9 100644
--- a/techlibs/ecp5/Makefile.inc
+++ b/techlibs/ecp5/Makefile.inc
@@ -8,9 +8,9 @@ $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_map.v))
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_sim.v))
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_bb.v))
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/lutrams_map.v))
-$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/lutram.txt))
+$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/lutrams.txt))
$(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/brams.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))
diff --git a/techlibs/ecp5/abc9_5g.box b/techlibs/ecp5/abc9_5g.box
index 2bc945a54..f153a665e 100644
--- a/techlibs/ecp5/abc9_5g.box
+++ b/techlibs/ecp5/abc9_5g.box
@@ -1,43 +1,36 @@
-# NB: Inputs/Outputs must be ordered alphabetically
-# (with exceptions for carry in/out)
+# NB: Box inputs/outputs must each be in the same order
+# as their corresponding module definition
+# (with exceptions detailed below)
# Box 1 : CCU2C (2xCARRY + 2xLUT4)
-# Outputs: S0, S1, COUT
-# (NB: carry chain input/output must be last
-# input/output and bus has been moved
-# there overriding the otherwise
+# (Exception: carry chain input/output must be the
+# last input and output and the entire bus has been
+# moved there overriding the otherwise
# alphabetical ordering)
# name ID w/b ins outs
CCU2C 1 1 9 3
-
-#A0 A1 B0 B1 C0 C1 D0 D1 CIN
-379 - 379 - 275 - 141 - 257
-630 379 630 379 526 275 392 141 273
-516 516 516 516 412 412 278 278 43
+#A0 B0 C0 D0 A1 B1 C1 D1 CIN
+379 379 275 141 - - - - 257 # S0
+630 630 526 392 379 379 275 141 273 # S1
+516 516 412 278 516 516 412 278 43 # COUT
# Box 2 : TRELLIS_DPR16X4_COMB (16x4 dist ram)
-# Outputs: DO0, DO1, DO2, DO3
# name ID w/b ins outs
$__ABC9_DPR16X4_COMB 2 0 8 4
-
-#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
+#$DO0 $DO1 $DO2 $DO3 RAD0 RAD1 RAD2 RAD3
+0 0 0 0 141 379 275 379 # DO0
+0 0 0 0 141 379 275 379 # DO1
+0 0 0 0 141 379 275 379 # DO2
+0 0 0 0 141 379 275 379 # DO3
# Box 3 : PFUMX (MUX2)
-# Outputs: Z
# name ID w/b ins outs
PFUMX 3 1 3 1
-
#ALUT BLUT C0
-98 98 151
+98 98 151 # Z
# Box 4 : L6MUX21 (MUX2)
-# Outputs: Z
# name ID w/b ins outs
L6MUX21 4 1 3 1
-
#D0 D1 SD
-140 141 148
+140 141 148 # Z
diff --git a/techlibs/ecp5/abc9_map.v b/techlibs/ecp5/abc9_map.v
index d8d70f9f6..113a35b91 100644
--- a/techlibs/ecp5/abc9_map.v
+++ b/techlibs/ecp5/abc9_map.v
@@ -1,24 +1,27 @@
// ---------------------------------------
+// Attach a (combinatorial) black-box onto the output
+// of this LUTRAM primitive to capture its
+// asynchronous read behaviour
module TRELLIS_DPR16X4 (
- input [3:0] DI,
- input [3:0] WAD,
- input WRE,
- input WCK,
- input [3:0] RAD,
+ (* techmap_autopurge *) input [3:0] DI,
+ (* techmap_autopurge *) input [3:0] WAD,
+ (* techmap_autopurge *) input WRE,
+ (* techmap_autopurge *) input WCK,
+ (* techmap_autopurge *) input [3:0] RAD,
output [3:0] DO
);
parameter WCKMUX = "WCK";
parameter WREMUX = "WRE";
parameter [63:0] INITVAL = 64'h0000000000000000;
- wire [3:0] \$DO ;
+ 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 )
+ .RAD(RAD), .DO($DO)
);
- \$__ABC9_DPR16X4_COMB do (.A(\$DO ), .S(RAD), .Y(DO));
+ $__ABC9_DPR16X4_COMB do (.$DO($DO), .RAD(RAD), .DO(DO));
endmodule
diff --git a/techlibs/ecp5/abc9_model.v b/techlibs/ecp5/abc9_model.v
index 1dc8b5617..81e5cd070 100644
--- a/techlibs/ecp5/abc9_model.v
+++ b/techlibs/ecp5/abc9_model.v
@@ -1,5 +1,5 @@
// ---------------------------------------
(* abc9_box_id=2 *)
-module \$__ABC9_DPR16X4_COMB (input [3:0] A, S, output [3:0] Y);
+module \$__ABC9_DPR16X4_COMB (input [3:0] $DO, RAD, output [3:0] DO);
endmodule
diff --git a/techlibs/ecp5/abc9_unmap.v b/techlibs/ecp5/abc9_unmap.v
index 9ae143c46..cbdffdaf1 100644
--- a/techlibs/ecp5/abc9_unmap.v
+++ b/techlibs/ecp5/abc9_unmap.v
@@ -1,5 +1,5 @@
// ---------------------------------------
-module \$__ABC9_DPR16X4_COMB (input [3:0] A, S, output [3:0] Y);
- assign Y = A;
+module \$__ABC9_DPR16X4_COMB (input [3:0] $DO, RAD, output [3:0] DO);
+ assign DO = $DO;
endmodule
diff --git a/techlibs/ecp5/bram.txt b/techlibs/ecp5/brams.txt
index 777ccaa2e..777ccaa2e 100644
--- a/techlibs/ecp5/bram.txt
+++ b/techlibs/ecp5/brams.txt
diff --git a/techlibs/ecp5/cells_map.v b/techlibs/ecp5/cells_map.v
index 71ae9237b..c031703a9 100644
--- a/techlibs/ecp5/cells_map.v
+++ b/techlibs/ecp5/cells_map.v
@@ -47,6 +47,21 @@ module \$__DFFSE_NP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .
module \$__DFFSE_PP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$__DFFSE_PP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
+`ifdef ASYNC_PRLD
+module \$_DLATCH_N_ (input E, input D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.LSR(!E), .DI(1'b0), .M(D), .Q(Q)); endmodule
+module \$_DLATCH_P_ (input E, input D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.LSR(E), .DI(1'b0), .M(D), .Q(Q)); endmodule
+
+module \$_DFFSR_NNN_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!S || !R), .DI(D), .M(R), .Q(Q)); endmodule
+module \$_DFFSR_NNP_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!S || R), .DI(D), .M(!R), .Q(Q)); endmodule
+module \$_DFFSR_NPN_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(S || !R), .DI(D), .M(R), .Q(Q)); endmodule
+module \$_DFFSR_NPP_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(S || R), .DI(D), .M(!R), .Q(Q)); endmodule
+
+module \$_DFFSR_PNN_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!S || !R), .DI(D), .M(R), .Q(Q)); endmodule
+module \$_DFFSR_PNP_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!S || R), .DI(D), .M(!R), .Q(Q)); endmodule
+module \$_DFFSR_PPN_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(S || !R), .DI(D), .M(R), .Q(Q)); endmodule
+module \$_DFFSR_PPP_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(S || R), .DI(D), .M(!R), .Q(Q)); endmodule
+`endif
+
`include "cells_ff.vh"
`include "cells_io.vh"
@@ -58,102 +73,80 @@ module \$lut (A, Y);
input [WIDTH-1:0] A;
output Y;
- // Need to swap input ordering, and fix init accordingly,
- // to match ABC's expectation of LUT inputs in non-decreasing
- // delay order
- localparam P_WIDTH = WIDTH < 4 ? 4 : WIDTH;
- function [P_WIDTH-1:0] permute_index;
- input [P_WIDTH-1:0] i;
- integer j;
- begin
- permute_index = 0;
- for (j = 0; j < P_WIDTH; j = j + 1)
- permute_index[P_WIDTH-1 - j] = i[j];
- end
- endfunction
-
- function [2**P_WIDTH-1:0] permute_init;
- integer i;
- begin
- permute_init = 0;
- for (i = 0; i < 2**P_WIDTH; i = i + 1)
- permute_init[i] = LUT[permute_index(i)];
- end
- endfunction
-
- parameter [2**P_WIDTH-1:0] P_LUT = permute_init();
-
generate
if (WIDTH == 1) begin
- LUT4 #(.INIT(P_LUT)) _TECHMAP_REPLACE_ (.Z(Y),
+ localparam [15:0] INIT = {{8{LUT[1]}}, {8{LUT[0]}}};
+ LUT4 #(.INIT(INIT)) _TECHMAP_REPLACE_ (.Z(Y),
.A(1'b0), .B(1'b0), .C(1'b0), .D(A[0]));
end else
if (WIDTH == 2) begin
- LUT4 #(.INIT(P_LUT)) _TECHMAP_REPLACE_ (.Z(Y),
- .A(1'b0), .B(1'b0), .C(A[1]), .D(A[0]));
+ localparam [15:0] INIT = {{4{LUT[3]}}, {4{LUT[2]}}, {4{LUT[1]}}, {4{LUT[0]}}};
+ LUT4 #(.INIT(INIT)) _TECHMAP_REPLACE_ (.Z(Y),
+ .A(1'b0), .B(1'b0), .C(A[0]), .D(A[1]));
end else
if (WIDTH == 3) begin
- LUT4 #(.INIT(P_LUT)) _TECHMAP_REPLACE_ (.Z(Y),
- .A(1'b0), .B(A[2]), .C(A[1]), .D(A[0]));
+ localparam [15:0] INIT = {{2{LUT[7]}}, {2{LUT[6]}}, {2{LUT[5]}}, {2{LUT[4]}}, {2{LUT[3]}}, {2{LUT[2]}}, {2{LUT[1]}}, {2{LUT[0]}}};
+ LUT4 #(.INIT(INIT)) _TECHMAP_REPLACE_ (.Z(Y),
+ .A(1'b0), .B(A[0]), .C(A[1]), .D(A[2]));
end else
if (WIDTH == 4) begin
- LUT4 #(.INIT(P_LUT)) _TECHMAP_REPLACE_ (.Z(Y),
- .A(A[3]), .B(A[2]), .C(A[1]), .D(A[0]));
+ LUT4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.Z(Y),
+ .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
`ifndef NO_PFUMUX
end else
if (WIDTH == 5) begin
wire f0, f1;
- LUT4 #(.INIT(P_LUT[15: 0])) lut0 (.Z(f0),
- .A(A[4]), .B(A[3]), .C(A[2]), .D(A[1]));
- LUT4 #(.INIT(P_LUT[31:16])) lut1 (.Z(f1),
- .A(A[4]), .B(A[3]), .C(A[2]), .D(A[1]));
- PFUMX mux5(.ALUT(f1), .BLUT(f0), .C0(A[0]), .Z(Y));
+ LUT4 #(.INIT(LUT[15: 0])) lut0 (.Z(f0),
+ .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
+ LUT4 #(.INIT(LUT[31:16])) lut1 (.Z(f1),
+ .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
+ PFUMX mux5(.ALUT(f1), .BLUT(f0), .C0(A[4]), .Z(Y));
end else
if (WIDTH == 6) begin
wire f0, f1, f2, f3, g0, g1;
- LUT4 #(.INIT(P_LUT[15: 0])) lut0 (.Z(f0),
- .A(A[5]), .B(A[4]), .C(A[3]), .D(A[2]));
- LUT4 #(.INIT(P_LUT[31:16])) lut1 (.Z(f1),
- .A(A[5]), .B(A[4]), .C(A[3]), .D(A[2]));
-
- LUT4 #(.INIT(P_LUT[47:32])) lut2 (.Z(f2),
- .A(A[5]), .B(A[4]), .C(A[3]), .D(A[2]));
- LUT4 #(.INIT(P_LUT[63:48])) lut3 (.Z(f3),
- .A(A[5]), .B(A[4]), .C(A[3]), .D(A[2]));
-
- PFUMX mux50(.ALUT(f1), .BLUT(f0), .C0(A[1]), .Z(g0));
- PFUMX mux51(.ALUT(f3), .BLUT(f2), .C0(A[1]), .Z(g1));
- L6MUX21 mux6 (.D0(g0), .D1(g1), .SD(A[0]), .Z(Y));
+ LUT4 #(.INIT(LUT[15: 0])) lut0 (.Z(f0),
+ .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
+ LUT4 #(.INIT(LUT[31:16])) lut1 (.Z(f1),
+ .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
+
+ LUT4 #(.INIT(LUT[47:32])) lut2 (.Z(f2),
+ .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
+ LUT4 #(.INIT(LUT[63:48])) lut3 (.Z(f3),
+ .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
+
+ PFUMX mux50(.ALUT(f1), .BLUT(f0), .C0(A[4]), .Z(g0));
+ PFUMX mux51(.ALUT(f3), .BLUT(f2), .C0(A[4]), .Z(g1));
+ L6MUX21 mux6 (.D0(g0), .D1(g1), .SD(A[5]), .Z(Y));
end else
if (WIDTH == 7) begin
wire f0, f1, f2, f3, f4, f5, f6, f7, g0, g1, g2, g3, h0, h1;
- LUT4 #(.INIT(P_LUT[15: 0])) lut0 (.Z(f0),
- .A(A[6]), .B(A[5]), .C(A[4]), .D(A[3]));
- LUT4 #(.INIT(P_LUT[31:16])) lut1 (.Z(f1),
- .A(A[6]), .B(A[5]), .C(A[4]), .D(A[3]));
-
- LUT4 #(.INIT(P_LUT[47:32])) lut2 (.Z(f2),
- .A(A[6]), .B(A[5]), .C(A[4]), .D(A[3]));
- LUT4 #(.INIT(P_LUT[63:48])) lut3 (.Z(f3),
- .A(A[6]), .B(A[5]), .C(A[4]), .D(A[3]));
-
- LUT4 #(.INIT(P_LUT[79:64])) lut4 (.Z(f4),
- .A(A[6]), .B(A[5]), .C(A[4]), .D(A[3]));
- LUT4 #(.INIT(P_LUT[95:80])) lut5 (.Z(f5),
- .A(A[6]), .B(A[5]), .C(A[4]), .D(A[3]));
-
- LUT4 #(.INIT(P_LUT[111: 96])) lut6 (.Z(f6),
- .A(A[6]), .B(A[5]), .C(A[4]), .D(A[3]));
- LUT4 #(.INIT(P_LUT[127:112])) lut7 (.Z(f7),
- .A(A[6]), .B(A[5]), .C(A[4]), .D(A[3]));
-
- PFUMX mux50(.ALUT(f1), .BLUT(f0), .C0(A[2]), .Z(g0));
- PFUMX mux51(.ALUT(f3), .BLUT(f2), .C0(A[2]), .Z(g1));
- PFUMX mux52(.ALUT(f5), .BLUT(f4), .C0(A[2]), .Z(g2));
- PFUMX mux53(.ALUT(f7), .BLUT(f6), .C0(A[2]), .Z(g3));
- L6MUX21 mux60 (.D0(g0), .D1(g1), .SD(A[1]), .Z(h0));
- L6MUX21 mux61 (.D0(g2), .D1(g3), .SD(A[1]), .Z(h1));
- L6MUX21 mux7 (.D0(h0), .D1(h1), .SD(A[0]), .Z(Y));
+ LUT4 #(.INIT(LUT[15: 0])) lut0 (.Z(f0),
+ .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
+ LUT4 #(.INIT(LUT[31:16])) lut1 (.Z(f1),
+ .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
+
+ LUT4 #(.INIT(LUT[47:32])) lut2 (.Z(f2),
+ .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
+ LUT4 #(.INIT(LUT[63:48])) lut3 (.Z(f3),
+ .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
+
+ LUT4 #(.INIT(LUT[79:64])) lut4 (.Z(f4),
+ .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
+ LUT4 #(.INIT(LUT[95:80])) lut5 (.Z(f5),
+ .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
+
+ LUT4 #(.INIT(LUT[111: 96])) lut6 (.Z(f6),
+ .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
+ LUT4 #(.INIT(LUT[127:112])) lut7 (.Z(f7),
+ .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
+
+ PFUMX mux50(.ALUT(f1), .BLUT(f0), .C0(A[4]), .Z(g0));
+ PFUMX mux51(.ALUT(f3), .BLUT(f2), .C0(A[4]), .Z(g1));
+ PFUMX mux52(.ALUT(f5), .BLUT(f4), .C0(A[4]), .Z(g2));
+ PFUMX mux53(.ALUT(f7), .BLUT(f6), .C0(A[4]), .Z(g3));
+ L6MUX21 mux60 (.D0(g0), .D1(g1), .SD(A[5]), .Z(h0));
+ L6MUX21 mux61 (.D0(g2), .D1(g3), .SD(A[5]), .Z(h1));
+ L6MUX21 mux7 (.D0(h0), .D1(h1), .SD(A[6]), .Z(Y));
`endif
end else begin
wire _TECHMAP_FAIL_ = 1;
diff --git a/techlibs/ecp5/cells_sim.v b/techlibs/ecp5/cells_sim.v
index f467218cc..0d3ec4e5b 100644
--- a/techlibs/ecp5/cells_sim.v
+++ b/techlibs/ecp5/cells_sim.v
@@ -1,5 +1,6 @@
// ---------------------------------------
+(* lib_whitebox *)
module LUT4(input A, B, C, D, output Z);
parameter [15:0] INIT = 16'h0000;
wire [7:0] s3 = D ? INIT[15:8] : INIT[7:0];
@@ -31,13 +32,8 @@ module CCU2C(
// First half
wire LUT4_0, LUT2_0;
-`ifdef _ABC
- assign LUT4_0 = INIT0[{D0, C0, B0, A0}];
- assign LUT2_0 = INIT0[{2'b00, B0, A0}];
-`else
LUT4 #(.INIT(INIT0)) lut4_0(.A(A0), .B(B0), .C(C0), .D(D0), .Z(LUT4_0));
LUT2 #(.INIT(INIT0[3:0])) lut2_0(.A(A0), .B(B0), .Z(LUT2_0));
-`endif
wire gated_cin_0 = (INJECT1_0 == "YES") ? 1'b0 : CIN;
assign S0 = LUT4_0 ^ gated_cin_0;
@@ -46,13 +42,8 @@ module CCU2C(
// Second half
wire LUT4_1, LUT2_1;
-`ifdef _ABC
- assign LUT4_1 = INIT1[{D1, C1, B1, A1}];
- assign LUT2_1 = INIT1[{2'b00, B1, A1}];
-`else
LUT4 #(.INIT(INIT1)) lut4_1(.A(A1), .B(B1), .C(C1), .D(D1), .Z(LUT4_1));
LUT2 #(.INIT(INIT1[3:0])) lut2_1(.A(A1), .B(B1), .Z(LUT2_1));
-`endif
wire gated_cin_1 = (INJECT1_1 == "YES") ? 1'b0 : cout_0;
assign S1 = LUT4_1 ^ gated_cin_1;
@@ -209,6 +200,7 @@ endmodule
// ---------------------------------------
+(* lib_whitebox *)
module LUT2(input A, B, output Z);
parameter [3:0] INIT = 4'h0;
wire [1:0] s1 = B ? INIT[ 3:2] : INIT[1:0];
diff --git a/techlibs/ecp5/lutram.txt b/techlibs/ecp5/lutrams.txt
index b94357429..b94357429 100644
--- a/techlibs/ecp5/lutram.txt
+++ b/techlibs/ecp5/lutrams.txt
diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc
index 4cbb56ea1..6583f43fd 100644
--- a/techlibs/ecp5/synth_ecp5.cc
+++ b/techlibs/ecp5/synth_ecp5.cc
@@ -62,7 +62,7 @@ struct SynthEcp5Pass : public ScriptPass
log(" do not flatten design before synthesis\n");
log("\n");
log(" -retime\n");
- log(" run 'abc' with -dff option\n");
+ log(" run 'abc' with '-dff -D 1' options\n");
log("\n");
log(" -noccu2\n");
log(" do not use CCU2 cells in output netlist\n");
@@ -79,6 +79,9 @@ struct SynthEcp5Pass : public ScriptPass
log(" -nowidelut\n");
log(" do not use PFU muxes to implement LUTs larger than LUT4s\n");
log("\n");
+ log(" -asyncprld\n");
+ log(" use async PRLD mode to implement DLATCH and DFFSR (EXPERIMENTAL)\n");
+ log("\n");
log(" -abc2\n");
log(" run two passes of 'abc' for slightly improved logic density\n");
log("\n");
@@ -99,7 +102,7 @@ struct SynthEcp5Pass : public ScriptPass
}
string top_opt, blif_file, edif_file, json_file;
- bool noccu2, nodffe, nobram, nolutram, nowidelut, flatten, retime, abc2, abc9, nodsp, vpr;
+ bool noccu2, nodffe, nobram, nolutram, nowidelut, asyncprld, flatten, retime, abc2, abc9, nodsp, vpr;
void clear_flags() YS_OVERRIDE
{
@@ -112,6 +115,7 @@ struct SynthEcp5Pass : public ScriptPass
nobram = false;
nolutram = false;
nowidelut = false;
+ asyncprld = false;
flatten = true;
retime = false;
abc2 = false;
@@ -176,6 +180,10 @@ struct SynthEcp5Pass : public ScriptPass
nobram = true;
continue;
}
+ if (args[argidx] == "-asyncprld") {
+ asyncprld = true;
+ continue;
+ }
if (args[argidx] == "-nolutram" || /*deprecated alias*/ args[argidx] == "-nodram") {
nolutram = true;
continue;
@@ -222,7 +230,7 @@ struct SynthEcp5Pass : public ScriptPass
{
if (check_label("begin"))
{
- run("read_verilog -D_ABC -lib +/ecp5/cells_sim.v +/ecp5/cells_bb.v");
+ run("read_verilog -lib +/ecp5/cells_sim.v +/ecp5/cells_bb.v");
run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
}
@@ -258,13 +266,13 @@ struct SynthEcp5Pass : public ScriptPass
if (!nobram && check_label("map_bram", "(skip if -nobram)"))
{
- run("memory_bram -rules +/ecp5/bram.txt");
+ run("memory_bram -rules +/ecp5/brams.txt");
run("techmap -map +/ecp5/brams_map.v");
}
if (!nolutram && check_label("map_lutram", "(skip if -nolutram)"))
{
- run("memory_bram -rules +/ecp5/lutram.txt");
+ run("memory_bram -rules +/ecp5/lutrams.txt");
run("techmap -map +/ecp5/lutrams_map.v");
}
@@ -282,7 +290,7 @@ struct SynthEcp5Pass : public ScriptPass
else
run("techmap -map +/techmap.v -map +/ecp5/arith_map.v");
if (retime || help_mode)
- run("abc -dff", "(only if -retime)");
+ run("abc -dff -D 1", "(only if -retime)");
}
if (check_label("map_ffs"))
@@ -292,7 +300,7 @@ struct SynthEcp5Pass : public ScriptPass
run("opt_clean");
if (!nodffe)
run("dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_*");
- run("techmap -D NO_LUT -map +/ecp5/cells_map.v");
+ run(stringf("techmap -D NO_LUT %s -map +/ecp5/cells_map.v", help_mode ? "[-D ASYNC_PRLD]" : (asyncprld ? "-D ASYNC_PRLD" : "")));
run("opt_expr -undriven -mux_undef");
run("simplemap");
run("ecp5_ffinit");
@@ -306,17 +314,18 @@ struct SynthEcp5Pass : public ScriptPass
if (abc2 || help_mode) {
run("abc", " (only if -abc2)");
}
- std::string techmap_args = "-map +/ecp5/latches_map.v";
+ std::string techmap_args = asyncprld ? "" : "-map +/ecp5/latches_map.v";
if (abc9)
techmap_args += " -map +/ecp5/abc9_map.v -max_iter 1";
- run("techmap " + techmap_args);
+ if (!asyncprld || abc9)
+ run("techmap " + techmap_args);
if (abc9) {
run("read_verilog -icells -lib +/ecp5/abc9_model.v");
if (nowidelut)
- run("abc9 -lut +/ecp5/abc9_5g_nowide.lut -box +/ecp5/abc9_5g.box -W 200 -nomfs");
+ run("abc9 -lut +/ecp5/abc9_5g_nowide.lut -box +/ecp5/abc9_5g.box -W 200");
else
- run("abc9 -lut +/ecp5/abc9_5g.lut -box +/ecp5/abc9_5g.box -W 200 -nomfs");
+ run("abc9 -lut +/ecp5/abc9_5g.lut -box +/ecp5/abc9_5g.box -W 200");
run("techmap -map +/ecp5/abc9_unmap.v");
} else {
if (nowidelut)