77from amaranth .lib .wiring import Out
88
99from .. import ChipFlowError
10- from ._utils import InputIOSignature , OutputIOSignature , BidirIOSignature , IOModelOptions , _chipflow_schema_uri , amaranth_annotate
10+ from ._utils import InputIOSignature , OutputIOSignature , BidirIOSignature , IOModelOptions , _chipflow_schema_uri
11+ from ._annotate import amaranth_annotate
1112
12- SIM_ANNOTATION_SCHEMA = str (_chipflow_schema_uri ("sim-interface" , 0 ))
13+ SIM_ANNOTATION_SCHEMA = str (_chipflow_schema_uri ("simulatable-interface" , 0 ))
14+ SIM_DATA_SCHEMA = str (_chipflow_schema_uri ("simulatable-data" , 0 ))
1315
1416class SimInterface (TypedDict ):
1517 uid : str
1618 parameters : dict
1719
20+ class SimData (TypedDict ):
21+ file_name : str
22+ offset : int
23+
1824_VALID_UID = re .compile ('[a-zA-Z_.]' ).search
1925
26+ def _unpack_dict (d : dict ) -> str :
27+ params = [ f"{ k } ={ repr (v )} " for k ,v in d .items ()]
28+ return ', ' .join (params )
29+
2030"""
2131Attributes:
2232 __chipflow_parameters__: list of tuples (name, value).
2333 It is expected that a model that takes parameters is implmemted as a template, with the parameters in the order
2434 given.
2535"""
26- def sim_annotate (base = "com.chipflow.chipflow_lib" ):
36+ def simulatable_interface (base = "com.chipflow.chipflow_lib" ):
2737 def decorate (klass ):
2838 assert _VALID_UID (base )
2939 dec = amaranth_annotate (SimInterface , SIM_ANNOTATION_SCHEMA )
3040 klass = dec (klass )
3141
3242 def new_init (self ,* args , ** kwargs ):
33- print ("called new_init" )
3443 original_init (self , * args , ** kwargs )
3544 self .__chipflow_annotation__ = {
3645 "uid" : klass .__chipflow_uid__ ,
3746 "parameters" : self .__chipflow_parameters__ (),
3847 }
3948
49+ def repr (self ) -> str :
50+ return f"{ klass .__name__ } ({ _unpack_dict (self .__chipflow_parameters__ ())} , { _unpack_dict (self ._options )} )"
51+
4052 original_init = klass .__init__
4153 klass .__init__ = new_init
4254 klass .__chipflow_uid__ = f"{ base } .{ klass .__name__ } "
4355 if not hasattr (klass , '__chipflow_parameters__' ):
4456 klass .__chipflow_parameters__ = lambda self : []
57+ if not klass .__repr__ :
58+ klass .__repr__ = repr
4559 return klass
4660 return decorate
4761
4862
49- @sim_annotate ()
63+ @simulatable_interface ()
5064class JTAGSignature (wiring .Signature ):
5165 def __init__ (self , ** kwargs : Unpack [IOModelOptions ]):
5266 super ().__init__ ({
@@ -58,7 +72,7 @@ def __init__(self, **kwargs: Unpack[IOModelOptions]):
5872 })
5973
6074
61- @sim_annotate ()
75+ @simulatable_interface ()
6276class SPISignature (wiring .Signature ):
6377 def __init__ (self , ** kwargs : Unpack [IOModelOptions ]):
6478 super ().__init__ ({
@@ -68,7 +82,7 @@ def __init__(self, **kwargs: Unpack[IOModelOptions]):
6882 "csn" : Out (OutputIOSignature (1 )),
6983 })
7084
71- @sim_annotate ()
85+ @simulatable_interface ()
7286class QSPIFlashSignature (wiring .Signature ):
7387 def __init__ (self , ** kwargs : Unpack [IOModelOptions ]):
7488 super ().__init__ ({
@@ -77,51 +91,40 @@ def __init__(self, **kwargs: Unpack[IOModelOptions]):
7791 "d" : Out (BidirIOSignature (4 , individual_oe = True )),
7892 })
7993
80- @sim_annotate ()
94+ @simulatable_interface ()
8195class UARTSignature (wiring .Signature ):
8296 def __init__ (self , ** kwargs : Unpack [IOModelOptions ]):
8397 super ().__init__ ({
8498 "tx" : Out (OutputIOSignature (1 )),
8599 "rx" : Out (InputIOSignature (1 )),
86100 })
87101
88- @sim_annotate ()
102+ @simulatable_interface ()
89103class I2CSignature (wiring .Signature ):
90104 def __init__ (self , ** kwargs : Unpack [IOModelOptions ]):
91105 super ().__init__ ({
92- "scl" : Out (BidirIOSignature (1 )),
93- "sda" : Out (BidirIOSignature (1 ))
94- })
106+ "scl" : Out (BidirIOSignature (1 )),
107+ "sda" : Out (BidirIOSignature (1 ))
108+ })
109+ self ._options = kwargs
110+
95111
96- @sim_annotate ()
112+ @simulatable_interface ()
97113class GPIOSignature (wiring .Signature ):
98114
99115 def __init__ (self , pin_count = 1 , ** kwargs : Unpack [IOModelOptions ]):
100- if pin_count > 32 :
101- raise ValueError (f"Pin pin_count must be lesser than or equal to 32, not { pin_count } " )
102116 self ._pin_count = pin_count
117+ self ._options = kwargs
103118 kwargs ['individual_oe' ] = True
104119 super ().__init__ ({
105120 "gpio" : Out (BidirIOSignature (pin_count , ** kwargs ))
106121 })
107122
108123 def __chipflow_parameters__ (self ):
109- print ("called GPIOSignature.__chipflow_parameters__" )
110124 return [('pin_count' ,self ._pin_count )]
111125
112- def __repr__ (self ) -> str :
113- return f"GPIOSignature(pin_count={ self ._pin_count } , { dict (self .members .items ())} )"
114-
115-
116- class SimulationCanLoadData :
117- """
118- Inherit from this in your object's Signature if you want a simulation model
119- to be able to load data from your object
120- """
121- @classmethod
122- def __init_submodule__ (cls , / , * args , ** kwargs ):
123- if wiring .Signature not in cls .mro ():
124- raise ChipFlowError ("SimulationCanLoadData can only be used with ``wiring.Signature`` classes" )
125- original_annotations = getattr (cls , 'annotations' )
126- #def annotations(self, obj, /):
127- #cls.annotate
126+
127+ def attach_simulation_data (c : wiring .Component , ** kwargs : Unpack [SimData ]):
128+ setattr (c .signature , '__chipflow_simulation_data__' , kwargs )
129+ amaranth_annotate (SimData , SIM_DATA_SCHEMA , '__chipflow_simulation_data__' , decorate_object = True )(c .signature )
130+
0 commit comments