mirror of
https://github.com/YosysHQ/yosys
synced 2026-01-17 07:56:26 +00:00
Merge d25171806b into 967b47d984
This commit is contained in:
commit
8d3b5ebe58
2 changed files with 97 additions and 34 deletions
|
|
@ -55,6 +55,7 @@ struct WreduceWorker
|
|||
ModIndex mi;
|
||||
|
||||
std::set<Cell*, IdString::compare_ptr_by_name<Cell>> work_queue_cells;
|
||||
std::set<Wire*, IdString::compare_ptr_by_name<Wire>> work_queue_wires;
|
||||
std::set<SigBit> work_queue_bits;
|
||||
pool<SigBit> keep_bits;
|
||||
FfInitVals initvals;
|
||||
|
|
@ -78,6 +79,8 @@ struct WreduceWorker
|
|||
for (int i = GetSize(sig_y)-1; i >= 0; i--)
|
||||
{
|
||||
auto info = mi.query(sig_y[i]);
|
||||
if (info == nullptr)
|
||||
return;
|
||||
if (!info->is_output && GetSize(info->ports) <= 1 && !keep_bits.count(mi.sigmap(sig_y[i]))) {
|
||||
bits_removed.push_back(State::Sx);
|
||||
continue;
|
||||
|
|
@ -393,6 +396,8 @@ struct WreduceWorker
|
|||
break;
|
||||
|
||||
auto info = mi.query(bit);
|
||||
if (info == nullptr)
|
||||
return;
|
||||
if (info->is_output || GetSize(info->ports) > 1)
|
||||
break;
|
||||
|
||||
|
|
@ -457,63 +462,87 @@ struct WreduceWorker
|
|||
return count;
|
||||
}
|
||||
|
||||
void run_wire(Wire *w, pool<SigSpec> complete_wires)
|
||||
{
|
||||
int unused_top_bits = 0;
|
||||
|
||||
if (w->port_id > 0 || count_nontrivial_wire_attrs(w) > 0)
|
||||
return;
|
||||
|
||||
for (int i = GetSize(w)-1; i >= 0; i--) {
|
||||
SigBit bit(w, i);
|
||||
auto info = mi.query(bit);
|
||||
if (info == nullptr)
|
||||
return;
|
||||
if (info && (info->is_input || info->is_output || GetSize(info->ports) > 0))
|
||||
break;
|
||||
unused_top_bits++;
|
||||
}
|
||||
|
||||
if (unused_top_bits == 0 || unused_top_bits == GetSize(w))
|
||||
return;
|
||||
|
||||
if (complete_wires[mi.sigmap(w).extract(0, GetSize(w) - unused_top_bits)])
|
||||
return;
|
||||
|
||||
log("Removed top %d bits (of %d) from wire %s.%s.\n", unused_top_bits, GetSize(w), log_id(module), log_id(w));
|
||||
Wire *nw = module->addWire(module->uniquify(IdString(w->name.str() + "_wreduce")), GetSize(w) - unused_top_bits);
|
||||
module->connect(nw, SigSpec(w).extract(0, GetSize(nw)));
|
||||
module->swap_names(w, nw);
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
// create a copy as mi.sigmap will be updated as we process the module
|
||||
// Create a copy as mi.sigmap will be updated as we process the module
|
||||
SigMap init_attr_sigmap = mi.sigmap;
|
||||
initvals.set(&init_attr_sigmap, module);
|
||||
|
||||
// Initialize cell work queue
|
||||
for (auto c : module->selected_cells())
|
||||
work_queue_cells.insert(c);
|
||||
|
||||
// Initialize wire work queue
|
||||
for (auto w : module->selected_wires())
|
||||
work_queue_wires.insert(w);
|
||||
|
||||
// Initialize keep bits
|
||||
for (auto w : module->wires()) {
|
||||
if (w->get_bool_attribute(ID::keep))
|
||||
for (auto bit : mi.sigmap(w))
|
||||
keep_bits.insert(bit);
|
||||
}
|
||||
|
||||
for (auto c : module->selected_cells())
|
||||
work_queue_cells.insert(c);
|
||||
|
||||
while (!work_queue_cells.empty())
|
||||
while (!work_queue_cells.empty() || !work_queue_wires.empty())
|
||||
{
|
||||
// Initialize complete wires
|
||||
pool<SigSpec> complete_wires;
|
||||
for (auto w : module->wires())
|
||||
complete_wires.insert(mi.sigmap(w));
|
||||
|
||||
// Run cells
|
||||
work_queue_bits.clear();
|
||||
for (auto c : work_queue_cells)
|
||||
run_cell(c);
|
||||
|
||||
// Run wires
|
||||
for (auto w : work_queue_wires)
|
||||
run_wire(w, complete_wires);
|
||||
|
||||
// Get next batch of cells to process
|
||||
work_queue_cells.clear();
|
||||
for (auto bit : work_queue_bits)
|
||||
for (auto port : mi.query_ports(bit))
|
||||
if (module->selected(port.cell))
|
||||
work_queue_cells.insert(port.cell);
|
||||
}
|
||||
|
||||
pool<SigSpec> complete_wires;
|
||||
for (auto w : module->wires())
|
||||
complete_wires.insert(mi.sigmap(w));
|
||||
// Get next batch of wires to process
|
||||
work_queue_wires.clear();
|
||||
for (auto bit : work_queue_bits)
|
||||
if (bit.wire != NULL && module->selected(bit.wire))
|
||||
work_queue_wires.insert(bit.wire);
|
||||
|
||||
for (auto w : module->selected_wires())
|
||||
{
|
||||
int unused_top_bits = 0;
|
||||
|
||||
if (w->port_id > 0 || count_nontrivial_wire_attrs(w) > 0)
|
||||
continue;
|
||||
|
||||
for (int i = GetSize(w)-1; i >= 0; i--) {
|
||||
SigBit bit(w, i);
|
||||
auto info = mi.query(bit);
|
||||
if (info && (info->is_input || info->is_output || GetSize(info->ports) > 0))
|
||||
break;
|
||||
unused_top_bits++;
|
||||
}
|
||||
|
||||
if (unused_top_bits == 0 || unused_top_bits == GetSize(w))
|
||||
continue;
|
||||
|
||||
if (complete_wires[mi.sigmap(w).extract(0, GetSize(w) - unused_top_bits)])
|
||||
continue;
|
||||
|
||||
log("Removed top %d bits (of %d) from wire %s.%s.\n", unused_top_bits, GetSize(w), log_id(module), log_id(w));
|
||||
Wire *nw = module->addWire(NEW_ID, GetSize(w) - unused_top_bits);
|
||||
module->connect(nw, SigSpec(w).extract(0, GetSize(nw)));
|
||||
module->swap_names(w, nw);
|
||||
// Reload module
|
||||
mi.reload_module();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
34
tests/opt/wreduce_traversal.ys
Normal file
34
tests/opt/wreduce_traversal.ys
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
# Ensure wreduce propagates width reductions across dependent cells.
|
||||
read_verilog <<EOT
|
||||
module top(input [7:0] a, input [7:0] b, input [3:0] c, output [3:0] y);
|
||||
wire [8:0] sum_full;
|
||||
wire [3:0] sum_trunc;
|
||||
|
||||
assign sum_full = a + b;
|
||||
assign sum_trunc = sum_full[3:0];
|
||||
assign y = sum_trunc + c;
|
||||
endmodule
|
||||
EOT
|
||||
|
||||
hierarchy -auto-top
|
||||
proc
|
||||
opt_expr
|
||||
opt_clean
|
||||
|
||||
design -save gold
|
||||
|
||||
wreduce
|
||||
opt_clean
|
||||
|
||||
# After wreduce, the first add should be reduced from 9 bits to 4 bits
|
||||
select -assert-count 2 t:$add
|
||||
select -assert-count 0 t:$add r:Y_WIDTH=9 %i
|
||||
select -assert-count 2 t:$add r:Y_WIDTH=4 %i
|
||||
|
||||
design -stash reduced
|
||||
|
||||
design -import gold -as gold
|
||||
design -import reduced -as reduced
|
||||
|
||||
miter -equiv -flatten -make_assert -make_outputs gold reduced miter
|
||||
sat -verify -prove-asserts -show-ports miter
|
||||
Loading…
Add table
Add a link
Reference in a new issue