summaryrefslogtreecommitdiffstats
path: root/src/uscxml
diff options
context:
space:
mode:
authorJens Heuschkel <heuschkel@tk.tu-darmstadt.de>2016-11-23 10:24:55 (GMT)
committerJens Heuschkel <heuschkel@tk.tu-darmstadt.de>2016-11-23 10:24:55 (GMT)
commit5dbac430453dac1ec1fb76250797df7222f37f40 (patch)
tree26e3c255ac71afa09267242ea882878a3599b7fa /src/uscxml
parente7aa2089b209388afd361b1d094ceeb57b5a6910 (diff)
downloaduscxml-5dbac430453dac1ec1fb76250797df7222f37f40.zip
uscxml-5dbac430453dac1ec1fb76250797df7222f37f40.tar.gz
uscxml-5dbac430453dac1ec1fb76250797df7222f37f40.tar.bz2
butify code again
Diffstat (limited to 'src/uscxml')
-rw-r--r--src/uscxml/plugins/datamodel/promela/PromelaParser.cpp2
-rw-r--r--src/uscxml/transform/ChartToPromela.cpp4610
-rw-r--r--src/uscxml/transform/ChartToPromela.h82
-rw-r--r--src/uscxml/transform/ChartToVHDL.cpp2708
-rw-r--r--src/uscxml/transform/ChartToVHDL.h322
-rw-r--r--src/uscxml/transform/Transformer.h10
-rw-r--r--src/uscxml/transform/promela/PromelaCodeAnalyzer.cpp258
-rw-r--r--src/uscxml/transform/promela/PromelaCodeAnalyzer.h30
-rw-r--r--src/uscxml/util/String.cpp25
9 files changed, 4027 insertions, 4020 deletions
diff --git a/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp b/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp
index 32fbc13..57f694a 100644
--- a/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp
+++ b/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp
@@ -85,7 +85,7 @@ void PromelaParser::init(const std::string& expr) {
parseInCompound = 0;
input_length = expr.length() + 2; // plus some zero terminators
input = (char*) calloc(1, input_length);
- memcpy(input, expr.c_str(), expr.length());
+ memcpy(input, expr.c_str(), expr.length());
promela_lex_init(&scanner);
// promela_assign_set_extra(ast, &scanner);
diff --git a/src/uscxml/transform/ChartToPromela.cpp b/src/uscxml/transform/ChartToPromela.cpp
index 06c8a92..5dcf9f0 100644
--- a/src/uscxml/transform/ChartToPromela.cpp
+++ b/src/uscxml/transform/ChartToPromela.cpp
@@ -78,140 +78,140 @@ ChartToPromela::~ChartToPromela() {
}
void ChartToPromela::prepare() {
- if (_machinesAll == NULL) {
- _machinesAll = new std::map<DOMElement*, ChartToPromela*>();
- (*_machinesAll)[_scxml] = this;
- }
-
- if (_machinesAllPerId == NULL)
- _machinesAllPerId = new std::map<std::string, XERCESC_NS::DOMElement* >();
-
- if (_parentTopMost == NULL) {
- _parentTopMost = this;
- }
-
- // are there nested SCXML invokers?
- std::list<DOMElement*> invokes = DOMUtils::inDocumentOrder({ XML_PREFIX(_scxml).str() + "invoke" }, _scxml);
- for (auto invoke : invokes) {
-
- if (!HAS_ATTR(invoke, "id")) {
- invoke->setAttribute(X("id"), X("INV_" + UUID::getUUID().substr(0,5)));
- } else if (HAS_ATTR(invoke, "id") && UUID::isUUID(ATTR(invoke, "id"))) {
- // shorten UUIDs
- invoke->setAttribute(X("id"), X("INV_" + ATTR(invoke, "id").substr(0,5)));
- }
-
- if (HAS_ATTR(invoke, "type") &&
- ATTR(invoke, "type") != "scxml" &&
- ATTR(invoke, "type") != "http://www.w3.org/TR/scxml/" &&
- ATTR(invoke, "type") != "http://www.w3.org/TR/scxml/#SCXMLEventProcessor")
- continue;
-
- assert(HAS_ATTR(invoke, "id"));
- invoke->setAttribute(X("name"), invoke->getAttribute(X("id")));
-
- Interpreter nested;
- if (HAS_ATTR(invoke, "src")) {
- nested = Interpreter::fromURL(URL::resolve(ATTR(invoke, "src"), _baseURL));
- } else {
- std::list<DOMElement*> contents = DOMUtils::filterChildElements(XML_PREFIX(invoke).str() + "content", invoke);
- std::list<DOMElement*> scxmls = DOMUtils::filterChildElements(XML_PREFIX(invoke).str() + "scxml", contents.front());
-
- assert (scxmls.size() > 0);
- nested = Interpreter::fromElement(scxmls.front(), _baseURL);
- }
-
- _machinesNested[invoke] = new ChartToPromela(nested);
- _machinesNested[invoke]->_analyzer = _analyzer;
- _machinesNested[invoke]->_analyzer->analyze(_machinesNested[invoke]);
- _machinesNested[invoke]->prepare();
- _machinesNested[invoke]->_parent = this;
- _machinesNested[invoke]->_parentTopMost = _parentTopMost;
- _machinesNested[invoke]->_machinesAll = _machinesAll;
- (*_machinesAll)[invoke] = _machinesNested[invoke];
-
- _machinesNested[invoke]->_invokerid = ATTR(invoke, "id");
- _analyzer->createMacroName(_machinesNested[invoke]->_invokerid);
- _analyzer->addEvent("done.invoke." + _machinesNested[invoke]->_invokerid);
-
- _machinesNested[invoke]->_prefix = _analyzer->macroForLiteral(ATTR(invoke, "id")) + "_";
-
-
- _machinesPerId[ATTR_CAST(invoke, "id")] = invoke;
- (*_machinesAllPerId)[ATTR(invoke, "id")] = invoke;
-
- }
-
- if (_machinesAll->size() > 1) {
+ if (_machinesAll == NULL) {
+ _machinesAll = new std::map<DOMElement*, ChartToPromela*>();
+ (*_machinesAll)[_scxml] = this;
+ }
+
+ if (_machinesAllPerId == NULL)
+ _machinesAllPerId = new std::map<std::string, XERCESC_NS::DOMElement* >();
+
+ if (_parentTopMost == NULL) {
+ _parentTopMost = this;
+ }
+
+ // are there nested SCXML invokers?
+ std::list<DOMElement*> invokes = DOMUtils::inDocumentOrder({ XML_PREFIX(_scxml).str() + "invoke" }, _scxml);
+ for (auto invoke : invokes) {
+
+ if (!HAS_ATTR(invoke, "id")) {
+ invoke->setAttribute(X("id"), X("INV_" + UUID::getUUID().substr(0,5)));
+ } else if (HAS_ATTR(invoke, "id") && UUID::isUUID(ATTR(invoke, "id"))) {
+ // shorten UUIDs
+ invoke->setAttribute(X("id"), X("INV_" + ATTR(invoke, "id").substr(0,5)));
+ }
+
+ if (HAS_ATTR(invoke, "type") &&
+ ATTR(invoke, "type") != "scxml" &&
+ ATTR(invoke, "type") != "http://www.w3.org/TR/scxml/" &&
+ ATTR(invoke, "type") != "http://www.w3.org/TR/scxml/#SCXMLEventProcessor")
+ continue;
+
+ assert(HAS_ATTR(invoke, "id"));
+ invoke->setAttribute(X("name"), invoke->getAttribute(X("id")));
+
+ Interpreter nested;
+ if (HAS_ATTR(invoke, "src")) {
+ nested = Interpreter::fromURL(URL::resolve(ATTR(invoke, "src"), _baseURL));
+ } else {
+ std::list<DOMElement*> contents = DOMUtils::filterChildElements(XML_PREFIX(invoke).str() + "content", invoke);
+ std::list<DOMElement*> scxmls = DOMUtils::filterChildElements(XML_PREFIX(invoke).str() + "scxml", contents.front());
+
+ assert (scxmls.size() > 0);
+ nested = Interpreter::fromElement(scxmls.front(), _baseURL);
+ }
+
+ _machinesNested[invoke] = new ChartToPromela(nested);
+ _machinesNested[invoke]->_analyzer = _analyzer;
+ _machinesNested[invoke]->_analyzer->analyze(_machinesNested[invoke]);
+ _machinesNested[invoke]->prepare();
+ _machinesNested[invoke]->_parent = this;
+ _machinesNested[invoke]->_parentTopMost = _parentTopMost;
+ _machinesNested[invoke]->_machinesAll = _machinesAll;
+ (*_machinesAll)[invoke] = _machinesNested[invoke];
+
+ _machinesNested[invoke]->_invokerid = ATTR(invoke, "id");
+ _analyzer->createMacroName(_machinesNested[invoke]->_invokerid);
+ _analyzer->addEvent("done.invoke." + _machinesNested[invoke]->_invokerid);
+
+ _machinesNested[invoke]->_prefix = _analyzer->macroForLiteral(ATTR(invoke, "id")) + "_";
+
+
+ _machinesPerId[ATTR_CAST(invoke, "id")] = invoke;
+ (*_machinesAllPerId)[ATTR(invoke, "id")] = invoke;
+
+ }
+
+ if (_machinesAll->size() > 1) {
// _analyzer->addCode("_event.origin", this);
- _analyzer->addCode("_event.invokeid", this);
- }
-
- // transform data / assign json into PROMELA statements
- std::list<DOMElement*> values;
- values.splice(values.end(), DOMUtils::inDocumentOrder({XML_PREFIX(_scxml).str() + "assign"}, _scxml));
- values.splice(values.end(), DOMUtils::inDocumentOrder({XML_PREFIX(_scxml).str() + "data"}, _scxml));
-
- for (auto element : values) {
- std::string key;
- if (HAS_ATTR(element, "id")) {
- key = ATTR(element, "id");
- } else if (HAS_ATTR(element, "location")) {
- key = ATTR(element, "location");
- }
-
- if (key.length() == 0)
- continue;
-
- std::string value;
- if (HAS_ATTR(element, "expr")) {
- value = ATTR(element, "expr");
- } else if (HAS_ATTR(element, "src")) {
- URL absUrl = URL::resolve(ATTR_CAST(element, "src"), _baseURL);
- value = absUrl.getInContent();
- } else {
- std::list<DOMNode*> assignTexts = DOMUtils::filterChildType(DOMNode::TEXT_NODE, element, true);
- if (assignTexts.size() > 0) {
- for (auto assignText : assignTexts) {
- value += X(assignText->getNodeValue()).str();
- }
- }
- }
-
- boost::trim(value);
- if (value.size() == 0)
- continue;
-
- // remove all children, we will replace by suitable promela statements
- while(element->hasChildNodes())
- element->removeChild(element->getFirstChild());
-
- std::string newValue;
- Data json = Data::fromJSON(value);
- if (!json.empty()) {
- newValue = dataToAssignments(key, json);
- } else {
- newValue = key + " = " + value + ";";
- }
-
- if (LOCALNAME(element) == "data")
- _varInitializers.push_back(newValue);
-
- DOMText* newText = _document->createTextNode(X(newValue));
- element->insertBefore(newText, NULL);
-
- _analyzer->addCode(newValue, this);
-
- }
+ _analyzer->addCode("_event.invokeid", this);
+ }
+
+ // transform data / assign json into PROMELA statements
+ std::list<DOMElement*> values;
+ values.splice(values.end(), DOMUtils::inDocumentOrder({XML_PREFIX(_scxml).str() + "assign"}, _scxml));
+ values.splice(values.end(), DOMUtils::inDocumentOrder({XML_PREFIX(_scxml).str() + "data"}, _scxml));
+
+ for (auto element : values) {
+ std::string key;
+ if (HAS_ATTR(element, "id")) {
+ key = ATTR(element, "id");
+ } else if (HAS_ATTR(element, "location")) {
+ key = ATTR(element, "location");
+ }
+
+ if (key.length() == 0)
+ continue;
+
+ std::string value;
+ if (HAS_ATTR(element, "expr")) {
+ value = ATTR(element, "expr");
+ } else if (HAS_ATTR(element, "src")) {
+ URL absUrl = URL::resolve(ATTR_CAST(element, "src"), _baseURL);
+ value = absUrl.getInContent();
+ } else {
+ std::list<DOMNode*> assignTexts = DOMUtils::filterChildType(DOMNode::TEXT_NODE, element, true);
+ if (assignTexts.size() > 0) {
+ for (auto assignText : assignTexts) {
+ value += X(assignText->getNodeValue()).str();
+ }
+ }
+ }
+
+ boost::trim(value);
+ if (value.size() == 0)
+ continue;
+
+ // remove all children, we will replace by suitable promela statements
+ while(element->hasChildNodes())
+ element->removeChild(element->getFirstChild());
+
+ std::string newValue;
+ Data json = Data::fromJSON(value);
+ if (!json.empty()) {
+ newValue = dataToAssignments(key, json);
+ } else {
+ newValue = key + " = " + value + ";";
+ }
+
+ if (LOCALNAME(element) == "data")
+ _varInitializers.push_back(newValue);
+
+ DOMText* newText = _document->createTextNode(X(newValue));
+ element->insertBefore(newText, NULL);
+
+ _analyzer->addCode(newValue, this);
+
+ }
}
-
+
void ChartToPromela::writeTo(std::ostream& stream) {
- _prefix = "ROOT_";
- _invokerid = "ROOT";
- _analyzer = new PromelaCodeAnalyzer();
- _analyzer->analyze(this);
- _analyzer->createMacroName(_invokerid);
- prepare();
+ _prefix = "ROOT_";
+ _invokerid = "ROOT";
+ _analyzer = new PromelaCodeAnalyzer();
+ _analyzer->analyze(this);
+ _analyzer->createMacroName(_invokerid);
+ prepare();
stream << "/** generated from " << std::endl;
stream << " " << std::string(_baseURL) << std::endl;
@@ -224,88 +224,88 @@ void ChartToPromela::writeTo(std::ostream& stream) {
writeMacros(stream);
- stream << std::endl;
- writeStrings(stream);
- stream << std::endl;
-
- for (auto machine : *_machinesAll) {
- machine.second->writeBitHasAndMacro(stream);
- stream << std::endl;
- machine.second->writeBitHasAnyMacro(stream);
- stream << std::endl;
- machine.second->writeBitOrMacro(stream);
- stream << std::endl;
- machine.second->writeBitClearMacro(stream);
- stream << std::endl;
- machine.second->writeBitCopyMacro(stream);
- stream << std::endl;
- machine.second->writeBitAndMacro(stream);
- stream << std::endl;
- machine.second->writeBitAndNotMacro(stream);
- stream << std::endl;
- writeTypeDefs(stream);
- stream << std::endl;
-
- }
-
- writeCommonTypeDefs(stream);
- stream << std::endl;
-
- for (auto machine : *_machinesAll) {
- machine.second->writeVariables(stream);
- stream << std::endl;
- }
- writeCommonVariables(stream);
- stream << std::endl;
-
- if (_analyzer->usesComplexEventStruct()) {
- if (_analyzer->usesEventField("delay")) {
- writeInsertWithDelay(stream);
- stream << std::endl;
- }
- writeAdvanceTime(stream);
- stream << std::endl;
- writeScheduleMachines(stream);
- stream << std::endl;
- writeRescheduleProcess(stream);
- stream << std::endl;
- writeDetermineShortestDelay(stream);
- stream << std::endl;
- }
-
- if (_machinesAll->size() > 1) {
- writeRemovePendingEventsFromInvoker(stream);
- stream << std::endl;
- }
-
- writeCancelEvents(stream);
- stream << std::endl;
-
- for (auto machine : *_machinesAll) {
- machine.second->writeFSM(stream);
- stream << std::endl;
- }
+ stream << std::endl;
+ writeStrings(stream);
+ stream << std::endl;
+
+ for (auto machine : *_machinesAll) {
+ machine.second->writeBitHasAndMacro(stream);
+ stream << std::endl;
+ machine.second->writeBitHasAnyMacro(stream);
+ stream << std::endl;
+ machine.second->writeBitOrMacro(stream);
+ stream << std::endl;
+ machine.second->writeBitClearMacro(stream);
+ stream << std::endl;
+ machine.second->writeBitCopyMacro(stream);
+ stream << std::endl;
+ machine.second->writeBitAndMacro(stream);
+ stream << std::endl;
+ machine.second->writeBitAndNotMacro(stream);
+ stream << std::endl;
+ writeTypeDefs(stream);
+ stream << std::endl;
+
+ }
+
+ writeCommonTypeDefs(stream);
+ stream << std::endl;
+
+ for (auto machine : *_machinesAll) {
+ machine.second->writeVariables(stream);
+ stream << std::endl;
+ }
+ writeCommonVariables(stream);
+ stream << std::endl;
+
+ if (_analyzer->usesComplexEventStruct()) {
+ if (_analyzer->usesEventField("delay")) {
+ writeInsertWithDelay(stream);
+ stream << std::endl;
+ }
+ writeAdvanceTime(stream);
+ stream << std::endl;
+ writeScheduleMachines(stream);
+ stream << std::endl;
+ writeRescheduleProcess(stream);
+ stream << std::endl;
+ writeDetermineShortestDelay(stream);
+ stream << std::endl;
+ }
+
+ if (_machinesAll->size() > 1) {
+ writeRemovePendingEventsFromInvoker(stream);
+ stream << std::endl;
+ }
+
+ writeCancelEvents(stream);
+ stream << std::endl;
+
+ for (auto machine : *_machinesAll) {
+ machine.second->writeFSM(stream);
+ stream << std::endl;
+ }
stream << "init {" << std::endl;
-
- stream << "/* initialize state and transition information */" << std::endl;
- for (auto machine : *_machinesAll) {
- machine.second->writeTransitions(stream);
- stream << std::endl;
- machine.second->writeStates(stream);
- stream << std::endl;
-
- stream << "/* initialize data model variables */" << std::endl;
- stream << " " << machine.second->_prefix << "flags[USCXML_CTX_PRISTINE] = true;" << std::endl;
- stream << " " << machine.second->_prefix << "flags[USCXML_CTX_SPONTANEOUS] = true;" << std::endl;
-
- for (auto initializer : machine.second->_varInitializers) {
- stream << _analyzer->adaptCode(beautifyIndentation(initializer, 1), machine.second->_prefix) << std::endl;
- }
- }
-
- stream << std::endl;
+
+ stream << "/* initialize state and transition information */" << std::endl;
+ for (auto machine : *_machinesAll) {
+ machine.second->writeTransitions(stream);
+ stream << std::endl;
+ machine.second->writeStates(stream);
+ stream << std::endl;
+
+ stream << "/* initialize data model variables */" << std::endl;
+ stream << " " << machine.second->_prefix << "flags[USCXML_CTX_PRISTINE] = true;" << std::endl;
+ stream << " " << machine.second->_prefix << "flags[USCXML_CTX_SPONTANEOUS] = true;" << std::endl;
+
+ for (auto initializer : machine.second->_varInitializers) {
+ stream << _analyzer->adaptCode(beautifyIndentation(initializer, 1), machine.second->_prefix) << std::endl;
+ }
+ }
+
+ stream << std::endl;
stream << " run " << _prefix << "step() priority 10;" << std::endl;
stream << "}" << std::endl;
@@ -315,128 +315,128 @@ void ChartToPromela::writeTo(std::ostream& stream) {
}
void ChartToPromela::writeBitAndMacro(std::ostream& stream) {
- stream << "/** and'ing bits in a with mask */" << std::endl;
- stream << "#define " << _prefix << "TRANS_AND(a, mask) \\" << std::endl;
- for (size_t i = 0; i < _transitions.size(); i++) {
- stream << "a[" << i << "] = a[" << i << "] & mask[" << i << "]; \\" << std::endl;
- }
- stream << std::endl;
-
- stream << "#define " << _prefix << "STATES_AND(a, mask) \\" << std::endl;
- for (size_t i = 0; i < _states.size(); i++) {
- stream << "a[" << i << "] = a[" << i << "] & mask[" << i << "]; \\" << std::endl;
- }
- stream << std::endl;
+ stream << "/** and'ing bits in a with mask */" << std::endl;
+ stream << "#define " << _prefix << "TRANS_AND(a, mask) \\" << std::endl;
+ for (size_t i = 0; i < _transitions.size(); i++) {
+ stream << "a[" << i << "] = a[" << i << "] & mask[" << i << "]; \\" << std::endl;
+ }
+ stream << std::endl;
+
+ stream << "#define " << _prefix << "STATES_AND(a, mask) \\" << std::endl;
+ for (size_t i = 0; i < _states.size(); i++) {
+ stream << "a[" << i << "] = a[" << i << "] & mask[" << i << "]; \\" << std::endl;
+ }
+ stream << std::endl;
}
void ChartToPromela::writeBitAndNotMacro(std::ostream& stream) {
- stream << "/** not and'ing bits in a with mask */" << std::endl;
- stream << "#define " << _prefix << "TRANS_AND_NOT(a, mask) \\" << std::endl;
- for (size_t i = 0; i < _transitions.size(); i++) {
- stream << "a[" << i << "] = a[" << i << "] & !mask[" << i << "]; \\" << std::endl;
- }
- stream << std::endl;
-
- stream << "#define " << _prefix << "STATES_AND_NOT(a, mask) \\" << std::endl;
- for (size_t i = 0; i < _states.size(); i++) {
- stream << "a[" << i << "] = a[" << i << "] & !mask[" << i << "]; \\" << std::endl;
- }
- stream << std::endl;
-
+ stream << "/** not and'ing bits in a with mask */" << std::endl;
+ stream << "#define " << _prefix << "TRANS_AND_NOT(a, mask) \\" << std::endl;
+ for (size_t i = 0; i < _transitions.size(); i++) {
+ stream << "a[" << i << "] = a[" << i << "] & !mask[" << i << "]; \\" << std::endl;
+ }
+ stream << std::endl;
+
+ stream << "#define " << _prefix << "STATES_AND_NOT(a, mask) \\" << std::endl;
+ for (size_t i = 0; i < _states.size(); i++) {
+ stream << "a[" << i << "] = a[" << i << "] & !mask[" << i << "]; \\" << std::endl;
+ }
+ stream << std::endl;
+
}
void ChartToPromela::writeBitCopyMacro(std::ostream& stream) {
- stream << "/** copy bits from a to b */" << std::endl;
- stream << "#define " << _prefix << "TRANS_COPY(a, b) \\" << std::endl;
- for (size_t i = 0; i < _transitions.size(); i++) {
- stream << "a[" << i << "] = b[" << i << "]; \\" << std::endl;
- }
- stream << std::endl;
-
- stream << "#define " << _prefix << "STATES_COPY(a, b) \\" << std::endl;
- for (size_t i = 0; i < _states.size(); i++) {
- stream << "a[" << i << "] = b[" << i << "]; \\" << std::endl;
- }
- stream << std::endl;
-
-
+ stream << "/** copy bits from a to b */" << std::endl;
+ stream << "#define " << _prefix << "TRANS_COPY(a, b) \\" << std::endl;
+ for (size_t i = 0; i < _transitions.size(); i++) {
+ stream << "a[" << i << "] = b[" << i << "]; \\" << std::endl;
+ }
+ stream << std::endl;
+
+ stream << "#define " << _prefix << "STATES_COPY(a, b) \\" << std::endl;
+ for (size_t i = 0; i < _states.size(); i++) {
+ stream << "a[" << i << "] = b[" << i << "]; \\" << std::endl;
+ }
+ stream << std::endl;
+
+
}
-
+
void ChartToPromela::writeBitHasAndMacro(std::ostream& stream) {
- stream << "/** is there a common bit in t1 and t2 */" << std::endl;
- stream << "#define " << _prefix << "TRANS_HAS_AND(a, b) \\" << std::endl;
-
+ stream << "/** is there a common bit in t1 and t2 */" << std::endl;
+ stream << "#define " << _prefix << "TRANS_HAS_AND(a, b) \\" << std::endl;
+
stream << "(false \\" << std::endl;
for (size_t i = 0; i < _transitions.size(); i++) {
stream << " || a[" << i << "] & b[" << i << "] \\" << std::endl;
}
stream << ")" << std::endl;
- stream << std::endl;
+ stream << std::endl;
- stream << "#define " << _prefix << "STATES_HAS_AND(a, b) \\" << std::endl;
-
- stream << "(false \\" << std::endl;
- for (size_t i = 0; i < _states.size(); i++) {
- stream << " || a[" << i << "] & b[" << i << "] \\" << std::endl;
- }
- stream << ")" << std::endl;
- stream << std::endl;
+ stream << "#define " << _prefix << "STATES_HAS_AND(a, b) \\" << std::endl;
+
+ stream << "(false \\" << std::endl;
+ for (size_t i = 0; i < _states.size(); i++) {
+ stream << " || a[" << i << "] & b[" << i << "] \\" << std::endl;
+ }
+ stream << ")" << std::endl;
+ stream << std::endl;
}
void ChartToPromela::writeBitHasAnyMacro(std::ostream& stream) {
- stream << "/** is there bit set in a */" << std::endl;
- stream << "#define " << _prefix << "TRANS_HAS_ANY(a) \\" << std::endl;
-
- stream << "(false \\" << std::endl;
- for (size_t i = 0; i < _transitions.size(); i++) {
- stream << " || a[" << i << "] \\" << std::endl;
- }
- stream << ")" << std::endl;
- stream << std::endl;
-
- stream << "#define " << _prefix << "STATES_HAS_ANY(a) \\" << std::endl;
-
- stream << "(false \\" << std::endl;
- for (size_t i = 0; i < _states.size(); i++) {
- stream << " || a[" << i << "] \\" << std::endl;
- }
- stream << ")" << std::endl;
- stream << std::endl;
-
+ stream << "/** is there bit set in a */" << std::endl;
+ stream << "#define " << _prefix << "TRANS_HAS_ANY(a) \\" << std::endl;
+
+ stream << "(false \\" << std::endl;
+ for (size_t i = 0; i < _transitions.size(); i++) {
+ stream << " || a[" << i << "] \\" << std::endl;
+ }
+ stream << ")" << std::endl;
+ stream << std::endl;
+
+ stream << "#define " << _prefix << "STATES_HAS_ANY(a) \\" << std::endl;
+
+ stream << "(false \\" << std::endl;
+ for (size_t i = 0; i < _states.size(); i++) {
+ stream << " || a[" << i << "] \\" << std::endl;
+ }
+ stream << ")" << std::endl;
+ stream << std::endl;
+
}
void ChartToPromela::writeBitOrMacro(std::ostream& stream) {
- stream << "/** or'ing bits in a with mask */" << std::endl;
- stream << "#define " << _prefix << "TRANS_OR(a, mask) \\" << std::endl;
- for (size_t i = 0; i < _transitions.size(); i++) {
- stream << "a[" << i << "] = a[" << i << "] | mask[" << i << "]; \\" << std::endl;
- }
- stream << std::endl;
-
- stream << "#define " << _prefix << "STATES_OR(a, mask) \\" << std::endl;
- for (size_t i = 0; i < _states.size(); i++) {
- stream << "a[" << i << "] = a[" << i << "] | mask[" << i << "]; \\" << std::endl;
- }
- stream << std::endl;
+ stream << "/** or'ing bits in a with mask */" << std::endl;
+ stream << "#define " << _prefix << "TRANS_OR(a, mask) \\" << std::endl;
+ for (size_t i = 0; i < _transitions.size(); i++) {
+ stream << "a[" << i << "] = a[" << i << "] | mask[" << i << "]; \\" << std::endl;
+ }
+ stream << std::endl;
+
+ stream << "#define " << _prefix << "STATES_OR(a, mask) \\" << std::endl;
+ for (size_t i = 0; i < _states.size(); i++) {
+ stream << "a[" << i << "] = a[" << i << "] | mask[" << i << "]; \\" << std::endl;
+ }
+ stream << std::endl;
}
void ChartToPromela::writeBitClearMacro(std::ostream& stream) {
- stream << "/** clearing all bits of a */" << std::endl;
- stream << "#define " << _prefix << "TRANS_CLEAR(a) \\" << std::endl;
- for (size_t i = 0; i < _transitions.size(); i++) {
- stream << "a[" << i << "] = false; \\" << std::endl;
- }
- stream << std::endl;
-
- stream << "#define " << _prefix << "STATES_CLEAR(a) \\" << std::endl;
- for (size_t i = 0; i < _states.size(); i++) {
- stream << "a[" << i << "] = false; \\" << std::endl;
- }
- stream << std::endl;
-
+ stream << "/** clearing all bits of a */" << std::endl;
+ stream << "#define " << _prefix << "TRANS_CLEAR(a) \\" << std::endl;
+ for (size_t i = 0; i < _transitions.size(); i++) {
+ stream << "a[" << i << "] = false; \\" << std::endl;
+ }
+ stream << std::endl;
+
+ stream << "#define " << _prefix << "STATES_CLEAR(a) \\" << std::endl;
+ for (size_t i = 0; i < _states.size(); i++) {
+ stream << "a[" << i << "] = false; \\" << std::endl;
+ }
+ stream << std::endl;
+
}
void ChartToPromela::printBitArray(std::ostream& stream,
@@ -467,8 +467,8 @@ void ChartToPromela::writeMacros(std::ostream& stream) {
stream << "#define USCXML_CTX_SPONTANEOUS 1" << std::endl;
stream << "#define USCXML_CTX_TOP_LEVEL_FINAL 2" << std::endl;
stream << "#define USCXML_CTX_TRANSITION_FOUND 3" << std::endl;
- stream << "#define USCXML_CTX_FINISHED 4" << std::endl;
- stream << "#define USCXML_CTX_DEQUEUE_EXTERNAL 5" << std::endl;
+ stream << "#define USCXML_CTX_FINISHED 4" << std::endl;
+ stream << "#define USCXML_CTX_DEQUEUE_EXTERNAL 5" << std::endl;
stream << std::endl;
stream << "#define USCXML_TRANS_SPONTANEOUS 0" << std::endl;
@@ -500,105 +500,105 @@ void ChartToPromela::writeMacros(std::ostream& stream) {
}
void ChartToPromela::writeCommonTypeDefs(std::ostream& stream) {
- stream << "/* common type definitions */" << std::endl;
- PromelaCodeAnalyzer::PromelaTypedef typeDefs = _analyzer->getTypes();
- if (typeDefs.types.size() == 0)
- return;
-
- std::list<PromelaCodeAnalyzer::PromelaTypedef> individualDefs;
- std::list<PromelaCodeAnalyzer::PromelaTypedef> currDefs;
- currDefs.push_back(typeDefs);
-
- while(currDefs.size() > 0) {
- if (std::find(individualDefs.begin(), individualDefs.end(), currDefs.front()) == individualDefs.end()) {
- individualDefs.push_back(currDefs.front());
- for (std::map<std::string, PromelaCodeAnalyzer::PromelaTypedef>::iterator typeIter = currDefs.front().types.begin(); typeIter != currDefs.front().types.end(); typeIter++) {
- currDefs.push_back(typeIter->second);
- }
- }
- currDefs.pop_front();
- }
- individualDefs.pop_front();
-
- for (std::list<PromelaCodeAnalyzer::PromelaTypedef>::reverse_iterator rIter = individualDefs.rbegin(); rIter != individualDefs.rend(); rIter++) {
- PromelaCodeAnalyzer::PromelaTypedef currDef = *rIter;
-
- if (currDef.types.size() == 0 || currDef.name.size() == 0)
- continue;
-
- stream << "typedef " << currDef.name << " {" << std::endl;
- if (currDef.name.compare("_event_t") ==0) {
- if (_analyzer->usesEventField("delay")) {
- // make sure delay is the first member for sorted enqueuing to work
- stream << " " << declForRange("delay", 0, _analyzer->largestDelay, true) << ";" << std::endl;
+ stream << "/* common type definitions */" << std::endl;
+ PromelaCodeAnalyzer::PromelaTypedef typeDefs = _analyzer->getTypes();
+ if (typeDefs.types.size() == 0)
+ return;
+
+ std::list<PromelaCodeAnalyzer::PromelaTypedef> individualDefs;
+ std::list<PromelaCodeAnalyzer::PromelaTypedef> currDefs;
+ currDefs.push_back(typeDefs);
+
+ while(currDefs.size() > 0) {
+ if (std::find(individualDefs.begin(), individualDefs.end(), currDefs.front()) == individualDefs.end()) {
+ individualDefs.push_back(currDefs.front());
+ for (std::map<std::string, PromelaCodeAnalyzer::PromelaTypedef>::iterator typeIter = currDefs.front().types.begin(); typeIter != currDefs.front().types.end(); typeIter++) {
+ currDefs.push_back(typeIter->second);
+ }
+ }
+ currDefs.pop_front();
+ }
+ individualDefs.pop_front();
+
+ for (std::list<PromelaCodeAnalyzer::PromelaTypedef>::reverse_iterator rIter = individualDefs.rbegin(); rIter != individualDefs.rend(); rIter++) {
+ PromelaCodeAnalyzer::PromelaTypedef currDef = *rIter;
+
+ if (currDef.types.size() == 0 || currDef.name.size() == 0)
+ continue;
+
+ stream << "typedef " << currDef.name << " {" << std::endl;
+ if (currDef.name.compare("_event_t") ==0) {
+ if (_analyzer->usesEventField("delay")) {
+ // make sure delay is the first member for sorted enqueuing to work
+ stream << " " << declForRange("delay", 0, _analyzer->largestDelay, true) << ";" << std::endl;
#if NEW_DELAY_RESHUFFLE
#else
- stream << " short seqNr;" << std::endl;
+ stream << " short seqNr;" << std::endl;
#endif
- }
- stream << " " << declForRange("name", 0, _analyzer->getTrie().lastIndex, true) << ";" << std::endl;
- if (_analyzer->usesEventField("invokeid")) {
- stream << " " << declForRange("invokeid", 0, _machinesAll->size() + 1, true) << ";" << std::endl;
- }
- if (_analyzer->usesEventField("origin")) {
- stream << " " << declForRange("origin", 0, _machinesAll->size() + 1, true) << ";" << std::endl;
- }
- }
- for (std::map<std::string, PromelaCodeAnalyzer::PromelaTypedef>::iterator tIter = currDef.types.begin(); tIter != currDef.types.end(); tIter++) {
- if (currDef.name.compare("_event_t") == 0 && (tIter->first.compare("name") == 0 ||
- tIter->first.compare("seqNr") == 0 ||
- tIter->first.compare("invokeid") == 0 ||
- tIter->first.compare("origin") == 0 ||
- tIter->first.compare("delay") == 0)) { // special treatment for _event
- continue;
- }
- if (tIter->second.types.size() == 0) {
- stream << " " << declForRange(tIter->first, tIter->second.minValue, tIter->second.maxValue, true) << ";" << std::endl; // not further nested
- // stream << " int " << tIter->first << ";" << std::endl; // not further nested
- } else {
- stream << " " << tIter->second.name << " " << tIter->first << ";" << std::endl;
- }
- }
- stream << "};" << std::endl << std::endl;
- }
-
- // stream << "/* typedef instances */" << std::endl;
- // PromelaCodeAnalyzer::PromelaTypedef allTypes = _analyzer->getTypes();
- // std::map<std::string, PromelaCodeAnalyzer::PromelaTypedef>::iterator typeIter = allTypes.types.begin();
- // while(typeIter != allTypes.types.end()) {
- // if (typeIter->second.types.size() > 0) {
- // // an actual typedef
- // stream << "hidden " << typeIter->second.name << " " << typeIter->first << ";" << std::endl;
- // } else {
- // stream << "hidden " << declForRange(typeIter->first, typeIter->second.minValue, typeIter->second.maxValue) << ";" << std::endl;
- // }
- // typeIter++;
- // }
-
+ }
+ stream << " " << declForRange("name", 0, _analyzer->getTrie().lastIndex, true) << ";" << std::endl;
+ if (_analyzer->usesEventField("invokeid")) {
+ stream << " " << declForRange("invokeid", 0, _machinesAll->size() + 1, true) << ";" << std::endl;
+ }
+ if (_analyzer->usesEventField("origin")) {
+ stream << " " << declForRange("origin", 0, _machinesAll->size() + 1, true) << ";" << std::endl;
+ }
+ }
+ for (std::map<std::string, PromelaCodeAnalyzer::PromelaTypedef>::iterator tIter = currDef.types.begin(); tIter != currDef.types.end(); tIter++) {
+ if (currDef.name.compare("_event_t") == 0 && (tIter->first.compare("name") == 0 ||
+ tIter->first.compare("seqNr") == 0 ||
+ tIter->first.compare("invokeid") == 0 ||
+ tIter->first.compare("origin") == 0 ||
+ tIter->first.compare("delay") == 0)) { // special treatment for _event
+ continue;
+ }
+ if (tIter->second.types.size() == 0) {
+ stream << " " << declForRange(tIter->first, tIter->second.minValue, tIter->second.maxValue, true) << ";" << std::endl; // not further nested
+ // stream << " int " << tIter->first << ";" << std::endl; // not further nested
+ } else {
+ stream << " " << tIter->second.name << " " << tIter->first << ";" << std::endl;
+ }
+ }
+ stream << "};" << std::endl << std::endl;
+ }
+
+ // stream << "/* typedef instances */" << std::endl;
+ // PromelaCodeAnalyzer::PromelaTypedef allTypes = _analyzer->getTypes();
+ // std::map<std::string, PromelaCodeAnalyzer::PromelaTypedef>::iterator typeIter = allTypes.types.begin();
+ // while(typeIter != allTypes.types.end()) {
+ // if (typeIter->second.types.size() > 0) {
+ // // an actual typedef
+ // stream << "hidden " << typeIter->second.name << " " << typeIter->first << ";" << std::endl;
+ // } else {
+ // stream << "hidden " << declForRange(typeIter->first, typeIter->second.minValue, typeIter->second.maxValue) << ";" << std::endl;
+ // }
+ // typeIter++;
+ // }
+
}
void ChartToPromela::writeTypeDefs(std::ostream& stream) {
- stream << "/* custom type definitions for " << _prefix << " */" << std::endl;
+ stream << "/* custom type definitions for " << _prefix << " */" << std::endl;
}
void ChartToPromela::writeCommonVariables(std::ostream& stream) {
- stream << "hidden int tmpIndex;" << std::endl;
- if (_analyzer->usesComplexEventStruct()) {
- stream << "hidden _event_t tmpE;" << std::endl;
- } else {
- stream << "hidden int tmpE;" << std::endl;
- }
-
- if (_analyzer->hasIndexLessLoops())
- stream << "hidden int _index; /* helper for indexless foreach loops */" << std::endl;
-
- if (_analyzer->usesEventField("sendid"))
- stream << "hidden int _lastSendId = 0; /* sequential counter for send ids */" << std::endl;
-
- if (_analyzer->usesEventField("delay"))
- stream << "hidden short _lastSeqId = 0; /* sequential counter for delayed events */" << std::endl;
- stream << std::endl;
+ stream << "hidden int tmpIndex;" << std::endl;
+ if (_analyzer->usesComplexEventStruct()) {
+ stream << "hidden _event_t tmpE;" << std::endl;
+ } else {
+ stream << "hidden int tmpE;" << std::endl;
+ }
+
+ if (_analyzer->hasIndexLessLoops())
+ stream << "hidden int _index; /* helper for indexless foreach loops */" << std::endl;
+
+ if (_analyzer->usesEventField("sendid"))
+ stream << "hidden int _lastSendId = 0; /* sequential counter for send ids */" << std::endl;
+
+ if (_analyzer->usesEventField("delay"))
+ stream << "hidden short _lastSeqId = 0; /* sequential counter for delayed events */" << std::endl;
+ stream << std::endl;
}
@@ -609,65 +609,65 @@ void ChartToPromela::writeVariables(std::ostream& stream) {
stream << "bool " << _prefix << "history[" << _states.size() << "];" << std::endl;
stream << "bool " << _prefix << "invocations[" << _states.size() << "];" << std::endl;
// stream << "bool " << _prefix << "initialized_data[" << _states.size() << "];" << std::endl;
-
- size_t tolerance = 6;
-
- if (_analyzer->usesComplexEventStruct()) {
- // event is defined with the typedefs
- stream << "hidden _event_t " << _prefix << "_event; /* current event */" << std::endl;
- stream << "hidden _event_t " << _prefix << "_tmpE; /* temporary event for send */" << std::endl;
- stream << "chan " << _prefix << "iQ = [" << (std::max)(_internalQueueLength, (size_t)1) << "] of {_event_t} /* internal queue */" << std::endl;
- stream << "chan " << _prefix << "eQ = [" << _externalQueueLength + tolerance << "] of {_event_t} /* external queue */" << std::endl;
- if (_allowEventInterleaving)
- stream << "chan " << _prefix << "tmpQ = [" << (std::max)(_externalQueueLength + tolerance, (size_t)1) << "] of {_event_t} /* temporary queue for external events in transitions */" << std::endl;
- } else {
- stream << "unsigned " << _prefix << "_event : " << BIT_WIDTH(_analyzer->getLiterals().size() + 1) << "; /* current event */" << std::endl;
- stream << "hidden unsigned " << _prefix << "_tmpE : " << BIT_WIDTH(_analyzer->getLiterals().size() + 1) << "; /* temporary event for send */" << std::endl;
- stream << "chan " << _prefix << "iQ = [" << (std::max)(_internalQueueLength, (size_t)1) << "] of {int} /* internal queue */" << std::endl;
- stream << "chan " << _prefix << "eQ = [" << _externalQueueLength + tolerance << "] of {int} /* external queue */" << std::endl;
- if (_allowEventInterleaving)
- stream << "chan " << _prefix << "tmpQ = [" << (std::max)(_externalQueueLength + tolerance, (size_t)1) << "] of {int} /* temporary queue for external events in transitions */" << std::endl;
- }
-
- if (_transitions.size() > 0) {
- stream << std::endl;
- stream << "typedef " << _prefix << "transition_t {" << std::endl;
- stream << " unsigned source : " << BIT_WIDTH(_states.size()) << ";" << std::endl;
- stream << " bool target[" << _states.size() << "];" << std::endl;
- stream << " bool type[5];" << std::endl;
- stream << " bool conflicts[" << _transitions.size() << "];" << std::endl;
- stream << " bool exit_set[" << _states.size() << "];" << std::endl;
- stream << "}" << std::endl;
+
+ size_t tolerance = 6;
+
+ if (_analyzer->usesComplexEventStruct()) {
+ // event is defined with the typedefs
+ stream << "hidden _event_t " << _prefix << "_event; /* current event */" << std::endl;
+ stream << "hidden _event_t " << _prefix << "_tmpE; /* temporary event for send */" << std::endl;
+ stream << "chan " << _prefix << "iQ = [" << (std::max)(_internalQueueLength, (size_t)1) << "] of {_event_t} /* internal queue */" << std::endl;
+ stream << "chan " << _prefix << "eQ = [" << _externalQueueLength + tolerance << "] of {_event_t} /* external queue */" << std::endl;
+ if (_allowEventInterleaving)
+ stream << "chan " << _prefix << "tmpQ = [" << (std::max)(_externalQueueLength + tolerance, (size_t)1) << "] of {_event_t} /* temporary queue for external events in transitions */" << std::endl;
+ } else {
+ stream << "unsigned " << _prefix << "_event : " << BIT_WIDTH(_analyzer->getLiterals().size() + 1) << "; /* current event */" << std::endl;
+ stream << "hidden unsigned " << _prefix << "_tmpE : " << BIT_WIDTH(_analyzer->getLiterals().size() + 1) << "; /* temporary event for send */" << std::endl;
+ stream << "chan " << _prefix << "iQ = [" << (std::max)(_internalQueueLength, (size_t)1) << "] of {int} /* internal queue */" << std::endl;
+ stream << "chan " << _prefix << "eQ = [" << _externalQueueLength + tolerance << "] of {int} /* external queue */" << std::endl;
+ if (_allowEventInterleaving)
+ stream << "chan " << _prefix << "tmpQ = [" << (std::max)(_externalQueueLength + tolerance, (size_t)1) << "] of {int} /* temporary queue for external events in transitions */" << std::endl;
+ }
+
+ if (_transitions.size() > 0) {
+ stream << std::endl;
+ stream << "typedef " << _prefix << "transition_t {" << std::endl;
+ stream << " unsigned source : " << BIT_WIDTH(_states.size()) << ";" << std::endl;
+ stream << " bool target[" << _states.size() << "];" << std::endl;
+ stream << " bool type[5];" << std::endl;
+ stream << " bool conflicts[" << _transitions.size() << "];" << std::endl;
+ stream << " bool exit_set[" << _states.size() << "];" << std::endl;
+ stream << "}" << std::endl;
stream << "hidden " << _prefix << "transition_t " << _prefix << "transitions[" << toStr(_transitions.size()) << "];" << std::endl;
- stream << std::endl;
+ stream << std::endl;
}
- if (_states.size() > 0) {
- stream << "typedef " << _prefix << "state_t {" << std::endl;
- stream << " unsigned parent : " << BIT_WIDTH(_states.size()) << ";" << std::endl;
- stream << " bool children[" << _states.size() << "];" << std::endl;
- stream << " bool completion[" << _states.size() << "];" << std::endl;
- stream << " bool ancestors[" << _states.size() << "];" << std::endl;
- stream << " bool type[8];" << std::endl;
- stream << "}" << std::endl;
+ if (_states.size() > 0) {
+ stream << "typedef " << _prefix << "state_t {" << std::endl;
+ stream << " unsigned parent : " << BIT_WIDTH(_states.size()) << ";" << std::endl;
+ stream << " bool children[" << _states.size() << "];" << std::endl;
+ stream << " bool completion[" << _states.size() << "];" << std::endl;
+ stream << " bool ancestors[" << _states.size() << "];" << std::endl;
+ stream << " bool type[8];" << std::endl;
+ stream << "}" << std::endl;
stream << "hidden " << _prefix << "state_t " << _prefix << "states[" << toStr(_states.size()) << "];" << std::endl;
- stream << std::endl;
- }
-
- stream << "typedef " << _prefix << "ctx_t {" << std::endl;
- if (_transitions.size() > 0) {
- stream << " bool conflicts[" << _transitions.size() << "];" << std::endl;
- stream << " bool trans_set[" << _transitions.size() << "];" << std::endl;
- }
-
- stream << " bool target_set[" << _states.size() << "];" << std::endl;
- stream << " bool exit_set[" << _states.size() << "];" << std::endl;
- stream << " bool entry_set[" << _states.size() << "];" << std::endl;
- stream << " bool tmp_states[" << _states.size() << "];" << std::endl;
- stream << "}" << std::endl;
- stream << "hidden " << _prefix << "ctx_t " << _prefix << "ctx;" << std::endl;
- stream << std::endl;
- stream << std::endl;
+ stream << std::endl;
+ }
+
+ stream << "typedef " << _prefix << "ctx_t {" << std::endl;
+ if (_transitions.size() > 0) {
+ stream << " bool conflicts[" << _transitions.size() << "];" << std::endl;
+ stream << " bool trans_set[" << _transitions.size() << "];" << std::endl;
+ }
+
+ stream << " bool target_set[" << _states.size() << "];" << std::endl;
+ stream << " bool exit_set[" << _states.size() << "];" << std::endl;
+ stream << " bool entry_set[" << _states.size() << "];" << std::endl;
+ stream << " bool tmp_states[" << _states.size() << "];" << std::endl;
+ stream << "}" << std::endl;
+ stream << "hidden " << _prefix << "ctx_t " << _prefix << "ctx;" << std::endl;
+ stream << std::endl;
+ stream << std::endl;
std::set<std::string> processedIdentifiers;
@@ -723,12 +723,12 @@ void ChartToPromela::writeVariables(std::ostream& stream) {
}
if (typeIter->first == "_event"
- || typeIter->first == "config"
- || typeIter->first == "_ioprocessors"
- || typeIter->first == "_SESSIONID"
- || typeIter->first == "_NAME"
- || !std::any_of(typeIter->first.begin(), typeIter->first.end(), ::islower)
- ) {
+ || typeIter->first == "config"
+ || typeIter->first == "_ioprocessors"
+ || typeIter->first == "_SESSIONID"
+ || typeIter->first == "_NAME"
+ || !std::any_of(typeIter->first.begin(), typeIter->first.end(), ::islower)
+ ) {
typeIter++;
continue;
}
@@ -743,41 +743,41 @@ void ChartToPromela::writeVariables(std::ostream& stream) {
typeIter++;
}
- if (_analyzer->getTypes().types.find("_ioprocessors") != _analyzer->getTypes().types.end()) {
- stream << "hidden _ioprocessors_t " << _prefix << "_ioprocessors;" << std::endl;
- _varInitializers.push_front("_ioprocessors.scxml.location = " + (_invokerid.size() > 0 ? _analyzer->macroForLiteral(_invokerid) : "1") + ";");
- }
+ if (_analyzer->getTypes().types.find("_ioprocessors") != _analyzer->getTypes().types.end()) {
+ stream << "hidden _ioprocessors_t " << _prefix << "_ioprocessors;" << std::endl;
+ _varInitializers.push_front("_ioprocessors.scxml.location = " + (_invokerid.size() > 0 ? _analyzer->macroForLiteral(_invokerid) : "1") + ";");
+ }
- stream << "hidden int " << _prefix << "procid; /* the process id running this machine */" << std::endl;
+ stream << "hidden int " << _prefix << "procid; /* the process id running this machine */" << std::endl;
}
-
+
void ChartToPromela::writeStrings(std::ostream& stream) {
- stream << "/* states, events and string literals */" << std::endl;
- std::set<std::string> literals = _analyzer->getLiterals();
-
- {
- for (size_t i = 0; i < _states.size(); i++) {
- if (HAS_ATTR(_states[i], "id")) {
- stream << "#define " << _prefix << _analyzer->macroForLiteral(ATTR(_states[i], "id")) << " " << toStr(i);
- stream << " /* index for state " << ATTR(_states[i], "id") << " */" << std::endl;
- }
- }
- }
-
- {
- size_t i = 0;
- for (auto machine : *_machinesAll) {
- i++;
- stream << "#define " << _analyzer->macroForLiteral(machine.second->_invokerid) << " " << toStr(i);
- stream << " /* index for invoker " << machine.second->_invokerid << " */" << std::endl;
- }
- }
-
- for (auto literal : literals) {
- stream << "#define " << _analyzer->macroForLiteral(literal) << " " << _analyzer->indexForLiteral(literal) << " /* " << literal << " */" << std::endl;
- }
+ stream << "/* states, events and string literals */" << std::endl;
+ std::set<std::string> literals = _analyzer->getLiterals();
+
+ {
+ for (size_t i = 0; i < _states.size(); i++) {
+ if (HAS_ATTR(_states[i], "id")) {
+ stream << "#define " << _prefix << _analyzer->macroForLiteral(ATTR(_states[i], "id")) << " " << toStr(i);
+ stream << " /* index for state " << ATTR(_states[i], "id") << " */" << std::endl;
+ }
+ }
+ }
+
+ {
+ size_t i = 0;
+ for (auto machine : *_machinesAll) {
+ i++;
+ stream << "#define " << _analyzer->macroForLiteral(machine.second->_invokerid) << " " << toStr(i);
+ stream << " /* index for invoker " << machine.second->_invokerid << " */" << std::endl;
+ }
+ }
+
+ for (auto literal : literals) {
+ stream << "#define " << _analyzer->macroForLiteral(literal) << " " << _analyzer->indexForLiteral(literal) << " /* " << literal << " */" << std::endl;
+ }
}
void ChartToPromela::writeTransitions(std::ostream& stream) {
@@ -797,7 +797,7 @@ void ChartToPromela::writeTransitions(std::ostream& stream) {
stream << " " << _prefix << "transitions[" << toStr(i) << "].target[" << toStr(j) << "] = 1;" << std::endl;
}
}
-
+
if (!HAS_ATTR(transition, "event"))
stream << " " << _prefix << "transitions[" << toStr(i) << "].type[USCXML_TRANS_SPONTANEOUS] = 1;" << std::endl;
@@ -898,64 +898,64 @@ void ChartToPromela::writeStates(std::ostream& stream) {
}
void ChartToPromela::writeRaiseDoneDate(std::ostream& stream, const DOMElement* donedata, size_t indent) {
- std::string padding;
- for (size_t i = 0; i < indent; i++) {
- padding += " ";
- }
-
- std::list<DOMElement*> contents = DOMUtils::filterChildElements(XML_PREFIX(donedata).str() + "content", donedata);
- if (contents.size() > 0) {
- auto& content = contents.front();
-
- // an expression
- if (HAS_ATTR(content, "expr")) {
- stream << dataToAssignments(_prefix + "_tmpE.data", Data(ADAPT_SRC(ATTR(content, "expr")), Data::INTERPRETED));
- return;
- }
-
- std::list<DOMNode*> textChilds = DOMUtils::filterChildType(DOMNode::TEXT_NODE, content);
- std::stringstream ss;
- for (auto text : textChilds) {
- ss << X(text->getNodeValue()).str();
- }
-
- // text childs
- std::string value = boost::trim_copy(ss.str());
- if (value.size() > 0) {
- Data d = Data::fromJSON(value);
- if (!d.empty()) {
- stream << dataToAssignments(_prefix + "_tmpE.data", d);
- } else {
- if (!isNumeric(value.c_str(), 10)) {
- stream << dataToAssignments(_prefix + "_tmpE.data", Data(value, Data::VERBATIM));
- } else {
- stream << dataToAssignments(_prefix + "_tmpE.data", Data(value, Data::INTERPRETED));
- }
- }
- return;
- }
- }
-
- std::list<DOMElement*> params = DOMUtils::filterChildElements(XML_PREFIX(donedata).str() + "param", donedata);
- if (params.size() > 0) {
- Data d;
- for (auto& param : params) {
- if (!HAS_ATTR(param, "name"))
- continue;
- std::string name = ATTR(param, "name");
- std::string expr;
- if (HAS_ATTR(param, "expr")) {
- expr = ATTR(param, "expr");
- } else if (HAS_ATTR(param, "location")) {
- expr = ATTR(param, "location");
- }
-
- d[name] = Data(expr, Data::INTERPRETED);
- }
- stream << dataToAssignments(_prefix + "_tmpE.data", d);
-
- }
-
+ std::string padding;
+ for (size_t i = 0; i < indent; i++) {
+ padding += " ";
+ }
+
+ std::list<DOMElement*> contents = DOMUtils::filterChildElements(XML_PREFIX(donedata).str() + "content", donedata);
+ if (contents.size() > 0) {
+ auto& content = contents.front();
+
+ // an expression
+ if (HAS_ATTR(content, "expr")) {
+ stream << dataToAssignments(_prefix + "_tmpE.data", Data(ADAPT_SRC(ATTR(content, "expr")), Data::INTERPRETED));
+ return;
+ }
+
+ std::list<DOMNode*> textChilds = DOMUtils::filterChildType(DOMNode::TEXT_NODE, content);
+ std::stringstream ss;
+ for (auto text : textChilds) {
+ ss << X(text->getNodeValue()).str();
+ }
+
+ // text childs
+ std::string value = boost::trim_copy(ss.str());
+ if (value.size() > 0) {
+ Data d = Data::fromJSON(value);
+ if (!d.empty()) {
+ stream << dataToAssignments(_prefix + "_tmpE.data", d);
+ } else {
+ if (!isNumeric(value.c_str(), 10)) {
+ stream << dataToAssignments(_prefix + "_tmpE.data", Data(value, Data::VERBATIM));
+ } else {
+ stream << dataToAssignments(_prefix + "_tmpE.data", Data(value, Data::INTERPRETED));
+ }
+ }
+ return;
+ }
+ }
+
+ std::list<DOMElement*> params = DOMUtils::filterChildElements(XML_PREFIX(donedata).str() + "param", donedata);
+ if (params.size() > 0) {
+ Data d;
+ for (auto& param : params) {
+ if (!HAS_ATTR(param, "name"))
+ continue;
+ std::string name = ATTR(param, "name");
+ std::string expr;
+ if (HAS_ATTR(param, "expr")) {
+ expr = ATTR(param, "expr");
+ } else if (HAS_ATTR(param, "location")) {
+ expr = ATTR(param, "location");
+ }
+
+ d[name] = Data(expr, Data::INTERPRETED);
+ }
+ stream << dataToAssignments(_prefix + "_tmpE.data", d);
+
+ }
+
}
void ChartToPromela::writeExecContent(std::ostream& stream, const XERCESC_NS::DOMNode* node, size_t indent) {
@@ -1049,18 +1049,18 @@ void ChartToPromela::writeExecContent(std::ostream& stream, const XERCESC_NS::DO
writeIfBlock(stream, condChain, indent);
} else if(TAGNAME(element) == "assign") {
-
- std::list<DOMNode*> assignTexts = DOMUtils::filterChildType(DOMNode::TEXT_NODE, element, true);
- assert(assignTexts.size() > 0);
- stream << beautifyIndentation(ADAPT_SRC(boost::trim_copy(X(assignTexts.front()->getNodeValue()).str())), indent + 1) << std::endl;
-
+
+ std::list<DOMNode*> assignTexts = DOMUtils::filterChildType(DOMNode::TEXT_NODE, element, true);
+ assert(assignTexts.size() > 0);
+ stream << beautifyIndentation(ADAPT_SRC(boost::trim_copy(X(assignTexts.front()->getNodeValue()).str())), indent + 1) << std::endl;
+
} else if(TAGNAME(element) == "send" || TAGNAME(element) == "raise") {
std::string targetQueue;
-
- stream << padding << "if" << std::endl;
- stream << padding << ":: !" << _prefix << "flags[USCXML_CTX_FINISHED] || " << _prefix << "flags[USCXML_CTX_TOP_LEVEL_FINAL] -> {" << std::endl;
- padding += " ";
+ stream << padding << "if" << std::endl;
+ stream << padding << ":: !" << _prefix << "flags[USCXML_CTX_FINISHED] || " << _prefix << "flags[USCXML_CTX_TOP_LEVEL_FINAL] -> {" << std::endl;
+
+ padding += " ";
std::string insertOp = "!";
if (TAGNAME(element) == "raise") {
targetQueue = _prefix + "iQ";
@@ -1112,12 +1112,12 @@ void ChartToPromela::writeExecContent(std::ostream& stream, const XERCESC_NS::DO
if (_analyzer->usesEventField("origintype") && !boost::ends_with(targetQueue, "iQ")) {
typeAssignSS << padding << " " << _prefix << "_tmpE.origintype = " << _analyzer->macroForLiteral("http://www.w3.org/TR/scxml/#SCXMLEventProcessor") << ";" << std::endl;
}
-
- if (_analyzer->usesEventField("origin") && !boost::ends_with(targetQueue, "iQ")) {
- typeAssignSS << padding << " " << _prefix << "_tmpE.origin = " << _analyzer->macroForLiteral(_invokerid) << ";" << std::endl;
- }
- if (_analyzer->usesEventField("delay")) {
+ if (_analyzer->usesEventField("origin") && !boost::ends_with(targetQueue, "iQ")) {
+ typeAssignSS << padding << " " << _prefix << "_tmpE.origin = " << _analyzer->macroForLiteral(_invokerid) << ";" << std::endl;
+ }
+
+ if (_analyzer->usesEventField("delay")) {
#if NEW_DELAY_RESHUFFLE
#else
// insertOp += "!";
@@ -1198,14 +1198,14 @@ void ChartToPromela::writeExecContent(std::ostream& stream, const XERCESC_NS::DO
}
stream << typeAssignSS.str();
- stream << "#if TRACE_EXECUTION" << std::endl;
- if (_analyzer->usesComplexEventStruct()) {
- stream << "printf(\"%d: Sending " << event << " (%d) to " << targetQueue << "\\n\", _pid, " << _prefix << TMP_EVENT_NAME << " );" << std::endl;
- } else {
- stream << "printf(\"Sending " << event << " (%d) to " << targetQueue << "\\n\", " << _prefix << TMP_EVENT_NAME << " );" << std::endl;
- }
- stream << "#endif" << std::endl;
- stream << std::endl;
+ stream << "#if TRACE_EXECUTION" << std::endl;
+ if (_analyzer->usesComplexEventStruct()) {
+ stream << "printf(\"%d: Sending " << event << " (%d) to " << targetQueue << "\\n\", _pid, " << _prefix << TMP_EVENT_NAME << " );" << std::endl;
+ } else {
+ stream << "printf(\"Sending " << event << " (%d) to " << targetQueue << "\\n\", " << _prefix << TMP_EVENT_NAME << " );" << std::endl;
+ }
+ stream << "#endif" << std::endl;
+ stream << std::endl;
stream << padding << " " << targetQueue << insertOp << _prefix <<"_tmpE;" << std::endl;
@@ -1218,12 +1218,12 @@ void ChartToPromela::writeExecContent(std::ostream& stream, const XERCESC_NS::DO
stream << padding << targetQueue << insertOp << event << ";" << std::endl;
}
}
- stream << padding << "skip;" << std::endl;
+ stream << padding << "skip;" << std::endl;
- padding = padding.substr(0, padding.size() - 2);
- stream << padding << "}" << std::endl;
- stream << padding << ":: else -> skip;" << std::endl;
- stream << padding << "fi" << std::endl;
+ padding = padding.substr(0, padding.size() - 2);
+ stream << padding << "}" << std::endl;
+ stream << padding << ":: else -> skip;" << std::endl;
+ stream << padding << "fi" << std::endl;
} else if(TAGNAME(element) == "cancel") {
if (HAS_ATTR(element, "sendid")) {
@@ -1243,97 +1243,97 @@ void ChartToPromela::writeFSM(std::ostream& stream) {
stream << "/* machine microstep function */" << std::endl;
stream << "#define " << _prefix << "USCXML_NUMBER_STATES " << _states.size() << std::endl;
stream << "#define " << _prefix << "USCXML_NUMBER_TRANS " << _transitions.size() << std::endl;
- stream << std::endl;
+ stream << std::endl;
stream << "proctype " << _prefix << "step() { atomic {" << std::endl;
- stream << std::endl;
- stream << _prefix << "procid = _pid;" << std::endl;
-
- size_t largestBitWidth = (_states.size() > _transitions.size() ?
- BIT_WIDTH(_states.size() + 1) :
- BIT_WIDTH(_transitions.size() + 1));
-
- stream << "unsigned";
- stream << " i : " << largestBitWidth << ", ";
- stream << " j : " << largestBitWidth << ", ";
- stream << " k : " << largestBitWidth << ";" << std::endl;
- stream << std::endl;
-
- std::list<DOMElement*> globalScripts = DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "script", _scxml, false);
- if (globalScripts.size() > 0) {
- stream << "/* run global scripts */" << std::endl;
- stream << "d_step { " << std::endl;
-
- for (auto globalScript : globalScripts) {
- TRACE_EXECUTION("Processing executable content for global script");
-
- writeExecContent(stream, globalScript, 2);
- }
- stream << "} /* d_step */" << std::endl;
- stream << std::endl;
- }
-
- stream << std::endl;
- stream << "/* ---------------------------- */" << std::endl;
- stream << _prefix << "MICROSTEP:" << std::endl;
+ stream << std::endl;
+ stream << _prefix << "procid = _pid;" << std::endl;
+
+ size_t largestBitWidth = (_states.size() > _transitions.size() ?
+ BIT_WIDTH(_states.size() + 1) :
+ BIT_WIDTH(_transitions.size() + 1));
+
+ stream << "unsigned";
+ stream << " i : " << largestBitWidth << ", ";
+ stream << " j : " << largestBitWidth << ", ";
+ stream << " k : " << largestBitWidth << ";" << std::endl;
+ stream << std::endl;
+
+ std::list<DOMElement*> globalScripts = DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "script", _scxml, false);
+ if (globalScripts.size() > 0) {
+ stream << "/* run global scripts */" << std::endl;
+ stream << "d_step { " << std::endl;
+
+ for (auto globalScript : globalScripts) {
+ TRACE_EXECUTION("Processing executable content for global script");
+
+ writeExecContent(stream, globalScript, 2);
+ }
+ stream << "} /* d_step */" << std::endl;
+ stream << std::endl;
+ }
+
+ stream << std::endl;
+ stream << "/* ---------------------------- */" << std::endl;
+ stream << _prefix << "MICROSTEP:" << std::endl;
stream << "do" << std::endl;
stream << ":: !" << _prefix << "flags[USCXML_CTX_FINISHED] -> {" << std::endl;
- stream << " /* Run until machine is finished */" << std::endl;
- stream << std::endl;
+ stream << " /* Run until machine is finished */" << std::endl;
+ stream << std::endl;
- TRACE_EXECUTION("Taking a step");
+ TRACE_EXECUTION("Taking a step");
#if 0
- writeFSMRescheduleMachines(stream);
- stream << std::endl;
- writeFSMMacrostep(stream);
- stream << std::endl;
- writeFSMDequeueInternalOrSpontaneousEvent(stream);
+ writeFSMRescheduleMachines(stream);
+ stream << std::endl;
+ writeFSMMacrostep(stream);
+ stream << std::endl;
+ writeFSMDequeueInternalOrSpontaneousEvent(stream);
#else
- writeFSMDequeueEvent(stream);
+ writeFSMDequeueEvent(stream);
#endif
- stream << std::endl;
- stream << "d_step { skip;" << std::endl;
-
- stream << std::endl;
- writeFSMSelectTransitions(stream);
- stream << std::endl;
-
-
- stream << " if" << std::endl;
- stream << " :: " << _prefix << "flags[USCXML_CTX_TRANSITION_FOUND] -> {" << std::endl;
- stream << " /* only process anything if we found transitions or are on initial entry */" << std::endl;
-
- writeFSMRememberHistory(stream);
- stream << std::endl;
- writeFSMEstablishEntrySet(stream);
- stream << std::endl;
- writeFSMExitStates(stream);
- stream << std::endl;
- writeFSMTakeTransitions(stream);
- stream << std::endl;
- writeFSMEnterStates(stream);
- stream << std::endl;
+ stream << std::endl;
+ stream << "d_step { skip;" << std::endl;
+
+ stream << std::endl;
+ writeFSMSelectTransitions(stream);
+ stream << std::endl;
+
+
+ stream << " if" << std::endl;
+ stream << " :: " << _prefix << "flags[USCXML_CTX_TRANSITION_FOUND] -> {" << std::endl;
+ stream << " /* only process anything if we found transitions or are on initial entry */" << std::endl;
+
+ writeFSMRememberHistory(stream);
+ stream << std::endl;
+ writeFSMEstablishEntrySet(stream);
+ stream << std::endl;
+ writeFSMExitStates(stream);
+ stream << std::endl;
+ writeFSMTakeTransitions(stream);
+ stream << std::endl;
+ writeFSMEnterStates(stream);
+ stream << std::endl;
// TRACE_EXECUTION("Exited States")
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi /* USCXML_CTX_TRANSITION_FOUND */" << std::endl;
- stream << " } skip; /* d_step */" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi /* USCXML_CTX_TRANSITION_FOUND */" << std::endl;
+ stream << " } skip; /* d_step */" << std::endl;
- stream << "} /* !USCXML_CTX_FINISHED */" << std::endl;
+ stream << "} /* !USCXML_CTX_FINISHED */" << std::endl;
stream << ":: else -> break;" << std::endl;
stream << "od" << std::endl;
- stream << std::endl;
-
- writeFSMTerminateMachine(stream);
- stream << std::endl;
-
- TRACE_EXECUTION("Done");
+ stream << std::endl;
+
+ writeFSMTerminateMachine(stream);
+ stream << std::endl;
+
+ TRACE_EXECUTION("Done");
stream << "} } /* atomic, step() */" << std::endl;
@@ -1343,1391 +1343,1391 @@ void ChartToPromela::writeFSM(std::ostream& stream) {
#if 0
void ChartToPromela::writeFSMRescheduleMachines(std::ostream& stream) {
- if (_analyzer->usesEventField("delay") && _machinesAll->size() > 1) {
- stream << " /* Determine machines with smallest delay and set their process priority */" << std::endl;
- stream << " scheduleMachines();" << std::endl << std::endl;
- stream << std::endl;
-
- stream << " /* we may return to find ourselves terminated */" << std::endl;
- stream << " if" << std::endl;
- stream << " :: " << _prefix << "flags[USCXML_CTX_FINISHED] -> {" << std::endl;
- stream << " goto " << _prefix << "TERMINATE_MACHINE;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
- stream << std::endl;
- }
+ if (_analyzer->usesEventField("delay") && _machinesAll->size() > 1) {
+ stream << " /* Determine machines with smallest delay and set their process priority */" << std::endl;
+ stream << " scheduleMachines();" << std::endl << std::endl;
+ stream << std::endl;
+
+ stream << " /* we may return to find ourselves terminated */" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: " << _prefix << "flags[USCXML_CTX_FINISHED] -> {" << std::endl;
+ stream << " goto " << _prefix << "TERMINATE_MACHINE;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+ stream << std::endl;
+ }
}
-
+
void ChartToPromela::writeFSMMacrostep(std::ostream& stream) {
-
- stream << " /* Dequeue an external event */" << std::endl;
- stream << " " << _prefix << "flags[USCXML_CTX_DEQUEUED_EXTERNAL] = false;" << std::endl;
-
- stream << " if" << std::endl;
- stream << " :: !" << _prefix << "flags[USCXML_CTX_SPONTANEOUS] && len(" << _prefix << "iQ) == 0 -> {" << std::endl;
-
- stream << " /* manage invocations */" << std::endl;
- stream << " i = 0;" << std::endl;
- stream << " do" << std::endl;
- stream << " :: i < " << _prefix << "USCXML_NUMBER_STATES -> {" << std::endl;
- stream << " /* uninvoke */" << std::endl;
- stream << " if" << std::endl;
- stream << " :: !" << _prefix << "config[i] && " << _prefix << "invocations[i] -> {" << std::endl;
-
- TRACE_EXECUTION_V("Uninvoking in state %d", "i");
-
- stream << " if" << std::endl;
-
- for (size_t i = 0; i < _states.size(); i++) {
- std::list<DOMElement*> invokers = DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "invoke" , _states[i]);
- if (invokers.size() > 0) {
- stream << " :: i == " << toStr(i) << " -> {" << std::endl;
- for (auto invokeElem : invokers) {
- if (_machinesNested.find(invokeElem) == _machinesNested.end())
- continue;
- ChartToPromela* invoker = _machinesNested[invokeElem];
- stream << " " << invoker->_prefix << "flags[USCXML_CTX_FINISHED] = true;" << std::endl;
- }
- stream << " }" << std::endl;
- }
- }
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
-
- stream << " " << _prefix << "invocations[i] = false;" << std::endl;
-
- stream << " skip;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi;" << std::endl;
- stream << std::endl;
-
- stream << " /* invoke */" << std::endl;
- stream << " if" << std::endl;
- stream << " :: " << _prefix << "config[i] && !" << _prefix << "invocations[i] -> {" << std::endl;
- stream << " if" << std::endl;
-
- for (size_t i = 0; i < _states.size(); i++) {
- std::list<DOMElement*> invokers = DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "invoke" , _states[i]);
- if (invokers.size() > 0) {
- stream << " :: i == " << toStr(i) << " -> {" << std::endl;
- for (auto invokeElem : invokers) {
- if (_machinesNested.find(invokeElem) == _machinesNested.end())
- continue;
- ChartToPromela* invoker = _machinesNested[invokeElem];
-
- // pass variables via namelist
- if (HAS_ATTR(invokeElem, "namelist")) {
- std::list<std::string> namelist = tokenize(ATTR_CAST(invokeElem, "namelist"));
- for (auto name : namelist) {
- if (invoker->_dataModelVars.find(name) != invoker->_dataModelVars.end()) {
- stream << " " << invoker->_prefix << name << " = " << _prefix << name << ";" << std::endl;
- }
- }
- }
-
- // pass variables via params
- std::list<DOMElement*> invokeParams = DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + + "param", invokeElem);
- for (auto param : invokeParams) {
- std::string name = ATTR(param, "name");
- std::string expression = ATTR(param, "expr");
- if (invoker->_dataModelVars.find(name) != invoker->_dataModelVars.end()) {
- stream << " " << invoker->_prefix << name << " = " << ADAPT_SRC(expression) << ";" << std::endl;
- }
- }
-
- TRACE_EXECUTION_V("Invoking in state %d", "i");
-
- stream << " run " << invoker->_prefix << "step() priority 20;" << std::endl;
- if (HAS_ATTR(invokeElem, "idlocation")) {
- stream << " " << ADAPT_SRC(ATTR(invokeElem, "idlocation")) << " = ";
- stream << _analyzer->macroForLiteral(invoker->_invokerid) << ";" << std::endl;
- }
-
- }
- stream << " " << _prefix << "invocations[i] = true;" << std::endl;
- stream << " skip;" << std::endl;
- stream << " }" << std::endl;
- }
- }
-
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi;" << std::endl;
- stream << " i = i + 1;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> break;" << std::endl;
- stream << " od;" << std::endl;
- stream << std::endl;
-
- stream << " /* Not sure if this should be before the invocation due to auto-forwarding */" << std::endl;
- stream << " do" << std::endl;
- stream << " :: len(" << _prefix << "eQ) != 0 -> {" << std::endl;
- stream << " " << _prefix << "eQ ? " << _prefix << "_event;" << std::endl;
-
- if (_machinesNested.size() > 0) {
- stream << std::endl;
- stream << " /* auto-forward event */" << std::endl;
- stream << " i = 0;" << std::endl;
- stream << " do" << std::endl;
- stream << " :: i < " << _prefix << "USCXML_NUMBER_STATES -> {" << std::endl;
- stream << " if" << std::endl;
-
- std::string insertOp = "!";
- if (_analyzer->usesEventField("delay")) {
- // insertOp += "!";
- }
-
-
- for (auto state : _states) {
- std::list<DOMElement*> invokers = DOMUtils::filterChildElements(XML_PREFIX(state).str() + "invoke", state, false);
- if (invokers.size() > 0) {
- stream << " :: i == " << ATTR(state, "documentOrder") << " && " << _prefix << "invocations[i] -> { " << std::endl;
- for (auto invoker : invokers) {
- assert(_machinesNested.find(invoker) != _machinesNested.end());
- if (HAS_ATTR(invoker, "autoforward") && stringIsTrue(ATTR(invoker, "autoforward"))) {
- stream << " " << _machinesNested[invoker]->_prefix << "eQ " << insertOp << " " << _prefix << "_event;" << std::endl;
- if (_analyzer->usesEventField("delay")) {
- stream << " insertWithDelay(" << _machinesNested[invoker]->_prefix << "eQ);" << std::endl;
- }
- TRACE_EXECUTION("Auto forwarded event");
- }
- }
- stream << " skip;" << std::endl;
- stream << " }" << std::endl;
- }
- }
-
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
- stream << " i = i + 1;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> break;" << std::endl;
- stream << " od" << std::endl;
-
- stream << std::endl;
- stream << " /* finalize event */" << std::endl;
- stream << " if" << std::endl;
-
- for (auto machine : _machinesNested) {
-
- stream << " :: " << _prefix << "_event.invokeid == " << _analyzer->macroForLiteral(machine.second->_invokerid) << " -> {" << std::endl;
- std::list<DOMElement*> finalizers = DOMUtils::filterChildElements(XML_PREFIX(machine.first).str() + "finalize", machine.first, false);
-
- TRACE_EXECUTION("Finalizing event")
-
- for (auto finalize : finalizers) {
- writeExecContent(stream, finalize, 4);
- }
- stream << " skip" << std::endl;
- stream << " }" << std::endl;
- }
- stream << " :: else -> skip;" << std::endl;
-
- stream << " fi" << std::endl;
-
- }
-
- TRACE_EXECUTION("Deqeued an external event");
- stream << " " << _prefix << "flags[USCXML_CTX_DEQUEUED_EXTERNAL] = true;" << std::endl;
- stream << " break;" << std::endl;
- stream << " }" << std::endl;
- // stream << " :: else -> quit;" << std::endl;
- stream << " od;" << std::endl;
-
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
- stream << std::endl;
+
+ stream << " /* Dequeue an external event */" << std::endl;
+ stream << " " << _prefix << "flags[USCXML_CTX_DEQUEUED_EXTERNAL] = false;" << std::endl;
+
+ stream << " if" << std::endl;
+ stream << " :: !" << _prefix << "flags[USCXML_CTX_SPONTANEOUS] && len(" << _prefix << "iQ) == 0 -> {" << std::endl;
+
+ stream << " /* manage invocations */" << std::endl;
+ stream << " i = 0;" << std::endl;
+ stream << " do" << std::endl;
+ stream << " :: i < " << _prefix << "USCXML_NUMBER_STATES -> {" << std::endl;
+ stream << " /* uninvoke */" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: !" << _prefix << "config[i] && " << _prefix << "invocations[i] -> {" << std::endl;
+
+ TRACE_EXECUTION_V("Uninvoking in state %d", "i");
+
+ stream << " if" << std::endl;
+
+ for (size_t i = 0; i < _states.size(); i++) {
+ std::list<DOMElement*> invokers = DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "invoke" , _states[i]);
+ if (invokers.size() > 0) {
+ stream << " :: i == " << toStr(i) << " -> {" << std::endl;
+ for (auto invokeElem : invokers) {
+ if (_machinesNested.find(invokeElem) == _machinesNested.end())
+ continue;
+ ChartToPromela* invoker = _machinesNested[invokeElem];
+ stream << " " << invoker->_prefix << "flags[USCXML_CTX_FINISHED] = true;" << std::endl;
+ }
+ stream << " }" << std::endl;
+ }
+ }
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+
+ stream << " " << _prefix << "invocations[i] = false;" << std::endl;
+
+ stream << " skip;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi;" << std::endl;
+ stream << std::endl;
+
+ stream << " /* invoke */" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: " << _prefix << "config[i] && !" << _prefix << "invocations[i] -> {" << std::endl;
+ stream << " if" << std::endl;
+
+ for (size_t i = 0; i < _states.size(); i++) {
+ std::list<DOMElement*> invokers = DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "invoke" , _states[i]);
+ if (invokers.size() > 0) {
+ stream << " :: i == " << toStr(i) << " -> {" << std::endl;
+ for (auto invokeElem : invokers) {
+ if (_machinesNested.find(invokeElem) == _machinesNested.end())
+ continue;
+ ChartToPromela* invoker = _machinesNested[invokeElem];
+
+ // pass variables via namelist
+ if (HAS_ATTR(invokeElem, "namelist")) {
+ std::list<std::string> namelist = tokenize(ATTR_CAST(invokeElem, "namelist"));
+ for (auto name : namelist) {
+ if (invoker->_dataModelVars.find(name) != invoker->_dataModelVars.end()) {
+ stream << " " << invoker->_prefix << name << " = " << _prefix << name << ";" << std::endl;
+ }
+ }
+ }
+
+ // pass variables via params
+ std::list<DOMElement*> invokeParams = DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + + "param", invokeElem);
+ for (auto param : invokeParams) {
+ std::string name = ATTR(param, "name");
+ std::string expression = ATTR(param, "expr");
+ if (invoker->_dataModelVars.find(name) != invoker->_dataModelVars.end()) {
+ stream << " " << invoker->_prefix << name << " = " << ADAPT_SRC(expression) << ";" << std::endl;
+ }
+ }
+
+ TRACE_EXECUTION_V("Invoking in state %d", "i");
+
+ stream << " run " << invoker->_prefix << "step() priority 20;" << std::endl;
+ if (HAS_ATTR(invokeElem, "idlocation")) {
+ stream << " " << ADAPT_SRC(ATTR(invokeElem, "idlocation")) << " = ";
+ stream << _analyzer->macroForLiteral(invoker->_invokerid) << ";" << std::endl;
+ }
+
+ }
+ stream << " " << _prefix << "invocations[i] = true;" << std::endl;
+ stream << " skip;" << std::endl;
+ stream << " }" << std::endl;
+ }
+ }
+
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi;" << std::endl;
+ stream << " i = i + 1;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> break;" << std::endl;
+ stream << " od;" << std::endl;
+ stream << std::endl;
+
+ stream << " /* Not sure if this should be before the invocation due to auto-forwarding */" << std::endl;
+ stream << " do" << std::endl;
+ stream << " :: len(" << _prefix << "eQ) != 0 -> {" << std::endl;
+ stream << " " << _prefix << "eQ ? " << _prefix << "_event;" << std::endl;
+
+ if (_machinesNested.size() > 0) {
+ stream << std::endl;
+ stream << " /* auto-forward event */" << std::endl;
+ stream << " i = 0;" << std::endl;
+ stream << " do" << std::endl;
+ stream << " :: i < " << _prefix << "USCXML_NUMBER_STATES -> {" << std::endl;
+ stream << " if" << std::endl;
+
+ std::string insertOp = "!";
+ if (_analyzer->usesEventField("delay")) {
+ // insertOp += "!";
+ }
+
+
+ for (auto state : _states) {
+ std::list<DOMElement*> invokers = DOMUtils::filterChildElements(XML_PREFIX(state).str() + "invoke", state, false);
+ if (invokers.size() > 0) {
+ stream << " :: i == " << ATTR(state, "documentOrder") << " && " << _prefix << "invocations[i] -> { " << std::endl;
+ for (auto invoker : invokers) {
+ assert(_machinesNested.find(invoker) != _machinesNested.end());
+ if (HAS_ATTR(invoker, "autoforward") && stringIsTrue(ATTR(invoker, "autoforward"))) {
+ stream << " " << _machinesNested[invoker]->_prefix << "eQ " << insertOp << " " << _prefix << "_event;" << std::endl;
+ if (_analyzer->usesEventField("delay")) {
+ stream << " insertWithDelay(" << _machinesNested[invoker]->_prefix << "eQ);" << std::endl;
+ }
+ TRACE_EXECUTION("Auto forwarded event");
+ }
+ }
+ stream << " skip;" << std::endl;
+ stream << " }" << std::endl;
+ }
+ }
+
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+ stream << " i = i + 1;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> break;" << std::endl;
+ stream << " od" << std::endl;
+
+ stream << std::endl;
+ stream << " /* finalize event */" << std::endl;
+ stream << " if" << std::endl;
+
+ for (auto machine : _machinesNested) {
+
+ stream << " :: " << _prefix << "_event.invokeid == " << _analyzer->macroForLiteral(machine.second->_invokerid) << " -> {" << std::endl;
+ std::list<DOMElement*> finalizers = DOMUtils::filterChildElements(XML_PREFIX(machine.first).str() + "finalize", machine.first, false);
+
+ TRACE_EXECUTION("Finalizing event")
+
+ for (auto finalize : finalizers) {
+ writeExecContent(stream, finalize, 4);
+ }
+ stream << " skip" << std::endl;
+ stream << " }" << std::endl;
+ }
+ stream << " :: else -> skip;" << std::endl;
+
+ stream << " fi" << std::endl;
+
+ }
+
+ TRACE_EXECUTION("Deqeued an external event");
+ stream << " " << _prefix << "flags[USCXML_CTX_DEQUEUED_EXTERNAL] = true;" << std::endl;
+ stream << " break;" << std::endl;
+ stream << " }" << std::endl;
+ // stream << " :: else -> quit;" << std::endl;
+ stream << " od;" << std::endl;
+
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+ stream << std::endl;
}
-
+
void ChartToPromela::writeFSMDequeueInternalOrSpontaneousEvent(std::ostream& stream) {
- stream << " if" << std::endl;
- stream << " :: !" << _prefix << "flags[USCXML_CTX_DEQUEUED_EXTERNAL] -> {" << std::endl;
- stream << " /* Try with a spontaneous event or dequeue an internal event */" << std::endl;
- stream << " if" << std::endl;
- stream << " :: " << _prefix << "flags[USCXML_CTX_SPONTANEOUS] -> {" << std::endl;
- stream << " /* We try with a spontaneous event */" << std::endl;
- stream << " " << _prefix << EVENT_NAME << " = USCXML_EVENT_SPONTANEOUS;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> {" << std::endl;
- stream << " /* We try with an internal event */" << std::endl;
- stream << " assert(len(" << _prefix << "iQ) > 0);" << std::endl;
- stream << " " << _prefix << "iQ ? " << _prefix << "_event;" << std::endl;
- stream << " }" << std::endl;
- stream << " fi" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: !" << _prefix << "flags[USCXML_CTX_DEQUEUED_EXTERNAL] -> {" << std::endl;
+ stream << " /* Try with a spontaneous event or dequeue an internal event */" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: " << _prefix << "flags[USCXML_CTX_SPONTANEOUS] -> {" << std::endl;
+ stream << " /* We try with a spontaneous event */" << std::endl;
+ stream << " " << _prefix << EVENT_NAME << " = USCXML_EVENT_SPONTANEOUS;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> {" << std::endl;
+ stream << " /* We try with an internal event */" << std::endl;
+ stream << " assert(len(" << _prefix << "iQ) > 0);" << std::endl;
+ stream << " " << _prefix << "iQ ? " << _prefix << "_event;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " fi" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
}
#endif
-
+
#if 1
void ChartToPromela::writeFSMDequeueEvent(std::ostream& stream) {
- stream << " /* Dequeue an event */" << std::endl;
- stream << " " << _prefix << "flags[USCXML_CTX_DEQUEUE_EXTERNAL] = false;" << std::endl;
- stream << " if" << std::endl;
- stream << " ::" << _prefix << "flags[USCXML_CTX_SPONTANEOUS] -> {" << std::endl;
- stream << " " << _prefix << EVENT_NAME << " = USCXML_EVENT_SPONTANEOUS;" << std::endl;
-
- TRACE_EXECUTION("Trying with a spontaneous event");
-
- stream << " }" << std::endl;
- stream << " :: else -> {" << std::endl;
- stream << " if" << std::endl;
- stream << " :: len(" << _prefix << "iQ) != 0 -> {" << std::endl;
- stream << " " << _prefix << "iQ ? " << _prefix << "_event;" << std::endl;
-
- TRACE_EXECUTION("Deqeued an internal event");
-
- stream << " }" << std::endl;
- stream << " :: else -> {" << std::endl;
- stream << " " << _prefix << "flags[USCXML_CTX_DEQUEUE_EXTERNAL] = true;" << std::endl;
- stream << " }" << std::endl;
- stream << " fi;" << std::endl;
- stream << " }" << std::endl;
- stream << " fi;" << std::endl;
- stream << std::endl;
-
- stream << std::endl;
-
- stream << " if" << std::endl;
- stream << " :: " << _prefix << "flags[USCXML_CTX_DEQUEUE_EXTERNAL] -> {" << std::endl;
- stream << " /* manage invocations */" << std::endl;
- stream << " i = 0;" << std::endl;
- stream << " do" << std::endl;
- stream << " :: i < " << _prefix << "USCXML_NUMBER_STATES -> {" << std::endl;
- stream << " d_step { " << std::endl;
- stream << " /* uninvoke */" << std::endl;
- stream << " if" << std::endl;
- stream << " :: !" << _prefix << "config[i] && " << _prefix << "invocations[i] -> {" << std::endl;
-
- TRACE_EXECUTION_V("Uninvoking in state %d", "i");
-
- stream << " if" << std::endl;
-
- for (size_t i = 0; i < _states.size(); i++) {
- std::list<DOMElement*> invokers = DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "invoke" , _states[i]);
- if (invokers.size() > 0) {
- stream << " :: i == " << toStr(i) << " -> {" << std::endl;
- for (auto invokeElem : invokers) {
- if (_machinesNested.find(invokeElem) == _machinesNested.end())
- continue;
- ChartToPromela* invoker = _machinesNested[invokeElem];
- stream << " " << invoker->_prefix << "flags[USCXML_CTX_FINISHED] = true;" << std::endl;
- }
- stream << " }" << std::endl;
- }
- }
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
-
- stream << " " << _prefix << "invocations[i] = false;" << std::endl;
-
- stream << " skip;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi;" << std::endl;
- stream << " } /* d_step */" << std::endl;
-
- stream << std::endl;
-
-
-
- stream << " /* invoke */" << std::endl;
- stream << " if" << std::endl;
- stream << " :: " << _prefix << "config[i] && !" << _prefix << "invocations[i] -> {" << std::endl;
- stream << " if" << std::endl;
-
- for (size_t i = 0; i < _states.size(); i++) {
- std::list<DOMElement*> invokers = DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "invoke" , _states[i]);
- if (invokers.size() > 0) {
- stream << " :: i == " << toStr(i) << " -> {" << std::endl;
- for (auto invokeElem : invokers) {
- if (_machinesNested.find(invokeElem) == _machinesNested.end())
- continue;
- ChartToPromela* invoker = _machinesNested[invokeElem];
-
- // pass variables via namelist
- if (HAS_ATTR(invokeElem, "namelist")) {
- std::list<std::string> namelist = tokenize(ATTR_CAST(invokeElem, "namelist"));
- for (auto name : namelist) {
- if (invoker->_dataModelVars.find(name) != invoker->_dataModelVars.end()) {
- stream << " " << invoker->_prefix << name << " = " << _prefix << name << ";" << std::endl;
- }
- }
- }
-
- // pass variables via params
- std::list<DOMElement*> invokeParams = DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + + "param", invokeElem);
- for (auto param : invokeParams) {
- std::string name = ATTR(param, "name");
- std::string expression = ATTR(param, "expr");
- if (invoker->_dataModelVars.find(name) != invoker->_dataModelVars.end()) {
- stream << " " << invoker->_prefix << name << " = " << ADAPT_SRC(expression) << ";" << std::endl;
- }
- }
-
- TRACE_EXECUTION_V("Invoking in state %d", "i");
-
- stream << " run " << invoker->_prefix << "step() priority 20;" << std::endl;
- if (HAS_ATTR(invokeElem, "idlocation")) {
- stream << " " << ADAPT_SRC(ATTR(invokeElem, "idlocation")) << " = ";
- stream << _analyzer->macroForLiteral(invoker->_invokerid) << ";" << std::endl;
- }
-
- }
- stream << " " << _prefix << "invocations[i] = true;" << std::endl;
- stream << " skip;" << std::endl;
- stream << " }" << std::endl;
- }
- }
-
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi;" << std::endl;
- stream << " i = i + 1;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> break;" << std::endl;
- stream << " od;" << std::endl;
-
- stream << std::endl;
-
- if (_analyzer->usesEventField("delay") && _machinesAll->size() > 1) {
- stream << " /* Determine machines with smallest delay and set their process priority */" << std::endl;
- stream << " scheduleMachines();" << std::endl << std::endl;
- }
-
- stream << " /* we may return to find ourselves terminated */" << std::endl;
- stream << " if" << std::endl;
- stream << " :: " << _prefix << "flags[USCXML_CTX_FINISHED] -> {" << std::endl;
- stream << " goto " << _prefix << "TERMINATE_MACHINE;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
-
-
- stream << " /* Not sure if this should be before the invocation due to auto-forwarding */" << std::endl;
- stream << " if" << std::endl;
- stream << " :: len(" << _prefix << "eQ) != 0 -> {" << std::endl;
- stream << " " << _prefix << "eQ ? " << _prefix << "_event;" << std::endl;
-
- if (_machinesNested.size() > 0) {
- stream << std::endl;
- stream << " d_step {" << std::endl;
- stream << " /* auto-forward event */" << std::endl;
- stream << " i = 0;" << std::endl;
- stream << " do" << std::endl;
- stream << " :: i < " << _prefix << "USCXML_NUMBER_STATES -> {" << std::endl;
- stream << " if" << std::endl;
-
- std::string insertOp = "!";
- if (_analyzer->usesEventField("delay")) {
- // insertOp += "!";
- }
-
-
- for (auto state : _states) {
- std::list<DOMElement*> invokers = DOMUtils::filterChildElements(XML_PREFIX(state).str() + "invoke", state, false);
- if (invokers.size() > 0) {
- stream << " :: i == " << ATTR(state, "documentOrder") << " && " << _prefix << "invocations[i] -> { " << std::endl;
- for (auto invoker : invokers) {
- assert(_machinesNested.find(invoker) != _machinesNested.end());
- if (HAS_ATTR(invoker, "autoforward") && stringIsTrue(ATTR(invoker, "autoforward"))) {
- stream << " " << _machinesNested[invoker]->_prefix << "eQ " << insertOp << " " << _prefix << "_event;" << std::endl;
- if (_analyzer->usesEventField("delay")) {
- stream << " insertWithDelay(" << _machinesNested[invoker]->_prefix << "eQ);" << std::endl;
- }
- TRACE_EXECUTION("Auto forwarded event");
- }
- }
- stream << " skip;" << std::endl;
- stream << " }" << std::endl;
- }
- }
-
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
- stream << " i = i + 1;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> break;" << std::endl;
- stream << " od" << std::endl;
-
- stream << std::endl;
- stream << " /* finalize event */" << std::endl;
- stream << " if" << std::endl;
-
- for (auto machine : _machinesNested) {
-
- stream << " :: " << _prefix << "_event.invokeid == " << _analyzer->macroForLiteral(machine.second->_invokerid) << " -> {" << std::endl;
- std::list<DOMElement*> finalizers = DOMUtils::filterChildElements(XML_PREFIX(machine.first).str() + "finalize", machine.first, false);
-
- TRACE_EXECUTION("Finalizing event")
-
- for (auto finalize : finalizers) {
- writeExecContent(stream, finalize, 4);
- }
- stream << " skip" << std::endl;
- stream << " }" << std::endl;
- }
- stream << " :: else -> skip;" << std::endl;
-
- stream << " fi" << std::endl;
- stream << " } /* d_step */" << std::endl;
-
- }
-
- TRACE_EXECUTION("Deqeued an external event");
-
- stream << " }" << std::endl;
- // stream << " :: else -> quit;" << std::endl;
- stream << " fi;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
- stream << std::endl;
+ stream << " /* Dequeue an event */" << std::endl;
+ stream << " " << _prefix << "flags[USCXML_CTX_DEQUEUE_EXTERNAL] = false;" << std::endl;
+ stream << " if" << std::endl;
+ stream << " ::" << _prefix << "flags[USCXML_CTX_SPONTANEOUS] -> {" << std::endl;
+ stream << " " << _prefix << EVENT_NAME << " = USCXML_EVENT_SPONTANEOUS;" << std::endl;
+
+ TRACE_EXECUTION("Trying with a spontaneous event");
+
+ stream << " }" << std::endl;
+ stream << " :: else -> {" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: len(" << _prefix << "iQ) != 0 -> {" << std::endl;
+ stream << " " << _prefix << "iQ ? " << _prefix << "_event;" << std::endl;
+
+ TRACE_EXECUTION("Deqeued an internal event");
+
+ stream << " }" << std::endl;
+ stream << " :: else -> {" << std::endl;
+ stream << " " << _prefix << "flags[USCXML_CTX_DEQUEUE_EXTERNAL] = true;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " fi;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " fi;" << std::endl;
+ stream << std::endl;
+
+ stream << std::endl;
+
+ stream << " if" << std::endl;
+ stream << " :: " << _prefix << "flags[USCXML_CTX_DEQUEUE_EXTERNAL] -> {" << std::endl;
+ stream << " /* manage invocations */" << std::endl;
+ stream << " i = 0;" << std::endl;
+ stream << " do" << std::endl;
+ stream << " :: i < " << _prefix << "USCXML_NUMBER_STATES -> {" << std::endl;
+ stream << " d_step { " << std::endl;
+ stream << " /* uninvoke */" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: !" << _prefix << "config[i] && " << _prefix << "invocations[i] -> {" << std::endl;
+
+ TRACE_EXECUTION_V("Uninvoking in state %d", "i");
+
+ stream << " if" << std::endl;
+
+ for (size_t i = 0; i < _states.size(); i++) {
+ std::list<DOMElement*> invokers = DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "invoke" , _states[i]);
+ if (invokers.size() > 0) {
+ stream << " :: i == " << toStr(i) << " -> {" << std::endl;
+ for (auto invokeElem : invokers) {
+ if (_machinesNested.find(invokeElem) == _machinesNested.end())
+ continue;
+ ChartToPromela* invoker = _machinesNested[invokeElem];
+ stream << " " << invoker->_prefix << "flags[USCXML_CTX_FINISHED] = true;" << std::endl;
+ }
+ stream << " }" << std::endl;
+ }
+ }
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+
+ stream << " " << _prefix << "invocations[i] = false;" << std::endl;
+
+ stream << " skip;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi;" << std::endl;
+ stream << " } /* d_step */" << std::endl;
+
+ stream << std::endl;
+
+
+
+ stream << " /* invoke */" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: " << _prefix << "config[i] && !" << _prefix << "invocations[i] -> {" << std::endl;
+ stream << " if" << std::endl;
+
+ for (size_t i = 0; i < _states.size(); i++) {
+ std::list<DOMElement*> invokers = DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "invoke" , _states[i]);
+ if (invokers.size() > 0) {
+ stream << " :: i == " << toStr(i) << " -> {" << std::endl;
+ for (auto invokeElem : invokers) {
+ if (_machinesNested.find(invokeElem) == _machinesNested.end())
+ continue;
+ ChartToPromela* invoker = _machinesNested[invokeElem];
+
+ // pass variables via namelist
+ if (HAS_ATTR(invokeElem, "namelist")) {
+ std::list<std::string> namelist = tokenize(ATTR_CAST(invokeElem, "namelist"));
+ for (auto name : namelist) {
+ if (invoker->_dataModelVars.find(name) != invoker->_dataModelVars.end()) {
+ stream << " " << invoker->_prefix << name << " = " << _prefix << name << ";" << std::endl;
+ }
+ }
+ }
+
+ // pass variables via params
+ std::list<DOMElement*> invokeParams = DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + + "param", invokeElem);
+ for (auto param : invokeParams) {
+ std::string name = ATTR(param, "name");
+ std::string expression = ATTR(param, "expr");
+ if (invoker->_dataModelVars.find(name) != invoker->_dataModelVars.end()) {
+ stream << " " << invoker->_prefix << name << " = " << ADAPT_SRC(expression) << ";" << std::endl;
+ }
+ }
+
+ TRACE_EXECUTION_V("Invoking in state %d", "i");
+
+ stream << " run " << invoker->_prefix << "step() priority 20;" << std::endl;
+ if (HAS_ATTR(invokeElem, "idlocation")) {
+ stream << " " << ADAPT_SRC(ATTR(invokeElem, "idlocation")) << " = ";
+ stream << _analyzer->macroForLiteral(invoker->_invokerid) << ";" << std::endl;
+ }
+
+ }
+ stream << " " << _prefix << "invocations[i] = true;" << std::endl;
+ stream << " skip;" << std::endl;
+ stream << " }" << std::endl;
+ }
+ }
+
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi;" << std::endl;
+ stream << " i = i + 1;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> break;" << std::endl;
+ stream << " od;" << std::endl;
+
+ stream << std::endl;
+
+ if (_analyzer->usesEventField("delay") && _machinesAll->size() > 1) {
+ stream << " /* Determine machines with smallest delay and set their process priority */" << std::endl;
+ stream << " scheduleMachines();" << std::endl << std::endl;
+ }
+
+ stream << " /* we may return to find ourselves terminated */" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: " << _prefix << "flags[USCXML_CTX_FINISHED] -> {" << std::endl;
+ stream << " goto " << _prefix << "TERMINATE_MACHINE;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+
+
+ stream << " /* Not sure if this should be before the invocation due to auto-forwarding */" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: len(" << _prefix << "eQ) != 0 -> {" << std::endl;
+ stream << " " << _prefix << "eQ ? " << _prefix << "_event;" << std::endl;
+
+ if (_machinesNested.size() > 0) {
+ stream << std::endl;
+ stream << " d_step {" << std::endl;
+ stream << " /* auto-forward event */" << std::endl;
+ stream << " i = 0;" << std::endl;
+ stream << " do" << std::endl;
+ stream << " :: i < " << _prefix << "USCXML_NUMBER_STATES -> {" << std::endl;
+ stream << " if" << std::endl;
+
+ std::string insertOp = "!";
+ if (_analyzer->usesEventField("delay")) {
+ // insertOp += "!";
+ }
+
+
+ for (auto state : _states) {
+ std::list<DOMElement*> invokers = DOMUtils::filterChildElements(XML_PREFIX(state).str() + "invoke", state, false);
+ if (invokers.size() > 0) {
+ stream << " :: i == " << ATTR(state, "documentOrder") << " && " << _prefix << "invocations[i] -> { " << std::endl;
+ for (auto invoker : invokers) {
+ assert(_machinesNested.find(invoker) != _machinesNested.end());
+ if (HAS_ATTR(invoker, "autoforward") && stringIsTrue(ATTR(invoker, "autoforward"))) {
+ stream << " " << _machinesNested[invoker]->_prefix << "eQ " << insertOp << " " << _prefix << "_event;" << std::endl;
+ if (_analyzer->usesEventField("delay")) {
+ stream << " insertWithDelay(" << _machinesNested[invoker]->_prefix << "eQ);" << std::endl;
+ }
+ TRACE_EXECUTION("Auto forwarded event");
+ }
+ }
+ stream << " skip;" << std::endl;
+ stream << " }" << std::endl;
+ }
+ }
+
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+ stream << " i = i + 1;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> break;" << std::endl;
+ stream << " od" << std::endl;
+
+ stream << std::endl;
+ stream << " /* finalize event */" << std::endl;
+ stream << " if" << std::endl;
+
+ for (auto machine : _machinesNested) {
+
+ stream << " :: " << _prefix << "_event.invokeid == " << _analyzer->macroForLiteral(machine.second->_invokerid) << " -> {" << std::endl;
+ std::list<DOMElement*> finalizers = DOMUtils::filterChildElements(XML_PREFIX(machine.first).str() + "finalize", machine.first, false);
+
+ TRACE_EXECUTION("Finalizing event")
+
+ for (auto finalize : finalizers) {
+ writeExecContent(stream, finalize, 4);
+ }
+ stream << " skip" << std::endl;
+ stream << " }" << std::endl;
+ }
+ stream << " :: else -> skip;" << std::endl;
+
+ stream << " fi" << std::endl;
+ stream << " } /* d_step */" << std::endl;
+
+ }
+
+ TRACE_EXECUTION("Deqeued an external event");
+
+ stream << " }" << std::endl;
+ // stream << " :: else -> quit;" << std::endl;
+ stream << " fi;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+ stream << std::endl;
}
#endif
void ChartToPromela::writeFSMSelectTransitions(std::ostream& stream) {
- stream << "/* ---------------------------- */" << std::endl;
- stream << _prefix << "SELECT_TRANSITIONS:" << std::endl;
-
- stream << _prefix << "STATES_CLEAR(" << _prefix << "ctx.target_set)" << std::endl;
- stream << _prefix << "STATES_CLEAR(" << _prefix << "ctx.exit_set)" << std::endl;
-
- if (_transitions.size() > 0) {
- stream << _prefix << "TRANS_CLEAR(" << _prefix << "ctx.conflicts)" << std::endl;
- stream << _prefix << "TRANS_CLEAR(" << _prefix << "ctx.trans_set)" << std::endl;
-
- stream << "#if TRACE_EXECUTION" << std::endl;
- if (_machinesAll->size() > 1) {
- stream << "printf(\"%d: Establishing optimal transition set for event %d\\n\", _pid, " << _prefix << EVENT_NAME << " );" << std::endl;
- } else {
- stream << "printf(\"Establishing optimal transition set for event %d\\n\", " << _prefix << EVENT_NAME << " );" << std::endl;
- }
- stream << "#endif" << std::endl;
- stream << std::endl;
-
- stream << "#if TRACE_EXECUTION" << std::endl;
- stream << "printf(\"Configuration: \");" << std::endl;
- printBitArray(stream, _prefix + "config", _states.size());
- stream << "printf(\"\\n\");" << std::endl;
- stream << "#endif" << std::endl;
- stream << std::endl;
- stream << " " << _prefix << "flags[USCXML_CTX_TRANSITION_FOUND] = false;" << std::endl;
- stream << " i = 0;" << std::endl;
- stream << " do" << std::endl;
- stream << " :: i < " << _prefix << "USCXML_NUMBER_TRANS -> {" << std::endl;
-
- stream << " /* only select non-history, non-initial transitions */" << std::endl;
- stream << " if" << std::endl;
- stream << " :: !" << _prefix << "transitions[i].type[USCXML_TRANS_HISTORY] &&" << std::endl;
- stream << " !" << _prefix << "transitions[i].type[USCXML_TRANS_INITIAL] -> {" << std::endl;
-
- stream << " if" << std::endl;
- stream << " :: /* is the transition active? */" << std::endl;
- stream << " " << _prefix << "config[" << _prefix << "transitions[i].source] && " << std::endl;
- stream << std::endl;
- stream << " /* is it non-conflicting? */" << std::endl;
- stream << " !" << _prefix << "ctx.conflicts[i] && " << std::endl;
- stream << std::endl;
- stream << " /* is it spontaneous with an event or vice versa? */" << std::endl;
- stream << " ((" << _prefix << EVENT_NAME << " == USCXML_EVENT_SPONTANEOUS && " << std::endl;
- stream << " " << _prefix << "transitions[i].type[USCXML_TRANS_SPONTANEOUS]) || " << std::endl;
- stream << " (" << _prefix << EVENT_NAME << " != USCXML_EVENT_SPONTANEOUS && " << std::endl;
- stream << " !" << _prefix << "transitions[i].type[USCXML_TRANS_SPONTANEOUS])) &&" << std::endl;
- stream << std::endl;
- stream << " /* is it matching and enabled? */" << std::endl;
- stream << " (false " << std::endl;
-
-
- for (auto i = 0; i < _transitions.size(); i++) {
- stream << " || (i == " << toStr(i);
- if (HAS_ATTR(_transitions[i], "event") && ATTR(_transitions[i], "event") != "*") {
- stream << " && (false";
- std::list<std::string> eventLiterals = tokenize(ATTR(_transitions[i], "event"));
- for (auto eventLiteral : eventLiterals) {
- if (boost::ends_with(eventLiteral, ".*")) {
- eventLiteral = eventLiteral.substr(0, eventLiteral.size() - 2);
- }
- if (boost::ends_with(eventLiteral, ".")) {
- eventLiteral = eventLiteral.substr(0, eventLiteral.size() - 1);
- }
- std::list<TrieNode*> events =_analyzer->getTrie().getWordsWithPrefix(eventLiteral);
- for (auto event : events) {
- stream << " || " << _prefix << EVENT_NAME << " == " << _analyzer->macroForLiteral(event->value);
- }
- }
- stream << ")";
- }
- if (HAS_ATTR(_transitions[i], "cond")) {
- stream << " && " << ADAPT_SRC(ATTR(_transitions[i], "cond"));
- }
- stream << ")" << std::endl;
- }
-
- stream << " ) -> {" << std::endl;
-
- stream << " /* remember that we found a transition */" << std::endl;
- stream << " " << _prefix << "flags[USCXML_CTX_TRANSITION_FOUND] = true;" << std::endl;
- stream << std::endl;
-
- stream << " /* transitions that are pre-empted */" << std::endl;
- stream << " " << _prefix << "TRANS_OR(" << _prefix << "ctx.conflicts, " << _prefix << "transitions[i].conflicts)" << std::endl;
- stream << std::endl;
-
- stream << " /* states that are directly targeted (resolve as entry-set later) */" << std::endl;
- stream << " " << _prefix << "STATES_OR(" << _prefix << "ctx.target_set, " << _prefix << "transitions[i].target)" << std::endl;
- stream << std::endl;
-
- stream << " /* states that will be left */" << std::endl;
- stream << " " << _prefix << "STATES_OR(" << _prefix << "ctx.exit_set, " << _prefix << "transitions[i].exit_set)" << std::endl;
- stream << std::endl;
-
- stream << " " << _prefix << "ctx.trans_set[i] = true;" << std::endl;
-
-
- stream << " }" << std::endl;
- stream << " :: else {" << std::endl;
- stream << " skip;" << std::endl;
- stream << " }" << std::endl;
- stream << " fi" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> {" << std::endl;
- stream << " skip;" << std::endl;
- stream << " }" << std::endl;
- stream << " fi" << std::endl;
-
- stream << " i = i + 1;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> break;" << std::endl;
- stream << " od;" << std::endl;
-
- stream << " " << _prefix << "STATES_AND(" << _prefix << "ctx.exit_set, " << _prefix << "config)" << std::endl;
-
- stream << std::endl;
- stream << "#if TRACE_EXECUTION" << std::endl;
- stream << "printf(\"Selected Transitions: \");" << std::endl;
- printBitArray(stream, _prefix + "ctx.trans_set", _transitions.size());
- stream << "printf(\"\\n\");" << std::endl;
- stream << "#endif" << std::endl;
- stream << std::endl;
- }
- stream << std::endl;
- stream << "#if TRACE_EXECUTION" << std::endl;
- stream << "printf(\"Target Set: \");" << std::endl;
- printBitArray(stream, _prefix + "ctx.target_set", _states.size());
- stream << "printf(\"\\n\");" << std::endl;
- stream << "#endif" << std::endl;
- stream << std::endl;
-
- stream << std::endl;
- stream << "#if TRACE_EXECUTION" << std::endl;
- stream << "printf(\"Exit Set: \");" << std::endl;
- printBitArray(stream, _prefix + "ctx.exit_set", _states.size());
- stream << "printf(\"\\n\");" << std::endl;
- stream << "#endif" << std::endl;
- stream << std::endl;
-
- stream << " if" << std::endl;
- stream << " :: !" << _prefix << "STATES_HAS_ANY(" << _prefix << "config) -> {" << std::endl;
- stream << " /* Enter initial configuration */" << std::endl;
- stream << " " << _prefix << "STATES_COPY(" << _prefix << "ctx.target_set, " << _prefix << "states[0].completion)" << std::endl;
- stream << " " << _prefix << "flags[USCXML_CTX_SPONTANEOUS] = true;" << std::endl;
- stream << " " << _prefix << "flags[USCXML_CTX_TRANSITION_FOUND] = true;" << std::endl;
-
- TRACE_EXECUTION("Entering initial default completion");
-
- // stream << " goto " << _prefix << "ESTABLISH_ENTRY_SET;" << std::endl;
- stream << std::endl;
-
- stream << " }" << std::endl;
- stream << " :: " << _prefix << "flags[USCXML_CTX_TRANSITION_FOUND] -> {" << std::endl;
-
- TRACE_EXECUTION("Found transitions");
-
- stream << " " << _prefix << "flags[USCXML_CTX_SPONTANEOUS] = true;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else {" << std::endl;
- stream << " " << _prefix << "flags[USCXML_CTX_SPONTANEOUS] = false;" << std::endl;
-
- TRACE_EXECUTION("Found NO transitions");
-
- // stream << " goto " << _prefix << "MICROSTEP;" << std::endl;
- stream << " }" << std::endl;
- stream << " fi" << std::endl;
- stream << std::endl;
+ stream << "/* ---------------------------- */" << std::endl;
+ stream << _prefix << "SELECT_TRANSITIONS:" << std::endl;
+
+ stream << _prefix << "STATES_CLEAR(" << _prefix << "ctx.target_set)" << std::endl;
+ stream << _prefix << "STATES_CLEAR(" << _prefix << "ctx.exit_set)" << std::endl;
+
+ if (_transitions.size() > 0) {
+ stream << _prefix << "TRANS_CLEAR(" << _prefix << "ctx.conflicts)" << std::endl;
+ stream << _prefix << "TRANS_CLEAR(" << _prefix << "ctx.trans_set)" << std::endl;
+
+ stream << "#if TRACE_EXECUTION" << std::endl;
+ if (_machinesAll->size() > 1) {
+ stream << "printf(\"%d: Establishing optimal transition set for event %d\\n\", _pid, " << _prefix << EVENT_NAME << " );" << std::endl;
+ } else {
+ stream << "printf(\"Establishing optimal transition set for event %d\\n\", " << _prefix << EVENT_NAME << " );" << std::endl;
+ }
+ stream << "#endif" << std::endl;
+ stream << std::endl;
+
+ stream << "#if TRACE_EXECUTION" << std::endl;
+ stream << "printf(\"Configuration: \");" << std::endl;
+ printBitArray(stream, _prefix + "config", _states.size());
+ stream << "printf(\"\\n\");" << std::endl;
+ stream << "#endif" << std::endl;
+ stream << std::endl;
+ stream << " " << _prefix << "flags[USCXML_CTX_TRANSITION_FOUND] = false;" << std::endl;
+ stream << " i = 0;" << std::endl;
+ stream << " do" << std::endl;
+ stream << " :: i < " << _prefix << "USCXML_NUMBER_TRANS -> {" << std::endl;
+
+ stream << " /* only select non-history, non-initial transitions */" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: !" << _prefix << "transitions[i].type[USCXML_TRANS_HISTORY] &&" << std::endl;
+ stream << " !" << _prefix << "transitions[i].type[USCXML_TRANS_INITIAL] -> {" << std::endl;
+
+ stream << " if" << std::endl;
+ stream << " :: /* is the transition active? */" << std::endl;
+ stream << " " << _prefix << "config[" << _prefix << "transitions[i].source] && " << std::endl;
+ stream << std::endl;
+ stream << " /* is it non-conflicting? */" << std::endl;
+ stream << " !" << _prefix << "ctx.conflicts[i] && " << std::endl;
+ stream << std::endl;
+ stream << " /* is it spontaneous with an event or vice versa? */" << std::endl;
+ stream << " ((" << _prefix << EVENT_NAME << " == USCXML_EVENT_SPONTANEOUS && " << std::endl;
+ stream << " " << _prefix << "transitions[i].type[USCXML_TRANS_SPONTANEOUS]) || " << std::endl;
+ stream << " (" << _prefix << EVENT_NAME << " != USCXML_EVENT_SPONTANEOUS && " << std::endl;
+ stream << " !" << _prefix << "transitions[i].type[USCXML_TRANS_SPONTANEOUS])) &&" << std::endl;
+ stream << std::endl;
+ stream << " /* is it matching and enabled? */" << std::endl;
+ stream << " (false " << std::endl;
+
+
+ for (auto i = 0; i < _transitions.size(); i++) {
+ stream << " || (i == " << toStr(i);
+ if (HAS_ATTR(_transitions[i], "event") && ATTR(_transitions[i], "event") != "*") {
+ stream << " && (false";
+ std::list<std::string> eventLiterals = tokenize(ATTR(_transitions[i], "event"));
+ for (auto eventLiteral : eventLiterals) {
+ if (boost::ends_with(eventLiteral, ".*")) {
+ eventLiteral = eventLiteral.substr(0, eventLiteral.size() - 2);
+ }
+ if (boost::ends_with(eventLiteral, ".")) {
+ eventLiteral = eventLiteral.substr(0, eventLiteral.size() - 1);
+ }
+ std::list<TrieNode*> events =_analyzer->getTrie().getWordsWithPrefix(eventLiteral);
+ for (auto event : events) {
+ stream << " || " << _prefix << EVENT_NAME << " == " << _analyzer->macroForLiteral(event->value);
+ }
+ }
+ stream << ")";
+ }
+ if (HAS_ATTR(_transitions[i], "cond")) {
+ stream << " && " << ADAPT_SRC(ATTR(_transitions[i], "cond"));
+ }
+ stream << ")" << std::endl;
+ }
+
+ stream << " ) -> {" << std::endl;
+
+ stream << " /* remember that we found a transition */" << std::endl;
+ stream << " " << _prefix << "flags[USCXML_CTX_TRANSITION_FOUND] = true;" << std::endl;
+ stream << std::endl;
+
+ stream << " /* transitions that are pre-empted */" << std::endl;
+ stream << " " << _prefix << "TRANS_OR(" << _prefix << "ctx.conflicts, " << _prefix << "transitions[i].conflicts)" << std::endl;
+ stream << std::endl;
+
+ stream << " /* states that are directly targeted (resolve as entry-set later) */" << std::endl;
+ stream << " " << _prefix << "STATES_OR(" << _prefix << "ctx.target_set, " << _prefix << "transitions[i].target)" << std::endl;
+ stream << std::endl;
+
+ stream << " /* states that will be left */" << std::endl;
+ stream << " " << _prefix << "STATES_OR(" << _prefix << "ctx.exit_set, " << _prefix << "transitions[i].exit_set)" << std::endl;
+ stream << std::endl;
+
+ stream << " " << _prefix << "ctx.trans_set[i] = true;" << std::endl;
+
+
+ stream << " }" << std::endl;
+ stream << " :: else {" << std::endl;
+ stream << " skip;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " fi" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> {" << std::endl;
+ stream << " skip;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " fi" << std::endl;
+
+ stream << " i = i + 1;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> break;" << std::endl;
+ stream << " od;" << std::endl;
+
+ stream << " " << _prefix << "STATES_AND(" << _prefix << "ctx.exit_set, " << _prefix << "config)" << std::endl;
+
+ stream << std::endl;
+ stream << "#if TRACE_EXECUTION" << std::endl;
+ stream << "printf(\"Selected Transitions: \");" << std::endl;
+ printBitArray(stream, _prefix + "ctx.trans_set", _transitions.size());
+ stream << "printf(\"\\n\");" << std::endl;
+ stream << "#endif" << std::endl;
+ stream << std::endl;
+ }
+ stream << std::endl;
+ stream << "#if TRACE_EXECUTION" << std::endl;
+ stream << "printf(\"Target Set: \");" << std::endl;
+ printBitArray(stream, _prefix + "ctx.target_set", _states.size());
+ stream << "printf(\"\\n\");" << std::endl;
+ stream << "#endif" << std::endl;
+ stream << std::endl;
+
+ stream << std::endl;
+ stream << "#if TRACE_EXECUTION" << std::endl;
+ stream << "printf(\"Exit Set: \");" << std::endl;
+ printBitArray(stream, _prefix + "ctx.exit_set", _states.size());
+ stream << "printf(\"\\n\");" << std::endl;
+ stream << "#endif" << std::endl;
+ stream << std::endl;
+
+ stream << " if" << std::endl;
+ stream << " :: !" << _prefix << "STATES_HAS_ANY(" << _prefix << "config) -> {" << std::endl;
+ stream << " /* Enter initial configuration */" << std::endl;
+ stream << " " << _prefix << "STATES_COPY(" << _prefix << "ctx.target_set, " << _prefix << "states[0].completion)" << std::endl;
+ stream << " " << _prefix << "flags[USCXML_CTX_SPONTANEOUS] = true;" << std::endl;
+ stream << " " << _prefix << "flags[USCXML_CTX_TRANSITION_FOUND] = true;" << std::endl;
+
+ TRACE_EXECUTION("Entering initial default completion");
+
+ // stream << " goto " << _prefix << "ESTABLISH_ENTRY_SET;" << std::endl;
+ stream << std::endl;
+
+ stream << " }" << std::endl;
+ stream << " :: " << _prefix << "flags[USCXML_CTX_TRANSITION_FOUND] -> {" << std::endl;
+
+ TRACE_EXECUTION("Found transitions");
+
+ stream << " " << _prefix << "flags[USCXML_CTX_SPONTANEOUS] = true;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else {" << std::endl;
+ stream << " " << _prefix << "flags[USCXML_CTX_SPONTANEOUS] = false;" << std::endl;
+
+ TRACE_EXECUTION("Found NO transitions");
+
+ // stream << " goto " << _prefix << "MICROSTEP;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " fi" << std::endl;
+ stream << std::endl;
}
void ChartToPromela::writeFSMRememberHistory(std::ostream& stream) {
- stream << "/* ---------------------------- */" << std::endl;
- stream << "/* REMEMBER_HISTORY: */" << std::endl;
- TRACE_EXECUTION("Save history configurations");
-
- stream << " if" << std::endl;
- stream << " :: " << _prefix << "STATES_HAS_ANY(" << _prefix << "config) -> {" << std::endl;
- stream << " /* only remember history on non-initial entry */" << std::endl;
-
- stream << " i = 0;" << std::endl;
- stream << " do" << std::endl;
- stream << " :: i < " << _prefix << "USCXML_NUMBER_STATES -> {" << std::endl;
-
- stream << " if" << std::endl;
- stream << " :: " << _prefix << "states[i].type[USCXML_STATE_HISTORY_SHALLOW] ||" << std::endl;
- stream << " " << _prefix << "states[i].type[USCXML_STATE_HISTORY_DEEP] -> {" << std::endl;
- stream << " if" << std::endl;
- stream << " :: " << _prefix << "ctx.exit_set[" << _prefix << "states[i].parent] -> {" << std::endl;
-
- stream << " /* a history state whose parent is about to be exited */" << std::endl;
- TRACE_EXECUTION_V("history state %d is about to be exited", "i");
-
- stream << std::endl;
- stream << "#if TRACE_EXECUTION" << std::endl;
- stream << "printf(\"COMPLET: \");" << std::endl;
- printBitArray(stream, _prefix + "states[i].completion", _states.size());
- stream << "printf(\"\\n\");" << std::endl;
- stream << "#endif" << std::endl;
- stream << std::endl;
-
- stream << " " << _prefix << "STATES_COPY(" << _prefix << "ctx.tmp_states, " << _prefix << "states[i].completion)" << std::endl;
-
- stream << std::endl;
- stream << " /* set those states who were enabled */" << std::endl;
- stream << " " << _prefix << "STATES_AND(" << _prefix << "ctx.tmp_states, " << _prefix << "config)" << std::endl;
-
- stream << std::endl;
- stream << "#if TRACE_EXECUTION" << std::endl;
- stream << "printf(\"CONFIG : \");" << std::endl;
- printBitArray(stream, _prefix + "config", _states.size());
- stream << "printf(\"\\n\");" << std::endl;
- stream << "#endif" << std::endl;
- stream << std::endl;
-
- stream << std::endl;
- stream << "#if TRACE_EXECUTION" << std::endl;
- stream << "printf(\"TMP_STS: \");" << std::endl;
- printBitArray(stream, _prefix + "ctx.tmp_states", _states.size());
- stream << "printf(\"\\n\");" << std::endl;
- stream << "#endif" << std::endl;
- stream << std::endl;
-
- stream << std::endl;
- stream << " /* clear current history with completion mask */" << std::endl;
- stream << " " << _prefix << "STATES_AND_NOT(" << _prefix << "history, " << _prefix << "states[i].completion)" << std::endl;
- stream << std::endl;
-
- stream << " /* set history */" << std::endl;
- stream << " " << _prefix << "STATES_OR(" << _prefix << "history, " << _prefix << "ctx.tmp_states)" << std::endl;
-
- stream << std::endl;
-
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi;" << std::endl;
-
- stream << " i = i + 1;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> break;" << std::endl;
- stream << " od;" << std::endl;
- stream << std::endl;
-
- stream << std::endl;
- stream << "#if TRACE_EXECUTION" << std::endl;
- stream << "printf(\"History: \");" << std::endl;
- printBitArray(stream, _prefix + "history", _states.size());
- stream << "printf(\"\\n\");" << std::endl;
- stream << "#endif" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi;" << std::endl;
+ stream << "/* ---------------------------- */" << std::endl;
+ stream << "/* REMEMBER_HISTORY: */" << std::endl;
+ TRACE_EXECUTION("Save history configurations");
+
+ stream << " if" << std::endl;
+ stream << " :: " << _prefix << "STATES_HAS_ANY(" << _prefix << "config) -> {" << std::endl;
+ stream << " /* only remember history on non-initial entry */" << std::endl;
+
+ stream << " i = 0;" << std::endl;
+ stream << " do" << std::endl;
+ stream << " :: i < " << _prefix << "USCXML_NUMBER_STATES -> {" << std::endl;
+
+ stream << " if" << std::endl;
+ stream << " :: " << _prefix << "states[i].type[USCXML_STATE_HISTORY_SHALLOW] ||" << std::endl;
+ stream << " " << _prefix << "states[i].type[USCXML_STATE_HISTORY_DEEP] -> {" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: " << _prefix << "ctx.exit_set[" << _prefix << "states[i].parent] -> {" << std::endl;
+
+ stream << " /* a history state whose parent is about to be exited */" << std::endl;
+ TRACE_EXECUTION_V("history state %d is about to be exited", "i");
+
+ stream << std::endl;
+ stream << "#if TRACE_EXECUTION" << std::endl;
+ stream << "printf(\"COMPLET: \");" << std::endl;
+ printBitArray(stream, _prefix + "states[i].completion", _states.size());
+ stream << "printf(\"\\n\");" << std::endl;
+ stream << "#endif" << std::endl;
+ stream << std::endl;
+
+ stream << " " << _prefix << "STATES_COPY(" << _prefix << "ctx.tmp_states, " << _prefix << "states[i].completion)" << std::endl;
+
+ stream << std::endl;
+ stream << " /* set those states who were enabled */" << std::endl;
+ stream << " " << _prefix << "STATES_AND(" << _prefix << "ctx.tmp_states, " << _prefix << "config)" << std::endl;
+
+ stream << std::endl;
+ stream << "#if TRACE_EXECUTION" << std::endl;
+ stream << "printf(\"CONFIG : \");" << std::endl;
+ printBitArray(stream, _prefix + "config", _states.size());
+ stream << "printf(\"\\n\");" << std::endl;
+ stream << "#endif" << std::endl;
+ stream << std::endl;
+
+ stream << std::endl;
+ stream << "#if TRACE_EXECUTION" << std::endl;
+ stream << "printf(\"TMP_STS: \");" << std::endl;
+ printBitArray(stream, _prefix + "ctx.tmp_states", _states.size());
+ stream << "printf(\"\\n\");" << std::endl;
+ stream << "#endif" << std::endl;
+ stream << std::endl;
+
+ stream << std::endl;
+ stream << " /* clear current history with completion mask */" << std::endl;
+ stream << " " << _prefix << "STATES_AND_NOT(" << _prefix << "history, " << _prefix << "states[i].completion)" << std::endl;
+ stream << std::endl;
+
+ stream << " /* set history */" << std::endl;
+ stream << " " << _prefix << "STATES_OR(" << _prefix << "history, " << _prefix << "ctx.tmp_states)" << std::endl;
+
+ stream << std::endl;
+
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi;" << std::endl;
+
+ stream << " i = i + 1;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> break;" << std::endl;
+ stream << " od;" << std::endl;
+ stream << std::endl;
+
+ stream << std::endl;
+ stream << "#if TRACE_EXECUTION" << std::endl;
+ stream << "printf(\"History: \");" << std::endl;
+ printBitArray(stream, _prefix + "history", _states.size());
+ stream << "printf(\"\\n\");" << std::endl;
+ stream << "#endif" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi;" << std::endl;
}
-
+
void ChartToPromela::writeFSMEstablishEntrySet(std::ostream& stream) {
- stream << "/* ---------------------------- */" << std::endl;
- stream << _prefix << "ESTABLISH_ENTRY_SET:" << std::endl;
- stream << " /* calculate new entry set */" << std::endl;
- stream << " " << _prefix << "STATES_COPY(" << _prefix << "ctx.entry_set, " << _prefix << "ctx.target_set)" << std::endl;
- stream << std::endl;
-
- stream << " i = 0;" << std::endl;
- stream << " do" << std::endl;
- stream << " :: i < " << _prefix << "USCXML_NUMBER_STATES -> {" << std::endl;
-
- stream << " if" << std::endl;
- stream << " :: " << _prefix << "ctx.entry_set[i] -> {" << std::endl;
- stream << " /* ancestor completion */" << std::endl;
- stream << " " << _prefix << "STATES_OR(" << _prefix << "ctx.entry_set, " << _prefix << "states[i].ancestors)" << std::endl;
-
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi;" << std::endl;
-
- stream << " i = i + 1;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> break;" << std::endl;
- stream << " od;" << std::endl;
- stream << std::endl;
-
- stream << " /* iterate for descendants */" << std::endl;
- stream << " i = 0;" << std::endl;
- stream << " do" << std::endl;
- stream << " :: i < " << _prefix << "USCXML_NUMBER_STATES -> {" << std::endl;
- stream << " if" << std::endl;
- stream << " :: " << _prefix << "ctx.entry_set[i] -> {" << std::endl;
- stream << " if" << std::endl;
-
- stream << " :: " << _prefix << "states[i].type[USCXML_STATE_PARALLEL] -> {" << std::endl;
- stream << " " << _prefix << "STATES_OR(" << _prefix << "ctx.entry_set, " << _prefix << "states[i].completion)" << std::endl;
- stream << " }" << std::endl;
-
-
- stream << " :: " << _prefix << "states[i].type[USCXML_STATE_HISTORY_SHALLOW] ||" << std::endl;
- stream << " " << _prefix << "states[i].type[USCXML_STATE_HISTORY_DEEP] -> {" << std::endl;
-
- TRACE_EXECUTION_V("Descendant completion for history state %d", "i")
-
- stream << " if" << std::endl;
- stream << " :: !" << _prefix << "STATES_HAS_AND(" << _prefix << "states[i].completion, " << _prefix << "history)";
- // bit_has_and(stream, _prefix + "states[i].completion", _prefix + "history", _states.size(), 5);
- stream << " && !" << _prefix << "config[" << _prefix << "states[i].parent]" << " -> {" << std::endl;
- stream << " /* nothing set for history, look for a default transition */" << std::endl;
- TRACE_EXECUTION("Fresh history in target set")
- if (_transitions.size() > 0) {
- stream << " j = 0;" << std::endl;
- stream << " do" << std::endl;
- stream << " :: j < " << _prefix << "USCXML_NUMBER_TRANS -> {" << std::endl;
- stream << " if" << std::endl;
- stream << " :: " << _prefix << "transitions[j].source == i -> {" << std::endl;
- stream << " " << _prefix << "ctx.trans_set[j] = true;" << std::endl;
-
- stream << " " << _prefix << "STATES_OR(" << _prefix << "ctx.entry_set, " << _prefix << "transitions[j].target)" << std::endl;
- stream << std::endl;
- stream << " if" << std::endl;
- stream << " :: (" << _prefix << "states[i].type[USCXML_STATE_HISTORY_DEEP] &&" << std::endl;
- stream << " !" << _prefix << "STATES_HAS_AND(" << _prefix << "transitions[j].target, " << _prefix << "states[i].children)";
- // bit_has_and(stream, _prefix + "transitions[j].target", _prefix + "states[i].children", _states.size(), 10);
- stream << " ) -> {" << std::endl;
- stream << " k = i + 1" << std::endl;
- stream << " do" << std::endl;
- stream << " :: k < " << _prefix << "USCXML_NUMBER_STATES -> {" << std::endl;
- stream << " if" << std::endl;
- stream << " :: " << _prefix << "transitions[j].target[k] -> {" << std::endl;
- stream << " " << _prefix << "STATES_OR(" << _prefix << "ctx.entry_set, " << _prefix << "states[k].ancestors)" << std::endl;
- stream << " break;" << std::endl;
- stream << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
- stream << " k = k + 1;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> break;" << std::endl;
- stream << " od" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
- stream << " break;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
- stream << " j = j + 1;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> break" << std::endl;
- stream << " od" << std::endl;
- }
- stream << " skip;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> {" << std::endl;
-
- TRACE_EXECUTION("Established history in target set")
- stream << " " << _prefix << "STATES_COPY(" << _prefix << "ctx.tmp_states, " << _prefix << "states[i].completion)" << std::endl;
- stream << " " << _prefix << "STATES_AND(" << _prefix << "ctx.tmp_states, " << _prefix << "history)" << std::endl;
- stream << " " << _prefix << "STATES_OR(" << _prefix << "ctx.entry_set, " << _prefix << "ctx.tmp_states)" << std::endl;
- stream << " if" << std::endl;
- stream << " :: " << _prefix << "states[i].type[USCXML_STATE_HAS_HISTORY] ||" << std::endl;
- stream << " " << _prefix << "states[i].type[USCXML_STATE_HISTORY_DEEP] -> { " << std::endl;
- stream << " /* a deep history state with nested histories -> more completion */" << std::endl;
- TRACE_EXECUTION("DEEP HISTORY")
- stream << " j = i + 1;" << std::endl;
- stream << " do" << std::endl;
- stream << " :: j < " << _prefix << "USCXML_NUMBER_STATES -> {" << std::endl;
- stream << " if" << std::endl;
- stream << " :: (" << _prefix << "states[i].completion[j] &&" << std::endl;
- stream << " " << _prefix << "ctx.entry_set[j] && " << std::endl;
- stream << " " << _prefix << "states[j].type[USCXML_STATE_HAS_HISTORY]) -> {" << std::endl;
- stream << " k = j + 1;" << std::endl;
- stream << " do" << std::endl;
- stream << " :: k < " << _prefix << "USCXML_NUMBER_STATES -> {" << std::endl;
- stream << " /* add nested history to entry_set */" << std::endl;
- stream << " if" << std::endl;
- stream << " :: (" << _prefix << "states[k].type[USCXML_STATE_HISTORY_DEEP] ||" << std::endl;
- stream << " " << _prefix << "states[k].type[USCXML_STATE_HISTORY_SHALLOW]) &&" << std::endl;
- stream << " " << _prefix << "states[j].children[k] -> {" << std::endl;
- stream << " /* a nested history state */" << std::endl;
- stream << " " << _prefix << "ctx.entry_set[k] = true;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
- stream << " k = k + 1;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> break;" << std::endl;
- stream << " od" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
- stream << " }" << std::endl;
- stream << " j = j + 1;" << std::endl;
- stream << " :: else -> break;" << std::endl;
- stream << " od" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
-
- stream << " }" << std::endl;
- stream << " fi;" << std::endl;
-
- stream << " }" << std::endl;
-
- if (_transitions.size() > 0) {
- stream << " :: " << _prefix << "states[i].type[USCXML_STATE_INITIAL] -> {" << std::endl;
-
- TRACE_EXECUTION_V("Descendant completion for initial state %d", "i")
-
- stream << " j = 0" << std::endl;
- stream << " do" << std::endl;
- stream << " :: j < " << _prefix << "USCXML_NUMBER_TRANS -> {" << std::endl;
- stream << " if" << std::endl;
- stream << " :: " << _prefix << "transitions[j].source == i -> {" << std::endl;
- stream << " " << _prefix << "ctx.trans_set[j] = true;" << std::endl;
- stream << " " << _prefix << "ctx.entry_set[i] = false;" << std::endl;
-
- TRACE_EXECUTION_V("Adding transition %d!", "j");
-
-
- stream << " " << _prefix << "STATES_OR(" << _prefix << "ctx.entry_set, " << _prefix << "transitions[j].target)" << std::endl;
- stream << std::endl;
-
- stream << " k = i + 1;" << std::endl;
- stream << " do" << std::endl;
- stream << " :: k < " << _prefix << "USCXML_NUMBER_STATES -> {" << std::endl;
- stream << " if" << std::endl;
- stream << " :: " << _prefix << "transitions[j].target[k] -> {" << std::endl;
-
- stream << " " << _prefix << "STATES_OR(" << _prefix << "ctx.entry_set, " << _prefix << "states[k].ancestors)" << std::endl;
- stream << std::endl;
-
- stream << " }" << std::endl;
- stream << " :: else -> break;" << std::endl;
- stream << " fi" << std::endl;
- stream << " k = k + 1;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> break" << std::endl;
- stream << " od" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
- stream << " j = j + 1;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> break" << std::endl;
- stream << " od;" << std::endl;
-
- stream << " }" << std::endl;
- }
-
- stream << " :: " << _prefix << "states[i].type[USCXML_STATE_COMPOUND] -> {" << std::endl;
-
- // TRACE_EXECUTION_V("Descendant completion for compound state %d", "i")
-
- stream << " /* we need to check whether one child is already in entry_set */" << std::endl;
- stream << " if" << std::endl;
- stream << " :: (" << std::endl;
- stream << " !" << _prefix << "STATES_HAS_AND(" << _prefix << "ctx.entry_set, " << _prefix << "states[i].children)";
- stream << " && " << std::endl;
- stream << " (!" << _prefix << "STATES_HAS_AND(" << _prefix << "config, " << _prefix << "states[i].children)";
- // bit_has_and(stream, _prefix + "config", _prefix + "states[i].children", _states.size(), 5);
- stream << " || " << _prefix << "STATES_HAS_AND(" << _prefix << "ctx.exit_set, " << _prefix << "states[i].children)" << std::endl;
- stream << ")) " << std::endl;
- stream << " -> {" << std::endl;
-
- stream << " " << _prefix << "STATES_OR(" << _prefix << "ctx.entry_set, " << _prefix << "states[i].completion)" << std::endl;
-
- stream << " if" << std::endl;
- stream << " :: (" << _prefix << "STATES_HAS_AND(" << _prefix << "states[i].completion, " << _prefix << "states[i].children)";
- // bit_has_and(stream, _prefix + "states[i].completion", _prefix + "states[i].children", _states.size(), 6);
- stream << std::endl;
- stream << " ) -> {" << std::endl;
- stream << " /* deep completion */" << std::endl;
- stream << " j = i + 1;" << std::endl;
-
- // TRACE_EXECUTION_V("Deep completion for compound state %d", "i")
-
- stream << " do" << std::endl;
- stream << " :: j < " << _prefix << "USCXML_NUMBER_STATES - 1 -> {" << std::endl;
- stream << " j = j + 1;" << std::endl;
- stream << " if" << std::endl;
- stream << " :: " << _prefix << "states[i].completion[j] -> {" << std::endl;
-
- stream << " " << _prefix << "STATES_OR(" << _prefix << "ctx.entry_set, " << _prefix << "states[j].ancestors)" << std::endl;
- stream << std::endl;
-
- stream << " /* completion of compound is single state */" << std::endl;
- stream << " break;" << std::endl;
- stream << " } " << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> break;" << std::endl;
- stream << " od" << std::endl;
-
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
-
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
- stream << " }" << std::endl;
-
- stream << " :: else -> skip;" << std::endl;
- stream << " fi;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi;" << std::endl;
- stream << " i = i + 1;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> break;" << std::endl;
- stream << " od;" << std::endl;
- stream << std::endl;
-
- stream << std::endl;
- stream << "#if TRACE_EXECUTION" << std::endl;
- stream << "printf(\"Entry Set\");" << std::endl;
- printBitArray(stream, _prefix + "ctx.entry_set", _states.size());
- stream << "printf(\"\\n\");" << std::endl;
- stream << "#endif" << std::endl;
- stream << std::endl;
+ stream << "/* ---------------------------- */" << std::endl;
+ stream << _prefix << "ESTABLISH_ENTRY_SET:" << std::endl;
+ stream << " /* calculate new entry set */" << std::endl;
+ stream << " " << _prefix << "STATES_COPY(" << _prefix << "ctx.entry_set, " << _prefix << "ctx.target_set)" << std::endl;
+ stream << std::endl;
+
+ stream << " i = 0;" << std::endl;
+ stream << " do" << std::endl;
+ stream << " :: i < " << _prefix << "USCXML_NUMBER_STATES -> {" << std::endl;
+
+ stream << " if" << std::endl;
+ stream << " :: " << _prefix << "ctx.entry_set[i] -> {" << std::endl;
+ stream << " /* ancestor completion */" << std::endl;
+ stream << " " << _prefix << "STATES_OR(" << _prefix << "ctx.entry_set, " << _prefix << "states[i].ancestors)" << std::endl;
+
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi;" << std::endl;
+
+ stream << " i = i + 1;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> break;" << std::endl;
+ stream << " od;" << std::endl;
+ stream << std::endl;
+
+ stream << " /* iterate for descendants */" << std::endl;
+ stream << " i = 0;" << std::endl;
+ stream << " do" << std::endl;
+ stream << " :: i < " << _prefix << "USCXML_NUMBER_STATES -> {" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: " << _prefix << "ctx.entry_set[i] -> {" << std::endl;
+ stream << " if" << std::endl;
+
+ stream << " :: " << _prefix << "states[i].type[USCXML_STATE_PARALLEL] -> {" << std::endl;
+ stream << " " << _prefix << "STATES_OR(" << _prefix << "ctx.entry_set, " << _prefix << "states[i].completion)" << std::endl;
+ stream << " }" << std::endl;
+
+
+ stream << " :: " << _prefix << "states[i].type[USCXML_STATE_HISTORY_SHALLOW] ||" << std::endl;
+ stream << " " << _prefix << "states[i].type[USCXML_STATE_HISTORY_DEEP] -> {" << std::endl;
+
+ TRACE_EXECUTION_V("Descendant completion for history state %d", "i")
+
+ stream << " if" << std::endl;
+ stream << " :: !" << _prefix << "STATES_HAS_AND(" << _prefix << "states[i].completion, " << _prefix << "history)";
+ // bit_has_and(stream, _prefix + "states[i].completion", _prefix + "history", _states.size(), 5);
+ stream << " && !" << _prefix << "config[" << _prefix << "states[i].parent]" << " -> {" << std::endl;
+ stream << " /* nothing set for history, look for a default transition */" << std::endl;
+ TRACE_EXECUTION("Fresh history in target set")
+ if (_transitions.size() > 0) {
+ stream << " j = 0;" << std::endl;
+ stream << " do" << std::endl;
+ stream << " :: j < " << _prefix << "USCXML_NUMBER_TRANS -> {" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: " << _prefix << "transitions[j].source == i -> {" << std::endl;
+ stream << " " << _prefix << "ctx.trans_set[j] = true;" << std::endl;
+
+ stream << " " << _prefix << "STATES_OR(" << _prefix << "ctx.entry_set, " << _prefix << "transitions[j].target)" << std::endl;
+ stream << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: (" << _prefix << "states[i].type[USCXML_STATE_HISTORY_DEEP] &&" << std::endl;
+ stream << " !" << _prefix << "STATES_HAS_AND(" << _prefix << "transitions[j].target, " << _prefix << "states[i].children)";
+ // bit_has_and(stream, _prefix + "transitions[j].target", _prefix + "states[i].children", _states.size(), 10);
+ stream << " ) -> {" << std::endl;
+ stream << " k = i + 1" << std::endl;
+ stream << " do" << std::endl;
+ stream << " :: k < " << _prefix << "USCXML_NUMBER_STATES -> {" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: " << _prefix << "transitions[j].target[k] -> {" << std::endl;
+ stream << " " << _prefix << "STATES_OR(" << _prefix << "ctx.entry_set, " << _prefix << "states[k].ancestors)" << std::endl;
+ stream << " break;" << std::endl;
+ stream << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+ stream << " k = k + 1;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> break;" << std::endl;
+ stream << " od" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+ stream << " break;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+ stream << " j = j + 1;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> break" << std::endl;
+ stream << " od" << std::endl;
+ }
+ stream << " skip;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> {" << std::endl;
+
+ TRACE_EXECUTION("Established history in target set")
+ stream << " " << _prefix << "STATES_COPY(" << _prefix << "ctx.tmp_states, " << _prefix << "states[i].completion)" << std::endl;
+ stream << " " << _prefix << "STATES_AND(" << _prefix << "ctx.tmp_states, " << _prefix << "history)" << std::endl;
+ stream << " " << _prefix << "STATES_OR(" << _prefix << "ctx.entry_set, " << _prefix << "ctx.tmp_states)" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: " << _prefix << "states[i].type[USCXML_STATE_HAS_HISTORY] ||" << std::endl;
+ stream << " " << _prefix << "states[i].type[USCXML_STATE_HISTORY_DEEP] -> { " << std::endl;
+ stream << " /* a deep history state with nested histories -> more completion */" << std::endl;
+ TRACE_EXECUTION("DEEP HISTORY")
+ stream << " j = i + 1;" << std::endl;
+ stream << " do" << std::endl;
+ stream << " :: j < " << _prefix << "USCXML_NUMBER_STATES -> {" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: (" << _prefix << "states[i].completion[j] &&" << std::endl;
+ stream << " " << _prefix << "ctx.entry_set[j] && " << std::endl;
+ stream << " " << _prefix << "states[j].type[USCXML_STATE_HAS_HISTORY]) -> {" << std::endl;
+ stream << " k = j + 1;" << std::endl;
+ stream << " do" << std::endl;
+ stream << " :: k < " << _prefix << "USCXML_NUMBER_STATES -> {" << std::endl;
+ stream << " /* add nested history to entry_set */" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: (" << _prefix << "states[k].type[USCXML_STATE_HISTORY_DEEP] ||" << std::endl;
+ stream << " " << _prefix << "states[k].type[USCXML_STATE_HISTORY_SHALLOW]) &&" << std::endl;
+ stream << " " << _prefix << "states[j].children[k] -> {" << std::endl;
+ stream << " /* a nested history state */" << std::endl;
+ stream << " " << _prefix << "ctx.entry_set[k] = true;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+ stream << " k = k + 1;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> break;" << std::endl;
+ stream << " od" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+ stream << " }" << std::endl;
+ stream << " j = j + 1;" << std::endl;
+ stream << " :: else -> break;" << std::endl;
+ stream << " od" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+
+ stream << " }" << std::endl;
+ stream << " fi;" << std::endl;
+
+ stream << " }" << std::endl;
+
+ if (_transitions.size() > 0) {
+ stream << " :: " << _prefix << "states[i].type[USCXML_STATE_INITIAL] -> {" << std::endl;
+
+ TRACE_EXECUTION_V("Descendant completion for initial state %d", "i")
+
+ stream << " j = 0" << std::endl;
+ stream << " do" << std::endl;
+ stream << " :: j < " << _prefix << "USCXML_NUMBER_TRANS -> {" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: " << _prefix << "transitions[j].source == i -> {" << std::endl;
+ stream << " " << _prefix << "ctx.trans_set[j] = true;" << std::endl;
+ stream << " " << _prefix << "ctx.entry_set[i] = false;" << std::endl;
+
+ TRACE_EXECUTION_V("Adding transition %d!", "j");
+
+
+ stream << " " << _prefix << "STATES_OR(" << _prefix << "ctx.entry_set, " << _prefix << "transitions[j].target)" << std::endl;
+ stream << std::endl;
+
+ stream << " k = i + 1;" << std::endl;
+ stream << " do" << std::endl;
+ stream << " :: k < " << _prefix << "USCXML_NUMBER_STATES -> {" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: " << _prefix << "transitions[j].target[k] -> {" << std::endl;
+
+ stream << " " << _prefix << "STATES_OR(" << _prefix << "ctx.entry_set, " << _prefix << "states[k].ancestors)" << std::endl;
+ stream << std::endl;
+
+ stream << " }" << std::endl;
+ stream << " :: else -> break;" << std::endl;
+ stream << " fi" << std::endl;
+ stream << " k = k + 1;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> break" << std::endl;
+ stream << " od" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+ stream << " j = j + 1;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> break" << std::endl;
+ stream << " od;" << std::endl;
+
+ stream << " }" << std::endl;
+ }
+
+ stream << " :: " << _prefix << "states[i].type[USCXML_STATE_COMPOUND] -> {" << std::endl;
+
+ // TRACE_EXECUTION_V("Descendant completion for compound state %d", "i")
+
+ stream << " /* we need to check whether one child is already in entry_set */" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: (" << std::endl;
+ stream << " !" << _prefix << "STATES_HAS_AND(" << _prefix << "ctx.entry_set, " << _prefix << "states[i].children)";
+ stream << " && " << std::endl;
+ stream << " (!" << _prefix << "STATES_HAS_AND(" << _prefix << "config, " << _prefix << "states[i].children)";
+ // bit_has_and(stream, _prefix + "config", _prefix + "states[i].children", _states.size(), 5);
+ stream << " || " << _prefix << "STATES_HAS_AND(" << _prefix << "ctx.exit_set, " << _prefix << "states[i].children)" << std::endl;
+ stream << ")) " << std::endl;
+ stream << " -> {" << std::endl;
+
+ stream << " " << _prefix << "STATES_OR(" << _prefix << "ctx.entry_set, " << _prefix << "states[i].completion)" << std::endl;
+
+ stream << " if" << std::endl;
+ stream << " :: (" << _prefix << "STATES_HAS_AND(" << _prefix << "states[i].completion, " << _prefix << "states[i].children)";
+ // bit_has_and(stream, _prefix + "states[i].completion", _prefix + "states[i].children", _states.size(), 6);
+ stream << std::endl;
+ stream << " ) -> {" << std::endl;
+ stream << " /* deep completion */" << std::endl;
+ stream << " j = i + 1;" << std::endl;
+
+ // TRACE_EXECUTION_V("Deep completion for compound state %d", "i")
+
+ stream << " do" << std::endl;
+ stream << " :: j < " << _prefix << "USCXML_NUMBER_STATES - 1 -> {" << std::endl;
+ stream << " j = j + 1;" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: " << _prefix << "states[i].completion[j] -> {" << std::endl;
+
+ stream << " " << _prefix << "STATES_OR(" << _prefix << "ctx.entry_set, " << _prefix << "states[j].ancestors)" << std::endl;
+ stream << std::endl;
+
+ stream << " /* completion of compound is single state */" << std::endl;
+ stream << " break;" << std::endl;
+ stream << " } " << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> break;" << std::endl;
+ stream << " od" << std::endl;
+
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+ stream << " }" << std::endl;
+
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi;" << std::endl;
+ stream << " i = i + 1;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> break;" << std::endl;
+ stream << " od;" << std::endl;
+ stream << std::endl;
+
+ stream << std::endl;
+ stream << "#if TRACE_EXECUTION" << std::endl;
+ stream << "printf(\"Entry Set\");" << std::endl;
+ printBitArray(stream, _prefix + "ctx.entry_set", _states.size());
+ stream << "printf(\"\\n\");" << std::endl;
+ stream << "#endif" << std::endl;
+ stream << std::endl;
}
void ChartToPromela::writeFSMExitStates(std::ostream& stream) {
- stream << "/* ---------------------------- */" << std::endl;
- stream << "/* EXIT_STATES: */" << std::endl;
- stream << " i = " << _prefix << "USCXML_NUMBER_STATES;" << std::endl;
- stream << " do" << std::endl;
- stream << " :: i > 0 -> {" << std::endl;
- stream << " i = i - 1;" << std::endl;
- stream << " if" << std::endl;
- stream << " :: " << _prefix << "ctx.exit_set[i] && " << _prefix << "config[i] -> {" << std::endl;
- stream << " /* call all on-exit handlers */" << std::endl;
-
- TRACE_EXECUTION_V("Exiting state %d", "i");
-
- stream << " if" << std::endl;
- for (auto i = 0; i < _states.size(); i++) {
- std::list<DOMElement*> onexits = DOMUtils::filterChildElements(XML_PREFIX(_states[i]).str() + "onexit" , _states[i]);
- if (onexits.size() > 0) {
- stream << " :: i == " << toStr(i) << " -> {" << std::endl;
- TRACE_EXECUTION_V("Processing executable content for exiting state %d", "i");
- for (auto onexit : onexits)
- writeExecContent(stream, onexit, 3);
- stream << " }" << std::endl;
- }
- }
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
- stream << std::endl;
-
- stream << " " << _prefix << "config[i] = false;" << std::endl;
- stream << " skip;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> break;" << std::endl;
- stream << " od;" << std::endl;
- stream << std::endl;
+ stream << "/* ---------------------------- */" << std::endl;
+ stream << "/* EXIT_STATES: */" << std::endl;
+ stream << " i = " << _prefix << "USCXML_NUMBER_STATES;" << std::endl;
+ stream << " do" << std::endl;
+ stream << " :: i > 0 -> {" << std::endl;
+ stream << " i = i - 1;" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: " << _prefix << "ctx.exit_set[i] && " << _prefix << "config[i] -> {" << std::endl;
+ stream << " /* call all on-exit handlers */" << std::endl;
+
+ TRACE_EXECUTION_V("Exiting state %d", "i");
+
+ stream << " if" << std::endl;
+ for (auto i = 0; i < _states.size(); i++) {
+ std::list<DOMElement*> onexits = DOMUtils::filterChildElements(XML_PREFIX(_states[i]).str() + "onexit" , _states[i]);
+ if (onexits.size() > 0) {
+ stream << " :: i == " << toStr(i) << " -> {" << std::endl;
+ TRACE_EXECUTION_V("Processing executable content for exiting state %d", "i");
+ for (auto onexit : onexits)
+ writeExecContent(stream, onexit, 3);
+ stream << " }" << std::endl;
+ }
+ }
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+ stream << std::endl;
+
+ stream << " " << _prefix << "config[i] = false;" << std::endl;
+ stream << " skip;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> break;" << std::endl;
+ stream << " od;" << std::endl;
+ stream << std::endl;
}
void ChartToPromela::writeFSMTakeTransitions(std::ostream& stream) {
- stream << "/* ---------------------------- */" << std::endl;
- stream << "/* TAKE_TRANSITIONS: */" << std::endl;
- if (_transitions.size() > 0) {
- stream << " i = 0;" << std::endl;
- stream << " do" << std::endl;
- stream << " :: i < " << _prefix << "USCXML_NUMBER_TRANS -> {" << std::endl;
- stream << " if" << std::endl;
- stream << " :: " << _prefix << "ctx.trans_set[i] && " << std::endl;
- stream << " !" << _prefix << "transitions[i].type[USCXML_TRANS_HISTORY] && " << std::endl;
- stream << " !" << _prefix << "transitions[i].type[USCXML_TRANS_INITIAL] -> {" << std::endl;
- stream << " /* Call executable content in normal transition */" << std::endl;
-
- TRACE_EXECUTION_V("Taking transition %d", "i");
-
- stream << " if" << std::endl;
- for (auto i = 0; i < _transitions.size(); i++) {
- stream << " :: i == " << toStr(i) << " -> {" << std::endl;
- TRACE_EXECUTION_V("Processing executable content for transition %d", "i");
- writeExecContent(stream, _transitions[i], 4);
- stream << " skip;" << std::endl;
- stream << " }" << std::endl;
- }
- stream << " :: else ->skip;" << std::endl;
- stream << " fi" << std::endl;
- stream << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi;" << std::endl;
- stream << " i = i + 1;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> break;" << std::endl;
- stream << " od;" << std::endl;
- }
+ stream << "/* ---------------------------- */" << std::endl;
+ stream << "/* TAKE_TRANSITIONS: */" << std::endl;
+ if (_transitions.size() > 0) {
+ stream << " i = 0;" << std::endl;
+ stream << " do" << std::endl;
+ stream << " :: i < " << _prefix << "USCXML_NUMBER_TRANS -> {" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: " << _prefix << "ctx.trans_set[i] && " << std::endl;
+ stream << " !" << _prefix << "transitions[i].type[USCXML_TRANS_HISTORY] && " << std::endl;
+ stream << " !" << _prefix << "transitions[i].type[USCXML_TRANS_INITIAL] -> {" << std::endl;
+ stream << " /* Call executable content in normal transition */" << std::endl;
+
+ TRACE_EXECUTION_V("Taking transition %d", "i");
+
+ stream << " if" << std::endl;
+ for (auto i = 0; i < _transitions.size(); i++) {
+ stream << " :: i == " << toStr(i) << " -> {" << std::endl;
+ TRACE_EXECUTION_V("Processing executable content for transition %d", "i");
+ writeExecContent(stream, _transitions[i], 4);
+ stream << " skip;" << std::endl;
+ stream << " }" << std::endl;
+ }
+ stream << " :: else ->skip;" << std::endl;
+ stream << " fi" << std::endl;
+ stream << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi;" << std::endl;
+ stream << " i = i + 1;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> break;" << std::endl;
+ stream << " od;" << std::endl;
+ }
}
void ChartToPromela::writeFSMEnterStates(std::ostream& stream) {
- stream << "/* ---------------------------- */" << std::endl;
- stream << "/* ENTER_STATES: */" << std::endl;
- stream << " i = 0;" << std::endl;
- stream << " do" << std::endl;
- stream << " :: i < " << _prefix << "USCXML_NUMBER_STATES -> {" << std::endl;
- stream << " if" << std::endl;
- stream << " :: (" << _prefix << "ctx.entry_set[i] &&" << std::endl;
- stream << " !" << _prefix << "config[i] && " << std::endl;
- stream << " /* these are no proper states */" << std::endl;
- stream << " !" << _prefix << "states[i].type[USCXML_STATE_HISTORY_DEEP] && " << std::endl;
- stream << " !" << _prefix << "states[i].type[USCXML_STATE_HISTORY_SHALLOW] && " << std::endl;
- stream << " !" << _prefix << "states[i].type[USCXML_STATE_INITIAL]" << std::endl;
- stream << " ) -> {" << std::endl;
-
- TRACE_EXECUTION_V("Entering state %d", "i");
-
- stream << " " << _prefix << "config[i] = true;" << std::endl;
- stream << std::endl;
-
+ stream << "/* ---------------------------- */" << std::endl;
+ stream << "/* ENTER_STATES: */" << std::endl;
+ stream << " i = 0;" << std::endl;
+ stream << " do" << std::endl;
+ stream << " :: i < " << _prefix << "USCXML_NUMBER_STATES -> {" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: (" << _prefix << "ctx.entry_set[i] &&" << std::endl;
+ stream << " !" << _prefix << "config[i] && " << std::endl;
+ stream << " /* these are no proper states */" << std::endl;
+ stream << " !" << _prefix << "states[i].type[USCXML_STATE_HISTORY_DEEP] && " << std::endl;
+ stream << " !" << _prefix << "states[i].type[USCXML_STATE_HISTORY_SHALLOW] && " << std::endl;
+ stream << " !" << _prefix << "states[i].type[USCXML_STATE_INITIAL]" << std::endl;
+ stream << " ) -> {" << std::endl;
+
+ TRACE_EXECUTION_V("Entering state %d", "i");
+
+ stream << " " << _prefix << "config[i] = true;" << std::endl;
+ stream << std::endl;
+
#if 0
- stream << " if" << std::endl;
- stream << " :: !" << _prefix << "initialized_data[i] -> {" << std::endl;
- stream << " /* TODO: late data binding not supported yet */" << std::endl;
- stream << " " << _prefix << "initialized_data[i] = true;" << std::endl;
- stream << " skip" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
- stream << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: !" << _prefix << "initialized_data[i] -> {" << std::endl;
+ stream << " /* TODO: late data binding not supported yet */" << std::endl;
+ stream << " " << _prefix << "initialized_data[i] = true;" << std::endl;
+ stream << " skip" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+ stream << std::endl;
#endif
-
- stream << " /* Process executable content for entering a state */" << std::endl;
- stream << " if" << std::endl;
- for (auto i = 0; i < _states.size(); i++) {
- std::list<DOMElement*> onentries = DOMUtils::filterChildElements(XML_PREFIX(_states[i]).str() + "onentry" , _states[i]);
- if (onentries.size() > 0) {
- stream << " :: i == " << toStr(i) << " -> {" << std::endl;
- TRACE_EXECUTION_V("Processing executable content for entering state %d", "i");
- for (auto onentry : onentries)
- writeExecContent(stream, onentry, 5);
- stream << " }" << std::endl;
- }
- }
- stream << " :: else ->skip;" << std::endl;
- stream << " fi" << std::endl;
- stream << std::endl;
-
- stream << " /* take history and initial transitions */" << std::endl;
- if (_transitions.size() > 0) {
- stream << " j = 0;" << std::endl;
- stream << " do" << std::endl;
- stream << " :: j < " << _prefix << "USCXML_NUMBER_TRANS -> {" << std::endl;
- stream << " if" << std::endl;
- stream << " :: (" << _prefix << "ctx.trans_set[j] &&" << std::endl;
- stream << " (" << _prefix << "transitions[j].type[USCXML_TRANS_HISTORY] ||" << std::endl;
- stream << " " << _prefix << "transitions[j].type[USCXML_TRANS_INITIAL]) && " << std::endl;
- stream << " " << _prefix << "states[" << _prefix << "transitions[j].source].parent == i) -> {" << std::endl;
- stream << " /* Call executable content in history or initial transition */" << std::endl;
- stream << " if" << std::endl;
- for (auto i = 0; i < _transitions.size(); i++) {
- stream << " :: j == " << toStr(i) << " -> {" << std::endl;
- TRACE_EXECUTION_V("Processing executable content for transition %d", "j");
-
- writeExecContent(stream, _transitions[i], 8);
- stream << " skip;" << std::endl;
- stream << " }" << std::endl;
- }
- stream << " :: else ->skip;" << std::endl;
- stream << " fi" << std::endl;
- stream << std::endl;
-
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
- stream << " j = j + 1;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> break;" << std::endl;
- stream << " od" << std::endl;
- }
-
- stream << " /* handle final states */" << std::endl;
- stream << " if" << std::endl;
- stream << " :: " << _prefix << "states[i].type[USCXML_STATE_FINAL] -> {" << std::endl;
-
- stream << " if" << std::endl;
- stream << " :: " << _prefix << "states[" << _prefix << "states[i].parent].children[1] -> {" << std::endl;
- stream << " /* exit topmost SCXML state */" << std::endl;
- stream << " " << _prefix << "flags[USCXML_CTX_TOP_LEVEL_FINAL] = true;" << std::endl;
- stream << " " << _prefix << "flags[USCXML_CTX_FINISHED] = true;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> {" << std::endl;
- stream << " /* raise done event */" << std::endl;
- stream << " if" << std::endl;
-
- std::string insertOp = "!";
- // if (_analyzer->usesEventField("delay"))
- // insertOp += "!";
-
- for (auto state : _states) {
- if (state->getParentNode() == NULL || state->getParentNode()->getNodeType() != DOMNode::ELEMENT_NODE)
- continue;
-
- if (!isFinal(state))
- continue;
-
- DOMElement* parent = static_cast<DOMElement*>(state->getParentNode());
- if (!HAS_ATTR(parent, "id"))
- continue;
-
- std::string doneEvent = _analyzer->macroForLiteral("done.state." + ATTR_CAST(state->getParentNode(), "id"));
-
- stream << " :: (i == " << ATTR(state, "documentOrder") << ") -> {" << std::endl;
-
- if (_analyzer->usesComplexEventStruct()) {
- std::string typeReset = _analyzer->getTypeReset(_prefix + "_tmpE", _analyzer->getType("_event"), 7);
- stream << typeReset << std::endl;
- stream << " " << _prefix << "_tmpE.name = " << doneEvent << ";" << std::endl;
-
- std::list<DOMElement*> donedatas = DOMUtils::filterChildElements(XML_PREFIX(state).str() + "donedata" , state);
- if (donedatas.size() > 0) {
- writeRaiseDoneDate(stream, donedatas.front(), 8);
- }
-
- doneEvent = _prefix + "_tmpE";
- }
-
-
- stream << " " << _prefix << "iQ" << insertOp << doneEvent << ";" << std::endl;
- stream << " }" << std::endl;
-
- }
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
-
- stream << " }" << std::endl;
- stream << " fi" << std::endl;
-
- stream << " /**" << std::endl;
- stream << " * are we the last final state to leave a parallel state?:" << std::endl;
- stream << " * 1. Gather all parallel states in our ancestor chain" << std::endl;
- stream << " * 2. Find all states for which these parallels are ancestors" << std::endl;
- stream << " * 3. Iterate all active final states and remove their ancestors" << std::endl;
- stream << " * 4. If a state remains, not all children of a parallel are final" << std::endl;
- stream << " */" << std::endl;
- stream << " j = 0;" << std::endl;
- stream << " do" << std::endl;
- stream << " :: j < " << _prefix << "USCXML_NUMBER_STATES -> {" << std::endl;
- stream << " if" << std::endl;
- stream << " :: " << _prefix << "states[j].type[USCXML_STATE_PARALLEL] && " << _prefix << "states[i].ancestors[j] -> {" << std::endl;
- stream << " " << _prefix << "STATES_CLEAR(" << _prefix << "ctx.tmp_states)" << std::endl;
-
- stream << " k = 0;" << std::endl;
- stream << " do" << std::endl;
- stream << " :: k < " << _prefix << "USCXML_NUMBER_STATES -> {" << std::endl;
- stream << " if" << std::endl;
- stream << " :: " << _prefix << "states[k].ancestors[j] && " << _prefix << "config[k] -> {" << std::endl;
- stream << " if" << std::endl;
- stream << " :: " << _prefix << "states[k].type[USCXML_STATE_FINAL] -> {" << std::endl;
-
- stream << " " << _prefix << "STATES_AND_NOT(" << _prefix << "ctx.tmp_states, " << _prefix << "states[k].ancestors)" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> {" << std::endl;
-
- stream << " " << _prefix << "ctx.tmp_states[k] = true;" << std::endl;
- stream << " }" << std::endl;
- stream << " fi" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
- stream << " k = k + 1;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> break;" << std::endl;
- stream << " od" << std::endl;
- stream << " if" << std::endl;
- stream << " :: !" << _prefix << "STATES_HAS_ANY(" << _prefix << "ctx.tmp_states) -> {" << std::endl;
- stream << " if" << std::endl;
-
- for (auto state : _states) {
- if (isParallel(state) && HAS_ATTR(state, "id")) {
- stream << " :: j == " << toStr(ATTR(state, "documentOrder")) << " -> {" << std::endl;
-
- std::string doneEvent = _analyzer->macroForLiteral("done.state." + ATTR(state, "id"));
-
- if (_analyzer->usesComplexEventStruct()) {
- std::string typeReset = _analyzer->getTypeReset(_prefix + "_tmpE", _analyzer->getType("_event"), 10);
- stream << typeReset << std::endl;
- stream << " " << _prefix << "_tmpE.name = " << doneEvent << ";" << std::endl;
-
- std::list<DOMElement*> donedatas = DOMUtils::filterChildElements(XML_PREFIX(state).str() + "donedata" , state);
- if (donedatas.size() > 0) {
- writeRaiseDoneDate(stream, donedatas.front(), 11);
- }
- doneEvent = _prefix + "_tmpE";
- }
-
- stream << " " << _prefix << "iQ" << insertOp << doneEvent << ";" << std::endl;
- stream << " }" << std::endl;
- }
- }
-
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
-
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
- stream << " j = j + 1;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> break;" << std::endl;
- stream << " od" << std::endl;
-
-
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
-
- stream << std::endl;
-
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " i = i + 1;" << std::endl;
- stream << " fi;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> break;" << std::endl;
- stream << " od;" << std::endl;
+
+ stream << " /* Process executable content for entering a state */" << std::endl;
+ stream << " if" << std::endl;
+ for (auto i = 0; i < _states.size(); i++) {
+ std::list<DOMElement*> onentries = DOMUtils::filterChildElements(XML_PREFIX(_states[i]).str() + "onentry" , _states[i]);
+ if (onentries.size() > 0) {
+ stream << " :: i == " << toStr(i) << " -> {" << std::endl;
+ TRACE_EXECUTION_V("Processing executable content for entering state %d", "i");
+ for (auto onentry : onentries)
+ writeExecContent(stream, onentry, 5);
+ stream << " }" << std::endl;
+ }
+ }
+ stream << " :: else ->skip;" << std::endl;
+ stream << " fi" << std::endl;
+ stream << std::endl;
+
+ stream << " /* take history and initial transitions */" << std::endl;
+ if (_transitions.size() > 0) {
+ stream << " j = 0;" << std::endl;
+ stream << " do" << std::endl;
+ stream << " :: j < " << _prefix << "USCXML_NUMBER_TRANS -> {" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: (" << _prefix << "ctx.trans_set[j] &&" << std::endl;
+ stream << " (" << _prefix << "transitions[j].type[USCXML_TRANS_HISTORY] ||" << std::endl;
+ stream << " " << _prefix << "transitions[j].type[USCXML_TRANS_INITIAL]) && " << std::endl;
+ stream << " " << _prefix << "states[" << _prefix << "transitions[j].source].parent == i) -> {" << std::endl;
+ stream << " /* Call executable content in history or initial transition */" << std::endl;
+ stream << " if" << std::endl;
+ for (auto i = 0; i < _transitions.size(); i++) {
+ stream << " :: j == " << toStr(i) << " -> {" << std::endl;
+ TRACE_EXECUTION_V("Processing executable content for transition %d", "j");
+
+ writeExecContent(stream, _transitions[i], 8);
+ stream << " skip;" << std::endl;
+ stream << " }" << std::endl;
+ }
+ stream << " :: else ->skip;" << std::endl;
+ stream << " fi" << std::endl;
+ stream << std::endl;
+
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+ stream << " j = j + 1;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> break;" << std::endl;
+ stream << " od" << std::endl;
+ }
+
+ stream << " /* handle final states */" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: " << _prefix << "states[i].type[USCXML_STATE_FINAL] -> {" << std::endl;
+
+ stream << " if" << std::endl;
+ stream << " :: " << _prefix << "states[" << _prefix << "states[i].parent].children[1] -> {" << std::endl;
+ stream << " /* exit topmost SCXML state */" << std::endl;
+ stream << " " << _prefix << "flags[USCXML_CTX_TOP_LEVEL_FINAL] = true;" << std::endl;
+ stream << " " << _prefix << "flags[USCXML_CTX_FINISHED] = true;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> {" << std::endl;
+ stream << " /* raise done event */" << std::endl;
+ stream << " if" << std::endl;
+
+ std::string insertOp = "!";
+ // if (_analyzer->usesEventField("delay"))
+ // insertOp += "!";
+
+ for (auto state : _states) {
+ if (state->getParentNode() == NULL || state->getParentNode()->getNodeType() != DOMNode::ELEMENT_NODE)
+ continue;
+
+ if (!isFinal(state))
+ continue;
+
+ DOMElement* parent = static_cast<DOMElement*>(state->getParentNode());
+ if (!HAS_ATTR(parent, "id"))
+ continue;
+
+ std::string doneEvent = _analyzer->macroForLiteral("done.state." + ATTR_CAST(state->getParentNode(), "id"));
+
+ stream << " :: (i == " << ATTR(state, "documentOrder") << ") -> {" << std::endl;
+
+ if (_analyzer->usesComplexEventStruct()) {
+ std::string typeReset = _analyzer->getTypeReset(_prefix + "_tmpE", _analyzer->getType("_event"), 7);
+ stream << typeReset << std::endl;
+ stream << " " << _prefix << "_tmpE.name = " << doneEvent << ";" << std::endl;
+
+ std::list<DOMElement*> donedatas = DOMUtils::filterChildElements(XML_PREFIX(state).str() + "donedata" , state);
+ if (donedatas.size() > 0) {
+ writeRaiseDoneDate(stream, donedatas.front(), 8);
+ }
+
+ doneEvent = _prefix + "_tmpE";
+ }
+
+
+ stream << " " << _prefix << "iQ" << insertOp << doneEvent << ";" << std::endl;
+ stream << " }" << std::endl;
+
+ }
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+
+ stream << " }" << std::endl;
+ stream << " fi" << std::endl;
+
+ stream << " /**" << std::endl;
+ stream << " * are we the last final state to leave a parallel state?:" << std::endl;
+ stream << " * 1. Gather all parallel states in our ancestor chain" << std::endl;
+ stream << " * 2. Find all states for which these parallels are ancestors" << std::endl;
+ stream << " * 3. Iterate all active final states and remove their ancestors" << std::endl;
+ stream << " * 4. If a state remains, not all children of a parallel are final" << std::endl;
+ stream << " */" << std::endl;
+ stream << " j = 0;" << std::endl;
+ stream << " do" << std::endl;
+ stream << " :: j < " << _prefix << "USCXML_NUMBER_STATES -> {" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: " << _prefix << "states[j].type[USCXML_STATE_PARALLEL] && " << _prefix << "states[i].ancestors[j] -> {" << std::endl;
+ stream << " " << _prefix << "STATES_CLEAR(" << _prefix << "ctx.tmp_states)" << std::endl;
+
+ stream << " k = 0;" << std::endl;
+ stream << " do" << std::endl;
+ stream << " :: k < " << _prefix << "USCXML_NUMBER_STATES -> {" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: " << _prefix << "states[k].ancestors[j] && " << _prefix << "config[k] -> {" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: " << _prefix << "states[k].type[USCXML_STATE_FINAL] -> {" << std::endl;
+
+ stream << " " << _prefix << "STATES_AND_NOT(" << _prefix << "ctx.tmp_states, " << _prefix << "states[k].ancestors)" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> {" << std::endl;
+
+ stream << " " << _prefix << "ctx.tmp_states[k] = true;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " fi" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+ stream << " k = k + 1;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> break;" << std::endl;
+ stream << " od" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: !" << _prefix << "STATES_HAS_ANY(" << _prefix << "ctx.tmp_states) -> {" << std::endl;
+ stream << " if" << std::endl;
+
+ for (auto state : _states) {
+ if (isParallel(state) && HAS_ATTR(state, "id")) {
+ stream << " :: j == " << toStr(ATTR(state, "documentOrder")) << " -> {" << std::endl;
+
+ std::string doneEvent = _analyzer->macroForLiteral("done.state." + ATTR(state, "id"));
+
+ if (_analyzer->usesComplexEventStruct()) {
+ std::string typeReset = _analyzer->getTypeReset(_prefix + "_tmpE", _analyzer->getType("_event"), 10);
+ stream << typeReset << std::endl;
+ stream << " " << _prefix << "_tmpE.name = " << doneEvent << ";" << std::endl;
+
+ std::list<DOMElement*> donedatas = DOMUtils::filterChildElements(XML_PREFIX(state).str() + "donedata" , state);
+ if (donedatas.size() > 0) {
+ writeRaiseDoneDate(stream, donedatas.front(), 11);
+ }
+ doneEvent = _prefix + "_tmpE";
+ }
+
+ stream << " " << _prefix << "iQ" << insertOp << doneEvent << ";" << std::endl;
+ stream << " }" << std::endl;
+ }
+ }
+
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+ stream << " j = j + 1;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> break;" << std::endl;
+ stream << " od" << std::endl;
+
+
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+
+ stream << std::endl;
+
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " i = i + 1;" << std::endl;
+ stream << " fi;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> break;" << std::endl;
+ stream << " od;" << std::endl;
}
void ChartToPromela::writeFSMTerminateMachine(std::ostream& stream) {
- stream << "/* ---------------------------- */" << std::endl;
- stream << _prefix << "TERMINATE_MACHINE:" << std::endl;
-
- stream << "skip; d_step {" << std::endl;
-
- TRACE_EXECUTION("Machine finished");
-
- stream << "/* exit all remaining states */" << std::endl;
- stream << "i = " << _prefix << "USCXML_NUMBER_STATES;" << std::endl;
- stream << "do" << std::endl;
- stream << ":: i > 0 -> {" << std::endl;
- stream << " i = i - 1;" << std::endl;
- stream << " if" << std::endl;
- stream << " :: " << _prefix << "config[i] && " << _prefix << "flags[USCXML_CTX_TOP_LEVEL_FINAL] -> {" << std::endl;
- stream << " /* call all on exit handlers */" << std::endl;
- stream << " if" << std::endl;
- for (auto i = 0; i < _states.size(); i++) {
- std::list<DOMElement*> onentries = DOMUtils::filterChildElements(XML_PREFIX(_states[i]).str() + "onexit" , _states[i]);
- if (onentries.size() > 0) {
- stream << " :: i == " << toStr(i) << " -> {" << std::endl;
- TRACE_EXECUTION_V("Processing executable content for exiting state %d", "i");
- for (auto onentry : onentries)
- writeExecContent(stream, onentry, 2);
- stream << " }" << std::endl;
- }
- }
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
- stream << std::endl;
- stream << " skip;" << std::endl;
- stream << " " << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi;" << std::endl;
- stream << std::endl;
-
- stream << " if" << std::endl;
- stream << " :: " << _prefix << "invocations[i] -> {" << std::endl;
- stream << " /* cancel invocations */" << std::endl;
- stream << " " << _prefix << "invocations[i] = false;" << std::endl;
- stream << " if" << std::endl;
-
- for (auto machine : _machinesNested) {
- stream << " :: i == " << ATTR_CAST(machine.first->getParentNode(), "documentOrder") << " -> {" << std::endl;
- stream << " " << machine.second->_prefix << "flags[USCXML_CTX_FINISHED] = true;" << std::endl;
- stream << " }" << std::endl;
- }
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
-
- stream << " skip;" << std::endl;
- stream << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi;" << std::endl;
- stream << "}" << std::endl;
- stream << ":: else -> break;" << std::endl;
- stream << "od;" << std::endl;
-
- stream << std::endl;
-
- if (_machinesAll->size() > 1 && _analyzer->usesEventField("delay")) {
- /* TODO: We nee to clear all events if we were canceled */
- TRACE_EXECUTION("Removing pending events");
- stream << "removePendingEventsFromInvoker(" << _analyzer->macroForLiteral(_invokerid) << ")" << std::endl;
- }
-
-
- if (_parent != NULL) {
- stream << "/* send done event */" << std::endl;
- stream << "if" << std::endl;
- stream << ":: " << _prefix << "flags[USCXML_CTX_TOP_LEVEL_FINAL] -> {" << std::endl;
-
- if (_analyzer->usesComplexEventStruct()) {
- std::string typeReset = _analyzer->getTypeReset(_prefix + "_tmpE", _analyzer->getType("_event"), 2);
- stream << typeReset << std::endl;
- stream << " " << _prefix << "_tmpE.name = " << _analyzer->macroForLiteral("done.invoke." + _invokerid) << std::endl;
-
- if (_analyzer->usesEventField("invokeid")) {
- stream << " " << _prefix << "_tmpE.invokeid = " << _analyzer->macroForLiteral(_invokerid) << std::endl;
- }
-
- } else {
- stream << " " << _prefix << "_tmpE = " << _analyzer->macroForLiteral("done.invoke." + _invokerid) << std::endl;
- }
-
-
- TRACE_EXECUTION("Sending DONE.INVOKE");
-
- stream << " " << _parent->_prefix << "eQ!" << _prefix << "_tmpE;" << std::endl;
- if (_analyzer->usesEventField("delay")) {
- stream << " insertWithDelay(" << _parent->_prefix << "eQ);" << std::endl;
- }
- stream << "}" << std::endl;
- stream << ":: else -> skip" << std::endl;
- stream << "fi;" << std::endl;
- stream << std::endl;
-
- }
- stream << "} /* d_step */" << std::endl;
+ stream << "/* ---------------------------- */" << std::endl;
+ stream << _prefix << "TERMINATE_MACHINE:" << std::endl;
+
+ stream << "skip; d_step {" << std::endl;
+
+ TRACE_EXECUTION("Machine finished");
+
+ stream << "/* exit all remaining states */" << std::endl;
+ stream << "i = " << _prefix << "USCXML_NUMBER_STATES;" << std::endl;
+ stream << "do" << std::endl;
+ stream << ":: i > 0 -> {" << std::endl;
+ stream << " i = i - 1;" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: " << _prefix << "config[i] && " << _prefix << "flags[USCXML_CTX_TOP_LEVEL_FINAL] -> {" << std::endl;
+ stream << " /* call all on exit handlers */" << std::endl;
+ stream << " if" << std::endl;
+ for (auto i = 0; i < _states.size(); i++) {
+ std::list<DOMElement*> onentries = DOMUtils::filterChildElements(XML_PREFIX(_states[i]).str() + "onexit" , _states[i]);
+ if (onentries.size() > 0) {
+ stream << " :: i == " << toStr(i) << " -> {" << std::endl;
+ TRACE_EXECUTION_V("Processing executable content for exiting state %d", "i");
+ for (auto onentry : onentries)
+ writeExecContent(stream, onentry, 2);
+ stream << " }" << std::endl;
+ }
+ }
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+ stream << std::endl;
+ stream << " skip;" << std::endl;
+ stream << " " << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi;" << std::endl;
+ stream << std::endl;
+
+ stream << " if" << std::endl;
+ stream << " :: " << _prefix << "invocations[i] -> {" << std::endl;
+ stream << " /* cancel invocations */" << std::endl;
+ stream << " " << _prefix << "invocations[i] = false;" << std::endl;
+ stream << " if" << std::endl;
+
+ for (auto machine : _machinesNested) {
+ stream << " :: i == " << ATTR_CAST(machine.first->getParentNode(), "documentOrder") << " -> {" << std::endl;
+ stream << " " << machine.second->_prefix << "flags[USCXML_CTX_FINISHED] = true;" << std::endl;
+ stream << " }" << std::endl;
+ }
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+
+ stream << " skip;" << std::endl;
+ stream << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi;" << std::endl;
+ stream << "}" << std::endl;
+ stream << ":: else -> break;" << std::endl;
+ stream << "od;" << std::endl;
+
+ stream << std::endl;
+
+ if (_machinesAll->size() > 1 && _analyzer->usesEventField("delay")) {
+ /* TODO: We nee to clear all events if we were canceled */
+ TRACE_EXECUTION("Removing pending events");
+ stream << "removePendingEventsFromInvoker(" << _analyzer->macroForLiteral(_invokerid) << ")" << std::endl;
+ }
+
+
+ if (_parent != NULL) {
+ stream << "/* send done event */" << std::endl;
+ stream << "if" << std::endl;
+ stream << ":: " << _prefix << "flags[USCXML_CTX_TOP_LEVEL_FINAL] -> {" << std::endl;
+
+ if (_analyzer->usesComplexEventStruct()) {
+ std::string typeReset = _analyzer->getTypeReset(_prefix + "_tmpE", _analyzer->getType("_event"), 2);
+ stream << typeReset << std::endl;
+ stream << " " << _prefix << "_tmpE.name = " << _analyzer->macroForLiteral("done.invoke." + _invokerid) << std::endl;
+
+ if (_analyzer->usesEventField("invokeid")) {
+ stream << " " << _prefix << "_tmpE.invokeid = " << _analyzer->macroForLiteral(_invokerid) << std::endl;
+ }
+
+ } else {
+ stream << " " << _prefix << "_tmpE = " << _analyzer->macroForLiteral("done.invoke." + _invokerid) << std::endl;
+ }
+
+
+ TRACE_EXECUTION("Sending DONE.INVOKE");
+
+ stream << " " << _parent->_prefix << "eQ!" << _prefix << "_tmpE;" << std::endl;
+ if (_analyzer->usesEventField("delay")) {
+ stream << " insertWithDelay(" << _parent->_prefix << "eQ);" << std::endl;
+ }
+ stream << "}" << std::endl;
+ stream << ":: else -> skip" << std::endl;
+ stream << "fi;" << std::endl;
+ stream << std::endl;
+
+ }
+ stream << "} /* d_step */" << std::endl;
}
-
+
void ChartToPromela::writeIfBlock(std::ostream& stream, std::list<DOMElement*>& condChain, size_t indent) {
if (condChain.size() == 0)
return;
@@ -2884,332 +2884,332 @@ std::string ChartToPromela::declForRange(const std::string& identifier, long min
}
void ChartToPromela::writeDetermineShortestDelay(std::ostream& stream, int indent) {
- std::string padding;
- for (size_t i = 0; i < indent; i++) {
- padding += " ";
- }
-
- stream << padding << "inline determineSmallestDelay(smallestDelay, queue) {" << std::endl;
- // stream << padding << _analyzer->getTypeReset("tmpE", _analyzer->getType("_event"), " ");
- stream << padding << " if" << std::endl;
- stream << padding << " :: len(queue) > 0 -> {" << std::endl;
- stream << padding << " queue?<tmpE>;" << std::endl;
- stream << padding << " if" << std::endl;
- stream << padding << " :: (tmpE.delay < smallestDelay) -> { smallestDelay = tmpE.delay; }" << std::endl;
- stream << padding << " :: else -> skip;" << std::endl;
- stream << padding << " fi;" << std::endl;
- stream << padding << " }" << std::endl;
- stream << padding << " :: else -> skip;" << std::endl;
- stream << padding << " fi;" << std::endl;
- stream << padding << "}" << std::endl;
+ std::string padding;
+ for (size_t i = 0; i < indent; i++) {
+ padding += " ";
+ }
+
+ stream << padding << "inline determineSmallestDelay(smallestDelay, queue) {" << std::endl;
+ // stream << padding << _analyzer->getTypeReset("tmpE", _analyzer->getType("_event"), " ");
+ stream << padding << " if" << std::endl;
+ stream << padding << " :: len(queue) > 0 -> {" << std::endl;
+ stream << padding << " queue?<tmpE>;" << std::endl;
+ stream << padding << " if" << std::endl;
+ stream << padding << " :: (tmpE.delay < smallestDelay) -> { smallestDelay = tmpE.delay; }" << std::endl;
+ stream << padding << " :: else -> skip;" << std::endl;
+ stream << padding << " fi;" << std::endl;
+ stream << padding << " }" << std::endl;
+ stream << padding << " :: else -> skip;" << std::endl;
+ stream << padding << " fi;" << std::endl;
+ stream << padding << "}" << std::endl;
}
void ChartToPromela::writeScheduleMachines(std::ostream& stream, int indent) {
- std::string padding;
- for (size_t i = 0; i < indent; i++) {
- padding += " ";
- }
-
- stream << padding << "inline scheduleMachines() {" << std::endl;
- std::list<std::string> queues;
- queues.push_back("eQ");
-
- if (_allowEventInterleaving)
- queues.push_back("tmpQ");
-
- stream << " /* schedule state-machines with regard to their event's delay */" << std::endl;
- stream << " skip;" << std::endl;
- stream << " d_step {" << std::endl;
-
- stream << std::endl << "/* determine smallest delay */" << std::endl;
- stream << " int smallestDelay = 2147483647;" << std::endl;
-
- for (auto machine : *_machinesAll) {
- for (auto queue : queues) {
- stream << " determineSmallestDelay(smallestDelay, " << machine.second->_prefix << queue << ");" << std::endl;
- }
- }
-
- TRACE_EXECUTION_V("Smallest delay is %d", "smallestDelay");
-
- stream << std::endl << "/* prioritize processes with lowest delay or internal events */" << std::endl;
-
- for (auto machine : *_machinesAll) {
- stream << " rescheduleProcess(smallestDelay, "
- << machine.second->_prefix << "procid, "
- << machine.second->_prefix << "iQ, "
- << machine.second->_prefix << "eQ";
- if (_allowEventInterleaving) {
- stream << ", " << machine.second->_prefix << "tmpQ);" << std::endl;
- } else {
- stream << ");" << std::endl;
- }
- }
-
- stream << std::endl << "/* advance time by subtracting the smallest delay from all event delays */" << std::endl;
- stream << " if" << std::endl;
- stream << " :: (smallestDelay > 0) -> {" << std::endl;
- for (auto machine : *_machinesAll) {
- for (auto queue : queues) {
- stream << " advanceTime(smallestDelay, " << machine.second->_prefix << queue << ");" << std::endl;
- }
- }
- stream << " }" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi;" << std::endl;
- stream << " }" << std::endl;
- stream << " set_priority(_pid, 10);" << std::endl << std::endl;
- stream << padding << "}" << std::endl;
+ std::string padding;
+ for (size_t i = 0; i < indent; i++) {
+ padding += " ";
+ }
+
+ stream << padding << "inline scheduleMachines() {" << std::endl;
+ std::list<std::string> queues;
+ queues.push_back("eQ");
+
+ if (_allowEventInterleaving)
+ queues.push_back("tmpQ");
+
+ stream << " /* schedule state-machines with regard to their event's delay */" << std::endl;
+ stream << " skip;" << std::endl;
+ stream << " d_step {" << std::endl;
+
+ stream << std::endl << "/* determine smallest delay */" << std::endl;
+ stream << " int smallestDelay = 2147483647;" << std::endl;
+
+ for (auto machine : *_machinesAll) {
+ for (auto queue : queues) {
+ stream << " determineSmallestDelay(smallestDelay, " << machine.second->_prefix << queue << ");" << std::endl;
+ }
+ }
+
+ TRACE_EXECUTION_V("Smallest delay is %d", "smallestDelay");
+
+ stream << std::endl << "/* prioritize processes with lowest delay or internal events */" << std::endl;
+
+ for (auto machine : *_machinesAll) {
+ stream << " rescheduleProcess(smallestDelay, "
+ << machine.second->_prefix << "procid, "
+ << machine.second->_prefix << "iQ, "
+ << machine.second->_prefix << "eQ";
+ if (_allowEventInterleaving) {
+ stream << ", " << machine.second->_prefix << "tmpQ);" << std::endl;
+ } else {
+ stream << ");" << std::endl;
+ }
+ }
+
+ stream << std::endl << "/* advance time by subtracting the smallest delay from all event delays */" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: (smallestDelay > 0) -> {" << std::endl;
+ for (auto machine : *_machinesAll) {
+ for (auto queue : queues) {
+ stream << " advanceTime(smallestDelay, " << machine.second->_prefix << queue << ");" << std::endl;
+ }
+ }
+ stream << " }" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " set_priority(_pid, 10);" << std::endl << std::endl;
+ stream << padding << "}" << std::endl;
}
void ChartToPromela::writeAdvanceTime(std::ostream& stream, int indent) {
- std::string padding;
- for (size_t i = 0; i < indent; i++) {
- padding += " ";
- }
-
- stream << padding << "inline advanceTime(increment, queue) {" << std::endl;
- stream << padding << " tmpIndex = 0;" << std::endl;
- stream << padding << " do" << std::endl;
- stream << padding << " :: tmpIndex < len(queue) -> {" << std::endl;
- stream << padding << " queue?tmpE;" << std::endl;
- stream << padding << " if" << std::endl;
- stream << padding << " :: tmpE.delay >= increment -> tmpE.delay = tmpE.delay - increment;" << std::endl;
- stream << padding << " :: else -> skip;" << std::endl;
- stream << padding << " fi" << std::endl;
- stream << padding << " queue!tmpE;" << std::endl;
- stream << padding << " tmpIndex++;" << std::endl;
- stream << padding << " }" << std::endl;
- stream << padding << " :: else -> break;" << std::endl;
- stream << padding << " od" << std::endl;
- stream << padding << "}" << std::endl;
+ std::string padding;
+ for (size_t i = 0; i < indent; i++) {
+ padding += " ";
+ }
+
+ stream << padding << "inline advanceTime(increment, queue) {" << std::endl;
+ stream << padding << " tmpIndex = 0;" << std::endl;
+ stream << padding << " do" << std::endl;
+ stream << padding << " :: tmpIndex < len(queue) -> {" << std::endl;
+ stream << padding << " queue?tmpE;" << std::endl;
+ stream << padding << " if" << std::endl;
+ stream << padding << " :: tmpE.delay >= increment -> tmpE.delay = tmpE.delay - increment;" << std::endl;
+ stream << padding << " :: else -> skip;" << std::endl;
+ stream << padding << " fi" << std::endl;
+ stream << padding << " queue!tmpE;" << std::endl;
+ stream << padding << " tmpIndex++;" << std::endl;
+ stream << padding << " }" << std::endl;
+ stream << padding << " :: else -> break;" << std::endl;
+ stream << padding << " od" << std::endl;
+ stream << padding << "}" << std::endl;
}
void ChartToPromela::writeInsertWithDelay(std::ostream& stream, int indent) {
- std::string padding;
- for (size_t i = 0; i < indent; i++) {
- padding += " ";
- }
-
- uint32_t maxExternalQueueLength = 1;
- for(auto machine : *_machinesAll) {
- maxExternalQueueLength = MAX(maxExternalQueueLength, machine.second->_externalQueueLength);
- }
-
- maxExternalQueueLength += 6;
-
- if (maxExternalQueueLength <= 1) {
- stream << padding << "/* noop for external queues with length <= 1 */" << std::endl;
- stream << padding << "inline insertWithDelay(queue) {}" << std::endl;
- }
-
- stream << padding << "hidden _event_t _iwdQ[" << maxExternalQueueLength - 1 << "];" << std::endl;
- stream << padding << "hidden int _iwdQLength = 0;" << std::endl;
- stream << padding << "hidden int _iwdIdx1 = 0;" << std::endl;
- stream << padding << "hidden int _iwdIdx2 = 0;" << std::endl;
- stream << padding << "hidden _event_t _iwdTmpE;" << std::endl;
- stream << padding << "hidden _event_t _iwdLastE;" << std::endl;
- stream << padding << "bool _iwdInserted = false;" << std::endl;
- stream << padding << "" << std::endl;
- stream << padding << "/* last event in given queue is potentially at wrong position */" << std::endl;
- stream << padding << "inline insertWithDelay(queue) {" << std::endl;
- stream << padding << " d_step {" << std::endl;
- stream << padding << "" << std::endl;
- stream << padding << " /* only process for non-trivial queues */" << std::endl;
- stream << padding << " if" << std::endl;
- stream << padding << " :: len(queue) > 1 -> {" << std::endl;
-
- TRACE_EXECUTION("Reshuffling events")
-
- stream << padding << "" << std::endl;
- stream << padding << " /* move all events but last over and remember the last one */" << std::endl;
- stream << padding << " _iwdIdx1 = 0;" << std::endl;
- stream << padding << " _iwdQLength = len(queue) - 1;" << std::endl;
- stream << padding << "" << std::endl;
- stream << padding << " do" << std::endl;
- stream << padding << " :: _iwdIdx1 < _iwdQLength -> {" << std::endl;
- stream << padding << " queue?_iwdTmpE;" << std::endl;
- stream << padding << " _iwdQ[_iwdIdx1].name = _iwdTmpE.name;" << std::endl;
-
- stream << _analyzer->getTypeAssignment("_iwdQ[_iwdIdx1]", "_iwdTmpE", _analyzer->getType("_event"), 8);
-
- stream << padding << " _iwdIdx1++;" << std::endl;
- stream << padding << " }" << std::endl;
- stream << padding << " :: else -> break;" << std::endl;
- stream << padding << " od" << std::endl;
- stream << padding << "" << std::endl;
- stream << padding << " queue?_iwdLastE;" << std::endl;
-
- stream << padding << "" << std::endl;
- stream << padding << " /* _iwdQ now contains all but last item in _iwdLastE */" << std::endl;
- stream << padding << " assert(len(queue) == 0);" << std::endl;
- stream << padding << "" << std::endl;
- stream << padding << " /* reinsert into queue and place _iwdLastE correctly */" << std::endl;
- stream << padding << " _iwdInserted = false;" << std::endl;
- stream << padding << " _iwdIdx2 = 0;" << std::endl;
- stream << padding << "" << std::endl;
- stream << padding << " do" << std::endl;
- stream << padding << " :: _iwdIdx2 < _iwdIdx1 -> {" << std::endl;
- stream << padding << " _iwdTmpE.name = _iwdQ[_iwdIdx2].name;" << std::endl;
-
- stream << _analyzer->getTypeAssignment("_iwdTmpE", "_iwdQ[_iwdIdx2]", _analyzer->getType("_event"), 4);
-
- stream << padding << "" << std::endl;
- stream << padding << " if" << std::endl;
- stream << padding << " :: _iwdTmpE.delay > _iwdLastE.delay && !_iwdInserted -> {" << std::endl;
- stream << padding << " queue!_iwdLastE;" << std::endl;
- TRACE_EXECUTION_V("Event %d has delay %d (last)", "_iwdLastE.name, _iwdLastE.delay");
-
- stream << padding << " _iwdInserted = true;" << std::endl;
- stream << padding << " }" << std::endl;
- stream << padding << " :: else -> skip" << std::endl;
- stream << padding << " fi;" << std::endl;
- stream << padding << "" << std::endl;
- stream << padding << " queue!_iwdTmpE;" << std::endl;
- TRACE_EXECUTION_V("Event %d has delay %d", "_iwdTmpE.name, _iwdTmpE.delay");
-
- stream << padding << " _iwdIdx2++;" << std::endl;
- stream << padding << " }" << std::endl;
- stream << padding << " :: else -> break;" << std::endl;
- stream << padding << " od" << std::endl;
- stream << padding << "" << std::endl;
- stream << padding << " if" << std::endl;
- stream << padding << " :: !_iwdInserted -> {" << std::endl;
- stream << padding << " queue!_iwdLastE;" << std::endl;
- TRACE_EXECUTION_V("Event %d has delay %d (last)", "_iwdLastE.name, _iwdLastE.delay");
- stream << padding << " }" << std::endl;
- stream << padding << " :: else -> skip;" << std::endl;
- stream << padding << " fi;" << std::endl;
- stream << padding << "" << std::endl;
- stream << padding << " }" << std::endl;
- stream << padding << " :: else -> skip;" << std::endl;
- stream << padding << " fi;" << std::endl;
- stream << padding << " }" << std::endl;
- stream << padding << "}" << std::endl;
+ std::string padding;
+ for (size_t i = 0; i < indent; i++) {
+ padding += " ";
+ }
+
+ uint32_t maxExternalQueueLength = 1;
+ for(auto machine : *_machinesAll) {
+ maxExternalQueueLength = MAX(maxExternalQueueLength, machine.second->_externalQueueLength);
+ }
+
+ maxExternalQueueLength += 6;
+
+ if (maxExternalQueueLength <= 1) {
+ stream << padding << "/* noop for external queues with length <= 1 */" << std::endl;
+ stream << padding << "inline insertWithDelay(queue) {}" << std::endl;
+ }
+
+ stream << padding << "hidden _event_t _iwdQ[" << maxExternalQueueLength - 1 << "];" << std::endl;
+ stream << padding << "hidden int _iwdQLength = 0;" << std::endl;
+ stream << padding << "hidden int _iwdIdx1 = 0;" << std::endl;
+ stream << padding << "hidden int _iwdIdx2 = 0;" << std::endl;
+ stream << padding << "hidden _event_t _iwdTmpE;" << std::endl;
+ stream << padding << "hidden _event_t _iwdLastE;" << std::endl;
+ stream << padding << "bool _iwdInserted = false;" << std::endl;
+ stream << padding << "" << std::endl;
+ stream << padding << "/* last event in given queue is potentially at wrong position */" << std::endl;
+ stream << padding << "inline insertWithDelay(queue) {" << std::endl;
+ stream << padding << " d_step {" << std::endl;
+ stream << padding << "" << std::endl;
+ stream << padding << " /* only process for non-trivial queues */" << std::endl;
+ stream << padding << " if" << std::endl;
+ stream << padding << " :: len(queue) > 1 -> {" << std::endl;
+
+ TRACE_EXECUTION("Reshuffling events")
+
+ stream << padding << "" << std::endl;
+ stream << padding << " /* move all events but last over and remember the last one */" << std::endl;
+ stream << padding << " _iwdIdx1 = 0;" << std::endl;
+ stream << padding << " _iwdQLength = len(queue) - 1;" << std::endl;
+ stream << padding << "" << std::endl;
+ stream << padding << " do" << std::endl;
+ stream << padding << " :: _iwdIdx1 < _iwdQLength -> {" << std::endl;
+ stream << padding << " queue?_iwdTmpE;" << std::endl;
+ stream << padding << " _iwdQ[_iwdIdx1].name = _iwdTmpE.name;" << std::endl;
+
+ stream << _analyzer->getTypeAssignment("_iwdQ[_iwdIdx1]", "_iwdTmpE", _analyzer->getType("_event"), 8);
+
+ stream << padding << " _iwdIdx1++;" << std::endl;
+ stream << padding << " }" << std::endl;
+ stream << padding << " :: else -> break;" << std::endl;
+ stream << padding << " od" << std::endl;
+ stream << padding << "" << std::endl;
+ stream << padding << " queue?_iwdLastE;" << std::endl;
+
+ stream << padding << "" << std::endl;
+ stream << padding << " /* _iwdQ now contains all but last item in _iwdLastE */" << std::endl;
+ stream << padding << " assert(len(queue) == 0);" << std::endl;
+ stream << padding << "" << std::endl;
+ stream << padding << " /* reinsert into queue and place _iwdLastE correctly */" << std::endl;
+ stream << padding << " _iwdInserted = false;" << std::endl;
+ stream << padding << " _iwdIdx2 = 0;" << std::endl;
+ stream << padding << "" << std::endl;
+ stream << padding << " do" << std::endl;
+ stream << padding << " :: _iwdIdx2 < _iwdIdx1 -> {" << std::endl;
+ stream << padding << " _iwdTmpE.name = _iwdQ[_iwdIdx2].name;" << std::endl;
+
+ stream << _analyzer->getTypeAssignment("_iwdTmpE", "_iwdQ[_iwdIdx2]", _analyzer->getType("_event"), 4);
+
+ stream << padding << "" << std::endl;
+ stream << padding << " if" << std::endl;
+ stream << padding << " :: _iwdTmpE.delay > _iwdLastE.delay && !_iwdInserted -> {" << std::endl;
+ stream << padding << " queue!_iwdLastE;" << std::endl;
+ TRACE_EXECUTION_V("Event %d has delay %d (last)", "_iwdLastE.name, _iwdLastE.delay");
+
+ stream << padding << " _iwdInserted = true;" << std::endl;
+ stream << padding << " }" << std::endl;
+ stream << padding << " :: else -> skip" << std::endl;
+ stream << padding << " fi;" << std::endl;
+ stream << padding << "" << std::endl;
+ stream << padding << " queue!_iwdTmpE;" << std::endl;
+ TRACE_EXECUTION_V("Event %d has delay %d", "_iwdTmpE.name, _iwdTmpE.delay");
+
+ stream << padding << " _iwdIdx2++;" << std::endl;
+ stream << padding << " }" << std::endl;
+ stream << padding << " :: else -> break;" << std::endl;
+ stream << padding << " od" << std::endl;
+ stream << padding << "" << std::endl;
+ stream << padding << " if" << std::endl;
+ stream << padding << " :: !_iwdInserted -> {" << std::endl;
+ stream << padding << " queue!_iwdLastE;" << std::endl;
+ TRACE_EXECUTION_V("Event %d has delay %d (last)", "_iwdLastE.name, _iwdLastE.delay");
+ stream << padding << " }" << std::endl;
+ stream << padding << " :: else -> skip;" << std::endl;
+ stream << padding << " fi;" << std::endl;
+ stream << padding << "" << std::endl;
+ stream << padding << " }" << std::endl;
+ stream << padding << " :: else -> skip;" << std::endl;
+ stream << padding << " fi;" << std::endl;
+ stream << padding << " }" << std::endl;
+ stream << padding << "}" << std::endl;
}
void ChartToPromela::writeRescheduleProcess(std::ostream& stream, int indent) {
- std::string padding;
- for (size_t i = 0; i < indent; i++) {
- padding += " ";
- }
-
- if (_allowEventInterleaving) {
- stream << padding << "inline rescheduleProcess(smallestDelay, procId, internalQ, externalQ, tempQ) {" << std::endl;
- } else {
- stream << padding << "inline rescheduleProcess(smallestDelay, procId, internalQ, externalQ) {" << std::endl;
- }
- // stream << _analyzer->getTypeReset("tmpE", _analyzer->getType("_event"), " ");
-
- stream << padding << " set_priority(procId, 1);" << std::endl;
- stream << padding << " if" << std::endl;
- stream << padding << " :: len(internalQ) > 0 -> set_priority(procId, 10);" << std::endl;
- stream << padding << " :: else {" << std::endl;
- stream << padding << " if" << std::endl;
-
- stream << padding << " :: len(externalQ) > 0 -> {" << std::endl;
- stream << padding << " externalQ?<tmpE>;" << std::endl;
- stream << padding << " if" << std::endl;
- stream << padding << " :: smallestDelay == tmpE.delay -> set_priority(procId, 10);" << std::endl;
- stream << padding << " :: else -> skip;" << std::endl;
- stream << padding << " fi;" << std::endl;
- stream << padding << " }" << std::endl;
-
- if (_allowEventInterleaving) {
- stream << padding << " :: len(tempQ) > 0 -> {" << std::endl;
- stream << padding << " tempQ?<tmpE>;" << std::endl;
- stream << padding << " if" << std::endl;
- stream << padding << " :: smallestDelay == tmpE.delay -> set_priority(procId, 10);" << std::endl;
- stream << padding << " :: else -> skip;" << std::endl;
- stream << padding << " fi;" << std::endl;
- stream << padding << " }" << std::endl;
- }
-
- stream << padding << " :: else -> skip;" << std::endl;
- stream << padding << " fi;" << std::endl;
- stream << padding << " }" << std::endl;
- stream << padding << " fi;" << std::endl;
- stream << padding << "}" << std::endl;
+ std::string padding;
+ for (size_t i = 0; i < indent; i++) {
+ padding += " ";
+ }
+
+ if (_allowEventInterleaving) {
+ stream << padding << "inline rescheduleProcess(smallestDelay, procId, internalQ, externalQ, tempQ) {" << std::endl;
+ } else {
+ stream << padding << "inline rescheduleProcess(smallestDelay, procId, internalQ, externalQ) {" << std::endl;
+ }
+ // stream << _analyzer->getTypeReset("tmpE", _analyzer->getType("_event"), " ");
+
+ stream << padding << " set_priority(procId, 1);" << std::endl;
+ stream << padding << " if" << std::endl;
+ stream << padding << " :: len(internalQ) > 0 -> set_priority(procId, 10);" << std::endl;
+ stream << padding << " :: else {" << std::endl;
+ stream << padding << " if" << std::endl;
+
+ stream << padding << " :: len(externalQ) > 0 -> {" << std::endl;
+ stream << padding << " externalQ?<tmpE>;" << std::endl;
+ stream << padding << " if" << std::endl;
+ stream << padding << " :: smallestDelay == tmpE.delay -> set_priority(procId, 10);" << std::endl;
+ stream << padding << " :: else -> skip;" << std::endl;
+ stream << padding << " fi;" << std::endl;
+ stream << padding << " }" << std::endl;
+
+ if (_allowEventInterleaving) {
+ stream << padding << " :: len(tempQ) > 0 -> {" << std::endl;
+ stream << padding << " tempQ?<tmpE>;" << std::endl;
+ stream << padding << " if" << std::endl;
+ stream << padding << " :: smallestDelay == tmpE.delay -> set_priority(procId, 10);" << std::endl;
+ stream << padding << " :: else -> skip;" << std::endl;
+ stream << padding << " fi;" << std::endl;
+ stream << padding << " }" << std::endl;
+ }
+
+ stream << padding << " :: else -> skip;" << std::endl;
+ stream << padding << " fi;" << std::endl;
+ stream << padding << " }" << std::endl;
+ stream << padding << " fi;" << std::endl;
+ stream << padding << "}" << std::endl;
}
void ChartToPromela::writeCancelEvents(std::ostream& stream, int indent) {
- std::list<std::string> queues;
- queues.push_back("eQ");
- if (_allowEventInterleaving)
- queues.push_back("tmpQ");
-
- stream << "inline cancelSendId(sendIdentifier, source) {" << std::endl;
- for (auto machine : *_machinesAll) {
- for (auto queue : queues) {
- stream << " cancelSendIdOnQueue(sendIdentifier, source, " << machine.second->_prefix << queue << ");" << std::endl;
- }
- }
- stream << "}" << std::endl;
- stream << std::endl;
-
-
- stream << "inline cancelSendIdOnQueue(sendIdentifier, source, queue) {" << std::endl;
- stream << " tmpIndex = 0;" << std::endl;
- // stream << _analyzer->getTypeReset("tmpE", _analyzer->getType("_event"), " ");
- stream << " do" << std::endl;
- stream << " :: tmpIndex < len(queue) -> {" << std::endl;
- stream << " queue?tmpE;" << std::endl;
- stream << " if" << std::endl;
- stream << " :: tmpE.sendid != sendIdentifier || tmpE.origin != source || tmpE.delay == 0 -> queue!tmpE;" << std::endl;
- stream << " :: else -> skip;" << std::endl;
- stream << " fi" << std::endl;
- stream << " tmpIndex++;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> break;" << std::endl;
- stream << " od" << std::endl;
- stream << "}" << std::endl;
+ std::list<std::string> queues;
+ queues.push_back("eQ");
+ if (_allowEventInterleaving)
+ queues.push_back("tmpQ");
+
+ stream << "inline cancelSendId(sendIdentifier, source) {" << std::endl;
+ for (auto machine : *_machinesAll) {
+ for (auto queue : queues) {
+ stream << " cancelSendIdOnQueue(sendIdentifier, source, " << machine.second->_prefix << queue << ");" << std::endl;
+ }
+ }
+ stream << "}" << std::endl;
+ stream << std::endl;
+
+
+ stream << "inline cancelSendIdOnQueue(sendIdentifier, source, queue) {" << std::endl;
+ stream << " tmpIndex = 0;" << std::endl;
+ // stream << _analyzer->getTypeReset("tmpE", _analyzer->getType("_event"), " ");
+ stream << " do" << std::endl;
+ stream << " :: tmpIndex < len(queue) -> {" << std::endl;
+ stream << " queue?tmpE;" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: tmpE.sendid != sendIdentifier || tmpE.origin != source || tmpE.delay == 0 -> queue!tmpE;" << std::endl;
+ stream << " :: else -> skip;" << std::endl;
+ stream << " fi" << std::endl;
+ stream << " tmpIndex++;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> break;" << std::endl;
+ stream << " od" << std::endl;
+ stream << "}" << std::endl;
}
void ChartToPromela::writeRemovePendingEventsFromInvoker(std::ostream& stream, int indent) {
- std::list<std::string> queues;
- queues.push_back("eQ");
- if (_allowEventInterleaving)
- queues.push_back("tmpQ");
-
- stream << "inline removePendingEventsFromInvoker(invoker) {" << std::endl;
- for (auto machine : *_machinesAll) {
- for (auto queue : queues) {
- stream << " removePendingEventsFromInvokerOnQueue(invoker, " << machine.second->_prefix << queue << ");" << std::endl;
- }
- }
- stream << "}" << std::endl;
- stream << std::endl;
-
- stream << "inline removePendingEventsFromInvokerOnQueue(invoker, queue) {" << std::endl;
- stream << " tmpIndex = len(queue);" << std::endl;
- // stream << _analyzer->getTypeReset("tmpE", _analyzer->getType("_event"), " ");
- stream << " do" << std::endl;
- stream << " :: tmpIndex > 0 -> {" << std::endl;
- stream << " queue?tmpE;" << std::endl;
- stream << " if" << std::endl;
- stream << " :: false || ";
- if (_analyzer->usesEventField("delay"))
- stream << "tmpE.delay == 0 || ";
- if (_analyzer->usesEventField("invokeid"))
- stream << "tmpE.invokeid != invoker" << std::endl;
- stream << " -> {" << std::endl;
-
- TRACE_EXECUTION_V("Reenqueing event %d", "tmpE.name");
-
- stream << " queue!tmpE;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> {" << std::endl;
-
- TRACE_EXECUTION_V("Dropping event %d", "tmpE.name");
-
- stream << " skip;" << std::endl;
- stream << " }" << std::endl;
- stream << " fi" << std::endl;
- stream << " tmpIndex = tmpIndex - 1;" << std::endl;
- stream << " }" << std::endl;
- stream << " :: else -> break;" << std::endl;
- stream << " od" << std::endl;
- stream << "}" << std::endl;
+ std::list<std::string> queues;
+ queues.push_back("eQ");
+ if (_allowEventInterleaving)
+ queues.push_back("tmpQ");
+
+ stream << "inline removePendingEventsFromInvoker(invoker) {" << std::endl;
+ for (auto machine : *_machinesAll) {
+ for (auto queue : queues) {
+ stream << " removePendingEventsFromInvokerOnQueue(invoker, " << machine.second->_prefix << queue << ");" << std::endl;
+ }
+ }
+ stream << "}" << std::endl;
+ stream << std::endl;
+
+ stream << "inline removePendingEventsFromInvokerOnQueue(invoker, queue) {" << std::endl;
+ stream << " tmpIndex = len(queue);" << std::endl;
+ // stream << _analyzer->getTypeReset("tmpE", _analyzer->getType("_event"), " ");
+ stream << " do" << std::endl;
+ stream << " :: tmpIndex > 0 -> {" << std::endl;
+ stream << " queue?tmpE;" << std::endl;
+ stream << " if" << std::endl;
+ stream << " :: false || ";
+ if (_analyzer->usesEventField("delay"))
+ stream << "tmpE.delay == 0 || ";
+ if (_analyzer->usesEventField("invokeid"))
+ stream << "tmpE.invokeid != invoker" << std::endl;
+ stream << " -> {" << std::endl;
+
+ TRACE_EXECUTION_V("Reenqueing event %d", "tmpE.name");
+
+ stream << " queue!tmpE;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> {" << std::endl;
+
+ TRACE_EXECUTION_V("Dropping event %d", "tmpE.name");
+
+ stream << " skip;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " fi" << std::endl;
+ stream << " tmpIndex = tmpIndex - 1;" << std::endl;
+ stream << " }" << std::endl;
+ stream << " :: else -> break;" << std::endl;
+ stream << " od" << std::endl;
+ stream << "}" << std::endl;
}
diff --git a/src/uscxml/transform/ChartToPromela.h b/src/uscxml/transform/ChartToPromela.h
index b8b513e..ac7f26a 100644
--- a/src/uscxml/transform/ChartToPromela.h
+++ b/src/uscxml/transform/ChartToPromela.h
@@ -40,55 +40,55 @@ public:
protected:
ChartToPromela(const Interpreter& other) : ChartToC(other) {
- _prefix = "U" + _md5.substr(0, 8) + "_";
- }
+ _prefix = "U" + _md5.substr(0, 8) + "_";
+ }
void writeTransitions(std::ostream& stream);
void writeStates(std::ostream& stream);
-
- void writeCommonTypeDefs(std::ostream& stream);
- void writeCommonVariables(std::ostream& stream);
- void writeTypeDefs(std::ostream& stream);
- void writeVariables(std::ostream& stream);
+
+ void writeCommonTypeDefs(std::ostream& stream);
+ void writeCommonVariables(std::ostream& stream);
+ void writeTypeDefs(std::ostream& stream);
+ void writeVariables(std::ostream& stream);
// void writeTypeDefs(std::ostream& stream);
// void writeTypes(std::ostream& stream);
void writeMacros(std::ostream& stream);
void writeFSM(std::ostream& stream);
- void writeFSMDequeueEvent(std::ostream& stream);
+ void writeFSMDequeueEvent(std::ostream& stream);
// void writeFSMRescheduleMachines(std::ostream& stream);
// void writeFSMMacrostep(std::ostream& stream);
// void writeFSMDequeueInternalOrSpontaneousEvent(std::ostream& stream);
- void writeFSMSelectTransitions(std::ostream& stream);
- void writeFSMRememberHistory(std::ostream& stream);
- void writeFSMEstablishEntrySet(std::ostream& stream);
- void writeFSMExitStates(std::ostream& stream);
- void writeFSMTakeTransitions(std::ostream& stream);
- void writeFSMEnterStates(std::ostream& stream);
- void writeFSMTerminateMachine(std::ostream& stream);
+ void writeFSMSelectTransitions(std::ostream& stream);
+ void writeFSMRememberHistory(std::ostream& stream);
+ void writeFSMEstablishEntrySet(std::ostream& stream);
+ void writeFSMExitStates(std::ostream& stream);
+ void writeFSMTakeTransitions(std::ostream& stream);
+ void writeFSMEnterStates(std::ostream& stream);
+ void writeFSMTerminateMachine(std::ostream& stream);
void writeExecContent(std::ostream& stream, const XERCESC_NS::DOMNode* node, size_t indent = 0);
- void writeRaiseDoneDate(std::ostream& stream, const XERCESC_NS::DOMElement* donedata, size_t indent = 0);
-
- void writeStrings(std::ostream& stream);
-
- void writeCancelEvents(std::ostream& stream, int indent = 0);
- void writeScheduleMachines(std::ostream& stream, int indent = 0);
- void writeDetermineShortestDelay(std::ostream& stream, int indent = 0);
- void writeRescheduleProcess(std::ostream& stream, int indent = 0);
- void writeInsertWithDelay(std::ostream& stream, int indent = 0);
- void writeAdvanceTime(std::ostream& stream, int indent = 0);
- void writeRemovePendingEventsFromInvoker(std::ostream& stream, int indent = 0);
-
- void prepare();
-
- void writeBitClearMacro(std::ostream& stream);
- void writeBitHasAndMacro(std::ostream& stream);
- void writeBitHasAnyMacro(std::ostream& stream);
- void writeBitOrMacro(std::ostream& stream);
- void writeBitCopyMacro(std::ostream& stream);
- void writeBitAndMacro(std::ostream& stream);
- void writeBitAndNotMacro(std::ostream& stream);
+ void writeRaiseDoneDate(std::ostream& stream, const XERCESC_NS::DOMElement* donedata, size_t indent = 0);
+
+ void writeStrings(std::ostream& stream);
+
+ void writeCancelEvents(std::ostream& stream, int indent = 0);
+ void writeScheduleMachines(std::ostream& stream, int indent = 0);
+ void writeDetermineShortestDelay(std::ostream& stream, int indent = 0);
+ void writeRescheduleProcess(std::ostream& stream, int indent = 0);
+ void writeInsertWithDelay(std::ostream& stream, int indent = 0);
+ void writeAdvanceTime(std::ostream& stream, int indent = 0);
+ void writeRemovePendingEventsFromInvoker(std::ostream& stream, int indent = 0);
+
+ void prepare();
+
+ void writeBitClearMacro(std::ostream& stream);
+ void writeBitHasAndMacro(std::ostream& stream);
+ void writeBitHasAnyMacro(std::ostream& stream);
+ void writeBitOrMacro(std::ostream& stream);
+ void writeBitCopyMacro(std::ostream& stream);
+ void writeBitAndMacro(std::ostream& stream);
+ void writeBitAndNotMacro(std::ostream& stream);
void printBitArray(std::ostream& stream,
const std::string& array,
@@ -101,17 +101,17 @@ protected:
ChartToPromela* _parent = NULL;
std::string _invokerid;
- size_t _internalQueueLength = 7;
- size_t _externalQueueLength = 7;
- bool _allowEventInterleaving = false;
-
+ size_t _internalQueueLength = 7;
+ size_t _externalQueueLength = 7;
+ bool _allowEventInterleaving = false;
+
std::map<std::string, XERCESC_NS::DOMElement* > _machinesPerId;
std::map<std::string, XERCESC_NS::DOMElement* >* _machinesAllPerId = NULL;
std::map<XERCESC_NS::DOMElement*, ChartToPromela*> _machinesNested;
std::map<XERCESC_NS::DOMElement*, ChartToPromela*>* _machinesAll = NULL;
std::set<std::string> _dataModelVars;
- std::list<std::string> _varInitializers; // pending initializations for arrays
+ std::list<std::string> _varInitializers; // pending initializations for arrays
std::string beautifyIndentation(const std::string& code, size_t indent = 0);
void writeIfBlock(std::ostream& stream, std::list<XERCESC_NS::DOMElement*>& condChain, size_t indent = 0);
diff --git a/src/uscxml/transform/ChartToVHDL.cpp b/src/uscxml/transform/ChartToVHDL.cpp
index 5061e33..071d863 100644
--- a/src/uscxml/transform/ChartToVHDL.cpp
+++ b/src/uscxml/transform/ChartToVHDL.cpp
@@ -37,1363 +37,1371 @@
namespace uscxml {
- using namespace XERCESC_NS;
-
- Transformer ChartToVHDL::transform(const Interpreter &other) {
- ChartToVHDL *c2c = new ChartToVHDL(other);
-
- return std::shared_ptr<TransformerImpl>(c2c);
- }
-
- ChartToVHDL::ChartToVHDL(const Interpreter &other) : ChartToC(other), _eventTrie(".") {
- }
-
- ChartToVHDL::~ChartToVHDL() {
- }
-
- void ChartToVHDL::checkDocument() {
- // filter unsupported stuff
- std::list<DOMElement *> 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<DOMElement *> withEvents = DOMUtils::inDocumentOrder({
- XML_PREFIX(_scxml).str() + "raise",
- XML_PREFIX(_scxml).str() + "send",
- XML_PREFIX(_scxml).str() + "transition",
- }, _scxml);
-
- for (auto withEvent : withEvents) {
+using namespace XERCESC_NS;
+
+Transformer ChartToVHDL::transform(const Interpreter &other) {
+ ChartToVHDL *c2c = new ChartToVHDL(other);
+
+ return std::shared_ptr<TransformerImpl>(c2c);
+}
+
+ChartToVHDL::ChartToVHDL(const Interpreter &other) : ChartToC(other), _eventTrie(".") {
+}
+
+ChartToVHDL::~ChartToVHDL() {
+}
+
+void ChartToVHDL::checkDocument() {
+ // filter unsupported stuff
+ std::list<DOMElement *> 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<DOMElement *> withEvents = DOMUtils::inDocumentOrder({
+ XML_PREFIX(_scxml).str() + "raise",
+ XML_PREFIX(_scxml).str() + "send",
+ XML_PREFIX(_scxml).str() + "transition",
+ }, _scxml);
+
+ 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<std::string> events = tokenize(eventNames);
- for (std::list<std::string>::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 <scxml> (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
- }
-
-
- }
-
- _execContent = DOMUtils::inDocumentOrder({
- XML_PREFIX(_scxml).str() + "raise",
- XML_PREFIX(_scxml).str() + "send"
- }, _scxml);
-
- }
-
- bool ChartToVHDL::filterSupportedExecContent(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<TrieNode *> eventNames = _eventTrie.getWordsWithPrefix("");
- stream << " type event_type is ( hwe_null, ";
- seperator = "";
-
- for (std::list<TrieNode *>::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;
- }
-
- void ChartToVHDL::writeTestbench(std::ostream &stream) {
-
- stream << "-- TESTBENCH" << std::endl;
- writeIncludes(stream);
- 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;
- }
- }
-
- 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 << " 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;
- }
- }
-
- 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 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;
- }
-
- 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 << " 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;
- }
- }
-
- 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 << " 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;
-
- 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;
- }
- }
-
- 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;
-
- // find pass state
- std::list<DOMElement *> 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");
- }
- }
-
- 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 \"Complted with errors\" severity error;" << std::endl;
- }
- stream << " -- stop simulation" << 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::writeExContentBlock(std::ostream &stream,
- std::string index, std::list<DOMElement *> commandSequence) {
- // index should be [entry, transition, exit]_<index of state/transition>_<optional index for block>
-
- // 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;
- }
-
- 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;
- }
- }
-
- 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 << "-- 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;
-
- 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";
- }
-
- 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 <= 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;
-
- 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 << " 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;
-
- 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'.
+ // Tokenized version below
+
+ if (HAS_ATTR_CAST(withEvent, "event")) {
+ std::string eventNames = ATTR_CAST(withEvent, "event");
+ std::list<std::string> events = tokenize(eventNames);
+ for (std::list<std::string>::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 <scxml> (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
+ }
+
+
+ }
+
+ _execContent = DOMUtils::inDocumentOrder({
+ XML_PREFIX(_scxml).str() + "raise",
+ XML_PREFIX(_scxml).str() + "send"
+ }, _scxml);
+
+}
+
+bool ChartToVHDL::filterSupportedExecContent(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<TrieNode *> eventNames = _eventTrie.getWordsWithPrefix("");
+ stream << " type event_type is ( hwe_null, ";
+ seperator = "";
+
+ for (std::list<TrieNode *>::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;
+}
+
+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;
+ }
+ }
+
+ 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 << " 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;
+ }
+ }
+
+ 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 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;
+ }
+
+ 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 << " 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;
+ }
+ }
+
+ 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 << " 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;
+
+ 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;
+ }
+ }
+
+ 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;
+
+ // find pass state
+ std::list<DOMElement *> 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");
+ }
+ }
+
+ 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 \"Complted with errors\" severity error;" << std::endl;
+ }
+ stream << " -- stop simulation" << std::endl;
+ stream << " finish(1);" << std::endl;
+// -- 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<DOMElement *> commandSequence) {
+ // index should be [entry, transition, exit]_<index of state/transition>_<optional index for block>
+
+ // 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;
+ }
+
+ 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;
+ }
+ }
+
+ 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 << "-- 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;
+
+ 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";
+ }
+
+ 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 <= 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;
+
+ 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 << " 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;
+
+ 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 << " 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;
-
- 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";
- }
-
- if (localName == XML_PREFIX(_scxml).str() + "onexit") {
- return "exit_set_" + ATTR_CAST(ecBlock->getParentNode(), "documentOrder") + "_i";
- }
-
- }
- 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;
- }
-
- 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;
- }
- }
-
- 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<std::string> 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 <scxml> state
- if (parent.size() != 0) {
- signalDecls.push_back(
- "signal in_complete_entry_set_up_" + ATTR(state, "documentOrder") + "_sig : std_logic;");
- }
- }
-
- signalDecls.sort();
- for (std::list<std::string>::iterator iter = signalDecls.begin(); iter != signalDecls.end(); iter++) {
- stream << *iter << 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;
- }
- 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<TrieNode *> eventNames = _eventTrie.getWordsWithPrefix("");
- for (std::list<TrieNode *>::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<TrieNode *> eventNames = _eventTrie.getWordsWithPrefix("");
- for (std::list<TrieNode *>::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 << " elsif falling_edge(clk) and stall = '0' then" << std::endl;
-
- VContainer eventConsumed = VOR;
- for (auto transition : _transitions) {
-
- 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;
- for (std::list<TrieNode *>::iterator eventIter = eventNames.begin();
- eventIter != eventNames.end(); eventIter++) {
- stream << " when hwe_"
- << escapeMacro((*eventIter)->value) << " =>" << std::endl;
- for (std::list<TrieNode *>::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<TrieNode *>::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<TrieNode *>::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 <scxml> 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;
-
- }
- }
-
- 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<std::string> eventDescs = tokenize(ATTR(transition, "event"));
- for (std::list<std::string>::iterator descIter = eventDescs.begin();
- descIter != eventDescs.end(); descIter++) {
- std::list<TrieNode *> eventNames = _eventTrie.getWordsWithPrefix(
- (*descIter) == "*" ? "" : *descIter);
- for (std::list<TrieNode *>::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<size_t>(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("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) {
-
- 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<size_t>(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));
-
- tree->print(stream);
- stream << ";" << std::endl;
- }
- }
-
- 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");
-
- if (parent.size() == 0) {
- continue; // skips <scxml> 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<size_t>(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<size_t>(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;
- }
-
-
- // 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 <scxml> node
- }
-
- VContainer descendantCompletion = VAND;
- // if parent is compound
- if (getParentState(state) != NULL &&
- isCompound(getParentState(state))) {
- std::string children = ATTR_CAST(_states[strTo<size_t>(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<size_t>(ATTR(getParentState(state), "documentOrder")) + 1) ==
- strTo<size_t>(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<size_t>(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");
- }
-
- 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;
- }
-
- 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::writeSystemSignalMapping(std::ostream &stream) {
- stream << "-- system signals" << std::endl;
- std::list<DOMElement *> topLevelFinal = DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "final",
- _scxml);
-
- VContainer tlf = VOR;
- for (auto final : topLevelFinal) {
- *tlf += VLINE("state_active_" + ATTR(final, "documentOrder") + "_sig");
-
- }
-
- 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;
- }
- }
-
- stream << "completed_o <= completed_sig; " << std::endl;
- stream << "error_o <= reg_error_out; " << std::endl;
- 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";
+ }
+
+ if (localName == XML_PREFIX(_scxml).str() + "onexit") {
+ return "exit_set_" + ATTR_CAST(ecBlock->getParentNode(), "documentOrder") + "_i";
+ }
+
+ }
+ 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;
+ }
+
+ 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;
+ }
+ }
+
+ 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<std::string> 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 <scxml> state
+ if (parent.size() != 0) {
+ signalDecls.push_back(
+ "signal in_complete_entry_set_up_" + ATTR(state, "documentOrder") + "_sig : std_logic;");
+ }
+ }
+
+ signalDecls.sort();
+ for (std::list<std::string>::iterator iter = signalDecls.begin(); iter != signalDecls.end(); iter++) {
+ stream << *iter << 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;
+ }
+ 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<TrieNode *> eventNames = _eventTrie.getWordsWithPrefix("");
+ for (std::list<TrieNode *>::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<TrieNode *> eventNames = _eventTrie.getWordsWithPrefix("");
+ for (std::list<TrieNode *>::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 << " elsif falling_edge(clk) and stall = '0' then" << std::endl;
+
+ VContainer eventConsumed = VOR;
+ for (auto transition : _transitions) {
+
+ 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;
+ for (std::list<TrieNode *>::iterator eventIter = eventNames.begin();
+ eventIter != eventNames.end(); eventIter++) {
+ stream << " when hwe_"
+ << escapeMacro((*eventIter)->value) << " =>" << std::endl;
+ for (std::list<TrieNode *>::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<TrieNode *>::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<TrieNode *>::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 <scxml> 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;
+
+ }
+}
+
+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<std::string> eventDescs = tokenize(ATTR(transition, "event"));
+ for (std::list<std::string>::iterator descIter = eventDescs.begin();
+ descIter != eventDescs.end(); descIter++) {
+ std::list<TrieNode *> eventNames = _eventTrie.getWordsWithPrefix(
+ (*descIter) == "*" ? "" : *descIter);
+ for (std::list<TrieNode *>::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<size_t>(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("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) {
+
+ 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<size_t>(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));
+
+ tree->print(stream);
+ stream << ";" << std::endl;
+ }
+}
+
+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");
+
+ if (parent.size() == 0) {
+ continue; // skips <scxml> 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<size_t>(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<size_t>(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;
+ }
+
+
+ // 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 <scxml> node
+ }
+
+ VContainer descendantCompletion = VAND;
+ // if parent is compound
+ if (getParentState(state) != NULL &&
+ isCompound(getParentState(state))) {
+ std::string children = ATTR_CAST(_states[strTo<size_t>(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<size_t>(ATTR(getParentState(state), "documentOrder")) + 1) ==
+ strTo<size_t>(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<size_t>(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");
+ }
+
+ 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;
+ }
+
+ 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::writeSystemSignalMapping(std::ostream &stream) {
+ stream << "-- system signals" << std::endl;
+ std::list<DOMElement *> topLevelFinal = DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "final",
+ _scxml);
+
+ VContainer tlf = VOR;
+ for (auto final : topLevelFinal) {
+ *tlf += VLINE("state_active_" + ATTR(final, "documentOrder") + "_sig");
+
+ }
+
+ 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;
+ }
+ }
+
+ 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 2506584..4b047da 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:
-
- virtual ~ChartToVHDL();
-
- static Transformer transform(const Interpreter &other);
-
- void writeTo(std::ostream &stream);
-
-
- struct VNode {
- virtual void print(std::ostream &stream, const std::string padding = "") = 0;
-
- virtual ~VNode() { };
- };
-
- struct VBranch : VNode {
- std::vector<VNode *> v;
-
- virtual ~VBranch() {
- for (unsigned i = 0; i < v.size(); i++)
- delete v[i];
- }
-
- VBranch &operator+=(VNode *p) {
- v.push_back(p);
- return *this;
- }
- };
-
- struct VPointer {
- VNode *ptr;
-
- operator VNode *() {
- return ptr;
- }
-
- operator VBranch *() {
- return static_cast<VBranch *> (ptr);
- }
-
- VPointer &operator/(VNode *p) {
- ptr = p;
- return *this;
- }
- };
-
- struct VContainer {
- VBranch *ptr;
-
- operator VBranch *() {
- return ptr;
- }
-
- VContainer &operator/(VBranch *p) {
- ptr = p;
- 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;
- }
- };
-
- struct VLine : VNode {
- VLine(const std::string &name) : name(name) { }
-
- virtual void print(std::ostream &stream, const std::string padding = "") {
- stream << " " << 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 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);
- }
- };
+class USCXML_API ChartToVHDL : public ChartToC {
+public:
+
+ virtual ~ChartToVHDL();
+
+ static Transformer transform(const Interpreter &other);
+
+ void writeTo(std::ostream &stream);
+
+
+ struct VNode {
+ virtual void print(std::ostream &stream, const std::string padding = "") = 0;
+
+ virtual ~VNode() { };
+ };
+
+ struct VBranch : VNode {
+ std::vector<VNode *> v;
+
+ virtual ~VBranch() {
+ for (unsigned i = 0; i < v.size(); i++)
+ delete v[i];
+ }
+
+ VBranch &operator+=(VNode *p) {
+ v.push_back(p);
+ return *this;
+ }
+ };
+
+ struct VPointer {
+ VNode *ptr;
+
+ operator VNode *() {
+ return ptr;
+ }
+
+ operator VBranch *() {
+ return static_cast<VBranch *> (ptr);
+ }
+
+ VPointer &operator/(VNode *p) {
+ ptr = p;
+ return *this;
+ }
+ };
+
+ struct VContainer {
+ VBranch *ptr;
+
+ operator VBranch *() {
+ return ptr;
+ }
+
+ VContainer &operator/(VBranch *p) {
+ ptr = p;
+ 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;
+ }
+ };
+
+ struct VLine : VNode {
+ VLine(const std::string &name) : name(name) { }
+
+ virtual void print(std::ostream &stream, const std::string padding = "") {
+ stream << " " << 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 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,71 +164,71 @@ namespace uscxml {
#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);
+ // 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 writeTransitionSet(std::ostream &stream);
+ void writeTransitionSet(std::ostream &stream);
- void writeDefaultCompletions(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<XERCESC_NS::DOMElement *> commandSequence);
+ // event generation
+ void writeExContentBlock(std::ostream &stream, std::string index,
+ std::list<XERCESC_NS::DOMElement *> commandSequence);
- Trie _eventTrie;
- std::list<XERCESC_NS::DOMElement *> _execContent;
+ Trie _eventTrie;
+ std::list<XERCESC_NS::DOMElement *> _execContent;
- private:
- std::string getLineForExecContent(const XERCESC_NS::DOMNode *elem);
+private:
+ std::string getLineForExecContent(const XERCESC_NS::DOMNode *elem);
- bool filterSupportedExecContent(XERCESC_NS::DOMElement *execContentElement);
- };
+ bool filterSupportedExecContent(XERCESC_NS::DOMElement *execContentElement);
+};
}
diff --git a/src/uscxml/transform/Transformer.h b/src/uscxml/transform/Transformer.h
index 5b2fbdb..6a9f2f3 100644
--- a/src/uscxml/transform/Transformer.h
+++ b/src/uscxml/transform/Transformer.h
@@ -39,16 +39,16 @@ public:
_binding = other.getImpl()->_binding;
}
-
-
+
+
virtual void writeTo(std::ostream& stream) = 0;
virtual operator Interpreter() {
throw std::runtime_error("Transformer cannot be interpreted as an Interpreter again");
}
- virtual XERCESC_NS::DOMDocument* getDocument() const {
- return _document;
- }
+ virtual XERCESC_NS::DOMDocument* getDocument() const {
+ return _document;
+ }
protected:
std::multimap<std::string, std::string> _extensions;
diff --git a/src/uscxml/transform/promela/PromelaCodeAnalyzer.cpp b/src/uscxml/transform/promela/PromelaCodeAnalyzer.cpp
index 7cb69d7..044e660 100644
--- a/src/uscxml/transform/promela/PromelaCodeAnalyzer.cpp
+++ b/src/uscxml/transform/promela/PromelaCodeAnalyzer.cpp
@@ -33,20 +33,20 @@ using namespace XERCESC_NS;
void PromelaCodeAnalyzer::analyze(ChartToPromela* interpreter) {
- /**
- Create macro names for state identifiers
- Do not add as literals as they are not unique with nested state-charts
- */
- {
- for (size_t i = 0; i < interpreter->_states.size(); i++) {
- DOMElement* state = interpreter->_states[i];
- if (HAS_ATTR(state, "id")) {
- createMacroName(ATTR(state, "id"));
- }
- }
- }
+ /**
+ Create macro names for state identifiers
+ Do not add as literals as they are not unique with nested state-charts
+ */
+ {
+ for (size_t i = 0; i < interpreter->_states.size(); i++) {
+ DOMElement* state = interpreter->_states[i];
+ if (HAS_ATTR(state, "id")) {
+ createMacroName(ATTR(state, "id"));
+ }
+ }
+ }
// _lastStrIndex = interpreter->_states.size();
-
+
/** Find all event names that might occur */
{
std::list<XERCESC_NS::DOMElement*> internalEventNames = DOMUtils::inDocumentOrder({
@@ -77,24 +77,24 @@ void PromelaCodeAnalyzer::analyze(ChartToPromela* interpreter) {
addEvent("done.state." + ATTR(state, "id"));
}
}
-
- std::list<XERCESC_NS::DOMElement*> invokers = DOMUtils::inDocumentOrder({XML_PREFIX(interpreter->_scxml).str() + "invoke"}, interpreter->_scxml, false);
- for (auto invoker : invokers) {
- addCode("_event.invokeid", interpreter);
-
- if (HAS_ATTR(invoker, "id")) {
- addEvent("done.state." + ATTR(invoker, "id"));
- }
- }
+
+ std::list<XERCESC_NS::DOMElement*> invokers = DOMUtils::inDocumentOrder({XML_PREFIX(interpreter->_scxml).str() + "invoke"}, interpreter->_scxml, false);
+ for (auto invoker : invokers) {
+ addCode("_event.invokeid", interpreter);
+
+ if (HAS_ATTR(invoker, "id")) {
+ addEvent("done.state." + ATTR(invoker, "id"));
+ }
+ }
+ }
+
+ // add event names from trie to string literals
+ std::list<TrieNode*> events = _eventTrie.getWordsWithPrefix("");
+ for (auto event : events) {
+ addLiteral(event->value);
}
- // add event names from trie to string literals
- std::list<TrieNode*> events = _eventTrie.getWordsWithPrefix("");
- for (auto event : events) {
- addLiteral(event->value);
- }
-
-
+
/** Find all string literals */
{
// string literals for raise / send content
@@ -103,8 +103,8 @@ void PromelaCodeAnalyzer::analyze(ChartToPromela* interpreter) {
}, interpreter->_scxml);
for (auto content : contents) {
- if (!content->hasChildNodes())
- continue;
+ if (!content->hasChildNodes())
+ continue;
std::string contentStr = spaceNormalize(X(content->getFirstChild()->getNodeValue()));
if (!isNumeric(contentStr.c_str(), 10)) {
addLiteral(contentStr);
@@ -129,7 +129,7 @@ void PromelaCodeAnalyzer::analyze(ChartToPromela* interpreter) {
if (HAS_ATTR(cond, "cond")) {
std::string code = ATTR_CAST(cond, "cond");
code = sanitizeCode(code);
- addCode(code, interpreter);
+ addCode(code, interpreter);
cond->setAttribute(X("cond"), X(code));
}
}
@@ -159,7 +159,7 @@ void PromelaCodeAnalyzer::analyze(ChartToPromela* interpreter) {
if (HAS_ATTR(location, "location")) {
std::string code = ATTR_CAST(location, "location");
code = sanitizeCode(code);
- addCode(code, interpreter);
+ addCode(code, interpreter);
location->setAttribute(X("location"), X(code));
}
}
@@ -175,7 +175,7 @@ void PromelaCodeAnalyzer::analyze(ChartToPromela* interpreter) {
std::string code = X(textText->getNodeValue()).str();
if (code.size() > 0) {
code = sanitizeCode(code);
- addCode(code, interpreter);
+ addCode(code, interpreter);
textText->setNodeValue(X(code));
}
}
@@ -186,73 +186,73 @@ void PromelaCodeAnalyzer::analyze(ChartToPromela* interpreter) {
}, interpreter->_scxml);
for (auto foreach : foreachs) {
- if (HAS_ATTR(foreach, "index")) {
- addCode(ATTR(foreach, "index"), interpreter);
- } else {
- _hasIndexLessLoops = true;
- }
- if (HAS_ATTR(foreach, "item")) {
- addCode(ATTR(foreach, "item"), interpreter);
- }
- }
-
- // do we need sendid / invokeid?
- {
- std::list<DOMElement*> invokes = DOMUtils::inDocumentOrder({XML_PREFIX(interpreter->_scxml).str() + "invoke"}, interpreter->_scxml);
- std::list<DOMElement*> sends = DOMUtils::inDocumentOrder({XML_PREFIX(interpreter->_scxml).str() + "send"}, interpreter->_scxml);
- std::list<DOMElement*> cancels = DOMUtils::inDocumentOrder({XML_PREFIX(interpreter->_scxml).str() + "cancel"}, interpreter->_scxml);
-
- if (cancels.size() > 0) {
- addCode("_event.origin", interpreter);
- _usesCancel = true;
- }
-
- for (auto send : sends) {
- if (HAS_ATTR(send, "idlocation")) {
- addCode("_event.sendid", interpreter);
- }
- if (HAS_ATTR(send, "id")) {
- addLiteral(ATTR(send, "id"));
- addCode("_event.sendid", interpreter);
- }
-
- // do we need delays?
- if (HAS_ATTR(send, "delay") || HAS_ATTR(send, "delayexpr")) {
- size_t delay = strTo<size_t>(ATTR(send, "delay"));
- if (delay > largestDelay)
- largestDelay = delay;
- addCode("_event.delay", interpreter);
+ if (HAS_ATTR(foreach, "index")) {
+ addCode(ATTR(foreach, "index"), interpreter);
+ } else {
+ _hasIndexLessLoops = true;
+ }
+ if (HAS_ATTR(foreach, "item")) {
+ addCode(ATTR(foreach, "item"), interpreter);
+ }
+ }
+
+ // do we need sendid / invokeid?
+ {
+ std::list<DOMElement*> invokes = DOMUtils::inDocumentOrder({XML_PREFIX(interpreter->_scxml).str() + "invoke"}, interpreter->_scxml);
+ std::list<DOMElement*> sends = DOMUtils::inDocumentOrder({XML_PREFIX(interpreter->_scxml).str() + "send"}, interpreter->_scxml);
+ std::list<DOMElement*> cancels = DOMUtils::inDocumentOrder({XML_PREFIX(interpreter->_scxml).str() + "cancel"}, interpreter->_scxml);
+
+ if (cancels.size() > 0) {
+ addCode("_event.origin", interpreter);
+ _usesCancel = true;
+ }
+
+ for (auto send : sends) {
+ if (HAS_ATTR(send, "idlocation")) {
+ addCode("_event.sendid", interpreter);
+ }
+ if (HAS_ATTR(send, "id")) {
+ addLiteral(ATTR(send, "id"));
+ addCode("_event.sendid", interpreter);
+ }
+
+ // do we need delays?
+ if (HAS_ATTR(send, "delay") || HAS_ATTR(send, "delayexpr")) {
+ size_t delay = strTo<size_t>(ATTR(send, "delay"));
+ if (delay > largestDelay)
+ largestDelay = delay;
+ addCode("_event.delay", interpreter);
#if NEW_DELAY_RESHUFFLE
#else
- addCode("_event.seqNr", interpreter);
+ addCode("_event.seqNr", interpreter);
#endif
- }
- }
- }
-
- // add all namelist entries to the _event structure
- {
- std::list<DOMElement*> withNamelists;
- withNamelists.splice(withNamelists.end(), DOMUtils::inDocumentOrder({XML_PREFIX(interpreter->_scxml).str() + "send"}, interpreter->_scxml));
- withNamelists.splice(withNamelists.end(), DOMUtils::inDocumentOrder({XML_PREFIX(interpreter->_scxml).str() + "invoke"}, interpreter->_scxml));
- for (auto withNamelist : withNamelists) {
- if (HAS_ATTR(withNamelist, "namelist")) {
- std::string namelist = ATTR(withNamelist, "namelist");
- std::list<std::string> names = tokenize(namelist);
- for (std::list<std::string>::iterator nameIter = names.begin(); nameIter != names.end(); nameIter++) {
- addCode("_event.data." + *nameIter + " = 0;", interpreter); // introduce for _event_t typedef
- }
- }
- }
- }
+ }
+ }
+ }
+
+ // add all namelist entries to the _event structure
+ {
+ std::list<DOMElement*> withNamelists;
+ withNamelists.splice(withNamelists.end(), DOMUtils::inDocumentOrder({XML_PREFIX(interpreter->_scxml).str() + "send"}, interpreter->_scxml));
+ withNamelists.splice(withNamelists.end(), DOMUtils::inDocumentOrder({XML_PREFIX(interpreter->_scxml).str() + "invoke"}, interpreter->_scxml));
+ for (auto withNamelist : withNamelists) {
+ if (HAS_ATTR(withNamelist, "namelist")) {
+ std::string namelist = ATTR(withNamelist, "namelist");
+ std::list<std::string> names = tokenize(namelist);
+ for (std::list<std::string>::iterator nameIter = names.begin(); nameIter != names.end(); nameIter++) {
+ addCode("_event.data." + *nameIter + " = 0;", interpreter); // introduce for _event_t typedef
+ }
+ }
+ }
+ }
}
}
void PromelaCodeAnalyzer::addEvent(const std::string& eventName) {
- addLiteral(eventName);
- _eventTrie.addWord(eventName);
+ addLiteral(eventName);
+ _eventTrie.addWord(eventName);
}
std::string PromelaCodeAnalyzer::sanitizeCode(const std::string& code) {
@@ -401,14 +401,14 @@ void PromelaCodeAnalyzer::addCode(const std::string& code, ChartToPromela* inter
}
}
-
+
void PromelaCodeAnalyzer::addLiteral(const std::string& literal, int forceIndex) {
if (boost::starts_with(literal, "'"))
throw std::runtime_error("Literal " + literal + " passed with quotes");
- if (_literals.find(literal) != _literals.end())
- return;
- _literals.insert(literal);
+ if (_literals.find(literal) != _literals.end())
+ return;
+ _literals.insert(literal);
createMacroName(literal);
enumerateLiteral(literal, forceIndex);
}
@@ -519,16 +519,16 @@ std::string PromelaCodeAnalyzer::adaptCode(const std::string& code, const std::s
lastPos = 0;
while (posIter != posList.end()) {
- std::string token = code.substr(posIter->first, posIter->second - posIter->first);
- if (std::all_of(token.begin(), token.end(), ::isupper) && false) {
- // assume it is a state-name macro
- processedStr << code.substr(lastPos, posIter->first - lastPos) << token;
- } else if (boost::starts_with(prefix, token)) {
- processedStr << code.substr(lastPos, posIter->first - lastPos) << token;
- } else {
- processedStr << code.substr(lastPos, posIter->first - lastPos) << prefix << token;
- }
- lastPos = posIter->second;
+ std::string token = code.substr(posIter->first, posIter->second - posIter->first);
+ if (std::all_of(token.begin(), token.end(), ::isupper) && false) {
+ // assume it is a state-name macro
+ processedStr << code.substr(lastPos, posIter->first - lastPos) << token;
+ } else if (boost::starts_with(prefix, token)) {
+ processedStr << code.substr(lastPos, posIter->first - lastPos) << token;
+ } else {
+ processedStr << code.substr(lastPos, posIter->first - lastPos) << prefix << token;
+ }
+ lastPos = posIter->second;
posIter++;
}
processedStr << processed.substr(lastPos, processed.size() - lastPos);
@@ -595,9 +595,9 @@ std::list<std::pair<size_t, size_t> > PromelaCodeAnalyzer::getTokenPositions(con
std::string PromelaCodeAnalyzer::getTypeReset(const std::string& var, const PromelaTypedef& type, size_t indent) {
std::stringstream assignment;
- std::string padding;
- for (size_t i = 0; i < indent; i++)
- padding += " ";
+ std::string padding;
+ for (size_t i = 0; i < indent; i++)
+ padding += " ";
std::map<std::string, PromelaTypedef>::const_iterator typeIter = type.types.begin();
while(typeIter != type.types.end()) {
@@ -618,26 +618,26 @@ std::string PromelaCodeAnalyzer::getTypeReset(const std::string& var, const Prom
}
std::string PromelaCodeAnalyzer::getTypeAssignment(const std::string& varTo, const std::string& varFrom, const PromelaTypedef& type, size_t indent) {
- std::stringstream assignment;
- std::string padding;
- for (size_t i = 0; i < indent; i++)
- padding += " ";
-
- std::map<std::string, PromelaTypedef>::const_iterator typeIter = type.types.begin();
- while(typeIter != type.types.end()) {
- const PromelaTypedef& innerType = typeIter->second;
- if (innerType.arraySize > 0) {
- for (size_t i = 0; i < innerType.arraySize; i++) {
- assignment << padding << varTo << "." << typeIter->first << "[" << i << "] = " << varFrom << "." << typeIter->first << "[" << i << "];" << std::endl;
- }
- } else if (innerType.types.size() > 0) {
- assignment << getTypeAssignment(varTo + "." + typeIter->first, varFrom + "." + typeIter->first, typeIter->second, indent);
- } else {
- assignment << padding << varTo << "." << typeIter->first << " = " << varFrom << "." << typeIter->first << ";" << std::endl;
- }
- typeIter++;
- }
- return assignment.str();
+ std::stringstream assignment;
+ std::string padding;
+ for (size_t i = 0; i < indent; i++)
+ padding += " ";
+
+ std::map<std::string, PromelaTypedef>::const_iterator typeIter = type.types.begin();
+ while(typeIter != type.types.end()) {
+ const PromelaTypedef& innerType = typeIter->second;
+ if (innerType.arraySize > 0) {
+ for (size_t i = 0; i < innerType.arraySize; i++) {
+ assignment << padding << varTo << "." << typeIter->first << "[" << i << "] = " << varFrom << "." << typeIter->first << "[" << i << "];" << std::endl;
+ }
+ } else if (innerType.types.size() > 0) {
+ assignment << getTypeAssignment(varTo + "." + typeIter->first, varFrom + "." + typeIter->first, typeIter->second, indent);
+ } else {
+ assignment << padding << varTo << "." << typeIter->first << " = " << varFrom << "." << typeIter->first << ";" << std::endl;
+ }
+ typeIter++;
+ }
+ return assignment.str();
}
}
diff --git a/src/uscxml/transform/promela/PromelaCodeAnalyzer.h b/src/uscxml/transform/promela/PromelaCodeAnalyzer.h
index 83ee684..7f69ac9 100644
--- a/src/uscxml/transform/promela/PromelaCodeAnalyzer.h
+++ b/src/uscxml/transform/promela/PromelaCodeAnalyzer.h
@@ -64,10 +64,10 @@ public:
return true;
return false;
}
- bool usesCancel(const std::string& elementName) {
- return _usesCancel;
- }
-
+ bool usesCancel(const std::string& elementName) {
+ return _usesCancel;
+ }
+
bool usesEventDataField(const std::string& fieldName) {
if (usesComplexEventStruct() &&
_typeDefs.types["_event"].types.find("data") != _typeDefs.types["_event"].types.end() &&
@@ -76,8 +76,8 @@ public:
return false;
}
- size_t largestDelay = 0;
-
+ size_t largestDelay = 0;
+
std::string getTypeAssignment(const std::string& varTo, const std::string& varFrom, const PromelaTypedef& type, size_t indent = 0);
std::string getTypeReset(const std::string& var, const PromelaTypedef& type, size_t indent = 0);
@@ -91,9 +91,9 @@ public:
return _usesPlatformVars;
}
- bool hasIndexLessLoops() {
- return _hasIndexLessLoops;
- }
+ bool hasIndexLessLoops() {
+ return _hasIndexLessLoops;
+ }
std::string macroForLiteral(const std::string& literal);
int indexForLiteral(const std::string& literal);
@@ -121,17 +121,17 @@ public:
}
std::string sanitizeCode(const std::string& code);
- void addEvent(const std::string& eventName);
- std::string createMacroName(const std::string& literal);
+ void addEvent(const std::string& eventName);
+ std::string createMacroName(const std::string& literal);
protected:
- void addState(const std::string& stateName, size_t index);
+ void addState(const std::string& stateName, size_t index);
int enumerateLiteral(const std::string& literal, int forceIndex = -1);
std::map<std::string, std::string> _strMacros; // macronames for string literals
std::map<std::string, int> _strIndex; // integer enumeration for string
- std::set<std::string> _literals;
+ std::set<std::string> _literals;
PromelaTypedef _typeDefs;
Trie _eventTrie;
@@ -139,8 +139,8 @@ protected:
private:
std::set<std::string> _macroNameSet; // helper set for uniqueness of macros
int _lastStrIndex = 1;
- bool _usesCancel = false;
- bool _usesInPredicate = false;
+ bool _usesCancel = false;
+ bool _usesInPredicate = false;
bool _usesPlatformVars = false;
bool _hasIndexLessLoops = false;
};
diff --git a/src/uscxml/util/String.cpp b/src/uscxml/util/String.cpp
index ae1aa68..6a80756 100644
--- a/src/uscxml/util/String.cpp
+++ b/src/uscxml/util/String.cpp
@@ -26,26 +26,25 @@ 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="";
+ // 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()){
+ 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<std::string> strHash;
returnValue += "_";
returnValue += strHash(specialChars);
}
- return returnValue;
+ return returnValue;
}
std::list<std::string> tokenize(const std::string& line, const char sep, bool trimWhiteSpace) {