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

Subversion Repositories ssbcc

[/] [ssbcc/] [trunk/] [core/] [9x8/] [peripherals/] [AXI4_Lite_Slave_DualPortRAM.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 6 sinclairrf
# Copyright 2013-2014, Sinclair R.F., Inc.
4 2 sinclairrf
#
5
################################################################################
6
 
7
import math
8
import re;
9
 
10
from ssbccPeripheral import SSBCCperipheral
11
from ssbccUtil import SSBCCException;
12
 
13
class AXI4_Lite_Slave_DualPortRAM(SSBCCperipheral):
14
  """
15
  AXI-Lite slave implemented as a dual-port RAM.  The dual-port RAM has at most
16
  256 bytes addressable by a single 8-bit value.  The data is stored in little
17
  endian format (i.e., the LSB of the 32-bit word is stored in the lowest
18
  numbered address).\n
19
  Usage:
20
    PERIPHERAL AXI4_Lite_Slave_DualPortRAM              \\
21
                                basePortName=<name>     \\
22
                                address=<O_address>     \\
23
                                read=<I_read>           \\
24
                                write=<O_write>         \\
25
                                [size=<N>]              \\
26
                                [ram8|ram32]\n
27
  Where:
28
    basePortName=<name>
29
      specifies the name used to construct the multiple AXI4-Lite signals
30
    address=<O_address>
31
      specifies the symbol used to set the address used for read and write
32
      operations from and to the dual-port memory
33
    read=<I_read>
34
      specifies the symbol used to read from the dual-port memory
35
    write=<O_write>
36
      specifies the symbol used to write to the dual-port memory
37
    size=<N>
38
      optionally specify the size of the dual-port memory.
39
      Note:  N must be either a power of 2 in the range from 16 to 256 inclusive
40
             or it must be a local param with the same restrictions on its
41
             value.
42
      Note:  N=256, i.e., the largest memory possible, is the default.
43
      Note:  Using a localparam for the memory size provides a convenient way
44
             to use the size of the dual port RAM in the micro controller code.\n
45
    ram8
46
      optionally specifies using an 8-bit RAM for the dual-port memory instantiation
47
      Note:  This is the default
48
    ram32
49 4 sinclairrf
      optionally specifies using a 32-bit RAM for the dual-port memory instantiation
50 3 sinclairrf
      Note:  This is required for Vivado 2013.3.\n
51
  Vivado Users:
52
    The peripheral creates a TCL script to facilitate turning the micro
53
    controller into an IP core.  Look for a file with the name
54
    "vivado_<basePortName>.tcl".\n
55 2 sinclairrf
  Example:  The code fragments
56
              <addr> .outport(O_address) .inport(I_read)
57
            and
58
              <addr> .outport(O_address) <value> .outport(O_write)
59
            will read from and write to the dual-port RAM.\n
60
  Example:  Function to read the byte at the specified address:
61
              ; ( u_addr - u_value)
62
              .function als_read
63
                .outport(O_address) .inport(I_read) .return
64
            or
65
              ; ( u_addr - u_value)
66
              .function als_read
67
                .outport(O_address) I_read .return(inport)
68
            To invoke the function:
69
              <addr> .call(als_read)
70
            or
71
              .call(als_read,<addr>)\n
72
  Example:  Function to write the byte at the specified address:
73
              ; ( u_value u_addr - )
74
              .function als_write
75
                .outport(O_address) O_write outport .return(drop)
76
            To invoke the function:
77
              <value> <addr> .call(als_write)
78
            or
79
              <value> .call(als_write,<addr>)\n
80
  Example:  Spin on an address, waiting for the host processor to write to the
81
            address, do something when the address is written to, and then
82
            clear its contents.
83
              0x00 .outport(O_address)
84
              :loop .inport(I_read) 0= .jumpc(loop)
85
              ; Avoid race conditions between the processor writes and the micro
86
              ; controller read.
87
              .inport(I_read)
88
              ...
89
              ; clear the value and start waiting again
90
              0x00 O_address outport O_write outport .jump(loop,drop)\n
91
  LEGAL NOTICE:  ARM has restrictions on what kinds of applications can use
92
  interfaces based on their AXI protocol.  Ensure your application is in
93
  compliance with their restrictions before using this peripheral for an AXI
94
  interface.
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
    allowables = (
102 6 sinclairrf
      ( 'address',      r'O_\w+$',      None,           ),
103
      ( 'basePortName', r'\w+$',        None,           ),
104
      ( 'ram8',         None,           None,           ),
105
      ( 'ram32',        None,           None,           ),
106
      ( 'read',         r'I_\w+$',      None,           ),
107 9 sinclairrf
      ( 'size',         r'\S+$',        lambda v : self.IntPow2Method(config,v,lowLimit=16,highLimit=256), ),
108 6 sinclairrf
      ( 'write',        r'O_\w+$',      None,           ),
109 2 sinclairrf
    );
110
    names = [a[0] for a in allowables];
111
    for param_tuple in param_list:
112
      param = param_tuple[0];
113
      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
    # Ensure the required parameters are provided.
118
    for paramname in (
119
      'address',
120
      'basePortName',
121
      'read',
122
      'write',
123
    ):
124
      if not hasattr(self,paramname):
125
        raise SSBCCException('Required parameter "%s" is missing at %s' % (paramname,loc,));
126
    # Set optional parameters.
127
    for optionalpair in (
128
        ('size',        256,    ),
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
        ('ram8','ram32','ram8',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]):
139
        setattr(self,exclusivepair[2],exclusivepair[3]);
140
    # Set the string used to identify signals associated with this peripheral.
141
    self.namestring = self.basePortName;
142
    # Add the I/O port, internal signals, and the INPORT and OUTPORT symbols for this peripheral.
143 3 sinclairrf
    self.address_width = int(math.log(self.size,2));
144 2 sinclairrf
    for signal in (
145 6 sinclairrf
        ( '%s_aresetn',         1,                      'input',        ),
146
        ( '%s_aclk',            1,                      'input',        ),
147
        ( '%s_awvalid',         1,                      'input',        ),
148
        ( '%s_awready',         1,                      'output',       ),
149
        ( '%s_awaddr',          self.address_width,     'input',        ),
150
        ( '%s_wvalid',          1,                      'input',        ),
151
        ( '%s_wready',          1,                      'output',       ),
152
        ( '%s_wdata',           32,                     'input',        ),
153
        ( '%s_wstrb',           4,                      'input',        ),
154
        ( '%s_bresp',           2,                      'output',       ),
155
        ( '%s_bvalid',          1,                      'output',       ),
156
        ( '%s_bready',          1,                      'input',        ),
157
        ( '%s_arvalid',         1,                      'input',        ),
158
        ( '%s_arready',         1,                      'output',       ),
159
        ( '%s_araddr',          self.address_width,     'input',        ),
160
        ( '%s_rvalid',          1,                      'output',       ),
161
        ( '%s_rready',          1,                      'input',        ),
162
        ( '%s_rdata',           32,                     'output',       ),
163
        ( '%s_rresp',           2,                      'output',       ),
164
      ):
165 2 sinclairrf
      thisName = signal[0] % self.basePortName;
166
      config.AddIO(thisName,signal[1],signal[2],loc);
167 3 sinclairrf
    config.AddSignal('s__%s__mc_addr'  % self.namestring, self.address_width, loc);
168 2 sinclairrf
    config.AddSignal('s__%s__mc_rdata' % self.namestring, 8, loc);
169
    config.AddOutport((self.address,False,
170 3 sinclairrf
                      ('s__%s__mc_addr' % self.namestring, self.address_width, 'data', ),
171 2 sinclairrf
                      ),loc);
172
    config.AddInport((self.read,
173
                      ('s__%s__mc_rdata' % self.namestring, 8, 'data', ),
174
                      ),loc);
175
    self.ix_write = config.NOutports();
176
    config.AddOutport((self.write,False,
177
                      # empty list
178
                      ),loc);
179
    # Add the 'clog2' function to the processor (if required).
180
    config.functions['clog2'] = True;
181
 
182
  def GenVerilog(self,fp,config):
183
    body = self.LoadCore(self.peripheralFile,'.v');
184
    for subpair in (
185 6 sinclairrf
        ( r'\bL__',             'L__@NAME@__',                          ),
186
        ( r'\bgen__',           'gen__@NAME@__',                        ),
187
        ( r'\bi_a',             '@NAME@_a',                             ),
188
        ( r'\bi_b',             '@NAME@_b',                             ),
189
        ( r'\bi_r',             '@NAME@_r',                             ),
190
        ( r'\bi_w',             '@NAME@_w',                             ),
191
        ( r'\bix__',            'ix__@NAME@__',                         ),
192
        ( r'\bo_',              '@NAME@_',                              ),
193
        ( r'\bs__',             's__@NAME@__',                          ),
194
        ( r'@IX_WRITE@',        "8'h%02x" % self.ix_write,              ),
195
        ( r'@NAME@',            self.namestring,                        ),
196
        ( r'@SIZE@',            str(self.size),                         ),
197
        ( r'@MEM8@',            '1' if hasattr(self,'mem8') else '0',   ),
198
      ):
199 2 sinclairrf
      body = re.sub(subpair[0],subpair[1],body);
200
    body = self.GenVerilogFinal(config,body);
201
    fp.write(body);

powered by: WebSVN 2.1.0

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