情処研報 2007-ARC-171/2007-EMB-3 (2007年1月)

高位合成システム CCAP におけるハードウェア関数からのソフトウェア関数の呼び出し
西村 啓 成†石 浦 菜 岐 佐†
石 守 祥 之†神 原 弘 之†† 冨 山 宏 之†††我々は, C プログラムを入力として, 指定した関数をソフトウェアから呼び出し可能なハードウェ
アに合成する高位合成システム CCAP (C Compatible Architecture Prototyper) を開発している.
CCAP が合成するシステムでは, ハードウェアに合成した関数 (以下, ハードウェア関数と呼ぶ) を,特別なインターフェースなしにソフトウェア及びハードウェア関数から呼び出すことができる. 本稿
では, CCAP においてハードウェア関数からソフトウェア関数を呼び出す手法を提案する. また, マルチスレッドあるいはシングルスレッドを用いて実装する例についても示す. このうちシングルスレッドを用いる手法を実装し, シミュレータ上で実際にハードウェア関数からソフトウェア関数を呼び出せることを確認した.

Calling Software Functions from Hardware Functionsin High Level Synthesizer CCAPMasanari Nishimura,† Nagisa Ishiura,† Yoshiyuki Ishimori,†Hiroyuki Kanbara†† and Hiroyuki Tomiyama†††
We are developing a high-level synthesizer named CCAP (C Compatible Architecture Prototyper), which synthesizes functions in C programs into hardware callable from software. Thehardware functions (the functions synthesized into hardware) can be called from software andthe other hardware funcstions without designing speciﬁc interface in the synthesized system.
In this paper, we propose a novel framework in which the hardware functions can call software
functions in CCAP, for which we show both multi-thread and single-thread implementation
schemes. We veriﬁed the correctness of the proposed method (single-thread version) throughregister transfer level simulation.

1. は じ め にレーション速度等の観点から C/C++ のようなプログラミング言語に対する期待が高まりつつある. しか

近年, VLSI の回路規模や複雑度は増大の一途をたし, C/C++ を入力にとることのできる既存の高位合どっており, その設計効率を向上させることが重要な成ツールは, 関数呼び出しやポインタの合成に関して課題となっている. 高位合成技術は, 設計者がハード制約が多いという問題があった.

ウェアの動作を記述し, そこから自動的にレジスタ転送

そこで我々は, 入力として与えられた C プログラレベルの回路記述を得る技術であり, 設計効率の問題

ム中の指定された関数を, 残りのプログラムから呼びに対する一つの解決策として注目を集めている. 入力出し可能なハードウェアに合成する高位合成システムとなる動作記述には, ハードウェア記述言語 (VHDL,CCAP (C Compatible Architecture Prototyper) を

Verilog HDL 等) やシステム記述言語 (SpecC, Sys-開発している. CCAP では, CPU で実行される部分

temC 等) を用いるのが一般的だが, 生産性やシミュとハードウェアに合成した関数がメモリ空間を共有しており, 主記憶を通してデータや制御をやり取りでき† 関西学院大学
Kwansei Gakuin University†† 京都高度技術研究所
ASTEM††† 名古屋大学
Nagoya University

る. このため, 特別なインターフェースを設計することなく関数呼び出しやポインタを合成可能である.
現在 CCAP では, CPU で実行するソフトウェアからのハードウェア関数の呼び出し, およびハードウェア関数からの別のハードウェア関数の呼び出しが可能

である. 本稿では, これに加えてソフトウェア関数かCプログラム合成されるシステムらハードウェア関数を呼び出す手法を提案する . こ

hw1()

hw1()

れにより, 例えば内部で動的記憶割り当てを行う関数

2)

hw2()

hw2()

もハードウェア化が可能となり, 高位合成を適用でき...

...

るプログラムの範囲を大幅に拡大することができる.

sw1()

本稿では, ソフトウェア関数からハードウェア関数をsw2()呼び出す具体的な方法として, マルチスレッドを用い...

る手法とシングルスレッドによる手法を示す. シング
ルスレッドによる手法を実装し, シミュレーションをArbiter

MMCPU

図 1 CCAP が合成するシステム
Fig. 1 A system synthesized by CCAP.

行ったところ, 実際にハードウェア関数からソフトウェ
ア関数を呼び出せることが確認できた.
高位合成ツールでは必要だったインターフェースを設

2. 関 連 研 究

計せずとも関数呼び出しを合成することができる. ま

C/C++ 等のプログラミング言語を入力とする高た, SpC では不可能だったソフトウェアとハードウェ

位合成ツールの研究, 開発は近年盛んに行われており,ア関数の間におけるポインタのやり取りを実現できる

Catapult C Synthesis3) や eXCite4) 等, 市販されてため, ソフトウェアが確保した動的メモリ領域をハードウェアに渡したり, 大規模なオブジェクトを参照渡いるものも多く存在する.
これらのツールを用いて C プログラム中の関数呼しで効率よく受け渡すことが可能である.

び出しを合成する場合, 関数をインライン展開する, あさらに, ハードウェア側からソフトウェアを呼び出

るいは関数をハードウェアに合成し, CPU と各ハーす手法に関する研究はこれまで行われて来なかった.

ドウェアの間に専用インターフェースを設計するのが本研究で提案する手法により, ハードウェア関数から一般的である. しかし, インライン展開を行うと, 複ソフトウェア関数を呼び出すことができるようになれ

数回の関数呼び出しに対して同じハードウェアが生成ば, ハードウェア関数自身が malloc を呼び出して動されるため, 回路面積が増大してしまう. また, イン的メモリ領域を確保することが可能となる. また, ハーターフェースの設計には設計コストが必要である.

ドウェア関数中に含まれる大規模な処理や例外処理を高位合成におけるこの問題を解決する手法として,ソフトウェアで実行することにより, 回路規模を抑制

岡田らは「ソフトウェア/ハードウェア協調設計手法」

することもできる. すなわち, 高位合成を適用できる

5)

C プログラムの範囲を大幅に拡大することができる.

を特許として公開している . これはソフトウェアとハードウェアの間にデータ授受専用のバッファ RAMを配するもので, 個々のハードウェアに対してインター3. 高位合成システム CCAPフェースを設計する必要はない. しかし, データの参3.1 CCAP の合成するシステム

照渡しができず, ハードウェアからハードウェアを呼図 1 に, CCAP を用いて合成するシステムの構成び出すこともできないため, 合成可能なプログラムのを示す. CCAP は, 入力となる C プログラム中の一クラスが制限される.

部の関数 (設計者が指定) を, ソフトウェアから呼び

SpC6) は静的な解析とタグ付けにより, C 言語のポイ出し可能なハードウェア関数に合成する. 一方, 残りンタの合成を可能にした高位合成ツールである. また,の関数はソフトウェアとしてそのまま CPU で実行す専用ハードウェアを導入することにより malloc/freeる. CPU とハードウェア関数はメモリ空間を共有し,の合成も実現している. しかし, グローバル変数へのポ主記憶上に配置するグローバル変数への代入および参インタの合成や, ソフトウェアとハードウェア関数の照により, データや制御の受け渡しを行う.

間のポインタの受け渡しはサポートしていない. この

CCAP では, CPU や複数のハードウェア関数がそため, ソフトウェアで確保した動的メモリ領域をハーれぞれ主記憶にアクセスするため, アクセス要求を適ドウェア関数に渡すことはできない.

切に調停する必要がある. これは, 各デバイスと主記

これらに対し我々の CCAP では, CPU で実行され憶の間にアービタが介在し, アクセス要求を先着順 (同るソフトウェアとハードウェア関数がメモリ空間を共時の場合は CPU を優先) に調停することにより行う.

有しており, これらが主記憶上のグローバル変数を通

アービタは受理したメモリアクセス要求を主記憶に送じてデータや制御をやり取りする. このため, 従来のり, 他のデバイスには stall 信号を送る.

Cプログラム

callee の実行開始と終了を制御する. 1 が実行中を表し, 0 が非実行中を表す.

SUIF

スケジューリング

CDFG生成バインディング

CDFG

RTL生成

データフロー解析

RTLcallee から caller に渡す返り値を格納する.

HDL生成

図 3 (a) にあるように, caller はまず引数 x1 ,Verilog HDL..., xn の値をグローバル変数 ARG callee 1, ...,CCAP

図 2 CCAP の合成の流れ
Fig. 2 Flow of synthesis in CCAP.

•ARG callee 1, ..., ARG callee ncaller から callee に渡す引数を格納する.

•RET callee

ARG callee n に代入する.

続いて

RUN calleeに 1 を代入すると, callee が処理を開始する.

RUN callee の値は callee の処理が終了すると 0になるので, callee はその値を監視しながら待機す
int caller() {int y;...
y = callee(x1, ..., xn);...
}

int callee(a1, ..., an) {int r;...
return r;}

る. その後, 返り値をグローバル変数 RET callee から受け取り, 残りの処理を続行する.
一方 callee 側では, 図 3 (b) にあるように, まず

RUN callee を監視しながら, その値が 1 になるまで
void caller() {int y;...

void callee() {while (1) {wait1(_RUN_callee);int r;
int a1 = _ARG_callee_1;...
int an = _ARG_callee_n;_ARG_callee_1 = x1;...
_ARG_callee_n = xn;_RUN_callee = 1;
wait0(_RUN_callee);}y = _RET_callee;...

(a) 呼び出し側の変換}}待機する. その後, ARG callee 1, ..., ARG callee nから引数を受け取り, 関数本体の処理を実行する. 処理が終了したら, RET callee に返り値を書き込み,RUN callee の値を 0 にして, 処理が終了したことを...

caller に伝える. その後, 再び RUN callee の監視_RET_callee = r;
_RUN_callee = 0;に戻る.

(b) 関数側の変換

図 3 ハードウェア関数の呼び出しのための変換
Fig. 3 Transformation for calling hardware function.

4. ハードウェア関数からのソフトウェア関数の呼び出し
グローバル変数を用いてデータや制御を受け渡せば,3.2 節と同様の枠組みでハードウェア関数からソフトウェア関数を呼び出すことが可能である. このためにCCAP の合成の流れを図 2 に示す. 入力となる Cは, グローバル変数を監視するプロセスを CPU で実プログラムは SUIF7) によって中間表現に変換し, そ行する必要があるが, これはマルチスレッドを用いてこから CDFG (Control Data Flow Graph) を生成す容易に実現できる. また, ソフトウェアからハードウェる. これに対してさらにデータフロー解析, スケジューア関数を呼び出した後の CPU の待機状態を利用すリング, バインディングを行ってレジスタ転送レベルれば, シングルスレッドでも同等の機能を実現可能での中間表現を得る. この中間表現を元に Verilog HDLある.

記述を生成する.

4.1 マルチスレッドによる実現

3.2 CCAP におけるハードウェア関数の呼び出し

マルチスレッドが利用可能な環境では, 1 つのソフ

CCAP におけるハードウェア関数の呼び出しは, 制

トウェア関数につき 1 つのスレッドを CPU 上で作御やデータの受け渡しのために主記憶上に確保したグ成し, ソフトウェア関数の制御用グローバル変数を監ローバル変数へのアクセスに変換する. ただし, 再帰視するスタブ関数を各スレッドにおいて実行すること呼び出しは扱わないものとする.

により, ハードウェア関数からソフトウェア関数を呼図 3 は, 関数 caller からハードウェア関数 callee

び出す手法を提案する. スタブ関数は制御用グローバを呼び出す C プログラムを変換する例である. 呼び

ル変数の監視の他, 引数用グローバル変数からの引数出し元である caller はソフトウェアでもハードウェの受け取り, 通常の方法でのソフトウェア関数の呼びアでもよい. まず, ハードウェア関数 callee に対し出し, 返り値用グローバル変数からの返り値の受け取て, 以下の 3 種類のグローバル変数を作成する.

りを行う.

•RUN callee

図 4 (a) に, マルチスレッドを用いた制御用グローバ

メインスレッド

スレッド1

スレッド2

CPU

main()

sw1_stub()sw2_stub()

CPU

主記憶

_RUN_hw_RUN_sw1_RUN_sw2

主記憶

(実行)

(待機)

(待機)

hw()

HW

(a) マルチスレッドによるグローバル変数の監視
スレッド1

main()(待機)_RUN_hw(a) シングルスレッドによるグローバル変数の監視

スレッド2

メインスレッド

呼び出し(待機)主記憶HW

sw1 ()(実行)

main()_RUN_hw

sw1_stub()_RUN_sw1

1を代入_RUN_sw2(実行)

sw1 ()CPU_RUN_sw1

hw()

HW

(待機)

メインスレッド

メインスレッドsw2_stub()(実行)CPU呼び出しmain()(待機)_RUN_sw2

hw()

(実行)

(b) ハードウェア関数からのソフトウェア関数呼び出し
図4

マルチスレッドによるハードウェア関数からのソフトウェア関数の呼び出しFig. 4 Multi-thread scheme of calling software functions
from hardware functions.

void calleestub() {while (1) {while (!_RUN_callee) {}_RET_callee = callee(_ARG_callee_1, ...);_RUN_callee = 0;}}

図 5 スタブ関数の例
Fig. 5 An implementation example of stub function.

主記憶HW_RUN_hw_RUN_sw1

1を代入_RUN_sw2

hw()

(実行)

(b) ハードウェア関数からのソフトウェア関数呼び出し
図 6 シングルスレッドによるハードウェア関数からのソフトウェ
ア関数の呼び出し
Fig. 6 Single-thread scheme of calling software functions
from hardware functions.

バル変数 ARG callee 1, ..., ARG callee n の値を引数として, 通常の関数呼び出しと同じように calleeを呼び出す. 返り値はグローバル変数 RET calleeに代入する. その後, RUN callee に 0 を代入してcaller に実行終了を通知し, 再び RUN callee の監視に戻る. CPU 上で実行される他のソフトウェア関数からは, スタブ関数を介さずに呼び出すことにより,そのまま呼び出すことができる.

ル変数の監視について示す. この図において, main(),4.2 シングルスレッドによる実現

sw1 stub(), sw2 stub() は CPU 上で実行するソフマルチスレッドによる実現手法は, OS やライブラトウェア関数, hw() はハードウェアに合成する関数でリ等の利用が前提となる. また, 複数のスレッドを常ある. CPU 上には, メインスレッドの他に 2 つのス時実行させておくオーバヘッドが性能上の問題となるレッドが存在し, これらはそれぞれ sw1() のスタブ関場合もある. ハードウェア関数の実行終了を待ち合わ

数 sw1 stub() と, sw2() のスタブ関数 sw2 stub()せるための CPU の待機状態を利用することにより,を実行している. 各スタブ関数はバックグラウンドでシングルスレッドでハードウェアからソフトウェア関動作し, 制御用グローバル変数を監視しながら, その数を呼び出す手法を提案する.

値が 1 になるまで待機する. ここで, 図 4 (b) にある

図 6 に, CPU の待機状態を用いてハードウェア関ように hw() が RUN sw1 に 1 を書き込むと, それを数からソフトウェア関数を呼び出す手法を示す. ソフ

監視する sw1 stub() がこれを検知し, sw1() を呼びトウェア側からハードウェア関数 hw() を呼び出すと,出す.

ハードウェア関数が実行を開始し, CPU はハードウェ

図 5 は, 各スレッドで実行するスタブ関数の例であア関数の制御用グローバル変数を監視しながら待機状る. 関数 calleestub は関数 callee のスタブ関数であ態に入る. この待機状態を, 図 6 (a) にあるように,り, callee の制御用グローバル変数 RUN callee を複数のソフトウェア関数の制御用グローバル変数に対監視する. この値が 1 になると, calleestub はグローする監視を繰り返す処理に書き換える. ハードウェア

void caller() {int y;...

void caller() {int y;...
_ARG_callee_1 = x1;...
_ARG_callee_n = xn;_RUN_callee = 1;

_ARG_callee_1 = x1;...
_ARG_callee_n = xn;_RUN_callee = 1;①}

while (_RUN_callee) {}②

y = _RET_callee;}(a) 従来の待機状態

while (_RUN_callee) {if (_RUN_sw1) {_RET_sw1 =sw1(_ARG_sw1_1, ...);} else if (_RUN_sw2) {...
} else if (_RUN_swn) {_RET_swn =swn(_ARG_swn_1, ...);}}

main() {ソート対象となる配列 a の初期化;
bucket_sort(a) の呼び出し;}
bucket_sort(a[]) {バケット数を求める;
malloc を呼び出してバケットの領域を確保;
バケットにソート情報を生成;
バケット内の情報に従って配列をソート;}

図 8 実験用 C プログラムの概要
Fig. 8 Outline of experimented C program.

y = _RET_callee;(b) 待機状態を利用した監視

図 7 待機状態を利用したグローバル変数の監視
Fig. 7 Polling of global variables during the wait state.

ることなどから, CPU 性能に余裕があるシステムに向く. 特にマルチ CPU を備えたシステムの場合, 複数のスレッドの実行を各 CPU に振り分けることで,パフォーマンスの低下を抑えながらハードウェア関数からのソフトウェア関数の呼び出しを達成することが関数からいずれかのソフトウェア関数に対して, その可能である. 一方シングルスレッドによる実現手法は,制御用グローバル変数に 1 が代入されると, CPU 側特にライブラリ等を必要としないため, 環境を選ばなでこれを検知し, 引数用グローバル変数の値を引数といという利点がある. また, CPU の待機状態を活用すして, 該当するソフトウェア関数を呼び出す. ソフト

るため, CPU で実行される他のソフトウェアプロセウェア関数の実行が終了すると, 受け取った返り値をスのパフォーマンスを損なうこともない.

グローバル変数に書き込み, 制御用グローバル変数の値を 0 にして, ソフトウェア関数の実行終了を示す.

5. 実

験

その後, CPU は再び待機状態に戻り, hw() が終了す

本稿で提案した手法のうち, シングルスレッドによるまで, ソフトウェア関数の制御用グローバル変数のる実装手法に基づき, ハードウェア関数からソフトウェ監視を続ける.

ア関数を呼び出す実験を行った.

図 7 は CPU の待機状態中に実行する監視処理の

図 8 に実験用の C プログラムの概要を示す. main実装例である. 図 7 (a) は従来の待機状態, (b) は監関数を CPU で実行し, bucket_sort 関数をハード視処理を加えた新しい待機状態である. ➀ の while

ウェア化して main から呼び出した. CPU には MIPS

文はハードウェア関数 callee の実行終了待ち状態をR2000 (ソフトコア) を用い, bucket_sort を手設計

busy loop で実装したものである. 従来の CCAP のでハードウェア化したもの及びアービタとともに RT実装では, ハードウェア関数の制御用グローバル変数レベルでシミュレーションを行った. bucket_sort 内に対する値のテストを繰り返すのみであった. これを部から呼び出す malloc は, MIPS R2000 用の C ラ

図 7 (b) ➁ のように, callee から呼び出され得るソイブラリが利用できないため, malloc と同様の動作をフトウェア関数の制御用グローバル変数 RUN sw1 , ...,行うソフトウェア関数を実装した. 以上のシステムをRUN swn をテストする処理を while 文の本体に加えModelSim (XE II 5.8c) でシミュレーションし, mainる. もしいずれかの値が 1 ならば, 引数用グローバルから起動された bucket_sort が malloc を呼び出し変数の値を引数として, 該当するソフトウェア関数をてバケット用領域を動的に割り当て, 正しくソートを通常の方法で呼び出す. ➁ のループはメインスレッド行うことを確認した.

で実行され, 呼び出されるソフトウェア関数の数にかかわらず 1 つである. これにより, マルチスレッドによる実現手法と同等の機能をシングルスレッドで実現することが可能となる.

6. む す び
本稿では, 高位合成システム CCAP においてハードウェア関数からソフトウェア関数を呼び出す方法を4.3 提案手法の利点と欠点提案し, そのマルチスレッドによる実装法とシングルマルチスレッドによる実現手法は, OS やライブラスレッドによる実装法を示した. また, シングルスレッリによるサポートが必要であることや, 複数のスレッドによる手法を実装し, 実際にハードウェア関数からドをバックグラウンドで常時実行させておく必要があ

ソフトウェア関数を起動できることをシミュレーショ

ンにより確認した.
今後, ソフトウェア関数からハードウェア関数を呼び出すための処理を自動的に生成できるように, 本稿で述べた手法を CCAP に実装する予定である. また,
現在 CPU の待機状態は busy loop により実現している. これを, 割り込みを用いて実装することも検討していきたい.
謝辞 本研究に際し, シミュレータによる実験に御協力頂いた立命館大学の梅原直人氏, 中谷嵩之氏に感謝致します. また, 御討論頂いた京都大学の杉原有理氏,及び関西学院大学石浦研究室の諸氏に感謝致します.

参 考 文 献1) 西口 健一, 石浦 菜岐佐, 西村 啓成, 神原 弘之,冨山 宏之, 高務 祐哲, 小谷 学: “ソフトウェア互換ハードウェアを合成する高位合成システム
CCAP における変数と関数の扱い,” 信学技報,
VLD2005-12 (Dec.2005).
2) 西村 啓成, 石浦 菜岐佐, 石守 祥之, 神原 弘之,
冨山 宏之: “高位合成システム CCAP におけるハードウェア関数からのソフトウェア関数の呼び出し,” 情処関西支部大会, C-05 (Oct.2006).
3) http://www.mentor.com/.
4) http://www.yxi.com/.
5) 岡田 和久: “ソフトウェア/ハードウェア協調設計
手法,” 公開特許広報, 特開 2003-114914 (2003).
6) L.Séméria, K.Sato, and G.De Micheli: “Synthesis of Hardware Models in C With Pointers and Complex Data Structures,” in IEEE
Trans.VLSI Systems, vol.9, no.6, pp.743–756(Dec.2001).
7) http://suif.stanford.edu/.