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?

This image has an empty alt attribute; its file name is hls-combinational-1.png