[pinmux/tap] Rework DFT TAP hooks
The current DFT TAP hooks expose the JTAG signals as a struct type,
and the pinmux_jtag_buf module is instantiated not only for the DFT
TAP but also for the other TAPs that are connected in RTL.
While this is all correct from a syntax and design perspective, the
struct type seems to confuse certain automatic DFT insertion tools.
Further having multiple pinmux_jtag_buf modules instantiated exposed a
uniquification bug in Tessent.
To solve this issue, this patch adds a breakout module called
pinmux_jtag_breakout for the DFT tap on the top-level that exposes the
DFT signal hooks as simple logic ports.
Signed-off-by: Michael Schaffner <msf@opentitan.org>
diff --git a/hw/ip/pinmux/pinmux_component.core b/hw/ip/pinmux/pinmux_component.core
index d7e0283..8789541 100644
--- a/hw/ip/pinmux/pinmux_component.core
+++ b/hw/ip/pinmux/pinmux_component.core
@@ -24,6 +24,7 @@
- rtl/pinmux_pkg.sv
- rtl/pinmux_wkup.sv
- rtl/pinmux_jtag_buf.sv
+ - rtl/pinmux_jtag_breakout.sv
- rtl/pinmux_strap_sampling.sv
- rtl/pinmux.sv
file_type: systemVerilogSource
diff --git a/hw/ip/pinmux/rtl/pinmux_jtag_breakout.sv b/hw/ip/pinmux/rtl/pinmux_jtag_breakout.sv
new file mode 100644
index 0000000..2feb510
--- /dev/null
+++ b/hw/ip/pinmux/rtl/pinmux_jtag_breakout.sv
@@ -0,0 +1,24 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+module pinmux_jtag_breakout (
+ input jtag_pkg::jtag_req_t req_i,
+ output jtag_pkg::jtag_rsp_t rsp_o,
+
+ output logic tck_o,
+ output logic trst_no,
+ output logic tms_o,
+ output logic tdi_o,
+ input tdo_i,
+ input tdo_oe_i
+);
+
+ assign tck_o = req_i.tck;
+ assign trst_no = req_i.trst_n;
+ assign tms_o = req_i.tms;
+ assign tdi_o = req_i.tdi;
+ assign rsp_o.tdo = tdo_i;
+ assign rsp_o.tdo_oe = tdo_oe_i;
+
+endmodule : pinmux_jtag_breakout
diff --git a/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson b/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson
index 3cf9218..834aaca 100644
--- a/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson
+++ b/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson
@@ -2942,6 +2942,8 @@
act: req
width: 1
inst_name: pinmux_aon
+ default: ""
+ top_signame: pinmux_aon_dft_jtag
index: -1
}
{
@@ -6265,6 +6267,7 @@
main.tl_cored
main.tl_dm_sba
main.tl_debug_mem
+ pinmux_aon.dft_jtag
]
external:
{
@@ -13282,6 +13285,8 @@
act: req
width: 1
inst_name: pinmux_aon
+ default: ""
+ top_signame: pinmux_aon_dft_jtag
index: -1
}
{
@@ -18286,6 +18291,24 @@
end_idx: -1
default: ""
}
+ {
+ package: jtag_pkg
+ struct: jtag_req
+ signame: pinmux_aon_dft_jtag_req
+ width: 1
+ type: req_rsp
+ end_idx: -1
+ default: ""
+ }
+ {
+ package: jtag_pkg
+ struct: jtag_rsp
+ signame: pinmux_aon_dft_jtag_rsp
+ width: 1
+ type: req_rsp
+ end_idx: -1
+ default: ""
+ }
]
}
}
\ No newline at end of file
diff --git a/hw/top_earlgrey/data/top_earlgrey.hjson b/hw/top_earlgrey/data/top_earlgrey.hjson
index 86077dd..0841037 100644
--- a/hw/top_earlgrey/data/top_earlgrey.hjson
+++ b/hw/top_earlgrey/data/top_earlgrey.hjson
@@ -912,9 +912,6 @@
'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'],
'pinmux_aon.rv_jtag' : ['rv_dm.jtag'],
@@ -971,7 +968,11 @@
'pwrmgr_aon.fetch_en',
// Xbars
- 'main.tl_corei', 'main.tl_cored', 'main.tl_dm_sba', 'main.tl_debug_mem'
+ 'main.tl_corei', 'main.tl_cored', 'main.tl_dm_sba', 'main.tl_debug_mem',
+
+ // Pinmux JTAG signals for the tool-inserted DFT TAP
+ 'pinmux_aon.dft_jtag'
+
],
// ext is to create port in the top.
diff --git a/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv b/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv
index 0a430f3..de4714e 100644
--- a/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv
+++ b/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv
@@ -643,6 +643,8 @@
tlul_pkg::tl_d2h_t main_tl_dm_sba_rsp;
tlul_pkg::tl_h2d_t main_tl_debug_mem_req;
tlul_pkg::tl_d2h_t main_tl_debug_mem_rsp;
+ jtag_pkg::jtag_req_t pinmux_aon_dft_jtag_req;
+ jtag_pkg::jtag_rsp_t pinmux_aon_dft_jtag_rsp;
// define mixed connection to port
assign edn0_edn_req[2] = ast_edn_req_i;
@@ -805,6 +807,18 @@
assign rstmgr_aon_cpu.ndmreset_req = ndmreset_req;
assign rstmgr_aon_cpu.rst_cpu_n = rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel];
+ // Struct breakout module tool-inserted DFT TAP signals
+ pinmux_jtag_breakout u_dft_tap_breakout (
+ .req_i (pinmux_aon_dft_jtag_req),
+ .rsp_o (pinmux_aon_dft_jtag_rsp),
+ .tck_o (),
+ .trst_no (),
+ .tms_o (),
+ .tdi_o (),
+ .tdo_i (1'b0),
+ .tdo_oe_i (1'b0)
+ );
+
// sram device
logic ram_main_req;
logic ram_main_gnt;
@@ -1796,8 +1810,8 @@
.lc_jtag_i(pinmux_aon_lc_jtag_rsp),
.rv_jtag_o(pinmux_aon_rv_jtag_req),
.rv_jtag_i(pinmux_aon_rv_jtag_rsp),
- .dft_jtag_o(),
- .dft_jtag_i(jtag_pkg::JTAG_RSP_DEFAULT),
+ .dft_jtag_o(pinmux_aon_dft_jtag_req),
+ .dft_jtag_i(pinmux_aon_dft_jtag_rsp),
.dft_strap_test_o(dft_strap_test_o),
.dft_hold_tap_sel_i(dft_hold_tap_sel_i),
.sleep_en_i(pwrmgr_aon_low_power),
diff --git a/util/topgen/templates/toplevel.sv.tpl b/util/topgen/templates/toplevel.sv.tpl
index f0248b3..c7470ff 100644
--- a/util/topgen/templates/toplevel.sv.tpl
+++ b/util/topgen/templates/toplevel.sv.tpl
@@ -347,6 +347,18 @@
assign rstmgr_aon_cpu.ndmreset_req = ndmreset_req;
assign rstmgr_aon_cpu.rst_cpu_n = ${top["reset_paths"]["sys"]}[rstmgr_pkg::Domain0Sel];
+ // Struct breakout module tool-inserted DFT TAP signals
+ pinmux_jtag_breakout u_dft_tap_breakout (
+ .req_i (pinmux_aon_dft_jtag_req),
+ .rsp_o (pinmux_aon_dft_jtag_rsp),
+ .tck_o (),
+ .trst_no (),
+ .tms_o (),
+ .tdi_o (),
+ .tdo_i (1'b0),
+ .tdo_oe_i (1'b0)
+ );
+
## Memory Instantiation
% for m in top["memory"]:
<%