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

Subversion Repositories ssbcc

[/] [ssbcc/] [trunk/] [ssbccPeripheral.py] - Blame information for rev 9

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

Line No. Rev Author Line
1 2 sinclairrf
################################################################################
2
#
3 6 sinclairrf
# Copyright 2012-2014, Sinclair R.F., Inc.
4 2 sinclairrf
#
5
################################################################################
6
 
7
import re
8
 
9 8 sinclairrf
from ssbccUtil import IsIntExpr
10 6 sinclairrf
from ssbccUtil import IsPosInt
11
from ssbccUtil import IsPowerOf2
12 8 sinclairrf
from ssbccUtil import ParseIntExpr
13 2 sinclairrf
from ssbccUtil import SSBCCException
14
 
15
class SSBCCperipheral:
16
  """Base class for peripherals"""
17
 
18
  def __init__(self,peripheralFile,config,param_list,loc):
19
    """
20
    Prototype constructor.
21
    peripheralFile      the full path name of the peripheral source
22
                        Note:  "__file__" doesn't work because 'execfile" and
23
                        "exec" are used to load the python script for the
24
                        peripheral.
25
    config              the ssbccConfig object for the processor core
26
    param_list          parameter list for the processor
27
    loc                 file name and line number for error messages
28
    """
29
    pass;
30
 
31
  def AddAttr(self,config,name,value,reformat,loc,optFn=None):
32
    """
33
    Add attribute to the peripheral:
34
    config      ssbccConfig object for the procedssor core
35
    name        attribute name
36
    value       possibly optional value for the attribute
37
    reformat    regular expression format for the attribute value
38
                Note:  reformat=None means the attribute can only be set to True
39
    loc         file name and line number for error messages
40
    optFn       optional function to set stored type
41 6 sinclairrf
                Note:  See IntPow, RateMethod, etc. below for example methods.
42 2 sinclairrf
    """
43
    if hasattr(self,name):
44
      raise SSBCCException('%s repeated at %s' % (name,loc,));
45
    if reformat == None:
46
      if value != None:
47
        raise SSBCCException('No parameter allowed for %s at %s' % (name,loc,));
48
      setattr(self,name,True);
49
    else:
50
      if value == None:
51
        raise SSBCCException('%s missing value at %s' % (name,loc,));
52
      if not re.match(reformat,value):
53
        raise SSBCCException('I/O symbol at %s does not match required format "%s":  "%s"' % (loc,reformat,value,));
54
      if optFn != None:
55 6 sinclairrf
        try:
56
          value = optFn(value);
57
        except SSBCCException,msg:
58
          raise SSBCCException('Parameter "%s=%s" at %s:  %s' % (name,value,loc,str(msg),));
59
        except:
60
          raise SSBCCException('Value for "%s" not parsable at %s:  "%s"' % (name,loc,value,));
61 2 sinclairrf
      setattr(self,name,value);
62
 
63
  def GenAssembly(self,config):
64
    """
65 6 sinclairrf
    Virtual method to generate assembly modules associated with the peripheral.
66 2 sinclairrf
    """
67
    pass;
68
 
69
  def GenHDL(self,fp,config):
70
    """
71
    Generate the peripheral HDL.
72
    fp          file pointer for the output processor
73
    config      ssbccConfig object for the procedssor core
74
    """
75
    if config.Get('hdl') == 'Verilog':
76
      self.GenVerilog(fp,config);
77
    elif config.Get('hdl') == 'VHDL':
78
      self.GenVHDL(fp,config);
79
    else:
80
      raise SSBCCException('HDL "%s" not implemented' % config.Get('hdl'));
81
 
82
  def GenVerilog(self,fp,config):
83
    """
84 6 sinclairrf
    Virtual method to generate the Verilog version of the peripheral.
85 2 sinclairrf
    Raise an exception if there is no Verilog version of the peripheral.
86
    """
87
    raise Exception('Verilog is not implemented for this peripheral');
88
 
89
  def GenVerilogFinal(self,config,body):
90
    """
91
    Clean up the peripheral code.
92
    Change "$clog2" to "clog2" for simulators and synthesis tools that don't
93
      recognize or process "$clog2."
94
    """
95
    if config.Get('define_clog2'):
96
      body = re.sub('\$clog2','clog2',body);
97
    return body;
98
 
99
  def GenVHDL(self,fp,config):
100
    """
101 6 sinclairrf
    Virtual method to generate the VHDL version of the peripheral.
102 2 sinclairrf
    Raise an exception if there is no VHDL version of the peripheral.
103
    """
104
    raise Exception('VHDL is not implemented for this peripheral');
105
 
106
  def LoadCore(self,filename,extension):
107
    """
108
    Read the source HDL for the peripheral from the same directory as the python
109
    script.
110
    filename    name for the python peripheral (usually "__file__")
111
    extension   the string such as ".v" or ".vhd" required by the HDL\n
112
    Note:  The '.' must be included in the extension.  For example, the UART
113
           peripheral uses '_Rx.v' and '_Tx.v' or similar to invoke the UART_Tx
114
           and UART_Rx HDL files.
115
    """
116
    hdlName = re.sub(r'\.py$',extension,filename);
117
    fp = open(hdlName,'r');
118
    body = fp.read();
119
    fp.close();
120
    return body;
121
 
122 6 sinclairrf
  ##############################################################################
123
  #
124
  # Methods to supplement python intrisics for the optFn argument of AddAttr
125
  #
126
  # Note:  AddAttr embelleshes exception messages with the symbol name and
127
  #        source code line number.
128
  #
129
  # Note:  One weird side effect of using lambda expressions is that the
130
  #        functions won't be recognized unless they're members of the
131
  #        SSBCCperipheral class.
132
  #
133
  ##############################################################################
134
 
135 9 sinclairrf
  def IntPow2Method(self,config,value,lowLimit=1,highLimit=None):
136 6 sinclairrf
    """
137 9 sinclairrf
    Return the integer value of the argument if it is a power of 2 between the
138
    optional limits (inclusive).  Otherwise throw an error.\n
139
    Note:  Other than a lower limit of 1 for "lowLimit", IntMethod validates
140
           "lowLimit" and "highLimit".
141 6 sinclairrf
    """
142 9 sinclairrf
    value = self.IntMethod(config,value,lowLimit,highLimit)
143
    if lowLimit < 1:
144
      raise SSBCCException('Program bug:  lowLimit = %d is less than 1' % lowLimit);
145
    if not IsPowerOf2(value):
146
      raise SSBCCException('Must be a power of 2');
147
    return value;
148
 
149
  def IntMethod(self,config,value,lowLimit=None,highLimit=None):
150
    """
151
    Return the integer value of the argument.  Throw an error if the argument is
152
    unrecognized, not an integer, or is outside the optionally specified range.
153
    """
154
    if (lowLimit != None) and (highLimit != None) and (highLimit < lowLimit):
155
      raise SSBCCException('Program bug:  lowLimit = %d and highLimit = %d conflict' % (lowLimit,highLimit,));
156 6 sinclairrf
    if re.match(r'L_\w+$',value):
157
      if not config.IsParameter(value):
158
        raise SSBCCException('Unrecognized parameter');
159
      ix = [param[0] for param in config.parameters].index(value);
160
      value = config.parameters[ix][1];
161
    elif re.match(r'C_\w+$',value):
162
      if not config.IsConstant(value):
163
        raise SSBCCException('Unrecognized constant');
164
      value = config.constants[value];
165 8 sinclairrf
    value = ParseIntExpr(value);
166 9 sinclairrf
    if (lowLimit != None) and value < lowLimit:
167
      if lowLimit == 1:
168
        raise SSBCCException('Must be a positive integer');
169
      else:
170
        raise SSBCCException('Cannot be less than %d' % lowLimit);
171
    if (highLimit != None) and value > highLimit:
172
      raise SSBCCException('Cannot be more than %d' % highLimit);
173 6 sinclairrf
    return value;
174
 
175
  def RateMethod(self,config,value):
176
    """
177
    Return the string to evaluate the provided value or ratio of two values.
178 9 sinclairrf
    The value can be an integer (including underscores), a constant, or a
179
    parameter.  Ratios are restated to do rounding instead of truncation.\n
180 6 sinclairrf
    Examples:
181
      123456
182
      123_456
183
      L_DIVISION_RATIO
184
      G_CLOCK_FREQUENCY_HZ/19200
185 9 sinclairrf
      C_CLOCK_FREQUENCY_HZ/19200
186 6 sinclairrf
      G_CLOCK_FREQUENCY_HZ/L_BAUD_RATE
187
      100_000_000/G_BAUD_RATE
188
    """
189 9 sinclairrf
    def LocalIntMethod(self,config,value,position=None):
190
      try:
191
        if config.IsParameter(value):
192
          return value;
193
        else:
194
          v = self.IntMethod(config,value,lowLimit=1);
195
          return str(v);
196
      except SSBCCException, msg:
197
        if not position:
198
          raise SSBCCException(msg);
199
        else:
200
          raise SSBCCException('%s in %s' % (msg,position,));
201 8 sinclairrf
    if value.find('/') < 0:
202 9 sinclairrf
      return LocalIntMethod(self,config,value);
203 6 sinclairrf
    else:
204
      ratearg = re.findall('([^/]+)',value);
205
      if len(ratearg) != 2:
206
        raise SSBCCException('Only one "/" allowed in expression');
207 9 sinclairrf
      ratearg[0] = LocalIntMethod(self,config,ratearg[0],'numerator');
208
      ratearg[1] = LocalIntMethod(self,config,ratearg[1],'denominator');
209 6 sinclairrf
      return '(%s+%s/2)/%s' % (ratearg[0],ratearg[1],ratearg[1],);
210 9 sinclairrf
 
211
  def TimeMethod(self,config,value,lowLimit=None,highLimit=None):
212
    """
213
    Convert the provided time from the specified units to seconds.
214
    """
215
    if not re.match(r'(0|[1-9]\d*)(\.\d*)?(e[+-]?\d+)?[mun]?s$',value):
216
      raise SSBCCException('Malformed time value');
217
    if value[-2:] == 'ms':
218
      v = float(value[:-2]) * 1.e-3;
219
    elif value[-2:] == 'us':
220
      v = float(value[:-2]) * 1.e-6;
221
    elif value[-2:] == 'ns':
222
      v = float(value[:-2]) * 1.e-9;
223
    else:
224
      v = float(value[:-1]);
225
    if (lowLimit != None) and (v < lowLimit):
226
      raise SSBCCException('%s must be %s or greater' % (v,lowLimit,));
227
    if (highLimit != None) and (v > highLimit):
228
      raise SSBCCException('%s must be %s or smaller' % (v,highLimit,));
229
    return v;

powered by: WebSVN 2.1.0

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