pp.261-262
+
演算子の場合、出力のビット幅は、複数ある入力のうち最大のビット幅と同じでなければならない。
VHDL 2008ではsigned
とシングルビット値とが加算できるようになったらしいがQuartus Prime Liteはまだサポートしていないようなので、下のコードでは'0' & cin
のように0を連結して無理矢理ベクタにした。
複数ある入力は、1つだけを符号拡張して出力ビット幅に合わせればよい。
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity adder_signed is generic( NUM_BITS: integer := 4 ); port( -- 原則1: 入出力ポートはstd_logic型、std_logic_vector型にする。 a, b: in std_logic_vector(NUM_BITS-1 downto 0); cin : in std_logic; sum: out std_logic_vector(NUM_BITS-1 downto 0); cout, oflow, sumMSB: out std_logic ); end entity; architecture rtl of adder_signed is -- 加算値を假置きするための信号を定義する。 signal sum_sig: signed(NUM_BITS downto 0); begin -- 原則2: 演算型に変換してから演算をする。シングルビットはそのままでよい。 -- キャリーアウト、オーバーフローを得るため1ビット増やして加算する。 sum_sig <= resize(signed(a), NUM_BITS+1) + signed(b) + ('0' & cin); -- 原則3: std_logic型、std_logic_vector型に変換してから出力する。シングルビットはそのままでよい。 -- 加算結果(キャリーアウト、オーバーフローは含めない)を出力する。 sum <= std_logic_vector(sum_sig(NUM_BITS-1 downto 0)); -- 加算結果(キャリーアウト、オーバーフローは含める)の最上位ビットを出力する。 sumMSB <= sum_sig(NUM_BITS); cout <= a(NUM_BITS-1) xor b(NUM_BITS-1) xor sumMSB; oflow <= sumMSB xor sum(NUM_BITS-1); end architecture;