diff --git a/hw/ip/pinmux/data/pinmux.hjson b/hw/ip/pinmux/data/pinmux.hjson index 9566e51af0eea..d448948de43fa 100644 --- a/hw/ip/pinmux/data/pinmux.hjson +++ b/hw/ip/pinmux/data/pinmux.hjson @@ -26,13 +26,39 @@ ], inter_signal_list: [ - // Define lc <-> pinmux signal for strap sampling - { struct: "lc_strap", - type: "req_rsp", - name: "lc_pinmux_strap", - act: "rsp", - package: "pinmux_pkg", - default: "'0" + // Life cycle inputs + { struct: "lc_tx" + type: "uni" + name: "lc_hw_debug_en" + act: "rcv" + default: "lc_ctrl_pkg::Off" + package: "lc_ctrl_pkg" + } + { struct: "lc_tx" + type: "uni" + name: "lc_dft_en" + act: "rcv" + default: "lc_ctrl_pkg::Off" + package: "lc_ctrl_pkg" + } + // JTAG TAPs + { struct: "jtag" + type: "req_rsp" + name: "lc_jtag" + act: "req" + package: "jtag_pkg" + } + { struct: "jtag" + type: "req_rsp" + name: "rv_jtag" + act: "req" + package: "jtag_pkg" + } + { struct: "jtag" + type: "req_rsp" + name: "dft_jtag" + act: "req" + package: "jtag_pkg" } // Testmode signals to AST { struct: "dft_strap_test", @@ -50,6 +76,13 @@ package: "", default: "1'b0" }, + { struct: "logic", + type: "uni", + name: "strap_en", + act: "rcv", + package: "", + default: "1'b0" + }, { struct: "logic", type: "uni", name: "aon_wkup_req", diff --git a/hw/ip/pinmux/data/pinmux.hjson.tpl b/hw/ip/pinmux/data/pinmux.hjson.tpl index 3d3e6a0e9de37..fbf3ee688c1d5 100644 --- a/hw/ip/pinmux/data/pinmux.hjson.tpl +++ b/hw/ip/pinmux/data/pinmux.hjson.tpl @@ -38,13 +38,39 @@ ], inter_signal_list: [ - // Define lc <-> pinmux signal for strap sampling - { struct: "lc_strap", - type: "req_rsp", - name: "lc_pinmux_strap", - act: "rsp", - package: "pinmux_pkg", - default: "'0" + // Life cycle inputs + { struct: "lc_tx" + type: "uni" + name: "lc_hw_debug_en" + act: "rcv" + default: "lc_ctrl_pkg::Off" + package: "lc_ctrl_pkg" + } + { struct: "lc_tx" + type: "uni" + name: "lc_dft_en" + act: "rcv" + default: "lc_ctrl_pkg::Off" + package: "lc_ctrl_pkg" + } + // JTAG TAPs + { struct: "jtag" + type: "req_rsp" + name: "lc_jtag" + act: "req" + package: "jtag_pkg" + } + { struct: "jtag" + type: "req_rsp" + name: "rv_jtag" + act: "req" + package: "jtag_pkg" + } + { struct: "jtag" + type: "req_rsp" + name: "dft_jtag" + act: "req" + package: "jtag_pkg" } // Testmode signals to AST { struct: "dft_strap_test", @@ -62,6 +88,13 @@ package: "", default: "1'b0" }, + { struct: "logic", + type: "uni", + name: "strap_en", + act: "rcv", + package: "", + default: "1'b0" + }, { struct: "logic", type: "uni", name: "aon_wkup_req", diff --git a/hw/ip/pinmux/pinmux_component.core b/hw/ip/pinmux/pinmux_component.core index 82a29e8a67867..cb86fe8ee3370 100644 --- a/hw/ip/pinmux/pinmux_component.core +++ b/hw/ip/pinmux/pinmux_component.core @@ -10,6 +10,10 @@ filesets: depend: - lowrisc:ip:tlul - lowrisc:prim:all + - lowrisc:prim:clock_buf + - lowrisc:prim:buf + - lowrisc:prim:lc_sync + - lowrisc:ip:jtag_pkg - lowrisc:ip:usbdev # pinmux_wkup.sv depends on pinmux_reg_pkg.sv - "fileset_topgen ? (lowrisc:systems:topgen-reg-only)" @@ -18,6 +22,8 @@ filesets: - rtl/padring.sv - rtl/pinmux_pkg.sv - rtl/pinmux_wkup.sv + - rtl/pinmux_jtag_buf.sv + - rtl/pinmux_strap_sampling.sv - rtl/pinmux.sv file_type: systemVerilogSource diff --git a/hw/ip/pinmux/rtl/pinmux.sv b/hw/ip/pinmux/rtl/pinmux.sv index 2bb34a444fe50..44f6c5bfdcd56 100644 --- a/hw/ip/pinmux/rtl/pinmux.sv +++ b/hw/ip/pinmux/rtl/pinmux.sv @@ -19,12 +19,23 @@ module pinmux // Wakeup request, running on clk_aon_i output logic aon_wkup_req_o, output logic usb_wkup_req_o, - // Sleep enable, running on clk_i + // Sleep enable and strap sample enable + // from pwrmgr, running on clk_i + // TODO(#5198): figure out the connections. input sleep_en_i, - // Strap sample request - input lc_strap_req_t lc_pinmux_strap_i, - output lc_strap_rsp_t lc_pinmux_strap_o, + input strap_en_i, + // LC signals for TAP qualification + input lc_ctrl_pkg::lc_tx_t lc_dft_en_i, + input lc_ctrl_pkg::lc_tx_t lc_hw_debug_en_i, + // Sampled values for DFT straps output dft_strap_test_req_t dft_strap_test_o, + // Qualified JTAG signals for TAPs + output jtag_pkg::jtag_req_t lc_jtag_o, + input jtag_pkg::jtag_rsp_t lc_jtag_i, + output jtag_pkg::jtag_req_t rv_jtag_o, + input jtag_pkg::jtag_rsp_t rv_jtag_i, + output jtag_pkg::jtag_req_t dft_jtag_o, + input jtag_pkg::jtag_rsp_t dft_jtag_i, // Direct USB connection input usb_out_of_rst_i, input usb_aon_wake_en_i, @@ -103,7 +114,7 @@ module pinmux // Connect attributes // //////////////////////// - // TODO: rework the WARL behavior + // TODO(#5221): rework the WARL behavior for (genvar k = 0; k < NDioPads; k++) begin : gen_dio_attr logic [AttrDw-1:0] warl_mask; assign warl_mask = '0; @@ -296,7 +307,7 @@ module pinmux dio_data_mux[reg2hw.wkup_detector_padsel[k]] : mio_data_mux[reg2hw.wkup_detector_padsel[k]]; - pinmux_wkup i_pinmux_wkup ( + pinmux_wkup u_pinmux_wkup ( .clk_i, .rst_ni, .clk_aon_i, @@ -319,43 +330,25 @@ module pinmux // OR' together all wakeup requests assign aon_wkup_req_o = |aon_wkup_req; - //////////////////// - // Strap Sampling // - //////////////////// - - logic [NLcStraps-1:0] lc_strap_taps; - logic [NDFTStraps-1:0] dft_strap_taps; - lc_strap_rsp_t lc_strap_d, lc_strap_q; - dft_strap_test_req_t dft_strap_test_d, dft_strap_test_q; - - for (genvar k = 0; k < NLcStraps; k++) begin : gen_lc_strap_taps - assign lc_strap_taps[k] = mio_in_i[LcStrapPos[k]]; - end - - for (genvar k = 0; k < NDFTStraps; k++) begin : gen_dft_strap_taps - assign dft_strap_taps[k] = mio_in_i[DftStrapPos[k]]; - end - - assign lc_pinmux_strap_o = lc_strap_q; - assign lc_strap_d = (lc_pinmux_strap_i.sample_pulse) ? - '{valid: 1'b1, straps: lc_strap_taps} : - lc_strap_q; - - // DFT straps are triggered by the same LC sampling pulse - assign dft_strap_test_o = dft_strap_test_q; - assign dft_strap_test_d = (lc_pinmux_strap_i.sample_pulse) ? - '{valid: 1'b1, straps: dft_strap_taps} : - dft_strap_test_q; - - always_ff @(posedge clk_i or negedge rst_ni) begin : p_strap_sample - if (!rst_ni) begin - lc_strap_q <= '0; - dft_strap_test_q <= '0; - end else begin - lc_strap_q <= lc_strap_d; - dft_strap_test_q <= dft_strap_test_d; - end - end + ////////////////////////// + // Strap Sampling Logic // + ////////////////////////// + + pinmux_strap_sampling u_pinmux_strap_sampling ( + .clk_i, + .rst_ni, + .mio_in_i, + .strap_en_i, + .lc_dft_en_i, + .lc_hw_debug_en_i, + .dft_strap_test_o, + .lc_jtag_o, + .lc_jtag_i, + .rv_jtag_o, + .rv_jtag_i, + .dft_jtag_o, + .dft_jtag_i + ); //////////////// // Assertions // @@ -367,7 +360,6 @@ module pinmux `ASSERT_KNOWN(MioOeKnownO_A, mio_oe_o) // `ASSERT_KNOWN(DioToPeriphKnownO_A, dio_to_periph_o) `ASSERT_KNOWN(DioOeKnownO_A, dio_oe_o) - `ASSERT_KNOWN(LcPinmuxStrapKnownO_A, lc_pinmux_strap_o) // TODO: need to check why some outputs are not valid (e.g. SPI device SDO) // for (genvar k = 0; k < NMioPads; k++) begin : gen_mio_known_if @@ -381,6 +373,11 @@ module pinmux `ASSERT_KNOWN(MioKnownO_A, mio_attr_o) `ASSERT_KNOWN(DioKnownO_A, dio_attr_o) + `ASSERT_KNOWN(LcJtagKnown_A, lc_jtag_o) + `ASSERT_KNOWN(RvJtagKnown_A, rv_jtag_o) + `ASSERT_KNOWN(DftJtagKnown_A, dft_jtag_o) + `ASSERT_KNOWN(DftStrapsKnown_A, dft_strap_test_o) + // running on slow AON clock `ASSERT_KNOWN(AonWkupReqKnownO_A, aon_wkup_req_o, clk_aon_i, !rst_aon_ni) diff --git a/hw/ip/pinmux/rtl/pinmux_jtag_buf.sv b/hw/ip/pinmux/rtl/pinmux_jtag_buf.sv new file mode 100644 index 0000000000000..516e5725e707b --- /dev/null +++ b/hw/ip/pinmux/rtl/pinmux_jtag_buf.sv @@ -0,0 +1,37 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +module pinmux_jtag_buf ( + input jtag_pkg::jtag_req_t req_i, + output jtag_pkg::jtag_req_t req_o, + input jtag_pkg::jtag_rsp_t rsp_i, + output jtag_pkg::jtag_rsp_t rsp_o +); + + prim_clock_buf prim_clock_buf_tck ( + .clk_i(req_i.tck), + .clk_o(req_o.tck) + ); + prim_clock_buf prim_clock_buf_trst_n ( + .clk_i(req_i.trst_n), + .clk_o(req_o.trst_n) + ); + prim_buf prim_buf_tms ( + .in_i(req_i.tms), + .out_o(req_o.tms) + ); + prim_buf prim_buf_tdi ( + .in_i(req_i.tdi), + .out_o(req_o.tdi) + ); + prim_buf prim_buf_tdo ( + .in_i(rsp_i.tdo), + .out_o(rsp_o.tdo) + ); + prim_buf prim_buf_tdo_oe ( + .in_i(rsp_i.tdo_oe), + .out_o(rsp_o.tdo_oe) + ); + +endmodule : pinmux_jtag_buf diff --git a/hw/ip/pinmux/rtl/pinmux_pkg.sv b/hw/ip/pinmux/rtl/pinmux_pkg.sv index ac63a8a0030b0..b36d66a04b29d 100644 --- a/hw/ip/pinmux/rtl/pinmux_pkg.sv +++ b/hw/ip/pinmux/rtl/pinmux_pkg.sv @@ -25,18 +25,8 @@ package pinmux_pkg; } dft_strap_test_req_t; // Life cycle DFT straps for TAP select - parameter int NLcStraps = 2; + parameter int NTapStraps = 2; // Strap sampling is only supported on MIOs at the moment - parameter int LcStrapPos [NLcStraps] = '{1, 0}; - - // Interface with LC controller - typedef struct packed { - logic sample_pulse; - } lc_strap_req_t; - - typedef struct packed { - logic valid; - logic [NLcStraps-1:0] straps; - } lc_strap_rsp_t; + parameter int TapStrapPos [NTapStraps] = '{1, 0}; endpackage : pinmux_pkg diff --git a/hw/ip/pinmux/rtl/pinmux_strap_sampling.sv b/hw/ip/pinmux/rtl/pinmux_strap_sampling.sv new file mode 100644 index 0000000000000..e9e166405db1b --- /dev/null +++ b/hw/ip/pinmux/rtl/pinmux_strap_sampling.sv @@ -0,0 +1,223 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +module pinmux_strap_sampling + import pinmux_pkg::*; + import pinmux_reg_pkg::*; +( + input clk_i, + input rst_ni, + // MIO inputs. + // TODO(#5221): need tapped IOs for JTAG mux. + input logic [NMioPads-1:0] mio_in_i, + // Used for TAP qualification + input logic strap_en_i, + input lc_ctrl_pkg::lc_tx_t lc_dft_en_i, + input lc_ctrl_pkg::lc_tx_t lc_hw_debug_en_i, + // Sampled values for DFT straps + output dft_strap_test_req_t dft_strap_test_o, + // Qualified JTAG signals for TAPs + output jtag_pkg::jtag_req_t lc_jtag_o, + input jtag_pkg::jtag_rsp_t lc_jtag_i, + output jtag_pkg::jtag_req_t rv_jtag_o, + input jtag_pkg::jtag_rsp_t rv_jtag_i, + output jtag_pkg::jtag_req_t dft_jtag_o, + input jtag_pkg::jtag_rsp_t dft_jtag_i +); + + ///////////////////////////////////// + // Life cycle signal synchronizers // + ///////////////////////////////////// + + lc_ctrl_pkg::lc_tx_t [1:0] lc_hw_debug_en; + lc_ctrl_pkg::lc_tx_t [1:0] lc_dft_en; + prim_lc_sync #( + .NumCopies(2) + ) u_prim_lc_sync_rv ( + .clk_i, + .rst_ni, + .lc_en_i(lc_hw_debug_en_i), + .lc_en_o(lc_hw_debug_en) + ); + prim_lc_sync #( + .NumCopies(2) + ) u_prim_lc_sync_dft ( + .clk_i, + .rst_ni, + .lc_en_i(lc_dft_en_i), + .lc_en_o(lc_dft_en) + ); + + ////////////////////////// + // Strap Sampling Logic // + ////////////////////////// + + typedef enum logic [NTapStraps-1:0] { + FuncSel = 2'b00, + LcTapSel = 2'b01, + RvTapSel = 2'b10, + DftTapSel = 2'b11 + } tap_strap_t; + + logic strap_en_q; + logic dft_strap_valid_d, dft_strap_valid_q; + logic lc_strap_sample_en, rv_strap_sample_en, dft_strap_sample_en; + logic [1:0] tap_strap_sample_en; + logic [NTapStraps-1:0] tap_strap_d, tap_strap_q; + logic [NDFTStraps-1:0] dft_strap_d, dft_strap_q; + lc_ctrl_pkg::lc_tx_e continue_sampling_d, continue_sampling_q; + + // Not all MIOs are used. + logic unused_mio_in; + assign unused_mio_in = ^mio_in_i; + + // The LC strap at index 0 has a slightly different + // enable condition than the DFT strap at index 1. + for (genvar k = 0; k < NTapStraps; k++) begin : gen_lc_strap_taps + assign tap_strap_d[k] = (tap_strap_sample_en[k]) ? mio_in_i[TapStrapPos[k]] : tap_strap_q[k]; + end + + // We're always using the DFT strap sample enable for the DFT straps. + for (genvar k = 0; k < NDFTStraps; k++) begin : gen_dft_strap_taps + assign dft_strap_d[k] = (dft_strap_sample_en) ? mio_in_i[DftStrapPos[k]] : dft_strap_q[k]; + end + + assign dft_strap_valid_d = dft_strap_sample_en | dft_strap_valid_q; + assign dft_strap_test_o.valid = dft_strap_valid_q; + assign dft_strap_test_o.straps = dft_strap_q; + + assign tap_strap_sample_en = {rv_strap_sample_en, + lc_strap_sample_en}; + + always_comb begin : p_strap_sampling + lc_strap_sample_en = 1'b0; + rv_strap_sample_en = 1'b0; + dft_strap_sample_en = 1'b0; + continue_sampling_d = continue_sampling_q; + + // Initial strap sampling pulse from pwrmgr, + // qualified by life cycle signals. + if (strap_en_i || continue_sampling_q == lc_ctrl_pkg::On) begin + lc_strap_sample_en = 1'b1; + if (lc_hw_debug_en[0] == lc_ctrl_pkg::On) begin + rv_strap_sample_en = 1'b1; + end + if (lc_dft_en[0] == lc_ctrl_pkg::On) begin + dft_strap_sample_en = 1'b1; + end + end + + // In case DFT is enabled, and in case the TAP straps + // where not set to functional mode upon the first + // sampling event, we continue sampling all straps + // until system reset. This is used during the + // DFT-enabled life cycle states only. + if (lc_dft_en[0] == lc_ctrl_pkg::On) begin + if (strap_en_q && + tap_strap_t'(tap_strap_q) != FuncSel) begin + continue_sampling_d = lc_ctrl_pkg::On; + end + end + end + + always_ff @(posedge clk_i or negedge rst_ni) begin : p_strap_sample + if (!rst_ni) begin + tap_strap_q <= '0; + dft_strap_q <= '0; + strap_en_q <= 1'b0; + dft_strap_valid_q <= 1'b0; + continue_sampling_q <= lc_ctrl_pkg::Off; + end else begin + tap_strap_q <= tap_strap_d; + dft_strap_q <= dft_strap_d; + strap_en_q <= strap_en_i; + dft_strap_valid_q <= dft_strap_valid_d; + continue_sampling_q <= continue_sampling_d; + end + end + + //////////////////// + // TAP Selection // + //////////////////// + + jtag_pkg::jtag_req_t jtag_req, lc_jtag_req, rv_jtag_req, dft_jtag_req; + jtag_pkg::jtag_rsp_t jtag_rsp, lc_jtag_rsp, rv_jtag_rsp, dft_jtag_rsp; + + // TODO(#5221): need to mux this with the correct MIOs. + // But first, the jtag_mux from the chip level hierarchy needs + // to be pulled into pinmux, and the FPGA emulation and the simulation + // environments need to be adapted such that this does not break our + // regressions. + logic unused_jtag_rsp; + assign jtag_req = '0; + assign unused_jtag_rsp = ^jtag_rsp; + + // This muxes the JTAG signals to the correct TAP, based on the + // sampled straps. Further, the individual JTAG signals are gated + // using the corresponding life cycle signal. + tap_strap_t tap_strap; + assign tap_strap = tap_strap_t'(tap_strap_q); + `ASSERT_KNOWN(TapStrapKnown_A, tap_strap) + + always_comb begin : p_tap_mux + jtag_rsp = '0; + lc_jtag_req = '0; + rv_jtag_req = '0; + dft_jtag_req = '0; + + unique case (tap_strap) + LcTapSel: begin + lc_jtag_req = jtag_req; + jtag_rsp = lc_jtag_rsp; + end + RvTapSel: begin + if (lc_hw_debug_en[1] == lc_ctrl_pkg::On) begin + rv_jtag_req = jtag_req; + jtag_rsp = rv_jtag_rsp; + end + end + DftTapSel: begin + if (lc_dft_en[1] == lc_ctrl_pkg::On) begin + dft_jtag_req = jtag_req; + jtag_rsp = dft_jtag_rsp; + end + end + default: ; + endcase // tap_strap_t'(tap_strap_q) + end + + // Insert hand instantiated buffers for + // these signals to prevent further optimization. + pinmux_jtag_buf u_pinmux_jtag_buf_lc ( + .req_i(lc_jtag_req), + .req_o(lc_jtag_o), + .rsp_i(lc_jtag_i), + .rsp_o(lc_jtag_rsp) + ); + pinmux_jtag_buf u_pinmux_jtag_buf_rv ( + .req_i(rv_jtag_req), + .req_o(rv_jtag_o), + .rsp_i(rv_jtag_i), + .rsp_o(rv_jtag_rsp) + ); + pinmux_jtag_buf u_pinmux_jtag_buf_dft ( + .req_i(dft_jtag_req), + .req_o(dft_jtag_o), + .rsp_i(dft_jtag_i), + .rsp_o(dft_jtag_rsp) + ); + + //////////////// + // Assertions // + //////////////// + + // The strap sampling enable input shall be pulsed high exactly once after cold boot. + `ASSERT(PwrMgrStrapSampleOnce_A, strap_en_i |=> ##0 !strap_en_i [*]) + + `ASSERT(RvTapOff0_A, lc_hw_debug_en_i == lc_ctrl_pkg::Off |-> ##2 rv_jtag_o == '0) + `ASSERT(RvTapOff1_A, lc_hw_debug_en_i == lc_ctrl_pkg::Off |-> ##2 rv_jtag_i == '0) + `ASSERT(DftTapOff0_A, lc_dft_en_i == lc_ctrl_pkg::Off |-> ##2 dft_jtag_o == '0) + `ASSERT(DftTapOff1_A, lc_dft_en_i == lc_ctrl_pkg::Off |-> ##2 dft_jtag_i == '0) + +endmodule : pinmux_strap_sampling diff --git a/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson b/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson index a008dd6991eba..fdcf909b8aed0 100644 --- a/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson +++ b/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson @@ -3218,6 +3218,9 @@ act: rsp package: jtag_pkg inst_name: lc_ctrl + width: 1 + default: "" + top_signame: pinmux_aon_lc_jtag index: -1 } { @@ -4359,12 +4362,57 @@ inter_signal_list: [ { - struct: lc_strap + struct: lc_tx + type: uni + name: lc_hw_debug_en + act: rcv + default: lc_ctrl_pkg::Off + package: lc_ctrl_pkg + inst_name: pinmux_aon + width: 1 + top_signame: lc_ctrl_lc_hw_debug_en + index: -1 + } + { + struct: lc_tx + type: uni + name: lc_dft_en + act: rcv + default: lc_ctrl_pkg::Off + package: lc_ctrl_pkg + inst_name: pinmux_aon + width: 1 + top_signame: lc_ctrl_lc_dft_en + index: -1 + } + { + struct: jtag type: req_rsp - name: lc_pinmux_strap - act: rsp - package: pinmux_pkg - default: "'0" + name: lc_jtag + act: req + package: jtag_pkg + inst_name: pinmux_aon + width: 1 + default: "" + end_idx: -1 + top_signame: pinmux_aon_lc_jtag + index: -1 + } + { + struct: jtag + type: req_rsp + name: rv_jtag + act: req + package: jtag_pkg + inst_name: pinmux_aon + index: -1 + } + { + struct: jtag + type: req_rsp + name: dft_jtag + act: req + package: jtag_pkg inst_name: pinmux_aon index: -1 } @@ -4388,6 +4436,16 @@ inst_name: pinmux_aon index: -1 } + { + struct: logic + type: uni + name: strap_en + act: rcv + package: "" + default: 1'b0 + inst_name: pinmux_aon + index: -1 + } { struct: logic type: uni @@ -7590,6 +7648,10 @@ kmac.idle otbn.idle ] + pinmux_aon.lc_jtag: + [ + lc_ctrl.jtag + ] otp_ctrl.otp_lc_data: [ lc_ctrl.otp_lc_data @@ -7616,6 +7678,7 @@ lc_ctrl.lc_dft_en: [ otp_ctrl.lc_dft_en + pinmux_aon.lc_dft_en ] lc_ctrl.lc_nvm_debug_en: [ @@ -7625,6 +7688,7 @@ [ sram_ctrl_main.lc_hw_debug_en sram_ctrl_ret_aon.lc_hw_debug_en + pinmux_aon.lc_hw_debug_en ] lc_ctrl.lc_cpu_en: [] lc_ctrl.lc_escalate_en: @@ -12715,6 +12779,9 @@ act: rsp package: jtag_pkg inst_name: lc_ctrl + width: 1 + default: "" + top_signame: pinmux_aon_lc_jtag index: -1 } { @@ -13544,12 +13611,57 @@ index: -1 } { - struct: lc_strap + struct: lc_tx + type: uni + name: lc_hw_debug_en + act: rcv + default: lc_ctrl_pkg::Off + package: lc_ctrl_pkg + inst_name: pinmux_aon + width: 1 + top_signame: lc_ctrl_lc_hw_debug_en + index: -1 + } + { + struct: lc_tx + type: uni + name: lc_dft_en + act: rcv + default: lc_ctrl_pkg::Off + package: lc_ctrl_pkg + inst_name: pinmux_aon + width: 1 + top_signame: lc_ctrl_lc_dft_en + index: -1 + } + { + struct: jtag type: req_rsp - name: lc_pinmux_strap - act: rsp - package: pinmux_pkg - default: "'0" + name: lc_jtag + act: req + package: jtag_pkg + inst_name: pinmux_aon + width: 1 + default: "" + end_idx: -1 + top_signame: pinmux_aon_lc_jtag + index: -1 + } + { + struct: jtag + type: req_rsp + name: rv_jtag + act: req + package: jtag_pkg + inst_name: pinmux_aon + index: -1 + } + { + struct: jtag + type: req_rsp + name: dft_jtag + act: req + package: jtag_pkg inst_name: pinmux_aon index: -1 } @@ -13573,6 +13685,16 @@ inst_name: pinmux_aon index: -1 } + { + struct: logic + type: uni + name: strap_en + act: rcv + package: "" + default: 1'b0 + inst_name: pinmux_aon + index: -1 + } { struct: logic type: uni @@ -16272,6 +16394,28 @@ suffix: "" default: "" } + { + package: jtag_pkg + struct: jtag_req + signame: pinmux_aon_lc_jtag_req + width: 1 + type: req_rsp + end_idx: -1 + act: req + suffix: req + default: "" + } + { + package: jtag_pkg + struct: jtag_rsp + signame: pinmux_aon_lc_jtag_rsp + width: 1 + type: req_rsp + end_idx: -1 + act: req + suffix: rsp + default: "" + } { package: otp_ctrl_pkg struct: otp_lc_data diff --git a/hw/top_earlgrey/data/top_earlgrey.hjson b/hw/top_earlgrey/data/top_earlgrey.hjson index 59d78ac92a7f9..e14b7cd4fef61 100755 --- a/hw/top_earlgrey/data/top_earlgrey.hjson +++ b/hw/top_earlgrey/data/top_earlgrey.hjson @@ -755,6 +755,15 @@ // an empty list. 'clkmgr_aon.idle' : [], + // Pinmux JTAG signals + // Note that the DFT TAP will be connected + // automatically by the DFT insertion tool, + // hence it does not have to be connected here. + 'pinmux_aon.lc_jtag' : ['lc_ctrl.jtag'], + // TODO: connect this once JTAG muxing is functional + // and also works on FPGA. + //'pinmux_aon.rv_jtag' : ['rv_dm.jtag'], + // OTP LC interface 'otp_ctrl.otp_lc_data' : ['lc_ctrl.otp_lc_data'], 'lc_ctrl.lc_otp_program' : ['otp_ctrl.lc_otp_program'], @@ -769,10 +778,12 @@ // LC function control signal broadcast // TODO(#3920): connect all these signals once top-level sim and FPGA can backload LC state - 'lc_ctrl.lc_dft_en' : ['otp_ctrl.lc_dft_en'], + 'lc_ctrl.lc_dft_en' : ['otp_ctrl.lc_dft_en', + 'pinmux_aon.lc_dft_en'], 'lc_ctrl.lc_nvm_debug_en' : ['eflash.lc_nvm_debug_en'], 'lc_ctrl.lc_hw_debug_en' : ['sram_ctrl_main.lc_hw_debug_en', - 'sram_ctrl_ret_aon.lc_hw_debug_en'], + 'sram_ctrl_ret_aon.lc_hw_debug_en', + 'pinmux_aon.lc_hw_debug_en'], 'lc_ctrl.lc_cpu_en' : [], //'lc_ctrl.lc_keymgr_en' : ['keymgr.lc_keymgr_en'], 'lc_ctrl.lc_escalate_en' : ['otp_ctrl.lc_escalate_en', diff --git a/hw/top_earlgrey/ip/pinmux/data/autogen/pinmux.hjson b/hw/top_earlgrey/ip/pinmux/data/autogen/pinmux.hjson index fd408b662c6d4..a4a07abde9eba 100644 --- a/hw/top_earlgrey/ip/pinmux/data/autogen/pinmux.hjson +++ b/hw/top_earlgrey/ip/pinmux/data/autogen/pinmux.hjson @@ -34,13 +34,39 @@ ], inter_signal_list: [ - // Define lc <-> pinmux signal for strap sampling - { struct: "lc_strap", - type: "req_rsp", - name: "lc_pinmux_strap", - act: "rsp", - package: "pinmux_pkg", - default: "'0" + // Life cycle inputs + { struct: "lc_tx" + type: "uni" + name: "lc_hw_debug_en" + act: "rcv" + default: "lc_ctrl_pkg::Off" + package: "lc_ctrl_pkg" + } + { struct: "lc_tx" + type: "uni" + name: "lc_dft_en" + act: "rcv" + default: "lc_ctrl_pkg::Off" + package: "lc_ctrl_pkg" + } + // JTAG TAPs + { struct: "jtag" + type: "req_rsp" + name: "lc_jtag" + act: "req" + package: "jtag_pkg" + } + { struct: "jtag" + type: "req_rsp" + name: "rv_jtag" + act: "req" + package: "jtag_pkg" + } + { struct: "jtag" + type: "req_rsp" + name: "dft_jtag" + act: "req" + package: "jtag_pkg" } // Testmode signals to AST { struct: "dft_strap_test", @@ -58,6 +84,13 @@ package: "", default: "1'b0" }, + { struct: "logic", + type: "uni", + name: "strap_en", + act: "rcv", + package: "", + default: "1'b0" + }, { struct: "logic", type: "uni", name: "aon_wkup_req", diff --git a/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv b/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv index d1093a094bc71..241a51c56d4b0 100644 --- a/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv +++ b/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv @@ -440,6 +440,8 @@ module top_earlgrey #( keymgr_pkg::kmac_data_req_t keymgr_kmac_data_req; keymgr_pkg::kmac_data_rsp_t keymgr_kmac_data_rsp; logic [3:0] clkmgr_aon_idle; + jtag_pkg::jtag_req_t pinmux_aon_lc_jtag_req; + jtag_pkg::jtag_rsp_t pinmux_aon_lc_jtag_rsp; otp_ctrl_pkg::otp_lc_data_t otp_ctrl_otp_lc_data; otp_ctrl_pkg::lc_otp_program_req_t lc_ctrl_lc_otp_program_req; otp_ctrl_pkg::lc_otp_program_rsp_t lc_ctrl_lc_otp_program_rsp; @@ -1419,8 +1421,8 @@ module top_earlgrey #( .alert_rx_i ( alert_rx[3:2] ), // Inter-module signals - .jtag_i(jtag_pkg::JTAG_REQ_DEFAULT), - .jtag_o(), + .jtag_i(pinmux_aon_lc_jtag_req), + .jtag_o(pinmux_aon_lc_jtag_rsp), .esc_wipe_secrets_tx_i(alert_handler_esc_tx[1]), .esc_wipe_secrets_rx_o(alert_handler_esc_rx[1]), .esc_scrap_state_tx_i(alert_handler_esc_tx[2]), @@ -1581,10 +1583,17 @@ module top_earlgrey #( pinmux u_pinmux_aon ( // Inter-module signals - .lc_pinmux_strap_i('0), - .lc_pinmux_strap_o(), + .lc_hw_debug_en_i(lc_ctrl_lc_hw_debug_en), + .lc_dft_en_i(lc_ctrl_lc_dft_en), + .lc_jtag_o(pinmux_aon_lc_jtag_req), + .lc_jtag_i(pinmux_aon_lc_jtag_rsp), + .rv_jtag_o(), + .rv_jtag_i(jtag_pkg::JTAG_RSP_DEFAULT), + .dft_jtag_o(), + .dft_jtag_i(jtag_pkg::JTAG_RSP_DEFAULT), .dft_strap_test_o(), .sleep_en_i(1'b0), + .strap_en_i(1'b0), .aon_wkup_req_o(pwrmgr_aon_wakeups[0]), .usb_wkup_req_o(pwrmgr_aon_wakeups[1]), .usb_out_of_rst_i(usbdev_usb_out_of_rst),