dakies/OSS_Verilog huggingface dataset:
module jelly_signal_transfer
        #(
            parameter   ASYNC          = 1,
            parameter   CAPACITY_WIDTH = 8
        )
        (
            input   wire    s_reset,
            input   wire    s_clk,
            input   wire    s_valid,
            
            input   wire    m_reset,
            input   wire    m_clk,
            output  wire    m_valid,
            input   wire    m_ready
        );
    
    wire    [CAPACITY_WIDTH-1:0]    async_size;
    wire                            async_valid;
    
    jelly_capacity_async
            #(
                .ASYNC                  (ASYNC),
                .CAPACITY_WIDTH         (CAPACITY_WIDTH),
                .REQUEST_WIDTH          (1),
                .ISSUE_WIDTH            (CAPACITY_WIDTH),
                .REQUEST_SIZE_OFFSET    (1'b0),
                .ISSUE_SIZE_OFFSET      (1'b0),
                .INIT_REQUEST           ({CAPACITY_WIDTH{1'b0}})
            )
        i_capacity_async
            (
                .s_reset                (s_reset),
                .s_clk                  (s_clk),
                .s_request_size         (1'b1),
                .s_request_valid        (s_valid),
                .s_queued_request       (),
                
                .m_reset                (m_reset),
                .m_clk                  (m_clk),
                .m_issue_size           (async_size),
                .m_issue_valid          (async_valid),
                .m_issue_ready          (1'b1),
                .m_queued_request       ()
            );
    
    
    jelly_capacity_size_limitter
            #(
                .CAPACITY_WIDTH         (CAPACITY_WIDTH),
                .REQUEST_WIDTH          (CAPACITY_WIDTH),
                .ISSUE_WIDTH            (1),
                .REQUEST_SIZE_OFFSET    (1'b0),
                .ISSUE_SIZE_OFFSET      (1'b0)
            )
        i_capacity_size_limitter
            (
                .reset                  (m_reset),
                .clk                    (m_clk),
                .cke                    (1'b1),
                
                .max_issue_size         (1'b1),
                .queued_request         (),
                
                .s_request_size         (async_size),
                .s_request_valid        (async_valid),
                
                .m_issue_size           (),
                .m_issue_valid          (m_valid),
                .m_issue_ready          (m_ready)
            );
    
    
endmodule
module jelly_signal_transfer_sync
        #(
            parameter CAPACITY_WIDTH = 8
        )
        (
            input   wire    reset,
            input   wire    clk,
            
            input   wire    s_valid,
            
            output  wire    m_valid,
            input   wire    m_ready
        );
    
    reg                             reg_valid;
    reg     [CAPACITY_WIDTH-1:0]    reg_capacity;
    wire    [CAPACITY_WIDTH-1:0]    next_capacity = reg_capacity + s_valid - (m_valid & m_ready);
    
    always @(posedge clk) begin
        if ( reset ) begin
            reg_valid    <= 1'b0;
            reg_capacity <= {CAPACITY_WIDTH{1'b0}};
        end
        else begin
            reg_valid    <= (next_capacity != 0);
            reg_capacity <= next_capacity;
        end
    end
    
    assign m_valid = reg_valid;
    
endmodule
module jelly_pipeline_delay
        #(
            parameter   PIPELINE_STAGES = 2,
            parameter   DATA_WIDTH      = 8,
            parameter   INIT_DATA       = {DATA_WIDTH{1'bx}}
        )
        (
            input   wire                            reset,
            input   wire                            clk,
            input   wire    [PIPELINE_STAGES-1:0]   stage_cke,
            
            input   wire    [DATA_WIDTH-1:0]        in_data,
            
            output  wire    [DATA_WIDTH-1:0]        out_data
        );
    
    
    generate
    if ( PIPELINE_STAGES > 0 ) begin
        integer                                     i;
        reg     [PIPELINE_STAGES*DATA_WIDTH-1:0]    reg_data;
        always @(posedge clk) begin
            if ( reset ) begin
                for ( i = 0; i < PIPELINE_STAGES; i = i+1 ) begin
                    reg_data[i*DATA_WIDTH +: DATA_WIDTH] <= INIT_DATA;
                end
            end
            else begin
                for ( i = 0; i < PIPELINE_STAGES; i = i+1 ) begin
                    if ( stage_cke[i] ) begin
                        reg_data[i*DATA_WIDTH +: DATA_WIDTH] <= (i == 0 ) ? in_data : reg_data[(i-1)*DATA_WIDTH +: DATA_WIDTH];
                    end
                end
            end
        end
        assign out_data = reg_data[(PIPELINE_STAGES-1)*DATA_WIDTH +: DATA_WIDTH];
    end
    else begin
        assign out_data = in_data;
    end
    endgenerate
    
    
endmodule
module jelly_data_expand
        #(
            parameter   NUM            = 1,
            parameter   IN_DATA_WIDTH  = 8,
            parameter   OUT_DATA_WIDTH = 12,
            parameter   DATA_SIGNED    = 1,
            parameter   OFFSET         = 0,
            parameter   RSHIFT         = 0,
            parameter   LSHIFT         = 0
        )
        (
            input   wire    [NUM*IN_DATA_WIDTH-1:0]     din,
            output  wire    [NUM*OUT_DATA_WIDTH-1:0]    dout
        );
    
    genvar      i;
    
    generate
    if ( DATA_SIGNED ) begin : blk_signed
        for ( i = 0; i < NUM; i = i+1 ) begin : loop_unit
            wire    signed  [IN_DATA_WIDTH-1:0]     in_data;
            wire    signed  [OUT_DATA_WIDTH-1:0]    out_data;
            assign in_data  = din[i*IN_DATA_WIDTH +: IN_DATA_WIDTH];
            assign out_data = (((in_data + OFFSET) >>> RSHIFT) <<< LSHIFT);
            assign dout[i*OUT_DATA_WIDTH +: OUT_DATA_WIDTH] = out_data;
        end
    end
    else begin : blk_unsigned
        for ( i = 0; i < NUM; i = i+1 ) begin : loop_unit
            wire            [IN_DATA_WIDTH-1:0]     in_data;
            wire            [OUT_DATA_WIDTH-1:0]    out_data;
            assign in_data  = din[i*IN_DATA_WIDTH +: IN_DATA_WIDTH];
            assign out_data = (((in_data + OFFSET) >> RSHIFT) << LSHIFT);
            assign dout[i*OUT_DATA_WIDTH +: OUT_DATA_WIDTH] = out_data;
        end
    end
    endgenerate
    
endmodule
module jelly_ram_async_singleport
        #(
            parameter   ADDR_WIDTH   = 6,
            parameter   DATA_WIDTH   = 8,
            parameter   MEM_SIZE     = (1 << ADDR_WIDTH),
            
            parameter   FILLMEM      = 0,
            parameter   FILLMEM_DATA = 0,
            parameter   READMEMB     = 0,
            parameter   READMEMH     = 0,
            parameter   READMEM_FIlE = ""
        )
        (
            input   wire                        clk,
            
            input   wire                        we,
            input   wire    [ADDR_WIDTH-1:0]    addr,
            input   wire    [DATA_WIDTH-1:0]    din,
            output  wire    [DATA_WIDTH-1:0]    dout
        );
    
    // memory
    (* ram_style = "distributed" *)
    reg     [DATA_WIDTH-1:0]    mem [0:MEM_SIZE-1];
    
    always @(posedge clk) begin
        if ( we ) begin
            mem[addr] <= din;
        end
    end
    
    assign dout = mem[addr];
    
    
    // initialize
`ifndef ALTERA
    integer i;
    initial begin
        if ( FILLMEM ) begin
            for ( i = 0; i < MEM_SIZE; i = i + 1 ) begin
                mem[i] = FILLMEM_DATA;
            end
        end
        
        if ( READMEMB ) begin
            $readmemb(READMEM_FIlE, mem);
        end
        if ( READMEMH ) begin
            $readmemh(READMEM_FIlE, mem);
        end
    end
`endif

endmodule
module jelly_busy_control
        #(
            parameter   CAPACITY_WIDTH       = 32,
            parameter   ISSUE_WIDTH          = CAPACITY_WIDTH,
            parameter   COMPLETE_WIDTH       = CAPACITY_WIDTH,
            parameter   ISSUE_SIZE_OFFSET    = 1'b1,
            parameter   COMPLETE_SIZE_OFFSET = 1'b1,
            parameter   FAST_BUSY            = 0
        )
        (
            input   wire                            reset,
            input   wire                            clk,
            input   wire                            cke,
            
            input   wire                            enable,
            output  wire                            busy,
            
            output  wire    [CAPACITY_WIDTH-1:0]    current_count,
            
            input   wire    [ISSUE_WIDTH-1:0]       s_issue_size,
            input   wire                            s_issue_valid,
            
            input   wire    [COMPLETE_WIDTH-1:0]    s_complete_size,
            input   wire                            s_complete_valid
        );
    
    
    reg                             reg_busy,    next_busy;
    reg     [CAPACITY_WIDTH-1:0]    reg_counter, next_counter;
    
    always @(posedge clk) begin
        if ( reset ) begin
            reg_busy    <= 1'b0;
            reg_counter <= {CAPACITY_WIDTH{1'b0}};
        end
        else if ( cke ) begin
            reg_busy    <= next_busy;
            reg_counter <= next_counter;
        end
    end
    
    always @* begin
        next_busy    = reg_busy;
        next_counter = reg_counter;
        
        if ( s_issue_valid ) begin
            next_counter = next_counter + s_issue_size + ISSUE_SIZE_OFFSET;
        end
        if ( s_complete_valid ) begin
            next_counter = next_counter - s_complete_size - COMPLETE_SIZE_OFFSET;
        end
        
        if ( enable ) begin
            next_busy = 1'b1;
        end
        else begin
            next_busy = FAST_BUSY ? (next_counter != 0) : (reg_counter != 0);
        end
    end
    
    assign current_count = reg_counter;
    
    assign busy          = reg_busy;
    
endmodule
module jelly_reset
        #(
            parameter   IN_LOW_ACTIVE  = 0,
            parameter   OUT_LOW_ACTIVE = 0,
            parameter   INPUT_REGS     = 2,
            parameter   COUNTER_WIDTH  = 0,
            parameter   COUNTER_VALUE  = COUNTER_WIDTH > 0 ? (1 << COUNTER_WIDTH) - 1 : 0,
            parameter   INSERT_BUFG    = 0
        )
        (
            input   wire    clk,
            input   wire    in_reset,       // asyncrnous reset
            output  wire    out_reset       // syncrnous reset
        );
    
    wire    input_reset = IN_LOW_ACTIVE ? ~in_reset : in_reset;
    
    
    // input REGS (remove metastable)
    wire    in_regs_reset;
    generate
    if ( INPUT_REGS > 0 ) begin : blk_input_reg
        (* ASYNC_REG="true" *)  reg     [INPUT_REGS-1:0]    reg_in_reset;
        always @(posedge clk or posedge input_reset) begin
            if ( input_reset ) begin
                reg_in_reset <= {INPUT_REGS{1'b1}};
            end
            else begin
                reg_in_reset <= (reg_in_reset >> 1);
            end
        end
        assign in_regs_reset = reg_in_reset[0];
    end
    else begin : bypass_input_reg
        assign in_regs_reset = input_reset;
    end
    endgenerate
    
    
    // counter
    wire    counter_reset;
    generate
    if ( COUNTER_WIDTH > 0 ) begin : blk_counter
        reg     [COUNTER_WIDTH-1:0] reg_counter;
        always @(posedge clk) begin
            if ( in_regs_reset ) begin
                reg_counter <= COUNTER_VALUE;
            end
            else begin
                if ( reg_counter > 0 ) begin
                    reg_counter <= reg_counter - 1'b1;
                end
            end
        end
        assign counter_reset = (reg_counter != 0);
    end
    else begin : bypass_counter
        assign counter_reset = in_regs_reset;
    end
    endgenerate
    
    
    // syncrnous reset
    reg     reg_reset;
    always @(posedge clk) begin
        if ( counter_reset ) begin
            reg_reset <= OUT_LOW_ACTIVE ? 1'b0 : 1'b1;
        end
        else begin
            reg_reset <= OUT_LOW_ACTIVE ? 1'b1 : 1'b0;
        end
    end
    
    
    // insert BUFG
    generate
    if ( INSERT_BUFG ) begin : blk_bufg
        BUFG    i_bufg  (.I(reg_reset), .O(out_reset));
    end
    else begin : bypass_bufg
        assign out_reset = reg_reset;
    end
    endgenerate
    
    
endmodule
module jelly_signal_transfer_async
        #(
            parameter   PTR_WIDTH      = 6,
            parameter   CAPACITY_WIDTH = 8
        )
        (
            input   wire    s_reset,
            input   wire    s_clk,
            input   wire    s_valid,
            
            input   wire    m_reset,
            input   wire    m_clk,
            output  wire    m_valid,
            input   wire    m_ready
        );
    
    
    // gray code
    wire    [PTR_WIDTH-1:0] s_bin;
    wire    [PTR_WIDTH-1:0] s_gray;
    wire    [PTR_WIDTH-1:0] m_gray;
    wire    [PTR_WIDTH-1:0] m_bin;
    jelly_func_binary_to_graycode
            #(
                .WIDTH  (PTR_WIDTH)
            )
        i_func_binary_to_graycode
            (
                .binary     (s_bin),
                .graycode   (s_gray)
            );
    
    jelly_func_graycode_to_binary
            #(
                .WIDTH      (PTR_WIDTH)
            )
        i_func_graycode_to_binary
            (
                .graycode   (m_gray),
                .binary     (m_bin)
            );
    
    
    reg     [PTR_WIDTH-1:0] reg_s_ptr;
    reg     [PTR_WIDTH-1:0] reg_s_gray;
    
    wire    [PTR_WIDTH-1:0] next_s_ptr = reg_s_ptr + s_valid;
    
    always @(posedge s_clk) begin
        if ( s_reset ) begin
            reg_s_ptr  <= {PTR_WIDTH{1'b0}};
            reg_s_gray <= {PTR_WIDTH{1'b0}};
        end
        else begin
            reg_s_ptr  <= next_s_ptr;
            reg_s_gray <= s_gray;
        end
    end
    
    assign s_bin = next_s_ptr;
    
    (* ASYNC_REG="true" *)  reg     [PTR_WIDTH-1:0] reg_m_gray_ff, reg_m_gray;
                            reg     [PTR_WIDTH-1:0] reg_m_bin;
    
    assign m_gray = reg_m_gray;
    
    always @(posedge m_clk) begin
        if ( m_reset ) begin
            reg_m_gray_ff <= {PTR_WIDTH{1'b0}};
            reg_m_gray    <= {PTR_WIDTH{1'b0}};
            reg_m_bin     <= {PTR_WIDTH{1'b0}};
        end
        else begin
            reg_m_gray_ff <= reg_s_gray;
            reg_m_gray    <= reg_m_gray_ff;
            reg_m_bin     <= m_bin;
        end
    end
    
    wire    [PTR_WIDTH-1:0]         ptr_diff = m_bin - reg_m_bin;
    
    reg                             reg_valid;
    reg     [CAPACITY_WIDTH-1:0]    reg_capacity;
    wire    [CAPACITY_WIDTH-1:0]    next_capacity = reg_capacity + ptr_diff - (m_valid & m_ready);
    
    always @(posedge m_clk) begin
        if ( m_reset ) begin
            reg_valid    <= 1'b0;
            reg_capacity <= {CAPACITY_WIDTH{1'b0}};
        end
        else begin
            reg_valid    <= (next_capacity != 0);
            reg_capacity <= next_capacity;
        end
    end
    
    assign m_valid = reg_valid;
    
endmodule
module jelly_demultiplexer
        #(
            parameter   SEL_WIDTH = 2,
            parameter   NUM       = (1 << SEL_WIDTH),
            parameter   IN_WIDTH  = 8,
            parameter   OUT_WIDTH = (IN_WIDTH  * NUM),
            
            parameter   SEL_BITS  = SEL_WIDTH > 0 ? SEL_WIDTH : 1
        )
        (
            input   wire                        endian,
            input   wire    [SEL_BITS-1:0]      sel,
            input   wire    [IN_WIDTH-1:0]      din,
            output  wire    [OUT_WIDTH-1:0]     dout
        );
    
    generate
    if ( SEL_WIDTH > 0 ) begin
        reg     [OUT_WIDTH-1:0]     sig_dout;
        
        integer i;
        integer j;
        always @* begin
            sig_dout = {OUT_WIDTH{1'b0}};
            for ( i = 0; i < NUM; i = i + 1 ) begin
                if ( i == (sel ^ {SEL_WIDTH{endian}}) ) begin
                    for ( j = 0; j < IN_WIDTH; j = j + 1 ) begin
                        sig_dout[IN_WIDTH*i + j] = din[j];
                    end
                end
            end
        end
        assign dout = sig_dout;
    end
    else begin
        assign dout = din;
    end
    endgenerate
    
endmodule
module jelly_multiplexer
        #(
            parameter   SEL_WIDTH = 2,
            parameter   NUM       = (1 << SEL_WIDTH),
            parameter   OUT_WIDTH = 8,
            parameter   IN_WIDTH  = (OUT_WIDTH * NUM),
            
            parameter   SEL_BITS  = SEL_WIDTH > 0 ? SEL_WIDTH : 1
        )
        (
            input   wire                        endian,
            input   wire    [SEL_BITS-1:0]      sel,
            input   wire    [IN_WIDTH-1:0]      din,
            output  wire    [OUT_WIDTH-1:0]     dout
        );
    
    // verilator lint_off WIDTH
    generate
    if ( SEL_WIDTH > 0 ) begin
        reg     [OUT_WIDTH-1:0]     sig_dout;
        
        integer i;
        integer j;
        always @* begin
            sig_dout = {OUT_WIDTH{1'b0}};
            for ( i = 0; i < NUM; i = i + 1 ) begin
                if ( i == (sel ^ {SEL_WIDTH{endian}}) ) begin
                    for ( j = 0; j < OUT_WIDTH; j = j + 1 ) begin
                        sig_dout[j] = din[OUT_WIDTH*i + j];
                    end
                end
            end
        end
        
        assign dout = sig_dout;
    end
    else begin
        assign dout = din;
    end
    endgenerate
    // verilator lint_on WIDTH
    
endmodule
module jelly_pulse_async
        #(
            parameter   ASYNC = 1
        )
        (
            input   wire                        s_reset,
            input   wire                        s_clk,
            input   wire                        s_pulse,
            
            input   wire                        m_reset,
            input   wire                        m_clk,
            output  wire                        m_pulse
        );
    
    generate
    if ( ASYNC ) begin : blk_async
        // semaphore
                                    reg                         reg_s_sem0;
        
        (* ASYNC_REG = "true" *)    reg                         reg_m_sem0_ff;
                                    reg                         reg_m_sem0;
                                    reg                         reg_m_sem1;
        
        
        
        // slave
        always @(posedge s_clk) begin
            if ( s_reset ) begin
                reg_s_sem0 <= 1'b0;
            end
            else begin
                if ( s_pulse ) begin
                    reg_s_sem0 <= ~reg_s_sem0;
                end
            end
        end
        
        
        // master
        always @(posedge m_clk) begin
            if ( m_reset ) begin
                reg_m_sem0_ff <= 1'b0;
                reg_m_sem0    <= 1'b0;
                reg_m_sem1    <= 1'b0;
            end
            else begin
                // double latch
                reg_m_sem0_ff <= reg_s_sem0;
                reg_m_sem0    <= reg_m_sem0_ff;
                
                if ( m_pulse ) begin
                    reg_m_sem1 <= ~reg_m_sem1;
                end
            end
        end
        
        assign m_pulse = (reg_m_sem0 != reg_m_sem1);
    end
    else begin : blk_sync
        assign m_pulse = s_pulse;
    end
    endgenerate
    
    
endmodule
module jelly_ram_singleport
        #(
            parameter   ADDR_WIDTH   = 8,
            parameter   DATA_WIDTH   = 8,
            parameter   MEM_SIZE     = (1 << ADDR_WIDTH),
            parameter   RAM_TYPE     = "block",
            parameter   DOUT_REGS    = 0,
            parameter   MODE         = "WRITE_FIRST",
            
            parameter   FILLMEM      = 0,
            parameter   FILLMEM_DATA = 0,
            parameter   READMEMB     = 0,
            parameter   READMEMH     = 0,
            parameter   READMEM_FILE = ""
        )
        (
            input   wire                        clk,
            input   wire                        en,
            input   wire                        regcke,
            input   wire                        we,
            input   wire    [ADDR_WIDTH-1:0]    addr,
            input   wire    [DATA_WIDTH-1:0]    din,
            output  wire    [DATA_WIDTH-1:0]    dout
        );
    
    // memory
    (* ram_style = RAM_TYPE *)
    reg     [DATA_WIDTH-1:0]    mem [0:MEM_SIZE-1];
    
    reg     [DATA_WIDTH-1:0]    tmp_dout;
    
    generate
    if ( MODE == "WRITE_FIRST" ) begin : blk_write_first
        // write first
        always @ ( posedge clk ) begin
            if ( en ) begin
                if ( we ) begin
                    mem[addr] <= din;
                end
                
                if ( we ) begin
                    tmp_dout <= din;
                end
                else begin
                    tmp_dout <= mem[addr];
                end
            end
        end
    end
    else begin : blk_read_first
        // read first
        always @ ( posedge clk ) begin
            if ( en ) begin
                if ( we ) begin
                    mem[addr] <= din;
                end
                tmp_dout <= mem[addr];
            end
        end
    end
    
    // DOUT FF insert
    if ( DOUT_REGS ) begin : blk_dout_regs
        reg     [DATA_WIDTH-1:0]    reg_dout;
        always @(posedge clk) begin
            if ( regcke ) begin
                reg_dout <= tmp_dout;
            end
        end
        assign dout = reg_dout;
    end
    else begin: blk_dout
        assign dout = tmp_dout;
    end
    endgenerate
    
    
`ifndef ALTERA
    // initialize
    integer i;
    initial begin
        if ( FILLMEM ) begin
            for ( i = 0; i < MEM_SIZE; i = i + 1 ) begin
                mem[i] = FILLMEM_DATA;
            end
        end
        
        if ( READMEMB ) begin
            $display("readmemb:%s", READMEM_FILE);
            $readmemb(READMEM_FILE, mem);
        end
        
        if ( READMEMH ) begin
            $display("readmemh:%s", READMEM_FILE);
            $readmemh(READMEM_FILE, mem);
        end
    end
`endif
    
endmodule
module jelly_reverse
        #(
            parameter   WIDTH = 8
        )
        (
            input   wire                    reverse,
            
            input   wire    [WIDTH-1:0]     din,
            output  wire    [WIDTH-1:0]     dout
        );
    
    reg     [WIDTH-1:0]     rev_data;
    
    integer i;
    always @* begin
        rev_data = {WIDTH{1'b0}};
        for ( i = 0; i < WIDTH; i = i + 1 ) begin
            rev_data[i] = din[WIDTH-1-i];
        end
    end
    
    assign dout = reverse ? rev_data : din;
    
endmodule
module jelly_counter_async
        #(
            parameter   ASYNC         = 1,
            parameter   COUNTER_WIDTH = 16
        )
        (
            input   wire                        s_reset,
            input   wire                        s_clk,
            input   wire    [COUNTER_WIDTH-1:0] s_add,
            input   wire                        s_valid,
            
            input   wire                        m_reset,
            input   wire                        m_clk,
            output  wire    [COUNTER_WIDTH-1:0] m_counter,
            output  wire                        m_valid
        );
    
    
    generate
    if ( ASYNC ) begin : blk_async
        
        wire                            s_ready;
        
        reg     [COUNTER_WIDTH-1:0]     reg_counter, next_counter;
        
        always @* begin
            next_counter = reg_counter;
            
            if ( s_ready ) begin
                next_counter = {COUNTER_WIDTH{1'b0}};
            end
            
            if ( s_valid ) begin
                next_counter = next_counter + s_add;
            end
        end
        
        always @(posedge s_clk) begin
            if ( s_reset ) begin
                reg_counter <= {COUNTER_WIDTH{1'b0}};
            end
            else begin
                reg_counter <= next_counter;
            end
        end
        
        
        jelly_data_async
                #(
                    .DATA_WIDTH     (COUNTER_WIDTH)
                )
            i_data_async
                (
                    .s_reset        (s_reset),
                    .s_clk          (s_clk),
                    .s_data         (reg_counter),
                    .s_valid        (1'b1),
                    .s_ready        (s_ready),
                    
                    .m_reset        (m_reset),
                    .m_clk          (m_clk),
                    .m_data         (m_counter),
                    .m_valid        (m_valid),
                    .m_ready        (1'b1)
                );
    end
    else begin : blk_bypass
        assign m_counter = s_add;
        assign m_valid   = s_valid;
    end
    endgenerate
    
endmodule
module jelly_data_switch_simple
        #(
            parameter   NUM         = 16,
            parameter   ID_WIDTH    = 4,
            parameter   DATA_WIDTH  = 32,
            parameter   USE_M_READY = 1
        )
        (
            input   wire                            reset,
            input   wire                            clk,
            input   wire                            cke,
            
            input   wire    [ID_WIDTH-1:0]          s_id,
            input   wire    [DATA_WIDTH-1:0]        s_data,
            input   wire                            s_valid,
            
            output  wire    [NUM*DATA_WIDTH-1:0]    m_data,
            output  wire    [NUM-1:0]               m_valid
        );
    
    
    // -----------------------------------------
    //  switch
    // -----------------------------------------
    
    reg     [NUM-1:0]           reg_valid;
    reg     [DATA_WIDTH-1:0]    reg_data;
    
    integer                     i;
    
    always @(posedge clk) begin
        if ( cke ) begin
            reg_data <= s_data;
        end
    end
    
    always @(posedge clk) begin
        if ( reset ) begin
            reg_valid <= {NUM{1'b0}};
        end
        else if( cke ) begin
            reg_valid <= {NUM{1'b0}};
            for ( i = 0; i < NUM; i = i+1 ) begin
                if ( s_id == i ) begin
                    reg_valid[i] <= s_valid;
                end
            end
        end
    end
        
    assign m_data  = {NUM{reg_data}};
    assign m_valid = reg_valid;
    
endmodule
module jelly_fifo_read_fwtf
        #(
            parameter   DATA_WIDTH  = 8,
            parameter   PTR_WIDTH   = 8,
            parameter   DOUT_REGS   = 0,
            parameter   MASTER_REGS = 1
        )
        (
            input   wire                        reset,
            input   wire                        clk,
            
            output  wire                        rd_en,
            output  wire                        rd_regcke,
            input   wire    [DATA_WIDTH-1:0]    rd_data,
            input   wire                        rd_empty,
            input   wire    [PTR_WIDTH:0]       rd_count,
            
            output  wire    [DATA_WIDTH-1:0]    m_data,
            output  wire                        m_valid,
            input   wire                        m_ready,
            output  wire    [PTR_WIDTH:0]       m_count
        );
    
    localparam PIPELINE_STAGES = 1 + DOUT_REGS;

    wire    [PIPELINE_STAGES-1:0]   stage_cke;
    wire    [PIPELINE_STAGES-1:0]   stage_valid;
    wire                            buffered;
    
    jelly_pipeline_control
            #(
                .PIPELINE_STAGES    (PIPELINE_STAGES),
                .S_DATA_WIDTH       (1),
                .M_DATA_WIDTH       (DATA_WIDTH),
                .AUTO_VALID         (1),
                .MASTER_IN_REGS     (MASTER_REGS),
                .MASTER_OUT_REGS    (MASTER_REGS)
            )
        i_pipeline_control
            (
                .reset              (reset),
                .clk                (clk),
                .cke                (1'b1),
                
                .s_data             (1'b0),
                .s_valid            (!rd_empty),
                .s_ready            (),
                
                .m_data             (m_data),
                .m_valid            (m_valid),
                .m_ready            (m_ready),
                
                .stage_cke          (stage_cke),
                .stage_valid        (stage_valid),
                .next_valid         ({PIPELINE_STAGES{1'bx}}),
                .src_data           (),
                .src_valid          (),
                .sink_data          (rd_data),
                .buffered           (buffered)
            );
    
    assign rd_en   = stage_cke[0];
    
    generate
    if ( DOUT_REGS ) begin
        assign rd_regcke = stage_cke[1];
        assign m_count   = rd_count + m_valid + buffered + stage_valid[0] + stage_valid[1];
    end
    else begin
        assign rd_regcke = 1'b0;
        assign m_count   = rd_count + m_valid + buffered + stage_valid[0];
    end
    endgenerate
    
    
endmodule
module jelly_data_shift_register_lut
        #(
            parameter   SEL_WIDTH  = 5,
            parameter   NUM        = (1 << SEL_WIDTH),
            parameter   DATA_WIDTH = 8,
            parameter   DEVICE     = "RTL"
        )
        (
            input   wire                        clk,
            input   wire                        cke,
            
            input   wire    [SEL_WIDTH-1:0]     sel,
            input   wire    [DATA_WIDTH-1:0]    in_data,
            output  wire    [DATA_WIDTH-1:0]    out_data
        );
    
    genvar      i;
    
    generate
`ifndef VERILATOR
    if ( SEL_WIDTH <= 5
            && (DEVICE == "SPARTAN6"
             || DEVICE == "VIRTEX6"
             || DEVICE == "7SERIES"
             || DEVICE == "ULTRASCALE"
             || DEVICE == "ULTRASCALE_PLUS_ES1"
             || DEVICE == "ULTRASCALE_PLUS_ES2") ) begin : xilinx_srlc32e
        
        for ( i = 0; i < DATA_WIDTH; i = i+1 ) begin : loop_shift
            // XILINX
            wire    [4:0]   a = sel;
            SRLC32E
                    #(
                        .INIT   (32'h00000000)
                    )
                i_srlc32e
                    (
                        .Q      (out_data[i]),
                        .Q31    (),
                        .A      (a),
                        .CE     (cke),
                        .CLK    (clk),
                        .D      (in_data[i])
                    );
        end
    end
`else
    if (0) begin end 
`endif
    else begin : blk_rtl
        // RTL
        reg     [NUM*DATA_WIDTH-1:0]    reg_data;
        always @(posedge clk) begin
            if ( cke ) begin
                reg_data <= {reg_data, in_data};
            end
        end
        
        assign out_data = reg_data[sel*DATA_WIDTH +: DATA_WIDTH];
    end
    endgenerate
    
    
endmodule
module iob_diff
  #(
    parameter DATA_W = 32
    )
   (
    input               clk,
    input               rst,

    input               en,
    input [DATA_W-1:0]  data_in,
    output [DATA_W-1:0] data_out
    );

   reg [DATA_W-1:0]     data_in_reg;
   always @(posedge clk, posedge rst) begin
      if (rst) begin
         data_in_reg <= {DATA_W{1'b0}};
      end else if (en) begin
         data_in_reg <= data_in;
      end
   end

   assign data_out = data_in - data_in_reg;

endmodule
module iob_s2f_sync
  #(
    parameter DATA_W = 32
    )
   (
    input                   clk,

    input                   rst,
    input [DATA_W-1:0]      rst_val,

    input [DATA_W-1:0]      data_in,
    output reg [DATA_W-1:0] data_out
    );

   reg [DATA_W-1:0]         sync;
   always @(posedge clk, posedge rst) begin
      if (rst) begin
         sync <= rst_val;
         data_out <= rst_val;
      end else begin
         sync <= data_in;
         data_out <= sync;
      end
   end

endmodule
module iob_sipo_reg_are
  #(
    parameter DATA_W = 32
    )
   (

    input               clk,
    input               rst,
    input               en,

    //parallel input
    input               s_in,

    //serial output
    output [DATA_W-1:0] p_out
    );

   reg [DATA_W-1:0]  data_reg;
   
   always @(posedge clk, posedge rst)
     if(rst)
       data_reg <= 1'b0;
     else if (en)
       data_reg <= (data_reg<<1)|s_in;

   assign p_out = data_reg;
   
endmodule
module iob_reverse
  #(
    parameter DATA_W = 32
    )
   (
    input [DATA_W-1:0]      data_in,
    output reg [DATA_W-1:0] data_out
    );

   integer i;

   always @* begin
      for (i=0; i < DATA_W; i=i+1) begin : reverse
         data_out[i] = data_in[DATA_W-1-i];
      end
   end

endmodule
module iob_modcnt
  #(
    parameter DATA_W = 32
    )
   (

    input                   clk,
    input                   arst,
    input                   rst,
    input                   en,

    input [DATA_W-1:0]      load_val,

    //masters interface
    input [DATA_W-1:0]      mod,

    //slave interface
    output reg [DATA_W-1:0] cnt
    );

   reg                      loaded;
   
   always @(posedge clk, posedge arst) 
      if(arst) begin
         cnt <= -1'b1;
         loaded <= 1'b0;
      end else if (rst) begin 
         cnt <= -1'b1;
         loaded <= 1'b0;
      end else if (!loaded) begin
          cnt <= load_val;
          loaded <= 1'b1;
      end else if (en)
        if (cnt == (mod-1'b1))
          cnt <= 1'b0;
        else
          cnt <= cnt + 1'b1;
   
endmodule
module iob_wstrb2offset
   #(
     parameter DATA_W = 32
     )
   (
    input [DATA_W/8-1:0] wstrb,
    output reg [$clog2(DATA_W/8)-1:0] wr_addr_offset
    );

   generate if (DATA_W==32)
     always @* begin
        case (wstrb)
          4'b0010: wr_addr_offset = 2'b01;
          4'b0100: wr_addr_offset = 2'b10;
          4'b1000: wr_addr_offset = 2'b11;
          4'b1100: wr_addr_offset = 2'b10;
          default: wr_addr_offset = 2'b00;
        endcase
     end
   endgenerate
endmodule
module iob_piso_reg_are
  #(
    parameter DATA_W = 32
    )
   (

    input                   clk,
    input                   rst,
    input                   ld,
    input                   en,

    //parallel input
    input [DATA_W-1:0]      p_in,

    //serial output
    output s_out
    );

   reg [DATA_W-1:0]  data_reg;
   
   always @(posedge clk, posedge rst)
     if(rst)
       data_reg <= 1'b0;
     else if (ld)
       data_reg <= p_in;
     else if (en)
       data_reg <= data_reg <<1;

   assign s_out = data_reg[DATA_W-1];
   
endmodule
module iob_acc
  #(
    parameter DATA_W = 32
    )
   (
    input                   clk,

    input                   rst,
    input [DATA_W-1:0]      rst_val,

    input                   en,
    input [DATA_W-1:0]      incr,
    output reg [DATA_W-1:0] data_out
    );

   always @(posedge clk, posedge rst) begin
      if (rst) begin
         data_out <= rst_val;
      end else if (en) begin
         data_out <= data_out + incr;
      end
   end

endmodule
module iob_counter
  #(
    parameter DATA_W = 32
    )
   (
    input                   clk,
    input                   arst,
    input                   rst,

    input                   en,
    output reg [DATA_W-1:0] data_out
    );

   always @(posedge clk, posedge arst) begin
      if (arst) begin
         data_out <= {DATA_W{1'b0}};
      end else if (rst) begin
         data_out <= {DATA_W{1'b0}};
      end else if (en) begin
         data_out <= data_out + 1'b1;
      end
   end

endmodule
module iob_merge
  #(
    parameter N_MASTERS = 2,
    parameter DATA_W = 32,
    parameter ADDR_W = 32
    )
   (

    input                              clk,
    input                              rst,

    //masters interface
    input [N_MASTERS*`REQ_W-1:0]       m_req,
    output reg [N_MASTERS*`RESP_W-1:0] m_resp,

    //slave interface
    output reg [`REQ_W-1:0]            s_req,
    input [`RESP_W-1:0]                s_resp
    );


   localparam Nb=$clog2(N_MASTERS)+($clog2(N_MASTERS)==0);
   

   //                               
   //priority encoder: most significant bus has priority   
   //
   reg [Nb-1:0]                        sel, sel_reg;
   
   //select enable
   reg                                 sel_en; 
   always @(posedge clk, posedge rst)
     if(rst)
       sel_en <= 1'b1;
     else if(s_req[`valid(0)])
       sel_en <= 1'b0;
     else if(s_resp[`ready(0)])
       sel_en <= ~s_req[`valid(0)];

   
   //select master
   integer                             k; 
   always @* begin
      sel = {Nb{1'b0}};
      for (k=0; k<N_MASTERS; k=k+1)
        if (~sel_en)
          sel = sel_reg;
        else if( m_req[`valid(k)] )
          sel = k[Nb-1:0];          
   end
   
   //
   //route master request to slave
   //  
   integer                             i;
   always @* begin
      s_req = {`REQ_W{1'b0}};
      for (i=0; i<N_MASTERS; i=i+1)
        if( i == sel )
          s_req = m_req[`req(i)];
   end

   //
   //route response from slave to previously selected master
   //

   //register master selection
   always @( posedge clk, posedge rst ) begin
      if( rst )
        sel_reg <= {Nb{1'b0}};
      else
        sel_reg <= sel;
   end
   
   //route
   integer                             j;
   always @* begin
      for (j=0; j<N_MASTERS; j=j+1)
        if( j == sel_reg )
          m_resp[`resp(j)] = s_resp;
        else
          m_resp[`resp(j)] = {`RESP_W{1'b0}};
   end

   
endmodule
module iob_reg
  #(
    parameter DATA_W = 0,
    parameter RST_VAL = 0
    )
   (
    input                   clk,
    input                   arst,
    input                   rst,
    input                   en,
    input [DATA_W-1:0]      data_in,
    output reg [DATA_W-1:0] data_out
    );

   //prevent width mismatch
   localparam [DATA_W-1:0] RST_VAL_INT = RST_VAL;
   
   always @(posedge clk, posedge arst) begin
      if (arst) begin
         data_out <= RST_VAL_INT;
      end else if (rst) begin
         data_out <= RST_VAL_INT;
      end else if (en) begin
         data_out <= data_in;
      end
   end

endmodule
module iob_f2s_1bit_sync
  (
   input  clk,
   input  in,
   output out
   );

   reg [1:0] sync;
   always @(posedge clk, posedge in) begin
      if (in) begin
         sync <= 2'b11;
      end else begin
         sync <= {sync[0], 1'b0};
      end
   end

   assign out = sync[1];

endmodule
module iob_split
  #(
    parameter DATA_W = 32,
    parameter ADDR_W = 32,
    parameter N_SLAVES = 2, //number of slaves
    parameter P_SLAVES = `REQ_W-2 //slave select word msb position
    )
   (
    input                            clk,
    input                            rst,

    //masters interface
    input [`REQ_W-1:0]               m_req,
    output reg [`RESP_W-1:0]         m_resp,

    //slave interface
    output reg [N_SLAVES*`REQ_W-1:0] s_req,
    input [N_SLAVES*`RESP_W-1:0]     s_resp
    );

   localparam  Nb=$clog2(N_SLAVES)+($clog2(N_SLAVES)==0);


   //slave select word
   wire [Nb-1:0] s_sel;
   assign s_sel = m_req[P_SLAVES -:Nb];

   //route master request to selected slave
   integer                           i;
   always @* begin
      /*
     $display("pslave %d", P_SLAVES+1);
     $display("mreq %x", m_req);
     $display("s_sel %x", s_sel);
   */
     for (i=0; i<N_SLAVES; i=i+1)
       if(i == s_sel)
         s_req[`req(i)] = m_req;
       else
         s_req[`req(i)] = {(`REQ_W){1'b0}};
   end

   //
   //route response from previously selected slave to master
   //

   //register the slave selection
   reg [Nb-1:0]                       s_sel_reg;
   always @( posedge clk, posedge rst ) begin
      if( rst )
        s_sel_reg <= {Nb{1'b0}};
      else
        s_sel_reg <= s_sel;
   end

   //route
   integer                           j;
   always @* begin
      m_resp = {`RESP_W{1'b0}};
      for (j=0; j<N_SLAVES; j=j+1)
        if( j == s_sel_reg )
          m_resp = s_resp[`resp(j)];
   end

endmodule
module iob_sync
  #(
    parameter WIDTH = 0,
    parameter RST_VAL = 0
    )
  (
   input clk,
   input rst,
   input [WIDTH-1:0] signal_in,
   output reg [WIDTH-1:0] signal_out
   );
   

   reg [WIDTH-1:0]        sync_reg;

   always @(posedge clk, posedge rst) begin : iob_sync
      if(rst) begin
         sync_reg <= RST_VAL;
         signal_out <= RST_VAL;
      end else begin
         sync_reg <= signal_in;
         signal_out <= sync_reg;
      end
   end
   
endmodule
module axil2iob
  #(
    parameter AXIL_ADDR_W = 32, // Width of address bus in bits
    parameter AXIL_DATA_W = 32  // Width of data bus in bits
    )
   (
    // AXI-4 lite slave interface
`include "axil_s_port.vh"

    // Native master interface
    output                     valid,
    output [AXIL_ADDR_W-1:0]   addr,
    output [AXIL_DATA_W-1:0]   wdata,
    output [AXIL_DATA_W/8-1:0] wstrb,
    input [AXIL_DATA_W-1:0]    rdata,
    input                      ready,
`include "iob_gen_if.vh"
    );

   reg                         awvalid_ack;
   reg                         arvalid_ack;

   assign axil_rdata = rdata;

   // AXI IDs
   assign axil_bid = `AXI_ID_W'd0;
   assign axil_rid = `AXI_ID_W'd0;

   // Response is always OK
   assign axil_bresp = `AXI_RESP_W'd0;
   assign axil_rresp = `AXI_RESP_W'd0;

   assign valid = (axil_wvalid | axil_arvalid) & ~ready;
   assign addr  = axil_wvalid? axil_awaddr: axil_araddr;
   assign wstrb = axil_wvalid? axil_wstrb: {(AXIL_DATA_W/8){1'b0}};
   assign wdata = axil_wdata;

   assign axil_awready = awvalid_ack & ready;
   assign axil_wready  = awvalid_ack & ready;
   assign axil_arready = arvalid_ack & ready;
   assign axil_rvalid  = arvalid_ack & ready;

   reg                         axil_bvalid_int;
   assign axil_bvalid = axil_bvalid_int;
   always @(posedge clk, posedge rst) begin
      if (rst) begin
         axil_bvalid_int <= 1'b0;
      end else begin
         axil_bvalid_int <= axil_wready;
      end
   end

   always @(posedge clk, posedge rst) begin
      if (rst) begin
         awvalid_ack <= 1'b0;
      end else if (axil_awvalid & ~awvalid_ack) begin
         awvalid_ack <= 1'b1;
      end else if (ready) begin
         awvalid_ack <= 1'b0;
      end
   end

   always @(posedge clk, posedge rst) begin
      if (rst) begin
         arvalid_ack <= 1'b0;
      end else if (axil_arvalid & ~arvalid_ack) begin
         arvalid_ack <= 1'b1;
      end else if (ready) begin
         arvalid_ack <= 1'b0;
      end
   end

endmodule
module iob_ram_2p_be_tb;

   // Inputs
   reg clk;

   // Write signals
   reg w_en;
   reg [`DATA_W-1:0] w_data;
   reg [`ADDR_W-1:0] w_addr;


   // Read signals
   reg               r_en;
   reg [`ADDR_W-1:0] r_addr;
   wire [`DATA_W-1:0] r_data;

   integer            i, seq_ini;

   parameter clk_per = 10; // clk period = 10 timeticks

   initial begin
      clk = 1;
      r_en = 0;
      w_en = 0;
      r_addr = 0;
      w_addr = 0;
      w_data = 0;

      // Number from which to start the incremental sequence to write into the RAM
      seq_ini = 32;

      // optional VCD
`ifdef VCD
      $dumpfile("uut.vcd");
      $dumpvars();
`endif

      @(posedge clk) #1;
      w_en = 1;

      // Write all the locations of RAM
      for(i = 0; i < 2**`ADDR_W; i = i + 1) begin
         w_data = i+seq_ini;
         w_addr = i;
         @(posedge clk) #1;
      end

      w_en = 0;
      @(posedge clk) #1;

      // Read all the locations of RAM with r_en = 0
      r_en = 0;
      @(posedge clk) #1;

      for(i = 0; i < 2**`ADDR_W; i = i + 1) begin
         r_addr = i;
         @(posedge clk) #1;
         if(r_data != 0) begin
            $display("ERROR: with r_en = 0, at position %0d, r_data should be 0 but is %d", i, r_data);
            $finish;
         end
      end

      r_en = 1;
      @(posedge clk) #1;

      // Read all the locations of RAM with r_en = 1
      for(i = 0; i < 2**`ADDR_W; i = i + 1) begin
         r_addr = i;
         @(posedge clk) #1;
         if(r_data != i+seq_ini) begin
            $display("ERROR: on position %0d, r_data is %d where it should be %0d", i, r_data, i+seq_ini);
            $finish;
         end
      end

      r_en = 0;

      #(5*clk_per);
      $display("%c[1;34m",27);
      $display("Test completed successfully.");
      $display("%c[0m",27);
      $finish;
   end

   // Instantiate the Unit Under Test (UUT)
   iob_ram_2p_be
     #(
       .DATA_W(`DATA_W),
       .ADDR_W(`ADDR_W)
       )
   uut
     (
      .clk(clk),

      .w_en(w_en),
      .w_addr(w_addr),
      .w_data(w_data),

      .r_en(r_en),
      .r_addr(r_addr),
      .r_data(r_data)
      );

   // Clock
   always #(clk_per/2) clk = ~clk;

endmodule
module iob_ram_2p_be
  #( 
     parameter HEXFILE = "none",
     parameter DATA_W = 0,
     parameter ADDR_W = 0
     ) 
   (
    input                   clk,

    //write port
    input [DATA_W/8-1:0]    w_en,
    input [ADDR_W-1:0]      w_addr,
    input [DATA_W-1:0]      w_data,

    //read port
    input                   r_en,
    input [ADDR_W-1:0]      r_addr,
    output reg [DATA_W-1:0] r_data
    );

   localparam COL_W = 8;
   localparam NUM_COL = DATA_W/COL_W;

`ifdef IS_CYCLONEV
   localparam file_suffix = {"7","6","5","4","3","2","1","0"};

   genvar                    i;
   generate
      for (i=0; i < NUM_COL; i=i+1) begin: ram_col
         localparam mem_init_file_int = (HEXFILE != "none")? {HEXFILE, "_", file_suffix[8*(i+1)-1 -: 8], ".hex"}: "none";

         iob_ram_2p
             #(
               .HEXFILE(mem_init_file_int),
               .ADDR_W(ADDR_W),
               .DATA_W(COL_W)
               ) ram
           (
            .clk   (clk),

            .w_en   (w_en[i]),
            .w_addr (w_addr),
            .w_data (w_data[i*COL_W +: COL_W]),
            .r_en   (r_en),
            .r_addr (r_addr),
            .r_data (r_data[i*COL_W +: COL_W])
            );
      end
   endgenerate
`else // !IS_CYCLONEV
   //this allows ISE 14.7 to work; do not remove
   localparam mem_init_file_int = HEXFILE;

   // Declare the RAM
   reg [DATA_W-1:0]         mem [(2**ADDR_W)-1:0];

   // Initialize the RAM
   initial
     if(mem_init_file_int != "none")
       $readmemh(mem_init_file_int, mem, 0, (2**ADDR_W) - 1);

   //read port
   always @(posedge clk)
      if(r_en)
        r_data <= mem[r_addr];

   //write port
   integer                   i;
   always @(posedge clk) begin
      for (i=0; i < NUM_COL; i=i+1) begin
         if (w_en[i]) begin
            mem[w_addr][i*COL_W +: COL_W] <= w_data[i*COL_W +: COL_W];
         end
      end
   end
`endif

endmodule
module umi_pipeline
  #(parameter CW  = 32,
    parameter AW  = 64,
    parameter DW  = 256
    )
   (// clock, reset
    input               clk,
    input               nreset,
    // Incoming UMI request
    input               umi_in_valid,
    input [CW-1:0]      umi_in_cmd,
    input [AW-1:0]      umi_in_dstaddr,
    input [AW-1:0]      umi_in_srcaddr,
    input [DW-1:0]      umi_in_data,
    // Outgoing UMI response
    output reg          umi_out_valid,
    output reg [CW-1:0] umi_out_cmd,
    output reg [AW-1:0] umi_out_dstaddr,
    output reg [AW-1:0] umi_out_srcaddr,
    output reg [DW-1:0] umi_out_data,
    input               umi_out_ready
    );

   // valid
   always @ (posedge clk or negedge nreset)
     if(!nreset)
       umi_out_valid <= 'b0;
     else if (umi_out_ready)
       umi_out_valid <= umi_in_valid;

   // packet
   always @ (posedge clk)
     if (umi_out_ready & umi_in_valid)
       begin
          umi_out_cmd[CW-1:0]     <= umi_in_cmd[CW-1:0];
          umi_out_dstaddr[AW-1:0] <= umi_in_dstaddr[AW-1:0];
          umi_out_srcaddr[AW-1:0] <= umi_in_srcaddr[AW-1:0];
          umi_out_data[DW-1:0]    <= umi_in_data[DW-1:0];
       end

endmodule
module umi_priority
  #(parameter N   = 4    // number of inputs
    )
   (input [N-1:0]  requests, // request vector ([0] is highest priority)
    output [N-1:0] grants    // outgoing grant vector
    );

   wire [N-1:0]   mask;
   genvar         j;

   // priority maskx
   assign mask[0] = 1'b0;
   for (j=N-1; j>=1; j=j-1)
     begin : ipri
        assign mask[j] = |requests[j-1:0];
     end

   // priority grant circuit
   assign grants[N-1:0] = requests[N-1:0] & ~mask[N-1:0];

endmodule // umi_priority