Verilog HDL之于FPGA--阻塞与非阻塞赋值
2015-08-20 00:05
211 查看
Verilog HDL之于FPGA
阻塞与非阻塞赋值
Verilog HDL硬件描述语言:Verilog HDL硬件描述语言脱胎于C语言,却与C语言执行的方式不同。
Verilog 有并行和顺序执行两种方式,
而C语言程序只能从main函数进入,然后开始顺序执行。
并行执行:
Verilog HDL在模块与模块之间是并行执行。
module test(clk,a,b,c); input clk; output a,b,c; reg a=0,b=0; /*第一个模块*/ always @(posedge clk) begin a <= 1; end /*第二个模块*/ always @(posedge clk) begin b <= 1; end /*第三个模块*/ assign c = 1; endmodule
注:两个模块之间不能同时对一个寄存器进行操作,比如:
… always @(posedge clk) a <= 0; always @(posedge clk) a <= 1; ….
顺序执行:
Verilog HDL 在always块里面是顺序的;
但是这种顺序执行的结果也不一定跟C语言同样。
Verilog的阻塞与非阻塞问题,这是个难点。(笔者曾经在一段很长的时间内一直搞混,如果习惯用C语言的同学理解起来就会有一点点。。。那个,虽然笔者是先学verilog 后学C语言,但是开始时理解也很吃力。)
如果在块里面用“=”时也就是用阻塞赋值功能,这样代码执行就会以顺序执行方式执行,比如:
`timescale 1ns / 1ps module adder(clk,out); input clk; output [3:0]out; reg [3:0]out = 4'b0; always @(posedge clk) begin out = out + 1'b1; out = out + 1'b1; end endmodule
从图中可以看出,out的值一个周期后为2。
分析:
开始out = out + 1’b1; out 本身值加1然后赋给out本身,这时 out 的值已经变为1,
然后再一句 out = out + 1’b1;
也是同上面一样,out本身的值加1然后赋给out本身,
本来out的值变为1了,加上1就是2了,所以out的值在一个周期结束后更新为 2;
这跟C执行的是一样。
但是,如果我们用 “<=” 时也就是非阻塞赋值时情况就不同了,所有的值要等到一个时钟周期结束后值才会被改变。比如:
`timescale 1ns / 1ps module adder(clk,out); input clk; output [3:0]out; reg [3:0]out= 4’b0; always @(posedge clk) begin out <= out + 1’b1; out <= out + 1’b1; end endmodule
从图中可以看出,out的值一个周期后为1。
分析:
开始out <= out + 1’b1;
右边 out 本身值加1,右边值为1,
但这时右边的值还没赋给左边out
(out的值还是初始值0,这个跟阻塞赋值不同,值的改变在块结束后立刻更新),
然后再一句 out <= out + 1’b1;
(在块里面代码是顺序的,如果出现两句代码对一个reg的值进行改变,虽然代码都运行了,但最终的值还是最后运行的那一句代码的值,也就是说前面的代码都无效了);
但是这时由于上面out的值没有被赋值,
所以右边out的值,还是初始时的0,然后加1 ,右边的值还是1,
然后一个周期后,更新了寄存器的值于是左边out的值变为1了,于是out的值最终为1,后面几个周期同理累加1。
(这个好好理解,如果不理解,后面写多代码就会明白的,不过一般在always块里面都是用非阻塞赋值”<=”,阻塞赋值一般用在assign语句中)
测试台编写testbench文件编写
`include "adder.v" module adder_test(); reg clk; wire [3:0]out; /*实例化adder 模块,采用位置对应实例化*/ adder u0(clk,out); /*每10个时钟单位clk翻转一次*/ always #10 clk = ~clk; /*初始化*/ initial begin clk = 0; end endmodule
注:笔者能力有限,如有不对请指出,谢谢!
相关文章推荐
- struts2传递对象
- http 和 Tcp 的区别
- HDOJ 5396 Expression DP
- java之 ------ 设计思想
- 【Powershell】【计数器】实时获取邮箱服务器的队列
- ajax提交整个form表单
- 基础理解部分
- Android SDK Android NDK Android Studio 官方下载地址
- hdu 5400 Arithmetic Sequence
- Twig中文说明手册
- Android SDK Android NDK Android Studio 官方下载地址
- 基于核方法的模糊C均值聚类
- 2015 Multi-University Training Contest 9 1005
- 用 GNOME Boxes 下载一个操作系统镜像
- 详解Python3中yield生成器的用法
- 使用Python3编写抓取网页和只抓网页图片的脚本
- 使用Python求解最大公约数的实现方法
- hdu 5402 Travelling Salesman Problem(构造)
- Python中列表和元组的相关语句和方法讲解
- Python3字符串学习教程