异步fifo实现

下面展示一些 内联代码片

//`include "../../rtl/defines.v" //mike 0201
//`define FFD 1
module fifo_async # (
	       parameter DATWIDTH = 18,
	       parameter FIFODEEP = 8,
	       parameter ADRWIDTH = 3
	       )
  (
   input wire 		     rstn,
   //write
   input wire 		     wclk,
   input wire 		     we,
   input wire [DATWIDTH-1:0] dati,
   //read
   input wire 		     rclk,
   input wire 		     re,
   output reg [DATWIDTH-1:0] dato,
   //status
   output reg 		     full,
   output reg 		     empty
   );
  
    //------------------------------------------------------------------------

    //------------------------------------------------------------------------

    //------------------------------------------------------------------------

    reg    [DATWIDTH-1:0] mem [FIFODEEP-1:0];
    wire   [ADRWIDTH-1:0] wadr;
    reg	   [  ADRWIDTH:0] wptr_b;
    reg    [  ADRWIDTH:0] wptr_g;
    reg	   [  ADRWIDTH:0] rptr_g_wsync1;
    reg    [  ADRWIDTH:0] rptr_g_wsync2;
    wire   [  ADRWIDTH:0] wptr_b_next;
    wire   [  ADRWIDTH:0] wptr_g_next;
    wire	  	  full_flag;
    wire   [ADRWIDTH-1:0] radr;
    reg	   [  ADRWIDTH:0] rptr_b;
    reg	   [  ADRWIDTH:0] rptr_g;
    reg    [  ADRWIDTH:0] wptr_g_rsync1;
    reg    [  ADRWIDTH:0] wptr_g_rsync2;
    wire   [  ADRWIDTH:0] rptr_b_next;
    wire   [  ADRWIDTH:0] rptr_g_next;
    wire	  	  empty_flag;

    //------------------------------------------------------------------------

    // rptr sync to wclk domain
    always @(posedge wclk or negedge rstn)
    if (~rstn)
    begin
        rptr_g_wsync1 <=  0;
        rptr_g_wsync2 <=  0;
    end
    else
    begin
        rptr_g_wsync1 <=  rptr_g;
        rptr_g_wsync2 <=  rptr_g_wsync1;
    end

    // fifo write ptr and flag
    always @(posedge wclk or negedge rstn)
    if (~rstn)
    begin
        wptr_b <=  0;
        wptr_g <=  0;
        full   <=  0;
    end
    else
    begin
        wptr_b <=  wptr_b_next;
        wptr_g <=  wptr_g_next;
        full   <=  full_flag;
    end

    assign wptr_b_next = (we && ~full) ? (wptr_b + 1'b1) : wptr_b;
    assign wptr_g_next = {1'b0, wptr_b_next[ADRWIDTH:1]} ^ wptr_b_next;
    assign full_flag   = (wptr_g_next == {~rptr_g_wsync2[ADRWIDTH:ADRWIDTH-1], rptr_g_wsync2[ADRWIDTH-2:0]});
    assign wadr        = wptr_b[ADRWIDTH-1:0];

    // wptr sync to rclk domain
    always @(posedge rclk or negedge rstn)
    if (~rstn)
    begin
        wptr_g_rsync1 <=  0;
        wptr_g_rsync2 <=  0;
    end
    else
    begin
        wptr_g_rsync1 <=  wptr_g;
        wptr_g_rsync2 <=  wptr_g_rsync1;
    end

    // fifo read ptr and flag
    always @(posedge rclk or negedge rstn)
    if (~rstn)
    begin
        rptr_b <=  0;
        rptr_g <=  0;
        empty  <=  1;
    end
    else
    begin
        rptr_b <=  rptr_b_next;
        rptr_g <=  rptr_g_next;
        empty  <=  empty_flag;
    end

    assign rptr_b_next = (re && ~empty) ? (rptr_b + 1'b1) : rptr_b;
    assign rptr_g_next = {1'b0, rptr_b_next[ADRWIDTH:1]} ^ rptr_b_next;
    assign empty_flag  = (rptr_g_next == wptr_g_rsync2);
    assign radr        = rptr_b[ADRWIDTH-1:0];

    // fifo access
    always @(posedge wclk)
    if (we && ~full)
        mem[wadr] <=  dati;

    always@(posedge rclk, negedge rstn)
    if(!rstn)
      dato <= {DATWIDTH{1'b0}};
    else if(re && ~empty)
      dato <= mem[radr];
      
    //assign dato = mem[radr];

endmodule
//`undef FFD

你可能感兴趣的:(lcd,lvds)