<s> from __future__ import absolute_import <EOL> from __future__ import print_function <EOL> import os <EOL> import sys <EOL> import copy <EOL> from collections import OrderedDict <EOL> import veriloggen . core . vtypes as vtypes <EOL> import veriloggen . core . module as module <EOL> def get_width ( node ) : <EOL> ret = node . bit_length ( ) <EOL> if isinstance ( node , int ) and ret < <NUM_LIT:32> : <EOL> return <NUM_LIT:32> <EOL> if ret is None or isinstance ( node , vtypes . AnyType ) : <EOL> return <NUM_LIT:32> <EOL> return ret <EOL> def check_constant ( obj ) : <EOL> if not isinstance ( obj , vtypes . VeriloggenNode ) : <EOL> return True <EOL> return False <EOL> def check_overwrite ( obj ) : <EOL> if check_constant ( obj ) : <EOL> return True <EOL> if isinstance ( obj , ( tuple , list ) ) : <EOL> return True <EOL> return False <EOL> class _Visitor ( object ) : <EOL> def generic_visit ( self , node ) : <EOL> raise TypeError ( "<STR_LIT>" % str ( type ( node ) ) ) <EOL> def visit ( self , node ) : <EOL> visitor = getattr ( self , '<STR_LIT>' + node . __class__ . __name__ , self . generic_visit ) <EOL> return visitor ( node ) <EOL> class _CachedVisitor ( _Visitor ) : <EOL> def __init__ ( self ) : <EOL> _Visitor . __init__ ( self ) <EOL> self . visited_node = { } <EOL> def visit ( self , node ) : <EOL> if isinstance ( node , ( tuple , list ) ) : <EOL> return self . _visit ( node ) <EOL> if node in self . visited_node : <EOL> return self . visited_node [ node ] <EOL> ret = self . _visit ( node ) <EOL> self . visited_node [ node ] = ret <EOL> return ret <EOL> def _visit ( self , node ) : <EOL> visitor = getattr ( self , '<STR_LIT>' + node . __class__ . __name__ , self . generic_visit ) <EOL> return visitor ( node ) <EOL> class _CommonVisitor ( _CachedVisitor ) : <EOL> def generic_visit ( self , node ) : <EOL> if isinstance ( node , vtypes . _Variable ) : <EOL> return self . visit__Variable ( node ) <EOL> if isinstance ( node , vtypes . _Constant ) : <EOL> return self . visit__Constant ( node ) <EOL> if isinstance ( node , vtypes . _BinaryOperator ) : <EOL> return self . visit__BinaryOperator ( node ) <EOL> if isinstance ( node , vtypes . _UnaryOperator ) : <EOL> return self . visit__UnaryOperator ( node ) <EOL> return node <EOL> def visit__Variable ( self , node ) : <EOL> return node <EOL> def visit__Constant ( self , node ) : <EOL> return node . value <EOL> def visit__BinaryOperator ( self , node ) : <EOL> return node <EOL> def visit__UnaryOperator ( self , node ) : <EOL> return node <EOL> class ConstantVisitor ( _CommonVisitor ) : <EOL> def __init__ ( self , const_dict ) : <EOL> _CommonVisitor . __init__ ( self ) <EOL> self . const_dict = const_dict <EOL> def get_const ( self , name ) : <EOL> if name not in self . const_dict : <EOL> raise KeyError ( "<STR_LIT>" % name ) <EOL> return self . const_dict [ name ] <EOL> def has_const ( self , name ) : <EOL> return ( name in self . const_dict ) <EOL> def update_const ( self , name , value ) : <EOL> self . const_dict [ name ] = value <EOL> def get_const_dict ( self ) : <EOL> return self . const_dict <EOL> def _visit_param ( self , node ) : <EOL> if self . has_const ( node . name ) : <EOL> value = self . get_const ( node . name ) <EOL> return value <EOL> return node <EOL> def visit_Parameter ( self , node ) : <EOL> return self . _visit_param ( node ) <EOL> def visit_Localparam ( self , node ) : <EOL> return self . _visit_param ( node ) <EOL> def visit_AnyType ( self , node ) : <EOL> return self . _visit_param ( node ) <EOL> def visit__BinaryOperator ( self , node ) : <EOL> left = self . visit ( node . left ) <EOL> right = self . visit ( node . right ) <EOL> lwidth = self . visit ( get_width ( node . left ) ) <EOL> rwidth = self . visit ( get_width ( node . right ) ) <EOL> if ( check_constant ( left ) and <EOL> check_constant ( right ) and <EOL> check_constant ( lwidth ) and <EOL> check_constant ( rwidth ) ) : <EOL> return node . op ( left , right , lwidth , rwidth ) <EOL> return node <EOL> def visit__UnaryOperator ( self , node ) : <EOL> right = self . visit ( node . right ) <EOL> rwidth = self . visit ( get_width ( node . right ) ) <EOL> if ( check_constant ( right ) and <EOL> check_constant ( rwidth ) ) : <EOL> return node . op ( right , rwidth ) <EOL> return node <EOL> def visit_Pointer ( self , node ) : <EOL> var = self . visit ( node . var ) <EOL> pos = self . visit ( node . pos ) <EOL> if ( check_constant ( var ) and <EOL> check_constant ( pos ) ) : <EOL> return node . op ( var , pos ) <EOL> return node <EOL> def visit_Slice ( self , node ) : <EOL> var = self . visit ( node . var ) <EOL> msb = self . visit ( node . msb ) <EOL> lsb = self . visit ( node . lsb ) <EOL> if ( check_constant ( var ) and <EOL> check_constant ( msb ) and <EOL> check_constant ( lsb ) ) : <EOL> return node . op ( var , msb , lsb ) <EOL> return node <EOL> def visit_Cat ( self , node ) : <EOL> vars = [ self . visit ( var ) for var in node . vars ] <EOL> widths = [ self . visit ( get_width ( var ) ) for var in node . vars ] <EOL> for var , width in zip ( vars , widths ) : <EOL> if not check_constant ( var ) : <EOL> return node <EOL> if not check_constant ( width ) : <EOL> return node <EOL> return node . op ( vars , widths ) <EOL> def visit_Repeat ( self , node ) : <EOL> var = self . visit ( node . var ) <EOL> width = self . visit ( get_width ( node . var ) ) <EOL> times = self . visit ( node . times ) <EOL> if ( check_constant ( var ) and <EOL> check_constant ( width ) and <EOL> check_constant ( times ) ) : <EOL> return node . op ( var , width , times ) <EOL> return node <EOL> def visit_Cond ( self , node ) : <EOL> condition = self . visit ( node . condition ) <EOL> true_value = self . visit ( node . true_value ) <EOL> false_value = self . visit ( node . false_value ) <EOL> if ( check_constant ( condition ) and <EOL> check_constant ( true_value ) and <EOL> check_constant ( false_value ) ) : <EOL> return node . op ( condition , true_value , false_value ) <EOL> return node <EOL> class ReplaceVisitor ( ConstantVisitor ) : <EOL> def visit_tuple ( self , node ) : <EOL> return tuple ( [ self . visit ( n ) for n in node ] ) <EOL> def visit_list ( self , node ) : <EOL> return [ self . visit ( n ) for n in node ] <EOL> def visit__BinaryOperator ( self , node ) : <EOL> left = self . visit ( node . left ) <EOL> right = self . visit ( node . right ) <EOL> lwidth = self . visit ( get_width ( node . left ) ) <EOL> rwidth = self . visit ( get_width ( node . right ) ) <EOL> if ( check_constant ( left ) and <EOL> check_constant ( right ) and <EOL> check_constant ( lwidth ) and <EOL> check_constant ( rwidth ) ) : <EOL> return node . op ( left , right , lwidth , rwidth ) <EOL> if check_constant ( left ) : <EOL> node . left = left <EOL> if check_constant ( right ) : <EOL> node . right = right <EOL> return node <EOL> def visit__UnaryOperator ( self , node ) : <EOL> right = self . visit ( node . right ) <EOL> rwidth = self . visit ( get_width ( node . right ) ) <EOL> if ( check_constant ( right ) and <EOL> check_constant ( rwidth ) ) : <EOL> return node . op ( right , rwidth ) <EOL> if check_constant ( right ) : <EOL> node . right = right <EOL> return node <EOL> def visit_Pointer ( self , node ) : <EOL> var = self . visit ( node . var ) <EOL> pos = self . visit ( node . pos ) <EOL> if ( check_constant ( var ) and <EOL> check_constant ( pos ) ) : <EOL> return node . op ( var , pos ) <EOL> if check_constant ( var ) : <EOL> node . var = var <EOL> if check_constant ( pos ) : <EOL> node . pos = pos <EOL> return node <EOL> def visit_Slice ( self , node ) : <EOL> var = self . visit ( node . var ) <EOL> msb = self . visit ( node . msb ) <EOL> lsb = self . visit ( node . lsb ) <EOL> if ( check_constant ( var ) and <EOL> check_constant ( msb ) and <EOL> check_constant ( lsb ) ) : <EOL> return node . op ( var , msb , lsb ) <EOL> if check_constant ( var ) : <EOL> node . var = var <EOL> if check_constant ( msb ) : <EOL> node . msb = msb <EOL> if check_constant ( lsb ) : <EOL> node . lsb = lsb <EOL> return node <EOL> def visit_Cat ( self , node ) : <EOL> vars = [ self . visit ( var ) for var in node . vars ] <EOL> widths = [ self . visit ( get_width ( var ) ) for var in node . vars ] <EOL> node . vars = vars <EOL> for var , width in zip ( vars , widths ) : <EOL> if not check_constant ( var ) : <EOL> return node <EOL> if not check_constant ( width ) : <EOL> return node <EOL> return node . op ( vars , widths ) <EOL> def visit_Repeat ( self , node ) : <EOL> var = self . visit ( node . var ) <EOL> width = self . visit ( get_width ( node . var ) ) <EOL> times = self . visit ( node . times ) <EOL> if ( check_constant ( var ) and <EOL> check_constant ( width ) and <EOL> check_constant ( times ) ) : <EOL> return node . op ( var , width , times ) <EOL> if check_constant ( var ) : <EOL> node . var = var <EOL> if check_constant ( times ) : <EOL> node . times = times <EOL> return node <EOL> def visit_Cond ( self , node ) : <EOL> condition = self . visit ( node . condition ) <EOL> true_value = self . visit ( node . true_value ) <EOL> false_value = self . visit ( node . false_value ) <EOL> if ( check_constant ( condition ) and <EOL> check_constant ( true_value ) and <EOL> check_constant ( false_value ) ) : <EOL> return node . op ( condition , true_value , false_value ) <EOL> if check_constant ( condition ) : <EOL> node . condition = condition <EOL> if check_constant ( true_value ) : <EOL> node . true_value = true_value <EOL> if check_constant ( false_value ) : <EOL> node . false_value = false_value <EOL> return node <EOL> def visit_Posedge ( self , node ) : <EOL> name = self . visit ( node . name ) <EOL> if check_overwrite ( name ) : <EOL> node . name = name <EOL> return node <EOL> def visit_Negedge ( self , node ) : <EOL> name = self . visit ( node . name ) <EOL> if check_overwrite ( name ) : <EOL> node . name = name <EOL> return node <EOL> def visit_SensitiveAll ( self , node ) : <EOL> return node <EOL> def visit_Subst ( self , node ) : <EOL> left = self . visit ( node . left ) <EOL> right = self . visit ( node . right ) <EOL> ldelay = self . visit ( node . ldelay ) if node . ldelay is not None else None <EOL> rdelay = self . visit ( node . rdelay ) if node . rdelay is not None else None <EOL> node . left = left <EOL> if check_constant ( right ) : <EOL> node . right = right <EOL> if check_constant ( ldelay ) : <EOL> node . ldelay = ldelay <EOL> if check_constant ( rdelay ) : <EOL> node . rdelay = rdelay <EOL> return node <EOL> def visit_If ( self , node ) : <EOL> condition = self . visit ( node . condition ) <EOL> true_statement = self . visit ( node . true_statement ) <EOL> if node . false_statement is not None : <EOL> false_statement = self . visit ( node . false_statement ) <EOL> if check_overwrite ( condition ) : <EOL> node . condition = condition <EOL> node . true_statement = true_statement <EOL> if node . false_statement is not None : <EOL> node . false_statement = false_statement <EOL> return node <EOL> def visit_For ( self , node ) : <EOL> pre = self . visit ( node . pre ) <EOL> condition = self . visit ( node . condition ) <EOL> post = self . visit ( node . post ) <EOL> if check_overwrite ( condition ) : <EOL> node . condition = condition <EOL> new_statement = [ ] <EOL> const_dict = copy . deepcopy ( self . const_dict ) <EOL> dst = pre . left . name <EOL> val = pre . right <EOL> const_dict [ dst ] = val <EOL> while True : <EOL> cvisitor = ForReplaceVisitor ( const_dict ) <EOL> cond = cvisitor . visit ( condition ) <EOL> if not check_constant ( cond ) : <EOL> return node <EOL> if not cond : <EOL> break <EOL> rslt = cvisitor . visit ( copy . deepcopy ( node . statement ) ) <EOL> new_statement . append ( rslt ) <EOL> if post . left . name != dst : <EOL> raise ValueError ( "<STR_LIT>" % dst ) <EOL> const_dict [ dst ] = cvisitor . visit ( post . right ) <EOL> return new_statement <EOL> def visit_While ( self , node ) : <EOL> condition = self . visit ( node . condition ) <EOL> statement = self . visit ( node . statement ) <EOL> if check_constant ( condition ) : <EOL> node . condition = condition <EOL> node . statement = statement <EOL> return node <EOL> def visit_Case ( self , node ) : <EOL> comp = self . visit ( node . comp ) <EOL> statement = [ self . visit ( s ) for s in node . statement ] <EOL> if check_constant ( comp ) : <EOL> node . comp = comp <EOL> node . statement = statement <EOL> return node <EOL> def visit_Casex ( self , node ) : <EOL> comp = self . visit ( node . comp ) <EOL> statement = [ self . visit ( s ) for s in node . statement ] <EOL> if check_constant ( comp ) : <EOL> node . comp = comp <EOL> node . statement = statement <EOL> return node <EOL> def visit_When ( self , node ) : <EOL> condition = self . visit ( node . condition ) <EOL> statement = self . visit ( node . statement ) <EOL> if check_constant ( condition ) : <EOL> node . condition = condition <EOL> node . statement = statement <EOL> return node <EOL> def visit_ScopeIndex ( self , node ) : <EOL> self . visit ( node . name ) <EOL> index = self . visit ( node . index ) <EOL> if check_constant ( index ) : <EOL> node . index = index <EOL> return node <EOL> def visit_Scope ( self , node ) : <EOL> args = [ self . visit ( arg ) for arg in node . args ] <EOL> node . args = args <EOL> return node <EOL> def visit_SystemTask ( self , node ) : <EOL> args = [ self . visit ( a ) for a in node . args ] <EOL> node . args = args <EOL> return node <EOL> def visit_Event ( self , node ) : <EOL> sensitivity = [ self . visit ( s ) for s in node . sensitivity ] <EOL> node . sensitivity = sensitivity <EOL> return node <EOL> def visit_Forever ( self , node ) : <EOL> statement = [ self . visit ( s ) for s in node . statement ] <EOL> node . statement = statement <EOL> return node <EOL> def visit_Delay ( self , node ) : <EOL> delay = self . visit ( node . delay ) <EOL> if check_constant ( delay ) : <EOL> node . delay = delay <EOL> return node <EOL> def visit_SingleStatement ( self , node ) : <EOL> statement = self . visit ( node . statement ) <EOL> node . statement = statement <EOL> return node <EOL> def visit_Function ( self , node ) : <EOL> return node <EOL> def visit_FunctionCall ( self , node ) : <EOL> self . visit ( node . func ) <EOL> args = [ self . visit ( a ) for a in node . args ] <EOL> node . args = args <EOL> return node <EOL> def visit_Task ( self , node ) : <EOL> return node <EOL> def visit_TaskCall ( self , node ) : <EOL> self . visit ( node . func ) <EOL> args = [ self . visit ( a ) for a in node . args ] <EOL> node . args = args <EOL> return node <EOL> class ForReplaceVisitor ( ReplaceVisitor ) : <EOL> def visit__Variable ( self , node ) : <EOL> return self . _visit_param ( node ) <EOL> class ModuleReplaceVisitor ( _CachedVisitor ) : <EOL> tmp_count = <NUM_LIT:0> <EOL> def __init__ ( self , mod , const_dict = None , submodule = None ) : <EOL> _CachedVisitor . __init__ ( self ) <EOL> if not isinstance ( mod , module . Module ) and not isinstance ( mod , module . Generate ) : <EOL> raise TypeError ( "<STR_LIT>" , str ( type ( mod ) ) ) <EOL> if const_dict is None : <EOL> const_dict = OrderedDict ( ) <EOL> if submodule is None : <EOL> submodule = OrderedDict ( ) <EOL> self . mod = mod <EOL> self . const_dict = const_dict <EOL> self . submodule = submodule <EOL> self . replace_visitor = None <EOL> def resolve ( self ) : <EOL> self . _update_const_dict ( ) <EOL> self . replace_visitor = ReplaceVisitor ( self . const_dict ) <EOL> return self . visit ( self . mod ) <EOL> def _update_const_dict ( self ) : <EOL> params = self . mod . get_params ( ) <EOL> localparams = self . mod . get_localparams ( ) <EOL> unresolved = OrderedDict ( ) <EOL> unresolved . update ( params ) <EOL> unresolved . update ( localparams ) <EOL> prev_size = len ( unresolved ) + <NUM_LIT:1> <EOL> while unresolved and len ( unresolved ) < prev_size : <EOL> prev_size = len ( unresolved ) <EOL> unresolved = self . _update_const_dict_iter ( unresolved ) <EOL> if unresolved : <EOL> varlist = '<STR_LIT:U+002CU+0020>' . join ( unresolved . keys ( ) ) <EOL> raise ValueError ( '<STR_LIT>' % varlist ) <EOL> def _update_const_dict_iter ( self , unresolved ) : <EOL> const_visitor = ConstantVisitor ( self . const_dict ) <EOL> next_unresolved = OrderedDict ( ) <EOL> for name , param in unresolved . items ( ) : <EOL> value = const_visitor . visit ( param . value ) <EOL> if not check_constant ( value ) : <EOL> next_unresolved [ name ] = param <EOL> continue <EOL> if name not in self . const_dict : <EOL> const_visitor . update_const ( name , value ) <EOL> self . const_dict = const_visitor . get_const_dict ( ) <EOL> return next_unresolved <EOL> def visit_Module ( self , node ) : <EOL> params = node . get_params ( ) <EOL> for param in params . values ( ) : <EOL> if param . width is not None : <EOL> param . width = self . replace_visitor . visit ( param . width ) <EOL> param . value = self . replace_visitor . visit ( param . value ) <EOL> localparams = node . get_localparams ( ) <EOL> for localparam in localparams . values ( ) : <EOL> if localparam . width is not None : <EOL> localparam . width = self . replace_visitor . visit ( localparam . width ) <EOL> localparam . value = self . replace_visitor . visit ( localparam . value ) <EOL> ports = node . get_ports ( ) <EOL> for port in ports . values ( ) : <EOL> if port . width is not None : <EOL> port . width = self . replace_visitor . visit ( port . width ) <EOL> vars = node . get_vars ( ) <EOL> for var in vars . values ( ) : <EOL> if var . width is not None : <EOL> var . width = self . replace_visitor . visit ( var . width ) <EOL> for asg in node . assign : <EOL> self . visit ( asg ) <EOL> for alw in node . always : <EOL> self . visit ( alw ) <EOL> for ini in node . initial : <EOL> self . visit ( ini ) <EOL> for ins in node . instance . values ( ) : <EOL> self . visit ( ins ) <EOL> return node <EOL> def visit__Variable ( self , node ) : <EOL> width = self . replace_visitor . visit ( node . width ) if node . width is not None else None <EOL> length = self . replace_visitor . visit ( node . length ) if node . length is not None else None <EOL> initval = self . replace_visitor . visit ( node . initval ) if node . initval is not None else None <EOL> if check_constant ( width ) : <EOL> node . width = width <EOL> if check_constant ( length ) : <EOL> node . length = length <EOL> if check_constant ( initval ) : <EOL> node . initval = initval <EOL> return node <EOL> def visit_Always ( self , node ) : <EOL> sensitivity = self . replace_visitor . visit ( node . sensitivity ) <EOL> self . replace_visitor . visit ( node . statement ) <EOL> if check_constant ( sensitivity ) : <EOL> node . sensitivity = sensitivity <EOL> return node <EOL> def visit_Assign ( self , node ) : <EOL> self . replace_visitor . visit ( node . statement ) <EOL> return node <EOL> def visit_Initial ( self , node ) : <EOL> for s in node . statement : <EOL> self . replace_visitor . visit ( s ) <EOL> return node <EOL> def visit_Instance ( self , node ) : <EOL> params = [ ( k , self . replace_visitor . visit ( v ) ) for k , v in node . params ] <EOL> ports = [ ( k , self . replace_visitor . visit ( v ) ) for k , v in node . ports ] <EOL> node . params = params <EOL> node . ports = ports <EOL> inst_const_dict = OrderedDict ( ) <EOL> for k , v in params : <EOL> inst_const_dict [ k ] = v <EOL> if isinstance ( node . module , ( module . StubModule , str ) ) : <EOL> return node <EOL> mod = copy . deepcopy ( node . module ) <EOL> prev_name = mod . name <EOL> new_name = prev_name <EOL> while True : <EOL> if new_name not in self . submodule : <EOL> self . submodule [ new_name ] = mod <EOL> self . mod . submodule [ new_name ] = mod <EOL> mod . name = new_name <EOL> break <EOL> new_name = '<STR_LIT:_>' . join ( [ prev_name , '<STR_LIT>' , str ( ModuleReplaceVisitor . tmp_count ) ] ) <EOL> ModuleReplaceVisitor . tmp_count += <NUM_LIT:1> <EOL> mvisitor = ModuleReplaceVisitor ( mod , inst_const_dict , self . submodule ) <EOL> mod = mvisitor . resolve ( ) <EOL> node . module = mod <EOL> return node <EOL> def visit_GenerateFor ( self , node ) : <EOL> raise NotImplementedError ( "<STR_LIT>" ) <EOL> def visit_GenerateIf ( self , node ) : <EOL> raise NotImplementedError ( "<STR_LIT>" ) <EOL> def resolve ( m , const_dict = None ) : <EOL> mvisitor = ModuleReplaceVisitor ( m , const_dict ) <EOL> return mvisitor . resolve ( ) </s>
