Closed
Description
Issue by RobertBaruch
Thursday Sep 26, 2019 at 02:12 GMT
Originally opened as m-labs/nmigen#236
What's the right pattern to use? Here is an example of what I've tried:
from nmigen import *
from nmigen.cli import main
from nmigen.asserts import *
from nmigen.back import pysim
from nmigen.hdl.ast import Tick
# module edgelord outputs the state of the clock without using
# the clock in combinatorial logic. This is a good thing in
# FPGAs, where the clock is a special signal that might get
# badly routed if it has to go through anything other than the
# clock inputs of flipflops.
#
# The reset signal MUST be held high for both edges,
# otherwise the clk_state will be inverted.
class Edgelord(Elaboratable):
def __init__(self):
self.clk_state = Signal()
def elaborate(self, platform):
pos = Signal()
neg = Signal()
rst = ResetSignal("pos")
m = Module()
# Verilog equivalent:
#
# assign clk_state = reset || !(pos ^ neg);
m.d.comb += self.clk_state.eq(rst | ~(pos ^ neg))
# Verilog equivalent:
#
# always @(posedge clk) begin
# if (reset) pos <= 0;
# else pos <= !(pos ^ clk_state);
# end
#
# always @(negedge clk) begin
# if (reset) neg <= 0;
# else neg <= neg ^ clk_state;
# end
with m.If(rst):
m.d.pos += pos.eq(0)
m.d.neg += neg.eq(0)
with m.Else():
m.d.pos += pos.eq(~(pos ^ self.clk_state))
m.d.neg += neg.eq(neg ^ self.clk_state)
if platform == "formal":
self.formal(m)
return m
def formal(self, m):
cycle = Signal(8, reset_less=True)
rst = ResetSignal("pos")
clk = ClockSignal("pos")
m.d.pos += cycle.eq(cycle + (cycle != 255))
m.d.comb += Assume(rst == (cycle < 2))
with m.If(rst == 0):
m.d.comb += Assert(clk == self.clk_state)
if __name__ == "__main__":
clk = Signal()
rst = Signal()
pos = ClockDomain()
pos.clk = clk
pos.rst = rst
neg = ClockDomain(clk_edge="neg")
neg.clk = clk
neg.rst = rst
edgelord = Edgelord()
m = Module()
m.domains.pos = pos
m.domains.neg = neg
m.submodules.edgelord = edgelord
with pysim.Simulator(
m,
vcd_file=open("edgelord.vcd", "w"),
gtkw_file=open("edgelord.gtkw", "w"),
traces=[clk, rst, edgelord.clk_state]) as sim:
sim.add_clock(1e-9, domain="pos")
sim.add_clock(1e-9, domain="neg")
#sim.add_clock(1e-9)
def process():
for i in range(0, 30):
yield Tick(domain="pos")
yield Tick(domain="neg")
#sim.add_sync_process(process(), domain="pos")
sim.add_process(process())
sim.run()
#main(m, ports=[clk, rst, edgelord.clk_state], platform="formal")
This resulted in:
Traceback (most recent call last):
File "/usr/lib/python3.6/runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "/usr/lib/python3.6/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/mnt/f/mz80/mz80/core/edgelord.py", line 104, in <module>
sim.run()
File "/home/robertbaruch/.local/lib/python3.6/site-packages/nmigen/back/pysim.py", line 835, in run
while self.step():
File "/home/robertbaruch/.local/lib/python3.6/site-packages/nmigen/back/pysim.py", line 800, in step
raise DeadlineError("Delta cycles exceeded process deadline; combinatorial loop?")
nmigen.back.pysim.DeadlineError: Delta cycles exceeded process deadline; combinatorial loop?
Activity
nmigen-issue-migration commentedon Sep 26, 2019
Thursday Sep 26, 2019 at 02:16 GMT
This is currently broken for reasons that are not entirely clear. See #28. I plan to rewrite the simulator entirely, since it has a number of serious flaws that require changing core decisions, but this will take some time.
A possible workaround is to use
EnableInserter
to sequence thepos
andneg
actions, and thenDomainRenamer
to map them both to a singlesync
domain.Another possible workaround is to use https://github.com/andresdemski/nmigen-cocotb. (I have not personally used it.) I will also take a good look at cocotb's user interface (see #228), so if later you want to get rid of cocotb in favor of Python-only simulation, it is likely that the migration would not be very painful.
nmigen-issue-migration commentedon Oct 12, 2019
Saturday Oct 12, 2019 at 23:32 GMT
@RobertBaruch Have you been able to use one of these workarounds?
nmigen-issue-migration commentedon Oct 13, 2019
Sunday Oct 13, 2019 at 13:52 GMT
I haven't looked at it yet. I can try nmigen-cocotb.
nmigen-issue-migration commentedon Oct 13, 2019
Sunday Oct 13, 2019 at 16:15 GMT
Tried nmigen-cocotb, but apparently nothing is output. I get a sim_build directory with a vvp file. I did run vvp on that vvp file and got an output.vcd, which contained no signal changes. Maybe there's some documentation out of date -- the test runner doesn't seem to run the function annotated with
@cocotb.test()
.output.zip
nmigen-issue-migration commentedon Oct 13, 2019
Sunday Oct 13, 2019 at 16:20 GMT
Hmm, the coctb-nmigen example doesn't even output anything, so there must be some step missing.
nmigen-issue-migration commentedon Oct 13, 2019
Sunday Oct 13, 2019 at 16:43 GMT
Yeah, no.
nmigen-issue-migration commentedon Oct 13, 2019
Sunday Oct 13, 2019 at 16:45 GMT
What about my other suggestion?
nmigen-issue-migration commentedon Oct 13, 2019
Sunday Oct 13, 2019 at 16:49 GMT
Working on that now!
nmigen-issue-migration commentedon Oct 13, 2019
Sunday Oct 13, 2019 at 17:05 GMT
Sorry, I'm going to need more explicit instructions on what to do with
EnableInserter
andDomainRenamer
.nmigen-issue-migration commentedon Oct 13, 2019
Sunday Oct 13, 2019 at 17:09 GMT
Something like:
nmigen-issue-migration commentedon Oct 13, 2019
Sunday Oct 13, 2019 at 17:28 GMT
Yes, that seems to have worked, thanks!
nmigen-issue-migration commentedon Oct 17, 2019
Thursday Oct 17, 2019 at 16:12 GMT
Hi, get_current_module function is not working currently in nmigen-cocotb. Try to use it with harcoded module.
Try this commit: https://github.com/andresdemski/nmigen-cocotb/tree/9e5d868587c859820147365a51d38f60e459cbb0