mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-20 04:07:36 -04:00
cache_subsystem: Parametrise AXI interface (#982)
Parametrise the AXI interface of CVA6. With this PR, both cache subsystems support variable AXI address widths. The write-through cache furthermore supports variable AXI data widths. Moreover, this PR includes a modular AXI testbench for the WT cache to test the introduced changes. The following configurations of the WT cache have been verified: XLEN Cacheline Width AXI data width AXI address width 64 128 64 64 64 128 128 52 64 512 128 64 32 512 256 48 32 64 32 48
This commit is contained in:
parent
f346d6604f
commit
17743bc712
35 changed files with 1787 additions and 185 deletions
|
@ -19,8 +19,12 @@
|
|||
module axi_adapter #(
|
||||
parameter int unsigned DATA_WIDTH = 256,
|
||||
parameter logic CRITICAL_WORD_FIRST = 0, // the AXI subsystem needs to support wrapping reads for this feature
|
||||
parameter int unsigned AXI_ID_WIDTH = 10,
|
||||
parameter int unsigned CACHELINE_BYTE_OFFSET = 8
|
||||
parameter int unsigned CACHELINE_BYTE_OFFSET = 8,
|
||||
parameter int unsigned AXI_ADDR_WIDTH = 0,
|
||||
parameter int unsigned AXI_DATA_WIDTH = 0,
|
||||
parameter int unsigned AXI_ID_WIDTH = 0,
|
||||
parameter type axi_req_t = ariane_axi::req_t,
|
||||
parameter type axi_rsp_t = ariane_axi::resp_t
|
||||
)(
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
|
@ -31,23 +35,23 @@ module axi_adapter #(
|
|||
output logic gnt_o,
|
||||
input logic [riscv::XLEN-1:0] addr_i,
|
||||
input logic we_i,
|
||||
input logic [(DATA_WIDTH/riscv::XLEN)-1:0][riscv::XLEN-1:0] wdata_i,
|
||||
input logic [(DATA_WIDTH/riscv::XLEN)-1:0][(riscv::XLEN/8)-1:0] be_i,
|
||||
input logic [(DATA_WIDTH/AXI_DATA_WIDTH)-1:0][AXI_DATA_WIDTH-1:0] wdata_i,
|
||||
input logic [(DATA_WIDTH/AXI_DATA_WIDTH)-1:0][(AXI_DATA_WIDTH/8)-1:0] be_i,
|
||||
input logic [1:0] size_i,
|
||||
input logic [AXI_ID_WIDTH-1:0] id_i,
|
||||
// read port
|
||||
output logic valid_o,
|
||||
output logic [(DATA_WIDTH/riscv::XLEN)-1:0][riscv::XLEN-1:0] rdata_o,
|
||||
output logic [(DATA_WIDTH/AXI_DATA_WIDTH)-1:0][AXI_DATA_WIDTH-1:0] rdata_o,
|
||||
output logic [AXI_ID_WIDTH-1:0] id_o,
|
||||
// critical word - read port
|
||||
output logic [riscv::XLEN-1:0] critical_word_o,
|
||||
output logic [AXI_DATA_WIDTH-1:0] critical_word_o,
|
||||
output logic critical_word_valid_o,
|
||||
// AXI port
|
||||
output ariane_axi::req_t axi_req_o,
|
||||
input ariane_axi::resp_t axi_resp_i
|
||||
output axi_req_t axi_req_o,
|
||||
input axi_rsp_t axi_resp_i
|
||||
);
|
||||
localparam BURST_SIZE = DATA_WIDTH/riscv::XLEN-1;
|
||||
localparam ADDR_INDEX = ($clog2(DATA_WIDTH/riscv::XLEN) > 0) ? $clog2(DATA_WIDTH/riscv::XLEN) : 1;
|
||||
localparam BURST_SIZE = (DATA_WIDTH/AXI_DATA_WIDTH)-1;
|
||||
localparam ADDR_INDEX = ($clog2(DATA_WIDTH/AXI_DATA_WIDTH) > 0) ? $clog2(DATA_WIDTH/AXI_DATA_WIDTH) : 1;
|
||||
|
||||
enum logic [3:0] {
|
||||
IDLE, WAIT_B_VALID, WAIT_AW_READY, WAIT_LAST_W_READY, WAIT_LAST_W_READY_AW_READY, WAIT_AW_READY_BURST,
|
||||
|
@ -56,9 +60,9 @@ module axi_adapter #(
|
|||
|
||||
// counter for AXI transfers
|
||||
logic [ADDR_INDEX-1:0] cnt_d, cnt_q;
|
||||
logic [(DATA_WIDTH/riscv::XLEN)-1:0][riscv::XLEN-1:0] cache_line_d, cache_line_q;
|
||||
logic [(DATA_WIDTH/AXI_DATA_WIDTH)-1:0][AXI_DATA_WIDTH-1:0] cache_line_d, cache_line_q;
|
||||
// save the address for a read, as we allow for non-cacheline aligned accesses
|
||||
logic [(DATA_WIDTH/riscv::XLEN)-1:0] addr_offset_d, addr_offset_q;
|
||||
logic [(DATA_WIDTH/AXI_DATA_WIDTH)-1:0] addr_offset_d, addr_offset_q;
|
||||
logic [AXI_ID_WIDTH-1:0] id_d, id_q;
|
||||
logic [ADDR_INDEX-1:0] index;
|
||||
// save the atomic operation and size
|
||||
|
@ -68,6 +72,7 @@ module axi_adapter #(
|
|||
always_comb begin : axi_fsm
|
||||
// Default assignments
|
||||
axi_req_o.aw_valid = 1'b0;
|
||||
// Cast to AXI address width
|
||||
axi_req_o.aw.addr = addr_i;
|
||||
axi_req_o.aw.prot = 3'b0;
|
||||
axi_req_o.aw.region = 4'b0;
|
||||
|
@ -82,9 +87,13 @@ module axi_adapter #(
|
|||
axi_req_o.aw.user = '0;
|
||||
|
||||
axi_req_o.ar_valid = 1'b0;
|
||||
// Cast to AXI address width
|
||||
axi_req_o.ar.addr = addr_i;
|
||||
// in case of a single request or wrapping transfer we can simply begin at the address, if we want to request a cache-line
|
||||
// with an incremental transfer we need to output the corresponding base address of the cache line
|
||||
axi_req_o.ar.addr = (CRITICAL_WORD_FIRST || type_i == ariane_axi::SINGLE_REQ) ? addr_i : { addr_i[(riscv::XLEN-1):CACHELINE_BYTE_OFFSET], {{CACHELINE_BYTE_OFFSET}{1'b0}}};
|
||||
if (!CRITICAL_WORD_FIRST && type_i != ariane_axi::SINGLE_REQ) begin
|
||||
axi_req_o.ar.addr[CACHELINE_BYTE_OFFSET-1:0] = '0;
|
||||
end
|
||||
axi_req_o.ar.prot = 3'b0;
|
||||
axi_req_o.ar.region = 4'b0;
|
||||
axi_req_o.ar.len = 8'b0;
|
||||
|
|
|
@ -22,7 +22,11 @@
|
|||
module axi_shim #(
|
||||
parameter int unsigned AxiUserWidth = 64, // data width in dwords, this is also the maximum burst length, must be >=2
|
||||
parameter int unsigned AxiNumWords = 4, // data width in dwords, this is also the maximum burst length, must be >=2
|
||||
parameter int unsigned AxiIdWidth = 4 // stick to the spec
|
||||
parameter int unsigned AxiAddrWidth = 0,
|
||||
parameter int unsigned AxiDataWidth = 0,
|
||||
parameter int unsigned AxiIdWidth = 0,
|
||||
parameter type axi_req_t = ariane_axi::req_t,
|
||||
parameter type axi_rsp_t = ariane_axi::resp_t
|
||||
) (
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
|
@ -30,28 +34,28 @@ module axi_shim #(
|
|||
// request
|
||||
input logic rd_req_i,
|
||||
output logic rd_gnt_o,
|
||||
input logic [63:0] rd_addr_i,
|
||||
input logic [AxiAddrWidth-1:0] rd_addr_i,
|
||||
input logic [$clog2(AxiNumWords)-1:0] rd_blen_i, // axi convention: LEN-1
|
||||
input logic [1:0] rd_size_i,
|
||||
input logic [2:0] rd_size_i,
|
||||
input logic [AxiIdWidth-1:0] rd_id_i, // use same ID for reads, or make sure you only have one outstanding read tx
|
||||
input logic rd_lock_i,
|
||||
// read response (we have to unconditionally sink the response)
|
||||
input logic rd_rdy_i,
|
||||
output logic rd_last_o,
|
||||
output logic rd_valid_o,
|
||||
output logic [63:0] rd_data_o,
|
||||
output logic [AxiDataWidth-1:0] rd_data_o,
|
||||
output logic [AxiUserWidth-1:0] rd_user_o,
|
||||
output logic [AxiIdWidth-1:0] rd_id_o,
|
||||
output logic rd_exokay_o, // indicates whether exclusive tx succeeded
|
||||
// write channel
|
||||
input logic wr_req_i,
|
||||
output logic wr_gnt_o,
|
||||
input logic [63:0] wr_addr_i,
|
||||
input logic [AxiNumWords-1:0][63:0] wr_data_i,
|
||||
input logic [AxiNumWords-1:0][AxiUserWidth-1:0] wr_user_i,
|
||||
input logic [AxiNumWords-1:0][7:0] wr_be_i,
|
||||
input logic [AxiAddrWidth-1:0] wr_addr_i,
|
||||
input logic [AxiNumWords-1:0][AxiDataWidth-1:0] wr_data_i,
|
||||
input logic [AxiNumWords-1:0][AxiUserWidth-1:0] wr_user_i,
|
||||
input logic [AxiNumWords-1:0][(AxiDataWidth/8)-1:0] wr_be_i,
|
||||
input logic [$clog2(AxiNumWords)-1:0] wr_blen_i, // axi convention: LEN-1
|
||||
input logic [1:0] wr_size_i,
|
||||
input logic [2:0] wr_size_i,
|
||||
input logic [AxiIdWidth-1:0] wr_id_i,
|
||||
input logic wr_lock_i,
|
||||
input logic [5:0] wr_atop_i,
|
||||
|
@ -61,8 +65,8 @@ module axi_shim #(
|
|||
output logic [AxiIdWidth-1:0] wr_id_o,
|
||||
output logic wr_exokay_o, // indicates whether exclusive tx succeeded
|
||||
// AXI port
|
||||
output ariane_axi::req_t axi_req_o,
|
||||
input ariane_axi::resp_t axi_resp_i
|
||||
output axi_req_t axi_req_o,
|
||||
input axi_rsp_t axi_resp_i
|
||||
);
|
||||
localparam AddrIndex = ($clog2(AxiNumWords) > 0) ? $clog2(AxiNumWords) : 1;
|
||||
|
||||
|
@ -82,7 +86,7 @@ module axi_shim #(
|
|||
|
||||
// address
|
||||
assign axi_req_o.aw.burst = axi_pkg::BURST_INCR; // Use BURST_INCR for AXI regular transaction
|
||||
assign axi_req_o.aw.addr = wr_addr_i;
|
||||
assign axi_req_o.aw.addr = wr_addr_i[AxiAddrWidth-1:0];
|
||||
assign axi_req_o.aw.size = wr_size_i;
|
||||
assign axi_req_o.aw.len = wr_blen_i;
|
||||
assign axi_req_o.aw.id = wr_id_i;
|
||||
|
@ -92,6 +96,8 @@ module axi_shim #(
|
|||
assign axi_req_o.aw.cache = 4'b0;
|
||||
assign axi_req_o.aw.qos = 4'b0;
|
||||
assign axi_req_o.aw.atop = wr_atop_i;
|
||||
assign axi_req_o.aw.user = '0;
|
||||
|
||||
// data
|
||||
assign axi_req_o.w.data = wr_data_i[wr_cnt_q];
|
||||
assign axi_req_o.w.user = wr_user_i[wr_cnt_q];
|
||||
|
@ -239,7 +245,7 @@ module axi_shim #(
|
|||
// in case of a wrapping transfer we can simply begin at the address, if we want to request a cache-line
|
||||
// with an incremental transfer we need to output the corresponding base address of the cache line
|
||||
assign axi_req_o.ar.burst = axi_pkg::BURST_INCR; // Use BURST_INCR for AXI regular transaction
|
||||
assign axi_req_o.ar.addr = rd_addr_i;
|
||||
assign axi_req_o.ar.addr = rd_addr_i[AxiAddrWidth-1:0];
|
||||
assign axi_req_o.ar.size = rd_size_i;
|
||||
assign axi_req_o.ar.len = rd_blen_i;
|
||||
assign axi_req_o.ar.id = rd_id_i;
|
||||
|
@ -248,6 +254,7 @@ module axi_shim #(
|
|||
assign axi_req_o.ar.lock = rd_lock_i;
|
||||
assign axi_req_o.ar.cache = 4'b0;
|
||||
assign axi_req_o.ar.qos = 4'b0;
|
||||
assign axi_req_o.ar.user = '0;
|
||||
|
||||
// make the read request
|
||||
assign axi_req_o.ar_valid = rd_req_i;
|
||||
|
@ -285,7 +292,9 @@ module axi_shim #(
|
|||
`ifndef VERILATOR
|
||||
initial begin
|
||||
assert (AxiNumWords >= 1) else
|
||||
$fatal(1,"[axi adapter] AxiNumWords must be >= 1");
|
||||
$fatal(1, "[axi adapter] AxiNumWords must be >= 1");
|
||||
assert (AxiIdWidth >= 2) else
|
||||
$fatal(1, "[axi adapter] AXI id width must be at least 2 bit wide");
|
||||
end
|
||||
`endif
|
||||
//pragma translate_on
|
||||
|
|
|
@ -201,11 +201,7 @@ module cache_ctrl import ariane_pkg::*; import std_cache_pkg::*; #(
|
|||
end
|
||||
|
||||
// this is timing critical
|
||||
// req_port_o.data_rdata = cl_i[cl_offset +: 64];
|
||||
case (mem_req_q.index[3])
|
||||
1'b0: req_port_o.data_rdata = cl_i[63:0];
|
||||
1'b1: req_port_o.data_rdata = cl_i[127:64];
|
||||
endcase
|
||||
req_port_o.data_rdata = cl_i[cl_offset +: 64];
|
||||
|
||||
// report data for a read
|
||||
if (!mem_req_q.we) begin
|
||||
|
|
|
@ -116,7 +116,7 @@ module cva6_icache import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
assign cl_index = vaddr_d[ICACHE_INDEX_WIDTH-1:ICACHE_OFFSET_WIDTH];
|
||||
|
||||
|
||||
if (ArianeCfg.Axi64BitCompliant) begin : gen_axi_offset
|
||||
if (ArianeCfg.AxiCompliant) begin : gen_axi_offset
|
||||
// if we generate a noncacheable access, the word will be at offset 0 or 4 in the cl coming from memory
|
||||
assign cl_offset_d = ( dreq_o.ready & dreq_i.req) ? {dreq_i.vaddr>>2, 2'b0} :
|
||||
( paddr_is_nc & mem_data_req_o ) ? cl_offset_q[2]<<2 : // needed since we transfer 32bit over a 64bit AXI bus in this case
|
||||
|
|
|
@ -14,7 +14,12 @@
|
|||
//
|
||||
|
||||
module cva6_icache_axi_wrapper import ariane_pkg::*; import wt_cache_pkg::*; #(
|
||||
parameter ariane_cfg_t ArianeCfg = ArianeDefaultConfig // contains cacheable regions
|
||||
parameter ariane_cfg_t ArianeCfg = ArianeDefaultConfig, // contains cacheable regions
|
||||
parameter int unsigned AxiAddrWidth = 0,
|
||||
parameter int unsigned AxiDataWidth = 0,
|
||||
parameter int unsigned AxiIdWidth = 0,
|
||||
parameter type axi_req_t = ariane_axi::req_t,
|
||||
parameter type axi_rsp_t = ariane_axi::resp_t
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
|
@ -30,12 +35,12 @@ module cva6_icache_axi_wrapper import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
input icache_dreq_i_t dreq_i,
|
||||
output icache_dreq_o_t dreq_o,
|
||||
// AXI refill port
|
||||
output ariane_axi::req_t axi_req_o,
|
||||
input ariane_axi::resp_t axi_resp_i
|
||||
output axi_req_t axi_req_o,
|
||||
input axi_rsp_t axi_resp_i
|
||||
);
|
||||
|
||||
localparam AxiNumWords = (ICACHE_LINE_WIDTH/64) * (ICACHE_LINE_WIDTH > DCACHE_LINE_WIDTH) +
|
||||
(DCACHE_LINE_WIDTH/64) * (ICACHE_LINE_WIDTH <= DCACHE_LINE_WIDTH) ;
|
||||
localparam AxiNumWords = (ICACHE_LINE_WIDTH/AxiDataWidth) * (ICACHE_LINE_WIDTH > DCACHE_LINE_WIDTH) +
|
||||
(DCACHE_LINE_WIDTH/AxiDataWidth) * (ICACHE_LINE_WIDTH <= DCACHE_LINE_WIDTH) ;
|
||||
|
||||
logic icache_mem_rtrn_vld;
|
||||
icache_rtrn_t icache_mem_rtrn;
|
||||
|
@ -47,20 +52,20 @@ module cva6_icache_axi_wrapper import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
logic axi_rd_gnt;
|
||||
logic [63:0] axi_rd_addr;
|
||||
logic [$clog2(AxiNumWords)-1:0] axi_rd_blen;
|
||||
logic [1:0] axi_rd_size;
|
||||
logic [2:0] axi_rd_size;
|
||||
logic [$size(axi_resp_i.r.id)-1:0] axi_rd_id_in;
|
||||
logic axi_rd_rdy;
|
||||
logic axi_rd_lock;
|
||||
logic axi_rd_last;
|
||||
logic axi_rd_valid;
|
||||
logic [63:0] axi_rd_data;
|
||||
logic [AxiDataWidth-1:0] axi_rd_data;
|
||||
logic [$size(axi_resp_i.r.id)-1:0] axi_rd_id_out;
|
||||
logic axi_rd_exokay;
|
||||
|
||||
logic req_valid_d, req_valid_q;
|
||||
icache_req_t req_data_d, req_data_q;
|
||||
logic first_d, first_q;
|
||||
logic [ICACHE_LINE_WIDTH/64-1:0][63:0] rd_shift_d, rd_shift_q;
|
||||
logic [ICACHE_LINE_WIDTH/AxiDataWidth-1:0][AxiDataWidth-1:0] rd_shift_d, rd_shift_q;
|
||||
|
||||
// Keep read request asserted until we have an AXI grant. This is not guaranteed by icache (but
|
||||
// required by AXI).
|
||||
|
@ -75,7 +80,7 @@ module cva6_icache_axi_wrapper import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
|
||||
// Fetch a full cache line on a cache miss, or a single word on a bypassed access
|
||||
assign axi_rd_blen = (req_data_d.nc) ? '0 : ariane_pkg::ICACHE_LINE_WIDTH/64-1;
|
||||
assign axi_rd_size = 2'b11;
|
||||
assign axi_rd_size = $clog2(AxiDataWidth/8); // Maximum
|
||||
assign axi_rd_id_in = req_data_d.tid;
|
||||
assign axi_rd_rdy = 1'b1;
|
||||
assign axi_rd_lock = 1'b0;
|
||||
|
@ -118,9 +123,13 @@ module cva6_icache_axi_wrapper import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
// AXI shim
|
||||
// --------
|
||||
axi_shim #(
|
||||
.AxiUserWidth ( AXI_USER_WIDTH ),
|
||||
.AxiNumWords ( AxiNumWords ),
|
||||
.AxiIdWidth ( $size(axi_resp_i.r.id) )
|
||||
.AxiNumWords ( AxiNumWords ),
|
||||
.AxiAddrWidth ( AxiAddrWidth ),
|
||||
.AxiDataWidth ( AxiDataWidth ),
|
||||
.AxiIdWidth ( AxiIdWidth ),
|
||||
.AxiUserWidth ( AXI_USER_WIDTH ),
|
||||
.axi_req_t ( axi_req_t ),
|
||||
.axi_rsp_t ( axi_rsp_t )
|
||||
) i_axi_shim (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
|
@ -164,7 +173,11 @@ module cva6_icache_axi_wrapper import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
|
||||
if (axi_rd_valid) begin
|
||||
first_d = axi_rd_last;
|
||||
rd_shift_d = {axi_rd_data, rd_shift_q[ICACHE_LINE_WIDTH/64-1:1]};
|
||||
if (ICACHE_LINE_WIDTH == AxiDataWidth) begin
|
||||
rd_shift_d = axi_rd_data;
|
||||
end else begin
|
||||
rd_shift_d = {axi_rd_data, rd_shift_q[ICACHE_LINE_WIDTH/AxiDataWidth-1:1]};
|
||||
end
|
||||
|
||||
// If this is a single word transaction, we need to make sure that word is placed at offset 0
|
||||
if (first_q) begin
|
||||
|
|
|
@ -17,7 +17,12 @@
|
|||
// --------------
|
||||
|
||||
module miss_handler import ariane_pkg::*; import std_cache_pkg::*; #(
|
||||
parameter int unsigned NR_PORTS = 3
|
||||
parameter int unsigned NR_PORTS = 3,
|
||||
parameter int unsigned AXI_ADDR_WIDTH = 0,
|
||||
parameter int unsigned AXI_DATA_WIDTH = 0,
|
||||
parameter int unsigned AXI_ID_WIDTH = 0,
|
||||
parameter type axi_req_t = ariane_axi::req_t,
|
||||
parameter type axi_rsp_t = ariane_axi::resp_t
|
||||
)(
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
|
@ -33,8 +38,8 @@ module miss_handler import ariane_pkg::*; import std_cache_pkg::*; #(
|
|||
output logic [NR_PORTS-1:0][63:0] bypass_data_o,
|
||||
|
||||
// AXI port
|
||||
output ariane_axi::req_t axi_bypass_o,
|
||||
input ariane_axi::resp_t axi_bypass_i,
|
||||
output axi_req_t axi_bypass_o,
|
||||
input axi_rsp_t axi_bypass_i,
|
||||
|
||||
// Miss handling (~> cacheline refill)
|
||||
output logic [NR_PORTS-1:0] miss_gnt_o,
|
||||
|
@ -42,8 +47,8 @@ module miss_handler import ariane_pkg::*; import std_cache_pkg::*; #(
|
|||
|
||||
output logic [63:0] critical_word_o,
|
||||
output logic critical_word_valid_o,
|
||||
output ariane_axi::req_t axi_data_o,
|
||||
input ariane_axi::resp_t axi_data_i,
|
||||
output axi_req_t axi_data_o,
|
||||
input axi_rsp_t axi_data_i,
|
||||
|
||||
input logic [NR_PORTS-1:0][55:0] mshr_addr_i,
|
||||
output logic [NR_PORTS-1:0] mshr_addr_matches_o,
|
||||
|
@ -559,18 +564,26 @@ module miss_handler import ariane_pkg::*; import std_cache_pkg::*; #(
|
|||
// ----------------------
|
||||
// Bypass AXI Interface
|
||||
// ----------------------
|
||||
// Cast bypass_adapter_req.addr to axi_adapter port size
|
||||
logic [riscv::XLEN-1:0] bypass_addr;
|
||||
assign bypass_addr = bypass_adapter_req.addr;
|
||||
|
||||
axi_adapter #(
|
||||
.DATA_WIDTH (64),
|
||||
.AXI_ID_WIDTH (4),
|
||||
.CACHELINE_BYTE_OFFSET(DCACHE_BYTE_OFFSET)
|
||||
.DATA_WIDTH ( 64 ),
|
||||
.CACHELINE_BYTE_OFFSET ( DCACHE_BYTE_OFFSET ),
|
||||
.AXI_ADDR_WIDTH ( AXI_ADDR_WIDTH ),
|
||||
.AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
|
||||
.AXI_ID_WIDTH ( AXI_ID_WIDTH ),
|
||||
.axi_req_t ( axi_req_t ),
|
||||
.axi_rsp_t ( axi_rsp_t )
|
||||
) i_bypass_axi_adapter (
|
||||
.clk_i (clk_i),
|
||||
.rst_ni (rst_ni),
|
||||
.req_i (bypass_adapter_req.req),
|
||||
.type_i (bypass_adapter_req.reqtype),
|
||||
.amo_i (bypass_adapter_req.amo),
|
||||
.id_i (bypass_adapter_req.id),
|
||||
.addr_i (bypass_adapter_req.addr),
|
||||
.id_i (({{AXI_ID_WIDTH-4{1'b0}}, bypass_adapter_req.id})),
|
||||
.addr_i (bypass_addr),
|
||||
.wdata_i (bypass_adapter_req.wdata),
|
||||
.we_i (bypass_adapter_req.we),
|
||||
.be_i (bypass_adapter_req.be),
|
||||
|
@ -588,10 +601,18 @@ module miss_handler import ariane_pkg::*; import std_cache_pkg::*; #(
|
|||
// ----------------------
|
||||
// Cache Line AXI Refill
|
||||
// ----------------------
|
||||
// Cast req_fsm_miss_addr to axi_adapter port size
|
||||
logic [riscv::XLEN-1:0] miss_addr;
|
||||
assign miss_addr = req_fsm_miss_addr;
|
||||
|
||||
axi_adapter #(
|
||||
.DATA_WIDTH ( DCACHE_LINE_WIDTH ),
|
||||
.AXI_ID_WIDTH ( 4 ),
|
||||
.CACHELINE_BYTE_OFFSET ( DCACHE_BYTE_OFFSET )
|
||||
.CACHELINE_BYTE_OFFSET ( DCACHE_BYTE_OFFSET ),
|
||||
.AXI_ADDR_WIDTH ( AXI_ADDR_WIDTH ),
|
||||
.AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
|
||||
.AXI_ID_WIDTH ( AXI_ID_WIDTH ),
|
||||
.axi_req_t ( axi_req_t ),
|
||||
.axi_rsp_t ( axi_rsp_t )
|
||||
) i_miss_axi_adapter (
|
||||
.clk_i,
|
||||
.rst_ni,
|
||||
|
@ -599,12 +620,12 @@ module miss_handler import ariane_pkg::*; import std_cache_pkg::*; #(
|
|||
.type_i ( req_fsm_miss_req ),
|
||||
.amo_i ( AMO_NONE ),
|
||||
.gnt_o ( gnt_miss_fsm ),
|
||||
.addr_i ( req_fsm_miss_addr ),
|
||||
.addr_i ( miss_addr ),
|
||||
.we_i ( req_fsm_miss_we ),
|
||||
.wdata_i ( req_fsm_miss_wdata ),
|
||||
.be_i ( req_fsm_miss_be ),
|
||||
.size_i ( req_fsm_miss_size ),
|
||||
.id_i ( 4'b1100 ),
|
||||
.id_i ( {{AXI_ID_WIDTH-4{1'b0}}, 4'b1100} ),
|
||||
.valid_o ( valid_miss_fsm ),
|
||||
.rdata_o ( data_miss_fsm ),
|
||||
.id_o ( ),
|
||||
|
|
|
@ -16,7 +16,15 @@
|
|||
|
||||
|
||||
module std_cache_subsystem import ariane_pkg::*; import std_cache_pkg::*; #(
|
||||
parameter ariane_cfg_t ArianeCfg = ArianeDefaultConfig // contains cacheable regions
|
||||
parameter ariane_cfg_t ArianeCfg = ArianeDefaultConfig, // contains cacheable regions
|
||||
parameter int unsigned AxiAddrWidth = 0,
|
||||
parameter int unsigned AxiDataWidth = 0,
|
||||
parameter int unsigned AxiIdWidth = 0,
|
||||
parameter type axi_ar_chan_t = ariane_axi::ar_chan_t,
|
||||
parameter type axi_aw_chan_t = ariane_axi::aw_chan_t,
|
||||
parameter type axi_w_chan_t = ariane_axi::w_chan_t,
|
||||
parameter type axi_req_t = ariane_axi::req_t,
|
||||
parameter type axi_rsp_t = ariane_axi::resp_t
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
|
@ -45,21 +53,26 @@ module std_cache_subsystem import ariane_pkg::*; import std_cache_pkg::*; #(
|
|||
input dcache_req_i_t [2:0] dcache_req_ports_i, // to/from LSU
|
||||
output dcache_req_o_t [2:0] dcache_req_ports_o, // to/from LSU
|
||||
// memory side
|
||||
output ariane_axi::req_t axi_req_o,
|
||||
input ariane_axi::resp_t axi_resp_i
|
||||
output axi_req_t axi_req_o,
|
||||
input axi_rsp_t axi_resp_i
|
||||
);
|
||||
|
||||
assign wbuffer_empty_o = 1'b1;
|
||||
|
||||
ariane_axi::req_t axi_req_icache;
|
||||
ariane_axi::resp_t axi_resp_icache;
|
||||
ariane_axi::req_t axi_req_bypass;
|
||||
ariane_axi::resp_t axi_resp_bypass;
|
||||
ariane_axi::req_t axi_req_data;
|
||||
ariane_axi::resp_t axi_resp_data;
|
||||
axi_req_t axi_req_icache;
|
||||
axi_rsp_t axi_resp_icache;
|
||||
axi_req_t axi_req_bypass;
|
||||
axi_rsp_t axi_resp_bypass;
|
||||
axi_req_t axi_req_data;
|
||||
axi_rsp_t axi_resp_data;
|
||||
|
||||
cva6_icache_axi_wrapper #(
|
||||
.ArianeCfg ( ArianeCfg )
|
||||
.ArianeCfg ( ArianeCfg ),
|
||||
.AxiAddrWidth ( AxiAddrWidth ),
|
||||
.AxiDataWidth ( AxiDataWidth ),
|
||||
.AxiIdWidth ( AxiIdWidth ),
|
||||
.axi_req_t ( axi_req_t ),
|
||||
.axi_rsp_t ( axi_rsp_t )
|
||||
) i_cva6_icache_axi_wrapper (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
|
@ -80,7 +93,12 @@ module std_cache_subsystem import ariane_pkg::*; import std_cache_pkg::*; #(
|
|||
// Port 1: Load Unit
|
||||
// Port 2: Store Unit
|
||||
std_nbdcache #(
|
||||
.ArianeCfg ( ArianeCfg )
|
||||
.ArianeCfg ( ArianeCfg ),
|
||||
.AXI_ADDR_WIDTH ( AxiAddrWidth ),
|
||||
.AXI_DATA_WIDTH ( AxiDataWidth ),
|
||||
.AXI_ID_WIDTH ( AxiIdWidth ),
|
||||
.axi_req_t ( axi_req_t ),
|
||||
.axi_rsp_t ( axi_rsp_t )
|
||||
) i_nbdcache (
|
||||
.clk_i,
|
||||
.rst_ni,
|
||||
|
@ -107,7 +125,7 @@ module std_cache_subsystem import ariane_pkg::*; import std_cache_pkg::*; #(
|
|||
|
||||
// AR Channel
|
||||
stream_arbiter #(
|
||||
.DATA_T ( ariane_axi::ar_chan_t ),
|
||||
.DATA_T ( axi_ar_chan_t ),
|
||||
.N_INP ( 3 )
|
||||
) i_stream_arbiter_ar (
|
||||
.clk_i,
|
||||
|
@ -122,7 +140,7 @@ module std_cache_subsystem import ariane_pkg::*; import std_cache_pkg::*; #(
|
|||
|
||||
// AW Channel
|
||||
stream_arbiter #(
|
||||
.DATA_T ( ariane_axi::aw_chan_t ),
|
||||
.DATA_T ( axi_aw_chan_t ),
|
||||
.N_INP ( 3 )
|
||||
) i_stream_arbiter_aw (
|
||||
.clk_i,
|
||||
|
@ -174,7 +192,7 @@ module std_cache_subsystem import ariane_pkg::*; import std_cache_pkg::*; #(
|
|||
assign w_select_arbiter = (w_fifo_empty) ? 0 : w_select_fifo;
|
||||
|
||||
stream_mux #(
|
||||
.DATA_T ( ariane_axi::w_chan_t ),
|
||||
.DATA_T ( axi_w_chan_t ),
|
||||
.N_INP ( 3 )
|
||||
) i_stream_mux_w (
|
||||
.inp_data_i ( {axi_req_data.w, axi_req_bypass.w, axi_req_icache.w} ),
|
||||
|
|
|
@ -14,7 +14,12 @@
|
|||
|
||||
|
||||
module std_nbdcache import std_cache_pkg::*; import ariane_pkg::*; #(
|
||||
parameter ariane_cfg_t ArianeCfg = ArianeDefaultConfig // contains cacheable regions
|
||||
parameter ariane_cfg_t ArianeCfg = ArianeDefaultConfig, // contains cacheable regions
|
||||
parameter int unsigned AXI_ADDR_WIDTH = 0,
|
||||
parameter int unsigned AXI_DATA_WIDTH = 0,
|
||||
parameter int unsigned AXI_ID_WIDTH = 0,
|
||||
parameter type axi_req_t = ariane_axi::req_t,
|
||||
parameter type axi_rsp_t = ariane_axi::resp_t
|
||||
)(
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
|
@ -30,10 +35,10 @@ module std_nbdcache import std_cache_pkg::*; import ariane_pkg::*; #(
|
|||
input dcache_req_i_t [2:0] req_ports_i, // request ports
|
||||
output dcache_req_o_t [2:0] req_ports_o, // request ports
|
||||
// Cache AXI refill port
|
||||
output ariane_axi::req_t axi_data_o,
|
||||
input ariane_axi::resp_t axi_data_i,
|
||||
output ariane_axi::req_t axi_bypass_o,
|
||||
input ariane_axi::resp_t axi_bypass_i
|
||||
output axi_req_t axi_data_o,
|
||||
input axi_rsp_t axi_data_i,
|
||||
output axi_req_t axi_bypass_o,
|
||||
input axi_rsp_t axi_bypass_i
|
||||
);
|
||||
|
||||
import std_cache_pkg::*;
|
||||
|
@ -127,7 +132,12 @@ import std_cache_pkg::*;
|
|||
// Miss Handling Unit
|
||||
// ------------------
|
||||
miss_handler #(
|
||||
.NR_PORTS ( 3 )
|
||||
.NR_PORTS ( 3 ),
|
||||
.AXI_ADDR_WIDTH ( AXI_ADDR_WIDTH ),
|
||||
.AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
|
||||
.AXI_ID_WIDTH ( AXI_ID_WIDTH ),
|
||||
.axi_req_t ( axi_req_t ),
|
||||
.axi_rsp_t ( axi_rsp_t )
|
||||
) i_miss_handler (
|
||||
.flush_i ( flush_i ),
|
||||
.busy_i ( |busy ),
|
||||
|
@ -261,8 +271,7 @@ import std_cache_pkg::*;
|
|||
|
||||
//pragma translate_off
|
||||
initial begin
|
||||
assert ($bits(axi_data_o.aw.addr) == 64) else $fatal(1, "Ariane needs a 64-bit bus");
|
||||
assert (DCACHE_LINE_WIDTH/64 inside {2, 4, 8, 16}) else $fatal(1, "Cache line size needs to be a power of two multiple of 64");
|
||||
assert (DCACHE_LINE_WIDTH/AXI_DATA_WIDTH inside {2, 4, 8, 16}) else $fatal(1, "Cache line size needs to be a power of two multiple of AXI_DATA_WIDTH");
|
||||
end
|
||||
//pragma translate_on
|
||||
endmodule
|
||||
|
|
|
@ -16,7 +16,12 @@
|
|||
|
||||
module wt_axi_adapter import ariane_pkg::*; import wt_cache_pkg::*; #(
|
||||
parameter int unsigned ReqFifoDepth = 2,
|
||||
parameter int unsigned MetaFifoDepth = wt_cache_pkg::DCACHE_MAX_TX
|
||||
parameter int unsigned MetaFifoDepth = wt_cache_pkg::DCACHE_MAX_TX,
|
||||
parameter int unsigned AxiAddrWidth = 0,
|
||||
parameter int unsigned AxiDataWidth = 0,
|
||||
parameter int unsigned AxiIdWidth = 0,
|
||||
parameter type axi_req_t = ariane_axi::req_t,
|
||||
parameter type axi_rsp_t = ariane_axi::resp_t
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
|
@ -38,13 +43,13 @@ module wt_axi_adapter import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
output dcache_rtrn_t dcache_rtrn_o,
|
||||
|
||||
// AXI port
|
||||
output ariane_axi::req_t axi_req_o,
|
||||
input ariane_axi::resp_t axi_resp_i
|
||||
output axi_req_t axi_req_o,
|
||||
input axi_rsp_t axi_resp_i
|
||||
);
|
||||
|
||||
// support up to 512bit cache lines
|
||||
localparam AxiNumWords = (ariane_pkg::ICACHE_LINE_WIDTH/64) * (ariane_pkg::ICACHE_LINE_WIDTH > ariane_pkg::DCACHE_LINE_WIDTH) +
|
||||
(ariane_pkg::DCACHE_LINE_WIDTH/64) * (ariane_pkg::ICACHE_LINE_WIDTH <= ariane_pkg::DCACHE_LINE_WIDTH) ;
|
||||
localparam AxiNumWords = (ariane_pkg::ICACHE_LINE_WIDTH/AxiDataWidth) * (ariane_pkg::ICACHE_LINE_WIDTH > ariane_pkg::DCACHE_LINE_WIDTH) +
|
||||
(ariane_pkg::DCACHE_LINE_WIDTH/AxiDataWidth) * (ariane_pkg::ICACHE_LINE_WIDTH <= ariane_pkg::DCACHE_LINE_WIDTH) ;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
|
@ -63,18 +68,18 @@ module wt_axi_adapter import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
logic axi_wr_req, axi_wr_gnt;
|
||||
logic axi_wr_valid, axi_rd_valid, axi_rd_rdy, axi_wr_rdy;
|
||||
logic axi_rd_lock, axi_wr_lock, axi_rd_exokay, axi_wr_exokay, wr_exokay;
|
||||
logic [63:0] axi_rd_addr, axi_wr_addr;
|
||||
logic [AxiAddrWidth-1:0] axi_rd_addr, axi_wr_addr;
|
||||
logic [$clog2(AxiNumWords)-1:0] axi_rd_blen, axi_wr_blen;
|
||||
logic [1:0] axi_rd_size, axi_wr_size;
|
||||
logic [$size(axi_resp_i.r.id)-1:0] axi_rd_id_in, axi_wr_id_in, axi_rd_id_out, axi_wr_id_out, wr_id_out;
|
||||
logic [AxiNumWords-1:0][63:0] axi_wr_data;
|
||||
logic [2:0] axi_rd_size, axi_wr_size;
|
||||
logic [AxiIdWidth-1:0] axi_rd_id_in, axi_wr_id_in, axi_rd_id_out, axi_wr_id_out, wr_id_out;
|
||||
logic [AxiNumWords-1:0][AxiDataWidth-1:0] axi_wr_data;
|
||||
logic [AxiNumWords-1:0][AXI_USER_WIDTH-1:0] axi_wr_user;
|
||||
logic [63:0] axi_rd_data;
|
||||
logic [AxiDataWidth-1:0] axi_rd_data;
|
||||
logic [AXI_USER_WIDTH-1:0] axi_rd_user;
|
||||
logic [AxiNumWords-1:0][7:0] axi_wr_be;
|
||||
logic [AxiNumWords-1:0][(AxiDataWidth/8)-1:0] axi_wr_be;
|
||||
logic [5:0] axi_wr_atop;
|
||||
logic invalidate;
|
||||
logic [2:0] amo_off_d, amo_off_q;
|
||||
logic [$clog2(AxiDataWidth/8)-1:0] amo_off_d, amo_off_q;
|
||||
// AMO generates r beat
|
||||
logic amo_gen_r_d, amo_gen_r_q;
|
||||
|
||||
|
@ -121,10 +126,11 @@ module wt_axi_adapter import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
always_comb begin : p_axi_req
|
||||
// write channel
|
||||
axi_wr_id_in = arb_idx;
|
||||
axi_wr_data = dcache_data.data;
|
||||
axi_wr_data = {(AxiDataWidth/riscv::XLEN){dcache_data.data}};
|
||||
axi_wr_user = dcache_data.user;
|
||||
axi_wr_addr = {{64-riscv::PLEN{1'b0}}, dcache_data.paddr};
|
||||
axi_wr_size = dcache_data.size[1:0];
|
||||
// Cast to AXI address width
|
||||
axi_wr_addr = dcache_data.paddr;
|
||||
axi_wr_size = dcache_data.size;
|
||||
axi_wr_req = 1'b0;
|
||||
axi_wr_blen = '0;// single word writes
|
||||
axi_wr_be = '0;
|
||||
|
@ -140,25 +146,26 @@ module wt_axi_adapter import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
axi_rd_blen = '0;
|
||||
|
||||
if (dcache_data.paddr[2] == 1'b0) begin
|
||||
axi_wr_data = {{64-riscv::XLEN{1'b0}}, dcache_data.data};
|
||||
axi_wr_user = {{64-AXI_USER_WIDTH{1'b0}}, dcache_data.user};
|
||||
end else begin
|
||||
axi_wr_data = {dcache_data.data, {64-riscv::XLEN{1'b0}}};
|
||||
axi_wr_user = {dcache_data.user, {64-AXI_USER_WIDTH{1'b0}}};
|
||||
end
|
||||
|
||||
// arbiter mux
|
||||
if (arb_idx) begin
|
||||
axi_rd_addr = {{64-riscv::PLEN{1'b0}}, dcache_data.paddr};
|
||||
axi_rd_size = dcache_data.size[1:0];
|
||||
// Cast to AXI address width
|
||||
axi_rd_addr = dcache_data.paddr;
|
||||
// If dcache_data.size MSB is set, we want to read as much as possible
|
||||
axi_rd_size = dcache_data.size[2] ? $clog2(AxiDataWidth/8) : dcache_data.size;
|
||||
if (dcache_data.size[2]) begin
|
||||
axi_rd_blen = ariane_pkg::DCACHE_LINE_WIDTH/64-1;
|
||||
axi_rd_blen = ariane_pkg::DCACHE_LINE_WIDTH/AxiDataWidth-1;
|
||||
end
|
||||
end else begin
|
||||
axi_rd_addr = {{64-riscv::PLEN{1'b0}}, icache_data.paddr};
|
||||
axi_rd_size = 2'b11;// always request 64bit words in case of ifill
|
||||
// Cast to AXI address width
|
||||
axi_rd_addr = icache_data.paddr;
|
||||
axi_rd_size = $clog2(AxiDataWidth/8); // always request max number of words in case of ifill
|
||||
if (!icache_data.nc) begin
|
||||
axi_rd_blen = ariane_pkg::ICACHE_LINE_WIDTH/64-1;
|
||||
axi_rd_blen = ariane_pkg::ICACHE_LINE_WIDTH/AxiDataWidth-1;
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -182,7 +189,13 @@ module wt_axi_adapter import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
//////////////////////////////////////
|
||||
wt_cache_pkg::DCACHE_STORE_REQ: begin
|
||||
axi_wr_req = 1'b1;
|
||||
axi_wr_be = wt_cache_pkg::to_byte_enable8(dcache_data.paddr[2:0], dcache_data.size[1:0]);
|
||||
axi_wr_be = '0;
|
||||
unique case(dcache_data.size[1:0])
|
||||
2'b00: axi_wr_be[0][dcache_data.paddr[$clog2(AxiDataWidth/8)-1:0]] = '1; // byte
|
||||
2'b01: axi_wr_be[0][dcache_data.paddr[$clog2(AxiDataWidth/8)-1:0] +:2 ] = '1; // hword
|
||||
2'b10: axi_wr_be[0][dcache_data.paddr[$clog2(AxiDataWidth/8)-1:0] +:4 ] = '1; // word
|
||||
default: axi_wr_be[0][dcache_data.paddr[$clog2(AxiDataWidth/8)-1:0] +:8 ] = '1; // dword = '1; // dword
|
||||
endcase
|
||||
end
|
||||
//////////////////////////////////////
|
||||
wt_cache_pkg::DCACHE_ATOMIC_REQ: begin
|
||||
|
@ -193,7 +206,13 @@ module wt_axi_adapter import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
// an atomic, this is safe.
|
||||
invalidate = arb_gnt;
|
||||
axi_wr_req = 1'b1;
|
||||
axi_wr_be = wt_cache_pkg::to_byte_enable8(dcache_data.paddr[2:0], dcache_data.size[1:0]);
|
||||
axi_wr_be = '0;
|
||||
unique case(dcache_data.size[1:0])
|
||||
2'b00: axi_wr_be[0][dcache_data.paddr[$clog2(AxiDataWidth/8)-1:0]] = '1; // byte
|
||||
2'b01: axi_wr_be[0][dcache_data.paddr[$clog2(AxiDataWidth/8)-1:0] +:2 ] = '1; // hword
|
||||
2'b10: axi_wr_be[0][dcache_data.paddr[$clog2(AxiDataWidth/8)-1:0] +:4 ] = '1; // word
|
||||
default: axi_wr_be[0][dcache_data.paddr[$clog2(AxiDataWidth/8)-1:0] +:8 ] = '1; // dword
|
||||
endcase
|
||||
amo_gen_r_d = 1'b1;
|
||||
// need to use a separate ID here, so concat an additional bit
|
||||
axi_wr_id_in[1] = 1'b1;
|
||||
|
@ -210,26 +229,17 @@ module wt_axi_adapter import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
AMO_SC: begin
|
||||
axi_wr_lock = 1'b1;
|
||||
amo_gen_r_d = 1'b0;
|
||||
// needed to properly encode success
|
||||
unique case (dcache_data.size[1:0])
|
||||
2'b00: amo_off_d = dcache_data.paddr[2:0];
|
||||
2'b01: amo_off_d = {dcache_data.paddr[2:1], 1'b0};
|
||||
2'b10: amo_off_d = {dcache_data.paddr[2], 2'b00};
|
||||
2'b11: amo_off_d = '0;
|
||||
endcase
|
||||
// needed to properly encode success. store the result at offset within the returned
|
||||
// AXI data word aligned with the requested word size.
|
||||
amo_off_d = dcache_data.paddr[$clog2(AxiDataWidth/8)-1:0] & ~((1 << dcache_data.size[1:0]) - 1);
|
||||
end
|
||||
// RISC-V atops have a load semantic
|
||||
AMO_SWAP: axi_wr_atop = {axi_pkg::ATOP_ATOMICLOAD, axi_pkg::ATOP_LITTLE_END, axi_pkg::ATOP_ATOMICSWAP};
|
||||
AMO_ADD: axi_wr_atop = {axi_pkg::ATOP_ATOMICLOAD, axi_pkg::ATOP_LITTLE_END, axi_pkg::ATOP_ADD};
|
||||
AMO_AND: begin
|
||||
// in this case we need to invert the data to get a "CLR"
|
||||
if (dcache_data.paddr[2] == 1'b0) begin
|
||||
axi_wr_data = {{64-riscv::XLEN{1'b1}}, ~dcache_data.data};
|
||||
axi_wr_user = {{64-riscv::XLEN{1'b1}}, ~dcache_data.user};
|
||||
end else begin
|
||||
axi_wr_data = {~dcache_data.data, {64-riscv::XLEN{1'b1}}};
|
||||
axi_wr_user = {~dcache_data.user, {64-riscv::XLEN{1'b1}}};
|
||||
end
|
||||
axi_wr_data = ~{(AxiDataWidth/riscv::XLEN){dcache_data.data}};
|
||||
axi_wr_user = ~{(AxiDataWidth/riscv::XLEN){dcache_data.user}};
|
||||
axi_wr_atop = {axi_pkg::ATOP_ATOMICLOAD, axi_pkg::ATOP_LITTLE_END, axi_pkg::ATOP_CLR};
|
||||
end
|
||||
AMO_OR: axi_wr_atop = {axi_pkg::ATOP_ATOMICLOAD, axi_pkg::ATOP_LITTLE_END, axi_pkg::ATOP_SET};
|
||||
|
@ -351,7 +361,7 @@ module wt_axi_adapter import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
assign b_push = axi_wr_valid & axi_wr_rdy;
|
||||
|
||||
fifo_v3 #(
|
||||
.DATA_WIDTH ( $size(axi_resp_i.r.id) + 1 ),
|
||||
.DATA_WIDTH ( AxiIdWidth + 1 ),
|
||||
.DEPTH ( MetaFifoDepth ),
|
||||
.FALL_THROUGH ( 1'b1 )
|
||||
) i_b_fifo (
|
||||
|
@ -370,10 +380,10 @@ module wt_axi_adapter import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
|
||||
// buffer read responses in shift regs
|
||||
logic icache_first_d, icache_first_q, dcache_first_d, dcache_first_q;
|
||||
logic [ICACHE_LINE_WIDTH/64-1:0][63:0] icache_rd_shift_d, icache_rd_shift_q;
|
||||
logic [ICACHE_USER_LINE_WIDTH/AXI_USER_WIDTH-1:0][AXI_USER_WIDTH-1:0] icache_rd_shift_user_d, icache_rd_shift_user_q;
|
||||
logic [DCACHE_LINE_WIDTH/64-1:0][63:0] dcache_rd_shift_d, dcache_rd_shift_q;
|
||||
logic [DCACHE_USER_LINE_WIDTH/AXI_USER_WIDTH-1:0][AXI_USER_WIDTH-1:0] dcache_rd_shift_user_d, dcache_rd_shift_user_q;
|
||||
logic [ICACHE_LINE_WIDTH/AxiDataWidth-1:0][AxiDataWidth-1:0] icache_rd_shift_d, icache_rd_shift_q;
|
||||
logic [DCACHE_LINE_WIDTH/AxiDataWidth-1:0][AxiDataWidth-1:0] dcache_rd_shift_d, dcache_rd_shift_q;
|
||||
wt_cache_pkg::dcache_in_t dcache_rtrn_type_d, dcache_rtrn_type_q;
|
||||
wt_cache_pkg::dcache_inval_t dcache_rtrn_inv_d, dcache_rtrn_inv_q;
|
||||
logic dcache_sc_rtrn, axi_rd_last;
|
||||
|
@ -405,7 +415,11 @@ module wt_axi_adapter import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
|
||||
if (icache_rtrn_rd_en) begin
|
||||
icache_first_d = axi_rd_last;
|
||||
icache_rd_shift_d = {axi_rd_data, icache_rd_shift_q[ICACHE_LINE_WIDTH/64-1:1]};
|
||||
if (ICACHE_LINE_WIDTH == AxiDataWidth) begin
|
||||
icache_rd_shift_d = axi_rd_data;
|
||||
end else begin
|
||||
icache_rd_shift_d = {axi_rd_data, icache_rd_shift_q[ICACHE_LINE_WIDTH/AxiDataWidth-1:1]};
|
||||
end
|
||||
icache_rd_shift_user_d = {axi_rd_user, icache_rd_shift_user_q[ICACHE_USER_LINE_WIDTH/AXI_USER_WIDTH-1:1]};
|
||||
// if this is a single word transaction, we need to make sure that word is placed at offset 0
|
||||
if (icache_first_q) begin
|
||||
|
@ -416,7 +430,11 @@ module wt_axi_adapter import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
|
||||
if (dcache_rtrn_rd_en) begin
|
||||
dcache_first_d = axi_rd_last;
|
||||
dcache_rd_shift_d = {axi_rd_data, dcache_rd_shift_q[DCACHE_LINE_WIDTH/64-1:1]};
|
||||
if (DCACHE_LINE_WIDTH == AxiDataWidth) begin
|
||||
dcache_rd_shift_d = axi_rd_data;
|
||||
end else begin
|
||||
dcache_rd_shift_d = {axi_rd_data, dcache_rd_shift_q[DCACHE_LINE_WIDTH/AxiDataWidth-1:1]};
|
||||
end
|
||||
dcache_rd_shift_user_d = {axi_rd_user, dcache_rd_shift_user_q[DCACHE_USER_LINE_WIDTH/AXI_USER_WIDTH-1:1]};
|
||||
// if this is a single word transaction, we need to make sure that word is placed at offset 0
|
||||
if (dcache_first_q) begin
|
||||
|
@ -571,9 +589,13 @@ module wt_axi_adapter import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
///////////////////////////////////////////////////////
|
||||
|
||||
axi_shim #(
|
||||
.AxiUserWidth ( AXI_USER_WIDTH ),
|
||||
.AxiNumWords ( AxiNumWords ),
|
||||
.AxiIdWidth ( $size(axi_resp_i.r.id) )
|
||||
.AxiNumWords ( AxiNumWords ),
|
||||
.AxiAddrWidth ( AxiAddrWidth ),
|
||||
.AxiDataWidth ( AxiDataWidth ),
|
||||
.AxiIdWidth ( AxiIdWidth ),
|
||||
.AxiUserWidth ( AXI_USER_WIDTH ),
|
||||
.axi_req_t ( axi_req_t ),
|
||||
.axi_rsp_t ( axi_rsp_t )
|
||||
) i_axi_shim (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
|
|
|
@ -20,7 +20,12 @@
|
|||
|
||||
|
||||
module wt_cache_subsystem import ariane_pkg::*; import wt_cache_pkg::*; #(
|
||||
parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig // contains cacheable regions
|
||||
parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig, // contains cacheable regions
|
||||
parameter int unsigned AxiAddrWidth = 0,
|
||||
parameter int unsigned AxiDataWidth = 0,
|
||||
parameter int unsigned AxiIdWidth = 0,
|
||||
parameter type axi_req_t = ariane_axi::req_t,
|
||||
parameter type axi_rsp_t = ariane_axi::resp_t
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
|
@ -55,8 +60,8 @@ module wt_cache_subsystem import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
input l15_rtrn_t l15_rtrn_i
|
||||
`else
|
||||
// memory side
|
||||
output ariane_axi::req_t axi_req_o,
|
||||
input ariane_axi::resp_t axi_resp_i
|
||||
output axi_req_t axi_req_o,
|
||||
input axi_rsp_t axi_resp_i
|
||||
`endif
|
||||
// TODO: interrupt interface
|
||||
);
|
||||
|
@ -97,6 +102,7 @@ module wt_cache_subsystem import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
// they have equal prio and are RR arbited
|
||||
// Port 2 is write only and goes into the merging write buffer
|
||||
wt_dcache #(
|
||||
.AxiDataWidth ( AxiDataWidth ),
|
||||
// use ID 1 for dcache reads and amos. note that the writebuffer
|
||||
// uses all IDs up to DCACHE_MAX_TX-1 for write transactions.
|
||||
.RdAmoTxId ( 1 ),
|
||||
|
@ -147,7 +153,13 @@ module wt_cache_subsystem import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
.l15_rtrn_i ( l15_rtrn_i )
|
||||
);
|
||||
`else
|
||||
wt_axi_adapter i_adapter (
|
||||
wt_axi_adapter #(
|
||||
.AxiAddrWidth ( AxiAddrWidth ),
|
||||
.AxiDataWidth ( AxiDataWidth ),
|
||||
.AxiIdWidth ( AxiIdWidth ),
|
||||
.axi_req_t ( axi_req_t ),
|
||||
.axi_rsp_t ( axi_rsp_t )
|
||||
) i_adapter (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
.icache_data_req_i ( icache_adapter_data_req ),
|
||||
|
@ -176,10 +188,12 @@ module wt_cache_subsystem import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
else $warning(1,"[l1 dcache] reading invalid instructions: vaddr=%08X, data=%08X",
|
||||
icache_dreq_o.vaddr, icache_dreq_o.data);
|
||||
|
||||
a_invalid_write_data: assert property (
|
||||
@(posedge clk_i) disable iff (!rst_ni) dcache_req_ports_i[2].data_req |-> |dcache_req_ports_i[2].data_be |-> (|dcache_req_ports_i[2].data_wdata) !== 1'hX)
|
||||
else $warning(1,"[l1 dcache] writing invalid data: paddr=%016X, be=%02X, data=%016X",
|
||||
{dcache_req_ports_i[2].address_tag, dcache_req_ports_i[2].address_index}, dcache_req_ports_i[2].data_be, dcache_req_ports_i[2].data_wdata);
|
||||
for (genvar j=0; j<riscv::XLEN/8; j++) begin : gen_invalid_write_assertion
|
||||
a_invalid_write_data: assert property (
|
||||
@(posedge clk_i) disable iff (!rst_ni) dcache_req_ports_i[2].data_req |-> dcache_req_ports_i[2].data_be[j] |-> (|dcache_req_ports_i[2].data_wdata[j*8+:8] !== 1'hX))
|
||||
else $warning(1,"[l1 dcache] writing invalid data: paddr=%016X, be=%02X, data=%016X, databe=%016X",
|
||||
{dcache_req_ports_i[2].address_tag, dcache_req_ports_i[2].address_index}, dcache_req_ports_i[2].data_be, dcache_req_ports_i[2].data_wdata, dcache_req_ports_i[2].data_be & dcache_req_ports_i[2].data_wdata);
|
||||
end
|
||||
|
||||
|
||||
for (genvar j=0; j<2; j++) begin : gen_assertion
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
|
||||
module wt_dcache import ariane_pkg::*; import wt_cache_pkg::*; #(
|
||||
parameter int unsigned AxiDataWidth = 0,
|
||||
// ID to be used for read and AMO transactions.
|
||||
// note that the write buffer uses all IDs up to DCACHE_MAX_TX-1 for write transactions
|
||||
parameter logic [CACHE_ID_WIDTH-1:0] RdAmoTxId = 1,
|
||||
|
@ -112,9 +113,10 @@ module wt_dcache import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
///////////////////////////////////////////////////////
|
||||
|
||||
wt_dcache_missunit #(
|
||||
.Axi64BitCompliant ( ArianeCfg.Axi64BitCompliant ),
|
||||
.AmoTxId ( RdAmoTxId ),
|
||||
.NumPorts ( NumPorts )
|
||||
.AxiCompliant ( ArianeCfg.AxiCompliant ),
|
||||
.AmoTxId ( RdAmoTxId ),
|
||||
.NumPorts ( NumPorts ),
|
||||
.AxiDataWidth ( AxiDataWidth )
|
||||
) i_wt_dcache_missunit (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
|
@ -275,8 +277,9 @@ module wt_dcache import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
///////////////////////////////////////////////////////
|
||||
|
||||
wt_dcache_mem #(
|
||||
.Axi64BitCompliant ( ArianeCfg.Axi64BitCompliant ),
|
||||
.NumPorts ( NumPorts )
|
||||
.AxiCompliant ( ArianeCfg.AxiCompliant ),
|
||||
.AxiDataWidth ( AxiDataWidth ),
|
||||
.NumPorts ( NumPorts )
|
||||
) i_wt_dcache_mem (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
|
|
|
@ -27,8 +27,9 @@
|
|||
|
||||
|
||||
module wt_dcache_mem import ariane_pkg::*; import wt_cache_pkg::*; #(
|
||||
parameter bit Axi64BitCompliant = 1'b0, // set this to 1 when using in conjunction with 64bit AXI bus adapter
|
||||
parameter int unsigned NumPorts = 3
|
||||
parameter bit AxiCompliant = 1'b0, // set this to 1 when using in conjunction with AXI bus adapter
|
||||
parameter int unsigned AxiDataWidth = 0,
|
||||
parameter int unsigned NumPorts = 3
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
|
@ -71,6 +72,10 @@ module wt_dcache_mem import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
input wbuffer_t [DCACHE_WBUF_DEPTH-1:0] wbuffer_data_i
|
||||
);
|
||||
|
||||
// number of bits needed to address AXI data. If AxiDataWidth equals XLEN this parameter
|
||||
// is not needed. Therefore, increment it by one to avoid reverse range select during elaboration.
|
||||
localparam AXI_OFFSET_WIDTH = AxiDataWidth == riscv::XLEN ? $clog2(AxiDataWidth/8)+1 : $clog2(AxiDataWidth/8);
|
||||
|
||||
logic [DCACHE_NUM_BANKS-1:0] bank_req;
|
||||
logic [DCACHE_NUM_BANKS-1:0] bank_we;
|
||||
logic [DCACHE_NUM_BANKS-1:0][DCACHE_SET_ASSOC-1:0][(riscv::XLEN/8)-1:0] bank_be;
|
||||
|
@ -241,9 +246,11 @@ module wt_dcache_mem import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
assign wbuffer_ruser = wbuffer_data_i[wbuffer_hit_idx].user;
|
||||
assign wbuffer_be = (|wbuffer_hit_oh) ? wbuffer_data_i[wbuffer_hit_idx].valid : '0;
|
||||
|
||||
if (Axi64BitCompliant) begin : gen_axi_off
|
||||
assign wr_cl_nc_off = riscv::IS_XLEN64 ? '0 : wr_cl_off_i[2];
|
||||
assign wr_cl_off = (wr_cl_nc_i) ? wr_cl_nc_off : wr_cl_off_i[DCACHE_OFFSET_WIDTH-1:riscv::XLEN_ALIGN_BYTES];
|
||||
if (AxiCompliant) begin : gen_axi_off
|
||||
// In case of an uncached read, return the desired XLEN-bit segment of the most recent AXI read
|
||||
assign wr_cl_off = (wr_cl_nc_i) ? (AxiDataWidth == riscv::XLEN) ? '0 :
|
||||
wr_cl_off_i[AXI_OFFSET_WIDTH-1:riscv::XLEN_ALIGN_BYTES] :
|
||||
wr_cl_off_i[DCACHE_OFFSET_WIDTH-1:riscv::XLEN_ALIGN_BYTES];
|
||||
end else begin : gen_piton_off
|
||||
assign wr_cl_off = wr_cl_off_i[DCACHE_OFFSET_WIDTH-1:3];
|
||||
end
|
||||
|
@ -337,6 +344,20 @@ module wt_dcache_mem import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
|
||||
//pragma translate_off
|
||||
`ifndef VERILATOR
|
||||
initial begin
|
||||
cach_line_width_axi: assert (DCACHE_LINE_WIDTH >= AxiDataWidth)
|
||||
else $fatal(1, "[l1 dcache] cache line size needs to be greater or equal AXI data width");
|
||||
end
|
||||
|
||||
initial begin
|
||||
axi_xlen: assert (AxiDataWidth >= riscv::XLEN)
|
||||
else $fatal(1, "[l1 dcache] AXI data width needs to be greater or equal XLEN");
|
||||
end
|
||||
|
||||
initial begin
|
||||
cach_line_width_xlen: assert (DCACHE_LINE_WIDTH > riscv::XLEN)
|
||||
else $fatal(1, "[l1 dcache] cache_line_size needs to be greater than XLEN");
|
||||
end
|
||||
|
||||
hit_hot1: assert property (
|
||||
@(posedge clk_i) disable iff (!rst_ni) &vld_req |-> !vld_we |=> $onehot0(rd_hit_oh_o))
|
||||
|
|
|
@ -15,9 +15,10 @@
|
|||
|
||||
|
||||
module wt_dcache_missunit import ariane_pkg::*; import wt_cache_pkg::*; #(
|
||||
parameter bit Axi64BitCompliant = 1'b0, // set this to 1 when using in conjunction with 64bit AXI bus adapter
|
||||
parameter logic [CACHE_ID_WIDTH-1:0] AmoTxId = 1, // TX id to be used for AMOs
|
||||
parameter int unsigned NumPorts = 3 // number of miss ports
|
||||
parameter bit AxiCompliant = 1'b0, // set this to 1 when using in conjunction with AXI bus adapter
|
||||
parameter logic [CACHE_ID_WIDTH-1:0] AmoTxId = 1, // TX id to be used for AMOs
|
||||
parameter int unsigned NumPorts = 3, // number of miss ports
|
||||
parameter int AxiDataWidth = 0
|
||||
) (
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
|
@ -220,8 +221,12 @@ module wt_dcache_missunit import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
end
|
||||
|
||||
// note: openpiton returns a full cacheline!
|
||||
if (Axi64BitCompliant) begin : gen_axi_rtrn_mux
|
||||
assign amo_rtrn_mux = mem_rtrn_i.data[0 +: 64];
|
||||
if (AxiCompliant) begin : gen_axi_rtrn_mux
|
||||
if (AxiDataWidth > 64) begin
|
||||
assign amo_rtrn_mux = mem_rtrn_i.data[amo_req_i.operand_a[$clog2(AxiDataWidth/8)-1:3]*64 +: 64];
|
||||
end else begin
|
||||
assign amo_rtrn_mux = mem_rtrn_i.data[0 +: 64];
|
||||
end
|
||||
end else begin : gen_piton_rtrn_mux
|
||||
assign amo_rtrn_mux = mem_rtrn_i.data[amo_req_i.operand_a[DCACHE_OFFSET_WIDTH-1:3]*64 +: 64];
|
||||
end
|
||||
|
|
|
@ -1201,7 +1201,7 @@ module csr_regfile import ariane_pkg::*; #(
|
|||
`ifndef VERILATOR
|
||||
// check that eret and ex are never valid together
|
||||
assert property (
|
||||
@(posedge clk_i) !(eret_o && ex_i.valid))
|
||||
@(posedge clk_i) disable iff (!rst_ni !== '0) !(eret_o && ex_i.valid))
|
||||
else begin $error("eret and exception should never be valid at the same time"); $stop(); end
|
||||
`endif
|
||||
//pragma translate_on
|
||||
|
|
31
core/cva6.sv
31
core/cva6.sv
|
@ -24,7 +24,15 @@ import "DPI-C" function void init_dromajo(string cfg_f_name);
|
|||
|
||||
|
||||
module cva6 import ariane_pkg::*; #(
|
||||
parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig
|
||||
parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig,
|
||||
parameter int unsigned AxiAddrWidth = ariane_axi::AddrWidth,
|
||||
parameter int unsigned AxiDataWidth = ariane_axi::DataWidth,
|
||||
parameter int unsigned AxiIdWidth = ariane_axi::IdWidth,
|
||||
parameter type axi_ar_chan_t = ariane_axi::ar_chan_t,
|
||||
parameter type axi_aw_chan_t = ariane_axi::aw_chan_t,
|
||||
parameter type axi_w_chan_t = ariane_axi::w_chan_t,
|
||||
parameter type axi_req_t = ariane_axi::req_t,
|
||||
parameter type axi_rsp_t = ariane_axi::resp_t
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
|
@ -55,8 +63,8 @@ module cva6 import ariane_pkg::*; #(
|
|||
input wt_cache_pkg::l15_rtrn_t l15_rtrn_i
|
||||
`else
|
||||
// memory side, AXI Master
|
||||
output ariane_axi::req_t axi_req_o,
|
||||
input ariane_axi::resp_t axi_resp_i
|
||||
output axi_req_t axi_req_o,
|
||||
input axi_rsp_t axi_resp_i
|
||||
`endif
|
||||
);
|
||||
|
||||
|
@ -674,7 +682,12 @@ module cva6 import ariane_pkg::*; #(
|
|||
`ifdef WT_DCACHE
|
||||
// this is a cache subsystem that is compatible with OpenPiton
|
||||
wt_cache_subsystem #(
|
||||
.ArianeCfg ( ArianeCfg )
|
||||
.ArianeCfg ( ArianeCfg ),
|
||||
.AxiAddrWidth ( AxiAddrWidth ),
|
||||
.AxiDataWidth ( AxiDataWidth ),
|
||||
.AxiIdWidth ( AxiIdWidth ),
|
||||
.axi_req_t ( axi_req_t ),
|
||||
.axi_rsp_t ( axi_rsp_t )
|
||||
) i_cache_subsystem (
|
||||
// to D$
|
||||
.clk_i ( clk_i ),
|
||||
|
@ -716,7 +729,15 @@ module cva6 import ariane_pkg::*; #(
|
|||
// note: this only works with one cacheable region
|
||||
// not as important since this cache subsystem is about to be
|
||||
// deprecated
|
||||
.ArianeCfg ( ArianeCfg )
|
||||
.ArianeCfg ( ArianeCfg ),
|
||||
.AxiAddrWidth ( AxiAddrWidth ),
|
||||
.AxiDataWidth ( AxiDataWidth ),
|
||||
.AxiIdWidth ( AxiIdWidth ),
|
||||
.axi_ar_chan_t ( axi_ar_chan_t ),
|
||||
.axi_aw_chan_t ( axi_aw_chan_t ),
|
||||
.axi_w_chan_t ( axi_w_chan_t ),
|
||||
.axi_req_t ( axi_req_t ),
|
||||
.axi_rsp_t ( axi_rsp_t )
|
||||
) i_cache_subsystem (
|
||||
// to D$
|
||||
.clk_i ( clk_i ),
|
||||
|
|
|
@ -48,7 +48,7 @@ package ariane_pkg;
|
|||
logic [NrMaxRules-1:0][63:0] CachedRegionAddrBase; // base which needs to match
|
||||
logic [NrMaxRules-1:0][63:0] CachedRegionLength; // bit mask which bits to consider when matching the rule
|
||||
// cache config
|
||||
bit Axi64BitCompliant; // set to 1 when using in conjunction with 64bit AXI bus adapter
|
||||
bit AxiCompliant; // set to 1 when using in conjunction with 64bit AXI bus adapter
|
||||
bit SwapEndianess; // set to 1 to swap endianess inside L1.5 openpiton adapter
|
||||
//
|
||||
logic [63:0] DmBaseAddress; // offset of the debug module
|
||||
|
@ -72,7 +72,7 @@ package ariane_pkg;
|
|||
CachedRegionAddrBase: {64'h8000_0000},
|
||||
CachedRegionLength: {64'h40000000},
|
||||
// cache config
|
||||
Axi64BitCompliant: 1'b1,
|
||||
AxiCompliant: 1'b1,
|
||||
SwapEndianess: 1'b0,
|
||||
// debug
|
||||
DmBaseAddress: 64'h0,
|
||||
|
@ -96,6 +96,7 @@ package ariane_pkg;
|
|||
|
||||
function automatic logic range_check(logic[63:0] base, logic[63:0] len, logic[63:0] address);
|
||||
// if len is a power of two, and base is properly aligned, this check could be simplified
|
||||
// Extend base by one bit to prevent an overflow.
|
||||
return (address >= base) && (address < (65'(base)+len));
|
||||
endfunction : range_check
|
||||
|
||||
|
|
|
@ -559,7 +559,12 @@ logic [1:0] axi_adapter_size;
|
|||
assign axi_adapter_size = (riscv::XLEN == 64) ? 2'b11 : 2'b10;
|
||||
|
||||
axi_adapter #(
|
||||
.DATA_WIDTH ( riscv::XLEN )
|
||||
.DATA_WIDTH ( riscv::XLEN ),
|
||||
.AXI_ADDR_WIDTH ( ariane_axi::AddrWidth ),
|
||||
.AXI_DATA_WIDTH ( ariane_axi::DataWidth ),
|
||||
.AXI_ID_WIDTH ( ariane_axi::IdWidth ),
|
||||
.axi_req_t ( ariane_axi::req_t ),
|
||||
.axi_rsp_t ( ariane_axi::resp_t )
|
||||
) i_dm_axi_master (
|
||||
.clk_i ( clk ),
|
||||
.rst_ni ( rst_n ),
|
||||
|
|
|
@ -186,7 +186,7 @@ module ariane_verilog_wrap
|
|||
CachedRegionAddrBase: CachedRegionAddrBase,
|
||||
CachedRegionLength: CachedRegionLength,
|
||||
// cache config
|
||||
Axi64BitCompliant: 1'b0,
|
||||
AxiCompliant: 1'b0,
|
||||
SwapEndianess: SwapEndianess,
|
||||
// debug
|
||||
DmBaseAddress: DmBaseAddress,
|
||||
|
|
|
@ -85,7 +85,7 @@ package ariane_soc;
|
|||
CachedRegionAddrBase: {DRAMBase},
|
||||
CachedRegionLength: {DRAMLength},
|
||||
// cache config
|
||||
Axi64BitCompliant: 1'b1,
|
||||
AxiCompliant: 1'b1,
|
||||
SwapEndianess: 1'b0,
|
||||
// debug
|
||||
DmBaseAddress: DebugBase,
|
||||
|
|
|
@ -284,7 +284,11 @@ module ariane_testharness #(
|
|||
|
||||
axi_adapter #(
|
||||
.DATA_WIDTH ( AXI_DATA_WIDTH ),
|
||||
.AXI_ID_WIDTH ( ariane_soc::IdWidth )
|
||||
.AXI_ADDR_WIDTH ( ariane_axi_soc::AddrWidth ),
|
||||
.AXI_DATA_WIDTH ( ariane_axi_soc::DataWidth ),
|
||||
.AXI_ID_WIDTH ( ariane_soc::IdWidth ),
|
||||
.axi_req_t ( ariane_axi_soc::req_t ),
|
||||
.axi_rsp_t ( ariane_axi_soc::resp_t )
|
||||
) i_dm_axi_master (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
`include "tb.svh"
|
||||
|
||||
program tb_amoport import ariane_pkg::*; import std_cache_pkg::*; import tb_pkg::*; #(
|
||||
program tb_amoport import ariane_pkg::*; import tb_pkg::*; #(
|
||||
parameter string PortName = "atomics port 0",
|
||||
parameter MemWords = 1024*1024,// in 64bit words
|
||||
parameter logic [63:0] CachedAddrBeg = 0,
|
||||
|
@ -82,7 +82,10 @@ program tb_amoport import ariane_pkg::*; import std_cache_pkg::*; import tb_pkg:
|
|||
// Apply random stimuli, choose random AMO operand
|
||||
void'(randomize(amo_op) with {!(amo_op inside {AMO_NONE, AMO_CAS1, AMO_CAS2});});
|
||||
void'(randomize(data));
|
||||
void'(randomize(size) with {size >= 2; size <= 3;});
|
||||
if (riscv::XLEN == 64)
|
||||
void'(randomize(size) with {size >= 2; size <= 3;});
|
||||
else
|
||||
size = 'h2;
|
||||
|
||||
// For LRs/SCs, choose from only 4 adresses,
|
||||
// so that valid LR/SC combinations become more likely.
|
||||
|
@ -190,7 +193,7 @@ program tb_amoport import ariane_pkg::*; import std_cache_pkg::*; import tb_pkg:
|
|||
|
||||
if(Verbose | !ok) begin
|
||||
tmpstr0 = $psprintf("vector: %02d - %06d -- paddr: %16X -- AMO: 0x%2X -- size: %X -- op_a: %16X -- op_b: %16X",
|
||||
n, k, dut_amo_req_port_o.operand_a, dut_amo_req_port_o.amo_op, 2**dut_amo_req_port_o.size, exp_result_i, dut_amo_req_port_o.operand_b);
|
||||
n, k, dut_amo_req_port_o.operand_a, dut_amo_req_port_o.amo_op, 2**dut_amo_req_port_o.size, dut_amo_req_port_o.operand_a, dut_amo_req_port_o.operand_b);
|
||||
tmpstr1 = $psprintf("vector: %02d - %06d -- exp_res: %16X -- exp_mem: %16X",
|
||||
n, k, exp_result_i, exp_mem_i);
|
||||
tmpstr2 = $psprintf("vector: %02d - %06d -- result: %16X -- memory: %16X",
|
|
@ -190,6 +190,7 @@ package tb_pkg;
|
|||
rand_ax_beat_queue_t ar_queue;
|
||||
ax_beat_t aw_queue[$];
|
||||
int unsigned b_wait_cnt;
|
||||
ax_beat_t b_aw_queue[$];
|
||||
|
||||
static byte_t memory_q[MEM_BYTES-1:0]; // Main memory
|
||||
static byte_t shadow_q[MEM_BYTES-1:0]; // Shadow of main memory for verification.
|
||||
|
@ -353,12 +354,12 @@ package tb_pkg;
|
|||
forever begin
|
||||
automatic ax_beat_t aw_beat;
|
||||
automatic addr_t byte_addr;
|
||||
wait (aw_queue.size() > 0);
|
||||
aw_beat = aw_queue.pop_front();
|
||||
forever begin
|
||||
automatic w_beat_t w_beat;
|
||||
rand_wait(RESP_MIN_WAIT_CYCLES, RESP_MAX_WAIT_CYCLES);
|
||||
drv.recv_w(w_beat);
|
||||
wait (aw_queue.size() > 0);
|
||||
aw_beat = aw_queue[0];
|
||||
byte_addr = (aw_beat.ax_addr >> $clog2(DW/8)) << $clog2(DW/8);
|
||||
|
||||
assert (min_paddr != max_paddr && byte_addr inside {[min_paddr:max_paddr]}) else
|
||||
|
@ -376,11 +377,10 @@ package tb_pkg;
|
|||
aw_beat.ax_addr = ((aw_beat.ax_addr >> aw_beat.ax_size) << aw_beat.ax_size) +
|
||||
2**aw_beat.ax_size;
|
||||
end
|
||||
aw_queue[0] = aw_beat;
|
||||
if (w_beat.w_last)
|
||||
break;
|
||||
end
|
||||
b_wait_cnt++;
|
||||
b_aw_queue.push_back(aw_beat);
|
||||
end
|
||||
endtask
|
||||
|
||||
|
@ -389,8 +389,8 @@ package tb_pkg;
|
|||
automatic ax_beat_t aw_beat;
|
||||
automatic b_beat_t b_beat = new;
|
||||
automatic logic rand_success;
|
||||
wait (b_wait_cnt > 0 && (aw_queue.size() != 0));
|
||||
aw_beat = aw_queue.pop_front();
|
||||
wait (b_aw_queue.size() > 0);
|
||||
aw_beat = b_aw_queue.pop_front();
|
||||
rand_success = std::randomize(b_beat); assert(rand_success);
|
||||
b_beat.b_id = aw_beat.ax_id;
|
||||
if (aw_beat.ax_lock) begin
|
||||
|
|
|
@ -47,7 +47,7 @@ program tb_readport import tb_pkg::*; import ariane_pkg::*; #(
|
|||
// expresp interface
|
||||
output logic [63:0] exp_paddr_o,
|
||||
input logic [1:0] exp_size_i,
|
||||
input logic [63:0] exp_rdata_i,
|
||||
input riscv::xlen_t exp_rdata_i,
|
||||
input logic [63:0] exp_paddr_i,
|
||||
input logic [63:0] act_paddr_i,
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ module tb import tb_pkg::*; import ariane_pkg::*; import wt_cache_pkg::*; #()();
|
|||
CachedRegionAddrBase: {CachedAddrBeg},
|
||||
CachedRegionLength: {CachedAddrEnd-CachedAddrBeg+64'b1},
|
||||
// cache config
|
||||
Axi64BitCompliant: 1'b0,
|
||||
AxiCompliant: 1'b0,
|
||||
SwapEndianess: 1'b0,
|
||||
// debug
|
||||
DmBaseAddress: 64'h0,
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
`include "tb.svh"
|
||||
`include "assign.svh"
|
||||
`include "axi/typedef.svh"
|
||||
|
||||
module tb import ariane_pkg::*; import std_cache_pkg::*; import tb_pkg::*; #()();
|
||||
|
||||
|
@ -47,7 +48,7 @@ module tb import ariane_pkg::*; import std_cache_pkg::*; import tb_pkg::*; #()()
|
|||
CachedRegionAddrBase: {CachedAddrBeg},//1/8th of the memory is NC
|
||||
CachedRegionLength: {CachedAddrEnd-CachedAddrBeg+64'b1},
|
||||
// cache config
|
||||
Axi64BitCompliant: 1'b1,
|
||||
AxiCompliant: 1'b1,
|
||||
SwapEndianess: 1'b0,
|
||||
// debug
|
||||
DmBaseAddress: 64'h0,
|
||||
|
@ -87,6 +88,13 @@ module tb import ariane_pkg::*; import std_cache_pkg::*; import tb_pkg::*; #()()
|
|||
// MUT signal declarations
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`AXI_TYPEDEF_ALL(axi,
|
||||
logic [ TbAxiAddrWidthFull-1:0],
|
||||
logic [ TbAxiIdWidthFull-1:0],
|
||||
logic [ TbAxiDataWidthFull-1:0],
|
||||
logic [(TbAxiDataWidthFull/8)-1:0],
|
||||
logic [ TbAxiUserWidthFull-1:0])
|
||||
|
||||
logic enable_i;
|
||||
logic flush_i;
|
||||
logic flush_ack_o;
|
||||
|
@ -95,10 +103,10 @@ module tb import ariane_pkg::*; import std_cache_pkg::*; import tb_pkg::*; #()()
|
|||
amo_resp_t amo_resp_o;
|
||||
dcache_req_i_t [2:0] req_ports_i;
|
||||
dcache_req_o_t [2:0] req_ports_o;
|
||||
ariane_axi::req_t axi_data_o;
|
||||
ariane_axi::resp_t axi_data_i;
|
||||
ariane_axi::req_t axi_bypass_o;
|
||||
ariane_axi::resp_t axi_bypass_i;
|
||||
axi_req_t axi_data_o;
|
||||
axi_resp_t axi_data_i;
|
||||
axi_req_t axi_bypass_o;
|
||||
axi_resp_t axi_bypass_i;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// TB signal declarations
|
||||
|
@ -410,7 +418,12 @@ module tb import ariane_pkg::*; import std_cache_pkg::*; import tb_pkg::*; #()()
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std_nbdcache #(
|
||||
.ArianeCfg ( ArianeDefaultConfig )
|
||||
.ArianeCfg ( ArianeDefaultConfig ),
|
||||
.AXI_ADDR_WIDTH ( TbAxiAddrWidthFull ),
|
||||
.AXI_DATA_WIDTH ( TbAxiDataWidthFull ),
|
||||
.AXI_ID_WIDTH ( TbAxiIdWidthFull ),
|
||||
.axi_req_t ( axi_req_t ),
|
||||
.axi_rsp_t ( axi_resp_t )
|
||||
) i_dut (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
|
|
|
@ -45,5 +45,5 @@
|
|||
../common/tb_dcache_pkg.sv
|
||||
../common/tb_readport.sv
|
||||
../common/tb_writeport.sv
|
||||
hdl/tb_amoport.sv
|
||||
../common/tb_amoport.sv
|
||||
hdl/tb.sv
|
||||
|
|
|
@ -57,7 +57,8 @@ add wave -noupdate -group i_missunit /tb/i_dut/i_miss_handler/*
|
|||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/master_ports[0]/i_cache_ctrl/*}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/master_ports[1]/i_cache_ctrl/*}
|
||||
add wave -noupdate -group i_ctrl2 {/tb/i_dut/master_ports[2]/i_cache_ctrl/*}
|
||||
add wave -noupdate -group i_miss_axi_adapter0 /tb/i_dut/i_miss_handler/i_miss_axi_adapter/*
|
||||
add wave -noupdate -group i_bypass_axi_adapter /tb/i_dut/i_miss_handler/i_bypass_axi_adapter/*
|
||||
add wave -noupdate -group i_miss_axi_adapter /tb/i_dut/i_miss_handler/i_miss_axi_adapter/*
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {{Cursor 1} {31432807547 ps} 0} {{Cursor 2} {17675291 ps} 0} {{Cursor 3} {1027790000 ps} 0}
|
||||
quietly wave cursor active 2
|
||||
|
|
7
corev_apu/tb/tb_wt_axi_dcache/.gitignore
vendored
Normal file
7
corev_apu/tb/tb_wt_axi_dcache/.gitignore
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
work
|
||||
*.rep
|
||||
transcript
|
||||
*.ini
|
||||
*.wlf
|
||||
*.log
|
||||
|
46
corev_apu/tb/tb_wt_axi_dcache/Makefile
Executable file
46
corev_apu/tb/tb_wt_axi_dcache/Makefile
Executable file
|
@ -0,0 +1,46 @@
|
|||
# Copyright 2018 ETH Zurich and University of Bologna.
|
||||
# Copyright and related rights are licensed under the Solderpad Hardware
|
||||
# License, Version 0.51 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License at
|
||||
# http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
# or agreed to in writing, software, hardware and materials distributed under
|
||||
# this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations under the License.
|
||||
#
|
||||
# Author: Michael Schaffner <schaffner@iis.ee.ethz.ch>, ETH Zurich
|
||||
# Date: 15.08.2018
|
||||
# Description: Makefile for the dcache testbench.
|
||||
|
||||
library ?= work
|
||||
toplevel ?= tb
|
||||
src-list := tb.list
|
||||
inc-path := $(shell pwd)/hdl/
|
||||
src := $(shell xargs printf '\n%s' < $(src-list) | cut -b 1-)
|
||||
compile_flag += +cover+i_dut -incr -64 -nologo -svinputport=compat -override_timescale 1ns/1ps -suppress 2583 -suppress 13262 +cover
|
||||
sim_opts += -64 -coverage -classdebug -voptargs="+acc"
|
||||
incdir += ../common/
|
||||
incdir += ../../axi/include/
|
||||
|
||||
# Iterate over all include directories and write them with +incdir+ prefixed
|
||||
# +incdir+ works for Verilator and QuestaSim
|
||||
list_incdir := $(foreach dir, ${incdir}, +incdir+$(dir))
|
||||
|
||||
build: clean
|
||||
vlib $(library)
|
||||
vlog -work $(library) -pedanticerrors $(src) $(compile_flag) $(list_incdir)
|
||||
touch $(library)/.build
|
||||
|
||||
# this starts modelsim with gui
|
||||
sim: build
|
||||
vsim -lib $(library) $(toplevel) -do "do wave.do" $(sim_opts)
|
||||
|
||||
# batch mode without gui
|
||||
simc: build
|
||||
vsim -lib $(library) $(toplevel) -c -do "run -all; exit" $(sim_opts)
|
||||
|
||||
clean:
|
||||
rm -rf $(library)
|
||||
|
||||
.PHONY: clean simc sim build
|
||||
|
954
corev_apu/tb/tb_wt_axi_dcache/hdl/tb.sv
Normal file
954
corev_apu/tb/tb_wt_axi_dcache/hdl/tb.sv
Normal file
|
@ -0,0 +1,954 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
//
|
||||
// Author: Michael Schaffner <schaffner@iis.ee.ethz.ch>, ETH Zurich
|
||||
// Nils Wistoff <nwistoff@iis.ee.ethz.ch>, ETH Zurich
|
||||
// Date: 04.09.2020
|
||||
// Description: testbench for nonblocking write-back L1 dcache.
|
||||
|
||||
`include "tb.svh"
|
||||
`include "assign.svh"
|
||||
`include "axi/typedef.svh"
|
||||
|
||||
module tb import ariane_pkg::*; import wt_cache_pkg::*; import tb_pkg::*; #()();
|
||||
|
||||
// leave this
|
||||
timeunit 1ps;
|
||||
timeprecision 1ps;
|
||||
|
||||
// memory configuration (64bit words)
|
||||
parameter MemBytes = 2**DCACHE_INDEX_WIDTH * 4 * 32;
|
||||
parameter MemWords = MemBytes>>3;
|
||||
|
||||
// noncacheable portion
|
||||
parameter logic [63:0] CachedAddrBeg = MemBytes>>3;//1/8th of the memory is NC
|
||||
parameter logic [63:0] CachedAddrEnd = 64'hFFFF_FFFF_FFFF_FFFF;
|
||||
|
||||
// contention and invalidation rates (in %)
|
||||
parameter MemRandHitRate = 75;
|
||||
parameter MemRandInvRate = 10;
|
||||
parameter TlbHitRate = 95;
|
||||
|
||||
// parameters for random read sequences (in %)
|
||||
parameter FlushRate = 10;
|
||||
parameter KillRate = 5;
|
||||
|
||||
parameter Verbose = 0;
|
||||
|
||||
// number of vectors per test
|
||||
parameter nReadVectors = 20000;
|
||||
parameter nWriteVectors = 20000;
|
||||
parameter nAMOs = 20000;
|
||||
|
||||
/// ID width of the Full AXI slave port, master port has ID `AxiIdWidthFull + 32'd1`
|
||||
parameter int unsigned TbAxiIdWidthFull = 32'd6;
|
||||
/// Address width of the full AXI bus
|
||||
parameter int unsigned TbAxiAddrWidthFull = 32'd64;
|
||||
/// Data width of the full AXI bus
|
||||
parameter int unsigned TbAxiDataWidthFull = 32'd64;
|
||||
localparam int unsigned TbAxiUserWidthFull = AXI_USER_WIDTH;
|
||||
/// Application time to the DUT
|
||||
parameter time TbApplTime = 2ns;
|
||||
/// Test time of the DUT
|
||||
parameter time TbTestTime = 8ns;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// MUT signal declarations
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`AXI_TYPEDEF_ALL(axi_data,
|
||||
logic [ TbAxiAddrWidthFull-1:0],
|
||||
logic [ TbAxiIdWidthFull-1:0],
|
||||
logic [ TbAxiDataWidthFull-1:0],
|
||||
logic [(TbAxiDataWidthFull/8)-1:0],
|
||||
logic [ TbAxiUserWidthFull-1:0])
|
||||
|
||||
logic enable_i;
|
||||
logic flush_i;
|
||||
logic flush_ack_o;
|
||||
logic miss_o;
|
||||
amo_req_t amo_req_i;
|
||||
amo_resp_t amo_resp_o;
|
||||
dcache_req_i_t [2:0] req_ports_i;
|
||||
dcache_req_o_t [2:0] req_ports_o;
|
||||
axi_data_req_t axi_data_o;
|
||||
axi_data_resp_t axi_data_i;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// TB signal declarations
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
string test_name;
|
||||
logic clk_i, rst_ni;
|
||||
logic [31:0] seq_num_resp, seq_num_write, seq_num_amo;
|
||||
seq_t [2:0] seq_type;
|
||||
logic [3:0] seq_done;
|
||||
logic [6:0] req_rate[2:0];
|
||||
logic seq_run, seq_last;
|
||||
logic end_of_sim;
|
||||
|
||||
logic mem_rand_en;
|
||||
logic inv_rand_en;
|
||||
logic amo_rand_en;
|
||||
logic tlb_rand_en;
|
||||
|
||||
logic write_en;
|
||||
logic [63:0] write_paddr, write_data;
|
||||
logic [7:0] write_be;
|
||||
|
||||
typedef struct packed {
|
||||
logic [1:0] size;
|
||||
logic [63:0] paddr;
|
||||
} resp_fifo_t;
|
||||
|
||||
typedef struct packed {
|
||||
logic valid;
|
||||
logic [63:0] paddr;
|
||||
} reservation_t;
|
||||
|
||||
logic [63:0] act_paddr[1:0];
|
||||
riscv::xlen_t exp_rdata[1:0];
|
||||
logic [63:0] exp_paddr[1:0];
|
||||
logic [63:0] amo_act_mem;
|
||||
logic [63:0] amo_shadow;
|
||||
logic [63:0] amo_exp_result;
|
||||
resp_fifo_t fifo_data_in[1:0];
|
||||
resp_fifo_t fifo_data[1:0];
|
||||
logic [1:0] fifo_push, fifo_pop, fifo_flush;
|
||||
logic [2:0] flush;
|
||||
logic flush_rand_en;
|
||||
|
||||
AXI_BUS_DV #(
|
||||
.AXI_ADDR_WIDTH ( TbAxiAddrWidthFull ),
|
||||
.AXI_DATA_WIDTH ( TbAxiDataWidthFull ),
|
||||
.AXI_ID_WIDTH ( TbAxiIdWidthFull + 32'd1 ),
|
||||
.AXI_USER_WIDTH ( TbAxiUserWidthFull )
|
||||
) axi_data_dv (
|
||||
.clk_i ( clk_i )
|
||||
);
|
||||
|
||||
`AXI_ASSIGN_FROM_REQ(axi_data_dv, axi_data_o)
|
||||
`AXI_ASSIGN_TO_RESP(axi_data_i, axi_data_dv)
|
||||
|
||||
typedef tb_mem_port #(
|
||||
.AW ( TbAxiAddrWidthFull ),
|
||||
.DW ( TbAxiDataWidthFull ),
|
||||
.IW ( TbAxiIdWidthFull + 32'd1 ),
|
||||
.UW ( TbAxiUserWidthFull ),
|
||||
.TA ( TbApplTime ),
|
||||
.TT ( TbTestTime ),
|
||||
.AX_MIN_WAIT_CYCLES ( 0 ),
|
||||
.AX_MAX_WAIT_CYCLES ( 50 ),
|
||||
.R_MIN_WAIT_CYCLES ( 10 ),
|
||||
.R_MAX_WAIT_CYCLES ( 20 ),
|
||||
.RESP_MIN_WAIT_CYCLES ( 10 ),
|
||||
.RESP_MAX_WAIT_CYCLES ( 20 ),
|
||||
.MEM_BYTES ( MemBytes )
|
||||
) tb_mem_port_t;
|
||||
|
||||
tb_mem_port_t data_mem_port;
|
||||
|
||||
AXI_BUS #(
|
||||
.AXI_ADDR_WIDTH ( TbAxiAddrWidthFull ),
|
||||
.AXI_DATA_WIDTH ( TbAxiDataWidthFull ),
|
||||
.AXI_ID_WIDTH ( TbAxiIdWidthFull + 32'd1 ),
|
||||
.AXI_USER_WIDTH ( TbAxiUserWidthFull )
|
||||
) axi_data ();
|
||||
|
||||
AXI_BUS #(
|
||||
.AXI_ADDR_WIDTH ( TbAxiAddrWidthFull ),
|
||||
.AXI_DATA_WIDTH ( TbAxiDataWidthFull ),
|
||||
.AXI_ID_WIDTH ( TbAxiIdWidthFull + 32'd1 ),
|
||||
.AXI_USER_WIDTH ( TbAxiUserWidthFull )
|
||||
) axi_amo_adapter ();
|
||||
|
||||
AXI_BUS_DV #(
|
||||
.AXI_ADDR_WIDTH ( TbAxiAddrWidthFull ),
|
||||
.AXI_DATA_WIDTH ( TbAxiDataWidthFull ),
|
||||
.AXI_ID_WIDTH ( TbAxiIdWidthFull + 32'd1 ),
|
||||
.AXI_USER_WIDTH ( TbAxiUserWidthFull )
|
||||
) axi_amo_adapter_dv (
|
||||
.clk_i ( clk_i )
|
||||
);
|
||||
|
||||
`AXI_ASSIGN(axi_data, axi_data_dv)
|
||||
`AXI_ASSIGN(axi_amo_adapter_dv, axi_amo_adapter)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Helper tasks
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Run a sequence of read (and write) vectors
|
||||
task automatic runSeq(input int nReadVectors, input int nWriteVectors = 0, input logic last =1'b0);
|
||||
seq_last = last;
|
||||
seq_run = 1'b1;
|
||||
seq_num_resp = nReadVectors;
|
||||
seq_num_write = nWriteVectors;
|
||||
seq_num_amo = 0;
|
||||
`APPL_WAIT_CYC(clk_i, 1)
|
||||
seq_run = 1'b0;
|
||||
`APPL_WAIT_SIG(clk_i, &seq_done)
|
||||
`APPL_WAIT_CYC(clk_i, 1)
|
||||
endtask : runSeq
|
||||
|
||||
// Run a sequence of AMOs
|
||||
task automatic runAMOs(input int nAMOs, input logic last =1'b0);
|
||||
seq_last = last;
|
||||
seq_run = 1'b1;
|
||||
seq_num_resp = 0;
|
||||
seq_num_write = 0;
|
||||
seq_num_amo = nAMOs;
|
||||
`APPL_WAIT_CYC(clk_i, 1)
|
||||
seq_run = 1'b0;
|
||||
`APPL_WAIT_SIG(clk_i, &seq_done)
|
||||
`APPL_WAIT_CYC(clk_i, 1)
|
||||
endtask : runAMOs
|
||||
|
||||
// Flush the cache
|
||||
task automatic flushCache();
|
||||
flush[2] = 1'b1;
|
||||
`APPL_WAIT_SIG(clk_i, flush_ack_o);
|
||||
flush[2] = 0'b0;
|
||||
`APPL_WAIT_CYC(clk_i, 1)
|
||||
endtask : flushCache
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Clock Process
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
always @*
|
||||
begin
|
||||
do begin
|
||||
clk_i = 1; #(CLK_HI);
|
||||
clk_i = 0; #(CLK_LO);
|
||||
end while (end_of_sim == 1'b0);
|
||||
repeat (100) begin
|
||||
// generate a few extra cycle to allow
|
||||
// response acquisition to complete
|
||||
clk_i = 1; #(CLK_HI);
|
||||
clk_i = 0; #(CLK_LO);
|
||||
end
|
||||
end
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// memory emulation
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// listen to the write/AMO ports and keep shadow memory up-to-date
|
||||
initial begin : p_mem
|
||||
automatic logic[63:0] amo_result, amo_op_a, amo_op_b, amo_op_a_u, amo_op_b_u;
|
||||
reservation_t reservation;
|
||||
|
||||
// Initialize
|
||||
reservation = '0;
|
||||
amo_exp_result = 'x;
|
||||
`APPL_WAIT_SIG(clk_i, ~rst_ni)
|
||||
`APPL_WAIT_CYC(clk_i, 1)
|
||||
|
||||
forever begin
|
||||
`ACQ_WAIT_CYC(clk_i, 1)
|
||||
amo_exp_result = 'x;
|
||||
|
||||
// Regular stores. These are directly written to shadow memory.
|
||||
if(write_en) begin
|
||||
for(int k=0; k<8; k++) begin
|
||||
if(write_be[k]) begin
|
||||
tb_mem_port_t::shadow_q[write_paddr + k] <= write_data[k*8 +: 8];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// AMOs. Here, we perform the AMO on shadow memory to keep it consistent with the memory and
|
||||
// deliver to an expected response.
|
||||
if (amo_req_i.req) begin
|
||||
// 32-bit AMO
|
||||
if (amo_req_i.size == 2'h2) begin
|
||||
// Sign-extended operands
|
||||
amo_op_a = $signed(amo_shadow[31:0]);
|
||||
amo_op_b = $signed(amo_req_i.operand_b[31:0]);
|
||||
|
||||
// Zero-extended operands
|
||||
amo_op_a_u = $unsigned(amo_shadow[31:0]);
|
||||
amo_op_b_u = $unsigned(amo_req_i.operand_b[31:0]);
|
||||
|
||||
// The result that is expected to be returned by AMO and evantually to be stored in rd.
|
||||
// For most AMOs, this is the previous memory content.
|
||||
// RISC-V spec requires: "For RV64, 32-bit AMOs always sign-extend the value placed in rd."
|
||||
amo_exp_result = amo_op_a;
|
||||
|
||||
// 64-bit AMO
|
||||
end else begin
|
||||
// Sign-extended operands
|
||||
amo_op_a = $signed(amo_shadow);
|
||||
amo_op_b = $signed(amo_req_i.operand_b);
|
||||
|
||||
// Zero-extended operands
|
||||
amo_op_a_u = $unsigned(amo_shadow);
|
||||
amo_op_b_u = $unsigned(amo_req_i.operand_b);
|
||||
|
||||
// The result that is expected to be returned by AMO and evantually to be stored in rd.
|
||||
// For most AMOs, this is the previous memory content.
|
||||
amo_exp_result = amo_shadow;
|
||||
end
|
||||
|
||||
// Perform actual AMO.
|
||||
case (amo_req_i.amo_op)
|
||||
// LR instruction
|
||||
AMO_LR: begin
|
||||
// Mark a reservation for requested memory location.
|
||||
reservation.valid = 1'b1;
|
||||
reservation.paddr = amo_req_i.operand_a;
|
||||
|
||||
// The memory contents remain unchanged (old contents == new contents)
|
||||
amo_result = amo_shadow;
|
||||
end
|
||||
|
||||
// SC instruction
|
||||
AMO_SC: begin
|
||||
// Check whether we have a valid reservation. If so, do the store and return 0.
|
||||
if (reservation.valid && reservation.paddr == amo_req_i.operand_a) begin
|
||||
amo_result = amo_op_b;
|
||||
amo_exp_result = 64'b0;
|
||||
|
||||
// Else, leave the memory unchanged and return 1.
|
||||
end else begin
|
||||
amo_result = amo_shadow;
|
||||
amo_exp_result = 64'b1;
|
||||
end
|
||||
|
||||
// Either way, invalidate the reservation.
|
||||
reservation.valid = 1'b0;
|
||||
end
|
||||
|
||||
// AMOs
|
||||
AMO_SWAP: amo_result = amo_op_b;
|
||||
AMO_ADD: amo_result = amo_op_a + amo_op_b;
|
||||
AMO_AND: amo_result = amo_op_a & amo_op_b;
|
||||
AMO_OR: amo_result = amo_op_a | amo_op_b;
|
||||
AMO_XOR: amo_result = amo_op_a ^ amo_op_b;
|
||||
AMO_MAX: amo_result = ($signed(amo_op_a) > $signed(amo_op_b)) ? amo_op_a : amo_op_b;
|
||||
AMO_MIN: amo_result = ($signed(amo_op_a) < $signed(amo_op_b)) ? amo_op_a : amo_op_b;
|
||||
AMO_MAXU: amo_result = (amo_op_a_u > amo_op_b_u) ? amo_op_a : amo_op_b;
|
||||
AMO_MINU: amo_result = (amo_op_a_u < amo_op_b_u) ? amo_op_a : amo_op_b;
|
||||
|
||||
// Default: Leave memory unchanged.
|
||||
default: amo_result = amo_shadow;
|
||||
endcase
|
||||
|
||||
`ACQ_WAIT_CYC(clk_i,1)
|
||||
|
||||
// Write back arithmetic result of AMO to shadow memory.
|
||||
for (int k = 0; k < 2**amo_req_i.size; k++) begin
|
||||
tb_mem_port_t::shadow_q[amo_req_i.operand_a + k] <= amo_result[k*8 +: 8];
|
||||
end
|
||||
|
||||
`ACQ_WAIT_SIG(clk_i,amo_resp_o.ack)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Instantiate memory and AXI ports
|
||||
initial begin : p_sim_mem
|
||||
// Create AXI ports
|
||||
data_mem_port = new(axi_amo_adapter_dv, CACHED);
|
||||
|
||||
// Initialize AXI ports and memory
|
||||
data_mem_port.reset();
|
||||
tb_mem_port_t::init_mem();
|
||||
|
||||
@(posedge rst_ni);
|
||||
|
||||
// Start AXI port emulation
|
||||
fork
|
||||
data_mem_port.run();
|
||||
join
|
||||
end
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// MUT
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
localparam ariane_cfg_t ArianeDefaultConfig = '{
|
||||
RASDepth: 2,
|
||||
BTBEntries: 32,
|
||||
BHTEntries: 128,
|
||||
// idempotent region
|
||||
NrNonIdempotentRules: 0,
|
||||
NonIdempotentAddrBase: {64'b0},
|
||||
NonIdempotentLength: {64'b0},
|
||||
// executable region
|
||||
NrExecuteRegionRules: 0,
|
||||
ExecuteRegionAddrBase: {64'h0},
|
||||
ExecuteRegionLength: {64'h0},
|
||||
// cached region
|
||||
NrCachedRegionRules: 1,
|
||||
CachedRegionAddrBase: {CachedAddrBeg},//1/8th of the memory is NC
|
||||
CachedRegionLength: {CachedAddrEnd-CachedAddrBeg+64'b1},
|
||||
// cache config
|
||||
AxiCompliant: 1'b1,
|
||||
SwapEndianess: 1'b0,
|
||||
// debug
|
||||
DmBaseAddress: 64'h0,
|
||||
NrPMPEntries: 0
|
||||
};
|
||||
|
||||
wt_cache_subsystem #(
|
||||
.ArianeCfg ( ArianeDefaultConfig ),
|
||||
.AxiAddrWidth ( TbAxiAddrWidthFull ),
|
||||
.AxiDataWidth ( TbAxiDataWidthFull ),
|
||||
.AxiIdWidth ( TbAxiIdWidthFull ),
|
||||
.axi_req_t ( axi_data_req_t ),
|
||||
.axi_rsp_t ( axi_data_resp_t )
|
||||
) i_dut (
|
||||
.clk_i (clk_i ),
|
||||
.rst_ni (rst_ni ),
|
||||
.icache_en_i ( '0 ),
|
||||
.icache_flush_i ( '0 ),
|
||||
.icache_miss_o ( ),
|
||||
.icache_areq_i ( '0 ),
|
||||
.icache_areq_o ( ),
|
||||
.icache_dreq_i ( '0 ),
|
||||
.icache_dreq_o ( ),
|
||||
.dcache_enable_i ( 1'b1 ),
|
||||
.dcache_flush_i ( flush_i ),
|
||||
.dcache_flush_ack_o ( flush_ack_o ),
|
||||
.dcache_amo_req_i ( amo_req_i ),
|
||||
.dcache_amo_resp_o ( amo_resp_o ),
|
||||
.dcache_miss_o ( ),
|
||||
.dcache_req_ports_i ( req_ports_i ),
|
||||
.dcache_req_ports_o ( req_ports_o ),
|
||||
.wbuffer_empty_o ( ),
|
||||
.wbuffer_not_ni_o ( ),
|
||||
.axi_req_o ( axi_data_o ),
|
||||
.axi_resp_i ( axi_data_i )
|
||||
);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// AXI Atomics Adapter
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
axi_riscv_atomics_wrap #(
|
||||
.AXI_ADDR_WIDTH ( TbAxiAddrWidthFull ),
|
||||
.AXI_DATA_WIDTH ( TbAxiDataWidthFull ),
|
||||
.AXI_ID_WIDTH ( TbAxiIdWidthFull + 32'd1 ),
|
||||
.AXI_USER_WIDTH ( TbAxiUserWidthFull ),
|
||||
.AXI_MAX_WRITE_TXNS ( 1 ),
|
||||
.RISCV_WORD_WIDTH ( riscv::XLEN )
|
||||
) i_amo_adapter (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
.mst ( axi_amo_adapter.Master ),
|
||||
.slv ( axi_data.Slave )
|
||||
);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// port emulation programs
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// get actual paddr from read controllers
|
||||
assign act_paddr[0] = {i_dut.i_wt_dcache.gen_rd_ports[0].i_wt_dcache_ctrl.address_tag_d,
|
||||
i_dut.i_wt_dcache.gen_rd_ports[0].i_wt_dcache_ctrl.address_idx_q,
|
||||
i_dut.i_wt_dcache.gen_rd_ports[0].i_wt_dcache_ctrl.address_off_q};
|
||||
assign act_paddr[1] = {i_dut.i_wt_dcache.gen_rd_ports[1].i_wt_dcache_ctrl.address_tag_d,
|
||||
i_dut.i_wt_dcache.gen_rd_ports[1].i_wt_dcache_ctrl.address_idx_q,
|
||||
i_dut.i_wt_dcache.gen_rd_ports[1].i_wt_dcache_ctrl.address_off_q};
|
||||
|
||||
// generate fifo queues for expected responses
|
||||
generate
|
||||
for(genvar k=0; k<2;k++) begin
|
||||
assign fifo_data_in[k] = {req_ports_i[k].data_size,
|
||||
exp_paddr[k]};
|
||||
|
||||
for (genvar l=0; l<riscv::XLEN/8; l++)
|
||||
assign exp_rdata[k][l*8 +: 8] = tb_mem_port_t::shadow_q[{fifo_data[k].paddr[63:3], 3'b0} + l];
|
||||
|
||||
assign fifo_push[k] = req_ports_i[k].data_req & req_ports_o[k].data_gnt;
|
||||
assign fifo_flush[k] = req_ports_i[k].kill_req;
|
||||
assign fifo_pop[k] = req_ports_o[k].data_rvalid & ~req_ports_i[k].kill_req;
|
||||
|
||||
fifo_v3 #(
|
||||
.dtype(resp_fifo_t)
|
||||
) i_resp_fifo (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
.flush_i ( fifo_flush[k] ),
|
||||
.testmode_i ( '0 ),
|
||||
.full_o ( ),
|
||||
.empty_o ( ),
|
||||
.usage_o ( ),
|
||||
.data_i ( fifo_data_in[k] ),
|
||||
.push_i ( fifo_push[k] ),
|
||||
.data_o ( fifo_data[k] ),
|
||||
.pop_i ( fifo_pop[k] )
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// memory and shadow memory region that are addressed by current AMO
|
||||
for (genvar k=0; k<8; k++) begin
|
||||
assign amo_act_mem[k*8 +: 8] = tb_mem_port_t::memory_q[amo_req_i.operand_a + k];
|
||||
assign amo_shadow[k*8 +: 8] = tb_mem_port_t::shadow_q[amo_req_i.operand_a + k];
|
||||
end
|
||||
|
||||
tb_readport #(
|
||||
.PortName ( "RD0" ),
|
||||
.FlushRate ( FlushRate ),
|
||||
.KillRate ( KillRate ),
|
||||
.TlbHitRate ( TlbHitRate ),
|
||||
.MemWords ( MemWords ),
|
||||
.CachedAddrBeg ( CachedAddrBeg ),
|
||||
.CachedAddrEnd ( CachedAddrEnd ),
|
||||
.RndSeed ( 5555555 ),
|
||||
.Verbose ( Verbose )
|
||||
) i_tb_readport0 (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
.test_name_i ( test_name ),
|
||||
.req_rate_i ( req_rate[0] ),
|
||||
.seq_type_i ( seq_type[0] ),
|
||||
.tlb_rand_en_i ( tlb_rand_en ),
|
||||
.flush_rand_en_i ( flush_rand_en ),
|
||||
.seq_run_i ( seq_run ),
|
||||
.seq_num_resp_i ( seq_num_resp ),
|
||||
.seq_last_i ( seq_last ),
|
||||
.seq_done_o ( seq_done[0] ),
|
||||
.exp_paddr_o ( exp_paddr[0] ),
|
||||
.exp_size_i ( fifo_data[0].size ),
|
||||
.exp_paddr_i ( fifo_data[0].paddr ),
|
||||
.exp_rdata_i ( exp_rdata[0] ),
|
||||
.act_paddr_i ( act_paddr[0] ),
|
||||
.flush_o ( flush[0] ),
|
||||
.flush_ack_i ( flush_ack_o ),
|
||||
.dut_req_port_o ( req_ports_i[0] ),
|
||||
.dut_req_port_i ( req_ports_o[0] )
|
||||
);
|
||||
|
||||
tb_readport #(
|
||||
.PortName ( "RD1" ),
|
||||
.FlushRate ( FlushRate ),
|
||||
.KillRate ( KillRate ),
|
||||
.TlbHitRate ( TlbHitRate ),
|
||||
.MemWords ( MemWords ),
|
||||
.CachedAddrBeg ( CachedAddrBeg ),
|
||||
.CachedAddrEnd ( CachedAddrEnd ),
|
||||
.RndSeed ( 3333333 ),
|
||||
.Verbose ( Verbose )
|
||||
) i_tb_readport1 (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
.test_name_i ( test_name ),
|
||||
.req_rate_i ( req_rate[1] ),
|
||||
.seq_type_i ( seq_type[1] ),
|
||||
.tlb_rand_en_i ( tlb_rand_en ),
|
||||
.flush_rand_en_i ( flush_rand_en ),
|
||||
.seq_run_i ( seq_run ),
|
||||
.seq_num_resp_i ( seq_num_resp ),
|
||||
.seq_last_i ( seq_last ),
|
||||
.exp_paddr_o ( exp_paddr[1] ),
|
||||
.exp_size_i ( fifo_data[1].size ),
|
||||
.exp_paddr_i ( fifo_data[1].paddr ),
|
||||
.exp_rdata_i ( exp_rdata[1] ),
|
||||
.act_paddr_i ( act_paddr[1] ),
|
||||
.seq_done_o ( seq_done[1] ),
|
||||
.flush_o ( flush[1] ),
|
||||
.flush_ack_i ( flush_ack_o ),
|
||||
.dut_req_port_o ( req_ports_i[1] ),
|
||||
.dut_req_port_i ( req_ports_o[1] )
|
||||
);
|
||||
|
||||
tb_writeport #(
|
||||
.PortName ( "WR0" ),
|
||||
.MemWords ( MemWords ),
|
||||
.CachedAddrBeg ( CachedAddrBeg ),
|
||||
.CachedAddrEnd ( CachedAddrEnd ),
|
||||
.RndSeed ( 7777777 ),
|
||||
.Verbose ( Verbose )
|
||||
) i_tb_writeport (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
.test_name_i ( test_name ),
|
||||
.req_rate_i ( req_rate[2] ),
|
||||
.seq_type_i ( seq_type[2] ),
|
||||
.seq_run_i ( seq_run ),
|
||||
.seq_num_vect_i ( seq_num_write ),
|
||||
.seq_last_i ( seq_last ),
|
||||
.seq_done_o ( seq_done[2] ),
|
||||
.dut_req_port_o ( req_ports_i[2] ),
|
||||
.dut_req_port_i ( req_ports_o[2] )
|
||||
);
|
||||
|
||||
tb_amoport #(
|
||||
.PortName ("AMO0"),
|
||||
.MemWords ( MemWords ),
|
||||
.CachedAddrBeg ( CachedAddrBeg ),
|
||||
.CachedAddrEnd ( CachedAddrEnd ),
|
||||
.RndSeed ( 1111111 ),
|
||||
.Verbose ( Verbose )
|
||||
) i_tb_amoport (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
.test_name_i ( test_name ),
|
||||
.seq_run_i ( seq_run ),
|
||||
.seq_num_amo_i ( seq_num_amo ),
|
||||
.seq_last_i ( seq_last ),
|
||||
.seq_done_o ( seq_done[3] ),
|
||||
.act_mem_i ( amo_act_mem ),
|
||||
.exp_mem_i ( amo_shadow ),
|
||||
.exp_result_i ( amo_exp_result ),
|
||||
.dut_amo_req_port_o ( amo_req_i ),
|
||||
.dut_amo_resp_port_i ( amo_resp_o )
|
||||
);
|
||||
|
||||
// Translate write requests for shadow memory.
|
||||
initial begin
|
||||
forever begin
|
||||
`WAIT_CYC(clk_i,1)
|
||||
|
||||
write_en = req_ports_i[2].data_req & req_ports_o[2].data_gnt & req_ports_i[2].data_we;
|
||||
write_paddr = {req_ports_i[2].address_tag, req_ports_i[2].address_index};
|
||||
write_data = req_ports_i[2].data_wdata;
|
||||
write_be = req_ports_i[2].data_be;
|
||||
end
|
||||
end
|
||||
|
||||
assign flush_i = |flush;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// simulation coordinator process
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TODO: implement CSR / controller
|
||||
// flush_i, flush_ack_o, enable_i, miss_o, wbuffer_empty_o
|
||||
|
||||
|
||||
initial begin : p_stim
|
||||
test_name = "";
|
||||
seq_type = '{default: RANDOM_SEQ};
|
||||
req_rate = '{default: 7'd75};
|
||||
seq_run = 1'b0;
|
||||
seq_last = 1'b0;
|
||||
seq_num_resp = '0;
|
||||
seq_num_write = '0;
|
||||
// seq_done
|
||||
end_of_sim = 0;
|
||||
rst_ni = 0;
|
||||
// randomization settings
|
||||
mem_rand_en = 0;
|
||||
tlb_rand_en = 0;
|
||||
inv_rand_en = 0;
|
||||
amo_rand_en = 0;
|
||||
flush_rand_en = 0;
|
||||
// cache ctrl
|
||||
flush[2] = 0;
|
||||
// flush_ack_o
|
||||
enable_i = 0;
|
||||
// miss_o
|
||||
|
||||
// Print some info
|
||||
$display("TB> current configuration:");
|
||||
$display("TB> MemWords %d", MemWords);
|
||||
$display("TB> CachedAddrBeg %16X", CachedAddrBeg);
|
||||
$display("TB> CachedAddrEnd %16X", CachedAddrEnd);
|
||||
$display("TB> MemRandHitRate %d", MemRandHitRate);
|
||||
$display("TB> MemRandInvRate %d", MemRandInvRate);
|
||||
|
||||
// Reset cycles
|
||||
`APPL_WAIT_CYC(clk_i,100)
|
||||
rst_ni = 1'b1;
|
||||
`APPL_WAIT_CYC(clk_i,100)
|
||||
|
||||
$display("TB> start with test sequences");
|
||||
|
||||
// Apply each test until seq_num_resp memory requests have successfully completed
|
||||
///////////////////////////////////////////////
|
||||
test_name = "TEST 0 -- random read -- disabled cache";
|
||||
|
||||
// Config
|
||||
enable_i = 0;
|
||||
seq_type = '{default: RANDOM_SEQ};
|
||||
req_rate = '{default: 7'd50};
|
||||
|
||||
// Cache disabled ~> all requests should use bypass port
|
||||
data_mem_port.set_region(0, MemBytes - 1);
|
||||
|
||||
runSeq(nReadVectors);
|
||||
flushCache();
|
||||
tb_mem_port_t::check_mem();
|
||||
|
||||
///////////////////////////////////////////////
|
||||
test_name = "TEST 1 -- linear read -- disabled cache";
|
||||
|
||||
// Config
|
||||
enable_i = 0;
|
||||
seq_type = '{default: LINEAR_SEQ};
|
||||
req_rate = '{default: 7'd50};
|
||||
|
||||
runSeq(nReadVectors);
|
||||
flushCache();
|
||||
tb_mem_port_t::check_mem();
|
||||
|
||||
///////////////////////////////////////////////
|
||||
test_name = "TEST 2 -- random read -- enabled cache";
|
||||
|
||||
// Config
|
||||
enable_i = 1;
|
||||
seq_type = '{default: RANDOM_SEQ};
|
||||
req_rate = '{default: 7'd50};
|
||||
|
||||
runSeq(nReadVectors);
|
||||
flushCache();
|
||||
tb_mem_port_t::check_mem();
|
||||
|
||||
///////////////////////////////////////////////
|
||||
test_name = "TEST 3 -- linear read -- enabled cache";
|
||||
|
||||
// Config
|
||||
enable_i = 1;
|
||||
seq_type = '{default: LINEAR_SEQ};
|
||||
req_rate = '{default: 7'd50};
|
||||
|
||||
runSeq(nReadVectors);
|
||||
flushCache();
|
||||
tb_mem_port_t::check_mem();
|
||||
|
||||
///////////////////////////////////////////////
|
||||
test_name = "TEST 4 -- random read -- enabled cache + tlb, mem contentions";
|
||||
|
||||
// Config
|
||||
enable_i = 1;
|
||||
tlb_rand_en = 1;
|
||||
mem_rand_en = 1;
|
||||
seq_type = '{default: RANDOM_SEQ};
|
||||
req_rate = '{default: 7'd50};
|
||||
|
||||
runSeq(nReadVectors);
|
||||
flushCache();
|
||||
tb_mem_port_t::check_mem();
|
||||
|
||||
///////////////////////////////////////////////
|
||||
test_name = "TEST 5 -- linear read -- enabled cache + tlb, mem contentions";
|
||||
|
||||
// Config
|
||||
enable_i = 1;
|
||||
tlb_rand_en = 1;
|
||||
mem_rand_en = 1;
|
||||
seq_type = '{default: LINEAR_SEQ};
|
||||
req_rate = '{default: 7'd50};
|
||||
|
||||
runSeq(nReadVectors);
|
||||
flushCache();
|
||||
tb_mem_port_t::check_mem();
|
||||
|
||||
///////////////////////////////////////////////
|
||||
test_name = "TEST 6 -- random read -- enabled cache + tlb, mem contentions + invalidations";
|
||||
|
||||
// Config
|
||||
enable_i = 1;
|
||||
tlb_rand_en = 1;
|
||||
mem_rand_en = 1;
|
||||
inv_rand_en = 1;
|
||||
seq_type = '{default: RANDOM_SEQ};
|
||||
req_rate = '{default: 7'd50};
|
||||
|
||||
runSeq(nReadVectors);
|
||||
flushCache();
|
||||
tb_mem_port_t::check_mem();
|
||||
|
||||
///////////////////////////////////////////////
|
||||
test_name = "TEST 7 -- random read/write -- disabled cache";
|
||||
|
||||
// Config
|
||||
enable_i = 0;
|
||||
tlb_rand_en = 0;
|
||||
mem_rand_en = 0;
|
||||
inv_rand_en = 0;
|
||||
seq_type = '{default: RANDOM_SEQ};
|
||||
req_rate = '{default: 7'd25};
|
||||
|
||||
runSeq(nReadVectors,nWriteVectors);
|
||||
flushCache();
|
||||
tb_mem_port_t::check_mem();
|
||||
|
||||
///////////////////////////////////////////////
|
||||
test_name = "TEST 8 -- random read/write -- enabled cache";
|
||||
|
||||
// Config
|
||||
enable_i = 1;
|
||||
tlb_rand_en = 0;
|
||||
mem_rand_en = 0;
|
||||
inv_rand_en = 0;
|
||||
seq_type = '{default: RANDOM_SEQ};
|
||||
req_rate = '{default: 7'd25};
|
||||
|
||||
runSeq(nReadVectors,2*nWriteVectors);
|
||||
flushCache();
|
||||
tb_mem_port_t::check_mem();
|
||||
|
||||
///////////////////////////////////////////////
|
||||
test_name = "TEST 9 -- random read/write -- enabled cache + tlb, mem contentions + invalidations";
|
||||
|
||||
// Config
|
||||
enable_i = 1;
|
||||
tlb_rand_en = 1;
|
||||
mem_rand_en = 1;
|
||||
inv_rand_en = 1;
|
||||
seq_type = '{default: RANDOM_SEQ};
|
||||
req_rate = '{default: 7'd25};
|
||||
|
||||
runSeq(nReadVectors,2*nWriteVectors);
|
||||
flushCache();
|
||||
tb_mem_port_t::check_mem();
|
||||
|
||||
///////////////////////////////////////////////
|
||||
test_name = "TEST 10 -- linear burst write -- enabled cache";
|
||||
|
||||
// Config
|
||||
enable_i = 1;
|
||||
tlb_rand_en = 0;
|
||||
mem_rand_en = 0;
|
||||
inv_rand_en = 0;
|
||||
seq_type = '{LINEAR_SEQ, IDLE_SEQ, IDLE_SEQ};
|
||||
req_rate = '{100, 0, 0};
|
||||
|
||||
runSeq(0,nWriteVectors);
|
||||
flushCache();
|
||||
tb_mem_port_t::check_mem();
|
||||
|
||||
///////////////////////////////////////////////
|
||||
test_name = "TEST 11 -- linear burst write with hot cache";
|
||||
|
||||
// Config
|
||||
enable_i = 1;
|
||||
tlb_rand_en = 0;
|
||||
mem_rand_en = 0;
|
||||
inv_rand_en = 0;
|
||||
seq_type = '{IDLE_SEQ, IDLE_SEQ, LINEAR_SEQ};
|
||||
req_rate = '{default:100};
|
||||
|
||||
runSeq((CachedAddrBeg>>3)+(2**(DCACHE_INDEX_WIDTH-3))*DCACHE_SET_ASSOC);
|
||||
seq_type = '{LINEAR_SEQ, IDLE_SEQ, IDLE_SEQ};
|
||||
runSeq(0,(CachedAddrBeg>>3)+(2**(DCACHE_INDEX_WIDTH-3))*DCACHE_SET_ASSOC);
|
||||
flushCache();
|
||||
tb_mem_port_t::check_mem();
|
||||
|
||||
///////////////////////////////////////////////
|
||||
test_name = "TEST 12 -- random write bursts -- enabled cache";
|
||||
|
||||
// Config
|
||||
enable_i = 1;
|
||||
tlb_rand_en = 0;
|
||||
mem_rand_en = 0;
|
||||
inv_rand_en = 0;
|
||||
seq_type = '{BURST_SEQ, RANDOM_SEQ, RANDOM_SEQ};
|
||||
req_rate = '{75, 0, 0};
|
||||
|
||||
runSeq(0,nWriteVectors);
|
||||
flushCache();
|
||||
tb_mem_port_t::check_mem();
|
||||
|
||||
///////////////////////////////////////////////
|
||||
test_name = "TEST 13 -- random write bursts -- enabled cache + tlb, mem contentions + invalidations";
|
||||
|
||||
// Config
|
||||
enable_i = 1;
|
||||
tlb_rand_en = 1;
|
||||
mem_rand_en = 1;
|
||||
inv_rand_en = 1;
|
||||
seq_type = '{BURST_SEQ, IDLE_SEQ, IDLE_SEQ};
|
||||
req_rate = '{75, 0, 0};
|
||||
|
||||
runSeq(0,nWriteVectors);
|
||||
flushCache();
|
||||
tb_mem_port_t::check_mem();
|
||||
|
||||
///////////////////////////////////////////////
|
||||
test_name = "TEST 14 -- random write/read-- enabled cache + tlb, mem contentions + invalidations";
|
||||
|
||||
// Config
|
||||
enable_i = 1;
|
||||
tlb_rand_en = 1;
|
||||
mem_rand_en = 1;
|
||||
inv_rand_en = 1;
|
||||
seq_type = '{RANDOM_SEQ, RANDOM_SEQ, RANDOM_SEQ};
|
||||
req_rate = '{default:25};
|
||||
|
||||
runSeq(nReadVectors,nWriteVectors);
|
||||
flushCache();
|
||||
tb_mem_port_t::check_mem();
|
||||
|
||||
///////////////////////////////////////////////
|
||||
test_name = "TEST 15 -- short wrapping sequences to provoke writebuffer hits";
|
||||
|
||||
// Config
|
||||
enable_i = 1;
|
||||
tlb_rand_en = 0;
|
||||
mem_rand_en = 0;
|
||||
inv_rand_en = 0;
|
||||
seq_type = '{WRAP_SEQ, IDLE_SEQ, WRAP_SEQ};
|
||||
req_rate = '{100,0,20};
|
||||
|
||||
runSeq(nReadVectors,nWriteVectors);
|
||||
flushCache();
|
||||
tb_mem_port_t::check_mem();
|
||||
|
||||
///////////////////////////////////////////////
|
||||
test_name = "TEST 16 -- random write/read-- enabled cache + tlb, mem contentions + invalidations + random flushes";
|
||||
|
||||
// Config
|
||||
enable_i = 1;
|
||||
tlb_rand_en = 1;
|
||||
mem_rand_en = 1;
|
||||
inv_rand_en = 1;
|
||||
flush_rand_en = 1;
|
||||
seq_type = '{RANDOM_SEQ, RANDOM_SEQ, RANDOM_SEQ};
|
||||
req_rate = '{default:25};
|
||||
|
||||
runSeq(nReadVectors,nWriteVectors);
|
||||
flushCache();
|
||||
tb_mem_port_t::check_mem();
|
||||
|
||||
///////////////////////////////////////////////
|
||||
test_name = "TEST 17 -- set contention -- enabled cache";
|
||||
|
||||
// Config
|
||||
enable_i = 1;
|
||||
tlb_rand_en = 1;
|
||||
mem_rand_en = 0;
|
||||
inv_rand_en = 0;
|
||||
seq_type = '{CONST_SEQ, IDLE_SEQ, SET_SEQ};
|
||||
req_rate = '{50,0,2};
|
||||
|
||||
runSeq(0.2*nReadVectors,2*nWriteVectors);
|
||||
flushCache();
|
||||
tb_mem_port_t::check_mem();
|
||||
|
||||
///////////////////////////////////////////////
|
||||
test_name = "TEST 18 -- AMOs";
|
||||
|
||||
// Config
|
||||
enable_i = 1;
|
||||
tlb_rand_en = 1;
|
||||
mem_rand_en = 0;
|
||||
inv_rand_en = 0;
|
||||
seq_type = '{CONST_SEQ, IDLE_SEQ, SET_SEQ};
|
||||
req_rate = '{50,0,2};
|
||||
|
||||
runAMOs(nAMOs,1); // Last sequence flag, terminates agents
|
||||
flushCache();
|
||||
tb_mem_port_t::check_mem();
|
||||
|
||||
/////////////////////////////////////////////
|
||||
end_of_sim = 1;
|
||||
$display("TB> end test sequences");
|
||||
tb_mem_port_t::report_mem();
|
||||
end
|
||||
|
||||
endmodule
|
54
corev_apu/tb/tb_wt_axi_dcache/tb.list
Normal file
54
corev_apu/tb/tb_wt_axi_dcache/tb.list
Normal file
|
@ -0,0 +1,54 @@
|
|||
../../../core/include/cv64a6_imafdc_sv39_config_pkg.sv
|
||||
../../../core/include/riscv_pkg.sv
|
||||
../common_verification/src/clk_rst_gen.sv
|
||||
../common_verification/src/rand_id_queue.sv
|
||||
../common_verification/src/rand_stream_mst.sv
|
||||
../common_verification/src/rand_synch_holdable_driver.sv
|
||||
../common_verification/src/rand_verif_pkg.sv
|
||||
../common_verification/src/sim_timeout.sv
|
||||
../common_verification/src/rand_synch_driver.sv
|
||||
../common_verification/src/rand_stream_slv.sv
|
||||
../../riscv-dbg/src/dm_pkg.sv
|
||||
../../axi/src/axi_pkg.sv
|
||||
../../axi/src/axi_intf.sv
|
||||
../../axi/src/axi_test.sv
|
||||
../../../core/fpu/src/fpnew_pkg.sv
|
||||
../../../core/include/ariane_pkg.sv
|
||||
../ariane_soc_pkg.sv
|
||||
../ariane_axi_soc_pkg.sv
|
||||
../../../core/include/ariane_axi_pkg.sv
|
||||
../../../core/include/wt_cache_pkg.sv
|
||||
../../fpga-support/rtl/SyncSpRamBeNx64.sv
|
||||
../../../core/cache_subsystem/wt_dcache_ctrl.sv
|
||||
../../../core/cache_subsystem/wt_dcache_mem.sv
|
||||
../../../core/cache_subsystem/wt_dcache_missunit.sv
|
||||
../../../core/cache_subsystem/wt_dcache_wbuffer.sv
|
||||
../../../core/cache_subsystem/wt_dcache.sv
|
||||
../../../core/cache_subsystem/cva6_icache.sv
|
||||
../../../core/axi_shim.sv
|
||||
../../../core/cache_subsystem/wt_axi_adapter.sv
|
||||
../../../core/cache_subsystem/wt_cache_subsystem.sv
|
||||
../../../common/submodules/common_cells/src/cf_math_pkg.sv
|
||||
../../../common/submodules/common_cells/src/lfsr.sv
|
||||
../../../common/submodules/common_cells/src/fifo_v3.sv
|
||||
../../../common/submodules/common_cells/src/lzc.sv
|
||||
../../../common/submodules/common_cells/src/rr_arb_tree.sv
|
||||
../../../common/submodules/common_cells/src/exp_backoff.sv
|
||||
../../../common/submodules/common_cells/src/stream_arbiter.sv
|
||||
../../../common/submodules/common_cells/src/stream_arbiter_flushable.sv
|
||||
../../../common/submodules/common_cells/src/stream_mux.sv
|
||||
../../src/tech_cells_generic/src/rtl/tc_sram.sv
|
||||
../../../common/local/util/tc_sram_wrapper.sv
|
||||
../../../common/local/util/sram.sv
|
||||
../../src/axi_riscv_atomics/src/axi_res_tbl.sv
|
||||
../../src/axi_riscv_atomics/src/axi_riscv_amos.sv
|
||||
../../src/axi_riscv_atomics/src/axi_riscv_amos_alu.sv
|
||||
../../src/axi_riscv_atomics/src/axi_riscv_lrsc.sv
|
||||
../../src/axi_riscv_atomics/src/axi_riscv_atomics.sv
|
||||
../../src/axi_riscv_atomics/src/axi_riscv_atomics_wrap.sv
|
||||
|
||||
../common/tb_dcache_pkg.sv
|
||||
../common/tb_readport.sv
|
||||
../common/tb_writeport.sv
|
||||
../common/tb_amoport.sv
|
||||
hdl/tb.sv
|
348
corev_apu/tb/tb_wt_axi_dcache/wave.do
Normal file
348
corev_apu/tb/tb_wt_axi_dcache/wave.do
Normal file
|
@ -0,0 +1,348 @@
|
|||
onerror {resume}
|
||||
quietly WaveActivateNextPane {} 0
|
||||
add wave -noupdate /tb/*
|
||||
add wave -noupdate -divider Modules
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/clk_i
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/rst_ni
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/enable_i
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/flush_i
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/amo_req_i
|
||||
add wave -noupdate -expand -group i_dut -expand -subitemconfig {{/tb/i_dut/i_wt_dcache/req_ports_i[1]} -expand} /tb/i_dut/i_wt_dcache/req_ports_i
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/mem_rtrn_vld_i
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/mem_rtrn_i
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/mem_data_ack_i
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/cache_en
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/wr_cl_vld
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/wr_cl_tag
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/wr_cl_idx
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/wr_cl_off
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/wr_cl_data
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/wr_cl_data_be
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/wr_vld_bits
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/wr_req
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/wr_ack
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/wr_idx
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/wr_off
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/wr_data
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/wr_data_be
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/miss_req
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/miss_ack
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/miss_nc
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/miss_we
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/miss_wdata
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/miss_paddr
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/miss_vld_bits
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/miss_size
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/miss_rtrn_vld
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/miss_rtrn_id
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/rd_req
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/rd_ack
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/rd_tag
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/rd_idx
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/rd_off
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/rd_data
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/rd_vld_bits
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/rd_hit_oh
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/wbuffer_data
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/flush_ack_o
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/miss_o
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/wbuffer_empty_o
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/req_ports_o
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/mem_data_req_o
|
||||
add wave -noupdate -expand -group i_dut /tb/i_dut/i_wt_dcache/mem_data_o
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/clk_i
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/rst_ni
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/cache_en_i
|
||||
add wave -noupdate -group i_wbuffer -color Magenta /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/req_port_i
|
||||
add wave -noupdate -group i_wbuffer -color Magenta /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/req_port_o
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/miss_ack_i
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/miss_rtrn_vld_i
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/miss_rtrn_id_i
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/rd_ack_i
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/rd_data_i
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/rd_vld_bits_i
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/rd_hit_oh_i
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/wr_ack_i
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/empty_o
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/miss_paddr_o
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/miss_req_o
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/miss_we_o
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/miss_wdata_o
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/miss_vld_bits_o
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/miss_nc_o
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/miss_size_o
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/rd_tag_o
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/rd_idx_o
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/rd_off_o
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/rd_req_o
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/wr_req_o
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/wr_idx_o
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/wr_off_o
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/wr_data_o
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/wr_data_be_o
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/wbuffer_data_o
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/tx_stat_d
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/tx_stat_q
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/wbuffer_q
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/wbuffer_d
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/valid
|
||||
add wave -noupdate -group i_wbuffer -color Magenta /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/debug_paddr
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/dirty
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/tocheck
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/wbuffer_hit_oh
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/inval_hit
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/bdirty
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/next_ptr
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/dirty_ptr
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/hit_ptr
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/wr_ptr
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/check_ptr_d
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/check_ptr_q
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/rtrn_ptr
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/rtrn_id
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/bdirty_off
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/tx_be
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/wr_paddr
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/rd_paddr
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/check_en_d
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/check_en_q
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/full
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/dirty_rd_en
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/rdy
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/rtrn_empty
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/evict
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/ni_pending_d
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/ni_pending_q
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/is_ni
|
||||
add wave -noupdate -group i_wbuffer /tb/i_dut/i_wt_dcache/i_wt_dcache_wbuffer/is_nc_miss
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/clk_i
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/rst_ni
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/enable_i
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/flush_i
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/wbuffer_empty_i
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/amo_req_i
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/miss_req_i
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/miss_nc_i
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/miss_we_i
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/miss_wdata_i
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/miss_paddr_i
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/miss_vld_bits_i
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/miss_size_i
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/miss_id_i
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/tx_paddr_i
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/tx_vld_i
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/mem_rtrn_vld_i
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/mem_rtrn_i
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/mem_data_ack_i
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/AxiCompliant
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/AmoTxId
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/NumPorts
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/state_d
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/state_q
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/mshr_d
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/mshr_q
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/repl_way
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/inv_way
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/rnd_way
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/mshr_vld_d
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/mshr_vld_q
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/mshr_vld_q1
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/mshr_allocate
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/update_lfsr
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/all_ways_valid
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/enable_d
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/enable_q
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/flush_ack_d
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/flush_ack_q
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/flush_en
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/flush_done
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/mask_reads
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/lock_reqs
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/amo_sel
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/miss_is_write
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/amo_data
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/tmp_paddr
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/amo_rtrn_mux
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/miss_port_idx
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/cnt_d
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/cnt_q
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/miss_req_masked_d
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/miss_req_masked_q
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/inv_vld
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/inv_vld_all
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/cl_write_en
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/load_ack
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/store_ack
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/amo_ack
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/mshr_rdrd_collision_d
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/mshr_rdrd_collision_q
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/mshr_rdrd_collision
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/tx_rdwr_collision
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/mshr_rdwr_collision
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/flush_ack_o
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/miss_o
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/cache_en_o
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/amo_resp_o
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/miss_ack_o
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/miss_replay_o
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/miss_rtrn_vld_o
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/miss_rtrn_id_o
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/wr_cl_vld_o
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/wr_cl_nc_o
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/wr_cl_we_o
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/wr_cl_tag_o
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/wr_cl_idx_o
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/wr_cl_off_o
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/wr_cl_data_o
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/wr_cl_data_be_o
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/wr_vld_bits_o
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/mem_data_req_o
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache/i_wt_dcache_missunit/mem_data_o
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/clk_i
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/rst_ni
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/rd_tag_i
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/rd_idx_i
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/rd_off_i
|
||||
add wave -noupdate -group i_mem -expand /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/rd_req_i
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/wr_cl_vld_i
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/wr_cl_tag_i
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/wr_cl_idx_i
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/wr_cl_off_i
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/wr_cl_data_i
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/wr_cl_data_be_i
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/wr_vld_bits_i
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/wr_req_i
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/wr_idx_i
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/wr_off_i
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/wr_data_i
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/wr_data_be_i
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/wbuffer_data_i
|
||||
add wave -noupdate -group i_mem -expand /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/rd_ack_o
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/rd_vld_bits_o
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/rd_hit_oh_o
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/rd_data_o
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/wr_ack_o
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/bank_req
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/bank_we
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/bank_be
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/bank_idx
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/bank_idx_d
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/bank_idx_q
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/bank_off_d
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/bank_off_q
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/bank_wdata
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/bank_rdata
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/rdata_cl
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/vld_req
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/vld_we
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/vld_wdata
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/tag_rdata
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/vld_addr
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/vld_sel_d
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/vld_sel_q
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/wbuffer_hit_oh
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/wbuffer_be
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/wbuffer_rdata
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/rdata
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/wbuffer_cmp_addr
|
||||
add wave -noupdate -group i_mem /tb/i_dut/i_wt_dcache/i_wt_dcache_mem/vld_tag_rdata
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/clk_i}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/rst_ni}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/cache_en_i}
|
||||
add wave -noupdate -group i_ctrl0 -expand {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/req_port_i}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/miss_ack_i}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/miss_replay_i}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/miss_rtrn_vld_i}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/rd_ack_i}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/rd_data_i}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/rd_vld_bits_i}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/rd_hit_oh_i}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/req_port_o}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/miss_req_o}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/miss_we_o}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/miss_wdata_o}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/miss_vld_bits_o}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/miss_paddr_o}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/miss_nc_o}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/miss_size_o}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/rd_tag_o}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/rd_idx_o}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/rd_off_o}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/rd_req_o}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/state_d}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/state_q}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/address_tag_d}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/address_tag_q}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/address_idx_d}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/address_idx_q}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/address_off_d}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/address_off_q}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/vld_data_d}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/vld_data_q}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/save_tag}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/rd_req_d}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/rd_req_q}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/data_size_d}
|
||||
add wave -noupdate -group i_ctrl0 {/tb/i_dut/i_wt_dcache/gen_rd_ports[0]/i_wt_dcache_ctrl/data_size_q}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/clk_i}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/rst_ni}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/cache_en_i}
|
||||
add wave -noupdate -group i_ctrl1 -expand {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/req_port_i}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/miss_ack_i}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/miss_replay_i}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/miss_rtrn_vld_i}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/rd_ack_i}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/rd_data_i}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/rd_vld_bits_i}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/rd_hit_oh_i}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/req_port_o}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/miss_req_o}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/miss_we_o}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/miss_wdata_o}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/miss_vld_bits_o}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/miss_paddr_o}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/miss_nc_o}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/miss_size_o}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/rd_tag_o}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/rd_idx_o}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/rd_off_o}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/rd_req_o}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/state_d}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/state_q}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/address_tag_d}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/address_tag_q}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/address_idx_d}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/address_idx_q}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/address_off_d}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/address_off_q}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/vld_data_d}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/vld_data_q}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/save_tag}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/rd_req_d}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/rd_req_q}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/data_size_d}
|
||||
add wave -noupdate -group i_ctrl1 {/tb/i_dut/i_wt_dcache/gen_rd_ports[1]/i_wt_dcache_ctrl/data_size_q}
|
||||
add wave -noupdate -group i_axi_adapter {/tb/i_dut/i_adapter/*}
|
||||
add wave -noupdate -group i_axi_shim {/tb/i_dut/i_adapter/i_axi_shim/*}
|
||||
TreeUpdate [SetDefaultTree]
|
||||
quietly WaveActivateNextPane
|
||||
add wave -position insertpoint {sim:/tb_pkg::tb_mem_port::tb_mem_port__1::memory_q[8]}
|
||||
add wave -position insertpoint {sim:/tb_pkg::tb_mem_port::tb_mem_port__1::shadow_q[8]}
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {{Cursor 1} {31432807547 ps} 0} {{Cursor 2} {17675291 ps} 0} {{Cursor 3} {1027790000 ps} 0}
|
||||
quietly wave cursor active 2
|
||||
configure wave -namecolwidth 375
|
||||
configure wave -valuecolwidth 224
|
||||
configure wave -justifyvalue left
|
||||
configure wave -signalnamewidth 1
|
||||
configure wave -snapdistance 10
|
||||
configure wave -datasetprefix 0
|
||||
configure wave -rowmargin 4
|
||||
configure wave -childrowmargin 2
|
||||
configure wave -gridoffset 0
|
||||
configure wave -gridperiod 1
|
||||
configure wave -griddelta 40
|
||||
configure wave -timeline 0
|
||||
configure wave -timelineunits ps
|
||||
update
|
||||
WaveRestoreZoom {0 ps} {56623104 ps}
|
|
@ -55,7 +55,7 @@ module tb import tb_pkg::*; import ariane_pkg::*; import wt_cache_pkg::*; #()();
|
|||
CachedRegionAddrBase: {CachedAddrBeg},//1/8th of the memory is NC
|
||||
CachedRegionLength: {CachedAddrEnd-CachedAddrBeg+64'b1},
|
||||
// cache config
|
||||
Axi64BitCompliant: 1'b1,
|
||||
AxiCompliant: 1'b1,
|
||||
SwapEndianess: 1'b0,
|
||||
// debug
|
||||
DmBaseAddress: 64'h0,
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
../../axi/src/axi_intf.sv
|
||||
../../axi/src/axi_test.sv
|
||||
../../../core/include/ariane_pkg.sv
|
||||
../ariane_soc_pkg.sv
|
||||
../ariane_axi_soc_pkg.sv
|
||||
../../../core/include/ariane_axi_pkg.sv
|
||||
../../../core/include/wt_cache_pkg.sv
|
||||
../../fpga-support/rtl/SyncSpRamBeNx64.sv
|
||||
../../../core/cache_subsystem/wt_dcache_ctrl.sv
|
||||
|
@ -19,6 +22,8 @@
|
|||
../../../common/submodules/common_cells/src/lzc.sv
|
||||
../../../common/submodules/common_cells/src/rr_arb_tree.sv
|
||||
../../../common/submodules/common_cells/src/exp_backoff.sv
|
||||
../../src/tech_cells_generic/src/rtl/tc_sram.sv
|
||||
../../../common/local/util/tc_sram_wrapper.sv
|
||||
../../../common/local/util/sram.sv
|
||||
../common/tb_dcache_pkg.sv
|
||||
hdl/tb_mem.sv
|
||||
|
|
|
@ -246,7 +246,7 @@ add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache_missunit/tx_vld_i
|
|||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache_missunit/mem_rtrn_vld_i
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache_missunit/mem_rtrn_i
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache_missunit/mem_data_ack_i
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache_missunit/Axi64BitCompliant
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache_missunit/AxiCompliant
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache_missunit/AmoTxId
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache_missunit/NumPorts
|
||||
add wave -noupdate -group i_missunit /tb/i_dut/i_wt_dcache_missunit/state_d
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue