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

Subversion Repositories ssbcc

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

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

Line No. Rev Author Line
1 2 sinclairrf
################################################################################
2
#
3 9 sinclairrf
# Copyright 2013-2015, Sinclair R.F., Inc.
4 2 sinclairrf
#
5
################################################################################
6
 
7
import math;
8
import re;
9
 
10
from ssbccPeripheral import SSBCCperipheral
11 9 sinclairrf
from ssbccUtil import CeilLog2
12
from ssbccUtil import SSBCCException
13 2 sinclairrf
 
14
class UART_Rx(SSBCCperipheral):
15
  """
16
  Receive UART:
17
    1 start bit
18
    8 data bits
19
    1 or 2 stop bits\n
20
  Usage:
21
    PERIPHERAL UART_Rx inport=I_inport_name        \\
22
                       inempty=I_inempty_name      \\
23
                       baudmethod={clk/rate|count} \\
24
                       [insignal=i_name]           \\
25
                       [noSync|sync=n]             \\
26
                       [noDeglitch|deglitch=n]     \\
27
                       [noInFIFO|inFIFO=n]         \\
28 9 sinclairrf
                       [{RTR|RTRn}=o_rtr_name]     \\
29
                       rtr_buffer=n                \\
30 2 sinclairrf
                       [nStop={1|2}]               \n
31
  Where:
32
    inport=I_inport_name
33
      specifies the symbol used by the inport instruction to read a received by
34
      from the peripheral
35
      Note:  The name must start with "I_".
36
    inempty=I_inempty_name
37
      specifies the symbol used by the inport instruction to get the empty
38
      status of the input side of the peripheral
39
      Note:  The name must start with "I_".
40
    baudmethod
41
      specifies the method to generate the desired bit rate:
42
      1st method:  clk/rate
43
        clk is the frequency of "i_clk" in Hz
44
          a number will be interpreted as the clock frequency in Hz
45 9 sinclairrf
          a symbol will be interpreted as a constant or a parameter
46
            Note:  the symbol must be declared with the CONSTANT, LOCALPARARM,
47
                   or PARAMETER configuration command.
48 2 sinclairrf
        rate is the desired baud rate
49
          this is specified as per "clk"
50
      2nd method:
51
        specify the number of "i_clk" clock cycles between bit edges
52
      Note:  clk, rate, and count can be parameters or constants.  For example,
53
             the following uses the parameter G_CLK_FREQ_HZ for the clock
54
             frequency and a hard-wired baud rate of 9600:
55
             "baudmethod=G_CLK_FREQ_HZ/9600".
56
      Note:  The numeric values can have Verilog-style '_' separators between
57 9 sinclairrf
             the digits.  For example, 100_000_000 represents 100 million.
58 2 sinclairrf
    insignal=i_name
59
      optionally specifies the name of the single-bit transmit signal
60
      Default:  i_UART_Rx
61
    noSync
62
      optionally state no synchronization or registration is performed on the
63
      input signal.
64
    sync=n
65
      optionally state that an n-bit synchronizer will be performed on the
66
      input signal.
67
      Note:  sync=3 is the default.
68
    noDeglitch
69
      optionally state that no deglitching is performed on the input signal.
70
      Note:  This is the default.
71
    deglitching=n
72
      optionally state that an n-bit deglitcher is performed on the input signal
73
      Note:  Deglitching consists of changing the output state when n
74
             successive input bits are in the opposite state.
75
    noInFIFO
76
      optionally state that the peripheral will not have an input FIFO
77
      Note:  This is the default.
78
    inFIFO=n
79
      optionally add a FIFO of depth n to the input side of the UART
80
      Note:  n must be a power of 2.
81 9 sinclairrf
    RTR=o_rtr_name or RTRn=o_rtr_name
82 6 sinclairrf
      optionally specify an output handshake signal to indicate that the
83
      peripheral is ready to receive data
84
      Note:  If RTR is specified then the receiver indicates it is ready when
85 9 sinclairrf
             o_rtr_name is high.  If RTRn is specified then the transmitter
86
             indicates it is ready when o_rtr_name is low.
87 6 sinclairrf
      Note:  The default, i.e., neither CTS nor CTSn is specified, is to always
88
             enable the receiver.
89
      Note:  If there is no FIFO and the RTR/RTRn handshake indicates that the
90
             receiver is not ready as soon as it starts receiving data and
91
             until that data is read from the peripheral.
92 9 sinclairrf
      Default:  1
93
    rtr_buffer=n
94
      optionally specify the number of entries in inFIFO to reserve for data
95
      received after the RTR/RTRn signal indicates to stop data flow.
96
      Note:  n must be a power of 2.
97
      Note:  This requires that inFIFO be specified.
98
      Note:  Some USB UARTs  will transmit several characters after the RTR/RTRn
99
             signal indicates to stop the data flow.
100 2 sinclairrf
    nStop=n
101
      optionally configure the peripheral for n stop bits
102
      default:  1 stop bit
103
      Note:  n must be 1 or 2
104
      Note:  the peripheral does not accept 1.5 stop bits
105
  The following ports are provided by this peripheral:
106
    I_inport_name
107
      input a recieved byte from the peripheral
108
      Note:  If there is no input FIFO, then this is the last received byte.
109
             If there is an input FIFO, then this is the next byte in the FIFO.
110
      Note:  If there is an input FIFO and the read would cause a FIFO
111
             underflow, this will repeat the last received byte.
112
    I_inempty_name
113
      input the empty status of the input side of the peripheral
114
      bit 0:  input empty
115
        this bit will be high when the input side of the peripheral has one or
116
        more bytes read to be read
117
        Note:  If there is no FIFO this means that a single byte is ready to be
118
               read and has not been read.  If there is an input FIFO this
119
               means that there are one or more bytes in the FIFO.
120
        Note:  "Empty" is used rather than "ready" to facilitate loops that
121
               respond when there is a new byte ready to be processed.  See the
122
               examples below.
123
  """
124
 
125
  def __init__(self,peripheralFile,config,param_list,loc):
126
    # Use the externally provided file name for the peripheral
127
    self.peripheralFile = peripheralFile;
128
    # Get the parameters.
129 6 sinclairrf
    allowables = (
130
      ( 'RTR',          r'o_\w+$',      None,   ),
131
      ( 'RTRn',         r'o_\w+$',      None,   ),
132
      ( 'baudmethod',   r'\S+$',        lambda v : self.RateMethod(config,v), ),
133
      ( 'deglitch',     r'[1-9]\d*$',   int,    ),
134 9 sinclairrf
      ( 'inFIFO',       r'[1-9]\d*$',   lambda v : self.IntPow2Method(config,v), ),
135 6 sinclairrf
      ( 'inempty',      r'I_\w+$',      None,   ),
136
      ( 'inport',       r'I_\w+$',      None,   ),
137
      ( 'insignal',     r'i_\w+$',      None,   ),
138
      ( 'noDeglitch',   None,           None,   ),
139
      ( 'noInFIFO',     None,           None,   ),
140
      ( 'noSync',       None,           None,   ),
141
      ( 'nStop',        r'[12]$',       int,    ),
142 9 sinclairrf
      ( 'rtr_buffer',   r'[1-9]\d*$',   lambda v : self.IntPow2Method(config,v), ),
143 6 sinclairrf
      ( 'sync',         r'[1-9]\d*$',   int,    ),
144
    );
145
    names = [a[0] for a in allowables];
146 2 sinclairrf
    for param_tuple in param_list:
147
      param = param_tuple[0];
148 6 sinclairrf
      if param not in names:
149
        raise SSBCCException('Unrecognized parameter "%s" at %s' % (param,loc,));
150
      param_test = allowables[names.index(param)];
151
      self.AddAttr(config,param,param_tuple[1],param_test[1],loc,param_test[2]);
152 2 sinclairrf
    # Ensure the required parameters are provided.
153
    for paramname in (
154
        'baudmethod',
155
        'inempty',
156
        'inport',
157
      ):
158
      if not hasattr(self,paramname):
159
        raise SSBCCException('Required parameter "%s" is missing at %s' % (paramname,loc,));
160
    # Set optional parameters.
161
    for optionalpair in (
162 6 sinclairrf
        ( 'insignal',   'i_UART_Rx',    ),
163
        ( 'nStop',      1,              ),
164 2 sinclairrf
      ):
165
      if not hasattr(self,optionalpair[0]):
166
        setattr(self,optionalpair[0],optionalpair[1]);
167 9 sinclairrf
    # Ensure the rtr_buffer, if specified, is consistent with the inFIFO
168
    # specification.
169
    if hasattr(self,'rtr_buffer'):
170
      if not hasattr(self,'inFIFO'):
171
        raise SSBCCException('rtr_buffer specification requires simultaneous inFIFO specification at %s' % loc);
172
      if not self.rtr_buffer < self.inFIFO:
173
        raise SSBCCException('rtr_buffer=%d specification must be less than the inFIFO=%d specification at %s' % (self.rtr_buffer,self.inFIFO,loc,));
174
    else:
175
      self.rtr_buffer = 1;
176 2 sinclairrf
    # Ensure exclusive pair configurations are set and consistent.
177
    for exclusivepair in (
178 6 sinclairrf
        ( 'RTR',        'RTRn',         None,           None,   ),
179
        ( 'noSync',     'sync',         'sync',         3,      ),
180
        ( 'noDeglitch', 'deglitch',     'noDeglitch',   True,   ),
181
        ( 'noInFIFO',   'inFIFO',       'noInFIFO',     True,   ),
182 2 sinclairrf
      ):
183
      if hasattr(self,exclusivepair[0]) and hasattr(self,exclusivepair[1]):
184
        raise SSBCCException('Only one of "%s" and "%s" can be specified at %s' % (exclusivepair[0],exclusivepair[1],loc,));
185 6 sinclairrf
      if not hasattr(self,exclusivepair[0]) and not hasattr(self,exclusivepair[1]) and exclusivepair[2]:
186 2 sinclairrf
        setattr(self,exclusivepair[2],exclusivepair[3]);
187 6 sinclairrf
    # Convert configurations to alternate format.
188
    for equivalent in (
189
        ( 'noDeglitch', 'deglitch',     0,      ),
190
        ( 'noInFIFO',   'inFIFO',       0,      ),
191
        ( 'noSync',     'sync',         0,      ),
192
      ):
193
      if hasattr(self,equivalent[0]):
194
        delattr(self,equivalent[0]);
195
        setattr(self,equivalent[1],equivalent[2]);
196
    # Set the value used to identify signals associated with this peripheral.
197 2 sinclairrf
    self.namestring = self.insignal;
198
    # Add the I/O port, internal signals, and the INPORT and OUTPORT symbols for this peripheral.
199 6 sinclairrf
    for ioEntry in (
200
        ( 'insignal',   1,      'input',        ),
201
        ( 'RTR',        1,      'output',       ),
202
        ( 'RTRn',       1,      'output',       ),
203
      ):
204
      if hasattr(self,ioEntry[0]):
205
        config.AddIO(getattr(self,ioEntry[0]),ioEntry[1],ioEntry[2],loc);
206 2 sinclairrf
    config.AddSignal('s__%s__Rx'          % self.namestring,8,loc);
207
    config.AddSignal('s__%s__Rx_empty'    % self.namestring,1,loc);
208
    config.AddSignal('s__%s__Rx_rd'       % self.namestring,1,loc);
209
    config.AddInport((self.inport,
210
                    ('s__%s__Rx'          % self.namestring,8,'data',),
211
                    ('s__%s__Rx_rd'       % self.namestring,1,'strobe',),
212
                   ),loc);
213
    config.AddInport((self.inempty,
214 6 sinclairrf
                    ('s__%s__Rx_empty'     % self.namestring,1,'data',),
215
                   ),loc);
216 2 sinclairrf
    # Add the 'clog2' function to the processor (if required).
217
    config.functions['clog2'] = True;
218
 
219
  def GenVerilog(self,fp,config):
220
    for bodyextension in ('.v',):
221
      body = self.LoadCore(self.peripheralFile,bodyextension);
222 6 sinclairrf
      if hasattr(self,'RTR') or hasattr(self,'RTRn'):
223
        body = re.sub(r'@RTR_BEGIN@\n','',body);
224
        body = re.sub(r'@RTR_END@\n','',body);
225
      else:
226
        body = re.sub(r'@RTR_BEGIN@.*?@RTR_END@\n','',body,flags=re.DOTALL);
227 2 sinclairrf
      for subpair in (
228 6 sinclairrf
          ( r'@RTR_SIGNAL@',    self.RTR if hasattr(self,'RTR') else self.RTRn if hasattr(self,'RTRn') else '', ),
229 9 sinclairrf
          ( r'@RTRN_INVERT@',           '!' if hasattr(self,'RTR') else '', ),
230
          ( r'\bL__',                   'L__@NAME@__',          ),
231
          ( r'\bgen__',                 'gen__@NAME@__',        ),
232
          ( r'\bs__',                   's__@NAME@__',          ),
233
          ( r'@INPORT@',                self.insignal,          ),
234
          ( r'@BAUDMETHOD@',            str(self.baudmethod),   ),
235
          ( r'@SYNC@',                  str(self.sync),         ),
236
          ( r'@DEGLITCH@',              str(self.deglitch),     ),
237
          ( r'@INFIFO@',                str(self.inFIFO),       ),
238
          ( r'@NSTOP@',                 str(self.nStop),        ),
239
          ( r'@NAME@',                  self.namestring,        ),
240
          ( r'@RTR_FIFO_COMPARE@',      str(CeilLog2(self.rtr_buffer)), ),
241 6 sinclairrf
        ):
242
        if re.search(subpair[0],body):
243
          body = re.sub(subpair[0],subpair[1],body);
244 2 sinclairrf
      body = self.GenVerilogFinal(config,body);
245
      fp.write(body);

powered by: WebSVN 2.1.0

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