mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-07 01:54:10 +00:00
Added support for truncating of wires to wreduce pass
This commit is contained in:
parent
d3b1a29708
commit
523df73145
|
@ -59,14 +59,20 @@ struct ModIndex : public RTLIL::Monitor
|
||||||
|
|
||||||
void port_add(RTLIL::Cell *cell, RTLIL::IdString port, const RTLIL::SigSpec &sig)
|
void port_add(RTLIL::Cell *cell, RTLIL::IdString port, const RTLIL::SigSpec &sig)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < SIZE(sig); i++)
|
for (int i = 0; i < SIZE(sig); i++) {
|
||||||
database[sigmap(sig[i])].ports.insert(PortInfo(cell, port, i));
|
RTLIL::SigBit bit = sigmap(sig[i]);
|
||||||
|
if (bit.wire)
|
||||||
|
database[bit].ports.insert(PortInfo(cell, port, i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void port_del(RTLIL::Cell *cell, RTLIL::IdString port, const RTLIL::SigSpec &sig)
|
void port_del(RTLIL::Cell *cell, RTLIL::IdString port, const RTLIL::SigSpec &sig)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < SIZE(sig); i++)
|
for (int i = 0; i < SIZE(sig); i++) {
|
||||||
database[sigmap(sig[i])].ports.erase(PortInfo(cell, port, i));
|
RTLIL::SigBit bit = sigmap(sig[i]);
|
||||||
|
if (bit.wire)
|
||||||
|
database[bit].ports.erase(PortInfo(cell, port, i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const SigBitInfo &info(RTLIL::SigBit bit)
|
const SigBitInfo &info(RTLIL::SigBit bit)
|
||||||
|
@ -83,10 +89,11 @@ struct ModIndex : public RTLIL::Monitor
|
||||||
for (auto wire : module->wires())
|
for (auto wire : module->wires())
|
||||||
if (wire->port_input || wire->port_output)
|
if (wire->port_input || wire->port_output)
|
||||||
for (int i = 0; i < SIZE(wire); i++) {
|
for (int i = 0; i < SIZE(wire); i++) {
|
||||||
if (wire->port_input)
|
RTLIL::SigBit bit = sigmap(RTLIL::SigBit(wire, i));
|
||||||
database[sigmap(RTLIL::SigBit(wire, i))].is_input = true;
|
if (bit.wire && wire->port_input)
|
||||||
if (wire->port_output)
|
database[bit].is_input = true;
|
||||||
database[sigmap(RTLIL::SigBit(wire, i))].is_output = true;
|
if (bit.wire && wire->port_output)
|
||||||
|
database[bit].is_output = true;
|
||||||
}
|
}
|
||||||
for (auto cell : module->cells())
|
for (auto cell : module->cells())
|
||||||
for (auto &conn : cell->connections())
|
for (auto &conn : cell->connections())
|
||||||
|
@ -137,6 +144,7 @@ struct ModIndex : public RTLIL::Monitor
|
||||||
{
|
{
|
||||||
if (auto_reload_module)
|
if (auto_reload_module)
|
||||||
reload_module();
|
reload_module();
|
||||||
|
|
||||||
auto it = database.find(sigmap(bit));
|
auto it = database.find(sigmap(bit));
|
||||||
if (it == database.end())
|
if (it == database.end())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -1071,6 +1071,36 @@ void RTLIL::Module::rename(RTLIL::IdString old_name, RTLIL::IdString new_name)
|
||||||
log_abort();
|
log_abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RTLIL::Module::swap_names(RTLIL::Wire *w1, RTLIL::Wire *w2)
|
||||||
|
{
|
||||||
|
log_assert(wires_[w1->name] == w1);
|
||||||
|
log_assert(wires_[w2->name] == w2);
|
||||||
|
log_assert(refcount_wires_ == 0);
|
||||||
|
|
||||||
|
wires_.erase(w1->name);
|
||||||
|
wires_.erase(w2->name);
|
||||||
|
|
||||||
|
std::swap(w1->name, w2->name);
|
||||||
|
|
||||||
|
wires_[w1->name] = w1;
|
||||||
|
wires_[w2->name] = w2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RTLIL::Module::swap_names(RTLIL::Cell *c1, RTLIL::Cell *c2)
|
||||||
|
{
|
||||||
|
log_assert(cells_[c1->name] == c1);
|
||||||
|
log_assert(cells_[c2->name] == c2);
|
||||||
|
log_assert(refcount_cells_ == 0);
|
||||||
|
|
||||||
|
cells_.erase(c1->name);
|
||||||
|
cells_.erase(c2->name);
|
||||||
|
|
||||||
|
std::swap(c1->name, c2->name);
|
||||||
|
|
||||||
|
cells_[c1->name] = c1;
|
||||||
|
cells_[c2->name] = c2;
|
||||||
|
}
|
||||||
|
|
||||||
static bool fixup_ports_compare(const RTLIL::Wire *a, const RTLIL::Wire *b)
|
static bool fixup_ports_compare(const RTLIL::Wire *a, const RTLIL::Wire *b)
|
||||||
{
|
{
|
||||||
if (a->port_id && !b->port_id)
|
if (a->port_id && !b->port_id)
|
||||||
|
|
|
@ -590,6 +590,10 @@ public:
|
||||||
std::vector<RTLIL::Wire*> selected_wires() const;
|
std::vector<RTLIL::Wire*> selected_wires() const;
|
||||||
std::vector<RTLIL::Cell*> selected_cells() const;
|
std::vector<RTLIL::Cell*> selected_cells() const;
|
||||||
|
|
||||||
|
template<typename T> bool selected(T *member) const {
|
||||||
|
return design->selected_member(name, member->name);
|
||||||
|
}
|
||||||
|
|
||||||
RTLIL::Wire* wire(RTLIL::IdString id) { return wires_.count(id) ? wires_.at(id) : nullptr; }
|
RTLIL::Wire* wire(RTLIL::IdString id) { return wires_.count(id) ? wires_.at(id) : nullptr; }
|
||||||
RTLIL::Cell* cell(RTLIL::IdString id) { return cells_.count(id) ? cells_.at(id) : nullptr; }
|
RTLIL::Cell* cell(RTLIL::IdString id) { return cells_.count(id) ? cells_.at(id) : nullptr; }
|
||||||
|
|
||||||
|
@ -604,6 +608,9 @@ public:
|
||||||
void rename(RTLIL::Cell *cell, RTLIL::IdString new_name);
|
void rename(RTLIL::Cell *cell, RTLIL::IdString new_name);
|
||||||
void rename(RTLIL::IdString old_name, RTLIL::IdString new_name);
|
void rename(RTLIL::IdString old_name, RTLIL::IdString new_name);
|
||||||
|
|
||||||
|
void swap_names(RTLIL::Wire *w1, RTLIL::Wire *w2);
|
||||||
|
void swap_names(RTLIL::Cell *c1, RTLIL::Cell *c2);
|
||||||
|
|
||||||
RTLIL::Wire *addWire(RTLIL::IdString name, int width = 1);
|
RTLIL::Wire *addWire(RTLIL::IdString name, int width = 1);
|
||||||
RTLIL::Wire *addWire(RTLIL::IdString name, const RTLIL::Wire *other);
|
RTLIL::Wire *addWire(RTLIL::IdString name, const RTLIL::Wire *other);
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,6 @@
|
||||||
#include "kernel/sigtools.h"
|
#include "kernel/sigtools.h"
|
||||||
#include "kernel/modtools.h"
|
#include "kernel/modtools.h"
|
||||||
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
using namespace RTLIL;
|
using namespace RTLIL;
|
||||||
|
|
||||||
|
@ -243,6 +241,14 @@ struct WreduceWorker
|
||||||
return did_something;
|
return did_something;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int count_nontrivial_wire_attrs(RTLIL::Wire *w)
|
||||||
|
{
|
||||||
|
int count = w->attributes.size();
|
||||||
|
count -= w->attributes.count("\\src");
|
||||||
|
count -= w->attributes.count("\\unused_bits");
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
void run()
|
void run()
|
||||||
{
|
{
|
||||||
for (auto c : module->selected_cells())
|
for (auto c : module->selected_cells())
|
||||||
|
@ -257,7 +263,32 @@ struct WreduceWorker
|
||||||
work_queue_cells.clear();
|
work_queue_cells.clear();
|
||||||
for (auto bit : work_queue_bits)
|
for (auto bit : work_queue_bits)
|
||||||
for (auto port : mi.query_ports(bit))
|
for (auto port : mi.query_ports(bit))
|
||||||
work_queue_cells.insert(port.cell);
|
if (module->selected(port.cell))
|
||||||
|
work_queue_cells.insert(port.cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = SIZE(w)-1; i >= 0; i--) {
|
||||||
|
SigBit bit(w, i);
|
||||||
|
auto info = mi.query(bit);
|
||||||
|
if (info && (info->is_input || info->is_output || SIZE(info->ports) > 0))
|
||||||
|
break;
|
||||||
|
unused_top_bits++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 < unused_top_bits && unused_top_bits < SIZE(w)) {
|
||||||
|
log("Removed top %d bits (of %d) from wire %s.%s.\n", unused_top_bits, SIZE(w), log_id(module), log_id(w));
|
||||||
|
Wire *nw = module->addWire(NEW_ID, w);
|
||||||
|
nw->width = SIZE(w) - unused_top_bits;
|
||||||
|
module->connect(nw, SigSpec(w).extract(0, SIZE(nw)));
|
||||||
|
module->swap_names(w, nw);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -270,7 +301,12 @@ struct WreducePass : public Pass {
|
||||||
log("\n");
|
log("\n");
|
||||||
log(" wreduce [options] [selection]\n");
|
log(" wreduce [options] [selection]\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
log("This command reduces the word size of operations.\n");
|
log("This command reduces the word size of operations. For example it will replace\n");
|
||||||
|
log("the 32 bit adders in the following code with adders of more appropriate widths:\n");
|
||||||
|
log("\n");
|
||||||
|
log(" module test(input [3:0] a, b, c, output [7:0] y);\n");
|
||||||
|
log(" assign y = a + b + c + 1;\n");
|
||||||
|
log(" endmodule\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
}
|
}
|
||||||
virtual void execute(std::vector<std::string> args, Design *design)
|
virtual void execute(std::vector<std::string> args, Design *design)
|
||||||
|
|
Loading…
Reference in a new issue