@Vengineerの戯言 : Twitter
SystemVerilogの世界へようこそ、すべては、SystemC v0.9公開から始まった
はじめに
先月の後半にシリーズとしてお届けしたXilinxのQEMU + SystemC + Verilog HDL (Verilator) のデモの内容を探っていく。
XilinxのQEMU + SystemC + Verilog HDL (Verilator) のデモの内容を探っていく(その1)
XilinxのQEMU + SystemC + Verilog HDL (Verilator) のデモの内容を探っていく(その2)
XilinxのQEMU + SystemC + Verilog HDL (Verilator) のデモの内容を探っていく(その3)
XilinxのQEMU + SystemC + Verilog HDL (Verilator) のデモの内容を探っていく(その4)
XilinxのQEMU + SystemC + Verilog HDL (Verilator) のデモの内容を探っていく(その5)
では、ARM CPUコア入りの Zynq, ZynqMP, Versal をベースとして、Xilinx QEMU + SystemC 環境について探ってみました。Xilinx の QEMU 側では、PS(processing system)部の Zynqでは ARM Cortex-A9x2、ZynqMPでは ARM Cortex-A53x2、Versalでは ARM Cortex-A72x2 の CPUコアを動かし、それ以外、つまり、PL (Programming Logic)部を SystemC + Verilog HDL (Verilator) で実装していたわけです。
今回から探っていくのは、Xilinx QEMU で動く部分は PS部でなくてもOKなんですよ。SystemCで動く部分には、PCI Express の Endpoint Device なので、CPUは何でもOKなんですよ。
PCIe EP HW Bridges が今回から数回に分けて探っていくモデルです。今回は概要だけで、次回以降内部を探っていきます。
PCIe EP HW Bridges
PCIe EP HW Bridges は、前回までのデモの中にはなくて、LibSystemCTLM-SoC の中のライブラリのひとつという扱いですね。
ドキュメントは、ここ です。
ドキュメントから抜き出したのが以下のもの(引用します)
- The host is modelled by QEMU/KVM
- The PCIe Root Complex and parts of the fabric reside in QEMU Parts of the PCIe fabric can be modelled in System/RTL
- The PCIe EndPoint will be modelled in SystemC combined with RTL simulations or HW in the loop
- The PCIe EndPoint User-Logic is RTL and can be:
- RTL co-simulated
- Synthesized onto an FPGA and co-simulated (Hardware in the loop)
- The simulated PCIe EP can be hot-plugged and unplugged
- The simulated PCIe EP can DMA into the host
- The simulated PCIe EP can raise interrups to the host (Legacy, MSI and MSI-X)
- Multiple PCIe EP's can be simulated simultaneously
PCIe EP なので、基本的には、x86 の PCIe slot に差し込むボード開発用の部品です。XilinxのFPGAの中には PCIe IP が Hard IP として入っているものをあります。この PCIe IP の部分と Xilinx QEMUを接続する機能を探っていくことになるわけです。
QEMU での起動
x86-64のQEMUを使って下記の引数で起動します。-serial mon:stdio を指定しているので起動したコンソールが、Ctrl-A C を入力することで、そのまま QEMU のコンソールになります。
```
qemu-system-x86_64 -M q35,accel=kvm,kernel-irqchip=split \
-device intel-iommu,intremap=on,device-iotlb=on \
-cpu host -smp 8 -m 8G \
-netdev user,hostfwd=tcp:127.0.0.1:2225-10.0.2.15:22,id=n0 \
-device virtio-net,netdev=n0 \
-drive file=hd0.qcow2,format=qcow2 \
-machine-path machine-x86/ \
-serial mon:stdio \
-device ioh3420,id=rootport,slot=0 \
-device ioh3420,id=rootport1,slot=1
```
コンソールにて、下記のコマンドを入力して、SystemC側と接続する remote-port-pci-adaptor を追加します。
```
$ device_add remote-port-pci-adaptor,bus=rootport1,id=rp0
```
この時点で、SystemC側を起動していないと、以下のようなメッセージが表示され、待ちます。
```
Failed to connect socket machine-x86//qemu-rport-_machine_peripheral_rp0_rp: Connection refused
info: QEMU waiting for connection on: disconnected:unix:machine-x86//qemu-rport-_machine_peripheral_rp0_rp,server
```
SystemC側を起動
別のコンソール(ウィンドウを立ち上げ)、次のコマンドを実行します。
```
$ ./refdesign-sim unix:./machine-x86/qemu-rport-_machine_peripheral_rp0_rp 1000
```
refdesign-sim コマンドは、この コードをビルドしたものです。このディレクトリ で Build すればいいと思います。
詳しくは、次回以降で説明します。
再度、QEMUでコマンド打つ
SystemC側が起動したら、QEMUのコンソールで下記のコマンドを入力して、SystemCと接続します。
```
$ device_add remote-port-pci-device,bus=rootport,rp-adaptor0=rp,rp-chan0=0,vendor-id=0x10ee,device-id=0xd004,class-id=0x0700,revision=0x12,nr-io-bars=0,nr-mm-bars=1,bar-size0=0x100000,id=pcidev1
```
SystemCと接続できたら、
```
$ lspci -vv
```
にて、PCIe EP が見えることを確認します。