Rename instr_core_intf to prefetch_buffer, add if_busy signal again

This commit is contained in:
Andreas Traber 2015-09-10 09:54:43 +02:00
parent 84ea2c90ee
commit 6fb05eab34
4 changed files with 44 additions and 61 deletions

View file

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

View file

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

View file

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

View file

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