Vengineerの妄想

人生を妄想しています。

Xilinx QEMU + SystemC (PCIe EP) + Verilog HDL(Verilator) の内容を探っていく(その1)

@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 環境について探ってみました。XilinxQEMU 側では、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 host is typically an x86 host emulated/virtualized on an x86 host
  • 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 に差し込むボード開発用の部品です。XilinxFPGAの中には PCIe IP が Hard IP として入っているものをあります。この PCIe IP の部分と Xilinx QEMUを接続する機能を探っていくことになるわけです。

QEMU での起動

x86-64QEMUを使って下記の引数で起動します。-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 が見えることを確認します。

おわりに

Xilinx QEMU はARMコアだけでなく、x86-64 でも SystemC側と通信ができるんですよ。。。てか、よく考えると、当たり前なんですが。。。。
次回から 上記の refdesign-sim.cc の内容を見ていきますよ。