data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv
1: b'%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.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_warp_sched.sv:6: Define or directive not defined: \'`SCOPE_IO_VX_warp_sched\'\n    `SCOPE_IO_VX_warp_sched\n    ^~~~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:23: Define or directive not defined: \'`UNUSED_PARAM\'\n    `UNUSED_PARAM (CORE_ID)\n    ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:23: syntax error, unexpected \'(\'\n    `UNUSED_PARAM (CORE_ID)\n                   ^~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:27: Define or directive not defined: \'`NUM_THREADS\'\n    wire [`NUM_THREADS-1:0] join_tmask;\n          ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:29: Define or directive not defined: \'`NUM_WARPS\'\n    reg [`NUM_WARPS-1:0] active_warps, active_warps_n;    \n         ^~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:30: Define or directive not defined: \'`NUM_WARPS\'\n    reg [`NUM_WARPS-1:0] stalled_warps;   \n         ^~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:32: Define or directive not defined: \'`NUM_WARPS\'\n    reg [`NUM_WARPS-1:0][`NUM_THREADS-1:0] thread_masks;\n         ^~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:32: Define or directive not defined: \'`NUM_THREADS\'\n    reg [`NUM_WARPS-1:0][`NUM_THREADS-1:0] thread_masks;\n                         ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:33: Define or directive not defined: \'`NUM_WARPS\'\n    reg [`NUM_WARPS-1:0][31:0] warp_pcs;\n         ^~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:36: Define or directive not defined: \'`NUM_BARRIERS\'\n    reg [`NUM_BARRIERS-1:0][`NUM_WARPS-1:0] barrier_masks;  \n         ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:36: Define or directive not defined: \'`NUM_WARPS\'\n    reg [`NUM_BARRIERS-1:0][`NUM_WARPS-1:0] barrier_masks;  \n                            ^~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:41: Define or directive not defined: \'`NUM_WARPS\'\n    reg [`NUM_WARPS-1:0]    use_wspawn;   \n         ^~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:43: Define or directive not defined: \'`NW_BITS\'\n    wire [`NW_BITS-1:0]     schedule_wid;\n          ^~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:44: Define or directive not defined: \'`NUM_THREADS\'\n    wire [`NUM_THREADS-1:0] schedule_tmask;\n          ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:73: Define or directive not defined: \'`STARTUP_ADDR\'\n            warp_pcs[0]     <= `STARTUP_ADDR;\n                               ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:73: syntax error, unexpected \';\', expecting TYPE-IDENTIFIER\n            warp_pcs[0]     <= `STARTUP_ADDR;\n                                            ^\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:78: Define or directive not defined: \'`NUM_WARPS\'\n                use_wspawn <= warp_ctl_if.wspawn.wmask & (~`NUM_WARPS\'(1));\n                                                           ^~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:78: syntax error, unexpected "\'", expecting TYPE-IDENTIFIER\n                use_wspawn <= warp_ctl_if.wspawn.wmask & (~`NUM_WARPS\'(1));\n                                                                     ^\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:147: Define or directive not defined: \'`IGNORE_UNUSED_BEGIN\'\n`IGNORE_UNUSED_BEGIN\n^~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:148: Define or directive not defined: \'`NW_BITS\'\n    wire [`NW_BITS:0] active_barrier_count;\n          ^~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:148: syntax error, unexpected \':\', expecting TYPE-IDENTIFIER\n    wire [`NW_BITS:0] active_barrier_count;\n                  ^\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:149: Define or directive not defined: \'`IGNORE_UNUSED_END\'\n`IGNORE_UNUSED_END\n^~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:150: Define or directive not defined: \'`NUM_WARPS\'\n    wire [`NUM_WARPS-1:0] barrier_mask = barrier_masks[warp_ctl_if.barrier.id];\n          ^~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:151: Define or directive not defined: \'`POP_COUNT\'\n    `POP_COUNT(active_barrier_count, barrier_mask);\n    ^~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:151: syntax error, unexpected \'(\'\n    `POP_COUNT(active_barrier_count, barrier_mask);\n               ^~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:153: Define or directive not defined: \'`NW_BITS\'\n    assign reached_barrier_limit = (active_barrier_count[`NW_BITS-1:0] == warp_ctl_if.barrier.size_m1);\n                                                         ^~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:155: Define or directive not defined: \'`NUM_WARPS\'\n    reg [`NUM_WARPS-1:0] barrier_stalls;\n         ^~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:158: Define or directive not defined: \'`NUM_BARRIERS\'\n        for (integer i = 1; i < `NUM_BARRIERS; ++i) begin\n                                ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:158: syntax error, unexpected \';\', expecting TYPE-IDENTIFIER\n        for (integer i = 1; i < `NUM_BARRIERS; ++i) begin\n                                             ^\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:158: syntax error, unexpected \')\'\n        for (integer i = 1; i < `NUM_BARRIERS; ++i) begin\n                                                  ^\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:165: Define or directive not defined: \'`NUM_THREADS\'\n    wire [(32+`NUM_THREADS)-1:0] ipdom_data [`NUM_WARPS-1:0]; \n              ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:165: Define or directive not defined: \'`NUM_WARPS\'\n    wire [(32+`NUM_THREADS)-1:0] ipdom_data [`NUM_WARPS-1:0]; \n                                             ^~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:166: Define or directive not defined: \'`NUM_WARPS\'\n    wire ipdom_index [`NUM_WARPS-1:0];   \n                      ^~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:168: Define or directive not defined: \'`NUM_WARPS\'\n    for (genvar i = 0; i < `NUM_WARPS; i++) begin\n                           ^~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:168: syntax error, unexpected \';\', expecting TYPE-IDENTIFIER\n    for (genvar i = 0; i < `NUM_WARPS; i++) begin\n                                     ^\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:175: Define or directive not defined: \'`NUM_THREADS\'\n        wire [`NUM_THREADS-1:0] else_tmask = warp_ctl_if.split.else_tmask;\n              ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:176: Define or directive not defined: \'`NUM_THREADS\'\n        wire [`NUM_THREADS-1:0] orig_tmask = thread_masks[warp_ctl_if.wid];\n              ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:178: Define or directive not defined: \'`NUM_THREADS\'\n        wire [(32+`NUM_THREADS)-1:0] q_else = {warp_ctl_if.split.pc, else_tmask};\n                  ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:178: syntax error, unexpected \')\', expecting TYPE-IDENTIFIER\n        wire [(32+`NUM_THREADS)-1:0] q_else = {warp_ctl_if.split.pc, else_tmask};\n                              ^\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:179: Define or directive not defined: \'`NUM_THREADS\'\n        wire [(32+`NUM_THREADS)-1:0] q_end  = {32\'b0,                orig_tmask};\n                  ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:179: syntax error, unexpected \')\', expecting TYPE-IDENTIFIER\n        wire [(32+`NUM_THREADS)-1:0] q_end  = {32\'b0,                orig_tmask};\n                              ^\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:182: Define or directive not defined: \'`NUM_THREADS\'\n            .WIDTH (32+`NUM_THREADS), \n                       ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:182: syntax error, unexpected \')\', expecting TYPE-IDENTIFIER\n            .WIDTH (32+`NUM_THREADS), \n                                   ^\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:183: Define or directive not defined: \'`NT_BITS\'\n            .DEPTH (2 ** (`NT_BITS+1))\n                          ^~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:194: Define or directive not defined: \'`UNUSED_PIN\'\n            `UNUSED_PIN (empty),\n            ^~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:195: Define or directive not defined: \'`UNUSED_PIN\'\n            `UNUSED_PIN (full)\n            ^~~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:204: Define or directive not defined: \'`NUM_WARPS\'\n    wire [`NUM_WARPS-1:0] ready_warps = active_warps & ~(stalled_warps | barrier_stalls);\n          ^~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:207: Define or directive not defined: \'`NUM_WARPS\'\n        .N (`NUM_WARPS)\n            ^~~~~~~~~~\n%Error: data/full_repos/permissive/473423187/hw/rtl/VX_warp_sched.sv:214: Define or directive not defined: \'`NUM_WARPS\'\n    wire [`NUM_WARPS-1:0][(`NUM_THREADS + 32)-1:0] schedule_data;\n          ^~~~~~~~~~\n%Error: Exiting due to too many errors encountered; --error-limit=50\n'
module VX_warp_sched #(
    parameter CORE_ID = 0
) (
    `SCOPE_IO_VX_warp_sched
    
    input wire              clk,
    input wire              reset,

    VX_warp_ctl_if.slave    warp_ctl_if,
    VX_wstall_if.slave      wstall_if,
    VX_join_if.slave        join_if,
    VX_branch_ctl_if.slave  branch_ctl_if,

    VX_ifetch_req_if.master ifetch_req_if,

    VX_fetch_to_csr_if.master fetch_to_csr_if,

    output wire             busy
);

    `UNUSED_PARAM (CORE_ID)

    wire                    join_else;
    wire [31:0]             join_pc;
    wire [`NUM_THREADS-1:0] join_tmask;

    reg [`NUM_WARPS-1:0] active_warps, active_warps_n;
    reg [`NUM_WARPS-1:0] stalled_warps;
    
    reg [`NUM_WARPS-1:0][`NUM_THREADS-1:0] thread_masks;
    reg [`NUM_WARPS-1:0][31:0] warp_pcs;


    reg [`NUM_BARRIERS-1:0][`NUM_WARPS-1:0] barrier_masks;
    wire reached_barrier_limit;
    

    reg [31:0]              wspawn_pc;
    reg [`NUM_WARPS-1:0]    use_wspawn;   

    wire [`NW_BITS-1:0]     schedule_wid;
    wire [`NUM_THREADS-1:0] schedule_tmask;
    wire [31:0]             schedule_pc;
    wire                    schedule_valid;
    wire                    warp_scheduled;

    wire ifetch_req_fire = ifetch_req_if.valid && ifetch_req_if.ready;

    wire tmc_active = (warp_ctl_if.tmc.tmask != 0);   

    always @(*) begin
        active_warps_n = active_warps;
        if (warp_ctl_if.valid && warp_ctl_if.wspawn.valid) begin
            active_warps_n = warp_ctl_if.wspawn.wmask;
        end
        if (warp_ctl_if.valid && warp_ctl_if.tmc.valid) begin
            active_warps_n[warp_ctl_if.wid] = tmc_active;
        end        
    end

    always @(posedge clk) begin
        if (reset) begin
            barrier_masks   <= 0;
            use_wspawn      <= 0;
            stalled_warps   <= 0;
            warp_pcs        <= '0;
            active_warps    <= '0;
            thread_masks    <= '0;


            warp_pcs[0]     <= `STARTUP_ADDR;
            active_warps[0] <= 1;
            thread_masks[0] <= 1;
        end else begin            
            if (warp_ctl_if.valid && warp_ctl_if.wspawn.valid) begin
                use_wspawn <= warp_ctl_if.wspawn.wmask & (~`NUM_WARPS'(1));
                wspawn_pc  <= warp_ctl_if.wspawn.pc;
            end

            if (warp_ctl_if.valid && warp_ctl_if.barrier.valid) begin
                stalled_warps[warp_ctl_if.wid] <= 0;
                if (reached_barrier_limit) begin
                    barrier_masks[warp_ctl_if.barrier.id] <= 0;
                end else begin
                    barrier_masks[warp_ctl_if.barrier.id][warp_ctl_if.wid] <= 1;
                end
            end 
            
            if (warp_ctl_if.valid && warp_ctl_if.tmc.valid) begin
                thread_masks[warp_ctl_if.wid]  <= warp_ctl_if.tmc.tmask;
                stalled_warps[warp_ctl_if.wid] <= 0;
            end 
            
            if (warp_ctl_if.valid && warp_ctl_if.split.valid) begin
                stalled_warps[warp_ctl_if.wid] <= 0;
                if (warp_ctl_if.split.diverged) begin
                    thread_masks[warp_ctl_if.wid] <= warp_ctl_if.split.then_tmask;
                end
            end


            if (branch_ctl_if.valid) begin
                if (branch_ctl_if.taken) begin
                    warp_pcs[branch_ctl_if.wid] <= branch_ctl_if.dest;
                end
                stalled_warps[branch_ctl_if.wid] <= 0;
            end

            if (warp_scheduled) begin

                stalled_warps[schedule_wid] <= 1;


                use_wspawn[schedule_wid] <= 0;
                if (use_wspawn[schedule_wid]) begin
                    thread_masks[schedule_wid] <= 1;
                end
            end

            if (ifetch_req_fire) begin
                warp_pcs[ifetch_req_if.wid] <= ifetch_req_if.PC + 4;
            end

            if (wstall_if.valid) begin
                stalled_warps[wstall_if.wid] <= wstall_if.stalled;
            end


            if (join_if.valid) begin
                if (join_else) begin
                    warp_pcs[join_if.wid] <= join_pc;
                end
                thread_masks[join_if.wid] <= join_tmask;
            end

            active_warps <= active_warps_n;
        end
    end


    assign fetch_to_csr_if.thread_masks = thread_masks;



`IGNORE_UNUSED_BEGIN
    wire [`NW_BITS:0] active_barrier_count;
`IGNORE_UNUSED_END
    wire [`NUM_WARPS-1:0] barrier_mask = barrier_masks[warp_ctl_if.barrier.id];
    `POP_COUNT(active_barrier_count, barrier_mask);

    assign reached_barrier_limit = (active_barrier_count[`NW_BITS-1:0] == warp_ctl_if.barrier.size_m1);

    reg [`NUM_WARPS-1:0] barrier_stalls;
    always @(*) begin
        barrier_stalls = barrier_masks[0];
        for (integer i = 1; i < `NUM_BARRIERS; ++i) begin
            barrier_stalls |= barrier_masks[i];
        end
    end



    wire [(32+`NUM_THREADS)-1:0] ipdom_data [`NUM_WARPS-1:0]; 
    wire ipdom_index [`NUM_WARPS-1:0];   
    
    for (genvar i = 0; i < `NUM_WARPS; i++) begin
        wire push = warp_ctl_if.valid 
                 && warp_ctl_if.split.valid
                 && (i == warp_ctl_if.wid);

        wire pop = join_if.valid && (i == join_if.wid);

        wire [`NUM_THREADS-1:0] else_tmask = warp_ctl_if.split.else_tmask;
        wire [`NUM_THREADS-1:0] orig_tmask = thread_masks[warp_ctl_if.wid];

        wire [(32+`NUM_THREADS)-1:0] q_else = {warp_ctl_if.split.pc, else_tmask};
        wire [(32+`NUM_THREADS)-1:0] q_end  = {32'b0,                orig_tmask};

        VX_ipdom_stack #(
            .WIDTH (32+`NUM_THREADS), 
            .DEPTH (2 ** (`NT_BITS+1))
        ) ipdom_stack (
            .clk   (clk),
            .reset (reset),
            .push  (push),
            .pop   (pop),
            .pair  (warp_ctl_if.split.diverged),
            .q1    (q_end),
            .q2    (q_else),
            .d     (ipdom_data[i]),
            .index (ipdom_index[i]),
            `UNUSED_PIN (empty),
            `UNUSED_PIN (full)
        );
    end

    assign {join_pc, join_tmask} = ipdom_data[join_if.wid];
    assign join_else = ~ipdom_index[join_if.wid];



    wire [`NUM_WARPS-1:0] ready_warps = active_warps & ~(stalled_warps | barrier_stalls);

    VX_lzc #(
        .N (`NUM_WARPS)
    ) wid_select (
        .in_i    (ready_warps),
        .cnt_o   (schedule_wid),
        .valid_o (schedule_valid)
    );

    wire [`NUM_WARPS-1:0][(`NUM_THREADS + 32)-1:0] schedule_data;
    for (genvar i = 0; i < `NUM_WARPS; ++i) begin
        assign schedule_data[i] = {(use_wspawn[i] ? `NUM_THREADS'(1) : thread_masks[i]),
                                   (use_wspawn[i] ? wspawn_pc : warp_pcs[i])};
    end

    assign {schedule_tmask, schedule_pc} = schedule_data[schedule_wid];

    wire stall_out = ~ifetch_req_if.ready && ifetch_req_if.valid;   

    assign warp_scheduled = schedule_valid && ~stall_out;

    VX_pipe_register #( 
        .DATAW  (1 + `NUM_THREADS + 32 + `NW_BITS),
        .RESETW (1)
    ) pipe_reg (
        .clk      (clk),
        .reset    (reset),
        .enable   (!stall_out),
        .data_in  ({schedule_valid,      schedule_tmask,      schedule_pc,      schedule_wid}),
        .data_out ({ifetch_req_if.valid, ifetch_req_if.tmask, ifetch_req_if.PC, ifetch_req_if.wid})
    );

    assign busy = (active_warps != 0); 

    `SCOPE_ASSIGN (wsched_scheduled,      warp_scheduled);
    `SCOPE_ASSIGN (wsched_active_warps,   active_warps);
    `SCOPE_ASSIGN (wsched_stalled_warps,  stalled_warps);
    `SCOPE_ASSIGN (wsched_schedule_wid,   schedule_wid);
    `SCOPE_ASSIGN (wsched_schedule_tmask, schedule_tmask);
    `SCOPE_ASSIGN (wsched_schedule_pc,    schedule_pc);

endmodule
module VX_warp_sched #(
    parameter CORE_ID = 0
) (
    `SCOPE_IO_VX_warp_sched
    
    input wire              clk,
    input wire              reset,

    VX_warp_ctl_if.slave    warp_ctl_if,
    VX_wstall_if.slave      wstall_if,
    VX_join_if.slave        join_if,
    VX_branch_ctl_if.slave  branch_ctl_if,

    VX_ifetch_req_if.master ifetch_req_if,

    VX_fetch_to_csr_if.master fetch_to_csr_if,

    output wire             busy
);


    `UNUSED_PARAM (CORE_ID)

    wire                    join_else;
    wire [31:0]             join_pc;
    wire [`NUM_THREADS-1:0] join_tmask;

    reg [`NUM_WARPS-1:0] active_warps, active_warps_n;
    reg [`NUM_WARPS-1:0] stalled_warps;
    
    reg [`NUM_WARPS-1:0][`NUM_THREADS-1:0] thread_masks;
    reg [`NUM_WARPS-1:0][31:0] warp_pcs;


    reg [`NUM_BARRIERS-1:0][`NUM_WARPS-1:0] barrier_masks;
    wire reached_barrier_limit;
    

    reg [31:0]              wspawn_pc;
    reg [`NUM_WARPS-1:0]    use_wspawn;   

    wire [`NW_BITS-1:0]     schedule_wid;
    wire [`NUM_THREADS-1:0] schedule_tmask;
    wire [31:0]             schedule_pc;
    wire                    schedule_valid;
    wire                    warp_scheduled;

    wire ifetch_req_fire = ifetch_req_if.valid && ifetch_req_if.ready;

    wire tmc_active = (warp_ctl_if.tmc.tmask != 0);   

    always @(*) begin
        active_warps_n = active_warps;
        if (warp_ctl_if.valid && warp_ctl_if.wspawn.valid) begin
            active_warps_n = warp_ctl_if.wspawn.wmask;
        end
        if (warp_ctl_if.valid && warp_ctl_if.tmc.valid) begin
            active_warps_n[warp_ctl_if.wid] = tmc_active;
        end        
    end

    always @(posedge clk) begin
        if (reset) begin
            barrier_masks   <= 0;
            use_wspawn      <= 0;
            stalled_warps   <= 0;
            warp_pcs        <= '0;
            active_warps    <= '0;
            thread_masks    <= '0;


            warp_pcs[0]     <= `STARTUP_ADDR;
            active_warps[0] <= 1;
            thread_masks[0] <= 1;
        end else begin            
            if (warp_ctl_if.valid && warp_ctl_if.wspawn.valid) begin
                use_wspawn <= warp_ctl_if.wspawn.wmask & (~`NUM_WARPS'(1));
                wspawn_pc  <= warp_ctl_if.wspawn.pc;
            end

            if (warp_ctl_if.valid && warp_ctl_if.barrier.valid) begin
                stalled_warps[warp_ctl_if.wid] <= 0;
                if (reached_barrier_limit) begin
                    barrier_masks[warp_ctl_if.barrier.id] <= 0;
                end else begin
                    barrier_masks[warp_ctl_if.barrier.id][warp_ctl_if.wid] <= 1;
                end
            end 
            
            if (warp_ctl_if.valid && warp_ctl_if.tmc.valid) begin
                thread_masks[warp_ctl_if.wid]  <= warp_ctl_if.tmc.tmask;
                stalled_warps[warp_ctl_if.wid] <= 0;
            end 
            
            if (warp_ctl_if.valid && warp_ctl_if.split.valid) begin
                stalled_warps[warp_ctl_if.wid] <= 0;
                if (warp_ctl_if.split.diverged) begin
                    thread_masks[warp_ctl_if.wid] <= warp_ctl_if.split.then_tmask;
                end
            end


            if (branch_ctl_if.valid) begin
                if (branch_ctl_if.taken) begin
                    warp_pcs[branch_ctl_if.wid] <= branch_ctl_if.dest;
                end
                stalled_warps[branch_ctl_if.wid] <= 0;
            end

            if (warp_scheduled) begin

                stalled_warps[schedule_wid] <= 1;


                use_wspawn[schedule_wid] <= 0;
                if (use_wspawn[schedule_wid]) begin
                    thread_masks[schedule_wid] <= 1;
                end
            end

            if (ifetch_req_fire) begin
                warp_pcs[ifetch_req_if.wid] <= ifetch_req_if.PC + 4;
            end

            if (wstall_if.valid) begin
                stalled_warps[wstall_if.wid] <= wstall_if.stalled;
            end


            if (join_if.valid) begin
                if (join_else) begin
                    warp_pcs[join_if.wid] <= join_pc;
                end
                thread_masks[join_if.wid] <= join_tmask;
            end

            active_warps <= active_warps_n;
        end
    end


    assign fetch_to_csr_if.thread_masks = thread_masks;



`IGNORE_UNUSED_BEGIN
    wire [`NW_BITS:0] active_barrier_count;
`IGNORE_UNUSED_END
    wire [`NUM_WARPS-1:0] barrier_mask = barrier_masks[warp_ctl_if.barrier.id];
    `POP_COUNT(active_barrier_count, barrier_mask);

    assign reached_barrier_limit = (active_barrier_count[`NW_BITS-1:0] == warp_ctl_if.barrier.size_m1);

    reg [`NUM_WARPS-1:0] barrier_stalls;
    always @(*) begin
        barrier_stalls = barrier_masks[0];
        for (integer i = 1; i < `NUM_BARRIERS; ++i) begin
            barrier_stalls |= barrier_masks[i];
        end
    end



    wire [(32+`NUM_THREADS)-1:0] ipdom_data [`NUM_WARPS-1:0]; 
    wire ipdom_index [`NUM_WARPS-1:0];   
    
    for (genvar i = 0; i < `NUM_WARPS; i++) begin
        wire push = warp_ctl_if.valid 
                 && warp_ctl_if.split.valid
                 && (i == warp_ctl_if.wid);

        wire pop = join_if.valid && (i == join_if.wid);

        wire [`NUM_THREADS-1:0] else_tmask = warp_ctl_if.split.else_tmask;
        wire [`NUM_THREADS-1:0] orig_tmask = thread_masks[warp_ctl_if.wid];

        wire [(32+`NUM_THREADS)-1:0] q_else = {warp_ctl_if.split.pc, else_tmask};
        wire [(32+`NUM_THREADS)-1:0] q_end  = {32'b0,                orig_tmask};

        VX_ipdom_stack #(
            .WIDTH (32+`NUM_THREADS), 
            .DEPTH (2 ** (`NT_BITS+1))
        ) ipdom_stack (
            .clk   (clk),
            .reset (reset),
            .push  (push),
            .pop   (pop),
            .pair  (warp_ctl_if.split.diverged),
            .q1    (q_end),
            .q2    (q_else),
            .d     (ipdom_data[i]),
            .index (ipdom_index[i]),
            `UNUSED_PIN (empty),
            `UNUSED_PIN (full)
        );
    end

    assign {join_pc, join_tmask} = ipdom_data[join_if.wid];
    assign join_else = ~ipdom_index[join_if.wid];



    wire [`NUM_WARPS-1:0] ready_warps = active_warps & ~(stalled_warps | barrier_stalls);

    VX_lzc #(
        .N (`NUM_WARPS)
    ) wid_select (
        .in_i    (ready_warps),
        .cnt_o   (schedule_wid),
        .valid_o (schedule_valid)
    );

    wire [`NUM_WARPS-1:0][(`NUM_THREADS + 32)-1:0] schedule_data;
    for (genvar i = 0; i < `NUM_WARPS; ++i) begin
        assign schedule_data[i] = {(use_wspawn[i] ? `NUM_THREADS'(1) : thread_masks[i]),
                                   (use_wspawn[i] ? wspawn_pc : warp_pcs[i])};
    end

    assign {schedule_tmask, schedule_pc} = schedule_data[schedule_wid];

    wire stall_out = ~ifetch_req_if.ready && ifetch_req_if.valid;   

    assign warp_scheduled = schedule_valid && ~stall_out;

    VX_pipe_register #( 
        .DATAW  (1 + `NUM_THREADS + 32 + `NW_BITS),
        .RESETW (1)
    ) pipe_reg (
        .clk      (clk),
        .reset    (reset),
        .enable   (!stall_out),
        .data_in  ({schedule_valid,      schedule_tmask,      schedule_pc,      schedule_wid}),
        .data_out ({ifetch_req_if.valid, ifetch_req_if.tmask, ifetch_req_if.PC, ifetch_req_if.wid})
    );

    assign busy = (active_warps != 0); 

    `SCOPE_ASSIGN (wsched_scheduled,      warp_scheduled);
    `SCOPE_ASSIGN (wsched_active_warps,   active_warps);
    `SCOPE_ASSIGN (wsched_stalled_warps,  stalled_warps);
    `SCOPE_ASSIGN (wsched_schedule_wid,   schedule_wid);
    `SCOPE_ASSIGN (wsched_schedule_tmask, schedule_tmask);
    `SCOPE_ASSIGN (wsched_schedule_pc,    schedule_pc);

endmodule