From ca75829c332eec771c825f30d370c7b17903d7a4 Mon Sep 17 00:00:00 2001 From: Jakub Janeczko Date: Mon, 20 Jul 2026 03:09:00 +0200 Subject: [PATCH 1/5] new transparent memory verilog pattern --- backends/verilog/verilog_backend.cc | 446 ++++++++++++++++------------ 1 file changed, 255 insertions(+), 191 deletions(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 1db3eb298..e8ab4af4f 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -602,212 +602,276 @@ 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 = true; - for (auto bit : port.transparency_mask) - if (!bit) - trans_use_addr = false; + // Due to some synthesis tools being incompetent in detecting address colission pattern + // from verilog with strictly defined semantics and not infering bram (see github issue #5082), + // memory cannot use: + // 1. e.g Vivado assumes non-transparent port + // assign r_data = mem[latched r_addr]; + // 2. not recognised - synthesized to LUTRAM + // always @(...) begin + // if (rd_en) begin + // r_data <= mem[r_addr]; + // if (wr_en && r_addr == w_addr) r_data <= w_data; + // end + // end + // + // As such, we need to implement transparency manually, outside of the always block. - if (GetSize(mem.wr_ports) == 0) - trans_use_addr = false; + // for clocked read ports make something like: + // reg [..] temp_id; + // always @(posedge clk) + // if (rd_en) temp_id <= array_reg[r_addr]; + // assign r_data = temp_id; + std::string temp_id = next_auto_id(); + lof_reg_declarations.push_back( stringf("reg [%d:0] %s;\n", port.data.size() - 1, temp_id) ); - if (port.en != State::S1 || port.srst != State::S0 || port.arst != State::S0 || !port.init_value.is_fully_undef()) - trans_use_addr = false; + bool has_transparency = false; + int bypass_part_width = port.data.size() / port.en.size(); + for (int i = 0; i < GetSize(mem.wr_ports); i++) { + auto &wport = mem.wr_ports[i]; + if (!port.transparency_mask[i] && !port.collision_x_mask[i]) + continue; + has_transparency = true; + bypass_part_width = std::min(bypass_part_width, wport.data.size() / wport.en.size()); + } + int bypass_valid_width = port.data.size() / bypass_part_width; - if (!trans_use_addr) - { - // for clocked read ports make something like: - // reg [..] temp_id; - // always @(posedge clk) - // if (rd_en) temp_id <= array_reg[r_addr]; - // assign r_data = temp_id; - std::string temp_id = next_auto_id(); - lof_reg_declarations.push_back( stringf("reg [%d:0] %s;\n", port.data.size() - 1, temp_id) ); + std::string bypass_valid_id; + std::string bypass_valid_reset_str; + std::string bypass_data_id; + std::string bypass_data_reset_str; + if (has_transparency) { + bypass_valid_id = next_auto_id(); + lof_reg_declarations.push_back( stringf("reg [%d:0] %s;\n", bypass_valid_width - 1, bypass_valid_id) ); - bool has_indent = false; + std::ostringstream os; + os << stringf("%s <= ", bypass_valid_id); + dump_sigspec(os, Const(State::S0, bypass_valid_width)); + os << ";\n"; + bypass_valid_reset_str = os.str(); - if (port.arst != State::S0) { - std::ostringstream os; - os << stringf("%s <= ", temp_id); - dump_sigspec(os, port.arst_value); - os << ";\n"; - clk_to_arst_body[clk_domain_str].push_back(os.str()); - } + bypass_data_id = next_auto_id(); + lof_reg_declarations.push_back( stringf("reg [%d:0] %s;\n", port.data.size() - 1, bypass_data_id) ); - if (port.srst != State::S0 && !port.ce_over_srst) { - std::ostringstream os; - os << stringf("if ("); - dump_sigspec(os, port.srst); - os << stringf(")\n"); - clk_to_lof_body[clk_domain_str].push_back(os.str()); - std::ostringstream os2; - os2 << stringf("%s" "%s <= ", indent, temp_id); - dump_sigspec(os2, port.srst_value); - os2 << ";\n"; - clk_to_lof_body[clk_domain_str].push_back(os2.str()); - std::ostringstream os3; - if (port.en == State::S1) { - os3 << "else begin\n"; - } else { - os3 << "else if ("; - dump_sigspec(os3, port.en); - os3 << ") begin\n"; - } - clk_to_lof_body[clk_domain_str].push_back(os3.str()); - has_indent = true; - } else if (port.en != State::S1) { - std::ostringstream os; - os << stringf("if ("); - dump_sigspec(os, port.en); - os << stringf(") begin\n"); - clk_to_lof_body[clk_domain_str].push_back(os.str()); - has_indent = true; - } + std::ostringstream os2; + os2 << stringf("%s <= ", bypass_data_id); + dump_sigspec(os2, Const(State::Sx, port.data.size())); + os2 << ";\n"; + bypass_data_reset_str = os2.str(); + } - for (int sub = 0; sub < (1 << port.wide_log2); sub++) - { - SigSpec addr = port.sub_addr(sub); - std::ostringstream os; - if (has_indent) - os << indent; - os << temp_id; - if (port.wide_log2) - os << stringf("[%d:%d]", (sub + 1) * mem.width - 1, sub * mem.width); - os << stringf(" <= %s[", mem_id); - dump_sigspec(os, addr); - os << stringf("];\n"); - clk_to_lof_body[clk_domain_str].push_back(os.str()); - } + bool has_indent = false; - for (int i = 0; i < GetSize(mem.wr_ports); i++) { - auto &wport = mem.wr_ports[i]; - 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); - bool wide_write = wport.wide_log2 > port.wide_log2; - for (int sub = 0; sub < (1 << max_wide_log2); sub += (1 << min_wide_log2)) { - SigSpec raddr = port.addr; - SigSpec waddr = wport.addr; - if (wide_write) - waddr = wport.sub_addr(sub); - else - raddr = port.sub_addr(sub); - int pos = 0; - int ewidth = mem.width << min_wide_log2; - int wsub = wide_write ? sub : 0; - int rsub = wide_write ? 0 : sub; - while (pos < ewidth) { - int epos = pos; - while (epos < ewidth && wport.en[epos + wsub * mem.width] == wport.en[pos + wsub * mem.width]) - epos++; + if (port.arst != State::S0) { + std::ostringstream os; + os << stringf("%s <= ", temp_id); + dump_sigspec(os, port.arst_value); + os << ";\n"; + clk_to_arst_body[clk_domain_str].push_back(os.str()); - std::ostringstream os; - if (has_indent) - os << indent; - os << "if ("; - dump_sigspec(os, wport.en[pos + wsub * mem.width]); - if (raddr != waddr) { - os << " && "; - dump_sigspec(os, raddr); - os << " == "; - dump_sigspec(os, waddr); - } - os << ")\n"; - clk_to_lof_body[clk_domain_str].push_back(os.str()); - - std::ostringstream os2; - if (has_indent) - os2 << indent; - os2 << indent; - os2 << temp_id; - if (epos-pos != GetSize(port.data)) - os2 << stringf("[%d:%d]", rsub * mem.width + epos-1, rsub * mem.width + pos); - os2 << " <= "; - 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()); - - pos = epos; - } - } - } - - if (port.srst != State::S0 && port.ce_over_srst) - { - std::ostringstream os; - if (has_indent) - os << indent; - os << stringf("if ("); - dump_sigspec(os, port.srst); - os << stringf(")\n"); - clk_to_lof_body[clk_domain_str].push_back(os.str()); - std::ostringstream os2; - if (has_indent) - os2 << indent; - os2 << stringf("%s" "%s <= ", indent, temp_id); - dump_sigspec(os2, port.srst_value); - os2 << ";\n"; - clk_to_lof_body[clk_domain_str].push_back(os2.str()); - } - - if (has_indent) - clk_to_lof_body[clk_domain_str].push_back("end\n"); - - if (!port.init_value.is_fully_undef()) - { - std::ostringstream os; - dump_sigspec(os, port.init_value); - std::string line = stringf("initial %s = %s;\n", temp_id, os.str()); - clk_to_lof_body[""].push_back(line); - } - - { - std::ostringstream os; - dump_sigspec(os, port.data); - std::string line = stringf("assign %s = %s;\n", os.str(), temp_id); - clk_to_lof_body[""].push_back(line); + if (has_transparency) { + clk_to_arst_body[clk_domain_str].push_back(bypass_valid_reset_str); + clk_to_arst_body[clk_domain_str].push_back(bypass_data_reset_str); } } - else - { - // for rd-transparent read-ports make something like: - // reg [..] temp_id; - // always @(posedge clk) - // temp_id <= r_addr; - // assign r_data = array_reg[temp_id]; - std::string temp_id = next_auto_id(); - lof_reg_declarations.push_back( stringf("reg [%d:0] %s;\n", port.addr.size() - 1 - port.wide_log2, temp_id) ); - { - std::ostringstream os; - dump_sigspec(os, port.addr.extract_end(port.wide_log2)); - std::string line = stringf("%s <= %s;\n", temp_id, os.str()); - clk_to_lof_body[clk_domain_str].push_back(line); + + if (port.srst != State::S0 && !port.ce_over_srst) { + std::ostringstream os; + os << stringf("if ("); + dump_sigspec(os, port.srst); + os << stringf(") begin\n"); + clk_to_lof_body[clk_domain_str].push_back(os.str()); + + std::ostringstream os2; + os2 << stringf("%s" "%s <= ", indent, temp_id); + dump_sigspec(os2, port.srst_value); + os2 << ";\n"; + clk_to_lof_body[clk_domain_str].push_back(os2.str()); + + if (has_transparency) { + clk_to_lof_body[clk_domain_str].push_back(indent + bypass_valid_reset_str); + clk_to_lof_body[clk_domain_str].push_back(indent + bypass_data_reset_str); } - for (int sub = 0; sub < (1 << port.wide_log2); sub++) - { + std::ostringstream os3; + if (port.en == State::S1) { + os3 << "end else begin\n"; + } else { + os3 << "end else if ("; + dump_sigspec(os3, port.en); + os3 << ") begin\n"; + } + clk_to_lof_body[clk_domain_str].push_back(os3.str()); + has_indent = true; + } else if (port.en != State::S1) { + std::ostringstream os; + os << stringf("if ("); + dump_sigspec(os, port.en); + os << stringf(") begin\n"); + clk_to_lof_body[clk_domain_str].push_back(os.str()); + has_indent = true; + } + + for (int sub = 0; sub < (1 << port.wide_log2); sub++) + { + SigSpec addr = port.sub_addr(sub); + std::ostringstream os; + if (has_indent) + os << indent; + os << temp_id; + if (port.wide_log2) + os << stringf("[%d:%d]", (sub + 1) * mem.width - 1, sub * mem.width); + os << stringf(" <= %s[", mem_id); + dump_sigspec(os, addr); + os << stringf("];\n"); + clk_to_lof_body[clk_domain_str].push_back(os.str()); + } + + if (has_transparency) { + clk_to_lof_body[clk_domain_str].push_back((has_indent ? indent : "") + bypass_valid_reset_str); + clk_to_lof_body[clk_domain_str].push_back((has_indent ? indent : "") + bypass_data_reset_str); + } + + for (int i = 0; i < GetSize(mem.wr_ports); i++) { + auto &wport = mem.wr_ports[i]; + 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); + bool wide_write = wport.wide_log2 > port.wide_log2; + for (int sub = 0; sub < (1 << max_wide_log2); sub += (1 << min_wide_log2)) { + SigSpec raddr = port.addr; + SigSpec waddr = wport.addr; + if (wide_write) + waddr = wport.sub_addr(sub); + else + raddr = port.sub_addr(sub); + int pos = 0; + int ewidth = mem.width << min_wide_log2; + int wsub = wide_write ? sub : 0; + int rsub = wide_write ? 0 : sub; + while (pos < ewidth) { + int epos = pos; + while (epos < ewidth && wport.en[epos + wsub * mem.width] == wport.en[pos + wsub * mem.width]) + epos++; + + std::ostringstream os; + if (has_indent) + os << indent; + os << "if ("; + dump_sigspec(os, wport.en[pos + wsub * mem.width]); + if (raddr != waddr) { + os << " && "; + dump_sigspec(os, raddr); + os << " == "; + dump_sigspec(os, waddr); + } + os << ") begin\n"; + clk_to_lof_body[clk_domain_str].push_back(os.str()); + + int sig_beg = rsub * mem.width + pos; + int sig_end = rsub * mem.width + epos; + int valid_beg = sig_beg / bypass_part_width; + int valid_end = (sig_end + bypass_part_width - 1) / bypass_part_width; + std::ostringstream os2; + if (has_indent) + os2 << indent; + os2 << stringf("%s" "%s", indent, bypass_valid_id); + if (epos-pos != GetSize(port.data)) + os2 << stringf("[%d:%d]", valid_end - 1, valid_beg); + os2 << " <= "; + dump_sigspec(os2, Const(State::S1, valid_end - valid_beg)); + os2 << ";\n"; + clk_to_lof_body[clk_domain_str].push_back(os2.str()); + + std::ostringstream os3; + if (has_indent) + os3 << indent; + os3 << stringf("%s" "%s", indent, bypass_data_id); + if (epos-pos != GetSize(port.data)) + os3 << stringf("[%d:%d]", sig_end - 1, sig_beg); + os3 << " <= "; + if (port.transparency_mask[i]) + dump_sigspec(os3, wport.data.extract(wsub * mem.width + pos, epos-pos)); + else + dump_sigspec(os3, Const(State::Sx, epos - pos)); + os3 << ";\n"; + clk_to_lof_body[clk_domain_str].push_back(os3.str()); + clk_to_lof_body[clk_domain_str].push_back(stringf("%s" "end\n", has_indent ? indent : "")); + + pos = epos; + } + } + } + + if (port.srst != State::S0 && port.ce_over_srst) + { + std::ostringstream os; + if (has_indent) + os << indent; + os << stringf("if ("); + dump_sigspec(os, port.srst); + os << stringf(") begin\n"); + clk_to_lof_body[clk_domain_str].push_back(os.str()); + + std::ostringstream os2; + if (has_indent) + os2 << indent; + os2 << stringf("%s" "%s <= ", indent, temp_id); + dump_sigspec(os2, port.srst_value); + os2 << ";\n"; + clk_to_lof_body[clk_domain_str].push_back(os2.str()); + + if (has_transparency) { + clk_to_lof_body[clk_domain_str].push_back((has_indent ? indent : "") + indent + bypass_valid_reset_str); + clk_to_lof_body[clk_domain_str].push_back((has_indent ? indent : "") + indent + bypass_data_reset_str); + } + clk_to_lof_body[clk_domain_str].push_back((has_indent ? indent : "") + "end\n"); + } + + if (has_indent) + clk_to_lof_body[clk_domain_str].push_back("end\n"); + + if (!port.init_value.is_fully_undef()) + { + std::ostringstream os; + os << stringf("initial %s = ", temp_id); + dump_sigspec(os, port.init_value); + os << ";\n"; + clk_to_lof_body[""].push_back(os.str()); + + if (has_transparency) { + std::ostringstream os2; + os2 << stringf("initial %s = ", bypass_valid_id); + dump_sigspec(os2, Const(State::S0, bypass_valid_width)); + os2 << ";\n"; + clk_to_lof_body[""].push_back(os2.str()); + } + } + + { + if (!has_transparency) { std::ostringstream os; os << "assign "; - dump_sigspec(os, port.data.extract(sub * mem.width, mem.width)); - os << stringf(" = %s[", mem_id);; - if (port.wide_log2) { - Const::Builder addr_lo_builder(port.wide_log2); - for (int i = 0; i < port.wide_log2; i++) - addr_lo_builder.push_back(State(sub >> i & 1)); - Const addr_lo = addr_lo_builder.build(); - os << "{"; - os << temp_id; - os << ", "; - dump_const(os, addr_lo); - os << "}"; - } else { - os << temp_id; - } - os << "];\n"; + dump_sigspec(os, port.data); + os << " = "; + os << temp_id; + os << ";\n"; clk_to_lof_body[""].push_back(os.str()); + } else { + for (int sub = 0; sub < bypass_valid_width; sub++) { + int seg_beg = sub * bypass_part_width; + int seg_end = (sub + 1) * bypass_part_width; + + std::ostringstream os; + os << "assign "; + dump_sigspec(os, port.data.extract(seg_beg, seg_end - seg_beg)); + os << " = "; + os << stringf("%s[%d]", bypass_valid_id, sub); + os << stringf(" ? %s[%d:%d]", bypass_data_id, seg_end - 1, seg_beg); + os << stringf(" : %s[%d:%d]", temp_id, seg_end - 1, seg_beg); + os << ";\n"; + clk_to_lof_body[""].push_back(os.str()); + } } } } else { From 3349e9c8ea9250c35dcd31085b875ac928e90e09 Mon Sep 17 00:00:00 2001 From: Jakub Janeczko Date: Thu, 23 Jul 2026 14:55:02 +0200 Subject: [PATCH 2/5] bypass part width is 1 --- backends/verilog/verilog_backend.cc | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index e8ab4af4f..bd7471c39 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -626,15 +626,13 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem) lof_reg_declarations.push_back( stringf("reg [%d:0] %s;\n", port.data.size() - 1, temp_id) ); bool has_transparency = false; - int bypass_part_width = port.data.size() / port.en.size(); for (int i = 0; i < GetSize(mem.wr_ports); i++) { - auto &wport = mem.wr_ports[i]; if (!port.transparency_mask[i] && !port.collision_x_mask[i]) continue; has_transparency = true; - bypass_part_width = std::min(bypass_part_width, wport.data.size() / wport.en.size()); } - int bypass_valid_width = port.data.size() / bypass_part_width; + int bypass_valid_width = port.data.size(); + int bypass_part_width = 1; std::string bypass_valid_id; std::string bypass_valid_reset_str; @@ -864,7 +862,7 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem) std::ostringstream os; os << "assign "; - dump_sigspec(os, port.data.extract(seg_beg, seg_end - seg_beg)); + dump_sigspec(os, port.data.extract(seg_beg, bypass_part_width)); os << " = "; os << stringf("%s[%d]", bypass_valid_id, sub); os << stringf(" ? %s[%d:%d]", bypass_data_id, seg_end - 1, seg_beg); From d479af29cfcd84ce933a06fcae6a4a17d4030b51 Mon Sep 17 00:00:00 2001 From: Jakub Janeczko Date: Thu, 23 Jul 2026 19:00:03 +0200 Subject: [PATCH 3/5] cleaner assign with transparency --- backends/verilog/verilog_backend.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index bd7471c39..ffd2f09ae 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -855,6 +855,14 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem) os << temp_id; os << ";\n"; clk_to_lof_body[""].push_back(os.str()); + } else if (bypass_part_width == 1) { + std::ostringstream os; + os << "assign "; + dump_sigspec(os, port.data); + os << " = "; + os << stringf("(%s & %s) | (~%s & %s)", bypass_valid_id, bypass_data_id, bypass_valid_id, temp_id); + os << ";\n"; + clk_to_lof_body[""].push_back(os.str()); } else { for (int sub = 0; sub < bypass_valid_width; sub++) { int seg_beg = sub * bypass_part_width; From d02d8253ac5c1e78d6b4a21a1f4d7e3723280ce9 Mon Sep 17 00:00:00 2001 From: Jakub Janeczko Date: Thu, 23 Jul 2026 19:07:17 +0200 Subject: [PATCH 4/5] format --- backends/verilog/verilog_backend.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index ffd2f09ae..a0db88e09 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -631,8 +631,8 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem) continue; has_transparency = true; } - int bypass_valid_width = port.data.size(); int bypass_part_width = 1; + int bypass_valid_width = port.data.size() / bypass_part_width; std::string bypass_valid_id; std::string bypass_valid_reset_str; @@ -856,13 +856,13 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem) os << ";\n"; clk_to_lof_body[""].push_back(os.str()); } else if (bypass_part_width == 1) { - std::ostringstream os; - os << "assign "; - dump_sigspec(os, port.data); - os << " = "; - os << stringf("(%s & %s) | (~%s & %s)", bypass_valid_id, bypass_data_id, bypass_valid_id, temp_id); - os << ";\n"; - clk_to_lof_body[""].push_back(os.str()); + std::ostringstream os; + os << "assign "; + dump_sigspec(os, port.data); + os << " = "; + os << stringf("(%s & %s) | (~%s & %s)", bypass_valid_id, bypass_data_id, bypass_valid_id, temp_id); + os << ";\n"; + clk_to_lof_body[""].push_back(os.str()); } else { for (int sub = 0; sub < bypass_valid_width; sub++) { int seg_beg = sub * bypass_part_width; From c771db06bbe41967d921c5f1d92cffbb838bb1e5 Mon Sep 17 00:00:00 2001 From: Jakub Janeczko Date: Thu, 23 Jul 2026 19:12:25 +0200 Subject: [PATCH 5/5] remove generic path width --- backends/verilog/verilog_backend.cc | 31 ++++++----------------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index a0db88e09..d12f70e31 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -631,8 +631,6 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem) continue; has_transparency = true; } - int bypass_part_width = 1; - int bypass_valid_width = port.data.size() / bypass_part_width; std::string bypass_valid_id; std::string bypass_valid_reset_str; @@ -640,11 +638,11 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem) std::string bypass_data_reset_str; if (has_transparency) { bypass_valid_id = next_auto_id(); - lof_reg_declarations.push_back( stringf("reg [%d:0] %s;\n", bypass_valid_width - 1, bypass_valid_id) ); + lof_reg_declarations.push_back( stringf("reg [%d:0] %s;\n", port.data.size() - 1, bypass_valid_id) ); std::ostringstream os; os << stringf("%s <= ", bypass_valid_id); - dump_sigspec(os, Const(State::S0, bypass_valid_width)); + dump_sigspec(os, Const(State::S0, port.data.size())); os << ";\n"; bypass_valid_reset_str = os.str(); @@ -768,16 +766,14 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem) int sig_beg = rsub * mem.width + pos; int sig_end = rsub * mem.width + epos; - int valid_beg = sig_beg / bypass_part_width; - int valid_end = (sig_end + bypass_part_width - 1) / bypass_part_width; std::ostringstream os2; if (has_indent) os2 << indent; os2 << stringf("%s" "%s", indent, bypass_valid_id); if (epos-pos != GetSize(port.data)) - os2 << stringf("[%d:%d]", valid_end - 1, valid_beg); + os2 << stringf("[%d:%d]", sig_end - 1, sig_beg); os2 << " <= "; - dump_sigspec(os2, Const(State::S1, valid_end - valid_beg)); + dump_sigspec(os2, Const(State::S1, sig_end - sig_beg)); os2 << ";\n"; clk_to_lof_body[clk_domain_str].push_back(os2.str()); @@ -840,7 +836,7 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem) if (has_transparency) { std::ostringstream os2; os2 << stringf("initial %s = ", bypass_valid_id); - dump_sigspec(os2, Const(State::S0, bypass_valid_width)); + dump_sigspec(os2, Const(State::S0, port.data.size())); os2 << ";\n"; clk_to_lof_body[""].push_back(os2.str()); } @@ -855,7 +851,7 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem) os << temp_id; os << ";\n"; clk_to_lof_body[""].push_back(os.str()); - } else if (bypass_part_width == 1) { + } else { std::ostringstream os; os << "assign "; dump_sigspec(os, port.data); @@ -863,21 +859,6 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem) os << stringf("(%s & %s) | (~%s & %s)", bypass_valid_id, bypass_data_id, bypass_valid_id, temp_id); os << ";\n"; clk_to_lof_body[""].push_back(os.str()); - } else { - for (int sub = 0; sub < bypass_valid_width; sub++) { - int seg_beg = sub * bypass_part_width; - int seg_end = (sub + 1) * bypass_part_width; - - std::ostringstream os; - os << "assign "; - dump_sigspec(os, port.data.extract(seg_beg, bypass_part_width)); - os << " = "; - os << stringf("%s[%d]", bypass_valid_id, sub); - os << stringf(" ? %s[%d:%d]", bypass_data_id, seg_end - 1, seg_beg); - os << stringf(" : %s[%d:%d]", temp_id, seg_end - 1, seg_beg); - os << ";\n"; - clk_to_lof_body[""].push_back(os.str()); - } } } } else {