transmit_fifo.v
module transmit_fifo
(
    clock, resetj,
    pi_tf_write, pi_tf_data, tf_pi_size, tf_pi_ready,
    ci_tf_read, tf_ci_data
);

// PARAMETERS

    // MEMORY DIMENSIONS

    parameter SIZE  = 1;
    parameter WIDTH = 32;

// INTERFACE

    input clock;
    input resetj;

    // WRITE INTERFACE

    input              pi_tf_write;
    input  [WIDTH-1:0] pi_tf_data;
    output    [SIZE:0] tf_pi_size;
    output             tf_pi_ready;

    // READ INTERFACE

    input              ci_tf_read;
    output [WIDTH-1:0] tf_ci_data;

// INTERNAL SIGNALS

    // READ AND WRITE POINTERS

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

    // NUMBER OF FREE WORDS CURRENTLY AVAILBLE

    reg [SIZE:0] size;

    // WRITE 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
        // WRITE NOT READY BY DEFAULT

        ready <= 0;

        // IF RESET ACTIVE, RESET REGISTERS

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

        // ELSE IF READ REQUESTED AND FIFO HAS DATA

        else if (ci_tf_read && size != SIZE)
        begin
            // INCREMENT THE READ POINTER AND THE FREE SPACE REGISTER

            read_pointer <= read_pointer + 1;
            size <= size + 1;
        end

        // ELSE IF WRITE REQUESTED, FIFO HAS SPACE AND DATA WASN'T WRITTEN LAST CYCLE

        else if (pi_tf_write && size != 0 && !ready)
        begin
            // INCREMENT THE WRITE POINTER AND DECREMENT THE FREE SPACE REGISTER

            write_pointer <= write_pointer + 1;
            size <= size - 1;

            // PULSE WRITE READY SIGNAL

            ready <= 1;
        end
    end

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

    assign address = ci_tf_read && size != SIZE ? read_pointer : write_pointer;
    assign write_enable = !(ci_tf_read && size != SIZE) && (pi_tf_write && size != 0 && !ready);

    // INSTANCE THE SRAM MODEL

    SRAM #("transmit_fifo", SIZE, WIDTH) transmit_ram (address, clock, resetj, write_enable, pi_tf_data, dout);

    // CONNECT OUTPUTS

    assign tf_ci_data  = dout;
    assign tf_pi_size  = size;
    assign tf_pi_ready = ready;

endmodule
© Copyright 2000-2001 Adrian Lewis