mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-23 21:57:11 -04:00
Add commit full signal to store buffer
This commit is contained in:
parent
d330ed32a6
commit
a2726cfcae
6 changed files with 43 additions and 20 deletions
|
@ -186,6 +186,7 @@ module ariane
|
|||
logic csr_commit_commit_ex;
|
||||
// LSU Commit
|
||||
logic lsu_commit_commit_ex;
|
||||
logic lsu_commit_ready_ex_commit;
|
||||
logic no_st_pending_ex_commit;
|
||||
// --------------
|
||||
// ID <-> COMMIT
|
||||
|
@ -430,6 +431,7 @@ module ariane
|
|||
.lsu_trans_id_o ( lsu_trans_id_ex_id ),
|
||||
.lsu_valid_o ( lsu_valid_ex_id ),
|
||||
.lsu_commit_i ( lsu_commit_commit_ex ), // from commit
|
||||
.lsu_commit_ready_o ( lsu_commit_ready_ex_commit ), // to commit
|
||||
.lsu_exception_o ( lsu_exception_ex_id ),
|
||||
.no_st_pending_o ( no_st_pending_ex_commit ),
|
||||
|
||||
|
@ -479,6 +481,7 @@ module ariane
|
|||
.wdata_a_o ( wdata_a_commit_id ),
|
||||
.we_a_o ( we_a_commit_id ),
|
||||
.commit_lsu_o ( lsu_commit_commit_ex ),
|
||||
.commit_lsu_ready_i ( lsu_commit_ready_ex_commit ),
|
||||
.commit_csr_o ( csr_commit_commit_ex ),
|
||||
.pc_o ( pc_commit ),
|
||||
.csr_op_o ( csr_op_commit_csr ),
|
||||
|
|
|
@ -41,6 +41,7 @@ module commit_stage (
|
|||
input exception csr_exception_i,
|
||||
// commit signals to ex
|
||||
output logic commit_lsu_o, // commit the pending store
|
||||
input logic commit_lsu_ready_i,
|
||||
input logic no_st_pending_i, // there is no store pending
|
||||
output logic commit_csr_o, // commit the pending CSR instruction
|
||||
output logic fence_i_o, // flush icache and pipeline
|
||||
|
@ -69,6 +70,8 @@ module commit_stage (
|
|||
// we will not commit the instruction if we took an exception
|
||||
// but we do not commit the instruction if we requested a halt
|
||||
if (commit_instr_i.valid && !halt_i) begin
|
||||
|
||||
commit_ack_o = 1'b1;
|
||||
// register will be the all zero register.
|
||||
// and also acknowledge the instruction, this is mainly done for the instruction tracer
|
||||
// as it will listen on the instruction ack signal. For the overall result it does not make any
|
||||
|
@ -82,11 +85,13 @@ module commit_stage (
|
|||
// do not commit the instruction if we got an exception since the store buffer will be cleared
|
||||
// by the subsequent flush triggered by an exception
|
||||
if (commit_instr_i.fu == STORE) begin
|
||||
commit_lsu_o = 1'b1;
|
||||
if (commit_lsu_ready_i)
|
||||
commit_lsu_o = 1'b1;
|
||||
else // if the LSU buffer is not ready - do not commit, wait
|
||||
commit_ack_o = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
commit_ack_o = 1'b1;
|
||||
// ---------
|
||||
// CSR Logic
|
||||
// ---------
|
||||
|
|
|
@ -60,6 +60,7 @@ module ex_stage #(
|
|||
output logic [63:0] lsu_result_o,
|
||||
output logic [TRANS_ID_BITS-1:0] lsu_trans_id_o,
|
||||
input logic lsu_commit_i,
|
||||
output logic lsu_commit_ready_o, // commit queue is ready to accept another commit request
|
||||
output exception lsu_exception_o,
|
||||
output logic no_st_pending_o,
|
||||
// CSR
|
||||
|
@ -144,7 +145,8 @@ module ex_stage #(
|
|||
// Load-Store Unit
|
||||
// ----------------
|
||||
lsu lsu_i (
|
||||
.commit_i ( lsu_commit_i ),
|
||||
.commit_i ( lsu_commit_i ),
|
||||
.commit_ready_o ( lsu_commit_ready_o ),
|
||||
.*
|
||||
);
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ module lsu #(
|
|||
output logic [63:0] lsu_result_o,
|
||||
output logic lsu_valid_o, // transaction id for which the output is the requested one
|
||||
input logic commit_i, // commit the pending store
|
||||
output logic commit_ready_o, // commit queue is ready to accept another commit request
|
||||
|
||||
input logic enable_translation_i, // enable virtual memory translation
|
||||
input logic en_ld_st_translation_i, // enable virtual memory translation for load/stores
|
||||
|
|
|
@ -29,6 +29,7 @@ module store_buffer (
|
|||
output logic page_offset_matches_o,
|
||||
|
||||
input logic commit_i, // commit the instruction which was placed there most recently
|
||||
output logic commit_ready_o, // commit queue is ready to accept another commit request
|
||||
output logic ready_o, // the store queue is ready to accept a new request
|
||||
// it is only ready if it can unconditionally commit the instruction, e.g.:
|
||||
// the commit buffer needs to be empty
|
||||
|
@ -49,8 +50,10 @@ module store_buffer (
|
|||
input logic data_gnt_i,
|
||||
input logic data_rvalid_i
|
||||
);
|
||||
// depth of store-buffer
|
||||
localparam int unsigned DEPTH = 4;
|
||||
// depth of store-buffers
|
||||
localparam int unsigned DEPTH_SPEC = 4;
|
||||
// allocate more space for the commit buffer to be on the save side
|
||||
localparam int unsigned DEPTH_COMMIT = 4;
|
||||
|
||||
// we need to keep the tag portion of the address for a cycle later
|
||||
logic [43:0] address_tag_n, address_tag_q;
|
||||
|
@ -65,27 +68,27 @@ module store_buffer (
|
|||
logic [63:0] data;
|
||||
logic [7:0] be;
|
||||
logic valid; // this entry is valid, we need this for checking if the address offset matches
|
||||
} speculative_queue_n [DEPTH-1:0], speculative_queue_q [DEPTH-1:0],
|
||||
commit_queue_n [DEPTH-1:0], commit_queue_q [DEPTH-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];
|
||||
|
||||
// keep a status count for both buffers
|
||||
logic [$clog2(DEPTH):0] speculative_status_cnt_n, speculative_status_cnt_q;
|
||||
logic [$clog2(DEPTH):0] commit_status_cnt_n, commit_status_cnt_q;
|
||||
logic [$clog2(DEPTH_SPEC):0] speculative_status_cnt_n, speculative_status_cnt_q;
|
||||
logic [$clog2(DEPTH_COMMIT):0] commit_status_cnt_n, commit_status_cnt_q;
|
||||
// Speculative queue
|
||||
logic [$clog2(DEPTH)-1:0] speculative_read_pointer_n, speculative_read_pointer_q;
|
||||
logic [$clog2(DEPTH)-1:0] speculative_write_pointer_n, speculative_write_pointer_q;
|
||||
logic [$clog2(DEPTH_SPEC)-1:0] speculative_read_pointer_n, speculative_read_pointer_q;
|
||||
logic [$clog2(DEPTH_SPEC)-1:0] speculative_write_pointer_n, speculative_write_pointer_q;
|
||||
// Commit Queue
|
||||
logic [$clog2(DEPTH)-1:0] commit_read_pointer_n, commit_read_pointer_q;
|
||||
logic [$clog2(DEPTH)-1:0] commit_write_pointer_n, commit_write_pointer_q;
|
||||
logic [$clog2(DEPTH_COMMIT)-1:0] commit_read_pointer_n, commit_read_pointer_q;
|
||||
logic [$clog2(DEPTH_COMMIT)-1:0] commit_write_pointer_n, commit_write_pointer_q;
|
||||
|
||||
// ----------------------------------------
|
||||
// Speculative Queue - Core Interface
|
||||
// ----------------------------------------
|
||||
always_comb begin : core_if
|
||||
automatic logic [DEPTH:0] speculative_status_cnt = speculative_status_cnt_q;
|
||||
automatic logic [DEPTH_SPEC:0] speculative_status_cnt = speculative_status_cnt_q;
|
||||
|
||||
// we are ready if the speculative and the commit queue have a space left
|
||||
ready_o = (speculative_status_cnt_q < DEPTH) && (commit_status_cnt_q < DEPTH);
|
||||
ready_o = speculative_status_cnt_q < (DEPTH_SPEC - 1);
|
||||
// default assignments
|
||||
speculative_status_cnt_n = speculative_status_cnt_q;
|
||||
speculative_read_pointer_n = speculative_read_pointer_q;
|
||||
|
@ -93,7 +96,7 @@ module store_buffer (
|
|||
speculative_queue_n = speculative_queue_q;
|
||||
// LSU interface
|
||||
// we are ready to accept a new entry and the input data is valid
|
||||
if (ready_o && valid_i) begin
|
||||
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;
|
||||
|
@ -116,9 +119,9 @@ module store_buffer (
|
|||
speculative_status_cnt_n = speculative_status_cnt;
|
||||
|
||||
// when we flush evict the speculative stores
|
||||
if (flush_i) begin
|
||||
if (ready_o && flush_i) begin
|
||||
// reset all valid flags
|
||||
for (int unsigned i = 0; i < DEPTH; i++)
|
||||
for (int unsigned i = 0; i < DEPTH_SPEC; i++)
|
||||
speculative_queue_n[i].valid = 1'b0;
|
||||
|
||||
speculative_write_pointer_n = speculative_read_pointer_q;
|
||||
|
@ -141,7 +144,8 @@ module store_buffer (
|
|||
assign data_we_o = 1'b1; // we will always write in the store queue
|
||||
|
||||
always_comb begin : store_if
|
||||
automatic logic [DEPTH:0] commit_status_cnt = commit_status_cnt_q;
|
||||
automatic logic [DEPTH_COMMIT:0] commit_status_cnt = commit_status_cnt_q;
|
||||
commit_ready_o = (commit_status_cnt_q < DEPTH_COMMIT);
|
||||
// no store is pending if we don't have any element in the commit queue e.g.: it is empty
|
||||
no_st_pending_o = (commit_status_cnt_q == 0);
|
||||
// default assignments
|
||||
|
@ -201,12 +205,14 @@ module store_buffer (
|
|||
always_comb begin : address_checker
|
||||
page_offset_matches_o = 1'b0;
|
||||
// check if the LSBs are identical and the entry is valid
|
||||
for (int unsigned i = 0; i < DEPTH; i++) begin
|
||||
for (int unsigned i = 0; i < DEPTH_COMMIT; i++) begin
|
||||
// Check if the page offset matches and whether the entry is valid, for the commit queue
|
||||
if ((page_offset_i[11:3] == commit_queue_q[i].address[11:3]) && commit_queue_q[i].valid) begin
|
||||
page_offset_matches_o = 1'b1;
|
||||
break;
|
||||
end
|
||||
end
|
||||
for (int unsigned i = 0; i < DEPTH_SPEC; i++) begin
|
||||
// do the same for the speculative queue
|
||||
if ((page_offset_i[11:3] == speculative_queue_q[i].address[11:3]) && speculative_queue_q[i].valid) begin
|
||||
page_offset_matches_o = 1'b1;
|
||||
|
@ -255,6 +261,10 @@ module store_buffer (
|
|||
assert property (
|
||||
@(posedge clk_i) rst_ni && flush_i |-> !commit_i)
|
||||
else $error ("You are trying to commit and flush in the same cycle");
|
||||
|
||||
assert property (
|
||||
@(posedge clk_i) rst_ni && !ready_o |-> !valid_i)
|
||||
else $error ("You are trying to push new data although the buffer is not ready");
|
||||
`endif
|
||||
`endif
|
||||
endmodule
|
||||
|
|
|
@ -28,6 +28,8 @@ module store_unit (
|
|||
input lsu_ctrl_t lsu_ctrl_i,
|
||||
output logic pop_st_o,
|
||||
input logic commit_i,
|
||||
output logic commit_ready_o,
|
||||
|
||||
// store unit output port
|
||||
output logic valid_o,
|
||||
output logic [TRANS_ID_BITS-1:0] trans_id_o,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue