2024-02-28 14:47:38 +08:00
|
|
|
# This file is part of Fast Servo Software Package.
|
|
|
|
#
|
|
|
|
# Copyright (C) 2023 Jakub Matyas
|
|
|
|
# Warsaw University of Technology <jakubk.m@gmail.com>
|
|
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
#
|
|
|
|
# This program is free software: you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
from migen import *
|
|
|
|
from migen.genlib.cdc import MultiReg
|
|
|
|
from misoc.interconnect.csr import AutoCSR, CSRStatus, CSRStorage
|
2024-11-13 15:25:04 +08:00
|
|
|
from misoc.interconnect.stream import AsyncFIFO
|
2024-02-28 14:47:38 +08:00
|
|
|
|
|
|
|
class ADC(Module, AutoCSR):
|
2025-01-10 12:38:02 +08:00
|
|
|
def __init__(self, platform):
|
2024-02-28 14:47:38 +08:00
|
|
|
adc_pads = platform.request("adc")
|
|
|
|
afe_pads = platform.request("adc_afe")
|
|
|
|
|
2024-11-08 12:35:13 +08:00
|
|
|
self.frame_csr = CSRStatus(5)
|
2024-02-28 14:47:38 +08:00
|
|
|
self.data_ch0 = CSRStatus(16)
|
|
|
|
self.data_ch1 = CSRStatus(16)
|
|
|
|
|
|
|
|
self.tap_delay = CSRStorage(5)
|
|
|
|
self.bitslip_csr = CSRStorage(1)
|
|
|
|
|
2024-11-08 12:35:13 +08:00
|
|
|
self.afe_ctrl = CSRStorage(7)
|
2024-02-28 14:47:38 +08:00
|
|
|
|
|
|
|
tap_delay_val = Signal(5)
|
|
|
|
bitslip = Signal()
|
|
|
|
bitslip_re_dco_2d = Signal()
|
|
|
|
|
|
|
|
ch1_gain_x10 = Signal()
|
|
|
|
ch2_gain_x10 = Signal()
|
|
|
|
ch1_shdn = Signal()
|
|
|
|
ch2_shdn = Signal()
|
|
|
|
|
|
|
|
self.data_out = [Signal(16, reset_less=True), Signal(16, reset_less=True)]
|
|
|
|
self.s_frame = Signal(4)
|
|
|
|
|
|
|
|
self.comb += [
|
|
|
|
tap_delay_val.eq(self.tap_delay.storage),
|
|
|
|
Cat(ch1_gain_x10, ch2_gain_x10, ch1_shdn, ch2_shdn).eq(
|
2024-11-08 12:35:13 +08:00
|
|
|
self.afe_ctrl.storage[0:4]
|
2024-02-28 14:47:38 +08:00
|
|
|
),
|
|
|
|
]
|
|
|
|
|
2025-01-10 12:38:02 +08:00
|
|
|
# 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)
|
2024-02-28 14:47:38 +08:00
|
|
|
|
2025-01-10 12:38:02 +08:00
|
|
|
self.specials += MultiReg(self.bitslip_csr.re, bitslip_re_dco_2d, "sys")
|
|
|
|
self.sync.sys += [
|
2024-02-28 14:47:38 +08:00
|
|
|
bitslip.eq(Mux(bitslip_re_dco_2d, self.bitslip_csr.storage, 0))
|
|
|
|
]
|
|
|
|
|
|
|
|
self.comb += [
|
2024-11-08 12:35:13 +08:00
|
|
|
self.frame_csr.status[0:4].eq(self.s_frame[0:4]),
|
2025-01-10 12:38:02 +08:00
|
|
|
# self.frame_csr.status[4].eq(self.crg.locked),
|
2024-02-28 14:47:38 +08:00
|
|
|
self.data_ch0.status.eq(self.data_out[0]),
|
|
|
|
self.data_ch1.status.eq(self.data_out[1]),
|
|
|
|
]
|
|
|
|
|
|
|
|
self.comb += [
|
|
|
|
afe_pads.ch1_gain.eq(ch1_gain_x10),
|
|
|
|
afe_pads.ch2_gain.eq(ch2_gain_x10),
|
|
|
|
afe_pads.nshdn_ch1.eq(~ch1_shdn),
|
|
|
|
afe_pads.nshdn_ch2.eq(~ch2_shdn),
|
|
|
|
]
|
|
|
|
|
|
|
|
dummy = Signal(8)
|
|
|
|
dummy_idelay_rdy = Signal()
|
|
|
|
|
|
|
|
self.specials += Instance(
|
|
|
|
"LTC2195",
|
2025-01-10 12:38:02 +08:00
|
|
|
i_rst_in=ResetSignal("sys"),
|
2024-02-28 14:47:38 +08:00
|
|
|
i_clk200=ClockSignal("idelay"),
|
2025-01-10 12:38:02 +08:00
|
|
|
i_DCO=ClockSignal("sys_double"),
|
|
|
|
i_DCO_2D=ClockSignal("sys"),
|
2024-02-28 14:47:38 +08:00
|
|
|
i_FR_in_p=adc_pads.frame_p,
|
|
|
|
i_FR_in_n=adc_pads.frame_n,
|
|
|
|
i_D0_in_p=adc_pads.data0_p,
|
|
|
|
i_D0_in_n=adc_pads.data0_n,
|
|
|
|
i_D1_in_p=adc_pads.data1_p,
|
|
|
|
i_D1_in_n=adc_pads.data1_n,
|
|
|
|
i_bitslip=bitslip,
|
|
|
|
i_delay_val=tap_delay_val,
|
2025-01-10 12:38:02 +08:00
|
|
|
o_ADC0_out=self.data_out[1], # LANES swapped on hardware
|
|
|
|
o_ADC1_out=self.data_out[0],
|
|
|
|
o_FR_out=self.s_frame,
|
2024-02-28 14:47:38 +08:00
|
|
|
o_o_data_from_pins=dummy,
|
|
|
|
o_idelay_rdy=dummy_idelay_rdy,
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
class AUX_ADC_CTRL(Module, AutoCSR):
|
|
|
|
def __init__(self, platform):
|
|
|
|
adc_aux_pads = platform.request("aux_adc")
|
|
|
|
|
|
|
|
self.adc_aux_ctrl = CSRStorage(5)
|
|
|
|
|
|
|
|
self.comb += [
|
|
|
|
adc_aux_pads.diff_n.eq(~self.adc_aux_ctrl.storage[0]),
|
|
|
|
adc_aux_pads.a.eq(self.adc_aux_ctrl.storage[1:4]),
|
|
|
|
adc_aux_pads.range.eq(self.adc_aux_ctrl.storage[4]),
|
|
|
|
]
|