Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
SystemVerilog を使用したXilinx FPGA開発
Search
tethys_seesaa
September 23, 2017
Technology
0
2.4k
SystemVerilog を使用したXilinx FPGA開発
2017年9月24日(日)に開催した
RTLを語る会(14)~FPGAの現実~の発表スライド(公開版)
tethys_seesaa
September 23, 2017
Tweet
Share
More Decks by tethys_seesaa
See All by tethys_seesaa
RTLを語る会(17)あいさつ
tethys_seesaa
0
420
UVVMをさわってみた
tethys_seesaa
0
570
Vivado2019.2でUVMを使った話
tethys_seesaa
0
830
RTLを語る会(16)あいさつ
tethys_seesaa
0
500
あいさつ
tethys_seesaa
0
550
Other Decks in Technology
See All in Technology
3D生成AIのための画像生成
kosukeito
2
570
エンジニアリングで組織のアウトカムを最速で最大化する!
ham0215
1
260
Как мы автоматизировали интеграционное тестирование с Gonkey и не пожалели. Паша Егорычев, Кирилл Поляков
lamodatech
0
620
Web Intelligence and Visual Media Analytics
weblyzard
PRO
1
5.9k
Twelve-Factor-Appから学ぶECS設計プラクティス/ECS practice for Twelve-Factor-App
ozawa
3
150
C++26アップデート 2025-03
faithandbrave
0
1.1k
watsonx.data上のベクトル・データベース Milvusを見てみよう/20250418-milvus-dojo
mayumihirano
0
180
【Λ(らむだ)】最近のアプデ情報 / RPALT20250422
lambda
0
140
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
2
420
Compose におけるパスワード自動入力とパスワード保存
tonionagauzzi
0
160
Terraform Cloudで始めるおひとりさまOrganizationsのすゝめ
handy
2
210
Microsoft の SSE の現在地
skmkzyk
0
250
Featured
See All Featured
How to train your dragon (web standard)
notwaldorf
91
6k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
26k
How STYLIGHT went responsive
nonsquared
100
5.5k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.7k
The Straight Up "How To Draw Better" Workshop
denniskardys
233
140k
Fireside Chat
paigeccino
37
3.4k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
49k
GitHub's CSS Performance
jonrohan
1030
460k
What's in a price? How to price your products and services
michaelherold
245
12k
Java REST API Framework Comparison - PWX 2021
mraible
31
8.5k
Imperfection Machines: The Place of Print at Facebook
scottboms
267
13k
Transcript
SystemVerilog を使用した Xilinx FPGA開発 〜Zynq-7000〜 @tethys_seesaa
Table of Contents • Vivadoの設計言語としてのSystemVerilog対応 • 合成可能なSystemVerilog記述 • Zynq-7000をターゲットとしたHW/SW開発について
VivadoのSystemVerilog対応話
VivadoのSystemVerilog対応の利点(1/5) • typedef対応 • VHDLのsubtypeのようなもの。 • バグの入りにくいスッキリとしたコード記述ができる。
typedef logic[7:0] Byte_t; // 幅表記が統一できる Byte_t [7:0] ad, dat; logic
[7:0] be; always_ff @(posedge rst, posedge clk) if(rst) begin ad <= '0; // logic型0のaggregationも兼ねる be <= '0; end … … always_comb dat[6] = '1; // バイト6に0xFFを入れる
VivadoのSystemVerilog対応の利点(2/5) • typedefとpacked配列の合わせ技 • packed構造体 • VHDLのrecordのようなもの • コード行を比較的、減らせる
typedef logic[7:0] Byte_t; typedef struct packed unsigned { Byte_t [7:0]
ad; logic [7:0] be; logic frame, irdy; } Pci_t; ... Pci_t pd; ... always_ff @(posedge rst, posedge clk) if(rst) begin pd <= '0; // ほとんどのメンバ信号は0 pd.frame <= '1; // このメンバ信号だけ1を入れる end ...
VivadoのSystemVerilog対応の利点(3/5) • typedefとenumの合わせ技 • VHDLのtypeみたいなもの • 例えばステートマシンでいちいち`defineで文字列にエン コード値を割り振らなくても良い • シミュレータからの波形も文字列で表示される
• ただし、これを用いて設計する場合、Vivadoだと論理合成のデ フォルト(auto)はエンコード値がワンホットに割り当てられるこ とが多いので注意。
typedef enum logic [7:0] { RESET = '0, // Vivadoのデフォルトだと無意味かも
INIT, ... ERROR } St_t; St_t cur, nxt; always_ff @(posedge rst, posedge clk) if(rst) cur <= RESET; else cur <= nxt; ...
VivadoのSystemVerilog対応の利点(4/5) • package, import • packageにて、これまでのtypedef等を共通の定義としてまとめること ができる。 • まとめたpackageは、importで各moduleで使用できる •
VHDLのpackageのようなもの • Vivadoでは論理合成時にちょっとクセがある • 後述します • Vivadoだと、importのimportはどうも対応していないようだ
package common_pack; typedef logic[7:0] Byte_t; ... // SystemVerilogではfunctionの入力はinput文を省略可 function Byte_t
get_data(Byte_t data); return data; endfunction ... endpackage ... import common_pack::*; module module_a( ... endmodule
VivadoのSystemVerilog対応の利点(5/5) • interface • 信号をまとめることができ、Master/Slaveでそれぞれメソッドを記述 することが可能 • modportでMaster/Slaveの指定ができる。 • ただし、今回のプロジェクトには未採用
• Block Designを使用すると、採用する機会が無かった
interface bus_t (); logic sel; logic rw; addr_t addr; //typedefで型指定
data_t rdat; //typedefで型指定 data_t wdat; // Master methods function data_t get_rdata(); return rdat; endfunction task automatic mst_rst(); sel <= ‘0; rw <= ‘0; addr <= ‘0; wdat <= ‘0; endtask // Slave methods function logic get_sel(); return sel; endfunction function data_t get_wdata(); return wdat; endfunction // modportでMaster/Slave決め modport mst( import get_rdata, mst_rst, output sel, rw, addr, wdat, input rdat ); modport slv( import get_sel, get_wdata, input sel, rw, addr, wdat, output rdat ); endinterface
module top(); // interfaceのインスタンス // interfaceの配列はダメっぽい bus_t bus_0(); bus_t bus_1();
... // module_0にbus_0をslaveとして接続 module_0 mod_0( .bus_0(bus_0), .*); ... endmodule module module_0( ... bus_t.slv bus_0 ); data_t dat; // Slave methods呼び出し always_ff @(posedge RST, posedge CLK) if(RST) dat <= ‘0; else if(bus_0.get_sel()) dat <= bus_0.get_wdata(); ... endmodule
VivadoのSystemVerilog対応まとめ • VHDLなみの型を意識しつつ、シンプルに記述できる • バグが発生しにくいコードが書ける • typedefを駆使して、packageを使用する • ただし、あくまでVerilog HDL
• バス幅表記とか • interfaceにも対応している • ここは個人的に意外だった
ここからはVivadoを使用した 開発の話
このZynq-7000システムを支えるボード • Zynq-7000 All Programmable SoC ZC706 評価キット • 一家に一台は欲しいZC706ボード
本当に起こっていた事実
開発フロー • Block Design • SystemVerilo g/Verilog • その他IP HW開発、
Vivado(RH EL6.x) Petalinux SW開発、 OSビルド (Ubuntu 14.04) ILA等 FPGA動作 確認 (Windows 7)
ハードウェア開発
採用したIP(すべて無償) • Zynqシステム(Block Design) • AXI DMA(Scatter/Gatherではないノーマル) x 2 •
AXI Peripheralテンプレート • Vivadoのユーティリティ • AXI4 Lite Slave • AXI4 Stream Master/Slave • 10GbE PCS/PMA(10GbE用PHY) • ZC706ボード(Zynq-7000?)だと無償 • GbE PCS/PMA(GbE用PHY) • 無償
CDC対策(1)~あるある対応~ • 今回のプロジェクトでは、ほとんどのCDC部分の通信は、ある 時間で局所的にまとまって発生する。 • 常にやり取りするわけではない。 • Dual Port SRAM(Block
RAM)で対応 • 一定量たまったら、送信先クロックドメインに信号送る • 1bit 2段 F/Fで受けて、応答を返す(ハンドシェイク) • Dual Port SRAMは、Vivadoの合成ツールにてRAM推論させる ようにしました。 • Block Memory Generator等を使用しない
// VivadoにDual Port RAM(BlockRAM)推論させるVerilog記述 reg [31:0] mem [0:1023] // RAM定義
always @(posedge WCLK) if(WEN) mem[WADDR] <= WDAT; always @(posedge RCLK) RDAT <= mem[RADDR];
CDC対策(2)~ちょっと面倒な対応~ • Block RAMほど、ワード数の多いモジュールは必要ない • データが受信されたら、すぐにデータを取り出したい • もちろん、空っぽの時はデータを取り出さないように制御する • SystemVerilogにて、FIFOのF/F記述
• read/write ポインタはグレイコードでクロックドメイン渡し • グレイコードの性質を利用して、満タンおよび空っぽ状態をシンプル に表現 • 150行程度のコード • SystemVerilogの .* 接続を活用
FIFO構造 • 「FPGAの部屋」より拝借 • 同期FIFOと非同期FIFO • http://marsee101.blog19.fc2.com/blog -entry-1085.html ココだけ、次のスライドでコード説明
// 空っぽ always_comb begin rbinnext = rbin + (rinc &
~rempty); rgraynext = (rbinnext>>1) ^ rbinnext; rempty_val = (rgraynext == rq2_wptr); end always_ff @(posedge RST, posedge RCLK) if (RST) rempty <= ’1; else rempty <= rempty_val; //満タン always_comb begin wbinnext = wbin + (winc & ~wfull); wgraynext = (wbinnext>>1) ^ wbinnext; wfull_val = (wgraynext=={~wq2_rptr[ADDRSIZE:ADDRSIZ E-1], wq2_rptr[ADDRSIZE-2:0]}); end always_ff @(posedge RST, posedge WCLK) if (RST) wfull <= ’0; else wfull <= wfull_val;
Block Designの作成(比較的簡単) • 時間をかければ、なんとなく慣れる • 初心者に優しい
されどBlock Design • ブロックが多くなると… • 配線がミスしていないか、チェックするのが大変難しい • Validate Designが問題なくとも、バグが無いことを保証するわけではない •
目視チェックしかない! • RTLシミュレーション…あきらめました • IPごとにVerilogだったりVHDLだったり • Vivadoから出力されるシミュレータスクリプトが前時代的 • Incisiveだとirunコマンドで出して欲しい • RTLシミュレーションは、Zynq VIPで今後何とかなるかもしれない • EDAベンダのシミュレータじゃないと面倒(工数のかかる)ところがいろいろ ありそう
けっこう面倒なBlock Design • Block Designに入れるブロックが多くなると問題が発 生しやすくなった • メンテナンスで開発進行に影響が出るケースがあった • 開発には別のプロジェクトを作成して実行
• 専用プロジェクトで生成したBlock Design(bdファイル)をイ ンポートして、論理合成・配置配線を行う • IPも専用のディレクトリで管理 • ディレクトリ構成が深く、かつ複雑怪奇
IPのアサインおよび設定~AXI DMA~ • シンプルな設定 • アーキ検討でここまで絞り込んだ • Block Designで自動配線 •
何故か割り込みをZynqにつないでくれない • 理由はなんとなく想像がつく • 後工程のDevice Tree作成でようやく気づく • Validate Designで指摘してくれせんかね •
IPのアサインおよび設定~MyIP~ • AXI DMAからAXI Streamバス経由 で来るデータとUser Designとの受 け渡し • VivadoのAXI
Peripheral生成ツール にて作成 • 中のVerilogを編集してUser Design I/Fを作る • AXI Stream側は手動結線 • さらにバスを開き、tstrbとtlastを手動結 線する必要がある • tkeep信号の意味?
IPのアサインおよび設定 ~MyIP レジスタ~ • PLのレジスタ設定をAXI Lite I/Fを持つモジュールに集約 • Block Designにおく
• VivadoのAXI Peripheral生成ツールにて作成 • 中のVerilogを編集する
IPのアサインおよび設定 ~10GbE PCS/PMA~ • Licenseは「Purchase(有償)」だが、ZC706ボードでは無償 • …のハズ?
IPのアサインおよび設定 ~10GbE PCS/PMA~ • Include Shared Logic in example design
• Shared Logicをコアの外に出す (ややこしい) • example designをベースに改造す る • ZC706では無償だが、デフォル ト有償 • ライセンスチェックを行うため、 画面遷移で1分ほど待たされる
IPのアサインおよび設定 ~GbE PCS/PMA~ • Licenseは「Included(無償)」
IPのアサインおよび設定 ~GbE PCS/PMA~ • Include Shared Logic in Core •
Shared Logicも含める • ZC706ボードのSFPポート1個し か使用しないため
GbE PCS/PMAにおけるわたしの凡ミス • Vivado 2016.2に含まれている同IP • v15.2 • Vivado 2016.4に含まれている同IP
• v16.0 • プロジェクト開始時、2016.4のドキュメントを読んでいた • MDIO関係の、1bitのあるレジスタの設定値の定義が反転していた • 2016.2と2016.4で異なる! • 実機デバッグにて発覚するまで1日浪費してしまった • ドキュメントは使うIPのバージョンに気をつけましょう
VivadoのフローとSystemVerilog(1/2) • IP設定が固まったら、基本はtclモード(CUI)でVivadoを実行 • 合成 • 配置配線 • bitファイル生成 •
SDK Export • tclモードには2つのモードがある • プロジェクトモード • 非プロジェクトモード
VivadoのフローとSystemVerilog(2/2) • Cadence Incisive等のシミュレータは、typedef等、共通ファイ ルは共通のコンパイルスコープで実施される。 • よって、package, import等は明確に記述しなくても良い • Vivado非プロジェクトモードも同様
• Block Designはプロジェクトモードで作られる • packageで指定しないと、typedefで指定した型がVivadoで見つけてく れない • 合成以前に、エラボレーションでエラーとなる • やむなく、package, importを明示して使用した
Vivado実行スクリプト #!/bin/sh # 以下のようにシェルスクリプトを実行 # ./run.sh clean; ./run.sh work fpga_top
if [ $# -lt 1 ]; then echo "usage: ./run.sh workdir top_name " exit 1 fi if [ $1 ="clean"]; then TRASH=$(ls -a -I . -I .. -I run.sh -I top.xdc -I pin.xdc) rm -rf ${TRASH} exit 0 fi # set environment source ../env/current.env source /opt/Xilinx/Vivado/2016.2/settings64.sh # Block Design用プロジェクトからのエクスポート vivado -mode tcl -source ../tcl/gen_bd.tcl # ワークディレクトリとトップモジュール設定 export WORKDIR=$1 export TOPMODULE=$2 # Vivado実行 vivado -mode tcl -source ../tcl/syn.tcl
ソフトウェア開発
OS/ソフトウェア • OSはPetalinux 2016.2 • ブートおよびソフトウェア実行はUARTコンソールより実行 • C++/Cアプリ用テンプレートを生成し、作成
メモリ/レジスタダンプ用アプリ #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <sys/mman.h> #define
MAP_LENG 0x00100000 void main (int argc, char **argv){ int fd , i; unsigned int *addr; unsigned int offset, count; fd = open( "/dev/mem", O_RDWR ); if ( fd == -1 ){ printf ( "Can't open /dev/mem. ¥n" ); return ; } offset = strtol ( argv[1], NULL, 16 ); count = strtol ( argv[2], NULL, 10 ); addr = mmap ( NULL, MAP_LENG, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset & 0xFFFF0000) ; if ( addr == MAP_FAILED ) { printf( "Error: mmap()¥n" ); } printf (" usage: memdump ADRS(hex) LEN(dec) ¥n" ); for( i=0; i<count; i++){ printf ( "%08X: %08X¥n", ( (offset & 0xFFFFFFFC) + (i * 4) ), ( addr[((offset & 0x0000FFFC) /4 ) + i] ) ); } printf ( "¥n" ); return ; }
メモリ/レジスタライトアプリ #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <sys/mman.h> #define
MAP_LENG 0x00100000 void main (int argc, char **argv){ int fd , i; unsigned int *addr; unsigned int offset, data; fd = open( "/dev/mem", O_RDWR ); if ( fd == -1 ){ printf ( "Can't open /dev/mem. ¥n" ); return ; } offset = strtol ( argv[1], NULL, 16 ); data = strtol ( argv[2], NULL, 16 ); addr = mmap ( NULL, MAP_LENG, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset & 0xFFFF0000) ; if ( addr == MAP_FAILED ) { printf( "Error: mmap()¥n" ); } printf (" usage: memwrite ADRS(hex) LEN(dec) ¥n" ); addr[(offset & 0x0000FFFC) / 4] = data; printf ( "%08X: %08X¥n", ( offset & 0xFFFFFFFC ), ( addr[(offset & 0x0000FFFC) /4] ) ); printf ( "¥n" ); return ; }
Petalinuxブート用SDカードイメージ作成 #!/bin/sh PETAPROJ='petaprj' VIVPROJ='fpgaprj' BD_NAME='design_1_wrapper' VIVPROJ_DIR='/home/tethys/work' VIVPROJ_SDK_DIR=${VIVPROJ_DIR}/${VIVPROJ}.sdk source /opt/Xilinx/Vivado/2016.2/settings64.sh source
/opt/Xilinx/petalinux-v2016.2-final/settings.sh #Create Project petalinux-create --force --type project ¥ --template zynq ¥ --name ${PETAPROJ} #Import HDF cd ${PETAPROJ} petalinux-config --get-hw-description=${VIVPROJ_SDK_DIR} #Create new app #petalinux-create -t apps --template c --name myapp #Choice Apps petalinux-config -c rootfs #Build Petalinux LANG=C petalinux-build #Make bood.bin petalinux-package ¥ --boot ¥ --fsbl ./images/linux/zynq_fsbl.elf ¥ --fpga ./images/linux/${BD_NAME}.bit ¥ --u-boot
スクリプト一発で完了させるつもりが… • Device Tree生成で、dtsiファイルに同じモジュールのエントリ が2つ生成される • たぶん、Vivado 2016.2のバグ • 仕方ないのでビルド前の段階で毎回手修正
まとめ • Zynq-7000をスクラッチで開発できた
Reference 1. 小林優, (2016). FPGAプログラミング大全. ISBN 4798047538. 2. FPGAマガジン, (2013).
高速Ethernet x FPGA. ISBN 478984613X 3. FPGAマガジン, (2016). ARMコアFPGA x Linux初体験. ISBN 4789846229 4. Clifford E. Cummings, (2001). Simulation and Synthesis Techniques for Asynchronous FIFO Design. Sunburst Design, Inc. http://www.sunburst- design.com/papers/CummingsSNUG2002SJ_FIFO1.pdf 5. zakii, (2011). RAMのRTL記述. http://zakii.la.coocan.jp/hdl/44_ram_rtl.htm 6. ikwzm, (2016). VivadoをGUIを使わずに実行するためのTclスクリ プト達. http://qiita.com/ikwzm/items/a0120079d2f7f86a5904