mirror of https://github.com/YosysHQ/yosys.git
Revert three passes
This commit is contained in:
parent
a0d1c8b30f
commit
b5f3d7ee9c
|
|
@ -31,9 +31,8 @@ struct ExclusiveDatabase
|
|||
|
||||
dict<SigBit, std::pair<SigSpec,std::vector<Const>>> sig_cmp_prev;
|
||||
|
||||
ExclusiveDatabase(Module *module, const SigMap &sigmap, bool assume_excl, bool make_excl) : module(module), sigmap(sigmap)
|
||||
ExclusiveDatabase(Module *module, const SigMap &sigmap) : module(module), sigmap(sigmap)
|
||||
{
|
||||
if (assume_excl || make_excl) return;
|
||||
SigSpec const_sig, nonconst_sig;
|
||||
SigBit y_port;
|
||||
pool<Cell*> reduce_or;
|
||||
|
|
@ -181,7 +180,7 @@ struct MuxpackWorker
|
|||
}
|
||||
}
|
||||
|
||||
void find_chain_start_cells(bool assume_excl)
|
||||
void find_chain_start_cells()
|
||||
{
|
||||
for (auto cell : candidate_cells)
|
||||
{
|
||||
|
|
@ -211,7 +210,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 (!assume_excl && !excl_db.query(s_sig))
|
||||
if (!excl_db.query(s_sig))
|
||||
goto start_cell;
|
||||
}
|
||||
|
||||
|
|
@ -244,7 +243,7 @@ struct MuxpackWorker
|
|||
return chain;
|
||||
}
|
||||
|
||||
void process_chain(vector<Cell*> &chain, bool make_excl)
|
||||
void process_chain(vector<Cell*> &chain)
|
||||
{
|
||||
if (GetSize(chain) < 2)
|
||||
return;
|
||||
|
|
@ -277,7 +276,6 @@ struct MuxpackWorker
|
|||
for (int i = 1; i < cases; i++) {
|
||||
Cell* prev_cell = chain[cursor+i-1];
|
||||
Cell* cursor_cell = chain[cursor+i];
|
||||
Cell* cell = cursor_cell; // SILIMATE: Set cell to cursor cell for better naming
|
||||
if (sigmap(prev_cell->getPort(ID::Y)) == sigmap(cursor_cell->getPort(ID::A))) {
|
||||
b_sig.append(cursor_cell->getPort(ID::B));
|
||||
s_sig.append(cursor_cell->getPort(ID::S));
|
||||
|
|
@ -285,72 +283,13 @@ struct MuxpackWorker
|
|||
else {
|
||||
log_assert(cursor_cell->type == ID($mux));
|
||||
b_sig.append(cursor_cell->getPort(ID::A));
|
||||
s_sig.append(module->LogicNot(NEW_ID2_SUFFIX("sel"), cursor_cell->getPort(ID::S), false, cell->get_src_attribute())); // SILIMATE: Improve the naming
|
||||
s_sig.append(module->LogicNot(NEW_ID, cursor_cell->getPort(ID::S)));
|
||||
}
|
||||
remove_cells.insert(cursor_cell);
|
||||
first_cell->add_strpool_attribute(ID::src, cursor_cell->get_strpool_attribute(ID::src)); // SILIMATE: Improve src attribution
|
||||
}
|
||||
|
||||
if (make_excl) {
|
||||
/* Create the following one-hot select line decoder:
|
||||
S0 S1 S2 S3 ...
|
||||
| | | |
|
||||
+--------+ +----------+ +-------------+ |
|
||||
| _|_ | _|_ | _|_ |
|
||||
| \_/ | \_/ | \_/ |
|
||||
| o | o | o |
|
||||
| | | | | ___ | |
|
||||
| +----------+ | | / | | |
|
||||
| | | |___| | / |___| |
|
||||
| |___| | & | / / | & | / ...
|
||||
| | & | \___/ / / \___/ / /
|
||||
| \___/ | | / | | /
|
||||
| | +------+ +-------+
|
||||
| | | | | |
|
||||
| | |___| |___|
|
||||
| | | & | | & |
|
||||
| | \___/ \___/
|
||||
| | | |
|
||||
S0 S0'S1 S0'S1'S2 S0'S1'S2'S3 ...
|
||||
*/
|
||||
SigSpec decodedSelect;
|
||||
Cell *cell = last_cell;
|
||||
std::vector<RTLIL::SigBit> select_bits = s_sig.bits();
|
||||
RTLIL::SigBit prevSigNot = RTLIL::State::S1;
|
||||
RTLIL::SigBit prevSigAnd = RTLIL::State::S1;
|
||||
for (int i = (int) (select_bits.size() -1); i >= 0; i--) {
|
||||
Yosys::RTLIL::SigBit sigbit = select_bits[i];
|
||||
if (i == (int) (select_bits.size() -1)) {
|
||||
decodedSelect.append(sigbit);
|
||||
Wire *not_y = module->addWire(NEW_ID2_SUFFIX("not_y"), 1);
|
||||
module->addNot(NEW_ID2_SUFFIX("not"), sigbit, not_y, false, last_cell->get_src_attribute());
|
||||
prevSigNot = not_y;
|
||||
} else if (i == (int) (select_bits.size() -2)) {
|
||||
Wire *and_y = module->addWire(NEW_ID2_SUFFIX("and_y"), 1);
|
||||
module->addAnd(NEW_ID2_SUFFIX("sel"), sigbit, prevSigNot, and_y, false, last_cell->get_src_attribute());
|
||||
decodedSelect.append(and_y);
|
||||
Wire *not_y = module->addWire(NEW_ID2_SUFFIX("not_y"), 1);
|
||||
module->addNot(NEW_ID2_SUFFIX("not"), sigbit, not_y, false, last_cell->get_src_attribute());
|
||||
prevSigAnd = prevSigNot;
|
||||
prevSigNot = not_y;
|
||||
} else {
|
||||
Wire *and_y1 = module->addWire(NEW_ID2_SUFFIX("and_y1"), 1);
|
||||
module->addAnd(NEW_ID2_SUFFIX("sel"), prevSigAnd, prevSigNot, and_y1, false, last_cell->get_src_attribute());
|
||||
Wire *and_y2 = module->addWire(NEW_ID2_SUFFIX("and_y2"), 1);
|
||||
module->addAnd(NEW_ID2_SUFFIX("sel"), sigbit, and_y1, and_y2, false, last_cell->get_src_attribute());
|
||||
decodedSelect.append(and_y2);
|
||||
Wire *not_y = module->addWire(NEW_ID2_SUFFIX("not_y"), 1);
|
||||
module->addNot(NEW_ID2_SUFFIX("not"), sigbit, not_y, false, last_cell->get_src_attribute());
|
||||
prevSigAnd = and_y1;
|
||||
prevSigNot = not_y;
|
||||
}
|
||||
}
|
||||
decodedSelect.reverse();
|
||||
first_cell->setPort(ID::S, decodedSelect);
|
||||
} else {
|
||||
first_cell->setPort(ID::S, s_sig);
|
||||
}
|
||||
first_cell->setPort(ID::B, b_sig);
|
||||
first_cell->setPort(ID::S, s_sig);
|
||||
first_cell->setParam(ID::S_WIDTH, GetSize(s_sig));
|
||||
first_cell->setPort(ID::Y, last_cell->getPort(ID::Y));
|
||||
|
||||
|
|
@ -370,18 +309,17 @@ struct MuxpackWorker
|
|||
candidate_cells.clear();
|
||||
}
|
||||
|
||||
MuxpackWorker(Module *module, bool assume_excl, bool make_excl) :
|
||||
module(module), sigmap(module), mux_count(0), pmux_count(0), excl_db(module, sigmap, assume_excl, make_excl)
|
||||
MuxpackWorker(Module *module) :
|
||||
module(module), sigmap(module), mux_count(0), pmux_count(0), excl_db(module, sigmap)
|
||||
{
|
||||
make_sig_chain_next_prev();
|
||||
find_chain_start_cells(assume_excl);
|
||||
find_chain_start_cells();
|
||||
|
||||
// Make the actual transform
|
||||
for (auto c : chain_start_cells) {
|
||||
vector<Cell *> chain = create_chain(c);
|
||||
process_chain(chain, make_excl);
|
||||
vector<Cell*> chain = create_chain(c);
|
||||
process_chain(chain);
|
||||
}
|
||||
// Clean up
|
||||
|
||||
cleanup();
|
||||
}
|
||||
};
|
||||
|
|
@ -392,7 +330,7 @@ struct MuxpackPass : public Pass {
|
|||
{
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
log("\n");
|
||||
log(" muxpack [options] [selection]\n");
|
||||
log(" muxpack [selection]\n");
|
||||
log("\n");
|
||||
log("This pass converts cascaded chains of $pmux cells (e.g. those create from case\n");
|
||||
log("constructs) and $mux cells (e.g. those created by if-else constructs) into\n");
|
||||
|
|
@ -402,32 +340,14 @@ 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(" -assume_excl\n");
|
||||
log(" assume mutually exclusive constraint when packing (may result in inequivalence)\n");
|
||||
log("\n");
|
||||
log(" -make_excl\n");
|
||||
log(" Adds a one-hot decoder on the control signals\n");
|
||||
log("\n");
|
||||
}
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||
{
|
||||
bool assume_excl = false;
|
||||
bool make_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] == "-assume_excl") {
|
||||
assume_excl = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-make_excl") {
|
||||
make_excl = true;
|
||||
assume_excl = true;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
extra_args(args, argidx, design);
|
||||
|
|
@ -436,15 +356,9 @@ struct MuxpackPass : public Pass {
|
|||
int pmux_count = 0;
|
||||
|
||||
for (auto module : design->selected_modules()) {
|
||||
int worker_mux_count = 0;
|
||||
int worker_pmux_count = 0;
|
||||
do {
|
||||
MuxpackWorker worker(module, assume_excl, make_excl);
|
||||
mux_count += worker.mux_count;
|
||||
pmux_count += worker.pmux_count;
|
||||
worker_mux_count = worker.mux_count;
|
||||
worker_pmux_count = worker.pmux_count;
|
||||
} while (worker_mux_count + worker_pmux_count > 0);
|
||||
MuxpackWorker worker(module);
|
||||
mux_count += worker.mux_count;
|
||||
pmux_count += worker.pmux_count;
|
||||
}
|
||||
|
||||
log("Converted %d (p)mux cells into %d pmux cells.\n", mux_count, pmux_count);
|
||||
|
|
|
|||
|
|
@ -36,14 +36,10 @@ struct BmuxmapPass : public Pass {
|
|||
log(" -pmux\n");
|
||||
log(" transform to $pmux instead of $mux cells.\n");
|
||||
log("\n");
|
||||
log(" -fewunq\n");
|
||||
log(" only transform $bmux cells that have few unique A bits.\n");
|
||||
log("\n");
|
||||
}
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||
{
|
||||
bool pmux_mode = false;
|
||||
bool fewunq_mode = false;
|
||||
|
||||
log_header(design, "Executing BMUXMAP pass.\n");
|
||||
|
||||
|
|
@ -53,10 +49,6 @@ struct BmuxmapPass : public Pass {
|
|||
pmux_mode = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-fewunq") {
|
||||
fewunq_mode = true;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
extra_args(args, argidx, design);
|
||||
|
|
@ -66,17 +58,6 @@ struct BmuxmapPass : public Pass {
|
|||
{
|
||||
if (cell->type != ID($bmux))
|
||||
continue;
|
||||
|
||||
if (fewunq_mode) {
|
||||
SigSpec data = cell->getPort(ID::A);
|
||||
SigMap sigmap(module);
|
||||
pool<SigBit> unqbits;
|
||||
for (auto bit : data)
|
||||
if (bit.wire != nullptr)
|
||||
unqbits.insert(sigmap(bit));
|
||||
if (GetSize(unqbits) > GetSize(data)/2)
|
||||
continue;
|
||||
}
|
||||
|
||||
SigSpec sel = cell->getPort(ID::S);
|
||||
SigSpec data = cell->getPort(ID::A);
|
||||
|
|
@ -89,16 +70,14 @@ struct BmuxmapPass : public Pass {
|
|||
SigSpec new_a = SigSpec(State::Sx, width);
|
||||
SigSpec new_s = module->addWire(NEW_ID2_SUFFIX("sel"), num_cases); // SILIMATE: Improve the naming
|
||||
SigSpec new_data = module->addWire(NEW_ID2_SUFFIX("data"), width); // SILIMATE: Improve the naming
|
||||
for (int val = 0; val < num_cases; val++) {
|
||||
RTLIL::Cell *eq = module->addEq(NEW_ID2_SUFFIX("eq"), sel, SigSpec(val, GetSize(sel)), new_s[val]); // SILIMATE: Improve the naming
|
||||
for (auto attr : cell->attributes) // SILIMATE: Copy all attributes from original cell to new cell
|
||||
eq->attributes[attr.first] = attr.second;
|
||||
for (int val = 0; val < num_cases; val++)
|
||||
{
|
||||
module->addEq(NEW_ID2_SUFFIX("eq"), sel, SigSpec(val, GetSize(sel)), new_s[val], false, cell->get_src_attribute()); // SILIMATE: Improve the naming
|
||||
}
|
||||
IdString cell_name = cell->name; // SILIMATE: Save the original cell name
|
||||
module->rename(cell_name, NEW_ID); // SILIMATE: Rename the original cell, which will be deleted
|
||||
RTLIL::Cell *pmux = module->addPmux(cell_name, new_a, data, new_s, new_data); // SILIMATE: Improve the naming
|
||||
pmux->attributes = cell->attributes; // SILIMATE: Copy all attributes from original cell to new cell
|
||||
RTLIL::Cell *pmux = module->addPmux(NEW_ID, new_a, data, new_s, new_data);
|
||||
pmux->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
|
||||
data = new_data;
|
||||
module->swap_names(cell, pmux); // SILIMATE: Improve the naming
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -110,7 +89,7 @@ struct BmuxmapPass : public Pass {
|
|||
data.extract(i*2+width, width),
|
||||
sel[idx],
|
||||
new_data.extract(i, width));
|
||||
mux->attributes = cell->attributes; // SILIMATE: Copy all attributes from original cell to new cell
|
||||
mux->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
|
||||
}
|
||||
data = new_data;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,11 +29,10 @@ struct ExtractReducePass : public Pass
|
|||
enum GateType {
|
||||
And,
|
||||
Or,
|
||||
Xor,
|
||||
Mux
|
||||
Xor
|
||||
};
|
||||
|
||||
ExtractReducePass() : Pass("extract_reduce", "converts gate chains into $reduce_*/$pmux cells") { }
|
||||
ExtractReducePass() : Pass("extract_reduce", "converts gate chains into $reduce_* cells") { }
|
||||
|
||||
void help() override
|
||||
{
|
||||
|
|
@ -50,46 +49,18 @@ struct ExtractReducePass : public Pass
|
|||
log("to map the design to only $_AND_ cells, run extract_reduce, map the remaining\n");
|
||||
log("parts of the design to AND/OR/XOR cells, and run extract_reduce a second time.\n");
|
||||
log("\n");
|
||||
log("Silimate has modified this pass to support word-level cells ($and, $or, \n");
|
||||
log("and $xor) as well as the single-bit cells ($_AND_, $_OR_, and $_XOR_).\n");
|
||||
log("Mux cells ($mux, $_MUX_) can also be reduced to $pmux cells with the mods.\n");
|
||||
log("\n");
|
||||
log(" -allow-off-chain\n");
|
||||
log(" Allows matching of cells that have loads outside the chain. These cells\n");
|
||||
log(" will be replicated and folded into the $reduce_* cell, but the original\n");
|
||||
log(" cell will remain, driving its original loads.\n");
|
||||
log("\n");
|
||||
log(" -mux-only\n");
|
||||
log(" Only reduce $mux cells to $pmux cells, ignore other cell types.\n");
|
||||
log("\n");
|
||||
log(" -no-mux\n");
|
||||
log(" Do not reduce $mux cells to $pmux cells, only reduce other cell types.\n");
|
||||
log("\n");
|
||||
log(" -assume-excl\n");
|
||||
log(" Assume that $mux select signals are exclusive. Will result in logical\n");
|
||||
log(" inequivalence if this assumption is incorrect.\n");
|
||||
log("\n");
|
||||
}
|
||||
|
||||
inline bool IsSingleBit(Cell* cell)
|
||||
{
|
||||
return (cell->hasParam(ID::WIDTH) && cell->getParam(ID::WIDTH).as_int() == 1) ||
|
||||
(cell->hasParam(ID::A_WIDTH) &&
|
||||
cell->getParam(ID::A_WIDTH).as_int() == 1 &&
|
||||
cell->getParam(ID::B_WIDTH).as_int() == 1 &&
|
||||
cell->getParam(ID::Y_WIDTH).as_int() == 1);
|
||||
}
|
||||
|
||||
inline bool IsRightType(Cell* cell, GateType gt)
|
||||
{
|
||||
return (cell->type == ID($_AND_) && gt == GateType::And) ||
|
||||
(cell->type == ID($_OR_) && gt == GateType::Or) ||
|
||||
(cell->type == ID($_XOR_) && gt == GateType::Xor) ||
|
||||
(cell->type == ID($_MUX_) && gt == GateType::Mux) ||
|
||||
(cell->type == ID($and) && IsSingleBit(cell) && gt == GateType::And) ||
|
||||
(cell->type == ID($or) && IsSingleBit(cell) && gt == GateType::Or) ||
|
||||
(cell->type == ID($xor) && IsSingleBit(cell) && gt == GateType::Xor) ||
|
||||
(cell->type == ID($mux) && IsSingleBit(cell) && gt == GateType::Mux);
|
||||
(cell->type == ID($_XOR_) && gt == GateType::Xor);
|
||||
}
|
||||
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||
|
|
@ -98,7 +69,7 @@ struct ExtractReducePass : public Pass
|
|||
log_push();
|
||||
|
||||
size_t argidx;
|
||||
bool allow_off_chain = false, mux_only = false, no_mux = false, assume_excl = false;
|
||||
bool allow_off_chain = false;
|
||||
for (argidx = 1; argidx < args.size(); argidx++)
|
||||
{
|
||||
if (args[argidx] == "-allow-off-chain")
|
||||
|
|
@ -106,21 +77,6 @@ struct ExtractReducePass : public Pass
|
|||
allow_off_chain = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-mux-only")
|
||||
{
|
||||
mux_only = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-no-mux")
|
||||
{
|
||||
no_mux = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-assume-excl")
|
||||
{
|
||||
assume_excl = true;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
extra_args(args, argidx, design);
|
||||
|
|
@ -174,26 +130,10 @@ struct ExtractReducePass : public Pass
|
|||
gt = GateType::Or;
|
||||
else if (cell->type == ID($_XOR_))
|
||||
gt = GateType::Xor;
|
||||
else if (cell->type == ID($_MUX_))
|
||||
gt = GateType::Mux;
|
||||
else if (cell->type == ID($and) && IsSingleBit(cell))
|
||||
gt = GateType::And;
|
||||
else if (cell->type == ID($or) && IsSingleBit(cell))
|
||||
gt = GateType::Or;
|
||||
else if (cell->type == ID($xor) && IsSingleBit(cell))
|
||||
gt = GateType::Xor;
|
||||
else if (cell->type == ID($mux) && IsSingleBit(cell))
|
||||
gt = GateType::Mux;
|
||||
else
|
||||
continue;
|
||||
|
||||
if (mux_only && gt != GateType::Mux)
|
||||
continue;
|
||||
|
||||
if (no_mux && gt == GateType::Mux)
|
||||
continue;
|
||||
|
||||
log_debug("Working on cell %s...\n", cell->name);
|
||||
log("Working on cell %s...\n", cell->name);
|
||||
|
||||
// If looking for a single chain, follow linearly to the sink
|
||||
pool<Cell*> sinks;
|
||||
|
|
@ -280,60 +220,33 @@ struct ExtractReducePass : public Pass
|
|||
//We have our list, go act on it
|
||||
for(auto head_cell : sinks)
|
||||
{
|
||||
log_debug(" Head cell is %s\n", head_cell->name);
|
||||
log(" Head cell is %s\n", head_cell->name);
|
||||
|
||||
//Avoid duplication if we already were covered
|
||||
if(consumed_cells.count(head_cell))
|
||||
continue;
|
||||
|
||||
dict<SigBit, int> sources;
|
||||
dict<SigBit, int> sels;
|
||||
int inner_cells = 0;
|
||||
std::deque<std::pair<Cell*, SigBit>> bfs_queue = {{head_cell, State::S1}};
|
||||
std::set<Cell*> seen_set = {};
|
||||
std::deque<Cell*> bfs_queue = {head_cell};
|
||||
while (bfs_queue.size())
|
||||
{
|
||||
auto bfs_item = bfs_queue.front();
|
||||
Cell* x = bfs_queue.front();
|
||||
bfs_queue.pop_front();
|
||||
|
||||
Cell* x = bfs_item.first;
|
||||
SigBit excl = bfs_item.second;
|
||||
|
||||
for (IdString port: {ID::B, ID::A}) {
|
||||
for (auto port: {ID::A, ID::B}) {
|
||||
auto bit = sigmap(x->getPort(port)[0]);
|
||||
|
||||
bool sink_single = sig_to_sink[bit].size() == 1 && !port_sigs.count(bit);
|
||||
|
||||
Cell* drv = sig_to_driver[bit];
|
||||
bool drv_ok = drv && IsRightType(drv, gt) && !consumed_cells.count(drv) && !seen_set.count(drv);
|
||||
seen_set.insert(drv);
|
||||
|
||||
SigBit s_port;
|
||||
SigBit sel_sig;
|
||||
if (gt == GateType::Mux) {
|
||||
s_port = sigmap(x->getPort(ID::S)[0]);
|
||||
if (port == ID::A)
|
||||
sel_sig = module->Not(NEW_ID2_SUFFIX("not"), s_port, false, x->get_src_attribute());
|
||||
else
|
||||
sel_sig = module->Buf(NEW_ID2_SUFFIX("buf"), s_port, false, x->get_src_attribute());
|
||||
}
|
||||
bool drv_ok = drv && drv->type == head_cell->type;
|
||||
|
||||
if (drv_ok && (allow_off_chain || sink_single)) {
|
||||
inner_cells++;
|
||||
if (gt == GateType::Mux && !assume_excl) { // if not assuming exclusivity, add to excl signal
|
||||
SigBit sel_sig_inv = (port == ID::A) ? module->Not(NEW_ID2_SUFFIX("not"), s_port, false, x->get_src_attribute())[0] : s_port;
|
||||
bfs_queue.push_back({drv, module->And(NEW_ID2_SUFFIX("excl_and"), sel_sig_inv, excl, false, x->get_src_attribute())});
|
||||
} else { // otherwise, just use the drv signal and don't worry about exclusivity
|
||||
bfs_queue.push_back({drv, excl});
|
||||
}
|
||||
bfs_queue.push_back(drv);
|
||||
} else {
|
||||
sources[module->Buf(NEW_ID2_SUFFIX("buf"), bit, false, x->get_src_attribute())]++;
|
||||
if (gt == GateType::Mux) {
|
||||
if (assume_excl) // if assuming exclusivity, just use select signal
|
||||
sels[sel_sig]++;
|
||||
else // enforce exclusivity by ANDing with excl signal
|
||||
sels[module->And(NEW_ID2_SUFFIX("selex_and"), sel_sig, excl)]++;
|
||||
}
|
||||
sources[bit]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -341,35 +254,27 @@ struct ExtractReducePass : public Pass
|
|||
if (inner_cells)
|
||||
{
|
||||
// Worth it to create reduce cell
|
||||
log_debug("Creating reduce_* cell for %s (%s) in %s\n", head_cell->name.c_str(), head_cell->type.c_str(), module->name.c_str());
|
||||
log(" Creating $reduce_* cell!\n");
|
||||
|
||||
SigBit output = sigmap(head_cell->getPort(ID::Y)[0]);
|
||||
|
||||
SigSpec input, sel;
|
||||
SigSpec input;
|
||||
for (auto it : sources) {
|
||||
bool cond;
|
||||
if (head_cell->type == ID($_XOR_) || head_cell->type == ID($xor))
|
||||
if (head_cell->type == ID($_XOR_))
|
||||
cond = it.second & 1;
|
||||
else
|
||||
cond = it.second != 0;
|
||||
if (cond || head_cell->hasPort(ID::S))
|
||||
if (cond)
|
||||
input.append(it.first);
|
||||
}
|
||||
if (head_cell->hasPort(ID::S)) {
|
||||
for (auto it : sels)
|
||||
sel.append(it.first);
|
||||
input.reverse();
|
||||
sel.reverse();
|
||||
}
|
||||
|
||||
if (head_cell->type == ID($_AND_) || head_cell->type == ID($and)) {
|
||||
module->addReduceAnd(NEW_ID2_SUFFIX("reduce_and"), input, output, false, cell->get_src_attribute()); // SILIMATE: Improve the naming
|
||||
} else if (head_cell->type == ID($_OR_) || head_cell->type == ID($or)) {
|
||||
module->addReduceOr(NEW_ID2_SUFFIX("reduce_or"), input, output, false, cell->get_src_attribute()); // SILIMATE: Improve the naming
|
||||
} else if (head_cell->type == ID($_XOR_) || head_cell->type == ID($xor)) {
|
||||
module->addReduceXor(NEW_ID2_SUFFIX("reduce_xor"), input, output, false, cell->get_src_attribute()); // SILIMATE: Improve the naming
|
||||
} else if (head_cell->type == ID($_MUX_) || head_cell->type == ID($mux)) {
|
||||
module->addPmux(NEW_ID2_SUFFIX("pmux"), State::Sx, input, sel, output, cell->get_src_attribute()); // SILIMATE: Improve the naming
|
||||
if (head_cell->type == ID($_AND_)) {
|
||||
module->addReduceAnd(NEW_ID, input, output);
|
||||
} else if (head_cell->type == ID($_OR_)) {
|
||||
module->addReduceOr(NEW_ID, input, output);
|
||||
} else if (head_cell->type == ID($_XOR_)) {
|
||||
module->addReduceXor(NEW_ID, input, output);
|
||||
} else {
|
||||
log_assert(false);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue