mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-13 04:28:18 +00:00
intel_alm: ABC9 sequential optimisations
This commit is contained in:
parent
a9b61080a4
commit
83cde2d02b
|
@ -2,6 +2,9 @@
|
||||||
OBJS += techlibs/intel_alm/synth_intel_alm.o
|
OBJS += techlibs/intel_alm/synth_intel_alm.o
|
||||||
|
|
||||||
# Techmap
|
# Techmap
|
||||||
|
$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/abc9_map.v))
|
||||||
|
$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/abc9_unmap.v))
|
||||||
|
$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/abc9_model.v))
|
||||||
$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/alm_map.v))
|
$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/alm_map.v))
|
||||||
$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/alm_sim.v))
|
$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/alm_sim.v))
|
||||||
$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/arith_alm_map.v))
|
$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/arith_alm_map.v))
|
||||||
|
|
18
techlibs/intel_alm/common/abc9_map.v
Normal file
18
techlibs/intel_alm/common/abc9_map.v
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// This file exists to map purely-synchronous flops to ABC9 flops, while
|
||||||
|
// mapping flops with asynchronous-clear as boxes, this is because ABC9
|
||||||
|
// doesn't support asynchronous-clear flops in sequential synthesis.
|
||||||
|
|
||||||
|
module MISTRAL_FF(
|
||||||
|
input DATAIN, CLK, ACLR, ENA, SCLR, SLOAD, SDATA,
|
||||||
|
output reg Q
|
||||||
|
);
|
||||||
|
|
||||||
|
parameter _TECHMAP_CONSTMSK_ACLR_ = 1'b0;
|
||||||
|
|
||||||
|
// If the async-clear is constant, we assume it's disabled.
|
||||||
|
if (_TECHMAP_CONSTMSK_ACLR_ != 1'b0)
|
||||||
|
MISTRAL_FF_SYNCONLY _TECHMAP_REPLACE_ (.DATAIN(DATAIN), .CLK(CLK), .ENA(ENA), .SCLR(SCLR), .SLOAD(SLOAD), .SDATA(SDATA), .Q(Q));
|
||||||
|
else
|
||||||
|
wire _TECHMAP_FAIL_ = 1;
|
||||||
|
|
||||||
|
endmodule
|
55
techlibs/intel_alm/common/abc9_model.v
Normal file
55
techlibs/intel_alm/common/abc9_model.v
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
`ifdef cyclonev
|
||||||
|
`define SYNCPATH 262
|
||||||
|
`define SYNCSETUP 522
|
||||||
|
`define COMBPATH 0
|
||||||
|
`endif
|
||||||
|
`ifdef cyclone10gx
|
||||||
|
`define SYNCPATH 219
|
||||||
|
`define SYNCSETUP 268
|
||||||
|
`define COMBPATH 0
|
||||||
|
`endif
|
||||||
|
|
||||||
|
// fallback for when a family isn't detected (e.g. when techmapping for equivalence)
|
||||||
|
`ifndef SYNCPATH
|
||||||
|
`define SYNCPATH 0
|
||||||
|
`define SYNCSETUP 0
|
||||||
|
`define COMBPATH 0
|
||||||
|
`endif
|
||||||
|
|
||||||
|
// This is a purely-synchronous flop, that ABC9 can use for sequential synthesis.
|
||||||
|
(* abc9_flop, lib_whitebox *)
|
||||||
|
module MISTRAL_FF_SYNCONLY(
|
||||||
|
input DATAIN, CLK, ENA, SCLR, SLOAD, SDATA,
|
||||||
|
output reg Q
|
||||||
|
);
|
||||||
|
|
||||||
|
specify
|
||||||
|
if (ENA) (posedge CLK => (Q : DATAIN)) = `SYNCPATH;
|
||||||
|
if (ENA) (posedge CLK => (Q : SCLR)) = `SYNCPATH;
|
||||||
|
if (ENA) (posedge CLK => (Q : SLOAD)) = `SYNCPATH;
|
||||||
|
if (ENA) (posedge CLK => (Q : SDATA)) = `SYNCPATH;
|
||||||
|
|
||||||
|
$setup(DATAIN, posedge CLK, `SYNCSETUP);
|
||||||
|
$setup(ENA, posedge CLK, `SYNCSETUP);
|
||||||
|
$setup(SCLR, posedge CLK, `SYNCSETUP);
|
||||||
|
$setup(SLOAD, posedge CLK, `SYNCSETUP);
|
||||||
|
$setup(SDATA, posedge CLK, `SYNCSETUP);
|
||||||
|
endspecify
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
// Altera flops initialise to zero.
|
||||||
|
Q = 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge CLK) begin
|
||||||
|
// Clock-enable
|
||||||
|
if (ENA) begin
|
||||||
|
// Synchronous clear
|
||||||
|
if (SCLR) Q <= 0;
|
||||||
|
// Synchronous load
|
||||||
|
else if (SLOAD) Q <= SDATA;
|
||||||
|
else Q <= DATAIN;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
11
techlibs/intel_alm/common/abc9_unmap.v
Normal file
11
techlibs/intel_alm/common/abc9_unmap.v
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// After performing sequential synthesis, map the synchronous flops back to
|
||||||
|
// standard MISTRAL_FF flops.
|
||||||
|
|
||||||
|
module MISTRAL_FF_SYNCONLY(
|
||||||
|
input DATAIN, CLK, ENA, SCLR, SLOAD, SDATA,
|
||||||
|
output reg Q
|
||||||
|
);
|
||||||
|
|
||||||
|
MISTRAL_FF _TECHMAP_REPLACE_ (.DATAIN(DATAIN), .CLK(CLK), .ACLR(1'b1), .ENA(ENA), .SCLR(SCLR), .SLOAD(SLOAD), .SDATA(SDATA), .Q(Q));
|
||||||
|
|
||||||
|
endmodule
|
|
@ -53,23 +53,45 @@
|
||||||
// Q: data output
|
// Q: data output
|
||||||
//
|
//
|
||||||
// Note: the DFFEAS primitive is mostly emulated; it does not reflect what the hardware implements.
|
// Note: the DFFEAS primitive is mostly emulated; it does not reflect what the hardware implements.
|
||||||
|
|
||||||
|
`ifdef cyclonev
|
||||||
|
`define SYNCPATH 262
|
||||||
|
`define SYNCSETUP 522
|
||||||
|
`define COMBPATH 0
|
||||||
|
`endif
|
||||||
|
`ifdef cyclone10gx
|
||||||
|
`define SYNCPATH 219
|
||||||
|
`define SYNCSETUP 268
|
||||||
|
`define COMBPATH 0
|
||||||
|
`endif
|
||||||
|
|
||||||
|
// fallback for when a family isn't detected (e.g. when techmapping for equivalence)
|
||||||
|
`ifndef SYNCPATH
|
||||||
|
`define SYNCPATH 0
|
||||||
|
`define SYNCSETUP 0
|
||||||
|
`define COMBPATH 0
|
||||||
|
`endif
|
||||||
|
|
||||||
|
(* abc9_box, lib_whitebox *)
|
||||||
module MISTRAL_FF(
|
module MISTRAL_FF(
|
||||||
input DATAIN, CLK, ACLR, ENA, SCLR, SLOAD, SDATA,
|
input DATAIN, CLK, ACLR, ENA, SCLR, SLOAD, SDATA,
|
||||||
output reg Q
|
output reg Q
|
||||||
);
|
);
|
||||||
|
|
||||||
`ifdef cyclonev
|
|
||||||
specify
|
specify
|
||||||
(posedge CLK => (Q : DATAIN)) = 262;
|
if (ENA) (posedge CLK => (Q : DATAIN)) = `SYNCPATH;
|
||||||
$setup(DATAIN, posedge CLK, 522);
|
if (ENA) (posedge CLK => (Q : SCLR)) = `SYNCPATH;
|
||||||
|
if (ENA) (posedge CLK => (Q : SLOAD)) = `SYNCPATH;
|
||||||
|
if (ENA) (posedge CLK => (Q : SDATA)) = `SYNCPATH;
|
||||||
|
|
||||||
|
$setup(DATAIN, posedge CLK, `SYNCSETUP);
|
||||||
|
$setup(ENA, posedge CLK, `SYNCSETUP);
|
||||||
|
$setup(SCLR, posedge CLK, `SYNCSETUP);
|
||||||
|
$setup(SLOAD, posedge CLK, `SYNCSETUP);
|
||||||
|
$setup(SDATA, posedge CLK, `SYNCSETUP);
|
||||||
|
|
||||||
|
(ACLR => Q) = `COMBPATH;
|
||||||
endspecify
|
endspecify
|
||||||
`endif
|
|
||||||
`ifdef cyclone10gx
|
|
||||||
specify
|
|
||||||
(posedge CLK => (Q : DATAIN)) = 219;
|
|
||||||
$setup(DATAIN, posedge CLK, 268);
|
|
||||||
endspecify
|
|
||||||
`endif
|
|
||||||
|
|
||||||
initial begin
|
initial begin
|
||||||
// Altera flops initialise to zero.
|
// Altera flops initialise to zero.
|
||||||
|
|
|
@ -48,10 +48,20 @@
|
||||||
// the following model because it's very difficult to trigger this in practice
|
// the following model because it's very difficult to trigger this in practice
|
||||||
// as clock cycles will be much longer than any potential blip of 'x, so the
|
// as clock cycles will be much longer than any potential blip of 'x, so the
|
||||||
// model can be treated as always returning a defined result.
|
// model can be treated as always returning a defined result.
|
||||||
|
|
||||||
|
(* abc9_box, lib_whitebox *)
|
||||||
module MISTRAL_MLAB(input [4:0] A1ADDR, input A1DATA, A1EN, CLK1, input [4:0] B1ADDR, output B1DATA);
|
module MISTRAL_MLAB(input [4:0] A1ADDR, input A1DATA, A1EN, CLK1, input [4:0] B1ADDR, output B1DATA);
|
||||||
|
|
||||||
reg [31:0] mem = 32'b0;
|
reg [31:0] mem = 32'b0;
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
specify
|
||||||
|
$setup(A1ADDR, posedge CLK1, 0);
|
||||||
|
$setup(A1DATA, posedge CLK1, 0);
|
||||||
|
|
||||||
|
(B1ADDR *> B1DATA) = 0;
|
||||||
|
endspecify
|
||||||
|
|
||||||
always @(posedge CLK1)
|
always @(posedge CLK1)
|
||||||
if (A1EN) mem[A1ADDR] <= A1DATA;
|
if (A1EN) mem[A1ADDR] <= A1DATA;
|
||||||
|
|
||||||
|
|
|
@ -38,20 +38,26 @@ struct SynthIntelALMPass : public ScriptPass {
|
||||||
log("This command runs synthesis for ALM-based Intel FPGAs.\n");
|
log("This command runs synthesis for ALM-based Intel FPGAs.\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
log(" -top <module>\n");
|
log(" -top <module>\n");
|
||||||
log(" use the specified module as top module (default='top')\n");
|
log(" use the specified module as top module\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
log(" -family <family>\n");
|
log(" -family <family>\n");
|
||||||
log(" target one of:\n");
|
log(" target one of:\n");
|
||||||
log(" \"cyclonev\" - Cyclone V (default)\n");
|
log(" \"cyclonev\" - Cyclone V (default)\n");
|
||||||
log(" \"cyclone10gx\" - Cyclone 10GX\n");
|
log(" \"cyclone10gx\" - Cyclone 10GX\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
log(" -quartus\n");
|
|
||||||
log(" output a netlist using Quartus cells instead of MISTRAL_* cells\n");
|
|
||||||
log("\n");
|
|
||||||
log(" -vqm <file>\n");
|
log(" -vqm <file>\n");
|
||||||
log(" write the design to the specified Verilog Quartus Mapping File. Writing of an\n");
|
log(" write the design to the specified Verilog Quartus Mapping File. Writing of an\n");
|
||||||
log(" output file is omitted if this parameter is not specified. Implies -quartus.\n");
|
log(" output file is omitted if this parameter is not specified. Implies -quartus.\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
|
log(" -noflatten\n");
|
||||||
|
log(" do not flatten design before synthesis; useful for per-module area statistics\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -quartus\n");
|
||||||
|
log(" output a netlist using Quartus cells instead of MISTRAL_* cells\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -dff\n");
|
||||||
|
log(" pass DFFs to ABC to perform sequential logic optimisations (EXPERIMENTAL)\n");
|
||||||
|
log("\n");
|
||||||
log(" -run <from_label>:<to_label>\n");
|
log(" -run <from_label>:<to_label>\n");
|
||||||
log(" only run the commands between the labels (see below). an empty\n");
|
log(" only run the commands between the labels (see below). an empty\n");
|
||||||
log(" from label is synonymous to 'begin', and empty to label is\n");
|
log(" from label is synonymous to 'begin', and empty to label is\n");
|
||||||
|
@ -63,16 +69,13 @@ struct SynthIntelALMPass : public ScriptPass {
|
||||||
log(" -nobram\n");
|
log(" -nobram\n");
|
||||||
log(" do not use block RAM cells in output netlist\n");
|
log(" do not use block RAM cells in output netlist\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
log(" -noflatten\n");
|
|
||||||
log(" do not flatten design before synthesis\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, family_opt, bram_type, vout_file;
|
string top_opt, family_opt, bram_type, vout_file;
|
||||||
bool flatten, quartus, nolutram, nobram;
|
bool flatten, quartus, nolutram, nobram, dff;
|
||||||
|
|
||||||
void clear_flags() override
|
void clear_flags() override
|
||||||
{
|
{
|
||||||
|
@ -84,6 +87,7 @@ struct SynthIntelALMPass : public ScriptPass {
|
||||||
quartus = false;
|
quartus = false;
|
||||||
nolutram = false;
|
nolutram = false;
|
||||||
nobram = false;
|
nobram = false;
|
||||||
|
dff = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||||
|
@ -130,6 +134,10 @@ struct SynthIntelALMPass : public ScriptPass {
|
||||||
flatten = false;
|
flatten = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (args[argidx] == "-dff") {
|
||||||
|
dff = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
extra_args(args, argidx, design);
|
extra_args(args, argidx, design);
|
||||||
|
@ -165,6 +173,7 @@ struct SynthIntelALMPass : public ScriptPass {
|
||||||
run(stringf("read_verilog -specify -lib -D %s +/intel_alm/common/alm_sim.v", family_opt.c_str()));
|
run(stringf("read_verilog -specify -lib -D %s +/intel_alm/common/alm_sim.v", family_opt.c_str()));
|
||||||
run(stringf("read_verilog -specify -lib -D %s +/intel_alm/common/dff_sim.v", family_opt.c_str()));
|
run(stringf("read_verilog -specify -lib -D %s +/intel_alm/common/dff_sim.v", family_opt.c_str()));
|
||||||
run(stringf("read_verilog -specify -lib -D %s +/intel_alm/common/mem_sim.v", family_opt.c_str()));
|
run(stringf("read_verilog -specify -lib -D %s +/intel_alm/common/mem_sim.v", family_opt.c_str()));
|
||||||
|
run(stringf("read_verilog -specify -lib -D %s +/intel_alm/common/abc9_model.v", family_opt.c_str()));
|
||||||
|
|
||||||
// Misc and common cells
|
// Misc and common cells
|
||||||
run("read_verilog -lib +/intel/common/altpll_bb.v");
|
run("read_verilog -lib +/intel/common/altpll_bb.v");
|
||||||
|
@ -209,7 +218,9 @@ struct SynthIntelALMPass : public ScriptPass {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check_label("map_luts")) {
|
if (check_label("map_luts")) {
|
||||||
run("abc9 -maxlut 6 -W 200");
|
run("techmap -map +/intel_alm/common/abc9_map.v");
|
||||||
|
run(stringf("abc9 %s -maxlut 6 -W 200", help_mode ? "[-dff]" : dff ? "-dff" : ""));
|
||||||
|
run("techmap -map +/intel_alm/common/abc9_unmap.v");
|
||||||
run("techmap -map +/intel_alm/common/alm_map.v");
|
run("techmap -map +/intel_alm/common/alm_map.v");
|
||||||
run("opt -fast");
|
run("opt -fast");
|
||||||
run("autoname");
|
run("autoname");
|
||||||
|
|
Loading…
Reference in a new issue