...

Cプログラムからのハードウェア設計: Handel

by user

on
Category: Documents
22

views

Report

Comments

Transcript

Cプログラムからのハードウェア設計: Handel
Cプログラムからのハードウェア設計:
Handel-CとDK4の学習
松本 剛史
[email protected]
大規模集積システム設計教育研究センター
演習のスケジュール
> 1日目(10/6):動作合成の概要とDK4の使用法
> 2日目(10/20):Handel-C言語の文法,設計フローの習得
> 3日目(10/27):実例を題材としたHandel-C記述の習得
> 4日目(11/10):Elegantシステムを用いた上位設計手法
> 5日目(11/17):Handel-C言語を使った自由課題の設計
> 6日目(12/1):報告会
> 報告会後に演習レポート提出(期限は後日指定)
2
概要
> FPGAボード (RC100)を使ったシステム設計
> プログラミング言語を使ったハードウェア設計
> Handel-C(言語)とDK4(コンパイラ/シミュレータ)の習得
> 実例: 7セグメント表示とブロック崩しゲーム (演習課題)
> 自由課題の設計
3
用語の説明と使用するツール
> RC100: FPGAボード
> Handel-C: C言語を拡張し
たプログラミング言語
> DK4: Handel-C用の論理
合成/デバッガ/シミュレー
タ
> Agilent (旧Celoxica):
Handel-C/DK4を開発して
いる会社
> DK4: Handel-C用の論理合
成/デバッガ/シミュレータ
> Project Navigator: FPGA
の配置配線(Xilinx社)
> File Transfer Utility: BITフ
ァイルのダウンロード
> RC100: FPGAボード
> Xilinx: FPGA用の論理合
成ツールを開発している会社
4
RC-100 開発ボード
> Xilinx Spartan2-200 FPGA
> 2MB ZBT SRAM, in 2 36-bit banks. 8MB Flash RAM
> ビデオ入力デコーダ, VGA 出力DAコンバータ
> 50 pin 拡張ボード用コネクタ, PS/2ポート×2, パラレルポート
> クロック発振器 (最大80MHz)
ボード上にCPUはありません!
5
実験環境
> PCと設計用ツールは一人に一つずつ
„
アカウント:enshu
„
パスワード:cad2008
> RC100(FPGAボード)は一人に一台
> RC100のVGA出力を使う場合は、PCとケーブルをシェアする
6
Handel-C言語の特徴
> RTL(リソースシェアリングやスケジューリングはしない)の設計が可能
> ソフトウェアの開発技術がそのまま使える
> C/C++の文法の一部がそのまま使える
> ハードウェアとソフトウェアの設計を同時に行なうことができる
> ハードウェアを知らない人でもとっつきやすい
7
従来フローとの比較
Executable
Executable
Specification
Specification
Software
Software
VHDL/
VHDL/
Verilog
Verilog
Handel-C
Handel-C
Simulator
Simulator
Simulator
Simulator
Simulator
Simulator
VHDL
System
System
Model
Model
Synthesis
Synthesis
EDIF
EDIF
ASIC
ASIC Flow
Flow
Place
Place and
and Route
Route
Target
Target Device
Device
8
論理合成と動作合成
> RTL記述からネットリスト(ゲートレベルの回路記述)を
生成するのが論理合成
> 動作記述からRTLを生成するのが動作合成
9
動作合成の例
10
RTL記述とネットリストの例
11
動作合成
> スケジューリング
> アロケーション
> バインディング
> 制約条件を満たすまでスケジューリング・アロケーション
・バインディングを繰り返し実行する
12
スケジューリング
動作記述をコントロールフローグラフ(CFG)に
展開してコントロールステップに割り当てる作業
13
スケジューリング(制約条件)
14
アロケーション
> 論理合成のテクノロジマッピングに相当する
> ライブラリの中から条件に合った演算器を各演算に
割り当てる
15
アロケーション(制約条件)
16
バインディング
> 演算器の共有方法を決定する
17
バインディングの例
バインディングによってマルチプレクサの数や
結線数が大幅に変わることがある
18
演習の目的
> 演算のスケジューリング方法や演算器の共有方法
によって実行ステップ数(速度性能)や回路規模およ
びクロック周波数が変化することを確認する
> ソフトウェアプログラミングとハードウェア設計の違
いを体験する
19
本演習での設計のフロー
> Handel-C言語で回路を記述する
> DK4上でシミュレーション、デバッ
グ および論理合成を行なう
> Xilinx Project Navigatorで
FPGA上の配置配線を決定し、ダ
ウンロード用のbitデータを作成す
る
> File Transfer Utilityでbitデ
ータをFPGAにダウンロードする
Handel-C
Simulate
FPGA
Vendor’s
Tools
1
Register
A
Q1
D
Q4
ENB
Netlist
Place
And
Route
> RC100で動作確認を行なう
> エラーがあればHandel-Cの記述
まで戻って修正する
20
DK4の操作練習
準備するファイル
> Handel-C言語で記述されたプログラムソース … sample1.c
> DK4でコンパイルする際の設定が記述された設定ファイル … sample1.hp
> ワークスペースを定義するためのファイル … sample1.hw
sample1.hwの例
#@hw
project sample1.hp
sample1.hpの例
#@hp
type XilinxVirtex
setting Debug lib:stdlib.hcl true
setting Debug lib:rc100.hcl true
setting EDIF lib:stdlib.hcl true
setting EDIF lib:rc100.hcl true
document sample1.c {
type c
}
21
DK4の起動
> sample1.hwまたはDKのアイコンをダブルクリック
> DKのアイコンから起動した場合は
File → Open Workspace をクリック
22
シミュレータ(デバッガ)の起動(1/3)
> Build→Set Active Configuration…をクリック
> Debugを指定してOK!
23
シミュレータ(デバッガ)の起動(2/3)
> Build→Start Debug→Step Into をクリック あるいは ソースファイルの画面
をクリックした後F11キーでステップ実行
(1回目の場合、コンパイルするかと聞かれる。YESでバイナリを生成する)
24
シミュレータ(デバッガ)の起動(3/3)
>
F11キーでステップ実行
>
display1とdisplay2(重なる場合移動する)が同時に変化する(並列動作する)ことを確認する
>
Debug→Stop Debuggingでデバッガを終了する
25
論理合成(1/2)
> Build→Set Active Configuration…をクリック
> EDIFを指定してOK!
26
論理合成(2/2)
> Build→Build sample1をクリック
> 0 errors, 0 warningsであることを確認する
27
EDIFファイルの確認
> EDIFは論理回路のネットリストを表現する標準フォーマットの一つ
> ネットリスト : セルの名前とその入出力ポートの接続関係が記述されたリスト
WordPadを使って表示させる
(cell XOR2
(cellType GENERIC)
(view view_1
(viewType NETLIST)
(interface
(port I0 (direction INPUT))
(port I1 (direction INPUT))
(port O (direction OUTPUT))
)
)
)
(cell OR4
(cellType GENERIC)
……
……
28
Project Navigator の起動
> Project Navigatorのアイコンをクリック
> 下図のようなウィンドウが立ち上がることを確認する
29
FPGAの配置配線(1/5)
> File→New Projectをクリックし、Project Nameはここではsample1とする
> Project LocationはHandel-Cソースがあるフォルダのフォルダを指定し、その
他の変数は図のとおり記述して 次へ
30
FPGAの配置配線(2/5)
> Input DesignのところにEDIFフォルダの中のsample1.edfを指定する
> Copy のチェックを外す
31
FPGAの配置配線(3/5)
> FPGAの種類、速度、パッケージ、スピードを指定する(デフォルトのままで可)
> 最後に確認して完了
32
FPGAの配置配線(4/5)
> sample.edfをクリックしEDIFファイルが表示されることを確認する
> Inplement Designをダブルクリックすると配置配線がはじまる
> Gnenrate Programming Fileをクリックしてダウンロード用のファイルに変換する
33
FPGAの配置配線(5/5)
> 配置配線が正常に終了すると緑色のチェックマークが表示される
> Warningがある場合は!が表示されるがwarningなので一応無視できる
34
FPGAへのダウンロード(1/3)
> PCのプリンタポートとボードのパラレルポートを接続する
> RC100ボードの電源をONにする(緑色LEDが点灯する)
35
FPGAへのダウンロード(2/3)
> File Transfer Utility 2(FTU2) を起動する
> Please select a boardボタンをクリックして、Celoxica RC100を
選択する。
> FPGAへ書き込みを選択する
> Browseボタンをクリックして、.bitファイルを選択する。
36
FPGAへのダウンロード(3/3)
> Configureボタンをクリックすることで、ダウンロードが開始し
、7セグメントLEDがルーレット状に点灯する
37
Handel-C 言語
Variables
Bit manipulation operators
Timing model
Par {...}
Signals
Channels
Functions
Interface
38
文法の特徴
>
ISO-C (ANSI-C) 準拠… if, while, switch etc including
„
関数, 構造体, ポインタが使用可能
> ハードウェア記述用に拡張されたいくつかの文法を持つ
„
par{…} 記述により並列動作を記述できる
„
変数に対して任意のビット幅を指定できる
„
演算に必要なクロック数を指定できる
„
ビット操作が可能
„
資源の共有やスケジュールを明示的に記述できる
„
RAMやROMおよび外部ピンへの接続を明示的に記述できる
39
変数定義
> Integer タイプのみをサポート
> 符号なしの変数はunsigned で定義する(指定がない場合はsigned)
> 変数のビット幅を指定できる
変数はハードウェアのレジスタに対応する
void main(void)
{
unsigned 6 a;
a=45;
}
a=
1
MSB 5
0
1
1
0
1
= 0x2d
LSB 0
40
ビット操作命令
<<
左シフト
>>
右シフト
<-
最下位ビットを取り出す
¥¥
最下位ビットを切り捨てる
@
ビット接続
[]
ビット範囲指定
41
ビット接続の例
[MSB :LSB ] ビット選択 (ビットの範囲)
1 0 1 1
= 0xb
a=
b=
0
1
= 0x1
c = a@b
c=
1
0
1
1
0
1
= 0x2d
42
ビット切り捨ての例
[MSB :LSB ] ビット選択 (ビットの範囲)
a=
1
0
1
1
1
0
1
1
0
1
= 0x2d
b = a¥¥2
b=
= 0xb
43
ビット選択の例
[MSB :LSB ] ビット選択 (ビットの範囲)
a=
1
0
1
1
0
0
1
1
0
1
= 0x2d
b = a[4:1]
b=
= 0x6
44
タイミングモデル
>
変数の代入とdelay文は1クロックサイクルを必要とする
>
それ以外の動作には遅延は発生しない
void main(void)
{
…
a=b+c+d;
…
}
b
c
+
a
d
Cf. Assembler for a Typical Microprocessor
LOAD B,REG1
LOAD C,REG2
ADD REG1,REG2
LOAD D,REG2
ADD REG1,REG2
STORE REG1,A
3 Clock Cycles
3 Clock Cycles
1 Clock Cycle
3 Clock Cycles
1 Clock Cycle
3 Clock Cycles
45
並列動作の記述
> 通常の記述では逐次動作するハードウェアが合成される。
> par{…} 記述で囲まれた動作が同時に実行される(並列動作する)。
Sequential Block
// 3 Clock Cycles
{
a=1;
b=2;
c=3;
}
Parallel Block
// 1 Clock Cycles
{
par{
a=1;
b=2;
c=3;
}
}
46
並列動作の記述例
void main(void)
{
…
a = 1;
a = 1;
1
par
{
a = a + 1;
b = 5;
a = 2
b = 5
2
}
par
{
a = 5
b = 6
3
b = b + 1;
a = b;
}
}
47
並列動作の記述例
macro proc ParExample()
{
unsigned 4 Tenths, Count;
unsigned 3 Circle;
Count = 0; Circle = 0;
<<< 途中省略 >>>
while (1)
{
par
/*run the two displays in parallel*/
{
{
Count = (Count == 15) ? 0 : (Count + 1);
DisplayOutput1 = HexDisplayEncode1[Count];
}
{
Circle = (Circle == 5) ? 0 : (Circle + 1);
DisplayOutput2 = CircleDisplayEncode[Circle];
}
}
}
}
48
逐次動作と比較してみよう!
macro proc ParExample()
{
unsigned 4 Tenths, Tenth4, Count;
unsigned 3 Circle;
Count = 0; Circle = 0;
新しい変数の定義
<<< 途中省略 >>>
while (1)
{
#ifndef DEBUG
Tenths = 4; TimeDelay(Tenths);
遅延の挿入
#endif
// par
/*run the two displays in parallel*/
{
{
Count = (Count == 15) ? 0 : (Count + 1);
コメントアウト DisplayOutput1
= HexDisplayEncode1[Count];
}
#ifndef DEBUG
遅延の挿入
Tenth4 = 4; TimeDelay(Tenth4);
#endif
{
Circle = (Circle == 5) ? 0 : (Circle + 1);
DisplayOutput2 = CircleDisplayEncode[Circle];
}
}
}
}
演習1 : par文をコメントアウトした場合としない場合の動作を比較せよ
49
演習で使うmain関数(ソースの末尾)
void main(void)
{
<<< 省略 >>>
該当する例題の
コメントを外す
/* Uncomment to run par{} example. */
// ParExample();
/* Uncomment to run channel examples. */
// par
// {
//
ChanCount();
//
ChanCircle();
// }
/* Uncomment to run drop example. */
//
DropExample();
/* Uncomment to run take example. */
//
TakeExample();
……
……
50
Signal変数
> あるクロックサイクルで代入された値をそのクロックサイクル内に限り読み出
すことができる
„
Signal変数に代入した値を同じクロックサイクル内で読み出すことができる
„
上記以外のクロックサイクルでは値の代入は行なわれない
// 2 Clock Cycles
int 15 a, b;
signal <int> sig;
a = 7;
par
{
sig = a;
b = sig;
}
51
Signal変数の使用例
macro proc SignalExample()
{
unsigned 4 Tenths, Count1, Count2, Count3;
signal <unsigned 4> CountSig;
Count1 = 0; Count2 = 0; Count3 = 0;
<<< 途中省略 >>>
while (1)
{
Count1 = (Count1 == 15) ? 0 : (Count1 + 1);
par
{
CountSig = Count1+1; /*assign value to the signal*/
Signal変数からの代入
Count2 = CountSig; /*use the value from the signal*/
Count3 = Count1+1; /*...and use it again here*/
}
<<< 途中省略 >>>
}
52
}
Unsigned変数で置き換えた記述
macro proc SignalExample()
{
unsigned 4 Tenths, Count1, Count2, Count3;
unsigned 4 CountSig;
Count1 = 0; Count2 = 0; Count3 = 0;
<<< 途中省略 >>>
while (1)
{
Count1 = (Count1 == 15) ? 0 : (Count1 + 1);
par
{
CountSig = Count1+1; /*assign value to the signal*/
Count2 = CountSig; /*use the value from the signal*/
Count3 = Count1+1; /*...and use it again here*/
}
<<< 途中省略 >>>
}
演習2 : 1ページ前の記述とこの記述の動作をボード上で比較せよ
53
Signal変数とUnsigned変数の違い
Integerの場合
Count1
1
Signalの場合
CountSig
+
Count1
+
1
Count1
1
+
Count1
1
+
CountSig
CountSig
Count2
Count3
Count2
Count3
54
Channel変数
> プロセス間通信
„
並列実行されるプロセス間の同期を取るために使われる
„
チャンネルによって接続された双方のプロセスが通信可能状態になるまで待たされる
c
a
b
Chan c; //Declaration
{
{
…
c!a;
…
}
…
c?b;
…
//write a to c
//read c to b
}
55
Channel変数の使用例
macro proc ChanCount()
{
<<< 省略 >>>
while (1)
{
do
{
<<< カウントアップ>>>
}
while (Count != 16);
Counted ! 0;
/*write to channel*/
Circled ? Temp; /*read from channel*/
}
}
チャンネルを書き込むまで chanel read
以降の処理が待たされる
macro proc ChanCircle()
{
<<< 省略 >>>
while (1)
{
Counted ? Temp; /*read from channel*/
do
{
do
{
<<< ルーレット >>>
}
while (Circle != 6);
}
while(Loops);
Circled ! 0; /*write to channel*/
}
}
56
Channel変数を使った演習
macro proc ChanCount()
{
<<< 省略 >>>
while (1)
{
do
{
<<< カウントアップ>>>
}
while (Count != 16);
Counted ! 0; /*write to channel*/
Circled ? Temp;/*read from channel*/
}
}
演習3 : Channelの記述をコメントア
ウトした場合としない場合を比較せよ
macro proc ChanCircle()
{
<<< 省略 >>>
while (1)
{
Counted ? Temp;/*read from channel*/
do
{
do
{
<<< ルーレット >>>
}
while (Circle != 6);
}
while(Loops);
Circled ! 0; /*write to channel*/
}
}
57
関数
> 繰り返し実行される文をマクロ化する
> ハードウェア向けの拡張
„
同一の関数が並列に呼び出される場合は配列関数を使う
例)
par{
a=mult[0](b,c);
d=mult[1](e,f);
}
58
関数の使用例
> e.g. Multiplication
// 2 Multipliers,seq
void main(void)
{
…
a=b*c;
d=e*f;
…
}
// 1 Multiplier
void main(void)
{
…
a=mult(b,c);
d=mult(e,f);
…
}
// 2 Multipliers,par
void main(void)
{
par{
a=mult[0](b,c);
d=mult[1](e,f);
}
}
unsigned mult(a,b)
mult[2](a,b)
{
return a*b;
}
59
設計誤りとその対処法
> 機能的なエラー
„
シミュレーションとデバッガを使って修正する
„
参考) imageprocDebug.c
> 遅すぎる回路
„
RC100 のクロックは20 MHz
„
組み合わせ回路の遅延を削減する手法を導入する
design0
design1
design2
X = A*B*C*D*E*F
par {X1 = A*B*C ; X2 = D*E*F;} X = X1*X2;
par {X1 = A*B*C ; X2 = D*E*F; X = X1*X2;}
> 大きすぎる回路
„
Xilinx ツールがコンパイルできない可能性がある
„
シーケンシャルな回路に変形する
60
まとめ
> 並列動作と逐次動作
„
Par{}記述により明示的に並列実行を指定する
„
並列動作は実行ステップ数を小さくできるがゲート数が多くなる
> プロセス間通信
„
ハードウェア特有の拡張
„
チャンネルを使ってプロセス間で通信することによりプロセス間で同期を取
ることができる
> Signal変数
„
クロックに同期しない代入が可能(ハードウェアの配線に相当)
„
多用すると直列パスが長くなり高速動作ができなくなる
61
演習課題
> 演習1 : sample1のpar文をコメントアウトした場
合としない場合の動作を比較せよ
> 演習2 : sample1のsignal変数とunsigned変数
の動作をボード上で比較せよ
> 演習3 : sample1のChannelの記述をコメントア
ウトした場合としない場合を比較せよ
62
演習資料とデータのダウンロード:
http://www.cad.u-tokyo.ac.jp/ から、「講義資料」へ
そこからsample1.zipをダウンロードし、C:¥Enshu内で解凍
Handel-C の文法、RC-100の詳しい利用法:
1.
2.
3.
4.
DK4のヘルプファイルを参考してください
C:¥Program Files¥Celoxica¥DK¥Documentation
C:¥Program Files¥Celoxica¥PDK¥Documentation
C:¥Program Files¥Celoxica¥RC100¥Manuals
63
Fly UP