From baf289277aeb63121630a6b0af6226f03a65c403 Mon Sep 17 00:00:00 2001
From: Roberto Hexsel <roberto@inf.ufpr.br>
Date: Fri, 9 Oct 2015 12:09:45 -0300
Subject: [PATCH] timing is no good; improved interrupt processing

---
 cMIPS/tests/mmu_context.s    |  18 ---
 cMIPS/tests/mtc0CAUSE2.s     |  11 +-
 cMIPS/vhdl/core.vhd          | 223 ++++++++++++++++++++---------------
 cMIPS/vhdl/exception.vhd     |  56 +++++----
 cMIPS/vhdl/packageExcp.vhd   |  40 +++----
 cMIPS/vhdl/packageMemory.vhd |   4 +-
 cMIPS/vhdl/tb_cMIPS.vhd      |  15 ++-
 7 files changed, 202 insertions(+), 165 deletions(-)

diff --git a/cMIPS/tests/mmu_context.s b/cMIPS/tests/mmu_context.s
index 90e4d09..0b6e554 100644
--- a/cMIPS/tests/mmu_context.s
+++ b/cMIPS/tests/mmu_context.s
@@ -18,24 +18,6 @@
 
 	# New entries cannot overwrite tlb[0,1] that map base of ROM + I/O
 	
-	# EntryHi cannot have an ASID different from zero, otw TLB misses
-	.set entryHi_1,  0x00012000 #  VPN2 (31..13)  0000  0000 0000 asid 
-			            #                 pfn0  zzcc cdvg
-	.set entryLo0_1, 0x0000091b #  PPN (31..9)=9  1001  0001 1011 x91b
-	.set entryLo1_1, 0x00000c1b #  x0 x0 x0 x0 x0 1100  0001 1011 xc1b
-
-	.set entryHi_2,  0x00014000 #                 pfn0  zzcc cdvg
-	.set entryLo0_2, 0x00001016 #  x0 x0 x0 x0 x1 0000  0001 0110 x1016
-	.set entryLo1_2, 0x0000141e #  x0 x0 x0 x0 x1 0100  0001 1110 x141e
-
-	.set entryHi_3,  0x00016000 #                 pfn0  zzcc cdvg
-	.set entryLo0_3, 0x0000191f #  x0 x0 x0 x0 x1 1001  0001 1111 x191f
-	.set entryLo1_3, 0x00001d3f #  x0 x0 x0 x0 x1 1101  0011 1111 x1d3f
-
-	.set entryHi_4,  0x00018000 #  VPN2=30,31     pfn0  zzcc cdvg
-	.set entryLo0_4, 0x00000012 #  x0 x0 x0 x0 x0 0000  0001 0010 x12
-	.set entryLo1_4, 0x00000412 #  x0 x0 x0 x0 x0 0100  0001 0010 x412
-
 	.set MMU_ini_tag_RAM0, x_DATA_BASE_ADDR
 	.set MMU_ini_dat_RAM0, 0x0001005         # this mapping is INVALID
 	.set MMU_ini_dat_RAM1, 0x0001047
diff --git a/cMIPS/tests/mtc0CAUSE2.s b/cMIPS/tests/mtc0CAUSE2.s
index 862dce8..c91bb51 100644
--- a/cMIPS/tests/mtc0CAUSE2.s
+++ b/cMIPS/tests/mtc0CAUSE2.s
@@ -24,6 +24,7 @@ _exit:	nop	# flush pipeline
 	nop
 	nop
 	.end _start
+
 	
 	.org x_EXCEPTION_0180,0 # exception vector_180
 	.ent _excp_180
@@ -40,23 +41,23 @@ _excp_180:
 
 	.org x_ENTRY_POINT,0	# normal code start
 main:	la $15,x_IO_BASE_ADDR
-	li $7,4                # do four rounds
+	li $7,4                	# do four rounds
 	li $5,0
 here:	sw $5, 0($15)
 
-	li   $6, 0x10000302   # kernel mode, disable interrupts
+	li   $6, 0x10000302   	# kernel mode, disable interrupts
 	mtc0 $6,cop0_STATUS
-	li   $6, 0x0000ffff   # write garbage to CAUSE, assert sw interr 0,1
+	li   $6, 0x0000ffff   	# write garbage to CAUSE, assert sw interr 0,1
 	mtc0 $6,cop0_CAUSE
 
 	addiu $5,$5,2
 	
-	li   $6, 0x10000311   # user mode, enable sw interrupts
+	li   $6, 0x10000311   	# user mode, enable sw interrupts
 	mtc0 $6,cop0_STATUS
 	nop
 	nop
 	nop
-	nop		      # wait for software interrupt
+	nop		      	# wait for software interrupt
 	
 	bne   $7,$zero, here
 	nop
diff --git a/cMIPS/vhdl/core.vhd b/cMIPS/vhdl/core.vhd
index 1650a70..133163c 100644
--- a/cMIPS/vhdl/core.vhd
+++ b/cMIPS/vhdl/core.vhd
@@ -85,7 +85,7 @@ architecture rtl of core is
          EX_trapped:      out boolean);
   end component reg_excp_RF_EX;
 
-  component reg_excp_EX_MM is
+  component reg_excp_EX_MM is -- jjjjj
     port(clk, rst, ld:  in  std_logic;
          EX_cop0_reg:   in  reg5;
          MM_cop0_reg:   out reg5;
@@ -95,21 +95,25 @@ architecture rtl of core is
          MM_PC:         out std_logic_vector;
          EX_v_addr:     in  std_logic_vector;
          MM_v_addr:     out std_logic_vector;
-         nullify:       in  boolean;
+         EX_nullify:    in  boolean;
          MM_nullify:    out boolean;
-         addrError:     in  boolean;
+         EX_addrError:  in  boolean;
          MM_addrError:  out boolean;
-         addrErr_stage_mm:    in  boolean;
+         EX_addrErr_stage_mm: in  boolean;
          MM_addrErr_stage_mm: out boolean;
-         EX_is_delayslot: in  std_logic;
-         MM_is_delayslot: out std_logic;
-         EX_trapped:    in  boolean;
-         MM_trapped:    out boolean;
-         EX_ll_sc_abort: in boolean;
-         MM_ll_sc_abort: out boolean;
-         TLB_exception:    in  boolean;
+         EX_mem_excp_type: in  exception_type;
+         MM_mem_excp_type: out exception_type;
+         EX_is_delayslot:  in  std_logic;
+         MM_is_delayslot:  out std_logic;
+         EX_trapped:       in  boolean;
+         MM_trapped:       out boolean;
+         EX_ll_sc_abort:   in  boolean;
+         MM_ll_sc_abort:   out boolean;
+         EX_tlb_exception: in  boolean;
          MM_tlb_exception: out boolean;
-         tlb_stage_MM:     in  boolean;
+         EX_tlb_excp_type: in  exception_type;
+         MM_tlb_excp_type: out exception_type;
+         EX_tlb_stage_MM:  in  boolean;
          MM_tlb_stage_MM:  out boolean;
          EX_nmi:           in  std_logic;
          MM_nmi:           out std_logic;       
@@ -121,8 +125,12 @@ architecture rtl of core is
          MM_is_SC:         out boolean;
          EX_is_MFC0:       in  boolean;
          MM_is_MFC0:       out boolean;
-         EX_is_exception:  in  exception_type;
-         MM_is_exception:  out exception_type);
+         EX_ext_event:     in  boolean;
+         MM_ext_event:     out boolean;
+         EX_ext_event_type: in  exception_type;
+         MM_ext_event_type: out exception_type;
+         EX_int_event_type: in  exception_type;
+         MM_int_event_type: out exception_type);
   end component reg_excp_EX_MM;
 
   component reg_excp_MM_WB is
@@ -143,8 +151,9 @@ architecture rtl of core is
   signal nullify_fetch, nullify, MM_nullify : boolean;
   signal addrError, MM_addrError, abort_ref, MM_ll_sc_abort : boolean;
   signal PC_abort, RF_PC_abort, EX_PC_abort : boolean;
-  signal IF_excp_type,RF_excp_type: exception_type;
-  signal mem_excp_type, TLB_excp_type : exception_type;
+  signal IF_excp_type,RF_excp_type : exception_type;
+  signal mem_excp_type, MM_mem_excp_type : exception_type;
+  signal tlb_excp_type, MM_tlb_excp_type : exception_type;
   signal trap_instr,EX_trap_instr: instr_type;
   signal RF_PC,EX_PC,MM_PC,WB_PC, LLaddr: reg32;
   signal ll_sc_bit, MM_LLbit,WB_LLbit: std_logic;
@@ -164,7 +173,8 @@ architecture rtl of core is
   signal STATUSinp,STATUS, CAUSEinp,CAUSE, EPCinp,EPC : reg32;
   signal COUNT, COMPARE : reg32;
   signal count_eq_compare,count_update,count_enable : std_logic;
-  signal exception,EX_exception, is_exception, MM_is_exception : exception_type;
+  signal exception,EX_exception, MM_exception : exception_type;
+  signal is_exception, MM_is_exception : exception_type;
   signal ExcCode : reg5 := cop0code_NULL;
   signal exception_dec,TLB_excp_num,trap_dec: integer; -- debugging
   signal RF_is_delayslot,EX_is_delayslot,MM_is_delayslot,WB_is_delayslot,is_delayslot : std_logic;
@@ -175,8 +185,10 @@ architecture rtl of core is
   signal BadVAddr_update : std_logic;
   signal is_SC, MM_is_SC, is_MFC0, MM_is_MFC0 : boolean;
 
-  signal busError : boolean;
+  signal is_busError, is_nmi, is_interr, is_ovfl, ext_event, MM_ext_event : boolean;
   signal busError_type : exception_type;
+  signal ext_event_type, MM_ext_event_type  : exception_type;
+  signal int_event_type, MM_int_event_type  : exception_type;
   
   -- MMU signals --
   signal INDEX, index_inp, RANDOM, WIRED, wired_inp : reg32;
@@ -338,7 +350,7 @@ architecture rtl of core is
   signal WB_mem_t : reg2;
 
   signal alu_inp_A,alu_fwd_B,alu_inp_B : reg32;
-  signal alu_move_ok, MM_alu_move_ok, ovfl,MM_ovfl : std_logic;
+  signal alu_move_ok, MM_alu_move_ok, ovfl : std_logic;
   
   signal selB,EX_selB:  std_logic;
   signal oper,EX_oper: t_alu_fun;
@@ -1093,7 +1105,7 @@ begin
   
   RF_DECODE_FUNCT: process (opcode,IF_RF_ld,ctrl_word,funct_word,rimm_word,
                             func,shamt, a_rs,a_rd, STATUS,
-                            RF_excp_type,RF_instruction) -- mem_excp_type)
+                            RF_excp_type,RF_instruction, mem_excp_type)
     variable i_wreg : std_logic;
     variable i_csel : reg2;
     variable i_oper : t_alu_fun := opNOP;
@@ -1776,7 +1788,8 @@ begin
               trap_taken,EX_trapped);
   
 
-  EX_nmi     <= nmi;
+  is_nmi     <= ( (nmi = '1') and (STATUS(STATUS_ERL) = '0') );
+
   int_req(7) <= (irq(5) or count_eq_compare);
   int_req(6) <= irq(4);
   int_req(5) <= irq(3);
@@ -1789,25 +1802,36 @@ begin
   interrupt <= int_req(7) or int_req(6) or int_req(5) or int_req(4) or
                int_req(3) or int_req(2) or int_req(1) or int_req(0);
 
+  is_interr <= ( (interrupt = '1') and
+                 (STATUS(STATUS_EXL) = '0') and
+                 (STATUS(STATUS_ERL) = '0') and
+                 (STATUS(STATUS_IE)  = '1') );
+  
   -- check for overflow in EX, send it to MM for later processing
-  EX_ovfl <= (EX_can_trap = b"10" and ovfl = '1');
+  is_ovfl <= (EX_can_trap = b"10" and ovfl = '1');
 
   is_SC   <= (EX_exception = exSC);       -- is StoreConditional?  (alu_fwd)
   is_mfc0 <= (EX_exception = exMFC0);     -- is MFC0?  (alu_fwd)
 
-  -- priority is given to events later in the pipeline
+  
+  -- priority is always given to events later in the pipeline
   busError_type <= exDBE when d_busErr = '0' else
                    exIBE when i_busErr = '0' else
                    exNOP;
-  busError      <= (i_busErr = '0') or (d_busErr = '0');
+  is_busError   <= (i_busErr = '0') or (d_busErr = '0');
 
-  is_exception <= busError_type     when busError      else
-                  TLB_excp_type     when tlb_exception else
-                  mem_excp_type     when addrError     else
-                  exTrap            when EX_trapped    else
-                  exOvfl            when EX_ovfl       else
-                  IFaddressError    when EX_PC_abort   else
-                  EX_exception;
+  ext_event      <= is_nmi or is_interr or is_busError;
+  ext_event_type <= busError_type when is_busError else
+                    exNMI         when is_nmi      else
+                    exInterr      when is_interr   else
+                    exNOP;  
+
+  -- must always check for these
+  int_event_type <= mem_excp_type   when addrError     else
+                    exTrap          when EX_trapped    else
+                    exOvfl          when is_ovfl       else
+                    IFaddressError  when EX_PC_abort   else
+                    EX_exception;
   
   -- ----------------------------------------------------------------------
   PIPESTAGE_EXCP_EX_MM: reg_excp_EX_MM
@@ -1816,18 +1840,37 @@ begin
               EX_PC,MM_PC, v_addr,MM_v_addr, nullify,MM_nullify,
               addrError,MM_addrError,
               addrErr_stage_mm,MM_addrErr_stage_mm,
+              mem_excp_type, MM_mem_excp_type,
               EX_is_delayslot,MM_is_delayslot,
               EX_trapped,MM_trapped,
               SL2BOOL(LL_SC_abort), MM_ll_sc_abort,
-              tlb_exception,MM_tlb_exception, tlb_stage_mm,MM_tlb_stage_mm,
+              tlb_exception,MM_tlb_exception,
+              tlb_excp_type,MM_tlb_excp_type, 
+              tlb_stage_mm,MM_tlb_stage_mm,
               EX_nmi,MM_nmi, interrupt,MM_interrupt, int_req,MM_int_req,
               is_SC, MM_is_SC, is_MFC0, MM_is_MFC0,
-              is_exception,MM_is_exception);
+              ext_event, MM_ext_event,
+              ext_event_type, MM_ext_event_type,
+              int_event_type, MM_int_event_type);
+
+  -- kkkkk
+--   is_exception <= MM_ext_event_type  when MM_ext_event     else
+--                   MM_TLB_excp_type   when MM_tlb_exception else
+--                   MM_mem_excp_type   when MM_addrError     else
+--                   exTrap             when MM_trapped       else
+--                   exOvfl             when MM_ovfl          else
+--                   IFaddressError     when MM_PC_abort      else
+--                   MM_exception;
 
+  is_exception <= MM_ext_event_type  when MM_ext_event     else
+                  MM_TLB_excp_type   when MM_tlb_exception else
+                  MM_int_event_type;
+
+  
 
   -- STATUS -- pg 79 -- cop0_12 --------------------
   COP0_DECODE_EXCEPTION_AND_UPDATE_STATUS:
-  process (MM_a_rt, MM_is_exception, cop0_inp,
+  process (MM_a_rt, is_exception, cop0_inp,
            MM_cop0_reg, MM_cop0_sel, MM_nmi, MM_interrupt,MM_int_req,
            RF_is_delayslot, EX_is_delayslot, MM_is_delayslot, WB_is_delayslot,
            rom_stall,ram_stall, MM_is_mfc0,
@@ -1863,7 +1906,7 @@ begin
     newSTATUS(STATUS_CU1) := '0';  -- COP-1 absent (always)
     newSTATUS(STATUS_CU0) := '1';  -- COP-0 present=1 (always)
     
-    case MM_is_exception is
+    case is_exception is
 
       when exMTC0 =>            -- move to COP-0
         i_update_r := MM_cop0_reg;
@@ -1938,7 +1981,7 @@ begin
         
       when exSYSCALL | exBREAK =>       -- SYSCALL, BREAK
         i_stall    := '0';
-        if MM_is_exception = exSYSCALL then
+        if is_exception = exSYSCALL then
           ExcCode <= cop0code_Sys;
         else
           ExcCode <= cop0code_Bp;
@@ -2033,7 +2076,7 @@ begin
         i_update_r      := cop0reg_STATUS;
         i_epc_update    := '0';
         i_nullify       := TRUE;        -- nullify instructions in IF,RF,EX
-        if MM_is_exception = MMaddressErrorST then
+        if is_exception = MMaddressErrorST then
           ExcCode <= cop0code_AdES;
         else
           ExcCode <= cop0code_AdEL;
@@ -2073,7 +2116,7 @@ begin
         
 
       when exTLBrefillRD | exTLBrefillWR =>
-        case MM_is_exception is
+        case is_exception is
           when exTLBrefillRD =>
             ExcCode <= cop0code_TLBL;
           when exTLBrefillWR =>
@@ -2113,7 +2156,7 @@ begin
 
       when exTLBdblFaultRD | exTLBdblFaultWR |
            exTLBinvalRD    | exTLBinvalWR    | exTLBmod =>
-        case MM_is_exception is
+        case is_exception is
           when exTLBinvalRD | exTLBdblFaultRD =>
             ExcCode <= cop0code_TLBL;
           when exTLBinvalWR | exTLBdblFaultWR =>
@@ -2138,7 +2181,7 @@ begin
 
 
       when exIBE | exDBE =>             -- BUS ERROR
-        if MM_is_exception = exIBE then
+        if is_exception = exIBE then
           ExcCode <= cop0code_IBE;
         else
           ExcCode <= cop0code_DBE;
@@ -2150,34 +2193,8 @@ begin
         i_nullify  := TRUE;             -- nullify instructions in IF,RF,EX
         
         
-      when others =>                    -- interrupt pending?
-
-        if ( (MM_nmi = '1') and (STATUS(STATUS_ERL) = '0') ) then
-          -- non maskable interrupt
-          -- assert false report "NMinterrupt PC="&SLV32HEX(PC) severity note;
-          exception_taken <= '1';
-          newSTATUS(STATUS_BEV) := '1'; -- locationVector at bootstrap
-          newSTATUS(STATUS_TS)  := '0'; -- not TLBmatchesSeveral
-          newSTATUS(STATUS_SR)  := '0'; -- not softReset
-          newSTATUS(STATUS_NMI) := '1'; -- non maskable interrupt
-          newSTATUS(STATUS_ERL) := '1'; -- at error level
-          i_update   := '1';
-          i_update_r := cop0reg_STATUS;
-          i_stall    := '0';
-          i_epc_update := '0';
-          i_nullify    := TRUE;         -- nullify instructions in IF,RF,EX
-          if MM_is_delayslot = '1' then -- instr is in delay slot
-            i_epc_source := EPC_src_MM; -- re-execute branch/jump
-            is_delayslot <= MM_is_delayslot;
-          else
-            i_epc_source := EPC_src_EX;
-            is_delayslot <= EX_is_delayslot;
-          end if;
-        
-        elsif ( (STATUS(STATUS_EXL) = '0') and (STATUS(STATUS_ERL) = '0') and
-                (STATUS(STATUS_IE) = '1')  and (MM_interrupt = '1')  and
-                (rom_stall = '0' and ram_stall = '0')) then
-          -- normal interrupt
+      when exInterr =>                  -- normal interrupt
+        if (rom_stall = '0') and (ram_stall = '0') then
           -- assert false report "interrupt PC="&SLV32HEX(PC) severity note;
           interrupt_taken <= '1';       -- debugging only     
           newSTATUS(STATUS_UM)  := '0'; -- enter kernel mode          
@@ -2196,8 +2213,31 @@ begin
             i_epc_source := EPC_src_EX;
             is_delayslot <= EX_is_delayslot;
           end if;
+        end if;
 
-        end if; -- NMI or else interrupt 
+        
+      when exNMI =>                   -- non maskable interrupt
+        -- assert false report "NMinterrupt PC="&SLV32HEX(PC) severity note;
+        exception_taken <= '1';
+        newSTATUS(STATUS_BEV) := '1'; -- locationVector at bootstrap
+        newSTATUS(STATUS_TS)  := '0'; -- not TLBmatchesSeveral
+        newSTATUS(STATUS_SR)  := '0'; -- not softReset
+        newSTATUS(STATUS_NMI) := '1'; -- non maskable interrupt
+        newSTATUS(STATUS_ERL) := '1'; -- at error level
+        i_update   := '1';
+        i_update_r := cop0reg_STATUS;
+        i_stall    := '0';
+        i_epc_update := '0';
+        i_nullify    := TRUE;         -- nullify instructions in IF,RF,EX
+        if MM_is_delayslot = '1' then -- instr is in delay slot
+          i_epc_source := EPC_src_MM; -- re-execute branch/jump
+          is_delayslot <= MM_is_delayslot;
+        else
+          i_epc_source := EPC_src_EX;
+          is_delayslot <= EX_is_delayslot;
+        end if;
+        
+      when others => null;
 
     end case;
 
@@ -2206,7 +2246,7 @@ begin
     update          <= i_update;
     update_reg      <= i_update_r;
 
-    if MM_is_exception = exMTC0 and MM_cop0_reg = cop0reg_EPC then
+    if is_exception = exMTC0 and MM_cop0_reg = cop0reg_EPC then
       epc_update   <= i_epc_update;
     else
       epc_update   <= i_epc_update OR STATUS(STATUS_EXL);
@@ -2220,12 +2260,12 @@ begin
 
 
   -- Select input to PC on an exception --------------------
-  COP0_SEL_EPC: process (MM_is_exception, MM_nmi, MM_interrupt, STATUS, CAUSE,
+  COP0_SEL_EPC: process (is_exception, MM_nmi, MM_interrupt, STATUS, CAUSE,
                          MM_trapped, rom_stall, ram_stall)
     variable i_excp_PCsel : reg3;
   begin
 
-    case MM_is_exception is
+    case is_exception is
 
       when exERET =>            -- exception return
         i_excp_PCsel := PCsel_EXC_EPC;    -- PC <= EPC
@@ -2247,24 +2287,23 @@ begin
       when exTLBrefillIF | exTLBrefillRD | exTLBrefillWR =>
         i_excp_PCsel := PCsel_EXC_0000; -- PC <= exception_0000
 
-      when others =>                    -- interrupt pending?
+      when exNMI =>                     -- non maskable interrupt
+        i_excp_PCsel := PCsel_EXC_BFC0; -- PC <= 0xBFC0.0000
 
-        if ( (MM_nmi = '1') and (STATUS(STATUS_ERL) = '0') ) then
-          -- non maskable interrupt
-          i_excp_PCsel := PCsel_EXC_BFC0; -- PC <= 0xBFC0.0000
-        
-        elsif ( (STATUS(STATUS_EXL) = '0') and (STATUS(STATUS_ERL) = '0') and
-                (STATUS(STATUS_IE) = '1')  and (MM_interrupt = '1')  and
-                (rom_stall = '0' and ram_stall = '0')) then
-          -- normal interrupt
+      when exInterr =>                  -- normal interrupt
+        if (rom_stall = '0' and ram_stall = '0') then
           if CAUSE(CAUSE_IV) = '1' then
             i_excp_PCsel := PCsel_EXC_0200; -- PC <= exception_0200
           else
             i_excp_PCsel := PCsel_EXC_0180; -- PC <= exception_0180
           end if;
-        else
-          i_excp_PCsel := PCsel_EXC_none;   -- should never get here
-        end if; -- NMI or interrupt 
+        end if;
+
+      when exNOP =>
+        i_excp_PCsel := PCsel_EXC_none; -- no exception, do nothing to PC
+
+      when others =>                    -- should never get here
+        i_excp_PCsel := PCsel_EXC_none;
 
     end case;
 
@@ -2341,7 +2380,7 @@ begin
     end if;
   end process COP0_COMPUTE_CAUSE;
 
-  COP0_CAUSE_HOLD: process(rst,clk, ExcCode,MM_is_exception,
+  COP0_CAUSE_HOLD: process(rst,clk, ExcCode,is_exception,
                            MM_cop0_reg,not_stalled)
     variable state: reg32;
   begin
@@ -2349,7 +2388,7 @@ begin
       cause_update <= '0';
     elsif ( rising_edge(clk) and (ExcCode /= cop0code_NULL) ) then
       cause_update <= '1';              -- syscall/trap/interrupt/exception
-    elsif ( rising_edge(clk) and (MM_is_exception = exMFC0) and
+    elsif ( rising_edge(clk) and (is_exception = exMFC0) and
             MM_cop0_reg = cop0reg_CAUSE and (not_stalled = '1') ) then
         cause_update <= '0';            -- CAUSE is being read
     end if;
@@ -2402,11 +2441,11 @@ begin
   
   -- BadVAddr -- pg 74 ---------------------------
 
-  U_BadVAddr_UPDATE: process(MM_is_exception, RF_is_delayslot, RF_PC, EX_PC,
+  U_BadVAddr_UPDATE: process(is_exception, RF_is_delayslot, RF_PC, EX_PC,
                              MM_v_addr)
     variable i_update : std_logic;
   begin
-    case MM_is_exception is    
+    case is_exception is    
       when IFaddressError | exTLBrefillIF | exTLBdblFaultIF | exTLBinvalIF =>
         if RF_is_delayslot = '1' then       -- instr is in delay slot
           BadVAddr_inp <= EX_PC;
@@ -2452,7 +2491,7 @@ begin
     if rst = '0' then
       ll_sc_bit <= '0';
     elsif rising_edge(clk) then
-      case MM_is_exception is
+      case is_exception is
         when exERET =>
           ll_sc_bit <= '0';            -- break SC -> LL
         when exLL =>
@@ -2700,7 +2739,7 @@ begin
   -- TLB_tag: 31..13 = VPN, 12..9 = 0, 8 = G, 7..0 = ASID
   -- TLB_dat: 29..6 = PPN, 5..3 = C, 2 = D, 1 = V, 0 = G
   
-  MMU_CONTROL: process(MM_is_exception, INDEX, RANDOM)
+  MMU_CONTROL: process(is_exception, INDEX, RANDOM)
     variable i_tlb_adr : integer range MMU_CAPACITY-1 downto 0;
   begin
 
@@ -2722,7 +2761,7 @@ begin
     tlb_dat6_updt <= '1';
     tlb_dat7_updt <= '1';
     
-    case MM_is_exception is
+    case is_exception is
       when exTLBP =>
         
         tlb_probe <= '1';
@@ -2739,7 +2778,7 @@ begin
 
         tlb_probe <= '0';
         tlb_read  <= '0';
-        if MM_is_exception = exTLBWI then
+        if is_exception = exTLBWI then
           i_tlb_adr := to_integer(unsigned(INDEX(MMU_CAPACITY-1 downto 0)));
         else
           i_tlb_adr := to_integer(unsigned(RANDOM));
diff --git a/cMIPS/vhdl/exception.vhd b/cMIPS/vhdl/exception.vhd
index 1931760..ca089e6 100644
--- a/cMIPS/vhdl/exception.vhd
+++ b/cMIPS/vhdl/exception.vhd
@@ -126,21 +126,25 @@ entity reg_excp_EX_MM is
        MM_PC:         out reg32;
        EX_v_addr:     in  reg32;
        MM_v_addr:     out reg32;
-       nullify:       in  boolean;
+       EX_nullify:    in  boolean;
        MM_nullify:    out boolean;
-       addrError:     in  boolean;
+       EX_addrError:  in  boolean;
        MM_addrError:  out boolean;
-       addrErr_stage_mm:    in  boolean;
+       EX_addrErr_stage_mm: in  boolean;
        MM_addrErr_stage_mm: out boolean;
-       EX_is_delayslot: in  std_logic;
-       MM_is_delayslot: out std_logic;
-       EX_trapped:     in  boolean;
-       MM_trapped:     out boolean;
-       EX_ll_sc_abort: in boolean;
-       MM_ll_sc_abort: out boolean;
-       tlb_exception:    in  boolean;
+       EX_mem_excp_type: in  exception_type;
+       MM_mem_excp_type: out exception_type;
+       EX_is_delayslot:  in  std_logic;
+       MM_is_delayslot:  out std_logic;
+       EX_trapped:       in  boolean;
+       MM_trapped:       out boolean;
+       EX_ll_sc_abort:   in boolean;
+       MM_ll_sc_abort:   out boolean;
+       EX_tlb_exception: in  boolean;
        MM_tlb_exception: out boolean;
-       tlb_stage_mm:     in  boolean;
+       EX_tlb_excp_type: in  exception_type;
+       MM_tlb_excp_type: out exception_type;
+       EX_tlb_stage_mm:  in  boolean;
        MM_tlb_stage_mm:  out boolean;
        EX_nmi:           in  std_logic;
        MM_nmi:           out std_logic;
@@ -152,9 +156,12 @@ entity reg_excp_EX_MM is
        MM_is_SC:         out boolean;
        EX_is_MFC0:       in  boolean;
        MM_is_MFC0:       out boolean;
-       EX_is_exception:    in  exception_type;
-       MM_is_exception:    out exception_type
-       );
+       EX_ext_event:     in  boolean;
+       MM_ext_event:     out boolean;
+       EX_ext_event_type: in  exception_type;
+       MM_ext_event_type: out exception_type;
+       EX_int_event_type: in  exception_type;
+       MM_int_event_type: out exception_type);
 end reg_excp_EX_MM;
 
 architecture funcional of reg_excp_EX_MM is
@@ -165,28 +172,35 @@ begin
       MM_trapped        <= FALSE;
       MM_nullify        <= FALSE;
       MM_addrError      <= FALSE;
+      MM_trapped        <= FALSE;
       MM_tlb_exception  <= FALSE;
-      MM_is_exception      <= exNOP;
+      MM_ext_event      <= FALSE;
+      MM_ext_event_type <= exNOP;
+      MM_int_event_type <= exNOP;
     elsif rising_edge(clk) then
       if ld = '0' then
         MM_cop0_reg      <= EX_cop0_reg    ;
         MM_cop0_sel      <= EX_cop0_sel    ;
         MM_PC            <= EX_PC          ;
         MM_v_addr        <= EX_v_addr      ;
-        MM_nullify       <= nullify        ;
-        MM_addrError     <= addrError      ;
-        MM_addrErr_stage_mm <= addrErr_stage_mm;
+        MM_nullify       <= EX_nullify     ;
+        MM_addrError     <= EX_addrError   ;
+        MM_addrErr_stage_mm <= EX_addrErr_stage_mm;
+        MM_mem_excp_type <= EX_mem_excp_type;
         MM_is_delayslot  <= EX_is_delayslot;
         MM_trapped       <= EX_trapped     ;
         MM_ll_sc_abort   <= EX_ll_sc_abort ;
-        MM_tlb_exception <= TLB_exception  ;
-        MM_tlb_stage_MM  <= tlb_stage_MM   ;
+        MM_tlb_exception <= EX_tlb_exception;
+        MM_tlb_excp_type <= EX_tlb_excp_type;
+        MM_tlb_stage_MM  <= EX_tlb_stage_MM;
         MM_nmi           <= EX_nmi         ;
         MM_interrupt     <= EX_interrupt   ;
         MM_int_req       <= EX_int_req     ;
         MM_is_SC         <= EX_is_SC       ;
         MM_is_MFC0       <= EX_is_MFC0     ;
-        MM_is_exception  <= EX_is_exception;
+        MM_ext_event     <= EX_ext_event;
+        MM_ext_event_type <= EX_ext_event_type;
+        MM_int_event_type <= EX_int_event_type;
       end if;
     end if;
   end process;
diff --git a/cMIPS/vhdl/packageExcp.vhd b/cMIPS/vhdl/packageExcp.vhd
index 0b6e556..f1781d3 100644
--- a/cMIPS/vhdl/packageExcp.vhd
+++ b/cMIPS/vhdl/packageExcp.vhd
@@ -38,15 +38,31 @@ package p_EXCEPTION is
                           exTLBP, exTLBR, exTLBWI, exTLBWR,  -- 31
                           exDERET,  -- 32
                           exIBE, exDBE,  -- 34
+                          exNMI, exInterr,  -- 36
                           invalid_exception);
 
   attribute enum_encoding of exception_type : type is
-    "000000 000001 000010 000011 000100 000101 000110 000111 001000 001001 001010 001011 001100 001101 001110 001111 010000 010001 010010 010011 010100 010101 010110 010111 011000 011001 011010 011011 011100 011101 011110 011111 100000 100001";
+    "000000 000001 000010 000011 000100 000101 000110 000111    001000 001001 001010 001011 001100 001101 001110 001111    010000 010001 010010 010011 010100 010101 010110 010111    011000 011001 011010 011011 011100 011101 011110 011111    100000 100001 100010 100011 100100 100101";  --   100110";
 
---   100010";
+  
+  -- Table 8-25 Cause Register ExcCode Field, pg 95
+  constant cop0code_Int  : reg5 := b"00000";  --  0, interrupt=00 (CAUSE lsB)
+  constant cop0code_Mod  : reg5 := b"00001";  --  1, TLBmodified=x04
+  constant cop0code_TLBL : reg5 := b"00010";  --  2, TLBload if/ld=x08
+  constant cop0code_TLBS : reg5 := b"00011";  --  3, TLBstore if/ld=x0c
+  constant cop0code_AdEL : reg5 := b"00100";  --  4, AddrError if/ld=x10
+  constant cop0code_AdES : reg5 := b"00101";  --  5, AddrError store=x14
+  constant cop0code_IBE  : reg5 := b"00110";  --  6, BusErrorExcp if=x18
+  constant cop0code_DBE  : reg5 := b"00111";  --  7, BusErrorExcp ld/st=x1c
+  constant cop0code_Sys  : reg5 := b"01000";  --  8, syscall=x20
+  constant cop0code_Bp   : reg5 := b"01001";  --  9, breakpoint=x24
+  constant cop0code_RI   : reg5 := b"01010";  -- 10, reserved instruction=x28
+  constant cop0code_CpU  : reg5 := b"01011";  -- 11, CopUnusable excp=x2c
+  constant cop0code_Ov   : reg5 := b"01100";  -- 12, arithmetic overflow=x30
+  constant cop0code_Tr   : reg5 := b"01101";  -- 13, trap=x34
+  constant cop0code_NULL : reg5 := b"11111";  -- 1f, (no exception)=x3c
 
 
-  
   -- Table 8-1 Coprocessor 0 Registers, pg 55
   constant cop0reg_Index    : reg5 := b"00000";  -- 0
   constant cop0reg_Random   : reg5 := b"00001";  -- 1
@@ -66,25 +82,7 @@ package p_EXCEPTION is
   constant cop0reg_CONFIG   : reg5 := b"10000";  -- 16
   constant cop0reg_LLAddr   : reg5 := b"10001";  -- 17
   constant cop0reg_ErrorPC  : reg5 := b"11110";  -- 30
-
   
-  -- Table 8-25 Cause Register ExcCode Field, pg 95
-  constant cop0code_Int  : reg5 := b"00000";  --  0, interrupt=00 (CAUSE lsB)
-  constant cop0code_Mod  : reg5 := b"00001";  --  1, TLBmodified=x04
-  constant cop0code_TLBL : reg5 := b"00010";  --  2, TLBload if/ld=x08
-  constant cop0code_TLBS : reg5 := b"00011";  --  3, TLBstore if/ld=x0c
-  constant cop0code_AdEL : reg5 := b"00100";  --  4, AddrError if/ld=x10
-  constant cop0code_AdES : reg5 := b"00101";  --  5, AddrError store=x14
-  constant cop0code_IBE  : reg5 := b"00110";  --  6, BusErrorExcp if=x18
-  constant cop0code_DBE  : reg5 := b"00111";  --  7, BusErrorExcp ld/st=x1c
-  constant cop0code_Sys  : reg5 := b"01000";  --  8, syscall=x20
-  constant cop0code_Bp   : reg5 := b"01001";  --  9, breakpoint=x24
-  constant cop0code_RI   : reg5 := b"01010";  -- 10, reserved instruction=x28
-  constant cop0code_CpU  : reg5 := b"01011";  -- 11, CopUnusable excp=x2c
-  constant cop0code_Ov   : reg5 := b"01100";  -- 12, arithmetic overflow=x30
-  constant cop0code_Tr   : reg5 := b"01101";  -- 13, trap=x34
-  constant cop0code_NULL : reg5 := b"11111";  -- 1f, (no exception)=x3c
-
 
   -- at exception level, kernel mode, cop0, all else disabled
   constant RESET_STATUS: std_logic_vector(31 downto 0) := x"10000002";
diff --git a/cMIPS/vhdl/packageMemory.vhd b/cMIPS/vhdl/packageMemory.vhd
index 3e0e799..2458190 100644
--- a/cMIPS/vhdl/packageMemory.vhd
+++ b/cMIPS/vhdl/packageMemory.vhd
@@ -41,8 +41,8 @@ package p_MEMORY is
   -- begin DO NOT change these names as several scripts depend on them --
   --  you may change the values, not names neither formatting          --
   constant x_INST_BASE_ADDR : reg32   := x"00000000";
-  constant x_INST_MEM_SZ    : reg32   := x"00004000";
-  constant x_DATA_BASE_ADDR : reg32   := x"00020000";
+  constant x_INST_MEM_SZ    : reg32   := x"00010000";
+  constant x_DATA_BASE_ADDR : reg32   := x"00010000";
   constant x_DATA_MEM_SZ    : reg32   := x"00008000";
   constant x_IO_BASE_ADDR   : reg32   := x"0F000000";
   constant x_IO_MEM_SZ      : reg32   := x"00002000";
diff --git a/cMIPS/vhdl/tb_cMIPS.vhd b/cMIPS/vhdl/tb_cMIPS.vhd
index 2ad57d8..2643bc6 100644
--- a/cMIPS/vhdl/tb_cMIPS.vhd
+++ b/cMIPS/vhdl/tb_cMIPS.vhd
@@ -509,7 +509,7 @@ begin  -- TB
   cpu_d_wait <= data_wait and io_wait;
   io_wait    <= io_lcd_wait and io_fpu_wait;
 
-  not_waiting <= (inst_wait and data_wait); --  and io_wait);
+  not_waiting <= (inst_wait and data_wait and io_wait);
 
   -- irq <= b"000000"; -- NO interrupt requests
   irq <= uart_irq & counter_irq & b"0000"; -- uart+counter interrupts
@@ -672,15 +672,18 @@ architecture behavioral of inst_addr_decode is
   constant HI_ADDR : integer := HI_SEL_BITS;
   constant LO_ADDR : integer := log2_ceil(INST_BASE_ADDR + INST_MEM_SZ);
   constant PREFIX : std_logic_vector(HI_ADDR downto LO_ADDR) := (others=>'0');
+
+  signal in_range : boolean;
 begin
 
-  aVal <= '0' when ( cpu_i_aVal = '0' and rst = '1'
-                     and (addr(HI_ADDR downto LO_ADDR) = PREFIX) )
-          else '1';
+  in_range <= (addr(HI_ADDR downto LO_ADDR) = PREFIX); 
+
+  aVal <= '0' when ( cpu_i_aVal = '0' and rst = '1' and in_range ) else
+          '1';
 
   i_busError <= '0' when ( cpu_i_aVal = '0' and rst = '1'
-                           and (addr(HI_ADDR downto LO_ADDR) /= PREFIX) )
-                else '1';
+                           and not(in_range) ) else
+                '1';
   
 end architecture behavioral;
 --++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- 
GitLab