amaranth-lang / amaranth

A modern hardware definition language and toolchain based on Python
https://amaranth-lang.org/docs/amaranth/
BSD 2-Clause "Simplified" License
1.52k stars 168 forks source link

Simulations for code that uses Platform #113

Open nmigen-issue-migration opened 5 years ago

nmigen-issue-migration commented 5 years ago

Issue by zignig Tuesday Jun 25, 2019 at 00:21 GMT Originally opened as https://github.com/m-labs/nmigen/issues/108


Platform example ( simplified version of _blinky ) , fails to simulate. Minimal example of fail https://github.com/zignig/tinybx_stuff/blob/master/sim_fail/sim_fail.py

Looks to be the clock binding into a m.d.comb expression.

>>  python sim_fail.py simulate -c 1000 -v test.vcd
Traceback (most recent call last):
  File "sim_fail.py", line 36, in <module>
    cli.main_runner(parser, args, tb,platform=platform,ports=ios)
  File "/usr/local/lib/python3.6/dist-packages/nmigen/cli.py", line 71, in main_runner
    sim.run_until(args.sync_period * args.sync_clocks, run_passive=True)
  File "/usr/local/lib/python3.6/dist-packages/nmigen/back/pysim.py", line 802, in run_until
    if not self.step(run_passive):
  File "/usr/local/lib/python3.6/dist-packages/nmigen/back/pysim.py", line 786, in step
    self._run_process(process)
  File "/usr/local/lib/python3.6/dist-packages/nmigen/back/pysim.py", line 749, in _run_process
    process.throw(e)
  File "/usr/local/lib/python3.6/dist-packages/nmigen/back/pysim.py", line 442, in clk_process
    yield clk.eq(1)
  File "/usr/local/lib/python3.6/dist-packages/nmigen/back/pysim.py", line 711, in _run_process
    .format(self._name_process(process), signal))
ValueError: Process '/usr/local/lib/python3.6/dist-packages/nmigen/back/pysim.py:442' sent a request to set signal '(sig clk)', which is a part of combinatorial assignment in simulation
nmigen-issue-migration commented 5 years ago

Comment by whitequark Tuesday Jun 25, 2019 at 00:28 GMT


Not a bug. nMigen's internal simulator, by design, cannot simulate platforms, since it does not know how to handle primitives like I/O buffers.

nmigen-issue-migration commented 5 years ago

Comment by zignig Tuesday Jun 25, 2019 at 03:00 GMT


I can rewrite the front end to use the simulation clock. rather than one bound to a platform clock.

That said it would be cool to be able to simulate a "platform" board system without modification.

Thanks

nmigen-issue-migration commented 5 years ago

Comment by whitequark Tuesday Jun 25, 2019 at 03:03 GMT


That said it would be cool to be able to simulate a "platform" board system without modification.

It's not possible. nMigen's built-in simulator doesn't support tristates or dual-edge flip-flops, so you could at best support only the absolute basic designs with no bidirectional or DDR I/O.

nmigen-issue-migration commented 5 years ago

Comment by programmerjake Tuesday Jun 25, 2019 at 04:38 GMT


DDR flip-flops shouldn't be that hard to add, just trigger on both edges instead of one (assuming falling edge flip-flops are supported). tri-state would be harder

nmigen-issue-migration commented 5 years ago

Comment by whitequark Tuesday Jun 25, 2019 at 04:52 GMT


They're quite deliberately not supported. Among other things the Python simulator is already very slow.

nmigen-issue-migration commented 5 years ago

Comment by zignig Tuesday Jun 25, 2019 at 15:16 GMT


I have played around and managed to get simulations and gateware running, however there is a weird duplication.

Would to be possible to change this.

        m = Module()
        m.domains.sync = ClockDomain()
        m.d.comb += ClockSignal().eq(clk16.i)

into a bound clock so the simulator will run it?

I don't want nor need the tristates or DDR interfaces running . I would like a waveform in gtkwave.

nmigen-issue-migration commented 5 years ago

Comment by whitequark Tuesday Jun 25, 2019 at 15:35 GMT


I would rather not have it possible to simulate platform code at all than be able to simulate only the most basic case. So no. If you don't want nor need tristates and such, then simulate without any platform code at all.

nmigen-issue-migration commented 5 years ago

Comment by whitequark Sunday Jul 07, 2019 at 06:50 GMT


Pretty much everyone learning nMigen wants to use platform code with the simulator, so there needs to be some solution. I don't know how it should look like though.

nmigen-issue-migration commented 5 years ago

Comment by cr1901 Sunday Jul 07, 2019 at 11:36 GMT


A long while ago, @sbourdeauducq and @enjoy-digital proposed a solution for misoc that uses ffi hooks to simulate basic hardware like, say, UART using IPC (using pttys on *nix, but this won't work on Windoze).

Of course, a basic-to-comprehensive SPI flash is quite simulate-able using nmigen alone for said emulation layer. Just needs to be written :D. Alternatively, it could still be written partially calling to an FFI to avoid needing to simulate accessing memory array.

Those two alone will get you a decent chunk of use cases I imagine.

nmigen-issue-migration commented 5 years ago

Comment by whitequark Sunday Jul 07, 2019 at 11:40 GMT


That's kinda different, and I've already discussed it (privately); the problem here is specifically simulating an existing platform, not providing simulated devices to a special, separate platform.

nmigen-issue-migration commented 5 years ago

Comment by cr1901 Sunday Jul 07, 2019 at 11:44 GMT


If it was meant to be a special, separate platform, I've since forgotten.

The way I started coding my (failed!) PoC was that the platform needed to register w/ the ffi what peripherals it supported to the omigen simulator. Then the simulator would intercept accesses (using a queue for async inputs from the user) that relied on input/output on supported peripheral pins and redirect to the ffi.

This way, the simulated peripherals and platforms remained decoupled.

nmigen-issue-migration commented 5 years ago

Comment by mithro Sunday Jul 07, 2019 at 16:16 GMT


For "full platform simulation" something like Verilator is a good solution. By "full platform" I mean simulating things like the UART, Video Display, SPI flash -- all the stuff not actually inside the FPGA itself. People have already written good emulation of these parts and we should just reuse them. Trying to simulate theses in nmigen's simulator gets way too slow very quickly.... Verilator does introduce complexity around needed a C++ compiler and similar issues, so I would not say this is for "simple" solutions were you just want some VCD or one or two LED type things.

For "partial platform simulation" -- IE just emulating one of the LEDs, switches, UART or SPI flash for debugging your nmigen core is a different situation and probably makes sense to try and keep it all internal.

nmigen-issue-migration commented 5 years ago

Comment by zignig Sunday Jul 14, 2019 at 09:56 GMT


The problem that I hit was that the platform clock would not run inside the simulator. By wrapping or replacing this clock with a sim clock would satisfy my requirements for platform simulation.

I just want a .vcd so I can see what's going on inside.