fetch mmu fault propagation

This commit is contained in:
Eric Matthews 2020-09-07 13:26:17 -07:00
parent d522444a7c
commit a309d88e67
5 changed files with 29 additions and 16 deletions

View file

@ -158,7 +158,7 @@ module decode_and_issue (
if (issue_stage_ready) begin
issue.pc <= decode.pc;
issue.instruction <= decode.instruction;
issue.addr_valid <= decode.addr_valid;
issue.fetch_metadata <= decode.fetch_metadata;
issue.fn3 <= fn3;
issue.opcode <= opcode;
issue.rs_addr[RS1] <= rs1_addr;
@ -541,7 +541,7 @@ module decode_and_issue (
//TODO: convert into exception and expand support into all fetch stage exceptions
//If an invalid fetch address has reached the issue stage and has not been flushed as a branch, processor state is corrupted
invalid_fetch_address_assertion:
assert property (@(posedge clk) disable iff (rst) (issue.stage_valid & ~issue.addr_valid) |-> (gc_fetch_flush))
assert property (@(posedge clk) disable iff (rst) (issue.stage_valid & (~issue.fetch_metadata.ok & issue.fetch_metadata.error_code == FETCH_ACCESS_FAULT)) |-> (gc_fetch_flush))
else $error("invalid fetch address");
////////////////////////////////////////////////////

View file

@ -40,7 +40,7 @@ module fetch(
input logic pc_id_available,
output logic pc_id_assigned,
output logic fetch_complete,
output logic fetch_address_valid,
output fetch_metadata_t fetch_metadata,
branch_predictor_interface.fetch bp,
ras_interface.fetch ras,
@ -76,6 +76,7 @@ module fetch(
typedef struct packed{
logic address_valid;
logic mmu_fault;
logic [NUM_SUB_UNITS_W-1:0] subunit_id;
} fetch_attributes_t;
fetch_attributes_t fetch_attr_next;
@ -159,12 +160,12 @@ module fetch(
assign flush_or_rst = (rst | gc_fetch_flush);
assign new_mem_request = (~tlb_on | tlb.done) & pc_id_available & units_ready & ~gc_fetch_hold & ~exception_pending;
assign pc_id_assigned = new_mem_request;
assign pc_id_assigned = new_mem_request | tlb.is_fault;
//////////////////////////////////////////////
//Subunit Tracking
assign fetch_attr_fifo.push = new_mem_request;
assign fetch_attr_fifo.potential_push = new_mem_request;
assign fetch_attr_fifo.push = new_mem_request | tlb.is_fault;
assign fetch_attr_fifo.potential_push = new_mem_request | tlb.is_fault;
assign fetch_attr_fifo.pop = fetch_complete;
one_hot_to_integer #(NUM_SUB_UNITS) hit_way_conv (
.clk (clk),
@ -173,6 +174,7 @@ module fetch(
.int_out (fetch_attr_next.subunit_id)
);
assign fetch_attr_next.address_valid = address_valid;
assign fetch_attr_next.mmu_fault = tlb.is_fault;
assign fetch_attr_fifo.data_in = fetch_attr_next;
@ -232,7 +234,8 @@ module fetch(
assign if_pc = pc;
assign fetch_instruction = unit_data_array[fetch_attr.subunit_id];
assign fetch_complete = (|unit_data_valid) | (fetch_attr_fifo.valid & ~fetch_attr.address_valid);//allow instruction to propagate to decode if address is invalid
assign fetch_address_valid = fetch_attr.address_valid;
assign fetch_metadata.ok = fetch_attr.address_valid & ~fetch_attr.mmu_fault;
assign fetch_metadata.error_code = fetch_attr.mmu_fault ? FETCH_PAGE_FAULT : FETCH_ACCESS_FAULT;
////////////////////////////////////////////////////
//End of Implementation

View file

@ -41,7 +41,7 @@ module instruction_metadata_and_id_management
output id_t fetch_id,
input logic fetch_complete,
input logic [31:0] fetch_instruction,
input logic fetch_address_valid,
input fetch_metadata_t fetch_metadata,
//Decode ID
output decode_packet_t decode,
@ -87,7 +87,7 @@ module instruction_metadata_and_id_management
logic [4:0] rd_addr_table [MAX_IDS];
logic [$bits(branch_metadata_t)-1:0] branch_metadata_table [MAX_IDS];
logic [31:0] rd_table [MAX_IDS];
logic [$bits(fetch_metadata_t)-1:0] fetch_metadata_table [MAX_IDS];
localparam LOG2_MAX_IDS = $clog2(MAX_IDS);
id_t clear_index;
@ -151,7 +151,7 @@ module instruction_metadata_and_id_management
//valid fetched address table
always_ff @ (posedge clk) begin
if (fetch_complete)
valid_fetch_addr_table[fetch_id] <= fetch_address_valid;
fetch_metadata_table[fetch_id] <= fetch_metadata;
end
@ -343,7 +343,7 @@ module instruction_metadata_and_id_management
assign decode.valid = fetched_count[LOG2_MAX_IDS];
assign decode.pc = pc_table[decode_id];
assign decode.instruction = instruction_table[decode_id];
assign decode.addr_valid = valid_fetch_addr_table[decode_id];
assign decode.fetch_metadata = fetch_metadata_table[decode_id];
//Branch Predictor
assign branch_metadata_ex = branch_metadata_table[branch_id];

View file

@ -94,7 +94,7 @@ module taiga (
id_t fetch_id;
logic fetch_complete;
logic [31:0] fetch_instruction;
logic fetch_address_valid;
fetch_metadata_t fetch_metadata;
//Decode stage
logic decode_advance;
decode_packet_t decode;
@ -218,7 +218,7 @@ module taiga (
.fetch_id (fetch_id),
.fetch_complete (fetch_complete),
.fetch_instruction (fetch_instruction),
.fetch_address_valid (fetch_address_valid),
.fetch_metadata (fetch_metadata),
.decode (decode),
.decode_advance (decode_advance),
.issue (issue),
@ -256,7 +256,7 @@ module taiga (
.pc_id_available (pc_id_available),
.pc_id_assigned (pc_id_assigned),
.fetch_complete (fetch_complete),
.fetch_address_valid (fetch_address_valid),
.fetch_metadata (fetch_metadata),
.bp (bp),
.ras (ras),
.if_pc (if_pc),

View file

@ -74,12 +74,22 @@ package taiga_types;
logic [BRANCH_PREDICTOR_WAYS-1:0] branch_predictor_update_way;
} branch_metadata_t;
typedef enum logic {
FETCH_ACCESS_FAULT = 1'b0,
FETCH_PAGE_FAULT = 1'b1
} fetch_error_codes_t;
typedef struct packed{
logic ok;
fetch_error_codes_t error_code;
} fetch_metadata_t;
typedef struct packed{
id_t id;
logic [31:0] pc;
logic [31:0] instruction;
logic valid;
logic addr_valid;
fetch_metadata_t fetch_metadata;
} decode_packet_t;
typedef struct packed{
@ -96,7 +106,7 @@ package taiga_types;
logic uses_rd;
id_t id;
logic stage_valid;
logic addr_valid;
fetch_metadata_t fetch_metadata;
} issue_packet_t;
typedef struct packed{