mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-23 05:37:16 -04:00
🐎 Improve timing from 2.1 -> 1.85
This commit is contained in:
parent
465b090532
commit
f74d7728bc
2 changed files with 73 additions and 29 deletions
|
@ -128,9 +128,19 @@ module load_unit (
|
|||
ready_o = 1'b0;
|
||||
end else begin
|
||||
// put the request in the queue
|
||||
push = 1'b1;
|
||||
push = 1'b1;
|
||||
// we got a grant so we can send the tag in the next cycle
|
||||
NS = SEND_TAG;
|
||||
// -----------------
|
||||
// Access Exception
|
||||
// -----------------
|
||||
// we've got an exception
|
||||
// we got an exception so abort the request in the next cycle
|
||||
// this is like a normal memory request but without the extra checks which
|
||||
// would normally occur in SEND_TAG.
|
||||
if (ex_i.valid) begin
|
||||
NS = ABORT_TRANSACTION;
|
||||
end
|
||||
end
|
||||
// we got a TLB miss
|
||||
end else begin
|
||||
|
@ -144,27 +154,57 @@ module load_unit (
|
|||
// wait for the store buffer to train and the page offset to not match anymore
|
||||
NS = WAIT_PAGE_OFFSET;
|
||||
end
|
||||
// -----------------
|
||||
// Access Exception
|
||||
// -----------------
|
||||
// we've got an exception
|
||||
// we got an exception so abort the request in the next cycle
|
||||
// we handle this with an extra cycle since any other way would imply a critical
|
||||
// path from any exception to memory (because we would make another request)
|
||||
if (ex_i.valid) begin
|
||||
ready_o = 1'b0;
|
||||
NS = ABORT_TRANSACTION;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// abort the previous transaction without sending a new one
|
||||
// abort the current load and send a new one
|
||||
ABORT_TRANSACTION: begin
|
||||
ready_o = 1'b0;
|
||||
// send an abort signal
|
||||
tag_valid_o = 1'b1;
|
||||
kill_req_o = 1'b1;
|
||||
NS = IDLE;
|
||||
// -------------
|
||||
// New Request
|
||||
// -------------
|
||||
// we can make a new request if we got one
|
||||
if (valid_i) begin
|
||||
// do another address translation
|
||||
translation_req_o = 1'b1;
|
||||
if(!page_offset_matches_i) begin
|
||||
// make a load request to memory
|
||||
data_req_o = 1'b1;
|
||||
// the translation request we got is valid
|
||||
if (translation_valid_i) begin
|
||||
// save the physical address for the next cycle
|
||||
paddr_n = paddr_i;
|
||||
// we got no data grant so wait for the grant before sending the tag
|
||||
if (!data_gnt_i) begin
|
||||
NS = WAIT_GNT;
|
||||
ready_o = 1'b0;
|
||||
end else begin
|
||||
// put the request in the queue
|
||||
push = 1'b1;
|
||||
// we got a grant so we can send the tag in the next cycle
|
||||
NS = SEND_TAG;
|
||||
// got an exception and we already sent a transaction so abort it
|
||||
if (ex_i.valid) begin
|
||||
NS = ABORT_TRANSACTION;
|
||||
end
|
||||
end
|
||||
// we got a TLB miss
|
||||
end else begin
|
||||
// we need to abort the translation and let the PTW walker fix the TLB miss
|
||||
NS = WAIT_TRANSLATION;
|
||||
ready_o = 1'b0;
|
||||
end
|
||||
// page offset mis-match -> go back to idle
|
||||
end else begin
|
||||
NS = IDLE;
|
||||
end
|
||||
|
||||
// otherwise go back to idle
|
||||
end else begin
|
||||
NS = IDLE;
|
||||
end
|
||||
end
|
||||
|
||||
// wait here for the page offset to not match anymore
|
||||
|
@ -226,7 +266,7 @@ module load_unit (
|
|||
translation_req_o = 1'b1;
|
||||
if(!page_offset_matches_i) begin
|
||||
// make a load request to memory
|
||||
data_req_o = 1'b1;
|
||||
data_req_o = 1'b1;
|
||||
// the translation request we got is valid
|
||||
if (translation_valid_i) begin
|
||||
// save the physical address for the next cycle
|
||||
|
@ -237,9 +277,13 @@ module load_unit (
|
|||
ready_o = 1'b0;
|
||||
end else begin
|
||||
// put the request in the queue
|
||||
push = 1'b1;
|
||||
// we got a grant so we can send the tag in the next cycle
|
||||
push = 1'b1;
|
||||
// got an exception and we already sent a transaction so abort it
|
||||
NS = SEND_TAG;
|
||||
// got an exception
|
||||
if (ex_i.valid) begin
|
||||
NS = ABORT_TRANSACTION;
|
||||
end
|
||||
end
|
||||
// we got a TLB miss
|
||||
end else begin
|
||||
|
|
22
src/mmu.sv
22
src/mmu.sv
|
@ -224,7 +224,7 @@ module mmu #(
|
|||
instr_if_address_o = {itlb_content.ppn, fetch_vaddr_i[11:0]};
|
||||
// Mega page
|
||||
if (itlb_is_2M) begin
|
||||
instr_if_address_o[20:12] = fetch_vaddr_i[20:12];
|
||||
instr_if_address_o[20:12] = fetch_vaddr_i[20:12];
|
||||
end
|
||||
// Giga page
|
||||
if (itlb_is_1G) begin
|
||||
|
@ -236,16 +236,16 @@ module mmu #(
|
|||
// --------
|
||||
// if we hit the ITLB output the request signal immediately
|
||||
if (itlb_lu_hit) begin
|
||||
instr_if_data_req_o = fetch_req_i;
|
||||
// we got an access error
|
||||
if (iaccess_err) begin
|
||||
// immediately grant a fetch which threw an exception, and stop the request from happening
|
||||
instr_if_data_req_o = 1'b0;
|
||||
fetch_gnt_o = 1'b1;
|
||||
ierr_valid_n = 1'b1;
|
||||
// throw a page fault
|
||||
fetch_ex_n = {INSTR_ACCESS_FAULT, fetch_vaddr_i, 1'b1};
|
||||
end
|
||||
instr_if_data_req_o = fetch_req_i;
|
||||
// we got an access error
|
||||
if (iaccess_err) begin
|
||||
// immediately grant a fetch which threw an exception, and stop the request from happening
|
||||
instr_if_data_req_o = 1'b0;
|
||||
fetch_gnt_o = 1'b1;
|
||||
ierr_valid_n = 1'b1;
|
||||
// throw a page fault
|
||||
fetch_ex_n = {INSTR_ACCESS_FAULT, fetch_vaddr_i, 1'b1};
|
||||
end
|
||||
end else
|
||||
// ---------
|
||||
// ITLB Miss
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue