@@ -229,10 +229,10 @@ def visit_Always(self, node):
229229
230230 (clock_name , clock_edge , clock_bit ,
231231 reset_name , reset_edge , reset_bit ,
232- senslist ) = self ._createAlwaysinfo (node , current )
232+ senslist , load_const_dict ) = self ._createAlwaysinfo (node , current )
233233
234234 self .frames .setAlwaysInfo (clock_name , clock_edge , clock_bit ,
235- reset_name , reset_edge , reset_bit , senslist )
235+ reset_name , reset_edge , reset_bit , senslist , load_const_dict )
236236
237237 self .generic_visit (node )
238238 self .frames .setCurrent (current )
@@ -255,29 +255,33 @@ def _createAlwaysinfo(self, node, scope):
255255 reset_edge = None
256256 reset_name = None
257257 reset_bit = None
258+ reset_sig = None
259+ is_sync_reset = True
260+ r_finder = self .reset_finder (node , self .frames .current , self .dataflow )
258261
259- #TODO unimplemented
260- #print('load: ' + str(self._first_lvalue_is_const(node)))
261- #print('if_branch: ' + str(self._has_if_branch(node)))
262- #print('reset_info: ' + str(self._get_rst_info(node)))
262+ if str (r_finder ._has_if_branch (node )) and any (r_finder .load_const_dict .values ()):
263+ reset_sig , reset_edge , reset_bit = r_finder .get_rst_info ()
264+ reset_name = self .searchTerminal (reset_sig , scope )
263265
264266 for l in node .sens_list .list :
265267 if l .sig is None :
266268 continue
267- if isinstance (l .sig , pyverilog . vparser . ast . Pointer ):
269+ if isinstance (l .sig , Pointer ):
268270 signame = self ._get_signal_name (l .sig .var )
269271 bit = int (l .sig .ptr .value )
270272 else :
271273 signame = self ._get_signal_name (l .sig )
272274 bit = 0
273- if signaltype .isClock (signame ):
275+
276+ if signame == reset_sig and bit == reset_bit :
277+ if l .type == reset_edge :
278+ is_sync_reset = False
279+ else :
280+ raise verror .FormatError ('Illegal reset polarity' )
281+ elif not clock_name : #First signal which is not reset is regard as clock.
274282 clock_name = self .searchTerminal (signame , scope )
275283 clock_edge = l .type
276284 clock_bit = bit
277- elif signaltype .isReset (signame ):
278- reset_name = self .searchTerminal (signame , scope )
279- reset_edge = l .type
280- reset_bit = bit
281285 else :
282286 senslist .append (l )
283287
@@ -286,135 +290,10 @@ def _createAlwaysinfo(self, node, scope):
286290 if reset_edge is not None and len (senslist ) > 0 :
287291 raise verror .FormatError ('Illegal sensitivity list' )
288292
289- return (clock_name , clock_edge , clock_bit , reset_name , reset_edge , reset_bit , senslist )
290-
291- #TODO This function is implemented for https://github.com/PyHDI/Pyverilog/issues/14.
292- #Be incorporated into formally in lator commit.
293- def _first_lvalue_is_const (self , node ):
294- """ [FUNCTIONS]
295- Walk until lvalue and judge whether it is constant or not.
296-
297- ex.
298- if(RST)
299- reg1 <= 1'd0: //const: judged as rst branch
300-
301- if(RST)
302- reg1 <= {1'd0, 1'd0}: //const: judged as rst branch
303-
304- if(RST)
305- reg1 <= reg2: //variable: judged as not rst branch
306-
307- if(RST)
308- reg1 <= {1'd0, reg2}: //variable: judged as not rst branch
309- """
310- if isinstance (node , Always ):
311- return self ._first_lvalue_is_const (node .statement )
312- elif isinstance (node , Block ):
313- return self ._first_lvalue_is_const (node .statements [0 ])
314- elif isinstance (node , IfStatement ):
315- return self ._first_lvalue_is_const (node .true_statement )
316- elif isinstance (node , NonblockingSubstitution ):
317- print (node .left .var )# for debug
318- return self ._first_lvalue_is_const (node .right )
319- elif isinstance (node , Identifier ):
320- node_chain = self .get_scopechain (node )
321- if node_chain in self .dataflow .terms .keys ():
322- #Parameter is regard as constant.
323- return 'Parameter' in self .dataflow .terms [node_chain ].termtype
324- return False
325- elif hasattr (node , 'children' ):
326- for child in node .children ():
327- if not self ._first_lvalue_is_const (child ):
328- return False
329- return True
330- elif isinstance (node , Rvalue ):
331- return self ._first_lvalue_is_const (node .var )
332- elif hasattr (node , 'value' ):
333- return True
334- else :
335- raise Exception ('Pyverilog unknown error' )
336-
337- def get_scopechain (self , node ):
338- assert isinstance (node , Identifier ), 'Node type should be Identifier.'
339- scope_list = self .frames .current .get_module_list () + [util .ScopeLabel (str (node )),]
340- return util .ScopeChain (scope_list )
341-
342- #TODO This function is implemented for https://github.com/PyHDI/Pyverilog/issues/14.
343- #Be incorporated into formally in lator commit.
344- def _get_rst_info (self , node , rst_name = '' , is_posedge = True , rst_bit = 0 ):
345- """ [FUNCTIONS]
346- get reset information from first if statement.
347-
348- ex1.
349- always @(posedge CLK or posedge RST) begin
350- if(RST)
351- reg1 <= 0;
352- else
353- reg1 <= !reg1;
354- end
355- ->RST is posedge RST.
356-
357- ex2.
358- always @(posedge CLK or posedge RST) begin
359- if(!RSTN[1])
360- reg1 <= 0;
361- else
362- reg1 <= !reg1;
363- end
364- ->RSTN[1] is negedge RST.
365-
366- ex3.
367- always @(posedge CLK or posedge RST) begin
368- if(RST && RST2)
369- reg1 <= 0;
370- else
371- reg1 <= !reg1;
372- end
373- -> reg1 has no reset. (too complex condition)
374- """
375- if isinstance (node , Always ):
376- return self ._get_rst_info (node .statement , rst_name , is_posedge , rst_bit )
377- elif isinstance (node , Block ):
378- return self ._get_rst_info (node .statements [0 ], rst_name , is_posedge , rst_bit )
379- elif isinstance (node , IfStatement ):
380- return self ._get_rst_info (node .cond , rst_name , is_posedge , rst_bit )
381- elif isinstance (node , pyverilog .vparser .ast .Ulnot ):
382- is_posedge = not is_posedge
383- return self ._get_rst_info (node .children ()[0 ], rst_name , is_posedge , rst_bit )
384- elif isinstance (node , pyverilog .vparser .ast .Pointer ):
385- #TODO if identifier
386- if isinstance (node .ptr , Identifier ):
387- ptr_chain = self .get_scopechain (node .ptr )
388- if 'Parameter' in self .dataflow .terms [ptr_chain ].termtype :
389- rst_bit = self .dataflow .binddict [ptr_chain ][0 ].tree .eval ()
390- return self ._get_rst_info (node .var , rst_name , is_posedge , rst_bit )
391- else :
392- return (None , None , None )
393- elif hasattr (node .ptr , 'value' ):
394- return self ._get_rst_info (node .var , rst_name , is_posedge , int (node .ptr .value ))
395- elif isinstance (node , pyverilog .vparser .ast .Identifier ):
396- return (node , is_posedge , rst_bit )
397- return (None , None , None )
398-
399- #TODO This function is implemented for https://github.com/PyHDI/Pyverilog/issues/14.
400- #Be incorporated into formally in lator commit.
401- def _has_if_branch (self , node ):
402- """ [FUNCTIONS]
403- Return always block have 'if branch' or not.
404- ex.
405- always @(posedge CLK or posedge RST) begin
406- reg1 <= 0;
407- end
408- -> reg1 has no reset. (If statement isn't exists.)
409- """
410- if isinstance (node , Always ):
411- return self ._has_if_branch (node .statement )
412- elif isinstance (node , Block ):
413- return self ._has_if_branch (node .statements [0 ])
414- elif isinstance (node , IfStatement ):
415- return True
416- else :
417- return False
293+ if is_sync_reset :
294+ reset_edge = 'sync'
295+ return (clock_name , clock_edge , clock_bit , reset_name , reset_edge , reset_bit ,
296+ senslist , r_finder .load_const_dict )
418297
419298 def visit_IfStatement (self , node ):
420299 if self .frames .isFunctiondef () and not self .frames .isFunctioncall (): return
@@ -495,7 +374,6 @@ def visit_CaseStatement(self, node):
495374 start_frame = self .frames .getCurrent ()
496375 caseframes = []
497376 self ._case (node .comp , node .caselist , caseframes )
498- #self._case(node.comp, tuple(reversed(list(node.caselist))), caseframes)
499377 self .frames .setCurrent (start_frame )
500378 for f in caseframes :
501379 self .copyBlockingAssigns (f , start_frame )
@@ -662,15 +540,15 @@ def visit_Assign(self, node):
662540 self .addBind (node .left , node .right , bindtype = 'assign' )
663541
664542 def visit_BlockingSubstitution (self , node ):
665- self .addBind (node .left , node .right , self .frames .getAlwaysStatus (), 'blocking' )
543+ self .addBind (node .left , node .right , self .frames .getAlwaysStatus (node . left ), 'blocking' )
666544
667545 def visit_NonblockingSubstitution (self , node ):
668546 if self .frames .isForpre () or self .frames .isForpost ():
669547 raise verror .FormatError (("Non Blocking Substitution is not allowed"
670548 "in for-statement" ))
671549 if self .frames .isFunctioncall ():
672550 raise verror .FormatError ("Non Blocking Substitution is not allowed in function" )
673- self .addBind (node .left , node .right , self .frames .getAlwaysStatus (), 'nonblocking' )
551+ self .addBind (node .left , node .right , self .frames .getAlwaysStatus (node . left ), 'nonblocking' )
674552
675553 def visit_SystemCall (self , node ):
676554 print ("Warning: Isolated system call is not supported: %s" % node .syscall )
@@ -1646,3 +1524,147 @@ def appendBranchTree(self, base, pos, tree):
16461524 base .condnode ,
16471525 base .truenode ,
16481526 self .appendBranchTree (base .falsenode , pos [1 :], tree ))
1527+
1528+ class reset_finder (object ):
1529+ def __init__ (self , node , current , dataflow ):
1530+ self .current = current
1531+ self .dataflow = dataflow
1532+ self .is_posedge = 'posedge'
1533+ self .rst_bit = 0
1534+ self .rst_name = None
1535+ self .load_const_dict = {}
1536+ self ._walk_in_first_ifbranch (node )
1537+ self ._make_rst_info (node )
1538+
1539+ def _walk_in_first_ifbranch (self , node ):
1540+ """ [FUNCTIONS]
1541+ Walk until lvalue and judge whether it is constant or not.
1542+
1543+ ex.
1544+ if(RST)
1545+ reg1 <= 1'd0: //const: judged as rst branch
1546+
1547+ if(RST)
1548+ reg1 <= {1'd0, 1'd0}: //const: judged as rst branch
1549+
1550+ if(RST)
1551+ reg1 <= reg2: //variable: judged as not rst branch
1552+
1553+ if(RST)
1554+ reg1 <= {1'd0, reg2}: //variable: judged as not rst branch
1555+ """
1556+ if isinstance (node , Always ):
1557+ self ._walk_in_first_ifbranch (node .statement )
1558+ elif isinstance (node , Block ):
1559+ for statement in node .statements :
1560+ self ._walk_in_first_ifbranch (statement )
1561+ elif isinstance (node , IfStatement ):
1562+ self ._walk_in_first_ifbranch (node .true_statement )
1563+ elif isinstance (node , NonblockingSubstitution ):
1564+ self .load_const_dict [node .left ] = self ._is_const (node .right )
1565+ else :
1566+ raise Exception ('Pyverilog unknown error' )
1567+
1568+ def _is_const (self , node ):
1569+ if isinstance (node , Identifier ):
1570+ node_chain = self .get_scopechain (node )
1571+ if node_chain in self .dataflow .terms .keys ():
1572+ #Parameter is regard as constant.
1573+ return 'Parameter' in self .dataflow .terms [node_chain ].termtype
1574+ elif hasattr (node , 'children' ):
1575+ for child in node .children ():
1576+ if not self ._is_const (child ):
1577+ return False
1578+ else :
1579+ return True
1580+ elif isinstance (node , Rvalue ):
1581+ self ._is_const (node .var )
1582+ elif hasattr (node , 'value' ):
1583+ return True
1584+ else :
1585+ raise Exception ('Pyverilog unknown error' )
1586+
1587+ def get_is_const_subed (self ):
1588+ return self .const_substituted
1589+
1590+ def get_scopechain (self , node ):
1591+ assert isinstance (node , Identifier ), 'Node type should be Identifier.'
1592+ scope_list = self .current .get_module_list () + [util .ScopeLabel (str (node )),]
1593+ return util .ScopeChain (scope_list )
1594+
1595+ def _make_rst_info (self , node ):
1596+ """ [FUNCTIONS]
1597+ get reset information from first if statement.
1598+
1599+ ex1.
1600+ always @(posedge CLK or posedge RST) begin
1601+ if(RST)
1602+ reg1 <= 0;
1603+ else
1604+ reg1 <= !reg1;
1605+ end
1606+ ->RST is posedge RST.
1607+
1608+ ex2.
1609+ always @(posedge CLK or posedge RST) begin
1610+ if(!RSTN[1])
1611+ reg1 <= 0;
1612+ else
1613+ reg1 <= !reg1;
1614+ end
1615+ ->RSTN[1] is negedge RST.
1616+
1617+ ex3.
1618+ always @(posedge CLK or posedge RST) begin
1619+ if(RST && RST2)
1620+ reg1 <= 0;
1621+ else
1622+ reg1 <= !reg1;
1623+ end
1624+ -> reg1 has no reset. (too complex condition)
1625+ """
1626+ if isinstance (node , Always ):
1627+ self ._make_rst_info (node .statement )
1628+ elif isinstance (node , Block ):
1629+ self ._make_rst_info (node .statements [0 ])
1630+ elif isinstance (node , IfStatement ):
1631+ self ._make_rst_info (node .cond )
1632+ elif isinstance (node , Ulnot ):
1633+ self .is_posedge = 'negedge' if self .is_posedge == 'posedge' else 'posedge'
1634+ self ._make_rst_info (node .children ()[0 ])
1635+ elif isinstance (node , Pointer ):
1636+ if isinstance (node .ptr , Identifier ):
1637+ ptr_chain = self .get_scopechain (node .ptr )
1638+ if 'Parameter' in self .dataflow .terms [ptr_chain ].termtype :
1639+ self .rst_bit = self .dataflow .binddict [ptr_chain ][0 ].tree .eval ()
1640+ self ._make_rst_info (node .var )
1641+ else :
1642+ self .is_posedge = None
1643+ self .rst_name = None
1644+ self .rst_bit = None
1645+ elif hasattr (node .ptr , 'value' ):
1646+ self .rst_bit = int (node .ptr .value )
1647+ self ._make_rst_info (node .var )
1648+ elif isinstance (node , Identifier ):
1649+ self .rst_name = str (node )
1650+
1651+ def _has_if_branch (self , node ):
1652+ """ [FUNCTIONS]
1653+ Return always block have 'if branch' or not.
1654+ ex.
1655+ always @(posedge CLK or posedge RST) begin
1656+ reg1 <= 0;
1657+ end
1658+ -> reg1 has no reset. (If statement isn't exists.)
1659+ """
1660+ if isinstance (node , Always ):
1661+ return self ._has_if_branch (node .statement )
1662+ elif isinstance (node , Block ):
1663+ return self ._has_if_branch (node .statements [0 ])
1664+ elif isinstance (node , IfStatement ):
1665+ return True
1666+ else :
1667+ return False
1668+
1669+ def get_rst_info (self ):
1670+ return self .rst_name , self .is_posedge , self .rst_bit
0 commit comments