【问题标题】:Xilinx / ISim seem claims value to be X but it has been declaredXilinx / ISim 似乎声称价值是 X,但它已被宣布
【发布时间】:2015-07-11 00:25:52
【问题描述】:

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

我的行为准则:

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

我发布了整个代码,以防万一我在其中的某些部分遗漏了一些我不会想到的东西。所以,当我 ISim 它时,任何“成功”的 p3 触发器......

在这里再次引用它:

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 在这部分中说

“算术操作数中有一个'U'|'X'|'W'|'Z'|'-',结果将是'X'(es)。”

并继续在该部分之后将某些值设为 X,尽管所有信号都已初始化(至少这部分中的信号)

“park_counter

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

另外,由于我每天登录 2 到 3 次,请耐心等待我的回复。在此先感谢

【问题讨论】:

  • 用代码进行实验,我现在有以下观察结果:使 park_counter 和 free_park_counter 的值相同 ("0000") ,当我的测试台实例化这种情况时,它们都在 p3 处递增,并且在同一行声明它们。 park_counter 工作,free_park_counter 做和以前一样的事情。我觉得这越来越傻了,有人知道吗?

标签: vhdl xilinx xilinx-ise


【解决方案1】:

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

应为您的计数器计时以防止组合循环,此外,由于组合延迟不均匀,它们可能无法有效地合成时钟。如果仅出于使模拟与合成结果匹配的目的,则敏感性列表同样应该是完整的。

查看测试台的结果:

(可点击)

我们可以将其与 Synopsys 包 std_logic_arith 中的算术运算符的消息进行比较:

../../../src/synopsys/std_logic_arith.vhdl:315:20:@350ns:(断言警告):有一个'U'|'X'|'W'|'Z' |'-' 在算术操作数中,结果将是 'X'(es)。
../../../src/synopsys/std_logic_arith.vhdl:315:20:@350ns:(断言警告):有一个'U'|'X'|'W'|'Z'|'- ' 在算术操作数中,结果将是 'X'(es)。
../../../src/synopsys/std_logic_arith.vhdl:315:20:@550ns:(断言警告):有一个'U'|'X'|'W'|'Z'|'- ' 在算术操作数中,结果将是 'X'(es)。

波形中显示的信号是按重要性和外观顺序选择的第一次通过选择,我们立即看到在free_park_counterERROR 上也得到'U's。

ERROR 引起了人们的注意,因为您之前没有提到它。当问“'U' 来自哪里?”时很明显,问题是在ERRORfree_park_counter 两个进程p3max 上都有驱动程序。这些消息是副作用。

每个分配信号的进程都提供一个驱动程序。具有多个驱动程序的信号要么被解析,要么导致未解析类型的错误。

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

您的听众很难注意到这两个驱动因素,部分原因可能是您强烈坚持专注于流程p3,但没有明确说明。您问题的标题和重点似乎也有点不清楚。没有一个最小完整和可验证的例子,也必然会减少审查。

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

【讨论】:

  • @Brian 花了我大约一周的时间,但我通读了 Brian 发布的所有文章,我认为我对正在发生的事情的各个方面有了更好的了解,它至少更复杂比我一开始想的要多。我必须感谢你们俩在一些基本层面上对我进行了很多教育(我无论如何都没有),但是由于 user1155120 给出了我最初问题的答案,所以我选择了这个。无论如何不要误会我的意思,你们有我最深切的感谢
【解决方案2】:

问题标题中存在一些混淆:声明信号和设置其值是完全分开的。

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

现在,您正在使用多进程形式的状态机,其中操作在时钟进程和组合进程之间进行拆分。这些是由不止一本教科书推荐的。这是不幸的,因为它们是出了名的难以正确处理,例如,稍等片刻就会发现进程 P3 上的敏感度列表是错误的。

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

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

【讨论】:

  • 他在四个敏感度列表中存在不足。修复这些(没有整合流程),切换到包 numeric_std (一个干净的替换)并编写一个测试平台我没有收到任何消息。这表明问题不是Minimal, Complete, and Verifiable example。如何复制问题? postponed 可以解决小故障和多次添加,但您确实希望计数器应该计时。似乎还有其他各种推断的闩锁。
  • @Brian 确实标题写得很糟糕,当你指出它时不得不意识到这一点,对整个想法感到非常疲倦和沮丧,所以我粗心了,抱歉。当您说如果在一个过程中完成这可以更干净地完成时,您可能是对的,但我想知道这些类型的错误一般是怎么回事,如果只是为了在未来的任何类型的项目中避免它们并理解它背后的想法一般。如果我失败了,我可能确实会切换到 1 个函数。您能否解释一下 P3 如何驱动其输入?它只改变内部信号值
  • @user1155120 我现在才学习这些东西,但正如我在您的评论中理解的那样,您几乎是在说您更改了很多东西,现在无法复制我的问题?几乎发生在 p3 的“当 s3 =>”成功完成并执行“free_park_counter
  • “您能解释一下 P3 是如何驱动其输入的吗?”是的。 park_counter &lt;= park_counter - plus; 修正 P3 的敏感度列表,这会执行无数次,追逐自己的尾巴。 (是的,发布测试平台。正如其他评论所说,它是最小完整可验证示例的重要组成部分。
  • 您可能会发现此问答有助于了解信号分配、流程调度和敏感度列表的背景故事。 stackoverflow.com/questions/13954193/…
【解决方案3】:

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

如果您真的是 VHDL 新手,我的这个答案应该可以帮助您理解这种描述语言的一些基本概念 :) VHDL - iSIM output uninitialised, doesn't change states

另一个建议是我通过艰难的方式学到的,但是在我们解决了这个问题之后你可以考虑一下:教科书甚至赛灵思都描述了如何实现具有两个甚至三个不同进程的有限状态机。这来自一种教育方法,其中 FSM 分为同步逻辑和异步逻辑。在实践中,这弊大于利:大多数 FSM 可以用单个同步过程来描述。谷歌它(或者如果你有兴趣我们可以谈论它)并尝试它,你会很快掌握它并且它会真正简化代码(你甚至不再需要两个单独的状态信号!) .

【讨论】:

  • 这就是我从中获取值的地方,已将大部分值添加到波形中,并查看它们在哪里以及如何变化。这几乎就是我尝试和调试整个代码的方式。为了功能的缘故,可能会切换到只使用一个进程,但是这个错误令人困惑,我非常想不明白为什么会发生这种情况。如果您愿意,请查看针对 user1155120 的上述帖子的评论,以查看这些值会发生什么情况。另外,我想说的是,我还尝试过使用以下方式进行加法/减法:free_park_counter
  • 忘了提到当这种情况发生时,值已经设置好了。几乎所有值都已设置。但是当“free_park_counter
猜你喜欢
  • 2016-03-04
  • 2016-08-26
  • 1970-01-01
  • 2014-06-28
  • 1970-01-01
  • 2019-06-23
  • 2013-07-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多