Xilinx / ISim 似乎声称值是 X 但它已被声明

Xilinx / ISim seem claims value to be X but it has been declared

刚刚开始学习如何使用这个工具,所以如果我的问题看起来很愚蠢,我提前道歉。我在许多论坛(已经回答的帖子,不是我的)中搜索了错误并且无法理解我做错了什么所以这是我的问题:

我的行为准则:

-----------------------------------------------------------------------------    -----
-- Company: 
-- Engineer: 
-- 
-- Create Date:    01:47:22 07/07/2015 
-- Design Name: 
-- Module Name:    Module_1 - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
-----------------------------------------------------------------------------    -----
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;


-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned valuessss
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity Module_1 is
    port (A,B,WE,reset : in std_logic;
            clk : in std_logic;
            DIN : in signed(3 downto 0);
            FULL,EMPTY,ERROR : out std_logic:= '0';
            PARKFREE : out signed(3 downto 0)
            );
end Module_1;

architecture Behavioral of Module_1 is
signal current_state,next_state:std_ulogic_vector(1 downto 0);
    signal empty_bf, full_bf :std_ulogic;
    signal enter, reset_b : std_ulogic := '0' ;
    constant s0: std_ulogic_vector (1 downto 0):="00";
constant s1: std_ulogic_vector (1 downto 0):="10";
constant s2: std_ulogic_vector (1 downto 0):="11";
constant s3: std_ulogic_vector (1 downto 0):="01";
signal  park_counter,buffr: signed(3 downto 0):="0000";
signal PARKTOTAL,free_park_counter: signed(3 downto 0):= "1111";
begin


p1: process (clk,reset,reset_b)
begin   
    if (reset = '1') then
    current_state <= s0;


elsif clk'event and clk = '1' then
    current_state <= next_state;
end if;
end process p1;

p2: process (current_state,A,B)
begin
next_state <= current_state;

case current_state is
    when s0 =>
        if A = '1' then
            enter <= '1';
            next_state <= s1;
        elsif B = '1' then
            next_state <= s3;
        end if;

    when s1 =>
            if A = '0' then
                enter <= '0';
                next_state <= s0;
            elsif B = '1' then
                next_state <= s2;
            end if;


    when s2 =>
            if A = '0' then
                next_state <= s3;
            elsif B = '0' then
                next_state <= s1;
            end if;

    when s3 => 
        if B = '0' then
            enter <= '0';
            next_state <= s0;
        elsif A = '1' then
            next_state <= s2;
        end if;

    when others =>

    end case;
end process p2;


p3: process(current_state,A,B)
begin

case current_state is
    when s1 =>
        if enter = '0' and A = '0' and empty_bf = '0' then
            park_counter <= park_counter - 1;
            free_park_counter <= free_park_counter + 1;
            ERROR <= '0';
        end if;

    when s3 =>
        if enter = '1' and B = '0' and full_bf = '0' then
            park_counter <= park_counter + 1;
            free_park_counter <= free_park_counter - 1;
            ERROR <= '0';
        end if;

    when others =>

    end case;
end process p3;

max: process(WE)
begin

if clk'event and clk = '1' and WE = '1' then
    PARKTOTAL <= DIN ;
    buffr <= DIN ;
    if (free_park_counter < buffr - park_counter) then
        ERROR <= '1';
        reset_b <= '1';
    else    free_park_counter <=  buffr - park_counter;
    end if;
end if;

end process max;

incr: process(free_park_counter,DIN)
begin
PARKFREE <= free_park_counter;
if (free_park_counter = 15) then
    EMPTY <= '1';
    empty_bf <= '1';
else    EMPTY <= '0';
        empty_bf <= '0';
end if;
if (free_park_counter = 0) then
    FULL <= '1';
    full_bf <= '1';
else    FULL <= '0';
        full_bf <= '0';
end if;

end process incr;







end Behavioral;

我的测试平台

-----------------------------------------------------------------------------    ---
-- Company: 
-- Engineer:
--
-- Create Date:   02:17:07 07/11/2015
-- Design Name:   
-- Module Name:   D:/Users/ErgasiaFPGA/Testbench.vhd
-- Project Name:  ErgasiaFPGA
-- Target Device:  
-- Tool versions:  
-- Description:   
-- 
-- VHDL Test Bench Created by ISE for module: Module_1
-- 
-- Dependencies:
-- 
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
-- Notes: 
-- This testbench has been automatically generated using types std_logic and
-- std_logic_vector for the ports of the unit under test.  Xilinx recommends
-- that these types always be used for the top-level I/O of a design in order
-- to guarantee that the testbench will bind correctly to the post-implementation 
-- simulation model.
--------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

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

ENTITY Testbench IS
END Testbench;

ARCHITECTURE behavior OF Testbench IS 

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

COMPONENT Module_1
PORT(
     A : IN  std_logic;
     B : IN  std_logic;
     WE : IN  std_logic;
     reset : IN  std_logic;
     clk : IN  std_logic;
     DIN : IN  signed(3 downto 0);
     FULL : OUT  std_logic;
     EMPTY : OUT  std_logic;
     ERROR : OUT  std_logic;
     PARKFREE : OUT  signed(3 downto 0)
    );
END COMPONENT;


   --Inputs
   signal A : std_logic := '0';
   signal B : std_logic := '0';
   signal WE : std_logic := '0';
   signal reset : std_logic := '0';
   signal clk : std_logic := '0';
   signal DIN : signed(3 downto 0) := (others => '0');

--Outputs
   signal FULL : std_logic;
   signal EMPTY : std_logic;
   signal ERROR : std_logic;
   signal PARKFREE : signed(3 downto 0);

   -- Clock period definitions
   constant clk_period : time := 10 ns;

BEGIN

-- Instantiate the Unit Under Test (UUT)
   uut: Module_1 PORT MAP (
      A => A,
      B => B,
      WE => WE,
      reset => reset,
      clk => clk,
      DIN => DIN,
      FULL => FULL,
      EMPTY => EMPTY,
      ERROR => ERROR,
      PARKFREE => PARKFREE
    );

   -- Clock process definitions
   clk_process :process
   begin
    clk <= '0';
    wait for clk_period/2;
    clk <= '1';
    wait for clk_period/2;
   end process;


   -- Stimulus process
   stim_proc: process
   begin        
      -- hold reset state for 100 ns.
    reset <= '1' ;
  wait for 100 ns;  
    reset <= '0' ;
  wait for clk_period*10;

  -- insert stimulus here 
    A <= '1' ;
    wait for clk_period*5;
    B <= '1' ;
    wait for clk_period*5;
    A <= '0' ;
    wait for clk_period*5;
    B <= '0' ;
    wait for clk_period*5;
    B <= '1' ;
    wait for clk_period*5;
    A <= '1' ;
    wait for clk_period*5;
    B <= '0' ;
    wait for clk_period*5;
    A <= '0' ;
  wait;
   end process;

END;

我发布了整个代码以防万一我在其中的某些部分遗漏了一些我不会想到的东西。所以,当我模拟它时,使用 p3 的任何 "succesful" 触发器...

在这里再次引用它:

p3: process(current_state,A,B)
begin

case current_state is
    when s1 =>
        if enter = '0' and A = '0' and empty_bf = '0' then
            park_counter <= park_counter - 1;
            free_park_counter <= free_park_counter + 1;
            ERROR <= '0';
        end if;

    when s3 =>
        if enter = '1' and B = '0' and full_bf = '0' then
            park_counter <= park_counter + 1;
            free_park_counter <= free_park_counter - 1;
            ERROR <= '0';
        end if;

    when others =>

    end case;
end process p3;

...ISim 在这部分说

"There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es)."

并继续对该部分之后的一些值进行 Xs,尽管所有信号都已初始化(至少这部分中的信号)

"park_counter <= park_counter + 1;" 部分在模拟中正确工作,但 "free_park_counter <= free_park_counter -1;" 部分不正确。这完全让我感到困惑,因为它们被声明为相同的类型并且都以相同的方式初始化,即使具有不同的值。

那么我错过了什么,甚至做错了什么?任何帮助将不胜感激。只寻找错误,如果你能包含优化,因为我希望通过反复试验和思考来学习,并希望自己努力让它变得更好

此外,请耐心等待我的回复,因为我每天登录2到3次。提前致谢

在 ISim 中,如果您浏览左侧的树形菜单,您可以添加信号 window 任何您想要的内部信号。添加所有这些,重新运行模拟并查找具有 'U'|'X'|'W'|'Z'|'-' 值的信号。这应该可以帮助我们找到问题所在。

如果您真的是 VHDL 新手,我的这个回答应该可以帮助您理解这种描述语言的一些基本概念:)

另外一个我辛苦学到的建议,但是你可以在我们解决了这个问题之后再想一想:教科书甚至 Xilinx 都描述了如何用两个甚至三个不同的进程来实现有限状态机。这来自一种教育方法,其中 FSM 分为同步逻辑和异步逻辑。实际上,这样做弊大于利:大多数 FSM 都可以用单个同步进程来描述。 Google 它(或者如果你有兴趣我们可以讨论)并尝试它,你会很快掌握它的窍门并且它会真正简化代码(你甚至不需要两个单独的信号来状态了!)。

问题标题有些混乱:声明信号和设置其值是完全分开的。

初始化信号(在声明中)会影响它的值,但不能完全确定它。如果初始化和另一个驱动值不同,结果可能是'X'。同样,如果信号是由不同意其值的不同进程驱动的。

现在,您使用的是 multiple-process 形式的状态机,其中操作分为时钟进程和组合进程。这些被不止一本教科书推荐。这很不幸,因为众所周知它们很难正确,例如,片刻的检查会显示进程 P3 上的敏感度列表是错误的。

修复 P3 的敏感度列表可能不会影响该问题,因为 P3 还在所谓的组合循环中驱动自己的输入。考虑到,如果进程由于其敏感列表中的组合输入出现故障而多次唤醒,则添加将发生多次...

以单个时钟进程 P1 的形式重写这三个进程(不幸的是,在一些教科书中没有很好地讲授)将避免所有这些困难。

根据 Brian 的回答,您的设计 non-workable。在时钟边沿之前从 s3 或 s1 到 s0 时,您的测试台会产生消息。 free_park_counter 转到 'U' 秒。 (一旦它得到 U's 它就不会进一步循环,没有信号值变化就不会发生任何事件)。

您的计数器应该被计时以防止组合循环,而且由于不均匀的组合延迟,它们可能不会有用地合成时钟。灵敏度列表同样应该是完整的,如果没有其他原因只是为了使模拟与合成结果相匹配。

查看测试台的结果:

(可点击)

我们可以将其与 Synopsys 包 std_logic_arith:

中算术运算符的消息进行比较

../../../src/synopsys/std_logic_arith.vhdl:315:20:@350ns:(assertion warning): There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
../../../src/synopsys/std_logic_arith.vhdl:315:20:@350ns:(assertion warning): There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
../../../src/synopsys/std_logic_arith.vhdl:315:20:@550ns:(assertion warning): There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).

波形中显示的信号是按照重要性和出现的顺序选择的,这是第一轮选择,我们立即看到我们在 free_park_counterERROR 上也得到了 'U's .

ERROR 引起注意是因为您之前没有提到它。当询问 [​​=54=] 时,很明显问题是 ERRORfree_park_counterp3max 两个进程中都有 driver。这些消息是副作用。

每个进程分配一个信号提供一个driver。具有多个 driver 的信号要么被解析,要么导致 non-resolved 类型的错误。

free_park_counter 的解析值具有一个或多个具有元值的元素将导致包 std_logic_arith 生成诊断消息。波形中的'U'是两个driver的分辨率造成的。

您的听众难以注意到这两个 driver 可能部分是由于您强烈坚持关注过程 p3,但没有明确说明。您的问题的标题和重点似乎也不清楚。如果没有一个最小的完整和可验证的例子,那么审查也必然会减少。

您可能希望至少将对 ERRORfree_park_counter 的所有分配合并到一个进程中。 ERROR 应该会被注册,我希望名为 park_counter 的东西也可能会被注册。