mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-24 13:57:19 -04:00
Add and use a 'badbit' RAM for ICache tests
This does nothing by default, just wrapping up a prim_generic_ram_1p. But we can bind an interface into it to inject bit errors by forcing the bad_bit_mask signal. Note that the icache uses ECC RAMs in a reasonably unusual way (ORing together inputs and outputs from its data RAMs), so we have to do this ourselves, rather than piggy-backing on the implementation or testing done for e.g. OpenTitan's prim_ram_1p_adv.
This commit is contained in:
parent
8a145a9330
commit
48fbea833f
4 changed files with 119 additions and 0 deletions
|
@ -20,6 +20,7 @@ targets:
|
|||
sim:
|
||||
parameters:
|
||||
- ICacheECC
|
||||
- PRIM_DEFAULT_IMPL=prim_pkg::ImplBadbit
|
||||
filesets:
|
||||
- files_rtl
|
||||
- files_dv
|
||||
|
@ -32,3 +33,9 @@ parameters:
|
|||
default: 0
|
||||
paramtype: vlogparam
|
||||
description: "Enable ECC protection in instruction cache"
|
||||
|
||||
PRIM_DEFAULT_IMPL:
|
||||
datatype: str
|
||||
paramtype: vlogdefine
|
||||
description: Primitives implementation to use, e.g. "prim_pkg::ImplGeneric".
|
||||
default: prim_pkg::ImplBadbit
|
||||
|
|
11
dv/uvm/icache/dv/prim_badbit/README.md
Normal file
11
dv/uvm/icache/dv/prim_badbit/README.md
Normal file
|
@ -0,0 +1,11 @@
|
|||
Badbit RAM
|
||||
==========
|
||||
|
||||
This is an SRAM wrapper that allows a testbench to force bit errors onthe read interface.
|
||||
|
||||
This works as a dummy technology library.
|
||||
Instantiate it by adding setting `PRIM_DEFAULT_IMPL` to prim_pkg::ImplBadbit (see the README.md in the prim directory for details).
|
||||
To use it, bind a module or interface into an instance of `prim_badbit_ram_1p` and force the value of `bad_bit_mask`, which is XOR'd with rdata.
|
||||
|
||||
To make this easier to use, we don't vary the width of `bad_bit_mask` with the `Width` parameter: it's a constant 128.
|
||||
This means that the bound interface doesn't need to be parameterised.
|
20
dv/uvm/icache/dv/prim_badbit/prim_badbit_ram_1p.core
Normal file
20
dv/uvm/icache/dv/prim_badbit/prim_badbit_ram_1p.core
Normal file
|
@ -0,0 +1,20 @@
|
|||
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:prim_badbit:ram_1p"
|
||||
description: "Single-port RAM which allows a bound interface to inject errors"
|
||||
filesets:
|
||||
files_rtl:
|
||||
depend:
|
||||
- lowrisc:prim_generic:ram_1p
|
||||
- lowrisc:prim:assert
|
||||
files:
|
||||
- prim_badbit_ram_1p.sv
|
||||
file_type: systemVerilogSource
|
||||
|
||||
targets:
|
||||
default:
|
||||
filesets:
|
||||
- files_rtl
|
81
dv/uvm/icache/dv/prim_badbit/prim_badbit_ram_1p.sv
Normal file
81
dv/uvm/icache/dv/prim_badbit/prim_badbit_ram_1p.sv
Normal file
|
@ -0,0 +1,81 @@
|
|||
// Copyright lowRISC contributors.
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
// Single-port SRAM model which allows a test to corrupt read responses from the underlying memory.
|
||||
//
|
||||
// To use this, instantiate it then bind in a module or interface that has bad_bit_mask as an
|
||||
// output. A nonzero bit in bad_bit_mask will cause the corresponding bit to be flipped in the
|
||||
// response.
|
||||
|
||||
`include "prim_assert.sv"
|
||||
|
||||
module prim_badbit_ram_1p #(
|
||||
parameter int Width = 32, // bit
|
||||
parameter int Depth = 128,
|
||||
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
|
||||
) (
|
||||
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.
|
||||
);
|
||||
|
||||
logic [Width-1:0] sram_rdata;
|
||||
|
||||
prim_generic_ram_1p #(
|
||||
.Width (Width),
|
||||
.Depth (Depth),
|
||||
.DataBitsPerMask (DataBitsPerMask),
|
||||
.MemInitFile (MemInitFile)
|
||||
) u_mem (
|
||||
.clk_i (clk_i),
|
||||
|
||||
.req_i (req_i),
|
||||
.write_i (write_i),
|
||||
.addr_i (addr_i),
|
||||
.wdata_i (wdata_i),
|
||||
.wmask_i (wmask_i),
|
||||
.rdata_o (sram_rdata)
|
||||
);
|
||||
|
||||
// This module doesn't work with Verilator (because of the wired-or). Because we define the
|
||||
// "badbit" ram as a technology library, it gets picked up and parsed by any tool using the Ibex
|
||||
// repo. Rather than telling Verilator to ignore the whole lot (which causes NOTFOUNDMODULE
|
||||
// warnings), we just hide the actual guts.
|
||||
`ifdef VERILATOR
|
||||
assign rdata_o = sram_rdata;
|
||||
`else
|
||||
// Making bad_bit_mask a constant size makes this easier to use (because you don't need to faff
|
||||
// around with parameterised interfaces in your UVM database). Check that rdata_o is actually
|
||||
// controllable. Similarly, we make the address a constant width: make sure that's large enough.
|
||||
`ASSERT_INIT(WidthSmallEnough, Width <= 128)
|
||||
`ASSERT_INIT(AddrSmallEnough, Aw <= 32)
|
||||
|
||||
// Make the Width parameter easily accessible to bound-in modules.
|
||||
logic [31:0] width;
|
||||
assign width = Width;
|
||||
|
||||
// Similarly, extend addr and sram_rdata (the un-fiddled value)
|
||||
logic [31:0] addr;
|
||||
logic [127:0] rdata;
|
||||
assign addr = {{32-Aw{1'b0}}, addr_i};
|
||||
assign rdata = {{128-Width{1'b0}}, sram_rdata};
|
||||
|
||||
// To inject errors, bind in an interface with bad_bit_mask as an output and assign one of the
|
||||
// bits in bad_bit_mask[Width-1:0] to one. The wired-OR together with an assignment to zero means
|
||||
// this acts like a weak pull-down.
|
||||
wor [127:0] bad_bit_mask;
|
||||
assign bad_bit_mask = 128'b0;
|
||||
|
||||
assign rdata_o = sram_rdata ^ bad_bit_mask;
|
||||
`endif // VERILATOR
|
||||
|
||||
endmodule
|
Loading…
Add table
Add a link
Reference in a new issue