17 #include <coreir/passes/analysis/verilog.h>
25 static std::string
ID;
29 void print()
override {
30 std::cout <<
"Propagating ports\n";
40 : top_level_module(std::make_unique<
Module>(std::move(name), std::move(templateName)))
46 if((std::ptrdiff_t)
mrrgs.size() < II)
48 mrrgs.resize(II, std::shared_ptr<MRRG>(
nullptr));
51 auto& mrrg_ptr =
mrrgs[II-1];
54 auto initial_mrrg = std::unique_ptr<const MRRG>(
getTopLevelModule().createMRRG(II));
56 mrrg_ptr = std::make_shared<const MRRG>(std::move(*initial_mrrg));
67 std::vector<ConfigCell*> config_table;
74 std::cout <<
"config table: \n\t";
75 for (
auto* p : config_table) {
76 std::cout << p <<
' ';
81 std::map<const Module*, MRRGNodesFromOpNode> mrrgnodes_for_op_node_for_module;
85 mrrgnodes_for_op_node_for_module[n->parent][op].insert(n);
90 std::cout <<
"Value mappings: (val node: {mrrg node })\n";
92 std::cout << val <<
":";
94 const auto& mrrg_node = *nptr;
95 std::cout << mrrg_node <<
" ";
101 std::map<const Module*, MRRGNodesFromValNode> mrrgnodes_for_val_node_for_module;
104 mrrgnodes_for_val_node_for_module[n->parent][val].insert(n);
108 if (mrrgnodes_for_val_node_for_module.find(
nullptr) !=
end(mrrgnodes_for_val_node_for_module)) {
109 std::cout <<
"detected mrrg node(s) with unset parent (no containing Module)!:\n";
112 int II = mapping.
getII();
114 for (
const auto* ccell : config_table) {
115 const auto* module = &ccell->getSingleConnectedPort().getModule();
117 const auto module_and_mrrg_nodes_for_val_node = mrrgnodes_for_val_node_for_module.find(module);
118 const auto module_and_mrrg_nodes_for_op_node = mrrgnodes_for_op_node_for_module.find(module);
119 const bool val_nodes_available = module_and_mrrg_nodes_for_val_node !=
end(mrrgnodes_for_val_node_for_module);
120 const bool op_nodes_available = module_and_mrrg_nodes_for_op_node !=
end(mrrgnodes_for_op_node_for_module);
121 const auto value_for_bitstream = [&](){
124 if (val_nodes_available) {
125 if (op_nodes_available) {
126 return module->getBitConfig(
getMRRG(II), mapping.
getOpGraph(), mapping, *ccell, module_and_mrrg_nodes_for_op_node->second, module_and_mrrg_nodes_for_val_node->second);
128 return module->getBitConfig(
getMRRG(II), mapping.
getOpGraph(), mapping, *ccell, {}, module_and_mrrg_nodes_for_val_node->second);
131 if (op_nodes_available) {
132 return module->getBitConfig(
getMRRG(II), mapping.
getOpGraph(), mapping, *ccell, module_and_mrrg_nodes_for_op_node->second, {});
134 return module->getBitConfig(
getMRRG(II), mapping.
getOpGraph(), mapping, *ccell, {}, {});
140 std::cout <<
"Exception thrown when getting bitconfig from " << module->getName() <<
" with the following input:" << std::endl;
141 std::cout <<
"ConfigCell name: " << ccell->getName() << std::endl;
142 std::cout <<
"Op Nodes:" << std::endl;
143 if (op_nodes_available) {
144 for (
const auto& op_and_nodes : module_and_mrrg_nodes_for_op_node->second) {
145 std::cout <<
'\t' << *op_and_nodes.first << std::endl;
146 for (
const auto& mrrg_node : op_and_nodes.second) {
147 std::cout <<
"\t\t" << *mrrg_node << std::endl;
151 std::cout <<
"\t[ none ]" << std::endl;
153 std::cout <<
"Value Nodes:" << std::endl;
154 if (val_nodes_available) {
155 for (
const auto& val_and_nodes : module_and_mrrg_nodes_for_val_node->second) {
156 std::cout <<
'\t' << *val_and_nodes.first << std::endl;
157 for (
const auto& mrrg_node : val_and_nodes.second) {
158 std::cout <<
"\t\t" << *mrrg_node << std::endl;
162 std::cout <<
"\t[ none ]" << std::endl;
164 std::cout <<
"End listing" << std::endl;
170 auto padded_bitstream =
BitConfig(ccell->l_contexts);
171 for (
auto cycle=0; cycle<ccell->l_contexts ; cycle++) {
173 padded_bitstream.add(value_for_bitstream.getBitSetting()[cycle], cycle);
176 padded_bitstream.add({(size_t)ccell->getStorageSize(),
BitSetting::LOW}, cycle);
181 if ((std::ptrdiff_t)value_for_bitstream[0].size() != ccell->getStorageSize()) {
182 std::cout << (
"wrong number of bits returned for " + module->getName() +
"::" + ccell->getName()) <<
": " << value_for_bitstream[0] <<
". Expected " << ccell->getStorageSize() <<
" bits. Got " << value_for_bitstream[0].size() <<
" bits\n";
183 throw cgrame_error(
"wrong number of bits returned for " + module->getName() +
"::" + ccell->getName());
186 int used_cycles = value_for_bitstream.getUsedCycles();
187 bitstream.
append(ccell, value_for_bitstream.getBitSetting(), used_cycles);
189 bitstream.
append(ccell, padded_bitstream.getBitSetting());
273 std::ofstream Floorplan;
274 Floorplan.open(
"encounter.tcl");
276 Floorplan <<
"variable blockarea\n";
277 Floorplan <<
"variable blocklength [expr sqrt($blockarea) / 0.85]\n";
280 Floorplan <<
"variable cgrawidth [expr $N*$blocklength]\n";
281 Floorplan <<
"variable cgraheight [expr $M*$blocklength]\n";
282 Floorplan <<
"variable border 20\n";
284 Floorplan <<
"# loading libraries\n";
285 Floorplan <<
"loadConfig encounter.conf 0\n";
286 Floorplan <<
"setUIVar rda_Input ui_netlist CGRA_comp.v\n";
287 Floorplan <<
"setUIVar rda_Input ui_topcell CGRA\n";
288 Floorplan <<
"commitConfig\n";
290 Floorplan <<
"# set up chip\n";
291 Floorplan <<
"floorPlan -site core -s $cgrawidth $cgraheight $border $border $border $border\n";
294 Floorplan <<
"# floorplan blocks\n";
296 int CurrentROW = 0, CurrentCOL = 0;
297 for (
auto it = submodules.begin(); it != submodules.end(); it++)
302 Floorplan <<
"setObjFPlanBox Module " << it->second->getName();
304 Floorplan <<
" [expr $border+" << CurrentCOL <<
"*$blocklength] ";
306 Floorplan <<
"[expr $cgraheight+$border-" << (CurrentROW+1) <<
"*$blocklength] ";
308 Floorplan <<
"[expr $border+" << (CurrentCOL+1) <<
"*$blocklength] ";
310 Floorplan <<
"[expr $cgraheight+$border-" << CurrentROW <<
"*$blocklength]\n";
321 Floorplan <<
"# placing design\n";
322 Floorplan <<
"getMultiCpuUsage -localCpu\n";
323 Floorplan <<
"setPlaceMode -fp false\n";
324 Floorplan <<
"placeDesign -prePlaceOpt\n";
327 Floorplan <<
"# routing design\n";
328 Floorplan <<
"setNanoRouteMode -quiet -drouteStartIteration default\n";
329 Floorplan <<
"setNanoRouteMode -quiet -routeTopRoutingLayer default\n";
330 Floorplan <<
"setNanoRouteMode -quiet -routeBottomRoutingLayer default\n";
331 Floorplan <<
"setNanoRouteMode -quiet -drouteEndIteration default\n";
332 Floorplan <<
"setNanoRouteMode -quiet -routeWithTimingDriven false\n";
333 Floorplan <<
"setNanoRouteMode -quiet -routeWithSiDriven false\n";
334 Floorplan <<
"routeDesign -globalDetail\n";
337 Floorplan <<
"saveDesign CGRA.enc\n";
339 Floorplan <<
"rcOut -spef CGRA.spef\n";
341 Floorplan <<
"saveNetlist CGRA_Golden.v\n";
348 std::vector<Module*> computeModulePostorder(
Module* module, std::vector<Module*> unique_postorder) {
349 for(
const auto& nameAndSubmodule : module->
submodules) {
350 auto submod = nameAndSubmodule.second;
351 unique_postorder = computeModulePostorder(submod, std::move(unique_postorder));
354 for(
const auto& nameAndConfigCell : module->
configcells) {
355 auto ccell = nameAndConfigCell.second;
356 unique_postorder = computeModulePostorder(ccell, std::move(unique_postorder));
359 unique_postorder.push_back(module);
361 return std::move(unique_postorder);
365 void genVerilogCoreIR(
CGRA& cgra, std::string dir,
const int& contexts) {
366 CoreIR::Context* c = CoreIR::newContext();
367 CoreIR::Namespace* cgrame = c->newNamespace(
"cgrame");
371 const auto generate_order = computeModulePostorder(cgra_top, {});
372 std::set<std::string> generated_names;
373 for (
const auto& module : generate_order) {
375 not generated_names.insert(module->
GenericName()).second
382 CoreIR::Module* topMod = cgrame->getGenerator(cgra_top->GenericName())->getModule({});
383 topMod->runGenerator();
385 std::string fileName = dir +
"/cgrame.v";
386 std::ofstream fout(fileName);
388 c->runPasses({
"rungenerators",
"removebulkconnections",
"flattentypes",
"propagatePorts",
"verilog"}, {
"cgrame"});
389 auto& vpass =
dynamic_cast<CoreIR::Passes::Verilog&
>(*c->getPassManager()->getAnalysisPass(
"verilog"));
390 std::vector<CoreIR::Passes::VModule*> modList = vpass.getModList();
391 cgra.
hybridPorts = modList[modList.size()-1]->getPorts();
392 vpass.writeToStream(fout);
393 CoreIR::deleteContext(c);
396 void genHybridCoreIR(
CGRA& cgra, std::string dir,
int mem_size) {
397 std::ofstream myfile;
398 std::string fileName = dir +
"/control.sv";
399 myfile.open(fileName);
434 CoreIR::Context* c = this->getContext();
436 CoreIR::Module* m = node.getModule();
438 if (m->isGenerated()) {
439 CoreIR::Generator* g = m->getGenerator();
440 if (g->getMetaData().find(
"propagatePorts") != g->getMetaData().end()) {
441 std::vector<std::string> portsToPropagate = g->getMetaData()[
"propagatePorts"].get<std::vector<std::string>>();
442 if (!portsToPropagate.empty()) {
448 if (!m->hasDef())
return false;
449 CoreIR::ModuleDef* def = m->getDef();
451 for (
auto imap : def->getInstances()) {
452 CoreIR::Instance* inst = imap.second;
453 CoreIR::Module* mref = imap.second->getModuleRef();
457 string iname = imap.first;
459 auto thisRecord = m->getType()->getRecord();
460 auto submodRecord = mref->getType()->getRecord();
461 for (
auto & port : portsToPropagate) {
464 if (submodRecord.find(port) != submodRecord.end()) {
465 if (thisRecord.find(iname+
"_"+port) == thisRecord.end()) {
466 node.appendField(iname+
"_"+port, mref->getType()->getRecord().at(port));
470 def->connect(
"self." + iname +
"_" + port, iname +
"." + port);
471 port = iname+
"_"+port;
479 std::copy(portsToPropagate.begin(), portsToPropagate.end(), std::back_inserter(
modulesToPropagateFrom[m]));