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

Subversion Repositories ssbcc

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

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

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

powered by: WebSVN 2.1.0

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