[sram_ctrl] Add first cut implementation
Signed-off-by: Michael Schaffner <msf@opentitan.org>
diff --git a/hw/ip/lc_ctrl/rtl/lc_ctrl_pkg.sv b/hw/ip/lc_ctrl/rtl/lc_ctrl_pkg.sv
index fd608d8..82b6ca7 100644
--- a/hw/ip/lc_ctrl/rtl/lc_ctrl_pkg.sv
+++ b/hw/ip/lc_ctrl/rtl/lc_ctrl_pkg.sv
@@ -43,9 +43,10 @@
// Typedefs for LC Interfaces //
////////////////////////////////
- typedef enum logic [2:0] {
- On = 3'b101,
- Off = 3'b000
+ parameter int TxWidth = 4;
+ typedef enum logic [TxWidth-1:0] {
+ On = 4'b1010,
+ Off = 4'b0101
} lc_tx_e;
typedef struct packed {
diff --git a/hw/ip/otp_ctrl/data/otp_ctrl.hjson b/hw/ip/otp_ctrl/data/otp_ctrl.hjson
index 14110a7..2c9cdde 100644
--- a/hw/ip/otp_ctrl/data/otp_ctrl.hjson
+++ b/hw/ip/otp_ctrl/data/otp_ctrl.hjson
@@ -154,21 +154,21 @@
type: "uni"
name: "lc_escalate_en"
act: "rcv"
- default: "'0"
+ default: "lc_ctrl_pkg::Off"
package: "lc_ctrl_pkg"
}
{ struct: "lc_tx"
type: "uni"
name: "lc_provision_en"
act: "rcv"
- default: "'0"
+ default: "lc_ctrl_pkg::Off"
package: "lc_ctrl_pkg"
}
{ struct: "lc_tx"
type: "uni"
name: "lc_dft_en"
act: "rcv"
- default: "'0"
+ default: "lc_ctrl_pkg::Off"
package: "lc_ctrl_pkg"
}
// Broadcast to Key Manager
diff --git a/hw/ip/prim/rtl/prim_prince.sv b/hw/ip/prim/rtl/prim_prince.sv
index b8744a7..97b075d 100644
--- a/hw/ip/prim/rtl/prim_prince.sv
+++ b/hw/ip/prim/rtl/prim_prince.sv
@@ -16,7 +16,8 @@
// References: - https://en.wikipedia.org/wiki/PRESENT
// - https://en.wikipedia.org/wiki/Prince_(cipher)
// - http://www.lightweightcrypto.org/present/present_ches2007.pdf
-// - https://csrc.nist.gov/csrc/media/events/lightweight-cryptography-workshop-2015/documents/papers/session7-maene-paper.pdf
+// - https://csrc.nist.gov/csrc/media/events/lightweight-cryptography-workshop-2015/
+// documents/papers/session7-maene-paper.pdf
// - https://eprint.iacr.org/2012/529.pdf
// - https://eprint.iacr.org/2015/372.pdf
// - https://eprint.iacr.org/2014/656.pdf
diff --git a/hw/ip/prim/rtl/prim_ram_1p_scr.sv b/hw/ip/prim/rtl/prim_ram_1p_scr.sv
index 600784d..39a646e 100644
--- a/hw/ip/prim/rtl/prim_ram_1p_scr.sv
+++ b/hw/ip/prim/rtl/prim_ram_1p_scr.sv
@@ -19,9 +19,6 @@
// that nonce, the address mapping is not fully baked into RTL and can be changed at runtime as
// well.
//
-// Note that this design is not final nor tested, and its main purpose is to be instantiated in
-// Bronze for area and timing estimates.
-//
// See also: prim_cipher_pkg, prim_prince
`include "prim_assert.sv"
@@ -30,7 +27,7 @@
parameter int Depth = 512, // Needs to be a power of 2 if NumAddrScrRounds > 0.
parameter int Width = 256, // Needs to be Byte aligned for parity
parameter int DataBitsPerMask = 8, // Currently only 8 is supported
- parameter int CfgW = 8, // WTC, RTC, etc
+ parameter int CfgWidth = 8, // WTC, RTC, etc
// Scrambling parameters. Note that this needs to be low-latency, hence we have to keep the
// amount of cipher rounds low. PRINCE has 5 half rounds in its original form, which corresponds
@@ -63,6 +60,7 @@
input [DataKeyWidth-1:0] key_i,
input [NonceWidth-1:0] nonce_i,
+ // Interface to TL-UL SRAM adapter
input req_i,
input write_i,
input [AddrWidth-1:0] addr_i,
@@ -71,9 +69,10 @@
output logic [Width-1:0] rdata_o,
output logic rvalid_o, // Read response (rdata_o) is valid
output logic [1:0] rerror_o, // Bit1: Uncorrectable, Bit0: Correctable
+ output logic [AddrWidth-1:0] raddr_o, // Read address for error reporting.
// config
- input [CfgW-1:0] cfg_i
+ input [CfgWidth-1:0] cfg_i
);
//////////////////////
@@ -146,6 +145,11 @@
assign addr_scr = addr_mux;
end
+ // We latch the non-scrambled address for error reporting.
+ logic [AddrWidth-1:0] raddr_d, raddr_q;
+ assign raddr_d = addr_mux;
+ assign raddr_o = raddr_q;
+
//////////////////////////////////////////////
// Keystream Generation for Data Scrambling //
//////////////////////////////////////////////
@@ -176,6 +180,13 @@
.data_o ( keystream[k * 64 +: 64] ),
.valid_o ( )
);
+
+ // Unread unused bits from keystream
+ if (k == NumParKeystr-1 && (Width % 64) > 0) begin : gen_unread_last
+ localparam int UnusedWidth = 64 - (Width % 64);
+ logic [UnusedWidth-1:0] unused_keystream;
+ assign unused_keystream = keystream[(k+1) * 64 - 1 -: UnusedWidth];
+ end
end
// Replicate keystream if needed
@@ -197,7 +208,7 @@
// Write path. Note that since this does not fan out into the interconnect, the write path is not
// as critical as the read path below in terms of timing.
- logic [Width-1:0] wdata_scr_d, wdata_scr_q;
+ logic [Width-1:0] wdata_scr_d, wdata_scr_q, wdata_q;
for (genvar k = 0; k < Width/8; k++) begin : gen_diffuse_wdata
// Apply the keystream first
logic [7:0] wdata_xor;
@@ -277,7 +288,6 @@
// Registers //
///////////////
- logic [Width-1:0] wdata_q;
logic [Width-1:0] wmask_q;
always_ff @(posedge clk_i or negedge rst_ni) begin : p_wdata_buf
if (!rst_ni) begin
@@ -289,11 +299,13 @@
wdata_q <= '0;
wdata_scr_q <= '0;
wmask_q <= '0;
+ raddr_q <= '0;
end else begin
write_scr_pending_q <= write_scr_pending_d;
write_pending_q <= write_pending_d;
collision_q <= collision_d;
rvalid_q <= read_en;
+ raddr_q <= raddr_d;
if (write_en) begin
waddr_q <= addr_i;
wmask_q <= wmask_i;
@@ -313,7 +325,7 @@
.Depth(Depth),
.Width(Width),
.DataBitsPerMask(DataBitsPerMask),
- .CfgW(CfgW),
+ .CfgW(CfgWidth),
.EnableECC(1'b0),
.EnableParity(1'b1), // We are using Byte parity
.EnableInputPipeline(1'b0),
diff --git a/hw/ip/prim/rtl/prim_subst_perm.sv b/hw/ip/prim/rtl/prim_subst_perm.sv
index a882dff..5f96f3a 100644
--- a/hw/ip/prim/rtl/prim_subst_perm.sv
+++ b/hw/ip/prim/rtl/prim_subst_perm.sv
@@ -42,7 +42,7 @@
end
// Flip vector
for (int k = 0; k < DataWidth; k++) begin
- data_state_flipped[DataWidth - 1 - k] = data_state_sbox[k];
+ data_state_sbox[DataWidth - 1 - k] = data_state_flipped[k];
end
// Inverse SBox layer
for (int k = 0; k < DataWidth/4; k++) begin
@@ -66,7 +66,7 @@
data_state_flipped[DataWidth - 1 - k] = data_state_sbox[k];
end
// Regroup bits such that all even indices are stacked up first, followed by all odd
- // indices, and then flip the vector. Note that if the Width is odd, this is still ok, since
+ // indices. Note that if the Width is odd, this is still ok, since
// the uppermost bit just stays in place in that case.
for (int k = 0; k < DataWidth/2; k++) begin
data_state_sbox[k] = data_state_flipped[k * 2];
diff --git a/hw/ip/sram_ctrl/lint/sram_ctrl.vlt b/hw/ip/sram_ctrl/lint/sram_ctrl.vlt
new file mode 100644
index 0000000..901b4bd
--- /dev/null
+++ b/hw/ip/sram_ctrl/lint/sram_ctrl.vlt
@@ -0,0 +1,6 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+//
+// waiver file for SRAM controller
+
diff --git a/hw/ip/sram_ctrl/lint/sram_ctrl.waiver b/hw/ip/sram_ctrl/lint/sram_ctrl.waiver
new file mode 100644
index 0000000..0282f17
--- /dev/null
+++ b/hw/ip/sram_ctrl/lint/sram_ctrl.waiver
@@ -0,0 +1,6 @@
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+#
+# waiver file for SRAM controller
+
diff --git a/hw/ip/sram_ctrl/rtl/sram_ctrl.sv b/hw/ip/sram_ctrl/rtl/sram_ctrl.sv
new file mode 100644
index 0000000..1bfc665
--- /dev/null
+++ b/hw/ip/sram_ctrl/rtl/sram_ctrl.sv
@@ -0,0 +1,286 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+//
+// SRAM controller.
+//
+
+`include "prim_assert.sv"
+
+module sram_ctrl
+ import sram_ctrl_reg_pkg::*;
+#(
+ parameter int Depth = 512, // Needs to be a power of 2 if NumAddrScrRounds > 0.
+ parameter int Width = 32, // Needs to be Byte aligned for parity
+ parameter int CfgWidth = 8, // WTC, RTC, etc
+ // Scrambling parameters. Note that this needs to be low-latency, hence we have to keep the
+ // amount of cipher rounds low. PRINCE has 5 half rounds in its original form, which corresponds
+ // to 2*5 + 1 effective rounds. Setting this to 2 halves this to approximately 5 effective rounds.
+ parameter int NumPrinceRoundsHalf = 2, // Number of PRINCE half rounds, can be [1..5]
+ // Number of extra intra-Byte diffusion rounds. Setting this to 0 disables intra-Byte diffusion.
+ parameter int NumByteScrRounds = 2,
+ // Number of address scrambling rounds. Setting this to 0 disables address scrambling.
+ parameter int NumAddrScrRounds = 2,
+ // Derived parameters
+ localparam int AddrWidth = prim_util_pkg::vbits(Depth)
+) (
+ // SRAM Clock
+ input clk_i,
+ input rst_ni,
+ // OTP Clock (for key interface)
+ input clk_otp_i,
+ input rst_otp_ni,
+ // Bus Interface (device) for CSRs
+ input tlul_pkg::tl_h2d_t tl_i,
+ output tlul_pkg::tl_d2h_t tl_o,
+ // Bus Interface (device) for SRAM
+ input tlul_pkg::tl_h2d_t sram_tl_i,
+ output tlul_pkg::tl_d2h_t sram_tl_o,
+ // Interrupt Requests
+ output logic sram_integ_error_o,
+ // Life-cycle escalation input (scraps the scrambling keys)
+ input lc_ctrl_pkg::lc_tx_t lc_escalate_en_i,
+ // Key request to OTP (running on clk_fixed)
+ output otp_ctrl_pkg::sram_otp_key_req_t sram_otp_key_o,
+ input otp_ctrl_pkg::sram_otp_key_rsp_t sram_otp_key_i
+);
+
+ // This peripheral only works up to a width of 64bits.
+ `ASSERT_INIT(WidthMustBeBelow64_A, Width <= 64)
+
+ //////////////////////////
+ // CSR Node and Mapping //
+ //////////////////////////
+
+ sram_ctrl_reg_pkg::sram_ctrl_reg2hw_t reg2hw;
+ sram_ctrl_reg_pkg::sram_ctrl_hw2reg_t hw2reg;
+
+ sram_ctrl_reg_top u_reg (
+ .clk_i,
+ .rst_ni,
+ .tl_i,
+ .tl_o,
+ .reg2hw,
+ .hw2reg,
+ .devmode_i (1'b1)
+ );
+
+ // Key and attribute outputs to scrambling device
+ logic [otp_ctrl_pkg::SramKeyWidth-1:0] key_d, key_q;
+ logic [otp_ctrl_pkg::SramNonceWidth-1:0] nonce_d, nonce_q;
+ logic [otp_ctrl_pkg::SramKeyWidth-1:0] sram_scr_key;
+ logic [otp_ctrl_pkg::SramNonceWidth-1:0] sram_scr_nonce;
+ logic [CfgWidth-1:0] sram_scr_cfg;
+ assign sram_scr_key = key_q;
+ assign sram_scr_nonce = nonce_q;
+ assign sram_scr_cfg = reg2hw.sram_cfg.q;
+
+ // Status register outputs
+ logic [AddrWidth-1:0] sram_scr_raddr;
+ logic key_valid_d, key_valid_q;
+ logic key_seed_valid_d, key_seed_valid_q;
+ // Flag an error if any of the error bits is set.
+ assign hw2reg.status.error = |reg2hw.error_type;
+ assign hw2reg.status.scr_key_valid = key_valid_q;
+ assign hw2reg.status.scr_key_seed_valid = key_seed_valid_q;
+
+ // Control register
+ logic key_req;
+ assign key_req = reg2hw.ctrl.q & reg2hw.ctrl.qe;
+
+ // Integrity errors
+ logic [1:0] sram_rerror;
+ assign hw2reg.error_type.correctable.d = sram_rerror[0];
+ assign hw2reg.error_type.correctable.de = sram_rerror[0];
+ assign hw2reg.error_type.uncorrectable.d = sram_rerror[1];
+ assign hw2reg.error_type.uncorrectable.de = sram_rerror[1];
+ assign hw2reg.error_address.d = 32'(sram_scr_raddr);
+ assign hw2reg.error_address.de = |sram_rerror;
+
+ ////////////////
+ // Interrupts //
+ ////////////////
+
+ prim_intr_hw #(
+ .Width(1)
+ ) u_intr_sram_integ_error (
+ .clk_i,
+ .rst_ni,
+ .event_intr_i ( |sram_rerror ),
+ .reg2hw_intr_enable_q_i ( reg2hw.intr_enable.q ),
+ .reg2hw_intr_test_q_i ( reg2hw.intr_test.q ),
+ .reg2hw_intr_test_qe_i ( reg2hw.intr_test.qe ),
+ .reg2hw_intr_state_q_i ( reg2hw.intr_state.q ),
+ .hw2reg_intr_state_de_o ( hw2reg.intr_state.de ),
+ .hw2reg_intr_state_d_o ( hw2reg.intr_state.d ),
+ .intr_o ( sram_integ_error_o )
+ );
+
+ ///////////////////////////////////
+ // Lifecycle Escalation Receiver //
+ ///////////////////////////////////
+
+ lc_ctrl_pkg::lc_tx_t escalate_en;
+ prim_multibit_sync #(
+ .Width(lc_ctrl_pkg::TxWidth),
+ .NumChecks (2),
+ .ResetValue(lc_ctrl_pkg::TxWidth'(lc_ctrl_pkg::Off))
+ ) u_prim_multibit_sync (
+ .clk_i,
+ .rst_ni,
+ .data_i (lc_escalate_en_i),
+ .data_o (escalate_en)
+ );
+
+ ////////////////////////////
+ // Scrambling Key Request //
+ ////////////////////////////
+
+ // The scrambling key and nonce have to be requested from the OTP controller via a req/ack
+ // protocol. Since the OTP controller works in a different clock domain, we have to synchronize
+ // the req/ack protocol as described in more details here:
+ // https://docs.opentitan.org/hw/ip/otp_ctrl/doc/index.html#interfaces-to-sram-and-otbn-scramblers
+ logic key_ack;
+ logic key_req_pending_d, key_req_pending_q;
+ assign key_req_pending_d = (key_req) ? 1'b1 :
+ (key_ack) ? 1'b0 : key_req_pending_q;
+
+ assign key_valid_d = (key_req) ? 1'b0 :
+ (key_ack) ? 1'b1 : key_valid_q;
+
+ assign key_d = sram_otp_key_i.key;
+ assign nonce_d = sram_otp_key_i.nonce;
+ assign key_seed_valid_d = sram_otp_key_i.seed_valid;
+
+ always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
+ if (!rst_ni) begin
+ key_req_pending_q <= 1'b0;
+ key_valid_q <= 1'b0;
+ key_seed_valid_q <= 1'b0;
+ key_q <= '0;
+ nonce_q <= '0;
+ end else begin
+ key_req_pending_q <= key_req_pending_d;
+ key_valid_q <= key_valid_d;
+ if (key_ack) begin
+ key_seed_valid_q <= key_seed_valid_d;
+ key_q <= key_d;
+ nonce_q <= nonce_d;
+ end
+ // This scraps the keys
+ if (escalate_en.state != lc_ctrl_pkg::Off) begin
+ key_seed_valid_q <= '0;
+ key_q <= '0;
+ nonce_q <= '0;
+ end
+ end
+ end
+
+ prim_sync_reqack u_prim_sync_reqack (
+ .clk_src_i ( clk_i ),
+ .rst_src_ni ( rst_ni ),
+ .clk_dst_i ( clk_otp_i ),
+ .rst_dst_ni ( rst_otp_ni ),
+ .src_req_i ( key_req_pending_q ),
+ .src_ack_o ( key_ack ),
+ .dst_req_o ( sram_otp_key_o.req ),
+ .dst_ack_i ( sram_otp_key_i.ack )
+ );
+
+ ////////////////////////////////
+ // Scrambled Memory Primitive //
+ ////////////////////////////////
+
+ logic tlul_req;
+ logic tlul_we;
+ logic [AddrWidth-1:0] tlul_addr;
+ logic [Width-1:0] tlul_wdata;
+ logic [Width-1:0] tlul_wmask;
+ logic [Width-1:0] tlul_rdata;
+ logic tlul_rvalid;
+ logic [1:0] tlul_rerror;
+
+ tlul_adapter_sram #(
+ .SramAw(AddrWidth),
+ .SramDw(Width)
+ ) u_tlul_adapter_sram (
+ .clk_i,
+ .rst_ni,
+ .tl_i ( sram_tl_i ),
+ .tl_o ( sram_tl_o ),
+ .req_o ( tlul_req ),
+ .gnt_i ( 1'b1 ),
+ .we_o ( tlul_we ),
+ .addr_o ( tlul_addr ),
+ .wdata_o ( tlul_wdata ),
+ .wmask_o ( tlul_wmask ),
+ .rdata_i ( tlul_rdata ),
+ .rvalid_i ( tlul_rvalid ),
+ .rerror_i ( tlul_rerror )
+ );
+
+ logic sram_req;
+ logic sram_we;
+ logic [AddrWidth-1:0] sram_addr;
+ logic [Width-1:0] sram_wdata;
+ logic [Width-1:0] sram_wmask;
+ logic [Width-1:0] sram_rdata;
+ logic sram_rvalid;
+
+ prim_ram_1p_scr #(
+ .Depth ( Depth ),
+ .Width ( Width ),
+ .CfgWidth ( CfgWidth ),
+ .NumPrinceRoundsHalf ( NumPrinceRoundsHalf ),
+ .NumByteScrRounds ( NumByteScrRounds ),
+ .NumAddrScrRounds ( NumAddrScrRounds )
+ ) i_prim_ram_1p_scr (
+ .clk_i,
+ .rst_ni,
+ .key_i ( sram_scr_key ),
+ .nonce_i ( sram_scr_nonce ),
+ .req_i ( sram_req ),
+ .write_i ( sram_we ),
+ .addr_i ( sram_addr ),
+ .wdata_i ( sram_wdata ),
+ .wmask_i ( sram_wmask ),
+ .rdata_o ( sram_rdata ),
+ .rvalid_o ( sram_rvalid ),
+ .rerror_o ( sram_rerror ),
+ .raddr_o ( sram_scr_raddr ),
+ .cfg_i ( sram_scr_cfg )
+ );
+
+ // Do not forward requests to SRAM while key request is pending.
+ // Instead, we return a TLUL error.
+ assign sram_req = ~key_req_pending_q & tlul_req;
+ assign sram_we = ~key_req_pending_q & tlul_we;
+ assign sram_addr = tlul_addr;
+ assign sram_wdata = tlul_wdata;
+ assign sram_wmask = tlul_wmask;
+
+ // Delay the key pending error by one cycle in order to match with the SRAM read latency.
+ logic key_pending_error_d, key_pending_error_q;
+ assign key_pending_error_d = key_req_pending_q & tlul_req;
+ assign tlul_rdata = (key_pending_error_q) ? '0 : sram_rdata;
+ assign tlul_rvalid = (key_pending_error_q) ? 1'b1 : sram_rvalid;
+ assign tlul_rerror = (key_pending_error_q) ? 2'b10 : sram_rerror; // signal as uncorrectable
+
+ always_ff @(posedge clk_i or negedge rst_ni) begin : p_error_reg
+ if (!rst_ni) begin
+ key_pending_error_q <= 1'b0;
+ end else begin
+ key_pending_error_q <= key_pending_error_d;
+ end
+ end
+
+ ////////////////
+ // Assertions //
+ ////////////////
+
+ `ASSERT_KNOWN(TlOutKnown_A, tl_o)
+ `ASSERT_KNOWN(TlSramOutKnown_A, sram_tl_o)
+ `ASSERT_KNOWN(IntrSramParityErrorKnown_A, sram_integ_error_o)
+ `ASSERT_KNOWN(SramOtpKeyKnown_A, sram_otp_key_o)
+
+endmodule : sram_ctrl
diff --git a/hw/ip/sram_ctrl/sram_ctrl.core b/hw/ip/sram_ctrl/sram_ctrl.core
new file mode 100644
index 0000000..45a216c
--- /dev/null
+++ b/hw/ip/sram_ctrl/sram_ctrl.core
@@ -0,0 +1,81 @@
+CAPI=2:
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+name: "lowrisc:ip:sram_ctrl:0.1"
+description: "SRAM Controller"
+
+filesets:
+ files_rtl:
+ depend:
+ - lowrisc:prim:all
+ - lowrisc:prim:util
+ - lowrisc:prim:multibit_sync
+ - lowrisc:prim:ram_1p_scr
+ - lowrisc:tlul:adapter_sram
+ - lowrisc:ip:tlul
+ - lowrisc:ip:sram_ctrl_pkg
+ - lowrisc:ip:lc_ctrl_pkg
+ - lowrisc:ip:otp_ctrl_pkg
+ files:
+ - rtl/sram_ctrl_reg_top.sv
+ - rtl/sram_ctrl.sv
+ file_type: systemVerilogSource
+
+ files_verilator_waiver:
+ depend:
+ # common waivers
+ - lowrisc:lint:common
+ - lowrisc:lint:comportable
+ files:
+ - lint/sram_ctrl.vlt
+ file_type: vlt
+
+ files_ascentlint_waiver:
+ depend:
+ # common waivers
+ - lowrisc:lint:common
+ - lowrisc:lint:comportable
+ files:
+ - lint/sram_ctrl.waiver
+ file_type: waiver
+
+ files_formal:
+ files:
+ - dv/tb/sram_ctrl_bind.sv
+ file_type: systemVerilogSource
+
+parameters:
+ SYNTHESIS:
+ datatype: bool
+ paramtype: vlogdefine
+
+
+targets:
+ default: &default_target
+ filesets:
+ - tool_verilator ? (files_verilator_waiver)
+ - tool_ascentlint ? (files_ascentlint_waiver)
+ - target_formal ? (files_formal)
+ - files_rtl
+ toplevel: sram_ctrl
+
+ formal:
+ filesets:
+ - files_rtl
+ - files_formal
+ toplevel: sram_ctrl
+
+ lint:
+ <<: *default_target
+ default_tool: verilator
+ parameters:
+ - SYNTHESIS=true
+ tools:
+ ascentlint:
+ ascentlint_options:
+ - "-wait_license"
+ verilator:
+ mode: lint-only
+ verilator_options:
+ - "-Wall"
diff --git a/hw/ip/sram_ctrl/sram_ctrl_pkg.core b/hw/ip/sram_ctrl/sram_ctrl_pkg.core
new file mode 100644
index 0000000..1af89c5
--- /dev/null
+++ b/hw/ip/sram_ctrl/sram_ctrl_pkg.core
@@ -0,0 +1,21 @@
+CAPI=2:
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+name: "lowrisc:ip:sram_ctrl_pkg:0.1"
+description: "SRAM Controller Package"
+filesets:
+ files_rtl:
+ depend:
+ - lowrisc:tlul:headers
+ - lowrisc:ip:otp_ctrl_pkg
+
+ files:
+ - rtl/sram_ctrl_reg_pkg.sv
+ file_type: systemVerilogSource
+
+
+targets:
+ default: &default_target
+ filesets:
+ - files_rtl
diff --git a/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson b/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson
index 203ddfa..418fad3 100644
--- a/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson
+++ b/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson
@@ -2741,7 +2741,7 @@
type: uni
name: lc_escalate_en
act: rcv
- default: "'0"
+ default: lc_ctrl_pkg::Off
package: lc_ctrl_pkg
inst_name: otp_ctrl
index: -1
@@ -2751,7 +2751,7 @@
type: uni
name: lc_provision_en
act: rcv
- default: "'0"
+ default: lc_ctrl_pkg::Off
package: lc_ctrl_pkg
inst_name: otp_ctrl
index: -1
@@ -2761,7 +2761,7 @@
type: uni
name: lc_dft_en
act: rcv
- default: "'0"
+ default: lc_ctrl_pkg::Off
package: lc_ctrl_pkg
inst_name: otp_ctrl
index: -1
@@ -6308,7 +6308,7 @@
type: uni
name: lc_escalate_en
act: rcv
- default: "'0"
+ default: lc_ctrl_pkg::Off
package: lc_ctrl_pkg
inst_name: otp_ctrl
index: -1
@@ -6318,7 +6318,7 @@
type: uni
name: lc_provision_en
act: rcv
- default: "'0"
+ default: lc_ctrl_pkg::Off
package: lc_ctrl_pkg
inst_name: otp_ctrl
index: -1
@@ -6328,7 +6328,7 @@
type: uni
name: lc_dft_en
act: rcv
- default: "'0"
+ default: lc_ctrl_pkg::Off
package: lc_ctrl_pkg
inst_name: otp_ctrl
index: -1
diff --git a/hw/top_earlgrey/lint/top_earlgrey_lint_cfgs.hjson b/hw/top_earlgrey/lint/top_earlgrey_lint_cfgs.hjson
index e91c2c8..c4841ec 100644
--- a/hw/top_earlgrey/lint/top_earlgrey_lint_cfgs.hjson
+++ b/hw/top_earlgrey/lint/top_earlgrey_lint_cfgs.hjson
@@ -151,6 +151,17 @@
import_cfgs: ["{proj_root}/hw/lint/data/common_lint_cfg.hjson"]
rel_path: "hw/ip/spi_device/lint/{tool}"
},
+ { name: sram_ctrl
+ fusesoc_core: lowrisc:ip:sram_ctrl
+ import_cfgs: ["{proj_root}/hw/lint/data/common_lint_cfg.hjson"]
+ rel_path: "hw/ip/sram_ctrl/lint/{tool}"
+ overrides: [
+ {
+ name: design_level
+ value: "top"
+ }
+ ]
+ },
{ name: uart
fusesoc_core: lowrisc:ip:uart
import_cfgs: ["{proj_root}/hw/lint/data/common_lint_cfg.hjson"]
diff --git a/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv b/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv
index 13c1df1..d413b46 100644
--- a/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv
+++ b/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv
@@ -1030,9 +1030,9 @@
.lc_otp_token_i('0),
.lc_otp_token_o(),
.otp_lc_data_o(),
- .lc_escalate_en_i('0),
- .lc_provision_en_i('0),
- .lc_dft_en_i('0),
+ .lc_escalate_en_i(lc_ctrl_pkg::Off),
+ .lc_provision_en_i(lc_ctrl_pkg::Off),
+ .lc_dft_en_i(lc_ctrl_pkg::Off),
.otp_keymgr_key_o(),
.flash_otp_key_i('0),
.flash_otp_key_o(),