mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-24 01:25:33 +00:00
kernel/mem: Introduce transparency masks.
This commit is contained in:
parent
681a1c07e5
commit
e6f3d1c225
8 changed files with 407 additions and 117 deletions
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue