diff --git a/cMIPS/vhdl/core.vhd b/cMIPS/vhdl/core.vhd
index d5991dac45a6a7116940a2d4ae773b2dd4a8e63c..54af5119218ef717bbabf11d05152ddceaf1dd63 100644
--- a/cMIPS/vhdl/core.vhd
+++ b/cMIPS/vhdl/core.vhd
@@ -48,251 +48,6 @@ end core;
 
 architecture rtl of core is
 
--- fields of the control table
---    aVal:  std_logic;        -- addressValid, enable data-mem=0
---    wmem:  std_logic;        -- READ=1/WRITE=0 in/to memory
---    i:     instr_type;       -- instruction
---    wreg:  std_logic;        -- register write=0
---    selB:  std_logic;        -- B ALU input, reg=0 ext=1
---    fun:   std_logic;        -- check function_field=1
---    oper:  t_alu_fun;        -- ALU operation
---    muxC:  reg3;             -- select result mem=0 ula=1 jr=2 pc+8=3
---    c_sel: reg2;             -- select destination reg RD=0 RT=1 31=2
---    extS:  std_logic;        -- sign-extend=1, zero-ext=0
---    PCsel: reg2;             -- PCmux 0=PC+4 1=beq 2=j 3=jr
---    br_t:  t_comparison;     -- branch: 0=no 1=beq 2=bne
---    excp:  reg2              -- stage with exception 0=no,1=rf,2=ex,3=mm
-  
-  constant ctrl_table : t_control_mem := (
-  --aVal wmem ins wreg selB fun oper muxC  csel extS PCsel br_t excp
-    ('1','1',iALU, '1','0','1',opNOP,"001","00", '0', "00",cNOP,"00"),--ALU=0
-    ('1','1',RIMM, '1','0','0',opNOP,"001","00", '1', "00",cOTH,"00"),--BR=1
-    ('1','1',J,    '1','0','0',opNOP,"001","00", '0', "10",cNOP,"00"),--j=2
-    ('1','1',JAL,  '0','0','0',opNOP,"011","10", '0', "10",cNOP,"00"),--jal=3
-    ('1','1',BEQ,  '1','0','0',opNOP,"001","00", '1', "01",cEQU,"00"),--beq=4
-    ('1','1',BNE,  '1','0','0',opNOP,"001","00", '1', "01",cNEQ,"00"),--bne=5
-    ('1','1',BLEZ, '1','0','0',opNOP,"001","00", '1', "01",cLEZ,"00"),--blez=6
-    ('1','1',BGTZ, '1','0','0',opNOP,"001","00", '1', "01",cGTZ,"00"),--bgtz=7
-    ('1','1',ADDI, '0','1','0',opADD,"001","01", '1', "00",cNOP,"10"),--addi=8
-    ('1','1',ADDIU,'0','1','0',opADD,"001","01", '1', "00",cNOP,"00"),--addiu=9
-    ('1','1',SLTI, '0','1','0',opSLT,"001","01", '1', "00",cNOP,"10"),--slti=10
-    ('1','1',SLTIU,'0','1','0',opSLTU,"001","01",'1', "00",cNOP,"00"),--sltiu11
-    ('1','1',ANDI, '0','1','0',opAND,"001","01", '0', "00",cNOP,"00"),--andi=12
-    ('1','1',ORI,  '0','1','0',opOR, "001","01", '0', "00",cNOP,"00"),--ori=13
-    ('1','1',XORI, '0','1','0',opXOR,"001","01", '0', "00",cNOP,"00"),--xori=14
-    ('1','1',LUI,  '0','1','0',opLUI,"001","01", '0', "00",cNOP,"00"),--lui=15
-    ('1','1',COP0, '1','0','1',opNOP,"110","01", '0', "00",cNOP,"00"),--COP0=16
-    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--17
-    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--18
-    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--19
-    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--beql=20
-    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--bnel=21
-    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--blzel=22
-    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--bgtzl=23
-    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--24
-    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--25
-    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--26
-    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--27
-    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--28
-    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--29
-    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--30
-    ('1','1',SPEC3,'0','0','0',opSPC,"001","00", '0', "00",cNOP,"00"),--special3
-    ('0','1',LB,   '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--lb=32
-    ('0','1',LH,   '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--lh=33
-    ('0','1',LWL,  '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--lwl=34
-    ('0','1',LW,   '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--lw=35
-    ('0','1',LBU,  '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--lbu=36
-    ('0','1',LHU,  '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--lhu=37
-    ('0','1',LWR,  '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--lwr=38
-    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--39
-    ('0','0',SB,   '1','1','0',opADD,"001","00", '1', "00",cNOP,"00"),--sb=40
-    ('0','0',SH,   '1','1','0',opADD,"001","00", '1', "00",cNOP,"00"),--sh=41
-    ('1','1',NIL,  '1','1','0',opNOP,"001","00", '0', "00",cNOP,"00"),--swl=42
-    ('0','0',SW,   '1','1','0',opADD,"001","00", '1', "00",cNOP,"00"),--sw=43
-    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--44
-    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--45
-    ('1','1',NIL,  '1','1','0',opNOP,"001","00", '0', "00",cNOP,"00"),--swr=46
-    ('1','1',NIL,  '1','1','0',opNOP,"001","00", '0', "00",cNOP,"00"),--cache=47
-    ('0','1',LL,   '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--ll=48
-    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--lwc1=49
-    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--lwc2=50
-    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--pref=51
-    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--52
-    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--ldc1=53
-    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--ldc2=54
-    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--55
-    ('0','0',SC,   '0','1','0',opADD,"111","01", '1', "00",cNOP,"00"),--sc=56
-    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--swc1=57
-    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--swc2=58
-    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--59
-    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--60
-    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--sdc1=61
-    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--sdc2=62
-    ('1','1',NOP,  '1','0','0',opNOP,"000","00", '0', "00",cNOP,"00") --63
-    );
-
--- fields of the function table (opcode=0)
---    i:     instr_type;       -- instruction
---    wreg:  std_logic;        -- register write=0
---    selB:  std_logic;        -- B ALU input, reg=0 ext=1
---    oper:  t_alu_fun;        -- ALU operation
---    muxC:  reg3;             -- select result mem=0 ula=1 jr=2 pc+8=3
---    trap:  std_logic;        -- trap on compare
---    move:  std_logic;        -- conditional move
---    sync:  std_logic;        -- synch the memory hierarchy
---    PCsel: reg2;             -- PCmux 0=PC+4 1=beq 2=j 3=jr
---    excp:  reg2              -- stage with exception 0=no,1=rf,2=ex,3=mm
-  
-  constant func_table : t_function_mem := (
-  -- i    wreg selB oper   muxC trap mov syn PCsel excp
-    (iSLL, '0','0',opSLL,  "001",'0','0','0',"00","00"),  --sll=0
-    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --1, FlPoint
-    (iSRL, '0','0',opSRL,  "001",'0','0','0',"00","00"),  --srl=2
-    (iSRA, '0','0',opSRA,  "001",'0','0','0',"00","00"),  --sra=3
-    (SLLV, '0','0',opSLLV, "001",'0','0','0',"00","00"),  --sllv=4
-    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --5
-    (SRLV, '0','0',opSRLV, "001",'0','0','0',"00","00"),  --srlv=6
-    (SRAV, '0','0',opSRAV, "001",'0','0','0',"00","00"),  --srav=7
-    (JR,   '1','0',opNOP,  "001",'0','0','0',"11","00"),  --jr=8
-    (JALR, '0','0',opNOP,  "011",'0','0','0',"11","00"),  --jalr=9
-    (MOVZ, '0','0',opMOVZ, "001",'0','1','0',"00","00"),  --movz=10
-    (MOVN, '0','0',opMOVN, "001",'0','1','0',"00","00"),  --movn=11
-    (SYSCALL,'1','0',trNOP,"001",'1','0','0',"00","00"),  --syscall=12
-    (BREAK,'1','0',trNOP,  "001",'1','0','0',"00","00"),  --break=13
-    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --14
-    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --15
-    (MFHI, '0','0',opMFHI, "100",'0','0','0',"00","00"),  --mfhi=16
-    (MTHI, '1','0',opMTHI, "001",'0','0','0',"00","00"),  --mthi=17
-    (MFLO, '0','0',opMFLO, "101",'0','0','0',"00","00"),  --mflo=18
-    (MTLO, '1','0',opMTLO, "001",'0','0','0',"00","00"),  --mtlo=19
-    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --20
-    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --21
-    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --22
-    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --23
-    (MULT, '1','0',opMULT, "001",'0','0','0',"00","00"),  --mult=24
-    (MULTU,'1','0',opMULTU,"001",'0','0','0',"00","00"),  --multu=25
-    (DIV,  '1','0',opDIV,  "001",'0','0','0',"00","00"),  --div=26
-    (DIVU, '1','0',opDIVU, "001",'0','0','0',"00","00"),  --divu=27
-    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --28
-    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --29
-    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --30
-    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --31
-    (ADD,  '0','0',opADD,  "001",'0','0','0',"00","10"),  --add=32
-    (ADDU, '0','0',opADDU, "001",'0','0','0',"00","00"),  --addu=33
-    (SUB,  '0','0',opSUB,  "001",'0','0','0',"00","10"),  --sub=34
-    (SUBU, '0','0',opSUBU, "001",'0','0','0',"00","00"),  --subu=35
-    (iAND, '0','0',opAND,  "001",'0','0','0',"00","00"),  --and=36
-    (iOR,  '0','0',opOR,   "001",'0','0','0',"00","00"),  --or=37
-    (iXOR, '0','0',opXOR,  "001",'0','0','0',"00","00"),  --xor=38
-    (iNOR, '0','0',opNOR,  "001",'0','0','0',"00","00"),  --nor=39
-    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --40
-    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --41
-    (SLT,  '0','0',opSLT,  "001",'0','0','0',"00","10"),  --slt=42
-    (SLTU, '0','0',opSLTU, "001",'0','0','0',"00","00"),  --sltu=43
-    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --44
-    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --45
-    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --46
-    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --47
-    (TGE,  '1','0',trGEQ,  "001",'1','0','0',"00","01"),  --tge=48
-    (TGEU, '1','0',trGEU,  "001",'1','0','0',"00","01"),  --tgeu=49
-    (TLT,  '1','0',trLTH,  "001",'1','0','0',"00","01"),  --tlt=50
-    (TLTU, '1','0',trLTU,  "001",'1','0','0',"00","01"),  --tltu=51
-    (TEQ,  '1','0',trEQU,  "001",'1','0','0',"00","01"),  --teq=52
-    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --53
-    (TNE,  '1','0',trNEQ,  "001",'1','0','0',"00","01"),  --tne=54
-    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --55
-    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --56
-    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --57
-    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --58
-    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --59
-    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --60
-    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --61
-    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --62
-    (NOP,  '1','0',opNOP,  "001",'0','0','0',"00","00")   --63
-    );
-
-  -- fields of the register-immediate control table (opcode=1)
-  --   i:     instr_type;       -- instruction
-  --   wreg:  std_logic;        -- register write=0
-  --   selB:  std_logic;        -- B ALU input, reg=0 ext=1
-  --   br_t:  t_comparison;     -- comparison type: ltz,gez
-  --   muxC:  reg3;             -- select result mem=0 ula=1 jr=2 *al(pc+8)=3
-  --   c_sel: reg2              -- select destination reg rd=0 rt=1 31=2
-  --   trap:  std_logic;        -- trap on compare
-  --   PCsel: reg2;             -- PCmux 0=PC+4 1=beq 2=j 3=jr
-  --   excp:  reg2              -- stage with exception 0=no,1=rf,2=ex,3=mm
-  
-  constant rimm_table : t_rimm_mem := (
-  -- i    wreg selB br_t muxC  csel trap PCsel excp
-    (BLTZ, '1','0',cLTZ, "001","00",'0',"01","00"),  --0bltz
-    (BGEZ, '1','0',cGEZ, "001","00",'0',"01","00"),  --1bgez
-    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --2
-    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --3
-    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --4
-    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --5
-    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --6
-    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --7
-    (TGEI, '1','1',tGEQ, "001","00",'1',"00","10"),  --8tgei
-    (TGEIU,'1','1',tGEU, "001","00",'1',"00","10"),  --9tgeiu
-    (TLTI, '1','1',tLTH, "001","00",'1',"00","10"),  --10tlti
-    (TLTIU,'1','1',tLTU, "001","00",'1',"00","10"),  --11tltiu
-    (TEQI, '1','1',tEQU, "001","00",'1',"00","10"),  --12teqi
-    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --13
-    (TNEI, '1','1',tNEQ, "001","00",'1',"00","10"),  --14tnei
-    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --15
-    (BLTZAL,'0','0',cLTZ,"011","10",'0',"01","00"),  --16bltzal
-    (BGEZAL,'0','0',cGEZ,"011","10",'0',"01","00"),  --17bgezal
-    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --18
-    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --19
-    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --20
-    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --21
-    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --22
-    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --23
-    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --24
-    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --25
-    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --26
-    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --27
-    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --28
-    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --29
-    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --30
-    (NOP,  '1','0',cNOP, "001","00",'0',"00","00")   --31
-    );
-
-  -- Table 8-30 Config Register Field Descriptions, pg 101
-  constant CONFIG0 : reg32 := (
-    '1'&        -- M, Config1 implemented = 1
-    b"000"&     -- K23, with MMU, kseg2,kseg3 coherency algorithm
-    b"000"&     -- KU, with MMU, kuseg coherency algorithm
-    b"000000000"& -- Impl, implementation dependent = 0
-    '0'&        -- BE, little endian = 0
-    b"00"&      -- AT, MIPS32 = 0
-    b"001"&     -- AR, Release 2 = 1
-    b"000"&     -- MT, MMU type = 0, none
-    b"000"&     -- nil, always zero = 0
-    '1'&        -- VI, Instruction Cache is virtual = 1
-    b"000"      -- K0, Kseg0 coherency algorithm
-    );
-
-  -- Table 8-31 Config1 Register Field Descriptions, pg 103
-  constant CONFIG1 : reg32 := (
-    '0'&               -- M, Config2 implemented = 0
-    b"000000"&         -- MMUsz, MMU entries minus 1
-    IC_SETS_PER_WAY  & -- ICS, IC sets per way
-    IC_LINE_SIZE     & -- ICL, IC line size
-    IC_ASSOCIATIVITY & -- ICA, IC associativity
-    DC_SETS_PER_WAY  & -- DCS, DC sets per way
-    DC_LINE_SIZE     & -- DCL, DC line size = 3 16 bytes/line
-    DC_ASSOCIATIVITY & -- DCA, DC associativity = 0 direct mapped
-    '0'&        -- C2, No coprocessor 2 implemented = 0
-    '0'&        -- MD, No MDMX ASE implemented = 0
-    '0'&        -- PC, No performance counters implemented = 0
-    '0'&        -- WR, No watch registers implemented = 0
-    '0'&        -- CA, No code compression implemented = 0
-    '0'&        -- EP, No EJTAG implemented = 0
-    '0'         -- FP, No FPU implemented = 0
-    );
-
-   
   -- control pipeline registers ------------ 
   component reg_excp_IF_RF is
     port(clk, rst, ld: in  std_logic;
@@ -402,6 +157,30 @@ architecture rtl of core is
   signal BadVAddr, BadVAddr_inp : reg32;
   signal BadVAddr_update, BadVAddr_source : std_logic;
 
+  -- MMU signals --
+  signal INDEX, index_inp, RANDOM, WIRED, wired_inp : reg32;
+  signal index_update, wired_update : std_logic;
+  signal EntryLo0, EntryLo1, EntryLo0_inp, EntryLo1_inp : reg32;
+  signal EntryHi, EntryHi_inp : reg32;
+  signal Context, PageMask, Context_inp, PageMask_inp : reg32;
+  signal entryLo0_update, entryLo1_update, entryHi_update : std_logic;
+  signal context_update, tlb_read : std_logic;
+  signal tlb_entrylo0_mm,tlb_entrylo1_mm,tlb_context_mm,tlb_entryhi : reg32;
+  signal tlb_tag0_updt, tlb_tag1_updt, tlb_tag2_updt, tlb_tag3_updt : std_logic;
+  signal tlb_dat0_updt, tlb_dat1_updt, tlb_dat2_updt, tlb_dat3_updt : std_logic;
+  signal hit_pc, hit0_pc, hit1_pc, hit2_pc, hit3_pc : std_logic;
+  signal tlb_a0_pc, tlb_a1_pc, tlb_a2_pc : std_logic;
+  signal hit_mm, hit0_mm, hit1_mm, hit2_mm, hit3_mm : std_logic;
+  signal tlb_a0_mm, tlb_a1_mm, tlb_a2_mm : std_logic;
+  signal tlb_adr_pc, tlb_adr_mm, probe_adr : MMU_idx_bits;
+  signal tlb_probe, probe_hit : std_logic;
+  signal mm : std_logic_vector(VA_HI_BIT downto VA_LO_BIT);
+  signal tlb_adr : natural range 0 to (MMU_CAPACITY - 1);
+  signal tlb_ppn : std_logic_vector(PPN_BITS - 1 downto 0);
+  
+  signal tlb_tag_inp, tlb_tag0, tlb_tag1, tlb_tag2, tlb_tag3 : reg32;
+  signal tlb_dat_inp, tlb_dat0, tlb_dat1, tlb_dat2, tlb_dat3 : reg28;
+  signal tlb_entryLo0, tlb_entryLo1, phy_i_addr : reg32;
   
   -- other components ------------ 
   
@@ -446,6 +225,13 @@ architecture rtl of core is
          Q:            out std_logic_vector);
   end component register32;
 
+  component register28 is
+    generic (INITIAL_VALUE: std_logic_vector);
+    port(clk, rst, ld: in  std_logic;
+         D:            in  std_logic_vector;
+         Q:            out std_logic_vector);
+  end component register28;
+
   component counter32 is
     generic (INITIAL_VALUE: std_logic_vector);
     port(clk, rst, ld, en: in  std_logic;
@@ -478,7 +264,7 @@ architecture rtl of core is
   signal br_target, br_addend, br_tgt_pl4, br_tgt_displ, j_target : reg32;
   signal RF_PCincd, RF_instruction : reg32;
   signal eq_fwd_A,eq_fwd_B : reg32;
-
+  
   -- register fetch/read and instruction decode --  
   component reg_IF_RF is
     port(clk, rst, ld: in  std_logic;
@@ -499,7 +285,6 @@ architecture rtl of core is
   signal br_equal,br_negative,br_eq_zero: boolean;
   signal flush_RF_EX: boolean := FALSE;
   signal is_branch: std_logic;
-  -- attribute BUFFERED of is_branch : signal is "HIGH_DRIVE";
   signal c_sel : reg2;
   
   -- execution and beyond --  
@@ -513,8 +298,6 @@ architecture rtl of core is
   signal wrmem,EX_wrmem,EX_wrmem_cond,MM_wrmem, m_sign_ext: std_logic;
   signal mem_t, EX_mem_t,MM_mem_t: reg4;
   signal WB_mem_t : reg2;
-  -- attribute CLOCK_SIGNAL of MM_wrmem : signal is "no";
-  -- attribute BUFFERED     of MM_wrmem : signal is "HIGH_DRIVE";
 
   signal alu_inp_A,alu_fwd_B,alu_inp_B : reg32;
   signal alu_move_ok, MM_alu_move_ok, ovfl,MM_ovfl : std_logic;
@@ -532,8 +315,6 @@ architecture rtl of core is
   signal rd_data_raw, rd_data, WB_rd_data, WB_mem_data: reg32;
   signal MM_B_data, WB_B_data: reg32;
   signal jr_stall, br_stall, fwd_lwlr, sw_stall : std_logic;
-  -- attribute CLOCK_SIGNAL of rom_stall,ram_stall : signal is "no";
-  -- attribute BUFFERED     of rom_stall,ram_stall : signal is "HIGH_DRIVE";
   signal fwd_mem, WB_addr2: reg2;
 
 
@@ -611,34 +392,280 @@ architecture rtl of core is
          MM_pc_p8:   out std_logic_vector);
   end component reg_EX_MM;
   
-  component reg_MM_WB is
-    port(clk, rst, ld: in  std_logic;
-         MM_a_c:     in  std_logic_vector;
-         WB_a_c:     out std_logic_vector;
-         MM_wreg:    in  std_logic;
-         WB_wreg:    out std_logic;
-         MM_muxC:    in  std_logic_vector;
-         WB_muxC:    out std_logic_vector;
-         MM_A:       in  std_logic_vector;
-         WB_A:       out std_logic_vector;
-         MM_result:  in  std_logic_vector;
-         WB_result:  out std_logic_vector;
-         MM_HI:      in  std_logic_vector;
-         WB_HI:      out std_logic_vector;
-         MM_LO:      in  std_logic_vector;
-         WB_LO:      out std_logic_vector;
-         rd_data:    in  std_logic_vector;
-         WB_rd_data: out std_logic_vector;
-         MM_B_data:  in  std_logic_vector;
-         WB_B_data:  out std_logic_vector;
-         MM_addr2:   in  std_logic_vector;
-         WB_addr2:   out std_logic_vector;
-         MM_oper:    in  std_logic_vector;
-         WB_oper:    out std_logic_vector;
-         MM_pc_p8:   in  std_logic_vector;
-         WB_pc_p8:   out std_logic_vector);
-  end component reg_MM_WB;
+  component reg_MM_WB is
+    port(clk, rst, ld: in  std_logic;
+         MM_a_c:     in  std_logic_vector;
+         WB_a_c:     out std_logic_vector;
+         MM_wreg:    in  std_logic;
+         WB_wreg:    out std_logic;
+         MM_muxC:    in  std_logic_vector;
+         WB_muxC:    out std_logic_vector;
+         MM_A:       in  std_logic_vector;
+         WB_A:       out std_logic_vector;
+         MM_result:  in  std_logic_vector;
+         WB_result:  out std_logic_vector;
+         MM_HI:      in  std_logic_vector;
+         WB_HI:      out std_logic_vector;
+         MM_LO:      in  std_logic_vector;
+         WB_LO:      out std_logic_vector;
+         rd_data:    in  std_logic_vector;
+         WB_rd_data: out std_logic_vector;
+         MM_B_data:  in  std_logic_vector;
+         WB_B_data:  out std_logic_vector;
+         MM_addr2:   in  std_logic_vector;
+         WB_addr2:   out std_logic_vector;
+         MM_oper:    in  std_logic_vector;
+         WB_oper:    out std_logic_vector;
+         MM_pc_p8:   in  std_logic_vector;
+         WB_pc_p8:   out std_logic_vector);
+  end component reg_MM_WB;
+
+
+-- fields of the control table
+--    aVal:  std_logic;        -- addressValid, enable data-mem=0
+--    wmem:  std_logic;        -- READ=1/WRITE=0 in/to memory
+--    i:     instr_type;       -- instruction
+--    wreg:  std_logic;        -- register write=0
+--    selB:  std_logic;        -- B ALU input, reg=0 ext=1
+--    fun:   std_logic;        -- check function_field=1
+--    oper:  t_alu_fun;        -- ALU operation
+--    muxC:  reg3;             -- select result mem=0 ula=1 jr=2 pc+8=3
+--    c_sel: reg2;             -- select destination reg RD=0 RT=1 31=2
+--    extS:  std_logic;        -- sign-extend=1, zero-ext=0
+--    PCsel: reg2;             -- PCmux 0=PC+4 1=beq 2=j 3=jr
+--    br_t:  t_comparison;     -- branch: 0=no 1=beq 2=bne
+--    excp:  reg2              -- stage with exception 0=no,1=rf,2=ex,3=mm
+  
+  constant ctrl_table : t_control_mem := (
+  --aVal wmem ins wreg selB fun oper muxC  csel extS PCsel br_t excp
+    ('1','1',iALU, '1','0','1',opNOP,"001","00", '0', "00",cNOP,"00"),--ALU=0
+    ('1','1',RIMM, '1','0','0',opNOP,"001","00", '1', "00",cOTH,"00"),--BR=1
+    ('1','1',J,    '1','0','0',opNOP,"001","00", '0', "10",cNOP,"00"),--j=2
+    ('1','1',JAL,  '0','0','0',opNOP,"011","10", '0', "10",cNOP,"00"),--jal=3
+    ('1','1',BEQ,  '1','0','0',opNOP,"001","00", '1', "01",cEQU,"00"),--beq=4
+    ('1','1',BNE,  '1','0','0',opNOP,"001","00", '1', "01",cNEQ,"00"),--bne=5
+    ('1','1',BLEZ, '1','0','0',opNOP,"001","00", '1', "01",cLEZ,"00"),--blez=6
+    ('1','1',BGTZ, '1','0','0',opNOP,"001","00", '1', "01",cGTZ,"00"),--bgtz=7
+    ('1','1',ADDI, '0','1','0',opADD,"001","01", '1', "00",cNOP,"10"),--addi=8
+    ('1','1',ADDIU,'0','1','0',opADD,"001","01", '1', "00",cNOP,"00"),--addiu=9
+    ('1','1',SLTI, '0','1','0',opSLT,"001","01", '1', "00",cNOP,"10"),--slti=10
+    ('1','1',SLTIU,'0','1','0',opSLTU,"001","01",'1', "00",cNOP,"00"),--sltiu11
+    ('1','1',ANDI, '0','1','0',opAND,"001","01", '0', "00",cNOP,"00"),--andi=12
+    ('1','1',ORI,  '0','1','0',opOR, "001","01", '0', "00",cNOP,"00"),--ori=13
+    ('1','1',XORI, '0','1','0',opXOR,"001","01", '0', "00",cNOP,"00"),--xori=14
+    ('1','1',LUI,  '0','1','0',opLUI,"001","01", '0', "00",cNOP,"00"),--lui=15
+    ('1','1',COP0, '1','0','1',opNOP,"110","01", '0', "00",cNOP,"00"),--COP0=16
+    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--17
+    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--18
+    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--19
+    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--beql=20
+    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--bnel=21
+    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--blzel=22
+    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--bgtzl=23
+    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--24
+    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--25
+    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--26
+    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--27
+    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--28
+    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--29
+    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--30
+    ('1','1',SPEC3,'0','0','0',opSPC,"001","00", '0', "00",cNOP,"00"),--special3
+    ('0','1',LB,   '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--lb=32
+    ('0','1',LH,   '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--lh=33
+    ('0','1',LWL,  '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--lwl=34
+    ('0','1',LW,   '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--lw=35
+    ('0','1',LBU,  '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--lbu=36
+    ('0','1',LHU,  '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--lhu=37
+    ('0','1',LWR,  '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--lwr=38
+    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--39
+    ('0','0',SB,   '1','1','0',opADD,"001","00", '1', "00",cNOP,"00"),--sb=40
+    ('0','0',SH,   '1','1','0',opADD,"001","00", '1', "00",cNOP,"00"),--sh=41
+    ('1','1',NIL,  '1','1','0',opNOP,"001","00", '0', "00",cNOP,"00"),--swl=42
+    ('0','0',SW,   '1','1','0',opADD,"001","00", '1', "00",cNOP,"00"),--sw=43
+    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--44
+    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--45
+    ('1','1',NIL,  '1','1','0',opNOP,"001","00", '0', "00",cNOP,"00"),--swr=46
+    ('1','1',NIL,  '1','1','0',opNOP,"001","00", '0', "00",cNOP,"00"),--cache=47
+    ('0','1',LL,   '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--ll=48
+    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--lwc1=49
+    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--lwc2=50
+    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--pref=51
+    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--52
+    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--ldc1=53
+    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--ldc2=54
+    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--55
+    ('0','0',SC,   '0','1','0',opADD,"111","01", '1', "00",cNOP,"00"),--sc=56
+    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--swc1=57
+    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--swc2=58
+    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--59
+    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--60
+    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--sdc1=61
+    ('1','1',NIL,  '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--sdc2=62
+    ('1','1',NOP,  '1','0','0',opNOP,"000","00", '0', "00",cNOP,"00") --63
+    );
+
+-- fields of the function table (opcode=0)
+--    i:     instr_type;       -- instruction
+--    wreg:  std_logic;        -- register write=0
+--    selB:  std_logic;        -- B ALU input, reg=0 ext=1
+--    oper:  t_alu_fun;        -- ALU operation
+--    muxC:  reg3;             -- select result mem=0 ula=1 jr=2 pc+8=3
+--    trap:  std_logic;        -- trap on compare
+--    move:  std_logic;        -- conditional move
+--    sync:  std_logic;        -- synch the memory hierarchy
+--    PCsel: reg2;             -- PCmux 0=PC+4 1=beq 2=j 3=jr
+--    excp:  reg2              -- stage with exception 0=no,1=rf,2=ex,3=mm
+  
+  constant func_table : t_function_mem := (
+  -- i    wreg selB oper   muxC trap mov syn PCsel excp
+    (iSLL, '0','0',opSLL,  "001",'1','0','0',"00","00"),  --sll=0, EHB
+    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --1, FlPoint
+    (iSRL, '0','0',opSRL,  "001",'0','0','0',"00","00"),  --srl=2
+    (iSRA, '0','0',opSRA,  "001",'0','0','0',"00","00"),  --sra=3
+    (SLLV, '0','0',opSLLV, "001",'0','0','0',"00","00"),  --sllv=4
+    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --5
+    (SRLV, '0','0',opSRLV, "001",'0','0','0',"00","00"),  --srlv=6
+    (SRAV, '0','0',opSRAV, "001",'0','0','0',"00","00"),  --srav=7
+    (JR,   '1','0',opNOP,  "001",'0','0','0',"11","00"),  --jr=8
+    (JALR, '0','0',opNOP,  "011",'0','0','0',"11","00"),  --jalr=9
+    (MOVZ, '0','0',opMOVZ, "001",'0','1','0',"00","00"),  --movz=10
+    (MOVN, '0','0',opMOVN, "001",'0','1','0',"00","00"),  --movn=11
+    (SYSCALL,'1','0',trNOP,"001",'1','0','0',"00","00"),  --syscall=12
+    (BREAK,'1','0',trNOP,  "001",'1','0','0',"00","00"),  --break=13
+    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --14
+    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --15
+    (MFHI, '0','0',opMFHI, "100",'0','0','0',"00","00"),  --mfhi=16
+    (MTHI, '1','0',opMTHI, "001",'0','0','0',"00","00"),  --mthi=17
+    (MFLO, '0','0',opMFLO, "101",'0','0','0',"00","00"),  --mflo=18
+    (MTLO, '1','0',opMTLO, "001",'0','0','0',"00","00"),  --mtlo=19
+    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --20
+    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --21
+    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --22
+    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --23
+    (MULT, '1','0',opMULT, "001",'0','0','0',"00","00"),  --mult=24
+    (MULTU,'1','0',opMULTU,"001",'0','0','0',"00","00"),  --multu=25
+    (DIV,  '1','0',opDIV,  "001",'0','0','0',"00","00"),  --div=26
+    (DIVU, '1','0',opDIVU, "001",'0','0','0',"00","00"),  --divu=27
+    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --28
+    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --29
+    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --30
+    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --31
+    (ADD,  '0','0',opADD,  "001",'0','0','0',"00","10"),  --add=32
+    (ADDU, '0','0',opADDU, "001",'0','0','0',"00","00"),  --addu=33
+    (SUB,  '0','0',opSUB,  "001",'0','0','0',"00","10"),  --sub=34
+    (SUBU, '0','0',opSUBU, "001",'0','0','0',"00","00"),  --subu=35
+    (iAND, '0','0',opAND,  "001",'0','0','0',"00","00"),  --and=36
+    (iOR,  '0','0',opOR,   "001",'0','0','0',"00","00"),  --or=37
+    (iXOR, '0','0',opXOR,  "001",'0','0','0',"00","00"),  --xor=38
+    (iNOR, '0','0',opNOR,  "001",'0','0','0',"00","00"),  --nor=39
+    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --40
+    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --41
+    (SLT,  '0','0',opSLT,  "001",'0','0','0',"00","10"),  --slt=42
+    (SLTU, '0','0',opSLTU, "001",'0','0','0',"00","00"),  --sltu=43
+    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --44
+    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --45
+    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --46
+    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --47
+    (TGE,  '1','0',trGEQ,  "001",'1','0','0',"00","01"),  --tge=48
+    (TGEU, '1','0',trGEU,  "001",'1','0','0',"00","01"),  --tgeu=49
+    (TLT,  '1','0',trLTH,  "001",'1','0','0',"00","01"),  --tlt=50
+    (TLTU, '1','0',trLTU,  "001",'1','0','0',"00","01"),  --tltu=51
+    (TEQ,  '1','0',trEQU,  "001",'1','0','0',"00","01"),  --teq=52
+    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --53
+    (TNE,  '1','0',trNEQ,  "001",'1','0','0',"00","01"),  --tne=54
+    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --55
+    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --56
+    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --57
+    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --58
+    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --59
+    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --60
+    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --61
+    (NIL,  '1','0',opNOP,  "001",'0','0','0',"00","00"),  --62
+    (NOP,  '1','0',opNOP,  "001",'0','0','0',"00","00")   --63
+    );
+
+  -- fields of the register-immediate control table (opcode=1)
+  --   i:     instr_type;       -- instruction
+  --   wreg:  std_logic;        -- register write=0
+  --   selB:  std_logic;        -- B ALU input, reg=0 ext=1
+  --   br_t:  t_comparison;     -- comparison type: ltz,gez
+  --   muxC:  reg3;             -- select result mem=0 ula=1 jr=2 *al(pc+8)=3
+  --   c_sel: reg2              -- select destination reg rd=0 rt=1 31=2
+  --   trap:  std_logic;        -- trap on compare
+  --   PCsel: reg2;             -- PCmux 0=PC+4 1=beq 2=j 3=jr
+  --   excp:  reg2              -- stage with exception 0=no,1=rf,2=ex,3=mm
+  
+  constant rimm_table : t_rimm_mem := (
+  -- i    wreg selB br_t muxC  csel trap PCsel excp
+    (BLTZ, '1','0',cLTZ, "001","00",'0',"01","00"),  --0bltz
+    (BGEZ, '1','0',cGEZ, "001","00",'0',"01","00"),  --1bgez
+    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --2
+    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --3
+    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --4
+    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --5
+    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --6
+    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --7
+    (TGEI, '1','1',tGEQ, "001","00",'1',"00","10"),  --8tgei
+    (TGEIU,'1','1',tGEU, "001","00",'1',"00","10"),  --9tgeiu
+    (TLTI, '1','1',tLTH, "001","00",'1',"00","10"),  --10tlti
+    (TLTIU,'1','1',tLTU, "001","00",'1',"00","10"),  --11tltiu
+    (TEQI, '1','1',tEQU, "001","00",'1',"00","10"),  --12teqi
+    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --13
+    (TNEI, '1','1',tNEQ, "001","00",'1',"00","10"),  --14tnei
+    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --15
+    (BLTZAL,'0','0',cLTZ,"011","10",'0',"01","00"),  --16bltzal
+    (BGEZAL,'0','0',cGEZ,"011","10",'0',"01","00"),  --17bgezal
+    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --18
+    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --19
+    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --20
+    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --21
+    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --22
+    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --23
+    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --24
+    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --25
+    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --26
+    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --27
+    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --28
+    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --29
+    (NIL,  '1','0',cNOP, "001","00",'0',"00","00"),  --30
+    (NOP,  '1','0',cNOP, "001","00",'0',"00","00")   --31
+    );
+
+  -- Table 8-30 Config Register Field Descriptions, pg 101
+  constant CONFIG0 : reg32 := (
+    '1'&        -- M, Config1 implemented = 1
+    b"000"&     -- K23, with MMU, kseg2,kseg3 coherency algorithm
+    b"000"&     -- KU, with MMU, kuseg coherency algorithm
+    b"000000000"& -- Impl, implementation dependent = 0
+    '0'&        -- BE, little endian = 0
+    b"00"&      -- AT, MIPS32 = 0
+    b"001"&     -- AR, Release 2 = 1
+    b"001"&     -- MT, MMU type = 1, standard
+    b"000"&     -- nil, always zero = 0
+    '1'&        -- VI, Instruction Cache is virtual = 1
+    b"000"      -- K0, Kseg0 coherency algorithm
+    );
+
+  -- Table 8-31 Config1 Register Field Descriptions, pg 103
+  constant CONFIG1 : reg32 := (
+    '0'&               -- M, Config2 not implemented = 0
+    MMU_SIZE         & -- MMUsz, MMU entries minus 1
+    IC_SETS_PER_WAY  & -- ICS, IC sets per way
+    IC_LINE_SIZE     & -- ICL, IC line size
+    IC_ASSOCIATIVITY & -- ICA, IC associativity
+    DC_SETS_PER_WAY  & -- DCS, DC sets per way
+    DC_LINE_SIZE     & -- DCL, DC line size = 3 16 bytes/line
+    DC_ASSOCIATIVITY & -- DCA, DC associativity = 0 direct mapped
+    '0'&        -- C2, No coprocessor 2 implemented = 0
+    '0'&        -- MD, No MDMX ASE implemented = 0
+    '0'&        -- PC, No performance counters implemented = 0
+    '0'&        -- WR, No watch registers implemented = 0
+    '0'&        -- CA, No code compression implemented = 0
+    '0'&        -- EP, No EJTAG implemented = 0
+    '0'         -- FP, No FPU implemented = 0
+    );
 
+  
 -- pipeline ============================================================
 begin
 
@@ -1002,6 +1029,10 @@ begin
           case funct_word.i is
             when SYSCALL => i_exception := exSYSCALL;
             when BREAK   => i_exception := exBREAK;
+            when iSLL    =>
+              if RF_instruction = x"000000c0" then 
+                i_exception := exEHB;
+              end if; 
             when others  => i_exception := exTRAP;
           end case;
         end if;
@@ -1030,18 +1061,23 @@ begin
             i_wreg     := '0';
           when b"10000" =>              -- ERET
             case func is
+              when b"000001" => i_exception := exTLBR;
+              when b"000010" => i_exception := exTLBWI;
+              when b"000110" => i_exception := exTLBWR;
+              when b"001000" => i_exception := exTLBP;
               when b"011000" => i_exception := exERET;
+              when b"011111" => i_exception := exDERET;
               when b"100000" => i_exception := exWAIT;
               when others =>    i_exception := exRESV_INSTR;
             end case;
           when b"01011" =>              -- EI and DI
             case func is
               when b"100000" =>    -- EI;
-              i_exception := exEI;
-              i_wreg := '0';
+                i_exception := exEI;
+                i_wreg := '0';
               when b"000000" =>    -- DI;
-              i_exception := exDI;
-              i_wreg := '0';
+                i_exception := exDI;
+                i_wreg := '0';
               when others => i_exception := exRESV_INSTR;
             end case;
           when others => i_exception := exRESV_INSTR;
@@ -1530,7 +1566,7 @@ begin
     end if;
   end process RF_FORWARDING_TRAPS;
 
-  
+
   -- ----------------------------------------------------------------------    
   PIPESTAGE_EXCP_RF_EX: reg_excp_RF_EX
     port map (clk, rst, excp_RF_EX_ld, can_trap,EX_can_trap,
@@ -1586,6 +1622,12 @@ begin
     BadVAddr_source <= '0';
     BadVAddr_update <= '1';
 
+    newSTATUS(STATUS_BEV) := '0';  -- interrupts at offset 0x200
+    newSTATUS(STATUS_CU3) := '0';  -- COP-3 absent (always)
+    newSTATUS(STATUS_CU2) := '0';  -- COP-2 absent (always)
+    newSTATUS(STATUS_CU1) := '0';  -- COP-1 absent (always)
+    newSTATUS(STATUS_CU0) := '1';  -- COP-0 present=1 (always)
+    
     case is_exception is
 
       when exMTC0 =>            -- move to COP-0
@@ -1595,13 +1637,17 @@ begin
             newSTATUS := cop0_inp;
             i_update   := '1';
             i_stall    := '1';
-          when cop0reg_COUNT | cop0reg_COMPARE | cop0reg_CAUSE =>
+          when cop0reg_COUNT    | cop0reg_COMPARE  | cop0reg_CAUSE   |
+               cop0reg_EntryLo0 | cop0reg_EntryLo1 | cop0reg_EntryHi =>
             i_update   := '1';
             i_stall    := '1';
+          when cop0reg_Index  | cop0reg_Context | cop0reg_Wired =>
+            i_update   := '1';
+            i_stall    := '0';
           when cop0reg_EPC =>
             i_epc_update := '0';
             i_epc_source := b"100";     -- EX_B
-            i_stall      := '1';
+            i_stall      := '0';
           when others =>
             i_stall  := '0';
             i_update := '0';
@@ -1625,6 +1671,14 @@ begin
 
       when exMFC0 =>            -- move from COP-0
         case EX_cop0_reg is
+          when cop0reg_Index    => i_COP0_rd := INDEX;
+          when cop0reg_Random   => i_COP0_rd := RANDOM;
+          when cop0reg_EntryLo0 => i_COP0_rd := EntryLo0;
+          when cop0reg_EntryLo1 => i_COP0_rd := EntryLo1;
+          when cop0reg_Context  => i_COP0_rd := CONTEXT;
+          when cop0reg_PageMask => i_COP0_rd := PAGEMASK;
+          when cop0reg_Wired    => i_COP0_rd := WIRED;
+          when cop0reg_EntryHi  => i_COP0_rd := EntryHi;
           when cop0reg_COUNT    => i_COP0_rd := COUNT;
           when cop0reg_COMPARE  => i_COP0_rd := COMPARE;
           when cop0reg_STATUS   => i_COP0_rd := STATUS;
@@ -1640,17 +1694,17 @@ begin
           when others           => i_COP0_rd := (others => 'X');
         end case;
         i_a_c   := EX_a_rt;
-        i_stall := '1';
+        i_stall := '0';
 
       when exERET =>            -- exception return
         i_update     := '1';
         i_update_r   := cop0reg_STATUS;
-        i_stall      := '0';
-        i_excp_PCsel := PCsel_EXC_EPC;   -- PC <= EPC
-        i_nullify    := '1';             -- nullify instructions in IF,RF
-
+        i_stall      := '0';            -- do not stall
+        i_excp_PCsel := PCsel_EXC_EPC;  -- PC <= EPC
+        i_nullify    := '1';            -- nullify instructions in IF,RF
+        newSTATUS(STATUS_EXL) := '0';   -- leave exception level
+        
       when exTRAP | exSYSCALL | exBREAK =>   -- trap instruction
-        ExcCode <= cop0code_Tr;
         i_stall    := '0';
         case EX_trap_instr is
           when TEQ | TEQI =>
@@ -1663,15 +1717,20 @@ begin
             i_take_trap := not(EX_tr_less_than);
           when SYSCALL =>
             i_take_trap := '1';
-            ExcCode     <= cop0code_Sys;
           when BREAK =>
             i_take_trap := '1';
-            ExcCode     <= cop0code_Bp;
           when others =>
             i_take_trap := '0';
         end case;
         if  i_take_trap = '1' then
           trap_taken <= '1';
+          case EX_trap_instr is
+            when TEQ | TEQI | TNE | TNEI | TLT | TLTI | TLTU | TLTIU |
+                 TGE | TGEI | TGEU | TGEIU =>  ExcCode <= cop0code_Tr;
+            when SYSCALL => ExcCode <= cop0code_Sys;
+            when BREAK   => ExcCode <= cop0code_Bp;
+            when others  => null;
+          end case;  
           newSTATUS(STATUS_EXL) := '1';   -- at exception level
           newSTATUS(STATUS_UM)  := '0';   -- enter kernel mode          
           newSTATUS(STATUS_IE)  := '0';   -- disable interrupts
@@ -1695,7 +1754,7 @@ begin
         i_update_r := cop0reg_LLaddr;
 
       -- when exSC => null; if treated here, SC might delay an interrupt
-        
+
 
       when exRESV_INSTR =>      -- reserved instruction ABORT SIMULATION
           assert true                   -- invalid opcode
@@ -1738,8 +1797,15 @@ begin
           i_epc_source    := b"011";    -- bad address is in EXCP_MM_PC
           badVAddr_source <= '1';       -- load/store
         end if;
+
+      when exEHB =>                     -- stall processor to clear hazards
+        i_stall    := '1';
+
+
+      when exTLBP | exTLBR | exTLBWI | exTLBWR =>  -- TLB access
+        i_stall := '1';                 -- stall the processor
+        
         
-          
       when others =>                    -- interrupt pending?
 
         if ( (EX_nmi = '1') and (STATUS(STATUS_ERL) = '0') ) then
@@ -1793,22 +1859,22 @@ begin
 
     end case;
 
-    newSTATUS(STATUS_CU3) := '0';  -- COP-3 absent (always)
-    newSTATUS(STATUS_CU2) := '0';  -- COP-2 absent (always)
-    newSTATUS(STATUS_CU1) := '0';  -- COP-1 absent (always)
-    newSTATUS(STATUS_CU0) := '1';  -- COP-0 present=1 (always)
-
-
     STATUSinp    <= newSTATUS;
     EX_cop0_val  <= i_COP0_rd;
     EX_cop0_a_c  <= i_a_c;              -- only for forwarding COP0 values
     update       <= i_update;
     update_reg   <= i_update_r;
-    epc_update   <= i_epc_update;
+
+    if is_exception = exMTC0 and EX_cop0_reg = cop0reg_EPC then
+      epc_update   <= i_epc_update;
+    else
+      epc_update   <= i_epc_update OR STATUS(STATUS_EXL);
+    end if;
     epc_source   <= i_epc_source;
     excp_PCsel   <= i_excp_PCsel;
+
     exception_stall <= i_stall;
-    nullify      <= i_nullify;
+    nullify         <= i_nullify;
     
   end process COP0_DECODE_EXCEPTION_AND_UPDATE_STATUS;
 
@@ -1850,38 +1916,43 @@ begin
           EX_is_delayslot, count_eq_compare,count_enable, CAUSE)
     variable newCAUSE : reg32;
   begin
-      newCAUSE(CAUSE_BD)     := EX_is_delayslot; -- instr is in delay slot
-      newCAUSE(CAUSE_TI)     := count_eq_compare;
-      newCAUSE(CAUSE_CE1)    := '0';
-      newCAUSE(CAUSE_CE0)    := '0';
-      newCAUSE(CAUSE_DC)     := CAUSE(CAUSE_DC);
-      newCAUSE(CAUSE_PCI)    := '0';
-      newCAUSE(25 downto 24) := b"00";
-      newCAUSE(CAUSE_IV)     := CAUSE(CAUSE_IV);
-      newCAUSE(CAUSE_WP)     := '0';
-      newCAUSE(21 downto 16) := b"000000";      
-      newCAUSE(CAUSE_IP7)    := EX_int_req(7);
-      newCAUSE(CAUSE_IP6)    := EX_int_req(6);
-      newCAUSE(CAUSE_IP5)    := EX_int_req(5);
-      newCAUSE(CAUSE_IP4)    := EX_int_req(4);
-      newCAUSE(CAUSE_IP3)    := EX_int_req(3);
-      newCAUSE(CAUSE_IP2)    := EX_int_req(2);
-      newCAUSE(CAUSE_IP1)    := CAUSE(CAUSE_IP1);
-      newCAUSE(CAUSE_IP0)    := CAUSE(CAUSE_IP0);
-      newCAUSE(7)            := '0';
-      newCAUSE(6 downto 2)   := ExcCode;
-      newCAUSE(1 downto 0)   := b"00";
-
-      if (update = '1' and update_reg = cop0reg_CAUSE) then
-        CAUSEinp <= newCAUSE(CAUSE_BD downto CAUSE_CE0) &
-                    cop0_inp(CAUSE_DC) & cop0_inp(CAUSE_PCI) & b"00" &
-                    cop0_inp(CAUSE_IV) & 
-                    newCAUSE(CAUSE_WP  downto CAUSE_IP2) &
-                    cop0_inp(CAUSE_IP1 downto CAUSE_IP0) & '0' &
-                    newCAUSE(6 downto 2) & b"00";
-      else
-        CAUSEinp <= newCAUSE;
-      end if;
+
+    if STATUS(STATUS_EXL) = '0' then
+      newCAUSE(CAUSE_BD)   := EX_is_delayslot;  -- instr is in delay slot
+    else
+      newCAUSE(CAUSE_BD)   := CAUSE(CAUSE_BD);
+    end if;
+    newCAUSE(CAUSE_TI)     := count_eq_compare;
+    newCAUSE(CAUSE_CE1)    := '0';
+    newCAUSE(CAUSE_CE0)    := '0';
+    newCAUSE(CAUSE_DC)     := CAUSE(CAUSE_DC);
+    newCAUSE(CAUSE_PCI)    := '0';
+    newCAUSE(25 downto 24) := b"00";
+    newCAUSE(CAUSE_IV)     := CAUSE(CAUSE_IV);
+    newCAUSE(CAUSE_WP)     := '0';
+    newCAUSE(21 downto 16) := b"000000";      
+    newCAUSE(CAUSE_IP7)    := EX_int_req(7);
+    newCAUSE(CAUSE_IP6)    := EX_int_req(6);
+    newCAUSE(CAUSE_IP5)    := EX_int_req(5);
+    newCAUSE(CAUSE_IP4)    := EX_int_req(4);
+    newCAUSE(CAUSE_IP3)    := EX_int_req(3);
+    newCAUSE(CAUSE_IP2)    := EX_int_req(2);
+    newCAUSE(CAUSE_IP1)    := CAUSE(CAUSE_IP1);
+    newCAUSE(CAUSE_IP0)    := CAUSE(CAUSE_IP0);
+    newCAUSE(7)            := '0';
+    newCAUSE(6 downto 2)   := ExcCode;
+    newCAUSE(1 downto 0)   := b"00";
+
+    if (update = '1' and update_reg = cop0reg_CAUSE) then
+      CAUSEinp <= newCAUSE(CAUSE_BD downto CAUSE_CE0) &
+                  cop0_inp(CAUSE_DC) & cop0_inp(CAUSE_PCI) & b"00" &
+                  cop0_inp(CAUSE_IV) & 
+                  newCAUSE(CAUSE_WP  downto CAUSE_IP2) &
+                  cop0_inp(CAUSE_IP1 downto CAUSE_IP0) & '0' &
+                  newCAUSE(6 downto 2) & b"00";
+    else
+      CAUSEinp <= newCAUSE;
+    end if;
   end process COP0_COMPUTE_CAUSE;
 
   COP0_CAUSE_HOLD: process(rst,clk,
@@ -1925,8 +1996,8 @@ begin
                     else '1';
   
   COP0_COUNT: counter32 generic map (x"00000001")
-    -- port map (clk, rst, count_update, count_enable, cop0_inp, COUNT);
-    port map (clk, rst, count_update, PCload, cop0_inp, COUNT); -- DEBUG
+    port map (clk, rst, count_update, count_enable, cop0_inp, COUNT);
+    -- port map (clk, rst, count_update, PCload, cop0_inp, COUNT); -- DEBUG
 
   compare_set <= (count_eq_compare or BOOL2SL(COUNT = COMPARE))
                  when compare_update = '1'
@@ -1949,7 +2020,7 @@ begin
   COP0_BadVAddr: register32 generic map(x"00000000")
     port map (clk, rst, BadVAddr_update, BadVAddr_inp, BadVAddr);
 
-  
+
   -- LLaddr & LLbit ------------------------------
   LL_update <= '0' when (update = '1' and update_reg = cop0reg_LLAddr)
                else '1';
@@ -1963,23 +2034,324 @@ begin
                  '0';
   
   COP0_LLbit: process(rst,phi2)
-    begin
-      if rst = '0' then
-        EX_LLbit    <= '0';             -- break SC -> LL
-      elsif rising_edge(phi2) then
-        case is_exception is
-          when exERET =>
-            EX_LLbit <= '0';            -- break SC -> LL
-          when exLL =>
-            EX_LLbit <= not LL_update;  -- update only if instr is a LL
-          when others =>
-            null; -- LL_SC_abort <= '0';
-        end case;
+  begin
+    if rst = '0' then
+      EX_LLbit    <= '0';             -- break SC -> LL
+    elsif rising_edge(phi2) then
+      case is_exception is
+        when exERET =>
+          EX_LLbit <= '0';            -- break SC -> LL
+        when exLL =>
+          EX_LLbit <= not LL_update;  -- update only if instr is a LL
+        when others =>
+          null;
+      end case;
+    end if;
+  end process COP0_LLbit;
+  
+  EX_excp_type <= exNOP;
+
+  
+  -- MMU-TLB ===========================================================
+
+  -- MMU Index -----------------------------------
+
+  index_update <= '0' when (update = '1' and update_reg = cop0reg_Index)
+                  else not(tlb_probe);
+  
+  index_inp <= not(hit_mm) & MMU_IDX_0s & tlb_adr_mm when tlb_probe = '1' else 
+               '0' & MMU_IDX_0s & cop0_inp(MMU_CAPACITY_BITS-1 downto 0);
+
+  MMU_Index: register32 generic map(x"00000000")
+    port map (clk, rst, index_update, index_inp, INDEX);
+
+
+  -- MMU Wired -----------------------------------
+
+  wired_update <= '0' when (update = '1' and update_reg = cop0reg_Wired)
+                  else '1';
+  
+  wired_inp <= '0' & MMU_IDX_0s & cop0_inp(MMU_CAPACITY_BITS-1 downto 0);
+
+  MMU_Wired: register32 generic map(MMU_WIRED_INIT)
+    port map (clk, rst, wired_update, wired_inp, WIRED);
+
+  -- MMU Random ----------------------------------
+
+  MMU_Random: process(clk, rst, WIRED, wired_update)
+    variable count : integer range -1 to MMU_CAPACITY-1;
+  begin
+    if rst = '0' or wired_update = '0' then
+      count := MMU_CAPACITY - 1 ;
+    elsif rising_edge(clk) then
+      count := count - 1;
+      if count = to_integer(unsigned(WIRED))-1 then
+        count := MMU_CAPACITY - 1;
       end if;
-    end process COP0_LLbit;
-    
-    EX_excp_type <= exNOP;
-    
+    end if;
+    RANDOM <= std_logic_vector(to_signed(count, 32));
+  end process MMU_Random;
+
+  -- MMU EntryLo0 -- pg 63 ----------------------
+
+  entryLo0_update <= '0' when (update = '1' and update_reg = cop0reg_EntryLo0)
+                  else not(tlb_read);
+  
+  entryLo0_inp <= cop0_inp when tlb_read = '0' else tlb_entryLo0;
+  
+  MMU_EntryLo0: register32 generic map(x"00000000")
+    port map (clk, rst, entryLo0_update, entryLo0_inp, EntryLo0);
+
+  -- MMU EntryLo1 -- pg 63 ----------------------  
+  
+  entryLo1_update <= '0' when (update = '1' and update_reg = cop0reg_EntryLo1)
+                  else not(tlb_read);
+  
+  entryLo1_inp <= cop0_inp when tlb_read = '0' else tlb_entryLo1;
+  
+  MMU_EntryLo1: register32 generic map(x"00000000")
+    port map (clk, rst, entryLo1_update, entryLo1_inp, EntryLo1);
+
+  -- MMU Context -- pg 67 ----------------------  
+  
+  context_update <= '0' when (update = '1' and update_reg = cop0reg_Context)
+                  else '1';
+  
+  context_inp <= cop0_inp when tlb_read = '0' else tlb_context_mm;
+  
+  MMU_Context: register32 generic map(x"00000000")
+    port map (clk, rst, context_update, context_inp, Context);
+
+  -- MMU Pagemask -----------------------------  
+  -- page size is fixed = 4k, thus PageMask is not register
+  
+  -- pageMask_update <= '0' when (update='1' and update_reg=cop0reg_PageMask)
+  --                else '1';
+  
+  -- pageMask_inp <= cop0_inp when tlb_read = '0' else tlb_pageMask_mm;
+  
+  -- MMU_PageMask: register32 generic map(x"00000000")
+  --  port map (clk, rst, pageMask_update, pageMask_inp, PageMask);
+
+  PageMask <= x"00001800";              -- pg 68
+
+  -- MMU EntryHi -- pg 76 ----------------------  
+  -- EntryHi holds the ASID of the current process, to check for a match
+  
+  entryHi_update <= '0' when (update = '1' and update_reg = cop0reg_EntryHi)
+                  else not(tlb_read);
+  
+  entryHi_inp <= cop0_inp when tlb_read = '0' else tlb_entryhi;
+  
+  MMU_EntryHi: register32 generic map(x"00000000")
+    port map (clk, rst, entryHi_update, entryHi_inp, EntryHi);
+
+  
+  -- MMU TLB DATA array ------------------------
+
+  -- TLB_tag: 31..10 = VPN, 9 = 0, 8 = G, 7..0 = ASID
+  -- TLB_dat: 27..6 = PPN, 5..3 = C, 2 = D, 1 = V, 0 = G
+  
+  MMU_CONTROL: process(rst, clk, EX_exception, hit_mm, tlb_adr_mm,
+                          INDEX, RANDOM, EntryHi, EntryLo0, -- EntryLo1,
+                          tlb_tag0, tlb_tag1, tlb_tag2, tlb_tag3)
+    variable e_hi : reg32;
+    variable e_lo : reg28;
+  begin
+
+    tlb_tag0_updt <= '1';
+    tlb_tag1_updt <= '1';
+    tlb_tag2_updt <= '1';
+    tlb_tag3_updt <= '1';
+    tlb_dat0_updt <= '1';
+    tlb_dat1_updt <= '1';
+    tlb_dat2_updt <= '1';
+    tlb_dat3_updt <= '1';
+    tlb_read      <= '0';
+    tlb_probe     <= '0';
+
+    case EX_exception is
+      when exTLBP =>
+        
+        tlb_probe <= '1';
+
+      when exTLBR => 
+
+        tlb_read <= '1';
+        tlb_adr  <= to_integer(unsigned(INDEX));
+ 
+        case tlb_adr is
+          when 0 => e_hi := tlb_tag0; e_lo := tlb_dat0;
+          when 1 => e_hi := tlb_tag1; e_lo := tlb_dat1;
+          when 2 => e_hi := tlb_tag2; e_lo := tlb_dat2;
+          when 3 => e_hi := tlb_tag3; e_lo := tlb_dat3;
+          when others => null;
+        end case;
+
+        -- assert false
+        -- report "e_hi="&SLV32HEX(e_hi)&" adr="&natural'image(tlb_adr);--DEBUG
+
+        tlb_entryLo0(31 downto ELO_AHI_BIT+1) <= (others => '0');
+        tlb_entryLo0(ELO_AHI_BIT downto ELO_ALO_BIT)
+          <= e_lo(DAT_AHI_BIT downto DAT_ALO_BIT);
+        tlb_entryLo0(ELO_CHI_BIT  downto ELO_CLO_BIT)
+          <= e_lo(DAT_CHI_BIT  downto DAT_CLO_BIT);
+        tlb_entryLo0(ELO_D_BIT) <= e_lo(DAT_D_BIT);
+        tlb_entryLo0(ELO_V_BIT) <= e_lo(DAT_V_BIT);
+        tlb_entryLo0(ELO_G_BIT) <= e_lo(DAT_G_BIT);
+
+        tlb_entryhi(EHI_AHI_BIT downto EHI_ALO_BIT)
+          <= e_hi(TAG_AHI_BIT downto TAG_ALO_BIT);
+        tlb_entryhi(EHI_ALO_BIT-1 downto EHI_ASIDHI_BIT+1) <= (others => '0');
+        tlb_entryhi(EHI_ASIDHI_BIT downto EHI_ASIDLO_BIT)
+          <= e_hi(TAG_ASIDHI_BIT downto TAG_ASIDLO_BIT);
+
+      when exTLBWI | exTLBWR => 
+
+        e_hi := EntryHi;
+        e_hi(TAG_G_BIT) := EntryLo0(ELO_G_BIT);
+        e_hi(TAG_Z_BIT) := '0';
+        tlb_tag_inp <= e_hi;
+
+        e_lo := EntryLo0(ELO_AHI_BIT downto ELO_G_BIT);
+        tlb_dat_inp <= e_lo;
+
+        
+        case EX_exception is
+          when exTLBWI => tlb_adr <= to_integer(unsigned(INDEX));
+          when exTLBWR => tlb_adr <= to_integer(unsigned(RANDOM));
+          when others => null;
+        end case;
+
+        case tlb_adr is
+          when 0 => tlb_tag0_updt <= '0'; tlb_dat0_updt <= '0';
+          when 1 => tlb_tag1_updt <= '0'; tlb_dat1_updt <= '0';
+          when 2 => tlb_tag2_updt <= '0'; tlb_dat2_updt <= '0';
+          when 3 => tlb_tag3_updt <= '0'; tlb_dat3_updt <= '0';
+          when others => null;
+        end case;
+          
+      when others => null;
+
+    end case;    
+
+  end process MMU_CONTROL;
+
+  
+  -- MMU TLB TAG array -------------------------
+
+  mm <= entryHi(VABITS-1 downto PAGE_SZ_BITS) when tlb_probe = '1' else
+        MM_result(VABITS-1 downto PAGE_SZ_BITS);
+
+  MMU_TAG0: register32 generic map(x"00000000")
+    port map (clk, rst, tlb_tag0_updt, tlb_tag_inp, tlb_tag0);
+
+  hit0_pc <= BOOL2SL(
+    tlb_tag0(VA_HI_BIT downto VA_LO_BIT) = PC(VA_HI_BIT downto VA_LO_BIT) AND
+    tlb_tag0(ASID_HI_BIT downto 0) = EntryHi(ASID_HI_BIT downto 0));
+
+  hit0_mm <= BOOL2SL(
+    tlb_tag0(VA_HI_BIT downto VA_LO_BIT) = mm(VA_HI_BIT downto VA_LO_BIT) AND
+    tlb_tag0(ASID_HI_BIT downto 0) = EntryHi(ASID_HI_BIT downto 0));
+
+  MMU_DAT0: register28 generic map(x"0000012")  -- PPN=0, v=1
+    port map (clk, rst, tlb_dat0_updt, tlb_dat_inp, tlb_dat0);
+  
+  
+  
+  MMU_TAG1: register32 generic map(x"00000400")
+    port map (clk, rst, tlb_tag1_updt, tlb_tag_inp, tlb_tag1);
+
+  hit1_pc <= BOOL2SL(
+    tlb_tag1(VA_HI_BIT downto VA_LO_BIT) = PC(VA_HI_BIT downto VA_LO_BIT) AND
+    tlb_tag1(ASID_HI_BIT downto 0) = EntryHi(ASID_HI_BIT downto 0));
+
+  hit1_mm <= BOOL2SL(
+    tlb_tag1(VA_HI_BIT downto VA_LO_BIT) = mm(VA_HI_BIT downto VA_LO_BIT) AND
+    tlb_tag1(ASID_HI_BIT downto 0) = EntryHi(ASID_HI_BIT downto 0));
+
+  MMU_DAT1: register28 generic map(x"0000052")  -- PPN=1, v=1
+    port map (clk, rst, tlb_dat1_updt, tlb_dat_inp, tlb_dat1);
+
+  
+  MMU_TAG2: register32 generic map(x"00000800")
+    port map (clk, rst, tlb_tag2_updt, tlb_tag_inp, tlb_tag2);
+
+  hit2_pc <= BOOL2SL(
+    tlb_tag2(VA_HI_BIT downto VA_LO_BIT) = PC(VA_HI_BIT downto VA_LO_BIT) AND
+    tlb_tag2(ASID_HI_BIT downto 0) = EntryHi(ASID_HI_BIT downto 0));
+
+  hit2_mm <= BOOL2SL(
+    tlb_tag2(VA_HI_BIT downto VA_LO_BIT) = mm(VA_HI_BIT downto VA_LO_BIT) AND
+    tlb_tag2(ASID_HI_BIT downto 0) = EntryHi(ASID_HI_BIT downto 0));
+  
+  MMU_DAT2: register28 generic map(x"0000092")  -- PPN=2, v=1
+    port map (clk, rst, tlb_dat2_updt, tlb_dat_inp, tlb_dat2);
+
+  
+  MMU_TAG3: register32 generic map(x"00000c00")
+    port map (clk, rst, tlb_tag3_updt, tlb_tag_inp, tlb_tag3);
+
+  hit3_pc <= BOOL2SL(
+    tlb_tag3(VA_HI_BIT downto VA_LO_BIT) = PC(VA_HI_BIT downto VA_LO_BIT) AND
+    tlb_tag3(ASID_HI_BIT downto 0) = EntryHi(ASID_HI_BIT downto 0));
+
+  hit3_mm <= BOOL2SL(
+    tlb_tag3(VA_HI_BIT downto VA_LO_BIT) = mm(VA_HI_BIT downto VA_LO_BIT) AND
+    tlb_tag3(ASID_HI_BIT downto 0) = EntryHi(ASID_HI_BIT downto 0));
+
+  MMU_DAT3: register28 generic map(x"00000d2")  -- PPN=3, v=1
+    port map (clk, rst, tlb_dat3_updt, tlb_dat_inp, tlb_dat3);
+
+  
+
+  tlb_a2_pc <= '0';
+  tlb_a1_pc <= hit2_pc or hit3_pc;
+  tlb_a0_pc <= hit1_pc or hit3_pc;
+
+  hit_pc     <= hit0_pc or hit1_pc or hit2_pc or hit3_pc;
+  tlb_adr_pc <= tlb_a1_pc & tlb_a0_pc;  -- tlb_a2_pc & 
+
+  tlb_ppn <= tlb_dat0(DAT_AHI_BIT downto DAT_ALO_BIT) when hit0_pc = '1'
+             else (others => 'Z');
+  tlb_ppn <= tlb_dat1(DAT_AHI_BIT downto DAT_ALO_BIT) when hit1_pc = '1'
+             else (others => 'Z');
+  tlb_ppn <= tlb_dat2(DAT_AHI_BIT downto DAT_ALO_BIT) when hit2_pc = '1'
+             else (others => 'Z');
+  tlb_ppn <= tlb_dat3(DAT_AHI_BIT downto DAT_ALO_BIT) when hit2_pc = '1'
+             else (others => 'Z');
+
+  
+--  with "00" select --  tlb_adr_pc select
+--    tlb_ppn <= tlb_dat0(DAT_AHI_BIT downto DAT_ALO_BIT) when "00",
+--                tlb_dat1(DAT_AHI_BIT downto DAT_ALO_BIT) when "01",
+--                tlb_dat2(DAT_AHI_BIT downto DAT_ALO_BIT) when "10",
+--                tlb_dat3(DAT_AHI_BIT downto DAT_ALO_BIT) when "11",
+--                (others => 'X') when others;
+
+  phy_i_addr <= tlb_ppn(21 downto 0) & PC(VA_LO_BIT-1 downto 0);
+  
+  assert false report LF& " dathi "&integer'image(DAT_AHI_BIT) &
+                          " datlo "&integer'image(DAT_ALO_BIT) &
+                          " valo " &integer'image(VA_LO_BIT) &
+                          " ppn_b "&integer'image(PPN_BITS) &
+                          " dathl "&integer'image(DAT_AHI_BIT - DAT_ALO_BIT) &
+    " ppn_bits " &integer'image(PPN_BITS)&
+    " 2bits " &integer'image(to_integer(signed(tlb_ppn(1 downto 0))))&
+    LF & " elohi "&integer'image(ELO_AHI_BIT)&
+    " elolo "&integer'image(ELO_ALO_BIT);
+  
+  
+  tlb_a2_mm <= '0';  
+  tlb_a1_mm <= hit2_mm or hit3_mm;
+  tlb_a0_mm <= hit1_mm or hit3_mm;
+
+  hit_mm     <= hit0_mm or hit1_mm or hit2_mm or hit3_mm;
+  tlb_adr_mm <= tlb_a1_mm & tlb_a0_mm;  -- tlb_a2_mm & 
+  
+  -- MMU-TLB == end =======================================================
+
+      
   -- ----------------------------------------------------------------------
   PIPESTAGE_EXCP_EX_MM: reg_excp_EX_MM
     port map (clk, rst, excp_EX_MM_ld, EX_can_trap,MM_can_trap,   
diff --git a/cMIPS/vhdl/packageExcp.vhd b/cMIPS/vhdl/packageExcp.vhd
index cca34ff70c9fbf9db12284ce90d8384431221b52..2b7c02cb10f909f7e0e10d1a1156816907752063 100644
--- a/cMIPS/vhdl/packageExcp.vhd
+++ b/cMIPS/vhdl/packageExcp.vhd
@@ -29,21 +29,33 @@ package p_EXCEPTION is
                           exBREAK, exTRAP, exSYSCALL,  -- 8
                           exRESV_INSTR, exWAIT,  -- 10
                           IFaddressError, MMaddressErrorLD, MMaddressErrorST,
-                          exTLBld, exTLBst, exTLBmod,  --16
-                          exOvfl,       -- 17
-                          exLL,exSC,    -- 18,19  these are treated by COP0
+                          exTLBrefill, exTLBld, exTLBst, exTLBmod,  -- 17
+                          exOvfl,       -- 18
+                          exLL,exSC,    -- 19,20  these are handled by COP0
+                          exEHB,        -- 21
+                          exTLBP, exTLBR, exTLBWI, exTLBWR,  -- 25
+                          exDERET,  -- 26
                           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";
+    "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";
 
---  010101 010110 010111 011000 011001 011010 011011 011100 011101 011110 011111 100000 100001 100010";
+-- 011100 011101 011110 011111 100000 100001 100010";
 
 
   
   -- Table 8-1 Coprocessor 0 Registers, pg 55
+  constant cop0reg_Index    : reg5 := b"00000";  -- 0
+  constant cop0reg_Random   : reg5 := b"00001";  -- 1
+  constant cop0reg_EntryLo0 : reg5 := b"00010";  -- 2
+  constant cop0reg_EntryLo1 : reg5 := b"00011";  -- 3
+  constant cop0reg_Context  : reg5 := b"00100";  -- 4
+  constant cop0reg_PageMask : reg5 := b"00101";  -- 5
+  constant cop0reg_Wired    : reg5 := b"00110";  -- 6
+  constant cop0reg_HWREna   : reg5 := b"00111";  -- 7
   constant cop0reg_BadVAddr : reg5 := b"01000";  -- 8
   constant cop0reg_COUNT    : reg5 := b"01001";  -- 9
+  constant cop0reg_EntryHi  : reg5 := b"01010";  -- 10
   constant cop0reg_COMPARE  : reg5 := b"01011";  -- 11
   constant cop0reg_STATUS   : reg5 := b"01100";  -- 12
   constant cop0reg_CAUSE    : reg5 := b"01101";  -- 13
@@ -70,10 +82,10 @@ package p_EXCEPTION is
   constant cop0code_NULL : reg5 := b"11111";  -- 1f, (no exception)=x3c
 
 
-  -- kernel mode, all else disabled
+  -- at exception level, kernel mode, cop0, all else disabled
   constant RESET_STATUS: std_logic_vector(31 downto 0) := x"10000002";
 
-  -- COUNTER disabled, kernel mode, exceptionCode = noException
+  -- COUNTER disabled, special interr vector, exceptionCode = noException
   constant RESET_CAUSE:  std_logic_vector(31 downto 0) := x"0880007c";
 
 
diff --git a/cMIPS/vhdl/packageMemory.vhd b/cMIPS/vhdl/packageMemory.vhd
index b1ad89a0d896fac82077f11dac4f384b3701192c..a1ac9efbd4718cfff8fed2ba2ca3758386965f85 100644
--- a/cMIPS/vhdl/packageMemory.vhd
+++ b/cMIPS/vhdl/packageMemory.vhd
@@ -23,19 +23,23 @@ use work.p_wires.all;
 package p_MEMORY is
 
   -- To simplify (and accelerate) the RAM address decoding,
-  --  the BASE of the RAM addresses MUST be allocated at an
-  --  address that is above/larger the RAM capacity.  Otherwise, the
-  --  base must be subtracted from the address on every reference,
-  --  which means having an adder in the critical path.  Bad idea.
+  --   the BASE of the RAM addresses MUST be allocated at an
+  --   address that is above/larger the the RAM capacity.  Otherwise,
+  --   the base must be subtracted from the address on every reference,
+  --   which means having an adder in the critical path.  Not good.
 
   -- The address ranges for ROM, RAM and I/O must be distinct in the
-  -- uppermost 12 bits of the address (bits 31..20).
+  --   uppermost 12 bits of the address (bits 31..20).
   constant HI_SEL_BITS : integer := 31;
   constant LO_SEL_BITS : integer := 20;
+
   
-  -- x_IO_ADDR_RANGE can have only ONE bit set, thus being a power of 2
+  -- x_IO_ADDR_RANGE can have only ONE bit set, thus being a power of 2.
+  -- ACHTUNG: changing the above number may break some of the test programs.  
+
   
   -- begin DO NOT change these names as several scripts depend on them --
+  --  you may change the values, not names nor formatting              --
   constant x_INST_BASE_ADDR : reg32   := x"00000000";
   constant x_INST_MEM_SZ    : reg32   := x"00002000";  
   constant x_DATA_BASE_ADDR : reg32   := x"00400000";  
@@ -61,7 +65,7 @@ package p_MEMORY is
   constant IO_ADDR_MASK    : integer := (0 - IO_ADDR_RANGE);
   constant x_IO_ADDR_MASK  : reg32   := std_logic_vector(to_signed(0 - IO_ADDR_RANGE, 32));
 
-  -- maximum number of IO devices, must be power of two.
+  -- maximum number of IO devices, must be a power of two.
   constant IO_MAX_NUM_DEVS : integer := 16;
   
   -- I/O addresses are IO_ADDR_RANGE apart 
@@ -80,6 +84,7 @@ package p_MEMORY is
   constant IO_HIGHEST_ADDR : integer :=
     IO_BASE_ADDR + (IO_MAX_NUM_DEVS - 1)*IO_ADDR_RANGE;
 
+
   -- DATA CACHE parameters ----------------------------------------------
   
   -- The combination of capacity, associativity and block/line size
@@ -96,7 +101,7 @@ package p_MEMORY is
   constant DC_WORD_SEL_BITS   : natural := log2_ceil( DC_WORDS_PER_BLOCK );
   constant DC_BYTE_SEL_BITS   : natural := log2_ceil( DC_BYTES_PER_WORD );
 
-  -- constants for CONFIG1 cop0 register
+  -- constants for CONFIG1 cop0 register (Table 8-24 pg 103)
   constant DC_SETS_PER_WAY: reg3 :=
     std_logic_vector(to_signed(DC_INDEX_BITS - 6, 3));
   constant DC_LINE_SIZE: reg3 :=
@@ -104,6 +109,7 @@ package p_MEMORY is
   constant DC_ASSOCIATIVITY: reg3 :=
     std_logic_vector(to_signed(DC_NUM_WAYS - 1, 3));
 
+  
   -- INSTRUCTION CACHE parameters ---------------------------------------
 
   -- The combination of capacity, associativity and block/line size
@@ -120,7 +126,7 @@ package p_MEMORY is
   constant IC_WORD_SEL_BITS   : natural := log2_ceil( IC_WORDS_PER_BLOCK );
   constant IC_BYTE_SEL_BITS   : natural := log2_ceil( IC_BYTES_PER_WORD );
 
-  -- constants for CONFIG1 cop0 register
+  -- constants for CONFIG1 cop0 register (Table 8-24 pg 103)
   constant IC_SETS_PER_WAY: reg3 :=
     std_logic_vector(to_signed(IC_INDEX_BITS - 6, 3));
   constant IC_LINE_SIZE: reg3 :=
@@ -128,13 +134,73 @@ package p_MEMORY is
   constant IC_ASSOCIATIVITY: reg3 :=
     std_logic_vector(to_signed(IC_NUM_WAYS - 1, 3));
 
-  -- constants to access statistics counter
+  -- constants to access the cache statistics counters
   constant dcache_Stats_ref   : reg3 := "000";
   constant dcache_Stats_rdhit : reg3 := "001";
   constant dcache_Stats_wrhit : reg3 := "010";
   constant dcache_Stats_flush : reg3 := "011";
   constant icache_Stats_ref   : reg3 := "100";
   constant icache_Stats_hit   : reg3 := "101";
+
+  
+  -- MMU parameters -----------------------------------------------------
+
+  -- constants for CONFIG1 cop0 register (Table 8-24 pg 103)
+  constant MMU_CAPACITY : natural := 4;
+  constant MMU_CAPACITY_BITS : natural := log2_ceil( MMU_CAPACITY );
+  constant MMU_SIZE: reg6 := 
+    std_logic_vector(to_signed( (MMU_CAPACITY-1), 6) );
+  constant MMU_WIRED_INIT : reg32 := x"00000000";
+  
+  constant VABITS       : natural := 32;
+  constant PABITS       : natural := 32;
+  constant PAGE_SZ      : natural := 1024;   -- 1k pages
+  constant PAGE_SZ_BITS : natural := log2_ceil( PAGE_SZ );
+
+  constant PPN_BITS     : natural := PABITS - PAGE_SZ_BITS;
+  constant VA_HI_BIT    : natural := 31; -- VAaddr in EntryHi 31..PG_size
+  constant VA_LO_BIT    : natural := PAGE_SZ_BITS;
+
+  constant ASID_HI_BIT  : natural := 7;  -- ASID   in EntryHi 7..0
+  constant ASID_LO_BIT  : natural := 0;
+
+  constant EHI_ASIDLO_BIT : natural := 0;
+  constant EHI_ASIDHI_BIT : natural := 7;  
+  constant EHI_ALO_BIT  : natural := PAGE_SZ_BITS;
+  constant EHI_AHI_BIT  : natural := EHI_ALO_BIT + PPN_BITS - 1;
+
+  constant ELO_G_BIT    : natural := 0;
+  constant ELO_V_BIT    : natural := 1;
+  constant ELO_D_BIT    : natural := 2;
+  constant ELO_CLO_BIT  : natural := 3;
+  constant ELO_CHI_BIT  : natural := 5;  
+  constant ELO_ALO_BIT  : natural := 6;
+  constant ELO_AHI_BIT  : natural := ELO_ALO_BIT + PPN_BITS - 1;
+
+  constant TAG_ASIDLO_BIT : natural := 0;
+  constant TAG_ASIDHI_BIT : natural := 7;
+  constant TAG_G_BIT    : natural := 8;
+  constant TAG_Z_BIT    : natural := 9;
+  constant TAG_AHI_BIT  : natural := 31;  
+  constant TAG_ALO_BIT  : natural := TAG_AHI_BIT - PPN_BITS + 1;
+
+  constant DAT_G_BIT    : natural := 0;
+  constant DAT_V_BIT    : natural := 1;
+  constant DAT_D_BIT    : natural := 2;
+  constant DAT_CLO_BIT  : natural := 3;
+  constant DAT_CHI_BIT  : natural := 5;  
+  constant DAT_ALO_BIT  : natural := 6;
+  constant DAT_AHI_BIT  : natural := DAT_ALO_BIT + PPN_BITS - 1;
+
+ 
+  subtype  MMU_idx_bits is std_logic_vector(MMU_CAPACITY_BITS-1 downto 0);
+  constant MMU_idx_0s : std_logic_vector(30 downto MMU_CAPACITY_BITS) :=
+    (others => '0');
+  constant MMU_IDX_BIT : natural := 31;  -- probe hit=1, miss=0
+  
+  constant mmu_PageMask : reg32 := x"00000000";  -- pg 68, 1k pages only
+  -- constant mmu_PageMask : reg32 := x"00001800";  -- pg 68, 4k pages only
+
   
 end p_MEMORY;