mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-23 17:15:33 +00:00
Sign extend port connections where necessary
- Signed cell outputs are sign extended when bound to larger wires - Signed connections are sign extended when bound to larger cell inputs - Sign extension is performed in hierarchy and flatten phases - genrtlil indirects signed constants through signed wires - Other phases producing RTLIL may need to be updated to preserve signedness information - Resolves #1418 - Resolves #2265
This commit is contained in:
parent
40e35993af
commit
0d8e5d965f
5 changed files with 132 additions and 5 deletions
|
@ -1233,14 +1233,18 @@ struct HierarchyPass : public Pass {
|
|||
{
|
||||
int n = GetSize(conn.second) - GetSize(w);
|
||||
if (!w->port_input && w->port_output)
|
||||
module->connect(sig.extract(GetSize(w), n), Const(0, n));
|
||||
{
|
||||
RTLIL::SigSpec out = sig.extract(0, GetSize(w));
|
||||
out.extend_u0(GetSize(sig), w->is_signed);
|
||||
module->connect(sig.extract(GetSize(w), n), out.extract(GetSize(w), n));
|
||||
}
|
||||
sig.remove(GetSize(w), n);
|
||||
}
|
||||
else
|
||||
{
|
||||
int n = GetSize(w) - GetSize(conn.second);
|
||||
if (w->port_input && !w->port_output)
|
||||
sig.append(Const(0, n));
|
||||
sig.extend_u0(GetSize(w), sig.is_wire() && sig.as_wire()->is_signed);
|
||||
else
|
||||
sig.append(module->addWire(NEW_ID, n));
|
||||
}
|
||||
|
|
|
@ -180,12 +180,15 @@ struct FlattenWorker
|
|||
|
||||
RTLIL::Wire *tpl_wire = tpl->wire(port_name);
|
||||
RTLIL::SigSig new_conn;
|
||||
bool is_signed = false;
|
||||
if (tpl_wire->port_output && !tpl_wire->port_input) {
|
||||
new_conn.first = port_it.second;
|
||||
new_conn.second = tpl_wire;
|
||||
is_signed = tpl_wire->is_signed;
|
||||
} else if (!tpl_wire->port_output && tpl_wire->port_input) {
|
||||
new_conn.first = tpl_wire;
|
||||
new_conn.second = port_it.second;
|
||||
is_signed = new_conn.second.is_wire() && new_conn.second.as_wire()->is_signed;
|
||||
} else {
|
||||
SigSpec sig_tpl = tpl_wire, sig_mod = port_it.second;
|
||||
for (int i = 0; i < GetSize(sig_tpl) && i < GetSize(sig_mod); i++) {
|
||||
|
@ -204,7 +207,7 @@ struct FlattenWorker
|
|||
if (new_conn.second.size() > new_conn.first.size())
|
||||
new_conn.second.remove(new_conn.first.size(), new_conn.second.size() - new_conn.first.size());
|
||||
if (new_conn.second.size() < new_conn.first.size())
|
||||
new_conn.second.append(RTLIL::SigSpec(RTLIL::State::S0, new_conn.first.size() - new_conn.second.size()));
|
||||
new_conn.second.extend_u0(new_conn.first.size(), is_signed);
|
||||
log_assert(new_conn.first.size() == new_conn.second.size());
|
||||
|
||||
if (sigmap(new_conn.first).has_const())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue