In this lecture, we are going to synthesis the 7-segment controller code using the Xilinx Vivado-HLx 1
and generate the FPGA bitstream. The controller gets a single-digit decimal number and shows that on a 2
7-segment display. 3
We also check our design on the Basys3 board. 4
Firstly, run the Vivado-HLS IDE and create a new HLS project. Choose a project name, for example, 5
“single_digit_seven_segment-vhls” and select a proper 6
path for the project files. 7
In the second step of the create new project wizard choose a design top-function name. Then 8
choose the Basys3 board as the target FPGA platform. 9
After creating the project, we should define the design files. For this purpose right-click on 10
the source folder and create a New Files and name it “single_digit_seven_segment.cpp”. 11
“single_digit_seven_segment.cpp”. Then, create the design header file with the name of “single_digit_seven_segment.h” 12
“single_digit_seven_segment.h”. At this stage, we can create the source and header test bench files. 13
For this purpose, 14
right-click on 15
the Test Bench folder and name the created files properly. 16
As we are going to use arbitrary precision data types, open the design header file and include the 17
“ap_int.h” file. 18
Now go to the design source file, include the header file and write the design top-function code. 19
The top-function receives a single-digit decimal number through an 8-bit input argument called digit 20
and generates two groups of signals for the seven-segment. 21
The first group via the code7segment output argument defines the 7-segment data and the second 22
group through the anodes output argument enables the desired seven-segment. A switch-case 23
statement can implement the behaviour of the design. 24
The statement can select the proper 7-segment code corresponding to the value in the input argument. 25
Also, we need a single assignment to enable the first 7-segment. For this purpose, the value of 26
1110 should be assigned to the anodes output argument. 27
Finally, we should define the argument interfaces, but let’s deliberately leave them for later and 28
check what would happen in the synthesis report. 29
Before synthesising the design code, we should make sure that its behaviour and functionality is correct. 30
For this purpose, 31
we need a test bench. 32
If you haven’t created the testbench files yet, Create two files under the test bench folder under the 33
project in the Explorer view. The first file would contain the test bench source file, and another 34
is the test bench header file. 35
The header file includes the design header file and defines the design top-function prototype. 36
The source file should import the header file. 37
Let’s define an array that keeps all the 7-segment codes from 0 to 9. 38
The source file contains the main() function. We need a variable that represents the status of the test 39
bench. 40
Let’s call that status. At the end of the function, 41
we use the value of this variable to report the status of the design test. 42
Then we need a for-loop to generate all the desired design input as the test vectors to be applied to 43
the design. 44
Before that, we need to declare a couple of variables. 45
The for-loop generates all the numbers between 0 and 9. 46
Also, it applies them to the design and compares the result with the code in our array. 47
In the case of any discrepancy, it changes the status variable value. 48
Now we are ready to perform the C-simulation. 49
The C-simulation report confirms that the functionality of our design is correct. 50
Now let’s perform the HLS synthesis and check the report. 51
As can be seen from the synthesis report, the design is combinational. 52
It doesn’t use any memory cell. 53
However, it has more ports that the top-function arguments. 54
The reason is that we didn’t define the argument interfaces in the design top-function and HLS has 55
selected default interfaces for each port according to its type as an input or output. 56
So let’s go back to the design and add the required interfaces. 57
Now, after synthesis, we see only the function arguments in the port list. 58
Let’s perform the RTL/C Co-simulation to make sure that the design after synthesis is correct. 59
The report confirms the RTL design correctness. 60
Now we are ready to generate the hardware-IP to be used later in a Vivado project. 61
After greeting the design RTL-IP, we are ready for logic synthesis. 62
So, Let’s create a new vivado project and name it “single_digit_seven_segment-vivado” 63
Choose the Basys3 board as the target FPGA platform. 64
Create a block design by clicking on “Create Block Design” under IP Integrator in the Flow Navigator 65
view. Then, accept the default name and press, OK. Add the generated IP to the Vivado repository, By pressing 66
the right-click somewhere in the Diagram window and select the “IP settings…” option. Then go to the Repository 67
under IP, and press on the plus icon. Select the Vivado-HLS project path. 68
The Vivado will search for any IP in the folder and add that to the repository. 69
Add the IP to the design by clicking somewhere in the diagram window and selecting the “Add IP...” option. Make 70
the design ports external. 71
You can do this by holding the control key and selecting all ports and then right-click on one port 72
and select the “Make external” option. 73
Then you can rename ports to make them more descriptive. 74
Now we should connect the external ports to the FPGA pins by defining a few physical constraints. For 75
this purpose, create a new constraint file. Then you can copy all the commented constraints provided 76
by the board vendor and uncomment the desired ones. 77
We need eight switches to provide the input number for the design. Uncomment the required switch constraints 78
and replace the default port names with the design port names. 79
Notice that here I have made a mistake. Let’s keep the mistake to check the Vivado error message. 80
Also, we need 7-segment constraints to connect the design output ports to the 7-segments on the 81
board. Uncomment them and change their names. 82
To uncomment a couple of lines, you can select them and then press the ctrl and slash keys together. 83
Now let’s Generate Output Products… and then Create HDL Wrapper… 84
Now we are ready to generate the FPGA bitstream. 85
However, there is an error in the design. Let’s examine the error message. 86
There is a conflict VCC voltage between signals in digit port, for example, digit[7] and 87
digit[0]. 88
The error in voltage levels indicates that at least of the IOSTANDARD properties assigned to the 89
ports is not correct. 90
If we have a look at the constraint file, then we should correct the typo. 91
And generate the bitstream again. 92
Now, we have another error message. 93
The error message indicates that at least one port has not been assigned to a location or I/O pin. This 94
message shows that at least one the ports does not have any assigned PACKAGE_PIN property. 95
Let’s have a look at the constraint file again and find the problem. 96
There is another typo at line 88. Lets correst that and generate the FPGA bitstream. 97
Now we can program the FPGA and play with the design on the board. 98
This lecture is the last in this section that explained the design concepts and techniques. So the 99
next lecture will give you a couple of hardware designs as exercises through which you review and master 100
the proposed techniques in this section. 101
This is our takeaway message. If we don’t define the port interfaces in the HLS top-function, then 102
the synthesis tool will choose the default interface for each port 103
that depends on the corresponding argument definition and usage in the code. 104
Now the quiz question. Change the code such that the design can show a single-hex digit on 105
one 7-segment.