mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-23 05:37:16 -04:00
Break store path AGU separate unit
This commit is contained in:
parent
f74d7728bc
commit
df88975656
2 changed files with 57 additions and 21 deletions
25
src/lsu.sv
25
src/lsu.sv
|
@ -120,6 +120,8 @@ module lsu #(
|
|||
logic [63:0] st_vaddr;
|
||||
logic translation_req;
|
||||
logic translation_valid;
|
||||
logic translation_valid_st;
|
||||
logic translation_valid_ld;
|
||||
logic [63:0] mmu_vaddr;
|
||||
logic [63:0] mmu_paddr;
|
||||
exception mmu_exception;
|
||||
|
@ -234,7 +236,7 @@ module lsu #(
|
|||
.translation_req_o ( st_translation_req ),
|
||||
.vaddr_o ( st_vaddr ),
|
||||
.paddr_i ( mmu_paddr ),
|
||||
.translation_valid_i ( translation_valid ),
|
||||
.translation_valid_i ( translation_valid_st ),
|
||||
.ex_i ( mmu_exception ),
|
||||
// Load Unit
|
||||
.page_offset_i ( page_offset ),
|
||||
|
@ -271,7 +273,7 @@ module lsu #(
|
|||
.translation_req_o ( ld_translation_req ),
|
||||
.vaddr_o ( ld_vaddr ),
|
||||
.paddr_i ( mmu_paddr ),
|
||||
.translation_valid_i ( translation_valid ),
|
||||
.translation_valid_i ( translation_valid_ld ),
|
||||
.ex_i ( mmu_exception ),
|
||||
// to store unit
|
||||
.page_offset_o ( page_offset ),
|
||||
|
@ -321,16 +323,21 @@ module lsu #(
|
|||
// the LSU is ready if both, stores and loads are ready because we do not know
|
||||
// which of the two we are getting
|
||||
lsu_ready_o = ld_ready_o && st_ready_o;
|
||||
// "arbitrate" MMU access, there is only one request possible
|
||||
translation_req = 1'b0;
|
||||
mmu_vaddr = 64'b0;
|
||||
// "arbitrate" MMU access
|
||||
translation_req = 1'b0;
|
||||
mmu_vaddr = 64'b0;
|
||||
translation_valid_st = 1'b0;
|
||||
translation_valid_ld = 1'b0;
|
||||
|
||||
// this arbitrates access to the MMU
|
||||
if (st_translation_req) begin
|
||||
translation_req = 1'b1;
|
||||
mmu_vaddr = st_vaddr;
|
||||
translation_req = 1'b1;
|
||||
mmu_vaddr = st_vaddr;
|
||||
translation_valid_st = translation_valid;
|
||||
end else if (ld_translation_req) begin
|
||||
translation_req = 1'b1;
|
||||
mmu_vaddr = ld_vaddr;
|
||||
translation_req = 1'b1;
|
||||
mmu_vaddr = ld_vaddr;
|
||||
translation_valid_ld = translation_valid;
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -69,7 +69,13 @@ module store_unit (
|
|||
logic st_ready;
|
||||
logic st_valid;
|
||||
|
||||
assign vaddr_o = vaddr_i;
|
||||
// vaddr and valid signal one cycle later
|
||||
logic [63:0] vaddr_n, vaddr_q;
|
||||
logic valid_n, valid_q;
|
||||
logic [TRANS_ID_BITS-1:0] trans_id_n, trans_id_q;
|
||||
|
||||
assign vaddr_o = vaddr_q;
|
||||
assign trans_id_o = trans_id_q;
|
||||
// ---------------
|
||||
// Store Control
|
||||
// ---------------
|
||||
|
@ -77,11 +83,10 @@ module store_unit (
|
|||
translation_req_o = 1'b0;
|
||||
valid_o = 1'b0;
|
||||
ready_o = 1'b1;
|
||||
trans_id_o = trans_id_i;
|
||||
ex_o = ex_i;
|
||||
st_valid = 1'b0;
|
||||
// we got a valid store
|
||||
if (valid_i) begin
|
||||
if (valid_q) begin
|
||||
// first do address translation, we need to do it in the first cycle since we want to share the MMU
|
||||
// between the load and the store unit. But we only know that when a new request arrives that we are not using
|
||||
// it at the same time.
|
||||
|
@ -92,19 +97,43 @@ module store_unit (
|
|||
valid_o = 1'b1;
|
||||
// post this store to the store buffer
|
||||
st_valid = 1'b1;
|
||||
// -----------------
|
||||
// Access Exception
|
||||
// -----------------
|
||||
// we got an address translation exception (access rights)
|
||||
// this will also assert the translation valid
|
||||
if (ex_i.valid) begin
|
||||
// the only difference is that we do not want to store this request
|
||||
st_valid = 1'b0;
|
||||
end
|
||||
// translation was not successful - stall here
|
||||
end else begin
|
||||
ready_o = 1'b0;
|
||||
end
|
||||
// -----------------
|
||||
// Access Exception
|
||||
// -----------------
|
||||
// we got an address translation exception (access rights)
|
||||
// this will also assert the translation valid
|
||||
if (ex_i.valid) begin
|
||||
// the only difference is that we do not want to store this request
|
||||
st_valid = 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
// Store 2nd register stage
|
||||
always_comb begin
|
||||
vaddr_n = vaddr_q;
|
||||
valid_n = valid_q;
|
||||
trans_id_n = trans_id_n;
|
||||
|
||||
if (ready_o) begin
|
||||
vaddr_n = vaddr_i;
|
||||
valid_n = valid_i;
|
||||
trans_id_n = trans_id_i;
|
||||
end
|
||||
end
|
||||
// Sequential Process for 2nd register stage
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if(~rst_ni) begin
|
||||
vaddr_q <= '0;
|
||||
valid_q <= 1'b0;
|
||||
trans_id_q <= '0;
|
||||
end else begin
|
||||
vaddr_q <= vaddr_n;
|
||||
valid_q <= valid_n;
|
||||
trans_id_q <= trans_id_n;
|
||||
end
|
||||
end
|
||||
// -----------
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue