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

Subversion Repositories ssbcc

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

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
from ssbccPeripheral import SSBCCperipheral
8
from ssbccUtil import SSBCCException;
9
 
10
class PWM_8bit(SSBCCperipheral):
11
  """
12
  Pulse Width Modulator (PWM) with 8-bit control.\n
13
  This peripheral creates one or more PWMs.  The PWM is designed so that it is
14
  allways off when the control is 0 and it is always on when the control is
15
  0xFF.\n
16
  Usage:
17
    PERIPHERAL PWM_8bit   outport=O_name \\
18
                          outsignal=o_name \\
19
                          ratemethod={clk/rate|count} \\
20
                          [invert|noinvert] \\
21
                          [instances=n] \\
22
                          [norunt]\n
23
  Where:
24
    outport=O_name
25
      specifies the symbol used by the outport instruction to write a byte to
26
      the peripheral
27
      Note:  The name must start with "O_".
28
    outsignal=o_name
29
      specifies the name of the output signal
30
      Note:  The name must start with "o_".
31
    ratemethod={clk/rate|count}
32 13 sinclairrf
      specifies the number of clock cycles per PWM count increment
33 9 sinclairrf
      Note:  "clk," "rate," and "count" can be integers or can be declared by
34
             CONSTANT, LOCALPARARM, or PARAMETER configuration commands.
35 2 sinclairrf
      Example:  ratemethod=count means to increment the PWM counter once every
36
                "count" clock cycles.
37 9 sinclairrf
      Example:  ratemethod=G_CLK_HZ/1_000 means to use the parameter G_CLK_HZ
38
                (set elsewhere) and a 1,000 Hz update rate to determine the
39
                number of clock cycles between updates.
40 2 sinclairrf
    invert|noinvert
41
      optional configuration command to invert or to not invert the PWM output
42
      Default:  don't invert the output (i.e., a command of 0 means the output is
43
                always low)
44
      Note:  "invert" should be used when pulling the external signal to ground
45
             means the device is "on"
46
    instances=n
47
      specifies the number of PWMs for the peripheral
48
      Default:  The default is one PWM control and output.
49
    norunt
50
      optionally add logic to ensure "runt" pulses are not generated by
51
      incorporating new PWM commands at the start of the counting cycle
52
      Default:  "runt" pulses are allowed.\n
53
  The following OUTPORT is provided by this peripheral when instances=1:
54
    O_name
55
      output the next 8-bit value to transmit or to queue for transmission\n
56
  The following OUTPORT is provided by this peripheral when instances=n is larger
57
  than 1:
58
    O_name_0, O_name_1, ..., O_name_{n-1}
59
      output the next 8-bit value to transmit on the specified PWM
60
      Note:  O_name_i = ${O_name_0+i) where 0<=i<n.
61
      Note:  The PWM for o_name[i] is controlled by the outport O_name_i
62
      Example:  If "instances=3" is specified, then the following outports are
63
                provided:  O_name_0, O_name_1, and O_name_2.  The assembly
64
                sequence "5 .outport(O_name_1)" will change the PWM control for
65
                the second of these three PWMs to 5.\n
66
  Note:  The PWM counter is an 8-bit count that ranges from 1 to 255.  Each PWM
67
         output is '1' when this count is less than or equal to the commanded
68
         count.  The signal for a commanded count of 0 will never be on while
69
         the signal for a commanded count of 255 will always be on.\n
70
  Example:  Control the intensity of an LED through a PWM.  The LED must flicker
71
            at a frequency greater than about 30 Hz in order for the flickering
72
            to not be visible by human eyes.  The LED is turned on when the
73
            signal to the LED is at ground.  The processor clock frequency is
74
            provided by the parameter G_CLK_FREQ_HZ.\n
75
    Within the processor architecture file include the configuration command:\n
76 13 sinclairrf
    CONSTANT   C_PWM_LED_HZ 30*255
77 2 sinclairrf
    PERIPHERAL PWM_8bit   outport=O_PWM_LED                     \\
78
                          outsignal=o_led                       \\
79 13 sinclairrf
                          ratemethod=G_CLK_FREQ_HZ/C_PWM_LED_HZ \\
80 2 sinclairrf
                          invert\n
81
    Use the following assembly to set the LED to about 1/4 intensity:\n
82
    0x40 .outport(O_PWM_LED)\n
83
  Example:  Similarly to obove, but for the three controls of a tri-color LED:\n
84
    Within the processor architecture file include the configuration command:\n
85 13 sinclairrf
    CONSTANT   C_PWM_LED_HZ 30*255
86 2 sinclairrf
    PERIPHERAL PWM_8bit   outport=O_PWM_LED                     \\
87
                          outsignal=o_led                       \\
88 13 sinclairrf
                          ratemethod=G_CLK_FREQ_HZ/C_PWM_LED_HZ \\
89 2 sinclairrf
                          invert                                \\
90
                          instances=3\n
91
    Use the following assembly to set the LED intensities to 0x10 0x20 and 0x55:\n
92
    0x10 .outport(O_PWM_LED_0)
93
    0x20 .outport(O_PWM_LED_1)
94
    0x55 .outport(O_PWM_LED_2)\n
95
    or use the following function to send the three values on the stack where
96
    the top of the stack is 0x55 0x20 0x10 (this isn't less code, but it
97
    illustrates how to increment the outport index):\n
98
    ; ( u_pwm_led_2 u_pwm_led_1 u_pwm_led_0 - )
99
    .function set_pwm_led
100
      O_PWM_LED_0 ${3-1} :loop r> swap over outport drop 1+ r> .jumpc(loop,1-) drop
101
    .return(drop)
102
  """
103
 
104
  def __init__(self,peripheralFile,config,param_list,loc):
105
    # Use the externally provided file name for the peripheral
106
    self.peripheralFile = peripheralFile;
107
    # Get the parameters.
108 6 sinclairrf
    allowables = (
109
      ( 'outport',      r'O_\w+$',      None,   ),
110
      ( 'outsignal',    r'o_\w+$',      None,   ),
111
      ( 'ratemethod',   r'\S+$',        lambda v : self.RateMethod(config,v), ),
112
      ( 'invert',       None,           True,   ),
113
      ( 'noinvert',     None,           True,   ),
114
      ( 'instances',    r'[1-9]\d*$',   int,    ),
115
      ( 'norunt',       None,           True,   ),
116
    );
117
    names = [a[0] for a in allowables];
118 2 sinclairrf
    for param_tuple in param_list:
119
      param = param_tuple[0];
120 6 sinclairrf
      if param not in names:
121
        raise SSBCCException('Unrecognized parameter "%s" at %s' % (param,loc,));
122
      param_test = allowables[names.index(param)];
123
      self.AddAttr(config,param,param_tuple[1],param_test[1],loc,param_test[2]);
124 2 sinclairrf
    # Ensure the required parameters are provided.
125 6 sinclairrf
    for paramname in (
126
        'outport',
127
        'outsignal',
128
        'ratemethod',
129
      ):
130
      if not hasattr(self,paramname):
131
        raise SSBCCException('Required parameter "%s" is missing at %s' % (paramname,loc,));
132 2 sinclairrf
    # Set optional parameters.
133 6 sinclairrf
    for optionalpair in (
134
        ( 'instances',  1,      ),
135
        ( 'norunt',     False,  ),
136
      ):
137
      if not hasattr(self,optionalpair[0]):
138
        setattr(self,optionalpair[0],optionalpair[1]);
139
    # Ensure exclusive pair configurations are set and consistent.
140
    for exclusivepair in (
141
        ( 'invert',     'noinvert',     'noinvert',     True,   ),
142
      ):
143
      if hasattr(self,exclusivepair[0]) and hasattr(self,exclusivepair[1]):
144
        raise SSBCCException('Only one of "%s" and "%s" can be specified at %s' % (exclusivepair[0],exclusivepair[1],loc,));
145
      if not hasattr(self,exclusivepair[0]) and not hasattr(self,exclusivepair[1]) and exclusivepair[2]:
146
        setattr(self,exclusivepair[2],exclusivepair[3]);
147 2 sinclairrf
    # Add the I/O port, internal signals, and the INPORT and OUTPORT symbols for this peripheral.
148
    config.AddIO(self.outsignal,self.instances,'output',loc);
149
    self.ix_outport_0 = config.NOutports();
150
    if self.instances == 1:
151
      tmpOutport = self.outport;
152
      config.AddOutport((tmpOutport,False,),loc);
153
    else:
154
      for ixOutPort in range(self.instances):
155
        tmpOutport = '%s_%d' % (self.outport,ixOutPort,);
156
        config.AddOutport((tmpOutport,False,),loc);
157
    # Add the 'clog2' function to the processor (if required).
158
    config.functions['clog2'] = True;
159
 
160
  def GenVerilog(self,fp,config):
161
    body = self.LoadCore(self.peripheralFile,'.v');
162
    output_on = "1'b1";
163
    output_off = "1'b0";
164 6 sinclairrf
    if hasattr(self,'invert'):
165 2 sinclairrf
      output_on = "1'b0";
166
      output_off = "1'b1";
167 6 sinclairrf
    for subpair in (
168
        ( r'\bL__',             'L__@NAME@__',          ),
169
        ( r'\bgen__',           'gen__@NAME@__',        ),
170
        ( r'\bs__',             's__@NAME@__',          ),
171
        ( r'\bix\b',            'ix__@NAME@',           ),
172
        ( r'@COUNT@',           self.ratemethod,        ),
173
        ( r'@INSTANCES@',       str(self.instances),    ),
174
        ( r'@IX_OUTPORT_0@',    str(self.ix_outport_0), ),
175
        ( r'@OFF@',             output_off,             ),
176
        ( r'@ON@',              output_on,              ),
177
        ( r'@NAME@',            self.outsignal,         ),
178
        ( r'@NORUNT@',          '1\'b1' if self.norunt else '1\'b0', ),
179
      ):
180
      body = re.sub(subpair[0],subpair[1],body);
181 2 sinclairrf
    body = self.GenVerilogFinal(config,body);
182
    fp.write(body);

powered by: WebSVN 2.1.0

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