From 4e9a529e5ac19af78d393fd80f34773756c9e30d Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Thu, 7 May 2020 21:34:02 +0800 Subject: [PATCH] kasli: integrate WRPLL --- artiq/firmware/libboard_artiq/wrpll.rs | 3 ++ artiq/firmware/libboard_misoc/io_expander.rs | 21 +++++++-- artiq/firmware/satman/main.rs | 11 +++++ artiq/gateware/targets/kasli.py | 48 ++++++++++++++------ 4 files changed, 65 insertions(+), 18 deletions(-) diff --git a/artiq/firmware/libboard_artiq/wrpll.rs b/artiq/firmware/libboard_artiq/wrpll.rs index 5df8eef1e..123e70c47 100644 --- a/artiq/firmware/libboard_artiq/wrpll.rs +++ b/artiq/firmware/libboard_artiq/wrpll.rs @@ -175,7 +175,10 @@ mod si549 { use board_misoc::clock; use super::i2c; + #[cfg(any(soc_platform = "metlino", soc_platform = "sayma_amc", soc_platform = "sayma_rtm"))] pub const ADDRESS: u8 = 0x55; + #[cfg(soc_platform = "kasli")] + pub const ADDRESS: u8 = 0x67; pub fn write(dcxo: i2c::Dcxo, reg: u8, val: u8) -> Result<(), &'static str> { i2c::start(dcxo); diff --git a/artiq/firmware/libboard_misoc/io_expander.rs b/artiq/firmware/libboard_misoc/io_expander.rs index 136a38856..d2d2acd2f 100644 --- a/artiq/firmware/libboard_misoc/io_expander.rs +++ b/artiq/firmware/libboard_misoc/io_expander.rs @@ -6,6 +6,7 @@ pub struct IoExpander { port: u8, address: u8, virtual_led_mapping: &'static [(u8, u8, u8)], + iodir: [u8; 2], out_current: [u8; 2], out_target: [u8; 2], } @@ -22,6 +23,7 @@ impl IoExpander { port: 11, address: 0x40, virtual_led_mapping: &VIRTUAL_LED_MAPPING0, + iodir: [0xff; 2], out_current: [0; 2], out_target: [0; 2], }, @@ -30,6 +32,7 @@ impl IoExpander { port: 11, address: 0x42, virtual_led_mapping: &VIRTUAL_LED_MAPPING1, + iodir: [0xff; 2], out_current: [0; 2], out_target: [0; 2], }, @@ -54,15 +57,19 @@ impl IoExpander { Ok(()) } + fn update_iodir(&self) -> Result<(), &'static str> { + self.write(0x00, self.iodir[0])?; + self.write(0x01, self.iodir[1])?; + Ok(()) + } + pub fn init(&mut self) -> Result<(), &'static str> { self.select()?; - let mut iodir = [0xffu8; 2]; for (_led, port, bit) in self.virtual_led_mapping.iter() { - iodir[*port as usize] &= !(1 << *bit); + self.iodir[*port as usize] &= !(1 << *bit); } - self.write(0x00, iodir[0])?; - self.write(0x01, iodir[1])?; + self.update_iodir()?; self.out_current[0] = 0x00; self.write(0x12, 0x00)?; @@ -71,6 +78,12 @@ impl IoExpander { Ok(()) } + pub fn set_oe(&mut self, port: u8, outputs: u8) -> Result<(), &'static str> { + self.iodir[port as usize] &= !outputs; + self.update_iodir()?; + Ok(()) + } + pub fn set(&mut self, port: u8, bit: u8, high: bool) { if high { self.out_target[port as usize] |= 1 << bit; diff --git a/artiq/firmware/satman/main.rs b/artiq/firmware/satman/main.rs index cb10671c6..9e2144370 100644 --- a/artiq/firmware/satman/main.rs +++ b/artiq/firmware/satman/main.rs @@ -464,6 +464,17 @@ pub extern fn main() -> i32 { io_expander1 = board_misoc::io_expander::IoExpander::new(1); io_expander0.init().expect("I2C I/O expander #0 initialization failed"); io_expander1.init().expect("I2C I/O expander #1 initialization failed"); + #[cfg(has_wrpll)] + { + io_expander0.set_oe(1, 1 << 7).unwrap(); + io_expander0.set(1, 7, true); + io_expander0.service().unwrap(); + io_expander1.set_oe(0, 1 << 7).unwrap(); + io_expander1.set_oe(1, 1 << 7).unwrap(); + io_expander1.set(0, 7, true); + io_expander1.set(1, 7, true); + io_expander1.service().unwrap(); + } } #[cfg(has_si5324)] diff --git a/artiq/gateware/targets/kasli.py b/artiq/gateware/targets/kasli.py index fe2d5a65c..73162c65b 100755 --- a/artiq/gateware/targets/kasli.py +++ b/artiq/gateware/targets/kasli.py @@ -20,6 +20,7 @@ from artiq.gateware.rtio.phy import ttl_simple, ttl_serdes_7series, edge_counter from artiq.gateware import eem from artiq.gateware.drtio.transceiver import gtp_7series from artiq.gateware.drtio.siphaser import SiPhaser7Series +from artiq.gateware.drtio.wrpll import WRPLL, DDMTDSamplerGTP from artiq.gateware.drtio.rx_synchronizer import XilinxRXSynchronizer from artiq.gateware.drtio import * from artiq.build_soc import * @@ -452,7 +453,7 @@ class SatelliteBase(BaseSoC): } mem_map.update(BaseSoC.mem_map) - def __init__(self, rtio_clk_freq=125e6, enable_sata=False, **kwargs): + def __init__(self, rtio_clk_freq=125e6, enable_sata=False, *, with_wrpll=False, **kwargs): BaseSoC.__init__(self, cpu_type="or1k", sdram_controller_type="minicon", @@ -556,24 +557,38 @@ class SatelliteBase(BaseSoC): self.add_memory_group("drtioaux_mem", drtioaux_memory_group) self.add_csr_group("drtiorep", drtiorep_csr_group) - self.config["RTIO_FREQUENCY"] = str(rtio_clk_freq/1e6) - self.submodules.siphaser = SiPhaser7Series( - si5324_clkin=platform.request("cdr_clk") if platform.hw_rev == "v2.0" - else platform.request("si5324_clkin"), - rx_synchronizer=self.rx_synchronizer, - ref_clk=self.crg.clk125_div2, ref_div2=True, - rtio_clk_freq=rtio_clk_freq) - platform.add_false_path_constraints( - self.crg.cd_sys.clk, self.siphaser.mmcm_freerun_output) - self.csr_devices.append("siphaser") i2c = self.platform.request("i2c") self.submodules.i2c = gpio.GPIOTristate([i2c.scl, i2c.sda]) self.csr_devices.append("i2c") self.config["I2C_BUS_COUNT"] = 1 - self.config["HAS_SI5324"] = None - self.config["SI5324_SOFT_RESET"] = None rtio_clk_period = 1e9/rtio_clk_freq + self.config["RTIO_FREQUENCY"] = str(rtio_clk_freq/1e6) + if with_wrpll: + self.submodules.wrpll_sampler = DDMTDSamplerGTP( + self.drtio_transceiver, + platform.request("cdr_clk_clean_fabric")) + self.submodules.wrpll = WRPLL( + helper_clk_pads=platform.request("ddmtd_helper_clk"), + main_dcxo_i2c=platform.request("ddmtd_main_dcxo_i2c"), + helper_dxco_i2c=platform.request("ddmtd_helper_dcxo_i2c"), + ddmtd_inputs=self.wrpll_sampler) + self.csr_devices.append("wrpll") + platform.add_period_constraint(self.wrpll.cd_helper.clk, rtio_clk_period*0.99) + platform.add_false_path_constraints(self.crg.cd_sys.clk, self.wrpll.cd_helper.clk) + else: + self.submodules.siphaser = SiPhaser7Series( + si5324_clkin=platform.request("cdr_clk") if platform.hw_rev == "v2.0" + else platform.request("si5324_clkin"), + rx_synchronizer=self.rx_synchronizer, + ref_clk=self.crg.clk125_div2, ref_div2=True, + rtio_clk_freq=rtio_clk_freq) + platform.add_false_path_constraints( + self.crg.cd_sys.clk, self.siphaser.mmcm_freerun_output) + self.csr_devices.append("siphaser") + self.config["HAS_SI5324"] = None + self.config["SI5324_SOFT_RESET"] = None + gtp = self.drtio_transceiver.gtps[0] platform.add_period_constraint(gtp.txoutclk, rtio_clk_period) platform.add_period_constraint(gtp.rxoutclk, rtio_clk_period) @@ -658,15 +673,20 @@ def main(): parser.add_argument("-V", "--variant", default="tester", help="variant: {} (default: %(default)s)".format( "/".join(sorted(VARIANTS.keys())))) + parser.add_argument("--with-wrpll", default=False, action="store_true") args = parser.parse_args() + argdict = dict() + if args.with_wrpll: + argdict["with_wrpll"] = True + variant = args.variant.lower() try: cls = VARIANTS[variant] except KeyError: raise SystemExit("Invalid variant (-V/--variant)") - soc = cls(**soc_kasli_argdict(args)) + soc = cls(**soc_kasli_argdict(args), **argdict) build_artiq_soc(soc, builder_argdict(args))