summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Radomski <github@mintwerk.de>2016-11-23 09:44:43 (GMT)
committerStefan Radomski <github@mintwerk.de>2016-11-23 09:44:43 (GMT)
commit63d1783beadf2f365de990e198dbb9c8cb885586 (patch)
treeb7fd2b69529b6887e7e2b402e21614b31127902d
parent0c7c61257e8277ea6c05451da9a6f0bfd0fe7eea (diff)
parent84df16100bb76a99e6d6474dc118d94fc271d5dd (diff)
downloaduscxml-63d1783beadf2f365de990e198dbb9c8cb885586.zip
uscxml-63d1783beadf2f365de990e198dbb9c8cb885586.tar.gz
uscxml-63d1783beadf2f365de990e198dbb9c8cb885586.tar.bz2
Merge branch 'master' of github.com:tklab-tud/uscxml
-rw-r--r--src/uscxml/transform/ChartToVHDL.cpp89
-rw-r--r--src/uscxml/transform/ChartToVHDL.h329
-rw-r--r--src/uscxml/util/String.cpp27
-rw-r--r--src/uscxml/util/String.h2
-rw-r--r--test/w3c/ecma/test144.scxml2
5 files changed, 252 insertions, 197 deletions
diff --git a/src/uscxml/transform/ChartToVHDL.cpp b/src/uscxml/transform/ChartToVHDL.cpp
index 6b4eebf..5061e33 100644
--- a/src/uscxml/transform/ChartToVHDL.cpp
+++ b/src/uscxml/transform/ChartToVHDL.cpp
@@ -138,6 +138,11 @@ namespace uscxml {
}
+ 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();
@@ -176,7 +181,7 @@ namespace uscxml {
for (std::list<TrieNode *>::iterator eventIter = eventNames.begin();
eventIter != eventNames.end(); eventIter++) {
- stream << seperator << "hwe_" << escapedMacro((*eventIter)->value);
+ stream << seperator << "hwe_" << escapeMacro((*eventIter)->value);
seperator = ", ";
}
stream << " );" << std::endl;
@@ -205,7 +210,7 @@ namespace uscxml {
stream << "end entity tb;" << std::endl;
stream << std::endl;
- stream << "architecture bhv of tb is" << std::endl;
+ stream << "architecture behavioral of tb is" << std::endl;
stream << std::endl;
// modules
@@ -404,6 +409,40 @@ namespace uscxml {
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;
@@ -539,12 +578,11 @@ namespace uscxml {
for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) {
DOMElement *exContentElem = *ecIter;
- if (TAGNAME(exContentElem) == XML_PREFIX(_scxml).str() + "raise" ||
- TAGNAME(exContentElem) == XML_PREFIX(_scxml).str() + "send") {
+ if (filterSupportedExecContent(exContentElem)) {
stream << seperator << "if start_" << toStr(i) << "_sig = '1' then"
<< std::endl;
- stream << " event_bus <= hwe_" << escapedMacro(ATTR(exContentElem, "event"))
+ stream << " event_bus <= hwe_" << escapeMacro(ATTR(exContentElem, "event"))
<< ";" << std::endl;
stream << " done_" << toStr(i) << "_sig <= '1';" << std::endl;
stream << " event_we <= '1';" << std::endl;
@@ -556,8 +594,7 @@ namespace uscxml {
//for (auto exContentElem : _execContent) {
for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) {
DOMElement *exContentElem = *ecIter;
- //TODO y not send here --> general filter function ?
- if (TAGNAME(exContentElem) == XML_PREFIX(_scxml).str() + "raise") {
+ if (filterSupportedExecContent(exContentElem)) {
stream << " done_" << toStr(i) << "_sig <= '0';" << std::endl;
}
}
@@ -588,18 +625,16 @@ namespace uscxml {
if (_execContent.size() > 1) {
i = 0;
for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) {
- if (i == 0) {
- // prevent writing seq_0_sig since this should be hardcoded to '1'
- continue;
+ // 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;
}
- // 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;
@@ -866,7 +901,7 @@ namespace uscxml {
std::list<TrieNode *> eventNames = _eventTrie.getWordsWithPrefix("");
for (std::list<TrieNode *>::iterator eventIter = eventNames.begin();
eventIter != eventNames.end(); eventIter++) {
- stream << "signal event_" << escapedMacro((*eventIter)->value) << "_sig : std_logic;" << std::endl;
+ stream << "signal event_" << escapeMacro((*eventIter)->value) << "_sig : std_logic;" << std::endl;
}
stream << std::endl;
@@ -940,7 +975,7 @@ namespace uscxml {
stream << " if spontaneous_en = '1' then" << std::endl;
stream << " spontaneous_en <= optimal_transition_set_combined_sig;" << std::endl;
stream << " else" << std::endl;
- //TODO if new event is dequeued then 1 else stay 0
+ //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;
@@ -959,7 +994,7 @@ namespace uscxml {
std::list<TrieNode *> eventNames = _eventTrie.getWordsWithPrefix("");
for (std::list<TrieNode *>::iterator eventIter = eventNames.begin();
eventIter != eventNames.end(); eventIter++) {
- stream << " event_" << escapedMacro((*eventIter)->value) << "_sig <= '0';" << std::endl;
+ stream << " event_" << escapeMacro((*eventIter)->value) << "_sig <= '0';" << std::endl;
}
stream << " next_event_dequeued <= '0';" << std::endl;
@@ -987,11 +1022,11 @@ namespace uscxml {
for (std::list<TrieNode *>::iterator eventIter = eventNames.begin();
eventIter != eventNames.end(); eventIter++) {
stream << " when hwe_"
- << escapedMacro((*eventIter)->value) << " =>" << std::endl;
+ << escapeMacro((*eventIter)->value) << " =>" << std::endl;
for (std::list<TrieNode *>::iterator eventIter2 = eventNames.begin();
eventIter2 != eventNames.end(); eventIter2++) {
- stream << " event_" << escapedMacro((*eventIter2)->value);
- if (escapedMacro((*eventIter)->value) == escapedMacro((*eventIter2)->value)) {
+ stream << " event_" << escapeMacro((*eventIter2)->value);
+ if (escapeMacro((*eventIter)->value) == escapeMacro((*eventIter2)->value)) {
stream << "_sig <= '1';" << std::endl;
} else {
stream << "_sig <= '0';" << std::endl;
@@ -1002,7 +1037,7 @@ namespace uscxml {
stream << " when others =>" << std::endl;
for (std::list<TrieNode *>::iterator eventIter = eventNames.begin();
eventIter != eventNames.end(); eventIter++) {
- stream << " event_" << escapedMacro((*eventIter)->value) << "_sig <= '0';" << std::endl;
+ stream << " event_" << escapeMacro((*eventIter)->value) << "_sig <= '0';" << std::endl;
}
stream << " next_event_dequeued <= '0';" << std::endl;
stream << " end case;" << std::endl;
@@ -1010,7 +1045,7 @@ namespace uscxml {
for (std::list<TrieNode *>::iterator eventIter = eventNames.begin();
eventIter != eventNames.end(); eventIter++) {
- stream << " event_" << escapedMacro((*eventIter)->value) << "_sig <= '0';" << std::endl;
+ stream << " event_" << escapeMacro((*eventIter)->value) << "_sig <= '0';" << std::endl;
}
stream << " next_event_dequeued <= '0';" << std::endl;
stream << " end if;" << std::endl;
@@ -1072,7 +1107,7 @@ namespace uscxml {
(*descIter) == "*" ? "" : *descIter);
for (std::list<TrieNode *>::iterator eventIter = eventNames.begin();
eventIter != eventNames.end(); eventIter++) {
- *nameMatchers += VLINE("event_" + escapedMacro((*eventIter)->value) + "_sig");
+ *nameMatchers += VLINE("event_" + escapeMacro((*eventIter)->value) + "_sig");
}
}
} else {
diff --git a/src/uscxml/transform/ChartToVHDL.h b/src/uscxml/transform/ChartToVHDL.h
index a46265d..2506584 100644
--- a/src/uscxml/transform/ChartToVHDL.h
+++ b/src/uscxml/transform/ChartToVHDL.h
@@ -31,121 +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
@@ -156,54 +164,71 @@ public:
#define VNOP VContainer()/new VNop
+ protected:
+ ChartToVHDL(const Interpreter &other);
-protected:
- ChartToVHDL(const Interpreter& other);
+ void checkDocument();
- void checkDocument();
- void findEvents();
+ void findEvents();
- void writeTypes(std::ostream& stream);
- void writeIncludes(std::ostream& stream);
+ void writeTypes(std::ostream &stream);
- // top layer components
- void writeFiFo(std::ostream& stream);
- void writeEventController(std::ostream & stream);
- void writeMicroStepper(std::ostream& stream);
- void writeTestbench(std::ostream & stream);
+ void writeIncludes(std::ostream &stream);
- // system
- void writeSignalsAndComponents(std::ostream& stream);
- void writeSystemSignalMapping(std::ostream& stream);
- void writeModuleInstantiation(std::ostream& stream);
+ // top layer components
+ void writeFiFo(std::ostream &stream);
- // combinatorial logic
- void writeOptimalTransitionSetSelection(std::ostream& stream);
- void writeExitSet(std::ostream & stream);
- void writeEntrySet(std::ostream & stream);
- void writeTransitionSet(std::ostream & stream);
- void writeDefaultCompletions(std::ostream & stream);
- void writeCompleteEntrySet(std::ostream & stream);
- void writeActiveStateNplusOne(std::ostream & stream);
+ void writeEventController(std::ostream &stream);
- // handler
- void writeStateHandler(std::ostream& stream);
- void writeResetHandler(std::ostream & stream);
- void writeSpontaneousHandler(std::ostream & stream);
- void writeInternalEventHandler(std::ostream & stream);
- void writeErrorHandler(std::ostream& stream);
+ void writeMicroStepper(std::ostream &stream);
- // event generation
- void writeExContentBlock(std::ostream & stream, std::string index,
- std::list< XERCESC_NS::DOMElement* > commandSequence);
+ void writeTestbench(std::ostream &stream);
- Trie _eventTrie;
- std::list< XERCESC_NS::DOMElement* > _execContent;
+ // system
+ void writeSignalsAndComponents(std::ostream &stream);
-private:
- std::string getLineForExecContent(const XERCESC_NS::DOMNode* elem);
+ void writeSystemSignalMapping(std::ostream &stream);
-};
+ void writeModuleInstantiation(std::ostream &stream);
+
+ // combinatorial logic
+ void writeOptimalTransitionSetSelection(std::ostream &stream);
+
+ void writeExitSet(std::ostream &stream);
+
+ void writeEntrySet(std::ostream &stream);
+
+ void writeTransitionSet(std::ostream &stream);
+
+ void writeDefaultCompletions(std::ostream &stream);
+
+ void writeCompleteEntrySet(std::ostream &stream);
+
+ void writeActiveStateNplusOne(std::ostream &stream);
+
+ // handler
+ void writeStateHandler(std::ostream &stream);
+
+ void writeResetHandler(std::ostream &stream);
+
+ void writeSpontaneousHandler(std::ostream &stream);
+
+ void writeInternalEventHandler(std::ostream &stream);
+
+ void writeErrorHandler(std::ostream &stream);
+
+ // event generation
+ void writeExContentBlock(std::ostream &stream, std::string index,
+ std::list<XERCESC_NS::DOMElement *> commandSequence);
+
+ Trie _eventTrie;
+ std::list<XERCESC_NS::DOMElement *> _execContent;
+
+ private:
+ std::string getLineForExecContent(const XERCESC_NS::DOMNode *elem);
+
+ bool filterSupportedExecContent(XERCESC_NS::DOMElement *execContentElement);
+ };
}
diff --git a/src/uscxml/util/String.cpp b/src/uscxml/util/String.cpp
index 24c7d42..ae1aa68 100644
--- a/src/uscxml/util/String.cpp
+++ b/src/uscxml/util/String.cpp
@@ -25,31 +25,26 @@ namespace uscxml {
#define ISWHITESPACE(char) (isspace(char))
-std::string escapedMacro(std::string const& s) {
+std::string escapeMacro(std::string const &s) {
// inspired by http://stackoverflow.com/questions/2417588/escaping-a-c-string
std::string returnValue="";
+ std::string specialChars="";
for (std::string::const_iterator iter = s.begin(), end = s.end(); iter != end; ++iter) {
char c = *iter;
- if (' ' <= c && c <= '~' && c != '\\' && c != '"') {
+ if (('0' <= c && c <= '9') || ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || c == '_') {
returnValue += c;
}
else {
- returnValue += "__";
- switch(c) {
- case '"': returnValue += "COLON"; break;
- case '\\': returnValue += "BACHSLASH"; break;
- case '\t': returnValue += "TAB"; break;
- case '\r': returnValue += "RETURN"; break;
- case '\n': returnValue += "NEWLINE"; break;
- default:
- char const* const hexdig = "0123456789ABCDEF";
- returnValue += 'x';
- returnValue += hexdig[c >> 4];
- returnValue += hexdig[c & 0xF];
- }
- returnValue += "__";
+ 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;
}
diff --git a/src/uscxml/util/String.h b/src/uscxml/util/String.h
index 9acd288..8d9c9ef 100644
--- a/src/uscxml/util/String.h
+++ b/src/uscxml/util/String.h
@@ -25,7 +25,7 @@
namespace uscxml {
-std::string escapedMacro(std::string const& s);
+std::string escapeMacro(std::string const &s);
std::list<std::string> tokenize(const std::string& line, const char seperator = ' ', bool trimWhiteSpace = true);
std::string spaceNormalize(const std::string& text);
bool nameMatch(const std::string& eventDescs, const std::string& event);
diff --git a/test/w3c/ecma/test144.scxml b/test/w3c/ecma/test144.scxml
index e47f3f0..76ee416 100644
--- a/test/w3c/ecma/test144.scxml
+++ b/test/w3c/ecma/test144.scxml
@@ -5,7 +5,7 @@ foo occurs before bar, success, otherwise failure -->
<state id="s0">
<onentry>
<raise event="foo"/>
- <raise event="*"/>
+ <raise event="bar"/>
</onentry>
<transition event="foo" target="s1"/>
<transition event="*" target="fail"/>