fifo周周周周

module syn_fifo(

	input	sys_clk,
	input	rst_n,
	
	input	wr_en,
	input	[7:0]	wr_data,
	output	full,
	
	input	rd_en,
	output	reg	[7:0]	rd_data,
	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 sys_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] <= wr_data;
	else
		fifo[wr_addr] <= fifo[wr_addr];
end

//更新写地址
always @(posedge sys_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 sys_clk or negedge rst_n) begin
	if(!rst_n)
		rd_data <= 8'd0;
	else if(rd_en && (empty==1'b0))
		rd_data <= fifo[rd_addr];
	else
		rd_data <= rd_data;
end

//更新读地址
always @(posedge sys_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 sys_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



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值