mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-22 04:47:25 -04:00
Rename instr_core_intf to prefetch_buffer, add if_busy signal again
This commit is contained in:
parent
84ea2c90ee
commit
6fb05eab34
4 changed files with 44 additions and 61 deletions
|
@ -959,7 +959,7 @@ module controller
|
|||
// Default values
|
||||
instr_req_o = 1'b1;
|
||||
|
||||
pc_mux_sel_o = `PC_INCR;
|
||||
pc_mux_sel_o = `PC_BOOT;
|
||||
|
||||
ctrl_fsm_ns = ctrl_fsm_cs;
|
||||
|
||||
|
|
31
if_stage.sv
31
if_stage.sv
|
@ -96,7 +96,8 @@ module if_stage
|
|||
logic unaligned;
|
||||
logic unaligned_jump;
|
||||
|
||||
// instr_core_interface
|
||||
// prefetch buffer related signals
|
||||
logic prefetch_busy;
|
||||
logic branch_req, branch_req_Q;
|
||||
logic [31:0] fetch_addr_n;
|
||||
|
||||
|
@ -151,15 +152,13 @@ module if_stage
|
|||
`PC_BOOT: fetch_addr_n = {boot_addr_i[31:5], `EXC_OFF_RST};
|
||||
`PC_JUMP: fetch_addr_n = {jump_target_id_i[31:2], 2'b0};
|
||||
`PC_BRANCH: fetch_addr_n = {jump_target_ex_i[31:2], 2'b0};
|
||||
// TODO: remove the next entry
|
||||
`PC_INCR: fetch_addr_n = 'X; // no longer needed, remove!
|
||||
`PC_EXCEPTION: fetch_addr_n = exc_pc; // set PC to exception handler
|
||||
`PC_ERET: fetch_addr_n = exception_pc_reg_i; // PC is restored when returning from IRQ/exception
|
||||
`PC_HWLOOP: fetch_addr_n = hwloop_target_i; // PC is taken from hwloop start addr
|
||||
`PC_DBG_NPC: fetch_addr_n = dbg_npc_i; // PC is taken from debug unit
|
||||
default:
|
||||
begin
|
||||
fetch_addr_n = {boot_addr_i[31:5], `EXC_OFF_RST};
|
||||
fetch_addr_n = 'X;
|
||||
// synopsys translate_off
|
||||
$display("%t: Illegal pc_mux_sel value (%0d)!", $time, pc_mux_sel_i);
|
||||
// synopsys translate_on
|
||||
|
@ -181,14 +180,14 @@ module if_stage
|
|||
end
|
||||
|
||||
|
||||
// cache fetch interface
|
||||
instr_core_interface instr_core_if_i
|
||||
// prefetch buffer, caches a fixed number of instructions
|
||||
prefetch_buffer prefetch_buffer_i
|
||||
(
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
|
||||
.req_i ( 1'b1 ),
|
||||
.clear_i ( branch_req ),
|
||||
.req_i ( 1'b1 ), // TODO: FETCH_ENABLE!
|
||||
.branch_i ( branch_req ),
|
||||
.addr_i ( fetch_addr_n ),
|
||||
|
||||
.ready_i ( fetch_ready ),
|
||||
|
@ -199,11 +198,15 @@ module if_stage
|
|||
.unaligned_valid_o ( fetch_unaligned_valid ),
|
||||
.unaligned_rdata_o ( fetch_unaligned_rdata ),
|
||||
|
||||
// goes to instruction memory / instruction cache
|
||||
.instr_req_o ( instr_req_o ),
|
||||
.instr_addr_o ( instr_addr_o ),
|
||||
.instr_gnt_i ( instr_gnt_i ),
|
||||
.instr_rvalid_i ( instr_rvalid_i ),
|
||||
.instr_rdata_i ( instr_rdata_i )
|
||||
.instr_rdata_i ( instr_rdata_i ),
|
||||
|
||||
// Prefetch Buffer Status
|
||||
.busy_o ( prefetch_busy )
|
||||
);
|
||||
|
||||
|
||||
|
@ -303,6 +306,7 @@ module if_stage
|
|||
|
||||
|
||||
// take care of jumps and branches
|
||||
// only send one branch request per jump/branch
|
||||
if (branch_req_Q == 1'b0) begin
|
||||
if (jump_in_ex_i == `BRANCH_COND) begin
|
||||
if (branch_decision_i) begin
|
||||
|
@ -331,14 +335,7 @@ module if_stage
|
|||
end
|
||||
|
||||
|
||||
assign if_busy_o = 1'b1; // TODO
|
||||
// assign if_busy_o = ~(offset_fsm_cs == IDLE ||
|
||||
// offset_fsm_cs == VALID_JUMPED_ALIGNED ||
|
||||
// offset_fsm_cs == VALID_JUMPED_UNALIGNED ||
|
||||
// offset_fsm_cs == VALID_ALIGNED ||
|
||||
// offset_fsm_cs == VALID_UNALIGNED_32 ||
|
||||
// offset_fsm_cs == UNALIGNED_16) || instr_req_o;
|
||||
|
||||
assign if_busy_o = prefetch_busy;
|
||||
|
||||
|
||||
// compressed instruction decoding, or more precisely compressed instruction
|
||||
|
|
|
@ -359,7 +359,6 @@ endfunction // prettyPrintInstruction
|
|||
|
||||
// PC mux selector defines
|
||||
`define PC_BOOT 3'b000
|
||||
`define PC_INCR 3'b001
|
||||
`define PC_JUMP 3'b010
|
||||
`define PC_BRANCH 3'b011
|
||||
`define PC_EXCEPTION 3'b100
|
||||
|
|
|
@ -2,19 +2,19 @@
|
|||
// Company: IIS @ ETHZ - Federal Institute of Technology //
|
||||
// DEI @ UNIBO - University of Bologna //
|
||||
// //
|
||||
// Engineer: Igor Loi - igor.loi@unibo.it //
|
||||
// Engineer: Andreas Traber - atraber@iis.ee.ethz.ch //
|
||||
// //
|
||||
// Additional contributions by: //
|
||||
// //
|
||||
// //
|
||||
// Create Date: 06/08/2014 //
|
||||
// Design Name: RISC-V processor core //
|
||||
// Module Name: instr_core_interface.sv //
|
||||
// Module Name: prefetch_buffer.sv //
|
||||
// Project Name: RI5CY //
|
||||
// Language: SystemVerilog //
|
||||
// //
|
||||
// Description: Instruction Fetch interface used to properly handle //
|
||||
// cache stalls //
|
||||
// Description: Prefetch Buffer that caches instructions. This cuts overly //
|
||||
// long critical paths to the instruction cache //
|
||||
// //
|
||||
// Revision: //
|
||||
// Revision v0.1 - File Created //
|
||||
|
@ -191,15 +191,15 @@ module fetch_fifo
|
|||
|
||||
endmodule
|
||||
|
||||
// clear_i deletes everything up to now, i.e. it assumes that addr_i now has
|
||||
// branch_i deletes everything up to now, i.e. it assumes that addr_i now has
|
||||
// the correct state and uses the current cycle's addr_i to fetch new data
|
||||
module instr_core_interface
|
||||
module prefetch_buffer
|
||||
(
|
||||
input logic clk,
|
||||
input logic rst_n,
|
||||
|
||||
input logic req_i,
|
||||
input logic clear_i,
|
||||
input logic branch_i,
|
||||
input logic ready_i,
|
||||
input logic [31:0] addr_i,
|
||||
|
||||
|
@ -215,12 +215,11 @@ module instr_core_interface
|
|||
output logic [31:0] instr_addr_o,
|
||||
input logic instr_gnt_i,
|
||||
input logic instr_rvalid_i,
|
||||
input logic [31:0] instr_rdata_i
|
||||
);
|
||||
input logic [31:0] instr_rdata_i,
|
||||
|
||||
// TODO: THERE IS A PROBLEM WIHT REQ_I AND CLEAR_I
|
||||
// i.e. what happens if req_i is low and clear_i is high? the core will miss
|
||||
// the updated address....
|
||||
// Prefetch Buffer Status
|
||||
output logic busy_o
|
||||
);
|
||||
|
||||
enum logic [1:0] {IDLE, WAIT_GNT, WAIT_RVALID, WAIT_ABORTED } CS, NS;
|
||||
|
||||
|
@ -233,12 +232,17 @@ module instr_core_interface
|
|||
logic fifo_rdata_valid;
|
||||
logic fifo_rdata_ready;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// prefetch buffer status
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
assign busy_o = (CS != IDLE) || instr_req_o;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// address selection and increase
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
assign addr_next = (clear_i) ? addr_i : (fifo_last_addr + 32'd4);
|
||||
assign addr_next = (branch_i) ? addr_i : (fifo_last_addr + 32'd4);
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -251,7 +255,7 @@ module instr_core_interface
|
|||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
|
||||
.clear_i ( clear_i ),
|
||||
.clear_i ( branch_i ),
|
||||
|
||||
.in_addr_valid_i ( fifo_addr_valid ),
|
||||
.in_addr_ready_o ( fifo_addr_ready ),
|
||||
|
@ -291,7 +295,7 @@ module instr_core_interface
|
|||
begin
|
||||
instr_req_o = 1'b0;
|
||||
|
||||
if (req_i && fifo_addr_ready) begin
|
||||
if ((req_i && fifo_addr_ready) || branch_i) begin
|
||||
instr_req_o = 1'b1;
|
||||
|
||||
fifo_addr_valid = 1'b1;
|
||||
|
@ -307,43 +311,26 @@ module instr_core_interface
|
|||
// we sent a request but did not yet get a grant
|
||||
WAIT_GNT:
|
||||
begin
|
||||
instr_req_o = 1'b1;
|
||||
|
||||
if (clear_i) begin
|
||||
if (branch_i) begin
|
||||
instr_addr_o = addr_next;
|
||||
|
||||
if (req_i && fifo_addr_ready) begin
|
||||
instr_req_o = 1'b1;
|
||||
|
||||
fifo_addr_valid = 1'b1;
|
||||
|
||||
if(instr_gnt_i) //~> granted request
|
||||
NS = WAIT_ABORTED;
|
||||
else begin //~> got a request but no grant
|
||||
NS = WAIT_GNT;
|
||||
end
|
||||
end else begin
|
||||
if(instr_gnt_i) //~> granted request
|
||||
NS = WAIT_ABORTED;
|
||||
else begin //~> got a request but no grant
|
||||
NS = IDLE;
|
||||
end
|
||||
end
|
||||
|
||||
fifo_addr_valid = 1'b1;
|
||||
end else begin
|
||||
instr_req_o = 1'b1;
|
||||
instr_addr_o = fifo_last_addr;
|
||||
|
||||
if(instr_gnt_i)
|
||||
NS = WAIT_RVALID;
|
||||
else
|
||||
NS = WAIT_GNT;
|
||||
end
|
||||
|
||||
if(instr_gnt_i)
|
||||
NS = WAIT_RVALID;
|
||||
else
|
||||
NS = WAIT_GNT;
|
||||
end // case: WAIT_GNT
|
||||
|
||||
// we wait for rvalid, after that we are ready to serve a new request
|
||||
WAIT_RVALID: begin
|
||||
|
||||
if ((req_i && fifo_addr_ready) || clear_i) begin
|
||||
if ((req_i && fifo_addr_ready) || branch_i) begin
|
||||
// prepare for next request
|
||||
instr_req_o = 1'b1;
|
||||
|
||||
|
@ -359,7 +346,7 @@ module instr_core_interface
|
|||
end else begin
|
||||
// we are requested to abort our current request
|
||||
// we didn't get an rvalid yet, so wait for it
|
||||
if (clear_i) begin
|
||||
if (branch_i) begin
|
||||
fifo_addr_valid = 1'b1;
|
||||
NS = WAIT_ABORTED;
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue