Skip to content

Commit

Permalink
Various optimizations to LUT delay characterization
Browse files Browse the repository at this point in the history
azonenberg committed Jun 5, 2017
1 parent 517fb32 commit 5f47939
Showing 4 changed files with 76 additions and 26 deletions.
8 changes: 4 additions & 4 deletions src/gp4tchar/main.cpp
Original file line number Diff line number Diff line change
@@ -129,10 +129,10 @@ int main(int argc, char* argv[])
return 1;

//Measure delay through each element
//if(!MeasurePinToPinDelays(sock, hdev))
// return 1;
//if(!MeasureCrossConnectionDelays(sock, hdev))
// return 1;
if(!MeasurePinToPinDelays(sock, hdev))
return 1;
if(!MeasureCrossConnectionDelays(sock, hdev))
return 1;
if(!MeasureLUTDelays(sock, hdev))
return 1;

88 changes: 66 additions & 22 deletions src/gp4tchar/measurements.cpp
Original file line number Diff line number Diff line change
@@ -62,7 +62,7 @@ bool MeasureLUTDelay(
int nlut,
int ninput,
PTVCorner corner,
float& delay);
map<PTVCorner, CombinatorialDelay>& delays);

bool ProgramAndMeasureDelay(
Socket& sock,
@@ -73,6 +73,16 @@ bool ProgramAndMeasureDelay(
int voltage_mv,
float& delay);

bool ProgramAndMeasureDelayAcrossVoltageCorners(
Socket& sock,
hdevice hdev,
vector<uint8_t>& bitstream,
int src,
int dst,
PTVCorner corner,
bool subtractPadDelay,
map<PTVCorner, CombinatorialDelay>& delays);

float GetRoundTripDelayWith2x(
int src,
int dst,
@@ -273,6 +283,47 @@ bool ProgramAndMeasureDelay(
return MeasureDelay(sock, src, dst, delay);
}

bool ProgramAndMeasureDelayAcrossVoltageCorners(
Socket& sock,
hdevice hdev,
vector<uint8_t>& bitstream,
int src,
int dst,
PTVCorner corner,
bool subtractPadDelay,
map<PTVCorner, CombinatorialDelay>& delays)
{
//Emulate the device
LogVerbose("Loading new bitstream\n");
if(!DownloadBitstream(hdev, bitstream, DownloadMode::EMULATION))
return false;

for(auto v : g_testVoltages)
{
corner.SetVoltage(v);
if(!PostProgramSetup(hdev, v))
return false;

//wait a bit to let voltages stabilize
usleep (1000 * 50);

float delay;
if(!MeasureDelay(sock, src, dst, delay))
return false;

//Remove off-die delays if requested
if(subtractPadDelay)
{
//Subtract PCB trace and IO buffer delays
delay -= GetRoundTripDelayWith2x(src, dst, corner);
}

delays[corner] = CombinatorialDelay(delay, -1);
}

return true;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Characterize I/O buffers

@@ -588,28 +639,26 @@ bool MeasureLUTDelays(Socket& sock, hdevice hdev)

//Characterize each LUT
//Don't forget to only measure pins it actually has!
float delay;
for(unsigned int nlut = 0; nlut < g_calDevice.GetLUTCount(); nlut++)
{
auto baselut = g_calDevice.GetLUT(nlut);
auto lut = GetRealLUT(baselut);

//Try various voltages
for(auto voltage : g_testVoltages)
for(unsigned int npin = 0; npin < lut->GetOrder(); npin ++)
{
//Test conditions (TODO: pass this in from somewhere?)
PTVCorner corner(PTVCorner::SPEED_TYPICAL, 25, voltage);

for(unsigned int npin = 0; npin < lut->GetOrder(); npin ++)
{
if(!MeasureLUTDelay(sock, hdev, nlut, npin, corner, delay))
return false;
PTVCorner corner(PTVCorner::SPEED_TYPICAL, 25, 3300);

map<PTVCorner, CombinatorialDelay> delays;
if(!MeasureLUTDelay(sock, hdev, nlut, npin, corner, delays))
return false;

//For now, the parent (in case of a muxed lut etc) stores all timing data
//TODO: does this make the most sense?
//For now, the parent (in case of a muxed lut etc) stores all timing data
//TODO: does this make the most sense?
for(auto it : delays)
{
char portname[] = "IN0";
portname[2] += npin;
baselut->AddCombinatorialDelay(portname, "OUT", corner, CombinatorialDelay(delay, -1));
baselut->AddCombinatorialDelay(portname, "OUT", it.first, it.second);
}
}
}
@@ -623,10 +672,8 @@ bool MeasureLUTDelay(
int nlut,
int ninput,
PTVCorner corner,
float& delay)
map<PTVCorner, CombinatorialDelay>& delays)
{
delay = -1;

//Create the device object
Greenpak4Device device(part, unused_pull, unused_drive);
device.SetIOPrecharge(false);
@@ -675,12 +722,9 @@ bool MeasureLUTDelay(
device.WriteToBuffer(bitstream, 0, false);
//device.WriteToFile("/tmp/test.txt", 0, false); //for debug in case of failure

//Get the delay
if(!ProgramAndMeasureDelay(sock, hdev, bitstream, src, dst, corner.GetVoltage(), delay))
//Get the delays
if(!ProgramAndMeasureDelayAcrossVoltageCorners(sock, hdev, bitstream, src, dst, corner, true, delays))
return false;

//Subtract PCB trace and IO buffer delays
delay -= GetRoundTripDelayWith2x(src, dst, corner);

return true;
}
2 changes: 2 additions & 0 deletions src/gp4tchar/setup.cpp
Original file line number Diff line number Diff line change
@@ -25,6 +25,8 @@ using namespace std;

bool PostProgramSetup(hdevice hdev, int voltage_mv)
{
SetStatusLED(hdev, 1);

//Clear I/Os from programming mode
if(!IOReset(hdev))
return false;
4 changes: 4 additions & 0 deletions src/xbpar/PTVCorner.h
Original file line number Diff line number Diff line change
@@ -51,6 +51,10 @@ class PTVCorner
int GetVoltage() const
{ return m_voltage; }

//TODO: verify within legal limits
void SetVoltage(int v)
{ m_voltage = v; }

std::string toString() const;

//Comparison operator for STL collections

0 comments on commit 5f47939

Please sign in to comment.