diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 58742a7e..62f03b23 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,14 +4,14 @@ lib_ethernet change log 4.0.0 ----- - * REMOVED: Slicekit based examples because hardware is obsolete - * REMOVED: Support for waf build system - * ADDED: Support for XCommon CMake build system - * REMOVED: Support for XS1 devices - * RESOLVED: Build warnings even when compile successful * ADDED: Support for running MII sim tests for XS3 architecture * ADDED: RMII Ethernet MAC support for XCORE-AI * ADDED: Extended sim tests for testing RMII applications + * ADDED: Support for XCommon CMake build system + * RESOLVED: Build warnings even when compile successful + * REMOVED: Slicekit based examples because hardware is obsolete + * REMOVED: Support for waf build system + * REMOVED: Support for XS1 devices * Changes to dependencies: diff --git a/doc/rst/lib_ethernet.rst b/doc/rst/lib_ethernet.rst index e2bb7a1f..1710a76c 100644 --- a/doc/rst/lib_ethernet.rst +++ b/doc/rst/lib_ethernet.rst @@ -33,7 +33,7 @@ Various MAC blocks are available depending on the XMOS architecture selected, de - Supported * - XS3 (xcore.ai) - Supported - - Contact XMOS + - Supported - Contact XMOS - N/A @@ -67,11 +67,11 @@ The amount required depends on the feature set of the MAC. The table below summa - 2 - ~23 k - 4 - * - 10/100 Mb/s Real-Time MII + * - 10/100 Mb/s Real-Time RMII - 7 - 3 (1-bit), 2 (4-bit) or 4 (1-bit) - 2 - - ~TBD k + - ~25 k - 4 * - 10/100/1000Mb/s RGMII - 12 @@ -196,6 +196,9 @@ have their port type set independently and can be mixed. Unused pins on a 4-bit the PHY to be configured so that the receive data strobe is set to RX_DV mode. Please check your chosen PHY supports this. +The RMII MAC requires a minimum thread speed of 75 MHz which allows all 8 hardware threads to be used on a 600 MHz xcore.ai device. + + Table 1 below describes the RMII signals: .. list-table:: RMII signals @@ -471,18 +474,24 @@ Similarly the RMII real-time MAC may be instantiated:: streaming chan c_rx_hp; streaming chan c_tx_hp; par { - rmii_ethernet_rt_mac(i_cfg, 1, i_rx_lp, 1, i_tx_lp, 1, - c_rx_hp, c_tx_hp, - p_eth_clk, - &p_eth_rxd, p_eth_rxdv, - p_eth_txen, &p_eth_txd, - eth_rxclk, eth_txclk, - 4000, 4000, ETHERNET_ENABLE_SHAPER); + unsafe{rmii_ethernet_rt_mac(i_cfg, 1, i_rx_lp, 1, i_tx_lp, 1, + c_rx_hp, c_tx_hp, + p_eth_clk, + &p_eth_rxd, p_eth_rxdv, + p_eth_txen, &p_eth_txd, + eth_rxclk, eth_txclk, + 4000, 4000, ETHERNET_ENABLE_SHAPER);} application(i_cfg[0], i_rx_lp[0], i_tx_lp[0], c_rx_hp, c_tx_hp); } } +.. note:: + The call to rmii_ethernet_rt_mac() needs to be wrapped in ``unsafe{}`` because the rmii_data_port_t types are sent as references which translate to unsafe (array bounds unchecked) pointers. + + + + The application can use the other end of the streaming channels to send and receive high-priority traffic e.g.:: void application(client ethernet_cfg_if i_cfg, diff --git a/examples/AN00120_100Mbit_ethernet_demo/LICENSE.rst b/examples/AN00120_100Mbit_ethernet_demo/LICENSE.rst deleted file mode 100644 index ca48f20f..00000000 --- a/examples/AN00120_100Mbit_ethernet_demo/LICENSE.rst +++ /dev/null @@ -1,84 +0,0 @@ -******************************* -XMOS PUBLIC LICENCE: Version 1 -******************************* - -Subject to the conditions and limitations below, permission is hereby granted by XMOS LIMITED (“XMOS”), free of charge, to any person or entity obtaining a copy of the XMOS Software. - -**1. Definitions** - -**“Applicable Patent Rights”** means: (a) where XMOS is the grantor of the rights, (i) claims of patents that are now or in future owned by or assigned to XMOS and (ii) that cover subject matter contained in the Software, but only to the extent it is necessary to use, reproduce or distribute the Software without infringement; and (b) where you are the grantor of the rights, (i) claims of patents that are now or in future owned by or assigned to you and (ii) that cover the subject matter contained in your Derivatives, taken alone or in combination with the Software. - -**“Compiled Code”** means any compiled, binary, machine readable or executable version of the Source Code. - -**“Contributor”** means any person or entity that creates or contributes to the creation of Derivatives. - -**“Derivatives”** means any addition to, deletion from and/or change to the substance, structure of the Software, any previous Derivatives, the combination of the Derivatives and the Software and/or any respective portions thereof. - -**“Source Code”** means the human readable code that is suitable for making modifications but excluding any Compiled Code. - -**“Software”** means the software and associated documentation files which XMOS makes available and which contain a notice identifying the software as original XMOS software and referring to the software being subject to the terms of this XMOS Public Licence. - -This Licence refers to XMOS Software and does not relate to any XMOS hardware or devices which are protected by intellectual property rights (including patent and trade marks) which may be sold to you under a separate agreement. - - -**2. Licence** - -**Permitted Uses, Conditions and Restrictions.** Subject to the conditions below, XMOS grants you a worldwide, royalty free, non-exclusive licence, to the extent of any Patent Rights to do the following: - -2.1 **Unmodified Software.** You may use, copy, display, publish, distribute and make available unmodified copies of the Software: - -2.1.1 for personal or academic, non-commercial purposes; or - -2.1.2 for commercial purposes provided the Software is at all times used on a device designed, licensed or developed by XMOS and, provided that in each instance (2.1.1 and 2.1.2): - -(a) you must retain and reproduce in all copies of the Software the copyright and proprietary notices and disclaimers of XMOS as they appear in the Software, and keep intact all notices and disclaimers in the Software files that refer to this Licence; and - -(b) you must include a copy of this Licence with every copy of the Software and documentation you publish, distribute and make available and you may not offer or impose any terms on such Software that alter or restrict this Licence or the intent of such Licence, except as permitted below (Additional Terms). - -The licence above does not include any Compiled Code which XMOS may make available under a separate support and licence agreement. - -2.2 **Derivatives.** You may create and modify Derivatives and use, copy, display, publish, distribute and make available Derivatives: - -2.2.1 for personal or academic, non-commercial purposes; or - -2.2.2 for commercial purposes, provided the Derivatives are at all times used on a device designed, licensed or developed by XMOS and, provided that in each instance (2.2.1 and 2.2.2): - -(a) you must comply with the terms of clause 2.1 with respect to the Derivatives; - -(b) you must copy (to the extent it doesn’t already exist) the notice below in each file of the Derivatives, and ensure all the modified files carry prominent notices stating that you have changed the files and the date of any change; and - -(c) if you sublicence, distribute or otherwise make the Software and/or the Derivatives available for commercial purposes, you must provide that the Software and Derivatives are at all times used on a device designed, licensed or developed by XMOS. - -Without limitation to these terms and clause 3 below, the Source Code and Compiled Code to your Derivatives may at your discretion (but without obligation) be released, copied, displayed, published, distributed and made available; and if you elect to do so, it must be under the terms of this Licence including the terms of the licence at clauses 2.2.1, 2.2.2 and clause 3 below. - -2.3 **Distribution of Executable Versions.** If you distribute or make available Derivatives, you must include a prominent notice in the code itself as well as in all related documentation, stating that the Source Code of the Software from which the Derivatives are based is available under the terms of this Licence, with information on how and where to obtain such Source Code. - -**3. Your Grant of Rights.** In consideration and as a condition to this Licence, you grant to any person or entity receiving or distributing any Derivatives, a non-exclusive, royalty free, perpetual, irrevocable license under your Applicable Patent Rights and all other intellectual property rights owned or controlled by you, to use, copy, display, publish, distribute and make available your Derivatives of the same scope and extent as XMOS’s licence under clause 2.2 above. - -**4. Combined Products.** You may create a combined product by combining Software, Derivatives and other code not covered by this Licence as a single application or product. In such instance, you must comply with the requirements of this Licence for any portion of the Software and/or Derivatives. - -**5. Additional Terms.** You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations and/or other rights consistent with the term of this Licence (“Additional Terms”) to any legitimate recipients of the Software and/or Derivatives. The terms on which you provide such Additional Terms are on your sole responsibility and you shall indemnify, defend and hold XMOS harmless against any claims asserted against XMOS. - -**6. New Versions.** XMOS may publish revised and/or new versions of this Licence from time to time to accommodate changes to the Licence terms, new versions, updates and bug fixes of the Software. Each version will be given a distinguishing version number. Once Software has been published under a particular version of this Licence, you may continue to use it under the terms of that version. You may also choose to use the latest version of the Software under any subsequent version published by XMOS. Only XMOS shall have the right to modify these terms. - -**7. IPR and Ownership** -Any rights, including all intellectual property rights and all trademarks not expressly granted herein are reserved in full by the authors or copyright holders. Any requests for additional permissions by XMOS including any rights to use XMOS trademarks, should be made (without obligation) to XMOS at **support@xmos.com** - -Nothing herein shall limit any rights that XMOS is otherwise entitled to under the doctrines of patent exhaustion, implied license, or legal estoppel. Neither the name of the authors, the copyright holders or any contributors may be used to endorse or promote any Derivatives from this Software without specific written permission. Any attempt to deal with the Software which does not comply with this Licence shall be void and shall automatically terminate any rights granted under this licence (including any licence of any intellectual property rights granted herein). -Subject to the licences granted under this Licence any Contributor retains all rights, title and interest in and to any Derivatives made by Contributor subject to the underlying rights of XMOS in the Software. XMOS shall retain all rights, title and interest in the Software and any Derivatives made by XMOS (“XMOS Derivatives”). XMOS Derivatives will not automatically be subject to this Licence and XMOS shall be entitled to licence such rights on any terms (without obligation) as it sees fit. - -**8. Termination** - -8.1 This Licence will automatically terminate immediately, without notice to you, if: - -(a) you fail to comply with the terms of this Licence; and/or - -(b) you directly or indirectly commence any action for patent or intellectual property right infringement against XMOS, or any parent, group, affiliate or subsidiary of XMOS; provided XMOS did not first commence an action or patent infringement against you in that instance; and/or - -(c) the terms of this Licence are held by any court of competent jurisdiction to be unenforceable in whole or in part. - -**9. Critical Applications.** Unless XMOS has agreed in writing with you an agreement specifically governing use of the Goods in military, aerospace, automotive or medically related functions (collectively and individually hereinafter referred to as "Special Use"), any permitted use of the Software excludes Special Use. Notwithstanding any agreement between XMOS and you for Special Use, Special Use shall be at your own risk, and you shall fully indemnify XMOS against any damages, losses, costs and claims (direct and indirect) arising out of any Special Use. - -**10. NO WARRANTY OR SUPPORT.** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL XMOS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, WARRANTY, CIVIL TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE INCLUDING GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES EVEN IF SUCH PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND NOT WITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE. IN SOME JURISDICTIONS PARTIES ARE UNABLE TO LIMIT LIABILTY IN THIS WAY, IF THIS APPLIES TO YOUR JURISDICTION THIS LIABILITY CLAUSE ABOVE MAY NOT APPLY. NOTWITHSTANDING THE ABOVE, IN NO EVENT SHALL XMOS’s TOTAL LIABILITY TO YOU FOR ALL DAMAGES, LOSS OR OTHERWISE EXCEED $50. - -**11. Governing Law and Jurisdiction.** This Licence constitutes the entire agreement between the parties with respect to the subject matter hereof. The Licence shall be governed by the laws of England and the conflict of laws and UN Convention on Contracts for the International Sale of Goods, shall not apply. diff --git a/examples/AN00120_100Mbit_ethernet_demo/Makefile b/examples/AN00120_100Mbit_ethernet_demo/Makefile deleted file mode 100644 index aa8848b6..00000000 --- a/examples/AN00120_100Mbit_ethernet_demo/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -# Do not build for XCOREAI -ifeq ($(XCOREAI),1) -$(error XCOREAI is not supported in this example) -endif - -# The TARGET variable determines what target system the application is -# compiled for. It either refers to an XN file in the source directories -# or a valid argument for the --target option when compiling. - -TARGET = SLICEKIT-ETH-TRIANGLE1 - -# The APP_NAME variable determines the name of the final .xe file. It should -# not include the .xe postfix. If left blank the name will default to -# the project name - -APP_NAME = - -# The flags passed to xcc when building the application -# You can also set the following to override flags for a particular language: -# -# XCC_XC_FLAGS, XCC_C_FLAGS, XCC_ASM_FLAGS, XCC_CPP_FLAGS -# -# If the variable XCC_MAP_FLAGS is set it overrides the flags passed to -# xcc for the final link (mapping) stage. - -XCC_FLAGS = -g -report -DDEBUG_PRINT_ENABLE -save-temps -Os -Xmapper --map -Xmapper MAPFILE - -XCC_FLAGS_icmp = $(XCC_FLAGS) -Wno-reinterpret-alignment - -# The USED_MODULES variable lists other module used by the application. - -USED_MODULES = lib_ethernet(>=4.0.0) lib_otpinfo(>=2.0.0) lib_slicekit_support(>=2.0.0) - -#============================================================================= -# The following part of the Makefile includes the common build infrastructure -# for compiling XMOS applications. You should not need to edit below here. - -XMOS_MAKE_PATH ?= ../.. -include $(XMOS_MAKE_PATH)/xcommon/module_xcommon/build/Makefile.common diff --git a/examples/AN00120_100Mbit_ethernet_demo/README.rst b/examples/AN00120_100Mbit_ethernet_demo/README.rst deleted file mode 100644 index 456f9c1a..00000000 --- a/examples/AN00120_100Mbit_ethernet_demo/README.rst +++ /dev/null @@ -1,61 +0,0 @@ -XMOS 100Mbit Ethernet application note -====================================== - -Summary -------- - -Ethernet connectivity is an essential part of the explosion of connected -devices known collectively as the Internet of Things (IoT). XMOS technology is -perfectly suited to these applications - offering future proof and reliable -ethernet connectivity whilst offering the flexibility to interface to a huge -variety of "Things". - -This application note shows a simple example that demonstrates the use -of the XMOS Ethernet library to create a layer 2 ethernet MAC -interface on an XMOS multicore microcontroller. - -The code associated with this application note provides an example of -using the Ethernet Library to provide a framework for the creation of an -ethernet Media Independent Interface (MII) and MAC interface for -100Mbps. - -The applcation note uses XMOS libraries to provide a simple IP stack -capable of responding to an ICMP ping message. The code used in the -application note provides both MII communication to the PHY and a MAC -transport layer for ethernet packets and enables a client to connect -to it and send/receive packets. - -Required tools and libraries -............................ - -For a list of direct dependencies, look for USED_MODULES in the Makefile. - -Required hardware -................. - -This application note is designed to run on an XMOS xCORE-200 -series device. -The example code provided with the application has been implemented -and tested on the X200 sliceKIT 1V0 (XK-SK-X200-ST) core board using -ethernet sliceCARD 1V1 (XA-SK-E100). There is no dependancy on this -core board - it can be modified to run on any (XMOS) development board -which has the option to connect to the ethernet sliceCARD. - -Prerequisites -.............. - - * This document assumes familarity with the XMOS xCORE architecture, - the Ethernet standards IEEE 802.3u (MII), the XMOS tool chain and - the xC language. Documentation related to these aspects which are - not specific to this application note are linked to in the - references appendix. - - * For a description of XMOS related terms found in this document - please see the XMOS Glossary [#]_. - - * For an overview of the Ethernet library, please see the Ethernet - library user guide. - -.. [#] http://www.xmos.com/published/glossary - - diff --git a/examples/AN00120_100Mbit_ethernet_demo/SLICEKIT-ETH-TRIANGLE1.xn b/examples/AN00120_100Mbit_ethernet_demo/SLICEKIT-ETH-TRIANGLE1.xn deleted file mode 100644 index 4bac151a..00000000 --- a/examples/AN00120_100Mbit_ethernet_demo/SLICEKIT-ETH-TRIANGLE1.xn +++ /dev/null @@ -1,67 +0,0 @@ - - - Board - sliceKIT Core Board (X200) - - tileref tile[2] - tileref usb_tile - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/AN00120_100Mbit_ethernet_demo/doc/rst/AN00120.rst b/examples/AN00120_100Mbit_ethernet_demo/doc/rst/AN00120.rst deleted file mode 100644 index 26bf2f9b..00000000 --- a/examples/AN00120_100Mbit_ethernet_demo/doc/rst/AN00120.rst +++ /dev/null @@ -1,352 +0,0 @@ -.. include:: ../../README.rst - -|newpage| - -Overview --------- - -Introduction -............ - -The application note shows the use of the XMOS Ethernet library. The -library allows multiple clients to access the Ethernet hardware. This -application note uses the standard Ethernet MAC which uses two logical -cores. The Ethernet library also provides a real-time MAC which uses -more cores but provides high performance streaming data, accurate -packet timestamping, priority queuing and 802.1Qav traffic shaping. - -MII provides the data transfer signals -between the Ethernet PHY (Physical Layer Device or transceiver) and -the xCORE device. The MII layer receives packets of data which are -then routed by an Ethernet MAC layer to multiple processes running on -the xCORE. SMI provides the management interface between the PHY and -the xCORE device. - -Block Diagram -............. - -.. figure:: images/block_diag.* - :width: 80% - - Application block diagram - -The application communicates with the Ethernet MAC that drives the MII -data interface to the PHY. A separate PHY driver configures the PHY -via the SMI serial interface. - - -100Mbit Ethernet library demo ------------------------------ - - -The Makefile -............ - -The demo in this note uses the XMOS Ethernet library and shows a -simple program communicating with the Ethernet library. - -To start using the Ethernet library, you need to add ``lib_ethernet`` -to you Makefile:: - - USED_MODULES = .. lib_ethernet ... - -This demo also gets the MAC address out of the xCORE OTP rom and is -for the sliceKIT. So the Makefile also includes the OTP reading library -(``lib_otpinfo``) and the sliceKIT support library -(``lib_slicekit_support``):: - - USED_MODULES = .. lib_otpinfo lib_slicekit_support - - -Allocating hardware resources -............................. - -The Ethernet library requires several ports to communicate with the -Ethernet PHY. These ports are declared in the main program file -(``main.xc``). In this demo the ports are set up for the Ethernet -slice connected to tile 1 triangle slot of the sliceKIT. Actual port -names such as ``XS1_PORT_1J`` are specified in XN file and source refers -to them with symbolic names such as ``PORT_ETH_RXCLK``: - -.. literalinclude:: main.xc - :start-on: PORT_ETH_RXCLK - :end-on: PORT_SMI_MDC - -Note that the port ``p_eth_dummy`` does not need to be connected to -external hardware - it is just used internally by the Ethernet -library. - -You will find three additional PHY signals on the sliceCARD: RST_N, -CLK_IN and INT_N. INT_N will be left unused and we will poll SMI registers -to get link state instead. CLK_N receives 25MHz clock from the sliceKIT -and RST_N receives the sliceKITs system reset. - -The MDIO Serial Management Interface (SMI) is used to transfer -management information between MAC and PHY. This interface consists of -two signals which are connected to two ports: - -.. literalinclude:: main.xc - :start-on: p_smi_mdio - :end-on: p_smi_mdc - -The final ports used in the application -are the ones to access the internal OTP -memory on the xCORE. These ports are fixed and can be intialized with -the ``OTP_PORTS_INITIALIZER`` macro supplied by the ``lib_otpinfo`` -OTP reading library. - -.. literalinclude:: main.xc - :start-on: // These ports are for accessing the OTP memory - :end-on: otp_ports - -The application main() function -............................... - -The main function in the program sets up the tasks in the application. - -.. literalinclude:: main.xc - :start-on: int main - -The ``mii_ethernet_mac`` communicates with the PHY and connects to the -application via the three interfaces. It takes the previously declared -ports as arguments as well as the required buffer size for the packet -buffer within the MAC. - -The ``smi`` task is part of the Ethernet library and controls the SMI -protocol to configure the PHY. It connects to the -``lan8710a_phy_driver`` task which connects configuration of the PHY - -|newpage| - -The PHY driver -.............. - -The PHY drive task connects to both the Ethernet MAC (via the -``ethernet_cfg_if`` interface for configuration) and the SMI driver -(via the ``smi_if`` interface): - -.. literalinclude:: main.xc - :start-on: [[combinable]] - :end-before: ETH_RX_BUFFER - -The first action the drive does is wait for the PHY to power up and -then configure the PHY. This is done via library functions provided by -the Ethernet library. - -The main body of the drive is an infinite loop that periodically -reacts to a timer event in an xC ``select`` statement. A a set period -it checks the state of the PHY over SMI and then informs the MAC of -this state via the ``eth.set_link_state`` call. This way the MAC can -know about link up/down events or change of link speed. - -ICMP Packet Processing -...................... - -The packet processing in the application is handled by the -``icmp_server`` task which is defined in the file ``icmp.xc``. This -function connects to the ethernet MAC via a transmit, receive and -configuration interface: - -.. literalinclude:: icmp.xc - :start-on: [[combinable]] - :end-on: { - -The first thing the task performs is configuring its connection to the -MAC. The MAC address is configured by reading a MAC address out of OTP -(using the ``otp_board_info_get_mac`` function from the OTP reading -library) and then calling the ``set_macaddr`` interface function: - -.. literalinclude:: icmp.xc - :start-on: unsigned char mac_address[MACADDR_NUM_BYTES]; - :end-on: cfg.set_macaddr - -After this, the task configures filters to determine which type of -packets is will receive from the MAC: - -.. literalinclude:: icmp.xc - :start-on: memcpy(macaddr_filter.addr - :end-before: debug_printf - -The task then proceeds into an infinite loop that waits for a packet -from the MAC and then processes it: - -.. literalinclude:: icmp.xc - :start-on: while (1) - -The xC ``select`` statement will wait for the event -``rx.packet_ready()`` which is a receive notification from the MAC -(see the Ethernet library user guide for details of the ethernet -receive interface). When a packet arrives the ``rx.get_packet`` call -will retreive the packet from the MAC. - -After the packet is processed the ``tx.send_packet`` call will send -the created reponse packet to the MAC. - -Details of the packet processing functions ``is_valid_arp_packet``, -``build_arp_response``, ``is_valid_icmp_packet`` and -``build_icmp_response`` can be found in the ``icmp.xc`` file. The -functions implement the ICMP protocol. - -|newpage| -|appendix| - -Demo Hardware Setup --------------------- - - * To run the demo, connect the XTAG USB debug adapter to the sliceKIT via the supplied adaptor board - * Connect the XTAG to the host PC (using USB extension cable if desired) - * Connect the ethernet sliceCARD to the **TILE 1 TRIANGLE** slot of the sliceKIT. Then, connect the slice to the host PC or to the network switch using an ethernet cable. - * On the xCORE-200 series sliceKIT ensure that the xCONNECT LINK (xSCOPE) switch is set to ON, as per the image, to allow xSCOPE to function. - -.. figure:: images/hardware_setup.* - :scale: 100% - :align: center - - Hardware Setup for XMOS MAC library demo - -|newpage| - -Launching the demo device -------------------------- - - - -Once the application source code is imported into the tools you can -edit the demo to configure the IP address the ICMP code uses. This is -declared as a data structure in ``main.xc`` (which is then passed to -the ``icmp_server`` function):: - - static unsigned char ip_address[4] = {192, 168, 1, 178}; - -Alter this value to an IP address that works on your network. - -You can now build the project which will generate the binary file required to run the demo application. -Once the application has been built you need to download the application code onto the xCORE-L sliceKIT. Here you use the tools to load the application over JTAG onto the xCORE device. - - * Select **Run Configuration**. - * In **Main** menu, enable **xSCOPE** in Target I/O options. - * In **XScope** menu, enable **Offline [XScope] Mode**. - * Click **Apply** and then **Run**. - -When the processor has finished booting you will see the following text in the xTIMEcomposer console window when **ping**-ed from the host. - -.. _fig_ping_response: - -.. figure:: images/ping_response.* - :scale: 85% - :align: center - - Response on xTIMEcomposer console for **Ping** - -|newpage| - -.. figure:: images/host_ping_response.* - :scale: 85% - :align: center - - Response on Host PC for **Ping** - -On the above `ping` response on host, out of 40 packets transmitted to device first 15 packet couldn't able to reach the device. During this period, device will respond as **ARP packet received**. -After that device (remaining 35 packets) responds as **ICMP packet received**. (:ref:`fig_ping_response`) - -|newpage| - -FAQs ------ - -1. What do I do if I need to change the ethernet sliceCARD slot? - -The ports in the application are configured to connect to ethernet -sliceCARD in the CIRCLE slot but this can be changed by changing the -port declarations in ``main.xc``. - -2. How can the demo be altered to use the real-time MAC? - - The call to ``mii_ethernet_mac`` needs to be replaces with a call - to ``mii_ethernet_rt_mac``. See the Ethernet library user guide for - more details. - -3. What are Buffers and Queues? Why are they needed? - - The MAC maintains two sets of buffers: one for the incoming packets - and the other for outgoing packets. - - For the incoming packets: - - - Empty buffers are in the incoming queue awaiting a packet coming from the MII interfaces. - - Buffers received from the MII interface are filtered and moved into a forwarding queue if appropriate. - - Buffers in the forwarding queue are moved into a client queue depending on which client registered for that type of packet. - - Once the data from a buffer has been sent to a client, the buffer is moved back into the incoming queue. - - For the outgoing packets: - - - Empty buffers are stored in an empty queue awaiting a packet from the client. - - Once the data is received the buffer is moved into a transmit queue awaiting output on the MII interface. - - Once the data is transmitted, the buffer is released back to the empty queue. - -|newpage| - -References ----------- - -.. nopoints:: - - * XMOS Tools User Guide - - http://www.xmos.com/published/xtimecomposer-user-guide - - * XMOS xCORE Programming Guide - - http://www.xmos.com/published/xmos-programming-guide - - * XMOS Layer 2 Ethernet MAC Component - - https://www.xmos.com/published/xmos-layer-2-ethernet-mac-component - - * IEEE 802.3 Ethernet Standards - - http://standards.ieee.org/about/get/802/802.3.html - - * Ethernet Basics - - http://homepage.smc.edu/morgan_david/linux/n-protocol-09-ethernet.pdf - - * Ethernet Frame - - http://en.wikipedia.org/wiki/Ethernet_frame - - * Ethernet Timestamps - - http://m.eetindia.co.in/STATIC/PDF/200906/EEIOL_2009JUN03_NETD_TA_01.pdf?SOURCES=DOWNLOAD - - * MAC address - - http://en.wikipedia.org/wiki/MAC_address - - * Ethernet Type - - http://en.wikipedia.org/wiki/EtherType - - * Internet Control Message Protocol - - http://en.wikipedia.org/wiki/Internet_Control_Message_Protocol - -|newpage| - -Full Source code listing -------------------------- - -Source code for main.xc -....................... - -.. literalinclude:: main.xc - :largelisting: - -Source code for icmp.xc -........................... - -.. literalinclude:: icmp.xc - :largelisting: - -|newpage| - diff --git a/examples/AN00120_100Mbit_ethernet_demo/doc/rst/images/Makefile b/examples/AN00120_100Mbit_ethernet_demo/doc/rst/images/Makefile deleted file mode 100644 index fddcef82..00000000 --- a/examples/AN00120_100Mbit_ethernet_demo/doc/rst/images/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -ODGS = $(wildcard *.odg) -PDFS = $(ODGS:.odg=.pdf) - -all: $(PDFS) - @echo PDFs created - -_uncropped: - mkdir _uncropped - -_uncropped/%.pdf: %.odg | _uncropped - soffice -env:UserInstallation=file:///home/$(USER)/.libreoffice-alt --headless --convert-to pdf $< --outdir _uncropped - -%.pdf: _uncropped/%.pdf - pdfcrop $< $@ - -clean: - -rm $(PDFS) - -rm _uncropped/*.pdf - -rmdir _uncropped diff --git a/examples/AN00120_100Mbit_ethernet_demo/doc/rst/images/Target_IO_JTAG.png b/examples/AN00120_100Mbit_ethernet_demo/doc/rst/images/Target_IO_JTAG.png deleted file mode 100644 index 5134f5ec..00000000 Binary files a/examples/AN00120_100Mbit_ethernet_demo/doc/rst/images/Target_IO_JTAG.png and /dev/null differ diff --git a/examples/AN00120_100Mbit_ethernet_demo/doc/rst/images/block_diag.odg b/examples/AN00120_100Mbit_ethernet_demo/doc/rst/images/block_diag.odg deleted file mode 100644 index 396f2fc5..00000000 Binary files a/examples/AN00120_100Mbit_ethernet_demo/doc/rst/images/block_diag.odg and /dev/null differ diff --git a/examples/AN00120_100Mbit_ethernet_demo/doc/rst/images/block_diag.pdf b/examples/AN00120_100Mbit_ethernet_demo/doc/rst/images/block_diag.pdf deleted file mode 100644 index 0de4009b..00000000 Binary files a/examples/AN00120_100Mbit_ethernet_demo/doc/rst/images/block_diag.pdf and /dev/null differ diff --git a/examples/AN00120_100Mbit_ethernet_demo/doc/rst/images/ethernet_mii_mac_layers.png b/examples/AN00120_100Mbit_ethernet_demo/doc/rst/images/ethernet_mii_mac_layers.png deleted file mode 100644 index 26877b0c..00000000 Binary files a/examples/AN00120_100Mbit_ethernet_demo/doc/rst/images/ethernet_mii_mac_layers.png and /dev/null differ diff --git a/examples/AN00120_100Mbit_ethernet_demo/doc/rst/images/full_implementation_block_dia.png b/examples/AN00120_100Mbit_ethernet_demo/doc/rst/images/full_implementation_block_dia.png deleted file mode 100644 index 6cf232ed..00000000 Binary files a/examples/AN00120_100Mbit_ethernet_demo/doc/rst/images/full_implementation_block_dia.png and /dev/null differ diff --git a/examples/AN00120_100Mbit_ethernet_demo/doc/rst/images/hardware_setup.png b/examples/AN00120_100Mbit_ethernet_demo/doc/rst/images/hardware_setup.png deleted file mode 100644 index 6f858fdc..00000000 Binary files a/examples/AN00120_100Mbit_ethernet_demo/doc/rst/images/hardware_setup.png and /dev/null differ diff --git a/examples/AN00120_100Mbit_ethernet_demo/doc/rst/images/host_ping_response.png b/examples/AN00120_100Mbit_ethernet_demo/doc/rst/images/host_ping_response.png deleted file mode 100644 index d799a4ca..00000000 Binary files a/examples/AN00120_100Mbit_ethernet_demo/doc/rst/images/host_ping_response.png and /dev/null differ diff --git a/examples/AN00120_100Mbit_ethernet_demo/doc/rst/images/ping_response.jpg b/examples/AN00120_100Mbit_ethernet_demo/doc/rst/images/ping_response.jpg deleted file mode 100644 index fca7c496..00000000 Binary files a/examples/AN00120_100Mbit_ethernet_demo/doc/rst/images/ping_response.jpg and /dev/null differ diff --git a/examples/AN00120_100Mbit_ethernet_demo/doc/rst/xdoc.conf b/examples/AN00120_100Mbit_ethernet_demo/doc/rst/xdoc.conf deleted file mode 100644 index cb5aab68..00000000 --- a/examples/AN00120_100Mbit_ethernet_demo/doc/rst/xdoc.conf +++ /dev/null @@ -1,2 +0,0 @@ -XMOSNEWSTYLE=1 -SOURCE_INCLUDE_DIRS=../../src diff --git a/examples/AN00120_100Mbit_ethernet_demo/src/config.xscope b/examples/AN00120_100Mbit_ethernet_demo/src/config.xscope deleted file mode 100644 index 1cef58cc..00000000 --- a/examples/AN00120_100Mbit_ethernet_demo/src/config.xscope +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/examples/AN00120_100Mbit_ethernet_demo/src/icmp.h b/examples/AN00120_100Mbit_ethernet_demo/src/icmp.h deleted file mode 100644 index afa69f1d..00000000 --- a/examples/AN00120_100Mbit_ethernet_demo/src/icmp.h +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2013-2021 XMOS LIMITED. -// This Software is subject to the terms of the XMOS Public Licence: Version 1. -#ifndef __icmp_h__ -#define __icmp_h__ -#include -#include - - -[[combinable]] -void icmp_server(client ethernet_cfg_if cfg, - client ethernet_rx_if rx, - client ethernet_tx_if tx, - const unsigned char ip_address[4], - otp_ports_t &otp_ports); - -#endif // __icmp_h__ diff --git a/examples/AN00120_100Mbit_ethernet_demo/src/icmp.xc b/examples/AN00120_100Mbit_ethernet_demo/src/icmp.xc deleted file mode 100644 index ab727060..00000000 --- a/examples/AN00120_100Mbit_ethernet_demo/src/icmp.xc +++ /dev/null @@ -1,298 +0,0 @@ -// Copyright 2013-2021 XMOS LIMITED. -// This Software is subject to the terms of the XMOS Public Licence: Version 1. -#include -#include -#include -#include -#include -#include - -static unsigned short checksum_ip(const unsigned char frame[34]) -{ - int i; - unsigned accum = 0; - - for (i = 14; i < 34; i += 2) - { - accum += *((const uint16_t*)(frame + i)); - } - - // Fold carry into 16bits - while (accum >> 16) - { - accum = (accum & 0xFFFF) + (accum >> 16); - } - - accum = byterev(~accum) >> 16; - - return accum; -} - - -static int build_arp_response(unsigned char rxbuf[64], - unsigned char txbuf[64], - const unsigned char own_mac_addr[MACADDR_NUM_BYTES], - const unsigned char own_ip_addr[4]) -{ - unsigned word; - unsigned char byte; - - for (int i = 0; i < MACADDR_NUM_BYTES; i++) - { - byte = rxbuf[22+i]; - txbuf[i] = byte; - txbuf[32 + i] = byte; - } - word = ((const unsigned int *) rxbuf)[7]; - for (int i = 0; i < 4; i++) - { - txbuf[38 + i] = word & 0xFF; - word >>= 8; - } - - txbuf[28] = own_ip_addr[0]; - txbuf[29] = own_ip_addr[1]; - txbuf[30] = own_ip_addr[2]; - txbuf[31] = own_ip_addr[3]; - - for (int i = 0; i < MACADDR_NUM_BYTES; i++) - { - txbuf[22 + i] = own_mac_addr[i]; - txbuf[6 + i] = own_mac_addr[i]; - } - txbuf[12] = 0x08; - txbuf[13] = 0x06; - txbuf[14] = 0x00; - txbuf[15] = 0x01; - txbuf[16] = 0x08; - txbuf[17] = 0x00; - txbuf[18] = 0x06; - txbuf[19] = 0x04; - txbuf[20] = 0x00; - txbuf[21] = 0x02; - - // Typically 48 bytes (94 for IPv6) - for (int i = 42; i < 64; i++) - { - txbuf[i] = 0x00; - } - - return 64; -} - - -static int is_valid_arp_packet(const unsigned char rxbuf[nbytes], - unsigned nbytes, - const unsigned char own_ip_addr[4]) -{ - if (rxbuf[12] != 0x08 || rxbuf[13] != 0x06) - return 0; - - debug_printf("ARP packet received\n"); - - if (((const unsigned int *) rxbuf)[3] != 0x01000608) - { - debug_printf("Invalid et_htype\n"); - return 0; - } - if (((const unsigned int *) rxbuf)[4] != 0x04060008) - { - debug_printf("Invalid ptype_hlen\n"); - return 0; - } - if ((((const unsigned int *) rxbuf)[5] & 0xFFFF) != 0x0100) - { - debug_printf("Not a request\n"); - return 0; - } - for (int i = 0; i < 4; i++) - { - if (rxbuf[38 + i] != own_ip_addr[i]) - { - debug_printf("Not for us\n"); - return 0; - } - } - - return 1; -} - - -static int build_icmp_response(unsigned char rxbuf[], unsigned char txbuf[], - const unsigned char own_mac_addr[MACADDR_NUM_BYTES], - const unsigned char own_ip_addr[4]) -{ - unsigned icmp_checksum; - int datalen; - int totallen; - const int ttl = 0x40; - int pad; - - // Precomputed empty IP header checksum (inverted, bytereversed and shifted right) - unsigned ip_checksum = 0x0185; - - for (int i = 0; i < MACADDR_NUM_BYTES; i++) - { - txbuf[i] = rxbuf[6 + i]; - } - for (int i = 0; i < 4; i++) - { - txbuf[30 + i] = rxbuf[26 + i]; - } - icmp_checksum = byterev(((const unsigned int *) rxbuf)[9]) >> 16; - for (int i = 0; i < 4; i++) - { - txbuf[38 + i] = rxbuf[38 + i]; - } - totallen = byterev(((const unsigned int *) rxbuf)[4]) >> 16; - datalen = totallen - 28; - for (int i = 0; i < datalen; i++) - { - txbuf[42 + i] = rxbuf[42+i]; - } - - for (int i = 0; i < MACADDR_NUM_BYTES; i++) - { - txbuf[6 + i] = own_mac_addr[i]; - } - ((unsigned int *) txbuf)[3] = 0x00450008; - totallen = byterev(28 + datalen) >> 16; - ((unsigned int *) txbuf)[4] = totallen; - ip_checksum += totallen; - ((unsigned int *) txbuf)[5] = 0x01000000 | (ttl << 16); - ((unsigned int *) txbuf)[6] = 0; - for (int i = 0; i < 4; i++) - { - txbuf[26 + i] = own_ip_addr[i]; - } - ip_checksum += (own_ip_addr[0] | own_ip_addr[1] << 8); - ip_checksum += (own_ip_addr[2] | own_ip_addr[3] << 8); - ip_checksum += txbuf[30] | (txbuf[31] << 8); - ip_checksum += txbuf[32] | (txbuf[33] << 8); - - txbuf[34] = 0x00; - txbuf[35] = 0x00; - - icmp_checksum = (icmp_checksum + 0x0800); - icmp_checksum += icmp_checksum >> 16; - txbuf[36] = icmp_checksum >> 8; - txbuf[37] = icmp_checksum & 0xFF; - - while (ip_checksum >> 16) - { - ip_checksum = (ip_checksum & 0xFFFF) + (ip_checksum >> 16); - } - ip_checksum = byterev(~ip_checksum) >> 16; - txbuf[24] = ip_checksum >> 8; - txbuf[25] = ip_checksum & 0xFF; - - for (pad = 42 + datalen; pad < 64; pad++) - { - txbuf[pad] = 0x00; - } - return pad; -} - - -static int is_valid_icmp_packet(const unsigned char rxbuf[nbytes], - unsigned nbytes, - const unsigned char own_ip_addr[4]) -{ - unsigned totallen; - if (rxbuf[23] != 0x01) - return 0; - - debug_printf("ICMP packet received\n"); - - if (((const unsigned int *) rxbuf)[3] != 0x00450008) - { - debug_printf("Invalid et_ver_hdrl_tos\n"); - return 0; - } - if ((((const unsigned int *) rxbuf)[8] >> 16) != 0x0008) - { - debug_printf("Invalid type_code\n"); - return 0; - } - for (int i = 0; i < 4; i++) - { - if (rxbuf[30 + i] != own_ip_addr[i]) - { - debug_printf("Not for us\n"); - return 0; - } - } - - totallen = byterev(((const unsigned int *) rxbuf)[4]) >> 16; - if (nbytes > 60 && nbytes != totallen + 14) - { - debug_printf("Invalid size (nbytes:%d, totallen:%d)\n", nbytes, totallen+14); - return 0; - } - if (checksum_ip(rxbuf) != 0) - { - debug_printf("Bad checksum\n"); - return 0; - } - - return 1; -} - -[[combinable]] -void icmp_server(client ethernet_cfg_if cfg, - client ethernet_rx_if rx, - client ethernet_tx_if tx, - const unsigned char ip_address[4], - otp_ports_t &otp_ports) -{ - unsigned char mac_address[MACADDR_NUM_BYTES]; - ethernet_macaddr_filter_t macaddr_filter; - - // Get the mac address from OTP and set it in the ethernet component - otp_board_info_get_mac(otp_ports, 0, mac_address); - - size_t index = rx.get_index(); - cfg.set_macaddr(0, mac_address); - - memcpy(macaddr_filter.addr, mac_address, sizeof(mac_address)); - cfg.add_macaddr_filter(index, 0, macaddr_filter); - - // Add broadcast filter - memset(macaddr_filter.addr, 0xff, MACADDR_NUM_BYTES); - cfg.add_macaddr_filter(index, 0, macaddr_filter); - - // Only allow ARP and IP packets to the app - cfg.add_ethertype_filter(index, 0x0806); - cfg.add_ethertype_filter(index, 0x0800); - - debug_printf("Test started\n"); - while (1) - { - select { - case rx.packet_ready(): - unsigned char rxbuf[ETHERNET_MAX_PACKET_SIZE]; - unsigned char txbuf[ETHERNET_MAX_PACKET_SIZE]; - ethernet_packet_info_t packet_info; - rx.get_packet(packet_info, rxbuf, ETHERNET_MAX_PACKET_SIZE); - - if (packet_info.type != ETH_DATA) - continue; - - if (is_valid_arp_packet(rxbuf, packet_info.len, ip_address)) - { - int len = build_arp_response(rxbuf, txbuf, mac_address, ip_address); - tx.send_packet(txbuf, len, ETHERNET_ALL_INTERFACES); - debug_printf("ARP response sent\n"); - } - else if (is_valid_icmp_packet(rxbuf, packet_info.len, ip_address)) - { - int len = build_icmp_response(rxbuf, txbuf, mac_address, ip_address); - tx.send_packet(txbuf, len, ETHERNET_ALL_INTERFACES); - debug_printf("ICMP response sent\n"); - } - break; - } - } -} - - diff --git a/examples/AN00120_100Mbit_ethernet_demo/src/main.xc b/examples/AN00120_100Mbit_ethernet_demo/src/main.xc deleted file mode 100644 index a56942cc..00000000 --- a/examples/AN00120_100Mbit_ethernet_demo/src/main.xc +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2014-2021 XMOS LIMITED. -// This Software is subject to the terms of the XMOS Public Licence: Version 1. -#include -#include -#include "otp_board_info.h" -#include "ethernet.h" -#include "icmp.h" -#include "smi.h" - - -port p_eth_rxclk = PORT_ETH_RXCLK; -port p_eth_rxd = PORT_ETH_RXD; -port p_eth_txd = PORT_ETH_TXD; -port p_eth_rxdv = PORT_ETH_RXDV; -port p_eth_txen = PORT_ETH_TXEN; -port p_eth_txclk = PORT_ETH_TXCLK; -port p_eth_rxerr = PORT_ETH_RXER; -port p_eth_dummy = on tile[1]: XS1_PORT_8C; - -clock eth_rxclk = on tile[1]: XS1_CLKBLK_1; -clock eth_txclk = on tile[1]: XS1_CLKBLK_2; - -port p_smi_mdio = PORT_SMI_MDIO; -port p_smi_mdc = PORT_SMI_MDC; - - -// These ports are for accessing the OTP memory -otp_ports_t otp_ports = on tile[0]: OTP_PORTS_INITIALIZER; - -static unsigned char ip_address[4] = {192, 168, 1, 178}; - -// An enum to manage the array of connections from the ethernet component -// to its clients. -enum eth_clients { - ETH_TO_ICMP, - NUM_ETH_CLIENTS -}; - -enum cfg_clients { - CFG_TO_ICMP, - CFG_TO_PHY_DRIVER, - NUM_CFG_CLIENTS -}; - -[[combinable]] -void lan8710a_phy_driver(client interface smi_if smi, - client interface ethernet_cfg_if eth) { - ethernet_link_state_t link_state = ETHERNET_LINK_DOWN; - ethernet_speed_t link_speed = LINK_100_MBPS_FULL_DUPLEX; - const int link_poll_period_ms = 1000; - const int phy_address = 0x0; - timer tmr; - int t; - tmr :> t; - - while (smi_phy_is_powered_down(smi, phy_address)); - smi_configure(smi, phy_address, LINK_100_MBPS_FULL_DUPLEX, SMI_ENABLE_AUTONEG); - - while (1) { - select { - case tmr when timerafter(t) :> t: - ethernet_link_state_t new_state = smi_get_link_state(smi, phy_address); - // Read LAN8710A status register bit 2 to get the current link speed - if ((new_state == ETHERNET_LINK_UP) && - ((smi.read_reg(phy_address, 0x1F) >> 2) & 1)) { - link_speed = LINK_10_MBPS_FULL_DUPLEX; - } - else { - link_speed = LINK_100_MBPS_FULL_DUPLEX; - } - if (new_state != link_state) { - link_state = new_state; - eth.set_link_state(0, new_state, link_speed); - } - t += link_poll_period_ms * XS1_TIMER_KHZ; - break; - } - } -} - -#define ETH_RX_BUFFER_SIZE_WORDS 1600 - -int main() -{ - ethernet_cfg_if i_cfg[NUM_CFG_CLIENTS]; - ethernet_rx_if i_rx[NUM_ETH_CLIENTS]; - ethernet_tx_if i_tx[NUM_ETH_CLIENTS]; - smi_if i_smi; - - par { - on tile[1]: mii_ethernet_mac(i_cfg, NUM_CFG_CLIENTS, - i_rx, NUM_ETH_CLIENTS, - i_tx, NUM_ETH_CLIENTS, - p_eth_rxclk, p_eth_rxerr, - p_eth_rxd, p_eth_rxdv, - p_eth_txclk, p_eth_txen, p_eth_txd, - p_eth_dummy, - eth_rxclk, eth_txclk, - ETH_RX_BUFFER_SIZE_WORDS); - - on tile[1]: lan8710a_phy_driver(i_smi, i_cfg[CFG_TO_PHY_DRIVER]); - - on tile[1]: smi(i_smi, p_smi_mdio, p_smi_mdc); - - on tile[0]: icmp_server(i_cfg[CFG_TO_ICMP], - i_rx[ETH_TO_ICMP], i_tx[ETH_TO_ICMP], - ip_address, otp_ports); - } - return 0; -} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index fa586c2b..958176eb 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -18,4 +18,5 @@ add_subdirectory(test_vlan_strip) add_subdirectory(test_speed_change) add_subdirectory(test_rx_queues) add_subdirectory(test_check_ifg_wait) +add_subdirectory(test_rmii_timing) diff --git a/tests/test_rmii_timing.py b/tests/test_rmii_timing.py new file mode 100644 index 00000000..c05e32e2 --- /dev/null +++ b/tests/test_rmii_timing.py @@ -0,0 +1,68 @@ +# Copyright 2014-2024 XMOS LIMITED. +# This Software is subject to the terms of the XMOS Public Licence: Version 1. + +import random +import Pyxsim as px +from pathlib import Path +import pytest +import sys + +from mii_packet import MiiPacket +from mii_clock import Clock +from helpers import do_rx_test, packet_processing_time, get_dut_mac_address +from helpers import choose_small_frame_size, check_received_packet, run_parametrised_test_rx +from helpers import generate_tests + +class TxError(px.SimThread): + + def __init__(self, tx_phy, do_error): + self._tx_phy = tx_phy + self._do_error = do_error + self._initial_delay = tx_phy._initial_delay - 5000*1e6 + + def run(self): + xsi = self.xsi + + if not self._do_error: + return + + self.wait_until(xsi.get_time() + self._initial_delay) + self._tx_phy.drive_error(1) + self.wait_until(xsi.get_time() + 100*1e6) + self._tx_phy.drive_error(0) + +""" +This runs the device at 350MHz with 5 threads so max 70MHz per thread which gives us a little +headroom for a typical operating rate of 600MHz with 8 threads (75MHz min) +rx1b and rx4b are the hardest cases. CUrrently these break at 300MHz (310 OK) so we are well withing timing +""" +def do_test(capfd, mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, seed, rx_width=None, tx_width=None): + rand = random.Random() + rand.seed(seed) + + dut_mac_address = get_dut_mac_address() + broadcast_mac_address = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff] + + packets = [] + + # Send frames which excercise all of the tail length vals (0, 1, 2, 3 bytes) + packet_start_len = 100 + for i in range(5): + packets.append(MiiPacket(rand, + dst_mac_addr=dut_mac_address, + create_data_args=['step', (i, packet_start_len)], + inter_frame_gap=packet_processing_time(tx_phy, packet_start_len, mac), + )) + + do_rx_test(capfd, mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, __file__, seed, rx_width=rx_width, tx_width=tx_width) + +test_params_file = Path(__file__).parent / "test_rmii_timing/test_params.json" +@pytest.mark.parametrize("params", generate_tests(test_params_file)[0], ids=generate_tests(test_params_file)[1]) +def test_rx(capfd, seed, params): + with capfd.disabled(): + print(params) + + if seed == None: + seed = random.randint(0, sys.maxsize) + + run_parametrised_test_rx(capfd, do_test, params, seed=seed) diff --git a/tests/test_rmii_timing/CMakeLists.txt b/tests/test_rmii_timing/CMakeLists.txt new file mode 100644 index 00000000..b8e48af2 --- /dev/null +++ b/tests/test_rmii_timing/CMakeLists.txt @@ -0,0 +1,85 @@ +cmake_minimum_required(VERSION 3.21) +include($ENV{XMOS_CMAKE_PATH}/xcommon.cmake) +project(test_rmii_timing) + +include(../helpers.cmake) +include(../test_deps.cmake) + +set(APP_PCA_ENABLE ON) + +file(GLOB_RECURSE SOURCES_XC RELATIVE ${CMAKE_CURRENT_LIST_DIR} "src/*.xc") +set(APP_XC_SRCS ${SOURCES_XC}) +set(APP_INCLUDES ../include src) + +set(COMPILER_FLAGS_COMMON -g + -report + -DDEBUG_PRINT_ENABLE=1 + -Os) + +set(XMOS_SANDBOX_DIR ${CMAKE_CURRENT_LIST_DIR}/../../..) + + +file(READ ${CMAKE_CURRENT_LIST_DIR}/test_params.json JSON_CONTENT) +get_json_list(${JSON_CONTENT} PROFILES profile_list) + +set(done_configs "") +foreach(PROFILE ${profile_list}) + get_json_list(${PROFILE} arch arch_list) # Get archs to build for, for this particular profile + foreach(arch ${arch_list}) + string(JSON phy GET ${PROFILE} phy) + string(JSON mac GET ${PROFILE} mac) + + set(config "${mac}_${phy}") + string(FIND ${PROFILE} "rx_width" rx_width_found) + if(rx_width_found GREATER -1) + string(JSON rx_width GET ${PROFILE} rx_width) + set(config "${config}_rx${rx_width}") + endif() + string(FIND ${PROFILE} "tx_width" tx_width_found) + if(rx_width_found GREATER -1) + string(JSON tx_width GET ${PROFILE} tx_width) + set(config "${config}_tx${tx_width}") + endif() + set(config "${config}_${arch}") + + list (FIND done_configs ${config} _index) + if(${_index} EQUAL -1) # Only build if it is a new config + list(APPEND done_configs ${config}) + message(STATUS "Building cfg_name: ${config}") + + set(APP_HW_TARGET src/XCORE-AI-EXPLORER-350.xn) + + set(APP_COMPILER_FLAGS_${config} ${COMPILER_FLAGS_COMMON}) + + set_app_rx_width(rx_width) + + set_app_tx_width(tx_width) + + string(FIND "${PROFILE}" "rt" position) + if(position GREATER -1) + list(APPEND APP_COMPILER_FLAGS_${config} -DRT=1) + else() + list(APPEND APP_COMPILER_FLAGS_${config} -DRT=0) + endif() + + string(FIND "${PROFILE}" "hp" position) + if(position GREATER -1) + list(APPEND APP_COMPILER_FLAGS_${config} -DETHERNET_SUPPORT_HP_QUEUES=1) + else() + list(APPEND APP_COMPILER_FLAGS_${config} -DETHERNET_SUPPORT_HP_QUEUES=0) + endif() + + if(${phy} MATCHES "rgmii") + list(APPEND APP_COMPILER_FLAGS_${config} -DRGMII=1) + elseif(${phy} MATCHES "rmii")# + list(APPEND APP_COMPILER_FLAGS_${config} -DRMII=1) + elseif(${phy} MATCHES "mii") + list(APPEND APP_COMPILER_FLAGS_${config} -DMII=1) + endif() + + XMOS_REGISTER_APP() + unset(APP_COMPILER_FLAGS_${config}) + endif() # if(${_index} equal -1) # New config + endforeach() # foreach(arch ${arch_list}) + unset(arch_list) +endforeach() # foreach(PROFILE ${profile_list}) diff --git a/tests/test_rmii_timing/src/XCORE-AI-EXPLORER-350.xn b/tests/test_rmii_timing/src/XCORE-AI-EXPLORER-350.xn new file mode 100644 index 00000000..3120cbad --- /dev/null +++ b/tests/test_rmii_timing/src/XCORE-AI-EXPLORER-350.xn @@ -0,0 +1,75 @@ + + + Board + xcore.ai Explorer Kit + + + tileref tile[2] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/test_rmii_timing/src/config.xscope b/tests/test_rmii_timing/src/config.xscope new file mode 100644 index 00000000..5c4b0f67 --- /dev/null +++ b/tests/test_rmii_timing/src/config.xscope @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/tests/test_rmii_timing/src/main.xc b/tests/test_rmii_timing/src/main.xc new file mode 100644 index 00000000..7853d6bd --- /dev/null +++ b/tests/test_rmii_timing/src/main.xc @@ -0,0 +1,77 @@ +// Copyright 2014-2024 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +#include +#include +#include +#include "ethernet.h" +#include "print.h" +#include "debug_print.h" +#include "syscall.h" + +#include "ports_rmii.h" + + + +void loopback(client ethernet_cfg_if cfg, + client ethernet_rx_if rx, + client ethernet_tx_if tx) +{ + set_core_fast_mode_on(); + + ethernet_macaddr_filter_t macaddr_filter; + + size_t index = rx.get_index(); + + macaddr_filter.appdata = 0; + for (int i = 0; i < 6; i++){ + macaddr_filter.addr[i] = i; + } + cfg.add_macaddr_filter(index, 0, macaddr_filter); + + // Add the broadcast MAC address + memset(macaddr_filter.addr, 0xff, 6); + cfg.add_macaddr_filter(index, 0, macaddr_filter); + + int done = 0; + while (!done) { + select { + case rx.packet_ready(): + unsigned char rxbuf[ETHERNET_MAX_PACKET_SIZE]; + ethernet_packet_info_t packet_info; + rx.get_packet(packet_info, rxbuf, ETHERNET_MAX_PACKET_SIZE); + tx.send_packet(rxbuf, packet_info.len, ETHERNET_ALL_INTERFACES); + break; + } + } +} + + +#define NUM_CFG_IF 1 +#define NUM_RX_LP_IF 1 +#define NUM_TX_LP_IF 1 + +int main() +{ + ethernet_cfg_if i_cfg[NUM_CFG_IF]; + ethernet_rx_if i_rx_lp[NUM_RX_LP_IF]; + ethernet_tx_if i_tx_lp[NUM_TX_LP_IF]; + + + par { + // 5 threads total so thread speed = f/5 + unsafe{rmii_ethernet_rt_mac(i_cfg, NUM_CFG_IF, + i_rx_lp, NUM_RX_LP_IF, + i_tx_lp, NUM_TX_LP_IF, + NULL, NULL, + p_eth_clk, + &p_eth_rxd, p_eth_rxdv, + p_eth_txen, &p_eth_txd, + eth_rxclk, eth_txclk, + 4000, 4000, ETHERNET_DISABLE_SHAPER);} + loopback(i_cfg[0], i_rx_lp[0], i_tx_lp[0]); + + } + return 0; +} + diff --git a/tests/test_rmii_timing/test_params.json b/tests/test_rmii_timing/test_params.json new file mode 100644 index 00000000..5e66e0ea --- /dev/null +++ b/tests/test_rmii_timing/test_params.json @@ -0,0 +1,15 @@ +{ + "PROFILES": [ + {"phy":"rmii", "mac":"rt", "arch":["xs3"], "rx_width":"4b_lower", "tx_width":"4b_lower"}, + {"phy":"rmii", "mac":"rt", "arch":["xs3"], "rx_width":"4b_upper", "tx_width":"4b_lower"}, + {"phy":"rmii", "mac":"rt", "arch":["xs3"], "rx_width":"1b", "tx_width":"4b_lower"}, + + {"phy":"rmii", "mac":"rt", "arch":["xs3"], "rx_width":"4b_lower", "tx_width":"4b_upper"}, + {"phy":"rmii", "mac":"rt", "arch":["xs3"], "rx_width":"4b_upper", "tx_width":"4b_upper"}, + {"phy":"rmii", "mac":"rt", "arch":["xs3"], "rx_width":"1b", "tx_width":"4b_upper"}, + + {"phy":"rmii", "mac":"rt", "arch":["xs3"], "rx_width":"4b_lower", "tx_width":"1b"}, + {"phy":"rmii", "mac":"rt", "arch":["xs3"], "rx_width":"4b_upper", "tx_width":"1b"}, + {"phy":"rmii", "mac":"rt", "arch":["xs3"], "rx_width":"1b", "tx_width":"1b"} + ] +}