ImpulseCに関する唯一の日本語の解説書。図書館にある。 ※コーディングが微妙つか、読みにくい。マクロもっと使えや、streamの命名とかわかりやすくしろや禿げ

※本を読みながら付けたメモなので、突然話が逸れたりするよ

目次

SECTION 2

  • 2-1-1 ハードウェア設計フロー

  設計フロー

1.ビヘイビア記述 → ImpluseCで記述
2.ビヘイビアでのシミュレーション、動作合成 → CoDeveloper
3.論理合成 → ISE(XST)
4.配置配線 → ISE(Implement Design)
5.FPGA用のデータの作成 → ISE(Generate Programming File)
6.FPGAへのデータ転送 → ボード付属のオリジナルプログラム(BitCfg)
  • 2-1-2 Impulse Cの関数
	・SWとHW部分、またはHW部分同士を接続するインターフェイス(co_register_create, co_stream_create, co_siganl_create)
	・HW部分の入力・出力(co_port_create)
	・プログラム中でのHWになる部分の指定(co_proces_config)
	・ビット幅指定を行う宣言(co_unit)
	・HW部分を含んだシミュレーションをするための初期化、並びに実行(co_initialize, co_execute)
  • 2-1-5 FPGAのピン固定

    ・Xilinx ピンのアドレスマッピングをUser Constraint Fileで書き込む

SECTION 3

  • 3-1-1 ImpulseCとCoDeveloperの違い
	ImpulseC → ANSI C仕様でのHW/SW協調設計を可能にするライブラリ仕様

    設計入力とシミュレーションに安価なGNU、M$などのコンパイラなどのツールが使える

	CoDeveloper → ImpulseC仕様でのシステム開発をサポートする動作合成を含む開発環境を持つツール

    Impulse-Cの仕様とCoDeveloperのツールをペアで仕様して、初めてCベースのHW開発ができる

  • 3-3  生成されたファイルの役割     ・HelloWorld.c → いわゆるCのプログラムのmainに当たる部分

    ・HelloWorld_hw.c → HWプロセスの中身と各プロセスの接続、mainから読んでいるコンフィグ関数の定義

    ・HelloWorld_sw.c → 二つのSWプロセスの中身

  • 3-3-2 HW部のリソース(HelloWorld_hw.c)
	・co_stream:一種のFIFO

コンフィグレーション関数で三つのプロセス同士の接続情報を記述

	・co_process_create(名前、co_functionプロセスとして使う関数名、引数の数、引数1、引数2, …);

 引数をstreamとして、それを介してプロセス同士をつなぐ

	・co_process_config(HW化したいプロセス名、アトリビュート(co_loc固定)、定数("PE0"固定));
	・co_architecture_create(任意の文字列、"generic"を使っている場合はgeneric、コンフィグ関数名、コンフィグ関数への引数);
	・co_architecture宣言
	・co_architecture co_initialize(int iterations)関数の中身

 基本的にはco_architecture_create関数をリターンするだけ

 VHDLラッパーは、VHDLにだけ存在する特定のファイルではなく、Verilogでも書くことができる。

 ちなみに、VHDLとVerilogを見分けるのは、"process"やファイルの先頭にlibrary ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all;

SECTION 4

  • 4-1, 4-2 カウンタの値を7セグメントLEDに出力させる

 VHDLのラッパーファイルとかよくわかんなかったので、Led_Selという1011などの値を常に出しておくプロセスを作成。LEDの列を選択するようにした。結構かかった

  • 4-3-1 co_signalによる時間制御

P.117

	co_signal宣言
	co_signal:バスのリクエストとアクノレッジの関係のようなもの。片方のプロセスから1クロック分のリクエストが出力されると、リクエストを受けたプロセスからアクノレッジが1クロック分出力される。
	
		+-----------+                               +-----------+
		|           | ----------(Request)---------> |           |
		| process A |                               | process B |
		|           | <-------(Acknowledge)-------- |           |
		+-----------+                               +-----------+
	
	co_signal_create(const char *name):シグナルのクリエイト
	co_signal_post(co_signal signal, int32 val):val=メッセージを別のプロセスに送る
	co_signal_wait(co_signal signal, int32 *ip):別のプロセスのco_signal_postからのメッセージを待つ。

※※※co_signalのコンフィグに関して※※※

理由がよく分からないのだが、co_process_configをシミュレーション時に行うと、cosim_logwindow_initでエラーが発生してしまう。

回避方法としては、

	#ifdef IMPULSE_C_SYNTHESIS
		co_process_config(time_tick_process, co_loc, "PE0");
	#end

として、シミュレーションから外す

これに関連して、co_error.hとerrno.hをインクルードしておく。

使い方

	printf("%s", strerror(co_errno));

SECTION 5

  • 5-1-1 アップダウンカウンタへの仕様の変更
	int32 co_register_get(co_register reg):regの値をint32で読み取る
	void co_register_put(co_register reg, int32 value):regにint32でvalueを書き込む

SW <-> HW : register, stream, signal

HW <-> HW : register, stream, signal

  • > HW -> : port(input, output)
	!co_process_create内の引数は、入力順をしっかり対応させる!

モジュールのインスタンス化の際に、direction_real_enの部分を1'b1に置き換える。

assign p_counter_process_direction_value = counter_direction_value;
 defparam inst1.datawidth = 1;
 cregister inst1(
     .clk(clk),
     .input_en(1'b1),
     .input_data(direction_real_data),
     .output_data(counter_direction_value)
   );

SECTION 6

P.186

  • 6-3-2 回路的に大きな部分はないか?

※〜ここ重要〜※

	Block化:Cのソースを制御文と制御文の間で分割
	 最適化単位のBlock化は、Cのソースを走査して制御文に到達する、あるいは制御ブロックから出るごとに、それまでの部分を一つの最適化単位ブロックとしている。
	つまり、最適化単位ブロックには、代入文と演算のみが含まれることになる。
	 ※制御文:while, for, if, switch文のこと。「}」も制御文の切れ目として扱う。
	Stage化:各Blockを少ないクロックで処理する
	 単位ブロックを最小のクロックで処理するように分析して、最終的にステージとしている。つまり、各1クロックでの処理対象をステージという。
	各ステージには、ステートマシンの各ステートが割り当てられる。

Tools -> Stage Master Exploereを使う

例:時間の桁分けをDIVでやった場合

	|----------------------------------------
	| Clock 
	|----------------------------------------
	|
	|  Block #0:
	|    Stages: 1
	|    Max. Unit Delay: 0
	|
	|												+------------------------+
	|  Block #1 loop:										| sec60++;		 |
	|    Stages: 10											| if(sec60 == 60){	 |
	|    Max. Unit Delay: 7										|			 |
	|												+------------------------+
	|
	|												+---#2に対応するコード---+
	|  Block #2:											| sec60 = 0;	 	 |
	|    Stages: 1											| min60++;		 |
	|    Max. Unit Delay: 7										| if(min60 == 60){	 |
	|												+------------------------+
	|
	|												+----#3に対応するコード----+
	|  Block #3:											|   	min60 = 0;         |
	|    Stages: 1											|   	hour24++;          |
	|    Max. Unit Delay: 7										|   	if(hour24 == 24){  |
	|												+--------------------------+
	|
	|												+------------------#4に対応するコード------------------+
	|  Block #4:											|		hour24 = 0;			       |
	|    Stages: 1											|		IF_SIM(if (iterations++ == 2) break;)  |
	|    Max. Unit Delay: 0										|		}			    	       |
	|												|	}					       |
	|												| }						       |
	|												+------------------------------------------------------+
	|
	|												+---#5に対応するコード---+
	|  Block #5:											|  sec10 =  sec60 % DIV; |
	|    Stages: 2											|   sec6 =  sec60 / DIV; |
	|    Max. Unit Delay: 32									|  min10 =  min60 % DIV; |
	|												|   min6 =  min60 / DIV; |
	|												| hour10 = hour24 % DIV; |
	|												|  hour3 = hour24 / DIV; |
	|												+------------------------+
	|
	|  Block #6:
	|    Stages: 3
	|    Max. Unit Delay: 0
	|  Block #7:
	|    Stages: 3
	|    Max. Unit Delay: 0
	|  Block #8:
	|    Stages: 1
	|    Max. Unit Delay: 0
	|  Block #9:
	|    Stages: 1
	|    Max. Unit Delay: 0
	|----------------------------------------
	| Operators:                            ← 使用したオペレータとデータパス幅のまとめ
	|  3 Adder(s)/Subtractor(s) (6 bit)
	|  6 Divider(s) (32 bit)
	|  1 Comparator(s) (2 bit)
	|  3 Comparator(s) (7 bit)
	|----------------------------------------

※パイプライニングが適用された場合 See ImpulseC-syn-report-howto-read.ppt

	|  Block #1 pipeline:                        ← パイプライン化ブロック
	|    Latency: 3                             ← パイプライン段数
	|    Rate:    2                             ← 1つの出力が得られるサイクル数
	|    Max. Unit Delay: 148
	|    Effective Rate: 296                       ←  1つの出力が得られる総ユニットディレイ。最適パイプライン化のための、効率比較の基準値小さいほど良い
	|                 Rate × Max. Unit Delay
	|  ------            

Yngwie J. Malmsteen様用しおり  j∬-●3●)ハ   < 今日はここまで読んだ

メモはメモ

Vertex4のI/Oスタイル

PAD→外に出ている配線

OUTBUF→スレッショルドが変更できる。(変更するのはボードを設計したりする時)

ImpulseCのエラーとその対処

	ERROR: Stream "sim_led_sel" must be created and opened with the same data type
	   →対応するco_stream_openの幅が間違っている。
	UINT_TYPE(hoge)を確認
	   →プロセス作成時の引数宣言の順番と、コンフィグ時の引数の順番が合致していない

プログラミング全般に関して

	・関数は出来るだけ短く。100行くらい
	・コメントを書く
	・組み込み関数を出来るだけ使う
	・変数や関数には分かりやすい名前をつける
	・意味を示さない関数名、変数名の使用はダメ。ゼッタイ
	・定数はできるだけマクロ
	・マクロ用のヘッダーファイルを作る
	・switch文のcaseは直接定数値でなく、マクロにする(せめてコメント)
	・配列のサイズは適切に。ちゃんと最大サイズを調べる
	・下手な関数をわざわざ作らなくても、標準関数を使う
	・ポインタを理解していない。(ImpulseCには関係ないかな)

個人的なImpulseCの記述時の取り決め

	           sim_:コンフィギュレーションにおいては、シミュレーション時に使うものは(#ifndef IMPULSE_C_SYNTHESIS)はsim_をつける
	          real_:コンフィギュレーションにおいては、ハードウェア時に使うものはreal_をつける
	        common_:コンフィギュレーションにおいては、シミュレーション時にもハードウェア時にも使うものはcommon_をつける
	ImpulseC_MACROs:マクロは出来るだけ、このマクロ用のヘッダーファイルに集める
 co_architecture_create:ここの第一引数""は最初に名前を付けてはいけない*[[ImpulseC/CoDeveloperについて]] 

きょう:1万人 きのう:0万人 ぜんぶ:246万人


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2019-08-29 (木) 00:03:49