一、时序电路
1.D触发器
先来看一个最简单的时序电路:
module D1(
input D,
input CLK,
output reg Q
);
always@(posedge CLK)
begin
Q <= D;
end
endmodule
上面描述了一个最简单的边沿触发的D触发器:输入数据D,在下一时钟周期就输出Q。
其中,数据的存储时刻是时钟信号的上升沿(跳变瞬间),即寄存器Q在时钟上升沿采样到数据D,并更新存储内容;
除了时钟上升沿的其他时刻,无论D如何变化,都不会存储到Q寄存器中。只要理解这一点,就明白了数字电路进行时序电路控制的基础,寄存器具有稳定输入和输出的特性
2.阻塞赋值与非阻塞赋值
在Verilog中,信号有两种赋值方式:
1.非阻塞(Non-Blocking)赋值方式: b <= a
(1)在语句块中,上面语句所赋的变量值不能立即就为下面的语句所用;
(2)块结束后才能完成这次赋值操作,而所赋的变量值是上一次赋值得到的;
(3)在编写可综合的时序逻辑模块时,是最常用的赋值方法。
always@(posedge CLK)
begin
b <= a;
c <= b;
end
赋值是在always块结束后进行的,c应为原来b的值。实际电路如图:
2.阻塞(Blocking)赋值方式:b = a
(1)赋值语句执行完后,块才结束;
(2)b的值在赋值语句执行完后立刻改变;
(3)在时序逻辑中使用时,可能会产生意想不到的后果。
always@(posedge CLK)
begin
b = a;
c = b;
end
赋值是马上执行的,也就是说执行b=a之后,c=b也立即执行,最后c为a的值,即c=a。实际电路如图:
b是一个中间变量,最后被综合掉,只有c输出,也可以理解成b只是一个连线
3.阻塞赋值与非阻塞赋值是Verilog中专门针对电路行为而特殊设计的赋值语句。
module block(a, b, c, clk, sel, out);
input a, b, c, clk, sel;
output out;
reg out, temp;
always @(posedge clk)
begin
temp = a&b;
if (sel) out = temp|c;//out = (a&b)|c
else out = c;
end
endmodule
module non_block(a, b, c, clk, sel