mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-22 04:47:25 -04:00
Move unalignment selection into prefetch buffer
This commit is contained in:
parent
5de1132e47
commit
965be8059a
3 changed files with 57 additions and 57 deletions
38
if_stage.sv
38
if_stage.sv
|
@ -111,9 +111,6 @@ module riscv_if_stage
|
|||
logic [31:0] fetch_rdata;
|
||||
logic [31:0] fetch_addr;
|
||||
|
||||
logic fetch_unaligned_valid;
|
||||
logic [31:0] fetch_unaligned_rdata;
|
||||
|
||||
|
||||
logic [31:0] instr_rdata_int;
|
||||
|
||||
|
@ -129,7 +126,6 @@ module riscv_if_stage
|
|||
|
||||
if (unaligned) begin
|
||||
current_pc_if_o = {fetch_addr[31:2], 2'b10};
|
||||
instr_rdata_int = fetch_unaligned_rdata;
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -195,14 +191,12 @@ module riscv_if_stage
|
|||
.branch_i ( branch_req ),
|
||||
.addr_i ( {fetch_addr_n[31:2], 2'b00} ),
|
||||
|
||||
.unaligned_i ( unaligned ), // is the current address unaligned?
|
||||
.ready_i ( fetch_ready ),
|
||||
.valid_o ( fetch_valid ),
|
||||
.rdata_o ( fetch_rdata ),
|
||||
.addr_o ( fetch_addr ),
|
||||
|
||||
.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 ),
|
||||
|
@ -224,14 +218,12 @@ module riscv_if_stage
|
|||
.branch_i ( branch_req ),
|
||||
.addr_i ( {fetch_addr_n[31:2], 2'b00} ),
|
||||
|
||||
.unaligned_i ( unaligned ), // is the current address unaligned?
|
||||
.ready_i ( fetch_ready ),
|
||||
.valid_o ( fetch_valid ),
|
||||
.rdata_o ( fetch_rdata ),
|
||||
.addr_o ( fetch_addr ),
|
||||
|
||||
.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 ),
|
||||
|
@ -304,26 +296,16 @@ module riscv_if_stage
|
|||
unaligned = 1'b1;
|
||||
|
||||
if (fetch_valid) begin
|
||||
if (is_compressed[1]) begin
|
||||
valid = 1'b1; // an instruction is ready for ID stage
|
||||
valid = 1'b1; // an instruction is ready for ID stage
|
||||
|
||||
if (req_i && if_valid_o) begin
|
||||
// next instruction will be aligned
|
||||
fetch_ready = 1'b1;
|
||||
if (req_i && if_valid_o) begin
|
||||
// next instruction will be aligned
|
||||
fetch_ready = 1'b1;
|
||||
|
||||
if (is_compressed[1])
|
||||
offset_fsm_ns = WAIT_ALIGNED;
|
||||
end
|
||||
end else begin
|
||||
// not compressed, we are looking at a 32 bit instruction
|
||||
|
||||
if (fetch_unaligned_valid) begin
|
||||
valid = 1'b1; // an instruction is ready for ID stage
|
||||
|
||||
if (req_i && if_valid_o) begin
|
||||
// next instruction will be unaligned
|
||||
fetch_ready = 1'b1;
|
||||
offset_fsm_ns = WAIT_UNALIGNED;
|
||||
end
|
||||
end
|
||||
else
|
||||
offset_fsm_ns = WAIT_UNALIGNED;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -40,8 +40,7 @@ module riscv_prefetch_L0_buffer
|
|||
output logic [31:0] rdata_o,
|
||||
output logic [31:0] addr_o,
|
||||
|
||||
output logic unaligned_valid_o,
|
||||
output logic [31:0] unaligned_rdata_o,
|
||||
input logic unaligned_i,
|
||||
|
||||
// goes to instruction memory / instruction cache
|
||||
output logic instr_req_o,
|
||||
|
@ -67,6 +66,10 @@ module riscv_prefetch_L0_buffer
|
|||
logic ready_L0;
|
||||
logic is_prefetch_q, is_prefetch_n;
|
||||
|
||||
// prepared data for output
|
||||
logic [31:0] rdata, unaligned_rdata;
|
||||
logic valid, unaligned_valid;
|
||||
|
||||
|
||||
assign busy_o = (CS != EMPTY && CS != VALID_L0) || instr_req_o;
|
||||
|
||||
|
@ -112,7 +115,7 @@ module riscv_prefetch_L0_buffer
|
|||
|
||||
always_comb
|
||||
begin
|
||||
valid_o = 1'b0;
|
||||
valid = 1'b0;
|
||||
valid_L0 = 1'b0;
|
||||
pointer_ns = pointer_cs;
|
||||
instr_req_o = 1'b0;
|
||||
|
@ -165,7 +168,7 @@ module riscv_prefetch_L0_buffer
|
|||
end
|
||||
else // else (branch_i)
|
||||
begin
|
||||
valid_o = instr_rvalid_i;
|
||||
valid = instr_rvalid_i;
|
||||
|
||||
// prepare address even if we don't need it
|
||||
// this removes the dependency for instr_addr_o on instr_rvalid_i
|
||||
|
@ -206,7 +209,7 @@ module riscv_prefetch_L0_buffer
|
|||
|
||||
VALID_L0:
|
||||
begin
|
||||
valid_o = 1'b1;
|
||||
valid = 1'b1;
|
||||
valid_L0 = 1'b1;
|
||||
|
||||
if (branch_i)
|
||||
|
@ -308,41 +311,41 @@ module riscv_prefetch_L0_buffer
|
|||
begin
|
||||
if (is_prefetch_q)
|
||||
begin
|
||||
rdata_o = previous_chunk;
|
||||
rdata = previous_chunk;
|
||||
addr_o = { last_address[31:4], 2'b11, 2'b00 };
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (valid_L0) begin
|
||||
rdata_o = L0_buffer[pointer_cs];
|
||||
rdata = L0_buffer[pointer_cs];
|
||||
addr_o = { current_address[31:4], pointer_cs, 2'b00 };
|
||||
end
|
||||
else
|
||||
begin
|
||||
rdata_o = instr_rdata_i[pointer_cs];
|
||||
rdata = instr_rdata_i[pointer_cs];
|
||||
addr_o = { current_address[31:4], pointer_cs, 2'b00 };
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// the lower part of unaligned_rdata_o is always the higher part of rdata_o
|
||||
assign unaligned_rdata_o[15:0] = rdata_o[31:16];
|
||||
// the lower part of unaligned_rdata is always the higher part of rdata
|
||||
assign unaligned_rdata[15:0] = rdata[31:16];
|
||||
|
||||
always_comb
|
||||
begin
|
||||
if (valid_L0) begin
|
||||
case(addr_o[3:2])
|
||||
2'b00: begin unaligned_rdata_o[31:16] = L0_buffer[1][15:0]; unaligned_valid_o = 1'b1; end
|
||||
2'b01: begin unaligned_rdata_o[31:16] = L0_buffer[2][15:0]; unaligned_valid_o = 1'b1; end
|
||||
2'b10: begin unaligned_rdata_o[31:16] = L0_buffer[3][15:0]; unaligned_valid_o = 1'b1; end
|
||||
2'b00: begin unaligned_rdata[31:16] = L0_buffer[1][15:0]; unaligned_valid = 1'b1; end
|
||||
2'b01: begin unaligned_rdata[31:16] = L0_buffer[2][15:0]; unaligned_valid = 1'b1; end
|
||||
2'b10: begin unaligned_rdata[31:16] = L0_buffer[3][15:0]; unaligned_valid = 1'b1; end
|
||||
// this state is only interesting if we have already done a prefetch
|
||||
2'b11: begin
|
||||
unaligned_rdata_o[31:16] = L0_buffer[0][15:0];
|
||||
unaligned_rdata[31:16] = L0_buffer[0][15:0];
|
||||
|
||||
if (is_prefetch_q) begin
|
||||
unaligned_valid_o = 1'b1;
|
||||
unaligned_valid = 1'b1;
|
||||
end else begin
|
||||
unaligned_valid_o = 1'b0;
|
||||
unaligned_valid = 1'b0;
|
||||
end
|
||||
end
|
||||
endcase // addr_o
|
||||
|
@ -351,18 +354,18 @@ module riscv_prefetch_L0_buffer
|
|||
// icache
|
||||
|
||||
case(addr_o[3:2])
|
||||
2'b00: begin unaligned_rdata_o[31:16] = instr_rdata_i[1][15:0]; unaligned_valid_o = instr_rvalid_i; end
|
||||
2'b01: begin unaligned_rdata_o[31:16] = instr_rdata_i[2][15:0]; unaligned_valid_o = instr_rvalid_i; end
|
||||
2'b10: begin unaligned_rdata_o[31:16] = instr_rdata_i[3][15:0]; unaligned_valid_o = instr_rvalid_i; end
|
||||
2'b00: begin unaligned_rdata[31:16] = instr_rdata_i[1][15:0]; unaligned_valid = instr_rvalid_i; end
|
||||
2'b01: begin unaligned_rdata[31:16] = instr_rdata_i[2][15:0]; unaligned_valid = instr_rvalid_i; end
|
||||
2'b10: begin unaligned_rdata[31:16] = instr_rdata_i[3][15:0]; unaligned_valid = instr_rvalid_i; end
|
||||
|
||||
2'b11:
|
||||
begin
|
||||
unaligned_rdata_o[31:16] = instr_rdata_i[0][15:0];
|
||||
unaligned_rdata[31:16] = instr_rdata_i[0][15:0];
|
||||
|
||||
if (is_prefetch_q)
|
||||
unaligned_valid_o = instr_rvalid_i;
|
||||
unaligned_valid = instr_rvalid_i;
|
||||
else
|
||||
unaligned_valid_o = 1'b0;
|
||||
unaligned_valid = 1'b0;
|
||||
end
|
||||
endcase // pointer_cs
|
||||
end
|
||||
|
@ -394,4 +397,11 @@ module riscv_prefetch_L0_buffer
|
|||
end
|
||||
end
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// instruction aligner (if unaligned)
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
assign rdata_o = unaligned_i ? unaligned_rdata : rdata;
|
||||
assign valid_o = unaligned_i ? unaligned_valid : valid;
|
||||
|
||||
endmodule // prefetch_L0_buffer
|
||||
|
|
|
@ -198,6 +198,7 @@ module riscv_prefetch_buffer
|
|||
input logic clk,
|
||||
input logic rst_n,
|
||||
|
||||
input logic unaligned_i,
|
||||
input logic req_i,
|
||||
input logic branch_i,
|
||||
input logic ready_i,
|
||||
|
@ -207,9 +208,6 @@ module riscv_prefetch_buffer
|
|||
output logic [31:0] rdata_o,
|
||||
output logic [31:0] addr_o,
|
||||
|
||||
output logic unaligned_valid_o,
|
||||
output logic [31:0] unaligned_rdata_o,
|
||||
|
||||
// goes to instruction memory / instruction cache
|
||||
output logic instr_req_o,
|
||||
output logic [31:0] instr_addr_o,
|
||||
|
@ -232,6 +230,9 @@ module riscv_prefetch_buffer
|
|||
logic fifo_rdata_valid;
|
||||
logic fifo_rdata_ready;
|
||||
|
||||
logic [31:0] rdata, unaligned_rdata;
|
||||
logic valid, unaligned_valid;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// prefetch buffer status
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -266,15 +267,22 @@ module riscv_prefetch_buffer
|
|||
.in_rdata_ready_o ( fifo_rdata_ready ),
|
||||
.in_rdata_i ( instr_rdata_i ),
|
||||
|
||||
.out_valid_o ( valid_o ),
|
||||
.out_valid_o ( valid ),
|
||||
.out_ready_i ( ready_i ),
|
||||
.out_rdata_o ( rdata_o ),
|
||||
.out_rdata_o ( rdata ),
|
||||
.out_addr_o ( addr_o ),
|
||||
|
||||
.out_unaligned_valid_o ( unaligned_valid_o ),
|
||||
.out_unaligned_rdata_o ( unaligned_rdata_o )
|
||||
.out_unaligned_valid_o ( unaligned_valid ),
|
||||
.out_unaligned_rdata_o ( unaligned_rdata )
|
||||
);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// instruction aligner (if unaligned)
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
assign rdata_o = unaligned_i ? unaligned_rdata : rdata;
|
||||
assign valid_o = unaligned_i ? unaligned_valid : valid;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// instruction fetch FSM
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue