summaryrefslogtreecommitdiff
path: root/src/mem
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem')
-rw-r--r--src/mem/slicc/parser.py9
-rw-r--r--src/mem/slicc/symbols/State.py8
-rw-r--r--src/mem/slicc/symbols/StateMachine.py13
-rw-r--r--src/mem/slicc/symbols/Transition.py15
4 files changed, 40 insertions, 5 deletions
diff --git a/src/mem/slicc/parser.py b/src/mem/slicc/parser.py
index 10dd99ece..1ce8bf1bd 100644
--- a/src/mem/slicc/parser.py
+++ b/src/mem/slicc/parser.py
@@ -278,7 +278,7 @@ class SLICC(Grammar):
p[0] = ast.OutPortDeclAST(self, p[3], p[5], p[7], p[8])
def p_decl__trans0(self, p):
- "decl : TRANS '(' idents ',' idents ',' ident ')' idents"
+ "decl : TRANS '(' idents ',' idents ',' ident_or_star ')' idents"
p[0] = ast.TransitionDeclAST(self, [], p[3], p[5], p[7], p[9])
def p_decl__trans1(self, p):
@@ -286,7 +286,7 @@ class SLICC(Grammar):
p[0] = ast.TransitionDeclAST(self, [], p[3], p[5], None, p[7])
def p_decl__trans2(self, p):
- "decl : TRANS '(' idents ',' idents ',' ident ')' idents idents"
+ "decl : TRANS '(' idents ',' idents ',' ident_or_star ')' idents idents"
p[0] = ast.TransitionDeclAST(self, p[9], p[3], p[5], p[7], p[10])
def p_decl__trans3(self, p):
@@ -506,6 +506,11 @@ class SLICC(Grammar):
"ident : IDENT"
p[0] = p[1]
+ def p_ident_or_star(self, p):
+ """ident_or_star : ident
+ | STAR"""
+ p[0] = p[1]
+
# Pair and pair lists
def p_pairs__list(self, p):
"pairs : ',' pairsx"
diff --git a/src/mem/slicc/symbols/State.py b/src/mem/slicc/symbols/State.py
index 123693256..164c585f6 100644
--- a/src/mem/slicc/symbols/State.py
+++ b/src/mem/slicc/symbols/State.py
@@ -30,5 +30,13 @@ from slicc.symbols.Symbol import Symbol
class State(Symbol):
def __repr__(self):
return "[State: %s]" % self.ident
+ def isWildcard(self):
+ return False
+
+class WildcardState(State):
+ def __repr__(self):
+ return "[State: *]"
+ def isWildcard(self):
+ return True
__all__ = [ "State" ]
diff --git a/src/mem/slicc/symbols/StateMachine.py b/src/mem/slicc/symbols/StateMachine.py
index 174d66e0f..8a4d7d9b5 100644
--- a/src/mem/slicc/symbols/StateMachine.py
+++ b/src/mem/slicc/symbols/StateMachine.py
@@ -1310,8 +1310,17 @@ ${ident}_Controller::doTransitionWorker(${ident}_Event event,
case = self.symtab.codeFormatter()
# Only set next_state if it changes
if trans.state != trans.nextState:
- ns_ident = trans.nextState.ident
- case('next_state = ${ident}_State_${ns_ident};')
+ if trans.nextState.isWildcard():
+ # When * is encountered as an end state of a transition,
+ # the next state is determined by calling the
+ # machine-specific getNextState function. The next state
+ # is determined before any actions of the transition
+ # execute, and therefore the next state calculation cannot
+ # depend on any of the transitionactions.
+ case('next_state = getNextState(addr);')
+ else:
+ ns_ident = trans.nextState.ident
+ case('next_state = ${ident}_State_${ns_ident};')
actions = trans.actions
request_types = trans.request_types
diff --git a/src/mem/slicc/symbols/Transition.py b/src/mem/slicc/symbols/Transition.py
index 901d4a0e8..9ecd6c54b 100644
--- a/src/mem/slicc/symbols/Transition.py
+++ b/src/mem/slicc/symbols/Transition.py
@@ -26,6 +26,7 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.symbols.Symbol import Symbol
+from slicc.symbols.State import WildcardState
class Transition(Symbol):
def __init__(self, table, machine, state, event, nextState, actions,
@@ -35,7 +36,19 @@ class Transition(Symbol):
self.state = machine.states[state]
self.event = machine.events[event]
- self.nextState = machine.states[nextState]
+ if nextState == '*':
+ # check to make sure there is a getNextState function declared
+ found = False
+ for func in machine.functions:
+ if func.c_ident == 'getNextState':
+ found = True
+ break
+ if found == False:
+ fatal("Machine uses a wildcard transition without getNextState defined")
+ self.nextState = WildcardState(machine.symtab,
+ '*', location)
+ else:
+ self.nextState = machine.states[nextState]
self.actions = [ machine.actions[a] for a in actions ]
self.request_types = [ machine.request_types[s] for s in request_types ]
self.resources = {}