Quartus2 V13.1 ~Tips編 VHDL記述による合成結果の違い~

 HDL記述は、高級言語でのプログラム記述と同様に、コンパイラの癖や性能によって、合成結果(回路、規模など)が大きく異なる場合があります。

デジタル設計での必須アイテムであるカウンタの記述にて、Quartus2の合成結果を見比べてみました。

■仕様

4bitの13進同期式カウンタ
非同期リセット入力有り
カウントイネーブル入力有り

■トップ回路図

■COUNTERのVHDL記述
カウンターの出力変数をintegerで定義しています。桁数が大きい時やシーケンサなどを記述する時には読みやすいので使いやすいですね。

ARCHITECTURE counter_architecture OF counter IS
signal counto : integer;

BEGIN
count <= CONV_STD_LOGIC_VECTOR(counto,4);

process (clk, reset, enable)
begin
if (reset = '1') then
counto <= 0;
elsif (rising_edge(clk)) then
if (enable = '1') then
if(counto = 12) then
counto <= 0;
else
counto <= counto + 1;
end if;
end if;
end if;
end process;

END counter_architecture;

■COUNTER1のVHDL記述
integerを使用せず、std_logic_vectorで記述したものです。ビット幅が大きくなると間違い易い記述です。

ARCHITECTURE counter1_architecture OF counter1 IS
signal counto : STD_LOGIC_VECTOR(3 downto 0);

BEGIN
counto1 <= counto;

process (clk, reset, enable)
begin
if (reset = '1') then
counto <= "0000";
elsif (rising_edge(clk)) then
if (enable = '1') then
if(counto = "1100") then
counto <= "0000";
else
counto <= counto + '1';
end if;
end if;
end if;
end process;

END counter1_architecture;

■COUNTER2のVHDL記述
条件記述をif文では無く、シーケンサ記述でお馴染みのcase文で記述したものです。

ARCHITECTURE counter2_architecture OF counter2 IS
signal counto : STD_LOGIC_VECTOR(3 downto 0);

BEGIN
counto2 <= counto;

process (clk, reset, enable)
begin
if (reset = '1') then
counto <= "0000";
elsif (rising_edge(clk)) then
if (enable = '1') then
case counto is
when "1100" => counto <= "0000";
when others => counto <= counto + '1';
end case;
end if;
end if;
end process;

END counter2_architecture;

■タイミングシュミレーション結果

いずれも仕様通りの動作をしています。
しかし、COUNTERの出力であるco0の出力遅延が大きいので、明らかに生成された回路が異なる事が予想されます。

■RTLViewer表示

COUNTERはintegerのビット幅である32bitカウンターが生成されてしまっています。
4bitしか使用しないのに、約8倍の回路規模になってしまっている計算になります。

COUNTER1は、最も回路規模が小さいであろうと思われる回路です。

COUNTER2は、典型的なロードカウンタの回路ですね。

 この様に、同じ動作であっても、記述によってコンパイラが生成する回路は異なります。 又、これはQuartus2 V13.1での結果であって、バージョンが異なったり、他社製コンパイラでは違った結果となりえます。

 コストダウンの為に、エレメント数(ASICではゲート数)を削減せねばならないとか、要求性能を満たす為に、より高速クロックで動作する様にしたり、遅延時間を小さくせねばならない場合などにおいては、使用するコンパイラの癖を掴んで記述せねばならない場合がある事を示唆しています。

■追記(2014.6.30)

COUNTERでは32bitカウンターが生成されていましたが、変数の取りうる範囲を記述(range A to B)する事で、bit数の最適化を図る事ができました。
※コンパイラによっては、4bitカウンタに最適化が図られる場合もありえますが、設計者の持っている情報を少しでも多くコンパイラに教える(記述する)事で、より良い回路の生成が期待できます。

ARCHITECTURE counter_architecture OF counter3 IS
signal counto : integer range 0 to 12;


コメント

このブログの人気の投稿

ARM用クロスコンパイラのビルド(Windows8+Cygwin)

Raspberry Pi のsleep時間測定

Quartus2 V13.1 ~エントリー編 HDL回路から回路図用シンボルを作成する~