




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、同步缓冲器(FIFO)的设计与实现姓名:崔 琦 学号:100260305班级:2010级电科3班院系:电气与信息工程学院专业:电子科学与技术 同组人姓名:梁承润 李建凯 (说明:我们三个人前面的报告部分是一样的,因为课设基本是三个人商议完成,所以就感觉报告部分没什么不同的就只写了一份报告)目 录1原理与系统设计32设计思想43源码与注释54仿真125综合156心得体会与建议191 原理与系统设计FIFO(First In First Out)是一种可以实现数据先入先出的存储器件。FIFO就像一个单向管道,数据只能按固定的方向从管道一头进来,再按相同的顺序从管道另一头出去,最先进来的数据必定是最
2、先出去。FIFO被普遍用作数据缓冲器。FIFO的基本单元是寄存器,作为存储器件,FIFO的存储能力是由其内部定义的存储寄存器的数量决定的。本题中所设计的是同步FIFO(即输出输入端时钟频率一致),异步复位,其存储能力为(16x8),输出两个状态信号:full与empty,以供后继电路使用。根据系统要求,画出的系统框图,如图1所示图1同步FIFO框图端口说明:输入:in_data: 输入数据端口,位宽为8位;read_n: 读使能端,当read_n=0时,可以读出数据;write_n: 写使能端,当write_n=0时,可以写入数据;clock: 时钟信号, 在时钟的正边沿进行采样;reset_
3、n: 复位信号,当reset_n=0时,计数器及读写都被清零(即:读写地址指针都指向0)输出:out_data: 输出数据端口,位宽为8位;;full:FIFO状态信号,当full=1时,表明该FIFO存储器已经写满;empty:FIFO状态信号,当empty=1时,表明该FIFO存储器已经读空;FIFO满的情况下,不能再写,写指针不能加1;FIFO空的情况下,不能再读,读指针不能加1;2 设计思想由以上的系统框图和端口分析,我们将设计的重点定在了解决以下三个核心问题上:1. FIFO的存储体如何表示?2. 如何实现“先进先出”的逻辑功能?3. 如何知道FIFO内部使用了多少,是满是空?针对以
4、上三个问题,我们所采取的方法是:1. 定义一个16×8的二维数组来表示FIFO的存储体。2. 为了实现“先进先出”的逻辑功能,我们定义了“读指针”及“写指针”,分别用来指示读操作与写操作的位置。3. 为了表示FIFO是满还是空,我们定义了一个计数器,用以标志FIFO已使用了多少空间。在解决了以上三个重点问题以后,针对同步FIFO的逻辑功能,我们拟定了以下一个结构图,如图2所示: 图2 FIFO设计结构图3源码与注释3.1源代码我们在完成了之前两步的准备工作之后,进行了源码的设计,具体的代码如下:define DEL 1 /为了使仿真接近真实情形,我们定义了从时钟到输出的延时modul
5、e sfifo(clock,reset_n,in_data,read_n,write_n,out_data,full,empty);/输入信号input clock; /输入时钟input reset_n; /复位信号,低有效input7:0 in_data; /输入的数据input read_n; /读控制信号,低有效input write_n; /写控制信号,低有效/输出信号 output7:0 out_data; /FIFO的输出数据output full; /FIFO满标志信号output empty; /FIFO空标志信号/信号声明 reg 7:0 out_data; reg 7:0
6、 fifo_mem15:0; /FIFO存储体即8*16存储器,用数组表示reg 4:0 counter; /计数器表示FIFO中已用了多少reg 3:0 rd_pointer; /FIFO读指针,指向下次读操作的地址reg 3:0 wr_pointer; /FIFO读指针,指向下次读操作的地址/赋值声明,给出满标志与空标志的实现 assign #DEL full=(counter=16)?1'b1:1'b0; assign #DEL empty=(counter=0)?1'b1:1'b0;/本模块实现读指针、写指针和计数器的功能always(posedge c
7、lock or negedge reset_n)beginif(reset_n)begin /计数器及读、写指针清零 rd_pointer<=#DEL 4'b0; wr_pointer<=#DEL 4'b0; counter<=#DEL 5'b0; end else beginif(read_n) begin /如果FIFO为空,不能再读,并报错 if(counter=0)/检查fifo是否溢出(empty) begin $display("nERROR at time %0t:",$time); $display("FI
8、FO Underflown"); $stop; /终止系统任务,用于调试 end /读有效,写无效时,计数器减1 if(write_n) begin counter<=#DEL counter-1; end /如果读指针已指到最后一个位置,则返回起始位置 if(rd_pointer = 15) rd_pointer <= #DEL 4'b0; else rd_pointer <= #DEL rd_pointer + 1; endif(write_n)/检查fifo是否溢出(full)beginif(counter>=16)begin$display(&
9、quot;n ERROR at time %0t:", $time);$display("FIFO overflown");$stop;endif(read_n)/写有效,读无效时,计数器加1begincounter <= #DEL counter + 1;endif(wr_pointer = 15)/如果写指针已指到最后一位,则返回起始位置wr_pointer <= #DEL 4'b0;elsewr_pointer <= #DEL wr_pointer + 1;endendendalways(posedge clock)/本模块实现数据
10、的读写功能beginif(write_n)beginfifo_memwr_pointer <= #DEL in_data;endif(read_n)beginout_data <= #DEL fifo_memrd_pointer;/读取数据endendendmodule3.2测试文件本设计中为了让输入激励能够完整地测试出设计的功能,以证明FIFO确实能起到数据缓冲的作用,因而要测试当读写速度不一致的情况,即要仿真写速度大于读速度的情形以及读速度大于写速度的情形。测试文件中:异步复位如下进行:reset_n=1; #20 reset_n=0; #20 reset_n=1;时钟信号如下
11、产生:always #100 clock<=clock;写入数据递增加1产生:in_data <= in_data + 1;而编写测试文件的核心问题在于:在同一文件中如何既能仿真写快与读的情形又能仿真读快于写的情形?对此,我们的想法:先让写快于读以达到满的状态(full=1),而后让读快于写以达到排空的状态(empty=1)由此我们定义了两个状态信号:fast_read: fast_read=1时以高速度进行读操作 fast_write:fast_write=1时以高速度进行写操作又为了让读和写的速度产生差异,我们定义了一个周期计数信号cycle_count(其周期计数的值为.01
12、010101.),它用来控制生成读写使能信号,控制方式为:当fast_write=1时,只要FIFO 非满就使写入,得到写使能信号;在非空的情况下,当cycle_count1时才产生读使能信号; 当fast_read=1时,只要FIFO非空就使读取,得到读使能信号;在非满的情况下,当cycle_count1时才产生写使能信号;从而达到了让快的一方速度是慢的一方速度2倍的效果。在解决了以上核心问题之后,具体的测试代码如下:/DEFINESdefine DEL 1 /时钟到输出的延时module test_sfifo(clock,reset_n,in_data,read_n,write_n,out
13、_data,full,empty);/INPUTSinput 7:0out_data;input empty,full;/OUTPUTSoutput clock,reset_n,read_n,write_n;output 7:0in_data;/信号声明,这些信号应与测试模块中的端口信号一一对应reg clock;reg reset_n;reg7:0in_data;/输入到端口in_data的激励信号regread_n;regwrite_n;wire7:0out_data;/从端口out_data输出的信号wirefull;wireempty;/定义需要的一些信号integerfifo_cou
14、nt;/记录FIFO中的字节数,定义为实型整数reg7:0 exp_data;/期望从FIFO输出的数据reg fast_read; /标志以高速度进行读操作reg fast_write; /标志以高速度进行写操作reg filled_flag; /标志FIFO已填满regcycle_count;/周期计数,用来生成读写控制信号/对FIFO进行实例化sfifo Sfifo(.clock(clock),.reset_n(reset_n),.in_data(in_data),.read_n(read_n),.write_n(write_n),.out_data(out_data),.full(fu
15、ll),.empty(empty);initial begin in_data=0; exp_data=0; fifo_count=0; read_n=1; write_n=1; filled_flag=0; cycle_count=0; clock=1; /写速度大于读速度fast_write=1;fast_read=0;/复位reset_n=1;#20 reset_n=0;#20 reset_n=1;/初始情况下,FIFO应该为空,即empty=1且full=0if(empty!=1)begin$display("nERROR at time %0t:",$time);
16、$display("After reset,empty status not assertedn");/报错$stop;endif(full!=0)begin$display("nERROR at time %0t:",$time);$display("After reset,empty status not assertedn");$stop;endend /生成时钟信号always #100 clock<=clock;/对FIFO中的字节数进行计数。每次写操作时,计数加1;读操作时计数减1always(posedge clo
17、ck)beginif(write_n&&read_n) /写但不读fifo_count<= fifo_count + 1;else if(read_n && write_n) /读但不写fifo_count<= fifo_count - 1;end/检查输出数据是否是期望的数据。如果不是,则报错always(negedge clock) /读写控制信号和输入信号在下降沿产生,而采样在上升沿完成,如此可防止锁错数据beginif(read_n && (out_data != exp_data)begin$display("nE
18、RROR at time %0t:",$time); /$time为当前仿真时间$display(" Expected data out = %h",exp_data);$display(" Actual data out = %hn",out_data);$stop; endif(fast_write | (cycle_count & 1'b1) && full)begin/只要非满就使写入,得到写控制信号write_n <= 0;/生成输入数据in_data <= in_data + 1;ende
19、lsewrite_n <= 1;/得到读控制信号,并给出期望的数据if(fast_read | (cycle_count & 1'b1) && empty)begin/在非空的情况下,当cycle=1时才产生读控制信号read_n <= 0;exp_data <= exp_data + 1;/由于写入数据为递增加1的,所以exp_data同意也是递增加1的endelseread_n <= 1;if(full)begin/如果fifo已满,则使读速度大于写速度fast_read <= 1;fast_write <= 0;/设置写
20、满标志filled_flag <= 1;endif(filled_flag && empty)/如果已清空fifo,则结束begin$display("nSimulation complete - no errors");$finish;/仿真结束end/对计算周期进行计数cycle_count <= cycle_count + 1;/由于默认cycle_count为1位变量,所以cycle的值实质为'010101end/check all of the status signals with each change of fifo_co
21、untalways(fifo_count)begin/wait a moment to evaluate everything#DEL;#DEL;#DEL;case(fifo_count)0:beginif(empty != 1) | (full != 0)begin$display("nERROR at time %0t:",$time);$display(" fifo_count = %h",fifo_count);$display(" empty = %b",empty);$display(" full = %bn&q
22、uot;,full);/Use $stop for debugging$stop;endif(filled_flag = 1)begin/the fifo has filled and emptied$display("nSimulation complete - no errorsn");$finish;endend16:beginif(empty != 0) | (full != 1)begin$display("nERROR at time %0t:",$time);$display("fifo_count = %h",fifo
23、_count);$display("empty = %b",empty);$display("full = %bn",full);/Use $stop for debugging$stop;end/如果fifo写满,则给出写满标志,此时,读速度大于写速度filled_flag <= 1;fast_write <= 0;fast_read <= 1;enddefault:beginif(empty != 0) | (full != 0)begin$display("nERROR at time %0t:",$time)
24、;$display("fifo_count = %h",fifo_count);$display("empty = %b",empty);$display("full = %bn",full);/Use $stop for debugging$stop;endendendcaseendendmodule.4 仿真4.1波形仿真(仿真过程使用ModlSim SE 6.0进行)波形图中端口信号说明:empty:FIFO状态信号,当empty=1时,表明该FIFO存储器已经读空;full:FIFO状态信号,当full=1时,表明该FIFO存
25、储器已经写满;clock: 时钟信号, 在时钟的正边沿进行采样;reset_n: 复位信号,当reset_n=0时,计数器及读写都被清零(即:读写地址指针都指向0)read_n: 读使能端,当read_n=0时,可以读出数据;write_n: 写使能端,当write_n=0时,可以写入数据;in_data: 输入数据端口,位宽为8位;out_data: 输出数据端口,位宽为8位;fifo_count:记录FIFO中的字节数,定义为实型整数exp_data:期望从FIFO输出的数据fast_read:标志以高速度进行读操作fast_write:标志以高速度进行写操作filled_flag:标志F
26、IFO已填满cycle_count:周期计数,用来生成读写控制信号图1 写快于读直至写满的波形图图2 读快于写由满直至读空的波形图图3 仿真全过程波形图4.2 时序,逻辑分析图1 写快于读直至写满的波形图的分析:仿真开始时,由于fast_write1,fast_read=0,所以:只要FIFO 非满就使写入,得到写使能信号/在非空的情况下,当cycle_count1时才产生读使能信号.所以写速度是读速度的2倍(即写入2个数据,只读取一个数据),当FIFO写满后,这时full1,填满信号filled_flag由0变为了1.图2 读快于写由满直至读空的波形图的分析:由于FIFO在图1中所示过程已填
27、满,所以接着必须使读速度大于写速度,即fast_read=1,fast_write=0,此时:只要FIFO非空就使读取,得到读使能信号/在非满的情况下,当cycle_count1时才产生写使能信号.所以读速度是写速度的2倍(即读取2个数据,只写入一个数据),在此过程中full0,filled_flag保持为1,最终FIFO排空时,empty1.图3 仿真全过程波形图分析:由仿真全过程的波形图来看:在reset_n=0后,计数器及读写地址指针都被清0,说明达到了异步复位的要求;由read_n及write_n值的变化与读写数据的波形来看,read_n及write_n起到了读写使能控制的作用;由波形
28、可知读写操作都是在时钟clock的上升沿完成,说明FIFO是同步的;对比full与empty的值与FIFO的满空状况来看,full与empty能正确反映FIFO的实际状态。由上述分析可以验证:本次设计的器件能满足同步FIFO的逻辑功能。.5 综合(综合过程使用LeonardoSpectrum 2000.1b进行)(考虑到使用不同的器件库,综合出来的电路图不同,说明一下:以下综合使用的器件库为MAX3000A)5.1顶层综合电路示意图图1图2注:顶层综合电路图由图1与图2两部分构成,其由三个端口相连,它们依次是:Not_write_n , Not_reset_n , Not_read_n5.2门
29、级综合电路示意图图1注:此为顶层图中读写地址指针产生模块注:此为顶层图中的ram存储器部分的门级图5.3输入输出描述输入:in_data: 输入数据端口,位宽为8位;read_n: 读使能端,当read_n=0时,可以读出数据;write_n: 写使能端,当write_n=0时,可以写入数据;clock: 时钟信号, 在时钟的正边沿进行采样;reset_n: 复位信号,当reset_n=0时,计数器及读写都被清零(即:读写地址指针都指向0)输出:out_data: 输出数据端口,位宽为8位;;full:FIFO状态信号,当full=1时,表明该FIFO存储器已经写满;empty:FIFO状态信
30、号,当empty=1时,表明该FIFO存储器已经读空;6 心得体会与建议(小组成员:刘鑫)通过这次课程设计,确实学到了不少东西!不光是知识上的长进,其他方面也得到了提高! 上完第一节介绍课,在BBS上看了学长的建议说是要选一个模拟的题就比较有挑战性,可以学不少东西。就有一点想挑个模电的题,不过后来还是抽中了数电的题。后来跟同学们一样都被认为抽到数电是很幸运的!因为确实不是一件简单的事情! 我们组的课题是“FIFO同步缓冲器的设计”,过了一个暑假都不记得缓冲器是什么了,于是又拉出厚厚的数电的书开始翻,看到了寄存器,移位寄存器,计数器这些东西,觉得有点熟悉了,但是到具体的这个16*8的缓存器是个什
31、么概念,我们的意见还是有点分歧,于是去网上找这些概念,弄明白这意思。就看到有的说同步就是同一个时钟脉冲,有的又说同步不是这个概念,后来我们就一起商讨了一下,统一了题目的意思:同步FIFO(即输出输入端时钟频率一致),异步复位,其存储能力为(16x8),输出两个状态信号:full与empty,以供后继电路使用。 弄清了题目的意思之后,就开始按照设计的程序来完成各部分的内容。首先我们在网上找到了一些关于IC课程设计的流程介绍,我们也就使根据那些介绍的流程来一步步完成我们的任务。在查资料的同时才发现,因特网真的可以帮我们不少的忙,其实我们平时的好多资料都可以借助网络来查询,所以这次还下载了不少这方面的知识以备后用。 我们设计的这个缓冲器是以寄存
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年上海市建筑施工企业三类人员考试题库及答案
- 泰安语文考试题及答案
- 小学教师反思与课程目标实现的关系试题及答案
- 2025年度农村信用社招聘考试基础知识试题150道及答案
- 会计笔试面试题目及答案
- 美国智力测试题及答案
- 电池管理系统创新技术对新能源车的影响试题及答案
- 新能源汽车行业发展的外部环境考量试题及答案
- 小学教师教育教学反思与技巧试题及答案
- 新能源汽车的能效标准评估试题及答案
- 3D打印技术与应用智慧树知到期末考试答案2024年
- 相关方需求和期望识别评价表
- 西南科技大学井巷工程课程设计样本
- 《养老护理员职业培训》课程标准
- 船舶修造业通用安全知识讲义课件
- 新生儿死亡讨论模板课件
- 曼娜小说全文的回忆
- 《精益生产培训》课件
- 快递客户服务与营销快递客户维护
- 《中国的生物灾害》课件
- 《吸烟的危害性》课件
评论
0/150
提交评论