mirror of https://github.com/YosysHQ/yosys.git
opt_clean: refactor
This commit is contained in:
parent
818aad7542
commit
d2d97433b6
|
|
@ -53,10 +53,10 @@ ShardedVector<std::pair<SigBit, State>> build_inits(AnalysisContext& actx) {
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
dict<SigBit, State> qbits_from_inits(ShardedVector<std::pair<SigBit, State>>& inits, AnalysisContext& actx) {
|
dict<SigBit, State> qbits_from_inits(ShardedVector<std::pair<SigBit, State>>& inits, SigMap& assign_map) {
|
||||||
dict<SigBit, State> qbits;
|
dict<SigBit, State> qbits;
|
||||||
for (std::pair<SigBit, State> &p : inits) {
|
for (std::pair<SigBit, State> &p : inits) {
|
||||||
actx.assign_map.add(p.first);
|
assign_map.add(p.first);
|
||||||
qbits[p.first] = p.second;
|
qbits[p.first] = p.second;
|
||||||
}
|
}
|
||||||
return qbits;
|
return qbits;
|
||||||
|
|
@ -126,7 +126,7 @@ bool rmunused_module_init(RTLIL::Module *module, ParallelDispatchThreadPool::Sub
|
||||||
AnalysisContext actx(module, subpool);
|
AnalysisContext actx(module, subpool);
|
||||||
|
|
||||||
ShardedVector<std::pair<SigBit, State>> inits = build_inits(actx);
|
ShardedVector<std::pair<SigBit, State>> inits = build_inits(actx);
|
||||||
dict<SigBit, State> qbits = qbits_from_inits(inits, actx);
|
dict<SigBit, State> qbits = qbits_from_inits(inits, actx.assign_map);
|
||||||
ShardedVector<RTLIL::Wire*> inits_to_transfer = deferred_init_transfer(qbits, actx);
|
ShardedVector<RTLIL::Wire*> inits_to_transfer = deferred_init_transfer(qbits, actx);
|
||||||
|
|
||||||
bool did_something = remove_redundant_inits(inits_to_transfer, verbose);
|
bool did_something = remove_redundant_inits(inits_to_transfer, verbose);
|
||||||
|
|
|
||||||
|
|
@ -28,12 +28,12 @@
|
||||||
|
|
||||||
YOSYS_NAMESPACE_BEGIN
|
YOSYS_NAMESPACE_BEGIN
|
||||||
|
|
||||||
struct keep_cache_t
|
struct KeepCache
|
||||||
{
|
{
|
||||||
dict<Module*, bool> keep_modules;
|
dict<Module*, bool> keep_modules;
|
||||||
bool purge_mode;
|
bool purge_mode;
|
||||||
|
|
||||||
keep_cache_t(bool purge_mode, ParallelDispatchThreadPool &thread_pool, const std::vector<RTLIL::Module *> &selected_modules)
|
KeepCache(bool purge_mode, ParallelDispatchThreadPool &thread_pool, const std::vector<RTLIL::Module *> &selected_modules)
|
||||||
: purge_mode(purge_mode) {
|
: purge_mode(purge_mode) {
|
||||||
|
|
||||||
std::vector<RTLIL::Module *> scan_modules_worklist;
|
std::vector<RTLIL::Module *> scan_modules_worklist;
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ struct OptCleanPass : public Pass {
|
||||||
for (RTLIL::Module *m : selected_modules)
|
for (RTLIL::Module *m : selected_modules)
|
||||||
thread_pool_size = std::max(thread_pool_size, ThreadPool::work_pool_size(0, m->cells_size(), 1000));
|
thread_pool_size = std::max(thread_pool_size, ThreadPool::work_pool_size(0, m->cells_size(), 1000));
|
||||||
ParallelDispatchThreadPool thread_pool(thread_pool_size);
|
ParallelDispatchThreadPool thread_pool(thread_pool_size);
|
||||||
keep_cache_t keep_cache(purge_mode, thread_pool, selected_modules);
|
KeepCache keep_cache(purge_mode, thread_pool, selected_modules);
|
||||||
|
|
||||||
{
|
{
|
||||||
CleanRunContext clean_ctx(design, {purge_mode, true});
|
CleanRunContext clean_ctx(design, {purge_mode, true});
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ struct CleanRunContext {
|
||||||
RmStats stats;
|
RmStats stats;
|
||||||
ParallelDispatchThreadPool thread_pool;
|
ParallelDispatchThreadPool thread_pool;
|
||||||
std::vector<RTLIL::Module*> selected_modules;
|
std::vector<RTLIL::Module*> selected_modules;
|
||||||
keep_cache_t keep_cache;
|
KeepCache keep_cache;
|
||||||
Flags flags;
|
Flags flags;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -50,24 +50,24 @@ struct ShardedSigSpecEquality {
|
||||||
};
|
};
|
||||||
using ShardedSigSpecPool = ShardedHashtable<ShardedSigSpec, ShardedSigSpecEquality>;
|
using ShardedSigSpecPool = ShardedHashtable<ShardedSigSpec, ShardedSigSpecEquality>;
|
||||||
|
|
||||||
struct DirectWires {
|
struct ExactCellWires {
|
||||||
const ShardedSigSpecPool &direct_sigs;
|
const ShardedSigSpecPool &exact_cells;
|
||||||
const SigMap &assign_map;
|
const SigMap &assign_map;
|
||||||
dict<RTLIL::Wire *, bool> cache;
|
dict<RTLIL::Wire *, bool> cache;
|
||||||
|
|
||||||
DirectWires(const ShardedSigSpecPool &direct_sigs, const SigMap &assign_map) : direct_sigs(direct_sigs), assign_map(assign_map) {}
|
ExactCellWires(const ShardedSigSpecPool &exact_cells, const SigMap &assign_map) : exact_cells(exact_cells), assign_map(assign_map) {}
|
||||||
void cache_result_for_bit(const SigBit &bit) {
|
void cache_result_for_bit(const SigBit &bit) {
|
||||||
if (bit.wire != nullptr)
|
if (bit.wire != nullptr)
|
||||||
(void)is_direct(bit.wire);
|
(void)is_exactly_cell_driven(bit.wire);
|
||||||
}
|
}
|
||||||
bool is_direct(RTLIL::Wire *wire) {
|
bool is_exactly_cell_driven(RTLIL::Wire *wire) {
|
||||||
if (wire->port_input)
|
if (wire->port_input)
|
||||||
return true;
|
return true;
|
||||||
auto it = cache.find(wire);
|
auto it = cache.find(wire);
|
||||||
if (it != cache.end())
|
if (it != cache.end())
|
||||||
return it->second;
|
return it->second;
|
||||||
SigSpec direct_sig = assign_map(wire);
|
SigSpec sig = assign_map(wire);
|
||||||
bool direct = direct_sigs.find({direct_sig, direct_sig.hash_into(Hasher()).yield()}) != nullptr;
|
bool direct = exact_cells.find({sig, sig.hash_into(Hasher()).yield()}) != nullptr;
|
||||||
cache.insert({wire, direct});
|
cache.insert({wire, direct});
|
||||||
return direct;
|
return direct;
|
||||||
}
|
}
|
||||||
|
|
@ -91,7 +91,7 @@ int count_nontrivial_wire_attrs(RTLIL::Wire *w)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should we pick `s2` over `s1` to represent a signal?
|
// Should we pick `s2` over `s1` to represent a signal?
|
||||||
bool compare_signals(const RTLIL::SigBit &s1, const RTLIL::SigBit &s2, const ShardedSigPool ®s, const ShardedSigPool &conns, DirectWires &direct_wires)
|
bool compare_signals(const RTLIL::SigBit &s1, const RTLIL::SigBit &s2, const ShardedSigPool ®s, const ShardedSigPool &conns, ExactCellWires &cell_wires)
|
||||||
{
|
{
|
||||||
if (s1 == s2)
|
if (s1 == s2)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -115,10 +115,10 @@ bool compare_signals(const RTLIL::SigBit &s1, const RTLIL::SigBit &s2, const Sha
|
||||||
bool regs2 = regs.find(s2_val) != nullptr;
|
bool regs2 = regs.find(s2_val) != nullptr;
|
||||||
if (regs1 != regs2)
|
if (regs1 != regs2)
|
||||||
return regs2;
|
return regs2;
|
||||||
bool w1_direct = direct_wires.is_direct(w1);
|
bool w1_exact = cell_wires.is_exactly_cell_driven(w1);
|
||||||
bool w2_direct = direct_wires.is_direct(w2);
|
bool w2_exact = cell_wires.is_exactly_cell_driven(w2);
|
||||||
if (w1_direct != w2_direct)
|
if (w1_exact != w2_exact)
|
||||||
return w2_direct;
|
return w2_exact;
|
||||||
bool conns1 = conns.find(s1_val) != nullptr;
|
bool conns1 = conns.find(s1_val) != nullptr;
|
||||||
bool conns2 = conns.find(s2_val) != nullptr;
|
bool conns2 = conns.find(s2_val) != nullptr;
|
||||||
if (conns1 != conns2)
|
if (conns1 != conns2)
|
||||||
|
|
@ -180,7 +180,7 @@ struct UpdateConnection {
|
||||||
RTLIL::IdString port;
|
RTLIL::IdString port;
|
||||||
RTLIL::SigSpec spec;
|
RTLIL::SigSpec spec;
|
||||||
};
|
};
|
||||||
void fixup_update_ports(ShardedVector<UpdateConnection> &update_connections)
|
void fixup_cell_ports(ShardedVector<UpdateConnection> &update_connections)
|
||||||
{
|
{
|
||||||
for (UpdateConnection &update : update_connections)
|
for (UpdateConnection &update : update_connections)
|
||||||
update.cell->connections_.at(update.port) = std::move(update.spec);
|
update.cell->connections_.at(update.port) = std::move(update.spec);
|
||||||
|
|
@ -229,18 +229,23 @@ static InitBits consume_inits(ShardedVector<RTLIL::Wire*> &initialized_wires, co
|
||||||
* What kinds of things are signals connected to?
|
* What kinds of things are signals connected to?
|
||||||
* Helps pick representatives out of groups of connected signals */
|
* Helps pick representatives out of groups of connected signals */
|
||||||
struct SigConnKinds {
|
struct SigConnKinds {
|
||||||
// Wire bits driven by registers (with clk2fflogic exception)
|
// Wire bits directly driven by registers (with clk2fflogic exception)
|
||||||
ShardedSigPool registers;
|
ShardedSigPool raw_registers;
|
||||||
// Wire bits connected to any cell port
|
// Wire bits directly connected to any cell port
|
||||||
ShardedSigPool cells;
|
ShardedSigPool raw_cell_connected;
|
||||||
// construct a pool of wires which are directly driven by a known celltype,
|
|
||||||
// this will influence our choice of representatives
|
// Signals exactly driven by a known cell output,
|
||||||
ShardedSigSpecPool direct;
|
// this will influence only our choice of representatives.
|
||||||
|
// A signal is exactly driven by a cell output iff all its bits are driven by this output
|
||||||
|
// and all bits of this output drive a bit of this signal.
|
||||||
|
// Additionally, all signals that sigmap to this signal are exactly driven by the port, too
|
||||||
|
ShardedSigSpecPool exact_cells;
|
||||||
|
|
||||||
SigConnKinds(bool purge_mode, const AnalysisContext& actx, CleanRunContext& clean_ctx) {
|
SigConnKinds(bool purge_mode, const AnalysisContext& actx, CleanRunContext& clean_ctx) {
|
||||||
ShardedSigPool::Builder register_signals_builder(actx.subpool);
|
ShardedSigPool::Builder raw_register_builder(actx.subpool);
|
||||||
ShardedSigPool::Builder connected_signals_builder(actx.subpool);
|
ShardedSigPool::Builder raw_cell_connected_builder(actx.subpool);
|
||||||
ShardedSigSpecPool::Builder direct_sigs_builder(actx.subpool);
|
ShardedSigSpecPool::Builder exact_cell_output_builder(actx.subpool);
|
||||||
actx.subpool.run([&direct_sigs_builder, ®ister_signals_builder, &connected_signals_builder, purge_mode, &actx, &clean_ctx](const ParallelDispatchThreadPool::RunCtx &ctx) {
|
actx.subpool.run([&exact_cell_output_builder, &raw_register_builder, &raw_cell_connected_builder, purge_mode, &actx, &clean_ctx](const ParallelDispatchThreadPool::RunCtx &ctx) {
|
||||||
|
|
||||||
for (int i : ctx.item_range(actx.mod->cells_size())) {
|
for (int i : ctx.item_range(actx.mod->cells_size())) {
|
||||||
RTLIL::Cell *cell = actx.mod->cell_at(i);
|
RTLIL::Cell *cell = actx.mod->cell_at(i);
|
||||||
|
|
@ -251,65 +256,65 @@ struct SigConnKinds {
|
||||||
bool clk2fflogic = cell->get_bool_attribute(ID::clk2fflogic);
|
bool clk2fflogic = cell->get_bool_attribute(ID::clk2fflogic);
|
||||||
for (auto &[port, sig] : cell->connections())
|
for (auto &[port, sig] : cell->connections())
|
||||||
if (clk2fflogic ? port == ID::D : clean_ctx.ct_reg.cell_output(cell->type, port))
|
if (clk2fflogic ? port == ID::D : clean_ctx.ct_reg.cell_output(cell->type, port))
|
||||||
add_spec(register_signals_builder, ctx, sig);
|
add_spec(raw_register_builder, ctx, sig);
|
||||||
}
|
}
|
||||||
// TODO optimize for direct wire connections?
|
|
||||||
for (auto &[_, sig] : cell->connections())
|
for (auto &[_, sig] : cell->connections())
|
||||||
add_spec(connected_signals_builder, ctx, sig);
|
add_spec(raw_cell_connected_builder, ctx, sig);
|
||||||
}
|
}
|
||||||
if (clean_ctx.ct_all.cell_known(cell->type))
|
if (clean_ctx.ct_all.cell_known(cell->type))
|
||||||
for (auto &[port, sig] : cell->connections())
|
for (auto &[port, sig] : cell->connections())
|
||||||
if (clean_ctx.ct_all.cell_output(cell->type, port)) {
|
if (clean_ctx.ct_all.cell_output(cell->type, port)) {
|
||||||
RTLIL::SigSpec spec = actx.assign_map(sig);
|
RTLIL::SigSpec spec = actx.assign_map(sig);
|
||||||
unsigned int hash = spec.hash_into(Hasher()).yield();
|
unsigned int hash = spec.hash_into(Hasher()).yield();
|
||||||
direct_sigs_builder.insert(ctx, {std::move(spec), hash});
|
exact_cell_output_builder.insert(ctx, {std::move(spec), hash});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
actx.subpool.run([®ister_signals_builder, &connected_signals_builder, &direct_sigs_builder](const ParallelDispatchThreadPool::RunCtx &ctx) {
|
actx.subpool.run([&raw_register_builder, &raw_cell_connected_builder, &exact_cell_output_builder](const ParallelDispatchThreadPool::RunCtx &ctx) {
|
||||||
register_signals_builder.process(ctx);
|
raw_register_builder.process(ctx);
|
||||||
connected_signals_builder.process(ctx);
|
raw_cell_connected_builder.process(ctx);
|
||||||
direct_sigs_builder.process(ctx);
|
exact_cell_output_builder.process(ctx);
|
||||||
});
|
});
|
||||||
registers = register_signals_builder;
|
raw_registers = raw_register_builder;
|
||||||
cells = connected_signals_builder;
|
raw_cell_connected = raw_cell_connected_builder;
|
||||||
direct = direct_sigs_builder;
|
exact_cells = exact_cell_output_builder;
|
||||||
}
|
}
|
||||||
void clear(const ParallelDispatchThreadPool::RunCtx &ctx) {
|
void clear(const ParallelDispatchThreadPool::RunCtx &ctx) {
|
||||||
registers.clear(ctx);
|
raw_registers.clear(ctx);
|
||||||
cells.clear(ctx);
|
raw_cell_connected.clear(ctx);
|
||||||
direct.clear(ctx);
|
exact_cells.clear(ctx);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ShardedVector<RTLIL::SigBit> build_candidates(DirectWires& direct_wires, const SigConnKinds& sig_analysis, const AnalysisContext& actx) {
|
ShardedVector<RTLIL::SigBit> build_candidates(ExactCellWires& cell_wires, const SigConnKinds& sig_analysis, const AnalysisContext& actx) {
|
||||||
ShardedVector<RTLIL::SigBit> sigmap_canonical_candidates(actx.subpool);
|
ShardedVector<RTLIL::SigBit> candidates(actx.subpool);
|
||||||
actx.subpool.run([&actx, &sig_analysis, &sigmap_canonical_candidates, &direct_wires](const ParallelDispatchThreadPool::RunCtx &ctx) {
|
actx.subpool.run([&actx, &sig_analysis, &candidates, &cell_wires](const ParallelDispatchThreadPool::RunCtx &ctx) {
|
||||||
std::optional<DirectWires> local_direct_wires;
|
std::optional<ExactCellWires> local_cell_wires;
|
||||||
DirectWires *this_thread_direct_wires = &direct_wires;
|
ExactCellWires *this_thread_cell_wires = &cell_wires;
|
||||||
if (ctx.thread_num > 0) {
|
if (ctx.thread_num > 0) {
|
||||||
// Rebuild a thread-local direct_wires from scratch
|
local_cell_wires.emplace(sig_analysis.exact_cells, actx.assign_map);
|
||||||
// but from the same inputs
|
this_thread_cell_wires = &local_cell_wires.value();
|
||||||
local_direct_wires.emplace(sig_analysis.direct, actx.assign_map);
|
|
||||||
this_thread_direct_wires = &local_direct_wires.value();
|
|
||||||
}
|
}
|
||||||
for (int i : ctx.item_range(actx.mod->wires_size())) {
|
for (int i : ctx.item_range(actx.mod->wires_size())) {
|
||||||
RTLIL::Wire *wire = actx.mod->wire_at(i);
|
RTLIL::Wire *wire = actx.mod->wire_at(i);
|
||||||
for (int j = 0; j < wire->width; ++j) {
|
for (int j = 0; j < wire->width; ++j) {
|
||||||
RTLIL::SigBit s1(wire, j);
|
RTLIL::SigBit s1(wire, j);
|
||||||
RTLIL::SigBit s2 = actx.assign_map(s1);
|
RTLIL::SigBit s2 = actx.assign_map(s1);
|
||||||
if (compare_signals(s2, s1, sig_analysis.registers, sig_analysis.cells, *this_thread_direct_wires))
|
if (compare_signals(s2, s1, sig_analysis.raw_registers, sig_analysis.raw_cell_connected, *this_thread_cell_wires))
|
||||||
sigmap_canonical_candidates.insert(ctx, s1);
|
candidates.insert(ctx, s1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return sigmap_canonical_candidates;
|
return candidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_assign_map(ShardedVector<RTLIL::SigBit>& sigmap_canonical_candidates, DirectWires& direct_wires, const SigConnKinds& sig_analysis, SigMap& assign_map) {
|
void update_assign_map(SigMap& assign_map, ShardedVector<RTLIL::SigBit>& sigmap_canonical_candidates, ExactCellWires& cell_wires, const SigConnKinds& sig_analysis) {
|
||||||
for (RTLIL::SigBit candidate : sigmap_canonical_candidates) {
|
for (RTLIL::SigBit candidate : sigmap_canonical_candidates) {
|
||||||
RTLIL::SigBit current_canonical = assign_map(candidate);
|
RTLIL::SigBit current_canonical = assign_map(candidate);
|
||||||
if (compare_signals(current_canonical, candidate, sig_analysis.registers, sig_analysis.cells, direct_wires))
|
// Resolves if two threads in build_candidates found different candidates
|
||||||
|
// for the same set
|
||||||
|
// TODO adds effort for single-threaded?
|
||||||
|
if (compare_signals(current_canonical, candidate, sig_analysis.raw_registers, sig_analysis.raw_cell_connected, cell_wires))
|
||||||
assign_map.add(candidate);
|
assign_map.add(candidate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -340,7 +345,7 @@ struct UsedSignals {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::tuple<DeferredUpdates, UsedSignals> analyse_connectivity(SigConnKinds& sig_analysis, const AnalysisContext& actx, CleanRunContext &clean_ctx) {
|
DeferredUpdates analyse_connectivity(UsedSignals& used, SigConnKinds& sig_analysis, const AnalysisContext& actx, CleanRunContext &clean_ctx) {
|
||||||
DeferredUpdates deferred(actx.subpool);
|
DeferredUpdates deferred(actx.subpool);
|
||||||
ShardedSigPool::Builder conn_builder(actx.subpool);
|
ShardedSigPool::Builder conn_builder(actx.subpool);
|
||||||
ShardedSigPool::Builder raw_conn_builder(actx.subpool);
|
ShardedSigPool::Builder raw_conn_builder(actx.subpool);
|
||||||
|
|
@ -390,8 +395,8 @@ std::tuple<DeferredUpdates, UsedSignals> analyse_connectivity(SigConnKinds& sig_
|
||||||
raw_conn_builder.process(ctx);
|
raw_conn_builder.process(ctx);
|
||||||
used_builder.process(ctx);
|
used_builder.process(ctx);
|
||||||
});
|
});
|
||||||
UsedSignals used {conn_builder, raw_conn_builder, used_builder};
|
used = {conn_builder, raw_conn_builder, used_builder};
|
||||||
return {std::move(deferred), std::move(used)};
|
return deferred;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WireDeleter {
|
struct WireDeleter {
|
||||||
|
|
@ -536,24 +541,26 @@ bool rmunused_module_signals(RTLIL::Module *module, ParallelDispatchThreadPool::
|
||||||
AnalysisContext actx(module, subpool);
|
AnalysisContext actx(module, subpool);
|
||||||
SigConnKinds conn_kinds(clean_ctx.flags.purge, actx, clean_ctx);
|
SigConnKinds conn_kinds(clean_ctx.flags.purge, actx, clean_ctx);
|
||||||
|
|
||||||
// Main thread's cached direct wires are retained and used later:
|
ExactCellWires cell_wires(conn_kinds.exact_cells, actx.assign_map);
|
||||||
DirectWires direct_wires(conn_kinds.direct, actx.assign_map);
|
// Collect sigmap representative candidates as built in parallel
|
||||||
// Other threads' caches get discarded when threads finish in build_candidates
|
// With parallel runs, this creates redundant candidates that have to resolve in update_assign_map
|
||||||
// but the per-thread results are collected into sigmap_canonical_candidates
|
ShardedVector<RTLIL::SigBit> new_sigmap_rep_candidates = build_candidates(cell_wires, conn_kinds, actx);
|
||||||
ShardedVector<RTLIL::SigBit> sigmap_canonical_candidates = build_candidates(direct_wires, conn_kinds, actx);
|
|
||||||
|
|
||||||
// Cache all the direct_wires results that we might possible need. This avoids the results
|
// Cache all the cell_wires results that we might possible need. This avoids the results
|
||||||
// changing when we update `assign_map` below.
|
// changing when we update `assign_map` below.
|
||||||
direct_wires.cache_all(sigmap_canonical_candidates);
|
cell_wires.cache_all(new_sigmap_rep_candidates);
|
||||||
// Modify assign_map to reflect the connectivity we want, not the one we have
|
// Modify assign_map to reflect the connectivity we want, not the one we have
|
||||||
update_assign_map(sigmap_canonical_candidates, direct_wires, conn_kinds, actx.assign_map);
|
// this changes representative selection in assign_map
|
||||||
|
update_assign_map(actx.assign_map, new_sigmap_rep_candidates, cell_wires, conn_kinds);
|
||||||
|
|
||||||
// Remove all wire-wire connections
|
// Remove all wire-wire connections
|
||||||
module->connections_.clear();
|
module->connections_.clear();
|
||||||
|
|
||||||
// UsedSigConnKinds used_sig_analysis(sig_analysis, actx);
|
UsedSignals used;
|
||||||
auto [deferred, used] = analyse_connectivity(conn_kinds, actx, clean_ctx);
|
DeferredUpdates deferred = analyse_connectivity(used, conn_kinds, actx, clean_ctx);
|
||||||
fixup_update_ports(deferred.update_connections);
|
fixup_cell_ports(deferred.update_connections);
|
||||||
|
// Rip up and re-apply init attributes onto representative wires with x-bits
|
||||||
|
// in place of unset init bits
|
||||||
consume_inits(deferred.initialized_wires, actx.assign_map).apply_normalised_inits();
|
consume_inits(deferred.initialized_wires, actx.assign_map).apply_normalised_inits();
|
||||||
|
|
||||||
WireDeleter deleter(used, clean_ctx.flags.purge, actx);
|
WireDeleter deleter(used, clean_ctx.flags.purge, actx);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue