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: 120d81712308
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: fe5fb34fae3b
Choose a head ref
  • 2 commits
  • 1 file changed
  • 1 contributor

Commits on Dec 14, 2018

  1. Copy the full SHA
    70ebc6f View commit details
  2. back.pysim: squash one level of hierarchy.

    There's really no point in the "top" node.
    whitequark committed Dec 14, 2018
    Copy the full SHA
    fe5fb34 View commit details
Showing with 34 additions and 14 deletions.
  1. +34 −14 nmigen/back/pysim.py
48 changes: 34 additions & 14 deletions nmigen/back/pysim.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import math
import inspect
from contextlib import contextmanager
from vcd import VCDWriter
from vcd.gtkw import GTKWSave

@@ -24,9 +25,6 @@ def __init__(self):
self.curr_dirty = ValueSet()
self.next_dirty = ValueSet()

def get(self, signal):
return self.curr[signal]

def set(self, signal, value):
assert isinstance(value, int)
if self.next[signal] != value:
@@ -47,15 +45,21 @@ def commit(self, signal):


class _RHSValueCompiler(ValueTransformer):
def __init__(self, sensitivity):
def __init__(self, sensitivity=None):
self.sensitivity = sensitivity
self.signal_mode = "next"

def on_Const(self, value):
return lambda state: value.value

def on_Signal(self, value):
self.sensitivity.add(value)
return lambda state: state.get(value)
if self.sensitivity:
self.sensitivity.add(value)
if self.signal_mode == "curr":
return lambda state: state.curr[value]
if self.signal_mode == "next":
return lambda state: state.next[value]
raise NotImplementedError # :nocov:

def on_ClockSignal(self, value):
raise NotImplementedError # :nocov:
@@ -147,6 +151,14 @@ def __init__(self):
self.sensitivity = ValueSet()
self.rhs_compiler = _RHSValueCompiler(self.sensitivity)

@contextmanager
def initial(self):
try:
self.rhs_compiler.signal_mode = "curr"
yield
finally:
self.rhs_compiler.signal_mode = "next"

def lhs_compiler(self, value):
# TODO
return lambda state, arg: state.set(value, arg)
@@ -283,7 +295,7 @@ def __enter__(self):
self._domain_signals[domain] = ValueSet()

hierarchy = {}
def add_fragment(fragment, scope=("top",)):
def add_fragment(fragment, scope=()):
hierarchy[fragment] = scope
for subfragment, name in fragment.subfragments:
add_fragment(subfragment, (*scope, name))
@@ -342,20 +354,28 @@ def add_fragment(fragment, scope=("top",)):
self._sync_signals.update(signals)
self._domain_signals[domain].update(signals)

statements = []
initial_stmts = []
for signal in fragment.iter_comb():
statements.append(signal.eq(signal.reset))
initial_stmts.append(signal.eq(signal.reset))
for domain, signal in fragment.iter_sync():
statements.append(signal.eq(signal))
statements += fragment.statements
initial_stmts.append(signal.eq(signal))

compiler = _StatementCompiler()
def make_funclet():
with compiler.initial():
funclet_init = compiler(initial_stmts)
funclet_frag = compiler(fragment.statements)
def funclet(state):
funclet_init(state)
funclet_frag(state)
return funclet
funclet = make_funclet()

def add_funclet(signal, funclet):
if signal not in self._funclets:
self._funclets[signal] = set()
self._funclets[signal].add(funclet)

compiler = _StatementCompiler()
funclet = compiler(statements)
for signal in compiler.sensitivity:
add_funclet(signal, funclet)
for domain, cd in fragment.domains.items():
@@ -464,7 +484,7 @@ def format_process(process):
self._passive.add(process)

elif isinstance(cmd, Value):
funclet = _RHSValueCompiler(sensitivity=ValueSet())(cmd)
funclet = _RHSValueCompiler()(cmd)
cmd = process.send(funclet(self._state))
continue