--- /dev/null
+from types import SimpleNamespace
+from nmigen import *
+from nmigen.back import rtlil, verilog, pysim
+
+
+class GPIO:
+ def __init__(self, pins, bus):
+ self.pins = pins
+ self.bus = bus
+
+ def get_fragment(self, platform):
+ m = Module()
+ m.d.comb += self.bus.dat_r.eq(self.pins[self.bus.adr])
+ with m.If(self.bus.we):
+ m.d.sync += self.pins[self.bus.adr].eq(self.bus.dat_w)
+ return m.lower(platform)
+
+
+# TODO: use Record
+bus = SimpleNamespace(
+ adr=Signal(max=8),
+ dat_r=Signal(),
+ dat_w=Signal(),
+ we=Signal()
+)
+pins = Signal(8)
+gpio = GPIO(Array(pins), bus)
+frag = gpio.get_fragment(platform=None)
+
+# print(rtlil.convert(frag, ports=[pins, bus.adr, bus.dat_r, bus.dat_w, bus.we]))
+print(verilog.convert(frag, ports=[pins, bus.adr, bus.dat_r, bus.dat_w, bus.we]))
return wire_curr
def expand(self, value):
+ if not self.expansions:
+ return value
return self.expansions.get(value, value)
@contextmanager
else:
return "{} [{}:{}]".format(sigspec, value.end - 1, value.start)
+ def on_ArrayProxy(self, value):
+ index = self.s.expand(value.index)
+ if isinstance(index, ast.Const):
+ if index.value < len(value.elems):
+ return self(value.elems[index.value])
+ else:
+ return self(value.elems[-1])
+ else:
+ raise LegalizeValue(value.index, range(len(value.elems)))
+
class _RHSValueCompiler(_ValueCompiler):
operator_map = {
def on_Repl(self, value):
return "{{ {} }}".format(" ".join(self(value.value) for _ in range(value.count)))
- def on_ArrayProxy(self, value):
- raise NotImplementedError
-
class _LHSValueCompiler(_ValueCompiler):
def on_Const(self, value):
if isinstance(offset, ast.Const):
return self(ast.Slice(value.value, offset.value, offset.value + value.width))
else:
- raise LegalizeValue(value.offset, range(0, (1 << len(value.offset) - 1)))
+ raise LegalizeValue(value.offset, range((1 << len(value.offset)) - 1))
def on_Repl(self, value):
raise TypeError # :nocov:
- def on_ArrayProxy(self, value):
- raise NotImplementedError
-
class _StatementCompiler(xfrm.AbstractStatementTransformer):
def __init__(self, state, rhs_compiler, lhs_compiler):
self.value.width))
elif isinstance(self.value, Cat):
return hash(tuple(ValueKey(o) for o in self.value.operands))
+ elif isinstance(self.value, ArrayProxy):
+ return hash((ValueKey(self.value.index),
+ tuple(ValueKey(e) for e in self.value._iter_as_values())))
else: # :nocov:
raise TypeError("Object '{!r}' cannot be used as a key in value collections"
.format(self.value))
elif isinstance(self.value, Cat):
return all(ValueKey(a) == ValueKey(b)
for a, b in zip(self.value.operands, other.value.operands))
+ elif isinstance(self.value, ArrayProxy):
+ return (ValueKey(self.value.index) == ValueKey(other.value.index) and
+ len(self.value.elems) == len(other.value.elems) and
+ all(ValueKey(a) == ValueKey(b)
+ for a, b in zip(self.value._iter_as_values(),
+ other.value._iter_as_values())))
else: # :nocov:
raise TypeError("Object '{!r}' cannot be used as a key in value collections"
.format(self.value))