sayma: prepare for SYSREF align

We will try DDMTD on the AMC first, as this is simpler and perhaps will work on v2 after the power supply fixes.
This commit is contained in:
Sebastien Bourdeauducq 2019-10-08 12:30:47 +08:00
parent 5ee81dc643
commit 4df2c5d1fb
5 changed files with 139 additions and 118 deletions

View File

@ -155,8 +155,8 @@ pub mod hmc7043 {
(true, SYSREF_DIV, 0x08, true), // 1: DAC1_SYSREF (true, SYSREF_DIV, 0x08, true), // 1: DAC1_SYSREF
(true, DAC_CLK_DIV, 0x08, false), // 2: DAC0_CLK (true, DAC_CLK_DIV, 0x08, false), // 2: DAC0_CLK
(true, SYSREF_DIV, 0x08, true), // 3: DAC0_SYSREF (true, SYSREF_DIV, 0x08, true), // 3: DAC0_SYSREF
(false, 0, 0x10, true), // 4: AMC_FPGA_SYSREF0 (true, SYSREF_DIV, 0x10, true), // 4: AMC_FPGA_SYSREF0
(true, SYSREF_DIV, 0x10, true), // 5: AMC_FPGA_SYSREF1 (true, FPGA_CLK_DIV, 0x10, true), // 5: AMC_FPGA_SYSREF1
(false, 0, 0x10, false), // 6: unused (false, 0, 0x10, false), // 6: unused
(true, SYSREF_DIV, 0x10, true), // 7: RTM_FPGA_SYSREF0 (true, SYSREF_DIV, 0x10, true), // 7: RTM_FPGA_SYSREF0
(true, FPGA_CLK_DIV, 0x08, false), // 8: GTP_CLK0_IN (true, FPGA_CLK_DIV, 0x08, false), // 8: GTP_CLK0_IN

View File

@ -1,100 +1,123 @@
use board_misoc::{csr, clock}; pub mod jesd {
use board_artiq::drtioaux; use board_misoc::{csr, clock};
use super::jdac_requests; pub fn reset(reset: bool) {
unsafe {
pub fn jesd_reset(reset: bool) { csr::jesd_crg::jreset_write(if reset {1} else {0});
unsafe { }
csr::jesd_crg::jreset_write(if reset {1} else {0});
} }
}
fn jesd_enable(dacno: u8, en: bool) { pub fn enable(dacno: u8, en: bool) {
unsafe { unsafe {
(csr::JDCG[dacno as usize].jesd_control_enable_write)(if en {1} else {0}) (csr::JDCG[dacno as usize].jesd_control_enable_write)(if en {1} else {0})
}
clock::spin_us(5000);
}
fn jesd_ready(dacno: u8) -> bool {
unsafe {
(csr::JDCG[dacno as usize].jesd_control_ready_read)() != 0
}
}
fn jesd_prbs(dacno: u8, en: bool) {
unsafe {
(csr::JDCG[dacno as usize].jesd_control_prbs_config_write)(if en {0b01} else {0b00})
}
clock::spin_us(5000);
}
fn jesd_stpl(dacno: u8, en: bool) {
unsafe {
(csr::JDCG[dacno as usize].jesd_control_stpl_enable_write)(if en {1} else {0})
}
clock::spin_us(5000);
}
fn jesd_jsync(dacno: u8) -> bool {
unsafe {
(csr::JDCG[dacno as usize].jesd_control_jsync_read)() != 0
}
}
fn jdac_basic_request(dacno: u8, reqno: u8) {
if let Err(e) = drtioaux::send(1, &drtioaux::Packet::JdacBasicRequest {
destination: 0,
dacno: dacno,
reqno: reqno
}) {
error!("aux packet error ({})", e);
}
match drtioaux::recv_timeout(1, Some(1000)) {
Ok(drtioaux::Packet::JdacBasicReply { succeeded }) =>
if !succeeded {
error!("JESD DAC basic request failed (dacno={}, reqno={})", dacno, reqno);
},
Ok(packet) => error!("received unexpected aux packet: {:?}", packet),
Err(e) => error!("aux packet error ({})", e),
}
}
pub fn init() {
for dacno in 0..csr::JDCG.len() {
let dacno = dacno as u8;
info!("DAC-{} initializing...", dacno);
jesd_enable(dacno, true);
jesd_prbs(dacno, false);
jesd_stpl(dacno, false);
jdac_basic_request(dacno, jdac_requests::INIT);
jesd_prbs(dacno, true);
jdac_basic_request(dacno, jdac_requests::PRBS);
jesd_prbs(dacno, false);
jesd_stpl(dacno, true);
jdac_basic_request(dacno, jdac_requests::STPL);
jesd_stpl(dacno, false);
jdac_basic_request(dacno, jdac_requests::INIT);
let t = clock::get_ms();
while !jesd_ready(dacno) {
if clock::get_ms() > t + 200 {
error!("JESD ready timeout");
break;
}
} }
clock::spin_us(5000); clock::spin_us(5000);
jdac_basic_request(dacno, jdac_requests::PRINT_STATUS); }
if !jesd_jsync(dacno) { pub fn ready(dacno: u8) -> bool {
error!("bad SYNC"); unsafe {
(csr::JDCG[dacno as usize].jesd_control_ready_read)() != 0
} }
}
info!(" ...done"); pub fn prbs(dacno: u8, en: bool) {
unsafe {
(csr::JDCG[dacno as usize].jesd_control_prbs_config_write)(if en {0b01} else {0b00})
}
clock::spin_us(5000);
}
pub fn stpl(dacno: u8, en: bool) {
unsafe {
(csr::JDCG[dacno as usize].jesd_control_stpl_enable_write)(if en {1} else {0})
}
clock::spin_us(5000);
}
pub fn jsync(dacno: u8) -> bool {
unsafe {
(csr::JDCG[dacno as usize].jesd_control_jsync_read)() != 0
}
}
}
pub mod jdac {
use board_misoc::{csr, clock};
use board_artiq::drtioaux;
use super::jesd;
use super::super::jdac_requests;
pub fn basic_request(dacno: u8, reqno: u8) {
if let Err(e) = drtioaux::send(1, &drtioaux::Packet::JdacBasicRequest {
destination: 0,
dacno: dacno,
reqno: reqno
}) {
error!("aux packet error ({})", e);
}
match drtioaux::recv_timeout(1, Some(1000)) {
Ok(drtioaux::Packet::JdacBasicReply { succeeded }) =>
if !succeeded {
error!("JESD DAC basic request failed (dacno={}, reqno={})", dacno, reqno);
},
Ok(packet) => error!("received unexpected aux packet: {:?}", packet),
Err(e) => error!("aux packet error ({})", e),
}
}
pub fn init() {
for dacno in 0..csr::JDCG.len() {
let dacno = dacno as u8;
info!("DAC-{} initializing...", dacno);
jesd::enable(dacno, true);
clock::spin_us(10);
if !jesd::ready(dacno) {
error!("JESD core reported not ready");
}
basic_request(dacno, jdac_requests::INIT);
jesd::prbs(dacno, true);
basic_request(dacno, jdac_requests::PRBS);
jesd::prbs(dacno, false);
jesd::stpl(dacno, true);
basic_request(dacno, jdac_requests::STPL);
jesd::stpl(dacno, false);
basic_request(dacno, jdac_requests::INIT);
clock::spin_us(5000);
basic_request(dacno, jdac_requests::PRINT_STATUS);
if !jesd::jsync(dacno) {
error!("JESD core reported bad SYNC");
}
info!(" ...done");
}
}
}
pub mod jesd204sync {
fn sysref_auto_rtio_align() -> Result<(), &'static str> {
info!("TODO: sysref_auto_rtio_align");
Ok(())
}
fn sysref_auto_dac_align() -> Result<(), &'static str> {
info!("TODO: sysref_auto_dac_align");
Ok(())
}
pub fn sysref_auto_align() {
if let Err(e) = sysref_auto_rtio_align() {
error!("failed to align SYSREF at FPGA: {}", e);
}
if let Err(e) = sysref_auto_dac_align() {
error!("failed to align SYSREF at DAC: {}", e);
}
} }
} }

View File

@ -498,9 +498,9 @@ pub extern fn main() -> i32 {
* To handle those cases, we simply keep the JESD204 core in reset unless the * To handle those cases, we simply keep the JESD204 core in reset unless the
* Si5324 is locked to the recovered clock. * Si5324 is locked to the recovered clock.
*/ */
jdcg::jesd_reset(false); jdcg::jesd::reset(false);
if repeaters[0].is_up() { if repeaters[0].is_up() {
jdcg::init(); jdcg::jdac::init();
} }
} }
@ -516,26 +516,15 @@ pub extern fn main() -> i32 {
for mut rep in repeaters.iter_mut() { for mut rep in repeaters.iter_mut() {
rep.service(&routing_table, rank); rep.service(&routing_table, rank);
} }
#[cfg(has_jdcg)]
{
let rep0_is_up = repeaters[0].is_up();
if rep0_is_up && !rep0_was_up {
jdcg::init();
}
rep0_was_up = rep0_is_up;
}
hardware_tick(&mut hardware_tick_ts); hardware_tick(&mut hardware_tick_ts);
if drtiosat_tsc_loaded() { if drtiosat_tsc_loaded() {
info!("TSC loaded from uplink"); info!("TSC loaded from uplink");
/* TODO: #[cfg(has_jdcg)] #[cfg(has_jdcg)]
{ {
if let Err(e) = board_artiq::jesd204sync::sysref_auto_rtio_align() { if rep0_was_up {
error!("failed to align SYSREF at FPGA: {}", e); jdcg::jesd204sync::sysref_auto_align();
} }
if let Err(e) = board_artiq::jesd204sync::sysref_auto_dac_align() { }
error!("failed to align SYSREF at DAC: {}", e);
}
} */
for rep in repeaters.iter() { for rep in repeaters.iter() {
if let Err(e) = rep.sync_tsc() { if let Err(e) = rep.sync_tsc() {
error!("failed to sync TSC ({})", e); error!("failed to sync TSC ({})", e);
@ -545,10 +534,19 @@ pub extern fn main() -> i32 {
error!("aux packet error: {}", e); error!("aux packet error: {}", e);
} }
} }
#[cfg(has_jdcg)]
{
let rep0_is_up = repeaters[0].is_up();
if rep0_is_up && !rep0_was_up {
jdcg::jdac::init();
jdcg::jesd204sync::sysref_auto_align();
}
rep0_was_up = rep0_is_up;
}
} }
#[cfg(has_jdcg)] #[cfg(has_jdcg)]
jdcg::jesd_reset(true); jdcg::jesd::reset(true);
drtiosat_reset_phy(true); drtiosat_reset_phy(true);
drtiosat_reset(true); drtiosat_reset(true);

View File

@ -58,6 +58,7 @@ class SatelliteBase(BaseSoC):
l2_size=128*1024, l2_size=128*1024,
**kwargs) **kwargs)
add_identifier(self, suffix=identifier_suffix) add_identifier(self, suffix=identifier_suffix)
self.rtio_clk_freq = rtio_clk_freq
platform = self.platform platform = self.platform
@ -279,11 +280,17 @@ class Satellite(SatelliteBase):
self.add_rtio(rtio_channels) self.add_rtio(rtio_channels)
self.submodules.sysref_sampler = jesd204_tools.SysrefSampler( self.submodules.sysref_sampler = jesd204_tools.SysrefSampler(
platform.request("dac_sysref"), self.rtio_tsc.coarse_ts) platform.request("amc_fpga_sysref", 0), self.rtio_tsc.coarse_ts)
self.csr_devices.append("sysref_sampler") self.csr_devices.append("sysref_sampler")
self.jdcg_0.jesd.core.register_jref(self.sysref_sampler.jref) self.jdcg_0.jesd.core.register_jref(self.sysref_sampler.jref)
self.jdcg_1.jesd.core.register_jref(self.sysref_sampler.jref) self.jdcg_1.jesd.core.register_jref(self.sysref_sampler.jref)
# DDMTD
# https://github.com/sinara-hw/Sayma_RTM/issues/68
sysref_pads = platform.request("amc_fpga_sysref", 1)
self.submodules.sysref_ddmtd = jesd204_tools.DDMTD(sysref_pads, self.rtio_clk_freq)
self.csr_devices.append("sysref_ddmtd")
class SimpleSatellite(SatelliteBase): class SimpleSatellite(SatelliteBase):
def __init__(self, **kwargs): def __init__(self, **kwargs):

View File

@ -21,7 +21,6 @@ from artiq.gateware.drtio.transceiver import gtp_7series
from artiq.gateware.drtio.siphaser import SiPhaser7Series from artiq.gateware.drtio.siphaser import SiPhaser7Series
from artiq.gateware.drtio.rx_synchronizer import XilinxRXSynchronizer from artiq.gateware.drtio.rx_synchronizer import XilinxRXSynchronizer
from artiq.gateware.drtio import * from artiq.gateware.drtio import *
from artiq.gateware import jesd204_tools
from artiq.build_soc import add_identifier from artiq.build_soc import add_identifier
from artiq import __artiq_dir__ as artiq_dir from artiq import __artiq_dir__ as artiq_dir
@ -216,12 +215,6 @@ class Satellite(_SatelliteBase):
platform.request("hmc7043_out_en")) platform.request("hmc7043_out_en"))
self.csr_devices.append("hmc7043_out_en") self.csr_devices.append("hmc7043_out_en")
# DDMTD
# https://github.com/sinara-hw/Sayma_RTM/issues/68
sysref_pads = platform.request("rtm_fpga_sysref", 1) # use odd-numbered 7043 output
self.submodules.sysref_ddmtd = jesd204_tools.DDMTD(sysref_pads, self.rtio_clk_freq)
self.csr_devices.append("sysref_ddmtd")
class SatmanSoCBuilder(Builder): class SatmanSoCBuilder(Builder):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):