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

Subversion Repositories ssbcc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 sinclairrf
################################################################################
2
#
3 9 sinclairrf
# Copyright 2012-2015, Sinclair R.F., Inc.
4 2 sinclairrf
#
5
################################################################################
6
 
7
import math;
8
import re;
9
 
10
from ssbccPeripheral import SSBCCperipheral
11 6 sinclairrf
from ssbccUtil import IsPowerOf2;
12 2 sinclairrf
from ssbccUtil import SSBCCException;
13
 
14
class UART_Tx(SSBCCperipheral):
15
  """
16
  Transmit side of a UART:
17
    1 start bit
18
    8 data bits
19
    1 or 2 stop bits\n
20
  Usage:
21
    PERIPHERAL UART_Tx outport=O_outport_name      \\
22
                       outstatus=I_outstatus_name  \\
23
                       baudmethod={clk/rate|count} \\
24
                       [outsignal=o_name]          \\
25
                       [noOutFIFO|outFIFO=n]       \\
26 6 sinclairrf
                       [{CTS|CTSn}=i_cts_name]     \\
27 2 sinclairrf
                       [nStop={1|2}]\n
28
  Where:
29
    outport=O_outport_name
30
      specifies the symbol used by the outport instruction to write a byte to
31
      the peripheral
32
      Note:  The name must start with "O_".
33
    outstatus=I_outstatus_name
34
      specifies the symbol used by the inport instruction to get the status of
35
      the output 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 9 sinclairrf
          a symbol will be interpreted as a constant or a parameter
43
            Note:  the symbol must be declared with the CONSTANT, LOCALPARARM,
44
                   or PARAMETER configuration command.
45 2 sinclairrf
        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
    outsignal=o_name
56
      optionally specifies the name of the output signal
57
      Default:  o_UART_Tx
58
    noOutFIFO
59
      optionally state that the peripheral will not have an output FIFO
60
      Note:  This is the default.
61
    outFIFO=n
62
      optionally add a FIFO of depth n to the output side of the UART
63
      Note:  n must be a power of 2.
64 6 sinclairrf
    CTS=i_cts_name or CTSn=i_cts_name
65
      optionally specify an input handshake signal to control whether or not the
66
      peripheral transmits data
67
      Note:  If CTS is specified then the transmitter is active when i_cts_name
68
             is high.  If CTSn is specified then the transmitter is active when
69
             i_cts_name is low.
70
      Note:  The default, i.e., neither CTS nor CTSn is specified, is to always
71
             enable the transmitter.
72
      Note:  If there is no FIFO and the CTS/CTSn handshake indicates that the
73
             data flow is disabled, then the busy signal will be high and the
74
             processor code must not transmit the next byte.
75 2 sinclairrf
    nStop=n
76
      optionally configure the peripheral for n stop bits
77
      default:  1 stop bit
78
      Note:  n must be 1 or 2
79
      Note:  the peripheral does not accept 1.5 stop bits\n
80
  The following ports are provided by this peripheral:
81
    O_outport_name
82
      output the next 8-bit value to transmit or to queue for transmission
83
      Note:  If there is no output FIFO or if there is an output FIFO and this
84
             write would cause a FIFO overflow, then this byte will be
85
             discarded.
86
    I_outstatus_name
87
      input the status of the output side of the peripheral
88
      bit 0:  output busy
89
        this bit will be high when the output side of the peripheral cannot
90
        accept more writes
91
        Note:  If there is no FIFO this means that the peripheral is still
92
               transmitting the last byte.  If there is an output FIFO it means
93
               that it is full.\n
94
        Note:  "Busy" is used rather that "ready" to facilitate loops that wait
95
               for a not-busy status to send the next byte.  See the examples below.\n
96
  WARNING:  The peripheral is very simple and does not protect against writing a
97
            new value in the middle of a transmition or writing to a full FIFO.
98
            Adding such logic would be contrary to the design principle of
99
            keeping the HDL small and relying on the assembly code to provide
100
            the protection.\n
101
  Example:  Configure the UART for 115200 baud using a 100 MHz clock and
102
            transmit the message "Hello World!"\n
103
    Within the processor architecture file include the configuration command:\n
104
    PERIPHERAL UART_Tx O_UART_TX I_UART_TX baudmethod=100_000_000/115200\n
105
    Use the following assembly code to transmit the message "Hello World!".
106
    This transmits the entire message whether or not the peripheral has a FIFO.\n
107
    N"Hello World!\\r\\n"
108 12 sinclairrf
      :loop .outport(O_UART_TX) :wait .inport(I_UART_TX_BUSY) .jumpc(wait) .jumpc(loop,nop) drop\n
109
  Interrupt handler:  "!s__<outsignal>__TX_uart_busy" is is suitable input to
110
  an interrupt handler where "<outsignal>" is the name assigned to "outsignal".
111
  This signal is low when the peripheral is not transmitting data and there is
112
  no output FIFO and can be used as an indication that the peripheral is ready
113
  for a new byte to transmit.
114 2 sinclairrf
  """
115
 
116
  def __init__(self,peripheralFile,config,param_list,loc):
117
    # Use the externally provided file name for the peripheral
118
    self.peripheralFile = peripheralFile;
119
    # Get the parameters.
120 6 sinclairrf
    allowables = (
121
      ( 'CTS',          r'i_\w+$',              None,           ),
122
      ( 'CTSn',         r'i_\w+$',              None,           ),
123
      ( 'baudmethod',   r'\S+$',                lambda v : self.RateMethod(config,v), ),
124
      ( 'noOutFIFO',    None,                   None,           ),
125
      ( 'nStop',        r'[12]$',               int,            ),
126 9 sinclairrf
      ( 'outFIFO',      r'[1-9]\d*$',           lambda v : self.IntPow2Method(config,v), ),
127 6 sinclairrf
      ( 'outport',      r'O_\w+$',              None,           ),
128
      ( 'outsignal',    r'o_\w+$',              None,           ),
129
      ( 'outstatus',    r'I_\w+$',              None,           ),
130
    );
131
    names = [a[0] for a in allowables];
132 2 sinclairrf
    for param_tuple in param_list:
133
      param = param_tuple[0];
134 6 sinclairrf
      if param not in names:
135
        raise SSBCCException('Unrecognized parameter "%s" at %s' % (param,loc,));
136
      param_test = allowables[names.index(param)];
137
      self.AddAttr(config,param,param_tuple[1],param_test[1],loc,param_test[2]);
138 2 sinclairrf
    # Ensure the required parameters are provided.
139
    for paramname in (
140
        'baudmethod',
141
        'outport',
142
        'outstatus',
143
      ):
144
      if not hasattr(self,paramname):
145
        raise SSBCCException('Required parameter "%s" is missing at %s' % (paramname,loc,));
146
    # Set optional parameters.
147
    for optionalpair in (
148 6 sinclairrf
        ( 'nStop',      1,              ),
149
        ( 'outsignal',  'o_UART_Tx',    ),
150 2 sinclairrf
      ):
151
      if not hasattr(self,optionalpair[0]):
152
        setattr(self,optionalpair[0],optionalpair[1]);
153
    # Ensure exclusive pair configurations are set and consistent.
154
    for exclusivepair in (
155 6 sinclairrf
        ( 'CTS',        'CTSn',         None,           None,   ),
156
        ( 'noOutFIFO',  'outFIFO',      'noOutFIFO',    True,   ),
157 2 sinclairrf
      ):
158
      if hasattr(self,exclusivepair[0]) and hasattr(self,exclusivepair[1]):
159
        raise SSBCCException('Only one of "%s" and "%s" can be specified at %s' % (exclusivepair[0],exclusivepair[1],loc,));
160 6 sinclairrf
      if not hasattr(self,exclusivepair[0]) and not hasattr(self,exclusivepair[1]) and exclusivepair[2]:
161 2 sinclairrf
        setattr(self,exclusivepair[2],exclusivepair[3]);
162 6 sinclairrf
    # Convert configurations to alternative format.
163
    for equivalent in (
164
        ( 'noOutFIFO',  'outFIFO',      0,      ),
165
      ):
166
      if hasattr(self,equivalent[0]):
167
        delattr(self,equivalent[0]);
168
        setattr(self,equivalent[1],equivalent[2]);
169 2 sinclairrf
    # Set the string used to identify signals associated with this peripheral.
170
    self.namestring = self.outsignal;
171
    # Add the I/O port, internal signals, and the INPORT and OUTPORT symbols for this peripheral.
172 6 sinclairrf
    for ioEntry in (
173
        ( 'outsignal',  1,      'output',       ),
174
        ( 'CTS',        1,      'input',        ),
175
        ( 'CTSn',       1,      'input',        ),
176
      ):
177
      if hasattr(self,ioEntry[0]):
178
        config.AddIO(getattr(self,ioEntry[0]),ioEntry[1],ioEntry[2],loc);
179 9 sinclairrf
    config.AddSignalWithInit('s__%s__Tx'        % self.namestring,8,None,loc);
180
    config.AddSignal('s__%s__Tx_busy'           % self.namestring,1,loc);
181
    config.AddSignalWithInit('s__%s__Tx_wr'     % self.namestring,1,None,loc);
182 2 sinclairrf
    config.AddOutport((self.outport,False,
183 6 sinclairrf
                    ('s__%s__Tx'           % self.namestring,8,'data',),
184
                    ('s__%s__Tx_wr'        % self.namestring,1,'strobe',),
185
                   ),loc);
186 2 sinclairrf
    config.AddInport((self.outstatus,
187 6 sinclairrf
                    ('s__%s__Tx_busy'      % self.namestring,1,'data',),
188
                   ),loc);
189 2 sinclairrf
    # Add the 'clog2' function to the processor (if required).
190
    config.functions['clog2'] = True;
191
 
192
  def GenVerilog(self,fp,config):
193
    for bodyextension in ('.v',):
194
      body = self.LoadCore(self.peripheralFile,bodyextension);
195
      for subpair in (
196 9 sinclairrf
          ( r'\bL__',                   'L__@NAME@__',          ),
197
          ( r'\bgen__',                 'gen__@NAME@__',        ),
198
          ( r'\bs__',                   's__@NAME@__',          ),
199
          ( r'@BAUDMETHOD@',            str(self.baudmethod),   ),
200
          ( r'@ENABLED@',               self.CTS if hasattr(self,'CTS') else ('!%s' % self.CTSn) if hasattr(self,'CTSn') else '1\'b1', ),
201
          ( r'@NSTOP@',                 str(self.nStop),        ),
202
          ( r'@OUTFIFO@',               str(self.outFIFO),      ),
203
          ( r'@NAME@',                  self.namestring,        ),
204 6 sinclairrf
        ):
205 2 sinclairrf
        body = re.sub(subpair[0],subpair[1],body);
206
      body = self.GenVerilogFinal(config,body);
207
      fp.write(body);

powered by: WebSVN 2.1.0

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