FIFO的设计与仿真
本设计参照齐威王大哥的设计,采用模块化的设计方法,每个模块简单易懂,并进行了每个模块的仿真。最后进行顶层设计,编写了测试激励在modisim上仿真正确,
下面给出代码和测试激励,附上一篇比较好的英文文献。

1 module yibu_fifo(wclk,wreset,wdata,wena,rclk,rena,rdata,rreset,full,empty);
2 parameter DSIZE = 8,
3 ASIZE = 4;
4 input wclk,wreset,rclk,rreset;
5 input wena,rena; //写控制信号 读控制信号
6 input [DSIZE-1:0] wdata; //写数据
7 output[DSIZE-1:0] rdata; //读数据
8 output full,empty ;//写满 读空
9 wire [ASIZE:0] wzz, wzz_syn,rzz,rzz_syn; //特别注意
10 wire [ASIZE-1:0] raddr,waddr; //特别注意
11 fifomem U1(rdata, wdata, waddr, raddr, wena,full, wclk);
12 w_full U2(full, waddr, wzz, rzz_syn, wena, wclk, wreset);
13 r_empty U3(empty, raddr, rzz, wzz_syn, rena, rclk, rreset);
14 syn_w2r U4(wzz,rclk,rreset,wzz_syn);
15 syn_r2w U5(wclk,wreset,rzz,rzz_syn);
16 endmodule


module fifomem (rdata, wdata, waddr, raddr, wena,full, wclk);
parameter DSIZE = 8,
ASIZE = 4;
input wclk;
input [DSIZE-1:0] wdata;
input wena,full;
output [DSIZE-1:0] rdata;
input [ASIZE-1:0] waddr;
input [ASIZE-1:0] raddr;
reg [DSIZE-1:0] mem[0:(1<<ASIZE)-1]; //register
assign rdata=mem[raddr]; //read
always @(posedge wclk) //write
if (wena && !full)
mem[waddr] <= wdata;
endmodule


module r_empty(empty, raddr, rzz, wzz_syn, rena, rclk, rreset);
parameter DSIZE = 8,
ASIZE = 4; //
input rclk, rreset,rena;
input [ASIZE:0] wzz_syn;
output [ASIZE:0] rzz;
output [ASIZE-1:0] raddr;
output empty;
reg empty;
reg [ASIZE:0] rzz;
reg [ASIZE:0] rbin;
wire [ASIZE:0] rgraynext,rbinnext;
//-------------empty产生与raddr产生-------------------
always @(posedge rclk or negedge rreset) // GRAYSTYLE2 pointer
begin
if (!rreset)
{rbin, rzz} <= 0;
else
{rbin, rzz} <= {rbinnext, rgraynext};
end
// Memory read-address pointer (okay to use binary to address memory)
assign raddr = rbin[ASIZE-1:0];
assign rbinnext = rbin + (rena & ~empty);
assign rgraynext = (rbinnext>>1) ^ rbinnext; // FIFO empty when the next rptr == synchronized wptr or on reset
assign rempty_val = (rgraynext == wzz_syn);
always @(posedge rclk or negedge rreset)
begin
if (!rreset)
empty <= 1'b1;
else
empty <= rempty_val;
end
endmodule


module w_full(full, waddr, wzz, rzz_syn, wena, wclk, wreset);
parameter DSIZE = 8,
ASIZE = 4;
input wclk,wreset;
input wena;
input [ASIZE:0] rzz_syn;
output [ASIZE:0] wzz;
output full;
output [ASIZE-1:0] waddr;
reg full;
reg [ASIZE:0] wzz;
reg [ASIZE:0] wbin;
wire [ASIZE:0] wgraynext,wbinnext;
//---------------full产生与waddr产生--------------------
always @(posedge wclk or negedge wreset)
if (!wreset)
{wbin, wzz} <= 0;
else
{wbin, wzz} <= {wbinnext, wgraynext};
// Memory write-address pointer (okay to use binary to address memory)
assign waddr = wbin[ASIZE-1:0];
assign wbinnext = wbin + (wena & ~full); assign wgraynext = (wbinnext>>1) ^ wbinnext; //bin to g
assign wfull_val = (wgraynext=={~rzz_syn[ASIZE:ASIZE-1], rzz_syn[ASIZE-2:0]}); // full always @(posedge wclk or negedge wreset)
if (!wreset)
full <= 1'b0;
else
full <= wfull_val;
endmodule


module syn_r2w(wclk,wreset,rzz,rzz_syn);
parameter DSIZE = 8,
ASIZE = 4;
input wclk,wreset;
input [ASIZE:0] rzz;
output [ASIZE:0] rzz_syn;
reg [ASIZE:0] rzz_syn;
reg [ASIZE:0] rzz_syn_1; //两级同步
always @(posedge wclk or negedge wreset)
if(!wreset)
{rzz_syn,rzz_syn_1} <= 0;
else
{rzz_syn,rzz_syn_1} <= {rzz_syn_1,rzz};
endmodule


module syn_w2r (wzz,rclk,rreset,wzz_syn);
parameter DSIZE = 8,
ASIZE = 4;
input rclk,rreset;
input [ASIZE:0] wzz;
output [ASIZE:0] wzz_syn;
reg [ASIZE:0] wzz_syn;
reg [ASIZE:0] wzz_syn_1; //两级同步
always @(posedge rclk or negedge rreset)
if (!rreset)
{wzz_syn,wzz_syn_1} <= 0;
else
{wzz_syn,wzz_syn_1} <= {wzz_syn_1,wzz};
endmodule


module testbench;
reg wclk,wreset;
reg rclk,rreset;
reg rena;
reg wena;
wire full;
wire empty;
reg [7:0] wdata;
wire [7:0] rdata;
reg [7:0] value;
yibu_fifo FIFO(wclk,wreset,wdata,wena,rclk,rena,rdata,rreset,full,empty);
// read
task read_word;
begin
@(negedge rclk);
rena = 1;
@(posedge rclk)
#5;
rena = 0;
end
endtask
//write
task write_word;
input [7:0] value;
begin
@(negedge wclk);
wdata = value;
wena = 1;
@(posedge wclk);
#5;
wdata = 8'hzz;
wena = 0;
end
endtask
//write clock
initial begin
wclk = 0;
forever begin
#5 wclk = 1;
#5 wclk = 0;
end
end
//read clock
initial begin
rclk = 0;
forever begin
#10 rclk = 1;
#10 rclk = 0;
end
end
// process
initial
begin
test1;
end
task test1;
begin
wdata = 8'hzz;
wena = 0;
rena = 0;
wreset = 0;
rreset= 0;
#10 wreset = 1;rreset=1;
#50;
//写入10个数据
write_word (8'h01);
write_word (8'h02); //正常
write_word (8'h03);
write_word (8'h04);
write_word (8'h05);
write_word (8'h06);
write_word (8'h07);
write_word (8'h08);
write_word (8'h09);
write_word (8'h0A);
repeat (10)
begin
read_word; // read 10
end
write_word (8'h01);
write_word (8'h02);
write_word (8'h03);
write_word (8'h04);
write_word (8'h05);
write_word (8'h06);
write_word (8'h07);
write_word (8'h08);
write_word (8'h09);
write_word (8'h0A);
write_word (8'h0B);
write_word (8'h0C);
write_word (8'h0D);
write_word (8'h0E);
write_word (8'h0F);
write_word (8'h10);
write_word (8'h11);
write_word (8'h12);
write_word (8'h13); // 写满溢出
repeat (16)
begin
read_word; // 读空
end
end
endtask
endmodule

2013-03-24
英文文献http://www.sunburst-design.com/papers/
FIFO的设计与仿真的更多相关文章
- 异步fifo的设计
本文首先对异步 FIFO 设计的重点难点进行分析 最后给出详细代码 一.FIFO简单讲解 FIFO的本质是RAM, 先进先出 重要参数:fifo深度(简单来说就是需要存多少个数据) ...
- 异步fifo的设计(FPGA)
本文首先对异步 FIFO 设计的重点难点进行分析 最后给出详细代码 一.FIFO简单讲解 FIFO的本质是RAM, 先进先出 重要参数:fifo深度(简单来说就是需要存多少个数据) ...
- 基于Verilog HDL整数乘法器设计与仿真验证
基于Verilog HDL整数乘法器设计与仿真验证 1.预备知识 整数分为短整数,中整数,长整数,本文只涉及到短整数.短整数:占用一个字节空间,8位,其中最高位为符号位(最高位为1表示为负数,最高位为 ...
- Fixed-Point Designer(设计、仿真和分析定点系统)
Fixed-Point Designer™ 提供开发定点和单精度算法所需的数据类型和工具,以在嵌入式硬件上进行性能优化.Fixed-Point Designer 会分析您的设计并提供建议的数据类型和属 ...
- 基于TDA4863-2的单级PFC反激LED电源设计与仿真
LED是一个非线性器件,正向电压的微小变化会引起电流的巨大变化:LED是一个半导体二极管,其伏安特性随温度变化而变化(-2mV/℃),假如温度升高,在恒压驱动下LED的电流会增加.长期超过额定电流工作 ...
- 同步FIFO的设计
module scfifo #( , ) ( input clk, input rst_n, input wren, input rden, :] din, :] dout, output full, ...
- Verilog设计异步FIFO
转自http://ninghechuan.com 异步FIFO有两个异步时钟,一个端口写入数据,一个端口读出数据.通常被用于数据的跨时钟域的传输. 同步FIFO的设计.一个时钟控制一个计数器,计数器增 ...
- 基于FPGA的异步FIFO设计
今天要介绍的异步FIFO,可以有不同的读写时钟,即不同的时钟域.由于异步FIFO没有外部地址端口,因此内部采用读写指针并顺序读写,即先写进FIFO的数据先读取(简称先进先出).这里的读写指针是异步的, ...
- FIFO设计思考之一
不管同步FIFO还是异步FIFO,设计难点是full/empty状态flag的正确性. 要保证任何情况 FULL时NO WRITE,EMPTY时NO READ.overflow / underflow ...
随机推荐
- django 获得请求头
django 获得到的请求头封装在 request 的 META 中,为一个 dict 以下选自官方文档: https://docs.djangoproject.com/zh-hans/2.0/ref ...
- 字符串的格式化(转自武sir)
百分号s方式: (name) 可选,用于选择指定的key flags 可选,可供选择的值有: + 右对齐:正数前加正好,负数前加负号: - 左对齐 ...
- CSS 子元素选择器
所有选择器参考手册:http://www.w3school.com.cn/cssref/css_selectors.asp 1)子元素选择器 参考链接:http://www.w3school.com. ...
- 让div垂直居中
参考链接:https://www.cnblogs.com/softwarefang/p/6095806.html 以前我的方法总是比较粗暴,纯粹通过margin来实现,这个方法的缺点不仅在于需要多次微 ...
- 紫书 例题8-19 UVa 12265 (扫描法+单调栈)
首先可以用扫描法处理出一个height数组, 来保存从当前行开始, 每一个格子可以向上延伸的最大长度. 这种"延伸"的问题用扫描法, 因为往往这个时候可以利用前一次的结果来更新当前 ...
- matlab 中语句 a(b)的意思
a=[1 2; 3, 4; 5, 6]; b=[1 3 2 1; 1 2 4 2]; c=a(b) c = 1 5 3 1 1 3 ...
- ActiveMQ安装部署(Windows)
JMS(Java Messaging Service)是Java平台上有关面向消息中间件的技术规范,它便于消息系统中的Java应用程序进行消息交换,并且通过提供标准的产生.发送.接收消息的接口简化企业 ...
- java实现上传图片
1.将图片上传到tomcat下 2.将相对路径存放到数据库中 @RequestMapping(params="upLoadPicture") @ResponseBody publi ...
- HttpClient 图讲解明
大家刚看这个名字一定会想问这是什么东东,在这我特意百度百科了下 HTTP 协议可能是如今 Internet 上使用得最多.最重要的协议了,越来越多的 Java 应用程序须要直接通过 HTTP 协议来訪 ...
- php 数组元素高速去重
1.使用array_unique方法进行去重 对数组元素进行去重.我们通常会使用array_unique方法,使用这种方法能够把数组中的元素去重. <?php $arr = array(1,1, ...