2016-03-19 17 views
1

ALUの結果がゼロであるかどうかをチェックしようとしました。テスト結果はゼロですが、シミュレーションではalu_zeroは '1'ではありません。誰かが私に理由を教えてもらえますか?VHDL:ゼロの結果のチェックが失敗しました

Library IEEE; 
USE IEEE.STD_LOGIC_1164.ALL; 
USE IEEE.STD_LOGIC_UNSIGNED.ALL; 
USE IEEE.NUMERIC_STD.ALL; 

ENTITY alu IS 
PORT(
    alu_operand_A,alu_operand_B:in std_logic_vector(31 downto 0); 
    alu_control:in std_logic_vector(1 downto 0); 
    alu_result:out std_logic_vector(31 downto 0); 
    alu_zero:out std_logic 
); 
END alu; 

ARCHITECTURE behavioral OF alu IS 
    signal s_alu_result:std_logic_vector(31 downto 0); 
    BEGIN 
    PROCESS(alu_operand_A,alu_operand_B,alu_control) 
    BEGIN 
    CASE alu_control IS 
    WHEN "00"=>s_alu_result<=alu_operand_A + alu_operand_B; 
       alu_result<=alu_operand_A + alu_operand_B; 
    WHEN "01"=>s_alu_result<=alu_operand_A - alu_operand_B; 
       alu_result<=alu_operand_A - alu_operand_B; 
    WHEN "10"=>s_alu_result<=alu_operand_A and alu_operand_B; 
       alu_result<=alu_operand_A and alu_operand_B; 
    WHEN "11"=>s_alu_result<=alu_operand_A or alu_operand_B; 
       alu_result<=alu_operand_A or alu_operand_B; 
    WHEN OTHERS=>alu_result<=(others=>'X'); 
    END CASE; 

    if s_alu_result="00000000000000000000000000000000" then 
    alu_zero<='1'; 
    else 
    alu_zero<='0'; 
    end if; 
    END PROCESS; 

END behavioral; 

screenshot reference

+1

プロセスセンシティビティリストにs_alu_resultを入れてみてくださいまたはプロセスでそれを割り当てるのではなくalu_zeroする同時の条件付き信号の割り当てを作成したり、プロセス変数を使用しますs_alu_resultの仲介変数として使用し、ゼロをテストします。 – user1155120

答えて

0

あなたのコード内の概念の誤差は信号の割り当てはすぐに行われていないこと、です。代わりに、after句で遅延を指定しないと、新しい信号値は次のデルタサイクルのためにスケジュールされます。しかし、s_alu_resultは機密性リストではないので、プロセスは再度実行されません。したがって、はまだチェックで 'U'なので、alu_zeroは '1'に割り当てられません。最短修正感度リストにs_alu_resultを追加するために、次のようになります「0」つ全ての定数値を割り当てることによってさらにコードを最小限に抑えることができ、より良く理解するため

PROCESS(alu_operand_A,alu_operand_B,alu_control,s_alu_result) 

s_alu_resultをシグナリングするとように、私は正しい動作をmiminするために最後にwait;文を挿入する必要があり、

Library IEEE; 
USE IEEE.STD_LOGIC_1164.ALL; 

ENTITY alu2 IS 
    PORT(
    alu_zero : out std_logic 
    ); 
END alu2; 

ARCHITECTURE behavioral OF alu2 IS 
    signal s_alu_result : std_logic_vector(31 downto 0); 
BEGIN 
    PROCESS 
    BEGIN 
    s_alu_result <= (others => '0'); 

    if s_alu_result="00000000000000000000000000000000" then 
     alu_zero<='1'; 
    else 
     alu_zero<='0'; 
    end if; 

    wait;        -- empty sensitivity list 
    END PROCESS; 
END behavioral; 

感度リストが空になっている:すべての不要な信号や割り当てを削除します。これをシミュレートすると、alu_zeroは '1'ではなく '0'になります。値「0」は、次のデルタサイクルのために信号s_alu_resultに割り当てられます。したがって、すべてのゼロをチェックしても、すべてが 'U'である古い値が使用されます。したがって、条件は偽であり、all_zeroには「0」が割り当てられます。


さらに発言:

  • alu_results_alu_resultを計算し、重複する行を取り除くために、あなたはs_alu_result最初にしてalu_result <= s_alu_result後に割り当てる必要があります。

  • Synopsysの非標準VHDLパッケージstd_logic_unsignedは使用しないでください。代わりにnumeric_stdを使用してください。ビット・シーケンスを符号なしの数として扱う必要があることを示すには、オペランドはstd_logic_vectorの代わりにタイプunsignedでなければなりません。次に、ゼロのチェックを簡略化してs_alu_result = 0にすることもできます。

最終的なコードは次のようになります。

Library IEEE; 
USE IEEE.STD_LOGIC_1164.ALL; 
USE IEEE.NUMERIC_STD.ALL; 

ENTITY alu IS 
PORT(
    alu_operand_A : in unsigned(31 downto 0); 
    alu_operand_B : in unsigned(31 downto 0); 
    alu_control : in std_logic_vector(1 downto 0); 
    alu_result : out unsigned(31 downto 0); 
    alu_zero  : out std_logic 
); 
END alu; 

ARCHITECTURE behavioral OF alu IS 
    signal s_alu_result : unsigned(31 downto 0); 
BEGIN 
    PROCESS(alu_operand_A, alu_operand_B, alu_control, s_alu_result) 
    BEGIN 
    CASE alu_control IS 
     WHEN "00" => s_alu_result <= alu_operand_A + alu_operand_B; 
     WHEN "01" => s_alu_result <= alu_operand_A - alu_operand_B; 
     WHEN "10" => s_alu_result <= alu_operand_A and alu_operand_B; 
     WHEN "11" => s_alu_result <= alu_operand_A or alu_operand_B; 
     WHEN OTHERS => s_alu_result <= (others => 'X'); 
    END CASE; 

    alu_result <= s_alu_result; 

    if s_alu_result = 0 then 
     alu_zero <= '1'; 
    else 
     alu_zero <= '0'; 
    end if; 
    END PROCESS; 

END behavioral; 
関連する問題