This wiki article describes the process required to setup an existing SystemC implementation and connect it to a PetaLinux QEMU system for co-simulation.

Configuring your SystemC model to communicate with QEMU

In order to configure your SystemC model to communicate with Xilinx 's QEMU model you will need to include our SystemC SoC library. This library is available here: https://github.com/Xilinx/libsystemctlm-soc
The README in the library includes steps of how to integrate it into your SystemC code.
You can also see this repo for an example of how to do this: https://github.com/Xilinx/systemctlm-cosim-demo
NOTE: That cosimulating QEMU with SystemC will dramatically decrease QEMU's performance. You can change the sync quantum and icount settings to improve performance (at the cost of accuracy) if desired.

Steps to run TLM CoSim Zynq-7000 Demo

1. Create a Zynq PetaLinux project and enter the PetaLinux directory
2. Download the QEMU CoSim device tree overlay
$ wget https://raw.githubusercontent.com/Xilinx/qemu-devicetrees/master/zynq-pl-remoteport.dtsi -O subsystems/linux/configs/device-tree/zynq-pl-remoteport.dtsi
3. Now include the new file in the 'subsystems/linux/configs/device-tree/system-top.dts' file be including this line below the other includes:
/include/ "zynq-pl-remoteport.dtsi"
4. Rebuild PetaLinux
$ petalinux-build
5. Boot QEMU with an extra option to point to a shared simulation directory This is where QEMU stores the shared memory regions. You will need to ensure that this directory exists and can be accessed by both QEMU and the SystemC program
$ petalinux-boot --qemu --kernel --qemu-args "-machine-path ./qemu-tmp -icount 1 -sync-quantum 10000"

QEMU will now hang waiting for a connection. When connection to QEMU from a SystemC application make sure to specify the same directory that QEMU is using for the machine path.

You can follow the steps below to start the SystemC side of the emulation. Once up you can use the PetaLinux peek/poke commands to query the SystemC side. You can get details of the addresses in the Zynq-7000 TRM.
To revert back to the usual PetaLinux flow remove the '/include/ "zynq-pl-remoteport.dtsi"' line that was added earlier and rebuild.

Steps to run TLM CoSim ZynqMP Demo

The ZynqMP Process requires a little more work to prepare a device tree.
We are going to build the QEMU device tree (-hw-dtb option) outside of PetaLinux and then bring that into PetaLinux.
1. Clone the QEMU DTS repo
$ git clone https://github.com/Xilinx/qemu-devicetrees.git
2. Build the device trees
$ cd qemu-devicetrees; make
NOTE: If you have any problems see this page for more information: http://www.wiki.xilinx.com/QEMU+-+Zynq+UltraScalePlus
Back in PetaLinux follow the usual PetaLinux flow. When ready for testing use the below steps.
3. Run a similar petalinux-boot command as usual (an example is below) This command should include the hw-dtb and the machine-patch argument. The hw-dtb is a device tree used only by QEMU to describe the hardware to model. It is included in the device trees we built in step 2. The machine-path is where QEMU stores the shared memory regions. You will need to ensure that this directory exists and can be accessed by both QEMU and the SystemC program
$ petalinux-boot --qemu --kernel --qemu-args "-hw-dtb ${QEMU-DEVICETREES}/LATEST/MULTI_ARCH/zcu102-arm.cosim.dtb -machine-path ./qemu-tmp"
Where the ${QEMU-DEVICETREES} is the directory we just cloned the device trees to.
4. QEMU will now hang waiting for a connection. When connection to QEMU from a SystemC application make sure to secify the same directory that QEMU is using for the machine path.

You can follow the steps below to start the SystemC side of the emulation. Once up you can use the PetaLinux peek/poke commands to query the SystemC side. You can get details of the addresses in the ZynqMP TRM. Some example address that you can access are shown below (these re included in the SystemC demo mentioned earlier)
DEBUG_TIME 0xa0000000
DEBUG_WRITE 0xa0000004
DEBUG_STOP 0xa0000008
DEBUG_IRQ 0xa000000c
DEBUG_REAL_TIME 0xa0000010

APB_TIMER_CFG 0xa0020000
APB_TIMER_CNT 0xa0020004
APB_TIMER_DIV 0xa0020008
APB_TIMER_FREE_CNT 0xa002000c

Steps to run the SystemC side

The steps below are taken directory from the README included in the demo available at: https://github.com/Xilinx/systemctlm-cosim-demo
When running you will need to make sure the program can link to your SystemC/TLM libraries. You will also need to give arguments to the application. The first argument points to the QEMU machine-path to use. The second argument is the icount value to use. The arguments should line up with the QEMU command line arguments.
A ZynqMP example: In one terminal, in the demo directory
LD_LIBRARY_PATH=/usr/local/systemc-2.3.1/lib-linux64/ ./zynqmp_demo unix:./qemu-tmp/qemu-rport-_amba@0_cosim@0 10000
A Zynq-7000 example:
LD_LIBRARY_PATH=/usr/local/systemc-2.3.1/lib-linux64/ ./zynq_demo unix:./qemu-tmp/qemu-rport-_cosim@0 1000000
In another terminal you will need to start up the PS. In this case we are going to start up a PetaLinux QEMU session and use the Linux kernel to probe the SystemC side. You could also start up your own kernel with the required drivers or a baremetal application.