//**************************************************************************
// SMIPSv2 Branch prediction table
//--------------------------------------------------------------------------
// $Id: smipsProcBPTable.v,v 1.2 2007/02/20 11:28:55 jrk Exp $
//

module smipsProcBPTable
(
 input clk, reset,

 input  [31:0] correct_targ,
 input  [31:0] correct_pc4,
 input  [31:0] curr_pc4,
 
 input         wen,

 
 output [31:0] predicted_targ,
 output        predicted_taken
 );

   wire [64:0] table_val;
   
   // DATA_SZ = 1+32+32
   // ENTRIES = 4
   // ADDR_SZ = 2
   // RESET_VALUE = 0 -- PC+4 is always >= 0x1004 >> 0, and valid (bit 65) will be 0
   vcRAM_rst_1w1r_pf#(65,4,2,65'd0) tab
     (
      .clk     (clk),
      .reset_p (reset),
      .raddr   (curr_pc4[3:2]),
      .rdata   (table_val),
      .wen_p   (wen),
      .waddr_p (correct_pc4[3:2]),
      .wdata_p ({ 1'b1, (correct_pc4), correct_targ }) // valid, tag=pc4, target
      );

   wire [31:0] table_targ  = table_val[31:0];
   wire [31:0] table_tag   = table_val[63:32];
   wire        table_valid = table_val[64];

   assign predicted_taken = (table_tag == curr_pc4 && table_valid);
   assign predicted_targ  = (predicted_taken) ? table_targ
		          :                     curr_pc4;

   always @( posedge clk )
   begin
      if (wen) $display("smipsProcBPTable: write-enable");
      $display("wen = %d, table_valid = %d, correct_pc4 = %h, curr_pc4 = %h, table_tag = %h", wen, table_valid, correct_pc4, curr_pc4, table_tag);
      if (predicted_taken) $display("smipsProcBPTable: predicted taken -> %h", predicted_targ);
      else $display("smipsProcBPTable: predicted NOT taken");
   end
   
endmodule
