diff options
author | Marcelina Kościelnicka <mwk@0x04.net> | 2021-08-12 23:06:51 +0200 |
---|---|---|
committer | Marcelina Kościelnicka <mwk@0x04.net> | 2021-08-13 01:17:55 +0200 |
commit | d0d9aca2c301e0d71a6828bf0cf7b8673973ecb4 (patch) | |
tree | 86f1d34062b4af26c653f2a94fe875907be3af1a /passes | |
parent | bfcd08a323044e1856ca971ba942bd36ee979f8e (diff) | |
download | yosys-d0d9aca2c301e0d71a6828bf0cf7b8673973ecb4.tar.gz yosys-d0d9aca2c301e0d71a6828bf0cf7b8673973ecb4.tar.bz2 yosys-d0d9aca2c301e0d71a6828bf0cf7b8673973ecb4.zip |
memory_share: Pass addresses through sigmap_xmux everywhere.
This fixes wide port recognition in some cases.
Diffstat (limited to 'passes')
-rw-r--r-- | passes/memory/memory_share.cc | 45 |
1 files changed, 25 insertions, 20 deletions
diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index 8499b46d8..1951b5400 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -112,25 +112,27 @@ struct MemoryShareWorker // merged by widening the narrow one. Check if the conditions // hold for that. 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; - if (GetSize(port2.addr) <= wide_log2) + if (GetSize(addr2) <= wide_log2) continue; - if (!port1.addr.extract(0, wide_log2).is_fully_const()) + if (!addr1.extract(0, wide_log2).is_fully_const()) continue; - if (!port2.addr.extract(0, wide_log2).is_fully_const()) + if (!addr2.extract(0, wide_log2).is_fully_const()) 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 // ports by one more bit to merge them. if (!flag_widen) continue; 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; - if (!port1.addr.extract(0, wide_log2).is_fully_const()) + if (!addr1.extract(0, wide_log2).is_fully_const()) continue; - if (!port2.addr.extract(0, wide_log2).is_fully_const()) + if (!addr2.extract(0, wide_log2).is_fully_const()) continue; } // Combine init/reset values. @@ -150,12 +152,13 @@ struct MemoryShareWorker // At this point we are committed to the merge. { 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.widen_prep(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(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++) port1.addr[k] = State::S0; port1.init_value = init_value; @@ -211,31 +214,33 @@ struct MemoryShareWorker // merged by widening the narrow one. Check if the conditions // hold for that. 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; - if (GetSize(port2.addr) <= wide_log2) + if (GetSize(addr2) <= wide_log2) continue; - if (!port1.addr.extract(0, wide_log2).is_fully_const()) + if (!addr1.extract(0, wide_log2).is_fully_const()) continue; - if (!port2.addr.extract(0, wide_log2).is_fully_const()) + if (!addr2.extract(0, wide_log2).is_fully_const()) 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 // ports by one more bit to merge them. if (!flag_widen) continue; 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; - if (!port1.addr.extract(0, wide_log2).is_fully_const()) + if (!addr1.extract(0, wide_log2).is_fully_const()) continue; - if (!port2.addr.extract(0, wide_log2).is_fully_const()) + if (!addr2.extract(0, wide_log2).is_fully_const()) 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); - port1.addr = sigmap_xmux(port1.addr); - port2.addr = sigmap_xmux(port2.addr); mem.widen_wr_port(i, wide_log2); mem.widen_wr_port(j, wide_log2); int pos = 0; |