pp.138-143
nビット加算器 / リップルキャリーアダー / キャリーの遅延する様子を見る -の続き
もちろん普通はロジック回路を組むようなことはせずにただ+
演算子を使って足し算をするだけである。
上の式から分かるように、p、gを生成する手段としてandゲートまたはorゲートが1段、各項を求めるためのandゲートが1段、最後に全項のorを求めるためのorゲートが1段、全部で3ゲート分の遅延が生じる。このことはビット幅とは無関係である。
ひとまず確認のため2ビット幅の加算器を作ってみる。Figure 3.15と同じ回路が出来る。
ファイル一式: VHDL_for_Quartus_Prime/n_bits_adder_lookahead at main · ti-nspire/VHDL_for_Quartus_Prime · GitHub
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_misc.all; entity n_bits_adder_lookahead is generic ( NUM_BITS: natural := 2 ); port ( c0: in std_logic; x: in std_logic_vector(NUM_BITS-1 downto 0); y: in std_logic_vector(NUM_BITS-1 downto 0); cout: out std_logic; s: out std_logic_vector(NUM_BITS-1 downto 0) ); end entity; architecture logic of n_bits_adder_lookahead is signal g: std_logic_vector(NUM_BITS-1 downto 0); signal p: std_logic_vector(NUM_BITS-1 downto 0); signal c: std_logic_vector(NUM_BITS downto 0); type type_1dx1d is array(1 to NUM_BITS) of std_logic_vector(NUM_BITS-1 downto 0); signal term: type_1dx1d; --attribute keep: boolean; --attribute keep of g, p, c, term: signal is true; begin c(0) <= c0; g <= x and y; p <= x or y; process(g, p, c, term) begin for i in 1 to NUM_BITS loop for j in 0 to i-1 loop if j=0 then term(i)(j) <= and_reduce(p(i-1 downto 0) & c(0)); else term(i)(j) <= and_reduce(p(i-1 downto j) & g(j-1)); end if; c(i) <= or_reduce(g(i-1) & term(i)(j downto 0)); end loop; end loop; end process; cout <= c(NUM_BITS); s <= x xor y xor c(NUM_BITS-1 downto 0); end architecture;
ビット幅を増やすと急激に回路が複雑化する。下の図は8ビット幅にして合成した回路である。