YosysHQ / oss-cad-suite-build

Multi-platform nightly builds of open source digital design and verification tools
ISC License
742 stars 67 forks source link

Cocotb clashes with cocotb installed in venv #80

Open TheZoq2 opened 11 months ago

TheZoq2 commented 11 months ago

I'm not sure this is a supported use case, it seems like having oss-cad-suite in path at the same time as having a venv-installed cocotb version results in a glibc linker error on arch linux

Steps to reproduce

Create a cocotb "project" as follows

test_my_design.py

# test_my_design.py (simple)

import cocotb
from cocotb.triggers import Timer

@cocotb.test()
async def my_first_test(dut):
    """Try accessing the design."""

    for cycle in range(10):
        dut.clk.value = 0
        await Timer(1, units="ns")
        dut.clk.value = 1
        await Timer(1, units="ns")

    dut._log.info("my_signal_1 is %s", dut.my_signal_1.value)
    assert dut.my_signal_2.value[0] == 0, "my_signal_2[0] is not 0!"

my_design.sv

// This file is public domain, it can be freely copied without restrictions.
// SPDX-License-Identifier: CC0-1.0

module my_design(input logic clk);

  timeunit 1ns;
  timeprecision 1ns;

  logic my_signal_1;
  logic my_signal_2;

  assign my_signal_1 = 1'bx;
  assign my_signal_2 = 0;

endmodule

Makefile

# Makefile

# defaults
SIM ?= icarus
TOPLEVEL_LANG ?= verilog

VERILOG_SOURCES += $(PWD)/my_design.sv
# use VHDL_SOURCES for VHDL files

# TOPLEVEL is the name of the toplevel module in your Verilog or VHDL file
TOPLEVEL = my_design

# MODULE is the basename of the Python test file
MODULE = test_my_design

# include cocotb's make rules to take care of the simulator setup
include $(shell cocotb-config --makefiles)/Makefile.sim

Then create a venv, activate it, and install cocotb with pip

python3 -m venv venv
source venv/bin/activate
pip install cocotb

Running make now results in

rm -f results.xml
make -f Makefile results.xml
make[1]: Entering directory '/tmp/cocotb_test'
rm -f results.xml
MODULE=test_my_design TESTCASE= TOPLEVEL=my_design TOPLEVEL_LANG=verilog \
         /home/frans/bin/oss-cad-suite/bin/vvp -M /tmp/cocotb_test/venv/lib/python3.11/site-packages/cocotb/libs -m libcocotbvpi_icarus   sim_build/sim.vvp
     -.--ns ERROR    gpi                                ..s/cocotb_utils.cpp:68   in utils_dyn_open                  Unable to open lib /usr/lib/libpython3.11.so.1.0: /home/frans/bin/oss-cad-suite/lib/libm.so.6: version `GLIBC_2.35' not found (required by /usr/lib/libpython3.11.so.1.0)
     -.--ns INFO     gpi                                ../gpi/GpiCommon.cpp:101  in gpi_print_registered_impl       VPI registered
ERROR: results.xml was not written by the simulation!
make[1]: *** [/tmp/cocotb_test/venv/lib/python3.11/site-packages/cocotb/share/makefiles/simulators/Makefile.icarus:96: results.xml] Error 1
make[1]: Leaving directory '/tmp/cocotb_test'
make: *** [/tmp/cocotb_test/venv/lib/python3.11/site-packages/cocotb/share/makefiles/Makefile.inc:40: sim] Error 2

Not cativating the venv, or not having oss-cad suite in PATH results in the expected output

rm -f results.xml
"make" -f Makefile results.xml
make[1]: Entering directory '/tmp/cocotb_test'
rm -f results.xml
MODULE=test_my_design TESTCASE= TOPLEVEL=my_design TOPLEVEL_LANG=verilog \
         /home/frans/bin/oss-cad-suite/bin/vvp -M /home/frans/bin/oss-cad-suite/lib/python3.8/site-packages/cocotb-1.9.0.dev0-py3.8-linux-x86_64.egg/cocotb/libs -m libcocotbvpi_icarus   sim_build/sim.vvp
     -.--ns INFO     gpi                                ..mbed/gpi_embed.cpp:76   in set_program_name_in_venv        Did not detect Python virtual environment. Using system-wide Python interpreter
     -.--ns INFO     gpi                                ../gpi/GpiCommon.cpp:101  in gpi_print_registered_impl       VPI registered
     0.00ns INFO     cocotb                             Running on Icarus Verilog version 13.0 (devel)
     0.00ns INFO     cocotb                             Running tests with cocotb v1.9.0.dev0 from /home/frans/bin/oss-cad-suite/lib/python3.8/site-packages/cocotb-1.9.0.dev0-py3.8-linux-x86_64.egg/cocotb
     0.00ns INFO     cocotb                             Seeding Python random module with 1692282682
     0.00ns INFO     cocotb.regression                  Found test test_my_design.my_first_test
     0.00ns INFO     cocotb.regression                  running my_first_test (1/1)
                                                          Try accessing the design.
    20.00ns INFO     cocotb.my_design                   my_signal_1 is x
    20.00ns INFO     cocotb.regression                  my_first_test passed
    20.00ns INFO     cocotb.regression                  **************************************************************************************
                                                        ** TEST                          STATUS  SIM TIME (ns)  REAL TIME (s)  RATIO (ns/s) **
                                                        **************************************************************************************
                                                        ** test_my_design.my_first_test   PASS          20.00           0.00      12651.23  **
                                                        **************************************************************************************
                                                        ** TESTS=1 PASS=1 FAIL=0 SKIP=0                 20.00           0.05        364.21  **
                                                        **************************************************************************************

make[1]: Leaving directory '/tmp/cocotb_test'

This is on an up to date Arch system with the latest oss-cad-suite

TheZoq2 commented 11 months ago

I've done some further investigation into this. Naturally, when I create a venv with my system python, that venv will use the system python too which seems to cause conflicts.

I still want a venv because I would like to install some additional dependencies per project, so I figured I could create a venv using the python version that oss-cad-suite provides, i.e.

> tabbypy3 -m venv tabbyvenv                           
Error: Command '['/tmp/cocotb_test/test/bin/tabbypy3', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 127.

However, that seems to fail half way through the creation process. Running that raw command gives

/tmp/cocotb_test/tabbyvenv/bin/tabbypy3: line 10: /tmp/cocotb_test/tabbyvenv/lib/ld-linux-x86-64.so.2: No such file or directory
TheZoq2 commented 11 months ago

And another update: Not being able to create venvs with the cad suite seems to be because release_bindir does not resolve symlinks. So when python3 -m venv venv tries to run python, it runs python3 which is a symlink in venv/bin/python3 which points to tabbypy3

However, tabbypy3 relies on the location of the script as it was invoked without resolving symlinks, it therefore thinks that oss-cad-suite is installed invenv and the last exec call looks for the cad suite libraries in the venv.

I attempted to fix this by following the symlink as release_bindir="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"

But that updates PYTHONEXECUTABLE to the tabbycad install location, overriding the venv (maybe?, I still don't understand how python figures out which venv is active)

TheZoq2 commented 11 months ago

Ok, I think I have figured out a fix that works for me. I don't know if it is worth upstreaming it since I don't really know what i'm doing, my use case might be strange etc. But I figure it is worth posting this for others who run into similar issues

Python seems to determine venvs partially based on where the python executable being run is, before resolving symlinks so that needs to be set correctly. oss-cad-suite on the other hand relies on the executable location to be where the cad suite is installed, not following symlinks.

Modifying tabbypy3 to this. i.e. resolving the symlink for release_bindir and setting PYTHONEXECUTABLE to whatever invoked tabbypy3, rather than the resolved exe. PYTHONHOME seems to not do much, not sure if it is needed for something else

#!/usr/bin/env bash
release_bindir="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"
release_bindir_abs="$(readlink -f "$release_bindir")"
release_topdir_abs="$(readlink -f "$release_bindir/..")"
export PATH="$release_bindir_abs:$PATH"
export PYTHONEXECUTABLE="${BASH_SOURCE[0]}"
# export PYTHONEXECUTABLE="$release_topdir_abs/bin/tabbypy3"
# export PYTHONHOME="$release_topdir_abs"
export PYTHONNOUSERSITE=1
export SSL_CERT_FILE="$release_topdir_abs"/etc/cacert.pem
exec "$release_topdir_abs"/lib/ld-linux-x86-64.so.2 --inhibit-cache --inhibit-rpath "" --library-path "$release_topdir_abs"/lib "$release_topdir_abs"/libexec/python3.8 "$@"

Seems to resolve my issues, namely, oss-cad-sutie works to the point where cocotb works, both with and without virtual environments

To use it in a venv, you can make a new venv with tabbypy3 -m venv venv --system-site-packages. The flag is required in order for pip to work, though crucially, you need to run pip as python3 -m pip, not just pip as that uses the system version

TheZoq2 commented 4 months ago

As discussed in discord, this workflow breaks with the ubuntu bump, so libpthread will need to be added to the bundle

mmicko commented 4 months ago

File is added now in release, and I have rebuilt releases, so please do try if it fixes complete flow now. Thanks

TheZoq2 commented 4 months ago

Thanks for the quick fix! It does seem to work.

Unfortunately, now i'm running into some problems which I think are due to cocotb being bumped to 2.0-dev. It feels fixable by installing cocotb from pip, but I can't seem to get that to work