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: 20a04bca882f
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: d4e8d3e95a9d
Choose a head ref
  • 3 commits
  • 3 files changed
  • 1 contributor

Commits on Dec 15, 2018

  1. back.pysim: add (stub) LHSValueCompiler.

    whitequark committed Dec 15, 2018
    Copy the full SHA
    bdb8db2 View commit details
  2. test.sim: generalize assertOperator. NFC.

    whitequark committed Dec 15, 2018
    Copy the full SHA
    d957921 View commit details

Commits on Dec 16, 2018

  1. Copy the full SHA
    d4e8d3e View commit details
Showing with 202 additions and 97 deletions.
  1. +83 −11 nmigen/back/pysim.py
  2. +1 −1 nmigen/hdl/ast.py
  3. +118 −85 nmigen/test/test_sim.py
94 changes: 83 additions & 11 deletions nmigen/back/pysim.py
Original file line number Diff line number Diff line change
@@ -45,16 +45,22 @@ def commit(self, signal):


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

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

def on_Signal(self, value):
if self.sensitivity is not None:
self.sensitivity.add(value)
return lambda state: state.curr[value]
if self.signal_mode == "rhs":
return lambda state: state.curr[value]
elif self.signal_mode == "lhs":
return lambda state: state.next[value]
else:
raise ValueError # :nocov:

def on_ClockSignal(self, value):
raise NotImplementedError # :nocov:
@@ -159,26 +165,92 @@ def on_ArrayProxy(self, value):
return lambda state: normalize(elems[index(state)](state), shape)


class _LHSValueCompiler(ValueTransformer):
def __init__(self, rhs_compiler):
self.rhs_compiler = rhs_compiler

def on_Const(self, value):
raise TypeError # :nocov:

def on_Signal(self, value):
shape = value.shape()
def eval(state, rhs):
state.set(value, normalize(rhs, shape))
return eval

def on_ClockSignal(self, value):
raise NotImplementedError # :nocov:

def on_ResetSignal(self, value):
raise NotImplementedError # :nocov:

def on_Operator(self, value):
raise TypeError # :nocov:

def on_Slice(self, value):
lhs_r = self.rhs_compiler(value.value)
lhs_l = self(value.value)
shift = value.start
mask = (1 << (value.end - value.start)) - 1
def eval(state, rhs):
lhs_value = lhs_r(state)
lhs_value &= ~(mask << shift)
lhs_value |= (rhs & mask) << shift
lhs_l(state, lhs_value)
return eval

def on_Part(self, value):
lhs_r = self.rhs_compiler(value.value)
lhs_l = self(value.value)
shift = self.rhs_compiler(value.offset)
mask = (1 << value.width) - 1
def eval(state, rhs):
lhs_value = lhs_r(state)
shift_value = shift(state)
lhs_value &= ~(mask << shift_value)
lhs_value |= (rhs & mask) << shift_value
lhs_l(state, lhs_value)
return eval

def on_Cat(self, value):
parts = []
offset = 0
for opnd in value.operands:
parts.append((offset, (1 << len(opnd)) - 1, self(opnd)))
offset += len(opnd)
def eval(state, rhs):
for offset, mask, opnd in parts:
opnd(state, (rhs >> offset) & mask)
return eval

def on_Repl(self, value):
raise TypeError # :nocov:

def on_ArrayProxy(self, value):
elems = list(map(self, value.elems))
index = self.rhs_compiler(value.index)
def eval(state, rhs):
elems[index(state)](state, rhs)
return eval


class _StatementCompiler(StatementTransformer):
def __init__(self):
self.sensitivity = ValueSet()
self.rhs_compiler = _RHSValueCompiler(self.sensitivity)

def lhs_compiler(self, value):
# TODO
return lambda state, arg: state.set(value, arg)
self.sensitivity = ValueSet()
self.rrhs_compiler = _RHSValueCompiler(self.sensitivity, mode="rhs")
self.lrhs_compiler = _RHSValueCompiler(self.sensitivity, mode="lhs")
self.lhs_compiler = _LHSValueCompiler(self.lrhs_compiler)

def on_Assign(self, stmt):
assert isinstance(stmt.lhs, Signal)
shape = stmt.lhs.shape()
lhs = self.lhs_compiler(stmt.lhs)
rhs = self.rhs_compiler(stmt.rhs)
rhs = self.rrhs_compiler(stmt.rhs)
def run(state):
lhs(state, normalize(rhs(state), shape))
return run

def on_Switch(self, stmt):
test = self.rhs_compiler(stmt.test)
test = self.rrhs_compiler(stmt.test)
cases = []
for value, stmts in stmt.cases.items():
if "-" in value:
2 changes: 1 addition & 1 deletion nmigen/hdl/ast.py
Original file line number Diff line number Diff line change
@@ -813,7 +813,7 @@ def _lhs_signals(self):
return self.lhs._lhs_signals()

def _rhs_signals(self):
return self.rhs._rhs_signals()
return self.lhs._rhs_signals() | self.rhs._rhs_signals()

def __repr__(self):
return "(eq {!r} {!r})".format(self.lhs, self.rhs)
Loading