絶対差の和(マンハッタン距離)を求める

pp.265-267
a = {2ビットsigned値, 2ビットsigned値, 2ビットsigned値, 2ビットsigned値}
b = {2ビットsigned値, 2ビットsigned値, 2ビットsigned値, 2ビットsigned値}
という2ビットsigned値×4要素同士の差の絶対値の和を求める。4要素だと加算が2レイヤー必要なので出力は2ビット増えて4ビット必要である。

まずこういうパッケージをつくって排列型を宣言しておく。
user_defined_type_pkg.vhd

library ieee;
use ieee.numeric_std.all;
package user_defined_type_pkg is
   -- 入力信号用の排列型を宣言する。signed整数 × 要素数naturalの排列。
    type signed_array is array(natural range <>) of signed;
    
   -- 出力信号用の排列型を宣言する。unsigned整数 × 要素数naturalの排列。
    type unsigned_array is array(natural range <>) of unsigned;
end package;

トップvhd

library ieee;
use ieee.numeric_std.all;
use work.user_defined_type_pkg.all;

entity abs_difference_calculator is
    generic(
        NUM_BITS    : natural := 2;
        NUM_ELEMENTS: natural := 4
    );
    port(
       -- ここでは2ビット値×4要素の排列。
        a, b: in signed_array(0 to NUM_ELEMENTS-1)(NUM_BITS-1 downto 0);
        
       -- ここでは2ビット値の加算が2レイヤー必要なのでビットが2つ増えて4ビット値。
        abs_difference: out unsigned(NUM_BITS+1 downto 0)
    );
end entity;

architecture rtl of abs_difference_calculator is
   -- 差の絶対値を格納しておくための信号を宣言する。
   -- 最終的な出力に合わせて4ビット値×4要素の排列信号。
    signal abs_diff_vector: unsigned_array(0 to NUM_ELEMENTS-1)(NUM_BITS+1 downto 0);
begin
    gen_diff_vec: for i in 0 to NUM_ELEMENTS-1 generate
       -- 差の絶対値を計算する。
       -- 最終的な出力に合わせて4ビットにしてから計算する。
        abs_diff_vector(i) <= unsigned(abs(resize(a(i), NUM_BITS+2) -
                                           resize(b(i), NUM_BITS+2)));
    end generate;
    
   -- ツリータイプで加算する。
    abs_difference <= (abs_diff_vector(0) + abs_diff_vector(1)) +
                      (abs_diff_vector(2) + abs_diff_vector(3));
end architecture;

今a={1,1,1,1}、b={-2,-2,-2,-2}を入力しているので要素同士の絶対差は{3,3,3,3}、その和は12=0b1100
f:id:ti-nspire:20210414105222j:plain:w500