anchor.diff:     // the address given to the ICache.
      Reg #(WordXL)  rg_pc  <- mkRegU;
   
  -   // This register holds [15:0] of a 32b instr that was in the
  -   // upper-half of a word from the ICache.
  -   Reg #(Bit #(16))  rg_instr_15_0  <- mkRegU;
  -
  -   // The following hold args for the mmu-cache that are needed when
  -   // doing the second 32-bit fetch of an odd-aligned 32b instr
  +   // These registers caches the last output of imem32 (imem32.pc, and imem32.instr [31:16])
  +   Reg #(WordXL)    rg_cache_addr <- mkReg ('1);
  +   Reg #(Bit #(16)) rg_cache_b16  <- mkRegU;
  +
  +   // The following hold args of the 'req' method.
      Reg #(Bit #(3))  rg_f3          <- mkRegU;
      Reg #(Priv_Mode) rg_priv        <- mkRegU;
      Reg #(Bit #(1))  rg_sstatus_SUM <- mkRegU;
      Reg #(Bit #(1))  rg_mstatus_MXR <- mkRegU;
      Reg #(WordXL)    rg_satp        <- mkRegU;
   
  -   // Holds the faulting address
  -   Reg #(WordXL) rg_tval <- mkRegU;
  -
  -   // ----------------------------------------------------------------
  -
  -   function Bool is_even_h_pc (WordXL pc);
  -      return (pc [1:0] == 2'b00);
  -   endfunction
  -
  -   function Bool is_odd_h_pc (WordXL pc);
  -      return (pc [1:0] != 2'b00);
  -   endfunction
  -
  -   function Bool is_32b_instr (Bit #(n) instr);
  -      return (instr [1:0] == 2'b11);
  -   endfunction
  -
  -   function Bool is_16b_instr (Bit #(n) instr);
  -      return (instr [1:0] != 2'b11);
  -   endfunction
  -
  -   Bool eqw_rg_pc_imem_pc = ((imem32.pc >> 2) == (rg_pc >> 2));
  +   // Holds a faulting address
  +   Reg #(WordXL)    rg_tval        <- mkRegU;
   
      // ----------------------------------------------------------------
      // Conditions for selecting 16b and 32b instruction
   
  -   // Condition: 32b instr from {imem [15:0], rg_instr_15_0}
  -   Bool cond_i32_odd = (imem32.pc == rg_pc + 2);    // Assert: is_odd_h_pc (rg_pc)
  +   // Condition: 32b instr from {imem [15:0], rg_cache_b16}
  +   Bool cond_i32_odd = (   is_addr_odd16 (rg_pc)
  +			&& eq_b32_addr (rg_pc, rg_cache_addr)
  +			&& (imem32.pc == rg_pc + 2)
  +			&& is_32b_instr (rg_cache_b16));
   
      // Condition: 32b instr from imem [31:0]
  -   Bool cond_i32_even = (   eqw_rg_pc_imem_pc
  -			 && is_even_h_pc (rg_pc)
  -			 && (is_32b_instr (imem32.instr)));
  +   Bool cond_i32_even = (   is_addr_even16 (rg_pc)
  +			 && eq_b32_addr (rg_pc, imem32.pc)
  +			 && is_32b_instr (imem32.instr));
   
      // Condition: 16b instr from imem [31:16]
  -   Bool cond_i16_odd  = (   eqw_rg_pc_imem_pc
  -			 && is_odd_h_pc (rg_pc)
  -			 && (is_16b_instr (imem32.instr [31:16])));
  +   Bool cond_i16_odd  = (   is_addr_odd16 (rg_pc)
  +			 && (   (   eq_b32_addr (rg_pc, imem32.pc)
  +				 && is_16b_instr (imem32.instr [31:16]))
  +			     || (   eq_b32_addr (rg_pc, rg_cache_addr)
  +				 && is_16b_instr (rg_cache_b16))));
   
      // Condition: 16b instr from imem [15:0]
  -   Bool cond_i16_even = (   eqw_rg_pc_imem_pc
  -			 && is_even_h_pc (rg_pc)
  -			 && (is_16b_instr (imem32.instr)));
  +   Bool cond_i16_even = (   is_addr_even16 (rg_pc)
  +			 && eq_b32_addr (rg_pc, imem32.pc)
  +			 && is_16b_instr (imem32.instr));
   
      // Condition: 32b instr from { ...next imem [15:0], imem [31:16] }
  -   Bool cond_i32_odd_fetch_next = (   eqw_rg_pc_imem_pc
  -				   && is_odd_h_pc (rg_pc)
  -				   && (is_32b_instr (imem32.instr [31:16])));
  +   Bool cond_i32_odd_fetch_next = (   is_addr_odd16 (rg_pc)
  +				   && imem32.valid
  +				   && eq_b32_addr (rg_pc, imem32.pc)
  +				   && is_32b_instr (imem32.instr [31:16]));
  +
  +   // ----------------
  +   // Compose the 32b output 'instr' (either a 32b instr, or { 16'b0, 16b instr })
  +
  +   function Bit #(32) fn_instr_out ();
  +      Bit #(32) instr_out = imem32.instr;
  +      if (cond_i32_odd)
  +	 instr_out = { imem32.instr [15:0], rg_cache_b16 };
  +
  +      else if (cond_i16_even)
  +	 instr_out = { 16'b0, imem32.instr [15:0] };
  +
  +      else if (cond_i16_odd) begin
  +	 if (eq_b32_addr (rg_pc, imem32.pc))
  +	    instr_out = { 16'b0, imem32.instr [31:16] };
  +	 else
  +	    instr_out = { 16'b0, rg_cache_b16 };
  +      end
  +      return instr_out;
  +   endfunction
   
      // ================================================================
      // Assert: The underlying imem32 only knows about 32-bit aligned words
   
      rule rl_assert_fail (! imem32.is_i32_not_i16);
  -      $display ("ERROR: CPU_Fetch_C: imem32.is_i32_not_i16 is False");
  +      $display ("%0d: ERROR: CPU_Fetch_C: imem32.is_i32_not_i16 is False", cur_cycle);
         $finish (1);
      endrule
   
      rule rl_debug_conds (False && (verbosity != 0) && imem32.valid);
  -      $display ("    imem32.pc 0x%0h  pc 0x%0h  rg_f3 %0d  imem32.instr 0x%08h  rg_instr_15_0 0x%04h",
  -		imem32.pc,  rg_pc,  rg_f3,  imem32.instr,  rg_instr_15_0);
  +      $display ("%0d: imem32.pc 0x%0h  pc 0x%0h  rg_f3 %0d  imem32.instr 0x%08h  rg_cache_b16 0x%04h",
  +		cur_cycle, imem32.pc,  rg_pc,  rg_f3,  imem32.instr,  rg_cache_b16);
         $display ("    cond_i32_odd  = ", fshow (cond_i32_odd));
         $display ("    cond_i32_even = ", fshow (cond_i32_even));
         $display ("    cond_i16_odd  = ", fshow (cond_i16_odd));
         $display ("    cond_i16_even = ", fshow (cond_i16_even));
         $display ("    cond_i32_odd_fetch_next             = ", fshow (cond_i32_odd_fetch_next));
  -      $display ("    eqw_rg_pc_imem_pc                   = ", fshow (eqw_rg_pc_imem_pc));
  -      $display ("    is_odd_h_pc (rg_pc)                 = ", fshow (is_odd_h_pc (rg_pc)));
  +      $display ("    eq_b32_addr (rg_pc, imem32.pc)      = ", fshow (eq_b32_addr (rg_pc, imem32.pc)));
  +      $display ("    is_addr_odd16 (rg_pc)               = ", fshow (is_addr_odd16 (rg_pc)));
         $display ("    is_32b_instr (imem32.instr [31:16]) = ", fshow (is_32b_instr (imem32.instr [31:16])));
      endrule
   
      // ================================================================
  -   // On 32b odd instr in imem32.instr [31:15], fetch next 32 bits
  +   // When imem32.instr [31:15] has lower half of 32b instr, cache it and fetch next 32 bits
   
      (* no_implicit_conditions, fire_when_enabled *)
      rule rl_fetch_next_32b (imem32.valid && cond_i32_odd_fetch_next);
  -      Addr next_word_addr = rg_pc + 2;
  -      imem32.req (rg_f3, next_word_addr, rg_priv, rg_sstatus_SUM, rg_mstatus_MXR, rg_satp);
  -      rg_instr_15_0 <= imem32.instr [31:16];
  -      rg_tval <= next_word_addr;
  +      Addr next_b32_addr = imem32.pc + 4;
  +      imem32.req (rg_f3, next_b32_addr, rg_priv, rg_sstatus_SUM, rg_mstatus_MXR, rg_satp);
  +      rg_cache_addr <= imem32.pc;
  +      rg_cache_b16  <= imem32.instr [31:16];
  +      rg_tval       <= next_b32_addr;
  +
         if (verbosity != 0)
  -	 $display ("CPU_Fetch_C.rl_fetch_next_32b:  imem32.pc 0x%0h  next_word_addr 0x%0h",
  -		   imem32.pc, next_word_addr);
  +	 $display ("%0d: CPU_Fetch_C.rl_fetch_next_32b:  imem32.pc 0x%0h  next_b32_addr 0x%0h",
  +		   cur_cycle, imem32.pc, next_b32_addr);
      endrule
  -
  -   // ----------------
  -   // Compose the 'instr' 32b output
  -
  -   Instr instr_out = imem32.instr;
  -   Bool  is_32b_not_16b = True;
  -   if (cond_i32_odd)
  -      instr_out = { imem32.instr [15:0], rg_instr_15_0 };
  -
  -   else if (cond_i16_even) begin
  -      instr_out = { 16'b0, imem32.instr [15:0] };
  -      is_32b_not_16b = False;
  -   end
  -
  -   else if (cond_i16_odd) begin
  -      instr_out = { 16'b0, imem32.instr [31:16] };
  -      is_32b_not_16b = False;
  -   end
   
      // ================================================================
      // INTERFACE
   
      // CPU side: IMem request
  -   method Action  req (Bit #(3) f3,
  -		       WordXL addr,
  +   method Action  req (Bit #(3)   f3,
  +		       WordXL     addr,
   		       // The following  args for VM
   		       Priv_Mode  priv,
   		       Bit #(1)   sstatus_SUM,
  
positive.code:       rg_mstatus_MXR <= mstatus_MXR;
        rg_satp        <= satp;
        rg_tval        <= addr;
        WordXL even_addr = { addr [xlen-1:2], 2'b_00 };
        imem32.req (f3, even_addr, priv, sstatus_SUM, mstatus_MXR, satp);
        if (verbosity > 0) begin
  	 $display ("CPU_Fetch_C.req: addr 0x%0h, even_addr 0x%0h", addr, even_addr);
        end
     endmethod
  
  
negative.code:    method Bool     is_i32_not_i16 = (cond_i32_odd || cond_i32_even);
  
     method WordXL   pc       = rg_pc;
     method Instr    instr    = fn_instr_out ();
     method Bool     exc      = imem32.exc;
     method Exc_Code exc_code = imem32.exc_code;
     method WordXL   tval     = rg_tval;        // Can be different from rg_pc
  