Skip to content

Commit

Permalink
greenpak4/gp4par: Finished initial implementation of PCF constraints.…
Browse files Browse the repository at this point in the history
… Added basic test case.
azonenberg committed Feb 16, 2017
1 parent fddaeed commit a3df21b
Showing 10 changed files with 93 additions and 17 deletions.
4 changes: 2 additions & 2 deletions src/gp4par/main.cpp
Original file line number Diff line number Diff line change
@@ -221,7 +221,7 @@ int main(int argc, char* argv[])
}

//Set up logging
g_log_sinks.emplace(g_log_sinks.begin(), new STDLogSink(console_verbosity));
g_log_sinks.emplace(g_log_sinks.begin(), new ColoredSTDLogSink(console_verbosity));

//Print header
if(console_verbosity >= Severity::NOTICE)
@@ -307,7 +307,7 @@ int main(int argc, char* argv[])

//Parse the unplaced netlist
LogNotice("\nLoading Yosys JSON file \"%s\".\n", fname.c_str());
Greenpak4Netlist netlist(fname);
Greenpak4Netlist netlist(fname, pcfname);
if(!netlist.Validate())
return 1;

3 changes: 3 additions & 0 deletions src/gp4par/make_graphs.cpp
Original file line number Diff line number Diff line change
@@ -719,6 +719,9 @@ bool MakeNetlistEdges(Greenpak4Netlist* netlist)
LogDebug("[NULL]\n");
}

//Load the constraint file once we have the topology figured out
netlist->LoadConstraints();

return true;
}

62 changes: 49 additions & 13 deletions src/greenpak4/Greenpak4Netlist.cpp
Original file line number Diff line number Diff line change
@@ -30,6 +30,7 @@ Greenpak4NetlistEntity::~Greenpak4NetlistEntity()

Greenpak4Netlist::Greenpak4Netlist(string fname, string constraint_file)
: m_topModule(NULL)
, m_constraintFname(constraint_file)
, m_parseOK(true)
{
//Read the netlist
@@ -94,19 +95,6 @@ Greenpak4Netlist::Greenpak4Netlist(string fname, string constraint_file)
json_object_put(object);
json_tokener_free(tok);
delete[] json_string;

//Read the constraint file (if we have one)
if(constraint_file == "")
return;
fp = fopen(constraint_file.c_str(), "r");
if(fp == NULL)
{
LogError("Failed to open constraint file %s\n", fname.c_str());
m_parseOK = false;
return;
}
LoadConstraints(fp);
fclose(fp);
}

Greenpak4Netlist::~Greenpak4Netlist()
@@ -120,12 +108,60 @@ Greenpak4Netlist::~Greenpak4Netlist()
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Parsing stuff

void Greenpak4Netlist::LoadConstraints()
{
//Read the constraint file (if we have one)
if(m_constraintFname == "")
return;
FILE* fp = fopen(m_constraintFname.c_str(), "r");
if(fp == NULL)
{
LogError("Failed to open constraint file %s\n", m_constraintFname.c_str());
m_parseOK = false;
return;
}
LoadConstraints(fp);
fclose(fp);
}

/**
@brief Parsing for a PCF file
*/
void Greenpak4Netlist::LoadConstraints(FILE* fp)
{
char line[1024];
while(NULL != fgets(line, sizeof(line), fp))
LoadConstraint(line);
}

void Greenpak4Netlist::LoadConstraint(const char* line)
{
//Remove leading spaces
while(isspace(line[0]))
line++;

//Skip empty lines and comments
if(line[0] == '\0')
return;
if(line[0] == '#')
return;

//Parse the constraint
char target[512];
char name[512];
char value[512];
if(3 != sscanf(line, "set_%511s %511s %511s", name, target, value))
{
LogError("Ignoring malformed constraint %s\n", line);
return;
}

//Convert the name to uppercase
for(int i=0; i<512 && name[i]; i++)
name[i] = toupper(name[i]);

//Apply it
m_topModule->AddWireAttribute(target, name, value);
}

/**
5 changes: 5 additions & 0 deletions src/greenpak4/Greenpak4Netlist.h
Original file line number Diff line number Diff line change
@@ -56,6 +56,8 @@ class Greenpak4Netlist
bool Validate()
{ return m_parseOK; }

void LoadConstraints();

protected:

void IndexNets(bool verbose);
@@ -65,6 +67,7 @@ class Greenpak4Netlist
void Load(json_object* object);
void LoadModules(json_object* object);
void LoadConstraints(FILE* fp);
void LoadConstraint(const char* line);

std::string m_creator;

@@ -77,6 +80,8 @@ class Greenpak4Netlist
//All of the nets in the netlist
nodeset m_nodes;

std::string m_constraintFname;

bool m_parseOK;
};

25 changes: 25 additions & 0 deletions src/greenpak4/Greenpak4NetlistModule.cpp
Original file line number Diff line number Diff line change
@@ -179,6 +179,31 @@ void Greenpak4NetlistModule::CreatePowerNets()
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Loading

void Greenpak4NetlistModule::AddWireAttribute(string target, string name, string value)
{
LogDebug("Applying PCF constraint %s (with value %s) to wire %s\n", name.c_str(), value.c_str(), target.c_str());
LogIndenter li;

//For now assume it's a wire and apply that
//TODO: Support PCF constraints for cells too?
if(m_nets.find(target) == m_nets.end())
{
LogWarning("Couldn't constrain object \"%s\" because no such wire exists in the design\n", target.c_str());
return;
}

//Find the cell that drove the wire and tag it
auto net = m_nets[target];
auto driver = net->m_driver;
if(driver.m_cell == NULL)
{
LogWarning("Couldn't constrain object \"%s\" because it has no driver\n", target.c_str());
return;
}
LogDebug("Wire is driven by cell %s, constraining that instead\n", driver.m_cell->m_name.c_str());
driver.m_cell->m_attributes[name] = value;
}

void Greenpak4NetlistModule::LoadAttributes(json_object* object)
{
json_object_iterator end = json_object_iter_end(object);
3 changes: 3 additions & 0 deletions src/greenpak4/Greenpak4NetlistModule.h
Original file line number Diff line number Diff line change
@@ -92,6 +92,9 @@ class Greenpak4NetlistModule
bool Validate()
{ return m_parseOK; }

//Adds an extra attribute to a wire (used by PCF parsing)
void AddWireAttribute(std::string target, std::string name, std::string value);

protected:
Greenpak4Netlist* m_parent;

2 changes: 1 addition & 1 deletion src/greenpak4/Greenpak4NetlistNode.h
Original file line number Diff line number Diff line change
@@ -64,7 +64,7 @@ class Greenpak4NetlistNode
//Source file locations
std::vector<std::string> m_src_locations;

//Net source (only valid after indexing)
//Net source (only valid after MakeNetlistEdges)
Greenpak4NetlistNodePoint m_driver;

//List of internal points we link to (only valid after indexing)
2 changes: 1 addition & 1 deletion tests/greenpak4/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -70,7 +70,7 @@ function(add_greenpak4_bitstream name part)
set(pcfargs2 "")
if(${ARGC} EQUAL 3)
set(pcfargs1 "--constraints")
set(pcfargs2 "${ARGV2}")
set(pcfargs2 "${CMAKE_CURRENT_SOURCE_DIR}/${ARGV2}")
endif()

add_custom_command(
1 change: 1 addition & 0 deletions tests/greenpak4/slg46620v/Location.pcf
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
# this is a comment
set_loc f P15
3 changes: 3 additions & 0 deletions tests/greenpak4/slg46620v/Location.v
Original file line number Diff line number Diff line change
@@ -107,4 +107,7 @@ module Location(a, b, c, d, e, f);
wire d_int = (a & b & e);
assign d = d_int;

//Random other output constrained by PCF
assign f = ~d_int;

endmodule

0 comments on commit a3df21b

Please sign in to comment.