16 #include <coreir/passes/analysis/coreirjson.h>
25 std::string makeParameterListSyntaxItem(
const std::vector<ResolvedVeroligModuleParameter>& resolved_params) {
26 if (resolved_params.empty()) {
29 std::string paramstr =
"#(";
31 for (
const auto& resolved_param : resolved_params) {
32 paramstr +=
'.' + resolved_param.name +
'(' + resolved_param.value +
"), ";
35 paramstr[paramstr.size() - 2] =
')';
40 std::pair<Port,Port> splitBidirPort(
const Port& p) {
41 auto result = std::make_pair(p, p);
42 result.first.name +=
"_in";
43 result.second.name +=
"_out";
49 std::string makePortDeclaration(
const Port& p,
const char* indent) {
52 const auto ioport_copies = splitBidirPort(p);
53 result += indent + ioport_copies.first.makeVerilogDeclaration() +
'\n';
54 result += indent + ioport_copies.second.makeVerilogDeclaration() +
'\n';
61 template<
typename Ports,
typename Ports2>
62 std::string makePortsDeclaration(
const Ports& ports,
const Ports2& portsToPropagate,
const char* indent) {
64 for (
auto& port : ports) {
65 result += makePortDeclaration(*port.second,
SET_INDENT);
67 for (
auto& port : portsToPropagate) {
68 result += makePortDeclaration(port,
SET_INDENT);
73 template<
typename Ports,
typename Ports2>
74 nlohmann::json makeCoreIRInterface(
const Ports& ports,
const Ports2& portsToPropagate) {
75 nlohmann::json result = {};
77 for (
auto& port : ports) {
79 const auto ioport_copies = splitBidirPort(*port.second);
80 result.push_back(ioport_copies.first.name);
81 result.push_back(ioport_copies.second.name);
83 std::string portName = port.second->getName();
84 result.push_back(portName);
88 for (
auto& port : portsToPropagate) {
89 std::string portName = port.getName();
90 result.push_back(portName);
103 default:
return os <<
"FIXME_UNHANDLED_VerilogType_PRINTED";
114 default:
throw make_from_stream<cgrame_error>([&](
auto&& s) {
115 s <<
"unhandled port_type " <<
pt <<
" in " << __func__;
124 result +=
' ' +
name +
';';
131 :
Module(name,
"", loc, size, isElastic)
142 , templateName(template_name)
144 , adds_synchronous_circuitry(false)
145 , isElastic(isElastic)
154 for(
auto it =
ports.begin(); it !=
ports.end(); ++it)
166 for(
const auto& name_and_configcell :
configcells) {
167 ConfigTable.push_back(name_and_configcell.second);
170 for(
const auto& name_and_submodule :
submodules) {
171 name_and_submodule.second->genConfigOrder(ConfigTable);
176 std::set<std::string> PrintedModules;
177 std::queue<Module*> ToPrint;
182 std::set<unsigned> PrintedConfigs;
183 std::queue<ConfigCell*> ConfigsToPrint;
186 while (!ToPrint.empty())
188 std::string filename = dir + ToPrint.front()->GenericName() +
".v";
189 std::cout <<
" Generating \"" << filename <<
"\" ... ";
191 std::streambuf* original_sbuf = std::cout.rdbuf();
192 std::ofstream hdl_filebuf(filename);
193 std::cout.rdbuf(hdl_filebuf.rdbuf());
196 ToPrint.front()->GenModuleVerilog();
199 std::cout.rdbuf(original_sbuf);
200 std::cout <<
"Done!" << std::endl;
202 while (!ConfigsToPrint.empty())
204 std::string cellSize =
std::to_string(ConfigsToPrint.front()->getStorageSize());
205 std::string filename = dir +
"configCell_" + cellSize +
"b.v";
206 std::cout <<
" Generating \"" << filename <<
"\" ... ";
208 std::streambuf* original_sbuf = std::cout.rdbuf();
209 std::ofstream hdl_filebuf(filename);
210 std::cout.rdbuf(hdl_filebuf.rdbuf());
211 ConfigsToPrint.front()->GenModuleVerilog();
212 ConfigsToPrint.pop();
214 std::cout.rdbuf(original_sbuf);
215 std::cout <<
"Done!" << std::endl;
226 if (PrintedModules.find(UniqueModuleName) != PrintedModules.end())
230 PrintedModules.insert(UniqueModuleName);
234 for(
const auto& name_and_submodule :
submodules)
235 name_and_submodule.second->GetModulesToPrint(ToPrint, PrintedModules);
246 auto ccell = it.second;
247 auto size = ccell->getStorageSize();
248 if (uniq.find(size) == uniq.end())
256 it.second->GetConfigsToPrint(q, uniq);
291 std::cout <<
"endmodule\n\n";
298 is_cgra_top = this->
name ==
"CGRA",
303 CoreIR::Context* c, CoreIR::Values genargs
304 ) -> CoreIR::RecordType* {
305 CoreIR::RecordParams
interface = {};
306 if (needs_config_ports) {
307 interface.push_back({
"ConfigIn", c->BitIn()});
308 interface.push_back({
"ConfigOut", c->Bit()});
309 interface.push_back({
"Config_Clock", c->BitIn()});
310 interface.push_back({
"Config_Reset", c->BitIn()});
311 interface.push_back({
"CGRA_Clock", c->BitIn()});
312 interface.push_back({
"CGRA_Reset", c->BitIn()});
313 interface.push_back({
"CGRA_Enable", c->BitIn()});
314 }
else if (has_synchronous_cells) {
315 interface.push_back({
"CGRA_Clock", c->BitIn()});
316 interface.push_back({
"CGRA_Reset", c->BitIn()});
317 interface.push_back({
"CGRA_Enable", c->BitIn()});
320 for (
auto& port :
ports)
322 std::string portName = port.second->getName();
324 unsigned portSize = port.second->size;
325 unsigned portSizeForInterface;
328 CoreIR::Value* paramArg = genargs.at(port.second->parameter);
329 portSizeForInterface = (portSize > 0)? portSize : paramArg->get<
int>();
333 portSizeForInterface = portSize;
335 CoreIR::ArrayType* portTypeForInterface;
338 portTypeForInterface= c->Array(portSizeForInterface,c->BitIn());
343 portTypeForInterface = c->Array(portSizeForInterface,c->Bit());
348 const auto ioport_copies = splitBidirPort(*port.second);
349 interface.push_back({ioport_copies.first.name, c->Array(portSizeForInterface,c->BitIn())});
350 interface.push_back({ioport_copies.second.name, c->Array(portSizeForInterface,c->Bit())});
354 throw make_from_stream<cgrame_error>([&](
auto& s) {
355 s << __func__ <<
" port "<< portName <<
" doesn't handle " << portType <<
" port type";
358 interface.push_back({port.second->getName(), portTypeForInterface});
363 std::string portName = port.getName();
368 unsigned portSize = port.size;
369 unsigned portSizeForInterface;
372 CoreIR::Value* paramArg = genargs.at(port.parameter);
373 portSizeForInterface = (portSize > 0)? portSize : paramArg->get<
int>();
377 portSizeForInterface = portSize;
379 CoreIR::ArrayType* portTypeForInterface;
382 portTypeForInterface= c->Array(portSizeForInterface,c->BitIn());
387 portTypeForInterface = c->Array(portSizeForInterface,c->Bit());
392 const auto ioport_copies = splitBidirPort(port);
393 interface.push_back({ioport_copies.first.name, c->Array(portSizeForInterface,c->BitIn())});
394 interface.push_back({ioport_copies.second.name, c->Array(portSizeForInterface,c->Bit())});
398 throw make_from_stream<cgrame_error>([&](
auto& s) {
399 s << __func__ <<
" doesn't handle " << portType <<
" port type";
402 interface.push_back({port.getName(), portTypeForInterface});
405 return c->Record(interface);
413 CoreIR::Context* c, CoreIR::Values genargs, CoreIR::ModuleDef* def
419 CoreIR::Generator* submodGen = c->getGenerator(
"cgrame." + submodule.second->GenericName());
421 CoreIR::Values submoduleParams = {};
422 CoreIR::Module* submod = submodGen->getModule(submoduleParams);
424 CoreIR::Values submoduleInitializer = {};
425 CoreIR::Instance* submoduleinstance = def->addInstance(submodule.first, submod, submoduleInitializer);
426 (void)submoduleinstance;
432 CoreIR::Generator* configGen = c->getGenerator(
"cgrame." + configcell.second->GenericName());
435 CoreIR::Values configCellParams = {};
436 CoreIR::Module* configMod = configGen->getModule(configCellParams);
438 CoreIR::Values configCellInitializer = {};
439 CoreIR::Instance* configCellInstance = def->addInstance(configcell.first, configMod, configCellInitializer);
440 (void)configCellInstance;
445 auto is_cgra_top = this->
name ==
"CGRA";
450 def->connect(
"self.Config_Clock", submodule.first +
".Config_Clock");
451 def->connect(
"self.Config_Reset", submodule.first +
".Config_Reset");
452 def->connect(
"self.CGRA_Clock", submodule.first +
".CGRA_Clock");
453 def->connect(
"self.CGRA_Reset", submodule.first +
".CGRA_Reset");
454 def->connect(
"self.CGRA_Enable", submodule.first +
".CGRA_Enable");
458 def->connect(
"self.CGRA_Clock", submodule.first +
".CGRA_Clock");
459 def->connect(
"self.CGRA_Reset", submodule.first +
".CGRA_Reset");
460 def->connect(
"self.CGRA_Enable", submodule.first +
".CGRA_Enable");
466 def->connect(
"self.CGRA_Clock", configCell.first +
".CGRA_Clock");
467 def->connect(
"self.CGRA_Reset", configCell.first +
".CGRA_Reset");
468 def->connect(
"self.CGRA_Enable", configCell.first +
".CGRA_Enable");
469 def->connect(
"self.Config_Clock", configCell.first +
".Config_Clock");
470 def->connect(
"self.Config_Reset", configCell.first +
".Config_Reset");
473 const auto addModulePath = [this_ptr=
this](
const Module& m,
const std::string& port_name) {
474 if (&m == this_ptr) {
475 return "self." + port_name;
477 return m.getName() +
'.' + port_name;
484 Connection* connectionSpecifier = portAndConnection.second;
486 for (
auto dstConnection : connectionSpecifier->
dst)
488 const Port* src = connectionSpecifier->
src;
489 const Port* dst = dstConnection;
490 if (&src->
getModule() ==
this) { std::swap(src,dst); }
492 const auto src_ioport_copy = splitBidirPort(*src);
493 const auto dst_ioport_copy = splitBidirPort(*dst);
497 std::string srcPortName = src->
getName();
498 std::string dstPortName = dst->
getName();
504 srcPortName = src_ioport_copy.second.getName();
507 srcPortName = src_ioport_copy.first.getName();
517 dstPortName = dst_ioport_copy.second.getName();
520 dstPortName = dst_ioport_copy.first.getName();
527 addModulePath(src->
getModule(), srcPortName),
528 addModulePath(dst->
getModule(), dstPortName)
532 if (src_is_bidir && dst_is_bidir) {
542 std::string srcConfigInstance;
543 std::string srcConfig;
544 std::string stopSrcConfig;
545 std::string validSrcConfig;
546 std::string dstConfigInstance;
547 std::string dstConfigPortName;
548 std::string dstConfig;
549 std::string stopDstConfig;
550 std::string validDstConfig;
553 srcConfigInstance = configCell.second->getName();
554 srcConfig = srcConfigInstance +
".select";
555 validDstConfig = srcConfigInstance +
".valid";
556 stopDstConfig = srcConfigInstance +
".stop";
557 for (
auto configCellConnection : configCell.second->getAllConnectedPorts())
559 if (&(configCellConnection->getModule()) ==
this)
561 dstConfigInstance =
"self";
565 dstConfigInstance = configCellConnection->getModule().getName();
567 dstConfigPortName = configCellConnection->getName();
568 dstConfig = dstConfigInstance +
"." + dstConfigPortName;
569 validSrcConfig = dstConfig +
"_valid_upstream";
570 stopSrcConfig = dstConfig +
"_stop_upstream";
571 def->connect(srcConfig, dstConfig);
574 def->connect(validDstConfig, validSrcConfig);
575 def->connect(stopDstConfig, stopSrcConfig);
581 std::string PreviousWire =
"self.ConfigIn";
582 std::string ConfigInput;
585 ConfigInput = PreviousWire;
586 def->connect(ConfigInput, configCell.second->getName() +
".ConfigIn");
587 PreviousWire = configCell.second->getName() +
".ConfigOut";
593 ConfigInput = PreviousWire;
594 def->connect(ConfigInput, submodule.first +
".ConfigIn");
595 PreviousWire = submodule.first +
".ConfigOut";
600 def->connect(PreviousWire,
"self.ConfigOut");
608 CoreIR::Namespace* cgrame = c->getNamespace(
"cgrame");
609 const auto makeIntParameter = [c](
auto& param) -> CoreIR::Params::value_type {
return {param.first, c->Int()}; };
610 const auto makeConstParameter = [c](
auto& param) -> CoreIR::Values::value_type {
return {param.first, CoreIR::Const::make(c, param.second)}; };
612 CoreIR::Params moduleParams;
616 std::transform(
parameterlist.begin(),
parameterlist.end(), std::inserter(moduleParams, moduleParams.end()), makeIntParameter);
617 moduleParams.insert({
"contexts", c->Int()});
618 CoreIR::Values defaultArgs = {};
619 std::transform(
parameterlist.begin(),
parameterlist.end(), std::inserter(defaultArgs, defaultArgs.end()), makeConstParameter);
620 defaultArgs.insert({
"contexts", CoreIR::Const::make(c, contexts)});
623 CoreIR::Generator* modGen = cgrame->newGeneratorDecl(
GenericName(), tg, moduleParams);
624 modGen->addDefaultGenArgs(defaultArgs);
629 std::vector<std::string> portNames;
635 std::vector<std::string> portNames;
637 portNames.push_back(port.getName());
639 if (!portNames.empty()) {
640 modGen->getMetaData()[
"propagatePorts"] = portNames;
647 std::vector<std::string> PortList;
651 PortList.push_back(
"Config_Clock");
652 PortList.push_back(
"Config_Reset");
653 PortList.push_back(
"ConfigIn");
654 PortList.push_back(
"ConfigOut");
656 else if (HasRegisters)
658 PortList.push_back(
"CGRA_Clock");
659 PortList.push_back(
"CGRA_Reset");
662 for(
const auto& name_and_port :
ports)
663 PortList.push_back(name_and_port.second->name);
665 for (
unsigned i = 0; i < PortList.size(); i++)
667 std::cout << PortList[i];
668 if (i != PortList.size() - 1)
679 std::cout <<
SET_INDENT <<
"parameter " << it->first <<
" = " << it->second <<
";\n";
686 std::cout <<
SET_INDENT <<
"// Specifying the ports\n";
689 std::cout <<
SET_INDENT <<
"input Config_Clock, Config_Reset, ConfigIn;\n";
690 std::cout <<
SET_INDENT <<
"output ConfigOut;\n";
693 std::cout <<
SET_INDENT <<
"input CGRA_Clock, CGRA_Reset;\n";
695 for(std::map<std::string,Port*>::iterator it =
ports.begin(); it !=
ports.end(); ++it)
697 Port* curPort = it->second;
707 std::cout <<
"<ERROR: DID NOT DECLARE PORT SPECIFICATION!>";
711 std::cout <<
"[" << curPort->
parameter <<
"-1:0] ";
712 if (curPort->
size > 1)
713 std::cout <<
"[" << curPort->
size-1 <<
":0] ";
715 std::cout << curPort->
name <<
";\n";
723 PrintList WireList, SubmodList, AssignList;
745 for(std::map<std::string,Module*>::iterator it =
submodules.begin(); it !=
submodules.end(); ++it)
747 std::vector<std::string> StringVector;
749 for (
auto& port : it->second->ports)
753 Matrix.push_back(StringVector);
759 throw make_from_stream<cgrame_error>([&](
auto&& s) {
760 s <<
"module has no Module::CoreIRGenFunctionality";
767 std::stringstream buffer;
769 std::string PreviousWire, ConfigInput, ConfigOutput;
770 int SubmodIndex, PortIndex;
772 PreviousWire =
"ConfigIn";
778 WireList.
add({
"\n",
SET_INDENT,
"// Wires for the the config cells\n"});
779 SubmodList.
add({
"\n",
SET_INDENT,
"// Declaring the config cells\n"});
783 buffer << it->second->name <<
"_sig";
784 Signal = buffer.str();
785 buffer.str(std::string());
788 if (it->second->getStorageSize() > 1)
793 ConfigInput = PreviousWire;
796 buffer << it->second->name <<
"_config";
797 ConfigOutput = buffer.str();
798 buffer.str(std::string());
800 PreviousWire = ConfigOutput;
806 SET_DOUBLE_INDENT,
".ConfigIn(", ConfigInput,
"),\n",
SET_DOUBLE_INDENT,
".ConfigOut(" , ConfigOutput ,
"),\n",
810 for (
auto* port : it->second->getAllConnectedPorts())
813 if (SubmodIndex < 0)
continue;
814 PortIndex = port->parent->FindPortIndex(port->name);
815 Matrix[SubmodIndex][PortIndex] =
"." + port->name +
"(" + Signal +
")";
824 WireList.
add({
"\n",
SET_INDENT,
"// Wires connecting the main module and submodules\n"});
829 if (it->second->src->parent ==
this)
831 for(
unsigned j = 0; j < it->second->dst.size(); j++)
833 if (it->second->dst[j]->parent ==
this)
835 AssignList.
add({
SET_INDENT,
"assign ", it->second->dst[j]->name,
" = ", Signal,
";\n"});
840 PortIndex = it->second->dst[j]->parent->FindPortIndex(it->second->dst[j]->name);
841 buffer <<
"." << it->second->dst[j]->name <<
"(" << it->second->src->name <<
")";
842 Matrix[SubmodIndex][PortIndex] = buffer.str();
843 buffer.str(std::string());
848 if (it->second->dst.size() == 1 && it->second->dst[0]->parent ==
this)
851 int PortIndex = it->second->src->parent->FindPortIndex(it->second->src->name);
852 buffer <<
"." << it->second->src->name <<
"(" << it->second->dst[0]->name <<
")";
853 Matrix[SubmodIndex][PortIndex] = buffer.str();
854 buffer.str(std::string());
858 buffer << it->second->src->parent->name <<
"_" << it->second->src->name <<
"_sig";
859 Signal = buffer.str();
860 buffer.str(std::string());
863 if (it->second->src->size ==
PARAMETERIZED && it->second->src->parameter ==
"size")
867 else if (it->second->src->size > 1)
874 int PortIndex = it->second->src->parent->FindPortIndex(it->second->src->name);
875 buffer <<
"." << it->second->src->name <<
"(" << Signal <<
")";
876 Matrix[SubmodIndex][PortIndex] = buffer.str();
877 buffer.str(std::string());
880 for(
unsigned j = 0; j < it->second->dst.size(); j++)
882 if (it->second->dst[j]->parent ==
this)
884 AssignList.
add({
SET_INDENT,
"assign ", it->second->dst[j]->name,
" = ", Signal,
";\n"});
890 PortIndex = it->second->dst[j]->parent->FindPortIndex(it->second->dst[j]->name);
891 buffer <<
"." << it->second->dst[j]->name <<
"(" << Signal <<
")";
892 Matrix[SubmodIndex][PortIndex] = buffer.str();
893 buffer.str(std::string());
904 buffer.str(std::string());
908 SubmodList.
add({
"\n",
SET_INDENT,
"// Declaring the submodules\n"});
910 for(std::map<std::string,Module*>::iterator it =
submodules.begin(); it !=
submodules.end(); ++it)
912 const auto& resolved_params = it->second->ResolveVerilogParameters();
913 const auto& parameter_string = makeParameterListSyntaxItem(resolved_params);
914 SubmodList.
add({
SET_INDENT, it->second->GenericName(),
" ", parameter_string, it->second->name,
"(\n"});
917 ConfigInput = PreviousWire;
919 buffer << it->second->name <<
"_config";
920 ConfigOutput = buffer.str();
921 buffer.str(std::string());
922 PreviousWire = ConfigOutput;
926 SubmodList.
add({
SET_DOUBLE_INDENT,
".Config_Clock(Config_Clock),\n",
SET_DOUBLE_INDENT,
".Config_Reset(Config_Reset),\n",
SET_DOUBLE_INDENT,
".ConfigIn(", ConfigInput,
"),\n",
928 SubmodList.
add({
",\n"});
933 SubmodList.
add({
",\n"});
936 for(
unsigned j = 0; j < Matrix[i].size(); j++)
940 if (j+1 != Matrix[i].size())
941 SubmodList.
add({
",\n"});
943 SubmodList.
add({
");\n"});
948 if (PreviousWire !=
"ConfigIn")
949 AssignList.
add({
SET_INDENT,
"assign ConfigOut = ", PreviousWire,
";\n"});
956 std::vector<ResolvedVeroligModuleParameter> result;
972 for(std::map<std::string,Port*>::iterator it =
ports.begin(); it !=
ports.end(); ++it)
974 if (it->second->name == PortName)
986 for(std::map<std::string,Module*>::iterator it =
submodules.begin(); it !=
submodules.end(); ++it)
988 if (it->second->name == SubmoduleName)
998 std::cout << this->
name <<
":\n";
999 std::cout <<
"ports:\n";
1001 std::cout <<
"connections:\n";
1003 std::cout <<
"submodules:\n";
1011 std::cout << this->
name <<
";\n";
1015 for(
unsigned j = 0; j < it->second->dst.size(); j++)
1017 std::cout << it->first->parent->name <<
"." << it->first->name <<
"->" << it->second->dst[j]->parent->name <<
"." << it->second->dst[j]->name <<
";\n";
1021 for(std::map<std::string,Module*>::iterator it =
submodules.begin(); it !=
submodules.end(); ++it)
1023 it->second->print_dot();
1029 for(std::map<std::string,Port*>::iterator it =
ports.begin(); it !=
ports.end(); ++it)
1030 std::cout << it->second->name <<
"\n";
1039 for(
unsigned j = 0; j < it->second->dst.size(); j++)
1041 std::cout << this->
name <<
"<-" << it->second->dst[j]->parent->name <<
";\n";
1049 for(std::map<std::string,Module*>::iterator it =
submodules.begin(); it !=
submodules.end(); ++it)
1051 std::cout << it->second->name <<
"\n";
1060 std::cout << it->second->name <<
"\n";
1065 static bool getmoduleport(std::string name, std::string* module, std::string* port)
1067 std::size_t dot_loc;
1068 if(std::string::npos != (dot_loc = name.find_first_of(
".")))
1070 *module = name.substr(0,dot_loc);
1072 *port = name.substr(dot_loc + 1);
1074 return (std::string::npos == port->find_first_of(
"."));
1077 void Module::addConfig(std::string name, std::vector<std::string> ConnectTo,
int contexts,
bool isElastic) {
1092 auto error = make_from_stream<cgrame_model_error>([&](
auto&& s) {
1093 s <<
"a config cell called " << c->
name <<
" already exists";
1099 std::vector<Port*> new_ports_to_connect_to;
1101 for (
unsigned i = 0; i < ConnectTo.size(); i++)
1105 throw make_from_stream<cgrame_model_error>([&](
auto&& s) {
1106 s <<
"Connection ERROR!(" << ConnectTo[i] <<
"): module and port do not exist\n";
1109 if (
dynamic_cast<const ConfigCell*
>(module)) {
1111 throw make_from_stream<cgrame_model_error>([&](
auto&& s) {
1112 s <<
"Connection ERROR!(" << this->
name <<
"): cannot connect a config cell to another config cell ("<< ConnectTo[i] <<
")\n";
1116 new_ports_to_connect_to.push_back(port);
1129 std::stringstream msg;
1130 msg <<
"Submodule with same name: " << m->
name <<
" already exists\n";
1152 std::stringstream msg;
1153 msg <<
"Could not find submodule: '" << m <<
"'\n";
1170 if (module_name ==
"this") {
1177 if (module == NULL) {
1178 throw make_from_stream<cgrame_model_error>([&](
auto&& s) {
1179 s << err_context <<
"\nMODULE NOT FOUND!(" << this->
name <<
1180 "): module not found ("<< module_name <<
")";
1187 std::string module_name;
1188 std::string port_name;
1191 if (!
getmoduleport(full_port_name, &module_name, &port_name)) {
1192 throw make_from_stream<cgrame_model_error>([&](
auto&& s) {
1193 s << err_context <<
"\nMODULE NOT FOUND!(" << this->
name <<
1194 "): incorrect module.port (" << full_port_name <<
") name";
1202 std::string module_name;
1203 std::string port_name;
1206 if (!
getmoduleport(full_port_name, &module_name, &port_name)) {
1207 throw make_from_stream<cgrame_model_error>([&](
auto&& s) {
1208 s << err_context<<
"\nPORT NOT FOUND!(" << this->
name <<
1209 "): incorrect module.port (" << full_port_name <<
") name";
1214 if (module == NULL) {
1215 throw make_from_stream<cgrame_model_error>([&](
auto&& s) {
1216 s << err_context <<
"\nmodule not found!(" << this->
name <<
1217 "): port not found ("<< port_name <<
1218 ") in module (" << module_name <<
")";
1221 if (module->
ports.find(port_name) == module->
ports.end()) {
1222 throw make_from_stream<cgrame_model_error>([&](
auto&& s) {
1223 s << err_context <<
"\nPORT NOT FOUND!(" << this->
name <<
1224 "): port not found ("<< port_name <<
1225 ") in module (" <<module->
name <<
")";
1228 return module->
ports[port_name];;
1243 const auto& print_context = [&](
auto&& s) {
1244 s <<
"Connection ERROR! Could not make connection \"" << name1
1245 <<
"\" to \""<< name2 <<
"\" within module \"" << this->
name <<
"\"";
1248 std::string context =
"Connection ERROR! Could not make connection \""
1249 + name1 +
"\" to \"" + name2 +
"\" within module \"" + this->
name +
"\"";
1267 throw make_from_stream<cgrame_model_error>([&](
auto&& s) {
1269 s <<
"\nConnection ERROR!(" << this->name <<
"): source port could not be found. port 1 ("<< name1 <<
") or port 2 ("<< name2 <<
") are wrong";
1277 }
else if ((port2->
pt ==
PORT_INPUT && module2 !=
this) ||
1281 throw make_from_stream<cgrame_model_error>([&](
auto&& s) {
1283 s <<
"\nConnection ERROR!(" << this->name <<
"): destination port could not be found. port 1 ("<< name1 <<
") or port 2 ("<< name2 <<
") are wrong";
1289 throw make_from_stream<cgrame_model_error>([&](
auto&& s) {
1291 s <<
"\nConnection ERROR!(" << this->name <<
"): source port and destination port do not have the same size. port 1 ("<< name1 <<
") size 1 ("<<port1->
size<<
") and port 2 ("<< name2 <<
") size 2 ("<<port2->
size<<
") ";
1298 for(
auto & d : c.second->dst)
1302 throw make_from_stream<cgrame_model_error>([&](
auto&& s) {
1304 s <<
"\nConnection ERROR! In module (" << this->name <<
"): destination(" << name2 <<
") destination port ( "<<dstport->
name <<
" ) already connected to (" << c.second->src->parent->name <<
"." << c.second->src->name <<
")" ;
1321 throw make_from_stream<cgrame_model_error>([&](
auto&& s) {
1322 print_context(s); s <<
"\nConnection ERROR! destination already added";
1335 std::cout <<
"New Connection:" <<
connections[srcport]->src->parent->name <<
"."
1337 <<
connections[srcport]->dst.back()->parent->name <<
"."
1338 <<
connections[srcport]->dst.back()->name <<
"\n";
1358 std::stringstream msg;
1359 msg <<
"Port " << portname <<
" already exists\n";
1369 ports[portname] = p;
1372 std::cout << this->
name <<
": added port - " << p->
name <<
"\n";
1383 addPort(portname, pt, parameterName, size);
1392 std::stringstream msg;
1393 msg <<
"Port " << portname <<
" already exists\n";
1404 ports[portname] = p;
1408 std::cout << this->
name <<
": added port - " << p->
name << p->
size <<
"\n";
1419 stream =
"upstream";
1423 stream =
"downstream";
1428 stream =
"upstream";
1430 std::stringstream msg;
1431 msg <<
"Port type is not supported for elastic\n";
1435 addPort(portname, pt, parameterName, size);
1436 addPort(portname +
"_valid_" + stream, valid_port, 1);
1437 addPort(portname +
"_stop_" + stream, stop_port, 1);
1448 stream =
"upstream";
1452 stream =
"downstream";
1457 stream =
"upstream";
1459 std::stringstream msg;
1460 msg <<
"Port type is not supported for elastic\n";
1465 addPort(portname +
"_valid_" + stream, valid_port, 1);
1466 addPort(portname +
"_stop_" + stream, stop_port, 1);
1474 std::string stream1;
1476 stream1 =
"upstream";
1478 stream1 =
"downstream";
1480 throw make_from_stream<cgrame_model_error>([&](
auto&& s) {
1481 s <<
"\nPORT NOT FOUND!(" << this->
name <<
"): incorrect module.port (" << name1 <<
")";
1486 std::string stream2;
1488 stream2 =
"upstream";
1490 stream2 =
"downstream";
1492 throw make_from_stream<cgrame_model_error>([&](
auto&& s) {
1493 s <<
"\nPORT NOT FOUND!(" << this->
name <<
"): incorrect module.port (" << name2 <<
")";
1499 addConnection(name1 +
"_valid_" + stream1, name2 +
"_valid_" + stream2,
false);
1500 addConnection(name2 +
"_stop_" + stream2, name1 +
"_stop_" + stream1,
false);
1507 std::stringstream msg;
1508 msg <<
"Parameter " << parameterName <<
" already exists\n";
1522 std::map<std::string, std::unique_ptr<MRRG>> subMRRGs;
1526 auto temp = std::unique_ptr<MRRG>(name_and_submod.second->createMRRG(II));
1527 subMRRGs[name_and_submod.first] = std::move(temp);
1532 auto& result = *result_ptr;
1536 for(
auto& name_and_port :
ports)
1538 for(
unsigned i = 0; i < II; i++)
1549 for(
auto& submod_name_and_mrrg : subMRRGs)
1551 for(
auto& nodes_in_cycle : submod_name_and_mrrg.second->nodes)
1553 for(
auto& name_and_node : nodes_in_cycle)
1558 auto& node = submod_name_and_mrrg.second->getNodeRef(name_and_node.second.get());
1559 node.name = submod_name_and_mrrg.first +
'.' + node.name;
1560 result.nodes[node.getContextNum()][node.name] = std::move(name_and_node.second);
1569 const auto& port = *port_and_connection.first;
1570 const auto& connection = *port_and_connection.second;
1575 const auto& src_module_name = port.parent->name;
1576 const auto& src_module_port_name = port.name;
1579 if (!connection.isInMRRG)
1583 for(
unsigned j = 0; j < connection.dst.size(); j++)
1585 const auto& dst_module_name = connection.dst[j]->parent->name;
1586 const auto& dst_module_port_name = connection.dst[j]->name;
1588 for(
unsigned k = 0; k < II; k++)
1591 for (
unsigned l = 0; l < II; l++){
1592 const auto& src_ndesc = result.getNode(k, ( src_module_name ==
name ?
"" : src_module_name +
'.' ) + src_module_port_name);
1593 const auto& dst_ndesc = result.getNode(l, ( dst_module_name ==
name ?
"" : dst_module_name +
'.' ) + dst_module_port_name);
1595 throw make_from_stream<cgrame_model_error>([&](
auto&& s) {
1596 s <<
"MRRG port not found for port (" << src_module_port_name<<
") in MODULE (" << src_module_name <<
")";
1600 throw make_from_stream<cgrame_model_error>([&](
auto&& s) {
1601 s <<
"MRRG port not found for port (" << dst_module_port_name<<
") in MODULE (" << dst_module_name <<
")";
1604 result.link(src_ndesc, dst_ndesc);
1607 const auto& src_ndesc = result.getNode(k, ( src_module_name ==
name ?
"" : src_module_name +
'.' ) + src_module_port_name);
1608 const auto& dst_ndesc = result.getNode(k, ( dst_module_name ==
name ?
"" : dst_module_name +
'.' ) + dst_module_port_name);
1610 throw make_from_stream<cgrame_model_error>([&](
auto&& s) {
1611 s <<
"MRRG port not found for port (" << src_module_port_name<<
") in MODULE (" << src_module_name <<
")";
1615 throw make_from_stream<cgrame_model_error>([&](
auto&& s) {
1616 s <<
"MRRG port not found for port (" << dst_module_port_name<<
") in MODULE (" << dst_module_name <<
")";
1619 result.link(src_ndesc, dst_ndesc);
1630 if (
name != submodName &&
parent !=
nullptr) {
1633 else if (
parent ==
nullptr) {
1639 std::string cName = submodName;
1653 cName = cParent->
name;
1654 cParent = cParent->
parent;
1655 while (cParent !=
nullptr) {
1662 xPos = rel_pos.
x + xPos*rel_pos.
w;
1663 yPos = rel_pos.
y + yPos*rel_pos.
h;
1665 cName = cParent->
name;
1666 cParent = cParent->
parent;
1668 return {
true, {xPos, yPos}};
1683 return {
false, {-1, -1}};
1692 std::string cName =
name;
1694 while (cParent !=
nullptr) {
1696 return{
false, {-1, -1}};
1700 xPos = rel_pos.x + xPos*rel_pos.w;
1701 yPos = rel_pos.y + yPos*rel_pos.h;
1703 cName = cParent->
name;
1704 cParent = cParent->
parent;
1706 return {
true, {xPos, yPos}};
1711 :
Module(name, loc, size, isElastic)
1733 std::cout <<
SET_INDENT <<
"assign out = enable ? in : {size{1'bZ}};\n";
1734 std::cout <<
SET_INDENT <<
"assign bidir_out = out;\n";
1740 nlohmann::json vjson;
1743 vjson[
"prefix"] =
"cgrame_";
1744 vjson[
"parameters"] = {};
1746 vjson[
"parameters"].push_back(parameter.first);
1754 moduleDefinition += std::string(
SET_INDENT) +
"assign out = enable ? in : bidir_in;\n";
1755 moduleDefinition += std::string(
SET_INDENT) +
"assign out_valid_downstream = enable ? in_valid_upstream : bidir_in_valid_upstream;\n";
1756 moduleDefinition += std::string(
SET_INDENT) +
"assign in_stop_upstream = enable ? bidir_out_stop_downstream : out_stop_downstream;\n";
1757 moduleDefinition += std::string(
SET_INDENT) +
"assign bidir_out = out;\n";
1758 moduleDefinition += std::string(
SET_INDENT) +
"assign bidir_out_valid_downstream = out_valid_downstream;\n";
1759 moduleDefinition += std::string(
SET_INDENT) +
"assign bidir_in_stop_upstream = in_stop_upstream;\n";
1761 moduleDefinition += std::string(
SET_INDENT) +
"assign out = enable ? in : bidir_in;\n";
1762 moduleDefinition += std::string(
SET_INDENT) +
"assign bidir_out = out;";
1764 vjson[
"definition"] = moduleDefinition;
1773 const std::map<
OpGraphOp*,std::set<MRRG::NodeDescriptor>>& mrrg_nodes_from_op_node,
1774 const std::map<
OpGraphVal*, std::set<MRRG::NodeDescriptor>>& mrrg_nodes_from_val_node
1776 const std::regex in_regex(
"\\.in$");
1777 const std::regex out_regex(
"\\.out$");
1779 (void)mrrg_nodes_from_op_node;
1785 for (
const auto& val_and_mrrg_nodes : mrrg_nodes_from_val_node) {
1786 for (
const auto& mrrg_node : val_and_mrrg_nodes.second) {
1787 while (mrrg_node->cycle >= valNodesByCycle.size()) {
1788 valNodesByCycle.push_back({});
1790 valNodesByCycle[mrrg_node->cycle][val_and_mrrg_nodes.first].insert(mrrg_node);
1795 int used_cycles = 0;
1796 for (
auto & mrrg_nodes_from_val_by_cycle : valNodesByCycle) {
1797 if (mrrg_nodes_from_val_by_cycle.empty()) {
1799 }
else if (mrrg_nodes_from_val_by_cycle.size() != 1) {
1803 const auto& mrrg_nodes =
begin(mrrg_nodes_from_val_by_cycle)->second;
1804 if (mrrg_nodes.size() != 1) {
1807 const auto& mrrg_node = **
begin(mrrg_nodes);
1808 const auto&
name = mrrg_node.getHierarchyQualifiedName();
1809 if (regex_search(
name, in_regex)) {
1812 }
else if (regex_search(
name, out_regex)) {
1829 auto& result = *result_ptr;
1830 for(
unsigned i = 0; i < II; i++)
1854 result.link(in, io);
1855 result.link(io, out);
1863 std::string elas =
isElastic ?
"elastic_" :
"";
1874 :
Module(name, loc, size, isElastic)
1893 addConnection(
"this.Context",
"IOPinConfig.Context",
false);
1894 addConnection(
"this.Context",
"RegInConfig.Context",
false);
1895 addConnection(
"this.Context",
"RegOutConfig.Context",
false);
1914 :
Module(name, loc, size)
1928 nlohmann::json vjson;
1931 vjson[
"prefix"] =
"cgrame_";
1932 vjson[
"parameters"] = {};
1934 vjson[
"parameters"].push_back(parameter.first);
1942 vjson[
"definition"] = moduleDefinition;
1947 :
Module(name, loc, size)
1956 std::cout <<
SET_INDENT <<
"// purposefully left blank\n";
1960 nlohmann::json vjson;
1963 vjson[
"prefix"] =
"cgrame_";
1964 vjson[
"parameters"] = {};
1966 vjson[
"parameters"].push_back(parameter.first);
1973 moduleDefinition +=
"// purposefully left blank\n";
1974 vjson[
"definition"] = moduleDefinition;
1980 :
Module(name, loc, size)
1981 , Function(Function)
1995 for (
unsigned i = 0; i <
Function.size(); i++)
2002 nlohmann::json vjson;
2005 vjson[
"prefix"] =
"cgrame_";
2006 vjson[
"parameters"] = {};
2008 vjson[
"parameters"].push_back(parameter.first);
2010 vjson[
"interface"] = {};
2011 for (
auto& port :
ports) {
2013 const auto ioport_copies = splitBidirPort(*port.second);
2014 vjson[
"interface"].push_back(ioport_copies.first.name);
2015 vjson[
"interface"].push_back(ioport_copies.second.name);
2017 std::string portName = port.second->getName();
2018 vjson[
"interface"].push_back(portName);
2023 std::string moduleDefinition;
2024 for (
auto& port :
ports) {
2025 moduleDefinition += makePortDeclaration(*port.second,
SET_INDENT);
2029 for (
unsigned i = 0; i <
Function.size(); i++)
2033 vjson[
"definition"] = moduleDefinition;
2048 :
Module(name, loc, size)
2049 , Function(Function)
2062 for (
unsigned i = 0; i <
Function.size(); i++)
2069 nlohmann::json vjson;
2072 vjson[
"prefix"] =
"cgrame_";
2073 vjson[
"parameters"] = {};
2075 vjson[
"parameters"].push_back(parameter.first);
2077 vjson[
"interface"] = {};
2078 for (
auto& port :
ports) {
2080 const auto ioport_copies = splitBidirPort(*port.second);
2081 vjson[
"interface"].push_back(ioport_copies.first.name);
2082 vjson[
"interface"].push_back(ioport_copies.second.name);
2084 std::string portName = port.second->getName();
2085 vjson[
"interface"].push_back(portName);
2090 std::string moduleDefinition;
2091 for (
auto& port :
ports) {
2092 moduleDefinition += makePortDeclaration(*port.second,
SET_INDENT);
2096 for (
unsigned i = 0; i <
Function.size(); i++)
2100 vjson[
"definition"] = moduleDefinition;
2116 , prototype(prototype)
2120 for (
unsigned i = 0; i < Ports.size(); i++)
2141 , l_contexts(contexts)
2154 std::cout <<
"module configCell_" + cellSize +
"b(ConfigIn, ConfigOut, Config_Clock, Config_Reset, select);\n";
2156 std::cout <<
" parameter size = " + cellSize +
";\n";
2158 std::cout <<
" input Config_Clock, Config_Reset, ConfigIn;\n";
2159 std::cout <<
" output ConfigOut;\n";
2160 std::cout <<
" output [size-1:0] select;\n";
2162 std::cout <<
" reg [size-1:0] temp;\n\n";
2163 std::cout <<
" always @(posedge Config_Clock, posedge Config_Reset)\n";
2164 std::cout <<
" if (Config_Reset)\n";
2165 std::cout <<
" temp = 0;\n";
2166 std::cout <<
" else\n";
2167 std::cout <<
" begin\n";
2168 std::cout <<
" temp = temp >> 1;\n";
2169 std::cout <<
" temp[size-1] = ConfigIn;\n";
2170 std::cout <<
" end\n";
2171 std::cout <<
" assign select = temp;\n";
2172 std::cout <<
" assign ConfigOut = temp[0];\n";
2173 std::cout <<
"endmodule\n";
2178 const auto port_is_new = [&](
auto&& port) {
auto& cp =
connected_ports;
return cp.end() == std::find(cp.begin(), cp.end(), port); };
2179 std::copy_if(new_ports.begin(), new_ports.end(), std::back_inserter(
connected_ports), port_is_new);
2182 int port_size = port->size;
2184 port_size = port->parent->parameterlist.at(port->parameter);
2193 auto context_size = (
parameterlist[
"contexts"] == 1) ?
"0" :
"$clog2(contexts)-1";
2194 nlohmann::json vjson;
2197 vjson[
"prefix"] =
"cgrame_";
2198 vjson[
"parameters"] = {};
2201 vjson[
"parameters"].push_back(parameter.first);
2203 vjson[
"interface"] = {};
2204 vjson[
"interface"].push_back(
"ConfigIn");
2205 vjson[
"interface"].push_back(
"ConfigOut");
2206 vjson[
"interface"].push_back(
"Config_Clock");
2207 vjson[
"interface"].push_back(
"Config_Reset");
2208 vjson[
"interface"].push_back(
"CGRA_Clock");
2209 vjson[
"interface"].push_back(
"CGRA_Reset");
2210 vjson[
"interface"].push_back(
"CGRA_Enable");
2211 if (
l_contexts > 1) vjson[
"interface"].push_back(
"Context");
2212 vjson[
"interface"].push_back(
"select");
2215 std::string moduleDefinition;
2216 moduleDefinition += std::string(
SET_INDENT) +
"input CGRA_Clock;\n";
2217 moduleDefinition += std::string(
SET_INDENT) +
"input CGRA_Reset;\n";
2218 moduleDefinition += std::string(
SET_INDENT) +
"input CGRA_Enable;\n";
2219 moduleDefinition += std::string(
SET_INDENT) +
"input ConfigIn;\n";
2220 moduleDefinition += std::string(
SET_INDENT) +
"input Config_Clock;\n";
2221 moduleDefinition += std::string(
SET_INDENT) +
"input Config_Reset;\n";
2222 if (
l_contexts > 1) moduleDefinition += std::string(
SET_INDENT) +
"input [" + context_size +
":0] Context;\n";
2223 moduleDefinition += std::string(
SET_INDENT) +
"output ConfigOut;\n";
2224 moduleDefinition += std::string(
SET_INDENT) +
"output [size-1:0] select;\n";
2225 moduleDefinition += std::string(
SET_INDENT) +
"reg [size-1:0] config_reg [contexts-1:0];\n\n";
2226 moduleDefinition += std::string(
SET_INDENT) +
"reg [contexts-1:0] context_counter = {size{1'b0}};\n\n";
2227 moduleDefinition += std::string(
SET_INDENT) +
"integer i;\n\n";
2229 moduleDefinition += std::string(
SET_INDENT) +
"always @(posedge Config_Clock, posedge Config_Reset)\n";
2230 moduleDefinition += std::string(
SET_DOUBLE_INDENT) +
"if (Config_Reset) begin\n";
2231 moduleDefinition += std::string(
SET_TRIPLE_INDENT) +
"for (i = 0; i < contexts; i = i+1) begin\n";
2232 moduleDefinition += std::string(
SET_QUAD_INDENT) +
"config_reg[i] <= 'd0;\n";
2236 moduleDefinition += std::string(
SET_TRIPLE_INDENT) +
"for (i = 0; i < contexts; i = i+1) begin\n";
2237 moduleDefinition += std::string(
SET_QUAD_INDENT) +
"if(i == 0) begin\n";
2240 moduleDefinition += std::string(
SET_PENTA_INDENT) +
"config_reg[i] <= {ConfigIn,config_reg[i][size-1:1]};\n";
2243 moduleDefinition += std::string(
SET_PENTA_INDENT) +
"config_reg[i] <= {config_reg[i-1][0],config_reg[i][size-1:1]};\n";
2246 moduleDefinition += std::string(
SET_PENTA_INDENT) +
"config_reg[i] <= ConfigIn;\n";
2249 moduleDefinition += std::string(
SET_PENTA_INDENT) +
"config_reg[i] <= config_reg[i-1];\n";
2256 moduleDefinition += std::string(
SET_INDENT) +
"assign select = config_reg[0];\n";
2257 moduleDefinition += std::string(
SET_INDENT) +
"assign ConfigOut = config_reg[contexts-1][0];";
2259 moduleDefinition += std::string(
SET_INDENT) +
"assign select = config_reg[Context];\n";
2260 moduleDefinition += std::string(
SET_INDENT) +
"assign ConfigOut = config_reg[contexts-1][0];";
2263 vjson[
"definition"] = moduleDefinition;
2288 auto context_size = (
parameterlist[
"contexts"] == 1) ?
"0" :
"$clog2(contexts)-1";
2289 nlohmann::json vjson;
2292 vjson[
"prefix"] =
"cgrame_";
2293 vjson[
"parameters"] = {};
2296 vjson[
"parameters"].push_back(parameter.first);
2298 vjson[
"interface"] = {};
2299 vjson[
"interface"].push_back(
"CGRA_Clock");
2300 vjson[
"interface"].push_back(
"CGRA_Reset");
2301 vjson[
"interface"].push_back(
"CGRA_Enable");
2302 vjson[
"interface"].push_back(
"Context_Used");
2303 vjson[
"interface"].push_back(
"Context");
2306 std::string moduleDefinition;
2307 moduleDefinition += std::string(
SET_INDENT) +
"input CGRA_Clock;\n";
2308 moduleDefinition += std::string(
SET_INDENT) +
"input CGRA_Reset;\n";
2309 moduleDefinition += std::string(
SET_INDENT) +
"input CGRA_Enable;\n";
2310 moduleDefinition += std::string(
SET_INDENT) +
"input [" + context_size +
":0] Context_Used;\n";
2311 moduleDefinition += std::string(
SET_INDENT) +
"output reg [" + context_size +
":0] Context;\n\n";
2312 moduleDefinition += std::string(
SET_INDENT) +
"integer i;\n\n";
2314 moduleDefinition += std::string(
SET_INDENT) +
"always @(posedge CGRA_Clock, posedge CGRA_Reset)\n";
2318 moduleDefinition += std::string(
SET_DOUBLE_INDENT) +
"else if (CGRA_Enable) begin\n";
2319 moduleDefinition += std::string(
SET_TRIPLE_INDENT) +
"if (Context < Context_Used) begin\n";
2320 moduleDefinition += std::string(
SET_QUAD_INDENT) +
"Context <= (Context+1);\n";
2323 moduleDefinition += std::string(
SET_QUAD_INDENT) +
"Context <= 'd0;\n";
2327 vjson[
"definition"] = moduleDefinition;
2333 return "contextcounter";
2343 l_contexts(contexts)
2362 bitConfig.
add(result, 0);
2368 return "contextcell";
2388 is.setstate(std::ios_base::failbit);