时序电路的竞争与冒险
时序电路中主要存在以下两种竞争与冒险:
1)clk上升沿和rst_n下降沿同时到达:对于D触发器来说,rst_n信号的优先级高于clk信号的优先级。
2)clk上升沿和rst_n上升沿同时到达:容易造成竞争与冒险。
3)异步时钟的处理:最简单的方案是使用主时钟去打一拍,实现信号的同步化。
异步复位,同步释放机制
异步复位:
module test
(
input clk,
input rst_n,
input data_in,
output reg out
);
always @ (posedge clk or negedge rst_n)
if(!rst_n) out <= 1'b0;
else out <= data_in;
endmodule
我们可以看到FPGA的寄存器都有一个异步的清零端(CLR),在异步复位的设计中这个端口一般就是接低电平有效的复位信号rst_n。
此种情况会出现亚稳态,比如:clk信号和rst_n下降沿同时到达,两个改变的条件同时满足,会不知所措,严重影响系统的亚稳态。
同步复位:
module test
(
input clk,
input rst_n,
input data_in,
output reg out
);
always @ (posedge clk )
if(!rst_n) out <= 1'b0;
else out <= data_in;
endmodule
和异步复位相比,同步复位没有用上寄存器的CLR端口,综合出来的实际电路只是把复位信号rst_n作为了输入逻辑的使能信号。那么,这样的同步复位势必会额外增加FPGA内部的资源消耗。
那么同步复位和异步复位到底孰优孰劣呢?
只能说,各有优缺点。同步复位的好在于它只在时钟信号clk的上升沿触发进行系统是否复位的判断,这降低了亚稳态出现的概率;它的不好上面也说了,在于它需要消耗更多的器件资源,这是我们不希望看到的。FPGA的寄存器有支持异步复位专用的端口,采用异步复位的端口无需额外增加器件资源的消耗,但是异步复位也存在着隐患。异步时钟域的亚稳态问题同样的存在与异步复位信号和系统时钟信号之间。
异步复位、同步释放:
module test
(
input clk,
input rst_n,
input a,
output reg c
);
reg b,rst_nr;
always @ (posedge clk)
rst_nr <= rst_n;
always @ (posedge clk or negedge rst_nr)
if(!rst_nr) b <= 1'b0;
else b <= a;
always @ (posedge clk or negedge rst_nr)
if(!rst_nr) c <= 1'b0;
else c <= b;
endmodule
在第一个always进程中,进行异步复位信号的同步化:用D触发器将rst_n打一拍,这一过程将rst_n信号同步到了clk时钟域;在第二个always进程中,使用同步化的复位信号rst_nr作为D触发器的复位信号。这样设计的好处在于只用了一个D触发器实现了异步复位信号的同步,在资源上大大减少了组合逻辑的使用;
如此一来,既解决了同步复位的资源消耗问题,也解决了异步复位的亚稳态问题。其根本思想,也是将异步信号同步化。