├── code ├── ex_fifo.v ├── fifo_men.v ├── rd_ctl.v └── wr_ctl.v ├── doc └── 异步FIFO的设计.pdf └── sim └── ex_fifo_tb.v /code/ex_fifo.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 2018/08/26 14:04:20 7 | // Design Name: 8 | // Module Name: ex_fifo 9 | // Project Name: 10 | // Target Devices: 11 | // Tool Versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | 22 | 23 | module ex_fifo#( 24 | parameter FIFO_DEPTH_Bit = 8, 25 | parameter FIFO_WIDTH_Bit = 16, 26 | parameter FIFO_DEPTH = 8 27 | )( 28 | input wr_clk, 29 | input wr_rst_n, 30 | input wr_en, 31 | input [FIFO_WIDTH_Bit-1:0] wr_data, 32 | output wr_full, 33 | 34 | input rd_clk, 35 | input rd_rst_n, 36 | input rd_en, 37 | output [FIFO_WIDTH_Bit-1:0] rd_data, 38 | output rd_empty 39 | ); 40 | wire [FIFO_DEPTH:0] wr_addr_glay; 41 | wire [FIFO_DEPTH-1:0] rd_addr_bin; 42 | wire [FIFO_DEPTH-1:0] wr_addr_bin; 43 | wire [FIFO_DEPTH:0] rd_addr_glay; 44 | rd_ctl#( 45 | .FIFO_DEPTH(FIFO_DEPTH) 46 | )rd_ctl( 47 | .rd_en(rd_en), //input 48 | .rd_clk(rd_clk), //input 49 | .rd_rst_n(rd_rst_n), //input 50 | .wr_addr_glay(wr_addr_glay), //input [FIFO_DEPTH :0] 51 | .rd_addr_bin(rd_addr_bin), //output [FIFO_DEPTH-1 :0] 52 | .rd_addr_glay(rd_addr_glay), //output [FIFO_DEPTH :0] 53 | .rd_empty(rd_empty) //output reg 54 | ); 55 | wr_ctl#( 56 | .FIFO_DEPTH(FIFO_DEPTH) 57 | )wr_ctl( 58 | .wr_en(wr_en), //input 59 | .wr_clk(wr_clk), //input 60 | .wr_rst_n(wr_rst_n), //input 61 | .rd_addr_glay(rd_addr_glay), //input [FIFO_DEPTH :0] 62 | .wr_addr_bin(wr_addr_bin), //output [FIFO_DEPTH-1 :0] 63 | .wr_addr_glay(wr_addr_glay), //output [FIFO_DEPTH :0] 64 | .wr_full(wr_full) //output reg 65 | ); 66 | 67 | fifo_men#( 68 | .FIFO_DEPTH_Bit(FIFO_DEPTH_Bit), 69 | .FIFO_WIDTH_Bit(FIFO_WIDTH_Bit) 70 | )fifo_men( 71 | .wr_data(wr_data), //input [FIFO_WIDTH_Bit-1:0] 72 | .wr_clk(wr_clk), //input 73 | .wr_full(wr_full), //input 74 | .wr_en(wr_en), //input 75 | .wr_addr(wr_addr_bin), //input [FIFO_DEPTH_Bit-1:0] 76 | .rd_clk(rd_clk), //input 77 | .rd_addr(rd_addr_bin), //input [FIFO_DEPTH_Bit-1:0] 78 | .rd_data(rd_data) //output [FIFO_WIDTH_Bit-1:0] 79 | ); 80 | 81 | endmodule 82 | -------------------------------------------------------------------------------- /code/fifo_men.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 2018/08/26 13:21:06 7 | // Design Name: 8 | // Module Name: fifo_men 9 | // Project Name: 10 | // Target Devices: 11 | // Tool Versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | 22 | 23 | module fifo_men#( 24 | parameter FIFO_DEPTH_Bit = 8, 25 | parameter FIFO_WIDTH_Bit = 16 26 | )( 27 | input [FIFO_WIDTH_Bit-1:0] wr_data, 28 | input wr_clk, 29 | input wr_full, 30 | input wr_en, 31 | input [FIFO_DEPTH_Bit-1:0] wr_addr, 32 | input rd_clk, 33 | input [FIFO_DEPTH_Bit-1:0] rd_addr, 34 | output [FIFO_WIDTH_Bit-1:0] rd_data 35 | ); 36 | 37 | 38 | bram_depth256_16bit your_instance_name ( 39 | .clka(wr_clk), // input wire clka 40 | .ena(wr_en&& !wr_full), // input wire ena 41 | .wea(wr_en&& !wr_full), // input wire [0 : 0] wea 42 | .addra(wr_addr), // input wire [7 : 0] addra 43 | .dina(wr_data), // input wire [15 : 0] dina 44 | .clkb(rd_clk), // input wire clkb 45 | .addrb(rd_addr), // input wire [7 : 0] addrb 46 | .doutb(rd_data) // output wire [15 : 0] doutb 47 | ); 48 | 49 | endmodule 50 | -------------------------------------------------------------------------------- /code/rd_ctl.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 2018/08/26 12:49:28 7 | // Design Name: 8 | // Module Name: rd_ctl 9 | // Project Name: 10 | // Target Devices: 11 | // Tool Versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | 22 | 23 | module rd_ctl#( 24 | parameter FIFO_DEPTH = 8 25 | )( 26 | input rd_en, 27 | input rd_clk, 28 | input rd_rst_n, 29 | input [FIFO_DEPTH :0] wr_addr_glay, 30 | output [FIFO_DEPTH-1 :0] rd_addr_bin, 31 | output [FIFO_DEPTH :0] rd_addr_glay, 32 | output reg rd_empty 33 | ); 34 | //output ram addr_bin 35 | reg [FIFO_DEPTH : 0] rd_addr_bin_r; 36 | wire [FIFO_DEPTH : 0] rd_addr_bin_wire; 37 | assign rd_addr_bin_wire = rd_addr_bin_r +(!rd_empty && rd_en); 38 | 39 | always @(posedge rd_clk) begin 40 | if(!rd_rst_n) 41 | rd_addr_bin_r <= 0; 42 | else 43 | rd_addr_bin_r <= rd_addr_bin_wire; 44 | end 45 | assign rd_addr_bin = rd_addr_bin_r; 46 | 47 | //output ram_addr_glay 48 | wire [FIFO_DEPTH : 0] rd_addr_glay_wire; 49 | assign rd_addr_glay_wire = (rd_addr_bin_wire>>1) ^ rd_addr_bin_wire; 50 | reg [FIFO_DEPTH : 0] rd_addr_glay_r; 51 | always @(posedge rd_clk) begin 52 | if(!rd_rst_n) 53 | rd_addr_glay_r <= 0; 54 | else 55 | rd_addr_glay_r <= rd_addr_glay_wire; 56 | end 57 | assign rd_addr_glay = rd_addr_glay_r; 58 | //output fifo rd_empty 59 | reg [FIFO_DEPTH :0 ] wr_addr_glay_r1; 60 | reg [FIFO_DEPTH :0 ] wr_addr_glay_r2; 61 | always @(posedge rd_clk)begin 62 | if(!rd_rst_n) 63 | {wr_addr_glay_r2,wr_addr_glay_r1} <= 0; 64 | else 65 | {wr_addr_glay_r2,wr_addr_glay_r1} <= {wr_addr_glay_r1, wr_addr_glay}; 66 | end 67 | 68 | wire rd_empty_wire; 69 | assign rd_empty_wire = wr_addr_glay_r2== rd_addr_glay_wire; 70 | always @(posedge rd_clk) begin 71 | if(!rd_rst_n) 72 | rd_empty <= 0; 73 | else 74 | rd_empty <= rd_empty_wire; 75 | end 76 | 77 | endmodule 78 | -------------------------------------------------------------------------------- /code/wr_ctl.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 2018/08/26 12:20:00 7 | // Design Name: 8 | // Module Name: wr_ctl 9 | // Project Name: 10 | // Target Devices: 11 | // Tool Versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 8bit 256 , 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | 22 | 23 | module wr_ctl#( 24 | parameter FIFO_DEPTH = 8 25 | )( 26 | input wr_en, 27 | input wr_clk, 28 | input wr_rst_n, 29 | input [FIFO_DEPTH :0] rd_addr_glay, 30 | output [FIFO_DEPTH-1 :0] wr_addr_bin, 31 | output [FIFO_DEPTH :0] wr_addr_glay, 32 | output reg wr_full 33 | ); 34 | 35 | //output ram addr 36 | reg [FIFO_DEPTH :0] wr_addr_bin_r; 37 | wire [FIFO_DEPTH :0] wr_addr_bin_wire; 38 | assign wr_addr_bin_wire = wr_addr_bin_r +(!wr_full && wr_en); 39 | 40 | always @(posedge wr_clk) begin 41 | if(!wr_rst_n) 42 | wr_addr_bin_r <= 0; 43 | else 44 | wr_addr_bin_r <= wr_addr_bin_wire; 45 | end 46 | 47 | assign wr_addr_bin = wr_addr_bin_r; 48 | 49 | //output glay addr 50 | wire [FIFO_DEPTH :0] wr_addr_glay_wire; 51 | assign wr_addr_glay_wire = (wr_addr_bin_wire>>1)^wr_addr_bin_wire; 52 | reg [FIFO_DEPTH :0] wr_addr_glay_r; 53 | 54 | always @(posedge wr_clk) begin 55 | if(!wr_rst_n) 56 | wr_addr_glay_r <= 0; 57 | else 58 | wr_addr_glay_r <= wr_addr_glay_wire; 59 | end 60 | assign wr_addr_glay = wr_addr_glay_r; 61 | //output wr_full 62 | reg [FIFO_DEPTH :0] rd_addr_glay_r1; 63 | reg [FIFO_DEPTH :0] rd_addr_glay_r2; 64 | 65 | always @(posedge wr_clk) begin 66 | if(!wr_rst_n) 67 | {rd_addr_glay_r2,rd_addr_glay_r1} <= 0; 68 | else 69 | {rd_addr_glay_r2,rd_addr_glay_r1} <= {rd_addr_glay_r1,rd_addr_glay}; 70 | end 71 | wire wr_full_w; 72 | wire [FIFO_DEPTH :0] wr_addr_glay_wire1; 73 | assign wr_addr_glay_wire1={~wr_addr_glay_wire[FIFO_DEPTH:FIFO_DEPTH-1],wr_addr_glay_wire[FIFO_DEPTH-2:0]};//并没有按位取反, 74 | assign wr_full_w = wr_addr_glay_wire1==rd_addr_glay_r2; 75 | always @(posedge wr_clk) begin 76 | if(!wr_rst_n) 77 | wr_full <= 0; 78 | else 79 | wr_full <= wr_full_w; 80 | end 81 | endmodule 82 | -------------------------------------------------------------------------------- /doc/异步FIFO的设计.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangkunming0216/FIFO_-asynchronous/0eb65001a31ce404a5c2616ac151be47340f639d/doc/异步FIFO的设计.pdf -------------------------------------------------------------------------------- /sim/ex_fifo_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 2018/08/26 14:55:41 7 | // Design Name: 8 | // Module Name: ex_fifo_tb 9 | // Project Name: 10 | // Target Devices: 11 | // Tool Versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | 22 | 23 | module ex_fifo_tb#( 24 | parameter FIFO_DEPTH_Bit = 8, 25 | parameter FIFO_WIDTH_Bit = 16, 26 | parameter FIFO_DEPTH = 8 27 | 28 | )(); 29 | reg wr_clk ; 30 | reg wr_rst_n; 31 | reg wr_en ; 32 | reg [FIFO_WIDTH_Bit-1:0] wr_data ; 33 | wire wr_full ; 34 | ; 35 | reg rd_clk ; 36 | reg rd_rst_n; 37 | reg rd_en ; 38 | wire [FIFO_WIDTH_Bit-1:0] rd_data ; 39 | wire rd_empty; 40 | localparam CLK_P = 2; 41 | //instant 42 | ex_fifo#( 43 | .FIFO_DEPTH_Bit (FIFO_DEPTH_Bit), 44 | .FIFO_WIDTH_Bit (FIFO_WIDTH_Bit), 45 | .FIFO_DEPTH (FIFO_DEPTH) 46 | )ex_fifo_ins( 47 | .wr_clk (wr_clk), //input 48 | .wr_rst_n (wr_rst_n), //input 49 | .wr_en (wr_en), //input 50 | .wr_data (wr_data), //input [FIFO_WIDTH_Bit-1:0] 51 | .wr_full (wr_full), //output 52 | // 53 | .rd_clk (rd_clk), //input 54 | .rd_rst_n (rd_rst_n), //input 55 | .rd_en (rd_en), //input 56 | .rd_data (rd_data), //output [FIFO_WIDTH_Bit-1:0] 57 | .rd_empty (rd_empty)//output 58 | ); 59 | //time generate 60 | always # CLK_P wr_clk = ~ wr_clk; 61 | always # CLK_P rd_clk = ~ rd_clk; 62 | 63 | initial begin 64 | wr_clk = 0; 65 | rd_clk = 0; 66 | wr_rst_n =0; 67 | rd_rst_n =0; 68 | #100 69 | wr_rst_n =1; 70 | rd_rst_n =1; 71 | end 72 | 73 | initial begin 74 | wr_en =0; 75 | wr_data =0; 76 | #300 77 | write_data(257); 78 | end 79 | initial begin 80 | rd_en =0; 81 | #300 82 | @(posedge wr_full) 83 | read_data(257); 84 | end 85 | 86 | task write_data(len); 87 | integer len,i; 88 | begin 89 | for(i=0;i