mirror of
https://github.com/YosysHQ/yosys
synced 2025-09-08 02:31:26 +00:00
refactor
This commit is contained in:
parent
741e088e3a
commit
436d698525
3 changed files with 58 additions and 52 deletions
|
@ -4038,6 +4038,34 @@ void RTLIL::Cell::unsetPort(const RTLIL::IdString& portname)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct RTLIL::Detail {
|
||||||
|
static void bufNormalizeConflict(Module* module, CellPort port, Wire* wire)
|
||||||
|
{
|
||||||
|
auto [cell, portname] = port;
|
||||||
|
log_error("Conflict between %s.%s and %s.%s driving %s in module %s\n",
|
||||||
|
log_id(cell), log_id(portname),
|
||||||
|
log_id(wire->driverCell_), log_id(wire->driverPort_),
|
||||||
|
log_id(wire), log_id(module));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void drive(Wire* wire, CellPort port)
|
||||||
|
{
|
||||||
|
auto [cell, portname] = port;
|
||||||
|
if (wire->driverCell_) {
|
||||||
|
PortDir port_dir = cell->port_dir(portname);
|
||||||
|
if (port_dir != PD_OUTPUT) {
|
||||||
|
return;
|
||||||
|
} else if (wire->driverCell_->port_dir(wire->driverPort_) != PD_OUTPUT) {
|
||||||
|
// port_dir == PD_OUTPUT
|
||||||
|
} else {
|
||||||
|
Detail::bufNormalizeConflict(wire->module, {cell, portname}, wire);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wire->driverCell_ = cell;
|
||||||
|
wire->driverPort_ = portname;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void RTLIL::Design::bufNormalize(bool enable)
|
void RTLIL::Design::bufNormalize(bool enable)
|
||||||
{
|
{
|
||||||
if (!enable)
|
if (!enable)
|
||||||
|
@ -4062,30 +4090,19 @@ void RTLIL::Design::bufNormalize(bool enable)
|
||||||
for (auto module : modules())
|
for (auto module : modules())
|
||||||
{
|
{
|
||||||
for (auto cell : module->cells())
|
for (auto cell : module->cells())
|
||||||
for (auto &conn : cell->connections()) {
|
for (auto [portname, sig] : cell->connections()) {
|
||||||
|
|
||||||
PortDir port_dir = cell->port_dir(conn.first);
|
PortDir port_dir = cell->port_dir(portname);
|
||||||
if (port_dir == PD_INPUT || GetSize(conn.second) == 0)
|
if (port_dir == PD_INPUT || GetSize(sig) == 0)
|
||||||
continue;
|
continue;
|
||||||
if (conn.second.is_wire()) {
|
if (sig.is_wire()) {
|
||||||
Wire *wire = conn.second.as_wire();
|
Detail::drive(sig.as_wire(), {cell, portname});
|
||||||
if (wire->driverCell_ != nullptr) {
|
|
||||||
if (port_dir != PD_OUTPUT) {
|
|
||||||
continue;
|
continue;
|
||||||
} else if (wire->driverCell_->port_dir(wire->driverPort_) != PD_OUTPUT) {
|
|
||||||
// port_dir == PD_OUTPUT
|
|
||||||
} else {
|
} else {
|
||||||
log_error("Conflict between %s.%s and %s.%s driving %s in module %s\n",
|
// SigSpec has chunks
|
||||||
log_id(cell), log_id(conn.first),
|
// Defer normalization to Module::bufNormalize
|
||||||
log_id(wire->driverCell_), log_id(wire->driverPort_),
|
CellPort port({cell, portname});
|
||||||
log_id(wire), log_id(module));
|
module->bufNormQueue.insert(port);
|
||||||
}
|
|
||||||
}
|
|
||||||
wire->driverCell_ = cell;
|
|
||||||
wire->driverPort_ = conn.first;
|
|
||||||
} else {
|
|
||||||
pair<RTLIL::Cell*, RTLIL::IdString> key(cell, conn.first);
|
|
||||||
module->bufNormQueue.insert(key);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4104,36 +4121,20 @@ void RTLIL::Module::bufNormalize()
|
||||||
|
|
||||||
while (GetSize(bufNormQueue) || !connections_.empty())
|
while (GetSize(bufNormQueue) || !connections_.empty())
|
||||||
{
|
{
|
||||||
pool<pair<RTLIL::Cell*, RTLIL::IdString>> queue;
|
pool<CellPort> queue;
|
||||||
bufNormQueue.swap(queue);
|
bufNormQueue.swap(queue);
|
||||||
|
|
||||||
SigMap sigmap(this);
|
SigMap sigmap(this);
|
||||||
new_connections({});
|
new_connections({});
|
||||||
|
|
||||||
for (auto &key : queue)
|
for (const auto& [cell, portname] : queue)
|
||||||
{
|
{
|
||||||
Cell *cell = key.first;
|
|
||||||
const IdString &portname = key.second;
|
|
||||||
const SigSpec &sig = cell->getPort(portname);
|
const SigSpec &sig = cell->getPort(portname);
|
||||||
if (GetSize(sig) == 0) continue;
|
if (GetSize(sig) == 0) continue;
|
||||||
|
|
||||||
if (sig.is_wire()) {
|
if (sig.is_wire()) {
|
||||||
Wire *wire = sig.as_wire();
|
log_error("unreachable");
|
||||||
if (wire->driverCell_) {
|
Detail::drive(sig.as_wire(), {cell, portname});
|
||||||
PortDir port_dir = cell->port_dir(portname);
|
|
||||||
if (port_dir != PD_OUTPUT) {
|
|
||||||
continue;
|
|
||||||
} else if (wire->driverCell_->port_dir(wire->driverPort_) != PD_OUTPUT) {
|
|
||||||
// port_dir == PD_OUTPUT
|
|
||||||
} else {
|
|
||||||
log_error("Conflict between %s.%s and %s.%s driving %s in module %s\n",
|
|
||||||
log_id(cell), log_id(portname),
|
|
||||||
log_id(wire->driverCell_), log_id(wire->driverPort_),
|
|
||||||
log_id(wire), log_id(this));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
wire->driverCell_ = cell;
|
|
||||||
wire->driverPort_ = portname;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4244,7 +4245,7 @@ void RTLIL::Cell::setPort(const RTLIL::IdString& portname, RTLIL::SigSpec signal
|
||||||
|
|
||||||
while (module->design && module->design->flagBufferedNormalized && (pd = port_dir(portname)) != PD_INPUT)
|
while (module->design && module->design->flagBufferedNormalized && (pd = port_dir(portname)) != PD_INPUT)
|
||||||
{
|
{
|
||||||
pair<RTLIL::Cell*, RTLIL::IdString> key(this, portname);
|
CellPort key(this, portname);
|
||||||
|
|
||||||
if (conn_it->second.is_wire()) {
|
if (conn_it->second.is_wire()) {
|
||||||
Wire *w = conn_it->second.as_wire();
|
Wire *w = conn_it->second.as_wire();
|
||||||
|
@ -4267,7 +4268,7 @@ void RTLIL::Cell::setPort(const RTLIL::IdString& portname, RTLIL::SigSpec signal
|
||||||
Wire *w = signal.as_wire();
|
Wire *w = signal.as_wire();
|
||||||
if (w->driverCell_ != nullptr) {
|
if (w->driverCell_ != nullptr) {
|
||||||
if (pd == PD_OUTPUT) {
|
if (pd == PD_OUTPUT) {
|
||||||
pair<RTLIL::Cell*, RTLIL::IdString> other_key(w->driverCell_, w->driverPort_);
|
CellPort other_key(w->driverCell_, w->driverPort_);
|
||||||
module->bufNormQueue.insert(other_key);
|
module->bufNormQueue.insert(other_key);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -90,6 +90,7 @@ namespace RTLIL
|
||||||
PD_INOUT = 3
|
PD_INOUT = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Detail;
|
||||||
struct Const;
|
struct Const;
|
||||||
struct AttrObject;
|
struct AttrObject;
|
||||||
struct NamedObject;
|
struct NamedObject;
|
||||||
|
@ -1494,6 +1495,8 @@ struct RTLIL::Design
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using CellPort = std::pair<Cell*, IdString>;
|
||||||
|
|
||||||
struct RTLIL::Module : public RTLIL::NamedObject
|
struct RTLIL::Module : public RTLIL::NamedObject
|
||||||
{
|
{
|
||||||
Hasher::hash_t hashidx_;
|
Hasher::hash_t hashidx_;
|
||||||
|
@ -1547,7 +1550,7 @@ public:
|
||||||
std::vector<RTLIL::IdString> ports;
|
std::vector<RTLIL::IdString> ports;
|
||||||
void fixup_ports();
|
void fixup_ports();
|
||||||
|
|
||||||
pool<pair<RTLIL::Cell*, RTLIL::IdString>> bufNormQueue;
|
pool<CellPort> bufNormQueue;
|
||||||
void bufNormalize();
|
void bufNormalize();
|
||||||
|
|
||||||
template<typename T> void rewrite_sigspecs(T &functor);
|
template<typename T> void rewrite_sigspecs(T &functor);
|
||||||
|
@ -1870,6 +1873,7 @@ protected:
|
||||||
friend void RTLIL_BACKEND::dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire);
|
friend void RTLIL_BACKEND::dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire);
|
||||||
RTLIL::Cell *driverCell_ = nullptr;
|
RTLIL::Cell *driverCell_ = nullptr;
|
||||||
RTLIL::IdString driverPort_;
|
RTLIL::IdString driverPort_;
|
||||||
|
friend struct Detail;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// do not simply copy wires
|
// do not simply copy wires
|
||||||
|
@ -1883,6 +1887,7 @@ public:
|
||||||
bool driverKnown() const { return driverCell_ != nullptr; }
|
bool driverKnown() const { return driverCell_ != nullptr; }
|
||||||
RTLIL::Cell *driverCell() const { log_assert(driverCell_); return driverCell_; };
|
RTLIL::Cell *driverCell() const { log_assert(driverCell_); return driverCell_; };
|
||||||
RTLIL::IdString driverPort() const { log_assert(driverCell_); return driverPort_; };
|
RTLIL::IdString driverPort() const { log_assert(driverCell_); return driverPort_; };
|
||||||
|
void drive(Cell* cell);
|
||||||
|
|
||||||
int from_hdl_index(int hdl_index) {
|
int from_hdl_index(int hdl_index) {
|
||||||
int zero_index = hdl_index - start_offset;
|
int zero_index = hdl_index - start_offset;
|
||||||
|
|
|
@ -29,8 +29,8 @@ PRIVATE_NAMESPACE_BEGIN
|
||||||
|
|
||||||
static RTLIL::Module *module;
|
static RTLIL::Module *module;
|
||||||
static SigMap assign_map;
|
static SigMap assign_map;
|
||||||
typedef std::pair<RTLIL::Cell*, RTLIL::IdString> sig2driver_entry_t;
|
typedef std::pair<RTLIL::Cell*, RTLIL::IdString> CellPort;
|
||||||
static SigSet<sig2driver_entry_t> sig2driver, sig2user;
|
static SigSet<CellPort> sig2driver, sig2user;
|
||||||
static std::set<RTLIL::Cell*> muxtree_cells;
|
static std::set<RTLIL::Cell*> muxtree_cells;
|
||||||
static SigPool sig_at_port;
|
static SigPool sig_at_port;
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ ret_false:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<sig2driver_entry_t> cellport_list;
|
std::set<CellPort> cellport_list;
|
||||||
sig2driver.find(sig, cellport_list);
|
sig2driver.find(sig, cellport_list);
|
||||||
for (auto &cellport : cellport_list)
|
for (auto &cellport : cellport_list)
|
||||||
{
|
{
|
||||||
|
@ -93,7 +93,7 @@ static bool check_state_users(RTLIL::SigSpec sig)
|
||||||
if (sig_at_port.check_any(assign_map(sig)))
|
if (sig_at_port.check_any(assign_map(sig)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::set<sig2driver_entry_t> cellport_list;
|
std::set<CellPort> cellport_list;
|
||||||
sig2user.find(sig, cellport_list);
|
sig2user.find(sig, cellport_list);
|
||||||
for (auto &cellport : cellport_list) {
|
for (auto &cellport : cellport_list) {
|
||||||
RTLIL::Cell *cell = cellport.first;
|
RTLIL::Cell *cell = cellport.first;
|
||||||
|
@ -138,7 +138,7 @@ static void detect_fsm(RTLIL::Wire *wire, bool ignore_self_reset=false)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<sig2driver_entry_t> cellport_list;
|
std::set<CellPort> cellport_list;
|
||||||
sig2driver.find(RTLIL::SigSpec(wire), cellport_list);
|
sig2driver.find(RTLIL::SigSpec(wire), cellport_list);
|
||||||
|
|
||||||
for (auto &cellport : cellport_list)
|
for (auto &cellport : cellport_list)
|
||||||
|
@ -163,7 +163,7 @@ static void detect_fsm(RTLIL::Wire *wire, bool ignore_self_reset=false)
|
||||||
|
|
||||||
ConstEval ce(wire->module);
|
ConstEval ce(wire->module);
|
||||||
|
|
||||||
std::set<sig2driver_entry_t> cellport_list;
|
std::set<CellPort> cellport_list;
|
||||||
sig2user.find(sig_q, cellport_list);
|
sig2user.find(sig_q, cellport_list);
|
||||||
|
|
||||||
auto sig_q_bits = sig_q.to_sigbit_pool();
|
auto sig_q_bits = sig_q.to_sigbit_pool();
|
||||||
|
@ -322,12 +322,12 @@ struct FsmDetectPass : public Pass {
|
||||||
if (ct.cell_output(cell->type, conn_it.first) || !ct.cell_known(cell->type)) {
|
if (ct.cell_output(cell->type, conn_it.first) || !ct.cell_known(cell->type)) {
|
||||||
RTLIL::SigSpec sig = conn_it.second;
|
RTLIL::SigSpec sig = conn_it.second;
|
||||||
assign_map.apply(sig);
|
assign_map.apply(sig);
|
||||||
sig2driver.insert(sig, sig2driver_entry_t(cell, conn_it.first));
|
sig2driver.insert(sig, CellPort(cell, conn_it.first));
|
||||||
}
|
}
|
||||||
if (!ct.cell_known(cell->type) || ct.cell_input(cell->type, conn_it.first)) {
|
if (!ct.cell_known(cell->type) || ct.cell_input(cell->type, conn_it.first)) {
|
||||||
RTLIL::SigSpec sig = conn_it.second;
|
RTLIL::SigSpec sig = conn_it.second;
|
||||||
assign_map.apply(sig);
|
assign_map.apply(sig);
|
||||||
sig2user.insert(sig, sig2driver_entry_t(cell, conn_it.first));
|
sig2user.insert(sig, CellPort(cell, conn_it.first));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue