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

Subversion Repositories ssbcc

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

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
  def FixedPow2(self,config,lowLimit,highLimit,value):
136
    """
137
    Check the provided constant as a power of 2 between the provided limits.\n
138
    Note:  This differs from InpPow2 in that localparams and constants are
139
           permitted.
140
    """
141
    if re.match(r'L_\w+$',value):
142
      if not config.IsParameter(value):
143
        raise SSBCCException('Unrecognized parameter');
144
      ix = [param[0] for param in config.parameters].index(value);
145
      value = config.parameters[ix][1];
146
    elif re.match(r'C_\w+$',value):
147
      if not config.IsConstant(value):
148
        raise SSBCCException('Unrecognized constant');
149
      value = config.constants[value];
150
    if not IsPosInt(value):
151
      raise SSBCCException('Must be a constant positive integer');
152 8 sinclairrf
    value = ParseIntExpr(value);
153 6 sinclairrf
    if not IsPowerOf2(value):
154
      raise SSBCCException('Must be a power of 2');
155
    if not (lowLimit <= value <= highLimit):
156
      raise SSBCCException('Must be between %d and %d inclusive' % (lowLimit,highLimit,));
157
    return value;
158
 
159
  def IntPow2(self,value,minValue=1):
160
    """
161
    Return the integer value of the argument if it is a power of 2.  Otherwise
162
    throw an error.
163
    """
164
    if not IsPosInt(value):
165
      raise SSBCCException('Not a positive integer');
166 8 sinclairrf
    value = ParseIntExpr(value);
167 6 sinclairrf
    if not IsPowerOf2(value):
168
      raise SSBCCException('Not a power of 2');
169
    if value < minValue:
170
      raise SSBCCException('Must be at least %d' % minValue);
171
    return value;
172
 
173
  def PosInt(self,value,maxValue=0):
174
    """
175
    Return the integer value of the argument unless it is out of bounds.\n
176
    Note:  maxValue=0 means that there is no upper limit.
177
    """
178
    if not IsPosInt(value):
179
      raise SSBCCException('Not a positive integer');
180 8 sinclairrf
    value = ParseIntExpr(value);
181 6 sinclairrf
    if (maxValue != 0) and (value > maxValue):
182
      raise SSBCCException('Out of bounds -- can be at most %d' % maxValue);
183
    return value;
184
 
185
  def RateMethod(self,config,value):
186
    """
187
    Return the string to evaluate the provided value or ratio of two values.
188
    The value can be an integer (including underscores) or a parameter.  Ratios
189
    are restated to do rounding instead of truncation.\n
190
    Examples:
191
      123456
192
      123_456
193
      L_DIVISION_RATIO
194
      G_CLOCK_FREQUENCY_HZ/19200
195
      G_CLOCK_FREQUENCY_HZ/L_BAUD_RATE
196
      100_000_000/G_BAUD_RATE
197
    """
198 8 sinclairrf
    def TestAndGetValue(self,config,value,position):
199
      if IsIntExpr(value):
200
        return str(ParseIntExpr(value));
201
      elif config.IsConstant(value):
202
        value = config.constants[value];
203
        if not value > 0:
204
          raise SSBCCException('Constant "%s" must be positive');
205
        return str(value);
206
      elif config.IsParameter(value):
207 6 sinclairrf
        return value;
208
      else:
209 8 sinclairrf
        raise SSBCCException('%s must be a positive integer or a previously declared positive constant or a parameter', position);
210
    if value.find('/') < 0:
211
      return TestAndGetValue(self,config,value,'Value');
212 6 sinclairrf
    else:
213
      ratearg = re.findall('([^/]+)',value);
214
      if len(ratearg) != 2:
215
        raise SSBCCException('Only one "/" allowed in expression');
216 8 sinclairrf
      ratearg[0] = TestAndGetValue(self,config,ratearg[0],'Numerator');
217
      ratearg[1] = TestAndGetValue(self,config,ratearg[1],'Denominator');
218 6 sinclairrf
      return '(%s+%s/2)/%s' % (ratearg[0],ratearg[1],ratearg[1],);

powered by: WebSVN 2.1.0

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