OpenCores
URL https://opencores.org/ocsvn/ssbcc/ssbcc/trunk

Subversion Repositories ssbcc

[/] [ssbcc/] [trunk/] [ssbccUtil.py] - Blame information for rev 12

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 sinclairrf
################################################################################
2
#
3
# Copyright 2012, Sinclair R.F., Inc.
4
#
5
# Utilities required by ssbcc
6
#
7
################################################################################
8
 
9
import math
10 3 sinclairrf
import os
11 2 sinclairrf
import re
12
 
13
################################################################################
14
#
15
# Classes
16
#
17
################################################################################
18
 
19
class SSBCCException(Exception):
20
  """
21
  Exception class for ssbcc.
22
  """
23
  def __init__(self,message):
24
    self.message = message;
25
  def __str__(self):
26
    return self.message;
27
 
28
################################################################################
29
#
30
# Methods
31
#
32
################################################################################
33
 
34
def CeilLog2(v):
35
  """
36
  Return the smallest integer that has a power of 2 greater than or equal to
37
  the argument.
38
  """
39
  tmp = int(math.log(v,2));
40
  while 2**tmp < v:
41
    tmp = tmp + 1;
42
  return tmp;
43
 
44
def CeilPow2(v):
45
  """
46
  Return the smallest power of 2 greater than or equal to the argument.
47
  """
48
  return 2**CeilLog2(v);
49
 
50
def ExtractBits(v,bits):
51
  """
52
  Extract the bits specified by bits from v.
53
  bits must have a Verilog-type format.  I.e., [7:0], [0+:8], etc.
54
  """
55
  if type(v) != int:
56
    raise SSBCCException('%s must be an int' % v);
57
  if re.match(r'[[]\d+:\d+]$',bits):
58
    cmd = re.findall(r'[[](\d+):(\d+)]$',bits)[0];
59
    b0 = int(cmd[1]);
60
    bL = int(cmd[0]) - b0 + 1;
61
  elif re.match(r'[[]\d+\+:\d+]$',bits):
62
    cmd = re.findall(r'[[](\d+)\+:(\d+)]$',bits)[0];
63
    b0 = int(cmd[0]);
64
    bL = int(cmd[1]);
65
  else:
66
    raise SSBCCException('Unrecognized bit slice format:  %s' % bits);
67
  if not 1 <= bL <= 8:
68
    raise SSBCCException('Malformed range "%s" doesn\'t provide 1 to 8 bits' % bits)
69
  v /= 2**b0;
70
  v %= 2**bL;
71
  return v;
72
 
73 12 sinclairrf
def InitSignal(nBits,v):
74
  """
75
  Generate an initial value for a Verilog signal.
76
  """
77
  if v == None:
78
    return None;
79
  elif type(v) == str:
80
    return v;
81
  elif type(v) == int:
82
    format = '%d\'h%%0%dX' % (nBits,int((nBits+3)/4),);
83
    return format % v;
84
  else:
85
    raise Exception('Program Bug:  unrecognized signal type "%s"' % type(signalInit))
86
 
87 2 sinclairrf
def IntValue(v):
88
  """
89
  Convert a Verilog format integer into an integer value.
90
  """
91 3 sinclairrf
  save_v = v;
92
  if re.match(r'([1-9]\d*)?\'[bodh]',v):
93
    length = 0;
94
    while v[0] != '\'':
95
      length *= 10;
96
      length += ord(v[0]) - ord('0');
97
      v = v[1:];
98
    v=v[1:];
99
    if v[0] == 'b':
100
      base = 2;
101
    elif v[0] == 'o':
102
      base = 8;
103
    elif v[0] == 'd':
104
      base = 10;
105
    elif v[0] == 'h':
106
      base = 16;
107
    else:
108
      raise Exception('Program bug -- unrecognized base:  "%c"' % v[0]);
109
    v = v[1:];
110
  else:
111
    length = 0;
112
    base = 10;
113 2 sinclairrf
  ov = 0;
114 3 sinclairrf
  for vv in [v[i] for i in range(len(v)) if v[i] != '_']:
115
    ov *= base;
116
    try:
117
      dv = int(vv,base);
118
    except:
119
      raise SSBCCException('Malformed parameter value:  "%s"' % save_v);
120
    ov += dv;
121
  if length > 0 and ov >= 2**length:
122 9 sinclairrf
    raise SSBCCException('Parameter length and value don\'t match:  "%s"' % save_v);
123 2 sinclairrf
  return ov;
124
 
125 8 sinclairrf
def IsIntExpr(value):
126
  """
127
  Test the string to see if it is a well-formatted integer or multiplication of
128
  two integers.
129
  Allow underscores as per Verilog.
130
  """
131 11 sinclairrf
  if re.match(r'(0|-?[1-9][0-9_]*)$',value):
132 8 sinclairrf
    return True;
133 11 sinclairrf
  elif re.match(r'(-?[1-9][0-9_]*\(\*[1-9][0-9_]*\)+)$',value):
134 8 sinclairrf
    return True;
135
  else:
136
    return False;
137
 
138 6 sinclairrf
def IsPosInt(v):
139
  """
140
  Indicate whether or not the argument is a positive integer.
141
  """
142
  return re.match(r'[1-9][0-9_]*$',v);
143
 
144 2 sinclairrf
def IsPowerOf2(v):
145
  """
146
  Indicate whether or not the argument is a power of 2.
147
  """
148
  return v == 2**int(math.log(v,2)+0.5);
149
 
150 3 sinclairrf
def LoadFile(filename,config):
151 2 sinclairrf
  """
152
  Load the file into a list with the line contents and line numbers.\n
153
  filename is either the name of the file or a file object.\n
154
  Note:  The file object is closed in either case.
155
  """
156
  if type(filename) == str:
157 3 sinclairrf
    for path in config.includepaths:
158
      fullfilename = os.path.join(path,filename);
159
      if os.path.isfile(fullfilename):
160
        try:
161
          fp = file(fullfilename);
162
        except:
163
          raise SSBCCException('Error opening "%s"' % filename);
164
        break;
165
    else:
166
      raise SSBCCException('.INCLUDE file "%s" not found' % filename);
167 2 sinclairrf
  elif type(filename) == file:
168 3 sinclairrf
    fp = filename;
169 2 sinclairrf
  else:
170
    raise Exception('Unexpected argument type:  %s' % type(filename))
171
  v = list();
172
  ixLine = 0;
173 3 sinclairrf
  for tmpLine in fp:
174 2 sinclairrf
    ixLine += 1;
175
    while tmpLine and tmpLine[-1] in ('\n','\r',):
176
      tmpLine = tmpLine[0:-1];
177
    v.append((tmpLine,ixLine,));
178 3 sinclairrf
  fp.close();
179 2 sinclairrf
  return v;
180
 
181 8 sinclairrf
def ParseIntExpr(value):
182
  """
183
  Convert a string containing well-formatted integer or multiplication of two
184
  integers.
185
  Allow underscores as per Verilog.
186
  Note:  If this routine is called, then the value should have already been
187
         verified to be a well-formatted integer string.
188
  """
189 9 sinclairrf
  if type(value) == int:
190
    return value;
191 8 sinclairrf
  if not IsIntExpr(value):
192
    raise Exception('Program Bug -- shouldn\'t call with a badly formatted integer expression');
193
  return eval(re.sub('_','',value));
194
 
195 2 sinclairrf
################################################################################
196
#
197
# Unit test.
198
#
199
################################################################################
200
 
201
if __name__ == "__main__":
202
 
203
  def Test_ExtractBits(v,bits,vExpect):
204
    vGot = ExtractBits(v,bits);
205
    if vGot != vExpect:
206
      raise Exception('ExtractBits failed: 0x%04X %s ==> 0x%02X instead of 0x%02X' % (v,bits,ExtractBits(v,bits),vExpect,));
207
 
208
  for v in (256,257,510,):
209
    Test_ExtractBits(v,'[0+:8]',v%256);
210
    Test_ExtractBits(v,'[7:0]',v%256);
211
    Test_ExtractBits(v,'[4+:6]',(v/16)%64);
212
    Test_ExtractBits(v,'[9:4]',(v/16)%64);
213
 
214
  print 'Unit test passed';

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.