diff --git a/litex/soc/cores/gpio.py b/litex/soc/cores/gpio.py index daaf9c453..649669753 100644 --- a/litex/soc/cores/gpio.py +++ b/litex/soc/cores/gpio.py @@ -73,20 +73,35 @@ class GPIOInOut(Module): class GPIOTristate(_GPIOIRQ, Module, AutoCSR): def __init__(self, pads, with_irq=False): - assert isinstance(pads, Signal) - nbits = len(pads) - self._oe = CSRStorage(nbits, description="GPIO Tristate(s) Control.") - self._in = CSRStatus(nbits, description="GPIO Input(s) Status.") - self._out = CSRStorage(nbits, description="GPIO Ouptut(s) Control.") + assert isinstance(pads, Signal) or isinstance(pads, Record) # # # - for i in range(nbits): - t = TSTriple() - self.specials += t.get_tristate(pads[i]) - self.comb += t.oe.eq(self._oe.storage[i]) - self.comb += t.o.eq(self._out.storage[i]) - self.specials += MultiReg(t.i, self._in.status[i]) + if isinstance(pads, Signal): + # Proper inout IOs + nbits = len(pads) + self._oe = CSRStorage(nbits, description="GPIO Tristate(s) Control.") + self._in = CSRStatus(nbits, description="GPIO Input(s) Status.") + self._out = CSRStorage(nbits, description="GPIO Ouptut(s) Control.") + + for i in range(nbits): + t = TSTriple() + self.specials += t.get_tristate(pads[i]) + self.comb += t.oe.eq(self._oe.storage[i]) + self.comb += t.o.eq(self._out.storage[i]) + self.specials += MultiReg(t.i, self._in.status[i]) + else: + # Tristate record, for external tristate IO chips or simulation + nbits = len(pads.oe) + self._oe = CSRStorage(nbits, description="GPIO Tristate(s) Control.") + self._in = CSRStatus(nbits, description="GPIO Input(s) Status.") + self._out = CSRStorage(nbits, description="GPIO Ouptut(s) Control.") + clocked_inputs = Signal.like(pads.i) + + for i in range(nbits): + self.comb += pads.oe[i].eq(self._oe.storage[i]) + self.comb += pads.o[i].eq(self._out.storage[i]) + self.specials += MultiReg(pads.i[i], self._in.status[i]) if with_irq: self.add_irq(self._in.status)