Line 1... |
Line 1... |
################################################################################
|
################################################################################
|
#
|
#
|
# Copyright 2012-2013, Sinclair R.F., Inc.
|
# Copyright 2012-2014, Sinclair R.F., Inc.
|
#
|
#
|
################################################################################
|
################################################################################
|
|
|
from ssbccPeripheral import SSBCCperipheral
|
from ssbccPeripheral import SSBCCperipheral
|
from ssbccUtil import SSBCCException;
|
from ssbccUtil import SSBCCException;
|
Line 96... |
Line 96... |
|
|
def __init__(self,peripheralFile,config,param_list,loc):
|
def __init__(self,peripheralFile,config,param_list,loc):
|
# Use the externally provided file name for the peripheral
|
# Use the externally provided file name for the peripheral
|
self.peripheralFile = peripheralFile;
|
self.peripheralFile = peripheralFile;
|
# Get the parameters.
|
# Get the parameters.
|
|
allowables = (
|
|
( 'outport', r'O_\w+$', None, ),
|
|
( 'outsignal', r'o_\w+$', None, ),
|
|
( 'ratemethod', r'\S+$', lambda v : self.RateMethod(config,v), ),
|
|
( 'invert', None, True, ),
|
|
( 'noinvert', None, True, ),
|
|
( 'instances', r'[1-9]\d*$', int, ),
|
|
( 'norunt', None, True, ),
|
|
);
|
|
names = [a[0] for a in allowables];
|
for param_tuple in param_list:
|
for param_tuple in param_list:
|
param = param_tuple[0];
|
param = param_tuple[0];
|
param_arg = param_tuple[1];
|
if param not in names:
|
if param == 'outport':
|
raise SSBCCException('Unrecognized parameter "%s" at %s' % (param,loc,));
|
self.AddAttr(config,param,param_arg,r'O_\w+$',loc);
|
param_test = allowables[names.index(param)];
|
elif param == 'outsignal':
|
self.AddAttr(config,param,param_tuple[1],param_test[1],loc,param_test[2]);
|
self.AddAttr(config,param,param_arg,r'o_\w+$',loc);
|
|
elif param == 'ratemethod':
|
|
self.ProcessRateMethod(config,param_arg,loc);
|
|
elif param == 'invert':
|
|
self.AddAttr(config,param,param_arg,None,loc);
|
|
elif param == 'noinvert':
|
|
self.AddAttr(config,param,param_arg,None,loc);
|
|
elif param == 'instances':
|
|
self.AddAttr(config,param,param_arg,r'[1-9]\d*$',loc,int);
|
|
elif param == 'norunt':
|
|
self.AddAttr(config,param,param_arg,None,loc);
|
|
else:
|
|
raise SSBCCException('Unrecognized parameter at %s: %s' % (loc,param,));
|
|
# Ensure the required parameters are provided.
|
# Ensure the required parameters are provided.
|
if not hasattr(self,'instances'):
|
for paramname in (
|
self.instances = 1;
|
'outport',
|
|
'outsignal',
|
|
'ratemethod',
|
|
):
|
|
if not hasattr(self,paramname):
|
|
raise SSBCCException('Required parameter "%s" is missing at %s' % (paramname,loc,));
|
# Set optional parameters.
|
# Set optional parameters.
|
if not hasattr(self,'invert') and not hasattr(self,'noinvert'):
|
for optionalpair in (
|
self.noinvert = True;
|
( 'instances', 1, ),
|
if not hasattr(self,'norunt'):
|
( 'norunt', False, ),
|
self.norunt = False;
|
):
|
# Ensure parameters do not conflict.
|
if not hasattr(self,optionalpair[0]):
|
if hasattr(self,'invert') and hasattr(self,'noinvert'):
|
setattr(self,optionalpair[0],optionalpair[1]);
|
raise SSBCCException('Only one of "invert" or "noinvert" can be specified at %s' % loc);
|
# Ensure exclusive pair configurations are set and consistent.
|
# Use only one of mutually exclusive configuration settings.
|
for exclusivepair in (
|
if hasattr(self,'noinvert'):
|
( 'invert', 'noinvert', 'noinvert', True, ),
|
self.invert = False;
|
):
|
|
if hasattr(self,exclusivepair[0]) and hasattr(self,exclusivepair[1]):
|
|
raise SSBCCException('Only one of "%s" and "%s" can be specified at %s' % (exclusivepair[0],exclusivepair[1],loc,));
|
|
if not hasattr(self,exclusivepair[0]) and not hasattr(self,exclusivepair[1]) and exclusivepair[2]:
|
|
setattr(self,exclusivepair[2],exclusivepair[3]);
|
# Add the I/O port, internal signals, and the INPORT and OUTPORT symbols for this peripheral.
|
# Add the I/O port, internal signals, and the INPORT and OUTPORT symbols for this peripheral.
|
config.AddIO(self.outsignal,self.instances,'output',loc);
|
config.AddIO(self.outsignal,self.instances,'output',loc);
|
self.ix_outport_0 = config.NOutports();
|
self.ix_outport_0 = config.NOutports();
|
if self.instances == 1:
|
if self.instances == 1:
|
tmpOutport = self.outport;
|
tmpOutport = self.outport;
|
Line 142... |
Line 148... |
tmpOutport = '%s_%d' % (self.outport,ixOutPort,);
|
tmpOutport = '%s_%d' % (self.outport,ixOutPort,);
|
config.AddOutport((tmpOutport,False,),loc);
|
config.AddOutport((tmpOutport,False,),loc);
|
# Add the 'clog2' function to the processor (if required).
|
# Add the 'clog2' function to the processor (if required).
|
config.functions['clog2'] = True;
|
config.functions['clog2'] = True;
|
|
|
def ProcessRateMethod(self,config,param_arg,loc):
|
|
if hasattr(self,'ratemethod'):
|
|
raise SSBCCException('ratemethod repeated at %s' % loc);
|
|
if param_arg.find('/') < 0:
|
|
if self.IsIntExpr(param_arg):
|
|
self.ratemethod = str(self.ParseIntExpr(param_arg));
|
|
elif self.IsParameter(config,param_arg):
|
|
self.ratemethod = param_arg;
|
|
else:
|
|
raise SSBCCException('ratemethod with no "/" must be an integer or a previously declared parameter at %s' % loc);
|
|
else:
|
|
baudarg = re.findall('([^/]+)',param_arg);
|
|
if len(baudarg) == 2:
|
|
if not self.IsIntExpr(baudarg[0]) and not self.IsParameter(config,baudarg[0]):
|
|
raise SSBCCException('Numerator in ratemethod must be an integer or a previously declared parameter at %s' % loc);
|
|
if not self.IsIntExpr(baudarg[1]) and not self.IsParameter(config,baudarg[1]):
|
|
raise SSBCCException('Denominator in ratemethod must be an integer or a previously declared parameter at %s' % loc);
|
|
for ix in range(2):
|
|
if self.IsIntExpr(baudarg[ix]):
|
|
baudarg[ix] = str(self.ParseIntExpr(baudarg[ix]));
|
|
self.ratemethod = '('+baudarg[0]+'+'+baudarg[1]+'/2)/'+baudarg[1];
|
|
if not hasattr(self,'ratemethod'):
|
|
raise SSBCCException('Bad ratemethod value at %s: "%s"' % (loc,param_arg,));
|
|
|
|
def GenVerilog(self,fp,config):
|
def GenVerilog(self,fp,config):
|
body = self.LoadCore(self.peripheralFile,'.v');
|
body = self.LoadCore(self.peripheralFile,'.v');
|
output_on = "1'b1";
|
output_on = "1'b1";
|
output_off = "1'b0";
|
output_off = "1'b0";
|
if self.invert:
|
if hasattr(self,'invert'):
|
output_on = "1'b0";
|
output_on = "1'b0";
|
output_off = "1'b1";
|
output_off = "1'b1";
|
norunt = "1'b0";
|
for subpair in (
|
if self.norunt:
|
|
norunt = "1'b1";
|
|
for subs in (
|
|
(r'\bL__', 'L__@NAME@__',),
|
(r'\bL__', 'L__@NAME@__',),
|
(r'\bgen__', 'gen__@NAME@__',),
|
(r'\bgen__', 'gen__@NAME@__',),
|
(r'\bs__', 's__@NAME@__',),
|
(r'\bs__', 's__@NAME@__',),
|
(r'\bix\b', 'ix__@NAME@',),
|
(r'\bix\b', 'ix__@NAME@',),
|
(r'@COUNT@', self.ratemethod,),
|
(r'@COUNT@', self.ratemethod,),
|
(r'@INSTANCES@', str(self.instances),),
|
(r'@INSTANCES@', str(self.instances),),
|
(r'@IX_OUTPORT_0@', str(self.ix_outport_0),),
|
(r'@IX_OUTPORT_0@', str(self.ix_outport_0),),
|
(r'@OFF@', output_off,),
|
(r'@OFF@', output_off,),
|
(r'@ON@', output_on,),
|
(r'@ON@', output_on,),
|
(r'@NAME@', self.outsignal,),
|
(r'@NAME@', self.outsignal,),
|
(r'@NORUNT@', norunt,),
|
( r'@NORUNT@', '1\'b1' if self.norunt else '1\'b0', ),
|
):
|
):
|
body = re.sub(subs[0],subs[1],body);
|
body = re.sub(subpair[0],subpair[1],body);
|
body = self.GenVerilogFinal(config,body);
|
body = self.GenVerilogFinal(config,body);
|
fp.write(body);
|
fp.write(body);
|
|
|
No newline at end of file
|
No newline at end of file
|