gateware,runtime: use new migen/misoc

pull/235/head
Sebastien Bourdeauducq 2015-11-04 00:35:03 +08:00
parent 644a410c90
commit e26147b2ac
76 changed files with 343 additions and 270 deletions

2
.gitignore vendored
View File

@ -5,7 +5,7 @@ __pycache__
*.bin *.bin
*.elf *.elf
*.fbi *.fbi
soc/runtime/service_table.h artiq/runtime/service_table.h
doc/manual/_build doc/manual/_build
/build /build
/dist /dist

4
.gitmodules vendored
View File

@ -1,4 +1,4 @@
[submodule "soc/runtime/lwip"] [submodule "artiq/runtime/lwip"]
path = soc/runtime/lwip path = artiq/runtime/lwip
url = git://git.savannah.nongnu.org/lwip.git url = git://git.savannah.nongnu.org/lwip.git
ignore = untracked ignore = untracked

View File

@ -10,7 +10,7 @@ import os
from quamash import QEventLoop, QtGui, QtCore from quamash import QEventLoop, QtGui, QtCore
from pyqtgraph import dockarea from pyqtgraph import dockarea
from artiq.tools import verbosity_args, init_logger from artiq.tools import verbosity_args, init_logger, artiq_dir
from artiq.protocols.pc_rpc import AsyncioClient from artiq.protocols.pc_rpc import AsyncioClient
from artiq.gui.state import StateManager from artiq.gui.state import StateManager
from artiq.gui.explorer import ExplorerDock from artiq.gui.explorer import ExplorerDock
@ -21,10 +21,6 @@ from artiq.gui.log import LogDock
from artiq.gui.console import ConsoleDock from artiq.gui.console import ConsoleDock
data_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)),
"..", "gui")
def get_argparser(): def get_argparser():
parser = argparse.ArgumentParser(description="ARTIQ GUI client") parser = argparse.ArgumentParser(description="ARTIQ GUI client")
parser.add_argument( parser.add_argument(
@ -46,7 +42,8 @@ def get_argparser():
class MainWindow(QtGui.QMainWindow): class MainWindow(QtGui.QMainWindow):
def __init__(self, app, server): def __init__(self, app, server):
QtGui.QMainWindow.__init__(self) QtGui.QMainWindow.__init__(self)
self.setWindowIcon(QtGui.QIcon(os.path.join(data_dir, "icon.png"))) icon = QtGui.QIcon(os.path.join(artiq_dir, "gui", "icon.png"))
self.setWindowIcon(icon)
self.setWindowTitle("ARTIQ - {}".format(server)) self.setWindowTitle("ARTIQ - {}".format(server))
self.exit_request = asyncio.Event() self.exit_request = asyncio.Event()

View File

@ -1,18 +1,16 @@
from migen.fhdl.std import * from migen import *
from migen.genlib.fsm import * from migen.genlib.fsm import *
from migen.genlib.misc import WaitTimer from migen.genlib.misc import WaitTimer
from migen.bus import wishbone from misoc.interconnect import wishbone
from migen.bus.transactions import *
from migen.sim.generic import run_simulation
class AD9xxx(Module): class AD9xxx(Module):
"""Wishbone interface to the AD9858 and AD9914 DDS chips. """Wishbone interface to the AD9858 and AD9914 DDS chips.
Addresses 0-2**flen(pads.a)-1 map the AD9xxx registers. Addresses 0-2**len(pads.a)-1 map the AD9xxx registers.
Write to address 2**flen(pads.a) to pulse the FUD signal. Write to address 2**len(pads.a) to pulse the FUD signal.
Address 2**flen(pads.a)+1 is a GPIO register that controls the Address 2**len(pads.a)+1 is a GPIO register that controls the
sel and reset signals. rst is mapped to bit 0, followed by sel. sel and reset signals. rst is mapped to bit 0, followed by sel.
Write timing: Write timing:
@ -38,15 +36,15 @@ class AD9xxx(Module):
read_wait_cycles=10, hiz_wait_cycles=3, read_wait_cycles=10, hiz_wait_cycles=3,
bus=None): bus=None):
if bus is None: if bus is None:
bus = wishbone.Interface(data_width=flen(pads.d)) bus = wishbone.Interface(data_width=len(pads.d))
self.bus = bus self.bus = bus
# # # # # #
dts = TSTriple(flen(pads.d)) dts = TSTriple(len(pads.d))
self.specials += dts.get_tristate(pads.d) self.specials += dts.get_tristate(pads.d)
hold_address = Signal() hold_address = Signal()
dr = Signal(flen(pads.d)) dr = Signal(len(pads.d))
rx = Signal() rx = Signal()
self.sync += [ self.sync += [
If(~hold_address, pads.a.eq(bus.adr)), If(~hold_address, pads.a.eq(bus.adr)),
@ -56,9 +54,9 @@ class AD9xxx(Module):
] ]
if hasattr(pads, "sel"): if hasattr(pads, "sel"):
sel_len = flen(pads.sel) sel_len = len(pads.sel)
else: else:
sel_len = flen(pads.sel_n) sel_len = len(pads.sel_n)
gpio = Signal(sel_len + 1) gpio = Signal(sel_len + 1)
gpio_load = Signal() gpio_load = Signal()
self.sync += If(gpio_load, gpio.eq(bus.dat_w)) self.sync += If(gpio_load, gpio.eq(bus.dat_w))
@ -98,7 +96,7 @@ class AD9xxx(Module):
fsm.act("IDLE", fsm.act("IDLE",
If(bus.cyc & bus.stb, If(bus.cyc & bus.stb,
If(bus.adr[flen(pads.a)], If(bus.adr[len(pads.a)],
If(bus.adr[0], If(bus.adr[0],
NextState("GPIO") NextState("GPIO")
).Else( ).Else(
@ -157,20 +155,20 @@ class AD9xxx(Module):
) )
def _test_gen(): def _test_gen(bus):
# Test external bus writes # Test external bus writes
yield TWrite(4, 2) yield from bus.write(4, 2)
yield TWrite(5, 3) yield from bus.write(5, 3)
yield yield
# Test external bus reads # Test external bus reads
yield TRead(14) yield from bus.read(14)
yield TRead(15) yield from bus.read(15)
yield yield
# Test FUD # Test FUD
yield TWrite(64, 0) yield from bus.write(64, 0)
yield yield
# Test GPIO # Test GPIO
yield TWrite(65, 0xff) yield from bus.write(65, 0xff)
yield yield
@ -185,14 +183,7 @@ class _TestPads:
self.rst_n = Signal() self.rst_n = Signal()
class _TB(Module):
def __init__(self):
pads = _TestPads()
self.submodules.dut = AD9xxx(pads, drive_fud=True)
self.submodules.initiator = wishbone.Initiator(_test_gen())
self.submodules.interconnect = wishbone.InterconnectPointToPoint(
self.initiator.bus, self.dut.bus)
if __name__ == "__main__": if __name__ == "__main__":
run_simulation(_TB(), vcd_name="ad9xxx.vcd") pads = _TestPads()
dut = AD9xxx(pads)
run_simulation(dut, _test_gen(dut.bus), vcd_name="ad9xxx.vcd")

View File

@ -1,9 +1,8 @@
from migen.fhdl.std import * from migen import *
from migen.bank.description import * from misoc.interconnect.csr import *
from migen.bus import wishbone from misoc.interconnect import wishbone
from misoc.cores import mor1kx
from misoclib.cpu import mor1kx from misoc.integration.soc_core import mem_decoder
from misoclib.soc import mem_decoder
class KernelCPU(Module): class KernelCPU(Module):
@ -23,9 +22,8 @@ class KernelCPU(Module):
self.cd_sys_kernel.clk.eq(ClockSignal()), self.cd_sys_kernel.clk.eq(ClockSignal()),
self.cd_sys_kernel.rst.eq(self._reset.storage) self.cd_sys_kernel.rst.eq(self._reset.storage)
] ]
self.submodules.cpu = RenameClockDomains( self.submodules.cpu = ClockDomainsRenamer("sys_kernel")(
mor1kx.MOR1KX(platform, exec_address), mor1kx.MOR1KX(platform, exec_address))
"sys_kernel")
# DRAM access # DRAM access
self.wb_sdram = wishbone.Interface() self.wb_sdram = wishbone.Interface()

View File

@ -1,5 +1,5 @@
from migen.fhdl.std import * from migen import *
from migen.bus import wishbone from misoc.interconnect import wishbone
class Mailbox(Module): class Mailbox(Module):

View File

@ -1,4 +1,4 @@
from mibuild.generic_platform import * from migen.build.generic_platform import *
papilio_adapter_io = [ papilio_adapter_io = [

View File

@ -1,4 +1,4 @@
from mibuild.generic_platform import * from migen.build.generic_platform import *
fmc_adapter_io = [ fmc_adapter_io = [

View File

@ -1,10 +1,12 @@
from migen.fhdl.std import * from functools import reduce
from migen.bank.description import * from operator import and_
from migen.genlib.misc import optree
from migen import *
from migen.genlib.record import Record from migen.genlib.record import Record
from migen.genlib.cdc import * from migen.genlib.cdc import *
from migen.genlib.fifo import AsyncFIFO from migen.genlib.fifo import AsyncFIFO
from migen.genlib.resetsync import AsyncResetSynchronizer from migen.genlib.resetsync import AsyncResetSynchronizer
from misoc.interconnect.csr import *
from artiq.gateware.rtio import rtlink from artiq.gateware.rtio import rtlink
@ -105,9 +107,15 @@ class _OutputManager(Module):
# # # # # #
# FIFO # FIFO
fifo = RenameClockDomains(AsyncFIFO(ev_layout, fifo_depth), fifo = ClockDomainsRenamer({"write": "rsys", "read": "rio"})(
{"write": "rsys", "read": "rio"}) AsyncFIFO(layout_len(ev_layout), fifo_depth))
self.submodules += fifo self.submodules += fifo
fifo_in = Record(ev_layout)
fifo_out = Record(ev_layout)
self.comb += [
fifo.din.eq(fifo_in.raw_bits()),
fifo_out.raw_bits().eq(fifo.dout)
]
# Buffer # Buffer
buf_pending = Signal() buf_pending = Signal()
@ -138,13 +146,15 @@ class _OutputManager(Module):
if interface.suppress_nop: if interface.suppress_nop:
# disable NOP at reset: do not suppress a first write with all 0s # disable NOP at reset: do not suppress a first write with all 0s
nop_en = Signal(reset=0) nop_en = Signal(reset=0)
addresses_equal = [getattr(self.ev, a) == getattr(buf, a)
for a in ("data", "address")
if hasattr(self.ev, a)]
if addresses_equal:
self.sync.rsys += nop.eq(
nop_en & reduce(and_, addresses_equal))
else:
self.comb.eq(nop.eq(0))
self.sync.rsys += [ self.sync.rsys += [
nop.eq(nop_en &
optree("&",
[getattr(self.ev, a) == getattr(buf, a)
for a in ("data", "address")
if hasattr(self.ev, a)],
default=0)),
# buf now contains valid data. enable NOP. # buf now contains valid data. enable NOP.
If(self.we & ~any_error, nop_en.eq(1)), If(self.we & ~any_error, nop_en.eq(1)),
# underflows cancel the write. allow it to be retried. # underflows cancel the write. allow it to be retried.
@ -156,7 +166,7 @@ class _OutputManager(Module):
] ]
# Buffer read and FIFO write # Buffer read and FIFO write
self.comb += fifo.din.eq(buf) self.comb += fifo_in.eq(buf)
in_guard_time = Signal() in_guard_time = Signal()
self.comb += in_guard_time.eq( self.comb += in_guard_time.eq(
buf.timestamp[fine_ts_width:] buf.timestamp[fine_ts_width:]
@ -195,7 +205,7 @@ class _OutputManager(Module):
self.sync.rio += \ self.sync.rio += \
If(fifo.re, If(fifo.re,
dout_stb.eq(1), dout_stb.eq(1),
dout.eq(fifo.dout) dout.eq(fifo_out)
).Elif(dout_ack, ).Elif(dout_ack,
dout_stb.eq(0) dout_stb.eq(0)
) )
@ -235,24 +245,30 @@ class _InputManager(Module):
# # # # # #
fifo = RenameClockDomains(AsyncFIFO(ev_layout, fifo_depth), fifo = ClockDomainsRenamer({"read": "rsys", "write": "rio"})(
{"read": "rsys", "write": "rio"}) AsyncFIFO(layout_len(ev_layout), fifo_depth))
self.submodules += fifo self.submodules += fifo
fifo_in = Record(ev_layout)
fifo_out = Record(ev_layout)
self.comb += [
fifo.din.eq(fifo_in.raw_bits()),
fifo_out.raw_bits().eq(fifo.dout)
]
# FIFO write # FIFO write
if data_width: if data_width:
self.comb += fifo.din.data.eq(interface.data) self.comb += fifo_in.data.eq(interface.data)
if interface.timestamped: if interface.timestamped:
if fine_ts_width: if fine_ts_width:
full_ts = Cat(interface.fine_ts, counter.value_rio) full_ts = Cat(interface.fine_ts, counter.value_rio)
else: else:
full_ts = counter.value_rio full_ts = counter.value_rio
self.comb += fifo.din.timestamp.eq(full_ts) self.comb += fifo_in.timestamp.eq(full_ts)
self.comb += fifo.we.eq(interface.stb) self.comb += fifo.we.eq(interface.stb)
# FIFO read # FIFO read
self.comb += [ self.comb += [
self.ev.eq(fifo.dout), self.ev.eq(fifo_out),
self.readable.eq(fifo.readable), self.readable.eq(fifo.readable),
fifo.re.eq(self.re) fifo.re.eq(self.re)
] ]
@ -376,8 +392,8 @@ class RTIO(Module):
if hasattr(o_manager.ev, "address"): if hasattr(o_manager.ev, "address"):
self.comb += o_manager.ev.address.eq( self.comb += o_manager.ev.address.eq(
self.kcsrs.o_address.storage) self.kcsrs.o_address.storage)
ts_shift = (flen(self.kcsrs.o_timestamp.storage) ts_shift = (len(self.kcsrs.o_timestamp.storage)
- flen(o_manager.ev.timestamp)) - len(o_manager.ev.timestamp))
self.comb += o_manager.ev.timestamp.eq( self.comb += o_manager.ev.timestamp.eq(
self.kcsrs.o_timestamp.storage[ts_shift:]) self.kcsrs.o_timestamp.storage[ts_shift:])
@ -412,8 +428,8 @@ class RTIO(Module):
else: else:
i_datas.append(0) i_datas.append(0)
if channel.interface.i.timestamped: if channel.interface.i.timestamped:
ts_shift = (flen(self.kcsrs.i_timestamp.status) ts_shift = (len(self.kcsrs.i_timestamp.status)
- flen(i_manager.ev.timestamp)) - len(i_manager.ev.timestamp))
i_timestamps.append(i_manager.ev.timestamp << ts_shift) i_timestamps.append(i_manager.ev.timestamp << ts_shift)
else: else:
i_timestamps.append(0) i_timestamps.append(0)

View File

@ -1,6 +1,6 @@
from migen.fhdl.std import * from migen import *
from migen.bank.description import *
from migen.genlib.cdc import BusSynchronizer, MultiReg from migen.genlib.cdc import BusSynchronizer, MultiReg
from misoc.interconnect.csr import *
class Monitor(Module, AutoCSR): class Monitor(Module, AutoCSR):
@ -8,7 +8,7 @@ class Monitor(Module, AutoCSR):
chan_probes = [c.probes for c in channels] chan_probes = [c.probes for c in channels]
max_chan_probes = max(len(cp) for cp in chan_probes) max_chan_probes = max(len(cp) for cp in chan_probes)
max_probe_len = max(flen(p) for cp in chan_probes for p in cp) max_probe_len = max(len(p) for cp in chan_probes for p in cp)
self.chan_sel = CSRStorage(bits_for(len(chan_probes)-1)) self.chan_sel = CSRStorage(bits_for(len(chan_probes)-1))
self.probe_sel = CSRStorage(bits_for(max_chan_probes-1)) self.probe_sel = CSRStorage(bits_for(max_chan_probes-1))
self.value_update = CSR() self.value_update = CSR()
@ -20,7 +20,7 @@ class Monitor(Module, AutoCSR):
for cp in chan_probes: for cp in chan_probes:
cp_sys = [] cp_sys = []
for p in cp: for p in cp:
vs = BusSynchronizer(flen(p), "rio", "rsys") vs = BusSynchronizer(len(p), "rio", "rsys")
self.submodules += vs self.submodules += vs
self.comb += vs.i.eq(p) self.comb += vs.i.eq(p)
cp_sys.append(vs.o) cp_sys.append(vs.o)
@ -36,7 +36,7 @@ class Injector(Module, AutoCSR):
chan_overrides = [c.overrides for c in channels] chan_overrides = [c.overrides for c in channels]
max_chan_overrides = max(len(co) for co in chan_overrides) max_chan_overrides = max(len(co) for co in chan_overrides)
max_override_len = max(flen(o) for co in chan_overrides for o in co) max_override_len = max(len(o) for co in chan_overrides for o in co)
self.chan_sel = CSRStorage(bits_for(len(chan_overrides)-1)) self.chan_sel = CSRStorage(bits_for(len(chan_overrides)-1))
self.override_sel = CSRStorage(bits_for(max_chan_overrides-1)) self.override_sel = CSRStorage(bits_for(max_chan_overrides-1))
self.value = CSR(max_override_len) self.value = CSR(max_override_len)

View File

@ -1,4 +1,4 @@
from migen.fhdl.std import * from migen import *
from artiq.gateware import ad9xxx from artiq.gateware import ad9xxx
from artiq.gateware.rtio.phy.wishbone import RT2WB from artiq.gateware.rtio.phy.wishbone import RT2WB
@ -6,9 +6,9 @@ from artiq.gateware.rtio.phy.wishbone import RT2WB
class _AD9xxx(Module): class _AD9xxx(Module):
def __init__(self, ftw_base, pads, nchannels, onehot=False, **kwargs): def __init__(self, ftw_base, pads, nchannels, onehot=False, **kwargs):
self.submodules._ll = RenameClockDomains( self.submodules._ll = ClockDomainsRenamer("rio")(
ad9xxx.AD9xxx(pads, **kwargs), "rio") ad9xxx.AD9xxx(pads, **kwargs))
self.submodules._rt2wb = RT2WB(flen(pads.a)+1, self._ll.bus) self.submodules._rt2wb = RT2WB(len(pads.a)+1, self._ll.bus)
self.rtlink = self._rt2wb.rtlink self.rtlink = self._rt2wb.rtlink
self.probes = [Signal(32) for i in range(nchannels)] self.probes = [Signal(32) for i in range(nchannels)]
@ -22,8 +22,8 @@ class _AD9xxx(Module):
current_data.eq(self.rtlink.o.data)) current_data.eq(self.rtlink.o.data))
# keep track of the currently selected channel(s) # keep track of the currently selected channel(s)
current_sel = Signal(flen(current_data)-1) current_sel = Signal(len(current_data)-1)
self.sync.rio += If(current_address == 2**flen(pads.a) + 1, self.sync.rio += If(current_address == 2**len(pads.a) + 1,
current_sel.eq(current_data[1:])) # strip reset current_sel.eq(current_data[1:])) # strip reset
def selected(c): def selected(c):
@ -35,13 +35,13 @@ class _AD9xxx(Module):
# keep track of frequency tuning words, before they are FUDed # keep track of frequency tuning words, before they are FUDed
ftws = [Signal(32) for i in range(nchannels)] ftws = [Signal(32) for i in range(nchannels)]
for c, ftw in enumerate(ftws): for c, ftw in enumerate(ftws):
if flen(pads.d) == 8: if len(pads.d) == 8:
self.sync.rio_phy += \ self.sync.rio_phy += \
If(selected(c), [ If(selected(c), [
If(current_address == ftw_base+i, If(current_address == ftw_base+i,
ftw[i*8:(i+1)*8].eq(current_data)) ftw[i*8:(i+1)*8].eq(current_data))
for i in range(4)]) for i in range(4)])
elif flen(pads.d) == 16: elif len(pads.d) == 16:
self.sync.rio_phy += \ self.sync.rio_phy += \
If(selected(c), [ If(selected(c), [
If(current_address == ftw_base+2*i, If(current_address == ftw_base+2*i,
@ -51,7 +51,7 @@ class _AD9xxx(Module):
raise NotImplementedError raise NotImplementedError
# FTW to probe on FUD # FTW to probe on FUD
self.sync.rio_phy += If(current_address == 2**flen(pads.a), [ self.sync.rio_phy += If(current_address == 2**len(pads.a), [
If(selected(c), probe.eq(ftw)) If(selected(c), probe.eq(ftw))
for c, (probe, ftw) in enumerate(zip(self.probes, ftws))]) for c, (probe, ftw) in enumerate(zip(self.probes, ftws))])

View File

@ -1,4 +1,4 @@
from migen.fhdl.std import * from migen import *
from artiq.gateware.rtio.phy import ttl_serdes_generic from artiq.gateware.rtio.phy import ttl_serdes_generic

View File

@ -1,4 +1,4 @@
from migen.fhdl.std import * from migen import *
from migen.genlib.coding import PriorityEncoder from migen.genlib.coding import PriorityEncoder
from artiq.gateware.rtio import rtlink from artiq.gateware.rtio import rtlink
@ -18,7 +18,7 @@ def _mk_edges(w, direction):
class _SerdesDriver(Module): class _SerdesDriver(Module):
def __init__(self, serdes_o, stb, data, fine_ts, override_en, override_o): def __init__(self, serdes_o, stb, data, fine_ts, override_en, override_o):
previous_data = Signal() previous_data = Signal()
serdes_width = flen(serdes_o) serdes_width = len(serdes_o)
edges = Array(_mk_edges(serdes_width, "rising")) edges = Array(_mk_edges(serdes_width, "rising"))
edges_n = Array(_mk_edges(serdes_width, "falling")) edges_n = Array(_mk_edges(serdes_width, "falling"))
self.sync.rio_phy += [ self.sync.rio_phy += [
@ -40,7 +40,7 @@ class _SerdesDriver(Module):
class Output(Module): class Output(Module):
def __init__(self, serdes): def __init__(self, serdes):
self.rtlink = rtlink.Interface( self.rtlink = rtlink.Interface(
rtlink.OInterface(1, fine_ts_width=log2_int(flen(serdes.o)))) rtlink.OInterface(1, fine_ts_width=log2_int(len(serdes.o))))
self.probes = [serdes.o[-1]] self.probes = [serdes.o[-1]]
override_en = Signal() override_en = Signal()
override_o = Signal() override_o = Signal()
@ -56,8 +56,8 @@ class Output(Module):
class Inout(Module): class Inout(Module):
def __init__(self, serdes): def __init__(self, serdes):
serdes_width = flen(serdes.o) serdes_width = len(serdes.o)
assert flen(serdes.i) == serdes_width assert len(serdes.i) == serdes_width
self.rtlink = rtlink.Interface( self.rtlink = rtlink.Interface(
rtlink.OInterface(2, 2, fine_ts_width=log2_int(serdes_width)), rtlink.OInterface(2, 2, fine_ts_width=log2_int(serdes_width)),
rtlink.IInterface(1, fine_ts_width=log2_int(serdes_width))) rtlink.IInterface(1, fine_ts_width=log2_int(serdes_width)))

View File

@ -1,6 +1,6 @@
# Copyright (C) 2014, 2015 Robert Jordens <jordens@gmail.com> # Copyright (C) 2014, 2015 Robert Jordens <jordens@gmail.com>
from migen.fhdl.std import * from migen import *
from artiq.gateware.rtio.phy import ttl_serdes_generic from artiq.gateware.rtio.phy import ttl_serdes_generic

View File

@ -1,4 +1,4 @@
from migen.fhdl.std import * from migen import *
from migen.genlib.cdc import MultiReg from migen.genlib.cdc import MultiReg
from artiq.gateware.rtio import rtlink from artiq.gateware.rtio import rtlink

View File

@ -1,5 +1,5 @@
from migen.fhdl.std import * from migen import *
from migen.bus import wishbone from misoc.interconnect import wishbone
from artiq.gateware.rtio import rtlink from artiq.gateware.rtio import rtlink
@ -11,11 +11,11 @@ class RT2WB(Module):
self.wb = wb self.wb = wb
self.rtlink = rtlink.Interface( self.rtlink = rtlink.Interface(
rtlink.OInterface( rtlink.OInterface(
flen(wb.dat_w), len(wb.dat_w),
address_width + 1, address_width + 1,
suppress_nop=False), suppress_nop=False),
rtlink.IInterface( rtlink.IInterface(
flen(wb.dat_r), len(wb.dat_r),
timestamped=False) timestamped=False)
) )
@ -28,7 +28,7 @@ class RT2WB(Module):
wb.adr.eq(self.rtlink.o.address[:address_width]), wb.adr.eq(self.rtlink.o.address[:address_width]),
wb.we.eq(~self.rtlink.o.address[address_width]), wb.we.eq(~self.rtlink.o.address[address_width]),
wb.dat_w.eq(self.rtlink.o.data), wb.dat_w.eq(self.rtlink.o.data),
wb.sel.eq(2**flen(wb.sel) - 1) wb.sel.eq(2**len(wb.sel) - 1)
), ),
If(wb.ack, If(wb.ack,
active.eq(0) active.eq(0)

View File

@ -1,4 +1,4 @@
from migen.fhdl.std import * from migen import *
class OInterface: class OInterface:
@ -64,7 +64,7 @@ def _get_or_zero(interface, attr):
_get_or_zero(interface.o, attr)) _get_or_zero(interface.o, attr))
else: else:
if hasattr(interface, attr): if hasattr(interface, attr):
return flen(getattr(interface, attr)) return len(getattr(interface, attr))
else: else:
return 0 return 0

View File

@ -1,5 +1,5 @@
from misoclib.soc import mem_decoder from misoc.integration.soc_core import mem_decoder
from misoclib.cpu import timer from misoc.cores import timer
from artiq.gateware import amp from artiq.gateware import amp
@ -11,7 +11,7 @@ class AMPSoC:
a "mailbox" entry in the memory map. a "mailbox" entry in the memory map.
""" """
def __init__(self): def __init__(self):
if not hasattr(self, "cpu_or_bridge"): if not hasattr(self, "cpu"):
raise ValueError("Platform SoC must be initialized first") raise ValueError("Platform SoC must be initialized first")
if hasattr(self, "timer0"): if hasattr(self, "timer0"):
raise ValueError("Timer already exists. " raise ValueError("Timer already exists. "

View File

@ -1,20 +1,26 @@
from migen.fhdl.std import * #!/usr/bin/env python3
import argparse
import os
from migen import *
from migen.genlib.resetsync import AsyncResetSynchronizer from migen.genlib.resetsync import AsyncResetSynchronizer
from migen.genlib.cdc import MultiReg from migen.genlib.cdc import MultiReg
from migen.bank.description import * from migen.build.generic_platform import *
from migen.bank import wbgen from migen.build.xilinx.vivado import XilinxVivadoToolchain
from mibuild.generic_platform import * from migen.build.xilinx.ise import XilinxISEToolchain
from mibuild.xilinx.vivado import XilinxVivadoToolchain
from mibuild.xilinx.ise import XilinxISEToolchain
from misoclib.com import gpio from misoc.interconnect.csr import *
from misoclib.soc import mem_decoder from misoc.interconnect import wishbone
from misoclib.mem.sdram.core.minicon import MiniconSettings from misoc.cores import gpio
from targets.kc705 import MiniSoC from misoc.integration.soc_core import mem_decoder
from misoc.integration.builder import *
from misoc.targets.kc705 import MiniSoC, soc_kc705_args, soc_kc705_argdict
from artiq.gateware.soc import AMPSoC from artiq.gateware.soc import AMPSoC
from artiq.gateware import rtio, nist_qc1, nist_qc2 from artiq.gateware import rtio, nist_qc1, nist_qc2
from artiq.gateware.rtio.phy import ttl_simple, ttl_serdes_7series, dds from artiq.gateware.rtio.phy import ttl_simple, ttl_serdes_7series, dds
from artiq.tools import artiq_dir
class _RTIOCRG(Module, AutoCSR): class _RTIOCRG(Module, AutoCSR):
@ -87,15 +93,17 @@ class _NIST_QCx(MiniSoC, AMPSoC):
} }
mem_map.update(MiniSoC.mem_map) mem_map.update(MiniSoC.mem_map)
def __init__(self, platform, cpu_type="or1k", **kwargs): def __init__(self, cpu_type="or1k", **kwargs):
MiniSoC.__init__(self, platform, MiniSoC.__init__(self,
cpu_type=cpu_type, cpu_type=cpu_type,
sdram_controller_settings=MiniconSettings(l2_size=128*1024), sdram_controller_type="minicon",
l2_size=128*1024,
with_timer=False, **kwargs) with_timer=False, **kwargs)
AMPSoC.__init__(self) AMPSoC.__init__(self)
self.submodules.leds = gpio.GPIOOut(Cat( self.submodules.leds = gpio.GPIOOut(Cat(
platform.request("user_led", 0), self.platform.request("user_led", 0),
platform.request("user_led", 1))) self.platform.request("user_led", 1)))
def add_rtio(self, rtio_channels): def add_rtio(self, rtio_channels):
self.submodules.rtio_crg = _RTIOCRG(self.platform, self.crg.cd_sys.clk) self.submodules.rtio_crg = _RTIOCRG(self.platform, self.crg.cd_sys.clk)
@ -121,7 +129,7 @@ TIMESPEC "TSfix_cdc2" = FROM "GRPrio_clk" TO "GRPrsys_clk" TIG;
""", rio_clk=self.rtio_crg.cd_rtio.clk) """, rio_clk=self.rtio_crg.cd_rtio.clk)
rtio_csrs = self.rtio.get_csrs() rtio_csrs = self.rtio.get_csrs()
self.submodules.rtiowb = wbgen.Bank(rtio_csrs) self.submodules.rtiowb = wishbone.CSRBank(rtio_csrs)
self.kernel_cpu.add_wb_slave(mem_decoder(self.mem_map["rtio"]), self.kernel_cpu.add_wb_slave(mem_decoder(self.mem_map["rtio"]),
self.rtiowb.bus) self.rtiowb.bus)
self.add_csr_region("rtio", self.mem_map["rtio"] | 0x80000000, 32, self.add_csr_region("rtio", self.mem_map["rtio"] | 0x80000000, 32,
@ -129,8 +137,10 @@ TIMESPEC "TSfix_cdc2" = FROM "GRPrio_clk" TO "GRPrsys_clk" TIG;
class NIST_QC1(_NIST_QCx): class NIST_QC1(_NIST_QCx):
def __init__(self, platform, cpu_type="or1k", **kwargs): def __init__(self, cpu_type="or1k", **kwargs):
_NIST_QCx.__init__(self, platform, cpu_type, **kwargs) _NIST_QCx.__init__(self, cpu_type, **kwargs)
platform = self.platform
platform.add_extension(nist_qc1.fmc_adapter_io) platform.add_extension(nist_qc1.fmc_adapter_io)
self.comb += [ self.comb += [
@ -174,6 +184,8 @@ class NIST_QC1(_NIST_QCx):
class NIST_QC2(_NIST_QCx): class NIST_QC2(_NIST_QCx):
def __init__(self, platform, cpu_type="or1k", **kwargs): def __init__(self, platform, cpu_type="or1k", **kwargs):
_NIST_QCx.__init__(self, platform, cpu_type, **kwargs) _NIST_QCx.__init__(self, platform, cpu_type, **kwargs)
platform = self.platform
platform.add_extension(nist_qc2.fmc_adapter_io) platform.add_extension(nist_qc2.fmc_adapter_io)
rtio_channels = [] rtio_channels = []
@ -214,4 +226,34 @@ class NIST_QC2(_NIST_QCx):
self.add_rtio(rtio_channels) self.add_rtio(rtio_channels)
default_subtarget = NIST_QC1 def main():
parser = argparse.ArgumentParser(
description="ARTIQ core device builder / KC705 "
"+ NIST Ions QC1/QC2 hardware adapters")
builder_args(parser)
soc_kc705_args(parser)
parser.add_argument("-H", "--hw-adapter", default="qc1",
help="hardware adapter type: qc1/qc2 "
"(default: %(default)s)")
args = parser.parse_args()
hw_adapter = args.hw_adapter.lower()
if hw_adapter == "qc1":
cls = NIST_QC1
elif hw_adapter == "qc2":
cls = NIST_QC2
else:
print("Invalid hardware adapter string (-H/--hw-adapter), "
"choose from qc1 or qc2")
sys.exit(1)
soc = cls(**soc_kc705_argdict(args))
builder = Builder(soc, **builder_argdict(args))
builder.add_software_package("liblwip", os.path.join(artiq_dir, "runtime",
"liblwip"))
builder.add_software_package("runtime", os.path.join(artiq_dir, "runtime"))
builder.build()
if __name__ == "__main__":
main()

View File

@ -1,22 +1,26 @@
#!/usr/bin/env python3
# Copyright (C) 2014, 2015 Robert Jordens <jordens@gmail.com> # Copyright (C) 2014, 2015 Robert Jordens <jordens@gmail.com>
# Copyright (C) 2014, 2015 M-Labs Limited # Copyright (C) 2014, 2015 M-Labs Limited
import argparse
import os
from fractions import Fraction from fractions import Fraction
from migen.fhdl.std import * from migen import *
from migen.bank.description import *
from migen.bank import wbgen
from migen.genlib.resetsync import AsyncResetSynchronizer from migen.genlib.resetsync import AsyncResetSynchronizer
from migen.genlib.cdc import MultiReg from migen.genlib.cdc import MultiReg
from misoclib.com import gpio from misoc.interconnect.csr import *
from misoclib.soc import mem_decoder from misoc.interconnect import wishbone
from misoclib.mem.sdram.core.minicon import MiniconSettings from misoc.cores import gpio
from targets.pipistrello import BaseSoC from misoc.integration.soc_core import mem_decoder
from misoc.targets.pipistrello import *
from artiq.gateware.soc import AMPSoC from artiq.gateware.soc import AMPSoC
from artiq.gateware import rtio, nist_qc1 from artiq.gateware import rtio, nist_qc1
from artiq.gateware.rtio.phy import ttl_simple, ttl_serdes_spartan6, dds from artiq.gateware.rtio.phy import ttl_simple, ttl_serdes_spartan6, dds
from artiq.tools import artiq_dir
class _RTIOCRG(Module, AutoCSR): class _RTIOCRG(Module, AutoCSR):
@ -110,12 +114,15 @@ class NIST_QC1(BaseSoC, AMPSoC):
} }
mem_map.update(BaseSoC.mem_map) mem_map.update(BaseSoC.mem_map)
def __init__(self, platform, cpu_type="or1k", **kwargs): def __init__(self, cpu_type="or1k", **kwargs):
BaseSoC.__init__(self, platform, BaseSoC.__init__(self,
cpu_type=cpu_type, cpu_type=cpu_type,
sdram_controller_settings=MiniconSettings(l2_size=64*1024), l2_size=64*1024,
with_timer=False, **kwargs) with_timer=False, **kwargs)
AMPSoC.__init__(self) AMPSoC.__init__(self)
platform = self.platform
platform.toolchain.ise_commands += """ platform.toolchain.ise_commands += """
trce -v 12 -fastpaths -tsi {build_name}.tsi -o {build_name}.twr {build_name}.ncd {build_name}.pcf trce -v 12 -fastpaths -tsi {build_name}.tsi -o {build_name}.twr {build_name}.ncd {build_name}.pcf
""" """
@ -192,11 +199,28 @@ trce -v 12 -fastpaths -tsi {build_name}.tsi -o {build_name}.twr {build_name}.ncd
# CPU connections # CPU connections
rtio_csrs = self.rtio.get_csrs() rtio_csrs = self.rtio.get_csrs()
self.submodules.rtiowb = wbgen.Bank(rtio_csrs) self.submodules.rtiowb = wishbone.CSRBank(rtio_csrs)
self.kernel_cpu.add_wb_slave(mem_decoder(self.mem_map["rtio"]), self.kernel_cpu.add_wb_slave(mem_decoder(self.mem_map["rtio"]),
self.rtiowb.bus) self.rtiowb.bus)
self.add_csr_region("rtio", self.mem_map["rtio"] | 0x80000000, 32, self.add_csr_region("rtio", self.mem_map["rtio"] | 0x80000000, 32,
rtio_csrs) rtio_csrs)
default_subtarget = NIST_QC1 def main():
parser = argparse.ArgumentParser(
description="ARTIQ core device builder / Pipistrello "
"+ NIST Ions QC1 hardware adapter")
builder_args(parser)
soc_pipistrello_args(parser)
args = parser.parse_args()
soc = NIST_QC1(**soc_pipistrello_argdict(args))
builder = Builder(soc, **builder_argdict(args))
builder.add_software_package("liblwip", os.path.join(artiq_dir, "runtime",
"liblwip"))
builder.add_software_package("runtime", os.path.join(artiq_dir, "runtime"))
builder.build()
if __name__ == "__main__":
main()

64
artiq/runtime/Makefile Normal file
View File

@ -0,0 +1,64 @@
include ../include/generated/variables.mak
include $(MISOC_DIRECTORY)/software/common.mak
PYTHON ?= python3
OBJECTS := isr.o flash_storage.o clock.o rtiocrg.o elf_loader.o services.o session.o log.o test_mode.o kloader.o bridge_ctl.o mailbox.o ksupport_data.o net_server.o moninj.o main.o
OBJECTS_KSUPPORT := ksupport.o exception_jmp.o exceptions.o mailbox.o bridge.o rtio.o ttl.o dds.o
CFLAGS += -I$(LIBLWIP_DIRECTORY)/../lwip/src/include -I$(LIBLWIP_DIRECTORY)
all: runtime.bin runtime.fbi
%.bin: %.elf
$(OBJCOPY) -O binary $< $@
@chmod -x $@
%.fbi: %.bin
@echo " MSCIMG " $@ && $(PYTHON) -m misoc.tools.mkmscimg -f -o $@ $<
runtime.elf: $(OBJECTS)
$(LD) $(LDFLAGS) \
-T $(RUNTIME_DIRECTORY)/linker.ld \
-N -o $@ \
../libbase/crt0-$(CPU).o \
$(OBJECTS) \
-L../libbase \
-L../libcompiler_rt \
-L../liblwip \
-lbase -lcompiler_rt -llwip
@chmod -x $@
ksupport.elf: $(OBJECTS_KSUPPORT)
$(LD) $(LDFLAGS) \
-T $(RUNTIME_DIRECTORY)/ksupport.ld \
-N -o $@ \
../libbase/crt0-$(CPU).o \
$^ \
-L../libcompiler_rt \
-lcompiler_rt
@chmod -x $@
ksupport_data.o: ksupport.bin
$(LD) -r -b binary -o $@ $<
service_table.h: ksupport.elf $(RUNTIME_DIRECTORY)/gen_service_table.py
@echo " GEN " $@ && $(PYTHON) $(RUNTIME_DIRECTORY)/gen_service_table.py ksupport.elf > $@
services.c: service_table.h
main.o: $(RUNTIME_DIRECTORY)/main.c
$(compile)
%.o: $(RUNTIME_DIRECTORY)/%.c
$(compile)
%.o: $(RUNTIME_DIRECTORY)/%.S
$(assemble)
clean:
$(RM) $(OBJECTS) $(OBJECTS_KSUPPORT)
$(RM) runtime.elf runtime.bin runtime.fbi .*~ *~
$(RM) service_table.h ksupport.elf ksupport.bin
.PHONY: all clean main.o

View File

@ -0,0 +1,66 @@
include ../include/generated/variables.mak
include $(MISOC_DIRECTORY)/software/common.mak
LWIPDIR=$(LIBLWIP_DIRECTORY)/../lwip/src
CFLAGS += $(CPPFLAGS) -I. \
-I$(LWIPDIR)/include \
-I$(LWIPDIR)/include/ipv4
# COREFILES, CORE4FILES: The minimum set of files needed for lwIP.
COREFILES=core/mem.c \
core/memp.c \
core/netif.c \
core/pbuf.c \
core/raw.c \
core/stats.c \
core/sys.c \
core/tcp.c \
core/tcp_in.c \
core/tcp_out.c \
core/udp.c \
core/dhcp.c \
core/inet_chksum.c \
core/timers.c \
core/init.c
CORE4FILES=core/ipv4/icmp.c \
core/ipv4/ip4.c \
core/ipv4/ip4_addr.c \
core/ipv4/ip_frag.c
# NETIFFILES: Files implementing various generic network interface functions.
NETIFFILES=netif/etharp.c
# LWIPFILES: All the above.
LWIPFILES=$(COREFILES) $(CORE4FILES) $(NETIFFILES)
LWIPOBJS:=$(LWIPFILES:.c=.o) liteethif.o
all: prepare liblwip.a
prepare:
ln -sf $(LIBLWIP_DIRECTORY)/lwipopts.h lwipopts.h
ln -sf $(LIBLWIP_DIRECTORY)/arch arch
mkdir -p core/ipv4
mkdir -p netif
core/%.o: $(LWIPDIR)/core/%.c
$(compile)
core/ipv4/%.o: $(LWIPDIR)/core/ipv4/%.c
$(compile)
netif/%.o: $(LWIPDIR)/netif/%.c
$(compile)
%.o: $(LIBLWIP_DIRECTORY)/%.c
$(compile)
.PHONY: all clean prepare
clean:
rm -f $(LWIPOBJS) liblwip.a
liblwip.a: $(LWIPOBJS)
$(AR) clr liblwip.a $(LWIPOBJS)

View File

@ -10,7 +10,7 @@
#include <lwip/mem.h> #include <lwip/mem.h>
#include <netif/etharp.h> #include <netif/etharp.h>
#include "netif/liteethif.h" #include "liteethif.h"
#include <hw/flags.h> #include <hw/flags.h>
#include <hw/ethmac_mem.h> #include <hw/ethmac_mem.h>

View File

@ -8,8 +8,6 @@
#include <hw/flags.h> #include <hw/flags.h>
#ifdef CSR_ETHMAC_BASE #ifdef CSR_ETHMAC_BASE
#include <netif/etharp.h>
#include <netif/liteethif.h>
#include <lwip/init.h> #include <lwip/init.h>
#include <lwip/memp.h> #include <lwip/memp.h>
#include <lwip/ip4_addr.h> #include <lwip/ip4_addr.h>
@ -18,6 +16,8 @@
#include <lwip/sys.h> #include <lwip/sys.h>
#include <lwip/tcp.h> #include <lwip/tcp.h>
#include <lwip/timers.h> #include <lwip/timers.h>
#include <netif/etharp.h>
#include <liteethif.h>
#endif #endif
#include "bridge_ctl.h" #include "bridge_ctl.h"

View File

@ -2,8 +2,6 @@
#ifdef CSR_ETHMAC_BASE #ifdef CSR_ETHMAC_BASE
#include <netif/etharp.h>
#include <netif/liteethif.h>
#include <lwip/init.h> #include <lwip/init.h>
#include <lwip/memp.h> #include <lwip/memp.h>
#include <lwip/ip4_addr.h> #include <lwip/ip4_addr.h>
@ -12,6 +10,8 @@
#include <lwip/sys.h> #include <lwip/sys.h>
#include <lwip/tcp.h> #include <lwip/tcp.h>
#include <lwip/timers.h> #include <lwip/timers.h>
#include <netif/etharp.h>
#include <liteethif.h>
#include "session.h" #include "session.h"
#include "net_server.h" #include "net_server.h"

View File

@ -6,7 +6,7 @@ import sys
import asyncio import asyncio
import time import time
import collections import collections
import os.path import os
import numpy as np import numpy as np
@ -16,6 +16,8 @@ from artiq.protocols import pyon
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
artiq_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)))
def parse_arguments(arguments): def parse_arguments(arguments):
d = {} d = {}

View File

@ -1,72 +0,0 @@
include $(MSCDIR)/software/common.mak
PYTHON ?= python3
OBJECTS := isr.o flash_storage.o clock.o rtiocrg.o elf_loader.o services.o session.o log.o test_mode.o kloader.o bridge_ctl.o mailbox.o ksupport_data.o net_server.o moninj.o main.o
OBJECTS_KSUPPORT := ksupport.o exception_jmp.o exceptions.o mailbox.o bridge.o rtio.o ttl.o dds.o
CFLAGS += -Ilwip/src/include -Iliblwip
all: runtime.bin runtime.fbi
# pull in dependency info for *existing* .o files
-include $(OBJECTS:.o=.d)
%.bin: %.elf
$(OBJCOPY) -O binary $< $@
@chmod -x $@
%.fbi: %.bin
@echo " MSCIMG " $@ && $(MSCDIR)/mkmscimg.py -f -o $@ $<
runtime.elf: $(OBJECTS) libs
$(LD) $(LDFLAGS) \
-T linker.ld \
-N -o $@ \
$(MSCDIR)/software/libbase/crt0-$(CPU).o \
$(OBJECTS) \
-L$(MSCDIR)/software/libbase \
-L$(MSCDIR)/software/libcompiler-rt \
-Lliblwip \
-lbase -lcompiler-rt -llwip
@chmod -x $@
ksupport.elf: $(OBJECTS_KSUPPORT)
$(LD) $(LDFLAGS) \
-T ksupport.ld \
-N -o $@ \
$(MSCDIR)/software/libbase/crt0-$(CPU).o \
$^ \
-L$(MSCDIR)/software/libcompiler-rt \
-lcompiler-rt
@chmod -x $@
ksupport_data.o: ksupport.bin
$(LD) -r -b binary -o $@ $<
service_table.h: ksupport.elf gen_service_table.py
@echo " GEN " $@ && $(PYTHON) gen_service_table.py ksupport.elf > $@
services.c: service_table.h
main.o: main.c
$(compile-dep)
%.o: %.c
$(compile-dep)
%.o: %.S
$(assemble)
libs:
$(MAKE) -C $(MSCDIR)/software/libcompiler-rt
$(MAKE) -C $(MSCDIR)/software/libbase
$(MAKE) -C liblwip
clean:
$(MAKE) -C liblwip clean
$(RM) $(OBJECTS) $(OBJECTS:.o=.d) $(OBJECTS_KSUPPORT) $(OBJECTS_KSUPPORT:.o=.d)
$(RM) runtime.elf runtime.bin runtime.fbi .*~ *~
$(RM) service_table.h ksupport.elf ksupport.bin
.PHONY: all main.o clean libs load

View File

@ -1,55 +0,0 @@
include $(MSCDIR)/software/common.mak
LWIPDIR=../lwip/src
CFLAGS += $(CPPFLAGS) -I. \
-I$(LWIPDIR)/include \
-I$(LWIPDIR)/include/ipv4
# COREFILES, CORE4FILES: The minimum set of files needed for lwIP.
COREOBJS=$(LWIPDIR)/core/mem.o \
$(LWIPDIR)/core/memp.o \
$(LWIPDIR)/core/netif.o \
$(LWIPDIR)/core/pbuf.o \
$(LWIPDIR)/core/raw.o \
$(LWIPDIR)/core/stats.o \
$(LWIPDIR)/core/sys.o \
$(LWIPDIR)/core/tcp.o \
$(LWIPDIR)/core/tcp_in.o \
$(LWIPDIR)/core/tcp_out.o \
$(LWIPDIR)/core/udp.o \
$(LWIPDIR)/core/dhcp.o \
$(LWIPDIR)/core/inet_chksum.o \
$(LWIPDIR)/core/timers.o \
$(LWIPDIR)/core/init.o
CORE4OBJS=$(LWIPDIR)/core/ipv4/icmp.o \
$(LWIPDIR)/core/ipv4/ip4.o \
$(LWIPDIR)/core/ipv4/ip4_addr.o \
$(LWIPDIR)/core/ipv4/ip_frag.o
# NETIFOBJS: Files implementing various generic network interface functions.
NETIFOBJS=$(LWIPDIR)/netif/etharp.o \
netif/liteethif.o
# LWIPOBJS: All the above.
LWIPOBJS=$(COREOBJS) $(CORE4OBJS) $(NETIFOBJS)
OBJS_LIB+=$(LWIPOBJS)
LWIPLIB=liblwip.a
all: $(LWIPLIB)
.PHONY: all compile clean
%.o: %.c
$(compile-dep)
%.o: %.S
$(assemble)
clean:
rm -f $(LWIPOBJS) $(LWIPOBJS:.o=.d) $(LWIPLIB)
liblwip.a: $(LWIPOBJS)
$(AR) clr liblwip.a $(LWIPOBJS)