From 98fccd6ee7c019e32225f0122c041847944efd1e Mon Sep 17 00:00:00 2001 From: juehv Date: Wed, 23 Nov 2016 13:57:15 +0100 Subject: add support for non event state machines --- src/uscxml/transform/ChartToVHDL.cpp | 235 +++++++++++++++++++---------------- 1 file changed, 130 insertions(+), 105 deletions(-) diff --git a/src/uscxml/transform/ChartToVHDL.cpp b/src/uscxml/transform/ChartToVHDL.cpp index 9228a2d..052d78f 100644 --- a/src/uscxml/transform/ChartToVHDL.cpp +++ b/src/uscxml/transform/ChartToVHDL.cpp @@ -176,13 +176,13 @@ void ChartToVHDL::writeTypes(std::ostream &stream) { stream << " downto 0);" << std::endl; std::list eventNames = _eventTrie.getWordsWithPrefix(""); - stream << " type event_type is ( hwe_null, "; - seperator = ""; + stream << " type event_type is ( hwe_null"; + seperator = ", "; for (std::list::iterator eventIter = eventNames.begin(); eventIter != eventNames.end(); eventIter++) { stream << seperator << "hwe_" << escapeMacro((*eventIter)->value); - seperator = ", "; + // seperator = ", "; } stream << " );" << std::endl; @@ -431,7 +431,7 @@ void ChartToVHDL::writeTestbench(std::ostream &stream) { stream << " if (completed_o = '1') then" << std::endl; if (!passStateNo.empty()) { stream << " assert (state_active_" << passStateNo; - stream << "_sig = '1') report \"Complted with errors\" severity error;" << std::endl; + stream << "_sig = '1') report \"Completed with errors\" severity error;" << std::endl; } stream << " -- stop simulation" << std::endl; stream << " finish(0);" << std::endl; // use 0 for ctest @@ -508,6 +508,7 @@ void ChartToVHDL::writeEventController(std::ostream &stream) { stream << "architecture behavioral of event_controller is " << std::endl; stream << std::endl; + // Add signals and components stream << "signal rst : std_logic;" << std::endl; stream << "signal micro_stepper_en : std_logic;" << std::endl; @@ -529,128 +530,152 @@ void ChartToVHDL::writeEventController(std::ostream &stream) { stream << "begin" << std::endl; stream << std::endl; - // system signal mapping - stream << "rst <= rst_i;" << std::endl; - stream << "micro_stepper_en_o <= micro_stepper_en;" << std::endl; - stream << "event_o <= event_bus;" << std::endl; - stream << "event_we_o <= event_we;" << std::endl; - stream << std::endl; - // stall management - stream << "-- stalling microstepper" << std::endl; - stream << "micro_stepper_en <= completed_sig or not ( '0' "; - for (auto state : _states) { - - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << std::endl << " or entry_set_" << ATTR(state, "documentOrder") - << "_i"; + // check if there is SUPPORTED executable content + bool foundSupportedExecContent = false; + for (auto exContentElem : _execContent) { + if (filterSupportedExecContent(exContentElem)) { + foundSupportedExecContent = true; + break; } + } + if (!foundSupportedExecContent) { + // set output correct if there is no supported excontent + + stream << "-- no supported executable content found" << std::endl; + stream << "-- state machine may not run correctly" << std::endl; + stream << "-- setting output lines to fulfil dummy functionality" << std::endl; + stream << "micro_stepper_en_o <= '1';" << std::endl; + stream << "event_o <= hwe_null;" << std::endl; + stream << "event_we_o <= '0';" << std::endl; + stream << std::endl; + } else { + // system signal mapping + stream << "rst <= rst_i;" << std::endl; + stream << "micro_stepper_en_o <= micro_stepper_en;" << std::endl; + stream << "event_o <= event_bus;" << std::endl; + stream << "event_we_o <= event_we;" << std::endl; + stream << std::endl; + + // stall management + stream << "-- stalling microstepper" << std::endl; + stream << "micro_stepper_en <= completed_sig or not ( '0' "; + for (auto state : _states) { + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << std::endl << " or entry_set_" << ATTR(state, "documentOrder") + << "_i"; + } - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << std::endl << " or exit_set_" << ATTR(state, "documentOrder") - << "_i"; + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << std::endl << " or exit_set_" << ATTR(state, "documentOrder") + << "_i"; + } } - } - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << std::endl << " or transition_set_" << ATTR(transition, "postFixOrder") - << "_i"; + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << std::endl << " or transition_set_" << ATTR(transition, "postFixOrder") + << "_i"; + } } - } - stream << ");" << std::endl; - stream << std::endl; - - // sequential code operation - stream << "-- seq code block " << std::endl; - stream << "ex_content_block : process (clk, rst) " << std::endl; - stream << "begin" << std::endl; - stream << " if rst = '1' then" << std::endl; - for (int i = 0; i < _execContent.size(); i++) { - stream << " done_" << toStr(i) << "_sig <= '0';" << std::endl; - } - stream << " event_bus <= hwe_null;" << std::endl; - stream << " event_we <= '0';" << std::endl; - stream << " cmpl_buf <= '0';" << std::endl; - stream << " completed_sig <= '0';" << std::endl; - stream << " elsif rising_edge(clk) then" << std::endl; - - stream << " if micro_stepper_en = '1' then" << std::endl; - stream << " cmpl_buf <= '0' ;" << std::endl; - stream << " else" << std::endl; - stream << " cmpl_buf <= seq_" << toStr(_execContent.size() - 1) - << "_sig;" << std::endl; - stream << " end if;" << std::endl; - stream << " completed_sig <= cmpl_buf;" << std::endl << std::endl; + stream << ");" << std::endl; + stream << std::endl; + + // sequential code operation + stream << "-- seq code block " << std::endl; + stream << "ex_content_block : process (clk, rst) " << std::endl; + stream << "begin" << std::endl; + stream << " if rst = '1' then" << std::endl; + for (int i = 0; i < _execContent.size(); i++) { + stream << " done_" << toStr(i) << "_sig <= '0';" << std::endl; + } + stream << " event_bus <= hwe_null;" << std::endl; + stream << " event_we <= '0';" << std::endl; + stream << " cmpl_buf <= '0';" << std::endl; + stream << " completed_sig <= '0';" << std::endl; + stream << " elsif rising_edge(clk) then" << std::endl; + + stream << " if micro_stepper_en = '1' then" << std::endl; + stream << " cmpl_buf <= '0' ;" << std::endl; + stream << " else" << std::endl; + stream << " cmpl_buf <= seq_" << toStr(_execContent.size() - 1) + << "_sig;" << std::endl; + stream << " end if;" << std::endl; + stream << " completed_sig <= cmpl_buf;" << std::endl << std::endl; - size_t i = 0; - std::string seperator = " "; - for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { - DOMElement *exContentElem = *ecIter; + size_t i = 0; + std::string seperator = " "; + for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { + DOMElement *exContentElem = *ecIter; - if (filterSupportedExecContent(exContentElem)) { + if (filterSupportedExecContent(exContentElem)) { - stream << seperator << "if start_" << toStr(i) << "_sig = '1' then" - << std::endl; - stream << " event_bus <= hwe_" << escapeMacro(ATTR(exContentElem, "event")) - << ";" << std::endl; - stream << " done_" << toStr(i) << "_sig <= '1';" << std::endl; - stream << " event_we <= '1';" << std::endl; - seperator = " els"; + stream << seperator << "if start_" << toStr(i) << "_sig = '1' then" + << std::endl; + stream << " event_bus <= hwe_" << escapeMacro(ATTR(exContentElem, "event")) + << ";" << std::endl; + stream << " done_" << toStr(i) << "_sig <= '1';" << std::endl; + stream << " event_we <= '1';" << std::endl; + seperator = " els"; + } } - } - stream << " elsif micro_stepper_en = '1' then" << std::endl; - i = 0; - //for (auto exContentElem : _execContent) { - for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { - DOMElement *exContentElem = *ecIter; - if (filterSupportedExecContent(exContentElem)) { - stream << " done_" << toStr(i) << "_sig <= '0';" << std::endl; + stream << " elsif micro_stepper_en = '1' then" << std::endl; + i = 0; + //for (auto exContentElem : _execContent) { + for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { + DOMElement *exContentElem = *ecIter; + if (filterSupportedExecContent(exContentElem)) { + stream << " done_" << toStr(i) << "_sig <= '0';" << std::endl; + } } - } - stream << " event_we <= '0';" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << "end process;" << std::endl; - stream << std::endl; + stream << " event_we <= '0';" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << "end process;" << std::endl; + stream << std::endl; - i = 0; - for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { - // start lines - stream << "start_" << toStr(i) << "_sig <= " - << getLineForExecContent(*ecIter) << " and " - << "not done_" << toStr(i) << "_sig"; + i = 0; + for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { + // start lines + stream << "start_" << toStr(i) << "_sig <= " + << getLineForExecContent(*ecIter) << " and " + << "not done_" << toStr(i) << "_sig"; - // if not needed, since seq_0_sig is hard coded as '1'. + // if not needed, since seq_0_sig is hard coded as '1'. // if (i != 0) { // if not first element - stream << " and seq_" << toStr(i) << "_sig"; + stream << " and seq_" << toStr(i) << "_sig"; // } - stream << ";" << std::endl; - - } + stream << ";" << std::endl; - stream << "seq_0_sig <= '1';" << std::endl; + } - if (_execContent.size() > 1) { - i = 0; - for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { - // prevent writing seq_0_sig since this should be hardcoded to '1' - if (i != 0) { - // seq lines (input if process i is in seqence now) - stream << "seq_" << toStr(i) << "_sig <= " - << "done_" << toStr(i - 1) << "_sig or " - << "( not " - << getLineForExecContent(*ecIter); - stream << " and seq_" << toStr(i - 1) << "_sig"; - stream << " );" << std::endl; + stream << "seq_0_sig <= '1';" << std::endl; + + if (_execContent.size() > 1) { + i = 0; + for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { + // prevent writing seq_0_sig since this should be hardcoded to '1' + if (i != 0) { + // seq lines (input if process i is in seqence now) + stream << "seq_" << toStr(i) << "_sig <= " + << "done_" << toStr(i - 1) << "_sig or " + << "( not " + << getLineForExecContent(*ecIter); + stream << " and seq_" << toStr(i - 1) << "_sig"; + stream << " );" << std::endl; + } } } + stream << std::endl; } - stream << std::endl; - stream << "end behavioral; " << std::endl; - stream << "-- END Event Controller Logic" << std::endl; - stream << std::endl; + stream << "end behavioral; " << + std::endl; + stream << "-- END Event Controller Logic" << + std::endl; + stream << + std::endl; } std::string ChartToVHDL::getLineForExecContent(const DOMNode *elem) { -- cgit v0.12 From 7804fa03f76326a3bf988dcee20b7052db601ebf Mon Sep 17 00:00:00 2001 From: juehv Date: Wed, 23 Nov 2016 13:58:39 +0100 Subject: rename filter function accourding to coding style --- src/uscxml/transform/ChartToVHDL.cpp | 8 ++++---- src/uscxml/transform/ChartToVHDL.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/uscxml/transform/ChartToVHDL.cpp b/src/uscxml/transform/ChartToVHDL.cpp index 052d78f..3100ec3 100644 --- a/src/uscxml/transform/ChartToVHDL.cpp +++ b/src/uscxml/transform/ChartToVHDL.cpp @@ -138,7 +138,7 @@ void ChartToVHDL::findEvents() { } -bool ChartToVHDL::filterSupportedExecContent(DOMElement *execContentElement) { +bool ChartToVHDL::isSupportedExecContent(DOMElement *execContentElement) { return (TAGNAME(execContentElement) == XML_PREFIX(_scxml).str() + "raise" || TAGNAME(execContentElement) == XML_PREFIX(_scxml).str() + "send"); } @@ -534,7 +534,7 @@ void ChartToVHDL::writeEventController(std::ostream &stream) { // check if there is SUPPORTED executable content bool foundSupportedExecContent = false; for (auto exContentElem : _execContent) { - if (filterSupportedExecContent(exContentElem)) { + if (isSupportedExecContent(exContentElem)) { foundSupportedExecContent = true; break; } @@ -608,7 +608,7 @@ void ChartToVHDL::writeEventController(std::ostream &stream) { for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { DOMElement *exContentElem = *ecIter; - if (filterSupportedExecContent(exContentElem)) { + if (isSupportedExecContent(exContentElem)) { stream << seperator << "if start_" << toStr(i) << "_sig = '1' then" << std::endl; @@ -624,7 +624,7 @@ void ChartToVHDL::writeEventController(std::ostream &stream) { //for (auto exContentElem : _execContent) { for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { DOMElement *exContentElem = *ecIter; - if (filterSupportedExecContent(exContentElem)) { + if (isSupportedExecContent(exContentElem)) { stream << " done_" << toStr(i) << "_sig <= '0';" << std::endl; } } diff --git a/src/uscxml/transform/ChartToVHDL.h b/src/uscxml/transform/ChartToVHDL.h index 4b047da..b6c7853 100644 --- a/src/uscxml/transform/ChartToVHDL.h +++ b/src/uscxml/transform/ChartToVHDL.h @@ -227,7 +227,7 @@ protected: private: std::string getLineForExecContent(const XERCESC_NS::DOMNode *elem); - bool filterSupportedExecContent(XERCESC_NS::DOMElement *execContentElement); + bool isSupportedExecContent(XERCESC_NS::DOMElement *execContentElement); }; } -- cgit v0.12 From cf4b85f7ed8deb8c74cc11690e7e20da3c5f595c Mon Sep 17 00:00:00 2001 From: juehv Date: Wed, 23 Nov 2016 17:21:23 +0100 Subject: add test for testing vhdl spontanious transition aber event transitions --- test/w3c/ecma/test145.scxml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 test/w3c/ecma/test145.scxml diff --git a/test/w3c/ecma/test145.scxml b/test/w3c/ecma/test145.scxml new file mode 100644 index 0000000..b0fdba6 --- /dev/null +++ b/test/w3c/ecma/test145.scxml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v0.12 From e65f2a4a9162d208c0a66f321741201187cda0b8 Mon Sep 17 00:00:00 2001 From: juehv Date: Wed, 23 Nov 2016 17:21:57 +0100 Subject: remove unnessesary vcd generation --- test/ctest/scripts/run_generated_test.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/ctest/scripts/run_generated_test.cmake b/test/ctest/scripts/run_generated_test.cmake index 7057bd0..b91d4f2 100644 --- a/test/ctest/scripts/run_generated_test.cmake +++ b/test/ctest/scripts/run_generated_test.cmake @@ -44,9 +44,9 @@ if (${TARGETLANG} STREQUAL "vhdl") endif () message(STATUS "time for transforming to binary") - message(STATUS "${GHDL_BIN} -r ${VHDL_TESTBENCH_NAME} --vcd=${VHDL_TESTBENCH_NAME}.vcd") + message(STATUS "${GHDL_BIN} -r ${VHDL_TESTBENCH_NAME}") execute_process( - COMMAND time -p ${GHDL_BIN} -r ${VHDL_TESTBENCH_NAME} --vcd=${VHDL_TESTBENCH_NAME}.vcd + COMMAND time -p ${GHDL_BIN} -r ${VHDL_TESTBENCH_NAME} WORKING_DIRECTORY ${OUTDIR} RESULT_VARIABLE CMD_RESULT) if (CMD_RESULT) message(FATAL_ERROR "Error running ghdl ${GHDL_BIN}: ${CMD_RESULT}") -- cgit v0.12 From 7008bee60413d70e272650d01844a116bd45bcdb Mon Sep 17 00:00:00 2001 From: juehv Date: Wed, 23 Nov 2016 17:22:34 +0100 Subject: add a integer to binary string function --- src/uscxml/util/String.cpp | 289 +++++++++++++++++++++++++-------------------- src/uscxml/util/String.h | 13 +- 2 files changed, 168 insertions(+), 134 deletions(-) diff --git a/src/uscxml/util/String.cpp b/src/uscxml/util/String.cpp index 6a80756..2183ba8 100644 --- a/src/uscxml/util/String.cpp +++ b/src/uscxml/util/String.cpp @@ -25,174 +25,203 @@ namespace uscxml { #define ISWHITESPACE(char) (isspace(char)) -std::string escapeMacro(std::string const &s) { - // inspired by http://stackoverflow.com/questions/2417588/escaping-a-c-string - std::string returnValue=""; - std::string specialChars=""; - for (std::string::const_iterator iter = s.begin(), end = s.end(); iter != end; ++iter) { - char c = *iter; - if (('0' <= c && c <= '9') || ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || c == '_') { - returnValue += c; - } else { - specialChars += c; + std::string escapeMacro(std::string const &s) { + // inspired by http://stackoverflow.com/questions/2417588/escaping-a-c-string + std::string returnValue = ""; + std::string specialChars = ""; + for (std::string::const_iterator iter = s.begin(), end = s.end(); iter != end; ++iter) { + char c = *iter; + if (('0' <= c && c <= '9') || ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || c == '_') { + returnValue += c; + } else { + specialChars += c; + } } + if (!specialChars.empty()) { + // http://www.cplusplus.com/reference/functional/hash/ + // returns the same result for a given string within one execution + std::hash strHash; + returnValue += "_"; + returnValue += strHash(specialChars); + } + return returnValue; } - if (!specialChars.empty()) { - // http://www.cplusplus.com/reference/functional/hash/ - // returns the same result for a given string within one execution - std::hash strHash; - returnValue += "_"; - returnValue += strHash(specialChars); - } - return returnValue; -} - -std::list tokenize(const std::string& line, const char sep, bool trimWhiteSpace) { - std::list tokens; - - // appr. 3x faster than stringstream - size_t start = 0; - for (size_t i = 0; i < line.size(); i++) { - if (line[i] == sep || (trimWhiteSpace && ISWHITESPACE(line[i]))) { - if (i > 0 && start < i) { - tokens.push_back(line.substr(start, i - start)); - } - while(line[i] == sep || (trimWhiteSpace && ISWHITESPACE(line[i]))) { - i++; // skip multiple occurences of seperator and whitespaces + + std::string toBinStr(size_t val, size_t margin) { + // inspired by http://www.cplusplus.com/forum/general/65862/ + + // mask has only the leftmost bit set. + size_t mask = 1u << (std::numeric_limits::digits - 1); + + // skip leading bits that are not set. + while (0 == (val & mask) && mask != 0) + mask >>= 1; // shift all bits to the right by 1 + + std::string binStr; + binStr.reserve(std::numeric_limits::digits + 1); + + do { + // add a '1' or '0' depending the current bit. + binStr += static_cast(val & mask) + '0'; + + } while ((mask >>= 1) != 0); // next bit, when mask is 0 we've processed all bits + + // fill with leading 0 + if (binStr.size() < margin) { + for (size_t i = 0; i < (margin - binStr.size()); i++) { + binStr = "0" + binStr; } - start = i; - } else if (i + 1 == line.size()) { - tokens.push_back(line.substr(start, i + 1 - start)); } + + return binStr; } - return tokens; -} + std::list tokenize(const std::string &line, const char sep, bool trimWhiteSpace) { + std::list tokens; + + // appr. 3x faster than stringstream + size_t start = 0; + for (size_t i = 0; i < line.size(); i++) { + if (line[i] == sep || (trimWhiteSpace && ISWHITESPACE(line[i]))) { + if (i > 0 && start < i) { + tokens.push_back(line.substr(start, i - start)); + } + while (line[i] == sep || (trimWhiteSpace && ISWHITESPACE(line[i]))) { + i++; // skip multiple occurences of seperator and whitespaces + } + start = i; + } else if (i + 1 == line.size()) { + tokens.push_back(line.substr(start, i + 1 - start)); + } + } + + return tokens; + } -std::string spaceNormalize(const std::string& text) { - std::stringstream content; + std::string spaceNormalize(const std::string &text) { + std::stringstream content; #if 1 - // 195ms with test-performance-events.scml - std::string seperator; - - size_t start = 0; - for (size_t i = 0; i < text.size(); i++) { - if (isspace(text[i])) { - if (i > 0 && start < i) { - content << seperator << text.substr(start, i - start); - seperator = " "; + // 195ms with test-performance-events.scml + std::string seperator; + + size_t start = 0; + for (size_t i = 0; i < text.size(); i++) { + if (isspace(text[i])) { + if (i > 0 && start < i) { + content << seperator << text.substr(start, i - start); + seperator = " "; + } + while (isspace(text[++i])); // skip whitespaces + start = i; + } else if (i + 1 == text.size()) { + content << seperator << text.substr(start, i + 1 - start); } - while(isspace(text[++i])); // skip whitespaces - start = i; - } else if (i + 1 == text.size()) { - content << seperator << text.substr(start, i + 1 - start); } - } // std::cerr << ">>" << content.str() << "<<" << std::endl; #else -// 291ms with test-performance-events.scml - std::istringstream iss(text); - std::string seperator; - do { - std::string token; - iss >> token; - if (token.length() > 0) { - content << seperator << token; - seperator = " "; - } - } while (iss); + // 291ms with test-performance-events.scml + std::istringstream iss(text); + std::string seperator; + do { + std::string token; + iss >> token; + if (token.length() > 0) { + content << seperator << token; + seperator = " "; + } + } while (iss); #endif - return content.str(); -} + return content.str(); + } // see: http://www.w3.org/TR/scxml/#EventDescriptors -bool nameMatch(const std::string& eventDescs, const std::string& eventName) { + bool nameMatch(const std::string &eventDescs, const std::string &eventName) { #if 1 - if(eventDescs.length() == 0 || eventName.length() == 0) - return false; + if (eventDescs.length() == 0 || eventName.length() == 0) + return false; - // naive case of single descriptor and exact match - if (boost::iequals(eventDescs, eventName)) - return true; + // naive case of single descriptor and exact match + if (boost::iequals(eventDescs, eventName)) + return true; - size_t start = 0; - std::string eventDesc; - for (size_t i = 0; i < eventDescs.size(); i++) { - if (isspace(eventDescs[i])) { - if (i > 0 && start < i - 1) { - eventDesc = eventDescs.substr(start, i - start); + size_t start = 0; + std::string eventDesc; + for (size_t i = 0; i < eventDescs.size(); i++) { + if (isspace(eventDescs[i])) { + if (i > 0 && start < i - 1) { + eventDesc = eventDescs.substr(start, i - start); + } + while (isspace(eventDescs[++i])); // skip whitespaces + start = i; + } else if (i + 1 == eventDescs.size()) { + eventDesc = eventDescs.substr(start, i + 1 - start); } - while(isspace(eventDescs[++i])); // skip whitespaces - start = i; - } else if (i + 1 == eventDescs.size()) { - eventDesc = eventDescs.substr(start, i + 1 - start); - } - if (eventDesc.size() > 0) { - // remove optional trailing .* for CCXML compatibility - if (eventDesc.find("*", eventDesc.size() - 1) != std::string::npos) - eventDesc = eventDesc.substr(0, eventDesc.size() - 1); - if (eventDesc.find(".", eventDesc.size() - 1) != std::string::npos) - eventDesc = eventDesc.substr(0, eventDesc.size() - 1); + if (eventDesc.size() > 0) { + // remove optional trailing .* for CCXML compatibility + if (eventDesc.find("*", eventDesc.size() - 1) != std::string::npos) + eventDesc = eventDesc.substr(0, eventDesc.size() - 1); + if (eventDesc.find(".", eventDesc.size() - 1) != std::string::npos) + eventDesc = eventDesc.substr(0, eventDesc.size() - 1); - // was eventDesc the * wildcard - if (eventDesc.size() == 0) - return true; - - // eventDesc has to be a real prefix of event now and therefore shorter - if (eventDesc.size() > eventName.size()) - goto NEXT_DESC; + // was eventDesc the * wildcard + if (eventDesc.size() == 0) + return true; - // are they already equal? - if (boost::iequals(eventDesc, eventName)) - return true; + // eventDesc has to be a real prefix of event now and therefore shorter + if (eventDesc.size() > eventName.size()) + goto NEXT_DESC; - if (eventName.find(eventDesc) == 0) { - if (eventName.find(".", eventDesc.size()) == eventDesc.size()) + // are they already equal? + if (boost::iequals(eventDesc, eventName)) return true; + + if (eventName.find(eventDesc) == 0) { + if (eventName.find(".", eventDesc.size()) == eventDesc.size()) + return true; + } + NEXT_DESC: + eventDesc = ""; } -NEXT_DESC: - eventDesc = ""; } - } - return false; + return false; #else - const char* dPtr = eventDescs.c_str(); - const char* ePtr = eventName.c_str(); - while(*dPtr != 0) { + const char* dPtr = eventDescs.c_str(); + const char* ePtr = eventName.c_str(); + while(*dPtr != 0) { - if (*dPtr == '*' && *ePtr != 0) // something following - return true; + if (*dPtr == '*' && *ePtr != 0) // something following + return true; - // descriptor differs from event name - if (*dPtr != *ePtr) { - // move to next descriptor - while(*dPtr != ' ' && *dPtr != 0) { + // descriptor differs from event name + if (*dPtr != *ePtr) { + // move to next descriptor + while(*dPtr != ' ' && *dPtr != 0) { + dPtr++; + } + if (*dPtr == 0) + return false; + dPtr++; + ePtr = eventName.c_str(); + } else { + // move both pointers one character dPtr++; + ePtr++; + } - if (*dPtr == 0) - return false; - dPtr++; - ePtr = eventName.c_str(); - } else { - // move both pointers one character - dPtr++; - ePtr++; + // descriptor is done, return match + if (((*dPtr == 0 || *dPtr == ' ') && (*ePtr == 0 || *ePtr == ' ')) || // exact match, end of string + (*dPtr == ' ' && *ePtr == '.') || (*dPtr == 0 && *ePtr == '.')) // prefix match + return true; } - - // descriptor is done, return match - if (((*dPtr == 0 || *dPtr == ' ') && (*ePtr == 0 || *ePtr == ' ')) || // exact match, end of string - (*dPtr == ' ' && *ePtr == '.') || (*dPtr == 0 && *ePtr == '.')) // prefix match - return true; - } - return false; + return false; #endif -} + } } \ No newline at end of file diff --git a/src/uscxml/util/String.h b/src/uscxml/util/String.h index 8d9c9ef..91b8462 100644 --- a/src/uscxml/util/String.h +++ b/src/uscxml/util/String.h @@ -25,10 +25,15 @@ namespace uscxml { -std::string escapeMacro(std::string const &s); -std::list tokenize(const std::string& line, const char seperator = ' ', bool trimWhiteSpace = true); -std::string spaceNormalize(const std::string& text); -bool nameMatch(const std::string& eventDescs, const std::string& event); + std::string escapeMacro(std::string const &s); + + std::string toBinStr(size_t val, size_t margin); + + std::list tokenize(const std::string &line, const char seperator = ' ', bool trimWhiteSpace = true); + + std::string spaceNormalize(const std::string &text); + + bool nameMatch(const std::string &eventDescs, const std::string &event); } -- cgit v0.12 From 72b66be883924dd73d330523091c1c752856ac03 Mon Sep 17 00:00:00 2001 From: juehv Date: Wed, 23 Nov 2016 17:23:24 +0100 Subject: change event handling from special type to std_logic_vector for better simulation --- src/uscxml/transform/ChartToVHDL.cpp | 2610 +++++++++++++++++++--------------- src/uscxml/transform/ChartToVHDL.h | 271 ++-- 2 files changed, 1563 insertions(+), 1318 deletions(-) diff --git a/src/uscxml/transform/ChartToVHDL.cpp b/src/uscxml/transform/ChartToVHDL.cpp index 3100ec3..de63877 100644 --- a/src/uscxml/transform/ChartToVHDL.cpp +++ b/src/uscxml/transform/ChartToVHDL.cpp @@ -32,1402 +32,1650 @@ #include -#define CONST_TRANS_SPONTANIOUS "HWE_NOW" -#define CONST_EVENT_ANY "HWE_ANY" - namespace uscxml { -using namespace XERCESC_NS; - -Transformer ChartToVHDL::transform(const Interpreter &other) { - ChartToVHDL *c2c = new ChartToVHDL(other); - - return std::shared_ptr(c2c); -} - -ChartToVHDL::ChartToVHDL(const Interpreter &other) : ChartToC(other), _eventTrie(".") { -} - -ChartToVHDL::~ChartToVHDL() { -} - -void ChartToVHDL::checkDocument() { - // filter unsupported stuff - std::list unsupported; - unsupported = DOMUtils::inDocumentOrder({ - XML_PREFIX(_scxml).str() + "datamodel", - XML_PREFIX(_scxml).str() + "data", - XML_PREFIX(_scxml).str() + "assign", - XML_PREFIX(_scxml).str() + "donedata", - XML_PREFIX(_scxml).str() + "content", - XML_PREFIX(_scxml).str() + "param", - XML_PREFIX(_scxml).str() + "script", - XML_PREFIX(_scxml).str() + "parallel", - XML_PREFIX(_scxml).str() + "history", - XML_PREFIX(_scxml).str() + "if", - XML_PREFIX(_scxml).str() + "foreach", - XML_PREFIX(_scxml).str() + "send", - XML_PREFIX(_scxml).str() + "cancel", - XML_PREFIX(_scxml).str() + "invoke", - XML_PREFIX(_scxml).str() + "finalize" - }, _scxml); - - std::stringstream ss; - if (unsupported.size() > 0) { - for (auto elem : unsupported) { - ss << " " << DOMUtils::xPathForNode(elem) << " unsupported" << std::endl; - } - throw std::runtime_error("Unsupported elements found:\n" + ss.str()); + using namespace XERCESC_NS; + + Transformer ChartToVHDL::transform(const Interpreter &other) { + ChartToVHDL *c2c = new ChartToVHDL(other); + + return std::shared_ptr(c2c); } - unsupported = DOMUtils::inDocumentOrder({XML_PREFIX(_scxml).str() + "transition"}, _scxml); + ChartToVHDL::ChartToVHDL(const Interpreter &other) : ChartToC(other), _eventTrie(".") { + } + + ChartToVHDL::~ChartToVHDL() { + } - for (auto transition : unsupported) { - if (HAS_ATTR(transition, "cond")) { - ERROR_PLATFORM_THROW("transition with conditions not supported!"); + void ChartToVHDL::checkDocument() { + // filter unsupported stuff + std::list unsupported; + unsupported = DOMUtils::inDocumentOrder({ + XML_PREFIX(_scxml).str() + "datamodel", + XML_PREFIX(_scxml).str() + "data", + XML_PREFIX(_scxml).str() + "assign", + XML_PREFIX(_scxml).str() + "donedata", + XML_PREFIX(_scxml).str() + "content", + XML_PREFIX(_scxml).str() + "param", + XML_PREFIX(_scxml).str() + "script", + XML_PREFIX(_scxml).str() + "parallel", + XML_PREFIX(_scxml).str() + "history", + XML_PREFIX(_scxml).str() + "if", + XML_PREFIX(_scxml).str() + "foreach", + XML_PREFIX(_scxml).str() + "send", + XML_PREFIX(_scxml).str() + "cancel", + XML_PREFIX(_scxml).str() + "invoke", + XML_PREFIX(_scxml).str() + "finalize" + }, _scxml); + + std::stringstream ss; + if (unsupported.size() > 0) { + for (auto elem : unsupported) { + ss << " " << DOMUtils::xPathForNode(elem) << " unsupported" << std::endl; + } + throw std::runtime_error("Unsupported elements found:\n" + ss.str()); } - if (!HAS_ATTR(transition, "target")) { - ERROR_PLATFORM_THROW("targetless transition not supported!"); + + unsupported = DOMUtils::inDocumentOrder({XML_PREFIX(_scxml).str() + "transition"}, _scxml); + + for (auto transition : unsupported) { + if (HAS_ATTR(transition, "cond")) { + ERROR_PLATFORM_THROW("transition with conditions not supported!"); + } + if (!HAS_ATTR(transition, "target")) { + ERROR_PLATFORM_THROW("targetless transition not supported!"); + } } - } -} + } -void ChartToVHDL::findEvents() { - // elements with an event attribute - std::list withEvents = DOMUtils::inDocumentOrder({ - XML_PREFIX(_scxml).str() + "raise", - XML_PREFIX(_scxml).str() + "send", - XML_PREFIX(_scxml).str() + "transition", - }, _scxml); + void ChartToVHDL::findEvents() { + // elements with an event attribute + std::list withEvents = DOMUtils::inDocumentOrder({ + XML_PREFIX(_scxml).str() + "raise", + XML_PREFIX(_scxml).str() + "send", + XML_PREFIX(_scxml).str() + "transition", + }, _scxml); - for (auto withEvent : withEvents) { + for (auto withEvent : withEvents) { // if (HAS_ATTR_CAST(withEvent, "event")) { // if (ATTR_CAST(withEvent, "event") != "*") // _eventTrie.addWord(ATTR_CAST(withEvent, "event")); // } - // Tokenized version below - - if (HAS_ATTR_CAST(withEvent, "event")) { - std::string eventNames = ATTR_CAST(withEvent, "event"); - std::list events = tokenize(eventNames); - for (std::list::iterator eventIter = events.begin(); - eventIter != events.end(); eventIter++) { - std::string eventName = *eventIter; - if (boost::ends_with(eventName, "*")) - eventName = eventName.substr(0, eventName.size() - 1); - if (boost::ends_with(eventName, ".")) - eventName = eventName.substr(0, eventName.size() - 1); - if (eventName.size() > 0) - _eventTrie.addWord(eventName); - } - - //TODO implement "done" event - // --> enter a final from a compound state not (also prevent setting completed_o) - // --> all final children from a parallel are entered - //TODO implement error events --> set by output logic to a signal line + // Tokenized version below + + if (HAS_ATTR_CAST(withEvent, "event")) { + std::string eventNames = ATTR_CAST(withEvent, "event"); + std::list events = tokenize(eventNames); + for (std::list::iterator eventIter = events.begin(); + eventIter != events.end(); eventIter++) { + std::string eventName = *eventIter; + if (boost::ends_with(eventName, "*")) + eventName = eventName.substr(0, eventName.size() - 1); + if (boost::ends_with(eventName, ".")) + eventName = eventName.substr(0, eventName.size() - 1); + if (eventName.size() > 0) + _eventTrie.addWord(eventName); + } + + //TODO implement "done" event + // --> enter a final from a compound state not (also prevent setting completed_o) + // --> all final children from a parallel are entered + //TODO implement error events --> set by output logic to a signal line + } + } + // preprocess event names since they are often used + _eventNames = _eventTrie.getWordsWithPrefix(""); + // Calculate needed bit size for the event fifo + // --> |log2(n)| +1 with n is number of events + // we do not add +1 because the std_logic_vector startes with 0 + _eventBitSize = ceil(abs(log2(_eventNames.size()))); + + _execContent = DOMUtils::inDocumentOrder({ + XML_PREFIX(_scxml).str() + "raise", + XML_PREFIX(_scxml).str() + "send" + }, _scxml); } - _execContent = DOMUtils::inDocumentOrder({ - XML_PREFIX(_scxml).str() + "raise", - XML_PREFIX(_scxml).str() + "send" - }, _scxml); - -} - -bool ChartToVHDL::isSupportedExecContent(DOMElement *execContentElement) { - return (TAGNAME(execContentElement) == XML_PREFIX(_scxml).str() + "raise" || - TAGNAME(execContentElement) == XML_PREFIX(_scxml).str() + "send"); -} - -void ChartToVHDL::writeTo(std::ostream &stream) { - // checkDocument(); - findEvents(); - - - stream << "-- generated from " << std::string(_baseURL) << std::endl; - stream << "-- run as " << std::endl; - stream << "-- ghdl --clean && ghdl -a foo.vhdl && ghdl -e tb && ./tb --stop-time=10ms --vcd=tb.vcd" << - std::endl; - stream << "-- gtkwave tb.vcd" << std::endl; - stream << std::endl; - - writeTypes(stream); - writeFiFo(stream); - writeEventController(stream); - writeMicroStepper(stream); - writeTestbench(stream); -} - -void ChartToVHDL::writeTypes(std::ostream &stream) { - std::string seperator; - - stream << "-- required global types" << std::endl; - stream << "library IEEE;" << std::endl; - stream << "use IEEE.std_logic_1164.all;" << std::endl; - stream << std::endl; - stream << "package machine" << _md5 << " is" << std::endl; - // create state type - stream << " subtype state_type is std_logic_vector( "; - stream << _states.size() - 1; - stream << " downto 0);" << std::endl; - - std::list eventNames = _eventTrie.getWordsWithPrefix(""); - stream << " type event_type is ( hwe_null"; - seperator = ", "; - - for (std::list::iterator eventIter = eventNames.begin(); - eventIter != eventNames.end(); eventIter++) { - stream << seperator << "hwe_" << escapeMacro((*eventIter)->value); - // seperator = ", "; + bool ChartToVHDL::isSupportedExecContent(DOMElement *execContentElement) { + return (TAGNAME(execContentElement) == XML_PREFIX(_scxml).str() + "raise" || + TAGNAME(execContentElement) == XML_PREFIX(_scxml).str() + "send"); } - stream << " );" << std::endl; - - stream << "end machine" << _md5 << ";" << std::endl; - stream << std::endl; - stream << "-- END needed global types" << std::endl; -} - -void ChartToVHDL::writeIncludes(std::ostream &stream) { - // Add controler specific stuff here - stream << "library IEEE;" << std::endl; - stream << "use IEEE.std_logic_1164.all;" << std::endl; - stream << "use work.machine" << _md5 << ".all;" << std::endl; - stream << std::endl; -} - -void ChartToVHDL::writeTestbench(std::ostream &stream) { - - stream << "-- TESTBENCH" << std::endl; - writeIncludes(stream); - stream << "use std.env.all;" << std::endl; - stream << std::endl; - - stream << "-- empty entity" << std::endl; - stream << "entity tb is" << std::endl; - stream << "end entity tb;" << std::endl; - stream << std::endl; - - stream << "architecture behavioral of tb is" << std::endl; - stream << std::endl; - - // modules - stream << " -- Module declaration" << std::endl; - stream << " component micro_stepper is" << std::endl; - stream << " port (" << std::endl; - stream << " --inputs" << std::endl; - stream << " clk :in std_logic;" << std::endl; - stream << " rst_i :in std_logic;" << std::endl; - stream << " en :in std_logic;" << std::endl; - stream << " next_event_i :in event_type;" << std::endl; - stream << " next_event_we_i :in std_logic;" << std::endl; - stream << " --outputs" << std::endl; - stream << " error_o :out std_logic;" << std::endl; - - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; - - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " entry_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; - } - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " exit_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; - } + void ChartToVHDL::writeTo(std::ostream &stream) { + // checkDocument(); + findEvents(); + + + stream << "-- generated from " << std::string(_baseURL) << std::endl; + stream << "-- run as " << std::endl; + stream << "-- ghdl --clean && ghdl -a foo.vhdl && ghdl -e tb && ./tb --stop-time=10ms --vcd=tb.vcd" << + std::endl; + stream << "-- gtkwave tb.vcd" << std::endl; + stream << std::endl; + +// writeTypes(stream); + writeFiFo(stream); + writeEventController(stream); + writeMicroStepper(stream); + writeTestbench(stream); + writeTopLevel(stream); } - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " transition_set_" << ATTR(transition, "postFixOrder") << "_o :out std_logic;" - << std::endl; - } + // no longer required since events are a std_logic_vector now +// void ChartToVHDL::writeTypes(std::ostream &stream) { +// std::string seperator; +// +// stream << "-- required global types" << std::endl; +// stream << "library IEEE;" << std::endl; +// stream << "use IEEE.std_logic_1164.all;" << std::endl; +// stream << std::endl; +// stream << "package machine" << _md5 << " is" << std::endl; +// // create state type +// stream << " subtype state_type is std_logic_vector( "; +// stream << _states.size() - 1; +// stream << " downto 0);" << std::endl; +// +// std::list eventNames = _eventTrie.getWordsWithPrefix(""); +// stream << " type event_type is ( hwe_null"; +// seperator = ", "; +// +// for (std::list::iterator eventIter = eventNames.begin(); +// eventIter != eventNames.end(); eventIter++) { +// stream << seperator << "hwe_" << escapeMacro((*eventIter)->value); +// // seperator = ", "; +// } +// stream << " );" << std::endl; +// +// stream << "end machine" << _md5 << ";" << std::endl; +// stream << std::endl; +// stream << "-- END needed global types" << std::endl; +// } + + void ChartToVHDL::writeIncludes(std::ostream &stream) { + // Add controler specific stuff here + stream << "library IEEE;" << std::endl; + stream << "use IEEE.std_logic_1164.all;" << std::endl; +// stream << "use work.machine" << _md5 << ".all;" << std::endl; + stream << std::endl; } - stream << " completed_o :out std_logic" << std::endl; - stream << " );" << std::endl; - stream << " end component;" << std::endl; - stream << std::endl; + void ChartToVHDL::writeTestbench(std::ostream &stream) { - stream << " component event_controller is" << std::endl; - stream << " port(" << std::endl; - stream << " --inputs" << std::endl; - stream << " clk :in std_logic;" << std::endl; - stream << " rst_i :in std_logic;" << std::endl; + stream << "-- TESTBENCH" << std::endl; + writeIncludes(stream); + stream << "use std.env.all;" << std::endl; + stream << std::endl; - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") - << "_i :in std_logic;" << std::endl; + stream << "-- empty entity" << std::endl; + stream << "entity tb is" << std::endl; + stream << "end entity tb;" << std::endl; + stream << std::endl; - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " entry_set_" << ATTR(state, "documentOrder") - << "_i :in std_logic;" << std::endl; - } + stream << "architecture behavioral of tb is" << std::endl; + stream << std::endl; + + // modules + stream << " -- Module declaration" << std::endl; + stream << " component micro_stepper is" << std::endl; + stream << " port (" << std::endl; + stream << " --inputs" << std::endl; + stream << " clk :in std_logic;" << std::endl; + stream << " rst_i :in std_logic;" << std::endl; + stream << " en :in std_logic;" << std::endl; + stream << " next_event_i :in std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << " next_event_we_i :in std_logic;" << std::endl; + stream << " --outputs" << std::endl; + stream << " error_o :out std_logic;" << std::endl; + + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; + } - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " exit_set_" << ATTR(state, "documentOrder") - << "_i :in std_logic;" << std::endl; + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; + } } - } - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " transition_set_" << ATTR(transition, "postFixOrder") - << "_i :in std_logic;" << std::endl; + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") << "_o :out std_logic;" + << std::endl; + } } - } - stream << " --outputs" << std::endl; - stream << " micro_stepper_en_o :out std_logic;" << std::endl; - stream << " event_o :out event_type;" << std::endl; - stream << " event_we_o :out std_logic" << std::endl; - // stream << " done_o :out std_logic" << std::endl; - stream << ");" << std::endl; - stream << "end component; " << std::endl; - - // signals - stream << " -- input" << std::endl; - stream << " signal clk : std_logic := '0';" << std::endl; - stream << " signal reset : std_logic;" << std::endl; - stream << " signal dut_enable : std_logic;" << std::endl; - stream << " signal next_event_we_i : std_logic;" << std::endl; - stream << " signal next_event_i : event_type;" << std::endl; - stream << std::endl; - - stream << " -- output" << std::endl; - stream << " signal error_o, completed_o : std_logic;" << std::endl; - stream << std::endl; - - stream << " -- wiring" << std::endl; - for (auto state : _states) { - stream << " signal state_active_" << ATTR(state, "documentOrder") - << "_sig : std_logic;" << std::endl; - - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " signal entry_set_" << ATTR(state, "documentOrder") - << "_sig : std_logic;" << std::endl; + + stream << " completed_o :out std_logic" << std::endl; + stream << " );" << std::endl; + stream << " end component;" << std::endl; + stream << std::endl; + + stream << " component event_controller is" << std::endl; + stream << " port(" << std::endl; + stream << " --inputs" << std::endl; + stream << " clk :in std_logic;" << std::endl; + stream << " rst_i :in std_logic;" << std::endl; + + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") + << "_i :in std_logic;" << std::endl; + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") + << "_i :in std_logic;" << std::endl; + } + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") + << "_i :in std_logic;" << std::endl; + } } - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " signal exit_set_" << ATTR(state, "documentOrder") - << "_sig : std_logic;" << std::endl; + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") + << "_i :in std_logic;" << std::endl; + } } - } + stream << " --outputs" << std::endl; + stream << " micro_stepper_en_o :out std_logic;" << std::endl; + stream << " event_o :out std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << " event_we_o :out std_logic" << std::endl; + // stream << " done_o :out std_logic" << std::endl; + stream << ");" << std::endl; + stream << "end component; " << std::endl; + + // signals + stream << " -- input" << std::endl; + stream << " signal clk : std_logic := '0';" << std::endl; + stream << " signal reset : std_logic;" << std::endl; + stream << " signal dut_enable : std_logic;" << std::endl; + stream << " signal next_event_we_i : std_logic;" << std::endl; + stream << " signal next_event_i : std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << std::endl; + + stream << " -- output" << std::endl; + stream << " signal error_o, completed_o : std_logic;" << std::endl; + stream << std::endl; + + stream << " -- wiring" << std::endl; + for (auto state : _states) { + stream << " signal state_active_" << ATTR(state, "documentOrder") + << "_sig : std_logic;" << std::endl; - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " signal transition_set_" << ATTR(transition, "postFixOrder") - << "_sig : std_logic;" << std::endl; + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " signal entry_set_" << ATTR(state, "documentOrder") + << "_sig : std_logic;" << std::endl; + } + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " signal exit_set_" << ATTR(state, "documentOrder") + << "_sig : std_logic;" << std::endl; + } } - } - // wiring - stream << "begin" << std::endl; - stream << " clk <= not clk after 20 ns; -- 25 MHz clock frequency" << std::endl; - stream << " reset <= '1', '0' after 100 ns; -- generates reset signal: --__" << std::endl; - stream << std::endl; - - stream << " -- Module instantiation" << std::endl; - stream << " dut : micro_stepper" << std::endl; - stream << " port map (" << std::endl; - stream << " clk => clk," << std::endl; - stream << " rst_i => reset," << std::endl; - stream << " en => dut_enable," << std::endl; - stream << std::endl; - - stream << " next_event_i => next_event_i," << std::endl; - stream << " next_event_we_i => next_event_we_i," << std::endl; - stream << " error_o => error_o," << std::endl; - - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") - << "_o => state_active_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; - - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " entry_set_" << ATTR(state, "documentOrder") - << "_o => entry_set_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " signal transition_set_" << ATTR(transition, "postFixOrder") + << "_sig : std_logic;" << std::endl; + } } - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " exit_set_" << ATTR(state, "documentOrder") - << "_o => exit_set_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; + // wiring + stream << "begin" << std::endl; + stream << " clk <= not clk after 20 ns; -- 25 MHz clock frequency" << std::endl; + stream << " reset <= '1', '0' after 100 ns; -- generates reset signal: --__" << std::endl; + stream << std::endl; + + stream << " -- Module instantiation" << std::endl; + stream << " dut : micro_stepper" << std::endl; + stream << " port map (" << std::endl; + stream << " clk => clk," << std::endl; + stream << " rst_i => reset," << std::endl; + stream << " en => dut_enable," << std::endl; + stream << std::endl; + + stream << " next_event_i => next_event_i," << std::endl; + stream << " next_event_we_i => next_event_we_i," << std::endl; + stream << " error_o => error_o," << std::endl; + + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") + << "_o => state_active_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") + << "_o => entry_set_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; + } + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") + << "_o => exit_set_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; + } } - } - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " transition_set_" << ATTR(transition, "postFixOrder") - << "_o => transition_set_" << ATTR(transition, "postFixOrder") - << "_sig," << std::endl; + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") + << "_o => transition_set_" << ATTR(transition, "postFixOrder") + << "_sig," << std::endl; + } } - } - stream << " completed_o => completed_o" << std::endl; - stream << " );" << std::endl; - stream << std::endl; + stream << " completed_o => completed_o" << std::endl; + stream << " );" << std::endl; + stream << std::endl; - stream << " ec : event_controller" << std::endl; - stream << " port map (" << std::endl; - stream << " clk => clk," << std::endl; - stream << " rst_i => reset," << std::endl; - stream << std::endl; + stream << " ec : event_controller" << std::endl; + stream << " port map (" << std::endl; + stream << " clk => clk," << std::endl; + stream << " rst_i => reset," << std::endl; + stream << std::endl; - stream << " event_o => next_event_i," << std::endl; - stream << " event_we_o => next_event_we_i," << std::endl; + stream << " event_o => next_event_i," << std::endl; + stream << " event_we_o => next_event_we_i," << std::endl; - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") - << "_i => state_active_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") + << "_i => state_active_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " entry_set_" << ATTR(state, "documentOrder") - << "_i => entry_set_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") + << "_i => entry_set_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; + } - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " exit_set_" << ATTR(state, "documentOrder") - << "_i => exit_set_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") + << "_i => exit_set_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; + } } - } - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " transition_set_" << ATTR(transition, "postFixOrder") - << "_i => transition_set_" << ATTR(transition, "postFixOrder") - << "_sig," << std::endl; + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") + << "_i => transition_set_" << ATTR(transition, "postFixOrder") + << "_sig," << std::endl; + } } - } - stream << " micro_stepper_en_o => dut_enable" << std::endl; - // stream << " done_o => open" << std::endl; - stream << " );" << std::endl; - stream << std::endl; + stream << " micro_stepper_en_o => dut_enable" << std::endl; + // stream << " done_o => open" << std::endl; + stream << " );" << std::endl; + stream << std::endl; - // find pass state - std::list topLevelFinal = - DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "final", _scxml); + // find pass state + std::list topLevelFinal = + DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "final", _scxml); - std::string passStateNo = ""; - for (auto final : topLevelFinal) { - if (ATTR(final, "id") == "pass") { - passStateNo = ATTR(final, "documentOrder"); + std::string passStateNo = ""; + for (auto final : topLevelFinal) { + if (ATTR(final, "id") == "pass") { + passStateNo = ATTR(final, "documentOrder"); + } } - } - // test observation and exit condition - stream << " -- Test observation" << std::endl; - stream << " process (clk)" << std::endl; - stream << " variable count_clk : integer := 0;" << std::endl; - stream << " begin" << std::endl; - stream << " if rising_edge(clk) then" << std::endl; - stream << " count_clk := count_clk + 1;" << std::endl; - stream << " if (completed_o = '1') then" << std::endl; - if (!passStateNo.empty()) { - stream << " assert (state_active_" << passStateNo; - stream << "_sig = '1') report \"Completed with errors\" severity error;" << std::endl; - } - stream << " -- stop simulation" << std::endl; - stream << " finish(0);" << std::endl; // use 0 for ctest + // test observation and exit condition + stream << " -- Test observation" << std::endl; + stream << " process (clk)" << std::endl; + stream << " variable count_clk : integer := 0;" << std::endl; + stream << " begin" << std::endl; + stream << " if rising_edge(clk) then" << std::endl; + stream << " count_clk := count_clk + 1;" << std::endl; + stream << " if (completed_o = '1') then" << std::endl; + if (!passStateNo.empty()) { + stream << " assert (state_active_" << passStateNo; + stream << "_sig = '1') report \"Completed with errors\" severity error;" << std::endl; + } + stream << " -- stop simulation" << std::endl; + stream << " finish(0);" << std::endl; // use 0 for ctest // -- For both STOP and FINISH the STATUS values are those used // -- in the Verilog $finish task // -- 0 prints nothing // -- 1 prints simulation time and location // -- 2 prints simulation time, location, and statistics about // -- the memory and CPU times used in simulation - //stream << " assert false report \"Simulation Finished\" severity failure;" << std::endl; - stream << " else" << std::endl; - stream << " -- state machine not completed" << std::endl; - stream << " -- check if it is time to stop waiting (100 clk per state+transition+excontent)" << std::endl; - int tolleratedClocks = (_transitions.size() + _states.size() + _execContent.size()) * 100; - stream << " assert (count_clk < " << tolleratedClocks; - stream << ") report \"Clock count exceed\" severity failure;" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << " end process;" << std::endl; - - stream << "end architecture;" << std::endl; - stream << "-- END TESTBENCH" << std::endl; - -} - -void ChartToVHDL::writeExContentBlock(std::ostream &stream, - std::string index, std::list commandSequence) { - // index should be [entry, transition, exit]__ - - // write clock blocks -} - -void ChartToVHDL::writeEventController(std::ostream &stream) { - // Add controler specific stuff here - // create hardware top level - stream << "-- Event Controller Logic" << std::endl; - writeIncludes(stream); - stream << "entity event_controller is" << std::endl; - stream << "port(" << std::endl; - stream << " --inputs" << std::endl; - stream << " clk :in std_logic;" << std::endl; - stream << " rst_i :in std_logic;" << std::endl; - - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") - << "_i :in std_logic;" << std::endl; - - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " entry_set_" << ATTR(state, "documentOrder") - << "_i :in std_logic;" << std::endl; - } + //stream << " assert false report \"Simulation Finished\" severity failure;" << std::endl; + stream << " else" << std::endl; + stream << " -- state machine not completed" << std::endl; + stream << " -- check if it is time to stop waiting (100 clk per state+transition+excontent)" << std::endl; + int tolleratedClocks = (_transitions.size() + _states.size() + _execContent.size()) * 100; + stream << " assert (count_clk < " << tolleratedClocks; + stream << ") report \"Clock count exceed\" severity failure;" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << " end process;" << std::endl; + + stream << "end architecture;" << std::endl; + stream << "-- END TESTBENCH" << std::endl; - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " exit_set_" << ATTR(state, "documentOrder") - << "_i :in std_logic;" << std::endl; - } } - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " transition_set_" << ATTR(transition, "postFixOrder") - << "_i :in std_logic;" << std::endl; + void ChartToVHDL::writeTopLevel(std::ostream &stream) { + + stream << "-- TOP LEVEL entity for easy synthesis" << std::endl; + writeIncludes(stream); + stream << std::endl; + + stream << "-- empty entity" << std::endl; + stream << "entity top_level_design is" << std::endl; + stream << "port (" << std::endl; + stream << " --inputs" << std::endl; + stream << " clk :in std_logic;" << std::endl; + stream << " rst :in std_logic;" << std::endl; + stream << " --outputs" << std::endl; + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") + << "_o :out std_logic;" << std::endl; } - } + stream << " completed_o :out std_logic" << std::endl; + stream << ");" << std::endl; + stream << "end entity top_level_design;" << std::endl; + stream << std::endl; - stream << " --outputs" << std::endl; - stream << " micro_stepper_en_o :out std_logic;" << std::endl; - stream << " event_o :out event_type;" << std::endl; - stream << " event_we_o :out std_logic" << std::endl; - stream << ");" << std::endl; - stream << "end event_controller; " << std::endl; - - stream << std::endl; - stream << "architecture behavioral of event_controller is " << std::endl; - stream << std::endl; - - - // Add signals and components - stream << "signal rst : std_logic;" << std::endl; - stream << "signal micro_stepper_en : std_logic;" << std::endl; - stream << "signal cmpl_buf : std_logic;" << std::endl; - stream << "signal completed_sig : std_logic;" << std::endl; - stream << "signal event_bus : event_type;" << std::endl; - stream << "signal event_we : std_logic;" << std::endl; - - for (int i = 0; i < _execContent.size(); i++) { - stream << "signal done_" << toStr(i) << "_sig : std_logic;" << std::endl; - stream << "signal start_" << toStr(i) << "_sig : std_logic;" << std::endl; - } + stream << "architecture behavioral of top_level_design is" << std::endl; + stream << std::endl; - stream << "-- sequence input line" << std::endl; - for (int i = 0; i < _execContent.size(); i++) { - stream << "signal seq_" << toStr(i) << "_sig : std_logic;" << std::endl; - } - stream << std::endl; + // modules + stream << " -- Module declaration" << std::endl; + stream << " component micro_stepper is" << std::endl; + stream << " port (" << std::endl; + stream << " --inputs" << std::endl; + stream << " clk :in std_logic;" << std::endl; + stream << " rst_i :in std_logic;" << std::endl; + stream << " en :in std_logic;" << std::endl; + stream << " next_event_i :in std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << " next_event_we_i :in std_logic;" << std::endl; + stream << " --outputs" << std::endl; + stream << " error_o :out std_logic;" << std::endl; + + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; - stream << "begin" << std::endl; - stream << std::endl; + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; + } + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; + } + } - // check if there is SUPPORTED executable content - bool foundSupportedExecContent = false; - for (auto exContentElem : _execContent) { - if (isSupportedExecContent(exContentElem)) { - foundSupportedExecContent = true; - break; + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") << "_o :out std_logic;" + << std::endl; + } } - } - if (!foundSupportedExecContent) { - // set output correct if there is no supported excontent - - stream << "-- no supported executable content found" << std::endl; - stream << "-- state machine may not run correctly" << std::endl; - stream << "-- setting output lines to fulfil dummy functionality" << std::endl; - stream << "micro_stepper_en_o <= '1';" << std::endl; - stream << "event_o <= hwe_null;" << std::endl; - stream << "event_we_o <= '0';" << std::endl; - stream << std::endl; - } else { - // system signal mapping - stream << "rst <= rst_i;" << std::endl; - stream << "micro_stepper_en_o <= micro_stepper_en;" << std::endl; - stream << "event_o <= event_bus;" << std::endl; - stream << "event_we_o <= event_we;" << std::endl; + + stream << " completed_o :out std_logic" << std::endl; + stream << " );" << std::endl; + stream << " end component;" << std::endl; stream << std::endl; - // stall management - stream << "-- stalling microstepper" << std::endl; - stream << "micro_stepper_en <= completed_sig or not ( '0' "; + stream << " component event_controller is" << std::endl; + stream << " port(" << std::endl; + stream << " --inputs" << std::endl; + stream << " clk :in std_logic;" << std::endl; + stream << " rst_i :in std_logic;" << std::endl; + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") + << "_i :in std_logic;" << std::endl; if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << std::endl << " or entry_set_" << ATTR(state, "documentOrder") - << "_i"; + stream << " entry_set_" << ATTR(state, "documentOrder") + << "_i :in std_logic;" << std::endl; } if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << std::endl << " or exit_set_" << ATTR(state, "documentOrder") - << "_i"; + stream << " exit_set_" << ATTR(state, "documentOrder") + << "_i :in std_logic;" << std::endl; } } + for (auto transition : _transitions) { if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << std::endl << " or transition_set_" << ATTR(transition, "postFixOrder") - << "_i"; + stream << " transition_set_" << ATTR(transition, "postFixOrder") + << "_i :in std_logic;" << std::endl; } } + stream << " --outputs" << std::endl; + stream << " micro_stepper_en_o :out std_logic;" << std::endl; + stream << " event_o :out std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << " event_we_o :out std_logic" << std::endl; + // stream << " done_o :out std_logic" << std::endl; stream << ");" << std::endl; + stream << "end component; " << std::endl; + + // signals + stream << " -- input" << std::endl; + stream << " signal reset : std_logic;" << std::endl; + stream << " signal dut_enable : std_logic;" << std::endl; + stream << " signal next_event_we_i : std_logic;" << std::endl; + stream << " signal next_event_i : std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; stream << std::endl; - // sequential code operation - stream << "-- seq code block " << std::endl; - stream << "ex_content_block : process (clk, rst) " << std::endl; + stream << " -- output" << std::endl; + stream << " signal error_o : std_logic;" << std::endl; + stream << std::endl; + + stream << " -- wiring" << std::endl; + for (auto state : _states) { + stream << " signal state_active_" << ATTR(state, "documentOrder") + << "_sig : std_logic;" << std::endl; + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " signal entry_set_" << ATTR(state, "documentOrder") + << "_sig : std_logic;" << std::endl; + } + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " signal exit_set_" << ATTR(state, "documentOrder") + << "_sig : std_logic;" << std::endl; + } + } + + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " signal transition_set_" << ATTR(transition, "postFixOrder") + << "_sig : std_logic;" << std::endl; + } + } + + // wiring stream << "begin" << std::endl; - stream << " if rst = '1' then" << std::endl; - for (int i = 0; i < _execContent.size(); i++) { - stream << " done_" << toStr(i) << "_sig <= '0';" << std::endl; + stream << " reset <= rst;" << std::endl; + stream << std::endl; + + for (auto state : _states) { + stream << "state_active_" << ATTR(state, "documentOrder") + << "_o <= state_active_" << ATTR(state, "documentOrder") + << "_sig;" << std::endl; } - stream << " event_bus <= hwe_null;" << std::endl; - stream << " event_we <= '0';" << std::endl; - stream << " cmpl_buf <= '0';" << std::endl; - stream << " completed_sig <= '0';" << std::endl; - stream << " elsif rising_edge(clk) then" << std::endl; - - stream << " if micro_stepper_en = '1' then" << std::endl; - stream << " cmpl_buf <= '0' ;" << std::endl; - stream << " else" << std::endl; - stream << " cmpl_buf <= seq_" << toStr(_execContent.size() - 1) - << "_sig;" << std::endl; - stream << " end if;" << std::endl; - stream << " completed_sig <= cmpl_buf;" << std::endl << std::endl; + stream << std::endl; - size_t i = 0; - std::string seperator = " "; - for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { - DOMElement *exContentElem = *ecIter; + stream << " -- Module instantiation" << std::endl; + stream << " dut : micro_stepper" << std::endl; + stream << " port map (" << std::endl; + stream << " clk => clk," << std::endl; + stream << " rst_i => reset," << std::endl; + stream << " en => dut_enable," << std::endl; + stream << std::endl; - if (isSupportedExecContent(exContentElem)) { + stream << " next_event_i => next_event_i," << std::endl; + stream << " next_event_we_i => next_event_we_i," << std::endl; + stream << " error_o => error_o," << std::endl; + + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") + << "_o => state_active_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; - stream << seperator << "if start_" << toStr(i) << "_sig = '1' then" - << std::endl; - stream << " event_bus <= hwe_" << escapeMacro(ATTR(exContentElem, "event")) - << ";" << std::endl; - stream << " done_" << toStr(i) << "_sig <= '1';" << std::endl; - stream << " event_we <= '1';" << std::endl; - seperator = " els"; + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") + << "_o => entry_set_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; + } + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") + << "_o => exit_set_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; } } - stream << " elsif micro_stepper_en = '1' then" << std::endl; - i = 0; - //for (auto exContentElem : _execContent) { - for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { - DOMElement *exContentElem = *ecIter; - if (isSupportedExecContent(exContentElem)) { - stream << " done_" << toStr(i) << "_sig <= '0';" << std::endl; + + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") + << "_o => transition_set_" << ATTR(transition, "postFixOrder") + << "_sig," << std::endl; } } - stream << " event_we <= '0';" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << "end process;" << std::endl; + + stream << " completed_o => completed_o" << std::endl; + stream << " );" << std::endl; stream << std::endl; - i = 0; - for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { - // start lines - stream << "start_" << toStr(i) << "_sig <= " - << getLineForExecContent(*ecIter) << " and " - << "not done_" << toStr(i) << "_sig"; + stream << " ec : event_controller" << std::endl; + stream << " port map (" << std::endl; + stream << " clk => clk," << std::endl; + stream << " rst_i => reset," << std::endl; + stream << std::endl; - // if not needed, since seq_0_sig is hard coded as '1'. -// if (i != 0) { // if not first element - stream << " and seq_" << toStr(i) << "_sig"; -// } + stream << " event_o => next_event_i," << std::endl; + stream << " event_we_o => next_event_we_i," << std::endl; - stream << ";" << std::endl; + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") + << "_i => state_active_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") + << "_i => entry_set_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; + } - stream << "seq_0_sig <= '1';" << std::endl; + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") + << "_i => exit_set_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; + } + } - if (_execContent.size() > 1) { - i = 0; - for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { - // prevent writing seq_0_sig since this should be hardcoded to '1' - if (i != 0) { - // seq lines (input if process i is in seqence now) - stream << "seq_" << toStr(i) << "_sig <= " - << "done_" << toStr(i - 1) << "_sig or " - << "( not " - << getLineForExecContent(*ecIter); - stream << " and seq_" << toStr(i - 1) << "_sig"; - stream << " );" << std::endl; - } + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") + << "_i => transition_set_" << ATTR(transition, "postFixOrder") + << "_sig," << std::endl; } } + + stream << " micro_stepper_en_o => dut_enable" << std::endl; + // stream << " done_o => open" << std::endl; + stream << " );" << std::endl; stream << std::endl; - } - stream << "end behavioral; " << - std::endl; - stream << "-- END Event Controller Logic" << - std::endl; - stream << - std::endl; -} + // find pass state + std::list topLevelFinal = + DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "final", _scxml); -std::string ChartToVHDL::getLineForExecContent(const DOMNode *elem) { - const DOMNode *ecBlock = elem; - while (ecBlock) { - if (ecBlock->getNodeType() == DOMNode::ELEMENT_NODE) { - std::string localName = LOCALNAME_CAST(ecBlock); - if (localName == XML_PREFIX(_scxml).str() + "transition") { - return "transition_set_" + ATTR_CAST(ecBlock, "postFixOrder") + "_i"; + std::string passStateNo = ""; + for (auto final : topLevelFinal) { + if (ATTR(final, "id") == "pass") { + passStateNo = ATTR(final, "documentOrder"); } + } + stream << "end architecture;" << std::endl; + stream << "-- END TOP LEVEL" << std::endl; + } + + void ChartToVHDL::writeEventController(std::ostream &stream) { + // Add controler specific stuff here + // create hardware top level + stream << "-- Event Controller Logic" << std::endl; + writeIncludes(stream); + stream << "entity event_controller is" << std::endl; + stream << "port(" << std::endl; + stream << " --inputs" << std::endl; + stream << " clk :in std_logic;" << std::endl; + stream << " rst_i :in std_logic;" << std::endl; + + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") + << "_i :in std_logic;" << std::endl; - if (localName == XML_PREFIX(_scxml).str() + "onentry") { - return "entry_set_" + ATTR_CAST(ecBlock->getParentNode(), "documentOrder") + "_i"; + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") + << "_i :in std_logic;" << std::endl; } - if (localName == XML_PREFIX(_scxml).str() + "onexit") { - return "exit_set_" + ATTR_CAST(ecBlock->getParentNode(), "documentOrder") + "_i"; + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") + << "_i :in std_logic;" << std::endl; } + } + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") + << "_i :in std_logic;" << std::endl; + } } - ecBlock = ecBlock->getParentNode(); - } - return ""; -} - -void ChartToVHDL::writeMicroStepper(std::ostream &stream) { - // create MicroStepper top level - stream << "-- FSM Logic" << std::endl; - writeIncludes(stream); - stream << "entity micro_stepper is" << std::endl; - stream << "port(" << std::endl; - stream << " --inputs" << std::endl; - stream << " clk :in std_logic;" << std::endl; - stream << " rst_i :in std_logic;" << std::endl; - stream << " en :in std_logic;" << std::endl; - stream << " next_event_i :in event_type;" << std::endl; - stream << " next_event_we_i :in std_logic;" << std::endl; - stream << " --outputs" << std::endl; - stream << " error_o :out std_logic;" << std::endl; - - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; - - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " entry_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; + stream << " --outputs" << std::endl; + stream << " micro_stepper_en_o :out std_logic;" << std::endl; + stream << " event_o :out std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << " event_we_o :out std_logic" << std::endl; + stream << ");" << std::endl; + stream << "end event_controller; " << std::endl; + + stream << std::endl; + stream << "architecture behavioral of event_controller is " << std::endl; + stream << std::endl; + + + // Add signals and components + stream << "signal rst : std_logic;" << std::endl; + stream << "signal micro_stepper_en : std_logic;" << std::endl; + stream << "signal cmpl_buf : std_logic;" << std::endl; + stream << "signal completed_sig : std_logic;" << std::endl; + stream << "signal event_bus : std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << "signal event_we : std_logic;" << std::endl; + + for (int i = 0; i < _execContent.size(); i++) { + stream << "signal done_" << toStr(i) << "_sig : std_logic;" << std::endl; + stream << "signal start_" << toStr(i) << "_sig : std_logic;" << std::endl; } - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " exit_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; + stream << "-- sequence input line" << std::endl; + for (int i = 0; i < _execContent.size(); i++) { + stream << "signal seq_" << toStr(i) << "_sig : std_logic;" << std::endl; } - } + stream << std::endl; - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " transition_set_" << ATTR(transition, "postFixOrder") << "_o :out std_logic;" - << std::endl; + stream << "begin" << std::endl; + stream << std::endl; + + // check if there is SUPPORTED executable content + bool foundSupportedExecContent = false; + for (auto exContentElem : _execContent) { + if (isSupportedExecContent(exContentElem)) { + foundSupportedExecContent = true; + break; + } } - } + if (!foundSupportedExecContent) { + // set output correct if there is no supported excontent - stream << " completed_o :out std_logic" << std::endl; - stream << ");" << std::endl; - stream << "end micro_stepper; " << std::endl; - - stream << std::endl; - stream << "architecture behavioral of micro_stepper is " << std::endl; - stream << std::endl; - - // Add signals and components - writeSignalsAndComponents(stream); - - stream << std::endl; - stream << "begin" << std::endl; - stream << std::endl; - - // signal mapping - writeModuleInstantiation(stream); - - // signal handler - writeSpontaneousHandler(stream); - writeErrorHandler(stream); - writeInternalEventHandler(stream); - writeStateHandler(stream); - writeResetHandler(stream); - - // combinatorial logic for Sn+1 - writeOptimalTransitionSetSelection(stream); - writeExitSet(stream); - writeCompleteEntrySet(stream); - writeEntrySet(stream); - //writeDefaultCompletions(stream); - writeActiveStateNplusOne(stream); - - // connect output signals - writeSystemSignalMapping(stream); - - - stream << std::endl; - stream << "end behavioral; " << std::endl; - stream << "-- END FSM Logic" << std::endl; -} - -void ChartToVHDL::writeFiFo(std::ostream &stream) { - // taken from: http://www.deathbylogic.com/2013/07/vhdl-standard-fifo/ - // alternativly take fifo logic for a ram device: http://www.eng.auburn.edu/~strouce/class/elec4200/vhdlmods.pdf - stream << "-- standard FIFO buffer" << std::endl; - writeIncludes(stream); - stream << "" << std::endl; - stream << "entity std_fifo is" << std::endl; - stream << "generic (" << std::endl; - stream << " constant FIFO_DEPTH : positive := 256" << std::endl; - stream << ");" << std::endl; - stream << "port ( " << std::endl; - stream << " clk : in std_logic;" << std::endl; - stream << " rst : in std_logic;" << std::endl; - stream << " write_en : in std_logic;" << std::endl; - stream << " read_en : in std_logic;" << std::endl; - stream << " data_in : in event_type;" << std::endl; - stream << " data_out : out event_type;" << std::endl; - stream << " empty : out std_logic;" << std::endl; - stream << " full : out std_logic" << std::endl; - stream << ");" << std::endl; - stream << "end std_fifo;" << std::endl; - stream << "" << std::endl; - stream << "architecture behavioral of std_fifo is" << std::endl; - stream << "begin" << std::endl; - stream << "-- Memory Pointer Process" << std::endl; - stream << "fifo_proc : process (clk)" << std::endl; - stream << " type FIFO_Memory is array (0 to FIFO_DEPTH - 1) of event_type;" << std::endl; - stream << " variable Memory : FIFO_Memory;" << std::endl; - stream << "" << std::endl; - stream << " variable Head : natural range 0 to FIFO_DEPTH - 1;" << std::endl; - stream << " variable Tail : natural range 0 to FIFO_DEPTH - 1;" << std::endl; - stream << "" << std::endl; - stream << " variable Looped : boolean;" << std::endl; - stream << "begin" << std::endl; - stream << " if rising_edge(clk) then" << std::endl; - stream << " if rst = '1' then" << std::endl; - stream << " Head := 0;" << std::endl; - stream << " Tail := 0;" << std::endl; - stream << "" << std::endl; - stream << " Looped := false;" << std::endl; - stream << "" << std::endl; - stream << " full <= '0';" << std::endl; - stream << " empty <= '1';" << std::endl; - stream << " else" << std::endl; - stream << " if (read_en = '1') then" << std::endl; - stream << " if ((Looped = true) or (Head /= Tail)) then" << std::endl; - stream << " -- Update data output" << std::endl; - stream << " data_out <= Memory(Tail);" << std::endl; - stream << " " << std::endl; - stream << " -- Update Tail pointer as needed" << std::endl; - stream << " if (Tail = FIFO_DEPTH - 1) then" << std::endl; - stream << " Tail := 0;" << std::endl; - stream << " " << std::endl; - stream << " Looped := false;" << std::endl; - stream << " else" << std::endl; - stream << " Tail := Tail + 1;" << std::endl; - stream << " end if;" << std::endl; - stream << "" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << "" << std::endl; - stream << " if (write_en = '1') then" << std::endl; - stream << " if ((Looped = false) or (Head /= Tail)) then" << std::endl; - stream << " -- Write Data to Memory" << std::endl; - stream << " Memory(Head) := data_in;" << std::endl; - stream << " " << std::endl; - stream << " -- Increment Head pointer as needed" << std::endl; - stream << " if (Head = FIFO_DEPTH - 1) then" << std::endl; - stream << " Head := 0;" << std::endl; - stream << " " << std::endl; - stream << " Looped := true;" << std::endl; - stream << " else" << std::endl; - stream << " Head := Head + 1;" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << "" << std::endl; - stream << " -- Update empty and full flags" << std::endl; - stream << " if (Head = Tail) then" << std::endl; - stream << " if Looped then" << std::endl; - stream << " full <= '1';" << std::endl; - stream << " else" << std::endl; - stream << " empty <= '1';" << std::endl; - stream << " end if;" << std::endl; - stream << " else" << std::endl; - stream << " empty <= '0';" << std::endl; - stream << " full <= '0';" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << "end process;" << std::endl; - stream << "" << std::endl; - stream << "end behavioral;" << std::endl; - stream << "-- END standard FIFO buffer" << std::endl; -} - -void ChartToVHDL::writeSignalsAndComponents(std::ostream &stream) { - // create internal signals - stream << "-- system signals" << std::endl; - stream << "signal stall : std_logic;" << std::endl; - stream << "signal completed_sig : std_logic;" << std::endl; - stream << "signal rst : std_logic;" << std::endl; - stream << std::endl; - - stream << "-- state signals" << std::endl; - - std::list signalDecls; - - for (auto state : _states) { - std::string parent = ATTR(state, "parent"); - - signalDecls.push_back("signal state_active_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); - signalDecls.push_back("signal state_next_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); - signalDecls.push_back("signal in_entry_set_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); - signalDecls.push_back("signal in_exit_set_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); - signalDecls.push_back("signal in_complete_entry_set_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); - - // not needed for state - if (parent.size() != 0) { - signalDecls.push_back( - "signal in_complete_entry_set_up_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); + if (_execContent.size() > 0) { + // show warning if executable content is ignored + stream << "-- no supported executable content found" << std::endl; + stream << "-- state machine may not run correctly" << std::endl; + } + stream << "-- setting output lines to fulfil dummy functionality" << std::endl; + stream << "micro_stepper_en_o <= '1';" << std::endl; + stream << "event_o <= (others => '0');" << std::endl; + stream << "event_we_o <= '0';" << std::endl; + stream << std::endl; + } else { + // system signal mapping + stream << "rst <= rst_i;" << std::endl; + stream << "micro_stepper_en_o <= micro_stepper_en;" << std::endl; + stream << "event_o <= event_bus;" << std::endl; + stream << "event_we_o <= event_we;" << std::endl; + stream << std::endl; + + // stall management + stream << "-- stalling microstepper" << std::endl; + stream << "micro_stepper_en <= completed_sig or not ( '0' "; + for (auto state : _states) { + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << std::endl << " or entry_set_" << ATTR(state, "documentOrder") + << "_i"; + } + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << std::endl << " or exit_set_" << ATTR(state, "documentOrder") + << "_i"; + } + } + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << std::endl << " or transition_set_" << ATTR(transition, "postFixOrder") + << "_i"; + } + } + stream << ");" << std::endl; + stream << std::endl; + + // sequential code operation + stream << "-- seq code block " << std::endl; + stream << "ex_content_block : process (clk, rst) " << std::endl; + stream << "begin" << std::endl; + stream << " if rst = '1' then" << std::endl; + for (int i = 0; i < _execContent.size(); i++) { + stream << " done_" << toStr(i) << "_sig <= '0';" << std::endl; + } + stream << " event_bus <= (others => '0');" << std::endl; + stream << " event_we <= '0';" << std::endl; + stream << " cmpl_buf <= '0';" << std::endl; + stream << " completed_sig <= '0';" << std::endl; + stream << " elsif rising_edge(clk) then" << std::endl; + + stream << " if micro_stepper_en = '1' then" << std::endl; + stream << " cmpl_buf <= '0' ;" << std::endl; + stream << " else" << std::endl; + stream << " cmpl_buf <= seq_" << toStr(_execContent.size() - 1) + << "_sig;" << std::endl; + stream << " end if;" << std::endl; + stream << " completed_sig <= cmpl_buf;" << std::endl << std::endl; + + size_t i = 0; + std::string seperator = " "; + for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { + DOMElement *exContentElem = *ecIter; + + if (isSupportedExecContent(exContentElem)) { + + stream << seperator << "if start_" << toStr(i) << "_sig = '1' then" + << std::endl; + + size_t jj = 0; + for (auto eventIter = _eventNames.begin(); eventIter != _eventNames.end(); eventIter++, jj++) { + if (((*eventIter)->value) == ATTR(exContentElem, "event")) { + break; + } + } + stream << " event_bus <= \"" << toBinStr(jj, _eventBitSize+1) << "\";" << std::endl; + stream << " done_" << toStr(i) << "_sig <= '1';" << std::endl; + stream << " event_we <= '1';" << std::endl; + seperator = " els"; + } + } + stream << " elsif micro_stepper_en = '1' then" << std::endl; + i = 0; + //for (auto exContentElem : _execContent) { + for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { + DOMElement *exContentElem = *ecIter; + if (isSupportedExecContent(exContentElem)) { + stream << " done_" << toStr(i) << "_sig <= '0';" << std::endl; + } + } + stream << " event_we <= '0';" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << "end process;" << std::endl; + stream << std::endl; + + i = 0; + for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { + // start lines + stream << "start_" << toStr(i) << "_sig <= " + << getLineForExecContent(*ecIter) << " and " + << "not done_" << toStr(i) << "_sig"; + + // if not needed, since seq_0_sig is hard coded as '1'. +// if (i != 0) { // if not first element + stream << " and seq_" << toStr(i) << "_sig"; +// } + + stream << ";" << std::endl; + + } + + stream << "seq_0_sig <= '1';" << std::endl; + + if (_execContent.size() > 1) { + i = 0; + for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { + // prevent writing seq_0_sig since this should be hardcoded to '1' + if (i != 0) { + // seq lines (input if process i is in seqence now) + stream << "seq_" << toStr(i) << "_sig <= " + << "done_" << toStr(i - 1) << "_sig or " + << "( not " + << getLineForExecContent(*ecIter); + stream << " and seq_" << toStr(i - 1) << "_sig"; + stream << " );" << std::endl; + } + } + } + stream << std::endl; } - } - signalDecls.sort(); - for (std::list::iterator iter = signalDecls.begin(); iter != signalDecls.end(); iter++) { - stream << *iter << std::endl; + stream << "end behavioral; " << + std::endl; + stream << "-- END Event Controller Logic" << + std::endl; + stream << + std::endl; } - stream << std::endl; + std::string ChartToVHDL::getLineForExecContent(const DOMNode *elem) { + const DOMNode *ecBlock = elem; + while (ecBlock) { + if (ecBlock->getNodeType() == DOMNode::ELEMENT_NODE) { + std::string localName = LOCALNAME_CAST(ecBlock); + if (localName == XML_PREFIX(_scxml).str() + "transition") { + return "transition_set_" + ATTR_CAST(ecBlock, "postFixOrder") + "_i"; + } - stream << "-- transition signals" << std::endl; - stream << "signal spontaneous_en : std_logic;" << std::endl; - stream << "signal spontaneous_active : std_logic;" << std::endl; - stream << "signal optimal_transition_set_combined_sig : std_logic;" << std::endl; + if (localName == XML_PREFIX(_scxml).str() + "onentry") { + return "entry_set_" + ATTR_CAST(ecBlock->getParentNode(), "documentOrder") + "_i"; + } - for (auto transition : _transitions) { - stream << "signal in_optimal_transition_set_" << ATTR(transition, "postFixOrder") << "_sig : std_logic;" - << std::endl; - } - stream << std::endl; - - stream << "-- event signals" << std::endl; - stream << "signal int_event_write_en : std_logic;" << std::endl; - stream << "signal int_event_read_en : std_logic;" << std::endl; - stream << "signal int_event_empty : std_logic;" << std::endl; - stream << "signal int_event_input : event_type;" << std::endl; - stream << "signal int_event_output : event_type;" << std::endl; - stream << "signal next_event_re : std_logic;" << std::endl; - stream << "signal next_event_dequeued : std_logic;" << std::endl; - stream << "signal next_event : event_type;" << std::endl; - stream << "signal event_consumed : std_logic;" << std::endl; - stream << std::endl; - - std::list eventNames = _eventTrie.getWordsWithPrefix(""); - for (std::list::iterator eventIter = eventNames.begin(); - eventIter != eventNames.end(); eventIter++) { - stream << "signal event_" << escapeMacro((*eventIter)->value) << "_sig : std_logic;" << std::endl; - } - stream << std::endl; - - stream << "-- error signals" << std::endl; - stream << "signal reg_error_out : std_logic;" << std::endl; - stream << "signal error_full_int_event_fifo : std_logic;" << std::endl; - stream << std::endl; - - // add components - stream << "-- event FIFO" << std::endl; - stream << "component std_fifo is" << std::endl; - stream << "port ( " << std::endl; - stream << " clk : in std_logic;" << std::endl; - stream << " rst : in std_logic;" << std::endl; - stream << " write_en : in std_logic;" << std::endl; - stream << " read_en : in std_logic;" << std::endl; - stream << " data_in : in event_type;" << std::endl; - stream << " data_out : out event_type;" << std::endl; - stream << " empty : out std_logic;" << std::endl; - stream << " full : out std_logic" << std::endl; // we calculate how much we need - stream << ");" << std::endl; - stream << "end component;" << std::endl; - stream << std::endl; -} - -void ChartToVHDL::writeModuleInstantiation(std::ostream &stream) { - // instantiate event fifo - stream << "int_event_fifo : component std_fifo " << std::endl; - stream << "port map ( " << std::endl; - stream << " clk => clk," << std::endl; - stream << " rst => rst_i," << std::endl; - stream << " write_en => int_event_write_en," << std::endl; - stream << " read_en => int_event_read_en," << std::endl; - stream << " data_in => int_event_input," << std::endl; - stream << " data_out => int_event_output," << std::endl; - stream << " empty => int_event_empty," << std::endl; - stream << " full => error_full_int_event_fifo" << std::endl; // we calculate how much we need - stream << ");" << std::endl; - stream << std::endl; -} - -void ChartToVHDL::writeErrorHandler(std::ostream &stream) { - // sets error output signal if an error occures somewhere - stream << "-- error handler" << std::endl; - stream << "-- sets error output signal if an error occures somewhere" << std::endl; - stream << "error_handler : process (clk, rst) " << std::endl; - stream << "begin" << std::endl; - stream << " if rst = '1' then" << std::endl; - stream << " reg_error_out <= '0';" << std::endl; - stream << " elsif rising_edge(clk) then" << std::endl; - stream << " reg_error_out <= error_full_int_event_fifo;" << std::endl; - stream << " end if;" << std::endl; - stream << "end process;" << std::endl; - stream << std::endl; -} - -void ChartToVHDL::writeResetHandler(std::ostream &stream) { - stream << "-- reset handler" << std::endl; - stream << "rst <= rst_i;" << std::endl; - stream << std::endl; -} - -void ChartToVHDL::writeSpontaneousHandler(std::ostream &stream) { - // sets spontaneous signal - stream << "-- spontaneous handler" << std::endl; - stream << "spontaneous_handler : process (clk, rst) " << std::endl; - stream << "begin" << std::endl; - stream << " if rst = '1' then" << std::endl; - stream << " spontaneous_en <= '1';" << std::endl; - stream << " elsif rising_edge(clk) and stall = '0' then" << std::endl; - stream << " if spontaneous_en = '1' then" << std::endl; - stream << " spontaneous_en <= optimal_transition_set_combined_sig;" << std::endl; - stream << " else" << std::endl; - //if new event is dequeued then 1 else stay 0 - stream << " spontaneous_en <= next_event_dequeued;" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << "end process;" << std::endl; - stream << std::endl; -} - -void ChartToVHDL::writeInternalEventHandler(std::ostream &stream) { - // Add controler specific stuff here - stream << "-- event handler" << std::endl; - stream << "-- pops events and set event signals" << std::endl; - stream << "event_handler : process (clk, rst) " << std::endl; - stream << "begin" << std::endl; - stream << " if rst = '1' then" << std::endl; - - std::list eventNames = _eventTrie.getWordsWithPrefix(""); - for (std::list::iterator eventIter = eventNames.begin(); - eventIter != eventNames.end(); eventIter++) { - stream << " event_" << escapeMacro((*eventIter)->value) << "_sig <= '0';" << std::endl; + if (localName == XML_PREFIX(_scxml).str() + "onexit") { + return "exit_set_" + ATTR_CAST(ecBlock->getParentNode(), "documentOrder") + "_i"; + } + + } + ecBlock = ecBlock->getParentNode(); + } + + return ""; } - stream << " next_event_dequeued <= '0';" << std::endl; - stream << " event_consumed <= '0';" << std::endl; + void ChartToVHDL::writeMicroStepper(std::ostream &stream) { + // create MicroStepper top level + stream << "-- FSM Logic" << std::endl; + writeIncludes(stream); + stream << "entity micro_stepper is" << std::endl; + stream << "port(" << std::endl; + stream << " --inputs" << std::endl; + stream << " clk :in std_logic;" << std::endl; + stream << " rst_i :in std_logic;" << std::endl; + stream << " en :in std_logic;" << std::endl; + stream << " next_event_i :in std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << " next_event_we_i :in std_logic;" << std::endl; + stream << " --outputs" << std::endl; + stream << " error_o :out std_logic;" << std::endl; - stream << " elsif falling_edge(clk) and stall = '0' then" << std::endl; + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; - VContainer eventConsumed = VOR; - for (auto transition : _transitions) { + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; + } - if (HAS_ATTR(transition, "event") == true) { - *eventConsumed += VLINE("in_optimal_transition_set_" - + ATTR(transition, "postFixOrder") + "_sig"); + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; + } } - } - VBranch *tree = (VASSIGN, - VLINE("event_consumed"), - eventConsumed); - tree->print(stream); - stream << ";" << std::endl; - - stream << " if int_event_empty = '0' then " << std::endl; - stream << " case next_event is " << std::endl; - for (std::list::iterator eventIter = eventNames.begin(); - eventIter != eventNames.end(); eventIter++) { - stream << " when hwe_" - << escapeMacro((*eventIter)->value) << " =>" << std::endl; - for (std::list::iterator eventIter2 = eventNames.begin(); - eventIter2 != eventNames.end(); eventIter2++) { - stream << " event_" << escapeMacro((*eventIter2)->value); - if (escapeMacro((*eventIter)->value) == escapeMacro((*eventIter2)->value)) { - stream << "_sig <= '1';" << std::endl; - } else { - stream << "_sig <= '0';" << std::endl; + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") << "_o :out std_logic;" + << std::endl; } } - stream << " next_event_dequeued <= '1';" << std::endl; - } - stream << " when others =>" << std::endl; - for (std::list::iterator eventIter = eventNames.begin(); - eventIter != eventNames.end(); eventIter++) { - stream << " event_" << escapeMacro((*eventIter)->value) << "_sig <= '0';" << std::endl; + + stream << " completed_o :out std_logic" << std::endl; + stream << ");" << std::endl; + stream << "end micro_stepper; " << std::endl; + + stream << std::endl; + stream << "architecture behavioral of micro_stepper is " << std::endl; + stream << std::endl; + + // Add signals and components + writeSignalsAndComponents(stream); + + stream << std::endl; + stream << "begin" << std::endl; + stream << std::endl; + + // signal mapping + writeModuleInstantiation(stream); + + // signal handler + writeSpontaneousHandler(stream); + writeErrorHandler(stream); + writeInternalEventHandler(stream); + writeStateHandler(stream); + writeResetHandler(stream); + + // combinatorial logic for Sn+1 + writeOptimalTransitionSetSelection(stream); + writeExitSet(stream); + writeCompleteEntrySet(stream); + writeEntrySet(stream); + //writeDefaultCompletions(stream); + writeActiveStateNplusOne(stream); + + // connect output signals + writeSystemSignalMapping(stream); + + + stream << std::endl; + stream << "end behavioral; " << std::endl; + stream << "-- END FSM Logic" << std::endl; } - stream << " next_event_dequeued <= '0';" << std::endl; - stream << " end case;" << std::endl; - stream << " elsif int_event_empty = '1' and event_consumed = '1' then" << std::endl; - for (std::list::iterator eventIter = eventNames.begin(); - eventIter != eventNames.end(); eventIter++) { - stream << " event_" << escapeMacro((*eventIter)->value) << "_sig <= '0';" << std::endl; + void ChartToVHDL::writeFiFo(std::ostream &stream) { + // taken from: http://www.deathbylogic.com/2013/07/vhdl-standard-fifo/ + // alternativly take fifo logic for a ram device: http://www.eng.auburn.edu/~strouce/class/elec4200/vhdlmods.pdf + stream << "-- standard FIFO buffer" << std::endl; + writeIncludes(stream); + stream << "" << std::endl; + stream << "entity std_fifo is" << std::endl; + stream << "generic (" << std::endl; + stream << " constant FIFO_DEPTH : positive := 256" << std::endl; + stream << ");" << std::endl; + stream << "port ( " << std::endl; + stream << " clk : in std_logic;" << std::endl; + stream << " rst : in std_logic;" << std::endl; + stream << " write_en : in std_logic;" << std::endl; + stream << " read_en : in std_logic;" << std::endl; + stream << " data_in : in std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << " data_out : out std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << " empty : out std_logic;" << std::endl; + stream << " full : out std_logic" << std::endl; + stream << ");" << std::endl; + stream << "end std_fifo;" << std::endl; + stream << "" << std::endl; + stream << "architecture behavioral of std_fifo is" << std::endl; + stream << "begin" << std::endl; + stream << "-- Memory Pointer Process" << std::endl; + stream << "fifo_proc : process (clk)" << std::endl; + stream << " type FIFO_Memory is array (0 to FIFO_DEPTH - 1) of std_logic_vector( " << _eventBitSize << + " downto 0);" << std::endl; + stream << " variable Memory : FIFO_Memory;" << std::endl; + stream << "" << std::endl; + stream << " variable Head : natural range 0 to FIFO_DEPTH - 1;" << std::endl; + stream << " variable Tail : natural range 0 to FIFO_DEPTH - 1;" << std::endl; + stream << "" << std::endl; + stream << " variable Looped : boolean;" << std::endl; + stream << "begin" << std::endl; + stream << " if rising_edge(clk) then" << std::endl; + stream << " if rst = '1' then" << std::endl; + stream << " Head := 0;" << std::endl; + stream << " Tail := 0;" << std::endl; + stream << "" << std::endl; + stream << " Looped := false;" << std::endl; + stream << "" << std::endl; + stream << " full <= '0';" << std::endl; + stream << " empty <= '1';" << std::endl; + stream << " else" << std::endl; + stream << " if (read_en = '1') then" << std::endl; + stream << " if ((Looped = true) or (Head /= Tail)) then" << std::endl; + stream << " -- Update data output" << std::endl; + stream << " data_out <= Memory(Tail);" << std::endl; + stream << " " << std::endl; + stream << " -- Update Tail pointer as needed" << std::endl; + stream << " if (Tail = FIFO_DEPTH - 1) then" << std::endl; + stream << " Tail := 0;" << std::endl; + stream << " " << std::endl; + stream << " Looped := false;" << std::endl; + stream << " else" << std::endl; + stream << " Tail := Tail + 1;" << std::endl; + stream << " end if;" << std::endl; + stream << "" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << "" << std::endl; + stream << " if (write_en = '1') then" << std::endl; + stream << " if ((Looped = false) or (Head /= Tail)) then" << std::endl; + stream << " -- Write Data to Memory" << std::endl; + stream << " Memory(Head) := data_in;" << std::endl; + stream << " " << std::endl; + stream << " -- Increment Head pointer as needed" << std::endl; + stream << " if (Head = FIFO_DEPTH - 1) then" << std::endl; + stream << " Head := 0;" << std::endl; + stream << " " << std::endl; + stream << " Looped := true;" << std::endl; + stream << " else" << std::endl; + stream << " Head := Head + 1;" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << "" << std::endl; + stream << " -- Update empty and full flags" << std::endl; + stream << " if (Head = Tail) then" << std::endl; + stream << " if Looped then" << std::endl; + stream << " full <= '1';" << std::endl; + stream << " else" << std::endl; + stream << " empty <= '1';" << std::endl; + stream << " end if;" << std::endl; + stream << " else" << std::endl; + stream << " empty <= '0';" << std::endl; + stream << " full <= '0';" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << "end process;" << std::endl; + stream << "" << std::endl; + stream << "end behavioral;" << std::endl; + stream << "-- END standard FIFO buffer" << std::endl; } - stream << " next_event_dequeued <= '0';" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << "end process;" << std::endl; - stream << std::endl; - - stream << "next_event_re <= not int_event_empty and not stall; " << std::endl; - stream << "next_event <= int_event_output; " << std::endl; - stream << "int_event_write_en <= next_event_we_i; " << std::endl; - stream << "int_event_input <= next_event_i; " << std::endl; - stream << "int_event_read_en <= not stall; --not spontaneous_en and " << std::endl; - stream << std::endl; -} - -void ChartToVHDL::writeActiveStateNplusOne(std::ostream &stream) { - stream << "-- active configuration" << std::endl; - - for (auto state : _states) { - std::string parent = ATTR(state, "parent"); - - // special case for to start the state machine - if (parent.size() == 0) { - stream << " state_next_" << ATTR(state, "documentOrder") << "_sig <= " << - "not completed_sig;" << std::endl; - continue; - } - VBranch *tree = (VASSIGN, - VLINE("state_next_" + ATTR(state, "documentOrder") + "_sig"), - (VOR, - VLINE("in_complete_entry_set_" + ATTR(state, "documentOrder") + "_sig"), - (VAND, (VNOT, VLINE("in_exit_set_" + ATTR(state, "documentOrder") + "_sig")), - VLINE("state_active_" + ATTR(state, "documentOrder") + "_sig")) - )); + void ChartToVHDL::writeSignalsAndComponents(std::ostream &stream) { + // create internal signals + stream << "-- system signals" << std::endl; + stream << "signal stall : std_logic;" << std::endl; + stream << "signal completed_sig : std_logic;" << std::endl; + stream << "signal rst : std_logic;" << std::endl; + stream << std::endl; - tree->print(stream); - stream << ";" << std::endl; + stream << "-- state signals" << std::endl; - } -} - -void ChartToVHDL::writeOptimalTransitionSetSelection(std::ostream &stream) { - stream << "-- optimal transition set selection" << std::endl; - VContainer optimalTransitions = VOR; - VContainer spontaneoursActive = VOR; - - for (auto transIter = _transitions.begin(); transIter != _transitions.end(); transIter++) { - DOMElement *transition = *transIter; - std::string conflicts = ATTR(transition, "conflictBools"); - - - VContainer nameMatchers = VOR; - if (HAS_ATTR(transition, "event")) { - std::list eventDescs = tokenize(ATTR(transition, "event")); - for (std::list::iterator descIter = eventDescs.begin(); - descIter != eventDescs.end(); descIter++) { - std::list eventNames = _eventTrie.getWordsWithPrefix( - (*descIter) == "*" ? "" : *descIter); - for (std::list::iterator eventIter = eventNames.begin(); - eventIter != eventNames.end(); eventIter++) { - *nameMatchers += VLINE("event_" + escapeMacro((*eventIter)->value) + "_sig"); - } + std::list signalDecls; + + for (auto state : _states) { + std::string parent = ATTR(state, "parent"); + + signalDecls.push_back("signal state_active_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); + signalDecls.push_back("signal state_next_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); + signalDecls.push_back("signal in_entry_set_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); + signalDecls.push_back("signal in_exit_set_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); + signalDecls.push_back("signal in_complete_entry_set_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); + + // not needed for state + if (parent.size() != 0) { + signalDecls.push_back( + "signal in_complete_entry_set_up_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); } - } else { - *nameMatchers += VLINE("'1'"); } - VContainer conflicters = VOR; - for (size_t j = 0; j < strTo(ATTR(transition, "postFixOrder")); j++) { - if (conflicts[j] == '1') { - *conflicters += VLINE("in_optimal_transition_set_" + toStr(j) + "_sig"); - } + signalDecls.sort(); + for (std::list::iterator iter = signalDecls.begin(); iter != signalDecls.end(); iter++) { + stream << *iter << std::endl; } + stream << std::endl; - VBranch *tree = (VASSIGN, - VLINE("in_optimal_transition_set_" + ATTR(transition, "postFixOrder") + "_sig"), - (VAND, - (HAS_ATTR(transition, "event") - ? (VNOT, VLINE("spontaneous_active")) - : (VNOP, VLINE("spontaneous_en"))), - VLINE("state_active_" + ATTR(transition, "source") + "_sig"), - nameMatchers, - (VNOT, conflicters))); - tree->print(stream); - stream << ";" << std::endl; + stream << "-- transition signals" << std::endl; + stream << "signal spontaneous_en : std_logic;" << std::endl; + stream << "signal spontaneous_active : std_logic;" << std::endl; + stream << "signal optimal_transition_set_combined_sig : std_logic;" << std::endl; - *optimalTransitions += VLINE("in_optimal_transition_set_" - + ATTR(transition, "postFixOrder") + "_sig"); - if (HAS_ATTR(transition, "event") == false) { - *spontaneoursActive += VLINE("in_optimal_transition_set_" - + ATTR(transition, "postFixOrder") + "_sig"); + for (auto transition : _transitions) { + stream << "signal in_optimal_transition_set_" << ATTR(transition, "postFixOrder") << "_sig : std_logic;" + << std::endl; + } + stream << std::endl; + + stream << "-- event signals" << std::endl; + stream << "signal int_event_write_en : std_logic;" << std::endl; + stream << "signal int_event_read_en : std_logic;" << std::endl; + stream << "signal int_event_empty : std_logic;" << std::endl; + stream << "signal int_event_input : std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << "signal int_event_output : std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << "signal next_event_re : std_logic;" << std::endl; + stream << "signal next_event_dequeued : std_logic;" << std::endl; + stream << "signal next_event : std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << "signal event_consumed : std_logic;" << std::endl; + stream << std::endl; + + for (std::list::iterator eventIter = _eventNames.begin(); + eventIter != _eventNames.end(); eventIter++) { + stream << "signal event_" << escapeMacro((*eventIter)->value) << "_sig : std_logic;" << std::endl; } + stream << std::endl; + + stream << "-- error signals" << std::endl; + stream << "signal reg_error_out : std_logic;" << std::endl; + stream << "signal error_full_int_event_fifo : std_logic;" << std::endl; + stream << std::endl; + + // add components + stream << "-- event FIFO" << std::endl; + stream << "component std_fifo is" << std::endl; + stream << "port ( " << std::endl; + stream << " clk : in std_logic;" << std::endl; + stream << " rst : in std_logic;" << std::endl; + stream << " write_en : in std_logic;" << std::endl; + stream << " read_en : in std_logic;" << std::endl; + stream << " data_in : in std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << " data_out : out std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << " empty : out std_logic;" << std::endl; + stream << " full : out std_logic" << std::endl; // we calculate how much we need + stream << ");" << std::endl; + stream << "end component;" << std::endl; + stream << std::endl; } - VBranch *tree = (VASSIGN, - VLINE("optimal_transition_set_combined_sig"), - optimalTransitions); - tree->print(stream); - stream << ";" << std::endl; + void ChartToVHDL::writeModuleInstantiation(std::ostream &stream) { + // instantiate event fifo + stream << "int_event_fifo : component std_fifo " << std::endl; + stream << "port map ( " << std::endl; + stream << " clk => clk," << std::endl; + stream << " rst => rst_i," << std::endl; + stream << " write_en => int_event_write_en," << std::endl; + stream << " read_en => int_event_read_en," << std::endl; + stream << " data_in => int_event_input," << std::endl; + stream << " data_out => int_event_output," << std::endl; + stream << " empty => int_event_empty," << std::endl; + stream << " full => error_full_int_event_fifo" << std::endl; // we calculate how much we need + stream << ");" << std::endl; + stream << std::endl; + } + + void ChartToVHDL::writeErrorHandler(std::ostream &stream) { + // sets error output signal if an error occures somewhere + stream << "-- error handler" << std::endl; + stream << "-- sets error output signal if an error occures somewhere" << std::endl; + stream << "error_handler : process (clk, rst) " << std::endl; + stream << "begin" << std::endl; + stream << " if rst = '1' then" << std::endl; + stream << " reg_error_out <= '0';" << std::endl; + stream << " elsif rising_edge(clk) then" << std::endl; + stream << " reg_error_out <= error_full_int_event_fifo;" << std::endl; + stream << " end if;" << std::endl; + stream << "end process;" << std::endl; + stream << std::endl; + } + + void ChartToVHDL::writeResetHandler(std::ostream &stream) { + stream << "-- reset handler" << std::endl; + stream << "rst <= rst_i;" << std::endl; + stream << std::endl; + } + + void ChartToVHDL::writeSpontaneousHandler(std::ostream &stream) { + // sets spontaneous signal + stream << "-- spontaneous handler" << std::endl; + stream << "spontaneous_handler : process (clk, rst) " << std::endl; + stream << "begin" << std::endl; + stream << " if rst = '1' then" << std::endl; + stream << " spontaneous_en <= '1';" << std::endl; + stream << " elsif rising_edge(clk) and stall = '0' then" << std::endl; + stream << " if spontaneous_en = '1' then" << std::endl; + stream << " spontaneous_en <= optimal_transition_set_combined_sig;" << std::endl; + stream << " else" << std::endl; + //if new event is dequeued then 1 else stay 0 + stream << " spontaneous_en <= next_event_dequeued;" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << "end process;" << std::endl; + stream << std::endl; + } - VBranch *tree2 = (VASSIGN, - VLINE("spontaneous_active"), - spontaneoursActive); - tree2->print(stream); - stream << ";" << std::endl; -} + void ChartToVHDL::writeInternalEventHandler(std::ostream &stream) { + // Add controler specific stuff here + stream << "-- event handler" << std::endl; + stream << "-- pops events and set event signals" << std::endl; + stream << "event_handler : process (clk, rst) " << std::endl; + stream << "begin" << std::endl; + stream << " if rst = '1' then" << std::endl; -void ChartToVHDL::writeExitSet(std::ostream &stream) { - stream << "-- exit set selection" << std::endl; + for (std::list::iterator eventIter = _eventNames.begin(); + eventIter != _eventNames.end(); eventIter++) { + stream << " event_" << escapeMacro((*eventIter)->value) << "_sig <= '0';" << std::endl; + } - for (auto state : _states) { + stream << " next_event_dequeued <= '0';" << std::endl; + stream << " event_consumed <= '0';" << std::endl; - std::string completion = ATTR(state, "completionBools"); - std::string ancestors = ATTR(state, "ancBools"); - std::string children = ATTR(state, "childBools"); - std::string parent = ATTR(state, "parent"); + stream << " elsif falling_edge(clk) and stall = '0' then" << std::endl; - VContainer exitsetters = VOR; + VContainer eventConsumed = VOR; for (auto transition : _transitions) { - std::string exitSet = ATTR(transition, "exitSetBools"); - if (exitSet.at(strTo(ATTR(state, "documentOrder"))) == '1') { - *exitsetters += VLINE("in_optimal_transition_set_" + ATTR(transition, "postFixOrder") + "_sig "); + + if (HAS_ATTR(transition, "event") == true) { + *eventConsumed += VLINE("in_optimal_transition_set_" + + ATTR(transition, "postFixOrder") + "_sig"); } } VBranch *tree = (VASSIGN, - VLINE("in_exit_set_" + ATTR(state, "documentOrder") + "_sig"), - (VAND, - VLINE("state_active_" + ATTR(state, "documentOrder") + "_sig"), - exitsetters)); - + VLINE("event_consumed"), + eventConsumed); tree->print(stream); stream << ";" << std::endl; - } -} - -void ChartToVHDL::writeEntrySet(std::ostream &stream) { - stream << "-- entry set selection" << std::endl; - for (auto state : _states) { + stream << " if int_event_empty = '0' then " << std::endl; + stream << " case next_event is " << std::endl; + + size_t jj = 0; + for (std::list::iterator eventIter = _eventNames.begin(); + eventIter != _eventNames.end(); eventIter++, jj++) { + + stream << " when \"" << toBinStr(jj, _eventBitSize+1) << "\" =>" << std::endl; + for (std::list::iterator eventIter2 = _eventNames.begin(); + eventIter2 != _eventNames.end(); eventIter2++) { + stream << " event_" << escapeMacro((*eventIter2)->value); + if (escapeMacro((*eventIter)->value) == escapeMacro((*eventIter2)->value)) { + stream << "_sig <= '1';" << std::endl; + } else { + stream << "_sig <= '0';" << std::endl; + } + } + stream << " next_event_dequeued <= '1';" << std::endl; + } + stream << " when others =>" << std::endl; + for (std::list::iterator eventIter = _eventNames.begin(); + eventIter != _eventNames.end(); eventIter++) { + stream << " event_" << escapeMacro((*eventIter)->value) << "_sig <= '0';" << std::endl; + } + stream << " next_event_dequeued <= '0';" << std::endl; + stream << " end case;" << std::endl; + stream << " elsif int_event_empty = '1' and event_consumed = '1' then" << std::endl; - VBranch *tree = (VASSIGN, - VLINE("in_entry_set_" + ATTR(state, "documentOrder") + "_sig"), - (VAND, - VLINE("in_complete_entry_set_" + ATTR(state, "documentOrder") + "_sig"), - (VOR, VLINE("in_exit_set_" + ATTR(state, "documentOrder") + "_sig"), - (VNOT, VLINE("state_active_" + ATTR(state, "documentOrder") + "_sig"))))); + for (std::list::iterator eventIter = _eventNames.begin(); + eventIter != _eventNames.end(); eventIter++) { + stream << " event_" << escapeMacro((*eventIter)->value) << "_sig <= '0';" << std::endl; + } + stream << " next_event_dequeued <= '0';" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << "end process;" << std::endl; + stream << std::endl; - tree->print(stream); - stream << ";" << std::endl; + stream << "next_event_re <= not int_event_empty and not stall; " << std::endl; + stream << "next_event <= int_event_output; " << std::endl; + stream << "int_event_write_en <= next_event_we_i; " << std::endl; + stream << "int_event_input <= next_event_i; " << std::endl; + stream << "int_event_read_en <= not stall; --not spontaneous_en and " << std::endl; + stream << std::endl; } -} -void ChartToVHDL::writeCompleteEntrySet(std::ostream &stream) { - stream << "-- complete entry set selection" << std::endl; + void ChartToVHDL::writeActiveStateNplusOne(std::ostream &stream) { + stream << "-- active configuration" << std::endl; - for (auto state : _states) { - std::string completion = ATTR(state, "completionBools"); - std::string ancestors = ATTR(state, "ancBools"); - std::string children = ATTR(state, "childBools"); - std::string parent = ATTR(state, "parent"); + for (auto state : _states) { + std::string parent = ATTR(state, "parent"); - if (parent.size() == 0) { - continue; // skips node - } + // special case for to start the state machine + if (parent.size() == 0) { + stream << " state_next_" << ATTR(state, "documentOrder") << "_sig <= " << + "not completed_sig;" << std::endl; + continue; + } + VBranch *tree = (VASSIGN, + VLINE("state_next_" + ATTR(state, "documentOrder") + "_sig"), + (VOR, + VLINE("in_complete_entry_set_" + ATTR(state, "documentOrder") + "_sig"), + (VAND, (VNOT, VLINE("in_exit_set_" + ATTR(state, "documentOrder") + "_sig")), + VLINE("state_active_" + ATTR(state, "documentOrder") + "_sig")) + )); + + tree->print(stream); + stream << ";" << std::endl; - // EntrySet for every state types - VContainer optimalEntrysetters = VOR; - for (auto transition : _transitions) { - // Is this state in TargetSet of the transition? - std::string targetSet = ATTR(transition, "targetBools"); - if (targetSet[strTo(ATTR(state, "documentOrder"))] == '1') { - //yes? then add the transition to optimal entry set of the state - *optimalEntrysetters += - VLINE("in_optimal_transition_set_" + ATTR(transition, "postFixOrder") + "_sig"); - } } + } - // if composite state (or root) we have to add ancestor completion - VContainer completeEntrysetters = VOR; - if (isCompound(state) || isParallel(state)) { - for (auto tmp_state : _states) { - // is tmp_state is child of state continue? - if (children[strTo(ATTR(state, "documentOrder"))] == '1') { - // yes? then add its complete_entry_set_up as ancestor completion - *completeEntrysetters += - VLINE("in_complete_entry_set_up_" + ATTR(tmp_state, "documentOrder") + "_sig"); + void ChartToVHDL::writeOptimalTransitionSetSelection(std::ostream &stream) { + stream << "-- optimal transition set selection" << std::endl; + VContainer optimalTransitions = VOR; + VContainer spontaneoursActive = VOR; + + for (auto transIter = _transitions.begin(); transIter != _transitions.end(); transIter++) { + DOMElement *transition = *transIter; + std::string conflicts = ATTR(transition, "conflictBools"); + + + VContainer nameMatchers = VOR; + if (HAS_ATTR(transition, "event")) { + std::list eventDescs = tokenize(ATTR(transition, "event")); + for (std::list::iterator descIter = eventDescs.begin(); + descIter != eventDescs.end(); descIter++) { + std::list eventNames = _eventTrie.getWordsWithPrefix( + (*descIter) == "*" ? "" : *descIter); + for (std::list::iterator eventIter = eventNames.begin(); + eventIter != eventNames.end(); eventIter++) { + *nameMatchers += VLINE("event_" + escapeMacro((*eventIter)->value) + "_sig"); + } } + } else { + *nameMatchers += VLINE("'1'"); + } + + VContainer conflicters = VOR; + for (size_t j = 0; j < strTo(ATTR(transition, "postFixOrder")); j++) { + if (conflicts[j] == '1') { + *conflicters += VLINE("in_optimal_transition_set_" + toStr(j) + "_sig"); + } + } + + VBranch *tree = (VASSIGN, + VLINE("in_optimal_transition_set_" + ATTR(transition, "postFixOrder") + "_sig"), + (VAND, + (HAS_ATTR(transition, "event") + ? (VNOT, VLINE("spontaneous_active")) + : (VNOP, VLINE("spontaneous_en"))), + VLINE("state_active_" + ATTR(transition, "source") + "_sig"), + nameMatchers, + (VNOT, conflicters))); + + tree->print(stream); + stream << ";" << std::endl; + + *optimalTransitions += VLINE("in_optimal_transition_set_" + + ATTR(transition, "postFixOrder") + "_sig"); + if (HAS_ATTR(transition, "event") == false) { + *spontaneoursActive += VLINE("in_optimal_transition_set_" + + ATTR(transition, "postFixOrder") + "_sig"); } } VBranch *tree = (VASSIGN, - VLINE("in_complete_entry_set_up_" + ATTR(state, "documentOrder") + "_sig"), - (VOR, optimalEntrysetters, completeEntrysetters) - ); + VLINE("optimal_transition_set_combined_sig"), + optimalTransitions); tree->print(stream); stream << ";" << std::endl; + + VBranch *tree2 = (VASSIGN, + VLINE("spontaneous_active"), + spontaneoursActive); + tree2->print(stream); + stream << ";" << std::endl; } + void ChartToVHDL::writeExitSet(std::ostream &stream) { + stream << "-- exit set selection" << std::endl; + + for (auto state : _states) { - // descendant completion - for (auto state : _states) { - std::string completion = ATTR(state, "completionBools"); - std::string ancestors = ATTR(state, "ancBools"); - std::string parent = ATTR(state, "parent"); //is it a int ? + std::string completion = ATTR(state, "completionBools"); + std::string ancestors = ATTR(state, "ancBools"); + std::string children = ATTR(state, "childBools"); + std::string parent = ATTR(state, "parent"); + + VContainer exitsetters = VOR; + for (auto transition : _transitions) { + std::string exitSet = ATTR(transition, "exitSetBools"); + if (exitSet.at(strTo(ATTR(state, "documentOrder"))) == '1') { + *exitsetters += VLINE("in_optimal_transition_set_" + ATTR(transition, "postFixOrder") + "_sig "); + } + } - if (parent.size() == 0) { - continue; // skips node + VBranch *tree = (VASSIGN, + VLINE("in_exit_set_" + ATTR(state, "documentOrder") + "_sig"), + (VAND, + VLINE("state_active_" + ATTR(state, "documentOrder") + "_sig"), + exitsetters)); + + tree->print(stream); + stream << ";" << std::endl; } + } - VContainer descendantCompletion = VAND; - // if parent is compound - if (getParentState(state) != NULL && - isCompound(getParentState(state))) { - std::string children = ATTR_CAST(_states[strTo(parent)], - "childBools"); - - std::string parentInit = ATTR(getParentState(state), "initial"); - if (// if parent has init field an this state is inside --> add it as default completion - (!parentInit.empty() - && ATTR(state, "id").compare(parentInit) == 0) || - // or add this state as default completion when parent has no init field and it is the first in document order - (parentInit.empty() && - (strTo(ATTR(getParentState(state), "documentOrder")) + 1) == - strTo(ATTR(state, "documentOrder")))) { - *descendantCompletion += - VLINE("in_entry_set_" + ATTR(getParentState(state), "documentOrder") + "_sig"); + void ChartToVHDL::writeEntrySet(std::ostream &stream) { + stream << "-- entry set selection" << std::endl; + + for (auto state : _states) { + + VBranch *tree = (VASSIGN, + VLINE("in_entry_set_" + ATTR(state, "documentOrder") + "_sig"), + (VAND, + VLINE("in_complete_entry_set_" + ATTR(state, "documentOrder") + "_sig"), + (VOR, VLINE("in_exit_set_" + ATTR(state, "documentOrder") + "_sig"), + (VNOT, VLINE("state_active_" + ATTR(state, "documentOrder") + "_sig"))))); + + tree->print(stream); + stream << ";" << std::endl; + } + } + + void ChartToVHDL::writeCompleteEntrySet(std::ostream &stream) { + stream << "-- complete entry set selection" << std::endl; + + for (auto state : _states) { + std::string completion = ATTR(state, "completionBools"); + std::string ancestors = ATTR(state, "ancBools"); + std::string children = ATTR(state, "childBools"); + std::string parent = ATTR(state, "parent"); - // but only if compound parent is not already completed + if (parent.size() == 0) { + continue; // skips node + } + + + // EntrySet for every state types + VContainer optimalEntrysetters = VOR; + for (auto transition : _transitions) { + // Is this state in TargetSet of the transition? + std::string targetSet = ATTR(transition, "targetBools"); + if (targetSet[strTo(ATTR(state, "documentOrder"))] == '1') { + //yes? then add the transition to optimal entry set of the state + *optimalEntrysetters += + VLINE("in_optimal_transition_set_" + ATTR(transition, "postFixOrder") + "_sig"); + } + } + + // if composite state (or root) we have to add ancestor completion + VContainer completeEntrysetters = VOR; + if (isCompound(state) || isParallel(state)) { for (auto tmp_state : _states) { - if (tmp_state == state) { - // skip state itselve - continue; - } - if (children[strTo(ATTR(tmp_state, "documentOrder"))] == '1') { - *descendantCompletion += (VNOT, - (VAND, - VLINE("state_active_" + ATTR(tmp_state, "documentOrder") + "_sig"), - (VNOT, - VLINE("in_exit_set_" + ATTR(tmp_state, "documentOrder") + - "_sig")))); + // is tmp_state is child of state continue? + if (children[strTo(ATTR(state, "documentOrder"))] == '1') { + // yes? then add its complete_entry_set_up as ancestor completion + *completeEntrysetters += + VLINE("in_complete_entry_set_up_" + ATTR(tmp_state, "documentOrder") + "_sig"); } } - } else { - // disable this branche - *descendantCompletion += VLINE("'0'"); } - } else - // if parent is parallel + + VBranch *tree = (VASSIGN, + VLINE("in_complete_entry_set_up_" + ATTR(state, "documentOrder") + "_sig"), + (VOR, optimalEntrysetters, completeEntrysetters) + ); + tree->print(stream); + stream << ";" << std::endl; + } + + + // descendant completion + for (auto state : _states) { + std::string completion = ATTR(state, "completionBools"); + std::string ancestors = ATTR(state, "ancBools"); + std::string parent = ATTR(state, "parent"); //is it a int ? + + if (parent.size() == 0) { + continue; // skips node + } + + VContainer descendantCompletion = VAND; + // if parent is compound if (getParentState(state) != NULL && - isParallel(getParentState(state))) { + isCompound(getParentState(state))) { + std::string children = ATTR_CAST(_states[strTo(parent)], + "childBools"); + + std::string parentInit = ATTR(getParentState(state), "initial"); + if (// if parent has init field an this state is inside --> add it as default completion + (!parentInit.empty() + && ATTR(state, "id").compare(parentInit) == 0) || + // or add this state as default completion when parent has no init field and it is the first in document order + (parentInit.empty() && + (strTo(ATTR(getParentState(state), "documentOrder")) + 1) == + strTo(ATTR(state, "documentOrder")))) { + *descendantCompletion += + VLINE("in_entry_set_" + ATTR(getParentState(state), "documentOrder") + "_sig"); + + // but only if compound parent is not already completed + for (auto tmp_state : _states) { + if (tmp_state == state) { + // skip state itselve + continue; + } + if (children[strTo(ATTR(tmp_state, "documentOrder"))] == '1') { + *descendantCompletion += (VNOT, + (VAND, + VLINE("state_active_" + ATTR(tmp_state, "documentOrder") + "_sig"), + (VNOT, + VLINE("in_exit_set_" + ATTR(tmp_state, "documentOrder") + + "_sig")))); + } + } + } else { + // disable this branche + *descendantCompletion += VLINE("'0'"); + } + } else + // if parent is parallel + if (getParentState(state) != NULL && + isParallel(getParentState(state))) { *descendantCompletion += - VLINE("in_complete_entry_set_" + ATTR(getParentState(state), "documentOrder") + "_sig"); + VLINE("in_complete_entry_set_" + ATTR(getParentState(state), "documentOrder") + "_sig"); } - VBranch *tree = (VASSIGN, - VLINE("in_complete_entry_set_" + ATTR(state, "documentOrder") + "_sig"), - (VOR, - VLINE("in_complete_entry_set_up_" + ATTR(state, "documentOrder") + "_sig"), - descendantCompletion)); + VBranch *tree = (VASSIGN, + VLINE("in_complete_entry_set_" + ATTR(state, "documentOrder") + "_sig"), + (VOR, + VLINE("in_complete_entry_set_up_" + ATTR(state, "documentOrder") + "_sig"), + descendantCompletion)); - tree->print(stream); - stream << ";" << std::endl; - } -} - -void ChartToVHDL::writeStateHandler(std::ostream &stream) { - // updater for current state - stream << "-- State Handler" << std::endl; - stream << "-- updates current state" << std::endl; - stream << "state_proc: process(clk, rst, stall)" << std::endl; - stream << "begin" << std::endl; - stream << " if rst = '1' then" << std::endl; - - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") << "_sig <= " << "'0';" << std::endl; + tree->print(stream); + stream << ";" << std::endl; + } } - stream << " in_complete_entry_set_0_sig <= '1';" << std::endl; - stream << " elsif (rising_edge(clk) and stall = '0') then" << std::endl; - stream << " in_complete_entry_set_0_sig <= '0';" << std::endl; - - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") << "_sig <= " << "state_next_" << - ATTR(state, "documentOrder") << "_sig;" << std::endl; - } + void ChartToVHDL::writeStateHandler(std::ostream &stream) { + // updater for current state + stream << "-- State Handler" << std::endl; + stream << "-- updates current state" << std::endl; + stream << "state_proc: process(clk, rst, stall)" << std::endl; + stream << "begin" << std::endl; + stream << " if rst = '1' then" << std::endl; - stream << " end if;" << std::endl; - stream << "end process;" << std::endl; - stream << std::endl; -} + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") << "_sig <= " << "'0';" << std::endl; + } -void ChartToVHDL::writeSystemSignalMapping(std::ostream &stream) { - stream << "-- system signals" << std::endl; - std::list topLevelFinal = DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "final", - _scxml); + stream << " in_complete_entry_set_0_sig <= '1';" << std::endl; + stream << " elsif (rising_edge(clk) and stall = '0') then" << std::endl; + stream << " in_complete_entry_set_0_sig <= '0';" << std::endl; - VContainer tlf = VOR; - for (auto final : topLevelFinal) { - *tlf += VLINE("state_active_" + ATTR(final, "documentOrder") + "_sig"); + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") << "_sig <= " << "state_next_" << + ATTR(state, "documentOrder") << "_sig;" << std::endl; + } + stream << " end if;" << std::endl; + stream << "end process;" << std::endl; + stream << std::endl; } - VBranch *tree = (VASSIGN, - VLINE("completed_sig"), - tlf); - - tree->print(stream); - stream << ";" << std::endl; - - // tmp mapping for events - stream << "stall <= not en or completed_sig or ( int_event_empty and not spontaneous_en ) ; " << std::endl; - stream << std::endl; - - // interface signals - stream << "-- interface signals" << std::endl; - for (auto state : _states) { - stream << "state_active_" << ATTR(state, "documentOrder") - << "_o <= state_active_" << ATTR(state, "documentOrder") - << "_sig;" << std::endl; - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << "exit_set_" << ATTR(state, "documentOrder") - << "_o <= in_exit_set_" << ATTR(state, "documentOrder") - << "_sig;" << std::endl; + void ChartToVHDL::writeSystemSignalMapping(std::ostream &stream) { + stream << "-- system signals" << std::endl; + std::list topLevelFinal = DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "final", + _scxml); + + VContainer tlf = VOR; + for (auto final : topLevelFinal) { + *tlf += VLINE("state_active_" + ATTR(final, "documentOrder") + "_sig"); + } - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << "entry_set_" << ATTR(state, "documentOrder") - << "_o <= in_entry_set_" << ATTR(state, "documentOrder") - << "_sig;" << std::endl; + VBranch *tree = (VASSIGN, + VLINE("completed_sig"), + tlf); + + tree->print(stream); + stream << ";" << std::endl; + + // tmp mapping for events + stream << "stall <= not en or completed_sig or ( int_event_empty and not spontaneous_en ) ; " << std::endl; + stream << std::endl; + + // interface signals + stream << "-- interface signals" << std::endl; + for (auto state : _states) { + stream << "state_active_" << ATTR(state, "documentOrder") + << "_o <= state_active_" << ATTR(state, "documentOrder") + << "_sig;" << std::endl; + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << "exit_set_" << ATTR(state, "documentOrder") + << "_o <= in_exit_set_" << ATTR(state, "documentOrder") + << "_sig;" << std::endl; + } + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << "entry_set_" << ATTR(state, "documentOrder") + << "_o <= in_entry_set_" << ATTR(state, "documentOrder") + << "_sig;" << std::endl; + } } - } - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << "transition_set_" << ATTR(transition, "postFixOrder") - << "_o <= in_optimal_transition_set_" << ATTR(transition, "postFixOrder") - << "_sig;" << std::endl; + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << "transition_set_" << ATTR(transition, "postFixOrder") + << "_o <= in_optimal_transition_set_" << ATTR(transition, "postFixOrder") + << "_sig;" << std::endl; + } } - } - stream << "completed_o <= completed_sig; " << std::endl; - stream << "error_o <= reg_error_out; " << std::endl; - stream << std::endl; -} + stream << "completed_o <= completed_sig; " << std::endl; + stream << "error_o <= reg_error_out; " << std::endl; + stream << std::endl; + } } \ No newline at end of file diff --git a/src/uscxml/transform/ChartToVHDL.h b/src/uscxml/transform/ChartToVHDL.h index b6c7853..d93d59f 100644 --- a/src/uscxml/transform/ChartToVHDL.h +++ b/src/uscxml/transform/ChartToVHDL.h @@ -31,129 +31,129 @@ namespace uscxml { -class USCXML_API ChartToVHDL : public ChartToC { -public: + class USCXML_API ChartToVHDL : public ChartToC { + public: - virtual ~ChartToVHDL(); + virtual ~ChartToVHDL(); - static Transformer transform(const Interpreter &other); + static Transformer transform(const Interpreter &other); - void writeTo(std::ostream &stream); + void writeTo(std::ostream &stream); - struct VNode { - virtual void print(std::ostream &stream, const std::string padding = "") = 0; + struct VNode { + virtual void print(std::ostream &stream, const std::string padding = "") = 0; - virtual ~VNode() { }; - }; - - struct VBranch : VNode { - std::vector v; + virtual ~VNode() { }; + }; - virtual ~VBranch() { - for (unsigned i = 0; i < v.size(); i++) - delete v[i]; - } + struct VBranch : VNode { + std::vector v; - VBranch &operator+=(VNode *p) { - v.push_back(p); - return *this; - } - }; + virtual ~VBranch() { + for (unsigned i = 0; i < v.size(); i++) + delete v[i]; + } - struct VPointer { - VNode *ptr; + VBranch &operator+=(VNode *p) { + v.push_back(p); + return *this; + } + }; - operator VNode *() { - return ptr; - } + struct VPointer { + VNode *ptr; - operator VBranch *() { - return static_cast (ptr); - } + operator VNode *() { + return ptr; + } - VPointer &operator/(VNode *p) { - ptr = p; - return *this; - } - }; + operator VBranch *() { + return static_cast (ptr); + } - struct VContainer { - VBranch *ptr; + VPointer &operator/(VNode *p) { + ptr = p; + return *this; + } + }; - operator VBranch *() { - return ptr; - } + struct VContainer { + VBranch *ptr; - VContainer &operator/(VBranch *p) { - ptr = p; - return *this; - } + operator VBranch *() { + return ptr; + } - VContainer &operator,(VPointer p) { - if (ptr) ptr->v.push_back(p.ptr); - return *this; - } + VContainer &operator/(VBranch *p) { + ptr = p; + return *this; + } - VContainer &operator,(VContainer c) { - if (ptr) ptr->v.push_back(c.ptr); - return *this; - } - }; + VContainer &operator,(VPointer p) { + if (ptr) ptr->v.push_back(p.ptr); + return *this; + } - struct VLine : VNode { - VLine(const std::string &name) : name(name) { } + VContainer &operator,(VContainer c) { + if (ptr) ptr->v.push_back(c.ptr); + return *this; + } + }; - virtual void print(std::ostream &stream, const std::string padding = "") { - stream << " " << name; - } + struct VLine : VNode { + VLine(const std::string &name) : name(name) { } - std::string name; - }; + virtual void print(std::ostream &stream, const std::string padding = "") { + stream << " " << name; + } - struct VAssign : VBranch { - virtual void print(std::ostream &stream, const std::string padding = "") { - v[0]->print(stream, padding); - stream << padding << " <="; - v[1]->print(stream, padding + " "); - } - }; + std::string name; + }; - struct VAnd : VBranch { - virtual void print(std::ostream &stream, const std::string padding = "") { - stream << std::endl << padding << "( '1' "; - for (unsigned i = 0; i < v.size(); i++) { - stream << std::endl << padding << " and"; - v[i]->print(stream, padding + " "); + struct VAssign : VBranch { + virtual void print(std::ostream &stream, const std::string padding = "") { + v[0]->print(stream, padding); + stream << padding << " <="; + v[1]->print(stream, padding + " "); } - stream << padding << ")" << std::endl; - } - }; - - struct VOr : VBranch { - virtual void print(std::ostream &stream, const std::string padding = "") { - stream << std::endl << padding << "( '0' "; - for (unsigned i = 0; i < v.size(); i++) { - stream << std::endl << padding << " or"; - v[i]->print(stream, padding + " "); + }; + + struct VAnd : VBranch { + virtual void print(std::ostream &stream, const std::string padding = "") { + stream << std::endl << padding << "( '1' "; + for (unsigned i = 0; i < v.size(); i++) { + stream << std::endl << padding << " and"; + v[i]->print(stream, padding + " "); + } + stream << padding << ")" << std::endl; } - stream << std::endl << padding << ")" << std::endl; - } - }; + }; + + struct VOr : VBranch { + virtual void print(std::ostream &stream, const std::string padding = "") { + stream << std::endl << padding << "( '0' "; + for (unsigned i = 0; i < v.size(); i++) { + stream << std::endl << padding << " or"; + v[i]->print(stream, padding + " "); + } + stream << std::endl << padding << ")" << std::endl; + } + }; - struct VNot : VBranch { - virtual void print(std::ostream &stream, const std::string padding = "") { - stream << " ( not"; - v[0]->print(stream, padding + " "); - stream << " )"; - } - }; + struct VNot : VBranch { + virtual void print(std::ostream &stream, const std::string padding = "") { + stream << " ( not"; + v[0]->print(stream, padding + " "); + stream << " )"; + } + }; - struct VNop : VBranch { - virtual void print(std::ostream &stream, const std::string padding = "") { - v[0]->print(stream, padding); - } - }; + struct VNop : VBranch { + virtual void print(std::ostream &stream, const std::string padding = "") { + v[0]->print(stream, padding); + } + }; //TODO can we create the macros without IDE errors ?! #define VLINE VPointer()/new VLine @@ -164,71 +164,68 @@ public: #define VNOP VContainer()/new VNop -protected: - ChartToVHDL(const Interpreter &other); + protected: + ChartToVHDL(const Interpreter &other); - void checkDocument(); + void checkDocument(); - void findEvents(); + void findEvents(); - void writeTypes(std::ostream &stream); + void writeTypes(std::ostream &stream); - void writeIncludes(std::ostream &stream); + void writeIncludes(std::ostream &stream); - // top layer components - void writeFiFo(std::ostream &stream); + // top layer components + void writeFiFo(std::ostream &stream); - void writeEventController(std::ostream &stream); + void writeEventController(std::ostream &stream); - void writeMicroStepper(std::ostream &stream); + void writeMicroStepper(std::ostream &stream); - void writeTestbench(std::ostream &stream); + void writeTestbench(std::ostream &stream); - // system - void writeSignalsAndComponents(std::ostream &stream); + void writeTopLevel(std::ostream &stream); - void writeSystemSignalMapping(std::ostream &stream); + // system + void writeSignalsAndComponents(std::ostream &stream); - void writeModuleInstantiation(std::ostream &stream); + void writeSystemSignalMapping(std::ostream &stream); - // combinatorial logic - void writeOptimalTransitionSetSelection(std::ostream &stream); + void writeModuleInstantiation(std::ostream &stream); - void writeExitSet(std::ostream &stream); + // combinatorial logic + void writeOptimalTransitionSetSelection(std::ostream &stream); - void writeEntrySet(std::ostream &stream); + void writeExitSet(std::ostream &stream); - void writeTransitionSet(std::ostream &stream); + void writeEntrySet(std::ostream &stream); - void writeDefaultCompletions(std::ostream &stream); + void writeCompleteEntrySet(std::ostream &stream); - void writeCompleteEntrySet(std::ostream &stream); + void writeActiveStateNplusOne(std::ostream &stream); - void writeActiveStateNplusOne(std::ostream &stream); + // handler + void writeStateHandler(std::ostream &stream); - // handler - void writeStateHandler(std::ostream &stream); + void writeResetHandler(std::ostream &stream); - void writeResetHandler(std::ostream &stream); + void writeSpontaneousHandler(std::ostream &stream); - void writeSpontaneousHandler(std::ostream &stream); + void writeInternalEventHandler(std::ostream &stream); - void writeInternalEventHandler(std::ostream &stream); + void writeErrorHandler(std::ostream &stream); - void writeErrorHandler(std::ostream &stream); - // event generation - void writeExContentBlock(std::ostream &stream, std::string index, - std::list commandSequence); + Trie _eventTrie; + std::list _eventNames; + size_t _eventBitSize = 0; + std::map _eventsOnBus; + std::list _execContent; - Trie _eventTrie; - std::list _execContent; - -private: - std::string getLineForExecContent(const XERCESC_NS::DOMNode *elem); - - bool isSupportedExecContent(XERCESC_NS::DOMElement *execContentElement); -}; + private: + std::string getLineForExecContent(const XERCESC_NS::DOMNode *elem); + bool isSupportedExecContent(XERCESC_NS::DOMElement *execContentElement); + }; } -- cgit v0.12 From ac3d14f54299654d98d7d4a49cc5bc106c2ba02e Mon Sep 17 00:00:00 2001 From: juehv Date: Wed, 23 Nov 2016 17:25:17 +0100 Subject: remove some unused code --- src/uscxml/transform/ChartToVHDL.cpp | 73 ------------------------------------ src/uscxml/transform/ChartToVHDL.h | 4 +- 2 files changed, 1 insertion(+), 76 deletions(-) diff --git a/src/uscxml/transform/ChartToVHDL.cpp b/src/uscxml/transform/ChartToVHDL.cpp index de63877..ccaf290 100644 --- a/src/uscxml/transform/ChartToVHDL.cpp +++ b/src/uscxml/transform/ChartToVHDL.cpp @@ -48,48 +48,6 @@ namespace uscxml { ChartToVHDL::~ChartToVHDL() { } - void ChartToVHDL::checkDocument() { - // filter unsupported stuff - std::list unsupported; - unsupported = DOMUtils::inDocumentOrder({ - XML_PREFIX(_scxml).str() + "datamodel", - XML_PREFIX(_scxml).str() + "data", - XML_PREFIX(_scxml).str() + "assign", - XML_PREFIX(_scxml).str() + "donedata", - XML_PREFIX(_scxml).str() + "content", - XML_PREFIX(_scxml).str() + "param", - XML_PREFIX(_scxml).str() + "script", - XML_PREFIX(_scxml).str() + "parallel", - XML_PREFIX(_scxml).str() + "history", - XML_PREFIX(_scxml).str() + "if", - XML_PREFIX(_scxml).str() + "foreach", - XML_PREFIX(_scxml).str() + "send", - XML_PREFIX(_scxml).str() + "cancel", - XML_PREFIX(_scxml).str() + "invoke", - XML_PREFIX(_scxml).str() + "finalize" - }, _scxml); - - std::stringstream ss; - if (unsupported.size() > 0) { - for (auto elem : unsupported) { - ss << " " << DOMUtils::xPathForNode(elem) << " unsupported" << std::endl; - } - throw std::runtime_error("Unsupported elements found:\n" + ss.str()); - } - - unsupported = DOMUtils::inDocumentOrder({XML_PREFIX(_scxml).str() + "transition"}, _scxml); - - for (auto transition : unsupported) { - if (HAS_ATTR(transition, "cond")) { - ERROR_PLATFORM_THROW("transition with conditions not supported!"); - } - if (!HAS_ATTR(transition, "target")) { - ERROR_PLATFORM_THROW("targetless transition not supported!"); - } - } - - } - void ChartToVHDL::findEvents() { // elements with an event attribute std::list withEvents = DOMUtils::inDocumentOrder({ @@ -147,7 +105,6 @@ namespace uscxml { } void ChartToVHDL::writeTo(std::ostream &stream) { - // checkDocument(); findEvents(); @@ -158,7 +115,6 @@ namespace uscxml { stream << "-- gtkwave tb.vcd" << std::endl; stream << std::endl; -// writeTypes(stream); writeFiFo(stream); writeEventController(stream); writeMicroStepper(stream); @@ -166,35 +122,6 @@ namespace uscxml { writeTopLevel(stream); } - // no longer required since events are a std_logic_vector now -// void ChartToVHDL::writeTypes(std::ostream &stream) { -// std::string seperator; -// -// stream << "-- required global types" << std::endl; -// stream << "library IEEE;" << std::endl; -// stream << "use IEEE.std_logic_1164.all;" << std::endl; -// stream << std::endl; -// stream << "package machine" << _md5 << " is" << std::endl; -// // create state type -// stream << " subtype state_type is std_logic_vector( "; -// stream << _states.size() - 1; -// stream << " downto 0);" << std::endl; -// -// std::list eventNames = _eventTrie.getWordsWithPrefix(""); -// stream << " type event_type is ( hwe_null"; -// seperator = ", "; -// -// for (std::list::iterator eventIter = eventNames.begin(); -// eventIter != eventNames.end(); eventIter++) { -// stream << seperator << "hwe_" << escapeMacro((*eventIter)->value); -// // seperator = ", "; -// } -// stream << " );" << std::endl; -// -// stream << "end machine" << _md5 << ";" << std::endl; -// stream << std::endl; -// stream << "-- END needed global types" << std::endl; -// } void ChartToVHDL::writeIncludes(std::ostream &stream) { // Add controler specific stuff here diff --git a/src/uscxml/transform/ChartToVHDL.h b/src/uscxml/transform/ChartToVHDL.h index d93d59f..3e98c80 100644 --- a/src/uscxml/transform/ChartToVHDL.h +++ b/src/uscxml/transform/ChartToVHDL.h @@ -167,11 +167,8 @@ namespace uscxml { protected: ChartToVHDL(const Interpreter &other); - void checkDocument(); - void findEvents(); - void writeTypes(std::ostream &stream); void writeIncludes(std::ostream &stream); @@ -224,6 +221,7 @@ namespace uscxml { private: std::string getLineForExecContent(const XERCESC_NS::DOMNode *elem); + bool isSupportedExecContent(XERCESC_NS::DOMElement *execContentElement); }; -- cgit v0.12 From 7323947b6f65d44e5cb73347555256415a297138 Mon Sep 17 00:00:00 2001 From: juehv Date: Wed, 23 Nov 2016 17:25:45 +0100 Subject: beatify code again --- src/uscxml/transform/ChartToVHDL.cpp | 2642 +++++++++++++++++----------------- src/uscxml/transform/ChartToVHDL.h | 264 ++-- src/uscxml/util/String.cpp | 302 ++-- src/uscxml/util/String.h | 10 +- 4 files changed, 1609 insertions(+), 1609 deletions(-) diff --git a/src/uscxml/transform/ChartToVHDL.cpp b/src/uscxml/transform/ChartToVHDL.cpp index ccaf290..cbd46ef 100644 --- a/src/uscxml/transform/ChartToVHDL.cpp +++ b/src/uscxml/transform/ChartToVHDL.cpp @@ -34,1575 +34,1575 @@ namespace uscxml { - using namespace XERCESC_NS; +using namespace XERCESC_NS; - Transformer ChartToVHDL::transform(const Interpreter &other) { - ChartToVHDL *c2c = new ChartToVHDL(other); +Transformer ChartToVHDL::transform(const Interpreter &other) { + ChartToVHDL *c2c = new ChartToVHDL(other); - return std::shared_ptr(c2c); - } + return std::shared_ptr(c2c); +} - ChartToVHDL::ChartToVHDL(const Interpreter &other) : ChartToC(other), _eventTrie(".") { - } +ChartToVHDL::ChartToVHDL(const Interpreter &other) : ChartToC(other), _eventTrie(".") { +} - ChartToVHDL::~ChartToVHDL() { - } +ChartToVHDL::~ChartToVHDL() { +} - void ChartToVHDL::findEvents() { - // elements with an event attribute - std::list withEvents = DOMUtils::inDocumentOrder({ - XML_PREFIX(_scxml).str() + "raise", - XML_PREFIX(_scxml).str() + "send", - XML_PREFIX(_scxml).str() + "transition", - }, _scxml); +void ChartToVHDL::findEvents() { + // elements with an event attribute + std::list withEvents = DOMUtils::inDocumentOrder({ + XML_PREFIX(_scxml).str() + "raise", + XML_PREFIX(_scxml).str() + "send", + XML_PREFIX(_scxml).str() + "transition", + }, _scxml); - for (auto withEvent : withEvents) { + for (auto withEvent : withEvents) { // if (HAS_ATTR_CAST(withEvent, "event")) { // if (ATTR_CAST(withEvent, "event") != "*") // _eventTrie.addWord(ATTR_CAST(withEvent, "event")); // } - // Tokenized version below - - if (HAS_ATTR_CAST(withEvent, "event")) { - std::string eventNames = ATTR_CAST(withEvent, "event"); - std::list events = tokenize(eventNames); - for (std::list::iterator eventIter = events.begin(); - eventIter != events.end(); eventIter++) { - std::string eventName = *eventIter; - if (boost::ends_with(eventName, "*")) - eventName = eventName.substr(0, eventName.size() - 1); - if (boost::ends_with(eventName, ".")) - eventName = eventName.substr(0, eventName.size() - 1); - if (eventName.size() > 0) - _eventTrie.addWord(eventName); - } - - //TODO implement "done" event - // --> enter a final from a compound state not (also prevent setting completed_o) - // --> all final children from a parallel are entered - //TODO implement error events --> set by output logic to a signal line - } - + // Tokenized version below + + if (HAS_ATTR_CAST(withEvent, "event")) { + std::string eventNames = ATTR_CAST(withEvent, "event"); + std::list events = tokenize(eventNames); + for (std::list::iterator eventIter = events.begin(); + eventIter != events.end(); eventIter++) { + std::string eventName = *eventIter; + if (boost::ends_with(eventName, "*")) + eventName = eventName.substr(0, eventName.size() - 1); + if (boost::ends_with(eventName, ".")) + eventName = eventName.substr(0, eventName.size() - 1); + if (eventName.size() > 0) + _eventTrie.addWord(eventName); + } + + //TODO implement "done" event + // --> enter a final from a compound state not (also prevent setting completed_o) + // --> all final children from a parallel are entered + //TODO implement error events --> set by output logic to a signal line } - // preprocess event names since they are often used - _eventNames = _eventTrie.getWordsWithPrefix(""); - // Calculate needed bit size for the event fifo - // --> |log2(n)| +1 with n is number of events - // we do not add +1 because the std_logic_vector startes with 0 - _eventBitSize = ceil(abs(log2(_eventNames.size()))); - - _execContent = DOMUtils::inDocumentOrder({ - XML_PREFIX(_scxml).str() + "raise", - XML_PREFIX(_scxml).str() + "send" - }, _scxml); - } - bool ChartToVHDL::isSupportedExecContent(DOMElement *execContentElement) { - return (TAGNAME(execContentElement) == XML_PREFIX(_scxml).str() + "raise" || - TAGNAME(execContentElement) == XML_PREFIX(_scxml).str() + "send"); - } + // preprocess event names since they are often used + _eventNames = _eventTrie.getWordsWithPrefix(""); + // Calculate needed bit size for the event fifo + // --> |log2(n)| +1 with n is number of events + // we do not add +1 because the std_logic_vector startes with 0 + _eventBitSize = ceil(abs(log2(_eventNames.size()))); - void ChartToVHDL::writeTo(std::ostream &stream) { - findEvents(); + _execContent = DOMUtils::inDocumentOrder({ + XML_PREFIX(_scxml).str() + "raise", + XML_PREFIX(_scxml).str() + "send" + }, _scxml); +} - stream << "-- generated from " << std::string(_baseURL) << std::endl; - stream << "-- run as " << std::endl; - stream << "-- ghdl --clean && ghdl -a foo.vhdl && ghdl -e tb && ./tb --stop-time=10ms --vcd=tb.vcd" << - std::endl; - stream << "-- gtkwave tb.vcd" << std::endl; - stream << std::endl; +bool ChartToVHDL::isSupportedExecContent(DOMElement *execContentElement) { + return (TAGNAME(execContentElement) == XML_PREFIX(_scxml).str() + "raise" || + TAGNAME(execContentElement) == XML_PREFIX(_scxml).str() + "send"); +} - writeFiFo(stream); - writeEventController(stream); - writeMicroStepper(stream); - writeTestbench(stream); - writeTopLevel(stream); - } +void ChartToVHDL::writeTo(std::ostream &stream) { + findEvents(); - void ChartToVHDL::writeIncludes(std::ostream &stream) { - // Add controler specific stuff here - stream << "library IEEE;" << std::endl; - stream << "use IEEE.std_logic_1164.all;" << std::endl; -// stream << "use work.machine" << _md5 << ".all;" << std::endl; - stream << std::endl; - } + stream << "-- generated from " << std::string(_baseURL) << std::endl; + stream << "-- run as " << std::endl; + stream << "-- ghdl --clean && ghdl -a foo.vhdl && ghdl -e tb && ./tb --stop-time=10ms --vcd=tb.vcd" << + std::endl; + stream << "-- gtkwave tb.vcd" << std::endl; + stream << std::endl; - void ChartToVHDL::writeTestbench(std::ostream &stream) { + writeFiFo(stream); + writeEventController(stream); + writeMicroStepper(stream); + writeTestbench(stream); + writeTopLevel(stream); +} - stream << "-- TESTBENCH" << std::endl; - writeIncludes(stream); - stream << "use std.env.all;" << std::endl; - stream << std::endl; - - stream << "-- empty entity" << std::endl; - stream << "entity tb is" << std::endl; - stream << "end entity tb;" << std::endl; - stream << std::endl; - - stream << "architecture behavioral of tb is" << std::endl; - stream << std::endl; - - // modules - stream << " -- Module declaration" << std::endl; - stream << " component micro_stepper is" << std::endl; - stream << " port (" << std::endl; - stream << " --inputs" << std::endl; - stream << " clk :in std_logic;" << std::endl; - stream << " rst_i :in std_logic;" << std::endl; - stream << " en :in std_logic;" << std::endl; - stream << " next_event_i :in std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << " next_event_we_i :in std_logic;" << std::endl; - stream << " --outputs" << std::endl; - stream << " error_o :out std_logic;" << std::endl; - - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; - - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " entry_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; - } - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " exit_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; - } +void ChartToVHDL::writeIncludes(std::ostream &stream) { + // Add controler specific stuff here + stream << "library IEEE;" << std::endl; + stream << "use IEEE.std_logic_1164.all;" << std::endl; +// stream << "use work.machine" << _md5 << ".all;" << std::endl; + stream << std::endl; +} + +void ChartToVHDL::writeTestbench(std::ostream &stream) { + + stream << "-- TESTBENCH" << std::endl; + writeIncludes(stream); + stream << "use std.env.all;" << std::endl; + stream << std::endl; + + stream << "-- empty entity" << std::endl; + stream << "entity tb is" << std::endl; + stream << "end entity tb;" << std::endl; + stream << std::endl; + + stream << "architecture behavioral of tb is" << std::endl; + stream << std::endl; + + // modules + stream << " -- Module declaration" << std::endl; + stream << " component micro_stepper is" << std::endl; + stream << " port (" << std::endl; + stream << " --inputs" << std::endl; + stream << " clk :in std_logic;" << std::endl; + stream << " rst_i :in std_logic;" << std::endl; + stream << " en :in std_logic;" << std::endl; + stream << " next_event_i :in std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << " next_event_we_i :in std_logic;" << std::endl; + stream << " --outputs" << std::endl; + stream << " error_o :out std_logic;" << std::endl; + + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; } - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " transition_set_" << ATTR(transition, "postFixOrder") << "_o :out std_logic;" - << std::endl; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; } + } - stream << " completed_o :out std_logic" << std::endl; - stream << " );" << std::endl; - stream << " end component;" << std::endl; - stream << std::endl; + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") << "_o :out std_logic;" + << std::endl; + } + } - stream << " component event_controller is" << std::endl; - stream << " port(" << std::endl; - stream << " --inputs" << std::endl; - stream << " clk :in std_logic;" << std::endl; - stream << " rst_i :in std_logic;" << std::endl; + stream << " completed_o :out std_logic" << std::endl; + stream << " );" << std::endl; + stream << " end component;" << std::endl; + stream << std::endl; - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") - << "_i :in std_logic;" << std::endl; + stream << " component event_controller is" << std::endl; + stream << " port(" << std::endl; + stream << " --inputs" << std::endl; + stream << " clk :in std_logic;" << std::endl; + stream << " rst_i :in std_logic;" << std::endl; - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " entry_set_" << ATTR(state, "documentOrder") - << "_i :in std_logic;" << std::endl; - } + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") + << "_i :in std_logic;" << std::endl; - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " exit_set_" << ATTR(state, "documentOrder") - << "_i :in std_logic;" << std::endl; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") + << "_i :in std_logic;" << std::endl; } - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " transition_set_" << ATTR(transition, "postFixOrder") - << "_i :in std_logic;" << std::endl; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") + << "_i :in std_logic;" << std::endl; } - stream << " --outputs" << std::endl; - stream << " micro_stepper_en_o :out std_logic;" << std::endl; - stream << " event_o :out std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << " event_we_o :out std_logic" << std::endl; - // stream << " done_o :out std_logic" << std::endl; - stream << ");" << std::endl; - stream << "end component; " << std::endl; - - // signals - stream << " -- input" << std::endl; - stream << " signal clk : std_logic := '0';" << std::endl; - stream << " signal reset : std_logic;" << std::endl; - stream << " signal dut_enable : std_logic;" << std::endl; - stream << " signal next_event_we_i : std_logic;" << std::endl; - stream << " signal next_event_i : std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << std::endl; - - stream << " -- output" << std::endl; - stream << " signal error_o, completed_o : std_logic;" << std::endl; - stream << std::endl; - - stream << " -- wiring" << std::endl; - for (auto state : _states) { - stream << " signal state_active_" << ATTR(state, "documentOrder") - << "_sig : std_logic;" << std::endl; - - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " signal entry_set_" << ATTR(state, "documentOrder") - << "_sig : std_logic;" << std::endl; - } + } - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " signal exit_set_" << ATTR(state, "documentOrder") - << "_sig : std_logic;" << std::endl; - } + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") + << "_i :in std_logic;" << std::endl; } - - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " signal transition_set_" << ATTR(transition, "postFixOrder") - << "_sig : std_logic;" << std::endl; - } + } + stream << " --outputs" << std::endl; + stream << " micro_stepper_en_o :out std_logic;" << std::endl; + stream << " event_o :out std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << " event_we_o :out std_logic" << std::endl; + // stream << " done_o :out std_logic" << std::endl; + stream << ");" << std::endl; + stream << "end component; " << std::endl; + + // signals + stream << " -- input" << std::endl; + stream << " signal clk : std_logic := '0';" << std::endl; + stream << " signal reset : std_logic;" << std::endl; + stream << " signal dut_enable : std_logic;" << std::endl; + stream << " signal next_event_we_i : std_logic;" << std::endl; + stream << " signal next_event_i : std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << std::endl; + + stream << " -- output" << std::endl; + stream << " signal error_o, completed_o : std_logic;" << std::endl; + stream << std::endl; + + stream << " -- wiring" << std::endl; + for (auto state : _states) { + stream << " signal state_active_" << ATTR(state, "documentOrder") + << "_sig : std_logic;" << std::endl; + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " signal entry_set_" << ATTR(state, "documentOrder") + << "_sig : std_logic;" << std::endl; } - // wiring - stream << "begin" << std::endl; - stream << " clk <= not clk after 20 ns; -- 25 MHz clock frequency" << std::endl; - stream << " reset <= '1', '0' after 100 ns; -- generates reset signal: --__" << std::endl; - stream << std::endl; - - stream << " -- Module instantiation" << std::endl; - stream << " dut : micro_stepper" << std::endl; - stream << " port map (" << std::endl; - stream << " clk => clk," << std::endl; - stream << " rst_i => reset," << std::endl; - stream << " en => dut_enable," << std::endl; - stream << std::endl; - - stream << " next_event_i => next_event_i," << std::endl; - stream << " next_event_we_i => next_event_we_i," << std::endl; - stream << " error_o => error_o," << std::endl; + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " signal exit_set_" << ATTR(state, "documentOrder") + << "_sig : std_logic;" << std::endl; + } + } - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") - << "_o => state_active_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " signal transition_set_" << ATTR(transition, "postFixOrder") + << "_sig : std_logic;" << std::endl; + } + } - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " entry_set_" << ATTR(state, "documentOrder") - << "_o => entry_set_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; - } + // wiring + stream << "begin" << std::endl; + stream << " clk <= not clk after 20 ns; -- 25 MHz clock frequency" << std::endl; + stream << " reset <= '1', '0' after 100 ns; -- generates reset signal: --__" << std::endl; + stream << std::endl; + + stream << " -- Module instantiation" << std::endl; + stream << " dut : micro_stepper" << std::endl; + stream << " port map (" << std::endl; + stream << " clk => clk," << std::endl; + stream << " rst_i => reset," << std::endl; + stream << " en => dut_enable," << std::endl; + stream << std::endl; + + stream << " next_event_i => next_event_i," << std::endl; + stream << " next_event_we_i => next_event_we_i," << std::endl; + stream << " error_o => error_o," << std::endl; + + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") + << "_o => state_active_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") + << "_o => entry_set_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; + } - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " exit_set_" << ATTR(state, "documentOrder") - << "_o => exit_set_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") + << "_o => exit_set_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; } + } - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " transition_set_" << ATTR(transition, "postFixOrder") - << "_o => transition_set_" << ATTR(transition, "postFixOrder") - << "_sig," << std::endl; - } + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") + << "_o => transition_set_" << ATTR(transition, "postFixOrder") + << "_sig," << std::endl; } + } - stream << " completed_o => completed_o" << std::endl; - stream << " );" << std::endl; - stream << std::endl; + stream << " completed_o => completed_o" << std::endl; + stream << " );" << std::endl; + stream << std::endl; - stream << " ec : event_controller" << std::endl; - stream << " port map (" << std::endl; - stream << " clk => clk," << std::endl; - stream << " rst_i => reset," << std::endl; - stream << std::endl; + stream << " ec : event_controller" << std::endl; + stream << " port map (" << std::endl; + stream << " clk => clk," << std::endl; + stream << " rst_i => reset," << std::endl; + stream << std::endl; - stream << " event_o => next_event_i," << std::endl; - stream << " event_we_o => next_event_we_i," << std::endl; + stream << " event_o => next_event_i," << std::endl; + stream << " event_we_o => next_event_we_i," << std::endl; - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") - << "_i => state_active_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") + << "_i => state_active_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " entry_set_" << ATTR(state, "documentOrder") - << "_i => entry_set_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") + << "_i => entry_set_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; + } - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " exit_set_" << ATTR(state, "documentOrder") - << "_i => exit_set_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") + << "_i => exit_set_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; } + } - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " transition_set_" << ATTR(transition, "postFixOrder") - << "_i => transition_set_" << ATTR(transition, "postFixOrder") - << "_sig," << std::endl; - } + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") + << "_i => transition_set_" << ATTR(transition, "postFixOrder") + << "_sig," << std::endl; } + } - stream << " micro_stepper_en_o => dut_enable" << std::endl; - // stream << " done_o => open" << std::endl; - stream << " );" << std::endl; - stream << std::endl; + stream << " micro_stepper_en_o => dut_enable" << std::endl; + // stream << " done_o => open" << std::endl; + stream << " );" << std::endl; + stream << std::endl; - // find pass state - std::list topLevelFinal = - DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "final", _scxml); + // find pass state + std::list topLevelFinal = + DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "final", _scxml); - std::string passStateNo = ""; - for (auto final : topLevelFinal) { - if (ATTR(final, "id") == "pass") { - passStateNo = ATTR(final, "documentOrder"); - } + std::string passStateNo = ""; + for (auto final : topLevelFinal) { + if (ATTR(final, "id") == "pass") { + passStateNo = ATTR(final, "documentOrder"); } + } - // test observation and exit condition - stream << " -- Test observation" << std::endl; - stream << " process (clk)" << std::endl; - stream << " variable count_clk : integer := 0;" << std::endl; - stream << " begin" << std::endl; - stream << " if rising_edge(clk) then" << std::endl; - stream << " count_clk := count_clk + 1;" << std::endl; - stream << " if (completed_o = '1') then" << std::endl; - if (!passStateNo.empty()) { - stream << " assert (state_active_" << passStateNo; - stream << "_sig = '1') report \"Completed with errors\" severity error;" << std::endl; - } - stream << " -- stop simulation" << std::endl; - stream << " finish(0);" << std::endl; // use 0 for ctest + // test observation and exit condition + stream << " -- Test observation" << std::endl; + stream << " process (clk)" << std::endl; + stream << " variable count_clk : integer := 0;" << std::endl; + stream << " begin" << std::endl; + stream << " if rising_edge(clk) then" << std::endl; + stream << " count_clk := count_clk + 1;" << std::endl; + stream << " if (completed_o = '1') then" << std::endl; + if (!passStateNo.empty()) { + stream << " assert (state_active_" << passStateNo; + stream << "_sig = '1') report \"Completed with errors\" severity error;" << std::endl; + } + stream << " -- stop simulation" << std::endl; + stream << " finish(0);" << std::endl; // use 0 for ctest // -- For both STOP and FINISH the STATUS values are those used // -- in the Verilog $finish task // -- 0 prints nothing // -- 1 prints simulation time and location // -- 2 prints simulation time, location, and statistics about // -- the memory and CPU times used in simulation - //stream << " assert false report \"Simulation Finished\" severity failure;" << std::endl; - stream << " else" << std::endl; - stream << " -- state machine not completed" << std::endl; - stream << " -- check if it is time to stop waiting (100 clk per state+transition+excontent)" << std::endl; - int tolleratedClocks = (_transitions.size() + _states.size() + _execContent.size()) * 100; - stream << " assert (count_clk < " << tolleratedClocks; - stream << ") report \"Clock count exceed\" severity failure;" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << " end process;" << std::endl; - - stream << "end architecture;" << std::endl; - stream << "-- END TESTBENCH" << std::endl; - + //stream << " assert false report \"Simulation Finished\" severity failure;" << std::endl; + stream << " else" << std::endl; + stream << " -- state machine not completed" << std::endl; + stream << " -- check if it is time to stop waiting (100 clk per state+transition+excontent)" << std::endl; + int tolleratedClocks = (_transitions.size() + _states.size() + _execContent.size()) * 100; + stream << " assert (count_clk < " << tolleratedClocks; + stream << ") report \"Clock count exceed\" severity failure;" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << " end process;" << std::endl; + + stream << "end architecture;" << std::endl; + stream << "-- END TESTBENCH" << std::endl; + +} + +void ChartToVHDL::writeTopLevel(std::ostream &stream) { + + stream << "-- TOP LEVEL entity for easy synthesis" << std::endl; + writeIncludes(stream); + stream << std::endl; + + stream << "-- empty entity" << std::endl; + stream << "entity top_level_design is" << std::endl; + stream << "port (" << std::endl; + stream << " --inputs" << std::endl; + stream << " clk :in std_logic;" << std::endl; + stream << " rst :in std_logic;" << std::endl; + stream << " --outputs" << std::endl; + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") + << "_o :out std_logic;" << std::endl; } - - void ChartToVHDL::writeTopLevel(std::ostream &stream) { - - stream << "-- TOP LEVEL entity for easy synthesis" << std::endl; - writeIncludes(stream); - stream << std::endl; - - stream << "-- empty entity" << std::endl; - stream << "entity top_level_design is" << std::endl; - stream << "port (" << std::endl; - stream << " --inputs" << std::endl; - stream << " clk :in std_logic;" << std::endl; - stream << " rst :in std_logic;" << std::endl; - stream << " --outputs" << std::endl; - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") - << "_o :out std_logic;" << std::endl; + stream << " completed_o :out std_logic" << std::endl; + stream << ");" << std::endl; + stream << "end entity top_level_design;" << std::endl; + stream << std::endl; + + stream << "architecture behavioral of top_level_design is" << std::endl; + stream << std::endl; + + // modules + stream << " -- Module declaration" << std::endl; + stream << " component micro_stepper is" << std::endl; + stream << " port (" << std::endl; + stream << " --inputs" << std::endl; + stream << " clk :in std_logic;" << std::endl; + stream << " rst_i :in std_logic;" << std::endl; + stream << " en :in std_logic;" << std::endl; + stream << " next_event_i :in std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << " next_event_we_i :in std_logic;" << std::endl; + stream << " --outputs" << std::endl; + stream << " error_o :out std_logic;" << std::endl; + + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; } - stream << " completed_o :out std_logic" << std::endl; - stream << ");" << std::endl; - stream << "end entity top_level_design;" << std::endl; - stream << std::endl; - - stream << "architecture behavioral of top_level_design is" << std::endl; - stream << std::endl; - - // modules - stream << " -- Module declaration" << std::endl; - stream << " component micro_stepper is" << std::endl; - stream << " port (" << std::endl; - stream << " --inputs" << std::endl; - stream << " clk :in std_logic;" << std::endl; - stream << " rst_i :in std_logic;" << std::endl; - stream << " en :in std_logic;" << std::endl; - stream << " next_event_i :in std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << " next_event_we_i :in std_logic;" << std::endl; - stream << " --outputs" << std::endl; - stream << " error_o :out std_logic;" << std::endl; - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; - - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " entry_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; - } - - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " exit_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; } + } - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " transition_set_" << ATTR(transition, "postFixOrder") << "_o :out std_logic;" - << std::endl; - } + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") << "_o :out std_logic;" + << std::endl; } + } - stream << " completed_o :out std_logic" << std::endl; - stream << " );" << std::endl; - stream << " end component;" << std::endl; - stream << std::endl; + stream << " completed_o :out std_logic" << std::endl; + stream << " );" << std::endl; + stream << " end component;" << std::endl; + stream << std::endl; - stream << " component event_controller is" << std::endl; - stream << " port(" << std::endl; - stream << " --inputs" << std::endl; - stream << " clk :in std_logic;" << std::endl; - stream << " rst_i :in std_logic;" << std::endl; + stream << " component event_controller is" << std::endl; + stream << " port(" << std::endl; + stream << " --inputs" << std::endl; + stream << " clk :in std_logic;" << std::endl; + stream << " rst_i :in std_logic;" << std::endl; - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") - << "_i :in std_logic;" << std::endl; + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") + << "_i :in std_logic;" << std::endl; - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " entry_set_" << ATTR(state, "documentOrder") - << "_i :in std_logic;" << std::endl; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") + << "_i :in std_logic;" << std::endl; + } - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " exit_set_" << ATTR(state, "documentOrder") - << "_i :in std_logic;" << std::endl; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") + << "_i :in std_logic;" << std::endl; } + } - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " transition_set_" << ATTR(transition, "postFixOrder") - << "_i :in std_logic;" << std::endl; - } + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") + << "_i :in std_logic;" << std::endl; + } + } + stream << " --outputs" << std::endl; + stream << " micro_stepper_en_o :out std_logic;" << std::endl; + stream << " event_o :out std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << " event_we_o :out std_logic" << std::endl; + // stream << " done_o :out std_logic" << std::endl; + stream << ");" << std::endl; + stream << "end component; " << std::endl; + + // signals + stream << " -- input" << std::endl; + stream << " signal reset : std_logic;" << std::endl; + stream << " signal dut_enable : std_logic;" << std::endl; + stream << " signal next_event_we_i : std_logic;" << std::endl; + stream << " signal next_event_i : std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << std::endl; + + stream << " -- output" << std::endl; + stream << " signal error_o : std_logic;" << std::endl; + stream << std::endl; + + stream << " -- wiring" << std::endl; + for (auto state : _states) { + stream << " signal state_active_" << ATTR(state, "documentOrder") + << "_sig : std_logic;" << std::endl; + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " signal entry_set_" << ATTR(state, "documentOrder") + << "_sig : std_logic;" << std::endl; } - stream << " --outputs" << std::endl; - stream << " micro_stepper_en_o :out std_logic;" << std::endl; - stream << " event_o :out std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << " event_we_o :out std_logic" << std::endl; - // stream << " done_o :out std_logic" << std::endl; - stream << ");" << std::endl; - stream << "end component; " << std::endl; - - // signals - stream << " -- input" << std::endl; - stream << " signal reset : std_logic;" << std::endl; - stream << " signal dut_enable : std_logic;" << std::endl; - stream << " signal next_event_we_i : std_logic;" << std::endl; - stream << " signal next_event_i : std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << std::endl; - stream << " -- output" << std::endl; - stream << " signal error_o : std_logic;" << std::endl; - stream << std::endl; + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " signal exit_set_" << ATTR(state, "documentOrder") + << "_sig : std_logic;" << std::endl; + } + } - stream << " -- wiring" << std::endl; - for (auto state : _states) { - stream << " signal state_active_" << ATTR(state, "documentOrder") - << "_sig : std_logic;" << std::endl; + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " signal transition_set_" << ATTR(transition, "postFixOrder") + << "_sig : std_logic;" << std::endl; + } + } - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " signal entry_set_" << ATTR(state, "documentOrder") - << "_sig : std_logic;" << std::endl; - } + // wiring + stream << "begin" << std::endl; + stream << " reset <= rst;" << std::endl; + stream << std::endl; - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " signal exit_set_" << ATTR(state, "documentOrder") - << "_sig : std_logic;" << std::endl; - } + for (auto state : _states) { + stream << "state_active_" << ATTR(state, "documentOrder") + << "_o <= state_active_" << ATTR(state, "documentOrder") + << "_sig;" << std::endl; + } + stream << std::endl; + + stream << " -- Module instantiation" << std::endl; + stream << " dut : micro_stepper" << std::endl; + stream << " port map (" << std::endl; + stream << " clk => clk," << std::endl; + stream << " rst_i => reset," << std::endl; + stream << " en => dut_enable," << std::endl; + stream << std::endl; + + stream << " next_event_i => next_event_i," << std::endl; + stream << " next_event_we_i => next_event_we_i," << std::endl; + stream << " error_o => error_o," << std::endl; + + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") + << "_o => state_active_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") + << "_o => entry_set_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; } - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " signal transition_set_" << ATTR(transition, "postFixOrder") - << "_sig : std_logic;" << std::endl; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") + << "_o => exit_set_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; } + } - // wiring - stream << "begin" << std::endl; - stream << " reset <= rst;" << std::endl; - stream << std::endl; - - for (auto state : _states) { - stream << "state_active_" << ATTR(state, "documentOrder") - << "_o <= state_active_" << ATTR(state, "documentOrder") - << "_sig;" << std::endl; + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") + << "_o => transition_set_" << ATTR(transition, "postFixOrder") + << "_sig," << std::endl; } - stream << std::endl; + } - stream << " -- Module instantiation" << std::endl; - stream << " dut : micro_stepper" << std::endl; - stream << " port map (" << std::endl; - stream << " clk => clk," << std::endl; - stream << " rst_i => reset," << std::endl; - stream << " en => dut_enable," << std::endl; - stream << std::endl; + stream << " completed_o => completed_o" << std::endl; + stream << " );" << std::endl; + stream << std::endl; - stream << " next_event_i => next_event_i," << std::endl; - stream << " next_event_we_i => next_event_we_i," << std::endl; - stream << " error_o => error_o," << std::endl; + stream << " ec : event_controller" << std::endl; + stream << " port map (" << std::endl; + stream << " clk => clk," << std::endl; + stream << " rst_i => reset," << std::endl; + stream << std::endl; - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") - << "_o => state_active_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; + stream << " event_o => next_event_i," << std::endl; + stream << " event_we_o => next_event_we_i," << std::endl; - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " entry_set_" << ATTR(state, "documentOrder") - << "_o => entry_set_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; - } + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") + << "_i => state_active_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " exit_set_" << ATTR(state, "documentOrder") - << "_o => exit_set_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") + << "_i => entry_set_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; } - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " transition_set_" << ATTR(transition, "postFixOrder") - << "_o => transition_set_" << ATTR(transition, "postFixOrder") - << "_sig," << std::endl; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") + << "_i => exit_set_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; } + } - stream << " completed_o => completed_o" << std::endl; - stream << " );" << std::endl; - stream << std::endl; - - stream << " ec : event_controller" << std::endl; - stream << " port map (" << std::endl; - stream << " clk => clk," << std::endl; - stream << " rst_i => reset," << std::endl; - stream << std::endl; + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") + << "_i => transition_set_" << ATTR(transition, "postFixOrder") + << "_sig," << std::endl; + } + } - stream << " event_o => next_event_i," << std::endl; - stream << " event_we_o => next_event_we_i," << std::endl; + stream << " micro_stepper_en_o => dut_enable" << std::endl; + // stream << " done_o => open" << std::endl; + stream << " );" << std::endl; + stream << std::endl; - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") - << "_i => state_active_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; + // find pass state + std::list topLevelFinal = + DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "final", _scxml); - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " entry_set_" << ATTR(state, "documentOrder") - << "_i => entry_set_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; - } + std::string passStateNo = ""; + for (auto final : topLevelFinal) { + if (ATTR(final, "id") == "pass") { + passStateNo = ATTR(final, "documentOrder"); + } + } + stream << "end architecture;" << std::endl; + stream << "-- END TOP LEVEL" << std::endl; +} + +void ChartToVHDL::writeEventController(std::ostream &stream) { + // Add controler specific stuff here + // create hardware top level + stream << "-- Event Controller Logic" << std::endl; + writeIncludes(stream); + stream << "entity event_controller is" << std::endl; + stream << "port(" << std::endl; + stream << " --inputs" << std::endl; + stream << " clk :in std_logic;" << std::endl; + stream << " rst_i :in std_logic;" << std::endl; + + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") + << "_i :in std_logic;" << std::endl; + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") + << "_i :in std_logic;" << std::endl; + } - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " exit_set_" << ATTR(state, "documentOrder") - << "_i => exit_set_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") + << "_i :in std_logic;" << std::endl; } + } - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " transition_set_" << ATTR(transition, "postFixOrder") - << "_i => transition_set_" << ATTR(transition, "postFixOrder") - << "_sig," << std::endl; - } + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") + << "_i :in std_logic;" << std::endl; } + } - stream << " micro_stepper_en_o => dut_enable" << std::endl; - // stream << " done_o => open" << std::endl; - stream << " );" << std::endl; - stream << std::endl; + stream << " --outputs" << std::endl; + stream << " micro_stepper_en_o :out std_logic;" << std::endl; + stream << " event_o :out std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << " event_we_o :out std_logic" << std::endl; + stream << ");" << std::endl; + stream << "end event_controller; " << std::endl; + + stream << std::endl; + stream << "architecture behavioral of event_controller is " << std::endl; + stream << std::endl; + + + // Add signals and components + stream << "signal rst : std_logic;" << std::endl; + stream << "signal micro_stepper_en : std_logic;" << std::endl; + stream << "signal cmpl_buf : std_logic;" << std::endl; + stream << "signal completed_sig : std_logic;" << std::endl; + stream << "signal event_bus : std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << "signal event_we : std_logic;" << std::endl; + + for (int i = 0; i < _execContent.size(); i++) { + stream << "signal done_" << toStr(i) << "_sig : std_logic;" << std::endl; + stream << "signal start_" << toStr(i) << "_sig : std_logic;" << std::endl; + } + + stream << "-- sequence input line" << std::endl; + for (int i = 0; i < _execContent.size(); i++) { + stream << "signal seq_" << toStr(i) << "_sig : std_logic;" << std::endl; + } + stream << std::endl; - // find pass state - std::list topLevelFinal = - DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "final", _scxml); + stream << "begin" << std::endl; + stream << std::endl; - std::string passStateNo = ""; - for (auto final : topLevelFinal) { - if (ATTR(final, "id") == "pass") { - passStateNo = ATTR(final, "documentOrder"); - } + // check if there is SUPPORTED executable content + bool foundSupportedExecContent = false; + for (auto exContentElem : _execContent) { + if (isSupportedExecContent(exContentElem)) { + foundSupportedExecContent = true; + break; } - stream << "end architecture;" << std::endl; - stream << "-- END TOP LEVEL" << std::endl; } + if (!foundSupportedExecContent) { + // set output correct if there is no supported excontent - void ChartToVHDL::writeEventController(std::ostream &stream) { - // Add controler specific stuff here - // create hardware top level - stream << "-- Event Controller Logic" << std::endl; - writeIncludes(stream); - stream << "entity event_controller is" << std::endl; - stream << "port(" << std::endl; - stream << " --inputs" << std::endl; - stream << " clk :in std_logic;" << std::endl; - stream << " rst_i :in std_logic;" << std::endl; + if (_execContent.size() > 0) { + // show warning if executable content is ignored + stream << "-- no supported executable content found" << std::endl; + stream << "-- state machine may not run correctly" << std::endl; + } + stream << "-- setting output lines to fulfil dummy functionality" << std::endl; + stream << "micro_stepper_en_o <= '1';" << std::endl; + stream << "event_o <= (others => '0');" << std::endl; + stream << "event_we_o <= '0';" << std::endl; + stream << std::endl; + } else { + // system signal mapping + stream << "rst <= rst_i;" << std::endl; + stream << "micro_stepper_en_o <= micro_stepper_en;" << std::endl; + stream << "event_o <= event_bus;" << std::endl; + stream << "event_we_o <= event_we;" << std::endl; + stream << std::endl; + // stall management + stream << "-- stalling microstepper" << std::endl; + stream << "micro_stepper_en <= completed_sig or not ( '0' "; for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") - << "_i :in std_logic;" << std::endl; if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " entry_set_" << ATTR(state, "documentOrder") - << "_i :in std_logic;" << std::endl; + stream << std::endl << " or entry_set_" << ATTR(state, "documentOrder") + << "_i"; } if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " exit_set_" << ATTR(state, "documentOrder") - << "_i :in std_logic;" << std::endl; + stream << std::endl << " or exit_set_" << ATTR(state, "documentOrder") + << "_i"; } } - for (auto transition : _transitions) { if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " transition_set_" << ATTR(transition, "postFixOrder") - << "_i :in std_logic;" << std::endl; + stream << std::endl << " or transition_set_" << ATTR(transition, "postFixOrder") + << "_i"; } } - - stream << " --outputs" << std::endl; - stream << " micro_stepper_en_o :out std_logic;" << std::endl; - stream << " event_o :out std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << " event_we_o :out std_logic" << std::endl; stream << ");" << std::endl; - stream << "end event_controller; " << std::endl; - stream << std::endl; - stream << "architecture behavioral of event_controller is " << std::endl; - stream << std::endl; - - - // Add signals and components - stream << "signal rst : std_logic;" << std::endl; - stream << "signal micro_stepper_en : std_logic;" << std::endl; - stream << "signal cmpl_buf : std_logic;" << std::endl; - stream << "signal completed_sig : std_logic;" << std::endl; - stream << "signal event_bus : std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << "signal event_we : std_logic;" << std::endl; + // sequential code operation + stream << "-- seq code block " << std::endl; + stream << "ex_content_block : process (clk, rst) " << std::endl; + stream << "begin" << std::endl; + stream << " if rst = '1' then" << std::endl; for (int i = 0; i < _execContent.size(); i++) { - stream << "signal done_" << toStr(i) << "_sig : std_logic;" << std::endl; - stream << "signal start_" << toStr(i) << "_sig : std_logic;" << std::endl; - } - - stream << "-- sequence input line" << std::endl; - for (int i = 0; i < _execContent.size(); i++) { - stream << "signal seq_" << toStr(i) << "_sig : std_logic;" << std::endl; + stream << " done_" << toStr(i) << "_sig <= '0';" << std::endl; } - stream << std::endl; + stream << " event_bus <= (others => '0');" << std::endl; + stream << " event_we <= '0';" << std::endl; + stream << " cmpl_buf <= '0';" << std::endl; + stream << " completed_sig <= '0';" << std::endl; + stream << " elsif rising_edge(clk) then" << std::endl; + + stream << " if micro_stepper_en = '1' then" << std::endl; + stream << " cmpl_buf <= '0' ;" << std::endl; + stream << " else" << std::endl; + stream << " cmpl_buf <= seq_" << toStr(_execContent.size() - 1) + << "_sig;" << std::endl; + stream << " end if;" << std::endl; + stream << " completed_sig <= cmpl_buf;" << std::endl << std::endl; - stream << "begin" << std::endl; - stream << std::endl; + size_t i = 0; + std::string seperator = " "; + for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { + DOMElement *exContentElem = *ecIter; - // check if there is SUPPORTED executable content - bool foundSupportedExecContent = false; - for (auto exContentElem : _execContent) { if (isSupportedExecContent(exContentElem)) { - foundSupportedExecContent = true; - break; - } - } - if (!foundSupportedExecContent) { - // set output correct if there is no supported excontent - - if (_execContent.size() > 0) { - // show warning if executable content is ignored - stream << "-- no supported executable content found" << std::endl; - stream << "-- state machine may not run correctly" << std::endl; - } - stream << "-- setting output lines to fulfil dummy functionality" << std::endl; - stream << "micro_stepper_en_o <= '1';" << std::endl; - stream << "event_o <= (others => '0');" << std::endl; - stream << "event_we_o <= '0';" << std::endl; - stream << std::endl; - } else { - // system signal mapping - stream << "rst <= rst_i;" << std::endl; - stream << "micro_stepper_en_o <= micro_stepper_en;" << std::endl; - stream << "event_o <= event_bus;" << std::endl; - stream << "event_we_o <= event_we;" << std::endl; - stream << std::endl; - - // stall management - stream << "-- stalling microstepper" << std::endl; - stream << "micro_stepper_en <= completed_sig or not ( '0' "; - for (auto state : _states) { - - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << std::endl << " or entry_set_" << ATTR(state, "documentOrder") - << "_i"; - } - - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << std::endl << " or exit_set_" << ATTR(state, "documentOrder") - << "_i"; - } - } - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << std::endl << " or transition_set_" << ATTR(transition, "postFixOrder") - << "_i"; - } - } - stream << ");" << std::endl; - stream << std::endl; - - // sequential code operation - stream << "-- seq code block " << std::endl; - stream << "ex_content_block : process (clk, rst) " << std::endl; - stream << "begin" << std::endl; - stream << " if rst = '1' then" << std::endl; - for (int i = 0; i < _execContent.size(); i++) { - stream << " done_" << toStr(i) << "_sig <= '0';" << std::endl; - } - stream << " event_bus <= (others => '0');" << std::endl; - stream << " event_we <= '0';" << std::endl; - stream << " cmpl_buf <= '0';" << std::endl; - stream << " completed_sig <= '0';" << std::endl; - stream << " elsif rising_edge(clk) then" << std::endl; - - stream << " if micro_stepper_en = '1' then" << std::endl; - stream << " cmpl_buf <= '0' ;" << std::endl; - stream << " else" << std::endl; - stream << " cmpl_buf <= seq_" << toStr(_execContent.size() - 1) - << "_sig;" << std::endl; - stream << " end if;" << std::endl; - stream << " completed_sig <= cmpl_buf;" << std::endl << std::endl; - - size_t i = 0; - std::string seperator = " "; - for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { - DOMElement *exContentElem = *ecIter; - - if (isSupportedExecContent(exContentElem)) { - stream << seperator << "if start_" << toStr(i) << "_sig = '1' then" - << std::endl; + stream << seperator << "if start_" << toStr(i) << "_sig = '1' then" + << std::endl; - size_t jj = 0; - for (auto eventIter = _eventNames.begin(); eventIter != _eventNames.end(); eventIter++, jj++) { - if (((*eventIter)->value) == ATTR(exContentElem, "event")) { - break; - } + size_t jj = 0; + for (auto eventIter = _eventNames.begin(); eventIter != _eventNames.end(); eventIter++, jj++) { + if (((*eventIter)->value) == ATTR(exContentElem, "event")) { + break; } - stream << " event_bus <= \"" << toBinStr(jj, _eventBitSize+1) << "\";" << std::endl; - stream << " done_" << toStr(i) << "_sig <= '1';" << std::endl; - stream << " event_we <= '1';" << std::endl; - seperator = " els"; } + stream << " event_bus <= \"" << toBinStr(jj, _eventBitSize+1) << "\";" << std::endl; + stream << " done_" << toStr(i) << "_sig <= '1';" << std::endl; + stream << " event_we <= '1';" << std::endl; + seperator = " els"; } - stream << " elsif micro_stepper_en = '1' then" << std::endl; - i = 0; - //for (auto exContentElem : _execContent) { - for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { - DOMElement *exContentElem = *ecIter; - if (isSupportedExecContent(exContentElem)) { - stream << " done_" << toStr(i) << "_sig <= '0';" << std::endl; - } + } + stream << " elsif micro_stepper_en = '1' then" << std::endl; + i = 0; + //for (auto exContentElem : _execContent) { + for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { + DOMElement *exContentElem = *ecIter; + if (isSupportedExecContent(exContentElem)) { + stream << " done_" << toStr(i) << "_sig <= '0';" << std::endl; } - stream << " event_we <= '0';" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << "end process;" << std::endl; - stream << std::endl; + } + stream << " event_we <= '0';" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << "end process;" << std::endl; + stream << std::endl; - i = 0; - for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { - // start lines - stream << "start_" << toStr(i) << "_sig <= " - << getLineForExecContent(*ecIter) << " and " - << "not done_" << toStr(i) << "_sig"; + i = 0; + for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { + // start lines + stream << "start_" << toStr(i) << "_sig <= " + << getLineForExecContent(*ecIter) << " and " + << "not done_" << toStr(i) << "_sig"; - // if not needed, since seq_0_sig is hard coded as '1'. + // if not needed, since seq_0_sig is hard coded as '1'. // if (i != 0) { // if not first element - stream << " and seq_" << toStr(i) << "_sig"; + stream << " and seq_" << toStr(i) << "_sig"; // } - stream << ";" << std::endl; - - } + stream << ";" << std::endl; - stream << "seq_0_sig <= '1';" << std::endl; - - if (_execContent.size() > 1) { - i = 0; - for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { - // prevent writing seq_0_sig since this should be hardcoded to '1' - if (i != 0) { - // seq lines (input if process i is in seqence now) - stream << "seq_" << toStr(i) << "_sig <= " - << "done_" << toStr(i - 1) << "_sig or " - << "( not " - << getLineForExecContent(*ecIter); - stream << " and seq_" << toStr(i - 1) << "_sig"; - stream << " );" << std::endl; - } - } - } - stream << std::endl; } - stream << "end behavioral; " << - std::endl; - stream << "-- END Event Controller Logic" << - std::endl; - stream << - std::endl; - } - - std::string ChartToVHDL::getLineForExecContent(const DOMNode *elem) { - const DOMNode *ecBlock = elem; - while (ecBlock) { - if (ecBlock->getNodeType() == DOMNode::ELEMENT_NODE) { - std::string localName = LOCALNAME_CAST(ecBlock); - if (localName == XML_PREFIX(_scxml).str() + "transition") { - return "transition_set_" + ATTR_CAST(ecBlock, "postFixOrder") + "_i"; - } - - if (localName == XML_PREFIX(_scxml).str() + "onentry") { - return "entry_set_" + ATTR_CAST(ecBlock->getParentNode(), "documentOrder") + "_i"; - } + stream << "seq_0_sig <= '1';" << std::endl; - if (localName == XML_PREFIX(_scxml).str() + "onexit") { - return "exit_set_" + ATTR_CAST(ecBlock->getParentNode(), "documentOrder") + "_i"; + if (_execContent.size() > 1) { + i = 0; + for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { + // prevent writing seq_0_sig since this should be hardcoded to '1' + if (i != 0) { + // seq lines (input if process i is in seqence now) + stream << "seq_" << toStr(i) << "_sig <= " + << "done_" << toStr(i - 1) << "_sig or " + << "( not " + << getLineForExecContent(*ecIter); + stream << " and seq_" << toStr(i - 1) << "_sig"; + stream << " );" << std::endl; } - } - ecBlock = ecBlock->getParentNode(); } - - return ""; + stream << std::endl; } - void ChartToVHDL::writeMicroStepper(std::ostream &stream) { - // create MicroStepper top level - stream << "-- FSM Logic" << std::endl; - writeIncludes(stream); - stream << "entity micro_stepper is" << std::endl; - stream << "port(" << std::endl; - stream << " --inputs" << std::endl; - stream << " clk :in std_logic;" << std::endl; - stream << " rst_i :in std_logic;" << std::endl; - stream << " en :in std_logic;" << std::endl; - stream << " next_event_i :in std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << " next_event_we_i :in std_logic;" << std::endl; - stream << " --outputs" << std::endl; - stream << " error_o :out std_logic;" << std::endl; - - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; + stream << "end behavioral; " << + std::endl; + stream << "-- END Event Controller Logic" << + std::endl; + stream << + std::endl; +} - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " entry_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; +std::string ChartToVHDL::getLineForExecContent(const DOMNode *elem) { + const DOMNode *ecBlock = elem; + while (ecBlock) { + if (ecBlock->getNodeType() == DOMNode::ELEMENT_NODE) { + std::string localName = LOCALNAME_CAST(ecBlock); + if (localName == XML_PREFIX(_scxml).str() + "transition") { + return "transition_set_" + ATTR_CAST(ecBlock, "postFixOrder") + "_i"; } - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " exit_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; + if (localName == XML_PREFIX(_scxml).str() + "onentry") { + return "entry_set_" + ATTR_CAST(ecBlock->getParentNode(), "documentOrder") + "_i"; } - } - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " transition_set_" << ATTR(transition, "postFixOrder") << "_o :out std_logic;" - << std::endl; + if (localName == XML_PREFIX(_scxml).str() + "onexit") { + return "exit_set_" + ATTR_CAST(ecBlock->getParentNode(), "documentOrder") + "_i"; } - } - - stream << " completed_o :out std_logic" << std::endl; - stream << ");" << std::endl; - stream << "end micro_stepper; " << std::endl; - - stream << std::endl; - stream << "architecture behavioral of micro_stepper is " << std::endl; - stream << std::endl; - // Add signals and components - writeSignalsAndComponents(stream); - - stream << std::endl; - stream << "begin" << std::endl; - stream << std::endl; - - // signal mapping - writeModuleInstantiation(stream); - - // signal handler - writeSpontaneousHandler(stream); - writeErrorHandler(stream); - writeInternalEventHandler(stream); - writeStateHandler(stream); - writeResetHandler(stream); - - // combinatorial logic for Sn+1 - writeOptimalTransitionSetSelection(stream); - writeExitSet(stream); - writeCompleteEntrySet(stream); - writeEntrySet(stream); - //writeDefaultCompletions(stream); - writeActiveStateNplusOne(stream); - - // connect output signals - writeSystemSignalMapping(stream); - - - stream << std::endl; - stream << "end behavioral; " << std::endl; - stream << "-- END FSM Logic" << std::endl; - } - - void ChartToVHDL::writeFiFo(std::ostream &stream) { - // taken from: http://www.deathbylogic.com/2013/07/vhdl-standard-fifo/ - // alternativly take fifo logic for a ram device: http://www.eng.auburn.edu/~strouce/class/elec4200/vhdlmods.pdf - stream << "-- standard FIFO buffer" << std::endl; - writeIncludes(stream); - stream << "" << std::endl; - stream << "entity std_fifo is" << std::endl; - stream << "generic (" << std::endl; - stream << " constant FIFO_DEPTH : positive := 256" << std::endl; - stream << ");" << std::endl; - stream << "port ( " << std::endl; - stream << " clk : in std_logic;" << std::endl; - stream << " rst : in std_logic;" << std::endl; - stream << " write_en : in std_logic;" << std::endl; - stream << " read_en : in std_logic;" << std::endl; - stream << " data_in : in std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << " data_out : out std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << " empty : out std_logic;" << std::endl; - stream << " full : out std_logic" << std::endl; - stream << ");" << std::endl; - stream << "end std_fifo;" << std::endl; - stream << "" << std::endl; - stream << "architecture behavioral of std_fifo is" << std::endl; - stream << "begin" << std::endl; - stream << "-- Memory Pointer Process" << std::endl; - stream << "fifo_proc : process (clk)" << std::endl; - stream << " type FIFO_Memory is array (0 to FIFO_DEPTH - 1) of std_logic_vector( " << _eventBitSize << - " downto 0);" << std::endl; - stream << " variable Memory : FIFO_Memory;" << std::endl; - stream << "" << std::endl; - stream << " variable Head : natural range 0 to FIFO_DEPTH - 1;" << std::endl; - stream << " variable Tail : natural range 0 to FIFO_DEPTH - 1;" << std::endl; - stream << "" << std::endl; - stream << " variable Looped : boolean;" << std::endl; - stream << "begin" << std::endl; - stream << " if rising_edge(clk) then" << std::endl; - stream << " if rst = '1' then" << std::endl; - stream << " Head := 0;" << std::endl; - stream << " Tail := 0;" << std::endl; - stream << "" << std::endl; - stream << " Looped := false;" << std::endl; - stream << "" << std::endl; - stream << " full <= '0';" << std::endl; - stream << " empty <= '1';" << std::endl; - stream << " else" << std::endl; - stream << " if (read_en = '1') then" << std::endl; - stream << " if ((Looped = true) or (Head /= Tail)) then" << std::endl; - stream << " -- Update data output" << std::endl; - stream << " data_out <= Memory(Tail);" << std::endl; - stream << " " << std::endl; - stream << " -- Update Tail pointer as needed" << std::endl; - stream << " if (Tail = FIFO_DEPTH - 1) then" << std::endl; - stream << " Tail := 0;" << std::endl; - stream << " " << std::endl; - stream << " Looped := false;" << std::endl; - stream << " else" << std::endl; - stream << " Tail := Tail + 1;" << std::endl; - stream << " end if;" << std::endl; - stream << "" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << "" << std::endl; - stream << " if (write_en = '1') then" << std::endl; - stream << " if ((Looped = false) or (Head /= Tail)) then" << std::endl; - stream << " -- Write Data to Memory" << std::endl; - stream << " Memory(Head) := data_in;" << std::endl; - stream << " " << std::endl; - stream << " -- Increment Head pointer as needed" << std::endl; - stream << " if (Head = FIFO_DEPTH - 1) then" << std::endl; - stream << " Head := 0;" << std::endl; - stream << " " << std::endl; - stream << " Looped := true;" << std::endl; - stream << " else" << std::endl; - stream << " Head := Head + 1;" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << "" << std::endl; - stream << " -- Update empty and full flags" << std::endl; - stream << " if (Head = Tail) then" << std::endl; - stream << " if Looped then" << std::endl; - stream << " full <= '1';" << std::endl; - stream << " else" << std::endl; - stream << " empty <= '1';" << std::endl; - stream << " end if;" << std::endl; - stream << " else" << std::endl; - stream << " empty <= '0';" << std::endl; - stream << " full <= '0';" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << "end process;" << std::endl; - stream << "" << std::endl; - stream << "end behavioral;" << std::endl; - stream << "-- END standard FIFO buffer" << std::endl; + } + ecBlock = ecBlock->getParentNode(); } - void ChartToVHDL::writeSignalsAndComponents(std::ostream &stream) { - // create internal signals - stream << "-- system signals" << std::endl; - stream << "signal stall : std_logic;" << std::endl; - stream << "signal completed_sig : std_logic;" << std::endl; - stream << "signal rst : std_logic;" << std::endl; - stream << std::endl; - - stream << "-- state signals" << std::endl; - - std::list signalDecls; - - for (auto state : _states) { - std::string parent = ATTR(state, "parent"); - - signalDecls.push_back("signal state_active_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); - signalDecls.push_back("signal state_next_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); - signalDecls.push_back("signal in_entry_set_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); - signalDecls.push_back("signal in_exit_set_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); - signalDecls.push_back("signal in_complete_entry_set_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); - - // not needed for state - if (parent.size() != 0) { - signalDecls.push_back( - "signal in_complete_entry_set_up_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); - } + return ""; +} + +void ChartToVHDL::writeMicroStepper(std::ostream &stream) { + // create MicroStepper top level + stream << "-- FSM Logic" << std::endl; + writeIncludes(stream); + stream << "entity micro_stepper is" << std::endl; + stream << "port(" << std::endl; + stream << " --inputs" << std::endl; + stream << " clk :in std_logic;" << std::endl; + stream << " rst_i :in std_logic;" << std::endl; + stream << " en :in std_logic;" << std::endl; + stream << " next_event_i :in std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << " next_event_we_i :in std_logic;" << std::endl; + stream << " --outputs" << std::endl; + stream << " error_o :out std_logic;" << std::endl; + + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; } - signalDecls.sort(); - for (std::list::iterator iter = signalDecls.begin(); iter != signalDecls.end(); iter++) { - stream << *iter << std::endl; + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; } - stream << std::endl; - - - stream << "-- transition signals" << std::endl; - stream << "signal spontaneous_en : std_logic;" << std::endl; - stream << "signal spontaneous_active : std_logic;" << std::endl; - stream << "signal optimal_transition_set_combined_sig : std_logic;" << std::endl; + } - for (auto transition : _transitions) { - stream << "signal in_optimal_transition_set_" << ATTR(transition, "postFixOrder") << "_sig : std_logic;" - << std::endl; + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") << "_o :out std_logic;" + << std::endl; } - stream << std::endl; - - stream << "-- event signals" << std::endl; - stream << "signal int_event_write_en : std_logic;" << std::endl; - stream << "signal int_event_read_en : std_logic;" << std::endl; - stream << "signal int_event_empty : std_logic;" << std::endl; - stream << "signal int_event_input : std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << "signal int_event_output : std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << "signal next_event_re : std_logic;" << std::endl; - stream << "signal next_event_dequeued : std_logic;" << std::endl; - stream << "signal next_event : std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << "signal event_consumed : std_logic;" << std::endl; - stream << std::endl; + } - for (std::list::iterator eventIter = _eventNames.begin(); - eventIter != _eventNames.end(); eventIter++) { - stream << "signal event_" << escapeMacro((*eventIter)->value) << "_sig : std_logic;" << std::endl; + stream << " completed_o :out std_logic" << std::endl; + stream << ");" << std::endl; + stream << "end micro_stepper; " << std::endl; + + stream << std::endl; + stream << "architecture behavioral of micro_stepper is " << std::endl; + stream << std::endl; + + // Add signals and components + writeSignalsAndComponents(stream); + + stream << std::endl; + stream << "begin" << std::endl; + stream << std::endl; + + // signal mapping + writeModuleInstantiation(stream); + + // signal handler + writeSpontaneousHandler(stream); + writeErrorHandler(stream); + writeInternalEventHandler(stream); + writeStateHandler(stream); + writeResetHandler(stream); + + // combinatorial logic for Sn+1 + writeOptimalTransitionSetSelection(stream); + writeExitSet(stream); + writeCompleteEntrySet(stream); + writeEntrySet(stream); + //writeDefaultCompletions(stream); + writeActiveStateNplusOne(stream); + + // connect output signals + writeSystemSignalMapping(stream); + + + stream << std::endl; + stream << "end behavioral; " << std::endl; + stream << "-- END FSM Logic" << std::endl; +} + +void ChartToVHDL::writeFiFo(std::ostream &stream) { + // taken from: http://www.deathbylogic.com/2013/07/vhdl-standard-fifo/ + // alternativly take fifo logic for a ram device: http://www.eng.auburn.edu/~strouce/class/elec4200/vhdlmods.pdf + stream << "-- standard FIFO buffer" << std::endl; + writeIncludes(stream); + stream << "" << std::endl; + stream << "entity std_fifo is" << std::endl; + stream << "generic (" << std::endl; + stream << " constant FIFO_DEPTH : positive := 256" << std::endl; + stream << ");" << std::endl; + stream << "port ( " << std::endl; + stream << " clk : in std_logic;" << std::endl; + stream << " rst : in std_logic;" << std::endl; + stream << " write_en : in std_logic;" << std::endl; + stream << " read_en : in std_logic;" << std::endl; + stream << " data_in : in std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << " data_out : out std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << " empty : out std_logic;" << std::endl; + stream << " full : out std_logic" << std::endl; + stream << ");" << std::endl; + stream << "end std_fifo;" << std::endl; + stream << "" << std::endl; + stream << "architecture behavioral of std_fifo is" << std::endl; + stream << "begin" << std::endl; + stream << "-- Memory Pointer Process" << std::endl; + stream << "fifo_proc : process (clk)" << std::endl; + stream << " type FIFO_Memory is array (0 to FIFO_DEPTH - 1) of std_logic_vector( " << _eventBitSize << + " downto 0);" << std::endl; + stream << " variable Memory : FIFO_Memory;" << std::endl; + stream << "" << std::endl; + stream << " variable Head : natural range 0 to FIFO_DEPTH - 1;" << std::endl; + stream << " variable Tail : natural range 0 to FIFO_DEPTH - 1;" << std::endl; + stream << "" << std::endl; + stream << " variable Looped : boolean;" << std::endl; + stream << "begin" << std::endl; + stream << " if rising_edge(clk) then" << std::endl; + stream << " if rst = '1' then" << std::endl; + stream << " Head := 0;" << std::endl; + stream << " Tail := 0;" << std::endl; + stream << "" << std::endl; + stream << " Looped := false;" << std::endl; + stream << "" << std::endl; + stream << " full <= '0';" << std::endl; + stream << " empty <= '1';" << std::endl; + stream << " else" << std::endl; + stream << " if (read_en = '1') then" << std::endl; + stream << " if ((Looped = true) or (Head /= Tail)) then" << std::endl; + stream << " -- Update data output" << std::endl; + stream << " data_out <= Memory(Tail);" << std::endl; + stream << " " << std::endl; + stream << " -- Update Tail pointer as needed" << std::endl; + stream << " if (Tail = FIFO_DEPTH - 1) then" << std::endl; + stream << " Tail := 0;" << std::endl; + stream << " " << std::endl; + stream << " Looped := false;" << std::endl; + stream << " else" << std::endl; + stream << " Tail := Tail + 1;" << std::endl; + stream << " end if;" << std::endl; + stream << "" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << "" << std::endl; + stream << " if (write_en = '1') then" << std::endl; + stream << " if ((Looped = false) or (Head /= Tail)) then" << std::endl; + stream << " -- Write Data to Memory" << std::endl; + stream << " Memory(Head) := data_in;" << std::endl; + stream << " " << std::endl; + stream << " -- Increment Head pointer as needed" << std::endl; + stream << " if (Head = FIFO_DEPTH - 1) then" << std::endl; + stream << " Head := 0;" << std::endl; + stream << " " << std::endl; + stream << " Looped := true;" << std::endl; + stream << " else" << std::endl; + stream << " Head := Head + 1;" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << "" << std::endl; + stream << " -- Update empty and full flags" << std::endl; + stream << " if (Head = Tail) then" << std::endl; + stream << " if Looped then" << std::endl; + stream << " full <= '1';" << std::endl; + stream << " else" << std::endl; + stream << " empty <= '1';" << std::endl; + stream << " end if;" << std::endl; + stream << " else" << std::endl; + stream << " empty <= '0';" << std::endl; + stream << " full <= '0';" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << "end process;" << std::endl; + stream << "" << std::endl; + stream << "end behavioral;" << std::endl; + stream << "-- END standard FIFO buffer" << std::endl; +} + +void ChartToVHDL::writeSignalsAndComponents(std::ostream &stream) { + // create internal signals + stream << "-- system signals" << std::endl; + stream << "signal stall : std_logic;" << std::endl; + stream << "signal completed_sig : std_logic;" << std::endl; + stream << "signal rst : std_logic;" << std::endl; + stream << std::endl; + + stream << "-- state signals" << std::endl; + + std::list signalDecls; + + for (auto state : _states) { + std::string parent = ATTR(state, "parent"); + + signalDecls.push_back("signal state_active_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); + signalDecls.push_back("signal state_next_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); + signalDecls.push_back("signal in_entry_set_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); + signalDecls.push_back("signal in_exit_set_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); + signalDecls.push_back("signal in_complete_entry_set_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); + + // not needed for state + if (parent.size() != 0) { + signalDecls.push_back( + "signal in_complete_entry_set_up_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); } - stream << std::endl; - - stream << "-- error signals" << std::endl; - stream << "signal reg_error_out : std_logic;" << std::endl; - stream << "signal error_full_int_event_fifo : std_logic;" << std::endl; - stream << std::endl; - - // add components - stream << "-- event FIFO" << std::endl; - stream << "component std_fifo is" << std::endl; - stream << "port ( " << std::endl; - stream << " clk : in std_logic;" << std::endl; - stream << " rst : in std_logic;" << std::endl; - stream << " write_en : in std_logic;" << std::endl; - stream << " read_en : in std_logic;" << std::endl; - stream << " data_in : in std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << " data_out : out std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << " empty : out std_logic;" << std::endl; - stream << " full : out std_logic" << std::endl; // we calculate how much we need - stream << ");" << std::endl; - stream << "end component;" << std::endl; - stream << std::endl; } - void ChartToVHDL::writeModuleInstantiation(std::ostream &stream) { - // instantiate event fifo - stream << "int_event_fifo : component std_fifo " << std::endl; - stream << "port map ( " << std::endl; - stream << " clk => clk," << std::endl; - stream << " rst => rst_i," << std::endl; - stream << " write_en => int_event_write_en," << std::endl; - stream << " read_en => int_event_read_en," << std::endl; - stream << " data_in => int_event_input," << std::endl; - stream << " data_out => int_event_output," << std::endl; - stream << " empty => int_event_empty," << std::endl; - stream << " full => error_full_int_event_fifo" << std::endl; // we calculate how much we need - stream << ");" << std::endl; - stream << std::endl; + signalDecls.sort(); + for (std::list::iterator iter = signalDecls.begin(); iter != signalDecls.end(); iter++) { + stream << *iter << std::endl; } + stream << std::endl; - void ChartToVHDL::writeErrorHandler(std::ostream &stream) { - // sets error output signal if an error occures somewhere - stream << "-- error handler" << std::endl; - stream << "-- sets error output signal if an error occures somewhere" << std::endl; - stream << "error_handler : process (clk, rst) " << std::endl; - stream << "begin" << std::endl; - stream << " if rst = '1' then" << std::endl; - stream << " reg_error_out <= '0';" << std::endl; - stream << " elsif rising_edge(clk) then" << std::endl; - stream << " reg_error_out <= error_full_int_event_fifo;" << std::endl; - stream << " end if;" << std::endl; - stream << "end process;" << std::endl; - stream << std::endl; - } - void ChartToVHDL::writeResetHandler(std::ostream &stream) { - stream << "-- reset handler" << std::endl; - stream << "rst <= rst_i;" << std::endl; - stream << std::endl; - } + stream << "-- transition signals" << std::endl; + stream << "signal spontaneous_en : std_logic;" << std::endl; + stream << "signal spontaneous_active : std_logic;" << std::endl; + stream << "signal optimal_transition_set_combined_sig : std_logic;" << std::endl; - void ChartToVHDL::writeSpontaneousHandler(std::ostream &stream) { - // sets spontaneous signal - stream << "-- spontaneous handler" << std::endl; - stream << "spontaneous_handler : process (clk, rst) " << std::endl; - stream << "begin" << std::endl; - stream << " if rst = '1' then" << std::endl; - stream << " spontaneous_en <= '1';" << std::endl; - stream << " elsif rising_edge(clk) and stall = '0' then" << std::endl; - stream << " if spontaneous_en = '1' then" << std::endl; - stream << " spontaneous_en <= optimal_transition_set_combined_sig;" << std::endl; - stream << " else" << std::endl; - //if new event is dequeued then 1 else stay 0 - stream << " spontaneous_en <= next_event_dequeued;" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << "end process;" << std::endl; - stream << std::endl; + for (auto transition : _transitions) { + stream << "signal in_optimal_transition_set_" << ATTR(transition, "postFixOrder") << "_sig : std_logic;" + << std::endl; + } + stream << std::endl; + + stream << "-- event signals" << std::endl; + stream << "signal int_event_write_en : std_logic;" << std::endl; + stream << "signal int_event_read_en : std_logic;" << std::endl; + stream << "signal int_event_empty : std_logic;" << std::endl; + stream << "signal int_event_input : std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << "signal int_event_output : std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << "signal next_event_re : std_logic;" << std::endl; + stream << "signal next_event_dequeued : std_logic;" << std::endl; + stream << "signal next_event : std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << "signal event_consumed : std_logic;" << std::endl; + stream << std::endl; + + for (std::list::iterator eventIter = _eventNames.begin(); + eventIter != _eventNames.end(); eventIter++) { + stream << "signal event_" << escapeMacro((*eventIter)->value) << "_sig : std_logic;" << std::endl; + } + stream << std::endl; + + stream << "-- error signals" << std::endl; + stream << "signal reg_error_out : std_logic;" << std::endl; + stream << "signal error_full_int_event_fifo : std_logic;" << std::endl; + stream << std::endl; + + // add components + stream << "-- event FIFO" << std::endl; + stream << "component std_fifo is" << std::endl; + stream << "port ( " << std::endl; + stream << " clk : in std_logic;" << std::endl; + stream << " rst : in std_logic;" << std::endl; + stream << " write_en : in std_logic;" << std::endl; + stream << " read_en : in std_logic;" << std::endl; + stream << " data_in : in std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << " data_out : out std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << " empty : out std_logic;" << std::endl; + stream << " full : out std_logic" << std::endl; // we calculate how much we need + stream << ");" << std::endl; + stream << "end component;" << std::endl; + stream << std::endl; +} + +void ChartToVHDL::writeModuleInstantiation(std::ostream &stream) { + // instantiate event fifo + stream << "int_event_fifo : component std_fifo " << std::endl; + stream << "port map ( " << std::endl; + stream << " clk => clk," << std::endl; + stream << " rst => rst_i," << std::endl; + stream << " write_en => int_event_write_en," << std::endl; + stream << " read_en => int_event_read_en," << std::endl; + stream << " data_in => int_event_input," << std::endl; + stream << " data_out => int_event_output," << std::endl; + stream << " empty => int_event_empty," << std::endl; + stream << " full => error_full_int_event_fifo" << std::endl; // we calculate how much we need + stream << ");" << std::endl; + stream << std::endl; +} + +void ChartToVHDL::writeErrorHandler(std::ostream &stream) { + // sets error output signal if an error occures somewhere + stream << "-- error handler" << std::endl; + stream << "-- sets error output signal if an error occures somewhere" << std::endl; + stream << "error_handler : process (clk, rst) " << std::endl; + stream << "begin" << std::endl; + stream << " if rst = '1' then" << std::endl; + stream << " reg_error_out <= '0';" << std::endl; + stream << " elsif rising_edge(clk) then" << std::endl; + stream << " reg_error_out <= error_full_int_event_fifo;" << std::endl; + stream << " end if;" << std::endl; + stream << "end process;" << std::endl; + stream << std::endl; +} + +void ChartToVHDL::writeResetHandler(std::ostream &stream) { + stream << "-- reset handler" << std::endl; + stream << "rst <= rst_i;" << std::endl; + stream << std::endl; +} + +void ChartToVHDL::writeSpontaneousHandler(std::ostream &stream) { + // sets spontaneous signal + stream << "-- spontaneous handler" << std::endl; + stream << "spontaneous_handler : process (clk, rst) " << std::endl; + stream << "begin" << std::endl; + stream << " if rst = '1' then" << std::endl; + stream << " spontaneous_en <= '1';" << std::endl; + stream << " elsif rising_edge(clk) and stall = '0' then" << std::endl; + stream << " if spontaneous_en = '1' then" << std::endl; + stream << " spontaneous_en <= optimal_transition_set_combined_sig;" << std::endl; + stream << " else" << std::endl; + //if new event is dequeued then 1 else stay 0 + stream << " spontaneous_en <= next_event_dequeued;" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << "end process;" << std::endl; + stream << std::endl; +} + +void ChartToVHDL::writeInternalEventHandler(std::ostream &stream) { + // Add controler specific stuff here + stream << "-- event handler" << std::endl; + stream << "-- pops events and set event signals" << std::endl; + stream << "event_handler : process (clk, rst) " << std::endl; + stream << "begin" << std::endl; + stream << " if rst = '1' then" << std::endl; + + for (std::list::iterator eventIter = _eventNames.begin(); + eventIter != _eventNames.end(); eventIter++) { + stream << " event_" << escapeMacro((*eventIter)->value) << "_sig <= '0';" << std::endl; } - void ChartToVHDL::writeInternalEventHandler(std::ostream &stream) { - // Add controler specific stuff here - stream << "-- event handler" << std::endl; - stream << "-- pops events and set event signals" << std::endl; - stream << "event_handler : process (clk, rst) " << std::endl; - stream << "begin" << std::endl; - stream << " if rst = '1' then" << std::endl; - - for (std::list::iterator eventIter = _eventNames.begin(); - eventIter != _eventNames.end(); eventIter++) { - stream << " event_" << escapeMacro((*eventIter)->value) << "_sig <= '0';" << std::endl; - } + stream << " next_event_dequeued <= '0';" << std::endl; + stream << " event_consumed <= '0';" << std::endl; - stream << " next_event_dequeued <= '0';" << std::endl; - stream << " event_consumed <= '0';" << std::endl; + stream << " elsif falling_edge(clk) and stall = '0' then" << std::endl; - stream << " elsif falling_edge(clk) and stall = '0' then" << std::endl; + VContainer eventConsumed = VOR; + for (auto transition : _transitions) { - VContainer eventConsumed = VOR; - for (auto transition : _transitions) { + if (HAS_ATTR(transition, "event") == true) { + *eventConsumed += VLINE("in_optimal_transition_set_" + + ATTR(transition, "postFixOrder") + "_sig"); + } + } - if (HAS_ATTR(transition, "event") == true) { - *eventConsumed += VLINE("in_optimal_transition_set_" - + ATTR(transition, "postFixOrder") + "_sig"); + VBranch *tree = (VASSIGN, + VLINE("event_consumed"), + eventConsumed); + tree->print(stream); + stream << ";" << std::endl; + + stream << " if int_event_empty = '0' then " << std::endl; + stream << " case next_event is " << std::endl; + + size_t jj = 0; + for (std::list::iterator eventIter = _eventNames.begin(); + eventIter != _eventNames.end(); eventIter++, jj++) { + + stream << " when \"" << toBinStr(jj, _eventBitSize+1) << "\" =>" << std::endl; + for (std::list::iterator eventIter2 = _eventNames.begin(); + eventIter2 != _eventNames.end(); eventIter2++) { + stream << " event_" << escapeMacro((*eventIter2)->value); + if (escapeMacro((*eventIter)->value) == escapeMacro((*eventIter2)->value)) { + stream << "_sig <= '1';" << std::endl; + } else { + stream << "_sig <= '0';" << std::endl; } } + stream << " next_event_dequeued <= '1';" << std::endl; + } + stream << " when others =>" << std::endl; + for (std::list::iterator eventIter = _eventNames.begin(); + eventIter != _eventNames.end(); eventIter++) { + stream << " event_" << escapeMacro((*eventIter)->value) << "_sig <= '0';" << std::endl; + } + stream << " next_event_dequeued <= '0';" << std::endl; + stream << " end case;" << std::endl; + stream << " elsif int_event_empty = '1' and event_consumed = '1' then" << std::endl; + + for (std::list::iterator eventIter = _eventNames.begin(); + eventIter != _eventNames.end(); eventIter++) { + stream << " event_" << escapeMacro((*eventIter)->value) << "_sig <= '0';" << std::endl; + } + stream << " next_event_dequeued <= '0';" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << "end process;" << std::endl; + stream << std::endl; + + stream << "next_event_re <= not int_event_empty and not stall; " << std::endl; + stream << "next_event <= int_event_output; " << std::endl; + stream << "int_event_write_en <= next_event_we_i; " << std::endl; + stream << "int_event_input <= next_event_i; " << std::endl; + stream << "int_event_read_en <= not stall; --not spontaneous_en and " << std::endl; + stream << std::endl; +} + +void ChartToVHDL::writeActiveStateNplusOne(std::ostream &stream) { + stream << "-- active configuration" << std::endl; + + for (auto state : _states) { + std::string parent = ATTR(state, "parent"); + + // special case for to start the state machine + if (parent.size() == 0) { + stream << " state_next_" << ATTR(state, "documentOrder") << "_sig <= " << + "not completed_sig;" << std::endl; + continue; + } VBranch *tree = (VASSIGN, - VLINE("event_consumed"), - eventConsumed); + VLINE("state_next_" + ATTR(state, "documentOrder") + "_sig"), + (VOR, + VLINE("in_complete_entry_set_" + ATTR(state, "documentOrder") + "_sig"), + (VAND, (VNOT, VLINE("in_exit_set_" + ATTR(state, "documentOrder") + "_sig")), + VLINE("state_active_" + ATTR(state, "documentOrder") + "_sig")) + )); + tree->print(stream); stream << ";" << std::endl; - stream << " if int_event_empty = '0' then " << std::endl; - stream << " case next_event is " << std::endl; - - size_t jj = 0; - for (std::list::iterator eventIter = _eventNames.begin(); - eventIter != _eventNames.end(); eventIter++, jj++) { - - stream << " when \"" << toBinStr(jj, _eventBitSize+1) << "\" =>" << std::endl; - for (std::list::iterator eventIter2 = _eventNames.begin(); - eventIter2 != _eventNames.end(); eventIter2++) { - stream << " event_" << escapeMacro((*eventIter2)->value); - if (escapeMacro((*eventIter)->value) == escapeMacro((*eventIter2)->value)) { - stream << "_sig <= '1';" << std::endl; - } else { - stream << "_sig <= '0';" << std::endl; + } +} + +void ChartToVHDL::writeOptimalTransitionSetSelection(std::ostream &stream) { + stream << "-- optimal transition set selection" << std::endl; + VContainer optimalTransitions = VOR; + VContainer spontaneoursActive = VOR; + + for (auto transIter = _transitions.begin(); transIter != _transitions.end(); transIter++) { + DOMElement *transition = *transIter; + std::string conflicts = ATTR(transition, "conflictBools"); + + + VContainer nameMatchers = VOR; + if (HAS_ATTR(transition, "event")) { + std::list eventDescs = tokenize(ATTR(transition, "event")); + for (std::list::iterator descIter = eventDescs.begin(); + descIter != eventDescs.end(); descIter++) { + std::list eventNames = _eventTrie.getWordsWithPrefix( + (*descIter) == "*" ? "" : *descIter); + for (std::list::iterator eventIter = eventNames.begin(); + eventIter != eventNames.end(); eventIter++) { + *nameMatchers += VLINE("event_" + escapeMacro((*eventIter)->value) + "_sig"); } } - stream << " next_event_dequeued <= '1';" << std::endl; - } - stream << " when others =>" << std::endl; - for (std::list::iterator eventIter = _eventNames.begin(); - eventIter != _eventNames.end(); eventIter++) { - stream << " event_" << escapeMacro((*eventIter)->value) << "_sig <= '0';" << std::endl; - } - stream << " next_event_dequeued <= '0';" << std::endl; - stream << " end case;" << std::endl; - stream << " elsif int_event_empty = '1' and event_consumed = '1' then" << std::endl; - - for (std::list::iterator eventIter = _eventNames.begin(); - eventIter != _eventNames.end(); eventIter++) { - stream << " event_" << escapeMacro((*eventIter)->value) << "_sig <= '0';" << std::endl; + } else { + *nameMatchers += VLINE("'1'"); } - stream << " next_event_dequeued <= '0';" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << "end process;" << std::endl; - stream << std::endl; - - stream << "next_event_re <= not int_event_empty and not stall; " << std::endl; - stream << "next_event <= int_event_output; " << std::endl; - stream << "int_event_write_en <= next_event_we_i; " << std::endl; - stream << "int_event_input <= next_event_i; " << std::endl; - stream << "int_event_read_en <= not stall; --not spontaneous_en and " << std::endl; - stream << std::endl; - } - void ChartToVHDL::writeActiveStateNplusOne(std::ostream &stream) { - stream << "-- active configuration" << std::endl; - - for (auto state : _states) { - std::string parent = ATTR(state, "parent"); - - // special case for to start the state machine - if (parent.size() == 0) { - stream << " state_next_" << ATTR(state, "documentOrder") << "_sig <= " << - "not completed_sig;" << std::endl; - continue; + VContainer conflicters = VOR; + for (size_t j = 0; j < strTo(ATTR(transition, "postFixOrder")); j++) { + if (conflicts[j] == '1') { + *conflicters += VLINE("in_optimal_transition_set_" + toStr(j) + "_sig"); } + } - VBranch *tree = (VASSIGN, - VLINE("state_next_" + ATTR(state, "documentOrder") + "_sig"), - (VOR, - VLINE("in_complete_entry_set_" + ATTR(state, "documentOrder") + "_sig"), - (VAND, (VNOT, VLINE("in_exit_set_" + ATTR(state, "documentOrder") + "_sig")), - VLINE("state_active_" + ATTR(state, "documentOrder") + "_sig")) - )); + VBranch *tree = (VASSIGN, + VLINE("in_optimal_transition_set_" + ATTR(transition, "postFixOrder") + "_sig"), + (VAND, + (HAS_ATTR(transition, "event") + ? (VNOT, VLINE("spontaneous_active")) + : (VNOP, VLINE("spontaneous_en"))), + VLINE("state_active_" + ATTR(transition, "source") + "_sig"), + nameMatchers, + (VNOT, conflicters))); - tree->print(stream); - stream << ";" << std::endl; + tree->print(stream); + stream << ";" << std::endl; + *optimalTransitions += VLINE("in_optimal_transition_set_" + + ATTR(transition, "postFixOrder") + "_sig"); + if (HAS_ATTR(transition, "event") == false) { + *spontaneoursActive += VLINE("in_optimal_transition_set_" + + ATTR(transition, "postFixOrder") + "_sig"); } } - void ChartToVHDL::writeOptimalTransitionSetSelection(std::ostream &stream) { - stream << "-- optimal transition set selection" << std::endl; - VContainer optimalTransitions = VOR; - VContainer spontaneoursActive = VOR; - - for (auto transIter = _transitions.begin(); transIter != _transitions.end(); transIter++) { - DOMElement *transition = *transIter; - std::string conflicts = ATTR(transition, "conflictBools"); - - - VContainer nameMatchers = VOR; - if (HAS_ATTR(transition, "event")) { - std::list eventDescs = tokenize(ATTR(transition, "event")); - for (std::list::iterator descIter = eventDescs.begin(); - descIter != eventDescs.end(); descIter++) { - std::list eventNames = _eventTrie.getWordsWithPrefix( - (*descIter) == "*" ? "" : *descIter); - for (std::list::iterator eventIter = eventNames.begin(); - eventIter != eventNames.end(); eventIter++) { - *nameMatchers += VLINE("event_" + escapeMacro((*eventIter)->value) + "_sig"); - } - } - } else { - *nameMatchers += VLINE("'1'"); - } + VBranch *tree = (VASSIGN, + VLINE("optimal_transition_set_combined_sig"), + optimalTransitions); + tree->print(stream); + stream << ";" << std::endl; - VContainer conflicters = VOR; - for (size_t j = 0; j < strTo(ATTR(transition, "postFixOrder")); j++) { - if (conflicts[j] == '1') { - *conflicters += VLINE("in_optimal_transition_set_" + toStr(j) + "_sig"); - } - } + VBranch *tree2 = (VASSIGN, + VLINE("spontaneous_active"), + spontaneoursActive); + tree2->print(stream); + stream << ";" << std::endl; +} - VBranch *tree = (VASSIGN, - VLINE("in_optimal_transition_set_" + ATTR(transition, "postFixOrder") + "_sig"), - (VAND, - (HAS_ATTR(transition, "event") - ? (VNOT, VLINE("spontaneous_active")) - : (VNOP, VLINE("spontaneous_en"))), - VLINE("state_active_" + ATTR(transition, "source") + "_sig"), - nameMatchers, - (VNOT, conflicters))); - - tree->print(stream); - stream << ";" << std::endl; +void ChartToVHDL::writeExitSet(std::ostream &stream) { + stream << "-- exit set selection" << std::endl; + + for (auto state : _states) { - *optimalTransitions += VLINE("in_optimal_transition_set_" - + ATTR(transition, "postFixOrder") + "_sig"); - if (HAS_ATTR(transition, "event") == false) { - *spontaneoursActive += VLINE("in_optimal_transition_set_" - + ATTR(transition, "postFixOrder") + "_sig"); + std::string completion = ATTR(state, "completionBools"); + std::string ancestors = ATTR(state, "ancBools"); + std::string children = ATTR(state, "childBools"); + std::string parent = ATTR(state, "parent"); + + VContainer exitsetters = VOR; + for (auto transition : _transitions) { + std::string exitSet = ATTR(transition, "exitSetBools"); + if (exitSet.at(strTo(ATTR(state, "documentOrder"))) == '1') { + *exitsetters += VLINE("in_optimal_transition_set_" + ATTR(transition, "postFixOrder") + "_sig "); } } VBranch *tree = (VASSIGN, - VLINE("optimal_transition_set_combined_sig"), - optimalTransitions); - tree->print(stream); - stream << ";" << std::endl; + VLINE("in_exit_set_" + ATTR(state, "documentOrder") + "_sig"), + (VAND, + VLINE("state_active_" + ATTR(state, "documentOrder") + "_sig"), + exitsetters)); - VBranch *tree2 = (VASSIGN, - VLINE("spontaneous_active"), - spontaneoursActive); - tree2->print(stream); + tree->print(stream); stream << ";" << std::endl; } +} - void ChartToVHDL::writeExitSet(std::ostream &stream) { - stream << "-- exit set selection" << std::endl; +void ChartToVHDL::writeEntrySet(std::ostream &stream) { + stream << "-- entry set selection" << std::endl; - for (auto state : _states) { - - std::string completion = ATTR(state, "completionBools"); - std::string ancestors = ATTR(state, "ancBools"); - std::string children = ATTR(state, "childBools"); - std::string parent = ATTR(state, "parent"); + for (auto state : _states) { - VContainer exitsetters = VOR; - for (auto transition : _transitions) { - std::string exitSet = ATTR(transition, "exitSetBools"); - if (exitSet.at(strTo(ATTR(state, "documentOrder"))) == '1') { - *exitsetters += VLINE("in_optimal_transition_set_" + ATTR(transition, "postFixOrder") + "_sig "); - } - } - - VBranch *tree = (VASSIGN, - VLINE("in_exit_set_" + ATTR(state, "documentOrder") + "_sig"), - (VAND, - VLINE("state_active_" + ATTR(state, "documentOrder") + "_sig"), - exitsetters)); + VBranch *tree = (VASSIGN, + VLINE("in_entry_set_" + ATTR(state, "documentOrder") + "_sig"), + (VAND, + VLINE("in_complete_entry_set_" + ATTR(state, "documentOrder") + "_sig"), + (VOR, VLINE("in_exit_set_" + ATTR(state, "documentOrder") + "_sig"), + (VNOT, VLINE("state_active_" + ATTR(state, "documentOrder") + "_sig"))))); - tree->print(stream); - stream << ";" << std::endl; - } + tree->print(stream); + stream << ";" << std::endl; } +} - void ChartToVHDL::writeEntrySet(std::ostream &stream) { - stream << "-- entry set selection" << std::endl; +void ChartToVHDL::writeCompleteEntrySet(std::ostream &stream) { + stream << "-- complete entry set selection" << std::endl; - for (auto state : _states) { + for (auto state : _states) { + std::string completion = ATTR(state, "completionBools"); + std::string ancestors = ATTR(state, "ancBools"); + std::string children = ATTR(state, "childBools"); + std::string parent = ATTR(state, "parent"); - VBranch *tree = (VASSIGN, - VLINE("in_entry_set_" + ATTR(state, "documentOrder") + "_sig"), - (VAND, - VLINE("in_complete_entry_set_" + ATTR(state, "documentOrder") + "_sig"), - (VOR, VLINE("in_exit_set_" + ATTR(state, "documentOrder") + "_sig"), - (VNOT, VLINE("state_active_" + ATTR(state, "documentOrder") + "_sig"))))); - - tree->print(stream); - stream << ";" << std::endl; + if (parent.size() == 0) { + continue; // skips node } - } - void ChartToVHDL::writeCompleteEntrySet(std::ostream &stream) { - stream << "-- complete entry set selection" << std::endl; - for (auto state : _states) { - std::string completion = ATTR(state, "completionBools"); - std::string ancestors = ATTR(state, "ancBools"); - std::string children = ATTR(state, "childBools"); - std::string parent = ATTR(state, "parent"); - - if (parent.size() == 0) { - continue; // skips node + // EntrySet for every state types + VContainer optimalEntrysetters = VOR; + for (auto transition : _transitions) { + // Is this state in TargetSet of the transition? + std::string targetSet = ATTR(transition, "targetBools"); + if (targetSet[strTo(ATTR(state, "documentOrder"))] == '1') { + //yes? then add the transition to optimal entry set of the state + *optimalEntrysetters += + VLINE("in_optimal_transition_set_" + ATTR(transition, "postFixOrder") + "_sig"); } + } - - // EntrySet for every state types - VContainer optimalEntrysetters = VOR; - for (auto transition : _transitions) { - // Is this state in TargetSet of the transition? - std::string targetSet = ATTR(transition, "targetBools"); - if (targetSet[strTo(ATTR(state, "documentOrder"))] == '1') { - //yes? then add the transition to optimal entry set of the state - *optimalEntrysetters += - VLINE("in_optimal_transition_set_" + ATTR(transition, "postFixOrder") + "_sig"); + // if composite state (or root) we have to add ancestor completion + VContainer completeEntrysetters = VOR; + if (isCompound(state) || isParallel(state)) { + for (auto tmp_state : _states) { + // is tmp_state is child of state continue? + if (children[strTo(ATTR(state, "documentOrder"))] == '1') { + // yes? then add its complete_entry_set_up as ancestor completion + *completeEntrysetters += + VLINE("in_complete_entry_set_up_" + ATTR(tmp_state, "documentOrder") + "_sig"); } } + } - // if composite state (or root) we have to add ancestor completion - VContainer completeEntrysetters = VOR; - if (isCompound(state) || isParallel(state)) { - for (auto tmp_state : _states) { - // is tmp_state is child of state continue? - if (children[strTo(ATTR(state, "documentOrder"))] == '1') { - // yes? then add its complete_entry_set_up as ancestor completion - *completeEntrysetters += - VLINE("in_complete_entry_set_up_" + ATTR(tmp_state, "documentOrder") + "_sig"); - } - } - } + VBranch *tree = (VASSIGN, + VLINE("in_complete_entry_set_up_" + ATTR(state, "documentOrder") + "_sig"), + (VOR, optimalEntrysetters, completeEntrysetters) + ); + tree->print(stream); + stream << ";" << std::endl; + } - VBranch *tree = (VASSIGN, - VLINE("in_complete_entry_set_up_" + ATTR(state, "documentOrder") + "_sig"), - (VOR, optimalEntrysetters, completeEntrysetters) - ); - tree->print(stream); - stream << ";" << std::endl; - } + // descendant completion + for (auto state : _states) { + std::string completion = ATTR(state, "completionBools"); + std::string ancestors = ATTR(state, "ancBools"); + std::string parent = ATTR(state, "parent"); //is it a int ? - // descendant completion - for (auto state : _states) { - std::string completion = ATTR(state, "completionBools"); - std::string ancestors = ATTR(state, "ancBools"); - std::string parent = ATTR(state, "parent"); //is it a int ? + if (parent.size() == 0) { + continue; // skips node + } - if (parent.size() == 0) { - continue; // skips node - } + VContainer descendantCompletion = VAND; + // if parent is compound + if (getParentState(state) != NULL && + isCompound(getParentState(state))) { + std::string children = ATTR_CAST(_states[strTo(parent)], + "childBools"); + + std::string parentInit = ATTR(getParentState(state), "initial"); + if (// if parent has init field an this state is inside --> add it as default completion + (!parentInit.empty() + && ATTR(state, "id").compare(parentInit) == 0) || + // or add this state as default completion when parent has no init field and it is the first in document order + (parentInit.empty() && + (strTo(ATTR(getParentState(state), "documentOrder")) + 1) == + strTo(ATTR(state, "documentOrder")))) { + *descendantCompletion += + VLINE("in_entry_set_" + ATTR(getParentState(state), "documentOrder") + "_sig"); - VContainer descendantCompletion = VAND; - // if parent is compound - if (getParentState(state) != NULL && - isCompound(getParentState(state))) { - std::string children = ATTR_CAST(_states[strTo(parent)], - "childBools"); - - std::string parentInit = ATTR(getParentState(state), "initial"); - if (// if parent has init field an this state is inside --> add it as default completion - (!parentInit.empty() - && ATTR(state, "id").compare(parentInit) == 0) || - // or add this state as default completion when parent has no init field and it is the first in document order - (parentInit.empty() && - (strTo(ATTR(getParentState(state), "documentOrder")) + 1) == - strTo(ATTR(state, "documentOrder")))) { - *descendantCompletion += - VLINE("in_entry_set_" + ATTR(getParentState(state), "documentOrder") + "_sig"); - - // but only if compound parent is not already completed - for (auto tmp_state : _states) { - if (tmp_state == state) { - // skip state itselve - continue; - } - if (children[strTo(ATTR(tmp_state, "documentOrder"))] == '1') { - *descendantCompletion += (VNOT, - (VAND, - VLINE("state_active_" + ATTR(tmp_state, "documentOrder") + "_sig"), - (VNOT, - VLINE("in_exit_set_" + ATTR(tmp_state, "documentOrder") + - "_sig")))); - } + // but only if compound parent is not already completed + for (auto tmp_state : _states) { + if (tmp_state == state) { + // skip state itselve + continue; + } + if (children[strTo(ATTR(tmp_state, "documentOrder"))] == '1') { + *descendantCompletion += (VNOT, + (VAND, + VLINE("state_active_" + ATTR(tmp_state, "documentOrder") + "_sig"), + (VNOT, + VLINE("in_exit_set_" + ATTR(tmp_state, "documentOrder") + + "_sig")))); } - } else { - // disable this branche - *descendantCompletion += VLINE("'0'"); } - } else - // if parent is parallel + } else { + // disable this branche + *descendantCompletion += VLINE("'0'"); + } + } else + // if parent is parallel if (getParentState(state) != NULL && - isParallel(getParentState(state))) { + isParallel(getParentState(state))) { *descendantCompletion += - VLINE("in_complete_entry_set_" + ATTR(getParentState(state), "documentOrder") + "_sig"); + VLINE("in_complete_entry_set_" + ATTR(getParentState(state), "documentOrder") + "_sig"); } - VBranch *tree = (VASSIGN, - VLINE("in_complete_entry_set_" + ATTR(state, "documentOrder") + "_sig"), - (VOR, - VLINE("in_complete_entry_set_up_" + ATTR(state, "documentOrder") + "_sig"), - descendantCompletion)); + VBranch *tree = (VASSIGN, + VLINE("in_complete_entry_set_" + ATTR(state, "documentOrder") + "_sig"), + (VOR, + VLINE("in_complete_entry_set_up_" + ATTR(state, "documentOrder") + "_sig"), + descendantCompletion)); - tree->print(stream); - stream << ";" << std::endl; - } + tree->print(stream); + stream << ";" << std::endl; } - - void ChartToVHDL::writeStateHandler(std::ostream &stream) { - // updater for current state - stream << "-- State Handler" << std::endl; - stream << "-- updates current state" << std::endl; - stream << "state_proc: process(clk, rst, stall)" << std::endl; - stream << "begin" << std::endl; - stream << " if rst = '1' then" << std::endl; - - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") << "_sig <= " << "'0';" << std::endl; - } - - stream << " in_complete_entry_set_0_sig <= '1';" << std::endl; - stream << " elsif (rising_edge(clk) and stall = '0') then" << std::endl; - stream << " in_complete_entry_set_0_sig <= '0';" << std::endl; - - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") << "_sig <= " << "state_next_" << - ATTR(state, "documentOrder") << "_sig;" << std::endl; - } - - stream << " end if;" << std::endl; - stream << "end process;" << std::endl; - stream << std::endl; +} + +void ChartToVHDL::writeStateHandler(std::ostream &stream) { + // updater for current state + stream << "-- State Handler" << std::endl; + stream << "-- updates current state" << std::endl; + stream << "state_proc: process(clk, rst, stall)" << std::endl; + stream << "begin" << std::endl; + stream << " if rst = '1' then" << std::endl; + + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") << "_sig <= " << "'0';" << std::endl; } - void ChartToVHDL::writeSystemSignalMapping(std::ostream &stream) { - stream << "-- system signals" << std::endl; - std::list topLevelFinal = DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "final", - _scxml); + stream << " in_complete_entry_set_0_sig <= '1';" << std::endl; + stream << " elsif (rising_edge(clk) and stall = '0') then" << std::endl; + stream << " in_complete_entry_set_0_sig <= '0';" << std::endl; - VContainer tlf = VOR; - for (auto final : topLevelFinal) { - *tlf += VLINE("state_active_" + ATTR(final, "documentOrder") + "_sig"); + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") << "_sig <= " << "state_next_" << + ATTR(state, "documentOrder") << "_sig;" << std::endl; + } - } + stream << " end if;" << std::endl; + stream << "end process;" << std::endl; + stream << std::endl; +} - VBranch *tree = (VASSIGN, - VLINE("completed_sig"), - tlf); - - tree->print(stream); - stream << ";" << std::endl; +void ChartToVHDL::writeSystemSignalMapping(std::ostream &stream) { + stream << "-- system signals" << std::endl; + std::list topLevelFinal = DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "final", + _scxml); - // tmp mapping for events - stream << "stall <= not en or completed_sig or ( int_event_empty and not spontaneous_en ) ; " << std::endl; - stream << std::endl; + VContainer tlf = VOR; + for (auto final : topLevelFinal) { + *tlf += VLINE("state_active_" + ATTR(final, "documentOrder") + "_sig"); - // interface signals - stream << "-- interface signals" << std::endl; - for (auto state : _states) { - stream << "state_active_" << ATTR(state, "documentOrder") - << "_o <= state_active_" << ATTR(state, "documentOrder") - << "_sig;" << std::endl; - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << "exit_set_" << ATTR(state, "documentOrder") - << "_o <= in_exit_set_" << ATTR(state, "documentOrder") - << "_sig;" << std::endl; - } + } - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << "entry_set_" << ATTR(state, "documentOrder") - << "_o <= in_entry_set_" << ATTR(state, "documentOrder") - << "_sig;" << std::endl; - } + VBranch *tree = (VASSIGN, + VLINE("completed_sig"), + tlf); + + tree->print(stream); + stream << ";" << std::endl; + + // tmp mapping for events + stream << "stall <= not en or completed_sig or ( int_event_empty and not spontaneous_en ) ; " << std::endl; + stream << std::endl; + + // interface signals + stream << "-- interface signals" << std::endl; + for (auto state : _states) { + stream << "state_active_" << ATTR(state, "documentOrder") + << "_o <= state_active_" << ATTR(state, "documentOrder") + << "_sig;" << std::endl; + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << "exit_set_" << ATTR(state, "documentOrder") + << "_o <= in_exit_set_" << ATTR(state, "documentOrder") + << "_sig;" << std::endl; } - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << "transition_set_" << ATTR(transition, "postFixOrder") - << "_o <= in_optimal_transition_set_" << ATTR(transition, "postFixOrder") - << "_sig;" << std::endl; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << "entry_set_" << ATTR(state, "documentOrder") + << "_o <= in_entry_set_" << ATTR(state, "documentOrder") + << "_sig;" << std::endl; } + } - stream << "completed_o <= completed_sig; " << std::endl; - stream << "error_o <= reg_error_out; " << std::endl; - stream << std::endl; + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << "transition_set_" << ATTR(transition, "postFixOrder") + << "_o <= in_optimal_transition_set_" << ATTR(transition, "postFixOrder") + << "_sig;" << std::endl; + } } + stream << "completed_o <= completed_sig; " << std::endl; + stream << "error_o <= reg_error_out; " << std::endl; + stream << std::endl; +} + } \ No newline at end of file diff --git a/src/uscxml/transform/ChartToVHDL.h b/src/uscxml/transform/ChartToVHDL.h index 3e98c80..e4d9c53 100644 --- a/src/uscxml/transform/ChartToVHDL.h +++ b/src/uscxml/transform/ChartToVHDL.h @@ -31,129 +31,129 @@ namespace uscxml { - class USCXML_API ChartToVHDL : public ChartToC { - public: +class USCXML_API ChartToVHDL : public ChartToC { +public: - virtual ~ChartToVHDL(); + virtual ~ChartToVHDL(); - static Transformer transform(const Interpreter &other); + static Transformer transform(const Interpreter &other); - void writeTo(std::ostream &stream); + void writeTo(std::ostream &stream); - struct VNode { - virtual void print(std::ostream &stream, const std::string padding = "") = 0; + struct VNode { + virtual void print(std::ostream &stream, const std::string padding = "") = 0; - virtual ~VNode() { }; - }; + virtual ~VNode() { }; + }; - struct VBranch : VNode { - std::vector v; + struct VBranch : VNode { + std::vector v; - virtual ~VBranch() { - for (unsigned i = 0; i < v.size(); i++) - delete v[i]; - } + virtual ~VBranch() { + for (unsigned i = 0; i < v.size(); i++) + delete v[i]; + } - VBranch &operator+=(VNode *p) { - v.push_back(p); - return *this; - } - }; + VBranch &operator+=(VNode *p) { + v.push_back(p); + return *this; + } + }; - struct VPointer { - VNode *ptr; + struct VPointer { + VNode *ptr; - operator VNode *() { - return ptr; - } + operator VNode *() { + return ptr; + } - operator VBranch *() { - return static_cast (ptr); - } + operator VBranch *() { + return static_cast (ptr); + } - VPointer &operator/(VNode *p) { - ptr = p; - return *this; - } - }; + VPointer &operator/(VNode *p) { + ptr = p; + return *this; + } + }; - struct VContainer { - VBranch *ptr; + struct VContainer { + VBranch *ptr; - operator VBranch *() { - return ptr; - } + operator VBranch *() { + return ptr; + } - VContainer &operator/(VBranch *p) { - ptr = p; - return *this; - } + VContainer &operator/(VBranch *p) { + ptr = p; + return *this; + } - VContainer &operator,(VPointer p) { - if (ptr) ptr->v.push_back(p.ptr); - return *this; - } + VContainer &operator,(VPointer p) { + if (ptr) ptr->v.push_back(p.ptr); + return *this; + } - VContainer &operator,(VContainer c) { - if (ptr) ptr->v.push_back(c.ptr); - return *this; - } - }; + VContainer &operator,(VContainer c) { + if (ptr) ptr->v.push_back(c.ptr); + return *this; + } + }; - struct VLine : VNode { - VLine(const std::string &name) : name(name) { } + struct VLine : VNode { + VLine(const std::string &name) : name(name) { } - virtual void print(std::ostream &stream, const std::string padding = "") { - stream << " " << name; - } + virtual void print(std::ostream &stream, const std::string padding = "") { + stream << " " << name; + } - std::string name; - }; + std::string name; + }; - struct VAssign : VBranch { - virtual void print(std::ostream &stream, const std::string padding = "") { - v[0]->print(stream, padding); - stream << padding << " <="; - v[1]->print(stream, padding + " "); - } - }; - - struct VAnd : VBranch { - virtual void print(std::ostream &stream, const std::string padding = "") { - stream << std::endl << padding << "( '1' "; - for (unsigned i = 0; i < v.size(); i++) { - stream << std::endl << padding << " and"; - v[i]->print(stream, padding + " "); - } - stream << padding << ")" << std::endl; - } - }; - - struct VOr : VBranch { - virtual void print(std::ostream &stream, const std::string padding = "") { - stream << std::endl << padding << "( '0' "; - for (unsigned i = 0; i < v.size(); i++) { - stream << std::endl << padding << " or"; - v[i]->print(stream, padding + " "); - } - stream << std::endl << padding << ")" << std::endl; - } - }; + struct VAssign : VBranch { + virtual void print(std::ostream &stream, const std::string padding = "") { + v[0]->print(stream, padding); + stream << padding << " <="; + v[1]->print(stream, padding + " "); + } + }; - struct VNot : VBranch { - virtual void print(std::ostream &stream, const std::string padding = "") { - stream << " ( not"; - v[0]->print(stream, padding + " "); - stream << " )"; + struct VAnd : VBranch { + virtual void print(std::ostream &stream, const std::string padding = "") { + stream << std::endl << padding << "( '1' "; + for (unsigned i = 0; i < v.size(); i++) { + stream << std::endl << padding << " and"; + v[i]->print(stream, padding + " "); } - }; + stream << padding << ")" << std::endl; + } + }; - struct VNop : VBranch { - virtual void print(std::ostream &stream, const std::string padding = "") { - v[0]->print(stream, padding); + struct VOr : VBranch { + virtual void print(std::ostream &stream, const std::string padding = "") { + stream << std::endl << padding << "( '0' "; + for (unsigned i = 0; i < v.size(); i++) { + stream << std::endl << padding << " or"; + v[i]->print(stream, padding + " "); } - }; + stream << std::endl << padding << ")" << std::endl; + } + }; + + struct VNot : VBranch { + virtual void print(std::ostream &stream, const std::string padding = "") { + stream << " ( not"; + v[0]->print(stream, padding + " "); + stream << " )"; + } + }; + + struct VNop : VBranch { + virtual void print(std::ostream &stream, const std::string padding = "") { + v[0]->print(stream, padding); + } + }; //TODO can we create the macros without IDE errors ?! #define VLINE VPointer()/new VLine @@ -164,66 +164,66 @@ namespace uscxml { #define VNOP VContainer()/new VNop - protected: - ChartToVHDL(const Interpreter &other); +protected: + ChartToVHDL(const Interpreter &other); - void findEvents(); + void findEvents(); - void writeIncludes(std::ostream &stream); + void writeIncludes(std::ostream &stream); - // top layer components - void writeFiFo(std::ostream &stream); + // top layer components + void writeFiFo(std::ostream &stream); - void writeEventController(std::ostream &stream); + void writeEventController(std::ostream &stream); - void writeMicroStepper(std::ostream &stream); + void writeMicroStepper(std::ostream &stream); - void writeTestbench(std::ostream &stream); + void writeTestbench(std::ostream &stream); - void writeTopLevel(std::ostream &stream); + void writeTopLevel(std::ostream &stream); - // system - void writeSignalsAndComponents(std::ostream &stream); + // system + void writeSignalsAndComponents(std::ostream &stream); - void writeSystemSignalMapping(std::ostream &stream); + void writeSystemSignalMapping(std::ostream &stream); - void writeModuleInstantiation(std::ostream &stream); + void writeModuleInstantiation(std::ostream &stream); - // combinatorial logic - void writeOptimalTransitionSetSelection(std::ostream &stream); + // combinatorial logic + void writeOptimalTransitionSetSelection(std::ostream &stream); - void writeExitSet(std::ostream &stream); + void writeExitSet(std::ostream &stream); - void writeEntrySet(std::ostream &stream); + void writeEntrySet(std::ostream &stream); - void writeCompleteEntrySet(std::ostream &stream); + void writeCompleteEntrySet(std::ostream &stream); - void writeActiveStateNplusOne(std::ostream &stream); + void writeActiveStateNplusOne(std::ostream &stream); - // handler - void writeStateHandler(std::ostream &stream); + // handler + void writeStateHandler(std::ostream &stream); - void writeResetHandler(std::ostream &stream); + void writeResetHandler(std::ostream &stream); - void writeSpontaneousHandler(std::ostream &stream); + void writeSpontaneousHandler(std::ostream &stream); - void writeInternalEventHandler(std::ostream &stream); + void writeInternalEventHandler(std::ostream &stream); - void writeErrorHandler(std::ostream &stream); + void writeErrorHandler(std::ostream &stream); - Trie _eventTrie; - std::list _eventNames; - size_t _eventBitSize = 0; - std::map _eventsOnBus; - std::list _execContent; + Trie _eventTrie; + std::list _eventNames; + size_t _eventBitSize = 0; + std::map _eventsOnBus; + std::list _execContent; - private: - std::string getLineForExecContent(const XERCESC_NS::DOMNode *elem); +private: + std::string getLineForExecContent(const XERCESC_NS::DOMNode *elem); - bool isSupportedExecContent(XERCESC_NS::DOMElement *execContentElement); - }; + bool isSupportedExecContent(XERCESC_NS::DOMElement *execContentElement); +}; } diff --git a/src/uscxml/util/String.cpp b/src/uscxml/util/String.cpp index 2183ba8..95d69e9 100644 --- a/src/uscxml/util/String.cpp +++ b/src/uscxml/util/String.cpp @@ -25,203 +25,203 @@ namespace uscxml { #define ISWHITESPACE(char) (isspace(char)) - std::string escapeMacro(std::string const &s) { - // inspired by http://stackoverflow.com/questions/2417588/escaping-a-c-string - std::string returnValue = ""; - std::string specialChars = ""; - for (std::string::const_iterator iter = s.begin(), end = s.end(); iter != end; ++iter) { - char c = *iter; - if (('0' <= c && c <= '9') || ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || c == '_') { - returnValue += c; - } else { - specialChars += c; - } - } - if (!specialChars.empty()) { - // http://www.cplusplus.com/reference/functional/hash/ - // returns the same result for a given string within one execution - std::hash strHash; - returnValue += "_"; - returnValue += strHash(specialChars); +std::string escapeMacro(std::string const &s) { + // inspired by http://stackoverflow.com/questions/2417588/escaping-a-c-string + std::string returnValue = ""; + std::string specialChars = ""; + for (std::string::const_iterator iter = s.begin(), end = s.end(); iter != end; ++iter) { + char c = *iter; + if (('0' <= c && c <= '9') || ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || c == '_') { + returnValue += c; + } else { + specialChars += c; } - return returnValue; } + if (!specialChars.empty()) { + // http://www.cplusplus.com/reference/functional/hash/ + // returns the same result for a given string within one execution + std::hash strHash; + returnValue += "_"; + returnValue += strHash(specialChars); + } + return returnValue; +} - std::string toBinStr(size_t val, size_t margin) { - // inspired by http://www.cplusplus.com/forum/general/65862/ - - // mask has only the leftmost bit set. - size_t mask = 1u << (std::numeric_limits::digits - 1); +std::string toBinStr(size_t val, size_t margin) { + // inspired by http://www.cplusplus.com/forum/general/65862/ - // skip leading bits that are not set. - while (0 == (val & mask) && mask != 0) - mask >>= 1; // shift all bits to the right by 1 + // mask has only the leftmost bit set. + size_t mask = 1u << (std::numeric_limits::digits - 1); - std::string binStr; - binStr.reserve(std::numeric_limits::digits + 1); + // skip leading bits that are not set. + while (0 == (val & mask) && mask != 0) + mask >>= 1; // shift all bits to the right by 1 - do { - // add a '1' or '0' depending the current bit. - binStr += static_cast(val & mask) + '0'; + std::string binStr; + binStr.reserve(std::numeric_limits::digits + 1); - } while ((mask >>= 1) != 0); // next bit, when mask is 0 we've processed all bits + do { + // add a '1' or '0' depending the current bit. + binStr += static_cast(val & mask) + '0'; - // fill with leading 0 - if (binStr.size() < margin) { - for (size_t i = 0; i < (margin - binStr.size()); i++) { - binStr = "0" + binStr; - } - } + } while ((mask >>= 1) != 0); // next bit, when mask is 0 we've processed all bits - return binStr; + // fill with leading 0 + if (binStr.size() < margin) { + for (size_t i = 0; i < (margin - binStr.size()); i++) { + binStr = "0" + binStr; + } } - std::list tokenize(const std::string &line, const char sep, bool trimWhiteSpace) { - std::list tokens; - - // appr. 3x faster than stringstream - size_t start = 0; - for (size_t i = 0; i < line.size(); i++) { - if (line[i] == sep || (trimWhiteSpace && ISWHITESPACE(line[i]))) { - if (i > 0 && start < i) { - tokens.push_back(line.substr(start, i - start)); - } - while (line[i] == sep || (trimWhiteSpace && ISWHITESPACE(line[i]))) { - i++; // skip multiple occurences of seperator and whitespaces - } - start = i; - } else if (i + 1 == line.size()) { - tokens.push_back(line.substr(start, i + 1 - start)); + return binStr; +} + +std::list tokenize(const std::string &line, const char sep, bool trimWhiteSpace) { + std::list tokens; + + // appr. 3x faster than stringstream + size_t start = 0; + for (size_t i = 0; i < line.size(); i++) { + if (line[i] == sep || (trimWhiteSpace && ISWHITESPACE(line[i]))) { + if (i > 0 && start < i) { + tokens.push_back(line.substr(start, i - start)); + } + while (line[i] == sep || (trimWhiteSpace && ISWHITESPACE(line[i]))) { + i++; // skip multiple occurences of seperator and whitespaces } + start = i; + } else if (i + 1 == line.size()) { + tokens.push_back(line.substr(start, i + 1 - start)); } - - return tokens; } - std::string spaceNormalize(const std::string &text) { - std::stringstream content; + return tokens; +} + +std::string spaceNormalize(const std::string &text) { + std::stringstream content; #if 1 - // 195ms with test-performance-events.scml - std::string seperator; - - size_t start = 0; - for (size_t i = 0; i < text.size(); i++) { - if (isspace(text[i])) { - if (i > 0 && start < i) { - content << seperator << text.substr(start, i - start); - seperator = " "; - } - while (isspace(text[++i])); // skip whitespaces - start = i; - } else if (i + 1 == text.size()) { - content << seperator << text.substr(start, i + 1 - start); + // 195ms with test-performance-events.scml + std::string seperator; + + size_t start = 0; + for (size_t i = 0; i < text.size(); i++) { + if (isspace(text[i])) { + if (i > 0 && start < i) { + content << seperator << text.substr(start, i - start); + seperator = " "; } + while (isspace(text[++i])); // skip whitespaces + start = i; + } else if (i + 1 == text.size()) { + content << seperator << text.substr(start, i + 1 - start); } + } // std::cerr << ">>" << content.str() << "<<" << std::endl; #else - // 291ms with test-performance-events.scml - std::istringstream iss(text); - std::string seperator; - do { - std::string token; - iss >> token; - if (token.length() > 0) { - content << seperator << token; - seperator = " "; - } - } while (iss); + // 291ms with test-performance-events.scml + std::istringstream iss(text); + std::string seperator; + do { + std::string token; + iss >> token; + if (token.length() > 0) { + content << seperator << token; + seperator = " "; + } + } while (iss); #endif - return content.str(); - } + return content.str(); +} // see: http://www.w3.org/TR/scxml/#EventDescriptors - bool nameMatch(const std::string &eventDescs, const std::string &eventName) { +bool nameMatch(const std::string &eventDescs, const std::string &eventName) { #if 1 - if (eventDescs.length() == 0 || eventName.length() == 0) - return false; + if (eventDescs.length() == 0 || eventName.length() == 0) + return false; - // naive case of single descriptor and exact match - if (boost::iequals(eventDescs, eventName)) - return true; + // naive case of single descriptor and exact match + if (boost::iequals(eventDescs, eventName)) + return true; - size_t start = 0; - std::string eventDesc; - for (size_t i = 0; i < eventDescs.size(); i++) { - if (isspace(eventDescs[i])) { - if (i > 0 && start < i - 1) { - eventDesc = eventDescs.substr(start, i - start); - } - while (isspace(eventDescs[++i])); // skip whitespaces - start = i; - } else if (i + 1 == eventDescs.size()) { - eventDesc = eventDescs.substr(start, i + 1 - start); + size_t start = 0; + std::string eventDesc; + for (size_t i = 0; i < eventDescs.size(); i++) { + if (isspace(eventDescs[i])) { + if (i > 0 && start < i - 1) { + eventDesc = eventDescs.substr(start, i - start); } + while (isspace(eventDescs[++i])); // skip whitespaces + start = i; + } else if (i + 1 == eventDescs.size()) { + eventDesc = eventDescs.substr(start, i + 1 - start); + } - if (eventDesc.size() > 0) { - // remove optional trailing .* for CCXML compatibility - if (eventDesc.find("*", eventDesc.size() - 1) != std::string::npos) - eventDesc = eventDesc.substr(0, eventDesc.size() - 1); - if (eventDesc.find(".", eventDesc.size() - 1) != std::string::npos) - eventDesc = eventDesc.substr(0, eventDesc.size() - 1); + if (eventDesc.size() > 0) { + // remove optional trailing .* for CCXML compatibility + if (eventDesc.find("*", eventDesc.size() - 1) != std::string::npos) + eventDesc = eventDesc.substr(0, eventDesc.size() - 1); + if (eventDesc.find(".", eventDesc.size() - 1) != std::string::npos) + eventDesc = eventDesc.substr(0, eventDesc.size() - 1); - // was eventDesc the * wildcard - if (eventDesc.size() == 0) - return true; + // was eventDesc the * wildcard + if (eventDesc.size() == 0) + return true; - // eventDesc has to be a real prefix of event now and therefore shorter - if (eventDesc.size() > eventName.size()) - goto NEXT_DESC; + // eventDesc has to be a real prefix of event now and therefore shorter + if (eventDesc.size() > eventName.size()) + goto NEXT_DESC; - // are they already equal? - if (boost::iequals(eventDesc, eventName)) - return true; + // are they already equal? + if (boost::iequals(eventDesc, eventName)) + return true; - if (eventName.find(eventDesc) == 0) { - if (eventName.find(".", eventDesc.size()) == eventDesc.size()) - return true; - } - NEXT_DESC: - eventDesc = ""; + if (eventName.find(eventDesc) == 0) { + if (eventName.find(".", eventDesc.size()) == eventDesc.size()) + return true; } +NEXT_DESC: + eventDesc = ""; } - return false; + } + return false; #else - const char* dPtr = eventDescs.c_str(); - const char* ePtr = eventName.c_str(); - while(*dPtr != 0) { + const char* dPtr = eventDescs.c_str(); + const char* ePtr = eventName.c_str(); + while(*dPtr != 0) { - if (*dPtr == '*' && *ePtr != 0) // something following - return true; + if (*dPtr == '*' && *ePtr != 0) // something following + return true; - // descriptor differs from event name - if (*dPtr != *ePtr) { - // move to next descriptor - while(*dPtr != ' ' && *dPtr != 0) { - dPtr++; - } - if (*dPtr == 0) - return false; + // descriptor differs from event name + if (*dPtr != *ePtr) { + // move to next descriptor + while(*dPtr != ' ' && *dPtr != 0) { dPtr++; - ePtr = eventName.c_str(); - } else { - // move both pointers one character - dPtr++; - ePtr++; - } + if (*dPtr == 0) + return false; + dPtr++; + ePtr = eventName.c_str(); + } else { + // move both pointers one character + dPtr++; + ePtr++; - // descriptor is done, return match - if (((*dPtr == 0 || *dPtr == ' ') && (*ePtr == 0 || *ePtr == ' ')) || // exact match, end of string - (*dPtr == ' ' && *ePtr == '.') || (*dPtr == 0 && *ePtr == '.')) // prefix match - return true; } - return false; -#endif + + // descriptor is done, return match + if (((*dPtr == 0 || *dPtr == ' ') && (*ePtr == 0 || *ePtr == ' ')) || // exact match, end of string + (*dPtr == ' ' && *ePtr == '.') || (*dPtr == 0 && *ePtr == '.')) // prefix match + return true; } + return false; +#endif +} } \ No newline at end of file diff --git a/src/uscxml/util/String.h b/src/uscxml/util/String.h index 91b8462..974db3b 100644 --- a/src/uscxml/util/String.h +++ b/src/uscxml/util/String.h @@ -25,15 +25,15 @@ namespace uscxml { - std::string escapeMacro(std::string const &s); +std::string escapeMacro(std::string const &s); - std::string toBinStr(size_t val, size_t margin); +std::string toBinStr(size_t val, size_t margin); - std::list tokenize(const std::string &line, const char seperator = ' ', bool trimWhiteSpace = true); +std::list tokenize(const std::string &line, const char seperator = ' ', bool trimWhiteSpace = true); - std::string spaceNormalize(const std::string &text); +std::string spaceNormalize(const std::string &text); - bool nameMatch(const std::string &eventDescs, const std::string &event); +bool nameMatch(const std::string &eventDescs, const std::string &event); } -- cgit v0.12