../src/lowrisc_ip_padctrl_component_0.1/rtl/jtag_mux.sv Cov: 100%
1: // Copyright lowRISC contributors.
2: // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3: // SPDX-License-Identifier: Apache-2.0
4: //
5: // JTAG mux. Taps out JTAG singals from IO array signals.
6:
7: `include "prim_assert.sv"
8:
9: module jtag_mux #(
10: parameter int NumIOs = 32,
11: parameter logic [NumIOs-1:0] TieOffValues = '0,
12: // Pin to enable JTAG. This is only sampled but not fully muxed.
13: parameter int JtagEnIdx = 0,
14: parameter bit JtagEnPolarity = 1'b1,
15: // These signals are fully muxed and tied off if not in use.
16: parameter int TckIdx = 0,
17: parameter int TmsIdx = 0,
18: parameter int TrstIdx = 0,
19: parameter int SrstIdx = 0,
20: parameter int TdiIdx = 0,
21: parameter int TdoIdx = 0
22: ) (
23: // To JTAG inside core
24: output logic jtag_tck_o,
25: output logic jtag_tms_o,
26: output logic jtag_trst_no,
27: output logic jtag_srst_no,
28: output logic jtag_tdi_o,
29: input logic jtag_tdo_i,
30:
31: // To core side
32: input logic [NumIOs-1:0] out_core_i,
33: input logic [NumIOs-1:0] oe_core_i,
34: output logic [NumIOs-1:0] in_core_o,
35:
36: // To padring side
37: output logic [NumIOs-1:0] out_padring_o,
38: output logic [NumIOs-1:0] oe_padring_o,
39: input logic [NumIOs-1:0] in_padring_i
40: );
41:
42: // Note that we do not tie off the enable signal, since it
43: // is connected to a GPIO such that the core can determine
44: // whether the JTAG is enabled or not.
45: logic jtag_en;
46: assign jtag_en = in_padring_i[JtagEnIdx] == JtagEnPolarity;
47:
48: // Inputs taps
49: assign jtag_tck_o = (jtag_en) ? in_padring_i[TckIdx] : 1'b0;
50: assign jtag_tms_o = (jtag_en) ? in_padring_i[TmsIdx] : 1'b0;
51: assign jtag_trst_no = (jtag_en) ? in_padring_i[TrstIdx] : 1'b1;
52: assign jtag_srst_no = (jtag_en) ? in_padring_i[SrstIdx] : 1'b1;
53: assign jtag_tdi_o = (jtag_en) ? in_padring_i[TdiIdx] : 1'b0;
54:
55: // Input tie-off muxes
56: for (genvar k = 0; k < NumIOs; k++) begin : gen_input_tie_off
57: if (k inside {TckIdx, TmsIdx, TrstIdx, SrstIdx, TdiIdx, TdoIdx}) begin : gen_jtag_signal
58: assign in_core_o[k] = (jtag_en) ? TieOffValues[k] : in_padring_i[k];
59: end else begin : gen_other_inputs
60: assign in_core_o[k] = in_padring_i[k];
61: end
62: end
63:
64: // Override TDO output
65: for (genvar k = 0; k < NumIOs; k++) begin : gen_output_mux
66: if (k == TdoIdx) begin : gen_tdo
67: assign out_padring_o[k] = (jtag_en) ? jtag_tdo_i : out_core_i[k];
68: assign oe_padring_o[k] = (jtag_en) ? 1'b1 : oe_core_i[k];
69: end else begin : gen_other_outputs
70: assign out_padring_o[k] = out_core_i[k];
71: assign oe_padring_o[k] = oe_core_i[k];
72: end
73: end
74:
75: ////////////////
76: // Assertions //
77: ////////////////
78:
79: `ASSERT_INIT(JtagEnIdxRange_A, JtagEnIdx >= 0 && JtagEnIdx < NumIOs)
80: `ASSERT_INIT(TckIdxRange_A, TckIdx >= 0 && TckIdx < NumIOs)
81: `ASSERT_INIT(TmsIdxRange_A, TmsIdx >= 0 && TmsIdx < NumIOs)
82: `ASSERT_INIT(TrstIdxRange_A, TrstIdx >= 0 && TrstIdx < NumIOs)
83: `ASSERT_INIT(SrstIdxRange_A, SrstIdx >= 0 && SrstIdx < NumIOs)
84: `ASSERT_INIT(TdiIdxRange_A, TdiIdx >= 0 && TdiIdx < NumIOs)
85: `ASSERT_INIT(TdoIdxRange_A, TdoIdx >= 0 && TdoIdx < NumIOs)
86:
87: endmodule : jtag_mux
88: