[otp_ctrl] Split partition metadata into separate package
This is in preparation for the templated OTP memory map.
Signed-off-by: Michael Schaffner <msf@opentitan.org>
diff --git a/hw/ip/otp_ctrl/dv/env/otp_ctrl_env_pkg.sv b/hw/ip/otp_ctrl/dv/env/otp_ctrl_env_pkg.sv
index d0f82c6..6548d4c 100644
--- a/hw/ip/otp_ctrl/dv/env/otp_ctrl_env_pkg.sv
+++ b/hw/ip/otp_ctrl/dv/env/otp_ctrl_env_pkg.sv
@@ -13,8 +13,9 @@
import csr_utils_pkg::*;
import push_pull_agent_pkg::*;
import otp_ctrl_ral_pkg::*;
- import otp_ctrl_pkg::*;
import otp_ctrl_reg_pkg::*;
+ import otp_ctrl_pkg::*;
+ import otp_ctrl_part_pkg::*;
import lc_ctrl_pkg::*;
// macro includes
@@ -29,20 +30,21 @@
parameter uint TEST_ACCESS_WINDOW_SIZE = 16 * 4;
// sram rsp data has 1 bit for seed_valid, the rest are for key and nonce
- parameter uint SRAM_DATA_SIZE = 1 + otp_ctrl_pkg::SramKeyWidth + otp_ctrl_pkg::SramNonceWidth;
+ parameter uint SRAM_DATA_SIZE = 1 + SramKeyWidth + SramNonceWidth;
// otbn rsp data has 1 bit for seed_valid, the rest are for key and nonce
- parameter uint OTBN_DATA_SIZE = 1 + otp_ctrl_pkg::OtbnKeyWidth + otp_ctrl_pkg::OtbnNonceWidth;
+ parameter uint OTBN_DATA_SIZE = 1 + OtbnKeyWidth + OtbnNonceWidth;
// flash rsp data has 1 bit for seed_valid, the rest are for key
- parameter uint FLASH_DATA_SIZE = 1 + otp_ctrl_pkg::FlashKeyWidth;
+ parameter uint FLASH_DATA_SIZE = 1 + FlashKeyWidth;
// lc does not have digest
parameter bit[10:0] DIGESTS_ADDR [NumPart-1] = {
- PartInfo[CreatorSwCfgIdx].offset + PartInfo[CreatorSwCfgIdx].size - DIGEST_SIZE,
- PartInfo[OwnerSwCfgIdx].offset + PartInfo[OwnerSwCfgIdx].size - DIGEST_SIZE,
- PartInfo[HwCfgIdx].offset + PartInfo[HwCfgIdx].size - DIGEST_SIZE,
- PartInfo[Secret0Idx].offset + PartInfo[Secret0Idx].size - DIGEST_SIZE,
- PartInfo[Secret1Idx].offset + PartInfo[Secret1Idx].size - DIGEST_SIZE,
- PartInfo[Secret2Idx].offset + PartInfo[Secret2Idx].size - DIGEST_SIZE};
+ CreatorSwCfgDigestOffset,
+ OwnerSwCfgDigestOffset,
+ HwCfgDigestOffset,
+ Secret0DigestOffset,
+ Secret1DigestOffset,
+ Secret2DigestOffset
+ };
// types
typedef virtual pins_if #(3) pwr_otp_vif;
@@ -70,7 +72,7 @@
// functions
function automatic int get_part_index(bit [TL_DW-1:0] addr);
int index;
- for (index = 0; index < otp_ctrl_pkg::NumPart; index++) begin
+ for (index = 0; index < NumPart; index++) begin
if (PartInfo[index].offset > addr) begin
index--;
break;
diff --git a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_sanity_vseq.sv b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_sanity_vseq.sv
index 68219d3..7f0de27 100644
--- a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_sanity_vseq.sv
+++ b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_sanity_vseq.sv
@@ -14,7 +14,7 @@
randc bit [TL_AW-1:0] dai_addr;
rand bit [TL_DW-1:0] wdata0, wdata1;
rand int num_dai_wr;
- rand otp_ctrl_pkg::part_idx_e part_idx;
+ rand otp_ctrl_part_pkg::part_idx_e part_idx;
// TODO: temp -> no life-cycle partition involved
constraint partition_index_c {
diff --git a/hw/ip/otp_ctrl/otp_ctrl_pkg.core b/hw/ip/otp_ctrl/otp_ctrl_pkg.core
index c799c9e..021150c 100644
--- a/hw/ip/otp_ctrl/otp_ctrl_pkg.core
+++ b/hw/ip/otp_ctrl/otp_ctrl_pkg.core
@@ -13,6 +13,7 @@
files:
- rtl/otp_ctrl_reg_pkg.sv
- rtl/otp_ctrl_pkg.sv
+ - rtl/otp_ctrl_part_pkg.sv
file_type: systemVerilogSource
diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl.sv
index ce48771..683d4c7 100644
--- a/hw/ip/otp_ctrl/rtl/otp_ctrl.sv
+++ b/hw/ip/otp_ctrl/rtl/otp_ctrl.sv
@@ -10,6 +10,7 @@
module otp_ctrl
import otp_ctrl_pkg::*;
import otp_ctrl_reg_pkg::*;
+ import otp_ctrl_part_pkg::*;
#(
// Enable asynchronous transitions on alerts.
parameter logic [NumAlerts-1:0] AlertAsyncOn = {NumAlerts{1'b1}},
@@ -742,7 +743,7 @@
logic [SramKeySeedWidth-1:0] sram_data_key_seed;
logic [FlashKeySeedWidth-1:0] flash_data_key_seed, flash_addr_key_seed;
- otp_ctrl_kdi i_otp_ctrl_kdi (
+ otp_ctrl_kdi u_otp_ctrl_kdi (
.clk_i,
.rst_ni,
.kdi_en_i ( pwr_otp_o.otp_done ),
@@ -945,8 +946,6 @@
// Buffered Data Output Mapping //
//////////////////////////////////
- // TODO: template these mappings, based on the address map hjson contents.
-
// Output complete hardware config partition.
// Actual mapping to other IPs can occur at the top-level.
assign hw_cfg_o = part_buf_data[PartInfo[HwCfgIdx].offset +:
diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl_dai.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl_dai.sv
index 0adbf63..104c2cb 100644
--- a/hw/ip/otp_ctrl/rtl/otp_ctrl_dai.sv
+++ b/hw/ip/otp_ctrl/rtl/otp_ctrl_dai.sv
@@ -10,6 +10,7 @@
module otp_ctrl_dai
import otp_ctrl_pkg::*;
import otp_ctrl_reg_pkg::*;
+ import otp_ctrl_part_pkg::*;
(
input clk_i,
input rst_ni,
@@ -248,7 +249,7 @@
data_en = 1'b1;
base_sel_d = DaiOffset;
// If this partition is scrambled, directly go to write scrambling first.
- if (PartInfo[part_idx].scrambled) begin
+ if (PartInfo[part_idx].secret) begin
state_d = ScrSt;
end else begin
state_d = WriteSt;
@@ -294,7 +295,7 @@
error_d = otp_err_i;
end else begin
data_en = 1'b1;
- if (PartInfo[part_idx].scrambled) begin
+ if (PartInfo[part_idx].secret) begin
state_d = DescrSt;
end else begin
state_d = IdleSt;
@@ -595,9 +596,9 @@
// Depending on whether this is a 32bit or 64bit partition, we cut off the lower address bits.
logic [OtpByteAddrWidth-1:0] addr_base;
- assign addr_base = (base_sel_q == PartOffset) ? PartInfo[part_idx].offset :
- (PartInfo[part_idx].scrambled) ? {dai_addr_i[OtpByteAddrWidth-1:3], 3'h0} :
- {dai_addr_i[OtpByteAddrWidth-1:2], 2'h0};
+ assign addr_base = (base_sel_q == PartOffset) ? PartInfo[part_idx].offset :
+ (PartInfo[part_idx].secret) ? {dai_addr_i[OtpByteAddrWidth-1:3], 3'h0} :
+ {dai_addr_i[OtpByteAddrWidth-1:2], 2'h0};
// Access sizes are either 64bit or 32bit, depending on what partition and region the
// access goes to.
@@ -605,7 +606,7 @@
otp_size_o = OtpSizeWidth'(unsigned'(32 / OtpWidth - 1));
// 64bit transaction for scrambled partitions.
- if (PartInfo[part_idx].scrambled) begin
+ if (PartInfo[part_idx].secret) begin
otp_size_o = OtpSizeWidth'(unsigned'(ScrmblBlockWidth / OtpWidth - 1));
// 64bit transaction if computing a digest.
end else if (PartInfo[part_idx].hw_digest && (base_sel_q == PartOffset)) begin
diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl_lfsr_timer.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl_lfsr_timer.sv
index ab4ec6c..2fef041 100644
--- a/hw/ip/otp_ctrl/rtl/otp_ctrl_lfsr_timer.sv
+++ b/hw/ip/otp_ctrl/rtl/otp_ctrl_lfsr_timer.sv
@@ -28,7 +28,10 @@
`include "prim_assert.sv"
-module otp_ctrl_lfsr_timer import otp_ctrl_pkg::*; #(
+module otp_ctrl_lfsr_timer
+ import otp_ctrl_pkg::*;
+ import otp_ctrl_reg_pkg::*;
+#(
// Entropy reseeding is triggered every time this counter expires.
parameter int ReseedTimerWidth = 16,
parameter logic [TimerWidth-1:0] LfsrSeed = TimerWidth'(1'b1),
diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl_part_buf.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl_part_buf.sv
index 22b225d..17a255b 100644
--- a/hw/ip/otp_ctrl/rtl/otp_ctrl_part_buf.sv
+++ b/hw/ip/otp_ctrl/rtl/otp_ctrl_part_buf.sv
@@ -75,7 +75,7 @@
// Integration checks for parameters.
`ASSERT_INIT(OffsetMustBeBlockAligned_A, (Info.offset % (ScrmblBlockWidth/8)) == 0)
`ASSERT_INIT(SizeMustBeBlockAligned_A, (Info.size % (ScrmblBlockWidth/8)) == 0)
- `ASSERT(ScrambledImpliesDigest_A, Info.scrambled |-> Info.hw_digest)
+ `ASSERT(ScrambledImpliesDigest_A, Info.secret |-> Info.hw_digest)
`ASSERT(WriteLockImpliesDigest_A, Info.read_lock |-> Info.hw_digest)
`ASSERT(ReadLockImpliesDigest_A, Info.write_lock |-> Info.hw_digest)
@@ -225,7 +225,7 @@
state_d = IntegDigClrSt;
// Only need to descramble if this is a scrambled partition.
// Otherwise, we can just go back to InitSt and read the next block.
- end else if (Info.scrambled) begin
+ end else if (Info.secret) begin
state_d = InitDescrSt;
end else begin
state_d = InitSt;
@@ -356,7 +356,7 @@
// Need to reset the digest state and set it to chained
// mode if this partition is scrambled.
scrmbl_cmd_o = DigestInit;
- if (Info.scrambled) begin
+ if (Info.secret) begin
scrmbl_sel_o = ChainedMode;
if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin
state_d = IntegScrSt;
@@ -430,7 +430,7 @@
end
// Go back and scramble the next data block if this is
// a scrambled partition. Otherwise just stay here.
- if (Info.scrambled) begin
+ if (Info.secret) begin
state_d = IntegScrSt;
end
end
diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl_part_pkg.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl_part_pkg.sv
new file mode 100644
index 0000000..f0e33d4
--- /dev/null
+++ b/hw/ip/otp_ctrl/rtl/otp_ctrl_part_pkg.sv
@@ -0,0 +1,53 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+//
+// Package partition metadata.
+//
+// DO NOT EDIT THIS FILE DIRECTLY.
+// It has been generated with hw/ip/otp_ctrl/util/translate-mmap.py
+
+package otp_ctrl_part_pkg;
+
+ import otp_ctrl_reg_pkg::*;
+ import otp_ctrl_pkg::*;
+ // TODO: need to parse this somehow from an hjson
+ localparam part_info_t PartInfo [NumPart] = '{
+ // Variant | offset | size | key_sel | scrambled | HW digest | write_lock | read_lock
+ // CREATOR_SW_CFG
+ '{Unbuffered, 11'h0, 768, Secret0Key, 1'b0, 1'b0, 1'b1, 1'b0},
+ // OWNER_SW_CFG
+ '{Unbuffered, 11'h300, 768, Secret0Key, 1'b0, 1'b0, 1'b1, 1'b0},
+ // HW_CFG
+ '{Buffered, 11'h600, 176, Secret0Key, 1'b0, 1'b1, 1'b1, 1'b0},
+ // SECRET0
+ '{Buffered, 11'h6B0, 40, Secret0Key, 1'b1, 1'b1, 1'b1, 1'b1},
+ // SECRET1
+ '{Buffered, 11'h6D8, 88, Secret1Key, 1'b1, 1'b1, 1'b1, 1'b1},
+ // SECRET2
+ '{Buffered, 11'h730, 120, Secret2Key, 1'b1, 1'b1, 1'b1, 1'b1},
+ // LIFE_CYCLE
+ '{LifeCycle, 11'h7A8, 88, Secret0Key, 1'b0, 1'b0, 1'b0, 1'b0}
+ };
+
+ typedef enum {
+ CreatorSwCfgIdx,
+ OwnerSwCfgIdx,
+ HwCfgIdx,
+ Secret0Idx,
+ Secret1Idx,
+ Secret2Idx,
+ LifeCycleIdx,
+ // These are not "real partitions", but in terms of implementation it is convenient to
+ // add these at the end of certain arrays.
+ DaiIdx,
+ LciIdx,
+ KdiIdx,
+ // Number of agents is the last idx+1.
+ NumAgentsIdx
+ } part_idx_e;
+
+ parameter int NumAgents = int'(NumAgentsIdx);
+ parameter int NumHwCfgBits = PartInfo[HwCfgIdx].size*8;
+
+endmodule : otp_ctrl_part_pkg
diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl_pkg.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl_pkg.sv
index 7177ab8..b14a757 100644
--- a/hw/ip/otp_ctrl/rtl/otp_ctrl_pkg.sv
+++ b/hw/ip/otp_ctrl/rtl/otp_ctrl_pkg.sv
@@ -15,7 +15,6 @@
// Width of entropy input
parameter int EdnDataWidth = 64;
- parameter int NumPart = 7;
parameter int NumPartWidth = vbits(NumPart);
// This defines the width of the check timers and LFSR
parameter int TimerWidth = 40;
@@ -146,9 +145,9 @@
ChainedMode
} digest_mode_e;
- ////////////////////////
- // Partition Metadata //
- ////////////////////////
+ /////////////////////////////////////
+ // Typedefs for Partition Metadata //
+ /////////////////////////////////////
typedef enum logic [1:0] {
Unbuffered,
@@ -164,51 +163,12 @@
// Key index to use for scrambling.
key_sel_e key_sel;
// Attributes
- logic scrambled; // Whether the partition is scrambled
+ logic secret; // Whether the partition is secret (and hence scrambled)
logic hw_digest; // Whether the partition has a hardware digest
logic write_lock; // Whether the partition is write lockable (via digest)
logic read_lock; // Whether the partition is read lockable (via digest)
} part_info_t;
- // TODO: need to parse this somehow from an hjson
- localparam part_info_t PartInfo [NumPart] = '{
- // Variant | offset | size | key_sel | scrambled | HW digest | write_lock | read_lock
- // CREATOR_SW_CFG
- '{Unbuffered, 11'h0, 768, Secret0Key, 1'b0, 1'b0, 1'b1, 1'b0},
- // OWNER_SW_CFG
- '{Unbuffered, 11'h300, 768, Secret0Key, 1'b0, 1'b0, 1'b1, 1'b0},
- // HW_CFG
- '{Buffered, 11'h600, 176, Secret0Key, 1'b0, 1'b1, 1'b1, 1'b0},
- // SECRET0
- '{Buffered, 11'h6B0, 40, Secret0Key, 1'b1, 1'b1, 1'b1, 1'b1},
- // SECRET1
- '{Buffered, 11'h6D8, 88, Secret1Key, 1'b1, 1'b1, 1'b1, 1'b1},
- // SECRET2
- '{Buffered, 11'h730, 120, Secret2Key, 1'b1, 1'b1, 1'b1, 1'b1},
- // LIFE_CYCLE
- '{LifeCycle, 11'h7A8, 88, Secret0Key, 1'b0, 1'b0, 1'b0, 1'b0}
- };
-
- typedef enum {
- CreatorSwCfgIdx,
- OwnerSwCfgIdx,
- HwCfgIdx,
- Secret0Idx,
- Secret1Idx,
- Secret2Idx,
- LifeCycleIdx,
- // These are not "real partitions", but in terms of implementation it is convenient to
- // add these at the end of certain arrays.
- DaiIdx,
- LciIdx,
- KdiIdx,
- // Number of agents is the last idx+1.
- NumAgentsIdx
- } part_idx_e;
-
- parameter int NumAgents = int'(NumAgentsIdx);
- parameter int NumHwCfgBits = PartInfo[HwCfgIdx].size*8;
-
////////////////////////
// Typedefs for CSRNG //
////////////////////////
diff --git a/hw/ip/prim_generic/rtl/prim_generic_otp.sv b/hw/ip/prim_generic/rtl/prim_generic_otp.sv
index ced1caa..4b99019 100644
--- a/hw/ip/prim_generic/rtl/prim_generic_otp.sv
+++ b/hw/ip/prim_generic/rtl/prim_generic_otp.sv
@@ -13,7 +13,7 @@
parameter int ErrWidth = otp_ctrl_pkg::OtpErrWidth,
// Width of the power sequencing signal.
parameter int PwrSeqWidth = otp_ctrl_pkg::OtpPwrSeqWidth,
-// Number of Test TL-UL words
+ // Number of Test TL-UL words
parameter int TlDepth = 16,
// Derived parameters
localparam int AddrWidth = prim_util_pkg::vbits(Depth),