88import textwrap
99
1010import veriloggen .core .vtypes as vtypes
11-
11+ import veriloggen . types . fixed as fixed
1212from . import optimizer
1313from .scope import ScopeName , ScopeFrameList , ScopeFrame
14- from .operator import getVeriloggenOp
14+ from .operator import getVeriloggenOp , getMethodName
15+ from . import fixed_intrinsics as fi
16+
1517
18+ numerical_types = vtypes .numerical_types
1619
1720_tmp_count = 0
1821
@@ -45,18 +48,6 @@ def visit_FunctionDef(self, node):
4548 self .functions [node .name ] = node
4649
4750
48- class TargetVisitor (ast .NodeVisitor ):
49-
50- def visit_List (self , node ):
51- return [self .visit (elt ) for elt in node .elts ]
52-
53- def visit_Tuple (self , node ):
54- return [self .visit (elt ) for elt in node .elts ]
55-
56- def visit_Name (self , node ):
57- return node .id
58-
59-
6051class CompileVisitor (ast .NodeVisitor ):
6152
6253 def __init__ (self , m , name , clk , rst , fsm ,
@@ -76,7 +67,19 @@ def __init__(self, m, name, clk, rst, fsm,
7667 self .local_objects = local_objects
7768 self .datawidth = datawidth
7869
79- self .targetvisitor = TargetVisitor ()
70+ # fixed intrinsics
71+ fixed_intrinsics = {
72+ 'FixedInput' : fi ._intrinsic_FixedInput ,
73+ 'FixedOutput' : fi ._intrinsic_FixedOutput ,
74+ 'FixedOutputReg' : fi ._intrinsic_FixedOutputReg ,
75+ 'FixedReg' : fi ._intrinsic_FixedReg ,
76+ 'FixedWire' : fi ._intrinsic_FixedWire ,
77+ 'to_fixed' : fi ._intrinsic_to_fixed ,
78+ 'fixed_to_int' : fi ._intrinsic_fixed_to_int ,
79+ 'fixed_to_int_low' : fi ._intrinsic_fixed_to_int_low ,
80+ 'fixed_to_real' : fi ._intrinsic_fixed_to_real ,
81+ }
82+ self .intrinsic_functions .update (fixed_intrinsics )
8083
8184 self .scope = ScopeFrameList ()
8285 self .loop_info = OrderedDict ()
@@ -104,28 +107,39 @@ def visit_Assign(self, node):
104107
105108 right = self .visit (node .value )
106109 lefts = [self .visit (target ) for target in node .targets ]
107- raw_lefts = [self .targetvisitor .visit (target )
108- for target in node .targets ]
109110
110- for raw_left , left in zip ( raw_lefts , lefts ) :
111- self ._assign (raw_left , left , right )
111+ for left in lefts :
112+ self ._assign (left , right )
112113
113114 self .setFsm ()
114115 self .incFsmCount ()
115116
116- def _assign (self , raw_left , left , right ):
117- raw_dsts = raw_left if isinstance (
118- raw_left , (tuple , list )) else (raw_left ,)
117+ def _variable_type (self , right ):
118+ if isinstance (right , vtypes ._Numeric ):
119+ return None
120+ if isinstance (right , fixed ._FixedBase ):
121+ ret = {'type' : 'fixed' ,
122+ 'width' : right .bit_length (),
123+ 'point' : right .point ,
124+ 'signed' : right .signed }
125+ return ret
126+ raise TypeError ('unsupported type' )
127+
128+ def _assign (self , left , right ):
119129 dsts = left if isinstance (left , (tuple , list )) else (left ,)
120130
121131 if not isinstance (right , (tuple , list )):
122132 if len (dsts ) > 1 :
123133 raise ValueError (
124- "too many values to unpack (expected %d)" % len (right ))
125- self .setAssignBind (raw_dsts [0 ], dsts [0 ], right )
134+ "too many values to unpack (expected %d)" % 1 )
135+ _type = self ._variable_type (right )
136+ var = self .getVariable (dsts [0 ], store = True , _type = _type )
137+ self .setAssignBind (var , right )
126138
127139 elif len (dsts ) == 1 :
128- self .setAssignBind (raw_dsts [0 ], dsts [0 ], right )
140+ _type = self ._variable_type (right )
141+ var = self .getVariable (dsts [0 ], store = True , _type = _type )
142+ self .setAssignBind (var , right )
129143
130144 elif len (dsts ) < len (right ):
131145 raise ValueError (
@@ -136,14 +150,15 @@ def _assign(self, raw_left, left, right):
136150 (len (dsts ), len (right )))
137151
138152 else :
139- for raw_l , l , r in zip (raw_dsts , dsts , right ):
140- self ._assign (raw_l , l , r )
153+ for d , r in zip (dsts , right ):
154+ self ._assign (d , r )
141155
142156 def visit_AugAssign (self , node ):
143157 if self .skip ():
144158 return
145159 right = self .visit (node .value )
146- left = self .visit (node .target )
160+ left_name = self .visit (node .target )
161+ left = self .getVariable (left_name , store = True )
147162 op = getVeriloggenOp (node .op )
148163 if op is None :
149164 raise TypeError ("Unsupported BinOp: %s" % str (node .op ))
@@ -263,7 +278,8 @@ def _for_range(self, node):
263278 if len (node .iter .args ) < 3
264279 else self .visit (node .iter .args [2 ]))
265280
266- iter_node = self .visit (node .target )
281+ iter_name = self .visit (node .target )
282+ iter_node = self .getVariable (iter_name , store = True )
267283 cond_node = vtypes .LessThan (iter_node , end_node )
268284 update_node = vtypes .Plus (iter_node , step_node )
269285
@@ -326,7 +342,8 @@ def _for_range_fsm(self, begin_node, end_node, step_node,
326342 self .setFsmLoop (check_count , body_end_count , iter_node , step_node )
327343
328344 def _for_list (self , node ):
329- target = self .visit (node .target )
345+ target_name = self .visit (node .target )
346+ target = self .getVariable (target_name , store = True )
330347 iterobj = self .visit (node .iter )
331348
332349 begin_node = vtypes .Int (0 )
@@ -341,7 +358,7 @@ def _for_list(self, node):
341358
342359 patterns = []
343360 for i , obj in enumerate (iterobj ):
344- if not isinstance (obj , vtypes . numerical_types ):
361+ if not isinstance (obj , numerical_types ):
345362 raise TypeError ("unsupported type for for-statement" )
346363 patterns .append ((iter_node == i , obj ))
347364 patterns .append ((None , vtypes .IntX ()))
@@ -454,7 +471,7 @@ def _call_Name_len(self, node):
454471 raise TypeError (
455472 'takes %d positional arguments but %d were given' % (1 , len (node .args )))
456473 value = self .visit (node .args [0 ])
457- if not isinstance (value , vtypes . numerical_types ):
474+ if not isinstance (value , numerical_types ):
458475 return len (value )
459476
460477 length = getattr (value , 'length' , None )
@@ -782,7 +799,10 @@ def visit_Name(self, node):
782799 return vtypes .Int (0 )
783800
784801 store = isinstance (node .ctx , ast .Store )
785- name = self .getVariable (node .id , store )
802+ if store :
803+ return node .id
804+
805+ name = self .getVariable (node .id )
786806 return name
787807
788808 def visit_Print (self , node ):
@@ -837,7 +857,7 @@ def visit_Print(self, node):
837857 def visit_Attribute (self , node ):
838858 value = self .visit (node .value )
839859 attr = node .attr
840- if isinstance (value , vtypes . _Variable ) and attr == 'value' :
860+ if isinstance (value , numerical_types ) and attr == 'value' :
841861 return value
842862 obj = getattr (value , attr )
843863 return obj
@@ -897,13 +917,34 @@ def skip(self):
897917 val = self .hasBreak () or self .hasContinue () or self .hasReturn ()
898918 return val
899919
900- def makeVariable (self , name , width = None , initval = 0 ):
920+ def makeVariable (self , name , _type = None ):
921+ if _type is None :
922+ return self .makeVariableReg (name )
923+
924+ if _type ['type' ] == 'fixed' :
925+ width = _type ['width' ]
926+ point = _type ['point' ]
927+ signed = _type ['signed' ]
928+ return self .makeVariableFixed (name , width , point , signed )
929+
930+ raise TypeError ("not supported variable type" )
931+
932+ def makeVariableReg (self , name , width = None , initval = 0 ):
901933 signame = _tmp_name ('_' .join (['' , self .name , name ]))
902934 if width is None :
903935 width = self .datawidth
904936 return self .m .Reg (signame , width , initval = initval , signed = True )
905937
906- def getVariable (self , name , store = False ):
938+ def makeVariableFixed (self , name , width = None , point = 0 , signed = True ):
939+ signame = _tmp_name ('_' .join (['' , self .name , name ]))
940+ if width is None :
941+ width = self .datawidth
942+ return fixed .FixedReg (self .m , signame , width = width , point = point , signed = signed )
943+
944+ def getVariable (self , name , store = False , _type = None ):
945+ if isinstance (name , vtypes ._Numeric ):
946+ return name
947+
907948 var = self .scope .searchVariable (name , store )
908949 if var is None :
909950 if not store :
@@ -913,14 +954,14 @@ def getVariable(self, name, store=False):
913954 if glb is not None :
914955 return glb
915956 raise NameError ("name '%s' is not defined" % name )
916- var = self .makeVariable (name )
957+ var = self .makeVariable (name , _type = _type )
917958 self .scope .addVariable (name , var )
918959 var = self .scope .searchVariable (name )
919960 return var
920961
921- def getTmpVariable (self ):
962+ def getTmpVariable (self , _type = None ):
922963 name = _tmp_name ('tmp' )
923- var = self .getVariable (name , store = True )
964+ var = self .getVariable (name , store = True , _type = _type )
924965 return var
925966
926967 def getGlobalObject (self , name ):
@@ -952,42 +993,47 @@ def getFunction(self, name):
952993 raise NameError ("function '%s' is not defined" % name )
953994
954995 def setArgBind (self , name , value ):
955- if not isinstance (value , vtypes . numerical_types ):
996+ if not isinstance (value , numerical_types ):
956997 self .scope .addVariable (name , value )
957998 return
958999
959- left = self .getVariable (name , store = True )
9601000 right = optimize (value )
1001+ left = self .getVariable (name , store = True )
1002+
9611003 self .setBind (left , right )
9621004
9631005 def setVarargBind (self , name , values ):
9641006 lefts = []
9651007 for value in values :
966- if isinstance (value , vtypes .numerical_types ):
967- left = self .getTmpVariable ()
1008+ if isinstance (value , numerical_types ):
9681009 right = optimize (value )
1010+ left = self .getTmpVariable ()
1011+
9691012 self .setBind (left , right )
9701013 lefts .append (left )
9711014 else :
9721015 lefts .append (value )
9731016 self .scope .addVariable (name , lefts )
9741017
975- def setAssignBind (self , dst , var , value ):
976- if not isinstance (value , vtypes .numerical_types ):
977- #self.scope.addVariable(dst, value)
978- # return
1018+ def setAssignBind (self , dst , value ):
1019+ if not isinstance (value , numerical_types ):
9791020 raise TypeError ("dynamic object substitution is not supported" )
9801021
981- self .setBind (var , value )
1022+ self .setBind (dst , value )
9821023
9831024 def setBind (self , var , value , cond = None ):
9841025 if var is None :
9851026 cond = None
9861027
1028+ if isinstance (var , fixed ._FixedVariable ) and isinstance (value , fixed ._FixedBase ):
1029+ if var .point != value .point :
1030+ raise ValueError ("Fixed point not match: %d <- %d" %
1031+ var .point , value .point )
1032+
9871033 value = optimize (value )
9881034 cond = optimize (cond ) if cond is not None else None
9891035 subst = (vtypes .SingleStatement (value ) if var is None else
990- vtypes . Subst ( var , value ))
1036+ var . write ( value ))
9911037
9921038 if var is not None :
9931039 if hasattr (var , '_fsm' ) and id (var ._fsm ) != id (self .fsm ):
0 commit comments