{"id":248,"date":"2015-01-24T14:11:47","date_gmt":"2015-01-24T22:11:47","guid":{"rendered":"http:\/\/www.beyond-circuits.com\/wordpress\/?page_id=248"},"modified":"2015-11-10T08:25:36","modified_gmt":"2015-11-10T16:25:36","slug":"tutorial2","status":"publish","type":"page","link":"https:\/\/www.beyond-circuits.com\/wordpress\/tutorial\/tutorial2\/","title":{"rendered":"Tutorial 2: Simulation"},"content":{"rendered":"<p>In the last tutorial, we programmed our device and tested it by physically switching all the switches. That is all the testing you&#8217;re going to need for the simplest FPGA in the world. In reality, things can be somewhat more complicated. It becomes difficult to test your FPGA by manipulating it physically. This is why we use simulation. By simulating your design, you can check to see if it works,\u00a0and then spend very little time debugging it in the lab. In this tutorial we will simulate\u00a0our design. This will be the simplest simulation in the world.<\/p>\n<h1>The Test Bench<\/h1>\n<p>You can&#8217;t just simulate your design in isolation. Your design has input signals and output signals, and you need to control the inputs and verify that the outputs are correct. Ideally you want your test to create the input stimulus and verify the correctness of the output signals. In the real world, we want tests to print out what they are doing as the test runs, print any error messages if any of the tests fail, and print a summary about whether the test passed or failed.<\/p>\n<p>In our example, we will only have one file in our test bench. In the real world you will usually have many files that form the test bench and the tests. In fact, in complicated ASIC designs which require more elaborate testing than FPGAs, it is not uncommon for more effort to be put into the simulation and testing of the ASIC design than in the design itself.<\/p>\n<p>To create the test bench go to the <strong>Project Manager<\/strong> flow and click\u00a0the <em>Add Sources<\/em> button. Check the <em>Add or create simulation sources<\/em> radio button and click <em>Next<\/em>. Then click <em>Create File&#8230;<\/em> and give a file name called <code>bench.v<\/code>\u00a0and click <em>Finish<\/em>. A new dialog will pop up and you should name the module <em>bench<\/em>. Don&#8217;t give it any ports. Then click <em>OK<\/em>.<\/p>\n<h1>\u00a0Test Bench Contents<\/h1>\n<p>Unlike our FPGA, the test bench doesn&#8217;t need any input or output ports. You can think of it as the container for the simulation universe. Everything happens within the test bench. Another thing you need to know about is the simulation timescale. At the very top of the test bench file you will see (or you should type)<\/p>\n<pre><code>`timescale 1ns\/1ns<\/code><\/pre>\n<p>This tells the simulator that, when you give a delay value <em>in this file<\/em>,\u00a0the delay will be in nanoseconds. That is the numerator of the fraction value. The denominator of the fraction value tells the simulator how much time precision this file requires. In general, it is OK to leave it the same as the numerator. Note that the timescale directive, like all preprocessor directives in verilog, starts with a back tick (grave accent) character. Next comes the module declaration.<\/p>\n<pre><code>module bench;<\/code><\/pre>\n<p>Following that we need to declare the signals that we are going to connect to our FPGA that we will be simulating. The output signals from the FPGA need to be connected to <b>wire<\/b> type signals in the test bench. The input signals to the FPGA can come from <b>wire<\/b> or <b>reg<\/b> signals. The first thing to declare is the clock input:<\/p>\n<pre><code>reg clk = 1;<\/code><\/pre>\n<p>And then, we create a 100MHz clock:<\/p>\n<pre><code>always #5 clk = ~clk;<\/code><\/pre>\n<p>Let&#8217;s look at this code in a little more detail. First, <em>clk<\/em> is a reg signal, so we need to assign it in a procedural block. We can create a procedural block using an always statement. We saw in the last tutorial that an always clock had an event specifier which told it when to activate &#8211; like on the positive edge of clock. This always block has no event. It always runs. Once it finishes, it just runs all over again. Every time the block runs, it inverts the clock. What is the magical <code>#5<\/code>? That tells the simulator to advance the clock 5 nanoseconds before performing the assignment. The units are in nanoseconds because of our timescale statement. So the clock starts at one, and then at five\u00a0nanoseconds, it switches back to zero. In five more nanoseconds, it will switch back to one, and the process starts all over again, continuing forever. In effect, this is a 100MHz clock.<\/p>\n<h2>Instantiating the FPGA design<\/h2>\n<p>Now we need to declare a <b>reg<\/b> signal to drive the switch inputs and a <b>wire<\/b> signal sample the <em>led<\/em> outputs.<\/p>\n<pre><code>reg [7:0] switch;\r\nwire [7:0] led;\r\n<\/code><\/pre>\n<p>An important feature of Verilog is that a module can contain <em>instances<\/em> of other modules. You can create hierarchical designs this way. This feature is really useful for reusing design components, or for just creating a sense of order in your designs. In the next line, we instantiate the FPGA top module in our test bench and wire up its inputs and outputs. To instantiate a module, you first mention the name of the module, then you give an instance name\u2013 that is, a name for this particular instance of the module. Often you might instantiate the same module more than once within your module. In these cases, you&#8217;ll need to give them different names. The simulator will refer to signals within nested modules in a similar manner\u00a0to files nested within a directory structure. When doing so, the simulator will use the instance name, since the module name might\u00a0be ambiguous if there are multiple\u00a0instances of the module. An important thing to note is that module names and instance names use different <em>namespaces<\/em>. Because of this, there is never a situation where a name\u00a0could refer to either\u00a0a module or an instance. This means that the module name and the instance name can be the same. In my opinion, exploiting this actually leads to a more easily-understood design.<\/p>\n<p>Anyway, after the instance name we give an open parenthesis and list the module connections. This takes\u00a0the form of a period, followed by the port name within the module, then an open parenthesis and the name of the signal we are connecting up to the port. This is then followed by a close parenthesis, a comma, and finally the subsequent connections. All of these are followed by a close parenthesis and ended with a semicolon. Here is the module connections are supposed to look like:<\/p>\n<pre><code>top top (.clk(clk),.switch(switch),.led(led));<\/code><\/pre>\n<h2>Driving the switches<\/h2>\n<p>We still haven&#8217;t told the simulator how to set the switch inputs during the simulation. What are our options here? Hypothetically, we could count through all 256 possible switch settings. In this case, that&#8217;s not a bad option. But you&#8217;ll often have designs where the sequence of inputs is important. If you were to count, the sequence would\u00a0always be the same no matter how many times you counted. Because of this, you might not be able to spot bugs. Usually, the better approach is to use some type of randomness. This is what we&#8217;ll be doing here. Verilog has a built-in function called <b>$random<\/b> which you can use for this purpose. Here, we will make an always block which sets the switch inputs to a random value on every clock:<\/p>\n<pre><code>always @(posedge clk) switch = $random;<\/code><\/pre>\n<h2>Finishing up<\/h2>\n<p>As it stands, we have a simulation which continues\u00a0forever. That&#8217;s probably longer than we plan for\u00a0our simulation to run. We can add some code that\u00a0causes the simulation to end after a certain amount of\u00a0time. The built-in Verilog task <b>$finish<\/b> will cause the simulation to complete. We could just have an <b>initial<\/b> block that waits for some fixed amount of time and then calls <b>$finish<\/b> like this.<\/p>\n<pre><code>initial #10000 $finish;<\/code><\/pre>\n<p>But that&#8217;s not something I prefer,\u00a0because it will just wait for an amount of time to pass, and then kills the simulation. What if we made\u00a0our clock period longer or shorter? The length of the test wouldn&#8217;t\u00a0adjust to give us the same number of clock cycles. Instead I prefer to use the Verilog <b>repeat<\/b> construct and actually count the clock edges. That way, the simulation will always last the number of clock cycles I specify. In this case, I&#8217;ve chosen to run the simulation for 1000 clock cycles.<\/p>\n<pre><code>initial\r\n  begin\r\n    repeat (1000) @(posedge clk);\r\n    $finish;\r\n  end<\/code><\/pre>\n<p>The <b>repeat<\/b> statement tells the simulator to run the following statement 1000 times. The statement will simply\u00a0wait for the rising edge of <em>clk<\/em>, and then, it will finish the simulation.<\/p>\n<p>After this we just need to end the module with<\/p>\n<pre><code>endmodule<\/code><\/pre>\n<h1>Running the simulation<\/h1>\n<p>To run the simulation, click on\u00a0<b>Run Simulation<\/b> in the Flow Navigator window. This will bring up a drop-down menu. Select <b>Run Behavioral Simulation<\/b>. This should bring up a simulation waveform window which resembles\u00a0the screen on a logic analyzer. It shows the changes in the simulation&#8217;s signals over time. On the left, you should see buttons that\u00a0control the varying\u00a0views of the simulation. You can zoom in on specific points in time, or zoom out to see a grand overview of the entire simulation. Go ahead and play around with the functions to get a feel for the tool.<\/p>\n<p>In the next tutorial, I&#8217;m going to cover a few things that we glossed over in this tutorial. In particular, I&#8217;ll be talking about the difference between blocking and non-blocking assignment. It&#8217;s an important topic, so be sure to read that as well.<\/p>\n<p>Here is my\u00a0final version of bench.v for this tutorial:<\/p>\n<pre>`timescale 1ns\/1ns\r\nmodule bench;\r\n  reg clk = 1;\r\n  always #5 clk = ~clk;\r\n  reg [7:0] switch;\r\n  wire [7:0] led;\r\n  top top(.clk(clk), .switch(switch), .led(led));\r\n  always @(posedge clk) switch = $random;\r\n  initial\r\n    begin\r\n      repeat (1000) @(posedge clk);\r\n      $finish;\r\n    end\r\nendmodule<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>In the last tutorial, we programmed our device and tested it by physically switching all the switches. That is all the testing you&#8217;re going to need for the simplest FPGA in the world. In reality, things can be somewhat more &hellip; <a href=\"https:\/\/www.beyond-circuits.com\/wordpress\/tutorial\/tutorial2\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"parent":226,"menu_order":2,"comment_status":"open","ping_status":"open","template":"","meta":{"footnotes":""},"class_list":["post-248","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/pages\/248","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=248"}],"version-history":[{"count":7,"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/pages\/248\/revisions"}],"predecessor-version":[{"id":889,"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/pages\/248\/revisions\/889"}],"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=248"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}