LoginSignup
2
3

More than 5 years have passed since last update.

フィボナッチを求める回路をSynverllとMessagePack-RPCでFPGAに実装してみた(シミュレーション編)

Last updated at Posted at 2015-11-18

はじめに

Synverllは石原ひでみさんが開発している高位合成ツールです。詳細は以下のページや記事を参照してください。

今回はCで記述したフィボナッチを求めるプログラムをSynverllを使って高位合成したRTLをMessagePack-RPCと組み合わせてシミュレーションする例を示します。

用意するもの

ブロック図

akgeo2.jpg

ソースコード

フィボナッチを求めるCのソースコードです。

fib.c
int fib(int n)
{
  int curr = 0;
  int next = 1;
  int i;
  for(i = 0; i < n; i++) {
    int prev = curr;
    curr = next;
    next += prev;
  }
  return curr;
}

手順

Synverllをインストール

Synverllのインストールは上の記事を参照してください。
Synverllをコンパイルするには LLVM 3.6 以降がインストールされていなければなりません。

shell% git clone https://github.com/aquaxis/synverll
shell% cd synverll
shell% make

リポジトリと各submodule をダウンロード

shell% git clone git://github.com/ikwzm/msgpack-vhdl-examples.git
shell% cd msgpack-vhdl-examples
shell% git submodule init
shell% git submodule update

fib.cを高位合成

shell% cd examples/fibonacci/src/main/synverll
shell% synverll
Synverll Rev 0.04
 Synthesis for Verilog HDL using LLVM
 C Source to Verilog-HDL Convertor
 Hidemi Ishihara <hidemi(at)aquaxis.com>

Usage:
 synverll [-d] C_SOURCE_FILENAME
  -d: Debug Mode(output a debug file)

shell% synverll fib.c
topname: fib_top
[C Source Parser Start]
Open Filename: fib.c
 -> Parser for C Source
 -> Create Process Source
 -> Create Header Source
 -> Function Count: 1
[LLVM Compile Start]
[LLVM-IR Function Parser Start]
[Parsing struct type for LLCM-IR]
 -> Create Stage for LLVM-IR
 -> Parser Memory Tree
 -> deploy_array_type
 -> Create Verilog HDL for Proc Tree
 -> Output Verilog HDL: module = fib
 -> Output Memory Map
[Create top Module]

ラッパー回路の作成

Synverllが生成するVerilog-HDLは次のようになっています。

fib.v
module fib(
    input __func_clock,
    input __func_reset,
    input __func_start,
    output reg __func_done,
    output reg __func_ready,

    // Memory Singal
    input [31:0] __args_n,
    // Call Singal
    // Result Singal
    output reg [31:0] __func_result

);
   :
 (中略)
   :
endmodule

入出力ポート名が、アンダーラインで始まっているので、このままだとVHDLの命名規則にひっかかって(VHDLはアンダーラインから始まる名前は×)接続できないので、ラッパー回路を用意します。ここはちょっと面倒臭いですね。

fib_wrap.v
module fib_wrap(
    input  system_clock,
    input  system_reset,
    input  func_start,
    output func_done,
    output func_ready,
    input [31:0]  args_n,
    output [31:0] func_result
);
fib u_fib(
    .__func_clock(system_clock),
    .__func_reset(system_reset),
    .__func_start(func_start),
    .__func_done(func_done),
    .__func_ready(func_ready),
    .__args_n(args_n),
    .__func_result(func_result)
);
endmodule

テストシナリオの作成

すでに作成済みのテストシナリオ(examples/fibonacci/src/test/scenarios/test_1_32.snr)を用意しています。このテストシナリオを使う場合は、以下の手順は飛ばしてください。

AXI4_Stream_Master_PlayerおよびAXI4_Stream_Slave_Player用のテストシナリオを作ります。

shell% cd examples/fibonacci/src/test/scenarios
shell% ruby test_1_32.rb

test_1_32.rb はテストシナリオ(YAML形式)を生成するためのrubyスクリプトです。

Vivado プロジェクトの作成

Vivado プロジェクトを作成するためのTclファイル(create_project.tcl)を用意しています。
Vivadoを起動して次のメニューからTclファイルを実行してください。

Vivado > Tools > Run Tcl Script... > examples/fibonacci/sim/vivado/synverll/create_project.tcl

シミュレーションを実行

前節で作った Vivado プロジェクトを開き、次のようにシミュレーションを実行してください。

Vivado > Flow > Run Simulation > Run Behavioral Simulation

結果

とりあえずシミュレーションすることは出来ました。
n=0~42までの計算結果もあっています。
演算のビット幅を64ビットにする方法がわからなかったので、結果が32ビットに収まる範囲のnでしか計算していません。
参考までにn=2の時のシミュレーション波形を示します。
fibonacci_synverll.jpg
シミュレーション時のログは次の通りです。
fibonacci_synverll_log.jpg

参考

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3