2015-07-11 66 views
0

刚刚开始学习如何使用这个工具,所以如果我的问题似乎很愚蠢,我提前道歉。我已经搜索了许多论坛上的错误(已经回答的帖子,不是我的),无法理解我在做什么错了,所以这里是我的问题:赛灵思/ ISim似乎声称价值是X,但它已被宣布

我的行为准则:

----------------------------------------------------------------------------- ----- 
-- 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)。“

并前进到做出的一些部分后的值XS,虽然所有的信号都被初始化(至少在该部分的那些)

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

那么我错过了什么,甚至做了明显的错误?任何帮助将不胜感激。只是寻找错误,如果你可以请包含优化,因为我期待通过反复试验和思考来学习,并且想努力使自己变得更好我自己

此外,请耐心等待我的回复,因为我每天登录2至3次。在此先感谢

+0

试验代码,我现在有以下观察: 使得park_counter和free_park_counter的值相同(“0000”),使得它们都在p3时递增,当我的测试平台实例化这种情况并将它们声明为同一条线。 park_counter工作,free_park_counter和以前一样。我觉得这很傻,任何人有任何想法? – stonedevil

回答

1

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

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

看你的测试平台的结果:

stonedevil.png (点击)

我们可以比较,与来自Synopsys的std_logic_arith发现算术运算符消息:

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

波形显示的信号的重要性和外观的第一通选择的顺序选择,我们立即看到我们也得到'U' S于free_park_counter以及ERROR

ERROR备受关注,因为您之前没有提及过。当询问''U'从哪里来?'很明显问题是ERRORfree_park_counter在驱动程序p3max中都有。这些消息是一个副作用。

每个分配信号的进程都提供一个驱动程序。包含多个驱动程序的信号会被解析或导致未解析类型的错误。

解决的free_park_counter值与一个或多个具有metavalue的元素将导致由std_logic_arith包产生的诊断消息。波形中的'U' s是由两个驱动器的分辨率引起的。

您的观众在注意到这两位车手时遇到的困难可能部分是由于您坚持以过程p3为重点,这个过程没有详细说明。你的问题的标题和焦点似乎也有点不清楚。如果没有一个最小完整和可验证的例子,也必然会受到较少的审查。

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

+0

@布莱恩约我花了一个星期,但我通读了布莱恩发布的所有文章,我认为我对各方面的情况有了更好的理解,至少更完整x比我想象的要早。我必须感谢你们在基本水平上对我进行相当多的教育(我从来没有这样做),但是因为user1155120给出了我原来的问题的答案,所以我选择了这个。不管怎样,不要误解我的意思,你们对我最深切的赞赏 – stonedevil

0

在ISim中,如果您浏览左侧的树形菜单,您可以添加到信号窗口然后您需要的任何内部信号。将它们全部添加,重新运行模拟并查找具有'U'|'X'|'W'|'Z'|' - '值的信号。这应该会让我们找到一个领先的问题。

如果你是真正的新VHDL,我这个答案应该帮助你undersand一些本描述语言的基本概念:) VHDL - iSIM output uninitialised, doesn't change states

另一种意见,我学到了艰辛的道路,但你能想到的在我们解决了这个问题之后,关于它:教科书甚至Xilinx描述了如何实现具有两个甚至三个不同进程的有限状态机。这来自FSM在同步逻辑和异步逻辑中分裂的教育方法。实际上,这样做的弊大于利:大多数FSM可以用一个同步过程来描述。谷歌它(或者如果你有兴趣,我们可以谈论它)并尝试它,你会很快得到它的窍门,它会真正简化代码(你甚至不需要为状态两个单独的信号!) 。

+0

这就是我从中得到我的数值,将大部分数值添加到波形中并查看它们在哪里变化以及如何变化的地方。这几乎是我如何尝试和调试整个代码。为了功能的缘故,可能会切换到只使用一个进程,但是这个错误让我感到困惑,并且我非常想知道为什么它会发生。如果您愿意,请在user1155120的回复中查看上述帖子的评论,看看这些值会发生什么。此外,我想说,我也尝试了immediated的加法/减法:free_park_counter <= free_park_counter - 1;“ – stonedevil

+0

忘记提及当发生这种情况时,值已经设置好了。 。但是,当“free_park_counter <= free_park_counter -1”出现时,它从1111到111X,我无法弄清楚为什么我的生活 – stonedevil

2

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

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

现在,您正在使用多进程形式的状态机,其中操作在时钟和组合进程之间分开。这些由多个教科书推荐。这很不幸,因为他们很难得到正确的结果,例如,一段时间的检查将显示P3过程的敏感性列表是错误的。

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

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

+0

他在四个敏感性列表中存在缺陷。修复这些问题(没有整合过程),切换到包numeric_std(一个干净的替换)和写一个测试平台我没有得到任何消息。这表明这个问题不是[最小,完整和可验证的例子](http://stackoverflow.com/help/mcve)。如何复制这个问题?毛刺和多个加法可以用'推迟'来解决,但是你真的希望计数器应该是计时的,似乎还有各种其他推断的锁存器。 – user1155120

+0

@布莱恩确实标题写得很糟糕,当你指出它时,必须意识到它,对整个想法感到非常疲惫和沮丧,所以我得到了粗心大意,对不起。如果在一个流程中完成这项工作,你可能是对的,但是我想知道这些类型的错误会发生什么,如果只是为了避免它们在将来的任何项目中出现并理解总体背后的想法。如果我失败了,我可能会切换到1个功能。你能解释一下P3如何驱动它的输入吗?它只会改变内部信号值 – stonedevil

+0

@ user1155120我只是现在正在学习这些东西,但正如我在您的评论中所理解的那样,您几乎说你改变了一堆东西,现在无法复制我的问题?在p3的“当s3 =>”成功完成并执行“free_park_counter <= free_park_counter - plus;”之后,SIM卡中的值将从1111变为111X。另外,在激活第一部分后,现在111X将变成XXXX。这就是发生的事情。如果您认为我也应该发布测试平台,请告诉我这么做。我不认为它会有任何用处 – stonedevil