mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-24 01:25:33 +00:00
Working tree balance pass
This commit is contained in:
parent
f707a3b6cd
commit
4f6a153961
5 changed files with 51 additions and 23 deletions
|
@ -191,6 +191,8 @@ struct SplitfanoutPass : public Pass {
|
|||
log("Split %d cells in module '%s' into %d copies based on fanout.\n",
|
||||
count_split_pre, log_id(module), count_split_post);
|
||||
}
|
||||
|
||||
Pass::call(design, "clean");
|
||||
}
|
||||
} SplitfanoutPass;
|
||||
|
||||
|
|
|
@ -31,9 +31,9 @@ struct ExclusiveDatabase
|
|||
|
||||
dict<SigBit, std::pair<SigSpec,std::vector<Const>>> sig_cmp_prev;
|
||||
|
||||
ExclusiveDatabase(Module *module, const SigMap &sigmap, bool ignore_excl) : module(module), sigmap(sigmap)
|
||||
ExclusiveDatabase(Module *module, const SigMap &sigmap, bool assume_excl) : module(module), sigmap(sigmap)
|
||||
{
|
||||
if (ignore_excl) return;
|
||||
if (assume_excl) return;
|
||||
SigSpec const_sig, nonconst_sig;
|
||||
SigBit y_port;
|
||||
pool<Cell*> reduce_or;
|
||||
|
@ -181,7 +181,7 @@ struct MuxpackWorker
|
|||
}
|
||||
}
|
||||
|
||||
void find_chain_start_cells(bool ignore_excl)
|
||||
void find_chain_start_cells(bool assume_excl)
|
||||
{
|
||||
for (auto cell : candidate_cells)
|
||||
{
|
||||
|
@ -211,7 +211,7 @@ struct MuxpackWorker
|
|||
log_assert(prev_cell);
|
||||
SigSpec s_sig = sigmap(cell->getPort(ID::S));
|
||||
s_sig.append(sigmap(prev_cell->getPort(ID::S)));
|
||||
if (!ignore_excl && !excl_db.query(s_sig))
|
||||
if (!assume_excl && !excl_db.query(s_sig))
|
||||
goto start_cell;
|
||||
}
|
||||
|
||||
|
@ -310,11 +310,11 @@ struct MuxpackWorker
|
|||
candidate_cells.clear();
|
||||
}
|
||||
|
||||
MuxpackWorker(Module *module, bool ignore_excl) :
|
||||
module(module), sigmap(module), mux_count(0), pmux_count(0), excl_db(module, sigmap, ignore_excl)
|
||||
MuxpackWorker(Module *module, bool assume_excl) :
|
||||
module(module), sigmap(module), mux_count(0), pmux_count(0), excl_db(module, sigmap, assume_excl)
|
||||
{
|
||||
make_sig_chain_next_prev();
|
||||
find_chain_start_cells(ignore_excl);
|
||||
find_chain_start_cells(assume_excl);
|
||||
|
||||
for (auto c : chain_start_cells) {
|
||||
vector<Cell*> chain = create_chain(c);
|
||||
|
@ -341,32 +341,43 @@ struct MuxpackPass : public Pass {
|
|||
log("whose select lines are driven by '$eq' cells with other such cells if it can be\n");
|
||||
log("certain that their select inputs are mutually exclusive.\n");
|
||||
log("\n");
|
||||
log(" -ignore_excl\n");
|
||||
log(" ignore mutually exclusive constraint when packing (less conservative)\n");
|
||||
log(" -splitfanout\n");
|
||||
log(" run splitfanout pass first\n");
|
||||
log("\n");
|
||||
log(" -assume_excl\n");
|
||||
log(" assume mutually exclusive constraint when packing (may result in inequivalence)\n");
|
||||
log("\n");
|
||||
}
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||
{
|
||||
bool ignore_excl = false;
|
||||
bool splitfanout = false;
|
||||
bool assume_excl = false;
|
||||
|
||||
log_header(design, "Executing MUXPACK pass ($mux cell cascades to $pmux).\n");
|
||||
|
||||
size_t argidx;
|
||||
for (argidx = 1; argidx < args.size(); argidx++)
|
||||
{
|
||||
if (args[argidx] == "-ignore_excl") {
|
||||
ignore_excl = true;
|
||||
if (args[argidx] == "-splitfanout") {
|
||||
splitfanout = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-assume_excl") {
|
||||
assume_excl = true;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
extra_args(args, argidx, design);
|
||||
|
||||
if (splitfanout)
|
||||
Pass::call(design, "splitfanout t:$mux t:$pmux");
|
||||
|
||||
int mux_count = 0;
|
||||
int pmux_count = 0;
|
||||
|
||||
for (auto module : design->selected_modules()) {
|
||||
MuxpackWorker worker(module, ignore_excl);
|
||||
MuxpackWorker worker(module, assume_excl);
|
||||
mux_count += worker.mux_count;
|
||||
pmux_count += worker.pmux_count;
|
||||
}
|
||||
|
|
|
@ -27,13 +27,17 @@ PRIVATE_NAMESPACE_BEGIN
|
|||
|
||||
|
||||
struct OptBalanceTreeWorker {
|
||||
// Module and signal map
|
||||
Module *module;
|
||||
SigMap sigmap;
|
||||
|
||||
// Counts of each cell type that are getting balanced
|
||||
dict<IdString, int> cell_count;
|
||||
|
||||
// Cells to remove
|
||||
pool<Cell*> remove_cells;
|
||||
|
||||
// Signal chain data structures
|
||||
dict<SigSpec, Cell*> sig_chain_next;
|
||||
dict<SigSpec, Cell*> sig_chain_prev;
|
||||
pool<SigBit> sigbit_with_non_chain_users;
|
||||
|
@ -59,7 +63,7 @@ struct OptBalanceTreeWorker {
|
|||
SigSpec y_sig = sigmap(cell->getPort(ID::Y));
|
||||
|
||||
// If a_sig already has a chain user, mark its bits as having non-chain users
|
||||
if (sig_chain_next.count(a_sig) && !a_sig.is_fully_const()) // also ok if a_sig is fully const
|
||||
if (sig_chain_next.count(a_sig) && !a_sig.is_fully_const()) // ok if a_sig is fully const
|
||||
for (auto a_bit : a_sig.bits())
|
||||
sigbit_with_non_chain_users.insert(a_bit);
|
||||
// Otherwise, mark cell as the next in the chain relative to a_sig
|
||||
|
@ -70,7 +74,7 @@ struct OptBalanceTreeWorker {
|
|||
|
||||
if (!b_sig.empty()) {
|
||||
// If b_sig already has a chain user, mark its bits as having non-chain users
|
||||
if (sig_chain_next.count(b_sig) && !b_sig.is_fully_const()) // also ok if b_sig is fully const
|
||||
if (sig_chain_next.count(b_sig) && !b_sig.is_fully_const()) // ok if b_sig is fully const
|
||||
for (auto b_bit : b_sig.bits())
|
||||
sigbit_with_non_chain_users.insert(b_bit);
|
||||
// Otherwise, mark cell as the next in the chain relative to b_sig
|
||||
|
@ -152,6 +156,8 @@ struct OptBalanceTreeWorker {
|
|||
Cell *mid_cell = chain[GetSize(chain) / 2];
|
||||
Cell *midnext_cell = chain[GetSize(chain) / 2 + 1];
|
||||
Cell *end_cell = chain.back();
|
||||
log("Balancing chain of %d cells: mid=%s, midnext=%s, endcell=%s\n",
|
||||
GetSize(chain), log_id(mid_cell), log_id(midnext_cell), log_id(end_cell));
|
||||
|
||||
// Get mid signals
|
||||
SigSpec mid_a_sig = sigmap(mid_cell->getPort(ID::A));
|
||||
|
@ -173,10 +179,14 @@ struct OptBalanceTreeWorker {
|
|||
midnext_cell->unsetPort(midnext_chain_port);
|
||||
end_cell->unsetPort(ID::Y);
|
||||
|
||||
// Create new mid wire
|
||||
Wire *mid_wire = module->addWire(NEW_ID, GetSize(mid_non_chain_sig));
|
||||
|
||||
// Perform rotation
|
||||
mid_cell->setPort(mid_non_chain_port, mid_wire);
|
||||
mid_cell->setPort(ID::Y, end_y_sig);
|
||||
midnext_cell->setPort(midnext_chain_port, mid_non_chain_sig);
|
||||
end_cell->setPort(ID::Y, mid_cell->getPort(mid_non_chain_port));
|
||||
end_cell->setPort(ID::Y, mid_wire);
|
||||
|
||||
// Recurse on subtrees
|
||||
vector<Cell*> left_chain(chain.begin(), chain.begin() + GetSize(chain) / 2);
|
||||
|
@ -213,6 +223,7 @@ struct OptBalanceTreeWorker {
|
|||
for (auto c : chain_start_cells) {
|
||||
vector<Cell*> chain = create_chain(c);
|
||||
process_chain(chain);
|
||||
cell_count[cell_type] += GetSize(chain);
|
||||
}
|
||||
|
||||
// Clean up
|
||||
|
@ -252,10 +263,8 @@ struct OptBalanceTreePass : public Pass {
|
|||
extra_args(args, argidx, design);
|
||||
|
||||
// Run splitfanout pass first
|
||||
if (splitfanout) {
|
||||
string cmd = "splitfanout t:$and t:$or t:$xor t:$add t:$mul";
|
||||
Pass::call(design, cmd);
|
||||
}
|
||||
if (splitfanout)
|
||||
Pass::call(design, "splitfanout t:$and t:$or t:$xor t:$add t:$mul");
|
||||
|
||||
// Count of all cells that were packed
|
||||
dict<IdString, int> cell_count;
|
||||
|
@ -269,7 +278,7 @@ struct OptBalanceTreePass : public Pass {
|
|||
|
||||
// Log stats
|
||||
for (auto cell_type : cell_types)
|
||||
log("Converted %d %s cells into %s trees.\n", cell_count[cell_type], log_id(cell_type), log_id(cell_type.str() + "_tree"));
|
||||
log("Converted %d %s cells into trees.\n", cell_count[cell_type], log_id(cell_type));
|
||||
}
|
||||
} OptBalanceTreePass;
|
||||
|
||||
|
|
|
@ -7,6 +7,9 @@ OBJS += passes/techmap/maccmap.o
|
|||
OBJS += passes/techmap/booth.o
|
||||
OBJS += passes/techmap/libparse.o
|
||||
|
||||
OBJS += passes/techmap/bmuxmap.o
|
||||
OBJS += passes/techmap/demuxmap.o
|
||||
|
||||
ifeq ($(ENABLE_ABC),1)
|
||||
OBJS += passes/techmap/abc.o
|
||||
OBJS += passes/techmap/abc9.o
|
||||
|
@ -30,8 +33,6 @@ OBJS += passes/techmap/extract_reduce.o
|
|||
OBJS += passes/techmap/alumacc.o
|
||||
OBJS += passes/techmap/dffinit.o
|
||||
OBJS += passes/techmap/pmuxtree.o
|
||||
OBJS += passes/techmap/bmuxmap.o
|
||||
OBJS += passes/techmap/demuxmap.o
|
||||
OBJS += passes/techmap/bwmuxmap.o
|
||||
OBJS += passes/techmap/muxcover.o
|
||||
OBJS += passes/techmap/aigmap.o
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue