forked from M-Labs/artiq
sdram: clean up, make read_level robust to wrap around
* fix a few rust warnings * also do eye scans on kintex
This commit is contained in:
parent
3abb378fbe
commit
6fb0cbfcd3
@ -30,18 +30,19 @@ mod ddr {
|
||||
ddrphy::wlevel_en_write(enabled as u8);
|
||||
}
|
||||
|
||||
#[cfg(kusddrphy)]
|
||||
#[cfg(ddrphy_wlevel)]
|
||||
unsafe fn write_level_scan(logger: &mut Option<&mut fmt::Write>) {
|
||||
#[cfg(kusddrphy)]
|
||||
log!(logger, "DQS initial delay: {} taps\n", ddrphy::wdly_dqs_taps_read());
|
||||
log!(logger, "Write leveling scan:\n");
|
||||
|
||||
enable_write_leveling(true);
|
||||
spin_cycles(100);
|
||||
|
||||
let mut ddrphy_max_delay : u16 = DDRPHY_MAX_DELAY;
|
||||
#[cfg(kusddrphy)] {
|
||||
ddrphy_max_delay -= ddrphy::wdly_dqs_taps_read();
|
||||
}
|
||||
#[cfg(not(kusddrphy))]
|
||||
let ddrphy_max_delay : u16 = DDRPHY_MAX_DELAY;
|
||||
#[cfg(kusddrphy)]
|
||||
let ddrphy_max_delay : u16 = DDRPHY_MAX_DELAY - ddrphy::wdly_dqs_taps_read();
|
||||
|
||||
for n in 0..DQS_SIGNAL_COUNT {
|
||||
let dq_addr = dfii::PI0_RDDATA_ADDR
|
||||
@ -91,10 +92,10 @@ mod ddr {
|
||||
enable_write_leveling(true);
|
||||
spin_cycles(100);
|
||||
|
||||
let mut ddrphy_max_delay : u16 = DDRPHY_MAX_DELAY;
|
||||
#[cfg(kusddrphy)] {
|
||||
ddrphy_max_delay -= ddrphy::wdly_dqs_taps_read();
|
||||
}
|
||||
#[cfg(not(kusddrphy))]
|
||||
let ddrphy_max_delay : u16 = DDRPHY_MAX_DELAY;
|
||||
#[cfg(kusddrphy)]
|
||||
let ddrphy_max_delay : u16 = DDRPHY_MAX_DELAY - ddrphy::wdly_dqs_taps_read();
|
||||
|
||||
let mut failed = false;
|
||||
for n in 0..DQS_SIGNAL_COUNT {
|
||||
@ -202,7 +203,6 @@ mod ddr {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(kusddrphy)]
|
||||
unsafe fn read_level_scan(logger: &mut Option<&mut fmt::Write>) {
|
||||
log!(logger, "Read leveling scan:\n");
|
||||
|
||||
@ -280,7 +280,7 @@ mod ddr {
|
||||
spin_cycles(15);
|
||||
}
|
||||
|
||||
unsafe fn read_level(logger: &mut Option<&mut fmt::Write>) {
|
||||
unsafe fn read_level(logger: &mut Option<&mut fmt::Write>) -> bool {
|
||||
log!(logger, "Read leveling: ");
|
||||
|
||||
// Generate pseudo-random sequence
|
||||
@ -316,13 +316,15 @@ mod ddr {
|
||||
for n in 0..DQS_SIGNAL_COUNT {
|
||||
ddrphy::dly_sel_write(1 << (DQS_SIGNAL_COUNT - n - 1));
|
||||
|
||||
// Find the first (which=true) or last (which=false) tap that leads to a
|
||||
// sufficiently high number of correct reads.
|
||||
// Find the first (min_delay) and last (max_delay) tap that bracket
|
||||
// the largest tap interval of correct reads.
|
||||
let mut min_delay = 0;
|
||||
let mut have_min_delay = false;
|
||||
let mut max_delay = 0;
|
||||
let mut have_max_delay = false;
|
||||
let mut have_invalid = 0;
|
||||
|
||||
let mut first_valid = 0;
|
||||
let mut seen_valid = 0;
|
||||
let mut seen_invalid = 0;
|
||||
let mut max_seen_valid = 0;
|
||||
|
||||
ddrphy::rdly_dq_rst_write(1);
|
||||
|
||||
@ -345,22 +347,37 @@ mod ddr {
|
||||
}
|
||||
|
||||
if valid {
|
||||
if !have_min_delay {
|
||||
min_delay = delay;
|
||||
have_min_delay = true;
|
||||
if seen_valid == 0 {
|
||||
first_valid = delay;
|
||||
}
|
||||
if !have_max_delay {
|
||||
seen_valid += 1;
|
||||
seen_invalid = 0;
|
||||
if seen_valid > max_seen_valid {
|
||||
min_delay = first_valid;
|
||||
max_delay = delay;
|
||||
max_seen_valid = seen_valid;
|
||||
}
|
||||
} else if have_min_delay {
|
||||
have_invalid += 1;
|
||||
if have_invalid >= 10 {
|
||||
have_max_delay = true;
|
||||
} else {
|
||||
seen_invalid += 1;
|
||||
if seen_invalid >= DDRPHY_MAX_DELAY / 8 {
|
||||
seen_valid = 0;
|
||||
}
|
||||
}
|
||||
ddrphy::rdly_dq_inc_write(1);
|
||||
}
|
||||
|
||||
if max_delay <= min_delay {
|
||||
log!(logger, "Zero window: {}: {}-{}\n",
|
||||
DQS_SIGNAL_COUNT - n - 1, min_delay, max_delay);
|
||||
return false
|
||||
}
|
||||
if max_seen_valid <= 5 {
|
||||
log!(logger, "Small window: {}: {}-{} ({})\n",
|
||||
DQS_SIGNAL_COUNT - n - 1, min_delay, max_delay,
|
||||
max_seen_valid);
|
||||
return false
|
||||
}
|
||||
|
||||
let mean_delay = (min_delay + max_delay) / 2;
|
||||
log!(logger, "{}: {} ({} wide), ",
|
||||
DQS_SIGNAL_COUNT - n - 1, mean_delay,
|
||||
@ -380,6 +397,7 @@ mod ddr {
|
||||
spin_cycles(15);
|
||||
|
||||
log!(logger, "done\n");
|
||||
true
|
||||
}
|
||||
|
||||
pub unsafe fn level(logger: &mut Option<&mut fmt::Write>) -> bool {
|
||||
@ -387,7 +405,6 @@ mod ddr {
|
||||
{
|
||||
let mut delay = [0; DQS_SIGNAL_COUNT];
|
||||
let mut high_skew = [false; DQS_SIGNAL_COUNT];
|
||||
#[cfg(kusddrphy)]
|
||||
write_level_scan(logger);
|
||||
if !write_level(logger, &mut delay, &mut high_skew) {
|
||||
return false
|
||||
@ -395,9 +412,10 @@ mod ddr {
|
||||
read_bitslip(logger, &delay, &high_skew);
|
||||
}
|
||||
|
||||
#[cfg(kusddrphy)]
|
||||
read_level_scan(logger);
|
||||
read_level(logger);
|
||||
if !read_level(logger) {
|
||||
return false
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user