原创 第2讲 case语句及task任务块

2016-2-6 14:13 3176 30 30 分类: FPGA/CPLD

第二讲 case语句及task任务块

实验任务:

1)用case语句实现具有译码功能的模块(类似于3-8译码器);

2)学会在testbench中使用task任务块语句,用它产生测试数据给待测模块;

3)注意case语句的写法,思考:若case分支列举不全面,会出现什么不良后果?

实验内容及过程:

因本次实验简单,故直接贴出代码并予以简单的讲解,代码截图如下图所示:

20160130022736129001.png

20160130022745926002.png

20160130022751561003.png

注意事项:

在用Verilog语言设计数字电路的时候,出现多余无用的锁存器对电路危害大,应格外小心,消除锁存器的办法:①always中的敏感信号列表要写全(要包含case条件、赋值符号右边的变量);②所有条件分支要写全(包括default);③if—else语句要写全,不要只写if不写else,没有else的时候也要写一条空的else语句。

以下两个图展示了case条件分支写全与不全时综合后的结果:

20160130022757314004.png

1 case条件分支不全时综合的RTL视图

1为漏写了

3'd7:begin

       o_data = 8'b0111_1111;

       o_dv = 1'b1;

end

这条分支时综合后的结果,从图1可看出,在电路的输出端出现了8latch,且它们都与MUX7的输出端相连。由此可见,是因为漏写了上面的那段语句。

在利用Quartus II综合设计的实例时,也会出现一些相关的警告,如图2所示:

20160130022805750005.png

2 Quartus II综合时产生的警告

正确的RTL视图应该如图3所示:

20160130022812479006.png

3 正确的RTL级视图(无latch

 

testbench中使用task任务块依次产生0~255之间的数,并分别将这些数值赋值给i_datai_addr,代码截图如下图所示:

20160130022818522007.png

关于写task任务块,有很多语法约束,这里一一列举出来:

1task没有端口列表,但可以有输入变量列表,并且变量须在task内部予以声明(如上图中的size);

2)输入输出端口可在task内部尽心声明,支持inputoutput以及inout三种端口信号;

3)可以用integerreg声明task要用到的变量,但不能用wire声明;

4task任务块也属于块语句,但与module—endmodule的架构类似,可仿照module—endmodule的架构task任务块,但是,taskalwaysinitial属于同一层次,故task的内容要写在always块和initial块之外,但可在always块、initial块以及task任务块中调用task任务块(即:任务中可以再调用其他任务);

5)调用任务时,需按照端口声明的顺序调用(跟模块实例化中的“按顺序”实例化的操作是类似的);

6)任务不能实时输出,而是只能在整个任务结束时得到一个最终的结果,输出的值也是这个最终的结果的值,例如:

task seq;

output   q;

 

begin

q = 0;

#10  q = 1;

end

 

endtask

上述代码仿真的结果是,调用此任务之后只会得到一个延迟10个时间单位的输出数据1,前10ns输出数据的状态是未知的,如图4所示:

20160130022823212008.png

4 task不能实时输出的仿真图

6)在仿真过程中如果出现多次调用同一个任务,且每次操作的值不同时,就可能出现由于地址空间相互覆盖而导致的结果错误。针对这一问题,通常使用自动任务解决此问题。

最后,贴出本例的仿真波形图,如图5所示:

20160130022830355009.png

5 译码器和task任务块的功能仿真图

 

文章评论0条评论)

登录后参与讨论
我要评论
0
30
关闭 站长推荐上一条 /2 下一条