mirror of
https://github.com/openhwgroup/cve2.git
synced 2025-04-22 04:57:25 -04:00
Simplified fetch logic a little bit
This will probably not get us much performance though
This commit is contained in:
parent
fbf8874e13
commit
d5802e5e62
4 changed files with 43 additions and 114 deletions
|
@ -498,7 +498,7 @@ module id_stage
|
|||
.rst_n ( rst_n ),
|
||||
|
||||
// Read port a
|
||||
.raddr_a_i ( (dbg_reg_mux_i == 1'b0) ? regfile_addr_ra_id : dbg_reg_addr_i ),
|
||||
.raddr_a_i ( regfile_addr_ra_id ),
|
||||
.rdata_a_o ( regfile_data_ra_id ),
|
||||
|
||||
// Read port b
|
||||
|
@ -506,7 +506,7 @@ module id_stage
|
|||
.rdata_b_o ( regfile_data_rb_id ),
|
||||
|
||||
// Read port c
|
||||
.raddr_c_i ( regfile_addr_rc_id ),
|
||||
.raddr_c_i ( (dbg_reg_mux_i == 1'b0) ? regfile_addr_rc_id : dbg_reg_addr_i ),
|
||||
.rdata_c_o ( regfile_data_rc_id ),
|
||||
|
||||
// Write port a
|
||||
|
|
36
if_stage.sv
36
if_stage.sv
|
@ -101,8 +101,7 @@ module if_stage
|
|||
logic fetch_req;
|
||||
logic [31:0] fetch_rdata;
|
||||
logic fetch_valid;
|
||||
logic [31:0] fetch_addr, fetch_addr_n;
|
||||
logic [31:0] fetch_addr_Q;
|
||||
logic [31:0] fetch_addr_n, fetch_addr_Q, fetch_addr_QQ;
|
||||
|
||||
logic [31:0] instr_rdata_int;
|
||||
|
||||
|
@ -117,27 +116,27 @@ module if_stage
|
|||
begin
|
||||
// default values for regular aligned access
|
||||
instr_rdata_int = fetch_rdata;
|
||||
current_pc_if_o = {fetch_addr[31:2], 2'b00};
|
||||
current_pc_if_o = {fetch_addr_Q[31:2], 2'b00};
|
||||
|
||||
if (unaligned) begin
|
||||
if (crossword) begin
|
||||
// cross-word access, regular instruction
|
||||
instr_rdata_int = {fetch_rdata[15:0], data_arr};
|
||||
current_pc_if_o = {fetch_addr_Q[31:2], 2'b10};
|
||||
current_pc_if_o = {fetch_addr_QQ[31:2], 2'b10};
|
||||
end else begin
|
||||
// unaligned compressed instruction
|
||||
// don't care about upper half-word, insert good value for
|
||||
// optimization
|
||||
instr_rdata_int = {fetch_rdata[15:0], fetch_rdata[31:16]};
|
||||
current_pc_if_o = {fetch_addr[31:2], 2'b10};
|
||||
current_pc_if_o = {fetch_addr_Q[31:2], 2'b10};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// compressed instruction detection
|
||||
assign is_compressed[0] = fetch_rdata[1:0] != 2'b11;
|
||||
assign is_compressed[1] = fetch_rdata[17:16] != 2'b11;
|
||||
assign is_compressed[0] = (fetch_rdata[1:0] != 2'b11);
|
||||
assign is_compressed[1] = (fetch_rdata[17:16] != 2'b11);
|
||||
|
||||
|
||||
// exception PC selection mux
|
||||
|
@ -158,7 +157,7 @@ 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};
|
||||
`PC_INCR: fetch_addr_n = fetch_addr + 32'd4; // incremented PC
|
||||
`PC_INCR: fetch_addr_n = fetch_addr_Q + 32'd4; // incremented PC
|
||||
`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 = pc_from_hwloop_i; // PC is taken from hwloop start addr
|
||||
|
@ -195,16 +194,12 @@ module if_stage
|
|||
.valid_o ( fetch_valid ),
|
||||
.addr_i ( fetch_addr_n ),
|
||||
.rdata_o ( fetch_rdata ),
|
||||
.last_addr_o ( fetch_addr ),
|
||||
|
||||
.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 ),
|
||||
|
||||
.stall_if_i ( 1'b0 ),
|
||||
.drop_request_i ( 1'b0 ) // TODO: Remove?
|
||||
.instr_rdata_i ( instr_rdata_i )
|
||||
);
|
||||
|
||||
|
||||
|
@ -403,15 +398,20 @@ module if_stage
|
|||
|
||||
|
||||
// store instr_core_if data in local cache
|
||||
// store last address used to fetch an instruction
|
||||
// we also store the address we used before, so
|
||||
// fetch_addr_n -> fetch_addr_Q -> fetch_addr_QQ
|
||||
always_ff @(posedge clk, negedge rst_n)
|
||||
begin
|
||||
if (rst_n == 1'b0) begin
|
||||
data_arr <= 16'b0;
|
||||
fetch_addr_Q <= 32'b0;
|
||||
data_arr <= 16'b0;
|
||||
fetch_addr_Q <= 32'b0;
|
||||
fetch_addr_QQ <= 32'b0;
|
||||
end else begin
|
||||
if (fetch_req) begin
|
||||
data_arr <= fetch_rdata[31:16];
|
||||
fetch_addr_Q <= fetch_addr;
|
||||
data_arr <= fetch_rdata[31:16];
|
||||
fetch_addr_Q <= fetch_addr_n;
|
||||
fetch_addr_QQ <= fetch_addr_Q;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -421,7 +421,7 @@ module if_stage
|
|||
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;
|
||||
offset_fsm_cs == UNALIGNED_16) || instr_req_o;
|
||||
|
||||
|
||||
// IF-ID pipeline registers, frozen when the ID stage is stalled
|
||||
|
|
|
@ -359,7 +359,6 @@ endfunction // prettyPrintInstruction
|
|||
`define PC_EXCEPTION 3'b100
|
||||
`define PC_ERET 3'b101
|
||||
`define PC_HWLOOP 3'b110
|
||||
`define PC_BRANCH_PRED 3'b111
|
||||
|
||||
// Exception PC mux selector defines
|
||||
`define EXC_PC_NO_INCR 2'b00
|
||||
|
|
|
@ -39,16 +39,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 stall_if_i,
|
||||
|
||||
input logic drop_request_i
|
||||
input logic [31:0] instr_rdata_i
|
||||
);
|
||||
|
||||
enum logic [2:0] {IDLE, PENDING, WAIT_RVALID, WAIT_IF_STALL, WAIT_GNT, ABORT} CS, NS;
|
||||
enum logic [1:0] {IDLE, PENDING, WAIT_RVALID, WAIT_GNT } CS, NS;
|
||||
|
||||
logic save_rdata;
|
||||
logic [31:0] rdata_Q;
|
||||
|
||||
logic wait_gnt;
|
||||
|
@ -72,46 +67,40 @@ module instr_core_interface
|
|||
if (wait_gnt)
|
||||
addr_Q <= addr_i;
|
||||
|
||||
if (save_rdata)
|
||||
if (instr_rvalid_i)
|
||||
rdata_Q <= instr_rdata_i;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
assign last_addr_o = addr_Q;
|
||||
|
||||
assign valid_o = instr_rvalid_i;
|
||||
|
||||
always_comb
|
||||
begin
|
||||
instr_req_o = 1'b0;
|
||||
valid_o = 1'b0;
|
||||
save_rdata = 1'b0;
|
||||
rdata_o = instr_rdata_i;
|
||||
instr_addr_o = addr_i;
|
||||
wait_gnt = 1'b0;
|
||||
|
||||
unique case(CS)
|
||||
// default state, not waiting for requested data
|
||||
IDLE:
|
||||
begin
|
||||
instr_req_o = req_i;
|
||||
valid_o = 1'b0;
|
||||
rdata_o = rdata_Q;
|
||||
|
||||
if(req_i)
|
||||
begin
|
||||
NS = IDLE;
|
||||
instr_req_o = req_i;
|
||||
|
||||
if(req_i) begin
|
||||
if(instr_gnt_i) //~> granted request
|
||||
NS = PENDING;
|
||||
else begin //~> got a request but no grant
|
||||
NS = WAIT_GNT;
|
||||
wait_gnt = 1'b1;
|
||||
end
|
||||
end //~> if(req_i == 0)
|
||||
else
|
||||
begin
|
||||
NS = IDLE;
|
||||
end
|
||||
end // case: IDLE
|
||||
|
||||
// we sent a request but did not yet get a grant
|
||||
WAIT_GNT:
|
||||
begin
|
||||
instr_addr_o = addr_Q;
|
||||
|
@ -121,81 +110,39 @@ module instr_core_interface
|
|||
NS = PENDING;
|
||||
else
|
||||
begin
|
||||
// if (drop_request_i)
|
||||
// NS = IDLE;
|
||||
// else
|
||||
NS = WAIT_GNT;
|
||||
NS = WAIT_GNT;
|
||||
end
|
||||
end // case: WAIT_GNT
|
||||
|
||||
// we got a grant, so now we wait for the rvalid
|
||||
PENDING:
|
||||
begin
|
||||
if (instr_rvalid_i) begin
|
||||
save_rdata = 1'b1;
|
||||
valid_o = 1'b1;
|
||||
NS = IDLE;
|
||||
instr_req_o = req_i;
|
||||
|
||||
if (stall_if_i) begin
|
||||
NS = WAIT_IF_STALL;
|
||||
instr_req_o = 1'b0;
|
||||
end else begin
|
||||
NS = IDLE;
|
||||
instr_req_o = req_i;
|
||||
|
||||
if (req_i) begin
|
||||
if (instr_gnt_i) begin
|
||||
NS = PENDING;
|
||||
end else begin
|
||||
NS = WAIT_GNT;
|
||||
wait_gnt = 1'b1;
|
||||
end
|
||||
if (req_i) begin
|
||||
if (instr_gnt_i) begin
|
||||
NS = PENDING;
|
||||
end else begin
|
||||
NS = WAIT_GNT;
|
||||
wait_gnt = 1'b1;
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
NS = WAIT_RVALID;
|
||||
instr_req_o = 1'b0;
|
||||
valid_o = 1'b0;
|
||||
end
|
||||
end // case: PENDING
|
||||
|
||||
// we wait for rvalid, after that we are ready to serve a new request
|
||||
WAIT_RVALID :
|
||||
begin
|
||||
NS = WAIT_RVALID;
|
||||
valid_o = 1'b0;
|
||||
instr_req_o = 1'b0;
|
||||
|
||||
if (instr_rvalid_i) begin
|
||||
valid_o = 1'b1;
|
||||
save_rdata = 1'b1;
|
||||
|
||||
if (stall_if_i) begin
|
||||
instr_req_o = 1'b0;
|
||||
NS = WAIT_IF_STALL;
|
||||
end else begin
|
||||
instr_req_o = req_i;
|
||||
if (req_i) begin
|
||||
if (instr_gnt_i)
|
||||
NS = PENDING;
|
||||
else begin
|
||||
NS = WAIT_GNT;
|
||||
wait_gnt = 1'b1;
|
||||
end
|
||||
end else
|
||||
NS = IDLE;
|
||||
end
|
||||
end
|
||||
end // case: WAIT_RVALID
|
||||
|
||||
WAIT_IF_STALL:
|
||||
begin
|
||||
valid_o = 1'b1;
|
||||
rdata_o = rdata_Q;
|
||||
|
||||
if (stall_if_i) begin
|
||||
NS = WAIT_IF_STALL;
|
||||
instr_req_o = 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
NS = IDLE;
|
||||
instr_req_o = req_i;
|
||||
|
||||
if (req_i) begin
|
||||
|
@ -205,26 +152,9 @@ module instr_core_interface
|
|||
NS = WAIT_GNT;
|
||||
wait_gnt = 1'b1;
|
||||
end
|
||||
end else
|
||||
NS = IDLE;
|
||||
end
|
||||
end // case: WAIT_IF_STALL
|
||||
|
||||
ABORT:
|
||||
begin
|
||||
NS = IDLE;
|
||||
valid_o = 1'b1;
|
||||
instr_req_o = 1'b1;
|
||||
|
||||
if (req_i) begin
|
||||
if(instr_gnt_i) //~> granted request
|
||||
NS = PENDING;
|
||||
else begin //~> got a request but no grant
|
||||
NS = WAIT_GNT;
|
||||
wait_gnt = 1'b1;
|
||||
end
|
||||
end
|
||||
end // case: ABORT
|
||||
end // case: WAIT_RVALID
|
||||
|
||||
default:
|
||||
begin
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue