mirror of
https://github.com/YosysHQ/yosys
synced 2025-06-27 08:28:45 +00:00
memory_share: Pass addresses through sigmap_xmux everywhere.
This fixes wide port recognition in some cases.
This commit is contained in:
parent
bfcd08a323
commit
d0d9aca2c3
1 changed files with 25 additions and 20 deletions
|
@ -112,25 +112,27 @@ struct MemoryShareWorker
|
||||||
// merged by widening the narrow one. Check if the conditions
|
// merged by widening the narrow one. Check if the conditions
|
||||||
// hold for that.
|
// hold for that.
|
||||||
int wide_log2 = std::max(port1.wide_log2, port2.wide_log2);
|
int wide_log2 = std::max(port1.wide_log2, port2.wide_log2);
|
||||||
if (GetSize(port1.addr) <= wide_log2)
|
SigSpec addr1 = sigmap_xmux(port1.addr);
|
||||||
|
SigSpec addr2 = sigmap_xmux(port2.addr);
|
||||||
|
if (GetSize(addr1) <= wide_log2)
|
||||||
continue;
|
continue;
|
||||||
if (GetSize(port2.addr) <= wide_log2)
|
if (GetSize(addr2) <= wide_log2)
|
||||||
continue;
|
continue;
|
||||||
if (!port1.addr.extract(0, wide_log2).is_fully_const())
|
if (!addr1.extract(0, wide_log2).is_fully_const())
|
||||||
continue;
|
continue;
|
||||||
if (!port2.addr.extract(0, wide_log2).is_fully_const())
|
if (!addr2.extract(0, wide_log2).is_fully_const())
|
||||||
continue;
|
continue;
|
||||||
if (sigmap_xmux(port1.addr.extract_end(wide_log2)) != sigmap_xmux(port2.addr.extract_end(wide_log2))) {
|
if (addr1.extract_end(wide_log2) != addr2.extract_end(wide_log2)) {
|
||||||
// Incompatible addresses after widening. Last chance — widen both
|
// Incompatible addresses after widening. Last chance — widen both
|
||||||
// ports by one more bit to merge them.
|
// ports by one more bit to merge them.
|
||||||
if (!flag_widen)
|
if (!flag_widen)
|
||||||
continue;
|
continue;
|
||||||
wide_log2++;
|
wide_log2++;
|
||||||
if (sigmap_xmux(port1.addr.extract_end(wide_log2)) != sigmap_xmux(port2.addr.extract_end(wide_log2)))
|
if (addr1.extract_end(wide_log2) != addr2.extract_end(wide_log2))
|
||||||
continue;
|
continue;
|
||||||
if (!port1.addr.extract(0, wide_log2).is_fully_const())
|
if (!addr1.extract(0, wide_log2).is_fully_const())
|
||||||
continue;
|
continue;
|
||||||
if (!port2.addr.extract(0, wide_log2).is_fully_const())
|
if (!addr2.extract(0, wide_log2).is_fully_const())
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Combine init/reset values.
|
// Combine init/reset values.
|
||||||
|
@ -150,12 +152,13 @@ struct MemoryShareWorker
|
||||||
// At this point we are committed to the merge.
|
// At this point we are committed to the merge.
|
||||||
{
|
{
|
||||||
log(" Merging ports %d, %d (address %s).\n", i, j, log_signal(port1.addr));
|
log(" Merging ports %d, %d (address %s).\n", i, j, log_signal(port1.addr));
|
||||||
|
port1.addr = addr1;
|
||||||
|
port2.addr = addr2;
|
||||||
mem.prepare_rd_merge(i, j, &initvals);
|
mem.prepare_rd_merge(i, j, &initvals);
|
||||||
mem.widen_prep(wide_log2);
|
mem.widen_prep(wide_log2);
|
||||||
SigSpec new_data = module->addWire(NEW_ID, mem.width << wide_log2);
|
SigSpec new_data = module->addWire(NEW_ID, mem.width << wide_log2);
|
||||||
module->connect(port1.data, new_data.extract(sub1 * mem.width, mem.width << port1.wide_log2));
|
module->connect(port1.data, new_data.extract(sub1 * mem.width, mem.width << port1.wide_log2));
|
||||||
module->connect(port2.data, new_data.extract(sub2 * mem.width, mem.width << port2.wide_log2));
|
module->connect(port2.data, new_data.extract(sub2 * mem.width, mem.width << port2.wide_log2));
|
||||||
port1.addr = sigmap_xmux(port1.addr);
|
|
||||||
for (int k = 0; k < wide_log2; k++)
|
for (int k = 0; k < wide_log2; k++)
|
||||||
port1.addr[k] = State::S0;
|
port1.addr[k] = State::S0;
|
||||||
port1.init_value = init_value;
|
port1.init_value = init_value;
|
||||||
|
@ -211,31 +214,33 @@ struct MemoryShareWorker
|
||||||
// merged by widening the narrow one. Check if the conditions
|
// merged by widening the narrow one. Check if the conditions
|
||||||
// hold for that.
|
// hold for that.
|
||||||
int wide_log2 = std::max(port1.wide_log2, port2.wide_log2);
|
int wide_log2 = std::max(port1.wide_log2, port2.wide_log2);
|
||||||
if (GetSize(port1.addr) <= wide_log2)
|
SigSpec addr1 = sigmap_xmux(port1.addr);
|
||||||
|
SigSpec addr2 = sigmap_xmux(port2.addr);
|
||||||
|
if (GetSize(addr1) <= wide_log2)
|
||||||
continue;
|
continue;
|
||||||
if (GetSize(port2.addr) <= wide_log2)
|
if (GetSize(addr2) <= wide_log2)
|
||||||
continue;
|
continue;
|
||||||
if (!port1.addr.extract(0, wide_log2).is_fully_const())
|
if (!addr1.extract(0, wide_log2).is_fully_const())
|
||||||
continue;
|
continue;
|
||||||
if (!port2.addr.extract(0, wide_log2).is_fully_const())
|
if (!addr2.extract(0, wide_log2).is_fully_const())
|
||||||
continue;
|
continue;
|
||||||
if (sigmap_xmux(port1.addr.extract_end(wide_log2)) != sigmap_xmux(port2.addr.extract_end(wide_log2))) {
|
if (addr1.extract_end(wide_log2) != addr2.extract_end(wide_log2)) {
|
||||||
// Incompatible addresses after widening. Last chance — widen both
|
// Incompatible addresses after widening. Last chance — widen both
|
||||||
// ports by one more bit to merge them.
|
// ports by one more bit to merge them.
|
||||||
if (!flag_widen)
|
if (!flag_widen)
|
||||||
continue;
|
continue;
|
||||||
wide_log2++;
|
wide_log2++;
|
||||||
if (sigmap_xmux(port1.addr.extract_end(wide_log2)) != sigmap_xmux(port2.addr.extract_end(wide_log2)))
|
if (addr1.extract_end(wide_log2) != addr2.extract_end(wide_log2))
|
||||||
continue;
|
continue;
|
||||||
if (!port1.addr.extract(0, wide_log2).is_fully_const())
|
if (!addr1.extract(0, wide_log2).is_fully_const())
|
||||||
continue;
|
continue;
|
||||||
if (!port2.addr.extract(0, wide_log2).is_fully_const())
|
if (!addr2.extract(0, wide_log2).is_fully_const())
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
log(" Merging ports %d, %d (address %s).\n", i, j, log_signal(port1.addr));
|
log(" Merging ports %d, %d (address %s).\n", i, j, log_signal(addr1));
|
||||||
|
port1.addr = addr1;
|
||||||
|
port2.addr = addr2;
|
||||||
mem.prepare_wr_merge(i, j, &initvals);
|
mem.prepare_wr_merge(i, j, &initvals);
|
||||||
port1.addr = sigmap_xmux(port1.addr);
|
|
||||||
port2.addr = sigmap_xmux(port2.addr);
|
|
||||||
mem.widen_wr_port(i, wide_log2);
|
mem.widen_wr_port(i, wide_log2);
|
||||||
mem.widen_wr_port(j, wide_log2);
|
mem.widen_wr_port(j, wide_log2);
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue