//**********************************************************************
// Branch History Table
//----------------------------------------------------------------------
// $Id: mkBHT.bsv,v 1.1 2007/03/21 16:42:20 jrk Exp $
//
//

package mkBHT;

import ProcTypes::*;
import IBHT::*;
import RegFile::*;

typedef struct
{
 Bool valid;
 Addr tag;
 Addr target;
}
BHTEntry deriving (Bits, Eq);

module mkBHT( IBHT );
   
   //RegFile#( Bit#(2), Bit#(65) ) rfile <- mkRegFileFull();
   RegFile#( Bit#(2), BHTEntry ) rfile <- mkRegFileFull();
   //RegFile#( Bit#(8), BHTEntry ) rfile <- mkRegFileFull();
   //Reg#(Bool) taken <- mkReg(False);
   
   method NextPC nextPC( Addr pc4 );
      Addr predicted_target = pc4;
      Bool taken = False;

      /*
      Bit#(65) entry = rfile.sub( pc4[3:2] );
      Bool valid = (entry[64] == 1'b1) ? True : False;
      Addr tag = entry[63:32];
      Addr target = entry[31:0];
      */

      BHTEntry entry = rfile.sub( pc4[3:2] );
      //BHTEntry entry = rfile.sub( pc4[9:2] );
      Bool valid = entry.valid;
      Addr tag = entry.tag;
      Addr target = entry.target;

      if (valid && tag == pc4) begin
	 taken = True;
	 predicted_target = target;
      end
      /*
      else begin
	 taken = False;
      end
       */

      return NextPC{ branchTaken:taken, target:predicted_target };

   endmethod

   /*
   method Bool predictedTaken();
      return taken;
   endmethod
    */
   
   method Action update( Addr correct_pc4, Addr correct_target );
      //rfile.upd( correct_pc4[3:2], {1'b1, correct_pc4, correct_target} );
      rfile.upd( correct_pc4[3:2], BHTEntry{valid:True, tag:correct_pc4, target:correct_target} );
      //rfile.upd( correct_pc4[9:2], BHTEntry{valid:True, tag:correct_pc4, target:correct_target} );
   endmethod
   
endmodule

endpackage
