Skip to content

Commit

Permalink
Merge pull request anikau31#35 from anikau31/integrate-port-matchers
Browse files Browse the repository at this point in the history
Integrate port matchers
  • Loading branch information
rseac committed Jan 28, 2020
2 parents 02e8e26 + 5eda941 commit 8a91639
Show file tree
Hide file tree
Showing 63 changed files with 2,928 additions and 1,284 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "tests/data/verilog-conversion"]
path = tests/data/verilog-conversion
url = git@github.com:zhuanhao-wu/systemc-clang-verilog-conversion.git
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ set(CMAKE_CXX_EXTENSIONS OFF)
# Make verbose on?
set(CMAKE_VERBOSE_MAKEFILE ON CACHE BOOL "ON")

# Maya
set(CMAKE_BUILD_TYPE RelWithDebInfo)
# end Maya

# SystemC-Clang versions
set(SCC_MAJOR_VERSION 1)
set(SCC_MINOR_VERSION ${SCC_MAJOR_VERSION}.1)
Expand Down
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,14 @@ It parses RTL constructs and some TLM 2.0 constructs.

### Python Tests for Verilog conversion

1. To enable the python tests, run cmake with the `-DENABLE_PYTHON_TESTS=on` flag. Note that `python 3` should be installed.
2. To install necessary packages listed in `requirements.txt`, run `pip -r requirements.txt` in the **repo** directory.
3. To run the python tests, switch to the `$SYSTEMC_CLANG_BUILD_DIR` build directory and run `ctest -R python --output` after the build completes.
1. In the **repo_** directory, use `git submodule update` to pull the Verilog conversion data.
2. To enable the python tests, run cmake with the `-DENABLE_PYTHON_TESTS=on` flag. Note that `python 3` should be installed.
3. To install necessary packages listed in `requirements.txt`, run `pip install -r requirements.txt` in the **repo** directory.
4. To run the python tests, switch to the `$SYSTEMC_CLANG_BUILD_DIR` build directory and run `ctest -R python --output` after the build completes.

#### Details
- To observe the failing tests, one can run the tests in `tests/verilog-conversion/` by running `pytest -s -v -q --tool-output`.
The `-s` option captures the standard output for the test, `-v` enables verbose mode, and `-q --tool-output` captures the output of the binary.

## Contact

Expand Down
7 changes: 1 addition & 6 deletions driver-xlat.cpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
#include "plugins/xlat/Xlat.h"
#include "PluginAction.h"

#include "SystemCClang.h"
//#include "TimeAnalysis.h"

#include <iostream>
using namespace scpar;
using namespace std;

#include "plugins/xlat/Xlat.h"

//using namespace clang::tooling;
int main(int argc, const char **argv) {
cout << "Plugin XLAT\n";
PluginAction<Xlat> pa(argc, argv);
Expand Down
31 changes: 14 additions & 17 deletions plugins/xlat/Xlat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@ bool Xlat::postFire() {
vector<ModuleDecl *> instanceVec =
model->getModuleInstanceMap()[mit->second];
for (size_t i = 0; i < instanceVec.size(); i++) {
hNodep h_module = new hNode(false);
os_ << "\nmodule " << mit->first << "\n";
string modname = mit->first + "_" + to_string(i);
hNodep h_modname = new hNode(modname, hNode::hdlopsEnum::hModule);
hNodep h_module = new hNode(modname, hNode::hdlopsEnum::hModule);
//hNodep h_modname = new hNode(modname, hNode::hdlopsEnum::hModule);

// Ports
hNodep h_ports = new hNode(false); // list of ports, signals
hNodep h_ports = new hNode(hNode::hdlopsEnum::hPortsigvarlist); // list of ports, signals
xlatport(instanceVec.at(i)->getIPorts(), hNode::hdlopsEnum::hPortin,
h_ports);
xlatport(instanceVec.at(i)->getOPorts(), hNode::hdlopsEnum::hPortout,
Expand All @@ -61,17 +61,17 @@ bool Xlat::postFire() {
xlatsig(instanceVec.at(i)->getSignals(), hNode::hdlopsEnum::hSigdecl,
h_ports);

h_module->child_list.push_back(h_modname);
//h_module->child_list.push_back(h_modname);
h_module->child_list.push_back(h_ports);

h_top = new hNode(false);
h_top = new hNode(hNode::hdlopsEnum::hProcesses);

// Processes
xlatproc(instanceVec.at(i)->getEntryFunctionContainer(), h_top, os_);

h_module->child_list.push_back(h_top);
h_module->print(xlatout);
delete h_module;
delete h_top; //h_module;
}
}
return true;
Expand All @@ -85,7 +85,7 @@ void Xlat::xlatport(ModuleDecl::portMapType pmap, hNode::hdlopsEnum h_op,
h_info->child_list.push_back(new hNode(get<0>(*mit), h_op));
os_ << "object name is " << get<0>(*mit) << "\n";
PortDecl *pd = get<1>(*mit);
hNodep h_typeinfo = new hNode(false);
hNodep h_typeinfo = new hNode(hNode::hdlopsEnum::hTypeinfo);
xlattype(pd->getTemplateType(), h_typeinfo); // sctypes, xlatout);//, os_);
h_info->child_list.push_back(h_typeinfo);
}
Expand All @@ -103,7 +103,7 @@ void Xlat::xlatsig(ModuleDecl::signalMapType pmap, hNode::hdlopsEnum h_op,
// xlatout << mit->first;
//Signal *pd = mit->second;
Signal *pd = get<1>(*mit);
hNodep h_typeinfo = new hNode(false);
hNodep h_typeinfo = new hNode(hNode::hdlopsEnum::hTypeinfo);
xlattype(pd->getTemplateTypes(), h_typeinfo); // xlatout);//, os_);
h_info->child_list.push_back(h_typeinfo);
}
Expand All @@ -128,24 +128,21 @@ void Xlat::xlatproc(scpar::vector<EntryFunctionContainer *> efv, hNodep &h_top,
llvm::raw_ostream &os) {
for (auto efc : efv) {
if (efc->getProcessType() == PROCESS_TYPE::METHOD) {
hNodep h_process = new hNode(false);
// [process name, process body]
h_process->child_list.push_back(
new hNode(efc->getName(), hNode::hdlopsEnum::hProcess));
hNodep h_process = new hNode(efc->getName(), hNode::hdlopsEnum::hProcess);
os_ << "process " << efc->getName() << "\n";
// Sensitivity list
hNodep h_senslist = new hNode(false);
hNodep h_senslist = new hNode(hNode::hdlopsEnum::hSenslist);
for (auto sensmap : efc->getSenseMap()) {

hNodep h_senspair = new hNode(false); // [ (sensvar name) (edge expr) ]
hNodep h_sensitem = new hNode(sensmap.first, hNode::hdlopsEnum::hSensvar);
hNodep h_senspair = new hNode(sensmap.first, hNode::hdlopsEnum::hSensvar); // [ sensvar name (edge expr) ]
//hNodep h_sensitem = new hNode(sensmap.first, hNode::hdlopsEnum::hSensvar);

// HP: There is a change here.
// Sensitivity map returns as its second argument a tuple.
// The tuple has two parameters: the edge (pos/neg) and the second is the MemberExpr*.
//
//
h_senspair->child_list.push_back(h_sensitem);
//h_senspair->child_list.push_back(h_sensitem);

string edgeval = get<0>(sensmap.second);

Expand All @@ -159,7 +156,7 @@ void Xlat::xlatproc(scpar::vector<EntryFunctionContainer *> efv, hNodep &h_top,
}
h_process->child_list.push_back(h_senslist);
CXXMethodDecl *emd = efc->getEntryMethod();
hNodep h_body = new hNode(false);
hNodep h_body; // = new hNode(hNode::hdlopsEnum::hCStmt);
XlatMethod xmethod(emd, h_body, os_); //, xlatout);
h_process->child_list.push_back(h_body);
h_top->child_list.push_back(h_process);
Expand Down
7 changes: 5 additions & 2 deletions plugins/xlat/Xlat.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@ using namespace hnode;
class Xlat : public SystemCConsumer {

public:
Xlat( CompilerInstance& ci, std::string topModule )
Xlat( CompilerInstance& ci, std::string topModule = "!none" )
: SystemCConsumer( ci, topModule ) {
}

Xlat ( ASTUnit *from_ast, std::string topModule = "!none" )
: SystemCConsumer(from_ast,topModule) {
}

bool postFire();
void xlatport(ModuleDecl::portMapType pmap, hNode::hdlopsEnum h_op, hNodep &h_info);
void xlatsig(ModuleDecl::signalMapType pmap, hNode::hdlopsEnum h_op, hNodep &h_info);
Expand Down
70 changes: 36 additions & 34 deletions plugins/xlat/XlatEntryMethod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,8 @@ bool XlatMethod::TraverseStmt(Stmt *stmt) {

bool XlatMethod::TraverseCompoundStmt(CompoundStmt* cstmt) {
// Traverse each statement and append it to the array
hNodep h_cstmt = new hNode(false);
h_cstmt->child_list.push_back(new hNode("", hNode::hdlopsEnum::hCStmt));

hNodep h_cstmt = new hNode(hNode::hdlopsEnum::hCStmt);

for (clang::Stmt* stmt : cstmt->body()) {
TRY_TO(TraverseStmt(stmt));
if (h_ret) {
Expand All @@ -134,14 +133,14 @@ bool XlatMethod::TraverseCompoundStmt(CompoundStmt* cstmt) {
}

bool XlatMethod::TraverseDeclStmt(DeclStmt * declstmt) {
hNodep h_varlist = new hNode(false);
hNodep h_varlist = new hNode(hNode::hdlopsEnum::hPortsigvarlist);
// from https://clang.llvm.org/doxygen/DeadStoresChecker_8cpp_source.html
for (auto *DI : declstmt->decls())
if (DI) {
auto *vardecl = dyn_cast<VarDecl>(DI);
if (!vardecl)
continue;
hNodep h_vardecl = new hNode(false);
hNodep h_vardecl = new hNode(vardecl->getName(), hNode::hdlopsEnum::hVardecl);
ProcessVarDecl(vardecl, h_vardecl);
h_varlist->child_list.push_back(h_vardecl);
}
Expand All @@ -150,9 +149,8 @@ bool XlatMethod::TraverseDeclStmt(DeclStmt * declstmt) {
}

bool XlatMethod::ProcessVarDecl( VarDecl * vardecl, hNodep &h_vardecl) {
h_vardecl->child_list.push_back(new hNode(vardecl->getName(), hNode::hdlopsEnum::hVardecl));
os_ << "ProcessVarDecl var name is " << vardecl->getName() << "\n";
hNodep h_typeinfo = new hNode(false);
hNodep h_typeinfo = new hNode( hNode::hdlopsEnum::hTypeinfo);
QualType q = vardecl->getType();
const Type *tp = q.getTypePtr();
os_ << "ProcessVarDecl type name is " << q.getAsString() << "\n";
Expand Down Expand Up @@ -182,16 +180,18 @@ bool XlatMethod::TraverseBinaryOperator(BinaryOperator* expr)
// SourceLocation *Loc = nullptr,
// bool isEvaluated = true) const;

hNodep h_binop = new hNode(false); // node to hold binop expr
hNodep h_binop = new hNode(expr->getOpcodeStr(), hNode::hdlopsEnum::hBinop); // node to hold binop expr
os_ << "in TraverseBinaryOperator, opcode is " << expr->getOpcodeStr() << "\n";

h_binop->child_list.push_back(new hNode(expr->getOpcodeStr(), hNode::hdlopsEnum::hBinop));

TRY_TO(TraverseStmt(expr->getLHS()));
h_binop->child_list.push_back(h_ret);

hNodep save_h_ret = h_ret;
TRY_TO(TraverseStmt(expr->getRHS()));
h_binop->child_list.push_back(h_ret);
if (h_ret == save_h_ret)
h_binop->child_list.push_back(new hNode(hNode::hdlopsEnum::hUnimpl));
else
h_binop->child_list.push_back(h_ret);

h_ret = h_binop;

Expand All @@ -201,13 +201,13 @@ bool XlatMethod::TraverseBinaryOperator(BinaryOperator* expr)

bool XlatMethod::TraverseUnaryOperator(UnaryOperator* expr)
{
os_ << "in TraverseUnaryOperatory expr node is \n";
expr->dump(os_);

hNodep h_unop = new hNode(false); // node to hold unop expr
os_ << "in TraverseUnaryOperatory expr node is \n";
expr->dump(os_);
auto opcstr = expr->getOpcode();
h_unop->child_list.push_back(new hNode(expr->getOpcodeStr(opcstr), hNode::hdlopsEnum::hUnop));
auto opcstr = expr->getOpcode();

hNodep h_unop = new hNode(expr->getOpcodeStr(opcstr), hNode::hdlopsEnum::hUnop); // node to hold unop expr

TRY_TO(TraverseStmt(expr->getSubExpr()));
h_unop->child_list.push_back(h_ret);

Expand Down Expand Up @@ -248,8 +248,7 @@ bool XlatMethod::TraverseDeclRefExpr(DeclRefExpr* expr)
bool XlatMethod::TraverseArraySubscriptExpr(ArraySubscriptExpr* expr) {
os_ << "In TraverseArraySubscriptExpr, tree follows\n";
expr->dump(os_);
hNodep h_arrexpr = new hNode(false);
h_arrexpr->child_list.push_back(new hNode("[]", hNode::hdlopsEnum::hBinop));
hNodep h_arrexpr = new hNode("ARRAYSUBSCRIPT", hNode::hdlopsEnum::hBinop);
TRY_TO(TraverseStmt(expr->getLHS()));
h_arrexpr->child_list.push_back(h_ret);
TRY_TO(TraverseStmt(expr->getRHS()));
Expand Down Expand Up @@ -287,7 +286,6 @@ bool XlatMethod::TraverseCXXMemberCallExpr(CXXMemberCallExpr *callexpr) {

else methodname = "NOOP";

hNode * h_callp = new hNode(false); // list to hold call expr node
hNode::hdlopsEnum opc;

os_ << "found " << methodname << "\n";
Expand All @@ -300,14 +298,16 @@ bool XlatMethod::TraverseCXXMemberCallExpr(CXXMemberCallExpr *callexpr) {
opc = hNode::hdlopsEnum::hNoop;
}

h_callp -> child_list.push_back(new hNode(methodname, opc));
hNode * h_callp = new hNode(methodname, opc); // list to hold call expr node

TRY_TO(TraverseStmt(arg)); // traverse the x in x.f(5)

if (h_ret) h_callp -> child_list.push_back(h_ret);

for (auto arg : callexpr->arguments()) {
hNodep save_h_ret = h_ret;
TRY_TO(TraverseStmt(arg));
if (h_ret) h_callp->child_list.push_back(h_ret);
if (h_ret != save_h_ret) h_callp->child_list.push_back(h_ret);
}
h_ret = h_callp;
return true;
Expand Down Expand Up @@ -335,19 +335,21 @@ bool XlatMethod::TraverseCXXOperatorCallExpr(CXXOperatorCallExpr * opcall) {
(isLogicalOp(opcall->getOperator()))) {
if (opcall->getNumArgs() == 2) {
os_ << "assignment or logical operator, 2 args\n";
hNodep h_assignop = new hNode (false); // node to hold assignment expr
h_assignop->child_list.push_back(new hNode("=", hNode::hdlopsEnum::hBinop));
hNodep h_assignop = new hNode ("=", hNode::hdlopsEnum::hBinop); // node to hold assignment expr
TRY_TO(TraverseStmt(opcall->getArg(0)));
h_assignop->child_list.push_back(h_ret);
hNodep save_h_ret = h_ret;
TRY_TO(TraverseStmt(opcall->getArg(1)));
h_assignop->child_list.push_back(h_ret);
if (h_ret == save_h_ret) h_assignop->child_list.push_back(new hNode(hNode::hdlopsEnum::hUnimpl));
else h_assignop->child_list.push_back(h_ret);
h_ret = h_assignop;
opcall->getArg(0)->dump(os_);
opcall->getArg(1)->dump(os_);
return true;
}
}
os_ << "not yet implemented operator call expr, opc is " << clang::getOperatorSpelling(opcall->getOperator()) << " num arguments " << opcall->getNumArgs() << " skipping\n";
h_ret = new hNode(hNode::hdlopsEnum::hUnimpl);
return true;
}

Expand All @@ -361,9 +363,8 @@ bool XlatMethod::TraverseMemberExpr(MemberExpr *memberexpr){
}

bool XlatMethod::TraverseIfStmt(IfStmt *ifs) {
hNodep h_ifstmt, h_ifc, h_ifthen, h_ifelse;
h_ifstmt = new hNode(false);
h_ifstmt->child_list.push_back(new hNode("", hNode::hdlopsEnum::hIfStmt));
hNodep h_ifstmt, h_ifc = NULL, h_ifthen = NULL, h_ifelse = NULL;
h_ifstmt = new hNode(hNode::hdlopsEnum::hIfStmt);
if (ifs->getConditionVariable()) {
// Variable declarations are not allowed in if conditions
os_ << "Variable declarations are not allowed in if conditions, skipping\n";
Expand All @@ -374,13 +375,14 @@ bool XlatMethod::TraverseIfStmt(IfStmt *ifs) {
h_ifc = h_ret;
}
TRY_TO(TraverseStmt(ifs->getThen()));
h_ifthen = h_ret;
if (h_ret != h_ifc) // unchanged if couldn't translate the then clause
h_ifthen = h_ret;

if (ifs->getElse()) {
TRY_TO(TraverseStmt(ifs->getElse()));
h_ifelse = h_ret;
if ((h_ret != h_ifc) && (h_ret != h_ifthen))
h_ifelse = h_ret;
}
else h_ifelse = NULL;
h_ifstmt->child_list.push_back(h_ifc);
h_ifstmt->child_list.push_back(h_ifthen);
if(h_ifelse) h_ifstmt->child_list.push_back(h_ifelse);
Expand All @@ -391,8 +393,7 @@ bool XlatMethod::TraverseIfStmt(IfStmt *ifs) {
bool XlatMethod::TraverseForStmt(ForStmt *fors) {
hNodep h_forstmt, h_forinit, h_forcond, h_forinc, h_forbody;
os_ << "For stmt\n";
h_forstmt = new hNode(false);
h_forstmt->child_list.push_back(new hNode("", hNode::hdlopsEnum::hForStmt));
h_forstmt = new hNode(hNode::hdlopsEnum::hForStmt);
if (isa<CompoundStmt>(fors->getInit()))
os_ << "Compound stmt not handled in for init, skipping\n";
else TRY_TO(TraverseStmt(fors->getInit()));
Expand All @@ -401,6 +402,8 @@ bool XlatMethod::TraverseForStmt(ForStmt *fors) {
h_forcond = h_ret;
TRY_TO(TraverseStmt(fors->getInc()));
h_forinc = h_ret;
os_ << "For loop body\n";
fors->getBody()->dump(os_);
TRY_TO(TraverseStmt(fors->getBody()));
h_forbody = h_ret;
h_forstmt->child_list.push_back(h_forinit);
Expand All @@ -417,8 +420,7 @@ bool XlatMethod::TraverseForStmt(ForStmt *fors) {
bool XlatMethod::TraverseWhileStmt(WhileStmt *whiles) {
hNodep h_whilestmt, h_whilecond, h_whilebody;
os_ << "While stmt\n";
h_whilestmt = new hNode(false);
h_whilestmt->child_list.push_back(new hNode("", hNode::hdlopsEnum::hWhileStmt));
h_whilestmt = new hNode(hNode::hdlopsEnum::hWhileStmt);
if (whiles->getConditionVariable()) {
os_ << "Variable declarations not handled in while condition, skipping\n";
}
Expand Down
Loading

0 comments on commit 8a91639

Please sign in to comment.