mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-24 14:17:16 -04:00
Make appropriate AXI size requests
This commit is contained in:
parent
cb04234629
commit
11b03190f2
11 changed files with 89 additions and 31 deletions
|
@ -104,6 +104,20 @@ package ariane_pkg;
|
|||
DIV, DIVU, DIVW, DIVUW, REM, REMU, REMW, REMUW
|
||||
} fu_op;
|
||||
|
||||
// ----------------------
|
||||
// Extract Bytes from Op
|
||||
// ----------------------
|
||||
// TODO: Add atomics
|
||||
function automatic logic [1:0] extract_transfer_size (fu_op op);
|
||||
case (op)
|
||||
LD, SD: return 2'b11;
|
||||
LW, LWU, SW: return 2'b10;
|
||||
LH, LHU, SH: return 2'b01;
|
||||
LB, SB, LBU: return 2'b00;
|
||||
default: return 2'b11;
|
||||
endcase
|
||||
endfunction
|
||||
|
||||
typedef struct packed {
|
||||
logic valid;
|
||||
logic [63:0] vaddr;
|
||||
|
@ -393,7 +407,7 @@ package ariane_pkg;
|
|||
|
||||
// ----------------------
|
||||
// Arithmetic Functions
|
||||
// ----------------------s
|
||||
// ----------------------
|
||||
function automatic logic [63:0] sext32 (logic [31:0] operand);
|
||||
return {{32{operand[31]}}, operand[31:0]};
|
||||
endfunction
|
||||
|
|
|
@ -38,11 +38,12 @@ package nbdcache_pkg;
|
|||
|
||||
typedef struct packed {
|
||||
logic valid;
|
||||
logic bypass;
|
||||
logic [63:0] addr;
|
||||
logic [7:0] be;
|
||||
logic [1:0] size;
|
||||
logic we;
|
||||
logic [63:0] wdata;
|
||||
logic bypass;
|
||||
} miss_req_t;
|
||||
|
||||
typedef struct packed {
|
||||
|
|
|
@ -28,6 +28,7 @@ module cache_ctrl #(
|
|||
input logic data_req_i,
|
||||
input logic data_we_i,
|
||||
input logic [7:0] data_be_i,
|
||||
input logic [1:0] data_size_i,
|
||||
input logic kill_req_i,
|
||||
input logic tag_valid_i,
|
||||
output logic data_gnt_o,
|
||||
|
@ -67,6 +68,7 @@ module cache_ctrl #(
|
|||
logic [INDEX_WIDTH-1:0] index;
|
||||
logic [TAG_WIDTH-1:0] tag;
|
||||
logic [7:0] be;
|
||||
logic [1:0] size;
|
||||
logic we;
|
||||
logic [63:0] wdata;
|
||||
logic bypass;
|
||||
|
@ -118,6 +120,7 @@ module cache_ctrl #(
|
|||
mem_req_d.index = address_index_i;
|
||||
mem_req_d.tag = address_tag_i;
|
||||
mem_req_d.be = data_be_i;
|
||||
mem_req_d.size = data_size_i;
|
||||
mem_req_d.we = data_we_i;
|
||||
mem_req_d.wdata = data_wdata_i;
|
||||
// TODO: Check for non-cache able accesses
|
||||
|
@ -164,6 +167,7 @@ module cache_ctrl #(
|
|||
state_d = WAIT_TAG; // switch back to WAIT_TAG
|
||||
mem_req_d.index = address_index_i;
|
||||
mem_req_d.be = data_be_i;
|
||||
mem_req_d.size = data_size_i;
|
||||
mem_req_d.we = data_we_i;
|
||||
mem_req_d.wdata = data_wdata_i;
|
||||
mem_req_d.tag = address_tag_i;
|
||||
|
@ -290,13 +294,16 @@ module cache_ctrl #(
|
|||
miss_req_o.bypass = mem_req_q.bypass;
|
||||
miss_req_o.addr = {mem_req_q.tag, mem_req_q.index};
|
||||
miss_req_o.be = mem_req_q.be;
|
||||
miss_req_o.size = mem_req_q.size;
|
||||
miss_req_o.we = mem_req_q.we;
|
||||
miss_req_o.wdata = mem_req_q.wdata;
|
||||
|
||||
// got a grant so go to valid
|
||||
if (bypass_gnt_i) begin
|
||||
state_d = WAIT_REFILL_VALID;
|
||||
data_gnt_o = 1'b1;
|
||||
// if this was a write we still need to give a grant to the store unit
|
||||
if (mem_req_q.we)
|
||||
data_gnt_o = 1'b1;
|
||||
end
|
||||
|
||||
if (miss_gnt_i && !mem_req_q.we)
|
||||
|
@ -317,8 +324,9 @@ module cache_ctrl #(
|
|||
if (data_req_i) begin
|
||||
// save index, be and we
|
||||
mem_req_d.index = address_index_i;
|
||||
mem_req_d.be = data_be_i;
|
||||
mem_req_d.we = data_we_i;
|
||||
mem_req_d.be = data_be_i;
|
||||
mem_req_d.size = data_size_i;
|
||||
mem_req_d.we = data_we_i;
|
||||
mem_req_d.wdata = data_wdata_i;
|
||||
mem_req_d.tag = address_tag_i;
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ module load_unit (
|
|||
output logic data_req_o,
|
||||
output logic data_we_o,
|
||||
output logic [7:0] data_be_o,
|
||||
output logic [1:0] data_size_o,
|
||||
output logic kill_req_o,
|
||||
output logic tag_valid_o,
|
||||
input logic data_gnt_i,
|
||||
|
@ -92,6 +93,7 @@ module load_unit (
|
|||
kill_req_o = 1'b0;
|
||||
tag_valid_o = 1'b0;
|
||||
data_be_o = lsu_ctrl_i.be;
|
||||
data_size_o = extract_transfer_size(lsu_ctrl_i.operator);
|
||||
pop_ld_o = 1'b0;
|
||||
|
||||
case (CS)
|
||||
|
|
|
@ -133,6 +133,8 @@ module lsu #(
|
|||
logic [2:0][63:0] data_wdata_i;
|
||||
logic [2:0] data_req_i;
|
||||
logic [2:0] data_we_i;
|
||||
logic [2:0][1:0] data_size_i;
|
||||
|
||||
logic [2:0] kill_req_i;
|
||||
logic [2:0] tag_valid_i;
|
||||
logic [2:0][7:0] data_be_i;
|
||||
|
@ -163,6 +165,7 @@ module lsu #(
|
|||
.data_req_i ( data_req_i ),
|
||||
.data_we_i ( data_we_i ),
|
||||
.data_be_i ( data_be_i ),
|
||||
.data_size_i ( data_size_i ),
|
||||
.kill_req_i ( kill_req_i ),
|
||||
.tag_valid_i ( tag_valid_i ),
|
||||
.data_gnt_o ( data_gnt_o ),
|
||||
|
@ -202,6 +205,7 @@ module lsu #(
|
|||
.data_req_o ( data_req_i [0] ),
|
||||
.data_we_o ( data_we_i [0] ),
|
||||
.data_be_o ( data_be_i [0] ),
|
||||
.data_size_o ( data_size_i [0] ),
|
||||
.kill_req_o ( kill_req_i [0] ),
|
||||
.tag_valid_o ( tag_valid_i [0] ),
|
||||
.data_gnt_i ( data_gnt_o [0] ),
|
||||
|
@ -237,6 +241,7 @@ module lsu #(
|
|||
.data_req_o ( data_req_i [2] ),
|
||||
.data_we_o ( data_we_i [2] ),
|
||||
.data_be_o ( data_be_i [2] ),
|
||||
.data_size_o ( data_size_i [2] ),
|
||||
.kill_req_o ( kill_req_i [2] ),
|
||||
.tag_valid_o ( tag_valid_i [2] ),
|
||||
.data_gnt_i ( data_gnt_o [2] ),
|
||||
|
@ -273,6 +278,7 @@ module lsu #(
|
|||
.data_req_o ( data_req_i [1] ),
|
||||
.data_we_o ( data_we_i [1] ),
|
||||
.data_be_o ( data_be_i [1] ),
|
||||
.data_size_o ( data_size_i [1] ),
|
||||
.kill_req_o ( kill_req_i [1] ),
|
||||
.tag_valid_o ( tag_valid_i [1] ),
|
||||
.data_gnt_i ( data_gnt_o [1] ),
|
||||
|
|
|
@ -57,6 +57,7 @@ module miss_handler #(
|
|||
logic [NR_PORTS-1:0][63:0] miss_req_wdata;
|
||||
logic [NR_PORTS-1:0] miss_req_we;
|
||||
logic [NR_PORTS-1:0][7:0] miss_req_be;
|
||||
logic [NR_PORTS-1:0][1:0] miss_req_size;
|
||||
|
||||
// Cache Line Refill <-> AXI
|
||||
logic req_fsm_miss_valid;
|
||||
|
@ -340,17 +341,17 @@ module miss_handler #(
|
|||
// Bypass Arbiter
|
||||
// ----------------------
|
||||
// Connection Arbiter <-> AXI
|
||||
logic req_fsm_bypass_valid;
|
||||
logic [63:0] req_fsm_bypass_addr;
|
||||
logic [63:0] req_fsm_bypass_wdata;
|
||||
logic req_fsm_bypass_we;
|
||||
logic [7:0] req_fsm_bypass_be;
|
||||
|
||||
logic gnt_bypass_fsm;
|
||||
logic valid_bypass_fsm;
|
||||
logic [63:0] data_bypass_fsm;
|
||||
logic [$clog2(NR_PORTS)-1:0] id_fsm_bypass;
|
||||
logic [AXI_ID_WIDTH-1:0] id_bypass_fsm;
|
||||
logic req_fsm_bypass_valid;
|
||||
logic [63:0] req_fsm_bypass_addr;
|
||||
logic [63:0] req_fsm_bypass_wdata;
|
||||
logic req_fsm_bypass_we;
|
||||
logic [7:0] req_fsm_bypass_be;
|
||||
logic [1:0] req_fsm_bypass_size;
|
||||
logic gnt_bypass_fsm;
|
||||
logic valid_bypass_fsm;
|
||||
logic [63:0] data_bypass_fsm;
|
||||
logic [$clog2(NR_PORTS)-1:0] id_fsm_bypass;
|
||||
logic [AXI_ID_WIDTH-1:0] id_bypass_fsm;
|
||||
|
||||
arbiter #(
|
||||
.NR_PORTS ( NR_PORTS ),
|
||||
|
@ -362,6 +363,7 @@ module miss_handler #(
|
|||
.data_wdata_i ( miss_req_wdata ),
|
||||
.data_we_i ( miss_req_we ),
|
||||
.data_be_i ( miss_req_be ),
|
||||
.data_size_i ( miss_req_size ),
|
||||
.data_gnt_o ( bypass_gnt_o ),
|
||||
.data_rvalid_o ( bypass_valid_o ),
|
||||
.data_rdata_o ( bypass_data_o ),
|
||||
|
@ -373,6 +375,7 @@ module miss_handler #(
|
|||
.data_req_o ( req_fsm_bypass_valid ),
|
||||
.data_we_o ( req_fsm_bypass_we ),
|
||||
.data_be_o ( req_fsm_bypass_be ),
|
||||
.data_size_o ( req_fsm_bypass_size ),
|
||||
.data_gnt_i ( gnt_bypass_fsm ),
|
||||
.data_rvalid_i ( valid_bypass_fsm ),
|
||||
.data_rdata_i ( data_bypass_fsm ),
|
||||
|
@ -389,6 +392,7 @@ module miss_handler #(
|
|||
.we_i ( req_fsm_bypass_we ),
|
||||
.wdata_i ( req_fsm_bypass_wdata ),
|
||||
.be_i ( req_fsm_bypass_be ),
|
||||
.size_i ( req_fsm_bypass_size ),
|
||||
.id_i ( {{{AXI_ID_WIDTH-$clog2(NR_PORTS)}{1'b0}}, id_fsm_bypass} ),
|
||||
.valid_o ( valid_bypass_fsm ),
|
||||
.rdata_o ( data_bypass_fsm ),
|
||||
|
@ -412,6 +416,7 @@ module miss_handler #(
|
|||
.we_i ( req_fsm_miss_we ),
|
||||
.wdata_i ( req_fsm_miss_wdata ),
|
||||
.be_i ( req_fsm_miss_be ),
|
||||
.size_i ( 2'b11 ),
|
||||
.id_i ( '0 ),
|
||||
.valid_o ( valid_miss_fsm ),
|
||||
.rdata_o ( data_miss_fsm ),
|
||||
|
@ -445,6 +450,7 @@ module miss_handler #(
|
|||
miss_req_wdata [i] = miss_req.wdata;
|
||||
miss_req_we [i] = miss_req.we;
|
||||
miss_req_be [i] = miss_req.be;
|
||||
miss_req_size [i] = miss_req.size;
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -474,6 +480,7 @@ module arbiter #(
|
|||
input logic [NR_PORTS-1:0][DATA_WIDTH-1:0] data_wdata_i,
|
||||
input logic [NR_PORTS-1:0] data_we_i,
|
||||
input logic [NR_PORTS-1:0][DATA_WIDTH/8-1:0] data_be_i,
|
||||
input logic [NR_PORTS-1:0][1:0] data_size_i,
|
||||
output logic [NR_PORTS-1:0] data_gnt_o,
|
||||
output logic [NR_PORTS-1:0] data_rvalid_o,
|
||||
output logic [NR_PORTS-1:0][DATA_WIDTH-1:0] data_rdata_o,
|
||||
|
@ -485,6 +492,7 @@ module arbiter #(
|
|||
output logic [DATA_WIDTH-1:0] data_wdata_o,
|
||||
output logic data_we_o,
|
||||
output logic [DATA_WIDTH/8-1:0] data_be_o,
|
||||
output logic [1:0] data_size_o,
|
||||
input logic data_gnt_i,
|
||||
input logic data_rvalid_i,
|
||||
input logic [DATA_WIDTH-1:0] data_rdata_i
|
||||
|
@ -511,6 +519,7 @@ module arbiter #(
|
|||
address_o = address_i[request_index];
|
||||
data_wdata_o = data_wdata_i[request_index];
|
||||
data_be_o = data_be_i[request_index];
|
||||
data_size_o = data_size_i[request_index];
|
||||
data_we_o = data_we_i[request_index];
|
||||
data_gnt_o[request_index] = data_gnt_i;
|
||||
id_o = request_index;
|
||||
|
@ -569,6 +578,7 @@ module axi_adapter #(
|
|||
input logic we_i,
|
||||
input logic [(DATA_WIDTH/64)-1:0][63:0] wdata_i,
|
||||
input logic [(DATA_WIDTH/64)-1:0][7:0] be_i,
|
||||
input logic [1:0] size_i,
|
||||
input logic [AXI_ID_WIDTH-1:0] id_i,
|
||||
// read port
|
||||
output logic valid_o,
|
||||
|
@ -603,7 +613,7 @@ module axi_adapter #(
|
|||
axi.aw_prot = 3'b0;
|
||||
axi.aw_region = 4'b0;
|
||||
axi.aw_len = 8'b0;
|
||||
axi.aw_size = 3'b011; // 8 bytes
|
||||
axi.aw_size = {1'b0, size_i};
|
||||
axi.aw_burst = (req_i == SINGLE_REQ) ? 2'b00 : 2'b01; // fixed size for single request and incremental transfer for everything else
|
||||
axi.aw_lock = 1'b0;
|
||||
axi.aw_cache = 4'b0;
|
||||
|
@ -618,7 +628,7 @@ module axi_adapter #(
|
|||
axi.ar_prot = 3'b0;
|
||||
axi.ar_region = 4'b0;
|
||||
axi.ar_len = 8'b0;
|
||||
axi.ar_size = 3'b011; // 8 bytes
|
||||
axi.ar_size = {1'b0, size_i}; // 8 bytes
|
||||
axi.ar_burst = (req_i == SINGLE_REQ) ? 2'b00 : (CRITICAL_WORD_FIRST ? 2'b10 : 2'b01); // wrapping transfer in case of a critical word first strategy
|
||||
axi.ar_lock = 1'b0;
|
||||
axi.ar_cache = 4'b0;
|
||||
|
|
|
@ -81,6 +81,7 @@ module mmu #(
|
|||
output logic data_req_o,
|
||||
output logic data_we_o,
|
||||
output logic [7:0] data_be_o,
|
||||
output logic [1:0] data_size_o,
|
||||
output logic kill_req_o,
|
||||
output logic tag_valid_o,
|
||||
input logic data_gnt_i,
|
||||
|
|
|
@ -42,6 +42,7 @@ module nbdcache (
|
|||
input logic [2:0] data_req_i,
|
||||
input logic [2:0] data_we_i,
|
||||
input logic [2:0][7:0] data_be_i,
|
||||
input logic [2:0][1:0] data_size_i,
|
||||
input logic [2:0] kill_req_i,
|
||||
input logic [2:0] tag_valid_i,
|
||||
output logic [2:0] data_gnt_o,
|
||||
|
@ -111,6 +112,7 @@ module nbdcache (
|
|||
.data_req_i ( data_req_i [i] ),
|
||||
.data_we_i ( data_we_i [i] ),
|
||||
.data_be_i ( data_be_i [i] ),
|
||||
.data_size_i ( data_size_i [i] ),
|
||||
.kill_req_i ( kill_req_i [i] ),
|
||||
.tag_valid_i ( tag_valid_i [i] ),
|
||||
.data_gnt_o ( data_gnt_o [i] ),
|
||||
|
|
|
@ -44,6 +44,7 @@ module ptw #(
|
|||
output logic data_req_o,
|
||||
output logic data_we_o,
|
||||
output logic [7:0] data_be_o,
|
||||
output logic [1:0] data_size_o,
|
||||
output logic kill_req_o,
|
||||
output logic tag_valid_o,
|
||||
input logic data_gnt_i,
|
||||
|
@ -154,6 +155,7 @@ module ptw #(
|
|||
tag_valid_n = 1'b0;
|
||||
data_req_o = 1'b0;
|
||||
data_be_o = 8'hFF;
|
||||
data_size_o = 2'b11;
|
||||
data_we_o = 1'b0;
|
||||
ptw_error_o = 1'b0;
|
||||
itlb_update_o = 1'b0;
|
||||
|
|
|
@ -37,6 +37,7 @@ module store_buffer (
|
|||
input logic [63:0] paddr_i, // physical address of store which needs to be placed in the queue
|
||||
input logic [63:0] data_i, // data which is placed in the queue
|
||||
input logic [7:0] be_i, // byte enable in
|
||||
input logic [1:0] data_size_i, // type of request we are making (e.g.: bytes to write)
|
||||
|
||||
// D$ interface
|
||||
output logic [11:0] address_index_o,
|
||||
|
@ -45,6 +46,7 @@ module store_buffer (
|
|||
output logic data_req_o,
|
||||
output logic data_we_o,
|
||||
output logic [7:0] data_be_o,
|
||||
output logic [1:0] data_size_o,
|
||||
output logic kill_req_o,
|
||||
output logic tag_valid_o,
|
||||
input logic data_gnt_i,
|
||||
|
@ -63,6 +65,7 @@ module store_buffer (
|
|||
logic [63:0] address;
|
||||
logic [63:0] data;
|
||||
logic [7:0] be;
|
||||
logic [1:0] data_size;
|
||||
logic valid; // this entry is valid, we need this for checking if the address offset matches
|
||||
} speculative_queue_n [DEPTH_SPEC-1:0], speculative_queue_q [DEPTH_SPEC-1:0],
|
||||
commit_queue_n [DEPTH_COMMIT-1:0], commit_queue_q [DEPTH_COMMIT-1:0];
|
||||
|
@ -94,9 +97,10 @@ module store_buffer (
|
|||
// LSU interface
|
||||
// we are ready to accept a new entry and the input data is valid
|
||||
if (valid_i) begin
|
||||
speculative_queue_n[speculative_write_pointer_q].address = paddr_i;
|
||||
speculative_queue_n[speculative_write_pointer_q].data = data_i;
|
||||
speculative_queue_n[speculative_write_pointer_q].be = be_i;
|
||||
speculative_queue_n[speculative_write_pointer_q].address = paddr_i;
|
||||
speculative_queue_n[speculative_write_pointer_q].data = data_i;
|
||||
speculative_queue_n[speculative_write_pointer_q].be = be_i;
|
||||
speculative_queue_n[speculative_write_pointer_q].data_size = data_size_i;
|
||||
speculative_queue_n[speculative_write_pointer_q].valid = 1'b1;
|
||||
// advance the write pointer
|
||||
speculative_write_pointer_n = speculative_write_pointer_q + 1'b1;
|
||||
|
@ -137,6 +141,7 @@ module store_buffer (
|
|||
assign tag_valid_o = 1'b0;
|
||||
assign data_wdata_o = commit_queue_q[commit_read_pointer_q].data;
|
||||
assign data_be_o = commit_queue_q[commit_read_pointer_q].be;
|
||||
assign data_size_o = commit_queue_q[commit_read_pointer_q].data_size;
|
||||
// we will never kill a request in the store buffer since we already know that the translation is valid
|
||||
// e.g.: a kill request will only be necessary if we are not sure if the requested memory address will result in a TLB fault
|
||||
assign kill_req_o = 1'b0;
|
||||
|
|
|
@ -51,6 +51,7 @@ module store_unit (
|
|||
output logic data_req_o,
|
||||
output logic data_we_o,
|
||||
output logic [7:0] data_be_o,
|
||||
output logic [1:0] data_size_o,
|
||||
output logic kill_req_o,
|
||||
output logic tag_valid_o,
|
||||
input logic data_gnt_i,
|
||||
|
@ -67,6 +68,7 @@ module store_unit (
|
|||
// keep the data and the byte enable for the second cycle (after address translation)
|
||||
logic [63:0] st_data_n, st_data_q;
|
||||
logic [7:0] st_be_n, st_be_q;
|
||||
logic [1:0] st_data_size_n, st_data_size_q;
|
||||
logic [TRANS_ID_BITS-1:0] trans_id_n, trans_id_q;
|
||||
|
||||
// output assignments
|
||||
|
@ -175,8 +177,10 @@ module store_unit (
|
|||
// -----------
|
||||
// re-align the write data to comply with the address offset
|
||||
always_comb begin
|
||||
st_be_n = lsu_ctrl_i.be;
|
||||
st_data_n = lsu_ctrl_i.data;
|
||||
st_be_n = lsu_ctrl_i.be;
|
||||
st_data_n = lsu_ctrl_i.data;
|
||||
st_data_size_n = extract_transfer_size(lsu_ctrl_i.operator);
|
||||
|
||||
case (lsu_ctrl_i.vaddr[2:0])
|
||||
3'b000: st_data_n = lsu_ctrl_i.data;
|
||||
3'b001: st_data_n = {lsu_ctrl_i.data[55:0], lsu_ctrl_i.data[63:56]};
|
||||
|
@ -196,6 +200,7 @@ module store_unit (
|
|||
.valid_i ( st_valid ),
|
||||
.data_i ( st_data_q ),
|
||||
.be_i ( st_be_q ),
|
||||
.data_size_i ( st_data_size_q ),
|
||||
// store buffer out
|
||||
.ready_o ( st_ready ),
|
||||
.*
|
||||
|
@ -205,15 +210,17 @@ module store_unit (
|
|||
// ---------------
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if(~rst_ni) begin
|
||||
CS <= IDLE;
|
||||
st_be_q <= '0;
|
||||
st_data_q <= '0;
|
||||
trans_id_q <= '0;
|
||||
CS <= IDLE;
|
||||
st_be_q <= '0;
|
||||
st_data_q <= '0;
|
||||
st_data_size_q <= '0;
|
||||
trans_id_q <= '0;
|
||||
end else begin
|
||||
CS <= NS;
|
||||
st_be_q <= st_be_n;
|
||||
st_data_q <= st_data_n;
|
||||
trans_id_q <= trans_id_n;
|
||||
CS <= NS;
|
||||
st_be_q <= st_be_n;
|
||||
st_data_q <= st_data_n;
|
||||
trans_id_q <= trans_id_n;
|
||||
st_data_size_q <= st_data_size_n;
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue