Compare commits
No commits in common. "master" and "omit_arm_cache" have entirely different histories.
master
...
omit_arm_c
@ -20,15 +20,13 @@
|
|||||||
from migen import *
|
from migen import *
|
||||||
from migen.genlib.cdc import MultiReg
|
from migen.genlib.cdc import MultiReg
|
||||||
from misoc.interconnect.csr import AutoCSR, CSRStatus, CSRStorage
|
from misoc.interconnect.csr import AutoCSR, CSRStatus, CSRStorage
|
||||||
from misoc.interconnect.stream import AsyncFIFO
|
|
||||||
|
|
||||||
|
|
||||||
class CRG(Module):
|
class _CRG(Module):
|
||||||
def __init__(self, platform, dco_clk, dco_freq=200e6):
|
def __init__(self, platform, dco_clk, dco_freq=200e6):
|
||||||
self.clock_domains.cd_dco = ClockDomain()
|
self.clock_domains.cd_dco = ClockDomain()
|
||||||
self.clock_domains.cd_dco2x = ClockDomain()
|
self.clock_domains.cd_dco2x = ClockDomain()
|
||||||
self.clock_domains.cd_dco2d = 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_p, dco_clk_n = dco_clk
|
||||||
|
|
||||||
dco_clk_buf = Signal()
|
dco_clk_buf = Signal()
|
||||||
@ -43,83 +41,59 @@ class CRG(Module):
|
|||||||
clk_dco = Signal()
|
clk_dco = Signal()
|
||||||
clk_dco2x = Signal()
|
clk_dco2x = Signal()
|
||||||
clk_dco2d = Signal()
|
clk_dco2d = Signal()
|
||||||
clk_dco2d_45_degree = Signal()
|
|
||||||
mmcm_ps_psdone = Signal()
|
|
||||||
|
|
||||||
self.locked = 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)
|
platform.add_period_constraint(dco_clk_p, 1e9 / dco_freq)
|
||||||
self.specials += [
|
self.specials += [
|
||||||
Instance(
|
Instance(
|
||||||
"MMCME2_ADV",
|
"PLLE2_BASE",
|
||||||
p_BANDWIDTH="OPTIMIZED",
|
p_BANDWIDTH="OPTIMIZED",
|
||||||
p_DIVCLK_DIVIDE=1,
|
p_DIVCLK_DIVIDE=1,
|
||||||
p_CLKFBOUT_PHASE=0.0,
|
p_CLKFBOUT_PHASE=0.0,
|
||||||
p_CLKFBOUT_MULT_F=4, # VCO @ 800 MHz
|
p_CLKFBOUT_MULT=4, # VCO @ 800 MHz
|
||||||
p_CLKIN1_PERIOD=(1e9 / dco_freq),
|
p_CLKIN1_PERIOD=(1e9 / dco_freq),
|
||||||
p_REF_JITTER1=0.01,
|
p_REF_JITTER1=0.01,
|
||||||
p_STARTUP_WAIT="FALSE",
|
p_STARTUP_WAIT="FALSE",
|
||||||
i_CLKIN1=dco_clk_buf,
|
i_CLKIN1=dco_clk_buf,
|
||||||
i_PWRDWN=0,
|
i_PWRDWN=0,
|
||||||
i_RST=ResetSignal("sys") | self.mmcm_rst,
|
i_RST=ResetSignal("sys"),
|
||||||
i_CLKFBIN=clk_feedback_buf,
|
i_CLKFBIN=clk_feedback_buf,
|
||||||
o_CLKFBOUT=clk_feedback,
|
o_CLKFBOUT=clk_feedback,
|
||||||
|
p_CLKOUT0_DIVIDE=4,
|
||||||
p_CLKOUT0_USE_FINE_PS="TRUE",
|
p_CLKOUT0_PHASE=0.0,
|
||||||
p_CLKOUT0_DIVIDE_F=8,
|
|
||||||
p_CLKOUT0_PHASE=45.0,
|
|
||||||
p_CLKOUT0_DUTY_CYCLE=0.5,
|
p_CLKOUT0_DUTY_CYCLE=0.5,
|
||||||
o_CLKOUT0=clk_dco2d_45_degree, # 100 MHz <- dco_clk / 2 = 200 MHz / 2
|
o_CLKOUT0=clk_dco, # 200 MHz <- dco_clk
|
||||||
o_LOCKED=self.locked,
|
|
||||||
|
|
||||||
p_CLKOUT1_DIVIDE=2,
|
p_CLKOUT1_DIVIDE=2,
|
||||||
p_CLKOUT1_PHASE=0.0,
|
p_CLKOUT1_PHASE=0.0,
|
||||||
p_CLKOUT1_DUTY_CYCLE=0.5,
|
p_CLKOUT1_DUTY_CYCLE=0.5,
|
||||||
o_CLKOUT1=clk_dco2x, # 400 MHZ <- 2 * dco_clk = 2*200 MHz
|
o_CLKOUT1=clk_dco2x, # 400 MHZ <- 2 * dco_clk = 2*200 MHz
|
||||||
|
|
||||||
p_CLKOUT2_DIVIDE=8,
|
p_CLKOUT2_DIVIDE=8,
|
||||||
p_CLKOUT2_PHASE=0.0,
|
p_CLKOUT2_PHASE=0.0,
|
||||||
p_CLKOUT2_DUTY_CYCLE=0.5,
|
p_CLKOUT2_DUTY_CYCLE=0.5,
|
||||||
o_CLKOUT2=clk_dco2d, # 100 MHz <- dco_clk / 2 = 200 MHz / 2
|
o_CLKOUT2=clk_dco2d, # 100 MHz <- dco_clk / 2 = 200 MHz / 2
|
||||||
|
o_LOCKED=self.locked,
|
||||||
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_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_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, 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)
|
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):
|
class ADC(Module, AutoCSR):
|
||||||
def __init__(self, platform, dco_freq=200e6):
|
def __init__(self, platform, dco_freq=200e6):
|
||||||
adc_pads = platform.request("adc")
|
adc_pads = platform.request("adc")
|
||||||
afe_pads = platform.request("adc_afe")
|
afe_pads = platform.request("adc_afe")
|
||||||
|
|
||||||
self.frame_csr = CSRStatus(5)
|
self.frame_csr = CSRStatus(4)
|
||||||
self.data_ch0 = CSRStatus(16)
|
self.data_ch0 = CSRStatus(16)
|
||||||
self.data_ch1 = CSRStatus(16)
|
self.data_ch1 = CSRStatus(16)
|
||||||
|
|
||||||
self.tap_delay = CSRStorage(5)
|
self.tap_delay = CSRStorage(5)
|
||||||
self.bitslip_csr = CSRStorage(1)
|
self.bitslip_csr = CSRStorage(1)
|
||||||
|
|
||||||
self.afe_ctrl = CSRStorage(7)
|
self.afe_ctrl = CSRStorage(4)
|
||||||
|
|
||||||
tap_delay_val = Signal(5)
|
tap_delay_val = Signal(5)
|
||||||
bitslip = Signal()
|
bitslip = Signal()
|
||||||
@ -131,17 +105,7 @@ class ADC(Module, AutoCSR):
|
|||||||
ch2_shdn = Signal()
|
ch2_shdn = Signal()
|
||||||
|
|
||||||
self.data_out = [Signal(16, reset_less=True), Signal(16, reset_less=True)]
|
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 = 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")),
|
|
||||||
]
|
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|
||||||
@ -153,14 +117,11 @@ class ADC(Module, AutoCSR):
|
|||||||
# dco_clk.n.eq(adc_pads.dco_n),
|
# dco_clk.n.eq(adc_pads.dco_n),
|
||||||
tap_delay_val.eq(self.tap_delay.storage),
|
tap_delay_val.eq(self.tap_delay.storage),
|
||||||
Cat(ch1_gain_x10, ch2_gain_x10, ch1_shdn, ch2_shdn).eq(
|
Cat(ch1_gain_x10, ch2_gain_x10, ch1_shdn, ch2_shdn).eq(
|
||||||
self.afe_ctrl.storage[0:4]
|
self.afe_ctrl.storage
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
self.submodules.crg = CRG(platform, dco_clk, dco_freq)
|
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.specials += MultiReg(self.bitslip_csr.re, bitslip_re_dco_2d, "dco2d")
|
self.specials += MultiReg(self.bitslip_csr.re, bitslip_re_dco_2d, "dco2d")
|
||||||
self.sync.dco2d += [
|
self.sync.dco2d += [
|
||||||
@ -168,8 +129,7 @@ class ADC(Module, AutoCSR):
|
|||||||
]
|
]
|
||||||
|
|
||||||
self.comb += [
|
self.comb += [
|
||||||
self.frame_csr.status[0:4].eq(self.s_frame[0:4]),
|
self.frame_csr.status.eq(self.s_frame),
|
||||||
self.frame_csr.status[4].eq(self.crg.locked),
|
|
||||||
self.data_ch0.status.eq(self.data_out[0]),
|
self.data_ch0.status.eq(self.data_out[0]),
|
||||||
self.data_ch1.status.eq(self.data_out[1]),
|
self.data_ch1.status.eq(self.data_out[1]),
|
||||||
]
|
]
|
||||||
@ -186,7 +146,7 @@ class ADC(Module, AutoCSR):
|
|||||||
|
|
||||||
self.specials += Instance(
|
self.specials += Instance(
|
||||||
"LTC2195",
|
"LTC2195",
|
||||||
i_rst_in=ResetSignal("dco2d"),
|
i_rst_in=ResetSignal("sys"),
|
||||||
i_clk200=ClockSignal("idelay"),
|
i_clk200=ClockSignal("idelay"),
|
||||||
i_DCO=ClockSignal("dco"),
|
i_DCO=ClockSignal("dco"),
|
||||||
i_DCO_2D=ClockSignal("dco2d"),
|
i_DCO_2D=ClockSignal("dco2d"),
|
||||||
@ -198,9 +158,9 @@ class ADC(Module, AutoCSR):
|
|||||||
i_D1_in_n=adc_pads.data1_n,
|
i_D1_in_n=adc_pads.data1_n,
|
||||||
i_bitslip=bitslip,
|
i_bitslip=bitslip,
|
||||||
i_delay_val=tap_delay_val,
|
i_delay_val=tap_delay_val,
|
||||||
o_ADC0_out=self.data_out_cdc[1], # LANES swapped on hardware
|
o_ADC0_out=self.data_out[1], # LANES swapped on hardware
|
||||||
o_ADC1_out=self.data_out_cdc[0],
|
o_ADC1_out=self.data_out[0],
|
||||||
o_FR_out=self.s_frame_cdc,
|
o_FR_out=self.s_frame,
|
||||||
o_o_data_from_pins=dummy,
|
o_o_data_from_pins=dummy,
|
||||||
o_idelay_rdy=dummy_idelay_rdy,
|
o_idelay_rdy=dummy_idelay_rdy,
|
||||||
)
|
)
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
from migen import *
|
from migen import *
|
||||||
from misoc.interconnect.csr import AutoCSR, CSRStorage
|
from misoc.interconnect.csr import AutoCSR, CSRStorage
|
||||||
from migen.genlib.io import DDROutput
|
from migen.genlib.io import DDROutput
|
||||||
from misoc.interconnect.stream import AsyncFIFO
|
|
||||||
|
|
||||||
|
|
||||||
class DAC(Module, AutoCSR):
|
class DAC(Module, AutoCSR):
|
||||||
@ -39,51 +38,37 @@ class DAC(Module, AutoCSR):
|
|||||||
output_data_ch1 = Signal(14)
|
output_data_ch1 = Signal(14)
|
||||||
|
|
||||||
self.data_in = [Signal(14, reset_less=True), Signal(14, reset_less=True)]
|
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)
|
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 += [
|
self.comb += [
|
||||||
Cat(manual_override, ch0_pd, ch1_pd).eq(self.dac_ctrl.storage),
|
Cat(manual_override, ch0_pd, ch1_pd).eq(self.dac_ctrl.storage),
|
||||||
dac_pads.rst.eq(ResetSignal("dco2d")),
|
dac_pads.rst.eq(ResetSignal("sys")),
|
||||||
dac_afe_pads.ch1_pd_n.eq(~ch0_pd),
|
dac_afe_pads.ch1_pd_n.eq(~ch0_pd),
|
||||||
dac_afe_pads.ch2_pd_n.eq(~ch1_pd),
|
dac_afe_pads.ch2_pd_n.eq(~ch1_pd),
|
||||||
output_data_ch0.eq(
|
output_data_ch0.eq(
|
||||||
Mux(manual_override, self.data_in_csr_cdc[0], self.data_in_cdc[0])
|
Mux(manual_override, self.output_value_ch0.storage, self.data_in[0])
|
||||||
),
|
),
|
||||||
output_data_ch1.eq(
|
output_data_ch1.eq(
|
||||||
Mux(manual_override, self.data_in_csr_cdc[1], self.data_in_cdc[1])
|
Mux(manual_override, self.output_value_ch1.storage, self.data_in[1])
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
self.specials += [
|
# data
|
||||||
Instance("ODDR",
|
for lane in range(14):
|
||||||
i_C=ClockSignal("dco2d"),
|
self.specials += DDROutput(
|
||||||
i_CE=~ResetSignal("dco2d"),
|
i1 = output_data_ch0[lane],
|
||||||
i_D1=output_data_ch0[lane], # DDR CLK Rising Edge
|
i2 = output_data_ch1[lane],
|
||||||
i_D2=output_data_ch1[lane], # DDR CLK Falling Edge
|
o = dac_pads.data[lane],
|
||||||
o_Q=dac_pads.data[lane],
|
clk = ClockSignal("dco2d")
|
||||||
p_DDR_CLK_EDGE="SAME_EDGE")
|
)
|
||||||
for lane in range(14)]
|
|
||||||
self.specials += Instance("ODDR",
|
# clock forwarding
|
||||||
i_C=ClockSignal("dco2d_45_degree"),
|
self.specials += DDROutput(
|
||||||
i_CE=~ResetSignal("dco2d"),
|
i1 = 0b0,
|
||||||
i_D1=0,
|
i2 = 0b1,
|
||||||
i_D2=1,
|
o = dac_pads.dclkio,
|
||||||
o_Q=dac_pads.dclkio,
|
clk = ClockSignal("dco2d"),
|
||||||
p_DDR_CLK_EDGE="SAME_EDGE")
|
)
|
||||||
|
|
||||||
|
|
||||||
class AUX_DAC_CTRL(Module, AutoCSR):
|
class AUX_DAC_CTRL(Module, AutoCSR):
|
||||||
|
@ -147,7 +147,6 @@ class BaseSoC(PS7, AutoCSR):
|
|||||||
# self.add_main_adc(platform)
|
# self.add_main_adc(platform)
|
||||||
self.submodules.adc = ADC(platform)
|
self.submodules.adc = ADC(platform)
|
||||||
self.csr_devices.append("adc")
|
self.csr_devices.append("adc")
|
||||||
platform.add_false_path_constraints(self.crg.cd_sys.clk, self.adc.crg.cd_dco2d.clk)
|
|
||||||
|
|
||||||
# self.add_main_dac(platform)
|
# self.add_main_dac(platform)
|
||||||
self.submodules.dac = DAC(platform)
|
self.submodules.dac = DAC(platform)
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import time
|
|
||||||
import spidev
|
import spidev
|
||||||
from pyfastservo.common import (
|
from pyfastservo.common import (
|
||||||
ADC_AFE_CTRL_ADDR,
|
ADC_AFE_CTRL_ADDR,
|
||||||
@ -78,47 +78,30 @@ def read_frame():
|
|||||||
def perform_bitslip():
|
def perform_bitslip():
|
||||||
for i in range(4):
|
for i in range(4):
|
||||||
current_frame = read_frame()
|
current_frame = read_frame()
|
||||||
if current_frame & 0x0F != 0x0C:
|
if current_frame != 0x0C:
|
||||||
print(f"Performing bitslip (iteration: {i}). Current frame: 0x{current_frame:02x}")
|
print(f"Performing bitslip (iteration: {i}). Current frame: 0x{current_frame:02x}")
|
||||||
write_to_memory(ADC_BITSLIP_ADDR, 1)
|
write_to_memory(ADC_BITSLIP_ADDR, 1)
|
||||||
else:
|
else:
|
||||||
print(f"No bitslip required; Current frame: 0x{current_frame:02x}")
|
print(f"No bitslip required; Current frame: 0x{current_frame:02x}")
|
||||||
return
|
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():
|
def find_edge():
|
||||||
prev_frame = read_frame()
|
prev_frame = read_frame()
|
||||||
|
transition = False
|
||||||
for tap_delay in range(32):
|
for tap_delay in range(32):
|
||||||
write_to_memory(ADC_DELAY_ADDR, tap_delay)
|
write_to_memory(ADC_DELAY_ADDR, tap_delay)
|
||||||
current_frame = read_frame()
|
current_frame = read_frame()
|
||||||
|
|
||||||
print(f"Tap delay: {tap_delay}, Current frame: 0x{current_frame:02x}")
|
print(f"Tap delay: {tap_delay}, Current frame: 0x{current_frame:02x}")
|
||||||
print(f"prev_frame: 0x{prev_frame:02x}")
|
|
||||||
|
|
||||||
if current_frame != prev_frame:
|
if current_frame != prev_frame:
|
||||||
final_delay = ((tap_delay+1) // 2) + 2
|
if not transition:
|
||||||
print(f"Edge detected; setting iDelay to: {final_delay}")
|
transition = True
|
||||||
write_to_memory(ADC_DELAY_ADDR, final_delay)
|
else:
|
||||||
return
|
final_delay = (tap_delay // 2) + 2
|
||||||
|
print(f"Edge detected; setting iDelay to: {final_delay}")
|
||||||
|
write_to_memory(ADC_DELAY_ADDR, final_delay)
|
||||||
|
return
|
||||||
|
|
||||||
prev_frame = current_frame
|
prev_frame = current_frame
|
||||||
|
|
||||||
@ -143,36 +126,6 @@ def enable_adc_afe(ch1_x10=False, ch2_x10=False):
|
|||||||
print(f"ADC_AFE_CTRL: 0x{afe_ctrl:02X}")
|
print(f"ADC_AFE_CTRL: 0x{afe_ctrl:02X}")
|
||||||
return afe_ctrl
|
return afe_ctrl
|
||||||
|
|
||||||
def search_edge():
|
|
||||||
for tap_delay in range(32):
|
|
||||||
print(f"iDelay to: {tap_delay}")
|
|
||||||
write_to_memory(ADC_DELAY_ADDR, tap_delay)
|
|
||||||
time.sleep(1)
|
|
||||||
current_frame = read_frame()
|
|
||||||
print(f"Tap delay: {tap_delay}, Current frame: 0x{current_frame:02x}")
|
|
||||||
print_adc_channels()
|
|
||||||
|
|
||||||
def print_adc_channel(ch):
|
|
||||||
if ch == 0:
|
|
||||||
adc_ch0 = read_adc_channel(ADC_CH0_HIGH_ADDR, ADC_CH0_LOW_ADDR)
|
|
||||||
print(f"Final ADC_CH0: 0x{adc_ch0:04x}")
|
|
||||||
if ch == 1:
|
|
||||||
adc_ch1 = read_adc_channel(ADC_CH1_HIGH_ADDR, ADC_CH1_LOW_ADDR)
|
|
||||||
print(f"Final ADC_CH1: 0x{adc_ch1:04x}")
|
|
||||||
|
|
||||||
def find_min_max_ch(ch):
|
|
||||||
test = []
|
|
||||||
for i in range(100):
|
|
||||||
if ch == 0:
|
|
||||||
test.append(read_adc_channel(ADC_CH0_HIGH_ADDR, ADC_CH0_LOW_ADDR))
|
|
||||||
else:
|
|
||||||
test.append(read_adc_channel(ADC_CH1_HIGH_ADDR, ADC_CH1_LOW_ADDR))
|
|
||||||
print("ch", ch, hex(test[-1]))
|
|
||||||
print("Min:", hex(min(test)))
|
|
||||||
print("Max:", hex(max(test)))
|
|
||||||
print("Diff:", hex(max(test)-min(test)))
|
|
||||||
|
|
||||||
|
|
||||||
def configure_ltc2195():
|
def configure_ltc2195():
|
||||||
spi = spidev.SpiDev()
|
spi = spidev.SpiDev()
|
||||||
try:
|
try:
|
||||||
@ -191,31 +144,15 @@ def configure_ltc2195():
|
|||||||
0x04: test_pattern & 0xFF
|
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
|
# Performing Word Align
|
||||||
perform_bitslip()
|
perform_bitslip()
|
||||||
find_edge()
|
find_edge()
|
||||||
|
print_adc_channels()
|
||||||
# Printing it once is not enough to check whether the alignment is correct.
|
|
||||||
for i in range(100):
|
|
||||||
print_adc_channels()
|
|
||||||
|
|
||||||
main_adc_test_mode(spi, False)
|
main_adc_test_mode(spi, False)
|
||||||
verify_adc_registers(spi, {0x02: 0x11}) # Verify test mode is off
|
verify_adc_registers(spi, {0x02: 0x11}) # Verify test mode is off
|
||||||
|
|
||||||
# FIXME: AFE Gain 1x is not functional on that batch of fast servo under development
|
|
||||||
enable_adc_afe(ch1_x10=1, ch2_x10=1)
|
|
||||||
|
|
||||||
#find_min_max_ch(0)
|
enable_adc_afe()
|
||||||
#find_min_max_ch(1)
|
|
||||||
|
|
||||||
#for i in range(10):
|
|
||||||
# print_adc_channel(0)
|
|
||||||
|
|
||||||
#for i in range(10):
|
|
||||||
# print_adc_channel(1)
|
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
spi.close()
|
spi.close()
|
||||||
|
@ -45,7 +45,7 @@ def spi_read(spi, address):
|
|||||||
rx_buffer = spi.xfer2([0x80 | address, 0x00])
|
rx_buffer = spi.xfer2([0x80 | address, 0x00])
|
||||||
return rx_buffer[1]
|
return rx_buffer[1]
|
||||||
|
|
||||||
def soft_reset(spi):
|
def hard_reset(spi):
|
||||||
spi_write(spi, 0x00, 0x10) # Software reset
|
spi_write(spi, 0x00, 0x10) # Software reset
|
||||||
spi_write(spi, 0x00, 0x00) # Release software reset
|
spi_write(spi, 0x00, 0x00) # Release software reset
|
||||||
spi_read(spi, 0x00) # Read reset address (necessary for reset to take effect)
|
spi_read(spi, 0x00) # Read reset address (necessary for reset to take effect)
|
||||||
@ -63,10 +63,7 @@ def configure_dac(spi):
|
|||||||
spi_write(spi, 0x07, 0xA0) # Enable on-chip QRSET (1.6 kΩ for 20mA output)
|
spi_write(spi, 0x07, 0xA0) # Enable on-chip QRSET (1.6 kΩ for 20mA output)
|
||||||
spi_write(spi, 0x05, 0x00) # Disable internal IRCML
|
spi_write(spi, 0x05, 0x00) # Disable internal IRCML
|
||||||
spi_write(spi, 0x08, 0x00) # Disable internal QRCML
|
spi_write(spi, 0x08, 0x00) # Disable internal QRCML
|
||||||
spi_write(spi, 0x02, 0xB4) # Enable 2's complement, IFirst: True, IRising: True, DCI_EN: Enabled
|
spi_write(spi, 0x02, 0xB4) # Enable 2's complement, LVDS interface, 4 LVDS lanes
|
||||||
spi_write(spi, 0x14, 0x00)
|
|
||||||
spi_write(spi, 0x14, 0x08) # Trigger the retimer to reacquire the clock relationship
|
|
||||||
spi_write(spi, 0x14, 0x00)
|
|
||||||
|
|
||||||
def dac_self_calibration(spi):
|
def dac_self_calibration(spi):
|
||||||
spi_write(spi, 0x12, 0x00) # Reset calibration status
|
spi_write(spi, 0x12, 0x00) # Reset calibration status
|
||||||
@ -86,11 +83,11 @@ def dac_self_calibration(spi):
|
|||||||
|
|
||||||
def manual_override(enable=True):
|
def manual_override(enable=True):
|
||||||
reg_contents = read_from_memory(CTRL_ADDR, 1)[0]
|
reg_contents = read_from_memory(CTRL_ADDR, 1)[0]
|
||||||
|
print(f"REG contents: 0b{reg_contents:03b}")
|
||||||
to_write = reg_contents | 0b1 if enable else reg_contents & 0b110
|
to_write = reg_contents | 0b1 if enable else reg_contents & 0b110
|
||||||
write_to_memory(CTRL_ADDR, to_write)
|
write_to_memory(CTRL_ADDR, to_write)
|
||||||
print(f"Set DAC Output Manual Override: {enable}")
|
|
||||||
|
|
||||||
def power_down_afe(channel, power_down=True):
|
def power_down(channel, power_down=True):
|
||||||
assert channel in (0, 1)
|
assert channel in (0, 1)
|
||||||
|
|
||||||
bitmask = 1 << (channel + 1) & 0b111
|
bitmask = 1 << (channel + 1) & 0b111
|
||||||
@ -101,32 +98,19 @@ def power_down_afe(channel, power_down=True):
|
|||||||
to_write = reg_contents | value
|
to_write = reg_contents | value
|
||||||
write_to_memory(CTRL_ADDR, to_write)
|
write_to_memory(CTRL_ADDR, to_write)
|
||||||
reg_contents = read_from_memory(CTRL_ADDR, 1)[0]
|
reg_contents = read_from_memory(CTRL_ADDR, 1)[0]
|
||||||
print(f"Power Down DAC AFE Ch{channel}: {power_down}")
|
print(f"REG contents: 0b{reg_contents:03b}")
|
||||||
|
|
||||||
def set_dac_output(value):
|
def set_dac_output(value):
|
||||||
value = min(value, 0x3FFF)
|
value = min(value, 0x3FFF)
|
||||||
low_word = value & 0xFF
|
low_word = value & 0xFF
|
||||||
high_word = (value >> 8) & 0x3F
|
high_word = (value >> 8) & 0x3F
|
||||||
|
|
||||||
# Note: DAC HIGH word and LOW word output are not updated
|
|
||||||
# at the same time. On scope, you will see more than one step
|
|
||||||
# of value changed.
|
|
||||||
write_to_memory(CH0_HIGH_WORD_ADDR, high_word)
|
write_to_memory(CH0_HIGH_WORD_ADDR, high_word)
|
||||||
write_to_memory(CH0_LOW_WORD_ADDR, low_word)
|
write_to_memory(CH0_LOW_WORD_ADDR, low_word)
|
||||||
write_to_memory(CH1_HIGH_WORD_ADDR, high_word)
|
write_to_memory(CH1_HIGH_WORD_ADDR, high_word)
|
||||||
write_to_memory(CH1_LOW_WORD_ADDR, low_word)
|
write_to_memory(CH1_LOW_WORD_ADDR, low_word)
|
||||||
print(f"DAC output set to: 0x{value:04X}")
|
print(f"DAC output set to: 0x{value:04X}")
|
||||||
|
|
||||||
def check_clk_relationship(spi):
|
|
||||||
clkmode_reg = spi_read(spi, 0x14)
|
|
||||||
print(f"CLKMODE reg: 0x{clkmode_reg:02X}")
|
|
||||||
if clkmode_reg & 0b00010000:
|
|
||||||
print("Clock relationship is not found")
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
print("Clock relationship is found")
|
|
||||||
return True
|
|
||||||
|
|
||||||
def configure_ad9117():
|
def configure_ad9117():
|
||||||
spi = spidev.SpiDev()
|
spi = spidev.SpiDev()
|
||||||
spi.open(MAIN_DAC_BUS, MAIN_DAC_DEVICE)
|
spi.open(MAIN_DAC_BUS, MAIN_DAC_DEVICE)
|
||||||
@ -135,24 +119,20 @@ def configure_ad9117():
|
|||||||
spi.cshigh = False
|
spi.cshigh = False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
soft_reset(spi)
|
hard_reset(spi)
|
||||||
if not check_version(spi):
|
if not check_version(spi):
|
||||||
print("Unrecognized DAC version")
|
print("Unrecognized DAC version")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
power_down_afe(0, True)
|
|
||||||
power_down_afe(1, True)
|
|
||||||
|
|
||||||
configure_dac(spi)
|
configure_dac(spi)
|
||||||
check_clk_relationship(spi)
|
|
||||||
dac_self_calibration(spi)
|
dac_self_calibration(spi)
|
||||||
|
|
||||||
# Enable DAC outputs
|
# Enable DAC outputs
|
||||||
spi_write(spi, 0x01, spi_read(spi, 0x01) & ~((1 << 4) | (1 << 3)))
|
spi_write(spi, 0x01, spi_read(spi, 0x01) & ~((1 << 4) | (1 << 3)))
|
||||||
|
|
||||||
power_down_afe(0, False)
|
power_down(0, False)
|
||||||
power_down_afe(1, False)
|
power_down(1, False)
|
||||||
manual_override(False)
|
manual_override(True)
|
||||||
|
|
||||||
print("AD9117 configuration completed successfully")
|
print("AD9117 configuration completed successfully")
|
||||||
return True
|
return True
|
||||||
|
20
flake.lock
generated
20
flake.lock
generated
@ -18,11 +18,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1733220138,
|
"lastModified": 1723938990,
|
||||||
"narHash": "sha256-Yh5XZ9yVurrcYdNTSWxYgW4+EJ0pcOqgM1043z9JaRc=",
|
"narHash": "sha256-9tUadhnZQbWIiYVXH8ncfGXGvkNq3Hag4RCBEMUk7MI=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "bcb68885668cccec12276bbb379f8f2557aa06ce",
|
"rev": "c42fcfbdfeae23e68fc520f9182dde9f38ad1890",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@ -64,11 +64,11 @@
|
|||||||
"src-migen": {
|
"src-migen": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1727677091,
|
"lastModified": 1721561053,
|
||||||
"narHash": "sha256-Zg3SQnTwMM/VkOGKogbPyuCC2NhLy8HB2SPEUWWNgCU=",
|
"narHash": "sha256-z3LRhNmKZrjr6rFD0yxtccSa/SWvFIYmb+G/D5d2Jd8=",
|
||||||
"owner": "m-labs",
|
"owner": "m-labs",
|
||||||
"repo": "migen",
|
"repo": "migen",
|
||||||
"rev": "c19ae9f8ae162ffe2d310a92bfce53ac2a821bc8",
|
"rev": "9279e8623f8433bc4f23ac51e5e2331bfe544417",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@ -80,11 +80,11 @@
|
|||||||
"src-misoc": {
|
"src-misoc": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1729234629,
|
"lastModified": 1715647536,
|
||||||
"narHash": "sha256-TLsTCXV5AC2xh+bS7EhBVBKqdqIU3eKrnlWcFF9LtAM=",
|
"narHash": "sha256-q+USDcaKHABwW56Jzq8u94iGPWlyLXMyVt0j/Gyg+IE=",
|
||||||
"ref": "refs/heads/master",
|
"ref": "refs/heads/master",
|
||||||
"rev": "6085a312bca26adeca6584e37d08c8ba2e1d6e38",
|
"rev": "fea9de558c730bc394a5936094ae95bb9d6fa726",
|
||||||
"revCount": 2460,
|
"revCount": 2455,
|
||||||
"submodules": true,
|
"submodules": true,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/m-labs/misoc.git"
|
"url": "https://github.com/m-labs/misoc.git"
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
./not-os-patches/pr-30.patch
|
./not-os-patches/pr-30.patch
|
||||||
./not-os-patches/pr-31.patch
|
./not-os-patches/pr-31.patch
|
||||||
./not-os-patches/pr-33.patch
|
./not-os-patches/pr-33.patch
|
||||||
./not-os-patches/iproute2.patch
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -97,7 +96,7 @@
|
|||||||
freetype
|
freetype
|
||||||
fontconfig
|
fontconfig
|
||||||
];
|
];
|
||||||
profile = "set -e; source /opt/Xilinx/Vivado/2024.2/settings64.sh";
|
profile = "set -e; source /opt/Xilinx/Vivado/2022.2/settings64.sh";
|
||||||
runScript = "vivado";
|
runScript = "vivado";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
diff --git a/system-path.nix b/system-path.nix
|
|
||||||
index 490197d..93e940a 100644
|
|
||||||
--- a/system-path.nix
|
|
||||||
+++ b/system-path.nix
|
|
||||||
@@ -6,7 +6,7 @@
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
- requiredPackages = with pkgs; [ utillinux coreutils iproute iputils procps bashInteractive runit ];
|
|
||||||
+ requiredPackages = with pkgs; [ utillinux coreutils iproute2 iputils procps bashInteractive runit ];
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options = {
|
|
@ -1,5 +1,5 @@
|
|||||||
diff --git a/configuration.nix b/configuration.nix
|
diff --git a/configuration.nix b/configuration.nix
|
||||||
index 010c487..2d08009 100644
|
index 010c487..e1e85ba 100644
|
||||||
--- a/configuration.nix
|
--- a/configuration.nix
|
||||||
+++ b/configuration.nix
|
+++ b/configuration.nix
|
||||||
@@ -1,4 +1,4 @@
|
@@ -1,4 +1,4 @@
|
||||||
@ -8,7 +8,7 @@ index 010c487..2d08009 100644
|
|||||||
|
|
||||||
{
|
{
|
||||||
imports = [ ./qemu.nix ];
|
imports = [ ./qemu.nix ];
|
||||||
@@ -7,10 +7,16 @@
|
@@ -7,10 +7,15 @@
|
||||||
environment.etc = {
|
environment.etc = {
|
||||||
"ssh/authorized_keys.d/root" = {
|
"ssh/authorized_keys.d/root" = {
|
||||||
text = ''
|
text = ''
|
||||||
@ -18,7 +18,6 @@ index 010c487..2d08009 100644
|
|||||||
+ ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBNdIiLvP2hmDUFyyE0oLOIXrjrMdWWpBV9/gPR5m4AiARx4JkufIDZzmptdYQ5FhJORJ4lluPqp7dAmahoSwg4lv9Di0iNQpHMJvNGZLHYKM1H1FWCCFIEDJ8bD4SVfrDg== root
|
+ ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBNdIiLvP2hmDUFyyE0oLOIXrjrMdWWpBV9/gPR5m4AiARx4JkufIDZzmptdYQ5FhJORJ4lluPqp7dAmahoSwg4lv9Di0iNQpHMJvNGZLHYKM1H1FWCCFIEDJ8bD4SVfrDg== root
|
||||||
+ ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBF/YybP+fQ0J+bNqM5Vgx5vDmVqVWsgUdF1moUxghv7d73GZAFaM6IFBdrXTAa33AwnWwDPMrTgP1V6SXBkb3ciJo/lD1urJGbydbSI5Ksq9d59wvOeANvyWYrQw6+eqTQ== sb
|
+ ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBF/YybP+fQ0J+bNqM5Vgx5vDmVqVWsgUdF1moUxghv7d73GZAFaM6IFBdrXTAa33AwnWwDPMrTgP1V6SXBkb3ciJo/lD1urJGbydbSI5Ksq9d59wvOeANvyWYrQw6+eqTQ== sb
|
||||||
+ ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBFkmOCQ3BQh3qUjLtfdqyeBsx8rkk/QYlzB0TMrnfn6waLN6yKfPC3WVFv4zN5kNKb/OayvqDa+zfkKe85e/oIPQQKflF7GrCHdssz33DCnW90cz532E6iqG1pjeZjID2A== flo
|
+ ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBFkmOCQ3BQh3qUjLtfdqyeBsx8rkk/QYlzB0TMrnfn6waLN6yKfPC3WVFv4zN5kNKb/OayvqDa+zfkKe85e/oIPQQKflF7GrCHdssz33DCnW90cz532E6iqG1pjeZjID2A== flo
|
||||||
+ ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICAranL376soiSJ0kxdYNrwElcaZPW1heLFjs8Y7n0jT linuswck
|
|
||||||
'';
|
'';
|
||||||
mode = "0444";
|
mode = "0444";
|
||||||
};
|
};
|
||||||
|
@ -152,7 +152,7 @@ index c61f9d6..fbdf0fd 100644
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
diff --git a/zynq_image.nix b/zynq_image.nix
|
diff --git a/zynq_image.nix b/zynq_image.nix
|
||||||
index 3fa23ab..069fe89 100644
|
index 3fa23ab..d5c5eda 100644
|
||||||
--- a/zynq_image.nix
|
--- a/zynq_image.nix
|
||||||
+++ b/zynq_image.nix
|
+++ b/zynq_image.nix
|
||||||
@@ -1,66 +1,89 @@
|
@@ -1,66 +1,89 @@
|
||||||
@ -250,7 +250,7 @@ index 3fa23ab..069fe89 100644
|
|||||||
- environment.etc."service/getty/run".source = pkgs.writeShellScript "getty" ''
|
- environment.etc."service/getty/run".source = pkgs.writeShellScript "getty" ''
|
||||||
- agetty ttyPS0 115200
|
- agetty ttyPS0 115200
|
||||||
+ environment = {
|
+ environment = {
|
||||||
+ systemPackages = with pkgs; [ inetutils wget gnugrep nano vim ];
|
+ systemPackages = with pkgs; [ inetutils wget nano ];
|
||||||
+ etc = {
|
+ etc = {
|
||||||
+ "service/getty/run".source = pkgs.writeShellScript "getty" ''
|
+ "service/getty/run".source = pkgs.writeShellScript "getty" ''
|
||||||
+ hostname ${config.networking.hostName}
|
+ hostname ${config.networking.hostName}
|
||||||
|
Loading…
Reference in New Issue
Block a user