FWFT-FIFO的同步和异步verilog代码

//-----------------------------------------------------------------------------
// File Name   : fifo_sync.v
//-----------------------------------------------------------------------------
//参数化同步FIFO。DEPTH可以是任何大于0的整数值。实际使用的内存深度是depth,如果depth不是2的幂,
//则四舍五入到下一个2的幂。然而,满/空标志将表现得好像实际深度是depth。
//例如,DEPTH = 1000将使用ram大小WIDTH x 1024,但当level = 1000并且不执行后续写入时,
//将断言full flag。
//
// XST will synthesize to a block RAM if the size is large enough.
//
// parameter ranges:
//
// DEPTH    powers of 2, > 1
// WIDTH    > 0
//
// Actual write depth   = DEPTH
// Read latency         = 1
//
//=============================================================================

module fifo_sync_fwft
#(
   parameter RAM_STYLE = "block", //block, distributed, or ultra
   parameter WIDTH = 8,
   parameter DEPTH = 1024
)
(
   // use 'old style' ports since 'level' needs a calculated width
   input sreset,
   input clk,

   input wr_en,
   input [WIDTH-1:0] wr_data,
   output reg full = 1'b0,
   output reg alm_full = 1'b0,
   output reg overflow = 1'b0,

   input rd_en,
   output [WIDTH-1:0] rd_data,
   output reg empty = 1'b1,
   output reg underflow = 1'b0,
   output reg [$clog2(DEPTH+1)-1:0] level = 0

);

   // `include "sv_clog2.vh"

   localparam LVL_WID = $clog2(DEPTH+1);
   localparam AWID = $clog2(DEPTH);

   // variable length constants
   localparam [LVL_WID-1:0] LEVEL_ZERO = {LVL_WID {1'b0}};
   localparam [LVL_WID-1:0] LEVEL_ONE  = {{LVL_WID-1 {1'b0}}, 1'b1};
   localparam [AWID-1:0] PTR_ZERO      = {AWID {1'b0}};
   localparam [AWID-1:0] PTR_ONE       = {{AWID-1 {1'b0}}, 1'b1};

   // pointers
   reg [AWID-1:0]  wr_ptr = PTR_ZERO;
   reg [AWID-1:0]  rd_ptr = PTR_ZERO;
   reg [AWID-1:0]  rd_ptr_plus1 = PTR_ONE;

   // RAM
   reg wren_q1;
   reg [AWID-1:0] wr_ptr_q1;
   reg [WIDTH-1:0] wr_data_q1;
   reg take_new;
   reg [WIDTH-1:0] rd_data_mem = {WIDTH {1'b0}};
   reg [WIDTH-1:0] rd_data_new;

   // round up to the next power of 2 for depths which are not a power of 2
   (* ram_style = RAM_STYLE *)
   reg [WIDTH-1:0] mem [(1 << AWID)-1:0];

   // write pointer
   always @(posedge clk)
      if(sreset == 1'b1)
         wr_ptr <= PTR_ZERO;
      else if(wr_en == 1'b1 && full == 1'b0)
         wr_ptr <= wr_ptr + 1;

   // read pointer
   always @(posedge clk)
      if(sreset == 1'b1) begin
         rd_ptr         <= PTR_ZERO;
         rd_ptr_plus1   <= PTR_ONE;
      end
      else if(rd_en == 1'b1 && empty == 1'b0) begin
         rd_ptr         <= rd_ptr_plus1;
         rd_ptr_plus1   <= rd_ptr_plus1 + PTR_ONE;
      end

   // full
   always @(posedge clk) begin
      if(sreset == 1'b1)
         full <= 1'b0;

      // assert when level is 1 less than
      // the depth and a write occurs and
      // no read occurs
      else if(wr_en == 1'b1 && rd_en == 1'b0 && level == (DEPTH-1))
         full <= 1'b1;

      // de-assert when a read occurs since a write
      // is not honored when full == 1
      else if(rd_en == 1'b1)
         full <= 1'b0;
   end

   // alm_full, asserted when level greater than 3/4 Depth
   always @(posedge clk) begin
      if(sreset == 1'b1)
         alm_full <= 1'b0;
      else if(level >= (3*DEPTH>>2))
         alm_full <= 1'b1;
      else
         alm_full <= 1'b0;
   end

   // empty
   always @(posedge clk)
      if(sreset == 1'b1)
         empty <= 1'b1;

      // assert when the level is 1 and a read occurs, but no write occurs
      else if(rd_en == 1'b1 && wr_en == 1'b0 && level == LEVEL_ONE)
         empty <= 1'b1;

      // deassert when a write occurs since a read is not honored when empty = 1
      else if(wr_en == 1'b1)
         empty <= 1'b0;

   // level
   always @(posedge clk)
      if(sreset == 1'b1)
         level <= LEVEL_ZERO;
      else begin
         case({(wr_en & ~full),(rd_en & ~empty)})
            2'b00: level <= level;
            2'b01: level <= level - LEVEL_ONE;
            2'b10: level <= level + LEVEL_ONE;
            2'b11: level <= level;
         endcase
      end

   // overflow
   // the write fails when the FIFO is in reset
   always @(posedge clk)
      if(sreset == 1'b1)
         overflow <= wr_en;
      else
         overflow <= wr_en & full;

   // underflow
   // the read fails when the FIFO is in reset
   always @(posedge clk)
      if(sreset == 1'b1)
         underflow <= rd_en;
      else
         underflow <= rd_en & empty;

   //---------------------------------- RAM -----------------------------------

   // for XST to synthesize to a BRAM, the write address must be latched
   always @(posedge clk)
   begin
      wren_q1     <= wr_en & ~full;
      wr_data_q1  <= wr_data;
      wr_ptr_q1   <= wr_ptr;
   end

   always @(posedge clk)
      if(wren_q1 == 1'b1)
         mem[wr_ptr_q1] <= wr_data_q1;

   // Since the write is delayed by 1 clock,reading a memory cell that 
   // was written on the previous cycle will not return the new data.
   // To prevent this, return the data that was just written instead of 
   // the memory cell contents.

   // check for read after write on same memory address
   always@(posedge clk) begin
   // if the address of the desired memory cell (rd_ptr_plus1) is a pending write, forward the data that is still in the pipe to the output
      if(rd_en == 1'b1 && empty == 1'b0) begin
         if(rd_ptr_plus1 == wr_ptr || rd_ptr_plus1 == wr_ptr_q1) begin
            take_new <= 1'b1;
         end
         else
            take_new <= 1'b0;

         if(rd_ptr_plus1 == wr_ptr)
            rd_data_new <= wr_data;
         else if(rd_ptr_plus1 == wr_ptr_q1)
            rd_data_new <= wr_data_q1;
      end
      // if the address of the desired memory cell (rd_ptr) is a pending write, forward the data that is still in the pipe to the output
      else begin
         // rd_ptr == wr_ptr
         if(empty == 1'b1 || (rd_ptr == wr_ptr_q1 && wren_q1 == 1'b1))
            take_new <= 1'b1;
         else
            take_new <= 1'b0;

         if(rd_ptr == wr_ptr)
            rd_data_new <= wr_data;
         else if(rd_ptr == wr_ptr_q1)
            rd_data_new <= wr_data_q1;
      end
   end
   always @(posedge clk)
      if(rd_en == 1'b1 && empty == 1'b0)
         rd_data_mem <= mem[rd_ptr_plus1];
      else
         rd_data_mem <= mem[rd_ptr];

   assign rd_data = take_new ? rd_data_new : rd_data_mem;

endmodule

上面是同步FWFT-FIFO的verilog手写代码,这种FIFO的一般用于低延时场景,优点是读使能与读数据是同步输出的,没有时延。

module fifo_async_fwft
#(
   parameter WIDTH = 8,
   parameter DEPTH = 1024
)
(
   // use 'old style' ports since
   // wr_level and rd_level need a calculated width
   reset,

   wr_clk,
   wr_en,
   wr_data,
   wr_full,
   wr_overflow,
   wr_level,

   rd_clk,
   rd_en,
   rd_data,
   rd_empty,
   rd_underflow,
   rd_level
);

   // `include "sv_clog2.vh"

   localparam AWID = $clog2(DEPTH);

   // variable length constants
   localparam [AWID-1:0] ZERO = {AWID {1'b0}};
   localparam [AWID-1:0] ONE  = {{AWID-1 {1'b0}}, 1'b1};

   function [AWID-1:0] bin2gray;
      input [AWID-1:0] bin;
   begin

      bin2gray = (bin >> 1) ^ bin;

   end
   endfunction

   function [AWID-1:0] gray2bin;
      input [AWID-1:0] gray;
      integer i;
   begin

      gray2bin = gray;

      for(i = 1; i < AWID; i = 2 * i)
         gray2bin = gray2bin ^ (gray2bin >> i);

   end
   endfunction

   // PORTS
   // asynchronous reset
   input reset;

   // wr_clk domain ports
   input wr_clk;
   input wr_en;
   input [WIDTH-1:0] wr_data;
   output reg wr_full = 1'b0;
   output reg wr_overflow = 1'b0;
   output reg [AWID-1:0] wr_level = ZERO;

   // rd_clk domain ports
   input rd_clk;
   input rd_en;
   output reg [WIDTH-1:0] rd_data;
   output reg rd_empty = 1'b1;
   output reg rd_underflow = 1'b0;
   output reg [AWID-1:0] rd_level = ZERO;

   genvar k;

   reg rd_reset_ms;
   reg rd_reset;

   reg wr_reset_ms;
   reg wr_reset;

   // pointers
   reg [AWID-1:0] wr_ptr_bin      = ZERO;
   reg [AWID-1:0] wr_ptr_bin_q1   = ZERO;
   reg [AWID-1:0] wr_ptr_gray     = ZERO;
   reg [AWID-1:0] wr_ptr_gray_ms  = ZERO;
   reg [AWID-1:0] wr_ptr_gray_rd  = ZERO;
   reg [AWID-1:0] wr_ptr_bin_rd   = ZERO;

   reg [AWID-1:0] rd_ptr_bin      = ZERO;
   reg [AWID-1:0] rd_ptr_gray     = ZERO;
   reg [AWID-1:0] rd_ptr_gray_ms  = ZERO;
   reg [AWID-1:0] rd_ptr_gray_wr  = ZERO;
   reg [AWID-1:0] rd_ptr_bin_wr   = ZERO;

   // RAM
   reg wren_q1;
   reg [AWID-1:0] wr_ptr_gray_q1 = ZERO;
   reg [AWID-1:0] wr_ptr_gray_q2 = ZERO;
   reg [WIDTH-1:0] wr_data_q1;

   // round up to the next power of 2 for depths which are not a power of 2
   reg [WIDTH-1:0] mem [(1 << AWID)-1:0];

   // Initialize memory array for simulation
   integer i;
   initial begin
      for (i=0; i<(1 << AWID); i=i+1)
         mem[i] = {WIDTH{1'b1}};
   end

   //--------------------------- synchronize resets ---------------------------

   // sync reset to wr_clk domain
   (* HBLKNM="wr_reset_sync_ffs" *)
   always @(posedge wr_clk or posedge reset)
      if(reset == 1'b1) begin
         wr_reset_ms <= 1'b1;
         wr_reset    <= 1'b1;
      end
      else begin
         wr_reset_ms <= 1'b0;
         wr_reset    <= wr_reset_ms;
      end

   // sync reset to rd_clk domain
   (* HBLKNM="rd_reset_sync_ffs" *)
   always @(posedge rd_clk or posedge reset)
      if(reset == 1'b1) begin
         rd_reset_ms <= 1'b1;
         rd_reset    <= 1'b1;
      end
      else begin
         rd_reset_ms <= 1'b0;
         rd_reset    <= rd_reset_ms;
      end

   //----------------------------- write signals ------------------------------

   // write pointers - binary & gray
   always @(posedge wr_clk)
      if(wr_reset == 1'b1) begin
         wr_ptr_bin  <= ZERO;
         wr_ptr_gray <= ZERO;
      end
      else if(wr_en == 1'b1 && wr_full == 1'b0) begin
         wr_ptr_bin  <= wr_ptr_bin + ONE;
         wr_ptr_gray <= bin2gray(wr_ptr_bin + ONE);
      end

   // synchronize rd_ptr_gray to wr_clk domain
   generate
      for(k = 0; k < AWID; k = k + 1) begin: rd_ptr_sync

         // place each sync FF pair in the same component
         // for max settling time

         (* HBLKNM="rd_ptr_sync_ffs" *)
         always @(posedge wr_clk) begin
            rd_ptr_gray_ms[k] <= rd_ptr_gray[k];
            rd_ptr_gray_wr[k] <= rd_ptr_gray_ms[k];
         end
      end
   endgenerate

   always @(posedge wr_clk)
      rd_ptr_bin_wr <= gray2bin(rd_ptr_gray_wr);

   // wr_level
   always @(posedge wr_clk)
      if(wr_reset == 1'b1)
         wr_level <= ZERO;
      else
         wr_level <= wr_ptr_bin - rd_ptr_bin_wr + (wr_en & ~wr_full);

   // wr_full
   always @(posedge wr_clk)
      if(wr_reset == 1'b1)
         wr_full <= 1'b1;
      else
         wr_full <= &(wr_ptr_bin - rd_ptr_bin_wr + (wr_en & ~wr_full));

   // wr_overflow
   // the write fails when the FIFO is in reset
   always @(posedge wr_clk)
      if(wr_reset == 1'b1)
         wr_overflow <= wr_en;
      else
         wr_overflow <= wr_en & wr_full;

   //------------------------------ read signals ------------------------------

   // read pointer - binary & gray
   always @(posedge rd_clk)
      if(rd_reset == 1'b1) begin
         rd_ptr_bin  <= ZERO;
         rd_ptr_gray <= ZERO;
      end

      else if(rd_en == 1'b1 && rd_empty == 1'b0) begin
         rd_ptr_bin  <= rd_ptr_bin + ONE;
         rd_ptr_gray <= bin2gray(rd_ptr_bin + ONE);
      end

   // synchronize wr_ptr_gray_q2 to rd_clk domain
   generate
      for(k = 0; k < AWID; k = k + 1) begin: wr_ptr_sync

         // place each sync FF pair in the same component for max settling time

         (* HBLKNM="wr_ptr_sync_ffs" *)
         always @(posedge rd_clk) begin
            wr_ptr_gray_ms[k] <= wr_ptr_gray_q2[k];
            wr_ptr_gray_rd[k] <= wr_ptr_gray_ms[k];
         end
      end
   endgenerate

   always @(posedge rd_clk)
      wr_ptr_bin_rd <= gray2bin(wr_ptr_gray_rd);

   // rd_level
   always @(posedge rd_clk)
      if(rd_reset == 1'b1)
         rd_level <= ZERO;
      else
         rd_level <= wr_ptr_bin_rd - rd_ptr_bin - (rd_en & ~rd_empty);

   // rd_empty
   always @(posedge rd_clk)
      if(rd_reset == 1'b1)
         rd_empty <= 1'b1;
      else
         rd_empty <= (wr_ptr_bin_rd - rd_ptr_bin - (rd_en & ~rd_empty)) == ZERO;

   // rd_underflow the read fails when the FIFO is in reset
   always @(posedge rd_clk)
      if(rd_reset == 1'b1)
         rd_underflow <= rd_en;
      else
         rd_underflow <= rd_en & rd_empty;

   //---------------------------------- RAM -----------------------------------

   // for XST to synthesize to a BRAM, the write address must be latched
   always @(posedge wr_clk) begin
      wren_q1        <= wr_en & ~wr_full;
      wr_data_q1     <= wr_data;
      wr_ptr_bin_q1  <= wr_ptr_bin;
      wr_ptr_gray_q1 <= wr_ptr_gray;
      wr_ptr_gray_q2 <= wr_ptr_gray_q1;
   end

   always @(posedge wr_clk)
      if(wren_q1 == 1'b1)
         mem[wr_ptr_bin_q1] <= wr_data_q1;

   always @(posedge rd_clk)
      if(rd_en == 1'b1 && rd_empty == 1'b0)
         rd_data <= mem[rd_ptr_bin + ONE];
      else
         rd_data <= mem[rd_ptr_bin];

endmodule

上面是异步FWFT-FIFO的verilog代码,这种FIFO的一般用于低延时场景,优点是读使能与读数据是同步输出的,没有时延。

以上的两份代码均非原创,原创大佬另有其人。代码片不保证无BUG,只是在这里分享给各位借鉴与使用。

或者可以使用Xilinx的源码直接调用
异步FIFO-FWFT

module desc_afifo_fwft # (
	parameter WRITE_DATA_WIDTH = 96,
	parameter FIFO_WRITE_DEPTH = 8192,
	parameter READ_DATA_WIDTH  = 96,
	parameter WR_DATA_COUNT_WIDTH = 14,
	parameter RD_DATA_COUNT_WIDTH = 14
	)(
	input									wr_clk,
	input									wr_rst,
	input									rd_clk,
	input									rd_rst,
	input	[WRITE_DATA_WIDTH - 1:0]		din,
	input									wr_en,
	input									rd_en,
	output	[READ_DATA_WIDTH - 1:0]			dout,
	output									full,
	output									empty,
    output                                  prog_alfull,	
	output									data_valid,
	output	[RD_DATA_COUNT_WIDTH - 1:0]		rd_data_count,
	output	[WR_DATA_COUNT_WIDTH - 1:0]		wr_data_count
	
    );


// XPM_FIFO instantiation template for Asynchronous FIFO configurations

//  <-----Cut code below this line---->

   // xpm_fifo_async: Asynchronous FIFO
   // Xilinx Parameterized Macro, version 2019.2

   xpm_fifo_async #(
      .CDC_SYNC_STAGES(2),       // DECIMAL
      .DOUT_RESET_VALUE("0"),    // String
      .ECC_MODE("no_ecc"),       // String
      .FIFO_MEMORY_TYPE("auto"), // String
      .FIFO_READ_LATENCY(1),     // DECIMAL
      .FIFO_WRITE_DEPTH(FIFO_WRITE_DEPTH),   // DECIMAL
      .FULL_RESET_VALUE(0),      // DECIMAL
      .PROG_EMPTY_THRESH(10),    // DECIMAL
      .PROG_FULL_THRESH(10),     // DECIMAL
      .RD_DATA_COUNT_WIDTH(RD_DATA_COUNT_WIDTH),   // DECIMAL
      .READ_DATA_WIDTH(READ_DATA_WIDTH),      // DECIMAL
      .READ_MODE("fwft"),         // String
      .RELATED_CLOCKS(0),        // DECIMAL
      .SIM_ASSERT_CHK(0),        // DECIMAL; 0=disable simulation messages, 1=enable simulation messages
      .USE_ADV_FEATURES("1404"), // String
      .WAKEUP_TIME(0),           // DECIMAL
      .WRITE_DATA_WIDTH(WRITE_DATA_WIDTH),     // DECIMAL
      .WR_DATA_COUNT_WIDTH(WR_DATA_COUNT_WIDTH)    // DECIMAL
   )
   xpm_fifo_async_inst (
      .almost_empty(),   // 1-bit output: Almost Empty : When asserted, this signal indicates that
                                     // only one more read can be performed before the FIFO goes to empty.

      .almost_full(),     // 1-bit output: Almost Full: When asserted, this signal indicates that
                                     // only one more write can be performed before the FIFO is full.

      .data_valid(data_valid),       // 1-bit output: Read Data Valid: When asserted, this signal indicates
                                     // that valid data is available on the output bus (dout).

      .dbiterr(),             // 1-bit output: Double Bit Error: Indicates that the ECC decoder detected
                                     // a double-bit error and data in the FIFO core is corrupted.

      .dout(dout),                   // READ_DATA_WIDTH-bit output: Read Data: The output data bus is driven
                                     // when reading the FIFO.

      .empty(empty),                 // 1-bit output: Empty Flag: When asserted, this signal indicates that the
                                     // FIFO is empty. Read requests are ignored when the FIFO is empty,
                                     // initiating a read while empty is not destructive to the FIFO.

      .full(full),                   // 1-bit output: Full Flag: When asserted, this signal indicates that the
                                     // FIFO is full. Write requests are ignored when the FIFO is full,
                                     // initiating a write when the FIFO is full is not destructive to the
                                     // contents of the FIFO.

      .overflow(),           // 1-bit output: Overflow: This signal indicates that a write request
                                     // (wren) during the prior clock cycle was rejected, because the FIFO is
                                     // full. Overflowing the FIFO is not destructive to the contents of the
                                     // FIFO.

      .prog_empty(),       // 1-bit output: Programmable Empty: This signal is asserted when the
                                     // number of words in the FIFO is less than or equal to the programmable
                                     // empty threshold value. It is de-asserted when the number of words in
                                     // the FIFO exceeds the programmable empty threshold value.

      .prog_full(prog_alfull),         // 1-bit output: Programmable Full: This signal is asserted when the
                                     // number of words in the FIFO is greater than or equal to the
                                     // programmable full threshold value. It is de-asserted when the number of
                                     // words in the FIFO is less than the programmable full threshold value.

      .rd_data_count(rd_data_count), // RD_DATA_COUNT_WIDTH-bit output: Read Data Count: This bus indicates the
                                     // number of words read from the FIFO.

      .rd_rst_busy(),     // 1-bit output: Read Reset Busy: Active-High indicator that the FIFO read
                                     // domain is currently in a reset state.

      .sbiterr(),             // 1-bit output: Single Bit Error: Indicates that the ECC decoder detected
                                     // and fixed a single-bit error.

      .underflow(),         // 1-bit output: Underflow: Indicates that the read request (rd_en) during
                                     // the previous clock cycle was rejected because the FIFO is empty. Under
                                     // flowing the FIFO is not destructive to the FIFO.

      .wr_ack(),               // 1-bit output: Write Acknowledge: This signal indicates that a write
                                     // request (wr_en) during the prior clock cycle is succeeded.

      .wr_data_count(wr_data_count), // WR_DATA_COUNT_WIDTH-bit output: Write Data Count: This bus indicates
                                     // the number of words written into the FIFO.

      .wr_rst_busy(),     // 1-bit output: Write Reset Busy: Active-High indicator that the FIFO
                                     // write domain is currently in a reset state.

      .din(din),                     // WRITE_DATA_WIDTH-bit input: Write Data: The input data bus used when
                                     // writing the FIFO.

      .injectdbiterr(1'b0), // 1-bit input: Double Bit Error Injection: Injects a double bit error if
                                     // the ECC feature is used on block RAMs or UltraRAM macros.

      .injectsbiterr(1'b0), // 1-bit input: Single Bit Error Injection: Injects a single bit error if
                                     // the ECC feature is used on block RAMs or UltraRAM macros.

      .rd_clk(rd_clk),               // 1-bit input: Read clock: Used for read operation. rd_clk must be a free
                                     // running clock.

      .rd_en(rd_en),                 // 1-bit input: Read Enable: If the FIFO is not empty, asserting this
                                     // signal causes data (on dout) to be read from the FIFO. Must be held
                                     // active-low when rd_rst_busy is active high.

      .rst(wr_rst),                     // 1-bit input: Reset: Must be synchronous to wr_clk. The clock(s) can be
                                     // unstable at the time of applying reset, but reset must be released only
                                     // after the clock(s) is/are stable.

      .sleep(1'b0),                 // 1-bit input: Dynamic power saving: If sleep is High, the memory/fifo
                                     // block is in power saving mode.

      .wr_clk(wr_clk),               // 1-bit input: Write clock: Used for write operation. wr_clk must be a
                                     // free running clock.

      .wr_en(wr_en)                  // 1-bit input: Write Enable: If the FIFO is not full, asserting this
                                     // signal causes data (on din) to be written to the FIFO. Must be held
                                     // active-low when rst or wr_rst_busy is active high.

   );

   // End of xpm_fifo_async_inst instantiation
				
				
endmodule	

同步FIFO-FWFT

module xpm_sfifo_fwft # (
	parameter WRITE_DATA_WIDTH = 80,
	parameter FIFO_WRITE_DEPTH = 8192,
	parameter READ_DATA_WIDTH  = 80,
	parameter WR_DATA_COUNT_WIDTH = 14,
	parameter RD_DATA_COUNT_WIDTH = 14
	)(
	input									clk,
	input									rst,
	input	[WRITE_DATA_WIDTH - 1:0]		din,
	input									wr_en,
	input									rd_en,
	output	[READ_DATA_WIDTH - 1:0]			dout,
	output									full,
	output									empty,
	output									data_valid,
	output	[RD_DATA_COUNT_WIDTH - 1:0]		rd_data_count,
	output	[WR_DATA_COUNT_WIDTH - 1:0]		wr_data_count
	
    );

// xpm_fifo_sync: Synchronous FIFO

   xpm_fifo_sync #(
      .DOUT_RESET_VALUE("0"),    // String
      .ECC_MODE("no_ecc"),       // String
      .FIFO_MEMORY_TYPE("auto"), // String
      .FIFO_READ_LATENCY(0),     // DECIMAL
      .FIFO_WRITE_DEPTH(FIFO_WRITE_DEPTH),   // DECIMAL
      .FULL_RESET_VALUE(0),      // DECIMAL
      .PROG_EMPTY_THRESH(10),    // DECIMAL
      .PROG_FULL_THRESH(10),     // DECIMAL
      .RD_DATA_COUNT_WIDTH(RD_DATA_COUNT_WIDTH),   // DECIMAL
      .READ_DATA_WIDTH(READ_DATA_WIDTH),      // DECIMAL
      .READ_MODE("fwft"),         // String
      .SIM_ASSERT_CHK(0),        // DECIMAL; 0=disable simulation messages, 1=enable simulation messages
      .USE_ADV_FEATURES("1404"), // String
      .WAKEUP_TIME(0),           // DECIMAL
      .WRITE_DATA_WIDTH(WRITE_DATA_WIDTH),     // DECIMAL
      .WR_DATA_COUNT_WIDTH(WR_DATA_COUNT_WIDTH)    // DECIMAL
   )
	U_xpm_fifo_sync (
      .almost_empty(),   // 1-bit output: Almost Empty : When asserted, this signal indicates that
                                     // only one more read can be performed before the FIFO goes to empty.

      .almost_full(),     // 1-bit output: Almost Full: When asserted, this signal indicates that
                                     // only one more write can be performed before the FIFO is full.

      .data_valid(data_valid),       // 1-bit output: Read Data Valid: When asserted, this signal indicates
                                     // that valid data is available on the output bus (dout).

      .dbiterr(),             // 1-bit output: Double Bit Error: Indicates that the ECC decoder detected
                                     // a double-bit error and data in the FIFO core is corrupted.

      .dout(dout),                   // READ_DATA_WIDTH-bit output: Read Data: The output data bus is driven
                                     // when reading the FIFO.

      .empty(empty),                 // 1-bit output: Empty Flag: When asserted, this signal indicates that the
                                     // FIFO is empty. Read requests are ignored when the FIFO is empty,
                                     // initiating a read while empty is not destructive to the FIFO.

      .full(full),                   // 1-bit output: Full Flag: When asserted, this signal indicates that the
                                     // FIFO is full. Write requests are ignored when the FIFO is full,
                                     // initiating a write when the FIFO is full is not destructive to the
                                     // contents of the FIFO.

      .overflow(),           // 1-bit output: Overflow: This signal indicates that a write request
                                     // (wren) during the prior clock cycle was rejected, because the FIFO is
                                     // full. Overflowing the FIFO is not destructive to the contents of the
                                     // FIFO.

      .prog_empty(),       // 1-bit output: Programmable Empty: This signal is asserted when the
                                     // number of words in the FIFO is less than or equal to the programmable
                                     // empty threshold value. It is de-asserted when the number of words in
                                     // the FIFO exceeds the programmable empty threshold value.

      .prog_full(),         // 1-bit output: Programmable Full: This signal is asserted when the
                                     // number of words in the FIFO is greater than or equal to the
                                     // programmable full threshold value. It is de-asserted when the number of
                                     // words in the FIFO is less than the programmable full threshold value.

      .rd_data_count(rd_data_count), // RD_DATA_COUNT_WIDTH-bit output: Read Data Count: This bus indicates the
                                     // number of words read from the FIFO.

      .rd_rst_busy(),     // 1-bit output: Read Reset Busy: Active-High indicator that the FIFO read
                                     // domain is currently in a reset state.

      .sbiterr(),             // 1-bit output: Single Bit Error: Indicates that the ECC decoder detected
                                     // and fixed a single-bit error.

      .underflow(),         // 1-bit output: Underflow: Indicates that the read request (rd_en) during
                                     // the previous clock cycle was rejected because the FIFO is empty. Under
                                     // flowing the FIFO is not destructive to the FIFO.

      .wr_ack(),               // 1-bit output: Write Acknowledge: This signal indicates that a write
                                     // request (wr_en) during the prior clock cycle is succeeded.

      .wr_data_count(wr_data_count), // WR_DATA_COUNT_WIDTH-bit output: Write Data Count: This bus indicates
                                     // the number of words written into the FIFO.

      .wr_rst_busy(),     // 1-bit output: Write Reset Busy: Active-High indicator that the FIFO
                                     // write domain is currently in a reset state.

      .din(din),                     // WRITE_DATA_WIDTH-bit input: Write Data: The input data bus used when
                                     // writing the FIFO.

      .injectdbiterr(1'b0), // 1-bit input: Double Bit Error Injection: Injects a double bit error if
                                     // the ECC feature is used on block RAMs or UltraRAM macros.

      .injectsbiterr(1'b0), // 1-bit input: Single Bit Error Injection: Injects a single bit error if
                                     // the ECC feature is used on block RAMs or UltraRAM macros.

      .rd_en(rd_en),                 // 1-bit input: Read Enable: If the FIFO is not empty, asserting this
                                     // signal causes data (on dout) to be read from the FIFO. Must be held
                                     // active-low when rd_rst_busy is active high.

      .rst(rst),                     // 1-bit input: Reset: Must be synchronous to wr_clk. The clock(s) can be
                                     // unstable at the time of applying reset, but reset must be released only
                                     // after the clock(s) is/are stable.

      .sleep(1'b0),                 // 1-bit input: Dynamic power saving- If sleep is High, the memory/fifo
                                     // block is in power saving mode.

      .wr_clk(clk),               // 1-bit input: Write clock: Used for write operation. wr_clk must be a
                                     // free running clock.

      .wr_en(wr_en)                  // 1-bit input: Write Enable: If the FIFO is not full, asserting this
                                     // signal causes data (on din) to be written to the FIFO Must be held
                                     // active-low when rst or wr_rst_busy or rd_rst_busy is active high

   );

endmodule	

使用源码的话最好给调用的IP外面添加一层wrapper。

  • 11
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值