mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-25 06:37:14 -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
|
DIV, DIVU, DIVW, DIVUW, REM, REMU, REMW, REMUW
|
||||||
} fu_op;
|
} 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 {
|
typedef struct packed {
|
||||||
logic valid;
|
logic valid;
|
||||||
logic [63:0] vaddr;
|
logic [63:0] vaddr;
|
||||||
|
@ -393,7 +407,7 @@ package ariane_pkg;
|
||||||
|
|
||||||
// ----------------------
|
// ----------------------
|
||||||
// Arithmetic Functions
|
// Arithmetic Functions
|
||||||
// ----------------------s
|
// ----------------------
|
||||||
function automatic logic [63:0] sext32 (logic [31:0] operand);
|
function automatic logic [63:0] sext32 (logic [31:0] operand);
|
||||||
return {{32{operand[31]}}, operand[31:0]};
|
return {{32{operand[31]}}, operand[31:0]};
|
||||||
endfunction
|
endfunction
|
||||||
|
|
|
@ -38,11 +38,12 @@ package nbdcache_pkg;
|
||||||
|
|
||||||
typedef struct packed {
|
typedef struct packed {
|
||||||
logic valid;
|
logic valid;
|
||||||
logic bypass;
|
|
||||||
logic [63:0] addr;
|
logic [63:0] addr;
|
||||||
logic [7:0] be;
|
logic [7:0] be;
|
||||||
|
logic [1:0] size;
|
||||||
logic we;
|
logic we;
|
||||||
logic [63:0] wdata;
|
logic [63:0] wdata;
|
||||||
|
logic bypass;
|
||||||
} miss_req_t;
|
} miss_req_t;
|
||||||
|
|
||||||
typedef struct packed {
|
typedef struct packed {
|
||||||
|
|
|
@ -28,6 +28,7 @@ module cache_ctrl #(
|
||||||
input logic data_req_i,
|
input logic data_req_i,
|
||||||
input logic data_we_i,
|
input logic data_we_i,
|
||||||
input logic [7:0] data_be_i,
|
input logic [7:0] data_be_i,
|
||||||
|
input logic [1:0] data_size_i,
|
||||||
input logic kill_req_i,
|
input logic kill_req_i,
|
||||||
input logic tag_valid_i,
|
input logic tag_valid_i,
|
||||||
output logic data_gnt_o,
|
output logic data_gnt_o,
|
||||||
|
@ -67,6 +68,7 @@ module cache_ctrl #(
|
||||||
logic [INDEX_WIDTH-1:0] index;
|
logic [INDEX_WIDTH-1:0] index;
|
||||||
logic [TAG_WIDTH-1:0] tag;
|
logic [TAG_WIDTH-1:0] tag;
|
||||||
logic [7:0] be;
|
logic [7:0] be;
|
||||||
|
logic [1:0] size;
|
||||||
logic we;
|
logic we;
|
||||||
logic [63:0] wdata;
|
logic [63:0] wdata;
|
||||||
logic bypass;
|
logic bypass;
|
||||||
|
@ -118,6 +120,7 @@ module cache_ctrl #(
|
||||||
mem_req_d.index = address_index_i;
|
mem_req_d.index = address_index_i;
|
||||||
mem_req_d.tag = address_tag_i;
|
mem_req_d.tag = address_tag_i;
|
||||||
mem_req_d.be = data_be_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.we = data_we_i;
|
||||||
mem_req_d.wdata = data_wdata_i;
|
mem_req_d.wdata = data_wdata_i;
|
||||||
// TODO: Check for non-cache able accesses
|
// TODO: Check for non-cache able accesses
|
||||||
|
@ -164,6 +167,7 @@ module cache_ctrl #(
|
||||||
state_d = WAIT_TAG; // switch back to WAIT_TAG
|
state_d = WAIT_TAG; // switch back to WAIT_TAG
|
||||||
mem_req_d.index = address_index_i;
|
mem_req_d.index = address_index_i;
|
||||||
mem_req_d.be = data_be_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.we = data_we_i;
|
||||||
mem_req_d.wdata = data_wdata_i;
|
mem_req_d.wdata = data_wdata_i;
|
||||||
mem_req_d.tag = address_tag_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.bypass = mem_req_q.bypass;
|
||||||
miss_req_o.addr = {mem_req_q.tag, mem_req_q.index};
|
miss_req_o.addr = {mem_req_q.tag, mem_req_q.index};
|
||||||
miss_req_o.be = mem_req_q.be;
|
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.we = mem_req_q.we;
|
||||||
miss_req_o.wdata = mem_req_q.wdata;
|
miss_req_o.wdata = mem_req_q.wdata;
|
||||||
|
|
||||||
// got a grant so go to valid
|
// got a grant so go to valid
|
||||||
if (bypass_gnt_i) begin
|
if (bypass_gnt_i) begin
|
||||||
state_d = WAIT_REFILL_VALID;
|
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
|
end
|
||||||
|
|
||||||
if (miss_gnt_i && !mem_req_q.we)
|
if (miss_gnt_i && !mem_req_q.we)
|
||||||
|
@ -317,8 +324,9 @@ module cache_ctrl #(
|
||||||
if (data_req_i) begin
|
if (data_req_i) begin
|
||||||
// save index, be and we
|
// save index, be and we
|
||||||
mem_req_d.index = address_index_i;
|
mem_req_d.index = address_index_i;
|
||||||
mem_req_d.be = data_be_i;
|
mem_req_d.be = data_be_i;
|
||||||
mem_req_d.we = data_we_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.wdata = data_wdata_i;
|
||||||
mem_req_d.tag = address_tag_i;
|
mem_req_d.tag = address_tag_i;
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ module load_unit (
|
||||||
output logic data_req_o,
|
output logic data_req_o,
|
||||||
output logic data_we_o,
|
output logic data_we_o,
|
||||||
output logic [7:0] data_be_o,
|
output logic [7:0] data_be_o,
|
||||||
|
output logic [1:0] data_size_o,
|
||||||
output logic kill_req_o,
|
output logic kill_req_o,
|
||||||
output logic tag_valid_o,
|
output logic tag_valid_o,
|
||||||
input logic data_gnt_i,
|
input logic data_gnt_i,
|
||||||
|
@ -92,6 +93,7 @@ module load_unit (
|
||||||
kill_req_o = 1'b0;
|
kill_req_o = 1'b0;
|
||||||
tag_valid_o = 1'b0;
|
tag_valid_o = 1'b0;
|
||||||
data_be_o = lsu_ctrl_i.be;
|
data_be_o = lsu_ctrl_i.be;
|
||||||
|
data_size_o = extract_transfer_size(lsu_ctrl_i.operator);
|
||||||
pop_ld_o = 1'b0;
|
pop_ld_o = 1'b0;
|
||||||
|
|
||||||
case (CS)
|
case (CS)
|
||||||
|
|
|
@ -133,6 +133,8 @@ module lsu #(
|
||||||
logic [2:0][63:0] data_wdata_i;
|
logic [2:0][63:0] data_wdata_i;
|
||||||
logic [2:0] data_req_i;
|
logic [2:0] data_req_i;
|
||||||
logic [2:0] data_we_i;
|
logic [2:0] data_we_i;
|
||||||
|
logic [2:0][1:0] data_size_i;
|
||||||
|
|
||||||
logic [2:0] kill_req_i;
|
logic [2:0] kill_req_i;
|
||||||
logic [2:0] tag_valid_i;
|
logic [2:0] tag_valid_i;
|
||||||
logic [2:0][7:0] data_be_i;
|
logic [2:0][7:0] data_be_i;
|
||||||
|
@ -163,6 +165,7 @@ module lsu #(
|
||||||
.data_req_i ( data_req_i ),
|
.data_req_i ( data_req_i ),
|
||||||
.data_we_i ( data_we_i ),
|
.data_we_i ( data_we_i ),
|
||||||
.data_be_i ( data_be_i ),
|
.data_be_i ( data_be_i ),
|
||||||
|
.data_size_i ( data_size_i ),
|
||||||
.kill_req_i ( kill_req_i ),
|
.kill_req_i ( kill_req_i ),
|
||||||
.tag_valid_i ( tag_valid_i ),
|
.tag_valid_i ( tag_valid_i ),
|
||||||
.data_gnt_o ( data_gnt_o ),
|
.data_gnt_o ( data_gnt_o ),
|
||||||
|
@ -202,6 +205,7 @@ module lsu #(
|
||||||
.data_req_o ( data_req_i [0] ),
|
.data_req_o ( data_req_i [0] ),
|
||||||
.data_we_o ( data_we_i [0] ),
|
.data_we_o ( data_we_i [0] ),
|
||||||
.data_be_o ( data_be_i [0] ),
|
.data_be_o ( data_be_i [0] ),
|
||||||
|
.data_size_o ( data_size_i [0] ),
|
||||||
.kill_req_o ( kill_req_i [0] ),
|
.kill_req_o ( kill_req_i [0] ),
|
||||||
.tag_valid_o ( tag_valid_i [0] ),
|
.tag_valid_o ( tag_valid_i [0] ),
|
||||||
.data_gnt_i ( data_gnt_o [0] ),
|
.data_gnt_i ( data_gnt_o [0] ),
|
||||||
|
@ -237,6 +241,7 @@ module lsu #(
|
||||||
.data_req_o ( data_req_i [2] ),
|
.data_req_o ( data_req_i [2] ),
|
||||||
.data_we_o ( data_we_i [2] ),
|
.data_we_o ( data_we_i [2] ),
|
||||||
.data_be_o ( data_be_i [2] ),
|
.data_be_o ( data_be_i [2] ),
|
||||||
|
.data_size_o ( data_size_i [2] ),
|
||||||
.kill_req_o ( kill_req_i [2] ),
|
.kill_req_o ( kill_req_i [2] ),
|
||||||
.tag_valid_o ( tag_valid_i [2] ),
|
.tag_valid_o ( tag_valid_i [2] ),
|
||||||
.data_gnt_i ( data_gnt_o [2] ),
|
.data_gnt_i ( data_gnt_o [2] ),
|
||||||
|
@ -273,6 +278,7 @@ module lsu #(
|
||||||
.data_req_o ( data_req_i [1] ),
|
.data_req_o ( data_req_i [1] ),
|
||||||
.data_we_o ( data_we_i [1] ),
|
.data_we_o ( data_we_i [1] ),
|
||||||
.data_be_o ( data_be_i [1] ),
|
.data_be_o ( data_be_i [1] ),
|
||||||
|
.data_size_o ( data_size_i [1] ),
|
||||||
.kill_req_o ( kill_req_i [1] ),
|
.kill_req_o ( kill_req_i [1] ),
|
||||||
.tag_valid_o ( tag_valid_i [1] ),
|
.tag_valid_o ( tag_valid_i [1] ),
|
||||||
.data_gnt_i ( data_gnt_o [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][63:0] miss_req_wdata;
|
||||||
logic [NR_PORTS-1:0] miss_req_we;
|
logic [NR_PORTS-1:0] miss_req_we;
|
||||||
logic [NR_PORTS-1:0][7:0] miss_req_be;
|
logic [NR_PORTS-1:0][7:0] miss_req_be;
|
||||||
|
logic [NR_PORTS-1:0][1:0] miss_req_size;
|
||||||
|
|
||||||
// Cache Line Refill <-> AXI
|
// Cache Line Refill <-> AXI
|
||||||
logic req_fsm_miss_valid;
|
logic req_fsm_miss_valid;
|
||||||
|
@ -340,17 +341,17 @@ module miss_handler #(
|
||||||
// Bypass Arbiter
|
// Bypass Arbiter
|
||||||
// ----------------------
|
// ----------------------
|
||||||
// Connection Arbiter <-> AXI
|
// Connection Arbiter <-> AXI
|
||||||
logic req_fsm_bypass_valid;
|
logic req_fsm_bypass_valid;
|
||||||
logic [63:0] req_fsm_bypass_addr;
|
logic [63:0] req_fsm_bypass_addr;
|
||||||
logic [63:0] req_fsm_bypass_wdata;
|
logic [63:0] req_fsm_bypass_wdata;
|
||||||
logic req_fsm_bypass_we;
|
logic req_fsm_bypass_we;
|
||||||
logic [7:0] req_fsm_bypass_be;
|
logic [7:0] req_fsm_bypass_be;
|
||||||
|
logic [1:0] req_fsm_bypass_size;
|
||||||
logic gnt_bypass_fsm;
|
logic gnt_bypass_fsm;
|
||||||
logic valid_bypass_fsm;
|
logic valid_bypass_fsm;
|
||||||
logic [63:0] data_bypass_fsm;
|
logic [63:0] data_bypass_fsm;
|
||||||
logic [$clog2(NR_PORTS)-1:0] id_fsm_bypass;
|
logic [$clog2(NR_PORTS)-1:0] id_fsm_bypass;
|
||||||
logic [AXI_ID_WIDTH-1:0] id_bypass_fsm;
|
logic [AXI_ID_WIDTH-1:0] id_bypass_fsm;
|
||||||
|
|
||||||
arbiter #(
|
arbiter #(
|
||||||
.NR_PORTS ( NR_PORTS ),
|
.NR_PORTS ( NR_PORTS ),
|
||||||
|
@ -362,6 +363,7 @@ module miss_handler #(
|
||||||
.data_wdata_i ( miss_req_wdata ),
|
.data_wdata_i ( miss_req_wdata ),
|
||||||
.data_we_i ( miss_req_we ),
|
.data_we_i ( miss_req_we ),
|
||||||
.data_be_i ( miss_req_be ),
|
.data_be_i ( miss_req_be ),
|
||||||
|
.data_size_i ( miss_req_size ),
|
||||||
.data_gnt_o ( bypass_gnt_o ),
|
.data_gnt_o ( bypass_gnt_o ),
|
||||||
.data_rvalid_o ( bypass_valid_o ),
|
.data_rvalid_o ( bypass_valid_o ),
|
||||||
.data_rdata_o ( bypass_data_o ),
|
.data_rdata_o ( bypass_data_o ),
|
||||||
|
@ -373,6 +375,7 @@ module miss_handler #(
|
||||||
.data_req_o ( req_fsm_bypass_valid ),
|
.data_req_o ( req_fsm_bypass_valid ),
|
||||||
.data_we_o ( req_fsm_bypass_we ),
|
.data_we_o ( req_fsm_bypass_we ),
|
||||||
.data_be_o ( req_fsm_bypass_be ),
|
.data_be_o ( req_fsm_bypass_be ),
|
||||||
|
.data_size_o ( req_fsm_bypass_size ),
|
||||||
.data_gnt_i ( gnt_bypass_fsm ),
|
.data_gnt_i ( gnt_bypass_fsm ),
|
||||||
.data_rvalid_i ( valid_bypass_fsm ),
|
.data_rvalid_i ( valid_bypass_fsm ),
|
||||||
.data_rdata_i ( data_bypass_fsm ),
|
.data_rdata_i ( data_bypass_fsm ),
|
||||||
|
@ -389,6 +392,7 @@ module miss_handler #(
|
||||||
.we_i ( req_fsm_bypass_we ),
|
.we_i ( req_fsm_bypass_we ),
|
||||||
.wdata_i ( req_fsm_bypass_wdata ),
|
.wdata_i ( req_fsm_bypass_wdata ),
|
||||||
.be_i ( req_fsm_bypass_be ),
|
.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} ),
|
.id_i ( {{{AXI_ID_WIDTH-$clog2(NR_PORTS)}{1'b0}}, id_fsm_bypass} ),
|
||||||
.valid_o ( valid_bypass_fsm ),
|
.valid_o ( valid_bypass_fsm ),
|
||||||
.rdata_o ( data_bypass_fsm ),
|
.rdata_o ( data_bypass_fsm ),
|
||||||
|
@ -412,6 +416,7 @@ module miss_handler #(
|
||||||
.we_i ( req_fsm_miss_we ),
|
.we_i ( req_fsm_miss_we ),
|
||||||
.wdata_i ( req_fsm_miss_wdata ),
|
.wdata_i ( req_fsm_miss_wdata ),
|
||||||
.be_i ( req_fsm_miss_be ),
|
.be_i ( req_fsm_miss_be ),
|
||||||
|
.size_i ( 2'b11 ),
|
||||||
.id_i ( '0 ),
|
.id_i ( '0 ),
|
||||||
.valid_o ( valid_miss_fsm ),
|
.valid_o ( valid_miss_fsm ),
|
||||||
.rdata_o ( data_miss_fsm ),
|
.rdata_o ( data_miss_fsm ),
|
||||||
|
@ -445,6 +450,7 @@ module miss_handler #(
|
||||||
miss_req_wdata [i] = miss_req.wdata;
|
miss_req_wdata [i] = miss_req.wdata;
|
||||||
miss_req_we [i] = miss_req.we;
|
miss_req_we [i] = miss_req.we;
|
||||||
miss_req_be [i] = miss_req.be;
|
miss_req_be [i] = miss_req.be;
|
||||||
|
miss_req_size [i] = miss_req.size;
|
||||||
end
|
end
|
||||||
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_WIDTH-1:0] data_wdata_i,
|
||||||
input logic [NR_PORTS-1:0] data_we_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][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_gnt_o,
|
||||||
output logic [NR_PORTS-1:0] data_rvalid_o,
|
output logic [NR_PORTS-1:0] data_rvalid_o,
|
||||||
output logic [NR_PORTS-1:0][DATA_WIDTH-1:0] data_rdata_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_WIDTH-1:0] data_wdata_o,
|
||||||
output logic data_we_o,
|
output logic data_we_o,
|
||||||
output logic [DATA_WIDTH/8-1:0] data_be_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_gnt_i,
|
||||||
input logic data_rvalid_i,
|
input logic data_rvalid_i,
|
||||||
input logic [DATA_WIDTH-1:0] data_rdata_i
|
input logic [DATA_WIDTH-1:0] data_rdata_i
|
||||||
|
@ -511,6 +519,7 @@ module arbiter #(
|
||||||
address_o = address_i[request_index];
|
address_o = address_i[request_index];
|
||||||
data_wdata_o = data_wdata_i[request_index];
|
data_wdata_o = data_wdata_i[request_index];
|
||||||
data_be_o = data_be_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_we_o = data_we_i[request_index];
|
||||||
data_gnt_o[request_index] = data_gnt_i;
|
data_gnt_o[request_index] = data_gnt_i;
|
||||||
id_o = request_index;
|
id_o = request_index;
|
||||||
|
@ -569,6 +578,7 @@ module axi_adapter #(
|
||||||
input logic we_i,
|
input logic we_i,
|
||||||
input logic [(DATA_WIDTH/64)-1:0][63:0] wdata_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 [(DATA_WIDTH/64)-1:0][7:0] be_i,
|
||||||
|
input logic [1:0] size_i,
|
||||||
input logic [AXI_ID_WIDTH-1:0] id_i,
|
input logic [AXI_ID_WIDTH-1:0] id_i,
|
||||||
// read port
|
// read port
|
||||||
output logic valid_o,
|
output logic valid_o,
|
||||||
|
@ -603,7 +613,7 @@ module axi_adapter #(
|
||||||
axi.aw_prot = 3'b0;
|
axi.aw_prot = 3'b0;
|
||||||
axi.aw_region = 4'b0;
|
axi.aw_region = 4'b0;
|
||||||
axi.aw_len = 8'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_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_lock = 1'b0;
|
||||||
axi.aw_cache = 4'b0;
|
axi.aw_cache = 4'b0;
|
||||||
|
@ -618,7 +628,7 @@ module axi_adapter #(
|
||||||
axi.ar_prot = 3'b0;
|
axi.ar_prot = 3'b0;
|
||||||
axi.ar_region = 4'b0;
|
axi.ar_region = 4'b0;
|
||||||
axi.ar_len = 8'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_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_lock = 1'b0;
|
||||||
axi.ar_cache = 4'b0;
|
axi.ar_cache = 4'b0;
|
||||||
|
|
|
@ -81,6 +81,7 @@ module mmu #(
|
||||||
output logic data_req_o,
|
output logic data_req_o,
|
||||||
output logic data_we_o,
|
output logic data_we_o,
|
||||||
output logic [7:0] data_be_o,
|
output logic [7:0] data_be_o,
|
||||||
|
output logic [1:0] data_size_o,
|
||||||
output logic kill_req_o,
|
output logic kill_req_o,
|
||||||
output logic tag_valid_o,
|
output logic tag_valid_o,
|
||||||
input logic data_gnt_i,
|
input logic data_gnt_i,
|
||||||
|
|
|
@ -42,6 +42,7 @@ module nbdcache (
|
||||||
input logic [2:0] data_req_i,
|
input logic [2:0] data_req_i,
|
||||||
input logic [2:0] data_we_i,
|
input logic [2:0] data_we_i,
|
||||||
input logic [2:0][7:0] data_be_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] kill_req_i,
|
||||||
input logic [2:0] tag_valid_i,
|
input logic [2:0] tag_valid_i,
|
||||||
output logic [2:0] data_gnt_o,
|
output logic [2:0] data_gnt_o,
|
||||||
|
@ -111,6 +112,7 @@ module nbdcache (
|
||||||
.data_req_i ( data_req_i [i] ),
|
.data_req_i ( data_req_i [i] ),
|
||||||
.data_we_i ( data_we_i [i] ),
|
.data_we_i ( data_we_i [i] ),
|
||||||
.data_be_i ( data_be_i [i] ),
|
.data_be_i ( data_be_i [i] ),
|
||||||
|
.data_size_i ( data_size_i [i] ),
|
||||||
.kill_req_i ( kill_req_i [i] ),
|
.kill_req_i ( kill_req_i [i] ),
|
||||||
.tag_valid_i ( tag_valid_i [i] ),
|
.tag_valid_i ( tag_valid_i [i] ),
|
||||||
.data_gnt_o ( data_gnt_o [i] ),
|
.data_gnt_o ( data_gnt_o [i] ),
|
||||||
|
|
|
@ -44,6 +44,7 @@ module ptw #(
|
||||||
output logic data_req_o,
|
output logic data_req_o,
|
||||||
output logic data_we_o,
|
output logic data_we_o,
|
||||||
output logic [7:0] data_be_o,
|
output logic [7:0] data_be_o,
|
||||||
|
output logic [1:0] data_size_o,
|
||||||
output logic kill_req_o,
|
output logic kill_req_o,
|
||||||
output logic tag_valid_o,
|
output logic tag_valid_o,
|
||||||
input logic data_gnt_i,
|
input logic data_gnt_i,
|
||||||
|
@ -154,6 +155,7 @@ module ptw #(
|
||||||
tag_valid_n = 1'b0;
|
tag_valid_n = 1'b0;
|
||||||
data_req_o = 1'b0;
|
data_req_o = 1'b0;
|
||||||
data_be_o = 8'hFF;
|
data_be_o = 8'hFF;
|
||||||
|
data_size_o = 2'b11;
|
||||||
data_we_o = 1'b0;
|
data_we_o = 1'b0;
|
||||||
ptw_error_o = 1'b0;
|
ptw_error_o = 1'b0;
|
||||||
itlb_update_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] 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 [63:0] data_i, // data which is placed in the queue
|
||||||
input logic [7:0] be_i, // byte enable in
|
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
|
// D$ interface
|
||||||
output logic [11:0] address_index_o,
|
output logic [11:0] address_index_o,
|
||||||
|
@ -45,6 +46,7 @@ module store_buffer (
|
||||||
output logic data_req_o,
|
output logic data_req_o,
|
||||||
output logic data_we_o,
|
output logic data_we_o,
|
||||||
output logic [7:0] data_be_o,
|
output logic [7:0] data_be_o,
|
||||||
|
output logic [1:0] data_size_o,
|
||||||
output logic kill_req_o,
|
output logic kill_req_o,
|
||||||
output logic tag_valid_o,
|
output logic tag_valid_o,
|
||||||
input logic data_gnt_i,
|
input logic data_gnt_i,
|
||||||
|
@ -63,6 +65,7 @@ module store_buffer (
|
||||||
logic [63:0] address;
|
logic [63:0] address;
|
||||||
logic [63:0] data;
|
logic [63:0] data;
|
||||||
logic [7:0] be;
|
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
|
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],
|
} 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];
|
commit_queue_n [DEPTH_COMMIT-1:0], commit_queue_q [DEPTH_COMMIT-1:0];
|
||||||
|
@ -94,9 +97,10 @@ module store_buffer (
|
||||||
// LSU interface
|
// LSU interface
|
||||||
// we are ready to accept a new entry and the input data is valid
|
// we are ready to accept a new entry and the input data is valid
|
||||||
if (valid_i) begin
|
if (valid_i) begin
|
||||||
speculative_queue_n[speculative_write_pointer_q].address = paddr_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].data = data_i;
|
||||||
speculative_queue_n[speculative_write_pointer_q].be = be_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;
|
speculative_queue_n[speculative_write_pointer_q].valid = 1'b1;
|
||||||
// advance the write pointer
|
// advance the write pointer
|
||||||
speculative_write_pointer_n = speculative_write_pointer_q + 1'b1;
|
speculative_write_pointer_n = speculative_write_pointer_q + 1'b1;
|
||||||
|
@ -137,6 +141,7 @@ module store_buffer (
|
||||||
assign tag_valid_o = 1'b0;
|
assign tag_valid_o = 1'b0;
|
||||||
assign data_wdata_o = commit_queue_q[commit_read_pointer_q].data;
|
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_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
|
// 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
|
// 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;
|
assign kill_req_o = 1'b0;
|
||||||
|
|
|
@ -51,6 +51,7 @@ module store_unit (
|
||||||
output logic data_req_o,
|
output logic data_req_o,
|
||||||
output logic data_we_o,
|
output logic data_we_o,
|
||||||
output logic [7:0] data_be_o,
|
output logic [7:0] data_be_o,
|
||||||
|
output logic [1:0] data_size_o,
|
||||||
output logic kill_req_o,
|
output logic kill_req_o,
|
||||||
output logic tag_valid_o,
|
output logic tag_valid_o,
|
||||||
input logic data_gnt_i,
|
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)
|
// keep the data and the byte enable for the second cycle (after address translation)
|
||||||
logic [63:0] st_data_n, st_data_q;
|
logic [63:0] st_data_n, st_data_q;
|
||||||
logic [7:0] st_be_n, st_be_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;
|
logic [TRANS_ID_BITS-1:0] trans_id_n, trans_id_q;
|
||||||
|
|
||||||
// output assignments
|
// output assignments
|
||||||
|
@ -175,8 +177,10 @@ module store_unit (
|
||||||
// -----------
|
// -----------
|
||||||
// re-align the write data to comply with the address offset
|
// re-align the write data to comply with the address offset
|
||||||
always_comb begin
|
always_comb begin
|
||||||
st_be_n = lsu_ctrl_i.be;
|
st_be_n = lsu_ctrl_i.be;
|
||||||
st_data_n = lsu_ctrl_i.data;
|
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])
|
case (lsu_ctrl_i.vaddr[2:0])
|
||||||
3'b000: st_data_n = lsu_ctrl_i.data;
|
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]};
|
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 ),
|
.valid_i ( st_valid ),
|
||||||
.data_i ( st_data_q ),
|
.data_i ( st_data_q ),
|
||||||
.be_i ( st_be_q ),
|
.be_i ( st_be_q ),
|
||||||
|
.data_size_i ( st_data_size_q ),
|
||||||
// store buffer out
|
// store buffer out
|
||||||
.ready_o ( st_ready ),
|
.ready_o ( st_ready ),
|
||||||
.*
|
.*
|
||||||
|
@ -205,15 +210,17 @@ module store_unit (
|
||||||
// ---------------
|
// ---------------
|
||||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||||
if(~rst_ni) begin
|
if(~rst_ni) begin
|
||||||
CS <= IDLE;
|
CS <= IDLE;
|
||||||
st_be_q <= '0;
|
st_be_q <= '0;
|
||||||
st_data_q <= '0;
|
st_data_q <= '0;
|
||||||
trans_id_q <= '0;
|
st_data_size_q <= '0;
|
||||||
|
trans_id_q <= '0;
|
||||||
end else begin
|
end else begin
|
||||||
CS <= NS;
|
CS <= NS;
|
||||||
st_be_q <= st_be_n;
|
st_be_q <= st_be_n;
|
||||||
st_data_q <= st_data_n;
|
st_data_q <= st_data_n;
|
||||||
trans_id_q <= trans_id_n;
|
trans_id_q <= trans_id_n;
|
||||||
|
st_data_size_q <= st_data_size_n;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue