From 7b55e48d57c061bd65e7718a41bfddd90084345e Mon Sep 17 00:00:00 2001 From: Stefan Radomski Date: Mon, 12 Dec 2016 13:58:40 +0100 Subject: Added test / example for pausable eventqueue --- src/uscxml/debug/DebuggerServlet.cpp | 32 +- src/uscxml/debug/DebuggerServlet.h | 2 +- src/uscxml/interpreter/BasicContentExecutor.cpp | 6 +- src/uscxml/interpreter/BasicContentExecutor.h | 2 +- src/uscxml/interpreter/BasicDelayedEventQueue.cpp | 4 +- src/uscxml/interpreter/BasicDelayedEventQueue.h | 12 +- src/uscxml/interpreter/BasicEventQueue.cpp | 14 +- src/uscxml/interpreter/BasicEventQueue.h | 2 +- src/uscxml/interpreter/ContentExecutor.cpp | 2 +- src/uscxml/interpreter/ContentExecutor.h | 4 +- src/uscxml/interpreter/ContentExecutorImpl.h | 10 +- src/uscxml/interpreter/EventQueue.cpp | 8 +- src/uscxml/interpreter/EventQueue.h | 6 +- src/uscxml/interpreter/EventQueueImpl.h | 4 +- src/uscxml/interpreter/FastMicroStep.cpp | 4 +- src/uscxml/interpreter/FastMicroStep.h | 2 +- src/uscxml/interpreter/Logging.cpp | 64 +- src/uscxml/interpreter/Logging.h | 46 +- src/uscxml/interpreter/LoggingImpl.h | 10 +- src/uscxml/interpreter/MicroStep.cpp | 2 +- src/uscxml/interpreter/MicroStep.h | 2 +- src/uscxml/interpreter/MicroStepImpl.h | 4 +- src/uscxml/interpreter/StdOutLogger.cpp | 6 +- src/uscxml/messages/Data.h | 4 +- src/uscxml/messages/Event.h | 14 +- src/uscxml/plugins/DataModelImpl.h | 4 +- src/uscxml/plugins/ExecutableContentImpl.h | 4 +- src/uscxml/plugins/Invoker.h | 6 +- src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp | 28 +- src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp | 43 +- src/uscxml/transform/ChartToJava.cpp | 104 +- src/uscxml/transform/ChartToVHDL.cpp | 2894 ++++++++++---------- src/uscxml/transform/ChartToVHDL.h | 266 +- src/uscxml/util/String.cpp | 2 +- src/uscxml/util/URL.cpp | 72 +- src/uscxml/util/URL.h | 30 +- test/CMakeLists.txt | 1 + test/src/test-extensions.cpp | 168 ++ test/src/test-snippets.cpp | 2 +- 39 files changed, 2035 insertions(+), 1855 deletions(-) create mode 100644 test/src/test-extensions.cpp diff --git a/src/uscxml/debug/DebuggerServlet.cpp b/src/uscxml/debug/DebuggerServlet.cpp index 5e3159b..016d67c 100644 --- a/src/uscxml/debug/DebuggerServlet.cpp +++ b/src/uscxml/debug/DebuggerServlet.cpp @@ -238,26 +238,26 @@ void DebuggerServlet::processListSessions(const HTTPServer::Request& request) { returnData(request, replyData); } - /* +/* void DebuggerServlet::handle(const el::LogDispatchData* data) { } void DebuggerServlet::send(google::LogSeverity severity, const char* full_filename, - const char* base_filename, int line, - const struct ::tm* tm_time, - const char* message, size_t message_len) { - - // _sendQueue is thread-safe, not sure about ToString though - - LogMessage msg(severity, - full_filename, - base_filename, - line, - tm_time, - std::string(message, message_len), - ToString(severity, base_filename, line, tm_time, message, message_len)); - msg.compound["replyType"] = Data("log", Data::VERBATIM); - pushData(std::shared_ptr(), msg); + const char* base_filename, int line, + const struct ::tm* tm_time, + const char* message, size_t message_len) { + +// _sendQueue is thread-safe, not sure about ToString though + +LogMessage msg(severity, + full_filename, + base_filename, + line, + tm_time, + std::string(message, message_len), + ToString(severity, base_filename, line, tm_time, message, message_len)); +msg.compound["replyType"] = Data("log", Data::VERBATIM); +pushData(std::shared_ptr(), msg); } */ diff --git a/src/uscxml/debug/DebuggerServlet.h b/src/uscxml/debug/DebuggerServlet.h index 7e0f66b..05e1397 100644 --- a/src/uscxml/debug/DebuggerServlet.h +++ b/src/uscxml/debug/DebuggerServlet.h @@ -91,7 +91,7 @@ public: const char* base_filename, int line, const struct ::tm* tm_time, const char* message, size_t message_len); - void handle(const el::LogDispatchData* data); + void handle(const el::LogDispatchData* data); */ protected: diff --git a/src/uscxml/interpreter/BasicContentExecutor.cpp b/src/uscxml/interpreter/BasicContentExecutor.cpp index 0c77dfd..376561d 100644 --- a/src/uscxml/interpreter/BasicContentExecutor.cpp +++ b/src/uscxml/interpreter/BasicContentExecutor.cpp @@ -36,7 +36,7 @@ namespace uscxml { using namespace XERCESC_NS; std::shared_ptr BasicContentExecutor::create(ContentExecutorCallbacks* callbacks) { - return std::shared_ptr(new BasicContentExecutor(callbacks)); + return std::shared_ptr(new BasicContentExecutor(callbacks)); } void BasicContentExecutor::processRaise(XERCESC_NS::DOMElement* content) { @@ -635,13 +635,13 @@ Data BasicContentExecutor::elementAsData(XERCESC_NS::DOMElement* element) { contentSS << X((*textIter)->getNodeValue()); } #if 0 - try { + try { Data d = _callbacks->getAsData(contentSS.str()); if (!d.empty()) return d; } catch(...) {} #endif - // test294, test562 + // test294, test562 return Data(spaceNormalize(contentSS.str()), Data::VERBATIM); } } diff --git a/src/uscxml/interpreter/BasicContentExecutor.h b/src/uscxml/interpreter/BasicContentExecutor.h index 14f7881..db53eb2 100644 --- a/src/uscxml/interpreter/BasicContentExecutor.h +++ b/src/uscxml/interpreter/BasicContentExecutor.h @@ -35,7 +35,7 @@ public: BasicContentExecutor(ContentExecutorCallbacks* callbacks) : ContentExecutorImpl(callbacks) {} virtual ~BasicContentExecutor() {} - virtual std::shared_ptr create(ContentExecutorCallbacks* callbacks); + virtual std::shared_ptr create(ContentExecutorCallbacks* callbacks); void processRaise(XERCESC_NS::DOMElement* content); void processSend(XERCESC_NS::DOMElement* element); diff --git a/src/uscxml/interpreter/BasicDelayedEventQueue.cpp b/src/uscxml/interpreter/BasicDelayedEventQueue.cpp index 3ad9ebd..5081e05 100644 --- a/src/uscxml/interpreter/BasicDelayedEventQueue.cpp +++ b/src/uscxml/interpreter/BasicDelayedEventQueue.cpp @@ -64,7 +64,7 @@ BasicDelayedEventQueue::~BasicDelayedEventQueue() { } std::shared_ptr BasicDelayedEventQueue::create(DelayedEventQueueCallbacks* callbacks) { - return std::shared_ptr(new BasicDelayedEventQueue(callbacks)); + return std::shared_ptr(new BasicDelayedEventQueue(callbacks)); } void BasicDelayedEventQueue::timerCallback(evutil_socket_t fd, short what, void *arg) { @@ -93,6 +93,8 @@ void BasicDelayedEventQueue::enqueueDelayed(const Event& event, size_t delayMs, struct event* e = event_new(_eventLoop, -1, 0, timerCallback, &_callbackData[eventUUID]); _callbackData[eventUUID].event = e; + gettimeofday(&(_callbackData[eventUUID].added), NULL); + timeradd(&delay, &_callbackData[eventUUID].added, &_callbackData[eventUUID].due); event_add(e, &delay); } diff --git a/src/uscxml/interpreter/BasicDelayedEventQueue.h b/src/uscxml/interpreter/BasicDelayedEventQueue.h index 8666e9c..df5b13f 100644 --- a/src/uscxml/interpreter/BasicDelayedEventQueue.h +++ b/src/uscxml/interpreter/BasicDelayedEventQueue.h @@ -40,7 +40,7 @@ class USCXML_API BasicDelayedEventQueue : public BasicEventQueue, public Delayed public: BasicDelayedEventQueue(DelayedEventQueueCallbacks* callbacks); virtual ~BasicDelayedEventQueue(); - virtual std::shared_ptr create(DelayedEventQueueCallbacks* callbacks); + virtual std::shared_ptr create(DelayedEventQueueCallbacks* callbacks); virtual void enqueueDelayed(const Event& event, size_t delayMs, const std::string& eventUUID); virtual void cancelDelayed(const std::string& eventId); virtual void cancelAllDelayed(); @@ -53,10 +53,10 @@ public: virtual void reset(); protected: - virtual std::shared_ptr create() { - ErrorEvent e("Cannot create a DelayedEventQueue without callbacks"); - throw e; - } + virtual std::shared_ptr create() { + ErrorEvent e("Cannot create a DelayedEventQueue without callbacks"); + throw e; + } struct callbackData { Event userData; @@ -64,6 +64,8 @@ protected: bool persist; struct event *event; BasicDelayedEventQueue* eventQueue; + timeval added; + timeval due; }; bool _isStarted; diff --git a/src/uscxml/interpreter/BasicEventQueue.cpp b/src/uscxml/interpreter/BasicEventQueue.cpp index 3b51117..104c9fa 100644 --- a/src/uscxml/interpreter/BasicEventQueue.cpp +++ b/src/uscxml/interpreter/BasicEventQueue.cpp @@ -22,6 +22,8 @@ #include #include +//#include + #include "uscxml/interpreter/Logging.h" namespace uscxml { @@ -36,12 +38,18 @@ Event BasicEventQueue::dequeue(size_t blockMs) { if (blockMs > 0) { - // block for given milliseconds or until queue is filled + // block for given milliseconds or until queue is non-empty auto endTime = std::chrono::system_clock::now() + std::chrono::milliseconds(blockMs); +// std::time_t ttp = std::chrono::system_clock::to_time_t(endTime); +// std::cout << "End: " << ttp << std::endl; +// std::cout << "Now: " << std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()) << std::endl; - while (_queue.empty()) { + while (endTime > std::chrono::system_clock::now() && _queue.empty()) { _cond.wait_until(_mutex, endTime); +// std::cout << "Aft: " << std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()) << std::endl; +// std::cout << blockMs << "."; } + } if (_queue.size() > 0) { @@ -66,7 +74,7 @@ void BasicEventQueue::reset() { } std::shared_ptr BasicEventQueue::create() { - return std::shared_ptr(new BasicEventQueue()); + return std::shared_ptr(new BasicEventQueue()); } } diff --git a/src/uscxml/interpreter/BasicEventQueue.h b/src/uscxml/interpreter/BasicEventQueue.h index f9b6965..927b9c4 100644 --- a/src/uscxml/interpreter/BasicEventQueue.h +++ b/src/uscxml/interpreter/BasicEventQueue.h @@ -38,7 +38,7 @@ class USCXML_API BasicEventQueue : public EventQueueImpl { public: BasicEventQueue(); virtual ~BasicEventQueue(); - virtual std::shared_ptr create(); + virtual std::shared_ptr create(); virtual Event dequeue(size_t blockMs); virtual void enqueue(const Event& event); virtual void reset(); diff --git a/src/uscxml/interpreter/ContentExecutor.cpp b/src/uscxml/interpreter/ContentExecutor.cpp index aa623b6..ca9d877 100644 --- a/src/uscxml/interpreter/ContentExecutor.cpp +++ b/src/uscxml/interpreter/ContentExecutor.cpp @@ -44,7 +44,7 @@ void ContentExecutor::raiseDoneEvent(XERCESC_NS::DOMElement* state, XERCESC_NS:: } std::shared_ptr ContentExecutor::getImpl() const { - return _impl; + return _impl; } } diff --git a/src/uscxml/interpreter/ContentExecutor.h b/src/uscxml/interpreter/ContentExecutor.h index ae8ec64..1559c5c 100644 --- a/src/uscxml/interpreter/ContentExecutor.h +++ b/src/uscxml/interpreter/ContentExecutor.h @@ -48,8 +48,8 @@ public: virtual void uninvoke(XERCESC_NS::DOMElement* invoke); virtual Data elementAsData(XERCESC_NS::DOMElement* element); virtual void raiseDoneEvent(XERCESC_NS::DOMElement* state, XERCESC_NS::DOMElement* doneData); - virtual std::shared_ptr getImpl() const; - + virtual std::shared_ptr getImpl() const; + protected: std::shared_ptr _impl; }; diff --git a/src/uscxml/interpreter/ContentExecutorImpl.h b/src/uscxml/interpreter/ContentExecutorImpl.h index c085756..7eaebbc 100644 --- a/src/uscxml/interpreter/ContentExecutorImpl.h +++ b/src/uscxml/interpreter/ContentExecutorImpl.h @@ -29,14 +29,14 @@ #include namespace XERCESC_NS { - class DOMDocument; - class DOMNode; +class DOMDocument; +class DOMNode; } namespace uscxml { class X; - + /** * @ingroup execcontent * @ingroup callback @@ -84,8 +84,8 @@ class USCXML_API ContentExecutorImpl { public: ContentExecutorImpl(ContentExecutorCallbacks* callbacks) : _callbacks(callbacks) {} - virtual std::shared_ptr create(ContentExecutorCallbacks* callbacks) = 0; - + virtual std::shared_ptr create(ContentExecutorCallbacks* callbacks) = 0; + virtual void process(XERCESC_NS::DOMElement* block, const X& xmlPrefix) = 0; virtual void invoke(XERCESC_NS::DOMElement* invoke) = 0; diff --git a/src/uscxml/interpreter/EventQueue.cpp b/src/uscxml/interpreter/EventQueue.cpp index ab199b4..9b345d5 100644 --- a/src/uscxml/interpreter/EventQueue.cpp +++ b/src/uscxml/interpreter/EventQueue.cpp @@ -43,11 +43,11 @@ void EventQueue::reset() { } std::shared_ptr EventQueue::getImplBase() { - return _impl; + return _impl; } - - + + PIMPL_OPERATORS_INHERIT_IMPL(DelayedEventQueue, EventQueue) void DelayedEventQueue::enqueueDelayed(const Event& event, size_t delayMs, const std::string& eventUUID) { @@ -62,7 +62,7 @@ void DelayedEventQueue::cancelAllDelayed() { } std::shared_ptr DelayedEventQueue::getImplDelayed() { - return _impl; + return _impl; } } diff --git a/src/uscxml/interpreter/EventQueue.h b/src/uscxml/interpreter/EventQueue.h index 7356b23..5ca1f52 100644 --- a/src/uscxml/interpreter/EventQueue.h +++ b/src/uscxml/interpreter/EventQueue.h @@ -39,7 +39,7 @@ public: virtual Event dequeue(size_t blockMs); virtual void enqueue(const Event& event); virtual void reset(); - virtual std::shared_ptr getImplBase(); + virtual std::shared_ptr getImplBase(); protected: std::shared_ptr _impl; @@ -57,8 +57,8 @@ public: void enqueueDelayed(const Event& event, size_t delayMs, const std::string& eventUUID); void cancelDelayed(const std::string& eventUUID); void cancelAllDelayed(); - virtual std::shared_ptr getImplDelayed(); - + virtual std::shared_ptr getImplDelayed(); + protected: std::shared_ptr _impl; }; diff --git a/src/uscxml/interpreter/EventQueueImpl.h b/src/uscxml/interpreter/EventQueueImpl.h index 68c6d7c..2a33a75 100644 --- a/src/uscxml/interpreter/EventQueueImpl.h +++ b/src/uscxml/interpreter/EventQueueImpl.h @@ -38,7 +38,7 @@ namespace uscxml { */ class USCXML_API EventQueueImpl { public: - virtual std::shared_ptr create() = 0; + virtual std::shared_ptr create() = 0; virtual Event dequeue(size_t blockMs) = 0; virtual void enqueue(const Event& event) = 0; virtual void reset() = 0; @@ -59,7 +59,7 @@ public: */ class USCXML_API DelayedEventQueueImpl : public EventQueueImpl { public: - virtual std::shared_ptr create(DelayedEventQueueCallbacks*) = 0; + virtual std::shared_ptr create(DelayedEventQueueCallbacks*) = 0; virtual void enqueueDelayed(const Event& event, size_t delayMs, const std::string& eventUUID) = 0; virtual void cancelDelayed(const std::string& eventId) = 0; virtual void cancelAllDelayed() = 0; diff --git a/src/uscxml/interpreter/FastMicroStep.cpp b/src/uscxml/interpreter/FastMicroStep.cpp index 6a5f9a1..ed11fca 100644 --- a/src/uscxml/interpreter/FastMicroStep.cpp +++ b/src/uscxml/interpreter/FastMicroStep.cpp @@ -90,7 +90,7 @@ FastMicroStep::~FastMicroStep() { } std::shared_ptr FastMicroStep::create(MicroStepCallbacks* callbacks) { - return std::shared_ptr(new FastMicroStep(callbacks)); + return std::shared_ptr(new FastMicroStep(callbacks)); } void FastMicroStep::resortStates(DOMElement* element, const X& xmlPrefix) { @@ -1162,7 +1162,7 @@ bool FastMicroStep::hasLegalConfiguration() { if (isMember(childs[j], config)) { if (foundChildState) { LOG(USCXML_ERROR) << "Invalid configuration: Multiple childs of compound '" << ATTR_CAST(config[i], "id") - << "' are active '" << ATTR_CAST(foundChildState, "id") << "' and '" << ATTR_CAST(childs[j], "id") << "'"; + << "' are active '" << ATTR_CAST(foundChildState, "id") << "' and '" << ATTR_CAST(childs[j], "id") << "'"; return false; } foundChildState = childs[j]; diff --git a/src/uscxml/interpreter/FastMicroStep.h b/src/uscxml/interpreter/FastMicroStep.h index faf5f45..810b793 100644 --- a/src/uscxml/interpreter/FastMicroStep.h +++ b/src/uscxml/interpreter/FastMicroStep.h @@ -43,7 +43,7 @@ class FastMicroStep : public MicroStepImpl { public: FastMicroStep(MicroStepCallbacks* callbacks); virtual ~FastMicroStep(); - virtual std::shared_ptr create(MicroStepCallbacks* callbacks); + virtual std::shared_ptr create(MicroStepCallbacks* callbacks); virtual InterpreterState step(size_t blockMs); virtual void reset(); diff --git a/src/uscxml/interpreter/Logging.cpp b/src/uscxml/interpreter/Logging.cpp index bdb847a..70c29de 100644 --- a/src/uscxml/interpreter/Logging.cpp +++ b/src/uscxml/interpreter/Logging.cpp @@ -28,25 +28,25 @@ namespace uscxml { std::shared_ptr LoggerImpl::_defaultLogger; std::shared_ptr LoggerImpl::getDefault() { - if (!_defaultLogger) - _defaultLogger = std::shared_ptr(new StdOutLogger()); - return _defaultLogger; + if (!_defaultLogger) + _defaultLogger = std::shared_ptr(new StdOutLogger()); + return _defaultLogger; } Logger Logger::getDefault() { - return LoggerImpl::getDefault(); + return LoggerImpl::getDefault(); } - + void log(LogSeverity severity, const Event& event) { - LoggerImpl::getDefault()->log(severity, event); + LoggerImpl::getDefault()->log(severity, event); } void log(LogSeverity severity, const Data& data) { - LoggerImpl::getDefault()->log(severity, data); + LoggerImpl::getDefault()->log(severity, data); } void Logger::log(LogSeverity severity, const Event& event) { - _impl->log(severity, event); + _impl->log(severity, event); } void Logger::log(LogSeverity severity, const Data& data) { @@ -54,15 +54,15 @@ void Logger::log(LogSeverity severity, const Data& data) { } void Logger::log(LogSeverity severity, const std::string& message) { - _impl->log(severity, message); + _impl->log(severity, message); } StreamLogger Logger::log(LogSeverity severity) { - return StreamLogger(severity, _impl); + return StreamLogger(severity, _impl); } StreamLogger::~StreamLogger() { - _logger->log(_severity, ss.str()); + _logger->log(_severity, ss.str()); } std::shared_ptr Logger::getImpl() const { @@ -70,30 +70,30 @@ std::shared_ptr Logger::getImpl() const { } std::ostream& StreamLogger::operator<<(const std::string& message) { - ss << message; //_logger->log(_severity, event); - return ss; + ss << message; //_logger->log(_severity, event); + return ss; } std::string Logger::severityToString(LogSeverity severity) { - switch (severity) { - case USCXML_SCXML: - return "Interpreter"; - case USCXML_TRACE: - return "Trace"; - case USCXML_DEBUG: - return "Debug"; - case USCXML_INFO: - return "Info"; - case USCXML_WARN: - return "Warning"; - case USCXML_ERROR: - return "Error"; - case USCXML_FATAL: - return "Fatal"; - default: - return "Unknown"; - - } + switch (severity) { + case USCXML_SCXML: + return "Interpreter"; + case USCXML_TRACE: + return "Trace"; + case USCXML_DEBUG: + return "Debug"; + case USCXML_INFO: + return "Info"; + case USCXML_WARN: + return "Warning"; + case USCXML_ERROR: + return "Error"; + case USCXML_FATAL: + return "Fatal"; + default: + return "Unknown"; + + } } } diff --git a/src/uscxml/interpreter/Logging.h b/src/uscxml/interpreter/Logging.h index 85d28ca..dd59e95 100644 --- a/src/uscxml/interpreter/Logging.h +++ b/src/uscxml/interpreter/Logging.h @@ -34,8 +34,8 @@ namespace uscxml { enum LogSeverity { - USCXML_SCXML, - USCXML_TRACE, + USCXML_SCXML, + USCXML_TRACE, USCXML_DEBUG, USCXML_INFO, USCXML_WARN, @@ -50,37 +50,37 @@ void log(LogSeverity severity, const Data& data); class StreamLogger { public: - std::ostream& operator<<(const std::string& message); - ~StreamLogger(); + std::ostream& operator<<(const std::string& message); + ~StreamLogger(); protected: - StreamLogger(LogSeverity severity, std::shared_ptr logger) : _severity(severity), _logger(logger) {} - StreamLogger(const StreamLogger& other) : _severity(other._severity), _logger(other._logger) {} - - LogSeverity _severity; - std::shared_ptr _logger; - std::stringstream ss; - - friend class Logger; + StreamLogger(LogSeverity severity, std::shared_ptr logger) : _severity(severity), _logger(logger) {} + StreamLogger(const StreamLogger& other) : _severity(other._severity), _logger(other._logger) {} + + LogSeverity _severity; + std::shared_ptr _logger; + std::stringstream ss; + + friend class Logger; }; class USCXML_API Logger { public: - PIMPL_OPERATORS(Logger); - + PIMPL_OPERATORS(Logger); + virtual void log(LogSeverity severity, const Event& event); - virtual void log(LogSeverity severity, const Data& data); - virtual void log(LogSeverity severity, const std::string& message); - - virtual StreamLogger log(LogSeverity severity); - static std::string severityToString(LogSeverity severity); - - static Logger getDefault(); - + virtual void log(LogSeverity severity, const Data& data); + virtual void log(LogSeverity severity, const std::string& message); + + virtual StreamLogger log(LogSeverity severity); + static std::string severityToString(LogSeverity severity); + + static Logger getDefault(); + std::shared_ptr getImpl() const; protected: std::shared_ptr _impl; - + }; } diff --git a/src/uscxml/interpreter/LoggingImpl.h b/src/uscxml/interpreter/LoggingImpl.h index c6003ca..ee17082 100644 --- a/src/uscxml/interpreter/LoggingImpl.h +++ b/src/uscxml/interpreter/LoggingImpl.h @@ -40,13 +40,13 @@ public: virtual std::shared_ptr create() = 0; virtual void log(LogSeverity severity, const Event& event) = 0; - virtual void log(LogSeverity severity, const Data& data) = 0; - virtual void log(LogSeverity severity, const std::string& message) = 0; + virtual void log(LogSeverity severity, const Data& data) = 0; + virtual void log(LogSeverity severity, const std::string& message) = 0; + + static std::shared_ptr getDefault(); - static std::shared_ptr getDefault(); - private: - static std::shared_ptr _defaultLogger; + static std::shared_ptr _defaultLogger; }; } diff --git a/src/uscxml/interpreter/MicroStep.cpp b/src/uscxml/interpreter/MicroStep.cpp index 35e5d94..896c92a 100644 --- a/src/uscxml/interpreter/MicroStep.cpp +++ b/src/uscxml/interpreter/MicroStep.cpp @@ -45,6 +45,6 @@ void MicroStep::markAsCancelled() { } std::shared_ptr MicroStep::getImpl() const { - return _impl; + return _impl; } } diff --git a/src/uscxml/interpreter/MicroStep.h b/src/uscxml/interpreter/MicroStep.h index 9238fc8..56a7ee8 100644 --- a/src/uscxml/interpreter/MicroStep.h +++ b/src/uscxml/interpreter/MicroStep.h @@ -55,7 +55,7 @@ public: virtual void init(XERCESC_NS::DOMElement* scxml); virtual void markAsCancelled(); - std::shared_ptr getImpl() const; + std::shared_ptr getImpl() const; protected: std::shared_ptr _impl; }; diff --git a/src/uscxml/interpreter/MicroStepImpl.h b/src/uscxml/interpreter/MicroStepImpl.h index 110dbd2..cdb98f2 100644 --- a/src/uscxml/interpreter/MicroStepImpl.h +++ b/src/uscxml/interpreter/MicroStepImpl.h @@ -73,8 +73,8 @@ public: }; MicroStepImpl(MicroStepCallbacks* callbacks) : _callbacks(callbacks) {} - virtual std::shared_ptr create(MicroStepCallbacks* callbacks) = 0; - + virtual std::shared_ptr create(MicroStepCallbacks* callbacks) = 0; + virtual InterpreterState step(size_t blockMs) = 0; virtual void reset() = 0; ///< Reset state machine virtual bool isInState(const std::string& stateId) = 0; diff --git a/src/uscxml/interpreter/StdOutLogger.cpp b/src/uscxml/interpreter/StdOutLogger.cpp index 1794c1f..2cbe4c7 100644 --- a/src/uscxml/interpreter/StdOutLogger.cpp +++ b/src/uscxml/interpreter/StdOutLogger.cpp @@ -27,15 +27,15 @@ std::shared_ptr StdOutLogger::create() { } void StdOutLogger::log(LogSeverity severity, const std::string& message) { - std::cout << Logger::severityToString(severity) << ": " << message << std::endl; + std::cout << Logger::severityToString(severity) << ": " << message << std::endl; } void StdOutLogger::log(LogSeverity severity, const Event& event) { - std::cout << Logger::severityToString(severity) << ": " << event << std::endl; + std::cout << Logger::severityToString(severity) << ": " << event << std::endl; } void StdOutLogger::log(LogSeverity severity, const Data& data) { - std::cout << Logger::severityToString(severity) << ": " << data << std::endl; + std::cout << Logger::severityToString(severity) << ": " << data << std::endl; } } diff --git a/src/uscxml/messages/Data.h b/src/uscxml/messages/Data.h index c863e41..cee5afd 100644 --- a/src/uscxml/messages/Data.h +++ b/src/uscxml/messages/Data.h @@ -64,10 +64,10 @@ public: // we will have to drop this constructor as it interferes with operator Data() and requires C++11 template - Data(T value, typename std::enable_if::value>::type* = nullptr) + explicit Data(T value, typename std::enable_if::value>::type* = nullptr) : node(NULL), atom(toStr(value)), type(VERBATIM) {} template - Data(T value, Type type, typename std::enable_if::value>::type* = nullptr) + explicit Data(T value, Type type, typename std::enable_if::value>::type* = nullptr) : node(NULL), atom(toStr(value)), type(type) {} ~Data() {} diff --git a/src/uscxml/messages/Event.h b/src/uscxml/messages/Event.h index 2edbd3e..59b2690 100644 --- a/src/uscxml/messages/Event.h +++ b/src/uscxml/messages/Event.h @@ -109,12 +109,12 @@ public: return name.size() > 0; } - operator std::string() { - std::stringstream ss; - ss << *this; - return ss.str(); - } - + operator std::string() { + std::stringstream ss; + ss << *this; + return ss.str(); + } + typedef std::multimap params_t; typedef std::map namelist_t; @@ -198,7 +198,7 @@ class USCXML_API ErrorEvent : public Event { public: ErrorEvent() : Event() {} ErrorEvent(const std::string& msg) : Event("error.platform") { - data.compound["msg"] = Data(msg, Data::VERBATIM); + data.compound["msg"] = Data(msg, Data::VERBATIM); } }; diff --git a/src/uscxml/plugins/DataModelImpl.h b/src/uscxml/plugins/DataModelImpl.h index 444a9d4..9ee1ed1 100644 --- a/src/uscxml/plugins/DataModelImpl.h +++ b/src/uscxml/plugins/DataModelImpl.h @@ -25,8 +25,8 @@ #include "uscxml/plugins/IOProcessor.h" namespace XERCESC_NS { - class DOMDocument; - class DOMNode; +class DOMDocument; +class DOMNode; } #include diff --git a/src/uscxml/plugins/ExecutableContentImpl.h b/src/uscxml/plugins/ExecutableContentImpl.h index 5424717..3f987bb 100644 --- a/src/uscxml/plugins/ExecutableContentImpl.h +++ b/src/uscxml/plugins/ExecutableContentImpl.h @@ -27,8 +27,8 @@ #include namespace XERCESC_NS { - class DOMDocument; - class DOMNode; +class DOMDocument; +class DOMNode; } namespace uscxml { diff --git a/src/uscxml/plugins/Invoker.h b/src/uscxml/plugins/Invoker.h index 54458f0..2191e7b 100644 --- a/src/uscxml/plugins/Invoker.h +++ b/src/uscxml/plugins/Invoker.h @@ -26,9 +26,9 @@ #include "uscxml/messages/Event.h" namespace XERCESC_NS { - class DOMElement; - class DOMDocument; - class DOMNode; +class DOMElement; +class DOMDocument; +class DOMNode; } namespace uscxml { diff --git a/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp b/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp index 59c2427..55c4501 100644 --- a/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp +++ b/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp @@ -326,7 +326,7 @@ void LuaDataModel::setEvent(const Event& event) { Data LuaDataModel::evalAsData(const std::string& content) { Data data; - ErrorEvent originalError; + ErrorEvent originalError; std::string trimmedExpr = boost::trim_copy(content); @@ -338,31 +338,31 @@ Data LuaDataModel::evalAsData(const std::string& content) { lua_pop(_luaState, retVals); return data; } catch (ErrorEvent e) { - originalError = e; + originalError = e; } - int retVals = 0; + int retVals = 0; try { // evaluate again without the return() retVals = luaEval(_luaState, trimmedExpr); - } catch (ErrorEvent e) { - throw originalError; // we will assume syntax error and throw - } + } catch (ErrorEvent e) { + throw originalError; // we will assume syntax error and throw + } - if (retVals == 0) - throw originalError; // we will assume syntax error and throw + if (retVals == 0) + throw originalError; // we will assume syntax error and throw - - try { + + try { if (retVals == 1) { data = getLuaAsData(_luaState, luabridge::LuaRef::fromStack(_luaState, -1)); } lua_pop(_luaState, retVals); return data; - - } catch (ErrorEvent e) { - throw e; // we will assume syntax error and throw - } + + } catch (ErrorEvent e) { + throw e; // we will assume syntax error and throw + } return data; diff --git a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp index 26fc024..868fee7 100644 --- a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp +++ b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp @@ -100,7 +100,7 @@ void USCXMLInvoker::run(void* instance) { InterpreterState state = USCXML_UNDEF; while(state != USCXML_FINISHED) { - state = INSTANCE->_invokedInterpreter.step(true); + state = INSTANCE->_invokedInterpreter.step(); // if (!INSTANCE->_isStarted) { // // we have been cancelled @@ -158,31 +158,30 @@ void USCXMLInvoker::invoke(const std::string& source, const Event& invokeEvent) _invokedInterpreter.getImpl()->_invokeId = invokeEvent.invokeid; _invokedInterpreter.getImpl()->_invokeReq = invokeEvent; - // create new instances from the parent's ActionLanguage + // create new instances from the parent's ActionLanguage #if 1 - InterpreterImpl* invoked = _invokedInterpreter.getImpl().get(); - invoked->_execContent = _interpreter->_execContent.getImpl()->create(invoked); - invoked->_delayQueue = _interpreter->_delayQueue.getImplDelayed()->create(invoked); - invoked->_internalQueue = _interpreter->_internalQueue.getImplBase()->create(); - invoked->_externalQueue = _interpreter->_externalQueue.getImplBase()->create(); - invoked->_microStepper = _interpreter->_microStepper.getImpl()->create(invoked); - - // TODO: setup invokers dom, check datamodel attribute and create new instance from parent if matching? + InterpreterImpl* invoked = _invokedInterpreter.getImpl().get(); + invoked->_execContent = _interpreter->_execContent.getImpl()->create(invoked); + invoked->_delayQueue = _interpreter->_delayQueue.getImplDelayed()->create(invoked); + invoked->_internalQueue = _interpreter->_internalQueue.getImplBase()->create(); + invoked->_externalQueue = _interpreter->_externalQueue.getImplBase()->create(); + invoked->_microStepper = _interpreter->_microStepper.getImpl()->create(invoked); + + // TODO: setup invokers dom, check datamodel attribute and create new instance from parent if matching? #endif // copy monitors -// std::set::const_iterator monIter = _interpreter->_monitors.begin(); -// while(monIter != _interpreter->_monitors.end()) { -// if ((*monIter)->copyToInvokers()) { -// _invokedInterpreter.getImpl()->_monitors.insert(*monIter); -// } -// monIter++; -// } - + std::set::const_iterator monIter = _interpreter->_monitors.begin(); + while(monIter != _interpreter->_monitors.end()) { + if ((*monIter)->copyToInvokers()) { + _invokedInterpreter.getImpl()->_monitors.insert(*monIter); + } + monIter++; + } - /** - * test240 assumes that invoke request params will carry over to the datamodel - * This is solved by passing the invoke request above - */ + /** + * test240 assumes that invoke request params will carry over to the datamodel + * This is solved by passing the invoke request above + */ // _invokedInterpreter.getImpl()->setInvokeRequest(req); _isActive = true; diff --git a/src/uscxml/transform/ChartToJava.cpp b/src/uscxml/transform/ChartToJava.cpp index 8d4d61e..9612329 100644 --- a/src/uscxml/transform/ChartToJava.cpp +++ b/src/uscxml/transform/ChartToJava.cpp @@ -42,58 +42,58 @@ ChartToJava::~ChartToJava() { } void ChartToJava::writeTo(std::ostream& stream) { - std::string className; - std::string packageName = "org.uscxml.gen"; - - if (_extensions.find("packageName") != _extensions.end()) { - packageName = _extensions.equal_range("packageName").first->second; - } - - if (_extensions.find("outputFile") != _extensions.end()) { - URL outputFileURL(_extensions.equal_range("outputFile").first->second); - className = outputFileURL.pathComponents().back(); - } else if (_baseURL.pathComponents().size() > 0) { - className = _baseURL.pathComponents().back(); - } else { - className = "StateChartBase"; - } - - std::string javaVersion = "5"; - if (_extensions.find("javaVersion") != _extensions.end()) { - javaVersion = _extensions.equal_range("javaVersion").first->second; - } - std::string baseClass = "StateChartJava" + javaVersion + "Impl"; - - - size_t dotPos = std::string::npos; - if ((dotPos = className.find(".")) != std::string::npos) { - className = className.substr(0, dotPos); - } - - stream << "package " << packageName << ";" << std::endl; - stream << std::endl; - - stream << "/**" << std::endl; - stream << " Generated from source:" << std::endl; - stream << " " << (std::string)_baseURL << std::endl; - stream << "*/" << std::endl; - stream << std::endl; - - - stream << std::endl; - stream << "import java.util.ArrayList;" << std::endl; - stream << "import java.util.HashMap;" << std::endl; - stream << "import org.uscxml.*;" << std::endl; - stream << std::endl; - stream << "public abstract class " << className << " extends " << baseClass << " {" << std::endl; - stream << std::endl; - stream << " public " << className << "() {" << std::endl; - stream << " transitions = new ArrayList();" << std::endl; - stream << " states = new ArrayList();" << std::endl; - stream << " stateNamesToIndex = new HashMap();" << std::endl; - stream << " /* TODO: initialize all members */" << std::endl; - stream << " }" << std::endl; - stream << "}" << std::endl; + std::string className; + std::string packageName = "org.uscxml.gen"; + + if (_extensions.find("packageName") != _extensions.end()) { + packageName = _extensions.equal_range("packageName").first->second; + } + + if (_extensions.find("outputFile") != _extensions.end()) { + URL outputFileURL(_extensions.equal_range("outputFile").first->second); + className = outputFileURL.pathComponents().back(); + } else if (_baseURL.pathComponents().size() > 0) { + className = _baseURL.pathComponents().back(); + } else { + className = "StateChartBase"; + } + + std::string javaVersion = "5"; + if (_extensions.find("javaVersion") != _extensions.end()) { + javaVersion = _extensions.equal_range("javaVersion").first->second; + } + std::string baseClass = "StateChartJava" + javaVersion + "Impl"; + + + size_t dotPos = std::string::npos; + if ((dotPos = className.find(".")) != std::string::npos) { + className = className.substr(0, dotPos); + } + + stream << "package " << packageName << ";" << std::endl; + stream << std::endl; + + stream << "/**" << std::endl; + stream << " Generated from source:" << std::endl; + stream << " " << (std::string)_baseURL << std::endl; + stream << "*/" << std::endl; + stream << std::endl; + + + stream << std::endl; + stream << "import java.util.ArrayList;" << std::endl; + stream << "import java.util.HashMap;" << std::endl; + stream << "import org.uscxml.*;" << std::endl; + stream << std::endl; + stream << "public abstract class " << className << " extends " << baseClass << " {" << std::endl; + stream << std::endl; + stream << " public " << className << "() {" << std::endl; + stream << " transitions = new ArrayList();" << std::endl; + stream << " states = new ArrayList();" << std::endl; + stream << " stateNamesToIndex = new HashMap();" << std::endl; + stream << " /* TODO: initialize all members */" << std::endl; + stream << " }" << std::endl; + stream << "}" << std::endl; } diff --git a/src/uscxml/transform/ChartToVHDL.cpp b/src/uscxml/transform/ChartToVHDL.cpp index 4922f22..0a344c8 100644 --- a/src/uscxml/transform/ChartToVHDL.cpp +++ b/src/uscxml/transform/ChartToVHDL.cpp @@ -34,1786 +34,1786 @@ namespace uscxml { - using namespace XERCESC_NS; +using namespace XERCESC_NS; - Transformer ChartToVHDL::transform(const Interpreter &other) { - ChartToVHDL *c2c = new ChartToVHDL(other); +Transformer ChartToVHDL::transform(const Interpreter &other) { + ChartToVHDL *c2c = new ChartToVHDL(other); - return std::shared_ptr(c2c); - } + return std::shared_ptr(c2c); +} - ChartToVHDL::ChartToVHDL(const Interpreter &other) : ChartToC(other), _eventTrie(".") { - } +ChartToVHDL::ChartToVHDL(const Interpreter &other) : ChartToC(other), _eventTrie(".") { +} - ChartToVHDL::~ChartToVHDL() { - } +ChartToVHDL::~ChartToVHDL() { +} - void ChartToVHDL::findEvents() { - // elements with an event attribute - std::list withEvents = DOMUtils::inDocumentOrder({ - XML_PREFIX(_scxml).str() + "raise", - XML_PREFIX(_scxml).str() + "send", - XML_PREFIX(_scxml).str() + "transition", - }, _scxml); +void ChartToVHDL::findEvents() { + // elements with an event attribute + std::list withEvents = DOMUtils::inDocumentOrder({ + XML_PREFIX(_scxml).str() + "raise", + XML_PREFIX(_scxml).str() + "send", + XML_PREFIX(_scxml).str() + "transition", + }, _scxml); - for (auto withEvent : withEvents) { + for (auto withEvent : withEvents) { // if (HAS_ATTR_CAST(withEvent, "event")) { // if (ATTR_CAST(withEvent, "event") != "*") // _eventTrie.addWord(ATTR_CAST(withEvent, "event")); // } - // Tokenized version below - - if (HAS_ATTR_CAST(withEvent, "event")) { - std::string eventNames = ATTR_CAST(withEvent, "event"); - std::list events = tokenize(eventNames); - for (std::list::iterator eventIter = events.begin(); - eventIter != events.end(); eventIter++) { - std::string eventName = *eventIter; - if (boost::ends_with(eventName, "*")) - eventName = eventName.substr(0, eventName.size() - 1); - if (boost::ends_with(eventName, ".")) - eventName = eventName.substr(0, eventName.size() - 1); - if (eventName.size() > 0) - _eventTrie.addWord(eventName); - } + // Tokenized version below - //TODO implement "done" event - // --> enter a final from a compound state not (also prevent setting completed_o) - // --> all final children from a parallel are entered - //TODO implement error events --> set by output logic to a signal line + if (HAS_ATTR_CAST(withEvent, "event")) { + std::string eventNames = ATTR_CAST(withEvent, "event"); + std::list events = tokenize(eventNames); + for (std::list::iterator eventIter = events.begin(); + eventIter != events.end(); eventIter++) { + std::string eventName = *eventIter; + if (boost::ends_with(eventName, "*")) + eventName = eventName.substr(0, eventName.size() - 1); + if (boost::ends_with(eventName, ".")) + eventName = eventName.substr(0, eventName.size() - 1); + if (eventName.size() > 0) + _eventTrie.addWord(eventName); } + //TODO implement "done" event + // --> enter a final from a compound state not (also prevent setting completed_o) + // --> all final children from a parallel are entered + //TODO implement error events --> set by output logic to a signal line } - // preprocess event names since they are often used - _eventNames = _eventTrie.getWordsWithPrefix(""); - // Calculate needed bit size for the event fifo - // --> |log2(n)| +1 with n is number of events - // we do not add +1 because the std_logic_vector startes with 0 - _eventBitSize = ceil(std::abs(log2(_eventNames.size()))); - - _execContent = DOMUtils::inDocumentOrder({ - XML_PREFIX(_scxml).str() + "raise", - XML_PREFIX(_scxml).str() + "send" - }, _scxml); - } - bool ChartToVHDL::isSupportedExecContent(DOMElement *execContentElement) { - return (TAGNAME(execContentElement) == XML_PREFIX(_scxml).str() + "raise" || - TAGNAME(execContentElement) == XML_PREFIX(_scxml).str() + "send"); - } - - void ChartToVHDL::writeTo(std::ostream &stream) { - findEvents(); + // preprocess event names since they are often used + _eventNames = _eventTrie.getWordsWithPrefix(""); + // Calculate needed bit size for the event fifo + // --> |log2(n)| +1 with n is number of events + // we do not add +1 because the std_logic_vector startes with 0 + _eventBitSize = ceil(std::abs(log2(_eventNames.size()))); + _execContent = DOMUtils::inDocumentOrder({ + XML_PREFIX(_scxml).str() + "raise", + XML_PREFIX(_scxml).str() + "send" + }, _scxml); - stream << "-- generated from " << std::string(_baseURL) << std::endl; - stream << "-- run as " << std::endl; - stream << "-- ghdl --clean && ghdl -a foo.vhdl && ghdl -e tb && ./tb --stop-time=10ms --vcd=tb.vcd" << - std::endl; - stream << "-- gtkwave tb.vcd" << std::endl; - stream << std::endl; - - writeFiFo(stream); - writeEventController(stream); - writeMicroStepper(stream); - writeConditionSolver(stream); - writeTestbench(stream); - //writeTopLevel(stream); - } +} +bool ChartToVHDL::isSupportedExecContent(DOMElement *execContentElement) { + return (TAGNAME(execContentElement) == XML_PREFIX(_scxml).str() + "raise" || + TAGNAME(execContentElement) == XML_PREFIX(_scxml).str() + "send"); +} - 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::writeTo(std::ostream &stream) { + findEvents(); - void ChartToVHDL::writeTestbench(std::ostream &stream) { - stream << "-- TESTBENCH" << std::endl; - writeIncludes(stream); - stream << "use std.env.all;" << std::endl; - stream << std::endl; + stream << "-- generated from " << std::string(_baseURL) << std::endl; + stream << "-- run as " << std::endl; + stream << "-- ghdl --clean && ghdl -a foo.vhdl && ghdl -e tb && ./tb --stop-time=10ms --vcd=tb.vcd" << + std::endl; + stream << "-- gtkwave tb.vcd" << std::endl; + stream << std::endl; - stream << "-- empty entity" << std::endl; - stream << "entity tb is" << std::endl; - stream << "end entity tb;" << std::endl; - stream << std::endl; + writeFiFo(stream); + writeEventController(stream); + writeMicroStepper(stream); + writeConditionSolver(stream); + writeTestbench(stream); + //writeTopLevel(stream); +} - stream << "architecture behavioral of tb is" << std::endl; - stream << std::endl; - // modules - //COMPONENT MS - stream << " -- Module declaration" << std::endl; - stream << " component micro_stepper is" << std::endl; - stream << " port (" << std::endl; - stream << " --inputs" << std::endl; - stream << " clk :in std_logic;" << std::endl; - stream << " rst_i :in std_logic;" << std::endl; - stream << " en :in std_logic;" << std::endl; - stream << " next_event_i :in std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << " next_event_we_i :in std_logic;" << std::endl; +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; +} - for (auto transition : _transitions) { - if (HAS_ATTR(transition, "cond")) { // create enable line if transition has conditions - stream << " transition_condition_fulfilled_" << ATTR(transition, "postFixOrder") << - "_i : std_logic;" - << 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 + //COMPONENT MS + stream << " -- Module declaration" << std::endl; + stream << " component micro_stepper is" << std::endl; + stream << " port (" << std::endl; + stream << " --inputs" << std::endl; + stream << " clk :in std_logic;" << std::endl; + stream << " rst_i :in std_logic;" << std::endl; + stream << " en :in std_logic;" << std::endl; + stream << " next_event_i :in std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << " next_event_we_i :in std_logic;" << std::endl; + + for (auto transition : _transitions) { + if (HAS_ATTR(transition, "cond")) { // create enable line if transition has conditions + stream << " transition_condition_fulfilled_" << ATTR(transition, "postFixOrder") << + "_i : std_logic;" + << std::endl; } + } - stream << " --outputs" << std::endl; - stream << " error_o :out std_logic;" << std::endl; - - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; + stream << " --outputs" << std::endl; + stream << " error_o :out std_logic;" << std::endl; - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " entry_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; - } + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " exit_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; } - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " transition_set_" << ATTR(transition, "postFixOrder") << "_o :out std_logic;" - << std::endl; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; } + } - stream << " completed_o :out std_logic" << std::endl; - stream << " );" << std::endl; - stream << " end component;" << std::endl; - stream << std::endl; + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") << "_o :out std_logic;" + << std::endl; + } + } - // COMPONENT EC - stream << " component event_controller is" << std::endl; - stream << " port(" << std::endl; - stream << " --inputs" << std::endl; - stream << " clk :in std_logic;" << std::endl; - stream << " rst_i :in std_logic;" << std::endl; + stream << " completed_o :out std_logic" << std::endl; + stream << " );" << std::endl; + stream << " end component;" << std::endl; + stream << std::endl; - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") - << "_i :in std_logic;" << std::endl; + // COMPONENT EC + stream << " component event_controller is" << std::endl; + stream << " port(" << std::endl; + stream << " --inputs" << std::endl; + stream << " clk :in std_logic;" << std::endl; + stream << " rst_i :in std_logic;" << std::endl; - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " entry_set_" << ATTR(state, "documentOrder") - << "_i :in std_logic;" << std::endl; - } + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") + << "_i :in std_logic;" << std::endl; - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " exit_set_" << ATTR(state, "documentOrder") - << "_i :in std_logic;" << std::endl; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") + << "_i :in std_logic;" << std::endl; } - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " transition_set_" << ATTR(transition, "postFixOrder") - << "_i :in std_logic;" << std::endl; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") + << "_i :in std_logic;" << std::endl; } - stream << " --outputs" << std::endl; - stream << " micro_stepper_en_o :out std_logic;" << std::endl; - stream << " event_o :out std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << " event_we_o :out std_logic" << std::endl; - // stream << " done_o :out std_logic" << std::endl; - stream << ");" << std::endl; - stream << "end component; " << std::endl; - stream << std::endl; - - //COMPONENT CS - stream << "component condition_solver is" << std::endl; - stream << "port(" << std::endl; - stream << " --inputs" << std::endl; - stream << " clk :in std_logic;" << std::endl; - stream << " rst_i :in std_logic;" << std::endl; + } - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") - << "_i :in std_logic;" << std::endl; + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") + << "_i :in std_logic;" << std::endl; } + } + stream << " --outputs" << std::endl; + stream << " micro_stepper_en_o :out std_logic;" << std::endl; + stream << " event_o :out std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << " event_we_o :out std_logic" << std::endl; + // stream << " done_o :out std_logic" << std::endl; + stream << ");" << std::endl; + stream << "end component; " << std::endl; + stream << std::endl; + + //COMPONENT CS + stream << "component condition_solver 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; + } - stream << " --outputs" << std::endl; + stream << " --outputs" << std::endl; - for (auto transition : _transitions) { - if (HAS_ATTR(transition, "cond")) { - stream << " transition_condition_fulfilled_" << ATTR(transition, "postFixOrder") - << "_o :out std_logic;" << std::endl; - } + for (auto transition : _transitions) { + if (HAS_ATTR(transition, "cond")) { + stream << " transition_condition_fulfilled_" << ATTR(transition, "postFixOrder") + << "_o :out std_logic;" << std::endl; } + } - stream << " micro_stepper_en_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 ec_enable_out : std_logic;" << std::endl; - stream << " signal cs_enable_out : std_logic;" << std::endl; - stream << " signal next_event_we_i : std_logic;" << std::endl; - stream << " signal next_event_i : std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << std::endl; + stream << " micro_stepper_en_o :out std_logic" << std::endl; + stream << ");" << std::endl; + stream << "end component; " << std::endl; - stream << " -- output" << std::endl; - stream << " signal error_o, completed_o : std_logic;" << std::endl; - stream << 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 ec_enable_out : std_logic;" << std::endl; + stream << " signal cs_enable_out : std_logic;" << std::endl; + stream << " signal next_event_we_i : std_logic;" << std::endl; + stream << " signal next_event_i : std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << std::endl; - stream << " -- wiring" << std::endl; - for (auto state : _states) { - stream << " signal state_active_" << ATTR(state, "documentOrder") - << "_sig : std_logic;" << std::endl; + stream << " -- output" << std::endl; + stream << " signal error_o, completed_o : std_logic;" << std::endl; + stream << std::endl; - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " signal entry_set_" << ATTR(state, "documentOrder") - << "_sig : std_logic;" << std::endl; - } + stream << " -- 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() + "onexit", state).size() > 0) { - stream << " signal exit_set_" << 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; } - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " signal transition_set_" << ATTR(transition, "postFixOrder") - << "_sig : std_logic;" << std::endl; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " signal exit_set_" << ATTR(state, "documentOrder") + << "_sig : std_logic;" << std::endl; } + } - for (auto transition : _transitions) { - if (HAS_ATTR(transition, "cond")) { // create enable line if transition has conditions - stream << " signal transition_condition_fulfilled_" << ATTR(transition, "postFixOrder") << - "_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; } - stream << 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 << " dut_enable <= ec_enable_out and cs_enable_out; -- enable signal for microstepper" << - 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 (HAS_ATTR(transition, "cond")) { // create enable line if transition has conditions + stream << " signal transition_condition_fulfilled_" << ATTR(transition, "postFixOrder") << + "_sig : std_logic;" + << std::endl; } - - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " transition_set_" << ATTR(transition, "postFixOrder") - << "_o => transition_set_" << ATTR(transition, "postFixOrder") - << "_sig," << std::endl; - } + } + stream << 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 << " dut_enable <= ec_enable_out and cs_enable_out; -- enable signal for microstepper" << + 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 (HAS_ATTR(transition, "cond")) { // create enable line if transition has conditions - stream << " transition_condition_fulfilled_" << ATTR(transition, "postFixOrder") << - "_i => transition_condition_fulfilled_" << ATTR(transition, "postFixOrder") << - "_sig," << std::endl; - } + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") + << "_o => transition_set_" << ATTR(transition, "postFixOrder") + << "_sig," << std::endl; } + } - stream << " completed_o => completed_o" << std::endl; - stream << " );" << std::endl; - stream << std::endl; + for (auto transition : _transitions) { + if (HAS_ATTR(transition, "cond")) { // create enable line if transition has conditions + stream << " transition_condition_fulfilled_" << ATTR(transition, "postFixOrder") << + "_i => transition_condition_fulfilled_" << ATTR(transition, "postFixOrder") << + "_sig," << 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 << " completed_o => completed_o" << std::endl; + stream << " );" << std::endl; + stream << std::endl; - stream << " event_o => next_event_i," << std::endl; - stream << " event_we_o => next_event_we_i," << std::endl; + stream << " ec : event_controller" << std::endl; + stream << " port map (" << std::endl; + stream << " clk => clk," << std::endl; + stream << " rst_i => reset," << std::endl; + stream << std::endl; - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") - << "_i => state_active_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; + stream << " event_o => next_event_i," << std::endl; + stream << " event_we_o => next_event_we_i," << std::endl; - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " entry_set_" << ATTR(state, "documentOrder") - << "_i => entry_set_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; - } + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") + << "_i => state_active_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " exit_set_" << ATTR(state, "documentOrder") - << "_i => exit_set_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") + << "_i => entry_set_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; } - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " transition_set_" << ATTR(transition, "postFixOrder") - << "_i => transition_set_" << ATTR(transition, "postFixOrder") - << "_sig," << std::endl; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") + << "_i => exit_set_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; } + } - stream << " micro_stepper_en_o => ec_enable_out" << std::endl; - // stream << " done_o => open" << std::endl; - stream << " );" << std::endl; - stream << std::endl; - - stream << " cs : condition_solver" << std::endl; - stream << " port map(" << std::endl; - stream << " --inputs" << std::endl; - stream << " clk => clk," << std::endl; - stream << " rst_i => reset," << std::endl; - - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") - << "_i => state_active_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") + << "_i => transition_set_" << ATTR(transition, "postFixOrder") + << "_sig," << std::endl; } + } - stream << " --outputs" << std::endl; + stream << " micro_stepper_en_o => ec_enable_out" << std::endl; + // stream << " done_o => open" << std::endl; + stream << " );" << std::endl; + stream << std::endl; + + stream << " cs : condition_solver" << std::endl; + stream << " port map(" << std::endl; + stream << " --inputs" << std::endl; + stream << " clk => clk," << std::endl; + stream << " rst_i => reset," << std::endl; + + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") + << "_i => state_active_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; + } - for (auto transition : _transitions) { - if (HAS_ATTR(transition, "cond")) { - stream << " transition_condition_fulfilled_" << ATTR(transition, "postFixOrder") - << "_o => transition_condition_fulfilled_" << ATTR(transition, "postFixOrder") << - "_sig," << std::endl; - } + stream << " --outputs" << std::endl; + + for (auto transition : _transitions) { + if (HAS_ATTR(transition, "cond")) { + stream << " transition_condition_fulfilled_" << ATTR(transition, "postFixOrder") + << "_o => transition_condition_fulfilled_" << ATTR(transition, "postFixOrder") << + "_sig," << std::endl; } + } - stream << " micro_stepper_en_o => cs_enable_out" << std::endl; - stream << " );" << std::endl; - stream << std::endl; + stream << " micro_stepper_en_o => cs_enable_out" << std::endl; + stream << " );" << std::endl; + stream << std::endl; - // find pass state - std::list topLevelFinal = - DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "final", _scxml); + // find pass state + std::list topLevelFinal = + DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "final", _scxml); - std::string passStateNo = ""; - for (auto final : topLevelFinal) { - if (ATTR(final, "id") == "pass") { - passStateNo = ATTR(final, "documentOrder"); - } + std::string passStateNo = ""; + for (auto final : topLevelFinal) { + if (ATTR(final, "id") == "pass") { + passStateNo = ATTR(final, "documentOrder"); } + } - // test observation and exit condition - stream << " -- Test observation" << std::endl; - stream << " process (clk)" << std::endl; - stream << " variable count_clk : integer := 0;" << std::endl; - stream << " begin" << std::endl; - stream << " if rising_edge(clk) then" << std::endl; - stream << " count_clk := count_clk + 1;" << std::endl; - stream << " if (completed_o = '1') then" << std::endl; - if (!passStateNo.empty()) { - stream << " assert (state_active_" << passStateNo; - stream << "_sig = '1') report \"Completed with errors\" severity error;" << std::endl; - } - stream << " -- stop simulation" << std::endl; - stream << " finish(0);" << std::endl; // use 0 for ctest + // test observation and exit condition + stream << " -- Test observation" << std::endl; + stream << " process (clk)" << std::endl; + stream << " variable count_clk : integer := 0;" << std::endl; + stream << " begin" << std::endl; + stream << " if rising_edge(clk) then" << std::endl; + stream << " count_clk := count_clk + 1;" << std::endl; + stream << " if (completed_o = '1') then" << std::endl; + if (!passStateNo.empty()) { + stream << " assert (state_active_" << passStateNo; + stream << "_sig = '1') report \"Completed with errors\" severity error;" << std::endl; + } + stream << " -- stop simulation" << std::endl; + stream << " finish(0);" << std::endl; // use 0 for ctest // -- For both STOP and FINISH the STATUS values are those used // -- in the Verilog $finish task // -- 0 prints nothing // -- 1 prints simulation time and location // -- 2 prints simulation time, location, and statistics about // -- the memory and CPU times used in simulation - //stream << " assert false report \"Simulation Finished\" severity failure;" << std::endl; - stream << " else" << std::endl; - stream << " -- state machine not completed" << std::endl; - stream << " -- check if it is time to stop waiting (100 clk per state+transition+excontent)" << std::endl; - int tolleratedClocks = (_transitions.size() + _states.size() + _execContent.size()) * 100; - stream << " assert (count_clk < " << tolleratedClocks; - stream << ") report \"Clock count exceed\" severity failure;" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << " end process;" << std::endl; + //stream << " assert false report \"Simulation Finished\" severity failure;" << std::endl; + stream << " else" << std::endl; + stream << " -- state machine not completed" << std::endl; + stream << " -- check if it is time to stop waiting (100 clk per state+transition+excontent)" << std::endl; + int tolleratedClocks = (_transitions.size() + _states.size() + _execContent.size()) * 100; + stream << " assert (count_clk < " << tolleratedClocks; + stream << ") report \"Clock count exceed\" severity failure;" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << " end process;" << std::endl; + + stream << "end architecture;" << std::endl; + stream << "-- END TESTBENCH" << std::endl; - stream << "end architecture;" << std::endl; - stream << "-- END TESTBENCH" << std::endl; +} +void ChartToVHDL::writeTopLevel(std::ostream &stream) { + stream << "-- TOP LEVEL entity for easy synthesis" << std::endl; + writeIncludes(stream); + stream << std::endl; + + stream << "-- empty entity" << std::endl; + stream << "entity top_level_design is" << std::endl; + stream << "port (" << std::endl; + stream << " --inputs" << std::endl; + stream << " clk :in std_logic;" << std::endl; + stream << " rst :in std_logic;" << std::endl; + stream << " --outputs" << std::endl; + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") + << "_o :out std_logic;" << std::endl; } + stream << " completed_o :out std_logic" << std::endl; + stream << ");" << std::endl; + stream << "end entity top_level_design;" << std::endl; + stream << std::endl; - void ChartToVHDL::writeTopLevel(std::ostream &stream) { - stream << "-- TOP LEVEL entity for easy synthesis" << std::endl; - writeIncludes(stream); - stream << std::endl; - - stream << "-- empty entity" << std::endl; - stream << "entity top_level_design is" << std::endl; - stream << "port (" << std::endl; - stream << " --inputs" << std::endl; - stream << " clk :in std_logic;" << std::endl; - stream << " rst :in std_logic;" << std::endl; - stream << " --outputs" << std::endl; - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") - << "_o :out std_logic;" << std::endl; - } - stream << " completed_o :out std_logic" << std::endl; - stream << ");" << std::endl; - stream << "end entity top_level_design;" << std::endl; - stream << std::endl; - - stream << "architecture behavioral of top_level_design is" << std::endl; - stream << std::endl; + stream << "architecture behavioral of top_level_design is" << std::endl; + stream << std::endl; - // modules - stream << " -- Module declaration" << std::endl; - stream << " component micro_stepper is" << std::endl; - stream << " port (" << std::endl; - stream << " --inputs" << std::endl; - stream << " clk :in std_logic;" << std::endl; - stream << " rst_i :in std_logic;" << std::endl; - stream << " en :in std_logic;" << std::endl; - stream << " next_event_i :in std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << " next_event_we_i :in std_logic;" << std::endl; - stream << " --outputs" << std::endl; - stream << " error_o :out std_logic;" << std::endl; + // modules + stream << " -- Module declaration" << std::endl; + stream << " component micro_stepper is" << std::endl; + stream << " port (" << std::endl; + stream << " --inputs" << std::endl; + stream << " clk :in std_logic;" << std::endl; + stream << " rst_i :in std_logic;" << std::endl; + stream << " en :in std_logic;" << std::endl; + stream << " next_event_i :in std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << " next_event_we_i :in std_logic;" << std::endl; + stream << " --outputs" << std::endl; + stream << " error_o :out std_logic;" << std::endl; - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; + 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() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; + } - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " exit_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; } + } - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " transition_set_" << ATTR(transition, "postFixOrder") << "_o :out std_logic;" - << std::endl; - } + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") << "_o :out std_logic;" + << std::endl; } + } - stream << " completed_o :out std_logic" << std::endl; - stream << " );" << std::endl; - stream << " end component;" << std::endl; - stream << std::endl; + stream << " completed_o :out std_logic" << std::endl; + stream << " );" << std::endl; + stream << " end component;" << std::endl; + stream << std::endl; - stream << " component event_controller is" << std::endl; - stream << " port(" << std::endl; - stream << " --inputs" << std::endl; - stream << " clk :in std_logic;" << std::endl; - stream << " rst_i :in std_logic;" << std::endl; + stream << " component event_controller is" << std::endl; + stream << " port(" << std::endl; + stream << " --inputs" << std::endl; + stream << " clk :in std_logic;" << std::endl; + stream << " rst_i :in std_logic;" << std::endl; - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") - << "_i :in std_logic;" << std::endl; + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") + << "_i :in std_logic;" << std::endl; - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " entry_set_" << ATTR(state, "documentOrder") - << "_i :in std_logic;" << std::endl; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") + << "_i :in std_logic;" << std::endl; + } - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " exit_set_" << ATTR(state, "documentOrder") - << "_i :in std_logic;" << std::endl; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") + << "_i :in std_logic;" << std::endl; } + } - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " transition_set_" << ATTR(transition, "postFixOrder") - << "_i :in std_logic;" << std::endl; - } + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") + << "_i :in std_logic;" << std::endl; } - stream << " --outputs" << std::endl; - stream << " micro_stepper_en_o :out std_logic;" << std::endl; - stream << " event_o :out std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << " event_we_o :out std_logic" << std::endl; - // stream << " done_o :out std_logic" << std::endl; - stream << ");" << std::endl; - stream << "end component; " << std::endl; - - // signals - stream << " -- input" << std::endl; - stream << " signal reset : std_logic;" << std::endl; - stream << " signal dut_enable : std_logic;" << std::endl; - stream << " signal next_event_we_i : std_logic;" << std::endl; - stream << " signal next_event_i : std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << std::endl; + } + stream << " --outputs" << std::endl; + stream << " micro_stepper_en_o :out std_logic;" << std::endl; + stream << " event_o :out std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << " event_we_o :out std_logic" << std::endl; + // stream << " done_o :out std_logic" << std::endl; + stream << ");" << std::endl; + stream << "end component; " << std::endl; + + // signals + stream << " -- input" << std::endl; + stream << " signal reset : std_logic;" << std::endl; + stream << " signal dut_enable : std_logic;" << std::endl; + stream << " signal next_event_we_i : std_logic;" << std::endl; + stream << " signal next_event_i : std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << std::endl; + + stream << " -- output" << std::endl; + stream << " signal error_o : std_logic;" << std::endl; + stream << std::endl; + + stream << " -- wiring" << std::endl; + for (auto state : _states) { + stream << " signal state_active_" << ATTR(state, "documentOrder") + << "_sig : std_logic;" << std::endl; + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " signal entry_set_" << ATTR(state, "documentOrder") + << "_sig : std_logic;" << std::endl; + } + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " signal exit_set_" << ATTR(state, "documentOrder") + << "_sig : std_logic;" << std::endl; + } + } - stream << " -- output" << std::endl; - stream << " signal error_o : std_logic;" << std::endl; - stream << std::endl; + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " signal transition_set_" << ATTR(transition, "postFixOrder") + << "_sig : std_logic;" << std::endl; + } + } - stream << " -- wiring" << std::endl; - for (auto state : _states) { - stream << " signal state_active_" << ATTR(state, "documentOrder") - << "_sig : std_logic;" << std::endl; + // wiring + stream << "begin" << std::endl; + stream << " reset <= rst;" << std::endl; + stream << std::endl; - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " signal entry_set_" << ATTR(state, "documentOrder") - << "_sig : std_logic;" << std::endl; - } + for (auto state : _states) { + stream << "state_active_" << ATTR(state, "documentOrder") + << "_o <= state_active_" << ATTR(state, "documentOrder") + << "_sig;" << std::endl; + } + stream << std::endl; - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " signal exit_set_" << ATTR(state, "documentOrder") - << "_sig : std_logic;" << 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; - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " signal transition_set_" << ATTR(transition, "postFixOrder") - << "_sig : std_logic;" << std::endl; - } + stream << " 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; } - // wiring - stream << "begin" << std::endl; - stream << " reset <= rst;" << std::endl; - stream << std::endl; + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") + << "_o => exit_set_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; + } + } - for (auto state : _states) { - stream << "state_active_" << ATTR(state, "documentOrder") - << "_o <= state_active_" << ATTR(state, "documentOrder") - << "_sig;" << std::endl; + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") + << "_o => transition_set_" << ATTR(transition, "postFixOrder") + << "_sig," << std::endl; } - stream << std::endl; + } - stream << " -- Module instantiation" << std::endl; - stream << " dut : micro_stepper" << std::endl; - stream << " port map (" << std::endl; - stream << " clk => clk," << std::endl; - stream << " rst_i => reset," << std::endl; - stream << " en => dut_enable," << std::endl; - stream << std::endl; + stream << " completed_o => completed_o" << std::endl; + stream << " );" << std::endl; + stream << std::endl; - stream << " next_event_i => next_event_i," << std::endl; - stream << " next_event_we_i => next_event_we_i," << std::endl; - stream << " error_o => error_o," << std::endl; + stream << " ec : event_controller" << std::endl; + stream << " port map (" << std::endl; + stream << " clk => clk," << std::endl; + stream << " rst_i => reset," << std::endl; + stream << std::endl; - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") - << "_o => state_active_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; + stream << " event_o => next_event_i," << std::endl; + stream << " event_we_o => next_event_we_i," << std::endl; - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " entry_set_" << ATTR(state, "documentOrder") - << "_o => entry_set_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; - } + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") + << "_i => state_active_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " exit_set_" << ATTR(state, "documentOrder") - << "_o => exit_set_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") + << "_i => entry_set_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; } - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " transition_set_" << ATTR(transition, "postFixOrder") - << "_o => transition_set_" << ATTR(transition, "postFixOrder") - << "_sig," << std::endl; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") + << "_i => exit_set_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; } + } - stream << " completed_o => completed_o" << std::endl; - stream << " );" << std::endl; - stream << std::endl; + 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 << " 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 << " micro_stepper_en_o => dut_enable" << std::endl; + // stream << " done_o => open" << std::endl; + stream << " );" << std::endl; + stream << std::endl; - stream << " event_o => next_event_i," << std::endl; - stream << " event_we_o => next_event_we_i," << std::endl; + // find pass state + std::list topLevelFinal = + DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "final", _scxml); - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") - << "_i => state_active_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; + std::string passStateNo = ""; + for (auto final : topLevelFinal) { + if (ATTR(final, "id") == "pass") { + passStateNo = ATTR(final, "documentOrder"); + } + } + stream << "end architecture;" << std::endl; + stream << "-- END TOP LEVEL" << std::endl; +} - 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; - } +void ChartToVHDL::writeEventController(std::ostream &stream) { + // Add controler specific stuff here + // create hardware top level + stream << "-- Event Controller Logic" << std::endl; + writeIncludes(stream); + stream << "entity event_controller is" << std::endl; + stream << "port(" << std::endl; + stream << " --inputs" << std::endl; + stream << " clk :in std_logic;" << std::endl; + stream << " rst_i :in std_logic;" << std::endl; - if (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 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; } - 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; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") + << "_i :in std_logic;" << std::endl; } + } - stream << " micro_stepper_en_o => dut_enable" << std::endl; - // stream << " done_o => open" << std::endl; - stream << " );" << std::endl; - stream << std::endl; + 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; + } + } - // find pass state - std::list topLevelFinal = - DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "final", _scxml); + stream << " --outputs" << std::endl; + stream << " micro_stepper_en_o :out std_logic;" << std::endl; + stream << " event_o :out std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << " event_we_o :out std_logic" << std::endl; + stream << ");" << std::endl; + stream << "end event_controller; " << std::endl; + + stream << std::endl; + stream << "architecture behavioral of event_controller is " << std::endl; + stream << std::endl; + + + // Add signals and components + stream << "signal rst : std_logic;" << std::endl; + stream << "signal micro_stepper_en : std_logic;" << std::endl; + stream << "signal cmpl_buf : std_logic;" << std::endl; + stream << "signal completed_sig : std_logic;" << std::endl; + stream << "signal event_bus : std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << "signal event_we : std_logic;" << std::endl; + + for (int i = 0; i < _execContent.size(); i++) { + stream << "signal done_" << toStr(i) << "_sig : std_logic;" << std::endl; + stream << "signal start_" << toStr(i) << "_sig : std_logic;" << std::endl; + } - std::string passStateNo = ""; - for (auto final : topLevelFinal) { - if (ATTR(final, "id") == "pass") { - passStateNo = ATTR(final, "documentOrder"); - } - } - stream << "end architecture;" << std::endl; - stream << "-- END TOP LEVEL" << std::endl; + 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; - 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; + // check if there is SUPPORTED executable content + bool foundSupportedExecContent = false; + for (auto exContentElem : _execContent) { + if (isSupportedExecContent(exContentElem)) { + foundSupportedExecContent = true; + break; + } + } + if (!foundSupportedExecContent) { + // set output correct if there is no supported excontent + + if (_execContent.size() > 0) { + // show warning if executable content is ignored + stream << "-- no supported executable content found" << std::endl; + stream << "-- state machine may not run correctly" << std::endl; + } + stream << "-- setting output lines to fulfil dummy functionality" << std::endl; + stream << "micro_stepper_en_o <= '1';" << std::endl; + stream << "event_o <= (others => '0');" << std::endl; + stream << "event_we_o <= '0';" << std::endl; + stream << std::endl; + } else { + // system signal mapping + stream << "rst <= rst_i;" << std::endl; + stream << "micro_stepper_en_o <= micro_stepper_en;" << std::endl; + stream << "event_o <= event_bus;" << std::endl; + stream << "event_we_o <= event_we;" << std::endl; + stream << std::endl; + // stall management + stream << "-- stalling microstepper" << std::endl; + stream << "micro_stepper_en <= completed_sig or not ( '0' "; for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") - << "_i :in std_logic;" << std::endl; if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " entry_set_" << ATTR(state, "documentOrder") - << "_i :in std_logic;" << std::endl; + stream << std::endl << " or entry_set_" << ATTR(state, "documentOrder") + << "_i"; } if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " exit_set_" << ATTR(state, "documentOrder") - << "_i :in std_logic;" << std::endl; + stream << std::endl << " or exit_set_" << ATTR(state, "documentOrder") + << "_i"; } } - for (auto transition : _transitions) { if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " transition_set_" << ATTR(transition, "postFixOrder") - << "_i :in std_logic;" << std::endl; + stream << std::endl << " or transition_set_" << ATTR(transition, "postFixOrder") + << "_i"; } } - - stream << " --outputs" << std::endl; - stream << " micro_stepper_en_o :out std_logic;" << std::endl; - stream << " event_o :out std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << " event_we_o :out std_logic" << std::endl; stream << ");" << std::endl; - stream << "end event_controller; " << std::endl; - stream << std::endl; - stream << "architecture behavioral of event_controller is " << std::endl; - stream << std::endl; - - - // Add signals and components - stream << "signal rst : std_logic;" << std::endl; - stream << "signal micro_stepper_en : std_logic;" << std::endl; - stream << "signal cmpl_buf : std_logic;" << std::endl; - stream << "signal completed_sig : std_logic;" << std::endl; - stream << "signal event_bus : std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << "signal event_we : std_logic;" << std::endl; + // sequential code operation + stream << "-- seq code block " << std::endl; + stream << "ex_content_block : process (clk, rst) " << std::endl; + stream << "begin" << std::endl; + stream << " if rst = '1' then" << std::endl; for (int i = 0; i < _execContent.size(); i++) { - stream << "signal done_" << toStr(i) << "_sig : std_logic;" << std::endl; - stream << "signal start_" << toStr(i) << "_sig : std_logic;" << std::endl; + stream << " done_" << toStr(i) << "_sig <= '0';" << std::endl; } + stream << " event_bus <= (others => '0');" << std::endl; + stream << " event_we <= '0';" << std::endl; + stream << " cmpl_buf <= '0';" << std::endl; + stream << " completed_sig <= '0';" << std::endl; + stream << " elsif rising_edge(clk) then" << std::endl; - stream << "-- 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 << " if micro_stepper_en = '1' then" << std::endl; + stream << " cmpl_buf <= '0' ;" << std::endl; + stream << " else" << std::endl; + stream << " cmpl_buf <= seq_" << toStr(_execContent.size() - 1) + << "_sig;" << std::endl; + stream << " end if;" << std::endl; + stream << " completed_sig <= cmpl_buf;" << std::endl << std::endl; - stream << "begin" << std::endl; - stream << std::endl; + size_t i = 0; + std::string seperator = " "; + for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { + DOMElement *exContentElem = *ecIter; - // check if there is SUPPORTED executable content - bool foundSupportedExecContent = false; - for (auto exContentElem : _execContent) { if (isSupportedExecContent(exContentElem)) { - foundSupportedExecContent = true; - break; - } - } - if (!foundSupportedExecContent) { - // set output correct if there is no supported excontent - if (_execContent.size() > 0) { - // show warning if executable content is ignored - stream << "-- no supported executable content found" << std::endl; - stream << "-- state machine may not run correctly" << std::endl; - } - stream << "-- setting output lines to fulfil dummy functionality" << std::endl; - stream << "micro_stepper_en_o <= '1';" << std::endl; - stream << "event_o <= (others => '0');" << std::endl; - stream << "event_we_o <= '0';" << std::endl; - stream << std::endl; - } else { - // system signal mapping - stream << "rst <= rst_i;" << std::endl; - stream << "micro_stepper_en_o <= micro_stepper_en;" << std::endl; - stream << "event_o <= event_bus;" << std::endl; - stream << "event_we_o <= event_we;" << std::endl; - stream << std::endl; - - // stall management - stream << "-- stalling microstepper" << std::endl; - stream << "micro_stepper_en <= completed_sig or not ( '0' "; - for (auto state : _states) { - - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << std::endl << " or entry_set_" << ATTR(state, "documentOrder") - << "_i"; - } + stream << seperator << "if start_" << toStr(i) << "_sig = '1' then" + << std::endl; - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << std::endl << " or exit_set_" << ATTR(state, "documentOrder") - << "_i"; - } - } - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << std::endl << " or transition_set_" << ATTR(transition, "postFixOrder") - << "_i"; - } - } - stream << ");" << std::endl; - stream << std::endl; - - // sequential code operation - stream << "-- seq code block " << std::endl; - stream << "ex_content_block : process (clk, rst) " << std::endl; - stream << "begin" << std::endl; - stream << " if rst = '1' then" << std::endl; - for (int i = 0; i < _execContent.size(); i++) { - stream << " done_" << toStr(i) << "_sig <= '0';" << std::endl; - } - stream << " event_bus <= (others => '0');" << std::endl; - stream << " event_we <= '0';" << std::endl; - stream << " cmpl_buf <= '0';" << std::endl; - stream << " completed_sig <= '0';" << std::endl; - stream << " elsif rising_edge(clk) then" << std::endl; - - stream << " if micro_stepper_en = '1' then" << std::endl; - stream << " cmpl_buf <= '0' ;" << std::endl; - stream << " else" << std::endl; - stream << " cmpl_buf <= seq_" << toStr(_execContent.size() - 1) - << "_sig;" << std::endl; - stream << " end if;" << std::endl; - stream << " completed_sig <= cmpl_buf;" << std::endl << std::endl; - - size_t i = 0; - std::string seperator = " "; - for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { - DOMElement *exContentElem = *ecIter; - - if (isSupportedExecContent(exContentElem)) { - - stream << seperator << "if start_" << toStr(i) << "_sig = '1' then" - << std::endl; - - size_t jj = 0; - for (auto eventIter = _eventNames.begin(); eventIter != _eventNames.end(); eventIter++, jj++) { - if (((*eventIter)->value) == ATTR(exContentElem, "event")) { - break; - } + size_t jj = 0; + for (auto eventIter = _eventNames.begin(); eventIter != _eventNames.end(); eventIter++, jj++) { + if (((*eventIter)->value) == ATTR(exContentElem, "event")) { + break; } - stream << " event_bus <= \"" << toBinStr(jj, _eventBitSize + 1) << "\";" << std::endl; - stream << " done_" << toStr(i) << "_sig <= '1';" << std::endl; - stream << " event_we <= '1';" << std::endl; - seperator = " els"; } + stream << " event_bus <= \"" << toBinStr(jj, _eventBitSize + 1) << "\";" << std::endl; + stream << " done_" << toStr(i) << "_sig <= '1';" << std::endl; + stream << " event_we <= '1';" << std::endl; + seperator = " els"; } - stream << " elsif micro_stepper_en = '1' then" << std::endl; - i = 0; - //for (auto exContentElem : _execContent) { - for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { - DOMElement *exContentElem = *ecIter; - if (isSupportedExecContent(exContentElem)) { - stream << " done_" << toStr(i) << "_sig <= '0';" << std::endl; - } + } + stream << " elsif micro_stepper_en = '1' then" << std::endl; + i = 0; + //for (auto exContentElem : _execContent) { + for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { + DOMElement *exContentElem = *ecIter; + if (isSupportedExecContent(exContentElem)) { + stream << " done_" << toStr(i) << "_sig <= '0';" << std::endl; } - stream << " event_we <= '0';" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << "end process;" << std::endl; - stream << std::endl; + } + stream << " event_we <= '0';" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << "end process;" << std::endl; + stream << std::endl; - i = 0; - for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { - // start lines - stream << "start_" << toStr(i) << "_sig <= " - << getLineForExecContent(*ecIter) << " and " - << "not done_" << toStr(i) << "_sig"; + i = 0; + for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { + // start lines + stream << "start_" << toStr(i) << "_sig <= " + << getLineForExecContent(*ecIter) << " and " + << "not done_" << toStr(i) << "_sig"; - // if not needed, since seq_0_sig is hard coded as '1'. + // if not needed, since seq_0_sig is hard coded as '1'. // if (i != 0) { // if not first element - stream << " and seq_" << toStr(i) << "_sig"; + stream << " and seq_" << toStr(i) << "_sig"; // } - stream << ";" << std::endl; + stream << ";" << std::endl; - } + } - stream << "seq_0_sig <= '1';" << std::endl; - - if (_execContent.size() > 1) { - i = 0; - for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { - // prevent writing seq_0_sig since this should be hardcoded to '1' - if (i != 0) { - // seq lines (input if process i is in seqence now) - stream << "seq_" << toStr(i) << "_sig <= " - << "done_" << toStr(i - 1) << "_sig or " - << "( not " - << getLineForExecContent(*ecIter); - stream << " and seq_" << toStr(i - 1) << "_sig"; - stream << " );" << std::endl; - } + stream << "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; + stream << std::endl; } + stream << "end behavioral; " << + std::endl; + stream << "-- END Event Controller Logic" << + std::endl; + stream << + std::endl; +} - void ChartToVHDL::writeConditionSolver(std::ostream &stream) { - // TODO implement - // --> solves conditions given by ast - // --> Level 1 support In(), >, <, = - // --> Level 2 support +, - - // --> Level 3 support *, /, mod <-- (just integer operations) - - // Add controler specific stuff here - // create hardware top level - stream << "-- Condition Solver Logic" << std::endl; - writeIncludes(stream); - stream << "entity condition_solver 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; - } +void ChartToVHDL::writeConditionSolver(std::ostream &stream) { + // TODO implement + // --> solves conditions given by ast + // --> Level 1 support In(), >, <, = + // --> Level 2 support +, - + // --> Level 3 support *, /, mod <-- (just integer operations) + + // Add controler specific stuff here + // create hardware top level + stream << "-- Condition Solver Logic" << std::endl; + writeIncludes(stream); + stream << "entity condition_solver 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; + } - stream << " --outputs" << std::endl; + stream << " --outputs" << std::endl; - for (auto transition : _transitions) { - if (HAS_ATTR(transition, "cond")) { - stream << " transition_condition_fulfilled_" << ATTR(transition, "postFixOrder") - << "_o :out std_logic;" << std::endl; - } + for (auto transition : _transitions) { + if (HAS_ATTR(transition, "cond")) { + stream << " transition_condition_fulfilled_" << ATTR(transition, "postFixOrder") + << "_o :out std_logic;" << std::endl; } + } - stream << " micro_stepper_en_o :out std_logic" << std::endl; - stream << ");" << std::endl; - stream << "end condition_solver; " << std::endl; + stream << " micro_stepper_en_o :out std_logic" << std::endl; + stream << ");" << std::endl; + stream << "end condition_solver; " << std::endl; - stream << std::endl; - stream << "architecture behavioral of condition_solver is " << std::endl; - stream << std::endl; + stream << std::endl; + stream << "architecture behavioral of condition_solver 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; + // Add signals and components + stream << "signal rst : std_logic;" << std::endl; + stream << "signal micro_stepper_en : 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; - } + 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; + } - for (auto transition : _transitions) { - if (HAS_ATTR(transition, "cond")) { - stream << "signal transition_condition_fulfilled_" << ATTR(transition, "postFixOrder") - << "_sig : std_logic;" << std::endl; - } + for (auto transition : _transitions) { + if (HAS_ATTR(transition, "cond")) { + stream << "signal transition_condition_fulfilled_" << ATTR(transition, "postFixOrder") + << "_sig : std_logic;" << std::endl; } - stream << std::endl; + } + stream << std::endl; - stream << "begin" << 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 << std::endl; + // system signal mapping + stream << "rst <= rst_i;" << std::endl; + stream << "micro_stepper_en_o <= micro_stepper_en;" << std::endl; + stream << std::endl; - for (auto transition : _transitions) { - if (HAS_ATTR(transition, "cond")) { - stream << "transition_condition_fulfilled_" << ATTR(transition, "postFixOrder") - << "_o <= transition_condition_fulfilled_" << ATTR(transition, "postFixOrder") - << "_sig;" << std::endl; - } + for (auto transition : _transitions) { + if (HAS_ATTR(transition, "cond")) { + stream << "transition_condition_fulfilled_" << ATTR(transition, "postFixOrder") + << "_o <= transition_condition_fulfilled_" << ATTR(transition, "postFixOrder") + << "_sig;" << std::endl; } + } - // stall management - stream << "-- stalling microstepper" << std::endl; - stream << "micro_stepper_en <= '1';" << std::endl; - stream << std::endl; + // stall management + stream << "-- stalling microstepper" << std::endl; + stream << "micro_stepper_en <= '1';" << std::endl; + stream << std::endl; - // solve conditions - stream << "-- solve conditions" << std::endl; - for (auto transition : _transitions) { - if (HAS_ATTR(transition, "cond")) { - stream << "-- cond:"<< ATTR(transition, "cond") << std::endl; - // TODO parse code here and generate hardware from AST - stream << "transition_condition_fulfilled_" << ATTR(transition, "postFixOrder") - << "_sig <= '0';" << std::endl; - } + // solve conditions + stream << "-- solve conditions" << std::endl; + for (auto transition : _transitions) { + if (HAS_ATTR(transition, "cond")) { + stream << "-- cond:"<< ATTR(transition, "cond") << std::endl; + // TODO parse code here and generate hardware from AST + stream << "transition_condition_fulfilled_" << ATTR(transition, "postFixOrder") + << "_sig <= '0';" << std::endl; } - - - stream << "end behavioral; " << - std::endl; - stream << "-- END Condition Solver 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"; - } + stream << "end behavioral; " << + std::endl; + stream << "-- END Condition Solver Logic" << + std::endl; + stream << + std::endl; +} - 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"; - } +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 ""; + } + ecBlock = ecBlock->getParentNode(); } - void ChartToVHDL::writeMicroStepper(std::ostream &stream) { - // create MicroStepper top level - stream << "-- FSM Logic" << std::endl; - writeIncludes(stream); - stream << "entity micro_stepper is" << std::endl; - stream << "port(" << std::endl; - stream << " --inputs" << std::endl; - stream << " clk :in std_logic;" << std::endl; - stream << " rst_i :in std_logic;" << std::endl; - stream << " en :in std_logic;" << std::endl; - stream << " next_event_i :in std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << " next_event_we_i :in std_logic;" << std::endl; + return ""; +} - for (auto transition : _transitions) { - if (HAS_ATTR(transition, "cond")) { // create enable line if transition has conditions - stream << "signal transition_condition_fulfilled_" << ATTR(transition, "postFixOrder") << - "_i : std_logic;" - << std::endl; - } +void ChartToVHDL::writeMicroStepper(std::ostream &stream) { + // create MicroStepper top level + stream << "-- FSM Logic" << std::endl; + writeIncludes(stream); + stream << "entity micro_stepper is" << std::endl; + stream << "port(" << std::endl; + stream << " --inputs" << std::endl; + stream << " clk :in std_logic;" << std::endl; + stream << " rst_i :in std_logic;" << std::endl; + stream << " en :in std_logic;" << std::endl; + stream << " next_event_i :in std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << " next_event_we_i :in std_logic;" << std::endl; + + for (auto transition : _transitions) { + if (HAS_ATTR(transition, "cond")) { // create enable line if transition has conditions + stream << "signal transition_condition_fulfilled_" << ATTR(transition, "postFixOrder") << + "_i : std_logic;" + << std::endl; } + } - stream << " --outputs" << std::endl; - stream << " error_o :out std_logic;" << std::endl; - - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; + stream << " --outputs" << std::endl; + stream << " error_o :out std_logic;" << std::endl; - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " entry_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; - } + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " exit_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; } - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " transition_set_" << ATTR(transition, "postFixOrder") << "_o :out std_logic;" - << std::endl; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; } + } - stream << " completed_o :out std_logic" << std::endl; - stream << ");" << std::endl; - stream << "end micro_stepper; " << std::endl; + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") << "_o :out std_logic;" + << std::endl; + } + } - stream << std::endl; - stream << "architecture behavioral of micro_stepper is " << std::endl; - stream << std::endl; + stream << " completed_o :out std_logic" << std::endl; + stream << ");" << std::endl; + stream << "end micro_stepper; " << std::endl; - // Add signals and components - writeSignalsAndComponents(stream); + stream << std::endl; + stream << "architecture behavioral of micro_stepper is " << std::endl; + stream << std::endl; - stream << std::endl; - stream << "begin" << std::endl; - stream << std::endl; + // Add signals and components + writeSignalsAndComponents(stream); - // signal mapping - writeModuleInstantiation(stream); + stream << std::endl; + stream << "begin" << std::endl; + stream << std::endl; - // signal handler - writeSpontaneousHandler(stream); - writeErrorHandler(stream); - writeInternalEventHandler(stream); - writeStateHandler(stream); - writeResetHandler(stream); + // signal mapping + writeModuleInstantiation(stream); - // combinatorial logic for Sn+1 - writeOptimalTransitionSetSelection(stream); - writeExitSet(stream); - writeCompleteEntrySet(stream); - writeEntrySet(stream); - //writeDefaultCompletions(stream); - writeActiveStateNplusOne(stream); + // signal handler + writeSpontaneousHandler(stream); + writeErrorHandler(stream); + writeInternalEventHandler(stream); + writeStateHandler(stream); + writeResetHandler(stream); - // connect output signals - writeSystemSignalMapping(stream); + // combinatorial logic for Sn+1 + writeOptimalTransitionSetSelection(stream); + writeExitSet(stream); + writeCompleteEntrySet(stream); + writeEntrySet(stream); + //writeDefaultCompletions(stream); + writeActiveStateNplusOne(stream); + // connect output signals + writeSystemSignalMapping(stream); - stream << std::endl; - stream << "end behavioral; " << std::endl; - stream << "-- END FSM Logic" << std::endl; - } - - void ChartToVHDL::writeFiFo(std::ostream &stream) { - // taken from: http://www.deathbylogic.com/2013/07/vhdl-standard-fifo/ - // alternativly take fifo logic for a ram device: http://www.eng.auburn.edu/~strouce/class/elec4200/vhdlmods.pdf - stream << "-- standard FIFO buffer" << std::endl; - writeIncludes(stream); - stream << "" << std::endl; - stream << "entity std_fifo is" << std::endl; - stream << "generic (" << std::endl; - stream << " constant FIFO_DEPTH : positive := 256" << std::endl; - stream << ");" << std::endl; - stream << "port ( " << std::endl; - stream << " clk : in std_logic;" << std::endl; - stream << " rst : in std_logic;" << std::endl; - stream << " write_en : in std_logic;" << std::endl; - stream << " read_en : in std_logic;" << std::endl; - stream << " data_in : in std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << " data_out : out std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << " empty : out std_logic;" << std::endl; - stream << " full : out std_logic" << std::endl; - stream << ");" << std::endl; - stream << "end std_fifo;" << std::endl; - stream << "" << std::endl; - stream << "architecture behavioral of std_fifo is" << std::endl; - stream << "begin" << std::endl; - stream << "-- Memory Pointer Process" << std::endl; - stream << "fifo_proc : process (clk)" << std::endl; - stream << " type FIFO_Memory is array (0 to FIFO_DEPTH - 1) of std_logic_vector( " << _eventBitSize << - " downto 0);" << std::endl; - stream << " variable Memory : FIFO_Memory;" << std::endl; - stream << "" << std::endl; - stream << " variable Head : natural range 0 to FIFO_DEPTH - 1;" << std::endl; - stream << " variable Tail : natural range 0 to FIFO_DEPTH - 1;" << std::endl; - stream << "" << std::endl; - stream << " variable Looped : boolean;" << std::endl; - stream << "begin" << std::endl; - stream << " if rising_edge(clk) then" << std::endl; - stream << " if rst = '1' then" << std::endl; - stream << " Head := 0;" << std::endl; - stream << " Tail := 0;" << std::endl; - stream << "" << std::endl; - stream << " Looped := false;" << std::endl; - stream << "" << std::endl; - stream << " full <= '0';" << std::endl; - stream << " empty <= '1';" << std::endl; - stream << " else" << std::endl; - stream << " if (read_en = '1') then" << std::endl; - stream << " if ((Looped = true) or (Head /= Tail)) then" << std::endl; - stream << " -- Update data output" << std::endl; - stream << " data_out <= Memory(Tail);" << std::endl; - stream << " " << std::endl; - stream << " -- Update Tail pointer as needed" << std::endl; - stream << " if (Tail = FIFO_DEPTH - 1) then" << std::endl; - stream << " Tail := 0;" << std::endl; - stream << " " << std::endl; - stream << " Looped := false;" << std::endl; - stream << " else" << std::endl; - stream << " Tail := Tail + 1;" << std::endl; - stream << " end if;" << std::endl; - stream << "" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << "" << std::endl; - stream << " if (write_en = '1') then" << std::endl; - stream << " if ((Looped = false) or (Head /= Tail)) then" << std::endl; - stream << " -- Write Data to Memory" << std::endl; - stream << " Memory(Head) := data_in;" << std::endl; - stream << " " << std::endl; - stream << " -- Increment Head pointer as needed" << std::endl; - stream << " if (Head = FIFO_DEPTH - 1) then" << std::endl; - stream << " Head := 0;" << std::endl; - stream << " " << std::endl; - stream << " Looped := true;" << std::endl; - stream << " else" << std::endl; - stream << " Head := Head + 1;" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << "" << std::endl; - stream << " -- Update empty and full flags" << std::endl; - stream << " if (Head = Tail) then" << std::endl; - stream << " if Looped then" << std::endl; - stream << " full <= '1';" << std::endl; - stream << " else" << std::endl; - stream << " empty <= '1';" << std::endl; - stream << " end if;" << std::endl; - stream << " else" << std::endl; - stream << " empty <= '0';" << std::endl; - stream << " full <= '0';" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << "end process;" << std::endl; - stream << "" << std::endl; - stream << "end behavioral;" << std::endl; - stream << "-- END standard FIFO buffer" << std::endl; - } - void ChartToVHDL::writeSignalsAndComponents(std::ostream &stream) { - // create internal signals - stream << "-- system signals" << std::endl; - stream << "signal stall : std_logic;" << std::endl; - stream << "signal completed_sig : std_logic;" << std::endl; - stream << "signal rst : std_logic;" << std::endl; - stream << std::endl; + stream << std::endl; + stream << "end behavioral; " << std::endl; + stream << "-- END FSM Logic" << std::endl; +} - stream << "-- state signals" << std::endl; +void ChartToVHDL::writeFiFo(std::ostream &stream) { + // taken from: http://www.deathbylogic.com/2013/07/vhdl-standard-fifo/ + // alternativly take fifo logic for a ram device: http://www.eng.auburn.edu/~strouce/class/elec4200/vhdlmods.pdf + stream << "-- standard FIFO buffer" << std::endl; + writeIncludes(stream); + stream << "" << std::endl; + stream << "entity std_fifo is" << std::endl; + stream << "generic (" << std::endl; + stream << " constant FIFO_DEPTH : positive := 256" << std::endl; + stream << ");" << std::endl; + stream << "port ( " << std::endl; + stream << " clk : in std_logic;" << std::endl; + stream << " rst : in std_logic;" << std::endl; + stream << " write_en : in std_logic;" << std::endl; + stream << " read_en : in std_logic;" << std::endl; + stream << " data_in : in std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << " data_out : out std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << " empty : out std_logic;" << std::endl; + stream << " full : out std_logic" << std::endl; + stream << ");" << std::endl; + stream << "end std_fifo;" << std::endl; + stream << "" << std::endl; + stream << "architecture behavioral of std_fifo is" << std::endl; + stream << "begin" << std::endl; + stream << "-- Memory Pointer Process" << std::endl; + stream << "fifo_proc : process (clk)" << std::endl; + stream << " type FIFO_Memory is array (0 to FIFO_DEPTH - 1) of std_logic_vector( " << _eventBitSize << + " downto 0);" << std::endl; + stream << " variable Memory : FIFO_Memory;" << std::endl; + stream << "" << std::endl; + stream << " variable Head : natural range 0 to FIFO_DEPTH - 1;" << std::endl; + stream << " variable Tail : natural range 0 to FIFO_DEPTH - 1;" << std::endl; + stream << "" << std::endl; + stream << " variable Looped : boolean;" << std::endl; + stream << "begin" << std::endl; + stream << " if rising_edge(clk) then" << std::endl; + stream << " if rst = '1' then" << std::endl; + stream << " Head := 0;" << std::endl; + stream << " Tail := 0;" << std::endl; + stream << "" << std::endl; + stream << " Looped := false;" << std::endl; + stream << "" << std::endl; + stream << " full <= '0';" << std::endl; + stream << " empty <= '1';" << std::endl; + stream << " else" << std::endl; + stream << " if (read_en = '1') then" << std::endl; + stream << " if ((Looped = true) or (Head /= Tail)) then" << std::endl; + stream << " -- Update data output" << std::endl; + stream << " data_out <= Memory(Tail);" << std::endl; + stream << " " << std::endl; + stream << " -- Update Tail pointer as needed" << std::endl; + stream << " if (Tail = FIFO_DEPTH - 1) then" << std::endl; + stream << " Tail := 0;" << std::endl; + stream << " " << std::endl; + stream << " Looped := false;" << std::endl; + stream << " else" << std::endl; + stream << " Tail := Tail + 1;" << std::endl; + stream << " end if;" << std::endl; + stream << "" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << "" << std::endl; + stream << " if (write_en = '1') then" << std::endl; + stream << " if ((Looped = false) or (Head /= Tail)) then" << std::endl; + stream << " -- Write Data to Memory" << std::endl; + stream << " Memory(Head) := data_in;" << std::endl; + stream << " " << std::endl; + stream << " -- Increment Head pointer as needed" << std::endl; + stream << " if (Head = FIFO_DEPTH - 1) then" << std::endl; + stream << " Head := 0;" << std::endl; + stream << " " << std::endl; + stream << " Looped := true;" << std::endl; + stream << " else" << std::endl; + stream << " Head := Head + 1;" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << "" << std::endl; + stream << " -- Update empty and full flags" << std::endl; + stream << " if (Head = Tail) then" << std::endl; + stream << " if Looped then" << std::endl; + stream << " full <= '1';" << std::endl; + stream << " else" << std::endl; + stream << " empty <= '1';" << std::endl; + stream << " end if;" << std::endl; + stream << " else" << std::endl; + stream << " empty <= '0';" << std::endl; + stream << " full <= '0';" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << "end process;" << std::endl; + stream << "" << std::endl; + stream << "end behavioral;" << std::endl; + stream << "-- END standard FIFO buffer" << std::endl; +} - std::list signalDecls; +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; - for (auto state : _states) { - std::string parent = ATTR(state, "parent"); - - signalDecls.push_back("signal state_active_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); - signalDecls.push_back("signal state_next_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); - signalDecls.push_back("signal in_entry_set_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); - signalDecls.push_back("signal in_exit_set_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); - signalDecls.push_back("signal in_complete_entry_set_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); - - // not needed for state - if (parent.size() != 0) { - signalDecls.push_back( - "signal in_complete_entry_set_up_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); - } - } + stream << "-- state signals" << std::endl; - signalDecls.sort(); - for (std::list::iterator iter = signalDecls.begin(); iter != signalDecls.end(); iter++) { - stream << *iter << std::endl; - } - stream << std::endl; + std::list signalDecls; + for (auto state : _states) { + std::string parent = ATTR(state, "parent"); - 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; + 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;"); - for (auto transition : _transitions) { - stream << "signal in_optimal_transition_set_" << ATTR(transition, "postFixOrder") << "_sig : std_logic;" - << std::endl; + // not needed for state + if (parent.size() != 0) { + signalDecls.push_back( + "signal in_complete_entry_set_up_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); } - stream << std::endl; + } - stream << "-- event signals" << std::endl; - stream << "signal int_event_write_en : std_logic;" << std::endl; - stream << "signal int_event_read_en : std_logic;" << std::endl; - stream << "signal int_event_empty : std_logic;" << std::endl; - stream << "signal int_event_input : std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << "signal int_event_output : std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << "signal next_event_re : std_logic;" << std::endl; - stream << "signal event_dequeued : std_logic;" << std::endl; - stream << "signal next_event : std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << "signal event_consumed : std_logic;" << std::endl; - stream << std::endl; + signalDecls.sort(); + for (std::list::iterator iter = signalDecls.begin(); iter != signalDecls.end(); iter++) { + stream << *iter << std::endl; + } + stream << std::endl; - for (std::list::iterator eventIter = _eventNames.begin(); - eventIter != _eventNames.end(); eventIter++) { - stream << "signal event_" << escapeMacro((*eventIter)->value) << "_sig : std_logic;" << std::endl; - } - stream << std::endl; - stream << "-- error signals" << std::endl; - stream << "signal reg_error_out : std_logic;" << std::endl; - stream << "signal error_full_int_event_fifo : std_logic;" << std::endl; - stream << std::endl; + 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; - // add components - stream << "-- event FIFO" << std::endl; - stream << "component std_fifo is" << std::endl; - stream << "port ( " << std::endl; - stream << " clk : in std_logic;" << std::endl; - stream << " rst : in std_logic;" << std::endl; - stream << " write_en : in std_logic;" << std::endl; - stream << " read_en : in std_logic;" << std::endl; - stream << " data_in : in std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << " data_out : out std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; - stream << " empty : out std_logic;" << std::endl; - stream << " full : out std_logic" << std::endl; // we calculate how much we need - stream << ");" << std::endl; - stream << "end component;" << std::endl; - stream << std::endl; + for (auto transition : _transitions) { + stream << "signal in_optimal_transition_set_" << ATTR(transition, "postFixOrder") << "_sig : std_logic;" + << 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; + stream << std::endl; + + stream << "-- event signals" << std::endl; + stream << "signal int_event_write_en : std_logic;" << std::endl; + stream << "signal int_event_read_en : std_logic;" << std::endl; + stream << "signal int_event_empty : std_logic;" << std::endl; + stream << "signal int_event_input : std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << "signal int_event_output : std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << "signal next_event_re : std_logic;" << std::endl; + stream << "signal event_dequeued : std_logic;" << std::endl; + stream << "signal next_event : std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << "signal event_consumed : std_logic;" << std::endl; + stream << std::endl; + + for (std::list::iterator eventIter = _eventNames.begin(); + eventIter != _eventNames.end(); eventIter++) { + stream << "signal event_" << escapeMacro((*eventIter)->value) << "_sig : std_logic;" << std::endl; } + stream << std::endl; + + stream << "-- error signals" << std::endl; + stream << "signal reg_error_out : std_logic;" << std::endl; + stream << "signal error_full_int_event_fifo : std_logic;" << std::endl; + stream << std::endl; + + // add components + stream << "-- event FIFO" << std::endl; + stream << "component std_fifo is" << std::endl; + stream << "port ( " << std::endl; + stream << " clk : in std_logic;" << std::endl; + stream << " rst : in std_logic;" << std::endl; + stream << " write_en : in std_logic;" << std::endl; + stream << " read_en : in std_logic;" << std::endl; + stream << " data_in : in std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << " data_out : out std_logic_vector( " << _eventBitSize << " downto 0);" << std::endl; + stream << " empty : out std_logic;" << std::endl; + stream << " full : out std_logic" << std::endl; // we calculate how much we need + stream << ");" << std::endl; + stream << "end component;" << std::endl; + stream << std::endl; +} - void ChartToVHDL::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::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::writeResetHandler(std::ostream &stream) { - stream << "-- reset handler" << std::endl; - stream << "rst <= rst_i;" << 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::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 (but enable it when queue is empty -> spontaneous based state chart) - stream << " spontaneous_en <= event_dequeued or (not event_dequeued and int_event_empty);" << - std::endl; - stream << " end if;" << 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::writeInternalEventHandler(std::ostream &stream) { - // Add controler specific stuff here - stream << "-- event handler" << std::endl; - stream << "-- pops events and set event signals" << std::endl; - stream << "event_handler : process (clk, rst) " << std::endl; - stream << "begin" << std::endl; - stream << " if rst = '1' then" << std::endl; +void ChartToVHDL::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 (but enable it when queue is empty -> spontaneous based state chart) + stream << " spontaneous_en <= event_dequeued or (not event_dequeued and int_event_empty);" << + std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << "end process;" << std::endl; + stream << std::endl; +} - for (std::list::iterator eventIter = _eventNames.begin(); - eventIter != _eventNames.end(); eventIter++) { - stream << " event_" << escapeMacro((*eventIter)->value) << "_sig <= '0';" << std::endl; - } +void ChartToVHDL::writeInternalEventHandler(std::ostream &stream) { + // Add controler specific stuff here + stream << "-- event handler" << std::endl; + stream << "-- pops events and set event signals" << std::endl; + stream << "event_handler : process (clk, rst) " << std::endl; + stream << "begin" << std::endl; + stream << " if rst = '1' then" << std::endl; + + for (std::list::iterator eventIter = _eventNames.begin(); + eventIter != _eventNames.end(); eventIter++) { + stream << " event_" << escapeMacro((*eventIter)->value) << "_sig <= '0';" << std::endl; + } - stream << " event_dequeued <= '0';" << std::endl; - stream << " event_consumed <= '0';" << std::endl; + stream << " event_dequeued <= '0';" << std::endl; + stream << " event_consumed <= '0';" << std::endl; - stream << " elsif falling_edge(clk) and stall = '0' then" << std::endl; + stream << " elsif falling_edge(clk) and stall = '0' then" << std::endl; - VContainer eventConsumed = VOR; - for (auto transition : _transitions) { + VContainer eventConsumed = VOR; + for (auto transition : _transitions) { - if (HAS_ATTR(transition, "event") == true) { - *eventConsumed += VLINE("in_optimal_transition_set_" - + ATTR(transition, "postFixOrder") + "_sig"); - } + if (HAS_ATTR(transition, "event") == true) { + *eventConsumed += VLINE("in_optimal_transition_set_" + + ATTR(transition, "postFixOrder") + "_sig"); } + } - VBranch *tree = (VASSIGN, - VLINE(" event_consumed"), - eventConsumed); - tree->print(stream); - stream << ";" << std::endl; - - stream << " if int_event_empty = '0' then " << std::endl; - stream << " case next_event is " << std::endl; - - size_t jj = 0; - for (std::list::iterator eventIter = _eventNames.begin(); - eventIter != _eventNames.end(); eventIter++, jj++) { - - stream << " when \"" << toBinStr(jj, _eventBitSize + 1) << "\" =>" << std::endl; - for (std::list::iterator eventIter2 = _eventNames.begin(); - eventIter2 != _eventNames.end(); eventIter2++) { - stream << " event_" << escapeMacro((*eventIter2)->value); - if (escapeMacro((*eventIter)->value) == escapeMacro((*eventIter2)->value)) { - stream << "_sig <= '1';" << std::endl; - } else { - stream << "_sig <= '0';" << std::endl; - } + VBranch *tree = (VASSIGN, + VLINE(" event_consumed"), + eventConsumed); + tree->print(stream); + stream << ";" << std::endl; + + stream << " if int_event_empty = '0' then " << std::endl; + stream << " case next_event is " << std::endl; + + size_t jj = 0; + for (std::list::iterator eventIter = _eventNames.begin(); + eventIter != _eventNames.end(); eventIter++, jj++) { + + stream << " when \"" << toBinStr(jj, _eventBitSize + 1) << "\" =>" << std::endl; + for (std::list::iterator eventIter2 = _eventNames.begin(); + eventIter2 != _eventNames.end(); eventIter2++) { + stream << " event_" << escapeMacro((*eventIter2)->value); + if (escapeMacro((*eventIter)->value) == escapeMacro((*eventIter2)->value)) { + stream << "_sig <= '1';" << std::endl; + } else { + stream << "_sig <= '0';" << std::endl; } - stream << " event_dequeued <= '1';" << std::endl; - } - stream << " when others =>" << std::endl; - for (std::list::iterator eventIter = _eventNames.begin(); - eventIter != _eventNames.end(); eventIter++) { - stream << " event_" << escapeMacro((*eventIter)->value) << "_sig <= '0';" << std::endl; - } - stream << " event_dequeued <= '0';" << std::endl; - stream << " end case;" << std::endl; - stream << " elsif int_event_empty = '1' and event_consumed = '1' then" << std::endl; - - for (std::list::iterator eventIter = _eventNames.begin(); - eventIter != _eventNames.end(); eventIter++) { - stream << " event_" << escapeMacro((*eventIter)->value) << "_sig <= '0';" << std::endl; } - stream << " 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; + stream << " event_dequeued <= '1';" << std::endl; } + stream << " when others =>" << std::endl; + for (std::list::iterator eventIter = _eventNames.begin(); + eventIter != _eventNames.end(); eventIter++) { + stream << " event_" << escapeMacro((*eventIter)->value) << "_sig <= '0';" << std::endl; + } + stream << " event_dequeued <= '0';" << std::endl; + stream << " end case;" << std::endl; + stream << " elsif int_event_empty = '1' and event_consumed = '1' then" << std::endl; - void ChartToVHDL::writeActiveStateNplusOne(std::ostream &stream) { - stream << "-- active configuration" << std::endl; - - for (auto state : _states) { - std::string parent = ATTR(state, "parent"); - - // special case for to start the state machine - if (parent.size() == 0) { - stream << " state_next_" << ATTR(state, "documentOrder") << "_sig <= " << - "not completed_sig;" << std::endl; - continue; - } + for (std::list::iterator eventIter = _eventNames.begin(); + eventIter != _eventNames.end(); eventIter++) { + stream << " event_" << escapeMacro((*eventIter)->value) << "_sig <= '0';" << std::endl; + } + stream << " 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; +} - VBranch *tree = (VASSIGN, - VLINE("state_next_" + ATTR(state, "documentOrder") + "_sig"), - (VOR, - VLINE("in_complete_entry_set_" + ATTR(state, "documentOrder") + "_sig"), - (VAND, (VNOT, VLINE("in_exit_set_" + ATTR(state, "documentOrder") + "_sig")), - VLINE("state_active_" + ATTR(state, "documentOrder") + "_sig")) - )); +void ChartToVHDL::writeActiveStateNplusOne(std::ostream &stream) { + stream << "-- active configuration" << std::endl; - tree->print(stream); - stream << ";" << std::endl; + for (auto state : _states) { + std::string parent = ATTR(state, "parent"); + // special case for to start the state machine + if (parent.size() == 0) { + stream << " state_next_" << ATTR(state, "documentOrder") << "_sig <= " << + "not completed_sig;" << std::endl; + continue; } - } - - 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"); + 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; - VContainer nameMatchers = VOR; - if (HAS_ATTR(transition, "event")) { - std::list eventDescs = tokenize(ATTR(transition, "event")); - for (std::list::iterator descIter = eventDescs.begin(); - descIter != eventDescs.end(); descIter++) { - std::list eventNames = _eventTrie.getWordsWithPrefix( - (*descIter) == "*" ? "" : *descIter); - for (std::list::iterator eventIter = eventNames.begin(); - eventIter != eventNames.end(); eventIter++) { - *nameMatchers += VLINE("event_" + escapeMacro((*eventIter)->value) + "_sig"); - } - } - } else { - *nameMatchers += VLINE("'1'"); - } + } +} - VContainer conflicters = VOR; - for (size_t j = 0; j < strTo(ATTR(transition, "postFixOrder")); j++) { - if (conflicts[j] == '1') { - *conflicters += VLINE("in_optimal_transition_set_" + toStr(j) + "_sig"); +void ChartToVHDL::writeOptimalTransitionSetSelection(std::ostream &stream) { + stream << "-- optimal transition set selection" << std::endl; + VContainer optimalTransitions = VOR; + VContainer spontaneoursActive = VOR; + + for (auto transIter = _transitions.begin(); transIter != _transitions.end(); transIter++) { + DOMElement *transition = *transIter; + std::string conflicts = ATTR(transition, "conflictBools"); + + + VContainer nameMatchers = VOR; + if (HAS_ATTR(transition, "event")) { + std::list eventDescs = tokenize(ATTR(transition, "event")); + for (std::list::iterator descIter = eventDescs.begin(); + descIter != eventDescs.end(); descIter++) { + std::list eventNames = _eventTrie.getWordsWithPrefix( + (*descIter) == "*" ? "" : *descIter); + for (std::list::iterator eventIter = eventNames.begin(); + eventIter != eventNames.end(); eventIter++) { + *nameMatchers += VLINE("event_" + escapeMacro((*eventIter)->value) + "_sig"); } } + } else { + *nameMatchers += VLINE("'1'"); + } - VBranch *tree = (VASSIGN, - VLINE("in_optimal_transition_set_" + ATTR(transition, "postFixOrder") + "_sig"), - (VAND, - (HAS_ATTR(transition, "event") - ? (VNOT, VLINE("spontaneous_active")) - : (VNOP, VLINE("spontaneous_en"))), - - HAS_ATTR(transition, "cond") - ? (VNOP, - VLINE("transition_condition_fulfilled_" + ATTR(transition, "postFixOrder") + - "_i")) - : (VNOP, VLINE("'1'")), - - 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"); + VContainer conflicters = VOR; + for (size_t j = 0; j < strTo(ATTR(transition, "postFixOrder")); j++) { + if (conflicts[j] == '1') { + *conflicters += VLINE("in_optimal_transition_set_" + toStr(j) + "_sig"); } } VBranch *tree = (VASSIGN, - VLINE("optimal_transition_set_combined_sig"), - optimalTransitions); + VLINE("in_optimal_transition_set_" + ATTR(transition, "postFixOrder") + "_sig"), + (VAND, + (HAS_ATTR(transition, "event") + ? (VNOT, VLINE("spontaneous_active")) + : (VNOP, VLINE("spontaneous_en"))), + + HAS_ATTR(transition, "cond") + ? (VNOP, + VLINE("transition_condition_fulfilled_" + ATTR(transition, "postFixOrder") + + "_i")) + : (VNOP, VLINE("'1'")), + + VLINE("state_active_" + ATTR(transition, "source") + "_sig"), + nameMatchers, + (VNOT, conflicters))); + tree->print(stream); stream << ";" << std::endl; - VBranch *tree2 = (VASSIGN, - VLINE("spontaneous_active"), - spontaneoursActive); - tree2->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; +void ChartToVHDL::writeExitSet(std::ostream &stream) { + stream << "-- exit set selection" << std::endl; - for (auto state : _states) { + for (auto state : _states) { - std::string completion = ATTR(state, "completionBools"); - std::string ancestors = ATTR(state, "ancBools"); - std::string children = ATTR(state, "childBools"); - std::string parent = ATTR(state, "parent"); + std::string completion = ATTR(state, "completionBools"); + std::string ancestors = ATTR(state, "ancBools"); + std::string children = ATTR(state, "childBools"); + std::string parent = ATTR(state, "parent"); - VContainer exitsetters = VOR; - for (auto transition : _transitions) { - std::string exitSet = ATTR(transition, "exitSetBools"); - if (exitSet.at(strTo(ATTR(state, "documentOrder"))) == '1') { - *exitsetters += VLINE("in_optimal_transition_set_" + ATTR(transition, "postFixOrder") + "_sig "); - } + VContainer exitsetters = VOR; + for (auto transition : _transitions) { + std::string exitSet = ATTR(transition, "exitSetBools"); + if (exitSet.at(strTo(ATTR(state, "documentOrder"))) == '1') { + *exitsetters += VLINE("in_optimal_transition_set_" + ATTR(transition, "postFixOrder") + "_sig "); } + } - VBranch *tree = (VASSIGN, - VLINE("in_exit_set_" + ATTR(state, "documentOrder") + "_sig"), - (VAND, - VLINE("state_active_" + ATTR(state, "documentOrder") + "_sig"), - exitsetters)); + VBranch *tree = (VASSIGN, + VLINE("in_exit_set_" + ATTR(state, "documentOrder") + "_sig"), + (VAND, + VLINE("state_active_" + ATTR(state, "documentOrder") + "_sig"), + exitsetters)); - tree->print(stream); - stream << ";" << std::endl; - } + tree->print(stream); + stream << ";" << std::endl; } +} - void ChartToVHDL::writeEntrySet(std::ostream &stream) { - stream << "-- entry set selection" << std::endl; +void ChartToVHDL::writeEntrySet(std::ostream &stream) { + stream << "-- entry set selection" << std::endl; - for (auto state : _states) { + 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"))))); + VBranch *tree = (VASSIGN, + VLINE("in_entry_set_" + ATTR(state, "documentOrder") + "_sig"), + (VAND, + VLINE("in_complete_entry_set_" + ATTR(state, "documentOrder") + "_sig"), + (VOR, VLINE("in_exit_set_" + ATTR(state, "documentOrder") + "_sig"), + (VNOT, VLINE("state_active_" + ATTR(state, "documentOrder") + "_sig"))))); - tree->print(stream); - stream << ";" << std::endl; - } + tree->print(stream); + stream << ";" << std::endl; } +} - void ChartToVHDL::writeCompleteEntrySet(std::ostream &stream) { - stream << "-- complete entry set selection" << 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"); + for (auto state : _states) { + std::string completion = ATTR(state, "completionBools"); + std::string ancestors = ATTR(state, "ancBools"); + std::string children = ATTR(state, "childBools"); + std::string parent = ATTR(state, "parent"); - if (parent.size() == 0) { - continue; // skips node - } + if (parent.size() == 0) { + continue; // skips node + } - // EntrySet for every state types - VContainer optimalEntrysetters = VOR; - for (auto transition : _transitions) { - // Is this state in TargetSet of the transition? - std::string targetSet = ATTR(transition, "targetBools"); - if (targetSet[strTo(ATTR(state, "documentOrder"))] == '1') { - //yes? then add the transition to optimal entry set of the state - *optimalEntrysetters += - VLINE("in_optimal_transition_set_" + ATTR(transition, "postFixOrder") + "_sig"); + // EntrySet for every state types + VContainer optimalEntrysetters = VOR; + for (auto transition : _transitions) { + // Is this state in TargetSet of the transition? + std::string targetSet = ATTR(transition, "targetBools"); + if (targetSet[strTo(ATTR(state, "documentOrder"))] == '1') { + //yes? then add the transition to optimal entry set of the state + *optimalEntrysetters += + VLINE("in_optimal_transition_set_" + ATTR(transition, "postFixOrder") + "_sig"); + } + } + + // if composite state (or root) we have to add ancestor completion + VContainer completeEntrysetters = VOR; + if (isCompound(state) || isParallel(state)) { + for (auto tmp_state : _states) { + // is tmp_state is child of state continue? + if (children[strTo(ATTR(state, "documentOrder"))] == '1') { + // yes? then add its complete_entry_set_up as ancestor completion + *completeEntrysetters += + VLINE("in_complete_entry_set_up_" + ATTR(tmp_state, "documentOrder") + "_sig"); } } + } - // if composite state (or root) we have to add ancestor completion - VContainer completeEntrysetters = VOR; - if (isCompound(state) || isParallel(state)) { - for (auto tmp_state : _states) { - // is tmp_state is child of state continue? - if (children[strTo(ATTR(state, "documentOrder"))] == '1') { - // yes? then add its complete_entry_set_up as ancestor completion - *completeEntrysetters += - VLINE("in_complete_entry_set_up_" + ATTR(tmp_state, "documentOrder") + "_sig"); - } - } - } + VBranch *tree = (VASSIGN, + VLINE("in_complete_entry_set_up_" + ATTR(state, "documentOrder") + "_sig"), + (VOR, optimalEntrysetters, completeEntrysetters) + ); + tree->print(stream); + stream << ";" << std::endl; + } - VBranch *tree = (VASSIGN, - VLINE("in_complete_entry_set_up_" + ATTR(state, "documentOrder") + "_sig"), - (VOR, optimalEntrysetters, completeEntrysetters) - ); - tree->print(stream); - stream << ";" << std::endl; - } + // descendant completion + for (auto state : _states) { + std::string completion = ATTR(state, "completionBools"); + std::string ancestors = ATTR(state, "ancBools"); + std::string parent = ATTR(state, "parent"); //is it a int ? - // descendant completion - for (auto state : _states) { - std::string completion = ATTR(state, "completionBools"); - std::string ancestors = ATTR(state, "ancBools"); - std::string parent = ATTR(state, "parent"); //is it a int ? + if (parent.size() == 0) { + continue; // skips node + } - if (parent.size() == 0) { - continue; // skips node - } + VContainer descendantCompletion = VAND; + // if parent is compound + if (getParentState(state) != NULL && + isCompound(getParentState(state))) { + std::string children = ATTR_CAST(_states[strTo(parent)], + "childBools"); - VContainer descendantCompletion = VAND; - // if parent is compound - if (getParentState(state) != NULL && - isCompound(getParentState(state))) { - std::string children = ATTR_CAST(_states[strTo(parent)], - "childBools"); - - std::string parentInit = ATTR(getParentState(state), "initial"); - if (// if parent has init field an this state is inside --> add it as default completion - (!parentInit.empty() - && ATTR(state, "id").compare(parentInit) == 0) || - // or add this state as default completion when parent has no init field and it is the first in document order - (parentInit.empty() && - (strTo(ATTR(getParentState(state), "documentOrder")) + 1) == - strTo(ATTR(state, "documentOrder")))) { - *descendantCompletion += - VLINE("in_entry_set_" + ATTR(getParentState(state), "documentOrder") + "_sig"); - - // but only if compound parent is not already completed - for (auto tmp_state : _states) { - if (tmp_state == state) { - // skip state itselve - continue; - } - if (children[strTo(ATTR(tmp_state, "documentOrder"))] == '1') { - *descendantCompletion += (VNOT, - (VAND, - VLINE("state_active_" + ATTR(tmp_state, "documentOrder") + "_sig"), - (VNOT, - VLINE("in_exit_set_" + ATTR(tmp_state, "documentOrder") + - "_sig")))); - } + std::string parentInit = ATTR(getParentState(state), "initial"); + if (// if parent has init field an this state is inside --> add it as default completion + (!parentInit.empty() + && ATTR(state, "id").compare(parentInit) == 0) || + // or add this state as default completion when parent has no init field and it is the first in document order + (parentInit.empty() && + (strTo(ATTR(getParentState(state), "documentOrder")) + 1) == + strTo(ATTR(state, "documentOrder")))) { + *descendantCompletion += + VLINE("in_entry_set_" + ATTR(getParentState(state), "documentOrder") + "_sig"); + + // but only if compound parent is not already completed + for (auto tmp_state : _states) { + if (tmp_state == state) { + // skip state itselve + continue; + } + if (children[strTo(ATTR(tmp_state, "documentOrder"))] == '1') { + *descendantCompletion += (VNOT, + (VAND, + VLINE("state_active_" + ATTR(tmp_state, "documentOrder") + "_sig"), + (VNOT, + VLINE("in_exit_set_" + ATTR(tmp_state, "documentOrder") + + "_sig")))); } - } else { - // disable this branche - *descendantCompletion += VLINE("'0'"); } - } else - // if parent is parallel + } else { + // disable this branche + *descendantCompletion += VLINE("'0'"); + } + } else + // if parent is parallel if (getParentState(state) != NULL && - isParallel(getParentState(state))) { + isParallel(getParentState(state))) { *descendantCompletion += - VLINE("in_complete_entry_set_" + ATTR(getParentState(state), "documentOrder") + "_sig"); + VLINE("in_complete_entry_set_" + ATTR(getParentState(state), "documentOrder") + "_sig"); } - VBranch *tree = (VASSIGN, - VLINE("in_complete_entry_set_" + ATTR(state, "documentOrder") + "_sig"), - (VOR, - VLINE("in_complete_entry_set_up_" + ATTR(state, "documentOrder") + "_sig"), - descendantCompletion)); + VBranch *tree = (VASSIGN, + VLINE("in_complete_entry_set_" + ATTR(state, "documentOrder") + "_sig"), + (VOR, + VLINE("in_complete_entry_set_up_" + ATTR(state, "documentOrder") + "_sig"), + descendantCompletion)); - tree->print(stream); - stream << ";" << std::endl; - } + tree->print(stream); + stream << ";" << std::endl; } +} - void ChartToVHDL::writeStateHandler(std::ostream &stream) { - // updater for current state - stream << "-- State Handler" << std::endl; - stream << "-- updates current state" << std::endl; - stream << "state_proc: process(clk, rst, stall)" << std::endl; - stream << "begin" << std::endl; - stream << " if rst = '1' then" << std::endl; - - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") << "_sig <= " << "'0';" << std::endl; - } +void ChartToVHDL::writeStateHandler(std::ostream &stream) { + // updater for current state + stream << "-- State Handler" << std::endl; + stream << "-- updates current state" << std::endl; + stream << "state_proc: process(clk, rst, stall)" << std::endl; + stream << "begin" << std::endl; + stream << " if rst = '1' then" << std::endl; - stream << " 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 <= " << "'0';" << std::endl; + } - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") << "_sig <= " << "state_next_" << - ATTR(state, "documentOrder") << "_sig;" << 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; - stream << " end if;" << std::endl; - stream << "end process;" << std::endl; - stream << std::endl; + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") << "_sig <= " << "state_next_" << + ATTR(state, "documentOrder") << "_sig;" << std::endl; } - void ChartToVHDL::writeSystemSignalMapping(std::ostream &stream) { - stream << "-- system signals" << std::endl; - std::list topLevelFinal = DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "final", - _scxml); + stream << " end if;" << std::endl; + stream << "end process;" << std::endl; + stream << std::endl; +} - VContainer tlf = VOR; - for (auto final : topLevelFinal) { - *tlf += VLINE("state_active_" + ATTR(final, "documentOrder") + "_sig"); +void ChartToVHDL::writeSystemSignalMapping(std::ostream &stream) { + stream << "-- system signals" << std::endl; + std::list topLevelFinal = DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "final", + _scxml); - } + VContainer tlf = VOR; + for (auto final : topLevelFinal) { + *tlf += VLINE("state_active_" + ATTR(final, "documentOrder") + "_sig"); - VBranch *tree = (VASSIGN, - VLINE("completed_sig"), - tlf); + } - tree->print(stream); - stream << ";" << std::endl; + VBranch *tree = (VASSIGN, + VLINE("completed_sig"), + tlf); + + tree->print(stream); + stream << ";" << std::endl; - // tmp mapping for events + // tmp mapping for events // stream << "stall_handler : process (clk, rst) " << std::endl; // stream << "begin" << std::endl; // stream << " if rst = '1' then" << std::endl; // stream << " stall <= '0';" << std::endl; // stream << " elsif rising_edge(clk) then" << std::endl; - // empty queue as stall source can arise some issues with state charts just based on spontaneous transitions - stream << " stall <= not en or completed_sig ; --or ( int_event_empty and not spontaneous_en); " << - std::endl; + // empty queue as stall source can arise some issues with state charts just based on spontaneous transitions + stream << " stall <= not en or completed_sig ; --or ( int_event_empty and not spontaneous_en); " << + std::endl; // stream << " end if;" << std::endl; // stream << "end process;" << 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; - } + // interface signals + stream << "-- interface signals" << std::endl; + for (auto state : _states) { + stream << "state_active_" << ATTR(state, "documentOrder") + << "_o <= state_active_" << ATTR(state, "documentOrder") + << "_sig;" << std::endl; + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << "exit_set_" << ATTR(state, "documentOrder") + << "_o <= in_exit_set_" << ATTR(state, "documentOrder") + << "_sig;" << std::endl; } - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << "transition_set_" << ATTR(transition, "postFixOrder") - << "_o <= in_optimal_transition_set_" << ATTR(transition, "postFixOrder") - << "_sig;" << std::endl; - } + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << "entry_set_" << ATTR(state, "documentOrder") + << "_o <= in_entry_set_" << ATTR(state, "documentOrder") + << "_sig;" << std::endl; } + } - stream << "completed_o <= completed_sig; " << std::endl; - stream << "error_o <= reg_error_out; " << std::endl; - stream << std::endl; + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << "transition_set_" << ATTR(transition, "postFixOrder") + << "_o <= in_optimal_transition_set_" << ATTR(transition, "postFixOrder") + << "_sig;" << std::endl; + } } + stream << "completed_o <= completed_sig; " << std::endl; + stream << "error_o <= reg_error_out; " << std::endl; + stream << std::endl; +} + } diff --git a/src/uscxml/transform/ChartToVHDL.h b/src/uscxml/transform/ChartToVHDL.h index 34cda71..03ae681 100644 --- a/src/uscxml/transform/ChartToVHDL.h +++ b/src/uscxml/transform/ChartToVHDL.h @@ -31,129 +31,129 @@ namespace uscxml { - class USCXML_API ChartToVHDL : public ChartToC { - public: +class USCXML_API ChartToVHDL : public ChartToC { +public: - virtual ~ChartToVHDL(); + virtual ~ChartToVHDL(); - static Transformer transform(const Interpreter &other); + static Transformer transform(const Interpreter &other); - void writeTo(std::ostream &stream); + void writeTo(std::ostream &stream); - struct VNode { - virtual void print(std::ostream &stream, const std::string padding = "") = 0; + struct VNode { + virtual void print(std::ostream &stream, const std::string padding = "") = 0; - virtual ~VNode() { }; - }; + virtual ~VNode() { }; + }; - struct VBranch : VNode { - std::vector v; + struct VBranch : VNode { + std::vector v; - virtual ~VBranch() { - for (unsigned i = 0; i < v.size(); i++) - delete v[i]; - } + virtual ~VBranch() { + for (unsigned i = 0; i < v.size(); i++) + delete v[i]; + } - VBranch &operator+=(VNode *p) { - v.push_back(p); - return *this; - } - }; + VBranch &operator+=(VNode *p) { + v.push_back(p); + return *this; + } + }; - struct VPointer { - VNode *ptr; + struct VPointer { + VNode *ptr; - operator VNode *() { - return ptr; - } + operator VNode *() { + return ptr; + } - operator VBranch *() { - return static_cast (ptr); - } + operator VBranch *() { + return static_cast (ptr); + } - VPointer &operator/(VNode *p) { - ptr = p; - return *this; - } - }; + VPointer &operator/(VNode *p) { + ptr = p; + return *this; + } + }; - struct VContainer { - VBranch *ptr; + struct VContainer { + VBranch *ptr; - operator VBranch *() { - return ptr; - } + operator VBranch *() { + return ptr; + } - VContainer &operator/(VBranch *p) { - ptr = p; - return *this; - } + VContainer &operator/(VBranch *p) { + ptr = p; + return *this; + } - VContainer &operator,(VPointer p) { - if (ptr) ptr->v.push_back(p.ptr); - return *this; - } + VContainer &operator,(VPointer p) { + if (ptr) ptr->v.push_back(p.ptr); + return *this; + } - VContainer &operator,(VContainer c) { - if (ptr) ptr->v.push_back(c.ptr); - return *this; - } - }; + VContainer &operator,(VContainer c) { + if (ptr) ptr->v.push_back(c.ptr); + return *this; + } + }; - struct VLine : VNode { - VLine(const std::string &name) : name(name) { } + struct VLine : VNode { + VLine(const std::string &name) : name(name) { } - virtual void print(std::ostream &stream, const std::string padding = "") { - stream << " " << name; - } + virtual void print(std::ostream &stream, const std::string padding = "") { + stream << " " << name; + } - std::string name; - }; + std::string name; + }; - struct VAssign : VBranch { - virtual void print(std::ostream &stream, const std::string padding = "") { - v[0]->print(stream, padding); - stream << padding << " <="; - v[1]->print(stream, padding + " "); - } - }; - - struct VAnd : VBranch { - virtual void print(std::ostream &stream, const std::string padding = "") { - stream << std::endl << padding << "( '1' "; - for (unsigned i = 0; i < v.size(); i++) { - stream << std::endl << padding << " and"; - v[i]->print(stream, padding + " "); - } - stream << padding << ")" << std::endl; - } - }; - - struct VOr : VBranch { - virtual void print(std::ostream &stream, const std::string padding = "") { - stream << std::endl << padding << "( '0' "; - for (unsigned i = 0; i < v.size(); i++) { - stream << std::endl << padding << " or"; - v[i]->print(stream, padding + " "); - } - stream << std::endl << padding << ")" << std::endl; - } - }; + struct VAssign : VBranch { + virtual void print(std::ostream &stream, const std::string padding = "") { + v[0]->print(stream, padding); + stream << padding << " <="; + v[1]->print(stream, padding + " "); + } + }; - struct VNot : VBranch { - virtual void print(std::ostream &stream, const std::string padding = "") { - stream << " ( not"; - v[0]->print(stream, padding + " "); - stream << " )"; + struct VAnd : VBranch { + virtual void print(std::ostream &stream, const std::string padding = "") { + stream << std::endl << padding << "( '1' "; + for (unsigned i = 0; i < v.size(); i++) { + stream << std::endl << padding << " and"; + v[i]->print(stream, padding + " "); } - }; + stream << padding << ")" << std::endl; + } + }; - struct VNop : VBranch { - virtual void print(std::ostream &stream, const std::string padding = "") { - v[0]->print(stream, padding); + struct VOr : VBranch { + virtual void print(std::ostream &stream, const std::string padding = "") { + stream << std::endl << padding << "( '0' "; + for (unsigned i = 0; i < v.size(); i++) { + stream << std::endl << padding << " or"; + v[i]->print(stream, padding + " "); } - }; + stream << std::endl << padding << ")" << std::endl; + } + }; + + struct VNot : VBranch { + virtual void print(std::ostream &stream, const std::string padding = "") { + stream << " ( not"; + v[0]->print(stream, padding + " "); + stream << " )"; + } + }; + + struct VNop : VBranch { + virtual void print(std::ostream &stream, const std::string padding = "") { + v[0]->print(stream, padding); + } + }; //TODO can we create the macros without IDE errors ?! #define VLINE VPointer()/new VLine @@ -164,68 +164,68 @@ namespace uscxml { #define VNOP VContainer()/new VNop - protected: - ChartToVHDL(const Interpreter &other); +protected: + ChartToVHDL(const Interpreter &other); - void findEvents(); + void findEvents(); - void writeIncludes(std::ostream &stream); + void writeIncludes(std::ostream &stream); - // top layer components - void writeFiFo(std::ostream &stream); + // top layer components + void writeFiFo(std::ostream &stream); - void writeEventController(std::ostream &stream); + void writeEventController(std::ostream &stream); - void writeConditionSolver(std::ostream &stream); + void writeConditionSolver(std::ostream &stream); - void writeMicroStepper(std::ostream &stream); + void writeMicroStepper(std::ostream &stream); - void writeTestbench(std::ostream &stream); + void writeTestbench(std::ostream &stream); - void writeTopLevel(std::ostream &stream); + void writeTopLevel(std::ostream &stream); - // system - void writeSignalsAndComponents(std::ostream &stream); + // system + void writeSignalsAndComponents(std::ostream &stream); - void writeSystemSignalMapping(std::ostream &stream); + void writeSystemSignalMapping(std::ostream &stream); - void writeModuleInstantiation(std::ostream &stream); + void writeModuleInstantiation(std::ostream &stream); - // combinatorial logic - void writeOptimalTransitionSetSelection(std::ostream &stream); + // combinatorial logic + void writeOptimalTransitionSetSelection(std::ostream &stream); - void writeExitSet(std::ostream &stream); + void writeExitSet(std::ostream &stream); - void writeEntrySet(std::ostream &stream); + void writeEntrySet(std::ostream &stream); - void writeCompleteEntrySet(std::ostream &stream); + void writeCompleteEntrySet(std::ostream &stream); - void writeActiveStateNplusOne(std::ostream &stream); + void writeActiveStateNplusOne(std::ostream &stream); - // handler - void writeStateHandler(std::ostream &stream); + // handler + void writeStateHandler(std::ostream &stream); - void writeResetHandler(std::ostream &stream); + void writeResetHandler(std::ostream &stream); - void writeSpontaneousHandler(std::ostream &stream); + void writeSpontaneousHandler(std::ostream &stream); - void writeInternalEventHandler(std::ostream &stream); + void writeInternalEventHandler(std::ostream &stream); - void writeErrorHandler(std::ostream &stream); + void writeErrorHandler(std::ostream &stream); - Trie _eventTrie; - std::list _eventNames; - size_t _eventBitSize = 0; - std::map _eventsOnBus; - std::list _execContent; + Trie _eventTrie; + std::list _eventNames; + size_t _eventBitSize = 0; + std::map _eventsOnBus; + std::list _execContent; - private: - std::string getLineForExecContent(const XERCESC_NS::DOMNode *elem); +private: + std::string getLineForExecContent(const XERCESC_NS::DOMNode *elem); - bool isSupportedExecContent(XERCESC_NS::DOMElement *execContentElement); - }; + bool isSupportedExecContent(XERCESC_NS::DOMElement *execContentElement); +}; } diff --git a/src/uscxml/util/String.cpp b/src/uscxml/util/String.cpp index 7334d73..f55b36b 100644 --- a/src/uscxml/util/String.cpp +++ b/src/uscxml/util/String.cpp @@ -91,7 +91,7 @@ std::list tokenize(const std::string &line, const char sep, bool tr } start = i; } - if (i + 1 == line.size()) { + if (i + 1 == line.size()) { tokens.push_back(line.substr(start, i + 1 - start)); } } diff --git a/src/uscxml/util/URL.cpp b/src/uscxml/util/URL.cpp index 9329e7e..b9d7bc3 100644 --- a/src/uscxml/util/URL.cpp +++ b/src/uscxml/util/URL.cpp @@ -44,7 +44,7 @@ namespace uscxml { - void URLImpl::prepareException(ErrorEvent& exception, int errorCode, const std::string& origUri, void* parser) { +void URLImpl::prepareException(ErrorEvent& exception, int errorCode, const std::string& origUri, void* parser) { exception.data.compound["uri"].atom = origUri; if (parser != NULL && ((UriParserStateA*)parser)->errorPos != NULL) { @@ -88,12 +88,12 @@ namespace uscxml { } URLImpl::URLImpl() : _handle(NULL), _requestType(GET), _isDownloaded(false), _hasFailed(false) { - _uri = malloc(sizeof(UriUriA)); + _uri = malloc(sizeof(UriUriA)); } URLImpl::URLImpl(const std::string& url) : _orig(url), _handle(NULL), _requestType(GET), _isDownloaded(false), _hasFailed(false) { UriParserStateA state; - _uri = malloc(sizeof(UriUriA)); + _uri = malloc(sizeof(UriUriA)); state.uri = (UriUriA*)_uri; int err = uriParseUriA(&state, _orig.c_str()); @@ -130,14 +130,14 @@ URLImpl::~URLImpl() { uriFreeUriMembersA((UriUriA*)_uri); if (_handle != NULL) curl_easy_cleanup(_handle); - free(_uri); + free(_uri); } URL URLImpl::resolve(URLImpl* relative, URLImpl* absolute) { std::shared_ptr dest(new URLImpl()); int err = uriAddBaseUriExA(((UriUriA*)dest->_uri), - ((UriUriA*)relative->_uri), - ((UriUriA*)absolute->_uri), URI_RESOLVE_IDENTICAL_SCHEME_COMPAT); + ((UriUriA*)relative->_uri), + ((UriUriA*)absolute->_uri), URI_RESOLVE_IDENTICAL_SCHEME_COMPAT); if (err != URI_SUCCESS) { ErrorEvent exc("Cannot resolve " + (std::string)(*relative) + " with " + (std::string)(*absolute)); prepareException(exc, err, "", NULL); @@ -168,8 +168,8 @@ URL URLImpl::resolveWithCWD(URLImpl* relative) { URL URLImpl::refer(URLImpl* absoluteSource, URLImpl* absoluteBase) { std::shared_ptr dest(new URLImpl()); int err = uriRemoveBaseUriA(((UriUriA*)dest->_uri), - ((UriUriA*)absoluteSource->_uri), - ((UriUriA*)absoluteBase->_uri), URI_FALSE); + ((UriUriA*)absoluteSource->_uri), + ((UriUriA*)absoluteBase->_uri), URI_FALSE); if (err != URI_SUCCESS) { ErrorEvent exc("Cannot make a relative reference for " + (std::string)(*absoluteSource) + " with " + (std::string)(*absoluteBase)); prepareException(exc, err, "", NULL); @@ -190,28 +190,28 @@ void URLImpl::normalize() { } bool URLImpl::isAbsolute() const { - // see https://sourceforge.net/p/uriparser/bugs/3/ - return ((UriUriA*)_uri)->absolutePath || ((((UriUriA*)_uri)->hostText.first != nullptr) && (((UriUriA*)_uri)->pathHead != nullptr)); + // see https://sourceforge.net/p/uriparser/bugs/3/ + return ((UriUriA*)_uri)->absolutePath || ((((UriUriA*)_uri)->hostText.first != nullptr) && (((UriUriA*)_uri)->pathHead != nullptr)); } std::string URLImpl::scheme() const { - return USCXML_URI_STRING((*(UriUriA*)_uri), scheme); + return USCXML_URI_STRING((*(UriUriA*)_uri), scheme); } std::string URLImpl::userInfo() const { - return USCXML_URI_STRING((*(UriUriA*)_uri), userInfo); + return USCXML_URI_STRING((*(UriUriA*)_uri), userInfo); } std::string URLImpl::host() const { - return USCXML_URI_STRING((*(UriUriA*)_uri), hostText); + return USCXML_URI_STRING((*(UriUriA*)_uri), hostText); } std::string URLImpl::port() const { - return USCXML_URI_STRING((*(UriUriA*)_uri), portText); + return USCXML_URI_STRING((*(UriUriA*)_uri), portText); } std::string URLImpl::fragment() const { - return USCXML_URI_STRING((*(UriUriA*)_uri), fragment); + return USCXML_URI_STRING((*(UriUriA*)_uri), fragment); } std::string URLImpl::path() const { @@ -380,47 +380,47 @@ void URLImpl::downloadFailed(int errorCode) { } } - + void URLImpl::addOutHeader(const std::string& key, const std::string& value) { - _outHeader[key] = value; + _outHeader[key] = value; } void URLImpl::setOutContent(const std::string& content) { - _outContent = content; - _requestType = URLRequestType::POST; + _outContent = content; + _requestType = URLRequestType::POST; } void URLImpl::setRequestType(URLRequestType requestType) { - _requestType = requestType; - + _requestType = requestType; + } const std::map URLImpl::getInHeaderFields() { - DOWNLOAD_IF_NECESSARY - return _inHeaders; + DOWNLOAD_IF_NECESSARY + return _inHeaders; } const std::string URLImpl::getInHeaderField(const std::string& key) { - DOWNLOAD_IF_NECESSARY - if (_inHeaders.find(key) != _inHeaders.end()) { - return _inHeaders[key]; - } - return ""; + DOWNLOAD_IF_NECESSARY + if (_inHeaders.find(key) != _inHeaders.end()) { + return _inHeaders[key]; + } + return ""; } const std::string URLImpl::getStatusCode() const { - // DOWNLOAD_IF_NECESSARY - return _statusCode; + // DOWNLOAD_IF_NECESSARY + return _statusCode; } const std::string URLImpl::getStatusMessage() const { - // DOWNLOAD_IF_NECESSARY - return _statusMsg; + // DOWNLOAD_IF_NECESSARY + return _statusMsg; } const std::string URLImpl::getInContent(bool forceReload) { - if (forceReload) - _isDownloaded = false; - DOWNLOAD_IF_NECESSARY - return _rawInContent.str(); + if (forceReload) + _isDownloaded = false; + DOWNLOAD_IF_NECESSARY + return _rawInContent.str(); } const void URLImpl::download(bool blocking) { diff --git a/src/uscxml/util/URL.h b/src/uscxml/util/URL.h index a603c63..b3f486a 100644 --- a/src/uscxml/util/URL.h +++ b/src/uscxml/util/URL.h @@ -54,12 +54,12 @@ public: URLImpl(const std::string& url); ~URLImpl(); - bool isAbsolute() const; - std::string scheme() const; - std::string userInfo() const; - std::string host() const; - std::string port() const; - std::string fragment() const; + bool isAbsolute() const; + std::string scheme() const; + std::string userInfo() const; + std::string host() const; + std::string port() const; + std::string fragment() const; std::map query() const; std::string path() const; std::list pathComponents() const; @@ -78,15 +78,15 @@ public: } // downloading / uploading - void addOutHeader(const std::string& key, const std::string& value); - void setOutContent(const std::string& content); - void setRequestType(URLRequestType requestType); - const std::map getInHeaderFields(); - const std::string getInHeaderField(const std::string& key); - - const std::string getStatusCode() const; - const std::string getStatusMessage() const; - const std::string getInContent(bool forceReload = false); + void addOutHeader(const std::string& key, const std::string& value); + void setOutContent(const std::string& content); + void setRequestType(URLRequestType requestType); + const std::map getInHeaderFields(); + const std::string getInHeaderField(const std::string& key); + + const std::string getStatusCode() const; + const std::string getStatusMessage() const; + const std::string getInContent(bool forceReload = false); const void download(bool blocking = false); operator Data() const; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a6f9265..c2fe40c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -41,6 +41,7 @@ function(USCXML_TEST_COMPILE) endfunction() # simple one file tests +USCXML_TEST_COMPILE(NAME test-extensions LABEL general/test-extensions FILES src/test-extensions.cpp) USCXML_TEST_COMPILE(NAME test-url LABEL general/test-url FILES src/test-url.cpp) USCXML_TEST_COMPILE(NAME test-lifecycle LABEL general/test-lifecycle FILES src/test-lifecycle.cpp) USCXML_TEST_COMPILE(NAME test-validating LABEL general/test-validating FILES src/test-validating.cpp) diff --git a/test/src/test-extensions.cpp b/test/src/test-extensions.cpp new file mode 100644 index 0000000..ca189ef --- /dev/null +++ b/test/src/test-extensions.cpp @@ -0,0 +1,168 @@ +#include "uscxml/Interpreter.h" +#include "uscxml/interpreter/InterpreterMonitor.h" +#include "uscxml/interpreter/InterpreterImpl.h" +#include "uscxml/interpreter/BasicEventQueue.h" +#include "uscxml/interpreter/BasicDelayedEventQueue.h" + +#include +#include + +using namespace uscxml; + +// from issue 96: +// https://github.com/tklab-tud/uscxml/issues/96 + +static const char *customDelayedEQ = + "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + ""; + +class PausableDelayedEventQueue; +std::shared_ptr nestedDelayQueue; + +/** + * A DelayedEventQueue that implements pause/resume + */ +class PausableDelayedEventQueue : public BasicDelayedEventQueue { +public: + PausableDelayedEventQueue(DelayedEventQueueCallbacks* callbacks) : BasicDelayedEventQueue(callbacks) {} + + std::shared_ptr create(DelayedEventQueueCallbacks* callbacks) { + // remember as nestedDelayQueue in global scope + nestedDelayQueue = std::shared_ptr(new PausableDelayedEventQueue(callbacks)); + return nestedDelayQueue; + } + + void pause() { + if(_pausedAt.tv_sec != 0 || _pausedAt.tv_usec != 0) { + return; // we are already paused! + } + + gettimeofday(&_pausedAt, NULL); // remember when we paused + + { + // Verbatim copy of stop() without cancelAllDelayed() + if (_isStarted) { + _isStarted = false; + event_base_loopbreak(_eventLoop); + } + if (_thread) { + _thread->join(); + delete _thread; + _thread = NULL; + } + } + + std::lock_guard lock(_mutex); + + // remove all events from libevent without deleting them + for(auto callbackData : _callbackData) { + Event data = callbackData.second.userData; + event_del(callbackData.second.event); + } + } + + void resume() { + if (_pausedAt.tv_sec != 0 || _pausedAt.tv_usec != 0) { + struct timeval now; + struct timeval pausedFor; + + gettimeofday(&now, NULL); + timersub(&now, &_pausedAt, &pausedFor); + _pausedAt = {0,0}; + + for(auto& callbackData : _callbackData) { + // add the time we were paused to all due times + timeradd(&callbackData.second.due, &pausedFor, &callbackData.second.due); + + struct timeval remain; + timersub(&callbackData.second.due, &now, &remain); + +#if 0 + std::cout << "Now : " << now.tv_sec << "." << now.tv_usec << std::endl; + std::cout << "Paused : " << pausedFor.tv_sec << "." << pausedFor.tv_usec << std::endl; + std::cout << "Remaining: " << remain.tv_sec << "." << remain.tv_usec << std::endl; +#endif + assert(remain.tv_usec >= 0 && remain.tv_sec >= 0); + + // reenqueue with libevent + event_add(callbackData.second.event, &remain); + } + } + start(); + } + +protected: + timeval _pausedAt = {0,0}; +}; + +bool testPausableEventQueue() { + Interpreter interpreter = Interpreter::fromXML(customDelayedEQ, ""); + + PausableDelayedEventQueue* queue = new PausableDelayedEventQueue(interpreter.getImpl().get()); + ActionLanguage lang; + lang.delayedQueue = DelayedEventQueue(std::shared_ptr(queue)); + + interpreter.setActionLanguage(lang); + + StateTransitionMonitor mon; + mon.copyToInvokers(true); + interpreter.addMonitor(&mon); + + size_t iterations = 10; + + InterpreterState state = InterpreterState::USCXML_UNDEF; + while (state != USCXML_FINISHED) { + state = interpreter.step(); + if (nestedDelayQueue) { + /* + * As soon as we have the nested event queue instantiated, we pause and resume it + * We pause for 500ms, and run for 500ms. This will effectively double the time required + * for delayed events. + * This would usually done in another thread .. + */ + std::cout << "<- pausing" << std::endl; + nestedDelayQueue->pause(); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + std::cout << "-> continuing" << std::endl; + nestedDelayQueue->resume(); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + if (iterations-- == 0) + return true; + } + } + + return true; + +} + +int main(int argc, char** argv) { + testPausableEventQueue(); +} diff --git a/test/src/test-snippets.cpp b/test/src/test-snippets.cpp index 4b0fafe..968d65d 100644 --- a/test/src/test-snippets.cpp +++ b/test/src/test-snippets.cpp @@ -32,6 +32,6 @@ void microstep_snippet() { } int main(int argc, char** argv) { - Logger::getDefault().log(USCXML_FATAL) << "Foo!" << " BAR?"; + Logger::getDefault().log(USCXML_FATAL) << "Foo!" << " BAR?"; microstep_snippet(); } -- cgit v0.12