复位设计和全局时钟遵守的原则
0赞一.复位的设计:
转载:http://blog.chinaaet.com/detail/14471.html
首先,感谢特权和Master eBoy对我的影响……
参考:http://blog.ednchina.com/yuchen576/57388/message.aspx
在暑假的时候编写“逻辑分析仪”的时候,纠结过这个问题,因为系统大了,就会有稳定的问题,那时候一知半解,云里雾里……
如今,在设计一个摄像头(CPU,SDRAM,SRAM,ADV7120)的系统时候,老是发现系统不稳定的问题,于是再次回到了起点:
“异步复位、同步复位”的问题…
所谓亚稳态,是指“trecovery(recovery time)指的是原本有效的异步复位信号释放(对低电平有效的复位来说就是上跳沿)与紧 跟其后的第一个时钟有效沿之间所必须的最小时间。tremoval(removal time)指的是时钟有效沿与紧跟其后的原本有效的异步复位信号变得 无效之间所必须的最小时间。如果异步复位信号的上跳沿(以低电平有效为例)落在trecovery与tremoval的窗口之内,触发器的输出端的值将是 不确定的,可能是高电平,可能是低电平,可能处于高低电平之间,也可能处于震荡状态),并且在未知的时刻会固定到高电平或低电平。这种状态就称为亚稳态。 反映到仿真模型中,输出端的值是不定态X。图中tclk-q是触发器时钟端到Q端的延时,tMET是保证亚稳态不传播到下一级所允许的亚稳态持续的最大时 间。”
个人理解:如果RST_n的释放发生在靠近时钟沿或者离时钟沿很近的电,电路可能级没有足够的时间维持RST_n的值,也没有足够的时间维持D输入端口的值,从而造成亚稳态,并通过最后一级与非门传到Q端输出。
同步复位:(复位信号的产生依赖于系统时钟信号)
优缺点:更好的避免亚稳态,但是消耗更多的LE
时钟起到了过滤复位信号小毛刺的作用
同步复位需要一个脉宽沿展器来保证复位信号有一定脉冲宽度,以确保时钟的有效沿能采样到
1
2
3
4
5
6
7
|
always@(posedge CLK) begin if (!RST_n) b <= 0; else b <= a; end |
异步复位:(复位信号和系统时钟信号相互独立,可以发生在任何时候)
优缺点:消耗更少的LE,但是难以避免LE的消耗
1
2
3
4
5
6
7
|
always@(posedge CLK or negedge RST_n) begin if (!RST_n) b <= 0; else b <= a; end |
因此,如果对复位信号的处理,能够同步复位+异步复位,那将会是很完美,基于这样的设计能够避免亚稳态的发生,因为他让RST_n信号的释放再晚了一点(寄存器)
根据特权和eBoy的设计,我加之以深化,归纳了3中我们会用到的复位与亚稳态问题
(1)没有PLL
(2)有一个PLL
(3)多个PLL
具体如下:
(1)没有PLL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
/******************************************************************** * File Name : System_Ctrl * Author : Crazy Bingo * Version : Quartus II 9.1 * Date : 2010/12/4 * Function : 双锁相环系统异步复位 * Description : *********************************************************************/ module System_Ctrl0 ( input clk, //FPAG输入时钟信号50MHz input rst_n, //系统复位信号,低有效 output sys_rst_n //系统复位信号,低有效 ); reg rst_nr1,rst_nr2; always@(posedge clk or negedge rst_n) begin if (!rst_n) rst_nr1 <= 0; else rst_nr1 <= 1; end always@(posedge clk or negedge rst_n) begin if (!rst_n) rst_nr2 <= 0; else rst_nr2 <= rst_nr1; end assign sys_rst_n = rst_nr2; endmodule |
(2)一个PLL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
/******************************************************************** * File Name : System_Ctrl * Author : Crazy Bingo * Version : Quartus II 9.1 * Date : 2010/12/4 * Function : 双锁相环系统异步复位 * Description : *********************************************************************/ module System_Ctrl1 ( input clk, //FPAG输入时钟信号50MHz input rst_n, //系统复位信号,低有效 output sys_rst_n, //系统复位信号,低有效 output clk_125, //PLL1输出125MHz时钟 output clk_65 //PLL2输出65MHz时钟 ); //---------------------------------------------- //PLL复位信号产生,高有效,异步复位,同步释放输出 wire pll_rst; //PLL复位信号,高有效 reg rst_r1,rst_r2; //DFF触发,稳定信号 always @(posedge clk or negedge rst_n) begin if (!rst_n) rst_r1 <= 1'b1; else rst_r1 <= 1'b0; end always @(posedge clk or negedge rst_n) begin if (!rst_n) rst_r2 <= 1'b1; else rst_r2 <= rst_r1; end assign pll_rst = rst_r2; //---------------------------------------------- //系统复位信号产生,低有效,异步复位,同步释放 //等待两个锁相环都输出稳定的时候,系统释放复位 wire locked; //PLL输出有效标志位,高表示PLL输出有效 wire sysrst_nr0 = rst_n & locked; //系统复位直到PLL有效输出; reg sysrst_nr1,sysrst_nr2; always @(posedge clk_125 or negedge sysrst_nr0) begin if (!sysrst_nr0) begin sysrst_nr1 <= 1'b0; sysrst_nr2 <= 1'b0; end else begin sysrst_nr1 <= 1'b1; sysrst_nr2 <= sysrst_nr1; end end assign sys_rst_n = sysrst_nr2; //---------------------------------------------- //例化PLL1产生模块 PLL1 PLL1 ( .areset(pll_rst), //PLL复位信号,高电平复位 .inclk0(clk), //PLL输入时钟,50MHz .c0(clk_125), //PLL输出125MHz时钟 .c1(clk_65), //PLL输出125MHz时钟(-3.5ns) .locked(locked) //PLL输出有效标志位,高表示PLL输出有效 ); endmodule |
(3)多个PLL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
/******************************************************************** * File Name : System_Ctrl * Author : Crazy Bingo * Version : Quartus II 9.1 * Date : 2010/12/4 * Function : 双锁相环系统异步复位 * Description : *********************************************************************/ module System_Ctrl ( input clk1, //FPAG输入时钟信号50MHz input clk2, //FPAG输入时钟信号50MHz input rst_n, //系统复位信号,低有效 output sys_rst_n, //系统复位信号,低有效 output clk_125, //PLL1输出125MHz时钟 output clk_125_2, //PLL1输出125MHz时钟(-3.5ns) output clk_65 //PLL2输出65MHz时钟 ); //---------------------------------------------- //PLL1,PLL2复位信号产生,高有效,异步复位,同步释放输出 wire pll_rst1; //PLL1复位信号,高有效 wire pll_rst2; //PLL2复位信号,高有效 reg rst_r1,rst_r2; //DFF触发,稳定信号 always @(posedge clk1 or negedge rst_n) begin if (!rst_n) rst_r1 <= 1'b1; else rst_r1 <= 1'b0; end always @(posedge clk1 or negedge rst_n) begin if (!rst_n) rst_r2 <= 1'b1; else rst_r2 <= rst_r1; end assign pll_rst1 = rst_r2; assign pll_rst2 = rst_r2; //---------------------------------------------- //系统复位信号产生,低有效,异步复位,同步释放 //等待两个锁相环都输出稳定的时候,系统释放复位 wire locked1,locked2; //PLL输出有效标志位,高表示PLL输出有效 wire sysrst_nr0 = rst_n & locked1 & locked2; //系统复位直到PLL有效输出; reg sysrst_nr1,sysrst_nr2; always @(posedge clk_125 or negedge sysrst_nr0) begin if (!sysrst_nr0) begin sysrst_nr1 <= 1'b0; sysrst_nr2 <= 1'b0; end else begin sysrst_nr1 <= 1'b1; sysrst_nr2 <= sysrst_nr1; end end assign sys_rst_n = sysrst_nr2; //---------------------------------------------- //例化PLL1产生模块 PLL1 PLL1 ( .areset(pll_rst1), //PLL1复位信号,高电平复位 .inclk0(clk1), //PLL1输入时钟,50MHz .c0(clk_125), //PLL1输出125MHz时钟 .c1(clk_125_2), //PLL1输出125MHz时钟(-3.5ns) .locked(locked1) //PLL1输出有效标志位,高表示PLL1输出有效 ); //例化PLL2产生模块 PLL2 PLL2 ( .areset(pll_rst2), //PLL2复位信号,高电平复位 .inclk0(clk2), //PLL2输入时钟,50MHz .c0(clk_65), //PLL2输出125MHz时钟 .locked(locked2) //PLL2输出有效标志位,高表示PLL2输出有效 ); endmodule |
二:全局时钟应遵守的原则: 为了系统的稳定以及高速时钟干扰,整个系统要用最高时钟控制,不能用门控时钟,只能用使能时钟。