[top_earlgrey] Instantiate LC controller in toplevel
Signed-off-by: Michael Schaffner <msf@opentitan.org>
diff --git a/hw/ip/lc_ctrl/data/lc_ctrl.hjson b/hw/ip/lc_ctrl/data/lc_ctrl.hjson
index 2bb0e12..61cbbba 100644
--- a/hw/ip/lc_ctrl/data/lc_ctrl.hjson
+++ b/hw/ip/lc_ctrl/data/lc_ctrl.hjson
@@ -89,33 +89,40 @@
type: "req_rsp"
name: "jtag"
act: "rsp"
- package: "rv_dm_pkg"
+ package: "jtag_pkg"
}
// Escalation inputs from alert handler
{ struct: "esc_tx"
type: "uni"
- name: "esc1_tx"
+ name: "esc_wipe_secrets_tx"
act: "rcv"
package: "prim_esc_pkg"
}
{ struct: "esc_rx"
type: "uni"
- name: "esc1_rx"
+ name: "esc_wipe_secrets_rx"
act: "req"
package: "prim_esc_pkg"
}
{ struct: "esc_tx"
type: "uni"
- name: "esc2_tx"
+ name: "esc_scrap_state_tx"
act: "rcv"
package: "prim_esc_pkg"
}
{ struct: "esc_rx"
type: "uni"
- name: "esc2_rx"
+ name: "esc_scrap_state_rx"
act: "req"
package: "prim_esc_pkg"
}
+ // Init request from power manager
+ { struct: "pwr_lc",
+ type: "req_rsp",
+ name: "pwr_lc",
+ act: "rsp",
+ package: "pwrmgr_pkg",
+ },
// life cycle state broadcast from OTP
{ struct: "otp_lc_data"
type: "uni"
@@ -171,49 +178,7 @@
}
{ struct: "lc_tx"
type: "uni"
- name: "lc_cpu_en"
- act: "req"
- default: "lc_ctrl_pkg::Off"
- package: "lc_ctrl_pkg"
- }
- { struct: "lc_tx"
- type: "uni"
- name: "lc_cpu_en"
- act: "req"
- default: "lc_ctrl_pkg::Off"
- package: "lc_ctrl_pkg"
- }
- { struct: "lc_tx"
- type: "uni"
- name: "lc_creator_seed_sw_rw_en"
- act: "req"
- default: "lc_ctrl_pkg::Off"
- package: "lc_ctrl_pkg"
- }
- { struct: "lc_tx"
- type: "uni"
- name: "lc_owner_seed_sw_rw_en"
- act: "req"
- default: "lc_ctrl_pkg::Off"
- package: "lc_ctrl_pkg"
- }
- { struct: "lc_tx"
- type: "uni"
- name: "lc_iso_part_sw_rd_en"
- act: "req"
- default: "lc_ctrl_pkg::Off"
- package: "lc_ctrl_pkg"
- }
- { struct: "lc_tx"
- type: "uni"
- name: "lc_iso_part_sw_wr_en"
- act: "req"
- default: "lc_ctrl_pkg::Off"
- package: "lc_ctrl_pkg"
- }
- { struct: "lc_tx"
- type: "uni"
- name: "lc_seed_hw_rd_en"
+ name: "lc_keymgr_en"
act: "req"
default: "lc_ctrl_pkg::Off"
package: "lc_ctrl_pkg"
@@ -260,6 +225,41 @@
default: "lc_ctrl_pkg::Off"
package: "lc_ctrl_pkg"
}
+ { struct: "lc_tx"
+ type: "uni"
+ name: "lc_creator_seed_sw_rw_en"
+ act: "req"
+ default: "lc_ctrl_pkg::Off"
+ package: "lc_ctrl_pkg"
+ }
+ { struct: "lc_tx"
+ type: "uni"
+ name: "lc_owner_seed_sw_rw_en"
+ act: "req"
+ default: "lc_ctrl_pkg::Off"
+ package: "lc_ctrl_pkg"
+ }
+ { struct: "lc_tx"
+ type: "uni"
+ name: "lc_iso_part_sw_rd_en"
+ act: "req"
+ default: "lc_ctrl_pkg::Off"
+ package: "lc_ctrl_pkg"
+ }
+ { struct: "lc_tx"
+ type: "uni"
+ name: "lc_iso_part_sw_wr_en"
+ act: "req"
+ default: "lc_ctrl_pkg::Off"
+ package: "lc_ctrl_pkg"
+ }
+ { struct: "lc_tx"
+ type: "uni"
+ name: "lc_seed_hw_rd_en"
+ act: "req"
+ default: "lc_ctrl_pkg::Off"
+ package: "lc_ctrl_pkg"
+ }
// LC state diversification value for keymgr
{ struct: "lc_keymgr_div"
type: "uni"
@@ -268,6 +268,14 @@
default: "'0"
package: "lc_ctrl_pkg"
}
+ // HW config input for DEVICE_ID
+ { struct: "otp_hw_cfg"
+ type: "uni"
+ name: "otp_hw_cfg"
+ act: "rcv"
+ default: "'0"
+ package: "otp_ctrl_part_pkg"
+ }
] // inter_signal_list
registers: [
diff --git a/hw/ip/lc_ctrl/dv/tb.sv b/hw/ip/lc_ctrl/dv/tb.sv
index 047ec3d..a150bcf 100644
--- a/hw/ip/lc_ctrl/dv/tb.sv
+++ b/hw/ip/lc_ctrl/dv/tb.sv
@@ -42,8 +42,8 @@
.alert_rx_i (alert_rx ),
.alert_tx_o (alert_tx ),
- .jtag_req_i (0),
- .jtag_rsp_o (),
+ .jtag_i (0),
+ .jtag_o (),
.esc_wipe_secrets_tx_i ({2'b01}),
.esc_wipe_secrets_rx_o (),
diff --git a/hw/ip/lc_ctrl/rtl/lc_ctrl.sv b/hw/ip/lc_ctrl/rtl/lc_ctrl.sv
index fdd6035..2ed366a 100644
--- a/hw/ip/lc_ctrl/rtl/lc_ctrl.sv
+++ b/hw/ip/lc_ctrl/rtl/lc_ctrl.sv
@@ -26,8 +26,8 @@
input tlul_pkg::tl_h2d_t tl_i,
output tlul_pkg::tl_d2h_t tl_o,
// JTAG TAP.
- input jtag_pkg::jtag_req_t jtag_req_i,
- output jtag_pkg::jtag_rsp_t jtag_rsp_o,
+ input jtag_pkg::jtag_req_t jtag_i,
+ output jtag_pkg::jtag_rsp_t jtag_o,
// This bypasses the clock inverter inside the JTAG TAP for scanmmode.
input scanmode_i,
// Alert outputs.
@@ -153,12 +153,12 @@
.dmi_resp_i ( dmi_resp ),
.dmi_resp_ready_o ( dmi_resp_ready ),
.dmi_resp_valid_i ( dmi_resp_valid ),
- .tck_i ( jtag_req_i.tck ),
- .tms_i ( jtag_req_i.tms ),
- .trst_ni ( jtag_req_i.trst_n ),
- .td_i ( jtag_req_i.tdi ),
- .td_o ( jtag_rsp_o.tdo ),
- .tdo_oe_o ( jtag_rsp_o.tdo_oe )
+ .tck_i ( jtag_i.tck ),
+ .tms_i ( jtag_i.tms ),
+ .trst_ni ( jtag_i.trst_n ),
+ .td_i ( jtag_i.tdi ),
+ .td_o ( jtag_o.tdo ),
+ .tdo_oe_o ( jtag_o.tdo_oe )
);
// DMI to TL-UL transducing
@@ -291,7 +291,7 @@
end
if (tap_reg2hw.transition_target.qe) begin
- transition_target_d = tap_reg2hw.transition_target.q;
+ transition_target_d = dec_lc_state_e'(tap_reg2hw.transition_target.q);
end
end else if (sw_claim_transition_if_q == 8'hA5) begin
transition_cmd = reg2hw.transition_cmd.q &
@@ -304,7 +304,7 @@
end
if (reg2hw.transition_target.qe) begin
- transition_target_d = reg2hw.transition_target.q;
+ transition_target_d = dec_lc_state_e'(reg2hw.transition_target.q);
end
end
end
@@ -322,7 +322,7 @@
sw_claim_transition_if_q <= '0;
tap_claim_transition_if_q <= '0;
transition_token_q <= '0;
- transition_target_q <= '0;
+ transition_target_q <= DecLcStRaw;
end else begin
// All status and error bits are terminal and require a reset cycle.
trans_success_q <= trans_success_d | trans_success_q;
@@ -524,25 +524,25 @@
// Assertions //
////////////////
- `ASSERT_KNOWN(TlOKnown, tl_o )
- `ASSERT_KNOWN(AlertTxKnown_A, alert_tx_o )
- `ASSERT_KNOWN(PwrLcKnown_A, pwr_lc_o )
- `ASSERT_KNOWN(LcOtpProgramKnwon_A, lc_otp_program_o )
- `ASSERT_KNOWN(LcOtpTokenKnown_A, lc_otp_token_o )
- `ASSERT_KNOWN(LcDftEnKnown_A, lc_dft_en_o )
- `ASSERT_KNOWN(LcNvmDebugEnKnown_A, lc_nvm_debug_en_o )
- `ASSERT_KNOWN(LcHwDebugEnKnown_A, lc_hw_debug_en_o )
- `ASSERT_KNOWN(LcCpuEnKnown_A, lc_cpu_en_o )
- `ASSERT_KNOWN(LcCreatorSwRwEn_A, lc_creator_seed_sw_rw_en_o)
- `ASSERT_KNOWN(LcOwnerSwRwEn_A, lc_owner_seed_sw_rw_en_o)
- `ASSERT_KNOWN(LcIsoSwRwEn_A, lc_iso_part_sw_rd_en_o)
- `ASSERT_KNOWN(LcIsoSwWrEn_A, lc_iso_part_sw_wr_en_o)
- `ASSERT_KNOWN(LcSeedHwRdEn_A, lc_seed_hw_rd_en_o )
- `ASSERT_KNOWN(LcKeymgrEnKnown_A, lc_keymgr_en_o )
- `ASSERT_KNOWN(LcEscalateEnKnown_A, lc_escalate_en_o )
- `ASSERT_KNOWN(LcClkBypReqKnown_A, lc_clk_byp_req_o )
- `ASSERT_KNOWN(LcFlashRmaSeedKnown_A, lc_flash_rma_seed_o )
- `ASSERT_KNOWN(LcFlashRmaReqKnown_A, lc_flash_rma_req_o )
- `ASSERT_KNOWN(LcKeymgrDiv_A, lc_keymgr_div_o )
+ `ASSERT_KNOWN(TlOKnown, tl_o )
+ `ASSERT_KNOWN(AlertTxKnown_A, alert_tx_o )
+ `ASSERT_KNOWN(PwrLcKnown_A, pwr_lc_o )
+ `ASSERT_KNOWN(LcOtpProgramKnown_A, lc_otp_program_o )
+ `ASSERT_KNOWN(LcOtpTokenKnown_A, lc_otp_token_o )
+ `ASSERT_KNOWN(LcDftEnKnown_A, lc_dft_en_o )
+ `ASSERT_KNOWN(LcNvmDebugEnKnown_A, lc_nvm_debug_en_o )
+ `ASSERT_KNOWN(LcHwDebugEnKnown_A, lc_hw_debug_en_o )
+ `ASSERT_KNOWN(LcCpuEnKnown_A, lc_cpu_en_o )
+ `ASSERT_KNOWN(LcCreatorSwRwEn_A, lc_creator_seed_sw_rw_en_o )
+ `ASSERT_KNOWN(LcOwnerSwRwEn_A, lc_owner_seed_sw_rw_en_o )
+ `ASSERT_KNOWN(LcIsoSwRwEn_A, lc_iso_part_sw_rd_en_o )
+ `ASSERT_KNOWN(LcIsoSwWrEn_A, lc_iso_part_sw_wr_en_o )
+ `ASSERT_KNOWN(LcSeedHwRdEn_A, lc_seed_hw_rd_en_o )
+ `ASSERT_KNOWN(LcKeymgrEnKnown_A, lc_keymgr_en_o )
+ `ASSERT_KNOWN(LcEscalateEnKnown_A, lc_escalate_en_o )
+ `ASSERT_KNOWN(LcClkBypReqKnown_A, lc_clk_byp_req_o )
+ `ASSERT_KNOWN(LcFlashRmaSeedKnown_A, lc_flash_rma_seed_o )
+ `ASSERT_KNOWN(LcFlashRmaReqKnown_A, lc_flash_rma_req_o )
+ `ASSERT_KNOWN(LcKeymgrDiv_A, lc_keymgr_div_o )
endmodule : lc_ctrl
diff --git a/hw/ip/prim/rtl/prim_alert_pkg.sv b/hw/ip/prim/rtl/prim_alert_pkg.sv
index a7c6be8..a3594b6 100644
--- a/hw/ip/prim/rtl/prim_alert_pkg.sv
+++ b/hw/ip/prim/rtl/prim_alert_pkg.sv
@@ -3,6 +3,7 @@
// SPDX-License-Identifier: Apache-2.0
package prim_alert_pkg;
+
typedef struct packed {
logic alert_p;
logic alert_n;
@@ -14,4 +15,13 @@
logic ack_p;
logic ack_n;
} alert_rx_t;
-endpackage
+
+ parameter alert_tx_t ALERT_TX_DEFAULT = '{alert_p: 1'b0,
+ alert_n: 1'b1};
+
+ parameter alert_rx_t ALERT_RX_DEFAULT = '{ping_p: 1'b0,
+ ping_n: 1'b1,
+ ack_p: 1'b0,
+ ack_n: 1'b1};
+
+endpackage : prim_alert_pkg
diff --git a/hw/ip/prim/rtl/prim_esc_pkg.sv b/hw/ip/prim/rtl/prim_esc_pkg.sv
index 6d300b8..8cd9c4e 100644
--- a/hw/ip/prim/rtl/prim_esc_pkg.sv
+++ b/hw/ip/prim/rtl/prim_esc_pkg.sv
@@ -3,6 +3,7 @@
// SPDX-License-Identifier: Apache-2.0
package prim_esc_pkg;
+
typedef struct packed {
logic esc_p;
logic esc_n;
@@ -12,4 +13,11 @@
logic resp_p;
logic resp_n;
} esc_rx_t;
-endpackage
+
+ parameter esc_tx_t ESC_TX_DEFAULT = '{esc_p: 1'b0,
+ esc_n: 1'b1};
+
+ parameter esc_rx_t ESC_RX_DEFAULT = '{resp_p: 1'b0,
+ resp_n: 1'b1};
+
+endpackage : prim_esc_pkg
diff --git a/hw/top_earlgrey/data/top_earlgrey.hjson b/hw/top_earlgrey/data/top_earlgrey.hjson
index 4c770f3..5958ba1 100755
--- a/hw/top_earlgrey/data/top_earlgrey.hjson
+++ b/hw/top_earlgrey/data/top_earlgrey.hjson
@@ -221,6 +221,13 @@
reset_connections: {rst_ni: "lc_io_div4"},
base_addr: "0x40130000",
},
+ { name: "lc_ctrl",
+ type: "lc_ctrl",
+ clock_srcs: {clk_i: "io_div4"},
+ clock_group: "timers",
+ reset_connections: {rst_ni: "lc_io_div4"},
+ base_addr: "0x40140000",
+ },
{ name: "pwrmgr",
type: "pwrmgr",
clock_srcs: {clk_i: "io_div4", clk_slow_i: "aon"},
@@ -463,6 +470,12 @@
act: "rsp"
name: "tl"
},
+ { struct: "lc_tx",
+ package: "lc_ctrl_pkg",
+ type: "uni"
+ act: "rcv"
+ name: "lc_dft_en"
+ },
{ struct: "logic"
package: ""
type: "uni"
@@ -488,12 +501,6 @@
act: "rcv"
name: "flash_test_voltage_h"
},
- { struct: "lc_tx",
- package: "lc_ctrl",
- type: "uni"
- act: "rcv"
- name: "lc_dft_en"
- },
],
},
],
@@ -507,6 +514,13 @@
inter_module: {
'connect': {
'alert_handler.crashdump': ['rstmgr.alert_dump'],
+ // TODO: uncomment once NMI gen is removed,
+ // the processor core wrapper supports intermodule signals
+ // and the reset manager has an escalation input.
+ //'alert_handler.esc_rx': ['lc_ctrl.esc_wipe_secrets_rx',
+ // 'lc_ctrl.esc_scrap_state_rx'],
+ //'alert_handler.esc_tx': ['lc_ctrl.esc_wipe_secrets_tx',
+ // 'lc_ctrl.esc_scrap_state_tx'],
'csrng.csrng_cmd' : ['edn0.csrng_cmd', 'edn1.csrng_cmd'],
'csrng.entropy_src_hw_if' : ['entropy_src.entropy_src_hw_if'],
'flash_ctrl.flash' : ['eflash.flash_ctrl'],
@@ -516,16 +530,13 @@
'pwrmgr.pwr_rst' : ['rstmgr.pwr'],
'pwrmgr.pwr_clk' : ['clkmgr.pwr'],
'pwrmgr.pwr_otp' : ['otp_ctrl.pwr_otp'],
+ 'pwrmgr.pwr_lc' : ['lc_ctrl.pwr_lc'],
'flash_ctrl.keymgr': ['keymgr.flash'],
'alert_handler.crashdump': ['rstmgr.alert_dump'],
'csrng.entropy_src_hw_if' : ['entropy_src.entropy_src_hw_if'],
// TODO see #4447
//'edn0.edn' : ['keymgr.edn'],
- // life cycle connections
- // Temporarily commented out because lc_ctrl not instantiated yet
- //'lc_ctrl.lc_dft_en': ['eflash.lc_dft_en'],
-
// KeyMgr Sideload & KDF function
'otp_ctrl.otp_keymgr_key': ['keymgr.otp_key'],
'keymgr.kmac_key' : ['kmac.keymgr_key']
@@ -534,6 +545,44 @@
// The user does not need to explicitly declare anything other than
// an empty list.
'clkmgr.idle' : [],
+
+ // OTP LC interface
+ 'otp_ctrl.otp_lc_data' : ['lc_ctrl.otp_lc_data'],
+ 'lc_ctrl.lc_otp_program' : ['otp_ctrl.lc_otp_program'],
+ 'lc_ctrl.lc_otp_token' : ['otp_ctrl.lc_otp_token'],
+
+ // HW_CFG broadcast
+ 'otp_ctrl.otp_hw_cfg' : ['lc_ctrl.otp_hw_cfg'],
+
+ // Diversification constant coming from life cycle
+ 'lc_ctrl.lc_keymgr_div' : [],
+
+ // LC function control signal broadcast
+ // TODO(#3920): connect all these signals once top-level sim and FPGA can backload LC state
+ 'lc_ctrl.lc_dft_en' : ['otp_ctrl.lc_dft_en', 'eflash.lc_dft_en'],
+ 'lc_ctrl.lc_nvm_debug_en' : [],
+ 'lc_ctrl.lc_hw_debug_en' : [],
+ 'lc_ctrl.lc_cpu_en' : [],
+ 'lc_ctrl.lc_keymgr_en' : [],
+ 'lc_ctrl.lc_escalate_en' : ['otp_ctrl.lc_escalate_en'],
+
+ // TODO: OTP Clock bypass signal going from LC to AST/clkmgr
+ 'lc_ctrl.lc_clk_byp_req' : [],
+ //'lc_ctrl.lc_clk_byp_ack' : [],
+
+ // TODO: Flash RMA
+ 'lc_ctrl.lc_flash_rma_req' : [],
+ 'lc_ctrl.lc_flash_rma_seed' : [],
+ //'lc_ctrl.lc_flash_rma_ack' : [],
+
+ // LC access control signal broadcast
+ 'lc_ctrl.lc_creator_seed_sw_rw_en' : ['otp_ctrl.lc_creator_seed_sw_rw_en',
+ 'flash_ctrl.lc_creator_seed_sw_rw_en'],
+ 'lc_ctrl.lc_owner_seed_sw_rw_en' : ['flash_ctrl.lc_owner_seed_sw_rw_en'],
+ 'lc_ctrl.lc_iso_part_sw_rd_en' : ['flash_ctrl.lc_iso_part_sw_rd_en'],
+ 'lc_ctrl.lc_iso_part_sw_wr_en' : ['flash_ctrl.lc_iso_part_sw_wr_en'],
+ 'lc_ctrl.lc_seed_hw_rd_en' : ['otp_ctrl.lc_seed_hw_rd_en',
+ 'flash_ctrl.lc_seed_hw_rd_en'],
}
// top is to connect to top net/struct.
@@ -608,7 +657,7 @@
// ===== ALERT HANDLER ======================================================
// list all modules that expose alerts
// first item goes to LSB of the alert source
- alert_module: [ "aes", "otbn", "sensor_ctrl", "keymgr", "otp_ctrl", "entropy_src" ]
+ alert_module: [ "aes", "otbn", "sensor_ctrl", "keymgr", "otp_ctrl", "lc_ctrl", "entropy_src"]
// generated list of alerts:
alert: [
diff --git a/hw/top_earlgrey/data/top_earlgrey.sv.tpl b/hw/top_earlgrey/data/top_earlgrey.sv.tpl
index 6fd4ab7..c41134d 100644
--- a/hw/top_earlgrey/data/top_earlgrey.sv.tpl
+++ b/hw/top_earlgrey/data/top_earlgrey.sv.tpl
@@ -479,7 +479,7 @@
.host_rdata_o (flash_host_rdata),
.flash_ctrl_i (${m["inter_signal_list"][0]["top_signame"]}_req),
.flash_ctrl_o (${m["inter_signal_list"][0]["top_signame"]}_rsp),
- .lc_dft_en_i (lc_ctrl_pkg::LC_TX_DEFAULT),
+ .lc_dft_en_i (${m["inter_signal_list"][2]["top_signame"]}),
.tck_i ('0),
.tdi_i ('0),
.tms_i ('0),
@@ -605,8 +605,6 @@
.dio_attr_o,
% endif
% if m["type"] == "alert_handler":
- // TODO: wire this to TRNG
- .entropy_i ( 1'b0 ),
// alert signals
.alert_rx_o ( alert_rx ),
.alert_tx_i ( alert_tx ),
diff --git a/hw/top_earlgrey/data/xbar_peri.hjson b/hw/top_earlgrey/data/xbar_peri.hjson
index 8990872..d0f4392 100644
--- a/hw/top_earlgrey/data/xbar_peri.hjson
+++ b/hw/top_earlgrey/data/xbar_peri.hjson
@@ -73,7 +73,13 @@
type: "device",
clock: "clk_peri_i",
reset: "rst_peri_ni",
- pipeline: "false"
+ pipeline: "false"
+ },
+ { name: "lc_ctrl",
+ type: "device",
+ clock: "clk_peri_i",
+ reset: "rst_peri_ni",
+ pipeline: "false"
},
{ name: "sensor_ctrl",
type: "device",
@@ -98,6 +104,6 @@
],
connections: {
main: ["uart", "gpio", "spi_device", "rv_timer", "usbdev", "pwrmgr", "rstmgr", "clkmgr",
- "ram_ret", "otp_ctrl", "sensor_ctrl", "ast_wrapper"],
+ "ram_ret", "otp_ctrl", "lc_ctrl", "sensor_ctrl", "ast_wrapper"],
},
}
diff --git a/hw/top_earlgrey/top_earlgrey.core b/hw/top_earlgrey/top_earlgrey.core
index e351bf1..0617cc2 100644
--- a/hw/top_earlgrey/top_earlgrey.core
+++ b/hw/top_earlgrey/top_earlgrey.core
@@ -36,6 +36,7 @@
- lowrisc:constants:top_pkg
- lowrisc:ip:nmi_gen
- lowrisc:ip:otp_ctrl
+ - lowrisc:ip:lc_ctrl
- lowrisc:ip:usbdev
- lowrisc:top_earlgrey:xbar_main
- lowrisc:top_earlgrey:xbar_peri