はじめに
別記事 「はじめに」 を参照してください。
この記事では、マージソーター内部で使用するワード比較器(Word_Compare)について説明します。
ワード比較器とは
ワード比較器(Word_Compare)は、二つのワード(「ワードの定義」参照)を比較して、どちらかを選択します。二つのワード(AワードとBワード)のうち、選択した方の選択信号(SEL_A または SEL_B) がアサートされます。また、AワードとBワードが同一条件だった時は常にAワードが選択されます。
Fig.1 Word Compare
ワード比較器の VHDL 記述
Entity
ワード比較器(Word_Compare) の Entity 宣言は次のようになっています。ジェネリック変数の WORD_PARAM でワードの定義を指定します。SORT_ORDER で昇順か降順を指定します。
A_WORD および B_WORD はビット配列(std_logic_vector) で入力されます。ビット配列の長さは WORD_PARAM の BITS フィールドの値で指定されます。
library ieee;
use ieee.std_logic_1164.all;
library Merge_Sorter;
use Merge_Sorter.Word;
entity Word_Compare is
generic (
WORD_PARAM : Word.Param_Type := Word.Default_Param;
SORT_ORDER : integer := 0
);
port (
CLK : in std_logic;
RST : in std_logic;
CLR : in std_logic;
A_WORD : in std_logic_vector(WORD_PARAM.BITS-1 downto 0);
B_WORD : in std_logic_vector(WORD_PARAM.BITS-1 downto 0);
VALID : in std_logic;
READY : out std_logic;
SEL_A : out std_logic;
SEL_B : out std_logic
);
end Word_Compare;
Functions
ワードを中の DATA_COMP_HI および DATA_COMP_LO で指定されたフィールドを取り出して比較する関数は次のように定義しています。データが符号付きか符号無しかによって別々の関数を定義しています。
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
architecture RTL of Word_Compare is
function select_a_unsigned(A_WORD, B_WORD: std_logic_vector;ORDER: integer) return boolean is
variable a_comp : unsigned(WORD_PARAM.DATA_COMPARE_HI - WORD_PARAM.DATA_COMPARE_LO downto 0);
variable b_comp : unsigned(WORD_PARAM.DATA_COMPARE_HI - WORD_PARAM.DATA_COMPARE_LO downto 0);
begin
a_comp := to_01(unsigned(A_WORD(WORD_PARAM.DATA_COMPARE_HI downto WORD_PARAM.DATA_COMPARE_LO)));
b_comp := to_01(unsigned(B_WORD(WORD_PARAM.DATA_COMPARE_HI downto WORD_PARAM.DATA_COMPARE_LO)));
if (ORDER = 0) then
return (a_comp <= b_comp);
else
return (a_comp >= b_comp);
end if;
end function;
function select_a_signed(A_WORD, B_WORD: std_logic_vector;ORDER: integer) return boolean is
variable a_comp : signed(WORD_PARAM.DATA_COMPARE_HI - WORD_PARAM.DATA_COMPARE_LO downto 0);
variable b_comp : signed(WORD_PARAM.DATA_COMPARE_HI - WORD_PARAM.DATA_COMPARE_LO downto 0);
begin
a_comp := to_01( signed(A_WORD(WORD_PARAM.DATA_COMPARE_HI downto WORD_PARAM.DATA_COMPARE_LO)));
b_comp := to_01( signed(B_WORD(WORD_PARAM.DATA_COMPARE_HI downto WORD_PARAM.DATA_COMPARE_LO)));
if (ORDER = 0) then
return (a_comp <= b_comp);
else
return (a_comp >= b_comp);
end if;
end function;
Body
VALID 信号が '1' の時、A_WORD と B_WORD を比較して結果を出力します。
A_WORD に PRIORITY 属性がついているか B_WORD に POSTPEND 属性がついている場合は A_WORD を選択するために SEL_A 信号がアサートされます。
上記以外で、B_WORD にPRIORITY 属性がついているか A_WORD に POSTPEND 属性がついている場合は B_WORD を選択するために SEL_B 信号がアサートされます。
さらに上記以外では前述の比較関数の結果を出力します。
begin
process(VALID, A_WORD, B_WORD)
variable select_a : boolean;
begin
if (VALID = '1') then
if (WORD_PARAM.DATA_COMPARE_SIGN) then
select_a := select_a_signed (A_WORD, B_WORD, SORT_ORDER);
else
select_a := select_a_unsigned(A_WORD, B_WORD, SORT_ORDER);
end if;
if (A_WORD(WORD_PARAM.ATRB_PRIORITY_POS) = '1') or
(B_WORD(WORD_PARAM.ATRB_POSTPEND_POS) = '1') then
SEL_A <= '1';
SEL_B <= '0';
elsif (B_WORD(WORD_PARAM.ATRB_PRIORITY_POS) = '1') or
(A_WORD(WORD_PARAM.ATRB_POSTPEND_POS) = '1') then
SEL_A <= '0';
SEL_B <= '1';
elsif (select_a = TRUE) then
SEL_A <= '1';
SEL_B <= '0';
else
SEL_A <= '0';
SEL_B <= '1';
end if;
READY <= '1';
else
READY <= '0';
SEL_A <= '0';
SEL_B <= '0';
end if;
end process;
end RTL;