I tried debugging from Python via System Console

Introduction

System Console is a tool included in Quartus Prime that allows you to debug FPGAs via JTAG. Since you can hit registers and check values ​​in real time from the command line, it is useful for debugging on an actual machine. Regarding how to use it, there is a Very easy-to-understand article on Macnica's page, so I will leave it to you. This article will show you how to work with the System Console from a Python program.

environment

OS: CentOS7 (I think it works on other OS) Intel FPGA Tools: 20.1 Python: 3.6

code

Change the system_console_path part of the third line of the code below to suit your environment.

import subprocess

system_console_path = '/eda/intel/20.2/quartus/sopc_builder/bin/system-console'

class altera_system_console:
    def __init__(self):
        sc_path = [system_console_path, '--cli', '--disable_readline']
        self.console = subprocess.Popen(sc_path, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
        self.cmd_count = 1
        self.read_output()

    def __del__(self):
        self.console.terminate()

    def read_output(self, print_flag=True):
        if self.cmd_count == 0:
            print('cmd_count is zero')
            return ''
        txt = ''
        while True:
            r = self.console.stdout.read(1)
            if r == b'%':
                self.console.stdout.read(1)
                if print_flag:
                    print(txt)
                break
            txt += r.decode("utf8")
        self.cmd_count -= 1
        return txt

    def cmd(self, cmd_string, print_flag=True):
        self.console.stdin.write(bytes(cmd_string + '\n', 'utf-8'))
        self.console.stdin.flush()
        self.cmd_count += 1
        return self.read_output(print_flag)

    def write(self, addr, data, bits=32, print_flag=True):
        if not bits in [8, 16, 32]:
            print('bits is an invalid value')
        return self.cmd('master_write_{} $master_path 0x{:x} 0x{:x}'.format(bits, addr, data), print_flag=print_flag)

    def read(self, addr, length, bits=32, print_flag=True):
        if not bits in [8, 16, 32]:
            print('bits is an invalid value')
        self.cmd('master_read_{} $master_path 0x{:x} 0x{:x}'.format(bits, addr, length), print_flag=print_flag)


c = altera_system_console()

How to use

This time, we'll use Python's interactive mode. Save the above code as system_console.py and execute the following command to switch to interactive mode with system_console.py executed to the end.

python3 -i system_console.py

If all goes well, you will see the output of the System Console.

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
 Welcome to Intel's FPGA System Console

 This Tcl console provides access to the hardware modules instantiated in your
 FPGA. You can use System Console for all of the following purposes:

    * To start, stop, or step a Nios II processor
    * To read or write Avalon Memory-Mapped (Avalon-MM) slaves using special
     masters
    * To sample the SOPC system clock as well as system reset signal
    * To run JTAG loopback tests to analyze board noise problems
    * To shift arbitrary instruction register and data register values to
     instantiated system level debug (SLD) nodes

 In addition, the directory <QuartusII Dir>/sopc_builder/system_console/scripts
 contains Tcl files that provide miscellaneous utilities and examples of how to
 access the functionality provided. You can include those macros in your
 scripts by issuing Tcl source commands.
--------------------------------------------------------------------------------

>>>

From this state, you can enter commands for System Console by entering c.cmd ('commands you want to enter for System Console'). For example, you can connect to the service (see Macnica's page (https://www.macnica.co.jp/business/semiconductor/articles/intel/134097/)) as follows. The right side of > >> is the command you are typing, and below that is the output of the System Console.

>>> _ = c.cmd('get_service_paths master')
{/devices/10AX115H(1|2|3|4|4E3)|..@1#1-9/(link)/JTAG/(110:132 v1 #0)/phy_0/master} {/devices/10AX115H(1|2|3|4|4E3)|..@1#1-9/(link)/JTAG/(70:34 v3 #0)/nios2_0} {/devices/5M(1270ZF324|2210Z)|EPM2210@2#1-9/(link)/JTAG/(110:130 v3 #0)/jtagmem_0}

>>> _ = c.cmd('set mpath [lindex [get_service_paths master] 1]')
/devices/10AX115H(1|2|3|4|4E3)|..@1#1-9/(link)/JTAG/(70:34 v3 #0)/nios2_0

>>> _ = c.cmd('claim_service master $mpath ""')
/channels/local/(lib)/master_1

>>> _ = c.cmd('set master_path [claim_service master $mpath ""]')
/channels/local/(lib)/master_2

You can also read and write to the address in the same way.

>>> _ = c.cmd('master_read_32 $master_path 0x40000000 1')
0x22222222

>>> _ = c.cmd('master_write_32 $master_path 0x40000000 0x11111111')

>>> _ = c.cmd('master_read_32 $master_path 0x40000000 1')
0x11111111

You can also read and write to the address as shown below by adding the write and read methods to the altera_system_console class.

>>> _ = c.write(0x40000004, 0x33333333)

>>> _ = c.read(0x40000000, 0x2)
0x11111111 0x33333333

>>> for i in range(10):
...     _ = c.write(0x40000000 | i * 4, i, print_flag=False)
... 
>>> _ = c.read(0x40000000, 0xA)
0x00000000 0x00000001 0x00000002 0x00000003 0x00000004 0x00000005 0x00000006 0x00000007 0x00000008 0x00000009

What kind of place is convenient?

I think the following are some of the good things about debugging via Python. --Fixed work (connection to service, etc.) required when starting System Console can be described in the Python program in advance. --A series of processing required for debugging can be made into a function or a class. --You can easily write data mechanically using a for statement, or change the processing depending on the output result with an if statement. Also, in combination with the VS Code function, in VS Code, if you press Shift + Enter with the code selected, you can enter the code into the console in interactive mode, and while writing the debug command, it It is very convenient because you can check in real time in interactive mode. ezgif.com-gif-maker (1).gif

Recommended Posts

I tried debugging from Python via System Console
I tried using UnityCloudBuild API from Python
I tried Python> autopep8
I tried Python! ] I graduated today from "What is Python! Python!"!
I tried Python> decorator
I tried using TradeWave (BitCoin system trading in Python)
I tried running python etc. from a bat file
I tried scraping with Python
I tried Python C extension
[Python] I tried using OpenPose
I tried gRPC with Python
I tried scraping with python
I tried to create API list.csv in Python from swagger.yaml
I tried sending an email from Amazon SES with Python
I tried face recognition from the video (OpenCV: python version)
I tried changing the python script from 2.7.11 to 3.6.0 on windows10
I tried to touch Python (installation)
I tried web scraping with python.
I tried using Thonny (Python / IDE)
I tried Grumpy (Go running Python).
I tried task queuing from Celery
I tried running prolog with python 3.8.2.
I tried Line notification in Python
I tried SMTP communication with Python
[Python] I tried using YOLO v3
Movement that changes direction in the coordinate system I tried Python 3
[System trade] I tried playing with Stochastic Oscillator by decomposing with python ♬
I tried scraping conversation data from Askfm
[Data science basics] I tried saving from csv to mysql with python
I tried to implement permutation in Python
Wrangle x Python book I tried it [2]
I tried scraping Yahoo News with Python
I tried LeetCode every day 26. Remove Duplicates from Sorted Array (Python, Go)
I tried to implement PLSA in Python 2
Python3 standard input I tried to summarize
I tried sending an email with python.
I tried using Bayesian Optimization in Python
I tried non-photorealistic rendering with Python + opencv
I tried to implement ADALINE in Python
What I got from Python Boot Camp
I tried a functional language with Python
I tried recursion with Python ② (Fibonacci sequence)
I tried to implement PPO in Python
Python: I tried the traveling salesman problem
Wrangle x Python book I tried it [1]
Mayungo's Python Learning Episode 8: I tried input
[Python] I tried to calculate TF-IDF steadily
I tried scraping Yahoo weather (Python edition)
L-Chika TWE Lite from Python via ToCoStick
I tried to touch Python (basic syntax)
I tried using Headless Chrome from Selenium
[Lambda] I tried to incorporate an external module of python via S3
I tried the Python Tornado Testing Framework
#I tried something like Vlookup with Python # 2
[Python] [Natural language processing] I tried Deep Learning ❷ made from scratch in Japanese ①
I tried using Google Translate from Python and it was just too easy
I tried to easily create a fully automatic attendance system with Selenium + Python
[IBM Cloud] I tried to access the Db2 on Cloud table from Cloud Funtions (python)
I tried running two Jetson Nano hardware PWMs from the Jetson.GPIO Python library.
[Python] I tried to get the type name as a string from the type function
[Python] I tried the same calculation as LSTM predict with from scratch [Keras]