[flash_ctrl] Connect flash / pwrmgr functions - Connect init / done - Connect idle Signed-off-by: Timothy Chen <timothytim@google.com> [flash_ctrl] update waivers Signed-off-by: Timothy Chen <timothytim@google.com> [flash_ctrl] fix typos Signed-off-by: Timothy Chen <timothytim@google.com>
diff --git a/hw/ip/flash_ctrl/data/flash_ctrl.hjson b/hw/ip/flash_ctrl/data/flash_ctrl.hjson index f420430..c214965 100644 --- a/hw/ip/flash_ctrl/data/flash_ctrl.hjson +++ b/hw/ip/flash_ctrl/data/flash_ctrl.hjson
@@ -36,13 +36,20 @@ package: "flash_ctrl_pkg" }, - { struct: "pwrmgr_flash", + { struct: "edn_entropy", type: "uni", - name: "pwrmgr", + name: "edn", act: "rcv", package: "flash_ctrl_pkg" }, + { struct: "pwr_flash", + type: "req_rsp", + name: "pwrmgr", + act: "rsp", + package: "pwrmgr_pkg" + }, + ], param_list: [
diff --git a/hw/ip/flash_ctrl/dv/tb/flash_ctrl_wrapper.sv b/hw/ip/flash_ctrl/dv/tb/flash_ctrl_wrapper.sv index e4facd1..b903f01 100644 --- a/hw/ip/flash_ctrl/dv/tb/flash_ctrl_wrapper.sv +++ b/hw/ip/flash_ctrl/dv/tb/flash_ctrl_wrapper.sv
@@ -17,7 +17,8 @@ // OTP interface input flash_ctrl_pkg::otp_flash_t otp_i, input flash_ctrl_pkg::lc_flash_req_t lc_i, - input flash_ctrl_pkg::pwrmgr_flash_t pwrmgr_i, + output pwrmgr_pkg::pwr_flash_rsp_t pwrmgr_o, + input pwrmgr_pkg::pwr_flash_req_t pwrmgr_i, input flash_ctrl_pkg::edn_entropy_t edn_i, // Interrupts @@ -51,6 +52,7 @@ .otp_i (otp_i), .lc_i (lc_i), .pwrmgr_i (pwrmgr_i), + .pwrmgr_o (pwrmgr_o), .edn_i (edn_i), .clk_i (clk_i),
diff --git a/hw/ip/flash_ctrl/dv/tb/tb.sv b/hw/ip/flash_ctrl/dv/tb/tb.sv index fa564df..c6b08a1 100644 --- a/hw/ip/flash_ctrl/dv/tb/tb.sv +++ b/hw/ip/flash_ctrl/dv/tb/tb.sv
@@ -46,7 +46,8 @@ // TODO: create and hook this up to an interface. .otp_i (flash_ctrl_pkg::OTP_FLASH_DEFAULT), .lc_i (flash_ctrl_pkg::LC_FLASH_REQ_DEFAULT), - .pwrmgr_i (flash_ctrl_pkg::PWRMGR_FLASH_DEFAULT), + .pwrmgr_o (pwrmgr_pkg::PWR_FLASH_RSP_DEFAULT), + .pwrmgr_i (pwrmgr_pkg::PWR_FLASH_REQ_DEFAULT), .edn_i (flash_ctrl_pkg::EDN_ENTROPY_DEFAULT), .intr_prog_empty_o (intr_prog_empty),
diff --git a/hw/ip/flash_ctrl/flash_ctrl.core b/hw/ip/flash_ctrl/flash_ctrl.core index 2280904..b760c47 100644 --- a/hw/ip/flash_ctrl/flash_ctrl.core +++ b/hw/ip/flash_ctrl/flash_ctrl.core
@@ -14,6 +14,7 @@ - lowrisc:prim:lfsr - lowrisc:prim:flash - lowrisc:prim:gf_mult + - lowrisc:ip:pwrmgr_pkg - lowrisc:ip:flash_ctrl_pkg files: - rtl/flash_ctrl_reg_top.sv
diff --git a/hw/ip/flash_ctrl/lint/flash_ctrl.waiver b/hw/ip/flash_ctrl/lint/flash_ctrl.waiver index 25a4d5d..192c86b 100644 --- a/hw/ip/flash_ctrl/lint/flash_ctrl.waiver +++ b/hw/ip/flash_ctrl/lint/flash_ctrl.waiver
@@ -7,3 +7,14 @@ # All leaf resets have a reset multiplex waive -rules TERMINAL_STATE -location {flash_ctrl_lcmgr.sv} -regexp {.*StInvalid.*} \ -comment "StInvalid is intended to be a terminal state" + +# Remove errors from prim_* modules +# TBD These should be directly addressed in primgen modules long term +waive -rules INPUT_NOT_READ -location {prim_flop.sv} -regexp {Input port.*} \ + -comment "Silience prim related errors" + +waive -rules OUTPUT_NOT_DRIVEN -location {prim_flop*.sv} -regexp {.*q_o.*} \ + -comment "Silience prim related errors" + +waive -rules INPUT_NOT_READ -location {prim_flop_2sync.sv} -regexp {Input port.*} \ + -comment "Silience prim related errors"
diff --git a/hw/ip/flash_ctrl/rtl/flash_ctrl.sv b/hw/ip/flash_ctrl/rtl/flash_ctrl.sv index aacc643..71c69b1 100644 --- a/hw/ip/flash_ctrl/rtl/flash_ctrl.sv +++ b/hw/ip/flash_ctrl/rtl/flash_ctrl.sv
@@ -24,7 +24,8 @@ input otp_flash_t otp_i, input lc_flash_req_t lc_i, output lc_flash_rsp_t lc_o, - input pwrmgr_flash_t pwrmgr_i, + input pwrmgr_pkg::pwr_flash_req_t pwrmgr_i, + output pwrmgr_pkg::pwr_flash_rsp_t pwrmgr_o, input edn_entropy_t edn_i, // Interrupts @@ -269,7 +270,8 @@ .clk_i, .rst_ni, - .init_i(pwrmgr_i.init), + .init_i(pwrmgr_i.flash_init), + .init_done_o(pwrmgr_o.flash_done), .provision_en_i(lc_i.provision_en), // interface to ctrl arb control ports @@ -385,9 +387,6 @@ .flash_error_i (flash_mp_error) ); - // Read FIFO - - always_ff @(posedge clk_i or negedge rst_ni) begin if (!rst_ni) begin adapter_rvalid <= 1'b0; @@ -636,6 +635,23 @@ assign flash_rd_data = flash_i.rd_data; assign flash_phy_busy = flash_i.init_busy; + // Interface to pwrmgr + // flash is not idle as long as there is a stateful operation ongoing + logic flash_idle_d; + assign flash_idle_d = ~(flash_o.req & + (flash_o.prog | flash_o.pg_erase | flash_o.bk_erase)); + + prim_flop #( + .Width(1), + .ResetValue(1'b1) + ) u_reg_idle ( + .clk_i, + .rst_ni, + .d_i(flash_idle_d), + .q_o(pwrmgr_o.flash_idle) + ); + + // Interrupts // Generate edge triggered signals for sources that are level logic [3:0] intr_src;
diff --git a/hw/ip/flash_ctrl/rtl/flash_ctrl_arb.sv b/hw/ip/flash_ctrl/rtl/flash_ctrl_arb.sv index 181588d..f14534c 100644 --- a/hw/ip/flash_ctrl/rtl/flash_ctrl_arb.sv +++ b/hw/ip/flash_ctrl/rtl/flash_ctrl_arb.sv
@@ -60,7 +60,7 @@ output logic prog_fifo_wvalid_o, input logic prog_fifo_wready_i, - // flash phy initilization ongoing + // flash phy initialization ongoing input logic flash_phy_busy_i, // clear fifo contents
diff --git a/hw/ip/flash_ctrl/rtl/flash_ctrl_lcmgr.sv b/hw/ip/flash_ctrl/rtl/flash_ctrl_lcmgr.sv index fcf14f0..cd32191 100644 --- a/hw/ip/flash_ctrl/rtl/flash_ctrl_lcmgr.sv +++ b/hw/ip/flash_ctrl/rtl/flash_ctrl_lcmgr.sv
@@ -11,6 +11,7 @@ // initialization command input init_i, + output logic init_done_o, // only access seeds when provisioned input provision_en_i, @@ -81,6 +82,7 @@ } state_e; state_e state_q, state_d; + logic init_done_d; logic validate_q, validate_d; logic [SeedCntWidth-1:0] seed_cnt_q; logic [CntWidth-1:0] addr_cnt_q; @@ -97,9 +99,11 @@ if (!rst_ni) begin state_q <= StIdle; validate_q <= 1'b0; + init_done_o <= 1'b0; end else begin state_q <= state_d; validate_q <= validate_d; + init_done_o <= init_done_d; end end @@ -175,6 +179,19 @@ // rma phase is erase unless we are validating assign op = seed_phase || validate_q ? FlashOpRead : FlashOpErase; + // synchronize inputs + logic init_q; + + prim_flop_2sync #( + .Width(1), + .ResetValue(0) + ) u_sync_flash_init ( + .clk_i, + .rst_ni, + .d_i(init_i), + .q_o(init_q) + ); + always_comb begin // phases of the hardware interface @@ -202,15 +219,20 @@ state_d = state_q; validate_d = validate_q; + // init status + // flash_ctrl handles its own arbitration between hardware and software. + // So once the init kicks off it is safe to ack. The done signal is still + // to give a chance to hold off further power up progression in the future + // if required. + init_done_d = 1'b1; + unique case (state_q) StIdle: begin + init_done_d = 1'b0; phase = PhaseSeed; - // TBD: provision_en is only a "good" value after otp initilization - // Need to qualify this statement with some notion that otp init has - // finished. Since power manager will kick off otp init, it should - // also be able to kick off flash_init - if (init_i) begin + // provision_en is only a "good" value after otp/lc initialization + if (init_q) begin // if provisioning is not enabled, do not read seeds and skip directly // to wait state. state_d = provision_en_i ? StReadSeeds : StWait;
diff --git a/hw/ip/flash_ctrl/rtl/flash_ctrl_pkg.sv b/hw/ip/flash_ctrl/rtl/flash_ctrl_pkg.sv index e7f23e1..336f9b6 100644 --- a/hw/ip/flash_ctrl/rtl/flash_ctrl_pkg.sv +++ b/hw/ip/flash_ctrl/rtl/flash_ctrl_pkg.sv
@@ -282,11 +282,6 @@ logic [BusWidth-1:0] rma_ack_token; } lc_flash_rsp_t; - // pwrmgr to flash_ctrl - typedef struct packed { - logic init; - } pwrmgr_flash_t; - // place holder for interface to EDN, replace with real one later typedef struct packed { logic valid; @@ -309,10 +304,6 @@ provision_en: 1'b1 }; - parameter pwrmgr_flash_t PWRMGR_FLASH_DEFAULT = '{ - init: 1'b1 - }; - parameter edn_entropy_t EDN_ENTROPY_DEFAULT = '{ valid: 1'b1, entropy: '0
diff --git a/hw/ip/pwrmgr/data/pwrmgr.hjson.tpl b/hw/ip/pwrmgr/data/pwrmgr.hjson.tpl index 0ba5f45..17b1246 100644 --- a/hw/ip/pwrmgr/data/pwrmgr.hjson.tpl +++ b/hw/ip/pwrmgr/data/pwrmgr.hjson.tpl
@@ -49,9 +49,9 @@ }, { struct: "pwr_flash", - type: "uni", + type: "req_rsp", name: "pwr_flash", - act: "rcv", + act: "req", package: "pwrmgr_pkg", },
diff --git a/hw/ip/pwrmgr/rtl/pwrmgr.sv b/hw/ip/pwrmgr/rtl/pwrmgr.sv index e049fc3..d97cb89 100644 --- a/hw/ip/pwrmgr/rtl/pwrmgr.sv +++ b/hw/ip/pwrmgr/rtl/pwrmgr.sv
@@ -40,7 +40,8 @@ output pwr_lc_req_t pwr_lc_o, // flash interface - input pwr_flash_t pwr_flash_i, + output pwr_flash_req_t pwr_flash_o, + input pwr_flash_rsp_t pwr_flash_i, // processor interface input pwr_cpu_t pwr_cpu_i, @@ -79,6 +80,8 @@ logic low_power_fall_through; logic low_power_abort; + pwr_flash_rsp_t flash_rsp; + //////////////////////////// /// clk_slow_i domain declarations //////////////////////////// @@ -182,7 +185,11 @@ .ast_i(pwr_ast_i), // peripheral signals - .peri_i(peri_reqs_raw) + .peri_i(peri_reqs_raw), + + // flash handshake + .flash_i(pwr_flash_i), + .flash_o(flash_rsp) ); assign hw2reg.cfg_cdc_sync.d = 1'b0; @@ -291,7 +298,9 @@ .lc_idle_i (pwr_lc_i.lc_idle), // flash - .flash_idle_i (pwr_flash_i.flash_idle) + .flash_init_o (pwr_flash_o.flash_init), + .flash_done_i (flash_rsp.flash_done), + .flash_idle_i (flash_rsp.flash_idle) ); ////////////////////////////
diff --git a/hw/ip/pwrmgr/rtl/pwrmgr_cdc.sv b/hw/ip/pwrmgr/rtl/pwrmgr_cdc.sv index c4ccd9b..307f5c2 100644 --- a/hw/ip/pwrmgr/rtl/pwrmgr_cdc.sv +++ b/hw/ip/pwrmgr/rtl/pwrmgr_cdc.sv
@@ -48,6 +48,8 @@ // peripheral inputs, mixed domains input pwr_peri_t peri_i, + input pwr_flash_rsp_t flash_i, + output pwr_flash_rsp_t flash_o, // AST inputs, unknown domain input pwr_ast_rsp_t ast_i @@ -212,7 +214,7 @@ end end - prim_flop_2sync # ( + prim_flop_2sync #( .Width(HwRstReqs + NumWkups) ) i_ext_req_sync ( .clk_i, @@ -221,6 +223,27 @@ .q_o(peri_reqs_o) ); + // synchronize inputs from flash + prim_flop_2sync #( + .Width(1), + .ResetValue(1'b0) + ) u_sync_flash_done ( + .clk_i, + .rst_ni, + .d_i(flash_i.flash_done), + .q_o(flash_o.flash_done) + ); + + prim_flop_2sync #( + .Width(1), + .ResetValue(1'b1) + ) u_sync_flash_idle ( + .clk_i, + .rst_ni, + .d_i(flash_i.flash_idle), + .q_o(flash_o.flash_idle) + ); + endmodule
diff --git a/hw/ip/pwrmgr/rtl/pwrmgr_fsm.sv b/hw/ip/pwrmgr/rtl/pwrmgr_fsm.sv index 8c7028a..b923dd4 100644 --- a/hw/ip/pwrmgr/rtl/pwrmgr_fsm.sv +++ b/hw/ip/pwrmgr/rtl/pwrmgr_fsm.sv
@@ -48,6 +48,8 @@ input lc_idle_i, // flash + output logic flash_init_o, + input flash_done_i, input flash_idle_i ); @@ -58,6 +60,7 @@ StReleaseLcRst, StOtpInit, StLcInit, + StFlashInit, StAckPwrUp, StActive, StDisClks, @@ -96,6 +99,7 @@ logic [PowerDomains-1:0] rst_lc_req_d, rst_sys_req_d; logic otp_init; logic lc_init; + logic flash_init_d; assign pd_n_rsts_asserted = pwr_rst_i.rst_lc_src_n[PowerDomains-1:1] == '0 & pwr_rst_i.rst_sys_src_n[PowerDomains-1:1] == '0; @@ -149,6 +153,7 @@ rst_lc_req_d = rst_lc_req_q; rst_sys_req_d = rst_sys_req_q; reset_cause_d = reset_cause_q; + flash_init_d = 1'b0; unique case(state_q) @@ -186,12 +191,20 @@ lc_init = 1'b1; if (lc_done_i) begin - state_d = StAckPwrUp; - + state_d = StFlashInit; end end + StFlashInit: begin + flash_init_d = 1'b1; + + if (flash_done_i) begin + state_d = StAckPwrUp; + end + end + + StAckPwrUp: begin // only ack the slow_fsm if we actually transitioned through it ack_pwrup_d = !reset_ongoing_q; @@ -315,5 +328,15 @@ assign lc_init_o = lc_init; assign ips_clk_en_o = ip_clk_en_q; + prim_flop #( + .Width(1), + .ResetValue(1'b1) + ) u_reg_idle ( + .clk_i, + .rst_ni, + .d_i(flash_init_d), + .q_o(flash_init_o) + ); + endmodule
diff --git a/hw/ip/pwrmgr/rtl/pwrmgr_pkg.sv b/hw/ip/pwrmgr/rtl/pwrmgr_pkg.sv index 98c7d38..6019123 100644 --- a/hw/ip/pwrmgr/rtl/pwrmgr_pkg.sv +++ b/hw/ip/pwrmgr/rtl/pwrmgr_pkg.sv
@@ -12,7 +12,7 @@ // variables referenced by other modules / packages parameter int HwRstReqs = 2; // this needs to be a topgen populated number, or from topcfg? - parameter int PowerDomains = 2; // this maybe needs to be a topgen populated number, or from topcfg? + parameter int PowerDomains = 2; // this needs to be a topgen populated number, or from topcfg? // variables referenced only by pwrmgr // pwrmgr_reg_pkg::NumWkups; // should this be coming from top_pkg instead? @@ -122,11 +122,21 @@ // flash to pwrmgr typedef struct packed { + logic flash_init; + } pwr_flash_req_t; + + typedef struct packed { + logic flash_done; logic flash_idle; - } pwr_flash_t; + } pwr_flash_rsp_t; // default value (for dangling ports) - parameter pwr_flash_t PWR_FLASH_DEFAULT = '{ + parameter pwr_flash_req_t PWR_FLASH_REQ_DEFAULT = '{ + flash_init: 1'b1 + }; + + parameter pwr_flash_rsp_t PWR_FLASH_RSP_DEFAULT = '{ + flash_done: 1'b1, flash_idle: 1'b1 };
diff --git a/hw/top_earlgrey/data/top_earlgrey.hjson b/hw/top_earlgrey/data/top_earlgrey.hjson index 4cced93..7bb98f2 100644 --- a/hw/top_earlgrey/data/top_earlgrey.hjson +++ b/hw/top_earlgrey/data/top_earlgrey.hjson
@@ -399,7 +399,8 @@ // e.g flash_ctrl0.flash: [flash_phy0.flash_ctrl] inter_module: { 'connect': { - 'flash_ctrl.flash': ['eflash.flash_ctrl'] + 'flash_ctrl.flash': ['eflash.flash_ctrl'], + 'pwrmgr.pwr_flash': ['flash_ctrl.pwrmgr'], 'pwrmgr.pwr_rst' : ['rstmgr.pwr'], 'pwrmgr.pwr_clk' : ['clkmgr.pwr'], }
diff --git a/hw/top_earlgrey/lint/top_earlgrey_lint_cfgs.hjson b/hw/top_earlgrey/lint/top_earlgrey_lint_cfgs.hjson index 8253d82..117b1d5 100644 --- a/hw/top_earlgrey/lint/top_earlgrey_lint_cfgs.hjson +++ b/hw/top_earlgrey/lint/top_earlgrey_lint_cfgs.hjson
@@ -35,6 +35,12 @@ fusesoc_core: lowrisc:ip:flash_ctrl import_cfgs: ["{proj_root}/hw/lint/data/common_lint_cfg.hjson"] rel_path: "hw/ip/flash_ctrl/lint/{tool}" + overrides: [ + { + name: design_level + value: "top" + } + ] }, { name: gpio fusesoc_core: lowrisc:ip:gpio