nビット加算器 / キャリールックアヘッドアダー

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ビット幅にして合成した回路である。