From b80a0478528aa74cb303e9066c2c5805adb79fb2 Mon Sep 17 00:00:00 2001
From: Roberto Hexsel <roberto@inf.ufpr.br>
Date: Fri, 8 Apr 2016 18:17:38 -0300
Subject: [PATCH] forward progress holds with simultaneous interrupts

---
 cMIPS/tests/doTests.sh                |   2 +-
 cMIPS/tests/interrJR_dlySlot.expected |   6 +-
 cMIPS/tests/interrJR_dlySlot.s        |  39 +++--
 cMIPS/tests/interr_x2.expected        |  23 +++
 cMIPS/tests/interr_x2.s               | 214 ++++++++++++++++++++++++++
 cMIPS/tests/uart_irx.c                |  17 +-
 cMIPS/tests/uarttx.c                  |   4 +-
 cMIPS/v_rx.sav                        |  78 ++++++----
 cMIPS/vhdl/core.vhd                   |  37 +++--
 cMIPS/vhdl/sdram.vhd                  |   2 +-
 cMIPS/vhdl/tb_cMIPS.vhd               |  80 +++-------
 11 files changed, 372 insertions(+), 130 deletions(-)
 create mode 100644 cMIPS/tests/interr_x2.expected
 create mode 100644 cMIPS/tests/interr_x2.s

diff --git a/cMIPS/tests/doTests.sh b/cMIPS/tests/doTests.sh
index 36886b9..e0a8fc7 100755
--- a/cMIPS/tests/doTests.sh
+++ b/cMIPS/tests/doTests.sh
@@ -65,7 +65,7 @@ touch input.data serial.inp
 
 a_FWD="fwdAddAddAddSw fwd_SW lwFWDsw lwFWDsw2 slt32 slt_u_32 slt_s_32 reg0"
 a_CAC="dCacheTst lhUshUCache lbUsbUCache lbsbCache dCacheTstH dCacheTstB"
-a_BEQ="lw-bne bXtz sltbeq beq_dlySlot jr_dlySlot interrJR_dlySlot"
+a_BEQ="lw-bne bXtz sltbeq beq_dlySlot jr_dlySlot interr_x2 interrJR_dlySlot"
 a_FUN="jaljr jr_2 jal_fun_jr jalr_jr jallwjr bltzal_fun_jr"
 a_OTH="mult div mul sll slr movz wsbh_seb extract insert"
 a_BHW="lbsb lhsh lwsw lwswIncr swlw lwl_lwr"
diff --git a/cMIPS/tests/interrJR_dlySlot.expected b/cMIPS/tests/interrJR_dlySlot.expected
index b43db36..2672b25 100644
--- a/cMIPS/tests/interrJR_dlySlot.expected
+++ b/cMIPS/tests/interrJR_dlySlot.expected
@@ -1,5 +1,5 @@
-00000013
+00000012
 c0808000
-0000003f
-00000046
+0000003c
+00000042
 c0808000
diff --git a/cMIPS/tests/interrJR_dlySlot.s b/cMIPS/tests/interrJR_dlySlot.s
index fdaebaa..ab152fa 100644
--- a/cMIPS/tests/interrJR_dlySlot.s
+++ b/cMIPS/tests/interrJR_dlySlot.s
@@ -1,6 +1,6 @@
 # Testing the internal counter is difficult because it counts clock cycles
 # rather than instructions -- if the I/O or memory latencies change then
-# the simulation output also changes and comparisons are impossible.
+# the simulation output also changes and comparisons may be impossible.
 
 	.include "cMIPS.s"
 	.text
@@ -17,7 +17,7 @@ _start: nop
         li   $k0, c0_status_reset # RESET, kernel mode, all else disabled
         mtc0 $k0, c0_status
 	li   $sp,(x_DATA_BASE_ADDR+x_DATA_MEM_SZ-8) # initialize SP: ramTop-8
-        li   $k0, 0x1800ff01  # RESET_STATUS, kernel mode, interr enabled
+        li   $k0, 0x1000ff01  # RESET_STATUS, kernel mode, interr enabled
         mtc0 $k0, c0_status
         li   $k0, c0_cause_rst    # RESET, disable counter
         mtc0 $k0, c0_cause
@@ -78,11 +78,10 @@ _excp_180:
 	.org x_EXCEPTION_0200,0
 _excp_200:
 	mfc0  $k1, c0_count  	# read current COUNT
-	sw    $k1, 0($15)
+	sw    $k1, 0($15)	#   and print it
 
-	mfc0  $k0, c0_cause	# read CAUSE and
-	nop
-	sw    $k0, 0($15)      	# print CAUSE
+	mfc0  $k0, c0_cause	# read CAUSE
+	sw    $k0, 0($15)      	#   and print it
         li    $k0, 0            # remove IRQ
         mtc0  $k0, c0_compare
 
@@ -90,7 +89,6 @@ _excp_200:
 	
 	li    $k0, 0x10008001   # CP0active, enable COUNT interrupts
         mtc0  $k0, c0_status
-	ehb
 	eret
 	#
 	#================================================================
@@ -121,9 +119,13 @@ main:	la    $15, x_IO_BASE_ADDR
  	li    $13, '\n'
 	li    $11, 0		# used with the identifiable NOPs
 
-	#
-	# let us cause an interrupt on a stalled JALR
-	#
+	##
+	## let us cause an interrupt on a stalled JALR
+	##   interrupt MUST occur on the dly-slot caused by a previous LOAD
+	## JALR must be restarted and return address cannot be saved by JALR
+	##   since that instruction was neither started nor completed
+	##
+	
 	.set numCy, 12		# magic number: cycles needed to ensure
 				#   interrupt hits the JALR
 	
@@ -144,6 +146,7 @@ two_instr:
 	la    $12, err0
 	sw    $12, 4($20)	# write error message to memory
 	nop			# align COUNT==COMPARE with JR
+	nop
 	sw    $21, 0($20)	# store jump target
 	li    $11, 0   		# this is a NOP
 	li    $11, 1   		# this is a NOP
@@ -160,13 +163,14 @@ one_instr:
 				# $19 must be zero
 				# handler copies $24 -> $19
 	nop			#   to ensure JALR did not change $24
-	bne   $zero, $19, err2	# check if return addess was changed
+	bne   $zero, $19, err2	# check if return address was changed
 	nop
 	
 	
-	#
-	# let us cause an interrupt on a JR, delayed by a LW
-	#
+	##
+	## let us cause an interrupt on a JR, delayed by a LW
+	##
+	
 	.set numCy, 22		# magic number: cycles needed to ensure
 				#   interrupt hits the JALR
 	
@@ -181,6 +185,7 @@ one_instr:
 	and   $5, $5, $6
 	mtc0  $5, c0_cause   	# enable counter
 	nop
+	nop			# align interr with JALR
 
 	sw    $9, 0($15)     	# show old+numCycles
 
@@ -193,10 +198,10 @@ one_instr:
 	li    $11, 10  		# this is a NOP
 	li    $11, 11  		# this is a NOP
 	li    $11, 12  		# this is a NOP
-        lw    $23, 0($20)	# load target address to cause delay slot
+        lw    $23, 0($20)	# load target address to cause 2x delay slots
         jalr  $24, $23		# save ra in $24
 	li    $11, 13     	# this is a NOP
-one:	li    $11, 14     	# this is a NOP
+one:	li    $11, 14     	# this is a NOP, return address from jalr
 	li    $11, 15     	# this is a NOP
 
 zero_instr:
@@ -205,7 +210,7 @@ zero_instr:
 				# $19 must be zero
 				# handler copies $24 -> $19
 	nop			#   to ensure JALR did not change $24
-	bne   $zero, $19, err1	# check if return addess was changed
+	bne   $zero, $19, err1	# check if return address was changed
 	nop
 
 	li    $11, 16		# this is a NOP
diff --git a/cMIPS/tests/interr_x2.expected b/cMIPS/tests/interr_x2.expected
new file mode 100644
index 0000000..ea62ccd
--- /dev/null
+++ b/cMIPS/tests/interr_x2.expected
@@ -0,0 +1,23 @@
+C
+e
+e
+C
+e
+e
+C
+e
+e
+C
+e
+e
+C
+e
+e
+C
+e
+e
+C
+e
+e
+C
+e
diff --git a/cMIPS/tests/interr_x2.s b/cMIPS/tests/interr_x2.s
new file mode 100644
index 0000000..7a25d74
--- /dev/null
+++ b/cMIPS/tests/interr_x2.s
@@ -0,0 +1,214 @@
+# Objective: test two more or less simultaneous interrupts, one by internal
+#  counter and one by the external counter.
+#
+# 1st test: hi priority (internal cntr) arrives first
+# 2nd test: lo priority (external cntr) arrives first 
+#           then the two alternate
+
+# Testing the internal counter is difficult because it counts clock cycles
+# rather than instructions -- if the I/O or memory latencies change then
+# the simulation output also changes and comparisons may be impossible.
+
+
+	.include "cMIPS.s"
+	.text
+	.align 2
+	.set noat
+	.set noreorder
+	.set numCy, 64
+	.global _start
+	.global _exit
+
+        .set c0_cause_rst, 0x0880007c # disable counter, separate IntVector
+	.set ext_restart, 0xc0000000  # start ext_counter, intrr enable
+	
+_start: nop
+        li   $k0, c0_status_reset # RESET, kernel mode, all else disabled
+        mtc0 $k0, c0_status
+	li   $sp,(x_DATA_BASE_ADDR+x_DATA_MEM_SZ-8) # initialize SP: ramTop-8
+        li   $k0, 0x1000ff01      # RESET_STATUS, kernel mode, interr enabled
+        mtc0 $k0, c0_status
+        li   $k0, c0_cause_rst    # RESET, disable counter
+        mtc0 $k0, c0_cause
+
+	la   $15,x_IO_BASE_ADDR
+	nop
+	j    main
+	nop
+exit:	
+_exit:	nop	# flush pipeline
+	nop
+	nop
+	nop
+	nop
+	nop
+	wait	# then stop VHDL simulation
+	nop
+
+
+	#----------------------------------------------------------------
+        .org x_EXCEPTION_0000,0
+_excp_0000:        wait 0x01
+        la   $k0, x_IO_BASE_ADDR
+        mfc0 $k1, c0_cause
+        sw   $k1, 0($k0)        # print CAUSE, flush pipe and stop simulation
+        nop
+        nop
+        nop
+        wait 0x01
+        nop
+	#----------------------------------------------------------------
+        .org x_EXCEPTION_0100,0
+_excp_0100:        wait 0x02
+        la   $k0, x_IO_BASE_ADDR
+        mfc0 $k1, c0_cause
+        sw   $k1, 0($k0)        # print CAUSE, flush pipe and stop simulation
+        nop
+        nop
+        nop
+        wait 0x02
+        nop
+	#----------------------------------------------------------------
+	.org x_EXCEPTION_0180,0
+_excp_180:        wait 0x03
+        la   $k0, x_IO_BASE_ADDR
+        mfc0 $k1, c0_cause
+        sw   $k1, 0($k0)        # print CAUSE, flush pipe and stop simulation
+        nop
+        nop
+        nop
+        wait 0x03
+	nop
+
+	
+	
+	#
+	# interrupt handler =============================================
+	#
+	.org x_EXCEPTION_0200,0
+_excp_200:
+        nop			# wait a looong time to ensure both
+        nop			#  interrupts are signalled
+        nop
+        nop
+        nop
+        nop
+        nop
+        nop
+        nop
+        nop
+        nop
+        nop
+        nop
+        nop
+        nop
+        nop
+        nop
+
+	mfc0  $k0, c0_cause	# read CAUSE and
+	nop
+	nop # sw    $k0, 0($15)      	# print it
+
+	andi  $k1, $k0, 0x8000  # is hi_priority active?
+
+	beq   $k1, $zero, lo_pri # YES, handle it
+	nop
+
+hi_pri:	li    $k0, 0            # remove IRQ
+        mtc0  $k0, c0_compare
+
+	mfc0  $k1, c0_count  	# read current COUNT
+	nop # sw    $k1, 0($15)
+
+	addi  $k1, $k1, (numCy+10)  	# interrupt again in numCy cycles
+	mtc0  $k1, c0_compare
+
+	li    $k1, 'C'		# tell it was Counter
+	
+	j     rf_irq		#   and return
+	nop
+	
+lo_pri: lui   $k0, %hi(ext_restart)
+	ori   $k0, $k0, (numCy-40)  	# interrupt again in numCy cycles
+	lui   $k1, %hi(HW_counter_addr)
+	ori   $k1, $k1,%lo(HW_counter_addr)
+	sw    $k0, 0($k1)	# restart external counter
+	li    $k1, 'e'		# tell it was external counter
+	
+	
+rf_irq:	sw    $k1, 0x20($15)	# print IRQ source
+	sw    $13, 0x20($15)
+	
+	li    $k0, 0x1000f001   # CP0active, enable COUNT interrupts
+        mtc0  $k0, c0_status
+	eret
+	#
+	#================================================================
+	#
+
+
+	#----------------------------------------------------------------	
+	.org x_EXCEPTION_BFC0,0
+_excp_BFC0:        wait 0x04
+        la   $k0, x_IO_BASE_ADDR
+        mfc0 $k1, c0_cause
+        sw   $k1, 0($k0)        # print CAUSE, flush pipe and stop simulation
+        nop
+        nop
+        wait 0x04
+        nop
+
+
+        ##
+        ##-----------------------------------------------------------------
+        ##
+	.set TRUE,  1
+	.set FALSE, 0
+	
+	.org x_ENTRY_POINT,0
+main:	la    $15, x_IO_BASE_ADDR
+ 	li    $13, '\n'
+	li    $11, 0		# used with the identifiable NOPs
+
+	#
+	# let us cause two interrupts
+	#
+
+	li    $5, numCy  	# interrupt again in numCy cycles
+	mtc0  $5, c0_compare
+
+	# enable Counter
+	mfc0  $5, c0_cause
+	li    $6, 0xf7ffffff   	# CAUSE.DisableCount <= false
+	and   $5, $5, $6
+	mtc0  $5, c0_cause   	# enable counter
+
+	# start external counter
+	lui   $5, %hi(ext_restart)
+	ori   $5, $5, (numCy+4)  	# interrupt in numCy cycles
+	lui   $6, %hi(HW_counter_addr)	#   AFTER Count=Compare interrupt
+	ori   $6, $6, %lo(HW_counter_addr)
+	sw    $5, 0($6)		# restart external counter
+
+	nop
+
+	# lets do nothing for a long time.
+
+	li    $20, 0
+	li    $21, 20
+
+loop:	addi  $20, $20, 1
+	li    $2, 1
+	li    $2, 2
+	li    $2, 3
+	li    $2, 4
+	li    $2, 5
+	li    $2, 6
+	bne   $20, $21, loop
+	nop
+
+	nop
+	j     exit
+	nop
+	
+	
diff --git a/cMIPS/tests/uart_irx.c b/cMIPS/tests/uart_irx.c
index 9c837c4..fa79769 100644
--- a/cMIPS/tests/uart_irx.c
+++ b/cMIPS/tests/uart_irx.c
@@ -21,9 +21,6 @@ typedef struct status { // status register fields (uses only ls byte)
   overun  : 1;        // overun error (bit 0)
 } Tstatus;
 
-#define RXfull  0x00000020
-#define TXempty 0x00000040
-
 
 typedef union ctlStat { // control + status on same address
   Tcontrol  ctl;        // write-only
@@ -53,12 +50,20 @@ int main(void) { // receive a string through the UART serial interface
   uart = (void *)IO_UART_ADDR; // bottom of UART address range
 
   ctrl.ign   = 0;
-  ctrl.rts   = 0;
+  ctrl.rts   = 0;  // make RTS=0 to hold remote unit
   ctrl.intTX = 0;
-  ctrl.intRX = 1;
-  ctrl.speed = 1;    // operate at 1/2 of the highest data rate
+  ctrl.intRX = 0;
+  ctrl.speed = 1;  // operate at 1/2 of the highest data rate
+  uart->cs.ctl = ctrl; // initizlize UART
+
+  ctrl.ign   = 0;
+  ctrl.rts   = 1;  // make RTS=1 so RemoteUnit starts its transmission
+  ctrl.intTX = 0;
+  ctrl.intRX = 1;  // do generate interrupts on RXbuffer full
+  ctrl.speed = 1;  // operate at 1/2 of the highest data rate
   uart->cs.ctl = ctrl;
 
+
   // handler sets flag=bfr[2] to 1 after new character is received;
   // this program resets the flag on fetching a new character from buffer
 
diff --git a/cMIPS/tests/uarttx.c b/cMIPS/tests/uarttx.c
index 09d212e..a9b68c8 100644
--- a/cMIPS/tests/uarttx.c
+++ b/cMIPS/tests/uarttx.c
@@ -22,8 +22,6 @@ typedef struct status {  // status register fields (uses only ls byte)
   overun  : 1;           // overun error (bit 0)
 } Tstatus;
 
-#define RXfull  0x00000020
-#define TXempty 0x00000040
 
 typedef union ctlStat { // control + status on same address
   Tcontrol  ctl;        // write-only
@@ -89,7 +87,7 @@ int main(void) { // send a string through the UART serial interface
   ctrl.intRX = 0;
   ctrl.ign2  = 0;
   ctrl.ign   = 0;
-  ctrl.rts   = 1;
+  ctrl.rts   = 0;  // make RTS=0 so RemoteUnit won't transmit, just receive
   uart->cs.ctl = ctrl;
 
   i = -1;
diff --git a/cMIPS/v_rx.sav b/cMIPS/v_rx.sav
index 5b5101b..2b871ff 100644
--- a/cMIPS/v_rx.sav
+++ b/cMIPS/v_rx.sav
@@ -1,20 +1,22 @@
 [*]
 [*] GTKWave Analyzer v3.3.37 (w)1999-2012 BSI
-[*] Sun May 17 23:18:38 2015
+[*] Fri Apr  8 16:29:19 2016
 [*]
 [dumpfile] "/home/roberto/cMIPS/v_cMIPS.vcd"
-[dumpfile_mtime] "Sun May 17 23:11:59 2015"
-[dumpfile_size] 27081351
+[dumpfile_mtime] "Fri Apr  8 13:54:30 2016"
+[dumpfile_size] 11860622
 [savefile] "/home/roberto/cMIPS/v_rx.sav"
-[timestart] 56766300000
-[size] 1062 914
+[timestart] 1652600000
+[size] 1133 1018
 [pos] -1 -1
-*-27.000000 56960000000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
+*-26.000000 1820000000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
+[treeopen] u_core.
+[treeopen] u_core.u_alu.
 [treeopen] u_simple_uart.
 [sst_width] 210
-[signals_width] 227
+[signals_width] 218
 [sst_expanded] 1
-[sst_vpaned_height] 267
+[sst_vpaned_height] 304
 @28
 clk
 @22
@@ -23,9 +25,9 @@ u_core.instr_fetched[31:0]
 @200
 -    decode, reg fetch
 @22
-u_core.rf_instruction[31:0]
 u_core.regs_a[31:0]
 u_core.regs_b[31:0]
+u_core.rf_instruction[31:0]
 @200
 -    exec
 @24
@@ -39,55 +41,65 @@ u_core.result[31:0]
 @28
 u_core.b_sel[3:0]
 @22
-u_core.data_inp[31:0]
-u_core.data_out[31:0]
 d_addr[31:0]
 @28
 cpu_d_aval
 u_core.mm_wrmem
-@200
--    write-back
-@28
-u_core.wb_muxc[2:0]
-u_core.wb_wreg
 @22
-u_core.wb_a_c[4:0]
-u_core.wb_c[31:0]
+u_core.data_inp[31:0]
+u_core.data_out[31:0]
 @200
--  UART
+-   UART
 @28
+u_simple_uart.u_uart.rts
 u_simple_uart.u_uart.s_stat
+u_simple_uart.u_uart.status[7:0]
 @22
 u_simple_uart.u_uart.status[7:0]
 @28
 u_simple_uart.u_uart.s_ctrl
-@22
 u_simple_uart.u_uart.ctrl[7:0]
-@28
-u_simple_uart.u_uart.s_rx
-@22
-u_simple_uart.u_uart.rxreg[7:0]
 @200
--  reception
+-   reception circuit
 @24
 u_simple_uart.u_uart.rxcpu_dbg_st[31:0]
+u_simple_uart.u_uart.rx_dbg_st[31:0]
+@29
+u_simple_uart.u_uart.s_rx
+@22
+u_simple_uart.u_uart.rxreg[7:0]
 @28
-u_simple_uart.u_uart.rx_bfr_full
+u_simple_uart.u_uart.interr_rx_full
+@200
+-  transmission circuit
 @24
-u_simple_uart.u_uart.rx_dbg_st[31:0]
+u_simple_uart.u_uart.txcpu_dbg_st[31:0]
+u_simple_uart.u_uart.tx_dbg_st[31:0]
+@22
+u_simple_uart.u_uart.txreg[7:0]
 @28
-u_simple_uart.u_uart.sta_recv_sto[9:0]
-u_simple_uart.u_uart.rxclk
-u_simple_uart.u_uart.rxdat
+u_simple_uart.u_uart.txclk
+u_simple_uart.u_uart.txdat
+u_simple_uart.u_uart.interr_tx_empty
 @200
 -  REMOTE (fake) UART
-@28
-u_uart_remota.start
 @24
 u_uart_remota.tx_dbg_st[31:0]
 @28
 u_uart_remota.outdat
+@24
+u_uart_remota.rx_dbg_st[31:0]
+@28
+u_uart_remota.recv[7:0]
+@22
+u_uart_remota.recv[7:0]
 @200
--
+-    write-back
+@28
+u_core.wb_muxc[2:0]
+u_core.wb_wreg
+@22
+u_core.wb_a_c[4:0]
+u_core.wb_c[31:0]
 [pattern_trace] 1
 [pattern_trace] 0
diff --git a/cMIPS/vhdl/core.vhd b/cMIPS/vhdl/core.vhd
index 6686491..1521267 100644
--- a/cMIPS/vhdl/core.vhd
+++ b/cMIPS/vhdl/core.vhd
@@ -135,6 +135,7 @@ architecture rtl of core is
   signal nullify_MM_pre, nullify_MM_int :std_logic;
   signal annul_1, annul_2, annul_twice : std_logic;
   signal interrupt, exception_stall : std_logic;
+  signal dly_i0, dly_i1, dly_i2, dly_interr: std_logic; 
   signal exception_taken, interrupt_taken : std_logic;
   signal nullify_fetch, nullify, MM_nullify : boolean;
   signal addrError, MM_addrError, abort_ref, MM_ll_sc_abort : boolean;
@@ -1254,7 +1255,7 @@ begin
     end if;
   end process RF_DECODE_FUNCT;
 
-  exception_dec <= exception_type'pos(exception);  -- debugging only
+  -- exception_dec <= exception_type'pos(exception);  -- debugging only
  
   can_trap <= ctrl_word.excp or funct_word.excp or rimm_word.excp;
   
@@ -1795,7 +1796,20 @@ begin
   is_interr <= ( (interrupt = '1') and
                  (STATUS(STATUS_EXL) = '0') and
                  (STATUS(STATUS_ERL) = '0') and
-                 (STATUS(STATUS_IE)  = '1') );
+                 (STATUS(STATUS_IE)  = '1') and
+                 (dly_interr = '0')         and
+                 (interrupt_taken = '0') );  -- single cycle exception req
+
+  -- While returning from an exception (especially another interrupt),
+  --   delay the IRQ to make sure the interrupted instruction completes;
+  -- This is needed to ensure forward-progress: at least one instruction
+  --   must complete before another interrupt may be taken.
+  
+  dly_i0 <= '1' when is_exception = exERET else '0';
+  U_DLY_INT1: FFD port map (clk, rst, '1',dly_i0, dly_i1);
+  U_DLY_INT2: FFD port map (clk, rst, '1',dly_i1, dly_i2);
+  dly_interr <= dly_i0 or dly_i1 or dly_i2;
+
   
   -- check for overflow in EX, send it to MM for later processing
   is_ovfl <= (EX_can_trap = b"10" and ovfl = '1');
@@ -1821,6 +1835,7 @@ begin
                      exInterr        when is_interr     else
                      EX_exception;
 
+  exception_dec <= exception_type'pos(EX_is_exception);  -- debugging only
   
   -- ----------------------------------------------------------------------
   PIPESTAGE_EXCP_EX_MM: reg_excp_EX_MM
@@ -1837,8 +1852,10 @@ begin
               int_req,MM_int_req,
               is_SC, MM_is_SC, is_MFC0, MM_is_MFC0,
               EX_is_exception, is_exception);
-  
 
+  -- exception_dec <= exception_type'pos(is_exception);  -- debugging only
+  
+   
   -- STATUS -- pg 79 -- cop0_12 --------------------
   COP0_DECODE_EXCEPTION_AND_UPDATE_STATUS:
   process (MM_a_rt, is_exception, cop0_inp,
@@ -1872,7 +1889,7 @@ begin
     nullify_MM_pre  <= '0';
     
     newSTATUS             := STATUS;    -- preserve as needed
-    newSTATUS(STATUS_BEV) := '0';  -- interrupts at offset 0x200
+    newSTATUS(STATUS_BEV) := '0';  -- interrupts at offset 0x200, not boot
     newSTATUS(STATUS_CU3) := '0';  -- COP-3 absent (always)
     newSTATUS(STATUS_CU2) := '0';  -- COP-2 absent (always)
     newSTATUS(STATUS_CU1) := '0';  -- COP-1 absent (always)
@@ -2067,7 +2084,7 @@ begin
 
 
       when exTLBP | exTLBR | exTLBWI | exTLBWR =>  -- TLB access
-        i_stall := '0';                 -- stall the processor
+        i_stall := '0';                 -- do not stall the processor
         
 
       when exTLBrefillIF =>
@@ -2106,8 +2123,8 @@ begin
         newSTATUS(STATUS_IE)  := '0';   -- disable interrupts
         i_update     := '1';
         i_update_r   := cop0reg_STATUS;
-        i_epc_update   := '0';
-        i_nullify      := TRUE;         -- nullify instructions in IF,RF,EX
+        i_epc_update := '0';
+        i_nullify    := TRUE;           -- nullify instructions in IF,RF,EX
         
       when exTLBdblFaultIF | exTLBinvalIF  =>
         ExcCode <= cop0code_TLBL;
@@ -2122,8 +2139,8 @@ begin
         newSTATUS(STATUS_IE)  := '0';   -- disable interrupts
         i_update     := '1';
         i_update_r   := cop0reg_STATUS;
-        i_epc_update   := '0';
-        i_nullify      := TRUE;         -- nullify instructions in IF,RF,EX
+        i_epc_update := '0';
+        i_nullify    := TRUE;           -- nullify instructions in IF,RF,EX
 
 
       when exTLBdblFaultRD | exTLBdblFaultWR |
@@ -2168,7 +2185,7 @@ begin
       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     
+          interrupt_taken       <= '1';
           newSTATUS(STATUS_UM)  := '0'; -- enter kernel mode          
           newSTATUS(STATUS_EXL) := '1'; -- at exception level
           newSTATUS(STATUS_IE)  := '0'; -- disable interrupts
diff --git a/cMIPS/vhdl/sdram.vhd b/cMIPS/vhdl/sdram.vhd
index f1678ff..dad1dc4 100644
--- a/cMIPS/vhdl/sdram.vhd
+++ b/cMIPS/vhdl/sdram.vhd
@@ -457,4 +457,4 @@ begin
 
 end architecture fake;
 
--- ---------------------------------------------------------------------
+
diff --git a/cMIPS/vhdl/tb_cMIPS.vhd b/cMIPS/vhdl/tb_cMIPS.vhd
index 6c9597f..226e0c1 100644
--- a/cMIPS/vhdl/tb_cMIPS.vhd
+++ b/cMIPS/vhdl/tb_cMIPS.vhd
@@ -178,7 +178,6 @@ architecture TB of tb_cMIPS is
           cnt_ic_ref : in  integer;
           cnt_ic_hit : in  integer);
   end component sys_stats;
-
   
   component ram_addr_decode is
     port (rst         : in  std_logic;
@@ -224,17 +223,6 @@ architecture TB of tb_cMIPS is
           i_busError  : out std_logic);
   end component inst_addr_decode;
     
-  component simul_ROM is 
-    generic (LOAD_FILE_NAME : string);
-    port (rst     : in    std_logic;
-          clk     : in    std_logic;
-          sel     : in    std_logic;
-          rdy     : out   std_logic;
-          strobe  : in    std_logic;
-          addr    : in    std_logic_vector;
-          data    : out   std_logic_vector);
-  end component simul_ROM;
-
   component ROM is 
     generic (LOAD_FILE_NAME : string);
     port (rst     : in    std_logic;
@@ -261,21 +249,6 @@ architecture TB of tb_cMIPS is
           dump_ram : in    std_logic);
   end component RAM;
 
-  component fpga_RAM is
-    generic (LOAD_FILE_NAME : string; DUMP_FILE_NAME : string);
-    port (rst      : in    std_logic;
-          clk      : in    std_logic;
-          sel      : in    std_logic;
-          rdy      : out   std_logic;
-          wr       : in    std_logic;
-          strobe   : in    std_logic;
-          addr     : in    std_logic_vector;
-          data_inp : in    std_logic_vector;
-          data_out : out   std_logic_vector;
-          byte_sel : in    std_logic_vector;
-          dump_ram : in    std_logic);
-  end component fpga_RAM;
-
   component SDRAM_controller is
     port (rst      : in    std_logic;     -- FPGA reset (=0)
           clk2x    : in    std_logic;     -- 100MHz clock
@@ -399,6 +372,9 @@ architecture TB of tb_cMIPS is
     inclk  : IN  STD_LOGIC;
     outclk : OUT STD_LOGIC); 
   end component mf_altclkctrl;
+
+
+
   
   signal clock_50mhz, clk,clkin : std_logic;
   signal clk4x,clk4x0, clk4x180, clk2x : std_logic;
@@ -575,7 +551,7 @@ begin  -- TB
     port map (rst, clk, mem_d_sel, ram_rdy, mem_wr, phi2,
               mem_addr, datram_out, datram_inp, mem_xfer, dump_ram);
 
-  U_SDRAM_controller: SDRAM_controller port map 
+  U_SDRAMc: SDRAM_controller port map 
     (rst, clk,hcs,sdram_rdy,wr,cpu_xfer,haddr,hDinp,hDout,
      sdcke,sdscs,sdras,sdcas,sdwe,sddqm0,sddqm1,sdba0,sdba1,sdaddr,sddata); 
 
@@ -1019,39 +995,31 @@ end architecture behavioral;
 --++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
 
+
 -- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+use work.all;
+
 configuration CFG_TB of TB_CMIPS is
   for TB
+  
+  -- use fake / behavioral
+    for U_I_CACHE : I_cache use entity work.I_cache(fake); end for;
+
+  -- use simulation / rtl
+  for U_ROM : ROM         use entity work.ROM(simulation); end for;
+
+  -- use simulation / rtl
+  for U_RAM : RAM         use entity work.RAM(simulation); end for;
+
+  -- use fake / behavioral
+  for U_D_CACHE : D_cache use entity work.D_cache(fake); end for;
 
-    -- use fake / behavioral
-    for U_I_CACHE : I_cache
-      use entity work.I_cache(fake);
-    end for;
-
-    -- use simulation / rtl
-    for U_ROM : ROM
-      use entity work.ROM(simulation);
-    end for;
-
-    -- use simulation / rtl
-    for U_RAM : RAM
-      use entity work.RAM(simulation);
-    end for;
-
-    -- use fake / behavioral
-    for U_D_CACHE : D_cache
-      use entity work.D_cache(fake);
-    end for;
-
-    -- use fake / rtl
-    for U_FPU: FPU
-      use entity work.FPU(rtl);
-    end for;
+  -- use fake / rtl
+  for U_FPU: FPU          use entity work.FPU(rtl); end for;
     
-    -- use fake / simple
-    for U_SDRAM_controller : SDRAM_controller
-      use entity work.SDRAM_controller(fake);
-    end for;
+  -- use fake / simple
+  for U_SDRAMc : SDRAM_controller
+                          use entity work.SDRAM_controller(fake);  end for;
 
   end for;
 end configuration CFG_TB;
-- 
GitLab