aboutsummaryrefslogtreecommitdiffstats
path: root/backends
diff options
context:
space:
mode:
authorMarcelina Koƛcielnicka <mwk@0x04.net>2021-07-31 23:21:37 +0200
committerMarcelina Koƛcielnicka <mwk@0x04.net>2021-08-11 00:04:16 +0200
commite6f3d1c225abecf736782f43af4f36526c63f4c5 (patch)
tree5753dd1d51863623bbcb4e1ecc716171f99a6db0 /backends
parent681a1c07e52dc82449501f4939e6312f593449bd (diff)
downloadyosys-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.cc39
-rw-r--r--backends/verilog/verilog_backend.cc18
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());