Fix handling of init values in "abc -dff" and "abc -clk"

This commit is contained in:
Clifford Wolf 2017-06-20 15:32:23 +02:00
parent 1f517d2b96
commit 155a80dfb7
1 changed files with 181 additions and 136 deletions

View File

@ -92,6 +92,7 @@ struct gate_t
int in1, in2, in3, in4; int in1, in2, in3, in4;
bool is_port; bool is_port;
RTLIL::SigBit bit; RTLIL::SigBit bit;
RTLIL::State init;
}; };
bool map_mux4; bool map_mux4;
@ -104,7 +105,9 @@ SigMap assign_map;
RTLIL::Module *module; RTLIL::Module *module;
std::vector<gate_t> signal_list; std::vector<gate_t> signal_list;
std::map<RTLIL::SigBit, int> signal_map; std::map<RTLIL::SigBit, int> signal_map;
std::map<RTLIL::SigBit, RTLIL::State> signal_init;
pool<std::string> enabled_gates; pool<std::string> enabled_gates;
bool recover_init;
bool clk_polarity, en_polarity; bool clk_polarity, en_polarity;
RTLIL::SigSpec clk_sig, en_sig; RTLIL::SigSpec clk_sig, en_sig;
@ -123,6 +126,10 @@ int map_signal(RTLIL::SigBit bit, gate_type_t gate_type = G(NONE), int in1 = -1,
gate.in4 = -1; gate.in4 = -1;
gate.is_port = false; gate.is_port = false;
gate.bit = bit; gate.bit = bit;
if (signal_init.count(bit))
gate.init = signal_init.at(bit);
else
gate.init = State::Sx;
signal_list.push_back(gate); signal_list.push_back(gate);
signal_map[bit] = gate.id; signal_map[bit] = gate.id;
} }
@ -609,11 +616,10 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
signal_map.clear(); signal_map.clear();
signal_list.clear(); signal_list.clear();
recover_init = false;
if (clk_str != "$") if (clk_str != "$")
{ {
assign_map.set(module);
clk_polarity = true; clk_polarity = true;
clk_sig = RTLIL::SigSpec(); clk_sig = RTLIL::SigSpec();
@ -849,7 +855,11 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
fprintf(f, "00-- 1\n"); fprintf(f, "00-- 1\n");
fprintf(f, "--00 1\n"); fprintf(f, "--00 1\n");
} else if (si.type == G(FF)) { } else if (si.type == G(FF)) {
fprintf(f, ".latch n%d n%d\n", si.in1, si.id); if (si.init == State::S0 || si.init == State::S1) {
fprintf(f, ".latch n%d n%d %d\n", si.in1, si.id, si.init == State::S1 ? 1 : 0);
recover_init = true;
} else
fprintf(f, ".latch n%d n%d 2\n", si.in1, si.id);
} else if (si.type != G(NONE)) } else if (si.type != G(NONE))
log_abort(); log_abort();
if (si.type != G(NONE)) if (si.type != G(NONE))
@ -1155,6 +1165,15 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
module->connect(conn); module->connect(conn);
} }
if (recover_init)
for (auto wire : mapped_mod->wires()) {
if (wire->attributes.count("\\init")) {
Wire *w = module->wires_[remap_name(wire->name)];
log_assert(w->attributes.count("\\init") == 0);
w->attributes["\\init"] = wire->attributes.at("\\init");
}
}
for (auto &it : cell_stats) for (auto &it : cell_stats)
log("ABC RESULTS: %15s cells: %8d\n", it.first.c_str(), it.second); log("ABC RESULTS: %15s cells: %8d\n", it.first.c_str(), it.second);
int in_wires = 0, out_wires = 0; int in_wires = 0, out_wires = 0;
@ -1372,6 +1391,7 @@ struct AbcPass : public Pass {
assign_map.clear(); assign_map.clear();
signal_list.clear(); signal_list.clear();
signal_map.clear(); signal_map.clear();
signal_init.clear();
#ifdef ABCEXTERNAL #ifdef ABCEXTERNAL
std::string exe_file = ABCEXTERNAL; std::string exe_file = ABCEXTERNAL;
@ -1614,14 +1634,38 @@ struct AbcPass : public Pass {
log_cmd_error("Got -constr but no -liberty!\n"); log_cmd_error("Got -constr but no -liberty!\n");
for (auto mod : design->selected_modules()) for (auto mod : design->selected_modules())
if (mod->processes.size() > 0) {
if (mod->processes.size() > 0) {
log("Skipping module %s as it contains processes.\n", log_id(mod)); log("Skipping module %s as it contains processes.\n", log_id(mod));
else if (!dff_mode || !clk_str.empty()) continue;
}
assign_map.set(mod);
signal_init.clear();
for (Wire *wire : mod->wires())
if (wire->attributes.count("\\init")) {
SigSpec initsig = assign_map(wire);
Const initval = wire->attributes.at("\\init");
for (int i = 0; i < GetSize(initsig) && i < GetSize(initval); i++)
switch (initval[i]) {
case State::S0:
signal_init[initsig[i]] = State::S0;
break;
case State::S1:
signal_init[initsig[i]] = State::S0;
break;
default:
break;
}
}
if (!dff_mode || !clk_str.empty()) {
abc_module(design, mod, script_file, exe_file, liberty_file, constr_file, cleanup, lut_costs, dff_mode, clk_str, keepff, abc_module(design, mod, script_file, exe_file, liberty_file, constr_file, cleanup, lut_costs, dff_mode, clk_str, keepff,
delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, mod->selected_cells(), show_tempdir, sop_mode); delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, mod->selected_cells(), show_tempdir, sop_mode);
else continue;
{ }
assign_map.set(mod);
CellTypes ct(design); CellTypes ct(design);
std::vector<RTLIL::Cell*> all_cells = mod->selected_cells(); std::vector<RTLIL::Cell*> all_cells = mod->selected_cells();
@ -1771,6 +1815,7 @@ struct AbcPass : public Pass {
assign_map.clear(); assign_map.clear();
signal_list.clear(); signal_list.clear();
signal_map.clear(); signal_map.clear();
signal_init.clear();
log_pop(); log_pop();
} }