The object that can be used in as a module special is ``Tristate``, and it behaves exactly like an instance of a tri-state I/O buffer that would be defined as follows: ::
Instance("Tristate",
- Instance.Inout("target", target),
- Instance.Input("o", o),
- Instance.Input("oe", oe),
- Instance.Output("i", i)
+ io_target=target,
+ i_o=o,
+ i_oe=oe,
+ o_i=i
)
Signals ``target``, ``o`` and ``i`` can have any width, while ``oe`` is 1-bit wide. The ``target`` signal should go to a port and not be used elsewhere in the design. Like modern FPGA architectures, Migen does not support internal tri-states.
ina = Array(Signal() for a in range(dx))
outa = Array(Signal() for a in range(dy))
- self.specials += Instance("test", Instance.Output("O", outa[y]), Instance.Input("I", ina[x]))
+ self.specials += Instance("test", o_O=outa[y], i_I=ina[x])
print(verilog.convert(Example()))
+from operator import itemgetter
+
from migen.fhdl.structure import *
from migen.fhdl.size import bits_for, value_bits_sign
from migen.fhdl.tools import *
return Tristate(target, self.o, self.oe, self.i)
class Instance(Special):
- def __init__(self, of, *items, name=""):
- Special.__init__(self)
- self.of = of
- if name:
- self.name_override = name
- else:
- self.name_override = of
- self.items = items
-
class _IO:
def __init__(self, name, expr=None):
self.name = name
pass
class InOut(_IO):
pass
-
class Parameter:
def __init__(self, name, value):
self.name = name
self.value = value
+
+ def __init__(self, of, *items, name="", **kwargs):
+ Special.__init__(self)
+ self.of = of
+ if name:
+ self.name_override = name
+ else:
+ self.name_override = of
+ self.items = list(items)
+ for k, v in sorted(kwargs.items(), key=itemgetter(1)):
+ item_type, item_name = k.split("_", maxsplit=1)
+ item_class = {
+ "i": Instance.Input,
+ "o": Instance.Output,
+ "io": Instance.InOut,
+ "p": Instance.Parameter
+ }[item_type]
+ self.items.append(item_class(item_name, v))
def get_io(self, name):
for item in self.items: