Handel-CとCoreGeneratorの連携 †※この記事はVisionグループOBのfukudaさんのwikiから持ってきました。 fukudaさんのwiki→http://www.am.ics.keio.ac.jp/members/fukuda/wiki/index.php?Kyoshow Celoxica社のHandel-CとCoreGeneratorを連携させて、VirtexのBlockRAMを使ってみる。 ●マニュアルの方法 ram unsigned 8 MyRam[512] with {block=1}; とか、 ram unsigned 8 MyRam[512] with {block="BlockRAM"}; と書けばいい、とあるが、やってみると、何故か // RAM 'MyRam' reg [7:0] RAM_MyRam[511:0]; // RAM 'MyRam' read address wire [8:0] RAM_MyRam_RdAddr; などと頭の悪い吐き方をしてくれる。確かに、ISEでこれはメモリに推論される 場合もあるが、Distributed RAMになってしまうため本末転倒。 他の方法を考える必要がある。 ●CoreGeneratorで吐いたEDIFファイルを取り込む。 こちら側は行けそう。初期値等もいけるし、何よりメモリの構成が容易。 テストプログラムとして、まず乗算器を作ってみる。 CoreGeneratorでmymultという16x16bit乗算器を作成する。 //set family = XilinxVirtexII; //set part = "xc2v6000bf957-4"; set clock = external "P0"; set reset = external "P1"; unsigned 16 myA; unsigned 16 myB; interface mymult(unsigned 32 q) MyMulti(unsigned 16 a=myA, unsigned 16 b=myB, unsigned 1 clk=__clock) with{busformat="B<I>"}; void main(void) { unsigned 32 ans; par{ myA = 3; myB = 2; } delay; ans = MyMulti.q; } をDK3を用いてverilogへ。clkとresetは外部からの入力。適当な ピン名を書いておくと、外に引き出せる。書かないと、内部にresetの 発生装置が必要になるため面倒。 verilogを吐かせると、 module mymult ( a, b, clk, q ); // interface description input [15:0] a; input [15:0] b; input clk; output [31:0] q; endmodule のような物を作成してくれるので、これをコメントアウトする。 コメントアウトすることで、CoreGeneratorに吐かせたmymultを使用できる。 (2004/10/4 追記 by かなもり) with {bind = 1 or 0} を追加することで、 上記のようなモジュールの定義の有無を指定できる。 bind = 0 のときは、Verilogファイルにモジュールの定義を含む(デフォルト)。 bind = 1 のときは、含まない(ので、コメントアウトする手間が省ける)。 (例) interface mymult(unsigned 32 q) MyMulti(unsigned 16 a=myA, unsigned 16 b=myB, unsigned 1 clk=__clock) with{busformat="B<I>", bind = 1}; (2004/10/9 追記 by ふくだ) 乗算器に関しては、*を使ってverilogを吐かせて、ISE側で論理推定しちゃった方が早いかも。以下、たかまさ氏のサンプルコード set family = XilinxVirtexII; set part = "xc2v6000bf957-4"; set clock = external "P0"; set reset = external "P1"; unsigned int 4 myA; unsigned int 4 myB; void main(void) { unsigned int 8 DOut; interface bus_in(unsigned int 4 DIn1) DataIn1(); interface bus_in(unsigned int 4 DIn2) DataIn2(); interface bus_out() DataOut(DOut); //chanout 8 stdout; par{ myA = DataIn1.DIn1; myB = DataIn2.DIn2; } delay; DOut = (0@myA) * (0@myB); //stdout ! DOut; } ●メモリのサンプルコード 8bitx4096lineのメモリを接続するときの雛型。 set clock = external "clk"; set reset = external "reset"; //==========接続するモジュールの設定========= /*------------------------------------------------------------------------- 内部で用いる入力ポート用の変数名 ------------------------------------------------------------------------*/ unsigned 12 SpRam0_addr = 0; // Internal Variable for "addr" unsigned 8 SpRam0_din = 0; // Internal Variable for "din" unsigned 1 SpRam0_we = 0; // Internal Variable for "we" /*------------------------------------------------------------------------- interface モジュール名(モジュールの出力ポート名) インスタンス名(モジュールの入力ポート=handel-cで使う変数名) unsigned 1 clk = __clockで自動的にクロックをつなぐ ------------------------------------------------------------------------*/ interface spram(unsigned 8 dout) SpRam0(unsigned 12 addr=SpRam0_addr, unsigned 8 din=SpRam0_din, unsigned 1 we=SpRam0_we, unsigned 1 clk = __clock); void main(void) { //外部出力用のポートは以下のようにして定義。 unsigned int 8 DOut; interface bus_in(unsigned int 12 DIn1) DataIn1(); interface bus_in(unsigned int 8 DIn2) DataIn2(); interface bus_in(unsigned int 1 DIn3) DataIn3(); interface bus_out() DataOut(DOut); while(1){ par{ SpRam0_addr = DataIn1.DIn1+4; SpRam0_din = DataIn2.DIn2+4; SpRam0_we = ~DataIn3.DIn3; DOut = SpRam0.dout; } } } (souichi) (・ω・)384ノシ |