Skip to content

Commit 9be991e

Browse files
committedJun 4, 2017
Now measuring LUT delays
1 parent c014b81 commit 9be991e

File tree

6 files changed

+158
-14
lines changed

6 files changed

+158
-14
lines changed
 

Diff for: ‎src/gp4tchar/gp4tchar.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ bool ReadTraceDelays();
3939
bool CalibrateTraceDelays(Socket& sock, hdevice hdev);
4040
bool MeasureDelay(Socket& sock, int src, int dst, float& delay);
4141

42-
bool MeasureLutDelays(Socket& sock, hdevice hdev);
42+
bool MeasureLUTDelays(Socket& sock, hdevice hdev);
4343
bool MeasurePinToPinDelays(Socket& sock, hdevice hdev);
4444
bool MeasureCrossConnectionDelays(Socket& sock, hdevice hdev);
4545

Diff for: ‎src/gp4tchar/main.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,8 @@ int main(int argc, char* argv[])
133133
// return 1;
134134
//if(!MeasureCrossConnectionDelays(sock, hdev))
135135
// return 1;
136-
//if(!MeasureLutDelays(sock, hdev))
137-
// return 1;
136+
if(!MeasureLUTDelays(sock, hdev))
137+
return 1;
138138

139139
//Save to disk
140140

Diff for: ‎src/gp4tchar/measurements.cpp

+152-8
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@ bool MeasurePinToPinDelay(
5656
int voltage_mv,
5757
float& delay);
5858

59+
bool MeasureLUTDelay(
60+
Socket& sock,
61+
hdevice hdev,
62+
int nlut,
63+
int ninput,
64+
PTVCorner corner,
65+
float& delay);
66+
5967
bool ProgramAndMeasureDelay(
6068
Socket& sock,
6169
hdevice hdev,
@@ -65,6 +73,13 @@ bool ProgramAndMeasureDelay(
6573
int voltage_mv,
6674
float& delay);
6775

76+
float GetRoundTripDelayWith2x(
77+
int src,
78+
int dst,
79+
PTVCorner corner);
80+
81+
Greenpak4LUT* GetRealLUT(Greenpak4BitstreamEntity* lut);
82+
6883
//Voltages to test at
6984
//For now, 3.3 +/- 150 mV
7085
const int g_testVoltages[] = {3150, 3300, 3450};
@@ -503,36 +518,165 @@ bool MeasureCrossConnectionDelay(
503518
if(!ProgramAndMeasureDelay(sock, hdev, bitstream, src, dst, corner.GetVoltage(), delay))
504519
return false;
505520

521+
//Subtract PCB and I/O buffer delays
522+
delay -= GetRoundTripDelayWith2x(src, dst, corner);
523+
524+
return true;
525+
}
526+
527+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
528+
// Helper for subtracting I/O pad and test fixture delays from a measurement
529+
530+
float GetRoundTripDelayWith2x(
531+
int src,
532+
int dst,
533+
PTVCorner corner)
534+
{
506535
//Subtract the PCB trace delay at each end of the line
507-
delay -= g_devkitCal.pinDelays[src].m_rising;
508-
delay -= g_devkitCal.pinDelays[dst].m_rising;
536+
float delay = g_devkitCal.pinDelays[src].m_rising;
537+
delay += g_devkitCal.pinDelays[dst].m_rising;
509538

510539
//Subtract the I/O buffer delay at each end of the line
511540
//TODO: import calibration from the Greenpak4Device and/or reset it?
512541
CombinatorialDelay d;
513-
srciob = g_calDevice.GetIOB(src);
542+
auto srciob = g_calDevice.GetIOB(src);
514543
srciob->SetSchmittTrigger(false);
515544
if(!srciob->GetCombinatorialDelay("IO", "OUT", corner, d))
516545
return false;
517-
delay -= d.m_rising;
546+
delay += d.m_rising;
518547

519-
dstiob = g_calDevice.GetIOB(dst);
548+
auto dstiob = g_calDevice.GetIOB(dst);
520549
dstiob->SetDriveType(Greenpak4IOB::DRIVE_PUSHPULL);
521550
dstiob->SetDriveStrength(Greenpak4IOB::DRIVE_2X);
522551
if(!dstiob->GetCombinatorialDelay("IN", "IO", corner, d))
523552
return false;
524-
delay -= d.m_rising;
553+
delay += d.m_rising;
525554

526-
return true;
555+
return delay;
527556
}
528557

529558
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
530559
// Characterize LUTs
531560

532-
bool MeasureLutDelays(Socket& /*sock*/, hdevice /*hdev*/)
561+
/**
562+
@brief Gets the actual LUT object out of an entity that either is, or contains, a LUT
563+
*/
564+
Greenpak4LUT* GetRealLUT(Greenpak4BitstreamEntity* lut)
565+
{
566+
//First, just try casting.
567+
auto reallut = dynamic_cast<Greenpak4LUT*>(lut);
568+
if(reallut)
569+
return reallut;
570+
571+
//It would be too easy if that just worked, though... what if it's a muxed cell?
572+
auto pair = dynamic_cast<Greenpak4PairedEntity*>(lut);
573+
if(pair)
574+
{
575+
reallut = dynamic_cast<Greenpak4LUT*>(pair->GetEntity("GP_2LUT"));
576+
if(reallut)
577+
return reallut;
578+
}
579+
580+
//Something is wrong
581+
return NULL;
582+
}
583+
584+
bool MeasureLUTDelays(Socket& sock, hdevice hdev)
533585
{
534586
LogNotice("Measuring LUT delays...\n");
535587
LogIndenter li;
588+
589+
//Test conditions (TODO: pass this in from somewhere?)
590+
int voltage = 3300;
591+
PTVCorner corner(PTVCorner::SPEED_TYPICAL, 25, voltage);
592+
593+
//Characterize each LUT
594+
//Don't forget to only measure pins it actually has!
595+
float delay;
596+
for(unsigned int nlut = 0; nlut < g_calDevice.GetLUTCount(); nlut++)
597+
{
598+
auto baselut = g_calDevice.GetLUT(nlut);
599+
auto lut = GetRealLUT(baselut);
600+
for(unsigned int npin = 0; npin < lut->GetOrder(); npin ++)
601+
{
602+
if(!MeasureLUTDelay(sock, hdev, nlut, npin, corner, delay))
603+
return false;
604+
605+
//For now, the parent (in case of a muxed lut etc) stores all timing data
606+
//TODO: does this make the most sense?
607+
char portname[] = "IN0";
608+
portname[2] += npin;
609+
baselut->AddCombinatorialDelay(portname, "OUT", corner, CombinatorialDelay(delay, -1));
610+
}
611+
}
612+
536613
return true;
537614
}
538615

616+
bool MeasureLUTDelay(
617+
Socket& sock,
618+
hdevice hdev,
619+
int nlut,
620+
int ninput,
621+
PTVCorner corner,
622+
float& delay)
623+
{
624+
delay = -1;
625+
626+
//Create the device object
627+
Greenpak4Device device(part, unused_pull, unused_drive);
628+
device.SetIOPrecharge(false);
629+
device.SetDisableChargePump(false);
630+
device.SetLDOBypass(false);
631+
device.SetNVMRetryCount(1);
632+
633+
//Look up the LUT
634+
auto lut = GetRealLUT(device.GetLUT(nlut));
635+
636+
//See which half of the device it's in. Use pins 3/4 or 13/14 as appropriate
637+
int src = 3;
638+
int dst = 4;
639+
if(lut->GetMatrix() == 1)
640+
{
641+
src = 13;
642+
dst = 14;
643+
}
644+
645+
//Configure the input pin
646+
auto vss = device.GetGround();
647+
auto srciob = device.GetIOB(src);
648+
srciob->SetInput("OE", vss);
649+
auto din = srciob->GetOutput("OUT");
650+
651+
//Configure the LUT
652+
lut->MakeXOR();
653+
lut->SetInput("IN0", vss);
654+
lut->SetInput("IN1", vss);
655+
lut->SetInput("IN2", vss);
656+
lut->SetInput("IN3", vss);
657+
char portname[] = "IN0";
658+
portname[2] += ninput;
659+
lut->SetInput(portname, din);
660+
661+
//Configure the output pin
662+
auto vdd = device.GetPower();
663+
auto dstiob = device.GetIOB(dst);
664+
dstiob->SetInput("IN", lut->GetOutput("OUT"));
665+
dstiob->SetInput("OE", vdd);
666+
dstiob->SetDriveType(Greenpak4IOB::DRIVE_PUSHPULL);
667+
dstiob->SetDriveStrength(Greenpak4IOB::DRIVE_2X);
668+
669+
//Generate a bitstream
670+
vector<uint8_t> bitstream;
671+
device.WriteToBuffer(bitstream, 0, false);
672+
//device.WriteToFile("/tmp/test.txt", 0, false); //for debug in case of failure
673+
674+
//Get the delay
675+
if(!ProgramAndMeasureDelay(sock, hdev, bitstream, src, dst, corner.GetVoltage(), delay))
676+
return false;
677+
678+
//Subtract PCB trace and IO buffer delays
679+
delay -= GetRoundTripDelayWith2x(src, dst, corner);
680+
681+
return true;
682+
}

Diff for: ‎src/greenpak4/Greenpak4Device.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/***********************************************************************************************************************
2-
* Copyright (C) 2017 Andrew Zonenberg and contributors *
2+
* Copyright (C) 2016-2017 Andrew Zonenberg and contributors *
33
* *
44
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General *
55
* Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) *

Diff for: ‎src/greenpak4/Greenpak4Device.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/***********************************************************************************************************************
2-
* Copyright (C) 2016 Andrew Zonenberg and contributors *
2+
* Copyright (C) 2016-2017 Andrew Zonenberg and contributors *
33
* *
44
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General *
55
* Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) *

Diff for: ‎src/greenpak4/Greenpak4PairedEntity.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#define Greenpak4PairedEntity_h
2121

2222
/**
23-
@brief The bandgap voltage reference
23+
@brief A pair of entities muxed into one site
2424
*/
2525
class Greenpak4PairedEntity : public Greenpak4BitstreamEntity
2626
{

0 commit comments

Comments
 (0)
Please sign in to comment.