[flash_ctrl] Select appropriate ready's based on request source
- fixes #12381
- the previous design used the read stage's ready for arbitration.
Due to the way the design is currently done, the read stage ready
is actually dependent on the the downstream flash macro actually
ack-ing the transaction. To fix this, we would need to de-couple
the req/ack interface on the side facing the phy and the side facing
the macro. While this is doable, it would also require us to latch
incoming bus attributes. However, there is not a lot to gain by doing
so, because as long as the flash has not responded, the next read
cannot proceed anyways.
- This dependency can cause program/erase operations to lock-up if the
the downstream macro does not always keep ack asserted when idle (in
effect behaving more like ready).
- Even though the above fix would be cleaner long term, the quick fix is
simply to pick the appropriate ready for host and controller operations
separately.
Signed-off-by: Timothy Chen <timothytim@google.com>
diff --git a/hw/ip/flash_ctrl/rtl/flash_phy_core.sv b/hw/ip/flash_ctrl/rtl/flash_phy_core.sv
index 05ecbe3..6ec322e 100644
--- a/hw/ip/flash_ctrl/rtl/flash_phy_core.sv
+++ b/hw/ip/flash_ctrl/rtl/flash_phy_core.sv
@@ -101,7 +101,7 @@
state_e state_q, state_d;
// request signals to flash macro
- logic [PhyOps-1:0] reqs;
+ logic [PhyLastOp-1:0] reqs;
// host select for address
logic host_sel;
@@ -244,6 +244,8 @@
// SEC_CM: PHY_ARBITER.CTRL.REDUN
logic phy_req;
+ logic phy_rdy;
+
prim_arbiter_tree_dup #(
.N(2),
.DW(2),
@@ -258,10 +260,13 @@
.idx_o(),
.valid_o(phy_req),
.data_o(),
- .ready_i(rd_stage_rdy),
+ .ready_i(phy_rdy),
.err_o(arb_err_o)
);
+ assign phy_rdy = phy_req & host_req ? rd_stage_rdy : rd_stage_idle;
+
+
// if request happens at the same time as a host grant, increment count
assign inc_arb_cnt = req_i & host_gnt;
diff --git a/hw/ip/flash_ctrl/rtl/flash_phy_pkg.sv b/hw/ip/flash_ctrl/rtl/flash_phy_pkg.sv
index eaffdfd..4603ec0 100644
--- a/hw/ip/flash_ctrl/rtl/flash_phy_pkg.sv
+++ b/hw/ip/flash_ctrl/rtl/flash_phy_pkg.sv
@@ -84,14 +84,12 @@
// Flash Operations Supported
typedef enum logic [1:0] {
- PhyRead = 2'h0,
- PhyProg = 2'h1,
- PhyPgErase = 2'h2,
- PhyBkErase = 2'h3
+ PhyProg,
+ PhyPgErase,
+ PhyBkErase,
+ PhyLastOp
} flash_phy_op_e;
- localparam int PhyOps = 4;
-
// Flash Operations Selected
typedef enum logic [1:0] {
None = 2'h0,