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

Subversion Repositories ssbcc

[/] [ssbcc/] [trunk/] [core/] [9x8/] [peripherals/] [stepper_motor.py] - Blame information for rev 9

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

Line No. Rev Author Line
1 9 sinclairrf
################################################################################
2
#
3
# Copyright 2015, Sinclair R.F., Inc.
4
#
5
################################################################################
6
 
7
import math
8
 
9
from ssbccPeripheral import SSBCCperipheral
10
from ssbccUtil import CeilLog2
11
from ssbccUtil import SSBCCException
12
 
13
class stepper_motor(SSBCCperipheral):
14
  """
15
  Stepper motor driver\n
16
  This peripheral creates pulses to driver a stepper motor driver such as TI's
17
  DRV8825.  It includes a buffer which can be used to store acceleration,
18
  motion, and deceleration profiles and returns a "completed" status to the
19
  micro controller.\n
20
  The core runs accumulators for the angle and the rate.  I.e. the rate is an
21
  accumulated sum of the initial rate and the commanded acceleration and the
22
  angle is an accumulation of this possibly changing rate.  The direction signal
23
  to the stepper motor is the sign bit from the accumulated rate.  The "step"
24
  signal to the stepper motor driver is strobed every time the accumulated angle
25
  overflows or underflows and the direction bit to the driver is set according
26
  to whether the accumulated angle overflowed or underflowed.\n
27
  The motor control word consists of the following signals:
28
    initial rate
29
    acceleration
30
    number of steps to be performed this control word
31
    optional mode specification
32
  These control words are individually packed into one or more 8-bit bytes.  The
33
  8-bit values from the micro controller are shifted into a buffer from which
34
  the control word is constructed.  This completed control word is then shifted
35
  into a FIFO.  The control words in the FIFO are then used to generate the
36
  timing for the step strobes to the stepper motor driver.  When the FIFO
37
  empties, the rate and the acceleration are set to zero and the mode retains
38
  its most recent value.  The user must ensure they do not overfill the FIFO --
39
  the only FIFO status is an "empty" or control words "done" status.\n
40
  Usage:
41
    PERIPHERAL stepper_motor    basename=name                           \\
42
                                outcontrol=O_name                       \\
43
                                outrecord=O_name                        \\
44
                                outrun=O_name                           \\
45
                                indone=I_name                           \\
46
                                inerror=I_name                          \\
47
                                ratemethod={CLK_FREQ_HZ/RATE_HZ|count}  \\
48
                                ratescale=N_rate_scale                  \\
49
                                rateres=N_rate                          \\
50
                                accelscale=N_accel_scale                \\
51
                                accelres=N_accel                        \\
52
                                [accumres=N_accum]                      \\
53
                                countwidth=N_count                      \\
54
                                [modewidth=N_mode]                      \\
55
                                [FIFO=N_fifo]\n
56
  Or:\n
57
    PERIPHERAL stepper_motor    basename=name                           \\
58
                                master=mastername                       \\
59
                                outcontrol=O_name                       \\
60
                                outrecord=O_name                        \\
61
                                outrun=O_name                           \\
62
                                indone=I_name                           \\
63
                                inerror=I_name                          \\
64
                                [FIFO=N_fifo]\n
65
  Where:
66
    basename=name
67
      specifies the name used to contruct the I/O signals
68
      Note:  The name must start with an alphabetic character.
69
      Example:  "basename=stepper" results in the names "o_stepper_dir",
70
                "o_stepper_step", and "o_stepper_mode" for the output
71
                direction, step, and optional mode signals and
72
                "i_stepper_error" for the input error signal.
73
    master=mastername
74
      specifies a preceding stepper_motor peripheral to use for the internal
75
      clock and to use for the accleration, rate, angle accumulator, and mode
76
      sizes
77
    outcontrol=O_name
78
      specifies the port used to assemble 8-bit control values into the stepper
79
      motor control word
80
      Note:  The name must start with "O_".
81
    outrecord=O_name
82
      specifies the port used to generate the strobe that pushes the assembled
83
      motor control word into the stepper motor FIFO
84
      Note:  The name must start with "O_".
85
    outrun=O_name
86
      specified the port used to begin the sequence of operations specified by
87
      the motor control words in the buffer
88
      Note:  The name must start with "O_".
89
    indone=I_name
90
      specifies the port used to determine whether or not the operations in the
91
      FIFO have finished
92
      Note:  The name must start with "I_".
93
    inerror=I_name
94
      specifies the port used to read the error status from the stepper motor
95
      controller
96
      Note:  The name must start with "I_".
97
    ratemethod
98
      specified the method to generate the internal clock rate from the
99
      processor clock
100
      1st method:  CLK_FREQ_HZ/RATE_HZ
101
        CLK_FREQ_HZ is the frequency of "i_clk" in Hz
102
          a number will be interpreted as the clock frequency in Hz
103
          a symbol will be interpreted as a constant or a parameter
104
            Note:  the symbol must be declared with the CONSTANT, LOCALPARARM,
105
                   or PARAMETER configuration command.
106
        RATE_HZ is the desired internal clock rate
107
          this is specified as per "CLK_FREQ_HZ"
108
      2nd method:  count
109
        specify the number of "i_clk" clock cycles per internal clock cycle
110
      Note:  CLK_FREQ_HZ, RATE_HZ, and count can be parameters or constants.  For example,
111
             the following uses the parameter C_CLK_FREQ_HZ for the clock
112
             frequency and an internal rate to 500 kHz:
113
             "ratemethod=C_CLK_FREQ_HZ/500_000".
114
      Note:  The minimum value of "ratemethod" is 2.
115
    ratescale=N_rate_scale
116
      specifies the scaling for the most significant bit of the rate
117
      Note:  See the 'a' parameter in the "Theory of Operation" section.
118
    rateres=N_rate
119
      specifies the resolution of the rate
120
      Note:  See the 'r' parameter in the "Theory of Operation" section.
121
    accelscale=N_accel_scale
122
      specifies the scaling for the most significant bit of the acceleration
123
      Note:  See the 'a' parameter in the "Theory of Operation" section.
124
    accelres=N_accel
125
      specifies the resolution for the acceleration
126
      Note:  See the 'b' parameter in the "Theory of Operation" section.
127
    accumres=N_accum
128
      optionally specify the resolution for the accumulator to the summed angle
129
      (from which the step strobes are generated)
130
      Note:  This must be between rateres and accelres.
131
      Note:  The default value is accelres.
132
    countwidth=N_count
133
      specifies the width of the counter for the number of steps to be performed
134
      by the control word
135
    modewidth=N_mode
136
      - if not specified, there is no mode signal to the stepper motor
137
        controller
138
      - if specified then this specifies the width of the signal to the stepper
139
        motor controller
140
    FIFO=N_fifo
141
      optionally specify the depth of the control word FIFO
142
      Note:  This must be a power of 2 and must be at least 16.
143
      Note:  The default is 16.\n
144
  Theory of Operation:
145
    Define the following:
146
      n         is the number of internal clock cycles since the control word
147
                started being performed (i.e., these are counted after the dlock
148
                rate is reduced by ratemethod)
149
      F         is the internal clock cycle frequency (i.e., RATE_HZ in the
150
                second form for specifying the ratemethod
151
      R_0       is the initial rate command
152
      R_n       is the accumulated rate after n internal clock cycles
153
      A         is the commanded acceleration
154
      S_n       is the accumulated step after n internal clock cycles
155
    Then
156
      R_n = R_0 + A * n
157
      S_n = R_0 * n + A * n * (n-1) / 2
158
    The rate R_n can be thought of as a signed fraction with the format "s0.r"
159
    where 's' represents the sign bit, there are no bits to the left of the
160
    decimal, and there are 'r' bits to the right of the decimal.  Then the rate
161
    can be as high as F and as low as F/2^r.  Practically, the maximum rate
162
    cannot exceed half the internal clock frequency, otherwise the "step"
163
    signals will merge together and the stepper driver will not see distinct
164
    driver pulses.\n
165
    Similarly, the acceleration command A can be thought of as a signed fraction
166
    with the format "sa.b".  Here 's' again represents the sign bit and 'b'
167
    represents the number of bits to the right of the decimial, but 'a' is a
168
    negative number representing the first bit in A.  I.e., aside from the sign
169
    bit, A is b+a+1 bits wide.  For example, the specification s-4.8 means that
170
    A has a sign bit with 8-4+1 = 5 bits for the value of A with the leasts
171
    significant bit representing a rate of F^2/2^8.\n
172
    The bit widths are determined as follows: Let mR be the minimum non-zero
173
    magnitude of the rate, mA be the minimum non-zero mangitude of the
174
    acceleration, and MA be the mamximum magnitude of the acceleration, all in
175
    step/sec or step/sec^2.  Then\n
176
      r = ceil(-log_2(mR/F))\n
177
      a = floor(log_2(MA/F^2))\n
178
      b = ceil(-log_2(mA/f^2))\n
179
    Note:  r and b may be increased by a few bits if accurate representations of
180
    the minimum rates are needed.\n
181
  Example:
182
    A micro controller with an 8 MHz clock is used to operate a DRV8825 driving
183
    a stepper motor assembly.  The stepper motor has 200 steps per revolution,
184
    can be operated in full-step or a 16-step micro step mode, has a maximum
185
    rotation rate of 10 Hz, and has a maximum acceleration of 4 Hz/sec (i.e.,
186
    800 full-steps/sec^2).  The motor is attached to a 400mm theaded rod with a
187
    pitch of 4mm per revolution.\n
188
    The 1.9usec minimum high and low widths of the DRV8825 and the 8 MHz
189
    processor clock mean that the stepper motor controller can realistically be
190
    run at 500kHz.  The rate method to divide the micro controller clock to the
191
    internal processing rate is specified by "ratemethod" in the PERIPHERAL
192
    command.\n
193
    The bit widths are determine by choosing:\n
194
      MR = 10 rev/sec * 200 full-step/rev * 16 micro-step/full-step
195
         = 32000 micro-step/sec
196
        ==> R = -ceil(log_2(MR/F))
197
              = -ceil(log_2((32000 micro-step/sec)/500kHz))
198
              = 3
199
      mR = 10 step/sec
200
        ==> r = -floor(log_2(mR/F))
201
              = -floor(log_2((10 step/sec)/500kHz)
202
              = 16\n
203
      MA = 10 rev/sec^2 = 10*16*200 step/sec^2
204
        ==> A = -ceil(log_2(MA/F^2))
205
              = -ceil(log_2((32,000 step/sec^2)/500kHz^2))
206
              = 22\n
207
      mA = 20 step/sec^2 (in full step mode)
208
        ==> a = -floor(log_2(mA/F^2))
209
              = 34\n
210
    The values R=3 and r=16 along with the sign bit mean the rate would be
211
    stored in a signed 14-bit value.  The rate requires two 8-bit writes to the
212
    control word.\n
213
    The values A=22 and a=34 mean the acceleration would be stored in a signed
214
    1+(34-22) = 13 bit value.  The acceleration requires two 8-bit writes to the
215
    control word.\n
216
    The accumulator width is set to the same value as the acceleration
217
    resolution.  This avoid non-linear trunction errors and makes the motion
218
    profile more predictable using simple integer arithmetic.\n
219
    The number of full steps to move from one of the of rod to the other is
220
    (400mm/(4mm/rev)*(200steps/rev)=20_000 steps.  In the micro-stepmode there
221
    are 16 micro steps per full step, so at most 320_000 micro steps can be
222
    performed before the full length of the rod is traversed.  I.e., a 19-bit
223
    counter will suffice for the worst-case unidirection motion.  This 19-bit
224
    count requires 3 8-bit writes to the control word.\n
225
    A "modewidth" of 1 is specifies so that the controller can be operated in
226
    either full step or a single hard-wired micro-step mode.  If all 3 of the
227
    DRV8825 mode pins were connected, then "modewidth=3" would need to
228
    specified.\n
229
    The peripheral is then specified as follows:\n
230
      CONSTANT          C_RATE_SCALE     3
231
      CONSTANT          C_RATE_RES      16
232
      CONSTANT          C_ACCEL_SCALE   22
233
      CONSTANT          C_ACCEL_RES     34
234
      CONSTANT          C_ACCUM_RES     34
235
      CONSTANT          C_COUNT_WIDTH   19
236
      PERIPHERAL        stepper_motor   basename=stepper                \\
237
                                        outcontrol=O_stepper_control    \\
238
                                        outrecord=O_stepper_wr          \\
239
                                        outrun=O_stepper_go             \\
240
                                        indone=I_stepper_done           \\
241
                                        inerror=I_stepper_error         \\
242
                                        ratemethod=8_000_000/500_000    \\
243
                                        ratescale=C_RATE_SCALE          \\
244
                                        rateres=C_RATE_RES              \\
245
                                        accelscale=C_ACCEL_SCALE        \\
246
                                        accelres=C_ACCEL_RES            \\
247
                                        accumres=C_ACCUM_RES            \\
248
                                        countwidth=C_COUNT_WIDTH        \\
249
                                        modewidth=1\n
250
    and the TBD byte control words are pushed into the peripheral as follows:
251
      R_0       14-bit initial rate stored in a 16-bit field (MSB first)
252
      A         13-bit acceleration stored in a 16-bit field (MSB first)
253
      COUNT     19-bit count stored in a 24-bit field (MSB first)
254
      MODE      1-bit mode stored as the lsb of an 8-bit field
255
    The control word is a total of 8 bytes wide.\n
256
    To command the peripheral to accelerate from stop to 200 steps/sec in one
257
    second in the forward direction using the full-step mode, the following
258
    seqeuence of bytes would be written to the control port:
259
      0x00 0x00         ; initial rate is zero
260
      0x00 0x0E         ; 200 step/sec^2 * 2^34 / 500kHz^2 = 14
261
      0x00 0x00 0x63    ; send 100 step commands (command 100-1=99)
262
      0x00              ; full-step mode
263
    Note:  It will take t=sqrt(2*100*2^34/14)/F = 0.99 sec to move the commanded
264
    100 steps.  At this time the speed will be r=t*14/2^34*F^2 = 201 step/sec.
265
    A more accurate match to the commanded speed could be accomplished by adding
266
    additional bits to the acceleration resolution at the cost of using more
267
    FPGA resources.  Alternatively, the acceleration could be commanded for 99
268
    steps and any subsequent 200 step/sec motion could be lengthened by 1 step.
269
    Another alternative would be to use a micro-step acceleration.  Practically,
270
    the computed command is within 0.5% of the desired step rate.\n
271
    To command the peripheral to decelerate from 200 step/sec to zero in one
272
    second, the following sequence of bytes would be written to the control
273
    port:
274
      0x00 0x01 0xDB    ; 200 step/sec * 2^23 / 500kHz
275
      0xFF 0x9C         ; negative of the above acceleration
276
      0x00 0x00 0x63    ; send 100 step commands (command 100-1=99)
277
      0x00              ; full-step mode\n
278
    The first of these two control words could be assembled and transmitted to
279
    the peripheral as follows:\n
280
      0x00                      ; mode
281
      .push24(${100-1})         ; send 100 step commands
282
      .push16(14)               ; 200 step/sec^2
283
      .push16(0)                ; initial rate is zero
284
      ${8-1} :loop swap .outport(O_stepper_control) .jumpc(loop,1-) drop
285
      .outstrobe(O_stepper_wr)  ; push the assembed control word into the FIFO
286
      ...
287
      .outstrobe(O_stepper_go)  ; perform the queued control words\n
288
    Example:
289
      Slave a second stepper motor controller peripheral to the preceding
290
      periperal.\n
291
      PERIPHERAL        stepper_motor   basename=slave                  \\
292
                                        master=stepper                  \\
293
                                        outcontrol=O_slave_control      \\
294
                                        outrecord=O_slave_wr            \\
295
                                        outrun=O_slave_go               \\
296
                                        indone=I_slave_done             \\
297
                                        inerror=I_slave_error\n
298
      This controller will use the internal clock generated by the first
299
      controller and the scales, resolutions, and accumulator width will be the
300
      same as that master peripheral.  What will be different is the four I/O
301
      ports used to operate and status the controller.
302
    """
303
 
304
  def __init__(self,peripheralFile,config,param_list,loc):
305
    # Use the externally provided file name for the peripheral
306
    self.peripheralFile = peripheralFile
307
    # Get the parameters.
308
    allowables = (
309
      ( 'FIFO',         r'\S+$',                lambda v : self.IntPow2Method(config,v,lowLimit=16),  ),
310
      ( 'accelres',     r'\S+$',                lambda v : self.IntMethod(config,v,lowLimit=1),       ),
311
      ( 'accelscale',   r'\S+$',                lambda v : self.IntMethod(config,v,lowLimit=1),       ),
312
      ( 'accumres',     r'\S+$',                lambda v : self.IntMethod(config,v,lowLimit=1),       ),
313
      ( 'basename',     r'[A-Za-z]\w*$',        None,                                                 ),
314
      ( 'countwidth',   r'\S+$',                lambda v : self.IntMethod(config,v,lowLimit=1),       ),
315
      ( 'indone',       r'I_\w+$',              None,                                                 ),
316
      ( 'inerror',      r'I_\w+$',              None,                                                 ),
317
      ( 'master',       r'[A-Za-z]\w*$',        None,                                                 ),
318
      ( 'modewidth',    r'\S+$',                lambda v : self.IntMethod(config,v,lowLimit=1),       ),
319
      ( 'outcontrol',   r'O_\w+$',              None,                                                 ),
320
      ( 'outrecord',    r'O_\w+$',              None,                                                 ),
321
      ( 'outrun',       r'O_\w+$',              None,                                                 ),
322
      ( 'ratemethod',   r'\S+$',                lambda v : self.RateMethod(config,v),                 ),
323
      ( 'rateres',      r'\S+$',                lambda v : self.IntMethod(config,v,lowLimit=1),       ),
324
      ( 'ratescale',    r'\S+$',                lambda v : self.IntMethod(config,v,lowLimit=1),       ),
325
    )
326
    names = [a[0] for a in allowables]
327
    for param_tuple in param_list:
328
      param = param_tuple[0]
329
      if param not in names:
330
        raise SSBCCException('Unrecognized parameter "%s" at %s' % (param,loc,))
331
      param_test = allowables[names.index(param)]
332
      self.AddAttr(config,param,param_tuple[1],param_test[1],loc,param_test[2])
333
    # Signals that can't be specified when a master is specified.
334
    masterExclude = (
335
      'accelres',
336
      'accelscale',
337
      'accumres',
338
      'countwidth',
339
      'modewidth',
340
      'ratemethod',
341
      'rateres',
342
      'ratescale',
343
    )
344
    # Ensure the required parameters are provided.
345
    reqdParms = (
346
      'basename',
347
      'indone',
348
      'inerror',
349
      'outcontrol',
350
      'outrecord',
351
      'outrun',
352
    )
353
    if not hasattr(self,'master'):
354
      reqdParms += tuple([me for me in masterExclude if me not in ('accumres','modewidth',)])
355
    for paramname in reqdParms:
356
      if not hasattr(self,paramname):
357
        raise SSBCCException('Required parameter "%s" is missing at %s' % (paramname,loc,))
358
    # Ensure mutually exclusive parameters are not listed.
359
    if hasattr(self,'master'):
360
      for paramname in masterExclude:
361
        if hasattr(self,paramname):
362
          raise SSBCCException('Parameter "%s" cannot be specified alongside "master" at %s' % (paramname,loc,))
363
    # Ensure basename is unique for this class of peripheral
364
    for p in config.peripheral:
365
      if (str(p.__class__) == str(self.__class__)) and (p.basename == self.basename):
366
        raise SSBCCException('Duplicated stepper_motor basename "%s" at %s' % (self.basename,loc,))
367
    # For slaves, copy the bit widths from the master peripheral.
368
    if hasattr(self,'master'):
369
      for p in config.peripheral:
370
        if (str(p.__class__) == str(self.__class__)) and (p.basename == self.master):
371
          break
372
      else:
373
        raise SSBCCException('Can\'t find preceding stepper_motor peripheral with basename=%s at %s ' % (self.master,loc,))
374
      self.master = p
375
      for paramname in masterExclude:
376
        setattr(self,paramname,getattr(self.master,paramname))
377
    # Set unspecified optional parameters.
378
    if not hasattr(self,'accumres'):
379
      self.accumres = self.accelres
380
    if not hasattr(self,'modewidth'):
381
      self.modewidth = 0
382
    if not hasattr(self,'FIFO'):
383
      self.FIFO = 16
384
    # Ensure the parameters satisfy any mutual constraints.
385
    if not (self.rateres < self.accelres):
386
      raise SSBCCException('rateres should be smaller than accelres at %s' % loc)
387
    if not (self.rateres <= self.accumres <= self.accelres):
388
      raise SSBCCException('accumres must be between rateres and accelres at %s' % loc)
389
    # Add the I/O port, internal signals, and the INPORT and OUTPORT symbols for this peripheral.
390
    config.AddIO('o_%s_dir'    % self.basename, 1, 'output', loc)
391
    config.AddIO('o_%s_step'   % self.basename, 1, 'output', loc)
392
    if self.modewidth > 0:
393
      config.AddIO('o_%s_mode' % self.basename, 1, 'output', loc)
394
    config.AddIO('i_%s_error'  % self.basename, 1, 'input',  loc)
395
    config.AddSignal('s__%s__done' % self.basename, 1, loc)
396
    self.ix_outcontrol = config.NOutports()
397
    config.AddOutport((self.outcontrol,
398
                       False,
399
                       # empty list
400
                      ),loc)
401
    self.ix_outrecord = config.NOutports()
402
    config.AddOutport((self.outrecord,
403
                       True,
404
                       # empty list
405
                      ),loc)
406
    self.ix_outrun = config.NOutports()
407
    config.AddOutport((self.outrun,
408
                       True,
409
                       # empty list
410
                      ),loc)
411
    config.AddInport((self.inerror,
412
                      ('i_%s_error' % self.basename, 1, 'data', ),
413
                     ), loc)
414
    config.AddInport((self.indone,
415
                      ('s__%s__done' % self.basename, 1, 'data', ),
416
                     ), loc)
417
    # Compute bit widths.
418
    dw = config.Get('data_width')
419
    self.data_width = dw
420
    self.ratecmdwidth = 1 + self.rateres - self.ratescale
421
    self.ratewidth = 1 + self.accelres - self.ratescale
422
    self.accelwidth = 1 + self.accelres - self.accelscale
423
    self.accumwidth = self.accumres + 1
424
    self.controlwidth = self.ratecmdwidth
425
    self.controlwidth += dw*int((self.accelwidth+dw-1)/dw)
426
    self.controlwidth += dw*int((self.countwidth+dw-1)/dw)
427
    self.controlwidth += dw*int((self.modewidth+dw-1)/dw)
428
    self.controlwidthpacked = self.ratecmdwidth + self.accelwidth + self.countwidth + self.modewidth
429
    # Add the 'clog2' function to the processor (if required).
430
    config.functions['clog2'] = True
431
 
432
  def GenVerilog(self,fp,config):
433
    body = self.LoadCore(self.peripheralFile,'.v')
434
    if hasattr(self,'master'):
435
      body = re.sub(r'@MASTER_BEGIN@.*?@MASTER_END@\n','',body,flags=re.DOTALL)
436
    else:
437
      body = re.sub(r'@MASTER_BEGIN@\n','',body)
438
      body = re.sub(r'@MASTER_END@\n','',body)
439
    if self.modewidth == 0:
440
      body = re.sub(r'@OUTMODE_BEGIN@.*?@OUTMODE_END@\n','',body,flags=re.DOTALL)
441
    else:
442
      body = re.sub(r'@OUTMODE_BEGIN@\n','',body)
443
      body = re.sub(r'@OUTMODE_END@\n','',body)
444
    for subpair in (
445
      ( r'@ACCEL_WIDTH@',               str(self.accelwidth),           ),
446
      ( r'@ACCEL_RES@',                 str(self.accelres),             ),
447
      ( r'@ACCEL_SCALE@',               str(self.accelscale),           ),
448
      ( r'@ACCUM_RES@',                 str(self.accumres),             ),
449
      ( r'@ACCUM_WIDTH@',               str(self.accumwidth),           ),
450
      ( r'@CONTROL_WIDTH@',             str(self.controlwidth),         ),
451
      ( r'@CONTROL_WIDTH_PACKED@',      str(self.controlwidthpacked),   ),
452
      ( r'@COUNT_WIDTH@',               str(self.countwidth),           ),
453
      ( r'@DW@',                        str(self.data_width),           ),
454
      ( r'@DWM1@',                      str(self.data_width-1),         ),
455
      ( r'@FIFO_DEPTH@',                str(self.FIFO),                 ),
456
      ( r'@IX_OUTCONTROL@',             str(self.ix_outcontrol),        ),
457
      ( r'@IX_OUTRECORD@',              str(self.ix_outrecord),         ),
458
      ( r'@IX_OUTRUN@',                 str(self.ix_outrun),            ),
459
      ( r'@MODE_WIDTH@',                str(self.modewidth),            ),
460
      ( r'@NAME@',                      self.basename,                  ),
461
      ( r'@NBITS_FIFO_DEPTH@',          str(CeilLog2(self.FIFO)),       ),
462
      ( r'@OUTMODEWIDTH@',              str(self.modewidth),            ),
463
      ( r'@RATECMD_WIDTH@',             str(self.ratecmdwidth),         ),
464
      ( r'@RATEMETHOD@',                str(self.ratemethod),           ),
465
      ( r'@RATE_RES@',                  str(self.rateres),              ),
466
      ( r'@RATE_SCALE@',                str(self.ratescale),            ),
467
      ( r'@RATE_WIDTH@',                str(self.ratewidth),            ),
468
      ( r'\bL__',                       'L__%s__' % self.basename,      ),
469
      ( r'\bi__',                       'i_%s_' % self.basename,        ),
470
      ( r'\bo__',                       'o_%s_' % self.basename,        ),
471
      ( r'\bs__',                       's__%s__' % self.basename,      ),
472
      ( r'@S__CLK_EN@',                 's__%s__clk_en' % (self.basename if not hasattr(self,'master') else self.master.basename), ),
473
    ):
474
      body = re.sub(subpair[0],subpair[1],body)
475
    body = self.GenVerilogFinal(config,body)
476
    fp.write(body)

powered by: WebSVN 2.1.0

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