Introduction to FPGA Part 3 - Getting Started with Verilog | Digi-Key Electronics

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
now that we have the fpga  toolchain installed thanks to   opio we can start creating our  own digital designs using verilog   in this episode we'll see how to make basic  combinational logic circuits and how they   actually get implemented in the lookup  tables that are on the fpga let's dive in for most of this series we'll be working with the  pmod connector that's at the end of the ice stick   this just breaks out power ground and  some input output pins on either side   this header format was made popular by digilint  for use on their fpga dev boards and you can find   it on other boards too the idea is that you can  plug in common breakout boards to add features   like buttons leds sensors and networking here is  the pin out of that connector on the ice stick   pins 6 and 12 are 3.3 volts 5 and 11 are ground  and the rest are i o pins directly connected to   the fpga we'll start off by connecting some  buttons to pins 1 through 4 on the right side   note that these map to physical pins 78  79 80 and 81 on the fpga we'll only need   three buttons for this video but i like to  connect four just because here are the connections   note that we do not need to add external pull-up  resistors on the buttons we can enable internal   pull-up resistors on each of the pins in  the fpga and i'll show you how to do that   this is the first circuit we're going to make it's  a very basic and gate well it's an and gate with   two not gates on each of the inputs that's because  when we press one of the buttons the line will go   from high to low or from one to zero we want  one of the leds to light up only when we press   both buttons together another way to represent  the circuit is by using a truth table here you   can see that when both inputs are 0 the output is  1 which means the led should turn on otherwise the   led should remain off as i mentioned in a previous  episode i'm not going to go into the theory behind   digital logic design and boolean math if you are  familiar with boolean algebra you'll probably know   that we can use de morgan's law to simplify this  equation to become the inverse of the output of p   mod 0 or p mod 1 but we don't actually need to do  that the important thing here is the truth table   and that our verilog code can easily be understood  the first thing we'll want to do is create a   folder to hold all of our files our verilog file  and the physical constraints file i'm going to go   into documents appio wherever we created the  istick folder from last time when we created   that example you should see the example leds in  here and then i'm going to create a new folder   and i'm going to call it and gate i'm going to  start off by creating my pin constraint folder   so i'm going to create a new blank text document  i'm going to call it and gate just the name of my   project again dot pcf and if your operating system  asks just say yes it's fine to change the suffix   note that the next pnr tool will look for the  first available.pcf file in a particular folder   so from what i've seen you probably don't want to  have more than one file as it looks like the first   one gets used i could be wrong on that but that  just seems to be my experience i'm gonna go ahead   and open this up with notepad plus plus the dot  pcf file is different from verilog so the syntax   is not verilog at all comments are the pound  signed or hashtag and i'm going to define my leds   so that line is a comment and i'm going to  call set underscore i o and i'm going to tab   out a few times you don't need to tab as long  as there's at least one white space it seems   to be red just fine but you'll notice in verilog  things like to be tabled out or in tabular form   separated by tabs to create nice columns which  makes things easy to read so i'm going to do led 0   and its pin 99 is that led so remember that  physical pin 99 on the fpga is connected to led 0   or in our case d1 on our istick then i'm going to  define the pmod i o pins and these are connected   to my buttons i'm going to call set i o again tab  out and this is where we can define the pull up   so we do dash pull up for a parameter and just say  yes and that enables the pull-up resistor for this   particular pin i'm going to call this pin pmod  0 and that's connected to physical pin 78 let's   do the same thing we'll call pull up yes p mod 1  and this is physical pin 79 so save that file save   i already saved it and now we're going to create  our verilog so new let's create a new document i'm   going to rename this the same thing as the project  call it an and gate assuming i can spell today   and dot v for verilog yes we can change it  i'm going to open that up in notepad plus plus   again now we're going to create actual verilog  the c style comments work very well here like   this works well for line or inline comments  as well as the slash slash comments i'm going   to define my module here and give it a little  comment that says when both buttons are pressed   let's turn on the led a module is a keyword in  verilog that says i'm going to create a block   of functional code and remember that this is  not procedural code necessarily it doesn't run   one line at a time this is just a block  of functionality that gets implemented   as hardware when we run synthesis i'm going  to name the module something here it doesn't   have to match the file name but i'm going to  match it anyway then we define our interface   the inputs and the outputs that are part of this  module you can put comments in these parentheses   that's fine and you'll often find that you  might have a lot of inputs and outputs for   a particular module so it can help to keep them  nicely organized one way to do that is to do the   tabbing instead of spacing like we saw with  the pcf file to keep columns nice and orderly   as we get to more definitions of inputs and  outputs you'll see that where you might get   buses and vectors and registers and you can have  them on different columns so it becomes readily   apparent for whoever is reading your code what a  particular input or what a particular output is   supposed to be we're going to name our inputs pmod  0 and pmod1 these should line up with the names   that we created in our pcf file you'll notice that  these inputs and outputs are separated by commas   in fact these could all be on one line it's  very similar to c in that way you'll see a   lot of people's code where they are all on one  line next to the module name as you can see i'm   separating the inputs and outputs by commas and  in fact you might have them on one line and in a   lot of cases you'll see them on one line next to  the module name and this is very similar to c in   that fashion where the white space or indentation  doesn't really matter here however i like to keep   them on separate lines because it's easier to read  for yourself maybe later in the future when you're   coming back and reading your old code to easily  see what the inputs and outputs are and they're   essentially self-documenting here but i like  to separate them with some comments once again   we're going to put the output led name just like  we did in the pcf file and because that's it i'm   not going to have a comma after that label and i'm  going to close this module out or the inputs and   outputs of this module this interface rather with  a parentheses and a semicolon however that doesn't   mean the module is fully defined we actually  define the module underneath it and we say that   it's done with this n module you can kind of view  this as curly braces in c where this is an open   curly brace under here and this is the definition  of the module before the close curly brace or in   this case where it says end module that particular  keyword this is going to be a very simple what   we call a continuous assignment in verilog or hdl  this is not code that's run in the sense that it's   executing on a processor instead we're defining  hardware we're saying basically create an and gate   that ands the lines p mod 0 and p mod 1 together  after they've been knotted and connect that   to our output line or in this case an output  pin as it's defined up here and in the pcf file   because the buttons are active low we need to  use these not symbols when we push button zero   and push button one those two pins those lines  get anded together and the output goes to led   zero and it's continuous meaning there's no clocks  there's no execution of code you can think of it   essentially like hardware like we're wiring  something up on a breadboard let's save this   file and i'm gonna bring up my console i'm gonna  make it so that we can read it here and i'm gonna   go into my opio folder and i'm gonna go into i  stick and that's where we created our project   so i'm going to go into the and gate project  and the very first time before i try to build it   i want to run opio init to find the board that is  ice stick you can see that it creates that dot ini   file for us that just says hey appio we're using  the istick for our target board and then i want to   call opio build hopefully everything works don't  worry about the no clocks we're gonna be looking   into clocks in a later episode but ignoring that  everything built so then we say opio upload and   as you can see here i did not connect my  board let me connect it make sure you have   no other ftdi chips connected that includes things  like an analog discovery 2 board with it connected   let's say appio upload again and when it's done  let's test it to see if it works if i press either   button nothing happens it's only when i press both  buttons together that the led lights up that tells   me my design worked let's take a moment to talk  about what's actually happening in the fpga if you   look at the ice 40 data sheet you can find a block  diagram that shows what's in a single logic cell   a cell has two main parts a lookup table or  lut and a d flip flop we'll examine the d   flip flop later so let's focus on that lookup  table notice that it has four inputs labeled i0   through i3 here i've laid out what the entire  truth table would look like for our simple   and gate example we'll assume that p mod 0 and  p mod 1 were mapped to i 0 and i 1 for this   particular lookup table whenever i 0 and i 1 are  0 the output should be 1. it really doesn't matter   what i 2 and i 3 are as they're not used here  is a representation of our 4-input lookup table   despite what you might initially think a lookup  table is not a collection of logic gates instead   it's a simple chunk of memory that has 16 entries  and each entry contains one bit during boot up   the fpga reads the configuration data from the  external flash memory where it finds information   about how to program the random access memory or  ram in this particular lookup table the output   section of the truth table is copied to the lut's  memory the four input lines are then used to index   into the memory as the value of the input contains  the address of which memory element should be read   this is similar to using a 16x1 multiplexer to  select the output from the various memory elements   the output of the lookup table is a single bit a  0 or a 1. in reality converting the combinational   logic portion of our code into lookup table  values during synthesis is where a lot of the   magic happens let's take a look at a slightly more  complex example and introduce vectors a vector in   verilog is just a way of grouping inputs outputs  and other named containers together it's similar   to how you might use arrays in other programming  languages like c or python rather than assign   a name to each input and output we're going to  group them together a single named net like what   we were using in the previous example is known as  a scalar here is the truth table for what we want   to accomplish notice that we now have multiple  outputs we can write the boolean equations as   follows we want leds 0 and 1 to turn on whenever  the pmod 0 button is pressed and we want all three   leds to turn on whenever pmod 0 and 1 are pressed  together let's implement this in verilog code   let's start with the same code that we had last  time we'll go to the dot pcf file and let's modify   it the first thing we're going to do to enable  these vectors at least for our inputs and outputs   is define them with these brackets it's much like  you would see for an array in say c or python   i'll continue doing this for each of the  leds that i want to control mapping them to   a physical pin so leds 0 through 4 are 95 through  99 just notice that they're kind of in reverse   order because that's how the board is laid out  we're going to keep the buttons but we're going   to change them to vector form by using the bracket  notation to index 0 and 1. save the dot pcf file   and let's go to our verilog notice here they're  not really buttons one and two anymore although   that's kind of how they're wired i'll make a  note about what i expect the functionality to be   so try that again the first button lights  up two leds and if we push the two buttons   together buttons zero and one it lights up the  third along with those original two that is   intended behavior this is where we start getting  into columns for our inputs and outputs when we're   defining our interface you can see that this is an  input that i'm defining i'm going to give it the   vector name which is p mod and how many bits  it is in this case we have two bits which are   zero and one with most significant bit first  colon and the least significant bit i'm going   to do the same for the leds which there will be  three leds you'll notice that we defined five here   and that's for you to use later but i'm only going  to use zero one and two i expect to see a warning   during the build process because three and four  aren't used it's kind of like defining a variable   and not using it and i want to make sure that my  tabs line up i'm using four spaces per tab to make   things a little easier but you'll often find that  two spaces per tab is perfectly acceptable in fact   indentation doesn't matter it's just for you and  others being able to read your code let's start   over with our continuous assignment you can define  something called a wire inside of your module   it's not really a variable although  that's the closest comparison i can make   to something like c it's a net we're attaching  an input to an output or an output to an input   on the gates essentially even though a lot  of things are done through lookup tables   but it's telling the hardware that we want to make  connections inside of this module and a particular   connection is not an input or an output we just  need a named net it helps if you think about it   if you've done any sort of pcb layout and you name  some of your nets or wires it's kind of like that i realize i didn't talk about this assign  keyword this is essentially making a connection   in hardware we want to say that the p  mod in this case button the first button   should be knotted and then connected to this named  wire or net and that is going to always be the   case these curly braces work as a concatenation  function in verilog but we're not using them for   that you can use them to say concatenate two buses  together where we have multiple lines or these   vectors and we can put them together to make one  larger boss but here what we're doing is something   called replication we want to say that this not  pmod 0 wire this net that we've defined as the   inverse of our first button line and we're going  to copy that assignment twice hence the number   two here and assign it to leds one and zero we're  going to assign those two which is now replication   of not p mod zero this wire to the output pins  another way to think about this is that we have   one output here and we connect another wire to it  making a t junction and it splits out to our two   pins led 0 and led1 that's replication in verilog  this should look similar to our first example   where we are ending two of the lines together  in this case not p mod 0 which is a named net   which is the same as just copying this and  pasting it down here because it's just a   direct connection with no logic but it does carry  this logical not gate in front of it so that wire   the output of that not gate is connected here and  then ended with not p pmod1 so this is where we   can push both buttons and that third led lights up  let's save this because this is the same project   i can just call appiobuild again without needing  to call appioinit you should expect some warnings   here about led 3 and led 4 not being used  since we did not use them in the design   assuming everything builds and synthesizes  correctly let's call appio upload if i press the first button leds 0  and 1 turn on it's only when i press   both buttons together that the third  led illuminates with the other two   i found this reference card from a professor at  imperial college london to be very helpful i don't   know if it lists everything for the 2005 version  of verilog but it's definitely a good start   here's your challenge i want you to implement a  full adder in verilog and run it on your device   the full adder is a very important circuit  that performs the basic operation of addition   between two bits it plays a crucial role in  the arithmetic logic unit or alu that makes   up the computational part of a central processing  unit or cpu this wikipedia article gives you the   truth table as well as the logic diagram for  the full adder i recommend looking at these to   figure out how to implement it in verilog note  that you might need to invert the inputs if you   want to have a button press mean logic high  here is the full adder working on my istick   when i press any one of the buttons the output  is one if i press any two of the buttons the   carryout led lights up if i press all three  buttons the sum and carry out leds both light up   so far we've only looked at continuous assignments  where changes on the outputs are more or less   immediately responsive to changes on the  inputs and there may or may not be some   combinational logic in the middle next time  we'll look at introducing clocks and flip   flops where we can store and pass data around  from one clock cycle to the next happy hacking you
Info
Channel: DigiKey
Views: 61,091
Rating: undefined out of 5
Keywords: fpga, lattice, ice40, yosys, apio, project icestorm, electronics, digital logic, verilog, hdl, continuous assignment
Id: A4VfBoP4Hdk
Channel Id: undefined
Length: 20min 43sec (1243 seconds)
Published: Mon Nov 22 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.