由一个简单的串并变换来分析时钟歪斜
这是我写的一个简单的带输入输出使能的8位串并变换VHDL程序,程序虽小但可以分析一些时钟歪斜和保持时间的问题,程序如下:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_1164.all;
entity StoP is
port(clk,shift,en: in std_logic; --en为串行输入使能
y:out std_logic_vector(7 downto 0);
oe:buffer std_logic); --oe为并行输出使能
end ;
port(clk,shift,en: in std_logic; --en为串行输入使能
y:out std_logic_vector(7 downto 0);
oe:buffer std_logic); --oe为并行输出使能
end ;
architecture a of StoP is
signal y_r:std_logic_vector(7 downto 0);
begin
P1:process(clk)
variable i : integer range 0 to 7;
begin
if(clk'event and clk = '1') then
if(en='0') then
i:=0;
else
y_r(i)<=shift; --先移入的为低位
i := i+1;
end if;
if((i=0)and(en='1')) then
oe<='1';
else
oe<='0';
end if;
end if;
end process P1;
signal y_r:std_logic_vector(7 downto 0);
begin
P1:process(clk)
variable i : integer range 0 to 7;
begin
if(clk'event and clk = '1') then
if(en='0') then
i:=0;
else
y_r(i)<=shift; --先移入的为低位
i := i+1;
end if;
if((i=0)and(en='1')) then
oe<='1';
else
oe<='0';
end if;
end if;
end process P1;
P2:process(clk)
begin
if(clk'event and clk = '1') then
if(oe='1') then
y<=y_r;
end if;
end if;
end process P2;
begin
if(clk'event and clk = '1') then
if(oe='1') then
y<=y_r;
end if;
end if;
end process P2;
end a;
波行为:

如果上述程序的 P2:process如果这样写:
P2:process(oe)
begin
if(oe'event and oe = '1') then
y<=y_r;
end if;
end process P2;
begin
if(oe'event and oe = '1') then
y<=y_r;
end if;
end process P2;
从原理上看不会有问题,语法没有错误,而且在实现同样的功能的情况下使程序也得到了简化,但是这样一来全编译的时候会发现时序分析警告:
Warning: Circuit may not operate. Detected 8 non-operational path(s) clocked by clock "clk" with clock skew larger than data delay. See Compilation Report for details.
就是说,时钟延迟大于数据延迟时间,会造成保持时间不足,导致电路无法实现其预想功能,如果你打开RTL电路图,你就会发现问题所在,下图所示为被警告路径之一,到第二个触发器的CLK要经过复杂的路
径,导致时钟延迟大,才会出现警告。
径,导致时钟延迟大,才会出现警告。 当然,如果程序非要这么写也不是不可以,那就要设置时钟约束了,可以将第二个触发器的时钟作为CLK的衍生时钟对待,就可以了。