设计一个复位电路?同步复位&异步复位
请设计一个复位电路?
复位的目的:使芯片电路处于一个已知的、确定的状态。
复位的分类:同步复位和异步复位。
同步复位:指的是当时钟上升沿检测到复位信号,执行复位操作,有效的时钟沿是前提。
同步复位的优点如下: a、有利于仿真器的仿真; b、可以使所设计的系统成为 100%的同步时序电路,有利于时序分析,而且可综合出较高的 Fmax; c、由于只在时钟有效电平到来时才有效,所以可以滤除高于时钟频率的复位毛刺。
同步复位的一些缺点,缺点如下: a、复位信号的有效时长必须大于时钟周期,才能真正被系统识别并完成复位任务。同时还要考虑诸如 时钟偏移、组合逻辑路径延时、复位延时等因素(所以复位信号有时需要脉冲展宽,用以保证时钟有效期间 有足够的复位宽度); b、由于大多数的逻辑器件的目标库内的 DFF 都只有异步复位端口,所以,倘若采用同步复位的话,综 合器就会在寄存器的数据输入端口插入组合逻辑,这样就会一方面额外增加 FPGA 内部的逻辑资源,另一 方面也增加了相应的组合逻辑门时延。
异步复位:指的是无论时钟沿是否到来,只要复位信号有效,就对系统进行复位。
异步复位的优点: a、大多数目标器件库的 DFF 都有异步复位端口,那么该触发器的复位端口就不需要额外的组合逻辑, 这样就可以节省资源; b、设计相对简单; c、异步复位信号产生和响应都很方便(电路在任何情况下都能复位而不管是否有时钟出现)。
异步复位的缺点,缺点如下: a、最大的问题在于它属于异步逻辑,问题出现在复位释放时,而不是有效时,如果复位释放接近时钟有效沿,则触发器的输出可能进入亚稳态(此时 clk 检测到的 rst_n 的状态就会是一个亚稳态,即是 0 是 1 是不确定的),从而导致复位失败。 b、可能因为噪声或者毛刺造成虚假复位信号(比如系统正常工作时突然复位)(注意:时钟端口、清零和置位端口对毛刺信号十分敏感,任何一点毛刺都可能会使系统出错,因此判断逻辑电路中是否存在冒险以及如何避免冒险是设计人员必须要考虑的问题); c、静态定时分析比较困难,静态时序分析一般是针对同步设计的,都是基于时钟周期来分析时序的。 d、对于 DFT(DesignForTest 可测性设计)设计,如果复位信号不是直接来自于 I/O 引脚,在 DFT 扫描和测试时,复位信号必须被禁止,因此需要额外的同步电路。
总结下来,我们推荐使用异步复位、同步释放的方式,并且复位信号为低电平有效。
复位信号产生时不受时钟信号的控制,但是释放的时候受到时钟信号的同步。主要目的是防止复位信号释放时候产生亚稳态。
异步复位:当复位信号拉低时,直接进入复位状态。
同步释放:当复位信号释放时,加入两级同步缓存器,电路不会立即释放,而是同步到时钟有效时再进行释放。
1、复位信号到来的有效与否与 clk 无关,而且复位信号的撤除也与 clk 无关,但是复位信号的撤除是在下一个 clk 来到后才起的作用。
2、异步复位同步撤离的目的为了防止复位信号撤除时,可能产生的亚稳态。
同步复位代码&激励&仿真波形
module rst_n( input sys_clk , input sys_rst_n , input in , output reg out ); always@(posedge sys_clk ) begin //同步复位 if(!sys_rst_n) out<=1'b0; else out<=in; end endmodule
`timescale 1ns/1ns module tb_rst_n(); reg sys_clk ; reg sys_rst_n ; reg in ; wire out ; initial begin sys_clk<=1'b0; sys_rst_n<=1'b1; in<=1'b1; #33 sys_rst_n<=1'b1; #6 sys_rst_n<=1'b0; #3 sys_rst_n<=1'b1; #30 in<=1'b1; #55 sys_rst_n<=1'b0; #60 in<=1'b0; #45 sys_rst_n<=1'b1; #30 in<=1'b1; #26 sys_rst_n<=1'b0; #30 in<=1'b0; #58 sys_rst_n<=1'b1; #30 in<=1'b1; #23 sys_rst_n<=1'b0; #40 in<=1'b0; #78 sys_rst_n<=1'b1; end always #10 sys_clk<=~sys_clk; rst_n rst_n_inst( .sys_clk (sys_clk ) , .sys_rst_n (sys_rst_n) , .in (in) , .out (out ) ); endmodule
异步复位代码&激励&仿真波形
module rst_n( input sys_clk , input sys_rst_n , input in , output reg out ); always@(posedge sys_clk or negedge sys_rst_n) begin //异步复位 if(!sys_rst_n) out<=1'b0; else out<=in; end endmodule
`timescale 1ns/1ns module tb_rst_n(); reg sys_clk ; reg sys_rst_n ; reg in ; wire out ; initial begin sys_clk<=1'b0; sys_rst_n<=1'b1; in<=1'b1; #29 sys_rst_n<=1'b0; #2 sys_rst_n<=1'b1; #38 sys_rst_n<=1'b0; #2 sys_rst_n<=1'b1; #80 in<=1'b0; #45 sys_rst_n<=1'b1; #30 in<=1'b1; #20 sys_rst_n<=1'b0; #30 in<=1'b0; #58 sys_rst_n<=1'b1; #30 in<=1'b1; #23 sys_rst_n<=1'b0; #40 in<=1'b0; #78 sys_rst_n<=1'b1; end always #10 sys_clk<=~sys_clk; rst_n rst_n_inst( .sys_clk (sys_clk ) , .sys_rst_n (sys_rst_n) , .in (in) , .out (out ) ); endmodule
备注:这里作者还未完成复位信号接近与上升沿时的仿真,出现亚稳态现象,在以后遇到会补充说明。
异步复位同步释放代码&激励&仿真波形
module rst_n( input sys_clk , input sys_rst_n , input in , output reg out ); reg rst_n_0; reg rst_n_1; wire rst_n_2; always@(posedge sys_clk or negedge sys_rst_n ) begin //异步复位、同步释放 if(!sys_rst_n) begin rst_n_0<=1'b0; rst_n_1<=1'b0; end else begin rst_n_0<=1'b1; rst_n_1<=rst_n_0; end end assign rst_n_2=rst_n_1; always@(posedge sys_clk or negedge rst_n_2) begin if(!rst_n_2) out<=1'b0; else out<=in; end endmodule
`timescale 1ns/1ns module tb_rst_n(); reg sys_clk ; reg sys_rst_n ; reg in ; wire out ; initial begin sys_clk<=1'b0; sys_rst_n<=1'b1; in<=1'b1; #33 sys_rst_n<=1'b1; #6 sys_rst_n<=1'b0; #3 sys_rst_n<=1'b1; #30 in<=1'b1; #55 sys_rst_n<=1'b0; #60 in<=1'b0; #45 sys_rst_n<=1'b1; #30 in<=1'b1; #26 sys_rst_n<=1'b0; #30 in<=1'b0; #58 sys_rst_n<=1'b1; #30 in<=1'b1; #23 sys_rst_n<=1'b0; #40 in<=1'b0; #78 sys_rst_n<=1'b1; end always #10 sys_clk<=~sys_clk; rst_n rst_n_inst( .sys_clk (sys_clk ) , .sys_rst_n (sys_rst_n) , .in (in) , .out (out ) ); endmodule
若有不对的地方,敬请指正,万分感谢。
参考资料:
1、正点原子逻辑逻辑设计指南复位电路
2、Asynchronous & Synchronous Reset Design Techniques