mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
Merge pull request #1035 from lschuermann/dev/litex-sim-gpio
litex_sim: optionally add GPIOTristate core
This commit is contained in:
commit
6251474b39
2 changed files with 42 additions and 11 deletions
|
@ -73,20 +73,35 @@ class GPIOInOut(Module):
|
||||||
|
|
||||||
class GPIOTristate(_GPIOIRQ, Module, AutoCSR):
|
class GPIOTristate(_GPIOIRQ, Module, AutoCSR):
|
||||||
def __init__(self, pads, with_irq=False):
|
def __init__(self, pads, with_irq=False):
|
||||||
assert isinstance(pads, Signal)
|
assert isinstance(pads, Signal) or isinstance(pads, Record)
|
||||||
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):
|
if isinstance(pads, Signal):
|
||||||
t = TSTriple()
|
# Proper inout IOs
|
||||||
self.specials += t.get_tristate(pads[i])
|
nbits = len(pads)
|
||||||
self.comb += t.oe.eq(self._oe.storage[i])
|
self._oe = CSRStorage(nbits, description="GPIO Tristate(s) Control.")
|
||||||
self.comb += t.o.eq(self._out.storage[i])
|
self._in = CSRStatus(nbits, description="GPIO Input(s) Status.")
|
||||||
self.specials += MultiReg(t.i, self._in.status[i])
|
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:
|
if with_irq:
|
||||||
self.add_irq(self._in.status)
|
self.add_irq(self._in.status)
|
||||||
|
|
|
@ -22,6 +22,7 @@ from litex.soc.integration.soc_core import *
|
||||||
from litex.soc.integration.builder import *
|
from litex.soc.integration.builder import *
|
||||||
from litex.soc.integration.soc import *
|
from litex.soc.integration.soc import *
|
||||||
from litex.soc.cores.bitbang import *
|
from litex.soc.cores.bitbang import *
|
||||||
|
from litex.soc.cores.gpio import GPIOTristate
|
||||||
from litex.soc.cores.cpu import CPUS
|
from litex.soc.cores.cpu import CPUS
|
||||||
|
|
||||||
|
|
||||||
|
@ -87,6 +88,13 @@ _io = [
|
||||||
Subsignal("clk", Pins(1)),
|
Subsignal("clk", Pins(1)),
|
||||||
Subsignal("dq", Pins(4)),
|
Subsignal("dq", Pins(4)),
|
||||||
),
|
),
|
||||||
|
# Simulated tristate IO (Verilator does not support top-level
|
||||||
|
# tristate signals)
|
||||||
|
("gpio", 0,
|
||||||
|
Subsignal("oe", Pins(32)),
|
||||||
|
Subsignal("o", Pins(32)),
|
||||||
|
Subsignal("i", Pins(32)),
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
# Platform -----------------------------------------------------------------------------------------
|
# Platform -----------------------------------------------------------------------------------------
|
||||||
|
@ -115,6 +123,7 @@ class SimSoC(SoCCore):
|
||||||
with_sdcard = False,
|
with_sdcard = False,
|
||||||
with_spi_flash = False,
|
with_spi_flash = False,
|
||||||
spi_flash_init = [],
|
spi_flash_init = [],
|
||||||
|
with_gpio = False,
|
||||||
sim_debug = False,
|
sim_debug = False,
|
||||||
trace_reset_on = False,
|
trace_reset_on = False,
|
||||||
**kwargs):
|
**kwargs):
|
||||||
|
@ -260,6 +269,11 @@ class SimSoC(SoCCore):
|
||||||
self.submodules.spiflash_phy = LiteSPIPHYModel(spiflash_module, init=spi_flash_init)
|
self.submodules.spiflash_phy = LiteSPIPHYModel(spiflash_module, init=spi_flash_init)
|
||||||
self.add_spi_flash(phy=self.spiflash_phy, mode="4x", module=spiflash_module, with_master=True)
|
self.add_spi_flash(phy=self.spiflash_phy, mode="4x", module=spiflash_module, with_master=True)
|
||||||
|
|
||||||
|
# GPIO --------------------------------------------------------------------------------------
|
||||||
|
if with_gpio:
|
||||||
|
self.submodules.gpio = GPIOTristate(platform.request("gpio"), with_irq=True)
|
||||||
|
self.irq.add("gpio", use_loc_if_exists=True)
|
||||||
|
|
||||||
# Simulation debugging ----------------------------------------------------------------------
|
# Simulation debugging ----------------------------------------------------------------------
|
||||||
if sim_debug:
|
if sim_debug:
|
||||||
platform.add_debug(self, reset=1 if trace_reset_on else 0)
|
platform.add_debug(self, reset=1 if trace_reset_on else 0)
|
||||||
|
@ -325,6 +339,7 @@ def sim_args(parser):
|
||||||
parser.add_argument("--with-sdcard", action="store_true", help="Enable SDCard support")
|
parser.add_argument("--with-sdcard", action="store_true", help="Enable SDCard support")
|
||||||
parser.add_argument("--with-spi-flash", action="store_true", help="Enable SPI Flash (MMAPed)")
|
parser.add_argument("--with-spi-flash", action="store_true", help="Enable SPI Flash (MMAPed)")
|
||||||
parser.add_argument("--spi_flash-init", default=None, help="SPI Flash init file")
|
parser.add_argument("--spi_flash-init", default=None, help="SPI Flash init file")
|
||||||
|
parser.add_argument("--with-gpio", action="store_true", help="Enable Tristate GPIO (32 pins)")
|
||||||
parser.add_argument("--trace", action="store_true", help="Enable Tracing")
|
parser.add_argument("--trace", action="store_true", help="Enable Tracing")
|
||||||
parser.add_argument("--trace-fst", action="store_true", help="Enable FST tracing (default=VCD)")
|
parser.add_argument("--trace-fst", action="store_true", help="Enable FST tracing (default=VCD)")
|
||||||
parser.add_argument("--trace-start", default="0", help="Time to start tracing (ps)")
|
parser.add_argument("--trace-start", default="0", help="Time to start tracing (ps)")
|
||||||
|
@ -392,6 +407,7 @@ def main():
|
||||||
with_i2c = args.with_i2c,
|
with_i2c = args.with_i2c,
|
||||||
with_sdcard = args.with_sdcard,
|
with_sdcard = args.with_sdcard,
|
||||||
with_spi_flash = args.with_spi_flash,
|
with_spi_flash = args.with_spi_flash,
|
||||||
|
with_gpio = args.with_gpio,
|
||||||
sim_debug = args.sim_debug,
|
sim_debug = args.sim_debug,
|
||||||
trace_reset_on = trace_start > 0 or trace_end > 0,
|
trace_reset_on = trace_start > 0 or trace_end > 0,
|
||||||
sdram_init = [] if args.sdram_init is None else get_mem_data(args.sdram_init, cpu.endianness),
|
sdram_init = [] if args.sdram_init is None else get_mem_data(args.sdram_init, cpu.endianness),
|
||||||
|
|
Loading…
Reference in a new issue