OpenCores
URL https://opencores.org/ocsvn/orsoc_graphics_accelerator/orsoc_graphics_accelerator/trunk

Subversion Repositories orsoc_graphics_accelerator

[/] [orsoc_graphics_accelerator/] [trunk/] [rtl/] [verilog/] [gfx/] [basic_fifo.v] - Rev 6

Compare with Previous | Blame | View Log

/* 
 Basic fifo
 Copyright 2005, Timothy Miller
 
 Updated 2012 by Per Lenander & Anton Fosselius (ORSoC)
      - basic fifo is no longer of a fixed depth  
 
 This file is part of orgfx.
 
 orgfx is free software: you can redistribute it and/or modify
 it under the terms of the GNU Lesser General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version. 
 
 orgfx is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU Lesser General Public License for more details.
 
 You should have received a copy of the GNU Lesser General Public License
 along with orgfx.  If not, see <http://www.gnu.org/licenses/>.
 
*/
 
module basic_fifo(
  clk_i,
  rst_i,
 
  data_i,
  enq_i,
  full_o,
  count_o,
 
  data_o,
  valid_o,
  deq_i
);
 
parameter fifo_width     = 32;
parameter fifo_bit_depth = 6;
 
input clk_i, rst_i;
 
input        [fifo_width-1:0] data_i;
input                         enq_i;
output                        full_o;
output reg [fifo_bit_depth:0] count_o;
 
output reg [fifo_width-1:0] data_o;
output reg                  valid_o;
input                       deq_i;
 
 
 
reg   [fifo_width-1:0] fifo_data [2**(fifo_bit_depth)-1:0];
reg [fifo_bit_depth:0] fifo_head, fifo_tail;
reg [fifo_bit_depth:0] next_tail;
 
 
// accept input
wire next_full = fifo_head[fifo_bit_depth-1:0] == next_tail[fifo_bit_depth-1:0] &&
                 fifo_head[fifo_bit_depth]     != next_tail[fifo_bit_depth];
always @(posedge clk_i or posedge rst_i)
  if (rst_i)
  begin
    fifo_tail <= 1'b0;
    next_tail <= 1'b1;
  end
  else if (!next_full && enq_i)
  begin
     // We can only enqueue when not full
     fifo_data[fifo_tail[fifo_bit_depth-1:0]] <= data_i;
     next_tail <= next_tail + 1'b1;
     fifo_tail <= next_tail;
   end
 
assign full_o = next_full;
 
always @(posedge clk_i or posedge rst_i)
  if(rst_i)
    count_o <= 1'b0;
  else if(enq_i & ~deq_i & ~next_full)
    count_o <= count_o + 1'b1;
  else if(~enq_i & deq_i & valid_o)
    count_o <= count_o - 1'b1;
 
// provide output
wire is_empty = (fifo_head == fifo_tail);
always @(posedge clk_i or posedge rst_i)
  if (rst_i) begin
    valid_o <= 1'b0;
    fifo_head <= 1'b0;
  end 
  else
  begin        
    if (!is_empty)
    begin
      if (!valid_o || deq_i)
        fifo_head <= fifo_head + 1'b1;
 
      valid_o <= 1'b1;
    end
    else if (deq_i)
      valid_o <= 1'b0;
  end
 
always @(posedge clk_i)
    // If no valid out or we're dequeueing, we want to grab
    // the next data.  If we're empty, we don't get valid_o,
    // so we don't care if it's garbage.
  if (!valid_o || deq_i)
    data_o <= fifo_data[fifo_head[fifo_bit_depth-1:0]];
 
endmodule
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.