From 5628f5a88fa49c126af0149e302a8292229ab9df Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 25 May 2021 15:17:29 +0200 Subject: [PATCH] opt_mem_feedback: Respect write port priority. --- passes/opt/opt_mem_feedback.cc | 15 +++++++++++ tests/opt/opt_mem_feedback.ys | 47 ++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/passes/opt/opt_mem_feedback.cc b/passes/opt/opt_mem_feedback.cc index 90e5cea9b..8e93c93b9 100644 --- a/passes/opt/opt_mem_feedback.cc +++ b/passes/opt/opt_mem_feedback.cc @@ -237,6 +237,21 @@ struct OptMemFeedbackWorker log("Populating enable bits on write ports of memory %s.%s with async read feedback:\n", log_id(module), log_id(mem.memid)); + // If a write port has a feedback path that we're about to bypass, + // but also has priority over some other write port, the feedback + // path is not necessarily a NOP — it may overwrite the other port. + // Emulate this effect by converting the priority to soft logic + // (this will affect the other port's enable signal). + for (auto &it : portbit_conds) + { + int wrport_idx = it.first.first; + auto &port = mem.wr_ports[wrport_idx]; + + for (int i = 0; i < wrport_idx; i++) + if (port.priority_mask[i]) + mem.emulate_priority(i, wrport_idx); + } + for (auto &it : portbit_conds) { int wrport_idx = it.first.first; diff --git a/tests/opt/opt_mem_feedback.ys b/tests/opt/opt_mem_feedback.ys index 6a68921c3..56078ec27 100644 --- a/tests/opt/opt_mem_feedback.ys +++ b/tests/opt/opt_mem_feedback.ys @@ -140,3 +140,50 @@ memory_map design -save postopt equiv_opt -assert -run prepare: : + + + +design -reset + +# Tricky case: legit feedback path, but priority needs to be preserved. + +read_verilog << EOT + +module top(...); + +input clk; +input sel; +input [3:0] wa1; +input [3:0] wa2; +input [15:0] wd1; +input [3:0] ra; +output [15:0] rd; + +reg [15:0] mem [0:15]; + +always @(posedge clk) begin + mem[wa1] <= sel ? wd1 : mem[wa1]; + mem[wa2] <= mem[wa2]; +end + +assign rd = mem[ra]; + +endmodule + +EOT + +hierarchy -auto-top +proc +opt_clean + +design -save start +memory_map +design -save preopt + +design -load start +opt_mem_feedback +select -assert-count 1 t:$memrd +memory_map +design -save postopt + +equiv_opt -assert -run prepare: : -- 2.30.2