麻雀虽小,五脏俱全。cpld规模虽小,其原理和设计方法和fpga确是一样的。轻视在cpld上的投入,就有可能存在设计隐患,导致客户使用产品时出现故障,从而给公司带来不可挽回的信誉损失。
近一段时间,我遇到了两个cpld设计故障,这两个故障的根因(root cause)是一样的。其中的一个故障发生在实验室测试阶段,另一个发生在运营商的网络上,造成了非常不好的负面影响,因此引起了高度重视,必须彻底找出原因并消除。虽然可以很容易让故障不复现,但是要想找到根因,并给相关人员解释清楚, 却并不是一件容易的事情。
问题代码
图 1. 问题代码截图
这段代码的功能是统计 输入信号’status_in’ 的高电平持续时间。cpu写相应的寄存器产生’clr_cnt’把”cnt”清零。同时,也会把”cnt”的值给回读到cpu。实际上就是一个读清操作。
很明显,这里有一个问题,就是异步时钟域处理的问题。’clr_cnt’的时钟为’clk_sys’,而”cnt”的时钟为’clk_io’, ‘clk_sys’和’clk_io’是异步的,没有确定的相位关系。
测试方法
测试中,cpu循环执行以下四步:
清零: cpu通过local bus写寄存器,产生’clr_cnt’脉冲,把”cnt”清零;计数: cpu等待一段时间。“cnt” 开始对外部输入 ‘status_in’ 计数;回读: cpu通过local bus读取 ”cnt” 值;循环: goto 1.实际实现可能略有不同,cpld逻辑在执行清零1.的同时会把”cnt”的值锁存下来,供cpu回读,也就是1.和3.也可以是一个步骤。这样表述是为了突出问题代码。
问题描述
如果’status_in’ 恒为低电平’0’输入, 那么”cnt”应该恒为零值。可是,客户发现一个非常奇怪的现象。测试中,让 ‘status_in’ 恒为低电平’0’输入时,客户发现cpu会低概率的回读到非零的”cnt”值。朋友们,你们能解释这种现象吗?
初步分析
‘status_in’恒为零,不可能引起”cnt”变化。
‘clr_cnt’在测试中是翻转变化的。’clr_cnt’是从’clk_sys’时钟域来的信号。而时钟’clk_sys’和时钟’clk_io’是异步关系,没有固定的相位关系。也就是说’clr_cnt’是可能违反触发器”cnt”的建立/保持时间要求的,进而出现亚稳态。
但是有人认为, “cnt”的值原来是零,“clr_cnt”只是把”cnt”的值清零, 这样来说触发器“cnt”的输入根本没有发生过变化,怎么可能有亚稳态事件? 而且故障出现的概率很高,远比亚稳态的概率高,好像也不能用亚稳态来解释。
问题根因
解释问题的真正原因,必须要知道 ”cnt” 对应的电路网表是什么样的。”cnt”电路网表由综合工具(synthesis)生成,可以在综合工具中查看电路图, 图2是网表的局部放大。
*** 图 2. “cnt”的technology view电路***
图2中调用了进位链模块,看起来很乱,整理一下, 手工简化一下如图3。
图 3. 手工简化的“cnt”的电路图
图3中,可以看到,’clr_cnt’和’status_in’相或的结果控制触发器的使能端(‘ce’)。另外,’clr_cnt’还决定了触发器输入(‘d’)是”cnt+1”还是”0”。真值表如下。
也许和你想象中的不一样,电路使用了触发器的两个输入端’d’和’ce’,而不是单单一个’d’端。于是,’clr_cnt’的跳变引起了’d’/’ce’的跳变。
为了说明问题方便,定义 ‘clr_cnt’ 跳变的时刻为t0,这个跳变事件传播到触发器’ce’端的时刻为t1, 传播到触发器’d’端的时刻为t2。见图4。
图4. “cnt”触发器时序违反的演示
图4中的场景, t2>t1>t0。 最初的时候,”cnt”的值为hex”0000”,”cnt+1”的值为hex”0001”。 由于’clk_io’的上升沿落在t1和t2之间, 因此”cnt”错误地跳变为hex”0001”。
一个布局布线后的设计,一般情况下ce的传播延时(t1-t0)不会等于d的传播延时(t2-t0)。由于’clk_io’和’clk_sys’之间的相位关系是随机的, 肯定会出现’clk_io’的上升沿刚好位于t1和t2之间的情况。这种情况下,触发器cnt[15:0]就会错误的采样到”cnt+1”,而不是期望的hex”0000”值。
忽略次要参数和亚稳态事件,故障出现的概率可以被估算为 (t2-t1)/tclk_io 。(t2-t1)越大,故障概率越高。这就是为什么故障出现的概率这么高的原因。
对于t2=t1的情况(应该没有可能),只有当’clk_io’采样到’d’/’ce’的边沿附近时,引起亚稳态事件,cnt才会出错,当然这种故障的概率会低的多。
*** 图5. “cnt”触发器的后仿真时序违反演示***
解决措施
通过以上的分析,问题是由于信号跨异步时钟域而产生了模糊的时序关系,布局布线工具无法也不可能分析出这种时序要求,只能从代码上加以处理。
同步化一个很成熟的异步信号同步化方法就是多拍处理。见图6。
*** 图6. 优化过后的代码***
‘clr_cnt’经过同步化后,’clr_cnt_sync’会在’clk_io’上升沿之后很短的时间内稳定下来。布局布线工具通过利用’clk_io’的时钟周期,去约束’clr_cnt_sync’到’d’和’ce’的路径。从而不会出现”cnt”非零的错误。
如果’status_in’也是异步的信号,原理是一样的,会引起计数的不准确,只是故障更隐蔽,同样需要同步化。如果’status_in’是同步的引脚输入,必须通过时序约束告知布局布线工具,’status_in’相对于’clk_io’的建立时间和保持时间。
禁止ce有人提出过一种伪方案,我们来讨论一下。就是约束综合工具,禁止使用触发器的’ce’功能。这样,触发器只有d端口, 且d = ( clr_cnt ) ? “0000” : ( status_in ) ? cnt+1 : cnt 。
当’status_in’==0且”cnt”=”0000”时,d = ( clr_cnt ) ? “0000” : cnt = ”0000”,此时,’clr_cnt’的跳变不会引起d端口上出现跳变,也就不会出现错误的采样。
这样做局限性很大,首先限制了”cnt”=”0000”的状态才适用, 如果”cnt”的当前状态非零,一样会有问题,只是错误会更隐蔽。再者,使用ce端口可以降低逻辑级数,改善时序,节省面积,实际上可能的情况下应该尽量使用。
因此禁止ce的手段是不能作为解决措施的。
通过生成式模型驱动开发车辆中的电子E/E系统问题
超小型可穿戴医疗保健设计平台
华为Mate9遇劲敌 魅族PRO6Plus性能更强大
双十一NANK南卡耳机支付金额突破1000万,比去年同比增长150%!
vivo APEX 2020手机预告,摄像变焦将具有连续性
一个亚稳态设计案例分析
Windows中PNP和电源特性
数字化学习使学习到绩效转化的确定性成为可能
基于TEAC的集成放大器AI-503的介绍
美女手把手教你如何装机(中)
与“OEM”共舞气质最搭的互联网公司,语音将会成车内交互的基础
英伟达以超过70亿美元的价格收购以色列芯片制造商Mellanox!
一张纸秒破手机指纹锁
为什么银行最容易被人工智能所代替
国货之光,先进的磁悬浮传输技术--纵苇自研
这三个原因导致了笔记本电脑的电源适配器不通用
anyfeeder 视觉选料 柔性供料器
意法半导体于推出首款用于CAN总线的汽车级瞬态电压抑制器
用于无人机的工业物联网网络平台
如何使用示波器探头对被测电路进行检测