[pinmux] Move JTAG muxing into pinmux strap sample logic
Signed-off-by: Michael Schaffner <msf@opentitan.org>
diff --git a/hw/ip/pinmux/data/pinmux.hjson b/hw/ip/pinmux/data/pinmux.hjson
index d448948..35d9087 100644
--- a/hw/ip/pinmux/data/pinmux.hjson
+++ b/hw/ip/pinmux/data/pinmux.hjson
@@ -212,6 +212,17 @@
default: "0",
local: "true"
},
+ // Since the target-specific top-levels often have slightly
+ // different debug signal positions, we need a way to pass
+ // this info from the target specific top-level into the pinmux
+ // logic. The parameter struct below serves this purpose.
+ { name: "TargetCfg",
+ desc: "Target specific pinmux configuration.",
+ type: "pinmux_pkg::target_cfg_t",
+ default: "pinmux_pkg::DefaultTargetCfg",
+ local: "false",
+ expose: "true"
+ },
],
registers: [
//////////////////////////
diff --git a/hw/ip/pinmux/data/pinmux.hjson.tpl b/hw/ip/pinmux/data/pinmux.hjson.tpl
index fbf3ee6..08a210c 100644
--- a/hw/ip/pinmux/data/pinmux.hjson.tpl
+++ b/hw/ip/pinmux/data/pinmux.hjson.tpl
@@ -224,6 +224,17 @@
default: "${usb_dn_pull_sel}",
local: "true"
},
+ // Since the target-specific top-levels often have slightly
+ // different debug signal positions, we need a way to pass
+ // this info from the target specific top-level into the pinmux
+ // logic. The parameter struct below serves this purpose.
+ { name: "TargetCfg",
+ desc: "Target specific pinmux configuration.",
+ type: "pinmux_pkg::target_cfg_t",
+ default: "pinmux_pkg::DefaultTargetCfg",
+ local: "false",
+ expose: "true"
+ },
],
registers: [
//////////////////////////
diff --git a/hw/ip/pinmux/rtl/pinmux.sv b/hw/ip/pinmux/rtl/pinmux.sv
index c3d5d04..78aa55f 100644
--- a/hw/ip/pinmux/rtl/pinmux.sv
+++ b/hw/ip/pinmux/rtl/pinmux.sv
@@ -10,7 +10,11 @@
module pinmux
import pinmux_pkg::*;
import pinmux_reg_pkg::*;
-(
+#(
+ // Taget-specific pinmux configuration passed down from the
+ // target-specific top-level.
+ parameter target_cfg_t TargetCfg = DefaultTargetCfg
+) (
input clk_i,
input rst_ni,
// Slow always-on clock
@@ -131,6 +135,44 @@
end
+ //////////////////////////
+ // Strap Sampling Logic //
+ //////////////////////////
+
+ // Local versions of the input signals
+ logic [NMioPads-1:0] mio_out, mio_oe, mio_in;
+ logic [NDioPads-1:0] dio_out, dio_oe, dio_in;
+
+ // This module contains the strap sampling and JTAG mux.
+ // Affected inputs are intercepted/tapped before they go to the pinmux
+ // matrix. Likewise, affected outputs are intercepted/tapped after the
+ // retention registers.
+ pinmux_strap_sampling #(
+ .TargetCfg (TargetCfg)
+ ) u_pinmux_strap_sampling (
+ .clk_i,
+ .rst_ni,
+ // To padring side
+ .out_padring_o ( {dio_out_o, mio_out_o} ),
+ .oe_padring_o ( {dio_oe_o , mio_oe_o } ),
+ .in_padring_i ( {dio_in_i , mio_in_i } ),
+ // To core side
+ .out_core_i ( {dio_out, mio_out} ),
+ .oe_core_i ( {dio_oe, mio_oe} ),
+ .in_core_o ( {dio_in, mio_in} ),
+ // Strap and JTAG signals
+ .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
+ );
+
///////////////////////////////////////
// USB wake detect module connection //
///////////////////////////////////////
@@ -209,14 +251,14 @@
localparam int AlignedMuxSize = (NMioPads + 2 > NDioPads) ? 2**$clog2(NMioPads + 2) :
2**$clog2(NDioPads);
- // stack input and default signals for convenient indexing below possible defaults: constant 0 or
- // 1. make sure mux is aligned to a power of 2 to avoid Xes.
- logic [AlignedMuxSize-1:0] mio_data_mux;
- assign mio_data_mux = AlignedMuxSize'({mio_in_i, 1'b1, 1'b0});
+ // stack input and default signals for convenient indexing below possible defaults:
+ // constant 0 or 1. make sure mux is aligned to a power of 2 to avoid Xes.
+ logic [AlignedMuxSize-1:0] mio_mux;
+ assign mio_mux = AlignedMuxSize'({mio_in, 1'b1, 1'b0});
for (genvar k = 0; k < NMioPeriphIn; k++) begin : gen_mio_periph_in
// index using configured insel
- assign mio_to_periph_o[k] = mio_data_mux[reg2hw.mio_periph_insel[k].q];
+ assign mio_to_periph_o[k] = mio_mux[reg2hw.mio_periph_insel[k].q];
end
//////////////////////
@@ -231,13 +273,13 @@
for (genvar k = 0; k < NMioPads; k++) begin : gen_mio_out
// Check individual sleep enable status bits
- assign mio_out_o[k] = reg2hw.mio_pad_sleep_status[k].q ?
- mio_out_retreg_q[k] :
- periph_data_mux[reg2hw.mio_outsel[k].q];
+ assign mio_out[k] = reg2hw.mio_pad_sleep_status[k].q ?
+ mio_out_retreg_q[k] :
+ periph_data_mux[reg2hw.mio_outsel[k].q];
- assign mio_oe_o[k] = reg2hw.mio_pad_sleep_status[k].q ?
- mio_oe_retreg_q[k] :
- periph_oe_mux[reg2hw.mio_outsel[k].q];
+ assign mio_oe[k] = reg2hw.mio_pad_sleep_status[k].q ?
+ mio_oe_retreg_q[k] :
+ periph_oe_mux[reg2hw.mio_outsel[k].q];
// latch state when going to sleep
// 0: drive low
@@ -246,11 +288,11 @@
// 3: previous value
assign mio_out_retreg_d[k] = (reg2hw.mio_pad_sleep_mode[k].q == 0) ? 1'b0 :
(reg2hw.mio_pad_sleep_mode[k].q == 1) ? 1'b1 :
- (reg2hw.mio_pad_sleep_mode[k].q == 2) ? 1'b0 : mio_out_o[k];
+ (reg2hw.mio_pad_sleep_mode[k].q == 2) ? 1'b0 : mio_out[k];
assign mio_oe_retreg_d[k] = (reg2hw.mio_pad_sleep_mode[k].q == 0) ? 1'b1 :
(reg2hw.mio_pad_sleep_mode[k].q == 1) ? 1'b1 :
- (reg2hw.mio_pad_sleep_mode[k].q == 2) ? 1'b0 : mio_oe_o[k];
+ (reg2hw.mio_pad_sleep_mode[k].q == 2) ? 1'b0 : mio_oe[k];
// Activate sleep behavior only if it has been enabled
assign mio_sleep_trig[k] = reg2hw.mio_pad_sleep_en[k].q & sleep_trig;
@@ -263,17 +305,17 @@
/////////////////////
// Inputs are just fed through
- assign dio_to_periph_o = dio_in_i;
+ assign dio_to_periph_o = dio_in;
for (genvar k = 0; k < NDioPads; k++) begin : gen_dio_out
// Check individual sleep enable status bits
- assign dio_out_o[k] = reg2hw.dio_pad_sleep_status[k].q ?
- dio_out_retreg_q[k] :
- periph_to_dio_i[k];
+ assign dio_out[k] = reg2hw.dio_pad_sleep_status[k].q ?
+ dio_out_retreg_q[k] :
+ periph_to_dio_i[k];
- assign dio_oe_o[k] = reg2hw.dio_pad_sleep_status[k].q ?
- dio_oe_retreg_q[k] :
- periph_to_dio_oe_i[k];
+ assign dio_oe[k] = reg2hw.dio_pad_sleep_status[k].q ?
+ dio_oe_retreg_q[k] :
+ periph_to_dio_oe_i[k];
// latch state when going to sleep
// 0: drive low
@@ -282,11 +324,11 @@
// 3: previous value
assign dio_out_retreg_d[k] = (reg2hw.dio_pad_sleep_mode[k].q == 0) ? 1'b0 :
(reg2hw.dio_pad_sleep_mode[k].q == 1) ? 1'b1 :
- (reg2hw.dio_pad_sleep_mode[k].q == 2) ? 1'b0 : dio_out_o[k];
+ (reg2hw.dio_pad_sleep_mode[k].q == 2) ? 1'b0 : dio_out[k];
assign dio_oe_retreg_d[k] = (reg2hw.dio_pad_sleep_mode[k].q == 0) ? 1'b1 :
(reg2hw.dio_pad_sleep_mode[k].q == 1) ? 1'b1 :
- (reg2hw.dio_pad_sleep_mode[k].q == 2) ? 1'b0 : dio_oe_o[k];
+ (reg2hw.dio_pad_sleep_mode[k].q == 2) ? 1'b0 : dio_oe[k];
// Activate sleep behavior only if it has been enabled
assign dio_sleep_trig[k] = reg2hw.dio_pad_sleep_en[k].q & sleep_trig;
@@ -298,15 +340,20 @@
// Wakeup detectors //
//////////////////////
- logic [AlignedMuxSize-1:0] dio_data_mux;
- assign dio_data_mux = AlignedMuxSize'(dio_in_i);
+ // Wakeup detector taps are not affected by JTAG/strap
+ // selection mux. I.e., we always sample the unmuxed inputs
+ // that come directly from the pads.
+ logic [AlignedMuxSize-1:0] dio_wkup_mux;
+ logic [AlignedMuxSize-1:0] mio_wkup_mux;
+ assign dio_wkup_mux = AlignedMuxSize'(dio_in_i);
+ assign mio_wkup_mux = AlignedMuxSize'(mio_in_i);
logic [NWkupDetect-1:0] aon_wkup_req;
for (genvar k = 0; k < NWkupDetect; k++) begin : gen_wkup_detect
logic pin_value;
assign pin_value = (reg2hw.wkup_detector[k].miodio.q) ?
- dio_data_mux[reg2hw.wkup_detector_padsel[k]] :
- mio_data_mux[reg2hw.wkup_detector_padsel[k]];
+ dio_wkup_mux[reg2hw.wkup_detector_padsel[k]] :
+ mio_wkup_mux[reg2hw.wkup_detector_padsel[k]];
pinmux_wkup u_pinmux_wkup (
.clk_i,
@@ -331,26 +378,6 @@
// OR' together all wakeup requests
assign aon_wkup_req_o = |aon_wkup_req;
- //////////////////////////
- // 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 //
////////////////
@@ -374,9 +401,18 @@
`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(LcJtagTckKnown_A, lc_jtag_o.tck)
+ `ASSERT_KNOWN(LcJtagTrstKnown_A, lc_jtag_o.trst_n)
+ `ASSERT_KNOWN(LcJtagTmsKnown_A, lc_jtag_o.tms)
+
+ `ASSERT_KNOWN(RvJtagTckKnown_A, rv_jtag_o.tck)
+ `ASSERT_KNOWN(RvJtagTrstKnown_A, rv_jtag_o.trst_n)
+ `ASSERT_KNOWN(RvJtagTmsKnown_A, rv_jtag_o.tms)
+
+ `ASSERT_KNOWN(DftJtagTckKnown_A, dft_jtag_o.tck)
+ `ASSERT_KNOWN(DftJtagTrstKnown_A, dft_jtag_o.trst_n)
+ `ASSERT_KNOWN(DftJtagTmsKnown_A, dft_jtag_o.tms)
+
`ASSERT_KNOWN(DftStrapsKnown_A, dft_strap_test_o)
// running on slow AON clock
diff --git a/hw/ip/pinmux/rtl/pinmux_jtag_buf.sv b/hw/ip/pinmux/rtl/pinmux_jtag_buf.sv
index 516e572..d3b6dfa 100644
--- a/hw/ip/pinmux/rtl/pinmux_jtag_buf.sv
+++ b/hw/ip/pinmux/rtl/pinmux_jtag_buf.sv
@@ -13,9 +13,9 @@
.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_trst_n (
+ .in_i(req_i.trst_n),
+ .out_o(req_o.trst_n)
);
prim_buf prim_buf_tms (
.in_i(req_i.tms),
diff --git a/hw/ip/pinmux/rtl/pinmux_pkg.sv b/hw/ip/pinmux/rtl/pinmux_pkg.sv
index b36d66a..2c16eac 100644
--- a/hw/ip/pinmux/rtl/pinmux_pkg.sv
+++ b/hw/ip/pinmux/rtl/pinmux_pkg.sv
@@ -4,6 +4,44 @@
package pinmux_pkg;
+ import pinmux_reg_pkg::*;
+
+ parameter int NumIOs = NMioPads + NDioPads;
+ parameter int NDFTStraps = 2;
+ parameter int NTapStraps = 2;
+
+ // Since the target-specific top-levels often have slightly different debug signal positions, we
+ // need a way to pass this info from the target specific top-level into the pinmux logic. The
+ // datastructure below serves this purpose. Note that all the indices below are with respect to
+ // the concatenated {DIO, MIO} packed array.
+ typedef struct packed {
+ bit const_sampling; // TODO: check whether this can be eliminated.
+ logic [NumIOs-1:0] tie_offs; // TODO: check whether this can be eliminated.
+ int tck_idx;
+ int tms_idx;
+ int trst_idx;
+ int tdi_idx;
+ int tdo_idx;
+ int tap_strap0_idx;
+ int tap_strap1_idx;
+ int dft_strap0_idx;
+ int dft_strap1_idx;
+ } target_cfg_t;
+
+ parameter target_cfg_t DefaultTargetCfg = '{
+ const_sampling: 1'b0,
+ tie_offs: '0,
+ tck_idx: 0,
+ tms_idx: 0,
+ trst_idx: 0,
+ tdi_idx: 0,
+ tdo_idx: 0,
+ tap_strap0_idx: 0,
+ tap_strap1_idx: 0,
+ dft_strap0_idx: 0,
+ dft_strap1_idx: 0
+ };
+
// Wakeup Detector Modes
typedef enum logic [2:0] {
Posedge = 3'b000,
@@ -13,20 +51,17 @@
LowTimed = 3'b100
} wkup_mode_e;
- // DFT Test Mode straps
- parameter int NDFTStraps = 2;
- // Strap sampling is only supported on MIOs at the moment
- parameter int DftStrapPos [NDFTStraps] = '{3, 2};
-
// Interface with LC controller
typedef struct packed {
logic valid;
logic [NDFTStraps-1:0] straps;
} dft_strap_test_req_t;
- // Life cycle DFT straps for TAP select
- parameter int NTapStraps = 2;
- // Strap sampling is only supported on MIOs at the moment
- parameter int TapStrapPos [NTapStraps] = '{1, 0};
+ typedef enum logic [NTapStraps-1:0] {
+ FuncSel = 2'b00,
+ LcTapSel = 2'b01,
+ RvTapSel = 2'b10,
+ DftTapSel = 2'b11
+ } tap_strap_t;
endpackage : pinmux_pkg
diff --git a/hw/ip/pinmux/rtl/pinmux_strap_sampling.sv b/hw/ip/pinmux/rtl/pinmux_strap_sampling.sv
index e9e1664..2fcc9b3 100644
--- a/hw/ip/pinmux/rtl/pinmux_strap_sampling.sv
+++ b/hw/ip/pinmux/rtl/pinmux_strap_sampling.sv
@@ -5,12 +5,21 @@
module pinmux_strap_sampling
import pinmux_pkg::*;
import pinmux_reg_pkg::*;
-(
+#(
+ // Taget-specific pinmux configuration passed down from the
+ // target-specific top-level.
+ parameter target_cfg_t TargetCfg = DefaultTargetCfg
+) (
input clk_i,
input rst_ni,
- // MIO inputs.
- // TODO(#5221): need tapped IOs for JTAG mux.
- input logic [NMioPads-1:0] mio_in_i,
+ // To padring side
+ output logic [NumIOs-1:0] out_padring_o,
+ output logic [NumIOs-1:0] oe_padring_o,
+ input logic [NumIOs-1:0] in_padring_i,
+ // To core side
+ input logic [NumIOs-1:0] out_core_i,
+ input logic [NumIOs-1:0] oe_core_i,
+ output logic [NumIOs-1:0] in_core_o,
// Used for TAP qualification
input logic strap_en_i,
input lc_ctrl_pkg::lc_tx_t lc_dft_en_i,
@@ -53,42 +62,29 @@
// 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
+ assign tap_strap_d[0] = (lc_strap_sample_en) ? in_padring_i[TargetCfg.tap_strap0_idx] :
+ tap_strap_q[0];
+ assign tap_strap_d[1] = (rv_strap_sample_en) ? in_padring_i[TargetCfg.tap_strap1_idx] :
+ tap_strap_q[1];
// 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_d = (dft_strap_sample_en) ? {in_padring_i[TargetCfg.dft_strap1_idx],
+ in_padring_i[TargetCfg.dft_strap0_idx]} :
+ dft_strap_q;
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;
@@ -119,6 +115,11 @@
continue_sampling_d = lc_ctrl_pkg::On;
end
end
+ // TODO: this can currently be overridden with a parameter for legacy reasons.
+ // This parameter will be removed in the future.
+ if (TargetCfg.const_sampling) begin
+ continue_sampling_d = lc_ctrl_pkg::On;
+ end
end
always_ff @(posedge clk_i or negedge rst_ni) begin : p_strap_sample
@@ -137,50 +138,49 @@
end
end
- ////////////////////
- // TAP Selection //
- ////////////////////
+ ///////////////////////
+ // TAP Selection Mux //
+ ///////////////////////
+ logic jtag_en;
+ tap_strap_t tap_strap;
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;
+ // Note that this holds the JTAGs in reset
+ // when they are not selected.
lc_jtag_req = '0;
rv_jtag_req = '0;
dft_jtag_req = '0;
+ // This activates the TDO override further below.
+ jtag_en = 1'b0;
unique case (tap_strap)
LcTapSel: begin
lc_jtag_req = jtag_req;
- jtag_rsp = lc_jtag_rsp;
+ jtag_rsp = lc_jtag_rsp;
+ jtag_en = 1'b1;
end
RvTapSel: begin
if (lc_hw_debug_en[1] == lc_ctrl_pkg::On) begin
rv_jtag_req = jtag_req;
- jtag_rsp = rv_jtag_rsp;
+ jtag_rsp = rv_jtag_rsp;
+ jtag_en = 1'b1;
end
end
DftTapSel: begin
if (lc_dft_en[1] == lc_ctrl_pkg::On) begin
dft_jtag_req = jtag_req;
- jtag_rsp = dft_jtag_rsp;
+ jtag_rsp = dft_jtag_rsp;
+ jtag_en = 1'b1;
end
end
default: ;
@@ -208,15 +208,64 @@
.rsp_o(dft_jtag_rsp)
);
+ //////////////////////
+ // TAP Input Muxes //
+ //////////////////////
+
+ // Inputs connections
+ assign jtag_req.tck = in_padring_i[TargetCfg.tck_idx];
+ assign jtag_req.tms = in_padring_i[TargetCfg.tms_idx];
+ assign jtag_req.trst_n = in_padring_i[TargetCfg.trst_idx];
+ assign jtag_req.tdi = in_padring_i[TargetCfg.tdi_idx];
+
+ // Input tie-off muxes
+ for (genvar k = 0; k < NumIOs; k++) begin : gen_input_tie_off
+ if (k == TargetCfg.tck_idx ||
+ k == TargetCfg.tms_idx ||
+ k == TargetCfg.trst_idx ||
+ k == TargetCfg.tdi_idx ||
+ k == TargetCfg.tdo_idx) begin : gen_jtag_signal
+ assign in_core_o[k] = (jtag_en) ? TargetCfg.tie_offs[k] : in_padring_i[k];
+ end else begin : gen_other_inputs
+ assign in_core_o[k] = in_padring_i[k];
+ end
+ end
+
+ // Override TDO output
+ for (genvar k = 0; k < NumIOs; k++) begin : gen_output_mux
+ if (k == TargetCfg.tdo_idx) begin : gen_tdo
+ assign out_padring_o[k] = (jtag_en) ? jtag_rsp.tdo : out_core_i[k];
+ assign oe_padring_o[k] = (jtag_en) ? jtag_rsp.tdo_oe : oe_core_i[k];
+ end else begin : gen_other_outputs
+ assign out_padring_o[k] = out_core_i[k];
+ assign oe_padring_o[k] = oe_core_i[k];
+ end
+ end
+
////////////////
// Assertions //
////////////////
+ `ASSERT_INIT(tck_idxRange_A, TargetCfg.tck_idx >= 0 && TargetCfg.tck_idx < NumIOs)
+ `ASSERT_INIT(tms_idxRange_A, TargetCfg.tms_idx >= 0 && TargetCfg.tms_idx < NumIOs)
+ `ASSERT_INIT(trst_idxRange_A, TargetCfg.trst_idx >= 0 && TargetCfg.trst_idx < NumIOs)
+ `ASSERT_INIT(tdi_idxRange_A, TargetCfg.tdi_idx >= 0 && TargetCfg.tdi_idx < NumIOs)
+ `ASSERT_INIT(tdo_idxRange_A, TargetCfg.tdo_idx >= 0 && TargetCfg.tdo_idx < NumIOs)
+
+ `ASSERT_INIT(tap_strap0_idxRange_A, TargetCfg.tap_strap0_idx >= 0 &&
+ TargetCfg.tap_strap0_idx < NumIOs)
+ `ASSERT_INIT(tap_strap1_idxRange_A, TargetCfg.tap_strap1_idx >= 0 &&
+ TargetCfg.tap_strap1_idx < NumIOs)
+ `ASSERT_INIT(dft_strap0_idxRange_A, TargetCfg.dft_strap0_idx >= 0 &&
+ TargetCfg.dft_strap0_idx < NumIOs)
+ `ASSERT_INIT(dft_strap1_idxRange_A, TargetCfg.dft_strap1_idx >= 0 &&
+ TargetCfg.dft_strap1_idx < NumIOs)
+
// 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(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)