Skip to content

Commit

Permalink
[prim_ram_1p] Ram tiling for sram_ctrl and prim_ram_1p
Browse files Browse the repository at this point in the history
Signed-off-by: Robert Schilling <[email protected]>
  • Loading branch information
Razer6 committed Dec 21, 2024
1 parent b058bfe commit 9cf4b18
Show file tree
Hide file tree
Showing 12 changed files with 470 additions and 118 deletions.
115 changes: 87 additions & 28 deletions hw/ip/prim/rtl/prim_ram_1p_adv.sv
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

module prim_ram_1p_adv import prim_ram_1p_pkg::*; #(
parameter int Depth = 512,
parameter int InstDepth = Depth,
parameter int Width = 32,
parameter int DataBitsPerMask = 1, // Number of data bits per bit of write mask
parameter MemInitFile = "", // VMEM file to initialize the memory with
Expand All @@ -32,32 +33,36 @@ module prim_ram_1p_adv import prim_ram_1p_pkg::*; #(
// since this results in a more compact and faster implementation.
parameter bit HammingECC = 0,

localparam int Aw = prim_util_pkg::vbits(Depth)
localparam int Aw = prim_util_pkg::vbits(Depth),
// Compute RAM tiling
localparam int NumRamInst = $ceil(Depth / InstDepth),
localparam int InstAw = prim_util_pkg::vbits(InstDepth)
) (
input clk_i,
input rst_ni,

input req_i,
input write_i,
input [Aw-1:0] addr_i,
input [Width-1:0] wdata_i,
input [Width-1:0] wmask_i,
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
input req_i,
input write_i,
input [Aw-1:0] addr_i,
input [Width-1:0] wdata_i,
input [Width-1:0] wmask_i,
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

// config
input ram_1p_cfg_t cfg_i,
input ram_1p_cfg_t [NumRamInst-1:0] cfg_i,

// When detecting multi-bit encoding errors, raise alert.
output logic alert_o
output logic alert_o
);

import prim_mubi_pkg::mubi4_t;
import prim_mubi_pkg::mubi4_and_hi;
import prim_mubi_pkg::mubi4_bool_to_mubi;
import prim_mubi_pkg::mubi4_test_invalid;
import prim_mubi_pkg::mubi4_test_true_loose;
import prim_mubi_pkg::mubi4_test_true_strict;
import prim_mubi_pkg::MuBi4True;
import prim_mubi_pkg::MuBi4False;
import prim_mubi_pkg::MuBi4Width;
Expand Down Expand Up @@ -102,23 +107,77 @@ module prim_ram_1p_adv import prim_ram_1p_pkg::*; #(
assign req_q_b = mubi4_test_true_loose(req_q);
assign write_q_b = mubi4_test_true_loose(write_q);

prim_ram_1p #(
.MemInitFile (MemInitFile),

.Width (TotalWidth),
.Depth (Depth),
.DataBitsPerMask (LocalDataBitsPerMask)
) u_mem (
.clk_i,

.req_i (req_q_b),
.write_i (write_q_b),
.addr_i (addr_q),
.wdata_i (wdata_q),
.wmask_i (wmask_q),
.rdata_o (rdata_sram),
.cfg_i
);
logic [NumRamInst-1:0] inst_req_d, inst_req_q, rvalid_inst;
logic [InstAw-1:0] inst_addr;
logic [NumRamInst-1:0] [Width-1:0] inst_rdata;

// The lower InstAw bits of the address are used to address within one RAM primitive
assign inst_addr = addr_q[InstAw-1:0];

// The upper bits Aw-1:InstAw of the address select which RAM instance is selected. A special case
// is needed when no tiling is performed and only a single RAM macro is instantiated. Here, we
// can directly use the request signal and no demuxing is needed.
always_comb begin
inst_req_d = '0;

for (int i = 0; i < NumRamInst; i++) begin
if (NumRamInst == 1) begin
inst_req_d[i] = req_q_b;
end else begin
if (req_q_b && (i == addr_q[Aw-1:InstAw])) begin
inst_req_d[i] = 1'b1;
end
end
end
end

// Flop the instance request signal to know
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
inst_req_q <= '0;
end else begin
inst_req_q <= inst_req_d;
end
end

// Ensure that only one RAM instance gets activated
`ASSERT(OneHotInstReq_A, $onehot0(inst_req_d))

for (genvar i = 0; i < NumRamInst; i++) begin : gen_ram_inst
prim_ram_1p #(
.MemInitFile (MemInitFile),

.Width (TotalWidth),
.Depth (InstDepth),
.DataBitsPerMask (LocalDataBitsPerMask)
) u_mem (
.clk_i,

.req_i (inst_req_d[i]),
.write_i (write_q_b),
.addr_i (inst_addr),
.wdata_i (wdata_q),
.wmask_i (wmask_q),
.rdata_o (inst_rdata[i]),
.cfg_i (cfg_i[i])
);
end

// Mux output data
always_comb begin
rdata_sram = '0;

for (int i = 0; i < NumRamInst; i++) begin
// Determine which RAM tile we accessed based on the floped inst_req signal and we really
// got an rvalid. This determines if we mux the output data of that particular RAM tile.
rvalid_inst[i] = mubi4_test_true_strict(
mubi4_and_hi(mubi4_bool_to_mubi(inst_req_q[i]), rvalid_sram_q));

if(rvalid_inst[i]) begin
rdata_sram = inst_rdata[i];
end
end
end

assign rvalid_sram_d = mubi4_and_hi(req_q, mubi4_t'(~write_q));

Expand Down
46 changes: 25 additions & 21 deletions hw/ip/prim/rtl/prim_ram_1p_scr.sv
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

module prim_ram_1p_scr import prim_ram_1p_pkg::*; #(
parameter int Depth = 16*1024, // Needs to be a power of 2 if NumAddrScrRounds > 0.
parameter int InstDepth = Depth,
parameter int Width = 32, // Needs to be byte aligned if byte parity is enabled.
parameter int DataBitsPerMask = 8, // Needs to be set to 8 in case of byte parity.
parameter bit EnableParity = 1, // Enable byte parity.
Expand Down Expand Up @@ -58,39 +59,41 @@ module prim_ram_1p_scr import prim_ram_1p_pkg::*; #(
// use the same key, but they use a different IV
localparam int DataKeyWidth = 128,
// Each 64 bit scrambling primitive requires a 64bit IV
localparam int NonceWidth = 64 * NumParScr
localparam int NonceWidth = 64 * NumParScr,
// Compute RAM tiling
localparam int NumRamInst = $ceil(Depth / InstDepth)
) (
input clk_i,
input rst_ni,
input clk_i,
input rst_ni,

// Key interface. Memory requests will not be granted if key_valid is set to 0.
input key_valid_i,
input [DataKeyWidth-1:0] key_i,
input [NonceWidth-1:0] nonce_i,
input key_valid_i,
input [DataKeyWidth-1:0] key_i,
input [NonceWidth-1:0] nonce_i,

// Interface to TL-UL SRAM adapter
input req_i,
output logic gnt_o,
input write_i,
input [AddrWidth-1:0] addr_i,
input [Width-1:0] wdata_i,
input [Width-1:0] wmask_i, // Needs to be byte-aligned for parity
input req_i,
output logic gnt_o,
input write_i,
input [AddrWidth-1:0] addr_i,
input [Width-1:0] wdata_i,
input [Width-1:0] wmask_i, // Needs to be byte-aligned for parity
// On integrity errors, the primitive surpresses any real transaction to the memory.
input intg_error_i,
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 [31:0] raddr_o, // Read address for error reporting.
input intg_error_i,
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 [31:0] raddr_o, // Read address for error reporting.

// config
input ram_1p_cfg_t cfg_i,
input ram_1p_cfg_t [NumRamInst-1:0] cfg_i,

// Write currently pending inside this module.
output logic wr_collision_o,
output logic write_pending_o,
output logic wr_collision_o,
output logic write_pending_o,

// When detecting multi-bit encoding errors, raise alert.
output logic alert_o
output logic alert_o
);

import prim_mubi_pkg::mubi4_t;
Expand Down Expand Up @@ -481,6 +484,7 @@ module prim_ram_1p_scr import prim_ram_1p_pkg::*; #(

prim_ram_1p_adv #(
.Depth(Depth),
.InstDepth(InstDepth),
.Width(Width),
.DataBitsPerMask(DataBitsPerMask),
.EnableECC(1'b0),
Expand Down
22 changes: 13 additions & 9 deletions hw/ip/prim_generic/rtl/prim_generic_ram_1p.sv
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,24 @@
module prim_generic_ram_1p import prim_ram_1p_pkg::*; #(
parameter int Width = 32, // bit
parameter int Depth = 128,
parameter int InstDepth = Depth,
parameter int DataBitsPerMask = 1, // Number of data bits per bit of write mask
parameter MemInitFile = "", // VMEM file to initialize the memory with

localparam int Aw = $clog2(Depth) // derived parameter
localparam int Aw = $clog2(Depth), // derived parameter
// Compute RAM tiling
localparam int NumRamInst = $ceil(Depth / InstDepth)
) (
input logic clk_i,
input logic clk_i,

input logic req_i,
input logic write_i,
input logic [Aw-1:0] addr_i,
input logic [Width-1:0] wdata_i,
input logic [Width-1:0] wmask_i,
output logic [Width-1:0] rdata_o, // Read data. Data is returned one cycle after req_i is high.
input ram_1p_cfg_t cfg_i
input logic req_i,
input logic write_i,
input logic [Aw-1:0] addr_i,
input logic [Width-1:0] wdata_i,
input logic [Width-1:0] wmask_i,
output logic [Width-1:0] rdata_o, // Read data. Data is returned one cycle after req_i
// is high.
input ram_1p_cfg_t [NumRamInst-1:0] cfg_i
);

// For certain synthesis experiments we compile the design with generic models to get an unmapped
Expand Down
15 changes: 15 additions & 0 deletions hw/ip/sram_ctrl/data/sram_ctrl.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,20 @@
type: "int",
default: "0x1000"
},
{ name: "InstSize",
desc: "Memory size of a single RAM tile (in bytes).",
type: "int",
default: "4096"
local: "false"
expose: "true"
},
{ name: "NumRamInst",
desc: "Number of internal RAM instances. Must be the same as ceil(MemSizeRam / InstSize) .",
type: "int",
default: "1"
local: "false"
expose: "true"
},
{ name: "InstrExec",
desc: "Support execution from SRAM",
type: "bit",
Expand Down Expand Up @@ -155,6 +169,7 @@
type: "uni"
name: "cfg"
act: "rcv"
width: "NumRamInst",
default: "'0"
package: "prim_ram_1p_pkg"
},
Expand Down
18 changes: 9 additions & 9 deletions hw/ip/sram_ctrl/doc/interfaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ Referring to the [Comportable guideline for peripheral device functionality](htt

## [Inter-Module Signals](https://opentitan.org/book/doc/contributing/hw/comportability/index.html#inter-signal-handling)

| Port Name | Package::Struct | Type | Act | Width | Description |
|:-------------------|:----------------------------|:--------|:------|--------:|:--------------|
| sram_otp_key | otp_ctrl_pkg::sram_otp_key | req_rsp | req | 1 | |
| cfg | prim_ram_1p_pkg::ram_1p_cfg | uni | rcv | 1 | |
| lc_escalate_en | lc_ctrl_pkg::lc_tx | uni | rcv | 1 | |
| lc_hw_debug_en | lc_ctrl_pkg::lc_tx | uni | rcv | 1 | |
| otp_en_sram_ifetch | prim_mubi_pkg::mubi8 | uni | rcv | 1 | |
| regs_tl | tlul_pkg::tl | req_rsp | rsp | 1 | |
| ram_tl | tlul_pkg::tl | req_rsp | rsp | 1 | |
| Port Name | Package::Struct | Type | Act | Width | Description |
|:-------------------|:----------------------------|:--------|:------|:-----------|:--------------|
| sram_otp_key | otp_ctrl_pkg::sram_otp_key | req_rsp | req | 1 | |
| cfg | prim_ram_1p_pkg::ram_1p_cfg | uni | rcv | NumRamInst | |
| lc_escalate_en | lc_ctrl_pkg::lc_tx | uni | rcv | 1 | |
| lc_hw_debug_en | lc_ctrl_pkg::lc_tx | uni | rcv | 1 | |
| otp_en_sram_ifetch | prim_mubi_pkg::mubi8 | uni | rcv | 1 | |
| regs_tl | tlul_pkg::tl | req_rsp | rsp | 1 | |
| ram_tl | tlul_pkg::tl | req_rsp | rsp | 1 | |

## Security Alerts

Expand Down
Loading

0 comments on commit 9cf4b18

Please sign in to comment.