ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

同步FIFO的设计

2022-03-20 21:02:36  阅读:195  来源: 互联网

标签:同步 ADDR FIFO WIDTH en input 设计 data addr


数字IC设计学习笔记

同步FIFO的设计

1.  同步FIFO的设计

同步FIFO的设计

  • 问题描述
    设计同步FIFO,宽度8bit,深度512,ADDR位宽:2^9=512

  • Verilog代码

    • 方法1: 基于RAM设计, 用长度(fifo深度)计数器fcnt,执行一次写操作,fcnt加1,执行一次读操作,fcnt减1. 写满:fcnt=fifo
      deapth; 空:fcnt=0&& !en_r)|(factor=1&&en_r);
module fifo_syn(
	rst, //asyn reset
	clk,
	en_r,
	en_w,
	full,
	empty,
	fcnt, //count the number of the data
	data_r,
	data_w
);
	parameter DLY = 1;
	parameter DATA_WIDTH = 8;
	parameter ADDR_WIDTH = 9;
	input						rst;
	input       				clk;
	input [DATA_WIDTH-1:0] 		data_w;	
	input [ADDR_WIDTH-1:0] 		addr_w;		
	input [ADDR_WIDTH-1:0] 		addr_r;		
	input						en_r;
	input						en_w;	
	output  [DATA_WIDTH-1:0]    data_r;
	output						full;
	output						empty;
	output [ADDR_WIDTH-1:0] 	fcnt;		
	
	reg [DATA_WIDTH-1:0]  		data_r;
	reg					  		full;
	reg					  		empty;
	reg [ADDR_WIDTH-1:0]  		fcnt;
	reg [ADDR_WIDTH-1:0] 		addr_w;		
	reg [ADDR_WIDTH-1:0] 		addr_r;
	
	wire	allow_r = (en_r && !empty);
	wire	allow_w = (en_w && !full);	
	
	ram_dual u_ram(
			clk_r(clk),
			clk_w(clk),
			en_r(allow_r),
			en_w(allow_w),
			addr_r(addr_r),
			addr_w(addr_w).
			data_r(data_r),
			data_w(data_w)
	);
//emty
	always@(posedge clk or posedge rst)begin
		if(rst)
			emty<= 1'b1;
		else
			emty<= (!en_w &&( (fcnt=8'h1 && en_r=1)|| (fcnt=0)&&en_r=0));
	end
//full
	always@(posedge clk or posedge rst)begin
		if(rst)
			full<= 1'b1;
		else
			full<= (!en_r &&( (fcnt=8'd510 && en_w=1)|| (fcnt=9'd511&&en_w=0));
	end
//read operation
	always@(posedge clk or posedge rst)
		if(rst)
			addr_r <= 'h0;
		else if(allow_r)
			addr_r <=addr_r +'b1;
//write operation
	always@(posedge clk or posedge rst)
		if(rst)
			addr_w <= 'h0;
		else if(allow_w)
			addr_w <=addr_w +'b1;
	
endmodule
//***********************
//		ram rtl
//***********************
//https://blog.csdn.net/weixin_50722839/article/details/123612913?spm=1001.2014.3001.5501
  • 方法2: 地址位扩展一位,用最高位来判断空满。若低位地址addr_r=addr_w, 高位相等,就为空;不相等,就为满。
module fifo_syn(
	rst, //asyn reset
	clk,
	en_r,
	en_w,
	full,
	empty,
	data_r,
	data_w
);
	parameter DATA_WIDTH = 8;
	parameter ADDR_WIDTH = 9;
	parameter RAM_DEPTH = 512;
	input						rst;
	input       				clk;
	input [DATA_WIDTH-1:0] 		data_w;			
	input						en_r;
	input						en_w;	
	output  [DATA_WIDTH-1:0]    data_r;
	output						full;
	output						empty;
	reg [DATA_WIDTH-1:0] mem [DATA_WIDTH-1:0];
	wire [ADDR_WIDTH-1:0] 		addr_w;		
	wire [ADDR_WIDTH-1:0] 		addr_r;	
	reg  [ADDR_WIDTH:0] 		addr1_w;		
	reg  [ADDR_WIDTH:0] 		addr1_r;
	
	assign addr1_w = addr1_w[DATA_WIDTH-1:0];
	assign addr1_r = addr1_w[DATA_WIDTH-1:0];
//read operation		
	always@(posedge clk or posedge rst)
	begin
		if(rst)
		begin
			addr1_r<='h0;
		end
		else begin
		if(en_r==1&&empty==0)
			begin
				data_r<=mem[addr_r];
				addr1_r<= addr_r + 'b1;
			end
		end		
	end
//write operation
	always@(posedge clk or posedge rst)
	begin
		if(rst)
		begin
			addr1_w<='h0;
		end
		else begin
		if(en_w==1&&full==0)
			begin
				mem[addr_w]<=data_w;
				addr1_w<= addr_w + 'b1;
			end
		end		
	end	
//empty
assign empty= (addr1_r==addr1_w)?1:0;
//full
assign full= ((addr1_r[ADDR_WIDTH]!=addr1_w[ADDR_WIDTH])&&(addr1_r[ADDR_WIDTH-1:0]==addr1_w[ADDR_WIDTH-1:0]))?1:0;	
endmodule

【注】:个人学习笔记,如有错误,望不吝赐教,这厢有礼了~~~


标签:同步,ADDR,FIFO,WIDTH,en,input,设计,data,addr
来源: https://blog.csdn.net/weixin_50722839/article/details/123613874

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有