diff --git a/Makefile b/Makefile index 437766a1b31..8787e029eaf 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,7 @@ ENABLE_GHDL := 0 ENABLE_SLANG := 0 ENABLE_VERIFIC := 1 ENABLE_VERIFIC_SYSTEMVERILOG := 1 +VERIFIC_LINEFILE_INCLUDES_LOOPS := 1 ENABLE_VERIFIC_VHDL := 0 ENABLE_VERIFIC_HIER_TREE := 1 ENABLE_VERIFIC_SILIMATE_EXTENSIONS := 1 @@ -515,6 +516,9 @@ ifneq ($(wildcard $(VERIFIC_DIR)/hier_tree),) VERIFIC_COMPONENTS += hier_tree endif endif +ifeq ($(VERIFIC_LINEFILE_INCLUDES_LOOPS),1) +CXXFLAGS += -DVERIFIC_LINEFILE_INCLUDES_LOOPS +endif ifeq ($(ENABLE_VERIFIC_SYSTEMVERILOG),1) VERIFIC_COMPONENTS += verilog CXXFLAGS += -DVERIFIC_SYSTEMVERILOG_SUPPORT diff --git a/frontends/verific/decorate_loops.h b/frontends/verific/decorate_loops.h new file mode 100644 index 00000000000..acd3a2d9b4a --- /dev/null +++ b/frontends/verific/decorate_loops.h @@ -0,0 +1,76 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Claire Xenia Wolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ +#ifdef VERIFIC_LINEFILE_INCLUDES_LOOPS +/* + This Visitor decorates the AST with a loop ID attribute for all outer for loops. + All AST nodes contained within the subtree of an outer for-loop + have the same ID carried as an additional payload of the "linefile" struct. + The ID is unique accross the flat RTL module set, as it is computed before elaboration. + It is not unique per instance of the modules. + A further separation of cells belonging to a given loop instance is necessary by means of + connectivity analysis. + No "loop instance" information seems to exist to cluster those loops elements together unfortunately. +*/ +class DecorateLoopsVisitor : public VeriVisitor +{ + public: + DecorateLoopsVisitor() : VeriVisitor() {}; + ~DecorateLoopsVisitor() {}; + virtual void VERI_VISIT(VeriLoop, node) + { + // std::cout << "Loop in: " << (VeriLoop *)&node << " id: " << outerLoopId << std::endl; + if (loopStack.empty()) { + // We increase the loop count when we enter a new set of imbricated loops, + // That way we have a loop index for the outermost loop as we want to identify and group + // logic generated by imbricated loops + outerLoopId++; + } + loopStack.push((VeriLoop *)&node); + } + + void PreAction(VeriTreeNode & /*node*/) + { + // VeriNode *vnode = dynamic_cast(&node); + // std::cout << "Node pre: " << vnode << std::endl; + } + + virtual void PostAction(VeriTreeNode &node) + { + // std::cout << "Node post: " << (VeriTreeNode *)&node << std::endl; + if (loopStack.size()) { + if (loopStack.top() == (VeriLoop *)&node) { + loopStack.pop(); + std::cout << "Loop out: " << (VeriFor *)&node << std::endl; + return; + } + Verific::linefile_type linefile = (Verific::linefile_type)node.Linefile(); + // Unfortunately there is no good way to systematically copy certain AST attributes to the Netlist attributes like: + // VeriNode *vnode = dynamic_cast(&node); + // vnode->AddAttribute(" in_loop", new VeriIntVal(outerLoopId)); + // Instead using linefile struct to pass that information: + if (linefile) + linefile->SetInLoop(outerLoopId); + } + } + + private: + std::stack loopStack; + uint32_t outerLoopId = 0; +}; +#endif diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 761c80b9de5..833300fdeba 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -54,6 +54,9 @@ USING_YOSYS_NAMESPACE #include "VeriWrite.h" #include "VeriLibrary.h" #include "VeriExpression.h" +#ifdef VERIFIC_LINEFILE_INCLUDES_LOOPS +#include "VeriConstVal.h" +#endif #endif #ifdef VERIFIC_VHDL_SUPPORT @@ -104,6 +107,10 @@ using namespace Verific; #endif +#ifdef VERIFIC_LINEFILE_INCLUDES_LOOPS +#include "decorate_loops.h" +#endif + #ifdef YOSYS_ENABLE_VERIFIC YOSYS_NAMESPACE_BEGIN @@ -420,8 +427,14 @@ void VerificImporter::import_attributes(dict &att Att *attr; #ifdef VERIFIC_LINEFILE_INCLUDES_COLUMNS - if (obj->Linefile()) + if (obj->Linefile()) { attributes[ID::src] = stringf("%s:%d.%d-%d.%d", LineFile::GetFileName(obj->Linefile()), obj->Linefile()->GetLeftLine(), obj->Linefile()->GetLeftCol(), obj->Linefile()->GetRightLine(), obj->Linefile()->GetRightCol()); +#ifdef VERIFIC_LINEFILE_INCLUDES_LOOPS + if (uint32_t loopid = obj->Linefile()->GetInLoop()) { + attributes[RTLIL::escape_id("in_loop_" + std::to_string(loopid))] = std::to_string(loopid); + } +#endif + } #else if (obj->Linefile()) attributes[ID::src] = stringf("%s:%d", LineFile::GetFileName(obj->Linefile()), LineFile::GetLineNo(obj->Linefile())); @@ -2901,6 +2914,7 @@ std::set import_tops(const char* work, std::mapAccept(loop_visitor); + } +#endif + std::set top_mod_names; if (top.empty()) { import_all("work", &nl_todo, &verific_params, false, "");