gateware: use LTC2195 dco clk as PL only clock source
This commit is contained in:
parent
d9d44fa9e8
commit
0ca6ac1354
@ -22,93 +22,8 @@ from migen.genlib.cdc import MultiReg
|
||||
from misoc.interconnect.csr import AutoCSR, CSRStatus, CSRStorage
|
||||
from misoc.interconnect.stream import AsyncFIFO
|
||||
|
||||
|
||||
class CRG(Module):
|
||||
def __init__(self, platform, dco_clk, dco_freq=200e6):
|
||||
self.clock_domains.cd_dco = ClockDomain()
|
||||
self.clock_domains.cd_dco2x = ClockDomain()
|
||||
self.clock_domains.cd_dco2d = ClockDomain()
|
||||
self.clock_domains.cd_dco2d_45_degree = ClockDomain()
|
||||
dco_clk_p, dco_clk_n = dco_clk
|
||||
|
||||
dco_clk_buf = Signal()
|
||||
self.specials += Instance(
|
||||
"IBUFGDS", i_I=dco_clk_p, i_IB=dco_clk_n, o_O=dco_clk_buf
|
||||
)
|
||||
|
||||
# # #
|
||||
clk_feedback = Signal()
|
||||
clk_feedback_buf = Signal()
|
||||
|
||||
clk_dco = Signal()
|
||||
clk_dco2x = Signal()
|
||||
clk_dco2d = Signal()
|
||||
clk_dco2d_45_degree = Signal()
|
||||
mmcm_ps_psdone = Signal()
|
||||
|
||||
self.locked = Signal()
|
||||
self.mmcm_rst = Signal()
|
||||
self.ddr_clk_phase_shift_en = Signal()
|
||||
self.ddr_clk_phase_incdec = Signal()
|
||||
|
||||
platform.add_period_constraint(dco_clk_p, 1e9 / dco_freq)
|
||||
self.specials += [
|
||||
Instance(
|
||||
"MMCME2_ADV",
|
||||
p_BANDWIDTH="OPTIMIZED",
|
||||
p_DIVCLK_DIVIDE=1,
|
||||
p_CLKFBOUT_PHASE=0.0,
|
||||
p_CLKFBOUT_MULT_F=4, # VCO @ 800 MHz
|
||||
p_CLKIN1_PERIOD=(1e9 / dco_freq),
|
||||
p_REF_JITTER1=0.01,
|
||||
p_STARTUP_WAIT="FALSE",
|
||||
i_CLKIN1=dco_clk_buf,
|
||||
i_PWRDWN=0,
|
||||
i_RST=ResetSignal("sys") | self.mmcm_rst,
|
||||
i_CLKFBIN=clk_feedback_buf,
|
||||
o_CLKFBOUT=clk_feedback,
|
||||
|
||||
p_CLKOUT0_USE_FINE_PS="TRUE",
|
||||
p_CLKOUT0_DIVIDE_F=8,
|
||||
p_CLKOUT0_PHASE=45.0,
|
||||
p_CLKOUT0_DUTY_CYCLE=0.5,
|
||||
o_CLKOUT0=clk_dco2d_45_degree, # 100 MHz <- dco_clk / 2 = 200 MHz / 2
|
||||
o_LOCKED=self.locked,
|
||||
|
||||
p_CLKOUT1_DIVIDE=2,
|
||||
p_CLKOUT1_PHASE=0.0,
|
||||
p_CLKOUT1_DUTY_CYCLE=0.5,
|
||||
o_CLKOUT1=clk_dco2x, # 400 MHZ <- 2 * dco_clk = 2*200 MHz
|
||||
|
||||
p_CLKOUT2_DIVIDE=8,
|
||||
p_CLKOUT2_PHASE=0.0,
|
||||
p_CLKOUT2_DUTY_CYCLE=0.5,
|
||||
o_CLKOUT2=clk_dco2d, # 100 MHz <- dco_clk / 2 = 200 MHz / 2
|
||||
|
||||
p_CLKOUT3_DIVIDE=4,
|
||||
p_CLKOUT3_PHASE=0.0,
|
||||
p_CLKOUT3_DUTY_CYCLE=0.5,
|
||||
o_CLKOUT3=clk_dco, # 200 MHz <- dco_clk
|
||||
|
||||
i_PSCLK=ClockSignal(),
|
||||
i_PSEN=self.ddr_clk_phase_shift_en,
|
||||
i_PSINCDEC=self.ddr_clk_phase_incdec,
|
||||
o_PSDONE=mmcm_ps_psdone,
|
||||
)
|
||||
]
|
||||
|
||||
self.specials += Instance("BUFG", i_I=clk_feedback, o_O=clk_feedback_buf)
|
||||
self.specials += Instance("BUFG", i_I=clk_dco, o_O=self.cd_dco.clk)
|
||||
self.specials += Instance("BUFG", i_I=clk_dco2d, o_O=self.cd_dco2d.clk)
|
||||
self.specials += Instance("BUFG", i_I=clk_dco2d_45_degree, o_O=self.cd_dco2d_45_degree.clk)
|
||||
self.specials += Instance("BUFG", i_I=clk_dco2x, o_O=self.cd_dco2x.clk)
|
||||
|
||||
# Ignore dco2d to mmcm dco_clk path created by SoC's rst.
|
||||
platform.add_false_path_constraints(self.cd_dco2d.clk, dco_clk_buf)
|
||||
self.specials += Instance("FD", p_INIT=1, i_D=~self.locked, i_C=self.cd_dco2d.clk, o_Q=self.cd_dco2d.rst)
|
||||
|
||||
class ADC(Module, AutoCSR):
|
||||
def __init__(self, platform, dco_freq=200e6):
|
||||
def __init__(self, platform):
|
||||
adc_pads = platform.request("adc")
|
||||
afe_pads = platform.request("adc_afe")
|
||||
|
||||
@ -131,45 +46,27 @@ class ADC(Module, AutoCSR):
|
||||
ch2_shdn = Signal()
|
||||
|
||||
self.data_out = [Signal(16, reset_less=True), Signal(16, reset_less=True)]
|
||||
self.data_out_cdc = [Signal(16, reset_less=True), Signal(16, reset_less=True)]
|
||||
self.s_frame = Signal(4)
|
||||
self.s_frame_cdc = Signal(4)
|
||||
|
||||
self.submodules.cdc_fifo = ClockDomainsRenamer({"write": "dco2d", "read": "sys"})(AsyncFIFO([("data", 36)], 4))
|
||||
self.comb += [
|
||||
self.cdc_fifo.sink.data.eq(Cat(self.data_out_cdc[0], self.data_out_cdc[1], self.s_frame_cdc)),
|
||||
self.cdc_fifo.sink.stb.eq(~ResetSignal("dco2d")),
|
||||
Cat(self.data_out[0], self.data_out[1], self.s_frame).eq(self.cdc_fifo.source.data),
|
||||
self.cdc_fifo.source.ack.eq(~ResetSignal("sys")),
|
||||
]
|
||||
|
||||
###
|
||||
|
||||
# DCO clock coming from LTC2195
|
||||
# dco_clk = Record([("p", 1), ("n", 1)])
|
||||
dco_clk =(adc_pads.dco_p, adc_pads.dco_n)
|
||||
self.comb += [
|
||||
# dco_clk.p.eq(adc_pads.dco_p),
|
||||
# dco_clk.n.eq(adc_pads.dco_n),
|
||||
tap_delay_val.eq(self.tap_delay.storage),
|
||||
Cat(ch1_gain_x10, ch2_gain_x10, ch1_shdn, ch2_shdn).eq(
|
||||
self.afe_ctrl.storage[0:4]
|
||||
),
|
||||
]
|
||||
|
||||
self.submodules.crg = CRG(platform, dco_clk, dco_freq)
|
||||
self.comb += self.afe_ctrl.storage[4].eq(self.crg.mmcm_rst)
|
||||
self.comb += self.afe_ctrl.storage[5].eq(self.crg.ddr_clk_phase_shift_en)
|
||||
self.comb += self.afe_ctrl.storage[6].eq(self.crg.ddr_clk_phase_incdec)
|
||||
# self.comb += self.afe_ctrl.storage[4].eq(self.crg.mmcm_rst)
|
||||
# self.comb += self.afe_ctrl.storage[5].eq(self.crg.ddr_clk_phase_shift_en)
|
||||
# self.comb += self.afe_ctrl.storage[6].eq(self.crg.ddr_clk_phase_incdec)
|
||||
|
||||
self.specials += MultiReg(self.bitslip_csr.re, bitslip_re_dco_2d, "dco2d")
|
||||
self.sync.dco2d += [
|
||||
self.specials += MultiReg(self.bitslip_csr.re, bitslip_re_dco_2d, "sys")
|
||||
self.sync.sys += [
|
||||
bitslip.eq(Mux(bitslip_re_dco_2d, self.bitslip_csr.storage, 0))
|
||||
]
|
||||
|
||||
self.comb += [
|
||||
self.frame_csr.status[0:4].eq(self.s_frame[0:4]),
|
||||
self.frame_csr.status[4].eq(self.crg.locked),
|
||||
# self.frame_csr.status[4].eq(self.crg.locked),
|
||||
self.data_ch0.status.eq(self.data_out[0]),
|
||||
self.data_ch1.status.eq(self.data_out[1]),
|
||||
]
|
||||
@ -186,10 +83,10 @@ class ADC(Module, AutoCSR):
|
||||
|
||||
self.specials += Instance(
|
||||
"LTC2195",
|
||||
i_rst_in=ResetSignal("dco2d"),
|
||||
i_rst_in=ResetSignal("sys"),
|
||||
i_clk200=ClockSignal("idelay"),
|
||||
i_DCO=ClockSignal("dco"),
|
||||
i_DCO_2D=ClockSignal("dco2d"),
|
||||
i_DCO=ClockSignal("sys_double"),
|
||||
i_DCO_2D=ClockSignal("sys"),
|
||||
i_FR_in_p=adc_pads.frame_p,
|
||||
i_FR_in_n=adc_pads.frame_n,
|
||||
i_D0_in_p=adc_pads.data0_p,
|
||||
@ -198,9 +95,9 @@ class ADC(Module, AutoCSR):
|
||||
i_D1_in_n=adc_pads.data1_n,
|
||||
i_bitslip=bitslip,
|
||||
i_delay_val=tap_delay_val,
|
||||
o_ADC0_out=self.data_out_cdc[1], # LANES swapped on hardware
|
||||
o_ADC1_out=self.data_out_cdc[0],
|
||||
o_FR_out=self.s_frame_cdc,
|
||||
o_ADC0_out=self.data_out[1], # LANES swapped on hardware
|
||||
o_ADC1_out=self.data_out[0],
|
||||
o_FR_out=self.s_frame,
|
||||
o_o_data_from_pins=dummy,
|
||||
o_idelay_rdy=dummy_idelay_rdy,
|
||||
)
|
||||
|
@ -24,10 +24,13 @@ from misoc.interconnect.stream import AsyncFIFO
|
||||
|
||||
|
||||
class DAC(Module, AutoCSR):
|
||||
def __init__(self, platform):
|
||||
def __init__(self, platform, phase_shift_ctrl):
|
||||
dac_pads = platform.request("dac")
|
||||
dac_afe_pads = platform.request("dac_afe")
|
||||
self.dac_ctrl = CSRStorage(3)
|
||||
|
||||
phase_shift_en, phase_shift_dir = phase_shift_ctrl
|
||||
|
||||
self.dac_ctrl = CSRStorage(5)
|
||||
self.output_value_ch0 = CSRStorage(14)
|
||||
self.output_value_ch1 = CSRStorage(14)
|
||||
|
||||
@ -41,45 +44,36 @@ class DAC(Module, AutoCSR):
|
||||
self.data_in = [Signal(14, reset_less=True), Signal(14, reset_less=True)]
|
||||
self.data_in_csr = [Signal(14, reset_less=True), Signal(14, reset_less=True)]
|
||||
|
||||
self.data_in_cdc = [Signal(14, reset_less=True), Signal(14, reset_less=True)]
|
||||
self.data_in_csr_cdc = [Signal(14, reset_less=True), Signal(14, reset_less=True)]
|
||||
platform.add_period_constraint(dac_pads.dclkio, 10.0)
|
||||
|
||||
self.submodules.cdc_fifo = ClockDomainsRenamer({"write": "sys", "read": "dco2d"})(AsyncFIFO([("data", 56)], 4))
|
||||
self.comb += [
|
||||
self.data_in_csr[0].eq(self.output_value_ch0.storage),
|
||||
self.data_in_csr[1].eq(self.output_value_ch1.storage),
|
||||
self.cdc_fifo.sink.data.eq(Cat(self.data_in[0], self.data_in[1], self.data_in_csr[0], self.data_in_csr[1])),
|
||||
self.cdc_fifo.sink.stb.eq(~ResetSignal("sys")),
|
||||
Cat(self.data_in_cdc[0], self.data_in_cdc[1], self.data_in_csr_cdc[0], self.data_in_csr_cdc[1]).eq(self.cdc_fifo.source.data),
|
||||
self.cdc_fifo.source.ack.eq(~ResetSignal("dco2d")),
|
||||
]
|
||||
|
||||
self.comb += [
|
||||
Cat(manual_override, ch0_pd, ch1_pd).eq(self.dac_ctrl.storage),
|
||||
dac_pads.rst.eq(ResetSignal("dco2d")),
|
||||
Cat(manual_override, ch0_pd, ch1_pd, phase_shift_en, phase_shift_dir).eq(self.dac_ctrl.storage),
|
||||
dac_pads.rst.eq(ResetSignal("sys")),
|
||||
dac_afe_pads.ch1_pd_n.eq(~ch0_pd),
|
||||
dac_afe_pads.ch2_pd_n.eq(~ch1_pd),
|
||||
output_data_ch0.eq(
|
||||
Mux(manual_override, self.data_in_csr_cdc[0], self.data_in_cdc[0])
|
||||
Mux(manual_override, self.data_in_csr[0], self.data_in[0])
|
||||
),
|
||||
output_data_ch1.eq(
|
||||
Mux(manual_override, self.data_in_csr_cdc[1], self.data_in_cdc[1])
|
||||
Mux(manual_override, self.data_in_csr[1], self.data_in[1])
|
||||
),
|
||||
]
|
||||
|
||||
self.specials += [
|
||||
Instance("ODDR",
|
||||
i_C=ClockSignal("dco2d"),
|
||||
i_CE=~ResetSignal("dco2d"),
|
||||
i_C=ClockSignal("sys"),
|
||||
i_CE=~ResetSignal("sys"),
|
||||
i_D1=output_data_ch0[lane], # DDR CLK Rising Edge
|
||||
i_D2=output_data_ch1[lane], # DDR CLK Falling Edge
|
||||
o_Q=dac_pads.data[lane],
|
||||
p_DDR_CLK_EDGE="SAME_EDGE")
|
||||
for lane in range(14)]
|
||||
self.specials += Instance("ODDR",
|
||||
i_C=ClockSignal("dco2d_45_degree"),
|
||||
i_CE=~ResetSignal("dco2d"),
|
||||
i_C=ClockSignal("sys_45_degree"),
|
||||
i_CE=~ResetSignal("sys"),
|
||||
i_D1=0,
|
||||
i_D2=1,
|
||||
o_Q=dac_pads.dclkio,
|
||||
|
@ -80,11 +80,13 @@ _io = [
|
||||
Subsignal("data0_n", Pins("E7 B6 E3 C1"), IOStandard("LVDS_25")),
|
||||
Subsignal("data1_p", Pins("A2 D5 F2 D7"), IOStandard("LVDS_25")),
|
||||
Subsignal("data1_n", Pins("A1 C4 F1 D6"), IOStandard("LVDS_25")),
|
||||
Subsignal("dco_p", Pins("B4"), IOStandard("LVDS_25")),
|
||||
Subsignal("dco_n", Pins("B3"), IOStandard("LVDS_25")),
|
||||
Subsignal("frame_p", Pins("B2"), IOStandard("LVDS_25")),
|
||||
Subsignal("frame_n", Pins("B1"), IOStandard("LVDS_25"))
|
||||
),
|
||||
("adc_dco_clk", 0 ,
|
||||
Subsignal("p", Pins("B4"), IOStandard("LVDS_25")),
|
||||
Subsignal("n", Pins("B3"), IOStandard("LVDS_25")),
|
||||
),
|
||||
|
||||
# ADC AFE
|
||||
("adc_afe", 0,
|
||||
@ -315,21 +317,23 @@ ps7_config_board_preset = {
|
||||
}
|
||||
|
||||
class Platform(XilinxPlatform):
|
||||
default_clk_name = "clk100"
|
||||
default_clk_period = 10.0
|
||||
default_clk_name = "adc_dco_clk_p"
|
||||
default_clk_period = 5.0
|
||||
|
||||
def __init__(self):
|
||||
XilinxPlatform.__init__(self, "xc7z015-clg485-1", _io, _connector_gpio + _connector_eem, toolchain="vivado")
|
||||
ps7_config = ps7_config_board_preset
|
||||
self.ps7_config = ps7_config
|
||||
|
||||
self.toolchain.with_phys_opt = True
|
||||
|
||||
verilog_sources = os.listdir(verilog_dir)
|
||||
self.add_sources(verilog_dir, *verilog_sources)
|
||||
|
||||
def do_finalize(self, fragment):
|
||||
try:
|
||||
XilinxPlatform.do_finalize(self, fragment)
|
||||
self.add_period_constraint(self.lookup_request(self.default_clk_name, loose=True), self.default_clk_period)
|
||||
self.add_period_constraint(self.lookup_request(self.default_clk_name), self.default_clk_period)
|
||||
except ValueError:
|
||||
pass
|
||||
except ConstraintError:
|
||||
|
@ -31,72 +31,91 @@ from fast_servo.gateware.cores.spi_phy import SpiInterface, SpiPhy
|
||||
|
||||
|
||||
class CRG(Module):
|
||||
def __init__(self, platform):
|
||||
def __init__(self, platform, dco_freq=200e6):
|
||||
self.ps_rst = Signal()
|
||||
self.locked = Signal()
|
||||
|
||||
dco_clk = platform.request("adc_dco_clk")
|
||||
dco_clk_buf = Signal()
|
||||
self.specials += Instance(
|
||||
"IBUFGDS", i_I=dco_clk.p, i_IB=dco_clk.n, o_O=dco_clk_buf
|
||||
)
|
||||
|
||||
self.clock_domains.cd_sys = ClockDomain()
|
||||
self.clock_domains.cd_sys_45_degree = ClockDomain()
|
||||
self.clock_domains.cd_sys_double = ClockDomain()
|
||||
self.clock_domains.cd_idelay = ClockDomain()
|
||||
|
||||
# # #
|
||||
|
||||
# Clk.
|
||||
clk100 = platform.request("clk100")
|
||||
platform.add_period_constraint(clk100, 10.0)
|
||||
self.clkin = clk100
|
||||
clk100_buf = Signal()
|
||||
self.specials += Instance("IBUFG", i_I=clk100, o_O=clk100_buf)
|
||||
|
||||
clk_feedback = Signal()
|
||||
clk_feedback_buf = Signal()
|
||||
|
||||
clk_sys = Signal()
|
||||
clk_sys_45_degree = Signal()
|
||||
clk_sys_double = Signal()
|
||||
clk_idelay = Signal()
|
||||
|
||||
self.ddr_clk_phase_shift_en = Signal()
|
||||
self.ddr_clk_phase_incdec = Signal()
|
||||
self.mmcm_ps_psdone = Signal()
|
||||
|
||||
si5340_nlol = platform.request("si5340_nlol")
|
||||
si5340_nlol_buf = Signal()
|
||||
self.specials += Instance("IBUF", i_I=si5340_nlol, o_O=si5340_nlol_buf)
|
||||
|
||||
platform.add_period_constraint(dco_clk.p, 1e9 / dco_freq)
|
||||
self.specials += [
|
||||
Instance(
|
||||
"PLLE2_BASE",
|
||||
"MMCME2_ADV",
|
||||
p_BANDWIDTH="OPTIMIZED",
|
||||
p_DIVCLK_DIVIDE=1,
|
||||
p_CLKFBOUT_PHASE=0.0,
|
||||
p_CLKFBOUT_MULT=10,
|
||||
p_CLKIN1_PERIOD=10.0,
|
||||
p_REF_JITTER1=0.01,
|
||||
p_CLKFBOUT_MULT_F=4, # VCO @ 800 MHz
|
||||
p_CLKIN1_PERIOD=(1e9 / dco_freq),
|
||||
p_REF_JITTER1=0.06, # From LTC2195 Datasheet
|
||||
p_STARTUP_WAIT="FALSE",
|
||||
i_CLKIN1=clk100_buf,
|
||||
i_CLKIN1=dco_clk_buf,
|
||||
i_PWRDWN=0,
|
||||
i_RST=self.ps_rst | ~si5340_nlol_buf,
|
||||
i_CLKFBIN=clk_feedback_buf,
|
||||
o_CLKFBOUT=clk_feedback,
|
||||
p_CLKOUT0_DIVIDE=10,
|
||||
p_CLKOUT0_PHASE=0.0,
|
||||
|
||||
p_CLKOUT0_USE_FINE_PS="True",
|
||||
p_CLKOUT0_DIVIDE_F=8,
|
||||
p_CLKOUT0_PHASE=45.0,
|
||||
p_CLKOUT0_DUTY_CYCLE=0.5,
|
||||
o_CLKOUT0=clk_sys, # 100 MHz <- sys_clk
|
||||
p_CLKOUT1_DIVIDE=5,
|
||||
o_CLKOUT0=clk_sys_45_degree, # 800MHz / 8 -> 100MHz
|
||||
o_LOCKED=self.locked,
|
||||
|
||||
p_CLKOUT1_DIVIDE=8,
|
||||
p_CLKOUT1_PHASE=0.0,
|
||||
p_CLKOUT1_DUTY_CYCLE=0.5,
|
||||
o_CLKOUT1=clk_idelay, # 200 MHZ <- 2 * sys_clk = 2*100 MHz
|
||||
p_CLKOUT2_DIVIDE=5,
|
||||
o_CLKOUT1=clk_sys, # 800MHz / 8 -> 100MHz
|
||||
|
||||
p_CLKOUT2_DIVIDE=4,
|
||||
p_CLKOUT2_PHASE=0.0,
|
||||
p_CLKOUT2_DUTY_CYCLE=0.5,
|
||||
o_CLKOUT2=clk_sys_double, # 200 MHZ <- 2 * sys_clk_double = 2*100 MHz
|
||||
o_LOCKED=self.locked,
|
||||
o_CLKOUT2=clk_sys_double, # 800MHz / 4 -> 200MHz
|
||||
|
||||
p_CLKOUT3_DIVIDE=4,
|
||||
p_CLKOUT3_PHASE=0.0,
|
||||
p_CLKOUT3_DUTY_CYCLE=0.5,
|
||||
o_CLKOUT3=clk_idelay, # 800MHz / 4 -> 200MHz
|
||||
|
||||
i_PSCLK=ClockSignal(),
|
||||
i_PSEN=self.ddr_clk_phase_shift_en,
|
||||
i_PSINCDEC=self.ddr_clk_phase_incdec,
|
||||
o_PSDONE=self.mmcm_ps_psdone,
|
||||
)
|
||||
]
|
||||
|
||||
self.specials += Instance("BUFG", i_I=clk_feedback, o_O=clk_feedback_buf)
|
||||
self.specials += Instance("BUFG", i_I=clk_sys, o_O=self.cd_sys.clk)
|
||||
self.specials += Instance("BUFG", i_I=clk_idelay, o_O=self.cd_idelay.clk)
|
||||
self.specials += Instance("BUFG", i_I=clk_sys_45_degree, o_O=self.cd_sys_45_degree.clk)
|
||||
self.specials += Instance("BUFG", i_I=clk_sys_double, o_O=self.cd_sys_double.clk)
|
||||
|
||||
self.specials += Instance("BUFG", i_I=clk_idelay, o_O=self.cd_idelay.clk)
|
||||
|
||||
# Ignore sys_clk to pll clkin path created by SoC's rst.
|
||||
platform.add_false_path_constraints(self.cd_sys.clk, self.clkin)
|
||||
platform.add_false_path_constraints(self.cd_sys.clk, dco_clk)
|
||||
|
||||
self.specials += Instance("FD", p_INIT=1, i_D=~self.locked, i_C=self.cd_sys.clk, o_Q=self.cd_sys.rst)
|
||||
|
||||
@ -126,6 +145,10 @@ class BaseSoC(PS7, AutoCSR):
|
||||
|
||||
self.submodules.crg = CRG(platform)
|
||||
|
||||
# self.comb += self.afe_ctrl.storage[4].eq(self.crg.mmcm_rst)
|
||||
# self.comb += self.afe_ctrl.storage[5].eq(self.crg.ddr_clk_phase_shift_en)
|
||||
# self.comb += self.afe_ctrl.storage[6].eq(self.crg.ddr_clk_phase_incdec)
|
||||
|
||||
# # # AXI to system bus bridge
|
||||
self.submodules.axi2sys = Axi2Sys()
|
||||
self.submodules.sys2csr = Sys2CSR()
|
||||
@ -156,10 +179,10 @@ class BaseSoC(PS7, AutoCSR):
|
||||
# self.add_main_adc(platform)
|
||||
self.submodules.adc = ADC(platform)
|
||||
self.csr_devices.append("adc")
|
||||
platform.add_false_path_constraints(self.crg.cd_sys.clk, self.adc.crg.cd_dco2d.clk)
|
||||
# platform.add_false_path_constraints(self.crg.cd_sys.clk, self.adc.crg.cd_dco2d.clk)
|
||||
|
||||
# self.add_main_dac(platform)
|
||||
self.submodules.dac = DAC(platform)
|
||||
self.submodules.dac = DAC(platform, [self.crg.ddr_clk_phase_shift_en, self.crg.ddr_clk_phase_incdec,])
|
||||
self.csr_devices.append("dac")
|
||||
|
||||
# DEBUG
|
||||
|
@ -85,26 +85,6 @@ def perform_bitslip():
|
||||
print(f"No bitslip required; Current frame: 0x{current_frame:02x}")
|
||||
return
|
||||
|
||||
def mmcm_rst():
|
||||
curr_cfg = read_from_memory(ADC_AFE_CTRL_ADDR, 1)[0] & 0x0F
|
||||
write_to_memory(ADC_AFE_CTRL_ADDR, 0x10 | curr_cfg) # Reset MMCM
|
||||
write_to_memory(ADC_AFE_CTRL_ADDR, 0x00 | curr_cfg) # Release MMCM Reset
|
||||
while not(read_frame() & 0x10):
|
||||
print(f"Waiting for MMCM to lock")
|
||||
time.sleep(0.001)
|
||||
|
||||
def inc_ddr_clk_phase():
|
||||
curr_cfg = read_from_memory(ADC_AFE_CTRL_ADDR, 1)[0] & 0x1F
|
||||
write_to_memory(ADC_AFE_CTRL_ADDR, 0x40 | curr_cfg) # Set MMCM Phase Shift to be INC
|
||||
write_to_memory(ADC_AFE_CTRL_ADDR, 0x60 | curr_cfg) # Assert MMCM Phase Shift EN High
|
||||
write_to_memory(ADC_AFE_CTRL_ADDR, curr_cfg) # Deassert MMCM Phase Shift EN High
|
||||
|
||||
def dec_ddr_clk_phase():
|
||||
curr_cfg = read_from_memory(ADC_AFE_CTRL_ADDR, 1)[0] & 0x1F
|
||||
write_to_memory(ADC_AFE_CTRL_ADDR, 0x00 | curr_cfg) # Set MMCM Phase Shift to be DEC
|
||||
write_to_memory(ADC_AFE_CTRL_ADDR, 0x20 | curr_cfg) # Assert MMCM Phase Shift EN High
|
||||
write_to_memory(ADC_AFE_CTRL_ADDR, curr_cfg) # Deassert MMCM Phase Shift EN High
|
||||
|
||||
def find_edge():
|
||||
prev_frame = read_frame()
|
||||
for tap_delay in range(32):
|
||||
@ -191,9 +171,6 @@ def configure_ltc2195():
|
||||
0x04: test_pattern & 0xFF
|
||||
})
|
||||
|
||||
# ADC software reset put its PLL to sleep momentarily. Thus, MMCM needs to be reset as well.
|
||||
mmcm_rst()
|
||||
|
||||
# Performing Word Align
|
||||
perform_bitslip()
|
||||
find_edge()
|
||||
|
@ -37,6 +37,17 @@ MAIN_DAC_BUS = 2
|
||||
MAIN_DAC_DEVICE = 0
|
||||
DAC_VERSION = 0x0A
|
||||
|
||||
def inc_ddr_clk_phase():
|
||||
curr_cfg = read_from_memory(CTRL_ADDR, 1)[0] & 0x07
|
||||
write_to_memory(CTRL_ADDR, 0x10 | curr_cfg) # Set MMCM Phase Shift to be INC
|
||||
write_to_memory(CTRL_ADDR, 0x18 | curr_cfg) # Assert MMCM Phase Shift EN High
|
||||
write_to_memory(CTRL_ADDR, curr_cfg) # Deassert MMCM Phase Shift EN High
|
||||
|
||||
def dec_ddr_clk_phase():
|
||||
curr_cfg = read_from_memory(CTRL_ADDR, 1)[0] & 0x07
|
||||
write_to_memory(CTRL_ADDR, 0x00 | curr_cfg) # Set MMCM Phase Shift to be DEC
|
||||
write_to_memory(CTRL_ADDR, 0x08 | curr_cfg) # Assert MMCM Phase Shift EN High
|
||||
write_to_memory(CTRL_ADDR, curr_cfg) # Deassert MMCM Phase Shift EN High
|
||||
|
||||
def spi_write(spi, address, value):
|
||||
spi.xfer2([address, value])
|
||||
|
Loading…
Reference in New Issue
Block a user