3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-04-23 09:05:32 +00:00

Merge remote-tracking branch 'origin/xaig_dff' into eddie/abc9_refactor

This commit is contained in:
Eddie Hung 2020-01-06 12:04:08 -08:00
commit 921ff0f5e3
8 changed files with 295 additions and 255 deletions

View file

@ -1514,7 +1514,47 @@ struct AbcPass : public Pass {
#endif
#endif
size_t argidx;
// get arguments from scratchpad first, then override by command arguments
std::string lut_arg, luts_arg, g_arg;
exe_file = design->scratchpad_get_string("abc.exe", exe_file /* inherit default value if not set */);
script_file = design->scratchpad_get_string("abc.script", script_file);
liberty_file = design->scratchpad_get_string("abc.liberty", liberty_file);
constr_file = design->scratchpad_get_string("abc.constr", constr_file);
if (design->scratchpad.count("abc.D")) {
delay_target = "-D " + design->scratchpad_get_string("abc.D");
}
if (design->scratchpad.count("abc.I")) {
sop_inputs = "-I " + design->scratchpad_get_string("abc.I");
}
if (design->scratchpad.count("abc.P")) {
sop_products = "-P " + design->scratchpad_get_string("abc.P");
}
if (design->scratchpad.count("abc.S")) {
lutin_shared = "-S " + design->scratchpad_get_string("abc.S");
}
lut_arg = design->scratchpad_get_string("abc.lut", lut_arg);
luts_arg = design->scratchpad_get_string("abc.luts", luts_arg);
sop_mode = design->scratchpad_get_bool("abc.sop", sop_mode);
map_mux4 = design->scratchpad_get_bool("abc.mux4", map_mux4);
map_mux8 = design->scratchpad_get_bool("abc.mux8", map_mux8);
map_mux16 = design->scratchpad_get_bool("abc.mux16", map_mux16);
abc_dress = design->scratchpad_get_bool("abc.dress", abc_dress);
g_arg = design->scratchpad_get_string("abc.g", g_arg);
fast_mode = design->scratchpad_get_bool("abc.fast", fast_mode);
dff_mode = design->scratchpad_get_bool("abc.dff", dff_mode);
if (design->scratchpad.count("abc.clk")) {
clk_str = design->scratchpad_get_string("abc.clk");
dff_mode = true;
}
keepff = design->scratchpad_get_bool("abc.keepff", keepff);
cleanup = !design->scratchpad_get_bool("abc.nocleanup", !cleanup);
keepff = design->scratchpad_get_bool("abc.keepff", keepff);
show_tempdir = design->scratchpad_get_bool("abc.showtmp", show_tempdir);
markgroups = design->scratchpad_get_bool("abc.markgroups", markgroups);
size_t argidx, g_argidx;
bool g_arg_from_cmd = false;
char pwd [PATH_MAX];
if (!getcwd(pwd, sizeof(pwd))) {
log_cmd_error("getcwd failed: %s\n", strerror(errno));
@ -1528,23 +1568,14 @@ struct AbcPass : public Pass {
}
if (arg == "-script" && argidx+1 < args.size()) {
script_file = args[++argidx];
rewrite_filename(script_file);
if (!script_file.empty() && !is_absolute_path(script_file) && script_file[0] != '+')
script_file = std::string(pwd) + "/" + script_file;
continue;
}
if (arg == "-liberty" && argidx+1 < args.size()) {
liberty_file = args[++argidx];
rewrite_filename(liberty_file);
if (!liberty_file.empty() && !is_absolute_path(liberty_file))
liberty_file = std::string(pwd) + "/" + liberty_file;
continue;
}
if (arg == "-constr" && argidx+1 < args.size()) {
rewrite_filename(constr_file);
constr_file = args[++argidx];
if (!constr_file.empty() && !is_absolute_path(constr_file))
constr_file = std::string(pwd) + "/" + constr_file;
continue;
}
if (arg == "-D" && argidx+1 < args.size()) {
@ -1564,37 +1595,11 @@ struct AbcPass : public Pass {
continue;
}
if (arg == "-lut" && argidx+1 < args.size()) {
string arg = args[++argidx];
size_t pos = arg.find_first_of(':');
int lut_mode = 0, lut_mode2 = 0;
if (pos != string::npos) {
lut_mode = atoi(arg.substr(0, pos).c_str());
lut_mode2 = atoi(arg.substr(pos+1).c_str());
} else {
lut_mode = atoi(arg.c_str());
lut_mode2 = lut_mode;
}
lut_costs.clear();
for (int i = 0; i < lut_mode; i++)
lut_costs.push_back(1);
for (int i = lut_mode; i < lut_mode2; i++)
lut_costs.push_back(2 << (i - lut_mode));
lut_arg = args[++argidx];
continue;
}
if (arg == "-luts" && argidx+1 < args.size()) {
lut_costs.clear();
for (auto &tok : split_tokens(args[++argidx], ",")) {
auto parts = split_tokens(tok, ":");
if (GetSize(parts) == 0 && !lut_costs.empty())
lut_costs.push_back(lut_costs.back());
else if (GetSize(parts) == 1)
lut_costs.push_back(atoi(parts.at(0).c_str()));
else if (GetSize(parts) == 2)
while (GetSize(lut_costs) < std::atoi(parts.at(0).c_str()))
lut_costs.push_back(atoi(parts.at(1).c_str()));
else
log_cmd_error("Invalid -luts syntax.\n");
}
luts_arg = args[++argidx];
continue;
}
if (arg == "-sop") {
@ -1618,123 +1623,9 @@ struct AbcPass : public Pass {
continue;
}
if (arg == "-g" && argidx+1 < args.size()) {
for (auto g : split_tokens(args[++argidx], ",")) {
vector<string> gate_list;
bool remove_gates = false;
if (GetSize(g) > 0 && g[0] == '-') {
remove_gates = true;
g = g.substr(1);
}
if (g == "AND") goto ok_gate;
if (g == "NAND") goto ok_gate;
if (g == "OR") goto ok_gate;
if (g == "NOR") goto ok_gate;
if (g == "XOR") goto ok_gate;
if (g == "XNOR") goto ok_gate;
if (g == "ANDNOT") goto ok_gate;
if (g == "ORNOT") goto ok_gate;
if (g == "MUX") goto ok_gate;
if (g == "NMUX") goto ok_gate;
if (g == "AOI3") goto ok_gate;
if (g == "OAI3") goto ok_gate;
if (g == "AOI4") goto ok_gate;
if (g == "OAI4") goto ok_gate;
if (g == "simple") {
gate_list.push_back("AND");
gate_list.push_back("OR");
gate_list.push_back("XOR");
gate_list.push_back("MUX");
goto ok_alias;
}
if (g == "cmos2") {
if (!remove_gates)
cmos_cost = true;
gate_list.push_back("NAND");
gate_list.push_back("NOR");
goto ok_alias;
}
if (g == "cmos3") {
if (!remove_gates)
cmos_cost = true;
gate_list.push_back("NAND");
gate_list.push_back("NOR");
gate_list.push_back("AOI3");
gate_list.push_back("OAI3");
goto ok_alias;
}
if (g == "cmos4") {
if (!remove_gates)
cmos_cost = true;
gate_list.push_back("NAND");
gate_list.push_back("NOR");
gate_list.push_back("AOI3");
gate_list.push_back("OAI3");
gate_list.push_back("AOI4");
gate_list.push_back("OAI4");
goto ok_alias;
}
if (g == "cmos") {
if (!remove_gates)
cmos_cost = true;
gate_list.push_back("NAND");
gate_list.push_back("NOR");
gate_list.push_back("AOI3");
gate_list.push_back("OAI3");
gate_list.push_back("AOI4");
gate_list.push_back("OAI4");
gate_list.push_back("NMUX");
gate_list.push_back("MUX");
gate_list.push_back("XOR");
gate_list.push_back("XNOR");
goto ok_alias;
}
if (g == "gates") {
gate_list.push_back("AND");
gate_list.push_back("NAND");
gate_list.push_back("OR");
gate_list.push_back("NOR");
gate_list.push_back("XOR");
gate_list.push_back("XNOR");
gate_list.push_back("ANDNOT");
gate_list.push_back("ORNOT");
goto ok_alias;
}
if (g == "aig") {
gate_list.push_back("AND");
gate_list.push_back("NAND");
gate_list.push_back("OR");
gate_list.push_back("NOR");
gate_list.push_back("ANDNOT");
gate_list.push_back("ORNOT");
goto ok_alias;
}
if (g == "all") {
gate_list.push_back("AND");
gate_list.push_back("NAND");
gate_list.push_back("OR");
gate_list.push_back("NOR");
gate_list.push_back("XOR");
gate_list.push_back("XNOR");
gate_list.push_back("ANDNOT");
gate_list.push_back("ORNOT");
gate_list.push_back("AOI3");
gate_list.push_back("OAI3");
gate_list.push_back("AOI4");
gate_list.push_back("OAI4");
gate_list.push_back("MUX");
gate_list.push_back("NMUX");
}
cmd_error(args, argidx, stringf("Unsupported gate type: %s", g.c_str()));
ok_gate:
gate_list.push_back(g);
ok_alias:
for (auto gate : gate_list) {
if (remove_gates)
enabled_gates.erase(gate);
else
enabled_gates.insert(gate);
}
}
g_arg = args[++argidx];
g_argidx = argidx;
g_arg_from_cmd = true;
continue;
}
if (arg == "-fast") {
@ -1770,6 +1661,174 @@ struct AbcPass : public Pass {
}
extra_args(args, argidx, design);
rewrite_filename(script_file);
if (!script_file.empty() && !is_absolute_path(script_file) && script_file[0] != '+')
script_file = std::string(pwd) + "/" + script_file;
rewrite_filename(liberty_file);
if (!liberty_file.empty() && !is_absolute_path(liberty_file))
liberty_file = std::string(pwd) + "/" + liberty_file;
rewrite_filename(constr_file);
if (!constr_file.empty() && !is_absolute_path(constr_file))
constr_file = std::string(pwd) + "/" + constr_file;
// handle -lut argument
if (!lut_arg.empty()) {
size_t pos = lut_arg.find_first_of(':');
int lut_mode = 0, lut_mode2 = 0;
if (pos != string::npos) {
lut_mode = atoi(lut_arg.substr(0, pos).c_str());
lut_mode2 = atoi(lut_arg.substr(pos+1).c_str());
} else {
lut_mode = atoi(lut_arg.c_str());
lut_mode2 = lut_mode;
}
lut_costs.clear();
for (int i = 0; i < lut_mode; i++)
lut_costs.push_back(1);
for (int i = lut_mode; i < lut_mode2; i++)
lut_costs.push_back(2 << (i - lut_mode));
}
//handle -luts argument
if (!luts_arg.empty()){
lut_costs.clear();
for (auto &tok : split_tokens(luts_arg, ",")) {
auto parts = split_tokens(tok, ":");
if (GetSize(parts) == 0 && !lut_costs.empty())
lut_costs.push_back(lut_costs.back());
else if (GetSize(parts) == 1)
lut_costs.push_back(atoi(parts.at(0).c_str()));
else if (GetSize(parts) == 2)
while (GetSize(lut_costs) < std::atoi(parts.at(0).c_str()))
lut_costs.push_back(atoi(parts.at(1).c_str()));
else
log_cmd_error("Invalid -luts syntax.\n");
}
}
// handle -g argument
if (!g_arg.empty()){
for (auto g : split_tokens(g_arg, ",")) {
vector<string> gate_list;
bool remove_gates = false;
if (GetSize(g) > 0 && g[0] == '-') {
remove_gates = true;
g = g.substr(1);
}
if (g == "AND") goto ok_gate;
if (g == "NAND") goto ok_gate;
if (g == "OR") goto ok_gate;
if (g == "NOR") goto ok_gate;
if (g == "XOR") goto ok_gate;
if (g == "XNOR") goto ok_gate;
if (g == "ANDNOT") goto ok_gate;
if (g == "ORNOT") goto ok_gate;
if (g == "MUX") goto ok_gate;
if (g == "NMUX") goto ok_gate;
if (g == "AOI3") goto ok_gate;
if (g == "OAI3") goto ok_gate;
if (g == "AOI4") goto ok_gate;
if (g == "OAI4") goto ok_gate;
if (g == "simple") {
gate_list.push_back("AND");
gate_list.push_back("OR");
gate_list.push_back("XOR");
gate_list.push_back("MUX");
goto ok_alias;
}
if (g == "cmos2") {
if (!remove_gates)
cmos_cost = true;
gate_list.push_back("NAND");
gate_list.push_back("NOR");
goto ok_alias;
}
if (g == "cmos3") {
if (!remove_gates)
cmos_cost = true;
gate_list.push_back("NAND");
gate_list.push_back("NOR");
gate_list.push_back("AOI3");
gate_list.push_back("OAI3");
goto ok_alias;
}
if (g == "cmos4") {
if (!remove_gates)
cmos_cost = true;
gate_list.push_back("NAND");
gate_list.push_back("NOR");
gate_list.push_back("AOI3");
gate_list.push_back("OAI3");
gate_list.push_back("AOI4");
gate_list.push_back("OAI4");
goto ok_alias;
}
if (g == "cmos") {
if (!remove_gates)
cmos_cost = true;
gate_list.push_back("NAND");
gate_list.push_back("NOR");
gate_list.push_back("AOI3");
gate_list.push_back("OAI3");
gate_list.push_back("AOI4");
gate_list.push_back("OAI4");
gate_list.push_back("NMUX");
gate_list.push_back("MUX");
gate_list.push_back("XOR");
gate_list.push_back("XNOR");
goto ok_alias;
}
if (g == "gates") {
gate_list.push_back("AND");
gate_list.push_back("NAND");
gate_list.push_back("OR");
gate_list.push_back("NOR");
gate_list.push_back("XOR");
gate_list.push_back("XNOR");
gate_list.push_back("ANDNOT");
gate_list.push_back("ORNOT");
goto ok_alias;
}
if (g == "aig") {
gate_list.push_back("AND");
gate_list.push_back("NAND");
gate_list.push_back("OR");
gate_list.push_back("NOR");
gate_list.push_back("ANDNOT");
gate_list.push_back("ORNOT");
goto ok_alias;
}
if (g == "all") {
gate_list.push_back("AND");
gate_list.push_back("NAND");
gate_list.push_back("OR");
gate_list.push_back("NOR");
gate_list.push_back("XOR");
gate_list.push_back("XNOR");
gate_list.push_back("ANDNOT");
gate_list.push_back("ORNOT");
gate_list.push_back("AOI3");
gate_list.push_back("OAI3");
gate_list.push_back("AOI4");
gate_list.push_back("OAI4");
gate_list.push_back("MUX");
gate_list.push_back("NMUX");
}
if (g_arg_from_cmd)
cmd_error(args, g_argidx, stringf("Unsupported gate type: %s", g.c_str()));
else
log_cmd_error("Unsupported gate type: %s", g.c_str());
ok_gate:
gate_list.push_back(g);
ok_alias:
for (auto gate : gate_list) {
if (remove_gates)
enabled_gates.erase(gate);
else
enabled_gates.insert(gate);
}
}
}
if (!lut_costs.empty() && !liberty_file.empty())
log_cmd_error("Got -lut and -liberty! These two options are exclusive.\n");
if (!constr_file.empty() && liberty_file.empty())

View file

@ -40,7 +40,7 @@ struct Abc9Pass : public ScriptPass
log(" abc9 [options] [selection]\n");
log("\n");
log("This pass uses the ABC tool [1] for technology mapping of yosys's internal gate\n");
log("library to a target architecture.\n");
log("library to a target architecture. Only fully-selected modules are supported.\n");
log("\n");
log(" -exe <command>\n");
#ifdef ABCEXTERNAL
@ -113,11 +113,6 @@ struct Abc9Pass : public ScriptPass
log(" print the temp dir name in log. usually this is suppressed so that the\n");
log(" command output is identical across runs.\n");
log("\n");
log(" -markgroups\n");
log(" set a 'abcgroup' attribute on all objects created by ABC. The value of\n");
log(" this attribute is a unique integer for each ABC process started. This\n");
log(" is useful for debugging the partitioning of clock domains.\n");
log("\n");
log(" -box <file>\n");
log(" pass this file with box library to ABC. Use with -lut.\n");
log("\n");
@ -150,6 +145,25 @@ struct Abc9Pass : public ScriptPass
std::string run_from, run_to;
clear_flags();
// get arguments from scratchpad first, then override by command arguments
std::string lut_arg, luts_arg;
exe_file = design->scratchpad_get_string("abc9.exe", exe_file /* inherit default value if not set */);
script_file = design->scratchpad_get_string("abc9.script", script_file);
if (design->scratchpad.count("abc9.D")) {
delay_target = "-D " + design->scratchpad_get_string("abc9.D");
}
lut_arg = design->scratchpad_get_string("abc9.lut", lut_arg);
luts_arg = design->scratchpad_get_string("abc9.luts", luts_arg);
fast_mode = design->scratchpad_get_bool("abc9.fast", fast_mode);
dff_mode = design->scratchpad_get_bool("abc9.dff", dff_mode);
cleanup = !design->scratchpad_get_bool("abc9.nocleanup", !cleanup);
show_tempdir = design->scratchpad_get_bool("abc9.showtmp", show_tempdir);
box_file = design->scratchpad_get_string("abc9.box", box_file);
if (design->scratchpad.count("abc9.W")) {
wire_delay = "-W " + design->scratchpad_get_string("abc9.W");
}
nomfs = design->scratchpad_get_bool("abc9.nomfs", nomfs);
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++) {
std::string arg = args[argidx];
@ -161,7 +175,7 @@ struct Abc9Pass : public ScriptPass
continue;
}
if (arg == "-fast" || /* arg == "-dff" || */
/* arg == "-nocleanup" || */ arg == "-showtmp" || arg == "-markgroups" ||
/* arg == "-nocleanup" || */ arg == "-showtmp" ||
arg == "-nomfs") {
map_cmd << " " << arg;
continue;
@ -210,6 +224,10 @@ struct Abc9Pass : public ScriptPass
log("Skipping module %s as it contains processes.\n", log_id(mod));
continue;
}
log_assert(!module->attributes.count(ID(abc9_box_id)));
if (!design->selected_whole_module(module))
log_error("Can't handle partially selected module %s!\n", log_id(module));
active_design->selection().select(mod);

View file

@ -63,7 +63,6 @@ extern "C" int Abc_RealMain(int argc, char *argv[]);
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
bool markgroups;
int map_autoidx;
inline std::string remap_name(RTLIL::IdString abc9_name)
@ -349,11 +348,8 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip
if (mapped_mod == NULL)
log_error("ABC output file does not contain a module `$__abc9__'.\n");
for (auto &it : mapped_mod->wires_) {
RTLIL::Wire *w = it.second;
RTLIL::Wire *remap_wire = module->addWire(remap_name(w->name), GetSize(w));
if (markgroups) remap_wire->attributes[ID(abcgroup)] = map_autoidx;
}
for (auto wire : mapped_mod->wires())
module->addWire(remap_name(w->name), GetSize(w));
for (auto it = module->cells_.begin(); it != module->cells_.end(); )
if (it->second->type.in(ID($_AND_), ID($_NOT_), ID($__ABC9_FF_)))
@ -416,7 +412,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip
}
else
log_abort();
if (cell && markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
continue;
}
cell_stats[mapped_cell->type]++;
@ -429,7 +424,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip
SigSpec my_a = module->wires_.at(remap_name(mapped_cell->getPort(ID::A).as_wire()->name));
SigSpec my_y = module->wires_.at(remap_name(mapped_cell->getPort(ID::Y).as_wire()->name));
module->connect(my_y, my_a);
if (markgroups) mapped_cell->attributes[ID(abcgroup)] = map_autoidx;
log_abort();
continue;
}
@ -441,7 +435,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip
cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type);
}
if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
if (existing_cell) {
cell->parameters = existing_cell->parameters;
cell->attributes = existing_cell->attributes;
@ -660,8 +653,6 @@ struct Abc9MapPass : public Pass {
log(" set delay target. the string {D} in the default scripts above is\n");
log(" replaced by this option when used, and an empty string otherwise\n");
log(" (indicating best possible delay).\n");
// log(" This also replaces 'dretime' with 'dretime; retime -o {D}' in the\n");
// log(" default scripts above.\n");
log("\n");
// log(" -S <num>\n");
// log(" maximum number of LUT inputs shared.\n");
@ -683,28 +674,14 @@ struct Abc9MapPass : public Pass {
log(" generate netlist using luts. Use the specified costs for luts with 1,\n");
log(" 2, 3, .. inputs.\n");
log("\n");
// log(" -dff\n");
// log(" also pass $_DFF_?_ and $_DFFE_??_ cells through ABC. modules with many\n");
// log(" clock domains are automatically partitioned in clock domains and each\n");
// log(" domain is passed through ABC independently.\n");
// log("\n");
// log(" -clk [!]<clock-signal-name>[,[!]<enable-signal-name>]\n");
// log(" use only the specified clock domain. this is like -dff, but only FF\n");
// log(" cells that belong to the specified clock domain are used.\n");
// log("\n");
// log(" -keepff\n");
// log(" set the \"keep\" attribute on flip-flop output wires. (and thus preserve\n");
// log(" them, for example for equivalence checking.)\n");
// log("\n");
log(" -dff\n");
log(" also pass $_ABC9_FF_ cells through to ABC. modules with many clock\n");
log(" domains are marked as such and automatically partitioned by ABC.\n");
log("\n");
log(" -showtmp\n");
log(" print the temp dir name in log. usually this is suppressed so that the\n");
log(" command output is identical across runs.\n");
log("\n");
log(" -markgroups\n");
log(" set a 'abcgroup' attribute on all objects created by ABC. The value of\n");
log(" this attribute is a unique integer for each ABC process started. This\n");
log(" is useful for debugging the partitioning of clock domains.\n");
log("\n");
log(" -box <file>\n");
log(" pass this file with box library to ABC. Use with -lut.\n");
log("\n");
@ -737,7 +714,6 @@ struct Abc9MapPass : public Pass {
bool show_tempdir = false;
bool nomfs = false;
vector<int> lut_costs;
markgroups = false;
#if 0
cleanup = false;
@ -828,10 +804,6 @@ struct Abc9MapPass : public Pass {
show_tempdir = true;
continue;
}
if (arg == "-markgroups") {
markgroups = true;
continue;
}
if (arg == "-box" && argidx+1 < args.size()) {
box_file = args[++argidx];
continue;
@ -871,6 +843,9 @@ struct Abc9MapPass : public Pass {
continue;
}
if (!design->selected_whole_module(mod))
log_error("Can't handle partially selected module %s!\n", log_id(module));
abc9_module(design, mod, script_file, exe_file, lut_costs,
delay_target, lutin_shared, fast_mode, show_tempdir,
box_file, lut_file, wire_delay, nomfs, tempdir_name);