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) になります。"

すべての信号は初期化されていますが (少なくともこの部分の信号は)、その部分の後にいくつかの値の X を作成します。

「park_counter <= park_counter + 1;」パーツはシミュレーションで正しく動作しますが、「free_park_counter <= free_park_counter -1;」しません。これらは同じ型として宣言されており、値が異なっていても同じように初期化されているため、これは私を完全に困惑させます。

それで、私は何が欠けているのか、あるいは露骨に間違っているのでしょうか? どんな助けでも信じられないほど高く評価されます。エラーのみを探しています。試行錯誤と思考を通じて学び、自分で改善するのに苦労したいので、最適化を含めていただければ幸いです

また、私は 1 日に 2 ~ 3 回ログオンするので、返信にはしばらくお待ちください。前もって感謝します

4

3 に答える 3

1

ブライアンの回答によると、あなたのデザインは機能しません。クロック エッジの前に 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:(アサーション警告): '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'free_park_counterますERROR

ERRORあなたが以前に言及していなかったので、注目を集めます。'U'「どこから来たの?」と尋ねるとき 問題は、プロセスとプロセスの両方にドライバーがあることが明らかERRORfree_park_counterなりp3ますmax。メッセージは副作用です。

シグナルを割り当てる各プロセスは、ドライバーを提供します。複数のドライバーを持つシグナルは、解決されるか、解決されないタイプのエラーになります。

メタ値を持つ 1 つ以上の要素を持つ の解決された値はfree_park_counter、パッケージ std_logic_arith によって生成される診断メッセージを引き起こします。'U'波形のs は、2 つのドライバーの解像度が原因です。

視聴者が 2 つの要因に気付くのが難しかった理由の 1 つは、プロセスに焦点を当てることへの強い主張が原因である可能性がありますがp3、これは明確に規定されていません。あなたの質問のタイトルと焦点も少し不明確なようです。最小限の完全で検証可能な例がなければ、精査も少なくなるはずです。

少なくとも、すべての割り当てを1 つのプロセス ERRORに統合することを期待するかもしれません。登録される可能性が高く、名前付きのものも登録される可能性が高いと思います。free_park_counterERRORpark_counter

于 2015-07-12T03:28:52.827 に答える
1

質問のタイトルには混乱があります。シグナルの宣言とその値の設定は完全に別です。

(宣言で) シグナルを初期化すると、その値に影響しますが、完全には決定されません。初期化と別の駆動値が異なる場合、結果はおそらく「X」になります。同様に、信号がその値に同意しない異なるプロセスから駆動されている場合。

ここで、複数プロセス形式のステート マシンを使用しています。この場合、動作はクロック プロセスと組み合わせプロセスに分割されます。これらは複数の教科書で推奨されています。これは残念なことです。なぜなら、それらを正しくするのは難しいことで知られているからです。たとえば、ちょっと調べただけで、プロセス P3 のセンシティビティ リストが間違っていることがわかります。

P3 のセンシティビティ リストを修正しても、問題に影響しない可能性があります。これは、P3 も組み合わせループとして知られる方法で独自の入力を駆動するためです。センシティビティ リストの組み合わせ入力のグリッチが原因でプロセスが数回ウェイクアップする場合、追加が数回行われることを考慮してください...

これらの 3 つのプロセスを単一のクロック プロセス P1 の形式で書き直すと (残念ながら、いくつかの教科書では十分に教えられていません)、これらの問題をすべて回避できます。

于 2015-07-11T10:13:32.900 に答える
0

ISim では、左側のツリー メニューを参照すると、必要な内部信号を信号ウィンドウに追加できます。それらをすべて追加し、シミュレーションを再実行して、値が 'U'|'X'|'W'|'Z'|'-' である信号を探します。これにより、問題を追跡する手がかりが得られるはずです。

あなたがVHDLに本当に慣れていない場合、この私の答えは、この記述言語の基本的な概念のいくつかを理解するのに役立つはずです:) VHDL - 初期化されていないiSIM出力、状態を変更しません

私が苦労して学んだもう 1 つのアドバイスですが、この問題を解決した後に考えることができます。教科書やザイリンクスでさえ、2 つまたは 3 つの異なるプロセスで有限ステート マシンを実装する方法を説明しています。これは、FSM を同期ロジックと非同期ロジックに分割するという教育的アプローチに由来します。実際には、これは良いことよりも害を及ぼしています。ほとんどの FSM は、単一の同期プロセスで記述できます。Google で検索して (または、興味がある場合は、それについて話すことができます)、試してみてください。すぐにコツをつかむことができ、コードが非常に単純になります (状態に対して 2 つの別個の信号はもう必要ありません!) .

于 2015-07-11T10:06:46.967 に答える