In today’s fast-paced world, technology is evolving at an unprecedented rate, and FPGA design is no exception. High-level tools are emerging rapidly, accelerating development like never before. Traditionally, FPGA design involved writing code in hardware description languages (HDLs) and using synthesis tools to map the design. While these conventional methods remain essential, tools like Vitis Model Composer and HDL Coder have significantly streamlined the development process, especially for SDRs and FPGA-based systems. As a senior official at BAE Systems stated: “It took 645 hours for an engineer with years of VHDL coding experience to hand code a fully functional SDR waveform using our traditional design flow. A second engineer with limited experience completed the same project using Simulink and Xilinx System Generator in fewer than 46 hours.”
“It took 645 hours for an engineer with years of VHDL coding experience to hand code a fully functional SDR waveform using our traditional design flow. A second engineer with limited experience completed the same project using Simulink and Xilinx System Generator in fewer than 46 hours.”
Dr. David Haessig, BAE Systems
Today's tutorial provides a step-by-step guide to creating a custom IP, from algorithm development to preparing the model for IP generation, including resource and timing analysis, and finally adding it to the Vivado IP catalog.
IntroductionIn all signal processing applications, detecting a signal within noise is crucial, as noise is an inherent part of virtually all digital systems. Accurate detection is key to ensuring reliable communication and data processing. In today's tutorial, we will develop an algorithm designed to determine whether a pulse is present in a signal with an unknown frequency. This type of detection is especially important when dealing with noisy signals, where distinguishing the pulse from background noise can be challenging. We will walk through the steps required to create a robust algorithm that can effectively identify the presence of a pulse, regardless of the signal’s frequency, in a noisy environment.
Environment SetupVitis Model Composer is a part of the Vitis suite, which provides a high-level design environment for FPGA-based acceleration. To follow along with this tutorial, ensure that the Vitis suite is installed on your system and properly sourced in your terminal. You can do this by running the following command:
source /installationDirectory/Vitis/version/settings64.sh
Once Vitis is sourced, you can launch Vitis Model Composer by executing the following command in your terminal:
model_composer
This will open MATLAB with the AMD toolbox enabled. From within MATLAB, open Simulink, and you are now ready to begin designing and simulating your models using Vitis Model Composer.
Signal GenerationIn Simulink, we attempted to simulate a chirped pulse signal for analysis. To achieve this, we used the Chirp block to generate a frequency-modulated signal and then multiplied it with a Pulse Generator block to shape it into distinct pulses. To make the simulation more realistic and closer to real-world scenarios, we introduced white Gaussian noise to the signal. This addition simulates the inevitable noise present in practical systems, allowing us to analyze how well the signal can be detected and processed under noisy conditions.
After the signal generation in order to implement the pulse detection we first squared the signal in order to remove negative values than did FIR decimation followed by a low pass filter. The simulink block design can be seen in figure 5.
The signal after the envelope extraction can be seen in figure 8.
As seen in Figure 8, after applying the envelope detection algorithm, the signal amplitude has significantly increased, effectively distinguishing it from the noise. Within the noise region, no unwanted transitions are present, making it easier to differentiate the pulse from the background. This enhancement improves our ability to accurately determine whether a pulse is present in the signal, leading to more reliable detection.
Based on this post-processing of the signal, it became easier to select a constant threshold value to determine the presence of a pulse. The block outputs either a '1' or '0, ' indicating whether a pulse is detected. However, instead of using a fixed threshold, the detection can be further improved by making the threshold adaptive using methods such as standard deviation-based analysis. This approach allows the system to dynamically adjust the threshold based on noise variations, enhancing detection accuracy in different signal conditions. The final simulink model can be seen in figure 9.
The detection result can be seen below
After successfully verifying the algorithm against multiple test cases, the next step was to replicate similar results using Vitis Model Composer. To generate an IP and perform other related functions, the first requirement is to insert the Vitis Model Composer Hub block from the Simulink Library. This can be found under:
Simulink Library Browser → AMD Toolbox → Utilities → Code Generation → Vitis Model Composer Hub
The Vitis Model Composer Hub serves as the central flow advisor, guiding the entire process from design to code generation, ensuring seamless integration with the Vitis toolchain.
For this tutorial, I am using the Zynq UltraScale+ MPSoC ZCU102 board. However, you can choose any available board as long as it is from AMD (formerly Xilinx).
To select a board, open the Vitis Model Composer Hub and follow the steps shown in the figure below. The board selection process ensures that the generated IP and design configurations are compatible with your specific hardware platform.
There are some specifc guidelines given by AMD for IP core generation. To follow this tutorial following poinst to be kept in mind.
Gateway in/out Blocks are trested as inputs/outputs
Anything between these ports will automaticlally be identidfied by vitis model composer hub and can be converted into IPs.
For identification to be possible by the vitis model composer hub the desired blocks performing the function to be converted into subsystems AMD provides specific guidelines for IP core generation—because, of course, designing hardware isn’t already complicated enough! To successfully follow this tutorial, keep the following points in mind:
- Gateway In/Out blocks are treated as inputs and outputs. Think of them as the VIP entrance and exit for your data.
- Anything between these ports will be automatically detected by the Vitis Model Composer Hub and can be converted into IPs—like magic, but with more debugging.
- For proper identification, any blocks performing a function must be converted into subsystems. If you don’t do this, Vitis might just pretend it never saw them😆.
Now it's time to insert two Gateway In and Gateway Out blocks inside your block design—because, obviously, Simulink won’t just read your mind (yet).
- Attach the output of the signal generation subsystem to the input of Gateway In. This ensures your beautifully crafted signal has a proper entry point.
- If you haven't already made a subsystem out of the signal generation process now is the time to do it—because manual labor is still a thing in the world of automation 😆.
- Similarly, create a subsystem for the envelope detection algorithm, ensuring it consists of only generic Simulink blocks. No shortcuts here!
- Modify the Gateway In block parameters according to the settings shown in the figure below—because default settings are never quite what we need, are they? Meanwhile, leave the Gateway Out block untouched, because for once, something in this process doesn’t require extra tweaking.
At the output of the Gateway In block, connect a Multiplication block to compute the square of the sample—because apparently, Vitis Model Composer doesn’t believe in built-in square functions.
Since there's no direct square operation, here’s the workaround:
- Feed the same input to both ports of the first Multiplication block. Voilà! You’ve squared the value, the old-fashioned way.
- Now, for extra mathematical gymnastics, take another Multiplication block and add its output to the result of the previous multiplier—because nothing screams 'engineering' like using multiple blocks for something that should be one function.
- Finally, attach the second input to a Constant block with a value of 4, effectively raising the amplitude level.
The block parameters of these block can be seen in the next figures
At this point your figure model should look something like shown in figure 16.
For decimation, while a prebuilt Decimation block is available in Simulink's Generic Library, it is not included in the AMD Toolbox. However, we can achieve the same functionality using a low-pass filter followed by a downsampler, both available in the AMD Toolbox.
To implement this:
- At the output of the second multiplier, add a Digital FIR Filter to smooth the signal before downsampling.
- Follow this with a Downsample block from the AMD Toolbox to reduce the sampling rate.
- For designing the filter, we will use the FDA Tool, which provides a user-friendly interface for specifying filter parameters.
Note: Place the FDA Tool at the root level of your design (at a higher level, not inside any subsystem). It can be found under:
📍 Simulink Library Browser → AMD Toolbox → Utilities → Tools → FDATool
FDAToolPulse Detection Output Model Composer FlowDouble-click on the FDA Tool block to open its configuration window. Modify the parameters as shown in the figure below to ensure an exact replication of the results. These settings will define the filter characteristics required for proper signal processing.
To use the designed filter in your model, open the block parameters of the FIR Filter that we previously inserted. Under the Coefficient Vector field, enter the following line:
xlfda_numerator([bdroot, '/FDATool'])
This links the FIR filter to the coefficients generated by the FDA Tool, ensuring that the designed filter is applied correctly. The exact configuration of this block can be seen in Figure 18.
After applying the changes, verify that the filter is functioning as expected before proceeding to the next steps. Similarly, open the block parameters of the Downsample block and modify its settings according to Figure 19 to ensure proper functionality. These adjustments will configure the downsampling process to match the design requirements.
After the decimation step, add another Low-Pass Filter to further refine the signal. In the Coefficient Vector field of the filter’s block parameters, enter the following line:
firpm(20, [0 0.03 0.1 1], [1 1 0 0])
This defines the filter using the Parks-McClellan algorithm, specifying the desired frequency response. Configure the remaining parameters according to Figure 20 to ensure proper implementation.
The final Simulink block diagram is shown in Figure 21. At the output of the filter, a Relational Operator block is used to compare the filtered signal to a constant threshold of 2.5. The block outputs either 1 or 0, indicating whether the signal exceeds the threshold, effectively making a decision on pulse detection.
As seen in Figure 21, multiple subsystems have been created to organize the design. You can either structure your model similarly or simplify it by encapsulating everything from Gateway In to Gateway Out into a single subsystem.
With the block design now complete, we are ready to proceed with code generation. Ensure all configurations are set correctly before moving to the next step.
Final Result (Model Composer Flow)At this point simulate the design if both outputs normal simulink flow and model composer flow are similar means you ave successfully replicated the algorithm. My results excatly match as shown below.
Code/IP Generation
Open the Vitis Model Composer Hub once again. If all steps were followed correctly, your system should now be listed under the Code Generation tab with a green check mark, indicating that it is ready for further processing.
Additionally, under the same tab, you will see four different sections:
- Settings: Contains general settings related to clock configuration and target language selection.
- Analyze: Used for timing and resource analysis, ensuring the design meets hardware constraints.
- Validate on Hardware: This option allows you to test the design on actual hardware, verifying its real-world performance. (We will not cover this)
- Export: Enables the export of the generated IP, making it available for integration into Vivado or other tools.
Configure all these settings according to the steps shown figure 22.
Analysis
The Analysis section is a highly useful utility that allows you to perform both timing and resource analysis after synthesis and implementation. This helps in making informed design decisions, optimizing resource utilization, and fine-tuning your algorithm for better performance.
To perform the analysis, follow the steps shown in the following figure. This will provide insights into timing constraints, resource consumption, and overall system efficiency, allowing you to refine your design if needed before final deployment
After clicking Analyze, Vitis Model Composer will take some time to process the design and generate a Timing and Resource Analysis Report based on your selections.
- The Timing Analysis Report provides details on clock frequencies, delays, and setup/hold violations, helping to ensure your design meets timing constraints.
- The Resource Analysis Report breaks down LUTs, DSPs, BRAMs, and FFs usage, giving insights into hardware utilization and optimization opportunities.
The Timing and Resource Analysis Reports for our design can be seen in Figures 24 and 25, respectively. Review these reports to confirm that your design meets the required performance and resource constraints before proceeding further.
Export
The Export section is where we finalize and export our IP for Vivado. To ensure a smooth integration, configure the settings exactly as shown in Figure 26, then click Export. This will take some time and a message similar to as in figure 27 will appear.
This process will generate the necessary IP files, making them ready for use in Vivado's IP Catalog. Once exported, you can easily integrate the custom IP into your Vivado design flow for further processing and implementation.
Open Vivado and create a new project. Once the project is set up, navigate to the top bar, click on Tools, and then select Settings.
Follow the steps shown in Figure 28 to configure the required settings. This step ensures that Vivado is correctly set up to recognize and integrate the exported custom IP into your project.
With all steps successfully completed, your custom IP is now ready for integration into Vivado. This IP can be seamlessly used in both the IP Integrator and Block Design, making it a versatile addition to your FPGA development workflow.
To add the IP to your block design:
- Open the Block Diagram in Vivado.
- Press CTRL + I to bring up the IP Search Bar.
- Type the name of your custom IP, select it, and add it to your design.
- Voila! Your IP is now fully integrated and ready for further implementation and testing.
With the successful creation and integration of your custom IP, you have completed a critical step in FPGA development. This workflow not only streamlines the IP design process but also enhances efficiency, modularity, and scalability for future projects. By leveraging Vitis Model Composer and Vivado, you have ensured a seamless transition from algorithm development to hardware implementation.
As you move forward, further optimization, validation on hardware, and performance tuning will refine your design for real-world applications. This marks the foundation for more advanced FPGA-based solutions, paving the way for high-performance, hardware-accelerated systems.
Comments
Please log in or sign up to comment.