Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pinmux] Add strap sampling and TAP qualification logic #5301

Merged
merged 1 commit into from
Feb 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 40 additions & 7 deletions hw/ip/pinmux/data/pinmux.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand Down
47 changes: 40 additions & 7 deletions hw/ip/pinmux/data/pinmux.hjson.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand Down
6 changes: 6 additions & 0 deletions hw/ip/pinmux/pinmux_component.core
Original file line number Diff line number Diff line change
Expand Up @@ -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)"
Expand All @@ -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

Expand Down
85 changes: 41 additions & 44 deletions hw/ip/pinmux/rtl/pinmux.sv
Original file line number Diff line number Diff line change
Expand Up @@ -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,
msfschaffner marked this conversation as resolved.
Show resolved Hide resolved
// 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,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

quick question, since the flash technically also has a jtag connection to pinmux (however it is muxed and nothing special), should i just do that as part of normal cio_'s?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm... let me see... Afaik, the flash JTAG has a different LC qualification signal (the NVM debug one, right)? So we can't daisy chain the DFT TAP with the flash one?

We could technically add a strap pin bit to allow selection of other TAPs here as well...

Otherwise, if it is fine from a test-flow perspective that the JTAG is functionally muxed in the pinmux ( (and therefore requires a pinmux configuration), then we could go for that, yes.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah it's a different signal, and I do the controls for that directly in flash_phy already, so we don't have to expose anything to pinmux. Maybe that's better then, I just stick with the vanilla pinmux flow and we don't have to do anything extra here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok SGTM!

// Direct USB connection
input usb_out_of_rst_i,
input usb_aon_wake_en_i,
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand All @@ -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 //
Expand All @@ -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
Expand All @@ -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)

Expand Down
37 changes: 37 additions & 0 deletions hw/ip/pinmux/rtl/pinmux_jtag_buf.sv
Original file line number Diff line number Diff line change
@@ -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
14 changes: 2 additions & 12 deletions hw/ip/pinmux/rtl/pinmux_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -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
Loading