master WRPLL: init
gw: add rtio_frequency gw: add wrpll ref clock config gw: add mmcm and expose mmcm config port fw: add mmcm read fw: add CLK_SEL to expander
This commit is contained in:
parent
9d5d883b1b
commit
c7df09b6a3
|
@ -224,8 +224,6 @@ class GenericMaster(SoCCore):
|
|||
|
||||
self.config["HW_REV"] = description["hw_rev"]
|
||||
|
||||
self.submodules += SMAClkinForward(self.platform)
|
||||
|
||||
data_pads = [platform.request("sfp", i) for i in range(4)]
|
||||
|
||||
self.submodules.gt_drtio = gtx_7series.GTX(
|
||||
|
@ -259,8 +257,18 @@ class GenericMaster(SoCCore):
|
|||
self.comb += ext_async_rst.eq(self.sys_crg.clk_sw_fsm.o_clk_sw & ~gtx0.tx_init.done)
|
||||
self.specials += MultiReg(self.sys_crg.clk_sw_fsm.o_clk_sw & self.sys_crg.mmcm_locked, self.gt_drtio.clk_path_ready, odomain="bootstrap")
|
||||
|
||||
self.config["HAS_SI5324"] = None
|
||||
self.config["SI5324_SOFT_RESET"] = None
|
||||
if with_wrpll:
|
||||
self.submodules.sma_pll = wrpll.SMA_PLL(platform.request("sma_clkin"))
|
||||
self.csr_devices.append("sma_pll")
|
||||
|
||||
self.submodules.main_dcxo = si549.Si549(platform.request("ddmtd_main_dcxo_i2c"))
|
||||
self.csr_devices.append("main_dcxo")
|
||||
self.config["HAS_SI549"] = None
|
||||
self.config["WRPLL_REF_CLK"] = "SMA_CLKIN"
|
||||
else:
|
||||
self.submodules += SMAClkinForward(self.platform)
|
||||
self.config["HAS_SI5324"] = None
|
||||
self.config["SI5324_SOFT_RESET"] = None
|
||||
|
||||
self.rtio_channels = []
|
||||
has_grabber = any(peripheral["type"] == "grabber" for peripheral in description["peripherals"])
|
||||
|
@ -565,6 +573,7 @@ class GenericSatellite(SoCCore):
|
|||
self.csr_devices.append("wrpll")
|
||||
self.comb += self.ps7.core.core0.nfiq.eq(self.wrpll.ev.irq)
|
||||
self.config["HAS_SI549"] = None
|
||||
self.config["WRPLL_REF_CLK"] = "GTX_CDR"
|
||||
else:
|
||||
self.submodules.siphaser = SiPhaser7Series(
|
||||
si5324_clkin=platform.request("cdr_clk"),
|
||||
|
|
|
@ -123,4 +123,65 @@ class WRPLL(Module, AutoCSR):
|
|||
self.main_tag_ev.stb.trigger.eq(main_tag_stb_sys)
|
||||
]
|
||||
|
||||
self.submodules.ev = SharedIRQ(self.ref_tag_ev, self.main_tag_ev)
|
||||
self.submodules.ev = SharedIRQ(self.ref_tag_ev, self.main_tag_ev)
|
||||
|
||||
|
||||
class SMA_PLL(Module, AutoCSR):
|
||||
def __init__(self, sma_clkin):
|
||||
freq = 125e9
|
||||
period = 1e9/freq # ns
|
||||
|
||||
mmcm_locked = Signal()
|
||||
mmcm_fb_clk = Signal()
|
||||
ref_clk = Signal()
|
||||
self.clock_domains.cd_ref = ClockDomain()
|
||||
|
||||
self.mmcm_locked = CSRStatus()
|
||||
self.mmcm_reset = CSRStorage() #TODO for i_RST
|
||||
|
||||
self.drp_addr = CSRStorage(7)
|
||||
self.drp_in = CSRStorage(16)
|
||||
self.drp_w_en = CSRStorage()
|
||||
self.drp_en = CSRStorage()
|
||||
self.drp_clk = CSRStorage()
|
||||
self.drp_out = CSRStatus(16)
|
||||
self.drp_ready = CSRStatus()
|
||||
|
||||
# # #
|
||||
|
||||
self.specials += [
|
||||
# MMCME2 is capable to accept 10Mhz input while PLLE2 only support down to 19Mhz input (DS191)
|
||||
Instance("MMCME2_ADV",
|
||||
p_BANDWIDTH="LOW", # lower jitter
|
||||
o_LOCKED=self.mmcm_locked.status,
|
||||
|
||||
p_CLKIN1_PERIOD=period,
|
||||
i_CLKIN1=ClockSignal("sys"),
|
||||
i_RST=ResetSignal("sys"),
|
||||
i_CLKINSEL=1, # 1=CLKIN1 0=CLKIN2
|
||||
|
||||
# VCO @ 1Ghz
|
||||
p_CLKFBOUT_MULT_F=8.0,
|
||||
# p_CLKFBOUT_MULT = 1.0, # M = p_CLKFBOUT_MULT_F/p_CLKFBOUT_MULT
|
||||
p_DIVCLK_DIVIDE=1,
|
||||
i_CLKFBIN=mmcm_fb_clk, o_CLKFBOUT=mmcm_fb_clk,
|
||||
|
||||
# 62.5MHz
|
||||
p_CLKOUT0_DIVIDE_F=16, p_CLKOUT0_PHASE=0.0, o_CLKOUT0=ref_clk,
|
||||
|
||||
# Dynamic Reconfiguration Port
|
||||
i_DADDR = self.drp_addr.storage,
|
||||
i_DI = self.drp_in.storage,
|
||||
i_DWE = self.drp_w_en.storage,
|
||||
i_DEN = self.drp_en.storage,
|
||||
i_DCLK = self.drp_clk.storage,
|
||||
o_DO = self.drp_out.status,
|
||||
o_DRDY = self.drp_ready.status
|
||||
),
|
||||
Instance("BUFG", i_I=ref_clk, o_O=self.cd_ref.clk),
|
||||
AsyncResetSynchronizer(self.cd_ref, ~self.mmcm_locked.status),
|
||||
|
||||
# debug output
|
||||
Instance("OBUFDS", i_I=self.cd_ref.clk, o_O=sma_clkin.p, o_OB=sma_clkin.n)
|
||||
]
|
||||
|
||||
|
|
|
@ -547,3 +547,64 @@ pub mod wrpll {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(has_sma_pll)]
|
||||
pub mod sma_pll {
|
||||
use super::*;
|
||||
|
||||
// Based on "DRP State Machine" section from XAPP888
|
||||
mod mmcm {
|
||||
|
||||
use super::*;
|
||||
|
||||
fn one_clock_cycle(timer: &mut GlobalTimer) {
|
||||
unsafe {
|
||||
csr::sma_pll::drp_clk_write(1);
|
||||
timer.delay_us(1);
|
||||
csr::sma_pll::drp_clk_write(0);
|
||||
timer.delay_us(1);
|
||||
}
|
||||
}
|
||||
|
||||
fn set_addr(address: u8) {
|
||||
unsafe {
|
||||
csr::sma_pll::drp_addr_write(address);
|
||||
}
|
||||
}
|
||||
|
||||
fn set_enable(en: bool) {
|
||||
unsafe {
|
||||
let val = if en { 1 } else { 0 };
|
||||
csr::sma_pll::drp_en_write(val);
|
||||
}
|
||||
}
|
||||
|
||||
fn get_data() -> u16 {
|
||||
unsafe { csr::sma_pll::drp_out_read() }
|
||||
}
|
||||
|
||||
fn drp_ready() -> bool {
|
||||
unsafe { csr::sma_pll::drp_ready_read() == 1 }
|
||||
}
|
||||
|
||||
pub fn read(timer: &mut GlobalTimer, address: u8) -> u16 {
|
||||
set_addr(address);
|
||||
set_enable(true);
|
||||
// Set DADDR on the MMCM and assert DEN for one clock cycle
|
||||
one_clock_cycle(timer);
|
||||
set_enable(false);
|
||||
while !drp_ready() {
|
||||
// keep the clock signal until data is ready
|
||||
one_clock_cycle(timer);
|
||||
}
|
||||
get_data()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn setup(timer: &mut GlobalTimer) {
|
||||
for addr in 7..12 {
|
||||
info!("address = {:#x} | val = {:016b}", addr, mmcm::read(timer, addr));
|
||||
}
|
||||
info!("running SMA PLL");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,6 +104,11 @@ pub fn main_core0() {
|
|||
io_expander1
|
||||
.init(i2c_bus)
|
||||
.expect("I2C I/O expander #1 initialization failed");
|
||||
|
||||
// Drive CLK_SEL to true
|
||||
#[cfg(has_si549)]
|
||||
io_expander0.set(1, 7, true);
|
||||
|
||||
// Drive TX_DISABLE to false on SFP0..3
|
||||
io_expander0.set(0, 1, false);
|
||||
io_expander1.set(0, 1, false);
|
||||
|
|
|
@ -4,6 +4,8 @@ use ksupport::i2c;
|
|||
use libboard_artiq::pl;
|
||||
#[cfg(has_si5324)]
|
||||
use libboard_artiq::si5324;
|
||||
#[cfg(has_si549)]
|
||||
use libboard_artiq::si549;
|
||||
#[cfg(has_si5324)]
|
||||
use libboard_zynq::i2c::I2c;
|
||||
use libboard_zynq::timer::GlobalTimer;
|
||||
|
@ -260,6 +262,48 @@ fn setup_si5324(i2c: &mut I2c, timer: &mut GlobalTimer, clk: RtioClock) {
|
|||
si5324::setup(i2c, &si5324_settings, si5324_ref_input, timer).expect("cannot initialize Si5324");
|
||||
}
|
||||
|
||||
#[cfg(has_si549)]
|
||||
fn setup_si549(timer: &mut GlobalTimer, clk: RtioClock) {
|
||||
let si549_settings = match clk {
|
||||
RtioClock::Int_100 => {
|
||||
info!("using internal 100MHz RTIO clock");
|
||||
si549::FrequencySetting {
|
||||
main: si549::DividerConfig {
|
||||
hsdiv: 0x06C,
|
||||
lsdiv: 0,
|
||||
fbdiv: 0x046C5F49797,
|
||||
},
|
||||
}
|
||||
}
|
||||
RtioClock::Int_125 => {
|
||||
info!("using internal 125MHz RTIO clock");
|
||||
si549::FrequencySetting {
|
||||
main: si549::DividerConfig {
|
||||
hsdiv: 0x058,
|
||||
lsdiv: 0,
|
||||
fbdiv: 0x04815791F25,
|
||||
},
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
// same setting as Int_125, but fallback to default
|
||||
warn!(
|
||||
"rtio_clock setting '{:?}' is unsupported. Falling back to default 125MHz RTIO clock.",
|
||||
clk
|
||||
);
|
||||
si549::FrequencySetting {
|
||||
main: si549::DividerConfig {
|
||||
hsdiv: 0x058,
|
||||
lsdiv: 0,
|
||||
fbdiv: 0x04815791F25,
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
si549::main_setup(timer, si549_settings).expect("cannot initialize main Si549");
|
||||
}
|
||||
|
||||
pub fn init(timer: &mut GlobalTimer, cfg: &Config) {
|
||||
let clk = get_rtio_clock_cfg(cfg);
|
||||
#[cfg(has_si5324)]
|
||||
|
@ -273,6 +317,11 @@ pub fn init(timer: &mut GlobalTimer, cfg: &Config) {
|
|||
_ => setup_si5324(i2c, timer, clk),
|
||||
}
|
||||
}
|
||||
#[cfg(has_si549)]
|
||||
{
|
||||
si549::sma_pll::setup(timer);
|
||||
setup_si549(timer, clk);
|
||||
}
|
||||
|
||||
#[cfg(has_drtio)]
|
||||
init_drtio(timer);
|
||||
|
|
Loading…
Reference in New Issue