Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/nmigen
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 3e59d857e17f
Choose a base ref
...
head repository: m-labs/nmigen
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: d791b77cc868
Choose a head ref
  • 1 commit
  • 3 files changed
  • 1 contributor

Commits on Dec 14, 2018

  1. Copy the full SHA
    d791b77 View commit details
Showing with 39 additions and 13 deletions.
  1. +2 −1 examples/ctrl.py
  2. +25 −11 nmigen/back/pysim.py
  3. +12 −1 nmigen/fhdl/ast.py
3 changes: 2 additions & 1 deletion examples/ctrl.py
Original file line number Diff line number Diff line change
@@ -26,7 +26,8 @@ def get_fragment(self, platform):
def sim_proc():
yield pysim.Delay(15.25e-6)
yield ctr.ce.eq(Const(1))
yield pysim.Delay(15e-6)
yield pysim.Delay(15.25e-6)
yield pysim.Tick("sync")
yield ctr.ce.eq(Const(0))
sim.add_process(sim_proc())
with sim: sim.run_until(100e-6, run_passive=True)
36 changes: 25 additions & 11 deletions nmigen/back/pysim.py
Original file line number Diff line number Diff line change
@@ -184,9 +184,9 @@ def run(state):
class Simulator:
def __init__(self, fragment=None, vcd_file=None):
self._fragments = {} # fragment -> hierarchy
self._domains = {} # str -> ClockDomain
self._domain_triggers = ValueDict() # Signal -> str
self._domain_signals = {} # str -> {Signal}
self._domains = {} # str/domain -> ClockDomain
self._domain_triggers = ValueDict() # Signal -> str/domain
self._domain_signals = {} # str/domain -> {Signal}
self._signals = ValueSet() # {Signal}
self._comb_signals = ValueSet() # {Signal}
self._sync_signals = ValueSet() # {Signal}
@@ -198,7 +198,9 @@ def __init__(self, fragment=None, vcd_file=None):

self._processes = set() # {process}
self._passive = set() # {process}
self._suspended = {} # process -> until
self._suspended = set() # {process}
self._wait_deadline = {} # process -> float/timestamp
self._wait_tick = {} # process -> str/domain

self._handlers = ValueDict() # Signal -> set(lambda)

@@ -303,6 +305,11 @@ def _commit_signal(self, signal):
if sync_signal in self._domain_signals[domain]:
self._commit_signal(sync_signal)

for proc, wait_domain in list(self._wait_tick.items()):
if domain == wait_domain:
del self._wait_tick[proc]
self._suspended.remove(proc)

if self._vcd_writer:
for vcd_signal in self._vcd_signals[signal]:
self._vcd_writer.change(vcd_signal, self._timestamp * 1e10, new)
@@ -335,7 +342,11 @@ def _run_process(self, proc):
return

if isinstance(stmt, Delay):
self._suspended[proc] = self._timestamp + stmt.interval
self._wait_deadline[proc] = self._timestamp + stmt.interval
self._suspended.add(proc)
elif isinstance(stmt, Tick):
self._wait_tick[proc] = stmt.domain
self._suspended.add(proc)
elif isinstance(stmt, Passive):
self._passive.add(proc)
elif isinstance(stmt, Assign):
@@ -361,12 +372,15 @@ def step(self, run_passive=False):

# All processes are suspended. Are any of them active?
if len(self._processes) > len(self._passive) or run_passive:
# Schedule the one with the lowest deadline.
proc, deadline = min(self._suspended.items(), key=lambda x: x[1])
del self._suspended[proc]
self._timestamp = deadline
self._run_process(proc)
return True
# Are any of them suspended before a deadline?
if self._wait_deadline:
# Schedule the one with the lowest deadline.
proc, deadline = min(self._wait_deadline.items(), key=lambda x: x[1])
del self._wait_deadline[proc]
self._suspended.remove(proc)
self._timestamp = deadline
self._run_process(proc)
return True

# No processes, or all processes are passive. Nothing to do!
return False
13 changes: 12 additions & 1 deletion nmigen/fhdl/ast.py
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@
__all__ = [
"Value", "Const", "Operator", "Mux", "Part", "Slice", "Cat", "Repl",
"Signal", "ClockSignal", "ResetSignal",
"Statement", "Assign", "Switch", "Delay", "Passive",
"Statement", "Assign", "Switch", "Delay", "Tick", "Passive",
"ValueKey", "ValueDict", "ValueSet",
]

@@ -704,6 +704,17 @@ def __repr__(self):
return "(delay {:.3}us)".format(self.interval * 10e6)


class Tick(Statement):
def __init__(self, domain):
self.domain = str(domain)

def _rhs_signals(self):
return ValueSet()

def __repr__(self):
return "(tick {})".format(self.domain)


class Passive(Statement):
def _rhs_signals(self):
return ValueSet()