params.py (3103:330ec058b026) | params.py (3105:993f1abefd67) |
---|---|
1# Copyright (c) 2004-2006 The Regents of The University of Michigan 2# All rights reserved. 3# 4# Redistribution and use in source and binary forms, with or without 5# modification, are permitted provided that the following conditions are 6# met: redistributions of source code must retain the above copyright 7# notice, this list of conditions and the following disclaimer; 8# redistributions in binary form must reproduce the above copyright --- 738 unchanged lines hidden (view full) --- 747# 748# Ports are used to interconnect objects in the memory system. 749# 750##################################################################### 751 752# Port reference: encapsulates a reference to a particular port on a 753# particular SimObject. 754class PortRef(object): | 1# Copyright (c) 2004-2006 The Regents of The University of Michigan 2# All rights reserved. 3# 4# Redistribution and use in source and binary forms, with or without 5# modification, are permitted provided that the following conditions are 6# met: redistributions of source code must retain the above copyright 7# notice, this list of conditions and the following disclaimer; 8# redistributions in binary form must reproduce the above copyright --- 738 unchanged lines hidden (view full) --- 747# 748# Ports are used to interconnect objects in the memory system. 749# 750##################################################################### 751 752# Port reference: encapsulates a reference to a particular port on a 753# particular SimObject. 754class PortRef(object): |
755 def __init__(self, simobj, name, isVec): 756 assert(isSimObject(simobj)) | 755 def __init__(self, simobj, name): 756 assert(isSimObject(simobj) or isSimObjectClass(simobj)) |
757 self.simobj = simobj 758 self.name = name | 757 self.simobj = simobj 758 self.name = name |
759 self.index = -1 760 self.isVec = isVec # is this a vector port? | |
761 self.peer = None # not associated with another port yet 762 self.ccConnected = False # C++ port connection done? | 759 self.peer = None # not associated with another port yet 760 self.ccConnected = False # C++ port connection done? |
761 self.index = -1 # always -1 for non-vector ports |
|
763 764 def __str__(self): | 762 763 def __str__(self): |
765 ext = '' 766 if self.isVec: 767 ext = '[%d]' % self.index 768 return '%s.%s%s' % (self.simobj.path(), self.name, ext) | 764 return '%s.%s' % (self.simobj, self.name) |
769 | 765 |
770 # Set peer port reference. Called via __setattr__ as a result of 771 # a port assignment, e.g., "obj1.port1 = obj2.port2". 772 def setPeer(self, other): 773 if self.isVec: 774 curMap = self.simobj._port_map.get(self.name, []) 775 self.index = len(curMap) 776 curMap.append(other) 777 else: 778 curMap = self.simobj._port_map.get(self.name) 779 if curMap and not self.isVec: 780 print "warning: overwriting port", self.simobj, self.name 781 curMap = other 782 self.simobj._port_map[self.name] = curMap | 766 # for config.ini, print peer's name (not ours) 767 def ini_str(self): 768 return str(self.peer) 769 770 def __getattr__(self, attr): 771 if attr == 'peerObj': 772 # shorthand for proxies 773 return self.peer.simobj 774 raise AttributeError, "'%s' object has no attribute '%s'" % \ 775 (self.__class__.__name__, attr) 776 777 # Full connection is symmetric (both ways). Called via 778 # SimObject.__setattr__ as a result of a port assignment, e.g., 779 # "obj1.portA = obj2.portB", or via VectorPortRef.__setitem__, 780 # e.g., "obj1.portA[3] = obj2.portB". 781 def connect(self, other): 782 if isinstance(other, VectorPortRef): 783 # reference to plain VectorPort is implicit append 784 other = other._get_next() 785 if not (isinstance(other, PortRef) or proxy.isproxy(other)): 786 raise TypeError, \ 787 "assigning non-port reference '%s' to port '%s'" \ 788 % (other, self) 789 if self.peer and not proxy.isproxy(self.peer): 790 print "warning: overwriting port", self, \ 791 "value", self.peer, "with", other |
783 self.peer = other | 792 self.peer = other |
793 assert(not isinstance(self.peer, VectorPortRef)) 794 if isinstance(other, PortRef) and other.peer is not self: 795 other.connect(self) |
|
784 | 796 |
785 def clone(self, memo): | 797 def clone(self, simobj, memo): 798 if memo.has_key(self): 799 return memo[self] |
786 newRef = copy.copy(self) | 800 newRef = copy.copy(self) |
801 memo[self] = newRef 802 newRef.simobj = simobj |
|
787 assert(isSimObject(newRef.simobj)) | 803 assert(isSimObject(newRef.simobj)) |
788 newRef.simobj = newRef.simobj(_memo=memo) 789 # Tricky: if I'm the *second* PortRef in the pair to be 790 # cloned, then my peer is still in the middle of its clone 791 # method, and thus hasn't returned to its owner's 792 # SimObject.__init__ to get installed in _port_map. As a 793 # result I have no way of finding the *new* peer object. So I 794 # mark myself as "waiting" for my peer, and I let the *first* 795 # PortRef clone call set up both peer pointers after I return. 796 newPeer = newRef.simobj._port_map.get(self.name) 797 if newPeer: 798 if self.isVec: 799 assert(self.index != -1) 800 newPeer = newPeer[self.index] 801 # other guy is all set up except for his peer pointer 802 assert(newPeer.peer == -1) # peer must be waiting for handshake 803 newPeer.peer = newRef 804 newRef.peer = newPeer 805 else: 806 # other guy is in clone; just wait for him to do the work 807 newRef.peer = -1 # mark as waiting for handshake | 804 if self.peer and not proxy.isproxy(self.peer): 805 peerObj = memo[self.peer.simobj] 806 newRef.peer = self.peer.clone(peerObj, memo) 807 assert(not isinstance(newRef.peer, VectorPortRef)) |
808 return newRef 809 | 808 return newRef 809 |
810 def unproxy(self, simobj): 811 assert(simobj is self.simobj) 812 if proxy.isproxy(self.peer): 813 try: 814 realPeer = self.peer.unproxy(self.simobj) 815 except: 816 print "Error in unproxying port '%s' of %s" % \ 817 (self.name, self.simobj.path()) 818 raise 819 self.connect(realPeer) 820 |
|
810 # Call C++ to create corresponding port connection between C++ objects 811 def ccConnect(self): 812 if self.ccConnected: # already done this 813 return 814 peer = self.peer 815 cc_main.connectPorts(self.simobj.getCCObject(), self.name, self.index, 816 peer.simobj.getCCObject(), peer.name, peer.index) 817 self.ccConnected = True 818 peer.ccConnected = True 819 | 821 # Call C++ to create corresponding port connection between C++ objects 822 def ccConnect(self): 823 if self.ccConnected: # already done this 824 return 825 peer = self.peer 826 cc_main.connectPorts(self.simobj.getCCObject(), self.name, self.index, 827 peer.simobj.getCCObject(), peer.name, peer.index) 828 self.ccConnected = True 829 peer.ccConnected = True 830 |
831# A reference to an individual element of a VectorPort... much like a 832# PortRef, but has an index. 833class VectorPortElementRef(PortRef): 834 def __init__(self, simobj, name, index): 835 PortRef.__init__(self, simobj, name) 836 self.index = index 837 838 def __str__(self): 839 return '%s.%s[%d]' % (self.simobj, self.name, self.index) 840 841# A reference to a complete vector-valued port (not just a single element). 842# Can be indexed to retrieve individual VectorPortElementRef instances. 843class VectorPortRef(object): 844 def __init__(self, simobj, name): 845 assert(isSimObject(simobj) or isSimObjectClass(simobj)) 846 self.simobj = simobj 847 self.name = name 848 self.elements = [] 849 850 # for config.ini, print peer's name (not ours) 851 def ini_str(self): 852 return ' '.join([el.ini_str() for el in self.elements]) 853 854 def __getitem__(self, key): 855 if not isinstance(key, int): 856 raise TypeError, "VectorPort index must be integer" 857 if key >= len(self.elements): 858 # need to extend list 859 ext = [VectorPortElementRef(self.simobj, self.name, i) 860 for i in range(len(self.elements), key+1)] 861 self.elements.extend(ext) 862 return self.elements[key] 863 864 def _get_next(self): 865 return self[len(self.elements)] 866 867 def __setitem__(self, key, value): 868 if not isinstance(key, int): 869 raise TypeError, "VectorPort index must be integer" 870 self[key].connect(value) 871 872 def connect(self, other): 873 # reference to plain VectorPort is implicit append 874 self._get_next().connect(other) 875 876 def unproxy(self, simobj): 877 [el.unproxy(simobj) for el in self.elements] 878 879 def ccConnect(self): 880 [el.ccConnect() for el in self.elements] 881 |
|
820# Port description object. Like a ParamDesc object, this represents a 821# logical port in the SimObject class, not a particular port on a 822# SimObject instance. The latter are represented by PortRef objects. 823class Port(object): | 882# Port description object. Like a ParamDesc object, this represents a 883# logical port in the SimObject class, not a particular port on a 884# SimObject instance. The latter are represented by PortRef objects. 885class Port(object): |
824 def __init__(self, desc): 825 self.desc = desc 826 self.isVec = False | 886 # Port("description") or Port(default, "description") 887 def __init__(self, *args): 888 if len(args) == 1: 889 self.desc = args[0] 890 elif len(args) == 2: 891 self.default = args[0] 892 self.desc = args[1] 893 else: 894 raise TypeError, 'wrong number of arguments' 895 # self.name is set by SimObject class on assignment 896 # e.g., pio_port = Port("blah") sets self.name to 'pio_port' |
827 828 # Generate a PortRef for this port on the given SimObject with the 829 # given name | 897 898 # Generate a PortRef for this port on the given SimObject with the 899 # given name |
830 def makeRef(self, simobj, name): 831 return PortRef(simobj, name, self.isVec) | 900 def makeRef(self, simobj): 901 return PortRef(simobj, self.name) |
832 833 # Connect an instance of this port (on the given SimObject with 834 # the given name) with the port described by the supplied PortRef | 902 903 # Connect an instance of this port (on the given SimObject with 904 # the given name) with the port described by the supplied PortRef |
835 def connect(self, simobj, name, ref): 836 if not isinstance(ref, PortRef): 837 raise TypeError, \ 838 "assigning non-port reference port '%s'" % name 839 myRef = self.makeRef(simobj, name) 840 myRef.setPeer(ref) 841 ref.setPeer(myRef) | 905 def connect(self, simobj, ref): 906 self.makeRef(simobj).connect(ref) |
842 843# VectorPort description object. Like Port, but represents a vector 844# of connections (e.g., as on a Bus). 845class VectorPort(Port): | 907 908# VectorPort description object. Like Port, but represents a vector 909# of connections (e.g., as on a Bus). 910class VectorPort(Port): |
846 def __init__(self, desc): 847 Port.__init__(self, desc) | 911 def __init__(self, *args): 912 Port.__init__(self, *args) |
848 self.isVec = True 849 | 913 self.isVec = True 914 |
915 def makeRef(self, simobj): 916 return VectorPortRef(simobj, self.name) |
|
850 | 917 |
918 919 |
|
851__all__ = ['Param', 'VectorParam', 852 'Enum', 'Bool', 'String', 'Float', 853 'Int', 'Unsigned', 'Int8', 'UInt8', 'Int16', 'UInt16', 854 'Int32', 'UInt32', 'Int64', 'UInt64', 855 'Counter', 'Addr', 'Tick', 'Percent', 856 'TcpPort', 'UdpPort', 'EthernetAddr', 857 'MemorySize', 'MemorySize32', 858 'Latency', 'Frequency', 'RootClock', 'Clock', 859 'NetworkBandwidth', 'MemoryBandwidth', 860 'Range', 'AddrRange', 'TickRange', 861 'MaxAddr', 'MaxTick', 'AllMemory', 862 'NextEthernetAddr', 'NULL', 863 'Port', 'VectorPort'] 864 865# see comment on imports at end of __init__.py. 866from SimObject import isSimObject, isSimObjectSequence, isSimObjectClass 867import proxy 868import objects 869import cc_main | 920__all__ = ['Param', 'VectorParam', 921 'Enum', 'Bool', 'String', 'Float', 922 'Int', 'Unsigned', 'Int8', 'UInt8', 'Int16', 'UInt16', 923 'Int32', 'UInt32', 'Int64', 'UInt64', 924 'Counter', 'Addr', 'Tick', 'Percent', 925 'TcpPort', 'UdpPort', 'EthernetAddr', 926 'MemorySize', 'MemorySize32', 927 'Latency', 'Frequency', 'RootClock', 'Clock', 928 'NetworkBandwidth', 'MemoryBandwidth', 929 'Range', 'AddrRange', 'TickRange', 930 'MaxAddr', 'MaxTick', 'AllMemory', 931 'NextEthernetAddr', 'NULL', 932 'Port', 'VectorPort'] 933 934# see comment on imports at end of __init__.py. 935from SimObject import isSimObject, isSimObjectSequence, isSimObjectClass 936import proxy 937import objects 938import cc_main |