Skip to content

Commit

Permalink
[pinmux] Update strap sampling mode in DFT-enabled LC states
Browse files Browse the repository at this point in the history
This slightly modifies the strap sampling behavior in DFT-enabled
LC states. In particular, we now continously sample the straps in
those states, instead of gating the continous sampling mode
on whether the initial sample was nonzero or not.

This puts less burden on the emulation and simulation environments
where it the device can run in a DFT-enabled mode, since the
strap values may be changed arbitrarily during the test sequence.

This also changes the default life cycle state to RMA instead of DEV
for simulation and emulation environments to ungate all debug
infrastructure and functional modes.

Signed-off-by: Michael Schaffner <[email protected]>
  • Loading branch information
msfschaffner committed Apr 13, 2021
1 parent d61e2e6 commit 17f4bf8
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 36 deletions.
118 changes: 118 additions & 0 deletions hw/ip/otp_ctrl/data/otp_ctrl_img_rma.hjson
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// Use the gen-otp-img.py script to convert this configuration into
// a hex file for preloading the OTP in FPGA synthesis or simulation.
//

{
// Seed to be used for generation of partition randomized values.
// Can be overridden on the command line with the --seed switch.
seed: 01931961561863975174

// The partition and item names must correspond with the OTP memory map.
partitions: [
{
name: "CREATOR_SW_CFG",
items: [
{
name: "CREATOR_SW_CFG_CONTENT",
value: "0x0",
}
{
name: "CREATOR_SW_CFG_DIGEST",
value: "0x0",
}
],
}
{
name: "OWNER_SW_CFG",
items: [
{
name: "OWNER_SW_CFG_CONTENT",
value: "0x0"
}
{
name: "OWNER_SW_CFG_DIGEST",
value: "0x0",
}
],
}
{
name: "HW_CFG",
// If set to true, this computes the HW digest value
// and locks the partition.
lock: "True",
items: [
{
name: "DEVICE_ID",
value: "<random>",
},
{
name: "EN_ENTROPY_SRC_FW_READ",
value: "0xA5",
},
],
}
{
name: "SECRET0",
lock: "True",
items: [
{
name: "TEST_UNLOCK_TOKEN",
value: "<random>",
}
{
name: "TEST_EXIT_TOKEN",
value: "<random>",
}
],
}
{
name: "SECRET1",
lock: "True",
items: [
{
name: "FLASH_ADDR_KEY_SEED",
value: "<random>",
}
{
name: "FLASH_DATA_KEY_SEED",
value: "<random>",
}
{
name: "SRAM_DATA_KEY_SEED",
value: "<random>",
}
],
}
{
name: "SECRET2",
lock: "False",
items: [
{
name: "RMA_TOKEN",
value: "<random>",
}
{
name: "CREATOR_ROOT_KEY_SHARE0",
value: "<random>",
}
{
name: "CREATOR_ROOT_KEY_SHARE1",
value: "<random>",
}
],
}
{
name: "LIFE_CYCLE",
// Can be one of the following strings:
// RAW, TEST_UNLOCKED0-3, TEST_LOCKED0-2, DEV, PROD, PROD_END, RMA, SCRAP
state: "RMA",
// Can range from 0 to 16.
// Note that a value of 0 is only permissible in RAW state.
count: "8"
}
]
}
6 changes: 2 additions & 4 deletions hw/ip/pinmux/rtl/pinmux_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ package pinmux_pkg;
// datastructure below serves this purpose. Note that all the indices below are with respect to
// the concatenated {DIO, MIO} packed array.
typedef struct packed {
logic const_sampling; // TODO: check whether this can be eliminated.
integer tck_idx;
integer tms_idx;
integer trst_idx;
Expand All @@ -35,7 +34,6 @@ package pinmux_pkg;
} target_cfg_t;

parameter target_cfg_t DefaultTargetCfg = '{
const_sampling: 1'b0,
tck_idx: 0,
tms_idx: 0,
trst_idx: 0,
Expand All @@ -49,8 +47,8 @@ package pinmux_pkg;
usb_dn_idx: 0,
usb_dp_pullup_idx: 0,
usb_dn_pullup_idx: 0,
dio_pad_type: {NDioPads{BidirStd}},
mio_pad_type: {NMioPads{BidirStd}}
dio_pad_type: {NDioPads{BidirStd}},
mio_pad_type: {NMioPads{BidirStd}}
};

// Wakeup Detector Modes
Expand Down
28 changes: 3 additions & 25 deletions hw/ip/pinmux/rtl/pinmux_strap_sampling.sv
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,10 @@ module pinmux_strap_sampling
// Strap Sampling Logic //
//////////////////////////

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 [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;

// The LC strap at index 0 has a slightly different
// enable condition than the DFT strap at index 1.
Expand All @@ -104,11 +102,12 @@ module pinmux_strap_sampling
lc_strap_sample_en = 1'b0;
rv_strap_sample_en = 1'b0;
dft_strap_sample_en = 1'b0;
continue_sampling_d = continue_sampling_q;

// Initial strap sampling pulse from pwrmgr,
// qualified by life cycle signals.
if (strap_en_i || continue_sampling_q == lc_ctrl_pkg::On) begin
// In DFT-enabled life cycle states we continously
// sample all straps.
if (strap_en_i || lc_dft_en[0] == lc_ctrl_pkg::On) begin
lc_strap_sample_en = 1'b1;
if (lc_hw_debug_en[0] == lc_ctrl_pkg::On) begin
rv_strap_sample_en = 1'b1;
Expand All @@ -117,38 +116,17 @@ module pinmux_strap_sampling
dft_strap_sample_en = 1'b1;
end
end

// In case DFT is enabled, and in case the TAP straps
// where not set to functional mode upon the first
// sampling event, we continue sampling all straps
// until system reset. This is used during the
// DFT-enabled life cycle states only.
if (lc_dft_en[0] == lc_ctrl_pkg::On) begin
if (strap_en_q &&
tap_strap_t'(tap_strap_q) != FuncSel) begin
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
if (!rst_ni) begin
tap_strap_q <= '0;
dft_strap_q <= '0;
strap_en_q <= 1'b0;
dft_strap_valid_q <= 1'b0;
continue_sampling_q <= lc_ctrl_pkg::Off;
end else begin
tap_strap_q <= tap_strap_d;
dft_strap_q <= dft_strap_d;
strap_en_q <= strap_en_i;
dft_strap_valid_q <= dft_strap_valid_d;
continue_sampling_q <= continue_sampling_d;
end
end

Expand Down
1 change: 0 additions & 1 deletion hw/top_earlgrey/rtl/autogen/chip_earlgrey_asic.sv
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@ module chip_earlgrey_asic (

// DFT and Debug signal positions in the pinout.
localparam pinmux_pkg::target_cfg_t PinmuxTargetCfg = '{
const_sampling: 1'b1,
tck_idx: TckPadIdx,
tms_idx: TmsPadIdx,
trst_idx: TrstNPadIdx,
Expand Down
1 change: 0 additions & 1 deletion hw/top_earlgrey/rtl/autogen/chip_earlgrey_nexysvideo.sv
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ module chip_earlgrey_nexysvideo #(

// DFT and Debug signal positions in the pinout.
localparam pinmux_pkg::target_cfg_t PinmuxTargetCfg = '{
const_sampling: 1'b1,
tck_idx: TckPadIdx,
tms_idx: TmsPadIdx,
trst_idx: TrstNPadIdx,
Expand Down
1 change: 0 additions & 1 deletion hw/top_earlgrey/rtl/chip_earlgrey_verilator.sv
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ module chip_earlgrey_verilator (
// to be split into a Verilator TB and a Verilator chiplevel.
// DFT and Debug signal positions in the pinout.
localparam pinmux_pkg::target_cfg_t PinmuxTargetCfg = '{
const_sampling: 1'b1,
tck_idx: pinmux_reg_pkg::NMioPads +
top_earlgrey_pkg::DioSpiDeviceSck,
tms_idx: pinmux_reg_pkg::NMioPads +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ module chip_englishbreakfast_verilator (
// to be split into a Verilator TB and a Verilator chiplevel.
// DFT and Debug signal positions in the pinout.
localparam pinmux_pkg::target_cfg_t PinmuxTargetCfg = '{
const_sampling: 1'b1,
tck_idx: pinmux_reg_pkg::NMioPads +
top_englishbreakfast_pkg::DioSpiDeviceSck,
tms_idx: pinmux_reg_pkg::NMioPads +
Expand Down
6 changes: 4 additions & 2 deletions sw/device/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,13 @@ extract_sw_logs_sim_dv_depend_files = [

# Generates the OTP image containing root secrets, sw configuration partitions and
# the life cycle state.
# TODO: This just puts the device into DEV life cycle state, with randomized root keys.
# TODO: This just puts the device into RMA life cycle state, with randomized root keys.
# We are using RMA in order to open up all debug and functional infrastructure
# as our testing and emulation environments require that.
# Need to make this more flexible in the future.
# TODO: additional OTP partitions can be included with the --add-cfg switch
# see also util/design/README.md
make_otp_img_inputs = [meson.source_root() / 'hw/ip/otp_ctrl/data/otp_ctrl_img_dev.hjson']
make_otp_img_inputs = [meson.source_root() / 'hw/ip/otp_ctrl/data/otp_ctrl_img_rma.hjson']
make_otp_img_command = [
prog_python, meson.source_root() / 'util/design/gen-otp-img.py',
'--quiet',
Expand Down
1 change: 0 additions & 1 deletion util/topgen/templates/chiplevel.sv.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ module chip_${top["name"]}_${target["name"]} (

// DFT and Debug signal positions in the pinout.
localparam pinmux_pkg::target_cfg_t PinmuxTargetCfg = '{
const_sampling: 1'b1,
tck_idx: TckPadIdx,
tms_idx: TmsPadIdx,
trst_idx: TrstNPadIdx,
Expand Down

0 comments on commit 17f4bf8

Please sign in to comment.