Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: azonenberg/openfpga
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: da2ef5f40f15
Choose a base ref
...
head repository: azonenberg/openfpga
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 962be9377e80
Choose a head ref
  • 2 commits
  • 5 files changed
  • 1 contributor

Commits on Oct 24, 2016

  1. Copy the full SHA
    22a6c28 View commit details
  2. greenpak4: Initial implementation of SLG46140V can now build a "hello…

    … world" bitstream. Fixes #50.
    azonenberg committed Oct 24, 2016
    Copy the full SHA
    962be93 View commit details
Showing with 246 additions and 46 deletions.
  1. +1 −1 src/gpdevboard/protocol.cpp
  2. +66 −32 src/gpdevboard/utils.cpp
  3. +28 −12 src/greenpak4/Greenpak4NetlistCell.cpp
  4. +9 −1 tests/greenpak4/CMakeLists.txt
  5. +142 −0 tests/greenpak4/HIL_SocketTestLoopback_SLG46140.cpp
2 changes: 1 addition & 1 deletion src/gpdevboard/protocol.cpp
Original file line number Diff line number Diff line change
@@ -468,7 +468,7 @@ bool SelectADCChannel(hdevice hdev, unsigned int chan)
else if(chan >= 12 && chan <= 20)
frame.push_back(chan - 2);
else
LogFatal("Unexpected ADC channel\n");
LogFatal("Unexpected ADC channel (%d)\n", chan);
frame.push_back(0x00);
return frame.Send(hdev);
}
98 changes: 66 additions & 32 deletions src/gpdevboard/utils.cpp
Original file line number Diff line number Diff line change
@@ -329,6 +329,11 @@ bool SocketTest(hdevice hdev, SilegoPart part)
"0000000000000000000000000000000200800020000004000000000200000000");
break;

case SLG46140V:
LogWarning("FIXME: not doing anything in SocketTest\n");
return true;
break;

default: LogFatal("Unknown part\n");
}

@@ -425,6 +430,10 @@ bool TrimOscillator(hdevice hdev, SilegoPart part, double voltage, unsigned freq
trimBitstream[1650/8] |= 1 << (1650%8);
break;

case SLG46140V:
LogWarning("FIXME: not doing anything in SocketTest\n");
return true;

default: LogFatal("Unknown part\n");
}

@@ -567,44 +576,69 @@ bool TweakBitstream(vector<uint8_t>& bitstream, SilegoPart part, uint8_t oscTrim
LogNotice("Applying requested configuration to bitstream\n");
LogIndenter li;

//TODO: implement for other parts
switch(part)
if( (part == SLG46621V) || (part == SLG46620V) || (part == SLG4662XV) )
{
case SLG46620V:
case SLG46621V:
case SLG4662XV:
break;

default:
LogError("TweakBitstream only implemented for SLG4662XV\n");
return false;
//Set trim value reg<1981:1975>
bitstream[246] &= 0xFE;
bitstream[247] &= 0x01;
bitstream[246] |= oscTrim << 7;
bitstream[247] |= oscTrim >> 1;
LogVerbose("Oscillator trim value: %d\n", oscTrim);

//Set pattern ID reg<2031:2038>
if(patternID != 0)
{
bitstream[253] &= 0xFE;
bitstream[254] &= 0x01;
}
bitstream[253] |= patternID << 7;
bitstream[254] |= patternID >> 1;
LogNotice("Bitstream ID code: 0x%02x\n", patternID);

//Set read protection reg<2039>
//OR with the existing value: we can set the read protect bit here, but not overwrite the bit if
//it was set by gp4par. If you REALLY need to unprotect a bitstream, do it by hand in a text editor.
bitstream[254] |= ((uint8_t)readProtect) << 7;
if(bitstream[254] & 0x80)
LogNotice("Read protection: enabled\n");
else
LogNotice("Read protection: disabled\n");
}

//Set trim value reg<1981:1975>
bitstream[246] &= 0xFE;
bitstream[247] &= 0x01;
bitstream[246] |= oscTrim << 7;
bitstream[247] |= oscTrim >> 1;
LogVerbose("Oscillator trim value: %d\n", oscTrim);

//Set pattern ID reg<2031:2038>
if(patternID != 0)
else if(part == SLG46140V)
{
bitstream[253] &= 0xFE;
bitstream[254] &= 0x01;
LogWarning("Oscillator trim value: NOT IMPLEMENTED\n");

//Set pattern ID reg<1014:1007>
if(patternID != 0)
{
bitstream[125] &= 0xFE;
bitstream[126] &= 0x01;
}
bitstream[125] |= patternID << 7;
bitstream[126] |= patternID >> 1;
LogNotice("Bitstream ID code: 0x%02x\n", patternID);

//Set read protection... 1015 probably, but not sure?
LogWarning("Read protection: NOT IMPLEMENTED\n");

/*
//Set read protection reg<2039>
//OR with the existing value: we can set the read protect bit here, but not overwrite the bit if
//it was set by gp4par. If you REALLY need to unprotect a bitstream, do it by hand in a text editor.
bitstream[254] |= ((uint8_t)readProtect) << 7;
if(bitstream[254] & 0x80)
LogNotice("Read protection: enabled\n");
else
LogNotice("Read protection: disabled\n");
*/
}
bitstream[253] |= patternID << 7;
bitstream[254] |= patternID >> 1;
LogNotice("Bitstream ID code: 0x%02x\n", patternID);

//Set read protection reg<2039>
//OR with the existing value: we can set the read protect bit here, but not overwrite the bit if
//it was set by gp4par. If you REALLY need to unprotect a bitstream, do it by hand in a text editor.
bitstream[254] |= ((uint8_t)readProtect) << 7;
if(bitstream[254] & 0x80)
LogNotice("Read protection: enabled\n");

else
LogNotice("Read protection: disabled\n");
{
LogError("TweakBitstream: unrecognized part\n");
return false;
}

return true;
}
40 changes: 28 additions & 12 deletions src/greenpak4/Greenpak4NetlistCell.cpp
Original file line number Diff line number Diff line change
@@ -60,22 +60,38 @@ string Greenpak4NetlistCell::GetLOC()
string sindex = nodename.substr(pos + 1); //skip the [ character
int index = atoi(sindex.c_str());

//Find our LOC
pos = 0;
for(int i=0; i<index; i++)
//Split the vector of LOCs into individual locations
LogDebug("Get LOC for %s index %d\n", loc.c_str(), index);
vector<string> locs;
string tmp;
for(size_t i=0; i<loc.length(); i++)
{
pos = loc.find(" ", pos);
if(pos == string::npos)
return "<invalid LOC>";
if(loc[i] == ' ')
{
if(tmp != "")
locs.push_back(tmp);
tmp = "";
}

pos++; //skip the space
else
tmp += loc[i];
}
size_t nextpos = loc.find(" ", pos);
if(nextpos == string::npos)
nextpos = loc.length();
nextpos -= pos;
if(tmp != "")
locs.push_back(tmp);

return loc.substr(pos, nextpos);
//Count from the RIGHT
if(index >= (int)locs.size() )
{
LogError(
"LOC constraint \"%s\" on cell %s is invalid.\n"
"Cannot constrain vector element[%d] because there are only %d elements in the constraint list\n",
loc.c_str(), m_name.c_str(), index, (int)locs.size());
return "<invalid>";
}
string ret = locs[locs.size() - 1 - index];
LogDebug(" %s\n", ret.c_str());

return ret;
}

//Single bit signal, just return the attribute
10 changes: 9 additions & 1 deletion tests/greenpak4/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -12,6 +12,10 @@ function(add_greenpak4_netlist name part)
COMMENT "Synthesizing Verilog file ${CMAKE_CURRENT_SOURCE_DIR}/${name}"
VERBATIM)

add_custom_target(netlist-gp4-${name}
ALL
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${name}.json")

endfunction()

########################################################################################################################
@@ -88,6 +92,10 @@ add_greenpak4_bitstream(SocketTestLoopback_STQFN14 SLG46140V)

add_executable(HIL_PGA
HIL_PGA.cpp)

target_link_libraries(HIL_PGA
gpdevboard)

add_executable(HIL_SocketTestLoopback_SLG46140
HIL_SocketTestLoopback_SLG46140.cpp)
target_link_libraries(HIL_SocketTestLoopback_SLG46140
gpdevboard)
142 changes: 142 additions & 0 deletions tests/greenpak4/HIL_SocketTestLoopback_SLG46140.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
/***********************************************************************************************************************
* Copyright (C) 2016 Andrew Zonenberg and contributors *
* *
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General *
* Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for *
* more details. *
* *
* You should have received a copy of the GNU Lesser General Public License along with this program; if not, you may *
* find one here: *
* https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt *
* or you may search the http://www.gnu.org website for the version 2.1 license, or you may write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA *
**********************************************************************************************************************/

#include <log.h>
#include <gpdevboard.h>
#include <math.h>

using namespace std;

bool RunTest(hdevice hdev);

int main(int argc, char* argv[])
{
g_log_sinks.emplace(g_log_sinks.begin(), new STDLogSink(Severity::VERBOSE));

//expect one arg: the bitstream
if(argc != 2)
{
LogNotice("Usage: [testcase] bitstream.txt\n");
return 1;
}

//Do standard board bringup
hdevice hdev = OpenBoard();
if(!hdev)
{
LogError("Failed to open board\n");
return 1;
}
if(!SetStatusLED(hdev, 1))
return 1;

//Prepare to run the test
if(!TestSetup(hdev, argv[1], 25000, 1.8, SilegoPart::SLG46140V))
{
SetStatusLED(hdev, 0);
Reset(hdev);
return 1;
}

//Run the actual test case
LogNotice("\n");
LogNotice("Running application test case\n");
if(!RunTest(hdev))
{
SetStatusLED(hdev, 0);
Reset(hdev);
return 1;
}

//Turn off the LED before declaring success
LogVerbose("\n");
LogVerbose("Test complete, resetting board\n");
SetStatusLED(hdev, 0);
Reset(hdev);
USBCleanup(hdev);
return 0;
}

/**
@brief The actual application-layer test
*/
bool RunTest(hdevice hdev)
{
LogIndenter li;

//Wipe all I/O config
IOConfig ioConfig;
for(size_t i = 2; i <= 20; i++)
ioConfig.driverConfigs[i] = TP_RESET;
if(!SetIOConfig(hdev, ioConfig))
return false;

//Drive signals to pin 2
const int WRITE_PIN = 2;

//Read signals from everything else
//Need to translate between pin and socket numbers... TODO move this to gpdevboard?
const int board_pins[11] = {3, 4, 5, 6, 7, 12, 13, 14, 15, 16, 17};
const int chip_pins[11] = {3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14};

//Digital 0 and 1
tuple<TPConfig, TPConfig, bool> sequence[] =
{
make_tuple(TP_GND, TP_FLIMSY_PULLUP, false),
make_tuple(TP_VDD, TP_FLIMSY_PULLDOWN, true)
};

//Send a few cycles of each value
for(auto config : sequence)
{
//Write the test bit
bool bval = get<2>(config);
LogNotice("Setting pin %d to %d\n", WRITE_PIN, bval);
LogIndenter li;

//Set up the I/O configuration
ioConfig.driverConfigs[2] = get<0>(config);
for(size_t i = 3; i <= 20; i++)
ioConfig.driverConfigs[i] = get<1>(config);
if(!SetIOConfig(hdev, ioConfig))
return false;

//Read every output pin
float vexpected = bval ? 1.0 : 0;
for(int j=0; j<11; j++)
{
if(!SelectADCChannel(hdev, board_pins[j]))
return false;
double vin;
if(!ReadADC(hdev, vin))
return false;

LogNotice("Read chip pin %2d (board pin %2d): %.3f V\n", chip_pins[j], board_pins[j], vin);

//Allow 50 mV noise tolerance
float delta = fabs(vexpected - vin);
if(delta > 0.05)
{
LogError("Out of tolerance (delta = %.3f V)\n", delta);
return false;
}
}
}

return true;
}