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
|
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
|
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 update
|
||||||
sudo apt install verilator-4.100 device-tree-compiler
|
sudo apt install verilator-4.110 device-tree-compiler
|
||||||
|
|
||||||
ci/make-tmp.sh
|
ci/make-tmp.sh
|
||||||
sudo mkdir -p $RISCV && sudo chmod 777 $RISCV
|
sudo mkdir -p $RISCV && sudo chmod 777 $RISCV
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
|
|
||||||
module sram #(
|
module sram #(
|
||||||
parameter DATA_WIDTH = 64,
|
parameter DATA_WIDTH = 64,
|
||||||
|
parameter USER_WIDTH = 1,
|
||||||
|
parameter USER_EN = 0,
|
||||||
parameter NUM_WORDS = 1024,
|
parameter NUM_WORDS = 1024,
|
||||||
parameter OUT_REGS = 0, // enables output registers in FPGA macro (read lat = 2)
|
parameter OUT_REGS = 0, // enables output registers in FPGA macro (read lat = 2)
|
||||||
parameter DROMAJO_RAM = 0
|
parameter DROMAJO_RAM = 0
|
||||||
|
@ -29,26 +31,34 @@ module sram #(
|
||||||
input logic req_i,
|
input logic req_i,
|
||||||
input logic we_i,
|
input logic we_i,
|
||||||
input logic [$clog2(NUM_WORDS)-1:0] addr_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-1:0] wdata_i,
|
||||||
input logic [(DATA_WIDTH+7)/8-1:0] be_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
|
output logic [DATA_WIDTH-1:0] rdata_o
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam DATA_WIDTH_ALIGNED = ((DATA_WIDTH+63)/64)*64;
|
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;
|
localparam BE_WIDTH_ALIGNED = (((DATA_WIDTH+7)/8+7)/8)*8;
|
||||||
|
|
||||||
logic [DATA_WIDTH_ALIGNED-1:0] wdata_aligned;
|
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 [BE_WIDTH_ALIGNED-1:0] be_aligned;
|
||||||
logic [DATA_WIDTH_ALIGNED-1:0] rdata_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
|
// align to 64 bits for inferrable macro below
|
||||||
always_comb begin : p_align
|
always_comb begin : p_align
|
||||||
wdata_aligned ='0;
|
wdata_aligned ='0;
|
||||||
|
wuser_aligned ='0;
|
||||||
be_aligned ='0;
|
be_aligned ='0;
|
||||||
wdata_aligned[DATA_WIDTH-1:0] = wdata_i;
|
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;
|
be_aligned[BE_WIDTH_ALIGNED-1:0] = be_i;
|
||||||
|
|
||||||
rdata_o = rdata_aligned[DATA_WIDTH-1:0];
|
rdata_o = rdata_aligned[DATA_WIDTH-1:0];
|
||||||
|
ruser_o = ruser_aligned[USER_WIDTH-1:0];
|
||||||
end
|
end
|
||||||
|
|
||||||
for (genvar k = 0; k<(DATA_WIDTH+63)/64; k++) begin : gen_cut
|
for (genvar k = 0; k<(DATA_WIDTH+63)/64; k++) begin : gen_cut
|
||||||
|
@ -67,6 +77,22 @@ end
|
||||||
.Addr_DI ( addr_i ),
|
.Addr_DI ( addr_i ),
|
||||||
.RdData_DO ( rdata_aligned[k*64 +: 64] )
|
.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
|
end else begin : gen_mem
|
||||||
// unused byte-enable segments (8bits) are culled by the tool
|
// unused byte-enable segments (8bits) are culled by the tool
|
||||||
SyncSpRamBeNx64 #(
|
SyncSpRamBeNx64 #(
|
||||||
|
@ -86,6 +112,25 @@ end
|
||||||
.Addr_DI ( addr_i ),
|
.Addr_DI ( addr_i ),
|
||||||
.RdData_DO ( rdata_aligned[k*64 +: 64] )
|
.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
|
||||||
end
|
end
|
||||||
endmodule : sram
|
endmodule : sram
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
|
|
||||||
module axi_shim #(
|
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 AxiNumWords = 4, // data width in dwords, this is also the maximum burst length, must be >=2
|
||||||
parameter int unsigned AxiIdWidth = 4 // stick to the spec
|
parameter int unsigned AxiIdWidth = 4 // stick to the spec
|
||||||
) (
|
) (
|
||||||
|
@ -39,6 +40,7 @@ module axi_shim #(
|
||||||
output logic rd_last_o,
|
output logic rd_last_o,
|
||||||
output logic rd_valid_o,
|
output logic rd_valid_o,
|
||||||
output logic [63:0] rd_data_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 [AxiIdWidth-1:0] rd_id_o,
|
||||||
output logic rd_exokay_o, // indicates whether exclusive tx succeeded
|
output logic rd_exokay_o, // indicates whether exclusive tx succeeded
|
||||||
// write channel
|
// write channel
|
||||||
|
@ -46,6 +48,7 @@ module axi_shim #(
|
||||||
output logic wr_gnt_o,
|
output logic wr_gnt_o,
|
||||||
input logic [63:0] wr_addr_i,
|
input logic [63:0] wr_addr_i,
|
||||||
input logic [AxiNumWords-1:0][63:0] wr_data_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 [AxiNumWords-1:0][7:0] wr_be_i,
|
||||||
input logic [$clog2(AxiNumWords)-1:0] wr_blen_i, // axi convention: LEN-1
|
input logic [$clog2(AxiNumWords)-1:0] wr_blen_i, // axi convention: LEN-1
|
||||||
input logic [1:0] wr_size_i,
|
input logic [1:0] wr_size_i,
|
||||||
|
@ -91,6 +94,7 @@ module axi_shim #(
|
||||||
assign axi_req_o.aw.atop = wr_atop_i;
|
assign axi_req_o.aw.atop = wr_atop_i;
|
||||||
// data
|
// data
|
||||||
assign axi_req_o.w.data = wr_data_i[wr_cnt_q];
|
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.strb = wr_be_i[wr_cnt_q];
|
||||||
assign axi_req_o.w.last = wr_cnt_done;
|
assign axi_req_o.w.last = wr_cnt_done;
|
||||||
|
|
||||||
|
@ -252,6 +256,7 @@ module axi_shim #(
|
||||||
// return path
|
// return path
|
||||||
assign axi_req_o.r_ready = rd_rdy_i;
|
assign axi_req_o.r_ready = rd_rdy_i;
|
||||||
assign rd_data_o = axi_resp_i.r.data;
|
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_last_o = axi_resp_i.r.last;
|
||||||
assign rd_valid_o = axi_resp_i.r_valid;
|
assign rd_valid_o = axi_resp_i.r_valid;
|
||||||
assign rd_id_o = axi_resp_i.r.id;
|
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_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_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_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_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 [ICACHE_SET_ASSOC-1:0] vld_req; // bit enable for valid regs
|
||||||
logic vld_we; // valid bits write enable
|
logic vld_we; // valid bits write enable
|
||||||
logic [ICACHE_SET_ASSOC-1:0] vld_wdata; // valid bits to write
|
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
|
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_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_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
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -400,8 +403,15 @@ end else begin : gen_piton_offset
|
||||||
.empty_o ( )
|
.empty_o ( )
|
||||||
);
|
);
|
||||||
|
|
||||||
assign dreq_o.data = (cmp_en_q) ? cl_sel[hit_idx] :
|
always_comb begin
|
||||||
mem_rtrn_i.data[{cl_offset_q,3'b0} +: FETCH_WIDTH];
|
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
|
// memory arrays and regs
|
||||||
|
@ -424,8 +434,10 @@ end else begin : gen_piton_offset
|
||||||
.addr_i ( vld_addr ),
|
.addr_i ( vld_addr ),
|
||||||
// we can always use the saved tag here since it takes a
|
// we can always use the saved tag here since it takes a
|
||||||
// couple of cycle until we write to the cache upon a miss
|
// couple of cycle until we write to the cache upon a miss
|
||||||
|
.wuser_i ( '0 ),
|
||||||
.wdata_i ( {vld_wdata[i], cl_tag_q} ),
|
.wdata_i ( {vld_wdata[i], cl_tag_q} ),
|
||||||
.be_i ( '1 ),
|
.be_i ( '1 ),
|
||||||
|
.ruser_o ( ),
|
||||||
.rdata_o ( cl_tag_valid_rdata[i] )
|
.rdata_o ( cl_tag_valid_rdata[i] )
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -434,7 +446,9 @@ end else begin : gen_piton_offset
|
||||||
|
|
||||||
// Data RAM
|
// Data RAM
|
||||||
sram #(
|
sram #(
|
||||||
|
.USER_WIDTH ( ICACHE_USER_LINE_WIDTH ),
|
||||||
.DATA_WIDTH ( ICACHE_LINE_WIDTH ),
|
.DATA_WIDTH ( ICACHE_LINE_WIDTH ),
|
||||||
|
.USER_EN ( ariane_pkg::FETCH_USER_EN ),
|
||||||
.NUM_WORDS ( ICACHE_NUM_WORDS )
|
.NUM_WORDS ( ICACHE_NUM_WORDS )
|
||||||
) data_sram (
|
) data_sram (
|
||||||
.clk_i ( clk_i ),
|
.clk_i ( clk_i ),
|
||||||
|
@ -442,8 +456,10 @@ end else begin : gen_piton_offset
|
||||||
.req_i ( cl_req[i] ),
|
.req_i ( cl_req[i] ),
|
||||||
.we_i ( cl_we ),
|
.we_i ( cl_we ),
|
||||||
.addr_i ( cl_index ),
|
.addr_i ( cl_index ),
|
||||||
|
.wuser_i ( mem_rtrn_i.user ),
|
||||||
.wdata_i ( mem_rtrn_i.data ),
|
.wdata_i ( mem_rtrn_i.data ),
|
||||||
.be_i ( '1 ),
|
.be_i ( '1 ),
|
||||||
|
.ruser_o ( cl_ruser[i] ),
|
||||||
.rdata_o ( cl_rdata[i] )
|
.rdata_o ( cl_rdata[i] )
|
||||||
);
|
);
|
||||||
end
|
end
|
||||||
|
|
|
@ -118,6 +118,7 @@ module cva6_icache_axi_wrapper import ariane_pkg::*; import wt_cache_pkg::*; #(
|
||||||
// AXI shim
|
// AXI shim
|
||||||
// --------
|
// --------
|
||||||
axi_shim #(
|
axi_shim #(
|
||||||
|
.AxiUserWidth ( AXI_USER_WIDTH ),
|
||||||
.AxiNumWords ( AxiNumWords ),
|
.AxiNumWords ( AxiNumWords ),
|
||||||
.AxiIdWidth ( $size(axi_resp_i.r.id) )
|
.AxiIdWidth ( $size(axi_resp_i.r.id) )
|
||||||
) i_axi_shim (
|
) 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_last_o ( axi_rd_last ),
|
||||||
.rd_valid_o ( axi_rd_valid ),
|
.rd_valid_o ( axi_rd_valid ),
|
||||||
.rd_data_o ( axi_rd_data ),
|
.rd_data_o ( axi_rd_data ),
|
||||||
|
.rd_user_o ( ),
|
||||||
.rd_id_o ( axi_rd_id_out ),
|
.rd_id_o ( axi_rd_id_out ),
|
||||||
.rd_exokay_o ( axi_rd_exokay ),
|
.rd_exokay_o ( axi_rd_exokay ),
|
||||||
.wr_req_i ( '0 ),
|
.wr_req_i ( '0 ),
|
||||||
.wr_gnt_o ( ),
|
.wr_gnt_o ( ),
|
||||||
.wr_addr_i ( '0 ),
|
.wr_addr_i ( '0 ),
|
||||||
.wr_data_i ( '0 ),
|
.wr_data_i ( '0 ),
|
||||||
|
.wr_user_i ( '0 ),
|
||||||
.wr_be_i ( '0 ),
|
.wr_be_i ( '0 ),
|
||||||
.wr_blen_i ( '0 ),
|
.wr_blen_i ( '0 ),
|
||||||
.wr_size_i ( '0 ),
|
.wr_size_i ( '0 ),
|
||||||
|
|
|
@ -172,8 +172,10 @@ import std_cache_pkg::*;
|
||||||
.rst_ni ( rst_ni ),
|
.rst_ni ( rst_ni ),
|
||||||
.we_i ( we_ram ),
|
.we_i ( we_ram ),
|
||||||
.addr_i ( addr_ram[DCACHE_INDEX_WIDTH-1:DCACHE_BYTE_OFFSET] ),
|
.addr_i ( addr_ram[DCACHE_INDEX_WIDTH-1:DCACHE_BYTE_OFFSET] ),
|
||||||
|
.wuser_i ( '0 ),
|
||||||
.wdata_i ( wdata_ram.data ),
|
.wdata_i ( wdata_ram.data ),
|
||||||
.be_i ( be_ram.data ),
|
.be_i ( be_ram.data ),
|
||||||
|
.ruser_o ( ),
|
||||||
.rdata_o ( rdata_ram[i].data ),
|
.rdata_o ( rdata_ram[i].data ),
|
||||||
.*
|
.*
|
||||||
);
|
);
|
||||||
|
@ -186,8 +188,10 @@ import std_cache_pkg::*;
|
||||||
.rst_ni ( rst_ni ),
|
.rst_ni ( rst_ni ),
|
||||||
.we_i ( we_ram ),
|
.we_i ( we_ram ),
|
||||||
.addr_i ( addr_ram[DCACHE_INDEX_WIDTH-1:DCACHE_BYTE_OFFSET] ),
|
.addr_i ( addr_ram[DCACHE_INDEX_WIDTH-1:DCACHE_BYTE_OFFSET] ),
|
||||||
|
.wuser_i ( '0 ),
|
||||||
.wdata_i ( wdata_ram.tag ),
|
.wdata_i ( wdata_ram.tag ),
|
||||||
.be_i ( be_ram.tag ),
|
.be_i ( be_ram.tag ),
|
||||||
|
.ruser_o ( ),
|
||||||
.rdata_o ( rdata_ram[i].tag ),
|
.rdata_o ( rdata_ram[i].tag ),
|
||||||
.*
|
.*
|
||||||
);
|
);
|
||||||
|
@ -211,6 +215,7 @@ import std_cache_pkg::*;
|
||||||
end
|
end
|
||||||
|
|
||||||
sram #(
|
sram #(
|
||||||
|
.USER_WIDTH ( 1 ),
|
||||||
.DATA_WIDTH ( 4*DCACHE_DIRTY_WIDTH ),
|
.DATA_WIDTH ( 4*DCACHE_DIRTY_WIDTH ),
|
||||||
.NUM_WORDS ( DCACHE_NUM_WORDS )
|
.NUM_WORDS ( DCACHE_NUM_WORDS )
|
||||||
) valid_dirty_sram (
|
) valid_dirty_sram (
|
||||||
|
@ -219,8 +224,10 @@ import std_cache_pkg::*;
|
||||||
.req_i ( |req_ram ),
|
.req_i ( |req_ram ),
|
||||||
.we_i ( we_ram ),
|
.we_i ( we_ram ),
|
||||||
.addr_i ( addr_ram[DCACHE_INDEX_WIDTH-1:DCACHE_BYTE_OFFSET] ),
|
.addr_i ( addr_ram[DCACHE_INDEX_WIDTH-1:DCACHE_BYTE_OFFSET] ),
|
||||||
|
.wuser_i ( '0 ),
|
||||||
.wdata_i ( dirty_wdata ),
|
.wdata_i ( dirty_wdata ),
|
||||||
.be_i ( be_ram.vldrty ),
|
.be_i ( be_ram.vldrty ),
|
||||||
|
.ruser_o ( ),
|
||||||
.rdata_o ( dirty_rdata )
|
.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 [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 [$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][63:0] axi_wr_data;
|
||||||
|
logic [AxiNumWords-1:0][AXI_USER_WIDTH-1:0] axi_wr_user;
|
||||||
logic [63:0] axi_rd_data;
|
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 [AxiNumWords-1:0][7:0] axi_wr_be;
|
||||||
logic [5:0] axi_wr_atop;
|
logic [5:0] axi_wr_atop;
|
||||||
logic invalidate;
|
logic invalidate;
|
||||||
|
@ -119,6 +121,8 @@ module wt_axi_adapter import ariane_pkg::*; import wt_cache_pkg::*; #(
|
||||||
always_comb begin : p_axi_req
|
always_comb begin : p_axi_req
|
||||||
// write channel
|
// write channel
|
||||||
axi_wr_id_in = arb_idx;
|
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_addr = {{64-riscv::PLEN{1'b0}}, dcache_data.paddr};
|
||||||
axi_wr_size = dcache_data.size[1:0];
|
axi_wr_size = dcache_data.size[1:0];
|
||||||
axi_wr_req = 1'b0;
|
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
|
if (dcache_data.paddr[2] == 1'b0) begin
|
||||||
axi_wr_data = {{64-riscv::XLEN{1'b0}}, dcache_data.data};
|
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
|
end else begin
|
||||||
axi_wr_data = {dcache_data.data, {64-riscv::XLEN{1'b0}}};
|
axi_wr_data = {dcache_data.data, {64-riscv::XLEN{1'b0}}};
|
||||||
|
axi_wr_user = {dcache_data.user, {64-AXI_USER_WIDTH{1'b0}}};
|
||||||
end
|
end
|
||||||
|
|
||||||
// arbiter mux
|
// 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"
|
// in this case we need to invert the data to get a "CLR"
|
||||||
if (dcache_data.paddr[2] == 1'b0) begin
|
if (dcache_data.paddr[2] == 1'b0) begin
|
||||||
axi_wr_data = {{64-riscv::XLEN{1'b1}}, ~dcache_data.data};
|
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
|
end else begin
|
||||||
axi_wr_data = {~dcache_data.data, {64-riscv::XLEN{1'b1}}};
|
axi_wr_data = {~dcache_data.data, {64-riscv::XLEN{1'b1}}};
|
||||||
|
axi_wr_user = {~dcache_data.user, {64-riscv::XLEN{1'b1}}};
|
||||||
end
|
end
|
||||||
axi_wr_atop = {axi_pkg::ATOP_ATOMICLOAD, axi_pkg::ATOP_LITTLE_END, axi_pkg::ATOP_CLR};
|
axi_wr_atop = {axi_pkg::ATOP_ATOMICLOAD, axi_pkg::ATOP_LITTLE_END, axi_pkg::ATOP_CLR};
|
||||||
end
|
end
|
||||||
|
@ -363,7 +371,9 @@ module wt_axi_adapter import ariane_pkg::*; import wt_cache_pkg::*; #(
|
||||||
// buffer read responses in shift regs
|
// buffer read responses in shift regs
|
||||||
logic icache_first_d, icache_first_q, dcache_first_d, dcache_first_q;
|
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_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_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_in_t dcache_rtrn_type_d, dcache_rtrn_type_q;
|
||||||
wt_cache_pkg::dcache_inval_t dcache_rtrn_inv_d, dcache_rtrn_inv_q;
|
wt_cache_pkg::dcache_inval_t dcache_rtrn_inv_d, dcache_rtrn_inv_q;
|
||||||
logic dcache_sc_rtrn, axi_rd_last;
|
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.rtype = wt_cache_pkg::ICACHE_IFILL_ACK;
|
||||||
icache_rtrn_o.tid = icache_rtrn_tid_q;
|
icache_rtrn_o.tid = icache_rtrn_tid_q;
|
||||||
icache_rtrn_o.data = icache_rd_shift_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;
|
icache_rtrn_vld_o = icache_rtrn_vld_q;
|
||||||
|
|
||||||
dcache_rtrn_o = '0;
|
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.inv = dcache_rtrn_inv_q;
|
||||||
dcache_rtrn_o.tid = dcache_rtrn_tid_q;
|
dcache_rtrn_o.tid = dcache_rtrn_tid_q;
|
||||||
dcache_rtrn_o.data = dcache_rd_shift_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;
|
dcache_rtrn_vld_o = dcache_rtrn_vld_q;
|
||||||
|
|
||||||
// read shift registers
|
// read shift registers
|
||||||
icache_rd_shift_d = icache_rd_shift_q;
|
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_d = dcache_rd_shift_q;
|
||||||
|
dcache_rd_shift_user_d = dcache_rd_shift_user_q;
|
||||||
icache_first_d = icache_first_q;
|
icache_first_d = icache_first_q;
|
||||||
dcache_first_d = dcache_first_q;
|
dcache_first_d = dcache_first_q;
|
||||||
|
|
||||||
if (icache_rtrn_rd_en) begin
|
if (icache_rtrn_rd_en) begin
|
||||||
icache_first_d = axi_rd_last;
|
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_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 this is a single word transaction, we need to make sure that word is placed at offset 0
|
||||||
if (icache_first_q) begin
|
if (icache_first_q) begin
|
||||||
icache_rd_shift_d[0] = axi_rd_data;
|
icache_rd_shift_d[0] = axi_rd_data;
|
||||||
|
icache_rd_shift_user_d[0] = axi_rd_user;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if (dcache_rtrn_rd_en) begin
|
if (dcache_rtrn_rd_en) begin
|
||||||
dcache_first_d = axi_rd_last;
|
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_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 this is a single word transaction, we need to make sure that word is placed at offset 0
|
||||||
if (dcache_first_q) begin
|
if (dcache_first_q) begin
|
||||||
dcache_rd_shift_d[0] = axi_rd_data;
|
dcache_rd_shift_d[0] = axi_rd_data;
|
||||||
|
dcache_rd_shift_user_d[0] = axi_rd_user;
|
||||||
end
|
end
|
||||||
end else if (dcache_sc_rtrn) begin
|
end else if (dcache_sc_rtrn) begin
|
||||||
// encode lr/sc success
|
// encode lr/sc success
|
||||||
dcache_rd_shift_d[0] = '0;
|
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_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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -516,7 +536,9 @@ module wt_axi_adapter import ariane_pkg::*; import wt_cache_pkg::*; #(
|
||||||
icache_first_q <= 1'b1;
|
icache_first_q <= 1'b1;
|
||||||
dcache_first_q <= 1'b1;
|
dcache_first_q <= 1'b1;
|
||||||
icache_rd_shift_q <= '0;
|
icache_rd_shift_q <= '0;
|
||||||
|
icache_rd_shift_user_q <= '0;
|
||||||
dcache_rd_shift_q <= '0;
|
dcache_rd_shift_q <= '0;
|
||||||
|
dcache_rd_shift_user_q <= '0;
|
||||||
icache_rtrn_vld_q <= '0;
|
icache_rtrn_vld_q <= '0;
|
||||||
dcache_rtrn_vld_q <= '0;
|
dcache_rtrn_vld_q <= '0;
|
||||||
icache_rtrn_tid_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;
|
icache_first_q <= icache_first_d;
|
||||||
dcache_first_q <= dcache_first_d;
|
dcache_first_q <= dcache_first_d;
|
||||||
icache_rd_shift_q <= icache_rd_shift_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_q <= dcache_rd_shift_d;
|
||||||
|
dcache_rd_shift_user_q <= dcache_rd_shift_user_d;
|
||||||
icache_rtrn_vld_q <= icache_rtrn_vld_d;
|
icache_rtrn_vld_q <= icache_rtrn_vld_d;
|
||||||
dcache_rtrn_vld_q <= dcache_rtrn_vld_d;
|
dcache_rtrn_vld_q <= dcache_rtrn_vld_d;
|
||||||
icache_rtrn_tid_q <= icache_rtrn_tid_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 #(
|
axi_shim #(
|
||||||
|
.AxiUserWidth ( AXI_USER_WIDTH ),
|
||||||
.AxiNumWords ( AxiNumWords ),
|
.AxiNumWords ( AxiNumWords ),
|
||||||
.AxiIdWidth ( $size(axi_resp_i.r.id) )
|
.AxiIdWidth ( $size(axi_resp_i.r.id) )
|
||||||
) i_axi_shim (
|
) 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_last_o ( axi_rd_last ),
|
||||||
.rd_valid_o ( axi_rd_valid ),
|
.rd_valid_o ( axi_rd_valid ),
|
||||||
.rd_data_o ( axi_rd_data ),
|
.rd_data_o ( axi_rd_data ),
|
||||||
|
.rd_user_o ( axi_rd_user ),
|
||||||
.rd_id_o ( axi_rd_id_out ),
|
.rd_id_o ( axi_rd_id_out ),
|
||||||
.rd_exokay_o ( axi_rd_exokay ),
|
.rd_exokay_o ( axi_rd_exokay ),
|
||||||
.wr_req_i ( axi_wr_req ),
|
.wr_req_i ( axi_wr_req ),
|
||||||
.wr_gnt_o ( axi_wr_gnt ),
|
.wr_gnt_o ( axi_wr_gnt ),
|
||||||
.wr_addr_i ( axi_wr_addr ),
|
.wr_addr_i ( axi_wr_addr ),
|
||||||
.wr_data_i ( axi_wr_data ),
|
.wr_data_i ( axi_wr_data ),
|
||||||
|
.wr_user_i ( axi_wr_user ),
|
||||||
.wr_be_i ( axi_wr_be ),
|
.wr_be_i ( axi_wr_be ),
|
||||||
.wr_blen_i ( axi_wr_blen ),
|
.wr_blen_i ( axi_wr_blen ),
|
||||||
.wr_size_i ( axi_wr_size ),
|
.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_CL_IDX_WIDTH-1:0] wr_cl_idx;
|
||||||
logic [DCACHE_OFFSET_WIDTH-1:0] wr_cl_off;
|
logic [DCACHE_OFFSET_WIDTH-1:0] wr_cl_off;
|
||||||
logic [DCACHE_LINE_WIDTH-1:0] wr_cl_data;
|
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_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_vld_bits;
|
||||||
logic [DCACHE_SET_ASSOC-1:0] wr_req;
|
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;
|
logic [DCACHE_OFFSET_WIDTH-1:0] wr_off;
|
||||||
riscv::xlen_t wr_data;
|
riscv::xlen_t wr_data;
|
||||||
logic [(riscv::XLEN/8)-1:0] wr_data_be;
|
logic [(riscv::XLEN/8)-1:0] wr_data_be;
|
||||||
|
logic [DCACHE_USER_WIDTH-1:0] wr_user;
|
||||||
|
|
||||||
// miss unit <-> controllers/wbuffer
|
// miss unit <-> controllers/wbuffer
|
||||||
logic [NumPorts-1:0] miss_req;
|
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_nc;
|
||||||
logic [NumPorts-1:0] miss_we;
|
logic [NumPorts-1:0] miss_we;
|
||||||
logic [NumPorts-1:0][riscv::XLEN-1:0] miss_wdata;
|
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][riscv::PLEN-1:0] miss_paddr;
|
||||||
logic [NumPorts-1:0][DCACHE_SET_ASSOC-1:0] miss_vld_bits;
|
logic [NumPorts-1:0][DCACHE_SET_ASSOC-1:0] miss_vld_bits;
|
||||||
logic [NumPorts-1:0][2:0] miss_size;
|
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_CL_IDX_WIDTH-1:0] rd_idx;
|
||||||
logic [NumPorts-1:0][DCACHE_OFFSET_WIDTH-1:0] rd_off;
|
logic [NumPorts-1:0][DCACHE_OFFSET_WIDTH-1:0] rd_off;
|
||||||
riscv::xlen_t rd_data;
|
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_vld_bits;
|
||||||
logic [DCACHE_SET_ASSOC-1:0] rd_hit_oh;
|
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_nc_i ( miss_nc ),
|
||||||
.miss_we_i ( miss_we ),
|
.miss_we_i ( miss_we ),
|
||||||
.miss_wdata_i ( miss_wdata ),
|
.miss_wdata_i ( miss_wdata ),
|
||||||
|
.miss_wuser_i ( miss_wuser ),
|
||||||
.miss_paddr_i ( miss_paddr ),
|
.miss_paddr_i ( miss_paddr ),
|
||||||
.miss_vld_bits_i ( miss_vld_bits ),
|
.miss_vld_bits_i ( miss_vld_bits ),
|
||||||
.miss_size_i ( miss_size ),
|
.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_idx_o ( wr_cl_idx ),
|
||||||
.wr_cl_off_o ( wr_cl_off ),
|
.wr_cl_off_o ( wr_cl_off ),
|
||||||
.wr_cl_data_o ( wr_cl_data ),
|
.wr_cl_data_o ( wr_cl_data ),
|
||||||
|
.wr_cl_user_o ( wr_cl_user ),
|
||||||
.wr_cl_data_be_o ( wr_cl_data_be ),
|
.wr_cl_data_be_o ( wr_cl_data_be ),
|
||||||
.wr_vld_bits_o ( wr_vld_bits ),
|
.wr_vld_bits_o ( wr_vld_bits ),
|
||||||
// memory interface
|
// memory interface
|
||||||
|
@ -181,6 +187,7 @@ module wt_dcache import ariane_pkg::*; import wt_cache_pkg::*; #(
|
||||||
.miss_ack_i ( miss_ack [k] ),
|
.miss_ack_i ( miss_ack [k] ),
|
||||||
.miss_we_o ( miss_we [k] ),
|
.miss_we_o ( miss_we [k] ),
|
||||||
.miss_wdata_o ( miss_wdata [k] ),
|
.miss_wdata_o ( miss_wdata [k] ),
|
||||||
|
.miss_wuser_o ( miss_wuser [k] ),
|
||||||
.miss_vld_bits_o ( miss_vld_bits [k] ),
|
.miss_vld_bits_o ( miss_vld_bits [k] ),
|
||||||
.miss_paddr_o ( miss_paddr [k] ),
|
.miss_paddr_o ( miss_paddr [k] ),
|
||||||
.miss_nc_o ( miss_nc [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_tag_only_o ( rd_tag_only [k] ),
|
||||||
.rd_ack_i ( rd_ack [k] ),
|
.rd_ack_i ( rd_ack [k] ),
|
||||||
.rd_data_i ( rd_data ),
|
.rd_data_i ( rd_data ),
|
||||||
|
.rd_user_i ( rd_user ),
|
||||||
.rd_vld_bits_i ( rd_vld_bits ),
|
.rd_vld_bits_i ( rd_vld_bits ),
|
||||||
.rd_hit_oh_i ( rd_hit_oh )
|
.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_ack_i ( miss_ack [2] ),
|
||||||
.miss_we_o ( miss_we [2] ),
|
.miss_we_o ( miss_we [2] ),
|
||||||
.miss_wdata_o ( miss_wdata [2] ),
|
.miss_wdata_o ( miss_wdata [2] ),
|
||||||
|
.miss_wuser_o ( miss_wuser [2] ),
|
||||||
.miss_vld_bits_o ( miss_vld_bits [2] ),
|
.miss_vld_bits_o ( miss_vld_bits [2] ),
|
||||||
.miss_paddr_o ( miss_paddr [2] ),
|
.miss_paddr_o ( miss_paddr [2] ),
|
||||||
.miss_nc_o ( miss_nc [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_idx_o ( wr_idx ),
|
||||||
.wr_off_o ( wr_off ),
|
.wr_off_o ( wr_off ),
|
||||||
.wr_data_o ( wr_data ),
|
.wr_data_o ( wr_data ),
|
||||||
|
.wr_user_o ( wr_user ),
|
||||||
.wr_data_be_o ( wr_data_be ),
|
.wr_data_be_o ( wr_data_be ),
|
||||||
// write buffer forwarding
|
// write buffer forwarding
|
||||||
.wbuffer_data_o ( wbuffer_data ),
|
.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_vld_bits_o ( rd_vld_bits ),
|
||||||
.rd_hit_oh_o ( rd_hit_oh ),
|
.rd_hit_oh_o ( rd_hit_oh ),
|
||||||
.rd_data_o ( rd_data ),
|
.rd_data_o ( rd_data ),
|
||||||
|
.rd_user_o ( rd_user ),
|
||||||
// cacheline write port
|
// cacheline write port
|
||||||
.wr_cl_vld_i ( wr_cl_vld ),
|
.wr_cl_vld_i ( wr_cl_vld ),
|
||||||
.wr_cl_nc_i ( wr_cl_nc ),
|
.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_idx_i ( wr_cl_idx ),
|
||||||
.wr_cl_off_i ( wr_cl_off ),
|
.wr_cl_off_i ( wr_cl_off ),
|
||||||
.wr_cl_data_i ( wr_cl_data ),
|
.wr_cl_data_i ( wr_cl_data ),
|
||||||
|
.wr_cl_user_i ( wr_cl_user ),
|
||||||
.wr_cl_data_be_i ( wr_cl_data_be ),
|
.wr_cl_data_be_i ( wr_cl_data_be ),
|
||||||
.wr_vld_bits_i ( wr_vld_bits ),
|
.wr_vld_bits_i ( wr_vld_bits ),
|
||||||
// single word write port
|
// single word write port
|
||||||
|
@ -297,6 +309,7 @@ module wt_dcache import ariane_pkg::*; import wt_cache_pkg::*; #(
|
||||||
.wr_idx_i ( wr_idx ),
|
.wr_idx_i ( wr_idx ),
|
||||||
.wr_off_i ( wr_off ),
|
.wr_off_i ( wr_off ),
|
||||||
.wr_data_i ( wr_data ),
|
.wr_data_i ( wr_data ),
|
||||||
|
.wr_user_i ( wr_user ),
|
||||||
.wr_data_be_i ( wr_data_be ),
|
.wr_data_be_i ( wr_data_be ),
|
||||||
// write buffer forwarding
|
// write buffer forwarding
|
||||||
.wbuffer_data_i ( wbuffer_data )
|
.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,
|
input logic miss_ack_i,
|
||||||
output logic miss_we_o, // unused (set to 0)
|
output logic miss_we_o, // unused (set to 0)
|
||||||
output riscv::xlen_t miss_wdata_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 [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 [riscv::PLEN-1:0] miss_paddr_o,
|
||||||
output logic miss_nc_o, // request to I/O space
|
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
|
output logic rd_tag_only_o, // set to zero here
|
||||||
input logic rd_ack_i,
|
input logic rd_ack_i,
|
||||||
input riscv::xlen_t rd_data_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_vld_bits_i,
|
||||||
input logic [DCACHE_SET_ASSOC-1:0] rd_hit_oh_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 rd_off_o = address_off_d;
|
||||||
|
|
||||||
assign req_port_o.data_rdata = rd_data_i;
|
assign req_port_o.data_rdata = rd_data_i;
|
||||||
|
assign req_port_o.data_ruser = rd_user_i;
|
||||||
|
|
||||||
// to miss unit
|
// to miss unit
|
||||||
assign miss_vld_bits_o = vld_data_q;
|
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_we_o = '0;
|
||||||
assign miss_wdata_o = '0;
|
assign miss_wdata_o = '0;
|
||||||
|
assign miss_wuser_o = '0;
|
||||||
assign miss_id_o = RdTxId;
|
assign miss_id_o = RdTxId;
|
||||||
assign rd_req_d = rd_req_o;
|
assign rd_req_d = rd_req_o;
|
||||||
assign rd_ack_d = rd_ack_i;
|
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_vld_bits_o,
|
||||||
output logic [DCACHE_SET_ASSOC-1:0] rd_hit_oh_o,
|
output logic [DCACHE_SET_ASSOC-1:0] rd_hit_oh_o,
|
||||||
output riscv::xlen_t rd_data_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
|
// only available on port 0, uses address signals of port 0
|
||||||
input logic wr_cl_vld_i,
|
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_CL_IDX_WIDTH-1:0] wr_cl_idx_i,
|
||||||
input logic [DCACHE_OFFSET_WIDTH-1:0] wr_cl_off_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_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_LINE_WIDTH/8-1:0] wr_cl_data_be_i,
|
||||||
input logic [DCACHE_SET_ASSOC-1:0] wr_vld_bits_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_CL_IDX_WIDTH-1:0] wr_idx_i,
|
||||||
input logic [DCACHE_OFFSET_WIDTH-1:0] wr_off_i,
|
input logic [DCACHE_OFFSET_WIDTH-1:0] wr_off_i,
|
||||||
input riscv::xlen_t wr_data_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,
|
input logic [(riscv::XLEN/8)-1:0] wr_data_be_i,
|
||||||
|
|
||||||
// forwarded wbuffer
|
// forwarded wbuffer
|
||||||
|
@ -78,6 +81,9 @@ module wt_dcache_mem import ariane_pkg::*; import wt_cache_pkg::*; #(
|
||||||
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_wdata; //
|
||||||
logic [DCACHE_NUM_BANKS-1:0][DCACHE_SET_ASSOC-1:0][riscv::XLEN-1:0] bank_rdata; //
|
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_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_TAG_WIDTH-1:0] rd_tag;
|
||||||
logic [DCACHE_SET_ASSOC-1:0] vld_req; // bit enable for valid regs
|
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 [DCACHE_WBUF_DEPTH-1:0] wbuffer_hit_oh;
|
||||||
logic [(riscv::XLEN/8)-1:0] wbuffer_be;
|
logic [(riscv::XLEN/8)-1:0] wbuffer_be;
|
||||||
riscv::xlen_t wbuffer_rdata, rdata;
|
riscv::xlen_t wbuffer_rdata, rdata;
|
||||||
|
logic [DCACHE_USER_WIDTH-1:0] wbuffer_ruser, ruser;
|
||||||
logic [riscv::PLEN-1:0] wbuffer_cmp_addr;
|
logic [riscv::PLEN-1:0] wbuffer_cmp_addr;
|
||||||
|
|
||||||
logic cmp_en_d, cmp_en_q;
|
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)] :
|
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 :
|
(wr_req_i[j] & wr_ack_o) ? wr_data_be_i :
|
||||||
'0;
|
'0;
|
||||||
|
|
||||||
assign bank_wdata[k][j] = (wr_cl_we_i[j] & wr_cl_vld_i) ? wr_cl_data_i[k*riscv::XLEN +: riscv::XLEN] :
|
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;
|
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
|
||||||
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;
|
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
|
// 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 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
|
end
|
||||||
|
|
||||||
for(genvar k=0; k<DCACHE_WBUF_DEPTH; k++) begin : gen_wbuffer_hit
|
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_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;
|
assign wbuffer_be = (|wbuffer_hit_oh) ? wbuffer_data_i[wbuffer_hit_idx].valid : '0;
|
||||||
|
|
||||||
if (Axi64BitCompliant) begin : gen_axi_off
|
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];
|
assign wr_cl_off = wr_cl_off_i[DCACHE_OFFSET_WIDTH-1:3];
|
||||||
end
|
end
|
||||||
|
|
||||||
assign rdata = (wr_cl_vld_i) ? wr_cl_data_i[wr_cl_off*riscv::XLEN +: riscv::XLEN] :
|
always_comb begin
|
||||||
rdata_cl[rd_hit_idx];
|
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
|
// overlay bytes that hit in the write buffer
|
||||||
for(genvar k=0; k<(riscv::XLEN/8); k++) begin : gen_rd_data
|
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];
|
assign rd_data_o[8*k +: 8] = (wbuffer_be[k]) ? wbuffer_rdata[8*k +: 8] : rdata[8*k +: 8];
|
||||||
end
|
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
|
// 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
|
for (genvar k = 0; k < DCACHE_NUM_BANKS; k++) begin : gen_data_banks
|
||||||
// Data RAM
|
// Data RAM
|
||||||
sram #(
|
sram #(
|
||||||
|
.USER_WIDTH ( ariane_pkg::DCACHE_SET_ASSOC * DATA_USER_WIDTH ),
|
||||||
.DATA_WIDTH ( ariane_pkg::DCACHE_SET_ASSOC * riscv::XLEN ),
|
.DATA_WIDTH ( ariane_pkg::DCACHE_SET_ASSOC * riscv::XLEN ),
|
||||||
|
.USER_EN ( ariane_pkg::DATA_USER_EN ),
|
||||||
.NUM_WORDS ( wt_cache_pkg::DCACHE_NUM_WORDS )
|
.NUM_WORDS ( wt_cache_pkg::DCACHE_NUM_WORDS )
|
||||||
) i_data_sram (
|
) i_data_sram (
|
||||||
.clk_i ( clk_i ),
|
.clk_i ( clk_i ),
|
||||||
|
@ -263,8 +285,10 @@ module wt_dcache_mem import ariane_pkg::*; import wt_cache_pkg::*; #(
|
||||||
.req_i ( bank_req [k] ),
|
.req_i ( bank_req [k] ),
|
||||||
.we_i ( bank_we [k] ),
|
.we_i ( bank_we [k] ),
|
||||||
.addr_i ( bank_idx [k] ),
|
.addr_i ( bank_idx [k] ),
|
||||||
|
.wuser_i ( bank_wuser [k] ),
|
||||||
.wdata_i ( bank_wdata [k] ),
|
.wdata_i ( bank_wdata [k] ),
|
||||||
.be_i ( bank_be [k] ),
|
.be_i ( bank_be [k] ),
|
||||||
|
.ruser_o ( bank_ruser [k] ),
|
||||||
.rdata_o ( bank_rdata [k] )
|
.rdata_o ( bank_rdata [k] )
|
||||||
);
|
);
|
||||||
end
|
end
|
||||||
|
@ -285,8 +309,10 @@ module wt_dcache_mem import ariane_pkg::*; import wt_cache_pkg::*; #(
|
||||||
.req_i ( vld_req[i] ),
|
.req_i ( vld_req[i] ),
|
||||||
.we_i ( vld_we ),
|
.we_i ( vld_we ),
|
||||||
.addr_i ( vld_addr ),
|
.addr_i ( vld_addr ),
|
||||||
|
.wuser_i ( '0 ),
|
||||||
.wdata_i ( {vld_wdata[i], wr_cl_tag_i} ),
|
.wdata_i ( {vld_wdata[i], wr_cl_tag_i} ),
|
||||||
.be_i ( '1 ),
|
.be_i ( '1 ),
|
||||||
|
.ruser_o ( ),
|
||||||
.rdata_o ( vld_tag_rdata[i] )
|
.rdata_o ( vld_tag_rdata[i] )
|
||||||
);
|
);
|
||||||
end
|
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_nc_i,
|
||||||
input logic [NumPorts-1:0] miss_we_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][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][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][DCACHE_SET_ASSOC-1:0] miss_vld_bits_i,
|
||||||
input logic [NumPorts-1:0][2:0] miss_size_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_CL_IDX_WIDTH-1:0] wr_cl_idx_o,
|
||||||
output logic [DCACHE_OFFSET_WIDTH-1:0] wr_cl_off_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_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_LINE_WIDTH/8-1:0] wr_cl_data_be_o,
|
||||||
output logic [DCACHE_SET_ASSOC-1:0] wr_vld_bits_o,
|
output logic [DCACHE_SET_ASSOC-1:0] wr_vld_bits_o,
|
||||||
// memory interface
|
// 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 amo_req_d, amo_req_q;
|
||||||
logic [63:0] amo_rtrn_mux;
|
logic [63:0] amo_rtrn_mux;
|
||||||
riscv::xlen_t amo_data;
|
riscv::xlen_t amo_data;
|
||||||
|
logic [63:0] amo_user; //DCACHE USER ? DATA_USER_WIDTH
|
||||||
logic [riscv::PLEN-1:0] tmp_paddr;
|
logic [riscv::PLEN-1:0] tmp_paddr;
|
||||||
logic [$clog2(NumPorts)-1:0] miss_port_idx;
|
logic [$clog2(NumPorts)-1:0] miss_port_idx;
|
||||||
logic [DCACHE_CL_IDX_WIDTH-1:0] cnt_d, cnt_q;
|
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...
|
// 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 :
|
always_comb begin
|
||||||
amo_req_i.operand_b[0 +: 32];
|
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!
|
// note: openpiton returns a full cacheline!
|
||||||
if (Axi64BitCompliant) begin : gen_axi_rtrn_mux
|
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.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.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.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.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;
|
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_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_off_o = mshr_q.paddr[DCACHE_OFFSET_WIDTH-1:0];
|
||||||
assign wr_cl_data_o = mem_rtrn_i.data;
|
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
|
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
|
// 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_req_o,
|
||||||
output logic miss_we_o, // always 1 here
|
output logic miss_we_o, // always 1 here
|
||||||
output riscv::xlen_t miss_wdata_o,
|
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 [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 miss_nc_o, // request to I/O space
|
||||||
output logic [2:0] miss_size_o, //
|
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 logic [DCACHE_OFFSET_WIDTH-1:0] wr_off_o,
|
||||||
output riscv::xlen_t wr_data_o,
|
output riscv::xlen_t wr_data_o,
|
||||||
output logic [(riscv::XLEN/8)-1:0] wr_data_be_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
|
// to forwarding logic and miss unit
|
||||||
output wbuffer_t [DCACHE_WBUF_DEPTH-1:0] wbuffer_data_o,
|
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
|
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
|
// 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]):
|
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]);
|
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]):
|
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]);
|
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_idx_o = wr_paddr[DCACHE_INDEX_WIDTH-1:DCACHE_OFFSET_WIDTH];
|
||||||
assign wr_off_o = wr_paddr[DCACHE_OFFSET_WIDTH-1:0];
|
assign wr_off_o = wr_paddr[DCACHE_OFFSET_WIDTH-1:0];
|
||||||
assign wr_data_o = wbuffer_q[rtrn_ptr].data;
|
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_rvalid = '0;
|
||||||
assign req_port_o.data_rdata = '0;
|
assign req_port_o.data_rdata = '0;
|
||||||
|
assign req_port_o.data_ruser = '0;
|
||||||
|
|
||||||
assign rd_hit_oh_d = rd_hit_oh_i;
|
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]};
|
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
|
// mark bytes as dirty
|
||||||
|
wbuffer_d[wr_ptr].user = '0;
|
||||||
for (int k=0; k<(riscv::XLEN/8); k++) begin
|
for (int k=0; k<(riscv::XLEN/8); k++) begin
|
||||||
if (req_port_i.data_be[k]) begin
|
if (req_port_i.data_be[k]) begin
|
||||||
wbuffer_d[wr_ptr].valid[k] = 1'b1;
|
wbuffer_d[wr_ptr].valid[k] = 1'b1;
|
||||||
wbuffer_d[wr_ptr].dirty[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];
|
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
|
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");
|
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 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 (
|
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} )
|
@(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",
|
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;
|
typedef enum logic { SINGLE_REQ, CACHE_LINE_REQ } ad_req_t;
|
||||||
|
|
||||||
localparam IdWidth = 4; // Recommended by AXI standard
|
localparam IdWidth = 4; // Recommended by AXI standard
|
||||||
localparam UserWidth = 1;
|
localparam UserWidth = ariane_pkg::AXI_USER_WIDTH;
|
||||||
localparam AddrWidth = 64;
|
localparam AddrWidth = 64;
|
||||||
localparam DataWidth = 64;
|
localparam DataWidth = 64;
|
||||||
localparam StrbWidth = DataWidth / 8;
|
localparam StrbWidth = DataWidth / 8;
|
||||||
|
|
|
@ -278,6 +278,18 @@ package ariane_pkg;
|
||||||
| riscv::SSTATUS_FS
|
| riscv::SSTATUS_FS
|
||||||
| riscv::SSTATUS_SUM
|
| riscv::SSTATUS_SUM
|
||||||
| riscv::SSTATUS_MXR;
|
| 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
|
// Fetch Stage
|
||||||
// ---------------
|
// ---------------
|
||||||
|
@ -430,12 +442,15 @@ package ariane_pkg;
|
||||||
localparam int unsigned ICACHE_INDEX_WIDTH = $clog2(CONFIG_L1I_SIZE / ICACHE_SET_ASSOC); // in bit, contains also offset width
|
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_TAG_WIDTH = riscv::PLEN-ICACHE_INDEX_WIDTH; // in bit
|
||||||
localparam int unsigned ICACHE_LINE_WIDTH = 128; // 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$
|
// D$
|
||||||
localparam int unsigned CONFIG_L1D_SIZE = 32*1024;
|
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_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_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_TAG_WIDTH = riscv::PLEN-DCACHE_INDEX_WIDTH; // in bit
|
||||||
localparam int unsigned DCACHE_LINE_WIDTH = 128; // 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
|
`endif
|
||||||
|
|
||||||
localparam bit CVXIF_PRESENT = cva6_config_pkg::CVA6ConfigCvxifEn;
|
localparam bit CVXIF_PRESENT = cva6_config_pkg::CVA6ConfigCvxifEn;
|
||||||
|
@ -701,6 +716,7 @@ package ariane_pkg;
|
||||||
logic ready; // icache is ready
|
logic ready; // icache is ready
|
||||||
logic valid; // signals a valid read
|
logic valid; // signals a valid read
|
||||||
logic [FETCH_WIDTH-1:0] data; // 2+ cycle out: tag
|
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
|
logic [riscv::VLEN-1:0] vaddr; // virtual address out
|
||||||
exception_t ex; // we've encountered an exception
|
exception_t ex; // we've encountered an exception
|
||||||
} icache_dreq_o_t;
|
} icache_dreq_o_t;
|
||||||
|
@ -728,6 +744,7 @@ package ariane_pkg;
|
||||||
logic [DCACHE_INDEX_WIDTH-1:0] address_index;
|
logic [DCACHE_INDEX_WIDTH-1:0] address_index;
|
||||||
logic [DCACHE_TAG_WIDTH-1:0] address_tag;
|
logic [DCACHE_TAG_WIDTH-1:0] address_tag;
|
||||||
riscv::xlen_t data_wdata;
|
riscv::xlen_t data_wdata;
|
||||||
|
logic [DCACHE_USER_WIDTH-1:0] data_wuser;
|
||||||
logic data_req;
|
logic data_req;
|
||||||
logic data_we;
|
logic data_we;
|
||||||
logic [(riscv::XLEN/8)-1:0] data_be;
|
logic [(riscv::XLEN/8)-1:0] data_be;
|
||||||
|
@ -740,6 +757,7 @@ package ariane_pkg;
|
||||||
logic data_gnt;
|
logic data_gnt;
|
||||||
logic data_rvalid;
|
logic data_rvalid;
|
||||||
riscv::xlen_t data_rdata;
|
riscv::xlen_t data_rdata;
|
||||||
|
logic [DCACHE_USER_WIDTH-1:0] data_ruser;
|
||||||
} dcache_req_o_t;
|
} dcache_req_o_t;
|
||||||
|
|
||||||
// ----------------------
|
// ----------------------
|
||||||
|
|
|
@ -15,4 +15,9 @@ package cva6_config_pkg;
|
||||||
localparam CVA6ConfigCvxifEn = 0;
|
localparam CVA6ConfigCvxifEn = 0;
|
||||||
localparam CVA6ConfigCExtEn = 1;
|
localparam CVA6ConfigCExtEn = 1;
|
||||||
|
|
||||||
|
localparam CVA6ConfigFetchUserEn = 0;
|
||||||
|
localparam CVA6ConfigFetchUserWidth = CVA6ConfigXlen;
|
||||||
|
localparam CVA6ConfigDataUserEn = 0;
|
||||||
|
localparam CVA6ConfigDataUserWidth = CVA6ConfigXlen;
|
||||||
|
|
||||||
endpackage
|
endpackage
|
||||||
|
|
|
@ -15,4 +15,9 @@ package cva6_config_pkg;
|
||||||
localparam CVA6ConfigCvxifEn = 0;
|
localparam CVA6ConfigCvxifEn = 0;
|
||||||
localparam CVA6ConfigCExtEn = 1;
|
localparam CVA6ConfigCExtEn = 1;
|
||||||
|
|
||||||
|
localparam CVA6ConfigFetchUserEn = 0;
|
||||||
|
localparam CVA6ConfigFetchUserWidth = CVA6ConfigXlen;
|
||||||
|
localparam CVA6ConfigDataUserEn = 0;
|
||||||
|
localparam CVA6ConfigDataUserWidth = CVA6ConfigXlen;
|
||||||
|
|
||||||
endpackage
|
endpackage
|
||||||
|
|
|
@ -15,4 +15,9 @@ package cva6_config_pkg;
|
||||||
localparam CVA6ConfigCvxifEn = 0;
|
localparam CVA6ConfigCvxifEn = 0;
|
||||||
localparam CVA6ConfigCExtEn = 1;
|
localparam CVA6ConfigCExtEn = 1;
|
||||||
|
|
||||||
|
localparam CVA6ConfigFetchUserEn = 0;
|
||||||
|
localparam CVA6ConfigFetchUserWidth = CVA6ConfigXlen;
|
||||||
|
localparam CVA6ConfigDataUserEn = 0;
|
||||||
|
localparam CVA6ConfigDataUserWidth = CVA6ConfigXlen;
|
||||||
|
|
||||||
endpackage
|
endpackage
|
||||||
|
|
|
@ -15,4 +15,9 @@ package cva6_config_pkg;
|
||||||
localparam CVA6ConfigCvxifEn = 1;
|
localparam CVA6ConfigCvxifEn = 1;
|
||||||
localparam CVA6ConfigCExtEn = 1;
|
localparam CVA6ConfigCExtEn = 1;
|
||||||
|
|
||||||
|
localparam CVA6ConfigFetchUserEn = 0;
|
||||||
|
localparam CVA6ConfigFetchUserWidth = CVA6ConfigXlen;
|
||||||
|
localparam CVA6ConfigDataUserEn = 0;
|
||||||
|
localparam CVA6ConfigDataUserWidth = CVA6ConfigXlen;
|
||||||
|
|
||||||
endpackage
|
endpackage
|
||||||
|
|
|
@ -77,6 +77,7 @@ package wt_cache_pkg;
|
||||||
typedef struct packed {
|
typedef struct packed {
|
||||||
logic [ariane_pkg::DCACHE_TAG_WIDTH+(ariane_pkg::DCACHE_INDEX_WIDTH-riscv::XLEN_ALIGN_BYTES)-1:0] wtag;
|
logic [ariane_pkg::DCACHE_TAG_WIDTH+(ariane_pkg::DCACHE_INDEX_WIDTH-riscv::XLEN_ALIGN_BYTES)-1:0] wtag;
|
||||||
riscv::xlen_t data;
|
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] dirty; // byte is dirty
|
||||||
logic [(riscv::XLEN/8)-1:0] valid; // byte is valid
|
logic [(riscv::XLEN/8)-1:0] valid; // byte is valid
|
||||||
logic [(riscv::XLEN/8)-1:0] txblock; // byte is part of transaction in-flight
|
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 {
|
typedef struct packed {
|
||||||
icache_in_t rtype; // see definitions above
|
icache_in_t rtype; // see definitions above
|
||||||
logic [ariane_pkg::ICACHE_LINE_WIDTH-1:0] data; // full cache line width
|
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
|
icache_inval_t inv; // invalidation vector
|
||||||
logic [CACHE_ID_WIDTH-1:0] tid; // threadi id (used as transaction id in Ariane)
|
logic [CACHE_ID_WIDTH-1:0] tid; // threadi id (used as transaction id in Ariane)
|
||||||
} icache_rtrn_t;
|
} icache_rtrn_t;
|
||||||
|
@ -151,6 +153,7 @@ package wt_cache_pkg;
|
||||||
logic [L1D_WAY_WIDTH-1:0] way; // way to replace
|
logic [L1D_WAY_WIDTH-1:0] way; // way to replace
|
||||||
logic [riscv::PLEN-1:0] paddr; // physical address
|
logic [riscv::PLEN-1:0] paddr; // physical address
|
||||||
riscv::xlen_t data; // word width of processor (no block stores at the moment)
|
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 nc; // noncacheable
|
||||||
logic [CACHE_ID_WIDTH-1:0] tid; // threadi id (used as transaction id in Ariane)
|
logic [CACHE_ID_WIDTH-1:0] tid; // threadi id (used as transaction id in Ariane)
|
||||||
ariane_pkg::amo_t amo_op; // amo opcode
|
ariane_pkg::amo_t amo_op; // amo opcode
|
||||||
|
@ -159,6 +162,7 @@ package wt_cache_pkg;
|
||||||
typedef struct packed {
|
typedef struct packed {
|
||||||
dcache_in_t rtype; // see definitions above
|
dcache_in_t rtype; // see definitions above
|
||||||
logic [ariane_pkg::DCACHE_LINE_WIDTH-1:0] data; // full cache line width
|
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
|
dcache_inval_t inv; // invalidation vector
|
||||||
logic [CACHE_ID_WIDTH-1:0] tid; // threadi id (used as transaction id in Ariane)
|
logic [CACHE_ID_WIDTH-1:0] tid; // threadi id (used as transaction id in Ariane)
|
||||||
} dcache_rtrn_t;
|
} dcache_rtrn_t;
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 4650ca9006d3ed7dddb3078af150467087823c19
|
Subproject commit b494701501886ad71ba0c128560cc371610bcf1a
|
|
@ -159,7 +159,7 @@ localparam AxiAddrWidth = 64;
|
||||||
localparam AxiDataWidth = 64;
|
localparam AxiDataWidth = 64;
|
||||||
localparam AxiIdWidthMaster = 4;
|
localparam AxiIdWidthMaster = 4;
|
||||||
localparam AxiIdWidthSlaves = AxiIdWidthMaster + $clog2(NBSlave); // 5
|
localparam AxiIdWidthSlaves = AxiIdWidthMaster + $clog2(NBSlave); // 5
|
||||||
localparam AxiUserWidth = 1;
|
localparam AxiUserWidth = ariane_pkg::AXI_USER_WIDTH;
|
||||||
|
|
||||||
`AXI_TYPEDEF_ALL(axi_slave,
|
`AXI_TYPEDEF_ALL(axi_slave,
|
||||||
logic [ AxiAddrWidth-1:0],
|
logic [ AxiAddrWidth-1:0],
|
||||||
|
|
|
@ -20,7 +20,7 @@ package ariane_axi_soc;
|
||||||
// used in axi_adapter.sv
|
// used in axi_adapter.sv
|
||||||
typedef enum logic { SINGLE_REQ, CACHE_LINE_REQ } ad_req_t;
|
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 AddrWidth = 64;
|
||||||
localparam DataWidth = 64;
|
localparam DataWidth = 64;
|
||||||
localparam StrbWidth = DataWidth / 8;
|
localparam StrbWidth = DataWidth / 8;
|
||||||
|
|
|
@ -321,6 +321,7 @@ done_processing:
|
||||||
// Preload memory.
|
// Preload memory.
|
||||||
size_t mem_size = 0xFFFFFF;
|
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(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
|
#ifndef DROMAJO
|
||||||
while (!dtm->done() && !jtag->done()) {
|
while (!dtm->done() && !jtag->done()) {
|
||||||
|
|
|
@ -20,6 +20,7 @@ import uvm_pkg::*;
|
||||||
`include "uvm_macros.svh"
|
`include "uvm_macros.svh"
|
||||||
|
|
||||||
`define MAIN_MEM(P) dut.i_sram.gen_cut[0].gen_mem.i_ram.Mem_DP[(``P``)]
|
`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 read_elf(input string filename);
|
||||||
import "DPI-C" function byte get_section(output longint address, output longint len);
|
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
|
for (int j = 0; j < 8; j++) begin
|
||||||
mem_row[j] = buffer[i*8 + j];
|
mem_row[j] = buffer[i*8 + j];
|
||||||
end
|
end
|
||||||
`MAIN_MEM((address[28:0] >> 3) + i) = mem_row;
|
`MAIN_MEM((address[23:0] >> 3) + i) = mem_row;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,7 +16,8 @@
|
||||||
`include "axi/assign.svh"
|
`include "axi/assign.svh"
|
||||||
|
|
||||||
module ariane_testharness #(
|
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_ADDRESS_WIDTH = 64,
|
||||||
parameter int unsigned AXI_DATA_WIDTH = 64,
|
parameter int unsigned AXI_DATA_WIDTH = 64,
|
||||||
`ifdef DROMAJO
|
`ifdef DROMAJO
|
||||||
|
@ -272,7 +273,9 @@ module ariane_testharness #(
|
||||||
.we_o ( dm_slave_we ),
|
.we_o ( dm_slave_we ),
|
||||||
.addr_o ( dm_slave_addr ),
|
.addr_o ( dm_slave_addr ),
|
||||||
.be_o ( dm_slave_be ),
|
.be_o ( dm_slave_be ),
|
||||||
|
.user_o ( ),
|
||||||
.data_o ( dm_slave_wdata ),
|
.data_o ( dm_slave_wdata ),
|
||||||
|
.user_i ( '0 ),
|
||||||
.data_i ( dm_slave_rdata )
|
.data_i ( dm_slave_rdata )
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -325,7 +328,9 @@ module ariane_testharness #(
|
||||||
.we_o ( ),
|
.we_o ( ),
|
||||||
.addr_o ( rom_addr ),
|
.addr_o ( rom_addr ),
|
||||||
.be_o ( ),
|
.be_o ( ),
|
||||||
|
.user_o ( ),
|
||||||
.data_o ( ),
|
.data_o ( ),
|
||||||
|
.user_i ( '0 ),
|
||||||
.data_i ( rom_rdata )
|
.data_i ( rom_rdata )
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -384,6 +389,8 @@ module ariane_testharness #(
|
||||||
logic [AXI_DATA_WIDTH/8-1:0] be;
|
logic [AXI_DATA_WIDTH/8-1:0] be;
|
||||||
logic [AXI_DATA_WIDTH-1:0] wdata;
|
logic [AXI_DATA_WIDTH-1:0] wdata;
|
||||||
logic [AXI_DATA_WIDTH-1:0] rdata;
|
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_riscv_atomics_wrap #(
|
||||||
.AXI_ADDR_WIDTH ( AXI_ADDRESS_WIDTH ),
|
.AXI_ADDR_WIDTH ( AXI_ADDRESS_WIDTH ),
|
||||||
|
@ -435,12 +442,16 @@ module ariane_testharness #(
|
||||||
.we_o ( we ),
|
.we_o ( we ),
|
||||||
.addr_o ( addr ),
|
.addr_o ( addr ),
|
||||||
.be_o ( be ),
|
.be_o ( be ),
|
||||||
|
.user_o ( wuser ),
|
||||||
.data_o ( wdata ),
|
.data_o ( wdata ),
|
||||||
|
.user_i ( ruser ),
|
||||||
.data_i ( rdata )
|
.data_i ( rdata )
|
||||||
);
|
);
|
||||||
|
|
||||||
sram #(
|
sram #(
|
||||||
.DATA_WIDTH ( AXI_DATA_WIDTH ),
|
.DATA_WIDTH ( AXI_DATA_WIDTH ),
|
||||||
|
.USER_WIDTH ( AXI_USER_WIDTH ),
|
||||||
|
.USER_EN ( AXI_USER_EN ),
|
||||||
`ifdef DROMAJO
|
`ifdef DROMAJO
|
||||||
.DROMAJO_RAM (1),
|
.DROMAJO_RAM (1),
|
||||||
`endif
|
`endif
|
||||||
|
@ -451,8 +462,10 @@ module ariane_testharness #(
|
||||||
.req_i ( req ),
|
.req_i ( req ),
|
||||||
.we_i ( we ),
|
.we_i ( we ),
|
||||||
.addr_i ( addr[$clog2(NUM_WORDS)-1+$clog2(AXI_DATA_WIDTH/8):$clog2(AXI_DATA_WIDTH/8)] ),
|
.addr_i ( addr[$clog2(NUM_WORDS)-1+$clog2(AXI_DATA_WIDTH/8):$clog2(AXI_DATA_WIDTH/8)] ),
|
||||||
|
.wuser_i ( wuser ),
|
||||||
.wdata_i ( wdata ),
|
.wdata_i ( wdata ),
|
||||||
.be_i ( be ),
|
.be_i ( be ),
|
||||||
|
.ruser_o ( ruser ),
|
||||||
.rdata_o ( rdata )
|
.rdata_o ( rdata )
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue