1

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

我的行为准则:

-----------------------------------------------------------------------------    -----
-- 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次,请耐心等待我的回复。提前致谢

4

3 回答 3

1

There is some confusion in the question title : declaring a signal and setting its value are entirely separate.

Initialising a signal (in the declaration) will influence its value, but not fully determine it. If the initialisation and another driving value are different, the result probably will be 'X'. Likewise if the signal is driven from different processes which disagree on its value.

Now, you are using a multiple-process form of state machine, where the operations are split between clocked and combinational processes. These are recommended by more than one textbook. This is unfortunate because they are notoriously difficult to get right, and for example, a moment's inspection will show that the sensitivity list on process P3 is wrong.

Fixing P3's sensitivity list may not affect the problem, because P3 also drives its own inputs in what is known as a combinational loop. Consider that, if the process wakes up several times because of glitches on the combinational inputs in its sensitivity list, the additions will take place several times...

Rewriting these three processes in the form of a single clocked process P1, (which is, unfortunately, not well taught in several textbooks) will avoid all of these difficulties.

于 2015-07-11T10:13:32.900 回答
1

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

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

查看测试台的结果:

石头恶魔.png (可点击)

我们可以将其与 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)。

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

ERROR引起注意是因为您之前没有提到它。当问''U'从哪里来?很明显,问题是在两个进程ERROR和. 这些消息是副作用。free_park_counterp3max

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

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

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

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

于 2015-07-12T03:28:52.827 回答
0

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

如果您真的是 VHDL 的新手,我的这个答案应该可以帮助您理解这种描述语言的一些基本概念 :) VHDL - iSIM 输出未初始化,不会改变状态

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

于 2015-07-11T10:06:46.967 回答