本设计参照齐威王大哥的设计,采用模块化的设计方法,每个模块简单易懂,并进行了每个模块的仿真。最后进行顶层设计,编写了测试激励在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的设计与仿真的更多相关文章

  1. 异步fifo的设计

    本文首先对异步 FIFO 设计的重点难点进行分析 最后给出详细代码 一.FIFO简单讲解 FIFO的本质是RAM, 先进先出 重要参数:fifo深度(简单来说就是需要存多少个数据)           ...

  2. 异步fifo的设计(FPGA)

    本文首先对异步 FIFO 设计的重点难点进行分析 最后给出详细代码 一.FIFO简单讲解 FIFO的本质是RAM, 先进先出 重要参数:fifo深度(简单来说就是需要存多少个数据)           ...

  3. 基于Verilog HDL整数乘法器设计与仿真验证

    基于Verilog HDL整数乘法器设计与仿真验证 1.预备知识 整数分为短整数,中整数,长整数,本文只涉及到短整数.短整数:占用一个字节空间,8位,其中最高位为符号位(最高位为1表示为负数,最高位为 ...

  4. Fixed-Point Designer(设计、仿真和分析定点系统)

    Fixed-Point Designer™ 提供开发定点和单精度算法所需的数据类型和工具,以在嵌入式硬件上进行性能优化.Fixed-Point Designer 会分析您的设计并提供建议的数据类型和属 ...

  5. 基于TDA4863-2的单级PFC反激LED电源设计与仿真

    LED是一个非线性器件,正向电压的微小变化会引起电流的巨大变化:LED是一个半导体二极管,其伏安特性随温度变化而变化(-2mV/℃),假如温度升高,在恒压驱动下LED的电流会增加.长期超过额定电流工作 ...

  6. 同步FIFO的设计

    module scfifo #( , ) ( input clk, input rst_n, input wren, input rden, :] din, :] dout, output full, ...

  7. Verilog设计异步FIFO

    转自http://ninghechuan.com 异步FIFO有两个异步时钟,一个端口写入数据,一个端口读出数据.通常被用于数据的跨时钟域的传输. 同步FIFO的设计.一个时钟控制一个计数器,计数器增 ...

  8. 基于FPGA的异步FIFO设计

    今天要介绍的异步FIFO,可以有不同的读写时钟,即不同的时钟域.由于异步FIFO没有外部地址端口,因此内部采用读写指针并顺序读写,即先写进FIFO的数据先读取(简称先进先出).这里的读写指针是异步的, ...

  9. FIFO设计思考之一

    不管同步FIFO还是异步FIFO,设计难点是full/empty状态flag的正确性. 要保证任何情况 FULL时NO WRITE,EMPTY时NO READ.overflow / underflow ...

随机推荐

  1. c traps and pitfalls reading note(1)

    1. 一直知道char *p = 'a';这样写是错误的,但是为什么是错的,没想过,今天看书解惑. p指向一个字符,但是在c中,''引起来的一个字符代表一个整数,这样指针能不报错.o(^▽^)o 2. ...

  2. 解决wps的ppt演示不能打开的问题libbz2.so.1.0

      安装 wps-office-10.1.0.5707-1.a21.x86_64 无法打开ppt 其他正常

  3. nginx proxy_set_header设置,自定义header

    在实际应用中,我们可能需要获取用户的ip地址,比如做异地登陆的判断,或者统计ip访问次数等,通常情况下我们使用request.getRemoteAddr()就可以获取到客户端ip,但是当我们使用了ng ...

  4. 埃及分数 迭代加深搜索 IDA*

    迭代加深搜索 IDA* 首先枚举当前选择的分数个数上限maxd,进行迭代加深 之后进行估价,假设当前分数之和为a,目标分数为b,当前考虑分数为1/c,那么如果1/c×(maxd - d)< a ...

  5. 洛谷 P2734 游戏 A Game

    P2734 游戏 A Game 题目背景 有如下一个双人游戏:N(2 <= N <= 100)个正整数的序列放在一个游戏平台上,游戏由玩家1开始,两人轮流从序列的任意一端取一个数,取数后该 ...

  6. Objective-C的陷阱与缺陷

    Objective-C是一个强大而且非常有用的语言,但是同样也是有一点危险的.这次主题是受到一篇有关C++陷阱的文章启发,来聊聊Objective-C和Cocoa中的陷阱. 简介 我将和Horstma ...

  7. Java基础学习补充 -- 异常处理和log4j日志

    Java中的异常处理 异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的. Java中所有异常的基类Throwable:Throwable又分为Error类和Excepti ...

  8. 使用tinyxml2库解析xml

    tinyxml2简介 tinyxml2是c++编写的轻量级的xml解析器,而且是开放源代码的,在一些开源的游戏引擎中用的比较多.源码托管在github上. 源码地址:https://github.co ...

  9. monad-本质解释- a monad is a design pattern--monad与泛型相关

    monad的特征: 类型转化+添加新的操作. monad  RACStream RACSignal RACSubject monad:单一体,(不可分的)个体 以计算为中心的封装. In functi ...

  10. Ubuntu18.06 Mate桌面环境下VirtuslBox打开虚拟机“全局菜单”异常退出解决办法

    在安装完Ubuntu18.06 Mate桌面环境后在VirtuslBox里打开虚拟机会出现“全局菜单”异常退出问题. 产生上面问题的原因是你的虚拟机可能在 显示= >屏幕= >硬件加速里勾 ...