Repository navigation
Zero lab 1
Welcome to this lab in which you will learn how to create a pattern generator ; the one o' one IP for image processing. It is a fairly common IP to use in order to evaluate other image processing IP response to different kind of stimulus.
It's a fairly simple IP perfect for starting point.
In this design we create an IP that generates a video data stream with an arbitrary resolution. To this end, we plan to instanciate
- two input registers to handle width and height values of image
- one output stream, we will use an AXI4-stream standard
- a start control signal
- a done and ready status signals
design synoptic is given below

Start Vitis HLS and create a new project under HLS-Zybo/Zero-lab/lab1 named "pattern_generator"

In the next add tab add the provided design files located in the "src" folder

In the next add tab add the provided testbench file located in the "src" folder

In the final tab select the target FPGA part

Now the project is correctly configured you can explore the design source structure. We can see the IP interface list description in the main function located in pattern_generator.cpp, we offtenly call this function the "IP layout"
void PatternGeneratorUnit( Video_stream &stream_out, int width, int height){ #pragma HLS INTERFACE axis port = stream_out #pragma HLS INTERFACE ap_stable port = width #pragma HLS INTERFACE ap_stable port = height PatternGenerator(stream_out, width, height); }
The function right below :
void PatternGenerator(Video_stream &stream_out, int width, int height);
Is our actual IP, this is were the functional part is located. A double for loop encapsulate a serie of comparators. Depending on comparators output, the output value is defined.
Going back to the testbench file tb.cpp, we first define a call to our layout with a required arguments
// DUT //
PatternGeneratorUnit(stream_out, IMAGE_IN_W_o, IMAGE_IN_H_o);
In the final step, a AXI4 stream consummer model is created to extract the signal coming out of the pattern generator
// AXI4 Stream consummer model
for(int i=0; i < IMAGE_IN_H_o; i++) {
for(int j=0; j < IMAGE_IN_W_o; j++) {
stream_out >> video_elt_out;
f_pattern_out << video_elt_out.data.range(7, 0) << " ";
}
f_pattern_out << endl;
}
return 0;
The output pattern will be stored in a image txt file which we will be able to print out using ImageJ
No code edition is required at the moment, we can move on to dataflow validation
At this point, we would like to simulate the dataflow behavior of our IP. We're not trying to evaluate the real-time processing capabilities just yet.
The idea behing dataflow validation is to make sure our program describe correctly where data is generated and where it should be sent. It's sort of a point to point transfer evaluation. In our case we want to make sure that data is generated within our for loops and then acquired in our AXI4-stream consummer model.
To do so, execute a C simulation. The processing menu is located on the top left corner of the IDE

A standard C compilation occurs, the freshly compiled C program is then execute within vitis hls.
If everything went well, the console should prompt "c simulation done with 0 errors".
Since we are working with images, the ideal test would be an inspection our the generated pattern. To do so, open ImageJ. Select file > import > text image and navigate to <project_root_path>/csim/build/ and open "PatternOut.txt"
Pattern should appear like so :

We can edit the source code in order to generate different kind of pattern. Once We've decided which pattern we need and inspected it we can move to gate development.
Compared to other sort of IP design, this phase will be one of the simplest. Because the dataflow is neat and clear Vitis HLS can run with minimum directives to accomplish a performant HDL.
We simply have to configure the IP top function. To do so, enter project settings menu located on the top left corner of the IDE

under "synthesis" enter the name of the layout function and validate

Start high level synthesis procedure using the process menu.Onece the hls flow is done we can evaluate the ressource utilization of the IP

Note that, because HLS is nothing like true synthesis, LUT and FF ressource analysis lacks of precision. The final ressource utilization will offtenly be less than what's predicted by HLS tools.
Finally we can move to gateware validation, at this point we are interested in both behavior and real-time capabilities of the IP.
To start evaluation, we will ask the tool to automatically build HDL testbench for us and run it. The testbench will be based on our tb.cpp file.
Note that this procedure will be equivalent to HDL simulation. This means that it will be way much longer than c simulation.
In order to reduce the amount of simulation time edit IMAGE_IN_H_o defined variable located under genercis_n_options.h to a valie of 2.
Run co-simulation using the process menu located on the lop left corner of the IDE.
Configure the co-simulation tool like showed below :

If everything went well a "pass" mention should appear We can take a look at the waveform, clic on the wave icon located on the top left corner of the IDE.

Under output signal group we should see our axi4stream interface emitting a pattern like so

Using a 100Mhz clock the IP is able to generate 2 lines in 25.85us. For a 1280x1024 image the estimated frame rate would be 76 FPS. With this kind of information we can then decide if the design should run with a lower clock rate or use less ressource parallelization, this would depend on the application we plan to create.
Coming soon : hls improving an exsisting design