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

Subversion Repositories srdydrdy_lib

[/] [srdydrdy_lib/] [trunk/] [rtl/] [verilog/] [buffers/] [sd_fifo_s.v] - Rev 11

Go to most recent revision | Compare with Previous | Blame | View Log

//----------------------------------------------------------------------
// Srdy/Drdy FIFO "S"
//
// Building block for FIFOs.  The "S" (small or synchronizer) FIFO is 
// designed for smaller FIFOs based around memories or flops, with 
// sizes that are a power of 2.
//
// The "S" FIFO can be used as a two-clock asynchronous FIFO.  When the
// async parameter is set to 1, the pointers will be converted from
// binary to grey code and double-synchronized.
//
// Naming convention: c = consumer, p = producer, i = internal interface
//----------------------------------------------------------------------
// Author: Guy Hutchison
//
// This block is uncopyrighted and released into the public domain.
//----------------------------------------------------------------------
 
// delay unit for nonblocking assigns, default is to #1
`ifndef SDLIB_DELAY 
 `define SDLIB_DELAY #1 
`endif
 
module sd_fifo_s
  #(parameter width=8,
    parameter depth=16,
    parameter async=0
    )
    (
     input       c_clk,
     input       c_reset,
     input       c_srdy,
     output      c_drdy,
     input [width-1:0] c_data,
 
     input       p_clk,
     input       p_reset,
     output      p_srdy,
     input       p_drdy,
     output reg [width-1:0] p_data
     );
 
  localparam asz = $clog2(depth);
 
  reg [width-1:0] 	mem [0:depth-1];
  wire [width-1:0] 	mem_rddata;
  wire 			rd_en;
  wire [asz:0] 		rdptr_tail, rdptr_tail_sync;
  wire			wr_en;
  wire [asz:0] 		wrptr_head, wrptr_head_sync;
  reg 			dly_rd_en;
  wire [asz-1:0] 	rd_addr, wr_addr;
 
  always @(posedge c_clk)
    if (wr_en)
      mem[wr_addr] <= `SDLIB_DELAY c_data;
 
  assign mem_rddata = mem[rd_addr];
 
  sd_fifo_head_s #(depth, async) head
    (
     // Outputs
     .c_drdy				(c_drdy),
     .wrptr_head			(wrptr_head),
     .wr_en				(wr_en),
     .wr_addr                           (wr_addr),
     // Inputs
     .clk				(c_clk),
     .reset				(c_reset),
     .c_srdy				(c_srdy),
     .rdptr_tail			(rdptr_tail_sync));
 
  sd_fifo_tail_s #(depth, async) tail
    (
     // Outputs
     .rdptr_tail			(rdptr_tail),
     .rd_en				(rd_en),
     .rd_addr                           (rd_addr),
     .p_srdy				(p_srdy),
     // Inputs
     .clk				(p_clk),
     .reset				(p_reset),
     .wrptr_head			(wrptr_head_sync),
     .p_drdy				(p_drdy));
 
  always @(posedge p_clk)
    begin
      if (rd_en)
	p_data <= `SDLIB_DELAY mem_rddata;
    end
 
  generate
    if (async)
      begin : gen_sync
	reg [asz:0] r_sync1, r_sync2;
	reg [asz:0] w_sync1, w_sync2;
 
	always @(posedge p_clk)
	  begin
	    w_sync1 <= `SDLIB_DELAY wrptr_head;
	    w_sync2 <= `SDLIB_DELAY w_sync1;
	  end
 
	always @(posedge c_clk)
	  begin
	    r_sync1 <= `SDLIB_DELAY rdptr_tail;
	    r_sync2 <= `SDLIB_DELAY r_sync1;
	  end
 
	assign wrptr_head_sync = w_sync2;
	assign rdptr_tail_sync = r_sync2;
      end
    else
      begin : gen_nosync
	assign wrptr_head_sync = wrptr_head;
	assign rdptr_tail_sync = rdptr_tail;
      end
  endgenerate	
 
endmodule // sd_fifo_s
 

Go to most recent revision | 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.