greatscottgadgets / luna

Amaranth HDL framework for monitoring, hacking, and developing USB devices
https://greatscottgadgets.com/cynthion/
BSD 3-Clause "New" or "Revised" License
991 stars 171 forks source link

platform: recover dynamic detection of the FPGA type, when possible #241

Closed mndza closed 7 months ago

mndza commented 8 months ago

This ability was lost after 88ccb0983321bd0c694e0a10646191ad926ec913.

grvvy commented 8 months ago

Some notes from testing this locally:

I don't have to set LUNA_PLATFORM at all which is great. In order to get this running I had to add a few things (some of which exist in #237), like adding "apollo_fpga @ git+https://github.com/greatscottgadgets/apollo.git", to pyproject.toml and the following modifications to /ci-scripts/build.sh:

pip install "cynthion @ git+https://github.com/greatscottgadgets/cynthion/#subdirectory=cynthion/python/"
pip install "amaranth-stdio @ git+https://github.com/amaranth-lang/amaranth-stdio@4a14bb17"

The following are all back-to-back runs of interactive-test.py from within a python venv using oss-cad-suite-linux-x64-20240327 and both the "debug/alt" and "control host" ports (left side ports) connected on an r0.4 board. Connecting only debug/alt always results in the (bitstream provides data past the device's SRAM array / ffffffff) error.

grvvy@oliver:~/repos/luna$ ./ci-scripts/test.sh 
INFO    | __init__    | Building and uploading gateware to attached Cynthion r0.4...
Traceback (most recent call last):
  File "/home/grvvy/repos/luna/applets/interactive-test.py", line 295, in <module>
    tester = top_level_cli(InteractiveSelftest)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/luna/__init__.py", line 113, in top_level_cli
    products = platform.build(fragment,
               ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/amaranth/build/plat.py", line 113, in build
    self.toolchain_program(products, name, **(program_opts or {}))
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/cynthion/gateware/platform/core.py", line 79, in toolchain_program
    programmer.configure(bitstream)
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/apollo_fpga/ecp5.py", line 442, in configure
    self._execute_command(self.Opcode.ISC_ERASE, b"\x01", wait_for_completion=True, check_status=True)
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/apollo_fpga/ecp5.py", line 998, in _execute_command
    self._validate_status(status, extra_verbose=True)
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/apollo_fpga/ecp5.py", line 334, in _validate_status
    error_handler("Failed to execute last command!{}".format(error_text))
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/apollo_fpga/ecp5.py", line 318, in raise_error
    raise IOError(msg)
OSError: Failed to execute last command! (bitstream provides data past the device's SRAM array / ffffffff)

grvvy@oliver:~/repos/luna$ ./ci-scripts/test.sh 
/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/apollo_fpga/jtag.py:582: UserWarning: TDO appears to be stuck at '1'. Board I/O may be interfering; try 'apollo force-offline' first.
  warn("TDO appears to be stuck at '1'. Board I/O may be interfering; try 'apollo force-offline' first.")
INFO    | __init__    | Building and uploading gateware to attached Cynthion r0.4...
Traceback (most recent call last):
  File "/home/grvvy/repos/luna/applets/interactive-test.py", line 295, in <module>
    tester = top_level_cli(InteractiveSelftest)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/luna/__init__.py", line 113, in top_level_cli
    products = platform.build(fragment,
               ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/amaranth/build/plat.py", line 113, in build
    self.toolchain_program(products, name, **(program_opts or {}))
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/cynthion/gateware/platform/core.py", line 79, in toolchain_program
    programmer.configure(bitstream)
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/apollo_fpga/ecp5.py", line 421, in configure
    self._restart_configuration_process()
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/apollo_fpga/ecp5.py", line 490, in _restart_configuration_process
    self._execute_command(self.Opcode.LSC_REFRESH, wait_for_completion=True, check_status=False)
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/apollo_fpga/ecp5.py", line 994, in _execute_command
    self._wait_for_completion(context=opcode)
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/apollo_fpga/ecp5.py", line 551, in _wait_for_completion
    raise IOError("ECP5 request timed out waiting for completion (context: {})".format(context))
OSError: ECP5 request timed out waiting for completion (context: 121)

grvvy@oliver:~/repos/luna$ ./ci-scripts/test.sh 
INFO    | __init__    | Building and uploading gateware to attached Cynthion r0.4...
Traceback (most recent call last):
  File "/home/grvvy/repos/luna/applets/interactive-test.py", line 295, in <module>
    tester = top_level_cli(InteractiveSelftest)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/luna/__init__.py", line 113, in top_level_cli
    products = platform.build(fragment,
               ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/amaranth/build/plat.py", line 113, in build
    self.toolchain_program(products, name, **(program_opts or {}))
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/cynthion/gateware/platform/core.py", line 79, in toolchain_program
    programmer.configure(bitstream)
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/apollo_fpga/ecp5.py", line 428, in configure
    self._capture_part_id()
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/apollo_fpga/ecp5.py", line 509, in _capture_part_id
    raise IOError("Could not detect a connected FPGA (ID: {:08x}). Check your wiring?".format(self.part_id))
OSError: Could not detect a connected FPGA (ID: ffffffff). Check your wiring?

grvvy@oliver:~/repos/luna$ ./ci-scripts/test.sh 
/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/apollo_fpga/jtag.py:582: UserWarning: TDO appears to be stuck at '1'. Board I/O may be interfering; try 'apollo force-offline' first.
  warn("TDO appears to be stuck at '1'. Board I/O may be interfering; try 'apollo force-offline' first.")
INFO    | __init__    | Building and uploading gateware to attached Cynthion r0.4...
Traceback (most recent call last):
  File "/home/grvvy/repos/luna/applets/interactive-test.py", line 295, in <module>
    tester = top_level_cli(InteractiveSelftest)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/luna/__init__.py", line 113, in top_level_cli
    products = platform.build(fragment,
               ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/amaranth/build/plat.py", line 113, in build
    self.toolchain_program(products, name, **(program_opts or {}))
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/cynthion/gateware/platform/core.py", line 79, in toolchain_program
    programmer.configure(bitstream)
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/apollo_fpga/ecp5.py", line 428, in configure
    self._capture_part_id()
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/apollo_fpga/ecp5.py", line 509, in _capture_part_id
    raise IOError("Could not detect a connected FPGA (ID: {:08x}). Check your wiring?".format(self.part_id))
OSError: Could not detect a connected FPGA (ID: ffffffff). Check your wiring?

grvvy@oliver:~/repos/luna$ ./ci-scripts/test.sh 
INFO    | __init__    | Building and uploading gateware to attached Cynthion r0.4...
Traceback (most recent call last):
  File "/home/grvvy/repos/luna/applets/interactive-test.py", line 295, in <module>
    tester = top_level_cli(InteractiveSelftest)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/luna/__init__.py", line 113, in top_level_cli
    products = platform.build(fragment,
               ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/amaranth/build/plat.py", line 113, in build
    self.toolchain_program(products, name, **(program_opts or {}))
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/cynthion/gateware/platform/core.py", line 79, in toolchain_program
    programmer.configure(bitstream)
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/apollo_fpga/ecp5.py", line 451, in configure
    self._execute_command(self.Opcode.LSC_SET_WORKING_ADDRESS, b"\x01")
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/apollo_fpga/ecp5.py", line 998, in _execute_command
    self._validate_status(status, extra_verbose=True)
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/apollo_fpga/ecp5.py", line 334, in _validate_status
    error_handler("Failed to execute last command!{}".format(error_text))
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/apollo_fpga/ecp5.py", line 318, in raise_error
    raise IOError(msg)
OSError: Failed to execute last command! (bitstream provides data past the device's SRAM array / ffffffff)

grvvy@oliver:~/repos/luna$ ./ci-scripts/test.sh 
INFO    | __init__    | Building and uploading gateware to attached Cynthion r0.4...
Traceback (most recent call last):
  File "/home/grvvy/repos/luna/applets/interactive-test.py", line 295, in <module>
    tester = top_level_cli(InteractiveSelftest)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/luna/__init__.py", line 113, in top_level_cli
    products = platform.build(fragment,
               ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/amaranth/build/plat.py", line 113, in build
    self.toolchain_program(products, name, **(program_opts or {}))
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/cynthion/gateware/platform/core.py", line 79, in toolchain_program
    programmer.configure(bitstream)
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/apollo_fpga/ecp5.py", line 439, in configure
    self._validate_status(status, expect_isc=True)
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/apollo_fpga/ecp5.py", line 338, in _validate_status
    error_handler("Last command was invalid!{}".format(error_text))
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/apollo_fpga/ecp5.py", line 318, in raise_error
    raise IOError(msg)
OSError: Last command was invalid! (part ID mismatch / 10888821)

grvvy@oliver:~/repos/luna$ ./ci-scripts/test.sh 
INFO    | __init__    | Building and uploading gateware to attached Cynthion r0.4...
Traceback (most recent call last):
  File "/home/grvvy/repos/luna/applets/interactive-test.py", line 295, in <module>
    tester = top_level_cli(InteractiveSelftest)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/luna/__init__.py", line 113, in top_level_cli
    products = platform.build(fragment,
               ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/amaranth/build/plat.py", line 113, in build
    self.toolchain_program(products, name, **(program_opts or {}))
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/cynthion/gateware/platform/core.py", line 79, in toolchain_program
    programmer.configure(bitstream)
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/apollo_fpga/ecp5.py", line 421, in configure
    self._restart_configuration_process()
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/apollo_fpga/ecp5.py", line 490, in _restart_configuration_process
    self._execute_command(self.Opcode.LSC_REFRESH, wait_for_completion=True, check_status=False)
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/apollo_fpga/ecp5.py", line 994, in _execute_command
    self._wait_for_completion(context=opcode)
  File "/home/grvvy/repos/luna/testing-venv/lib/python3.11/site-packages/apollo_fpga/ecp5.py", line 551, in _wait_for_completion
    raise IOError("ECP5 request timed out waiting for completion (context: {})".format(context))
OSError: ECP5 request timed out waiting for completion (context: 121)
mossmann commented 7 months ago

This looks to me like an Apollo firmware bug affecting JTAG on r0.4.

mossmann commented 7 months ago

I was able to reproduce this on r0.3. I could run blinky.py successfully until updating Apollo firmware. After updating Apollo firmware I got:

(venv) mossmann@costard:~/src/cynthion/cynthion/python$ ~/src/luna/examples/blinky/blinky.py 
INFO    | __init__    | Building and uploading gateware to attached Cynthion r0.3...
Traceback (most recent call last):
  File "/home/mossmann/src/luna/examples/blinky/blinky.py", line 41, in <module>
    top_level_cli(Blinky)
  File "/home/mossmann/src/cynthion/cynthion/python/venv/lib/python3.11/site-packages/luna/__init__.py", line 113, in top_level_cli
    products = platform.build(fragment,
               ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mossmann/src/cynthion/cynthion/python/venv/lib/python3.11/site-packages/amaranth/build/plat.py", line 113, in build
    self.toolchain_program(products, name, **(program_opts or {}))
  File "/home/mossmann/src/cynthion/cynthion/python/venv/lib/python3.11/site-packages/cynthion/gateware/platform/core.py", line 79, in toolchain_program
    programmer.configure(bitstream)
  File "/home/mossmann/src/cynthion/cynthion/python/venv/lib/python3.11/site-packages/apollo_fpga/ecp5.py", line 461, in configure
    self._validate_status(status, expect_done=True)
  File "/home/mossmann/src/cynthion/cynthion/python/venv/lib/python3.11/site-packages/apollo_fpga/ecp5.py", line 334, in _validate_status
    error_handler("Failed to execute last command!{}".format(error_text))
  File "/home/mossmann/src/cynthion/cynthion/python/venv/lib/python3.11/site-packages/apollo_fpga/ecp5.py", line 318, in raise_error
    raise IOError(msg)
OSError: Failed to execute last command! (bitstream provides data past the device's SRAM array / ffffffff)