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 ...
随机推荐
- appium ios端自动化测试配置
一.安装环境介绍macOS 10.12.4 Xcode 8.3.2 适用机型:iOS9 及以上机型 二.Appium源码安装Xcode升级8.2之后不再支持UIAutomation,转而使用XCUIT ...
- CSS核心原理
1.优先原则: 后解析的内容,会覆盖掉之前解析的内容: 同一个选择器:文件执行从上往下,后面的样式会覆盖前面的: 如下例中color最终为粉色: div { color:red; color:pink ...
- BZOJ 3325 [SCOI2013]密码 (逆模拟Manacher+构造)
题目大意:给你一个字符串每个位置和相邻两个位置为回文中心的最长回文串长度,让你构造一个合法的字典序最小的字符串 挺有意思的构造题 首先按照$Manacher$的思想还原$p$数组 定义$f_{ij}$ ...
- VMware exsi 虚拟化嵌套
默认情况下exsi 虚拟化嵌套是没开启的 需要我们连接exsi主机,从后台找到对应的虚拟机修改配置文件开启虚拟化功能 1.连接exsi主机,开启ssh功能 2.ssh到exsi主机,修改配置文件 查找 ...
- caioj 1114 树形动态规划(TreeDP)3.0:多叉苹果树【scy改编ural1018二叉苹果树】
一波树上背包秒杀-- #include<cstdio> #include<cstring> #include<algorithm> #include<vect ...
- 紫书 习题8-11 UVa 1615 (区间选点问题)
这个点就是贪心策略中的区间选点问题. 把右端点从大到小排序, 左端点从小到大排序. 每次取区间右端点就可以了, 到不能覆盖的时候就ans++, 重新取点 ps:这道题不考虑精度也可以过 要着重复习一下 ...
- Java基础学习总结(3)——抽象类
一.抽象类介绍 下面通过一下的小程序深入理解抽象类 因此在类Animal里面只需要定义这个enjoy()方法就可以了,使用abstract关键字把enjoy()方法定义成一个抽象方法,定义如下:pub ...
- solr在windows下的安装及配置
solr在windows下的安装及配置 首先,solr是基于Java开发的,所以使用的话需要先进行java环境的配置,在Java环境配置好之后就可以去http://www.apache.org/dyn ...
- mysql-创建和操作表
一.建表 为了用程序创建表,我们可以使用SQL的create table 语句.如下: 每个列之间用逗号隔开,每列的定义以列名开始,后跟列的数据类型. 表的主键可以在创建表时用primary key关 ...
- hdu_2871
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #i ...