From d48108bfd01ec080df359f9831541ca513e6773d Mon Sep 17 00:00:00 2001 From: Vegard Storheil Eriksen Date: Wed, 5 Oct 2022 11:04:45 +0200 Subject: [PATCH] WIP --- deps/litex | 2 +- orbtrace/debug/dbgIF.py | 65 +++++++++++++++++++++++++++- orbtrace/dma8b.py | 21 ++++++++++ orbtrace/soc.py | 93 +++++++++++++++++++++++++++++++++-------- 4 files changed, 162 insertions(+), 19 deletions(-) create mode 100644 orbtrace/dma8b.py diff --git a/deps/litex b/deps/litex index 767647b..b8e22fc 160000 --- a/deps/litex +++ b/deps/litex @@ -1 +1 @@ -Subproject commit 767647bb291522cfe5499f2090c90f03d150d932 +Subproject commit b8e22fcd799cac29c8c78bac7e2ec7fe97a3a35c diff --git a/orbtrace/debug/dbgIF.py b/orbtrace/debug/dbgIF.py index ec430e5..8c10dca 100644 --- a/orbtrace/debug/dbgIF.py +++ b/orbtrace/debug/dbgIF.py @@ -1,8 +1,10 @@ from migen import * +from migen.genlib.cdc import MultiReg from litex.build.io import SDRInput, DDRInput, SDROutput, SDRTristate +from litex.soc.interconnect.csr import AutoCSR, CSRStorage, CSRStatus, CSRField -class DBGIF(Module): +class DBGIF(Module, AutoCSR): def __init__(self, pads): self.addr32 = Signal(2); self.rnw = Signal(); @@ -125,3 +127,64 @@ def __init__(self, pads): o_perr = self.perr, i_dev = self.dev, ) + + def add_csrs(self): + self._cmd = cmd = CSRStorage( + fields = [ + CSRField('cmd', offset = 0, size = 5), + CSRField('addr32', offset = 8, size = 2), + CSRField('rnw', offset = 10, size = 1), + CSRField('apndp', offset = 11, size = 1), + CSRField('dev', offset = 16, size = 3), + ], + ) + + self.comb += [ + self.command.eq(cmd.fields.cmd), + self.addr32.eq(cmd.fields.addr32), + self.rnw.eq(cmd.fields.rnw), + self.apndp.eq(cmd.fields.apndp), + self.dev.eq(cmd.fields.dev), + ] + + self.sync += [ + If(cmd.re, + self.go.eq(1), + ), + If(~self.done, + self.go.eq(0), + ), + ] + + self._status = status = CSRStatus( + fields = [ + CSRField('ack', offset = 0, size = 3), + CSRField('perr', offset = 8, size = 1), + CSRField('done', offset = 9, size = 1), + ], + ) + + done = Signal() + self.specials += MultiReg(self.done, done) + + self.comb += [ + status.fields.ack.eq(self.ack), + status.fields.perr.eq(self.perr), + status.fields.done.eq(~self.go & done), + ] + + self._dwrite = dwrite = CSRStorage(32) + self._dread = dread = CSRStatus(32) + + self.comb += [ + self.dwrite.eq(dwrite.storage), + dread.status.eq(self.dread), + ] + + self._pins_out = pins_out = CSRStorage(16) + self._pins_in = pins_in = CSRStatus(8) + + self.comb += [ + self.pinsin.eq(pins_out.storage), + pins_in.status.eq(self.pinsout), + ] diff --git a/orbtrace/dma8b.py b/orbtrace/dma8b.py new file mode 100644 index 0000000..fcf1025 --- /dev/null +++ b/orbtrace/dma8b.py @@ -0,0 +1,21 @@ +from migen import * + +from litex.soc.interconnect import wishbone + +class DMA8b(Module): + def __init__(self, mem_size): + self.masters = [] + + self.bus = wishbone.Interface() + self.submodules += wishbone.DownConverter(self.bus, self.get_master_port()) + + self.mem_bus = wishbone.Interface(8, 32) + self.submodules += wishbone.SRAM(mem_size, bus = self.mem_bus) + + def get_master_port(self): + bus = wishbone.Interface(8, 32) + self.masters.append(bus) + return bus + + def do_finalize(self): + self.submodules += wishbone.Arbiter(self.masters, self.mem_bus) diff --git a/orbtrace/soc.py b/orbtrace/soc.py index 3640ce6..13bd978 100644 --- a/orbtrace/soc.py +++ b/orbtrace/soc.py @@ -9,6 +9,8 @@ from litex.soc.integration.soc_core import SoCCore from litex.soc.integration.soc import SoCRegion +from .dma8b import DMA8b + from .trace import TraceCore from .trace.usb_handler import TraceUSBHandler @@ -42,6 +44,8 @@ from litex.soc.interconnect.stream import Endpoint, Pipeline, AsyncFIFO, ClockDomainCrossing, Converter, Multiplexer, Demultiplexer from litex.soc.interconnect.axi import AXILiteInterface, AXILiteClockDomainCrossing +from litex.soc.cores.dma import WishboneDMAReader, WishboneDMAWriter + from litespi.phy.generic import LiteSPIPHY from litespi import LiteSPI @@ -91,6 +95,31 @@ def out_ep(self): return n class OrbSoC(SoCCore): + csr_map = { + # Info and system management: + 'meta': 0, + 'flash_uid': 1, + 'led_ctrl': 2, + 'i2c': 3, + + # Common LiteX SoC peripherals: + 'ctrl': 4, + 'timer0': 5, + 'uart': 6, + + # Orbtrace peripherals: + 'dbgif': 8, + + # Stream DMA: + 'cmsis_dap_out': 12, + 'cmsis_dap_in': 13, + } + + interrupt_map = { + 'timer0': 0, + 'uart': 1, + } + def __init__(self, platform, sys_clk_freq, with_debug, with_trace, with_target_power, with_dfu, with_reset_csr, with_test_io, usb_vid, usb_pid, led_default, bootloader_auto_reset, **kwargs): # SoCCore @@ -104,6 +133,9 @@ def __init__(self, platform, sys_clk_freq, with_debug, with_trace, with_target_p # Flash self.add_flash() + # DMA8b + self.add_dma8b() + # Amaranth wrapper self.add_wrapper() @@ -243,6 +275,22 @@ def add_flash(self): port.source.connect(self.flash_uid.phy_sink), ] + def add_dma8b(self, size = 2048): + self.submodules.dma8b = DMA8b(size) + + dma8b_region = SoCRegion( + origin = self.mem_map.get('dma8b', 0xe0000000), + size = size, + mode = 'rw', + cached = False, + ) + + self.bus.add_slave( + name = 'dma8b', + slave = self.dma8b.bus, + region = dma8b_region, + ) + def add_target_power(self): pads = self.platform.request('target_power') @@ -289,23 +337,31 @@ def add_debug(self): # DBGIF self.submodules.dbgif = DBGIF(self.platform.request('debug')) + self.dbgif.add_csrs() + # SWO self.comb += self.trace.swo.eq(self.dbgif.swo) def add_cmsis_dap(self, with_v1 = True, with_v2 = True): # CMSIS-DAP. - self.submodules.cmsis_dap = CMSIS_DAP(self.dbgif, wrapper = self.wrapper) + #self.submodules.cmsis_dap = CMSIS_DAP(self.dbgif, wrapper = self.wrapper) + + # DMA + self.submodules.cmsis_dap_out = WishboneDMAWriter(self.dma8b.get_master_port()) + self.cmsis_dap_out.add_csr(ready_on_idle = 0) + self.submodules.cmsis_dap_in = WishboneDMAReader(self.dma8b.get_master_port()) + self.cmsis_dap_in.add_csr() # LEDs - if hasattr(self, 'led_debug'): - self.comb += [ - If(self.cmsis_dap.running, - self.led_debug.g.eq(1), - ).Elif(self.cmsis_dap.connected, - self.led_debug.r.eq(1), - self.led_debug.g.eq(1), - ), - ] + #if hasattr(self, 'led_debug'): + # self.comb += [ + # If(self.cmsis_dap.running, + # self.led_debug.g.eq(1), + # ).Elif(self.cmsis_dap.connected, + # self.led_debug.r.eq(1), + # self.led_debug.g.eq(1), + # ), + # ] if with_v1: # USB interface. @@ -398,18 +454,21 @@ def add_cmsis_dap(self, with_v1 = True, with_v2 = True): in_cdc = ClockDomainCrossing(stream_desc, 'sys', 'usb') out_cdc = ClockDomainCrossing(stream_desc, 'usb', 'sys') - pipeline = Pipeline(out_stream, out_cdc, self.cmsis_dap, in_cdc, in_stream) + #pipeline = Pipeline(out_stream, out_cdc, self.cmsis_dap, in_cdc, in_stream) + pipeline_out = Pipeline(out_stream, out_cdc, self.cmsis_dap_out) + pipeline_in = Pipeline(self.cmsis_dap_in, in_cdc, in_stream) - self.submodules += in_cdc, out_cdc, pipeline + #self.submodules += in_cdc, out_cdc, pipeline + self.submodules += in_cdc, out_cdc, pipeline_out, pipeline_in # Interface mux. is_v2 = Signal() - self.comb += self.cmsis_dap.is_v2.eq(is_v2) + #self.comb += self.cmsis_dap.is_v2.eq(is_v2) - can = self.platform.request('gpio', 0) - self.comb += can.data.eq(self.cmsis_dap.can) - if hasattr(can, 'dir'): - self.comb += can.dir.eq(1) + #can = self.platform.request('gpio', 0) + #self.comb += can.data.eq(self.cmsis_dap.can) + #if hasattr(can, 'dir'): + # self.comb += can.dir.eq(1) if with_v1 and with_v2: out_mux = Multiplexer(stream_desc, 2)