summaryrefslogtreecommitdiffstats
path: root/src/uscxml/transform/ChartToVHDL.cpp
diff options
context:
space:
mode:
authorStefan Radomski <sradomski@mintwerk.de>2016-02-24 10:50:32 (GMT)
committerStefan Radomski <sradomski@mintwerk.de>2016-02-24 10:50:32 (GMT)
commitcf19f11b8d2bd6d9566c7528fbed40af06928abf (patch)
treea373b8e934fa78a1bf9db8afca2e9854437e45da /src/uscxml/transform/ChartToVHDL.cpp
parent7212d5a3dbbd2845d09df96b2c345132c8a24931 (diff)
downloaduscxml-cf19f11b8d2bd6d9566c7528fbed40af06928abf.zip
uscxml-cf19f11b8d2bd6d9566c7528fbed40af06928abf.tar.gz
uscxml-cf19f11b8d2bd6d9566c7528fbed40af06928abf.tar.bz2
Some more refactoring and VHDL transformation
Diffstat (limited to 'src/uscxml/transform/ChartToVHDL.cpp')
-rw-r--r--src/uscxml/transform/ChartToVHDL.cpp213
1 files changed, 170 insertions, 43 deletions
diff --git a/src/uscxml/transform/ChartToVHDL.cpp b/src/uscxml/transform/ChartToVHDL.cpp
index 52f1a5c..7a139fa 100644
--- a/src/uscxml/transform/ChartToVHDL.cpp
+++ b/src/uscxml/transform/ChartToVHDL.cpp
@@ -78,7 +78,7 @@ void ChartToVHDL::checkDocument() {
std::stringstream ss;
if (unsupported.size() > 0) {
- for (int i = 0; i < unsupported.size(); i++) {
+ for (size_t i = 0; i < unsupported.size(); i++) {
ss << " " << DOMUtils::xPathForNode(unsupported[i]) << " unsupported" << std::endl;
}
throw std::runtime_error("Unsupported elements found:\n" + ss.str());
@@ -88,7 +88,7 @@ void ChartToVHDL::checkDocument() {
elements.insert(_nsInfo.xmlNSPrefix + "transition");
unsupported = DOMUtils::inDocumentOrder(elements, _scxml);
- for (int i = 0; i < unsupported.size(); i++) {
+ for (size_t i = 0; i < unsupported.size(); i++) {
Element<std::string> transition(unsupported[i]);
if (HAS_ATTR(transition, "cond")) {
ERROR_PLATFORM_THROW("transition with conditions not supported!");
@@ -122,14 +122,9 @@ void ChartToVHDL::writeTo(std::ostream& stream) {
// checkDocument();
findEvents();
-// _eventTrie.dump();
-
writeTypes(stream);
writeFiFo(stream);
- writeOptimalTransitionSetSelection(stream);
- writeExitSet(stream);
- writeEntrySet(stream);
writeFSM(stream);
}
@@ -169,10 +164,16 @@ void ChartToVHDL::writeFSM(std::ostream & stream) {
writeModuleInstantiation(stream);
// write fsm architecture
- writeNextStateLogic(stream);
+// writeNextStateLogic(stream);
+
+ writeOptimalTransitionSetSelection(stream);
+ writeExitSet(stream);
+ writeEntrySet(stream);
+
// writeOutputLogic(stream);
writeErrorHandler(stream);
+
stream << std::endl;
stream << "end behavioral; " << std::endl;
stream << "-- END FSM Logic" << std::endl;
@@ -226,15 +227,15 @@ void ChartToVHDL::writeTypes(std::ostream & stream) {
stream << std::endl;
stream << "package machine" << _md5 << " is" << std::endl;
// create state type
- stream << " type state_type is std_logic_vector( ";
+ stream << " subtype state_type is std_logic_vector( ";
stream << _states.size() - 1;
- stream << " downto 0)" << std::endl;
+ stream << " downto 0);" << std::endl;
//TODO complete
// create event type
stream << " type event_type is (";
seperator = "";
-// for (int i = 0; i < _events.size(); i++) {
+// for (size_t i = 0; i < _events.size(); i++) {
// stream << seperator;
// stream << _events[i];
// seperator = ", ";
@@ -358,16 +359,32 @@ void ChartToVHDL::writeSignals(std::ostream & stream) {
stream << "-- system signals" << std::endl;
stream << "signal stall : std_logic;" << std::endl;
stream << "-- state signals" << std::endl;
- stream << "signal next_state : state_type;" << std::endl;
- stream << "signal current_state : state_type;" << std::endl;
+// stream << "signal next_state : state_type;" << std::endl;
+// stream << "signal current_state : state_type;" << std::endl;
- for (int i = 0; i < _states.size(); i++) {
+ for (size_t i = 0; i < _states.size(); i++) {
Element<std::string> state(_states[i]);
- stream << "signal " << ATTR(state, "id") << "_curr : current_state("
- << toStr(i) << ");" << std::endl;
- stream << "signal " << ATTR(state, "id") << "_next : next_state("
- << toStr(i) << ");" << std::endl;
+ stream << "signal " << DOMUtils::idForNode(state) << "_curr : std_logic;" << std::endl;
+ stream << "signal " << DOMUtils::idForNode(state) << "_next : std_logic;" << std::endl;
}
+ for (size_t i = 0; i < _states.size(); i++) {
+ Element<std::string> state(_states[i]);
+ stream << "signal in_exit_set_" << ATTR(state, "documentOrder") << "_sig : std_logic;" << std::endl;
+ stream << "signal in_complete_entry_set_up_" << ATTR(state, "documentOrder") << "_sig : std_logic;" << std::endl;
+ stream << "signal in_complete_entry_set_" << ATTR(state, "documentOrder") << "_sig : std_logic;" << std::endl;
+ stream << "signal state_active_" << ATTR(state, "documentOrder") << "_sig : std_logic;" << std::endl;
+ stream << "signal default_completion_" << ATTR(state, "documentOrder") << "_sig : std_logic;" << std::endl;
+ }
+
+ stream << "-- transition signals" << std::endl;
+ stream << "signal spontaneous_en : std_logic;" << std::endl;
+
+ for (size_t i = 0; i < _transitions.size(); i++) {
+ Element<std::string> transition(_transitions[i]);
+ stream << "signal in_optimal_transition_set_" << ATTR(transition, "postFixOrder") << "_sig : std_logic;"
+ << std::endl;
+ }
+
stream << std::endl;
stream << "-- event signals" << std::endl;
stream << "signal int_event_write_en : std_logic;" << std::endl;
@@ -379,14 +396,13 @@ void ChartToVHDL::writeSignals(std::ostream & stream) {
stream << "signal next_event : event_type;" << std::endl;
stream << "signal event_consumed : std_logic;" << std::endl;
stream << std::endl;
- stream << "-- transition signals" << std::endl;
- stream << "signal transition_spntaneous_en : std_logic;" << std::endl;
- for (int i = 0; i < _transitions.size(); i++) {
- Element<std::string> transition(_transitions[i]);
- stream << "signal in_optimal_transition_set_" << ATTR(transition, "postFixOrder") << "_sig : std_logic;"
- << std::endl;
- }
+ std::list<TrieNode*> eventNames = _eventTrie.getWordsWithPrefix("");
+ for (std::list<TrieNode*>::iterator eventIter = eventNames.begin(); eventIter != eventNames.end(); eventIter++) {
+ stream << "signal event_" << eventNameEscape((*eventIter)->value) << "_sig : std_logic;" << std::endl;
+ }
+ // _eventTrie.dump();
+
stream << std::endl;
stream << "-- error signals" << std::endl;
@@ -421,7 +437,7 @@ void ChartToVHDL::writeModuleInstantiation(std::ostream & stream) {
stream << "next_event <= int_event_output; " << std::endl;
stream << "int_event_write_en <= next_event_en_i; " << std::endl;
stream << "int_event_input <= next_event_i; " << std::endl;
- stream << "int_event_read_en <= not transition_spontanous_en and not stall; " << std::endl;
+ stream << "int_event_read_en <= not spontaneous_en and not stall; " << std::endl;
stream << std::endl;
// instantiate event fifo
@@ -466,8 +482,44 @@ void ChartToVHDL::writeOptimalTransitionSetSelection(std::ostream & stream) {
Element<std::string> transition(_transitions[i]);
std::string conflicts = ATTR(transition, "conflictBools");
+
+ VContainer nameMatchers = VOR;
+ if (HAS_ATTR(transition, "event")) {
+ std::list<std::string> eventDescs = tokenize(ATTR(transition, "event"));
+ for (std::list<std::string>::iterator descIter = eventDescs.begin(); descIter != eventDescs.end(); descIter++) {
+ std::list<TrieNode*> eventNames = _eventTrie.getWordsWithPrefix((*descIter) == "*" ? "" : *descIter);
+ for (std::list<TrieNode*>::iterator eventIter = eventNames.begin(); eventIter != eventNames.end(); eventIter++) {
+ *nameMatchers += VLINE("event_" + eventNameEscape((*eventIter)->value) + "_sig");
+ }
+ }
+ } else {
+ *nameMatchers += VLINE("'1'");
+ }
+
+ VContainer conflicters = VOR;
+ for (size_t j = 0; j < i; j++) {
+ if (conflicts[j] == '1') {
+ *conflicters += VLINE("in_optimal_transition_set_" + toStr(j) + "_sig");
+ }
+ }
+
+ VBranch* tree = (VASSIGN ,
+ VLINE("in_optimal_transition_set_" + ATTR(transition, "postFixOrder") + "_sig") ,
+ (VAND ,
+ (HAS_ATTR(transition, "event")
+ ? ( VNOT , VLINE("spontaneous_en") )
+ : ( VNOP , VLINE("spontaneous_en") ) ) ,
+ VLINE("state_active_" + ATTR(transition, "source") + "_sig"),
+ nameMatchers,
+ (VNOT , conflicters) ) );
+
+ tree->print(stream);
+ stream << ";" << std::endl;
+
+
+#if 0
stream << "in_optimal_transition_set_" << ATTR(transition, "postFixOrder") << "_sig "
- << "<= " << (HAS_ATTR(transition, "event") ? "(not spontaneous_sig)" : "spontaneous_sig") << " and " << std::endl
+ << "<= " << (HAS_ATTR(transition, "event") ? "(not spontaneous_en)" : "spontaneous_en") << " and " << std::endl
<< " state_active_" << ATTR(transition, "source") << "_sig and not ( '0' " << std::endl;
for (size_t j = 0; j < i; j++) {
if (conflicts[j] == '1') {
@@ -490,8 +542,8 @@ void ChartToVHDL::writeOptimalTransitionSetSelection(std::ostream & stream) {
}
stream << ";" << std::endl;
+#endif
}
-
}
void ChartToVHDL::writeExitSet(std::ostream & stream) {
@@ -504,8 +556,27 @@ void ChartToVHDL::writeExitSet(std::ostream & stream) {
std::string children = ATTR(state, "childBools");
std::string parent = ATTR(state, "parent");
+ VContainer exitsetters = VOR;
+ for (size_t j = 0; j < _transitions.size(); j++) {
+ Element<std::string> transition(_transitions[j]);
+ std::string exitSet = ATTR(transition, "exitSetBools");
+ if (exitSet[i] == '1') {
+ *exitsetters += VLINE("in_optimal_transition_set_" + toStr(j) + "_sig ");
+ }
+ }
+
+ VBranch* tree = (VASSIGN ,
+ VLINE("in_exit_set_" + toStr(i) + "_sig"),
+ (VAND,
+ VLINE("state_active_" + toStr(i) + "_sig"),
+ exitsetters ));
+
+ tree->print(stream);
+ stream << ";" << std::endl;
+
+#if 0
stream << "in_exit_set_" << toStr(i) << "_sig "
- << "<= state_active_ " << toStr(i) << "_sig and ('0'" << std::endl;
+ << "<= state_active_" << toStr(i) << "_sig and ('0'" << std::endl;
for (size_t j = 0; j < _transitions.size(); j++) {
Element<std::string> transition(_transitions[j]);
std::string exitSet = ATTR(transition, "exitSetBools");
@@ -516,7 +587,7 @@ void ChartToVHDL::writeExitSet(std::ostream & stream) {
stream << ")";
stream << ";" << std::endl;
-
+#endif
}
}
@@ -530,6 +601,33 @@ void ChartToVHDL::writeEntrySet(std::ostream & stream) {
std::string children = ATTR(state, "childBools");
std::string parent = ATTR(state, "parent");
+ VContainer optimalEntrysetters = VOR;
+ 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') {
+ *optimalEntrysetters += VLINE("in_optimal_transition_set_" + toStr(j) + "_sig");
+ }
+ }
+
+ VContainer completeEntrysetters = VOR;
+ if (isCompound(state)) {
+ for (size_t j = 0; j < _states.size(); j++) {
+ if (children[j] != '1')
+ continue;
+ *completeEntrysetters += VLINE("in_complete_entry_set_up_" + toStr(j) + "_sig");
+ }
+ }
+
+ VBranch* tree = (VASSIGN ,
+ VLINE("in_complete_entry_set_up_" + toStr(i) + "_sig"),
+ optimalEntrysetters,
+ completeEntrysetters);
+
+ tree->print(stream);
+ stream << ";" << std::endl;
+
+#if 0
stream << "in_complete_entry_set_up_" << toStr(i) << "_sig <= ('0'" << std::endl;
for (size_t j = 0; j < _transitions.size(); j++) {
@@ -550,7 +648,7 @@ void ChartToVHDL::writeEntrySet(std::ostream & stream) {
}
stream << ");" << std::endl;
-
+#endif
}
for (size_t i = 0; i < _states.size(); i++) {
@@ -564,6 +662,35 @@ void ChartToVHDL::writeEntrySet(std::ostream & stream) {
continue; // TODO: FixMe <scxml>
}
+ VContainer tmp1 = VAND;
+ if (isCompound(Element<std::string>(_states[strTo<size_t>(parent)]))) {
+ *tmp1 += VLINE("default_completion_" + toStr(parent) + "_sig");
+
+ for (size_t j = 0; j < _states.size(); j++) {
+ if (children[j] != '1')
+ continue;
+ *tmp1 += ( VAND,
+ ( VNOT,
+ ( VAND,
+ VLINE("is_active" + toStr(j) + "_sig"),
+ ( VNOT,
+ VLINE("in_exit_set_" + toStr(j) + "_sig") ) ) ) );
+
+ }
+
+ }
+
+ if (isParallel(Element<std::string>(_states[strTo<size_t>(parent)]))) {
+ *tmp1 += VLINE("in_complete_entry_set_" + toStr(parent) + "_sig");
+ }
+
+ VBranch* tree = (VASSIGN ,
+ VLINE("in_complete_entry_set_" + toStr(i) + "_sig"), tmp1);
+
+ tree->print(stream);
+ stream << ";" << std::endl;
+
+#if 0
stream << "in_complete_entry_set_" << toStr(i) << "_sig <= (in_complete_entry_set_up_" << toStr(i) << "_sig or (" << std::endl;
if (isParallel(Element<std::string>(_states[strTo<size_t>(parent)]))) {
@@ -580,7 +707,7 @@ void ChartToVHDL::writeEntrySet(std::ostream & stream) {
}
stream << ");" << std::endl;
-
+#endif
}
}
@@ -595,7 +722,7 @@ void ChartToVHDL::writeNextStateLogic(std::ostream & stream) {
stream << "begin" << std::endl;
std::stringstream nextStateBuffer;
- for (int i = 0; i < _states.size(); i++) {
+ for (size_t i = 0; i < _states.size(); i++) {
Element<std::string> state(_states[i]);
// calculate event choices
@@ -604,7 +731,7 @@ void ChartToVHDL::writeNextStateLogic(std::ostream & stream) {
// will be written first
std::vector< Element<std::string> > choices;
std::string spntaneous_trans_sig = "";
- for (int j = 0; j < _transitions.size(); j++) {
+ for (size_t j = 0; j < _transitions.size(); j++) {
Element<std::string> transition(_transitions[j]);
if (ATTR_CAST(transition.getParentNode(), "id") == ATTR(state, "id")) {
choices.push_back(transition);
@@ -618,7 +745,7 @@ void ChartToVHDL::writeNextStateLogic(std::ostream & stream) {
// calculate incomming transitions (for later use)
std::vector< Element<std::string> > incommingTransitions;
- for (int j = 0; j < _transitions.size(); j++) {
+ for (size_t j = 0; j < _transitions.size(); j++) {
Element<std::string> transition(_transitions[j]);
if (ATTR_CAST(transition, "target") == ATTR(state, "id")) {
incommingTransitions.push_back(transition);
@@ -630,7 +757,7 @@ void ChartToVHDL::writeNextStateLogic(std::ostream & stream) {
stream << " if ( " << ATTR(state, "id") << " = '1' ) then" << std::endl;
stream << " if ( transition_spntaneous_en = '1' ) then" << std::endl;
// enable spntaneous transition (if any) and disable all other
- for (int j = 0; j < choices.size(); j++) {
+ for (size_t j = 0; j < choices.size(); j++) {
Element<std::string> transition(choices[j]);
if (ATTR(transition, "id") == spntaneous_trans_sig) {
stream << " " << ATTR(transition, "id") << "_sig <= '1';" << std::endl;
@@ -646,7 +773,7 @@ void ChartToVHDL::writeNextStateLogic(std::ostream & stream) {
// FIXME hopefully there is just one transition per state and event at a time
stream << " case next_event is" << std::endl;
bool hasWildcardTransition = false;
- for (int j = 0; j < choices.size(); j++) {
+ for (size_t j = 0; j < choices.size(); j++) {
Element<std::string> transition(choices[j]);
std::string eventName = ATTR(transition, "event");
if (eventName == CONST_EVENT_ANY) {
@@ -655,7 +782,7 @@ void ChartToVHDL::writeNextStateLogic(std::ostream & stream) {
}
stream << " when " << eventName << " =>" << std::endl;
// activate transition and deactivete others
- for (int k = 0; k < choices.size(); k++) {
+ for (size_t k = 0; k < choices.size(); k++) {
Element<std::string> tmp_t(choices[k]);
if (ATTR(tmp_t, "event") == ATTR(transition, "event")) {
stream << " " << ATTR(tmp_t, "id") << "_sig <= '1';" << std::endl;
@@ -667,7 +794,7 @@ void ChartToVHDL::writeNextStateLogic(std::ostream & stream) {
if (!hasWildcardTransition) {
// if there is no others we create one for deactivating everything
stream << " when others =>" << std::endl;
- for (int j = 0; j < choices.size(); j++) {
+ for (size_t j = 0; j < choices.size(); j++) {
Element<std::string> tmp_t(choices[j]);
stream << " " << ATTR(tmp_t, "id") << "_sig <= '0';" << std::endl;
}
@@ -679,7 +806,7 @@ void ChartToVHDL::writeNextStateLogic(std::ostream & stream) {
stream << " else" << std::endl;
// no enabled event ? disable all transitions (looks like we have to wait)
- for (int j = 0; j < choices.size(); j++) {
+ for (size_t j = 0; j < choices.size(); j++) {
Element<std::string> transition(choices[j]);
stream << " " << ATTR(transition, "id") << "_sig <= '0';" << std::endl;
}
@@ -690,14 +817,14 @@ void ChartToVHDL::writeNextStateLogic(std::ostream & stream) {
// write next state calculation in buffer for later use
nextStateBuffer << ATTR(state, "id") << "_next <= ( ( '0'";
std::string seperator = " or ";
- for (int j = 0; j < incommingTransitions.size(); j++) {
+ for (size_t j = 0; j < incommingTransitions.size(); j++) {
nextStateBuffer << seperator
<< ATTR(incommingTransitions[j], "id") << "_sig";
}
nextStateBuffer << " ) or ";
nextStateBuffer << "( ( not ( '0'";
seperator = " or ";
- for (int j = 0; j < choices.size(); j++) {
+ for (size_t j = 0; j < choices.size(); j++) {
nextStateBuffer << seperator
<< ATTR(choices[j], "id") << "_sig";
}
@@ -729,7 +856,7 @@ void ChartToVHDL::writeOutputLogic(std::ostream & stream) {
stream << "begin" << std::endl;
stream << " case current_state is" << std::endl;
- for (int i = 0; i < _states.size(); i++) {
+ for (size_t i = 0; i < _states.size(); i++) {
//TODO
// if end state set completed and result
// on entry events generated here