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:
JeanRochCoulon 2022-04-20 12:47:07 +02:00 committed by GitHub
parent 0b61544da8
commit 56f8c9f5fe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 269 additions and 41 deletions

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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 ),

View file

@ -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 )
);

View file

@ -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;
@ -137,8 +141,10 @@ module wt_axi_adapter import ariane_pkg::*; import wt_cache_pkg::*; #(
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 ),

View file

@ -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 )

View file

@ -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;

View file

@ -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,6 +238,7 @@ 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
@ -238,13 +248,23 @@ module wt_dcache_mem import ariane_pkg::*; import wt_cache_pkg::*; #(
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

View file

@ -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
@ -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

View file

@ -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
@ -190,6 +192,8 @@ module wt_dcache_wbuffer import ariane_pkg::*; import wt_cache_pkg::*; #(
// 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,6 +396,7 @@ 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;
@ -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",

View file

@ -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;

View file

@ -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;
@ -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;
@ -728,6 +744,7 @@ package ariane_pkg;
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;
// ----------------------

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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
@ -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;

@ -1 +1 @@
Subproject commit 4650ca9006d3ed7dddb3078af150467087823c19
Subproject commit b494701501886ad71ba0c128560cc371610bcf1a

View file

@ -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],

View file

@ -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;

View file

@ -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()) {

View file

@ -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

View file

@ -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 )
);