artiq/artiq/gateware/rtio/phy/dds.py

61 lines
2.3 KiB
Python
Raw Normal View History

2015-06-20 05:30:17 +08:00
from migen.fhdl.std import *
2015-06-29 03:37:27 +08:00
from artiq.gateware import ad9xxx
2015-06-20 05:30:17 +08:00
from artiq.gateware.rtio.phy.wishbone import RT2WB
2015-06-29 03:37:27 +08:00
class _AD9xxx(Module):
def __init__(self, ftw_base, pads, nchannels, **kwargs):
2015-06-20 05:30:17 +08:00
self.submodules._ll = RenameClockDomains(
2015-06-29 03:37:27 +08:00
ad9xxx.AD9xxx(pads, **kwargs), "rio")
self.submodules._rt2wb = RT2WB(flen(pads.a)+1, self._ll.bus)
2015-06-20 05:30:17 +08:00
self.rtlink = self._rt2wb.rtlink
self.probes = [Signal(32) for i in range(nchannels)]
# # #
# buffer the current address/data on the rtlink output
current_address = Signal.like(self.rtlink.o.address)
current_data = Signal.like(self.rtlink.o.data)
self.sync.rio += If(self.rtlink.o.stb,
current_address.eq(self.rtlink.o.address),
current_data.eq(self.rtlink.o.data))
2015-06-20 05:30:17 +08:00
# keep track of the currently selected channel
current_channel = Signal(max=nchannels)
self.sync.rio += If(current_address == 2**flen(pads.a) + 1,
current_channel.eq(current_data))
2015-06-20 05:30:17 +08:00
# keep track of frequency tuning words, before they are FUDed
ftws = [Signal(32) for i in range(nchannels)]
2015-06-20 07:36:46 +08:00
for c, ftw in enumerate(ftws):
2015-06-29 03:37:27 +08:00
if flen(pads.d) == 8:
self.sync.rio += \
If(current_channel == c, [
If(current_address == ftw_base+i,
ftw[i*8:(i+1)*8].eq(current_data))
for i in range(4)])
2015-06-29 03:37:27 +08:00
elif flen(pads.d) == 16:
self.sync.rio += \
If(current_channel == c, [
If(current_address == ftw_base+2*i,
ftw[i*16:(i+1)*16].eq(current_data))
for i in range(2)])
2015-06-29 03:37:27 +08:00
else:
raise NotImplementedError
2015-06-20 05:30:17 +08:00
# FTW to probe on FUD
self.sync.rio += If(current_address == 2**flen(pads.a), [
If(current_channel == c, probe.eq(ftw))
for c, (probe, ftw) in enumerate(zip(self.probes, ftws))])
2015-06-29 03:37:27 +08:00
class AD9858(_AD9xxx):
def __init__(self, pads, nchannels, **kwargs):
_AD9xxx.__init__(self, 0x0a, pads, nchannels, **kwargs)
class AD9914(_AD9xxx):
def __init__(self, pads, nchannels, **kwargs):
_AD9xxx.__init__(self, 0x2d, pads, nchannels, **kwargs)