PyTCL allows control EDA tools directly from Python that use TCL
Project description
PyTCL
PyTCL allows control EDA tools directly from Python that use TCL.
Features
- It executes Python method with provided positional arguments directly as TCL procedure
For example invocation of Python
<object>.<name>(*args)method is like calling TCL procedure<name> {*}${args} - Any Python value is converted to TCL value like for example Python
listto TCL list - Result from invoked TCL procedure is returned as
pytcl.TCLValuethat can handle any TCL value (that is represented always as string) to Pythonstr,int,bool,float,list,dict, ... - TCL error is returned as Python exception
pytcl.TCLError - High performance and very low (unnoticeable) overhead by using Unix domain sockets for communication between Python and TCL in streamable way (sockets are always open and ready)
- It allows to create and access TCL variables from Python side. Please see tests/test_tclsh.py for some examples
- It can work with any EDA tool. Please see tests/test_vivado.py how to use bare
PyTCLclass for that - No external dependencies
Install
pip install pytcl-eda
Examples
Creating new Vivado project:
#!/usr/bin/env python3
from pathlib import Path
from pytcl import Vivado
def main() -> None:
"""Create new Vivado project."""
hdl_dir: Path = Path.cwd() / "hdl"
project_dir: Path = Path.cwd() / "my-awesome-project"
with Vivado() as vivado:
# See Vivado Design Suite Tcl Command Reference Guide (UG835) for all available Vivado TCL procedures
# https://docs.amd.com/r/en-US/ug835-vivado-tcl-commands
vivado.create_project(project_dir.name, project_dir)
vivado.add_files(hdl_dir / "my_awesome_design.sv")
synthesis_runs = list(vivado.get_runs("synth_*"))
implementation_runs = list(vivado.get_runs("impl_*"))
vivado.launch_runs(synthesis_runs)
# wait_on_runs was introduced in Vivado 2021.2. For backward compatibility we will use wait_on_run
# https://docs.amd.com/r/2021.2-English/ug835-vivado-tcl-commands/wait_on_runs
# Vivado >= 2021.2 can just use: vivado.wait_on_runs(synthesis_runs)
for run in synthesis_runs:
vivado.wait_on_run(run)
vivado.launch_runs(implementation_runs)
for run in implementation_runs:
vivado.wait_on_run(run)
vivado.close_project()
if __name__ == "__main__":
main()
To use any EDA tool where PyTCL doesn't provide neat helper classes like pytcl.Vivado
you can use the pytcl.PyTCL class directly:
#!/usr/bin/env python3
from pathlib import Path
from pytcl import PyTCL
def main() -> None:
"""Create new Vivado project."""
project_dir: Path = Path.cwd() / "my-awesome-project"
# PyTCL offers some string placeholders {} that you can use:
# {tcl} -> it will insert <pytcl>/execute.tcl
# {receiver} -> it will insert <pytcl>/receiver.tcl
# {rx} -> it will insert /tmp/pytcl-XXXXX/rx.sock
# {sender} -> it will insert <pytcl>/sender.tcl
# {tx} -> it will insert /tmp/pytcl-XXXXX/tx.sock
# {args} -> it will insert '{receier} {rx} {sender} {tx}' in one go
cmd: list[str] = [
"vivado",
"-nojournal",
"-notrace",
"-nolog",
"-mode",
"batch",
"-source",
"{tcl}",
"-tclargs",
"{receiver}",
"{rx}",
"{sender}",
"{tx}",
]
with PyTCL(*cmd) as vivado:
vivado.create_project(project_dir.name, project_dir)
# Do the same magic that you would normally do in TCL
vivado.close_project()
if __name__ == "__main__":
main()
Architecture
stateDiagram-v2
direction LR
PyTCL --> rx.sock: send()
rx.sock --> receiver.py: string
state tool {
receiver.py --> execute.tcl: stdin
execute.tcl --> sender.py: stdout
}
sender.py --> tx.sock: NDJSON
tx.sock --> PyTCL: recv()
PyTCLwill start new receiver listened on Unix domain socket/tmp/pytcl-XXXX/tx.sockfor any incoming NDJSON messages{"result": "<tcl-result>", "status": <tcl-status>}fromexecute.tclscript filePyTCLwill call command line tool (by defaulttclsh) withexecute.tclscript file and argumentsreceiver.py /tmp/pytcl-XXXX/rx.sock sender.py /tmp/pytcl-XXXX/tx.sock- Started
execute.tclwill create own listener with Unix domain socket/tmp/pytcl-XXXX/rx.sockto receive incoming TCL expressions fromPyTCL PyTCLwill start new client and connect to Unix domain socket/tmp/pytcl-XXXX/rx.sockto send TCL expressions with arguments to be evaluated byexecute.tclscript filePyTCLwill transform any Python method call<object>.<name>(*args)to TCL expression<name> {*}${args}PyTCLwill send TCL expression toexecute.tclusing Unix domain socket/tmp/pytcl-XXXX/rx.sockexecute.tclwill receive TCL expressions from Unix domain socket/tmp/pytcl-XXXX/rx.sock- Received TCL expression is evaluated by TCL
evalwithin TCLcatch - TCL result and status from evaluated TCL expression will be packed into NDJSON message
{"result": "<tcl-result>", "status": <tcl-status>} - Packed NDJSON message with TCL result and status will be send back to
PyTCL PyTCLwill return received NDJSON message aspytcl.TCLValuePyTCLwill raise a Python exceptionpytcl.TCLErrorif received TCL status was non-zero
Development
Create Python virtual environment:
python3 -m venv .venv
Activate created Python virtual environment:
. .venv/bin/activate
Upgrade pip:
pip install --upgrade pip
Install project in editable mode with pytest:
pip install --editable .[test]
Run tests:
pytest
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pytcl_eda-0.2.1.tar.gz.
File metadata
- Download URL: pytcl_eda-0.2.1.tar.gz
- Upload date:
- Size: 14.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e3fa21db707e6557889d21994a59e97ddd57e282565a12b1abe28d5f680e800a
|
|
| MD5 |
4e65d859153628e71ee7888e8865e05a
|
|
| BLAKE2b-256 |
b8e894bdf8133b31e34158ee7877f81ea069672fd71c3d571324387f8ecc769a
|
File details
Details for the file pytcl_eda-0.2.1-py3-none-any.whl.
File metadata
- Download URL: pytcl_eda-0.2.1-py3-none-any.whl
- Upload date:
- Size: 11.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0293a14aea3b814ad05aede81501e45c2ed129d4af99b11a8678943ca747989d
|
|
| MD5 |
79c741dab11315882c7fcb1ab489cc13
|
|
| BLAKE2b-256 |
bc53b442a85f9fff0311c1b9a14e8f1f14073b180dad1444d37943d7247b9ccc
|