aboutsummaryrefslogtreecommitdiffstats
path: root/techlibs/quicklogic
diff options
context:
space:
mode:
Diffstat (limited to 'techlibs/quicklogic')
-rw-r--r--techlibs/quicklogic/Makefile.inc4
-rw-r--r--techlibs/quicklogic/abc9_map.v26
-rw-r--r--techlibs/quicklogic/abc9_model.v11
-rw-r--r--techlibs/quicklogic/abc9_unmap.v14
-rw-r--r--techlibs/quicklogic/pp3_cells_sim.v5
-rw-r--r--techlibs/quicklogic/synth_quicklogic.cc25
6 files changed, 80 insertions, 5 deletions
diff --git a/techlibs/quicklogic/Makefile.inc b/techlibs/quicklogic/Makefile.inc
index 9a07c2eed..51eb28d44 100644
--- a/techlibs/quicklogic/Makefile.inc
+++ b/techlibs/quicklogic/Makefile.inc
@@ -7,3 +7,7 @@ $(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/pp3_cells_map.
$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/cells_sim.v))
$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/lut_sim.v))
$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/pp3_cells_sim.v))
+
+$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/abc9_model.v))
+$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/abc9_map.v))
+$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/abc9_unmap.v))
diff --git a/techlibs/quicklogic/abc9_map.v b/techlibs/quicklogic/abc9_map.v
new file mode 100644
index 000000000..46c11d675
--- /dev/null
+++ b/techlibs/quicklogic/abc9_map.v
@@ -0,0 +1,26 @@
+// This file exists to map purely-synchronous flops to ABC9 flops, while
+// mapping flops with asynchronous-set/clear as boxes, this is because ABC9
+// doesn't support asynchronous-set/clear flops in sequential synthesis.
+
+module dffepc (
+ output Q,
+ input D,
+ input CLK,
+ input EN,
+ input CLR,
+ input PRE
+);
+
+parameter INIT = 1'b0;
+
+parameter _TECHMAP_CONSTMSK_CLR_ = 1'b0;
+parameter _TECHMAP_CONSTMSK_PRE_ = 1'b0;
+parameter _TECHMAP_CONSTVAL_CLR_ = 1'b0;
+parameter _TECHMAP_CONSTVAL_PRE_ = 1'b0;
+
+if (_TECHMAP_CONSTMSK_CLR_ != 1'b0 && _TECHMAP_CONSTMSK_PRE_ != 1'b0 && _TECHMAP_CONSTVAL_CLR_ == 1'b0 && _TECHMAP_CONSTVAL_PRE_ == 1'b0)
+ $__PP3_DFFEPC_SYNCONLY _TECHMAP_REPLACE_ (.Q(Q), .D(D), .CLK(CLK), .EN(EN));
+else
+ wire _TECHMAP_FAIL_ = 1;
+
+endmodule
diff --git a/techlibs/quicklogic/abc9_model.v b/techlibs/quicklogic/abc9_model.v
new file mode 100644
index 000000000..06d4a2a56
--- /dev/null
+++ b/techlibs/quicklogic/abc9_model.v
@@ -0,0 +1,11 @@
+(* abc9_flop, lib_whitebox *)
+module $__PP3_DFFEPC_SYNCONLY (
+ output Q,
+ input D,
+ input CLK,
+ input EN,
+);
+
+ dffepc ff (.Q(Q), .D(D), .CLK(CLK), .EN(EN), .PRE(1'b0), .CLR(1'b0));
+
+endmodule
diff --git a/techlibs/quicklogic/abc9_unmap.v b/techlibs/quicklogic/abc9_unmap.v
new file mode 100644
index 000000000..1681e01bb
--- /dev/null
+++ b/techlibs/quicklogic/abc9_unmap.v
@@ -0,0 +1,14 @@
+module $__PP3_DFFEPC_SYNCONLY (
+ output Q,
+ input D,
+ input CLK,
+ input EN,
+);
+
+// For some reason ABC9 adds init attributes to wires even though they were removed before mapping.
+// As a workaround, remove any init attributes that get reintroduced.
+wire _TECHMAP_REMOVEINIT_Q_ = 1;
+
+dffepc _TECHMAP_REPLACE_ (.Q(Q), .D(D), .CLK(CLK), .EN(EN), .PRE(1'b0), .CLR(1'b0));
+
+endmodule
diff --git a/techlibs/quicklogic/pp3_cells_sim.v b/techlibs/quicklogic/pp3_cells_sim.v
index 61d1ee314..5820d7a9e 100644
--- a/techlibs/quicklogic/pp3_cells_sim.v
+++ b/techlibs/quicklogic/pp3_cells_sim.v
@@ -147,11 +147,10 @@ module dffepc (
);
parameter [0:0] INIT = 1'b0;
- // The CLR => Q and PRE => Q paths are commented out due to YosysHQ/yosys#2530.
specify
if (EN) (posedge CLK => (Q : D)) = 1701; // QCK -> QZ
- // if (CLR) (CLR => Q) = 967; // QRT -> QZ
- // if (PRE) (PRE => Q) = 1252; // QST -> QZ
+ if (CLR) (CLR => Q) = 967; // QRT -> QZ
+ if (PRE) (PRE => Q) = 1252; // QST -> QZ
$setup(D, posedge CLK, 216); // QCK -> QDS
$setup(EN, posedge CLK, 590); // QCK -> QEN
endspecify
diff --git a/techlibs/quicklogic/synth_quicklogic.cc b/techlibs/quicklogic/synth_quicklogic.cc
index 90eb0f78b..a67b167b8 100644
--- a/techlibs/quicklogic/synth_quicklogic.cc
+++ b/techlibs/quicklogic/synth_quicklogic.cc
@@ -51,12 +51,17 @@ struct SynthQuickLogicPass : public ScriptPass {
log(" write the design to the specified verilog file. writing of an output file\n");
log(" is omitted if this parameter is not specified.\n");
log("\n");
+ log(" -abc\n");
+ log(" use old ABC flow, which has generally worse mapping results but is less\n");
+ log(" likely to have bugs.\n");
+ log("\n");
log("The following commands are executed by this synthesis command:\n");
help_script();
log("\n");
}
string top_opt, blif_file, family, currmodule, verilog_file;
+ bool abc9;
void clear_flags() override
{
@@ -65,6 +70,7 @@ struct SynthQuickLogicPass : public ScriptPass {
verilog_file = "";
currmodule = "";
family = "pp3";
+ abc9 = true;
}
void execute(std::vector<std::string> args, RTLIL::Design *design) override
@@ -91,6 +97,10 @@ struct SynthQuickLogicPass : public ScriptPass {
verilog_file = args[++argidx];
continue;
}
+ if (args[argidx] == "-abc") {
+ abc9 = false;
+ continue;
+ }
break;
}
extra_args(args, argidx, design);
@@ -101,6 +111,11 @@ struct SynthQuickLogicPass : public ScriptPass {
if (family != "pp3")
log_cmd_error("Invalid family specified: '%s'\n", family.c_str());
+ if (abc9 && design->scratchpad_get_int("abc9.D", 0) == 0) {
+ log_warning("delay target has not been set via SDC or scratchpad; assuming 12 MHz clock.\n");
+ design->scratchpad_set_int("abc9.D", 41667); // 12MHz = 83.33.. ns; divided by two to allow for interconnect delay.
+ }
+
log_header(design, "Executing SYNTH_QUICKLOGIC pass.\n");
log_push();
@@ -167,8 +182,14 @@ struct SynthQuickLogicPass : public ScriptPass {
if (check_label("map_luts")) {
run(stringf("techmap -map +/quicklogic/%s_latches_map.v", family.c_str()));
- run("abc -luts 1,2,2,4 -dress");
-
+ if (abc9) {
+ run("read_verilog -lib -specify -icells +/quicklogic/abc9_model.v");
+ run("techmap -map +/quicklogic/abc9_map.v");
+ run("abc9 -maxlut 4 -dff");
+ run("techmap -map +/quicklogic/abc9_unmap.v");
+ } else {
+ run("abc -luts 1,2,2,4 -dress");
+ }
run("clean");
}