Make appropriate AXI size requests

This commit is contained in:
Florian Zaruba 2017-12-08 17:01:25 +01:00
parent cb04234629
commit 11b03190f2
No known key found for this signature in database
GPG key ID: E742FFE8EC38A792
11 changed files with 89 additions and 31 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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