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

Subversion Repositories ssbcc

[/] [ssbcc/] [trunk/] [core/] [9x8/] [peripherals/] [PWM_8bit.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
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
      specifies the frequency at which the PWM counter is incremented
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
    PERIPHERAL PWM_8bit   outport=O_PWM_LED                     \\
77
                          outsignal=o_led                       \\
78
                          ratemethod=G_CLK_FREQ_HZ/(30*255)     \\
79
                          invert\n
80
    Use the following assembly to set the LED to about 1/4 intensity:\n
81
    0x40 .outport(O_PWM_LED)\n
82
  Example:  Similarly to obove, but for the three controls of a tri-color LED:\n
83
    Within the processor architecture file include the configuration command:\n
84
    PERIPHERAL PWM_8bit   outport=O_PWM_LED                     \\
85
                          outsignal=o_led                       \\
86
                          ratemethod=G_CLK_FREQ_HZ/(30*255)     \\
87
                          invert                                \\
88
                          instances=3\n
89
    Use the following assembly to set the LED intensities to 0x10 0x20 and 0x55:\n
90
    0x10 .outport(O_PWM_LED_0)
91
    0x20 .outport(O_PWM_LED_1)
92
    0x55 .outport(O_PWM_LED_2)\n
93
    or use the following function to send the three values on the stack where
94
    the top of the stack is 0x55 0x20 0x10 (this isn't less code, but it
95
    illustrates how to increment the outport index):\n
96
    ; ( u_pwm_led_2 u_pwm_led_1 u_pwm_led_0 - )
97
    .function set_pwm_led
98
      O_PWM_LED_0 ${3-1} :loop r> swap over outport drop 1+ r> .jumpc(loop,1-) drop
99
    .return(drop)
100
  """
101
 
102
  def __init__(self,peripheralFile,config,param_list,loc):
103
    # Use the externally provided file name for the peripheral
104
    self.peripheralFile = peripheralFile;
105
    # Get the parameters.
106 6 sinclairrf
    allowables = (
107
      ( 'outport',      r'O_\w+$',      None,   ),
108
      ( 'outsignal',    r'o_\w+$',      None,   ),
109
      ( 'ratemethod',   r'\S+$',        lambda v : self.RateMethod(config,v), ),
110
      ( 'invert',       None,           True,   ),
111
      ( 'noinvert',     None,           True,   ),
112
      ( 'instances',    r'[1-9]\d*$',   int,    ),
113
      ( 'norunt',       None,           True,   ),
114
    );
115
    names = [a[0] for a in allowables];
116 2 sinclairrf
    for param_tuple in param_list:
117
      param = param_tuple[0];
118 6 sinclairrf
      if param not in names:
119
        raise SSBCCException('Unrecognized parameter "%s" at %s' % (param,loc,));
120
      param_test = allowables[names.index(param)];
121
      self.AddAttr(config,param,param_tuple[1],param_test[1],loc,param_test[2]);
122 2 sinclairrf
    # Ensure the required parameters are provided.
123 6 sinclairrf
    for paramname in (
124
        'outport',
125
        'outsignal',
126
        'ratemethod',
127
      ):
128
      if not hasattr(self,paramname):
129
        raise SSBCCException('Required parameter "%s" is missing at %s' % (paramname,loc,));
130 2 sinclairrf
    # Set optional parameters.
131 6 sinclairrf
    for optionalpair in (
132
        ( 'instances',  1,      ),
133
        ( 'norunt',     False,  ),
134
      ):
135
      if not hasattr(self,optionalpair[0]):
136
        setattr(self,optionalpair[0],optionalpair[1]);
137
    # Ensure exclusive pair configurations are set and consistent.
138
    for exclusivepair in (
139
        ( 'invert',     'noinvert',     'noinvert',     True,   ),
140
      ):
141
      if hasattr(self,exclusivepair[0]) and hasattr(self,exclusivepair[1]):
142
        raise SSBCCException('Only one of "%s" and "%s" can be specified at %s' % (exclusivepair[0],exclusivepair[1],loc,));
143
      if not hasattr(self,exclusivepair[0]) and not hasattr(self,exclusivepair[1]) and exclusivepair[2]:
144
        setattr(self,exclusivepair[2],exclusivepair[3]);
145 2 sinclairrf
    # Add the I/O port, internal signals, and the INPORT and OUTPORT symbols for this peripheral.
146
    config.AddIO(self.outsignal,self.instances,'output',loc);
147
    self.ix_outport_0 = config.NOutports();
148
    if self.instances == 1:
149
      tmpOutport = self.outport;
150
      config.AddOutport((tmpOutport,False,),loc);
151
    else:
152
      for ixOutPort in range(self.instances):
153
        tmpOutport = '%s_%d' % (self.outport,ixOutPort,);
154
        config.AddOutport((tmpOutport,False,),loc);
155
    # Add the 'clog2' function to the processor (if required).
156
    config.functions['clog2'] = True;
157
 
158
  def GenVerilog(self,fp,config):
159
    body = self.LoadCore(self.peripheralFile,'.v');
160
    output_on = "1'b1";
161
    output_off = "1'b0";
162 6 sinclairrf
    if hasattr(self,'invert'):
163 2 sinclairrf
      output_on = "1'b0";
164
      output_off = "1'b1";
165 6 sinclairrf
    for subpair in (
166
        ( r'\bL__',             'L__@NAME@__',          ),
167
        ( r'\bgen__',           'gen__@NAME@__',        ),
168
        ( r'\bs__',             's__@NAME@__',          ),
169
        ( r'\bix\b',            'ix__@NAME@',           ),
170
        ( r'@COUNT@',           self.ratemethod,        ),
171
        ( r'@INSTANCES@',       str(self.instances),    ),
172
        ( r'@IX_OUTPORT_0@',    str(self.ix_outport_0), ),
173
        ( r'@OFF@',             output_off,             ),
174
        ( r'@ON@',              output_on,              ),
175
        ( r'@NAME@',            self.outsignal,         ),
176
        ( r'@NORUNT@',          '1\'b1' if self.norunt else '1\'b0', ),
177
      ):
178
      body = re.sub(subpair[0],subpair[1],body);
179 2 sinclairrf
    body = self.GenVerilogFinal(config,body);
180
    fp.write(body);

powered by: WebSVN 2.1.0

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