def __init__(self,peripheralFile,config,param_list,loc): # Use the externally provided file name for the peripheral self.peripheralFile = peripheralFile; # Get the parameters. allowables = ( ('inport', r'I_\w+$', None, ), ('ratemethod', r'\S+$', lambda v : self.RateMethod(config,v), ), ); names = [a[0] for a in allowables]; for param_tuple in param_list: param = param_tuple[0]; if param not in names: raise SSBCCException('Unrecognized parameter "%s" at %s' % (param,loc,)); param_test = allowables[names.index(param)]; self.AddAttr(config,param,param_tuple[1],param_test[1],loc,param_test[2]); # Ensure the required parameters are provided. for paramname in names: if not hasattr(self,paramname): raise SSBCCException('Required parameter "%s" is missing at %s' % (paramname,loc,)); # Add the I/O port, internal signals, and the INPORT and OUTPORT symbols for this peripheral. name = 's__%s__expired' % self.inport; config.AddSignal(name, 1, loc); config.AddSignal('s_SETRESET_%s' % name,1,loc); config.AddInport((self.inport, ('s__%s__expired' % self.inport, 1, 'set-reset'), ),loc); # Add the 'clog2' function to the processor (if required). config.functions['clog2'] = True;
def __init__(self,peripheralFile,config,param_list,loc): # Get the parameters. allowables = ( ( 'outport', r'O_\w+$', None, ), ( 'outsignal', r'o_\w+$', None, ), ( 'width', r'(9|[1-9]\d+)$', int, ), ); names = [a[0] for a in allowables]; for param_tuple in param_list: param = param_tuple[0]; if param not in names: raise SSBCCException('Unrecognized parameter "%s" at %s' % (param,loc,)); param_test = allowables[names.index(param)]; self.AddAttr(config,param,param_tuple[1],param_test[1],loc,param_test[2]); # Ensure the required parameters are provided (all parameters are required). for paramname in names: if not hasattr(self,paramname): raise SSBCCException('Required parameter "%s" is missing at %s' % (paramname,loc,)); # There are no optional parameters. # Add the I/O port, internal signals, and the INPORT and OUTPORT symbols for this peripheral. config.AddIO(self.outsignal,self.width,'output',loc); self.ix_outport = config.NOutports(); config.AddOutport((self.outport,False, # empty list ), loc);
def TimeMethod(self, config, value, lowLimit=None, highLimit=None): """ Convert the provided time from the specified units to seconds. """ if not re.match(r'(0|[1-9]\d*)(\.\d*)?(e[+-]?\d+)?[mun]?s$', value): raise SSBCCException('Malformed time value') if value[-2:] == 'ms': v = float(value[:-2]) * 1.e-3 elif value[-2:] == 'us': v = float(value[:-2]) * 1.e-6 elif value[-2:] == 'ns': v = float(value[:-2]) * 1.e-9 else: v = float(value[:-1]) if (lowLimit != None) and (v < lowLimit): raise SSBCCException('%s must be %s or greater' % ( v, lowLimit, )) if (highLimit != None) and (v > highLimit): raise SSBCCException('%s must be %s or smaller' % ( v, highLimit, )) return v
def AddAttr(self,config,name,value,reformat,loc,optFn=None): """ Add attribute to the peripheral: config ssbccConfig object for the procedssor core name attribute name value possibly optional value for the attribute reformat regular expression format for the attribute value Note: reformat=None means the attribute can only be set to True loc file name and line number for error messages optFn optional function to set stored type Note: See IntPow, RateMethod, etc. below for example methods. """ if hasattr(self,name): raise SSBCCException('%s repeated at %s' % (name,loc,)); if reformat == None: if value != None: raise SSBCCException('No parameter allowed for %s at %s' % (name,loc,)); setattr(self,name,True); else: if value == None: raise SSBCCException('%s missing value at %s' % (name,loc,)); if not re.match(reformat,value): raise SSBCCException('I/O symbol at %s does not match required format "%s": "%s"' % (loc,reformat,value,)); if optFn != None: try: value = optFn(value); except SSBCCException,msg: raise SSBCCException('Parameter "%s=%s" at %s: %s' % (name,value,loc,str(msg),)); except: raise SSBCCException('Value for "%s" not parsable at %s: "%s"' % (name,loc,value,));
def LocalIntMethod(self,config,value,position=None): try: if config.IsParameter(value): return value; else: v = self.IntMethod(config,value,lowLimit=1); return str(v); except SSBCCException, msg: if not position: raise SSBCCException(msg); else: raise SSBCCException('%s in %s' % (msg,position,));
def IntPow2Method(self,config,value,lowLimit=1,highLimit=None): """ Return the integer value of the argument if it is a power of 2 between the optional limits (inclusive). Otherwise throw an error.\n Note: Other than a lower limit of 1 for "lowLimit", IntMethod validates "lowLimit" and "highLimit". """ value = self.IntMethod(config,value,lowLimit,highLimit) if lowLimit < 1: raise SSBCCException('Program bug: lowLimit = %d is less than 1' % lowLimit); if not IsPowerOf2(value): raise SSBCCException('Must be a power of 2'); return value;
def __init__(self,peripheralFile,config,param_list,loc): # Use the externally provided file name for the peripheral self.peripheralFile = peripheralFile # Get the parameters. allowables = ( ('outclk', r'i_\w+$', None, ), ('data', r'o_\w+$', None, ), ('data_rd', r'i_\w+$', None, ), ('data_empty', r'o_\w+$', None, ), ('outport', r'O_\w+$', None, ), ('infull', r'I_\w+$', None, ), ('depth', r'[1-9]\d*$', lambda v : self.IntPow2Method(config,v,lowLimit=16), ), ('outempty', r'I_\w+$', None, ), ) names = [a[0] for a in allowables] for param_tuple in param_list: param = param_tuple[0] if param not in names: raise SSBCCException('Unrecognized parameter "%s" at %s' % (param,loc,)) param_test = allowables[names.index(param)] self.AddAttr(config,param,param_tuple[1],param_test[1],loc,param_test[2]) # Ensure the required parameters are provided. for paramname in names: if paramname in ('outempty',): continue if not hasattr(self,paramname): raise SSBCCException('Required parameter "%s" is missing at %s' % (paramname,loc,)) # Add the I/O port, internal signals, and the INPORT and OUTPORT symbols for this peripheral. config.AddIO(self.outclk,1,'input',loc) config.AddIO(self.data,8,'output',loc) config.AddIO(self.data_rd,1,'input',loc) config.AddIO(self.data_empty,1,'output',loc) config.AddSignal('s__%s__full' % self.data,1,loc) self.ix_outport = config.NOutports() config.AddOutport((self.outport,False, # empty list ),loc) config.AddInport((self.infull, ('s__%s__full' % self.data,1,'data',), ),loc) if hasattr(self,'outempty'): self.outempty_name = 's__%s__outempty_in' % self.data config.AddSignalWithInit(self.outempty_name,1,'1\'b1',loc) self.ix_outempty = config.NInports() config.AddInport((self.outempty, (self.outempty_name,1,'data',), ),loc)
def __init__(self, peripheralFile, config, param_list, loc): # Use the externally provided file name for the peripheral self.peripheralFile = peripheralFile # Get the parameters. allowables = (( 'history', r'[1-9]\d*$', int, ), ) names = [a[0] for a in allowables] for param_tuple in param_list: param = param_tuple[0] if param not in names: raise SSBCCException('Unrecognized parameter "%s" at %s' % ( param, loc, )) param_test = allowables[names.index(param)] self.AddAttr(config, param, param_tuple[1], param_test[1], loc, param_test[2]) # Set optional parameters. if not hasattr(self, 'history'): self.history = 50 # Configure the system for this peripheral. config.functions['display_trace'] = True
def __init__(self,config,loc): """ Perform tasks common to all interrupt peripherals: Ensure only one interrupt peripheral is defined. Declare the O_INTERRUPT_DIS and O_INTERRUPT_ENA output ports. These are set/reset outports and only require 2 instructions. These 2-instruction sequences are automatically generated by the ".ena" and ".dis" macros. ...\n Note: The "param_list" normally part of a peripheral __init__ method is missing. First, it isn't required here. Second, that helps ensure that this class is not instantiated by itself as a peripheral. """ # Ensure only one interrupt peripheral gets defined. if SSBCCinterruptPeripheral.instance: raise SSBCCException('Interrupt peripheral already defined before line %d' % loc); SSBCCinterruptPeripheral.instance = self; # Add the signals required by the interrupt handler. config.AddSignal('s_interrupt',1,loc); config.AddSignal('s_interrupted',1,loc); # Add the outports to disable and enable interrupts. self.ix_outport_interrupt_dis = config.NOutports(); config.AddOutport(('O_INTERRUPT_DIS',True,),loc); self.ix_outport_interrupt_ena = config.NOutports(); config.AddOutport(('O_INTERRUPT_ENA',True,),loc);
def GenHDL(self,fp,config): """ Generate the peripheral HDL. fp file pointer for the output processor config ssbccConfig object for the procedssor core """ if config.Get('hdl') == 'Verilog': self.GenVerilog(fp,config); elif config.Get('hdl') == 'VHDL': self.GenVHDL(fp,config); else: raise SSBCCException('HDL "%s" not implemented' % config.Get('hdl'));
def IntMethod(self,config,value,lowLimit=None,highLimit=None): """ Return the integer value of the argument. Throw an error if the argument is unrecognized, not an integer, or is outside the optionally specified range. """ if (lowLimit != None) and (highLimit != None) and (highLimit < lowLimit): raise SSBCCException('Program bug: lowLimit = %d and highLimit = %d conflict' % (lowLimit,highLimit,)); if re.match(r'L_\w+$',value): if not config.IsParameter(value): raise SSBCCException('Unrecognized parameter'); ix = [param[0] for param in config.parameters].index(value); value = config.parameters[ix][1]; elif re.match(r'C_\w+$',value): if not config.IsConstant(value): raise SSBCCException('Unrecognized constant'); value = config.constants[value]; value = ParseIntExpr(value); if (lowLimit != None) and value < lowLimit: if lowLimit == 1: raise SSBCCException('Must be a positive integer'); else: raise SSBCCException('Cannot be less than %d' % lowLimit); if (highLimit != None) and value > highLimit: raise SSBCCException('Cannot be more than %d' % highLimit); return value;
class SSBCCperipheral: """Base class for peripherals""" def __init__(self,peripheralFile,config,param_list,loc): """ Prototype constructor. peripheralFile the full path name of the peripheral source Note: "__file__" doesn't work because 'execfile" and "exec" are used to load the python script for the peripheral. config the ssbccConfig object for the processor core param_list parameter list for the processor loc file name and line number for error messages """ pass; def AddAttr(self,config,name,value,reformat,loc,optFn=None): """ Add attribute to the peripheral: config ssbccConfig object for the procedssor core name attribute name value possibly optional value for the attribute reformat regular expression format for the attribute value Note: reformat=None means the attribute can only be set to True loc file name and line number for error messages optFn optional function to set stored type Note: See IntPow, RateMethod, etc. below for example methods. """ if hasattr(self,name): raise SSBCCException('%s repeated at %s' % (name,loc,)); if reformat == None: if value != None: raise SSBCCException('No parameter allowed for %s at %s' % (name,loc,)); setattr(self,name,True); else: if value == None: raise SSBCCException('%s missing value at %s' % (name,loc,)); if not re.match(reformat,value): raise SSBCCException('I/O symbol at %s does not match required format "%s": "%s"' % (loc,reformat,value,)); if optFn != None: try: value = optFn(value); except SSBCCException,msg: raise SSBCCException('Parameter "%s=%s" at %s: %s' % (name,value,loc,str(msg),)); except: raise SSBCCException('Value for "%s" not parsable at %s: "%s"' % (name,loc,value,));
def __init__(self, peripheralFile, config, param_list, loc): """ Configure this peripheral as an interrupt peripheral. """ # Invoke the base class __init__ function before doing anything else. SSBCCinterruptPeripheral.__init__(self, config, loc) # Use the externally provided file name for the peripheral self.peripheralFile = peripheralFile # Get the parameters. allowables = ( ( 'initmask', r'\S+$', lambda v: self.IntValueMethod(v), ), ( 'inmaskport', r'I_\w+$', None, ), ( 'inport', r'I_\w+$', None, ), ( 'outmaskport', r'O_\w+$', None, ), ) names = [a[0] for a in allowables] self.insignal = [None for ix in range(config.Get('data_width'))] self.invert = 0 for param_tuple in param_list: param = param_tuple[0] if re.match(r'insignal[0-7]$', param): if param_tuple[1] == None: raise SSBCCException('"%s" missing value at %s' % ( param, loc, )) ix = int(param[-1]) if self.insignal[ix]: raise SSBCCException('%s already specified at %s' % ( param, loc, )) pars = re.findall(r'(!?)(i_\w+|s__\w+)(,C_\w+)?$', param_tuple[1]) if not pars or not pars[0][1]: raise SSBCCException( 'I/O symbol at %s does not match required format "[!]{i_name|s__name}[,C_name]": "%s"' % ( loc, param_tuple[1], )) pars = pars[0] if pars[0]: self.invert |= 2**ix self.insignal[ix] = pars[1] if pars[2]: config.AddConstant(pars[2][1:], 2**ix, loc) elif param in names: param_test = allowables[names.index(param)] self.AddAttr(config, param, param_tuple[1], param_test[1], loc, param_test[2]) else: raise SSBCCException('Unrecognized parameter "%s" at %s' % ( param, loc, )) # Ensure the required parameters are set. if not any(self.insignal): raise SSBCCException( 'Required parameter insignal<N> missing at %s' % loc) self.width = sum(1 for ix in range(len(self.insignal)) if self.insignal[ix]) ixMissing = [ix for ix in range(self.width) if not self.insignal[ix]] if ixMissing: raise SSBCCException('insignal%d missing at %s' % ( ixMissing[0], loc, )) if self.width == 1: if hasattr(self, 'inport'): raise SSBCCException( 'Parameter "inport" is prohibited when there is only one interrupt signal at %s' % loc) else: if not hasattr(self, 'inport'): raise SSBCCException( 'Required parameter "%s" is missing at %s' % ( paramname, loc, )) # Ensure optional parameters are consistent. for opt in ( 'inmaskport', 'initmask', ): if hasattr(self, opt) and not hasattr(self, 'outmaskport'): raise SSBCCException( 'Optional parameter "%s" requires "outmaskport" at %s' % ( opt, loc, )) if hasattr(self, 'initmask'): if self.initmask >= 2**self.width: raise SSBCCException( 'Value of "initmask" exceeds interrupt width at %s' % loc) # Create the signal for the triggering interrupt source. config.AddSignal('s_interrupt_trigger', self.width, loc) # Add the I/O port, internal signals, and the INPORT and OUTPORT symbols for this peripheral. for ix in [ ix for ix in range(self.width) if re.match(r'i_', self.insignal[ix]) ]: config.AddIO(self.insignal[ix], 1, 'input', loc) if hasattr(self, 'inport'): self.ix_inport = config.NInports() config.AddInport(( self.inport, ( 's_interrupt_trigger', self.width, 'data', ), ), loc) if not hasattr(self, 'initmask'): self.initmask = '%d\'h%X' % ( self.width, 2**self.width - 1, ) if hasattr(self, 'outmaskport'): self.masksignal = 's_interrupt_mask' config.AddSignalWithInit(self.masksignal, self.width, None, loc) config.AddOutport(( self.outmaskport, False, ( self.masksignal, self.width, 'data', self.initmask, ), ), loc) if hasattr(self, 'inmaskport'): config.AddInport(( self.inmaskport, ( self.masksignal, self.width, 'data', ), ), loc) else: self.masksignal = self.initmask
def __init__(self, peripheralFile, config, param_list, loc): # Use the externally provided file name for the peripheral self.peripheralFile = peripheralFile # Get the parameters. allowables = ( ( 'RTR', r'o_\w+$', None, ), ( 'RTRn', r'o_\w+$', None, ), ( 'baudmethod', r'\S+$', lambda v: self.RateMethod(config, v), ), ( 'deglitch', r'[1-9]\d*$', int, ), ( 'inFIFO', r'[1-9]\d*$', lambda v: self.IntPow2Method(config, v), ), ( 'inempty', r'I_\w+$', None, ), ( 'inport', r'I_\w+$', None, ), ( 'insignal', r'i_\w+$', None, ), ( 'noDeglitch', None, None, ), ( 'noInFIFO', None, None, ), ( 'noSync', None, None, ), ( 'nStop', r'[12]$', int, ), ( 'rtr_buffer', r'[1-9]\d*$', lambda v: self.IntPow2Method(config, v), ), ( 'sync', r'[1-9]\d*$', int, ), ) names = [a[0] for a in allowables] for param_tuple in param_list: param = param_tuple[0] if param not in names: raise SSBCCException('Unrecognized parameter "%s" at %s' % ( param, loc, )) param_test = allowables[names.index(param)] self.AddAttr(config, param, param_tuple[1], param_test[1], loc, param_test[2]) # Ensure the required parameters are provided. for paramname in ( 'baudmethod', 'inempty', 'inport', ): if not hasattr(self, paramname): raise SSBCCException( 'Required parameter "%s" is missing at %s' % ( paramname, loc, )) # Set optional parameters. for optionalpair in ( ( 'insignal', 'i_UART_Rx', ), ( 'nStop', 1, ), ): if not hasattr(self, optionalpair[0]): setattr(self, optionalpair[0], optionalpair[1]) # Ensure the rtr_buffer, if specified, is consistent with the inFIFO # specification. if hasattr(self, 'rtr_buffer'): if not hasattr(self, 'inFIFO'): raise SSBCCException( 'rtr_buffer specification requires simultaneous inFIFO specification at %s' % loc) if not self.rtr_buffer < self.inFIFO: raise SSBCCException( 'rtr_buffer=%d specification must be less than the inFIFO=%d specification at %s' % ( self.rtr_buffer, self.inFIFO, loc, )) else: self.rtr_buffer = 1 # Ensure exclusive pair configurations are set and consistent. for exclusivepair in ( ( 'RTR', 'RTRn', None, None, ), ( 'noSync', 'sync', 'sync', 3, ), ( 'noDeglitch', 'deglitch', 'noDeglitch', True, ), ( 'noInFIFO', 'inFIFO', 'noInFIFO', True, ), ): 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]) # Convert configurations to alternate format. for equivalent in ( ( 'noDeglitch', 'deglitch', 0, ), ( 'noInFIFO', 'inFIFO', 0, ), ( 'noSync', 'sync', 0, ), ): if hasattr(self, equivalent[0]): delattr(self, equivalent[0]) setattr(self, equivalent[1], equivalent[2]) # Set the value used to identify signals associated with this peripheral. self.namestring = self.insignal # Add the I/O port, internal signals, and the INPORT and OUTPORT symbols for this peripheral. for ioEntry in ( ( 'insignal', 1, 'input', ), ( 'RTR', 1, 'output', ), ( 'RTRn', 1, 'output', ), ): if hasattr(self, ioEntry[0]): config.AddIO(getattr(self, ioEntry[0]), ioEntry[1], ioEntry[2], loc) config.AddSignal('s__%s__Rx' % self.namestring, 8, loc) config.AddSignal('s__%s__Rx_empty' % self.namestring, 1, loc) config.AddSignal('s__%s__Rx_rd' % self.namestring, 1, loc) config.AddInport(( self.inport, ( 's__%s__Rx' % self.namestring, 8, 'data', ), ( 's__%s__Rx_rd' % self.namestring, 1, 'strobe', ), ), loc) config.AddInport(( self.inempty, ( 's__%s__Rx_empty' % self.namestring, 1, 'data', ), ), loc) # Add the 'clog2' function to the processor (if required). config.functions['clog2'] = True
def __init__(self, peripheralFile, config, param_list, loc): # Use the externally provided file name for the peripheral self.peripheralFile = peripheralFile # Get the parameters. allowables = ( ( 'inport', r'I_\w+$', None, ), ( 'iosignal', r'io_\w+$', None, ), ( 'outport', r'O_\w+$', None, ), ( 'width', r'\S+$', lambda v: self.IntMethod( config, v, lowLimit=1, highLimit=config.Get('data_width')), ), ) names = [a[0] for a in allowables] for param_tuple in param_list: param = param_tuple[0] if param not in names: raise SSBCCException('Unrecognized parameter "%s" at %s' % ( param, loc, )) param_test = allowables[names.index(param)] self.AddAttr(config, param, param_tuple[1], param_test[1], loc, param_test[2]) # Ensure the required parameters are set. for paramname in ( 'inport', 'iosignal', 'outport', ): if not hasattr(self, paramname): raise SSBCCException( 'Required parameter "%s" is missing at %s' % ( paramname, loc, )) # Set defaults for non-specified values. if not hasattr(self, 'width'): self.width = 1 # Create the internal signal name and initialization. self.sname = 's__%s' % self.iosignal sname_init = '%d\'b%s' % ( self.width, '1' * self.width, ) # Add the I/O port, internal signals, and the INPORT and OUTPORT symbols for this peripheral. config.AddIO(self.iosignal, self.width, 'inout', loc) config.AddSignalWithInit(self.sname, self.width, None, loc) config.AddInport(( self.inport, ( self.iosignal, self.width, 'data', ), ), loc) config.AddOutport(( self.outport, False, ( self.sname, self.width, 'data', sname_init, ), ), loc)
if config.IsParameter(value): return value; else: v = self.IntMethod(config,value,lowLimit=1); return str(v); except SSBCCException, msg: if not position: raise SSBCCException(msg); else: raise SSBCCException('%s in %s' % (msg,position,)); if value.find('/') < 0: return LocalIntMethod(self,config,value); else: ratearg = re.findall('([^/]+)',value); if len(ratearg) != 2: raise SSBCCException('Only one "/" allowed in expression'); ratearg[0] = LocalIntMethod(self,config,ratearg[0],'numerator'); ratearg[1] = LocalIntMethod(self,config,ratearg[1],'denominator'); return '(%s+%s/2)/%s' % (ratearg[0],ratearg[1],ratearg[1],); def TimeMethod(self,config,value,lowLimit=None,highLimit=None): """ Convert the provided time from the specified units to seconds. """ if not re.match(r'(0|[1-9]\d*)(\.\d*)?(e[+-]?\d+)?[mun]?s$',value): raise SSBCCException('Malformed time value'); if value[-2:] == 'ms': v = float(value[:-2]) * 1.e-3; elif value[-2:] == 'us': v = float(value[:-2]) * 1.e-6; elif value[-2:] == 'ns':
def __init__(self, peripheralFile, config, param_list, loc): # Use the externally provided file name for the peripheral self.peripheralFile = peripheralFile # Get the parameters. allowables = ( ( 'basePortName', r'\w+$', None, ), ( 'data_width', r'\w+$', lambda v: self.IntMethod(config, v, lowLimit=8, multipleof=8), ), ( 'hasTLast', None, None, ), ( 'indata', r'I_\w+$', None, ), ( 'instatus', r'I_\w+$', None, ), ( 'noTLast', None, None, ), ( 'outlatch', r'O_\w+$', None, ), ) names = [a[0] for a in allowables] for param_tuple in param_list: param = param_tuple[0] if param not in names: raise SSBCCException('Unrecognized parameter "%s" at %s' % ( param, loc, )) param_test = allowables[names.index(param)] self.AddAttr(config, param, param_tuple[1], param_test[1], loc, param_test[2]) # Ensure the required parameters are provided. for paramname in ( 'basePortName', 'data_width', 'indata', 'instatus', 'outlatch', ): if not hasattr(self, paramname): raise SSBCCException( 'Required parameter "%s" is missing at %s' % ( paramname, loc, )) # Ensure exclusive pair configurations are set and consistent. for exclusivepair in (( 'noTLast', 'hasTLast', 'noTLast', None, ), ): 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]): if exclusivepair[2]: setattr(self, exclusivepair[2], exclusivepair[3]) else: raise SSBCCException( 'One of "%s" or "%s" must be set at %s' % ( exclusivepair[0], exclusivepair[1], loc, )) # Add the I/O port, internal signals, and the INPORT and OUTPORT symbols for this peripheral. for signal in ( ( '%s_tvalid', 1, 'input', ), ( '%s_tready', 1, 'output', ), ( '%s_tlast', 1, 'input', ) if hasattr(self, 'hasTLast') else None, ( '%s_tdata', self.data_width, 'input', ), ): if not signal: continue thisName = signal[0] % self.basePortName config.AddIO(thisName, signal[1], signal[2], loc) config.AddSignal('s__%s__data' % self.basePortName, self.data_width, loc) config.AddInport(( self.instatus, ( '%s_tlast' % self.basePortName, 1, 'data', ) if hasattr(self, 'hasTLast') else None, ( '%s_tvalid' % self.basePortName, 1, 'data', ), ), loc) self.ix_latch = config.NOutports() config.AddOutport(( self.outlatch, True, ), loc) self.ix_indata = config.NInports() config.AddInport(( self.indata, ( 's__%s__data' % self.basePortName, self.data_width, 'data', ), ), loc)
def __init__(self, peripheralFile, config, param_list, loc): # Use the externally provided file name for the peripheral self.peripheralFile = peripheralFile # Get the parameters. allowables = ( ( 'FIFO', r'\S+$', lambda v: self.IntPow2Method(config, v, lowLimit=16), ), ( 'accelres', r'\S+$', lambda v: self.IntMethod(config, v, lowLimit=1), ), ( 'accelscale', r'\S+$', lambda v: self.IntMethod(config, v, lowLimit=1), ), ( 'accumres', r'\S+$', lambda v: self.IntMethod(config, v, lowLimit=1), ), ( 'basename', r'[A-Za-z]\w*$', None, ), ( 'countwidth', r'\S+$', lambda v: self.IntMethod(config, v, lowLimit=1), ), ( 'indone', r'I_\w+$', None, ), ( 'inerror', r'I_\w+$', None, ), ( 'master', r'[A-Za-z]\w*$', None, ), ( 'modewidth', r'\S+$', lambda v: self.IntMethod(config, v, lowLimit=1), ), ( 'nodir', None, None, ), ( 'outcontrol', r'O_\w+$', None, ), ( 'outrecord', r'O_\w+$', None, ), ( 'outrun', r'O_\w+$', None, ), ( 'ratemethod', r'\S+$', lambda v: self.RateMethod(config, v), ), ( 'rateres', r'\S+$', lambda v: self.IntMethod(config, v, lowLimit=1), ), ( 'ratescale', r'\S+$', lambda v: self.IntMethod(config, v, lowLimit=1), ), ) names = [a[0] for a in allowables] for param_tuple in param_list: param = param_tuple[0] if param not in names: raise SSBCCException('Unrecognized parameter "%s" at %s' % ( param, loc, )) param_test = allowables[names.index(param)] self.AddAttr(config, param, param_tuple[1], param_test[1], loc, param_test[2]) # Signals that can't be specified when a master is specified. masterExclude = ( 'accelres', 'accelscale', 'accumres', 'countwidth', 'modewidth', 'outcontrol', 'ratemethod', 'rateres', 'ratescale', ) # Ensure the required parameters are provided. reqdParms = ( 'basename', 'indone', 'outrecord', 'outrun', ) if not hasattr(self, 'master'): reqdParms += tuple([ me for me in masterExclude if me not in ( 'accumres', 'modewidth', ) ]) for paramname in reqdParms: if not hasattr(self, paramname): raise SSBCCException( 'Required parameter "%s" is missing at %s' % ( paramname, loc, )) # Ensure mutually exclusive parameters are not listed. if hasattr(self, 'master'): for paramname in masterExclude: if hasattr(self, paramname): raise SSBCCException( 'Parameter "%s" cannot be specified alongside "master" at %s' % ( paramname, loc, )) # Ensure basename is unique for this class of peripheral for p in config.peripheral: if (str(p.__class__) == str( self.__class__)) and (p.basename == self.basename): raise SSBCCException( 'Duplicated stepper_motor basename "%s" at %s' % ( self.basename, loc, )) # For slaves, copy the bit widths from the master peripheral. if hasattr(self, 'master'): for p in config.peripheral: if (str(p.__class__) == str( self.__class__)) and (p.basename == self.master): break else: raise SSBCCException( 'Can\'t find preceding stepper_motor peripheral with basename=%s at %s ' % ( self.master, loc, )) self.master = p for paramname in masterExclude: setattr(self, paramname, getattr(self.master, paramname)) # Set unspecified optional parameters. if not hasattr(self, 'accumres'): self.accumres = self.accelres if not hasattr(self, 'modewidth'): self.modewidth = 0 if not hasattr(self, 'FIFO'): self.FIFO = 16 # Ensure the parameters satisfy any mutual constraints. if not (self.rateres < self.accelres): raise SSBCCException( 'rateres should be smaller than accelres at %s' % loc) if not (self.rateres <= self.accumres <= self.accelres): raise SSBCCException( 'accumres must be between rateres and accelres at %s' % loc) # Add the I/O port, internal signals, and the INPORT and OUTPORT symbols for this peripheral. if not hasattr(self, 'nodir'): config.AddIO('o_%s_dir' % self.basename, 1, 'output', loc) config.AddIO('o_%s_step' % self.basename, 1, 'output', loc) if self.modewidth > 0: config.AddIO('o_%s_mode' % self.basename, 1, 'output', loc) if hasattr(self, 'inerror'): config.AddIO('i_%s_error' % self.basename, 1, 'input', loc) config.AddSignal('s__%s__done' % self.basename, 1, loc) self.ix_outcontrol = config.NOutports() if not hasattr(self, 'master'): config.AddOutport( ( self.outcontrol, False, # empty list ), loc) self.ix_outrecord = config.NOutports() config.AddOutport( ( self.outrecord, True, # empty list ), loc) self.ix_outrun = config.NOutports() config.AddOutport( ( self.outrun, True, # empty list ), loc) if hasattr(self, 'inerror'): config.AddInport(( self.inerror, ( 'i_%s_error' % self.basename, 1, 'data', ), ), loc) config.AddInport(( self.indone, ( 's__%s__done' % self.basename, 1, 'data', ), ), loc) # Compute bit widths. dw = config.Get('data_width') self.data_width = dw self.ratecmdwidth = 1 + self.rateres - self.ratescale self.ratewidth = 1 + self.accelres - self.ratescale self.accelwidth = 1 + self.accelres - self.accelscale self.accumwidth = self.accumres + 1 self.controlwidth = self.ratecmdwidth self.controlwidth += dw * int((self.accelwidth + dw - 1) / dw) self.controlwidth += dw * int((self.countwidth + dw - 1) / dw) self.controlwidth += dw * int((self.modewidth + dw - 1) / dw) self.controlwidthpacked = self.ratecmdwidth + self.accelwidth + self.countwidth + self.modewidth # Add the 'clog2' function to the processor (if required). config.functions['clog2'] = True
def __init__(self, peripheralFile, config, param_list, loc): # Use the externally provided file name for the peripheral self.peripheralFile = peripheralFile # Get the parameters. allowables = ( ( 'default_width', r'\S+', lambda v: self.TimeMethod(config, v), ), ( 'freq_hz', r'\S+$', lambda v: self.IntMethod(config, v), ), ( 'inperiod', r'I_\w+$', None, ), ( 'max_width', r'\S+$', lambda v: self.TimeMethod(config, v), ), ( 'min_width', r'\S+$', lambda v: self.TimeMethod(config, v), ), ( 'outport', r'O_\w+$', None, ), ( 'outsignal', r'o_\w+$', None, ), ( 'outsignaln', r'o_\w+$', None, ), ( 'period', r'\S+$', lambda v: self.TimeMethod(config, v), ), ( 'scale', r'C_\w+$', None, ), ( 'scale_max', r'C_\w+$', None, ), ( 'sync', r'o_\w+$', None, ), ) names = [a[0] for a in allowables] for param_tuple in param_list: param = param_tuple[0] if param not in names: raise SSBCCException('Unrecognized parameter "%s" at %s' % ( param, loc, )) param_test = allowables[names.index(param)] self.AddAttr(config, param, param_tuple[1], param_test[1], loc, param_test[2]) # Ensure the required parameters are provided. for paramname in ( 'outport', 'freq_hz', 'min_width', 'max_width', ): if not hasattr(self, paramname): raise SSBCCException( 'Required parameter "%s" is missing at %s' % ( paramname, loc, )) # Ensure exactly one of mandatory exclusive pairs are specified. for exclusivepair in ( ( 'outsignal', 'outsignaln', ), ( 'period', 'sync', ), ): if not hasattr(self, exclusivepair[0]) and not hasattr( self, exclusivepair[1]): raise SSBCCException('One of %s or %s must be specified at %s', ( exclusivepair[0], exclusivepair[1], loc, )) if hasattr(self, exclusivepair[0]) and hasattr( self, exclusivepair[1]): raise SSBCCException( 'Only one of %s or %s may be specified at %s', ( exclusivepair[0], exclusivepair[1], loc, )) # Set optional signals if not hasattr(self, 'default_width'): self.default_width = self.min_width # Ensure signal values are reasonable. if self.min_width >= self.max_width: raise SSBCCException( 'min_width must be smaller than max_width at %s' % loc) if not self.min_width <= self.default_width <= self.max_width: raise SSBCCException( 'default_width is not between min_width and max_width at %s' % loc) # Ensure the optionally provided "sync" servo_motor peripheral has been specified. if hasattr(self, 'sync'): for p in config.peripheral: if (str(p.__class__) == str( self.__class__)) and (p.outsignal == self.sync): break else: raise SSBCCException( 'Can\'t find preceding servo_motor peripheral with outsignal=%s at %s ' % ( self.sync, loc, )) if not hasattr(p, 'period'): raise SSBCCException( 'servo_motor peripherial with outsignal=%s must have period specified to be used at %s' % ( self.sync, loc, )) # Translate the outsignal specification into a single member for the signal # name and a specification as to whether or not the signal is inverted. if hasattr(self, 'outsignaln'): self.outsignal = self.outsignaln self.invertOutsignal = True else: self.invertOutsignal = False # Set the string used to identify signals associated with this peripheral. self.namestring = self.outsignal # Calculate the name of the signal to start the PWM. self.periodSignal = 's__%s__period_done' % (self.namestring if hasattr( self, 'period') else self.sync) # Calculate the scaling and set the optionally specified constants. # TODO -- ensure the realizable min_width is positive self.scaleValue = int( math.ceil((self.max_width - self.min_width) * self.freq_hz / 2**config.Get('data_width'))) self.scale_maxValue = int( math.ceil((self.max_width - self.min_width) * self.freq_hz / self.scaleValue)) for scalingPair in ( ( 'scaling', 'scaleValue', ), ( 'scale_max', 'scale_maxValue', ), ): if hasattr(self, scalingPair[0]): config.AddConstant(scalingPair[1], getAttr(self, scalingPair[1])) # Add the I/O port, internal signals, and the INPORT and OUTPORT symbols for this peripheral. config.AddIO(self.outsignal, 1, 'output', loc) if hasattr(self, 'period'): config.AddSignal(self.periodSignal, 1, loc) self.ix_outport = config.NOutports() config.AddOutport( ( self.outport, False, # empty list ), loc) if hasattr(self, 'inperiod'): config.AddSignal('s_SETRESET_%s' % self.periodSignal, 1, loc) config.AddInport(( self.inperiod, ( self.periodSignal, 1, 'set-reset', ), ), loc)
def __init__(self, peripheralFile, config, param_list, loc): # Use the externally provided file name for the peripheral self.peripheralFile = peripheralFile # Get the parameters. allowables = ( ( 'outlatch', r'O_\w+$', None, ), ( 'inport', r'I_\w+$', None, ), ( 'insignal', r'i_\w+$', None, ), ( 'width', r'(9|[1-9]\d*)$', int, ), ) names = [a[0] for a in allowables] for param_tuple in param_list: param = param_tuple[0] if param not in names: raise SSBCCException('Unrecognized parameter "%s" at %s' % ( param, loc, )) param_test = allowables[names.index(param)] self.AddAttr(config, param, param_tuple[1], param_test[1], loc, param_test[2]) # Ensure the optional width is set. if not hasattr(self, 'width'): self.width = 8 # Ensure the required parameters are provided. required = [ 'inport', 'insignal', ] if self.width > 8: required.append('outlatch') for paramname in required: if not hasattr(self, paramname): raise SSBCCException( 'Required parameter "%s" is missing at %s' % ( paramname, loc, )) # There are no optional parameters. # Add the I/O port, internal signals, and the INPORT and OUTPORT symbols for this peripheral. config.AddIO(self.insignal, 1, 'input', loc) config.AddSignal('s__%s__counter' % self.insignal, self.width, loc) self.ix_inport = config.NInports() config.AddInport(( self.inport, ( 's__%s__counter' % self.insignal, self.width, 'data', ), ), loc) self.ix_latch = config.NOutports() if hasattr(self, 'outlatch'): config.AddOutport( ( self.outlatch, True, # empty list ), loc)
def __init__(self, peripheralFile, config, param_list, loc): # Use the externally provided file name for the peripheral self.peripheralFile = peripheralFile # Get the parameters. allowables = ( ( 'basesignal', r'\w+$', None, ), ( 'inport', r'I_\w+$', None, ), ( 'outport', r'O_\w+$', None, ), ) names = [a[0] for a in allowables] for param_tuple in param_list: param = param_tuple[0] if param not in names: raise SSBCCException('Unrecognized parameter "%s" at %s' % ( param, loc, )) param_test = allowables[names.index(param)] self.AddAttr(config, param, param_tuple[1], param_test[1], loc, param_test[2]) # Ensure the required parameters are set. for paramname in names: if not hasattr(self, paramname): raise SSBCCException( 'Required parameter "%s" is missing at %s' % ( paramname, loc, )) # Add the I/O port, internal signals, and the INPORT and OUTPORT symbols for this peripheral. tristate_i = 'i_%s_i' % self.basesignal tristate_o = 'o_%s_o' % self.basesignal tristate_t = 'o_%s_t' % self.basesignal config.AddIO(tristate_i, 1, 'input', loc) config.AddIO(tristate_o, 1, 'output', loc) config.AddIO(tristate_t, 1, 'output', loc) config.AddInport(( self.inport, ( tristate_i, 1, 'data', ), ), loc) config.AddOutport(( self.outport, False, ( tristate_t, 1, 'data', "1'b1", ), ), loc)
def __init__(self, peripheralFile, config, param_list, loc): # Use the externally provided file name for the peripheral self.peripheralFile = peripheralFile # 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: param = param_tuple[0] if param not in names: raise SSBCCException('Unrecognized parameter "%s" at %s' % ( param, loc, )) param_test = allowables[names.index(param)] self.AddAttr(config, param, param_tuple[1], param_test[1], loc, param_test[2]) # Ensure the required parameters are provided. for paramname in ( 'outport', 'outsignal', 'ratemethod', ): if not hasattr(self, paramname): raise SSBCCException( 'Required parameter "%s" is missing at %s' % ( paramname, loc, )) # Set optional parameters. for optionalpair in ( ( 'instances', 1, ), ( 'norunt', False, ), ): if not hasattr(self, optionalpair[0]): setattr(self, optionalpair[0], optionalpair[1]) # Ensure exclusive pair configurations are set and consistent. for exclusivepair in (( 'invert', 'noinvert', 'noinvert', True, ), ): 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. config.AddIO(self.outsignal, self.instances, 'output', loc) self.ix_outport_0 = config.NOutports() if self.instances == 1: tmpOutport = self.outport config.AddOutport(( tmpOutport, False, ), loc) else: for ixOutPort in range(self.instances): tmpOutport = '%s_%d' % ( self.outport, ixOutPort, ) config.AddOutport(( tmpOutport, False, ), loc) # Add the 'clog2' function to the processor (if required). config.functions['clog2'] = True
def __init__(self, peripheralFile, config, param_list, loc): # Use the externally provided file name for the peripheral self.peripheralFile = peripheralFile # Get the parameters. parameters = { 'inport': ( r'I_\w+$', None, ), 'insignal': ( r'i_\w+$', None, ), 'outport_addr': ( r'O_\w+$', None, ), 'outport_latch': ( r'O_\w+$', None, ), 'width': ( r'[1-9]\d*$', lambda v: self.IntMethod(config, v, lowLimit=9), ), } for param_tuple in param_list: param_name, param_value = param_tuple try: name_test, value_test = parameters[param_name] except KeyError: raise SSBCCException('Unrecognized parameter "%s" at %s' % ( param_name, loc, )) self.AddAttr(config, param_name, param_value, name_test, loc, value_test) # Ensure the required parameters are set. for param_name in parameters: if not hasattr(self, param_name): raise SSBCCException( 'Required parameter "%s" not provided at %s', ( param_name, loc, )) # Derived parameters self.latch_width = 8 * ((self.width + 7) / 8) self.addr_width = int(math.ceil(math.log(self.latch_width / 8, 2))) # Configure the processor I/Os, etc. config.AddIO(self.insignal, self.width, 'input', loc) config.AddSignal('s__%s__select' % self.insignal, 8, loc) config.AddInport(( self.inport, ( 's__%s__select' % self.insignal, 8, 'data', ), ), loc) self.ix__o_latch = config.NOutports() config.AddOutport(( self.outport_latch, True, ), loc) self.ix__o_addr = config.NOutports() config.AddOutport(( self.outport_addr, False, ), loc)
def __init__(self, peripheralFile, config, param_list, loc): # Use the externally provided file name for the peripheral self.peripheralFile = peripheralFile # Get the parameters. allowables = ( ( 'CTS', r'i_\w+$', None, ), ( 'CTSn', r'i_\w+$', None, ), ( 'baudmethod', r'\S+$', lambda v: self.RateMethod(config, v), ), ( 'noOutFIFO', None, None, ), ( 'nStop', r'[12]$', int, ), ( 'outFIFO', r'[1-9]\d*$', lambda v: self.IntPow2Method(config, v), ), ( 'outport', r'O_\w+$', None, ), ( 'outsignal', r'o_\w+$', None, ), ( 'outstatus', r'I_\w+$', None, ), ) names = [a[0] for a in allowables] for param_tuple in param_list: param = param_tuple[0] if param not in names: raise SSBCCException('Unrecognized parameter "%s" at %s' % ( param, loc, )) param_test = allowables[names.index(param)] self.AddAttr(config, param, param_tuple[1], param_test[1], loc, param_test[2]) # Ensure the required parameters are provided. for paramname in ( 'baudmethod', 'outport', 'outstatus', ): if not hasattr(self, paramname): raise SSBCCException( 'Required parameter "%s" is missing at %s' % ( paramname, loc, )) # Set optional parameters. for optionalpair in ( ( 'nStop', 1, ), ( 'outsignal', 'o_UART_Tx', ), ): if not hasattr(self, optionalpair[0]): setattr(self, optionalpair[0], optionalpair[1]) # Ensure exclusive pair configurations are set and consistent. for exclusivepair in ( ( 'CTS', 'CTSn', None, None, ), ( 'noOutFIFO', 'outFIFO', 'noOutFIFO', True, ), ): 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]) # Convert configurations to alternative format. for equivalent in (( 'noOutFIFO', 'outFIFO', 0, ), ): if hasattr(self, equivalent[0]): delattr(self, equivalent[0]) setattr(self, equivalent[1], equivalent[2]) # Set the string used to identify signals associated with this peripheral. self.namestring = self.outsignal # Add the I/O port, internal signals, and the INPORT and OUTPORT symbols for this peripheral. for ioEntry in ( ( 'outsignal', 1, 'output', ), ( 'CTS', 1, 'input', ), ( 'CTSn', 1, 'input', ), ): if hasattr(self, ioEntry[0]): config.AddIO(getattr(self, ioEntry[0]), ioEntry[1], ioEntry[2], loc) config.AddSignalWithInit('s__%s__Tx' % self.namestring, 8, None, loc) config.AddSignal('s__%s__Tx_busy' % self.namestring, 1, loc) config.AddSignalWithInit('s__%s__Tx_wr' % self.namestring, 1, None, loc) config.AddOutport(( self.outport, False, ( 's__%s__Tx' % self.namestring, 8, 'data', ), ( 's__%s__Tx_wr' % self.namestring, 1, 'strobe', ), ), loc) config.AddInport(( self.outstatus, ( 's__%s__Tx_busy' % self.namestring, 1, 'data', ), ), loc) # Add the 'clog2' function to the processor (if required). config.functions['clog2'] = True
def __init__(self, peripheralFile, config, param_list, loc): # Use the externally provided file name for the peripheral self.peripheralFile = peripheralFile # Get the parameters. allowables = ( ( 'address', r'O_\w+$', None, ), ( 'basePortName', r'\w+$', None, ), ( 'ram8', None, None, ), ( 'ram32', None, None, ), ( 'read', r'I_\w+$', None, ), ( 'size', r'\S+$', lambda v: self.IntPow2Method( config, v, lowLimit=16, highLimit=256), ), ( 'write', r'O_\w+$', None, ), ) names = [a[0] for a in allowables] for param_tuple in param_list: param = param_tuple[0] if param not in names: raise SSBCCException('Unrecognized parameter "%s" at %s' % ( param, loc, )) param_test = allowables[names.index(param)] self.AddAttr(config, param, param_tuple[1], param_test[1], loc, param_test[2]) # Ensure the required parameters are provided. for paramname in ( 'address', 'basePortName', 'read', 'write', ): if not hasattr(self, paramname): raise SSBCCException( 'Required parameter "%s" is missing at %s' % ( paramname, loc, )) # Set optional parameters. for optionalpair in (( 'size', 256, ), ): if not hasattr(self, optionalpair[0]): setattr(self, optionalpair[0], optionalpair[1]) # Ensure exclusive pair configurations are set and consistent. for exclusivepair in (( 'ram8', 'ram32', 'ram8', True, ), ): 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]): setattr(self, exclusivepair[2], exclusivepair[3]) # Set the string used to identify signals associated with this peripheral. self.namestring = self.basePortName # Add the I/O port, internal signals, and the INPORT and OUTPORT symbols for this peripheral. self.address_width = int(math.log(self.size, 2)) for signal in ( ( '%s_aresetn', 1, 'input', ), ( '%s_aclk', 1, 'input', ), ( '%s_awvalid', 1, 'input', ), ( '%s_awready', 1, 'output', ), ( '%s_awaddr', self.address_width, 'input', ), ( '%s_wvalid', 1, 'input', ), ( '%s_wready', 1, 'output', ), ( '%s_wdata', 32, 'input', ), ( '%s_wstrb', 4, 'input', ), ( '%s_bresp', 2, 'output', ), ( '%s_bvalid', 1, 'output', ), ( '%s_bready', 1, 'input', ), ( '%s_arvalid', 1, 'input', ), ( '%s_arready', 1, 'output', ), ( '%s_araddr', self.address_width, 'input', ), ( '%s_rvalid', 1, 'output', ), ( '%s_rready', 1, 'input', ), ( '%s_rdata', 32, 'output', ), ( '%s_rresp', 2, 'output', ), ): thisName = signal[0] % self.basePortName config.AddIO(thisName, signal[1], signal[2], loc) config.AddSignal('s__%s__mc_addr' % self.namestring, self.address_width, loc) config.AddSignal('s__%s__mc_rdata' % self.namestring, 8, loc) config.AddOutport(( self.address, False, ( 's__%s__mc_addr' % self.namestring, self.address_width, 'data', ), ), loc) config.AddInport(( self.read, ( 's__%s__mc_rdata' % self.namestring, 8, 'data', ), ), loc) self.ix_write = config.NOutports() config.AddOutport( ( self.write, False, # empty list ), loc) # Add the 'clog2' function to the processor (if required). config.functions['clog2'] = True
def __init__(self, peripheralFile, config, param_list, loc): # Use the externally provided file name for the peripheral self.peripheralFile = peripheralFile # Get the parameters. allowables = ( ( 'address', r'O_\w+$', None, ), ( 'address_width', r'[1-9]\d*$', int, ), ( 'basePortName', r'\w+$', None, ), ( 'command_read', r'O_\w+$', None, ), ( 'command_write', r'O_\w+$', None, ), ( 'data', r'O_\w+$', None, ), ( 'data_width', r'(32|64)$', int, ), ( 'read', r'I_\w+$', None, ), ( 'busy', r'I_\w+$', None, ), ( 'error', r'I_\w+$', None, ), ( 'noWSTRB', None, None, ), ( 'synchronous', r'(True|False)$', bool, ), ( 'write_enable', r'O_\w+$', None, ), ) names = [a[0] for a in allowables] for param_tuple in param_list: param = param_tuple[0] if param not in names: raise SSBCCException('Unrecognized parameter "%s" at %s' % ( param, loc, )) param_test = allowables[names.index(param)] self.AddAttr(config, param, param_tuple[1], param_test[1], loc, param_test[2]) # Ensure the required parameters are provided. for paramname in ( 'address', 'address_width', 'basePortName', 'command_read', 'command_write', 'data', 'read', 'busy', 'error', 'synchronous', ): if not hasattr(self, paramname): raise SSBCCException( 'Required parameter "%s" is missing at %s' % ( paramname, loc, )) # Set optional parameters. for optionalpair in (( 'data_width', 32, ), ): if not hasattr(self, optionalpair[0]): setattr(self, optionalpair[0], optionalpair[1]) # Ensure exclusive pair configurations are set and consistent. for exclusivepair in (( 'write_enable', 'noWSTRB', None, None, ), ): 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]) # Ensure one and only one of the complementary optional values are set. if not hasattr(self, 'write_enable') and not hasattr(self, 'noWSTRB'): raise SSBCCException( 'One of "write_enable" or "noWSTRB" must be set at %s' % loc) # Temporary: Warning message if not self.synchronous: raise SSBCCException( 'synchronous=False has not been validated yet') # Add the I/O port, internal signals, and the INPORT and OUTPORT symbols for this peripheral. for signal in ( ( '%s_aresetn', 1, 'input', ), ( '%s_aclk', 1, 'input', ), ( '%s_awvalid', 1, 'output', ), ( '%s_awready', 1, 'input', ), ( '%s_awaddr', self.address_width, 'output', ), ( '%s_wvalid', 1, 'output', ), ( '%s_wready', 1, 'input', ), ( '%s_wdata', self.data_width, 'output', ), ( '%s_wstrb', self.data_width / 8, 'output', ) if hasattr(self, 'write_enable') else None, ( '%s_bresp', 2, 'input', ), ( '%s_bvalid', 1, 'input', ), ( '%s_bready', 1, 'output', ), ( '%s_arvalid', 1, 'output', ), ( '%s_arready', 1, 'input', ), ( '%s_araddr', self.address_width, 'output', ), ( '%s_rvalid', 1, 'input', ), ( '%s_rready', 1, 'output', ), ( '%s_rdata', self.data_width, 'input', ), ( '%s_rresp', 2, 'input', ), ): if not signal: continue thisName = signal[0] % self.basePortName config.AddIO(thisName, signal[1], signal[2], loc) config.AddSignal('s__%s__address' % self.basePortName, self.address_width, loc) config.AddSignal('s__%s__rd' % self.basePortName, 1, loc) config.AddSignal('s__%s__wr' % self.basePortName, 1, loc) config.AddSignal('s__%s__busy' % self.basePortName, 5, loc) config.AddSignal('s__%s__error' % self.basePortName, 2, loc) config.AddSignal('s__%s__read' % self.basePortName, self.data_width, loc) self.ix_address = config.NOutports() config.AddOutport( ( self.address, False, # empty list -- disable normal output port signal generation ), loc) self.ix_data = config.NOutports() config.AddOutport( ( self.data, False, # empty list -- disable normal output port signal generation ), loc) if hasattr(self, 'write_enable'): config.AddOutport(( self.write_enable, False, ( '%s_wstrb' % self.basePortName, self.data_width / 8, 'data', ), ), loc) config.AddOutport(( self.command_read, True, ( 's__%s__rd' % self.basePortName, 1, 'strobe', ), ), loc) config.AddOutport(( self.command_write, True, ( 's__%s__wr' % self.basePortName, 1, 'strobe', ), ), loc) config.AddInport(( self.busy, ( 's__%s__busy' % self.basePortName, 5, 'data', ), ), loc) config.AddInport(( self.error, ( 's__%s__error' % self.basePortName, 2, 'data', ), ), loc) self.ix_read = config.NInports() config.AddInport(( self.read, ( 's__%s__read' % self.basePortName, self.data_width, 'data', ), ), loc)
def __init__(self, peripheralFile, config, param_list, loc): # Use the externally provided file name for the peripheral self.peripheralFile = peripheralFile # Parse the parameters. for param_tuple in param_list: param = param_tuple[0] param_arg = param_tuple[1] if param == 'outport_latch': self.AddAttr(config, param, param_arg, r'O_\w+$', loc) elif param == 'outport_addr': self.AddAttr(config, param, param_arg, r'O_\w+$', loc) elif param == 'inport': self.AddAttr(config, param, param_arg, r'I_\w+$', loc) elif param == 'insignal': self.AddAttr(config, param, param_arg, r'i_\w+$', loc) elif param == 'width': self.AddAttr(config, param, param_arg, r'[1-9]\d*$', loc, int) else: raise SSBCCException('Unrecognized parameter at %s: %s' % ( loc, param, )) # Ensure the required parameters are set. for param in ( 'outport_latch', 'outport_addr', 'inport', 'insignal', 'width', ): if not hasattr(self, param): raise SSBCCException( 'Required parameter "%s" not provided at %s', ( param, loc, )) # Ensure parameters are reasonable. if self.width <= 8: raise SSBCCException( 'The "latch" peripheral doesn\'t make sense when width <= 8 on %s' % loc) # Derived parameters self.latch_width = 8 * ((self.width + 7) / 8) self.addr_width = int(math.ceil(math.log(self.latch_width / 8, 2))) # Configure the processor I/Os, etc. config.AddIO(self.insignal, self.width, 'input', loc) config.AddSignal('s__%s__select' % self.insignal, 8, loc) config.AddInport(( self.inport, ( 's__%s__select' % self.insignal, 8, 'data', ), ), loc) self.ix__o_latch = config.NOutports() config.AddOutport(( self.outport_latch, True, ), loc) self.ix__o_addr = config.NOutports() config.AddOutport(( self.outport_addr, False, ), loc)