The goal of this design is very similar to that of this project.
Here, we are going to have a 4-digit BCD counter. The following picture shows the board configuration. Here, I am using the Xilinx Vitis-2020.1 under Windows 10 OS.
To design an up/down counter on Basys-3 board using Vitis, I am going to use the MicroBlaze processor.
To design this counter, we have four steps: 1- create hardware 2- create platform 3- create application project 4- Test the design on the Basys3 board.
Create HardwareFor this purpose, we should use Vivado.
1- Run Vivado and create a project with the name of “basys3-platform.”
2- Choose the Basys-3 board as the target FPGA
3- Create a block design with the name of basys3
4- Insert the MicroBlaze processor to the design area
5- Click on “Run Block Automation” and do the following changes in the “Run Block Automation” dialog.
6- Click on “Run Connection Automation” select the option as shown in the following figure and press OK.
6- Remove the clock port with the name of “diff_clock_rtl”
7- Double clock on the “System Clock” in the Board window.
8- Accept the default and press OK.
9- now we have to add AXI GPIO IPs to connect the processor to the LED, Switches and 7-segments on the board. Add 5 AXI GPIO IPs to the design.
10- double click on each AXI GPIO API and select its GPIO interface as bellow
11- Now click on “Run Connection Automation.”
12- Right-click on the design in the Source tab and select “Create HDL Wrapper.”
13- Right-click again on the design in the Source tab and select “Generate Output Products.”
14- Then click on the “Generate Bitstream” under “PROGRAM AND DEBUG” in the Flow Navigator on the left.
15- After generating the FPGA bitstream. Click on “File–>Export–>Export Hardware” option. Choose “Fixed” as the platform type. In the next window select “Include bitstream” option and click on Next
16- Change the XSA file name to basys3. Please have a look at the Export to folder name as later we should go to this path and find the basys3.xsa file. Click Next and then Finish.
17- Go to the block design again and click on the Address Editor Tab. Write down the GPIO address somewhere as we need these address in our software code.
1- Now run the Xilinx Vitis tool and create a platform project
2- Choose the “basys3” as the project name and click next.
3- Then choose “Create from hardware specification (XSA)” and click next.
4- Browse and select to the xsa file that we created in the previous step and click next.
5- Right-click on the project in the explorer view and select Build Project.
Create application project1- Click on the File–>New–>Application Project
2- Select the basys3 platform that we created in the previous step
3- Choose an application project name such as “up-down-counter”
4- Choose the “Hello World” as our template code.
5- Right-click on the created project and build that.
6- Connect your board to the computer and run the program
7- You should see all the 7-segments are illuminating and the following message in the Console view.
8- Now modify the code as bellow
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
int* switches = (int*) 0x40000000; // only 16 bits
int* leds = (int*) 0x40010000; // only 16 bits
int* push_buttons = (int*) 0x40020000; // only 4 bits [Down Right Left Up]
int* segment_data = (int*) 0x40030000; // only 8 bits
int* segment_enable = (int*) 0x40040000; // only 4 bits
int counter = 0;
const int svn_sg_code [] = {
0b11000000, // 0---------- > index 0
0b11111001, // 1---------- > index 1
0b10100100, // 2---------- > index 2
0b10110000, // 3---------- > index 3
0b10011001, // 4---------- > index 4
0b10010010, // 5---------- > index 5
0b10000010, // 6---------- > index 6
0b11111000, // 7---------- > index 7
0b10000000, // 8---------- > index 8
0b10010000, // 9---------- > index 9
};
void delay(int n) {
volatile int x = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
x++;
}
}
}
void display( ) {
int count_tmp = counter;
int first_digit = count_tmp%10;
count_tmp = count_tmp/10;
int second_digit = count_tmp%10;
count_tmp = count_tmp/10;
int third_digit = count_tmp%10;
count_tmp = count_tmp/10;
int forth_digit = count_tmp%10;
*segment_data = svn_sg_code[first_digit];
*segment_enable = 0b1110;
delay(100);
*segment_data = svn_sg_code[second_digit];
*segment_enable = 0b1101;
delay(100);
*segment_data = svn_sg_code[third_digit];
*segment_enable = 0b1011;
delay(100);
*segment_data = svn_sg_code[forth_digit];
*segment_enable = 0b0111;
delay(100);
}
int main()
{
init_platform();
print("Hello Counter\n\r");
int up;
int down;
for (;;) {
*leds = *switches;
if (*push_buttons & 0b0010) { // initialization
counter = *switches;
}
if (*push_buttons & 0b0001) { // up
up = 1;
down = 0;
for (int i = 0; i < 50; i++) {
display();
}
}
if (*push_buttons & 0b1000) { // down
up = 0;
for (int i = 0; i < 50; i++) {
display();
}
down = 1;
}
if (up == 1) {
counter++;
if (counter > 9999)
counter = 0;
up = 0;
}
if (down == 1) {
counter--;
if (counter < 0)
counter = 9999;
down = 0;
}
display();
}
cleanup_platform();
return 0;
}
Test the design on the Basys3 boardAfter compiling the code run that on the board and play with the counter.
Comments