@@ -75,6 +75,7 @@ def __init__(self, m, name, clk, rst, width=32, initname='init',
7575 self .last_cond = []
7676 self .last_kwargs = {}
7777 self .last_if_statement = None
78+ self .next_else = False
7879 self .elif_cond = None
7980 self .next_kwargs = {}
8081
@@ -85,61 +86,111 @@ def __init__(self, m, name, clk, rst, width=32, initname='init',
8586
8687 # -------------------------------------------------------------------------
8788 def goto (self , dst , cond = None , else_dst = None ):
89+ if isinstance (dst , State ):
90+ dst = dst .index
91+
8892 if cond is None and 'cond' in self .next_kwargs :
8993 cond = self .next_kwargs ['cond' ]
94+
95+ if 'index' in self .next_kwargs :
96+ index = self .next_kwargs ['index' ]
97+ else :
98+ index = None
99+
90100 self ._clear_next_kwargs ()
91- self ._clear_last_if_statement ()
92- self ._clear_last_cond ()
101+ # self._clear_last_if_statement()
102+ # self._clear_last_cond()
103+ # self._clear_elif_cond()
93104
94- src = self .current
95- return self ._go (src , dst , cond , else_dst )
105+ if index is None :
106+ src = self .current
107+ else :
108+ src = index
109+
110+ self ._go (src , dst , cond , else_dst )
111+ return State (self , dst )
96112
97113 def goto_init (self , cond = None ):
98114 if cond is None and 'cond' in self .next_kwargs :
99115 cond = self .next_kwargs ['cond' ]
116+
117+ if 'index' in self .next_kwargs :
118+ index = self .next_kwargs ['index' ]
119+ else :
120+ index = None
121+
100122 self ._clear_next_kwargs ()
101- self ._clear_last_if_statement ()
102- self ._clear_last_cond ()
123+ # self._clear_last_if_statement()
124+ # self._clear_last_cond()
125+ # self._clear_elif_cond()
126+
127+ if index is None :
128+ src = self .current
129+ else :
130+ src = index
103131
104- src = self .current
105132 dst = 0
106- return self ._go (src , dst , cond )
133+ self ._go (src , dst , cond )
134+ return State (self , dst )
107135
108136 def goto_next (self , cond = None ):
109137 if cond is None and 'cond' in self .next_kwargs :
110138 cond = self .next_kwargs ['cond' ]
139+
140+ if 'index' in self .next_kwargs :
141+ index = self .next_kwargs ['index' ]
142+ else :
143+ index = None
144+
111145 self ._clear_next_kwargs ()
112- self ._clear_last_if_statement ()
113- self ._clear_last_cond ()
146+ # self._clear_last_if_statement()
147+ # self._clear_last_cond()
148+ # self._clear_elif_cond()
149+
150+ if index is None :
151+ src = self .current
152+ else :
153+ src = index
114154
115- src = self .current
116- dst = self .current + 1
117- ret = self ._go (src , dst , cond = cond )
155+ dst = src + 1
156+ self ._go (src , dst , cond = cond )
118157 self .inc ()
119- return ret
158+ return State ( self , dst )
120159
121160 def goto_from (self , src , dst , cond = None , else_dst = None ):
161+ if isinstance (src , State ):
162+ src = src .index
163+
164+ if isinstance (dst , State ):
165+ dst = dst .index
166+
122167 if cond is None and 'cond' in self .next_kwargs :
123168 cond = self .next_kwargs ['cond' ]
169+
124170 self ._clear_next_kwargs ()
125- self ._clear_last_if_statement ()
126- self ._clear_last_cond ()
171+ # self._clear_last_if_statement()
172+ # self._clear_last_cond()
173+ # self._clear_elif_cond()
127174
128- return self ._go (src , dst , cond , else_dst )
175+ self ._go (src , dst , cond , else_dst )
176+ return State (self , dst )
129177
130178 def inc (self ):
131- self ._set_index (None )
179+ return self ._set_index (None )
132180
133181 # -------------------------------------------------------------------------
134182 def add (self , * statement , ** kwargs ):
135- """ add new assignments """
183+ """ Adding new assignments. This method is usually called via __call__(). """
136184 kwargs .update (self .next_kwargs )
137185 self .last_kwargs = kwargs
138186 self ._clear_next_kwargs ()
139187
140188 # if there is no attributes, Elif object is reused.
141189 has_args = not (len (kwargs ) == 0 or # has no args
142- (len (kwargs ) == 1 and 'cond' in kwargs )) # has only 'cond'
190+ (len (kwargs ) == 1 and 'cond' in kwargs ) or # has only 'cond'
191+ (len (kwargs ) == 1 and 'index' in kwargs ) or # has only 'index'
192+ (len (kwargs ) == 2 and
193+ 'cond' in kwargs and 'index' in kwargs )) # has only 'cond' and 'index'
143194
144195 if self .elif_cond is not None and not has_args :
145196 next_call = self .last_if_statement .Elif (self .elif_cond )
@@ -149,6 +200,14 @@ def add(self, *statement, **kwargs):
149200 self ._clear_elif_cond ()
150201 return self
151202
203+ if self .next_else and not has_args :
204+ next_call = self .last_if_statement .Else
205+ next_call (* statement )
206+ self ._add_dst_var (statement )
207+ self ._clear_last_if_statement ()
208+ self ._clear_elif_cond ()
209+ return self
210+
152211 self ._clear_last_if_statement ()
153212 return self ._add_statement (statement , ** kwargs )
154213
@@ -179,7 +238,8 @@ def If(self, *cond):
179238
180239 return self
181240
182- def Else (self , * statement , ** kwargs ):
241+ @property
242+ def Else (self ):
183243 self ._clear_elif_cond ()
184244
185245 if len (self .last_cond ) == 0 :
@@ -192,25 +252,20 @@ def Else(self, *statement, **kwargs):
192252 # Else statement is separated.
193253 if 'delay' in self .last_kwargs and self .last_kwargs ['delay' ] > 0 :
194254 prev_cond = self .last_cond
195- ret = self .Then ()( * statement )
255+ ret = self .Then ()
196256 self .last_cond = prev_cond
197257 return ret
198258
199- # if there is additional attribute, Else statement is separated.
200- has_args = not (len (self .next_kwargs ) == 0 or # has no args
201- (len (self .next_kwargs ) == 1 and 'cond' in kwargs )) # has only 'cond'
259+ # if not isinstance(self.last_if_statement, vtypes.If):
260+ # raise ValueError("Last if-statement is not If")
202261
203- if has_args :
204- prev_cond = self .last_cond
205- ret = self .Then ()(* statement )
206- self .last_cond = prev_cond
207- return ret
262+ # self.next_else = True
208263
209- if not isinstance (self .last_if_statement , vtypes .If ):
210- raise ValueError ( "Last if-statement is not If" )
264+ if isinstance (self .last_if_statement , vtypes .If ):
265+ self . next_else = True
211266
212- self .last_if_statement . Else ( * statement )
213- self ._add_dst_var ( statement )
267+ cond = self ._make_cond ( self . last_cond )
268+ self .next_kwargs [ 'cond' ] = cond
214269
215270 return self
216271
@@ -224,18 +279,21 @@ def Elif(self, *cond):
224279 self .last_cond .append (vtypes .Not (old ))
225280 self .last_cond .append (cond )
226281
227- # if the true-statement has delay attributes, Else statement is
228- # separated.
282+ # if the true-statement has delay attributes,
283+ # Else statement is separated.
229284 if 'delay' in self .last_kwargs and self .last_kwargs ['delay' ] > 0 :
230285 prev_cond = self .last_cond
231286 ret = self .Then ()
232287 self .last_cond = prev_cond
233288 return ret
234289
235- if not isinstance (self .last_if_statement , vtypes .If ):
236- raise ValueError ("Last if-statement is not If" )
290+ # if not isinstance(self.last_if_statement, vtypes.If):
291+ # raise ValueError("Last if-statement is not If")
237292
238- self .elif_cond = cond
293+ # self.elif_cond = cond
294+
295+ if isinstance (self .last_if_statement , vtypes .If ):
296+ self .elif_cond = cond
239297
240298 cond = self ._make_cond (self .last_cond )
241299 self .next_kwargs ['cond' ] = cond
@@ -264,6 +322,10 @@ def EagerVal(self, value=True):
264322 self .next_kwargs ['eager_val' ] = value
265323 return self
266324
325+ def When (self , index ):
326+ self .next_kwargs ['index' ] = index
327+ return self
328+
267329 def Clear (self ):
268330 self ._clear_next_kwargs ()
269331 self ._clear_last_if_statement ()
@@ -272,13 +334,21 @@ def Clear(self):
272334 return self
273335
274336 # -------------------------------------------------------------------------
337+ @property
338+ def Always (self ):
339+ return self .seq
340+
341+ @property
342+ def init (self ):
343+ return State (self , 0 )
344+
275345 @property
276346 def current (self ):
277- return self .state_count
347+ return State ( self , self .state_count )
278348
279349 @property
280350 def next (self ):
281- return self . current + 1
351+ return State ( self , self . state_count + 1 )
282352
283353 @property
284354 def current_delay (self ):
@@ -806,6 +876,7 @@ def _clear_next_kwargs(self):
806876
807877 def _clear_last_if_statement (self ):
808878 self .last_if_statement = None
879+ self .next_else = False
809880
810881 def _clear_last_cond (self ):
811882 self .last_cond = []
@@ -824,9 +895,15 @@ def _make_cond(self, condlist):
824895
825896 # -------------------------------------------------------------------------
826897 def _set_index (self , index = None ):
898+ self ._clear_next_kwargs ()
899+ self ._clear_last_if_statement ()
900+ self ._clear_last_cond ()
901+ self ._clear_elif_cond ()
902+
827903 if index is None :
828904 self .state_count += 1
829905 return self .state_count
906+
830907 self .state_count = index
831908 return self .state_count
832909
@@ -970,3 +1047,43 @@ def __getitem__(self, index):
9701047
9711048 def __len__ (self ):
9721049 return self .state_count + 1
1050+
1051+
1052+ class State (vtypes .VeriloggenNode ):
1053+ """ FSM with a specic state index """
1054+
1055+ def __init__ (self , fsm , index ):
1056+ while isinstance (fsm , State ):
1057+ fsm = fsm .fsm
1058+
1059+ while isinstance (index , State ):
1060+ index = index .index
1061+
1062+ if not isinstance (fsm , FSM ):
1063+ raise TypeError ("'fsm' must be FSM, not '%s'" % str (type (fsm )))
1064+
1065+ if not isinstance (index , int ):
1066+ raise TypeError ("'index' must be int, not '%s'" % str (type (index )))
1067+
1068+ self .fsm = fsm
1069+ self .index = index
1070+
1071+ def __getattr__ (self , attr ):
1072+ self .fsm .When (self .index )
1073+ return getattr (self .fsm , attr )
1074+
1075+ def __call__ (self , * statement , ** kwargs ):
1076+ self .fsm .When (self .index )
1077+ return self .fsm .__call__ (* statement , ** kwargs )
1078+
1079+ def __add__ (self , r ):
1080+ if isinstance (r , State ):
1081+ r = r .index
1082+
1083+ return self .index + r
1084+
1085+ def __sub__ (self , r ):
1086+ if isinstance (r , State ):
1087+ r = r .index
1088+
1089+ return self .index - r
0 commit comments