8000 GitHub - htminuslab/Efinix_cli: Simple example to run Efinix P&R tools from the command line
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

htminuslab/Efinix_cli

Repository files navigation

Efinix_cli

Simple example on how to generate an Efinity project file to fully use the command line.

1. Introduction

It it my understanding that Efinix Efinity 2024.x Python API does not yet support generating XML project files which are required to run a project from the command line. In the supplied simple example below I use a Python script (thanks ChatGPT) to generate the XML project file. The rtl files and constraints are read from a text file.

2. Command Line Flow

Step 1: I/O pin file

I use the GUI Interface Designer to generate the interface scripting file (*.isf). You can also use the Efinity Python API to generate an XML periphery file but I think using the GUI is easier as in most cases you only have to do it once. For the next project you simply modify the *.isf file. While you are in the Interface Designer GUI I would also create the SDC file especially if you are using a PLL.

Step 2: Create a parameter text file

The file for this example is called params.txt and it contains a list of your input files (RTL/SDC/ISF) and some constrains.

# Project info
project.name=led_test
project.description=Simple LED test

# Device info
device.family=Trion
device.device=T20Q100F3
device.timing_model=C4

# Design info
design.def_veri_version=verilog_2k
design.def_vhdl_version=vhdl_2008
design.unified_flow=false

design.top_module=top
design.top_vhdl_arch=rtl

design.design_file1.name=rtl/ledtest.vhd
design.design_file1.library=default

design.design_file2.name=rtl/top.sv
design.design_file2.library=default


# Constraint info
constraint.sdc_file=led_test.pt.sdc
constraint.isf_file=led_test_io.isf

# Synthesis params
synthesis.hdl-loop-limit=20000

# Place_and_route params
place_and_route.optimization_level=TIMING_1

# Bitstream_generation params
bitstream_generation.mode=passive
bitstream_generation.width=1
bitstream_generation.generate_hex=on

Step 3: Generate the XML project file

H:\GitHub\Efinix_cli>python generate_xml.py
XML file 'generated_project.xml' generated successfully.

Step 4: Run Efinix P&R

H:\GitHub\Efinix_cli>efx_run.bat generated_project.xml --flow compile
Creating H:\GitHub\Efinix_cli\outflow
Running: efx_run_map.py led_test --family Trion --device T20Q100F3 --project_xml H:\GitHub\Efinix_cli\generated_project.xml --output_dir outflow --opt root=top --opt arch=rtl --opt veri_options=verilog_mode=verilog_2k,vhdl_mode=vhdl_2008
   map :        PASS
Running: efx_run_pt_unified.py led_test Trion T20Q100F3 --output_dir outflow --timing_model C4 --project_xml generated_project.xml
   interface :  PASS
Running: efx_run_pnr.py led_test --prj --family Trion --device T20Q100F3 --timing_model C4 --sim --output_dir outflow --opt sdc_file=ledtest.sdc --opt optimization_level=TIMING_1
   pnr :        PASS
Running: efx_run_pgm.py led_test --family Trion --device T20Q100F3 --output_dir outflow --opt mode=passive width=1
   pgm :        PASS

3. Verbose Output of efx_run.py

As of Efinity 2025.1 there is unfortunately no verbose output option for the command line option, this means that when you run efx_run.bat you have to check the various log file in the outflow directory at the end of the run. Luckily Efinix are kind enough to provide the full Python code for efx_run so you can make some changes until Efinix adds this feature.

To stream the warning and errors to both stdout an a log file modify <efinity_install_dir>\2025.1\scripts\efx_run.py

Around line 868 you will find the pre_run(args) function:

# some common preparation steps
def pre_run(args):

    # print out stage
    print('Running: ' + ' '.join(str(arg) for arg in sys.argv))

    # redirect stdout+stderr to log file
    sys.stdout = open(args.LOG_FILE, 'a')
    sys.stderr = sys.stdout  

    # print out stage (this time to log)
    print('Running: ' + ' '.join(str(arg) for arg in sys.argv))
    sys.stdout.flush()

    # save the offset to do error logging from here
    args.LOG_OFFSET = sys.stdout.tell()

Replace it with the code below:

class TeeOutput: # HABT stream both to stdout/logfile
    def __init__(self, log_file_path):
        self.file = open(log_file_path, 'a', buffering=1)
        self.stdout = sys.stdout

    def write(self, message):
        self.file.write(message)
        self.file.flush()
        if not message.startswith("INFO     :"):
            self.stdout.write(message)
            self.stdout.flush()

    def flush(self):
        self.stdout.flush()
        self.file.flush()

    def close(self):
        self.file.close()
        sys.stdout = self.stdout  # Restore original stdout
        
    def fileno(self):
        return self.file.fileno()

# some common preparation steps
def pre_run(args):

    # print out stage
    print('Running: ' + ' '.join(str(arg) for arg in sys.argv))

    # redirect stdout+stderr to log file
    # sys.stdout = open(args.LOG_FILE, 'a')
    sys.stdout = TeeOutput(args.LOG_FILE)  # HABT stream both to stdout/logfile
    sys.stderr = sys.stdout  

    # print out stage (this time to log)
    print('Running: ' + ' '.join(str(arg) for arg in sys.argv))
    sys.stdout.flush()

    # save the offset to do error logging from here
    # args.LOG_OFFSET = sys.stdout.tell()
    args.LOG_OFFSET = sys.stdout.file.tell() # HABT stream both to stdout/logfile

Note that it filters out the “INFO” lines for stdout but you add it back by removing the “if not message.startswith…” line.

You should now see all the warnings and errors whilst efx_run is running:

WARNING  : Mapping into logic memory block 'U_CPU/U_BIU/U_FIFO/mem__D$2' (64 bits) (H:\HTL32IMC\RTL\syncfifo.vhd:48) because size is too small (<=64) [EFX-0657]
WARNING  : Mapping into logic memory block 'U_CPU/U_BIU/U_FIFO/mem__D$b12' (64 bits) (H:\HTL32IMC\RTL\syncfifo.vhd:48) because size is too small (<=64) [EFX-0657]
WARNING  : Mapping into logic memory block 'U_CPU/U_BIU/U_FIFO/mem__D$c1' (64 bits) (H:\HTL32IMC\RTL\syncfifo.vhd:48) because size is too small (<=64) [EFX-0657]
WARNING  : H:\HTL32IMC\Testbench\rv32sys_struct.vhd(36): Input/inout port RX1 is unconnected and will be removed. [VDB-8003]
WARNING  : Found 1 warnings in the post-synthesis netlist.
Stage completed: map
   map :        PASS
Running: efx_run_pt_unified.py rv32sys Trion T20Q100F3 --output_dir outflow --timing_model C4 --project_xml generated_project.xml
Running: efx_run_pt_unified.py rv32sys Trion T20Q100F3 --output_dir outflow --timing_model C4 --project_xml generated_project.xml
Running: H:/Vendors/Efinity/2025.1\python311\bin\python.exe H:\Vendors\Efinity\2025.1\scripts\efx_run_pt_unified.py rv32sys Trion T20Q100F3 --output_dir outflow --timing_model C4 --project_xml generated_project.xml
Stage completed: interface
   interface :  PASS

4. Further enhancements

Rather than looking at the report files in the outflow directory you can simply display the relevant info at the end of the run (chatgpt generated Python):

H:\GitHub\Efinix_cli>python results.py outflow/led_test.place.rpt "Resource Summary (begin)" "Resource Summary (end)"
Inputs: 3 / 163 (1.84%)
Outputs: 3 / 347 (0.86%)
Clocks: 1 / 16 (6.25%)
Logic Elements: 26 / 19728 (0.13%)
LE: LUTs/Adders: 25 / 19728 (0.13%)
LE: Registers: 24 / 13920 (0.17%)
Memory Blocks: 0 / 204 (0.00%)
Multipliers: 0 / 36 (0.00%)

H:\GitHub\Efinix_cli>python results.py outflow/led_test.timing.rpt "Frequency Summary (begin)" "Frequency Summary (end)"

User target constrained clocks
Clock Name  Period (ns)  Frequency (MHz)   Waveform      Targets
PLL_OUT       1.000        1000.000     {0.000 0.500}  {PLL_OUT}

Maximum possible analyzed clocks frequency
Clock Name  Period (ns)  Frequency (MHz)     Edge
PLL_OUT       2.503        399.521         (R-R)

Geomean max period: 2.503

5. Some further comments

If you want to add/modify any of the parameters in params.txt simply load the generated xml project in the GUI, this will add all(?) parameters to the xml project file. Open the xml file in an editor and extract any parameters you want to use and add them to the parameter file. For example if you want to increase the P&R effort look for:

<efx:param name="placer_effort_level" value="5" value_type="e_option"/>

and update your params.txt with:

place_and_route.placer_effort_level=5

Now put all commands in batch file together with your download utility....

About

Simple example to run Efinix P&R tools from the command line

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published
0