def generate(self): resources = {} machine = self.symtab.state_machine if machine is None: self.error("Action declaration not part of a machine.") if self.statement_list: # Add new local vars self.symtab.pushFrame() addr_type = self.symtab.find("Addr", Type) if addr_type is None: self.error("Type 'Addr' not declared.") var = Var(self.symtab, "address", self.location, addr_type, "addr", self.pairs) self.symtab.newSymbol(var) #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++ #fanyao added int_type = self.symtab.find("int", Type) if int_type is None: self.error("Type 'int' not declared.") var = Var(self.symtab, "core_id", self.location, int_type, "core_id", self.pairs) self.symtab.newSymbol(var) #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++ if machine.TBEType != None: var = Var(self.symtab, "tbe", self.location, machine.TBEType, "m_tbe_ptr", self.pairs) self.symtab.newSymbol(var) if machine.EntryType != None: var = Var(self.symtab, "cache_entry", self.location, machine.EntryType, "m_cache_entry_ptr", self.pairs) self.symtab.newSymbol(var) # Do not allows returns in actions code = self.slicc.codeFormatter() self.statement_list.generate(code, None) self.pairs["c_code"] = str(code) self.statement_list.findResources(resources) self.symtab.popFrame() action = Action(self.symtab, self.ident, resources, self.location, self.pairs) machine.addAction(action)
def generate(self): resources = {} if self.statement_list: # Add new local vars self.symtab.pushFrame() addr_type = self.symtab.find("Address", Type) if addr_type is None: self.error("Type 'Address' not declared.") var = Var(self.symtab, "address", self.location, addr_type, "addr", self.pairs) self.symtab.newSymbol(var) # Do not allows returns in actions code = self.slicc.codeFormatter() self.statement_list.generate(code, None) self.pairs["c_code"] = str(code) self.statement_list.findResources(resources) self.symtab.popFrame() machine = self.symtab.state_machine if machine is None: self.error("Action declaration not part of a machine.") action = Action(self.symtab, self.ident, resources, self.location, self.pairs) machine.addAction(action)
def generate(self, code, return_type): code("{") code.indent() self.symtab.pushFrame() msg_type = self.type_ast.type # Add new local var to symbol table v = Var(self.symtab, "out_msg", self.location, msg_type, "*out_msg", self.pairs) self.symtab.newSymbol(v) # Declare message code("std::shared_ptr<${{msg_type.c_ident}}> out_msg = "\ "std::make_shared<${{msg_type.c_ident}}>(clockEdge());") # The other statements t = self.statements.generate(code, None) self.queue_name.assertType("OutPort") if self.latexpr != None: ret_type, rcode = self.latexpr.inline(True) code("(${{self.queue_name.var.code}}).enqueue(" \ "out_msg, clockEdge(), cyclesToTicks(Cycles($rcode)));") else: code("(${{self.queue_name.var.code}}).enqueue(out_msg, "\ "clockEdge(), cyclesToTicks(Cycles(1)));") # End scope self.symtab.popFrame() code.dedent() code("}")
def generate(self): type = self.type_ast.type param = "param_%s" % self.ident # Add to symbol table v = Var(self.symtab, self.ident, self.location, type, param, self.pairs) self.symtab.newSymbol(v) # Qualifier is always a pointer for TBE table and Cache entries. # It's expected to be left unspecified or specified as ptr. qualifier = self.qualifier if str(type) == "TBE" or ("interface" in type and (type["interface"] == "AbstractCacheEntry")): if qualifier not in ["", "PTR"]: self.warning("Parameter \'%s\' is always pointer. " "%s qualifier ignored" % (self.ident, qualifier)) qualifier = "PTR" # default if qualifier == "": qualifier = "CONST_REF" if qualifier == "PTR": return type, "%s* %s" % (type.c_ident, param) elif qualifier == "REF": return type, "%s& %s" % (type.c_ident, param) elif qualifier == "CONST_REF": return type, "const %s& %s" % (type.c_ident, param) else: self.error("Invalid qualifier for param \'%s\'" % self.ident)
def generate(self, code, return_type, **kwargs): code("{") code.indent() self.symtab.pushFrame() msg_type = self.type_ast.type # Add new local var to symbol table v = Var(self.symtab, "out_msg", self.location, msg_type, "*out_msg", self.pairs) self.symtab.newSymbol(v) # Declare message code("std::shared_ptr<${{msg_type.c_ident}}> out_msg = "\ "std::make_shared<${{msg_type.c_ident}}>(clockEdge());") # The other statements t = self.statements.generate(code, None) self.queue_name.assertType("OutPort") code("(${{self.queue_name.var.code}}).deferEnqueueingMessage(addr, "\ "out_msg);") # End scope self.symtab.popFrame() code.dedent() code("}")
def generate(self, parent=None): if "network" in self and not ("virtual_network" in self or "physical_network" in self): self.error("Network queues require a 'virtual_network' attribute") type = self.type_ast.type if type.isBuffer and "ordered" not in self: self.error("Buffer object decls require an 'ordered' attribute") if "ordered" in self: value = self["ordered"] if value not in ("true", "false"): self.error("The 'ordered' attribute is '%s' " + \ "must be 'true' or 'false'.", value) if "random" in self: value = self["random"] if value not in ("true", "false"): self.error("The 'random' attribute is '%s' " + \ "must be 'true' or 'false'.", value) # FIXME : should all use accessors here to avoid public member # variables if self.ident == "version": c_code = "m_version" elif self.ident == "machineID": c_code = "m_machineID" elif self.ident == "clusterID": c_code = "m_clusterID" else: c_code = "(*m_%s_ptr)" % (self.ident) # check type if this is a initialization init_code = "" if self.rvalue: rvalue_type, init_code = self.rvalue.inline(True) if type != rvalue_type: self.error("Initialization type mismatch '%s' and '%s'" % \ (type, rvalue_type)) machine = self.symtab.state_machine v = Var(self.symtab, self.ident, self.location, type, c_code, self.pairs, machine) # Add data member to the parent type if parent: if not parent.addDataMember(self.ident, type, self.pairs, init_code): self.error("Duplicate data member: %s:%s" % (parent, self.ident)) elif machine: machine.addObject(v) else: self.symtab.newSymbol(v)
def generate(self): type = self.type_ast.type param = "param_%s" % self.ident # Add to symbol table v = Var(self.symtab, self.ident, self.location, type, param, self.pairs) self.symtab.newSymbol(v) return type, "%s %s" % (type.c_ident, param)
def generate(self): machineComponentSym = False self["chip_object"] = "yes" if "hack" in self: warning("'hack=' is now deprecated") if "network" in self and "virtual_network" not in self: self.error("Network queues require a 'virtual_network' attribute") type = self.type_ast.type if type.isBuffer and "ordered" not in self: self.error("Buffer object decls require an 'ordered' attribute") if "ordered" in self: value = self["ordered"] if value not in ("true", "false"): self.error("The 'ordered' attribute is '%s' " + \ "must be 'true' or 'false'.", value) if "random" in self: value = self["random"] if value not in ("true", "false"): self.error("The 'random' attribute is '%s' " + \ "must be 'true' or 'false'.", value) machine = self.symtab.state_machine # FIXME : should all use accessors here to avoid public member # variables if self.ident == "id": c_code = "m_chip_ptr.getID()" elif self.ident == "version": c_code = "m_version" elif self.ident == "machineID": c_code = "m_machineID" elif machine: c_code = "(*m_%s_%s_ptr)" % (machine.ident, self.ident) else: c_code = "(*m_%s_ptr)" % (self.ident) v = Var(self.symtab, self.ident, self.location, type, c_code, self.pairs, machine) if machine: machine.addObject(v) self.symtab.newSymbol(v) # used to cheat-- that is, access components in other machines if machineComponentSym: self.symtab.newMachComponentSym(v)
def generate(self, code, return_type): self.symtab.pushFrame() msg_type = self.type_ast.type # Add new local var to symbol table var = Var(self.symtab, "in_msg", self.location, msg_type, "(*in_msg_ptr)", self.pairs) self.symtab.newSymbol(var) # Check the queue type self.queue_name.assertType("InPort") # Declare the new "in_msg_ptr" variable mtid = msg_type.c_ident qcode = self.queue_name.var.code code(''' { // Declare message const $mtid* in_msg_ptr M5_VAR_USED; in_msg_ptr = dynamic_cast<const $mtid *>(($qcode).${{self.method}}()); if (in_msg_ptr == NULL) { // If the cast fails, this is the wrong inport (wrong message type). // Throw an exception, and the caller will decide to either try a // different inport or punt. throw RejectException(); } ''') if self.pairs.has_key("block_on"): address_field = self.pairs['block_on'] code(''' if (m_is_blocking && (m_block_map.count(in_msg_ptr->m_$address_field) == 1) && (m_block_map[in_msg_ptr->m_$address_field] != &$qcode)) { $qcode.delayHead(); continue; } ''') if self.pairs.has_key("wake_up"): address_field = self.pairs['wake_up'] code(''' if (m_waiting_buffers.count(in_msg_ptr->m_$address_field) > 0) { wakeUpBuffers(in_msg_ptr->m_$address_field); } ''') # The other statements self.statements.generate(code, return_type) self.symtab.popFrame() code("}")
def generate(self): type = self.type_ast.type param = "param_%s" % self.ident # Add to symbol table v = Var(self.symtab, self.ident, self.location, type, param, self.pairs) self.symtab.newSymbol(v) if self.pointer or str(type) == "TBE" or ( "interface" in type and (type["interface"] == "AbstractCacheEntry" or type["interface"] == "AbstractEntry")): return type, "%s* %s" % (type.c_ident, param) else: return type, "const %s& %s" % (type.c_ident, param)
def generate(self, code, return_type): self.symtab.pushFrame() msg_type = self.type_ast.type # Add new local var to symbol table var = Var(self.symtab, "in_msg", self.location, msg_type, "(*in_msg_ptr)", self.pairs) self.symtab.newSymbol(var) # Check the queue type self.queue_name.assertType("InPort") # Declare the new "in_msg_ptr" variable mtid = msg_type.ident qcode = self.queue_name.var.code code(''' { // Declare message const $mtid* in_msg_ptr M5_VAR_USED; in_msg_ptr = dynamic_cast<const $mtid *>(($qcode).${{self.method}}()); assert(in_msg_ptr != NULL); // Check the cast result ''') if self.pairs.has_key("block_on"): address_field = self.pairs['block_on'] code(''' if ( (m_is_blocking == true) && (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; } } ''') if self.pairs.has_key("wake_up"): address_field = self.pairs['wake_up'] code(''' if (m_waiting_buffers.count(in_msg_ptr->m_$address_field) > 0) { wakeUpBuffers(in_msg_ptr->m_$address_field); } ''') # The other statements self.statements.generate(code, return_type) self.symtab.popFrame() code("}")
def generate(self, code): type = self.type_ast.type ident = "%s" % self.ident # Add to symbol table v = Var(self.symtab, self.ident, self.location, type, ident, self.pairs) self.symtab.newSymbol(v) if self.pointer or str(type) == "TBE" or ( "interface" in type and (type["interface"] == "AbstractCacheEntry" or type["interface"] == "AbstractEntry")): code += "%s* %s" % (type.c_ident, ident) else: code += "%s %s" % (type.c_ident, ident) return type
def generate(self, code): type = self.type_ast.type; ident = "%s" % self.ident; # Add to symbol table v = Var(self.symtab, self.ident, self.location, type, ident, self.pairs) self.symtab.newSymbol(v) if self.pointer or str(type) == "TBE" or ( # Check whether type is Entry by checking interface since # entries in protocol files use AbstractCacheEntry as interfaces. "interface" in type and ( type["interface"] == "AbstractCacheEntry")): code += "%s* %s" % (type.c_ident, ident) else: code += "%s %s" % (type.c_ident, ident) return type
def generate(self): code = self.slicc.codeFormatter(newlines=False) queue_type = self.var_expr.generate(code) if not queue_type.isOutPort: self.error( "The outport queue's type must have the 'outport' " + "attribute. Type '%s' does not have this attribute.", (queue_type)) if not self.symtab.find(self.msg_type.ident, Type): self.error("The message type '%s' does not exist.", self.msg_type.ident) var = Var(self.symtab, self.ident, self.location, self.queue_type.type, str(code), self.pairs) self.symtab.newSymbol(var)
def generate(self): type = self.type_ast.type param = "param_%s" % self.ident # Add to symbol table v = Var(self.symtab, self.ident, self.location, type, param, self.pairs) self.symtab.newSymbol(v) if self.pointer or str(type) == "TBE" or ( # Check whether type is entry by checking the interface since # in protocol files, entries use AbstractCacheEntry as interfaces. "interface" in type and (type["interface"] == "AbstractCacheEntry")): return type, "%s* %s" % (type.c_ident, param) else: return type, "const %s& %s" % (type.c_ident, param)
def generate(self): if "network" in self and not ("virtual_network" in self or "physical_network" in self): self.error("Network queues require a 'virtual_network' attribute") type = self.type_ast.type if type.isBuffer and "ordered" not in self: self.error("Buffer object decls require an 'ordered' attribute") if "ordered" in self: value = self["ordered"] if value not in ("true", "false"): self.error("The 'ordered' attribute is '%s' " + \ "must be 'true' or 'false'.", value) if "random" in self: value = self["random"] if value not in ("true", "false"): self.error("The 'random' attribute is '%s' " + \ "must be 'true' or 'false'.", value) machine = self.symtab.state_machine # FIXME : should all use accessors here to avoid public member # variables if self.ident == "version": c_code = "m_version" elif self.ident == "machineID": c_code = "m_machineID" elif self.ident == "clusterID": c_code = "m_clusterID" elif machine: c_code = "(*m_%s_%s_ptr)" % (machine.ident, self.ident) else: c_code = "(*m_%s_ptr)" % (self.ident) v = Var(self.symtab, self.ident, self.location, type, c_code, self.pairs, machine) if machine: machine.addObject(v) self.symtab.newSymbol(v)
def generate(self, parent = None): if "network" in self and not ("virtual_network" in self or "physical_network" in self) : self.error("Network queues require a 'virtual_network' attribute") type = self.type_ast.type # FIXME : should all use accessors here to avoid public member # variables if self.ident == "version": c_code = "m_version" elif self.ident == "machineID": c_code = "m_machineID" elif self.ident == "clusterID": c_code = "m_clusterID" elif self.ident == "recycle_latency": c_code = "m_recycle_latency" else: c_code = "(*m_%s_ptr)" % (self.ident) # check type if this is a initialization init_code = "" if self.rvalue: rvalue_type,init_code = self.rvalue.inline(True) if type != rvalue_type: self.error("Initialization type mismatch '%s' and '%s'" % \ (type, rvalue_type)) machine = self.symtab.state_machine v = Var(self.symtab, self.ident, self.location, type, c_code, self.pairs, machine) # Add data member to the parent type if parent: if not parent.addDataMember(self.ident, type, self.pairs, init_code): self.error("Duplicate data member: %s:%s" % (parent, self.ident)) elif machine: machine.addObject(v) else: self.symtab.newSymbol(v)
def generate(self, code, return_type): code("{") code.indent() self.symtab.pushFrame() msg_type = self.type_ast.type # Add new local var to symbol table v = Var(self.symtab, "out_msg", self.location, msg_type, "*out_msg", self.pairs) self.symtab.newSymbol(v) # Declare message code("${{msg_type.ident}} *out_msg = "\ "new ${{msg_type.ident}}(clockEdge());") # The other statements t = self.statements.generate(code, None) self.queue_name.assertType("OutPort") args = ["out_msg"] if "latency" in self: latency = self["latency"] try: # see if this is an integer latency = int(latency) args.append("Cycles(%s)" % latency) except ValueError: # if not, it should be a member args.append("m_%s" % latency) args = ", ".join(args) code('(${{self.queue_name.var.code}}).enqueue($args);') # End scope self.symtab.popFrame() code.dedent() code("}")
def generate(self): symtab = self.symtab void_type = symtab.find("void", Type) machine = symtab.state_machine if machine is None: self.error("InPort declaration not part of a machine.") code = self.slicc.codeFormatter() queue_type = self.var_expr.generate(code) if not queue_type.isInPort: self.error("The inport queue's type must have the 'inport' " + \ "attribute. Type '%s' does not have this attribute.", queue_type) type = self.queue_type.type in_port = Var(self.symtab, self.ident, self.location, type, str(code), self.pairs) symtab.newSymbol(in_port) symtab.pushFrame() param_types = [] # Check for Event type = symtab.find("Event", Type) if type is None: self.error("in_port decls require 'Event' enumeration defined") param_types.append(type) # Check for Address type = symtab.find("Address", Type) if type is None: self.error("in_port decls require 'Address' type to be defined") param_types.append(type) if machine.EntryType != None: param_types.append(machine.EntryType) if machine.TBEType != None: param_types.append(machine.TBEType) # Add the trigger method - FIXME, this is a bit dirty pairs = {"external": "yes"} func = Func(self.symtab, "trigger", self.location, void_type, param_types, [], "", pairs) symtab.newSymbol(func) param_types = [] # Check for Event2 type = symtab.find("Event", Type) if type is None: self.error("in_port decls require 'Event' enumeration") param_types.append(type) # Check for Address2 type = symtab.find("Address", Type) if type is None: self.error("in_port decls require 'Address' type to be defined") param_types.append(type) 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) symtab.popFrame() # Add port to state machine machine.addInPort(in_port) # Include max_rank to be used by StateMachine.py in_port["max_port_rank"] = InPortDeclAST.max_port_rank
def generate(self): symtab = self.symtab void_type = symtab.find("void", Type) machine = symtab.state_machine if machine is None: self.error("InPort declaration not part of a machine.") code = self.slicc.codeFormatter() queue_type = self.var_expr.generate(code) if not queue_type.isInPort: self.error("The inport queue's type must have the 'inport' " + \ "attribute. Type '%s' does not have this attribute.", queue_type) type = self.queue_type.type in_port = Var(self.symtab, self.ident, self.location, type, str(code), self.pairs, machine, self.var_expr) symtab.newSymbol(in_port) symtab.pushFrame() param_types = [] # Check for Event type = symtab.find("Event", Type) if type is None: self.error("in_port decls require 'Event' enumeration defined") param_types.append(type) # Check for Address type = symtab.find("Addr", Type) if type is None: self.error("in_port decls require 'Addr' type to be defined") param_types.append(type) if machine.EntryType != None: param_types.append(machine.EntryType) if machine.TBEType != None: param_types.append(machine.TBEType) # Add the trigger method - FIXME, this is a bit dirty pairs = {"external": "yes"} trigger_func_name = "trigger" for param in param_types: trigger_func_name += "_" + param.ident func = Func(self.symtab, trigger_func_name, "trigger", self.location, void_type, param_types, [], "", pairs) symtab.newSymbol(func) # Add the stallPort method - this hacks reschedules the controller # for stalled messages that don't trigger events func = Func(self.symtab, "stallPort", "stallPort", self.location, void_type, [], [], "", pairs) symtab.newSymbol(func) param_types = [] # Check for Event2 type = symtab.find("Event", Type) if type is None: self.error("in_port decls require 'Event' enumeration") param_types.append(type) # Check for Address2 type = symtab.find("Addr", Type) if type is None: self.error("in_port decls require 'Addr' type to be defined") param_types.append(type) 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) symtab.popFrame() # Add port to state machine machine.addInPort(in_port)
def generate(self): symtab = self.symtab void_type = symtab.find("void", Type) machine = symtab.state_machine if machine is None: self.error("InPort declaration not part of a machine.") code = self.slicc.codeFormatter() queue_type = self.var_expr.generate(code) if not queue_type.isInPort: self.error("The inport queue's type must have the 'inport' " + \ "attribute. Type '%s' does not have this attribute.", queue_type) type = self.queue_type.type in_port = Var(self.symtab, self.ident, self.location, type, str(code), self.pairs) symtab.newSymbol(in_port) symtab.pushFrame() param_types = [] # Check for Event type = symtab.find("Event", Type) if type is None: self.error("in_port decls require 'Event' enumeration defined") param_types.append(type) # Check for Address type = symtab.find("Address", Type) if type is None: self.error("in_port decls require 'Address' type to be defined") param_types.append(type) if machine.EntryType != None: param_types.append(machine.EntryType) if machine.TBEType != None: param_types.append(machine.TBEType) # Add the trigger method - FIXME, this is a bit dirty pairs = { "external" : "yes" } func = Func(self.symtab, "trigger", self.location, void_type, param_types, [], "", pairs) symtab.newSymbol(func) param_types = [] # Check for Event2 type = symtab.find("Event", Type) if type is None: self.error("in_port decls require 'Event' enumeration") param_types.append(type) # Check for Address2 type = symtab.find("Address", Type) if type is None: self.error("in_port decls require 'Address' type to be defined") 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, void_type, [], [], "", pairs) symtab.newSymbol(func) 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) symtab.popFrame() # Add port to state machine machine.addInPort(in_port) # Include max_rank to be used by StateMachine.py in_port["max_port_rank"] = InPortDeclAST.max_port_rank