CSE141L Lab 1: Tools of the Trade

CSE 141L Homepage | Lab Overview | Lab Description | Useful Resources

Deadline: Wednesday, April 6, 1:45PM; Submit via class moodle page
Change Log: April 2; clarification text added in Q9.
Change Log: April 2; Posted insructions to enable SystemVerilog in Quartus and ModelSim in 'Part 2'.
Change Log: April 4; Updated description with following clarifications:
  1. Post route simulation uses adder.svo, not adder.vo (since we are using SystemVerilog).
  2. If you forget to change your directory in modelsim for post route simulation, you will likely end up with an "SDF file was not found error."

Lab Overview:

Since you are new around here, we need to make sure you have all the tools to be a successful member of the AwesomeCore team. We expect you to have proficiency in both Quartus II and Verilog. In order to get you up to speed, this lab will have you work through a simple tutorial on using Quartus II. If you have worked with this tool in the past, this lab should be very easy. If not, you should get started immediately so you don't fall behind right away. In the future, you will be working with a partner to complete labs but for this lab you should work alone. Good luck!

Lab Deliverables:

Since this is an introductory lab, you will not be required to demonstrate anything at the end. The requirements are stated below.

Lab Description:

Jump to: Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6

Part 1: Install Quartus II and ModelSim:

Altera offers a free version of their design suite called Quartus II Web Edition and a free version of ModelSim for Altera. We will be using Quartus II version 10.1 SP1 and ModelSim-Altera Starter Edition version 6.6d, which can be downloaded

We encourage you to also work in the CSE labs in the basement of the CSE building. These software tools should be installed on the Windows partitions of all the computers in the lab after the second week of class. Please let us know (via the web forum) if you find lab computers that don't have these tools installed or have an older version of the software. Since the necessary tools will not be installed in the basement labs in time for this first lab, please install the tools on your own machine; the tools are available for Windows and Linux. If you cannot do this, please speak with the professor ASAP.

Part 2: Quartus II Quick Tutorial:

Altera provides a nice
step-by-step tutorial which will guide you through the basics of creating and working with projects in Quartus II. You only need to work though the first 6 sections. Sections 7 onwards it talks about issues related to FPGA board programming or simulation using Quartus II's built-in simulator (which we will not be using). Also work through the first three chapters of the ModelSim tutorial. A consolidated tutorial on Modelsim simulation can be found here. Look for resources in class moodle page as well!

To enable SystemVerilog in Quartus : Assignments - Settings - Verilog HDL Input and select SystemVerilog-2005.
To enable SystemVerilog in Modelsim : View - Properties - Verilog and SystemVerilog tab and select 'Use SystemVerilog'.
(or, Compile->Default Options->Verilog & SystemVerilog Tab->Use SystemVerilog)

Part 3: A Simple 8 bit Adder

Having completed the tools tutorials, we will now examine a few of the aspects of hardware design by having you implement an 8-bit Adder.

At AwesomeCore, we just bought a couple new Cyclone II FPGAs. To get you started, your manager has given you a Verilog file (adder.v) that describes a basic 8-bit adder. Look at the file and make sure you understand it thoroughly. After doing so, create a new project in Quartus II that contains this adder. When creating the project, set the device to Cyclone II EP2C35F672C6 and simulator to ModelSim-Altera with SystemVerilog HDL.

Note: the Altera tools don't seem to like spaces in filenames and paths, so don't use spaces in any filenames or directory names. This includes the "My Documents" directory; you can create your project on your network drive, which "My Documents" points to anyway--just don't specify the project location using the "My Documents" shortcut. There is a post on the discussion board with a little more detail.

Q1 Draw a schematic for adder.v. In your schematic, you should clearly show the function of the design by using flip-flops, various gates, a comparator, an adder, and wires. Try to infer a schematic from the Verilog source, but it is fine to use a generated schematic from Quartus II as long as it is detailed enough.

To see what is really going on, perform a behavioral (a.k.a. functional) simulation. Use test_adder.v as your testbench. When you've run the simulation, you should see something like what's in the figure below. Play around ModelSim (and perhaps the testbench) until you feel comfortable with it. You'll be using ModelSim as your primary debugging tool to debug your processor designs this quarter, so get familiar with it.

You might have noticed that output 'isOdd' is updated one cycle later than 'out'. (Stupid...who wrote this?) Anyway, it is a good opportunity to show your ability to tweak a design to get maximum performance.

Modify adder.v so that 'isOdd' is simultaneously updated with 'out'. Perform the same behavioral simulation you did in the previous step again. (Hint: You may want to examine blocking vs non-blocking assignment in Verilog.) Note: When updating your adder.v, both 'out' and 'isOdd' should be updated the cycle after the input(s) change, not two cycles later.

Q2 Draw a schematic for the modified adder and include it in your report. You should also briefly describe what changes you needed to make in order to get the desired behavior.

Don't forget to submit your modified adder.v.

Now that you have verified that your adder is functionally correct, it is time to synthesize. In the synthesis stage, Quartus translates your Verilog design to what its backend stage (implementation stage) can understand. To synthesize a design, double click on "Analysis and Synthesis" in the Tasks pane. When synthesis is done skim through the generated reports.

Now you'll want to see how your design maps onto the FPGA device. The stage where the design tools find a good layout on the device is called "Place and Route". Run this stage by double clicking on "Fitter" in the Tasks pane. Skim through the generated reports.

Q3 Report the following information from your generated Place and Route reports:
  • How many flip-flops (a.k.a. registers) are used for the design?
  • How many flip-flops does the EP2C35F672C6 have?
  • How many logic elements does your design use?
  • How many logic elements does the EP2C35F672C6 have?

Now that the design tools have mapped your design to an FPGA, you can estimate timing and figure out how fast your adder will operate. Now run the whole design compilation chain, which includes a timing analysis: go to "Processing" - "Start Compilation". Look over the reports in the "TimeQuest Timing Analyzer" section. The Fmax number in "Slow Model" Report is the maximum clock frequency at which your adder will run. The "Slack" and "TNS" which indicate how well the design meets the timing constraints in the clock domain. These can be seen in each of the "Setup Summary" reports. For more information on timing analysis in Quartus II, see the tutorial on timing.

Q4 Report the following information from your timing reports:
  • What is the maximum clock frequency at which your design will run?
  • What is the slack?

In order to prove that your adder works at a certain frequency, you need to do a post-route simulation. By comparing the results of your behavior simulation with post-route simulation, you can verify the validity of your implementation. Luckily, you can reuse the testbench from the behavior simulation you did earlier, and the process for running the simulation is very similar. Since the tutorials do not cover how to run timing simulations using ModelSim and a Verilog testbench, here are the instructions you'll need to get started:

  1. Make sure to run the entire compilation process in Quartus II (including "EDA Netlist Writer").
  2. Open ModelSim.
  3. Select "File" - "Change Directory..." and navigate to the "simulation" and then "modelsim" subdirectories under your adder project directory. If you forget to do this you will likely end up with the error "SDF file was not found" when you run your simulation.
  4. Select "File" - "New" - "Library..." and select "a new library and a logical mapping to it". Name the library "work" and enter "work" for the library physical name as well. You should then see the "work" library at the top of the library list.
  5. Select the work library and select "Compile" - "Compile...". Select "adder.svo" (assuming your project name in Quartus was set to "adder") and then click "Compile". Then navigate to "test_adder.v" (the same testbench file you downloaded before and used for your functional simulation), which should be a couple directories up. Click "Compile" with "test_adder.v" selected. Then click "Done". Now, in the library list, if you expand the "work" library, you should see "adder" and "test_adder". In the future, if you make any changes to adder or testbench Verilog source, you'll need to re-compile the "work" library before re-simulating.
  6. Select "Simulate" - "Start Simulation" and do the following:
    1. In the "Design" tab, expand the "work" library and highlight "test_adder". Select "ns" in the "Resolution" drop-down field.
    2. In the "Libraries" tab, in the "Search Libraries" area, select "Add" and add the "cycloneii_ver" library.
    3. In the "SDF" tab, select "Add". Add "adder_v.sdo" and apply it to the region "/test_adder/dut".
    4. Finally, click on "OK" to start the simulation. After this, use ModelSim to run the timing simulation in the same manner you used it to run the functional simulation.

Q5 Include the two simulation results (behavioral and post-route) in your report. Are they the same as each other? If not, why are they different? If needed, modify the test bench file and make sure post-route simulation works correctly. (Hint: Behavioral simulations do not have a sense of frequency while post-route simulations do.)

Part 4: 32-bit Adder

Now that you have a working, validated 8-bit adder, you should turn your attention towards bigger and better designs. One simple extension you can do is to modify your adder to support 32-bit addition rather than just 8-bit. Modify your Verilog source file then synthesize and implement it.

Generally, the bigger and more complex your design is, the slower it will be. It is important to understand the main causes of this phenomenon:

Q6 Since your FPGA has limited hardware resources and you are always concerned about your performance, you should try to characterize the cost of different sizes of adders. Fill out the following table with information on adders ranging from 8 bits to 64 bits.
Width Max Freq # of logic elements used # of registers used

Part 5: Register File

Now that you are a master of adders, it is time to move on to bigger and better things. Your next task is to design a register file. Go ahead and create a new project for your register file design.

Processors keep a small, but extremely fast collection of storage locations, called registers, grouped into what is called a register file. You'll design a register file with 2 read ports and 1 write port, so that every cycle two registers can be read and one written. You should parameterize your register file with number of registers and data width (the number of bits in each register). You can set the default parameters to 6 16-bit registers. Your register file should take as input:
Outputs are:

On every rising clock edge your register file should save whatever value is on wd_i into whatever register number is specified in wa_i if wen_i is high. In this register file, while writes are synchronous (happening only on rising clock edges), reads are asynchronous. Anytime ra0_i or ra1_i changes, the value(s) in the newly-specified register(s) should be output on rd0_o or rd1_o immediately (or as fast as the logic and signal propogation will allow). Below is example output from the wave form viewer, from behavioral simulation, demonstrating the desired register file behavior. Note that the signals names are from an older style convention in a previous 141L class; you should use the ones provided earlier in the text.

Hint: You can declare a 32-port 32-bit register array in verilog as:

reg [31:0] rf[31:0];

Hint: You can read it as (elipsis indicates surrounding code):

.. = rf[read_address] ..

Hint: You can write it as:

rf[write_address] <= ..

Synthesize and Place and Route your design. Then create a testbench in Verilog to test your register file design. Test a variety of inputs including all the corner cases you can think up. Your testbench should at the very least test the following cases:

Use ModelSim to perform a behavioral (not timing) simulation of your design and verify correct operation.

Q7 Briefly describe the setup of your register testbench. What scenarios were you trying to test? What behavior do you expect in each of these scenarios?

Include enough screenshots of your simulation waveform to demonstrate that your register file works correctly in all the scenarios you were testing. Be sure to point out what part of these screenshots demonstrate the correct behavior. Screenshots should be zoomed in enough to clearly see values. Be sure to switch to decimal representation in the screenshots for signals where it makes sense (e.g. wd_i and rd0_o). The goal of the screenshots is to clearly demonstrate your working register file so it is important that they are readable and understandable.

Remember to include your your register file and testbench Verilog files in your turn-in.

In order to get an estimate from the Altera tools of the maximum clock frequency of a design, there needs to be, at minimum, two flip-flops with wires and logic in between them. Then the tools can tell you the estimated maximum frequency based on how long it takes values to leave one flip-flop, pass through the wires and logic, and safely arrive at the other flip-flop. Since your register file design should not have any logic and wires between registers (just logic and wires around registers), you will not be able to estimate maximum frequency unless you sandwich your register file between some flip-flops (i.e. you latch its inputs and outputs somewhere). To facilitate this, use this wrapper module. Below is a schematic showing how the wrapper is sandwiching your register file between flip-flops. You should change its parameters each time you change the parameters for your register file. You should probably create a new project for the wrapped register file which should include the register file wrapper and your register file (with the wrapper as the top-level design element); if you just add the wrapper to your exisiting register file project, the tools may not recognize the wrapper as the top-level design element.

Q8 Fill out the following table for register files of different configurations. Note that some register files might not fit in the FPGA device due to their demands on resources. In such cases, explain the reason.
Configuration Max Freq # of logic elements used # of flip-flops used
8 16-bit registers      
16 16-bit registers      
32 16-bit registers      
32 64-bit registers      
256 32-bit registers      

Part 6: Synthesizable Verilog Hacking

You are given a FIFO queue (fifo.v) that is written in the short form that combines both sequential and combinational logic. For those new to verilog design, this can be harder to understand. "Desugar" this FIFO by converting the mixed sequential and combinational blocks (e.g. always_ff @(posedge clk)) into separate sequential and combinational blocks, as shown in the second to last slide of the first set of lecture slides.

Q9 Use OpenOffice.org Impress, Microsoft Powerpoint, or another drawing program to draw a CLEAR, reasonable schematic for your desugared fifo.v, assuming that default parameters are used. Be sure to label all wires and logic blocks with their names and their widths from the verilog. You should use symbols to indicate blocks like comparators, flip-flops, adders, register files, etc. You may want to make a library of such symbols for future use. Adders should be drawn like ALUs, comparators as circles with an == inside them, gates with the standard shapes, etc. You should organize the objects in the schematic so that signals tend to run from left to right. Flip-flops and registers should be drawn using the correct symbol. If a component implicitly contains sequential elements (for instance a register array), you should indicate that with an embedded flip-flop, so that the relative timing of signals in the design is clear. You should organize the objects in the schematic so that signals tend to run from left to right.

See the yellow portion of this example schematic for an example of roughly how we expect it to look. (Note that you will actually be drawing what goes "inside" the FIFO shown in the example, in the same style that is used for the example.)

Don't forget to include your modified fifo.v file with your lab turn-in.

Useful Resources

This lab created by Donghwan Jeon, 2007. Modified by Sat Garcia, 2008. Modified by Matt DeVuyst, 2010.