Verilog数字系统设计教程[第4版]夏宇闻——第三部分练习十二

  • 测试仿真流程
  • 模块源代码
  • 测试模块代码

测试仿真流程

测试仿真环境为win系统下的quartus prime + modelsim
测试仿真流程参照我之前的教程
Verilog数字系统设计教程第4版夏宇闻——第三部分练习一

模块源代码

//----------fifo_interface.v----------
`define SRAM_SIZE 8                                //为减小对FIFO控制器的测试工作量,置SRAM空间为8字节
`timescale 1ns/1nsmodule fifo_interface(in_data,                               //用户的输入数据总线out_data,                            //用户的输出数据总线fiford,                              //FIFO读控制信号,低电平有效fifowr,                             //FIFO写控制信号,低电平有效nfull,nempty,address,                               //到SRAM的地址总线sram_data,                          //到SRAM的双向数据总线rd,                                   //SRAM读使能,低电平有效wr,                                   //SRAM写使能,低电平有效clk,                                  //系统时钟信号rst);                                   //全局复位信号,低电平有效//来自用户的控制输入信号
input fiford,fifowr,clk,rst;//来自用户的数据信号
input[7:0] in_data;
output[7:0] out_data;
reg[7:0] in_data_buf,                           //输入数据缓冲区out_data_buf;                          //输出数据缓冲区//输出到用户的状态指示信号
output nfull,nempty;
reg nfull,nempty;//输出到SRAM的控制信号
output rd,wr;//到SRAM的双向数据总线
inout[7:0] sram_data;//输出到SRAM的地址总线
output[10:0] address;
reg[10:0] address;//Internal Register
reg[10:0] fifo_wp,                              //FIFO写指针fifo_rp;                               //FIFO读指针reg[10:0] fifo_wp_next,                            //fifo_wp的下一个值fifo_rp_next;                         //fifo_rp的下一个值reg near_full,near_empty;
reg[3:0] state;                                 //SRAM操作状态机寄存器parameter idle='b0000,read_ready='b0100,read='b0101,read_over='b0111,write_ready='b1000,write='b1001,write_over='b1011;//SRAM操作状态机
always@(posedge clk or negedge rst)if(~rst)state<=idle;elsecase(state)idle:                                        //等待FIFO的操作控制信号if(fifowr==0&&nfull)               //用户发出写FIFO申请,且FIFO未满state<=write_ready;else if(fiford==0&&nempty)     //用户发出读FIFO申请,且FIFO未空state<=read_ready;else                                  //没有对FIFO操作的申请state<=idle;read_ready:                               //建立SRAM操作所需地址和数据state<=read;read:                                      //等待用户结束当前读操作if(fiford==1)state<=read_over;elsestate<=read;read_over:                             //继续给出SRAM地址以保证数据稳定state<=idle;write_ready:                         //建立SRAM操作所需地址和数据state<=write;write:                                    //等待用户结束当前写操作if(fifowr==1)state<=write_over;elsestate<=write;write_over:                              //继续给出SRAM地址和写入数据以保证数据稳定state<=idle;default: state<=idle;endcase//产生SRAM操作相关信号
assign rd = ~state[2];
assign wr = (state==write)?fifowr:1'b1;always@(posedge clk)if(~fifowr)in_data_buf<=in_data;assign sram_data=(state[3])?in_data_buf:8'hzz;always@(state or fiford or fifowr or fifo_wp or fifo_rp)if(state[2]||~fiford)address=fifo_rp;else if(state[3]||~fifowr)address=fifo_wp;elseaddress='bz;//产生FIFO数据
assign out_data = (state[2])?sram_data:8'bz;always@(posedge clk)if(state==read)out_data_buf<=sram_data;//计算FIFO读写指针
always@(posedge clk or negedge rst)if(~rst)fifo_rp<=0;else if(state==read_over)fifo_rp<=fifo_rp_next;always@(fifo_rp)if(fifo_rp==`SRAM_SIZE-1)fifo_rp_next=0;elsefifo_rp_next=fifo_rp+1;always@(posedge clk or negedge rst)if(~rst)fifo_wp<=0;else if(state==write_over)fifo_wp<=fifo_wp_next;always@(fifo_wp)if(fifo_wp==`SRAM_SIZE-1)fifo_wp_next=0;elsefifo_wp_next=fifo_wp+1;always@(posedge clk or negedge rst)if(~rst)near_empty<=1'b0;else if(fifo_wp==fifo_rp_next)near_empty<=1'b1;elsenear_empty<=1'b0;always@(posedge clk or negedge rst)if(~rst)nempty<=1'b0;else if(near_empty&&state==read)nempty<=1'b0;else if(state==write)nempty<=1'b1;always@(posedge clk or negedge rst)if(~rst)near_full<=1'b0;else if(fifo_rp==fifo_wp_next)near_full<=1'b1;elsenear_full<=1'b0;always@(posedge clk or negedge rst)if(~rst)nfull<=1'b1;else if(near_full&&state==write)nfull<=1'b0;else if(state==read)nfull<=1'b1;endmodule//----------sram.v----------
module sram(Address,Data,SRG,SRE,SRW);
input[10:0] Address;
input SRG,                              //Output enableSRE,                             //Chip enableSRW;                               //Write enable
inout[7:0] Data;                        //Buswire[10:0] Addr=Address;
reg[7:0] RdData;
reg[7:0] SramMem[0:'h7ff];
reg RdSramDly,RdFlip;
wire[7:0] FlpData,Data;
reg WR_flag;                            //To judge the signals according to the specification of HM-65162
integer i;
wire RdSram=~SRG&~SRE;
wire WrSram=~SRW&~SRE;
reg[10:0] DelayAddr;
reg[7:0] DelayData;
reg WrSramDly;
integer file;assign FlpData = (RdFlip)?~RdData:RdData;
assign Data = (RdSramDly)?FlpData:'hz;parameter TAVQV=90,                    //2 (max)       Address access timeTELQV=90,                   //3 (max)       Chip enable access timeTELQX=5,                    //4 (min)       Chip enable output enable timeTGLQV=65,                    //5 (max)       Output enable access timeTGLQX=5,                  //6 (min)       Output enable output enable timeTEHQZ=50,                  //7 (max)       Chip enable output disable timeTGHQZ=40,                   //8 (max)       Output enable output disable timeTAVQX=5;                  //9 (min)       Output hold from address changeparameter TAVWL=10,                 //12    (min)       Address setup timeTWLWH=55,                    //13    (min)       Chip enable pulse setup timeTWHAX=15,                  //14    (min10) Write enable read setup timeTWLQZ=50,                  //16    (max)       Write enable output disable timeTDVWH=30,                  //17    (min)       Data setup timeTWHDX=20,                   //18    (min15) Data hold timeTWHQX=20,                    //19    (min0)  Write enable output enable timeTWLEH=55,                   //20    (min)       Write enable pulse setup timeTDVEH=30,                 //21    (min)       Chip enable data setup timeTAVWH=70,                   //22    (min65) Address valid to end of writeinitialbeginfile=$fopen("ramlow.txt");if(!file)begin$display("Could not open the file.");$stop;endendinitialbeginfor(i=0;i<'h7ff;i=i+1)SramMem[i]=i;$monitor($time,"DelayAddr=%h,DelayData=%h",DelayAddr,DelayData);endinitial RdSramDly=0;
initial WR_flag=1;always@(posedge RdSram) #TGLQX RdSramDly=RdSram;
always@(posedge SRW)       #TWHQX RdSramDly=RdSram;always@(Addr)begin#TAVQX;RdFlip=1;#(TGLQV-TAVQX)if(RdSram)RdFlip=0;endalways@(posedge RdSram)beginRdFlip=1;#TAVQV;if(RdSram)RdFlip=0;endalways@(Addr)               #TAVQX RdFlip=1;
always@(posedge SRG)       #TEHQZ RdSramDly=RdSram;
always@(posedge SRE)       #TGHQZ RdSramDly=RdSram;
always@(negedge SRW)       #TWLQZ RdSramDly=0;always@(negedge WrSramDly or posedge RdSramDly) RdData=SramMem[Addr];always@(Addr)               #TAVWL DelayAddr=Addr;
always@(Data)              #TDVWH DelayData=Data;
always@(WrSram)            #5   WrSramDly=WrSram;
always@(Addr or Data or WrSam) WR_flag=1;always@(negedge SRW)begin#TWLWH;if(SRW)beginWR_flag=0;$display("ERROR!Can't write!Write enable time(W) is too short!");endendalways@(posedge SRW)begin#TWHAX;if(DelayAddr!==Addr)beginWR_flag=0;$display("ERROR!Can't write!Write enable read setup time is too short!");endendalways@(Data)if(WrSram)begin#TDVEH;if(SRE)beginWR_flag=0;$display("ERROR!Can't write!Chip enable data setup time is too short!");endendalways@(Data)if(WrSram)begin#TDVEH;if(SRW)beginWR_flag=0;$display("ERROR!Can't write!Chip enable data setup time is too short!");endendalways@(posedge SRW)begin#TWHDXif(DelayData!==Data)$display("Warning!Data hold time is too short!");endalways@(DelayAddr or DelayData or WrSramDly)if(WrSram&&WR_flag)beginif(!Addr[5])begin#15 SramMem[Addr]=Data;$display("mem[%h]=%h",Addr,Data);$fwrite(file,"mem[%h]=%h",Addr,Data);if(Addr[0]&&Addr[1])$fwrite(file,"\n");endelsebegin$fclose(file);$display("Please check the txt.");$stop;endendendmodule

测试模块代码

//----------fifo_interface.vt----------
`define FIFO_SIZE 8
`timescale 1 ns/ 1 nsmodule fifo_interface_vlg_tst();
reg[7:0] in_data;
reg fiford,fifowr;
wire[7:0] out_data;
wire nfull,nempty;
reg clk,rst;
wire[7:0] sram_data;
wire[10:0] address;
wire rd,wr;
reg[7:0] data_buf[`FIFO_SIZE:0];
integer index;//系统时钟
initial clk=0;
always #25 clk=~clk;//测试激励序列
initialbeginfiford=1;fifowr=1;rst=1;#40 rst=0;#42 rst=1;if(nempty)$display($time,"Error:FIFO be empty, nempty should be low.\n");index=0;repeat(`FIFO_SIZE)begindata_buf[index]=$random;write_fifo(data_buf[index]);index=index+1;endif(nfull)$display($time,"Error:FIFO full, nfull should be low.\n");repeat(2) write_fifo($random);#200index=0;read_fifo_compare(data_buf[index]);if(~nfull)$display($time,"Error:FIFO not full, nfull should be high.\n");repeat(`FIFO_SIZE-1)beginindex=index+1;read_fifo_compare(data_buf[index]);endif(nempty)$display($time,"Error:FIFO be empty, nempty should be low.\n");repeat(2) read_fifo_compare(8'bx);reset_fifo;repeat(`FIFO_SIZE*2)begindata_buf[0]=$random;write_fifo(data_buf[0]);read_fifo_compare(data_buf[0]);endreset_fifo;read_fifo_compare(8'bx);write_fifo(data_buf[0]);read_fifo_compare(data_buf[0]);$stop;endfifo_interface i1 ( .address(address),.clk(clk),.fiford(fiford),.fifowr(fifowr),.in_data(in_data),.nempty(nempty),.nfull(nfull),.out_data(out_data),.rd(rd),.rst(rst),.sram_data(sram_data),.wr(wr)
);sram m1(.Address(address),.Data(sram_data),.SRG(rd),.SRE(1'b0),.SRW(wr));task write_fifo;
input[7:0] data;
beginin_data=data;#50 fifowr=0;#200 fifowr=1;#50;
end
endtasktask read_fifo_compare;
input[7:0] data;
begin#50 fiford=0;#200 fiford=1;if(out_data!=data)$display($time,"Error:Data retrieved(%h)not match the one stored(%h).\n",out_data,data);#50;
end
endtasktask reset_fifo;
begin#40 rst=0;#40 rst=1;
end
endtaskendmodule

Verilog数字系统设计教程[第4版]夏宇闻——第三部分练习十二相关推荐

  1. Verilog数字系统设计教程[第4版]夏宇闻——第三部分练习十

    Verilog数字系统设计教程[第4版]夏宇闻--第三部分练习十 测试仿真流程 模块源代码 测试模块代码 结果波形 测试仿真流程 测试仿真环境为win系统下的quartus prime + model ...

  2. Verilog数字系统设计教程[第4版]夏宇闻——第三部分练习四

    Verilog数字系统设计教程[第4版]夏宇闻--第三部分练习四 测试仿真流程 模块源代码 测试模块代码 结果波形 测试仿真流程 测试仿真环境为win系统下的modelsim 模块源代码 //---- ...

  3. Verilog数字系统设计教程[第4版]夏宇闻——第17章RISC_CPU代码

    Verilog数字系统设计教程[第4版]夏宇闻--第17章EEPROM代码 clk_gen.v accum.v adr.v alu.v counter.v register.v datactl.v m ...

  4. verilog学习|《Verilog数字系统设计教程》夏宇闻 第三版思考题答案(第三章)

    <Verilog数字系统设计教程>夏宇闻 第三版思考题 答案合集 : Verilog学习系列 第三部分 1.模块由几个部分组成?   由描述接口和描述逻辑功能两部分组成. 2.端口分为几种 ...

  5. verilog学习|《Verilog数字系统设计教程》夏宇闻 第三版思考题答案(第五章)

    <Verilog数字系统设计教程>夏宇闻 第三版思考题 答案合集 :个人主页verilog专栏中 1.为什么建议在编写Verilog模块程序时,如果用到 if 语句建议大家把配套的else ...

  6. verilog学习|《Verilog数字系统设计教程》夏宇闻 第三版思考题答案(第十四章)

    <Verilog数字系统设计教程>夏宇闻 第三版思考题 答案合集 : Verilog学习系列 第三部分 1.用带电平敏感列表触发条件的always 块表示组合逻辑时,应该用哪一种赋值?   ...

  7. [转]Verilog数字系统设计教程(大连理工一博士学习笔记)

    写在前面 学习Verilog HDL有一些时间,大概一年前的的这个时候开始的吧,从一点都不懂开始学,主要还是看夏宇闻老师的这本书入的门--<Verilog数字系统设计教程>,书写的特别好. ...

  8. Verilog数字系统设计教程(第四版)夏闻宇课后习题-绪论

    1.什么是信号处理电路?它通常由哪两大部分组成? 信号处理电路是进行一些复杂的数字运算和数据处理,并且又有实时响应要求的电路.它通常由高速数据通道接口和高速算法电路两大部分组成. 2.为什么要设计专用 ...

  9. 《Verilog数字系统设计教程》夏宇闻 第四版思考题答案(第3章)

    1.模块由几个部分组成? 由描述接口和描述逻辑功能两部分组成. 2.端口分为几种? 三种:输出口,输入口,输入/输出口. 3.为什么端口要说明信号的位宽? 因为如果不说明信号的位宽可能会在信号发生改变 ...

最新文章

  1. python文本编码转换_Python: 转换文本编码
  2. JAVA EE Eclipse下配置Tomcat服务器
  3. 内核功能导致重启_诊断修复 TiDB Operator 在 K8s 测试中遇到的 Linux 内核问题
  4. PostgreSQL在何处处理 sql查询之五十一
  5. .NET Core容器化@Docker
  6. linux 串口 qt,Linux-QT4.7 实现串口通信
  7. oracle v¥bh,【oracle笔记2】约束
  8. 面试基操:MQ怎么保障消息可靠性?
  9. jquery 获取checkbox 或 select 的选中值(一组和单个)
  10. 【kafka】kafka 建立很多很多消费组 会怎么样
  11. EasyRecovery数据恢复(U盘)
  12. Spring Cloud之Swagger集群搭建
  13. python的迭代器_python迭代器详解
  14. 安装 VS 2015 报错 kb2999226
  15. 学校邮箱的pop服务器地,常用邮箱的POP与SMTP服务器
  16. Python使用wordcloud做词云
  17. idea中整合redis中出现 Error creating bean with name ‘com.sxt.redis.RedisApplicationTests‘:
  18. windows CMD命令大全及详细解释和语法
  19. PC后台管理( 基于图形化界面自动安装教程)
  20. Unity Navigation

热门文章

  1. strtol全面解析
  2. 《白话机器学习的数学》正则化实现代码
  3. 开源中文词向量加载(训练好的词向量如何加载) tensorflow
  4. H5页面iphone(苹果)手机点击输入框输入内容时页面自动放大
  5. 618前夕看京东IT基础设施建设与无人机物流规划
  6. 我的k8s随笔:Kubernetes部署-问题篇
  7. ROS仿真机器人学习笔记一
  8. 【面试】面试时项目亮点怎样回答才满分?
  9. iframe跨域传递参数
  10. BP神经网络的手写体识别 Python3