FPGA Lecture for LUPO and GTO Vol. 1 2010, 31 August (revised 2013, 19 November) H. Baba
Contents FPGA の概要 LUPO の基本的な使い方 New Project Read and Write 基本的な Behavioral VHDL simulation Firmware のダウンロード
FPGA とは Field Programmable Gate Array CLB CLB CLB DCM IOB 外部 IO CLB CLB CLB Clock Manager SRAM 配線スイッチ CLB CLB CLB 内部 RAM ロジックの基本単位
CLB と配線 CLB LUT 0 1 2 3 In Out 0 0 0 0 0 0 0 0 1 1 0 0 1 0 1 0 0 1 1 1 0 1 0 0 0 0 1 0 1 1 0 1 1 1 1 1 0 0 0 0 DFF Clock
LUPO について NIM は LVTTL に一回変換している NIM->LVTTL->FPGA FPGA->LVTTL->NIM LVDS はダイレクトに接続 IOB を 2.5V にしているので 2.5V 系しか使えない 8LED 4NIM IN 16 LVDS IO 32 LVTTL IO 4NIM OUT VME Interface (CPLD) User FPGA (Spartan 3E)
New Project for LUPO Device と Design flow は以下のとおり
Design property for GTO
入出力の定義 (LUPO) LED : LED A : CAMAC/VME アドレス CLOCK : 50MHz clock INIT : CAMAC Z/C, VME Init? IP : NIM Input 0-3 IP0 : GCLK 接続の IP0 OP : NIM Output 0-3 LVDSn/LVDSp : LVDS IO 0-15 LVDS_CLKn/p : GCLK 接続のLVDS RD : Data Read WR : Data Write RD_STRB : Read strobe WR_STRB : Write strobe
制約ファイル (UCF) をコピー vlupo.ucf gto.ucf IO 等の制約を書く Association を Implementation にしておかないとヒドイ目にあう
CAMAC/VME を使わない場合は (LUPO) これで十分 vlupo.ucf を Edit Constraints(Text) で編集 UCF に書いてある NET は entity に書いておかないとエラー
簡単に書くと (LUPO) こんな感じ Synthesize -> Implement Design まで通ればたいてい OK
同期回路を作る場合 if, else を使うときは使う signal に対しすべて明示的に値を入れておくのが吉 Warning で確認すべし 非同期的な回路で作られる この場合はちゃんと else の部分で明示的に値を代入してあげること
こういうのは大丈夫な場合が多い event 同期にしてあげると DFF を使ってくれるので期待通りに値が保持される Clock のタイミングでしか値が変化しない
基本的にすべての行は同時に動作する IP(0) e d
ループ回路は注意 回路図的には以下で Latch が作れるが Combinational loop があるよと言われる パルス幅 伝達経路 delay ジッタ等々でうまくいかないこと多し
明示的に DFF を使うと安心 process 文で event を使うと基本的に DFF にしてくれる 回路要素として FDCE(=DFF) を使うと期待通りの動作をしてくれるでしょう
VME/CAMAC バスとのやりとり (Read for LUPO) RD_STRB が 1 の時に RD にデータを保持しておく
VME/CAMAC バスとのやりとり (for LUPO) WE_STRB が 1 から 0 に遷移したタイミングで WD からデータを取り込む
実際に値を読み出す場合 (LUPO) when で VME Address (CAMAC AF) を場合分け RD_STRB= 1 の間だけ RD に値を保持しておけばよい RD <= val; それ以外は RD は切り離しておく RD <= (others => z ); elsif (WR_STRB = 1 ) then
実際に値を書き込む場合 (LUPO) 1. WR_STRB= 1 の時にフラグを立てておく set <= 1 ; 2. WR_STRB event and WR_STRB= 0 の時にフラグが立っていれば値を代入する val <= WR; 3. WR_STRB= 0 になった時でも set の値は保持しておく set <= set; set が DFF の CE (clock enable) に接続される WR set WR_STRB elsif (WR_STRB = 1 ) then val
スケーラ ( カウンタ ) を作る eventを使って同期回路を作ればよい cnt <= cnt + 1 データを読み出したい場合はRD_STRB 時に値をラッチしてあげないと時々不正な値を返す 読み出し中にcntの値が変わるとアウト 各ビット間で必ずskew(~ 20ps) がある
スケーラ ( カウンタ ) 値をラッチする 読み出し用の vector を作ってあげる iq <= cnt; ではない こうすると cnt - 1 を読み出すことになる
使うライブラリを書いておく library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; これら ARITH 等が無いと cnt <= cnt + 1 等ができない ちなみに FDCE 等組み込みライブラリを使ったものをシミュレーションする場合は下記のようにコメントアウトしておく
シミュレーションする テストベンチをつくる
初期値を設定 Implementation Simulation 切り替え
こんな感じで書く clock 部分は自動的に生成してくれる wait for 100ns; で 100ns 時間を進める ダブルクリックでシミュレーション開始
ISim の画面 全体を表示 1 ステップ進める
LUPO/GTO にダウンロードする Generate Programming File bit ファイルができる Configure Target Device impact を起動 bit ファイルから Flash memory 用のファイルを作る FPGA に書き込む まずは PROM = Flash Memory 用ファイル
PROM 用ファイル設定 GTO の場合は xcf02s xcf04s を選んで Add Xilinx Flash/PROM を選んで押す
PROM ファイルを作る ウィザード形式で 1. デバイスを追加するか聞かれるので Yes 2.bit ファイルを選ぶ 3. さらに用意するか聞かれるので No ここをダブルクリックでファイルができる MCS という拡張子
Download firmware For FPGA, 電源切ると中身が消える (bit file) For Flash ROM, 不揮発性 (mcs file) Load FPGA をつけておくと Flash ROM を書いた時に FPGA にもロードしてくれる
やらかした例 conv_std_logic_vector 5000000 という数字を 24bit のベクターに変換したい conv_std_logic_vector(5000000, 24) 正しい conv_std_logic_vector(24, 5000000) 24 という数字を 5000000bit の vector に変換しようとする Synthesize がいっこうに終わらなくなる ( いつかは終わる )
downto ( 降順 ) と to( 昇順 ) signal a : std_logic_vector(3 downto 0) := 3210 vector を使う時は downto が一般的 bit で初期値を書く時は一番右が 0bit 目なのが馴染み type ARINT is array(3 downto 0) of integer; constant b : ARINT := (0,1,2,3); b(0)=3, b(1)=2, b(2)=1,b(3)=0 になるので注意 type ARINT is array(0 to 3) of integer; constant b : ARINT := (0,1,2,3); b(0)=0, b(1)=1, b(2)=2,b(3)=3 習慣の問題ですが array の時は to の方が馴染みやすい
black box と言われる場合 attribute box_type : string; attribute box_type of FDCE : component is black_box ; と書いておけば Warning が出なくなる または Xilinx 標準のライブラリを使う場合は COMPONENT の宣言をせずに 下記をコメントアウトするだけでもよい
LVDS を使う IBUFDS 入力 OBUFDS 出力 入力の場合は UCF ファイルの DIFF_TERM を TRUE にしておく これでターミネータが入る
GCLK と BUFG GCLKにアサインされているものはClock( 配線時にSkew, Delayが少ない ) として使える IP0とLVDSClockp/n それ以外でClock( 多数の回路のClockとなるもの ) として使いたい場合はBUFGにつなげる Place & Route 時に必要に応じて自動でつなげてくれる UCFで以下の記述が必要 回路規模が大きくなってきたら Place & Route Report は要チェック BUFGMUX ではなく Local になっていて Skew が大きい場合は PlanAhead を使って配線調整