forked from M-Labs/artiq
Shuttler: Add DAC Data Interface Gateware
- Add Parallel DDR Data Interface for DAC - Add MMCM to generate phase shifted DDR Clk(45 degree phase shift by default) - Connect dac_interface to Shuttler Module
This commit is contained in:
parent
2f3329181c
commit
7c8073c1ce
|
@ -18,9 +18,78 @@ from operator import add
|
||||||
|
|
||||||
from migen import *
|
from migen import *
|
||||||
from misoc.interconnect.stream import Endpoint
|
from misoc.interconnect.stream import Endpoint
|
||||||
|
from misoc.interconnect.csr import *
|
||||||
from misoc.cores.cordic import Cordic
|
from misoc.cores.cordic import Cordic
|
||||||
from artiq.gateware.rtio import rtlink
|
from artiq.gateware.rtio import rtlink
|
||||||
|
|
||||||
|
class DacInterface(Module, AutoCSR):
|
||||||
|
def __init__(self, pads):
|
||||||
|
bit_width = len(pads[0].data)
|
||||||
|
|
||||||
|
self.data = [[Signal(bit_width) for _ in range(2)] for _ in range(8)]
|
||||||
|
|
||||||
|
self.ddr_clk_phase_shift = CSR()
|
||||||
|
self.ddr_clk_phase_shift_done = CSRStatus(reset=1)
|
||||||
|
|
||||||
|
mmcm_ps_fb = Signal()
|
||||||
|
mmcm_ps_output = Signal()
|
||||||
|
mmcm_ps_psdone = Signal()
|
||||||
|
ddr_clk = Signal()
|
||||||
|
|
||||||
|
# Generate DAC DDR CLK
|
||||||
|
# 125MHz to 125MHz with controllable phase shift,
|
||||||
|
# VCO @ 1000MHz.
|
||||||
|
# Phase is shifted by 45 degree by default
|
||||||
|
self.specials += \
|
||||||
|
Instance("MMCME2_ADV",
|
||||||
|
p_CLKIN1_PERIOD=8.0,
|
||||||
|
i_CLKIN1=ClockSignal(),
|
||||||
|
i_RST=ResetSignal(),
|
||||||
|
i_CLKINSEL=1,
|
||||||
|
|
||||||
|
p_CLKFBOUT_MULT_F=8.0,
|
||||||
|
p_CLKOUT0_DIVIDE_F=8.0,
|
||||||
|
p_DIVCLK_DIVIDE=1,
|
||||||
|
p_CLKOUT0_PHASE=45.0,
|
||||||
|
|
||||||
|
o_CLKFBOUT=mmcm_ps_fb, i_CLKFBIN=mmcm_ps_fb,
|
||||||
|
|
||||||
|
p_CLKOUT0_USE_FINE_PS="TRUE",
|
||||||
|
o_CLKOUT0=mmcm_ps_output,
|
||||||
|
|
||||||
|
i_PSCLK=ClockSignal(),
|
||||||
|
i_PSEN=self.ddr_clk_phase_shift.re,
|
||||||
|
i_PSINCDEC=self.ddr_clk_phase_shift.r,
|
||||||
|
o_PSDONE=mmcm_ps_psdone,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.sync += [
|
||||||
|
If(self.ddr_clk_phase_shift.re, self.ddr_clk_phase_shift_done.status.eq(0)),
|
||||||
|
If(mmcm_ps_psdone, self.ddr_clk_phase_shift_done.status.eq(1))
|
||||||
|
]
|
||||||
|
|
||||||
|
# din.clk pads locate at multiple clock regions/IO banks
|
||||||
|
self.specials += [
|
||||||
|
Instance("BUFG", i_I=mmcm_ps_output, o_O=ddr_clk),
|
||||||
|
]
|
||||||
|
|
||||||
|
for i, din in enumerate(pads):
|
||||||
|
self.specials += Instance("ODDR",
|
||||||
|
i_C=ddr_clk,
|
||||||
|
i_CE=1,
|
||||||
|
i_D1=1,
|
||||||
|
i_D2=0,
|
||||||
|
o_Q=din.clk,
|
||||||
|
p_DDR_CLK_EDGE="SAME_EDGE")
|
||||||
|
self.specials += [
|
||||||
|
Instance("ODDR",
|
||||||
|
i_C=ClockSignal(),
|
||||||
|
i_CE=1,
|
||||||
|
i_D1=self.data[i][0][bit], # DDR CLK Rising Edge
|
||||||
|
i_D2=self.data[i][1][bit], # DDR CLK Falling Edge
|
||||||
|
o_Q=din.data[bit],
|
||||||
|
p_DDR_CLK_EDGE="SAME_EDGE")
|
||||||
|
for bit in range(bit_width)]
|
||||||
|
|
||||||
class Dac(Module):
|
class Dac(Module):
|
||||||
"""Output module.
|
"""Output module.
|
||||||
|
@ -170,7 +239,7 @@ class Config(Module):
|
||||||
Phy = namedtuple("Phy", "rtlink probes overrides")
|
Phy = namedtuple("Phy", "rtlink probes overrides")
|
||||||
|
|
||||||
|
|
||||||
class Shuttler(Module):
|
class Shuttler(Module, AutoCSR):
|
||||||
"""Shuttler module.
|
"""Shuttler module.
|
||||||
|
|
||||||
Used both in functional simulation and final gateware.
|
Used both in functional simulation and final gateware.
|
||||||
|
@ -181,9 +250,11 @@ class Shuttler(Module):
|
||||||
Attributes:
|
Attributes:
|
||||||
phys (list): List of Endpoints.
|
phys (list): List of Endpoints.
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
def __init__(self, pads):
|
||||||
NUM_OF_DACS = 16
|
NUM_OF_DACS = 16
|
||||||
|
|
||||||
|
self.submodules.dac_interface = DacInterface(pads)
|
||||||
|
|
||||||
self.phys = []
|
self.phys = []
|
||||||
|
|
||||||
self.submodules.cfg = Config()
|
self.submodules.cfg = Config()
|
||||||
|
@ -204,7 +275,10 @@ class Shuttler(Module):
|
||||||
|
|
||||||
for idx in range(NUM_OF_DACS):
|
for idx in range(NUM_OF_DACS):
|
||||||
dac = Dac()
|
dac = Dac()
|
||||||
self.comb += dac.clear.eq(self.cfg.clr[idx]),
|
self.comb += [
|
||||||
|
dac.clear.eq(self.cfg.clr[idx]),
|
||||||
|
self.dac_interface.data[idx // 2][idx % 2].eq(dac.data)
|
||||||
|
]
|
||||||
|
|
||||||
for i in dac.i:
|
for i in dac.i:
|
||||||
delay = getattr(i, "latency", 0)
|
delay = getattr(i, "latency", 0)
|
||||||
|
|
|
@ -153,8 +153,8 @@ class Satellite(BaseSoC, AMPSoC):
|
||||||
self.csr_devices.append("converter_spi")
|
self.csr_devices.append("converter_spi")
|
||||||
self.config["HAS_CONVERTER_SPI"] = None
|
self.config["HAS_CONVERTER_SPI"] = None
|
||||||
|
|
||||||
dac_rst = self.platform.request('dac_rst')
|
self.submodules.dac_rst = gpio.GPIOOut(self.platform.request("dac_rst"))
|
||||||
self.comb += dac_rst.eq(0)
|
self.csr_devices.append("dac_rst")
|
||||||
|
|
||||||
self.rtio_channels = []
|
self.rtio_channels = []
|
||||||
|
|
||||||
|
@ -163,7 +163,8 @@ class Satellite(BaseSoC, AMPSoC):
|
||||||
self.submodules += phy
|
self.submodules += phy
|
||||||
self.rtio_channels.append(rtio.Channel.from_phy(phy))
|
self.rtio_channels.append(rtio.Channel.from_phy(phy))
|
||||||
|
|
||||||
self.submodules.shuttler = Shuttler()
|
self.submodules.shuttler = Shuttler([platform.request("dac_din", i) for i in range(8)])
|
||||||
|
self.csr_devices.append("shuttler")
|
||||||
self.rtio_channels.extend(rtio.Channel.from_phy(phy) for phy in self.shuttler.phys)
|
self.rtio_channels.extend(rtio.Channel.from_phy(phy) for phy in self.shuttler.phys)
|
||||||
|
|
||||||
self.config["HAS_RTIO_LOG"] = None
|
self.config["HAS_RTIO_LOG"] = None
|
||||||
|
|
Loading…
Reference in New Issue