From 4e2216d68b14e51351c6c87708820fdeac1f1608 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tiago=20M=C3=BCck?= Date: Fri, 28 Feb 2020 15:32:00 -0600 Subject: [PATCH] mem-ruby: able to define resource stalls handlers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Input ports can specify a custom handler that is called on resource stalls. The handler should return 'true' to indicate the stall was handled and new messages from that queue can be processed on that cycle. When it returns 'false' or no handler is defined, a resource stall is generated. Handlers are defined using the 'rsc_stall_handler' (for resource stalls) and the 'prot_stall_handler' (for protocol stalls) parameters. For example: in_port(mandatory_in, RubyRequest, mandatoryQueue, rsc_stall_handler=mandatory_in_stall_handler) { ... } bool mandatory_in_stall_handler() { // Do something here to handle the stall ! return true; // or return false if we don't want to do anything } Note: this patch required a change to the generate() functions interface in the SLICC compiler, so we could propagate a reference to the in_port to the appropriate generate() functions. The updated interface allows passing and forwarding of keyword arguments. Change-Id: I3481d130d5eb411e6760a54d098d3da5de511c86 Signed-off-by: Tiago Mück Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/31265 Reviewed-by: Jason Lowe-Power Maintainer: Jason Lowe-Power Tested-by: kokoro --- src/mem/slicc/ast/AssignStatementAST.py | 2 +- .../slicc/ast/CheckAllocateStatementAST.py | 2 +- src/mem/slicc/ast/CheckNextCycleAST.py | 2 +- src/mem/slicc/ast/CheckProbeStatementAST.py | 2 +- .../slicc/ast/DeferEnqueueingStatementAST.py | 2 +- src/mem/slicc/ast/EnqueueStatementAST.py | 2 +- src/mem/slicc/ast/EnumExprAST.py | 2 +- src/mem/slicc/ast/ExprAST.py | 4 +- src/mem/slicc/ast/ExprStatementAST.py | 4 +- src/mem/slicc/ast/FuncCallExprAST.py | 61 +++++++++++++++++-- src/mem/slicc/ast/FuncDeclAST.py | 2 +- src/mem/slicc/ast/IfStatementAST.py | 6 +- src/mem/slicc/ast/InPortDeclAST.py | 14 ++++- src/mem/slicc/ast/IsValidPtrExprAST.py | 2 +- src/mem/slicc/ast/LiteralExprAST.py | 2 +- src/mem/slicc/ast/LocalVariableAST.py | 2 +- src/mem/slicc/ast/MethodCallExprAST.py | 2 +- src/mem/slicc/ast/NewExprAST.py | 2 +- src/mem/slicc/ast/ObjDeclAST.py | 2 +- src/mem/slicc/ast/OodAST.py | 2 +- src/mem/slicc/ast/OperatorExprAST.py | 4 +- src/mem/slicc/ast/PeekStatementAST.py | 4 +- src/mem/slicc/ast/ReturnStatementAST.py | 2 +- src/mem/slicc/ast/StallAndWaitStatementAST.py | 2 +- src/mem/slicc/ast/StatementListAST.py | 4 +- src/mem/slicc/ast/StaticCastAST.py | 2 +- src/mem/slicc/ast/TypeFieldEnumAST.py | 2 +- src/mem/slicc/ast/TypeFieldStateAST.py | 2 +- src/mem/slicc/ast/VarExprAST.py | 2 +- 29 files changed, 102 insertions(+), 41 deletions(-) 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)