FPGA's come in many different sizes, both physically and in the size of the 'program' they can store. I write program like that because well, they are not really program's. In fact the only similair factor is that they can be written in specific languages, but more on that later. The particular FPGA I got is a Cyclone IV from Altera, specifically the EP4CE22F17C6. This chip has 154 IO Pins, 22320 Logic Elements, 608256 Memory Bits and 4 Phase Locked Loops (PLL's), as well as other stats. These are stats that I myself don't really understand; what I do know is that it is mostly the amount of logic elements that determines the amount of hardware you can fit on an FPGA. However for our purposes we should be no where near that amount! At least for the time being... :D
So what's on the DE0 Nano Board? Well, apart from all of the ICs required to facilitate the operation of the FPGA, there is 32MB of SDRAM, a Digital Accelerometer, a 2Kb EEPROM, 8 LEDs, 2 Push Buttons, a 4 Way DIP Switch and an Analog to Digital Converter. The LEDs and Switches will be very useful for early projects when learning about Verilog and how to program FPGA's. Things like the Accelerometer and RAM will be useful later on in more complicated projects, so exciting things to look forward to in the future! This board is also incredibly small, around the size of a debit card in fact! This makes it extremely portable and its rather amazing that they fit this much stuff into such a small form factor! So why did I choose this development board specifically? Well FPGA's are something I have been wanting to play with for a while, however they can be extremely expensive and thus can be quite a money sink if you don't end up enjoying using them. This is currently one of the best development boards on the market at a cost of £66 on Farnell, which is way better than the £100+ that some other boards cost. Coupled with the additional hardware on the board and tutorial's provided, this board is a really good deal for someone wanting to test the water with FPGAs! There are other boards out there that provide more peripherals like display's that make the FPGA easier to with external item's. But its fun and educational to hook up hardware yourself, so sometimes a slightly more bare bones device is all you need! It also helps that I'm a real hardware nerd, and this board looks really awesome!
Anyway, moving on from that. Lets get down to business and actually do something with this board! That was the point I ran into problem's nearly a month ago. The tutorial provided by Terasic (the creators of the DE0 Nano) was great for walking me through how to create, compile and upload a project in quartus (Altera, the maker of the FPGA and programming software). However, this is little use when you don't know a Hardware Description Language or HDL in the first place! Once I had completed the Terasic Beginners Guide there was little other documentation to help me learn one of the languages required to program an FPGA. Luckily, the internet was there to help me some what!
After a bit of research I decided to learn Verilog HDL, as it has similarities to C in it's syntax and thus should be a bit easier for me to pick up. It is also fairly commonly used in Industry which may come in handy in the future! Unfortunately the task of learning Verilog is a lot harder than other languages, mostly because there is little documentation out there at all that is very useful if not put in context. There are plenty of University Course Guides on the Internet, but they get way too complicated way too quickly, which just makes things confusing. However after some hard searching I found a few websites which helped me to get a foot through the door (listed at the bottom of this post), and from there it's just a matter of learning bits of syntax bit by bit. The task of learning a language is not learning all of the words or syntax that the language uses, you can find that information easily online at any point and your understanding will increase as you do projects. No, learning a language means learning it's structure and understanding how all the pieces fit together. Once you start to do this things become a lot easier!
So, lets program something in Verilog! Mostly for my own benefit this is going to be very simple, however more complicated projects will come in the future! We are going to do a very simple Multiplexer system, where we can drive four outputs with only two inputs! In this case our inputs will be the push buttons on the DE0 Nano Board and the outputs will be four of the eight LED's also on the board. Lets get started!
Stage One - Creating a Project and Setting up the Device Requirements
I am going to try and keep this tutorial somewhat generalized so that anyone can use it. One problem with some of the tutorials online was that they were very specific to hardware, so I will try to avoid that where possible. I will mention where things may differ for your hardware, in these places you should refer to your hardware manual for the information you require.
We need to start by creating a project in Quartus, in this case I am using the latest version of Quartus Prime at the time of this post (15.1). On the home splash screen of the software, you want to click the button that says "New Project Wizard", this will open up a box that guides you through the process of starting a new project. When this box opens, click next. Now you have to choose a working folder on your computer, as well as enter the name of the project in the provided boxes. Do not use a number as the first letter in your project name, so other characters are also limited but all the letters and numbers are available to use so you should have no problems. It would be a good idea to name the working folder as the same name as the project, just for ease of use later on.
You should be met with a blank screen at this point. Firstly you need to create a new Block Diagram file. Click the new file icon in the top left hand corner and then select Block Diagram in the list. A Block Diagram is basically the schematic of the hardware that will be implemented on your FPGA. You should save this file once it is created, making sure you name it exactly the same as your project name. Doing this means that Quartus will default this file as the top level design entity, which is exactly what we want. This file is essentially where all the different modules we create are connected together, much like the schematic for a circuit board. We will be doing more in this file later, but for now just leave it alone... :D
Now that this file is created we need to make the Verilog File that will house the code for our Multiplexer Module. Again go to the top left hand corner and click the new file icon, however this time in the file type list select Verilog HDL File. A text editor will open up, this is where you type your Verilog Code that will make up the Multiplexer Module. You may have noticed I keep saying "Module," well before we look at the Verilog Code for the multiplexer we need to talk a tiny bit about the structure of Verilog.
Verilog is entirely made up of things called Modules, they are like descriptions of specific bits or sections of hardware. For example you might have a module that describes a shift register for use in a UART. All Verilog code needs to be contained within a module, these modules can then be instantiated elsewhere in the code with specific input values, much like functions in C. The idea is that you write the individual modules, and then instantiate versions of them in the correct connected layout to make your overall hardware design. Whether that be a completely custom chip or your interpretation of a specific processor package. I will go more into the ins and outs of Verilog in a later post, but I thought it best we understand how to program our FPGA first before we learn to code in the language.
So lets have a look at out Verilog Code! Here it is:
Line number 5 is creating out initial module. We are not instantiating a module here, but rather creating a new one, much like we would create a new function in C. The variables in the brackets are the names of all of the ports that will make up this module. At this stage we are not defining whether they are inputs or outputs, we are just saying that they exist.
Line number 6 is used to declare which of the ports are inputs, in this case we have three inputs: clk, in_a and in_b. Much like line 6, line 11 is devoted to declaring which ports are outputs.
Line number 14 is used to declare the types of ports that we are using, this is where it gets a bit more complicated. The syntax that says "reg" is short for "register." This means any port that acts like a register, in other words it stores the value that was last inputted too it. You may have noticed that I have not declared the type of every port in the module here! Any port that has not got a declared type defaults to type wire. The wire type does what it says on the tin, it acts like a simple wire that needs to be driven to be a certain value. In other words it does not retain it's last inputted value like a register, it must be constantly driven at that value.
Line number 17 is where the meat of the code starts. This is the main behavioral section of the code, or in other words the part that describes how the module will react to certain inputs. We must always start by telling the system at what point it should check the value of the inputs, in this case we are checking the inputs and changing the outputs accordingly on the rising edge of the clock. This is why we are using the phrase "always @ (posedge clk) begin." What follows is much like what you would see in some simple C code, where we tell the system how it has to react to certain input states. You will notice this strange looking symbol: "<=". For now all you need to know is that this is setting the variable to the value on the right hand side of the symbol.
Finally, whenever we start a specific section of behavioral code, whether that be an if else statement or an always @ statement, we must put in "begin" and "end" to tell the system where this little snippet of code starts and ends. Much like the } in C! So that's out Verilog Code done, what next? Well we need to make a symbol file for this module so that we can but it into out schematic file!
Go to File, Create/Update and click on "Create Symbol Files for Current File," if all foes according to plan this will complete successfully. Now switch to the schematic file and double click the dotted area where you draw the schematic! A boc will come up that looks like this:
Firstly we need to add something called a Phase Locked Loop or PLL. This is essentially a section of hardware that converts an input clock signal to a different frequency. In this case the DE0 Nano has a 50Mhz input clock signal, which we will then convert to 5Mhz. As far as I know we don't technically need to do this, but it is good understanding to gain now as it will be very useful later on! So lets make our PLL!
If the IP Catalog is not open on the right hand side of the screen then click the tools header and select IP Catalog in the drop down menu! Once this is open select Library, Basic Functions, Clocks; PLLs and Resets, PLL, ALTPLL. Then click "Add.." at the bottom of the IP Catalog. A window that looks like this will open up!
Now we need to make our schematic! This is the top level of the design that brings all of the modules we have created together! When we are finished it will look something like this!
To open the pin planner go to assignments on the top bar and select the "pin planner" option. When you are done this screen should look like this!
Finally click this button at the top of the main window!
A few things of note with this guide:
- This tutorial only works with the Altera Quartus Software, which is subsequently only for use with the Altera line of FPGA's. If you have an FPGA from Xilinix or another company then there are plenty of tutorials online on how to use their software, just search "FPGA tutorial Xilinix!"
- If you unplug and plug back in your FPGA the hardware will no longer be on the system. This is because the FPGA stores the hardware information in volatile memory, which is cleared when the power is removed. The DE0 Nano Board has a simple way of permanently storing the setup information. I'll talk about this in a later post!
Sam