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を使ってみる。
参考:Handel-Cについて

●マニュアルの方法

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)

(・ω・)237ノシ


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2019-08-29 (木) 00:03:49