mirror of
https://github.com/YosysHQ/yosys
synced 2026-06-19 07:16:27 +00:00
Add latch inference msg severity option.
This commit is contained in:
parent
8869ce61dc
commit
7473fcf939
4 changed files with 97 additions and 7 deletions
|
|
@ -69,10 +69,14 @@ struct ProcPass : public Pass {
|
|||
log(" -noopt\n");
|
||||
log(" Will omit the opt_expr pass.\n");
|
||||
log("\n");
|
||||
log(" -latches <auto|warn|error>\n");
|
||||
log(" controls how the inference of a latch is reported.\n");
|
||||
log("\n");
|
||||
}
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||
{
|
||||
std::string global_arst;
|
||||
std::string latches;
|
||||
bool ifxmode = false;
|
||||
bool nomux = false;
|
||||
bool noopt = false;
|
||||
|
|
@ -104,6 +108,10 @@ struct ProcPass : public Pass {
|
|||
norom = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-latches" && argidx+1 < args.size()) {
|
||||
latches = args[++argidx];
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
extra_args(args, argidx, design);
|
||||
|
|
@ -121,7 +129,10 @@ struct ProcPass : public Pass {
|
|||
Pass::call(design, "proc_rom");
|
||||
if (!nomux)
|
||||
Pass::call(design, ifxmode ? "proc_mux -ifx" : "proc_mux");
|
||||
Pass::call(design, "proc_dlatch");
|
||||
if (latches.empty())
|
||||
Pass::call(design, "proc_dlatch");
|
||||
else
|
||||
Pass::call(design, "proc_dlatch -latches " + latches);
|
||||
Pass::call(design, "proc_dff");
|
||||
Pass::call(design, "proc_memwr");
|
||||
Pass::call(design, "proc_clean");
|
||||
|
|
|
|||
|
|
@ -345,7 +345,13 @@ struct proc_dlatch_db_t
|
|||
}
|
||||
};
|
||||
|
||||
void proc_dlatch(proc_dlatch_db_t &db, RTLIL::Process *proc)
|
||||
enum LatchPolicy {
|
||||
POLICY_AUTO,
|
||||
POLICY_WARN,
|
||||
POLICY_ERROR
|
||||
};
|
||||
|
||||
void proc_dlatch(proc_dlatch_db_t &db, RTLIL::Process *proc, LatchPolicy policy)
|
||||
{
|
||||
RTLIL::SigSig latches_bits, nolatches_bits;
|
||||
dict<SigBit, SigBit> latches_out_in;
|
||||
|
|
@ -443,6 +449,12 @@ void proc_dlatch(proc_dlatch_db_t &db, RTLIL::Process *proc)
|
|||
if (proc->get_bool_attribute(ID::always_comb))
|
||||
log_error("Latch inferred for signal `%s.%s' from always_comb process `%s.%s'.\n",
|
||||
db.module->name.c_str(), log_signal(lhs), db.module->name.c_str(), proc->name.c_str());
|
||||
else if (policy == POLICY_ERROR)
|
||||
log_error("Latch inferred for signal `%s.%s' from process `%s.%s': %s\n",
|
||||
db.module->name.c_str(), log_signal(lhs), db.module->name.c_str(), proc->name.c_str(), cell);
|
||||
else if (policy == POLICY_WARN)
|
||||
log_warning("Latch inferred for signal `%s.%s' from process `%s.%s': %s\n",
|
||||
db.module->name.c_str(), log_signal(lhs), db.module->name.c_str(), proc->name.c_str(), cell);
|
||||
else
|
||||
log("Latch inferred for signal `%s.%s' from process `%s.%s': %s\n",
|
||||
db.module->name.c_str(), log_signal(lhs), db.module->name.c_str(), proc->name.c_str(), cell);
|
||||
|
|
@ -458,22 +470,49 @@ struct ProcDlatchPass : public Pass {
|
|||
{
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
log("\n");
|
||||
log(" proc_dlatch [selection]\n");
|
||||
log(" proc_dlatch [options] [selection]\n");
|
||||
log("\n");
|
||||
log("This pass identifies latches in the processes and converts them to\n");
|
||||
log("d-type latches.\n");
|
||||
log("\n");
|
||||
log(" -latches <auto|warn|error>\n");
|
||||
log(" controls how the inference of a latch is reported. Alternatively, one\n");
|
||||
log(" can use the 'proc.latches' scratchpad variable.\n");
|
||||
log("\n");
|
||||
}
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||
{
|
||||
log_header(design, "Executing PROC_DLATCH pass (convert process syncs to latches).\n");
|
||||
|
||||
extra_args(args, 1, design);
|
||||
std::string policy_str;
|
||||
|
||||
size_t argidx;
|
||||
for (argidx = 1; argidx < args.size(); argidx++) {
|
||||
if (args[argidx] == "-latches" && argidx+1 < args.size()) {
|
||||
policy_str = args[++argidx];
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
extra_args(args, argidx, design);
|
||||
|
||||
if (policy_str.empty())
|
||||
policy_str = design->scratchpad_get_string("proc.latches", "warn");
|
||||
|
||||
LatchPolicy policy;
|
||||
if (policy_str == "auto")
|
||||
policy = POLICY_AUTO;
|
||||
else if (policy_str == "warn")
|
||||
policy = POLICY_WARN;
|
||||
else if (policy_str == "error")
|
||||
policy = POLICY_ERROR;
|
||||
else
|
||||
log_cmd_error("Invalid value '%s' for -latches (expected auto|warn|error).\n", policy_str.c_str());
|
||||
|
||||
for (auto mod : design->all_selected_modules()) {
|
||||
proc_dlatch_db_t db(mod);
|
||||
for (auto proc : mod->selected_processes())
|
||||
proc_dlatch(db, proc);
|
||||
proc_dlatch(db, proc, policy);
|
||||
db.fixup_muxes();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,6 +78,9 @@ struct SynthPass : public ScriptPass {
|
|||
log(" -nordff\n");
|
||||
log(" passed to 'memory'. prohibits merging of FFs into memory read ports\n");
|
||||
log("\n");
|
||||
log(" -latches <auto|warn|error>\n");
|
||||
log(" controls how the inference of a latch is reported.\n");
|
||||
log("\n");
|
||||
log(" -noshare\n");
|
||||
log(" do not run SAT-based resource sharing\n");
|
||||
log("\n");
|
||||
|
|
@ -111,7 +114,7 @@ struct SynthPass : public ScriptPass {
|
|||
log("\n");
|
||||
}
|
||||
|
||||
string top_module, fsm_opts, memory_opts, abc;
|
||||
string top_module, fsm_opts, memory_opts, abc, latches_opt;
|
||||
bool autotop, flatten, noalumacc, nofsm, noabc, noshare, flowmap, booth, arith_tree, hieropt, relative_share;
|
||||
int lut;
|
||||
std::vector<std::string> techmap_maps;
|
||||
|
|
@ -121,6 +124,7 @@ struct SynthPass : public ScriptPass {
|
|||
top_module.clear();
|
||||
fsm_opts.clear();
|
||||
memory_opts.clear();
|
||||
latches_opt.clear();
|
||||
|
||||
autotop = false;
|
||||
flatten = false;
|
||||
|
|
@ -200,6 +204,10 @@ struct SynthPass : public ScriptPass {
|
|||
memory_opts += " -nordff";
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-latches" && argidx + 1 < args.size()) {
|
||||
latches_opt += " -latches " + args[++argidx];
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-noshare") {
|
||||
noshare = true;
|
||||
continue;
|
||||
|
|
@ -276,7 +284,7 @@ struct SynthPass : public ScriptPass {
|
|||
}
|
||||
|
||||
if (check_label("coarse")) {
|
||||
run("proc");
|
||||
run("proc" + latches_opt);
|
||||
if (flatten || help_mode) {
|
||||
run("check");
|
||||
run("flatten", " (if -flatten)");
|
||||
|
|
|
|||
32
tests/proc/proc_latches.ys
Normal file
32
tests/proc/proc_latches.ys
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
# warn
|
||||
read_verilog <<EOT
|
||||
module top(input g, rn, d, output reg q);
|
||||
always @* if (~rn) q <= 0; else if (g) q <= d;
|
||||
endmodule
|
||||
EOT
|
||||
logger -expect warning "Latch inferred for signal" 1
|
||||
proc
|
||||
logger -check-expected
|
||||
|
||||
design -reset
|
||||
|
||||
# auto
|
||||
read_verilog <<EOT
|
||||
module top(input g, rn, d, output reg q);
|
||||
always @* if (~rn) q <= 0; else if (g) q <= d;
|
||||
endmodule
|
||||
EOT
|
||||
logger -expect-no-warnings
|
||||
proc -latches auto
|
||||
logger -check-expected
|
||||
|
||||
design -reset
|
||||
|
||||
# error
|
||||
read_verilog <<EOT
|
||||
module top(input g, rn, d, output reg q);
|
||||
always @* if (~rn) q <= 0; else if (g) q <= d;
|
||||
endmodule
|
||||
EOT
|
||||
logger -expect error "Latch inferred for signal" 1
|
||||
proc -latches error
|
||||
Loading…
Add table
Add a link
Reference in a new issue