非阻塞赋值
各位大师:
请教一个问题。
always @(posedge clk or posedge rst)
if (rst) y1 <= 0; // reset
else y1 <= y2;
always @(posedge clk or posedge rst)
if (rst) y2 <= 1; // preset
此处插入许多非阻塞语句。
else y2 <= y1;
endmodule
资料说:左边的REG集中赋值,两个ALWAYS先后顺寻没关系。
如果第二个ALWAYS因为插入许多语句,导致执行时间与第一个ALWAYS有大的差异,那么两个ALWAYS的左边的REG更新
是在哪个ALWAYS执行完毕更新,是最长时间执行完毕的ALWAYS,然后两个一起更新吗?
虽说<=是并行执行,但表达式的计算应该需要时间吧?两个ALWAYS是否可能不同时结束?自己顶一下。
顶。。
进行波形仿真试试
FPGA语句执行和C语言是不一样的,不是逐条执行,所有语句都会被综合软件综合后都是通过电路表示的,对于reg来说,每一条非阻塞赋值语句综合后都对应一个D触发器,当时钟沿到来时always块里对应的所有D触发器同时被触发,至于你说的计算总需要时间吧,指的是单个语句完成时间,这个时间相比于时钟周期很短,不影响语句执行结果
楼上讲的很对,不要用理解C语言的思维去理解FPGA语句,两者有本质上的区别。
由于FPGA语句最终被综合成电路,所以要以电路的眼光去看待FPGA语句,而不能用C语言的思维去看待。
与C语言的顺序执行不同,FPGA最大的特点就是可以并行执行。这是因为,C语言的执行平台是CPU,所有的C语言语句共用CPU这1个”计算装置“,所以只有等上一条C语言执行完了,CPU“空”出来,下一条语句才能开始执行;而每条FPGA语句在FPGA内部都对应于各自的电路结构,相当于每条FPGA语句都有各自的“计算装置“,所以可以同时执行。
在verilog中,所有的always块并行执行,always块内的非阻塞赋值语句也是并行执行。资料中说的的集中赋值,实际上是说在时钟上升沿,所有reg同时赋值;小编所谓的执行时间,可能是想把所有非阻塞赋值语句的执行时间给加起来,而事实上,对于非阻塞赋值语句而言,所有语句是同时执行的,而且,不论右侧的计算是否执行完,当时钟上升沿到来之时,左侧reg的赋值都会执行,只是此时会产生时序错误罢了。
一看一下RTL视图,二看一下仿真波形,三结合一下原理。
谢谢诸位的回答,特别是5#,6#。那么我还有一个疑问。你们所说的时钟应该是系统时钟。
always @ (posedge clk or negedge rst_n),
是clk上升沿所有reg同时赋值吗?那么rst_n呢,对于REG赋值有影响吗?
如果有一语句always @ (posedge XXX ),XXX是一个输入引脚,它不是时钟,那么REG赋值是在什么时候呢?
如果还是系统时钟上升沿同时赋值,那不是有很大的风险吗?就是刚刚XXX上升沿来了,系统时钟上升沿又来了。
顶一下。新的问题。
新手吗?你不能只看verilog hdl语法,还要理解什么是组合逻辑,什么是时序逻辑!用HDL语言编写的代码,最终都要综合成电路,如果对电路没有概念的话,编写出来的代码可综合性非常差!针对你提出的问题,我建议你去看三段式的FSM编写方法,并自己去仿真和思考!网络上有很多关于三段式的详细说明!
always @ (posedge XXX )的时候 只跟XXX的上升沿来操作,always @ (posedge clk or negedge rst_n)这个是跟clk的上升沿和rst_n的下降沿来操作。always下边包含的代码 只通过后边()里面的沿运行
我想你们没明白我的问题:
举例:
always @(posedge XXX) //XXX为一输入信号,不是时钟。
if (rst) y1 <= 0; // reset
else y1 <= y2;
always @(posedge clk or posedge rst)
if (rst) y2 <= 1; // preset
else y2 <= y1;
endmodule
6#说,y1,y2的更新在clk上升沿,现在两个ALWAYS的条件不一样,y1,y2的更新在什么时刻呢?
注意看一下我1#的问题,这个问题与1#不一样。