data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv
1: b'%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:1: Cannot find include file: VX_define.vh\n`include "VX_define.vh" \n         ^~~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/473423187/hw/rtl,data/full_repos/permissive/473423187/VX_define.vh\n             data/full_repos/permissive/473423187/hw/rtl,data/full_repos/permissive/473423187/VX_define.vh.v\n             data/full_repos/permissive/473423187/hw/rtl,data/full_repos/permissive/473423187/VX_define.vh.sv\n             VX_define.vh\n             VX_define.vh.v\n             VX_define.vh.sv\n             obj_dir/VX_define.vh\n             obj_dir/VX_define.vh.v\n             obj_dir/VX_define.vh.sv\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:8: Define or directive not defined: \'`INST_MUL_BITS\'\n    input wire [`INST_MUL_BITS-1:0]     alu_op,\n                ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:9: Define or directive not defined: \'`NW_BITS\'\n    input wire [`NW_BITS-1:0]           wid_in,\n                ^~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:10: Define or directive not defined: \'`NUM_THREADS\'\n    input wire [`NUM_THREADS-1:0]       tmask_in,\n                ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:12: Define or directive not defined: \'`NR_BITS\'\n    input wire [`NR_BITS-1:0]           rd_in,\n                ^~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:14: Define or directive not defined: \'`NUM_THREADS\'\n    input wire [`NUM_THREADS-1:0][31:0] alu_in1, \n                ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:15: Define or directive not defined: \'`NUM_THREADS\'\n    input wire [`NUM_THREADS-1:0][31:0] alu_in2,\n                ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:18: Define or directive not defined: \'`NW_BITS\'\n    output wire [`NW_BITS-1:0]           wid_out,\n                 ^~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:19: Define or directive not defined: \'`NUM_THREADS\'\n    output wire [`NUM_THREADS-1:0]       tmask_out,\n                 ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:21: Define or directive not defined: \'`NR_BITS\'\n    output wire [`NR_BITS-1:0]           rd_out,\n                 ^~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:23: Define or directive not defined: \'`NUM_THREADS\'\n    output wire [`NUM_THREADS-1:0][31:0] data_out,\n                 ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:32: Define or directive not defined: \'`INST_MUL_IS_DIV\'\n    wire is_div_op = `INST_MUL_IS_DIV(alu_op);\n                     ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:34: Define or directive not defined: \'`NUM_THREADS\'\n    wire [`NUM_THREADS-1:0][31:0] mul_result;\n          ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:35: Define or directive not defined: \'`NW_BITS\'\n    wire [`NW_BITS-1:0] mul_wid_out;\n          ^~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:36: Define or directive not defined: \'`NUM_THREADS\'\n    wire [`NUM_THREADS-1:0] mul_tmask_out;\n          ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:38: Define or directive not defined: \'`NR_BITS\'\n    wire [`NR_BITS-1:0] mul_rd_out;\n          ^~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:47: Define or directive not defined: \'`INST_MUL_MUL\'\n    wire is_mulh_in      = (alu_op != `INST_MUL_MUL);\n                                      ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:47: syntax error, unexpected \')\', expecting TYPE-IDENTIFIER\n    wire is_mulh_in      = (alu_op != `INST_MUL_MUL);\n                                                   ^\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:48: Define or directive not defined: \'`INST_MUL_MULHU\'\n    wire is_signed_mul_a = (alu_op != `INST_MUL_MULHU);\n                                      ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:48: syntax error, unexpected \')\', expecting TYPE-IDENTIFIER\n    wire is_signed_mul_a = (alu_op != `INST_MUL_MULHU);\n                                                     ^\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:49: Define or directive not defined: \'`INST_MUL_MULHU\'\n    wire is_signed_mul_b = (alu_op != `INST_MUL_MULHU && alu_op != `INST_MUL_MULHSU);\n                                      ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:49: syntax error, unexpected &&, expecting TYPE-IDENTIFIER\n    wire is_signed_mul_b = (alu_op != `INST_MUL_MULHU && alu_op != `INST_MUL_MULHSU);\n                                                      ^~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:49: Define or directive not defined: \'`INST_MUL_MULHSU\'\n    wire is_signed_mul_b = (alu_op != `INST_MUL_MULHU && alu_op != `INST_MUL_MULHSU);\n                                                                   ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:81: Define or directive not defined: \'`NUM_THREADS\'\n    for (genvar i = 0; i < `NUM_THREADS; i++) begin\n                           ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:81: syntax error, unexpected \';\', expecting TYPE-IDENTIFIER\n    for (genvar i = 0; i < `NUM_THREADS; i++) begin\n                                       ^\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:84: Define or directive not defined: \'`IGNORE_UNUSED_BEGIN\'\n    `IGNORE_UNUSED_BEGIN\n    ^~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:86: Define or directive not defined: \'`IGNORE_UNUSED_END\'\n    `IGNORE_UNUSED_END\n    ^~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:93: Define or directive not defined: \'`LATENCY_IMUL\'\n            .LATENCY (`LATENCY_IMUL)\n                      ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:103: syntax error, unexpected end\n    end\n    ^~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:106: Define or directive not defined: \'`NW_BITS\'\n        .DATAW  (1 + `NW_BITS + `NUM_THREADS + 32 + `NR_BITS + 1 + 1),\n                     ^~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:106: Define or directive not defined: \'`NUM_THREADS\'\n        .DATAW  (1 + `NW_BITS + `NUM_THREADS + 32 + `NR_BITS + 1 + 1),\n                                ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:106: Define or directive not defined: \'`NR_BITS\'\n        .DATAW  (1 + `NW_BITS + `NUM_THREADS + 32 + `NR_BITS + 1 + 1),\n                                                    ^~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:107: Define or directive not defined: \'`LATENCY_IMUL\'\n        .DEPTH  (`LATENCY_IMUL),\n                 ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:121: Define or directive not defined: \'`NUM_THREADS\'\n    wire [`NUM_THREADS-1:0][31:0] div_result;\n          ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:122: Define or directive not defined: \'`NW_BITS\'\n    wire [`NW_BITS-1:0] div_wid_out;\n          ^~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:123: Define or directive not defined: \'`NUM_THREADS\'\n    wire [`NUM_THREADS-1:0] div_tmask_out;\n          ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:125: Define or directive not defined: \'`NR_BITS\'\n    wire [`NR_BITS-1:0] div_rd_out;\n          ^~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:128: Define or directive not defined: \'`INST_MUL_REM\'\n    wire is_rem_op_in  = (alu_op == `INST_MUL_REM) || (alu_op == `INST_MUL_REMU);\n                                    ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:128: syntax error, unexpected \')\', expecting TYPE-IDENTIFIER\n    wire is_rem_op_in  = (alu_op == `INST_MUL_REM) || (alu_op == `INST_MUL_REMU);\n                                                 ^\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:128: Define or directive not defined: \'`INST_MUL_REMU\'\n    wire is_rem_op_in  = (alu_op == `INST_MUL_REM) || (alu_op == `INST_MUL_REMU);\n                                                                 ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:129: Define or directive not defined: \'`INST_MUL_DIV\'\n    wire is_signed_div = (alu_op == `INST_MUL_DIV) || (alu_op == `INST_MUL_REM);     \n                                    ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:129: syntax error, unexpected \')\', expecting TYPE-IDENTIFIER\n    wire is_signed_div = (alu_op == `INST_MUL_DIV) || (alu_op == `INST_MUL_REM);     \n                                                 ^\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:129: Define or directive not defined: \'`INST_MUL_REM\'\n    wire is_signed_div = (alu_op == `INST_MUL_DIV) || (alu_op == `INST_MUL_REM);     \n                                                                 ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:165: Define or directive not defined: \'`NUM_THREADS\'\n    wire [`NUM_THREADS-1:0][31:0] div_result_tmp, rem_result_tmp;\n          ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:173: Define or directive not defined: \'`NUM_THREADS\'\n        .LANES  (`NUM_THREADS),\n                 ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:174: Define or directive not defined: \'`NW_BITS\'\n        .TAGW   (`NW_BITS + `NUM_THREADS + 32 + `NR_BITS + 1 + 1)\n                 ^~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:174: Define or directive not defined: \'`NUM_THREADS\'\n        .TAGW   (`NW_BITS + `NUM_THREADS + 32 + `NR_BITS + 1 + 1)\n                            ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:174: Define or directive not defined: \'`NR_BITS\'\n        .TAGW   (`NW_BITS + `NUM_THREADS + 32 + `NR_BITS + 1 + 1)\n                                                ^~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:198: Define or directive not defined: \'`NW_BITS\'\n    wire [`NW_BITS-1:0]     rsp_wid   = mul_valid_out ? mul_wid_out : div_wid_out;\n          ^~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_muldiv.sv:199: Define or directive not defined: \'`NUM_THREADS\'\n    wire [`NUM_THREADS-1:0] rsp_tmask = mul_valid_out ? mul_tmask_out : div_tmask_out;\n          ^~~~~~~~~~~~\n%Error: Exiting due to too many errors encountered; --error-limit=50\n'
module VX_muldiv (
    input wire clk,
    input wire reset,
    

    input wire [`INST_MUL_BITS-1:0]     alu_op,
    input wire [`NW_BITS-1:0]           wid_in,
    input wire [`NUM_THREADS-1:0]       tmask_in,
    input wire [31:0]                   PC_in,
    input wire [`NR_BITS-1:0]           rd_in,
    input wire                          wb_in,
    input wire [`NUM_THREADS-1:0][31:0] alu_in1, 
    input wire [`NUM_THREADS-1:0][31:0] alu_in2,


    output wire [`NW_BITS-1:0]           wid_out,
    output wire [`NUM_THREADS-1:0]       tmask_out,
    output wire [31:0]                   PC_out,
    output wire [`NR_BITS-1:0]           rd_out,
    output wire                          wb_out,
    output wire [`NUM_THREADS-1:0][31:0] data_out,


    input wire  valid_in,
    output wire ready_in,
    output wire valid_out,
    input wire  ready_out
); 

    wire is_div_op = `INST_MUL_IS_DIV(alu_op);

    wire [`NUM_THREADS-1:0][31:0] mul_result;
    wire [`NW_BITS-1:0] mul_wid_out;
    wire [`NUM_THREADS-1:0] mul_tmask_out;
    wire [31:0] mul_PC_out;
    wire [`NR_BITS-1:0] mul_rd_out;
    wire mul_wb_out;

    wire stall_out;

    wire mul_valid_out;
    wire mul_valid_in = valid_in && !is_div_op;    
    wire mul_ready_in = ~stall_out || ~mul_valid_out;

    wire is_mulh_in      = (alu_op != `INST_MUL_MUL);
    wire is_signed_mul_a = (alu_op != `INST_MUL_MULHU);
    wire is_signed_mul_b = (alu_op != `INST_MUL_MULHU && alu_op != `INST_MUL_MULHSU);

`ifdef IMUL_DPI

    wire [`NUM_THREADS-1:0][31:0] mul_result_tmp;  

    wire mul_fire_in = mul_valid_in && mul_ready_in;

    for (genvar i = 0; i < `NUM_THREADS; i++) begin
        wire [31:0] mul_resultl, mul_resulth;
        always @(*) begin        
            dpi_imul (mul_fire_in, alu_in1[i], alu_in2[i], is_signed_mul_a, is_signed_mul_b, mul_resultl, mul_resulth);
        end
        assign mul_result_tmp[i] = is_mulh_in ? mul_resulth : mul_resultl;
    end

    VX_shift_register #(
        .DATAW  (1 + `NW_BITS + `NUM_THREADS + 32 + `NR_BITS + 1 + (`NUM_THREADS * 32)),
        .DEPTH  (`LATENCY_IMUL),
        .RESETW (1)
    ) mul_shift_reg (
        .clk(clk),
        .reset    (reset),
        .enable   (mul_ready_in),
        .data_in  ({mul_valid_in,  wid_in,      tmask_in,       PC_in,      rd_in,      wb_in,      mul_result_tmp}),
        .data_out ({mul_valid_out, mul_wid_out, mul_tmask_out,  mul_PC_out, mul_rd_out, mul_wb_out, mul_result})
    );

`else      
    
    wire is_mulh_out;

    for (genvar i = 0; i < `NUM_THREADS; i++) begin
        wire [32:0] mul_in1 = {is_signed_mul_a & alu_in1[i][31], alu_in1[i]};
        wire [32:0] mul_in2 = {is_signed_mul_b & alu_in2[i][31], alu_in2[i]};
    `IGNORE_UNUSED_BEGIN
        wire [65:0] mul_result_tmp;
    `IGNORE_UNUSED_END

        VX_multiplier #(
            .WIDTHA  (33),
            .WIDTHB  (33),
            .WIDTHP  (66),
            .SIGNED  (1),
            .LATENCY (`LATENCY_IMUL)
        ) multiplier (
            .clk    (clk),
            .enable (mul_ready_in),
            .dataa  (mul_in1),
            .datab  (mul_in2),
            .result (mul_result_tmp)
        );

        assign mul_result[i] = is_mulh_out ? mul_result_tmp[63:32] : mul_result_tmp[31:0];
    end

    VX_shift_register #(
        .DATAW  (1 + `NW_BITS + `NUM_THREADS + 32 + `NR_BITS + 1 + 1),
        .DEPTH  (`LATENCY_IMUL),
        .RESETW (1)
    ) mul_shift_reg (
        .clk(clk),
        .reset    (reset),
        .enable   (mul_ready_in),
        .data_in  ({mul_valid_in,  wid_in,      tmask_in,       PC_in,      rd_in,      wb_in,      is_mulh_in}),
        .data_out ({mul_valid_out, mul_wid_out, mul_tmask_out,  mul_PC_out, mul_rd_out, mul_wb_out, is_mulh_out})
    );

`endif



    wire [`NUM_THREADS-1:0][31:0] div_result;
    wire [`NW_BITS-1:0] div_wid_out;
    wire [`NUM_THREADS-1:0] div_tmask_out;
    wire [31:0] div_PC_out;
    wire [`NR_BITS-1:0] div_rd_out;
    wire div_wb_out;

    wire is_rem_op_in  = (alu_op == `INST_MUL_REM) || (alu_op == `INST_MUL_REMU);
    wire is_signed_div = (alu_op == `INST_MUL_DIV) || (alu_op == `INST_MUL_REM);     
    wire div_valid_in  = valid_in && is_div_op; 
    wire div_ready_out = ~stall_out && ~mul_valid_out;
    wire div_ready_in;
    wire div_valid_out;

`ifdef IDIV_DPI    

    wire [`NUM_THREADS-1:0][31:0] div_result_tmp;

    wire div_fire_in = div_valid_in && div_ready_in;
    
    for (genvar i = 0; i < `NUM_THREADS; i++) begin
        wire [31:0] div_quotient, div_remainder;
        always @(*) begin        
            dpi_idiv (div_fire_in, alu_in1[i], alu_in2[i], is_signed_div, div_quotient, div_remainder);
        end
        assign div_result_tmp[i] = is_rem_op_in ? div_remainder : div_quotient;
    end

    VX_shift_register #(
        .DATAW  (1 + `NW_BITS + `NUM_THREADS + 32 + `NR_BITS + 1 + (`NUM_THREADS * 32)),
        .DEPTH  (`LATENCY_IMUL),
        .RESETW (1)
    ) div_shift_reg (
        .clk(clk),
        .reset    (reset),
        .enable   (div_ready_in),
        .data_in  ({div_valid_in,  wid_in,      tmask_in,       PC_in,      rd_in,      wb_in,      div_result_tmp}),
        .data_out ({div_valid_out, div_wid_out, div_tmask_out,  div_PC_out, div_rd_out, div_wb_out, div_result})
    );

    assign div_ready_in = div_ready_out || ~div_valid_out;

`else

    wire [`NUM_THREADS-1:0][31:0] div_result_tmp, rem_result_tmp;
    wire is_rem_op_out;
    
    VX_serial_div #(
        .WIDTHN (32),
        .WIDTHD (32),
        .WIDTHQ (32),
        .WIDTHR (32),
        .LANES  (`NUM_THREADS),
        .TAGW   (`NW_BITS + `NUM_THREADS + 32 + `NR_BITS + 1 + 1)
    ) divide (
        .clk       (clk),
        .reset     (reset),        
        .valid_in  (div_valid_in),
        .ready_in  (div_ready_in),
        .signed_mode(is_signed_div),
        .tag_in    ({wid_in, tmask_in, PC_in, rd_in, wb_in, is_rem_op_in}),
        .numer     (alu_in1),
        .denom     (alu_in2),
        .quotient  (div_result_tmp),
        .remainder (rem_result_tmp),
        .ready_out (div_ready_out),
        .valid_out (div_valid_out),
        .tag_out   ({div_wid_out, div_tmask_out, div_PC_out, div_rd_out, div_wb_out, is_rem_op_out})
    );

    assign div_result = is_rem_op_out ? rem_result_tmp : div_result_tmp; 

`endif



    wire                    rsp_valid = mul_valid_out || div_valid_out;  
    wire [`NW_BITS-1:0]     rsp_wid   = mul_valid_out ? mul_wid_out : div_wid_out;
    wire [`NUM_THREADS-1:0] rsp_tmask = mul_valid_out ? mul_tmask_out : div_tmask_out;
    wire [31:0]             rsp_PC    = mul_valid_out ? mul_PC_out : div_PC_out;
    wire [`NR_BITS-1:0]     rsp_rd    = mul_valid_out ? mul_rd_out : div_rd_out;
    wire                    rsp_wb    = mul_valid_out ? mul_wb_out : div_wb_out;
    wire [`NUM_THREADS-1:0][31:0] rsp_data = mul_valid_out ? mul_result : div_result;

    assign stall_out = ~ready_out && valid_out;

    VX_pipe_register #(
        .DATAW  (1 + `NW_BITS + `NUM_THREADS + 32 + `NR_BITS + 1 + (`NUM_THREADS * 32)),
        .RESETW (1)
    ) pipe_reg (
        .clk      (clk),
        .reset    (reset),
        .enable   (~stall_out),
        .data_in  ({rsp_valid, rsp_wid, rsp_tmask, rsp_PC, rsp_rd, rsp_wb, rsp_data}),
        .data_out ({valid_out, wid_out, tmask_out, PC_out, rd_out, wb_out, data_out})
    );


    assign ready_in = is_div_op ? div_ready_in : mul_ready_in;
    
endmodule
module VX_muldiv (
    input wire clk,
    input wire reset,
    

    input wire [`INST_MUL_BITS-1:0]     alu_op,
    input wire [`NW_BITS-1:0]           wid_in,
    input wire [`NUM_THREADS-1:0]       tmask_in,
    input wire [31:0]                   PC_in,
    input wire [`NR_BITS-1:0]           rd_in,
    input wire                          wb_in,
    input wire [`NUM_THREADS-1:0][31:0] alu_in1, 
    input wire [`NUM_THREADS-1:0][31:0] alu_in2,


    output wire [`NW_BITS-1:0]           wid_out,
    output wire [`NUM_THREADS-1:0]       tmask_out,
    output wire [31:0]                   PC_out,
    output wire [`NR_BITS-1:0]           rd_out,
    output wire                          wb_out,
    output wire [`NUM_THREADS-1:0][31:0] data_out,


    input wire  valid_in,
    output wire ready_in,
    output wire valid_out,
    input wire  ready_out
);
 

    wire is_div_op = `INST_MUL_IS_DIV(alu_op);

    wire [`NUM_THREADS-1:0][31:0] mul_result;
    wire [`NW_BITS-1:0] mul_wid_out;
    wire [`NUM_THREADS-1:0] mul_tmask_out;
    wire [31:0] mul_PC_out;
    wire [`NR_BITS-1:0] mul_rd_out;
    wire mul_wb_out;

    wire stall_out;

    wire mul_valid_out;
    wire mul_valid_in = valid_in && !is_div_op;    
    wire mul_ready_in = ~stall_out || ~mul_valid_out;

    wire is_mulh_in      = (alu_op != `INST_MUL_MUL);
    wire is_signed_mul_a = (alu_op != `INST_MUL_MULHU);
    wire is_signed_mul_b = (alu_op != `INST_MUL_MULHU && alu_op != `INST_MUL_MULHSU);

`ifdef IMUL_DPI

    wire [`NUM_THREADS-1:0][31:0] mul_result_tmp;  

    wire mul_fire_in = mul_valid_in && mul_ready_in;

    for (genvar i = 0; i < `NUM_THREADS; i++) begin
        wire [31:0] mul_resultl, mul_resulth;
        always @(*) begin        
            dpi_imul (mul_fire_in, alu_in1[i], alu_in2[i], is_signed_mul_a, is_signed_mul_b, mul_resultl, mul_resulth);
        end
        assign mul_result_tmp[i] = is_mulh_in ? mul_resulth : mul_resultl;
    end

    VX_shift_register #(
        .DATAW  (1 + `NW_BITS + `NUM_THREADS + 32 + `NR_BITS + 1 + (`NUM_THREADS * 32)),
        .DEPTH  (`LATENCY_IMUL),
        .RESETW (1)
    ) mul_shift_reg (
        .clk(clk),
        .reset    (reset),
        .enable   (mul_ready_in),
        .data_in  ({mul_valid_in,  wid_in,      tmask_in,       PC_in,      rd_in,      wb_in,      mul_result_tmp}),
        .data_out ({mul_valid_out, mul_wid_out, mul_tmask_out,  mul_PC_out, mul_rd_out, mul_wb_out, mul_result})
    );

`else      
    
    wire is_mulh_out;

    for (genvar i = 0; i < `NUM_THREADS; i++) begin
        wire [32:0] mul_in1 = {is_signed_mul_a & alu_in1[i][31], alu_in1[i]};
        wire [32:0] mul_in2 = {is_signed_mul_b & alu_in2[i][31], alu_in2[i]};
    `IGNORE_UNUSED_BEGIN
        wire [65:0] mul_result_tmp;
    `IGNORE_UNUSED_END

        VX_multiplier #(
            .WIDTHA  (33),
            .WIDTHB  (33),
            .WIDTHP  (66),
            .SIGNED  (1),
            .LATENCY (`LATENCY_IMUL)
        ) multiplier (
            .clk    (clk),
            .enable (mul_ready_in),
            .dataa  (mul_in1),
            .datab  (mul_in2),
            .result (mul_result_tmp)
        );

        assign mul_result[i] = is_mulh_out ? mul_result_tmp[63:32] : mul_result_tmp[31:0];
    end

    VX_shift_register #(
        .DATAW  (1 + `NW_BITS + `NUM_THREADS + 32 + `NR_BITS + 1 + 1),
        .DEPTH  (`LATENCY_IMUL),
        .RESETW (1)
    ) mul_shift_reg (
        .clk(clk),
        .reset    (reset),
        .enable   (mul_ready_in),
        .data_in  ({mul_valid_in,  wid_in,      tmask_in,       PC_in,      rd_in,      wb_in,      is_mulh_in}),
        .data_out ({mul_valid_out, mul_wid_out, mul_tmask_out,  mul_PC_out, mul_rd_out, mul_wb_out, is_mulh_out})
    );

`endif



    wire [`NUM_THREADS-1:0][31:0] div_result;
    wire [`NW_BITS-1:0] div_wid_out;
    wire [`NUM_THREADS-1:0] div_tmask_out;
    wire [31:0] div_PC_out;
    wire [`NR_BITS-1:0] div_rd_out;
    wire div_wb_out;

    wire is_rem_op_in  = (alu_op == `INST_MUL_REM) || (alu_op == `INST_MUL_REMU);
    wire is_signed_div = (alu_op == `INST_MUL_DIV) || (alu_op == `INST_MUL_REM);     
    wire div_valid_in  = valid_in && is_div_op; 
    wire div_ready_out = ~stall_out && ~mul_valid_out;
    wire div_ready_in;
    wire div_valid_out;

`ifdef IDIV_DPI    

    wire [`NUM_THREADS-1:0][31:0] div_result_tmp;

    wire div_fire_in = div_valid_in && div_ready_in;
    
    for (genvar i = 0; i < `NUM_THREADS; i++) begin
        wire [31:0] div_quotient, div_remainder;
        always @(*) begin        
            dpi_idiv (div_fire_in, alu_in1[i], alu_in2[i], is_signed_div, div_quotient, div_remainder);
        end
        assign div_result_tmp[i] = is_rem_op_in ? div_remainder : div_quotient;
    end

    VX_shift_register #(
        .DATAW  (1 + `NW_BITS + `NUM_THREADS + 32 + `NR_BITS + 1 + (`NUM_THREADS * 32)),
        .DEPTH  (`LATENCY_IMUL),
        .RESETW (1)
    ) div_shift_reg (
        .clk(clk),
        .reset    (reset),
        .enable   (div_ready_in),
        .data_in  ({div_valid_in,  wid_in,      tmask_in,       PC_in,      rd_in,      wb_in,      div_result_tmp}),
        .data_out ({div_valid_out, div_wid_out, div_tmask_out,  div_PC_out, div_rd_out, div_wb_out, div_result})
    );

    assign div_ready_in = div_ready_out || ~div_valid_out;

`else

    wire [`NUM_THREADS-1:0][31:0] div_result_tmp, rem_result_tmp;
    wire is_rem_op_out;
    
    VX_serial_div #(
        .WIDTHN (32),
        .WIDTHD (32),
        .WIDTHQ (32),
        .WIDTHR (32),
        .LANES  (`NUM_THREADS),
        .TAGW   (`NW_BITS + `NUM_THREADS + 32 + `NR_BITS + 1 + 1)
    ) divide (
        .clk       (clk),
        .reset     (reset),        
        .valid_in  (div_valid_in),
        .ready_in  (div_ready_in),
        .signed_mode(is_signed_div),
        .tag_in    ({wid_in, tmask_in, PC_in, rd_in, wb_in, is_rem_op_in}),
        .numer     (alu_in1),
        .denom     (alu_in2),
        .quotient  (div_result_tmp),
        .remainder (rem_result_tmp),
        .ready_out (div_ready_out),
        .valid_out (div_valid_out),
        .tag_out   ({div_wid_out, div_tmask_out, div_PC_out, div_rd_out, div_wb_out, is_rem_op_out})
    );

    assign div_result = is_rem_op_out ? rem_result_tmp : div_result_tmp; 

`endif



    wire                    rsp_valid = mul_valid_out || div_valid_out;  
    wire [`NW_BITS-1:0]     rsp_wid   = mul_valid_out ? mul_wid_out : div_wid_out;
    wire [`NUM_THREADS-1:0] rsp_tmask = mul_valid_out ? mul_tmask_out : div_tmask_out;
    wire [31:0]             rsp_PC    = mul_valid_out ? mul_PC_out : div_PC_out;
    wire [`NR_BITS-1:0]     rsp_rd    = mul_valid_out ? mul_rd_out : div_rd_out;
    wire                    rsp_wb    = mul_valid_out ? mul_wb_out : div_wb_out;
    wire [`NUM_THREADS-1:0][31:0] rsp_data = mul_valid_out ? mul_result : div_result;

    assign stall_out = ~ready_out && valid_out;

    VX_pipe_register #(
        .DATAW  (1 + `NW_BITS + `NUM_THREADS + 32 + `NR_BITS + 1 + (`NUM_THREADS * 32)),
        .RESETW (1)
    ) pipe_reg (
        .clk      (clk),
        .reset    (reset),
        .enable   (~stall_out),
        .data_in  ({rsp_valid, rsp_wid, rsp_tmask, rsp_PC, rsp_rd, rsp_wb, rsp_data}),
        .data_out ({valid_out, wid_out, tmask_out, PC_out, rd_out, wb_out, data_out})
    );


    assign ready_in = is_div_op ? div_ready_in : mul_ready_in;
    
endmodule