receive_fifo.v
module receive_fifo
(
    clock, resetj,
    pi_rf_read, rf_pi_data, rf_pi_size, rf_pi_ready,
    ci_rf_write, ci_rf_data
);

// PARAMETERS

    // MEMORY DIMENSIONS

    parameter SIZE  = 0;
    parameter WIDTH = 32;

// INTERFACE

    input clock;
    input resetj;

    // READ INTERFACE

    input              pi_rf_read;
    output [WIDTH-1:0] rf_pi_data;
    output    [SIZE:0] rf_pi_size;
    output             rf_pi_ready;

    // WRITE INTERFACE

    input             ci_rf_write;
    input [WIDTH-1:0] ci_rf_data;

// INTERNAL SIGNALS

    // READ AND WRITE POINTERS

    reg [SIZE-1:0] write_pointer;
    reg [SIZE-1:0] read_pointer;

    // NUMBER OF DATA WORDS CURRENTLY STORED

    reg [SIZE:0] size;

    // READ READY SIGNAL

    reg ready;

    // CURRENT MEMORY ADDRESS

    wire [SIZE-1:0] address;

    // MEMORY WRITE ENABLE

    wire write_enable;

    // MEMORY DATA OUTPUT

    wire [WIDTH-1:0] dout;

// IMPLEMENTATION

    always@(posedge clock or negedge resetj)
    begin
        // READ NOT READY BY DEFAULT

        ready <= 0;

        // IF RESET ACTIVE, RESET REGISTERS

        if (!resetj)
        begin
            write_pointer <= 0;
            read_pointer <= 0;
            size <= 0;
        end

        // ELSE IF WRITE REQUESTED AND FIFO SPACE IS AVAILABLE

        else if (ci_rf_write && size != SIZE)
        begin
            // INCREMENT THE WRITE POINTER AND THE FIFO SIZE

            write_pointer <= write_pointer + 1;
            size <= size + 1;
        end

        // ELSE IF READ REQUESTED, FIFO HAS DATA AND DATA WASN'T READ LAST CYCLE

        else if (pi_rf_read && size != 0 && !ready)
        begin
            // INCREMENT THE READ POINTER AND DECREMENT THE FIFO SIZE

            read_pointer <= read_pointer + 1;
            size <= size - 1;

            // PULSE READ READY SIGNAL

            ready <= 1;
        end
    end

    // IF WRITING, ASSERT MEMORY WRITE ENABLE AND SET THE CURRENT MEMORY
    // ADDRESS TO THE WRITE POINTER OTHERWISE USE THE READ POINTER

    assign address = ci_rf_write && size != SIZE ? write_pointer : read_pointer;
    assign write_enable = ci_rf_write && size != SIZE;

    // INSTANCE THE SRAM MODEL

    SRAM #("receive_fifo", SIZE, WIDTH) receive_ram (address, clock, resetj, write_enable, ci_rf_data, dout);

    // CONNECT OUTPUTS

    assign rf_pi_data  = dout;
    assign rf_pi_size  = size;
    assign rf_pi_ready = ready;

endmodule
© Copyright 2000-2001 Adrian Lewis