Today, I have a good article from Henry Von Bank of Posedge Software related to Zynq. Previously, I posted two articles involving Henry including an interview and a HOWTO about verification and virtual platforms.
This time Henry covers an often asked topic related to the virtual platform for the Xilinx Zynq-7000 EPP by explaining how to reuse C models for other Xilinx IP in a Zynq simulation.
Let me know if you are intested in obtaining the design files for the example.
Take it away, Henry.
Adding C Models to the Virtual Platform of the Zynq-7000
The Xilinx Zynq-7000 EPP provides an ARM dual-core processor along with programmable logic that can be used to implement custom peripherals. The Cadence Virtual System Platform (VSP) was used to build the Zynq virtual platform, and provides tools for quickly creating models of these custom peripherals and adding them to the simulation. All models use the SystemC TLM-2.0 standard, and are implemented as loosely-timed (LT) behavioral models.
Some existing Xilinx IP blocks contain a behavioral model written in C. These C models can easily be encapsulated into TLM-2.0 compatible models and integrated into the Zynq virtual platform. This same concept may apply to behavioral models from other vendors and other existing C models.
The Xilinx C models are pure behavioral models, and do not specify any register or processor interface. The IP blocks they describe would typically be combined with other logic to implement a complete peripheral. In this example, we will model a simple peripheral based on the FFT block. A process is described which involves defining registers for the peripheral, generating the interface code, implementing access functions, building the model, and integrating it into the platform.
Registers should first be defined in a Register Description File (RDF) using a simple register description language (RDL). The IP-XACT format can also be used, as both are supported by the model creation tool. It is also possible to generate an IP-XACT descrption from the RDF for use in other tools which use this format. This RDF file can then be used, along with the tlmgen tool available with VSP to generate a template for the model, including most of the needed TLM-2.0 interface code.
While the Xilinx FFT behavioral model supports a number of different algorithms and sizes, for this example it is simplified to an N=16 FFT using fixed-point values. A status register is first defined with fields for setting the FFT direction, triggering an FFT computation, and viewing the status after a computation is performed. This interface is defined by the user, and is not specified in the behavioral model.
Below is the STATUS register definition.
Two arrays of registers are also defined for real and imaginary data. These arrays of 16 registers each, are used to pass data to the FFT algorithm, and to read back the resulting data.
A register bank is then defined giving the overall space in the memory map allocated for this peripheral, and register offsets within this bank.
This completes the interface register definition. The next step is to generate the SystemC model.
Generate Interface Template
With the Zynq platform, a directory for this peripheral model, xfft_periph, should first be created under hw_unit, and the above RDF (xfft_periph.rdf) should be copied into it.
A template for the model can then be generated using the tlmgen command:
In addition to generating the needed source and header files (in the src/ and inc/ directories), a script is created to build the resulting model, along with a testbench to test the basic read/write access of the model (in the tb/ directory).
Update Header File
The generated TLM-2.0 header file for the model (inc/xfft_periph_tlm2.h) needs to be edited to include the C model header, and define some needed class members for passing data to and from the C model:
The C model header file xfft_v8_0_bitacc_cmodel.h (downloaded with the FFT C model) should also be copied into the inc/ directory.
Implement Model Constructor
An empty constructor function for the model is generated in src/xfft_periph_tlm2.c. This should be modified to initialize the state of the C model, and set the values of other variables.
Implement Access Functions
If the preamble or postamble values were set in the RDF, bus access functions for each specified register will be created in the src/xfft_periph_tlm2.c file. These functions need to be implemented to give the correct behavior and to interface with the C model. First, read and write functions should be defined for the data registers that will access the correct input or output array location:
A post-write function for the STATUS register is also implemented that sets the correct values in the xfft input struct, and calls the xfft simulate function if the field is set. It also sets the resulting value of the STATUS register based on the FFT results.
Build Model and Run Testbench
A script (xfft_periph_build.sh) was created in the build directory for building the model. This needs to be modified to link with the C model's shared library by setting the OTHER_ARGS= line to:
OTHER_ARGS= "-L. -lIp_xfft_v8_0_bitacc_cmodel"
The referenced shared object for the C model, libIp_xfft_v8_0_bitacc_cmodel.so should be copied into the build/ directory, and this script can then be run to build the model.
The generated testbench tb/xfft_periph_hwtest/systemc example can also be built and run using the available script tlm2_test_build.sh. This will test basic reads and writes to the model's registers. The testbench can easily be expanded to perform other functional testing of the model, such as computing and verifying FFT results.
Add Model to the Platform
Modify the file hw_unit/bp_demo/inc/bp_demo.h file as follows to map the xfft_periph to the axi_gp0 interface. For an initial test, the graphics IP that was located at address 0x40000000 is removed by commenting it out and the new fft model is inserted in the same place in the memory map.
Add the following line to the hw_unit/bp_demo/makefile:
DEP_UNITS += xfft_periph
It should now be possible to run the Zynq platform as usual and program the FFT from a software program running on one of the ARM processors.
Integrating existing C behavioral models, such as those available from Xilinx, into the Zynq platform can be done easily, in a very short amount of time. Using available tools, such as tlmgen, greatly simplifies this process, and can generate the majority of the needed interface code. While the example peripheral is very trivial, the same process can be followed for more complex devices.