diff options
author | Marcelina KoĆcielnicka <mwk@0x04.net> | 2021-07-31 23:21:37 +0200 |
---|---|---|
committer | Marcelina KoĆcielnicka <mwk@0x04.net> | 2021-08-11 00:04:16 +0200 |
commit | e6f3d1c225abecf736782f43af4f36526c63f4c5 (patch) | |
tree | 5753dd1d51863623bbcb4e1ecc716171f99a6db0 /backends | |
parent | 681a1c07e52dc82449501f4939e6312f593449bd (diff) | |
download | yosys-e6f3d1c225abecf736782f43af4f36526c63f4c5.tar.gz yosys-e6f3d1c225abecf736782f43af4f36526c63f4c5.tar.bz2 yosys-e6f3d1c225abecf736782f43af4f36526c63f4c5.zip |
kernel/mem: Introduce transparency masks.
Diffstat (limited to 'backends')
-rw-r--r-- | backends/cxxrtl/cxxrtl_backend.cc | 39 | ||||
-rw-r--r-- | backends/verilog/verilog_backend.cc | 18 |
2 files changed, 30 insertions, 27 deletions
diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 95ad6a86e..40e61e5af 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -542,19 +542,21 @@ struct FlowGraph { add_uses(node, port.arst); add_uses(node, port.srst); add_uses(node, port.addr); - if (port.transparent && port.clk_enable) { - // Our implementation of transparent read ports reads en, addr and data from every write port - // in the same domain. - for (auto &wrport : mem->wr_ports) { - if (wrport.clk_enable && wrport.clk == port.clk && wrport.clk_polarity == port.clk_polarity) { - add_uses(node, wrport.en); - add_uses(node, wrport.addr); - add_uses(node, wrport.data); - } + bool transparent = false; + for (int j = 0; j < GetSize(mem->wr_ports); j++) { + auto &wrport = mem->wr_ports[j]; + if (port.transparency_mask[j]) { + // Our implementation of transparent read ports reads en, addr and data from every write port + // the read port is transparent with. + add_uses(node, wrport.en); + add_uses(node, wrport.addr); + add_uses(node, wrport.data); + transparent = true; } - // Also we read the address twice in this case (prevent inlining). - add_uses(node, port.addr); } + // Also we read the read address twice in this case (prevent inlining). + if (transparent) + add_uses(node, port.addr); } if (!mem->wr_ports.empty()) { Node *node = new Node; @@ -1604,17 +1606,18 @@ struct CxxrtlWorker { std::string lhs_temp = fresh_temporary(); f << indent << "value<" << mem->width << "> " << lhs_temp << " = " << mangle(mem) << "[" << valid_index_temp << ".index];\n"; - if (port.transparent && port.clk_enable) { + bool transparent = false; + for (auto bit : port.transparency_mask) + if (bit) + transparent = true; + if (transparent) { std::string addr_temp = fresh_temporary(); f << indent << "const value<" << port.addr.size() << "> &" << addr_temp << " = "; dump_sigspec_rhs(port.addr); f << ";\n"; - for (auto &wrport : mem->wr_ports) { - if (!wrport.clk_enable) - continue; - if (wrport.clk != port.clk) - continue; - if (wrport.clk_polarity != port.clk_polarity) + for (int i = 0; i < GetSize(mem->wr_ports); i++) { + auto &wrport = mem->wr_ports[i]; + if (!port.transparency_mask[i]) continue; f << indent << "if (" << addr_temp << " == "; dump_sigspec_rhs(wrport.addr); diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 8f96c3a58..47b48a460 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -555,7 +555,10 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem) } // Decide how to represent the transparency; same idea as Mem::extract_rdff. - bool trans_use_addr = port.transparent; + bool trans_use_addr = true; + for (auto bit : port.transparency_mask) + if (!bit) + trans_use_addr = false; if (GetSize(mem.wr_ports) == 0) trans_use_addr = false; @@ -630,13 +633,7 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem) for (int i = 0; i < GetSize(mem.wr_ports); i++) { auto &wport = mem.wr_ports[i]; - if (!port.transparent) - continue; - if (!wport.clk_enable) - continue; - if (wport.clk != port.clk) - continue; - if (wport.clk_polarity != port.clk_polarity) + if (!port.transparency_mask[i] && !port.collision_x_mask[i]) continue; int min_wide_log2 = std::min(port.wide_log2, wport.wide_log2); int max_wide_log2 = std::max(port.wide_log2, wport.wide_log2); @@ -679,7 +676,10 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem) if (epos-pos != GetSize(port.data)) os2 << stringf("[%d:%d]", rsub * mem.width + epos-1, rsub * mem.width + pos); os2 << " <= "; - dump_sigspec(os2, wport.data.extract(wsub * mem.width + pos, epos-pos)); + if (port.transparency_mask[i]) + dump_sigspec(os2, wport.data.extract(wsub * mem.width + pos, epos-pos)); + else + dump_sigspec(os2, Const(State::Sx, epos - pos)); os2 << ";\n"; clk_to_lof_body[clk_domain_str].push_back(os2.str()); |