forked from M-Labs/artiq
1
0
Fork 0

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:
linuswck 2023-09-04 17:23:24 +08:00 committed by Sébastien Bourdeauducq
parent 2f3329181c
commit 7c8073c1ce
2 changed files with 81 additions and 6 deletions

View File

@ -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)

View File

@ -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