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

Subversion Repositories ssbcc

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

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

powered by: WebSVN 2.1.0

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