SystemC高位合成のはじめ方


#はじめに
Vivado HLSの環境でSystemCをはじめる手順を記載します。

#環境

- Vivado HLS 2016.2(他のバージョンでも可)
- Model Sim 10.5b(他のバージョンでも可)

Vivado HLSは当然ながらSystemCで高位合成する環境です。
Model Simは.vcd波形を出力するのに使用します。

#高位合成手順

![スクリーンショット 2017-07-13 23.36.52_40.png](https://qiita-image-store.s3.amazonaws.com/0/97833/fdd1d034-1eaf-1ab4-d298-92b218d6a6fd.png)
Vivado HLSを起動してCreate New Projectlを選択します。

![スクリーンショット 2017-07-14 00.02.17_60.png](https://qiita-image-store.s3.amazonaws.com/0/97833/df8a9b40-6bb0-e6cd-7799-59b536094fe1.png)
プロジェクト名とディレクトリを入力します。
次とその次は任意なのでNEXTで飛ばします。

![スクリーンショット 2017-07-14 00.07.46.png](https://qiita-image-store.s3.amazonaws.com/0/97833/b71f5486-f304-503f-4101-46d72affb5e6.png)
周期とFPGAの型番を設定します。
※FPGAの型番は自分のターゲットデバイスから決めてください(特にない人は適当にZYBOの**xz7z010clg400-1**を選択してください)。

![スクリーンショット 2017-07-14 00.19.20.png](https://qiita-image-store.s3.amazonaws.com/0/97833/ab6de5a0-637c-2862-e757-4c54f7274f5c.png)
ExplorerのSourceにモジュールの.cppを追加記述し、Test Benchにはsc_mainの.cppを追加し記述します。
モジュールの**.h**は.cppと**同階層**にファイルを置くことで勝手に読み込まれるのでExplorerのSourceに追加しなくてもいいです。
※**追記Vivado HLSのサンプルプロジェクトを見るとお作法的にはTest Benchに.hを追加するみたいです。**

以下にサンプルでビデオ信号っぽい物を出力するコード記載します。

```cpp:vid_sync.h
#ifndef VID_SYNC_H
#define VID_SYNC_H

#include <systemc.h>

SC_MODULE(vid_sync)
{
	//Ports
	sc_in  <bool>  clock;
	sc_in  <bool>  reset;
	sc_out <bool>  vsync;
	sc_out <bool>  hsync;
	sc_out <bool>  valid;
	sc_out <sc_uint<10> > data;

	//Variables

	//Process Declaration
	void Prc1();

	//Constructor
	SC_CTOR(vid_sync)
	{
		//Process Registration
		SC_CTHREAD(Prc1,clock.pos());
		reset_signal_is(reset,true);

	}
};

#endif

```

```cpp:vid_sync.cpp
#include "vid_sync.h"

#define hf_blank 2
#define hb_blank 3

void vid_sync::Prc1()
{
   //Initialization
	vsync.write(0);
	hsync.write(0);
	valid.write(0);
	data.write(0);
	wait();

	while(true)
	{
		wait();
		vsync.write(1);
		for(int v=0; v<480; v++)
		{
			hsync.write(1);
			wait();
			vsync.write(0);
			hsync.write(0);
			wait(hf_blank);
			for(int h=0; h<640; h++)
			{
				data.write(h);
				valid.write(1);
				wait();
			}
			data.write(0);
			valid.write(0);
			wait(hb_blank);
		}
	} //end of while(true)
}

```

```cpp:sc_main.cpp

#include <systemc.h>
#include "vid_sync.h"


int sc_main (int argc , char *argv[])
{


	sc_clock clock("clock",10,SC_NS); // Create a 10ns period clock signal
	sc_signal <bool> reset;
	sc_signal <bool> vsync;
	sc_signal <bool> hsync;
	sc_signal <bool> valid;
	sc_signal <sc_uint<10> > data;
	vid_sync U_vid_sync("U_vid_sync");


	// Generate a clock and reset to drive the sim
	U_vid_sync.clock(clock);
	U_vid_sync.reset(reset);
	U_vid_sync.vsync(vsync);
	U_vid_sync.hsync(hsync);
	U_vid_sync.valid(valid);
	U_vid_sync.data(data);

    sc_trace_file *trace_f;
    trace_f = sc_create_vcd_trace_file("wave");

    sc_trace( trace_f, clock, "clock");
    sc_trace( trace_f, reset, "reset");
    sc_trace( trace_f, vsync, "vsync");
    sc_trace( trace_f, hsync, "hsync");
    sc_trace( trace_f, valid, "valid");
    sc_trace( trace_f, data, "data");

	// start simulation
	sc_start(20, SC_NS);
	reset = 1;
	sc_start(20, SC_NS);
	reset = 0;
	sc_start(20*640*480*2, SC_NS);

	return 0;
};

```

コードが完成したら**Run C Simulation**を実行してください。
Explorer->ProjectName->solution1->csim->buildの中に**.vcd**ファイルが出力されていると思います。
![スクリーンショット 2017-08-05 12.19.52.png](https://qiita-image-store.s3.amazonaws.com/0/97833/7c581826-5e64-8d00-3669-4830fb95357b.png)


#SIM手順

Model Simで波形を見る場合**.vcd**を**.wlf**に変換するコマンドがあるので変換してから波形を見ます。
参考URL : https://www.altera.co.jp/support/support-resources/knowledge-base/solutions/rd07062010_692.html

![スクリーンショット 2017-08-05 15.46.44_.png](https://qiita-image-store.s3.amazonaws.com/0/97833/15f516b7-e715-e1b4-e8f9-23757d434cf0.png)


ModelSimのコマンドラインから.vcdのファイルがあるディレクトリに移動します。
移動したら以下のコマンドを実行します。

```code
vcd2wlf wave.vcd wave.wlf
```

すると同ディレクトリにwave.wlfが作成されると思います。

あとはModelSimの**OpenFile**で**wave.wlf**を読み込めば波形が確認出来ます。

![スクリーンショット 2017-08-05 13.09.05.png](https://qiita-image-store.s3.amazonaws.com/0/97833/86d62b0d-cf4a-3c61-8a92-d139db5c0722.png)

#合成データ生成手順

Simで動作確認が出来たら、Projects Settings->Synthesisで**Top Function**(上のサンプルの場合**vid_sync**)を設定します。
![aa.png](https://qiita-image-store.s3.amazonaws.com/0/97833/a2eeda45-0bdb-b644-088e-74afcf52f7c2.png)

あとは**C Synthesis**を実行すると**Explorer->ProjectName->solution1->syn**以下にRTLが出力されています。

![スクリーンショット 2017-08-06 03.18.24.png](https://qiita-image-store.s3.amazonaws.com/0/97833/54889351-e7c1-969b-afa8-85f55ce76bde.png)



#おわりに
Qiitaを見る限りSystemCは流行ってなさそうですが(**投稿時のタグ数2**)これからたくさん情報が載ればいいなぁと思っています。SystemCの超入門として[SystemCプログラミング基礎講座](https://www.amazon.co.jp/SystemC%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E5%9F%BA%E7%A4%8E%E8%AC%9B%E5%BA%A7-%E5%A1%9A%E7%94%B0-%E9%9B%84%E4%B8%80/dp/4798109894/ref=pd_sim_14_1?_encoding=UTF8&psc=1&refRID=CX6EB6ERVTB2QZ3MZ7NQ)という本が分かりやすかったです(2006年のものなので古い)。SystemCの公式ドキュメントは[accellera](http://www.accellera.org/downloads/standards/systemc)からDL出来ると思います。

![スクリーンショット 2017-08-07 20.22.36.png](https://qiita-image-store.s3.amazonaws.com/0/97833/04fba03c-0496-f1e0-5066-601cdcf57503.png)
あとVivado HLSのスタートページにあるOpen Example Projectのコードを参考にするのも勉強になると思います。