diff --git a/src/mem/protocol/RubySlicc_Exports.sm b/src/mem/protocol/RubySlicc_Exports.sm --- a/src/mem/protocol/RubySlicc_Exports.sm +++ b/src/mem/protocol/RubySlicc_Exports.sm @@ -113,7 +113,9 @@ } enumeration(TransitionResult, desc="...") { + NULL, desc="NULL transition"; Valid, desc="Valid transition"; + Ignore, desc="Ignore transition and continue"; ResourceStall, desc="Stalled due to insufficient resources"; ProtocolStall, desc="Protocol specified stall"; } diff --git a/src/mem/slicc/ast/FuncCallExprAST.py b/src/mem/slicc/ast/FuncCallExprAST.py --- a/src/mem/slicc/ast/FuncCallExprAST.py +++ b/src/mem/slicc/ast/FuncCallExprAST.py @@ -136,16 +136,7 @@ ''') code(''' - if (result == TransitionResult_Valid) { - counter++; - continue; // Check the first port again - } - - if (result == TransitionResult_ResourceStall) { - scheduleEvent(1); - - // Cannot do anything with this transition, go check next doable transition (mostly likely of next port) - } + return result; } ''') elif self.proc_name == "error": diff --git a/src/mem/slicc/ast/InPortDeclAST.py b/src/mem/slicc/ast/InPortDeclAST.py --- a/src/mem/slicc/ast/InPortDeclAST.py +++ b/src/mem/slicc/ast/InPortDeclAST.py @@ -109,17 +109,6 @@ param_types.append(type) - # Add the doubleTrigger method - this hack supports tiggering - # two simulateous events - # - # The key is that the second transistion cannot fail because - # the first event cannot be undone therefore you must do some - # checks before calling double trigger to ensure that won't - # happen - func = Func(self.symtab, "doubleTrigger", self.location, void_type, - param_types, [], "", pairs) - symtab.newSymbol(func) - # Add the continueProcessing method - this hack supports # messages that don't trigger events func = Func(self.symtab, "continueProcessing", self.location, @@ -128,8 +117,6 @@ if self.statements is not None: rcode = self.slicc.codeFormatter() - rcode.indent() - rcode.indent() self.statements.generate(rcode, None) in_port["c_code_in_port"] = str(rcode) diff --git a/src/mem/slicc/ast/PeekStatementAST.py b/src/mem/slicc/ast/PeekStatementAST.py --- a/src/mem/slicc/ast/PeekStatementAST.py +++ b/src/mem/slicc/ast/PeekStatementAST.py @@ -72,7 +72,7 @@ (m_block_map.count(in_msg_ptr->m_$address_field) == 1) ) { if (m_block_map[in_msg_ptr->m_$address_field] != &$qcode) { $qcode.delayHead(); - continue; + return TransitionResult_Ignore; } } ''') diff --git a/src/mem/slicc/symbols/StateMachine.py b/src/mem/slicc/symbols/StateMachine.py --- a/src/mem/slicc/symbols/StateMachine.py +++ b/src/mem/slicc/symbols/StateMachine.py @@ -382,6 +382,9 @@ if var.type.ident == "MessageBuffer": self.message_buffer_names.append("m_%s_ptr" % var.c_ident) + for port in self.in_ports: + code('''TransitionResult $port();''') + code.dedent() code('};') code('#endif // __${ident}_CONTROLLER_H__') @@ -1043,6 +1046,7 @@ ${ident}_Controller::wakeup() { int counter = 0; + TransitionResult result = TransitionResult_NULL; while (true) { // Some cases will put us into an infinite loop without this limit assert(counter <= m_transitions_per_cycle); @@ -1056,14 +1060,40 @@ } ''') - code.indent() - code.indent() - # InPorts # for port in self.in_ports: + code(''' + + // ${ident}InPort $port + result = $port(); + if (result == TransitionResult_Valid) { + counter++; + continue; // Check the first port again + } + if (result == TransitionResult_ResourceStall) { + g_system_ptr->scheduleEvent(this, 1); + + // Cannot do anything with this transition, go check next doable transition (mostly likely of next port) + } + if (result == TransitionResult_Ignore) { + continue; + } +''') + + code(''' + break; // If we got this far, we have nothing left todo + } + // g_system_ptr->scheduleEvent(this, 1); +} +''') + for port in self.in_ports: + code(''' +TransitionResult +${ident}_Controller::$port() +{ +''') code.indent() - code('// ${ident}InPort $port') if port.pairs.has_key("rank"): code('m_cur_in_port_rank = ${{port.pairs["rank"]}};') else: @@ -1071,16 +1101,10 @@ code('${{port["c_code_in_port"]}}') code.dedent() - code('') - - code.dedent() - code.dedent() - code(''' - break; // If we got this far, we have nothing left todo - } + code(''' + return TransitionResult_NULL; } ''') - code.write(path, "%s_Wakeup.cc" % self.ident) def printCSwitch(self, path):