微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > 求助 异步fifo

求助 异步fifo

时间:10-02 整理:3721RD 点击:
求助采用握手协议的异步fifo  verilog代码

写的精彩, 支持下,!
写的精彩, 支持下,!





_______________________________________________
wow gold
wow gold

conf_AFFxx.v
parameter   
    DEPTH_P_LOG2 = 4,
   DEPTH_P      = 16,
   DATA_W_P     = 8;
localparam
   ADDR_W_P     = DEPTH_P_LOG2;

`include "conf_TimeScale.v"
//
module AFFxx(/*AUTOARG*/
   // Outputs
   wfull, rempty, rdata,
   // Inputs
   wclk, wrst_n, push, wdata, rclk, rrst_n, pop
   );
   //-----------------------------------------------
`include "conf_AFFxx.v"
   //-----------------------------------------------
   //Input
   input                         wclk,wrst_n;
   input     push;
   input [DATA_W_P-1:0]   wdata;
   //Output
   output     wfull;
   //For read
   input     rclk,rrst_n;
   input     pop;
   //Output
   output     rempty;
   output [DATA_W_P-1:0]   rdata;
   //
   //Wire
   wire [ADDR_W_P-1:0]    wptr,rptr;

   wire   aempty_n;  // From uAFFxxCmp of AFFxxCmp.v
   wire   afull_n;  // From uAFFxxCmp of AFFxxCmp.v
   AFFxxMem
uAFFxxMem(/*AUTOINST*/
   // Outputs
   .rdata   (rdata[DATA_W_P-1:0]),
   // Inputs
   .wclk    (wclk),
   .push    (push),
   .wptr    (wptr[ADDR_W_P-1:0]),
   .rptr    (rptr[ADDR_W_P-1:0]),
   .wdata   (wdata[DATA_W_P-1:0]),
   .wfull   (wfull));
   AFFxxEmpty
uAFFxxEmpty(/*AUTOINST*/
     // Outputs
     .rempty   (rempty),
     .rptr   (rptr[ADDR_W_P-1:0]),
     // Inputs
     .rclk   (rclk),
     .rrst_n   (rrst_n),
     .pop   (pop),
     .aempty_n   (aempty_n));
   AFFxxCmp
uAFFxxCmp(/*AUTOINST*/
   // Outputs
   .aempty_n   (aempty_n),
   .afull_n   (afull_n),
   // Inputs
   .wrst_n   (wrst_n),
   .wptr    (wptr[ADDR_W_P-1:0]),
   .rptr    (rptr[ADDR_W_P-1:0]));
   AFFxxFull
uAFFxxFull(/*AUTOINST*/
    // Outputs
    .wfull   (wfull),
    .wptr   (wptr[ADDR_W_P-1:0]),
    // Inputs
    .wclk   (wclk),
    .wrst_n   (wrst_n),
    .push   (push),
    .afull_n   (afull_n));
//   
//--------------------------------------------- end of module --
endmodule


module AFFxxCmp(/*AUTOARG*/
   // Outputs
   aempty_n, afull_n,
   // Inputs
   wrst_n, wptr, rptr
   );
   //-----------------------------------------------
`include "conf_AFFxx.v"
   //-----------------------------------------------
   //
   //Input
   input        wrst_n;
   //
   input [ADDR_W_P-1:0] wptr,rptr;   
   //
   //Output
   output   aempty_n,afull_n;
   //
   //Reg
   wire   high;
   wire   dirc_set_n,dirc_clr_n;
   //
   assign high = 1'b1;
   assign dirc_set_n = ~(    (wptr[ADDR_W_P-1]^rptr[ADDR_W_P-2]) & ~(wptr[ADDR_W_P-2]^rptr[ADDR_W_P-1]) );
   assign dirc_clr_n = ~( ( ~(wptr[ADDR_W_P-1]^rptr[ADDR_W_P-2]) &  (wptr[ADDR_W_P-2]^rptr[ADDR_W_P-1]) )  | ~wrst_n );
   /*AUTOREG*/
   // Beginning of automatic regs (for this module's undeclared outputs)
   // End of automatics
   //--------------------------------------------------------------
   //-------------------       dirc
   reg   dirc;
   always @(posedge high or negedge dirc_set_n or negedge dirc_clr_n )begin
      if(!dirc_clr_n)  begin
  dirc <= 1'b0;
      end
      else if(!dirc_set_n)  begin
  dirc <= 1'b1;
      end
      else begin
  dirc <= high;
      end
   end
//--------------------------------------------------------------------
   wire ptr_equel;
   assign ptr_equel = (wptr == rptr);
   //--------------------------------------------------------------------
   assign aempty_n = ~( ptr_equel && (!dirc) );
   assign afull_n  = ~( ptr_equel &&   dirc  );
//--------------------------------------------- end of module --
endmodule // AFFxxCmp

module AFFxxEmpty(/*AUTOARG*/
   // Outputs
   rempty, rptr,
   // Inputs
   rclk, rrst_n, pop, aempty_n
   );
   //-----------------------------------------------
`include "conf_AFFxx.v"
   //-----------------------------------------------
//
   //Input
   input                 rclk,rrst_n;
   input    pop;
   input    aempty_n;
   //
   //Output
   output    rempty;
   reg     rempty;
   
   output [ADDR_W_P-1:0] rptr;
   reg [ADDR_W_P-1:0]   rptr;
   //
   //--------------------------------------------------------------------
   //  Gray style pointer
   //--------------------------------------------------------------------
   reg [ADDR_W_P-1:0]   rbin;
   wire [ADDR_W_P-1:0]   rgnxt,rbnxt;
   always @(posedge rclk or negedge rrst_n)begin
      if(!rrst_n)  begin
  rbin     <= {ADDR_W_P{1'b0}};
  rptr     <= {ADDR_W_P{1'b0}};
      end
      else  begin
  rbin     <= rbnxt;
  rptr     <= rgnxt;
      end
   end
   //--------------------------------------------------------------------
   // Binary increase , then Binary to Gray
   //--------------------------------------------------------------------
   assign rbnxt = (!rempty) ? (rbin + pop) : rbin;  //-- Binary increase
   assign rgnxt = (rbnxt>>1) ^ rbnxt;                //-- Binary to Gray
   //--------------------------------------------------------------------
   // FIFO empty
   //--------------------------------------------------------------------
   //
   //- double reg async signal or the signal from other clock domain
   reg    rempty2;
   always @(posedge rclk or negedge aempty_n)begin
      if( !aempty_n) begin
  {rempty,rempty2} <= 2'b11;
      end
      else begin
  {rempty,rempty2} <= {rempty2,!aempty_n};
      end
   end
/*
   //--------------------------------------------------------------------
   // FIFO full flag with rclk
   //--------------------------------------------------------------------
   //
   reg    rfull2;
   //
   always @(posedge rclk or negedge rrst_n or negedge afull_n )begin
      if(!rrst_n) begin
  {rfull,rfull2} <= 2'b00;
      end
      else if(!afull_n)  begin
  {rfull,rfull2} <= 2'b11;
      end
      else  begin
  {rfull,rfull2} <= {rfull2,~afull_n};
      end
   end
*/
//--------------------------------------------- end of module --
endmodule

module AFFxxFull(/*AUTOARG*/
   // Outputs
   wfull, wptr,
   // Inputs
   wclk, wrst_n, push, afull_n
   );
   //-----------------------------------------------
`include "conf_AFFxx.v"
   //-----------------------------------------------
   //Input
   input                wclk,wrst_n;
   //
   input   push;
   input   afull_n;
   //
   //Output
   output   wfull;
   reg   wfull;
   
   output [ADDR_W_P-1:0] wptr;
   reg [ADDR_W_P-1:0]   wptr;
   //
   //--------------------------------------------------------------------
   //  Gray style pointer
   //--------------------------------------------------------------------
   reg [ADDR_W_P-1:0]  wbin;
   wire [ADDR_W_P-1:0]  wgnxt,wbnxt;
   always @(posedge wclk or negedge wrst_n)begin
      if(!wrst_n)  begin
  wbin     <= {ADDR_W_P{1'b0}};
  wptr     <= {ADDR_W_P{1'b0}};
      end
      else  begin
  wbin     <= wbnxt;
  wptr     <= wgnxt;
      end
   end // always @ (posedge wclk or negedge wrst_n)
   //--------------------------------------------------------------------
   // Binary increase , then Binary to Gray
   //--------------------------------------------------------------------
   assign wbnxt = (!wfull) ? (wbin + push) : wbin;  //-- Binary increase
   assign wgnxt = (wbnxt>>1) ^ wbnxt;                //-- Binary to Gray
   //--------------------------------------------------------------------
   // A FIFO full flag
   //--------------------------------------------------------------------
   reg    wfull2;
   always @(posedge wclk or negedge wrst_n or negedge afull_n )begin
      if(!wrst_n) begin
  {wfull,wfull2} <= 2'b00;
      end
      else if(!afull_n)  begin
  {wfull,wfull2} <= 2'b11;
      end
      else  begin
  {wfull,wfull2} <= {wfull2,~afull_n};
      end
   end
//--------------------------------------------- end of module --
endmodule

module AFFxxMem(/*AUTOARG*/
   // Outputs
   rdata,
   // Inputs
   wclk, push, wptr, rptr, wdata, wfull
   );
   //-----------------------------------------------
`include "conf_AFFxx.v"
   //-----------------------------------------------
   //Input
   input                           wclk;
   input       push;
   input [ADDR_W_P-1:0]     wptr,rptr;
   input [DATA_W_P-1:0]     wdata;
   input       wfull;
   //Output
   output [DATA_W_P-1:0]     rdata;
   //
   reg [DATA_W_P-1:0]      mm  [0EPTH_P-1];
   //----------------------------------------------
   //-------------------       reg file
   //----------------------------------------------
   /*
   genvar       i;
   generate
      for(i=0; i<DEPTH_P; i=i+1)begin : aff_wd_g
  wire [DEPTH_P_LOG2-1:0] gen_i;
  assign  gen_i = i;
  //----------------------------------------------
  //- Write to FIFO
  //- when full ,also can write, but the newest one will be dropped
  always@( posedge wclk )begin
     if( push && (!wfull) && (wptr==gen_i) )begin
        mm <= wdata;
     end
  end
      end
   endgenerate
   */
   always@( posedge wclk )begin
      if( push && (!wfull) )begin
  mm[wptr] <= wdata;
      end
   end
   //----------------------------------------------
   //- Read from FIFO
   //- when empty ,also can read but read out data will be uncertainty
   assign rdata = mm[rptr];
//--------------------------------------------- end of module --
endmodule // AFFxxMem

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top