{"id":238,"date":"2015-01-22T11:20:00","date_gmt":"2015-01-22T19:20:00","guid":{"rendered":"http:\/\/www.beyond-circuits.com\/wordpress\/?page_id=238"},"modified":"2019-03-12T15:50:55","modified_gmt":"2019-03-12T23:50:55","slug":"tutorial1","status":"publish","type":"page","link":"https:\/\/www.beyond-circuits.com\/wordpress\/tutorial\/tutorial1\/","title":{"rendered":"Tutorial 1: The Simplest FPGA in the World"},"content":{"rendered":"<h2>Verilog<\/h2>\n<p>First, we will make the simplest possible FPGA. It will be a wire. Create a new project in Vivado called <em>tutorial1<\/em> and add a Verilog file called <em>top.v<\/em>. You can use the wizard to add ports if you like when Vivado creates the file, or you can add them yourself using the text editor. The design should have a single input called <em>switch<\/em> and a single output called <em>led<\/em>.<\/p>\n<p>Edit the file so it looks like this<\/p>\n<pre><code>module top (\r\n  input switch,\r\n  output led\r\n);\r\n\r\n  assign led = switch;\r\nendmodule<\/code><\/pre>\n<p>This declares a Verilog module called <em>top<\/em>. A module is just a container for part or all of your design. We will learn later that modules can instantiate other modules to create a hierarchical design. But, given that this is the simplest FPGA in the world, that is not necessary.<\/p>\n<p>We declare the module to have a single input called <em>switch<\/em> and a single output called <em>led<\/em>. These will correspond to input and output pins on the actual FPGA. The only thing else in the design is the assignment statement. This statement just means that the output <em>led<\/em> is to change whenever the input <em>switch<\/em> changes. In effect, it simply creates a wire and connects <em>led<\/em> to <em>switch<\/em>.<\/p>\n<h2>Constraints<\/h2>\n<p>The compiler cannot turn your Verilog code into a working FPGA however because you have not given\u00a0it enough information. Sure, it knows there is an input pin called switch and an output pin called led, but which pins do you want to use? There are hundreds to choose from. We need to tell it which pins to use. We call this information <em>constraints<\/em> because it constrains the compiler\u2013 it can&#8217;t just pick one, but instead must use the one you constrain it to.<\/p>\n<p>Create an XDC constraints source file and call it <em>top.xdc<\/em>. You should download a copy of the ZedBoard schematics to determine the constraints. But even so, I have included the important information here.<\/p>\n<p><a href=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/01\/ZedBoardPins.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-241\" src=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/01\/ZedBoardPins-300x181.png\" alt=\"ZedBoardPins\" width=\"300\" height=\"181\" srcset=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/01\/ZedBoardPins-300x181.png 300w, https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/01\/ZedBoardPins-1024x617.png 1024w, https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/01\/ZedBoardPins-498x300.png 498w, https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/01\/ZedBoardPins.png 1604w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>If you look at the schematic, you&#8217;ll see that there are eight switches and eight LEDs. Switch 0 comes into the FPGA as SW0 on the schematic and it connects to pin F22 on the FPGA. Notice also that the voltage on the IO bank where the input belongs (bank 35) is VADJ. This voltage is adjustable on the board between 2.5 and 1.8 volts. Assuming your jumper is set to 2.5V, that means this is a 2.5V input.<\/p>\n<p>If you look at\u00a0the upper left of the schematic you will see a signal called LD0 which is connected to LED 0. This is on a 3.3V bank connected to pin T22. Edit your top.xdc file so that it contains the following constraints. These constraints tell the compiler where we want to connect our inputs and outputs and what logic levels to use for those pins.<\/p>\n<pre><code>set_property IOSTANDARD LVCMOS33 [get_ports led]\r\nset_property IOSTANDARD LVCMOS25 [get_ports switch]\r\nset_property PACKAGE_PIN T22 [get_ports led]\r\nset_property PACKAGE_PIN F22 [get_ports switch]<\/code><\/pre>\n<p>You should now be able to compile the design. Generate a bit file and program the board. If the blue LED comes on after programming everything should have worked. Slide Switch 0 on and off. The LED should turn on and off as well. Congratulations: you have just created a very expensive and complicated wire!<\/p>\n<h2>More Wires<\/h2>\n<p>So now let&#8217;s modify our design to use a bus of eight wires for the switches and LEDs. since we have eight of those on our board.<\/p>\n<p>Change the Verilog file to<\/p>\n<pre><code>module top (\r\n  input [7:0] switch,\r\n  output [7:0] led\r\n);\r\n\r\n  assign led = switch;\r\nendmodule<\/code><\/pre>\n<p>This will change the inputs and outputs to eight-bit busses. You don&#8217;t need to modify the assignment statement. The width of the values just changes from one bit to eight bits. However, the constraints do change a fair amount.<\/p>\n<p>Before, the name of the input pin was <em>switch<\/em>, and the output pin was called\u00a0<em>led<\/em>. Now those values refer to eight pins. We need to apply the <em>PACKAGE_PIN<\/em> to individual pins. Our constraint files are actually a little program written in the <em>TCL<\/em> programming language. <em>set_property<\/em> is a function defined in TCL, and the values passed to it are arguments. <em>get_ports<\/em> is another function which searches the design database for ports. The square brackets tell TCL to call the function inside them and use the value of the result in place of the brackets. So we can still use the same <em>IO_STANDARD<\/em> commands. The <em>[get_ports led]<\/em> call will just return a list of eight ports that match the name <em>led<\/em>. The <em>set_property<\/em> command can apply the same <em>IOSTANDARD<\/em> attribute to all eight. For the <em>PACKAGE_PIN<\/em> attribute, we need to be more selective. The actual port name for the LSB of the <em>led<\/em>\u00a0is <em>led[0]<\/em>. But we can&#8217;t just use this for the name since TCL will try to call a function <em>0<\/em> rather than using the literal characters. We quote the special characters in curly braces. So we will use <em>[get_ports {led[0]}]<\/em>.<\/p>\n<p>Looking at the schematic for all the pin names, we get the following constraints:<\/p>\n<pre><code>set_property IOSTANDARD LVCMOS33 [get_ports led]\r\nset_property IOSTANDARD LVCMOS25 [get_ports switch]\r\nset_property PACKAGE_PIN T22 [get_ports {led[0]}]\r\nset_property PACKAGE_PIN T21 [get_ports {led[1]}]\r\nset_property PACKAGE_PIN U22 [get_ports {led[2]}]\r\nset_property PACKAGE_PIN U21 [get_ports {led[3]}]\r\nset_property PACKAGE_PIN V22 [get_ports {led[4]}]\r\nset_property PACKAGE_PIN W22 [get_ports {led[5]}]\r\nset_property PACKAGE_PIN U19 [get_ports {led[6]}]\r\nset_property PACKAGE_PIN U14 [get_ports {led[7]}]\r\nset_property PACKAGE_PIN F22 [get_ports {switch[0]}]\r\nset_property PACKAGE_PIN G22 [get_ports {switch[1]}]\r\nset_property PACKAGE_PIN H22 [get_ports {switch[2]}]\r\nset_property PACKAGE_PIN F21 [get_ports {switch[3]}]\r\nset_property PACKAGE_PIN H19 [get_ports {switch[4]}]\r\nset_property PACKAGE_PIN H18 [get_ports {switch[5]}]\r\nset_property PACKAGE_PIN H17 [get_ports {switch[6]}]\r\nset_property PACKAGE_PIN M15 [get_ports {switch[7]}]<\/code><\/pre>\n<p>Make these changes, generate a new bit file, and program the board and now all the switches should control the corresponding LED.<\/p>\n<h2>Adding a Clock<\/h2>\n<p>One final thing to do is to add a clock. Clocks are important in FPGA designs because they allow the FPGA to have states that vary over time. Make some more changes to your Verilog code. One thing we will be doing is changing the output declaration a little. Notice the <b>reg<\/b> keyword. In Verilog 2005 there are basically two types of nets: a\u00a0<b>wire<\/b> and a <b>reg<\/b>. Wires are assigned using the assign statement or as outputs of module instances. Reg nets are assigned from inside of procedural blocks. What are procedural blocks, you ask? They are basically blocks of code which behave in a sequential manner. They have some event that\u00a0activates them and causes them to\u00a0run. Code within the block runs from start to finish in a sequential manner, just like software.<\/p>\n<p>In the example above, the assign statement said that the output <em>led<\/em> was equal to the input <em>switch<\/em>. This isn&#8217;t something that is equal only once, and then the system forgets about it. <em>switch<\/em> and\u00a0<em>led<\/em> are\u00a0always equal. If the right-hand side changes, the left-hand side is updated along with it. This is called a <em>continuous<\/em> assignment, so named because it happens continuously. As such, it never makes sense to have multiple continuous assignments to a wire. You&#8217;ll only ever have one.<\/p>\n<p>We can rewrite the previous code using a sequential assignment like this:<\/p>\n<pre><code>module top (\r\n  input [7:0] switch,\r\n  output reg [7:0] led\r\n);\r\n\r\n  always @(switch)\r\n    begin\r\n      led = switch;\r\n    end\r\nendmodule<\/code><\/pre>\n<p>This tells Verilog to run the code between the <b>begin<\/b>\/<b>end<\/b> pair every time <em>switch<\/em> changes. This has the same effect as the continuous assignment. We can also clean up our code a little by removing the <b>begin<\/b>\/<b>end<\/b> pair since there is only one statement. The part within the<code>@()<\/code> section is called the <em>sensitivity list<\/em>. This is a list of variables separated by the keyword <b>or<\/b>. If any of the variables changes, the always block is reevaluated. We can just use the shorthand notation <code>@(*)<\/code> as well. This lets the compiler decide which variables have an effect on the outcome and use those instead. So we now have our slightly optimized code, as shown below:<\/p>\n<pre><code>module top (\r\n  input [7:0] switch,\r\n  output reg [7:0] led\r\n);\r\n\r\n  always @(*)\r\n    led = switch;\r\nendmodule<\/code><\/pre>\n<p>We can now add a clock to our design. To do that, we add another input pin called <em>clk<\/em> and we use that in the sensitivity list for the always block. However, we don&#8217;t want any change to <em>clk<\/em>\u00a0to sensitize the always block, just the rising edge. So we also use the <b>posedge<\/b> keyword. Like this:<\/p>\n<pre><code>module top (\r\n  input clk,\r\n  input [7:0] switch,\r\n  output reg [7:0] led\r\n);\r\n\r\n  always @(posedge clk)\r\n    led = switch;\r\nendmodule<\/code><\/pre>\n<p>Now all that is left is to tell the compiler which pin the clock comes in on, its logic level, and finally\u00a0the fact that it is a clock and it runs at a frequency of 100MHz. So here are the additional lines that we add to the constraints file:<\/p>\n<pre><code>set_property IOSTANDARD LVCMOS33 [get_ports clk]\r\nset_property PACKAGE_PIN Y9 [get_ports clk]\r\ncreate_clock -period 10 [get_ports clk]<\/code><\/pre>\n<p>If you compile this, you should see the exact same behavior as before.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Verilog First, we will make the simplest possible FPGA. It will be a wire. Create a new project in Vivado called tutorial1 and add a Verilog file called top.v. You can use the wizard to add ports if you like &hellip; <a href=\"https:\/\/www.beyond-circuits.com\/wordpress\/tutorial\/tutorial1\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"parent":226,"menu_order":0,"comment_status":"open","ping_status":"open","template":"","meta":{"footnotes":""},"class_list":["post-238","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/pages\/238","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/comments?post=238"}],"version-history":[{"count":9,"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/pages\/238\/revisions"}],"predecessor-version":[{"id":1242,"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/pages\/238\/revisions\/1242"}],"up":[{"embeddable":true,"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/pages\/226"}],"wp:attachment":[{"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/media?parent=238"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}