*Handel-CとCoreGeneratorの連携 [#r6509f83]

※この記事は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)
&counter(all);

(・ω・)&counter(total);ノシ


トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS