VHDL - iSIM输出未初始化,不会改变状态

时间:2015-01-24 03:12:22

标签: vhdl simulation

您好我是Xilinx的新用户,并且在如何在测试平台上编写激励/模拟方面遇到了麻烦。我的输出(Kd)没有给我任何明智的值,并且在移动前保持'1'前的几个时钟周期并保持在'1'。

不确定我是否写过正确的刺激物,但希望有人能在这里帮助我!

我的VHDL代码

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity codeFig2b is
    Port ( R0 : in  STD_LOGIC;
           R1 : in  STD_LOGIC;
           R2 : in  STD_LOGIC;
           R3 : in  STD_LOGIC;
           Kd : out  STD_LOGIC;
           clock : in  STD_LOGIC);
end codeFig2b;

architecture Behavioral of codeFig2b is
    signal Qa, Qb: STD_LOGIC;
begin
    process(clock, R0, R1, R2, R3)
        begin
        if clock = '1' and clock'event then
        Qa <= (R0 or R1 or R2 or R3) or (Qa and Qb);
        Qb <= Qa;
        end if;
    end process;
Kd <= Qa and Qb;    

end Behavioral;

My Testbench ##

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;

ENTITY codeFig2b_test IS
END codeFig2b_test;

ARCHITECTURE behavior OF codeFig2b_test IS 

    -- Component Declaration for the Unit Under Test (UUT)

    COMPONENT codeFig2b
    PORT(
         R0 : IN  std_logic;
         R1 : IN  std_logic;
         R2 : IN  std_logic;
         R3 : IN  std_logic;
         Kd : OUT  std_logic;
         clock : IN  std_logic
        );
    END COMPONENT;


   --Inputs
   signal R0 : std_logic := '0';
   signal R1 : std_logic := '0';
   signal R2 : std_logic := '0';
   signal R3 : std_logic := '0';
   signal clock : std_logic := '0';

    --Outputs
   signal Kd : std_logic;

   -- Clock period definitions
   constant clock_period : time := 100 ns;

BEGIN
    -- Instantiate the Unit Under Test (UUT)
   uut: codeFig2b PORT MAP (
          R0 => R0,
          R1 => R1,
          R2 => R2,
          R3 => R3,
          Kd => Kd,
          clock => clock
        );

   -- Clock process definitions
   clock_process :process
   begin
        clock <= '0';
        wait for clock_period/2;
        clock <= '1';
        wait for clock_period/2;
   end process;


   -- Stimulus process
   stim_proc: process
   begin        
      -- hold reset state for 100 ns.
       wait for 100 ns;
            R0 <= '0';
            R1 <= '0';
            R2 <= '0';
            R3 <= '0';

        wait for 100 ns;
            R0 <= '0';
            R1 <= '0';
            R2 <= '0';
            R3 <= '1';

        wait for 100 ns;
            R0 <= '0';
            R1 <= '0';
            R2 <= '1';
            R3 <= '0';

        wait for 100 ns;
            R0 <= '0';
            R1 <= '0';
            R2 <= '1';
            R3 <= '1';

        wait for 100 ns;
            R0 <= '0';
            R1 <= '1';
            R2 <= '0';
            R3 <= '0';

        wait for 100 ns;
            R0 <= '0';
            R1 <= '1';
            R2 <= '0';
            R3 <= '1';

        wait for 100 ns;
            R0 <= '0';
            R1 <= '1';
            R2 <= '1';
            R3 <= '0';

        wait for 100 ns;
            R0 <= '0';
            R1 <= '1';
            R2 <= '1';
            R3 <= '1';

        wait for 100 ns;
            R0 <= '1';
            R1 <= '0';
            R2 <= '0';
            R3 <= '0';

        wait for 100 ns;
            R0 <= '1';
            R1 <= '0';
            R2 <= '0';
            R3 <= '1';

        wait for 100 ns;
            R0 <= '1';
            R1 <= '0';
            R2 <= '1';
            R3 <= '0';

        wait for 100 ns;
            R0 <= '1';
            R1 <= '0';
            R2 <= '1';
            R3 <= '1';

        wait for 100 ns;
            R0 <= '1';
            R1 <= '1';
            R2 <= '0';
            R3 <= '0';

        wait for 100 ns;
            R0 <= '1';
            R1 <= '1';
            R2 <= '0';
            R3 <= '1';

        wait for 100 ns;
            R0 <= '1';
            R1 <= '1';
            R2 <= '1';
            R3 <= '0';

        wait for 100 ns;
            R0 <= '1';
            R1 <= '1';
            R2 <= '1';
            R3 <= '1';

      wait for clock_period*10;

      -- insert stimulus here 

      wait;
   end process;

END;

2 个答案:

答案 0 :(得分:2)

这可以在不模拟的情况下回答。 Kd的输出将变为'1'并保持不变。

    process(clock, R0, R1, R2, R3)
        begin
        if clock = '1' and clock'event then
        Qa <= (R0 or R1 or R2 or R3) or (Qa and Qb);
        Qb <= Qa;
        end if;
    end process;
Kd <= Qa and Qb;  

对于R0,R1,R2或R2或(Qa和Qb)中的任何一个,Qa都会变高;

所以一旦Qa和Qb走高,Qa就会保持高位。

Qa在第一次出现高位后的一个时钟点亮。

这种情况的发生方式是在R0,R1,R2或R3中的任何一个连续'1'输入。

您的时钟周期为100 ns,您的刺激间隔也是如此。

在第一个时钟之后没有任何刺激,其中所有R0,R1,R2和R3同时都是低电平以进行演示。

不幸的是,Xilinx帖子(iSIM output Unintialised, doesn't change states.)上的波形图像没有显示QA和Qb,看到它们都变高并留在那里:

codefig2b image (点击)

当你添加它们时,这一点就会出现:

codefig2b_test.png 可点击)

答案 1 :(得分:0)

您构建的是顺序逻辑,这意味着输出取决于输入/输出的先前的高级。在你的情况下,我们有Qa和Qb,这是Qa的最后一个值。

记住这一点,您在测试平台中使用的方法并不是最优的,因为您正在尝试输入的每个组合,而不考虑最后一个Qa实际上是否重要。

这就是:

Start :   Qa = U    Qb = U     =>    Kb = U
Inputs 1: Qa = 1    Qb = U     =>    Kb = U
Inputs 2: Qa = 1    Qb = 1     =>    Kb = 1
Inputs 3: Qa = 1    Qb = 1     =>    Kb = 1
Inputs 4: Qa = 1    Qb = 1     =>    Kb = 1
....

一旦R升高,Qa就会很高。根据输入组合的顺序,Qa不会再次变低。 这意味着在第二个输入组合之后,Qb得到一个已知值并且Kb变高。


敏感度列表

这不是答案的一部分,但它是对您编写的代码的考虑因素:您已经设置了敏感度列表R0,R1,R2,R3但是,鉴于您之后所写的内容,这不是必需的。

该过程仅在

时执行
if clock'event and clock = 1 then

这意味着忽略R上的任何事件。我确信合成器实际上意识到并忽略了它,但是设置一个合适的灵敏度列表是一个好习惯,并且在可能的情况下,只对顺序逻辑和有限状态机使用时钟进程。 / p>

我还建议您使用更易读的rising_edge(时钟)和falling_edge(时钟)函数:

process(clock)
begin
    if rising_edge(clock) then
        Qa <= R0 or R1 or R2 or R3 or (Qa and Qb);
        Qb <= Qa;
    end if;
end process;

信号和流程

您应该知道的另一件事是过程如何工作:您没有为信号分配新值,而是为它们分配规划值。如果重新编程某个信号,则只是覆盖了之前的计划,并且永远不会分配第一个值。最终在流程结束时分配值

这是一个简单的例子:

-- Let's assume A = 0 and B = 0 at startup
clocked_process : process(clk)
begin
    if rising_edge(clk) then
        A <= '1';
        B <= A;
        A <= '0';
    end if;
end process;

在结束时B仍为0,这是因为整个过程A = 0且只有计划值为1,实际上从未分配,因为它在过程结束前被覆盖(在这种特定情况下,合成器将忽略实现的A&lt; ='1'。

覆盖计划值可用于简化逻辑:我通常做的是设置一些默认值,然后仅在需要时覆盖它们。

所以,而不是写

...
case A is
when "00" =>
    B <= '0';
when "01" =>
    B <= '0';
when "10" =>
    B <= '0';
when "11" =>
    B <= '1';
end case;
...

我写这个(如果我需要其他信号,我可能会保留案例结构,通常在有限状态机中):

...
B <= '0';
if A = "11" then
    B <= '1';
end if;
...

对于这个简单的例子,合成器可能能够推断出简化。但是,您应该习惯于在逻辑级别端口进行思考,因为从行为的角度来看,以两种等效的方式编写的内容实际上是以不同的方式实现的。