diff options
Diffstat (limited to '')
| -rw-r--r-- | rtl/core/arm810.sv | 8 | ||||
| -rw-r--r-- | rtl/core/control/control.sv | 3 | ||||
| -rw-r--r-- | rtl/core/control/exception.sv | 6 | ||||
| -rw-r--r-- | rtl/core/control/issue.sv | 6 | ||||
| -rw-r--r-- | rtl/core/fetch/fetch.sv | 4 | ||||
| -rw-r--r-- | rtl/core/fetch/prefetch.sv | 33 | ||||
| -rw-r--r-- | rtl/core/mmu/mmu.sv | 3 | ||||
| -rw-r--r-- | rtl/core/porch/porch.sv | 8 |
8 files changed, 53 insertions, 18 deletions
diff --git a/rtl/core/arm810.sv b/rtl/core/arm810.sv index a0c1e0f..c820720 100644 --- a/rtl/core/arm810.sv +++ b/rtl/core/arm810.sv @@ -23,7 +23,7 @@ module arm810 ptr fetch_insn_pc, fetch_head, insn_addr; word fetch_insn; - logic fetch_nop, stall, flush, prefetch_flush, insn_start; + logic fetch_nop, fetch_abort, stall, flush, prefetch_flush, insn_start; //TODO assign prefetch_flush = halt; @@ -34,8 +34,10 @@ module arm810 .addr(insn_addr), .insn(fetch_insn), .fetch(insn_start), + .fault(insn_fault), .fetched(insn_ready), .insn_pc(fetch_insn_pc), + .insn_abort(fetch_abort), .fetch_data(insn_data_rd), .porch_insn_pc(insn_pc), .* @@ -51,10 +53,12 @@ module arm810 ptr insn_pc; word insn; + logic issue_abort; insn_decode dec; core_porch porch ( + .abort(issue_abort), .* ); @@ -166,7 +170,7 @@ module arm810 ptr data_addr; word data_data_rd, data_data_wr, insn_data_rd; - logic data_start, data_write, data_ready, insn_ready, data_fault; + logic data_start, data_write, data_ready, insn_ready, data_fault, insn_fault; logic[3:0] data_data_be; core_mmu mmu diff --git a/rtl/core/control/control.sv b/rtl/core/control/control.sv index 8bf4976..840cf19 100644 --- a/rtl/core/control/control.sv +++ b/rtl/core/control/control.sv @@ -9,6 +9,7 @@ module core_control input insn_decode dec, input ptr insn_pc, + input logic issue_abort, input psr_mode mode, input psr_flags flags, alu_flags, @@ -89,7 +90,7 @@ module core_control ); ptr pc /*verilator public*/, next_pc_visible; - logic issue, undefined; + logic issue, undefined, prefetch_abort; core_control_issue ctrl_issue ( diff --git a/rtl/core/control/exception.sv b/rtl/core/control/exception.sv index 2d12c0a..038cd2b 100644 --- a/rtl/core/control/exception.sv +++ b/rtl/core/control/exception.sv @@ -8,6 +8,7 @@ module core_control_exception input ctrl_cycle next_cycle, input logic high_vectors, undefined, + prefetch_abort, mem_fault, output logic exception, @@ -20,7 +21,7 @@ module core_control_exception //TODO: irq, fiq, prefetch abort, swi - assign exception = undefined || mem_fault; + assign exception = undefined || prefetch_abort || mem_fault; assign exception_vector = {{16{high_vectors}}, 11'b0, vector_offset, 2'b00}; always @(posedge clk or negedge rst_n) begin @@ -31,6 +32,9 @@ module core_control_exception end else if(mem_fault) begin vector_offset <= 3'b100; exception_mode <= `MODE_ABT; + end else if(prefetch_abort) begin + vector_offset <= 3'b011; + exception_mode <= `MODE_ABT; end else if(undefined) begin vector_offset <= 3'b001; exception_mode <= `MODE_UND; diff --git a/rtl/core/control/issue.sv b/rtl/core/control/issue.sv index ffdf250..23ecdcf 100644 --- a/rtl/core/control/issue.sv +++ b/rtl/core/control/issue.sv @@ -8,6 +8,7 @@ module core_control_issue input insn_decode dec, input ptr insn_pc, + input logic issue_abort, input ctrl_cycle next_cycle, input logic next_bubble, @@ -18,6 +19,7 @@ module core_control_issue output logic issue, undefined, + prefetch_abort, output ptr pc, pc_visible, next_pc_visible @@ -34,12 +36,14 @@ module core_control_issue pc <= 0; undefined <= 0; pc_visible <= 2; + prefetch_abort <= 0; end else if(next_cycle.issue) begin if(valid) begin undefined <= dec.ctrl.undefined; + prefetch_abort <= issue_abort; `ifdef VERILATOR - if(dec.ctrl.undefined) + if(dec.ctrl.undefined && !issue_abort) $display("[core] undefined insn: [0x%08x] %08x", insn_pc << 2, insn); `endif end diff --git a/rtl/core/fetch/fetch.sv b/rtl/core/fetch/fetch.sv index ba9d677..279d2c2 100644 --- a/rtl/core/fetch/fetch.sv +++ b/rtl/core/fetch/fetch.sv @@ -6,6 +6,7 @@ module core_fetch input logic clk, rst_n, stall, + fault, fetched, explicit_branch /*verilator public*/ /*verilator forceable*/, wr_pc, @@ -21,7 +22,8 @@ module core_fetch output word insn, output ptr insn_pc, addr, - fetch_head + fetch_head, + output logic insn_abort ); ptr target /*verilator public*/ /*verilator forceable*/, hold_addr; diff --git a/rtl/core/fetch/prefetch.sv b/rtl/core/fetch/prefetch.sv index 1b5a4c5..719ad95 100644 --- a/rtl/core/fetch/prefetch.sv +++ b/rtl/core/fetch/prefetch.sv @@ -7,6 +7,7 @@ module core_prefetch rst_n, stall, flush, + fault, fetched, input word fetch_data, input ptr head, @@ -14,34 +15,43 @@ module core_prefetch output word insn, output ptr insn_pc, output logic fetch, - nop + nop, + insn_abort ); localparam SIZE = (1 << ORDER) - 1; ptr next_pc; + logic faults[SIZE]; logic[31:0] prefetch[SIZE]; logic[ORDER - 1:0] valid; assign nop = flush ? 1 : ~|valid; assign insn = flush ? `NOP : prefetch[0]; - assign next_pc = ~stall & |valid ? insn_pc + 1 : insn_pc; assign fetch = !stall || ~&valid; + assign next_pc = ~stall & |valid ? insn_pc + 1 : insn_pc; + assign insn_abort = flush ? 0 : faults[0]; always_ff @(posedge clk or negedge rst_n) if(!rst_n) begin valid <= 0; insn_pc <= 0; + + faults[SIZE - 1] <= 0; prefetch[SIZE - 1] <= `NOP; end else begin insn_pc <= flush ? head : next_pc; - if(flush) + if(flush) begin + faults[SIZE - 1] <= 0; prefetch[SIZE - 1] <= `NOP; - else if(fetched && valid == SIZE - 1 + {{(ORDER - 1){1'b0}}, !stall}) + end else if(fetched && valid == SIZE - 1 + {{(ORDER - 1){1'b0}}, !stall}) begin + faults[SIZE - 1] <= fault; prefetch[SIZE - 1] <= fetch_data; - else if(!stall) + end else if(!stall) begin + faults[SIZE - 1] <= 0; prefetch[SIZE - 1] <= `NOP; + end if(flush) valid <= 0; @@ -55,14 +65,19 @@ module core_prefetch generate for(i = 0; i < SIZE - 1; ++i) begin: prefetch_slots always_ff @(posedge clk or negedge rst_n) - if(!rst_n) + if(!rst_n) begin + faults[i] <= 0; prefetch[i] <= `NOP; - else if(flush) + end else if(flush) begin + faults[i] <= 0; prefetch[i] <= `NOP; - else if(fetched & (~(|i | |valid) | (valid == i + {{(ORDER - 1){1'b0}}, ~stall}))) + end else if(fetched & (~(|i | |valid) | (valid == i + {{(ORDER - 1){1'b0}}, ~stall}))) begin + faults[i] <= fault; prefetch[i] <= fetch_data; - else if(~stall) + end else if(~stall) begin + faults[i] <= faults[i + 1]; prefetch[i] <= prefetch[i + 1]; + end end endgenerate diff --git a/rtl/core/mmu/mmu.sv b/rtl/core/mmu/mmu.sv index 17f1e98..d22f1cd 100644 --- a/rtl/core/mmu/mmu.sv +++ b/rtl/core/mmu/mmu.sv @@ -26,6 +26,7 @@ module core_mmu output logic bus_start, bus_write, insn_ready, + insn_fault, data_ready, data_fault, output word insn_data_rd, @@ -51,7 +52,7 @@ module core_mmu .core_start(insn_start), .core_write(0), .core_ready(insn_ready), - .core_fault(), + .core_fault(insn_fault), .core_data_wr(0), .core_data_be(0), .core_data_rd(insn_data_rd), diff --git a/rtl/core/porch/porch.sv b/rtl/core/porch/porch.sv index 4369836..99ba9ed 100644 --- a/rtl/core/porch/porch.sv +++ b/rtl/core/porch/porch.sv @@ -10,13 +10,15 @@ module core_porch input word fetch_insn, input logic fetch_nop, + fetch_abort, input ptr fetch_insn_pc, fetch_head, input insn_decode fetch_dec, output word insn, output ptr insn_pc, - output insn_decode dec + output insn_decode dec, + output logic abort ); logic execute, conditional, undefined, nop; @@ -25,7 +27,7 @@ module core_porch always_comb begin dec = hold_dec; dec.ctrl.nop = nop; - dec.ctrl.execute = !flush && dec.ctrl.execute && execute && !nop; + dec.ctrl.execute = !flush && dec.ctrl.execute && execute && !nop && !abort; dec.ctrl.undefined = !flush && (dec.ctrl.undefined || undefined); dec.ctrl.conditional = !flush && (dec.ctrl.conditional || conditional); end @@ -39,11 +41,13 @@ module core_porch if(!rst_n) begin nop <= 0; // Even though it is a NOP insn <= `NOP; + abort <= 0; insn_pc <= 0; hold_dec <= {$bits(hold_dec){1'b0}}; end else if(flush || !stall) begin nop <= flush ? 1 : fetch_nop; insn <= flush ? `NOP : fetch_insn; + abort <= flush ? 0 : fetch_abort; insn_pc <= flush ? fetch_head : fetch_insn_pc; hold_dec <= fetch_dec; end |
