基础项目(9)异步复位同步触发程序设计讲解

写在前面的话

在FPGA设计中,很多同学会纠结到底是应该使用同步复位还是应该使用异步复位。实际上,无论是同步复位还是异步复位都有各自的优缺点。在这里梦翼师兄和大家一起学习另外一种复位信号的处理方式-异步复位同步释放。

 基本概念

FPGA设计中常见的复位方式有同步复位和异步复位,同步复位就是指复位信号只有在时钟上升沿到来时,才能有效;异步复位是指无论时钟沿是否到来,只要复位信号有效,就对系统进行复位;这两种复位方式在实际应用中都有其弊端存在,所以,一般都推荐使用异步复位同步释放的方式,是提高系统稳定性的有效方式,下面来介绍前面两种复位方式,我们以此来比较说明异步复位同步释放的优点。

代码举例

下面是一个简单的同步复位的代码:


/****************************************************

*   Engineer        :   梦翼师兄

*   QQ               :   761664056

*   The module function:同步复位模块*****************************************************/

01  module syn(

02          clk,     //系统时钟50Mhz

03          rst_n,   //系统低电平复位

04          d,       //外部输入

05          q        //输出

06  );

07

08  input clk;

09  input rst_n;

10  input d;

11

12  output reg q;

13

14  always @ (posedge clk)  //同步复位

15      begin

16          if (!rst_n)

17              q <= 0;      //复位的时候清零

18          else

19              q <= d;   //置位的时候输出d

20      end

21

22  endmodule

该代码的RTL图如下:

从RTL视图我们可以看出,同步复位综合出来的实际电路只是把复位信号rst_n做为了输入逻辑的使能信号,经过一个数据选择器最后输出到寄存器,很明显,这样的同步复位电路势必会额外增加FPGA内部的资源消耗。

下面是一个简单的异步复位的代码:


/****************************************************

*   Engineer        :   梦翼师兄

*   QQ               :   761664056

*   The module function : 异步复位模块*****************************************************/

01  module asy(

02          clk,     //系统时钟50Mhz

03          rst_n,   //系统低电平复位

04          d,       //外部输入

05          q        //输出

06  );

07

08  input clk;

09  input rst_n;

10  input d;

11

12  output reg q;

13

14  always @ (posedge clk or negedge rst_n)  //异步复位

15      begin

16          if (!rst_n)

17              q <= 0;      //复位的时候清零

18          else

19              q <= d;   //置位的时候输出d

20      end

21

22  endmodule

该代码的RTL图如下:

我们可以看到寄存器有一个异步的清零端(CLR),在异步复位的设计中这个端口一般就是接低电平有效的复位信号rst_n。如果我们设计的是高电平复位,那么实际综合后会也会将该复位信号反向后接这个CLR端。

总结:同步复位的优点是它只在时钟信号clk的上升沿触发进行系统是否复位的判断,这降低了亚稳态出现的概率;缺点在于它需要消耗更多的器件资源。FPGA的寄存器有支持异步复位专用的端口,采用异步复位的端口无需额外增加器件资源的消耗,但是异步复位也存在着隐患,比如: 在同步复位和异步复位电路中复位信号刚好由复位状态跳变到置位状态时,时钟上升沿刚好到来,那么时钟采集的数据0还是1呢?

当上述情况发生时,电路会进入亚稳态。亚稳态是在寄存器的建立时间和保持时间不满足的情况下发生的。当亚稳态发生时采集到的数据是一个不定态,有可能是1也有可能是0,所以无法确保所有的寄存器在同一个时钟沿跳出复位状态。

上面的分析似乎都让人觉得同步复位和异步复位都不可靠,那么如何将两者结合,取长补短呢?下面我们来介绍一种异步复位同步释放的电路。

异步复位同步释放电路

观察这个电路图可以看出reset_n接到两个异步复位寄存器的清零端(CLRN端接低电平的时候寄存器输出端会清零),当reset_n为0 时,寄存器reg3和寄存器reg4输出为0;由于寄存器reg1和寄存器reg2的CLRN端接到了寄存器reg4的输出端,所以寄存器输出端out_a和out_b会被清零,从而实现复位清零的功能。在reset_n由低变高时,第一个时钟周期将VCC输入到左边第一个寄存器,第二个寄存器保持为0,在第二个时钟周期后两个寄存器都变为1,输出端寄存器的清零端为1,跳出复位。

将上图电路描述为代码如下:


/****************************************************

*   Engineer        :   梦翼师兄

*   QQ               :   761664056

*   The module function : 异步复位同步释放模块*****************************************************/

01  module sync_async_reset(

02                          clk,

03                          rst_n,

04                          data_a,

05                          data_b,

06                          out_a,

07                          out_b

08                          );

09

10  input clk;

11  input rst_n;

12  input data_a;

13  input data_b;

14

15  output  out_a;

16  output  out_b;

17

18  reg   reg1,reg2;

19  reg   reg3,reg4;

20

21  wire reset_n;

22

23  assign out_a = reg1;   //将reg1赋值给输出 out_a;

24  assign out_b = reg2;   //将reg2赋值给输出 out_b;

25  assign reset_n = reg4; //将寄存器的值赋给reset_n

26  //产生同步复位输出reset_n,reset_n作为第二个进程模块的异步复位。

27  always@(posedge clk or negedge rst_n)

28      begin

29          if(!rst_n)

30              begin

31                  reg3 <= 1‘b0;

32                  reg4 <= 1‘b0;

33              end

34          else

35              begin

36                  reg3 <= 1‘b1;

37                  reg4 <= reg3;

38              end

39      end

40  //将这个已经同步化了的复位信号当作异步复位使用。

41  always@(posedge clk or negedge reset_n)

42      begin

43          if(!reset_n)

44              begin

45                  reg1 <= 1‘b0;

46                  reg2 <= 1‘b0;

47              end

48          else

49              begin

50                  reg1 <= data_a;

51                  reg2 <= data_b;

52              end

53      end

54  endmodule

第27~39行定义了2个寄存器,对应于我们电路图中的reg3和reg4,目的是产生同步复位输出reset_n;第41~53行也定义了两个寄存器,对应于我们电路图中的reg1和reg2,输入的复位信号是reset_n;第23~25行只做连线。

测试代码如下:


/****************************************************

*   Engineer        :   梦翼师兄

*   QQ               :   761664056

*   The module function : 异步复位同步释放测试模块*****************************************************/

01  `timescale 1ns/1ps

02  module tb;

03

04      reg clk;

05      reg rst_n;

06      reg data_a;  //外部输入

07      reg data_b;  //外部输入

08      wire out_a;  //输出

09      wire out_b;  //输出

10

11      initial begin

12          clk = 1;

13          rst_n = 0; data_a = 0; data_b = 0;

14          #100 rst_n = 1;

15          #100 data_a = 1; data_b = 1; //输入4组数据

16          #100 data_a = 1; data_b = 0;

17          #100 data_a = 0; data_b = 1;

18          #100 data_a = 0; data_b = 0;

19      end

20

21      always #10 clk = ~clk; //产生周期是20ns的时钟

22

23      sync_async_reset sync_async_reset(

24      .clk(clk),

25      .rst_n(rst_n),

26      .data_a(data_a),

27      .data_b(data_b),

28      .out_a(out_a),

29      .out_b(out_b)

30      );

31

32  endmodule

仿真波形如下:

观察波形可以看出,我们外部输入的复位信号rst_n是一个异步复位,产生的reset_n是一个同步信号,它用于其他模块的输入的复位信号。

同理下面介绍如何使用锁相环进行异步复位同步释放,复位电路原理图如下:

要理解此电路,我们必须掌握以下几点:

locked信号为锁相环的输出信号,锁相环时钟输出端CO在上电以后会有一段不稳定的时间,此时locked信号为低电平,当时钟输出端C0输出保持稳定以后,locked信号也会同步拉高,表示输出有效。

areset为输入锁相环的高电平复位信号,当areset为高电平时,锁相环复位,没有时钟输出。

寄存器ENA端为寄存器输出使能,高电平有效,只有当ENA保持为高电平的时候,寄存器才会有数据输出。

由以上电路原理图可以看出,当reset_n信号变为低电平以后,寄存器reg1、reg2、reg3、reg4都会清零,由于reset_n到areset端口之间经过了一个非门,电平取反,对于锁相环来说,复位端为高电平,可以实现复位。

当reset_n信号由低电平变为高电平以后,锁相环复位和所有寄存器清零同步结束,但由于锁相环的输出端locked信号需要稳定一定时间才能输出高电平而且寄存器reg3和reg4的输出使能端有locked信号控制,所以必须要等到锁相环输出稳定以后,VCC才会开始在寄存器reg3和reg4之间传递,使其他寄存器电路正式结束复位状态。

上述电路图的代码描述如下:


/****************************************************

*   Engineer        :   梦翼师兄

*   QQ               :   761664056

*   The module function : 异步复位同步释放加锁相环模块*****************************************************/

00  module sync_async_reset_pll(

01                          clk,    //系统50Mhz时钟

02                          rst_n,  //系统低电平复位

03                          data_a, //寄存器reg1输入

04                          data_b, //寄存器reg2输入

05                          out_a,  //寄存器reg1输出

06                          out_b   //寄存器reg2输出

07                          );

08

09  input clk;

10  input rst_n;

11  input data_a;

12  input data_b;

13

14  output  out_a;

15  output  out_b;

16

17  reg   reg1,reg2;

18  reg   reg3,reg4;

19

20  wire reset_n;

21  wire clk_out;

22  wire lock;

23  assign out_a =reg1;  //将reg1赋值给输出 out_a;

24  assign out_b =reg2;  //将reg2赋值给输出 out_b;

25  assign reset_n =reg4;  //将寄存器的值赋给reset_n

26

27  always@(posedge clk_out or negedge rst_n)

28      begin

29          if(!rst_n)

30              begin

31                  reg3 <= 1‘b0;

32                  reg4 <= 1‘b0;

33              end

34      //lock信号有效,输出同步复位信号 reset_n

35          else if(lock)   //reset_n作为第二个进程模块的异步复位

36              begin

37                  reg3 <= 1‘b1;

38                  reg4 <= reg3;

39              end

40          else  //lock信号无效,输出保持上一个状态

41              begin

42                  reg3 <= reg3;

43                  reg4 <= reg4;

44              end

45      end

46

47  //将这个已经同步化了的复位信号当作异步复位使用

48  always@(posedge clk_out or negedge reset_n)

49      begin

50          if(!reset_n)

51              begin

52                  reg1 <= 1‘b0;

53                  reg2 <= 1‘b0;

54              end

55          else

56              begin

57                  reg1 <= data_a;

58                  reg2 <= data_b;

59              end

60      end

61

62   my_pll my_pll_inst (

63  .areset ( !rst_n ),

64  .inclk0 ( clk ),

65  .c0 ( clk_out ),

66  .locked ( lock )

67  );

68

69  endmodule

测试代码如下:


/****************************************************

*   Engineer        :   梦翼师兄

*   QQ               :   761664056

*   The module function : 异步复位同步释放加锁相环测试模块*****************************************************/

01  `timescale 1ns/1ps

02  module tb;

03

04      reg clk;

05      reg rst_n;

06      reg data_a;  //外部输入

07      reg data_b;  //外部输入

08      wire out_a;  //输出

09      wire out_b;  //输出

10

11      initial begin

12          clk = 1;

13          rst_n = 0; data_a = 0; data_b = 0;

14          #100 rst_n = 1;

15          #100 data_a = 1; data_b = 1; //输入4组数据

16          #100 data_a = 1; data_b = 0;

17          #100 data_a = 0; data_b = 1;

18          #100 data_a = 0; data_b = 0;

19      end

20

21      always #10 clk = ~clk; //产生周期是20ns的时钟

22

23      sync_async_reset_pll sync_async_reset_pll(

24      .clk(clk),

25      .rst_n(rst_n),

26      .data_a(data_a),

27      .data_b(data_b),

28      .out_a(out_a),

29      .out_b(out_b)

30      );

31

32  endmodule

15~18输入4组数据观察输出波形

仿真波形如下:

观察波形可知,当外部复位按键rst_n放开之后,锁相环开始动作,clk_out持续一段时间不定态以后开始输出稳定的方波信号,同时lock信号置为高电平。Lock信号置为高电平之后使能reg3和reg4,reg4比reg3晚一拍输出高电平,当reg4输出高电平之后,out_a和out_b才分别等于data_a和data_b。这与我们的分析是一致的,所以我们本次设计正确。

原文地址:https://www.cnblogs.com/mengyi1989/p/11521078.html

时间: 2024-08-28 02:22:01

基础项目(9)异步复位同步触发程序设计讲解的相关文章

异步复位同步释放

同步复位与异步复位的优缺点 同步复位的优点: 一般能够确保电路是百分之百同步的. 确保复位只发生在有效时钟沿,可以作为过滤掉毛刺的手段. 同步复位的缺点: 复位信号的有效时长必须大于时钟周期,才能真正被系统识别并完成复位.同时还要考虑如:时钟偏移.组合逻辑路径延时.复位延时等因素. 由于大多数的厂商目标库内的触发器都只有异步复位端口,采用同步复位的话,就会耗费较多的逻辑资源. 异步复位优点: 异步复位信号识别方便,而且可以很方便的使用全局复位. 由于大多数的厂商目标库内的触发器都有异步复位端口,

异步复位 同步释放

在FPGA设计中常遇到复位的设计,一般情况下,复位分为同步复位和异步复位. 异步复位与同步复位相比,其利用到了D触发器的CLR端,消耗硬件资源小,所以在很多情况下各个模块的复位方式选取为异步复位.但是异步信号容易产生潜在的危险:当异步复位信号在时钟上升沿附近取消复位状态时,时序电路很可能在此出现问题. 解决这个问题的一个方法为,对异步复位信号进行预处理,使其成为异步复位.同步释放的形式. 我设计的电路如下: library ieee; use ieee.std_logic_1164.all; u

什么是异步复位同步释放

1.电路原理图 2.verilog代码描述 module reset_gen ( output rst_sync_n, input clk, rst_async_n); reg rst_s1, rst_s2; wire rst_sync_n ; always @ (posedge clk, posedge rst_async_n) if (rst_async_n) begin rst_s1 <= 1'b0; rst_s2 <= 1'b0; end else begin rst_s1 <=

进阶项目(7)VGA显示程序设计讲解

 写在前面的话 可能大家觉得之前设计都是各种看波形,比较的单一.乏味.那么本节的内容,一定可以带给大家全新的感受,现代电子技术中,图像处理技术可谓是发展迅猛,其带给大家独特的视觉感受也总是那么的赏心悦目.这里,梦翼师兄和大家一起敲开图像世界的大门,让我们一起为之痴迷,为之陶醉. 什么是VGA? VGA(Video Graphics Array,视频图形阵列),是 IBM 于1987年提出的一个使用类比讯号的电脑显示标准.这个标准已对于现今的个人电脑市场已经十分过 时.即使如此,VGA 仍然是很多

进阶项目(11) 矩阵键盘程序设计讲解

写在前面的话 在使用按键的时候,如果按键不多的话,我们可以直接让按键与FPGA相连接,但是如果按键比较多的时候,如果还继续使用直接让按键与FPGA相连接的话,会大量增加FPGA端口的消耗,为了减少FPGA端口的消耗,我们可以把按键设计成矩阵的形式.接下来,梦翼师兄将和大家一起学习扫描键盘的电路原理以及驱动方式. 项目需求 设计4*4矩阵键盘按键扫描模块,正确解析按键值. 矩阵键盘的原理 由上图可以知道,矩阵键盘的行row(行)与col(列)的交点,都是通过一个按键相连接.传统的一个按键一个端口的

异步复位,同步释放

平时接触到的复位有三种,分别是同步复位.异步复位还有异步复位同步释放 ·1.同步复位 同步复位里,复位做为使能信号,就不存在因为不满足建立时间而产生的亚稳态,但是如果复位信号有效 周期小于一个时钟周期的话,会出现复位信号采样不到的问题. always @(posedge clk ) begin if(!rst_n) a <= 1'd0; else a <= b; end 2.异步复位 异步复位比同步复位节省资源,但是如果异步复位结束之后,紧跟着一个时钟上升沿,这时候会产生亚稳态 现象 alwa

FPGA基础之同步复位与异步复位

1.异步复位 //异步复位 always @ (posedge clk or negedge i_rst) if (!i_rst) begin a <= 1'b0; end else begin a <= 1'b1; end 2.同步复位 //同步复位 always @ (posedge clk ) if (!i_rst) begin b <= 1'b0; end else begin b <= 1'b1; end RTL视图 总结: 同步复位  缺点:占用了更多的逻辑资源,优点:

FPGA中的同步复位与异步复位

1.异步复位 always @ ( posedge sclk or negedge s_rst_n ) if ( !s_rst_n ) d_out <= 1'b0; else d_out <= a; 综合出来的RTL视图如下所示: 从图中可以看到寄存器d_out有一个低电平有效的复位信号s_rst_n端口,即使设计是高电平复位,实际综合后也会把异步复位信号反向后接到这个CLRN端: 2.同步复位 always @ ( posedge sclk ) if ( !s_rst_n ) d_out &

异步复位、同步释放

一.对于同步复位和异步复位而言,各自有自己的优缺点: (1)同步复位: 优点:与时钟同步,大大降低亚稳态的出现概率: 缺点:消耗片内逻辑资源: always@(posedge clk) if(!rst_n) a <= 1'b0; else a <= b; 同步复位 (2)异步复位: 优点:利用FPGA内部寄存器的清零端,不会增加多余逻辑消耗: 缺点:容易出现亚稳态,存在于异步复位和时钟之间的亚稳态: always@(posedge clk or negedge rst_n) if(!rst_n