mirror of
https://github.com/openhwgroup/cva5.git
synced 2025-04-20 12:07:53 -04:00
Store-queue cleanups
Signed-off-by: Eric Matthews <ematthew@sfu.ca>
This commit is contained in:
parent
1ffbacbb51
commit
28dc5bc43b
5 changed files with 58 additions and 49 deletions
|
@ -112,6 +112,7 @@ package cva5_config;
|
|||
//CSR constants
|
||||
csr_config_t CSRS;
|
||||
//Memory Options
|
||||
int unsigned SQ_DEPTH;//CAM-based reasonable max of 4
|
||||
//Caches
|
||||
bit INCLUDE_ICACHE;
|
||||
cache_config_t ICACHE;
|
||||
|
@ -178,10 +179,11 @@ package cva5_config;
|
|||
}
|
||||
},
|
||||
//Memory Options
|
||||
SQ_DEPTH : 4,
|
||||
INCLUDE_ICACHE : 0,
|
||||
ICACHE_ADDR : '{
|
||||
L: 32'h40000000,
|
||||
H: 32'h4FFFFFFF
|
||||
L: 32'h80000000,
|
||||
H: 32'h8FFFFFFF
|
||||
},
|
||||
ICACHE : '{
|
||||
LINES : 512,
|
||||
|
@ -190,8 +192,8 @@ package cva5_config;
|
|||
USE_EXTERNAL_INVALIDATIONS : 0,
|
||||
USE_NON_CACHEABLE : 0,
|
||||
NON_CACHEABLE : '{
|
||||
L: 32'h00000000,
|
||||
H: 32'h00000000
|
||||
L: 32'h70000000,
|
||||
H: 32'h7FFFFFFF
|
||||
}
|
||||
},
|
||||
ITLB : '{
|
||||
|
@ -200,8 +202,8 @@ package cva5_config;
|
|||
},
|
||||
INCLUDE_DCACHE : 0,
|
||||
DCACHE_ADDR : '{
|
||||
L: 32'h40000000,
|
||||
H: 32'h4FFFFFFF
|
||||
L: 32'h80000000,
|
||||
H: 32'h8FFFFFFF
|
||||
},
|
||||
DCACHE : '{
|
||||
LINES : 512,
|
||||
|
@ -210,8 +212,8 @@ package cva5_config;
|
|||
USE_EXTERNAL_INVALIDATIONS : 0,
|
||||
USE_NON_CACHEABLE : 0,
|
||||
NON_CACHEABLE : '{
|
||||
L: 32'h00000000,
|
||||
H: 32'h00000000
|
||||
L: 32'h70000000,
|
||||
H: 32'h7FFFFFFF
|
||||
}
|
||||
},
|
||||
DTLB : '{
|
||||
|
|
|
@ -221,7 +221,7 @@ interface load_store_queue_interface;
|
|||
endinterface
|
||||
|
||||
|
||||
interface store_queue_interface #(parameter DEPTH = 4);
|
||||
interface store_queue_interface;
|
||||
import riscv_types::*;
|
||||
import cva5_types::*;
|
||||
|
||||
|
|
|
@ -26,6 +26,9 @@ module load_store_queue //ID-based input buffer for Load/Store Unit
|
|||
import riscv_types::*;
|
||||
import cva5_types::*;
|
||||
|
||||
# (
|
||||
parameter cpu_config_t CONFIG = EXAMPLE_CONFIG
|
||||
)
|
||||
(
|
||||
input logic clk,
|
||||
input logic rst,
|
||||
|
@ -41,17 +44,16 @@ module load_store_queue //ID-based input buffer for Load/Store Unit
|
|||
|
||||
output logic tr_possible_load_conflict_delay
|
||||
);
|
||||
localparam SQ_DEPTH = 4;
|
||||
|
||||
typedef struct packed {
|
||||
logic [31:0] addr;
|
||||
logic [2:0] fn3;
|
||||
id_t id;
|
||||
logic [SQ_DEPTH-1:0] potential_store_conflicts;
|
||||
logic [CONFIG.SQ_DEPTH-1:0] potential_store_conflicts;
|
||||
} lq_entry_t;
|
||||
|
||||
addr_hash_t addr_hash;
|
||||
logic [SQ_DEPTH-1:0] potential_store_conflicts;
|
||||
logic [CONFIG.SQ_DEPTH-1:0] potential_store_conflicts;
|
||||
sq_entry_t sq_entry;
|
||||
logic store_conflict;
|
||||
logic load_selected;
|
||||
|
@ -60,7 +62,7 @@ module load_store_queue //ID-based input buffer for Load/Store Unit
|
|||
lq_entry_t lq_data_out;
|
||||
|
||||
fifo_interface #(.DATA_WIDTH($bits(lq_entry_t))) lq();
|
||||
store_queue_interface #(.DEPTH(SQ_DEPTH)) sq();
|
||||
store_queue_interface sq();
|
||||
////////////////////////////////////////////////////
|
||||
//Implementation
|
||||
|
||||
|
@ -104,7 +106,7 @@ module load_store_queue //ID-based input buffer for Load/Store Unit
|
|||
assign sq.pop = lsq.pop & ~load_selected;
|
||||
assign sq.data_in = lsq.data_in;
|
||||
|
||||
store_queue #(.DEPTH(SQ_DEPTH)) sq_block (
|
||||
store_queue # (.CONFIG(CONFIG)) sq_block (
|
||||
.clk (clk),
|
||||
.rst (rst | gc.sq_flush),
|
||||
.lq_push (lq.push),
|
||||
|
|
|
@ -225,7 +225,7 @@ module load_store_unit
|
|||
assign lsq.potential_push = issue.possible_issue;
|
||||
assign lsq.push = issue.new_request & ~unaligned_addr & (~tlb_on | tlb.done) & ~ls_inputs.fence;
|
||||
|
||||
load_store_queue lsq_block (
|
||||
load_store_queue # (.CONFIG(CONFIG)) lsq_block (
|
||||
.clk (clk),
|
||||
.rst (rst),
|
||||
.gc (gc),
|
||||
|
|
|
@ -27,7 +27,7 @@ module store_queue
|
|||
import cva5_types::*;
|
||||
|
||||
# (
|
||||
parameter DEPTH = 4
|
||||
parameter cpu_config_t CONFIG = EXAMPLE_CONFIG
|
||||
)
|
||||
(
|
||||
input logic clk,
|
||||
|
@ -40,9 +40,9 @@ module store_queue
|
|||
//Address hash (shared by loads and stores)
|
||||
input addr_hash_t addr_hash,
|
||||
//hash check on adding a load to the queue
|
||||
output logic [DEPTH-1:0] potential_store_conflicts,
|
||||
output logic [CONFIG.SQ_DEPTH-1:0] potential_store_conflicts,
|
||||
//Load issue collision check
|
||||
input logic [DEPTH-1:0] prev_store_conflicts,
|
||||
input logic [CONFIG.SQ_DEPTH-1:0] prev_store_conflicts,
|
||||
output logic store_conflict,
|
||||
|
||||
//Writeback snooping
|
||||
|
@ -53,42 +53,42 @@ module store_queue
|
|||
input logic retire_port_valid [RETIRE_PORTS]
|
||||
);
|
||||
|
||||
localparam LOG2_DEPTH = $clog2(DEPTH);
|
||||
typedef logic [LOG2_MAX_IDS-1:0] load_check_count_t;
|
||||
localparam LOG2_SQ_DEPTH = $clog2(CONFIG.SQ_DEPTH);
|
||||
typedef logic [LOG2_MAX_IDS:0] load_check_count_t;
|
||||
|
||||
|
||||
wb_packet_t wb_snoop_r;
|
||||
|
||||
//Register-based memory blocks
|
||||
logic [DEPTH-1:0] valid;
|
||||
logic [DEPTH-1:0] valid_next;
|
||||
addr_hash_t [DEPTH-1:0] hashes;
|
||||
logic [DEPTH-1:0] released;
|
||||
id_t [DEPTH-1:0] id_needed;
|
||||
load_check_count_t [DEPTH-1:0] load_check_count;
|
||||
logic [31:0] store_data_from_wb [DEPTH];
|
||||
logic [CONFIG.SQ_DEPTH-1:0] valid;
|
||||
logic [CONFIG.SQ_DEPTH-1:0] valid_next;
|
||||
addr_hash_t [CONFIG.SQ_DEPTH-1:0] hashes;
|
||||
logic [CONFIG.SQ_DEPTH-1:0] released;
|
||||
id_t [CONFIG.SQ_DEPTH-1:0] id_needed;
|
||||
load_check_count_t [CONFIG.SQ_DEPTH-1:0] load_check_count;
|
||||
logic [31:0] store_data_from_wb [CONFIG.SQ_DEPTH];
|
||||
|
||||
//LUTRAM-based memory blocks
|
||||
sq_entry_t sq_entry_in;
|
||||
(* ramstyle = "MLAB, no_rw_check" *) logic [$bits(sq_entry_t)-1:0] sq_entry [DEPTH];
|
||||
(* ramstyle = "MLAB, no_rw_check" *) id_t [DEPTH-1:0] ids;
|
||||
(* ramstyle = "MLAB, no_rw_check" *) logic [LOG2_DEPTH-1:0] sq_ids [MAX_IDS];
|
||||
(* ramstyle = "MLAB, no_rw_check" *) logic [$bits(sq_entry_t)-1:0] sq_entry [CONFIG.SQ_DEPTH];
|
||||
(* ramstyle = "MLAB, no_rw_check" *) id_t [CONFIG.SQ_DEPTH-1:0] ids;
|
||||
(* ramstyle = "MLAB, no_rw_check" *) logic [LOG2_SQ_DEPTH-1:0] sq_ids [MAX_IDS];
|
||||
|
||||
load_check_count_t [DEPTH-1:0] load_check_count_next;
|
||||
load_check_count_t [CONFIG.SQ_DEPTH-1:0] load_check_count_next;
|
||||
|
||||
logic [LOG2_DEPTH-1:0] sq_index;
|
||||
logic [LOG2_DEPTH-1:0] sq_index_next;
|
||||
logic [LOG2_DEPTH-1:0] sq_oldest;
|
||||
logic [LOG2_SQ_DEPTH-1:0] sq_index;
|
||||
logic [LOG2_SQ_DEPTH-1:0] sq_index_next;
|
||||
logic [LOG2_SQ_DEPTH-1:0] sq_oldest;
|
||||
|
||||
logic [DEPTH-1:0] new_request_one_hot;
|
||||
logic [DEPTH-1:0] issued_one_hot;
|
||||
logic [CONFIG.SQ_DEPTH-1:0] new_request_one_hot;
|
||||
logic [CONFIG.SQ_DEPTH-1:0] issued_one_hot;
|
||||
|
||||
|
||||
logic [DEPTH-1:0] wb_id_match;
|
||||
logic [CONFIG.SQ_DEPTH-1:0] wb_id_match;
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Implementation
|
||||
assign sq_index_next = sq_index + LOG2_DEPTH'(sq.push);
|
||||
assign sq_index_next = sq_index +LOG2_SQ_DEPTH'(sq.push);
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst)
|
||||
sq_index <= 0;
|
||||
|
@ -100,11 +100,11 @@ module store_queue
|
|||
if (rst)
|
||||
sq_oldest <= 0;
|
||||
else
|
||||
sq_oldest <= sq_oldest + LOG2_DEPTH'(sq.pop);
|
||||
sq_oldest <= sq_oldest +LOG2_SQ_DEPTH'(sq.pop);
|
||||
end
|
||||
|
||||
assign new_request_one_hot = DEPTH'(sq.push) << sq_index;
|
||||
assign issued_one_hot = DEPTH'(sq.pop) << sq_oldest;
|
||||
assign new_request_one_hot = CONFIG.SQ_DEPTH'(sq.push) << sq_index;
|
||||
assign issued_one_hot = CONFIG.SQ_DEPTH'(sq.pop) << sq_oldest;
|
||||
|
||||
assign valid_next = (valid | new_request_one_hot) & ~issued_one_hot;
|
||||
always_ff @ (posedge clk) begin
|
||||
|
@ -122,7 +122,7 @@ module store_queue
|
|||
else
|
||||
sq.full <= valid_next[sq_index_next] | (|load_check_count_next[sq_index_next]);
|
||||
end
|
||||
|
||||
|
||||
//SQ attributes and issue data
|
||||
assign sq_entry_in = '{
|
||||
addr : sq.data_in.addr,
|
||||
|
@ -144,11 +144,11 @@ module store_queue
|
|||
|
||||
//Keep count of the number of pending loads that might need a store result
|
||||
//Mask out any store completing on this cycle
|
||||
logic [DEPTH-1:0] new_load_waiting;
|
||||
logic [DEPTH-1:0] waiting_load_completed;
|
||||
logic [CONFIG.SQ_DEPTH-1:0] new_load_waiting;
|
||||
logic [CONFIG.SQ_DEPTH-1:0] waiting_load_completed;
|
||||
|
||||
always_comb begin
|
||||
for (int i = 0; i < DEPTH; i++) begin
|
||||
for (int i = 0; i < CONFIG.SQ_DEPTH; i++) begin
|
||||
potential_store_conflicts[i] = (valid[i] & ~issued_one_hot[i]) & (addr_hash == hashes[i]);
|
||||
new_load_waiting[i] = potential_store_conflicts[i] & lq_push;
|
||||
waiting_load_completed[i] = prev_store_conflicts[i] & lq_pop;
|
||||
|
@ -190,15 +190,15 @@ module store_queue
|
|||
|
||||
////////////////////////////////////////////////////
|
||||
//Release Handling
|
||||
logic [DEPTH-1:0] newly_released;
|
||||
logic [LOG2_DEPTH-1:0] store_released_index [RETIRE_PORTS];
|
||||
logic [CONFIG.SQ_DEPTH-1:0] newly_released;
|
||||
logic [LOG2_SQ_DEPTH-1:0] store_released_index [RETIRE_PORTS];
|
||||
logic store_released [RETIRE_PORTS];
|
||||
always_comb begin
|
||||
newly_released = '0;
|
||||
for (int i = 0; i < RETIRE_PORTS; i++) begin
|
||||
store_released_index[i] = sq_ids[retire_ids[i]];
|
||||
store_released[i] = {1'b1, ids[store_released_index[i]]} == {retire_port_valid[i], retire_ids[i]};
|
||||
newly_released |= DEPTH'(store_released[i]) << store_released_index[i];
|
||||
newly_released |= CONFIG.SQ_DEPTH'(store_released[i]) << store_released_index[i];
|
||||
end
|
||||
end
|
||||
always_ff @ (posedge clk) begin
|
||||
|
@ -214,7 +214,7 @@ module store_queue
|
|||
end
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
for (int i = 0; i < DEPTH; i++) begin
|
||||
for (int i = 0; i < CONFIG.SQ_DEPTH; i++) begin
|
||||
if ({1'b0, wb_snoop_r.valid, wb_snoop_r.id} == {released[i], 1'b1, id_needed[i]})
|
||||
store_data_from_wb[i] <= wb_snoop_r.data;
|
||||
end
|
||||
|
@ -258,5 +258,10 @@ module store_queue
|
|||
|
||||
////////////////////////////////////////////////////
|
||||
//Assertions
|
||||
sq_overflow_assertion:
|
||||
assert property (@(posedge clk) disable iff (rst) sq.push |-> (~sq.full | sq.pop)) else $error("sq overflow");
|
||||
fifo_underflow_assertion:
|
||||
assert property (@(posedge clk) disable iff (rst) sq.pop |-> sq.valid) else $error("sq underflow");
|
||||
|
||||
|
||||
endmodule
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue