data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v
None: at end of input
1: b'%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:9: Cannot find include file: riscv_defs.v\n`include "riscv_defs.v" \n         ^~~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/151207731/rv32i/rtl,data/full_repos/permissive/151207731/riscv_defs.v\n             data/full_repos/permissive/151207731/rv32i/rtl,data/full_repos/permissive/151207731/riscv_defs.v.v\n             data/full_repos/permissive/151207731/rv32i/rtl,data/full_repos/permissive/151207731/riscv_defs.v.sv\n             riscv_defs.v\n             riscv_defs.v.v\n             riscv_defs.v.sv\n             obj_dir/riscv_defs.v\n             obj_dir/riscv_defs.v.v\n             obj_dir/riscv_defs.v.sv\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:20: Define or directive not defined: \'`RV_SOFID_RANGE\'\n        input  wire    [`RV_SOFID_RANGE] pfu_sofid_i,  \n                        ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:20: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\n        input  wire    [`RV_SOFID_RANGE] pfu_sofid_i,  \n                                       ^\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:22: syntax error, unexpected input, expecting IDENTIFIER or do or final\n        input  wire                      pfu_ferr_i,   \n        ^~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:23: syntax error, unexpected input, expecting IDENTIFIER or do or final\n        input  wire       [`RV_XLEN-1:0] pfu_pc_i,     \n        ^~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:23: Define or directive not defined: \'`RV_XLEN\'\n        input  wire       [`RV_XLEN-1:0] pfu_pc_i,     \n                           ^~~~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:25: syntax error, unexpected output, expecting IDENTIFIER or do or final\n        output reg        [`RV_XLEN-1:0] exs_ins_o,\n        ^~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:25: Define or directive not defined: \'`RV_XLEN\'\n        output reg        [`RV_XLEN-1:0] exs_ins_o,\n                           ^~~~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:26: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n        output reg                       exs_valid_o,\n        ^~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:27: syntax error, unexpected input, expecting IDENTIFIER or \'=\' or do or final\n        input  wire                      exs_stall_i,\n        ^~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:28: syntax error, unexpected output, expecting IDENTIFIER or do or final\n        output reg     [`RV_SOFID_RANGE] exs_sofid_o,\n        ^~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:28: Define or directive not defined: \'`RV_SOFID_RANGE\'\n        output reg     [`RV_SOFID_RANGE] exs_sofid_o,\n                        ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:30: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n        output reg                       exs_ins_uerr_o,\n        ^~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:31: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n        output reg                       exs_ins_ferr_o,\n        ^~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:32: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n        output reg                       exs_fencei_o,\n        ^~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:33: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n        output reg                       exs_wfi_o,\n        ^~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:34: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n        output reg                       exs_jump_o,\n        ^~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:35: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n        output reg                       exs_ecall_o,\n        ^~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:36: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n        output reg                       exs_trap_rtn_o,\n        ^~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:37: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n        output reg                 [1:0] exs_trap_rtn_mode_o,\n        ^~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:38: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n        output reg                       exs_cond_o,\n        ^~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:39: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n        output reg      [`RV_ZONE_RANGE] exs_zone_o,\n        ^~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:39: Define or directive not defined: \'`RV_ZONE_RANGE\'\n        output reg      [`RV_ZONE_RANGE] exs_zone_o,\n                         ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:41: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n        output wire       [`RV_XLEN-1:0] exs_pc_o,\n        ^~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:41: Define or directive not defined: \'`RV_XLEN\'\n        output wire       [`RV_XLEN-1:0] exs_pc_o,\n                           ^~~~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:42: syntax error, unexpected output, expecting IDENTIFIER or do or final\n        output reg     [`RV_ALUOP_RANGE] exs_alu_op_o,\n        ^~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:42: Define or directive not defined: \'`RV_ALUOP_RANGE\'\n        output reg     [`RV_ALUOP_RANGE] exs_alu_op_o,\n                        ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:43: Define or directive not defined: \'`RV_XLEN\'\n        output reg        [`RV_XLEN-1:0] exs_operand_left_o,\n                           ^~~~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:44: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n        output reg        [`RV_XLEN-1:0] exs_operand_right_o,\n        ^~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:44: Define or directive not defined: \'`RV_XLEN\'\n        output reg        [`RV_XLEN-1:0] exs_operand_right_o,\n                           ^~~~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:45: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n        output reg        [`RV_XLEN-1:0] exs_cmp_right_o,\n        ^~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:45: Define or directive not defined: \'`RV_XLEN\'\n        output reg        [`RV_XLEN-1:0] exs_cmp_right_o,\n                           ^~~~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:46: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n        output wire       [`RV_XLEN-1:0] exs_regs1_data_o,\n        ^~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:46: Define or directive not defined: \'`RV_XLEN\'\n        output wire       [`RV_XLEN-1:0] exs_regs1_data_o,\n                           ^~~~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:47: syntax error, unexpected output, expecting IDENTIFIER or do or final\n        output wire       [`RV_XLEN-1:0] exs_regs2_data_o,\n        ^~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:47: Define or directive not defined: \'`RV_XLEN\'\n        output wire       [`RV_XLEN-1:0] exs_regs2_data_o,\n                           ^~~~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:48: syntax error, unexpected output, expecting IDENTIFIER or do or final\n        output reg                 [4:0] exs_regd_addr_o,\n        ^~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:49: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n        output reg                 [2:0] exs_funct3_o,\n        ^~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:50: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n        output reg                       exs_csr_rd_o,\n        ^~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:51: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n        output reg                       exs_csr_wr_o,\n        ^~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:52: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n        output reg                [11:0] exs_csr_addr_o,\n        ^~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:53: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n        output reg        [`RV_XLEN-1:0] exs_csr_wr_data_o,\n        ^~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:53: Define or directive not defined: \'`RV_XLEN\'\n        output reg        [`RV_XLEN-1:0] exs_csr_wr_data_o,\n                           ^~~~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:55: syntax error, unexpected input, expecting IDENTIFIER or \'=\' or do or final\n        input  wire                      exs_regd_cncl_load_i,\n        ^~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:56: syntax error, unexpected input, expecting IDENTIFIER or do or final\n        input  wire                      exs_regd_wr_i,\n        ^~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:57: syntax error, unexpected input, expecting IDENTIFIER or do or final\n        input  wire                [4:0] exs_regd_addr_i,\n        ^~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:58: syntax error, unexpected input, expecting IDENTIFIER or do or final\n        input  wire       [`RV_XLEN-1:0] exs_regd_data_i,\n        ^~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:58: Define or directive not defined: \'`RV_XLEN\'\n        input  wire       [`RV_XLEN-1:0] exs_regd_data_i,\n                           ^~~~~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:60: syntax error, unexpected input, expecting IDENTIFIER or do or final\n        input  wire                      lsq_reg_wr_i,\n        ^~~~~\n%Error: data/full_repos/permissive/151207731/rv32i/rtl/merlin_id_stage.v:61: syntax error, unexpected input, expecting IDENTIFIER or do or final\n        input  wire                [4:0] lsq_reg_addr_i,\n        ^~~~~\n%Error: Exiting due to too many errors encountered; --error-limit=50\n'
module merlin_id_stage
    (

        input  wire                      clk_i,
        input  wire                      reset_i,

        input  wire                      pfu_dav_i,
        output wire                      pfu_ack_o,
        output reg                 [1:0] pfu_ack_size_o,
        input  wire    [`RV_SOFID_RANGE] pfu_sofid_i,
        input  wire               [31:0] pfu_ins_i,
        input  wire                      pfu_ferr_i,
        input  wire       [`RV_XLEN-1:0] pfu_pc_i,

        output reg        [`RV_XLEN-1:0] exs_ins_o,
        output reg                       exs_valid_o,
        input  wire                      exs_stall_i,
        output reg     [`RV_SOFID_RANGE] exs_sofid_o,
        output reg                 [1:0] exs_ins_size_o,
        output reg                       exs_ins_uerr_o,
        output reg                       exs_ins_ferr_o,
        output reg                       exs_fencei_o,
        output reg                       exs_wfi_o,
        output reg                       exs_jump_o,
        output reg                       exs_ecall_o,
        output reg                       exs_trap_rtn_o,
        output reg                 [1:0] exs_trap_rtn_mode_o,
        output reg                       exs_cond_o,
        output reg      [`RV_ZONE_RANGE] exs_zone_o,
        output reg                       exs_link_o,
        output wire       [`RV_XLEN-1:0] exs_pc_o,
        output reg     [`RV_ALUOP_RANGE] exs_alu_op_o,
        output reg        [`RV_XLEN-1:0] exs_operand_left_o,
        output reg        [`RV_XLEN-1:0] exs_operand_right_o,
        output reg        [`RV_XLEN-1:0] exs_cmp_right_o,
        output wire       [`RV_XLEN-1:0] exs_regs1_data_o,
        output wire       [`RV_XLEN-1:0] exs_regs2_data_o,
        output reg                 [4:0] exs_regd_addr_o,
        output reg                 [2:0] exs_funct3_o,
        output reg                       exs_csr_rd_o,
        output reg                       exs_csr_wr_o,
        output reg                [11:0] exs_csr_addr_o,
        output reg        [`RV_XLEN-1:0] exs_csr_wr_data_o,

        input  wire                      exs_regd_cncl_load_i,
        input  wire                      exs_regd_wr_i,
        input  wire                [4:0] exs_regd_addr_i,
        input  wire       [`RV_XLEN-1:0] exs_regd_data_i,

        input  wire                      lsq_reg_wr_i,
        input  wire                [4:0] lsq_reg_addr_i,
        input  wire       [`RV_XLEN-1:0] lsq_reg_data_i
    );





    wire                     id_stage_en;
    wire                     exs_stall;

    wire                     ins_expanded_valid;
    wire                     rv32ic_ins_uerr;
    wire              [31:0] ins_expanded;

    wire                     ins_uerr_d;
    reg               [31:0] rv32i_ins;

    wire                     rv32i_ins_uerr;
    wire                     fencei_d;
    wire                     wfi_d;
    wire                     jump_d;
    wire                     ecall_d;
    wire                     trap_rtn_d;
    wire               [1:0] trap_rtn_mode_d;
    wire    [`RV_ZONE_RANGE] zone_d;
    wire                     regd_tgt;
    wire               [4:0] regd_addr_d;
    wire                     regs1_rd_d;
    wire               [4:0] regs1_addr_d;
    wire                     regs2_rd_d;
    wire               [4:0] regs2_addr_d;
    wire      [`RV_XLEN-1:0] imm_d;
    wire                     link_d;
    wire                     sels1_pc_d;
    wire                     sel_csr_wr_data_imm_d;
    wire                     sels2_imm_d;
    wire                     selcmps2_imm_d;
    wire   [`RV_ALUOP_RANGE] alu_op_d;
    wire               [2:0] funct3_d;
    wire                     csr_rd_d;
    wire                     csr_wr_d;
    wire              [11:0] csr_addr_d;
    wire                     conditional_d;

    wire                     s1_lq_fwd_available;
    wire                     s2_lq_fwd_available;
    reg                      ids_stall;
    reg               [31:1] reg_loading_vector_q;

    wire      [`RV_XLEN-1:0] regs1_dout;
    wire      [`RV_XLEN-1:0] regs2_dout;

    reg       [`RV_XLEN-1:0] pc_q;
    reg       [`RV_XLEN-1:0] imm_q;
    reg                      sels1_pc_q;
    reg                      sel_csr_wr_data_imm_q;
    reg                      sels2_imm_q;
    reg                      selcmps2_imm_q;
    reg                      regs1_rd_q;
    reg                [4:0] regs1_addr_q;
    reg                      regs2_rd_q;
    reg                [4:0] regs2_addr_q;

    reg       [`RV_XLEN-1:0] fwd_mux_regs1_data;
    reg       [`RV_XLEN-1:0] fwd_mux_regs2_data;










    assign exs_pc_o         = pc_q;
    assign exs_regs1_data_o = fwd_mux_regs1_data;
    assign exs_regs2_data_o = fwd_mux_regs2_data;





    assign pfu_ack_o    = pfu_dav_i & ~ids_stall & ~exs_stall;
    assign id_stage_en  = pfu_ack_o;
    assign exs_stall    = exs_stall_i & exs_valid_o;





    merlin_rv32ic_expander i_merlin_rv32ic_expander (
            .ins_i     (pfu_ins_i[15:0]),
            .ins_rvc_o (ins_expanded_valid),
            .ins_err_o (rv32ic_ins_uerr),
            .ins_o     (ins_expanded)
        );





    assign ins_uerr_d = rv32i_ins_uerr | (ins_expanded_valid & rv32ic_ins_uerr);

    always @ (*) begin
        if (ins_expanded_valid) begin
            pfu_ack_size_o = 2'b01;
            rv32i_ins      = ins_expanded;
        end else begin
            pfu_ack_size_o = 2'b10;
            rv32i_ins      = pfu_ins_i;
        end
    end





    merlin_rv32i_decoder i_merlin_rv32i_decoder (


            .ins_i                 (rv32i_ins),

            .ins_err_o             (rv32i_ins_uerr),
            .fencei_o              (fencei_d),
            .wfi_o                 (wfi_d),
            .jump_o                (jump_d),
            .ecall_o               (ecall_d),
            .trap_rtn_o            (trap_rtn_d),
            .trap_rtn_mode_o       (trap_rtn_mode_d),
            .zone_o                (zone_d),
            .regd_tgt_o            (regd_tgt),
            .regd_addr_o           (regd_addr_d),
            .regs1_rd_o            (regs1_rd_d),
            .regs1_addr_o          (regs1_addr_d),
            .regs2_rd_o            (regs2_rd_d),
            .regs2_addr_o          (regs2_addr_d),
            .imm_o                 (imm_d),
            .link_o                (link_d),
            .sels1_pc_o            (sels1_pc_d),
            .sel_csr_wr_data_imm_o (sel_csr_wr_data_imm_d),
            .sels2_imm_o           (sels2_imm_d),
            .selcmps2_imm_o        (selcmps2_imm_d),
            .aluop_o               (alu_op_d),
            .funct3_o              (funct3_d),
            .csr_rd_o              (csr_rd_d),
            .csr_wr_o              (csr_wr_d),
            .csr_addr_o            (csr_addr_d),
            .conditional_o         (conditional_d)
        );






    assign s1_lq_fwd_available = (lsq_reg_wr_i && (lsq_reg_addr_i == regs1_addr_d));
    assign s2_lq_fwd_available = (lsq_reg_wr_i && (lsq_reg_addr_i == regs2_addr_d));

    always @ (*) begin
        ids_stall = 1'b0;

        if (pfu_dav_i) begin

            if (regs1_addr_d != 5'b0 && regs1_rd_d &&
                reg_loading_vector_q[regs1_addr_d] && !s1_lq_fwd_available) begin
                ids_stall = 1'b1;
            end

            if (regs2_addr_d != 5'b0 && regs2_rd_d &&
                reg_loading_vector_q[regs2_addr_d] && !s2_lq_fwd_available) begin
                ids_stall = 1'b1;
            end

            if (regd_addr_d != 5'b0 && regd_tgt && reg_loading_vector_q[regd_addr_d]) begin
                ids_stall = 1'b1;
            end
        end
    end

    always @ `RV_SYNC_LOGIC_CLOCK_RESET(clk_i, reset_i) begin
        if (reset_i) begin
            reg_loading_vector_q <= 31'b0;
        end else begin
            if (regd_addr_d != 5'b0 && id_stage_en && zone_d == `RV_ZONE_LOADQ) begin
                `RV_ASSERT(reg_loading_vector_q[regd_addr_d] == 1'b0, "Register marked as pending load when already pending.")
                reg_loading_vector_q[regd_addr_d] <= 1'b1;
            end
            if (exs_regd_addr_i != 5'b0 && exs_regd_cncl_load_i) begin
                `RV_ASSERT(reg_loading_vector_q[exs_regd_addr_i] == 1'b1, "Load canceled when not pending.")
                reg_loading_vector_q[exs_regd_addr_i] <= 1'b0;
            end
            if (lsq_reg_addr_i != 5'b0 && lsq_reg_wr_i) begin
                `RV_ASSERT(reg_loading_vector_q[lsq_reg_addr_i] == 1'b1, "Load written when not pending.")
                reg_loading_vector_q[lsq_reg_addr_i] <= 1'b0;
            end
        end
    end





    merlin_int_regs i_merlin_int_regs (

            .clk_i         (clk_i),
            .reset_i       (reset_i),

            .wreg_a_wr_i   (exs_regd_wr_i),
            .wreg_a_addr_i (exs_regd_addr_i),
            .wreg_a_data_i (exs_regd_data_i),
            .wreg_b_wr_i   (lsq_reg_wr_i),
            .wreg_b_addr_i (lsq_reg_addr_i),
            .wreg_b_data_i (lsq_reg_data_i),

            .rreg_a_rd_i   (regs1_rd_q),
            .rreg_a_addr_i (regs1_addr_q),
            .rreg_a_data_o (regs1_dout),
            .rreg_b_rd_i   (regs2_rd_q),
            .rreg_b_addr_i (regs2_addr_q),
            .rreg_b_data_o (regs2_dout)
        );





    always @ `RV_SYNC_LOGIC_CLOCK_RESET(clk_i, reset_i) begin
        if (reset_i) begin
            exs_valid_o <= 1'b0;
        end else begin
            if (id_stage_en) begin
                exs_valid_o <= 1'b1;
            end else if (~exs_stall) begin
                exs_valid_o <= 1'b0;
            end
        end
    end
    always @ `RV_SYNC_LOGIC_CLOCK(clk_i) begin
        if (id_stage_en) begin
            exs_ins_o             <= { { `RV_XLEN-32 {1'b0} }, pfu_ins_i };
            exs_sofid_o           <= pfu_sofid_i;
            exs_fencei_o          <= fencei_d;
            exs_wfi_o             <= wfi_d;
            exs_jump_o            <= jump_d;
            exs_ecall_o           <= ecall_d;
            exs_trap_rtn_o        <= trap_rtn_d;
            exs_trap_rtn_mode_o   <= trap_rtn_mode_d;
            pc_q                  <= pfu_pc_i;
            exs_ins_size_o        <= pfu_ack_size_o;
            exs_ins_uerr_o        <= ins_uerr_d;
            exs_ins_ferr_o        <= pfu_ferr_i;
            exs_zone_o            <= zone_d;
            exs_regd_addr_o       <= regd_addr_d;
            imm_q                 <= imm_d;
            exs_link_o            <= link_d;
            sels1_pc_q            <= sels1_pc_d;
            sel_csr_wr_data_imm_q <= sel_csr_wr_data_imm_d;
            sels2_imm_q           <= sels2_imm_d;
            selcmps2_imm_q        <= selcmps2_imm_d;
            exs_alu_op_o          <= alu_op_d;
            exs_funct3_o          <= funct3_d;
            exs_csr_rd_o          <= csr_rd_d;
            exs_csr_wr_o          <= csr_wr_d;
            exs_csr_addr_o        <= csr_addr_d;
            exs_cond_o            <= conditional_d;

            regs1_rd_q            <= regs1_rd_d;
            regs1_addr_q          <= regs1_addr_d;
            regs2_rd_q            <= regs2_rd_d;
            regs2_addr_q          <= regs2_addr_d;
        end
    end






    always @ (*) begin
        if (regs1_addr_q == 5'b0) begin

            fwd_mux_regs1_data = regs1_dout;
        end else if (exs_regd_wr_i && exs_regd_addr_i == regs1_addr_q) begin

            fwd_mux_regs1_data = exs_regd_data_i;
        end else if (lsq_reg_wr_i && lsq_reg_addr_i == regs1_addr_q) begin

            fwd_mux_regs1_data = lsq_reg_data_i;
        end else begin

            fwd_mux_regs1_data = regs1_dout;
        end
    end

    always @ (*) begin
        if (regs2_addr_q == 5'b0) begin

            fwd_mux_regs2_data = regs2_dout;
        end else if (exs_regd_wr_i && exs_regd_addr_i == regs2_addr_q) begin

            fwd_mux_regs2_data = exs_regd_data_i;
        end else if (lsq_reg_wr_i && lsq_reg_addr_i == regs2_addr_q) begin

            fwd_mux_regs2_data = lsq_reg_data_i;
        end else begin

            fwd_mux_regs2_data = regs2_dout;
        end
    end





    always @ (*) begin
        if (sels1_pc_q) begin
            exs_operand_left_o = pc_q;
        end else begin
            exs_operand_left_o = fwd_mux_regs1_data;
        end
    end





    always @ (*) begin
        if (sels2_imm_q) begin
            exs_operand_right_o = imm_q;
        end else begin
            exs_operand_right_o = fwd_mux_regs2_data;
        end
    end





    always @ (*) begin
        if (selcmps2_imm_q) begin
            exs_cmp_right_o = imm_q;
        end else begin
            exs_cmp_right_o = fwd_mux_regs2_data;
        end
    end





    always @ (*) begin
        if (sel_csr_wr_data_imm_q) begin
            exs_csr_wr_data_o = imm_q;
        end else begin
            exs_csr_wr_data_o = fwd_mux_regs1_data;
        end
    end





`ifdef RV_ASSERTS_ON
    always @ `RV_SYNC_LOGIC_CLOCK(clk_i) begin

        `RV_ASSERT(
            !(pfu_ack_o == 1'b1 &&
              regs1_addr_d != 5'b0 && regs1_rd_d &&
              reg_loading_vector_q[regs1_addr_d] && !s1_lq_fwd_available),
            "Register read when pending a load."
        )

        `RV_ASSERT(
            !(pfu_ack_o == 1'b1 &&
              regs2_addr_d != 5'b0 && regs2_rd_d &&
              reg_loading_vector_q[regs2_addr_d] && !s2_lq_fwd_available),
            "Register read when pending a load."
        )
    end
`endif
endmodule
module merlin_id_stage
    (

        input  wire                      clk_i,
        input  wire                      reset_i,

        input  wire                      pfu_dav_i,
        output wire                      pfu_ack_o,
        output reg                 [1:0] pfu_ack_size_o,
        input  wire    [`RV_SOFID_RANGE] pfu_sofid_i,
        input  wire               [31:0] pfu_ins_i,
        input  wire                      pfu_ferr_i,
        input  wire       [`RV_XLEN-1:0] pfu_pc_i,

        output reg        [`RV_XLEN-1:0] exs_ins_o,
        output reg                       exs_valid_o,
        input  wire                      exs_stall_i,
        output reg     [`RV_SOFID_RANGE] exs_sofid_o,
        output reg                 [1:0] exs_ins_size_o,
        output reg                       exs_ins_uerr_o,
        output reg                       exs_ins_ferr_o,
        output reg                       exs_fencei_o,
        output reg                       exs_wfi_o,
        output reg                       exs_jump_o,
        output reg                       exs_ecall_o,
        output reg                       exs_trap_rtn_o,
        output reg                 [1:0] exs_trap_rtn_mode_o,
        output reg                       exs_cond_o,
        output reg      [`RV_ZONE_RANGE] exs_zone_o,
        output reg                       exs_link_o,
        output wire       [`RV_XLEN-1:0] exs_pc_o,
        output reg     [`RV_ALUOP_RANGE] exs_alu_op_o,
        output reg        [`RV_XLEN-1:0] exs_operand_left_o,
        output reg        [`RV_XLEN-1:0] exs_operand_right_o,
        output reg        [`RV_XLEN-1:0] exs_cmp_right_o,
        output wire       [`RV_XLEN-1:0] exs_regs1_data_o,
        output wire       [`RV_XLEN-1:0] exs_regs2_data_o,
        output reg                 [4:0] exs_regd_addr_o,
        output reg                 [2:0] exs_funct3_o,
        output reg                       exs_csr_rd_o,
        output reg                       exs_csr_wr_o,
        output reg                [11:0] exs_csr_addr_o,
        output reg        [`RV_XLEN-1:0] exs_csr_wr_data_o,

        input  wire                      exs_regd_cncl_load_i,
        input  wire                      exs_regd_wr_i,
        input  wire                [4:0] exs_regd_addr_i,
        input  wire       [`RV_XLEN-1:0] exs_regd_data_i,

        input  wire                      lsq_reg_wr_i,
        input  wire                [4:0] lsq_reg_addr_i,
        input  wire       [`RV_XLEN-1:0] lsq_reg_data_i
    );






    wire                     id_stage_en;
    wire                     exs_stall;

    wire                     ins_expanded_valid;
    wire                     rv32ic_ins_uerr;
    wire              [31:0] ins_expanded;

    wire                     ins_uerr_d;
    reg               [31:0] rv32i_ins;

    wire                     rv32i_ins_uerr;
    wire                     fencei_d;
    wire                     wfi_d;
    wire                     jump_d;
    wire                     ecall_d;
    wire                     trap_rtn_d;
    wire               [1:0] trap_rtn_mode_d;
    wire    [`RV_ZONE_RANGE] zone_d;
    wire                     regd_tgt;
    wire               [4:0] regd_addr_d;
    wire                     regs1_rd_d;
    wire               [4:0] regs1_addr_d;
    wire                     regs2_rd_d;
    wire               [4:0] regs2_addr_d;
    wire      [`RV_XLEN-1:0] imm_d;
    wire                     link_d;
    wire                     sels1_pc_d;
    wire                     sel_csr_wr_data_imm_d;
    wire                     sels2_imm_d;
    wire                     selcmps2_imm_d;
    wire   [`RV_ALUOP_RANGE] alu_op_d;
    wire               [2:0] funct3_d;
    wire                     csr_rd_d;
    wire                     csr_wr_d;
    wire              [11:0] csr_addr_d;
    wire                     conditional_d;

    wire                     s1_lq_fwd_available;
    wire                     s2_lq_fwd_available;
    reg                      ids_stall;
    reg               [31:1] reg_loading_vector_q;

    wire      [`RV_XLEN-1:0] regs1_dout;
    wire      [`RV_XLEN-1:0] regs2_dout;

    reg       [`RV_XLEN-1:0] pc_q;
    reg       [`RV_XLEN-1:0] imm_q;
    reg                      sels1_pc_q;
    reg                      sel_csr_wr_data_imm_q;
    reg                      sels2_imm_q;
    reg                      selcmps2_imm_q;
    reg                      regs1_rd_q;
    reg                [4:0] regs1_addr_q;
    reg                      regs2_rd_q;
    reg                [4:0] regs2_addr_q;

    reg       [`RV_XLEN-1:0] fwd_mux_regs1_data;
    reg       [`RV_XLEN-1:0] fwd_mux_regs2_data;










    assign exs_pc_o         = pc_q;
    assign exs_regs1_data_o = fwd_mux_regs1_data;
    assign exs_regs2_data_o = fwd_mux_regs2_data;





    assign pfu_ack_o    = pfu_dav_i & ~ids_stall & ~exs_stall;
    assign id_stage_en  = pfu_ack_o;
    assign exs_stall    = exs_stall_i & exs_valid_o;





    merlin_rv32ic_expander i_merlin_rv32ic_expander (
            .ins_i     (pfu_ins_i[15:0]),
            .ins_rvc_o (ins_expanded_valid),
            .ins_err_o (rv32ic_ins_uerr),
            .ins_o     (ins_expanded)
        );





    assign ins_uerr_d = rv32i_ins_uerr | (ins_expanded_valid & rv32ic_ins_uerr);

    always @ (*) begin
        if (ins_expanded_valid) begin
            pfu_ack_size_o = 2'b01;
            rv32i_ins      = ins_expanded;
        end else begin
            pfu_ack_size_o = 2'b10;
            rv32i_ins      = pfu_ins_i;
        end
    end





    merlin_rv32i_decoder i_merlin_rv32i_decoder (


            .ins_i                 (rv32i_ins),

            .ins_err_o             (rv32i_ins_uerr),
            .fencei_o              (fencei_d),
            .wfi_o                 (wfi_d),
            .jump_o                (jump_d),
            .ecall_o               (ecall_d),
            .trap_rtn_o            (trap_rtn_d),
            .trap_rtn_mode_o       (trap_rtn_mode_d),
            .zone_o                (zone_d),
            .regd_tgt_o            (regd_tgt),
            .regd_addr_o           (regd_addr_d),
            .regs1_rd_o            (regs1_rd_d),
            .regs1_addr_o          (regs1_addr_d),
            .regs2_rd_o            (regs2_rd_d),
            .regs2_addr_o          (regs2_addr_d),
            .imm_o                 (imm_d),
            .link_o                (link_d),
            .sels1_pc_o            (sels1_pc_d),
            .sel_csr_wr_data_imm_o (sel_csr_wr_data_imm_d),
            .sels2_imm_o           (sels2_imm_d),
            .selcmps2_imm_o        (selcmps2_imm_d),
            .aluop_o               (alu_op_d),
            .funct3_o              (funct3_d),
            .csr_rd_o              (csr_rd_d),
            .csr_wr_o              (csr_wr_d),
            .csr_addr_o            (csr_addr_d),
            .conditional_o         (conditional_d)
        );






    assign s1_lq_fwd_available = (lsq_reg_wr_i && (lsq_reg_addr_i == regs1_addr_d));
    assign s2_lq_fwd_available = (lsq_reg_wr_i && (lsq_reg_addr_i == regs2_addr_d));

    always @ (*) begin
        ids_stall = 1'b0;

        if (pfu_dav_i) begin

            if (regs1_addr_d != 5'b0 && regs1_rd_d &&
                reg_loading_vector_q[regs1_addr_d] && !s1_lq_fwd_available) begin
                ids_stall = 1'b1;
            end

            if (regs2_addr_d != 5'b0 && regs2_rd_d &&
                reg_loading_vector_q[regs2_addr_d] && !s2_lq_fwd_available) begin
                ids_stall = 1'b1;
            end

            if (regd_addr_d != 5'b0 && regd_tgt && reg_loading_vector_q[regd_addr_d]) begin
                ids_stall = 1'b1;
            end
        end
    end

    always @ `RV_SYNC_LOGIC_CLOCK_RESET(clk_i, reset_i) begin
        if (reset_i) begin
            reg_loading_vector_q <= 31'b0;
        end else begin
            if (regd_addr_d != 5'b0 && id_stage_en && zone_d == `RV_ZONE_LOADQ) begin
                `RV_ASSERT(reg_loading_vector_q[regd_addr_d] == 1'b0, "Register marked as pending load when already pending.")
                reg_loading_vector_q[regd_addr_d] <= 1'b1;
            end
            if (exs_regd_addr_i != 5'b0 && exs_regd_cncl_load_i) begin
                `RV_ASSERT(reg_loading_vector_q[exs_regd_addr_i] == 1'b1, "Load canceled when not pending.")
                reg_loading_vector_q[exs_regd_addr_i] <= 1'b0;
            end
            if (lsq_reg_addr_i != 5'b0 && lsq_reg_wr_i) begin
                `RV_ASSERT(reg_loading_vector_q[lsq_reg_addr_i] == 1'b1, "Load written when not pending.")
                reg_loading_vector_q[lsq_reg_addr_i] <= 1'b0;
            end
        end
    end





    merlin_int_regs i_merlin_int_regs (

            .clk_i         (clk_i),
            .reset_i       (reset_i),

            .wreg_a_wr_i   (exs_regd_wr_i),
            .wreg_a_addr_i (exs_regd_addr_i),
            .wreg_a_data_i (exs_regd_data_i),
            .wreg_b_wr_i   (lsq_reg_wr_i),
            .wreg_b_addr_i (lsq_reg_addr_i),
            .wreg_b_data_i (lsq_reg_data_i),

            .rreg_a_rd_i   (regs1_rd_q),
            .rreg_a_addr_i (regs1_addr_q),
            .rreg_a_data_o (regs1_dout),
            .rreg_b_rd_i   (regs2_rd_q),
            .rreg_b_addr_i (regs2_addr_q),
            .rreg_b_data_o (regs2_dout)
        );





    always @ `RV_SYNC_LOGIC_CLOCK_RESET(clk_i, reset_i) begin
        if (reset_i) begin
            exs_valid_o <= 1'b0;
        end else begin
            if (id_stage_en) begin
                exs_valid_o <= 1'b1;
            end else if (~exs_stall) begin
                exs_valid_o <= 1'b0;
            end
        end
    end
    always @ `RV_SYNC_LOGIC_CLOCK(clk_i) begin
        if (id_stage_en) begin
            exs_ins_o             <= { { `RV_XLEN-32 {1'b0} }, pfu_ins_i };
            exs_sofid_o           <= pfu_sofid_i;
            exs_fencei_o          <= fencei_d;
            exs_wfi_o             <= wfi_d;
            exs_jump_o            <= jump_d;
            exs_ecall_o           <= ecall_d;
            exs_trap_rtn_o        <= trap_rtn_d;
            exs_trap_rtn_mode_o   <= trap_rtn_mode_d;
            pc_q                  <= pfu_pc_i;
            exs_ins_size_o        <= pfu_ack_size_o;
            exs_ins_uerr_o        <= ins_uerr_d;
            exs_ins_ferr_o        <= pfu_ferr_i;
            exs_zone_o            <= zone_d;
            exs_regd_addr_o       <= regd_addr_d;
            imm_q                 <= imm_d;
            exs_link_o            <= link_d;
            sels1_pc_q            <= sels1_pc_d;
            sel_csr_wr_data_imm_q <= sel_csr_wr_data_imm_d;
            sels2_imm_q           <= sels2_imm_d;
            selcmps2_imm_q        <= selcmps2_imm_d;
            exs_alu_op_o          <= alu_op_d;
            exs_funct3_o          <= funct3_d;
            exs_csr_rd_o          <= csr_rd_d;
            exs_csr_wr_o          <= csr_wr_d;
            exs_csr_addr_o        <= csr_addr_d;
            exs_cond_o            <= conditional_d;

            regs1_rd_q            <= regs1_rd_d;
            regs1_addr_q          <= regs1_addr_d;
            regs2_rd_q            <= regs2_rd_d;
            regs2_addr_q          <= regs2_addr_d;
        end
    end






    always @ (*) begin
        if (regs1_addr_q == 5'b0) begin

            fwd_mux_regs1_data = regs1_dout;
        end else if (exs_regd_wr_i && exs_regd_addr_i == regs1_addr_q) begin

            fwd_mux_regs1_data = exs_regd_data_i;
        end else if (lsq_reg_wr_i && lsq_reg_addr_i == regs1_addr_q) begin

            fwd_mux_regs1_data = lsq_reg_data_i;
        end else begin

            fwd_mux_regs1_data = regs1_dout;
        end
    end

    always @ (*) begin
        if (regs2_addr_q == 5'b0) begin

            fwd_mux_regs2_data = regs2_dout;
        end else if (exs_regd_wr_i && exs_regd_addr_i == regs2_addr_q) begin

            fwd_mux_regs2_data = exs_regd_data_i;
        end else if (lsq_reg_wr_i && lsq_reg_addr_i == regs2_addr_q) begin

            fwd_mux_regs2_data = lsq_reg_data_i;
        end else begin

            fwd_mux_regs2_data = regs2_dout;
        end
    end





    always @ (*) begin
        if (sels1_pc_q) begin
            exs_operand_left_o = pc_q;
        end else begin
            exs_operand_left_o = fwd_mux_regs1_data;
        end
    end





    always @ (*) begin
        if (sels2_imm_q) begin
            exs_operand_right_o = imm_q;
        end else begin
            exs_operand_right_o = fwd_mux_regs2_data;
        end
    end





    always @ (*) begin
        if (selcmps2_imm_q) begin
            exs_cmp_right_o = imm_q;
        end else begin
            exs_cmp_right_o = fwd_mux_regs2_data;
        end
    end





    always @ (*) begin
        if (sel_csr_wr_data_imm_q) begin
            exs_csr_wr_data_o = imm_q;
        end else begin
            exs_csr_wr_data_o = fwd_mux_regs1_data;
        end
    end





`ifdef RV_ASSERTS_ON
    always @ `RV_SYNC_LOGIC_CLOCK(clk_i) begin

        `RV_ASSERT(
            !(pfu_ack_o == 1'b1 &&
              regs1_addr_d != 5'b0 && regs1_rd_d &&
              reg_loading_vector_q[regs1_addr_d] && !s1_lq_fwd_available),
            "Register read when pending a load."
        )

        `RV_ASSERT(
            !(pfu_ack_o == 1'b1 &&
              regs2_addr_d != 5'b0 && regs2_rd_d &&
              reg_loading_vector_q[regs2_addr_d] && !s2_lq_fwd_available),
            "Register read when pending a load."
        )
    end
`endif
endmodule