################################################################################
|
################################################################################
|
#
|
#
|
# Copyright 2012, Sinclair R.F., Inc.
|
# Copyright 2012, Sinclair R.F., Inc.
|
#
|
#
|
# Utilities required by ssbcc
|
# Utilities required by ssbcc
|
#
|
#
|
################################################################################
|
################################################################################
|
|
|
import math
|
import math
|
|
import os
|
import re
|
import re
|
|
|
################################################################################
|
################################################################################
|
#
|
#
|
# Classes
|
# Classes
|
#
|
#
|
################################################################################
|
################################################################################
|
|
|
class SSBCCException(Exception):
|
class SSBCCException(Exception):
|
"""
|
"""
|
Exception class for ssbcc.
|
Exception class for ssbcc.
|
"""
|
"""
|
def __init__(self,message):
|
def __init__(self,message):
|
self.message = message;
|
self.message = message;
|
def __str__(self):
|
def __str__(self):
|
return self.message;
|
return self.message;
|
|
|
################################################################################
|
################################################################################
|
#
|
#
|
# Methods
|
# Methods
|
#
|
#
|
################################################################################
|
################################################################################
|
|
|
def CeilLog2(v):
|
def CeilLog2(v):
|
"""
|
"""
|
Return the smallest integer that has a power of 2 greater than or equal to
|
Return the smallest integer that has a power of 2 greater than or equal to
|
the argument.
|
the argument.
|
"""
|
"""
|
tmp = int(math.log(v,2));
|
tmp = int(math.log(v,2));
|
while 2**tmp < v:
|
while 2**tmp < v:
|
tmp = tmp + 1;
|
tmp = tmp + 1;
|
return tmp;
|
return tmp;
|
|
|
def CeilPow2(v):
|
def CeilPow2(v):
|
"""
|
"""
|
Return the smallest power of 2 greater than or equal to the argument.
|
Return the smallest power of 2 greater than or equal to the argument.
|
"""
|
"""
|
return 2**CeilLog2(v);
|
return 2**CeilLog2(v);
|
|
|
def ExtractBits(v,bits):
|
def ExtractBits(v,bits):
|
"""
|
"""
|
Extract the bits specified by bits from v.
|
Extract the bits specified by bits from v.
|
bits must have a Verilog-type format. I.e., [7:0], [0+:8], etc.
|
bits must have a Verilog-type format. I.e., [7:0], [0+:8], etc.
|
"""
|
"""
|
if type(v) != int:
|
if type(v) != int:
|
raise SSBCCException('%s must be an int' % v);
|
raise SSBCCException('%s must be an int' % v);
|
if re.match(r'[[]\d+:\d+]$',bits):
|
if re.match(r'[[]\d+:\d+]$',bits):
|
cmd = re.findall(r'[[](\d+):(\d+)]$',bits)[0];
|
cmd = re.findall(r'[[](\d+):(\d+)]$',bits)[0];
|
b0 = int(cmd[1]);
|
b0 = int(cmd[1]);
|
bL = int(cmd[0]) - b0 + 1;
|
bL = int(cmd[0]) - b0 + 1;
|
elif re.match(r'[[]\d+\+:\d+]$',bits):
|
elif re.match(r'[[]\d+\+:\d+]$',bits):
|
cmd = re.findall(r'[[](\d+)\+:(\d+)]$',bits)[0];
|
cmd = re.findall(r'[[](\d+)\+:(\d+)]$',bits)[0];
|
b0 = int(cmd[0]);
|
b0 = int(cmd[0]);
|
bL = int(cmd[1]);
|
bL = int(cmd[1]);
|
else:
|
else:
|
raise SSBCCException('Unrecognized bit slice format: %s' % bits);
|
raise SSBCCException('Unrecognized bit slice format: %s' % bits);
|
if not 1 <= bL <= 8:
|
if not 1 <= bL <= 8:
|
raise SSBCCException('Malformed range "%s" doesn\'t provide 1 to 8 bits' % bits)
|
raise SSBCCException('Malformed range "%s" doesn\'t provide 1 to 8 bits' % bits)
|
v /= 2**b0;
|
v /= 2**b0;
|
v %= 2**bL;
|
v %= 2**bL;
|
return v;
|
return v;
|
|
|
def IntValue(v):
|
def IntValue(v):
|
"""
|
"""
|
Convert a Verilog format integer into an integer value.
|
Convert a Verilog format integer into an integer value.
|
"""
|
"""
|
|
save_v = v;
|
|
if re.match(r'([1-9]\d*)?\'[bodh]',v):
|
|
length = 0;
|
|
while v[0] != '\'':
|
|
length *= 10;
|
|
length += ord(v[0]) - ord('0');
|
|
v = v[1:];
|
|
v=v[1:];
|
|
if v[0] == 'b':
|
|
base = 2;
|
|
elif v[0] == 'o':
|
|
base = 8;
|
|
elif v[0] == 'd':
|
|
base = 10;
|
|
elif v[0] == 'h':
|
|
base = 16;
|
|
else:
|
|
raise Exception('Program bug -- unrecognized base: "%c"' % v[0]);
|
|
v = v[1:];
|
|
else:
|
|
length = 0;
|
|
base = 10;
|
ov = 0;
|
ov = 0;
|
for vv in [v[i] for i in range(len(v)) if '0' <= v[i] <= '9']:
|
for vv in [v[i] for i in range(len(v)) if v[i] != '_']:
|
ov *= 10;
|
ov *= base;
|
ov += ord(vv)-ord('0');
|
try:
|
|
dv = int(vv,base);
|
|
except:
|
|
raise SSBCCException('Malformed parameter value: "%s"' % save_v);
|
|
ov += dv;
|
|
if length > 0 and ov >= 2**length:
|
|
raise SSBCCException('Paramter length and value don\'t match: "%s"' % save_v);
|
return ov;
|
return ov;
|
|
|
def IsPowerOf2(v):
|
def IsPowerOf2(v):
|
"""
|
"""
|
Indicate whether or not the argument is a power of 2.
|
Indicate whether or not the argument is a power of 2.
|
"""
|
"""
|
return v == 2**int(math.log(v,2)+0.5);
|
return v == 2**int(math.log(v,2)+0.5);
|
|
|
def LoadFile(filename):
|
def LoadFile(filename,config):
|
"""
|
"""
|
Load the file into a list with the line contents and line numbers.\n
|
Load the file into a list with the line contents and line numbers.\n
|
filename is either the name of the file or a file object.\n
|
filename is either the name of the file or a file object.\n
|
Note: The file object is closed in either case.
|
Note: The file object is closed in either case.
|
"""
|
"""
|
if type(filename) == str:
|
if type(filename) == str:
|
|
for path in config.includepaths:
|
|
fullfilename = os.path.join(path,filename);
|
|
if os.path.isfile(fullfilename):
|
try:
|
try:
|
filename = file(filename);
|
fp = file(fullfilename);
|
except:
|
except:
|
raise SSBCCException('Error opening "%s"' % filename);
|
raise SSBCCException('Error opening "%s"' % filename);
|
|
break;
|
|
else:
|
|
raise SSBCCException('.INCLUDE file "%s" not found' % filename);
|
elif type(filename) == file:
|
elif type(filename) == file:
|
pass;
|
fp = filename;
|
else:
|
else:
|
raise Exception('Unexpected argument type: %s' % type(filename))
|
raise Exception('Unexpected argument type: %s' % type(filename))
|
v = list();
|
v = list();
|
ixLine = 0;
|
ixLine = 0;
|
for tmpLine in filename:
|
for tmpLine in fp:
|
ixLine += 1;
|
ixLine += 1;
|
while tmpLine and tmpLine[-1] in ('\n','\r',):
|
while tmpLine and tmpLine[-1] in ('\n','\r',):
|
tmpLine = tmpLine[0:-1];
|
tmpLine = tmpLine[0:-1];
|
v.append((tmpLine,ixLine,));
|
v.append((tmpLine,ixLine,));
|
filename.close();
|
fp.close();
|
return v;
|
return v;
|
|
|
################################################################################
|
################################################################################
|
#
|
#
|
# Unit test.
|
# Unit test.
|
#
|
#
|
################################################################################
|
################################################################################
|
|
|
if __name__ == "__main__":
|
if __name__ == "__main__":
|
|
|
def Test_ExtractBits(v,bits,vExpect):
|
def Test_ExtractBits(v,bits,vExpect):
|
vGot = ExtractBits(v,bits);
|
vGot = ExtractBits(v,bits);
|
if vGot != vExpect:
|
if vGot != vExpect:
|
raise Exception('ExtractBits failed: 0x%04X %s ==> 0x%02X instead of 0x%02X' % (v,bits,ExtractBits(v,bits),vExpect,));
|
raise Exception('ExtractBits failed: 0x%04X %s ==> 0x%02X instead of 0x%02X' % (v,bits,ExtractBits(v,bits),vExpect,));
|
|
|
for v in (256,257,510,):
|
for v in (256,257,510,):
|
Test_ExtractBits(v,'[0+:8]',v%256);
|
Test_ExtractBits(v,'[0+:8]',v%256);
|
Test_ExtractBits(v,'[7:0]',v%256);
|
Test_ExtractBits(v,'[7:0]',v%256);
|
Test_ExtractBits(v,'[4+:6]',(v/16)%64);
|
Test_ExtractBits(v,'[4+:6]',(v/16)%64);
|
Test_ExtractBits(v,'[9:4]',(v/16)%64);
|
Test_ExtractBits(v,'[9:4]',(v/16)%64);
|
|
|
print 'Unit test passed';
|
print 'Unit test passed';
|
|
|