data/full_repos/permissive/426889244/verilog/IF_ID_reg.v
data/verilator_xmls/08787f91-d3e3-4b91-ab5f-7376603e48e2.xml
module IF_ID_reg (
    input wire clk,
    input wire reset,
    input wire ena,
    input wire[31:0] if_pc_in,
    input wire[31:0] if_instr_in,

    output wire[1:0] ExtSelect_out,
    output wire id_GPR_we,
    output wire id_mtc0,
    output wire id_mfc0,
    output wire[4:0] id_GPR_waddr,
    output wire[1:0] id_GPR_wdata_select,
    output wire id_mem_we,
    output reg[31:0] id_pc_out,
    output reg[31:0] id_instr_out
);
    
    always @(posedge clk or negedge reset) begin
        if (!reset) begin
            id_pc_out <= 32'h00000000;
            id_instr_out <= 32'h00000000;
        end
        else if (ena) begin
            id_pc_out <= if_pc_in;
            id_instr_out <= if_instr_in;
        end
    end

    assign ExtSelect_out[1] = (~id_instr_out[29] & ~id_instr_out[28] & ~id_instr_out[27] & ~id_instr_out[26]) | (~id_instr_out[31] & ~id_instr_out[29] & id_instr_out[28] & ~id_instr_out[27]);
    assign ExtSelect_out[0] = id_instr_out[29] ^ id_instr_out[28];

    assign id_GPR_we = ena & (
                        ~((~id_instr_out[29] & ~id_instr_out[28] & ~id_instr_out[27] & ~id_instr_out[26] & ~id_instr_out[5] & id_instr_out[3] & ~id_instr_out[1])
                         |
                         (id_instr_out[31] & id_instr_out[29] & ~id_instr_out[28] & id_instr_out[27] & id_instr_out[26])
                         |
                         (~id_instr_out[31] & ~id_instr_out[29] & id_instr_out[28] & ~id_instr_out[27])
                         |
                         (~id_instr_out[31] & ~id_instr_out[29] & ~id_instr_out[28] & id_instr_out[27] & ~id_instr_out[26]))
                        )
                        & ~id_mtc0;
    
    assign id_mfc0 = id_instr_out[31:21] == 11'b01000000000;

    assign id_mtc0 = id_instr_out[31:21] == 11'b01000000100;

    wire[1:0] GPR_waddr_select;
    assign GPR_waddr_select[1] = ~id_mfc0 & (~id_instr_out[31] & ~id_instr_out[29] & ~id_instr_out[28] & id_instr_out[27] & id_instr_out[26]);
    assign GPR_waddr_select[0] = ~id_mfc0 & (id_instr_out[30] | (~id_instr_out[29] & ~id_instr_out[28] & ~id_instr_out[27] & ~id_instr_out[26]));

    assign id_GPR_waddr = GPR_waddr_select[1] ?
                            5'b11111
                            :
                            (GPR_waddr_select[0] ? id_instr_out[15:11] : id_instr_out[20:16]);

    assign id_GPR_wdata_select[1] = id_instr_out[30] | (~id_instr_out[31] & ~id_instr_out[29] & ~id_instr_out[28] & id_instr_out[27] & id_instr_out[26]);
    assign id_GPR_wdata_select[0] = id_instr_out[30] | id_instr_out[29] | id_instr_out[28] | ~id_instr_out[27] | ~id_instr_out[26];

    assign id_mem_we = ena & id_instr_out[31] & id_instr_out[29];
endmodule
module IF_ID_reg (
    input wire clk,
    input wire reset,
    input wire ena,
    input wire[31:0] if_pc_in,
    input wire[31:0] if_instr_in,

    output wire[1:0] ExtSelect_out,
    output wire id_GPR_we,
    output wire id_mtc0,
    output wire id_mfc0,
    output wire[4:0] id_GPR_waddr,
    output wire[1:0] id_GPR_wdata_select,
    output wire id_mem_we,
    output reg[31:0] id_pc_out,
    output reg[31:0] id_instr_out
);

    
    always @(posedge clk or negedge reset) begin
        if (!reset) begin
            id_pc_out <= 32'h00000000;
            id_instr_out <= 32'h00000000;
        end
        else if (ena) begin
            id_pc_out <= if_pc_in;
            id_instr_out <= if_instr_in;
        end
    end

    assign ExtSelect_out[1] = (~id_instr_out[29] & ~id_instr_out[28] & ~id_instr_out[27] & ~id_instr_out[26]) | (~id_instr_out[31] & ~id_instr_out[29] & id_instr_out[28] & ~id_instr_out[27]);
    assign ExtSelect_out[0] = id_instr_out[29] ^ id_instr_out[28];

    assign id_GPR_we = ena & (
                        ~((~id_instr_out[29] & ~id_instr_out[28] & ~id_instr_out[27] & ~id_instr_out[26] & ~id_instr_out[5] & id_instr_out[3] & ~id_instr_out[1])
                         |
                         (id_instr_out[31] & id_instr_out[29] & ~id_instr_out[28] & id_instr_out[27] & id_instr_out[26])
                         |
                         (~id_instr_out[31] & ~id_instr_out[29] & id_instr_out[28] & ~id_instr_out[27])
                         |
                         (~id_instr_out[31] & ~id_instr_out[29] & ~id_instr_out[28] & id_instr_out[27] & ~id_instr_out[26]))
                        )
                        & ~id_mtc0;
    
    assign id_mfc0 = id_instr_out[31:21] == 11'b01000000000;

    assign id_mtc0 = id_instr_out[31:21] == 11'b01000000100;

    wire[1:0] GPR_waddr_select;
    assign GPR_waddr_select[1] = ~id_mfc0 & (~id_instr_out[31] & ~id_instr_out[29] & ~id_instr_out[28] & id_instr_out[27] & id_instr_out[26]);
    assign GPR_waddr_select[0] = ~id_mfc0 & (id_instr_out[30] | (~id_instr_out[29] & ~id_instr_out[28] & ~id_instr_out[27] & ~id_instr_out[26]));

    assign id_GPR_waddr = GPR_waddr_select[1] ?
                            5'b11111
                            :
                            (GPR_waddr_select[0] ? id_instr_out[15:11] : id_instr_out[20:16]);

    assign id_GPR_wdata_select[1] = id_instr_out[30] | (~id_instr_out[31] & ~id_instr_out[29] & ~id_instr_out[28] & id_instr_out[27] & id_instr_out[26]);
    assign id_GPR_wdata_select[0] = id_instr_out[30] | id_instr_out[29] | id_instr_out[28] | ~id_instr_out[27] | ~id_instr_out[26];

    assign id_mem_we = ena & id_instr_out[31] & id_instr_out[29];
endmodule