The goal of this design is very similar to that of this post.
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 Hardware
For 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.

create platform
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 project
1- 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 computerand 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" 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++; } } } int main() { init_platform(); print("Hello Counter\n\r"); 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; int up; int down; for (;;) { *leds = *switches; if (*push_buttons & 0b0010) { // initialization counter = *switches; } if (*push_buttons & 0b0001) { // up up = 1; down = 0; delay(1000); } if (*push_buttons & 0b1000) { // down up = 0; delay(1000); down = 1; } if (up == 1) { counter++; if (counter > 9999) counter = 0; up = 0; } if (down == 1) { counter--; if (counter < 0) counter = 9999; down = 0; } 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); } cleanup_platform(); return 0; }
Test the design on the Basys3 board
After compiling the code run that on the board and play with the counter.
Challenge: can you modify the code to remove the blinking 7-segments when we press the Up or Down buttons?
