mirror of
https://github.com/YosysHQ/yosys
synced 2025-08-03 01:40:23 +00:00
Compute is_port
in AbcPass without iterating through all cells and wires in the module every time we run ABC.
This does not scale when we run ABC thousands of times in a single AbcPass.
This commit is contained in:
parent
d3b0c0df1a
commit
a54a673586
5 changed files with 264 additions and 91 deletions
|
@ -27,10 +27,10 @@ YOSYS_NAMESPACE_BEGIN
|
|||
|
||||
struct FfInitVals
|
||||
{
|
||||
const SigMap *sigmap;
|
||||
const SigMapView *sigmap;
|
||||
dict<SigBit, std::pair<State,SigBit>> initbits;
|
||||
|
||||
void set(const SigMap *sigmap_, RTLIL::Module *module)
|
||||
void set(const SigMapView *sigmap_, RTLIL::Module *module)
|
||||
{
|
||||
sigmap = sigmap_;
|
||||
initbits.clear();
|
||||
|
@ -126,7 +126,7 @@ struct FfInitVals
|
|||
initbits.clear();
|
||||
}
|
||||
|
||||
FfInitVals (const SigMap *sigmap, RTLIL::Module *module)
|
||||
FfInitVals (const SigMapView *sigmap, RTLIL::Module *module)
|
||||
{
|
||||
set(sigmap, module);
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ YOSYS_NAMESPACE_BEGIN
|
|||
|
||||
struct FfMergeHelper
|
||||
{
|
||||
const SigMap *sigmap;
|
||||
const SigMapView *sigmap;
|
||||
RTLIL::Module *module;
|
||||
FfInitVals *initvals;
|
||||
|
||||
|
|
|
@ -1327,7 +1327,8 @@ public:
|
|||
return p;
|
||||
}
|
||||
|
||||
// Merge sets if the given indices belong to different sets
|
||||
// Merge sets if the given indices belong to different sets.
|
||||
// Makes ifind(j) the root of the merged set.
|
||||
void imerge(int i, int j)
|
||||
{
|
||||
i = ifind(i);
|
||||
|
|
|
@ -237,6 +237,42 @@ using sort_by_name_id_guard = typename std::enable_if<std::is_same<T,RTLIL::Cell
|
|||
template<typename T>
|
||||
class SigSet<T, sort_by_name_id_guard<T>> : public SigSet<T, RTLIL::sort_by_name_id<typename std::remove_pointer<T>::type>> {};
|
||||
|
||||
struct SigMapView
|
||||
{
|
||||
mfp<SigBit> database;
|
||||
|
||||
// Modify bit to its representative
|
||||
void apply(RTLIL::SigBit &bit) const
|
||||
{
|
||||
bit = database.find(bit);
|
||||
}
|
||||
|
||||
void apply(RTLIL::SigSpec &sig) const
|
||||
{
|
||||
for (auto &bit : sig)
|
||||
apply(bit);
|
||||
}
|
||||
|
||||
RTLIL::SigBit operator()(RTLIL::SigBit bit) const
|
||||
{
|
||||
apply(bit);
|
||||
return bit;
|
||||
}
|
||||
|
||||
RTLIL::SigSpec operator()(RTLIL::SigSpec sig) const
|
||||
{
|
||||
apply(sig);
|
||||
return sig;
|
||||
}
|
||||
|
||||
RTLIL::SigSpec operator()(RTLIL::Wire *wire) const
|
||||
{
|
||||
SigSpec sig(wire);
|
||||
apply(sig);
|
||||
return sig;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* SigMap wraps a union-find "database"
|
||||
* to map SigBits of a module to canonical representative SigBits.
|
||||
|
@ -244,10 +280,8 @@ class SigSet<T, sort_by_name_id_guard<T>> : public SigSet<T, RTLIL::sort_by_name
|
|||
* If a SigBit has a const state (impl: bit.wire is nullptr),
|
||||
* it's promoted to a representative.
|
||||
*/
|
||||
struct SigMap
|
||||
struct SigMap final : public SigMapView
|
||||
{
|
||||
mfp<SigBit> database;
|
||||
|
||||
SigMap(RTLIL::Module *module = NULL)
|
||||
{
|
||||
if (module != NULL)
|
||||
|
@ -320,37 +354,6 @@ struct SigMap
|
|||
|
||||
inline void add(Wire *wire) { return add(RTLIL::SigSpec(wire)); }
|
||||
|
||||
// Modify bit to its representative
|
||||
void apply(RTLIL::SigBit &bit) const
|
||||
{
|
||||
bit = database.find(bit);
|
||||
}
|
||||
|
||||
void apply(RTLIL::SigSpec &sig) const
|
||||
{
|
||||
for (auto &bit : sig)
|
||||
apply(bit);
|
||||
}
|
||||
|
||||
RTLIL::SigBit operator()(RTLIL::SigBit bit) const
|
||||
{
|
||||
apply(bit);
|
||||
return bit;
|
||||
}
|
||||
|
||||
RTLIL::SigSpec operator()(RTLIL::SigSpec sig) const
|
||||
{
|
||||
apply(sig);
|
||||
return sig;
|
||||
}
|
||||
|
||||
RTLIL::SigSpec operator()(RTLIL::Wire *wire) const
|
||||
{
|
||||
SigSpec sig(wire);
|
||||
apply(sig);
|
||||
return sig;
|
||||
}
|
||||
|
||||
// All non-const bits
|
||||
RTLIL::SigSpec allbits() const
|
||||
{
|
||||
|
@ -362,6 +365,107 @@ struct SigMap
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* SiValgMap wraps a union-find "database" to map SigBits of a module to
|
||||
* canonical representative SigBits plus some optional Val value associated with the bits.
|
||||
* Val has a commutative, associative, idempotent operator|=, a default constructor
|
||||
* which constructs an identity element, and a copy constructor.
|
||||
* SigBits that are connected share a set in the underlying database;
|
||||
* the associated value is the "sum" of all the values associated with the contributing bits.
|
||||
* If any of the SigBits in a set are a constant, the canonical SigBit is a constant.
|
||||
*/
|
||||
template <class Val>
|
||||
struct SigValMap final : public SigMapView
|
||||
{
|
||||
dict<SigBit, Val> values;
|
||||
|
||||
void swap(SigValMap<Val> &other)
|
||||
{
|
||||
database.swap(other.database);
|
||||
values.swap(other.values);
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
database.clear();
|
||||
values.clear();
|
||||
}
|
||||
|
||||
// Rebuild SigMap for all connections in module
|
||||
void set(RTLIL::Module *module)
|
||||
{
|
||||
int bitcount = 0;
|
||||
for (auto &it : module->connections())
|
||||
bitcount += it.first.size();
|
||||
|
||||
database.clear();
|
||||
values.clear();
|
||||
database.reserve(bitcount);
|
||||
|
||||
for (auto &it : module->connections())
|
||||
add(it.first, it.second);
|
||||
}
|
||||
|
||||
// Add connections from "from" to "to", bit-by-bit.
|
||||
void add(const RTLIL::SigSpec& from, const RTLIL::SigSpec& to)
|
||||
{
|
||||
log_assert(GetSize(from) == GetSize(to));
|
||||
|
||||
for (int i = 0; i < GetSize(from); i++)
|
||||
{
|
||||
int bfi = database.lookup(from[i]);
|
||||
int bti = database.lookup(to[i]);
|
||||
if (bfi == bti) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const RTLIL::SigBit &bf = database[bfi];
|
||||
const RTLIL::SigBit &bt = database[bti];
|
||||
if (bf.wire == nullptr) {
|
||||
// bf is constant so make it the canonical representative.
|
||||
database.imerge(bti, bfi);
|
||||
merge_value(bt, bf);
|
||||
} else {
|
||||
// Make bt the canonical representative.
|
||||
database.imerge(bfi, bti);
|
||||
merge_value(bf, bt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void addVal(const RTLIL::SigBit &bit, const Val &val)
|
||||
{
|
||||
values[database.find(bit)] |= val;
|
||||
}
|
||||
|
||||
void addVal(const RTLIL::SigSpec &sig, const Val &val)
|
||||
{
|
||||
for (const auto &bit : sig)
|
||||
addVal(bit, val);
|
||||
}
|
||||
|
||||
Val apply_and_get_value(RTLIL::SigBit &bit) const
|
||||
{
|
||||
bit = database.find(bit);
|
||||
auto it = values.find(bit);
|
||||
return it == values.end() ? Val() : it->second;
|
||||
}
|
||||
|
||||
private:
|
||||
void merge_value(const RTLIL::SigBit &from, const RTLIL::SigBit &to)
|
||||
{
|
||||
auto it = values.find(from);
|
||||
if (it == values.end()) {
|
||||
return;
|
||||
}
|
||||
// values[to] could resize the underlying `entries` so
|
||||
// finish using `it` first.
|
||||
Val v = it->second;
|
||||
values.erase(it);
|
||||
values[to] |= v;
|
||||
}
|
||||
};
|
||||
|
||||
YOSYS_NAMESPACE_END
|
||||
|
||||
#endif /* SIGTOOLS_H */
|
||||
|
|
|
@ -138,6 +138,18 @@ struct AbcConfig
|
|||
bool abc_dress = false;
|
||||
};
|
||||
|
||||
struct AbcSigVal {
|
||||
bool is_port;
|
||||
|
||||
AbcSigVal(bool is_port = false) : is_port(is_port) {}
|
||||
AbcSigVal &operator|=(const AbcSigVal &other) {
|
||||
is_port |= other.is_port;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
using AbcSigMap = SigValMap<AbcSigVal>;
|
||||
|
||||
struct AbcModuleState {
|
||||
const AbcConfig &config;
|
||||
|
||||
|
@ -161,21 +173,21 @@ struct AbcModuleState {
|
|||
|
||||
AbcModuleState(const AbcConfig &config) : config(config) {}
|
||||
|
||||
int map_signal(const SigMap &assign_map, RTLIL::SigBit bit, gate_type_t gate_type = G(NONE), int in1 = -1, int in2 = -1, int in3 = -1, int in4 = -1);
|
||||
void mark_port(const SigMap &assign_map, RTLIL::SigSpec sig);
|
||||
void extract_cell(const SigMap &assign_map, RTLIL::Module *module, RTLIL::Cell *cell, bool keepff);
|
||||
int map_signal(const AbcSigMap &assign_map, RTLIL::SigBit bit, gate_type_t gate_type = G(NONE), int in1 = -1, int in2 = -1, int in3 = -1, int in4 = -1);
|
||||
void mark_port(const AbcSigMap &assign_map, RTLIL::SigSpec sig);
|
||||
bool extract_cell(const AbcSigMap &assign_map, RTLIL::Module *module, RTLIL::Cell *cell, bool keepff);
|
||||
std::string remap_name(RTLIL::IdString abc_name, RTLIL::Wire **orig_wire = nullptr);
|
||||
void dump_loop_graph(FILE *f, int &nr, dict<int, pool<int>> &edges, pool<int> &workpool, std::vector<int> &in_counts);
|
||||
void handle_loops(SigMap &assign_map, RTLIL::Module *module);
|
||||
void abc_module(RTLIL::Design *design, RTLIL::Module *module, SigMap &assign_map, const std::vector<RTLIL::Cell*> &cells,
|
||||
void handle_loops(AbcSigMap &assign_map, RTLIL::Module *module);
|
||||
void abc_module(RTLIL::Design *design, RTLIL::Module *module, AbcSigMap &assign_map, const std::vector<RTLIL::Cell*> &cells,
|
||||
bool dff_mode, std::string clk_str);
|
||||
void extract(SigMap &assign_map, RTLIL::Design *design, RTLIL::Module *module);
|
||||
void extract(AbcSigMap &assign_map, RTLIL::Design *design, RTLIL::Module *module);
|
||||
void finish();
|
||||
};
|
||||
|
||||
int AbcModuleState::map_signal(const SigMap &assign_map, RTLIL::SigBit bit, gate_type_t gate_type, int in1, int in2, int in3, int in4)
|
||||
int AbcModuleState::map_signal(const AbcSigMap &assign_map, RTLIL::SigBit bit, gate_type_t gate_type, int in1, int in2, int in3, int in4)
|
||||
{
|
||||
assign_map.apply(bit);
|
||||
AbcSigVal val = assign_map.apply_and_get_value(bit);
|
||||
|
||||
if (bit == State::Sx)
|
||||
undef_bits_lost++;
|
||||
|
@ -188,7 +200,7 @@ int AbcModuleState::map_signal(const SigMap &assign_map, RTLIL::SigBit bit, gate
|
|||
gate.in2 = -1;
|
||||
gate.in3 = -1;
|
||||
gate.in4 = -1;
|
||||
gate.is_port = false;
|
||||
gate.is_port = bit.wire != nullptr && val.is_port;
|
||||
gate.bit = bit;
|
||||
gate.init = initvals(bit);
|
||||
signal_list.push_back(gate);
|
||||
|
@ -211,40 +223,40 @@ int AbcModuleState::map_signal(const SigMap &assign_map, RTLIL::SigBit bit, gate
|
|||
return gate.id;
|
||||
}
|
||||
|
||||
void AbcModuleState::mark_port(const SigMap &assign_map, RTLIL::SigSpec sig)
|
||||
void AbcModuleState::mark_port(const AbcSigMap &assign_map, RTLIL::SigSpec sig)
|
||||
{
|
||||
for (auto &bit : assign_map(sig))
|
||||
if (bit.wire != nullptr && signal_map.count(bit) > 0)
|
||||
signal_list[signal_map[bit]].is_port = true;
|
||||
}
|
||||
|
||||
void AbcModuleState::extract_cell(const SigMap &assign_map, RTLIL::Module *module, RTLIL::Cell *cell, bool keepff)
|
||||
bool AbcModuleState::extract_cell(const AbcSigMap &assign_map, RTLIL::Module *module, RTLIL::Cell *cell, bool keepff)
|
||||
{
|
||||
if (RTLIL::builtin_ff_cell_types().count(cell->type)) {
|
||||
FfData ff(&initvals, cell);
|
||||
gate_type_t type = G(FF);
|
||||
if (!ff.has_clk)
|
||||
return;
|
||||
return false;
|
||||
if (ff.has_gclk)
|
||||
return;
|
||||
return false;
|
||||
if (ff.has_aload)
|
||||
return;
|
||||
return false;
|
||||
if (ff.has_sr)
|
||||
return;
|
||||
return false;
|
||||
if (!ff.is_fine)
|
||||
return;
|
||||
return false;
|
||||
if (clk_polarity != ff.pol_clk)
|
||||
return;
|
||||
return false;
|
||||
if (clk_sig != assign_map(ff.sig_clk))
|
||||
return;
|
||||
return false;
|
||||
if (ff.has_ce) {
|
||||
if (en_polarity != ff.pol_ce)
|
||||
return;
|
||||
return false;
|
||||
if (en_sig != assign_map(ff.sig_ce))
|
||||
return;
|
||||
return false;
|
||||
} else {
|
||||
if (GetSize(en_sig) != 0)
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
if (ff.val_init == State::S1) {
|
||||
type = G(FF1);
|
||||
|
@ -255,39 +267,39 @@ void AbcModuleState::extract_cell(const SigMap &assign_map, RTLIL::Module *modul
|
|||
}
|
||||
if (ff.has_arst) {
|
||||
if (arst_polarity != ff.pol_arst)
|
||||
return;
|
||||
return false;
|
||||
if (arst_sig != assign_map(ff.sig_arst))
|
||||
return;
|
||||
return false;
|
||||
if (ff.val_arst == State::S1) {
|
||||
if (type == G(FF0))
|
||||
return;
|
||||
return false;
|
||||
type = G(FF1);
|
||||
} else if (ff.val_arst == State::S0) {
|
||||
if (type == G(FF1))
|
||||
return;
|
||||
return false;
|
||||
type = G(FF0);
|
||||
}
|
||||
} else {
|
||||
if (GetSize(arst_sig) != 0)
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
if (ff.has_srst) {
|
||||
if (srst_polarity != ff.pol_srst)
|
||||
return;
|
||||
return false;
|
||||
if (srst_sig != assign_map(ff.sig_srst))
|
||||
return;
|
||||
return false;
|
||||
if (ff.val_srst == State::S1) {
|
||||
if (type == G(FF0))
|
||||
return;
|
||||
return false;
|
||||
type = G(FF1);
|
||||
} else if (ff.val_srst == State::S0) {
|
||||
if (type == G(FF1))
|
||||
return;
|
||||
return false;
|
||||
type = G(FF0);
|
||||
}
|
||||
} else {
|
||||
if (GetSize(srst_sig) != 0)
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
int gate_id = map_signal(assign_map, ff.sig_q, type, map_signal(assign_map, ff.sig_d));
|
||||
|
@ -301,7 +313,7 @@ void AbcModuleState::extract_cell(const SigMap &assign_map, RTLIL::Module *modul
|
|||
map_signal(assign_map, ff.sig_q, type, map_signal(assign_map, ff.sig_d));
|
||||
|
||||
ff.remove();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($_BUF_), ID($_NOT_)))
|
||||
|
@ -315,7 +327,7 @@ void AbcModuleState::extract_cell(const SigMap &assign_map, RTLIL::Module *modul
|
|||
map_signal(assign_map, sig_y, cell->type == ID($_BUF_) ? G(BUF) : G(NOT), map_signal(assign_map, sig_a));
|
||||
|
||||
module->remove(cell);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_)))
|
||||
|
@ -351,7 +363,7 @@ void AbcModuleState::extract_cell(const SigMap &assign_map, RTLIL::Module *modul
|
|||
log_abort();
|
||||
|
||||
module->remove(cell);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($_MUX_), ID($_NMUX_)))
|
||||
|
@ -373,7 +385,7 @@ void AbcModuleState::extract_cell(const SigMap &assign_map, RTLIL::Module *modul
|
|||
map_signal(assign_map, sig_y, cell->type == ID($_MUX_) ? G(MUX) : G(NMUX), mapped_a, mapped_b, mapped_s);
|
||||
|
||||
module->remove(cell);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($_AOI3_), ID($_OAI3_)))
|
||||
|
@ -395,7 +407,7 @@ void AbcModuleState::extract_cell(const SigMap &assign_map, RTLIL::Module *modul
|
|||
map_signal(assign_map, sig_y, cell->type == ID($_AOI3_) ? G(AOI3) : G(OAI3), mapped_a, mapped_b, mapped_c);
|
||||
|
||||
module->remove(cell);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($_AOI4_), ID($_OAI4_)))
|
||||
|
@ -420,8 +432,10 @@ void AbcModuleState::extract_cell(const SigMap &assign_map, RTLIL::Module *modul
|
|||
map_signal(assign_map, sig_y, cell->type == ID($_AOI4_) ? G(AOI4) : G(OAI4), mapped_a, mapped_b, mapped_c, mapped_d);
|
||||
|
||||
module->remove(cell);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string AbcModuleState::remap_name(RTLIL::IdString abc_name, RTLIL::Wire **orig_wire)
|
||||
|
@ -492,13 +506,13 @@ void AbcModuleState::dump_loop_graph(FILE *f, int &nr, dict<int, pool<int>> &edg
|
|||
fprintf(f, "}\n");
|
||||
}
|
||||
|
||||
void connect(SigMap &assign_map, RTLIL::Module *module, const RTLIL::SigSig &conn)
|
||||
void connect(AbcSigMap &assign_map, RTLIL::Module *module, const RTLIL::SigSig &conn)
|
||||
{
|
||||
module->connect(conn);
|
||||
assign_map.add(conn.first, conn.second);
|
||||
}
|
||||
|
||||
void AbcModuleState::handle_loops(SigMap &assign_map, RTLIL::Module *module)
|
||||
void AbcModuleState::handle_loops(AbcSigMap &assign_map, RTLIL::Module *module)
|
||||
{
|
||||
// http://en.wikipedia.org/wiki/Topological_sorting
|
||||
// (Kahn, Arthur B. (1962), "Topological sorting of large networks")
|
||||
|
@ -758,7 +772,7 @@ struct abc_output_filter
|
|||
}
|
||||
};
|
||||
|
||||
void AbcModuleState::abc_module(RTLIL::Design *design, RTLIL::Module *module, SigMap &assign_map, const std::vector<RTLIL::Cell*> &cells,
|
||||
void AbcModuleState::abc_module(RTLIL::Design *design, RTLIL::Module *module, AbcSigMap &assign_map, const std::vector<RTLIL::Cell*> &cells,
|
||||
bool dff_mode, std::string clk_str)
|
||||
{
|
||||
initvals.set(&assign_map, module);
|
||||
|
@ -943,18 +957,18 @@ void AbcModuleState::abc_module(RTLIL::Design *design, RTLIL::Module *module, Si
|
|||
undef_bits_lost = 0;
|
||||
|
||||
had_init = false;
|
||||
std::vector<RTLIL::Cell *> kept_cells;
|
||||
for (auto c : cells)
|
||||
extract_cell(assign_map, module, c, config.keepff);
|
||||
if (!extract_cell(assign_map, module, c, config.keepff))
|
||||
kept_cells.push_back(c);
|
||||
|
||||
if (undef_bits_lost)
|
||||
log("Replacing %d occurrences of constant undef bits with constant zero bits\n", undef_bits_lost);
|
||||
|
||||
for (auto wire : module->wires()) {
|
||||
if (wire->port_id > 0)
|
||||
mark_port(assign_map, wire);
|
||||
}
|
||||
|
||||
for (auto cell : module->cells())
|
||||
// Wires with port_id > 0 and connections to cells outside our cell set have already
|
||||
// been accounted for via AbcSigVal::is_port. Now we just need to account for
|
||||
// connections to cells inside our cell set that weren't removed by extract_cell().
|
||||
for (auto cell : kept_cells)
|
||||
for (auto &port_it : cell->connections())
|
||||
mark_port(assign_map, port_it.second);
|
||||
|
||||
|
@ -1213,7 +1227,7 @@ void AbcModuleState::abc_module(RTLIL::Design *design, RTLIL::Module *module, Si
|
|||
log("Don't call ABC as there is nothing to map.\n");
|
||||
}
|
||||
|
||||
void AbcModuleState::extract(SigMap &assign_map, RTLIL::Design *design, RTLIL::Module *module)
|
||||
void AbcModuleState::extract(AbcSigMap &assign_map, RTLIL::Design *design, RTLIL::Module *module)
|
||||
{
|
||||
if (!did_run_abc) {
|
||||
return;
|
||||
|
@ -1510,6 +1524,47 @@ void AbcModuleState::finish()
|
|||
log_pop();
|
||||
}
|
||||
|
||||
// For every signal that connects cells from different sets, or a cell in a set to a cell not in any set,
|
||||
// mark it as a port in `assign_map`.
|
||||
void assign_cell_connection_ports(RTLIL::Module *module, const std::vector<std::vector<RTLIL::Cell *> *> &cell_sets,
|
||||
AbcSigMap &assign_map)
|
||||
{
|
||||
pool<RTLIL::Cell *> cells_in_no_set;
|
||||
for (RTLIL::Cell *cell : module->cells()) {
|
||||
cells_in_no_set.insert(cell);
|
||||
}
|
||||
// For every canonical signal in `assign_map`, the index of the set it is connected to,
|
||||
// or -1 if it connects a cell in one set to a cell in another set or not in any set.
|
||||
dict<SigBit, int> signal_cell_set;
|
||||
for (int i = 0; i < int(cell_sets.size()); ++i) {
|
||||
for (RTLIL::Cell *cell : *cell_sets[i]) {
|
||||
cells_in_no_set.erase(cell);
|
||||
for (auto &port_it : cell->connections()) {
|
||||
for (SigBit bit : port_it.second) {
|
||||
assign_map.apply(bit);
|
||||
auto it = signal_cell_set.find(bit);
|
||||
if (it == signal_cell_set.end())
|
||||
signal_cell_set[bit] = i;
|
||||
else if (it->second >= 0 && it->second != i) {
|
||||
it->second = -1;
|
||||
assign_map.addVal(bit, AbcSigVal(true));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (RTLIL::Cell *cell : cells_in_no_set) {
|
||||
for (auto &port_it : cell->connections()) {
|
||||
for (SigBit bit : port_it.second) {
|
||||
assign_map.apply(bit);
|
||||
auto it = signal_cell_set.find(bit);
|
||||
if (it != signal_cell_set.end() && it->second >= 0)
|
||||
assign_map.addVal(bit, AbcSigVal(true));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct AbcPass : public Pass {
|
||||
AbcPass() : Pass("abc", "use ABC for technology mapping") { }
|
||||
void help() override
|
||||
|
@ -2084,17 +2139,24 @@ struct AbcPass : public Pass {
|
|||
|
||||
for (auto mod : design->selected_modules())
|
||||
{
|
||||
SigMap assign_map;
|
||||
assign_map.set(mod);
|
||||
|
||||
if (mod->processes.size() > 0) {
|
||||
log("Skipping module %s as it contains processes.\n", log_id(mod));
|
||||
continue;
|
||||
}
|
||||
|
||||
AbcSigMap assign_map;
|
||||
assign_map.set(mod);
|
||||
|
||||
for (auto wire : mod->wires())
|
||||
if (wire->port_id > 0)
|
||||
assign_map.addVal(SigSpec(wire), AbcSigVal(true));
|
||||
|
||||
if (!dff_mode || !clk_str.empty()) {
|
||||
std::vector<RTLIL::Cell*> cells = mod->selected_cells();
|
||||
assign_cell_connection_ports(mod, {&cells}, assign_map);
|
||||
|
||||
AbcModuleState state(config);
|
||||
state.abc_module(design, mod, assign_map, mod->selected_cells(), dff_mode, clk_str);
|
||||
state.abc_module(design, mod, assign_map, cells, dff_mode, clk_str);
|
||||
state.extract(assign_map, design, mod);
|
||||
state.finish();
|
||||
continue;
|
||||
|
@ -2250,6 +2312,12 @@ struct AbcPass : public Pass {
|
|||
std::get<4>(it.first) ? "" : "!", log_signal(std::get<5>(it.first)),
|
||||
std::get<6>(it.first) ? "" : "!", log_signal(std::get<7>(it.first)));
|
||||
|
||||
{
|
||||
std::vector<std::vector<RTLIL::Cell*>*> cell_sets;
|
||||
for (auto &it : assigned_cells)
|
||||
cell_sets.push_back(&it.second);
|
||||
assign_cell_connection_ports(mod, cell_sets, assign_map);
|
||||
}
|
||||
for (auto &it : assigned_cells) {
|
||||
AbcModuleState state(config);
|
||||
state.clk_polarity = std::get<0>(it.first);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue