/*
* Register Bank
*/

module Regbank(
    input               clk, reset,

    input       [3:0]   addr_a, addr_b,
    output      [31:0]  data_a, data_b, 

    input       [3:0]   addr_d,
    input       [31:0]  data_d,
    input               we, clear, hold
);

reg [31:0] regs [0:15]; // 16 registers of 32 bit, although reg0 is unused


reg [31:0] ramResulta = 32'd0;
reg [31:0] ramResultb = 32'd0;

// RAM logic
always @(posedge clk) 
begin
    ramResulta <= regs[addr_a];
    ramResultb <= regs[addr_b];

    if (we && addr_d != 4'd0)
    begin
        regs[addr_d] <= data_d;
        //$display("%d: reg%d := %d", $time, addr_d, data_d);
    end
end

reg [31:0] data_a_reg = 32'd0;
reg [31:0] data_b_reg = 32'd0;

reg useRamResult_a = 1'b0;
reg useRamResult_b = 1'b0;

assign data_a = (useRamResult_a) ? ramResulta : data_a_reg;
assign data_b = (useRamResult_b) ? ramResultb : data_b_reg;

// Read
always @(posedge clk) 
begin
    if (reset)
    begin
        useRamResult_a <= 1'b0;
        useRamResult_b <= 1'b0;
        data_a_reg <= 32'd0;
        data_b_reg <= 32'd0;
    end
    else
    begin
        useRamResult_a <= 1'b0;
        useRamResult_b <= 1'b0;

        if (clear)
        begin
            data_a_reg <= 32'd0;
        end
        else if (hold)
        begin
            data_a_reg <= data_a_reg;
        end
        else if (addr_a == 4'd0)
        begin
            data_a_reg <= 32'd0;
        end
        else if ((addr_a == addr_d) && we)
        begin
            data_a_reg <= data_d;
        end
        else
        begin
            //data_a <= regs[addr_a];
            useRamResult_a <= 1'b1;
        end

        if (clear)
        begin
            data_b_reg <= 32'd0;
        end
        else if (hold)
        begin
            data_b_reg <= data_b_reg;
        end
        else if (addr_b == 4'd0)
        begin
            data_b_reg <= 32'd0;
        end
        else if ((addr_b == addr_d) && we)
        begin
            data_b_reg <= data_d;
        end
        else
        begin
            //data_b <= regs[addr_b];
            useRamResult_b <= 1'b1;
        end
    end
end

/*
integer i;
initial
begin
    for (i = 0; i < 16; i = i + 1)
    begin
        regs[i] = 32'd0;
    end
end
*/

endmodule