当前位置:网站首页>【深入浅出玩转FPGA学习5-----复位设计】
【深入浅出玩转FPGA学习5-----复位设计】
2022-07-02 07:29:00 【周猿猿】
异步复位与同步复位
FPGA设计中常见得复位方式即异步复位与同步复位。所谓异步,是指复位信号与系统时钟信号的触发可以在任何时刻,二者相互独立。
异步复位实例
下面给出异步复位的一段代码:
always @ (posedge clk or negedge rst_n)
if(!rst_n) b <= 1'b0;
else b <= a;
下图是上面代码综合后的RTL视图,可以看到FPGA的寄存器都有一个异步的清零端(CLR),在异步复位的设计中,这个端口一般接低电平有效的复位信号rst_n,即使设计中是高电平复位,实际综合后也会把异步复位信号反向后接到这个CLR端。
同步复位实例
下面给出同步复位的一段代码:
always @ (posedge clk)
if(!rst_n) b <= 1'b0;
else b <=a;
代码综合后的RTL视图,和异步复位相比,同步复位没有用到寄存器的CLR端口,综合出来的实际电路只是把复位信号rst_n作为输入逻辑的使能信号,那么,这样的同步复位势必会额外增加FPGA内部的资源消耗。
那么,异步复位与同步复位到底孰优孰劣呢?只能说,各有优缺点。FPGA的寄存器有支持异步复位专用的端口,采用异步复位无需增加器件的额外资源,但是异步复位也存在着隐患。异步时钟域的亚稳态问题同样存在异步复位信号和系统时钟信号之间。同步复位在时钟信号clk的上升沿触发时进行系统是否复位的判断,这降低了亚稳态出现的概率(只是降低,不可能完全避免);它的缺点在于需要消耗更多的器件资源,无法充分利用专用的 复位端口CLR。
再通过下面一个两级寄存器异步复位的例子来说明异步复位存在的隐患。
always @ (posedge clk or negedge rst_n)
if(!rst_n) b <= 1'b0;
else b <=a;
always @ (posedge clk or negedge rst_n)
if (!rst_n) c <= 1'b0;
else c <= b;
代码综合后的RTL视图如图所示:
正常情况下,在clk的上升沿将c更新为b,b更新为a。一旦进入复位,b、c都将清零;但是并不能确定复位信号rst_n会在什么时候结束。如果结束于b_reg0和c_reg0的{latch edge setup time,latch edge + hold time} 时间之外,那么一切都会正常。但如果恰恰相反,会出现什么情况呢?复位信号rst_n的撤销(由低电平变为高电平)出现在clk锁存数据的建立时间或者保持时间内,此时clk检测到rst_n的状态就会是一个亚稳态(不确定是0还是1)。从代码里可以看到,如果此时b_reg0认为rst_n为0,那么依然保持复位清零;而如果认为rst_n为1,那么就跳出复位,执行相应的操作。
由于此时rst_n的不确定性,可能会出现4种情况,即b_reg0和c_reg0都复位或者都跳出复位,再或者一个复位一个跳出复位,那么后者就会造成系统功能做不同步的问题。
复位与亚稳态
亚稳态对于一个寄存器的影响相对小一些,但是对于诸如总线式的寄存器受到的亚稳态的影响那问题就大了,搞不好就是致命性的打击。
异步复位、同步释放
异步复位会影响寄存器recovery时间,引起设计的稳定性问题,尤其对于状态机的无意识的复位,将导致进入不确定的状态。同步复位也存在类似的问题,而且对于不带同步复位专用端口的器件会增加额外的逻辑资源。
下面介绍一种更为可靠的异步复位、同步释放的双缓冲电路。该电路有两个同一时钟沿触发的层叠寄存器组成,该时钟必须和目标寄存器是一个时钟域。Verilog代码如下:
input clk; //系统时钟信号
input rst_n; //输入复位信号,低有效
output rst_nr2; //异步复位、同步释放输出
reg rst_nr1,rst_nr2;
//两级层叠复位产生,低电平复位
always @ (posedge clk or negedge rst_n)
if(!rst_n) rst_nr2 <= 1'b0;
else rst_nr2 <= rst_nr1;
由此段代码实现的电路如图所示:

如此以来,既解决了同步复位的资源消耗问题,又解决了异步复位的亚稳态问题,其根本思想,也是将异步信号同步化。
PLL配置后得复位设计
很多FPGA设计中都会涉及多个时钟,使用器件内部的PLL或者DLL会使得多个时钟的管理变得更加容易。但是当多个时钟都是用PLL/DLL产生时,它们的系统复位电路如何设计才更稳定呢?
如图所示,先用FPGA的外部输入时钟clk将FPGA的输入复位信号rst_n做异步复位、同步释放处理,然后这个复位信号输入PLL,同时clk也输入PLL。设计初衷是在PLL输出时钟有效前,系统的其他部分都保持复位状态。PLL的输出locked信号在PLL有效输出之前一直是低电平,PLL输出稳定有效之后才会拉高该信号,所以这里就把FPGA外部输入复位信号rst_n和这个locked信号相与作为整个系统的复位信号,当然了,这个复位信号也需要让合适的PLL输出时钟异步复位、同步释放处理一下。也就是说,为了达到可靠稳定的复位信号,该设计中对复位信号进行了两次处理,分别是在PLL输出前和PLL输出后。
该设计实现的工程源代码如下:
module sys_ctrl(
clk,rst_n,sys_rst_n,clk_25m,clk_100m
);
input clk; //FPGA输入时钟信号25Mhz
input rst_n; //系统复位信号
output sys_rst_n; //系统复位信号,低有效
output clk_25m; //PLL输出25MHZ时钟频率
output clk_100m; //PLL输出100MHZ时钟频率
wire locked; //PLL输出有效标志位,高表示PLL输出有效
/PLL复位信号产生,高有效
//异步复位,同步释放
wire pll_rst; //PLL复位信号,高有效
reg rst_r1,rst_r2;
always @ (posedge clk or negedge rst_n)
if(!rst_n) rst_r1 <= 1'b1;
else rst_r1 <= 1'b0;
always @ (posedge clk or negedge rst_n)
if(!rst_n) rst_r2 <= 1'b1;
else rst_r2 <= rst_r1;
assign pll_rst = rst_r2;
//系统复位信号产生,低有效
//异步复位,同步释放
wire sys_rst_n; //系统复位信号,低有效
wire sysrst_nr0;
reg sysrst_nr1,sysrst_nr2;
assign sysrst_nr0 = rst_n & locked; //系统复位知道PLL有效输出
always @ (posedge clk_100m or negedge sysrst_nr0)
if(!sysrst_nr0) sysrst_nr1 <= 1'b0;
else sysrst_nr1 <= 1'b1;
always @ (posedge clk_100m or negedge sysrst_nr0)
if(!sysrst_nr0) sysrst_nr2 <= 1'b0;
else sysrst_nr2 <= sysrst_nr1;
assign sys_rst_n = sysrst_nr2;
//例化PLL产生模块
PLL_ctrl uut_PLL _ctrl(
.areset(pll_rst), //PLL复位信号,高电平复位
.inclk0(clk), //PLL输入时钟,25MHz
.c0(clk_25m), //PLL输出25MHz时钟频率
.c1(clk_100m), //PLL 输出100MHZ 时钟频率
.locked(locked) //PLL输出有效标志位,高电平表示PLL输出有效
);
endmodule
边栏推荐
- Pywin32 opens the specified window
- 华为快应用中如何实现同时传递事件对象和自定义参数
- 洛谷 P4281 [AHOI2008]紧急集合 / 聚会(树上倍增 LCA)
- PCL extracts a subset from a point cloud
- 2022爱分析· 国央企数字化厂商全景报告
- LabVIEW为什么浮点数会丢失精度
- Win11 arm系统配置.net core环境变量
- Set the playback speed during the playback of UOB equipment
- shell编程01_Shell基础
- 洛谷 P1892 [BOI2003]团伙(并查集变种 反集)
猜你喜欢

13. Semaphore critical zone protection

Disassembling Meitu SaaS: driving the plane to change the engine

二叉树专题--AcWing 47. 二叉树中和为某一值的路径(前序遍历)

Mongodb quickly get started with some simple operations of mongodb command line

Shell programming 01_ Shell foundation

拆解美图SaaS:开着飞机换引擎

如何使用IDE自动签名调试鸿蒙应用

Kustomize user manual

UVM learning - object attribute of UVM phase

二叉树专题--AcWing 3540. 二叉搜索树建树(实用板子 构建二叉搜索树 并输出前、中、后序遍历)
随机推荐
从.bag文件中读取并保存.jpg图片和.pcd点云
PCL eigen introduction and simple use
618 what is the secret of dominating the list again? Nike's latest financial report gives the answer
MySQL lethal serial question 3 -- are you familiar with MySQL locks?
二叉树专题--洛谷 P1229 遍历问题(乘法原理 已知前、后序遍历求中序遍历个数)
Sus system availability scale
JSP webshell free -- webshell free
Thanos Receiver
Kustomize user manual
QT学习日记8——资源文件添加
4. Random variables
Retrofit's callback hell is really vulnerable in kotlin synergy mode!
《实习报告》Skywalking分布式链路追踪?
二叉树专题--洛谷 P3884 [JLOI2009]二叉树问题(dfs求二叉树深度 bfs求二叉树宽度 dijkstra求最短路)
Easyexcel, a concise, fast and memory saving excel processing tool
PCL 投影点云
2022-06-17
[TS] 1368 seconds understand typescript generic tool types!
PCL projection point cloud
二叉树专题--【深基16.例7】普通二叉树(简化版)(multiset 求前驱 后继 哨兵法)