aboutsummaryrefslogtreecommitdiffstats
path: root/backends/aiger/xaiger.cc
diff options
context:
space:
mode:
Diffstat (limited to 'backends/aiger/xaiger.cc')
-rw-r--r--backends/aiger/xaiger.cc93
1 files changed, 54 insertions, 39 deletions
diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc
index b72dd6890..cde6d066a 100644
--- a/backends/aiger/xaiger.cc
+++ b/backends/aiger/xaiger.cc
@@ -47,6 +47,7 @@ inline static uint32_t bswap32(uint32_t x)
#include "kernel/yosys.h"
#include "kernel/sigtools.h"
#include "kernel/utils.h"
+#include "kernel/timinginfo.h"
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
@@ -173,20 +174,21 @@ struct XAigerWriter
undriven_bits.insert(bit);
unused_bits.insert(bit);
- bool keep = wire->get_bool_attribute(ID::keep);
- if (wire->port_input || keep)
+ bool scc = wire->attributes.count(ID(abc9_scc));
+ if (wire->port_input || scc)
input_bits.insert(bit);
- if (wire->port_output || keep) {
+ bool keep = wire->get_bool_attribute(ID::keep);
+ if (wire->port_output || keep || scc) {
if (bit != wirebit)
alias_map[wirebit] = bit;
output_bits.insert(wirebit);
}
}
- dict<IdString,dict<IdString,int>> arrival_cache;
+ TimingInfo timing;
+
for (auto cell : module->cells()) {
- RTLIL::Module* inst_module = module->design->module(cell->type);
if (!cell->has_keep_attr()) {
if (cell->type == "$_NOT_")
{
@@ -222,13 +224,21 @@ struct XAigerWriter
alias_map[Q] = D;
auto r YS_ATTRIBUTE(unused) = ff_bits.insert(std::make_pair(D, cell));
log_assert(r.second);
- if (input_bits.erase(Q))
- log_assert(Q.wire->attributes.count(ID::keep));
continue;
}
- if (inst_module) {
- bool abc9_flop = false;
+ if (cell->type.in("$specify2", "$specify3", "$specrule"))
+ continue;
+ }
+
+ RTLIL::Module* inst_module = module->design->module(cell->type);
+ if (inst_module) {
+ IdString derived_type = inst_module->derive(module->design, cell->parameters);
+ inst_module = module->design->module(derived_type);
+ log_assert(inst_module);
+
+ bool abc9_flop = false;
+ if (!cell->has_keep_attr()) {
auto it = cell->attributes.find("\\abc9_box_seq");
if (it != cell->attributes.end()) {
int abc9_box_seq = it->second.as_int();
@@ -236,34 +246,39 @@ 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;
}
+ }
+
+ if (!timing.count(derived_type))
+ timing.setup_module(inst_module);
+ auto &t = timing.at(derived_type).arrival;
+ for (const auto &conn : cell->connections()) {
+ auto port_wire = inst_module->wire(conn.first);
+ if (!port_wire->port_output)
+ continue;
+
+ for (int i = 0; i < GetSize(conn.second); i++) {
+ auto d = t.at(TimingInfo::NameBit(conn.first,i), 0);
+ if (d == 0)
+ continue;
- auto &cell_arrivals = arrival_cache[cell->type];
- for (const auto &conn : cell->connections()) {
- auto r = cell_arrivals.insert(conn.first);
- auto &arrival = 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();
- }
- }
+#ifndef NDEBUG
+ if (ys_debug(1)) {
+ static std::set<std::tuple<IdString,IdString,int>> seen;
+ if (seen.emplace(derived_type, conn.first, i).second) log("%s.%s[%d] abc9_arrival = %d\n",
+ log_id(cell->type), log_id(conn.first), i, d);
}
- if (arrival)
- for (auto bit : sigmap(conn.second))
- arrival_times[bit] = arrival;
+#endif
+ arrival_times[conn.second[i]] = d;
}
-
- if (abc9_flop)
- continue;
}
+
+ if (abc9_flop)
+ continue;
}
bool cell_known = inst_module || cell->known();
@@ -300,7 +315,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) {
@@ -362,11 +377,6 @@ struct XAigerWriter
alias_map[O] = b;
ci_bits.emplace_back(b);
undriven_bits.erase(O);
- // If PI and CI, then must be a (* keep *) wire
- if (input_bits.erase(O)) {
- log_assert(output_bits.count(O));
- log_assert(O.wire->get_bool_attribute(ID::keep));
- }
}
}
@@ -451,8 +461,8 @@ struct XAigerWriter
for (const auto &bit : output_bits) {
ordered_outputs[bit] = aig_o++;
int aig;
- // Unlike bit2aig() which checks aig_map first, for
- // inout/keep bits, since aig_map will point to
+ // Unlike bit2aig() which checks aig_map first for
+ // inout/scc bits, since aig_map will point to
// the PI, first attempt to find the NOT/AND driver
// before resorting to an aig_map lookup (which
// could be another PO)
@@ -579,7 +589,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;
@@ -625,7 +639,7 @@ struct XAigerWriter
log_assert(mergeability > 0);
write_r_buffer(mergeability);
- Const init = cell->attributes.at(ID(abc9_init));
+ Const init = cell->attributes.at(ID(abc9_init), State::Sx);
log_assert(GetSize(init) == 1);
if (init == State::S1)
write_s_buffer(1);
@@ -636,6 +650,7 @@ struct XAigerWriter
write_s_buffer(0);
}
+ // Use arrival time from output of flop box
write_i_buffer(arrival_times.at(d, 0));
//write_o_buffer(0);
}