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

Subversion Repositories ssbcc

[/] [ssbcc/] [trunk/] [ssbccPeripheral.py] - Diff between revs 2 and 6

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 2 Rev 6
Line 1... Line 1...
################################################################################
################################################################################
#
#
# Copyright 2012, Sinclair R.F., Inc.
# Copyright 2012-2014, Sinclair R.F., Inc.
#
#
################################################################################
################################################################################
 
 
import re
import re
 
 
 
from ssbccUtil import IsPosInt
 
from ssbccUtil import IsPowerOf2
from ssbccUtil import SSBCCException
from ssbccUtil import SSBCCException
 
 
class SSBCCperipheral:
class SSBCCperipheral:
  """Base class for peripherals"""
  """Base class for peripherals"""
 
 
Line 32... Line 34...
    value       possibly optional value for the attribute
    value       possibly optional value for the attribute
    reformat    regular expression format for the attribute value
    reformat    regular expression format for the attribute value
                Note:  reformat=None means the attribute can only be set to True
                Note:  reformat=None means the attribute can only be set to True
    loc         file name and line number for error messages
    loc         file name and line number for error messages
    optFn       optional function to set stored type
    optFn       optional function to set stored type
 
                Note:  See IntPow, RateMethod, etc. below for example methods.
    """
    """
    if hasattr(self,name):
    if hasattr(self,name):
      raise SSBCCException('%s repeated at %s' % (name,loc,));
      raise SSBCCException('%s repeated at %s' % (name,loc,));
    if reformat == None:
    if reformat == None:
      if value != None:
      if value != None:
Line 45... Line 48...
      if value == None:
      if value == None:
        raise SSBCCException('%s missing value at %s' % (name,loc,));
        raise SSBCCException('%s missing value at %s' % (name,loc,));
      if not re.match(reformat,value):
      if not re.match(reformat,value):
        raise SSBCCException('I/O symbol at %s does not match required format "%s":  "%s"' % (loc,reformat,value,));
        raise SSBCCException('I/O symbol at %s does not match required format "%s":  "%s"' % (loc,reformat,value,));
      if optFn != None:
      if optFn != None:
 
        try:
        value = optFn(value);
        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,));
      setattr(self,name,value);
      setattr(self,name,value);
 
 
  def AddRateMethod(self,config,name,param_arg,loc):
 
    """
 
    Add parameter or fraction for rates such as timer rates or baud rates:
 
    config      ssbccConfig object for the procedssor core
 
    name        attribute name
 
    param       constant, parameter, or fraction of the two to specify the
 
                clock counts between events
 
    loc         file name and line number for error messages
 
    """
 
    if hasattr(self,name):
 
      raise SSBCCException('%s repeated at %s' % (name,loc,));
 
    if param_arg.find('/') < 0:
 
      if self.IsInt(param_arg):
 
        setattr(self,name,str(self.ParseInt(param_arg)));
 
      elif self.IsParameter(config,param_arg):
 
        set(self,name,param_arg);
 
      else:
 
        raise SSBCCException('%s with no "/" must be an integer or a previously declared parameter at %s' % (name,loc,));
 
    else:
 
      ratearg = re.findall('([^/]+)',param_arg);
 
      if len(ratearg) == 2:
 
        if not self.IsInt(ratearg[0]) and not self.IsParameter(config,ratearg[0]):
 
          raise SSBCCException('Numerator in %s must be an integer or a previously declared parameter at %s' % (name,loc,));
 
        if not self.IsInt(ratearg[1]) and not self.IsParameter(config,ratearg[1]):
 
          raise SSBCCException('Denominator in %s must be an integer or a previously declared parameter at %s' % (name,loc,));
 
        for ix in range(2):
 
          if self.IsInt(ratearg[ix]):
 
            ratearg[ix] = str(self.ParseInt(ratearg[ix]));
 
        setattr(self,name,'('+ratearg[0]+'+'+ratearg[1]+'/2)/'+ratearg[1]);
 
    if not hasattr(self,name):
 
      raise SSBCCException('Bad %s value at %s:  "%s"' % (name,loc,param_arg,));
 
 
 
  def GenAssembly(self,config):
  def GenAssembly(self,config):
    """
    """
    Used to generate any assembly modules associated with the peripheral.
    Virtual method to generate assembly modules associated with the peripheral.
    """
    """
    pass;
    pass;
 
 
  def GenHDL(self,fp,config):
  def GenHDL(self,fp,config):
    """
    """
Line 101... Line 77...
    else:
    else:
      raise SSBCCException('HDL "%s" not implemented' % config.Get('hdl'));
      raise SSBCCException('HDL "%s" not implemented' % config.Get('hdl'));
 
 
  def GenVerilog(self,fp,config):
  def GenVerilog(self,fp,config):
    """
    """
    Generate the Verilog version of the peripheral.
    Virtual method to generate the Verilog version of the peripheral.
    Raise an exception if there is no Verilog version of the peripheral.
    Raise an exception if there is no Verilog version of the peripheral.
    """
    """
    raise Exception('Verilog is not implemented for this peripheral');
    raise Exception('Verilog is not implemented for this peripheral');
 
 
  def GenVerilogFinal(self,config,body):
  def GenVerilogFinal(self,config,body):
Line 118... Line 94...
      body = re.sub('\$clog2','clog2',body);
      body = re.sub('\$clog2','clog2',body);
    return body;
    return body;
 
 
  def GenVHDL(self,fp,config):
  def GenVHDL(self,fp,config):
    """
    """
    Generate the VHDL version of the peripheral.
    Virtual method to generate the VHDL version of the peripheral.
    Raise an exception if there is no VHDL version of the peripheral.
    Raise an exception if there is no VHDL version of the peripheral.
    """
    """
    raise Exception('VHDL is not implemented for this peripheral');
    raise Exception('VHDL is not implemented for this peripheral');
 
 
  def IsInt(self,value):
 
    """
 
    Test the string to see if it is a well-formatted integer.
 
    Allow underscores as per Verilog.
 
    """
 
    if re.match(r'[1-9][0-9_]*$',value):
 
      return True;
 
    else:
 
      return False;
 
 
 
  def IsIntExpr(self,value):
  def IsIntExpr(self,value):
    """
    """
    Test the string to see if it is a well-formatted integer or multiplication
    Test the string to see if it is a well-formatted integer or multiplication
    of two integers.
    of two integers.
    Allow underscores as per Verilog.
    Allow underscores as per Verilog.
Line 170... Line 136...
    fp = open(hdlName,'r');
    fp = open(hdlName,'r');
    body = fp.read();
    body = fp.read();
    fp.close();
    fp.close();
    return body;
    return body;
 
 
  def ParseInt(self,value):
 
    """
 
    Convert a well-formatted integer string to an integer.
 
    Allow underscores as per Verilog.
 
    Note:  If this routine is called, then the value should have already been
 
           verified to be a well-formatted integer string.
 
    """
 
    if not self.IsInt(value):
 
      raise Exception('Program Bug -- shouldn\'t call with a badly formatted integer');
 
    return int(re.sub('_','',value));
 
 
 
  def ParseIntExpr(self,value):
  def ParseIntExpr(self,value):
    """
    """
    Convert a string containing well-formatted integer or multiplication of two
    Convert a string containing well-formatted integer or multiplication of two
    integers.
    integers.
    Allow underscores as per Verilog.
    Allow underscores as per Verilog.
Line 193... Line 148...
    """
    """
    if not self.IsIntExpr(value):
    if not self.IsIntExpr(value):
      raise Exception('Program Bug -- shouldn\'t call with a badly formatted integer expression');
      raise Exception('Program Bug -- shouldn\'t call with a badly formatted integer expression');
    return eval(re.sub('_','',value));
    return eval(re.sub('_','',value));
 
 
 No newline at end of file
 No newline at end of file
 
  ##############################################################################
 
  #
 
  # Methods to supplement python intrisics for the optFn argument of AddAttr
 
  #
 
  # Note:  AddAttr embelleshes exception messages with the symbol name and
 
  #        source code line number.
 
  #
 
  # Note:  One weird side effect of using lambda expressions is that the
 
  #        functions won't be recognized unless they're members of the
 
  #        SSBCCperipheral class.
 
  #
 
  ##############################################################################
 
 
 
  def FixedPow2(self,config,lowLimit,highLimit,value):
 
    """
 
    Check the provided constant as a power of 2 between the provided limits.\n
 
    Note:  This differs from InpPow2 in that localparams and constants are
 
           permitted.
 
    """
 
    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];
 
    if not IsPosInt(value):
 
      raise SSBCCException('Must be a constant positive integer');
 
    value = self.ParseIntExpr(value);
 
    if not IsPowerOf2(value):
 
      raise SSBCCException('Must be a power of 2');
 
    if not (lowLimit <= value <= highLimit):
 
      raise SSBCCException('Must be between %d and %d inclusive' % (lowLimit,highLimit,));
 
    return value;
 
 
 
  def IntPow2(self,value,minValue=1):
 
    """
 
    Return the integer value of the argument if it is a power of 2.  Otherwise
 
    throw an error.
 
    """
 
    if not IsPosInt(value):
 
      raise SSBCCException('Not a positive integer');
 
    value = self.ParseIntExpr(value);
 
    if not IsPowerOf2(value):
 
      raise SSBCCException('Not a power of 2');
 
    if value < minValue:
 
      raise SSBCCException('Must be at least %d' % minValue);
 
    return value;
 
 
 
  def PosInt(self,value,maxValue=0):
 
    """
 
    Return the integer value of the argument unless it is out of bounds.\n
 
    Note:  maxValue=0 means that there is no upper limit.
 
    """
 
    if not IsPosInt(value):
 
      raise SSBCCException('Not a positive integer');
 
    value = self.ParseIntExpr(value);
 
    if (maxValue != 0) and (value > maxValue):
 
      raise SSBCCException('Out of bounds -- can be at most %d' % maxValue);
 
    return value;
 
 
 
  def RateMethod(self,config,value):
 
    """
 
    Return the string to evaluate the provided value or ratio of two values.
 
    The value can be an integer (including underscores) or a parameter.  Ratios
 
    are restated to do rounding instead of truncation.\n
 
    Examples:
 
      123456
 
      123_456
 
      L_DIVISION_RATIO
 
      G_CLOCK_FREQUENCY_HZ/19200
 
      G_CLOCK_FREQUENCY_HZ/L_BAUD_RATE
 
      100_000_000/G_BAUD_RATE
 
    """
 
    if value.find('/') < 0:
 
      if self.IsIntExpr(value):
 
        return str(self.ParseIntExpr(value));
 
      elif self.IsParameter(config,value):
 
        return value;
 
      else:
 
        raise SSBCCException('Value must be a positive integer or a previously declared parameter');
 
    else:
 
      ratearg = re.findall('([^/]+)',value);
 
      if len(ratearg) != 2:
 
        raise SSBCCException('Only one "/" allowed in expression');
 
      if not self.IsIntExpr(ratearg[0]) and not self.IsParameter(config,ratearg[0]):
 
        raise SSBCCException('Numerator must be an integer or a previously declared parameter');
 
      if not self.IsIntExpr(ratearg[1]) and not self.IsParameter(config,ratearg[1]):
 
        raise SSBCCException('Denominator must be an integer or a previously declared parameter');
 
      return '(%s+%s/2)/%s' % (ratearg[0],ratearg[1],ratearg[1],);
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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