Verilog数字系统设计教程[第4版]夏宇闻——第三部分练习十二
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版]夏宇闻——第三部分练习十二相关推荐
- Verilog数字系统设计教程[第4版]夏宇闻——第三部分练习十
Verilog数字系统设计教程[第4版]夏宇闻--第三部分练习十 测试仿真流程 模块源代码 测试模块代码 结果波形 测试仿真流程 测试仿真环境为win系统下的quartus prime + model ...
- Verilog数字系统设计教程[第4版]夏宇闻——第三部分练习四
Verilog数字系统设计教程[第4版]夏宇闻--第三部分练习四 测试仿真流程 模块源代码 测试模块代码 结果波形 测试仿真流程 测试仿真环境为win系统下的modelsim 模块源代码 //---- ...
- 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 ...
- verilog学习|《Verilog数字系统设计教程》夏宇闻 第三版思考题答案(第三章)
<Verilog数字系统设计教程>夏宇闻 第三版思考题 答案合集 : Verilog学习系列 第三部分 1.模块由几个部分组成? 由描述接口和描述逻辑功能两部分组成. 2.端口分为几种 ...
- verilog学习|《Verilog数字系统设计教程》夏宇闻 第三版思考题答案(第五章)
<Verilog数字系统设计教程>夏宇闻 第三版思考题 答案合集 :个人主页verilog专栏中 1.为什么建议在编写Verilog模块程序时,如果用到 if 语句建议大家把配套的else ...
- verilog学习|《Verilog数字系统设计教程》夏宇闻 第三版思考题答案(第十四章)
<Verilog数字系统设计教程>夏宇闻 第三版思考题 答案合集 : Verilog学习系列 第三部分 1.用带电平敏感列表触发条件的always 块表示组合逻辑时,应该用哪一种赋值? ...
- [转]Verilog数字系统设计教程(大连理工一博士学习笔记)
写在前面 学习Verilog HDL有一些时间,大概一年前的的这个时候开始的吧,从一点都不懂开始学,主要还是看夏宇闻老师的这本书入的门--<Verilog数字系统设计教程>,书写的特别好. ...
- Verilog数字系统设计教程(第四版)夏闻宇课后习题-绪论
1.什么是信号处理电路?它通常由哪两大部分组成? 信号处理电路是进行一些复杂的数字运算和数据处理,并且又有实时响应要求的电路.它通常由高速数据通道接口和高速算法电路两大部分组成. 2.为什么要设计专用 ...
- 《Verilog数字系统设计教程》夏宇闻 第四版思考题答案(第3章)
1.模块由几个部分组成? 由描述接口和描述逻辑功能两部分组成. 2.端口分为几种? 三种:输出口,输入口,输入/输出口. 3.为什么端口要说明信号的位宽? 因为如果不说明信号的位宽可能会在信号发生改变 ...
最新文章
- python文本编码转换_Python: 转换文本编码
- JAVA EE Eclipse下配置Tomcat服务器
- 内核功能导致重启_诊断修复 TiDB Operator 在 K8s 测试中遇到的 Linux 内核问题
- PostgreSQL在何处处理 sql查询之五十一
- .NET Core容器化@Docker
- linux 串口 qt,Linux-QT4.7 实现串口通信
- oracle v¥bh,【oracle笔记2】约束
- 面试基操:MQ怎么保障消息可靠性?
- jquery 获取checkbox 或 select 的选中值(一组和单个)
- 【kafka】kafka 建立很多很多消费组 会怎么样
- EasyRecovery数据恢复(U盘)
- Spring Cloud之Swagger集群搭建
- python的迭代器_python迭代器详解
- 安装 VS 2015 报错 kb2999226
- 学校邮箱的pop服务器地,常用邮箱的POP与SMTP服务器
- Python使用wordcloud做词云
- idea中整合redis中出现 Error creating bean with name ‘com.sxt.redis.RedisApplicationTests‘:
- windows CMD命令大全及详细解释和语法
- PC后台管理( 基于图形化界面自动安装教程)
- Unity Navigation