diff --git a/src/mem/slicc/ast/AssignStatementAST.py b/src/mem/slicc/ast/AssignStatementAST.py index b959793545..d3e449d4e3 100644 --- a/src/mem/slicc/ast/AssignStatementAST.py +++ b/src/mem/slicc/ast/AssignStatementAST.py @@ -36,7 +36,7 @@ class AssignStatementAST(StatementAST): def __repr__(self): return "[AssignStatementAST: %r := %r]" % (self.lvalue, self.rvalue) - def generate(self, code, return_type): + def generate(self, code, return_type, **kwargs): lcode = self.slicc.codeFormatter() rcode = self.slicc.codeFormatter() diff --git a/src/mem/slicc/ast/CheckAllocateStatementAST.py b/src/mem/slicc/ast/CheckAllocateStatementAST.py index b96153b0a2..425e8053d7 100644 --- a/src/mem/slicc/ast/CheckAllocateStatementAST.py +++ b/src/mem/slicc/ast/CheckAllocateStatementAST.py @@ -35,7 +35,7 @@ class CheckAllocateStatementAST(StatementAST): def __repr__(self): return "[CheckAllocateStatementAst: %r]" % self.variable - def generate(self, code, return_type): + def generate(self, code, return_type, **kwargs): # FIXME - check the type of the variable # Make sure the variable is valid diff --git a/src/mem/slicc/ast/CheckNextCycleAST.py b/src/mem/slicc/ast/CheckNextCycleAST.py index 5ca869d572..f3797755e8 100644 --- a/src/mem/slicc/ast/CheckNextCycleAST.py +++ b/src/mem/slicc/ast/CheckNextCycleAST.py @@ -35,6 +35,6 @@ class CheckNextCycleAST(StatementAST): def __repr__(self): return "[CheckNextCycleAST]" - def generate(self, code, return_type): + def generate(self, code, return_type, **kwargs): code("scheduleEvent(Cycles(1));") return "CheckNextCycle" diff --git a/src/mem/slicc/ast/CheckProbeStatementAST.py b/src/mem/slicc/ast/CheckProbeStatementAST.py index 53454635a5..0d84bbce43 100644 --- a/src/mem/slicc/ast/CheckProbeStatementAST.py +++ b/src/mem/slicc/ast/CheckProbeStatementAST.py @@ -37,7 +37,7 @@ class CheckProbeStatementAST(StatementAST): def __repr__(self): return "[CheckProbeStatementAst: %r]" % self.in_port - def generate(self, code, return_type): + def generate(self, code, return_type, **kwargs): self.in_port.assertType("InPort") self.address.assertType("Addr") diff --git a/src/mem/slicc/ast/DeferEnqueueingStatementAST.py b/src/mem/slicc/ast/DeferEnqueueingStatementAST.py index 40b9a4c527..9704836273 100644 --- a/src/mem/slicc/ast/DeferEnqueueingStatementAST.py +++ b/src/mem/slicc/ast/DeferEnqueueingStatementAST.py @@ -48,7 +48,7 @@ class DeferEnqueueingStatementAST(StatementAST): return "[DeferEnqueueingStatementAst: %s %s %s]" % \ (self.queue_name, self.type_ast.ident, self.statements) - def generate(self, code, return_type): + def generate(self, code, return_type, **kwargs): code("{") code.indent() self.symtab.pushFrame() diff --git a/src/mem/slicc/ast/EnqueueStatementAST.py b/src/mem/slicc/ast/EnqueueStatementAST.py index 556643e4eb..a8c157e426 100644 --- a/src/mem/slicc/ast/EnqueueStatementAST.py +++ b/src/mem/slicc/ast/EnqueueStatementAST.py @@ -42,7 +42,7 @@ class EnqueueStatementAST(StatementAST): return "[EnqueueStatementAst: %s %s %s]" % \ (self.queue_name, self.type_ast.ident, self.statements) - def generate(self, code, return_type): + def generate(self, code, return_type, **kwargs): code("{") code.indent() self.symtab.pushFrame() diff --git a/src/mem/slicc/ast/EnumExprAST.py b/src/mem/slicc/ast/EnumExprAST.py index 9cb76a8a19..27da269e90 100644 --- a/src/mem/slicc/ast/EnumExprAST.py +++ b/src/mem/slicc/ast/EnumExprAST.py @@ -40,7 +40,7 @@ class EnumExprAST(ExprAST): def __repr__(self): return "[EnumExpr: %s:%s]" % (self.type_ast, self.value) - def generate(self, code): + def generate(self, code, **kwargs): fix = code.nofix() code('${{self.type_ast.type.c_ident}}_${{self.value}}') code.fix(fix) diff --git a/src/mem/slicc/ast/ExprAST.py b/src/mem/slicc/ast/ExprAST.py index 393101112d..75554b2d3f 100644 --- a/src/mem/slicc/ast/ExprAST.py +++ b/src/mem/slicc/ast/ExprAST.py @@ -34,9 +34,9 @@ class ExprAST(AST): # The default is no resources pass - def inline(self, get_type=False): + def inline(self, get_type=False, **kwargs): code = self.slicc.codeFormatter(fix_newlines=False) - return_type = self.generate(code) + return_type = self.generate(code, **kwargs) if get_type: return return_type, code else: diff --git a/src/mem/slicc/ast/ExprStatementAST.py b/src/mem/slicc/ast/ExprStatementAST.py index 6c77522c78..7189df0401 100644 --- a/src/mem/slicc/ast/ExprStatementAST.py +++ b/src/mem/slicc/ast/ExprStatementAST.py @@ -38,8 +38,8 @@ class ExprStatementAST(StatementAST): def __repr__(self): return "[ExprStatementAST: %s]" % (self.expr) - def generate(self, code, return_type): - actual_type,rcode = self.expr.inline(True) + def generate(self, code, return_type, **kwargs): + actual_type,rcode = self.expr.inline(True, **kwargs) code("$rcode;") # The return type must be void, except for local var decls diff --git a/src/mem/slicc/ast/FuncCallExprAST.py b/src/mem/slicc/ast/FuncCallExprAST.py index b3cc9f1ec8..d93ee04e96 100644 --- a/src/mem/slicc/ast/FuncCallExprAST.py +++ b/src/mem/slicc/ast/FuncCallExprAST.py @@ -1,3 +1,15 @@ +# Copyright (c) 2020 ARM Limited +# All rights reserved. +# +# The license below extends only to copyright in the software and shall +# not be construed as granting a license to any other intellectual +# property including but not limited to intellectual property relating +# to a hardware implementation of the functionality of the software +# licensed hereunder. You may use the software subject to the license +# terms below provided that you ensure that this notice is replicated +# unmodified and in its entirety in all distributions of the software, +# modified or unmodified, in source code or in binary form. +# # Copyright (c) 1999-2008 Mark D. Hill and David A. Wood # Copyright (c) 2009 The Hewlett-Packard Development Company # Copyright (c) 2013 Advanced Micro Devices, Inc. @@ -38,7 +50,9 @@ class FuncCallExprAST(ExprAST): def __repr__(self): return "[FuncCallExpr: %s %s]" % (self.proc_name, self.exprs) - def generate(self, code): + # When calling generate for statements in a in_port, the reference to + # the port must be provided as the in_port kwarg (see InPortDeclAST) + def generate(self, code, **kwargs): machine = self.state_machine if self.proc_name == "DPRINTF": @@ -148,18 +162,53 @@ class FuncCallExprAST(ExprAST): TransitionResult result = doTransition(${{cvec[0]}}, ${{cvec[1]}}); ''') + assert('in_port' in kwargs) + in_port = kwargs['in_port'] + code(''' if (result == TransitionResult_Valid) { counter++; continue; // Check the first port again - } - - if (result == TransitionResult_ResourceStall || - result == TransitionResult_ProtocolStall) { + } else if (result == TransitionResult_ResourceStall) { +''') + if 'rsc_stall_handler' in in_port.pairs: + stall_func_name = in_port.pairs['rsc_stall_handler'] + code(''' + if (${{stall_func_name}}()) { + counter++; + continue; // Check the first port again + } else { + scheduleEvent(Cycles(1)); + // Cannot do anything with this transition, go check next doable transition (mostly likely of next port) + } +''') + else: + code(''' scheduleEvent(Cycles(1)); - // Cannot do anything with this transition, go check next doable transition (mostly likely of next port) +''') + code(''' + } else if (result == TransitionResult_ProtocolStall) { +''') + if 'prot_stall_handler' in in_port.pairs: + stall_func_name = in_port.pairs['prot_stall_handler'] + code(''' + if (${{stall_func_name}}()) { + counter++; + continue; // Check the first port again + } else { + scheduleEvent(Cycles(1)); + // Cannot do anything with this transition, go check next doable transition (mostly likely of next port) + } +''') + else: + code(''' + scheduleEvent(Cycles(1)); + // Cannot do anything with this transition, go check next doable transition (mostly likely of next port) +''') + code(''' } + } ''') elif self.proc_name == "error": diff --git a/src/mem/slicc/ast/FuncDeclAST.py b/src/mem/slicc/ast/FuncDeclAST.py index 47ae7076ef..675c408134 100644 --- a/src/mem/slicc/ast/FuncDeclAST.py +++ b/src/mem/slicc/ast/FuncDeclAST.py @@ -43,7 +43,7 @@ class FuncDeclAST(DeclAST): def files(self, parent=None): return set() - def generate(self, parent = None): + def generate(self, parent = None, **kwargs): types = [] params = [] void_type = self.symtab.find("void", Type) diff --git a/src/mem/slicc/ast/IfStatementAST.py b/src/mem/slicc/ast/IfStatementAST.py index 3ad3d182d7..2ddd7c0525 100644 --- a/src/mem/slicc/ast/IfStatementAST.py +++ b/src/mem/slicc/ast/IfStatementAST.py @@ -42,7 +42,7 @@ class IfStatementAST(StatementAST): def __repr__(self): return "[IfStatement: %r%r%r]" % (self.cond, self.then, self.else_) - def generate(self, code, return_type): + def generate(self, code, return_type, **kwargs): cond_code = self.slicc.codeFormatter() cond_type = self.cond.generate(cond_code) @@ -56,7 +56,7 @@ class IfStatementAST(StatementAST): # Then part code.indent() self.symtab.pushFrame() - self.then.generate(code, return_type) + self.then.generate(code, return_type, **kwargs) self.symtab.popFrame() code.dedent() # Else part @@ -64,7 +64,7 @@ class IfStatementAST(StatementAST): code('} else {') code.indent() self.symtab.pushFrame() - self.else_.generate(code, return_type) + self.else_.generate(code, return_type, **kwargs) self.symtab.popFrame() code.dedent() code('}') # End scope diff --git a/src/mem/slicc/ast/InPortDeclAST.py b/src/mem/slicc/ast/InPortDeclAST.py index e0aa25236e..8e80b6ad1c 100644 --- a/src/mem/slicc/ast/InPortDeclAST.py +++ b/src/mem/slicc/ast/InPortDeclAST.py @@ -1,3 +1,15 @@ +# Copyright (c) 2020 ARM Limited +# All rights reserved. +# +# The license below extends only to copyright in the software and shall +# not be construed as granting a license to any other intellectual +# property including but not limited to intellectual property relating +# to a hardware implementation of the functionality of the software +# licensed hereunder. You may use the software subject to the license +# terms below provided that you ensure that this notice is replicated +# unmodified and in its entirety in all distributions of the software, +# modified or unmodified, in source code or in binary form. +# # Copyright (c) 1999-2008 Mark D. Hill and David A. Wood # Copyright (c) 2009 The Hewlett-Packard Development Company # All rights reserved. @@ -118,7 +130,7 @@ class InPortDeclAST(DeclAST): rcode = self.slicc.codeFormatter() rcode.indent() rcode.indent() - self.statements.generate(rcode, None) + self.statements.generate(rcode, None, in_port=in_port) in_port["c_code_in_port"] = str(rcode) symtab.popFrame() diff --git a/src/mem/slicc/ast/IsValidPtrExprAST.py b/src/mem/slicc/ast/IsValidPtrExprAST.py index e68e084c05..a7d89a9b83 100644 --- a/src/mem/slicc/ast/IsValidPtrExprAST.py +++ b/src/mem/slicc/ast/IsValidPtrExprAST.py @@ -38,7 +38,7 @@ class IsValidPtrExprAST(ExprAST): def __repr__(self): return "[IsValidPtrExprAST: %r]" % self.variable - def generate(self, code): + def generate(self, code, **kwargs): # Make sure the variable is valid fix = code.nofix() code("(") diff --git a/src/mem/slicc/ast/LiteralExprAST.py b/src/mem/slicc/ast/LiteralExprAST.py index 6d259c17f9..59756b173f 100644 --- a/src/mem/slicc/ast/LiteralExprAST.py +++ b/src/mem/slicc/ast/LiteralExprAST.py @@ -37,7 +37,7 @@ class LiteralExprAST(ExprAST): def __repr__(self): return "[Literal: %s]" % self.literal - def generate(self, code): + def generate(self, code, **kwargs): fix = code.nofix() if self.type == "std::string": code('("${{self.literal}}")') diff --git a/src/mem/slicc/ast/LocalVariableAST.py b/src/mem/slicc/ast/LocalVariableAST.py index c1a5fdbd96..da75477c89 100644 --- a/src/mem/slicc/ast/LocalVariableAST.py +++ b/src/mem/slicc/ast/LocalVariableAST.py @@ -52,7 +52,7 @@ class LocalVariableAST(StatementAST): else: return code - def generate(self, code): + def generate(self, code, **kwargs): type = self.type_ast.type; ident = "%s" % self.ident; diff --git a/src/mem/slicc/ast/MethodCallExprAST.py b/src/mem/slicc/ast/MethodCallExprAST.py index 102ab6e4c9..9908fc815c 100644 --- a/src/mem/slicc/ast/MethodCallExprAST.py +++ b/src/mem/slicc/ast/MethodCallExprAST.py @@ -33,7 +33,7 @@ class MethodCallExprAST(ExprAST): self.proc_name = proc_name self.expr_ast_vec = expr_ast_vec - def generate(self, code): + def generate(self, code, **kwargs): tmp = self.slicc.codeFormatter() paramTypes = [] for expr_ast in self.expr_ast_vec: diff --git a/src/mem/slicc/ast/NewExprAST.py b/src/mem/slicc/ast/NewExprAST.py index a423507683..2f33bfac35 100644 --- a/src/mem/slicc/ast/NewExprAST.py +++ b/src/mem/slicc/ast/NewExprAST.py @@ -39,7 +39,7 @@ class NewExprAST(ExprAST): def name(self): return str(self.type_ast) - def generate(self, code): + def generate(self, code, **kwargs): type = self.type_ast.type fix = code.nofix() code("new ${{type.c_ident}}") diff --git a/src/mem/slicc/ast/ObjDeclAST.py b/src/mem/slicc/ast/ObjDeclAST.py index efc7ef9280..523a491abc 100644 --- a/src/mem/slicc/ast/ObjDeclAST.py +++ b/src/mem/slicc/ast/ObjDeclAST.py @@ -40,7 +40,7 @@ class ObjDeclAST(DeclAST): def __repr__(self): return "[ObjDecl: %r]" % self.ident - def generate(self, parent = None): + def generate(self, parent = None, **kwargs): if "network" in self and not ("virtual_network" in self or "physical_network" in self) : self.error("Network queues require a 'virtual_network' attribute") diff --git a/src/mem/slicc/ast/OodAST.py b/src/mem/slicc/ast/OodAST.py index 0f4cf141c4..173a1566e2 100644 --- a/src/mem/slicc/ast/OodAST.py +++ b/src/mem/slicc/ast/OodAST.py @@ -35,6 +35,6 @@ class OodAST(ExprAST): def __repr__(self): return "[Ood:]" - def generate(self, code): + def generate(self, code, **kwargs): code += "NULL" return "OOD" diff --git a/src/mem/slicc/ast/OperatorExprAST.py b/src/mem/slicc/ast/OperatorExprAST.py index cab13692c0..5c5ea834f0 100644 --- a/src/mem/slicc/ast/OperatorExprAST.py +++ b/src/mem/slicc/ast/OperatorExprAST.py @@ -39,7 +39,7 @@ class InfixOperatorExprAST(ExprAST): def __repr__(self): return "[InfixExpr: %r %s %r]" % (self.left, self.op, self.right) - def generate(self, code): + def generate(self, code, **kwargs): lcode = self.slicc.codeFormatter() rcode = self.slicc.codeFormatter() @@ -104,7 +104,7 @@ class PrefixOperatorExprAST(ExprAST): def __repr__(self): return "[PrefixExpr: %s %r]" % (self.op, self.operand) - def generate(self, code): + def generate(self, code, **kwargs): opcode = self.slicc.codeFormatter() optype = self.operand.generate(opcode) diff --git a/src/mem/slicc/ast/PeekStatementAST.py b/src/mem/slicc/ast/PeekStatementAST.py index 20e5140102..2ad182ff4f 100644 --- a/src/mem/slicc/ast/PeekStatementAST.py +++ b/src/mem/slicc/ast/PeekStatementAST.py @@ -42,7 +42,7 @@ class PeekStatementAST(StatementAST): return "[PeekStatementAST: %r queue_name: %r type: %r %r]" % \ (self.method, self.queue_name, self.type_ast, self.statements) - def generate(self, code, return_type): + def generate(self, code, return_type, **kwargs): self.symtab.pushFrame() msg_type = self.type_ast.type @@ -91,7 +91,7 @@ class PeekStatementAST(StatementAST): ''') # The other statements - self.statements.generate(code, return_type) + self.statements.generate(code, return_type, **kwargs) self.symtab.popFrame() code("}") diff --git a/src/mem/slicc/ast/ReturnStatementAST.py b/src/mem/slicc/ast/ReturnStatementAST.py index 754bb4c9fd..415d442c7d 100644 --- a/src/mem/slicc/ast/ReturnStatementAST.py +++ b/src/mem/slicc/ast/ReturnStatementAST.py @@ -36,7 +36,7 @@ class ReturnStatementAST(StatementAST): def __repr__(self): return "[ReturnStatementAST: %r]" % self.expr_ast - def generate(self, code, return_type): + def generate(self, code, return_type, **kwargs): actual_type, ecode = self.expr_ast.inline(True) code('return $ecode;') diff --git a/src/mem/slicc/ast/StallAndWaitStatementAST.py b/src/mem/slicc/ast/StallAndWaitStatementAST.py index ad261e26f3..04d9e20ed0 100644 --- a/src/mem/slicc/ast/StallAndWaitStatementAST.py +++ b/src/mem/slicc/ast/StallAndWaitStatementAST.py @@ -37,7 +37,7 @@ class StallAndWaitStatementAST(StatementAST): def __repr__(self): return "[StallAndWaitStatementAst: %r]" % self.in_port - def generate(self, code, return_type): + def generate(self, code, return_type, **kwargs): self.in_port.assertType("InPort") self.address.assertType("Addr") diff --git a/src/mem/slicc/ast/StatementListAST.py b/src/mem/slicc/ast/StatementListAST.py index 1475c5c977..9d74e66dc3 100644 --- a/src/mem/slicc/ast/StatementListAST.py +++ b/src/mem/slicc/ast/StatementListAST.py @@ -37,9 +37,9 @@ class StatementListAST(AST): def __repr__(self): return "[StatementListAST: %r]" % self.statements - def generate(self, code, return_type): + def generate(self, code, return_type, **kwargs): for statement in self.statements: - statement.generate(code, return_type) + statement.generate(code, return_type, **kwargs) def findResources(self, resources): for statement in self.statements: diff --git a/src/mem/slicc/ast/StaticCastAST.py b/src/mem/slicc/ast/StaticCastAST.py index 71280ba67a..4c664865a1 100644 --- a/src/mem/slicc/ast/StaticCastAST.py +++ b/src/mem/slicc/ast/StaticCastAST.py @@ -37,7 +37,7 @@ class StaticCastAST(ExprAST): def __repr__(self): return "[StaticCastAST: %r]" % self.expr_ast - def generate(self, code): + def generate(self, code, **kwargs): actual_type, ecode = self.expr_ast.inline(True) if self.type_modifier == "pointer": code('static_cast<${{self.type_ast.type.c_ident}} *>($ecode)') diff --git a/src/mem/slicc/ast/TypeFieldEnumAST.py b/src/mem/slicc/ast/TypeFieldEnumAST.py index b9a8ae80fc..f554990579 100644 --- a/src/mem/slicc/ast/TypeFieldEnumAST.py +++ b/src/mem/slicc/ast/TypeFieldEnumAST.py @@ -38,7 +38,7 @@ class TypeFieldEnumAST(TypeFieldAST): def __repr__(self): return "[TypeFieldEnum: %r]" % self.field_id - def generate(self, type): + def generate(self, type, **kwargs): if str(type) == "State": self.error("States must in a State Declaration, not a normal enum.") diff --git a/src/mem/slicc/ast/TypeFieldStateAST.py b/src/mem/slicc/ast/TypeFieldStateAST.py index deac143bb9..ff1ae9720a 100644 --- a/src/mem/slicc/ast/TypeFieldStateAST.py +++ b/src/mem/slicc/ast/TypeFieldStateAST.py @@ -40,7 +40,7 @@ class TypeFieldStateAST(TypeFieldAST): def __repr__(self): return "[TypeFieldState: %r]" % self.field_id - def generate(self, type): + def generate(self, type, **kwargs): if not str(type) == "State": self.error("State Declaration must be of type State.") diff --git a/src/mem/slicc/ast/VarExprAST.py b/src/mem/slicc/ast/VarExprAST.py index 19a619b370..f555c72d14 100644 --- a/src/mem/slicc/ast/VarExprAST.py +++ b/src/mem/slicc/ast/VarExprAST.py @@ -60,7 +60,7 @@ class VarExprAST(ExprAST): "'%s' is expected to be type '%s' not '%s'", self.var.ident, expected_type, self.var.type) - def generate(self, code): + def generate(self, code, **kwargs): fix = code.nofix() code("${{self.var.code}}") code.fix(fix)