Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python chokes on simulated memories of depth greater than ~3k #359

Closed
sjolsen opened this issue Apr 17, 2020 · 4 comments · Fixed by #1078
Closed

Python chokes on simulated memories of depth greater than ~3k #359

sjolsen opened this issue Apr 17, 2020 · 4 comments · Fixed by #1078

Comments

@sjolsen
Copy link
Contributor

sjolsen commented Apr 17, 2020

With Python 3.7.3 (shipped with Debian stable) and 3.8.2 (via pyenv), I encountered the following error when simulating a design with a couple of memory banks:

  File "/path/to/nmigen/back/pysim.py", line 765, in __call__
    exec(emitter.flush(), exec_locals)
RecursionError: maximum recursion depth exceeded during compilation

Here's a minimal reproduction:

import unittest

from nmigen import *
from nmigen.back.pysim import *

class MemTest(unittest.TestCase):

    def test_mem(self):
        m = Module()
        mem = Memory(width=1, depth=0xC00)
        m.submodules.rport = mem.read_port()
        m.submodules.wport = mem.write_port()
        sim = Simulator(m)
        sim.run()

Reducing the depth of the memory (width doesn't seem to matter) makes the failure go away. For the time being that workaround works for me, but it would be nice to use the same design parameters for simulation and synthesis.

@whitequark
Copy link
Member

Yep, this is a known pysim issue that requires reworking the way memories are translated.

sjolsen added a commit to sjolsen/nmigen-nexys that referenced this issue Apr 17, 2020
sjolsen added a commit to sjolsen/nmigen-nexys that referenced this issue Apr 17, 2020
This adds a simple RISC-V system with RAM, ROM, and a seven-segment display
driver peripheral. The GCC toolchain is integrated into the build and is used to
pre-program the ROM with a simple program that writes "deadbeef" to the display.

Also included is a bridge to drive JTAG over the on-board UART. This requires
opening a socket atop the TTY (e.g. with socat) and connecting to this using
OpenOCD's bitbang driver. GDB can connect and see some system state -- it can
dump registers and CSRs, read and write memory over the data bus -- but many
things don't work yet, including stepping.

RAM and ROM are provided by Xilinx block RAM primitives, which are 32 kib or
4 kiB. However, due to amaranth-lang/amaranth#359, this is
reduced to 2 kiB to make Python simulation work.
@whitequark
Copy link
Member

Interesting, I thought this would work on 3.7 (https://bugs.python.org/issue31113) but it doesn't.

@twam
Copy link
Contributor

twam commented Apr 12, 2021

Observed the same problem. Can workaround for now by calling sys.setrecursionlimit(x).

@jeremyherbert
Copy link

Just to add a few notes to this to help with people finding it from google:

On a Core i9 MBP (2019) this makes simulations of memory with a depth of 2**13 (just a lookup table) take about 1 minute if the recursion limit is set high enough. Python version is 3.9.5 (v3.9.5:0a7dcbdb13, May 3 2021, 13:05:53) \n[Clang 12.0.5 (clang-1205.0.22.9)].

You can expect to see an exception which looks something like this:

Traceback (most recent call last):
  File "/Users/jeremy/Seafile/misc_projects/amaranth_playing/sine_lookup.py", line 96, in <module>
    sim = Simulator(m)
  File "/Users/jeremy/Seafile/misc_projects/amaranth_playing/venv/lib/python3.9/site-packages/amaranth/sim/core.py", line 68, in __init__
    self._engine   = engine(self._fragment)
  File "/Users/jeremy/Seafile/misc_projects/amaranth_playing/venv/lib/python3.9/site-packages/amaranth/sim/pysim.py", line 282, in __init__
    self._processes = _FragmentCompiler(self._state)(self._fragment)
  File "/Users/jeremy/Seafile/misc_projects/amaranth_playing/venv/lib/python3.9/site-packages/amaranth/sim/_pyrtl.py", line 463, in __call__
    processes.update(self(subfragment))
  File "/Users/jeremy/Seafile/misc_projects/amaranth_playing/venv/lib/python3.9/site-packages/amaranth/sim/_pyrtl.py", line 463, in __call__
    processes.update(self(subfragment))
  File "/Users/jeremy/Seafile/misc_projects/amaranth_playing/venv/lib/python3.9/site-packages/amaranth/sim/_pyrtl.py", line 463, in __call__
    processes.update(self(subfragment))
  File "/Users/jeremy/Seafile/misc_projects/amaranth_playing/venv/lib/python3.9/site-packages/amaranth/sim/_pyrtl.py", line 455, in __call__
    exec(compile(code, filename, "exec"), exec_locals)
RecursionError: maximum recursion depth exceeded during compilation

whitequark pushed a commit that referenced this issue Sep 24, 2022
Current the value compiler translates ArrayProxy into if-elif trees 
which can cause the compiler to crash due to deep recursion (#359).

After this commit, it instead translates them into pattern matching 
when it is supported (on Python >= 3.10) to avoid this problem.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging a pull request may close this issue.

4 participants