data/full_repos/permissive/214620165/rtl/core/fifo.sv
 line:16: before: "dtype"
data/verilator_xmls/f5b9c1ec-4c7e-4101-b461-c9bc9f8d0c1b.xml
module fifo #(
        parameter type dtype            = logic[31:0],
        parameter int unsigned DEPTH    = 4
    )(
        input  logic clk_i,
        input  logic rst_ni,
        input  logic flush_i,

        output logic full_o,
        output logic empty_o,
        output logic single_element_o,

        input  dtype data_i,
        input  logic push_i,

        output dtype data_o,
        input  logic pop_i
    );

    logic [$clog2(DEPTH) - 1:0] read_pointer_n, read_pointer_q, write_pointer_n, write_pointer_q;

    int unsigned status_cnt_n, status_cnt_q;

    dtype [DEPTH-1:0] mem_n, mem_q;

    assign full_o            = (status_cnt_q == DEPTH);
    assign empty_o           = (status_cnt_q == 0);
    assign single_element_o  = (status_cnt_q == 1);

    always_comb begin : read_write_comb

        read_pointer_n  = read_pointer_q;
        write_pointer_n = write_pointer_q;
        status_cnt_n    = status_cnt_q;
        data_o          = mem_q[read_pointer_q];
        mem_n           = mem_q;

        if (push_i && ~full_o) begin

            mem_n[write_pointer_q] = data_i;

            write_pointer_n = write_pointer_q + 1;

            status_cnt_n    = status_cnt_q + 1;
        end

        if (pop_i && ~empty_o) begin


            read_pointer_n = read_pointer_q + 1;

            mem_n[read_pointer_q] = '0;
            status_cnt_n   = status_cnt_q - 1;
        end

        if (push_i &&  ~full_o && pop_i && ~empty_o)
            status_cnt_n   = status_cnt_q;
    end


    always_ff @(posedge clk_i or negedge rst_ni) begin
        if(~rst_ni) begin
            read_pointer_q  <= '0;
            write_pointer_q <= '0;
            status_cnt_q    <= '0;
            mem_q           <= '0;
        end else if (flush_i) begin
            read_pointer_q  <= '0;
            write_pointer_q <= '0;
            status_cnt_q    <= '0;
            mem_q           <= '0;
        end else begin
            read_pointer_q  <= read_pointer_n;
            write_pointer_q <= write_pointer_n;
            status_cnt_q    <= status_cnt_n;
            mem_q           <= mem_n;
        end
    end

    `ifndef SYNTHESIS
    `ifndef verilator
    initial begin
        assert (DEPTH == 2**$clog2(DEPTH)) else $fatal("FIFO size needs to be a power of two.");

    assert property(
        @(posedge clk_i) (rst_ni && full_o |-> ~push_i))
        else $error ("Trying to push new data although the FIFO is full.");

    assert property(
        @(posedge clk_i) (rst_ni && empty_o |-> ~pop_i))
        else $error ("Trying to pop data although the FIFO is empty.");
    end
    `endif
    `endif
endmodule
module fifo #(
        parameter type dtype            = logic[31:0],
        parameter int unsigned DEPTH    = 4
    )(
        input  logic clk_i,
        input  logic rst_ni,
        input  logic flush_i,

        output logic full_o,
        output logic empty_o,
        output logic single_element_o,

        input  dtype data_i,
        input  logic push_i,

        output dtype data_o,
        input  logic pop_i
    );


    logic [$clog2(DEPTH) - 1:0] read_pointer_n, read_pointer_q, write_pointer_n, write_pointer_q;

    int unsigned status_cnt_n, status_cnt_q;

    dtype [DEPTH-1:0] mem_n, mem_q;

    assign full_o            = (status_cnt_q == DEPTH);
    assign empty_o           = (status_cnt_q == 0);
    assign single_element_o  = (status_cnt_q == 1);

    always_comb begin : read_write_comb

        read_pointer_n  = read_pointer_q;
        write_pointer_n = write_pointer_q;
        status_cnt_n    = status_cnt_q;
        data_o          = mem_q[read_pointer_q];
        mem_n           = mem_q;

        if (push_i && ~full_o) begin

            mem_n[write_pointer_q] = data_i;

            write_pointer_n = write_pointer_q + 1;

            status_cnt_n    = status_cnt_q + 1;
        end

        if (pop_i && ~empty_o) begin


            read_pointer_n = read_pointer_q + 1;

            mem_n[read_pointer_q] = '0;
            status_cnt_n   = status_cnt_q - 1;
        end

        if (push_i &&  ~full_o && pop_i && ~empty_o)
            status_cnt_n   = status_cnt_q;
    end


    always_ff @(posedge clk_i or negedge rst_ni) begin
        if(~rst_ni) begin
            read_pointer_q  <= '0;
            write_pointer_q <= '0;
            status_cnt_q    <= '0;
            mem_q           <= '0;
        end else if (flush_i) begin
            read_pointer_q  <= '0;
            write_pointer_q <= '0;
            status_cnt_q    <= '0;
            mem_q           <= '0;
        end else begin
            read_pointer_q  <= read_pointer_n;
            write_pointer_q <= write_pointer_n;
            status_cnt_q    <= status_cnt_n;
            mem_q           <= mem_n;
        end
    end

    `ifndef SYNTHESIS
    `ifndef verilator
    initial begin
        assert (DEPTH == 2**$clog2(DEPTH)) else $fatal("FIFO size needs to be a power of two.");

    assert property(
        @(posedge clk_i) (rst_ni && full_o |-> ~push_i))
        else $error ("Trying to push new data although the FIFO is full.");

    assert property(
        @(posedge clk_i) (rst_ni && empty_o |-> ~pop_i))
        else $error ("Trying to pop data although the FIFO is empty.");
    end
    `endif
    `endif
endmodule