EIT020 - Digitalteknik (Fall 2014) Using VHDL on FPGA (Stop Watch) Teacher: Prof. Thomas Johansson Created By: Steffen Malkowsky v.1.0.0 1 Abstract In this lab you are going to use VHDL to implement a complex design, simulate it using Questa Sim and finally, prototype it on an FPGA board. As an example a stop watch will serve, which will be developed step by step throughout this lab. The goal is to get insight view on how complex designs are realized in industry and acquire knowledge about the design flow using the tool chain provided by Xilinx. Contents 1 Purpose of the Lab 2 Designing a Stop Watch 2.1 Specification . . . . . . . . . 2.2 Block Diagram . . . . . . . . 2.3 Defining the Interfaces . . . . 2.3.1 Debouncer . . . . . . 2.3.2 Edge Detection . . . . 2.3.3 Control_FSM . . . . . 2.3.4 Counter . . . . . . . . 2.3.5 BCD . . . . . . . . . 2.3.6 Seven Segment Driver 2.4 Verify the Design . . . . . . . 3 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using ISE to Program the FPGA 3 3 4 5 5 6 7 8 8 9 10 11 A Simulation A.1 Testbench . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A.2 Using Questa Sim . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 18 18 19 1 Purpose of the Lab In this course fundamental digital design techniques like Minimization of Boolean equations and application of Karnaugh-maps were introduced. When designing complex circuits built out of million of gates, however, these techniques are not practical. For such design an HDL (Hardware Description Language), e.g., VHDL or Verilog is applied to describe the circuits on a higher-level. On first glance these languages are similar to programming microcontrollers, however, the inherent difference is that HDLs do not show a sequential flow but rather a concurrent flow. As platform to verify the stop watch, a Nexys-4 development board is used. The manual for this board is provided on the course homepage. Keep in mind while you are designing your circuits that different processes in a VHDL file run concurrently to each other and are triggered by their sensitivity list. Statements outside a process within an architecture are implicit processes which also run concurrently and are triggered by their operands. In the next section you will be guided through the whole design flow of a stop watch, writing your own VHDL code, simulate your design and finally, prototype it on an FPGA starter board. To ease the first steps, a basic structure, i.e., a skeleton of the whole design is prepared for you. Home Exercise 1: Read the lab manual carefully, so you know what is expected from you. Do the home exercises before the lab session. Lab exercises will be done during the lab session. The files that you will use during the lab is also available on the course homepage. The .zip file contains two folders, vhdl and testbench. The first one contains all vhdl files that will be used during the lab. In the second folder you will find all the testbenches that will be used during simulation. 2 2.1 Designing a Stop Watch Specification Usually, the design process starts with a specification of the design. Here, a stop watch shall be developed. As interface to the user, two buttons, start and stop as well as a seven-segment display are envisaged. When powering up the device the display should show 00.00, where the digits before the decimal points are seconds and after are tenths 3 and hundredths of a second. This means that the maximum count of our stop watch is 99.99 seconds. If the stop watch reaches this value it should wrap and continue counting from zero. In the initial state the start button starts the stop watch and the current value is displayed on the display whereas the stop button is not supposed to have any function. While the stop watch is running a one time press of the stop button pauses the stop watch and a second press resets the counted value; bringing the stop watch back to its initial value. Pressing the start button during pause state of the stop watch will bring the stop watch back to running mode continuing counting at the paused value. The Nexys-4 board has plenty of basic I/Os available such as switches, buttons. LEDs etc. As input buttons start and stop, the left and right pushbutton of the plus-sign arranged pushbuttons are used. To display the current counter value the last four seven-segment displays triggered by AN0 to AN3 are employed. Have a look at the manual to see how these have to be triggered in order to display values. The system reset is connected to switch SW0 on the board. 2.2 Block Diagram To ease the development of complex designs, the design is broken up in to a number of smaller, less complex blocks. This approach is called "Divide-and-Conquer". This partitioning is done below for you but it would be a good exercise for you to think about this before continuing reading and to compare your result with the given design later on. Following things should be considered while doing this: • How many inputs does the design have? • What different functionalities are required and how can they be split-up in several blocks? • What interfaces are necessary between the different blocks to communicate? Our design will have two inputs, a start and a stop button. Due to the mechanical nature of these, pressing them will not lead to an immediate stable signal but the signal will bounce; therefore, a debouncer is required. Fig. 1 shows this behaviour. Amplitude Amplitude Button is pressed Time Button is pressed tBounce Behaviour in Theory Time Behaviour in Reality Figure 1: Behaviour of a mechanical switch: (left) in theory, (right) in reality. 4 Moreover, the FPGA will run on a high clock frequency. Hence, a single button press of the user will lead to an active signal at the input of our blocks for many thousand or even millions of clock cycles. Thus, an edge detection circuit is needed to ensure that each acknowledge of a button translates only to a signal being active for one clock cycle. To control the different states of the stop watch, a FSM (Finite-State-Machine) has to be employed in the design and subsequently this FSM has to trigger a counter counting the time. This binary value has to be decoded into a representation matching the inputs of the seven segment driver. The seven segment driver will be provided and will be explained in detail later. Fig. 2 shows the overall block diagram of the stop watch. Stop Watch Debouncer Start button_in button_out Debouncer Stop button_in button_out Edge Detection inp det_edge Control FSM start det_edge run count_int BCD binary SevenSegment Driver bcd set0 set0 stop count_frac SevenSegment Display anode seven_segment BCD Edge Detection inp run Counter binary count_frac seg3, seg2 bcd seg1, seg0 Figure 2: Block schematic of the stop watch. Clock and reset signals have been omitted for simplicity, however, keep in mind that all sequential circuits need to be reseted using the system reset signal. Throughout the lab all clocked gates should be sensitive to the rising edge of the clock. 2.3 Defining the Interfaces After sketching a block diagram we have to determine the interfaces required for communication among one another and define the exact functionality of each block. 2.3.1 Debouncer This circuit will only wait until the input button has a stable value for about 20 ms. Hence, it is a counter having the button as input button_in and a delayed output button_out. This block will be provided for you and is part of the package vhdl\stop_watch_package.vhd. 5 2.3.2 Edge Detection Detects the rising edge of the debouncer output button_out at its input inp and acknowledges this with an one cycle active output signal at det_edge. Home Exercise 2: Draw a sequential circuit that detects the rising edge of a signal using standard gates, e.g., flip-flops, OR, AND etc. Do not use more than 4 gates! Try to express your logic by using VDHL. Lab Exercise 1: Make a new folder in U:\DigTekLab\<name> and copy the folder S:\Lab6\ into it. In Lab6\ you will find two folders, vhdl and testbench. The first one contains all the VHDL files for the project, including the ones you will need to write your own code in. And the second folder, testbench, contains all the testbenches that will be used during simulation. Open vhdl\edge_det.vhd with notepad++ (or any other text editor) and fill in the logic that implements your edge detector. The places where you should fill in code are marked with TODO. To verify the functionality you will need to simulate your logic. This will be done by using Questa Sim. Refer to appendix A on how to set up the simulation project. For this task you only need to add vhdl\edge_det.vhd and testbench\edge_det_tb.vhd to the simulation project. When you think your logic works, show the simulation for a lab assistant. 6 2.3.3 Control_FSM Controlling the different states of the stop watch makes the use of a FSM necessary. The FSM shall have two inputs connected to the input buttons; therefore called start and stop. Two outputs run_cnt and set0 will trigger the subsequent counter block. Output run_cnt is active during run state of the stop watch and output set0 is active for one clock cycle when resetting the counter. Home Exercise 3: Draw the graph of the FSM fulfilling aforementioned specifications as Moore and Mealy implementation. Do you need the same number of states for both implementations? What is the fundamental difference between both? Draw a block diagram for both types consisting of next-state decoder, current-state and output-decoder blocks to be able to explain the differences to the teaching assistant. Do not draw the circuits at gate level. Try to express your next state logic and output logic by using VHDL, do it as either Mealy or Moore. A tips is to use CASE-statements, where each case is one of your states. Lab Exercise 2: Open vhdl\fsm.vhd and fill in the logic that implements your FSM, implement it as either Mealy or Moore. The places where you should fill in code are marked with TODO. Verify the functionality by simulation. For this task you only need to add vhdl\fsm.vhd and testbench\fsm_tb.vhd to the simulation project. When you think your logic works, show the simulation for a lab assistant. 7 2.3.4 Counter The actual counting of the values is performed in this block; thus, it mainly consists of different counters. To be able to map counted clock cycles to actual time, knowledge about the actual clock frequency of the FPGA board is necessary. Two inputs run and set0 are used. While run is active, counter is active, otherwise the current value is hold constant. The input set0 resets the counter to zero when activated. The output of the current time is split into two signals. First, count_int counts the seconds the stop watch is running since start and second, count_frac counts the hundredths of a second the stop watch is running. Home Exercise 4: The Nexys-4 board is driven by a 100Mhz clock. What is the time resolution that can be achieved with this frequency, i.e., the clock period. How many clock cycles need to be counted until 1/100 s, 1/10 s and 1 s passed? What is the number of bits required for the outputs count_int and count_frac? 2.3.5 BCD The BCD (Binary-Coded-Digital) block performs a binary-to-BCD decoding of the signals. The binary-coded input number at input binary is decoded using the Shift and Add3 algorithm and the resulting BCD coded number is available at output bcd_out. This blocks does not have a clock signal and neither a reset signal, i.e. it is purely combinational. Home Exercise 5: Have a look at the Shift and Add-3 algorithm and how to implement it in logic (plenty of sources are available on the web). The necessary add-3 components are defined in vhdl\stop_watch_package.vhd and the BCD block uses those to implement the decoder in a structural description. Perform binary-to-BCD conversion of the decimal number 99 by hand using a table. 8 Lab Exercise 3: The BCD block has already been written for you; but, it contains an error. Start by simulating the block, for this you need to add vhdl\bcd_with_error.vhd, testbench\bcd_tb.vhd and vhdl\stop_watch_package.vhd to the simulation project. Start the simulation and bring up the waves for the binary and bcd_out signal. Change the radix for the binary to decimal and bcd_out to hexadecimal, this way it will be easier to see the error (refer to appendix A). Now open the vhdl\bcd_with_error.vhd, correct the error and recompile the file in Questa Sim. When you are done, show the simulation for a lab assistant. 2.3.6 Seven Segment Driver The seven segment driver has 4 inputs seg0, seg1, seg2 and seg3 which are the BCD values for the four seven-segment panels. The seven-segment displays share cathodes but each has a separate anode; therefore the anodes are triggered in a round-robin fashion to illuminate one number at a time. Naturally, this has to happen in a speed fast enough to not make them flicker. Moreover, this has to happen at least four times as fast as the fastest used counter, to be able to illuminate all numbers at least once before counting up a value. The driver provided in vhdl\SevenSegment.vhd performs exactly this triggering and additionally, decodes the BCD input into a seven bit output for the seven segment display using a LUT (look-up table). 9 2.4 Verify the Design Now that all the coding has been done and the functionality of each module has been verified, it is time to simulate the final design. Lab Exercise 4: Set up the simulation for the final design. You need to add the following files to the simulation project: • testbench\stop_watch_tb.vhd • testbench\stop_watch_without_deb.vhd • vhdl\bcd_with_error.vhd • vhdl\counter.vhd • vhdl\edge_det.vhd • vhdl\FSM.vhd • vhdl\SevenSegment.vhd • vhdl\stop_watch_package.vhd Note: stop_watch_without_deb.vhd performs the same functionality as stop_watch.vhd but does not use debouncers, as this would lead to longer simulation times. Browse through the hierarchy in the sim window and bring up the the following signals into the Wave window: • stop_watch_tb⇒start • stop_watch_tb⇒stop • stop_watch_tb⇒DUT⇒FSM_1⇒current_state • stop_watch_tb⇒DUT⇒FSM_1⇒next_state • stop_watch_tb⇒DUT⇒bcd_1⇒bcd_out • stop_watch_tb⇒DUT⇒bcd_2⇒bcd_out Change the radix of both bcd_out to hexadecimal and set the simulation step time to 700 ms and run the simulation. Show the simulation to a lab assistant. 10 3 Using ISE to Program the FPGA Prototyping your design on an FPGA presupposes that your design is being synthesized and mapped on the respective FPGA type. Since you will not have an FPGA board available at home, the following steps are done in the lab. Nevertheless, read through this section before the lab session to be sure what is required from you. In the synthesize process your written RTL description is replaced by a gate level description of the circuit, i.e., your boolean functions are replaced by the respective gates, e.g., AND, OR etc. Next the design is mapped onto the FPGA, i.e., the configurable interconnects are programmed in a way to implement your design. Following you will be guided through the process of synthesize and mapping for the Xilinx ISE step by step. Click the start button on your computer and go to all programs. Then Xilinx Design Tools⇒ISE Design Tools⇒64-bit Project Navigator. An overview of the interface will be given later but now first open a new project by clicking File⇒New Project. Figure 3: Start a new project in ISE. The window for creating a new project will open (see Fig. 3). Enter a name for your project. Do not use spaces in the name as this can lead to problems in ISE. Choose U:\DigTekLab\<name>\Lab6 as the location for your project and hit the next button. Following, the FPGA settings have to be made. Basically, this means to provide ISE with the type and details about the FPGA we are using. Make sure all settings are as in Fig. 4. 11 Figure 4: Configure the FPGA. Subsequently, the design files, i.e. the developed VHDL files are added to the project (also add the top.ucf file, which will be explained later). Do not add the testbenches since they are not synthesizable! Select Project⇒Add Source from the menu bar, then browse for your VHDL files and hit OK. (a) Add the VHDL design files. (b) Feedback for successful loading. Figure 5: Add files to the project. The upcoming window will inform you if any problems were encountered while loading the files and is depicted in Fig. 5(b). After this step your windows appears like in Fig.6. On the upper left window called 12 Hierarchy the loaded design is shown in a hierarchical tree starting from the top level, in our case stop_watch. Underneath the different processes to perform are shown. On the right side, all design specific tasks are summarized. As you proceed performing different processes, logic utilization, error and warnings as well as reports will be available. On the bottom you see the console pane. All steps including sub-steps will be printed here while performing processes. Instead of checking warnings and errors in the summary you can also check them there. Using the tabs warnings and errors will filter the console output to only show warnings and errors, respectively. Figure 6: The standard ISE interface. To synthesize your design select the top level design entity, i.e. stop_watch, in the hierarchy window and then, double-click Synthesize - XST in the process window. During synthesize the HDL code is mapped onto gates and optimized for the chosen architecture. The resulting windows, shown in Fig.7, looks quite similar with the difference that outputs like warnings or device utilization reports are available now. There are some sub-processes available in the synthesis. For instance, the RTL schematic is viewed by double-clicking View RTL Schematic. A pop-up window ask if you want to start using the Explorer Wizard or a schematic of the top-level block. First, will give you the opportunity to customize the generated schematic, i.e. select which instances and signals you want to see whereas the latter will start with the schematic from the top-level block as seen in Fig. 8. By double-clicking the instance stop_watch you will descend into the lower level, i.e., the inside of the stop_watch. A further tool to to try is the View Technology Schematic process. As known, the developed hardware is mapped onto FPGA using LUTs (Look-up Tables) combined with flip-flops. In this view you can see how the hardware is mapped on the Artix-7. Hit CTRL+F to open a search window, as shown in Fig. 9 and use it to search for signals, however, some signals may not be available anymore since ISE performs optimization on the logic. 13 Figure 7: Window after performing Synthesis. Figure 8: Top-level block in Schematic Viewer. Lab Exercise 5: Perform Synthesis on your design. Make sure you do not have any warnings except the one shown in Fig.7 (Input <dot> is never used). Especially, any latches have to be removed as they can lead to unpredictable results in the design. Check the View RTL schematic tool and browse through your design. Is the topology like you expected? Check your edge detection circuit? Is it implemented as you drew it in your home exercise? Finally, have a look at your Synthesis result. What is the hardware utilization of the FPGA? Show your results for a lab assistant. 14 Figure 9: Search for signals in Schematic Viewer. Implement your design by hitting Implement Design in the Process Window. First, ISE will translate the design into a single merged netlist combining design and constraints out of your provided .ucf file (here basically the location of our inputs and outputs defined in top.ucf ). Moreover, timing specification and logical design rule checking is performed. During mapping the design is mapped onto the resources of the FPGA, i.e. the CLBs (Configurable Logic Blocks) and the IOBs (Input-Output Buffers). Additionally, a design rule check on the final mapped netlist is performed. Finally, Place-and-Route places the components on the FPGA and configures the logic in optimum way, i.e. it tries to keep path delays as small as possible. After this step, final timing and resources utilization reports are available in the right Design Summary window. Lab Exercise 6: Make sure that you have added top.ucf to the project and then implement your design. Check the timing as well as resource utilization reports, does it differ from the synthesis results? What is the maximum frequency you can clock your design with? You can wait to show the results until lab exercise 7. Having successfully performed all aforementioned tasks, it is time to generate the programming file for the Artix-7. Hit Generate Programming File in the Process Window and afterwards (when generation is finished) go to Tools and open iMPACT as depicted in Fig. 10. Hit OK on the upcoming pop-up window saying that no project file exists. 15 Figure 10: Open iMPACT. iMPACT is the ISE integrated tool to program FPGAs. After opening, make sure your FPGA board is connected using the USB-cable and turned-on. Then, double-click Boundary Scan and subsequently, press Initialize Chain (see Fig. 11). Figure 11: Initialze the FPGA. Select the generated .bit file in the upcoming Assign New Configuration File window. Answer no if iMPACT asks if you want to attach SPI or BPI PROM and finish Device Programming Properties by hitting OK again. In the right window you should now see a picture showing an Xilinx FPGA as in Fig. 12. Right-click the FPGA and hit Program. The generated bitfile is now transferred to the FPGA. The green LED DONE will light as soon as programming is finished. 16 Figure 12: Program the FPGA. Lab Exercise 7: Generate the bitstream and download it to the FPGA. Test your design and verify the functionality. Perform changes, if necessary, and re-generate the bitstream. Maybe you need to go back to simulation in order to fix possible malfunctions. Demonstrate your stop watch to a lab assistant. Additional Lab Exercise 8 (non-mandatory): In case you finish all aforementioned tasks in time and you still have some time available you can extend your stop watch. Say the stop watch should also print minutes instead of only seconds. This means, you have to add two additional seven segment displays and requires to add these in the seven segment driver. Additionally, another counter as well as an output for the minutes is necessary in the counter block. Moreover, a third BCD block has to be added to decode the value of the added minute counter. 17 A Simulation Simulating a logic circuit is an effective way to verify its correctness. During this course you will use Questa Sim from Mentor Graphics to simulate your logic circuits. To generate input patterns for the simulation, testbenches written in VHDl will be used. Below a testbench is briefly described and then a tutorial on how to run a simulation in Questa Sim is given. A.1 Testbench Verifying each block makes it necessary to write a testbench for each block. Listing 1 shows a testbench for the BCD block. For testing, an empty entity is used since we do not need to connect the design to any other block. The DUT (Device under Test) is included as an component as seen in line 15 to 19. Subsequently, signals are generated. The clock signal clk in line 26 and 37 is not needed here, but was preserved to show how you can generate the clock for your other testbenches. In line 31 to 34 the DUT is instantiated and connected to the generated internal signals. The WaveGen_Proc process starting at line 40 is then generating the signals for your testbench. In this case it just counts up the value at input binary and Questa Sim is used to observe if the output bcd_out reacts with the correct BCD values. Listing 1: Testbench Example 1 2 3 library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; 4 5 ------------------------------------------------------------------------------- 6 7 entity bcd_tb is 8 9 end bcd_tb; 10 11 ------------------------------------------------------------------------------- 12 13 architecture bcd_tb_arch of bcd_tb is 14 15 16 17 18 19 component bcd port ( binary : in std_logic_vector(6 downto 0); bcd_out : out std_logic_vector(7 downto 0)); end component; 20 21 22 23 -- component ports signal binary : std_logic_vector(6 downto 0) := (others => ’0’); signal bcd_out : std_logic_vector(7 downto 0); 24 25 26 -- clock signal Clk : std_logic := ’1’; 27 28 begin -- bcd_tb_arch 29 30 31 32 33 34 -- component instantiation DUT: bcd port map ( binary => binary, bcd_out => bcd_out); 35 36 37 -- clock generation Clk <= not Clk after 10 ns; 38 39 -- waveform generation 18 40 41 42 43 44 45 46 47 48 WaveGen_Proc: process begin -- insert signal assignments here for i in 0 to 9 loop wait for 10 ns; binary <= std_logic_vector(unsigned(binary) + 1); end loop; -- i wait until Clk = ’1’; end process WaveGen_Proc; 49 50 51 52 end bcd_tb_arch; A.2 Using Questa Sim When a testbench is written it is time to simulate your design. For this purpose, Questa Sim will be used in this course. Questa Sim is a standard RTL (Register-Transfer-Level) simulator and it is freely available as a Student version. All input combinations you chose in your testbench will be simulated cycle-correct on the RT level. Click on the start button of your computer and then All Programs⇒Questa Sim-64 10.1d⇒Questa Sim. First you need to create a new project in Questa Sim. Select File⇒New⇒Project from the menu bar, Fig. 13. In the Create Project dialog enter a name for the simulation project and where to save it. Make sure you save it in U:\DigTekLab\<name>\sim. Do not change any of the other settings. Figure 13: Creating a new project in Questa Sim. When the project has been created, you need to add the vhdl files and testbeches that you want to simulate. Click on Add Existing File in the Add items to the Project dialog or click on Project⇒Add to Project⇒Existing File in the menu bar. Then browse for the vhdl files that you want to verify and click on OK to import them, see Fig. 14. Do not forget to import the testbench that you want to use in the simulation. 19 Figure 14: Adding vhdl files and testbenches to the project. Before you can simulate your design the added files needs to be compiled. This is done by clicking Compile⇒Compile Order and then select Auto Generate in the newly opened window, Fig. 15. This compile option makes sure that the files are compiled in the right order, so that all dependencies between them are resolved. Figure 15: Compile the project. If the syntax of your files are correct, the status field will change from a question mark to a green tick. If some file contains error it will be marked with a red cross and there will be an error message in the transcript window at the bottom. To get detailed information about an error, double click on the red message and a new window will open, Fig. 16. 20 Figure 16: View compile error. When all files has been successfully compiled the simulation can start. Switch over to the library window and then expand the work library. Right click on the testbench that you want to run and select Simulate without Optimization, see Fig. 17. 21 Figure 17: Starting the simulation. When the simulation starts, some new windows will appear, Fig. 18. The sim window gives a hierarchical view of the active simulation, where the testbench is located at the top and it’s components, your vhdl files that will be tested, is located beneath. Figure 18: Viewing signals. 22 In the objects window you see all declared signal of the current scope, you change the scope by selecting another instance in the sim window. If you would like to view the internal signal in one of your vhdl files (entity) during simulation, you need to mark it in the sim window. To get a better view of the simulation result you can display the signals as waveforms. If you want to view all the signals that belongs to an instance, right click on it in the sim window and select Add Wave. If you only want to display some signals, select the signals of interest in the objects window, right click and select Add Wave, see Fig. 19. Figure 19: Adding waves. Fig. 20 shows controls that is used to run the simulation. First you select a step time and then you press the Run button (or F9). During each step the simulation will run through the code in the testbench and generate stimuli to your component. You can then view both the input and output to your component in the wave windowl. By pressing the Reset button the wave window can be cleared and the simulation restarted. Figure 20: Buttons to control the simulation. Fig. 21 shows the tools you can use to zoom in and out in the Wave window. You need to make the Wave window active before you can use them. Figure 21: Zoom control in the wave window. Sometimes it can be hard to verify the correctness of the code by just looking at the bit pattern in the Wave window. If you are testing a counter, it will be easier to view the value of the counter signal as decimal instead of binary. To do this you right click on the signal in the Wave window and select Radix⇒Decimal, see Fig. 22. 23 Figure 22: Change the radix of a signal. 24
© Copyright 2026 Paperzz