verilog实现同步FIFO

verilog实现同步FIFO:


同步FIFO是一种先进先出的数据缓存器,在逻辑设计里面用的非常多,FIFO 设计可以说是逻辑设计人员必须掌握的常识性设计。FIFO 一般用在隔离两边读写带宽不一致,或者位宽不一样的地方。
FIFO 与普通存储器 RAM 的区别是没有外部读写地址线,使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加 1 完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。 FIFO 本质上是由 RAM 加读写控制逻辑构成的一种先进先出的数据缓冲器。

下面设计一个16*8(16是深度,8是位宽)的FIFO:

module syn_fifo(

	input	clk,
	input	rst_n,
	
	input	wr_en,
	input	[7:0]	data_in,
	output	full,
	
	input	rd_en,
	output	reg	[7:0]	data_out,
	output	empty

);

reg	[3:0]	wr_addr;
reg	[3:0]	rd_addr;
reg	[3:0]	cnt;

parameter	max_cnt = 4'd15;
reg	[7:0]	fifo[max_cnt:0]; //16*8(16是深度,8是位宽)的fifo

assign empty = (cnt==4'd0) ? 1'b1:1'b0;
assign full = (cnt==max_cnt) ? 1'b1:1'b0;

//写数据
integer i;
always @(posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		for(i=0;i<max_cnt+1'b1;i=i+1)
			fifo[i] <= 8'd0;
	end
	else if(wr_en && (full==1'b0))
		fifo[wr_addr] <= data_in;
	else
		fifo[wr_addr] <= fifo[wr_addr];
end

//更新写地址
always @(posedge clk or negedge rst_n) begin
	if(!rst_n)
		wr_addr <= 4'd0;
	else if(wr_en && (full==1'b0))
		wr_addr <= wr_addr + 1'b1;
	else
		wr_addr <= wr_addr;
end

//读数据
always @(posedge clk or negedge rst_n) begin
	if(!rst_n)
		data_out <= 8'd0;
	else if(rd_en && (empty==1'b0))
		data_out <= fifo[rd_addr];
	else
		data_out <= data_out;
end

//更新读地址
always @(posedge clk or negedge rst_n) begin
	if(!rst_n)
		rd_addr <= 4'd0;
	else if(rd_en && (empty==1'b0))
		rd_addr <= rd_addr + 1'b1;
	else
		rd_addr <= rd_addr;
end

//更新计数器
always @(posedge clk or negedge rst_n) begin
	if(!rst_n)
		cnt <= 4'd0;
	else begin
		case({wr_en,rd_en})
			2'b00: cnt <= cnt;
			2'b01: begin
					if(cnt != 4'd0)
						cnt <= cnt - 1'b1;
					else
						cnt <= cnt;
					end
			2'b10: begin
					if(cnt != max_cnt)
						cnt <= cnt + 1'b1;
					else
						cnt <= cnt;
					end
			2'b11: cnt <= cnt;
			default: ;
		endcase
	end
end

endmodule



仿真代码:


`timescale 1 ps/ 1 ps
module syn_fifo_tb();

reg clk;
reg [7:0] data_in;
reg rd_en;
reg rst_n;
reg wr_en;
                                             
wire [7:0]  data_out;
wire empty;
wire full;


initial	begin 
	clk = 0;
	rst_n = 0;
	rd_en = 0;
	wr_en = 0;
	data_in = 0;
	
	#40 rst_n = 1;
	#35 wr_en = 1;
	#200 rd_en = 1;
	
end     

always #20 data_in <= data_in + 1'b1;

always #10 clk <= ~clk;


syn_fio i1 (
	.clk(clk),
	.data_in(data_in),
	.data_out(data_out),
	.empty(empty),
	.full(full),
	.rd_en(rd_en),
	.rst_n(rst_n),
	.wr_en(wr_en)
);                                                 
endmodule



仿真图片:

verilog实现同步FIFO_第1张图片

你可能感兴趣的:(FPGA/IC笔试题,fpga开发,硬件工程,开发语言)