aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcelina Kościelnicka <mwk@0x04.net>2021-05-27 23:43:25 +0200
committerMarcelina Kościelnicka <mwk@0x04.net>2021-05-28 00:40:56 +0200
commitcbf6b719fe85ce8544f9bb0796711f3f45638862 (patch)
treee5123705ba397f310a10c133d02fd4360c42800d
parent055ba748bcf8c77bff15bda0de49c0b4b3722bba (diff)
downloadyosys-cbf6b719fe85ce8544f9bb0796711f3f45638862.tar.gz
yosys-cbf6b719fe85ce8544f9bb0796711f3f45638862.tar.bz2
yosys-cbf6b719fe85ce8544f9bb0796711f3f45638862.zip
Make a few passes auto-call Mem::narrow instead of rejecting wide ports.
This essentially adds wide port support for free in passes that don't have a usefully better way of handling wide ports than just breaking them up to narrow ports, avoiding "please run memory_narrow" annoyance.
-rw-r--r--backends/btor/btor.cc12
-rw-r--r--backends/firrtl/firrtl.cc6
-rw-r--r--backends/smt2/smt2.cc7
-rw-r--r--kernel/mem.cc3
-rw-r--r--passes/memory/memory_bram.cc15
5 files changed, 10 insertions, 33 deletions
diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc
index 999836882..a7e32bc5c 100644
--- a/backends/btor/btor.cc
+++ b/backends/btor/btor.cc
@@ -732,14 +732,6 @@ struct BtorWorker
if (port.clk_enable)
log_error("Memory %s.%s has sync read ports. Please use memory_nordff to convert them first.\n",
log_id(module), log_id(mem->memid));
- if (port.wide_log2)
- log_error("Memory %s.%s has wide read ports. Please use memory_narrow to convert them first.\n",
- log_id(module), log_id(mem->memid));
- }
- for (auto &port : mem->wr_ports) {
- if (port.wide_log2)
- log_error("Memory %s.%s has wide write ports. Please use memory_narrow to convert them first.\n",
- log_id(module), log_id(mem->memid));
}
int data_sid = get_bv_sid(mem->width);
@@ -1089,8 +1081,10 @@ struct BtorWorker
memories = Mem::get_all_memories(module);
dict<IdString, Mem*> mem_dict;
- for (auto &mem : memories)
+ for (auto &mem : memories) {
+ mem.narrow();
mem_dict[mem.memid] = &mem;
+ }
for (auto cell : module->cells())
if (cell->is_mem_cell())
mem_cells[cell] = mem_dict[cell->parameters.at(ID::MEMID).decode_string()];
diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc
index dee24d0e2..86b1bbdf6 100644
--- a/backends/firrtl/firrtl.cc
+++ b/backends/firrtl/firrtl.cc
@@ -542,6 +542,8 @@ struct FirrtlWorker
vector<string> port_decls, wire_decls, mem_exprs, cell_exprs, wire_exprs;
std::vector<Mem> memories = Mem::get_all_memories(module);
+ for (auto &mem : memories)
+ mem.narrow();
for (auto wire : module->wires())
{
@@ -993,8 +995,6 @@ struct FirrtlWorker
if (port.clk_enable)
log_error("Clocked read port %d on memory %s.%s.\n", i, log_id(module), log_id(mem.memid));
- if (port.wide_log2 != 0)
- log_error("Wide read port %d on memory %s.%s. Use memory_narrow to convert them first.\n", i, log_id(module), log_id(mem.memid));
std::ostringstream rpe;
@@ -1016,8 +1016,6 @@ struct FirrtlWorker
if (!port.clk_enable)
log_error("Unclocked write port %d on memory %s.%s.\n", i, log_id(module), log_id(mem.memid));
- if (port.wide_log2 != 0)
- log_error("Wide write port %d on memory %s.%s. Use memory_narrow to convert them first.\n", i, log_id(module), log_id(mem.memid));
if (!port.clk_polarity)
log_error("Negedge write port %d on memory %s.%s.\n", i, log_id(module), log_id(mem.memid));
for (int i = 1; i < GetSize(port.en); i++)
diff --git a/backends/smt2/smt2.cc b/backends/smt2/smt2.cc
index 4dee0d4fb..7f6779c7d 100644
--- a/backends/smt2/smt2.cc
+++ b/backends/smt2/smt2.cc
@@ -124,6 +124,7 @@ struct Smt2Worker
memories = Mem::get_all_memories(module);
for (auto &mem : memories)
{
+ mem.narrow();
mem_dict[mem.memid] = &mem;
for (auto &port : mem.wr_ports)
{
@@ -715,12 +716,6 @@ struct Smt2Worker
has_sync_wr = true;
else
has_async_wr = true;
- if (port.wide_log2)
- log_error("Memory %s.%s has wide write ports. This is not supported by \"write_smt2\". Use memory_narrow to convert them first.\n", log_id(cell), log_id(module));
- }
- for (auto &port : mem->rd_ports) {
- if (port.wide_log2)
- log_error("Memory %s.%s has wide read ports. This is not supported by \"write_smt2\". Use memory_narrow to convert them first.\n", log_id(cell), log_id(module));
}
if (has_async_wr && has_sync_wr)
log_error("Memory %s.%s has mixed clocked/nonclocked write ports. This is not supported by \"write_smt2\".\n", log_id(cell), log_id(module));
diff --git a/kernel/mem.cc b/kernel/mem.cc
index 021e1991e..848dc9f3a 100644
--- a/kernel/mem.cc
+++ b/kernel/mem.cc
@@ -691,6 +691,9 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) {
}
void Mem::narrow() {
+ // NOTE: several passes depend on this function not modifying
+ // the design at all until (and unless) emit() is called.
+ // Be careful to preserve this.
std::vector<MemRd> new_rd_ports;
std::vector<MemWr> new_wr_ports;
std::vector<std::pair<int, int>> new_rd_map;
diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc
index b70864766..c1476669d 100644
--- a/passes/memory/memory_bram.cc
+++ b/passes/memory/memory_bram.cc
@@ -1052,6 +1052,7 @@ grow_read_ports:;
void handle_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals)
{
log("Processing %s.%s:\n", log_id(mem.module), log_id(mem.memid));
+ mem.narrow();
bool cell_init = !mem.inits.empty();
@@ -1069,20 +1070,6 @@ void handle_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals)
log(" %s=%d", it.first.c_str(), it.second);
log("\n");
- for (auto &port : mem.rd_ports) {
- if (port.wide_log2) {
- log("Wide read ports are not supported, skipping.\n");
- return;
- }
- }
-
- for (auto &port : mem.wr_ports) {
- if (port.wide_log2) {
- log("Wide write ports are not supported, skipping.\n");
- return;
- }
- }
-
// This pass cannot deal with write port priority — we need to emulate it,
// if present. Since priority emulation will change the enable signals,
// which in turn may change enable grouping and mapping eligibility in