summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Radomski <sradomski@mintwerk.de>2016-04-22 10:21:27 (GMT)
committerStefan Radomski <sradomski@mintwerk.de>2016-04-22 10:21:27 (GMT)
commitb3e5a85374523c614d09ceeebe7565a0a6ab6838 (patch)
tree1193f9d84ba4c4bd8697c06f5c7821c41212af06
parentc761e5f3931e4709f2736d5c3c0e11dc7b61ded5 (diff)
parentd4818c30f7f17427ee4f58e93a32f94f4ee45395 (diff)
downloaduscxml-b3e5a85374523c614d09ceeebe7565a0a6ab6838.zip
uscxml-b3e5a85374523c614d09ceeebe7565a0a6ab6838.tar.gz
uscxml-b3e5a85374523c614d09ceeebe7565a0a6ab6838.tar.bz2
Merge branch 'master' of github.com:tklab-tud/uscxml
-rw-r--r--src/uscxml/Interpreter.h43
-rw-r--r--src/uscxml/plugins/invoker/im/IMInvoker.cpp3
-rw-r--r--src/uscxml/transform/ChartToVHDL.cpp457
-rw-r--r--test/vhdltest/debug.do12
-rwxr-xr-xtest/vhdltest/green_write_dut.sh66
-rwxr-xr-xtest/vhdltest/tmp_write_dut.sh66
6 files changed, 563 insertions, 84 deletions
diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h
index c65c8f7..303e126 100644
--- a/src/uscxml/Interpreter.h
+++ b/src/uscxml/Interpreter.h
@@ -46,6 +46,8 @@
#include "uscxml/plugins/Invoker.h"
#include "uscxml/plugins/ExecutableContent.h"
+#include "dom/DOMUtils.h"
+
#ifndef TIME_BLOCK
# ifdef BUILD_PROFILING
# include "uscxml/concurrency/Timer.h"
@@ -402,6 +404,38 @@ public:
virtual void handleDOMEvent(Arabica::DOM::Events::Event<std::string>& event);
+ std::vector<std::string> getReachableTargets() {
+
+ std::vector<std::string> e;
+ tthread::lock_guard<tthread::recursive_mutex> lock(_mutex);
+ Arabica::XPath::NodeSet<std::string> possibleTransitions = DOMUtils::filterChildElements( "transition", _configuration, false);
+
+ for( size_t i = 0; i < possibleTransitions.size(); i++ ) {
+ Arabica::DOM::Node<std::string> transitions = possibleTransitions[ i ];
+ Arabica::DOM::NamedNodeMap<std::string> attributes = transitions.getAttributes();
+ Arabica::DOM::Node<std::string> events = attributes.getNamedItem("target");
+ e.push_back( std::string( events.getNodeValue() ) );
+ }
+ return e;
+
+ }
+
+ std::vector<std::string> getEventDescriptors() {
+
+ std::vector<std::string> e;
+ tthread::lock_guard<tthread::recursive_mutex> lock(_mutex);
+ Arabica::XPath::NodeSet<std::string> possibleTransitions = DOMUtils::filterChildElements( "transition", _configuration, false);
+
+ for( size_t i = 0; i < possibleTransitions.size(); i++ ) {
+ Arabica::DOM::Node<std::string> transitions = possibleTransitions[ i ];
+ Arabica::DOM::NamedNodeMap<std::string> attributes = transitions.getAttributes();
+ Arabica::DOM::Node<std::string> events = attributes.getNamedItem("event");
+ e.push_back( std::string( events.getNodeValue() ) );
+ }
+ return e;
+
+ }
+
protected:
static void run(void*); // static method for thread to run
@@ -589,6 +623,14 @@ public:
return _impl->reset();
}
+ std::vector<std::string> getReachableTargets() {
+ return _impl->getReachableTargets();
+ }
+
+ std::vector<std::string> getEventDescriptors() {
+ return _impl->getEventDescriptors();
+ }
+
void start() {
return _impl->start();
}
@@ -807,6 +849,7 @@ public:
Timer timer;
#endif
+
protected:
void setInvokeRequest(const InvokeRequest& req) {
diff --git a/src/uscxml/plugins/invoker/im/IMInvoker.cpp b/src/uscxml/plugins/invoker/im/IMInvoker.cpp
index 91a22e1..f111743 100644
--- a/src/uscxml/plugins/invoker/im/IMInvoker.cpp
+++ b/src/uscxml/plugins/invoker/im/IMInvoker.cpp
@@ -21,6 +21,7 @@
#include <glog/logging.h>
#include "uscxml/UUID.h"
#include "uscxml/dom/DOMUtils.h"
+#include "uscxml/dom/NameSpacingParser.h"
#include <boost/algorithm/string.hpp>
#include "uscxml/concurrency/DelayedEventQueue.h"
@@ -1405,4 +1406,4 @@ gboolean IMInvoker::purpleDebugIsEnabled(PurpleDebugLevel level, const char *cat
}
-} \ No newline at end of file
+}
diff --git a/src/uscxml/transform/ChartToVHDL.cpp b/src/uscxml/transform/ChartToVHDL.cpp
index 1573bc7..1bdcafe 100644
--- a/src/uscxml/transform/ChartToVHDL.cpp
+++ b/src/uscxml/transform/ChartToVHDL.cpp
@@ -128,7 +128,7 @@ namespace uscxml {
// elements.insert(_nsInfo.xmlNSPrefix + "else");
// elements.insert(_nsInfo.xmlNSPrefix + "foreach");
// elements.insert(_nsInfo.xmlNSPrefix + "log");
- // elements.insert(_nsInfo.xmlNSPrefix + "send");
+ elements.insert(_nsInfo.xmlNSPrefix + "send");
// elements.insert(_nsInfo.xmlNSPrefix + "assign");
// elements.insert(_nsInfo.xmlNSPrefix + "script");
// elements.insert(_nsInfo.xmlNSPrefix + "cancel");
@@ -170,7 +170,7 @@ namespace uscxml {
stream << " downto 0);" << std::endl;
std::list<TrieNode*> eventNames = _eventTrie.getWordsWithPrefix("");
- stream << " type event_type is ( ";
+ stream << " type event_type is ( hwe_null, ";
seperator = "";
for (std::list<TrieNode*>::iterator eventIter = eventNames.begin(); eventIter != eventNames.end(); eventIter++) {
@@ -206,6 +206,7 @@ namespace uscxml {
stream << "architecture bhv of tb is" << std::endl;
stream << std::endl;
+ // modules
stream << " -- Module declaration" << std::endl;
stream << " component micro_stepper is" << std::endl;
stream << " port (" << std::endl;
@@ -221,6 +222,22 @@ namespace uscxml {
for (size_t i = 0; i < _states.size(); i++) {
Element<std::string> state(_states[i]);
stream << " state_active_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl;
+
+ if (DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "onentry", state).size() > 0) {
+ stream << " entry_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl;
+ }
+
+ if (DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "onexit", state).size() > 0) {
+ stream << " exit_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl;
+ }
+ }
+
+ for (size_t i = 0; i < _transitions.size(); i++) {
+ Element<std::string> transition(_transitions[i]);
+ if (DOMUtils::filterChildType(Arabica::DOM::Node_base::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;
@@ -228,10 +245,49 @@ namespace uscxml {
stream << " end component;" << std::endl;
stream << std::endl;
+ stream << " component event_controller is" << std::endl;
+ stream << " port(" << std::endl;
+ stream << " --inputs" << std::endl;
+ stream << " clk :in std_logic;" << std::endl;
+ stream << " rst_i :in std_logic;" << std::endl;
+
+ for (size_t i = 0; i < _states.size(); i++) {
+ Element<std::string> state(_states[i]);
+ stream << " state_active_" << ATTR(state, "documentOrder")
+ << "_i :in std_logic;" << std::endl;
+
+ if (DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "onentry", state).size() > 0) {
+ stream << " entry_set_" << ATTR(state, "documentOrder")
+ << "_i :in std_logic;" << std::endl;
+ }
+
+ if (DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "onexit", state).size() > 0) {
+ stream << " exit_set_" << ATTR(state, "documentOrder")
+ << "_i :in std_logic;" << std::endl;
+ }
+ }
+
+ for (size_t i = 0; i < _transitions.size(); i++) {
+ Element<std::string> transition(_transitions[i]);
+ if (DOMUtils::filterChildType(Arabica::DOM::Node_base::ELEMENT_NODE, transition).size() > 0) {
+ stream << " transition_set_" << ATTR(transition, "postFixOrder")
+ << "_i :in std_logic;" << std::endl;
+ }
+ }
+ stream << " --outputs" << std::endl;
+ stream << " micro_stepper_en_o :out std_logic;" << std::endl;
+ stream << " event_o :out event_type;" << std::endl;
+ stream << " event_we_o :out std_logic" << std::endl;
+ // stream << " done_o :out std_logic" << std::endl;
+ stream << ");" << std::endl;
+ stream << "end component; " << std::endl;
+
+ // signals
stream << " -- input" << std::endl;
stream << " signal clk : std_logic := '0';" << std::endl;
stream << " signal reset : std_logic;" << std::endl;
- stream << " signal next_event_we_i : std_logic := '0';" << std::endl;
+ stream << " signal dut_enable : std_logic;" << std::endl;
+ stream << " signal next_event_we_i : std_logic;" << std::endl;
stream << " signal next_event_i : event_type;" << std::endl;
stream << std::endl;
@@ -239,6 +295,32 @@ namespace uscxml {
stream << " signal error_o, completed_o : std_logic;" << std::endl;
stream << std::endl;
+ stream << " -- wiring" << std::endl;
+ for (size_t i = 0; i < _states.size(); i++) {
+ Element<std::string> state(_states[i]);
+ stream << " signal state_active_" << ATTR(state, "documentOrder")
+ << "_sig : std_logic;" << std::endl;
+
+ if (DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "onentry", state).size() > 0) {
+ stream << " signal entry_set_" << ATTR(state, "documentOrder")
+ << "_sig : std_logic;" << std::endl;
+ }
+
+ if (DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "onexit", state).size() > 0) {
+ stream << " signal exit_set_" << ATTR(state, "documentOrder")
+ << "_sig : std_logic;" << std::endl;
+ }
+ }
+
+ for (size_t i = 0; i < _transitions.size(); i++) {
+ Element<std::string> transition(_transitions[i]);
+ if (DOMUtils::filterChildType(Arabica::DOM::Node_base::ELEMENT_NODE, transition).size() > 0) {
+ stream << " signal transition_set_" << ATTR(transition, "postFixOrder")
+ << "_sig : std_logic;" << std::endl;
+ }
+ }
+
+ // wiring
stream << "begin" << std::endl;
stream << " clk <= not clk after 20 ns; -- 25 MHz clock frequency" << std::endl;
stream << " reset <= '1', '0' after 100 ns; -- generates reset signal: --__" << std::endl;
@@ -249,7 +331,7 @@ namespace uscxml {
stream << " port map (" << std::endl;
stream << " clk => clk," << std::endl;
stream << " rst_i => reset," << std::endl;
- stream << " en => '1'," << std::endl;
+ stream << " en => dut_enable," << std::endl;
stream << std::endl;
stream << " next_event_i => next_event_i," << std::endl;
@@ -258,13 +340,78 @@ namespace uscxml {
for (size_t i = 0; i < _states.size(); i++) {
Element<std::string> state(_states[i]);
- stream << " state_active_" << ATTR(state, "documentOrder") << "_o => open," << std::endl;
+ stream << " state_active_" << ATTR(state, "documentOrder")
+ << "_o => state_active_" << ATTR(state, "documentOrder")
+ << "_sig," << std::endl;
+
+ if (DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "onentry", state).size() > 0) {
+ stream << " entry_set_" << ATTR(state, "documentOrder")
+ << "_o => entry_set_" << ATTR(state, "documentOrder")
+ << "_sig," << std::endl;
+ }
+
+ if (DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "onexit", state).size() > 0) {
+ stream << " exit_set_" << ATTR(state, "documentOrder")
+ << "_o => exit_set_" << ATTR(state, "documentOrder")
+ << "_sig," << std::endl;
+ }
+ }
+
+ for (size_t i = 0; i < _transitions.size(); i++) {
+ Element<std::string> transition(_transitions[i]);
+ if (DOMUtils::filterChildType(Arabica::DOM::Node_base::ELEMENT_NODE, transition).size() > 0) {
+ stream << " transition_set_" << ATTR(transition, "postFixOrder")
+ << "_o => transition_set_" << ATTR(transition, "postFixOrder")
+ << "_sig," << std::endl;
+ }
}
stream << " completed_o => completed_o" << std::endl;
stream << " );" << std::endl;
stream << std::endl;
+ stream << " ec : event_controller" << std::endl;
+ stream << " port map (" << std::endl;
+ stream << " clk => clk," << std::endl;
+ stream << " rst_i => reset," << std::endl;
+ stream << std::endl;
+
+ stream << " event_o => next_event_i," << std::endl;
+ stream << " event_we_o => next_event_we_i," << std::endl;
+
+ for (size_t i = 0; i < _states.size(); i++) {
+ Element<std::string> state(_states[i]);
+ stream << " state_active_" << ATTR(state, "documentOrder")
+ << "_i => state_active_" << ATTR(state, "documentOrder")
+ << "_sig," << std::endl;
+
+ if (DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "onentry", state).size() > 0) {
+ stream << " entry_set_" << ATTR(state, "documentOrder")
+ << "_i => entry_set_" << ATTR(state, "documentOrder")
+ << "_sig," << std::endl;
+ }
+
+ if (DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "onexit", state).size() > 0) {
+ stream << " exit_set_" << ATTR(state, "documentOrder")
+ << "_i => exit_set_" << ATTR(state, "documentOrder")
+ << "_sig," << std::endl;
+ }
+ }
+
+ for (size_t i = 0; i < _transitions.size(); i++) {
+ Element<std::string> transition(_transitions[i]);
+ if (DOMUtils::filterChildType(Arabica::DOM::Node_base::ELEMENT_NODE, transition).size() > 0) {
+ stream << " transition_set_" << ATTR(transition, "postFixOrder")
+ << "_i => transition_set_" << ATTR(transition, "postFixOrder")
+ << "_sig," << std::endl;
+ }
+ }
+
+ stream << " micro_stepper_en_o => dut_enable" << std::endl;
+ // stream << " done_o => open" << std::endl;
+ stream << " );" << std::endl;
+ stream << std::endl;
+
stream << "end architecture;" << std::endl;
stream << "-- END TESTBENCH" << std::endl;
@@ -287,7 +434,6 @@ namespace uscxml {
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;
for (size_t i = 0; i < _states.size(); i++) {
Element<std::string> state(_states[i]);
@@ -314,9 +460,9 @@ namespace uscxml {
}
stream << " --outputs" << std::endl;
+ stream << " micro_stepper_en_o :out std_logic;" << std::endl;
stream << " event_o :out event_type;" << std::endl;
- stream << " event_we_o :out std_logic;" << std::endl;
- stream << " done_o :out std_logic" << std::endl;
+ stream << " event_we_o :out std_logic" << std::endl;
stream << ");" << std::endl;
stream << "end event_controller; " << std::endl;
@@ -326,9 +472,11 @@ namespace uscxml {
// Add signals and components
stream << "signal rst : std_logic;" << std::endl;
+ stream << "signal micro_stepper_en : std_logic;" << std::endl;
+ stream << "signal cmpl_buf : std_logic;" << std::endl;
+ stream << "signal completed_sig : std_logic;" << std::endl;
stream << "signal event_bus : event_type;" << std::endl;
stream << "signal event_we : std_logic;" << std::endl;
- stream << "signal done : std_logic;" << std::endl;
for (int i = 0; i < _execContent.size(); i++) {
stream << "signal done_" << toStr(i) << "_sig : std_logic;" << std::endl;
@@ -337,74 +485,136 @@ namespace uscxml {
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 << "signal seq_" << toStr(i) << "_sig : std_logic;" << std::endl;
}
stream << std::endl;
stream << "begin" << std::endl;
stream << std::endl;
- // signal mapping
+ // 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 << "done_o <= done;" << std::endl;
stream << std::endl;
+ // stall management
+ stream << "-- stalling microstepper" << std::endl;
+ // stream << "ms_enable_manager : process (clk, rst) " << std::endl;
+ // stream << "begin" << std::endl;
+ // stream << " if rst = '1' then" << std::endl;
+ // stream << " micro_stepper_en <= '1';" << std::endl;
+ // stream << " elsif rising_edge(clk) then" << std::endl;
+ // stream << " " << std::endl;
+ stream << "micro_stepper_en <= completed_sig or not ( '0' ";
+ for (size_t i = 0; i < _states.size(); i++) {
+ Element<std::string> state(_states[i]);
+
+ if (DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "onentry", state).size() > 0) {
+ stream << std::endl << " or entry_set_" << ATTR(state, "documentOrder")
+ << "_i";
+ }
+
+ if (DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "onexit", state).size() > 0) {
+ stream << std::endl << " or exit_set_" << ATTR(state, "documentOrder")
+ << "_i";
+ }
+ }
+ for (size_t i = 0; i < _transitions.size(); i++) {
+ Element<std::string> transition(_transitions[i]);
+ if (DOMUtils::filterChildType(Arabica::DOM::Node_base::ELEMENT_NODE, transition).size() > 0) {
+ stream << std::endl << " or transition_set_" << ATTR(transition, "postFixOrder")
+ << "_i";
+ }
+ }
+ stream << ");" << std::endl;
+ // stream << " end if;" << std::endl;
+ // stream << "end process;" << std::endl;
+ stream << std::endl;
+
+ // write enable management
+ // stream << "-- write enable for FIFO buffer" << std::endl;
+ // stream << "event_we <= not rst and ('0'";
+ // for (int i = 0; i < _execContent.size(); i++) {
+ // stream << std::endl << " or start_" << toStr(i) << "_sig";
+ // }
+ // stream << ");" << std::endl;
+ // stream << std::endl;
+
// sequential code operation
- stream << "ex_content_block : process (clk) " << std::endl;
+ stream << "-- seq code block " << std::endl;
+ stream << "ex_content_block : process (clk, rst) " << std::endl;
stream << "begin" << std::endl;
stream << " if rst = '1' then" << std::endl;
for (int i = 0; i < _execContent.size(); i++) {
stream << " done_" << toStr(i) << "_sig <= '0';" << std::endl;
}
+ stream << " event_bus <= hwe_null;" << std::endl;
+ stream << " event_we <= '0';" << std::endl;
+ stream << " cmpl_buf <= '0';" << std::endl;
+ stream << " completed_sig <= '0';" << std::endl;
stream << " elsif rising_edge(clk) then" << std::endl;
+
+ stream << " if micro_stepper_en = '1' then" << std::endl;
+ stream << " cmpl_buf <= '0' ;" << std::endl;
+ stream << " else" << std::endl;
+ stream << " cmpl_buf <= seq_" << toStr(_execContent.size() - 1)
+ << "_sig;" << std::endl;
+ stream << " end if;" << std::endl;
+ stream << " completed_sig <= cmpl_buf;" << std::endl << std::endl;
std::string seperator = " ";
for (int i = 0; i < _execContent.size(); i++) {
Element<std::string> exContentElem(_execContent[i]);
- if (TAGNAME(_nsInfo.xmlNSPrefix + exContentElem) == "") {
- stream << seperator << "if start_" << toStr(i) << "_sig = '1' "
- << "and done_" << toStr(i) << "_sig = '0' then"
+ //TODO if raise
+ if (TAGNAME(_nsInfo.xmlNSPrefix + exContentElem) == "raise" ||
+ TAGNAME(_nsInfo.xmlNSPrefix + exContentElem) == "send") {
+ stream << seperator << "if start_" << toStr(i) << "_sig = '1' then"
<< std::endl;
- stream << " event_bus <= hwe_" << ATTR(exContentElem, "event")
+ //TODO use escape
+ stream << " event_bus <= hwe_" << ATTR(exContentElem, "event")
<< ";" << std::endl;
- stream << " done_" << toStr(i) << "_sig <= '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;
+ for (int i = 0; i < _execContent.size(); i++) {
+ Element<std::string> exContentElem(_execContent[i]);
+
+ //TODO if raise
+ if (TAGNAME(_nsInfo.xmlNSPrefix + exContentElem) == "raise") {
+ 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;
-
- // start signal generation
- if (_execContent.size() > 0) {
- stream << "start_0_sig <= "
- << /* TODO find enable line and put here */ "'1'"
- << ";" << std::endl;
- }
-
for (size_t i = 0; i < _execContent.size(); i++) {
// start lines
stream << "start_" << toStr(i) << "_sig <= "
<< getLineForExecContent(_execContent[i]) << " and "
- << "(not done_" << toStr(i) << "_sig )";
+ << "not done_" << toStr(i) << "_sig";
if (i != 0) { // if not first element
stream << " and seq_" << toStr(i) << "_sig";
}
stream << ";" << std::endl;
-
+
}
-
+
+ stream << "seq_0_sig <= '1';" << std::endl;
for (size_t i = 1; i < _execContent.size(); i++) {
- // seq lines
- stream << "seq_" << toStr(i) << "_sig <= "
- << "done_"<< toStr(i) << "_sig or "
+ // seq lines (input if process i is in seqence now)
+ stream << "seq_" << toStr(i) << "_sig <= "
+ << "done_" << toStr(i - 1) << "_sig or "
<< "( not "
- << getLineForExecContent(_execContent[i]) << " and "
- << "seq_" << toStr(i-1) << "_sig )";
- stream << ";" << std::endl;
+ << getLineForExecContent(_execContent[i - 1]);
+ stream << " and seq_" << toStr(i - 1) << "_sig";
+ stream << " );" << std::endl;
}
stream << std::endl;
@@ -414,13 +624,13 @@ namespace uscxml {
std::string ChartToVHDL::getLineForExecContent(const Arabica::DOM::Node<std::string>& elem) {
Arabica::DOM::Node<std::string> ecBlock = elem;
- while(ecBlock) {
+ while (ecBlock) {
if (ecBlock.getNodeType() == Arabica::DOM::Node_base::ELEMENT_NODE) {
std::string localName = LOCALNAME_CAST(ecBlock);
if (localName == _nsInfo.xmlNSPrefix + "transition") {
return "transition_set_" + ATTR_CAST(ecBlock, "postFixOrder") + "_i";
}
-
+
if (localName == _nsInfo.xmlNSPrefix + "onentry") {
return "entry_set_" + ATTR_CAST(ecBlock.getParentNode(), "documentOrder") + "_i";
}
@@ -436,7 +646,6 @@ namespace uscxml {
return "";
}
-
void ChartToVHDL::writeMicroStepper(std::ostream & stream) {
// create MicroStepper top level
stream << "-- FSM Logic" << std::endl;
@@ -616,8 +825,8 @@ namespace uscxml {
stream << "-- system signals" << std::endl;
stream << "signal stall : std_logic;" << std::endl;
stream << "signal completed_sig : std_logic;" << std::endl;
- stream << "signal rst_2 : std_logic;" << std::endl;
- stream << "signal rst_1 : std_logic;" << std::endl;
+ // stream << "signal rst_2 : std_logic;" << std::endl;
+ // stream << "signal rst_1 : std_logic;" << std::endl;
stream << "signal rst : std_logic;" << std::endl;
stream << std::endl;
@@ -646,6 +855,7 @@ namespace uscxml {
stream << "-- transition signals" << std::endl;
stream << "signal spontaneous_en : std_logic;" << std::endl;
+ stream << "signal spontaneous_active : std_logic;" << std::endl;
stream << "signal optimal_transition_set_combined_sig : std_logic;" << std::endl;
for (size_t i = 0; i < _transitions.size(); i++) {
@@ -728,18 +938,19 @@ namespace uscxml {
void ChartToVHDL::writeResetHandler(std::ostream & stream) {
stream << "-- reset handler" << std::endl;
- stream << "rst_proc: process(clk, rst_i)" << std::endl;
- stream << "begin" << std::endl;
- stream << " if rst_i = '1' then" << std::endl;
- stream << " rst_2 <= '1';" << std::endl;
- stream << " rst_1 <= '1';" << std::endl;
- stream << " rst <= '1';" << std::endl;
- stream << " elsif (rising_edge(clk)) then" << std::endl;
- stream << " rst_2 <= rst_i;" << std::endl;
- stream << " rst_1 <= rst_i;" << std::endl;
- stream << " rst <= rst_1;" << std::endl;
- stream << " end if;" << std::endl;
- stream << "end process;" << std::endl;
+ stream << "rst <= rst_i;" << std::endl;
+ // stream << "rst_proc: process(clk, rst_i)" << std::endl;
+ // stream << "begin" << std::endl;
+ // stream << " if rst_i = '1' then" << std::endl;
+ // stream << " rst_2 <= '1';" << std::endl;
+ // stream << " rst_1 <= '1';" << std::endl;
+ // stream << " rst <= '1';" << std::endl;
+ // stream << " elsif (rising_edge(clk)) then" << std::endl;
+ // stream << " rst_2 <= rst_i;" << std::endl;
+ // stream << " rst_1 <= rst_i;" << std::endl;
+ // stream << " rst <= rst_1;" << std::endl;
+ // stream << " end if;" << std::endl;
+ // stream << "end process;" << std::endl;
stream << std::endl;
}
@@ -750,7 +961,7 @@ namespace uscxml {
stream << "begin" << std::endl;
stream << " if rst = '1' then" << std::endl;
stream << " spontaneous_en <= '1';" << std::endl;
- stream << " elsif rising_edge(clk) then" << 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;
@@ -776,10 +987,54 @@ namespace uscxml {
}
stream << " next_event_dequeued <= '0';" << std::endl;
+ stream << " event_consumed <= '0';" << std::endl;
- stream << " elsif rising_edge(clk) then" << std::endl;
- //TODO
+ stream << " elsif falling_edge(clk) and stall = '0' then" << std::endl;
+ VContainer eventConsumed = VOR;
+ for (size_t i = 0; i < _transitions.size(); i++) {
+ Element<std::string> transition(_transitions[i]);
+
+ if (HAS_ATTR(transition, "event") == true) {
+ *eventConsumed += VLINE("in_optimal_transition_set_"
+ + ATTR(transition, "postFixOrder") + "_sig");
+ }
+ }
+
+ VBranch* tree = (VASSIGN,
+ VLINE("event_consumed"),
+ eventConsumed);
+ tree->print(stream);
+ stream << ";" << std::endl;
+
+ stream << " if int_event_empty = '0' then " << std::endl;
+ stream << " case next_event is " << std::endl;
+ for (std::list<TrieNode*>::iterator eventIter = eventNames.begin(); eventIter != eventNames.end(); eventIter++) {
+ stream << " when hwe_"
+ << eventNameEscape((*eventIter)->value) << " =>" << std::endl;
+ for (std::list<TrieNode*>::iterator eventIter2 = eventNames.begin(); eventIter2 != eventNames.end(); eventIter2++) {
+ stream << " event_" << eventNameEscape((*eventIter2)->value);
+ if (eventNameEscape((*eventIter)->value) == eventNameEscape((*eventIter2)->value)) {
+ stream << "_sig <= '1';" << std::endl;
+ } else {
+ stream << "_sig <= '0';" << std::endl;
+ }
+ }
+ stream << " next_event_dequeued <= '1';" << std::endl;
+ }
+ stream << " when others =>" << std::endl;
+ for (std::list<TrieNode*>::iterator eventIter = eventNames.begin(); eventIter != eventNames.end(); eventIter++) {
+ stream << " event_" << eventNameEscape((*eventIter)->value) << "_sig <= '0';" << std::endl;
+ }
+ stream << " next_event_dequeued <= '0';" << std::endl;
+ stream << " end case;" << std::endl;
+ stream << " elsif int_event_empty = '1' and event_consumed = '1' then" << std::endl;
+
+ for (std::list<TrieNode*>::iterator eventIter = eventNames.begin(); eventIter != eventNames.end(); eventIter++) {
+ stream << " event_" << eventNameEscape((*eventIter)->value) << "_sig <= '0';" << std::endl;
+ }
+ stream << " next_event_dequeued <= '0';" << std::endl;
+ stream << " end if;" << std::endl;
stream << " end if;" << std::endl;
stream << "end process;" << std::endl;
stream << std::endl;
@@ -788,7 +1043,7 @@ namespace uscxml {
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 spontaneous_en and not stall; " << std::endl;
+ stream << "int_event_read_en <= not stall; --not spontaneous_en and " << std::endl;
stream << std::endl;
}
@@ -797,11 +1052,18 @@ namespace uscxml {
for (size_t i = 0; i < _states.size(); i++) {
+ // TÖDO: is there a case where complete entry set reflects not the next state ?
VBranch* tree = (VASSIGN,
+ // VLINE("state_next_" + toStr(i) + "_sig"),
+ // (VAND,
+ // VLINE("in_complete_entry_set_" + toStr(i) + "_sig") ,
+ // (VOR, VLINE("in_exit_set_" + toStr(i) + "_sig"), (VNOT, VLINE("state_active_" + toStr(i) + "_sig"))))
+ // );
VLINE("state_next_" + toStr(i) + "_sig"),
- (VAND,
+ (VOR,
VLINE("in_complete_entry_set_" + toStr(i) + "_sig"),
- (VOR, VLINE("in_exit_set_" + toStr(i) + "_sig"), (VNOT, VLINE("state_active_" + toStr(i) + "_sig")))));
+ (VAND, (VNOT, VLINE("in_exit_set_" + toStr(i) + "_sig")), VLINE("state_active_" + toStr(i) + "_sig")))
+ );
tree->print(stream);
stream << ";" << std::endl;
@@ -812,6 +1074,7 @@ namespace uscxml {
void ChartToVHDL::writeOptimalTransitionSetSelection(std::ostream & stream) {
stream << "-- optimal transition set selection" << std::endl;
VContainer optimalTransitions = VOR;
+ VContainer spontaneoursActive = VOR;
for (size_t i = 0; i < _transitions.size(); i++) {
Element<std::string> transition(_transitions[i]);
std::string conflicts = ATTR(transition, "conflictBools");
@@ -841,7 +1104,7 @@ namespace uscxml {
VLINE("in_optimal_transition_set_" + ATTR(transition, "postFixOrder") + "_sig"),
(VAND,
(HAS_ATTR(transition, "event")
- ? (VNOT, VLINE("spontaneous_en"))
+ ? (VNOT, VLINE("spontaneous_active"))
: (VNOP, VLINE("spontaneous_en"))),
VLINE("state_active_" + ATTR(transition, "source") + "_sig"),
nameMatchers,
@@ -850,15 +1113,25 @@ namespace uscxml {
tree->print(stream);
stream << ";" << std::endl;
- *optimalTransitions += VLINE("in_optimal_transition_set_" + ATTR(transition, "postFixOrder") + "_sig");
+ *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) {
@@ -900,7 +1173,8 @@ namespace uscxml {
VLINE("in_entry_set_" + toStr(i) + "_sig"),
(VAND,
VLINE("in_complete_entry_set_" + toStr(i) + "_sig"),
- (VOR, VLINE("state_active_" + toStr(i) + "_sig"), (VNOT, VLINE("in_exit_set_" + toStr(i) + "_sig")))));
+ (VOR, VLINE("in_exit_set_" + toStr(i) + "_sig"),
+ (VNOT, VLINE("state_active_" + toStr(i) + "_sig")))));
tree->print(stream);
stream << ";" << std::endl;
@@ -908,17 +1182,26 @@ namespace uscxml {
}
void ChartToVHDL::writeDefaultCompletions(std::ostream & stream) {
+ // TODO direct connect the line in complete entry set (no extra line needed ...)
stream << "-- default completion assignments" << std::endl;
-
+ stream << "-- indikates if the state for which I am the def-completion is active" << std::endl;
std::map<Element<std::string>, NodeSet<std::string> > completions;
+
for (size_t i = 0; i < _states.size(); i++) {
Element<std::string> state(_states[i]);
completions[state]; // initialize other completions to 0
- std::string completion = ATTR(state, "completionBools");
- for (size_t j = 0; j < _states.size(); j++) {
- if (completion[j] == '1') {
- completions[Element<std::string>(_states[j])].push_back(state);
+ // we just need this if parent is a compound state
+ std::string parent = ATTR(state, "parent");
+ if (!parent.empty()
+ && isCompound(Element<std::string>(_states[strTo<size_t>(parent)]))) {
+
+ // Am I default completen ?
+ std::string completion = ATTR_CAST(_states[strTo<size_t>(parent)], "completionBools");
+ if (completion[i] == '1') {
+ // Yes? then give me the parent line
+ completions[state].push_back(Element<std::string>(_states[strTo<size_t>(parent)]));
+
}
}
}
@@ -932,7 +1215,11 @@ namespace uscxml {
VContainer defaultCompleters = VOR;
for (size_t i = 0; i < refs.size(); i++) {
- *defaultCompleters += VLINE("in_complete_entry_set_" + toStr(i) + "_sig ");
+ // *defaultCompleters += VLINE("in_complete_entry_set_" +
+ // TODO: default completion just when state is entered the first time ?
+ // if yes then we use the following code. If not we have to revert
+ *defaultCompleters += VLINE("in_entry_set_" +
+ ATTR_CAST(refs[i], "documentOrder") + "_sig ");
}
VBranch* tree = (VASSIGN,
@@ -961,15 +1248,16 @@ namespace uscxml {
for (size_t j = 0; j < _transitions.size(); j++) {
Element<std::string> transition(_transitions[j]);
std::string targetSet = ATTR(transition, "targetBools");
- if (targetSet[i] == '1') {
+ if (targetSet[i] == '1') {// <- ? TODO Was ist hier der vergleich?
*optimalEntrysetters += VLINE("in_optimal_transition_set_" + toStr(j) + "_sig");
}
}
VContainer completeEntrysetters = VOR;
- if (isCompound(state)) {
+ stream << "--" << state.getNodeName() << std::endl; // for debugging
+ if (isCompound(state) || isParallel(state)) { // <- true for scxml? TODO
for (size_t j = 0; j < _states.size(); j++) {
- if (children[j] != '1')
+ if (children[j] != '1') // if is child of state j
continue;
*completeEntrysetters += VLINE("in_complete_entry_set_up_" + toStr(j) + "_sig");
}
@@ -977,8 +1265,9 @@ namespace uscxml {
VBranch* tree = (VASSIGN,
VLINE("in_complete_entry_set_up_" + toStr(i) + "_sig"),
- optimalEntrysetters,
- completeEntrysetters);
+ (VOR, optimalEntrysetters, completeEntrysetters)
+ );
+
tree->print(stream);
stream << ";" << std::endl;
@@ -1011,7 +1300,6 @@ namespace uscxml {
Element<std::string> state(_states[i]);
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) {
@@ -1019,16 +1307,24 @@ namespace uscxml {
}
VContainer tmp1 = VAND;
- if (isCompound(Element<std::string>(_states[strTo<size_t>(parent)]))) {
+ // if parent is compound
+ if (!parent.empty() &&
+ isCompound(Element<std::string>(_states[strTo<size_t>(parent)]))) {
+ std::string children = ATTR_CAST(_states[strTo<size_t>(parent)],
+ "childBools");
+ // TODO: do not add default_completion line if not needed
+ // --> just if this state is the default completion of parent
+ // --> init attr. or if not present first in document order <-- = completion bool ?
*tmp1 += VLINE("default_completion_" + ATTR(state, "documentOrder") + "_sig");
+ //TODO check this
for (size_t j = 0; j < _states.size(); j++) {
if (children[j] != '1')
continue;
*tmp1 += (VAND,
(VNOT,
(VAND,
- VLINE("state_active" + toStr(j) + "_sig"),
+ VLINE("state_active_" + toStr(j) + "_sig"),
(VNOT,
VLINE("in_exit_set_" + toStr(j) + "_sig")))));
@@ -1036,6 +1332,7 @@ namespace uscxml {
}
+ // if parent is parallel
if (isParallel(Element<std::string>(_states[strTo<size_t>(parent)]))) {
*tmp1 += VLINE("in_complete_entry_set_" + toStr(parent) + "_sig");
}
@@ -1126,14 +1423,14 @@ namespace uscxml {
stream << "state_active_" << ATTR(state, "documentOrder")
<< "_o <= state_active_" << ATTR(state, "documentOrder")
<< "_sig;" << std::endl;
- if (DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "onentry", state).size() > 0) {
- stream << "entry_set_" << ATTR(state, "documentOrder")
+ if (DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "onexit", state).size() > 0) {
+ stream << "exit_set_" << ATTR(state, "documentOrder")
<< "_o <= in_exit_set_" << ATTR(state, "documentOrder")
<< "_sig;" << std::endl;
}
- if (DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "onexit", state).size() > 0) {
- stream << "exit_set_" << ATTR(state, "documentOrder")
+ if (DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "onentry", state).size() > 0) {
+ stream << "entry_set_" << ATTR(state, "documentOrder")
<< "_o <= in_entry_set_" << ATTR(state, "documentOrder")
<< "_sig;" << std::endl;
}
diff --git a/test/vhdltest/debug.do b/test/vhdltest/debug.do
index ca62e9c..39210fe 100644
--- a/test/vhdltest/debug.do
+++ b/test/vhdltest/debug.do
@@ -13,6 +13,7 @@ sim:/tb/dut/en
add wave -noupdate -divider -height 20 Outputs
add wave -position insertpoint \
sim:/tb/dut/state_active_*_o \
+sim:/tb/dut/*_set_*_o \
sim:/tb/dut/completed_o
add wave -noupdate -divider -height 20 System
@@ -35,11 +36,16 @@ add wave -noupdate -divider -height 20 Transition_Set
add wave -position insertpoint \
sim:/tb/dut/in_optimal_transition_set_*_sig
-add wave -noupdate -divider -height 20 Event
+#add wave -noupdate -divider -height 20 Event_Interface
+#add wave -position insertpoint \
+#sim:/tb/ec/*_i \
+#sim:/tb/ec/*_o
+
+add wave -noupdate -divider -height 20 ALL_EventController
add wave -position insertpoint \
-sim:/tb/dut/*event*
+sim:/tb/ec/*
-add wave -noupdate -divider -height 20 ALL
+add wave -noupdate -divider -height 20 ALL_MicroStepper
add wave -position insertpoint \
sim:/tb/dut/*
diff --git a/test/vhdltest/green_write_dut.sh b/test/vhdltest/green_write_dut.sh
new file mode 100755
index 0000000..615ca8e
--- /dev/null
+++ b/test/vhdltest/green_write_dut.sh
@@ -0,0 +1,66 @@
+#!/bin/bash
+
+ME=`basename $0`
+DIR="$( cd "$( dirname "$0" )" && pwd )/"
+
+SCXML_BIN=$DIR"../../build/bin/"
+SCXML_TEST=$DIR"../"
+
+SIM_DIR=$DIR"../../build/simulation/"
+#INSTALL_DIR=/home/juehv/altera/13.1/modelsim_ase/bin/
+INSTALL_DIR=""
+VHDL_OUT=${SIM_DIR}vhd/
+SIM_LIB_DIR=${SIM_DIR}scxml/
+
+LIB_CREATE_CMD="${INSTALL_DIR}vlib $SIM_LIB_DIR"
+LIB_MAP_CMD="${INSTALL_DIR}vmap work $SIM_LIB_DIR"
+COMPILE_CMD="${INSTALL_DIR}vcom ${VHDL_OUT}dut.vhd"
+#SIMULATION_CMD="${INSTALL_DIR}vsim -c scxml_lib.testbench -do automation.tcl"
+SIMULATION_CMD="${INSTALL_DIR}vsim work.tb -do debug.do"
+
+# get arguments
+TEST_NUMBER="test144.scxml"
+if [ "$1" != "" ] ; then
+ TEST_NUMBER="$1"
+fi
+
+# init simulation dir
+rm -rf $SIM_DIR
+mkdir -p $SIM_DIR
+mkdir -p $VHDL_OUT
+cp ./debug.do $SIM_DIR
+cp ./automation.tcl $SIM_DIR
+#cp ./modelsim.ini $SIM_DIR
+
+# Write file
+cd $DIR
+#${SCXML_BIN}uscxml-transform -t vhdl -i ${SCXML_TEST}/w3c/ecma/${TEST_NUMBER} -o ${VHDL_OUT}dut.vhd
+${SCXML_BIN}uscxml-transform -t vhdl -i /home/juehv/Desktop/green.scxml -o ${VHDL_OUT}dut.vhd
+#echo "$(cat ${VHDL_OUT}dut.vhd)"
+echo "${VHDL_OUT}dut.vhd written"
+TMP_RESULT="$(tail -n 1 ${VHDL_OUT}dut.vhd)"
+
+if [ "$TMP_RESULT" == "ERROR" ] ; then
+ echo "Error while generating VHDL"
+ exit -1
+fi
+
+# map librarys
+cd ${SIM_DIR}
+$LIB_CREATE_CMD
+$LIB_MAP_CMD
+echo "Library mapped"
+
+# compile stuff
+cd ${SIM_DIR}
+${COMPILE_CMD}
+
+if [ $? -eq 0 ] ; then
+ echo "compilation done."
+else
+ echo "compilation failed"
+ exit -1
+fi
+
+# start simulator
+${SIMULATION_CMD}
diff --git a/test/vhdltest/tmp_write_dut.sh b/test/vhdltest/tmp_write_dut.sh
new file mode 100755
index 0000000..2adc680
--- /dev/null
+++ b/test/vhdltest/tmp_write_dut.sh
@@ -0,0 +1,66 @@
+#!/bin/bash
+
+ME=`basename $0`
+DIR="$( cd "$( dirname "$0" )" && pwd )/"
+
+SCXML_BIN=$DIR"../../build/bin/"
+SCXML_TEST=$DIR"../"
+
+SIM_DIR=$DIR"../../build/simulation/"
+#INSTALL_DIR=/home/juehv/altera/13.1/modelsim_ase/bin/
+INSTALL_DIR=""
+VHDL_OUT=${SIM_DIR}vhd/
+SIM_LIB_DIR=${SIM_DIR}scxml/
+
+LIB_CREATE_CMD="${INSTALL_DIR}vlib $SIM_LIB_DIR"
+LIB_MAP_CMD="${INSTALL_DIR}vmap work $SIM_LIB_DIR"
+COMPILE_CMD="${INSTALL_DIR}vcom ${VHDL_OUT}dut.vhd"
+#SIMULATION_CMD="${INSTALL_DIR}vsim -c scxml_lib.testbench -do automation.tcl"
+SIMULATION_CMD="${INSTALL_DIR}vsim work.tb -do debug.do"
+
+# get arguments
+TEST_NUMBER="test144.scxml"
+if [ "$1" != "" ] ; then
+ TEST_NUMBER="$1"
+fi
+
+# init simulation dir
+rm -rf $SIM_DIR
+mkdir -p $SIM_DIR
+mkdir -p $VHDL_OUT
+cp ./debug.do $SIM_DIR
+cp ./automation.tcl $SIM_DIR
+#cp ./modelsim.ini $SIM_DIR
+
+# Write file
+cd $DIR
+${SCXML_BIN}uscxml-transform -t vhdl -i ${SCXML_TEST}/w3c/ecma/${TEST_NUMBER} -o ${VHDL_OUT}dut.vhd
+#${SCXML_BIN}uscxml-transform -t vhdl -i /home/juehv/Desktop/green.scxml -o ${VHDL_OUT}dut.vhd
+#echo "$(cat ${VHDL_OUT}dut.vhd)"
+echo "${VHDL_OUT}dut.vhd written"
+TMP_RESULT="$(tail -n 1 ${VHDL_OUT}dut.vhd)"
+
+if [ "$TMP_RESULT" == "ERROR" ] ; then
+ echo "Error while generating VHDL"
+ exit -1
+fi
+
+# map librarys
+cd ${SIM_DIR}
+$LIB_CREATE_CMD
+$LIB_MAP_CMD
+echo "Library mapped"
+
+# compile stuff
+cd ${SIM_DIR}
+${COMPILE_CMD}
+
+if [ $? -eq 0 ] ; then
+ echo "compilation done."
+else
+ echo "compilation failed"
+ exit -1
+fi
+
+# start simulator
+${SIMULATION_CMD}