ただ、この便利なDesignWareにも、問題があります。(と、伊藤は最初思った。)
問題1.defaultのDCさんはDesignWare-Basicというのを呼んでくるが、これで生成した回路がかなり遅い。
問題2.DesignWareの使い方というか、いろいろ指定する方法がよくわかんない。
さて、ここで、上記2つの問題をどのように克服したかをメモっとこうと思います。
まず、問題1について。
この問題は簡単に解消できます。
DesignWare-Foundationを用いて下さい。
モノによりますが、経験上、大体2倍弱の高速化が期待できます。
#逆に言うと、Basicが遅すぎるわけで。。。テクノロジライブラリもフリーの奴は理不尽に遅いでしょ。。。
ただ、DesignWare-Basicは、デフォルトでDCに付いてきますが、
DesignWare-Foundationは、そのライセンス取得をしてないと(入ってるけど)使えません。
現在のところ、VDECだと、SYNOPSYSのライセンスを持ってれば使えるようです。
以下を.synopsys_dc.setupに書き加えれば使えるようになるはずです。(ライセンスがあれば)
get_license DesignWare-Foundation
link_library = {"使ってるテクノロジライブラリ","dw_foundation.sldb", "dw01.sldb","dw02.sldb", "dw03.sldb", "dw04.sldb", "dw05.sldb", "dw06.sldb", "dw07.sldb"}
synthetic_library = {"dw_foundation.sldb", "dw01.sldb", "dw02.sldb","dw03.sldb", "dw04.sldb", "dw05.sldb", "dw06.sldb", "dw07.sldb"}
synlib_wait_for_design_license={"DesignWare-Foundation"}
#上で既にライセンス取得してるからこれはなくてもよい。
dw_prefer_mc_inside = "true"
#説明は省くが、mc_insideなやつを指定したいとき用。
次に、問題2の解消方法である。
具体例として、符号付きの乗算器(32bit×16bit)を取り上げる。
(出力は32bitとし、また、簡単のためoverflowを扱わないものとする。)
module multiplier32s(opr0, opr1, signed_flag, result
//,overflow
);
input [31:0] opr0;
input [15:0] opr1;
input signed_flag;
output [31:0] result;
//output overflow;
wire signed [31:0] product_sig;
wire [31:0] product_usig;
assign product_sig = $signed(opr0) * $signed(opr1);
assign product_usig = opr0 * opr1;
assign result = signed_flag? $unsigned(product_sig) :product_usig;
endmodule // multiplier32s
上記は、SYNOPSYSのDWのマニュアルにoperand infering(だっけ?)の例として書いてあるものを参考にしたものである。
このように、DCに推論させると訳分からない事をされることもあるし、
符号とかキャリーとかの細々としたことまで推論させるのはメンドイので、
伊藤はできるだけ、DWを自分で指定してます。
以下が、上記と同様の乗算器をDWを指定して書いたモノです。
module multiplier32s(opr0, opr1, signed_flag, result
//,overflow
);
input [31:0] opr0;
input [15:0] opr1;
input signed_flag;
output [31:0] result;
//output overflow;
wire [32+16-1:0] temp;
// Instance of DW02_mult
DW02_mult #(32, 16)
U1( .A(opr0), .B(opr1), .TC(signed_flag), .PRODUCT(temp));
assign result = temp[31:0];
endmodule // multiplier32
ここでは、DW02_mult
という乗算器を直接指定しています。
一般に、DesignWareを使用すると、冗長回路ができることが多いので、
合成スクリプトにset_ungroup {*DW*}とか付けて消してやります。
というか、伊藤の場合、演算器の類は全部(どうせ小さいので)DWを呼んでるモジュールごとUngroupします。
プロセッサの実行段は(INTなら)全体でUngroupで行くべきだと思います。
最後に、上記の乗算器(が含まれる回路)をVCSで検証するときには、
DW02_mult.vというシミュ用ファイルを読んでやらないとVCSに怒られるので、忘れずに読んでやりましょう。
当然環境依存だが、伊藤の環境におけるこのDW用のシミュファイルの場所を参考の為に書いておく。
/usr/local/CADmedia/SYNOPSYS/synthesis/dw/sim_ver/の下にある。
#パスが遠いんで、伊藤はこいつは、コピってもっと近くにも置いてます。
ということで、こんな感じでVCSを立ち上げたらいいと思う。↓
vcs +v2k test_multiplier32s.v ../../rtl/multiplier32s.v ../../../sim_lib/DW02_mult.v
以上、おわり、ありがとう。