同步fifo电路图
同步FIFO指的是写操作和读操作都是同一个时钟。为了保证数据的正确性,必须保证FIFO在满的情况下不能进行写操作,在空的状态下不能进行读操作。同时还需要明白一个就是写入了什么的数据,那么才能读出什么数据。电路的代码设计如下:
module fifo( input sys_clk, input sys_rst_n, input [7:0]datain, input wr, input rd, output reg [7:0]dataout, output empt, output full ); reg [3:0]cnt; reg [3:0]wr_ptr; reg [3:0]rd_ptr; reg [7:0]fifo_mem[15:0]; parameter s0=2'b00; parameter s1=2'b01; parameter s2=2'b10; parameter s3=2'b11; always @(posedge sys_clk or negedge sys_rst_n)begin if(!sys_rst_n)begin cnt<=4'b0; wr_ptr<=4'b0; rd_ptr<=4'b0; dataout<=8'b0; end else begin case({rd,wr}) s0:begin cnt<=cnt; wr_ptr<=wr_ptr; rd_ptr<=rd_ptr; dataout<=8'b0; end s1:begin if(!full)begin fifo_mem[wr_ptr]<=datain; wr_ptr<=wr_ptr+1'b1; cnt<=cnt+1'b1; dataout<=8'b0; end end s2:begin if(!empt)begin dataout<=fifo_mem[rd_ptr]; rd_ptr<=rd_ptr+1'b1; wr_ptr<=wr_ptr; cnt<=cnt-1'b1; end end s3:begin if(!full)begin fifo_mem[wr_ptr]<=datain; wr_ptr<=wr_ptr+1'b1; end if(!empt)begin dataout<=fifo_mem[rd_ptr]; rd_ptr<=rd_ptr+1'b1; end end default:; endcase end end assign full=(cnt==4'd15); assign empt=(cnt==4'd0); endmodule
电路的仿真代码设计如下:
`timescale 1ns/1ns module fifo_tb; reg sys_clk; reg sys_rst_n; reg [7:0]datain; reg wr; reg rd; wire [7:0]dataout; wire empt; wire full; initial begin sys_clk=1'b1; sys_rst_n=1'b0; datain=0; #10 sys_rst_n=1'b1; #40 wr=1'b1; #20 rd=1'b1; #20 rd=1'b0; #170 wr=1'b0; #200 rd=1'b1; #40 rd=1'b0; #60 rd=1'b1; #40 rd=1'b0; #1000 $stop; end always #10 sys_clk=~sys_clk; always @(posedge sys_clk)begin datain<=datain+1'b1; end fifo u_fifo( .sys_clk (sys_clk), .sys_rst_n (sys_rst_n), .datain (datain), .wr (wr), .rd (rd), .dataout (dataout), .empt (empt), .full (full) ); endmodule
仿真结果: