让JUST开始学习如何使用这个工具,所以如果我的问题看起来很傻,我会事先道歉。我在很多论坛上搜索过这个错误(已经回复了帖子,而不是我的帖子)并且无法理解我做错了什么,所以这是我的问题:
我的行为准则:
----------------------------------------------------------------------------- -----
-- 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;
My Testbench
----------------------------------------------------------------------------- ---
-- 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 ...
在这里再次引用它:
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&lt; = park_counter + 1;”部分在模拟中正常工作,但“free_park_counter&lt; = free_park_counter -1;”没有。这完全让我感到困惑,因为它们被声明为相同的类型,并且都以相同的方式初始化,即使具有不同的值。
那么我错过了什么,甚至做了明显的错误?任何帮助将非常感激。只查找错误,如果你可以请求优化,因为我希望通过反复试验和思考来学习,并且想努力让自己变得更好
此外,请耐心等待我的回复,因为我每天登录2至3次。提前致谢
答案 0 :(得分:2)
问题标题中存在一些混淆:声明信号并设置其值完全是分开的。
初始化信号(在声明中)将影响其值,但不能完全确定它。如果初始化和另一个驱动值不同,结果可能是&#39; X&#39;。同样,如果信号是由不同的过程驱动的,那么它的价值就不同了。
现在,您正在使用多进程形式的状态机,其中操作在时钟和组合进程之间分配。这些是由多本教科书推荐的。这是不幸的,因为众所周知难以做到正确,例如,片刻的检查会显示过程P3的敏感度列表是错误的。
修复P3的灵敏度列表可能不会影响问题,因为P3也会在所谓的组合循环中驱动自己的输入。考虑一下,如果由于灵敏度列表中组合输入的毛刺,该过程会多次唤醒,则会多次添加...
以单个时钟进程P1的形式重写这三个进程(不幸的是,在几本教科书中没有很好地教授)将避免所有这些困难。
答案 1 :(得分: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 :(断言警告):有一个&#39; U&#39; |&#39; X&# 39; |&#39; W&#39; |&#39; Z&#39; |&#39; - &#39;在算术操作数中,结果将是&#39; X&#39;(es) ../../../src/synopsys/std_logic_arith.vhdl:315:20:@350ns:(警告警告):有一个&#39; U&#39; X&#39; | &#39; W&#39; |&#39; Z&#39; |&#39; - &#39;在算术操作数中,结果将是&#39; X&#39;(es) ../../../src/synopsys/std_logic_arith.vhdl:315:20:@550ns:(警告警告):有一个&#39; |&#39; X&#39; | &#39; W&#39; |&#39; Z&#39; |&#39; - &#39;在算术操作数中,结果将是&#39; X&#39;(es)。
波形中显示的信号按重要性和外观顺序选择第一遍选择,我们立即看到'U'
和free_park_counter
上的ERROR
。{ / p>
ERROR
引起了人们的注意,因为你之前没有提到它。询问'U'
来自何处?&#39;显而易见的问题是,ERROR
和free_park_counter
进程中的p3
和max
都有驱动程序。这些消息是副作用。
分配信号的每个过程都提供了一个驱动程序。具有多个驱动程序的信号要么已解析,要么导致未解析类型出错。
free_park_counter
的解析值与一个或多个具有元值的元素将导致包std_logic_arith生成的诊断消息。波形中的'U'
s由两个驱动程序的分辨率引起。
您的观众在注意到这两位车手时遇到的困难可能部分是由于您强烈坚持专注于流程p3
,而这一点并未明确规定。你的问题的标题和焦点似乎也有点不清楚。如果没有最小的完整和可验证的例子,也必然会受到较少的审查。
您可能希望至少将ERROR
和free_park_counter
的所有作业合并到一个进程中。 ERROR
可能会被注册,并且我预计名为park_counter
的内容也可能会被注册。
答案 2 :(得分:0)
在ISim中,如果您浏览左侧的树状菜单,则可以向信号窗口添加所需的任何内部信号。添加所有这些,重新运行模拟并查找具有&#39;&#39; X&#39; |&#39; W&#39; |&#39; Z&#39; |&#39; - &#39;值。这应该让我们能够追踪问题。
如果你真的是VHDL的新手,我的这个答案可以帮助你理解这种描述语言的一些基本概念:) VHDL - iSIM output uninitialised, doesn't change states
我学到了很多困难的另一个建议,但是在我们解决了这个问题后你可以考虑一下:教科书甚至Xilinx都描述了如何用两个甚至三个不同的过程实现有限状态机。这来自于一种教育方法,其中FSM分为同步逻辑和异步逻辑。实际上,这弊大于利:大多数FSM都可以用单个同步过程来描述。谷歌它(或者如果你感兴趣我们可以谈论它)并尝试它,你将很快掌握它并且它将真正简化代码(你甚至不需要两个单独的信号为状态了!)。