diff options
author | Martin Braun <martin.braun@ettus.com> | 2018-05-31 10:06:30 -0700 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2018-06-04 13:53:43 -0700 |
commit | a368f91cdc59797391f9328e289cd67fed6c5ac4 (patch) | |
tree | b7e356b957e312953d4b3e6f2ed1f99fa0053fa3 | |
parent | 2b6046fb33e8f1d5f76766ed60d658027c6b45e9 (diff) | |
download | uhd-a368f91cdc59797391f9328e289cd67fed6c5ac4.tar.gz uhd-a368f91cdc59797391f9328e289cd67fed6c5ac4.tar.bz2 uhd-a368f91cdc59797391f9328e289cd67fed6c5ac4.zip |
tools: Add a script for automated testing of FPGAFUNCVERIF
-rw-r--r-- | host/docs/rd_testing.dox | 83 | ||||
-rwxr-xr-x | tools/gr-usrptest/apps/usrp_fpga_funcverif.py | 519 |
2 files changed, 593 insertions, 9 deletions
diff --git a/host/docs/rd_testing.dox b/host/docs/rd_testing.dox index f12244f2f..1b0e65aa9 100644 --- a/host/docs/rd_testing.dox +++ b/host/docs/rd_testing.dox @@ -322,8 +322,10 @@ tbd | FPGAFUNCVERIF-X300-XG-v1 | USRP X300 | 2x UBX | \ref rdtesting_fpgafuncverif_manual | \ref rdtesting_fpgafuncverif_auto | | FPGAFUNCVERIF-E310-SG1-v1 | USRP E310 SG1 | None | \ref rdtesting_fpgafuncverif_manual | \ref rdtesting_fpgafuncverif_auto | | FPGAFUNCVERIF-E310-SG3-v1 | USRP E310 SG3 | None | \ref rdtesting_fpgafuncverif_manual | \ref rdtesting_fpgafuncverif_auto | -| FPGAFUNCVERIF-N310-v1 | USRP N310 | None | \ref rdtesting_fpgafuncverif_manual | \ref rdtesting_fpgafuncverif_auto | -| FPGAFUNCVERIF-N300-v1 | USRP N300 | None | \ref rdtesting_fpgafuncverif_manual | \ref rdtesting_fpgafuncverif_auto | +| FPGAFUNCVERIF-N310-HG-v1 | USRP N310 | None | \ref rdtesting_fpgafuncverif_manual | \ref rdtesting_fpgafuncverif_auto | +| FPGAFUNCVERIF-N310-XG-v1 | USRP N310 | None | \ref rdtesting_fpgafuncverif_manual | \ref rdtesting_fpgafuncverif_auto | +| FPGAFUNCVERIF-N300-HG-v1 | USRP N300 | None | \ref rdtesting_fpgafuncverif_manual | \ref rdtesting_fpgafuncverif_auto | +| FPGAFUNCVERIF-N300-XG-v1 | USRP N300 | None | \ref rdtesting_fpgafuncverif_manual | \ref rdtesting_fpgafuncverif_auto | The FPGA functional verification tests exercise the Digital Downconverter (DDC), Digital Upconverter (DUC), and Radio Core RFNoC blocks. @@ -435,6 +437,7 @@ Note: On TX tests, initial Us within the first 5 seconds can be ignored and do n - Required images to test: HG - Note: On TX tests, initial Us within the first 5 seconds can be ignored and do not fail the test +<!--Note: If you change this table, also change tools/gr-usrptest/apps/usrp_fpga_funcverif.py!--> | Channels | Master Clock Rate | Sample Rates | Duration | Notes | |---------------|-------------------|-------------------------|----------|-----------------------------------| | 1x RX | 125e6 | 1.25e6 | 60 | One test each for all 4 channels | @@ -458,14 +461,27 @@ Note: On TX tests, initial Us within the first 5 seconds can be ignored and do n - Required images to test: N310 HG + XG - Note: On TX tests, initial Us within the first 5 seconds can be ignored and do not fail the test +<!--Note: If you change this table, also change tools/gr-usrptest/apps/usrp_fpga_funcverif.py!--> | Channels | Master Clock Rate | Sample Rates | Duration | Notes | |---------------|-------------------|-------------------------|----------|-----------------------------------| | 1x RX | 125e6 | 1.25e6, 125e6 | 60 | One test each for all 4 channels | | 1x RX | 122.88e6 | 1.2288e6, 122.88e6 | 60 | One test each for all 4 channels | | 1x RX | 153.6e6 | 1.536e6, 153.6e6 | 60 | One test each for all 4 channels | -| 2/3/4x RX | 125e6 | 1.25e6 | 60 | 3 tests total | -| 2/3/4x RX | 122.88e6 | 1.2288e6 | 60 | 3 tests total | -| 2/3/4x RX | 153.6e6 | 1.536e6 | 60 | 3 tests total | +| 1x TX | 125e6 | 1.25e6, 125e6 | 60 | One test each for all 4 channels | +| 1x TX | 122.88e6 | 1.2288e6, 122.88e6 | 60 | One test each for all 4 channels | +| 1x TX | 153.6e6 | 1.536e6, 153.6e6 | 60 | One test each for all 4 channels | +| 2x RX | 125e6 | 1.25e6, 125e6 | 60 | | +| 2x RX | 122.88e6 | 1.2288e6, 122.88e6 | 60 | | +| 2x RX | 153.6e6 | 1.536e6, 153.6e6 | 60 | | +| 3x RX | 125e6 | 1.25e6 | 60 | N310 only | +| 3x RX | 122.88e6 | 1.2288e6 | 60 | N310 only | +| 3x RX | 153.6e6 | 1.536e6 | 60 | N310 only | +| 2x TX | 125e6 | 1.25e6, 12.5e6 | 60 | | +| 2x TX | 122.88e6 | 1.2288e6, 12.288e6 | 60 | | +| 2x TX | 153.6e6 | 1.536e6, 15.36e6 | 60 | | +| 3x TX | 125e6 | 1.25e6 | 60 | N310 only | +| 3x TX | 122.88e6 | 1.2288e6 | 60 | N310 only | +| 3x TX | 153.6e6 | 1.536e6 | 60 | N310 only | | 4x RX | 125e6 | 1.25e6, 62.5e6 | 60 | N310 only | 4x TX | 125e6 | 1.25e6, 12.5e6 | 60 | N310 only | 4x RX & 4x TX | 125e6 | 1.25e6, 62.5e6 | 60 | Drop to 2 channels for N300 @@ -474,13 +490,62 @@ Note: On TX tests, initial Us within the first 5 seconds can be ignored and do n | 4x RX & 4x TX | 125e6 | 62.5e6 | 3600 | Drop to 2 channels for N300 | 4x RX & 4x TX | 122.88e6 | 61.44e6 | 3600 | Drop to 2 channels for N300 | 4x RX & 4x TX | 153e6 | 76.8e6 | 3600 | Drop to 2 channels for N300 -| 4x RX & 4x TX | 125e6 | 125e6 RX, 62.5e6 TX | 60 | Use dual 10GigE, N310 only -| 4x RX & 4x TX | 122.88e6 | 122.88e6 RX, 61.44e6 TX | 60 | Use dual 10GigE, N310 only -| 4x RX & 4x TX | 153e6 | 153e6 RX, 76.8e6 TX | 60 | Use dual 10GigE, N310 only +| 4x RX & 4x TX | 125e6 | 125e6 RX, 62.5e6 TX | 60 | Use dual 10GigE, N310 XG only +| 4x RX & 4x TX | 122.88e6 | 122.88e6 RX, 61.44e6 TX | 60 | Use dual 10GigE, N310 XG only +| 4x RX & 4x TX | 153e6 | 153e6 RX, 76.8e6 TX | 60 | Use dual 10GigE, N310 XG only +| 2x RX & 2x TX | 125e6 | 125e6 RX, 62.5e6 TX | 60 | Use dual 10GigE, N300 XG only +| 2x RX & 2x TX | 122.88e6 | 122.88e6 RX, 61.44e6 TX | 60 | Use dual 10GigE, N300 XG only +| 2x RX & 2x TX | 153e6 | 153e6 RX, 76.8e6 TX | 60 | Use dual 10GigE, N300 XG only \subsection rdtesting_fpgafuncverif_auto FPGA Functional Verification: Automatic Test Procedure -tbd +In all cases, make sure UHD is compiled in 'Release' mode (highest +optimization), and that all NIC and kernel are set to optimal (CPU governor, +ring buffer settings, ...). + +### N310/N300 + +The N310/N300 tests depend slightly on the type of FPGA image to be tested. +All calls to usrp_fpga_funcverif.py need to be adapted to ensure the correct +IP addresses and paths to the examples. Also, replace n310 with n300 where +appropriate. + +#### HG + +- Connect a 1GigE cable on SFP0, and a 10 GigE cable on SFP1. +- The following commands must pass: + + $ usrp_fpga_funcverif n310_1gige -a 192.168.10.2 -p /path/to/examples + $ usrp_fpga_funcverif n310_10gige -a 192.168.20.2 -p /path/to/examples + +#### XG + +- Connect a 10GigE cable on both SFP0 and SFP1. +- The following commands must pass: + + $ usrp_fpga_funcverif n310_10gige -a 192.168.10.2 -p /path/to/examples + $ usrp_fpga_funcverif n310_10gige -a 192.168.10.2 -2 192.168.20.2 -p /path/to/examples + +#### HA + +- Connect a 1GigE cable on SFP0 +- The following command must pass: + + $ usrp_fpga_funcverif n310_1gige -a 192.168.10.2 -p /path/to/examples + +#### XA + +- Connect a 10GigE cable on SFP0 +- The following command must pass: + + $ usrp_fpga_funcverif n310_10gige -a 192.168.10.2 -p /path/to/examples + +#### WX + +- Connect a 10GigE cable on SFP1 +- The following command must pass: + + $ usrp_fpga_funcverif n310_10gige -a 192.168.20.2 -p /path/to/examples \section rdtesting_phasealignment Phase alignment tests diff --git a/tools/gr-usrptest/apps/usrp_fpga_funcverif.py b/tools/gr-usrptest/apps/usrp_fpga_funcverif.py new file mode 100755 index 000000000..2075c1fc3 --- /dev/null +++ b/tools/gr-usrptest/apps/usrp_fpga_funcverif.py @@ -0,0 +1,519 @@ +#!/usr/bin/env python +# +# Copyright 2018 Ettus Research, a National Instruments Company +# +# SPDX-License-Identifier: GPL-3.0-or-later +# +""" +Run functional verification tests. Note: Does not actually require GNU Radio. + +This is basically a fancy executor for benchmark_rate. +""" + +from __future__ import print_function +import os +import copy +import time +import argparse +import subprocess +from itertools import chain +# Python 2/3 compat hack +try: + from itertools import izip + zip = izip +except ImportError: + pass +from six import iteritems + +#### Settings dictionary ###################################################### +# This stores all the settings for the individual tests. I hope it's obvious +# how to modify/amend/read it. Comments inline: +FUNCVERIF_SETTINGS = { + # Every key corresponds to one target that can be run. The key is the + # command line argument. + 'n310_1gige': { + # These arguments will be passed to every run of benchmark_rate, unless + # overriden. + # Strings get expanded, so we can use Python string expansion here. + # If something does not start with two dashes (--foo), then we keep it + # as a string expansion argument. For example, the {master_clock_rate} + # in the following string gets expanded from the master_clock_rate key/ + # value pair further down. + '--args': "type=n3xx,addr={addr},master_clock_rate={master_clock_rate},{args}", + '--seq-threshold': 0, + '--drop-threshold': 0, + '--underrun-threshold': 100, + '--overrun-threshold': 100, + '--rx_subdev': 'A:0 A:1 B:0 B:1', + '--tx_subdev': 'A:0 A:1 B:0 B:1', + '--duration': 60, + # __tests is a special key, it contains a list of dicts, which in turn + # describe the details of the test. len(__tests) equals the number of + # tests that get executed. + '__tests': [ + # Any command line argument (i.e., a key that starts with two + # dashes) is also appended to the call to benchmark_rate. It will + # override arguments that were listed above. This lets you, e.g., + # override --duration (see further down). + {'--rx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': 0,}, + {'--rx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': 1,}, + {'--rx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': 2,}, + {'--rx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': 3,}, + + {'--rx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': 0,}, + {'--rx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': 1,}, + {'--rx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': 2,}, + {'--rx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': 3,}, + + {'--rx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': 0,}, + {'--rx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': 1,}, + {'--rx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': 2,}, + {'--rx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': 3,}, + + {'--tx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': 0,}, + {'--tx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': 1,}, + {'--tx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': 2,}, + {'--tx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': 3,}, + + {'--tx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': 0,}, + {'--tx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': 1,}, + {'--tx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': 2,}, + {'--tx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': 3,}, + + {'--tx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': 0,}, + {'--tx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': 1,}, + {'--tx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': 2,}, + {'--tx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': 3,}, + + {'--rx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': '0,1',}, + {'--rx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': '0,1',}, + {'--rx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': '0,1',}, + + {'--rx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': '0,1,2',}, + {'--rx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': '0,1,2',}, + {'--rx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': '0,1,2',}, + + {'--rx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': '0,1,2,3',}, + {'--rx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': '0,1,2,3',}, + {'--rx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': '0,1,2,3',}, + + {'--tx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': '0,1',}, + {'--tx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': '0,1',}, + {'--tx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': '0,1',}, + + {'--tx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': '0,1,2',}, + {'--tx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': '0,1,2',}, + {'--tx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': '0,1,2',}, + + {'--tx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': '0,1,2,3',}, + {'--tx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': '0,1,2,3',}, + {'--tx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': '0,1,2,3',}, + + {'--rx_rate': 1.25e6, '--tx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': '0,1,2,3',}, + {'--rx_rate': 1.2288e6, '--tx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': '0,1,2,3',}, + {'--rx_rate': 1.536e6, '--tx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': '0,1,2,3',}, + ], + }, + 'n300_1gige': { + '--args': "type=n3xx,addr={addr},master_clock_rate={master_clock_rate},{args}", + '--seq-threshold': 0, + '--drop-threshold': 0, + '--underrun-threshold': 100, + '--overrun-threshold': 100, + '--rx_subdev': 'A:0 B:0', + '--tx_subdev': 'A:0 B:0', + '--duration': 60, + '__tests': [ + {'--rx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': 0,}, + {'--rx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': 1,}, + + {'--rx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': 0,}, + {'--rx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': 1,}, + + {'--rx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': 0,}, + {'--rx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': 1,}, + + {'--tx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': 0,}, + {'--tx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': 1,}, + + {'--tx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': 0,}, + {'--tx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': 1,}, + + {'--tx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': 0,}, + {'--tx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': 1,}, + + {'--rx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': '0,1',}, + {'--rx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': '0,1',}, + {'--rx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': '0,1',}, + + {'--tx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': '0,1',}, + {'--tx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': '0,1',}, + {'--tx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': '0,1',}, + + {'--rx_rate': 1.25e6, '--tx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': '0,1',}, + {'--rx_rate': 1.2288e6, '--tx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': '0,1',}, + {'--rx_rate': 1.536e6, '--tx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': '0,1',}, + ], + }, + 'n310_10gige': { + '--args': "type=n3xx,addr={addr},master_clock_rate={master_clock_rate},{args}", + '--seq-threshold': 0, + '--drop-threshold': 0, + '--underrun-threshold': 100, + '--overrun-threshold': 100, + '--rx_subdev': 'A:0 A:1 B:0 B:1', + '--tx_subdev': 'A:0 A:1 B:0 B:1', + '--duration': 60, + '__tests': [ + {'--rx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': 0,}, + {'--rx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': 1,}, + {'--rx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': 2,}, + {'--rx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': 3,}, + + {'--rx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': 0,}, + {'--rx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': 1,}, + {'--rx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': 2,}, + {'--rx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': 3,}, + + {'--rx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': 0,}, + {'--rx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': 1,}, + {'--rx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': 2,}, + {'--rx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': 3,}, + + {'--rx_rate': 125e6, 'master_clock_rate': '125e6', '--channels': 0,}, + {'--rx_rate': 125e6, 'master_clock_rate': '125e6', '--channels': 1,}, + {'--rx_rate': 125e6, 'master_clock_rate': '125e6', '--channels': 2,}, + {'--rx_rate': 125e6, 'master_clock_rate': '125e6', '--channels': 3,}, + + {'--rx_rate': 122.88e6, 'master_clock_rate': '122.88e6', '--channels': 0,}, + {'--rx_rate': 122.88e6, 'master_clock_rate': '122.88e6', '--channels': 1,}, + {'--rx_rate': 122.88e6, 'master_clock_rate': '122.88e6', '--channels': 2,}, + {'--rx_rate': 122.88e6, 'master_clock_rate': '122.88e6', '--channels': 3,}, + + {'--rx_rate': 153.6e6, 'master_clock_rate': '153.6e6', '--channels': 0,}, + {'--rx_rate': 153.6e6, 'master_clock_rate': '153.6e6', '--channels': 1,}, + {'--rx_rate': 153.6e6, 'master_clock_rate': '153.6e6', '--channels': 2,}, + {'--rx_rate': 153.6e6, 'master_clock_rate': '153.6e6', '--channels': 3,}, + + {'--tx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': 0,}, + {'--tx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': 1,}, + {'--tx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': 2,}, + {'--tx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': 3,}, + + {'--tx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': 0,}, + {'--tx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': 1,}, + {'--tx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': 2,}, + {'--tx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': 3,}, + + {'--tx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': 0,}, + {'--tx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': 1,}, + {'--tx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': 2,}, + {'--tx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': 3,}, + + {'--tx_rate': 125e6, 'master_clock_rate': '125e6', '--channels': 0,}, + {'--tx_rate': 125e6, 'master_clock_rate': '125e6', '--channels': 1,}, + {'--tx_rate': 125e6, 'master_clock_rate': '125e6', '--channels': 2,}, + {'--tx_rate': 125e6, 'master_clock_rate': '125e6', '--channels': 3,}, + + {'--tx_rate': 122.88e6, 'master_clock_rate': '122.88e6', '--channels': 0,}, + {'--tx_rate': 122.88e6, 'master_clock_rate': '122.88e6', '--channels': 1,}, + {'--tx_rate': 122.88e6, 'master_clock_rate': '122.88e6', '--channels': 2,}, + {'--tx_rate': 122.88e6, 'master_clock_rate': '122.88e6', '--channels': 3,}, + + {'--tx_rate': 153.6e6, 'master_clock_rate': '153.6e6', '--channels': 0,}, + {'--tx_rate': 153.6e6, 'master_clock_rate': '153.6e6', '--channels': 1,}, + {'--tx_rate': 153.6e6, 'master_clock_rate': '153.6e6', '--channels': 2,}, + {'--tx_rate': 153.6e6, 'master_clock_rate': '153.6e6', '--channels': 3,}, + + {'--rx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': '0,2',}, + {'--rx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': '0,2',}, + {'--rx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': '0,2',}, + + {'--rx_rate': 125e6, 'master_clock_rate': '125e6', '--channels': '0,2',}, + {'--rx_rate': 122.88e6, 'master_clock_rate': '122.88e6', '--channels': '0,2',}, + {'--rx_rate': 153.6e6, 'master_clock_rate': '153.6e6', '--channels': '0,2',}, + + {'--rx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': '0,1,2',}, + {'--rx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': '0,1,2',}, + {'--rx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': '0,1,2',}, + + {'--rx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': '0,1,2,3',}, + {'--rx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': '0,1,2,3',}, + {'--rx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': '0,1,2,3',}, + + # | 2x TX | 125e6 | 1.25e6, 12.5e6 | 60 + # | 2x TX | 122.88e6 | 1.2288e6, 12.288e6 | 60 + # | 2x TX | 153.6e6 | 1.536e6, 15.36e6 | 60 + {'--tx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': '0,2',}, + {'--tx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': '0,2',}, + {'--tx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': '0,2',}, + + {'--tx_rate': 12.5e6, 'master_clock_rate': '125e6', '--channels': '0,2',}, + {'--tx_rate': 12.288e6, 'master_clock_rate': '122.88e6', '--channels': '0,2',}, + {'--tx_rate': 15.36e6, 'master_clock_rate': '153.6e6', '--channels': '0,2',}, + + # | 3x TX | 125e6 | 1.25e6 | 60 + # | 3x TX | 122.88e6 | 1.2288e6 | 60 + # | 3x TX | 153.6e6 | 1.536e6 | 60 + {'--tx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': '0,1,2',}, + {'--tx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': '0,1,2',}, + {'--tx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': '0,1,2',}, + + # | 4x RX | 125e6 | 1.25e6, 62.5e6 | 60 + {'--rx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': '0,1,2',}, + {'--rx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': '0,1,2',}, + {'--rx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': '0,1,2',}, + + {'--rx_rate': 62.5e6, 'master_clock_rate': '125e6', '--channels': '0,1,2',}, + {'--rx_rate': 61.44e6, 'master_clock_rate': '122.88e6', '--channels': '0,1,2',}, + {'--rx_rate': 76.8e6, 'master_clock_rate': '153.6e6', '--channels': '0,1,2',}, +# + {'--tx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': '0,1,2,3',}, + {'--tx_rate': 12.5e6, 'master_clock_rate': '125e6', '--channels': '0,1,2,3',}, + + # | 4x RX & 4x TX | 125e6 | 1.25e6, 62.5e6 | 60 + # | 4x RX & 4x TX | 122.88e6 | 1.2288e6, 61.44e6 | 60 + # | 4x RX & 4x TX | 153e6 | 1.536e6, 76.8e6 | 60 + {'--rx_rate': 1.25e6, '--tx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': '0,1,2,3',}, + {'--rx_rate': 1.2288e6, '--tx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': '0,1,2,3',}, + {'--rx_rate': 1.536e6, '--tx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': '0,1,2,3',}, + + {'--rx_rate': 62.5e6, '--tx_rate': 62.5e6, 'master_clock_rate': '125e6', '--channels': '0,1,2,3', '--duration': 3600,}, + {'--rx_rate': 61.44e6, '--tx_rate': 61.44e6, 'master_clock_rate': '122.88e6', '--channels': '0,1,2,3', '--duration': 3600,}, + {'--rx_rate': 76.8e6, '--tx_rate': 76.8e6, 'master_clock_rate': '153.6e6', '--channels': '0,1,2,3', '--duration': 3600,}, + ], + }, + 'n300_10gige': { + '--args': "type=n3xx,addr={addr},master_clock_rate={master_clock_rate},{args}", + '--seq-threshold': 0, + '--drop-threshold': 0, + '--underrun-threshold': 100, + '--overrun-threshold': 100, + '--rx_subdev': 'A:0 B:0', + '--tx_subdev': 'A:0 B:0', + '--duration': 60, + '__tests': [ + {'--rx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': 0,}, + {'--rx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': 1,}, + + {'--rx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': 0,}, + {'--rx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': 1,}, + + {'--rx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': 0,}, + {'--rx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': 1,}, + + {'--rx_rate': 125e6, 'master_clock_rate': '125e6', '--channels': 0,}, + {'--rx_rate': 125e6, 'master_clock_rate': '125e6', '--channels': 1,}, + + {'--rx_rate': 122.88e6, 'master_clock_rate': '122.88e6', '--channels': 0,}, + {'--rx_rate': 122.88e6, 'master_clock_rate': '122.88e6', '--channels': 1,}, + + {'--rx_rate': 153.6e6, 'master_clock_rate': '153.6e6', '--channels': 0,}, + {'--rx_rate': 153.6e6, 'master_clock_rate': '153.6e6', '--channels': 1,}, + + {'--tx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': 0,}, + {'--tx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': 1,}, + + {'--tx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': 0,}, + {'--tx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': 1,}, + + {'--tx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': 0,}, + {'--tx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': 1,}, + + {'--tx_rate': 125e6, 'master_clock_rate': '125e6', '--channels': 0,}, + {'--tx_rate': 125e6, 'master_clock_rate': '125e6', '--channels': 1,}, + + {'--tx_rate': 122.88e6, 'master_clock_rate': '122.88e6', '--channels': 0,}, + {'--tx_rate': 122.88e6, 'master_clock_rate': '122.88e6', '--channels': 1,}, + + {'--tx_rate': 153.6e6, 'master_clock_rate': '153.6e6', '--channels': 0,}, + {'--tx_rate': 153.6e6, 'master_clock_rate': '153.6e6', '--channels': 1,}, + + {'--rx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': '0,1',}, + {'--rx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': '0,1',}, + {'--rx_rate': 1.536e6, 'master_clock_rate': '153.6e6', '--channels': '0,1',}, + + {'--rx_rate': 125e6, 'master_clock_rate': '125e6', '--channels': '0,1',}, + {'--rx_rate': 122.88e6, 'master_clock_rate': '122.88e6', '--channels': '0,1',}, + {'--rx_rate': 153.6e6, 'master_clock_rate': '153.6e6', '--channels': '0,1',}, + + {'--rx_rate': 1.25e6, '--tx_rate': 1.25e6, 'master_clock_rate': '125e6', '--channels': '0,1',}, + {'--rx_rate': 1.2288e6, '--tx_rate': 1.2288e6, 'master_clock_rate': '122.88e6', '--channels': '0,1',}, + {'--rx_rate': 1.536e6, '--tx_rate': 1.536, 'master_clock_rate': '153.6e6', '--channels': '0,1',}, + + {'--rx_rate': 62.5e6, '--tx_rate': 62.5e6, 'master_clock_rate': '125e6', '--channels': '0,1',}, + {'--rx_rate': 61.44e6, '--tx_rate': 61.44e6, 'master_clock_rate': '122.88e6', '--channels': '0,1',}, + {'--rx_rate': 76.8e6, '--tx_rate': 76.8e6, 'master_clock_rate': '153.6e6', '--channels': '0,1',}, + + {'--rx_rate': 62.5e6, '--tx_rate': 62.5e6, 'master_clock_rate': '125e6', '--channels': '0,1', '--duration': 3600,}, + {'--rx_rate': 61.44e6, '--tx_rate': 61.44e6, 'master_clock_rate': '122.88e6', '--channels': '0,1', '--duration': 3600,}, + {'--rx_rate': 76.8e6, '--tx_rate': 76.8e6, 'master_clock_rate': '153.6e6', '--channels': '0,1', '--duration': 3600,}, + ], + }, + 'n310_2x_10gige': { + '--args': "type=n3xx,addr={addr},second_addr={second_addr},master_clock_rate={master_clock_rate},{args}", + '--seq-threshold': 0, + '--drop-threshold': 0, + '--underrun-threshold': 100, + '--overrun-threshold': 100, + '--rx_subdev': 'A:0 A:1 B:0 B:1', + '--tx_subdev': 'A:0 A:1 B:0 B:1', + '--duration': 60, + '__tests': [ + {'--rx_rate': 125e6, '--tx_rate': 62.5e6, 'master_clock_rate': '125e6', '--channels': '0,1,2,3', + '--duration': 3600, '--underrun-threshold': 1000, '--overrun-threshold': 1000,}, + {'--rx_rate': 122.88e6,'--tx_rate': 61.44e6, 'master_clock_rate': '122.88e6', '--channels': '0,1,2,3', + '--duration': 3600, '--underrun-threshold': 1000, '--overrun-threshold': 1000,}, + {'--rx_rate': 153.6e6, '--tx_rate': 76.8e6, 'master_clock_rate': '153.6e6', '--channels': '0,1,2,3', + '--duration': 3600, '--underrun-threshold': 1000, '--overrun-threshold': 1000,}, + ], + }, + 'n300_2x_10gige': { + '--args': "type=n3xx,addr={addr},second_addr={second_addr},master_clock_rate={master_clock_rate},{args}", + '--seq-threshold': 0, + '--drop-threshold': 0, + '--underrun-threshold': 100, + '--overrun-threshold': 100, + '--rx_subdev': 'A:0 A:1 B:0 B:1', + '--tx_subdev': 'A:0 A:1 B:0 B:1', + '--duration': 60, + '__tests': [ + {'--rx_rate': 125e6, '--tx_rate': 62.5e6, 'master_clock_rate': '125e6', '--channels': '0,1', + '--duration': 3600, '--underrun-threshold': 1000, '--overrun-threshold': 1000,}, + {'--rx_rate': 122.88e6,'--tx_rate': 61.44e6, 'master_clock_rate': '122.88e6', '--channels': '0,1', + '--duration': 3600, '--underrun-threshold': 1000, '--overrun-threshold': 1000,}, + {'--rx_rate': 153.6e6, '--tx_rate': 76.8e6, 'master_clock_rate': '153.6e6', '--channels': '0,1', + '--duration': 3600, '--underrun-threshold': 1000, '--overrun-threshold': 1000,}, + ], + }, +} + + +def parse_args(): + """Parse args.""" + parser = argparse.ArgumentParser() + parser.add_argument( + # "-d", "--device-type", choices=FUNCVERIF_SETTINGS.keys(), + "device_type", choices=FUNCVERIF_SETTINGS.keys(), + help="Device type (n310, ...)" + ) + parser.add_argument( + '-a', '--addr', help="IP Address" + ) + parser.add_argument( + '-2', '--second-addr', help="Second IP Address" + ) + parser.add_argument( + '-p', '--path', default='.', help="Path to examples", + ) + parser.add_argument( + '-n', '--dry-run', action='store_true', help="Dry run", + ) + parser.add_argument( + '-v', '--verbose', action='store_true', help="Increase verbosity", + ) + parser.add_argument( + '-f', '--print-fastpath', action='store_true', + help="Don't disable fastpath messages", + ) + parser.add_argument( + '-s', '--sleep', type=int, default=30, help="Sleep time between tests", + ) + parser.add_argument( + '--args' + ) + return parser.parse_args() + + +def run_benchmark_rate(bmr_args, cli_args): + """ + Execute benchmark_rate + """ + bmr_exe = os.path.join(cli_args.path, 'benchmark_rate') + if not os.path.isfile(bmr_exe): + print("ERROR: Could not find benchmark_rate!") + exit(1) + cmd = [bmr_exe] + bmr_args + print("Executing: $ {}".format(" ".join(cmd))) + exe_env = os.environ + if not cli_args.verbose: + exe_env['UHD_LOG_LEVEL'] = 'warning' + if not cli_args.print_fastpath: + exe_env['UHD_LOG_FASTPATH_DISABLE'] = '1' + if cli_args.dry_run: + return True + if cli_args.verbose: + return subprocess.call(cmd, env=exe_env) == 0 + # Non-Verbose mode is a bit more complicated: + try: + subprocess.check_output(cmd, env=exe_env) + return True + except subprocess.CalledProcessError as ex: + print(ex.output) + return False + + +def prepare_args(default_args, test_args, extra_keys): + """ + Return a list of arguments for running benchmark_rate + """ + extra_keys.update({ + key: str(val) + for key, val in iteritems(test_args) + if not key.startswith('--') + }) + args = { + key: str(val).format(**extra_keys) + for key, val in iteritems(default_args) + if key.startswith('--') + } + for key in test_args: + if key.startswith('--'): + args[key] = str(test_args[key]).format(**extra_keys) + return list(chain.from_iterable(zip(args.keys(), args.values()))) + + +def run_tests(args, settings): + """ + args -- Command line args from parse_args + settings -- Sub-dictionary from FUNCVERIF_SETTINGS + """ + test_args_list = settings.pop('__tests') + num_tests = len(test_args_list) + default_args = { + key: str(val) + for key, val in iteritems(settings) + if key.startswith('--') + } + extra_keys = { + key: str(val) + for key, val in iteritems(settings) + if not key.startswith('--') + } + extra_keys.update({ + 'addr': args.addr, + 'second_addr': args.second_addr, + 'args': args.args, + }) + print("Preparing to execute {} tests...".format(num_tests)) + all_good = True + for test_idx, test_args in enumerate(test_args_list): + print("Running test {}/{}...".format(test_idx+1, num_tests)) + bmr_args = prepare_args(default_args, test_args, copy.copy(extra_keys)) + if not run_benchmark_rate(bmr_args, args): + print("Failure!") + all_good = False + time.sleep(args.sleep) + return all_good + + +def main(): + """Go, go, go!""" + args = parse_args() + settings = FUNCVERIF_SETTINGS[args.device_type] + return run_tests(args, settings) + + +if __name__ == "__main__": + exit(not main()) + |