Along with Hackster there is a world of great FPGA resources which are free, easily available. These resources range from blogs and courses, to editors, simulators and synthesis tools.
As December is just around the corner I thought it would be a good idea to create a simple project which could run on either a PYNQ Ultra96V2 or a desktop computer and share 24 of what I think are the best FPGA resources.
The project will be created such that if you wanted to modify it with your own recommendations it will be easy to do.
To be able to run the design both on the Ultra96V2 and Desktop PC we are going to use Python and PyGame to create a fun advent application.
The first thing we need to do is prepare the list of FPGA resources which we wish to share, all of them are either open source or freely available.
- Blog - MicroZed Chronicles - https://www.adiuvoengineering.com/microzed-chronicles-archive
- Editor - Teros HDL - https://www.terostech.com/
- Timing / Documentation - WaveDrom - https://wavedrom.com/
- Course - Avnet / Hackster MiniZed Course - https://www.hackster.io/workshops/minized?ref=workshops
- Simulator - Verilator - Verilog Simulator https://www.veripool.org/wiki/verilator
- Simulator - GHDL - VHDL Simulator http://ghdl.free.fr/
- Processor Core - Serial RISC V - https://github.com/olofk/serv
- Simulation / Test Bench cocotb - https://github.com/cocotb/cocotb
- Synthesis - YoSYS - http://www.clifford.at/yosys
- Course - Introduction to PYNQ https://www.element14.com/community/events/5504/l/pynq-z2-workshop-getting-started-with-pynq
- Language - MY HDL - http://www.myhdl.org/
- Blog - FPGA Related - https://www.fpgarelated.com/
- Course - Ultra96 CERN Course - https://ohwr.org/project/soc-course/wikis/home
- Simulator - Icarus Verilog - http://iverilog.icarus.com/
- Blog - Art of FPGA Design - https://www.element14.com/community/groups/fpga-group/blog/2018/07/11/the-art-of-fpga-design
- Simulation - Open Source VHDL Verification Methodology - https://osvvm.org/
- Resources - CERN Open HW Repo - https://ohwr.org/welcome
- Blog - Art of FPGA Design Season 2 - https://www.element14.com/community/groups/fpga-group/blog/2020/10/20/the-art-of-fpga-design-season-2-digital-signal-processing-from-algorithm-to-fpga-bitstream
- Getting Started with Vitis - https://www.adiuvoengineering.com/vitis-training
- IP Core - OpenCores - https://opencores.org/projects
- Simulation - Universal VHDL Verification Methodology - https://uvvm.org/
- Blog - Knitronics - https://www.knitronics.com/
- Course - Introduction to Vivado https://www.element14.com/community/events/5605/l/xilinx-workshop-getting-to-know-vivado-part-i
- Blog - Embedded Hour - http://embeddedhour.com
The next step is to connect our Ultra96 to the internet using the WIFI and install the necessary packages. On the Ulra96v2 we can connect to WIFI using the WIFI notebook in Jupyter. We can connect the PYNQ jupyter installation by connecting the Ultra96v2 directly to our development machine using the Upstream MicroB connector.
Connecting over USB in this manner enables us to use the device as a Ethernet Gadget and work with the Jupyter environment.
Once the PYNQ image is created we can open the Jupyter notebooks by opening a browser and navigating to
192.168.3.1
This will open up the Jupyter notebook environment, under the common folder you will see a WIFI notebook open this with your WIFI settings to hand.
Jupyter Notebook Environment
Enter the SSID and Passphrase when prompted by the notebook.
WIFI Notebook
Once we are connected to the internet, we can then open a terminal window and download the packages which are necessary.
Connect to internet and get packages we require these include
sudo apt-get install python3-tk
sudo apt-get build-dep python-pygame
python3 -m pip install -U pygame
If you have not seen it before the apt-get build_dep is very powerful it will determine the dependencies required, and if they are missing download them to our Ultra96v2.
installing the Python3-TK
Once installed we are ready to begin writing our application.
Creating the ApplicationMy idea for the application is really quite simple, the game will display image on top of which is located 24 doors one for every day of advent. The application will then be able to open the door depending upon the month and the day.
If the month is not yet December the application will ask the user to wait until the start of the month. Once the month of December starts the application will determine the day and then when the reveal button is clicked the doors up to that day of the month will be opened.
To be able to change or update the surprises behind each door, a text file will be used which contains the links to all 24 FPGA links
To get started developing our application we first need to obtain suitable images for the back ground and the open and closed doors. The best place to source open source images is www.pixabay.com from here I was able to download a excellent back ground image and images of the closed and open doors.
The first thing we need to do is set up all of the packages we need
import pygame
import pygame.gfxdraw
import time
import math
from random import randint
from pygame.locals import *
import webbrowser
from datetime import date
Following this we need to create our form, open the file with the links in and query the systems time and date.
today = date.today()
FRAME_X = 1280
FRAME_y = 800
WHITE = (255, 255, 255)
GREY = (200, 200, 200)
BLACK = (0, 0, 0)
GOLD = (197, 179, 88)
f = open("images/links.txt", "r")
links = f.readlines()
f.close()
pygame.init()
display_surf = pygame.display.set_mode((FRAME_X, FRAME_y))
pygame.display.set_caption('24 Days of FPGYAY Advent')
background_colour = (255,255,255)
display_surf.fill(background_colour)
month = today.month
day = today.day
In the code above we are setting the X and Y size of the frame to be displayed by the game. Defining the color for the different colors and fonts used within GUI.
The code then initializes the pygame and set up the basic image of the screen, before querying the month and day.
bg = pygame.image.load("images/snowman-1090261_1280.jpg")
display_surf.blit(bg, (0, 0))
pygame.display.flip()
font = pygame.font.SysFont('Times New Roman', 20)
text = font.render("What FPGA Resources are behind the doors?", True, (255, 0, 0))
textRect = text.get_rect()
textRect.center = (200,20)
display_surf.blit(text, textRect)
font = pygame.font.SysFont('Times New Roman', 20)
text = font.render("Warning will open up to 24 Tabs in your browser", True, (255, 0, 0))
textRect = text.get_rect()
textRect.center = (200,780)
display_surf.blit(text, textRect)
if month == 12:
test_day = day
else:
test_day = 0
x = 50
y = 50
element = 1
for vert in range(4):
for horz in range(6):
d1 = pygame.image.load("images/picture1.png")
display_surf.blit(d1, (x, y))
x = x + 100
element = element + 1;
x = 50
y = y + 150
button_01 = Button("Reveal!", (300, 700), reveal)
buttons = [button_01]
The next element of code above then sets up the background image (the snowman) along with writing text on the background image which defines the FPGA Resources and Warns the user up to 24 tabs might be opened in a browser.
The code then checks the month of the year if it is not December the month is set to a value of 0 to prevent the application opening doors regardless of the day
As the project is first starting up all of the doors on the images are drawn to be closed.
Finally a button is created which will reveal the links for the correct number of days.
class Button():
def __init__(self, txt, location, action, bg=GOLD, fg=BLACK, size=(200, 100), font_name="Segoe Print", font_size=50):
self.color = bg # the static (normal) color
self.bg = bg # actual background color, can change on mouseover
self.fg = fg # text color
self.size = size
self.font = pygame.font.SysFont(font_name, font_size)
self.txt = txt
self.txt_surf = self.font.render(self.txt, 1, self.fg)
self.txt_rect = self.txt_surf.get_rect(center=[s//2 for s in self.size])
self.surface = pygame.surface.Surface(size)
self.rect = self.surface.get_rect(center=location)
self.call_back_ = action
def draw(self):
self.mouseover()
self.surface.fill(self.bg)
self.surface.blit(self.txt_surf, self.txt_rect)
display_surf.blit(self.surface, self.rect)
def mouseover(self):
self.bg = self.color
pos = pygame.mouse.get_pos()
if self.rect.collidepoint(pos):
self.bg = GOLD # mouseover color
def call_back(self):
self.call_back_()
def mousebuttondown():
pos = pygame.mouse.get_pos()
for button in buttons:
if button.rect.collidepoint(pos):
button.call_back()
To create the button we first need to define the class and then define the action which should be taken when the mouse is clicked.
def reveal():
print("hello")
x = 50
y = 50
element = 1
if test_day == 0:
font = pygame.font.SysFont('Times New Roman', 20)
text = font.render("Please Wait For December", True, (255, 0, 0))
textRect = text.get_rect()
textRect.center = (500,20)
display_surf.blit(text, textRect)
for vert in range(4):
for horz in range(6):
if element <= test_day:
d1 = pygame.image.load("images/798005_713f7725.jpg")
display_surf.blit(d1, (x, y))
font = pygame.font.SysFont('Times New Roman', 20)
text = font.render(str(links[(vert+1)*horz][:-1]), True, (255, 0, 0))
textRect = text.get_rect()
textRect.center = (x+10,y)
# display_surf.blit(text, textRect)
new = 2 # open in a new tab, if possible
# open a public URL, in this case, the webbrowser docs
url = str(links[(vert+1)*horz][:-1])
chrome_path="SET BROWESER PATH"
webbrowser.register('chrome', None,webbrowser.BackgroundBrowser(chrome_path))
webbrowser.get(using='chrome').open_new_tab(url)
else:
d1 = pygame.image.load("images/picture1.png")
display_surf.blit(d1, (x, y))
x = x + 100
element = element + 1;
x = 50
y = y + 150
The penultimate step is to create the function which is run when the button is clicked. This takes the day of the month and opens the number of doors upto and including that door, provided the month is December.
To get this to work across platforms you need to set the path of the browser where the code is marked SET BROWSER PATH
The final element of the block is to run the main loop
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
mousebuttondown()
for button in buttons:
button.draw()
end = time.time()
pygame.display.flip()
pygame.time.wait(40)
We can then run the script from the command line as required.
Running On Ultra96V2When I ran this on the Ultra96V2 I modified the code slightly to allow me to test the different days and ensure it opened up the browser correctly.
We can run the pygame by launching a terminal and entering the command
python3 py_game_advent.py
This will open the application with the default interface of all doors closed.
Clicking the reveal with the correctly set days opens the correct number of web pages to the desired links.
This is a quick fun project which hopefully shares some new FPGA development resources which you may not have been previously familiar with.
Comments
Please log in or sign up to comment.