异步逻辑的劣势异步代码会产生难以约束、仿真及调试的逻辑。异步逻辑往往产生间歇性错误,而且这些错误几乎无法重现。另外,无法生成用于检测异步逻辑所导致的错误的测试平台。 虽然异步逻辑看起来可能容易检测,但是,事实上它经常不经检测;因此,设计人员必须小心异步逻辑在设计中隐藏的许多方面。所有钟控逻辑都需要一个最短建立与保持时间,而且这一点同样适用于触发器的复位输入。以下代码采用异步复位。在此无法为了满足触发器的建立与保持时间需求而应用时序约束。 data_proc : PROCESS (sys_clk,reset)
BEGIN
if (reset = '1') then
data_in <= '0';
elsif rising_edge(sys_clk) then
data_in <= serial_in;
end if;
END PROCESS data_proc; 下列代码采用同步复位。但是,大多数系统的复位信号都可能是按键开关,或是与系统时钟无关的其它信号源。尽管复位信号大部分情况是静态的,而且长期处于断言或解除断言状态,不过其水平仍然会有所变化。相当于系统时钟上升沿,复位解除断言可以违反触发器的建立时间要求,而对此无法约束。 data_proc : PROCESS (sys_clk)
BEGIN
if rising_edge(sys_clk) then
if (reset = '1') then
data_in <= '0';
else
data_in <= serial_in;
end if;
end if;
END PROCESS data_proc; 只要我们明白无法直接将异步信号馈送到我们的同步逻辑中,就很容易解决这个问题。以下代码创建一个称sys_reset 的新复位信号,其已经与我们的系统时钟sys_clk同步化。在异步逻辑采样时会产生亚稳定性问题。我们可以采用与阶梯的前几级进行了‘与’运算的梯形采样降低此问题的发生几率。 data_proc : PROCESS (sys_clk)
BEGIN
if rising_edge(sys_clk) then
reset_1 <= reset;
reset_2 <= reset_1 and reset;
sys_reset <= reset_2 and reset_1
and reset;
end if;
if rising_edge(sys_clk) then
if (sys_reset = '1') then
data_in <= '0';
else
data_in <= serial_in;
end if;
end if;
END PROCESS data_proc; 至此,假定您已经慎重实现了所有逻辑的同步化。不过,如果您不小心,则您的逻辑很容易与系统时钟脱节。切勿让您的工具链使用系统时钟所用的本地布线资源。那样做的话您就无法约束自己的逻辑。切记要明确定义所有的重要逻辑。 |