../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: