- // ****************************************************************************************************************
- // Copyright(c) 2012, Technology Endless - Creative Boundless , All right reserved
- // Filename : asynfifo.v
- // Author : lucien
- // Email : intellectuallib@126.com
- // Date : Apr 22th, 2012
- // Version : 1.0
- // Company :
- // Description : asynchronous FIFO(first in first out)
- // Modification History
- // Date By Revision Change Description
- // ---------------------------------------------------------------------------------------
- // 2012/04/22 Lucien 1.0 Original
- // ****************************************************************************************************************
- `timescale 1ns/1ps
- module asynfifo(
- rst ,
- wr_clk ,
- wr_en ,
- din ,
- full ,
- rd_clk ,
- rd_en ,
- dout ,
- empty
- );
- input wire rst ;//reset signal
- input wire wr_clk ;//clock of read clock field
- input wire wr_en ;//write enable
- input wire [7:0] din ;
- output wire full ;
- input wire rd_clk ;//clock of write clock field
- input wire rd_en ;
- output wire [7:0] dout ;
- output wire empty ;
- /**************************************************************************************************************/
- /**************************************************************************************************************\
- * define internal signals *
- \**************************************************************************************************************/
- reg [7:0] waddr; //write address in write clock field
- reg [7:0] raddr; //read address in read clock field
- wire [7:0] waddr_gray_wclk; //the gray code of write address in write clock field
- wire [7:0] raddr_gray_rclk; //the gray code of read address in read clock field
- reg [7:0] waddr_gray_rclk_0; //the dealyed gray codes of write address in read clock field
- reg [7:0] waddr_gray_rclk_1;
- reg [7:0] raddr_gray_wclk_0; //the dealyed gray codes of read address in write clock field
- reg [7:0] raddr_gray_wclk_1;
- wire [7:0] waddr_rclk; //write address in read clock field
- wire [7:0] raddr_wclk; //read address in write clock field
- reg [8:0] count_wclk; //the data counter in write clock field
- reg [8:0] count_rclk; //the data counter in read clock field
- function [7:0] binary_to_gray;
- input [7:0] binary_code ;
- begin
- binary_to_gray[0]=binary_code[0]^binary_code[1];
- binary_to_gray[1]=binary_code[1]^binary_code[2];
- binary_to_gray[2]=binary_code[2]^binary_code[3];
- binary_to_gray[3]=binary_code[3]^binary_code[4];
- binary_to_gray[4]=binary_code[4]^binary_code[5];
- binary_to_gray[5]=binary_code[5]^binary_code[6];
- binary_to_gray[6]=binary_code[6]^binary_code[7];
- binary_to_gray[7]=binary_code[7];
- end
- endfunction
- function [7:0] gray_to_binary;
- input [7:0] gray_code ;
- begin
- gray_to_binary[7]=waddr_gray_rclk_1[7];
- gray_to_binary[6]=waddr_gray_rclk_1[6]^gray_to_binary[7];
- gray_to_binary[5]=waddr_gray_rclk_1[5]^gray_to_binary[6];
- gray_to_binary[4]=waddr_gray_rclk_1[4]^gray_to_binary[5];
- gray_to_binary[3]=waddr_gray_rclk_1[3]^gray_to_binary[4];
- gray_to_binary[2]=waddr_gray_rclk_1[2]^gray_to_binary[3];
- gray_to_binary[1]=waddr_gray_rclk_1[1]^gray_to_binary[2];
- gray_to_binary[0]=waddr_gray_rclk_1[0]^gray_to_binary[1];
- end
- endfunction
- simple_dual_port_ram U_simple_dual_port_ram(
- .clka (wr_clk ),
- .wea (wr_en ),
- .addra (waddr ),
- .dina (din ),
- .clkb (rd_clk ),
- .addrb (raddr ),
- .doutb (dout )
- );
- assign empty = (count_rclk[8:0] == 9'h0);
- assign full = (count_rclk[8:0] == 9'h100);
- assign waddr_gray_wclk = binary_to_gray(waddr);
- assign raddr_gray_rclk = binary_to_gray(raddr);
- assign waddr_rclk = gray_to_binary(waddr_gray_rclk_1);
- assign raddr_wclk = gray_to_binary(raddr_gray_wclk_1);
- always@(posedge wr_clk or posedge rst)
- begin
- if(rst == 1'b1)
- waddr <= 8'h0;
- else
- if(wr_en==1'b1)
- waddr <= waddr + 8'h1;
- else
- waddr <= waddr;
- end
- always@(posedge rd_clk or posedge rst)
- begin
- if(rst == 1'b1)
- raddr <= 8'h0;
- else
- if(wr_en==1'b1)
- raddr <= raddr + 8'h1;
- else
- raddr <= raddr;
- end
- always@(posedge wr_clk or posedge rst)
- begin
- if(rst == 1'b1)
- begin
- raddr_gray_wclk_0<=8'b0;
- raddr_gray_wclk_1<=8'b0;
- end
- else
- begin
- raddr_gray_wclk_0<=raddr_gray_rclk;
- raddr_gray_wclk_1<=raddr_gray_wclk_0;
- end
- end
- always@(posedge rd_clk or posedge rst)
- begin
- if(rst == 1'b1)
- begin
- waddr_gray_rclk_0<=8'b0;
- waddr_gray_rclk_1<=8'b0;
- end
- else
- begin
- waddr_gray_rclk_0<=waddr_gray_wclk;
- waddr_gray_rclk_1<=waddr_gray_rclk_0;
- end
- end
- always@(posedge wr_clk or posedge rst)
- begin
- if(rst == 1'b1)
- count_wclk <= 9'h0;
- else
- if(waddr < raddr_wclk)
- count_wclk <= waddr + 9'h100 - raddr_wclk;
- else if((count_wclk > 9'h0) && (waddr == raddr_wclk))
- count_wclk <= 9'h100;
- else
- count_wclk <= waddr - raddr_wclk;
- end
- always@(posedge rd_clk or posedge rst)
- begin
- if(rst == 1'b1)
- count_rclk <= 9'h0;
- else
- if(waddr_rclk < raddr)
- count_rclk <= waddr_rclk + 9'h100 - raddr;
- else if((count_rclk > 9'h0) && (waddr_rclk == raddr))
- count_rclk <= 9'h100;
- else
- count_rclk <= waddr_rclk - raddr;
- end
- endmodule
|