Use different IDs for read transactions, allow for multiple outstanding reads.

This commit is contained in:
Michael Schaffner 2018-11-15 14:35:57 +01:00
parent 1933f066f3
commit 4431ad5edb
No known key found for this signature in database
GPG key ID: 7AA09AE049819C2C
7 changed files with 128 additions and 125 deletions

View file

@ -91,6 +91,8 @@ serpent_icache #(
`ifdef AXI64_CACHE_PORTS
.AXI64BIT_COMPLIANT ( 1'b1 ),
`endif
// use ID 0 for icache reads
.RD_TX_ID ( 0 ),
.NC_ADDR_GE_LT ( CACHE_LOW_REGION ),
.NC_ADDR_BEGIN ( CACHE_START_ADDR )
) i_serpent_icache (
@ -116,7 +118,10 @@ serpent_icache #(
// they have equal prio and are RR arbited
// Port 2 is write only and goes into the merging write buffer
serpent_dcache #(
.NC_ADDR_GE_LT ( CACHE_LOW_REGION ), // std config is for openpiton, where the upper memory region is NC
// use ID 1 for dcache reads and amos. note that the writebuffer
// uses all IDs up to DCACHE_MAX_TX-1 for write transactions.
.RD_AMO_TX_ID ( 1 ),
.NC_ADDR_GE_LT ( CACHE_LOW_REGION ),
.NC_ADDR_BEGIN ( CACHE_START_ADDR )
) i_serpent_dcache (
.clk_i ( clk_i ),
@ -163,10 +168,12 @@ serpent_l15_adapter #(
`endif
);
///////////////////////////////////////////////////////
// different memory plumbing to allow for using the
// serpent cache subsystem in a standard AXI setting
// for verificaton purposes.
///////////////////////////////////////////////////////
// different memory plumbing
// note that this is a workaround that is mainly used to verify L15 adapter
// and serpent cache system with the standard AXI-based testharness
`ifdef AXI64_CACHE_PORTS
// support up to 512bit cache lines
@ -186,29 +193,25 @@ logic axi_wr_valid, axi_rd_rdy, axi_wr_rdy;
logic ifill;
logic [serpent_cache_pkg::L15_TID_WIDTH+2-1:0] id_tmp;
logic rd_pending_d, rd_pending_q;
// request side
assign ifill = (l15_req.l15_rqtype==serpent_cache_pkg::L15_IMISS_RQ);
assign axi_rd_req = l15_req.l15_val && (l15_req.l15_rqtype==serpent_cache_pkg::L15_LOAD_RQ | ifill) && !rd_pending_q;
assign axi_rd_req = l15_req.l15_val && (l15_req.l15_rqtype==serpent_cache_pkg::L15_LOAD_RQ | ifill);
assign axi_wr_req = l15_req.l15_val && (l15_req.l15_rqtype==serpent_cache_pkg::L15_STORE_RQ);
assign axi_rd_addr = l15_req.l15_address;
assign axi_wr_addr = axi_rd_addr;
// the axi interconnect does not correctly handle the ordering of read responses with same IDs that
// go to different slaves. workaround: only allow for one outstanding TX
assign rd_pending_d = (axi_rd_valid) ? '0 : axi_rd_gnt;
assign axi_rd_id_in = {l15_req.l15_threadid, ifill, l15_req.l15_nc};
assign axi_wr_id_in = axi_rd_id_in;
assign axi_rd_size = (ifill) ? 2'b11 : l15_req.l15_size[1:0];// always request 64bit (fix this... at some point)
assign axi_rd_size = (ifill) ? 2'b11 : l15_req.l15_size[1:0];// always request 64bit in this case
assign axi_wr_size = l15_req.l15_size[1:0];
assign axi_rd_blen = (l15_req.l15_size[2]) ? ((ifill) ? ariane_pkg::ICACHE_LINE_WIDTH/64-1 :
ariane_pkg::DCACHE_LINE_WIDTH/64-1) : '0;
ariane_pkg::DCACHE_LINE_WIDTH/64-1) : '0;
assign axi_wr_blen = '0;// single word writes
assign axi_wr_data = l15_req.l15_data;
@ -250,13 +253,6 @@ always_comb begin : p_axi_rtrn
l15_rtrn.l15_data_3 = axi_rd_data[3];
end
always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
if(~rst_ni) begin
rd_pending_q <= '0;
end else begin
rd_pending_q <= rd_pending_d;
end
end
axi_adapter2 #(

View file

@ -16,12 +16,15 @@ import ariane_pkg::*;
import serpent_cache_pkg::*;
module serpent_dcache #(
parameter NC_ADDR_BEGIN = 40'h8000000000, // start address of noncacheable I/O region
parameter bit NC_ADDR_GE_LT = 1'b1 // determines how the physical address is compared with NC_ADDR_BEGIN
)(
// ID to be used for read and AMO transactions.
// note that the write buffer uses all IDs up to DCACHE_MAX_TX-1 for write transactions
parameter logic [DCACHE_ID_WIDTH-1:0] RD_AMO_TX_ID = 1,
parameter int unsigned NC_ADDR_BEGIN = 40'h8000000000, // start address of noncacheable I/O region
parameter bit NC_ADDR_GE_LT = 1'b1 // determines how the physical address is compared with NC_ADDR_BEGIN
) (
input logic clk_i, // Clock
input logic rst_ni, // Asynchronous reset active low
// Cache management
input logic enable_i, // from CSR
input logic flush_i, // high until acknowledged
@ -32,10 +35,10 @@ module serpent_dcache #(
// AMO interface
input amo_req_t amo_req_i,
output amo_resp_t amo_resp_o,
// Request ports
input dcache_req_i_t [2:0] req_ports_i,
output dcache_req_o_t [2:0] req_ports_o,
input dcache_req_i_t [2:0] req_ports_i,
output dcache_req_o_t [2:0] req_ports_o,
input logic mem_rtrn_vld_i,
input dcache_rtrn_t mem_rtrn_i,
@ -43,8 +46,8 @@ module serpent_dcache #(
input logic mem_data_ack_i,
output dcache_req_t mem_data_o
);
// LD unit and PTW
// LD unit and PTW
localparam NUM_PORTS = 3;
// miss unit <-> read controllers
@ -66,7 +69,7 @@ module serpent_dcache #(
logic [DCACHE_OFFSET_WIDTH-1:0] wr_off;
logic [63:0] wr_data;
logic [7:0] wr_data_be;
// miss unit <-> controllers/wbuffer
logic [NUM_PORTS-1:0] miss_req;
logic [NUM_PORTS-1:0] miss_ack;
@ -76,11 +79,11 @@ module serpent_dcache #(
logic [NUM_PORTS-1:0][63:0] miss_paddr;
logic [NUM_PORTS-1:0][DCACHE_SET_ASSOC-1:0] miss_vld_bits;
logic [NUM_PORTS-1:0][2:0] miss_size;
logic [NUM_PORTS-1:0][DCACHE_ID_WIDTH-1:0] miss_wr_id;
logic [NUM_PORTS-1:0][DCACHE_ID_WIDTH-1:0] miss_id;
logic [NUM_PORTS-1:0] miss_replay;
logic [NUM_PORTS-1:0] miss_rtrn_vld;
logic [DCACHE_ID_WIDTH-1:0] miss_rtrn_id;
// memory <-> read controllers/miss unit
logic [NUM_PORTS-1:0] rd_prio;
logic [NUM_PORTS-1:0] rd_tag_only;
@ -93,20 +96,21 @@ module serpent_dcache #(
logic [DCACHE_SET_ASSOC-1:0] rd_vld_bits;
logic [DCACHE_SET_ASSOC-1:0] rd_hit_oh;
// miss unit <-> wbuffer
logic [DCACHE_MAX_TX-1:0][63:0] tx_paddr;
logic [DCACHE_MAX_TX-1:0] tx_vld;
// wbuffer <-> memory
// miss unit <-> wbuffer
logic [DCACHE_MAX_TX-1:0][63:0] tx_paddr;
logic [DCACHE_MAX_TX-1:0] tx_vld;
// wbuffer <-> memory
wbuffer_t [DCACHE_WBUF_DEPTH-1:0] wbuffer_data;
///////////////////////////////////////////////////////
// miss handling unit
///////////////////////////////////////////////////////
serpent_dcache_missunit #(
.NUM_PORTS(NUM_PORTS)
.AMO_TX_ID( RD_AMO_TX_ID ),
.NUM_PORTS( NUM_PORTS )
) i_serpent_dcache_missunit (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
@ -116,10 +120,10 @@ module serpent_dcache #(
.miss_o ( miss_o ),
.wbuffer_empty_i ( wbuffer_empty_o ),
.cache_en_o ( cache_en ),
// amo interface
// amo interface
.amo_req_i ( amo_req_i ),
.amo_resp_o ( amo_resp_o ),
// miss handling interface
// miss handling interface
.miss_req_i ( miss_req ),
.miss_ack_o ( miss_ack ),
.miss_nc_i ( miss_nc ),
@ -128,14 +132,14 @@ module serpent_dcache #(
.miss_paddr_i ( miss_paddr ),
.miss_vld_bits_i ( miss_vld_bits ),
.miss_size_i ( miss_size ),
.miss_wr_id_i ( miss_wr_id ),
.miss_id_i ( miss_id ),
.miss_replay_o ( miss_replay ),
.miss_rtrn_vld_o ( miss_rtrn_vld ),
.miss_rtrn_id_o ( miss_rtrn_id ),
// from writebuffer
.tx_paddr_i ( tx_paddr ),
.tx_vld_i ( tx_vld ),
// cache memory interface
// cache memory interface
.wr_cl_vld_o ( wr_cl_vld ),
.wr_cl_nc_o ( wr_cl_nc ),
.wr_cl_we_o ( wr_cl_we ),
@ -145,7 +149,7 @@ module serpent_dcache #(
.wr_cl_data_o ( wr_cl_data ),
.wr_cl_data_be_o ( wr_cl_data_be ),
.wr_vld_bits_o ( wr_vld_bits ),
// memory interface
// memory interface
.mem_rtrn_vld_i ( mem_rtrn_vld_i ),
.mem_rtrn_i ( mem_rtrn_i ),
.mem_data_req_o ( mem_data_req_o ),
@ -162,10 +166,11 @@ module serpent_dcache #(
for(genvar k=0; k<NUM_PORTS-1; k++) begin
// set these to high prio ports
assign rd_prio[k] = 1'b1;
serpent_dcache_ctrl #(
.NC_ADDR_BEGIN(NC_ADDR_BEGIN),
.NC_ADDR_GE_LT(NC_ADDR_GE_LT))
.RD_TX_ID ( RD_AMO_TX_ID ),
.NC_ADDR_BEGIN ( NC_ADDR_BEGIN ),
.NC_ADDR_GE_LT ( NC_ADDR_GE_LT ))
i_serpent_dcache_ctrl (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
@ -173,7 +178,7 @@ module serpent_dcache #(
// reqs from core
.req_port_i ( req_ports_i [k] ),
.req_port_o ( req_ports_o [k] ),
// miss interface
// miss interface
.miss_req_o ( miss_req [k] ),
.miss_ack_i ( miss_ack [k] ),
.miss_we_o ( miss_we [k] ),
@ -182,12 +187,12 @@ module serpent_dcache #(
.miss_paddr_o ( miss_paddr [k] ),
.miss_nc_o ( miss_nc [k] ),
.miss_size_o ( miss_size [k] ),
.miss_wr_id_o ( miss_wr_id [k] ),
.miss_id_o ( miss_id [k] ),
.miss_replay_i ( miss_replay [k] ),
.miss_rtrn_vld_i ( miss_rtrn_vld [k] ),
// used to detect readout mux collisions
.wr_cl_vld_i ( wr_cl_vld ),
// cache mem interface
// cache mem interface
.rd_tag_o ( rd_tag [k] ),
.rd_idx_o ( rd_idx [k] ),
.rd_off_o ( rd_off [k] ),
@ -204,13 +209,13 @@ module serpent_dcache #(
///////////////////////////////////////////////////////
// store unit controller
///////////////////////////////////////////////////////
// set read port to low priority
assign rd_prio[2] = 1'b0;
serpent_dcache_wbuffer #(
.NC_ADDR_BEGIN ( NC_ADDR_BEGIN ),
.NC_ADDR_GE_LT ( NC_ADDR_GE_LT ))
.NC_ADDR_BEGIN ( NC_ADDR_BEGIN ),
.NC_ADDR_GE_LT ( NC_ADDR_GE_LT ))
i_serpent_dcache_wbuffer (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
@ -221,7 +226,7 @@ module serpent_dcache #(
// request ports from core (store unit)
.req_port_i ( req_ports_i [2] ),
.req_port_o ( req_ports_o [2] ),
// miss unit interface
// miss unit interface
.miss_req_o ( miss_req [2] ),
.miss_ack_i ( miss_ack [2] ),
.miss_we_o ( miss_we [2] ),
@ -230,10 +235,10 @@ module serpent_dcache #(
.miss_paddr_o ( miss_paddr [2] ),
.miss_nc_o ( miss_nc [2] ),
.miss_size_o ( miss_size [2] ),
.miss_wr_id_o ( miss_wr_id [2] ),
.miss_id_o ( miss_id [2] ),
.miss_rtrn_vld_i ( miss_rtrn_vld [2] ),
.miss_rtrn_id_i ( miss_rtrn_id ),
// cache read interface
// cache read interface
.rd_tag_o ( rd_tag [2] ),
.rd_idx_o ( rd_idx [2] ),
.rd_off_o ( rd_off [2] ),
@ -310,13 +315,13 @@ module serpent_dcache #(
//pragma translate_off
`ifndef VERILATOR
flush: assert property (
@(posedge clk_i) disable iff (~rst_ni) flush_i |-> flush_ack_o |-> wbuffer_empty_o)
@(posedge clk_i) disable iff (~rst_ni) flush_i |-> flush_ack_o |-> wbuffer_empty_o)
else $fatal(1,"[l1 dcache] flushed cache implies flushed wbuffer");
initial begin
// assert wrong parameterizations
assert (DCACHE_INDEX_WIDTH<=12)
else $fatal(1,"[l1 dcache] cache index width can be maximum 12bit since VM uses 4kB pages");
assert (DCACHE_INDEX_WIDTH<=12)
else $fatal(1,"[l1 dcache] cache index width can be maximum 12bit since VM uses 4kB pages");
end
`endif
//pragma translate_on

View file

@ -17,36 +17,37 @@ import ariane_pkg::*;
import serpent_cache_pkg::*;
module serpent_dcache_ctrl #(
parameter NC_ADDR_BEGIN = 40'h8000000000, // start address of noncacheable I/O region
parameter bit NC_ADDR_GE_LT = 1'b1 // determines how the physical address is compared with NC_ADDR_BEGIN
)(
parameter logic [DCACHE_ID_WIDTH-1:0] RD_TX_ID = 1, // ID to use for read transactions
parameter int unsigned NC_ADDR_BEGIN = 40'h8000000000, // start address of noncacheable I/O region
parameter bit NC_ADDR_GE_LT = 1'b1 // determines how the physical address is compared with NC_ADDR_BEGIN
) (
input logic clk_i, // Clock
input logic rst_ni, // Asynchronous reset active low
input logic cache_en_i,
// core request ports
input dcache_req_i_t req_port_i,
output dcache_req_o_t req_port_o,
input dcache_req_i_t req_port_i,
output dcache_req_o_t req_port_o,
// interface to miss handler
output logic miss_req_o,
input logic miss_ack_i,
input logic miss_ack_i,
output logic miss_we_o, // unused (set to 0)
output logic [63:0] miss_wdata_o, // unused (set to 0)
output logic [DCACHE_SET_ASSOC-1:0] miss_vld_bits_o, // valid bits at the missed index
output logic [63:0] miss_paddr_o,
output logic [DCACHE_SET_ASSOC-1:0] miss_vld_bits_o, // valid bits at the missed index
output logic [63:0] miss_paddr_o,
output logic miss_nc_o, // request to I/O space
output logic [2:0] miss_size_o, // 00: 1byte, 01: 2byte, 10: 4byte, 11: 8byte, 111: cacheline
output logic [DCACHE_ID_WIDTH-1:0] miss_wr_id_o, // unused (set to 0)
input logic miss_replay_i, // request collided with pending miss - have to replay the request
output logic [2:0] miss_size_o, // 00: 1byte, 01: 2byte, 10: 4byte, 11: 8byte, 111: cacheline
output logic [DCACHE_ID_WIDTH-1:0] miss_id_o, // set to constant ID
input logic miss_replay_i, // request collided with pending miss - have to replay the request
input logic miss_rtrn_vld_i, // signals that the miss has been served, asserted in the same cycle as when the data returns from memory
// used to detect readout mux collisions
input logic wr_cl_vld_i,
// cache memory interface
output logic [DCACHE_TAG_WIDTH-1:0] rd_tag_o, // tag in - comes one cycle later
output logic [DCACHE_CL_IDX_WIDTH-1:0] rd_idx_o,
output logic [DCACHE_OFFSET_WIDTH-1:0] rd_off_o,
output logic [DCACHE_CL_IDX_WIDTH-1:0] rd_idx_o,
output logic [DCACHE_OFFSET_WIDTH-1:0] rd_off_o,
output logic rd_req_o, // read the word at offset off_i[:3] in all ways
output logic rd_tag_only_o, // set to zero here
input logic rd_ack_i,
input logic rd_ack_i,
input logic [63:0] rd_data_i,
input logic [DCACHE_SET_ASSOC-1:0] rd_vld_bits_i,
input logic [DCACHE_SET_ASSOC-1:0] rd_hit_oh_i
@ -62,7 +63,7 @@ module serpent_dcache_ctrl #(
logic [DCACHE_SET_ASSOC-1:0] vld_data_d, vld_data_q;
logic save_tag, rd_req_d, rd_req_q, rd_ack_d, rd_ack_q;
logic [1:0] data_size_d, data_size_q;
///////////////////////////////////////////////////////
// misc
///////////////////////////////////////////////////////
@ -78,28 +79,28 @@ module serpent_dcache_ctrl #(
assign rd_off_o = address_off_d;
assign req_port_o.data_rdata = rd_data_i;
// to miss unit
assign miss_vld_bits_o = vld_data_q;
assign miss_paddr_o = {address_tag_q, address_idx_q, address_off_q};
assign miss_size_o = (miss_nc_o) ? data_size_q : 3'b111;
generate
generate
if (NC_ADDR_GE_LT) begin : g_nc_addr_high
assign miss_nc_o = (address_tag_q >= (NC_ADDR_BEGIN>>DCACHE_INDEX_WIDTH)) | ~cache_en_i;
end
if (~NC_ADDR_GE_LT) begin : g_nc_addr_low
assign miss_nc_o = (address_tag_q < (NC_ADDR_BEGIN>>DCACHE_INDEX_WIDTH)) | ~cache_en_i;
end
endgenerate
endgenerate
assign miss_we_o = '0;
assign miss_wdata_o = '0;
assign miss_wr_id_o = '0;
assign miss_wdata_o = '0;
assign miss_id_o = RD_TX_ID;
assign rd_req_d = rd_req_o;
assign rd_ack_d = rd_ack_i;
assign rd_tag_only_o = '0;
///////////////////////////////////////////////////////
// main control logic
///////////////////////////////////////////////////////
@ -112,13 +113,13 @@ module serpent_dcache_ctrl #(
miss_req_o = 1'b0;
req_port_o.data_rvalid = 1'b0;
req_port_o.data_gnt = 1'b0;
// interfaces
unique case (state_q)
// interfaces
unique case (state_q)
//////////////////////////////////
// wait for an incoming request
IDLE: begin
if (req_port_i.data_req) begin
rd_req_o = 1'b1;
@ -126,7 +127,7 @@ module serpent_dcache_ctrl #(
state_d = READ;
req_port_o.data_gnt = 1'b1;
end
end
end
end
//////////////////////////////////
// check whether we have a hit
@ -137,7 +138,7 @@ module serpent_dcache_ctrl #(
READ, REPLAY_READ: begin
// speculatively request cache line
rd_req_o = 1'b1;
// kill -> go back to IDLE
if(req_port_i.kill_req) begin
state_d = IDLE;
@ -146,7 +147,7 @@ module serpent_dcache_ctrl #(
save_tag = (state_q!=REPLAY_READ);
if(wr_cl_vld_i | ~rd_ack_q) begin
state_d = REPLAY_REQ;
// we've got a hit
// we've got a hit
end else if((|rd_hit_oh_i) & cache_en_i) begin
state_d = IDLE;
req_port_o.data_rvalid = 1'b1;
@ -157,9 +158,9 @@ module serpent_dcache_ctrl #(
end
// we've got a miss
end else begin
state_d = MISS_REQ;
end
end
state_d = MISS_REQ;
end
end
end
//////////////////////////////////
// issue request
@ -170,18 +171,18 @@ module serpent_dcache_ctrl #(
req_port_o.data_rvalid = 1'b1;
if(miss_ack_i) begin
state_d = KILL_MISS;
end else begin
end else begin
state_d = IDLE;
end
end
end else if(miss_replay_i) begin
state_d = REPLAY_REQ;
end else if(miss_ack_i) begin
state_d = MISS_WAIT;
end
end
end
//////////////////////////////////
// wait until the memory transaction
// returns.
// returns.
MISS_WAIT: begin
if(req_port_i.kill_req) begin
req_port_o.data_rvalid = 1'b1;
@ -189,8 +190,8 @@ module serpent_dcache_ctrl #(
state_d = IDLE;
end else begin
state_d = KILL_MISS;
end
end else if(miss_rtrn_vld_i) begin
end
end else if(miss_rtrn_vld_i) begin
state_d = IDLE;
req_port_o.data_rvalid = 1'b1;
end
@ -204,16 +205,16 @@ module serpent_dcache_ctrl #(
state_d = IDLE;
end else if(rd_ack_i) begin
state_d = REPLAY_READ;
end
end
end
end
//////////////////////////////////
// killed miss,
// wait until miss unit responds and
// wait until miss unit responds and
// go back to idle
KILL_MISS: begin
if (miss_rtrn_vld_i) begin
state_d = IDLE;
end
end
end
default: begin
// we should never get here
@ -229,7 +230,7 @@ module serpent_dcache_ctrl #(
always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
if(~rst_ni) begin
state_q <= IDLE;
address_tag_q <= '0;
address_tag_q <= '0;
address_idx_q <= '0;
address_off_q <= '0;
vld_data_q <= '0;
@ -238,7 +239,7 @@ always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
rd_ack_q <= '0;
end else begin
state_q <= state_d;
address_tag_q <= address_tag_d;
address_tag_q <= address_tag_d;
address_idx_q <= address_idx_d;
address_off_q <= address_off_d;
vld_data_q <= vld_data_d;
@ -255,15 +256,15 @@ end
//pragma translate_off
`ifndef VERILATOR
hot1: assert property (
@(posedge clk_i) disable iff (~rst_ni) (~rd_ack_i) |=> cache_en_i |-> $onehot0(rd_hit_oh_i))
@(posedge clk_i) disable iff (~rst_ni) (~rd_ack_i) |=> cache_en_i |-> $onehot0(rd_hit_oh_i))
else $fatal(1,"[l1 dcache ctrl] rd_hit_oh_i signal must be hot1");
initial begin
// assert wrong parameterizations
assert (DCACHE_INDEX_WIDTH<=12)
else $fatal(1,"[l1 dcache ctrl] cache index width can be maximum 12bit since VM uses 4kB pages");
assert (DCACHE_INDEX_WIDTH<=12)
else $fatal(1,"[l1 dcache ctrl] cache index width can be maximum 12bit since VM uses 4kB pages");
end
`endif
//pragma translate_on

View file

@ -18,8 +18,9 @@ import ariane_pkg::*;
import serpent_cache_pkg::*;
module serpent_dcache_missunit #(
parameter NUM_PORTS = 3
)(
parameter logic [DCACHE_ID_WIDTH-1:0] AMO_TX_ID = 1, // TX id to be used for AMOs
parameter int unsigned NUM_PORTS = 3 // number of miss ports
) (
input logic clk_i, // Clock
input logic rst_ni, // Asynchronous reset active low
// cache management, signals from/to core
@ -42,7 +43,7 @@ module serpent_dcache_missunit #(
input logic [NUM_PORTS-1:0][63:0] miss_paddr_i,
input logic [NUM_PORTS-1:0][DCACHE_SET_ASSOC-1:0] miss_vld_bits_i,
input logic [NUM_PORTS-1:0][2:0] miss_size_i,
input logic [NUM_PORTS-1:0][DCACHE_ID_WIDTH-1:0] miss_wr_id_i, // only used for writes, set to zero fro reads
input logic [NUM_PORTS-1:0][DCACHE_ID_WIDTH-1:0] miss_id_i, // used as transaction ID
// signals that the request collided with a pending read
output logic [NUM_PORTS-1:0] miss_replay_o,
// signals response from memory
@ -163,7 +164,7 @@ module serpent_dcache_missunit #(
assign mshr_d.size = (mshr_allocate) ? miss_size_i [miss_port_idx] : mshr_q.size;
assign mshr_d.paddr = (mshr_allocate) ? miss_paddr_i [miss_port_idx] : mshr_q.paddr;
assign mshr_d.vld_bits = (mshr_allocate) ? miss_vld_bits_i[miss_port_idx] : mshr_q.vld_bits;
assign mshr_d.id = (mshr_allocate) ? miss_wr_id_i [miss_port_idx] : mshr_q.id;
assign mshr_d.id = (mshr_allocate) ? miss_id_i [miss_port_idx] : mshr_q.id;
assign mshr_d.nc = (mshr_allocate) ? miss_nc_i [miss_port_idx] : mshr_q.nc;
assign mshr_d.repl_way = (mshr_allocate) ? repl_way : mshr_q.repl_way;
assign mshr_d.miss_port_idx = (mshr_allocate) ? miss_port_idx : mshr_q.miss_port_idx;
@ -209,7 +210,7 @@ module serpent_dcache_missunit #(
mem_rtrn_i.data[63:0];
// outgoing memory requests (AMOs are always uncached)
assign mem_data_o.tid = (amo_sel) ? '0 : miss_wr_id_i[miss_port_idx];
assign mem_data_o.tid = (amo_sel) ? AMO_TX_ID : miss_id_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.data = (amo_sel) ? amo_data : miss_wdata_i[miss_port_idx];

View file

@ -52,9 +52,9 @@ import ariane_pkg::*;
import serpent_cache_pkg::*;
module serpent_dcache_wbuffer #(
parameter NC_ADDR_BEGIN = 40'h8000000000, // start address of noncacheable I/O region
parameter bit NC_ADDR_GE_LT = 1'b1 // determines how the physical address is compared with NC_ADDR_BEGIN
)(
parameter int unsigned NC_ADDR_BEGIN = 40'h8000000000, // start address of noncacheable I/O region
parameter bit NC_ADDR_GE_LT = 1'b1 // determines how the physical address is compared with NC_ADDR_BEGIN
) (
input logic clk_i, // Clock
input logic rst_ni, // Asynchronous reset active low
@ -72,10 +72,10 @@ module serpent_dcache_wbuffer #(
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, //
output logic [DCACHE_ID_WIDTH-1:0] miss_wr_id_o, // id of this transaction
output logic [DCACHE_ID_WIDTH-1:0] miss_id_o, // ID of this transaction (wbuffer uses all IDs from 0 to DCACHE_MAX_TX-1)
// write responses from memory
input logic miss_rtrn_vld_i,
input logic [DCACHE_ID_WIDTH-1:0] miss_rtrn_id_i, // transaction id to clear
input logic [DCACHE_ID_WIDTH-1:0] miss_rtrn_id_i, // transaction ID to clear
// cache read interface
output logic [DCACHE_TAG_WIDTH-1:0] rd_tag_o, // tag in - comes one cycle later
output logic [DCACHE_CL_IDX_WIDTH-1:0] rd_idx_o,
@ -178,7 +178,7 @@ lzc #(
// add the offset to the physical base address of this buffer entry
assign miss_paddr_o = {wbuffer_q[dirty_ptr].wtag, bdirty_off};
assign miss_wr_id_o = tx_id;
assign miss_id_o = tx_id;
// is there any dirty word to be transmitted, and is there a free TX slot?
assign miss_req_o = (|dirty) && free_tx_slots;

View file

@ -32,11 +32,12 @@ import ariane_pkg::*;
import serpent_cache_pkg::*;
module serpent_icache #(
parameter bit AXI64BIT_COMPLIANT = 1'b0, // set this to 1 when using in conjunction with 64bit AXI bus adapter
parameter NC_ADDR_BEGIN = 40'h8000000000, // start address of noncacheable I/O region
parameter bit NC_ADDR_GE_LT = 1'b1 // determines how the physical address is compared with NC_ADDR_BEGIN
// NC_ADDR_GE_LT == 0 -> if paddr < NC_ADDR_BEGIN -> NC
// NC_ADDR_GE_LT == 1 -> if paddr >= NC_ADDR_BEGIN -> NC
parameter logic [DCACHE_ID_WIDTH-1:0] RD_TX_ID = 0, // ID to be used for read transactions
parameter int unsigned NC_ADDR_BEGIN = 40'h8000000000, // start address of noncacheable I/O region
parameter bit AXI64BIT_COMPLIANT = 1'b0, // set this to 1 when using in conjunction with 64bit AXI bus adapter
parameter bit NC_ADDR_GE_LT = 1'b1 // determines how the physical address is compared with NC_ADDR_BEGIN
// NC_ADDR_GE_LT == 0 -> if paddr < NC_ADDR_BEGIN -> NC
// NC_ADDR_GE_LT == 1 -> if paddr >= NC_ADDR_BEGIN -> NC
)(
input logic clk_i,
input logic rst_ni,
@ -150,8 +151,7 @@ module serpent_icache #(
end
endgenerate
// currently we can only have one outstanding tx here
assign mem_data_o.tid = '0;
assign mem_data_o.tid = RD_TX_ID;
assign mem_data_o.nc = paddr_is_nc;
// way that is being replaced

@ -1 +1 @@
Subproject commit 00e2579173f1412f06d4eb95d6b98d0eb1cd2e94
Subproject commit 1801c5e0ea231f83e9ba5422b9a7a4feaaad879f