mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-23 21:57:11 -04:00
🐛 Fix in new IF, double taken instruction
This commit is contained in:
parent
2fd9992fd1
commit
ee7a63d51e
1 changed files with 20 additions and 19 deletions
|
@ -54,7 +54,7 @@ module if_stage (
|
|||
branchpredict_sbe branchpredict;
|
||||
} address_fifo_t;
|
||||
|
||||
logic [63:0] instr_addr_n, instr_addr_q;
|
||||
logic [63:0] instr_addr_n, instr_addr_q, fetch_address;
|
||||
branchpredict_sbe branchpredict_n, branchpredict_q;
|
||||
// Control signals
|
||||
address_fifo_t push_data, pop_data;
|
||||
|
@ -63,12 +63,12 @@ module if_stage (
|
|||
logic empty, full;
|
||||
|
||||
// we are busy if we are either waiting for a grant or if the FIFO is full
|
||||
assign if_busy_o = (CS == WAIT_GNT) || !fifo_ready || (CS == WAIT_ABORTED_REQUEST) || full;
|
||||
assign if_busy_o = ((CS == WAIT_GNT) || !fifo_ready || (CS == WAIT_ABORTED_REQUEST) || full) && (CS != WAIT_ABORTED);
|
||||
assign fetch_address = {fetch_address_i[63:2], 2'b0};
|
||||
|
||||
// --------------------------------------------------
|
||||
// Instruction fetch FSM
|
||||
// deals with instruction memory / instruction cache
|
||||
// Instruction Fetch FSM
|
||||
// Deals with Instruction Memory / Instruction Cache
|
||||
// --------------------------------------------------
|
||||
always_comb begin : instr_fetch_fsm
|
||||
|
||||
|
@ -80,20 +80,14 @@ module if_stage (
|
|||
pop_empty = instr_rvalid_i; // only pop the address queue
|
||||
|
||||
// get new data by default
|
||||
if (!if_busy_o) begin
|
||||
branchpredict_n = branch_predict_i;
|
||||
instr_addr_n = fetch_address_i;
|
||||
// if we are not ready, latch the current data
|
||||
end else begin
|
||||
branchpredict_n = branchpredict_q;
|
||||
instr_addr_n = instr_addr_q;
|
||||
end
|
||||
branchpredict_n = branch_predict_i;
|
||||
instr_addr_n = fetch_address_i;
|
||||
|
||||
case (CS)
|
||||
// we are idling, and can accept a new request
|
||||
IDLE: begin
|
||||
// check if we have space in the FIFO and we want to do a request
|
||||
if (fifo_ready && fetch_valid_i) begin
|
||||
// check if we have space in the FIFOs and we want to do a request
|
||||
if (fifo_ready && fetch_valid_i && !full) begin
|
||||
instr_req_o = 1'b1;
|
||||
// did we get a grant?
|
||||
if (instr_gnt_i)
|
||||
|
@ -110,6 +104,9 @@ module if_stage (
|
|||
instr_addr_o = {instr_addr_q[63:2], 2'b0};
|
||||
instr_req_o = 1'b1;
|
||||
|
||||
branchpredict_n = branchpredict_q;
|
||||
instr_addr_n = instr_addr_q;
|
||||
|
||||
if (instr_gnt_i) begin
|
||||
// push the old data
|
||||
push_data = { instr_addr_q, branchpredict_q };
|
||||
|
@ -125,7 +122,8 @@ module if_stage (
|
|||
instr_addr_o = fetch_address;
|
||||
|
||||
// prepare for next request, we've got one if the fetch_valid_i is high
|
||||
if (fifo_ready && fetch_valid_i) begin
|
||||
// we can take it if both queues have still places left to store the request
|
||||
if (fifo_ready && fetch_valid_i && !full) begin
|
||||
|
||||
instr_req_o = 1'b1;
|
||||
|
||||
|
@ -160,7 +158,10 @@ module if_stage (
|
|||
WAIT_ABORTED_REQUEST: begin
|
||||
// abort the current rvalid, we don't want it anymore
|
||||
fifo_valid = 1'b0;
|
||||
// Here we wait for the queue to be empty, we do not make any requests
|
||||
// save request data
|
||||
branchpredict_n = branchpredict_q;
|
||||
instr_addr_n = instr_addr_q;
|
||||
// Here we wait for the queue to be empty, we do not make any new requests
|
||||
if (empty)
|
||||
NS = WAIT_GNT;
|
||||
end
|
||||
|
@ -181,21 +182,21 @@ module if_stage (
|
|||
// ---------------------------------
|
||||
// Address and Branch-predict Queue
|
||||
// ---------------------------------
|
||||
|
||||
fifo #(
|
||||
.dtype ( address_fifo_t ),
|
||||
.DEPTH ( 2 ) // right now we support two outstanding transactions
|
||||
) i_fifo (
|
||||
.flush_i ( 1'b0 ), // do not flush, we need to keep track of all outstanding rvalids
|
||||
.full_o ( full ), // the address buffer is full
|
||||
.empty_o ( empty ), // .. or overflow
|
||||
.empty_o ( empty ), // ...or empty
|
||||
.single_element_o ( ), // isn't needed here
|
||||
.data_i ( push_data ),
|
||||
.push_i ( instr_gnt_i ), // if we got a grant push the address and data
|
||||
.data_o ( pop_data ),
|
||||
.data_o ( pop_data ), // data we send to the fetch_fifo, along with the instr data which comes from memory
|
||||
.pop_i ( fifo_valid || pop_empty ), // pop the data if we say that the fetch is valid
|
||||
.*
|
||||
);
|
||||
|
||||
// ---------------------------------
|
||||
// Fetch FIFO
|
||||
// consumes addresses and rdata
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue