Break store path AGU separate unit

This commit is contained in:
Florian Zaruba 2017-06-19 20:03:39 +02:00
parent f74d7728bc
commit df88975656
2 changed files with 57 additions and 21 deletions

View file

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

View file

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