8#include "clang/Basic/Diagnostic.h"
14#define DEBUG_TYPE "HDL"
26 if (!isdigit(c))
return false;
44 if ((hp->
getopc()==hNode::hdlopsEnum::hVarAssign) &&
46 (hp->
child_list[0]->getopc() == hNode::hdlopsEnum::hVarref) &&
47 (hp->
child_list[0]->getname().find(
"_handle_")!=std::string::npos))
56 if ((hp->
getopc()==hNode::hdlopsEnum::hVardeclrn) &&
57 (hp->
getname().find(
"_handle_")!=std::string::npos))
59 if (hp->
getname() ==
"sc_process_handle")
return true;
60 if ((hp->
getopc()==hNode::hdlopsEnum::hBuiltinFunction) &&
61 (hp->
getname().find(
"create_method_process")!=std::string::npos))
73 (x->h_op == hNode::hdlopsEnum::hVardecl) ||
75 (x->h_op == hNode::hdlopsEnum::hReturnStmt) ||
76 (x->h_op == hNode::hdlopsEnum::hUnimpl));}), hp->
child_list.end() );
87 ((x->h_op==hNode::hdlopsEnum::hBinop) &&
88 (x->h_name==pbstring) || (x->h_name==sensop))
100 (((x->getopc()==hNode::hdlopsEnum::hVarAssign) || (x->getopc()==hNode::hdlopsEnum::hSensvar)) &&
102 (x->child_list[0]->getopc() == hNode::hdlopsEnum::hVarref) &&
103 (x->child_list[0]->getname().find(
"_handle_")!=std::string::npos))
112 ((x->getopc()==hNode::hdlopsEnum::hVardeclrn) &&
113 (x->getname().find(
"_handle_")!=std::string::npos))
121 ((x->h_op==hNode::hdlopsEnum::hCStmt) &&
122 (x->child_list.empty())) ||
124 ((x->h_op == hNode::hdlopsEnum::hVarref) && (x->h_name ==
"sensitive")) ||
125 (isMorF(x->h_op) && (x->h_name.find(strsccore) !=std::string::npos)) ||
126 ((x->h_op == hNode::hdlopsEnum::hNoop) &&
127 (x->h_name==arrsub)));}), hp->
child_list.end());
166 for_info.push_back(tmp);
173 if ((hlo->
h_op == hNode::hdlopsEnum::hVarAssign) &&
175 (hlo->
child_list[0]-> h_op == hNode::hdlopsEnum::hVarref) &&
176 (hlo->
child_list[1]->h_op == hNode::hdlopsEnum::hLiteral)) {
182 if ((hi->
h_op == hNode::hdlopsEnum::hBinop) &&
184 (hlo->
child_list[0]-> h_op == hNode::hdlopsEnum::hVarref) &&
185 (hlo->
child_list[1]->h_op == hNode::hdlopsEnum::hLiteral)) {
191 for_info.push_back(tmp);
200 for (
int i=0; i < for_info.size(); i++) {
201 if ((hp->
h_op == hNode::hdlopsEnum::hVarref) && (hp->
h_name == for_info[i].name)) {
203 hp->
h_op = hNode::hdlopsEnum::hLiteral;
221 if (hp == NULL)
return "";
222 if ((hp->
getopc() == hNode::hdlopsEnum::hBinop) && (hp->
getname() ==
"ARRAYSUBSCRIPT")) {
225 else if (hp->
getopc() == hNode::hdlopsEnum::hVarref) {
226 if (hp->
size() == 0) {
228 int delimix = tmpstr.find(fielddelim);
229 if (delimix != string::npos) {
230 hp->
set(tmpstr.substr(tmpstr.find(fielddelim)+fielddelim.size()));
231 return tmpstr.substr(0, tmpstr.find(fielddelim));
245 assert ((hp_orig->
h_op == hNode::hdlopsEnum::hBinop) && (hp_orig->
h_name == pbstring));
265 if (isMorF(hp->
h_op)) {
267 if (hpi->
h_op == hNode::hdlopsEnum::hUnop) {
268 std::size_t found = (hpi->
child_list[0]->h_name).find(qualnamedelim);
269 if ( found != std::string::npos) {
271 hNode::hdlopsEnum::hSenslist));
301 hp->
h_op = hNode::hdlopsEnum::hSensvar;
340 hp->
child_list.push_back(
new hNode(
"always", hNode::hdlopsEnum::hNoop));
343 if (!for_info.empty()) {
348 else hnewsens.back()->child_list.push_back(hp);
357 else if (isInitSensitem(hp)) {
361 else if ((hp->
h_op == hNode::hdlopsEnum::hForStmt) && (hp->
child_list.size() > 3)) {
363 for (
int forloopix = for_info.back().lo; forloopix < for_info.back().hi; forloopix+=for_info.back().step) {
364 for_info.back().curix = forloopix;
372 else if ((hp->
child_list[i]->h_op == hNode::hdlopsEnum::hForStmt) ||
373 (hp->
child_list[i]->h_op == hNode::hdlopsEnum::hCStmt))
379 else if (hp->
h_op == hNode::hdlopsEnum::hCStmt) {
384 else if (isMethodCall(hp)) {
387 hnewsens.push_back(
new hNode(
"METHOD ???", hNode::hdlopsEnum::hSenslist));
392 int threadsensitem = isThreadSensitem(hp);
393 if (threadsensitem >0 ) {
398 LLVM_DEBUG(llvm::dbgs() <<
"HDLHNode: found thread sens item " <<
"\n");
401 hpsens->
set(hNode::hdlopsEnum::hSensvar, threadsensitem == reset_async?
"ASYNC":
"SYNC");
403 hnewsens.push_back(
new hNode(
"METHOD ???", hNode::hdlopsEnum::hSenslist));
412 std::vector<for_info_t> for_info;
414 if (xconstructor==
nullptr)
return xconstructor;
419 {
int junk =2;
if (junk!=2) xconstructor->
dumphcode();}
431 if ( (xconstructor->
size() == 1) && (xconstructor->
child_list[0]->getopc()==hNode::hdlopsEnum::hCStmt)) {
494 void HDLConstructorHcode::UnrollBindingNotUsed(
hNodep &hp_orig, std::vector<for_info_t> &for_info) {
496 assert ((hp_orig->
h_op == hNode::hdlopsEnum::hBinop) && (hp_orig->
h_name == pbstring));
502 if (for_info.empty()) {
506 if (hp_orig->
child_list[0]->getopc() == hNode::hdlopsEnum::hVarref) {
510 hpb =
new hNode(submodport.substr(0, submodport.find(fielddelim)),
511 hNode::hdlopsEnum::hPortbinding);
512 hpb->
child_list.push_back(
new hNode(submodport.substr(submodport.find(fielddelim)+fielddelim.size()),
513 hNode::hdlopsEnum::hVarref));
517 hpb =
new hNode(submodport, hNode::hdlopsEnum::hPortbinding);
520 if (hp_orig->
child_list[1]->getopc() == hNode::hdlopsEnum::hVarref) {
522 hpb->
child_list.push_back(
new hNode(thismodsig, hNode::hdlopsEnum::hVarref));
536 string submodport{
"XXX"}, thismodsig{
"YYY"};
537 string submod{
"SUBMOD"};
540 if ((hsubmodport->
h_op == hNode::hdlopsEnum::hVarref) && (hsubmodport->
child_list.size() > 0)) {
552 hNodep hparent = hsubmodport;
553 std::vector<hNodep> hmodarrix;
555 while ((hportchild !=
nullptr) && (hportchild->
h_name == arrsub)) {
556 hmodarrix.push_back(hportchild->
child_list[1]);
557 if ((hportchild->
child_list[0]->h_op == hNode::hdlopsEnum::hVarref) &&
558 (hportchild->
child_list[0]->child_list.empty())) {
562 hparent = hportchild;
565 for (
hNodep hsubmodixname:hmodarrix) {
567 assert((hsubmodixname->h_op == hNode::hdlopsEnum::hVarref) &&
"Submodule index must be simple loop variable name");
568 string ixname = hsubmodixname->h_name;
569 for (
int i = 0; i < for_info.size(); i++) {
570 if (for_info[i].name == ixname) {
571 submod+=tokendelim+
to_string(for_info[i].curix);
576 if (hsubmodport->
child_list[0]->h_name == arrsub) {
580 else if (hsubmodport->
h_name == arrsub) {
613 hNodep hparent = hsubmodport;
614 std::vector<hNodep> hmodarrix;
616 while ((hportchild !=
nullptr) &&
617 ((hportchild->
h_name == arrsub) ||
618 ((hportchild->
h_op == hNode::hdlopsEnum::hVarref) &&
620 if (hportchild->
h_name == arrsub) {
621 hmodarrix.push_back(hportchild->
child_list[1]);
623 hparent = hportchild;
626 if ((hportchild !=
nullptr) && (hportchild->
h_op == hNode::hdlopsEnum::hVarref)) {
628 submod = hportchild->
h_name;
629 size_t found = submod.find(fielddelim);
630 if ( found != std::string::npos) {
631 hportchild->
h_name = submod.substr(found+fielddelim.size());
632 submod = submod.substr(0, found);
635 for (
hNodep hsubmodixname:hmodarrix) {
637 assert((hsubmodixname->h_op == hNode::hdlopsEnum::hVarref) &&
"Submodule index must be simple loop variable name");
638 string ixname = hsubmodixname->h_name;
639 for (
int i = 0; i < for_info.size(); i++) {
640 if (for_info[i].name == ixname) {
641 submod+=tokendelim+
to_string(for_info[i].curix);
646 hparent = hsubmodport;
648 while ((hportchild !=
nullptr) && (hportchild->
h_name != arrsub)) {
649 hparent = hportchild;
652 if (hportchild !=
nullptr) {
660 hNodep hpb =
new hNode( submod, hNode::hdlopsEnum::hPortbinding);
void set(hdlopsEnum h, string s="")
std::vector< hNodep > child_list
void UnrollSensitem(hNodep &hp_orig, std::vector< for_info_t > &for_info)
void UnrollBinding(hNodep &hp_orig, std::vector< for_info_t > &for_info)
bool SetupSenslist(hNodep hp)
void SubstituteIndex(hNodep &hp, std::vector< for_info_t > &for_info)
hNodep ProcessCXXConstructorHcode(hNodep xconstructor)
void PushRange(hNodep &hp, std::vector< for_info_t > &for_info)
void CleanupInitHcode(hNodep &hp)
bool isSimRelated(hNodep hp)
string ExtractModuleName(hNodep hp)
void PopRange(std::vector< for_info_t > &for_info)
void RemoveSCMethod(hNodep &hp)
hNodep HnodeDeepCopy(hNodep hp)
void HDLLoop(hNodep &hp, std::vector< for_info_t > &for_info)
std::vector< hNodep > hnewsens
std::string to_string(T *pointer)
bool is_numeric(string &s)