Skip to content

Commit a3df21b

Browse files
committedFeb 16, 2017
greenpak4/gp4par: Finished initial implementation of PCF constraints. Added basic test case.
1 parent fddaeed commit a3df21b

10 files changed

+93
-17
lines changed
 

‎src/gp4par/main.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ int main(int argc, char* argv[])
221221
}
222222

223223
//Set up logging
224-
g_log_sinks.emplace(g_log_sinks.begin(), new STDLogSink(console_verbosity));
224+
g_log_sinks.emplace(g_log_sinks.begin(), new ColoredSTDLogSink(console_verbosity));
225225

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

308308
//Parse the unplaced netlist
309309
LogNotice("\nLoading Yosys JSON file \"%s\".\n", fname.c_str());
310-
Greenpak4Netlist netlist(fname);
310+
Greenpak4Netlist netlist(fname, pcfname);
311311
if(!netlist.Validate())
312312
return 1;
313313

‎src/gp4par/make_graphs.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,9 @@ bool MakeNetlistEdges(Greenpak4Netlist* netlist)
719719
LogDebug("[NULL]\n");
720720
}
721721

722+
//Load the constraint file once we have the topology figured out
723+
netlist->LoadConstraints();
724+
722725
return true;
723726
}
724727

‎src/greenpak4/Greenpak4Netlist.cpp

+49-13
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Greenpak4NetlistEntity::~Greenpak4NetlistEntity()
3030

3131
Greenpak4Netlist::Greenpak4Netlist(string fname, string constraint_file)
3232
: m_topModule(NULL)
33+
, m_constraintFname(constraint_file)
3334
, m_parseOK(true)
3435
{
3536
//Read the netlist
@@ -94,19 +95,6 @@ Greenpak4Netlist::Greenpak4Netlist(string fname, string constraint_file)
9495
json_object_put(object);
9596
json_tokener_free(tok);
9697
delete[] json_string;
97-
98-
//Read the constraint file (if we have one)
99-
if(constraint_file == "")
100-
return;
101-
fp = fopen(constraint_file.c_str(), "r");
102-
if(fp == NULL)
103-
{
104-
LogError("Failed to open constraint file %s\n", fname.c_str());
105-
m_parseOK = false;
106-
return;
107-
}
108-
LoadConstraints(fp);
109-
fclose(fp);
11098
}
11199

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

111+
void Greenpak4Netlist::LoadConstraints()
112+
{
113+
//Read the constraint file (if we have one)
114+
if(m_constraintFname == "")
115+
return;
116+
FILE* fp = fopen(m_constraintFname.c_str(), "r");
117+
if(fp == NULL)
118+
{
119+
LogError("Failed to open constraint file %s\n", m_constraintFname.c_str());
120+
m_parseOK = false;
121+
return;
122+
}
123+
LoadConstraints(fp);
124+
fclose(fp);
125+
}
126+
123127
/**
124128
@brief Parsing for a PCF file
125129
*/
126130
void Greenpak4Netlist::LoadConstraints(FILE* fp)
127131
{
132+
char line[1024];
133+
while(NULL != fgets(line, sizeof(line), fp))
134+
LoadConstraint(line);
135+
}
136+
137+
void Greenpak4Netlist::LoadConstraint(const char* line)
138+
{
139+
//Remove leading spaces
140+
while(isspace(line[0]))
141+
line++;
142+
143+
//Skip empty lines and comments
144+
if(line[0] == '\0')
145+
return;
146+
if(line[0] == '#')
147+
return;
148+
149+
//Parse the constraint
150+
char target[512];
151+
char name[512];
152+
char value[512];
153+
if(3 != sscanf(line, "set_%511s %511s %511s", name, target, value))
154+
{
155+
LogError("Ignoring malformed constraint %s\n", line);
156+
return;
157+
}
158+
159+
//Convert the name to uppercase
160+
for(int i=0; i<512 && name[i]; i++)
161+
name[i] = toupper(name[i]);
128162

163+
//Apply it
164+
m_topModule->AddWireAttribute(target, name, value);
129165
}
130166

131167
/**

‎src/greenpak4/Greenpak4Netlist.h

+5
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ class Greenpak4Netlist
5656
bool Validate()
5757
{ return m_parseOK; }
5858

59+
void LoadConstraints();
60+
5961
protected:
6062

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

6972
std::string m_creator;
7073

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

83+
std::string m_constraintFname;
84+
8085
bool m_parseOK;
8186
};
8287

‎src/greenpak4/Greenpak4NetlistModule.cpp

+25
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,31 @@ void Greenpak4NetlistModule::CreatePowerNets()
179179
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
180180
// Loading
181181

182+
void Greenpak4NetlistModule::AddWireAttribute(string target, string name, string value)
183+
{
184+
LogDebug("Applying PCF constraint %s (with value %s) to wire %s\n", name.c_str(), value.c_str(), target.c_str());
185+
LogIndenter li;
186+
187+
//For now assume it's a wire and apply that
188+
//TODO: Support PCF constraints for cells too?
189+
if(m_nets.find(target) == m_nets.end())
190+
{
191+
LogWarning("Couldn't constrain object \"%s\" because no such wire exists in the design\n", target.c_str());
192+
return;
193+
}
194+
195+
//Find the cell that drove the wire and tag it
196+
auto net = m_nets[target];
197+
auto driver = net->m_driver;
198+
if(driver.m_cell == NULL)
199+
{
200+
LogWarning("Couldn't constrain object \"%s\" because it has no driver\n", target.c_str());
201+
return;
202+
}
203+
LogDebug("Wire is driven by cell %s, constraining that instead\n", driver.m_cell->m_name.c_str());
204+
driver.m_cell->m_attributes[name] = value;
205+
}
206+
182207
void Greenpak4NetlistModule::LoadAttributes(json_object* object)
183208
{
184209
json_object_iterator end = json_object_iter_end(object);

‎src/greenpak4/Greenpak4NetlistModule.h

+3
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ class Greenpak4NetlistModule
9292
bool Validate()
9393
{ return m_parseOK; }
9494

95+
//Adds an extra attribute to a wire (used by PCF parsing)
96+
void AddWireAttribute(std::string target, std::string name, std::string value);
97+
9598
protected:
9699
Greenpak4Netlist* m_parent;
97100

‎src/greenpak4/Greenpak4NetlistNode.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class Greenpak4NetlistNode
6464
//Source file locations
6565
std::vector<std::string> m_src_locations;
6666

67-
//Net source (only valid after indexing)
67+
//Net source (only valid after MakeNetlistEdges)
6868
Greenpak4NetlistNodePoint m_driver;
6969

7070
//List of internal points we link to (only valid after indexing)

‎tests/greenpak4/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ function(add_greenpak4_bitstream name part)
7070
set(pcfargs2 "")
7171
if(${ARGC} EQUAL 3)
7272
set(pcfargs1 "--constraints")
73-
set(pcfargs2 "${ARGV2}")
73+
set(pcfargs2 "${CMAKE_CURRENT_SOURCE_DIR}/${ARGV2}")
7474
endif()
7575

7676
add_custom_command(
+1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
# this is a comment
12
set_loc f P15

‎tests/greenpak4/slg46620v/Location.v

+3
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,7 @@ module Location(a, b, c, d, e, f);
107107
wire d_int = (a & b & e);
108108
assign d = d_int;
109109

110+
//Random other output constrained by PCF
111+
assign f = ~d_int;
112+
110113
endmodule

0 commit comments

Comments
 (0)
Please sign in to comment.