2017-02-12 152 views
0

VHDLには新しく(3週間)、最新の割り当てでは単純な4ビット加算器でオーバーフローチェックを実装することに問題があります:4ビット加算器/減算器(VHDL)でオーバーフローチェックを実装する

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.STD_LOGIC_UNSIGNED.ALL; 

entity add_sub_4bit is 
    Port (a : in STD_LOGIC_VECTOR(3 downto 0); 
      b : inout STD_LOGIC_VECTOR(3 downto 0); 
       sel: in STD_LOGIC); 
      --sum : inout STD_LOGIC_VECTOR(3 downto 0) 
end add_sub_4bit; 

architecture Behavioral of add_sub_4bit is 
signal localflow : STD_LOGIC; 
signal localsum : STD_LOGIC_VECTOR (3 downto 0); 

begin 
    localsum <= a + b when sel = '1' 
    else 
    a - b; 
process(a,b,localsum) begin 
    if a(3) = '0' AND b(3) = '0' AND localsum(3) = '1' then 
     localflow <= '1'; 
    elsif a(3) = '1' AND b(3) = '1' AND localsum(3) = '0' then 
     localflow <='1'; 
    else 
     localflow <='0'; 
    end if; 
end process; 
end Behavioral; 

すぐ、テストケースのようなある: A = 5、B = -3、SELに0を与えることは、1つの減算を追加します。 A = 6、B = 2、ほとんど同じことをしています。

ここで、数字が署名されているとしたら、もちろん2の補数なので結果も同じです。しかし、オーバーフローは6(0110)と2(0010)を加算して-8(1000)を出力する場合にしか検出できません。これは明らかに4ビットのオーバーフローの場合です。しかし、5 - ( - 3)を実行すると、結果はまったく同じ1000になりますが、私は2つの異なる符号を与えているので、私の方法でオーバーフローを検出することはできません。

先生たちはSELの値に応じて、Bの符号を変更することが示唆されている - 私はそれに基づいて、B < = B +「1000」を作るようなものを試してみましたが、それは助けにはならなかった、と私は知りません他の方法の、非常に言語に新しいです。適切なプログラムを取得するために私は何ができますか?ありがとうございました。まず

+1

HW減算では、Bの2の補数を追加します(b + 1ではなく)+ 1はキャリーインを使用します。減算するときは、オーバーフローのための実際のb加算オペランドの符号を使用する必要があります。これは、sel = '1'の場合はopb_sign <= b(3) (3); '。これを別のマルチプレクサ(セレクタ)として表示したり、XORを使用して '(b(3)xor not sel) 'という用語に展開してください。また、元のオーバーフローセレクタを崩壊させると 'localflow <= a(3)xor b(3)xor not sel xor localsum(3);'括弧は不要であり、XORは可換性です。優先度は高くない。 – user1155120

+0

こんにちは、 あなたの提案はうまくいった - 私はadditonal muxと同じプログラムを保った。どうもありがとう! – xen20

答えて

0

use IEEE.STD_LOGIC_UNSIGNED.ALL; 

はそれをしないでください。特に番号に署名を付ける場合。使用することが普通です:

use IEEE.numeric_std.all; 

は、その後、あなたが望むデータのタイプ、例えばにstd_logic_vectorをキャストする必要があります正しい演算のために 'signed'

第2に、inoutを使用しないでください。 VHDLは双方向の割り当てではあまり良くありません。 inまたはoutを使用してください。

ですから、(最良のコードではありませんNB)行うことができ、上記を組み合わせる:

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.numeric_std.ALL; 

entity add_sub_4bit is 
    Port (
     a : in STD_LOGIC_VECTOR(3 downto 0); 
     b : in STD_LOGIC_VECTOR(3 downto 0); 
     sel: in STD_LOGIC; 
     sum : out STD_LOGIC_VECTOR(3 downto 0); 
     overflow : out std_logic 
     ); 
end add_sub_4bit; 

architecture Behavioral of add_sub_4bit is 
signal localflow : STD_LOGIC; 
signal locala, localb, localsum : signed(4 downto 0); -- one bit more then input 
signal sumout : std_logic_vector(4 downto 0); 

begin 
    locala <= resize(signed(a), 5); 
    localb <= resize(signed(b), 5); 
    localsum <= locala + localb when sel = '1' else locala - localb; 
    -- overflow occurs when bit 3 is not equal to the sign bit(4) 
    localflow <= '1' when localsum(3) /= localsum(4) else '0'; 
    -- convert outputs 
    sumout <= std_logic_vector(localsum); 
    --outputs 
    sum <= sumout(4)&sumout(2 downto 0); 
    overflow <= localflow; 
end Behavioral; 

あなたはテストベンチを使用してこれをテストすることができます

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.numeric_std.ALL; 

entity add_sub_4bit_tb is 
end add_sub_4bit_tb; 

architecture Behavioral of add_sub_4bit_tb is 
signal sel : std_logic_vector(0 downto 0); 
signal a, b, sum : std_logic_vector(3 downto 0); 

begin 
    uut: entity work.add_sub_4bit 
    port map (a, b, sel(0), sum); 

    test: process 
    begin 
     for sel_o in 0 to 1 loop 
      sel <= std_logic_vector(to_signed(sel_o, 1)); 
      for a_o in -8 to 7 loop 
       a <= std_logic_vector(to_signed(a_o, 4)); 
       for b_o in -8 to 7 loop 
        b <= std_logic_vector(to_signed(b_o, 4)); 
        wait for 1 ns; 
       end loop; 
      end loop; 
     end loop; 
     wait; 
    end process; 
end Behavioral; 
関連する問題