VHDL - iSIM 输出未初始化,不改变状态 [英] VHDL - iSIM output uninitialised, doesn't change states

查看:34
本文介绍了VHDL - iSIM 输出未初始化,不改变状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 Xilinx 的新用户,在如何在测试台上编写激励/模拟时遇到了麻烦.我的输出(Kd)没有给我任何合理的值,而是在前几个时钟周期给出u",然后移动并始终保持在1".

Hi I am a new Xilinx user and been having trouble with how to write stimulus/simulate in a test bench. My output(Kd) isn't giving me any sensible values and gives 'u' for the first few clock cycles before moving and staying at '1' throughout.

不确定我是否写了正确的刺激,但希望有人能帮助我!

Not sure if I have written the correct stimulus but hoping someone would help me out here!

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;

我的测试平台##

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;

推荐答案

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

What you built is a sequential logic, meaning that the outputs depend on the previous hystory of the inputs/outputs. In your case we have Qa, and Qb which is the last value of Qa.

记住这一点,您在测试平台中使用的方法不是最佳的,因为您尝试输入的每一种组合,而没有考虑到最后一个 Qa 实际上很重要.

Keeping this in mind, the approach you have used in the testbench is not optimal, because you are trying every combination of the inputs without taking into account that the last Qa is actually important.

事情是这样的:

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
....

只要其中一个 Rs 变高,Qa 就会变高.鉴于输入组合的顺序,Qa 不会再次变低.这意味着在第二次输入组合后,Qb 获得一个已知值,而 Kb 变高.

As soon as one of the Rs goes high, Qa is high. Given the order of your combinations of inputs, there is no case where Qa goes low again. This means that after the second input combination, Qb gets a known value and Kb goes high.

敏感列表

这不是答案的一部分,而是对您编写的代码的考虑:您已将敏感度列表 R0、R1、R2、R3 放在了敏感列表中,但是,鉴于您之后编写的内容,这不是必需的.

This is not part of the answer but it's a consideration on the code you have written: you have put on the sensitivity list R0, R1, R2, R3 but, given what you have written after that, this is not necessary.

该进程仅在以下情况下执行某些操作

The process does something only if

if clock'event and clock = 1 then

这意味着 Rs 上的任何事件都将被忽略.我确信合成器实际上意识到了这一点并忽略了它,但设置适当的敏感度列表是一个很好的做法,并且在可能的情况下,仅对时序逻辑和有限状态机使用时钟过程.

this means that any event on the Rs are ignored. I'm sure that the synthetizer actually realizes that and ignores it, but it's a good practice to set a proper sensitivity list and, when possible, only use clocked processes for sequential logic and finite state machines.

我也建议你使用更易读的rising_edge(clock) 和falling_edge(clock) 函数:

I also suggest that you use the more readable rising_edge(clock) and falling_edge(clock) functions:

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;

<小时>

信号和过程

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

Another thing you should know is how the process work: you are not assigning new values to the signals, but rather planning values for them. If you reprogram a certain signal you are just overwriting the previous planning, and the first value is never assigned. The values are finally assigned at the end of the 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 <= '1' 实现).

At the end B is still 0, this because A = 0 for the whole process and only gets a planned value of 1, actually never assigned because it is overwritten before the end of the process (in this specific case the synthetizer will ignore A <= '1' for the implementation).

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

Overwriting the planned value can be used to simplify the logic: what I usually do is setting some default values and then overwriting them only when I need to.

所以,而不是写

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

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

I write this (I may retain the case structure if I need it for other signals, typically in Finite State Machines):

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

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

For this simple examples the synthetizer may be able to infer the semplification. However, you should get used to think in logic level ports because the same thing written in two equivalent ways from a behavioral point of view, is actually implemented differently.

这篇关于VHDL - iSIM 输出未初始化,不改变状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆