Overview

This tutorial shows you how to use the System Console debugging tool to program a compiled FPGA design into an FPGA device, then access the hardware modules (i.e. peripherals) that are instantiated in that FPGA design. This System Console tutorial is based on the FPGA design created in the “Build a Custom Hardware System” tutorial. In that tutorial, you create this Qsys system:

Figure 1: Qsys System Block Diagram

In this tutorial, you will interact with the Qsys system through a JTAG cable connected to the FPGA, sending read and write transactions through the JTAG master component to interact with the slave peripherals connected to it.

Materials

Hardware

Windows* or Linux* development host PC

Intel® Cyclone® 10 LP FPGA Evaluation Kit

USB Type A to Mini-B cable

Software

Installed Intel® Quartus® Prime Software Suite. Either the Lite or Standard Edition, but not the Pro Edition. This was accomplished in the “How to Program Your First FPGA” tutorial.

A completed Quartus project from “Build a Custom Hardware System” tutorial. If you have not completed that tutorial you should go back and complete it now.

Step 1: Preparing the Board

This section describes how to prepare the Intel® Cyclone® 10 LP FPGA board for use in this tutorial.

Plug the mini USB cable into the USB connector of the board. Then plug the other end of the USB cable to your host PC.

Make sure DIP switch S1-4 (BYPASS) is in the default “OFF” position as shown in figure 2. This enables a JTAG connection to the board via USB. The other 3 switches are general user inputs and can be in any state.

Figure 2: USB Connector

Step 2: Getting Started with System Console

This section describes how to use System Console to download the FPGA design into the FPGA device, and then interact with the JTAG master IP core inside the Qsys system to read from, and write to the attached slave peripherals. It also demonstrates JTAG link debug and Qsys system health observability provided by System Console.

Launch the Intel® Quartus® software and open the blink project you created in the “Build a Custom Hardware System” tutorial by selecting File > Open Project, navigating to your project folder, and selecting the blink.qpf file.

Launch System Console from the Tools > System Debugging Tools > System Console menu.

Figure 3: System Console Menu

The System Console tool looks for devices connected to the JTAG cable. To list the available devices, locate the TCL Console pane at the bottom right corner of the System Console window, and type the following command, then press ENTER:get_service_paths device

Figure 4: System Console’s TCL Console

You can use tab completion to finish commands as you type them, and even show you what possible commands can complete from the prefix you type. For instance, type get on the command line and then press TAB, to see a pop-up list of all commands that begin with get. You can use the up and down arrows on the keyboard to scroll up and down the list to select one of the commands. Press Enter to select a command from the pop-up menu.

Figure 5: Command Line Before Pressing Tab

Figure 6: Command Line After Pressing Tab

The TCL console history buffer can also be scrolled backward and forward using the up and down arrows on the keyboard, letting you easily recall previously executed command lines.

All commands provide help if you pass them into the help command. At the tcl prompt type:help get_service_paths

Figure 7: Getting Help for Commands

Type help help to see a list of commands.

Step 3: Program the FPGA

To program the FPGA device, we first need to get a service path to the device. We will assign that path to a variable called d_path by typing the following command:set d_path [lindex [get_service_paths device] 0 ]

Download the SOF file to the device by typing the following command:device_download_sof $d_path output_files/blink.sof
The amber D5 CONFIG LED should be illuminated once the commands above complete

Step 4: Using the JTAG Debug Service

Exercise the JTAG DEBUG service path provided by the JTAG master component.

Locate the JTAG DEBUG service path of the JTAG master and store it in a new variable called jd_path by typing the following command:set jd_path [lindex [get_service_paths jtag_debug] 0]

Exercise the JTAG interface by sending a list of values through a loopback at tdi and tdo of a system-level debug node (SLD). This command checks the physical interface of the board and JTAG TAP controller pins of the FPGA device. Type the following command and observe the values returned:jtag_debug_loop $jd_path [list 1 2 4 8 15 16]

Check the clock connected to the JTAG master component in the Qsys system. This command senses whether the clock is active, and returns a 1 if it is, and a 0 if it is not. Type the following command:jtag_debug_sense_clock $jd_path

Sample the “state” of the clock connected to the JTAG master component. Repeatedly sample the clock until you catch it in both the high (1) and low (0) state. Type the following command and press ENTER to observe the clock state. Repeat the command by pressing the up arrow followed by ENTER:jtag_debug_sample_clock $jd_path

Sample the reset signal connected to the JTAG master component inside the Qsys system. The S3 push button on the board is connected to the Qsys system reset input (active low). To sample the reset signal type the following command:jtag_debug_sample_reset $jd_path

To see the reset signal change, press and hold the S3 push button and resample the reset, then release the S3 push button and resample the reset.

Figure 8: Location of Push Button S3

Step 5: Using the JTAG Master Service

Next, we will exercise the master service path provided by the JTAG master. This will require us to recall the address map produced in the previous “Build a Custom Hardware System” tutorial. Remember that we used the sopc-create- header-files in that tutorial to create the master_0.h header file, and then dumped the base address macros from that file. To refresh your memory, here is what those addresses are:

First, set several TCL variables to allow us to more easily recall these base addresses in the rest of this tutorial. Execute each of the following commands to setup these variables:

set ocram 0x0
set led 0x10000
set button 0x10010
set switch 0x10020
set sysid 0x10030

To communicate with the peripherals in the device, we are going to use the “master” service. Locate the service path to the JTAG Master component and save it to the tcl variable m_path by typing the following command:set m_path [lindex [get_service_paths master] 0 ]
Claim the master service path so that we can interact with the JTAG Master component, and save it to the tcl variable c_path by typing the following command:set c_path [claim_service master $m_path ""]

Now that we can send commands to the JTAG Master, let’s interact with the on-chip RAM component by reading a single word from its base address. Type the following command and press ENTER:master_read_32 $c_path $ocram 1

Now write a word to the base address by typing the following command and pressing ENTER:master_write_32 $c_path $ocram 0x1234de10

Finally, let’s verify the word was written by reading from the on-chip RAM once more:master_read_32 $c_path $ocram 1

Next we'll use the JTAG Master to interact with the LED PIO component. First, turn on every other LED by typing the following command and pressing ENTER:master_write_32 $c_path $led 0x55

Now turn those LEDs off and turn the other ones on by typing the following command:master_write_32 $c_path $led 0xaa

New can also create a loop to toggle LED0 and LED1 every half second for 10 times by typing the following commands (or cutting and pasting into the Tcl Console):

Finally, let’s turn off all the user LEDs with the following command:master_write_32 $c_path $led 0xff

Exercise the JTAG DEBUG service reset functionality. Now that we have some LEDs illuminated, let’s look at one more JTAG DEBUG service provided by the JTAG master component. We can assert the reset signal connected to the Qsys system by the JTAG master component. To do that we use the following command:jtag_debug_reset_system $jd_path

After executing that command, the LEDs should all turn ON, returned to their reset state. You can trigger the same reset effect by pressing the S3 push button like we did before. Turn OFF some LEDs again and try pressing S3 to prove that as well.

Interact with the button PIO component by reading the status of the S4 Push Button.

First, read it before pressing the button with the following command:master_read_32 $c_path $button 1

Next, press and hold S4 and repeat the command.

Interact with the switch PIO component. There are 4 slide switches in DIP switch SW1, but only 3 of them are for GPIO use. We will use SW1-1 through SW1-3; avoid changing SW1-4 which causes the device JTAG link to be bypassed.

First, set SW1-1 through SW1-3 to the ON position and read the switches with the following command:master_read_32 $c_path $switch 1

Now, one by one, set SW1-3 through SW1-1 to the OFF position and read the switches again.

Interact with the system ID component. This component contains two 32-bit words. The first word is the ID value that we set to 0xde10de10 in the previous hardware portion of this tutorial, and the second word that represents the Unix second time value when the Qsys system was generated.master_read_32 $c_path $sysid 2

Exercise the default slave peripheral. Here we will demonstrate what happens when we read and write to unmapped addresses.

Our peripherals are mapped into addresses 0x0000_0000 thru 0x0001_0038. By reading an address outside that range, we will read instead from the default slave peripheral (which was initialized at device configuration to 0x0000_0000). Read from an unmapped address with the following command:master_read_32 $c_path 0x01000000 4

The read operation should return the following data:0x00000000 0x00000000 0x00000000 0x00000000

Let’s write to a slave that has no write interface, like the system ID peripheral. That write will not be decoded by any slave in the system and will be directed into the default slave.master_write_32 $c_path $sysid 0xfacecafe

Now verify that this write operation was sent to the default slave.

master_read_32 $c_path 0x01000000 4
The read operation should return the data shown below. Since only a single word was written (0xfacecafe), only the first word of the default slave was changed.0xfacecafe 0x1badf00d 0x2badf00d 0x3badf00d

Close the master service by typing the following command:close_service master $c_path

That’s it, you’ve used System Console to debug and test the FPGA hardware system.

As you have seen, System Console is useful for low-level, scripted or interactive testing and debugging of IP cores. In this exercise, we communicated with the device over a JTAG link, but you can also use other communication channels, such as TCP/IP making the tool useful for remote debug as well. For more details on using System Console check out the dedicated web page here.