| 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 AXI4_Lite_Master(SSBCCperipheral):
 | 
      
         | 14 |  |  |   """
 | 
      
         | 15 |  |  |   AXI-Lite master for 32-bit reads and 8, 16, and 32-bit writes.\n
 | 
      
         | 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 | 3 | sinclairrf |     PERIPHERAL AXI4_Lite_Master                                         \\
 | 
      
         | 21 |  |  |                                 basePortName=<name>                     \\
 | 
      
         | 22 |  |  |                                 address=<O_address>                     \\
 | 
      
         | 23 |  |  |                                 data=<O_data>                           \\
 | 
      
         | 24 |  |  |                                 command_read=<O_command_read>           \\
 | 
      
         | 25 |  |  |                                 command_write=<O_command_write>         \\
 | 
      
         | 26 |  |  |                                 busy=<I_busy>                           \\
 | 
      
         | 27 |  |  |                                 error=<I_error>                         \\
 | 
      
         | 28 |  |  |                                 read=<I_read>                           \\
 | 
      
         | 29 |  |  |                                 address_width=<N>                       \\
 | 
      
         | 30 |  |  |                                 synchronous={True|False}                \\
 | 
      
         | 31 |  |  |                                 write_enable=<O_write_enable>|noWSTRB\n
 | 
      
         | 32 | 2 | sinclairrf |   Where:
 | 
      
         | 33 |  |  |     basePortName=<name>
 | 
      
         | 34 |  |  |       specifies the name used to construct the multiple AXI4-Lite signals
 | 
      
         | 35 |  |  |     address=<O_address>
 | 
      
         | 36 |  |  |       specifies the symbol used to set the address used for read and write
 | 
      
         | 37 |  |  |       operations from and to the dual-port memory
 | 
      
         | 38 |  |  |       Note:  If the address is 8 bits or less, a single write to this port will
 | 
      
         | 39 |  |  |              set the address.  If the address is 9 bits or longer, then multiple
 | 
      
         | 40 |  |  |              writes to this address, starting with the MSB of the address, are
 | 
      
         | 41 |  |  |              required to set all of the address bits.  See the examples for
 | 
      
         | 42 |  |  |              illustrations of how this works.
 | 
      
         | 43 |  |  |       Note:  The 2 lsb of the address are ignored.  I.e., all addresses will be
 | 
      
         | 44 |  |  |              treated as 32-bit aligned.
 | 
      
         | 45 |  |  |     data=<O_data>
 | 
      
         | 46 |  |  |       specifies the symbol used to set the 32-bit data for write operations
 | 
      
         | 47 |  |  |       Note:  Four outputs to this address are required, starting with the MSB of
 | 
      
         | 48 |  |  |              the 32-bit value,  See the examples for illustrations of how this
 | 
      
         | 49 |  |  |              works.
 | 
      
         | 50 |  |  |     command_read=<O_command_read>
 | 
      
         | 51 |  |  |       specifies the symbol used to start the AXI4-Lite master core to issue a
 | 
      
         | 52 |  |  |       read and store the received data
 | 
      
         | 53 |  |  |     command_write=<O_command_write>
 | 
      
         | 54 |  |  |       specifies the symbol used to start the AXI4-Lite master core to issue a
 | 
      
         | 55 |  |  |       write
 | 
      
         | 56 |  |  |     busy=<I_busy>
 | 
      
         | 57 |  |  |       specifies the symbol used to read the busy/not-busy status of the core
 | 
      
         | 58 |  |  |       Note:  A non-zero value means the core is busy.
 | 
      
         | 59 |  |  |     error=<I_error>
 | 
      
         | 60 |  |  |       specified the symbol used to read the error status of the last write or
 | 
      
         | 61 |  |  |       read transaction on the core
 | 
      
         | 62 |  |  |       Note:  A non-zero value means an error was encountered.  Errors can be
 | 
      
         | 63 |  |  |              reset by resetting the interface or by re-attempting the write or
 | 
      
         | 64 |  |  |              read operation.
 | 
      
         | 65 |  |  |     read=<I_read>
 | 
      
         | 66 |  |  |       specifies the symbol used to read successive bytes of the received 32-bit
 | 
      
         | 67 |  |  |       value starting with the LSB
 | 
      
         | 68 |  |  |     address_width=<N>
 | 
      
         | 69 |  |  |       specifies the width of the 8-bit aligned address\n
 | 
      
         | 70 |  |  |     synchronous={True|False}
 | 
      
         | 71 |  |  |       indicates whether or not he micro controller clock and the AXI4-Lite bus
 | 
      
         | 72 |  |  |       are synchronous
 | 
      
         | 73 | 3 | sinclairrf |     write_enable=<O_write_enable>
 | 
      
         | 74 |  |  |       optionally specify the symbol used to set the 4 write enable bits
 | 
      
         | 75 |  |  |       Note:  This must be used if one or more of the slaves includes the
 | 
      
         | 76 |  |  |       optional WSTRB      signals.
 | 
      
         | 77 |  |  |     noWSTRB
 | 
      
         | 78 |  |  |       indicates that the optional WSTRB signal should not be included
 | 
      
         | 79 |  |  |       Note:  This must be specified if write_enable is not specified.\n
 | 
      
         | 80 |  |  |   Vivado Users:
 | 
      
         | 81 |  |  |     The peripheral creates a TCL script to facilitate turning the micro
 | 
      
         | 82 |  |  |     controller into an IP core.  Look for a file with the name
 | 
      
         | 83 |  |  |     "vivado_<basePortName>.tcl".\n
 | 
      
         | 84 | 2 | sinclairrf |   Example:  Xilinx' AXI_DMA core has a 7-bit address range for its register
 | 
      
         | 85 |  |  |     address map.  The PERIPHERAL configuration statement to interface to this
 | 
      
         | 86 |  |  |     core would be:\n
 | 
      
         | 87 |  |  |       PERIPHERAL AXI4_Lite_Master                                       \
 | 
      
         | 88 |  |  |                         basePortName=myAxiDmaDevice                     \
 | 
      
         | 89 |  |  |                         address=O_myAxiDmaDevice_address                \
 | 
      
         | 90 |  |  |                         data=O_myAxiDmaDevice_data                      \
 | 
      
         | 91 |  |  |                         command_read=O_myAxiDmaDevice_cmd_read          \
 | 
      
         | 92 |  |  |                         command_write=O_myAxiDmaDevice_cmd_write        \
 | 
      
         | 93 |  |  |                         busy=I_myAxiDmaDevice_busy                      \
 | 
      
         | 94 |  |  |                         error=I_myAxiDmaDevice_error                    \
 | 
      
         | 95 |  |  |                         read=I_myAxiDmaDevice_read                      \
 | 
      
         | 96 |  |  |                         address_width=7                                 \
 | 
      
         | 97 | 3 | sinclairrf |                         synchronous=True                                \\
 | 
      
         | 98 |  |  |                         write_enable=O_myAxiDmaDevice_wen\n
 | 
      
         | 99 | 2 | sinclairrf |     To write to the memory master to slave start address, use the
 | 
      
         | 100 |  |  |     following, where "start_address" is a 4-byte variable set elsewhere in the
 | 
      
         | 101 |  |  |     program:\n
 | 
      
         | 102 |  |  |       ; Set the 7-bit register address.
 | 
      
         | 103 |  |  |       0x18 .outport(O_myAxiDmaDevice_address)
 | 
      
         | 104 |  |  |       ; Read the 4-byte start address from memory.
 | 
      
         | 105 |  |  |       .fetchvector(start_address,4)
 | 
      
         | 106 |  |  |       ; write the address to the AXI4-Lite master
 | 
      
         | 107 |  |  |       ${4-1} :loop_data
 | 
      
         | 108 |  |  |         swap .outport(O_myAxiDmaDevice_data)
 | 
      
         | 109 |  |  |       .jumpc(loop_data,1-) drop
 | 
      
         | 110 |  |  |       ; Ensure all 4 bytes will be written.
 | 
      
         | 111 |  |  |       0x0F .outport(O_myAxiDmaDevice_wen)
 | 
      
         | 112 |  |  |       ; Issue the write strobe.
 | 
      
         | 113 |  |  |       .outstrobe(O_myAxiDmaDevice_cmd_write)
 | 
      
         | 114 |  |  |       ; Wait for the write operation to finish.
 | 
      
         | 115 |  |  |       :loop_write_wait
 | 
      
         | 116 |  |  |         .inport(I_myAxiDmaDevice_busy)
 | 
      
         | 117 |  |  |       .jumpc(loop_write_wait)\n
 | 
      
         | 118 |  |  |     Alternatively, a function could be defined as follows:\n
 | 
      
         | 119 |  |  |       ; Write the specified 32-bit value to the specified 7-bit address.
 | 
      
         | 120 |  |  |       ; ( u_LSB u u u_MSB u_addr - )
 | 
      
         | 121 |  |  |       .function myAxiDmaDevice_write
 | 
      
         | 122 |  |  |         ; Write the 7-bit register address.
 | 
      
         | 123 |  |  |         .outport(O_myAxiDmaDevice_address)
 | 
      
         | 124 |  |  |         ; Write the 32-bit value, starting with the MSB.
 | 
      
         | 125 |  |  |         ${4-1} :loop_data
 | 
      
         | 126 |  |  |           swap .outport(O_myAxiDmaDevice_data)
 | 
      
         | 127 |  |  |         .jumpc(loop_data,1-) drop
 | 
      
         | 128 |  |  |         ; Ensure all 4 bytes will be written.
 | 
      
         | 129 |  |  |         0x0F .outport(O_myAxiDmaDevice_wen)
 | 
      
         | 130 |  |  |         ; Issue the write strobe.
 | 
      
         | 131 |  |  |         .outstrobe(O_myAxiDmaDevice_cmd_write)
 | 
      
         | 132 |  |  |         ; Wait for the write operation to finish.
 | 
      
         | 133 |  |  |         :loop_write_wait
 | 
      
         | 134 |  |  |           .inport(I_myAxiDmaDevice_busy)
 | 
      
         | 135 |  |  |         .jumpc(loop_write_wait)
 | 
      
         | 136 |  |  |         ; That's all
 | 
      
         | 137 |  |  |         .return\n
 | 
      
         | 138 |  |  |     And the write could then be performed using the following code:\n
 | 
      
         | 139 |  |  |       .constant AXI_DMA_MM2S_Start_Address 0x18
 | 
      
         | 140 |  |  |       ...
 | 
      
         | 141 |  |  |       ; Write the start address to the AXI DMA.
 | 
      
         | 142 |  |  |       .fetchvector(start_address,4)
 | 
      
         | 143 |  |  |       .call(myAxiDmaDevice_write,AXI_DMA_MM2S_Start_Address)\n
 | 
      
         | 144 |  |  |   Example:  Suppose the AXI4-Lite Master peripheral is connected to a memory
 | 
      
         | 145 |  |  |     with a 22-bit address width, i.e., a 4 MB address range.  The PERIPHERAL
 | 
      
         | 146 |  |  |     configuration command would be similar to the above except the string
 | 
      
         | 147 |  |  |     "myAxiDmaDevice" would need to be changed to the new hardware peripheral and
 | 
      
         | 148 |  |  |     the address width would be set using "address_width=22".\n
 | 
      
         | 149 |  |  |     The 22-bit address would be set using 3 bytes.  For example, the address
 | 
      
         | 150 |  |  |     0x020100 would be set by:\n
 | 
      
         | 151 |  |  |       0x00 .outport(O_myAxiMaster_address)
 | 
      
         | 152 |  |  |       0x01 .outport(O_myAxiMaster_address)
 | 
      
         | 153 |  |  |       0x02 .outport(O_myAxiMaster_address)\n
 | 
      
         | 154 |  |  |     The 2 msb of the first, most-significant, address byte will be dropped by
 | 
      
         | 155 |  |  |     the shift register receiving the address and the 2 lsb of the last, least
 | 
      
         | 156 |  |  |     significant, address byte will be written as zeros to the AXI Lite
 | 
      
         | 157 |  |  |     peripheral.\n
 | 
      
         | 158 |  |  |   LEGAL NOTICE:  ARM has restrictions on what kinds of applications can use
 | 
      
         | 159 |  |  |   interfaces based on their AXI protocol.  Ensure your application is in
 | 
      
         | 160 |  |  |   compliance with their restrictions before using this peripheral for an AXI
 | 
      
         | 161 |  |  |   interface.
 | 
      
         | 162 |  |  |   """
 | 
      
         | 163 |  |  |  
 | 
      
         | 164 |  |  |   def __init__(self,peripheralFile,config,param_list,loc):
 | 
      
         | 165 |  |  |     # Use the externally provided file name for the peripheral
 | 
      
         | 166 |  |  |     self.peripheralFile = peripheralFile;
 | 
      
         | 167 |  |  |     # Get the parameters.
 | 
      
         | 168 |  |  |     allowables = (
 | 
      
         | 169 |  |  |       ('address',       r'O_\w+$',              None,           ),
 | 
      
         | 170 |  |  |       ('address_width', r'[1-9]\d*$',           int,            ),
 | 
      
         | 171 |  |  |       ('basePortName',  r'\w+$',                None,           ),
 | 
      
         | 172 |  |  |       ('command_read',  r'O_\w+$',              None,           ),
 | 
      
         | 173 |  |  |       ('command_write', r'O_\w+$',              None,           ),
 | 
      
         | 174 |  |  |       ('data',          r'O_\w+$',              None,           ),
 | 
      
         | 175 |  |  |       ('read',          r'I_\w+$',              None,           ),
 | 
      
         | 176 |  |  |       ('busy',          r'I_\w+$',              None,           ),
 | 
      
         | 177 |  |  |       ('error',         r'I_\w+$',              None,           ),
 | 
      
         | 178 | 3 | sinclairrf |       ('noWSTRB',       None,                   None,           ),
 | 
      
         | 179 | 2 | sinclairrf |       ('synchronous',   r'(True|False)$',       bool,           ),
 | 
      
         | 180 |  |  |       ('write_enable',  r'O_\w+$',              None,           ),
 | 
      
         | 181 |  |  |     );
 | 
      
         | 182 |  |  |     names = [a[0] for a in allowables];
 | 
      
         | 183 |  |  |     for param_tuple in param_list:
 | 
      
         | 184 |  |  |       param = param_tuple[0];
 | 
      
         | 185 |  |  |       if param not in names:
 | 
      
         | 186 |  |  |         raise SSBCCException('Unrecognized parameter "%s" at %s' % (param,loc,));
 | 
      
         | 187 |  |  |       param_test = allowables[names.index(param)];
 | 
      
         | 188 |  |  |       self.AddAttr(config,param,param_tuple[1],param_test[1],loc,param_test[2]);
 | 
      
         | 189 | 3 | sinclairrf |     # Ensure the required parameters are provided.
 | 
      
         | 190 |  |  |     for paramname in (
 | 
      
         | 191 |  |  |       'address',
 | 
      
         | 192 |  |  |       'address_width',
 | 
      
         | 193 |  |  |       'basePortName',
 | 
      
         | 194 |  |  |       'command_read',
 | 
      
         | 195 |  |  |       'command_write',
 | 
      
         | 196 |  |  |       'data',
 | 
      
         | 197 |  |  |       'read',
 | 
      
         | 198 |  |  |       'busy',
 | 
      
         | 199 |  |  |       'error',
 | 
      
         | 200 |  |  |       'synchronous',
 | 
      
         | 201 |  |  |     ):
 | 
      
         | 202 | 2 | sinclairrf |       if not hasattr(self,paramname):
 | 
      
         | 203 |  |  |         raise SSBCCException('Required parameter "%s" is missing at %s' % (paramname,loc,));
 | 
      
         | 204 | 3 | sinclairrf |     # Ensure one and only one of the complementary optional values are set.
 | 
      
         | 205 |  |  |     if not hasattr(self,'write_enable') and not hasattr(self,'noWSTRB'):
 | 
      
         | 206 |  |  |       raise SSBCCException('One of "write_enable" or "noWSTRB" must be set at %s' % loc);
 | 
      
         | 207 |  |  |     if hasattr(self,'write_enable') and hasattr(self,'noWSTRB'):
 | 
      
         | 208 |  |  |       raise SSBCCException('Only one of "write_enable" or "noWSTRB" can be set at %s' % loc);
 | 
      
         | 209 |  |  |     self.noWSTRB = hasattr(self,'noWSTRB');
 | 
      
         | 210 | 2 | sinclairrf |     # Temporary:  Warning message
 | 
      
         | 211 |  |  |     if not self.synchronous:
 | 
      
         | 212 |  |  |       raise SSBCCException('synchronous=False has not been validated yet');
 | 
      
         | 213 |  |  |     # Add the I/O port, internal signals, and the INPORT and OUTPORT symbols for this peripheral.
 | 
      
         | 214 |  |  |     for signal in (
 | 
      
         | 215 |  |  |       ( 'i_%s_aresetn',         1,                      'input',        ),
 | 
      
         | 216 |  |  |       ( 'i_%s_aclk',            1,                      'input',        ),
 | 
      
         | 217 |  |  |       ( 'o_%s_awvalid',         1,                      'output',       ),
 | 
      
         | 218 |  |  |       ( 'i_%s_awready',         1,                      'input',        ),
 | 
      
         | 219 |  |  |       ( 'o_%s_awaddr',          self.address_width,     'output',       ),
 | 
      
         | 220 |  |  |       ( 'o_%s_wvalid',          1,                      'output',       ),
 | 
      
         | 221 |  |  |       ( 'i_%s_wready',          1,                      'input',        ),
 | 
      
         | 222 |  |  |       ( 'o_%s_wdata',           32,                     'output',       ),
 | 
      
         | 223 | 3 | sinclairrf |       ( 'o_%s_wstrb',           4,                      'output',       ) if not self.noWSTRB else None,
 | 
      
         | 224 | 2 | sinclairrf |       ( 'i_%s_bresp',           2,                      'input',        ),
 | 
      
         | 225 |  |  |       ( 'i_%s_bvalid',          1,                      'input',        ),
 | 
      
         | 226 |  |  |       ( 'o_%s_bready',          1,                      'output',       ),
 | 
      
         | 227 |  |  |       ( 'o_%s_arvalid',         1,                      'output',       ),
 | 
      
         | 228 |  |  |       ( 'i_%s_arready',         1,                      'input',        ),
 | 
      
         | 229 |  |  |       ( 'o_%s_araddr',          self.address_width,     'output',       ),
 | 
      
         | 230 |  |  |       ( 'i_%s_rvalid',          1,                      'input',        ),
 | 
      
         | 231 |  |  |       ( 'o_%s_rready',          1,                      'output',       ),
 | 
      
         | 232 |  |  |       ( 'i_%s_rdata',           32,                     'input',        ),
 | 
      
         | 233 |  |  |       ( 'i_%s_rresp',           2,                      'input',        ),
 | 
      
         | 234 |  |  |     ):
 | 
      
         | 235 | 3 | sinclairrf |       if not signal:
 | 
      
         | 236 |  |  |         continue
 | 
      
         | 237 | 2 | sinclairrf |       thisName = signal[0] % self.basePortName;
 | 
      
         | 238 |  |  |       config.AddIO(thisName,signal[1],signal[2],loc);
 | 
      
         | 239 |  |  |     config.AddSignal('s__%s__address' % self.basePortName, self.address_width, loc);
 | 
      
         | 240 |  |  |     config.AddSignal('s__%s__rd' % self.basePortName, 1, loc);
 | 
      
         | 241 |  |  |     config.AddSignal('s__%s__wr' % self.basePortName, 1, loc);
 | 
      
         | 242 |  |  |     config.AddSignal('s__%s__busy' % self.basePortName, 5, loc);
 | 
      
         | 243 |  |  |     config.AddSignal('s__%s__error' % self.basePortName, 2, loc);
 | 
      
         | 244 |  |  |     config.AddSignal('s__%s__read' % self.basePortName, 32, loc);
 | 
      
         | 245 |  |  |     self.ix_address = config.NOutports();
 | 
      
         | 246 |  |  |     config.AddOutport((self.address,False,
 | 
      
         | 247 |  |  |                       # empty list -- disable normal output port signal generation
 | 
      
         | 248 |  |  |                       ),loc);
 | 
      
         | 249 |  |  |     self.ix_data = config.NOutports();
 | 
      
         | 250 |  |  |     config.AddOutport((self.data,False,
 | 
      
         | 251 |  |  |                       # empty list -- disable normal output port signal generation
 | 
      
         | 252 |  |  |                       ),loc);
 | 
      
         | 253 | 3 | sinclairrf |     if not self.noWSTRB:
 | 
      
         | 254 |  |  |       config.AddOutport((self.write_enable,False,
 | 
      
         | 255 | 2 | sinclairrf |                       ('o_%s_wstrb' % self.basePortName, 4, 'data', ),
 | 
      
         | 256 |  |  |                       ),loc);
 | 
      
         | 257 |  |  |     config.AddOutport((self.command_read,True,
 | 
      
         | 258 |  |  |                       ('s__%s__rd' % self.basePortName, 1, 'strobe', ),
 | 
      
         | 259 |  |  |                       ),loc);
 | 
      
         | 260 |  |  |     config.AddOutport((self.command_write,True,
 | 
      
         | 261 |  |  |                       ('s__%s__wr' % self.basePortName, 1, 'strobe', ),
 | 
      
         | 262 |  |  |                       ),loc);
 | 
      
         | 263 |  |  |     config.AddInport((self.busy,
 | 
      
         | 264 |  |  |                      ('s__%s__busy' % self.basePortName, 5, 'data', ),
 | 
      
         | 265 |  |  |                      ),loc);
 | 
      
         | 266 |  |  |     config.AddInport((self.error,
 | 
      
         | 267 |  |  |                      ('s__%s__error' % self.basePortName, 2, 'data', ),
 | 
      
         | 268 |  |  |                      ),loc);
 | 
      
         | 269 |  |  |     self.ix_read = config.NInports();
 | 
      
         | 270 |  |  |     config.AddInport((self.read,
 | 
      
         | 271 |  |  |                      ('s__%s__read' % self.basePortName, 32, 'data', ),
 | 
      
         | 272 |  |  |                      ),loc);
 | 
      
         | 273 |  |  |  
 | 
      
         | 274 |  |  |   def GenVerilog(self,fp,config):
 | 
      
         | 275 |  |  |     body = self.LoadCore(self.peripheralFile,'.v');
 | 
      
         | 276 |  |  |     # avoid i_clk and i_rst
 | 
      
         | 277 |  |  |     for subpair in (
 | 
      
         | 278 |  |  |       (r'\bgen__',              'gen__@NAME@__',                        ),
 | 
      
         | 279 |  |  |       (r'\bL__',                'L__@NAME@__',                          ),
 | 
      
         | 280 |  |  |       (r'\bs__',                's__@NAME@__',                          ),
 | 
      
         | 281 |  |  |       (r'\bi_a',                'i_@NAME@_a',                           ),
 | 
      
         | 282 |  |  |       (r'\bi_b',                'i_@NAME@_b',                           ),
 | 
      
         | 283 |  |  |       (r'\bi_rd',               'i_@NAME@_rd',                          ),
 | 
      
         | 284 |  |  |       (r'\bi_rr',               'i_@NAME@_rr',                          ),
 | 
      
         | 285 |  |  |       (r'\bi_rv',               'i_@NAME@_rv',                          ),
 | 
      
         | 286 |  |  |       (r'\bi_w',                'i_@NAME@_w',                           ),
 | 
      
         | 287 |  |  |       (r'\bo_',                 'o_@NAME@_',                            ),
 | 
      
         | 288 |  |  |       (r'@ADDRESS_WIDTH@',      str(self.address_width),                ),
 | 
      
         | 289 |  |  |       (r'@ISSYNC@',             "1'b1" if self.synchronous else "1'b0", ),
 | 
      
         | 290 |  |  |       (r'@IX_ADDRESS@',         str(self.ix_address),                   ),
 | 
      
         | 291 |  |  |       (r'@IX_DATA@',            str(self.ix_data),                      ),
 | 
      
         | 292 |  |  |       (r'@IX_READ@',            str(self.ix_read),                      ),
 | 
      
         | 293 |  |  |       (r'@NAME@',               self.basePortName,                      ),
 | 
      
         | 294 |  |  |     ):
 | 
      
         | 295 |  |  |       body = re.sub(subpair[0],subpair[1],body);
 | 
      
         | 296 |  |  |     body = self.GenVerilogFinal(config,body);
 | 
      
         | 297 |  |  |     fp.write(body);
 | 
      
         | 298 | 3 | sinclairrf |  
 | 
      
         | 299 |  |  |     # Write the TCL script to facilitate creating Vivado IP for the port.
 | 
      
         | 300 |  |  |     vivadoFile = os.path.join(os.path.dirname(self.peripheralFile),'vivado_AXI4_Lite_Bus.py');
 | 
      
         | 301 |  |  |     execfile(vivadoFile,globals());
 | 
      
         | 302 |  |  |     WriteTclScript('master',self.basePortName,self.address_width,noWSTRB=self.noWSTRB);
 |