mirror of https://github.com/YosysHQ/yosys.git
quicklogic: ABC9 synthesis
This commit is contained in:
parent
a58571d0fe
commit
dce037a62c
|
@ -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/cells_sim.v))
|
||||||
$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/lut_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/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))
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -147,11 +147,10 @@ module dffepc (
|
||||||
);
|
);
|
||||||
parameter [0:0] INIT = 1'b0;
|
parameter [0:0] INIT = 1'b0;
|
||||||
|
|
||||||
// The CLR => Q and PRE => Q paths are commented out due to YosysHQ/yosys#2530.
|
|
||||||
specify
|
specify
|
||||||
if (EN) (posedge CLK => (Q : D)) = 1701; // QCK -> QZ
|
if (EN) (posedge CLK => (Q : D)) = 1701; // QCK -> QZ
|
||||||
// if (CLR) (CLR => Q) = 967; // QRT -> QZ
|
if (CLR) (CLR => Q) = 967; // QRT -> QZ
|
||||||
// if (PRE) (PRE => Q) = 1252; // QST -> QZ
|
if (PRE) (PRE => Q) = 1252; // QST -> QZ
|
||||||
$setup(D, posedge CLK, 216); // QCK -> QDS
|
$setup(D, posedge CLK, 216); // QCK -> QDS
|
||||||
$setup(EN, posedge CLK, 590); // QCK -> QEN
|
$setup(EN, posedge CLK, 590); // QCK -> QEN
|
||||||
endspecify
|
endspecify
|
||||||
|
|
|
@ -51,12 +51,17 @@ struct SynthQuickLogicPass : public ScriptPass {
|
||||||
log(" write the design to the specified verilog file. writing of an output file\n");
|
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(" is omitted if this parameter is not specified.\n");
|
||||||
log("\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");
|
log("The following commands are executed by this synthesis command:\n");
|
||||||
help_script();
|
help_script();
|
||||||
log("\n");
|
log("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
string top_opt, blif_file, family, currmodule, verilog_file;
|
string top_opt, blif_file, family, currmodule, verilog_file;
|
||||||
|
bool abc9;
|
||||||
|
|
||||||
void clear_flags() override
|
void clear_flags() override
|
||||||
{
|
{
|
||||||
|
@ -65,6 +70,7 @@ struct SynthQuickLogicPass : public ScriptPass {
|
||||||
verilog_file = "";
|
verilog_file = "";
|
||||||
currmodule = "";
|
currmodule = "";
|
||||||
family = "pp3";
|
family = "pp3";
|
||||||
|
abc9 = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||||
|
@ -91,6 +97,10 @@ struct SynthQuickLogicPass : public ScriptPass {
|
||||||
verilog_file = args[++argidx];
|
verilog_file = args[++argidx];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (args[argidx] == "-abc") {
|
||||||
|
abc9 = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
extra_args(args, argidx, design);
|
extra_args(args, argidx, design);
|
||||||
|
@ -101,6 +111,11 @@ struct SynthQuickLogicPass : public ScriptPass {
|
||||||
if (family != "pp3")
|
if (family != "pp3")
|
||||||
log_cmd_error("Invalid family specified: '%s'\n", family.c_str());
|
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_header(design, "Executing SYNTH_QUICKLOGIC pass.\n");
|
||||||
log_push();
|
log_push();
|
||||||
|
|
||||||
|
@ -167,8 +182,14 @@ struct SynthQuickLogicPass : public ScriptPass {
|
||||||
|
|
||||||
if (check_label("map_luts")) {
|
if (check_label("map_luts")) {
|
||||||
run(stringf("techmap -map +/quicklogic/%s_latches_map.v", family.c_str()));
|
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");
|
run("clean");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,9 @@ hierarchy -top top
|
||||||
equiv_opt -assert -map +/quicklogic/lut_sim.v -map +/quicklogic/pp3_cells_sim.v synth_quicklogic -family pp3 # equivalency check
|
equiv_opt -assert -map +/quicklogic/lut_sim.v -map +/quicklogic/pp3_cells_sim.v synth_quicklogic -family pp3 # equivalency check
|
||||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
cd top # Constrain all select calls below inside the top module
|
cd top # Constrain all select calls below inside the top module
|
||||||
select -assert-count 3 t:LUT2
|
select -assert-count 2 t:LUT2
|
||||||
select -assert-count 4 t:LUT3
|
select -assert-count 8 t:LUT3
|
||||||
select -assert-count 4 t:LUT4
|
select -assert-count 2 t:LUT4
|
||||||
select -assert-count 8 t:inpad
|
select -assert-count 8 t:inpad
|
||||||
select -assert-count 8 t:outpad
|
select -assert-count 8 t:outpad
|
||||||
select -assert-none t:LUT2 t:LUT3 t:LUT4 t:inpad t:outpad %% t:* %D
|
select -assert-none t:LUT2 t:LUT3 t:LUT4 t:inpad t:outpad %% t:* %D
|
||||||
|
|
|
@ -6,9 +6,9 @@ equiv_opt -assert -multiclock -map +/quicklogic/pp3_cells_sim.v -map +/quicklogi
|
||||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
cd top # Constrain all select calls below inside the top module
|
cd top # Constrain all select calls below inside the top module
|
||||||
select -assert-count 1 t:LUT1
|
select -assert-count 1 t:LUT1
|
||||||
select -assert-count 5 t:LUT2
|
select -assert-count 3 t:LUT2
|
||||||
select -assert-count 2 t:LUT3
|
select -assert-count 5 t:LUT3
|
||||||
select -assert-count 3 t:LUT4
|
select -assert-count 1 t:LUT4
|
||||||
select -assert-count 8 t:dffepc
|
select -assert-count 8 t:dffepc
|
||||||
select -assert-count 1 t:logic_0
|
select -assert-count 1 t:logic_0
|
||||||
select -assert-count 1 t:logic_1
|
select -assert-count 1 t:logic_1
|
||||||
|
|
|
@ -11,14 +11,13 @@ sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip
|
||||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
cd fsm # Constrain all select calls below inside the top module
|
cd fsm # Constrain all select calls below inside the top module
|
||||||
|
|
||||||
select -assert-count 3 t:LUT2
|
select -assert-count 1 t:LUT2
|
||||||
select -assert-count 6 t:LUT3
|
select -assert-count 9 t:LUT3
|
||||||
select -assert-count 7 t:LUT4
|
select -assert-count 4 t:dffepc
|
||||||
select -assert-count 6 t:dffepc
|
|
||||||
select -assert-count 1 t:logic_0
|
select -assert-count 1 t:logic_0
|
||||||
select -assert-count 1 t:logic_1
|
select -assert-count 1 t:logic_1
|
||||||
select -assert-count 3 t:inpad
|
select -assert-count 3 t:inpad
|
||||||
select -assert-count 2 t:outpad
|
select -assert-count 2 t:outpad
|
||||||
select -assert-count 1 t:ckpad
|
select -assert-count 1 t:ckpad
|
||||||
|
|
||||||
select -assert-none t:LUT2 t:LUT3 t:LUT4 t:dffepc t:logic_0 t:logic_1 t:inpad t:outpad t:ckpad %% t:* %D
|
select -assert-none t:LUT2 t:LUT3 t:dffepc t:logic_0 t:logic_1 t:inpad t:outpad t:ckpad %% t:* %D
|
||||||
|
|
|
@ -32,8 +32,9 @@ proc
|
||||||
# Can't run any sort of equivalence check because latches are blown to LUTs
|
# Can't run any sort of equivalence check because latches are blown to LUTs
|
||||||
synth_quicklogic
|
synth_quicklogic
|
||||||
cd latchsr # Constrain all select calls below inside the top module
|
cd latchsr # Constrain all select calls below inside the top module
|
||||||
select -assert-count 2 t:LUT3
|
select -assert-count 1 t:LUT2
|
||||||
|
select -assert-count 1 t:LUT4
|
||||||
select -assert-count 5 t:inpad
|
select -assert-count 5 t:inpad
|
||||||
select -assert-count 1 t:outpad
|
select -assert-count 1 t:outpad
|
||||||
|
|
||||||
select -assert-none t:LUT3 t:inpad t:outpad %% t:* %D
|
select -assert-none t:LUT2 t:LUT4 t:inpad t:outpad %% t:* %D
|
||||||
|
|
|
@ -7,8 +7,8 @@ cd top # Constrain all select calls below inside the top module
|
||||||
|
|
||||||
select -assert-count 1 t:LUT1
|
select -assert-count 1 t:LUT1
|
||||||
select -assert-count 6 t:LUT2
|
select -assert-count 6 t:LUT2
|
||||||
select -assert-count 2 t:LUT4
|
select -assert-count 2 t:LUT3
|
||||||
select -assert-count 8 t:inpad
|
select -assert-count 8 t:inpad
|
||||||
select -assert-count 10 t:outpad
|
select -assert-count 10 t:outpad
|
||||||
|
|
||||||
select -assert-none t:LUT1 t:LUT2 t:LUT4 t:inpad t:outpad %% t:* %D
|
select -assert-none t:LUT1 t:LUT2 t:LUT3 t:inpad t:outpad %% t:* %D
|
||||||
|
|
|
@ -30,13 +30,13 @@ proc
|
||||||
equiv_opt -assert -map +/quicklogic/pp3_cells_sim.v -map +/quicklogic/cells_sim.v -map +/quicklogic/lut_sim.v synth_quicklogic # equivalency check
|
equiv_opt -assert -map +/quicklogic/pp3_cells_sim.v -map +/quicklogic/cells_sim.v -map +/quicklogic/lut_sim.v synth_quicklogic # equivalency check
|
||||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
cd mux8 # Constrain all select calls below inside the top module
|
cd mux8 # Constrain all select calls below inside the top module
|
||||||
select -assert-count 4 t:LUT2
|
select -assert-count 1 t:LUT1
|
||||||
select -assert-count 1 t:LUT3
|
select -assert-count 1 t:LUT3
|
||||||
select -assert-count 2 t:mux4x0
|
select -assert-count 2 t:mux4x0
|
||||||
select -assert-count 11 t:inpad
|
select -assert-count 11 t:inpad
|
||||||
select -assert-count 1 t:outpad
|
select -assert-count 1 t:outpad
|
||||||
|
|
||||||
select -assert-none t:LUT2 t:LUT3 t:mux4x0 t:inpad t:outpad %% t:* %D
|
select -assert-none t:LUT1 t:LUT3 t:mux4x0 t:inpad t:outpad %% t:* %D
|
||||||
|
|
||||||
design -load read
|
design -load read
|
||||||
hierarchy -top mux16
|
hierarchy -top mux16
|
||||||
|
|
Loading…
Reference in New Issue