aboutsummaryrefslogtreecommitdiffstats
path: root/backends
diff options
context:
space:
mode:
Diffstat (limited to 'backends')
-rw-r--r--backends/aiger/xaiger.cc59
-rw-r--r--backends/edif/edif.cc43
-rw-r--r--backends/json/json.cc38
-rw-r--r--backends/verilog/verilog_backend.cc1
4 files changed, 98 insertions, 43 deletions
diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc
index b72dd6890..76b7efbfc 100644
--- a/backends/aiger/xaiger.cc
+++ b/backends/aiger/xaiger.cc
@@ -184,7 +184,7 @@ struct XAigerWriter
}
}
- dict<IdString,dict<IdString,int>> arrival_cache;
+ dict<IdString,dict<IdString,std::vector<int>>> arrivals_cache;
for (auto cell : module->cells()) {
RTLIL::Module* inst_module = module->design->module(cell->type);
if (!cell->has_keep_attr()) {
@@ -236,29 +236,50 @@ struct XAigerWriter
box_list.resize(abc9_box_seq+1);
box_list[abc9_box_seq] = cell;
// Only flop boxes may have arrival times
+ // (all others are combinatorial)
abc9_flop = inst_module->get_bool_attribute("\\abc9_flop");
if (!abc9_flop)
continue;
}
- auto &cell_arrivals = arrival_cache[cell->type];
+ auto &cell_arrivals = arrivals_cache[cell->type];
for (const auto &conn : cell->connections()) {
+ auto port_wire = inst_module->wire(conn.first);
+ if (!port_wire->port_output)
+ continue;
+
auto r = cell_arrivals.insert(conn.first);
- auto &arrival = r.first->second;
+ auto &arrivals = r.first->second;
if (r.second) {
- auto port_wire = inst_module->wire(conn.first);
- if (port_wire->port_output) {
- auto it = port_wire->attributes.find("\\abc9_arrival");
- if (it != port_wire->attributes.end()) {
- if (it->second.flags != 0)
- log_error("Attribute 'abc9_arrival' on port '%s' of module '%s' is not an integer.\n", log_id(port_wire), log_id(cell->type));
- arrival = it->second.as_int();
- }
- }
+ auto it = port_wire->attributes.find("\\abc9_arrival");
+ if (it == port_wire->attributes.end())
+ continue;
+ if (it->second.flags == 0)
+ arrivals.emplace_back(it->second.as_int());
+ else
+ for (const auto &tok : split_tokens(it->second.decode_string()))
+ arrivals.push_back(atoi(tok.c_str()));
+ }
+
+ if (arrivals.empty())
+ continue;
+
+ if (GetSize(arrivals) > 1 && GetSize(arrivals) != GetSize(port_wire))
+ log_error("%s.%s is %d bits wide but abc9_arrival = %s has %d value(s)!\n", log_id(cell->type), log_id(conn.first),
+ GetSize(port_wire), log_signal(it->second), GetSize(arrivals));
+
+ auto jt = arrivals.begin();
+#ifndef NDEBUG
+ if (ys_debug(1)) {
+ static std::set<std::pair<IdString,IdString>> seen;
+ if (seen.emplace(cell->type, conn.first).second) log("%s.%s abc9_arrival = %d\n", log_id(cell->type), log_id(conn.first), *jt);
+ }
+#endif
+ for (auto bit : sigmap(conn.second)) {
+ arrival_times[bit] = *jt;
+ if (arrivals.size() > 1)
+ jt++;
}
- if (arrival)
- for (auto bit : sigmap(conn.second))
- arrival_times[bit] = arrival;
}
if (abc9_flop)
@@ -300,7 +321,7 @@ struct XAigerWriter
RTLIL::Module* box_module = module->design->module(cell->type);
log_assert(box_module);
- log_assert(box_module->attributes.count("\\abc9_box_id"));
+ log_assert(box_module->attributes.count("\\abc9_box_id") || box_module->get_bool_attribute("\\abc9_flop"));
auto r = box_ports.insert(cell->type);
if (r.second) {
@@ -579,7 +600,11 @@ struct XAigerWriter
RTLIL::Module* box_module = module->design->module(cell->type);
log_assert(box_module);
- auto r = cell_cache.insert(cell->type);
+ IdString derived_type = box_module->derive(box_module->design, cell->parameters);
+ box_module = box_module->design->module(derived_type);
+ log_assert(box_module);
+
+ auto r = cell_cache.insert(derived_type);
auto &v = r.first->second;
if (r.second) {
int box_inputs = 0, box_outputs = 0;
diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc
index 616b754ce..199560ad0 100644
--- a/backends/edif/edif.cc
+++ b/backends/edif/edif.cc
@@ -246,19 +246,25 @@ struct EdifBackend : public Backend {
else if (!ct.cell_input(cell_it.first, port_it.first))
dir = "OUTPUT";
}
- if (port_it.second == 1)
+ int width = port_it.second;
+ int start = 0;
+ bool upto = false;
+ auto m = design->module(cell_it.first);
+ if (m) {
+ auto w = m->wire(port_it.first);
+ if (w) {
+ width = GetSize(w);
+ start = w->start_offset;
+ upto = w->upto;
+ }
+ }
+ if (width == 1)
*f << stringf(" (port %s (direction %s))\n", EDIF_DEF(port_it.first), dir);
else {
- int b[2] = {port_it.second-1, 0};
- auto m = design->module(cell_it.first);
- if (m) {
- auto w = m->wire(port_it.first);
- if (w) {
- b[w->upto ? 0 : 1] = w->start_offset;
- b[w->upto ? 1 : 0] = w->start_offset+GetSize(w)-1;
- }
- }
- *f << stringf(" (port (array %s %d) (direction %s))\n", EDIF_DEFR(port_it.first, port_rename, b[0], b[1]), port_it.second, dir);
+ int b[2];
+ b[upto ? 0 : 1] = start;
+ b[upto ? 1 : 0] = start+width-1;
+ *f << stringf(" (port (array %s %d) (direction %s))\n", EDIF_DEFR(port_it.first, port_rename, b[0], b[1]), width, dir);
}
}
*f << stringf(" )\n");
@@ -390,18 +396,23 @@ struct EdifBackend : public Backend {
if (sig[i].wire == NULL && sig[i] != RTLIL::State::S0 && sig[i] != RTLIL::State::S1)
log_warning("Bit %d of cell port %s.%s.%s driven by %s will be left unconnected in EDIF output.\n",
i, log_id(module), log_id(cell), log_id(p.first), log_signal(sig[i]));
- else if (sig.size() == 1)
- net_join_db[sig[i]].insert(make_pair(stringf("(portRef %s (instanceRef %s))", EDIF_REF(p.first), EDIF_REF(cell->name)), cell->output(p.first)));
else {
int member_idx = GetSize(sig)-i-1;
auto m = design->module(cell->type);
+ int width = sig.size();
if (m) {
auto w = m->wire(p.first);
- if (w)
+ if (w) {
member_idx = GetSize(w)-i-1;
+ width = GetSize(w);
+ }
+ }
+ if (width == 1)
+ net_join_db[sig[i]].insert(make_pair(stringf("(portRef %s (instanceRef %s))", EDIF_REF(p.first), EDIF_REF(cell->name)), cell->output(p.first)));
+ else {
+ net_join_db[sig[i]].insert(make_pair(stringf("(portRef (member %s %d) (instanceRef %s))",
+ EDIF_REF(p.first), member_idx, EDIF_REF(cell->name)), cell->output(p.first)));
}
- net_join_db[sig[i]].insert(make_pair(stringf("(portRef (member %s %d) (instanceRef %s))",
- EDIF_REF(p.first), member_idx, EDIF_REF(cell->name)), cell->output(p.first)));
}
}
}
diff --git a/backends/json/json.cc b/backends/json/json.cc
index 107009ee4..5c67cb857 100644
--- a/backends/json/json.cc
+++ b/backends/json/json.cc
@@ -33,6 +33,7 @@ struct JsonWriter
std::ostream &f;
bool use_selection;
bool aig_mode;
+ bool compat_int_mode;
Design *design;
Module *module;
@@ -42,8 +43,9 @@ struct JsonWriter
dict<SigBit, string> sigids;
pool<Aig> aig_models;
- JsonWriter(std::ostream &f, bool use_selection, bool aig_mode) :
- f(f), use_selection(use_selection), aig_mode(aig_mode) { }
+ JsonWriter(std::ostream &f, bool use_selection, bool aig_mode, bool compat_int_mode) :
+ f(f), use_selection(use_selection), aig_mode(aig_mode),
+ compat_int_mode(compat_int_mode) { }
string get_string(string str)
{
@@ -102,8 +104,7 @@ struct JsonWriter
if (state < 2)
str += " ";
f << get_string(str);
- } else
- if (GetSize(value) == 32 && value.is_fully_def()) {
+ } else if (compat_int_mode && GetSize(value) == 32 && value.is_fully_def()) {
if ((value.flags & RTLIL::ConstFlags::CONST_FLAG_SIGNED) != 0)
f << stringf("%d", value.as_int());
else
@@ -294,6 +295,10 @@ struct JsonBackend : public Backend {
log(" -aig\n");
log(" include AIG models for the different gate types\n");
log("\n");
+ log(" -compat-int\n");
+ log(" emit 32-bit fully-defined parameter values directly\n");
+ log(" as JSON numbers (for compatibility with old parsers)\n");
+ log("\n");
log("\n");
log("The general syntax of the JSON output created by this command is as follows:\n");
log("\n");
@@ -368,10 +373,9 @@ struct JsonBackend : public Backend {
log("connected to a constant driver are denoted as string \"0\", \"1\", \"x\", or\n");
log("\"z\" instead of a number.\n");
log("\n");
- log("Numeric 32-bit parameter and attribute values are written as decimal values.\n");
- log("Bit verctors of different sizes, or ones containing 'x' or 'z' bits, are written\n");
- log("as string holding the binary representation of the value. Strings are written\n");
- log("as strings, with an appended blank in cases of strings of the form /[01xz]* */.\n");
+ log("Bit vectors (including integers) are written as string holding the binary");
+ log("representation of the value. Strings are written as strings, with an appended");
+ log("blank in cases of strings of the form /[01xz]* */.\n");
log("\n");
log("For example the following Verilog code:\n");
log("\n");
@@ -495,6 +499,7 @@ struct JsonBackend : public Backend {
void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
bool aig_mode = false;
+ bool compat_int_mode = false;
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++)
@@ -503,13 +508,17 @@ struct JsonBackend : public Backend {
aig_mode = true;
continue;
}
+ if (args[argidx] == "-compat-int") {
+ compat_int_mode = true;
+ continue;
+ }
break;
}
extra_args(f, filename, args, argidx);
log_header(design, "Executing JSON backend.\n");
- JsonWriter json_writer(*f, false, aig_mode);
+ JsonWriter json_writer(*f, false, aig_mode, compat_int_mode);
json_writer.write_design(design);
}
} JsonBackend;
@@ -530,6 +539,10 @@ struct JsonPass : public Pass {
log(" -aig\n");
log(" also include AIG models for the different gate types\n");
log("\n");
+ log(" -compat-int\n");
+ log(" emit 32-bit fully-defined parameter values directly\n");
+ log(" as JSON numbers (for compatibility with old parsers)\n");
+ log("\n");
log("See 'help write_json' for a description of the JSON format used.\n");
log("\n");
}
@@ -537,6 +550,7 @@ struct JsonPass : public Pass {
{
std::string filename;
bool aig_mode = false;
+ bool compat_int_mode = false;
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++)
@@ -549,6 +563,10 @@ struct JsonPass : public Pass {
aig_mode = true;
continue;
}
+ if (args[argidx] == "-compat-int") {
+ compat_int_mode = true;
+ continue;
+ }
break;
}
extra_args(args, argidx, design);
@@ -569,7 +587,7 @@ struct JsonPass : public Pass {
f = &buf;
}
- JsonWriter json_writer(*f, true, aig_mode);
+ JsonWriter json_writer(*f, true, aig_mode, compat_int_mode);
json_writer.write_design(design);
if (!filename.empty()) {
diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc
index 54d0f6148..682c47a1f 100644
--- a/backends/verilog/verilog_backend.cc
+++ b/backends/verilog/verilog_backend.cc
@@ -1066,6 +1066,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
// initial begin
// memid[0] = ...
// end
+ dump_attributes(f, indent.c_str(), cell->attributes);
f << stringf("%s" "reg [%d:%d] %s [%d:%d];\n", indent.c_str(), width-1, 0, mem_id.c_str(), size+offset-1, offset);
if (use_init)
{