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

Subversion Repositories ssbcc

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

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
                                outrecord=O_name                        \\
60
                                outrun=O_name                           \\
61
                                indone=I_name                           \\
62
                                inerror=I_name                          \\
63
                                [FIFO=N_fifo]\n
64
  Where:
65
    basename=name
66
      specifies the name used to contruct the I/O signals
67
      Note:  The name must start with an alphabetic character.
68
      Example:  "basename=stepper" results in the names "o_stepper_dir",
69
                "o_stepper_step", and "o_stepper_mode" for the output
70
                direction, step, and optional mode signals and
71
                "i_stepper_error" for the input error signal.
72
    master=mastername
73
      specifies a preceding stepper_motor peripheral to use for the internal
74
      clock and to use for the accleration, rate, angle accumulator, and mode
75
      sizes
76 10 sinclairrf
      Note:  The "outcontrol" port from the master peripheral is used to queue
77
             the control words for its slaves.
78 9 sinclairrf
    outcontrol=O_name
79
      specifies the port used to assemble 8-bit control values into the stepper
80
      motor control word
81
      Note:  The name must start with "O_".
82
    outrecord=O_name
83
      specifies the port used to generate the strobe that pushes the assembled
84
      motor control word into the stepper motor FIFO
85
      Note:  The name must start with "O_".
86
    outrun=O_name
87
      specified the port used to begin the sequence of operations specified by
88
      the motor control words in the buffer
89
      Note:  The name must start with "O_".
90
    indone=I_name
91
      specifies the port used to determine whether or not the operations in the
92
      FIFO have finished
93
      Note:  The name must start with "I_".
94
    inerror=I_name
95
      specifies the port used to read the error status from the stepper motor
96
      controller
97
      Note:  The name must start with "I_".
98
    ratemethod
99
      specified the method to generate the internal clock rate from the
100
      processor clock
101
      1st method:  CLK_FREQ_HZ/RATE_HZ
102
        CLK_FREQ_HZ is the frequency of "i_clk" in Hz
103
          a number will be interpreted as the clock frequency in Hz
104
          a symbol will be interpreted as a constant or a parameter
105
            Note:  the symbol must be declared with the CONSTANT, LOCALPARARM,
106
                   or PARAMETER configuration command.
107
        RATE_HZ is the desired internal clock rate
108
          this is specified as per "CLK_FREQ_HZ"
109
      2nd method:  count
110
        specify the number of "i_clk" clock cycles per internal clock cycle
111
      Note:  CLK_FREQ_HZ, RATE_HZ, and count can be parameters or constants.  For example,
112
             the following uses the parameter C_CLK_FREQ_HZ for the clock
113
             frequency and an internal rate to 500 kHz:
114
             "ratemethod=C_CLK_FREQ_HZ/500_000".
115
      Note:  The minimum value of "ratemethod" is 2.
116
    ratescale=N_rate_scale
117
      specifies the scaling for the most significant bit of the rate
118
      Note:  See the 'a' parameter in the "Theory of Operation" section.
119
    rateres=N_rate
120
      specifies the resolution of the rate
121
      Note:  See the 'r' parameter in the "Theory of Operation" section.
122
    accelscale=N_accel_scale
123
      specifies the scaling for the most significant bit of the acceleration
124
      Note:  See the 'a' parameter in the "Theory of Operation" section.
125
    accelres=N_accel
126
      specifies the resolution for the acceleration
127
      Note:  See the 'b' parameter in the "Theory of Operation" section.
128
    accumres=N_accum
129
      optionally specify the resolution for the accumulator to the summed angle
130
      (from which the step strobes are generated)
131
      Note:  This must be between rateres and accelres.
132
      Note:  The default value is accelres.
133
    countwidth=N_count
134
      specifies the width of the counter for the number of steps to be performed
135
      by the control word
136
    modewidth=N_mode
137
      - if not specified, there is no mode signal to the stepper motor
138
        controller
139
      - if specified then this specifies the width of the signal to the stepper
140
        motor controller
141
    FIFO=N_fifo
142
      optionally specify the depth of the control word FIFO
143
      Note:  This must be a power of 2 and must be at least 16.
144
      Note:  The default is 16.\n
145
  Theory of Operation:
146
    Define the following:
147
      n         is the number of internal clock cycles since the control word
148
                started being performed (i.e., these are counted after the dlock
149
                rate is reduced by ratemethod)
150
      F         is the internal clock cycle frequency (i.e., RATE_HZ in the
151
                second form for specifying the ratemethod
152
      R_0       is the initial rate command
153
      R_n       is the accumulated rate after n internal clock cycles
154
      A         is the commanded acceleration
155
      S_n       is the accumulated step after n internal clock cycles
156
    Then
157
      R_n = R_0 + A * n
158
      S_n = R_0 * n + A * n * (n-1) / 2
159
    The rate R_n can be thought of as a signed fraction with the format "s0.r"
160
    where 's' represents the sign bit, there are no bits to the left of the
161
    decimal, and there are 'r' bits to the right of the decimal.  Then the rate
162
    can be as high as F and as low as F/2^r.  Practically, the maximum rate
163
    cannot exceed half the internal clock frequency, otherwise the "step"
164
    signals will merge together and the stepper driver will not see distinct
165
    driver pulses.\n
166
    Similarly, the acceleration command A can be thought of as a signed fraction
167
    with the format "sa.b".  Here 's' again represents the sign bit and 'b'
168
    represents the number of bits to the right of the decimial, but 'a' is a
169
    negative number representing the first bit in A.  I.e., aside from the sign
170
    bit, A is b+a+1 bits wide.  For example, the specification s-4.8 means that
171
    A has a sign bit with 8-4+1 = 5 bits for the value of A with the leasts
172
    significant bit representing a rate of F^2/2^8.\n
173
    The bit widths are determined as follows: Let mR be the minimum non-zero
174
    magnitude of the rate, mA be the minimum non-zero mangitude of the
175
    acceleration, and MA be the mamximum magnitude of the acceleration, all in
176
    step/sec or step/sec^2.  Then\n
177
      r = ceil(-log_2(mR/F))\n
178
      a = floor(log_2(MA/F^2))\n
179
      b = ceil(-log_2(mA/f^2))\n
180
    Note:  r and b may be increased by a few bits if accurate representations of
181
    the minimum rates are needed.\n
182
  Example:
183
    A micro controller with an 8 MHz clock is used to operate a DRV8825 driving
184
    a stepper motor assembly.  The stepper motor has 200 steps per revolution,
185
    can be operated in full-step or a 16-step micro step mode, has a maximum
186
    rotation rate of 10 Hz, and has a maximum acceleration of 4 Hz/sec (i.e.,
187
    800 full-steps/sec^2).  The motor is attached to a 400mm theaded rod with a
188
    pitch of 4mm per revolution.\n
189
    The 1.9usec minimum high and low widths of the DRV8825 and the 8 MHz
190
    processor clock mean that the stepper motor controller can realistically be
191
    run at 500kHz.  The rate method to divide the micro controller clock to the
192
    internal processing rate is specified by "ratemethod" in the PERIPHERAL
193
    command.\n
194
    The bit widths are determine by choosing:\n
195
      MR = 10 rev/sec * 200 full-step/rev * 16 micro-step/full-step
196
         = 32000 micro-step/sec
197
        ==> R = -ceil(log_2(MR/F))
198
              = -ceil(log_2((32000 micro-step/sec)/500kHz))
199
              = 3
200
      mR = 10 step/sec
201
        ==> r = -floor(log_2(mR/F))
202
              = -floor(log_2((10 step/sec)/500kHz)
203
              = 16\n
204
      MA = 10 rev/sec^2 = 10*16*200 step/sec^2
205
        ==> A = -ceil(log_2(MA/F^2))
206
              = -ceil(log_2((32,000 step/sec^2)/500kHz^2))
207
              = 22\n
208
      mA = 20 step/sec^2 (in full step mode)
209
        ==> a = -floor(log_2(mA/F^2))
210
              = 34\n
211
    The values R=3 and r=16 along with the sign bit mean the rate would be
212
    stored in a signed 14-bit value.  The rate requires two 8-bit writes to the
213
    control word.\n
214
    The values A=22 and a=34 mean the acceleration would be stored in a signed
215
    1+(34-22) = 13 bit value.  The acceleration requires two 8-bit writes to the
216
    control word.\n
217
    The accumulator width is set to the same value as the acceleration
218
    resolution.  This avoid non-linear trunction errors and makes the motion
219
    profile more predictable using simple integer arithmetic.\n
220
    The number of full steps to move from one of the of rod to the other is
221
    (400mm/(4mm/rev)*(200steps/rev)=20_000 steps.  In the micro-stepmode there
222
    are 16 micro steps per full step, so at most 320_000 micro steps can be
223
    performed before the full length of the rod is traversed.  I.e., a 19-bit
224
    counter will suffice for the worst-case unidirection motion.  This 19-bit
225
    count requires 3 8-bit writes to the control word.\n
226
    A "modewidth" of 1 is specifies so that the controller can be operated in
227
    either full step or a single hard-wired micro-step mode.  If all 3 of the
228
    DRV8825 mode pins were connected, then "modewidth=3" would need to
229
    specified.\n
230
    The peripheral is then specified as follows:\n
231
      CONSTANT          C_RATE_SCALE     3
232
      CONSTANT          C_RATE_RES      16
233
      CONSTANT          C_ACCEL_SCALE   22
234
      CONSTANT          C_ACCEL_RES     34
235
      CONSTANT          C_ACCUM_RES     34
236
      CONSTANT          C_COUNT_WIDTH   19
237
      PERIPHERAL        stepper_motor   basename=stepper                \\
238
                                        outcontrol=O_stepper_control    \\
239
                                        outrecord=O_stepper_wr          \\
240
                                        outrun=O_stepper_go             \\
241
                                        indone=I_stepper_done           \\
242
                                        inerror=I_stepper_error         \\
243
                                        ratemethod=8_000_000/500_000    \\
244
                                        ratescale=C_RATE_SCALE          \\
245
                                        rateres=C_RATE_RES              \\
246
                                        accelscale=C_ACCEL_SCALE        \\
247
                                        accelres=C_ACCEL_RES            \\
248
                                        accumres=C_ACCUM_RES            \\
249
                                        countwidth=C_COUNT_WIDTH        \\
250
                                        modewidth=1\n
251
    and the TBD byte control words are pushed into the peripheral as follows:
252
      R_0       14-bit initial rate stored in a 16-bit field (MSB first)
253
      A         13-bit acceleration stored in a 16-bit field (MSB first)
254
      COUNT     19-bit count stored in a 24-bit field (MSB first)
255
      MODE      1-bit mode stored as the lsb of an 8-bit field
256
    The control word is a total of 8 bytes wide.\n
257
    To command the peripheral to accelerate from stop to 200 steps/sec in one
258
    second in the forward direction using the full-step mode, the following
259
    seqeuence of bytes would be written to the control port:
260
      0x00 0x00         ; initial rate is zero
261
      0x00 0x0E         ; 200 step/sec^2 * 2^34 / 500kHz^2 = 14
262
      0x00 0x00 0x63    ; send 100 step commands (command 100-1=99)
263
      0x00              ; full-step mode
264
    Note:  It will take t=sqrt(2*100*2^34/14)/F = 0.99 sec to move the commanded
265
    100 steps.  At this time the speed will be r=t*14/2^34*F^2 = 201 step/sec.
266
    A more accurate match to the commanded speed could be accomplished by adding
267
    additional bits to the acceleration resolution at the cost of using more
268
    FPGA resources.  Alternatively, the acceleration could be commanded for 99
269
    steps and any subsequent 200 step/sec motion could be lengthened by 1 step.
270
    Another alternative would be to use a micro-step acceleration.  Practically,
271
    the computed command is within 0.5% of the desired step rate.\n
272
    To command the peripheral to decelerate from 200 step/sec to zero in one
273
    second, the following sequence of bytes would be written to the control
274
    port:
275
      0x00 0x01 0xDB    ; 200 step/sec * 2^23 / 500kHz
276
      0xFF 0x9C         ; negative of the above acceleration
277
      0x00 0x00 0x63    ; send 100 step commands (command 100-1=99)
278
      0x00              ; full-step mode\n
279
    The first of these two control words could be assembled and transmitted to
280
    the peripheral as follows:\n
281
      0x00                      ; mode
282
      .push24(${100-1})         ; send 100 step commands
283
      .push16(14)               ; 200 step/sec^2
284
      .push16(0)                ; initial rate is zero
285
      ${8-1} :loop swap .outport(O_stepper_control) .jumpc(loop,1-) drop
286
      .outstrobe(O_stepper_wr)  ; push the assembed control word into the FIFO
287
      ...
288
      .outstrobe(O_stepper_go)  ; perform the queued control words\n
289
    Example:
290
      Slave a second stepper motor controller peripheral to the preceding
291
      periperal.\n
292
      PERIPHERAL        stepper_motor   basename=slave                  \\
293
                                        master=stepper                  \\
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 10 sinclairrf
      'outcontrol',
341 9 sinclairrf
      'ratemethod',
342
      'rateres',
343
      'ratescale',
344
    )
345
    # Ensure the required parameters are provided.
346
    reqdParms = (
347
      'basename',
348
      'indone',
349
      'inerror',
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 10 sinclairrf
    if not hasattr(self,'master'):
398
      config.AddOutport((self.outcontrol,
399
                         False,
400
                         # empty list
401
                        ),loc)
402 9 sinclairrf
    self.ix_outrecord = config.NOutports()
403
    config.AddOutport((self.outrecord,
404
                       True,
405
                       # empty list
406
                      ),loc)
407
    self.ix_outrun = config.NOutports()
408
    config.AddOutport((self.outrun,
409
                       True,
410
                       # empty list
411
                      ),loc)
412
    config.AddInport((self.inerror,
413
                      ('i_%s_error' % self.basename, 1, 'data', ),
414
                     ), loc)
415
    config.AddInport((self.indone,
416
                      ('s__%s__done' % self.basename, 1, 'data', ),
417
                     ), loc)
418
    # Compute bit widths.
419
    dw = config.Get('data_width')
420
    self.data_width = dw
421
    self.ratecmdwidth = 1 + self.rateres - self.ratescale
422
    self.ratewidth = 1 + self.accelres - self.ratescale
423
    self.accelwidth = 1 + self.accelres - self.accelscale
424
    self.accumwidth = self.accumres + 1
425
    self.controlwidth = self.ratecmdwidth
426
    self.controlwidth += dw*int((self.accelwidth+dw-1)/dw)
427
    self.controlwidth += dw*int((self.countwidth+dw-1)/dw)
428
    self.controlwidth += dw*int((self.modewidth+dw-1)/dw)
429
    self.controlwidthpacked = self.ratecmdwidth + self.accelwidth + self.countwidth + self.modewidth
430
    # Add the 'clog2' function to the processor (if required).
431
    config.functions['clog2'] = True
432
 
433
  def GenVerilog(self,fp,config):
434
    body = self.LoadCore(self.peripheralFile,'.v')
435
    if hasattr(self,'master'):
436
      body = re.sub(r'@MASTER_BEGIN@.*?@MASTER_END@\n','',body,flags=re.DOTALL)
437
    else:
438
      body = re.sub(r'@MASTER_BEGIN@\n','',body)
439
      body = re.sub(r'@MASTER_END@\n','',body)
440
    if self.modewidth == 0:
441
      body = re.sub(r'@OUTMODE_BEGIN@.*?@OUTMODE_END@\n','',body,flags=re.DOTALL)
442
    else:
443
      body = re.sub(r'@OUTMODE_BEGIN@\n','',body)
444
      body = re.sub(r'@OUTMODE_END@\n','',body)
445 10 sinclairrf
    masterBasename = self.basename if not hasattr(self,'master') else self.master.basename
446 9 sinclairrf
    for subpair in (
447
      ( r'@ACCEL_WIDTH@',               str(self.accelwidth),           ),
448
      ( r'@ACCEL_RES@',                 str(self.accelres),             ),
449
      ( r'@ACCEL_SCALE@',               str(self.accelscale),           ),
450
      ( r'@ACCUM_RES@',                 str(self.accumres),             ),
451
      ( r'@ACCUM_WIDTH@',               str(self.accumwidth),           ),
452
      ( r'@CONTROL_WIDTH@',             str(self.controlwidth),         ),
453
      ( r'@CONTROL_WIDTH_PACKED@',      str(self.controlwidthpacked),   ),
454
      ( r'@COUNT_WIDTH@',               str(self.countwidth),           ),
455
      ( r'@DW@',                        str(self.data_width),           ),
456
      ( r'@DWM1@',                      str(self.data_width-1),         ),
457
      ( r'@FIFO_DEPTH@',                str(self.FIFO),                 ),
458
      ( r'@IX_OUTCONTROL@',             str(self.ix_outcontrol),        ),
459
      ( r'@IX_OUTRECORD@',              str(self.ix_outrecord),         ),
460
      ( r'@IX_OUTRUN@',                 str(self.ix_outrun),            ),
461
      ( r'@MODE_WIDTH@',                str(self.modewidth),            ),
462
      ( r'@NAME@',                      self.basename,                  ),
463
      ( r'@NBITS_FIFO_DEPTH@',          str(CeilLog2(self.FIFO)),       ),
464
      ( r'@OUTMODEWIDTH@',              str(self.modewidth),            ),
465
      ( r'@RATECMD_WIDTH@',             str(self.ratecmdwidth),         ),
466
      ( r'@RATEMETHOD@',                str(self.ratemethod),           ),
467
      ( r'@RATE_RES@',                  str(self.rateres),              ),
468
      ( r'@RATE_SCALE@',                str(self.ratescale),            ),
469
      ( r'@RATE_WIDTH@',                str(self.ratewidth),            ),
470
      ( r'\bL__',                       'L__%s__' % self.basename,      ),
471
      ( r'\bi__',                       'i_%s_' % self.basename,        ),
472
      ( r'\bo__',                       'o_%s_' % self.basename,        ),
473
      ( r'\bs__',                       's__%s__' % self.basename,      ),
474 10 sinclairrf
      ( r'@S__CLK_EN@',                 's__%s__clk_en' % masterBasename, ),
475
      ( r'@S__INPUT_CONTROL_WORD_PACKED@', 's__%s__input_control_word_packed' % masterBasename, ),
476 9 sinclairrf
    ):
477
      body = re.sub(subpair[0],subpair[1],body)
478
    body = self.GenVerilogFinal(config,body)
479
    fp.write(body)

powered by: WebSVN 2.1.0

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