from generateCode import *


instances = 32
fname = "regfile.v"

input1Fmt = ".input{0} (genblock[{0}].regOut)"

repeatedInput  = repeatNTimes(input1Fmt, instances, delim=", ", end="")
# repeatedMux = repeatNTimes(muxFmt, instances, delim="\n")


baseStr = """
//------------------------------------------------------------------------------
// MIPS register file
//   width: 32 bits
//   depth: 32 words (reg[0] is static zero register)
//   2 asynchronous read ports
//   1 synchronous, positive edge triggered write port
//------------------------------------------------------------------------------
`include "decoder1to32.v"
`include "registerN.v"
`include "registerNzero.v"
`include "muxNto1by32.v"

module regfile
#(parameter WIDTH=32)
(
output[WIDTH-1:0]   ReadData1,  // Contents of first register read
output[WIDTH-1:0]   ReadData2,  // Contents of second register read
output[WIDTH-1:0]   ReadData2b, // Register immediately after 
output[WIDTH-1:0]   ReadData2c, 
output[WIDTH-1:0]   ReadData2d,
input[WIDTH-1:0]    WriteData,  // Contents to write to register
input[4:0]  ReadRegister1,  // Address of first register to read
input[4:0]  ReadRegister2,  // Address of second register to read
input[4:0]  WriteRegister,  // Address of register to write
input       RegWrite,   // Enable writing of register when High
input       Clk,        // Clock (Positive Edge Triggered)
    input[31:0] link_addr
);

    
    wire [31:0] decoded;
    decoder1to32 dec(.out(decoded), .enable (RegWrite), .address(WriteRegister));

    genvar i;
    generate
        for (i=0; i<WIDTH; i=i+1)
        begin:genblock
            wire [WIDTH-1:0] regOut;
            if (i == 0) 
                registerNzero  #(.WIDTH(WIDTH)) regs(.q(regOut), .d(WriteData), .wrenable(decoded[i]), .clk(Clk));
            else
                registerN  #(.WIDTH(WIDTH)) regs(.q(regOut), .d(WriteData), .wrenable(decoded[i]), .clk(Clk));
        end
    endgenerate

    muxNto1by32 #(.WIDTH(WIDTH)) endMux1(.out(ReadData1), .address(ReadRegister1), {0});
    muxNto1by32 #(.WIDTH(WIDTH)) endMux2(.out(ReadData2), .address(ReadRegister2), {0});

    muxNto1by32 #(.WIDTH(WIDTH)) endMuxb(.out(ReadData2b), .address(ReadRegister2 + 5'd1), {0});
    muxNto1by32 #(.WIDTH(WIDTH)) endMuxc(.out(ReadData2c), .address(ReadRegister2 + 5'd2), {0});
    muxNto1by32 #(.WIDTH(WIDTH)) endMuxd(.out(ReadData2d), .address(ReadRegister2 + 5'd3), {0});

    //always @(link_addr) begin

    //end
endmodule
""".format(repeatedInput)



genWarning = """// WARNING: THIS FILE WAS GENERATED. DO NOT MODIFY\n"""

# print(baseStr)
saveToFile(fname, genWarning + baseStr)