dakies/OSS_Verilog huggingface dataset:
module jelly_func_binary_to_graycode
        #(
            parameter                       WIDTH = 4
        )
        (
            input   wire    [WIDTH-1:0]     binary,
            output  reg     [WIDTH-1:0]     graycode
        );
    
    integer i;
    always @* begin
        graycode[WIDTH-1] = binary[WIDTH-1];
        for ( i = WIDTH - 2; i >= 0; i = i-1 ) begin
            graycode[i] = binary[i+1] ^ binary[i];
        end
    end
    
endmodule
module jelly_func_shift
        #(
            parameter   IN_WIDTH    = 32,
            parameter   OUT_WIDTH   = 32,
            parameter   SHIFT_LEFT  = 0,    // 負の値もOK
            parameter   SHIFT_RIGHT = 0,    // 負の値もOK
            parameter   ARITHMETIC  = 0,
            parameter   ROUNDUP     = 0
        )
        (
            input   wire    [IN_WIDTH-1:0]  in,
            output  wire    [OUT_WIDTH-1:0] out
        );
    
    localparam  VAL = SHIFT_RIGHT - SHIFT_LEFT;
    
    generate
    if ( ARITHMETIC && VAL >= 0 && ROUNDUP ) begin : blk_sar_roundup
        assign out = ((in + ((1 << VAL) - 1)) >>> VAL);
    end
    else if ( ARITHMETIC && VAL >= 0 && !ROUNDUP ) begin : blk_sar
        assign out = (in >>> VAL);
    end
    else if ( ARITHMETIC && VAL < 0 ) begin : blk_sal
        assign out = (in <<< (-VAL));
    end
    else if ( !ARITHMETIC && VAL >= 0 && ROUNDUP ) begin : blk_slr_roundup
        assign out = ((in + ((1 << VAL) - 1)) >> VAL);
    end
    else if ( !ARITHMETIC && VAL >= 0 && !ROUNDUP ) begin : blk_slr
        assign out = (in >> VAL);
    end
    else if ( !ARITHMETIC && VAL < 0 ) begin : blk_sll
        assign out = (in << (-VAL));
    end
    endgenerate
    
    
endmodule
module jelly_colormap
        #(
            parameter   USER_WIDTH = 0,
            parameter   COLORMAP   = "JET",   // "HSV"
            
            parameter   USER_BITS  = USER_WIDTH > 0 ? USER_WIDTH : 1
        )
        (
            input   wire                        reset,
            input   wire                        clk,
            input   wire                        cke,
            
            input   wire    [USER_BITS-1:0]     s_user,
            input   wire    [7:0]               s_data,
            input   wire                        s_valid,
            output  wire                        s_ready,
            
            output  wire     [USER_BITS-1:0]    m_user,
            output  wire    [7:0]               m_data,
            output  wire    [23:0]              m_color,
            output  wire                        m_valid,
            input   wire                        m_ready
        );
    
    
    wire    [23:0]  s_color;
    jelly_colormap_table
            #(
                .COLORMAP       (COLORMAP)
            )
        i_colormap_table
            (
                .in_data        (s_data),
                .out_data       (s_color)
            );
    
    reg     [USER_BITS-1:0]     reg_user;
    reg     [7:0]               reg_data;
    reg     [23:0]              reg_color;
    reg                         reg_valid;
    
    always @(posedge clk) begin
        if ( reset ) begin
            reg_user  <= {USER_BITS{1'bx}};
            reg_data  <= {8{1'bx}};
            reg_color <= {24{1'bx}};
            reg_valid <= 1'b0;
        end
        else if ( cke ) begin
            if ( s_ready ) begin
                reg_user  <= s_user;
                reg_data  <= s_data;
                reg_color <= s_color;
                reg_valid <= s_valid;
            end
        end
    end
    
    assign s_ready = (!m_valid || m_ready);
    
    assign m_user  = reg_user;
    assign m_data  = reg_data;
    assign m_color = reg_color;
    assign m_valid = reg_valid;
    
endmodule
module jelly_data_joint
        #(
            parameter   NUM         = 16,
            parameter   ID_WIDTH    = 4,
            parameter   DATA_WIDTH  = 32,
            parameter   S_REGS      = 1,
            parameter   M_REGS      = 1,
            parameter   ALGORITHM   = "PRIORITY",
            parameter   USE_M_READY = 1,
            parameter   NO_CONFLICT = 0
        )
        (
            input   wire                            reset,
            input   wire                            clk,
            input   wire                            cke,
            
            input   wire    [NUM*DATA_WIDTH-1:0]    s_data,
            input   wire    [NUM-1:0]               s_valid,
            output  wire    [NUM-1:0]               s_ready,
            
            output  wire    [ID_WIDTH-1:0]          m_id,
            output  wire    [DATA_WIDTH-1:0]        m_data,
            output  wire                            m_valid,
            input   wire                            m_ready
        );
    
    generate
    if ( ALGORITHM == "RINGBUS" ) begin : blk_ringbus
        jelly_data_arbiter_ring_bus
                #(
                    .S_NUM          (NUM),
                    .S_ID_WIDTH     (ID_WIDTH),
                    .M_NUM          (1),
                    .M_ID_WIDTH     (1),
                    .DATA_WIDTH     (DATA_WIDTH),
                    .NO_RING        (!USE_M_READY)
                )
            i_data_arbiter_ring_bus
                (
                    .reset          (reset),
                    .clk            (clk),
                    .cke            (cke),
                    
                    .s_id_to        (1'b0),
                    .s_data         (s_data),
                    .s_valid        (s_valid),
                    .s_ready        (s_ready),
                    
                    .m_id_from      (m_id),
                    .m_data         (m_data),
                    .m_valid        (m_valid),
                    .m_ready        (m_ready)
                );
    end
    else begin : blk_priority
        jelly_data_joint_priority
                #(
                    .NUM                (NUM),
                    .DATA_WIDTH         (DATA_WIDTH),
                    .NO_CONFLICT        (NO_CONFLICT),
                    .S_REGS             (S_REGS),
                    .M_REGS             (M_REGS)
                )
            i_data_joint_priority
                (
                    .reset              (reset),
                    .clk                (clk),
                    .cke                (cke),
                    
                    .s_data             (s_data ),
                    .s_valid            (s_valid),
                    .s_ready            (s_ready),
                    
                    .m_id               (m_id),
                    .m_data             (m_data ),
                    .m_valid            (m_valid),
                    .m_ready            (m_ready)
                );
    end
    endgenerate
    
endmodule
module jelly_capacity_buffer
        #(
            parameter   CAPACITY_WIDTH      = 32,               // オーバーフローしないサイズとする
            parameter   REQUEST_WIDTH       = CAPACITY_WIDTH,
            parameter   ISSUE_WIDTH         = CAPACITY_WIDTH,   // CAPACITY_WIDTH より大きくすること
            parameter   REQUEST_SIZE_OFFSET = 1'b0,
            parameter   ISSUE_SIZE_OFFSET   = 1'b0,
            
            parameter   INIT_REQUEST        = {CAPACITY_WIDTH{1'b0}}
        )
        (
            input   wire                            reset,
            input   wire                            clk,
            input   wire                            cke,
            
            output  wire    [CAPACITY_WIDTH-1:0]    queued_request,
            
            input   wire    [REQUEST_WIDTH-1:0]     s_request_size,
            input   wire                            s_request_valid,
            
            output  wire    [ISSUE_WIDTH-1:0]       m_issue_size,
            output  wire                            m_issue_valid,
            input   wire                            m_issue_ready
        );
    
    wire                            ready = (!m_issue_valid || m_issue_ready);
    
    reg     [CAPACITY_WIDTH-1:0]    reg_queued_request, next_queued_request;
    reg                             reg_request_empty,  next_request_empty;
    
    reg     [ISSUE_WIDTH-1:0]       reg_issue_size,     next_issue_size;
    reg                             reg_issue_valid,    next_issue_valid;
    
    always @(posedge clk) begin
        if ( reset ) begin
            reg_queued_request <= INIT_REQUEST;
            reg_request_empty  <= (INIT_REQUEST == 0);
            reg_issue_size     <= {ISSUE_WIDTH{1'bx}};
            reg_issue_valid    <= 1'b0;
        end
        else if ( cke ) begin
            reg_queued_request <= next_queued_request;
            reg_request_empty  <= next_request_empty;
            reg_issue_size     <= next_issue_size;
            reg_issue_valid    <= next_issue_valid;
        end
    end
    
    always @* begin
        next_queued_request = reg_queued_request;
        next_request_empty  = reg_request_empty;
        next_issue_size     = reg_issue_size;
        next_issue_valid    = reg_issue_valid;
        
        if ( m_issue_ready ) begin
            next_issue_valid = 1'b0;
        end
        
        if ( !next_issue_valid && !next_request_empty ) begin
            next_issue_size  = next_queued_request - ISSUE_SIZE_OFFSET;
            next_issue_valid = 1'b1;
            next_queued_request = 0;
            next_request_empty  = 1'b1;
        end
        
        if ( s_request_valid ) begin
            next_queued_request = next_queued_request + s_request_size + REQUEST_SIZE_OFFSET;
            next_request_empty  = (({1'b0, s_request_size} + REQUEST_SIZE_OFFSET) == 0);
        end
    end
    
    assign m_issue_size  = reg_issue_size;
    assign m_issue_valid = reg_issue_valid;
    
    assign queued_request = reg_queued_request;
    
endmodule
module jelly_rand_gen
        (
            input   wire            reset,
            input   wire            clk,
            input   wire            cke,
            
            input   wire    [15:0]  seed,
            output  wire            out
        );
    
    reg     [15:0]  lfsr;
    
    always @(posedge clk) begin
        if ( reset ) begin
            lfsr <= seed;
        end
        else if ( cke ) begin
            lfsr[15:1] <= lfsr[14:0];
            lfsr[0]    <= lfsr[15] ^ lfsr[13] ^ lfsr[12] ^ lfsr[10];
        end
    end
    
    assign out = lfsr[0];
    
endmodule
module jelly_stream_joint
        #(
            parameter   NUM         = 16,
            parameter   ID_WIDTH    = 4,
            parameter   DATA_WIDTH  = 32,
            parameter   LEN_WIDTH   = 8,
            parameter   S_REGS      = 1,
            parameter   M_REGS      = 1,
            parameter   ALGORITHM   = "RINGBUS",
            parameter   USE_TOKEN   = 1,
            parameter   USE_M_READY = 1,
            parameter   NO_CONFLICT = 0
        )
        (
            input   wire                            reset,
            input   wire                            clk,
            input   wire                            cke,
            
            input   wire    [NUM-1:0]               s_last,
            input   wire    [NUM*DATA_WIDTH-1:0]    s_data,
            input   wire    [NUM-1:0]               s_valid,
            output  wire    [NUM-1:0]               s_ready,
            
            output  wire    [ID_WIDTH-1:0]          m_id,
            output  wire                            m_last,
            output  wire    [DATA_WIDTH-1:0]        m_data,
            output  wire                            m_valid,
            input   wire                            m_ready
        );
    
    generate
//  if ( ALGORITHM == "TOKEN_RING" ) begin : blk_token_ring
    if ( 1 ) begin : blk_ringbus
        jelly_stream_arbiter_ring_bus
                #(
                    .S_NUM          (NUM),
                    .S_ID_WIDTH     (ID_WIDTH),
                    .M_NUM          (1),
                    .M_ID_WIDTH     (0),
                    .DATA_WIDTH     (DATA_WIDTH),
                    .USE_TOKEN      (USE_TOKEN),
                    .NO_RING        (!USE_M_READY)
                )
            i_stream_arbiter_ring_bus
                (
                    .reset          (reset),
                    .clk            (clk),
                    .cke            (cke),
                    
                    .s_id_to        (1'b0),
                    .s_last         (s_last),
                    .s_data         (s_data),
                    .s_valid        (s_valid),
                    .s_ready        (s_ready),
                    
                    .m_id_from      (m_id),
                    .m_last         (m_last),
                    .m_data         (m_data),
                    .m_valid        (m_valid),
                    .m_ready        (m_ready)
                );
    end
    else begin : blk_priority
    end
    endgenerate
    
endmodule
module jelly_stream_id_filter
        #(
            parameter   NUM            = 16,
            parameter   ID_WIDTH       = 4,
            parameter   DATA_WIDTH     = 32,
            parameter   BYPASS         = 0,
            parameter   FIFO_PTR_WIDTH = 6,
            parameter   FIFO_RAM_TYPE  = "distributed"
        )
        (
            input   wire                            reset,
            input   wire                            clk,
            input   wire                            cke,
            
            input   wire    [ID_WIDTH-1:0]          s_filter_id,
            input   wire                            s_filter_valid,
            output  wire                            s_filter_ready,
            
            input   wire    [NUM-1:0]               s_last,
            input   wire    [NUM*DATA_WIDTH-1:0]    s_data,
            input   wire    [NUM-1:0]               s_valid,
            output  wire    [NUM-1:0]               s_ready,
            
            output  wire    [NUM-1:0]               m_last,
            output  wire    [NUM*DATA_WIDTH-1:0]    m_data,
            output  wire    [NUM-1:0]               m_valid,
            input   wire    [NUM-1:0]               m_ready
        );
    
    genvar  i;
    
    generate
    if ( BYPASS ) begin : blk_bypass
        assign m_last  = s_last;
        assign m_data  = s_data;
        assign m_valid = s_valid;
        assign s_ready = m_ready;
    end
    else begin : blk_filter
        // FIFO
        wire    [ID_WIDTH-1:0]          filter_id;
        wire                            filter_valid;
        wire                            filter_ready;
        jelly_fifo_fwtf
                #(
                    .DATA_WIDTH     (ID_WIDTH),
                    .PTR_WIDTH      (FIFO_PTR_WIDTH),
                    .DOUT_REGS      (0),
                    .RAM_TYPE       (FIFO_RAM_TYPE),
                    .MASTER_REGS    (1)
                )
            jelly_fifo_fwtf
                (
                    .reset          (reset),
                    .clk            (clk),
                    
                    .s_data         (s_filter_id),
                    .s_valid        (s_filter_valid),
                    .s_ready        (s_filter_ready),
                    .s_free_count   (),
                    
                    .m_data         (filter_id),
                    .m_valid        (filter_valid),
                    .m_ready        (filter_ready & cke),
                    .m_data_count   ()
                );
        
        assign filter_ready = |(m_valid & m_ready & m_last);
        
        for ( i = 0; i < NUM; i = i+1 ) begin : loop_filter
            
            wire    filter_ready = (filter_valid && (i == filter_id));
            
            assign m_last[i]                          = s_last[i];
            assign m_data[i*DATA_WIDTH +: DATA_WIDTH] = s_data[i*DATA_WIDTH +: DATA_WIDTH];
            assign m_valid[i]                         = (s_valid[i] & filter_ready);
            assign s_ready[i]                         = (m_ready[i] & filter_ready);
        end
    end
    endgenerate
    
    
endmodule
module jelly_capacity_size_limitter
        #(
            parameter   CAPACITY_WIDTH      = 32,
            parameter   REQUEST_WIDTH       = CAPACITY_WIDTH,
            parameter   ISSUE_WIDTH         = 8,
            parameter   REQUEST_SIZE_OFFSET = 1'b1,
            parameter   ISSUE_SIZE_OFFSET   = 1'b1
        )
        (
            input   wire                            reset,
            input   wire                            clk,
            input   wire                            cke,
            
            input   wire    [ISSUE_WIDTH-1:0]       max_issue_size,
            output  wire    [CAPACITY_WIDTH-1:0]    queued_request,
            
            input   wire    [REQUEST_WIDTH-1:0]     s_request_size,
            input   wire                            s_request_valid,
            
            output  wire    [ISSUE_WIDTH-1:0]       m_issue_size,
            output  wire                            m_issue_valid,
            input   wire                            m_issue_ready
        );
    
    wire                            ready = (!m_issue_valid || m_issue_ready);
    
    reg     [CAPACITY_WIDTH-1:0]    reg_queued_request, next_queued_request;
    reg     [ISSUE_WIDTH-1:0]       reg_issue_size,     next_issue_size;
    reg                             reg_issue_valid,    next_issue_valid;
    
    always @(posedge clk) begin
        if ( reset ) begin
            reg_queued_request <= {CAPACITY_WIDTH{1'b0}};
            reg_issue_size     <= {ISSUE_WIDTH{1'bx}};
            reg_issue_valid    <= 1'b0;
        end
        else if ( cke ) begin
            reg_queued_request <= next_queued_request;
            reg_issue_size     <= next_issue_size;
            reg_issue_valid    <= next_issue_valid;
        end
    end
    
    always @* begin
        next_queued_request = reg_queued_request;
        next_issue_size     = reg_issue_size;
        next_issue_valid    = reg_issue_valid;
        
        if ( s_request_valid ) begin
            next_queued_request = next_queued_request + s_request_size + REQUEST_SIZE_OFFSET;
        end
        
        if ( ready ) begin
            next_issue_size  = {ISSUE_WIDTH{1'bx}};
            next_issue_valid = 1'b0;
            if ( next_queued_request > 0 ) begin
                if ( next_queued_request >= ({1'b0, max_issue_size} + ISSUE_SIZE_OFFSET) ) begin
                    next_issue_size     = max_issue_size;
                    next_issue_valid    = 1'b1;
                    next_queued_request = next_queued_request - ({1'b0, max_issue_size} + ISSUE_SIZE_OFFSET);
                end
                else begin
                    next_issue_size     = next_queued_request - ISSUE_SIZE_OFFSET;
                    next_issue_valid    = 1'b1;
                    next_queued_request = {CAPACITY_WIDTH{1'b0}};
                end
            end
        end
        
    end
    
    assign queued_request = reg_queued_request;
    
    assign m_issue_size   = reg_issue_size;
    assign m_issue_valid  = reg_issue_valid;
    
endmodule
module jelly_param_update_slave
        #(
            parameter   INDEX_WIDTH = 1
        )
        (
            input   wire                        reset,
            input   wire                        clk,
            input   wire                        cke,
            
            input   wire                        in_trigger,
            input   wire                        in_update,
            
            output  wire                        out_update,
            output  wire    [INDEX_WIDTH-1:0]   out_index
        );
    
    // parameter latch
    (* ASYNC_REG="true" *)  reg         ff0_update, ff1_update;
                            reg         reg_update;
    always @(posedge clk) begin
        if ( reset ) begin
            ff0_update <= 1'b0;
            ff1_update <= 1'b0;
            reg_update <= 1'b0;
        end
        else begin
            ff0_update <= in_update;
            ff1_update <= ff0_update;
            reg_update <= ff1_update;
        end
    end
    
    reg     [INDEX_WIDTH-1:0]   reg_index;
    always @(posedge clk) begin
        if ( reset ) begin
            reg_index  <= {INDEX_WIDTH{1'b0}};
        end
        else if ( cke ) begin
            if ( reg_update & in_trigger ) begin
                reg_index <= reg_index + 1'b1;
            end
        end
    end
    
    assign out_update = reg_update;
    assign out_index  = reg_index;
    
endmodule
module jelly_data_joint_simple
        #(
            parameter   NUM         = 16,
            parameter   ID_WIDTH    = 4,
            parameter   DATA_WIDTH  = 32
        )
        (
            input   wire                            reset,
            input   wire                            clk,
            input   wire                            cke,
            
            input   wire    [NUM*DATA_WIDTH-1:0]    s_data,
            input   wire    [NUM-1:0]               s_valid,
            
            output  wire    [ID_WIDTH-1:0]          m_id,
            output  wire    [DATA_WIDTH-1:0]        m_data,
            output  wire                            m_valid
        );
    
    
    integer                         i;
    
    reg     [NUM*DATA_WIDTH-1:0]    st0_data;
    reg     [ID_WIDTH-1:0]          st0_id;
    reg                             st0_valid;
    
    reg     [ID_WIDTH-1:0]          st1_id;
    reg     [DATA_WIDTH-1:0]        st1_data;
    reg                             st1_valid;
    
    always @(posedge clk) begin
        if ( cke ) begin
            // stage 0
            st0_data <= s_data;
            st0_id <= {ID_WIDTH{1'bx}};
            for ( i = 0; i < NUM; i = i+1 ) begin
                // parallel_case, full_case
                if ( s_valid == ({{(NUM-1){1'b0}}, 1'b1} << i) ) begin
                    st0_id <= i;
                end
            end
            
            
            // stage 1
            st1_data <= st0_data[st0_id*DATA_WIDTH +: DATA_WIDTH];
            st1_id   <= st0_id;
        end
    end
    
    always @(posedge clk) begin
        if ( reset ) begin
            st0_valid <= 1'b0;
            st1_valid <= 1'b0;
        end
        else if ( cke ) begin
            st0_valid <= |s_valid;
            st1_valid <= st0_valid;
        end
    end
    
    assign m_id    = st1_id;
    assign m_data  = st1_data;
    assign m_valid = st1_valid;
    
endmodule
module jelly_deselector
        #(
            parameter   SEL_WIDTH = 2,
            parameter   IN_WIDTH  = 8,
            parameter   OUT_WIDTH = (IN_WIDTH  * SEL_WIDTH)
        )
        (
            input   wire    [SEL_WIDTH-1:0]     sel,
            input   wire    [IN_WIDTH-1:0]      din,
            output  reg     [OUT_WIDTH-1:0]     dout
        );
    
    integer i;
    integer j;
    always @* begin
        dout = {OUT_WIDTH{1'b0}};
        for ( i = 0; i < SEL_WIDTH; i = i + 1 ) begin
            if ( sel[i] ) begin
                for ( j = 0; j < IN_WIDTH; j = j + 1 ) begin
                    dout[IN_WIDTH*i + j] = din[j];
                end
            end
        end
    end
    
endmodule
module jelly_data_delay
        #(
            parameter                               LATENCY    = 1,
            parameter                               DATA_WIDTH = 8,
            parameter           [DATA_WIDTH-1:0]    DATA_INIT  = {DATA_WIDTH{1'bx}}
        )
        (
            input   wire                        reset,
            input   wire                        clk,
            input   wire                        cke,
            
            input   wire    [DATA_WIDTH-1:0]    in_data,
            
            output  wire    [DATA_WIDTH-1:0]    out_data
        );
    
    integer     i;
    
    generate
    if ( LATENCY == 0 ) begin
        assign out_data = in_data;
    end
    else begin
        reg     [LATENCY*DATA_WIDTH-1:0]    reg_data;
        always @(posedge clk) begin
            if ( reset ) begin
                for ( i = 0; i < LATENCY; i = i+1 ) begin
                    reg_data[i*DATA_WIDTH +: DATA_WIDTH] <= DATA_INIT;
                end
            end
            else if ( cke ) begin
                reg_data[0 +: DATA_WIDTH] <= in_data;
                for ( i = 0; i < LATENCY-1; i = i+1 ) begin
                    reg_data[(i+1)*DATA_WIDTH +: DATA_WIDTH] <= reg_data[i*DATA_WIDTH +: DATA_WIDTH];
                end
            end
        end
        assign out_data = reg_data[(LATENCY-1)*DATA_WIDTH +: DATA_WIDTH];
    end
    endgenerate
    
endmodule
module jelly_bit_encoder
        #(
            parameter   DATA_WIDTH = 8,
            parameter   SEL_WIDTH  = DATA_WIDTH <     2 ?  1 :
                                     DATA_WIDTH <     4 ?  2 :
                                     DATA_WIDTH <     8 ?  3 :
                                     DATA_WIDTH <    16 ?  4 :
                                     DATA_WIDTH <    32 ?  5 :
                                     DATA_WIDTH <    64 ?  6 :
                                     DATA_WIDTH <   128 ?  7 :
                                     DATA_WIDTH <   256 ?  8 :
                                     DATA_WIDTH <   512 ?  9 :
                                     DATA_WIDTH <  1024 ? 10 :
                                     DATA_WIDTH <  2048 ? 11 :
                                     DATA_WIDTH <  4096 ? 12 :
                                     DATA_WIDTH <  8192 ? 13 :
                                     DATA_WIDTH < 16384 ? 14 :
                                     DATA_WIDTH < 32768 ? 15 : 16,
            parameter   PRIORITYT  = 0,
            parameter   LSB_FIRST  = 0
        )
        (
            input   wire    [DATA_WIDTH-1:0]    in_data,
            output  wire    [SEL_WIDTH-1:0]     out_sel
        );
    
    genvar  i, j;
    
    generate
    if ( PRIORITYT ) begin : blk_priority
        reg     [SEL_WIDTH-1:0]     sig_sel;
        integer                     k;
        always @* begin
            sig_sel = {SEL_WIDTH{1'bx}};
            if ( LSB_FIRST ) begin
                for ( k = DATA_WIDTH-1; k >= 0; k = k-1 ) begin
                    if ( in_data[k] ) begin
                        sig_sel = k;
                    end
                end
            end
            else begin
                for ( k = 0; k < DATA_WIDTH; k = k+1 ) begin
                    if ( in_data[k] ) begin
                        sig_sel = k;
                    end
                end
            end
        end
        assign out_sel = sig_sel;
    end
    else begin : blk_onehot
        // make mask
        wire    [SEL_WIDTH*DATA_WIDTH-1:0]  bit_mask;
        for ( i = 0; i < SEL_WIDTH; i = i+1 ) begin : loop_mask
            for ( j = 0; j < DATA_WIDTH; j = j+1 ) begin : loop_bit
                assign bit_mask[i*DATA_WIDTH + j] = ((j & (1 << i)) != 0);
            end
        end
        
        // bit encode
        for ( i = 0; i < SEL_WIDTH; i = i+1 ) begin  : loop_sel
            assign out_sel[i] = |(in_data & bit_mask[i*DATA_WIDTH +: DATA_WIDTH]);
        end
    end
    endgenerate
    
    
endmodule
module jelly_clkx2_mux
        #(
            parameter   DATA_WIDTH = 32
        )
        (
            input   wire                        reset,
            input   wire                        cke,
            input   wire                        clkx2,
            input   wire                        phase,
            
            input   wire    [DATA_WIDTH-1:0]    in0_data,
            input   wire                        in0_valid,
            
            input   wire    [DATA_WIDTH-1:0]    in1_data,
            input   wire                        in1_valid,
            
            output  wire    [DATA_WIDTH-1:0]    out_data,
            output  wire                        out_valid
        );
    
    reg     [DATA_WIDTH-1:0]    reg_data;
    reg                         reg_valid;
    
    always @(posedge clkx2) begin
        if ( reset ) begin
            reg_data  <= {DATA_WIDTH{1'bx}};
            reg_valid <= 1'bx;
        end
        else if ( cke ) begin
            reg_data  <= phase ? in0_data  : in1_data;
            reg_valid <= phase ? in0_valid : in1_valid;
        end
    end
    
    
endmodule
module jelly_semaphore
        #(
            parameter   ASYNC         = 0,
            parameter   COUNTER_WIDTH = 9,
            parameter   INIT_COUNTER  = 256
        )
        (
            // カウンタ値返却側
            input   wire                        rel_reset,
            input   wire                        rel_clk,
            input   wire    [COUNTER_WIDTH-1:0] rel_add,
            input   wire                        rel_valid,
            
            // カウンタ値取得側
            input   wire                        req_reset,
            input   wire                        req_clk,
            input   wire    [COUNTER_WIDTH-1:0] req_sub,
            input   wire                        req_valid,
            output  wire                        req_empty,
            output  wire    [COUNTER_WIDTH-1:0] req_counter
        );
    
    wire    [COUNTER_WIDTH-1:0]     add_counter;
    wire                            add_valid;
    
    jelly_counter_async
            #(
                .ASYNC          (ASYNC),
                .COUNTER_WIDTH  (COUNTER_WIDTH)
            )
        i_counter_async
            (
                .s_reset        (rel_reset),
                .s_clk          (rel_clk),
                .s_add          (rel_add),
                .s_valid        (rel_valid),
                
                .m_reset        (req_reset),
                .m_clk          (req_clk),
                .m_counter      (add_counter),
                .m_valid        (add_valid)
            );
    

    reg     [COUNTER_WIDTH-1:0]     reg_counter;
    reg                             reg_empty;
    
    always @(posedge req_clk ) begin
        if ( req_reset ) begin
            reg_counter <= INIT_COUNTER;
            reg_empty   <= (INIT_COUNTER == {COUNTER_WIDTH{1'b0}});
        end
        else begin
            reg_counter <= reg_counter + (add_valid ? add_counter : {COUNTER_WIDTH{1'b0}})
                                       - (req_valid ? req_sub     : {COUNTER_WIDTH{1'b0}});
            
            reg_empty   <= ((reg_counter + (add_valid ? add_counter : {COUNTER_WIDTH{1'b0}}))
                                        == (req_valid ? req_sub     : {COUNTER_WIDTH{1'b0}}));
        end
    end

    /*
    reg     [COUNTER_WIDTH-1:0]     reg_counter, next_counter;
    reg                             reg_empty,   next_empty;
    
    always @* begin
        next_counter = reg_counter;
        next_empty   = reg_empty;
        
        if ( add_valid ) begin
            next_counter = next_counter + rel_add;
        end
        
        if ( req_valid ) begin
            next_counter = next_counter - req_sub;
        end
        
        next_empty = (next_counter == {COUNTER_WIDTH{1'b0}});
    end
    
    always @(posedge req_clk ) begin
        if ( req_reset ) begin
            reg_counter <= INIT_COUNTER;
            reg_empty   <= (INIT_COUNTER == {COUNTER_WIDTH{1'b0}});
        end
        else begin
            reg_counter <= next_counter;
            reg_empty   <= next_empty;
        end
    end
    */
    
    assign req_empty   = reg_empty;
    assign req_counter = reg_counter;
    
endmodule
module jelly_fifo
        #(
            parameter   DATA_WIDTH = 8,
            parameter   PTR_WIDTH  = 10,
            parameter   DOUT_REGS  = 0,
            parameter   RAM_TYPE   = "block",
            parameter   LOW_DEALY  = 0
        )
        (
            input   wire                        reset,
            input   wire                        clk,
            
            input   wire                        wr_en,
            input   wire    [DATA_WIDTH-1:0]    wr_data,
            
            input   wire                        rd_en,
            input   wire                        rd_regcke,
            output  wire    [DATA_WIDTH-1:0]    rd_data,
            
            output  wire                        full,
            output  wire                        empty,
            output  wire    [PTR_WIDTH:0]       free_count,
            output  wire    [PTR_WIDTH:0]       data_count
        );
    
    
    generate
    if ( LOW_DEALY && RAM_TYPE == "distributed" && PTR_WIDTH < 8 ) begin : blk_shifter
        jelly_fifo_shifter
                #(
                    .DATA_WIDTH     (DATA_WIDTH),
                    .PTR_WIDTH      (PTR_WIDTH),
                    .DOUT_REGS      (DOUT_REGS)
                )
            i_fifo_shifter
                (
                    .reset          (reset),
                    .clk            (clk),
                    
                    .wr_en          (wr_en),
                    .wr_data        (wr_data),
                    
                    .rd_en          (rd_en),
                    .rd_regcke      (rd_regcke),
                    .rd_data        (rd_data),
                    
                    .full           (full),
                    .empty          (empty),
                    .free_count     (free_count),
                    .data_count     (data_count)
                );
    end
    else begin : blk_ram
        jelly_fifo_ram
                #(
                    .DATA_WIDTH     (DATA_WIDTH),
                    .PTR_WIDTH      (PTR_WIDTH),
                    .DOUT_REGS      (DOUT_REGS),
                    .RAM_TYPE       (RAM_TYPE),
                    .LOW_DEALY      (LOW_DEALY)
                )
            i_fifo_ram
                (
                    .reset          (reset),
                    .clk            (clk),
                    
                    .wr_en          (wr_en),
                    .wr_data        (wr_data),
                    
                    .rd_en          (rd_en),
                    .rd_regcke      (rd_regcke),
                    .rd_data        (rd_data),
                    
                    .full           (full),
                    .empty          (empty),
                    .free_count     (free_count),
                    .data_count     (data_count)
                );
    end
    endgenerate
    
    
endmodule
module jelly_bit_selector
        #(
            parameter   SEL_WIDTH     = 4,
            parameter   BIT_WIDTH     = (1 << SEL_WIDTH),
            
            parameter   USE_PRIMITIVE = 0,
            parameter   DEVICE        = "RTL"
        )
        (
            input   wire    [SEL_BITS-1:0]      sel,
            input   wire    [BIT_WIDTH-1:0]     din,
            output  wire                        dout
        );
    
    localparam  SEL_BITS  = SEL_WIDTH > 0 ? SEL_WIDTH : 1;
    
    generate
    if ( SEL_WIDTH <= 0 ) begin : blk_bypass
        assign dout = din;
    end
    else if ( USE_PRIMITIVE && (BIT_WIDTH <= 4) ) begin : blk_mul4
        wire    [1:0]   bit4_sel = sel;
        wire    [3:0]   bit4_din = din;
        jelly_multiplexer4
                #(
                    .DEVICE     (DEVICE)
                )
            i_multiplexer4
                (
                    .o          (dout),
                    .i          (bit4_din),
                    .s          (bit4_sel)
                );
    end
    else if ( USE_PRIMITIVE && (BIT_WIDTH <= 4) ) begin : blk_mul16
        wire    [3:0]   bit16_sel = sel;
        wire    [15:0]  bit16_din = din;
        jelly_multiplexer16
                #(
                    .DEVICE     (DEVICE)
                )
            i_multiplexer16
                (
                    .o          (dout),
                    .i          (bit16_din),
                    .s          (bit16_sel)
                );
    end
    else begin : blk_rtl
        assign dout = din[sel];
    end
    endgenerate
    
endmodule
module jelly_bit_shift
        #(
            parameter   SHIFT_WIDTH   = 4,
            parameter   DATA_WIDTH    = (1 << SHIFT_WIDTH),
            
            parameter   LEFT       = 0,
            parameter   ARITHMETIC = 0,
            parameter   ROTATION   = 0,
            
            
            parameter   USE_PRIMITIVE = 0,
            parameter   DEVICE        = "RTL"
        )
        (
            input   wire    [SHIFT_WIDTH-1:0]   shift,
            input   wire    [DATA_WIDTH-1:0]    in_data,
            output  wire    [DATA_WIDTH-1:0]    out_data
        );
    
    genvar      i;
    
    wire    [DATA_WIDTH-1:0]    stuffing;
    
    assign stuffing = ROTATION              ? in_data                             :
                      (!LEFT && ARITHMETIC) ? {DATA_WIDTH{in_data[DATA_WIDTH-1]}} :
                                              {DATA_WIDTH{1'b0}};
    
    generate
    if ( !USE_PRIMITIVE || DEVICE == "RTL" ) begin : blk_rtl
        assign out_data = LEFT ? (({in_data, stuffing} << shift) >> DATA_WIDTH) :
                                 (({in_data, stuffing} >> shift));
    end
    else begin : blk_mux
        // LEFT時に primitive のマルチプレクサに適合するように結線をリバースする
        
        // input reverse
        wire    [DATA_WIDTH-1:0]    rev_stuffing;
        wire    [DATA_WIDTH-1:0]    rev_in_data;
        for ( i = 0; i < DATA_WIDTH; i = i+1 ) begin : loop_in_rev
            assign rev_stuffing[i] = LEFT ? stuffing[DATA_WIDTH-1-i] : stuffing[i];
            assign rev_in_data [i] = LEFT ? in_data [DATA_WIDTH-1-i] : in_data [i];
        end
        
        // selector
        wire    [DATA_WIDTH-1:0]    sel_data;
        for ( i = 0; i < DATA_WIDTH; i = i+1 ) begin : loop_mux
            wire    [DATA_WIDTH-1:0]    sel_bits = ({rev_stuffing, rev_in_data} >> i);
            jelly_bit_selector
                    #(
                        .SEL_WIDTH      (SHIFT_WIDTH),
                        .BIT_WIDTH      (DATA_WIDTH),
                        .USE_PRIMITIVE  (USE_PRIMITIVE),
                        .DEVICE         (DEVICE)
                    )
                i_bit_selector
                    (
                        .sel            (shift),
                        .din            (sel_bits),
                        .dout           (sel_data[i])
                    );
        end
        
        // output reverse
        for ( i = 0; i < DATA_WIDTH; i = i+1 ) begin : loop_out_rev
            assign out_data[i] = LEFT ? sel_data[DATA_WIDTH-1-i] : sel_data[i];
        end
    end
    endgenerate
    
endmodule
module jelly_func_graycode_to_binary
        #(
            parameter                       WIDTH = 4
        )
        (
            input   wire    [WIDTH-1:0]     graycode,
            output  reg     [WIDTH-1:0]     binary
        );
    
    integer i;
    always @* begin
        binary[WIDTH-1] = graycode[WIDTH-1];
        for ( i = WIDTH - 2; i >= 0; i = i - 1 ) begin
            binary[i] = binary[i+1] ^ graycode[i];
        end
    end
    
endmodule
module jelly_shadow_reg_ctl
        #(
            parameter   INDEX_WIDTH = 1,
            parameter   INIT_INDEX  = {INDEX_WIDTH{1'b0}}
        )
        (
            input   wire                            reset,
            input   wire                            clk,
            input   wire                            update_req,
            output  wire                            update_ack,
            output  wire    [INDEX_WIDTH-1:0]       index,
            
            input   wire                            core_reset,
            input   wire                            core_clk,
            input   wire                            core_acceptable,
            output  wire                            core_update
        );
    
    wire    [INDEX_WIDTH-1:0]   sig_index;
    
    (* ASYNC_REG = "true" *)    reg     [INDEX_WIDTH-1:0]   ff0_index;
    (* ASYNC_REG = "true" *)    reg     [INDEX_WIDTH-1:0]   ff1_index;
    (* ASYNC_REG = "true" *)    reg     [INDEX_WIDTH-1:0]   ff2_index;
    
    always @(posedge clk) begin
        if ( reset ) begin
            ff0_index <= INIT_INDEX;
            ff1_index <= INIT_INDEX;
            ff2_index <= INIT_INDEX;
        end
        else begin
            ff0_index <= sig_index;
            ff1_index <= ff0_index;
            ff2_index <= ff1_index;
        end
    end
    
    assign update_ack = (ff2_index[0] != ff1_index[0]);
    assign index      = ff1_index;
    
    
    
    (* ASYNC_REG = "true" *)    reg         ff0_update;
    (* ASYNC_REG = "true" *)    reg         ff1_update;
    always @(posedge core_clk) begin
        if ( core_reset ) begin
            ff0_update <= 1'b0;
            ff1_update <= 1'b0;
        end
        else begin
            ff0_update <= update_req;
            ff1_update <= ff0_update;
        end
    end
    
    reg     [INDEX_WIDTH-1:0]   reg_index;
    always @(posedge core_clk) begin
        if ( core_reset ) begin
            reg_index <= INIT_INDEX;
        end
        else begin
            if ( core_acceptable && ff1_update ) begin
                reg_index <= reg_index + 1'b1;
            end
        end
    end
    
    assign core_update = (core_reset || (core_acceptable && ff1_update));
    assign sig_index   = reg_index;
    
endmodule
module jelly_ram_simple_dualport
        #(
            parameter   ADDR_WIDTH   = 6,
            parameter   DATA_WIDTH   = 8,
            parameter   MEM_SIZE     = (1 << ADDR_WIDTH),
            parameter   RAM_TYPE     = "distributed",
            parameter   DOUT_REGS    = 0,
            
            parameter   FILLMEM      = 0,
            parameter   FILLMEM_DATA = 0,
            parameter   READMEMB     = 0,
            parameter   READMEMH     = 0,
            parameter   READMEM_FIlE = ""
        )
        (
            // write port
            input   wire                        wr_clk,
            input   wire                        wr_en,
            input   wire    [ADDR_WIDTH-1:0]    wr_addr,
            input   wire    [DATA_WIDTH-1:0]    wr_din,
            
            // read port
            input   wire                        rd_clk,
            input   wire                        rd_en,
            input   wire                        rd_regcke,
            input   wire    [ADDR_WIDTH-1:0]    rd_addr,
            output  wire    [DATA_WIDTH-1:0]    rd_dout
        );
    
    // memory
    (* ram_style = RAM_TYPE *)
    reg     [DATA_WIDTH-1:0]    mem [0:MEM_SIZE-1];
    
    integer iMEM_SIZE = MEM_SIZE;
    
    // write port
    always @ ( posedge wr_clk ) begin
        if ( wr_en ) begin
            mem[wr_addr] <= wr_din;
        end
    end
    
    
    
    // read port
    reg     [DATA_WIDTH-1:0]    tmp_dout;
    always @(posedge rd_clk ) begin
        if ( rd_en ) begin
            tmp_dout <= mem[rd_addr];
        end
    end
    
    
    // DOUT FF insert
    generate
    if ( DOUT_REGS ) begin : blk_reg
        reg     [DATA_WIDTH-1:0]    reg_dout;
        always @(posedge rd_clk) begin
            if ( rd_regcke ) begin
                reg_dout <= tmp_dout;
            end
        end
        assign rd_dout = reg_dout;
    end
    else begin : blk_no_reg
        assign rd_dout = tmp_dout;
    end
    endgenerate
    
    
    
    // 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_clkx2_phase
        #(
            parameter   DATA_WIDTH = 32
        )
        (
            input   wire                        reset,
            input   wire                        clk,
            input   wire                        clkx2,
            
            output  wire                        phase
        );
    
    
    reg     reg_clk_ff      = 1'b0;
    reg     reg_clkx2_ff    = 1'b1;
    reg     reg_clkx2_phase = 1'b0;
    
    always @(posedge clk) begin
        if ( reset ) begin
            reg_clk_ff <= 1'b0;
        end
        else begin
            reg_clk_ff <= ~reg_clk_ff;
        end
    end
    
    always @(posedge clkx2) begin
        if ( reset ) begin
            reg_clkx2_ff    <= 1'b0;
            reg_clkx2_phase <= 1'b0;
        end
        else begin
            reg_clkx2_ff    <= reg_clk_ff;
            reg_clkx2_phase <= reg_clkx2_ff ^ reg_clk_ff;
        end
    end
    
    assign phase = reg_clkx2_phase;
    
endmodule
module jelly_stream_delay
        #(
            parameter   LATENCY    = 1,
            parameter   DATA_WIDTH = 8,
            parameter   DATA_INIT  = {DATA_WIDTH{1'bx}}
        )
        (
            input   wire                        reset,
            input   wire                        clk,
            input   wire                        cke,
            
            input   wire    [DATA_WIDTH-1:0]    s_data,
            input   wire                        s_valid,
            output  wire                        s_ready,
            
            output  wire    [DATA_WIDTH-1:0]    m_data,
            output  wire                        m_valid,
            input   wire                        m_ready
        );
    
    integer     i;
    
    generate
    if ( LATENCY == 0 ) begin : blk_bypass
        assign m_data  = s_data;
        assign m_valid = s_valid;
        assign s_ready = m_ready;
    end
    else begin : blk_delay
        reg     [LATENCY*DATA_WIDTH-1:0]    reg_data;
        reg     [LATENCY-1:0]               reg_valid;
        always @(posedge clk) begin
            if ( reset ) begin
                for ( i = 0; i < LATENCY; i = i+1 ) begin
                    reg_data[i*DATA_WIDTH +: DATA_WIDTH] <= DATA_INIT;
                    reg_valid[i] <= 1'b0;
                end
            end
            else if ( cke && s_ready ) begin
                reg_data[0 +: DATA_WIDTH] <= s_data;
                reg_valid[0]              <= s_valid;
                for ( i = 0; i < LATENCY-1; i = i+1 ) begin
                    reg_data[(i+1)*DATA_WIDTH +: DATA_WIDTH] <= reg_data[i*DATA_WIDTH +: DATA_WIDTH];
                    reg_valid[i+1] <= reg_valid[i];
                end
            end
        end
        assign m_data  = reg_data[(LATENCY-1)*DATA_WIDTH +: DATA_WIDTH];
        assign m_valid = reg_valid[LATENCY-1];
    end
    endgenerate
    
    assign s_ready = (!m_valid || m_ready);
    
endmodule
module jelly_signal_transfer
        #(
            parameter ASYNC          = 1,
            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
        );
    
    
    generate
    if ( ASYNC ) begin : blk_async
        jelly_signal_transfer_async
                #(
                    .PTR_WIDTH      (PTR_WIDTH),
                    .CAPACITY_WIDTH (CAPACITY_WIDTH)
                )
            i_signal_transfer_async
                (
                    .s_reset        (s_reset),
                    .s_clk          (s_clk),
                    .s_valid        (s_valid),
                    
                    .m_reset        (m_reset),
                    .m_clk          (m_clk),
                    .m_valid        (m_valid),
                    .m_ready        (m_ready)
                );
    end
    else begin : blk_sync
        jelly_signal_transfer_sync
                #(
                    .CAPACITY_WIDTH (CAPACITY_WIDTH)
                )
            i_signal_transfer_sync
                (
                    .reset          (s_reset),
                    .clk            (s_clk),
                    .s_valid        (s_valid),
                    
                    .m_valid        (m_valid),
                    .m_ready        (m_ready)
                );
    end
    endgenerate
endmodule