2017-10-29 1 views
0

VHDLで一般的なNビットALUを作成しています。加算のために桁上げの値を代入すること、または減算のために借りることができません。私は、次のことを試してみました:VHDL ALUのキャリー/ボロー

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.NUMERIC_STD.ALL; 

entity alu is 
    generic(n: integer :=1); --Default to 1 
    port (
     a : in std_logic_vector(n-1 downto 0); 
     b : in std_logic_vector(n-1 downto 0); 
     op : in std_logic_vector(1 downto 0); 
     output : out std_logic_vector(n-1 downto 0); 
     carryborrow: out std_logic 
    ); 
end alu; 

architecture Behavioral of alu is 
    signal result: std_logic_vector(n downto 0); 
begin 
process(a, b, op) 
begin 
    case op is 
    when "00" => 
     result(n) <= '0'; 
     result(n-1 downto 0) <= a and b; --and gate 
     output <= result(n-1 downto 0); 
     carryborrow <= '0'; 
    when "01" => 
     result(n) <= '0'; 
     result(n-1 downto 0) <= a or b; --or gate 
     output <= result(n-1 downto 0); 
     carryborrow <= '0'; 
    when "10" => 
     result(n) <= '0'; 
     result(n-1 downto 0) <= std_logic_vector(signed(a) + signed(b)); --addition 
     output <= result(n-1 downto 0); 
     carryborrow <= result(n); 
    when "11" => 
     result(n) <= '0'; 
     result(n-1 downto 0) <= std_logic_vector(signed(a) - signed(b)); --subtraction 
     output <= result(n-1 downto 0); 
     carryborrow <= result(n); 
    when others => 
     NULL; 
    end case; 

end process; 

end Behavioral; 

これは、常に私はそれが型エラーなしでどうあるべきかに割り当てることができますどのように0にcarryborrowビットを設定しているようですか?

+0

は[CARRYフラグとオーバーフローフラグにを読んで考えてみましょう:

だから、あなたのキャリー出力がandor操作で動作するようにである方法についての仮定を作る、これは私があなたのコードを書かれているだろうかですバイナリ演算](http://teaching.idallen.com/dat2343/10f/notes/040_overflow.txt)のすべての方法。バイナリ符号付き数値(2'sC)は、符号ビットを介してキャリーからオーバーフローする可能性があります。あなたは符号なし算術を行うことを意味しますか? – user1155120

+0

@ user1155120だから私はベクトルを 'signed'に変換するべきではないでしょうか? –

+0

テストベンチがありません。コードをテストするのが通常の方法です。何がうまくいかなかったかを示します。 – JHBonarius

答えて

3

あなたのコードにバグがあります

i)があなたのアカウントに信号がすぐに更新されていないという事実を取っていません。したがって、私はあなたが期待していると思うと、次の行ではないだろう。

result(n) <= '0'; 
    result(n-1 downto 0) <= a and b; --and gate 
    output <= result(n-1 downto 0); 

を代わりに、あなたは以下を参照することができますよう、組み合わせプロセス外outputcarryborrowを駆動ラインを取る必要があります。 ii)このコードを合成可能にすると仮定すると、NULLをalwaysブランチに入れるだけで、ラッチが推論されます。他のブランチでもresultを運転する必要があります。

architecture Behavioral of alu is 
    signal result: std_logic_vector(n downto 0); 
begin 
process(a, b, op) 
begin 
    case op is 
    when "00" => 
     result <= '0' & (a and b); --and gate 
    when "01" => 
     result <= '0' & (a or b); --or gate 
    when "10" => 
     result <= std_logic_vector(resize(signed(a), n+1) + resize(signed(b), n+1)); --addition 
    when "11" => 
     result <= std_logic_vector(resize(signed(a), n+1) - resize(signed(b), n+1)); --subtraction 
    when others => 
     result <= (others => 'X'); 
    end case; 
    end process; 

    output <= result(n-1 downto 0); 
    carryborrow <= result(n); 

end Behavioral; 
1

私は通常、次の操作を行います。

result <= std_logic_vector(signed(a(n-1) & a) + signed(b(n-1) & b)); 
result <= std_logic_vector(signed(a(n-1) & a) - signed(b(n-1) & b)); 

サインインして拡張し、結果は1つの余分ビット長であるときに、オーバーフローの世話をするための操作を行います。

+0

この結果、エラーが発生します。「エラー、式でエラーが発生しました」 –

+0

更新された回答を参照してください。 – vipin

+0

@SaraTibbetts 'signed'型の場合と同じことをする' numeric_std'の 'resize'関数を使うこともできますが、' unsigned'型も正しく拡張します。すなわち、 'result <= std_logic_vector(resize(符号付き(a)、n + 1)+サイズ変更(符号付き(b)、n + 1))' –