/****************** The 31 registers (plus zero) ***************************/

module NrvRegisterFile(
  input 	    clk, 
  input [31:0] 	    in,        // Data for write back register
  input [4:0] 	    inRegId,   // Register to write back to
  input 	    inEn,      // Enable register write back
  input [4:0] 	    outRegId1, // Register number for out1
  input [4:0] 	    outRegId2, // Register number for out2
  output reg [31:0] out1, // Data out 1, available one clock after outRegId1 is set
  output reg [31:0] out2  // Data out 2, available one clock after outRegId2 is set
);
   
   // Register file is duplicated so that we can read rs1 and rs2 simultaneously
   // It is a bit stupid, it wastes four (inferred) SB_RAM40_4K BRAMs, where a single
   // one would suffice, but it makes things simpler (and the CPU faster).
   
   reg [31:0]  bank1 [30:0];
   reg [31:0]  bank2 [30:0];

   always @(posedge clk) begin
      if (inEn) begin
	 // This test seems to be needed ! (else J followed by LI results in wrong result)
	 if(inRegId != 0) begin 
	    bank1[~inRegId] <= in;
	    bank2[~inRegId] <= in;
	 end	  
      end else begin // Not mandatory to put what's below in an 'else' branch, 
	             // but it allows higher overclocking.
	             //   with it: up to 80 MHz on the icestick, 
	             //   without it: 60 MHz
	             // TODO: understand critical path, optimize timings
      // Test bench does not seem to understand that
      // oob access in reg array is supposed to return 0.
`ifdef BENCH	 
         out1 <= (outRegId1 == 0) ? 0 : bank1[~outRegId1];
         out2 <= (outRegId2 == 0) ? 0 : bank2[~outRegId2];
`else
         out1 <= bank1[~outRegId1];
         out2 <= bank2[~outRegId2];
`endif
      end
   end 
endmodule
