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) (・ω・)518ノシ |