同步FIFO的设计
作者:互联网
数字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);
- 方法1: 基于RAM设计, 用长度(fifo深度)计数器fcnt,执行一次写操作,fcnt加1,执行一次读操作,fcnt减1. 写满:fcnt=fifo
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