mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-06-28 09:16:22 -04:00
Add user
field between memory and caches (#857)
* wt_dcche_wbuffer.sv: fix assert Signed-off-by: Jean-Roch Coulon <jean-roch.coulon@thalesgroup.com> * Many files: Add user between memories and cva6 Signed-off-by: Jean-Roch Coulon <jean-roch.coulon@thalesgroup.com> * Update std_nbdcache.sv Make wb cache work * Update setup.sh Co-authored-by: Guillaume Chauvon <guillaume.chauvon@thalesgroup.com>
This commit is contained in:
parent
0b61544da8
commit
56f8c9f5fe
25 changed files with 269 additions and 41 deletions
|
@ -11,7 +11,7 @@ export CPLUS_INCLUDE_PATH=$RISCV/include
|
|||
echo 'deb http://download.opensuse.org/repositories/home:/phiwag:/edatools/xUbuntu_20.04/ /' | sudo tee /etc/apt/sources.list.d/home:phiwag:edatools.list
|
||||
curl -fsSL https://download.opensuse.org/repositories/home:phiwag:edatools/xUbuntu_20.04/Release.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/home_phiwag_edatools.gpg > /dev/null
|
||||
sudo apt update
|
||||
sudo apt install verilator-4.100 device-tree-compiler
|
||||
sudo apt install verilator-4.110 device-tree-compiler
|
||||
|
||||
ci/make-tmp.sh
|
||||
sudo mkdir -p $RISCV && sudo chmod 777 $RISCV
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
module sram #(
|
||||
parameter DATA_WIDTH = 64,
|
||||
parameter USER_WIDTH = 1,
|
||||
parameter USER_EN = 0,
|
||||
parameter NUM_WORDS = 1024,
|
||||
parameter OUT_REGS = 0, // enables output registers in FPGA macro (read lat = 2)
|
||||
parameter DROMAJO_RAM = 0
|
||||
|
@ -29,26 +31,34 @@ module sram #(
|
|||
input logic req_i,
|
||||
input logic we_i,
|
||||
input logic [$clog2(NUM_WORDS)-1:0] addr_i,
|
||||
input logic [USER_WIDTH-1:0] wuser_i,
|
||||
input logic [DATA_WIDTH-1:0] wdata_i,
|
||||
input logic [(DATA_WIDTH+7)/8-1:0] be_i,
|
||||
output logic [USER_WIDTH-1:0] ruser_o,
|
||||
output logic [DATA_WIDTH-1:0] rdata_o
|
||||
);
|
||||
|
||||
localparam DATA_WIDTH_ALIGNED = ((DATA_WIDTH+63)/64)*64;
|
||||
localparam USER_WIDTH_ALIGNED = DATA_WIDTH_ALIGNED; // To be fine tuned to reduce memory size
|
||||
localparam BE_WIDTH_ALIGNED = (((DATA_WIDTH+7)/8+7)/8)*8;
|
||||
|
||||
logic [DATA_WIDTH_ALIGNED-1:0] wdata_aligned;
|
||||
logic [USER_WIDTH_ALIGNED-1:0] wuser_aligned;
|
||||
logic [BE_WIDTH_ALIGNED-1:0] be_aligned;
|
||||
logic [DATA_WIDTH_ALIGNED-1:0] rdata_aligned;
|
||||
logic [USER_WIDTH_ALIGNED-1:0] ruser_aligned;
|
||||
|
||||
// align to 64 bits for inferrable macro below
|
||||
always_comb begin : p_align
|
||||
wdata_aligned ='0;
|
||||
wuser_aligned ='0;
|
||||
be_aligned ='0;
|
||||
wdata_aligned[DATA_WIDTH-1:0] = wdata_i;
|
||||
wuser_aligned[USER_WIDTH-1:0] = wuser_i;
|
||||
be_aligned[BE_WIDTH_ALIGNED-1:0] = be_i;
|
||||
|
||||
rdata_o = rdata_aligned[DATA_WIDTH-1:0];
|
||||
ruser_o = ruser_aligned[USER_WIDTH-1:0];
|
||||
end
|
||||
|
||||
for (genvar k = 0; k<(DATA_WIDTH+63)/64; k++) begin : gen_cut
|
||||
|
@ -67,6 +77,22 @@ end
|
|||
.Addr_DI ( addr_i ),
|
||||
.RdData_DO ( rdata_aligned[k*64 +: 64] )
|
||||
);
|
||||
if (USER_EN) begin : gen_dromajo_user
|
||||
dromajo_ram #(
|
||||
.ADDR_WIDTH($clog2(NUM_WORDS)),
|
||||
.DATA_DEPTH(NUM_WORDS),
|
||||
.OUT_REGS (0)
|
||||
) i_ram_user (
|
||||
.Clk_CI ( clk_i ),
|
||||
.Rst_RBI ( rst_ni ),
|
||||
.CSel_SI ( req_i ),
|
||||
.WrEn_SI ( we_i ),
|
||||
.BEn_SI ( be_aligned[k*8 +: 8] ),
|
||||
.WrData_DI ( wuser_aligned[k*64 +: 64] ),
|
||||
.Addr_DI ( addr_i ),
|
||||
.RdData_DO ( ruser_aligned[k*64 +: 64] )
|
||||
);
|
||||
end
|
||||
end else begin : gen_mem
|
||||
// unused byte-enable segments (8bits) are culled by the tool
|
||||
SyncSpRamBeNx64 #(
|
||||
|
@ -86,6 +112,25 @@ end
|
|||
.Addr_DI ( addr_i ),
|
||||
.RdData_DO ( rdata_aligned[k*64 +: 64] )
|
||||
);
|
||||
if (USER_EN) begin : gen_mem_user
|
||||
SyncSpRamBeNx64 #(
|
||||
.ADDR_WIDTH($clog2(NUM_WORDS)),
|
||||
.DATA_DEPTH(NUM_WORDS),
|
||||
.OUT_REGS (0),
|
||||
// this initializes the memory with 0es. adjust to taste...
|
||||
// 0: no init, 1: zero init, 2: random init, 3: deadbeef init
|
||||
.SIM_INIT (1)
|
||||
) i_ram_user (
|
||||
.Clk_CI ( clk_i ),
|
||||
.Rst_RBI ( rst_ni ),
|
||||
.CSel_SI ( req_i ),
|
||||
.WrEn_SI ( we_i ),
|
||||
.BEn_SI ( be_aligned[k*8 +: 8] ),
|
||||
.WrData_DI ( wuser_aligned[k*64 +: 64] ),
|
||||
.Addr_DI ( addr_i ),
|
||||
.RdData_DO ( ruser_aligned[k*64 +: 64] )
|
||||
);
|
||||
end
|
||||
end
|
||||
end
|
||||
endmodule : sram
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
|
||||
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
|
||||
) (
|
||||
|
@ -39,6 +40,7 @@ module axi_shim #(
|
|||
output logic rd_last_o,
|
||||
output logic rd_valid_o,
|
||||
output logic [63: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
|
||||
|
@ -46,6 +48,7 @@ module axi_shim #(
|
|||
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 [$clog2(AxiNumWords)-1:0] wr_blen_i, // axi convention: LEN-1
|
||||
input logic [1:0] wr_size_i,
|
||||
|
@ -91,6 +94,7 @@ module axi_shim #(
|
|||
assign axi_req_o.aw.atop = wr_atop_i;
|
||||
// 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];
|
||||
assign axi_req_o.w.strb = wr_be_i[wr_cnt_q];
|
||||
assign axi_req_o.w.last = wr_cnt_done;
|
||||
|
||||
|
@ -252,6 +256,7 @@ module axi_shim #(
|
|||
// return path
|
||||
assign axi_req_o.r_ready = rd_rdy_i;
|
||||
assign rd_data_o = axi_resp_i.r.data;
|
||||
assign rd_user_o = axi_resp_i.r.user;
|
||||
assign rd_last_o = axi_resp_i.r.last;
|
||||
assign rd_valid_o = axi_resp_i.r_valid;
|
||||
assign rd_id_o = axi_resp_i.r.id;
|
||||
|
|
|
@ -81,7 +81,9 @@ module cva6_icache import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
logic [ICACHE_TAG_WIDTH-1:0] cl_tag_d, cl_tag_q; // this is the cache tag
|
||||
logic [ICACHE_TAG_WIDTH-1:0] cl_tag_rdata [ICACHE_SET_ASSOC-1:0]; // these are the tags coming from the tagmem
|
||||
logic [ICACHE_LINE_WIDTH-1:0] cl_rdata [ICACHE_SET_ASSOC-1:0]; // these are the cachelines coming from the cache
|
||||
logic [ICACHE_USER_LINE_WIDTH-1:0] cl_ruser[ICACHE_SET_ASSOC-1:0]; // these are the cachelines coming from the user cache
|
||||
logic [ICACHE_SET_ASSOC-1:0][FETCH_WIDTH-1:0]cl_sel; // selected word from each cacheline
|
||||
logic [ICACHE_SET_ASSOC-1:0][FETCH_USER_WIDTH-1:0] cl_user; // selected word from each cacheline
|
||||
logic [ICACHE_SET_ASSOC-1:0] vld_req; // bit enable for valid regs
|
||||
logic vld_we; // valid bits write enable
|
||||
logic [ICACHE_SET_ASSOC-1:0] vld_wdata; // valid bits to write
|
||||
|
@ -389,6 +391,7 @@ end else begin : gen_piton_offset
|
|||
for (genvar i=0;i<ICACHE_SET_ASSOC;i++) begin : gen_tag_cmpsel
|
||||
assign cl_hit[i] = (cl_tag_rdata[i] == cl_tag_d) & vld_rdata[i];
|
||||
assign cl_sel[i] = cl_rdata[i][{cl_offset_q,3'b0} +: FETCH_WIDTH];
|
||||
assign cl_user[i] = cl_ruser[i][{cl_offset_q,3'b0} +: FETCH_USER_WIDTH];
|
||||
end
|
||||
|
||||
|
||||
|
@ -400,8 +403,15 @@ end else begin : gen_piton_offset
|
|||
.empty_o ( )
|
||||
);
|
||||
|
||||
assign dreq_o.data = (cmp_en_q) ? cl_sel[hit_idx] :
|
||||
mem_rtrn_i.data[{cl_offset_q,3'b0} +: FETCH_WIDTH];
|
||||
always_comb begin
|
||||
if (cmp_en_q) begin
|
||||
dreq_o.data = cl_sel[hit_idx];
|
||||
dreq_o.user = cl_user[hit_idx];
|
||||
end else begin
|
||||
dreq_o.data = mem_rtrn_i.data[{cl_offset_q,3'b0} +: FETCH_WIDTH];
|
||||
dreq_o.user = mem_rtrn_i.user[{cl_offset_q,3'b0} +: FETCH_USER_WIDTH];
|
||||
end
|
||||
end
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// memory arrays and regs
|
||||
|
@ -424,8 +434,10 @@ end else begin : gen_piton_offset
|
|||
.addr_i ( vld_addr ),
|
||||
// we can always use the saved tag here since it takes a
|
||||
// couple of cycle until we write to the cache upon a miss
|
||||
.wuser_i ( '0 ),
|
||||
.wdata_i ( {vld_wdata[i], cl_tag_q} ),
|
||||
.be_i ( '1 ),
|
||||
.ruser_o ( ),
|
||||
.rdata_o ( cl_tag_valid_rdata[i] )
|
||||
);
|
||||
|
||||
|
@ -434,7 +446,9 @@ end else begin : gen_piton_offset
|
|||
|
||||
// Data RAM
|
||||
sram #(
|
||||
.USER_WIDTH ( ICACHE_USER_LINE_WIDTH ),
|
||||
.DATA_WIDTH ( ICACHE_LINE_WIDTH ),
|
||||
.USER_EN ( ariane_pkg::FETCH_USER_EN ),
|
||||
.NUM_WORDS ( ICACHE_NUM_WORDS )
|
||||
) data_sram (
|
||||
.clk_i ( clk_i ),
|
||||
|
@ -442,8 +456,10 @@ end else begin : gen_piton_offset
|
|||
.req_i ( cl_req[i] ),
|
||||
.we_i ( cl_we ),
|
||||
.addr_i ( cl_index ),
|
||||
.wuser_i ( mem_rtrn_i.user ),
|
||||
.wdata_i ( mem_rtrn_i.data ),
|
||||
.be_i ( '1 ),
|
||||
.ruser_o ( cl_ruser[i] ),
|
||||
.rdata_o ( cl_rdata[i] )
|
||||
);
|
||||
end
|
||||
|
|
|
@ -118,6 +118,7 @@ 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) )
|
||||
) i_axi_shim (
|
||||
|
@ -134,12 +135,14 @@ module cva6_icache_axi_wrapper import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
.rd_last_o ( axi_rd_last ),
|
||||
.rd_valid_o ( axi_rd_valid ),
|
||||
.rd_data_o ( axi_rd_data ),
|
||||
.rd_user_o ( ),
|
||||
.rd_id_o ( axi_rd_id_out ),
|
||||
.rd_exokay_o ( axi_rd_exokay ),
|
||||
.wr_req_i ( '0 ),
|
||||
.wr_gnt_o ( ),
|
||||
.wr_addr_i ( '0 ),
|
||||
.wr_data_i ( '0 ),
|
||||
.wr_user_i ( '0 ),
|
||||
.wr_be_i ( '0 ),
|
||||
.wr_blen_i ( '0 ),
|
||||
.wr_size_i ( '0 ),
|
||||
|
|
|
@ -172,8 +172,10 @@ import std_cache_pkg::*;
|
|||
.rst_ni ( rst_ni ),
|
||||
.we_i ( we_ram ),
|
||||
.addr_i ( addr_ram[DCACHE_INDEX_WIDTH-1:DCACHE_BYTE_OFFSET] ),
|
||||
.wuser_i ( '0 ),
|
||||
.wdata_i ( wdata_ram.data ),
|
||||
.be_i ( be_ram.data ),
|
||||
.ruser_o ( ),
|
||||
.rdata_o ( rdata_ram[i].data ),
|
||||
.*
|
||||
);
|
||||
|
@ -186,8 +188,10 @@ import std_cache_pkg::*;
|
|||
.rst_ni ( rst_ni ),
|
||||
.we_i ( we_ram ),
|
||||
.addr_i ( addr_ram[DCACHE_INDEX_WIDTH-1:DCACHE_BYTE_OFFSET] ),
|
||||
.wuser_i ( '0 ),
|
||||
.wdata_i ( wdata_ram.tag ),
|
||||
.be_i ( be_ram.tag ),
|
||||
.ruser_o ( ),
|
||||
.rdata_o ( rdata_ram[i].tag ),
|
||||
.*
|
||||
);
|
||||
|
@ -211,6 +215,7 @@ import std_cache_pkg::*;
|
|||
end
|
||||
|
||||
sram #(
|
||||
.USER_WIDTH ( 1 ),
|
||||
.DATA_WIDTH ( 4*DCACHE_DIRTY_WIDTH ),
|
||||
.NUM_WORDS ( DCACHE_NUM_WORDS )
|
||||
) valid_dirty_sram (
|
||||
|
@ -219,8 +224,10 @@ import std_cache_pkg::*;
|
|||
.req_i ( |req_ram ),
|
||||
.we_i ( we_ram ),
|
||||
.addr_i ( addr_ram[DCACHE_INDEX_WIDTH-1:DCACHE_BYTE_OFFSET] ),
|
||||
.wuser_i ( '0 ),
|
||||
.wdata_i ( dirty_wdata ),
|
||||
.be_i ( be_ram.vldrty ),
|
||||
.ruser_o ( ),
|
||||
.rdata_o ( dirty_rdata )
|
||||
);
|
||||
|
||||
|
|
|
@ -68,7 +68,9 @@ module wt_axi_adapter import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
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 [AxiNumWords-1:0][AXI_USER_WIDTH-1:0] axi_wr_user;
|
||||
logic [63:0] axi_rd_data;
|
||||
logic [AXI_USER_WIDTH-1:0] axi_rd_user;
|
||||
logic [AxiNumWords-1:0][7:0] axi_wr_be;
|
||||
logic [5:0] axi_wr_atop;
|
||||
logic invalidate;
|
||||
|
@ -119,6 +121,8 @@ 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_user = dcache_data.user;
|
||||
axi_wr_addr = {{64-riscv::PLEN{1'b0}}, dcache_data.paddr};
|
||||
axi_wr_size = dcache_data.size[1:0];
|
||||
axi_wr_req = 1'b0;
|
||||
|
@ -134,11 +138,13 @@ module wt_axi_adapter import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
axi_rd_req = 1'b0;
|
||||
axi_rd_lock = '0;
|
||||
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
|
||||
|
@ -219,8 +225,10 @@ module wt_axi_adapter import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
// 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_atop = {axi_pkg::ATOP_ATOMICLOAD, axi_pkg::ATOP_LITTLE_END, axi_pkg::ATOP_CLR};
|
||||
end
|
||||
|
@ -363,7 +371,9 @@ 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;
|
||||
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;
|
||||
|
@ -374,6 +384,7 @@ module wt_axi_adapter import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
icache_rtrn_o.rtype = wt_cache_pkg::ICACHE_IFILL_ACK;
|
||||
icache_rtrn_o.tid = icache_rtrn_tid_q;
|
||||
icache_rtrn_o.data = icache_rd_shift_q;
|
||||
icache_rtrn_o.user = icache_rd_shift_user_q;
|
||||
icache_rtrn_vld_o = icache_rtrn_vld_q;
|
||||
|
||||
dcache_rtrn_o = '0;
|
||||
|
@ -381,34 +392,43 @@ module wt_axi_adapter import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
dcache_rtrn_o.inv = dcache_rtrn_inv_q;
|
||||
dcache_rtrn_o.tid = dcache_rtrn_tid_q;
|
||||
dcache_rtrn_o.data = dcache_rd_shift_q;
|
||||
dcache_rtrn_o.user = dcache_rd_shift_user_q;
|
||||
dcache_rtrn_vld_o = dcache_rtrn_vld_q;
|
||||
|
||||
// read shift registers
|
||||
icache_rd_shift_d = icache_rd_shift_q;
|
||||
icache_rd_shift_user_d = icache_rd_shift_user_q;
|
||||
dcache_rd_shift_d = dcache_rd_shift_q;
|
||||
dcache_rd_shift_user_d = dcache_rd_shift_user_q;
|
||||
icache_first_d = icache_first_q;
|
||||
dcache_first_d = dcache_first_q;
|
||||
|
||||
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]};
|
||||
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
|
||||
icache_rd_shift_d[0] = axi_rd_data;
|
||||
icache_rd_shift_user_d[0] = axi_rd_user;
|
||||
end
|
||||
end
|
||||
|
||||
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]};
|
||||
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
|
||||
dcache_rd_shift_d[0] = axi_rd_data;
|
||||
dcache_rd_shift_user_d[0] = axi_rd_user;
|
||||
end
|
||||
end else if (dcache_sc_rtrn) begin
|
||||
// encode lr/sc success
|
||||
dcache_rd_shift_d[0] = '0;
|
||||
dcache_rd_shift_user_d[0] = '0;
|
||||
dcache_rd_shift_d[0][amo_off_q*8] = (wr_exokay) ? '0 : 1'b1;
|
||||
dcache_rd_shift_user_d[0][amo_off_q*8] = (wr_exokay) ? '0 : 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -516,7 +536,9 @@ module wt_axi_adapter import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
icache_first_q <= 1'b1;
|
||||
dcache_first_q <= 1'b1;
|
||||
icache_rd_shift_q <= '0;
|
||||
icache_rd_shift_user_q <= '0;
|
||||
dcache_rd_shift_q <= '0;
|
||||
dcache_rd_shift_user_q <= '0;
|
||||
icache_rtrn_vld_q <= '0;
|
||||
dcache_rtrn_vld_q <= '0;
|
||||
icache_rtrn_tid_q <= '0;
|
||||
|
@ -529,7 +551,9 @@ module wt_axi_adapter import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
icache_first_q <= icache_first_d;
|
||||
dcache_first_q <= dcache_first_d;
|
||||
icache_rd_shift_q <= icache_rd_shift_d;
|
||||
icache_rd_shift_user_q <= icache_rd_shift_user_d;
|
||||
dcache_rd_shift_q <= dcache_rd_shift_d;
|
||||
dcache_rd_shift_user_q <= dcache_rd_shift_user_d;
|
||||
icache_rtrn_vld_q <= icache_rtrn_vld_d;
|
||||
dcache_rtrn_vld_q <= dcache_rtrn_vld_d;
|
||||
icache_rtrn_tid_q <= icache_rtrn_tid_d;
|
||||
|
@ -547,6 +571,7 @@ 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) )
|
||||
) i_axi_shim (
|
||||
|
@ -563,12 +588,14 @@ module wt_axi_adapter import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
.rd_last_o ( axi_rd_last ),
|
||||
.rd_valid_o ( axi_rd_valid ),
|
||||
.rd_data_o ( axi_rd_data ),
|
||||
.rd_user_o ( axi_rd_user ),
|
||||
.rd_id_o ( axi_rd_id_out ),
|
||||
.rd_exokay_o ( axi_rd_exokay ),
|
||||
.wr_req_i ( axi_wr_req ),
|
||||
.wr_gnt_o ( axi_wr_gnt ),
|
||||
.wr_addr_i ( axi_wr_addr ),
|
||||
.wr_data_i ( axi_wr_data ),
|
||||
.wr_user_i ( axi_wr_user ),
|
||||
.wr_be_i ( axi_wr_be ),
|
||||
.wr_blen_i ( axi_wr_blen ),
|
||||
.wr_size_i ( axi_wr_size ),
|
||||
|
|
|
@ -60,6 +60,7 @@ module wt_dcache import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
logic [DCACHE_CL_IDX_WIDTH-1:0] wr_cl_idx;
|
||||
logic [DCACHE_OFFSET_WIDTH-1:0] wr_cl_off;
|
||||
logic [DCACHE_LINE_WIDTH-1:0] wr_cl_data;
|
||||
logic [DCACHE_USER_LINE_WIDTH-1:0] wr_cl_user;
|
||||
logic [DCACHE_LINE_WIDTH/8-1:0] wr_cl_data_be;
|
||||
logic [DCACHE_SET_ASSOC-1:0] wr_vld_bits;
|
||||
logic [DCACHE_SET_ASSOC-1:0] wr_req;
|
||||
|
@ -68,6 +69,7 @@ module wt_dcache import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
logic [DCACHE_OFFSET_WIDTH-1:0] wr_off;
|
||||
riscv::xlen_t wr_data;
|
||||
logic [(riscv::XLEN/8)-1:0] wr_data_be;
|
||||
logic [DCACHE_USER_WIDTH-1:0] wr_user;
|
||||
|
||||
// miss unit <-> controllers/wbuffer
|
||||
logic [NumPorts-1:0] miss_req;
|
||||
|
@ -75,6 +77,7 @@ module wt_dcache import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
logic [NumPorts-1:0] miss_nc;
|
||||
logic [NumPorts-1:0] miss_we;
|
||||
logic [NumPorts-1:0][riscv::XLEN-1:0] miss_wdata;
|
||||
logic [NumPorts-1:0][DCACHE_USER_WIDTH-1:0] miss_wuser;
|
||||
logic [NumPorts-1:0][riscv::PLEN-1:0] miss_paddr;
|
||||
logic [NumPorts-1:0][DCACHE_SET_ASSOC-1:0] miss_vld_bits;
|
||||
logic [NumPorts-1:0][2:0] miss_size;
|
||||
|
@ -92,6 +95,7 @@ module wt_dcache import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
logic [NumPorts-1:0][DCACHE_CL_IDX_WIDTH-1:0] rd_idx;
|
||||
logic [NumPorts-1:0][DCACHE_OFFSET_WIDTH-1:0] rd_off;
|
||||
riscv::xlen_t rd_data;
|
||||
logic [DCACHE_USER_WIDTH-1:0] rd_user;
|
||||
logic [DCACHE_SET_ASSOC-1:0] rd_vld_bits;
|
||||
logic [DCACHE_SET_ASSOC-1:0] rd_hit_oh;
|
||||
|
||||
|
@ -129,6 +133,7 @@ module wt_dcache import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
.miss_nc_i ( miss_nc ),
|
||||
.miss_we_i ( miss_we ),
|
||||
.miss_wdata_i ( miss_wdata ),
|
||||
.miss_wuser_i ( miss_wuser ),
|
||||
.miss_paddr_i ( miss_paddr ),
|
||||
.miss_vld_bits_i ( miss_vld_bits ),
|
||||
.miss_size_i ( miss_size ),
|
||||
|
@ -147,6 +152,7 @@ module wt_dcache import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
.wr_cl_idx_o ( wr_cl_idx ),
|
||||
.wr_cl_off_o ( wr_cl_off ),
|
||||
.wr_cl_data_o ( wr_cl_data ),
|
||||
.wr_cl_user_o ( wr_cl_user ),
|
||||
.wr_cl_data_be_o ( wr_cl_data_be ),
|
||||
.wr_vld_bits_o ( wr_vld_bits ),
|
||||
// memory interface
|
||||
|
@ -181,6 +187,7 @@ module wt_dcache import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
.miss_ack_i ( miss_ack [k] ),
|
||||
.miss_we_o ( miss_we [k] ),
|
||||
.miss_wdata_o ( miss_wdata [k] ),
|
||||
.miss_wuser_o ( miss_wuser [k] ),
|
||||
.miss_vld_bits_o ( miss_vld_bits [k] ),
|
||||
.miss_paddr_o ( miss_paddr [k] ),
|
||||
.miss_nc_o ( miss_nc [k] ),
|
||||
|
@ -198,6 +205,7 @@ module wt_dcache import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
.rd_tag_only_o ( rd_tag_only [k] ),
|
||||
.rd_ack_i ( rd_ack [k] ),
|
||||
.rd_data_i ( rd_data ),
|
||||
.rd_user_i ( rd_user ),
|
||||
.rd_vld_bits_i ( rd_vld_bits ),
|
||||
.rd_hit_oh_i ( rd_hit_oh )
|
||||
);
|
||||
|
@ -227,6 +235,7 @@ module wt_dcache import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
.miss_ack_i ( miss_ack [2] ),
|
||||
.miss_we_o ( miss_we [2] ),
|
||||
.miss_wdata_o ( miss_wdata [2] ),
|
||||
.miss_wuser_o ( miss_wuser [2] ),
|
||||
.miss_vld_bits_o ( miss_vld_bits [2] ),
|
||||
.miss_paddr_o ( miss_paddr [2] ),
|
||||
.miss_nc_o ( miss_nc [2] ),
|
||||
|
@ -253,6 +262,7 @@ module wt_dcache import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
.wr_idx_o ( wr_idx ),
|
||||
.wr_off_o ( wr_off ),
|
||||
.wr_data_o ( wr_data ),
|
||||
.wr_user_o ( wr_user ),
|
||||
.wr_data_be_o ( wr_data_be ),
|
||||
// write buffer forwarding
|
||||
.wbuffer_data_o ( wbuffer_data ),
|
||||
|
@ -281,6 +291,7 @@ module wt_dcache import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
.rd_vld_bits_o ( rd_vld_bits ),
|
||||
.rd_hit_oh_o ( rd_hit_oh ),
|
||||
.rd_data_o ( rd_data ),
|
||||
.rd_user_o ( rd_user ),
|
||||
// cacheline write port
|
||||
.wr_cl_vld_i ( wr_cl_vld ),
|
||||
.wr_cl_nc_i ( wr_cl_nc ),
|
||||
|
@ -289,6 +300,7 @@ module wt_dcache import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
.wr_cl_idx_i ( wr_cl_idx ),
|
||||
.wr_cl_off_i ( wr_cl_off ),
|
||||
.wr_cl_data_i ( wr_cl_data ),
|
||||
.wr_cl_user_i ( wr_cl_user ),
|
||||
.wr_cl_data_be_i ( wr_cl_data_be ),
|
||||
.wr_vld_bits_i ( wr_vld_bits ),
|
||||
// single word write port
|
||||
|
@ -297,6 +309,7 @@ module wt_dcache import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
.wr_idx_i ( wr_idx ),
|
||||
.wr_off_i ( wr_off ),
|
||||
.wr_data_i ( wr_data ),
|
||||
.wr_user_i ( wr_user ),
|
||||
.wr_data_be_i ( wr_data_be ),
|
||||
// write buffer forwarding
|
||||
.wbuffer_data_i ( wbuffer_data )
|
||||
|
|
|
@ -28,6 +28,7 @@ module wt_dcache_ctrl import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
input logic miss_ack_i,
|
||||
output logic miss_we_o, // unused (set to 0)
|
||||
output riscv::xlen_t miss_wdata_o, // unused (set to 0)
|
||||
output logic [DCACHE_USER_WIDTH-1:0] miss_wuser_o, // unused (set to 0)
|
||||
output logic [DCACHE_SET_ASSOC-1:0] miss_vld_bits_o, // valid bits at the missed index
|
||||
output logic [riscv::PLEN-1:0] miss_paddr_o,
|
||||
output logic miss_nc_o, // request to I/O space
|
||||
|
@ -45,6 +46,7 @@ module wt_dcache_ctrl import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
output logic rd_tag_only_o, // set to zero here
|
||||
input logic rd_ack_i,
|
||||
input riscv::xlen_t rd_data_i,
|
||||
input logic [DCACHE_USER_WIDTH-1:0] rd_user_i,
|
||||
input logic [DCACHE_SET_ASSOC-1:0] rd_vld_bits_i,
|
||||
input logic [DCACHE_SET_ASSOC-1:0] rd_hit_oh_i
|
||||
);
|
||||
|
@ -75,6 +77,7 @@ module wt_dcache_ctrl import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
assign rd_off_o = address_off_d;
|
||||
|
||||
assign req_port_o.data_rdata = rd_data_i;
|
||||
assign req_port_o.data_ruser = rd_user_i;
|
||||
|
||||
// to miss unit
|
||||
assign miss_vld_bits_o = vld_data_q;
|
||||
|
@ -87,6 +90,7 @@ module wt_dcache_ctrl import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
|
||||
assign miss_we_o = '0;
|
||||
assign miss_wdata_o = '0;
|
||||
assign miss_wuser_o = '0;
|
||||
assign miss_id_o = RdTxId;
|
||||
assign rd_req_d = rd_req_o;
|
||||
assign rd_ack_d = rd_ack_i;
|
||||
|
|
|
@ -44,6 +44,7 @@ module wt_dcache_mem import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
output logic [DCACHE_SET_ASSOC-1:0] rd_vld_bits_o,
|
||||
output logic [DCACHE_SET_ASSOC-1:0] rd_hit_oh_o,
|
||||
output riscv::xlen_t rd_data_o,
|
||||
output logic [DCACHE_USER_WIDTH-1:0] rd_user_o,
|
||||
|
||||
// only available on port 0, uses address signals of port 0
|
||||
input logic wr_cl_vld_i,
|
||||
|
@ -53,6 +54,7 @@ module wt_dcache_mem import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
input logic [DCACHE_CL_IDX_WIDTH-1:0] wr_cl_idx_i,
|
||||
input logic [DCACHE_OFFSET_WIDTH-1:0] wr_cl_off_i,
|
||||
input logic [DCACHE_LINE_WIDTH-1:0] wr_cl_data_i,
|
||||
input logic [DCACHE_USER_LINE_WIDTH-1:0] wr_cl_user_i,
|
||||
input logic [DCACHE_LINE_WIDTH/8-1:0] wr_cl_data_be_i,
|
||||
input logic [DCACHE_SET_ASSOC-1:0] wr_vld_bits_i,
|
||||
|
||||
|
@ -62,6 +64,7 @@ module wt_dcache_mem import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
input logic [DCACHE_CL_IDX_WIDTH-1:0] wr_idx_i,
|
||||
input logic [DCACHE_OFFSET_WIDTH-1:0] wr_off_i,
|
||||
input riscv::xlen_t wr_data_i,
|
||||
input logic [DCACHE_USER_WIDTH-1:0] wr_user_i,
|
||||
input logic [(riscv::XLEN/8)-1:0] wr_data_be_i,
|
||||
|
||||
// forwarded wbuffer
|
||||
|
@ -75,9 +78,12 @@ module wt_dcache_mem import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
logic [DCACHE_CL_IDX_WIDTH-1:0] bank_idx_d, bank_idx_q;
|
||||
logic [DCACHE_OFFSET_WIDTH-1:0] bank_off_d, bank_off_q;
|
||||
|
||||
logic [DCACHE_NUM_BANKS-1:0][DCACHE_SET_ASSOC-1:0][riscv::XLEN-1:0] bank_wdata; //
|
||||
logic [DCACHE_NUM_BANKS-1:0][DCACHE_SET_ASSOC-1:0][riscv::XLEN-1:0] bank_rdata; //
|
||||
logic [DCACHE_SET_ASSOC-1:0][riscv::XLEN-1:0] rdata_cl; // selected word from each cacheline
|
||||
logic [DCACHE_NUM_BANKS-1:0][DCACHE_SET_ASSOC-1:0][riscv::XLEN-1:0] bank_wdata; //
|
||||
logic [DCACHE_NUM_BANKS-1:0][DCACHE_SET_ASSOC-1:0][riscv::XLEN-1:0] bank_rdata; //
|
||||
logic [DCACHE_SET_ASSOC-1:0][riscv::XLEN-1:0] rdata_cl; // selected word from each cacheline
|
||||
logic [DCACHE_NUM_BANKS-1:0][DCACHE_SET_ASSOC-1:0][DCACHE_USER_WIDTH-1:0] bank_wuser; //
|
||||
logic [DCACHE_NUM_BANKS-1:0][DCACHE_SET_ASSOC-1:0][DCACHE_USER_WIDTH-1:0] bank_ruser; //
|
||||
logic [DCACHE_SET_ASSOC-1:0][DCACHE_USER_WIDTH-1:0] ruser_cl; // selected word from each cacheline
|
||||
|
||||
logic [DCACHE_TAG_WIDTH-1:0] rd_tag;
|
||||
logic [DCACHE_SET_ASSOC-1:0] vld_req; // bit enable for valid regs
|
||||
|
@ -91,6 +97,7 @@ module wt_dcache_mem import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
logic [DCACHE_WBUF_DEPTH-1:0] wbuffer_hit_oh;
|
||||
logic [(riscv::XLEN/8)-1:0] wbuffer_be;
|
||||
riscv::xlen_t wbuffer_rdata, rdata;
|
||||
logic [DCACHE_USER_WIDTH-1:0] wbuffer_ruser, ruser;
|
||||
logic [riscv::PLEN-1:0] wbuffer_cmp_addr;
|
||||
|
||||
logic cmp_en_d, cmp_en_q;
|
||||
|
@ -114,9 +121,10 @@ module wt_dcache_mem import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
assign bank_be[k][j] = (wr_cl_we_i[j] & wr_cl_vld_i) ? wr_cl_data_be_i[k*(riscv::XLEN/8) +: (riscv::XLEN/8)] :
|
||||
(wr_req_i[j] & wr_ack_o) ? wr_data_be_i :
|
||||
'0;
|
||||
|
||||
assign bank_wdata[k][j] = (wr_cl_we_i[j] & wr_cl_vld_i) ? wr_cl_data_i[k*riscv::XLEN +: riscv::XLEN] :
|
||||
wr_data_i;
|
||||
assign bank_wuser[k][j] = (wr_cl_we_i[j] & wr_cl_vld_i) ? wr_cl_user_i[k*DCACHE_USER_WIDTH +: DCACHE_USER_WIDTH] :
|
||||
wr_user_i;
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -206,6 +214,7 @@ module wt_dcache_mem import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
assign rd_hit_oh_o[i] = (rd_tag == tag_rdata[i]) & rd_vld_bits_o[i] & cmp_en_q;
|
||||
// byte offset mux of ways >0
|
||||
assign rdata_cl[i] = bank_rdata[bank_off_q[DCACHE_OFFSET_WIDTH-1:riscv::XLEN_ALIGN_BYTES]][i];
|
||||
assign ruser_cl[i] = bank_ruser[bank_off_q[DCACHE_OFFSET_WIDTH-1:riscv::XLEN_ALIGN_BYTES]][i];
|
||||
end
|
||||
|
||||
for(genvar k=0; k<DCACHE_WBUF_DEPTH; k++) begin : gen_wbuffer_hit
|
||||
|
@ -229,22 +238,33 @@ module wt_dcache_mem import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
);
|
||||
|
||||
assign wbuffer_rdata = wbuffer_data_i[wbuffer_hit_idx].data;
|
||||
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_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];
|
||||
end else begin : gen_piton_off
|
||||
assign wr_cl_off = wr_cl_off_i[DCACHE_OFFSET_WIDTH-1:3];
|
||||
end
|
||||
|
||||
assign rdata = (wr_cl_vld_i) ? wr_cl_data_i[wr_cl_off*riscv::XLEN +: riscv::XLEN] :
|
||||
rdata_cl[rd_hit_idx];
|
||||
|
||||
always_comb begin
|
||||
if (wr_cl_vld_i) begin
|
||||
rdata = wr_cl_data_i[wr_cl_off*riscv::XLEN +: riscv::XLEN];
|
||||
ruser = wr_cl_user_i[wr_cl_off*DCACHE_USER_WIDTH +: DCACHE_USER_WIDTH];
|
||||
end else begin
|
||||
rdata = rdata_cl[rd_hit_idx];
|
||||
ruser = ruser_cl[rd_hit_idx];
|
||||
end
|
||||
end
|
||||
|
||||
// overlay bytes that hit in the write buffer
|
||||
for(genvar k=0; k<(riscv::XLEN/8); k++) begin : gen_rd_data
|
||||
assign rd_data_o[8*k +: 8] = (wbuffer_be[k]) ? wbuffer_rdata[8*k +: 8] : rdata[8*k +: 8];
|
||||
end
|
||||
for(genvar k=0; k<DCACHE_USER_WIDTH/8; k++) begin : gen_rd_user
|
||||
assign rd_user_o[8*k +: 8] = (wbuffer_be[k]) ? wbuffer_ruser[8*k +: 8] : ruser[8*k +: 8];
|
||||
end
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// memory arrays and regs
|
||||
|
@ -255,7 +275,9 @@ module wt_dcache_mem import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
for (genvar k = 0; k < DCACHE_NUM_BANKS; k++) begin : gen_data_banks
|
||||
// Data RAM
|
||||
sram #(
|
||||
.USER_WIDTH ( ariane_pkg::DCACHE_SET_ASSOC * DATA_USER_WIDTH ),
|
||||
.DATA_WIDTH ( ariane_pkg::DCACHE_SET_ASSOC * riscv::XLEN ),
|
||||
.USER_EN ( ariane_pkg::DATA_USER_EN ),
|
||||
.NUM_WORDS ( wt_cache_pkg::DCACHE_NUM_WORDS )
|
||||
) i_data_sram (
|
||||
.clk_i ( clk_i ),
|
||||
|
@ -263,8 +285,10 @@ module wt_dcache_mem import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
.req_i ( bank_req [k] ),
|
||||
.we_i ( bank_we [k] ),
|
||||
.addr_i ( bank_idx [k] ),
|
||||
.wuser_i ( bank_wuser [k] ),
|
||||
.wdata_i ( bank_wdata [k] ),
|
||||
.be_i ( bank_be [k] ),
|
||||
.ruser_o ( bank_ruser [k] ),
|
||||
.rdata_o ( bank_rdata [k] )
|
||||
);
|
||||
end
|
||||
|
@ -285,8 +309,10 @@ module wt_dcache_mem import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
.req_i ( vld_req[i] ),
|
||||
.we_i ( vld_we ),
|
||||
.addr_i ( vld_addr ),
|
||||
.wuser_i ( '0 ),
|
||||
.wdata_i ( {vld_wdata[i], wr_cl_tag_i} ),
|
||||
.be_i ( '1 ),
|
||||
.ruser_o ( ),
|
||||
.rdata_o ( vld_tag_rdata[i] )
|
||||
);
|
||||
end
|
||||
|
|
|
@ -38,6 +38,7 @@ module wt_dcache_missunit import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
input logic [NumPorts-1:0] miss_nc_i,
|
||||
input logic [NumPorts-1:0] miss_we_i,
|
||||
input logic [NumPorts-1:0][riscv::XLEN-1:0] miss_wdata_i,
|
||||
input logic [NumPorts-1:0][DCACHE_USER_WIDTH-1:0] miss_wuser_i,
|
||||
input logic [NumPorts-1:0][riscv::PLEN-1:0] miss_paddr_i,
|
||||
input logic [NumPorts-1:0][DCACHE_SET_ASSOC-1:0] miss_vld_bits_i,
|
||||
input logic [NumPorts-1:0][2:0] miss_size_i,
|
||||
|
@ -58,6 +59,7 @@ module wt_dcache_missunit import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
output logic [DCACHE_CL_IDX_WIDTH-1:0] wr_cl_idx_o,
|
||||
output logic [DCACHE_OFFSET_WIDTH-1:0] wr_cl_off_o,
|
||||
output logic [DCACHE_LINE_WIDTH-1:0] wr_cl_data_o,
|
||||
output logic [DCACHE_USER_LINE_WIDTH-1:0] wr_cl_user_o,
|
||||
output logic [DCACHE_LINE_WIDTH/8-1:0] wr_cl_data_be_o,
|
||||
output logic [DCACHE_SET_ASSOC-1:0] wr_vld_bits_o,
|
||||
// memory interface
|
||||
|
@ -97,6 +99,7 @@ module wt_dcache_missunit import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
logic amo_req_d, amo_req_q;
|
||||
logic [63:0] amo_rtrn_mux;
|
||||
riscv::xlen_t amo_data;
|
||||
logic [63:0] amo_user; //DCACHE USER ? DATA_USER_WIDTH
|
||||
logic [riscv::PLEN-1:0] tmp_paddr;
|
||||
logic [$clog2(NumPorts)-1:0] miss_port_idx;
|
||||
logic [DCACHE_CL_IDX_WIDTH-1:0] cnt_d, cnt_q;
|
||||
|
@ -201,9 +204,20 @@ module wt_dcache_missunit import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
///////////////////////////////////////////////////////
|
||||
|
||||
// if size = 32bit word, select appropriate offset, replicate for openpiton...
|
||||
assign amo_data = riscv::IS_XLEN64 ? (amo_req_i.size==2'b10) ? {amo_req_i.operand_b[0 +: 32],amo_req_i.operand_b[0 +: 32]} : amo_req_i.operand_b :
|
||||
amo_req_i.operand_b[0 +: 32];
|
||||
|
||||
always_comb begin
|
||||
if (riscv::IS_XLEN64) begin
|
||||
if (amo_req_i.size==2'b10) begin
|
||||
amo_data = {amo_req_i.operand_b[0 +: 32], amo_req_i.operand_b[0 +: 32]};
|
||||
amo_user = {amo_req_i.operand_b[0 +: 32], amo_req_i.operand_b[0 +: 32]};
|
||||
end else begin
|
||||
amo_data = amo_req_i.operand_b;
|
||||
amo_user = amo_req_i.operand_b;
|
||||
end
|
||||
end else begin
|
||||
amo_data = amo_req_i.operand_b[0 +: 32];
|
||||
amo_user = amo_req_i.operand_b[0 +: 32];
|
||||
end
|
||||
end
|
||||
|
||||
// note: openpiton returns a full cacheline!
|
||||
if (Axi64BitCompliant) begin : gen_axi_rtrn_mux
|
||||
|
@ -215,8 +229,8 @@ module wt_dcache_missunit import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
// always sign extend 32bit values
|
||||
assign amo_resp_o.result = (amo_req_i.size==2'b10) ? {{32{amo_rtrn_mux[amo_req_i.operand_a[2]*32 + 31]}},amo_rtrn_mux[amo_req_i.operand_a[2]*32 +: 32]} :
|
||||
amo_rtrn_mux ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
assign amo_req_d = amo_req_i.req;
|
||||
|
||||
|
@ -225,6 +239,7 @@ module wt_dcache_missunit import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
assign mem_data_o.nc = (amo_sel) ? 1'b1 : miss_nc_i[miss_port_idx];
|
||||
assign mem_data_o.way = (amo_sel) ? '0 : repl_way;
|
||||
assign mem_data_o.data = (amo_sel) ? amo_data : miss_wdata_i[miss_port_idx];
|
||||
assign mem_data_o.user = (amo_sel) ? amo_user : miss_wuser_i[miss_port_idx];
|
||||
assign mem_data_o.size = (amo_sel) ? amo_req_i.size : miss_size_i [miss_port_idx];
|
||||
assign mem_data_o.amo_op = (amo_sel) ? amo_req_i.amo_op : AMO_NONE;
|
||||
|
||||
|
@ -341,6 +356,7 @@ module wt_dcache_missunit import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
assign wr_cl_tag_o = mshr_q.paddr[DCACHE_TAG_WIDTH+DCACHE_INDEX_WIDTH-1:DCACHE_INDEX_WIDTH];
|
||||
assign wr_cl_off_o = mshr_q.paddr[DCACHE_OFFSET_WIDTH-1:0];
|
||||
assign wr_cl_data_o = mem_rtrn_i.data;
|
||||
assign wr_cl_user_o = mem_rtrn_i.user;
|
||||
assign wr_cl_data_be_o = (cl_write_en) ? '1 : '0;// we only write complete cachelines into the memory
|
||||
|
||||
// only non-NC responses write to the cache
|
||||
|
|
|
@ -67,6 +67,7 @@ module wt_dcache_wbuffer import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
output logic miss_req_o,
|
||||
output logic miss_we_o, // always 1 here
|
||||
output riscv::xlen_t miss_wdata_o,
|
||||
output logic [DCACHE_USER_WIDTH-1:0] miss_wuser_o,
|
||||
output logic [DCACHE_SET_ASSOC-1:0] miss_vld_bits_o, // unused here (set to 0)
|
||||
output logic miss_nc_o, // request to I/O space
|
||||
output logic [2:0] miss_size_o, //
|
||||
|
@ -94,6 +95,7 @@ module wt_dcache_wbuffer import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
output logic [DCACHE_OFFSET_WIDTH-1:0] wr_off_o,
|
||||
output riscv::xlen_t wr_data_o,
|
||||
output logic [(riscv::XLEN/8)-1:0] wr_data_be_o,
|
||||
output logic [DCACHE_USER_WIDTH-1:0] wr_user_o,
|
||||
// to forwarding logic and miss unit
|
||||
output wbuffer_t [DCACHE_WBUF_DEPTH-1:0] wbuffer_data_o,
|
||||
output logic [DCACHE_MAX_TX-1:0][riscv::PLEN-1:0] tx_paddr_o, // used to check for address collisions with read operations
|
||||
|
@ -139,7 +141,7 @@ module wt_dcache_wbuffer import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
logic is_ni;
|
||||
assign miss_tag = miss_paddr_o[ariane_pkg::DCACHE_INDEX_WIDTH+:ariane_pkg::DCACHE_TAG_WIDTH];
|
||||
assign is_nc_miss = !ariane_pkg::is_inside_cacheable_regions(ArianeCfg, {{64-DCACHE_TAG_WIDTH-DCACHE_INDEX_WIDTH{1'b0}}, miss_tag, {DCACHE_INDEX_WIDTH{1'b0}}});
|
||||
assign miss_nc_o = !cache_en_i || is_nc_miss;
|
||||
assign miss_nc_o = !cache_en_i || is_nc_miss;
|
||||
// Non-idempotent if request goes to NI region
|
||||
assign is_ni = ariane_pkg::is_inside_nonidempotent_regions(ArianeCfg, {{64-DCACHE_TAG_WIDTH-DCACHE_INDEX_WIDTH{1'b0}}, req_port_i.address_tag, {DCACHE_INDEX_WIDTH{1'b0}}});
|
||||
|
||||
|
@ -183,13 +185,15 @@ module wt_dcache_wbuffer import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
// note: openpiton can only handle aligned offsets + size, and hence
|
||||
// we have to split unaligned data into multiple transfers (see toSize64)
|
||||
// e.g. if we have the following valid bytes: 0011_1001 -> TX0: 0000_0001, TX1: 0000_1000, TX2: 0011_0000
|
||||
|
||||
|
||||
assign miss_size_o = riscv::IS_XLEN64 ? toSize64(bdirty[dirty_ptr]):
|
||||
toSize32(bdirty[dirty_ptr]);
|
||||
|
||||
// replicate transfers shorter than a dword
|
||||
assign miss_wdata_o = riscv::IS_XLEN64 ? repData64(wbuffer_dirty_mux.data, bdirty_off, miss_size_o[1:0]):
|
||||
repData32(wbuffer_dirty_mux.data, bdirty_off, miss_size_o[1:0]);
|
||||
assign miss_wuser_o = riscv::IS_XLEN64 ? repData64(wbuffer_dirty_mux.user, bdirty_off, miss_size_o[1:0]):
|
||||
repData32(wbuffer_dirty_mux.user, bdirty_off, miss_size_o[1:0]);
|
||||
|
||||
assign tx_be = riscv::IS_XLEN64 ? to_byte_enable8(bdirty_off, miss_size_o[1:0]):
|
||||
to_byte_enable4(bdirty_off, miss_size_o[1:0]);
|
||||
|
@ -291,6 +295,7 @@ module wt_dcache_wbuffer import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
assign wr_idx_o = wr_paddr[DCACHE_INDEX_WIDTH-1:DCACHE_OFFSET_WIDTH];
|
||||
assign wr_off_o = wr_paddr[DCACHE_OFFSET_WIDTH-1:0];
|
||||
assign wr_data_o = wbuffer_q[rtrn_ptr].data;
|
||||
assign wr_user_o = wbuffer_q[rtrn_ptr].user;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
|
@ -391,10 +396,11 @@ module wt_dcache_wbuffer import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
|
||||
assign req_port_o.data_rvalid = '0;
|
||||
assign req_port_o.data_rdata = '0;
|
||||
assign req_port_o.data_ruser = '0;
|
||||
|
||||
assign rd_hit_oh_d = rd_hit_oh_i;
|
||||
|
||||
logic ni_inside,ni_conflict;
|
||||
|
||||
logic ni_inside,ni_conflict;
|
||||
assign ni_inside = |ni_pending_q;
|
||||
assign ni_conflict = is_ni && ni_inside;
|
||||
assign not_ni_o = !ni_inside;
|
||||
|
@ -471,11 +477,14 @@ module wt_dcache_wbuffer import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
wbuffer_d[wr_ptr].wtag = {req_port_i.address_tag, req_port_i.address_index[DCACHE_INDEX_WIDTH-1:riscv::XLEN_ALIGN_BYTES]};
|
||||
|
||||
// mark bytes as dirty
|
||||
wbuffer_d[wr_ptr].user = '0;
|
||||
for (int k=0; k<(riscv::XLEN/8); k++) begin
|
||||
if (req_port_i.data_be[k]) begin
|
||||
wbuffer_d[wr_ptr].valid[k] = 1'b1;
|
||||
wbuffer_d[wr_ptr].dirty[k] = 1'b1;
|
||||
wbuffer_d[wr_ptr].data[k*8 +: 8] = req_port_i.data_wdata[k*8 +: 8];
|
||||
if (ariane_pkg::DATA_USER_EN)
|
||||
wbuffer_d[wr_ptr].user[k*8 +: 8] = req_port_i.data_wuser[k*8 +: 8];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -552,7 +561,7 @@ module wt_dcache_wbuffer import ariane_pkg::*; import wt_cache_pkg::*; #(
|
|||
else $fatal(1,"[l1 dcache wbuffer] req_port_i.kill_req should not be asserted");
|
||||
|
||||
for (genvar k=0; k<DCACHE_WBUF_DEPTH; k++) begin : gen_assert1
|
||||
for (genvar j=0; j<8; j++) begin : gen_assert2
|
||||
for (genvar j=0; j<(riscv::XLEN/8); j++) begin : gen_assert2
|
||||
byteStates: assert property (
|
||||
@(posedge clk_i) disable iff (!rst_ni) {wbuffer_q[k].valid[j], wbuffer_q[k].dirty[j], wbuffer_q[k].txblock[j]} inside {3'b000, 3'b110, 3'b101, 3'b111} )
|
||||
else $fatal(1,"[l1 dcache wbuffer] byte %02d of wbuffer entry %02d has invalid state: valid=%01b, dirty=%01b, txblock=%01b",
|
||||
|
|
|
@ -21,7 +21,7 @@ package ariane_axi;
|
|||
typedef enum logic { SINGLE_REQ, CACHE_LINE_REQ } ad_req_t;
|
||||
|
||||
localparam IdWidth = 4; // Recommended by AXI standard
|
||||
localparam UserWidth = 1;
|
||||
localparam UserWidth = ariane_pkg::AXI_USER_WIDTH;
|
||||
localparam AddrWidth = 64;
|
||||
localparam DataWidth = 64;
|
||||
localparam StrbWidth = DataWidth / 8;
|
||||
|
|
|
@ -163,7 +163,7 @@ package ariane_pkg;
|
|||
localparam bit RVD = riscv::IS_XLEN64; // Is D extension enabled
|
||||
`else
|
||||
// Floating-point extensions configuration
|
||||
localparam bit RVF = (riscv::IS_XLEN64 | riscv::IS_XLEN32) & riscv::FPU_EN; // Is F extension enabled for both 32 Bit and 64 bit CPU
|
||||
localparam bit RVF = (riscv::IS_XLEN64 | riscv::IS_XLEN32) & riscv::FPU_EN; // Is F extension enabled for both 32 Bit and 64 bit CPU
|
||||
localparam bit RVD = (riscv::IS_XLEN64 ? 1:0) & riscv::FPU_EN; // Is D extension enabled for only 64 bit CPU
|
||||
`endif
|
||||
localparam bit RVA = 1'b1; // Is A extension enabled
|
||||
|
@ -278,6 +278,18 @@ package ariane_pkg;
|
|||
| riscv::SSTATUS_FS
|
||||
| riscv::SSTATUS_SUM
|
||||
| riscv::SSTATUS_MXR;
|
||||
// ---------------
|
||||
// User bits
|
||||
// ---------------
|
||||
|
||||
localparam FETCH_USER_WIDTH = (cva6_config_pkg::CVA6ConfigFetchUserEn == 0) ? 1: cva6_config_pkg::CVA6ConfigFetchUserWidth; // Possible cases: between 1 and 64
|
||||
localparam DATA_USER_WIDTH = (cva6_config_pkg::CVA6ConfigDataUserEn == 0) ? 1: cva6_config_pkg::CVA6ConfigDataUserWidth; // Possible cases: between 1 and 64
|
||||
localparam AXI_USER_WIDTH = DATA_USER_WIDTH > FETCH_USER_WIDTH ? DATA_USER_WIDTH : FETCH_USER_WIDTH;
|
||||
localparam DATA_USER_EN = cva6_config_pkg::CVA6ConfigDataUserEn;
|
||||
localparam FETCH_USER_EN = cva6_config_pkg::CVA6ConfigFetchUserEn;
|
||||
localparam AXI_USER_EN = cva6_config_pkg::CVA6ConfigDataUserEn | cva6_config_pkg::CVA6ConfigFetchUserEn;
|
||||
|
||||
|
||||
// ---------------
|
||||
// Fetch Stage
|
||||
// ---------------
|
||||
|
@ -425,17 +437,20 @@ package ariane_pkg;
|
|||
localparam int unsigned DCACHE_TAG_WIDTH = riscv::PLEN - DCACHE_INDEX_WIDTH;
|
||||
`else
|
||||
// I$
|
||||
localparam int unsigned CONFIG_L1I_SIZE = 16*1024;
|
||||
localparam int unsigned CONFIG_L1I_SIZE = 16*1024;
|
||||
localparam int unsigned ICACHE_SET_ASSOC = 4; // Must be between 4 to 64
|
||||
localparam int unsigned ICACHE_INDEX_WIDTH = $clog2(CONFIG_L1I_SIZE / ICACHE_SET_ASSOC); // in bit, contains also offset width
|
||||
localparam int unsigned ICACHE_TAG_WIDTH = riscv::PLEN-ICACHE_INDEX_WIDTH; // in bit
|
||||
localparam int unsigned ICACHE_LINE_WIDTH = 128; // in bit
|
||||
localparam int unsigned ICACHE_USER_LINE_WIDTH = (AXI_USER_WIDTH == 1) ? 4 : 128; // in bit
|
||||
// D$
|
||||
localparam int unsigned CONFIG_L1D_SIZE = 32*1024;
|
||||
localparam int unsigned DCACHE_SET_ASSOC = 8; // Must be between 4 to 64
|
||||
localparam int unsigned CONFIG_L1D_SIZE = 32*1024;
|
||||
localparam int unsigned DCACHE_SET_ASSOC = 8; // Must be between 4 to 64
|
||||
localparam int unsigned DCACHE_INDEX_WIDTH = $clog2(CONFIG_L1D_SIZE / DCACHE_SET_ASSOC); // in bit, contains also offset width
|
||||
localparam int unsigned DCACHE_TAG_WIDTH = riscv::PLEN-DCACHE_INDEX_WIDTH; // in bit
|
||||
localparam int unsigned DCACHE_LINE_WIDTH = 128; // in bit
|
||||
localparam int unsigned DCACHE_USER_LINE_WIDTH = (AXI_USER_WIDTH == 1) ? 4 : 128; // in bit
|
||||
localparam int unsigned DCACHE_USER_WIDTH = DATA_USER_WIDTH;
|
||||
`endif
|
||||
|
||||
localparam bit CVXIF_PRESENT = cva6_config_pkg::CVA6ConfigCvxifEn;
|
||||
|
@ -572,7 +587,7 @@ package ariane_pkg;
|
|||
default: return 1'b0;
|
||||
endcase
|
||||
endfunction
|
||||
|
||||
|
||||
typedef struct packed {
|
||||
logic valid;
|
||||
logic [riscv::VLEN-1:0] vaddr;
|
||||
|
@ -701,6 +716,7 @@ package ariane_pkg;
|
|||
logic ready; // icache is ready
|
||||
logic valid; // signals a valid read
|
||||
logic [FETCH_WIDTH-1:0] data; // 2+ cycle out: tag
|
||||
logic [FETCH_USER_WIDTH-1:0] user; // User bits
|
||||
logic [riscv::VLEN-1:0] vaddr; // virtual address out
|
||||
exception_t ex; // we've encountered an exception
|
||||
} icache_dreq_o_t;
|
||||
|
@ -723,11 +739,12 @@ package ariane_pkg;
|
|||
logic [63:0] result; // sign-extended, result
|
||||
} amo_resp_t;
|
||||
|
||||
// D$ data requests
|
||||
// D$ data requests
|
||||
typedef struct packed {
|
||||
logic [DCACHE_INDEX_WIDTH-1:0] address_index;
|
||||
logic [DCACHE_TAG_WIDTH-1:0] address_tag;
|
||||
riscv::xlen_t data_wdata;
|
||||
logic [DCACHE_USER_WIDTH-1:0] data_wuser;
|
||||
logic data_req;
|
||||
logic data_we;
|
||||
logic [(riscv::XLEN/8)-1:0] data_be;
|
||||
|
@ -740,6 +757,7 @@ package ariane_pkg;
|
|||
logic data_gnt;
|
||||
logic data_rvalid;
|
||||
riscv::xlen_t data_rdata;
|
||||
logic [DCACHE_USER_WIDTH-1:0] data_ruser;
|
||||
} dcache_req_o_t;
|
||||
|
||||
// ----------------------
|
||||
|
@ -826,7 +844,7 @@ package ariane_pkg;
|
|||
endcase
|
||||
return 8'b0;
|
||||
endfunction
|
||||
|
||||
|
||||
function automatic logic [3:0] be_gen_32(logic [1:0] addr, logic [1:0] size);
|
||||
case (size)
|
||||
2'b10: begin
|
||||
|
|
|
@ -15,4 +15,9 @@ package cva6_config_pkg;
|
|||
localparam CVA6ConfigCvxifEn = 0;
|
||||
localparam CVA6ConfigCExtEn = 1;
|
||||
|
||||
localparam CVA6ConfigFetchUserEn = 0;
|
||||
localparam CVA6ConfigFetchUserWidth = CVA6ConfigXlen;
|
||||
localparam CVA6ConfigDataUserEn = 0;
|
||||
localparam CVA6ConfigDataUserWidth = CVA6ConfigXlen;
|
||||
|
||||
endpackage
|
||||
|
|
|
@ -15,4 +15,9 @@ package cva6_config_pkg;
|
|||
localparam CVA6ConfigCvxifEn = 0;
|
||||
localparam CVA6ConfigCExtEn = 1;
|
||||
|
||||
localparam CVA6ConfigFetchUserEn = 0;
|
||||
localparam CVA6ConfigFetchUserWidth = CVA6ConfigXlen;
|
||||
localparam CVA6ConfigDataUserEn = 0;
|
||||
localparam CVA6ConfigDataUserWidth = CVA6ConfigXlen;
|
||||
|
||||
endpackage
|
||||
|
|
|
@ -15,4 +15,9 @@ package cva6_config_pkg;
|
|||
localparam CVA6ConfigCvxifEn = 0;
|
||||
localparam CVA6ConfigCExtEn = 1;
|
||||
|
||||
localparam CVA6ConfigFetchUserEn = 0;
|
||||
localparam CVA6ConfigFetchUserWidth = CVA6ConfigXlen;
|
||||
localparam CVA6ConfigDataUserEn = 0;
|
||||
localparam CVA6ConfigDataUserWidth = CVA6ConfigXlen;
|
||||
|
||||
endpackage
|
||||
|
|
|
@ -15,4 +15,9 @@ package cva6_config_pkg;
|
|||
localparam CVA6ConfigCvxifEn = 1;
|
||||
localparam CVA6ConfigCExtEn = 1;
|
||||
|
||||
localparam CVA6ConfigFetchUserEn = 0;
|
||||
localparam CVA6ConfigFetchUserWidth = CVA6ConfigXlen;
|
||||
localparam CVA6ConfigDataUserEn = 0;
|
||||
localparam CVA6ConfigDataUserWidth = CVA6ConfigXlen;
|
||||
|
||||
endpackage
|
||||
|
|
|
@ -77,6 +77,7 @@ package wt_cache_pkg;
|
|||
typedef struct packed {
|
||||
logic [ariane_pkg::DCACHE_TAG_WIDTH+(ariane_pkg::DCACHE_INDEX_WIDTH-riscv::XLEN_ALIGN_BYTES)-1:0] wtag;
|
||||
riscv::xlen_t data;
|
||||
logic [ariane_pkg::DCACHE_USER_WIDTH-1:0] user;
|
||||
logic [(riscv::XLEN/8)-1:0] dirty; // byte is dirty
|
||||
logic [(riscv::XLEN/8)-1:0] valid; // byte is valid
|
||||
logic [(riscv::XLEN/8)-1:0] txblock; // byte is part of transaction in-flight
|
||||
|
@ -87,7 +88,7 @@ package wt_cache_pkg;
|
|||
// TX status registers are indexed with the transaction ID
|
||||
// they basically store which bytes from which buffer entry are part
|
||||
// of that transaction
|
||||
|
||||
|
||||
typedef struct packed {
|
||||
logic vld;
|
||||
logic [(riscv::XLEN/8)-1:0] be;
|
||||
|
@ -133,6 +134,7 @@ package wt_cache_pkg;
|
|||
typedef struct packed {
|
||||
icache_in_t rtype; // see definitions above
|
||||
logic [ariane_pkg::ICACHE_LINE_WIDTH-1:0] data; // full cache line width
|
||||
logic [ariane_pkg::ICACHE_USER_LINE_WIDTH-1:0] user; // user bits
|
||||
icache_inval_t inv; // invalidation vector
|
||||
logic [CACHE_ID_WIDTH-1:0] tid; // threadi id (used as transaction id in Ariane)
|
||||
} icache_rtrn_t;
|
||||
|
@ -151,6 +153,7 @@ package wt_cache_pkg;
|
|||
logic [L1D_WAY_WIDTH-1:0] way; // way to replace
|
||||
logic [riscv::PLEN-1:0] paddr; // physical address
|
||||
riscv::xlen_t data; // word width of processor (no block stores at the moment)
|
||||
logic [ariane_pkg::DATA_USER_WIDTH-1:0] user; // user width of processor (no block stores at the moment)
|
||||
logic nc; // noncacheable
|
||||
logic [CACHE_ID_WIDTH-1:0] tid; // threadi id (used as transaction id in Ariane)
|
||||
ariane_pkg::amo_t amo_op; // amo opcode
|
||||
|
@ -159,6 +162,7 @@ package wt_cache_pkg;
|
|||
typedef struct packed {
|
||||
dcache_in_t rtype; // see definitions above
|
||||
logic [ariane_pkg::DCACHE_LINE_WIDTH-1:0] data; // full cache line width
|
||||
logic [ariane_pkg::DCACHE_USER_LINE_WIDTH-1:0] user; // user bits
|
||||
dcache_inval_t inv; // invalidation vector
|
||||
logic [CACHE_ID_WIDTH-1:0] tid; // threadi id (used as transaction id in Ariane)
|
||||
} dcache_rtrn_t;
|
||||
|
@ -311,7 +315,7 @@ package wt_cache_pkg;
|
|||
endcase // size
|
||||
return be;
|
||||
endfunction : to_byte_enable8
|
||||
|
||||
|
||||
function automatic logic [3:0] to_byte_enable4(
|
||||
input logic [1:0] offset,
|
||||
input logic [1:0] size
|
||||
|
@ -341,7 +345,7 @@ package wt_cache_pkg;
|
|||
endcase // size
|
||||
return out;
|
||||
endfunction : repData64
|
||||
|
||||
|
||||
function automatic logic [31:0] repData32(
|
||||
input logic [31:0] data,
|
||||
input logic [1:0] offset,
|
||||
|
@ -371,8 +375,8 @@ package wt_cache_pkg;
|
|||
endcase // be
|
||||
return size;
|
||||
endfunction : toSize64
|
||||
|
||||
|
||||
|
||||
|
||||
function automatic logic [1:0] toSize32(
|
||||
input logic [3:0] be
|
||||
);
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 4650ca9006d3ed7dddb3078af150467087823c19
|
||||
Subproject commit b494701501886ad71ba0c128560cc371610bcf1a
|
|
@ -159,7 +159,7 @@ localparam AxiAddrWidth = 64;
|
|||
localparam AxiDataWidth = 64;
|
||||
localparam AxiIdWidthMaster = 4;
|
||||
localparam AxiIdWidthSlaves = AxiIdWidthMaster + $clog2(NBSlave); // 5
|
||||
localparam AxiUserWidth = 1;
|
||||
localparam AxiUserWidth = ariane_pkg::AXI_USER_WIDTH;
|
||||
|
||||
`AXI_TYPEDEF_ALL(axi_slave,
|
||||
logic [ AxiAddrWidth-1:0],
|
||||
|
|
|
@ -20,7 +20,7 @@ package ariane_axi_soc;
|
|||
// used in axi_adapter.sv
|
||||
typedef enum logic { SINGLE_REQ, CACHE_LINE_REQ } ad_req_t;
|
||||
|
||||
localparam UserWidth = 1;
|
||||
localparam UserWidth = ariane_pkg::AXI_USER_WIDTH;
|
||||
localparam AddrWidth = 64;
|
||||
localparam DataWidth = 64;
|
||||
localparam StrbWidth = DataWidth / 8;
|
||||
|
|
|
@ -169,7 +169,7 @@ int main(int argc, char **argv) {
|
|||
case 'V': verbose = true; break;
|
||||
case 'p': perf = true; break;
|
||||
#ifdef DROMAJO
|
||||
case 'D': break;
|
||||
case 'D': break;
|
||||
#endif
|
||||
#if VM_TRACE
|
||||
case 'v': {
|
||||
|
@ -321,6 +321,7 @@ done_processing:
|
|||
// Preload memory.
|
||||
size_t mem_size = 0xFFFFFF;
|
||||
memif.read(0x80000000, mem_size, (void *)top->ariane_testharness__DOT__i_sram__DOT__gen_cut__BRA__0__KET____DOT__gen_mem__DOT__i_ram__DOT__Mem_DP);
|
||||
// memif.read(0x84000000, mem_size, (void *)top->ariane_testharness__DOT__i_sram__DOT__gen_cut__BRA__0__KET____DOT__gen_mem__DOT__gen_mem_user__DOT__i_ram_user__DOT__Mem_DP);
|
||||
|
||||
#ifndef DROMAJO
|
||||
while (!dtm->done() && !jtag->done()) {
|
||||
|
|
|
@ -20,6 +20,7 @@ import uvm_pkg::*;
|
|||
`include "uvm_macros.svh"
|
||||
|
||||
`define MAIN_MEM(P) dut.i_sram.gen_cut[0].gen_mem.i_ram.Mem_DP[(``P``)]
|
||||
// `define USER_MEM(P) dut.i_sram.gen_user_cut[0].gen_user_mem.i_ram_user.Mem_DP[(``P``)]
|
||||
|
||||
import "DPI-C" function read_elf(input string filename);
|
||||
import "DPI-C" function byte get_section(output longint address, output longint len);
|
||||
|
@ -146,7 +147,7 @@ UVM_LOW)
|
|||
for (int j = 0; j < 8; j++) begin
|
||||
mem_row[j] = buffer[i*8 + j];
|
||||
end
|
||||
`MAIN_MEM((address[28:0] >> 3) + i) = mem_row;
|
||||
`MAIN_MEM((address[23:0] >> 3) + i) = mem_row;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
`include "axi/assign.svh"
|
||||
|
||||
module ariane_testharness #(
|
||||
parameter int unsigned AXI_USER_WIDTH = 1,
|
||||
parameter int unsigned AXI_USER_WIDTH = ariane_pkg::AXI_USER_WIDTH,
|
||||
parameter int unsigned AXI_USER_EN = ariane_pkg::AXI_USER_EN,
|
||||
parameter int unsigned AXI_ADDRESS_WIDTH = 64,
|
||||
parameter int unsigned AXI_DATA_WIDTH = 64,
|
||||
`ifdef DROMAJO
|
||||
|
@ -272,7 +273,9 @@ module ariane_testharness #(
|
|||
.we_o ( dm_slave_we ),
|
||||
.addr_o ( dm_slave_addr ),
|
||||
.be_o ( dm_slave_be ),
|
||||
.user_o ( ),
|
||||
.data_o ( dm_slave_wdata ),
|
||||
.user_i ( '0 ),
|
||||
.data_i ( dm_slave_rdata )
|
||||
);
|
||||
|
||||
|
@ -325,7 +328,9 @@ module ariane_testharness #(
|
|||
.we_o ( ),
|
||||
.addr_o ( rom_addr ),
|
||||
.be_o ( ),
|
||||
.user_o ( ),
|
||||
.data_o ( ),
|
||||
.user_i ( '0 ),
|
||||
.data_i ( rom_rdata )
|
||||
);
|
||||
|
||||
|
@ -384,6 +389,8 @@ module ariane_testharness #(
|
|||
logic [AXI_DATA_WIDTH/8-1:0] be;
|
||||
logic [AXI_DATA_WIDTH-1:0] wdata;
|
||||
logic [AXI_DATA_WIDTH-1:0] rdata;
|
||||
logic [AXI_USER_WIDTH-1:0] wuser;
|
||||
logic [AXI_USER_WIDTH-1:0] ruser;
|
||||
|
||||
axi_riscv_atomics_wrap #(
|
||||
.AXI_ADDR_WIDTH ( AXI_ADDRESS_WIDTH ),
|
||||
|
@ -435,12 +442,16 @@ module ariane_testharness #(
|
|||
.we_o ( we ),
|
||||
.addr_o ( addr ),
|
||||
.be_o ( be ),
|
||||
.user_o ( wuser ),
|
||||
.data_o ( wdata ),
|
||||
.user_i ( ruser ),
|
||||
.data_i ( rdata )
|
||||
);
|
||||
|
||||
sram #(
|
||||
.DATA_WIDTH ( AXI_DATA_WIDTH ),
|
||||
.USER_WIDTH ( AXI_USER_WIDTH ),
|
||||
.USER_EN ( AXI_USER_EN ),
|
||||
`ifdef DROMAJO
|
||||
.DROMAJO_RAM (1),
|
||||
`endif
|
||||
|
@ -451,8 +462,10 @@ module ariane_testharness #(
|
|||
.req_i ( req ),
|
||||
.we_i ( we ),
|
||||
.addr_i ( addr[$clog2(NUM_WORDS)-1+$clog2(AXI_DATA_WIDTH/8):$clog2(AXI_DATA_WIDTH/8)] ),
|
||||
.wuser_i ( wuser ),
|
||||
.wdata_i ( wdata ),
|
||||
.be_i ( be ),
|
||||
.ruser_o ( ruser ),
|
||||
.rdata_o ( rdata )
|
||||
);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue