pp.257-258
内部信号を一種の変数として使う。
inp_vector = 0b11110011の場合:
1回目のループ: inp_vector[0]に1が立っているので internal[1]にinternal[0]+1 = 1を入れる。
2回目のループ: inp_vector[1]に1が立っているので internal[2]にinternal[1]+1 = 2を入れる。
3回目のループ: inp_vector[2]に1が立っていないのでinternal[3]にinternal[2] = 2を入れる。
4回目のループ: inp_vector[3]に1が立っていないのでinternal[4]にinternal[3] = 2を入れる。
5回目のループ: inp_vector[4]に1が立っているので internal[5]にinternal[4]+1 = 3を入れる。
6回目のループ: inp_vector[5]に1が立っているので internal[6]にinternal[5]+1 = 4を入れる。
7回目のループ: inp_vector[6]に1が立っているので internal[7]にinternal[6]+1 = 5を入れる。
8回目のループ: inp_vector[7]に1が立っているので internal[8]にinternal[7]+1 = 6を入れる。
......
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity hamming_weight_calculator is generic( BITS_IN : positive := 16; -- 入力を16ビットとすると、ハミング重みは最大16なので、 BITS_OUT: positive := 5 -- 出力は最大0b10000、すなわち5ビット = ceil(log2(BITS_IN+1)) ); port( inp_vector : in std_logic_vector(BITS_IN -1 downto 0); hamm_weight: out std_logic_vector(BITS_OUT-1 downto 0) ); end entity; architecture rtl of hamming_weight_calculator is -- {int[0], int[1], ..., int[16]}という1Dx1D排列型integer_arrayを定義して、 -- その型の信号internalを宣言する。 -- 要するに途中の計算結果を入れておくための信号(内部変数として使う)を16個用意しておく。 type integer_array is array(0 to BITS_IN) of integer range 0 to BITS_IN; signal internal: integer_array; begin internal(0) <= 0; gen: for i in 1 to BITS_IN generate internal(i) <= internal(i-1) + 1 when inp_vector(i-1) else internal(i-1); end generate; -- internal(16)を5ビット幅のunsingedに変換して、それをさらにベクタに変換する。 hamm_weight <= std_logic_vector(to_unsigned(internal(BITS_IN), BITS_OUT)); end architecture;