RoadTest: FPGA Essentials: Basys 3 Artix-7 FPGA
Evaluation Type: Development Boards & Tools
Did you receive all parts the manufacturer stated would be included in the package?: True
What other parts do you consider comparable to this product?: (1) Digilent Arty “Artix-7 35T Arty FPGA Evaluation Kit” $99 (2) Xilinx Artix-7 FPGA AC701 Evaluation Kit $1295 The Digilent Arty Artix-7 35T would be a good choice for those on a budget. I have several of these and they are a very good product for the money. You will need to acquire several Arduino Shields to hook up if you want to start some basic learning and want to do something other than flashing an LED light or you can use the Digilent PMOD connector to hook up several peripherals. The Xilinx Artix-7 FPGA AC701 Evaluation Kit is much more expensive and is more suitable for a development platform. Many Xilinx development platforms come with some additional licensing for Vivado tools, so that may justify the large price difference. The earlier BASYS 2 is a similar learning tool but it uses the Spartan 3E and is not supported with the new Vivado Development Kit and it will be avaialble for a limited time. https://store.digilentinc.com/basys-2-spartan-3e-fpga-trainer-board-limited-time.
What were the biggest problems encountered?: There were no problems encountered with the board. There was very good documentation and everything worked as stated.
The BASYS 3 by Digilent, provides a platform for learning how to program an FPGA and is highly recommended for students or learning on the job. There are a several positive points for the BASYS3:
Digilent has established a standard interface for adding peripherals, called PMOD. Several different radios (WIFI, Bluetooth etc), and other sensors are available using this interface.
It was very easy to take inventory on unboxing the BASYS3. What is included is the board and nothing else.
If you are planning on using the BASYS3 for teaching a class, where you hand these out, you will want to order a USB-A to micro cable for each of the students. If you are like me you may have dozens of them, so no worries. However, if you are impulsive and get the BASYS3 and find there is no cable and you check Prime Now, get ready for disappointment, Amazon did not have one that could be delivered in an hour in my zip code.
The summary of the Xilinx FPGA is as follows FPGA Part #XC7A35T-1CPG236C; Logic Cells: 33,280 in 5200 slices; Block RAM: 1,800 Kbits, DSP Slices 90, Internal clock 450 MHz+
Connectivity and On-board I/O consists of the following:
Pmod Connectors: 3; Switches: 16; Buttons: 5; User LED: 16; 7-Seg Display: 4-Digit; VGA: 12-bit; USB: HID Host (KB/Mouse/Mass Storage) Electrical Power; USB: 5v (Pins)
Logic Level: 3.3v; Physical: Width 2.8 in Length 4.8 in
The summary from the Digilent website is as follows:
The BASYS3 board is a complete, ready-to-use digital circuit development platform based on the latest Artix-7™ Field Programmable Gate Array (FPGA) from Xilinx. With its high-capacity FPGA (Xilinx part number XC7A35T-1CPG236C), low overall cost, and collection of USB, VGA, and other ports, the BASYS3 can host designs ranging from introductory combinational circuits to complex sequential circuits like embedded processors and controllers. It includes enough switches, LEDs and other I/O devices to allow a large number designs to be completed without the need for any additional hardware, and enough uncommitted FPGA I/O pins to allow designs to be expanded using Digilent Pmods or other custom boards and circuits.
The host machine (i.e. Desktop PC) used to run Vivado is a Linux Ubuntu-Studio 16.04 (six processor AMD) .
When the BASYS 3 was first plugged into the computer there was no lights or actions and the Linux "dmesg" command indicated that there was no new USB hardware plugged in. The slide switch was moved to the up position and lights started up. Upon examination, the switch was set in external power mode. It looks like 5VDC can be applied externally with the 2x.100 header below. This external power cable might be something else you would want to add to your shopping list. The AVNET Minized that was previously reviewed used a second micro USB connector for external power. With the proliferation of USB charging stations and wall mount supplies, that seems to be a bit more convenient. The micro USB provided enough current for most lab work, so this might not be an issue unless you want to run it in a final application.
Once powered up correctly, the output from the linux "dmesg" command indicates that there are two USB serial ports detected. It is assumed that one is for JTAG and the other is for a serial port.
In a previous road test , AVNET MiniZed Dev Board - Review, I discussed some considerations in installing Vivado and I chose the Linux system for installation. Because I already have Vivado installed then the general user could watch the short video, Vivado Design Suite Installation Overview, or you can simply set up a Xilinx account, if you don't already have one and Download the Vivado for your operating system. It should be noted, you will need to have about 20 Gigabytes of drive space. Xilinx gives you the option of installing the license for the WebPack or you could get a free 30 day license that have some additional features. You might want to wait to apply for that license should you want to use some of the additional features at a time when you may need them. The free WebPack gives you most everything you might need and certainly enough to get started. Being able to run Vivado is worth the price of a development board as it is quite an FPGA tool kit.
Digilent has a 16 minute training video Getting started with Vivado and Basys3 on youtube that you might want to refer to if you are new to FPGA's and Vivado. I briefly scanned through it and it looks like it covers quite a bit of material so I may be watching it at some time in the future.
During the evaluation process, Xilinx released a new version of Vivado so two versions were tested, the first being 2017.4 and then 2018.4, these are the latest versions of Vivado at the time of writing this review. In my previous review on AVNET MiniZed Dev Board, I mentioned that there was an issue with setting up the icons for the Vivado tools, during my installation, the reason was discovered: The /opt directory where Vivado wants to be installed requires sudo (root privileged) and thus the icons were put in the user "root" directory. They were manually copied to my user desktop.
Vivado was already installed on the linux host machine, so it was launched, the hardware tab was selected, and auto-connect was used and it was able to immediately find the BASYS3 board. Having the JTAG available on board is a feature that makes getting started much easier than the fly wire JTAG adapter of yesterday. The screenshot of what you should expect is shown below.
The first goal of my Road Test is to review the tutorials on the Digilent's website to become more familiar with the Vivado tools and some of the IP.
The second goal, after going through the tutorials, is to use this board for what it is intended, a teaching aid! My main personal goal of this Road-Test, is to use it as a vehicle to become more fluent in VHDL. In the past I have coded primarily in verilog and some system verilog. My exposure to VHDL has been minimal and was usually limited to working with a top level "test wrapper" that someone else has written.
To get going on my goal of learning VHDL, as quickly as possible, with the BASYS3 board, and to get as much as possible out of the Road-Test. I picked out an online VHDL course that would be used as a starting point for Road Testing called Xilinx FPGAs: Learning Through Labs using VHDL, from uDemy. It seemed like a pretty good fit and fortunately the course specifically called out the BASYS3. I previously bought several different FPGA training courses as they went on sale in anticipation of building up my FPGA and FPGA tool skills, and over time plan to follow through with them all. NOTE: There are routinely sales on the courses and I paid $10 for the course, lately the courses have gone on sale for $10.00, $10.99 and $11.99.
Upon inspection of the Digilent's website, Digilent has done a very good job on putting together a large amount of training material and videos so if you don't need to take a course to start getting to understand how to program an FPGA, you can visit https://reference.digilentinc.com/reference/programmable-logic/basys-3/start and look at the number of training material available for free. The BASYS3 is also used quite a bit for FPGA labs at Universities and Technical Colleges so you will find a lot of additional material if you google a bit.
In order to select the appropriate FPGA, the speed grade and how the I/O is configured, a Board Definition File should immediately be added.
A google search for "Board Definition Files Basys 3" resulted in the following site https://reference.digilentinc.com/reference/software/vivado/board-files?redirect=1
The files are contained in vivado-boards-master.zip . You may want to save a copy of this because the board files are copied into a directory of a specific version of Vivado. For instance I dropped mine into opt/Xilinx/Vivado/BDFS (this is the default location for Vivado in linux - it will be different for windows). I expanded the zipfile in that directory and the files that I will want to copy are in the /opt/Xilinx/Vivado/BDFS/vivado-boards-master/new/ as shown in the screenshot below.
The files from the link above, contain Board Definition Files for all of the Digilent product line that work with Vivado. The directory will be copied to the directory /opt/Xilinx/Vivado/2017.4/data/boards/board_files and you can see in the directory that basys3 is now included.
It looks like three xml files ultimately define the board definition as shown below, after descending into the basys3 sub-directory.
After successfully adding in the Board Definition File for the Basys3 board, you can now select if from the drop down window in Vivado when you are instructed to select the part. The Boards tab is selected as shown below. You can further sort through it. If you did not set up the board file then you would need to select the xc7a35tcpg236-1 part and either define each pin by hand in the constraints file or use the Basys3_Master.xdc. You will want to use the Basys3_Master.xdc file when you want to create a simple interface. The file has what you need to map the I/O to the correct pin, and all you need to do is uncomment the lines for the pins you want to use. The editor in Vivado has an uncomment/comment button, and even though I've used Vivado quite a bit in the past, I just discovered that during this Road-Test.
As an example, a new project was started called BASYS3_1 to test out the Board Definition File as shown below:
What is interesting is that the Board Definition File provides the External interfaces as shown below in the Design Tab. One has access to the 16 switches, 16 LED's, and the 4 digit 7 segment display. There is also access to the master clock and reset that can be used at the IP block level. However, after further investigation it appears that the IO uses the AXI standard and on first investigation it may be more useful if you are implementing a more complex system that uses the AXI standard throughout.
Some blocks that are either part of the Board IP or part of the built in Vivado IP, that may be useful for Lab 1, from the class are shown below. At this point I'm just kicking the tires so to speak. It should be noted that in general Block Design using IP, is quite useful. Also one does not need to stitch ( connect together with code) all of the modules together at a top_level netlist. The block method wiring can suffice for this operation. This is a step that is usually tedious in FPGA or IC design and one that I kind of hate to do.
NOTE: If you are interested in how a board definition file is written, you can refer to the Xilinx User Guide, UG895, for additional information. Search for "brd" to get you to the right section.
There is a second way of defining the resources of the BASYS3 board, or at least the FPGA associated with the BASYS3. That file is located at the following site: https://github.com/Digilent/Basys3/blob/master/Resources/XDC/Basys3_Master.xdc.
If you were to start a new hardware design from scratch, there is a step, that may be iterative, where you chose what type of a project you are starting, and if you chose I/O Planning Project you can map the FPGA pins to pins with mnemonic names that may be part of the schematic. You can also make choices about the property of the pins such as drive strength, chose, input or output as well as other options. As a result of this planning operation the outcome is a constraints file. This process usually goes hand in hand with the hardware board design. Fortunately Digilent has gone through this process and they provide you with the constraint file. As stated earlier, most of the lines are commented out so you need to uncomment them to use it. When other good point to make is when you add files, make sure that you copy them into the Project. Otherwise what you are fiddling with may affect other projects. That is OK if that is what you intended but I recall when I first started using Vivado, I didn't realize this!
The Digilent website for the Basys 3 has a training tutorial on the several different methods of programming the BASYS-3. The BASYS-3 Reference Manual also shows you the three options for programming. The jumper for JP1 needs to be in the appropriate position for either QSPI, JTAG or USB. When the jumper is selected for USB then you can transfer a 'bit' file with a USB memory stick configured as FAT32 (msdos) by just pressing the button next to the jumper. You can refer to the BASYS-3 Reference Manual for more details.
Each time the FPGA is powered up, a programming image needs to be loaded into the FPGA. Typically you will want to use what is programmed into the Quad SPI Flash memory chip, (Vendor=Spansion, size=32M, part number S25FL032) and that is what will be loaded the next time it is powered up, assuming JP1 is in the correct position. It should be noted that there are four serial lines on a Quad SPI so the FPGA can be read into the FPGA 4 bits each clock cycle, so this helps to load the FPGA faster upon power up.
In summary, it looks like this is a good tutorial to go through in order to figure out the different methods of programming the FPGA. Initially I was a bit surprised to find that I needed to press the program button to load the program on power up and it took 6 seconds, much longer than I expected (with a 33 MHz clock and 32 Mb of data, the transfer would take a second if it were loaded 1 bit at a time and 1/4 second with a quad SPI) . Upon further investigation, it was found that the setting for the configuration clock was set to default of 3 MHz. After correctly setting it to 33 MHz, per the tutorial, the SPI was loaded upon power up. See screenshot below after setting it correctly.
This operation resulted in a new constraint and it was written to a file I named configuration.xdc. Instead of going through the menu, one could paste this into a constraints file to be used henceforth.
The Digilent website for the Basys 3 has a training tutorial on using the Vivado IP Integrator. In it there is a discussion on using the AXI (Advanced eXtensible Interface) which would be helpful in using the AXI GPIO as shown in the first block diagram above. There is a mention of using a processor, which is also an IP element. For simpler designs you can also use constraint file, mentioned in the paragraph above (Baysys3_Master.xdc) if you want to do some basic I/O.
I had to abandon my first attempt as I must have made an incorrect choice and there were a couple of unresolved signals. The second attempt went much smoother and as a result a MicroBlaze, a 32 bit RISC CPU is instantiated and the connections to program the IO ( through software) was created. As the previous link indicates the MicroBlaze is a RISC based microprocessor that can be embedded in the logic fabric and general purpose fabric. This is pretty much a roll your own micro! This also gives you an opportunity to try out the SDK ( Software Development Kit). Vivado and the SDK can run hand in hand and besides just programming the hardware you can also load the internal firmware. This is a well written tutorial and it is worth following.
The Finished Block Diagram is shown below.
The SDK was opened as shown in the screenshot below and the bit file, containing both the MicroBlaze code (*.elf) and the FPGA program was loaded through JTAG. Once successfully programmed then the debugger can be used to launch the code, using the same JTAG interface. This tutorial took a few times through to get it all to work correctly, but when you stop and think about it, a lot of things worked to get everything to play. I'm impressed with what can be done with the IP.
Building a MicroBlaze in Xilinx has been on my todo list for quite a while so this was a really good exercise that Digilent created.
Getting Started with Digilent Pmod IP
After you have built a MicroBlaze you can add a Pmod into the block design. There are a large number of PMOD IP, from Digilent. you can follow the link "Getting Started with Digilent Pmod IP" to go to the tutorial. It is also a good idea to see what the Pmod Interface Specification is. It looks like with a small amount of bread boarding you could create a few of your own Pmods so that you would be able to more seamlessly interface to peripherals.
Digilent's Pmod Tutorial is somewhat open ended regarding specific Pmod devices so I looked around in my development board boxes and I found I had several Wifi Pmods. I had a GT202 that came with a couple of different Renesas Synergy kits I own; It consists of a Qualcomm Atheros QCA4002 chip in a PMOD profile. I thought, do not fear, Digilent has been touting Renesas Pmods in their blog, in the posting, Pmods at Embedded World 2017, so I thought why not try and build an FPGA PMOD interface to a WIFI module. I realized upfront that there could be a couple of issues, the first being the hardware interface, not all WIFI modules have the exact same interface, although that seemed like a reasonable thing to change in Vivado, perhaps by using sections of other IP. The second and more important factor is, is there ready made code available that could be run on the Microblaze host ( In Arduino speak they are called libraries) ? Because this is a review, I decided to take a chance and drop in a WIFI Pmod and so how easy it is to build the hardware component. If all else fails one could do one of two things, the first would be to buy a Digilent WIFI Pmod, or the second would be would be to buy or interface an ESP module to the Pmod interface, such as with the ESP32, that is touted in the Digilent Blog. I have many of these in my electronic stash.
When I got to the point of embedding the software with the SDK, I came up empty handed for a turn key approach to my GT202. I was able to go to the Qualcomm website and download an SDK for the part, but at that point it would be going down a huge rabbit hole and if I wanted WIFI with an FPGA there are certainly better approaches. At this point one might consider just using a microprocessor, for instance, Renesas has a turn key approach with the module that is more or less turnkey to sending data into a cloud such as AWS. With an Arduino, using a Wifi module is really very simple as there is an effort by many to provide the needed (software) libraries. I can't say that is the case with trying to use a Pmod with Xilinx for the first time. Perhaps I need to do more research on this subject of Pmods. Another link to the Pmod world is the Pmod org website. Perhaps there are ways of taking the code that has been written for the Arduino and porting it to the Vivado SDK, but this is currently the weakpoint. The Zynq FPGA might be better suited for some of these operations, where one does not want to reinvent the wheel.
All that said, the tutorial was pretty good and with a little struggle was able to get a bit image built. I started out by using the project used above in the Getting Started with Vivado IP Integrator. After first downloading the Digilent Libraries and importing the location into the project, The PmodWifi was added and autowired with "Run Connection Automation" in Vivado, the external Pmod interface and the interrupt were not connected. The tutorial covered the interrupt, although I was able to figure it out on my own, that an interrupt controller needed to be added. The tutorial reassured me that I had them connected up. The tutorial also covered that I could used the Connector JA from the board file that was imported above, by selecting Block Design->Board->Pmod->Connector JA as shown in the screen below. However, after several unsuccessful attempts at building a bit image there was a problem with the Pmod interface. After double clicking on the PmodWifi block the pulldown allowed me to select the connector JA as also shown in the screenshot further below, resulting in a 'clean' compile and a successful bit image.
The screenshot below shows the final block design, note the Pmod and Interrupt blocks.
The screenshot below shows the physical implementation of the design and it looks like about 10 to 15 percent of the resources have been used, although it has been my experience that the place and route is not very conservative when there is a lot of space available and/or when the route is loosely constrained.
In conclusion, this has given me quite a bit of confidence in using some of the Vivado and Digilent prebuilt IP and as stated earlier, the software aspect of using some complicated peripherals may be more complicated than the hardware part.
XILINX FPGAs Learning Through Labs Using VHDL Class
As stated earlier, one of the major advantages of the BASYS3 is that it is a well known and often used board for educational purposes so it is ideal for quickly jumping into a class and not needing to hook up a bunch of hardware. The XILINX FPGAs Learning Through Labs Using VHDL class mentioned above was started and it appears to be a reasonable way of getting into Vivado using VHDL. By a high level introduction, the class provides solutions to each of the labs for several different FPGA boards but does not go into detail about how to get there. If you like to learn by jumping into the deep end of the pool, so to speak, this class would be ideal for you. I'm interested in learning VHDL from a more systematic, bottoms up approach and have several in queue, but it is also a good idea to learn your way around the tools, so I will stick with this approach for the Test-Drive.
The first lab is a BCD Display assignment. In this Lab, First, a slow clock is generated from the 100 MHz internal master oscillator. Second, a driver that decodes binary to the 7 segment display needs to be written. Third a means of switching between decimal (base 10 counter) and binary (base 16) needs to be written and all of it connected together. This is a fairly big step for the first VHDL project. So here goes...
The lab by itself, is also a good first assignment as it gives some fairly instant gratification by using the pre-written code. The project files for the BCD_Display project were downloaded and unzipped into my workarea. There are many directories and many layers of sub-directories that were automatically created from Vivado and these files were cloned as shown in the file system below.
From Vivado use the File->Open Project->BCD_Display.xpr to open. Open the Block Diagram from IP Integrator->Open Block Design will result in the block diagram shown below. What this diagram indicates is that the lab was written using IP blocks and connected together at the block level. Some of the IP Blocks are included with Vivado and some were written in VHDL and a wrapper put around them. There are a couple of interesting blocks, the first is the Pulse Width Modulator block that creates a low frequency clock for the counter so it can be viewed in real time. It appears that this is IP generated for the class as I did not find this in the IP library. The binary counter and constant blocks can be pulled from the board definition file.
My goal for taking the class is to get familiar with VHDL and as such, a good exercise was to create a block diagram and then write the VHDL for each of the blocks independently. The screenshot below shows the result. Notice that the VHDL blocks that I created are marked as RTL and the blocks that are IP are not.
BCD to 7 Segment Design
After importing the Basys3_Master.xdc, the following is uncommented out, to allow use of the 7 segment display, four switches are also uncommented out to allow simple test of the code. The name of the signals for the display will be referred to as seg down to seg going from segment g down to segment a. The Anodes for each display digit, will be referenced as an downto an with anode an being the most significant display element digit. The decimal point will be referenced as dp.
The display is shown, and again, what we need to know is that pulling a segment to ground, will light the display. The four anode signals represent an down to an as described above and provide a positive voltage to all of the segments of a digit.
To code this with VHDL, I think the simplest method will be to have a case statement with a 7-Segment value associated with each.
For those new to either verilog or in my case VHDL, Vivado has built in templates and you can drop language constructs through the copy template as shown in the following screenshot.
My notation in the table above is hexadecimal, similar to a register map, as I was hoping to use hexadecimal for entering into the VHDL case statement, but because there are 8 bits and not 7 the compiler complained so I went to binary notation ( I realize there is a way of casting these but I didn't want to get hung up on this as my first VHDL coding experience).
I wrote this (hopefully!) where it uses combinatorial notation, requiring no clock. I found, a couple of 7 segment examples online, but they required a clock. Rather than build a simulation, the switches and displays were used directly. This is a major benefit of the BASYS3 board with built in displays and switches. As shown below, the switches were used to set the hex input to a value between 0 and 15 and the anodes are hard tied so that all four displays are tested.
4x7 Segment to 7 Segment Mux
The next step is to use four instances of the hex to 7 segment display created above and add a multiplexer for enabling the display and selecting which digit is currently enabled. The VHDL code is shown on the left and the block diagram is shown on the right. The push button switches were used to enable and select the digit. A combinatorial logic approach was chosen as there is not a need to use a clock for this as everything can be derived from a truth table. I must say I don't know any of the nuances of VHDL yet, so hopefully my coding doesn't result in using 'latches'. Using latches is considered a big no-no in IC design (unless there is actually a good reason for a latch). I also uncommented out the three pushbutton switches in the constraint file, Basys3_Master.xdc ( not shown ).
PWM and Clock Block
There is a clocking wizard, that builds some Xilinx specific code for creating a different frequency oscillator form the 100 MHz oscillator. This is a really import section as it will be used over and over again in other designs. This is not a VHDL exercise, but another use of the IP that comes with Vivado.
Select Project Manager->Board->System Clock and a Connect Board Component pop up window will occur, select clock_CLK_IN1 and hit OK.
Setting up the clock blocks was pretty straightforward but I added the PWM block at the same time and as a result caused a bunch of problems and errors, although I was able to create a bit image, the results were discouraging. The first thought was there was a problem with the clock MMC so I wanted to find out if there was anything special I needed to do to simulate the clock block. I found a YouTube video that I sped watched, Verilog Tutorial 21: Vivado Clock IP, and it covered a simple simulation and I was able to simulate a post synthesis result, however I was getting errors with the Behavioral Simulation
Below is the results, when trying to simulate a "Behavioral Simulation". There were quite a few error messages.
The post synthesized functional simulation did provide results that indicate that the clock wizard set up the clock correctly !
Because of the inability to run a Behavioral Simulation, I therefore decided to go back one step further, because debugging the post synthesized simulation didn't make sense because the internal signals were very difficult to figure out. Of course this is even harder when the code was just plain wrong. A new project was created with just the PWM and a very simple simulation, written in verilog, that was used to stimulate the behavioral simulation with enough initial conditions, to do something (OK I cheated a little, I used verilog for my simulation). Breaking things down into atomic level is probably good practice for anyone new to either verilog, VHDL and/or Vivado. Create a block independently and write a simple simulation. This can save a lot of banging the head against the wall.
The test bench called pwm_tb.v ( written in verilog for convenience) and the pwm.vhd are shown below. I had many iterations of the pwm.vhd until I figured out some of the differences between writing in verilog and VHDL, and I'm not going to guarantee that it is any good, but rather to demonstrate the use of the tools to learn the language, VHDL.
In the simulation, the clock was sped up from 4MHz to 100MHz so that results would be available sooner, for each simulation turn. If you notice the little red dots, you can also step through by setting breakpoints. That is a means of examining things more like software/firmware development. If you are using VHDL variables, you will only be able to access them in this mode, as they are not currently supported in Vivado, and means you will probably want to use signals instead of variables where possible.
The simulation is shown below and it shows that a counter can be created with the output from the clocks block.
The pwm.vhd block was re-imported back into the previous iteration where I could not get a Behavioral Simulation to run, and voila, from that point I was able to make good progress. There were a few changes made to the pwm.vhd block and the multiplexer block that takes the counter output to operate each of the 4 segments was tweaked as shown in the screenshot below: I went online and utilized a VHDL Coding 10 Bit Decimal to BCD article in StackOverflow as the basis of finishing the aspect of binary to BCD conversion.
The final block diagram is shown below:
A short video shows the final result.
In summary, Digilent provided a robust board with many user inputs, that are fairly easy to get some basic functionality out of. For those with little or no FPGA experience this is a real good setup up. If you are on a very tight budget, you might find other boards that are more economical but all in all it is a very good platform. Although I have experience in verilog, I chose to use this platform to become more familiar with VHDL. I was able to easily download other peoples projects and run them and start to evaluate how they built projects. I was also able to use a language that I had little ( or no coding) experience with (VHDL) and with the Vivado tools be able to write functional and test code, simulate, run images by loading through JTAG both directly and by programming the serial SPI Flash.
My only negative comments regarding the BASYS3 is perhaps Digilent could do some value analysis to reduce the product cost so it would be available to more as an inexpensive learning aid and narrow the gap between this board and some other FPGA boards with more features. It would also make more sense to move to an HDMI interface instead of VGA, but this may have been done for backward compatibility.
I feel that I've accomplished what I wanted to do (become familiar with VHDL). VHDL is a rich and complex language, and I think I have the basics to tackle a bigger project successfully or at least be dangerous. By tackling a VHDL project like this with minimal experience, I learned a great deal about VHDL, by figuring out what I needed to get the job done by the seat of the pants. At this point, it would be a good idea to take a more formal course in VHDL and learn from the ground up. In parallel it would also be good to do a few more Labs.
BTW, here's a thought re design - why not put the hex to seven seg decoder before the multiplexor - I think you'l find it uses less logic and is easier to debug.
And a second though:
Learn to love synchronous (ie clocked) logic design - with FPGAs it's the only way (to do anything complex).
Keep up the good work.