Skip to content

Commit

Permalink
Implemented bitstream loading for IOB type A, ACMP, VREF
Browse files Browse the repository at this point in the history
azonenberg committed Aug 7, 2017
1 parent 59c095e commit a9a4c13
Showing 4 changed files with 142 additions and 10 deletions.
49 changes: 45 additions & 4 deletions src/greenpak4/Greenpak4Comparator.cpp
Original file line number Diff line number Diff line change
@@ -141,11 +141,52 @@ bool Greenpak4Comparator::CommitChanges()
return true;
}

bool Greenpak4Comparator::Load(bool* /*bitstream*/)
bool Greenpak4Comparator::Load(bool* bitstream)
{
//TODO: Do our inputs
LogError("Unimplemented\n");
return false;
ReadMatrixSelector(bitstream, m_inputBaseWord, m_matrix, m_pwren);

//Optional features (not all devices have these)
if(m_cbaseIsrc > 0)
m_isrcEn = bitstream[m_cbaseIsrc];
if(m_cbaseBw > 0)
m_bandwidthHigh = !bitstream[m_cbaseBw];

//Gain selectors
if(m_cbaseGain > 0)
{
int gain = (bitstream[m_cbaseGain + 1] << 1) | bitstream[m_cbaseGain];
m_vinAtten = gain + 1;
}

//Hysteresis
if(m_cbaseHyst > 0)
{
int hyst = (bitstream[m_cbaseHyst + 1] << 1) | bitstream[m_cbaseHyst];
int hysts[4] = {0, 25, 50, 200};
m_hysteresis = hysts[hyst];
}

//Mux selector.
//Load second bit if we have one
unsigned int sel = bitstream[m_cbaseVin];
if(m_muxsels.size() > 2)
sel |= (bitstream[m_cbaseVin + 1] << 1);
for(auto it : m_muxsels)
{
if(it.second == sel)
m_vin = it.first;
}

//Find our reference. It's always the corresponding VREF for our number
m_vref = m_device->GetVref(m_cmpNum);

//Read the voltage reference
int muxsel = 0;
for(int i=0; i<5; i++)
muxsel |= (bitstream[m_cbaseVref + i] << i);
dynamic_cast<Greenpak4VoltageReference*>(m_vref.GetRealEntity())->SetMuxSel(muxsel);

return true;
}

bool Greenpak4Comparator::Save(bool* bitstream)
97 changes: 93 additions & 4 deletions src/greenpak4/Greenpak4IOBTypeA.cpp
Original file line number Diff line number Diff line change
@@ -55,11 +55,100 @@ string Greenpak4IOBTypeA::GetDescription() const
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Serialization

bool Greenpak4IOBTypeA::Load(bool* /*bitstream*/)
bool Greenpak4IOBTypeA::Load(bool* bitstream)
{
//TODO
LogError("Unimplemented\n");
return false;
//If we have no output pad driver, skip the driver inputs
if(m_flags & IOB_FLAG_INPUTONLY)
{
m_outputEnable = m_device->GetGround();
m_outputSignal = m_device->GetGround();
}

//We have an output driver, read the signals feeding it
else
{
ReadMatrixSelector(bitstream, m_inputBaseWord + 0, m_matrix, m_outputSignal);
ReadMatrixSelector(bitstream, m_inputBaseWord + 1, m_matrix, m_outputEnable);
}

int thresh = (bitstream[m_configBase + 1] << 1) | bitstream[m_configBase + 0];
switch(thresh)
{
case 3:
m_inputThreshold = THRESHOLD_ANALOG;
m_schmittTrigger = false;
break;

case 2:
m_inputThreshold = THRESHOLD_LOW;
m_schmittTrigger = false;
break;

case 1:
m_inputThreshold = THRESHOLD_NORMAL;
m_schmittTrigger = true;
break;

case 0:
m_inputThreshold = THRESHOLD_NORMAL;
m_schmittTrigger = false;
break;
}

//Base address for upcoming stuff, skipping output driver if not implemented
unsigned int base = m_configBase + 2;

//Load OBUF config if we're not input-only
if(! (m_flags & IOB_FLAG_INPUTONLY) )
{
//If second driver is off, we're x1 for sure
if(!bitstream[m_configBase + 2])
m_driveStrength = DRIVE_1X;

//Second driver is on. Do we have a quad?
else
{
if( (m_flags & IOB_FLAG_X4DRIVE) && bitstream[m_configBase + 7] )
m_driveStrength = DRIVE_4X;

else
m_driveStrength = DRIVE_2X;
}

if(bitstream[m_configBase + 3])
m_driveType = DRIVE_NMOS_OPENDRAIN;
else
m_driveType = DRIVE_PUSHPULL;

base += 2;
}

//Load pull direction (just up or down, float comes in the next block)
if(bitstream[base + 2])
m_pullDirection = PULL_UP;
else
m_pullDirection = PULL_DOWN;

//Load pull value and float flag
int pullVal = (bitstream[base+1] << 1) | bitstream[base];
switch(pullVal)
{
case 0:
m_pullDirection = PULL_NONE;
m_pullStrength = PULL_1M;
break;

case 1:
m_pullStrength = PULL_10K;

case 2:
m_pullStrength = PULL_100K;

case 3:
m_pullStrength = PULL_1M;
}

return true;
}

bool Greenpak4IOBTypeA::Save(bool* bitstream)
3 changes: 1 addition & 2 deletions src/greenpak4/Greenpak4VoltageReference.cpp
Original file line number Diff line number Diff line change
@@ -110,8 +110,7 @@ bool Greenpak4VoltageReference::CommitChanges()

bool Greenpak4VoltageReference::Load(bool* /*bitstream*/)
{
//TODO: how do we do this? Vref is attached to the comparator, so we have to steal config from that...
LogWarning("Greenpak4VoltageReference::Load needs to be figured out\n");
//We're configured in slave mode by the attached ACMP, so nothing to do here
return true;
}

3 changes: 3 additions & 0 deletions src/greenpak4/Greenpak4VoltageReference.h
Original file line number Diff line number Diff line change
@@ -52,6 +52,9 @@ class Greenpak4VoltageReference : public Greenpak4BitstreamEntity
unsigned int GetMuxSel()
{ return m_voutMuxsel; }

void SetMuxSel(unsigned int i)
{ m_voutMuxsel = i; }

//mux selector for ACMP voltage inputs
unsigned int GetACMPMuxSel();

0 comments on commit a9a4c13

Please sign in to comment.