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

Subversion Repositories ssbcc

[/] [ssbcc/] [trunk/] [core/] [9x8/] [peripherals/] [UART_Tx.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 2012-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_Tx(SSBCCperipheral):
14
  """
15
  Transmit side of a UART:
16
    1 start bit
17
    8 data bits
18
    1 or 2 stop bits\n
19
  Usage:
20
    PERIPHERAL UART_Tx outport=O_outport_name      \\
21
                       outstatus=I_outstatus_name  \\
22
                       baudmethod={clk/rate|count} \\
23
                       [outsignal=o_name]          \\
24
                       [noOutFIFO|outFIFO=n]       \\
25
                       [nStop={1|2}]\n
26
  Where:
27
    outport=O_outport_name
28
      specifies the symbol used by the outport instruction to write a byte to
29
      the peripheral
30
      Note:  The name must start with "O_".
31
    outstatus=I_outstatus_name
32
      specifies the symbol used by the inport instruction to get the status of
33
      the output side of the peripheral
34
      Note:  The name must start with "I_".
35
    baudmethod
36
      specifies the method to generate the desired bit rate:
37
      1st method:  clk/rate
38
        clk is the frequency of "i_clk" in Hz
39
          a number will be interpreted as the clock frequency in Hz
40
          a symbol will be interpreted as a parameter
41
            Note:  this parameter must have been declared with a "PARAMETER"
42
            command
43
        rate is the desired baud rate
44
          this is specified as per "clk"
45
      2nd method:
46
        specify the number of "i_clk" clock cycles between bit edges
47
      Note:  clk, rate, and count can be parameters or constants.  For example,
48
             the following uses the parameter G_CLK_FREQ_HZ for the clock
49
             frequency and a hard-wired baud rate of 9600:
50
             "baudmethod=G_CLK_FREQ_HZ/9600".
51
      Note:  The numeric values can have Verilog-style '_' separators between
52
             the digits.  For example, 100_000_000 represents 100 million.
53
    outsignal=o_name
54
      optionally specifies the name of the output signal
55
      Default:  o_UART_Tx
56
    noOutFIFO
57
      optionally state that the peripheral will not have an output FIFO
58
      Note:  This is the default.
59
    outFIFO=n
60
      optionally add a FIFO of depth n to the output side of the UART
61
      Note:  n must be a power of 2.
62
    nStop=n
63
      optionally configure the peripheral for n stop bits
64
      default:  1 stop bit
65
      Note:  n must be 1 or 2
66
      Note:  the peripheral does not accept 1.5 stop bits\n
67
  The following ports are provided by this peripheral:
68
    O_outport_name
69
      output the next 8-bit value to transmit or to queue for transmission
70
      Note:  If there is no output FIFO or if there is an output FIFO and this
71
             write would cause a FIFO overflow, then this byte will be
72
             discarded.
73
    I_outstatus_name
74
      input the status of the output side of the peripheral
75
      bit 0:  output busy
76
        this bit will be high when the output side of the peripheral cannot
77
        accept more writes
78
        Note:  If there is no FIFO this means that the peripheral is still
79
               transmitting the last byte.  If there is an output FIFO it means
80
               that it is full.\n
81
        Note:  "Busy" is used rather that "ready" to facilitate loops that wait
82
               for a not-busy status to send the next byte.  See the examples below.\n
83
  WARNING:  The peripheral is very simple and does not protect against writing a
84
            new value in the middle of a transmition or writing to a full FIFO.
85
            Adding such logic would be contrary to the design principle of
86
            keeping the HDL small and relying on the assembly code to provide
87
            the protection.\n
88
  Example:  Configure the UART for 115200 baud using a 100 MHz clock and
89
            transmit the message "Hello World!"\n
90
    Within the processor architecture file include the configuration command:\n
91
    PERIPHERAL UART_Tx O_UART_TX I_UART_TX baudmethod=100_000_000/115200\n
92
    Use the following assembly code to transmit the message "Hello World!".
93
    This transmits the entire message whether or not the peripheral has a FIFO.\n
94
    N"Hello World!\\r\\n"
95
      :loop .outport(O_UART_TX) :wait .inport(I_UART_TX_BUSY) .jumpc(wait) .jumpc(loop,nop) drop
96
  """
97
 
98
  def __init__(self,peripheralFile,config,param_list,loc):
99
    # Use the externally provided file name for the peripheral
100
    self.peripheralFile = peripheralFile;
101
    # Get the parameters.
102
    for param_tuple in param_list:
103
      param = param_tuple[0];
104
      param_arg = param_tuple[1];
105
      for param_test in (
106
          ('noOutFIFO',  None,         None,  ),
107
          ('nStop',      r'[12]$',     int,   ),
108
          ('outport',    r'O_\w+$',    None,  ),
109
          ('outsignal',  r'o_\w+$',    None,  ),
110
          ('outstatus',  r'I_\w+$',    None,  ),
111
        ):
112
        if param == param_test[0]:
113
          self.AddAttr(config,param,param_arg,param_test[1],loc,param_test[2]);
114
          break;
115
      else:
116
        if param == 'baudmethod':
117
          self.AddRateMethod(config,param,param_arg,loc);
118
        elif param in ('outFIFO',):
119
          self.AddAttr(config,param,param_arg,r'[1-9]\d*$',loc,int);
120
          x = getattr(self,param);
121
          if math.modf(math.log(x,2))[0] != 0:
122
            raise SSBCCException('%s=%d must be a power of 2 at %s' % (param,x,loc,));
123
        else:
124
          raise SSBCCException('Unrecognized parameter at %s: %s' % (loc,param,));
125
    # Ensure the required parameters are provided.
126
    for paramname in (
127
        'baudmethod',
128
        'outport',
129
        'outstatus',
130
      ):
131
      if not hasattr(self,paramname):
132
        raise SSBCCException('Required parameter "%s" is missing at %s' % (paramname,loc,));
133
    # Set optional parameters.
134
    for optionalpair in (
135
        ('nStop',     1,           ),
136
        ('outsignal', 'o_UART_Tx', ),
137
      ):
138
      if not hasattr(self,optionalpair[0]):
139
        setattr(self,optionalpair[0],optionalpair[1]);
140
    # Ensure exclusive pair configurations are set and consistent.
141
    for exclusivepair in (
142
        ('noOutFIFO',  'outFIFO',  'noOutFIFO',  True, ),
143
      ):
144
      if hasattr(self,exclusivepair[0]) and hasattr(self,exclusivepair[1]):
145
        raise SSBCCException('Only one of "%s" and "%s" can be specified at %s' % (exclusivepair[0],exclusivepair[1],loc,));
146
      if not hasattr(self,exclusivepair[0]) and not hasattr(self,exclusivepair[1]):
147
        setattr(self,exclusivepair[2],exclusivepair[3]);
148
      if hasattr(self,exclusivepair[0]):
149
        delattr(self,exclusivepair[0]);
150
        setattr(self,exclusivepair[1],0);
151
    # Set the string used to identify signals associated with this peripheral.
152
    self.namestring = self.outsignal;
153
    # Add the I/O port, internal signals, and the INPORT and OUTPORT symbols for this peripheral.
154
    config.AddIO(self.outsignal,1,'output',loc);
155
    config.AddSignal('s__%s__Tx'          % self.namestring,8,loc);
156
    config.AddSignal('s__%s__Tx_busy'     % self.namestring,1,loc);
157
    config.AddSignal('s__%s__Tx_wr'       % self.namestring,1,loc);
158
    config.AddOutport((self.outport,False,
159
                   ('s__%s__Tx'           % self.namestring,8,'data',),
160
                   ('s__%s__Tx_wr'        % self.namestring,1,'strobe',),
161
                  ),loc);
162
    config.AddInport((self.outstatus,
163
                   ('s__%s__Tx_busy'      % self.namestring,1,'data',),
164
                 ),loc);
165
    # Add the 'clog2' function to the processor (if required).
166
    config.functions['clog2'] = True;
167
 
168
  def GenVerilog(self,fp,config):
169
    for bodyextension in ('.v',):
170
      body = self.LoadCore(self.peripheralFile,bodyextension);
171
      for subpair in (
172
                    (r'\bL__',          'L__@NAME@__', ),
173
                    (r'\bgen__',        'gen__@NAME@__', ),
174
                    (r'\bs__',          's__@NAME@__', ),
175
                    (r'@BAUDMETHOD@',   str(self.baudmethod), ),
176
                    (r'@NSTOP@',        str(self.nStop), ),
177
                    (r'@OUTFIFO@',      str(self.outFIFO), ),
178
                    (r'@NAME@',         self.namestring, ),
179
                  ):
180
        body = re.sub(subpair[0],subpair[1],body);
181
      body = self.GenVerilogFinal(config,body);
182
      fp.write(body);

powered by: WebSVN 2.1.0

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