From d1d7e39da76bc751c35a62b994d004c405ebc849 Mon Sep 17 00:00:00 2001
From: Roberto Hexsel <roberto@inf.ufpr.br>
Date: Sat, 14 Nov 2015 13:10:42 -0200
Subject: [PATCH] yet another RAM address decoding scheme

---
 cMIPS/bin/run.sh         |  8 ++++----
 cMIPS/include/start.s    |  4 ++--
 cMIPS/tests/busError_i.s | 28 ++++++++++++++++++++++++++++
 cMIPS/tests/doTests.sh   |  6 +++---
 cMIPS/tests/echo.c       |  8 +++-----
 cMIPS/tests/stdin_out.s  |  3 +++
 cMIPS/vhdl/core.vhd      |  4 +---
 cMIPS/vhdl/tb_cMIPS.vhd  | 27 ++++++++++++++++++++++++---
 8 files changed, 68 insertions(+), 20 deletions(-)

diff --git a/cMIPS/bin/run.sh b/cMIPS/bin/run.sh
index 0e0a33c..7600998 100755
--- a/cMIPS/bin/run.sh
+++ b/cMIPS/bin/run.sh
@@ -1,7 +1,7 @@
 #!/bin/bash
 
 ## ------------------------------------------------------------------------
-## classicalMIPS, Roberto Hexsel, 23nov2012-12nov2015
+## classicalMIPS, Roberto Hexsel, 23nov2012-13nov2015
 ## ------------------------------------------------------------------------
 
 # set -x
@@ -89,11 +89,11 @@ if [ -v $WAVE ] ; then
 
 else 
 
-  ## this echo is for testing the reads from stdin
-  ## echo -en "abc\n%" | 
-  "${simulator}" $options ; gtkwave -O /dev/null ${visual} ${sav}
+  "${simulator}" $options ; gtkwave -O /dev/null ${visual} ${sav} &
 
 fi
 
+
+
 # --wave=${visual%.vcd}.ghw
 
diff --git a/cMIPS/include/start.s b/cMIPS/include/start.s
index 747e661..fdc6747 100644
--- a/cMIPS/include/start.s
+++ b/cMIPS/include/start.s
@@ -75,8 +75,8 @@ _start:
 	li   $k0, 4
 	mtc0 $k0, cop0_Wired
 
-	# initialize SP at top of RAM: ramTop - 8
-	li   $sp, ((x_DATA_BASE_ADDR+x_DATA_MEM_SZ) - 8)
+	# initialize SP at top of RAM: ramTop - 16
+	li   $sp, ((x_DATA_BASE_ADDR+x_DATA_MEM_SZ) - 16)
 	
 	# set STATUS, cop0, hw interrupt IRQ7,IRQ6,IRQ5 enabled, user mode
         li   $k0, 0x1000e011
diff --git a/cMIPS/tests/busError_i.s b/cMIPS/tests/busError_i.s
index 4cc0b54..b1f6957 100644
--- a/cMIPS/tests/busError_i.s
+++ b/cMIPS/tests/busError_i.s
@@ -2,6 +2,9 @@
 	## generate and handle (??) a instruction fetch bus error
 	## the error occurs on an attempt to fetch from non-exixting ROM
 	##
+	## one TLB entry must point into the non-existing ROM address to
+	##   avoid a TLBmiss exception.
+	##
 	
 	.include "cMIPS.s"
 	.text
@@ -9,6 +12,7 @@
 	.set noreorder
 	.global _start, _exit
 	.ent    _start
+
 _start: nop
 	li   $sp,(x_DATA_BASE_ADDR+x_DATA_MEM_SZ-8) # initialize SP: ramTop-8
 
@@ -16,6 +20,30 @@ _start: nop
         li   $k0, 0x10000010
         mtc0 $k0, cop0_STATUS
 
+	.set bad_address, (x_INST_BASE_ADDR + x_INST_MEM_SZ + 4096)
+	
+        # get physical page number for 2 pages above top of ROM
+        #   then write it to TLB[3]
+
+        li    $a0, ( bad_address >>12 )
+        sll   $a2, $a0, 12      # tag for RAM[8,9] double-page
+        mtc0  $a2, cop0_EntryHi
+
+        li    $a0, ((bad_address + 0*4096) >>12 )
+        sll   $a1, $a0, 6       # ROM_top+4096 (even)
+        ori   $a1, $a1, 0b00000000000000000000000000000111 # ccc=0, d,v,g1
+        mtc0  $a1, cop0_EntryLo0
+
+        li    $a0, ((bad_address + 1*4096) >>12 )
+        sll   $a1, $a0, 6       # ROM_top+8192 (odd)
+        ori   $a1, $a1, 0b00000000000000000000000000000111 # ccc=0, d,v,g1
+        mtc0  $a1, cop0_EntryLo1
+
+        # and write it to TLB[3]
+        li    $k0, 3
+        mtc0  $k0, cop0_Index
+        tlbwi 
+
 	j    main
         nop
 
diff --git a/cMIPS/tests/doTests.sh b/cMIPS/tests/doTests.sh
index 8b7c9d8..36ab14c 100755
--- a/cMIPS/tests/doTests.sh
+++ b/cMIPS/tests/doTests.sh
@@ -67,7 +67,7 @@ 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"
 a_FUN="jaljr jr_2 jal_fun_jr jalr_jr bltzal_fun_jr"
-a_OTH="mult div  mul sll slr movz wsbh_seb extract insert"
+a_OTH="mult div mul sll slr movz wsbh_seb extract insert"
 a_BHW="lbsb lhsh lwsw lwswIncr swlw lwl_lwr"
 a_MEM="lwSweepRAM"
 a_CTR="teq_tne teq_jal teq_lw tlt_tlti tltu_tgeu eiDI ll_sc overflow counter"
@@ -88,7 +88,7 @@ stoptime=20ms
 if [ 0 = 0 ] ; then
     for F in $(echo $a_FWD $a_CAC $a_BEQ $a_FUN $a_OTH $a_BHW $a_MEM $a_CTR $a_COP $a_MMU $a_EXC $a_IOs);
     do
-	$bin/assemble.sh ${F}.s
+	$bin/assemble.sh ${F}.s || exit 1
 	${simulator} --ieee-asserts=disable --stop-time=$stoptime \
               2>/dev/null   >$F.simout
 	diff $ignBLANKS -q $F.expected $F.simout
@@ -132,7 +132,7 @@ else
 fi
 
 for F in $(echo "$SIMULATE" ) ; do 
-    $bin/compile.sh -O 3 ${F}.c
+    $bin/compile.sh -O 3 ${F}.c  || exit 1
     ${simulator} --ieee-asserts=disable --stop-time=$stoptime \
           2>/dev/null >$F.simout
     diff $ignBLANKS -q $F.expected $F.simout
diff --git a/cMIPS/tests/echo.c b/cMIPS/tests/echo.c
index c56ea34..218de29 100644
--- a/cMIPS/tests/echo.c
+++ b/cMIPS/tests/echo.c
@@ -1,6 +1,6 @@
 // Test stdin and stdout -- echo characters read from stdin to stdout
-//   test ends when '%' (percent) is read.
-//   from_stdin() returns EOT (0x04) the there is nothing on stdin
+//   test ends when '%' (percent) is read/typed.
+//   from_stdin() returns LF (0x0a) the there is nothing on stdin
 // 
 // Keep in mind that the terminal itself does echoing -- characters are
 //  displayed AFTER a second NewLine because of the terminal also echoes
@@ -19,9 +19,7 @@ void main(void) {
 
     c = (char)from_stdin();
 
-    if (c != (char)0x04) { // EOT
-      to_stdout(c);
-    }
+    to_stdout(c);
 
   } while (c != '%');
 
diff --git a/cMIPS/tests/stdin_out.s b/cMIPS/tests/stdin_out.s
index 8a8a54c..2d083e8 100644
--- a/cMIPS/tests/stdin_out.s
+++ b/cMIPS/tests/stdin_out.s
@@ -1,3 +1,6 @@
+# Test stdin and stdout -- echo characters read from stdin to stdout
+#   test ends when '%' (percent) is read/typed.
+
 	.include "cMIPS.s"
 	.text
 	.align 2
diff --git a/cMIPS/vhdl/core.vhd b/cMIPS/vhdl/core.vhd
index e714031..b966cbc 100644
--- a/cMIPS/vhdl/core.vhd
+++ b/cMIPS/vhdl/core.vhd
@@ -73,8 +73,6 @@ architecture rtl of core is
          EX_can_trap:     out std_logic_vector;
          RF_exception:    in  exception_type;
          EX_exception:    out exception_type;
---          RF_trap_instr:   in  instr_type;
---          EX_trap_instr:   out instr_type;
          RF_is_delayslot: in  std_logic;
          EX_is_delayslot: out std_logic;
          RF_PC_abort:     in  boolean;
@@ -85,7 +83,7 @@ architecture rtl of core is
          EX_trapped:      out boolean);
   end component reg_excp_RF_EX;
 
-  component reg_excp_EX_MM is -- jjjjj
+  component reg_excp_EX_MM is
     port(clk, rst, ld:  in  std_logic;
          EX_cop0_reg:   in  reg5;
          MM_cop0_reg:   out reg5;
diff --git a/cMIPS/vhdl/tb_cMIPS.vhd b/cMIPS/vhdl/tb_cMIPS.vhd
index e6fff99..1fca33f 100644
--- a/cMIPS/vhdl/tb_cMIPS.vhd
+++ b/cMIPS/vhdl/tb_cMIPS.vhd
@@ -750,6 +750,14 @@ architecture behavioral of ram_addr_decode is
   constant r_mask : std_logic_vector := r_hi & r_lo;
     
   signal in_range : boolean;
+
+  constant RAM_ADDR_BOTTOM : natural :=
+        to_integer(signed(x_DATA_BASE_ADDR(HI_SEL_BITS downto LO_SEL_BITS)));
+  constant RAM_ADDR_RANGE : natural :=
+    (to_integer(signed(x_DATA_BASE_ADDR(HI_SEL_BITS downto LO_SEL_BITS)))
+     +
+     to_integer(signed(x_DATA_MEM_SZ(HI_SEL_BITS downto LO_SEL_BITS))));
+  constant RAM_ADDR_TOP : natural := RAM_ADDR_BOTTOM + RAM_ADDR_RANGE;
   
 begin
 
@@ -757,9 +765,22 @@ begin
 --                 and ((addr and a_mask) = x_DATA_BASE_ADDR)
 --                 and ((addr and r_mask) = x_DATA_BASE_ADDR) );
 
-  in_range <= ( addr(HI_SEL_BITS downto LO_SEL_BITS)
-                =
-                x_DATA_BASE_ADDR(HI_SEL_BITS downto LO_SEL_BITS) );
+-- this works only for small RAMS
+--   in_range <= ( addr(HI_SEL_BITS downto LO_SEL_BITS)
+--                 =
+--                 x_DATA_BASE_ADDR(HI_SEL_BITS downto LO_SEL_BITS) );
+
+
+  -- this is ONLY acceptable for simulations;
+  -- computing these differences is TOO expensive for synthesis
+  in_range <= ( (to_integer(signed(addr(HI_SEL_BITS downto LO_SEL_BITS)))
+                 >= 
+                 RAM_ADDR_BOTTOM)
+                and
+                (to_integer(signed(addr(HI_SEL_BITS downto LO_SEL_BITS)))
+                 <
+                 RAM_ADDR_TOP)
+              );
   
   aVal <= '0' when (rst = '1' and cpu_d_aVal = '0' and in_range) else '1';
 
-- 
GitLab