yosys-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
scshell.cc
Go to the documentation of this file.
1 #include "subcircuit.h"
2 #include <string.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 
6 std::vector<std::string> readLine()
7 {
8  char buffer[4096];
9  std::vector<std::string> tokenList;
10 
11  while (tokenList.size() == 0 && fgets(buffer, sizeof(buffer), stdin) != NULL) {
12  for (char *p = buffer; char *tok = strtok(p, " \t\r\n"); p = NULL) {
13  if (p != NULL && tok[0] == '#')
14  break;
15  tokenList.push_back(tok);
16  }
17  }
18 
19  return tokenList;
20 }
21 
22 int main()
23 {
24  std::string graphId;
25  SubCircuit::Graph *graph = NULL;
26  SubCircuit::Solver solver;
27  std::map<std::string, std::set<std::string>> initialMappings;
28  std::vector<SubCircuit::Solver::Result> results;
29  std::vector<SubCircuit::Solver::MineResult> mineResults;
30  std::vector<std::string> cmdBuffer;
31  bool lastCommandExpect = false;
32 
33  while (1)
34  {
35  cmdBuffer = readLine();
36  if (cmdBuffer.empty())
37  break;
38 
39  printf(graph == NULL || cmdBuffer[0] == "endgraph" ? ">" : "> ");
40  for (const auto &tok : cmdBuffer)
41  printf(" %s", tok.c_str());
42  printf("\n");
43 
44  lastCommandExpect = false;
45 
46  if (graph != NULL)
47  {
48  if (cmdBuffer[0] == "node" && cmdBuffer.size() >= 3) {
49  graph->createNode(cmdBuffer[1], cmdBuffer[2]);
50  for (int i = 3; i < int(cmdBuffer.size()); i++) {
51  std::string portId = cmdBuffer[i];
52  int width = 1, minWidth = -1;
53  if (i+1 < int(cmdBuffer.size()) && '0' <= cmdBuffer[i+1][0] && cmdBuffer[i+1][0] <= '9')
54  width = atoi(cmdBuffer[++i].c_str());
55  if (i+1 < int(cmdBuffer.size()) && '0' <= cmdBuffer[i+1][0] && cmdBuffer[i+1][0] <= '9')
56  minWidth = atoi(cmdBuffer[++i].c_str());
57  graph->createPort(cmdBuffer[1], portId, width, minWidth);
58  }
59  continue;
60  }
61 
62  if (cmdBuffer[0] == "connect" && cmdBuffer.size() == 5) {
63  graph->createConnection(cmdBuffer[1], cmdBuffer[2], cmdBuffer[3], cmdBuffer[4]);
64  continue;
65  }
66 
67  if (cmdBuffer[0] == "connect" && cmdBuffer.size() == 7) {
68  graph->createConnection(cmdBuffer[1], cmdBuffer[2], atoi(cmdBuffer[3].c_str()), cmdBuffer[4], cmdBuffer[5], atoi(cmdBuffer[6].c_str()));
69  continue;
70  }
71 
72  if (cmdBuffer[0] == "connect" && cmdBuffer.size() == 8) {
73  graph->createConnection(cmdBuffer[1], cmdBuffer[2], atoi(cmdBuffer[3].c_str()), cmdBuffer[4], cmdBuffer[5], atoi(cmdBuffer[6].c_str()), atoi(cmdBuffer[7].c_str()));
74  continue;
75  }
76 
77  if (cmdBuffer[0] == "constant" && cmdBuffer.size() == 5) {
78  int constValue = cmdBuffer[4].size() > 1 && cmdBuffer[4][0] == '#' ? atoi(cmdBuffer[4].c_str()+1) : cmdBuffer[4][0];
79  graph->createConstant(cmdBuffer[1], cmdBuffer[2], atoi(cmdBuffer[3].c_str()), constValue);
80  continue;
81  }
82 
83  if (cmdBuffer[0] == "constant" && cmdBuffer.size() == 4) {
84  graph->createConstant(cmdBuffer[1], cmdBuffer[2], atoi(cmdBuffer[3].c_str()));
85  continue;
86  }
87 
88  if (cmdBuffer[0] == "extern" && cmdBuffer.size() >= 3) {
89  for (int i = 2; i < int(cmdBuffer.size()); i++) {
90  std::string portId = cmdBuffer[i];
91  int bit = -1;
92  if (i+1 < int(cmdBuffer.size()) && '0' <= cmdBuffer[i+1][0] && cmdBuffer[i+1][0] <= '9')
93  bit = atoi(cmdBuffer[++i].c_str());
94  graph->markExtern(cmdBuffer[1], portId, bit);
95  }
96  continue;
97  }
98 
99  if (cmdBuffer[0] == "allextern" && cmdBuffer.size() == 1) {
100  graph->markAllExtern();
101  continue;
102  }
103 
104  if (cmdBuffer[0] == "endgraph" && cmdBuffer.size() == 1) {
105  solver.addGraph(graphId, *graph);
106  delete graph;
107  graph = NULL;
108  continue;
109  }
110  }
111  else
112  {
113  if (cmdBuffer[0] == "graph" && cmdBuffer.size() == 2) {
114  graph = new SubCircuit::Graph;
115  graphId = cmdBuffer[1];
116  continue;
117  }
118 
119  if (cmdBuffer[0] == "compatible" && cmdBuffer.size() == 3) {
120  solver.addCompatibleTypes(cmdBuffer[1], cmdBuffer[2]);
121  continue;
122  }
123 
124  if (cmdBuffer[0] == "constcompat" && cmdBuffer.size() == 3) {
125  int needleConstValue = cmdBuffer[1].size() > 1 && cmdBuffer[1][0] == '#' ? atoi(cmdBuffer[1].c_str()+1) : cmdBuffer[1][0];
126  int haystackConstValue = cmdBuffer[2].size() > 1 && cmdBuffer[2][0] == '#' ? atoi(cmdBuffer[2].c_str()+1) : cmdBuffer[2][0];
127  solver.addCompatibleConstants(needleConstValue, haystackConstValue);
128  continue;
129  }
130 
131  if (cmdBuffer[0] == "swapgroup" && cmdBuffer.size() >= 4) {
132  std::set<std::string> ports;
133  for (int i = 2; i < int(cmdBuffer.size()); i++)
134  ports.insert(cmdBuffer[i]);
135  solver.addSwappablePorts(cmdBuffer[1], ports);
136  continue;
137  }
138 
139  if (cmdBuffer[0] == "swapperm" && cmdBuffer.size() >= 4 && cmdBuffer.size() % 2 == 1 && cmdBuffer[cmdBuffer.size()/2 + 1] == ":") {
140  std::map<std::string, std::string> portMapping;
141  int n = (cmdBuffer.size()-3) / 2;
142  for (int i = 0; i < n; i++)
143  portMapping[cmdBuffer[i+2]] = cmdBuffer[i+3+n];
144  solver.addSwappablePortsPermutation(cmdBuffer[1], portMapping);
145  continue;
146  }
147 
148  if (cmdBuffer[0] == "initmap" && cmdBuffer.size() >= 4) {
149  for (int i = 2; i < int(cmdBuffer.size()); i++)
150  initialMappings[cmdBuffer[1]].insert(cmdBuffer[i]);
151  continue;
152  }
153 
154  if (cmdBuffer[0] == "solve" && 3 <= cmdBuffer.size() && cmdBuffer.size() <= 5) {
155  bool allowOverlap = true;
156  int maxSolutions = -1;
157  if (cmdBuffer.size() >= 4)
158  allowOverlap = cmdBuffer[3] == "true" || atoi(cmdBuffer[3].c_str()) ? true : false;
159  if (cmdBuffer.size() >= 5)
160  maxSolutions = atoi(cmdBuffer[4].c_str());
161  solver.solve(results, cmdBuffer[1], cmdBuffer[2], initialMappings, allowOverlap, maxSolutions);
162  initialMappings.clear();
163  continue;
164  }
165 
166  if (cmdBuffer[0] == "mine" && 4 <= cmdBuffer.size() && cmdBuffer.size() <= 5) {
167  solver.mine(mineResults, atoi(cmdBuffer[1].c_str()), atoi(cmdBuffer[2].c_str()),
168  atoi(cmdBuffer[3].c_str()), cmdBuffer.size() == 5 ? atoi(cmdBuffer[4].c_str()) : -1);
169  continue;
170  }
171 
172  if (cmdBuffer[0] == "clearoverlap" && cmdBuffer.size() == 1) {
173  solver.clearOverlapHistory();
174  continue;
175  }
176 
177  if (cmdBuffer[0] == "clearconfig" && cmdBuffer.size() == 1) {
178  solver.clearConfig();
179  continue;
180  }
181 
182  if (cmdBuffer[0] == "verbose" && cmdBuffer.size() == 1) {
183  solver.setVerbose();
184  continue;
185  }
186 
187  if (cmdBuffer[0] == "expect" && cmdBuffer.size() == 2) {
188  int expected = atoi(cmdBuffer[1].c_str());
189  printf("\n-- Expected %d, Got %d --\n", expected, int(results.size()) + int(mineResults.size()));
190  for (int i = 0; i < int(results.size()); i++) {
191  printf("\nMatch #%d: (%s in %s)\n", i, results[i].needleGraphId.c_str(), results[i].haystackGraphId.c_str());
192  for (const auto &it : results[i].mappings) {
193  printf(" %s -> %s", it.first.c_str(), it.second.haystackNodeId.c_str());
194  for (const auto &it2 : it.second.portMapping)
195  printf(" %s:%s", it2.first.c_str(), it2.second.c_str());
196  printf("\n");
197  }
198  }
199  for (auto &result : mineResults) {
200  printf("\nFrequent SubCircuit with %d nodes and %d matches:\n", int(result.nodes.size()), result.totalMatchesAfterLimits);
201  printf(" primary match in %s:", result.graphId.c_str());
202  for (auto &node : result.nodes)
203  printf(" %s", node.nodeId.c_str());
204  printf("\n");
205  for (auto &it : result.matchesPerGraph)
206  printf(" matches in %s: %d\n", it.first.c_str(), it.second);
207  }
208  printf("\n");
209  if (expected != int(results.size()) + int(mineResults.size())) {
210  printf("^^ expected %d, Got %d ^^\n\n", expected, int(results.size()) + int(mineResults.size()));
211  printf(" +----------------+\n");
212  printf(" | \\|/ ____ \\|/ |\n");
213  printf(" | \"@'/ ,. \\`@\" |\n");
214  printf(" | /_| \\__/ |_\\ |\n");
215  printf(" | \\__U_/ |\n");
216  printf(" | | | |\n");
217  printf(" +----------------+\n\n");
218  return 1;
219  }
220  results.clear();
221  mineResults.clear();
222  lastCommandExpect = true;
223  continue;
224  }
225  }
226 
227  printf("Invalid input command!\n");
228  return 1;
229  }
230 
231  if (graph)
232  delete graph;
233 
234  if (!lastCommandExpect) {
235  printf("\n-- Got %d --\n", int(results.size()) + int(mineResults.size()));
236  for (int i = 0; i < int(results.size()); i++) {
237  printf("\nMatch #%d: (%s in %s)\n", i, results[i].needleGraphId.c_str(), results[i].haystackGraphId.c_str());
238  for (const auto &it : results[i].mappings) {
239  printf(" %s -> %s", it.first.c_str(), it.second.haystackNodeId.c_str());
240  for (const auto &it2 : it.second.portMapping)
241  printf(" %s:%s", it2.first.c_str(), it2.second.c_str());
242  printf("\n");
243  }
244  }
245  for (auto &result : mineResults) {
246  printf("\nFrequent SubCircuit with %d nodes and %d matches:\n", int(result.nodes.size()), result.totalMatchesAfterLimits);
247  printf(" primary match in %s:", result.graphId.c_str());
248  for (auto &node : result.nodes)
249  printf(" %s", node.nodeId.c_str());
250  printf("\n");
251  for (auto &it : result.matchesPerGraph)
252  printf(" matches in %s: %d\n", it.first.c_str(), it.second);
253  }
254  } else
255  printf("PASSED.\n");
256 
257  printf("\n");
258 
259  return 0;
260 }
261 
void addSwappablePorts(std::string needleTypeId, std::string portId1, std::string portId2, std::string portId3=std::string(), std::string portId4=std::string())
Definition: subcircuit.cc:1647
tuple n
Definition: fsm/generate.py:59
void addCompatibleConstants(int needleConstant, int haystackConstant)
Definition: subcircuit.cc:1642
void createNode(std::string nodeId, std::string typeId, void *userData=NULL, bool shared=false)
Definition: subcircuit.cc:107
void solve(std::vector< Result > &results, std::string needleGraphId, std::string haystackGraphId, bool allowOverlap=true, int maxSolutions=-1)
Definition: subcircuit.cc:1668
void createConstant(std::string toNodeId, std::string toPortId, int toBit, int constValue)
Definition: subcircuit.cc:209
void addGraph(std::string graphId, const Graph &graph)
Definition: subcircuit.cc:1632
int main()
Definition: scshell.cc:22
void addSwappablePortsPermutation(std::string needleTypeId, std::map< std::string, std::string > portMapping)
Definition: subcircuit.cc:1663
void markExtern(std::string nodeId, std::string portId, int bit=-1)
Definition: subcircuit.cc:244
void mine(std::vector< MineResult > &results, int minNodes, int maxNodes, int minMatches, int limitMatchesPerGraph=-1)
Definition: subcircuit.cc:1680
void createConnection(std::string fromNodeId, std::string fromPortId, int fromBit, std::string toNodeId, std::string toPortId, int toBit, int width=1)
Definition: subcircuit.cc:144
void clearOverlapHistory()
Definition: subcircuit.cc:1685
#define NULL
void createPort(std::string nodeId, std::string portId, int width=1, int minWidth=-1)
Definition: subcircuit.cc:120
std::vector< std::string > readLine()
Definition: scshell.cc:6
void addCompatibleTypes(std::string needleTypeId, std::string haystackTypeId)
Definition: subcircuit.cc:1637