3. What makes the project Virtual FPGA Lab special?
5. FPGA peripheral macro instantiations
- 5.1 Board Select
- 5.2 Board Initailisation
- 5.3 LED Module
- 5.4 Seven segment displays
- 5.5 LCD Module
- 5.6 VGA display
- 5.7 Push buttons
- 5.8 Slideswitches
8. How to add own FPGA boards and peripherals
9. Steps to run in an actual FPGA
Field-Programmable Gate Array(FPGA) is a hardware circuit that a user can program to carry out logical operations. FPGAs are beneficial for prototyping application-specific integrated circuits (ASICs) or processors. The advantage of FPGA being energy-efficient, flexible to reprogram, support parallelism, decreased latency made them widely used in many applications. But the flexibility of FPGAs comes at the price of the difficulty of reprogramming the circuit. FPGA’s are a bit costly and difficult to learn for beginners. Also, students don’t have access to physical FPGA Lab classes in their curriculum amidst this pandemic situation. So there is a massive demand in having an alternative option of having an online simulator for FPGA curriculum development.This project Virtual FPGA Lab aims to solve the problem by taking advantage of the VIZ Visualization feature in the Makerchip platform and provide visualizations of basic peripherals of an FPGA, thereby mimicking the physical lab experience.
Here is the link to the blog post: Link
Makerchip is a free web-based IDE as well as available as makerchip-app, a virtual desktop application for developing high-quality integrated circuits. You can code, compile, simulate, and debug Verilog designs, all from your browser. Your code, block diagrams, and waveforms are tightly integrated. Makerchip supports the emerging Transaction-Level Verilog standard. Transaction-Level Verilog, or TL-Verilog, represents a huge step forward, by eliminating the need for the legacy language features of Verilog and by introducing simpler syntax. At the same time, TL-Verilog adds powerful constructs for pipelines and transactions. More details about TL-Verilog: https://www.redwoodeda.com/tl-verilog
- Easy Learning📖: Understanding the basics of FPGA programming without having an actual board
- Time travel😜: Move back and forth between cycles so that we can visualize what's happening in each cycle.
- Faster🚀: No need to wait for Synthesis, Implementation and Bitstream Generation for simple designs.
- Abstraction💪: TL-V requires lesser code than standard HDL languages, making faster development, fewer bugs, easier maintenance, and better quality silicon. It supports System Verilog as well.
- Synthesizable😊: Code in Virtual Lab works on real FPGAs!!!. We will cover this in the last section.
- Open Source🥰: Licensed under MIT.
- Zedboard Zynq-7000 ARM/FPGA SoC Development Board (Product Link)
- EDGE Artix 7 FPGA Development Board (Product Link)
- Basys 3 Artix-7 FPGA Trainer Board (Product Link)
- Icebreaker FPGA (Product Link)
- Nexys A7 (Product Link)
Currently we demonstrate using only these boards and we plan to add more boards in the future. You can very easily to add your own FPGA boards. Contributions are welcome.
m4_define(M4_BOARD, 1) // This should always be declared for below macros to work
// M4_BOARD numbering
// 1 - Zedboard
// 2 - Artix-7
// 3 - Basys3
// 4 - Icebreaker
// 5 - Nexys
m4+fpga_init()
m4+fpga_led(*led)
// Arguments:
// *led - led signal
m4+fpga_sseg(*digit, *sseg, *dp)
// Arguments:
// *digit - common anode signal
// *sseg - seven segments
// *dp - decimal point
m4+fpga_lcd(*data, *lcd_e, *lcd_rs)
// Arguments:
// *data - 8-bit data/command line
// *lcd_e - lcd enable signal
// *lcd_rs - lcd reset signal, 0 for command and 1 for data
m4+fpga_vga(*vga_hsync, *vga_vsync, *vga_r, *vga_g, *vga_b, /top|vga_pipe$sx, /top|vga_pipe$sy)
// Arguments:
// *vga_hsync - horizontal sync
// *vga_vsync - vertical sync
// *vga_r - red signal
// *vga_g - green signal
// *vga_b - blue signal
// $sx - horizontal count
// $sy - vertical count
m4+fpga_push(*pb)
// Arguments:
// *pb - push button signal
m4+fpga_led(*sw)
// Arguments:
// *sw - switch signal
Visual Debug is a JavaScript canvas where we used fabric.js, which is a powerful and simple Javascript HTML5 canvas library framework. It provides us to use interactive object models on top of canvas element.
Let us first visualize the output of simple digital logic gates. From the GIF below, we can see that the left portion is the coding part where you can see the logic of the gates and right portion is the Visual Debug(VIZ) part where you can see the visualization of each logic gates. We can move back and forth between cycles and see in the top right which cycle currently is. Also, look at the waveform of the logic from the below image.
This program prints the following in the LCD 16x2 display
Line 1: FPGAs are fun!!!
Line 2: --
And then left shift line1 and line2 once completed
NOTE: This visualization supports only 8 bit data/command mode
- 8'h38 - Function Set: 8-bit, 2 Line, 5x7 Dots
- 8'h30 - Function Set: 8-bit, 1 Line, 5x7 Dots
- 8'h0C - Display on Cursor off
- 8'h06 - Entry Mode: Increment, entire shift off
- 8'h04 - Entry Mode: Decrement, entire shift off
- 8'h01 - Clear display
- 8'h02 - Return home
- 8'h80 - force cursor to begin at first line
- 8'hC0 - force cursor to begin at second line
- 8'h18 - Shift entire display to the left
- 8'h1C - Shift entire display to the right
- 8'h10 - Shift cursor left
- 8'h14 - Shift cursor right
// Macro definition for adding fpga board
\TLV fpga_init()
|fpga_init_macro
@0
\viz_alpha
initEach() { // initialize this function on start
let fpga_img_url = "<PASTE YOUR FPGA BOARD IMAGE URL>"
let fpga_img = new fabric.Image.fromURL(
fpga_img_url,
function (img) {
global.canvas.add(img) // add image to canvas
global.canvas.sendToBack(img); // z-indexing always on bottom
},
{
// tweak the values here according to your board
originX: "center",
originY: "center",
left: 0,
top: 0,
scaleX: 0.3,
scaleY: 0.3,
}
)
}
\TLV fpga_led($_leds)
|led_pipe_macro
@0
$led[\$size($_leds)-1:0] = $_leds; // copying SystemVerilog/TL-Verilog to TL-Verilog signal
/led[7:0] // Hierarchy. The width is the number of LEDs in the board
\viz_alpha
initEach() { // initialize this function on start
// Fabric js object
let led = new fabric.Rect({
// modify these values according to your board
top: 233,
left: 151 - 32 * (this.getIndex() + 1),
width: 6,
height: 11,
fill: "red",
opacity: 0
})
// The objects that we return can be used in renderEach function
return{objects : {led}};
},
renderEach() { // initialize this function on every cycle count
// LED ON/OFF logic
var mod = ((('/top|_pipe$_leds'.asInt(-1) >> this.getScope("led").index) & 1) == 1);
// The object "led" that was returned in initEach is used below using this.getInitObjects() method
this.getInitObject().led.set(mod ? {opacity: 1} : {opacity: 0});
}
Detailed step-by-step instructions are provided in this link. Credit goes to Mayank Kabra for helping me build this part.
LED Demo: Link
- To support more FPGA boards and peripherals.
- The automated shell script that converts TL-V code to run in an actual FPGA currently supports only Xilinx boards with Vivado software. So to provide scripts that target other vendors as well using open source tools.
- Steve Hoover, Founder, Redwood EDA
- Akos Hadnagy, Advisor
- Dylan McNamee, Advisor
- Bala Dhinesh, Contributing as a participant in Google Summer of Code 2021, under FOSSi Foundation
- Shivani Shah, Student at the International Institute of Information Technology, Bangalore
- Mayank Kabra, Student at the International Institute of Information Technology, Bangalore
Funding for this work is provided by the Open Source Silicon Foundation
Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are greatly appreciated.
Distributed under the MIT License. See LICENSE
for more information.
Though the algorithms developed has been tested against a large number of custom inputs, there are situations where it can fail. If you come across any such problem, please feel free to raise an issue here and we will try to address the issue as soon as possible.