全球最实用的IT互联网信息网站!

AI人工智能P2P分享&下载搜索网页发布信息网站地图

当前位置:诺佳网 > 电子/半导体 > 可编程逻辑 >

FPGA学习系列:仿真测试文件的编写

时间:2018-05-31 11:40

人气:

作者:admin

标签:

导读:之前有一篇文章介绍过仿真测试文件编写的步骤: 1.给A模块写测试,其测试模块的模块名为A_tb,比如原模块模块名叫做led,测试模块名就叫 led_tb; 2.复制A模块的所有输入输出端口,也就...

之前有一篇文章介绍过仿真测试文件编写的步骤:

1.给A模块写测试,其测试模块的模块名为A_tb,比如原模块模块名叫做led,测试模块名就叫 led_tb;
2.复制A模块的所有输入输出端口,也就是I/O声明部分(input和output信号),注意这里不包括中间变量(reg型和wire型信号);将所有的input 改为 reg, output 改为 wire;
3.再把A模块的端口定义部分复制过来,包括 模块名到分号结束,进行模块例化;
4.测试模块的意义就是模拟输入信号,来验证原模块的输出信号是否符合代码逻辑,所以在测试模块里面需要写一个initial块模拟所有的输入变量,进行赋值操作;
5.如果有时钟,需要再产生一个时钟信号;
6.最后添加时间标识。

这篇文章就详细说一下怎么做,举得例子是上一篇二选一数据选择器的例子,大家可以动手做一做。

设计背景:

测试文件在我们的项目中格外的重要,比如我们要验证你的模块的正确性难道要不停的下板来验证吗,如果你的项目小还可以,如果编译一下超过10分钟了你难道不停的等待,修改中循坏下去吗,所以如果我们可以设计出我们的测试文件,那么先验证我们的系统,如果我们的逻辑都正确了,我们就可以下班来查看,如果还不正确那么我们就可以用quartus 中的工具signaltap来捕捉我们信号来验证,这些都会在我们以后的文档中给大家说明。

设计原理:

我们的设计就是一个简单的2选一多路选择器,我们通过给这个简单的多路选择器来写测试文件,让大家对测试有一个简单的认识。

在架构中我们可以明白的看出我们设计的架构,我们的项目中有2个输入数据data_1,data_2,一个输入的选择位select,还有一个输出data_out。其实给这个架构写测试也就是激励,其实说白了就是给其写输入,当给其写好输入后,我们不就可以在仿真工具中验证其逻辑关系了。

设计架构图:

sel_1架构

image.png

总架构

image.png

设计代码:

我们写好的代码如下,大家看下,然后我们给大家讲解测试怎么写

模块

0modulesel_1(data_1,data_2,select,data_out);

1

2 inputdata_1,data_2; //数据输入

3 inputselect; //选择位

4

5 outputregdata_out; //数据的输出

6

7 always@(*)

8 begin

9 if(select) //如果选择位为高,输出data_1

10 data_out =data_1;

11 else //如果选择位为低,输出data_2

12 data_out =data_2;

13 end

14

15endmodule

测试模块

测试的简单写法,测试中模块的输入定义为寄存器reg型,输出定义为wire型,然后加上我们的块 initial ,再加上我们的例化,如下:

0`timescale1ns/1ps

1

2module块名;

3

4 reg块输入;

5 wire块输出;

6

7 initialbegin

8

9

10

11

12 end

13

14 块名 例化名(

15 .端口(端口),

16 .端口(端口),

17

18 );

19

20endmodule

在测试中我们也有许多的系统比如我们的系统任务$stop等,这些都属于语法知识了,大家可以买一本适合的书来看看,我们为我们的设计写好的激励如下:

0`timescale1ns/1ps //这一行中1ns定义我们测试时的时间单位,后面的ps 是精度

1//前面的timescale英文也就是时间量程的意思

2

3modulesel_1_tb;//module 后面跟上我们测试名字,一般我们都写成模块名

4//加上_tb,如果我们对一个项目的多个模块写测试我们就能清楚的分清

5

6 regdata_1,data_2; //定义模块的输入输出

7 regselect; //模块中的输入定义为寄存器

8

9 wiredata_out; //输出定义为wire型也就是线型

10

11 initialbegin //initial 是一个串型执行的,在测试中被综合,

12 //如果你写到模块中,可是会报错的

13 data_1 =0; //然后我们就可以定义我们的端口,给我们的端口赋初值

14 data_2 =0;

15 select =0;

16

17 #200data_1 =1;data_2 =0;//延迟200ns给输入赋值

18 #100select =1; //延迟200ns后给选择位赋值

19 #100select =0; //延迟200ns后给选择位赋值

20

21 #200data_1 =0;data_2 =1;

22 #100select =0;

23 #100select =1;

24

25 #300$stop; //$stop 系统任务,也就是停止的意思,这句 就是延迟 300ns后,仿真停止

26 end

27

28 sel_1 sel_1_dut( //模块的例化,和端口的连接

29 .data_1(data_1),

30 .data_2(data_2),

31 .select(select),

32 .data_out(data_out)

33 );

34

35endmodule

在测试中如果我们用到时钟了怎么办,我们可以这样写,如下

0`timescale1ns/1ps

1

2module块名;

3

4 reg块输入;

5 wire块输出;

6 regclk,rst_n;

7

8 initialbegin

9 clk =1;

10 rst_n =0;

11

12 #200.1rst_n =1;

13

14 end

15

16 always#10clk =~clk; //always 一直,这样可以写成一个 50M的时钟

17 //说的是延迟10ns翻转一次,也就是一 个周期20ns

18

19 块名 例化名(

20 .端口(端口),

21 .端口(端口),

22

23 );

24

25endmodule

仿真图:

image.png

在仿真中我们可以真实的看到,当数据data_1为1,data_2位0的时候,当选择位select为0的时候,输出data_out的值为0也就是data_2的值,当select为1的时候,data_out的值位1,也就是data_1的值,后面的仿真也一样我们可以清楚的看到。

以上就是对于二选一数据选择器的仿真测试文件的编写细节,大家可以动手去做一做,加油,各位。

温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信