FC2カウンター FPGAの部屋 VHDLによる乗算記述方法によるインプリメントの差異(Ver.12.3のXST)
FC2ブログ

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

VHDLによる乗算記述方法によるインプリメントの差異(Ver.12.3のXST)

ISE12.3のXSTを使って、VHDLによる乗算記述方法によるインプリメントの差異について調べてみた。使用デバイスはSpartan-6(xc6slx45t-3fgg484) (”VHDLによる乗算について(ISE12.3のXSTを使用)”と”Type Qualification とType Conversion”を参照)
まずは、”VHDLによる乗算について(ISE12.3のXSTを使用)”の(2010/12/21:追加)の掛け算のVHDLをXSTでインプリメントしてみた。(XSTの-use_dsp48オプションはAuto)

library IEEE;
use IEEE.std_logic_1164.all;
use ieee.std_logic_signed.all;
use ieee.std_logic_arith.all;

entity mult_test is
    port (
        clk : in std_logic;
        reset : in std_logic;
        ina : in std_logic_vector(7 downto 0);
        mult_out : out std_logic_vector(17 downto 0)
    );
end mult_test;

architecture RTL of mult_test is
signal mult : std_logic_vector(17 downto 0);
signal temp : std_logic_vector(8 downto 0);
begin
    temp <= "111110000";
    process(clk)
    begin
        if clk'event and clk='1' then
            if reset='1' then
                mult <= (others => '0');
            else
                mult <= unsigned(ina) * signed(temp);
            end if;
        end if;
    end process;
    mult_out <= mult;
end RTL;


インプリメントすると、DPA41A1がインスタンスされている (FPGA Editor)。
mult_8_101222.png

次に、下のVHDLソースでインプリメントしてみた。

library IEEE;
use IEEE.std_logic_1164.all;
use ieee.std_logic_signed.all;
use ieee.std_logic_arith.all;

entity mult_test is
    port (
        clk : in std_logic;
        reset : in std_logic;
        ina : in std_logic_vector(7 downto 0);
        mult_out : out std_logic_vector(17 downto 0)
    );
end mult_test;

architecture RTL of mult_test is
signal mult : std_logic_vector(17 downto 0);
begin
    process(clk) begin
        if clk'event and clk='1' then
            if reset='1' then
                mult <= (others => '0');
            else
                mult <= unsigned(ina) * signed'("111110000");
            end if;
        end if;
    end process;
    mult_out <= mult;
end RTL;



SLICEXとOLOGIC2でインスタンスされていて、DPS48A1は使用されていない。
mult_9_101222.png

同じ設定で、XSTの -use_dsp48をAutomaxに設定して、インプリメントしてみた。結果は、SLICEXとOLOGIC2でインスタンスされた。
XSTの -use_dsp48をYESに設定してみた。結果はDSP48A1を使用した。
このVHDLコードだと、XSTの -use_dsp48がYESの時だけ、DSP48A1を使用する。でも、XSTの -use_dsp48がYESだと、DPS48A1を使い切るとエラーになってしまう。

mult <= unsigned(ina) * signed'("111110000");



mult <= unsigned(ina) * signed(std_logic_vector'("111110000"));


に変更しても、同様の結果になった。

  1. 2010年12月22日 15:34 |
  2. VHDLの書き方
  3. | トラックバック:0
  4. | コメント:8

コメント

これDSPを使うとサイズが大きくなると言う話でしたが、
定数が定数なので、ビットシフト+符号反転で計算できて
しまうってことはないですか?
  1. 2010/12/22(水) 21:07:49 |
  2. URL |
  3. 武内 #-
  4. [ 編集 ]

こんにちは。
良く考えてみると、*演算子を使ったDSP+LUTの演算している桁数が、シフト+加算よりも増えていることに気が付きました。*演算子を使うと被乗数桁数*乗数桁数=(被乗数桁数+乗数桁数)にする必要がありますが、計算の関係で乗数桁数を増やしていました。乗数桁数を元に戻して、その後で符号拡張すれば、もう少し小さくなるかもしれません。
#いずれにせよ面倒です。MATLAB+Simulink+System Generatorで簡単に出来れば良いですね?
  1. 2010/12/22(水) 21:53:17 |
  2. URL |
  3. marsee #f1oWVgn2
  4. [ 編集 ]

以下、蛇足かもしれないです。

signed'("111110000") = -0x10 ですよね?
すると verilog で言うところの - { ina, 4'b0000 } で済むので、最適化後はどこにも掛け算は出てこないことになってしまいます。

定数との掛け算だと、このようにビットシフト+ごく少数の足し算・引き算にできてしまうことがあるので、確かにこのあたりを総合的に判断して、DSP に割り振ったり、LUT に割り振ったりしてくれたら言うこと無いですね。

目的の式によっては DSP48 のアキュムレータ等をうまく使えて、掛け算以外の部分も LUT の機能を DSP に入れ込むことで、活用できる場面も増えるのでしょうけれど・・・
  1. 2010/12/23(木) 00:37:18 |
  2. URL |
  3. 武内 #-
  4. [ 編集 ]

了解しました。もう少し、複雑な式の方が良かったですね。
それでも、シフトした項+加算でできるわけですが。。。
ここではDSPを使うかどうかを見るという試行をしたかったので、目的は果たせているんじゃないか?と思います。
  1. 2010/12/23(木) 05:11:51 |
  2. URL |
  3. marsee #f1oWVgn2
  4. [ 編集 ]

>定数との掛け算だと、このようにビットシフト+ごく少数の足し算・引き算にできてしまうことがあるので、確かにこのあたりを総合的に判断して、DSP に割り振ったり、LUT に割り振ったりしてくれたら言うこと無いですね。

こうして貰う予定でした。なかなか難しいです。今のところの演算では、シフトとそれらの加算でVHDLを全て書いてあるので、LUTにしか割り当てていませんでした。それをDSPも使い切るようにしようということで、*演算子を使って書いたのですが、なかなかDSPに割り当ててくれないので、条件を試行してみました。式が悪いのか?DSP使ったほうがリソースが増えてしまいました。
面倒ですが、定数の桁数を減らして、そのあとで符号拡張をやってみるしかないと思います。
ですが、あまり、効果が無いようだったら、シフトとそれらの加算のままで良いかな?と思っています。定数が変わったらVHDLを生成するRubyスクリプトを書いてあるので、定数の変更は簡単です。
  1. 2010/12/23(木) 14:37:30 |
  2. URL |
  3. marsee #f1oWVgn2
  4. [ 編集 ]

そこまでできるスクリプトがあるのなら、足し算がn回以上になる場合だけを掛け算としてDSPにインプリメントするスクリプトに改良するとか・・・

すみません、人ごとと思って無茶言いました(?) (^ー^;
  1. 2010/12/23(木) 15:26:07 |
  2. URL |
  3. 武内 #-
  4. [ 編集 ]

ruby スクリプトを使わなくても、verilog なら generate で対応することもできそうに思えてきました。VHDL では・・・どうでしょうね。
  1. 2010/12/23(木) 15:28:54 |
  2. URL |
  3. 武内 #-
  4. [ 編集 ]

VHDLでもgenerateで対応可能です。シフトをつくるのに少し記述が必要ですが。。。
Ruby スクリプトを使うのは、元データをExcelで処理して、簡単な形にしてからCSVとして読み込んで、自動的にVHDLファイルに変換しているからです。これもVHDLで書けると言っては書けると思うんですが、はっきり言って面倒だと思います。それならば、文字列の扱いが楽なRubyという訳です。

#あまり書いていると、研究(補助)の内容がバレバレになるといけないので、このへんで終りにします。
  1. 2010/12/23(木) 15:41:52 |
  2. URL |
  3. marsee #f1oWVgn2
  4. [ 編集 ]

コメントの投稿


管理者にだけ表示を許可する

トラックバック URL
https://marsee101.blog.fc2.com/tb.php/1672-33249d20
この記事にトラックバックする(FC2ブログユーザー)