资源描述
一个关于异步信号作同步复位的问题
关键字:亚稳态 异步复位 同步复位
Serinf.vhd模块中有一段代码经过synplify综合以及QuartusII布局布线后,下载到FPGA执行的过程中出现了一段不符合逻辑的波形。
代码如下:
process(rst,clk_lc32_i)
begin
if rst='0' then
cnt <= (others=>'0');
elsif rising_edge(clk_lc32_i) then
if cs = '1' then
cnt <= (others=>'0');
elsif (svcksft(2 downto 1)="01") then
if cnt = 18 then
cnt <= (others=>'0');--自动清零
else
cnt <= cnt + 1;
end if;
end if;
end if;
end process;
其中cs是来自cpu的片选信号,svcksft是保存cpu时钟沿的移位寄存器
综合后,通过QuartusII自带工具RTL viewer看到的结果如下图所示:
其中红线为代码中的cs信号,经过cyclone_LCELL(1555)这个组合逻辑单元,作为寄存器cyclone_lcell(5A5A)的sclr(同步清零)端。
波形如图:
波形图1
波形图2
这两幅图都是采cs的下降沿得到的,多数情况下抓到的都是波形图2的波形,当cs=1时对cnt清零,cs=0时,cnt不变。
但是有的时候抓到的波形如波形图1,当cs=1时对cnt清零,cs=0时,cnt被置位。这种情况不符合逻辑。
将代码改为
process(rst,clk_lc32_i)
begin
if rst='0' or cs=’1’ then
cnt <= (others=>'0');
elsif rising_edge(clk_lc32_i) then
--if cs = '1' then
-- cnt <= (others=>'0');
if (svcksft(2 downto 1)="01") then
if cnt = 18 then
cnt <= (others=>'0');--自动清零
else
cnt <= cnt + 1;
end if;
end if;
end if;
end process;
综合后的电路如图所示。
从综合结果可以看出,经过这样的修改,cs信号和rst信号先经过一个组合逻辑单元,然后给cnt寄存器提供aclr(异步清零),代码经过这样处理后,cs依然实现了清零的功能,而且不会出现上述波形图1的情况。
将代码改为
process(rst,clk_lc32_i)
begin
if rst=’0’ then
cs_d <= ‘0’;
cs_dd <= ‘0’;
elsif rising_edge(clk_lc32_i) then
cs_d <= cs;
cs_dd <= cs_d;
end if
end process;
process(rst,clk_lc32_i)
begin
if rst='0' then
cnt <= (others=>'0');
elsif rising_edge(clk_lc32_i) then
if cs_dd = '1' then
cnt <= (others=>'0');
elsif (svcksft(2 downto 1)="01") then
if cnt = 18 then
cnt <= (others=>'0');--自动清零
else
cnt <= cnt + 1;
end if;
end if;
end if;
end process;
即对cs信号加入两级触发器,综合后的结果如下图,其中cs先经过寄存器cyclone_lcell(0704),然后作为cyclone_lcell(5A5A)的sclr(同步清零)端,综合的结果就不会出现问题。
结论:不能用异步信号直接进行同步复位操作。
修改方案:
1. 用该异步信号作为异步复位端。
2. 对异步复位信号做两级同步后,再来驱动同步复位端。
展开阅读全文