简单 VHDL 电路的意外行为
Unexpected behavior of simple VHDL circuit
模拟器中信号Q_VLD1和Q_VLD2延迟不同的原因是什么?
Result of simulation. 这是否是模拟器的预期行为?
我使用赛灵思 Isim。
有它的代码和测试台:
entity assign_test is
port(CLK : in STD_LOGIC;
D_VLD : in STD_LOGIC;
Q_VLD1 : out STD_LOGIC;
Q_VLD2 : out STD_LOGIC
);
end assign_test;
architecture Behavioral of assign_test is
signal D_VLD_i : std_logic;
signal d_vld_dly1 : std_logic;
signal d_vld_dly2 : std_logic;
begin
D_VLD_i <= D_VLD;
process (clk) is
begin
if rising_edge(clk) then
d_vld_dly1 <= D_VLD;
d_vld_dly2 <= D_VLD_i;
end if;
end process ;
Q_VLD1 <= d_vld_dly1;
Q_VLD2 <= d_vld_dly2;
end Behavioral;
ENTITY tb_assign_test IS
END tb_assign_test;
ARCHITECTURE behavior OF tb_assign_test IS
COMPONENT assign_test
PORT(
CLK : IN std_logic;
D_VLD : IN std_logic;
Q_VLD1 : OUT std_logic;
Q_VLD2 : OUT std_logic
);
END COMPONENT;
--Inputs
signal CLK : std_logic := '0';
signal D_VLD : std_logic := '0';
--Outputs
signal Q_VLD1 : std_logic;
signal Q_VLD2 : std_logic;
constant CLK_period : time := 10 ns;
BEGIN
uut: assign_test PORT MAP (
CLK => CLK,
D_VLD => D_VLD,
Q_VLD1 => Q_VLD1,
Q_VLD2 => Q_VLD2
);
CLK_process :process
begin
CLK <= '0';
wait for CLK_period/2;
CLK <= '1';
wait for CLK_period/2;
end process;
stim_proc: process
begin
wait for 100 ns;
wait for 5 ns;
wait for CLK_period*10;
D_VLD <= '1';
wait for CLK_period*3;
D_VLD <= '0';
wait;
end process;
END;
因此,如果您查看 assign_test
模块中的内部信号,仅基于模拟时间,它可能如下图所示(d_vld_dly*
在分配给 Q_VLD*
之前).
但该图具有误导性,因为该图未显示 VHDL concept of delta delay。如果波形被扩展以显示增量延迟(在这种情况下使用 ModelSim),它看起来如下所示。
因此,这表明 assign_test
中的 D_VLD_i <= D_VLD;
实际上延迟了 D_VLD_i
增量延迟,因此直到下一个时钟上升沿才会在时钟上看到新值。
这个问题的原因,是测试平台不生成输入数据作为时钟的原因,这会使数据在时钟之后延迟一个增量,但是独立且在相同的模拟时间 和 与时钟相同的增量延迟。
测试台可以更新以生成数据作为时钟的原因,如果等待时钟从:
wait for CLK_period*10;
至:
for i in 1 to 10 loop
wait until rising_edge(CLK);
end loop;
然后将给出波形为:
所以基于此,好的测试台设计的一个规则是生成刺激的方式与在合成模块中生成数据的方式相同,所以来自测试台的刺激通常就像模块之间的数据,为了得到预期的、可靠的和测试台行为。
模拟器中信号Q_VLD1和Q_VLD2延迟不同的原因是什么? Result of simulation. 这是否是模拟器的预期行为?
我使用赛灵思 Isim。 有它的代码和测试台:
entity assign_test is
port(CLK : in STD_LOGIC;
D_VLD : in STD_LOGIC;
Q_VLD1 : out STD_LOGIC;
Q_VLD2 : out STD_LOGIC
);
end assign_test;
architecture Behavioral of assign_test is
signal D_VLD_i : std_logic;
signal d_vld_dly1 : std_logic;
signal d_vld_dly2 : std_logic;
begin
D_VLD_i <= D_VLD;
process (clk) is
begin
if rising_edge(clk) then
d_vld_dly1 <= D_VLD;
d_vld_dly2 <= D_VLD_i;
end if;
end process ;
Q_VLD1 <= d_vld_dly1;
Q_VLD2 <= d_vld_dly2;
end Behavioral;
ENTITY tb_assign_test IS
END tb_assign_test;
ARCHITECTURE behavior OF tb_assign_test IS
COMPONENT assign_test
PORT(
CLK : IN std_logic;
D_VLD : IN std_logic;
Q_VLD1 : OUT std_logic;
Q_VLD2 : OUT std_logic
);
END COMPONENT;
--Inputs
signal CLK : std_logic := '0';
signal D_VLD : std_logic := '0';
--Outputs
signal Q_VLD1 : std_logic;
signal Q_VLD2 : std_logic;
constant CLK_period : time := 10 ns;
BEGIN
uut: assign_test PORT MAP (
CLK => CLK,
D_VLD => D_VLD,
Q_VLD1 => Q_VLD1,
Q_VLD2 => Q_VLD2
);
CLK_process :process
begin
CLK <= '0';
wait for CLK_period/2;
CLK <= '1';
wait for CLK_period/2;
end process;
stim_proc: process
begin
wait for 100 ns;
wait for 5 ns;
wait for CLK_period*10;
D_VLD <= '1';
wait for CLK_period*3;
D_VLD <= '0';
wait;
end process;
END;
因此,如果您查看 assign_test
模块中的内部信号,仅基于模拟时间,它可能如下图所示(d_vld_dly*
在分配给 Q_VLD*
之前).
但该图具有误导性,因为该图未显示 VHDL concept of delta delay。如果波形被扩展以显示增量延迟(在这种情况下使用 ModelSim),它看起来如下所示。
因此,这表明 assign_test
中的 D_VLD_i <= D_VLD;
实际上延迟了 D_VLD_i
增量延迟,因此直到下一个时钟上升沿才会在时钟上看到新值。
这个问题的原因,是测试平台不生成输入数据作为时钟的原因,这会使数据在时钟之后延迟一个增量,但是独立且在相同的模拟时间 和 与时钟相同的增量延迟。
测试台可以更新以生成数据作为时钟的原因,如果等待时钟从:
wait for CLK_period*10;
至:
for i in 1 to 10 loop
wait until rising_edge(CLK);
end loop;
然后将给出波形为:
所以基于此,好的测试台设计的一个规则是生成刺激的方式与在合成模块中生成数据的方式相同,所以来自测试台的刺激通常就像模块之间的数据,为了得到预期的、可靠的和测试台行为。