'+': IOType.Out,
'*': IOType.InTriOut}
+# TODO: move to suitable location
+class Pins:
-class JTAG(DMITAP):
def __init__(self):
- super().__init__(ir_width=4)
# sigh this needs to come from pinmux.
gpios = []
gpios.append("gpio%d*" % i)
self.io_names = {'serial': ['tx+', 'rx-'], 'gpio': gpios}
+ def __iter__(self):
# start parsing io_names and create IOConn Records
- self.ios = []
for fn, pins in self.io_names.items():
for pin in pins:
# decode the pin name and determine the c4m jtag io type
name, pin_type = pin[:-1], pin[-1]
iotype = iotypes[pin_type]
pin_name = "%s_%s" % (fn, name)
- self.ios.append(self.add_io(iotype=iotype, name=pin_name))
+ yield (fn, name, iotype, pin_name)
+
+class JTAG(DMITAP, Pins):
+ def __init__(self):
+ DMITAP.__init__(self, ir_width=4)
+ Pins.__init__(self)
+
+ # sigh this needs to come from pinmux.
+ gpios = []
+ for i in range(16):
+ gpios.append("gpio%d*" % i)
+ self.io_names = {'serial': ['tx+', 'rx-'], 'gpio': gpios}
+
+ # start parsing io_names and create IOConn Records
+ self.ios = []
+ for fn, pin, iotype, pin_name in list(self):
+ self.ios.append(self.add_io(iotype=iotype, name=pin_name))
# this is redundant. or maybe part of testing, i don't know.
self.sr = self.add_shiftreg(ircode=4, length=3)
from litex.soc.interconnect import wishbone as wb
from litex.soc.cores.cpu import CPU
+from soc.debug.jtag import Pins # TODO move to suitable location
+from c4m.nmigen.jtag.tap import IOType
+
+from libresoc.ls180io import make_uart, make_gpio
+from litex.build.generic_platform import ConstraintManager
+
+
CPU_VARIANTS = ["standard", "standard32", "standardjtag", "ls180"]
return res
+def make_jtag_ioconn(res, pin, cpupads, iopads):
+ (fn, pin, iotype, pin_name) = pin
+ #serial_tx__core__o, serial_rx__pad__i,
+ print ("cpupads", cpupads)
+ print ("iopads", iopads)
+ print ("pin", fn, pin, iotype, pin_name)
+ cpu = cpupads[fn]
+ io = iopads[fn]
+ sigs = []
+
+ if iotype == IOType.Out:
+ # output from the pad is routed through C4M JTAG and so
+ # is an *INPUT* into core. ls180soc connects this to "real" peripheral
+ res['i_%s_%s_core__o' % (fn, pin)] = getattr(cpu, pin)
+ res['o_%s_%s_pad__o' % (fn, pin)] = getattr(io, pin)
+
+ elif iotype == IOType.In:
+ # input to the pad is routed through C4M JTAG and so
+ # is an *OUTPUT* into core. ls180soc connects this to "real" peripheral
+ res['o_%s_%s_core__i' % (fn, pin)] = getattr(cpu, pin)
+ res['i_%s_%s_pad__i' % (fn, pin)] = getattr(io, pin)
+
+ if iotype in (IOType.In, IOType.InTriOut):
+ sigs.append(("i", 1))
+ if iotype in (IOType.Out, IOType.TriOut, IOType.InTriOut):
+ sigs.append(("o", 1))
+ if iotype in (IOType.TriOut, IOType.InTriOut):
+ sigs.append(("oe", 1))
+
class LibreSoC(CPU):
name = "libre_soc"
human_name = "Libre-SoC"
if jtag_en:
self.cpu_params.update(make_wb_bus("jtag_wb", jtag_wb, simple=True))
+ # urr yuk. have to expose iopads / pins from core to litex
+ # then back again. cut _some_ of that out by connecting
+ self.cpuresources = (make_uart('serial', 0),
+ make_gpio('gpio', 0, 16))
+ self.padresources = (make_uart('serial', 0),
+ make_gpio('gpio', 0, 16))
+ self.cpu_cm = ConstraintManager(self.cpuresources, [])
+ self.pad_cm = ConstraintManager(self.cpuresources, [])
+ self.cpupads = {'serial': self.cpu_cm.request('serial', 0),
+ 'gpio': self.cpu_cm.request('gpio', 0)}
+ self.iopads = {'serial': self.pad_cm.request('serial', 0),
+ 'gpio': self.pad_cm.request('gpio', 0)}
+
+ p = Pins()
+ for pin in list(p):
+ make_jtag_ioconn(self.cpu_params, pin, self.cpupads,
+ self.iopads)
+
# add verilog sources
self.add_sources(platform)
from litex.build.generic_platform import (GenericPlatform, Pins,
Subsignal, IOStandard, Misc,
)
+from libresoc.ls180io import make_uart, make_gpio
import os
+
# IOs ----------------------------------------------------------------------------------------------
_io = [
Subsignal("sda", Pins("M1"), IOStandard("LVCMOS33"))
),
- # UART0: 2 pins
- ("serial", 0,
- Subsignal("tx", Pins("L4"), IOStandard("LVCMOS33")),
- Subsignal("rx", Pins("M1"), IOStandard("LVCMOS33"))
- ),
-
- # UART1: 2 pins
- ("serial", 1,
- Subsignal("tx", Pins("L4"), IOStandard("LVCMOS33")),
- Subsignal("rx", Pins("M1"), IOStandard("LVCMOS33"))
- ),
-
# SPI0: 4 pins
("spi_master", 0,
Subsignal("clk", Pins("J1")),
("pwm", 1, Pins("P2"), IOStandard("LVCMOS33")),
]
-pins = []
n_gpio = 16
-for i in range(n_gpio):
- pins.append("X%d" % i)
-pins = ' '.join(pins)
# 16 GPIOs
-_io.append( ("gpio", 0,
- Subsignal("i", Pins(pins), Misc("PULLMODE=UP")),
- Subsignal("o", Pins(pins), Misc("PULLMODE=UP")),
- Subsignal("oe", Pins(pins), Misc("PULLMODE=UP")),
- IOStandard("LVCMOS33")) )
+_io.append( make_gpio("gpio_litex", 0, n_gpio) )
# EINT: 3 pins
_io.append( ("eint", 3, Pins("E0 E1 E2"), IOStandard("LVCMOS33")) )
+# UART0: 2 pins
+_io.append(make_uart("uart_litex", 0))
+# UART1: 2 pins
+_io.append(make_uart("uart_litex", 1))
+
+
# Platform -----------------------------------------------------------------------------------------
class LS180Platform(GenericPlatform):
from operator import or_
from migen import (Signal, FSM, If, Display, Finish, NextValue, NextState,
- Cat, Record, ClockSignal, wrap)
+ Cat, Record, ClockSignal, wrap, ResetInserter)
from litex.build.generic_platform import Pins, Subsignal
from litex.build.sim import SimPlatform
from litex.soc.cores.spi import SPIMaster
from litex.soc.cores.pwm import PWM
from litex.soc.cores.bitbang import I2CMaster
+from litex.soc.cores import uart
from litex.tools.litex_sim import sdram_module_nphases, get_sdram_phy_settings
uart_name = "sim"
elif platform == 'ls180':
platform = LS180Platform()
- uart_name = "serial"
+ uart_name = "uart_litex"
#cpu_data_width = 32
cpu_data_width = 64
cpu_variant = variant,
csr_data_width = 8,
l2_size = 0,
- uart_name = uart_name,
+ with_uart = False,
+ uart_name = None,
with_sdram = with_sdram,
sdram_module = sdram_module,
sdram_data_width = sdram_data_width,
self.add_constant("MEMTEST_ADDR_DEBUG", 1)
self.add_constant("MEMTEST_DATA_DEBUG", 1)
+ # UART
+ uart_core_pads = self.cpu.cpupads['serial']
+ self.submodules.uart_phy = uart.UARTPHY(
+ pads = uart_core_pads,
+ clk_freq = self.sys_clk_freq,
+ baudrate = 115200)
+ self.submodules.uart = ResetInserter()(uart.UART(self.uart_phy,
+ tx_fifo_depth = 16,
+ rx_fifo_depth = 16))
+ # "real" pads connect to C4M JTAG iopad
+ uart_pads = platform.request(uart_name) # "real" (actual) pin
+ uart_io_pads = self.cpu.iopads['serial'] # C4M JTAG pads
+ self.comb += uart_pads.tx.eq(uart_io_pads.tx)
+ self.comb += uart_io_pads.rx.eq(uart_pads.rx)
+
+ self.csr.add("uart_phy", use_loc_if_exists=True)
+ self.csr.add("uart", use_loc_if_exists=True)
+ self.irq.add("uart", use_loc_if_exists=True)
+
# GPIOs (bi-directional)
- self.submodules.gpio = GPIOTristateASIC(platform.request("gpio"))
- self.add_csr("gpio")
+ if False:
+ gpio_core_pads = self.cpu.cpupads['gpio']
+ self.submodules.gpio = GPIOTristateASIC(gpio_core_pads)
+ self.add_csr("gpio")
+
+ gpio_pads = platform.request("gpio_litex")
+ gpio_io_pads = self.cpu.iopads['gpio'] # C4M JTAG pads
+ self.comb += gpio_pads.i.eq(gpio_io_pads.i)
+ self.comb += gpio_io_pads.o.eq(gpio_pads.o)
+ self.comb += gpio_io_pads.oe.eq(gpio_pads.oe)
# SPI Master
self.submodules.spi_master = SPIMaster(