aboutsummaryrefslogtreecommitdiffstats
path: root/techlibs/ecp5
diff options
context:
space:
mode:
Diffstat (limited to 'techlibs/ecp5')
-rw-r--r--techlibs/ecp5/Makefile.inc3
-rw-r--r--techlibs/ecp5/abc9_map.v27
-rw-r--r--techlibs/ecp5/abc9_unmap.v5
-rw-r--r--techlibs/ecp5/arith_map.v10
-rw-r--r--techlibs/ecp5/cells_map.v1
-rw-r--r--techlibs/ecp5/cells_sim.v46
-rw-r--r--techlibs/ecp5/synth_ecp5.cc49
7 files changed, 86 insertions, 55 deletions
diff --git a/techlibs/ecp5/Makefile.inc b/techlibs/ecp5/Makefile.inc
index 217151e96..9a337b2b6 100644
--- a/techlibs/ecp5/Makefile.inc
+++ b/techlibs/ecp5/Makefile.inc
@@ -23,9 +23,6 @@ $(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))
-
-$(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))
EXTRA_OBJS += techlibs/ecp5/brams_init.mk techlibs/ecp5/brams_connect.mk
diff --git a/techlibs/ecp5/abc9_map.v b/techlibs/ecp5/abc9_map.v
deleted file mode 100644
index 113a35b91..000000000
--- a/techlibs/ecp5/abc9_map.v
+++ /dev/null
@@ -1,27 +0,0 @@
-// ---------------------------------------
-
-// Attach a (combinatorial) black-box onto the output
-// of this LUTRAM primitive to capture its
-// asynchronous read behaviour
-module TRELLIS_DPR16X4 (
- (* 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;
-
- 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 (.$DO($DO), .RAD(RAD), .DO(DO));
-endmodule
diff --git a/techlibs/ecp5/abc9_unmap.v b/techlibs/ecp5/abc9_unmap.v
deleted file mode 100644
index cbdffdaf1..000000000
--- a/techlibs/ecp5/abc9_unmap.v
+++ /dev/null
@@ -1,5 +0,0 @@
-// ---------------------------------------
-
-module \$__ABC9_DPR16X4_COMB (input [3:0] $DO, RAD, output [3:0] DO);
- assign DO = $DO;
-endmodule
diff --git a/techlibs/ecp5/arith_map.v b/techlibs/ecp5/arith_map.v
index 17bde0497..ffd42469c 100644
--- a/techlibs/ecp5/arith_map.v
+++ b/techlibs/ecp5/arith_map.v
@@ -26,15 +26,20 @@ module _80_ecp5_alu (A, B, CI, BI, X, Y, CO);
parameter B_WIDTH = 1;
parameter Y_WIDTH = 1;
+ (* force_downto *)
input [A_WIDTH-1:0] A;
+ (* force_downto *)
input [B_WIDTH-1:0] B;
+ (* force_downto *)
output [Y_WIDTH-1:0] X, Y;
input CI, BI;
+ (* force_downto *)
output [Y_WIDTH-1:0] CO;
wire _TECHMAP_FAIL_ = Y_WIDTH <= 4;
+ (* force_downto *)
wire [Y_WIDTH-1:0] A_buf, B_buf;
\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
@@ -48,10 +53,15 @@ module _80_ecp5_alu (A, B, CI, BI, X, Y, CO);
localparam Y_WIDTH2 = round_up2(Y_WIDTH);
+ (* force_downto *)
wire [Y_WIDTH2-1:0] AA = A_buf;
+ (* force_downto *)
wire [Y_WIDTH2-1:0] BB = BI ? ~B_buf : B_buf;
+ (* force_downto *)
wire [Y_WIDTH2-1:0] BX = B_buf;
+ (* force_downto *)
wire [Y_WIDTH2-1:0] C = {CO, CI};
+ (* force_downto *)
wire [Y_WIDTH2-1:0] FCO, Y1;
genvar i;
diff --git a/techlibs/ecp5/cells_map.v b/techlibs/ecp5/cells_map.v
index c031703a9..e19ac9ab9 100644
--- a/techlibs/ecp5/cells_map.v
+++ b/techlibs/ecp5/cells_map.v
@@ -70,6 +70,7 @@ module \$lut (A, Y);
parameter WIDTH = 0;
parameter LUT = 0;
+ (* force_downto *)
input [WIDTH-1:0] A;
output Y;
diff --git a/techlibs/ecp5/cells_sim.v b/techlibs/ecp5/cells_sim.v
index 12b33e925..357fd9173 100644
--- a/techlibs/ecp5/cells_sim.v
+++ b/techlibs/ecp5/cells_sim.v
@@ -186,6 +186,7 @@ module PFUMX (input ALUT, BLUT, C0, output Z);
endmodule
// ---------------------------------------
+(* abc9_box, lib_whitebox *)
module TRELLIS_DPR16X4 (
input [3:0] DI,
input [3:0] WAD,
@@ -222,10 +223,16 @@ module TRELLIS_DPR16X4 (
mem[WAD] <= DI;
assign DO = mem[RAD];
+
+ specify
+ // TODO
+ (RAD *> DO) = 0;
+ endspecify
endmodule
// ---------------------------------------
+(* abc9_box, lib_whitebox *)
module DPR16X4C (
input [3:0] DI,
input WCK, WRE,
@@ -281,6 +288,10 @@ module DPR16X4C (
assign DO = ram[RAD];
+ specify
+ // TODO
+ (RAD *> DO) = 0;
+ endspecify
endmodule
// ---------------------------------------
@@ -294,6 +305,9 @@ endmodule
// ---------------------------------------
+`ifdef YOSYS
+(* abc9_flop=(SRMODE != "ASYNC"), abc9_box=(SRMODE == "ASYNC"), lib_whitebox *)
+`endif
module TRELLIS_FF(input CLK, LSR, CE, DI, M, output reg Q);
parameter GSR = "ENABLED";
parameter [127:0] CEMUX = "1";
@@ -340,6 +354,38 @@ module TRELLIS_FF(input CLK, LSR, CE, DI, M, output reg Q);
Q <= DI;
end
endgenerate
+
+ generate
+ // TODO
+ if (CLKMUX == "INV")
+ specify
+ $setup(DI, negedge CLK, 0);
+ $setup(CE, negedge CLK, 0);
+ $setup(LSR, negedge CLK, 0);
+`ifndef YOSYS
+ if (SRMODE == "ASYNC" && muxlsr) (negedge CLK => (Q : srval)) = 0;
+`else
+ if (SRMODE == "ASYNC" && muxlsr) (LSR => Q) = 0; // Technically, this should be an edge sensitive path
+ // but for facilitating a bypass box, let's pretend it's
+ // a simple path
+`endif
+ if (!muxlsr && muxce) (negedge CLK => (Q : DI)) = 0;
+ endspecify
+ else
+ specify
+ $setup(DI, posedge CLK, 0);
+ $setup(CE, posedge CLK, 0);
+ $setup(LSR, posedge CLK, 0);
+`ifndef YOSYS
+ if (SRMODE == "ASYNC" && muxlsr) (posedge CLK => (Q : srval)) = 0;
+`else
+ if (SRMODE == "ASYNC" && muxlsr) (LSR => Q) = 0; // Technically, this should be an edge sensitive path
+ // but for facilitating a bypass box, let's pretend it's
+ // a simple path
+`endif
+ if (!muxlsr && muxce) (posedge CLK => (Q : DI)) = 0;
+ endspecify
+ endgenerate
endmodule
// ---------------------------------------
diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc
index b9b236a0c..e5c1f7550 100644
--- a/techlibs/ecp5/synth_ecp5.cc
+++ b/techlibs/ecp5/synth_ecp5.cc
@@ -66,6 +66,9 @@ struct SynthEcp5Pass : public ScriptPass
log(" -noflatten\n");
log(" do not flatten design before synthesis\n");
log("\n");
+ log(" -dff\n");
+ log(" run 'abc'/'abc9' with -dff option\n");
+ log("\n");
log(" -retime\n");
log(" run 'abc' with '-dff -D 1' options\n");
log("\n");
@@ -107,7 +110,7 @@ struct SynthEcp5Pass : public ScriptPass
}
string top_opt, blif_file, edif_file, json_file;
- bool noccu2, nodffe, nobram, nolutram, nowidelut, asyncprld, flatten, retime, abc2, abc9, nodsp, vpr;
+ bool noccu2, nodffe, nobram, nolutram, nowidelut, asyncprld, flatten, dff, retime, abc2, abc9, nodsp, vpr;
void clear_flags() YS_OVERRIDE
{
@@ -122,6 +125,7 @@ struct SynthEcp5Pass : public ScriptPass
nowidelut = false;
asyncprld = false;
flatten = true;
+ dff = false;
retime = false;
abc2 = false;
vpr = false;
@@ -169,6 +173,10 @@ struct SynthEcp5Pass : public ScriptPass
flatten = false;
continue;
}
+ if (args[argidx] == "-dff") {
+ dff = true;
+ continue;
+ }
if (args[argidx] == "-retime") {
retime = true;
continue;
@@ -307,6 +315,8 @@ struct SynthEcp5Pass : public ScriptPass
run("opt_clean");
if (!nodffe)
run("dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_*");
+ if ((abc9 && dff) || help_mode)
+ run("zinit -all w:* t:$_DFF_?_ t:$_DFFE_??_ t:$__DFFS*", "(only if -abc9 and -dff");
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");
@@ -318,17 +328,13 @@ struct SynthEcp5Pass : public ScriptPass
if (check_label("map_luts"))
{
- if (abc2 || help_mode) {
+ if (abc2 || help_mode)
run("abc", " (only if -abc2)");
- }
- std::string techmap_args = asyncprld ? "" : "-map +/ecp5/latches_map.v";
- if (abc9)
- techmap_args += " -map +/ecp5/abc9_map.v -max_iter 1";
- if (!asyncprld || abc9)
- run("techmap " + techmap_args);
+ if (!asyncprld || help_mode)
+ run("techmap -map +/ecp5/latches_map.v", "(skip if -asyncprld)");
if (abc9) {
- run("read_verilog -icells -lib -specify +/abc9_model.v +/ecp5/abc9_model.v");
+ run("read_verilog -icells -lib -specify +/ecp5/abc9_model.v");
std::string abc9_opts;
if (nowidelut)
abc9_opts += " -maxlut 4";
@@ -338,26 +344,29 @@ struct SynthEcp5Pass : public ScriptPass
else
abc9_opts += stringf(" -W %s", RTLIL::constpad.at(k).c_str());
if (nowidelut)
- run("abc9 -maxlut 4 -W 200");
- else
- run("abc9 -W 200");
- run("techmap -map +/ecp5/abc9_unmap.v");
+ abc9_opts += " -maxlut 4";
+ if (dff)
+ abc9_opts += " -dff";
+ run("abc9" + abc9_opts);
} else {
+ std::string abc_args = " -dress";
if (nowidelut)
- run("abc -lut 4 -dress");
+ abc_args += " -lut 4";
else
- run("abc -lut 4:7 -dress");
+ abc_args += " -lut 4:7";
+ if (dff)
+ abc_args += " -dff";
+ run("abc" + abc_args);
}
run("clean");
}
if (check_label("map_cells"))
{
- if (vpr)
- run("techmap -D NO_LUT -map +/ecp5/cells_map.v");
- else
- run("techmap -map +/ecp5/cells_map.v", "(with -D NO_LUT in vpr mode)");
-
+ if (help_mode)
+ run("techmap -map +/ecp5/cells_map.v", "(skip if -vpr)");
+ else if (!vpr)
+ run("techmap -map +/ecp5/cells_map.v");
run("opt_lut_ins -tech ecp5");
run("clean");
}