From 0c3625bdf5b989c3121a6f73f866dfa765291f0c Mon Sep 17 00:00:00 2001 From: Ed Date: Tue, 17 Dec 2024 16:47:11 +0000 Subject: [PATCH 01/25] Initial API and test prog --- examples/test_rmii_dual/CMakeLists.txt | 29 ++ .../test_rmii_dual/src/XCORE-AI-EXPLORER.xn | 75 +++++ examples/test_rmii_dual/src/config.xscope | 2 + examples/test_rmii_dual/src/main.xc | 256 ++++++++++++++++++ lib_ethernet/src/rmii_ethernet_rt_mac.xc | 176 ++++++++++++ 5 files changed, 538 insertions(+) create mode 100644 examples/test_rmii_dual/CMakeLists.txt create mode 100644 examples/test_rmii_dual/src/XCORE-AI-EXPLORER.xn create mode 100644 examples/test_rmii_dual/src/config.xscope create mode 100644 examples/test_rmii_dual/src/main.xc diff --git a/examples/test_rmii_dual/CMakeLists.txt b/examples/test_rmii_dual/CMakeLists.txt new file mode 100644 index 00000000..0a134946 --- /dev/null +++ b/examples/test_rmii_dual/CMakeLists.txt @@ -0,0 +1,29 @@ +cmake_minimum_required(VERSION 3.21) +include($ENV{XMOS_CMAKE_PATH}/xcommon.cmake) +project(test_rmii_dual) + +set(APP_HW_TARGET src/XCORE-AI-EXPLORER.xn) + +include(${CMAKE_CURRENT_LIST_DIR}/../deps.cmake) + +set(APP_PCA_ENABLE ON) + +set(COMPILER_FLAGS_COMMON -g + -report + -DDEBUG_PRINT_ENABLE=1 + -DETHERNET_SUPPORT_HP_QUEUES=1 + -Wno-unused-function + ) + + +set(APP_COMPILER_FLAGS_tx4b_rx4b ${COMPILER_FLAGS_COMMON} -DTX_WIDTH=4 -DRX_WIDTH=4) +set(APP_COMPILER_FLAGS_tx4b_rx4b_upper ${COMPILER_FLAGS_COMMON} -DTX_WIDTH=4 -DRX_WIDTH=4 -DUSE_LOWER=0) +set(APP_COMPILER_FLAGS_tx1b_rx4b ${COMPILER_FLAGS_COMMON} -DTX_WIDTH=1 -DRX_WIDTH=4) +set(APP_COMPILER_FLAGS_tx4b_rx1b ${COMPILER_FLAGS_COMMON} -DTX_WIDTH=4 -DRX_WIDTH=1) +set(APP_COMPILER_FLAGS_tx1b_rx1b ${COMPILER_FLAGS_COMMON} -DTX_WIDTH=1 -DRX_WIDTH=1) + +set(APP_XSCOPE_SRCS src/config.xscope) + +set(XMOS_SANDBOX_DIR ${CMAKE_CURRENT_LIST_DIR}/../../..) + +XMOS_REGISTER_APP() diff --git a/examples/test_rmii_dual/src/XCORE-AI-EXPLORER.xn b/examples/test_rmii_dual/src/XCORE-AI-EXPLORER.xn new file mode 100644 index 00000000..0baa0215 --- /dev/null +++ b/examples/test_rmii_dual/src/XCORE-AI-EXPLORER.xn @@ -0,0 +1,75 @@ + + + Board + xcore.ai Explorer Kit + + + tileref tile[2] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/test_rmii_dual/src/config.xscope b/examples/test_rmii_dual/src/config.xscope new file mode 100644 index 00000000..5c4b0f67 --- /dev/null +++ b/examples/test_rmii_dual/src/config.xscope @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/examples/test_rmii_dual/src/main.xc b/examples/test_rmii_dual/src/main.xc new file mode 100644 index 00000000..619b4ce5 --- /dev/null +++ b/examples/test_rmii_dual/src/main.xc @@ -0,0 +1,256 @@ +// Copyright 2024 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. +#include +#include +#include +#include +#include +#include +#include "ethernet.h" + +port p_eth_clk = XS1_PORT_1J; + +#ifndef USE_LOWER +#define USE_LOWER 1 +#endif + +#if TX_WIDTH == 4 +#if USE_LOWER +rmii_data_port_t p_eth_txd = {{XS1_PORT_4B, USE_LOWER_2B}}; +#else +rmii_data_port_t p_eth_txd = {{XS1_PORT_4B, USE_UPPER_2B}}; +#endif +#elif TX_WIDTH == 1 +rmii_data_port_t p_eth_txd = {{XS1_PORT_1C, XS1_PORT_1D}}; +#else +#error invalid TX_WIDTH +#endif + +#if RX_WIDTH == 4 +#if USE_LOWER +rmii_data_port_t p_eth_rxd = {{XS1_PORT_4A, USE_LOWER_2B}}; +#else +rmii_data_port_t p_eth_rxd = {{XS1_PORT_4A, USE_UPPER_2B}}; +#endif +#elif RX_WIDTH == 1 +rmii_data_port_t p_eth_rxd = {{XS1_PORT_1A, XS1_PORT_1B}}; +#else +#error invalid RX_WIDTH +#endif + +port p_eth_rxdv = XS1_PORT_1K; +port p_eth_txen = XS1_PORT_1L; +clock eth_rxclk = XS1_CLKBLK_1; +clock eth_txclk = XS1_CLKBLK_2; + + +// Test harness +clock eth_clk_harness = XS1_CLKBLK_3; +port p_eth_clk_harness = XS1_PORT_1I; + +#define MAX_PACKET_WORDS ((ETHERNET_MAX_PACKET_SIZE + 3) / 4) + +#define VLAN_TAGGED 1 + +#define MII_CREDIT_FRACTIONAL_BITS 16 + +static int calc_idle_slope(int bps) +{ + long long slope = ((long long) bps) << (MII_CREDIT_FRACTIONAL_BITS); + slope = slope / 100000000; // bits that should be sent per ref timer tick + + return (int) slope; +} + +static void printbytes(char *b, int n){ + for(int i=0; i> 32; + printhex(b[i]); printstr(", 0x");printhex(p0_val); printstr(", 0x");printhexln(p1_val); + } + printstr("\n"); +} + + + +void hp_traffic_tx( client ethernet_cfg_if i_cfg, + client ethernet_tx_if tx_lp, + streaming chanend c_tx_hp, + chanend test_info) +{ + // Request 5Mbits/sec + i_cfg.set_egress_qav_idle_slope(0, calc_idle_slope(5 * 1024 * 1024)); + + unsigned data[MAX_PACKET_WORDS]; + for (size_t i = 0; i < MAX_PACKET_WORDS; i++) { + data[i] = i; + } + + // src/dst MAC addresses + size_t j = 0; + for (; j < 12; j++) + ((char*)data)[j] = j; + + if (VLAN_TAGGED) { + ((char*)data)[j++] = 0x81; + ((char*)data)[j++] = 0x00; + ((char*)data)[j++] = 0x00; + ((char*)data)[j++] = 0x00; + } + + const int length = 61; + const int header_bytes = VLAN_TAGGED ? 18 : 14; + ((char*)data)[j++] = (length - header_bytes) >> 8; + ((char*)data)[j++] = (length - header_bytes) & 0xff; + + timer t; + int time; + t :> time; + t when timerafter(time + 1000) :> time; // Delay sending to allow Rx to be setup + + + int start_length = 1515; + + for(int length = start_length; length < start_length + 4; length++){ + printf("TX sending: %d\n", length); + test_info <: length; + // printbytes((char*)data, length); + // printwords_4b(data, (length + 3)/4); + tx_lp.send_packet((char *)data, length, ETHERNET_ALL_INTERFACES); + // printf("LP packet sent: %d bytes\n", length); + t :> time; + t when timerafter(time + 4000) :> time; + } +} + + +void rx_app(client ethernet_cfg_if i_cfg, + client ethernet_rx_if i_rx, + streaming chanend c_rx_hp, + chanend test_info) +{ + ethernet_macaddr_filter_t macaddr_filter; + size_t index = i_rx.get_index(); + for (int i = 0; i < MACADDR_NUM_BYTES; i++) { + macaddr_filter.addr[i] = i; + } + i_cfg.add_macaddr_filter(index, 1, macaddr_filter); + + int test_packet_lengths[128] = {0}; + int num_test_packets_sent = 0; + int num_test_packets_received = 0; + + + timer tmr; + int timeout_trig; + tmr :> timeout_trig; + int timeout = 20000; // Bit time is same as ref clock, 100MHz. Set to initial large value for startup + timeout_trig += timeout; + + int test_pass = 1; + + while (1) { + uint8_t rxbuf[ETHERNET_MAX_PACKET_SIZE]; + ethernet_packet_info_t packet_info; + + select { + case ethernet_receive_hp_packet(c_rx_hp, rxbuf, packet_info): + printf("HP packet received: %d bytes\n", packet_info.len); + // printbytes(rxbuf, packet_info.len); + if(packet_info.len != test_packet_lengths[num_test_packets_received]){ + printf("Wrong length. Expected %d got %d\n", packet_info.len, test_packet_lengths[num_test_packets_received]); + test_pass = 0; + } + num_test_packets_received++; + if(num_test_packets_received == num_test_packets_sent){ + printf("TEST %s\n", test_pass ? "PASS" : "FAIL"); + exit(test_pass); + } + + tmr :> timeout_trig; + timeout_trig += timeout; + break; + + case i_rx.packet_ready(): + unsigned n; + i_rx.get_packet(packet_info, rxbuf, n); + printf("LP packet received: %d bytes\n", n); + // printbytes(rxbuf, packet_info.len); + break; + + case test_info :> int length: + timeout = 1.5 * (32 * MAX_PACKET_WORDS); + test_packet_lengths[num_test_packets_sent] = length; + num_test_packets_sent++; + tmr :> timeout_trig; + timeout_trig += timeout; + printf("+"); + break; + + case tmr when timerafter(timeout_trig) :> int _: + if(num_test_packets_received != num_test_packets_sent){ + test_pass = 0; + printf("Timed out after %d bit times\n", timeout); + } + + printf("TEST %s\n", test_pass ? "PASS" : "FAIL"); + exit(test_pass); + break; + } + } +} + +int main() +{ + ethernet_cfg_if i_cfg[2]; + ethernet_rx_if i_rx_lp[1]; + ethernet_tx_if i_tx_lp[1]; + streaming chan c_rx_hp; + streaming chan c_tx_hp; + chan test_info; + + + // Setup 50M clock + unsigned divider = 2; // 100 / 2 = 50; + configure_clock_ref(eth_clk_harness, divider / 2); + set_port_clock(p_eth_clk_harness, eth_clk_harness); + set_port_mode_clock(p_eth_clk_harness); + start_clock(eth_clk_harness); + + par { + unsafe{rmii_ethernet_rt_mac(i_cfg, 2, + 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, + 500, 500, ETHERNET_ENABLE_SHAPER);} + + rx_app(i_cfg[0], i_rx_lp[0], c_rx_hp, test_info); + hp_traffic_tx(i_cfg[1], i_tx_lp[0], c_tx_hp, test_info); + } + + return 0; +} \ No newline at end of file diff --git a/lib_ethernet/src/rmii_ethernet_rt_mac.xc b/lib_ethernet/src/rmii_ethernet_rt_mac.xc index 9168b516..0b37867c 100644 --- a/lib_ethernet/src/rmii_ethernet_rt_mac.xc +++ b/lib_ethernet/src/rmii_ethernet_rt_mac.xc @@ -207,3 +207,179 @@ void rmii_ethernet_rt_mac(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), stati } // par } // unsafe block } + + +void rmii_ethernet_rt_mac_dual(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), static_const_unsigned_t n_cfg, + SERVER_INTERFACE(ethernet_rx_if, i_rx_lp[n_rx_lp]), static_const_unsigned_t n_rx_lp, + SERVER_INTERFACE(ethernet_tx_if, i_tx_lp[n_tx_lp]), static_const_unsigned_t n_tx_lp, + nullable_streaming_chanend_t c_rx_hp, + nullable_streaming_chanend_t c_tx_hp, + in_port_t p_clk, + rmii_data_port_t * unsafe p_rxd_0, in_port_t p_rxdv_0, + out_port_t p_txen_0, rmii_data_port_t * unsafe p_txd_0, + clock rxclk_0, + clock txclk_0, + rmii_data_port_t * unsafe p_rxd_1, in_port_t p_rxdv_1, + out_port_t p_txen_1, rmii_data_port_t * unsafe p_txd_1, + clock rxclk_1, + clock txclk_1, + static_const_unsigned_t rx_bufsize_words, + static_const_unsigned_t tx_bufsize_words, + enum ethernet_enable_shaper_t enable_shaper) +{ + // Establish types of data ports presented + unsafe{ + // Setup buffering + unsigned int rx_data[rx_bufsize_words]; + unsigned int tx_data[tx_bufsize_words]; + mii_mempool_t rx_mem = mii_init_mempool(rx_data, rx_bufsize_words*4); + + // If the high priority traffic is connected then allocate half the buffer for high priority + // and half for low priority. Otherwise, allocate it all to low priority. + const size_t lp_buffer_bytes = !isnull(c_tx_hp) ? tx_bufsize_words * 2 : tx_bufsize_words * 4; + const size_t hp_buffer_bytes = tx_bufsize_words * 4 - lp_buffer_bytes; + mii_mempool_t tx_mem_lp = mii_init_mempool(tx_data, lp_buffer_bytes); + mii_mempool_t tx_mem_hp = mii_init_mempool(tx_data + (lp_buffer_bytes/4), hp_buffer_bytes); + + packet_queue_info_t rx_packets_lp, rx_packets_hp, tx_packets_lp, tx_packets_hp, incoming_packets; + mii_init_packet_queue((mii_packet_queue_t)&rx_packets_lp); + mii_init_packet_queue((mii_packet_queue_t)&rx_packets_hp); + mii_init_packet_queue((mii_packet_queue_t)&tx_packets_lp); + mii_init_packet_queue((mii_packet_queue_t)&tx_packets_hp); + mii_init_packet_queue((mii_packet_queue_t)&incoming_packets); + + // Shared read pointer to help optimize the RX code + unsigned rx_rdptr = 0; + unsigned * unsafe p_rx_rdptr = &rx_rdptr; + + + mii_init_lock(); + mii_ts_queue_entry_t ts_fifo[MII_TIMESTAMP_QUEUE_MAX_SIZE + 1]; + mii_ts_queue_info_t ts_queue_info; + + if (n_tx_lp > MII_TIMESTAMP_QUEUE_MAX_SIZE) { + fail("Exceeded maximum number of transmit clients. Increase MII_TIMESTAMP_QUEUE_MAX_SIZE in ethernet_conf.h"); + } + + if (!ETHERNET_SUPPORT_HP_QUEUES && (!isnull(c_rx_hp) || !isnull(c_tx_hp))) { + fail("Using high priority channels without #define ETHERNET_SUPPORT_HP_QUEUES set true"); + } + + mii_ts_queue_t ts_queue = mii_ts_queue_init(&ts_queue_info, ts_fifo, n_tx_lp + 1); + + + + // Common initialisation + set_port_use_on(p_clk); // RMII 50MHz clock input port + + // Setup RX data ports + // First declare C pointers for port resources + in buffered port:32 * unsafe rx_data_0 = NULL; + in buffered port:32 * unsafe rx_data_1 = NULL; + + // Extract width and optionally which 4b pins to use + unsigned rx_port_width = ((unsigned)(p_rxd->rmii_data_1b.data_0) >> 16) & 0xff; + rmii_data_4b_pin_assignment_t rx_port_4b_pins = (rmii_data_4b_pin_assignment_t)(p_rxd->rmii_data_1b.data_1); + + // Extract pointers to ports with correct port qualifiers and setup data pins + switch(rx_port_width){ + case 4: + rx_data_0 = enable_buffered_in_port((unsigned*)(&p_rxd->rmii_data_1b.data_0), 32); + rmii_master_init_rx_4b(p_clk, rx_data_0, p_rxdv, rxclk); + break; + case 1: + rx_data_0 = enable_buffered_in_port((unsigned*)&p_rxd->rmii_data_1b.data_0, 32); + rx_data_1 = enable_buffered_in_port((unsigned*)&p_rxd->rmii_data_1b.data_1, 32); + rmii_master_init_rx_1b(p_clk, rx_data_0, rx_data_1, p_rxdv, rxclk); + break; + default: + fail("Invald port width for RMII Rx"); + break; + } + + // Setup TX data ports + out buffered port:32 * unsafe tx_data_0 = NULL; + out buffered port:32 * unsafe tx_data_1 = NULL; + + unsigned tx_port_width = ((unsigned)(p_txd->rmii_data_1b.data_0) >> 16) & 0xff; + rmii_data_4b_pin_assignment_t tx_port_4b_pins = (rmii_data_4b_pin_assignment_t)(p_txd->rmii_data_1b.data_1); + + switch(tx_port_width){ + case 4: + tx_data_0 = enable_buffered_out_port((unsigned*)(&p_txd->rmii_data_1b.data_0), 32); + rmii_master_init_tx_4b(p_clk, tx_data_0, p_txen, txclk); + break; + case 1: + tx_data_0 = enable_buffered_out_port((unsigned*)&p_txd->rmii_data_1b.data_0, 32); + tx_data_1 = enable_buffered_out_port((unsigned*)&p_txd->rmii_data_1b.data_1, 32); + rmii_master_init_tx_1b(p_clk, tx_data_0, tx_data_1, p_txen, txclk); + break; + default: + fail("Invald port width for RMII Tx"); + break; + } + + // Setup server + ethernet_port_state_t port_state; + init_server_port_state(port_state, enable_shaper == ETHERNET_ENABLE_SHAPER); + + ethernet_port_state_t * unsafe p_port_state = (ethernet_port_state_t * unsafe)&port_state; + + chan c_conf; + par { + // Rx task + { + if(rx_port_width == 4){ + rmii_master_rx_pins_4b(rx_mem, + (mii_packet_queue_t)&incoming_packets, + p_rx_rdptr, + p_rxdv, + rx_data_0, + rx_port_4b_pins); + } else { + rmii_master_rx_pins_1b(rx_mem, + (mii_packet_queue_t)&incoming_packets, + p_rx_rdptr, + p_rxdv, + rx_data_0, + rx_data_1); + } + } + // Tx task + + rmii_master_tx_pins(tx_mem_lp, + tx_mem_hp, + (mii_packet_queue_t)&tx_packets_lp, + (mii_packet_queue_t)&tx_packets_hp, + ts_queue, + tx_port_width, + tx_data_0, + tx_data_1, + tx_port_4b_pins, + txclk, + p_port_state); + + mii_ethernet_filter(c_conf, + (mii_packet_queue_t)&incoming_packets, + (mii_packet_queue_t)&rx_packets_lp, + (mii_packet_queue_t)&rx_packets_hp); + + mii_ethernet_server(rx_mem, + (mii_packet_queue_t)&rx_packets_lp, + (mii_packet_queue_t)&rx_packets_hp, + p_rx_rdptr, + tx_mem_lp, + tx_mem_hp, + (mii_packet_queue_t)&tx_packets_lp, + (mii_packet_queue_t)&tx_packets_hp, + ts_queue, + i_cfg, n_cfg, + i_rx_lp, n_rx_lp, + i_tx_lp, n_tx_lp, + c_rx_hp, + c_tx_hp, + c_conf, + p_port_state); + } // par + } // unsafe block +} From 7e3d4a2f1cb807e40f7be8b00b5724c4e8e5111f Mon Sep 17 00:00:00 2001 From: Ed Date: Mon, 23 Dec 2024 11:57:09 +0000 Subject: [PATCH 02/25] Initial API and pins for dual MAC --- .gitignore | 1 + lib_ethernet/api/ethernet.h | 19 ++ lib_ethernet/src/rmii_ethernet_rt_mac.xc | 379 ++++++++++++++--------- 3 files changed, 248 insertions(+), 151 deletions(-) diff --git a/.gitignore b/.gitignore index 13a48b54..62bc10f3 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,4 @@ tests/expect tests/*.xml seed.inc trace.txt +tests/expect_temp diff --git a/lib_ethernet/api/ethernet.h b/lib_ethernet/api/ethernet.h index c0168391..3039cb0b 100644 --- a/lib_ethernet/api/ethernet.h +++ b/lib_ethernet/api/ethernet.h @@ -685,6 +685,25 @@ void rmii_ethernet_rt_mac(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), stati static_const_unsigned_t tx_bufsize_words, enum ethernet_enable_shaper_t shaper_enabled); + +void rmii_ethernet_rt_mac_dual(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), static_const_unsigned_t n_cfg, + SERVER_INTERFACE(ethernet_rx_if, i_rx_lp[n_rx_lp]), static_const_unsigned_t n_rx_lp, + SERVER_INTERFACE(ethernet_tx_if, i_tx_lp[n_tx_lp]), static_const_unsigned_t n_tx_lp, + nullable_streaming_chanend_t c_rx_hp, + nullable_streaming_chanend_t c_tx_hp, + in_port_t p_clk, + rmii_data_port_t * unsafe p_rxd_0, in_port_t p_rxdv_0, + out_port_t p_txen_0, rmii_data_port_t * unsafe p_txd_0, + clock rxclk_0, + clock txclk_0, + rmii_data_port_t * unsafe p_rxd_1, in_port_t p_rxdv_1, + out_port_t p_txen_1, rmii_data_port_t * unsafe p_txd_1, + clock rxclk_1, + clock txclk_1, + static_const_unsigned_t rx_bufsize_words, + static_const_unsigned_t tx_bufsize_words, + enum ethernet_enable_shaper_t enable_shaper); + #endif // __XC__ || __DOXYGEN__ #endif // __ethernet__h__ diff --git a/lib_ethernet/src/rmii_ethernet_rt_mac.xc b/lib_ethernet/src/rmii_ethernet_rt_mac.xc index 0b37867c..496374ce 100644 --- a/lib_ethernet/src/rmii_ethernet_rt_mac.xc +++ b/lib_ethernet/src/rmii_ethernet_rt_mac.xc @@ -209,6 +209,68 @@ void rmii_ethernet_rt_mac(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), stati } +{unsigned, rmii_data_4b_pin_assignment_t} init_rx_ports(in_port_t p_clk, + in_port_t p_rxdv, + clock rxclk, + rmii_data_port_t * unsafe p_rxd, + in buffered port:32 * unsafe rx_data_0, + in buffered port:32 * unsafe rx_data_1){ + unsafe { + // Extract width and optionally which 4b pins to use + unsigned rx_port_width = ((unsigned)(p_rxd->rmii_data_1b.data_0) >> 16) & 0xff; + rmii_data_4b_pin_assignment_t rx_port_4b_pins = (rmii_data_4b_pin_assignment_t)(p_rxd->rmii_data_1b.data_1); + + // Extract pointers to ports with correct port qualifiers and setup data pins + switch(rx_port_width){ + case 4: + rx_data_0 = enable_buffered_in_port((unsigned*)(&p_rxd->rmii_data_1b.data_0), 32); + rmii_master_init_rx_4b(p_clk, rx_data_0, p_rxdv, rxclk); + break; + case 1: + rx_data_0 = enable_buffered_in_port((unsigned*)&p_rxd->rmii_data_1b.data_0, 32); + rx_data_1 = enable_buffered_in_port((unsigned*)&p_rxd->rmii_data_1b.data_1, 32); + rmii_master_init_rx_1b(p_clk, rx_data_0, rx_data_1, p_rxdv, rxclk); + break; + default: + fail("Invald port width for RMII Rx"); + break; + } + + return {rx_port_width, rx_port_4b_pins}; + } +} + +{unsigned, rmii_data_4b_pin_assignment_t} init_tx_ports(in_port_t p_clk, + out_port_t p_txen, + clock txclk, + rmii_data_port_t * unsafe p_txd, + out buffered port:32 * unsafe tx_data_0, + out buffered port:32 * unsafe tx_data_1){ + unsafe { + unsigned tx_port_width = ((unsigned)(p_txd->rmii_data_1b.data_0) >> 16) & 0xff; + rmii_data_4b_pin_assignment_t tx_port_4b_pins = (rmii_data_4b_pin_assignment_t)(p_txd->rmii_data_1b.data_1); + + switch(tx_port_width){ + case 4: + tx_data_0 = enable_buffered_out_port((unsigned*)(&p_txd->rmii_data_1b.data_0), 32); + rmii_master_init_tx_4b(p_clk, tx_data_0, p_txen, txclk); + break; + case 1: + tx_data_0 = enable_buffered_out_port((unsigned*)&p_txd->rmii_data_1b.data_0, 32); + tx_data_1 = enable_buffered_out_port((unsigned*)&p_txd->rmii_data_1b.data_1, 32); + rmii_master_init_tx_1b(p_clk, tx_data_0, tx_data_1, p_txen, txclk); + break; + default: + fail("Invald port width for RMII Tx"); + break; + } + + return {tx_port_width, tx_port_4b_pins}; + + } +} + + void rmii_ethernet_rt_mac_dual(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), static_const_unsigned_t n_cfg, SERVER_INTERFACE(ethernet_rx_if, i_rx_lp[n_rx_lp]), static_const_unsigned_t n_rx_lp, SERVER_INTERFACE(ethernet_tx_if, i_tx_lp[n_tx_lp]), static_const_unsigned_t n_tx_lp, @@ -228,158 +290,173 @@ void rmii_ethernet_rt_mac_dual(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), enum ethernet_enable_shaper_t enable_shaper) { // Establish types of data ports presented - unsafe{ - // Setup buffering - unsigned int rx_data[rx_bufsize_words]; - unsigned int tx_data[tx_bufsize_words]; - mii_mempool_t rx_mem = mii_init_mempool(rx_data, rx_bufsize_words*4); - - // If the high priority traffic is connected then allocate half the buffer for high priority - // and half for low priority. Otherwise, allocate it all to low priority. - const size_t lp_buffer_bytes = !isnull(c_tx_hp) ? tx_bufsize_words * 2 : tx_bufsize_words * 4; - const size_t hp_buffer_bytes = tx_bufsize_words * 4 - lp_buffer_bytes; - mii_mempool_t tx_mem_lp = mii_init_mempool(tx_data, lp_buffer_bytes); - mii_mempool_t tx_mem_hp = mii_init_mempool(tx_data + (lp_buffer_bytes/4), hp_buffer_bytes); - - packet_queue_info_t rx_packets_lp, rx_packets_hp, tx_packets_lp, tx_packets_hp, incoming_packets; - mii_init_packet_queue((mii_packet_queue_t)&rx_packets_lp); - mii_init_packet_queue((mii_packet_queue_t)&rx_packets_hp); - mii_init_packet_queue((mii_packet_queue_t)&tx_packets_lp); - mii_init_packet_queue((mii_packet_queue_t)&tx_packets_hp); - mii_init_packet_queue((mii_packet_queue_t)&incoming_packets); - - // Shared read pointer to help optimize the RX code - unsigned rx_rdptr = 0; - unsigned * unsafe p_rx_rdptr = &rx_rdptr; - - - mii_init_lock(); - mii_ts_queue_entry_t ts_fifo[MII_TIMESTAMP_QUEUE_MAX_SIZE + 1]; - mii_ts_queue_info_t ts_queue_info; - - if (n_tx_lp > MII_TIMESTAMP_QUEUE_MAX_SIZE) { - fail("Exceeded maximum number of transmit clients. Increase MII_TIMESTAMP_QUEUE_MAX_SIZE in ethernet_conf.h"); - } - - if (!ETHERNET_SUPPORT_HP_QUEUES && (!isnull(c_rx_hp) || !isnull(c_tx_hp))) { - fail("Using high priority channels without #define ETHERNET_SUPPORT_HP_QUEUES set true"); - } - - mii_ts_queue_t ts_queue = mii_ts_queue_init(&ts_queue_info, ts_fifo, n_tx_lp + 1); - - - - // Common initialisation - set_port_use_on(p_clk); // RMII 50MHz clock input port - - // Setup RX data ports - // First declare C pointers for port resources - in buffered port:32 * unsafe rx_data_0 = NULL; - in buffered port:32 * unsafe rx_data_1 = NULL; - - // Extract width and optionally which 4b pins to use - unsigned rx_port_width = ((unsigned)(p_rxd->rmii_data_1b.data_0) >> 16) & 0xff; - rmii_data_4b_pin_assignment_t rx_port_4b_pins = (rmii_data_4b_pin_assignment_t)(p_rxd->rmii_data_1b.data_1); - - // Extract pointers to ports with correct port qualifiers and setup data pins - switch(rx_port_width){ - case 4: - rx_data_0 = enable_buffered_in_port((unsigned*)(&p_rxd->rmii_data_1b.data_0), 32); - rmii_master_init_rx_4b(p_clk, rx_data_0, p_rxdv, rxclk); - break; - case 1: - rx_data_0 = enable_buffered_in_port((unsigned*)&p_rxd->rmii_data_1b.data_0, 32); - rx_data_1 = enable_buffered_in_port((unsigned*)&p_rxd->rmii_data_1b.data_1, 32); - rmii_master_init_rx_1b(p_clk, rx_data_0, rx_data_1, p_rxdv, rxclk); - break; - default: - fail("Invald port width for RMII Rx"); - break; - } - - // Setup TX data ports - out buffered port:32 * unsafe tx_data_0 = NULL; - out buffered port:32 * unsafe tx_data_1 = NULL; - - unsigned tx_port_width = ((unsigned)(p_txd->rmii_data_1b.data_0) >> 16) & 0xff; - rmii_data_4b_pin_assignment_t tx_port_4b_pins = (rmii_data_4b_pin_assignment_t)(p_txd->rmii_data_1b.data_1); - - switch(tx_port_width){ - case 4: - tx_data_0 = enable_buffered_out_port((unsigned*)(&p_txd->rmii_data_1b.data_0), 32); - rmii_master_init_tx_4b(p_clk, tx_data_0, p_txen, txclk); - break; - case 1: - tx_data_0 = enable_buffered_out_port((unsigned*)&p_txd->rmii_data_1b.data_0, 32); - tx_data_1 = enable_buffered_out_port((unsigned*)&p_txd->rmii_data_1b.data_1, 32); - rmii_master_init_tx_1b(p_clk, tx_data_0, tx_data_1, p_txen, txclk); - break; - default: - fail("Invald port width for RMII Tx"); - break; - } - - // Setup server - ethernet_port_state_t port_state; - init_server_port_state(port_state, enable_shaper == ETHERNET_ENABLE_SHAPER); - - ethernet_port_state_t * unsafe p_port_state = (ethernet_port_state_t * unsafe)&port_state; - - chan c_conf; - par { - // Rx task - { - if(rx_port_width == 4){ - rmii_master_rx_pins_4b(rx_mem, - (mii_packet_queue_t)&incoming_packets, - p_rx_rdptr, - p_rxdv, - rx_data_0, - rx_port_4b_pins); - } else { - rmii_master_rx_pins_1b(rx_mem, - (mii_packet_queue_t)&incoming_packets, - p_rx_rdptr, - p_rxdv, - rx_data_0, - rx_data_1); + unsafe{ + // Setup buffering + unsigned int rx_data[rx_bufsize_words]; + unsigned int tx_data[tx_bufsize_words]; + mii_mempool_t rx_mem = mii_init_mempool(rx_data, rx_bufsize_words*4); + + // If the high priority traffic is connected then allocate half the buffer for high priority + // and half for low priority. Otherwise, allocate it all to low priority. + const size_t lp_buffer_bytes = !isnull(c_tx_hp) ? tx_bufsize_words * 2 : tx_bufsize_words * 4; + const size_t hp_buffer_bytes = tx_bufsize_words * 4 - lp_buffer_bytes; + mii_mempool_t tx_mem_lp = mii_init_mempool(tx_data, lp_buffer_bytes); + mii_mempool_t tx_mem_hp = mii_init_mempool(tx_data + (lp_buffer_bytes/4), hp_buffer_bytes); + + packet_queue_info_t rx_packets_lp, rx_packets_hp, tx_packets_lp, tx_packets_hp, incoming_packets; + mii_init_packet_queue((mii_packet_queue_t)&rx_packets_lp); + mii_init_packet_queue((mii_packet_queue_t)&rx_packets_hp); + mii_init_packet_queue((mii_packet_queue_t)&tx_packets_lp); + mii_init_packet_queue((mii_packet_queue_t)&tx_packets_hp); + mii_init_packet_queue((mii_packet_queue_t)&incoming_packets); + + // Shared read pointer to help optimize the RX code + unsigned rx_rdptr = 0; + unsigned * unsafe p_rx_rdptr = &rx_rdptr; + + + mii_init_lock(); + mii_ts_queue_entry_t ts_fifo[MII_TIMESTAMP_QUEUE_MAX_SIZE + 1]; + mii_ts_queue_info_t ts_queue_info; + + if (n_tx_lp > MII_TIMESTAMP_QUEUE_MAX_SIZE) { + fail("Exceeded maximum number of transmit clients. Increase MII_TIMESTAMP_QUEUE_MAX_SIZE in ethernet_conf.h"); } - } - // Tx task - rmii_master_tx_pins(tx_mem_lp, - tx_mem_hp, - (mii_packet_queue_t)&tx_packets_lp, - (mii_packet_queue_t)&tx_packets_hp, - ts_queue, - tx_port_width, - tx_data_0, - tx_data_1, - tx_port_4b_pins, - txclk, - p_port_state); - - mii_ethernet_filter(c_conf, - (mii_packet_queue_t)&incoming_packets, - (mii_packet_queue_t)&rx_packets_lp, - (mii_packet_queue_t)&rx_packets_hp); + if (!ETHERNET_SUPPORT_HP_QUEUES && (!isnull(c_rx_hp) || !isnull(c_tx_hp))) { + fail("Using high priority channels without #define ETHERNET_SUPPORT_HP_QUEUES set true"); + } - mii_ethernet_server(rx_mem, - (mii_packet_queue_t)&rx_packets_lp, - (mii_packet_queue_t)&rx_packets_hp, - p_rx_rdptr, - tx_mem_lp, - tx_mem_hp, - (mii_packet_queue_t)&tx_packets_lp, - (mii_packet_queue_t)&tx_packets_hp, - ts_queue, - i_cfg, n_cfg, - i_rx_lp, n_rx_lp, - i_tx_lp, n_tx_lp, - c_rx_hp, - c_tx_hp, - c_conf, - p_port_state); - } // par - } // unsafe block + mii_ts_queue_t ts_queue = mii_ts_queue_init(&ts_queue_info, ts_fifo, n_tx_lp + 1); + + + + // Common initialisation + set_port_use_on(p_clk); // RMII 50MHz clock input port + + // Setup RX data ports + // First declare C pointers for port resources and the initialise + // MAC port 0 + in buffered port:32 * unsafe rx_data_0_0 = NULL; + in buffered port:32 * unsafe rx_data_0_1 = NULL; + unsigned rx_port_width_0; + rmii_data_4b_pin_assignment_t rx_port_4b_pins_0; + {rx_port_width_0, rx_port_4b_pins_0} = init_rx_ports(p_clk, p_rxdv_0, rxclk_0, p_rxd_0, rx_data_0_0, rx_data_0_1); + // MAC port 1 + in buffered port:32 * unsafe rx_data_1_0 = NULL; + in buffered port:32 * unsafe rx_data_1_1 = NULL; + unsigned rx_port_width_1 = 0; + rmii_data_4b_pin_assignment_t rx_port_4b_pins_1; + {rx_port_width_1, rx_port_4b_pins_1} = init_rx_ports(p_clk, p_rxdv_1, rxclk_1, p_rxd_1, rx_data_1_0, rx_data_1_1); + + + + // Setup TX data ports + // First declare C pointers for port resources and the initialise + // MAC port 0 + out buffered port:32 * unsafe tx_data_0_0 = NULL; + out buffered port:32 * unsafe tx_data_0_1 = NULL; + unsigned tx_port_width_0; + rmii_data_4b_pin_assignment_t tx_port_4b_pins_0; + {tx_port_width_0, tx_port_4b_pins_0} = init_tx_ports(p_clk, p_txen_0, txclk_0, p_txd_0, tx_data_0_0, tx_data_0_1); + // MAC port 1 + out buffered port:32 * unsafe tx_data_1_0 = NULL; + out buffered port:32 * unsafe tx_data_1_1 = NULL; + unsigned tx_port_width_1; + rmii_data_4b_pin_assignment_t tx_port_4b_pins_1; + {tx_port_width_1, tx_port_4b_pins_1} = init_tx_ports(p_clk, p_txen_1, txclk_1, p_txd_1, tx_data_1_0, tx_data_1_1); + + // Setup server + ethernet_port_state_t port_state; + init_server_port_state(port_state, enable_shaper == ETHERNET_ENABLE_SHAPER); + + ethernet_port_state_t * unsafe p_port_state = (ethernet_port_state_t * unsafe)&port_state; + + chan c_conf; + par + { + { + if(rx_port_width_0 == 4) + { + rmii_master_rx_pins_4b(rx_mem, + (mii_packet_queue_t)&incoming_packets, + p_rx_rdptr, + p_rxdv_0, + rx_data_0_0, + rx_port_4b_pins_0); + } else { + rmii_master_rx_pins_1b(rx_mem, + (mii_packet_queue_t)&incoming_packets, + p_rx_rdptr, + p_rxdv_0, + rx_data_0_0, + rx_data_0_1); + } + } + { + if(rx_port_width_1 == 4) + { + rmii_master_rx_pins_4b(rx_mem, + (mii_packet_queue_t)&incoming_packets, + p_rx_rdptr, + p_rxdv_1, + rx_data_1_0, + rx_port_4b_pins_1); + } else { + rmii_master_rx_pins_1b(rx_mem, + (mii_packet_queue_t)&incoming_packets, + p_rx_rdptr, + p_rxdv_1, + rx_data_1_0, + rx_data_1_1); + } + } + rmii_master_tx_pins(tx_mem_lp, + tx_mem_hp, + (mii_packet_queue_t)&tx_packets_lp, + (mii_packet_queue_t)&tx_packets_hp, + ts_queue, + tx_port_width_0, + tx_data_0_0, + tx_data_0_1, + tx_port_4b_pins_0, + txclk_0, + p_port_state); + + rmii_master_tx_pins(tx_mem_lp, + tx_mem_hp, + (mii_packet_queue_t)&tx_packets_lp, + (mii_packet_queue_t)&tx_packets_hp, + ts_queue, + tx_port_width_1, + tx_data_1_0, + tx_data_1_1, + tx_port_4b_pins_1, + txclk_1, + p_port_state); + + + mii_ethernet_filter(c_conf, + (mii_packet_queue_t)&incoming_packets, + (mii_packet_queue_t)&rx_packets_lp, + (mii_packet_queue_t)&rx_packets_hp); + + mii_ethernet_server(rx_mem, + (mii_packet_queue_t)&rx_packets_lp, + (mii_packet_queue_t)&rx_packets_hp, + p_rx_rdptr, + tx_mem_lp, + tx_mem_hp, + (mii_packet_queue_t)&tx_packets_lp, + (mii_packet_queue_t)&tx_packets_hp, + ts_queue, + i_cfg, n_cfg, + i_rx_lp, n_rx_lp, + i_tx_lp, n_tx_lp, + c_rx_hp, + c_tx_hp, + c_conf, + p_port_state); + } // par + } // unsafe block } From 5c44988457d26145c2c8fdbca9ddf89dc3fbf652 Mon Sep 17 00:00:00 2001 From: Ed Date: Mon, 23 Dec 2024 15:49:52 +0000 Subject: [PATCH 03/25] Use setup helpers in rmii_ethernet_rt_mac too --- lib_ethernet/src/rmii_ethernet_rt_mac.xc | 174 ++++++++++------------- 1 file changed, 72 insertions(+), 102 deletions(-) diff --git a/lib_ethernet/src/rmii_ethernet_rt_mac.xc b/lib_ethernet/src/rmii_ethernet_rt_mac.xc index 496374ce..236cf990 100644 --- a/lib_ethernet/src/rmii_ethernet_rt_mac.xc +++ b/lib_ethernet/src/rmii_ethernet_rt_mac.xc @@ -37,6 +37,70 @@ static out buffered port:32 * unsafe enable_buffered_out_port(unsigned *port_poi } + +{unsigned, rmii_data_4b_pin_assignment_t} init_rx_ports(in_port_t p_clk, + in_port_t p_rxdv, + clock rxclk, + rmii_data_port_t * unsafe p_rxd, + in buffered port:32 * unsafe rx_data_0, + in buffered port:32 * unsafe rx_data_1){ + unsafe { + // Extract width and optionally which 4b pins to use + unsigned rx_port_width = ((unsigned)(p_rxd->rmii_data_1b.data_0) >> 16) & 0xff; + rmii_data_4b_pin_assignment_t rx_port_4b_pins = (rmii_data_4b_pin_assignment_t)(p_rxd->rmii_data_1b.data_1); + + // Extract pointers to ports with correct port qualifiers and setup data pins + switch(rx_port_width){ + case 4: + rx_data_0 = enable_buffered_in_port((unsigned*)(&p_rxd->rmii_data_1b.data_0), 32); + rmii_master_init_rx_4b(p_clk, rx_data_0, p_rxdv, rxclk); + break; + case 1: + rx_data_0 = enable_buffered_in_port((unsigned*)&p_rxd->rmii_data_1b.data_0, 32); + rx_data_1 = enable_buffered_in_port((unsigned*)&p_rxd->rmii_data_1b.data_1, 32); + rmii_master_init_rx_1b(p_clk, rx_data_0, rx_data_1, p_rxdv, rxclk); + break; + default: + fail("Invald port width for RMII Rx"); + break; + } + + return {rx_port_width, rx_port_4b_pins}; + } +} + + +{unsigned, rmii_data_4b_pin_assignment_t} init_tx_ports(in_port_t p_clk, + out_port_t p_txen, + clock txclk, + rmii_data_port_t * unsafe p_txd, + out buffered port:32 * unsafe tx_data_0, + out buffered port:32 * unsafe tx_data_1){ + unsafe { + unsigned tx_port_width = ((unsigned)(p_txd->rmii_data_1b.data_0) >> 16) & 0xff; + rmii_data_4b_pin_assignment_t tx_port_4b_pins = (rmii_data_4b_pin_assignment_t)(p_txd->rmii_data_1b.data_1); + + switch(tx_port_width){ + case 4: + tx_data_0 = enable_buffered_out_port((unsigned*)(&p_txd->rmii_data_1b.data_0), 32); + rmii_master_init_tx_4b(p_clk, tx_data_0, p_txen, txclk); + break; + case 1: + tx_data_0 = enable_buffered_out_port((unsigned*)&p_txd->rmii_data_1b.data_0, 32); + tx_data_1 = enable_buffered_out_port((unsigned*)&p_txd->rmii_data_1b.data_1, 32); + rmii_master_init_tx_1b(p_clk, tx_data_0, tx_data_1, p_txen, txclk); + break; + default: + fail("Invald port width for RMII Tx"); + break; + } + + return {tx_port_width, tx_port_4b_pins}; + + } +} + + void rmii_ethernet_rt_mac(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), static_const_unsigned_t n_cfg, SERVER_INTERFACE(ethernet_rx_if, i_rx_lp[n_rx_lp]), static_const_unsigned_t n_rx_lp, SERVER_INTERFACE(ethernet_tx_if, i_tx_lp[n_tx_lp]), static_const_unsigned_t n_tx_lp, @@ -92,56 +156,24 @@ void rmii_ethernet_rt_mac(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), stati mii_ts_queue_t ts_queue = mii_ts_queue_init(&ts_queue_info, ts_fifo, n_tx_lp + 1); - // Common initialisation set_port_use_on(p_clk); // RMII 50MHz clock input port // Setup RX data ports - // First declare C pointers for port resources + // First declare C pointers for port resources and the initialise in buffered port:32 * unsafe rx_data_0 = NULL; in buffered port:32 * unsafe rx_data_1 = NULL; - - // Extract width and optionally which 4b pins to use - unsigned rx_port_width = ((unsigned)(p_rxd->rmii_data_1b.data_0) >> 16) & 0xff; - rmii_data_4b_pin_assignment_t rx_port_4b_pins = (rmii_data_4b_pin_assignment_t)(p_rxd->rmii_data_1b.data_1); - - // Extract pointers to ports with correct port qualifiers and setup data pins - switch(rx_port_width){ - case 4: - rx_data_0 = enable_buffered_in_port((unsigned*)(&p_rxd->rmii_data_1b.data_0), 32); - rmii_master_init_rx_4b(p_clk, rx_data_0, p_rxdv, rxclk); - break; - case 1: - rx_data_0 = enable_buffered_in_port((unsigned*)&p_rxd->rmii_data_1b.data_0, 32); - rx_data_1 = enable_buffered_in_port((unsigned*)&p_rxd->rmii_data_1b.data_1, 32); - rmii_master_init_rx_1b(p_clk, rx_data_0, rx_data_1, p_rxdv, rxclk); - break; - default: - fail("Invald port width for RMII Rx"); - break; - } + unsigned rx_port_width; + rmii_data_4b_pin_assignment_t rx_port_4b_pins; + {rx_port_width, rx_port_4b_pins} = init_rx_ports(p_clk, p_rxdv, rxclk, p_rxd, rx_data_0, rx_data_1); // Setup TX data ports + // First declare C pointers for port resources and the initialise out buffered port:32 * unsafe tx_data_0 = NULL; out buffered port:32 * unsafe tx_data_1 = NULL; - - unsigned tx_port_width = ((unsigned)(p_txd->rmii_data_1b.data_0) >> 16) & 0xff; - rmii_data_4b_pin_assignment_t tx_port_4b_pins = (rmii_data_4b_pin_assignment_t)(p_txd->rmii_data_1b.data_1); - - switch(tx_port_width){ - case 4: - tx_data_0 = enable_buffered_out_port((unsigned*)(&p_txd->rmii_data_1b.data_0), 32); - rmii_master_init_tx_4b(p_clk, tx_data_0, p_txen, txclk); - break; - case 1: - tx_data_0 = enable_buffered_out_port((unsigned*)&p_txd->rmii_data_1b.data_0, 32); - tx_data_1 = enable_buffered_out_port((unsigned*)&p_txd->rmii_data_1b.data_1, 32); - rmii_master_init_tx_1b(p_clk, tx_data_0, tx_data_1, p_txen, txclk); - break; - default: - fail("Invald port width for RMII Tx"); - break; - } + unsigned tx_port_width; + rmii_data_4b_pin_assignment_t tx_port_4b_pins; + {tx_port_width, tx_port_4b_pins} = init_tx_ports(p_clk, p_txen, txclk, p_txd, tx_data_0, tx_data_1); // Setup server ethernet_port_state_t port_state; @@ -209,68 +241,6 @@ void rmii_ethernet_rt_mac(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), stati } -{unsigned, rmii_data_4b_pin_assignment_t} init_rx_ports(in_port_t p_clk, - in_port_t p_rxdv, - clock rxclk, - rmii_data_port_t * unsafe p_rxd, - in buffered port:32 * unsafe rx_data_0, - in buffered port:32 * unsafe rx_data_1){ - unsafe { - // Extract width and optionally which 4b pins to use - unsigned rx_port_width = ((unsigned)(p_rxd->rmii_data_1b.data_0) >> 16) & 0xff; - rmii_data_4b_pin_assignment_t rx_port_4b_pins = (rmii_data_4b_pin_assignment_t)(p_rxd->rmii_data_1b.data_1); - - // Extract pointers to ports with correct port qualifiers and setup data pins - switch(rx_port_width){ - case 4: - rx_data_0 = enable_buffered_in_port((unsigned*)(&p_rxd->rmii_data_1b.data_0), 32); - rmii_master_init_rx_4b(p_clk, rx_data_0, p_rxdv, rxclk); - break; - case 1: - rx_data_0 = enable_buffered_in_port((unsigned*)&p_rxd->rmii_data_1b.data_0, 32); - rx_data_1 = enable_buffered_in_port((unsigned*)&p_rxd->rmii_data_1b.data_1, 32); - rmii_master_init_rx_1b(p_clk, rx_data_0, rx_data_1, p_rxdv, rxclk); - break; - default: - fail("Invald port width for RMII Rx"); - break; - } - - return {rx_port_width, rx_port_4b_pins}; - } -} - -{unsigned, rmii_data_4b_pin_assignment_t} init_tx_ports(in_port_t p_clk, - out_port_t p_txen, - clock txclk, - rmii_data_port_t * unsafe p_txd, - out buffered port:32 * unsafe tx_data_0, - out buffered port:32 * unsafe tx_data_1){ - unsafe { - unsigned tx_port_width = ((unsigned)(p_txd->rmii_data_1b.data_0) >> 16) & 0xff; - rmii_data_4b_pin_assignment_t tx_port_4b_pins = (rmii_data_4b_pin_assignment_t)(p_txd->rmii_data_1b.data_1); - - switch(tx_port_width){ - case 4: - tx_data_0 = enable_buffered_out_port((unsigned*)(&p_txd->rmii_data_1b.data_0), 32); - rmii_master_init_tx_4b(p_clk, tx_data_0, p_txen, txclk); - break; - case 1: - tx_data_0 = enable_buffered_out_port((unsigned*)&p_txd->rmii_data_1b.data_0, 32); - tx_data_1 = enable_buffered_out_port((unsigned*)&p_txd->rmii_data_1b.data_1, 32); - rmii_master_init_tx_1b(p_clk, tx_data_0, tx_data_1, p_txen, txclk); - break; - default: - fail("Invald port width for RMII Tx"); - break; - } - - return {tx_port_width, tx_port_4b_pins}; - - } -} - - void rmii_ethernet_rt_mac_dual(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), static_const_unsigned_t n_cfg, SERVER_INTERFACE(ethernet_rx_if, i_rx_lp[n_rx_lp]), static_const_unsigned_t n_rx_lp, SERVER_INTERFACE(ethernet_tx_if, i_tx_lp[n_tx_lp]), static_const_unsigned_t n_tx_lp, From d016936ddbe7ac35fac798e2087ee7f24f156318 Mon Sep 17 00:00:00 2001 From: Ed Date: Mon, 23 Dec 2024 15:50:28 +0000 Subject: [PATCH 04/25] Update initial local dual mac test app --- examples/test_rmii_dual/do_sim.sh | 7 + .../test_rmii_dual/src/XCORE-AI-EXPLORER.xn | 2 +- examples/test_rmii_dual/src/main.xc | 183 ++++++++---------- 3 files changed, 93 insertions(+), 99 deletions(-) create mode 100644 examples/test_rmii_dual/do_sim.sh diff --git a/examples/test_rmii_dual/do_sim.sh b/examples/test_rmii_dual/do_sim.sh new file mode 100644 index 00000000..32485c87 --- /dev/null +++ b/examples/test_rmii_dual/do_sim.sh @@ -0,0 +1,7 @@ +xsim bin/tx4b_rx4b/test_rmii_dual_tx4b_rx4b.xe --max-cycles 1000000 \ + --trace-plugin VcdPlugin.dll '-tile tile[0] -o trace.vcd -xe bin/tx4b_rx4b/test_rmii_dual_tx4b_rx4b.xe -ports -ports-detailed -cores -instructions -clock-blocks' \ + --plugin LoopbackPort.dll '-port tile[0] XS1_PORT_1C 1 0 -port tile[0] XS1_PORT_1A 1 0' \ + --plugin LoopbackPort.dll '-port tile[0] XS1_PORT_1D 1 0 -port tile[0] XS1_PORT_1B 1 0' \ + --plugin LoopbackPort.dll '-port tile[0] XS1_PORT_1K 1 0 -port tile[0] XS1_PORT_1L 1 0' \ + --plugin LoopbackPort.dll '-port tile[0] XS1_PORT_1I 1 0 -port tile[0] XS1_PORT_1J 1 0' \ + --trace-to trace.txt \ No newline at end of file diff --git a/examples/test_rmii_dual/src/XCORE-AI-EXPLORER.xn b/examples/test_rmii_dual/src/XCORE-AI-EXPLORER.xn index 0baa0215..06ad3b09 100644 --- a/examples/test_rmii_dual/src/XCORE-AI-EXPLORER.xn +++ b/examples/test_rmii_dual/src/XCORE-AI-EXPLORER.xn @@ -12,7 +12,7 @@ - + diff --git a/examples/test_rmii_dual/src/main.xc b/examples/test_rmii_dual/src/main.xc index 619b4ce5..e96b1e02 100644 --- a/examples/test_rmii_dual/src/main.xc +++ b/examples/test_rmii_dual/src/main.xc @@ -8,7 +8,7 @@ #include #include "ethernet.h" -port p_eth_clk = XS1_PORT_1J; +port p_eth_clk = XS1_PORT_1O; #ifndef USE_LOWER #define USE_LOWER 1 @@ -16,37 +16,47 @@ port p_eth_clk = XS1_PORT_1J; #if TX_WIDTH == 4 #if USE_LOWER -rmii_data_port_t p_eth_txd = {{XS1_PORT_4B, USE_LOWER_2B}}; +rmii_data_port_t p_eth_txd_0 = {{XS1_PORT_4B, USE_LOWER_2B}}; +rmii_data_port_t p_eth_txd_1 = {{XS1_PORT_4D, USE_LOWER_2B}}; #else -rmii_data_port_t p_eth_txd = {{XS1_PORT_4B, USE_UPPER_2B}}; +rmii_data_port_t p_eth_txd_0 = {{XS1_PORT_4B, USE_UPPER_2B}}; +rmii_data_port_t p_eth_txd_1 = {{XS1_PORT_4D, USE_UPPER_2B}}; #endif #elif TX_WIDTH == 1 -rmii_data_port_t p_eth_txd = {{XS1_PORT_1C, XS1_PORT_1D}}; +rmii_data_port_t p_eth_txd_0 = {{XS1_PORT_1C, XS1_PORT_1D}}; +rmii_data_port_t p_eth_txd_1 = {{XS1_PORT_1E, XS1_PORT_1F}}; #else #error invalid TX_WIDTH #endif #if RX_WIDTH == 4 #if USE_LOWER -rmii_data_port_t p_eth_rxd = {{XS1_PORT_4A, USE_LOWER_2B}}; +rmii_data_port_t p_eth_rxd_0 = {{XS1_PORT_4A, USE_LOWER_2B}}; +rmii_data_port_t p_eth_rxd_1 = {{XS1_PORT_4C, USE_LOWER_2B}}; #else -rmii_data_port_t p_eth_rxd = {{XS1_PORT_4A, USE_UPPER_2B}}; +rmii_data_port_t p_eth_rxd_0 = {{XS1_PORT_4A, USE_UPPER_2B}}; +rmii_data_port_t p_eth_rxd_1 = {{XS1_PORT_4C, USE_UPPER_2B}}; #endif #elif RX_WIDTH == 1 -rmii_data_port_t p_eth_rxd = {{XS1_PORT_1A, XS1_PORT_1B}}; +rmii_data_port_t p_eth_rxd_0 = {{XS1_PORT_1A, XS1_PORT_1B}}; +rmii_data_port_t p_eth_rxd_1 = {{XS1_PORT_1H, XS1_PORT_1I}}; #else #error invalid RX_WIDTH #endif -port p_eth_rxdv = XS1_PORT_1K; -port p_eth_txen = XS1_PORT_1L; -clock eth_rxclk = XS1_CLKBLK_1; -clock eth_txclk = XS1_CLKBLK_2; +port p_eth_rxdv_0 = XS1_PORT_1K; +port p_eth_rxdv_1 = XS1_PORT_1J; +port p_eth_txen_0 = XS1_PORT_1L; +port p_eth_txen_1 = XS1_PORT_1M; +clock eth_rxclk_0 = XS1_CLKBLK_1; +clock eth_txclk_0 = XS1_CLKBLK_2; +clock eth_rxclk_1 = XS1_CLKBLK_3; +clock eth_txclk_1 = XS1_CLKBLK_4; // Test harness -clock eth_clk_harness = XS1_CLKBLK_3; -port p_eth_clk_harness = XS1_PORT_1I; +clock eth_clk_harness = XS1_CLKBLK_5; +port p_eth_clk_harness = XS1_PORT_1N; #define MAX_PACKET_WORDS ((ETHERNET_MAX_PACKET_SIZE + 3) / 4) @@ -93,62 +103,56 @@ static void printwords_4b(unsigned *b, int n){ -void hp_traffic_tx( client ethernet_cfg_if i_cfg, - client ethernet_tx_if tx_lp, - streaming chanend c_tx_hp, - chanend test_info) +void test_app(client ethernet_cfg_if i_cfg, + client ethernet_rx_if i_rx, + streaming chanend c_rx_hp, + client ethernet_tx_if tx_lp, + streaming chanend c_tx_hp) { - // Request 5Mbits/sec - i_cfg.set_egress_qav_idle_slope(0, calc_idle_slope(5 * 1024 * 1024)); - - unsigned data[MAX_PACKET_WORDS]; - for (size_t i = 0; i < MAX_PACKET_WORDS; i++) { - data[i] = i; - } - - // src/dst MAC addresses - size_t j = 0; - for (; j < 12; j++) - ((char*)data)[j] = j; - - if (VLAN_TAGGED) { - ((char*)data)[j++] = 0x81; - ((char*)data)[j++] = 0x00; - ((char*)data)[j++] = 0x00; - ((char*)data)[j++] = 0x00; - } - - const int length = 61; - const int header_bytes = VLAN_TAGGED ? 18 : 14; - ((char*)data)[j++] = (length - header_bytes) >> 8; - ((char*)data)[j++] = (length - header_bytes) & 0xff; - - timer t; - int time; - t :> time; - t when timerafter(time + 1000) :> time; // Delay sending to allow Rx to be setup - - - int start_length = 1515; - - for(int length = start_length; length < start_length + 4; length++){ - printf("TX sending: %d\n", length); - test_info <: length; - // printbytes((char*)data, length); - // printwords_4b(data, (length + 3)/4); - tx_lp.send_packet((char *)data, length, ETHERNET_ALL_INTERFACES); - // printf("LP packet sent: %d bytes\n", length); - t :> time; - t when timerafter(time + 4000) :> time; - } -} + // Request 5Mbits/sec + i_cfg.set_egress_qav_idle_slope(0, calc_idle_slope(5 * 1024 * 1024)); + + unsigned tx_data[MAX_PACKET_WORDS]; + for (size_t i = 0; i < MAX_PACKET_WORDS; i++) { + tx_data[i] = i; + } + + // src/dst MAC addresses + size_t j = 0; + for (; j < 12; j++) + ((char*)tx_data)[j] = j; + + if (VLAN_TAGGED) { + ((char*)tx_data)[j++] = 0x81; + ((char*)tx_data)[j++] = 0x00; + ((char*)tx_data)[j++] = 0x00; + ((char*)tx_data)[j++] = 0x00; + } + + const int length = 61; + const int header_bytes = VLAN_TAGGED ? 18 : 14; + ((char*)tx_data)[j++] = (length - header_bytes) >> 8; + ((char*)tx_data)[j++] = (length - header_bytes) & 0xff; + + timer t; + int time; + t :> time; + t when timerafter(time + 1000) :> time; // Delay sending to allow Rx to be setup + + + int start_length = 1515; + + for(int length = start_length; length < start_length + 4; length++){ + printf("TX sending: %d\n", length); + // printbytes((char*)data, length); + // printwords_4b(data, (length + 3)/4); + tx_lp.send_packet((char *)tx_data, length, ETHERNET_ALL_INTERFACES); + // printf("LP packet sent: %d bytes\n", length); + t :> time; + t when timerafter(time + 4000) :> time; + } -void rx_app(client ethernet_cfg_if i_cfg, - client ethernet_rx_if i_rx, - streaming chanend c_rx_hp, - chanend test_info) -{ ethernet_macaddr_filter_t macaddr_filter; size_t index = i_rx.get_index(); for (int i = 0; i < MACADDR_NUM_BYTES; i++) { @@ -197,37 +201,18 @@ void rx_app(client ethernet_cfg_if i_cfg, printf("LP packet received: %d bytes\n", n); // printbytes(rxbuf, packet_info.len); break; - - case test_info :> int length: - timeout = 1.5 * (32 * MAX_PACKET_WORDS); - test_packet_lengths[num_test_packets_sent] = length; - num_test_packets_sent++; - tmr :> timeout_trig; - timeout_trig += timeout; - printf("+"); - break; - - case tmr when timerafter(timeout_trig) :> int _: - if(num_test_packets_received != num_test_packets_sent){ - test_pass = 0; - printf("Timed out after %d bit times\n", timeout); - } - - printf("TEST %s\n", test_pass ? "PASS" : "FAIL"); - exit(test_pass); - break; } } } + int main() { - ethernet_cfg_if i_cfg[2]; + ethernet_cfg_if i_cfg[1]; ethernet_rx_if i_rx_lp[1]; ethernet_tx_if i_tx_lp[1]; streaming chan c_rx_hp; streaming chan c_tx_hp; - chan test_info; // Setup 50M clock @@ -238,18 +223,20 @@ int main() start_clock(eth_clk_harness); par { - unsafe{rmii_ethernet_rt_mac(i_cfg, 2, - 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, - 500, 500, ETHERNET_ENABLE_SHAPER);} + unsafe{rmii_ethernet_rt_mac_dual(i_cfg, 1, + i_rx_lp, 1, + i_tx_lp, 1, + c_rx_hp, c_tx_hp, + p_eth_clk, + &p_eth_rxd_0, p_eth_rxdv_0, + p_eth_txen_0, &p_eth_txd_0, + eth_rxclk_0, eth_txclk_0, + &p_eth_rxd_1, p_eth_rxdv_1, + p_eth_txen_1, &p_eth_txd_1, + eth_rxclk_1, eth_txclk_1, + 4000, 4000, ETHERNET_ENABLE_SHAPER);} - rx_app(i_cfg[0], i_rx_lp[0], c_rx_hp, test_info); - hp_traffic_tx(i_cfg[1], i_tx_lp[0], c_tx_hp, test_info); + test_app(i_cfg[0], i_rx_lp[0], c_rx_hp, i_tx_lp[0], c_tx_hp); } return 0; From defd77287050e3f8a9921f0169eea57ce7c4479c Mon Sep 17 00:00:00 2001 From: Ed Date: Mon, 23 Dec 2024 17:14:40 +0000 Subject: [PATCH 05/25] Fix null pointer issue with init_rx_ports --- lib_ethernet/src/rmii_ethernet_rt_mac.xc | 42 +++++++++++++----------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/lib_ethernet/src/rmii_ethernet_rt_mac.xc b/lib_ethernet/src/rmii_ethernet_rt_mac.xc index 236cf990..38d64058 100644 --- a/lib_ethernet/src/rmii_ethernet_rt_mac.xc +++ b/lib_ethernet/src/rmii_ethernet_rt_mac.xc @@ -38,13 +38,14 @@ static out buffered port:32 * unsafe enable_buffered_out_port(unsigned *port_poi -{unsigned, rmii_data_4b_pin_assignment_t} init_rx_ports(in_port_t p_clk, - in_port_t p_rxdv, - clock rxclk, - rmii_data_port_t * unsafe p_rxd, - in buffered port:32 * unsafe rx_data_0, - in buffered port:32 * unsafe rx_data_1){ +{unsigned, rmii_data_4b_pin_assignment_t, in buffered port:32 * unsafe,in buffered port:32 * unsafe } + init_rx_ports(in_port_t p_clk, + in_port_t p_rxdv, + clock rxclk, + rmii_data_port_t * unsafe p_rxd){ unsafe { + in buffered port:32 * unsafe rx_data_0 = NULL; + in buffered port:32 * unsafe rx_data_1 = NULL; // Extract width and optionally which 4b pins to use unsigned rx_port_width = ((unsigned)(p_rxd->rmii_data_1b.data_0) >> 16) & 0xff; rmii_data_4b_pin_assignment_t rx_port_4b_pins = (rmii_data_4b_pin_assignment_t)(p_rxd->rmii_data_1b.data_1); @@ -65,18 +66,19 @@ static out buffered port:32 * unsafe enable_buffered_out_port(unsigned *port_poi break; } - return {rx_port_width, rx_port_4b_pins}; + return {rx_port_width, rx_port_4b_pins, rx_data_0, rx_data_1}; } } -{unsigned, rmii_data_4b_pin_assignment_t} init_tx_ports(in_port_t p_clk, - out_port_t p_txen, - clock txclk, - rmii_data_port_t * unsafe p_txd, - out buffered port:32 * unsafe tx_data_0, - out buffered port:32 * unsafe tx_data_1){ +{unsigned, rmii_data_4b_pin_assignment_t, out buffered port:32 * unsafe, out buffered port:32 * unsafe} + init_tx_ports(in_port_t p_clk, + out_port_t p_txen, + clock txclk, + rmii_data_port_t * unsafe p_txd){ unsafe { + out buffered port:32 * unsafe tx_data_0; + out buffered port:32 * unsafe tx_data_1; unsigned tx_port_width = ((unsigned)(p_txd->rmii_data_1b.data_0) >> 16) & 0xff; rmii_data_4b_pin_assignment_t tx_port_4b_pins = (rmii_data_4b_pin_assignment_t)(p_txd->rmii_data_1b.data_1); @@ -95,7 +97,7 @@ static out buffered port:32 * unsafe enable_buffered_out_port(unsigned *port_poi break; } - return {tx_port_width, tx_port_4b_pins}; + return {tx_port_width, tx_port_4b_pins, tx_data_0, tx_data_1}; } } @@ -165,7 +167,7 @@ void rmii_ethernet_rt_mac(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), stati in buffered port:32 * unsafe rx_data_1 = NULL; unsigned rx_port_width; rmii_data_4b_pin_assignment_t rx_port_4b_pins; - {rx_port_width, rx_port_4b_pins} = init_rx_ports(p_clk, p_rxdv, rxclk, p_rxd, rx_data_0, rx_data_1); + {rx_port_width, rx_port_4b_pins, rx_data_0, rx_data_1} = init_rx_ports(p_clk, p_rxdv, rxclk, p_rxd); // Setup TX data ports // First declare C pointers for port resources and the initialise @@ -173,7 +175,7 @@ void rmii_ethernet_rt_mac(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), stati out buffered port:32 * unsafe tx_data_1 = NULL; unsigned tx_port_width; rmii_data_4b_pin_assignment_t tx_port_4b_pins; - {tx_port_width, tx_port_4b_pins} = init_tx_ports(p_clk, p_txen, txclk, p_txd, tx_data_0, tx_data_1); + {tx_port_width, tx_port_4b_pins, tx_data_0, tx_data_1} = init_tx_ports(p_clk, p_txen, txclk, p_txd); // Setup server ethernet_port_state_t port_state; @@ -311,13 +313,13 @@ void rmii_ethernet_rt_mac_dual(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), in buffered port:32 * unsafe rx_data_0_1 = NULL; unsigned rx_port_width_0; rmii_data_4b_pin_assignment_t rx_port_4b_pins_0; - {rx_port_width_0, rx_port_4b_pins_0} = init_rx_ports(p_clk, p_rxdv_0, rxclk_0, p_rxd_0, rx_data_0_0, rx_data_0_1); + {rx_port_width_0, rx_port_4b_pins_0, rx_data_0_0, rx_data_0_1} = init_rx_ports(p_clk, p_rxdv_0, rxclk_0, p_rxd_0); // MAC port 1 in buffered port:32 * unsafe rx_data_1_0 = NULL; in buffered port:32 * unsafe rx_data_1_1 = NULL; unsigned rx_port_width_1 = 0; rmii_data_4b_pin_assignment_t rx_port_4b_pins_1; - {rx_port_width_1, rx_port_4b_pins_1} = init_rx_ports(p_clk, p_rxdv_1, rxclk_1, p_rxd_1, rx_data_1_0, rx_data_1_1); + {rx_port_width_1, rx_port_4b_pins_1, rx_data_1_0, rx_data_1_1} = init_rx_ports(p_clk, p_rxdv_1, rxclk_1, p_rxd_1); @@ -328,13 +330,13 @@ void rmii_ethernet_rt_mac_dual(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), out buffered port:32 * unsafe tx_data_0_1 = NULL; unsigned tx_port_width_0; rmii_data_4b_pin_assignment_t tx_port_4b_pins_0; - {tx_port_width_0, tx_port_4b_pins_0} = init_tx_ports(p_clk, p_txen_0, txclk_0, p_txd_0, tx_data_0_0, tx_data_0_1); + {tx_port_width_0, tx_port_4b_pins_0, tx_data_0_0, tx_data_0_1} = init_tx_ports(p_clk, p_txen_0, txclk_0, p_txd_0); // MAC port 1 out buffered port:32 * unsafe tx_data_1_0 = NULL; out buffered port:32 * unsafe tx_data_1_1 = NULL; unsigned tx_port_width_1; rmii_data_4b_pin_assignment_t tx_port_4b_pins_1; - {tx_port_width_1, tx_port_4b_pins_1} = init_tx_ports(p_clk, p_txen_1, txclk_1, p_txd_1, tx_data_1_0, tx_data_1_1); + {tx_port_width_1, tx_port_4b_pins_1, tx_data_1_0, tx_data_1_1} = init_tx_ports(p_clk, p_txen_1, txclk_1, p_txd_1); // Setup server ethernet_port_state_t port_state; From c2f069d4fd088818657eb4fad895aa6671632a3c Mon Sep 17 00:00:00 2001 From: Ed Date: Tue, 24 Dec 2024 08:47:43 +0000 Subject: [PATCH 06/25] Initial dual mac basic test --- tests/include/ports_rmii.h | 11 +- tests/test_rmii_dual_basic.py | 122 +++++++++++++++++++ tests/test_rmii_dual_basic/CMakeLists.txt | 85 +++++++++++++ tests/test_rmii_dual_basic/src/config.xscope | 2 + tests/test_rmii_dual_basic/src/main.xc | 81 ++++++++++++ tests/test_rmii_dual_basic/test_params.json | 5 + 6 files changed, 305 insertions(+), 1 deletion(-) create mode 100644 tests/test_rmii_dual_basic.py create mode 100644 tests/test_rmii_dual_basic/CMakeLists.txt create mode 100644 tests/test_rmii_dual_basic/src/config.xscope create mode 100644 tests/test_rmii_dual_basic/src/main.xc create mode 100644 tests/test_rmii_dual_basic/test_params.json diff --git a/tests/include/ports_rmii.h b/tests/include/ports_rmii.h index a023ec0d..f075863f 100644 --- a/tests/include/ports_rmii.h +++ b/tests/include/ports_rmii.h @@ -28,12 +28,15 @@ #if RX_USE_LOWER_2B rmii_data_port_t p_eth_rxd = {{on tile[0]:XS1_PORT_4A, USE_LOWER_2B}}; +rmii_data_port_t p_eth_rxd_2 = {{on tile[0]:XS1_PORT_4C, USE_LOWER_2B}}; #elif RX_USE_UPPER_2B rmii_data_port_t p_eth_rxd = {{on tile[0]:XS1_PORT_4A, USE_UPPER_2B}}; +rmii_data_port_t p_eth_rxd_2 = {{on tile[0]:XS1_PORT_4C, USE_UPPER_2B}}; #endif #elif RX_WIDTH == 1 rmii_data_port_t p_eth_rxd = {{on tile[0]:XS1_PORT_1A, XS1_PORT_1B}}; +rmii_data_port_t p_eth_rxd_2 = {{on tile[0]:XS1_PORT_1E, XS1_PORT_1F}}; #else #error invalid RX_WIDTH #endif @@ -50,22 +53,28 @@ rmii_data_port_t p_eth_rxd = {{on tile[0]:XS1_PORT_1A, XS1_PORT_1B}}; #if TX_USE_LOWER_2B rmii_data_port_t p_eth_txd = {{on tile[0]:XS1_PORT_4B, USE_LOWER_2B}}; + rmii_data_port_t p_eth_txd_2 = {{on tile[0]:XS1_PORT_4D, USE_LOWER_2B}}; #elif TX_USE_UPPER_2B rmii_data_port_t p_eth_txd = {{on tile[0]:XS1_PORT_4B, USE_UPPER_2B}}; + rmii_data_port_t p_eth_txd_2 = {{on tile[0]:XS1_PORT_4D, USE_UPPER_2B}}; #endif #elif TX_WIDTH == 1 rmii_data_port_t p_eth_txd = {{on tile[0]:XS1_PORT_1C, XS1_PORT_1D}}; +rmii_data_port_t p_eth_txd_2 = {{on tile[0]:XS1_PORT_1H, XS1_PORT_1I}}; #else #error invalid TX_WIDTH #endif port p_eth_clk = on tile[0]: XS1_PORT_1J; port p_eth_rxdv = on tile[0]: XS1_PORT_1K; +port p_eth_rxdv_2 = on tile[0]: XS1_PORT_1O; port p_eth_txen = on tile[0]: XS1_PORT_1L; +port p_eth_txen_2 = on tile[0]: XS1_PORT_1P; port p_test_ctrl = on tile[0]: XS1_PORT_1M; clock eth_rxclk = on tile[0]: XS1_CLKBLK_1; clock eth_txclk = on tile[0]: XS1_CLKBLK_2; - +clock eth_rxclk_2 = on tile[0]: XS1_CLKBLK_3; +clock eth_txclk_2 = on tile[0]: XS1_CLKBLK_4; #endif diff --git a/tests/test_rmii_dual_basic.py b/tests/test_rmii_dual_basic.py new file mode 100644 index 00000000..8f9bbeaa --- /dev/null +++ b/tests/test_rmii_dual_basic.py @@ -0,0 +1,122 @@ +# 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, os + +from mii_packet import MiiPacket +from mii_clock import Clock +from helpers import 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, create_if_needed, create_expect, get_sim_args +from helpers import get_rmii_clk, get_rmii_tx_phy, get_rmii_rx_phy +from rmii_phy import RMiiTransmitter, RMiiReceiver + + + +def do_rx_test(capfd, mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, test_file, seed, + extra_tasks=[], override_dut_dir=False, rx_width=None, tx_width=None): + + """ Shared test code for all RX tests using the test_rx application. + """ + testname,extension = os.path.splitext(os.path.basename(test_file)) + + with capfd.disabled(): + print(f"Running {testname}: {mac} {tx_phy.get_name()} phy, {arch}, rx_width {rx_width} arch at {tx_clk.get_name()} (seed = {seed})") + capfd.readouterr() # clear capfd buffer + + profile = f'{mac}_{tx_phy.get_name()}' + if rx_width: + profile = profile + f"_rx{rx_width}" + if tx_width: + profile = profile + f"_tx{tx_width}" + profile = profile + f"_{arch}" + + dut_dir = override_dut_dir if override_dut_dir else testname + binary = f'{dut_dir}/bin/{profile}/{dut_dir}_{profile}.xe' + assert os.path.isfile(binary), f"Missing .xe {binary}" + + tx_phy.set_packets(packets) + rx_phy.set_expected_packets(packets) + + expect_folder = create_if_needed("expect_temp") + if rx_width: + expect_filename = f'{expect_folder}/{testname}_{mac}_{tx_phy.get_name()}_{rx_width}_{tx_width}_{tx_clk.get_name()}_{arch}.expect' + else: + expect_filename = f'{expect_folder}/{testname}_{mac}_{tx_phy.get_name()}_{tx_clk.get_name()}_{arch}.expect' + + create_expect(packets, expect_filename) + + tester = px.testers.ComparisonTester(open(expect_filename)) + + simargs = get_sim_args(testname, mac, tx_clk, tx_phy, arch) + # with capfd.disabled(): + # print(f"simargs {simargs}\n bin: {binary}") + if rx_clk == None: # RMII has only one clock + st = [tx_clk, rx_phy, tx_phy] + else: + st = [rx_clk, rx_phy, tx_clk, tx_phy] + + result = px.run_on_simulator_( binary, + simthreads=st + extra_tasks, + tester=tester, + simargs=simargs, + do_xe_prebuild=False, + capfd=capfd + ) + + assert result is True, f"{result}" + + +def rmii_dual_test(capfd, params, seed): + verbose = False + with capfd.disabled(): + clk = get_rmii_clk(Clock.CLK_50MHz) + tx_rmii_phy = get_rmii_tx_phy(params['rx_width'], + clk, + verbose=verbose + ) + + rx_rmii_phy = get_rmii_rx_phy(params['tx_width'], + clk, + packet_fn=check_received_packet, + verbose=verbose + ) + + mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, rx_width, tx_width = params["mac"], params["arch"], None, rx_rmii_phy, clk, tx_rmii_phy, params['rx_width'],params['tx_width'] + + 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_dual_basic/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) + + rmii_dual_test(capfd, params, seed) + diff --git a/tests/test_rmii_dual_basic/CMakeLists.txt b/tests/test_rmii_dual_basic/CMakeLists.txt new file mode 100644 index 00000000..792f278e --- /dev/null +++ b/tests/test_rmii_dual_basic/CMakeLists.txt @@ -0,0 +1,85 @@ +cmake_minimum_required(VERSION 3.21) +include($ENV{XMOS_CMAKE_PATH}/xcommon.cmake) +project(test_rmii_dual_basic) + +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 XCORE-AI-EXPLORER) + + 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_dual_basic/src/config.xscope b/tests/test_rmii_dual_basic/src/config.xscope new file mode 100644 index 00000000..5c4b0f67 --- /dev/null +++ b/tests/test_rmii_dual_basic/src/config.xscope @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/tests/test_rmii_dual_basic/src/main.xc b/tests/test_rmii_dual_basic/src/main.xc new file mode 100644 index 00000000..a0d3555a --- /dev/null +++ b/tests/test_rmii_dual_basic/src/main.xc @@ -0,0 +1,81 @@ +// 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 { + + unsafe{rmii_ethernet_rt_mac_dual(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, + &p_eth_rxd_2, p_eth_rxdv_2, + p_eth_txen_2, &p_eth_txd_2, + eth_rxclk_2, eth_txclk_2, + 4000, 4000, ETHERNET_ENABLE_SHAPER);} + + loopback(i_cfg[0], i_rx_lp[0], i_tx_lp[0]); + + } + return 0; +} + diff --git a/tests/test_rmii_dual_basic/test_params.json b/tests/test_rmii_dual_basic/test_params.json new file mode 100644 index 00000000..210be0e3 --- /dev/null +++ b/tests/test_rmii_dual_basic/test_params.json @@ -0,0 +1,5 @@ +{ + "PROFILES": [ + {"phy":"rmii", "mac":"rt", "arch":["xs3"], "rx_width":"4b_lower", "tx_width":"4b_lower"} + ] +} From a9eb9865905563c00d0cc4d74ec0a2b147818b6f Mon Sep 17 00:00:00 2001 From: Ed Date: Tue, 24 Dec 2024 10:45:38 +0000 Subject: [PATCH 07/25] Add support for second RMII PHY in tests --- lib_ethernet/src/rmii_ethernet_rt_mac.xc | 3 +- tests/helpers.py | 52 ++++++++++++++++-------- 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/lib_ethernet/src/rmii_ethernet_rt_mac.xc b/lib_ethernet/src/rmii_ethernet_rt_mac.xc index 38d64058..7432f37e 100644 --- a/lib_ethernet/src/rmii_ethernet_rt_mac.xc +++ b/lib_ethernet/src/rmii_ethernet_rt_mac.xc @@ -38,7 +38,7 @@ static out buffered port:32 * unsafe enable_buffered_out_port(unsigned *port_poi -{unsigned, rmii_data_4b_pin_assignment_t, in buffered port:32 * unsafe,in buffered port:32 * unsafe } +{unsigned, rmii_data_4b_pin_assignment_t, in buffered port:32 * unsafe,in buffered port:32 * unsafe} init_rx_ports(in_port_t p_clk, in_port_t p_rxdv, clock rxclk, @@ -204,7 +204,6 @@ void rmii_ethernet_rt_mac(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), stati } } // Tx task - rmii_master_tx_pins(tx_mem_lp, tx_mem_hp, (mii_packet_queue_t)&tx_packets_lp, diff --git a/tests/helpers.py b/tests/helpers.py index 97143baa..f49a470b 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -350,9 +350,14 @@ def get_rmii_rx_phy(tx_width, clk, **kwargs): def get_rmii_4b_port_tx_phy(clk, rxd_4b_port_pin_assignment, **kwargs): - phy = RMiiTransmitter('tile[0]:XS1_PORT_4A', # 4b rxd port - 'tile[0]:XS1_PORT_1K', # 1b rxdv - 'tile[0]:XS1_PORT_1I', # 1b rxerr + rxd = 'tile[0]:XS1_PORT_4C' if "second_phy" in kwargs else 'tile[0]:XS1_PORT_4A' + rxdv = 'tile[0]:XS1_PORT_1O' if "second_phy" in kwargs else 'tile[0]:XS1_PORT_1K' + rxderr = 'tile[0]:XS1_PORT_1I' # Currently unused so assign the same + if "second_phy" in kwargs: kwargs.pop("second_phy") + + phy = RMiiTransmitter(rxd, # 4b rxd port + rxdv, # 1b rxdv + rxderr, # 1b rxerr clk, rxd_4b_port_pin_assignment=rxd_4b_port_pin_assignment, **kwargs @@ -360,28 +365,41 @@ def get_rmii_4b_port_tx_phy(clk, rxd_4b_port_pin_assignment, **kwargs): return phy def get_rmii_1b_port_tx_phy(clk, **kwargs): - phy = RMiiTransmitter(['tile[0]:XS1_PORT_1A', 'tile[0]:XS1_PORT_1B'], # 2, 1b rxd ports - 'tile[0]:XS1_PORT_1K', # 1b rxdv - 'tile[0]:XS1_PORT_1I', # 1b rxerr + rxd = ['tile[0]:XS1_PORT_1E', 'tile[0]:XS1_PORT_1F'] if "second_phy" in kwargs else ['tile[0]:XS1_PORT_1A', 'tile[0]:XS1_PORT_1B'] + rxdv = 'tile[0]:XS1_PORT_1O' if "second_phy" in kwargs else 'tile[0]:XS1_PORT_1K' + rxderr = 'tile[0]:XS1_PORT_1I' # Currently unused so assign the same + if "second_phy" in kwargs: kwargs.pop("second_phy") + + phy = RMiiTransmitter(rxd, # 2, 1b rxd ports + rxdv, # 1b rxdv + rxderr, # 1b rxerr clk, **kwargs ) return phy def get_rmii_4b_port_rx_phy(clk, txd_4b_port_pin_assignment, **kwargs): - phy = RMiiReceiver('tile[0]:XS1_PORT_4B', - 'tile[0]:XS1_PORT_1L', - clk, - txd_4b_port_pin_assignment=txd_4b_port_pin_assignment, - **kwargs - ) + txd = 'tile[0]:XS1_PORT_4D' if "second_phy" in kwargs else 'tile[0]:XS1_PORT_4B' + txen = 'tile[0]:XS1_PORT_1P' if "second_phy" in kwargs else 'tile[0]:XS1_PORT_1L' + if "second_phy" in kwargs: kwargs.pop("second_phy") + + phy = RMiiReceiver(txd, + txen, + clk, + txd_4b_port_pin_assignment=txd_4b_port_pin_assignment, + **kwargs + ) return phy def get_rmii_1b_port_rx_phy(clk, **kwargs): - phy = RMiiReceiver(['tile[0]:XS1_PORT_1C', 'tile[0]:XS1_PORT_1D'], - 'tile[0]:XS1_PORT_1L', - clk, - **kwargs - ) + txd = ['tile[0]:XS1_PORT_1H', 'tile[0]:XS1_PORT_1I'] if "second_phy" in kwargs else ['tile[0]:XS1_PORT_1C', 'tile[0]:XS1_PORT_1D'] + txen = 'tile[0]:XS1_PORT_1P' if "second_phy" in kwargs else 'tile[0]:XS1_PORT_1L' + if "second_phy" in kwargs: kwargs.pop("second_phy") + + phy = RMiiReceiver(txd, + txen, + clk, + **kwargs + ) return phy From febe6ab54789381edb3d5163ce2c925d7d33f071 Mon Sep 17 00:00:00 2001 From: Ed Date: Tue, 24 Dec 2024 10:47:05 +0000 Subject: [PATCH 08/25] Add extra PHYs to test_dual_basic --- tests/test_rmii_dual_basic.py | 47 ++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/tests/test_rmii_dual_basic.py b/tests/test_rmii_dual_basic.py index 8f9bbeaa..55f7ff79 100644 --- a/tests/test_rmii_dual_basic.py +++ b/tests/test_rmii_dual_basic.py @@ -17,7 +17,7 @@ -def do_rx_test(capfd, mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, test_file, seed, +def do_rx_test_dual(capfd, mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, test_file, seed, extra_tasks=[], override_dut_dir=False, rx_width=None, tx_width=None): """ Shared test code for all RX tests using the test_rx application. @@ -25,10 +25,10 @@ def do_rx_test(capfd, mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, test_f testname,extension = os.path.splitext(os.path.basename(test_file)) with capfd.disabled(): - print(f"Running {testname}: {mac} {tx_phy.get_name()} phy, {arch}, rx_width {rx_width} arch at {tx_clk.get_name()} (seed = {seed})") + print(f"Running {testname}: {mac} {[phy.get_name() for phy in tx_phy]} phy, {arch}, rx_width {rx_width} arch at {tx_clk.get_name()} (seed = {seed})") capfd.readouterr() # clear capfd buffer - profile = f'{mac}_{tx_phy.get_name()}' + profile = f'{mac}_{tx_phy[0].get_name()}' if rx_width: profile = profile + f"_rx{rx_width}" if tx_width: @@ -39,26 +39,26 @@ def do_rx_test(capfd, mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, test_f binary = f'{dut_dir}/bin/{profile}/{dut_dir}_{profile}.xe' assert os.path.isfile(binary), f"Missing .xe {binary}" - tx_phy.set_packets(packets) - rx_phy.set_expected_packets(packets) + tx_phy[0].set_packets(packets) + for phy in rx_phy: + phy.set_expected_packets(packets) expect_folder = create_if_needed("expect_temp") if rx_width: - expect_filename = f'{expect_folder}/{testname}_{mac}_{tx_phy.get_name()}_{rx_width}_{tx_width}_{tx_clk.get_name()}_{arch}.expect' + expect_filename = f'{expect_folder}/{testname}_{mac}_{tx_phy[0].get_name()}_{rx_width}_{tx_width}_{tx_clk.get_name()}_{arch}.expect' else: - expect_filename = f'{expect_folder}/{testname}_{mac}_{tx_phy.get_name()}_{tx_clk.get_name()}_{arch}.expect' + expect_filename = f'{expect_folder}/{testname}_{mac}_{tx_phy[0].get_name()}_{tx_clk.get_name()}_{arch}.expect' create_expect(packets, expect_filename) tester = px.testers.ComparisonTester(open(expect_filename)) + tester = None + + simargs = get_sim_args(testname, mac, tx_clk, tx_phy[0], arch) + print(simargs) + + st = [tx_clk, rx_phy[0], rx_phy[1], tx_phy[0], tx_phy[1]] - simargs = get_sim_args(testname, mac, tx_clk, tx_phy, arch) - # with capfd.disabled(): - # print(f"simargs {simargs}\n bin: {binary}") - if rx_clk == None: # RMII has only one clock - st = [tx_clk, rx_phy, tx_phy] - else: - st = [rx_clk, rx_phy, tx_clk, tx_phy] result = px.run_on_simulator_( binary, simthreads=st + extra_tasks, @@ -80,13 +80,26 @@ def rmii_dual_test(capfd, params, seed): verbose=verbose ) + tx_rmii_phy_2 = get_rmii_tx_phy(params['rx_width'], + clk, + verbose=verbose, + second_phy=True + ) + rx_rmii_phy = get_rmii_rx_phy(params['tx_width'], clk, packet_fn=check_received_packet, verbose=verbose ) - mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, rx_width, tx_width = params["mac"], params["arch"], None, rx_rmii_phy, clk, tx_rmii_phy, params['rx_width'],params['tx_width'] + rx_rmii_phy_2 = get_rmii_rx_phy(params['tx_width'], + clk, + packet_fn=check_received_packet, + verbose=verbose, + second_phy=True + ) + + mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, rx_width, tx_width = params["mac"], params["arch"], None, [rx_rmii_phy, rx_rmii_phy_2], clk, [tx_rmii_phy, tx_rmii_phy_2], params['rx_width'],params['tx_width'] rand = random.Random() rand.seed(seed) @@ -102,10 +115,10 @@ def rmii_dual_test(capfd, params, seed): 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), + inter_frame_gap=packet_processing_time(tx_phy[0], 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) + do_rx_test_dual(capfd, mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, __file__, seed, rx_width=rx_width, tx_width=tx_width) From 811cc804d9c4560b8278e3172d4e4f400c6cb075 Mon Sep 17 00:00:00 2001 From: Ed Date: Thu, 2 Jan 2025 14:00:21 +0000 Subject: [PATCH 09/25] More WIP dual rmii eval --- examples/test_rmii_dual/do_sim.sh | 7 ++- .../test_rmii_dual/src/XCORE-AI-EXPLORER.xn | 2 +- examples/test_rmii_dual/src/main.xc | 57 +++++-------------- lib_ethernet/src/rmii_master.xc | 1 + tests/test_rmii_dual_basic.py | 21 ++++++- tests/test_rmii_timing.py | 2 +- 6 files changed, 41 insertions(+), 49 deletions(-) diff --git a/examples/test_rmii_dual/do_sim.sh b/examples/test_rmii_dual/do_sim.sh index 32485c87..8a50a872 100644 --- a/examples/test_rmii_dual/do_sim.sh +++ b/examples/test_rmii_dual/do_sim.sh @@ -1,7 +1,8 @@ xsim bin/tx4b_rx4b/test_rmii_dual_tx4b_rx4b.xe --max-cycles 1000000 \ --trace-plugin VcdPlugin.dll '-tile tile[0] -o trace.vcd -xe bin/tx4b_rx4b/test_rmii_dual_tx4b_rx4b.xe -ports -ports-detailed -cores -instructions -clock-blocks' \ - --plugin LoopbackPort.dll '-port tile[0] XS1_PORT_1C 1 0 -port tile[0] XS1_PORT_1A 1 0' \ - --plugin LoopbackPort.dll '-port tile[0] XS1_PORT_1D 1 0 -port tile[0] XS1_PORT_1B 1 0' \ + --plugin LoopbackPort.dll '-port tile[0] XS1_PORT_1O 1 0 -port tile[0] XS1_PORT_1N 1 0' \ + --plugin LoopbackPort.dll '-port tile[0] XS1_PORT_4A 4 0 -port tile[0] XS1_PORT_4B 4 0' \ --plugin LoopbackPort.dll '-port tile[0] XS1_PORT_1K 1 0 -port tile[0] XS1_PORT_1L 1 0' \ - --plugin LoopbackPort.dll '-port tile[0] XS1_PORT_1I 1 0 -port tile[0] XS1_PORT_1J 1 0' \ + # --plugin LoopbackPort.dll '-port tile[0] XS1_PORT_1J 1 0 -port tile[0] XS1_PORT_1M 1 0' \ + # --plugin LoopbackPort.dll '-port tile[0] XS1_PORT_4C 4 0 -port tile[0] XS1_PORT_4D 4 0' \ --trace-to trace.txt \ No newline at end of file diff --git a/examples/test_rmii_dual/src/XCORE-AI-EXPLORER.xn b/examples/test_rmii_dual/src/XCORE-AI-EXPLORER.xn index 06ad3b09..f46d00cb 100644 --- a/examples/test_rmii_dual/src/XCORE-AI-EXPLORER.xn +++ b/examples/test_rmii_dual/src/XCORE-AI-EXPLORER.xn @@ -12,7 +12,7 @@ - + diff --git a/examples/test_rmii_dual/src/main.xc b/examples/test_rmii_dual/src/main.xc index e96b1e02..957f1404 100644 --- a/examples/test_rmii_dual/src/main.xc +++ b/examples/test_rmii_dual/src/main.xc @@ -134,23 +134,11 @@ void test_app(client ethernet_cfg_if i_cfg, ((char*)tx_data)[j++] = (length - header_bytes) >> 8; ((char*)tx_data)[j++] = (length - header_bytes) & 0xff; - timer t; - int time; - t :> time; - t when timerafter(time + 1000) :> time; // Delay sending to allow Rx to be setup - - - int start_length = 1515; - - for(int length = start_length; length < start_length + 4; length++){ - printf("TX sending: %d\n", length); - // printbytes((char*)data, length); - // printwords_4b(data, (length + 3)/4); - tx_lp.send_packet((char *)tx_data, length, ETHERNET_ALL_INTERFACES); - // printf("LP packet sent: %d bytes\n", length); - t :> time; - t when timerafter(time + 4000) :> time; - } + timer tmr_tx; + int time_tx_trig; + tmr_tx :> time_tx_trig; + + int start_length = 80; ethernet_macaddr_filter_t macaddr_filter; @@ -160,39 +148,15 @@ void test_app(client ethernet_cfg_if i_cfg, } i_cfg.add_macaddr_filter(index, 1, macaddr_filter); - int test_packet_lengths[128] = {0}; - int num_test_packets_sent = 0; - int num_test_packets_received = 0; - - - timer tmr; - int timeout_trig; - tmr :> timeout_trig; - int timeout = 20000; // Bit time is same as ref clock, 100MHz. Set to initial large value for startup - timeout_trig += timeout; - - int test_pass = 1; - while (1) { uint8_t rxbuf[ETHERNET_MAX_PACKET_SIZE]; ethernet_packet_info_t packet_info; + printstr("select\n"); select { case ethernet_receive_hp_packet(c_rx_hp, rxbuf, packet_info): printf("HP packet received: %d bytes\n", packet_info.len); // printbytes(rxbuf, packet_info.len); - if(packet_info.len != test_packet_lengths[num_test_packets_received]){ - printf("Wrong length. Expected %d got %d\n", packet_info.len, test_packet_lengths[num_test_packets_received]); - test_pass = 0; - } - num_test_packets_received++; - if(num_test_packets_received == num_test_packets_sent){ - printf("TEST %s\n", test_pass ? "PASS" : "FAIL"); - exit(test_pass); - } - - tmr :> timeout_trig; - timeout_trig += timeout; break; case i_rx.packet_ready(): @@ -201,6 +165,15 @@ void test_app(client ethernet_cfg_if i_cfg, printf("LP packet received: %d bytes\n", n); // printbytes(rxbuf, packet_info.len); break; + + case tmr_tx when timerafter(time_tx_trig) :> time_tx_trig: + printf("TX sending: %d\n", start_length); + // printbytes((char*)data, length); + // printwords_4b(data, (length + 3)/4); + tx_lp.send_packet((char *)tx_data, start_length, ETHERNET_ALL_INTERFACES); + start_length++; + time_tx_trig += 6000; + break; } } } diff --git a/lib_ethernet/src/rmii_master.xc b/lib_ethernet/src/rmii_master.xc index 0f898c3d..1aee8c68 100644 --- a/lib_ethernet/src/rmii_master.xc +++ b/lib_ethernet/src/rmii_master.xc @@ -448,6 +448,7 @@ unsafe void rmii_master_rx_pins_4b( mii_mempool_t rx_mem, /* to keep up and process the packets so that the incoming_packet */ /* pointers never fill up */ mii_add_packet(incoming_packets, buf); + printstr("mii_add_packet\n"); } } } diff --git a/tests/test_rmii_dual_basic.py b/tests/test_rmii_dual_basic.py index 55f7ff79..dacfc4be 100644 --- a/tests/test_rmii_dual_basic.py +++ b/tests/test_rmii_dual_basic.py @@ -10,7 +10,7 @@ from mii_packet import MiiPacket from mii_clock import Clock from helpers import packet_processing_time, get_dut_mac_address -from helpers import choose_small_frame_size, check_received_packet, run_parametrised_test_rx +from helpers import choose_small_frame_size, run_parametrised_test_rx #check_received_packet from helpers import generate_tests, create_if_needed, create_expect, get_sim_args from helpers import get_rmii_clk, get_rmii_tx_phy, get_rmii_rx_phy from rmii_phy import RMiiTransmitter, RMiiReceiver @@ -70,6 +70,23 @@ def do_rx_test_dual(capfd, mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, t assert result is True, f"{result}" + +def move_to_next_valid_packet(phy): + while (phy.expect_packet_index < phy.num_expected_packets and + phy.expected_packets[phy.expect_packet_index].dropped): + phy.expect_packet_index += 1 + + +def check_received_packet(packet, phy): + if phy.expected_packets is None: + return + + move_to_next_valid_packet(phy) + + print(packet, packet.num_data_bytes, packet.ether_len_type) + print(packet.data_bytes) + + def rmii_dual_test(capfd, params, seed): verbose = False @@ -114,7 +131,7 @@ def rmii_dual_test(capfd, params, seed): for i in range(5): packets.append(MiiPacket(rand, dst_mac_addr=dut_mac_address, - create_data_args=['step', (i, packet_start_len)], + create_data_args=['step', (i, packet_start_len + i)], inter_frame_gap=packet_processing_time(tx_phy[0], packet_start_len, mac), )) diff --git a/tests/test_rmii_timing.py b/tests/test_rmii_timing.py index c05e32e2..ffb22084 100644 --- a/tests/test_rmii_timing.py +++ b/tests/test_rmii_timing.py @@ -50,7 +50,7 @@ def do_test(capfd, mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, seed, rx_width=Non for i in range(5): packets.append(MiiPacket(rand, dst_mac_addr=dut_mac_address, - create_data_args=['step', (i, packet_start_len)], + create_data_args=['step', (i, packet_start_len + i)], inter_frame_gap=packet_processing_time(tx_phy, packet_start_len, mac), )) From a880f7c0d32252e7ee61c9e6ae4529f390cafdc1 Mon Sep 17 00:00:00 2001 From: Shuchita Khare Date: Fri, 10 Jan 2025 17:09:26 +0000 Subject: [PATCH 10/25] Allocate memory pool and queues per ethernet port --- examples/test_rmii_dual/src/main.xc | 14 +- lib_ethernet/api/ethernet.h | 4 +- lib_ethernet/src/client_state.h | 9 +- lib_ethernet/src/client_state.xc | 12 +- lib_ethernet/src/mii_buffering.c | 8 + lib_ethernet/src/mii_buffering.h | 4 +- lib_ethernet/src/mii_ethernet_rt_mac.xc | 264 ++++++++++++++--------- lib_ethernet/src/mii_filter.h | 6 +- lib_ethernet/src/mii_filter.xc | 33 ++- lib_ethernet/src/rgmii_buffering.xc | 34 +-- lib_ethernet/src/rmii_ethernet_rt_mac.xc | 162 ++++++++------ lib_ethernet/src/rmii_master.h | 16 +- tests/test_rmii_dual_basic.py | 17 +- tests/test_rmii_dual_basic/src/main.xc | 2 +- 14 files changed, 358 insertions(+), 227 deletions(-) diff --git a/examples/test_rmii_dual/src/main.xc b/examples/test_rmii_dual/src/main.xc index 957f1404..89192cbc 100644 --- a/examples/test_rmii_dual/src/main.xc +++ b/examples/test_rmii_dual/src/main.xc @@ -21,7 +21,7 @@ rmii_data_port_t p_eth_txd_1 = {{XS1_PORT_4D, USE_LOWER_2B}}; #else rmii_data_port_t p_eth_txd_0 = {{XS1_PORT_4B, USE_UPPER_2B}}; rmii_data_port_t p_eth_txd_1 = {{XS1_PORT_4D, USE_UPPER_2B}}; -#endif +#endif #elif TX_WIDTH == 1 rmii_data_port_t p_eth_txd_0 = {{XS1_PORT_1C, XS1_PORT_1D}}; rmii_data_port_t p_eth_txd_1 = {{XS1_PORT_1E, XS1_PORT_1F}}; @@ -137,7 +137,7 @@ void test_app(client ethernet_cfg_if i_cfg, timer tmr_tx; int time_tx_trig; tmr_tx :> time_tx_trig; - + int start_length = 80; @@ -152,7 +152,7 @@ void test_app(client ethernet_cfg_if i_cfg, uint8_t rxbuf[ETHERNET_MAX_PACKET_SIZE]; ethernet_packet_info_t packet_info; printstr("select\n"); - + select { case ethernet_receive_hp_packet(c_rx_hp, rxbuf, packet_info): printf("HP packet received: %d bytes\n", packet_info.len); @@ -186,11 +186,11 @@ int main() ethernet_tx_if i_tx_lp[1]; streaming chan c_rx_hp; streaming chan c_tx_hp; - + // Setup 50M clock unsigned divider = 2; // 100 / 2 = 50; - configure_clock_ref(eth_clk_harness, divider / 2); + configure_clock_ref(eth_clk_harness, divider / 2); set_port_clock(p_eth_clk_harness, eth_clk_harness); set_port_mode_clock(p_eth_clk_harness); start_clock(eth_clk_harness); @@ -208,9 +208,9 @@ int main() p_eth_txen_1, &p_eth_txd_1, eth_rxclk_1, eth_txclk_1, 4000, 4000, ETHERNET_ENABLE_SHAPER);} - + test_app(i_cfg[0], i_rx_lp[0], c_rx_hp, i_tx_lp[0], c_tx_hp); } return 0; -} \ No newline at end of file +} diff --git a/lib_ethernet/api/ethernet.h b/lib_ethernet/api/ethernet.h index 3039cb0b..1e9aa7ff 100644 --- a/lib_ethernet/api/ethernet.h +++ b/lib_ethernet/api/ethernet.h @@ -59,6 +59,8 @@ typedef enum ethernet_macaddr_filter_result_t { ETHERNET_MACADDR_FILTER_TABLE_FULL /**< The filter entry was not added because the filter table is full */ } ethernet_macaddr_filter_result_t; +#define NUM_ETHERNET_PORTS (2) + #if (defined(__XC__) || defined(__DOXYGEN__)) /** Ethernet MAC configuration interface. @@ -602,7 +604,7 @@ void mii_ethernet_mac(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), static_co -/** ENUM to determine which two bits of a four bit port are to be used as data lines +/** ENUM to determine which two bits of a four bit port are to be used as data lines * in the case that a four bit port is specified for RMII. The other two pins of the four bit * port cannot be used. For Rx the input values are ignored. For Tx, the unused pins are always driven low. */ typedef enum rmii_data_4b_pin_assignment_t{ diff --git a/lib_ethernet/src/client_state.h b/lib_ethernet/src/client_state.h index 5cf95e2d..25ab44b2 100644 --- a/lib_ethernet/src/client_state.h +++ b/lib_ethernet/src/client_state.h @@ -24,9 +24,9 @@ enum status_update_state_t { typedef struct { unsigned dropped_pkt_cnt; - unsigned rd_index; - unsigned wr_index; - void *fifo[ETHERNET_RX_CLIENT_QUEUE_SIZE]; + unsigned rd_index[NUM_ETHERNET_PORTS]; + unsigned wr_index[NUM_ETHERNET_PORTS]; + void *fifo[NUM_ETHERNET_PORTS][ETHERNET_RX_CLIENT_QUEUE_SIZE]; int status_update_state; size_t num_etype_filters; int strip_vlan_tags; @@ -37,9 +37,10 @@ typedef struct typedef struct { int requested_send_buffer_size; - mii_packet_t *send_buffer; + mii_packet_t *send_buffer[NUM_ETHERNET_PORTS]; int has_outgoing_timestamp_info; unsigned outgoing_timestamp; + int dst_port; } tx_client_state_t; #ifdef __XC__ diff --git a/lib_ethernet/src/client_state.xc b/lib_ethernet/src/client_state.xc index 579e33c5..71e9bcdf 100644 --- a/lib_ethernet/src/client_state.xc +++ b/lib_ethernet/src/client_state.xc @@ -6,8 +6,11 @@ void init_rx_client_state(rx_client_state_t client_state[n], unsigned n) { for (unsigned i = 0; i < n; i ++) { client_state[i].dropped_pkt_cnt = 0; - client_state[i].rd_index = 0; - client_state[i].wr_index = 0; + for(int p=0; pptrs, 0, sizeof(info->ptrs)); } +void mii_init_packet_queue_new(packet_queue_info_t *queue) +{ + packet_queue_info_t *info = (packet_queue_info_t *)queue; + info->rd_index = 0; + info->wr_index = 0; + memset(info->ptrs, 0, sizeof(info->ptrs)); +} + mii_mempool_t mii_init_mempool(unsigned *buf, int size) { if (size < 4) diff --git a/lib_ethernet/src/mii_buffering.h b/lib_ethernet/src/mii_buffering.h index fb66049c..f248aad2 100644 --- a/lib_ethernet/src/mii_buffering.h +++ b/lib_ethernet/src/mii_buffering.h @@ -61,7 +61,7 @@ typedef struct mii_packet_t { * The end of the buffer is used to contain a pointer to the start such that when the * end is reached it is a simple load operation from that address to get the start * address. - */ + */ typedef struct mempool_info_t { unsigned *wrptr; unsigned *start; @@ -92,6 +92,8 @@ typedef unsigned * mii_rdptr_t; typedef unsigned * mii_packet_queue_t; void mii_init_packet_queue(mii_packet_queue_t queue); +void mii_init_packet_queue_new(packet_queue_info_t *queue); + mii_mempool_t mii_init_mempool(unsigned *buffer, int size); void mii_init_lock(); diff --git a/lib_ethernet/src/mii_ethernet_rt_mac.xc b/lib_ethernet/src/mii_ethernet_rt_mac.xc index eade2b84..a94e0ffc 100644 --- a/lib_ethernet/src/mii_ethernet_rt_mac.xc +++ b/lib_ethernet/src/mii_ethernet_rt_mac.xc @@ -27,29 +27,33 @@ static inline unsigned int get_tile_id_from_chanend(chanend c) { #define MII_RX_THRESHOLD_BYTES 2000 #endif -unsafe static void reserve(tx_client_state_t client_state[n], unsigned n, mii_mempool_t mem, unsigned * unsafe rdptr) +unsafe static void reserve(tx_client_state_t client_state[n], unsigned n, mii_mempool_t mem, unsigned * unsafe rdptr, int tx_port) { for (unsigned i = 0; i < n; i++) { if (client_state[i].requested_send_buffer_size != 0 && - client_state[i].send_buffer == null) { + client_state[i].send_buffer[tx_port] == null + ) + { debug_printf("Trying to reserve send buffer (client %d, size %d)\n", i, client_state[i].requested_send_buffer_size); - client_state[i].send_buffer = + // reserve memory irrespective of whether the packet is destined for this tx_port. We'll not commit the packet if it isn't + client_state[i].send_buffer[tx_port] = mii_reserve_at_least(mem, rdptr, client_state[i].requested_send_buffer_size + sizeof(mii_packet_t)); } } } -unsafe static void handle_incoming_packet(mii_packet_queue_t packets, +unsafe static unsigned handle_incoming_packet(mii_packet_queue_t packets, unsigned &rd_index, rx_client_state_t client_states[n], server ethernet_rx_if i_rx[n], - unsigned n) + unsigned n, + unsigned current_port) { mii_packet_t * unsafe buf = mii_get_my_next_buf(packets, rd_index); if (!buf) - return; + return 0; int tcount = 0; if (buf->filter_result) { @@ -81,18 +85,18 @@ unsafe static void handle_incoming_packet(mii_packet_queue_t packets, if (client_wants_packet) { debug_printf("Trying to queue for client %d\n", i); - int wr_index = client_state.wr_index; + int wr_index = client_state.wr_index[current_port]; int new_wr_index = increment_and_wrap_to_zero(wr_index, ETHERNET_RX_CLIENT_QUEUE_SIZE); - if (new_wr_index != client_state.rd_index) { + if (new_wr_index != client_state.rd_index[current_port]) { debug_printf("Putting in client queue %d\n", i); // Store the index into the packet queue - client_state.fifo[wr_index] = (void *)rd_index; + client_state.fifo[current_port][wr_index] = (void *)rd_index; tcount++; i_rx[i].packet_ready(); - client_state.wr_index = new_wr_index; + client_state.wr_index[current_port] = new_wr_index; } else { client_state.dropped_pkt_cnt += 1; } @@ -108,18 +112,20 @@ unsafe static void handle_incoming_packet(mii_packet_queue_t packets, } // Only move the rd_index after any clients register using it rd_index = mii_move_my_rd_index(packets, rd_index); + return 1; } unsafe static void drop_lp_packets(mii_packet_queue_t packets, rx_client_state_t client_states[n], - unsigned n) + unsigned n, + unsigned current_port) { for (unsigned i = 0; i < n; i++) { rx_client_state_t &client_state = client_states[i]; - - if (client_state.rd_index != client_state.wr_index) { - unsigned client_rd_index = client_state.rd_index; - unsigned packets_rd_index = (unsigned)client_state.fifo[client_rd_index]; + + if (client_state.rd_index[current_port] != client_state.wr_index[current_port]) { + unsigned client_rd_index = client_state.rd_index[current_port]; + unsigned packets_rd_index = (unsigned)client_state.fifo[current_port][client_rd_index]; packet_queue_info_t * unsafe p_packets = (packet_queue_info_t * unsafe)packets; mii_packet_t * unsafe buf = (mii_packet_t * unsafe)p_packets->ptrs[packets_rd_index]; @@ -127,7 +133,7 @@ unsafe static void drop_lp_packets(mii_packet_queue_t packets, if (mii_get_and_dec_transmit_count(buf) == 0) { mii_free_index(packets, packets_rd_index); } - client_state.rd_index = increment_and_wrap_to_zero(client_state.rd_index, + client_state.rd_index[current_port] = increment_and_wrap_to_zero(client_state.rd_index[current_port], ETHERNET_RX_CLIENT_QUEUE_SIZE); client_state.dropped_pkt_cnt += 1; } @@ -203,14 +209,15 @@ unsafe static inline void handle_ts_queue(mii_ts_queue_t ts_queue, } } -unsafe void mii_ethernet_server(mii_mempool_t rx_mem, - mii_packet_queue_t rx_packets_lp, - mii_packet_queue_t rx_packets_hp, - unsigned * unsafe rx_rdptr, - mii_mempool_t tx_mem_lp, - mii_mempool_t tx_mem_hp, - mii_packet_queue_t tx_packets_lp, - mii_packet_queue_t tx_packets_hp, + +unsafe void mii_ethernet_server(mii_mempool_t * unsafe rx_mem, + mii_packet_queue_t * unsafe rx_packets_lp, + mii_packet_queue_t * unsafe rx_packets_hp, + mii_rdptr_t * unsafe rx_rdptr, + mii_mempool_t * unsafe tx_mem_lp, + mii_mempool_t * unsafe tx_mem_hp, + mii_packet_queue_t * unsafe tx_packets_lp, + mii_packet_queue_t * unsafe tx_packets_hp, mii_ts_queue_t ts_queue_lp, server ethernet_cfg_if i_cfg[n_cfg], static const unsigned n_cfg, server ethernet_rx_if i_rx_lp[n_rx_lp], static const unsigned n_rx_lp, @@ -226,8 +233,20 @@ unsafe void mii_ethernet_server(mii_mempool_t rx_mem, tx_client_state_t tx_client_state_lp[n_tx_lp]; tx_client_state_t tx_client_state_hp[1]; - unsigned rd_index_hp = mii_init_my_rd_index(rx_packets_hp); - unsigned rd_index_lp = mii_init_my_rd_index(rx_packets_lp); + packet_queue_info_t *rx_packets_lp_local = (packet_queue_info_t *)rx_packets_lp; + packet_queue_info_t *rx_packets_hp_local = (packet_queue_info_t *)rx_packets_hp; + + packet_queue_info_t *tx_packets_lp_local = (packet_queue_info_t *)tx_packets_lp; + packet_queue_info_t *tx_packets_hp_local = (packet_queue_info_t *)tx_packets_hp; + + unsigned rd_index_hp[NUM_ETHERNET_PORTS], rd_index_lp[NUM_ETHERNET_PORTS]; + // Server's read index in the rx_packets_lp and rx_packets_hp queues + for(int i=0; iptrs[packets_rd_index]; ethernet_packet_info_t info; @@ -278,7 +299,7 @@ unsafe void mii_ethernet_server(mii_mempool_t rx_mem, info.filter_data = buf->filter_data; int len = (n > buf->length ? buf->length : n); - unsigned * unsafe wrap_ptr = mii_get_wrap_ptr(rx_mem); + unsigned * unsafe wrap_ptr = mii_get_wrap_ptr(rx_mem[current_port_lp]); unsigned * unsafe dptr = buf->data; int prewrap = ((char *) wrap_ptr - (char *) dptr); int len1 = prewrap > len ? len : prewrap; @@ -298,12 +319,12 @@ unsafe void mii_ethernet_server(mii_mempool_t rx_mem, memcpy(&desc, &info, sizeof(info)); if (mii_get_and_dec_transmit_count(buf) == 0) { - mii_free_index(rx_packets_lp, packets_rd_index); + mii_free_index((mii_packet_queue_t)&rx_packets_lp_local[0], packets_rd_index); } - client_state.rd_index = increment_and_wrap_to_zero(client_state.rd_index, + client_state.rd_index[current_port_lp] = increment_and_wrap_to_zero(client_state.rd_index[current_port_lp], ETHERNET_RX_CLIENT_QUEUE_SIZE); - if (client_state.rd_index != client_state.wr_index) { + if (client_state.rd_index[current_port_lp] != client_state.wr_index[current_port_lp]) { i_rx_lp[i].packet_ready(); } } @@ -436,8 +457,11 @@ unsafe void mii_ethernet_server(mii_mempool_t rx_mem, break; case i_tx_lp[int i]._init_send_packet(unsigned n, unsigned dst_port): - if (tx_client_state_lp[i].send_buffer == null) + if (tx_client_state_lp[i].send_buffer[0] == null) + { tx_client_state_lp[i].requested_send_buffer_size = n; + tx_client_state_lp[i].dst_port = dst_port; + } break; [[independent_guard]] @@ -448,10 +472,10 @@ unsafe void mii_ethernet_server(mii_mempool_t rx_mem, tx_client_state_lp[i].has_outgoing_timestamp_info = 0; break; - case (!isnull(c_tx_hp) && tx_client_state_hp[0].send_buffer && !prioritize_rx) => c_tx_hp :> unsigned len: - mii_packet_t * unsafe buf = tx_client_state_hp[0].send_buffer; + case (!isnull(c_tx_hp) && tx_client_state_hp[0].send_buffer[0] && !prioritize_rx) => c_tx_hp :> unsigned len: + mii_packet_t * unsafe buf = tx_client_state_hp[0].send_buffer[0]; unsigned * unsafe dptr = &buf->data[0]; - unsigned * unsafe wrap_ptr = mii_get_wrap_ptr(tx_mem_hp); + unsigned * unsafe wrap_ptr = mii_get_wrap_ptr(tx_mem_hp[0]); unsigned prewrap = ((char *) wrap_ptr - (char *) dptr); unsigned len1 = prewrap > len ? len : prewrap; unsigned len2 = prewrap > len ? 0 : len - prewrap; @@ -470,44 +494,52 @@ unsafe void mii_ethernet_server(mii_mempool_t rx_mem, dptr = dptr + (len+3)/4; } buf->length = len; - mii_commit(tx_mem_hp, dptr); - mii_add_packet(tx_packets_hp, buf); + mii_commit(tx_mem_hp[0], dptr); + mii_add_packet((mii_packet_queue_t)&tx_packets_hp_local[0], buf); buf->tcount = 0; - tx_client_state_hp[0].send_buffer = null; + tx_client_state_hp[0].send_buffer[0] = null; prioritize_rx = 3; break; [[independent_guard]] case (unsigned i = 0; i < n_tx_lp; i++) - (tx_client_state_lp[i].send_buffer != null && !prioritize_rx) => - i_tx_lp[i]._complete_send_packet(char data[n], unsigned n, + (!prioritize_rx) => + i_tx_lp[i]._complete_send_packet(char data[n], unsigned n, int request_timestamp, unsigned dst_port): - mii_packet_t * unsafe buf = tx_client_state_lp[i].send_buffer; - unsigned * unsafe dptr = &buf->data[0]; - unsigned * unsafe wrap_ptr = mii_get_wrap_ptr(tx_mem_lp); - int prewrap = ((char *) wrap_ptr - (char *) dptr); - int len = n; - int len1 = prewrap > len ? len : prewrap; - int len2 = prewrap > len ? 0 : len - prewrap; - memcpy(dptr, data, len1); - if (len2) { - unsigned * unsafe start_ptr = (unsigned *) *wrap_ptr; - memcpy((unsigned *) start_ptr, &data[len1], len2); - dptr = start_ptr + (len2+3)/4; - } - else { - dptr = dptr + (len+3)/4; + + for(int p=0; pdata[0]; + unsigned * unsafe wrap_ptr = mii_get_wrap_ptr(tx_mem_lp[p]); + int prewrap = ((char *) wrap_ptr - (char *) dptr); + int len = n; + int len1 = prewrap > len ? len : prewrap; + int len2 = prewrap > len ? 0 : len - prewrap; + memcpy(dptr, data, len1); + if (len2) { + unsigned * unsafe start_ptr = (unsigned *) *wrap_ptr; + memcpy((unsigned *) start_ptr, &data[len1], len2); + dptr = start_ptr + (len2+3)/4; + } + else { + dptr = dptr + (len+3)/4; + } + buf->length = n; + if (request_timestamp) + buf->timestamp_id = i+1; + else + buf->timestamp_id = 0; + mii_commit(tx_mem_lp[p], dptr); + mii_add_packet((mii_packet_queue_t)&tx_packets_lp_local[p], buf); + buf->tcount = 0; + } + tx_client_state_lp[i].send_buffer[p] = null; } - buf->length = n; - if (request_timestamp) - buf->timestamp_id = i+1; - else - buf->timestamp_id = 0; - mii_commit(tx_mem_lp, dptr); - mii_add_packet(tx_packets_lp, buf); - buf->tcount = 0; - tx_client_state_lp[i].send_buffer = null; + tx_client_state_lp[i].requested_send_buffer_size = 0; prioritize_rx = 3; break; @@ -517,35 +549,50 @@ unsafe void mii_ethernet_server(mii_mempool_t rx_mem, } if (!isnull(c_rx_hp)) { - handle_incoming_hp_packets(rx_mem, rx_packets_hp, rd_index_hp, c_rx_hp, p_port_state); + handle_incoming_hp_packets(rx_mem[0], (mii_packet_queue_t)&rx_packets_hp_local[0], rd_index_hp[0], c_rx_hp, p_port_state); } - handle_incoming_packet(rx_packets_lp, rd_index_lp, rx_client_state_lp, i_rx_lp, n_rx_lp); - - unsigned * unsafe rx_rdptr = mii_get_next_rdptr(rx_packets_lp, rx_packets_hp); + for(int i=0; ilength; // Number of bytes in the frame minus the CRC unsigned crc; @@ -117,16 +130,16 @@ unsafe void mii_ethernet_filter(chanend c_conf, buf->filter_result = filter_result; if (ethernet_filter_result_is_hp(filter_result)) { - if (!mii_packet_queue_full(rx_packets_hp)) { - mii_add_packet(rx_packets_hp, buf); + if (!mii_packet_queue_full((mii_packet_queue_t)&rx_packets_hp_local[current_port])) { + mii_add_packet((mii_packet_queue_t)&rx_packets_hp_local[current_port], buf); } else { // Drop the packet because there is no room in the packet buffer // pointers } } else { - if (!mii_packet_queue_full(rx_packets_lp)) { - mii_add_packet(rx_packets_lp, buf); + if (!mii_packet_queue_full((mii_packet_queue_t)&rx_packets_lp_local[current_port])) { + mii_add_packet((mii_packet_queue_t)&rx_packets_lp_local[current_port], buf); } else { // Drop the packet because there is no room in the packet buffer // pointers diff --git a/lib_ethernet/src/rgmii_buffering.xc b/lib_ethernet/src/rgmii_buffering.xc index 1ccbfbeb..e3ff3d70 100644 --- a/lib_ethernet/src/rgmii_buffering.xc +++ b/lib_ethernet/src/rgmii_buffering.xc @@ -296,16 +296,16 @@ unsafe static void handle_incoming_packet(rx_client_state_t client_states[n], } if (client_wants_packet) { - int wrptr = client_state.wr_index; + int wrptr = client_state.wr_index[0]; int new_wrptr = wrptr + 1; if (new_wrptr >= ETHERNET_RX_CLIENT_QUEUE_SIZE) { new_wrptr = 0; } - if (new_wrptr != client_state.rd_index) { - client_state.fifo[wrptr] = (void *)buf; + if (new_wrptr != client_state.rd_index[0]) { + client_state.fifo[0][wrptr] = (void *)buf; tcount++; i_rx[i].packet_ready(); - client_state.wr_index = new_wrptr; + client_state.wr_index[0] = new_wrptr; } else { client_state.dropped_pkt_cnt += 1; @@ -328,14 +328,14 @@ unsafe static void drop_lp_packets(rx_client_state_t client_states[n], unsigned for (unsigned i = 0; i < n; i++) { rx_client_state_t &client_state = client_states[i]; - unsigned rd_index = client_state.rd_index; - if (rd_index != client_state.wr_index) { - mii_packet_t * unsafe buf = (mii_packet_t * unsafe)client_state.fifo[rd_index]; + unsigned rd_index = client_state.rd_index[0]; + if (rd_index != client_state.wr_index[0]) { + mii_packet_t * unsafe buf = (mii_packet_t * unsafe)client_state.fifo[0][rd_index]; if (mii_get_and_dec_transmit_count(buf) == 0) { buffers_free_add(free_buffers, buf, 1); } - client_state.rd_index = increment_and_wrap_power_of_2(rd_index, + client_state.rd_index[0] = increment_and_wrap_power_of_2(rd_index, ETHERNET_RX_CLIENT_QUEUE_SIZE); client_state.dropped_pkt_cnt += 1; } @@ -440,10 +440,10 @@ unsafe void rgmii_ethernet_rx_server(rx_client_state_t client_state_lp[n_rx_lp], desc.filter_data = 0; client_state.status_update_state = STATUS_UPDATE_WAITING; } - else if (client_state.rd_index != client_state.wr_index) { + else if (client_state.rd_index[0] != client_state.wr_index[0]) { // send received packet - int rd_index = client_state.rd_index; - mii_packet_t * unsafe buf = (mii_packet_t * unsafe)client_state.fifo[rd_index]; + int rd_index = client_state.rd_index[0]; + mii_packet_t * unsafe buf = (mii_packet_t * unsafe)client_state.fifo[0][rd_index]; ethernet_packet_info_t info; info.type = ETH_DATA; info.src_ifnum = 0; // There is only one RGMII port @@ -456,10 +456,10 @@ unsafe void rgmii_ethernet_rx_server(rx_client_state_t client_state_lp[n_rx_lp], buffers_free_add(free_buffers, buf, 1); } - client_state.rd_index = increment_and_wrap_power_of_2(client_state.rd_index, + client_state.rd_index[0] = increment_and_wrap_power_of_2(client_state.rd_index[0], ETHERNET_RX_CLIENT_QUEUE_SIZE); - if (client_state.rd_index != client_state.wr_index) { + if (client_state.rd_index[0] != client_state.wr_index[0]) { i_rx_lp[i].packet_ready(); } } @@ -585,7 +585,7 @@ unsafe void rgmii_ethernet_tx_server(tx_client_state_t client_state_lp[n_tx_lp], int request_timestamp, unsigned dst_port): - mii_packet_t * unsafe buf = client_state_lp[i].send_buffer; + mii_packet_t * unsafe buf = client_state_lp[i].send_buffer[0]; unsigned * unsafe dptr = &buf->data[0]; memcpy(buf->data, data, n); buf->length = n; @@ -602,7 +602,7 @@ unsafe void rgmii_ethernet_tx_server(tx_client_state_t client_state_lp[n_tx_lp], work_pending++; buffers_used_add(used_buffers_tx_lp, buf, RGMII_MAC_BUFFER_COUNT_TX, 0); buf->tcount = 0; - client_state_lp[i].send_buffer = null; + client_state_lp[i].send_buffer[0] = null; client_state_lp[i].requested_send_buffer_size = 0; prioritize_ack += 2; break; @@ -710,8 +710,8 @@ unsafe void rgmii_ethernet_tx_server(tx_client_state_t client_state_lp[n_tx_lp], } for (unsigned i = 0; i < n_tx_lp; i++) { - if (client_state_lp[i].requested_send_buffer_size != 0 && client_state_lp[i].send_buffer == null) { - client_state_lp[i].send_buffer = buffers_free_take(free_buffers_lp, 0); + if (client_state_lp[i].requested_send_buffer_size != 0 && client_state_lp[i].send_buffer[0] == null) { + client_state_lp[i].send_buffer[0] = buffers_free_take(free_buffers_lp, 0); } } } diff --git a/lib_ethernet/src/rmii_ethernet_rt_mac.xc b/lib_ethernet/src/rmii_ethernet_rt_mac.xc index 7432f37e..15a20301 100644 --- a/lib_ethernet/src/rmii_ethernet_rt_mac.xc +++ b/lib_ethernet/src/rmii_ethernet_rt_mac.xc @@ -38,7 +38,7 @@ static out buffered port:32 * unsafe enable_buffered_out_port(unsigned *port_poi -{unsigned, rmii_data_4b_pin_assignment_t, in buffered port:32 * unsafe,in buffered port:32 * unsafe} +{unsigned, rmii_data_4b_pin_assignment_t, in buffered port:32 * unsafe,in buffered port:32 * unsafe} init_rx_ports(in_port_t p_clk, in_port_t p_rxdv, clock rxclk, @@ -122,7 +122,11 @@ void rmii_ethernet_rt_mac(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), stati // Setup buffering unsigned int rx_data[rx_bufsize_words]; unsigned int tx_data[tx_bufsize_words]; - mii_mempool_t rx_mem = mii_init_mempool(rx_data, rx_bufsize_words*4); + mii_mempool_t rx_mem[1]; + mii_mempool_t * unsafe rx_mem_ptr = (mii_mempool_t *)rx_mem; + + + rx_mem[0] = mii_init_mempool(rx_data, rx_bufsize_words*4); // If the high priority traffic is connected then allocate half the buffer for high priority // and half for low priority. Otherwise, allocate it all to low priority. @@ -130,6 +134,8 @@ void rmii_ethernet_rt_mac(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), stati const size_t hp_buffer_bytes = tx_bufsize_words * 4 - lp_buffer_bytes; mii_mempool_t tx_mem_lp = mii_init_mempool(tx_data, lp_buffer_bytes); mii_mempool_t tx_mem_hp = mii_init_mempool(tx_data + (lp_buffer_bytes/4), hp_buffer_bytes); + mii_mempool_t * unsafe tx_mem_lp_ptr = (mii_mempool_t *)&tx_mem_lp; + mii_mempool_t * unsafe tx_mem_hp_ptr = (mii_mempool_t *)&tx_mem_hp; packet_queue_info_t rx_packets_lp, rx_packets_hp, tx_packets_lp, tx_packets_hp, incoming_packets; mii_init_packet_queue((mii_packet_queue_t)&rx_packets_lp); @@ -137,10 +143,15 @@ void rmii_ethernet_rt_mac(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), stati mii_init_packet_queue((mii_packet_queue_t)&tx_packets_lp); mii_init_packet_queue((mii_packet_queue_t)&tx_packets_hp); mii_init_packet_queue((mii_packet_queue_t)&incoming_packets); + mii_packet_queue_t * unsafe incoming_packets_ptr = (mii_packet_queue_t *)&incoming_packets; + mii_packet_queue_t * unsafe rx_packets_lp_ptr = (mii_packet_queue_t *)&rx_packets_lp; + mii_packet_queue_t * unsafe rx_packets_hp_ptr = (mii_packet_queue_t *)&rx_packets_hp; + mii_packet_queue_t * unsafe tx_packets_lp_ptr = (mii_packet_queue_t *)&tx_packets_lp; + mii_packet_queue_t * unsafe tx_packets_hp_ptr = (mii_packet_queue_t *)&tx_packets_hp; // Shared read pointer to help optimize the RX code unsigned rx_rdptr = 0; - unsigned * unsafe p_rx_rdptr = &rx_rdptr; + mii_rdptr_t * unsafe p_rx_rdptr = (mii_rdptr_t*)&rx_rdptr; mii_init_lock(); @@ -167,7 +178,7 @@ void rmii_ethernet_rt_mac(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), stati in buffered port:32 * unsafe rx_data_1 = NULL; unsigned rx_port_width; rmii_data_4b_pin_assignment_t rx_port_4b_pins; - {rx_port_width, rx_port_4b_pins, rx_data_0, rx_data_1} = init_rx_ports(p_clk, p_rxdv, rxclk, p_rxd); + {rx_port_width, rx_port_4b_pins, rx_data_0, rx_data_1} = init_rx_ports(p_clk, p_rxdv, rxclk, p_rxd); // Setup TX data ports // First declare C pointers for port resources and the initialise @@ -188,16 +199,16 @@ void rmii_ethernet_rt_mac(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), stati // Rx task { if(rx_port_width == 4){ - rmii_master_rx_pins_4b(rx_mem, + rmii_master_rx_pins_4b(rx_mem[0], (mii_packet_queue_t)&incoming_packets, - p_rx_rdptr, + (mii_rdptr_t)&rx_rdptr, p_rxdv, rx_data_0, rx_port_4b_pins); } else { - rmii_master_rx_pins_1b(rx_mem, + rmii_master_rx_pins_1b(rx_mem[0], (mii_packet_queue_t)&incoming_packets, - p_rx_rdptr, + (mii_rdptr_t)&rx_rdptr, p_rxdv, rx_data_0, rx_data_1); @@ -217,18 +228,18 @@ void rmii_ethernet_rt_mac(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), stati p_port_state); mii_ethernet_filter(c_conf, - (mii_packet_queue_t)&incoming_packets, - (mii_packet_queue_t)&rx_packets_lp, - (mii_packet_queue_t)&rx_packets_hp); + incoming_packets_ptr, + rx_packets_lp_ptr, + rx_packets_hp_ptr); - mii_ethernet_server(rx_mem, - (mii_packet_queue_t)&rx_packets_lp, - (mii_packet_queue_t)&rx_packets_hp, + mii_ethernet_server(rx_mem_ptr, + rx_packets_lp_ptr, + rx_packets_hp_ptr, p_rx_rdptr, - tx_mem_lp, - tx_mem_hp, - (mii_packet_queue_t)&tx_packets_lp, - (mii_packet_queue_t)&tx_packets_hp, + tx_mem_lp_ptr, + tx_mem_hp_ptr, + tx_packets_lp_ptr, + tx_packets_hp_ptr, ts_queue, i_cfg, n_cfg, i_rx_lp, n_rx_lp, @@ -263,27 +274,51 @@ void rmii_ethernet_rt_mac_dual(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), // Establish types of data ports presented unsafe{ // Setup buffering - unsigned int rx_data[rx_bufsize_words]; - unsigned int tx_data[tx_bufsize_words]; - mii_mempool_t rx_mem = mii_init_mempool(rx_data, rx_bufsize_words*4); + unsigned int rx_data[rx_bufsize_words ][NUM_ETHERNET_PORTS]; + unsigned int tx_data[tx_bufsize_words][NUM_ETHERNET_PORTS]; + mii_mempool_t rx_mem[NUM_ETHERNET_PORTS]; + mii_mempool_t * unsafe rx_mem_ptr = (mii_mempool_t *)rx_mem; + for(int i=0; i Date: Mon, 13 Jan 2025 13:29:14 +0000 Subject: [PATCH 11/25] Modified rmii_master_tx_pins to pass forwarding queues --- lib_ethernet/src/macaddr_filter.h | 3 ++ lib_ethernet/src/macaddr_filter.xc | 16 +++++- lib_ethernet/src/mii_buffering.c | 2 + lib_ethernet/src/mii_ethernet_rt_mac.xc | 7 ++- lib_ethernet/src/mii_filter.xc | 6 +++ lib_ethernet/src/rmii_ethernet_rt_mac.xc | 18 +++++-- lib_ethernet/src/rmii_master.h | 6 ++- lib_ethernet/src/rmii_master.xc | 63 ++++++++++++++++++++++-- tests/helpers.py | 3 ++ tests/test_rmii_dual_basic.py | 49 +++++++++--------- tests/test_rmii_dual_basic/src/main.xc | 2 +- 11 files changed, 138 insertions(+), 37 deletions(-) diff --git a/lib_ethernet/src/macaddr_filter.h b/lib_ethernet/src/macaddr_filter.h index b1e5364b..bd5f58ca 100644 --- a/lib_ethernet/src/macaddr_filter.h +++ b/lib_ethernet/src/macaddr_filter.h @@ -34,6 +34,9 @@ void ethernet_del_filter_table_entry(eth_global_filter_info_t table, void ethernet_clear_filter_table(eth_global_filter_info_t table, unsigned client_num, int is_hp); +int ethernet_filter_result_is_forwarding_set(unsigned value); +unsigned ethernet_filter_result_set_forwarding(unsigned value, int is_forwarding_set); + #ifdef __XC__ unsigned ethernet_do_filtering(eth_global_filter_info_t table, diff --git a/lib_ethernet/src/macaddr_filter.xc b/lib_ethernet/src/macaddr_filter.xc index e9ed2cbe..2d49ef0e 100644 --- a/lib_ethernet/src/macaddr_filter.xc +++ b/lib_ethernet/src/macaddr_filter.xc @@ -10,10 +10,15 @@ int ethernet_filter_result_is_hp(unsigned value) return (value >> 31) ? 1 : 0; } +int ethernet_filter_result_is_forwarding_set(unsigned value) +{ + return ((value >> 30) & 0x1) ? 1 : 0; +} + unsigned ethernet_filter_result_interfaces(unsigned value) { - // Throw away bit 31 - return (value << 1) >> 1; + // Throw away bit 30 and 31 + return (value << 2) >> 2; } unsigned ethernet_filter_result_set_hp(unsigned value, int is_hp) @@ -23,6 +28,13 @@ unsigned ethernet_filter_result_set_hp(unsigned value, int is_hp) return value | (is_hp << 31); } +unsigned ethernet_filter_result_set_forwarding(unsigned value, int is_forwarding_set) +{ + // Ensure it is a single bit in the LSB + is_forwarding_set = is_forwarding_set ? 1 : 0; + return value | (is_forwarding_set << 30); +} + void ethernet_init_filter_table(eth_global_filter_info_t table) { for (size_t i = 0; i < ETHERNET_MACADDR_FILTER_TABLE_SIZE; i++) { diff --git a/lib_ethernet/src/mii_buffering.c b/lib_ethernet/src/mii_buffering.c index c05d6691..e565bda9 100644 --- a/lib_ethernet/src/mii_buffering.c +++ b/lib_ethernet/src/mii_buffering.c @@ -185,6 +185,8 @@ void mii_add_packet(mii_packet_queue_t queue, mii_packet_t *buf) packet_queue_info_t *info = (packet_queue_info_t *)queue; unsigned wr_index = info->wr_index; + buf->forwarding = 0; + info->ptrs[wr_index] = (unsigned *)buf; info->wr_index = increment_and_wrap_power_of_2(wr_index, ETHERNET_NUM_PACKET_POINTERS); } diff --git a/lib_ethernet/src/mii_ethernet_rt_mac.xc b/lib_ethernet/src/mii_ethernet_rt_mac.xc index a94e0ffc..472f914e 100644 --- a/lib_ethernet/src/mii_ethernet_rt_mac.xc +++ b/lib_ethernet/src/mii_ethernet_rt_mac.xc @@ -103,6 +103,11 @@ unsafe static unsigned handle_incoming_packet(mii_packet_queue_t packets, } } } + if(ethernet_filter_result_is_forwarding_set(buf->filter_result)) + { + tcount++; // TODO this assumes that there is only one client we want to forward this to, which is a valid assumption for a 2 port system but doesn't scale + buf->forwarding = 0xffffffff; + } if (tcount == 0) { mii_free_index(packets, rd_index); @@ -319,7 +324,7 @@ unsafe void mii_ethernet_server(mii_mempool_t * unsafe rx_mem, memcpy(&desc, &info, sizeof(info)); if (mii_get_and_dec_transmit_count(buf) == 0) { - mii_free_index((mii_packet_queue_t)&rx_packets_lp_local[0], packets_rd_index); + mii_free_index((mii_packet_queue_t)&rx_packets_lp_local[current_port_lp], packets_rd_index); } client_state.rd_index[current_port_lp] = increment_and_wrap_to_zero(client_state.rd_index[current_port_lp], diff --git a/lib_ethernet/src/mii_filter.xc b/lib_ethernet/src/mii_filter.xc index d37a6a9b..9bedc01c 100644 --- a/lib_ethernet/src/mii_filter.xc +++ b/lib_ethernet/src/mii_filter.xc @@ -129,6 +129,12 @@ unsafe void mii_ethernet_filter(chanend c_conf, debug_printf("Filter result: %x\n", filter_result); buf->filter_result = filter_result; + if(!buf->filter_result) + { + // If none of the clients want the packet, forward it to the tx port + buf->filter_result = ethernet_filter_result_set_forwarding(buf->filter_result, 1); + } + if (ethernet_filter_result_is_hp(filter_result)) { if (!mii_packet_queue_full((mii_packet_queue_t)&rx_packets_hp_local[current_port])) { mii_add_packet((mii_packet_queue_t)&rx_packets_hp_local[current_port], buf); diff --git a/lib_ethernet/src/rmii_ethernet_rt_mac.xc b/lib_ethernet/src/rmii_ethernet_rt_mac.xc index 15a20301..77edecbf 100644 --- a/lib_ethernet/src/rmii_ethernet_rt_mac.xc +++ b/lib_ethernet/src/rmii_ethernet_rt_mac.xc @@ -219,13 +219,17 @@ void rmii_ethernet_rt_mac(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), stati tx_mem_hp, (mii_packet_queue_t)&tx_packets_lp, (mii_packet_queue_t)&tx_packets_hp, + rx_mem_ptr, + rx_packets_lp_ptr, + rx_packets_hp_ptr, ts_queue, tx_port_width, tx_data_0, tx_data_1, tx_port_4b_pins, txclk, - p_port_state); + p_port_state, + 0); mii_ethernet_filter(c_conf, incoming_packets_ptr, @@ -421,25 +425,33 @@ void rmii_ethernet_rt_mac_dual(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), tx_mem_hp[0], (mii_packet_queue_t)(&tx_packets_lp[0]), (mii_packet_queue_t)(&tx_packets_hp[0]), + rx_mem_ptr, // memory pool for the forwarding packets + rx_packets_lp_ptr, // lp forwarding packets queue + rx_packets_hp_ptr, // hp forwarding packets queue ts_queue, tx_port_width_0, tx_data_0_0, tx_data_0_1, tx_port_4b_pins_0, txclk_0, - p_port_state); + p_port_state, + 0); rmii_master_tx_pins(tx_mem_lp[1], tx_mem_hp[1], (mii_packet_queue_t)(&tx_packets_lp[1]), (mii_packet_queue_t)(&tx_packets_hp[1]), + rx_mem_ptr, // memory pool for the forwarding packets + rx_packets_lp_ptr, // lp forwarding packets queue + rx_packets_hp_ptr, // hp forwarding packets queue ts_queue, tx_port_width_1, tx_data_1_0, tx_data_1_1, tx_port_4b_pins_1, txclk_1, - p_port_state); + p_port_state, + 1); mii_ethernet_filter(c_conf, diff --git a/lib_ethernet/src/rmii_master.h b/lib_ethernet/src/rmii_master.h index 204236f7..1ba3b8c8 100644 --- a/lib_ethernet/src/rmii_master.h +++ b/lib_ethernet/src/rmii_master.h @@ -48,13 +48,17 @@ unsafe void rmii_master_tx_pins(mii_mempool_t tx_mem_lp, mii_mempool_t tx_mem_hp, mii_packet_queue_t hp_packets, mii_packet_queue_t lp_packets, + mii_mempool_t * unsafe rx_mem, + mii_packet_queue_t * unsafe rx_packets_lp, + mii_packet_queue_t * unsafe rx_packets_hp, mii_ts_queue_t ts_queue_lp, unsigned tx_port_width, out buffered port:32 * unsafe p_mii_txd_0, out buffered port:32 * unsafe p_mii_txd_1, rmii_data_4b_pin_assignment_t tx_port_4b_pins, clock txclk, - volatile ethernet_port_state_t * unsafe p_port_state); + volatile ethernet_port_state_t * unsafe p_port_state, + int ifnum); // This is re-used by RMII as it is abstracted from the MAC pins diff --git a/lib_ethernet/src/rmii_master.xc b/lib_ethernet/src/rmii_master.xc index 1aee8c68..24b85a73 100644 --- a/lib_ethernet/src/rmii_master.xc +++ b/lib_ethernet/src/rmii_master.xc @@ -857,13 +857,18 @@ unsafe void rmii_master_tx_pins(mii_mempool_t tx_mem_lp, mii_mempool_t tx_mem_hp, mii_packet_queue_t packets_lp, mii_packet_queue_t packets_hp, + mii_mempool_t * unsafe forwarding_mem, + mii_packet_queue_t * unsafe forwarding_packets_lp, + mii_packet_queue_t * unsafe forwarding_packets_hp, mii_ts_queue_t ts_queue_lp, unsigned tx_port_width, out buffered port:32 * unsafe p_mii_txd_0, out buffered port:32 * unsafe p_mii_txd_1, rmii_data_4b_pin_assignment_t tx_port_4b_pins, clock txclk, - volatile ethernet_port_state_t * unsafe p_port_state){ + volatile ethernet_port_state_t * unsafe p_port_state, + int ifnum + ){ // Flag for readability and faster comparison const unsigned use_4b = (tx_port_width == 4); @@ -878,6 +883,9 @@ unsafe void rmii_master_tx_pins(mii_mempool_t tx_mem_lp, unsigned eof_time = 0; unsigned enable_shaper = p_port_state->qav_shaper_enabled; + packet_queue_info_t *fwd_packets_lp_local = (packet_queue_info_t *)forwarding_packets_lp; + packet_queue_info_t *fwd_packets_hp_local = (packet_queue_info_t *)forwarding_packets_hp; + if (!ETHERNET_SUPPORT_TRAFFIC_SHAPER) { enable_shaper = 0; } @@ -886,14 +894,36 @@ unsafe void rmii_master_tx_pins(mii_mempool_t tx_mem_lp, } ifg_tmr :> ifg_time; - while (1) { mii_packet_t * unsafe buf = null; mii_ts_queue_t *p_ts_queue = null; mii_mempool_t tx_mem = tx_mem_hp; + mii_packet_queue_t pkt_queue = packets_hp; if (ETHERNET_SUPPORT_HP_QUEUES){ buf = mii_get_next_buf(packets_hp); + if(!buf) + { + for (unsigned int i=0; iforwarding) + { + tx_mem = forwarding_mem[i]; + pkt_queue = (mii_packet_queue_t)&fwd_packets_hp_local[i]; + break; + } + buf = 0; + } + } } if (enable_shaper) { @@ -915,9 +945,32 @@ unsafe void rmii_master_tx_pins(mii_mempool_t tx_mem_lp, } if (!buf) { + tx_mem = tx_mem_lp; + pkt_queue = packets_lp; buf = mii_get_next_buf(packets_lp); + if(!buf) + { + for (unsigned int i=0; iforwarding) + { + tx_mem = forwarding_mem[i]; + pkt_queue = (mii_packet_queue_t)&fwd_packets_lp_local[i]; + break; + } + buf = 0; + } + } p_ts_queue = &ts_queue_lp; - tx_mem = tx_mem_lp; } if (!buf) { @@ -961,9 +1014,9 @@ unsafe void rmii_master_tx_pins(mii_mempool_t tx_mem_lp, mii_ts_queue_add_entry(*p_ts_queue, buf->timestamp_id, time); } - mii_free_current(packets_lp); + mii_free_current(pkt_queue); } else { - mii_free_current(packets_hp); + mii_free_current(pkt_queue); } } } diff --git a/tests/helpers.py b/tests/helpers.py index f49a470b..d51baefb 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -274,6 +274,9 @@ def check_received_packet(packet, phy): if phy.expect_packet_index >= phy.num_expected_packets: print("Test done") + wait_time_us = 80 # In case the other port is receiving, wait sometime before terminating + wait_time_ticks = (wait_time_us * px.Xsi.get_xsi_tick_freq_hz())/1e6 + phy.wait_until(phy.xsi.get_time() + wait_time_ticks) phy.xsi.terminate() def generate_tests(test_params_json): diff --git a/tests/test_rmii_dual_basic.py b/tests/test_rmii_dual_basic.py index dea5f078..a92187d8 100644 --- a/tests/test_rmii_dual_basic.py +++ b/tests/test_rmii_dual_basic.py @@ -17,7 +17,7 @@ -def do_rx_test_dual(capfd, mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, test_file, seed, +def do_rx_test_dual(capfd, mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, test_file, seed, loopback_packets, forwarded_packets, extra_tasks=[], override_dut_dir=False, rx_width=None, tx_width=None): """ Shared test code for all RX tests using the test_rx application. @@ -40,9 +40,9 @@ def do_rx_test_dual(capfd, mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, t assert os.path.isfile(binary), f"Missing .xe {binary}" tx_phy[1].set_packets(packets) - rx_phy[1].set_expected_packets(packets) - #for phy in rx_phy: - # phy.set_expected_packets(packets) + rx_phy[1].set_expected_packets(loopback_packets) + rx_phy[0].set_expected_packets(forwarded_packets) + expect_folder = create_if_needed("expect_temp") if rx_width: @@ -71,23 +71,6 @@ def do_rx_test_dual(capfd, mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, t assert result is True, f"{result}" -""" -def move_to_next_valid_packet(phy): - while (phy.expect_packet_index < phy.num_expected_packets and - phy.expected_packets[phy.expect_packet_index].dropped): - phy.expect_packet_index += 1 - - -def check_received_packet(packet, phy): - if phy.expected_packets is None: - return - - move_to_next_valid_packet(phy) - - print(packet, packet.num_data_bytes, packet.ether_len_type) - print(packet.data_bytes) -""" - def rmii_dual_test(capfd, params, seed): verbose = False @@ -123,20 +106,38 @@ def rmii_dual_test(capfd, params, seed): rand.seed(seed) dut_mac_address = get_dut_mac_address() - broadcast_mac_address = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff] + not_dut_mac_address = [] + for i in range(6): + not_dut_mac_address.append(dut_mac_address[i]+1) packets = [] + loopback_packets = [] + forwarded_packets = [] # Send frames which excercise all of the tail length vals (0, 1, 2, 3 bytes) packet_start_len = 100 + # Packets that get looped back on the same port for i in range(5): - packets.append(MiiPacket(rand, + loopback_packets.append(MiiPacket(rand, dst_mac_addr=dut_mac_address, create_data_args=['step', (i, packet_start_len + i)], inter_frame_gap=packet_processing_time(tx_phy[0], packet_start_len, mac), )) + # packets that get forwarded to the other port + for i in range(5): + forwarded_packets.append(MiiPacket(rand, + dst_mac_addr=not_dut_mac_address, + create_data_args=['step', (i, packet_start_len + i)], + inter_frame_gap=packet_processing_time(tx_phy[0], packet_start_len, mac), + )) + + # interleave loopback and forwarded packets + for i in range(5): + packets.append(loopback_packets[i]) + packets.append(forwarded_packets[i]) + - do_rx_test_dual(capfd, mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, __file__, seed, rx_width=rx_width, tx_width=tx_width) + do_rx_test_dual(capfd, mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, __file__, seed, loopback_packets, forwarded_packets, rx_width=rx_width, tx_width=tx_width) diff --git a/tests/test_rmii_dual_basic/src/main.xc b/tests/test_rmii_dual_basic/src/main.xc index 81fa91f4..d8daddea 100644 --- a/tests/test_rmii_dual_basic/src/main.xc +++ b/tests/test_rmii_dual_basic/src/main.xc @@ -40,7 +40,7 @@ void loopback(client ethernet_cfg_if cfg, 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); + tx.send_packet(rxbuf, packet_info.len, 1); break; } } From 661fcf4bdd705ce1b37896b9240162c197cf51c6 Mon Sep 17 00:00:00 2001 From: Shuchita Khare Date: Tue, 14 Jan 2025 11:43:57 +0000 Subject: [PATCH 12/25] Add support for hp packets --- lib_ethernet/api/ethernet.h | 3 + lib_ethernet/src/mii_ethernet_mac.xc | 4 + lib_ethernet/src/mii_ethernet_rt_mac.xc | 140 +++++++++++--------- lib_ethernet/src/mii_filter.h | 6 +- lib_ethernet/src/mii_filter.xc | 46 ++++--- lib_ethernet/src/rgmii_buffering.xc | 4 + lib_ethernet/src/rmii_ethernet_rt_mac.xc | 20 +-- lib_ethernet/src/rmii_master.h | 14 +- lib_ethernet/src/rmii_master.xc | 20 ++- tests/test_rmii_dual_basic/src/main.xc | 101 +++++++++++++- tests/test_rmii_dual_basic/test_params.json | 3 +- 11 files changed, 247 insertions(+), 114 deletions(-) diff --git a/lib_ethernet/api/ethernet.h b/lib_ethernet/api/ethernet.h index 1e9aa7ff..276436b1 100644 --- a/lib_ethernet/api/ethernet.h +++ b/lib_ethernet/api/ethernet.h @@ -241,6 +241,8 @@ typedef interface ethernet_cfg_if { */ void disable_link_status_notification(size_t client_num); + void forward_packets_as_hp(unsigned forward_as_hp_flag); + #ifdef __XC__ } ethernet_cfg_if; #endif @@ -408,6 +410,7 @@ inline void ethernet_send_hp_packet(streaming_chanend_t c_tx_hp, unsigned ifnum) { c_tx_hp <: n; + c_tx_hp <: ifnum; sout_char_array(c_tx_hp, packet, n); } diff --git a/lib_ethernet/src/mii_ethernet_mac.xc b/lib_ethernet/src/mii_ethernet_mac.xc index 9fb84bf9..5d296a2b 100644 --- a/lib_ethernet/src/mii_ethernet_mac.xc +++ b/lib_ethernet/src/mii_ethernet_mac.xc @@ -257,6 +257,10 @@ static void mii_ethernet_aux(client mii_if i_mii, client_state.status_update_state = STATUS_UPDATE_IGNORING; break; + case i_cfg[int i].forward_packets_as_hp(unsigned forward_packets_in_hp_queue): + // Do nothing + break; + case i_tx[int i]._complete_send_packet(char data[n], unsigned n, int request_timestamp, unsigned dst_port): diff --git a/lib_ethernet/src/mii_ethernet_rt_mac.xc b/lib_ethernet/src/mii_ethernet_rt_mac.xc index 472f914e..d2b5fbf0 100644 --- a/lib_ethernet/src/mii_ethernet_rt_mac.xc +++ b/lib_ethernet/src/mii_ethernet_rt_mac.xc @@ -149,7 +149,8 @@ unsafe static void handle_incoming_hp_packets(mii_mempool_t rxmem, mii_packet_queue_t packets, unsigned &rd_index, streaming chanend c_rx_hp, - volatile ethernet_port_state_t * unsafe p_port_state) + volatile ethernet_port_state_t * unsafe p_port_state, + unsigned current_port) { while (1) { mii_packet_t * unsafe buf = mii_get_my_next_buf(packets, rd_index); @@ -158,7 +159,7 @@ unsafe static void handle_incoming_hp_packets(mii_mempool_t rxmem, int client_wants_packet = 0; if (buf->filter_result && ethernet_filter_result_is_hp(buf->filter_result)) { - client_wants_packet = (buf->filter_result & 1); + client_wants_packet = (buf->filter_result & 1); // there's only one hp client?? } if (client_wants_packet) @@ -183,8 +184,16 @@ unsafe static void handle_incoming_hp_packets(mii_mempool_t rxmem, sout_char_array(c_rx_hp, (char *)*wrap_ptr, len2); } } - - rd_index = mii_free_index(packets, rd_index); + if(ethernet_filter_result_is_forwarding_set(buf->filter_result)) + { + buf->forwarding = 0xffffffff; + buf->tcount = 0; + } + else + { + mii_free_index(packets, rd_index); + } + rd_index = mii_move_my_rd_index(packets, rd_index); } } @@ -216,13 +225,13 @@ unsafe static inline void handle_ts_queue(mii_ts_queue_t ts_queue, unsafe void mii_ethernet_server(mii_mempool_t * unsafe rx_mem, - mii_packet_queue_t * unsafe rx_packets_lp, - mii_packet_queue_t * unsafe rx_packets_hp, + packet_queue_info_t * unsafe rx_packets_lp, + packet_queue_info_t * unsafe rx_packets_hp, mii_rdptr_t * unsafe rx_rdptr, mii_mempool_t * unsafe tx_mem_lp, mii_mempool_t * unsafe tx_mem_hp, - mii_packet_queue_t * unsafe tx_packets_lp, - mii_packet_queue_t * unsafe tx_packets_hp, + packet_queue_info_t * unsafe tx_packets_lp, + packet_queue_info_t * unsafe tx_packets_hp, mii_ts_queue_t ts_queue_lp, server ethernet_cfg_if i_cfg[n_cfg], static const unsigned n_cfg, server ethernet_rx_if i_rx_lp[n_rx_lp], static const unsigned n_rx_lp, @@ -238,18 +247,13 @@ unsafe void mii_ethernet_server(mii_mempool_t * unsafe rx_mem, tx_client_state_t tx_client_state_lp[n_tx_lp]; tx_client_state_t tx_client_state_hp[1]; - packet_queue_info_t *rx_packets_lp_local = (packet_queue_info_t *)rx_packets_lp; - packet_queue_info_t *rx_packets_hp_local = (packet_queue_info_t *)rx_packets_hp; - - packet_queue_info_t *tx_packets_lp_local = (packet_queue_info_t *)tx_packets_lp; - packet_queue_info_t *tx_packets_hp_local = (packet_queue_info_t *)tx_packets_hp; unsigned rd_index_hp[NUM_ETHERNET_PORTS], rd_index_lp[NUM_ETHERNET_PORTS]; // Server's read index in the rx_packets_lp and rx_packets_hp queues for(int i=0; iptrs[packets_rd_index]; ethernet_packet_info_t info; @@ -324,7 +327,7 @@ unsafe void mii_ethernet_server(mii_mempool_t * unsafe rx_mem, memcpy(&desc, &info, sizeof(info)); if (mii_get_and_dec_transmit_count(buf) == 0) { - mii_free_index((mii_packet_queue_t)&rx_packets_lp_local[current_port_lp], packets_rd_index); + mii_free_index((mii_packet_queue_t)&rx_packets_lp[current_port_lp], packets_rd_index); } client_state.rd_index[current_port_lp] = increment_and_wrap_to_zero(client_state.rd_index[current_port_lp], @@ -355,6 +358,11 @@ unsafe void mii_ethernet_server(mii_mempool_t * unsafe rx_mem, } break; + case i_cfg[int i].forward_packets_as_hp(unsigned forward_packets_in_hp_queue): + c_macaddr_filter <: 1; + c_macaddr_filter <: forward_packets_in_hp_queue; + break; + case i_cfg[int i].add_macaddr_filter(size_t client_num, int is_hp, ethernet_macaddr_filter_t entry) -> ethernet_macaddr_filter_result_t result: @@ -477,32 +485,40 @@ unsafe void mii_ethernet_server(mii_mempool_t * unsafe rx_mem, tx_client_state_lp[i].has_outgoing_timestamp_info = 0; break; - case (!isnull(c_tx_hp) && tx_client_state_hp[0].send_buffer[0] && !prioritize_rx) => c_tx_hp :> unsigned len: - mii_packet_t * unsafe buf = tx_client_state_hp[0].send_buffer[0]; - unsigned * unsafe dptr = &buf->data[0]; - unsigned * unsafe wrap_ptr = mii_get_wrap_ptr(tx_mem_hp[0]); - unsigned prewrap = ((char *) wrap_ptr - (char *) dptr); - unsigned len1 = prewrap > len ? len : prewrap; - unsigned len2 = prewrap > len ? 0 : len - prewrap; - unsigned * unsafe start_ptr = (unsigned *) *wrap_ptr; - - // sout_char_array sends bytes in reverse order so the second - // half must be received first - if (len2) { - sin_char_array(c_tx_hp, (char*)start_ptr, len2); - } - sin_char_array(c_tx_hp, (char*)dptr, len1); - if (len2) { - dptr = start_ptr + (len2+3)/4; - } - else { - dptr = dptr + (len+3)/4; + case (!isnull(c_tx_hp) && !prioritize_rx) => c_tx_hp :> unsigned len: + unsigned dst_port; + c_tx_hp :> dst_port; + for(int p=0; pdata[0]; + unsigned * unsafe wrap_ptr = mii_get_wrap_ptr(tx_mem_hp[dst_port]); + unsigned prewrap = ((char *) wrap_ptr - (char *) dptr); + unsigned len1 = prewrap > len ? len : prewrap; + unsigned len2 = prewrap > len ? 0 : len - prewrap; + unsigned * unsafe start_ptr = (unsigned *) *wrap_ptr; + + // sout_char_array sends bytes in reverse order so the second + // half must be received first + if (len2) { + sin_char_array(c_tx_hp, (char*)start_ptr, len2); + } + sin_char_array(c_tx_hp, (char*)dptr, len1); + if (len2) { + dptr = start_ptr + (len2+3)/4; + } + else { + dptr = dptr + (len+3)/4; + } + buf->length = len; + mii_commit(tx_mem_hp[dst_port], dptr); + mii_add_packet((mii_packet_queue_t)&tx_packets_hp[dst_port], buf); + buf->tcount = 0; + } + tx_client_state_hp[0].send_buffer[0] = null; } - buf->length = len; - mii_commit(tx_mem_hp[0], dptr); - mii_add_packet((mii_packet_queue_t)&tx_packets_hp_local[0], buf); - buf->tcount = 0; - tx_client_state_hp[0].send_buffer[0] = null; prioritize_rx = 3; break; @@ -539,7 +555,7 @@ unsafe void mii_ethernet_server(mii_mempool_t * unsafe rx_mem, else buf->timestamp_id = 0; mii_commit(tx_mem_lp[p], dptr); - mii_add_packet((mii_packet_queue_t)&tx_packets_lp_local[p], buf); + mii_add_packet((mii_packet_queue_t)&tx_packets_lp[p], buf); buf->tcount = 0; } tx_client_state_lp[i].send_buffer[p] = null; @@ -554,12 +570,15 @@ unsafe void mii_ethernet_server(mii_mempool_t * unsafe rx_mem, } if (!isnull(c_rx_hp)) { - handle_incoming_hp_packets(rx_mem[0], (mii_packet_queue_t)&rx_packets_hp_local[0], rd_index_hp[0], c_rx_hp, p_port_state); + for(int i=0; i int: + case c_conf :> int i: // Give the routing table to the ethernet server to reconfigure unsafe { - eth_global_filter_info_t * unsafe p = &filter_info; - c_conf <: p; - c_conf :> int; + if(i == 0) // Add mac addr filter table entry + { + eth_global_filter_info_t * unsafe p = &filter_info; + c_conf <: p; + c_conf :> int; + } + else if(i == 1) // communicate if forwarding packets need to go in hp queue + { + c_conf :> forward_packets_as_high_priority; + } } break; default: break; } - packet_queue_info_t *incoming_packets_local = (packet_queue_info_t*)incoming_packets; - packet_queue_info_t *rx_packets_lp_local = (packet_queue_info_t *)rx_packets_lp; - packet_queue_info_t *rx_packets_hp_local = (packet_queue_info_t *)rx_packets_hp; - mii_packet_t * unsafe buf = mii_get_next_buf((mii_packet_queue_t)&incoming_packets_local[0]); + mii_packet_t * unsafe buf = mii_get_next_buf((mii_packet_queue_t)&incoming_packets[0]); current_port = 0; if (buf == null) { - buf = mii_get_next_buf((mii_packet_queue_t)&incoming_packets_local[1]); + buf = mii_get_next_buf((mii_packet_queue_t)&incoming_packets[1]); if(buf == null) { continue; @@ -87,7 +92,7 @@ unsafe void mii_ethernet_filter(chanend c_conf, } - mii_move_rd_index((mii_packet_queue_t)&incoming_packets_local[current_port]); + mii_move_rd_index((mii_packet_queue_t)&incoming_packets[current_port]); unsigned length = buf->length; // Number of bytes in the frame minus the CRC unsigned crc; @@ -118,7 +123,7 @@ unsafe void mii_ethernet_filter(chanend c_conf, continue; } - buf->src_port = 0; + buf->src_port = current_port; buf->timestamp_id = 0; char * unsafe data = (char * unsafe) buf->data; @@ -131,21 +136,22 @@ unsafe void mii_ethernet_filter(chanend c_conf, if(!buf->filter_result) { - // If none of the clients want the packet, forward it to the tx port + // If none of the clients want the packet, forward it to the other tx port buf->filter_result = ethernet_filter_result_set_forwarding(buf->filter_result, 1); } - if (ethernet_filter_result_is_hp(filter_result)) { - if (!mii_packet_queue_full((mii_packet_queue_t)&rx_packets_hp_local[current_port])) { - mii_add_packet((mii_packet_queue_t)&rx_packets_hp_local[current_port], buf); + if (ethernet_filter_result_is_hp(buf->filter_result) || forward_packets_as_high_priority) + { + if (!mii_packet_queue_full((mii_packet_queue_t)&rx_packets_hp[current_port])) { + mii_add_packet((mii_packet_queue_t)&rx_packets_hp[current_port], buf); } else { // Drop the packet because there is no room in the packet buffer // pointers } } else { - if (!mii_packet_queue_full((mii_packet_queue_t)&rx_packets_lp_local[current_port])) { - mii_add_packet((mii_packet_queue_t)&rx_packets_lp_local[current_port], buf); + if (!mii_packet_queue_full((mii_packet_queue_t)&rx_packets_lp[current_port])) { + mii_add_packet((mii_packet_queue_t)&rx_packets_lp[current_port], buf); } else { // Drop the packet because there is no room in the packet buffer // pointers diff --git a/lib_ethernet/src/rgmii_buffering.xc b/lib_ethernet/src/rgmii_buffering.xc index e3ff3d70..c68c8f23 100644 --- a/lib_ethernet/src/rgmii_buffering.xc +++ b/lib_ethernet/src/rgmii_buffering.xc @@ -858,6 +858,10 @@ void rgmii_ethernet_mac_config(server ethernet_cfg_if i_cfg[n], break; } + case i_cfg[int i].forward_packets_as_hp(unsigned forward_packets_in_hp_queue): + // Do nothing + break; + case c_rgmii_cfg :> unsigned tmp: // Server has reset unsafe { diff --git a/lib_ethernet/src/rmii_ethernet_rt_mac.xc b/lib_ethernet/src/rmii_ethernet_rt_mac.xc index 77edecbf..0f0cdf36 100644 --- a/lib_ethernet/src/rmii_ethernet_rt_mac.xc +++ b/lib_ethernet/src/rmii_ethernet_rt_mac.xc @@ -143,11 +143,11 @@ void rmii_ethernet_rt_mac(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), stati mii_init_packet_queue((mii_packet_queue_t)&tx_packets_lp); mii_init_packet_queue((mii_packet_queue_t)&tx_packets_hp); mii_init_packet_queue((mii_packet_queue_t)&incoming_packets); - mii_packet_queue_t * unsafe incoming_packets_ptr = (mii_packet_queue_t *)&incoming_packets; - mii_packet_queue_t * unsafe rx_packets_lp_ptr = (mii_packet_queue_t *)&rx_packets_lp; - mii_packet_queue_t * unsafe rx_packets_hp_ptr = (mii_packet_queue_t *)&rx_packets_hp; - mii_packet_queue_t * unsafe tx_packets_lp_ptr = (mii_packet_queue_t *)&tx_packets_lp; - mii_packet_queue_t * unsafe tx_packets_hp_ptr = (mii_packet_queue_t *)&tx_packets_hp; + packet_queue_info_t * unsafe incoming_packets_ptr = &incoming_packets; + packet_queue_info_t * unsafe rx_packets_lp_ptr = &rx_packets_lp; + packet_queue_info_t * unsafe rx_packets_hp_ptr = &rx_packets_hp; + packet_queue_info_t * unsafe tx_packets_lp_ptr = &tx_packets_lp; + packet_queue_info_t * unsafe tx_packets_hp_ptr = &tx_packets_hp; // Shared read pointer to help optimize the RX code unsigned rx_rdptr = 0; @@ -304,11 +304,11 @@ void rmii_ethernet_rt_mac_dual(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), packet_queue_info_t rx_packets_lp[NUM_ETHERNET_PORTS], rx_packets_hp[NUM_ETHERNET_PORTS], incoming_packets[NUM_ETHERNET_PORTS]; packet_queue_info_t tx_packets_lp[NUM_ETHERNET_PORTS], tx_packets_hp[NUM_ETHERNET_PORTS]; - mii_packet_queue_t * unsafe incoming_packets_ptr = (mii_packet_queue_t *)incoming_packets; - mii_packet_queue_t * unsafe rx_packets_lp_ptr = (mii_packet_queue_t *)rx_packets_lp; - mii_packet_queue_t * unsafe rx_packets_hp_ptr = (mii_packet_queue_t *)rx_packets_hp; - mii_packet_queue_t * unsafe tx_packets_lp_ptr = (mii_packet_queue_t *)tx_packets_lp; - mii_packet_queue_t * unsafe tx_packets_hp_ptr = (mii_packet_queue_t *)tx_packets_hp; + packet_queue_info_t * unsafe incoming_packets_ptr = incoming_packets; + packet_queue_info_t * unsafe rx_packets_lp_ptr = rx_packets_lp; + packet_queue_info_t * unsafe rx_packets_hp_ptr = rx_packets_hp; + packet_queue_info_t * unsafe tx_packets_lp_ptr = tx_packets_lp; + packet_queue_info_t * unsafe tx_packets_hp_ptr = tx_packets_hp; for(int i=0; iqav_shaper_enabled; - packet_queue_info_t *fwd_packets_lp_local = (packet_queue_info_t *)forwarding_packets_lp; - packet_queue_info_t *fwd_packets_hp_local = (packet_queue_info_t *)forwarding_packets_hp; if (!ETHERNET_SUPPORT_TRAFFIC_SHAPER) { enable_shaper = 0; @@ -910,15 +908,15 @@ unsafe void rmii_master_tx_pins(mii_mempool_t tx_mem_lp, { continue; } - buf = mii_get_next_buf((mii_packet_queue_t)(&fwd_packets_hp_local[i])); + buf = mii_get_next_buf((mii_packet_queue_t)(&forwarding_packets_hp[i])); if(!buf) { continue; } if(buf->forwarding) { - tx_mem = forwarding_mem[i]; - pkt_queue = (mii_packet_queue_t)&fwd_packets_hp_local[i]; + tx_mem = forwarding_packets_mem[i]; + pkt_queue = (mii_packet_queue_t)&forwarding_packets_hp[i]; break; } buf = 0; @@ -956,15 +954,15 @@ unsafe void rmii_master_tx_pins(mii_mempool_t tx_mem_lp, { continue; } - buf = mii_get_next_buf((mii_packet_queue_t)(&fwd_packets_lp_local[i])); + buf = mii_get_next_buf((mii_packet_queue_t)(&forwarding_packets_lp[i])); if(!buf) { continue; } if(buf->forwarding) { - tx_mem = forwarding_mem[i]; - pkt_queue = (mii_packet_queue_t)&fwd_packets_lp_local[i]; + tx_mem = forwarding_packets_mem[i]; + pkt_queue = (mii_packet_queue_t)&forwarding_packets_lp[i]; break; } buf = 0; diff --git a/tests/test_rmii_dual_basic/src/main.xc b/tests/test_rmii_dual_basic/src/main.xc index d8daddea..9c006248 100644 --- a/tests/test_rmii_dual_basic/src/main.xc +++ b/tests/test_rmii_dual_basic/src/main.xc @@ -11,9 +11,89 @@ #include "ports_rmii.h" +#if ETHERNET_SUPPORT_HP_QUEUES +typedef interface loopback_if { + [[notification]] slave void packet_ready(); + [[clears_notification]] void get_packet(unsigned &len, uintptr_t &buf); +} loopback_if; + +void test_loopback(streaming chanend c_tx_hp, + client loopback_if i_loopback) +{ + set_core_fast_mode_on(); + + unsafe { + while (1) { + unsigned len; + uintptr_t buf; + + select { + case i_loopback.packet_ready(): + i_loopback.get_packet(len, buf); + break; + } + ethernet_send_hp_packet(c_tx_hp, (char *)buf, len, 1); + } + } +} +#define NUM_BUF 8 -void loopback(client ethernet_cfg_if cfg, +void test_rx(client ethernet_cfg_if cfg, + streaming chanend c_rx_hp, + server loopback_if i_loopback) +{ + set_core_fast_mode_on(); + + ethernet_macaddr_filter_t macaddr_filter; + + macaddr_filter.appdata = 0; + for (int i = 0; i < 6; i++) + macaddr_filter.addr[i] = i; + cfg.add_macaddr_filter(0, 1, macaddr_filter); + + // Add the broadcast MAC address + memset(macaddr_filter.addr, 0xff, 6); + cfg.add_macaddr_filter(0, 1, macaddr_filter); + + cfg.forward_packets_as_hp(1); // put the forwarding packets in hp queue. For testing only. In reality, client doesn't get to tell this to the Mac. + + unsigned char rxbuf[NUM_BUF][ETHERNET_MAX_PACKET_SIZE]; + unsigned rxlen[NUM_BUF]; + unsigned wr_index = 0; + unsigned rd_index = 0; + + int done = 0; + while (!done) { + ethernet_packet_info_t packet_info; + + #pragma ordered + select { + case ethernet_receive_hp_packet(c_rx_hp, rxbuf[wr_index], packet_info): + rxlen[wr_index] = packet_info.len; + wr_index = (wr_index + 1) % NUM_BUF; + if (wr_index == rd_index) { + debug_printf("test_rx ran out of buffers\n"); + _exit(1); + } + i_loopback.packet_ready(); + break; + + case i_loopback.get_packet(unsigned &len, uintptr_t &buf): { + len = rxlen[rd_index]; + buf = (uintptr_t)&rxbuf[rd_index]; + rd_index = (rd_index + 1) % NUM_BUF; + + if (rd_index != wr_index) + i_loopback.packet_ready(); + break; + } + } + } +} + +#else +void test_rx_loopback(client ethernet_cfg_if cfg, client ethernet_rx_if rx, client ethernet_tx_if tx) { @@ -45,6 +125,7 @@ void loopback(client ethernet_cfg_if cfg, } } } +#endif #define NUM_CFG_IF 1 @@ -57,13 +138,22 @@ int main() ethernet_rx_if i_rx_lp[NUM_RX_LP_IF]; ethernet_tx_if i_tx_lp[NUM_TX_LP_IF]; +#if ETHERNET_SUPPORT_HP_QUEUES + loopback_if i_loopback; + streaming chan c_rx_hp; + streaming chan c_tx_hp; +#else + #define c_rx_hp null + #define c_tx_hp null +#endif + par { unsafe{rmii_ethernet_rt_mac_dual(i_cfg, NUM_CFG_IF, i_rx_lp, NUM_RX_LP_IF, i_tx_lp, NUM_TX_LP_IF, - NULL, NULL, + c_rx_hp, c_tx_hp, p_eth_clk, &p_eth_rxd, p_eth_rxdv, p_eth_txen, &p_eth_txd, @@ -73,7 +163,12 @@ int main() eth_rxclk_2, eth_txclk_2, 4000, 4000, ETHERNET_ENABLE_SHAPER);} - loopback(i_cfg[0], i_rx_lp[0], i_tx_lp[0]); +#if ETHERNET_SUPPORT_HP_QUEUES + test_rx(i_cfg[0], c_rx_hp, i_loopback); + test_loopback(c_tx_hp, i_loopback); +#else + test_rx_loopback(i_cfg[0], i_rx_lp[0], i_tx_lp[0]); +#endif } return 0; diff --git a/tests/test_rmii_dual_basic/test_params.json b/tests/test_rmii_dual_basic/test_params.json index 210be0e3..5afd4534 100644 --- a/tests/test_rmii_dual_basic/test_params.json +++ b/tests/test_rmii_dual_basic/test_params.json @@ -1,5 +1,6 @@ { "PROFILES": [ - {"phy":"rmii", "mac":"rt", "arch":["xs3"], "rx_width":"4b_lower", "tx_width":"4b_lower"} + {"phy":"rmii", "mac":"rt", "arch":["xs3"], "rx_width":"4b_lower", "tx_width":"4b_lower"}, + {"phy":"rmii", "mac":"rt_hp", "arch":["xs3"], "rx_width":"4b_lower", "tx_width":"4b_lower"} ] } From 8bf59f993c6a1088609e6191fd58cdc87f31bbe5 Mon Sep 17 00:00:00 2001 From: Shuchita Khare Date: Wed, 15 Jan 2025 10:38:26 +0000 Subject: [PATCH 13/25] Fix tx timestamp andlink status update code to work with multiple mac ports --- lib_ethernet/api/ethernet.h | 9 ++- lib_ethernet/src/client_state.h | 6 +- lib_ethernet/src/client_state.xc | 4 +- lib_ethernet/src/mii_ethernet_mac.xc | 2 +- lib_ethernet/src/mii_ethernet_rt_mac.xc | 98 +++++++++++++++--------- lib_ethernet/src/rgmii_buffering.xc | 24 +++--- lib_ethernet/src/rmii_ethernet_rt_mac.xc | 38 +++++---- 7 files changed, 110 insertions(+), 71 deletions(-) diff --git a/lib_ethernet/api/ethernet.h b/lib_ethernet/api/ethernet.h index 276436b1..07dbf4bf 100644 --- a/lib_ethernet/api/ethernet.h +++ b/lib_ethernet/api/ethernet.h @@ -269,7 +269,7 @@ typedef interface ethernet_tx_if { void _complete_send_packet(char packet[n], unsigned n, int request_timestamp, size_t ifnum); /** Internal API call. Do not use. */ - unsigned _get_outgoing_timestamp(); + unsigned _get_outgoing_timestamp(size_t ifnum); #ifdef __XC__ } ethernet_tx_if; @@ -311,7 +311,12 @@ extends client interface ethernet_tx_if : { unsigned ifnum) { i._init_send_packet(n, ifnum); i._complete_send_packet(packet, n, 1, ifnum); - return i._get_outgoing_timestamp(); + unsigned timestamp = 0; + while(!timestamp) + { + timestamp = i._get_outgoing_timestamp(ifnum); + } + return timestamp; } /**@}*/ // END: addtogroup ethernet_tx_if #ifdef __XC__ diff --git a/lib_ethernet/src/client_state.h b/lib_ethernet/src/client_state.h index 25ab44b2..c2dcebe9 100644 --- a/lib_ethernet/src/client_state.h +++ b/lib_ethernet/src/client_state.h @@ -27,7 +27,7 @@ typedef struct unsigned rd_index[NUM_ETHERNET_PORTS]; unsigned wr_index[NUM_ETHERNET_PORTS]; void *fifo[NUM_ETHERNET_PORTS][ETHERNET_RX_CLIENT_QUEUE_SIZE]; - int status_update_state; + int status_update_state[NUM_ETHERNET_PORTS]; size_t num_etype_filters; int strip_vlan_tags; uint16_t etype_filters[ETHERNET_MAX_ETHERTYPE_FILTERS]; @@ -38,8 +38,8 @@ typedef struct { int requested_send_buffer_size; mii_packet_t *send_buffer[NUM_ETHERNET_PORTS]; - int has_outgoing_timestamp_info; - unsigned outgoing_timestamp; + int has_outgoing_timestamp_info[NUM_ETHERNET_PORTS]; + unsigned outgoing_timestamp[NUM_ETHERNET_PORTS]; int dst_port; } tx_client_state_t; diff --git a/lib_ethernet/src/client_state.xc b/lib_ethernet/src/client_state.xc index 71e9bcdf..70e5f3ce 100644 --- a/lib_ethernet/src/client_state.xc +++ b/lib_ethernet/src/client_state.xc @@ -10,8 +10,8 @@ void init_rx_client_state(rx_client_state_t client_state[n], unsigned n) { client_state[i].rd_index[p] = 0; client_state[i].wr_index[p] = 0; + client_state[i].status_update_state[p] = STATUS_UPDATE_WAITING; } - client_state[i].status_update_state = STATUS_UPDATE_WAITING; client_state[i].num_etype_filters = 0; client_state[i].strip_vlan_tags = 0; } @@ -24,7 +24,7 @@ void init_tx_client_state(tx_client_state_t client_state[n], unsigned n) for(int p=0; p unsigned timestamp: + case i_tx[int i]._get_outgoing_timestamp(unsigned dst_port) -> unsigned timestamp: fail("Outgoing timestamps are not supported in standard MII Ethernet MAC"); break; diff --git a/lib_ethernet/src/mii_ethernet_rt_mac.xc b/lib_ethernet/src/mii_ethernet_rt_mac.xc index d2b5fbf0..5962d6a1 100644 --- a/lib_ethernet/src/mii_ethernet_rt_mac.xc +++ b/lib_ethernet/src/mii_ethernet_rt_mac.xc @@ -199,11 +199,12 @@ unsafe static void handle_incoming_hp_packets(mii_mempool_t rxmem, static inline void update_client_state(rx_client_state_t client_state[n], server ethernet_rx_if i_rx[n], - unsigned n) + unsigned n, + unsigned ifnum) { for (unsigned i = 0; i < n; i += 1) { - if (client_state[i].status_update_state == STATUS_UPDATE_WAITING) { - client_state[i].status_update_state = STATUS_UPDATE_PENDING; + if (client_state[i].status_update_state[ifnum] == STATUS_UPDATE_WAITING) { + client_state[i].status_update_state[ifnum] = STATUS_UPDATE_PENDING; i_rx[i].packet_ready(); } } @@ -211,15 +212,16 @@ static inline void update_client_state(rx_client_state_t client_state[n], unsafe static inline void handle_ts_queue(mii_ts_queue_t ts_queue, tx_client_state_t client_state[n], - unsigned n) + unsigned n, + unsigned current_port) { unsigned index = 0; unsigned timestamp = 0; int found = mii_ts_queue_get_entry(ts_queue, &index, ×tamp); if (found) { size_t client_id = index - 1; - client_state[client_id].has_outgoing_timestamp_info = 1; - client_state[client_id].outgoing_timestamp = timestamp; + client_state[client_id].has_outgoing_timestamp_info[current_port] = 1; + client_state[client_id].outgoing_timestamp[current_port] = timestamp; } } @@ -279,20 +281,26 @@ unsafe void mii_ethernet_server(mii_mempool_t * unsafe rx_mem, case i_rx_lp[int i].get_packet(ethernet_packet_info_t &desc, char data[n], unsigned n): { prioritize_rx += 1; - + unsigned update_client_state = 0; rx_client_state_t &client_state = rx_client_state_lp[i]; - - if (client_state.status_update_state == STATUS_UPDATE_PENDING) { - data[0] = p_port_state->link_state; - data[1] = p_port_state->link_speed; - desc.type = ETH_IF_STATUS; - desc.src_ifnum = 0; - desc.timestamp = 0; - desc.len = 2; - desc.filter_data = 0; - client_state.status_update_state = STATUS_UPDATE_WAITING; + for(int p=0; plink_state != status) { - p_port_state->link_state = status; - p_port_state->link_speed = speed; - update_client_state(rx_client_state_lp, i_rx_lp, n_rx_lp); + if (p_port_state[ifnum].link_state != status) { + p_port_state[ifnum].link_state = status; + p_port_state[ifnum].link_speed = speed; + update_client_state(rx_client_state_lp, i_rx_lp, n_rx_lp, ifnum); } break; @@ -429,7 +437,7 @@ unsafe void mii_ethernet_server(mii_mempool_t * unsafe rx_mem, } case i_cfg[int i].set_egress_qav_idle_slope(size_t ifnum, unsigned slope): { - p_port_state->qav_idle_slope = slope; + p_port_state[ifnum].qav_idle_slope = slope; break; } @@ -437,7 +445,7 @@ unsafe void mii_ethernet_server(mii_mempool_t * unsafe rx_mem, if (speed < 0 || speed >= NUM_ETHERNET_SPEEDS) { fail("Invalid Ethernet speed, must be a valid ethernet_speed_t enum value"); } - p_port_state->ingress_ts_latency[speed] = value / 10; + p_port_state[ifnum].ingress_ts_latency[speed] = value / 10; break; } @@ -445,7 +453,7 @@ unsafe void mii_ethernet_server(mii_mempool_t * unsafe rx_mem, if (speed < 0 || speed >= NUM_ETHERNET_SPEEDS) { fail("Invalid Ethernet speed, must be a valid ethernet_speed_t enum value"); } - p_port_state->egress_ts_latency[speed] = value / 10; + p_port_state[ifnum].egress_ts_latency[speed] = value / 10; break; } @@ -461,12 +469,18 @@ unsafe void mii_ethernet_server(mii_mempool_t * unsafe rx_mem, case i_cfg[int i].enable_link_status_notification(size_t client_num): rx_client_state_t &client_state = rx_client_state_lp[client_num]; - client_state.status_update_state = STATUS_UPDATE_WAITING; + for(int i=0; i - i_tx_lp[i]._get_outgoing_timestamp() -> unsigned timestamp: - timestamp = tx_client_state_lp[i].outgoing_timestamp + p_port_state->egress_ts_latency[p_port_state->link_speed]; - tx_client_state_lp[i].has_outgoing_timestamp_info = 0; + i_tx_lp[i]._get_outgoing_timestamp(unsigned dst_port) -> unsigned timestamp: + if(tx_client_state_lp[i].has_outgoing_timestamp_info[dst_port]) + { + timestamp = tx_client_state_lp[i].outgoing_timestamp[dst_port] + p_port_state[dst_port].egress_ts_latency[p_port_state[dst_port].link_speed]; + tx_client_state_lp[i].has_outgoing_timestamp_info[dst_port] = 0; + } + else + { + timestamp = 0; + } break; case (!isnull(c_tx_hp) && !prioritize_rx) => c_tx_hp :> unsigned len: @@ -572,7 +592,7 @@ unsafe void mii_ethernet_server(mii_mempool_t * unsafe rx_mem, if (!isnull(c_rx_hp)) { for(int i=0; ilink_speed; desc.type = ETH_IF_STATUS; @@ -438,7 +438,7 @@ unsafe void rgmii_ethernet_rx_server(rx_client_state_t client_state_lp[n_rx_lp], desc.timestamp = 0; desc.len = 2; desc.filter_data = 0; - client_state.status_update_state = STATUS_UPDATE_WAITING; + client_state.status_update_state[0] = STATUS_UPDATE_WAITING; } else if (client_state.rd_index[0] != client_state.wr_index[0]) { // send received packet @@ -490,8 +490,8 @@ unsafe void rgmii_ethernet_rx_server(rx_client_state_t client_state_lp[n_rx_lp], if (cur_link_state != p_port_state->link_state) { cur_link_state = p_port_state->link_state; for (unsigned i = 0; i < n_rx_lp; i += 1) { - if (client_state_lp[i].status_update_state == STATUS_UPDATE_WAITING) { - client_state_lp[i].status_update_state = STATUS_UPDATE_PENDING; + if (client_state_lp[i].status_update_state[0] == STATUS_UPDATE_WAITING) { + client_state_lp[i].status_update_state[0] = STATUS_UPDATE_PENDING; i_rx_lp[i].packet_ready(); } } @@ -572,10 +572,10 @@ unsafe void rgmii_ethernet_tx_server(tx_client_state_t client_state_lp[n_tx_lp], [[independent_guard]] case (unsigned i = 0; i < n_tx_lp; i++) - (client_state_lp[i].has_outgoing_timestamp_info) => - i_tx_lp[i]._get_outgoing_timestamp() -> unsigned timestamp: - timestamp = client_state_lp[i].outgoing_timestamp + p_port_state->egress_ts_latency[p_port_state->link_speed]; - client_state_lp[i].has_outgoing_timestamp_info = 0; + (client_state_lp[i].has_outgoing_timestamp_info[0]) => + i_tx_lp[i]._get_outgoing_timestamp(unsigned dst_port) -> unsigned timestamp: + timestamp = client_state_lp[i].outgoing_timestamp[0] + p_port_state->egress_ts_latency[p_port_state->link_speed]; + client_state_lp[i].has_outgoing_timestamp_info[0] = 0; break; [[independent_guard]] @@ -632,8 +632,8 @@ unsafe void rgmii_ethernet_tx_server(tx_client_state_t client_state_lp[n_tx_lp], // Low priority packet sent if (buf->timestamp_id) { size_t client_id = buf->timestamp_id - 1; - client_state_lp[client_id].has_outgoing_timestamp_info = 1; - client_state_lp[client_id].outgoing_timestamp = buf->timestamp + p_port_state->egress_ts_latency[p_port_state->link_speed]; + client_state_lp[client_id].has_outgoing_timestamp_info[0] = 1; + client_state_lp[client_id].outgoing_timestamp[0] = buf->timestamp + p_port_state->egress_ts_latency[p_port_state->link_speed]; } buffers_free_add(free_buffers_lp, buf, 0); } @@ -847,14 +847,14 @@ void rgmii_ethernet_mac_config(server ethernet_cfg_if i_cfg[n], case i_cfg[int i].enable_link_status_notification(size_t client_num): unsafe { rx_client_state_t &client_state = client_state_lp[client_num]; - client_state.status_update_state = STATUS_UPDATE_WAITING; + client_state.status_update_state[0] = STATUS_UPDATE_WAITING; break; } case i_cfg[int i].disable_link_status_notification(size_t client_num): unsafe { rx_client_state_t &client_state = client_state_lp[client_num]; - client_state.status_update_state = STATUS_UPDATE_IGNORING; + client_state.status_update_state[0] = STATUS_UPDATE_IGNORING; break; } diff --git a/lib_ethernet/src/rmii_ethernet_rt_mac.xc b/lib_ethernet/src/rmii_ethernet_rt_mac.xc index 0f0cdf36..287e343c 100644 --- a/lib_ethernet/src/rmii_ethernet_rt_mac.xc +++ b/lib_ethernet/src/rmii_ethernet_rt_mac.xc @@ -166,7 +166,8 @@ void rmii_ethernet_rt_mac(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), stati fail("Using high priority channels without #define ETHERNET_SUPPORT_HP_QUEUES set true"); } - mii_ts_queue_t ts_queue = mii_ts_queue_init(&ts_queue_info, ts_fifo, n_tx_lp + 1); + mii_ts_queue_init(&ts_queue_info, ts_fifo, n_tx_lp + 1); + mii_ts_queue_info_t * unsafe ts_queue_info_ptr = &ts_queue_info; // Common initialisation @@ -222,7 +223,7 @@ void rmii_ethernet_rt_mac(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), stati rx_mem_ptr, rx_packets_lp_ptr, rx_packets_hp_ptr, - ts_queue, + &ts_queue_info, tx_port_width, tx_data_0, tx_data_1, @@ -244,7 +245,7 @@ void rmii_ethernet_rt_mac(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), stati tx_mem_hp_ptr, tx_packets_lp_ptr, tx_packets_hp_ptr, - ts_queue, + ts_queue_info_ptr, i_cfg, n_cfg, i_rx_lp, n_rx_lp, i_tx_lp, n_tx_lp, @@ -326,8 +327,8 @@ void rmii_ethernet_rt_mac_dual(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), mii_init_lock(); - mii_ts_queue_entry_t ts_fifo[MII_TIMESTAMP_QUEUE_MAX_SIZE + 1]; - mii_ts_queue_info_t ts_queue_info; + mii_ts_queue_entry_t ts_fifo[NUM_ETHERNET_PORTS][MII_TIMESTAMP_QUEUE_MAX_SIZE + 1]; + mii_ts_queue_info_t ts_queue_info[NUM_ETHERNET_PORTS]; if (n_tx_lp > MII_TIMESTAMP_QUEUE_MAX_SIZE) { fail("Exceeded maximum number of transmit clients. Increase MII_TIMESTAMP_QUEUE_MAX_SIZE in ethernet_conf.h"); @@ -337,7 +338,12 @@ void rmii_ethernet_rt_mac_dual(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), fail("Using high priority channels without #define ETHERNET_SUPPORT_HP_QUEUES set true"); } - mii_ts_queue_t ts_queue = mii_ts_queue_init(&ts_queue_info, ts_fifo, n_tx_lp + 1); + for(int i=0; i Date: Wed, 15 Jan 2025 11:55:28 +0000 Subject: [PATCH 14/25] Set NUM_ETHERNET_PORTS to 1 by default. --- lib_ethernet/api/ethernet.h | 2 -- lib_ethernet/src/default_ethernet_conf.h | 6 +++++- lib_ethernet/src/rmii_ethernet_rt_mac.xc | 3 ++- tests/test_rmii_dual_basic/CMakeLists.txt | 3 ++- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/lib_ethernet/api/ethernet.h b/lib_ethernet/api/ethernet.h index e6235fef..739dc1a8 100644 --- a/lib_ethernet/api/ethernet.h +++ b/lib_ethernet/api/ethernet.h @@ -59,8 +59,6 @@ typedef enum ethernet_macaddr_filter_result_t { ETHERNET_MACADDR_FILTER_TABLE_FULL /**< The filter entry was not added because the filter table is full */ } ethernet_macaddr_filter_result_t; -#define NUM_ETHERNET_PORTS (2) - #if (defined(__XC__) || defined(__DOXYGEN__)) /** Ethernet MAC configuration interface. diff --git a/lib_ethernet/src/default_ethernet_conf.h b/lib_ethernet/src/default_ethernet_conf.h index ca3abed1..cdae618b 100644 --- a/lib_ethernet/src/default_ethernet_conf.h +++ b/lib_ethernet/src/default_ethernet_conf.h @@ -75,4 +75,8 @@ #define __SIMULATOR__ 0 #endif -#endif // __default_ethernet_conf_h__ \ No newline at end of file +#ifndef NUM_ETHERNET_PORTS +#define NUM_ETHERNET_PORTS (1) +#endif + +#endif // __default_ethernet_conf_h__ diff --git a/lib_ethernet/src/rmii_ethernet_rt_mac.xc b/lib_ethernet/src/rmii_ethernet_rt_mac.xc index 2c26db51..bcdac12a 100644 --- a/lib_ethernet/src/rmii_ethernet_rt_mac.xc +++ b/lib_ethernet/src/rmii_ethernet_rt_mac.xc @@ -314,7 +314,7 @@ void rmii_ethernet_rt_mac(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), stati } // unsafe block } - +#if (NUM_ETHERNET_PORTS == 2) void rmii_ethernet_rt_mac_dual(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), static_const_unsigned_t n_cfg, SERVER_INTERFACE(ethernet_rx_if, i_rx_lp[n_rx_lp]), static_const_unsigned_t n_rx_lp, SERVER_INTERFACE(ethernet_tx_if, i_tx_lp[n_tx_lp]), static_const_unsigned_t n_tx_lp, @@ -564,4 +564,5 @@ void rmii_ethernet_rt_mac_dual(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), } // par } // unsafe block } +#endif diff --git a/tests/test_rmii_dual_basic/CMakeLists.txt b/tests/test_rmii_dual_basic/CMakeLists.txt index 792f278e..95eb915d 100644 --- a/tests/test_rmii_dual_basic/CMakeLists.txt +++ b/tests/test_rmii_dual_basic/CMakeLists.txt @@ -14,7 +14,8 @@ set(APP_INCLUDES ../include src) set(COMPILER_FLAGS_COMMON -g -report -DDEBUG_PRINT_ENABLE=1 - -Os) + -Os + -DNUM_ETHERNET_PORTS=2) set(XMOS_SANDBOX_DIR ${CMAKE_CURRENT_LIST_DIR}/../../..) From d4339dd42c5a0375e91dd78ca8d7c5ff74b7a358 Mon Sep 17 00:00:00 2001 From: Shuchita Khare Date: Fri, 17 Jan 2025 11:37:04 +0000 Subject: [PATCH 15/25] Changes to ensure the existing single port rmii tests are not broken --- lib_ethernet/src/mii_ethernet_rt_mac.xc | 11 +- lib_ethernet/src/mii_filter.xc | 4 + lib_ethernet/src/rmii_master.xc | 2 - tests/CMakeLists.txt | 1 + tests/include/ports.h | 7 +- tests/test_avb_traffic.py | 2 +- tests/test_avb_traffic/src/main.xc | 2 +- tests/test_rmii_dual_basic.py | 127 ++++++++++++------------ tests/test_rx_queues.py | 4 +- tests/test_rx_queues/src/main.xc | 2 +- 10 files changed, 86 insertions(+), 76 deletions(-) diff --git a/lib_ethernet/src/mii_ethernet_rt_mac.xc b/lib_ethernet/src/mii_ethernet_rt_mac.xc index ee8604f7..ac35fa81 100644 --- a/lib_ethernet/src/mii_ethernet_rt_mac.xc +++ b/lib_ethernet/src/mii_ethernet_rt_mac.xc @@ -511,6 +511,10 @@ unsafe void mii_ethernet_server(mii_mempool_t * unsafe rx_mem, [[independent_guard]] case (unsigned i = 0; i < n_tx_lp; i++) i_tx_lp[i]._get_outgoing_timestamp(unsigned dst_port) -> unsigned timestamp: + if(dst_port == ETHERNET_ALL_INTERFACES) + { + dst_port = 0; // TODO - FIXME + } if(tx_client_state_lp[i].has_outgoing_timestamp_info[dst_port]) { timestamp = tx_client_state_lp[i].outgoing_timestamp[dst_port] + p_port_state[dst_port].egress_ts_latency[p_port_state[dst_port].link_speed]; @@ -531,7 +535,7 @@ unsafe void mii_ethernet_server(mii_mempool_t * unsafe rx_mem, if((dst_port == ETHERNET_ALL_INTERFACES || dst_port == p) && (buf != null)) { unsigned * unsafe dptr = &buf->data[0]; - unsigned * unsafe wrap_ptr = mii_get_wrap_ptr(tx_mem_hp[dst_port]); + unsigned * unsafe wrap_ptr = mii_get_wrap_ptr(tx_mem_hp[p]); unsigned prewrap = ((char *) wrap_ptr - (char *) dptr); unsigned len1 = prewrap > len ? len : prewrap; unsigned len2 = prewrap > len ? 0 : len - prewrap; @@ -550,8 +554,9 @@ unsafe void mii_ethernet_server(mii_mempool_t * unsafe rx_mem, dptr = dptr + (len+3)/4; } buf->length = len; - mii_commit(tx_mem_hp[dst_port], dptr); - mii_add_packet((mii_packet_queue_t)&tx_packets_hp[dst_port], buf); + mii_commit(tx_mem_hp[p], dptr); + mii_add_packet((mii_packet_queue_t)&tx_packets_hp[p], buf); + buf->tcount = 0; } tx_client_state_hp[0].send_buffer[0] = null; diff --git a/lib_ethernet/src/mii_filter.xc b/lib_ethernet/src/mii_filter.xc index dc501bf0..93cade3d 100644 --- a/lib_ethernet/src/mii_filter.xc +++ b/lib_ethernet/src/mii_filter.xc @@ -84,12 +84,16 @@ unsafe void mii_ethernet_filter(chanend c_conf, current_port = 0; if (buf == null) { +#if (NUM_ETHERNET_PORTS == 2) buf = mii_get_next_buf((mii_packet_queue_t)&incoming_packets[1]); if(buf == null) { continue; } current_port = 1; +#else + continue; +#endif } diff --git a/lib_ethernet/src/rmii_master.xc b/lib_ethernet/src/rmii_master.xc index 39a5802f..b04b833d 100644 --- a/lib_ethernet/src/rmii_master.xc +++ b/lib_ethernet/src/rmii_master.xc @@ -1118,8 +1118,6 @@ unsafe void rmii_master_tx_pins(mii_mempool_t tx_mem_lp, } } - - const int packet_is_high_priority = (p_ts_queue == null); if (enable_shaper && packet_is_high_priority) { const int preamble_bytes = 8; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c6844c1c..67e0df98 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -20,4 +20,5 @@ add_subdirectory(test_rx_queues) add_subdirectory(test_check_ifg_wait) add_subdirectory(test_rmii_timing) add_subdirectory(test_rmii_restart) +add_subdirectory(test_rmii_dual_basic) diff --git a/tests/include/ports.h b/tests/include/ports.h index 02a5a244..6f83921f 100644 --- a/tests/include/ports.h +++ b/tests/include/ports.h @@ -24,7 +24,10 @@ clock eth_txclk = on tile[0]: XS1_CLKBLK_2; #endif // RGMII -port p_smi_mdio = on tile[0]: XS1_PORT_1M; -port p_smi_mdc = on tile[0]: XS1_PORT_1N; +/* Commenting these out since they conflict with test ports (XS1_PORT_1N is the same as p_rx_lp_control[1] used in test_rx_queues and test_avb) + defined in other tests and the smi ports are not used in any tests +*/ +//port p_smi_mdio = on tile[0]: XS1_PORT_1M; +//port p_smi_mdc = on tile[0]: XS1_PORT_1N; #endif // __ports_h__ diff --git a/tests/test_avb_traffic.py b/tests/test_avb_traffic.py index 66f87f33..b4d11b3e 100644 --- a/tests/test_avb_traffic.py +++ b/tests/test_avb_traffic.py @@ -178,7 +178,7 @@ def do_test(capfd, mac, arch, tx_clk, tx_phy, seed, rand.seed(seed) bit_time = tx_phy.get_clock().get_bit_time() - rxLpControl = RxLpControl('tile[0]:XS1_PORT_1E', bit_time, 0, True, rand.randint(0, int(sys.maxsize))) + rxLpControl = RxLpControl('tile[0]:XS1_PORT_1G', bit_time, 0, True, rand.randint(0, int(sys.maxsize))) testname = 'test_avb_traffic' expect_folder = create_if_needed("expect_temp") diff --git a/tests/test_avb_traffic/src/main.xc b/tests/test_avb_traffic/src/main.xc index 855c85af..2327f3f5 100644 --- a/tests/test_avb_traffic/src/main.xc +++ b/tests/test_avb_traffic/src/main.xc @@ -17,7 +17,7 @@ port p_test_ctrl = on tile[0]: XS1_PORT_1C; #include "control.xc" -port p_rx_lp_control = on tile[0]: XS1_PORT_1E; +port p_rx_lp_control = on tile[0]: XS1_PORT_1G; #include "helpers.xc" diff --git a/tests/test_rmii_dual_basic.py b/tests/test_rmii_dual_basic.py index a92187d8..40d8fc38 100644 --- a/tests/test_rmii_dual_basic.py +++ b/tests/test_rmii_dual_basic.py @@ -74,70 +74,69 @@ def do_rx_test_dual(capfd, mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, t def rmii_dual_test(capfd, params, seed): verbose = False - with capfd.disabled(): - clk = get_rmii_clk(Clock.CLK_50MHz) - tx_rmii_phy = get_rmii_tx_phy(params['rx_width'], - clk, - verbose=verbose - ) - - tx_rmii_phy_2 = get_rmii_tx_phy(params['rx_width'], - clk, - verbose=verbose, - second_phy=True - ) - - rx_rmii_phy = get_rmii_rx_phy(params['tx_width'], - clk, - packet_fn=check_received_packet, - verbose=verbose - ) - - rx_rmii_phy_2 = get_rmii_rx_phy(params['tx_width'], - clk, - packet_fn=check_received_packet, - verbose=verbose, - second_phy=True - ) - - mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, rx_width, tx_width = params["mac"], params["arch"], None, [rx_rmii_phy, rx_rmii_phy_2], clk, [tx_rmii_phy, tx_rmii_phy_2], params['rx_width'],params['tx_width'] - - rand = random.Random() - rand.seed(seed) - - dut_mac_address = get_dut_mac_address() - not_dut_mac_address = [] - for i in range(6): - not_dut_mac_address.append(dut_mac_address[i]+1) - - packets = [] - loopback_packets = [] - forwarded_packets = [] - - # Send frames which excercise all of the tail length vals (0, 1, 2, 3 bytes) - packet_start_len = 100 - # Packets that get looped back on the same port - for i in range(5): - loopback_packets.append(MiiPacket(rand, - dst_mac_addr=dut_mac_address, - create_data_args=['step', (i, packet_start_len + i)], - inter_frame_gap=packet_processing_time(tx_phy[0], packet_start_len, mac), - )) - # packets that get forwarded to the other port - for i in range(5): - forwarded_packets.append(MiiPacket(rand, - dst_mac_addr=not_dut_mac_address, - create_data_args=['step', (i, packet_start_len + i)], - inter_frame_gap=packet_processing_time(tx_phy[0], packet_start_len, mac), - )) - - # interleave loopback and forwarded packets - for i in range(5): - packets.append(loopback_packets[i]) - packets.append(forwarded_packets[i]) - - - do_rx_test_dual(capfd, mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, __file__, seed, loopback_packets, forwarded_packets, rx_width=rx_width, tx_width=tx_width) + clk = get_rmii_clk(Clock.CLK_50MHz) + tx_rmii_phy = get_rmii_tx_phy(params['rx_width'], + clk, + verbose=verbose + ) + + tx_rmii_phy_2 = get_rmii_tx_phy(params['rx_width'], + clk, + verbose=verbose, + second_phy=True + ) + + rx_rmii_phy = get_rmii_rx_phy(params['tx_width'], + clk, + packet_fn=check_received_packet, + verbose=verbose + ) + + rx_rmii_phy_2 = get_rmii_rx_phy(params['tx_width'], + clk, + packet_fn=check_received_packet, + verbose=verbose, + second_phy=True + ) + + mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, rx_width, tx_width = params["mac"], params["arch"], None, [rx_rmii_phy, rx_rmii_phy_2], clk, [tx_rmii_phy, tx_rmii_phy_2], params['rx_width'],params['tx_width'] + + rand = random.Random() + rand.seed(seed) + + dut_mac_address = get_dut_mac_address() + not_dut_mac_address = [] + for i in range(6): + not_dut_mac_address.append(dut_mac_address[i]+1) + + packets = [] + loopback_packets = [] + forwarded_packets = [] + + # Send frames which excercise all of the tail length vals (0, 1, 2, 3 bytes) + packet_start_len = 100 + # Packets that get looped back on the same port + for i in range(5): + loopback_packets.append(MiiPacket(rand, + dst_mac_addr=dut_mac_address, + create_data_args=['step', (i, packet_start_len + i)], + inter_frame_gap=packet_processing_time(tx_phy[0], packet_start_len, mac), + )) + # packets that get forwarded to the other port + for i in range(5): + forwarded_packets.append(MiiPacket(rand, + dst_mac_addr=not_dut_mac_address, + create_data_args=['step', (i, packet_start_len + i)], + inter_frame_gap=packet_processing_time(tx_phy[0], packet_start_len, mac), + )) + + # interleave loopback and forwarded packets + for i in range(5): + packets.append(loopback_packets[i]) + packets.append(forwarded_packets[i]) + + + do_rx_test_dual(capfd, mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, __file__, seed, loopback_packets, forwarded_packets, rx_width=rx_width, tx_width=tx_width) diff --git a/tests/test_rx_queues.py b/tests/test_rx_queues.py index c8ac9d4a..fb0b8a86 100644 --- a/tests/test_rx_queues.py +++ b/tests/test_rx_queues.py @@ -122,8 +122,8 @@ def do_test(capfd, mac, arch, tx_clk, tx_phy, seed, test_id, rand.seed(seed) bit_time = tx_phy.get_clock().get_bit_time() - rxLpControl1 = RxLpControl('tile[0]:XS1_PORT_1E', bit_time, 0, True, rand.randint(0, sys.maxsize)) - rxLpControl2 = RxLpControl('tile[0]:XS1_PORT_1F', bit_time, 0, True, rand.randint(0, sys.maxsize)) + rxLpControl1 = RxLpControl('tile[0]:XS1_PORT_1G', bit_time, 0, True, rand.randint(0, sys.maxsize)) + rxLpControl2 = RxLpControl('tile[0]:XS1_PORT_1N', bit_time, 0, True, rand.randint(0, sys.maxsize)) testname = 'test_rx_queues' expect_folder = create_if_needed("expect_temp") diff --git a/tests/test_rx_queues/src/main.xc b/tests/test_rx_queues/src/main.xc index f274af31..51ed2e1f 100644 --- a/tests/test_rx_queues/src/main.xc +++ b/tests/test_rx_queues/src/main.xc @@ -22,7 +22,7 @@ port p_test_ctrl = on tile[0]: XS1_PORT_1C; #define NUM_TX_LP_IF 1 #define NUM_LP_CLIENTS 2 -port p_rx_lp_control[NUM_LP_CLIENTS] = on tile[0]: { XS1_PORT_1E, XS1_PORT_1F }; +port p_rx_lp_control[NUM_LP_CLIENTS] = on tile[0]: { XS1_PORT_1G, XS1_PORT_1N }; #include "helpers.xc" From fb5087643b569ad48ab678ab76bf3f978a527890 Mon Sep 17 00:00:00 2001 From: Shuchita Khare Date: Fri, 17 Jan 2025 13:03:13 +0000 Subject: [PATCH 16/25] Fix test failures --- lib_ethernet/api/ethernet.h | 21 +++- lib_ethernet/src/mii_ethernet_mac.xc | 3 +- lib_ethernet/src/mii_ethernet_rt_mac.xc | 144 ++++++++++++++---------- lib_ethernet/src/rgmii_buffering.xc | 4 +- tests/test_link_status/src/main.xc | 2 + 5 files changed, 110 insertions(+), 64 deletions(-) diff --git a/lib_ethernet/api/ethernet.h b/lib_ethernet/api/ethernet.h index 739dc1a8..4d62c9f2 100644 --- a/lib_ethernet/api/ethernet.h +++ b/lib_ethernet/api/ethernet.h @@ -276,7 +276,7 @@ typedef interface ethernet_tx_if { /** Internal API call. Do not use. */ void _init_send_packet(size_t n, size_t ifnum); /** Internal API call. Do not use. */ - void _complete_send_packet(char packet[n], unsigned n, + unsigned _complete_send_packet(char packet[n], unsigned n, int request_timestamp, size_t ifnum); /** Internal API call. Do not use. */ unsigned _get_outgoing_timestamp(size_t ifnum); @@ -299,7 +299,10 @@ extends client interface ethernet_tx_if : { inline void send_packet(CLIENT_INTERFACE(ethernet_tx_if, i), char packet[n], unsigned n, unsigned ifnum) { i._init_send_packet(n, ifnum); - i._complete_send_packet(packet, n, 0, ifnum); + unsigned ready; + do { + ready = i._complete_send_packet(packet, n, 1, ifnum); + }while(!ready); } /** Function to send an Ethernet packet on the specified interface and return a timestamp @@ -320,7 +323,10 @@ extends client interface ethernet_tx_if : { unsigned n, unsigned ifnum) { i._init_send_packet(n, ifnum); - i._complete_send_packet(packet, n, 1, ifnum); + unsigned ready; + do { + ready = i._complete_send_packet(packet, n, 1, ifnum); + }while(!ready); unsigned timestamp = 0; while(!timestamp) { @@ -424,8 +430,17 @@ inline void ethernet_send_hp_packet(streaming_chanend_t c_tx_hp, unsigned n, unsigned ifnum) { + unsigned ready = 0; + c_tx_hp <: n; c_tx_hp <: ifnum; + c_tx_hp :> ready; + while(!ready) + { + c_tx_hp <: n; + c_tx_hp <: ifnum; + c_tx_hp :> ready; + } sout_char_array(c_tx_hp, packet, n); } diff --git a/lib_ethernet/src/mii_ethernet_mac.xc b/lib_ethernet/src/mii_ethernet_mac.xc index 4e52133f..a1dc8bb7 100644 --- a/lib_ethernet/src/mii_ethernet_mac.xc +++ b/lib_ethernet/src/mii_ethernet_mac.xc @@ -268,7 +268,8 @@ static void mii_ethernet_aux(client mii_if i_mii, case i_tx[int i]._complete_send_packet(char data[n], unsigned n, int request_timestamp, - unsigned dst_port): + unsigned dst_port) -> unsigned ready: + ready = 1; memcpy(txbuf, data, n); i_mii.send_packet(txbuf, n); // wait for the packet to be sent diff --git a/lib_ethernet/src/mii_ethernet_rt_mac.xc b/lib_ethernet/src/mii_ethernet_rt_mac.xc index ac35fa81..c3057848 100644 --- a/lib_ethernet/src/mii_ethernet_rt_mac.xc +++ b/lib_ethernet/src/mii_ethernet_rt_mac.xc @@ -304,7 +304,11 @@ unsafe void mii_ethernet_server(mii_mempool_t * unsafe rx_mem, } } - if (!update_client_state && (client_state.rd_index[current_port_lp] != client_state.wr_index[current_port_lp])) + if(update_client_state) + { + break; + } + else if (client_state.rd_index[current_port_lp] != client_state.wr_index[current_port_lp]) { unsigned client_rd_index = client_state.rd_index[current_port_lp]; unsigned packets_rd_index = (unsigned)client_state.fifo[current_port_lp][client_rd_index]; @@ -526,42 +530,51 @@ unsafe void mii_ethernet_server(mii_mempool_t * unsafe rx_mem, } break; + case (!isnull(c_tx_hp) && !prioritize_rx) => c_tx_hp :> unsigned len: unsigned dst_port; c_tx_hp :> dst_port; - for(int p=0; pdata[0]; - unsigned * unsafe wrap_ptr = mii_get_wrap_ptr(tx_mem_hp[p]); - unsigned prewrap = ((char *) wrap_ptr - (char *) dptr); - unsigned len1 = prewrap > len ? len : prewrap; - unsigned len2 = prewrap > len ? 0 : len - prewrap; - unsigned * unsafe start_ptr = (unsigned *) *wrap_ptr; - - // sout_char_array sends bytes in reverse order so the second - // half must be received first - if (len2) { - sin_char_array(c_tx_hp, (char*)start_ptr, len2); - } - sin_char_array(c_tx_hp, (char*)dptr, len1); - if (len2) { - dptr = start_ptr + (len2+3)/4; - } - else { - dptr = dptr + (len+3)/4; - } - buf->length = len; - mii_commit(tx_mem_hp[p], dptr); - mii_add_packet((mii_packet_queue_t)&tx_packets_hp[p], buf); + dst_port = 0; // TODO FIXME Sending on multiple ports with one send_packet() call when NUM_ETHERNET_PORTS > 1 is not supported yet. + } + + mii_packet_t * unsafe buf = tx_client_state_hp[0].send_buffer[dst_port]; + if(!buf) // check if there's a send_buffer available for this port + { + c_tx_hp <: 0; // not ready + } + else + { + c_tx_hp <: 1; //ready. Expect data next - buf->tcount = 0; + unsigned * unsafe dptr = &buf->data[0]; + unsigned * unsafe wrap_ptr = mii_get_wrap_ptr(tx_mem_hp[dst_port]); + unsigned prewrap = ((char *) wrap_ptr - (char *) dptr); + unsigned len1 = prewrap > len ? len : prewrap; + unsigned len2 = prewrap > len ? 0 : len - prewrap; + unsigned * unsafe start_ptr = (unsigned *) *wrap_ptr; + + // sout_char_array sends bytes in reverse order so the second + // half must be received first + if (len2) { + sin_char_array(c_tx_hp, (char*)start_ptr, len2); + } + sin_char_array(c_tx_hp, (char*)dptr, len1); + if (len2) { + dptr = start_ptr + (len2+3)/4; } - tx_client_state_hp[0].send_buffer[0] = null; + else { + dptr = dptr + (len+3)/4; + } + buf->length = len; + buf->tcount = 0; + mii_commit(tx_mem_hp[dst_port], dptr); + mii_add_packet((mii_packet_queue_t)&tx_packets_hp[dst_port], buf); + tx_client_state_hp[0].send_buffer[dst_port] = null; + prioritize_rx = 3; } - prioritize_rx = 3; + break; [[independent_guard]] @@ -569,42 +582,55 @@ unsafe void mii_ethernet_server(mii_mempool_t * unsafe rx_mem, (!prioritize_rx) => i_tx_lp[i]._complete_send_packet(char data[n], unsigned n, int request_timestamp, - unsigned dst_port): - + unsigned dst_port) -> unsigned ready: + ready = 1; for(int p=0; pdata[0]; - unsigned * unsafe wrap_ptr = mii_get_wrap_ptr(tx_mem_lp[p]); - int prewrap = ((char *) wrap_ptr - (char *) dptr); - int len = n; - int len1 = prewrap > len ? len : prewrap; - int len2 = prewrap > len ? 0 : len - prewrap; - memcpy(dptr, data, len1); - if (len2) { - unsigned * unsafe start_ptr = (unsigned *) *wrap_ptr; - memcpy((unsigned *) start_ptr, &data[len1], len2); - dptr = start_ptr + (len2+3)/4; + if(tx_client_state_lp[i].send_buffer[p] == null) + { + ready = 0; + break; } - else { - dptr = dptr + (len+3)/4; + } + } + if(ready) + { + for(int p=0; pdata[0]; + unsigned * unsafe wrap_ptr = mii_get_wrap_ptr(tx_mem_lp[p]); + int prewrap = ((char *) wrap_ptr - (char *) dptr); + int len = n; + int len1 = prewrap > len ? len : prewrap; + int len2 = prewrap > len ? 0 : len - prewrap; + memcpy(dptr, data, len1); + if (len2) { + unsigned * unsafe start_ptr = (unsigned *) *wrap_ptr; + memcpy((unsigned *) start_ptr, &data[len1], len2); + dptr = start_ptr + (len2+3)/4; + } + else { + dptr = dptr + (len+3)/4; + } + buf->length = n; + if (request_timestamp) + buf->timestamp_id = i+1; + else + buf->timestamp_id = 0; + mii_commit(tx_mem_lp[p], dptr); + mii_add_packet((mii_packet_queue_t)&tx_packets_lp[p], buf); + buf->tcount = 0; } - buf->length = n; - if (request_timestamp) - buf->timestamp_id = i+1; - else - buf->timestamp_id = 0; - mii_commit(tx_mem_lp[p], dptr); - mii_add_packet((mii_packet_queue_t)&tx_packets_lp[p], buf); - buf->tcount = 0; + tx_client_state_lp[i].send_buffer[p] = null; } - tx_client_state_lp[i].send_buffer[p] = null; + tx_client_state_lp[i].requested_send_buffer_size = 0; + prioritize_rx = 3; } - - tx_client_state_lp[i].requested_send_buffer_size = 0; - prioritize_rx = 3; break; default: diff --git a/lib_ethernet/src/rgmii_buffering.xc b/lib_ethernet/src/rgmii_buffering.xc index e1d720d2..9d68dfca 100644 --- a/lib_ethernet/src/rgmii_buffering.xc +++ b/lib_ethernet/src/rgmii_buffering.xc @@ -583,7 +583,7 @@ unsafe void rgmii_ethernet_tx_server(tx_client_state_t client_state_lp[n_tx_lp], (client_state_lp[i].send_buffer[0] != null && !prioritize_ack) => i_tx_lp[i]._complete_send_packet(char data[n], unsigned n, int request_timestamp, - unsigned dst_port): + unsigned dst_port) -> unsigned ready: mii_packet_t * unsafe buf = client_state_lp[i].send_buffer[0]; unsigned * unsafe dptr = &buf->data[0]; @@ -608,6 +608,8 @@ unsafe void rgmii_ethernet_tx_server(tx_client_state_t client_state_lp[n_tx_lp], break; case (tx_buf_hp && !prioritize_ack) => c_tx_hp :> unsigned n_bytes: + c_tx_hp :> unsigned dst_port; + c_tx_hp <: 1; // protocol requires 'ready' to be transmitted sin_char_array(c_tx_hp, (char *)tx_buf_hp->data, n_bytes); tx_buf_hp->length = n_bytes; tx_buf_hp->timestamp_id = 0; diff --git a/tests/test_link_status/src/main.xc b/tests/test_link_status/src/main.xc index 154d1a26..69bb7963 100644 --- a/tests/test_link_status/src/main.xc +++ b/tests/test_link_status/src/main.xc @@ -50,6 +50,8 @@ void test_link_status(client ethernet_cfg_if cfg, size_t index = rx.get_index(); + index = 0; // This is the mac port index and not the client index + cfg.enable_link_status_notification(index); int events_expected = 4; From ab9645bddcee92cb9fe1b9e17a6ca9fdbdbf102c Mon Sep 17 00:00:00 2001 From: Shuchita Khare Date: Tue, 21 Jan 2025 14:51:16 +0000 Subject: [PATCH 17/25] Added rmii dual phy forwarding only test --- requirements.txt | 1 + tests/helpers.py | 107 ++++++++++++++++++++++++--- tests/mii_phy.py | 10 ++- tests/rgmii_phy.py | 4 +- tests/rmii_phy.py | 14 ++-- tests/test_rmii_dual_basic.py | 119 ++++++++----------------------- tests/test_rmii_dual_fwd_only.py | 103 ++++++++++++++++++++++++++ 7 files changed, 249 insertions(+), 109 deletions(-) create mode 100644 tests/test_rmii_dual_fwd_only.py diff --git a/requirements.txt b/requirements.txt index 9ef24564..d39791de 100644 --- a/requirements.txt +++ b/requirements.txt @@ -23,6 +23,7 @@ pytest==8.2.2 pytest-xdist==3.6.1 filelock==3.16.1 bitstring==4.3.0 +numpy==2.2.2 # Development dependencies # diff --git a/tests/helpers.py b/tests/helpers.py index 99af78da..fcd226f6 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -9,6 +9,7 @@ import pytest import json import copy +import numpy as np from mii_clock import Clock from mii_phy import MiiTransmitter, MiiReceiver @@ -184,11 +185,23 @@ def do_rx_test(capfd, mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, test_f def create_expect(packets, filename): """ Create the expect file for what packets should be reported by the DUT """ + ndim = np.array(packets).ndim with open(filename, 'w') as f: - for i,packet in enumerate(packets): - if not packet.dropped: - f.write("Received packet {} ok\n".format(i)) - f.write("Test done\n") + if ndim == 1: + for i,packet in enumerate(packets): + if not packet.dropped: + f.write(f"Received packet {i} ok\n") + f.write("Test done\n") + elif ndim == 2: + for id in range(2): + for i,packet in enumerate(packets[id]): + if not packet.dropped: + f.write(f"Phy {id} Received packet {i} ok\n") + f.write("Test done\n") + else: + assert False, f"Incorrect dimensions of the packets array.\n{packets}" + + def get_sim_args(testname, mac, clk, phy, arch='xs2'): sim_args = [] @@ -260,7 +273,10 @@ def check_received_packet(packet, phy): print("Expected:") sys.stdout.write(expected.dump()) - print(f"Received packet {phy.expect_packet_index} ok") + st = f"Received packet {phy.expect_packet_index} ok" + if phy.get_id() != None: + st = f"Phy {phy.get_id()} " + st + print(st) # Skip this packet phy.expect_packet_index += 1 @@ -274,9 +290,10 @@ def check_received_packet(packet, phy): if phy.expect_packet_index >= phy.num_expected_packets: print("Test done") - wait_time_us = 80 # In case the other port is receiving, wait sometime before terminating - wait_time_ticks = (wait_time_us * px.Xsi.get_xsi_tick_freq_hz())/1e6 - phy.wait_until(phy.xsi.get_time() + wait_time_ticks) + if phy.get_name() == "rmii": + wait_time_us = 200 # In case the other port is receiving, wait sometime before terminating + wait_time_ticks = (wait_time_us * px.Xsi.get_xsi_tick_freq_hz())/1e6 + phy.wait_until(phy.xsi.get_time() + wait_time_ticks) phy.xsi.terminate() def generate_tests(test_params_json): @@ -331,6 +348,20 @@ def get_rmii_tx_phy(rx_width, clk, **kwargs): assert False, f"get_rmii_tx_phy(): Invalid rx_width {rx_width}" return tx_rmii_phy +def get_rmii_tx_phy_dual(rx_widths, clk, **kwargs): + tx_rmii_phy = get_rmii_tx_phy(rx_widths[0], + clk, + **kwargs + ) + + tx_rmii_phy_2 = get_rmii_tx_phy(rx_widths[1], + clk, + **kwargs, + second_phy=True + ) + return tx_rmii_phy, tx_rmii_phy_2 + + def get_rmii_rx_phy(tx_width, clk, **kwargs): if tx_width == "4b_lower": rx_rmii_phy = get_rmii_4b_port_rx_phy(clk, @@ -350,6 +381,20 @@ def get_rmii_rx_phy(tx_width, clk, **kwargs): assert False, f"get_rmii_rx_phy(): Invalid tx_width {tx_width}" return rx_rmii_phy +def get_rmii_rx_phy_dual(tx_widths, clk, **kwargs): + rx_rmii_phy = get_rmii_rx_phy(tx_widths[0], + clk, + **kwargs, + id="0" + ) + + rx_rmii_phy_2 = get_rmii_rx_phy(tx_widths[1], + clk, + **kwargs, + second_phy=True, + id="1" + ) + return rx_rmii_phy, rx_rmii_phy_2 def get_rmii_4b_port_tx_phy(clk, rxd_4b_port_pin_assignment, **kwargs): @@ -406,3 +451,49 @@ def get_rmii_1b_port_rx_phy(clk, **kwargs): ) return phy +def do_rx_test_dual(capfd, mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, test_file, seed, + extra_tasks=[], override_dut_dir=False, rx_width=None, tx_width=None): + + """ Shared test code for all RX tests using the test_rx application. + """ + testname,extension = os.path.splitext(os.path.basename(test_file)) + + with capfd.disabled(): + print(f"Running {testname}: {mac} {[phy.get_name() for phy in tx_phy]} phy, {arch}, rx_width {rx_width} arch at {tx_clk.get_name()} (seed = {seed})") + capfd.readouterr() # clear capfd buffer + + profile = f'{mac}_{tx_phy[0].get_name()}' + if rx_width: + profile = profile + f"_rx{rx_width}" + if tx_width: + profile = profile + f"_tx{tx_width}" + profile = profile + f"_{arch}" + + dut_dir = override_dut_dir if override_dut_dir else testname + binary = f'{dut_dir}/bin/{profile}/{dut_dir}_{profile}.xe' + assert os.path.isfile(binary), f"Missing .xe {binary}" + + + expect_folder = create_if_needed("expect_temp") + if rx_width: + expect_filename = f'{expect_folder}/{testname}_{mac}_{tx_phy[0].get_name()}_{rx_width}_{tx_width}_{tx_clk.get_name()}_{arch}.expect' + else: + expect_filename = f'{expect_folder}/{testname}_{mac}_{tx_phy[0].get_name()}_{tx_clk.get_name()}_{arch}.expect' + + create_expect(packets, expect_filename) + + tester = px.testers.ComparisonTester(open(expect_filename), ordered=False) + + simargs = get_sim_args(testname, mac, tx_clk, tx_phy[0], arch) + + st = [tx_clk, rx_phy[0], rx_phy[1], tx_phy[0], tx_phy[1]] + + result = px.run_on_simulator_( binary, + simthreads=st + extra_tasks, + tester=tester, + simargs=simargs, + do_xe_prebuild=False, + capfd=capfd + ) + + assert result is True, f"{result}" diff --git a/tests/mii_phy.py b/tests/mii_phy.py index 5c073314..a968b64e 100644 --- a/tests/mii_phy.py +++ b/tests/mii_phy.py @@ -139,7 +139,7 @@ def run(self): class RxPhy(px.SimThread): - def __init__(self, name, txd, txen, clock, print_packets, packet_fn, verbose, test_ctrl): + def __init__(self, name, txd, txen, clock, print_packets, packet_fn, verbose, test_ctrl, id): self._name = name self._txd = txd self._txen = txen @@ -148,6 +148,7 @@ def __init__(self, name, txd, txen, clock, print_packets, packet_fn, verbose, te self._verbose = verbose self._test_ctrl = test_ctrl self._packet_fn = packet_fn + self._id = id self.expected_packets = None self.expect_packet_index = 0 @@ -163,6 +164,9 @@ def get_name(self): def get_clock(self): return self._clock + def get_id(self): + return self._id + def set_expected_packets(self, packets): self.expect_packet_index = 0; self.expected_packets = packets @@ -174,9 +178,9 @@ def set_expected_packets(self, packets): class MiiReceiver(RxPhy): def __init__(self, txd, txen, clock, print_packets=False, - packet_fn=None, verbose=False, test_ctrl=None): + packet_fn=None, verbose=False, test_ctrl=None, id=None): super(MiiReceiver, self).__init__('mii', txd, txen, clock, print_packets, - packet_fn, verbose, test_ctrl) + packet_fn, verbose, test_ctrl, id) def run(self): xsi = self.xsi diff --git a/tests/rgmii_phy.py b/tests/rgmii_phy.py index fc810611..27b69f27 100644 --- a/tests/rgmii_phy.py +++ b/tests/rgmii_phy.py @@ -112,9 +112,9 @@ def run(self): class RgmiiReceiver(RxPhy): def __init__(self, txd, txen, clock, print_packets=False, - packet_fn=None, verbose=None, test_ctrl=None): + packet_fn=None, verbose=None, test_ctrl=None, id=None): super(RgmiiReceiver, self).__init__('rgmii', txd, txen, clock, print_packets, - packet_fn, verbose, test_ctrl) + packet_fn, verbose, test_ctrl, id) def run(self): xsi = self.xsi diff --git a/tests/rmii_phy.py b/tests/rmii_phy.py index 3339397c..5d524fba 100644 --- a/tests/rmii_phy.py +++ b/tests/rmii_phy.py @@ -20,7 +20,7 @@ def get_port_width_from_name(port_name): class RMiiTxPhy(px.SimThread): # Time in fs from the last packet being sent until the end of test is signalled to the DUT - END_OF_TEST_TIME = (10 * px.Xsi.get_xsi_tick_freq_hz())/1e6 # 10us + END_OF_TEST_TIME = (1000 * px.Xsi.get_xsi_tick_freq_hz())/1e6 # 1000us def __init__(self, name, rxd, rxdv, rxer, clock, rxd_4b_port_pin_assignment, @@ -90,7 +90,6 @@ def end_test(self): total_data_bits = total_packet_bytes * 8 - # Allow 2 cycles per bit timeout_time += 2 * total_data_bits * 1e6 # scale to femtoseconds vs nanoseconds in old xsim # The clock ticks are 2ns long @@ -99,6 +98,7 @@ def end_test(self): # The packets are copied to and from the user application timeout_time *= 2 + self.wait_until(self.xsi.get_time() + timeout_time) if self._test_ctrl: @@ -253,7 +253,7 @@ def run(self): class RMiiRxPhy(px.SimThread): - def __init__(self, name, txd, txen, clock, txd_4b_port_pin_assignment, print_packets, packet_fn, verbose, test_ctrl): + def __init__(self, name, txd, txen, clock, txd_4b_port_pin_assignment, print_packets, packet_fn, verbose, test_ctrl, id): self._name = name # Check if txd is a string or an array of strings if not isinstance(txd, (list, tuple)): @@ -267,6 +267,7 @@ def __init__(self, name, txd, txen, clock, txd_4b_port_pin_assignment, print_pac self._verbose = verbose self._test_ctrl = test_ctrl self._packet_fn = packet_fn + self._id = id self._txd_port_width = get_port_width_from_name(self._txd[0]) if len(self._txd) == 2: @@ -295,6 +296,9 @@ def get_name(self): def get_clock(self): return self._clock + def get_id(self): + return self._id + def set_expected_packets(self, packets): self.expect_packet_index = 0; self.expected_packets = packets @@ -309,10 +313,10 @@ class RMiiReceiver(RMiiRxPhy): def __init__(self, txd, txen, clock, txd_4b_port_pin_assignment="lower_2b", print_packets=False, - packet_fn=None, verbose=False, test_ctrl=None): + packet_fn=None, verbose=False, test_ctrl=None, id=None): super(RMiiReceiver, self).__init__('rmii', txd, txen, clock, txd_4b_port_pin_assignment, print_packets, - packet_fn, verbose, test_ctrl) + packet_fn, verbose, test_ctrl, id) self._txen_val = None def run(self): diff --git a/tests/test_rmii_dual_basic.py b/tests/test_rmii_dual_basic.py index 336ebbe2..fc82b07a 100644 --- a/tests/test_rmii_dual_basic.py +++ b/tests/test_rmii_dual_basic.py @@ -11,104 +11,49 @@ from mii_clock import Clock from helpers import packet_processing_time, get_dut_mac_address from helpers import choose_small_frame_size, run_parametrised_test_rx, check_received_packet -from helpers import generate_tests, create_if_needed, create_expect, get_sim_args -from helpers import get_rmii_clk, get_rmii_tx_phy, get_rmii_rx_phy +from helpers import generate_tests +from helpers import get_rmii_clk, get_rmii_tx_phy_dual, get_rmii_rx_phy_dual from rmii_phy import RMiiTransmitter, RMiiReceiver +from helpers import do_rx_test_dual - -def do_rx_test_dual(capfd, mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, test_file, seed, loopback_packets, forwarded_packets, - extra_tasks=[], override_dut_dir=False, rx_width=None, tx_width=None): - - """ Shared test code for all RX tests using the test_rx application. - """ - testname,extension = os.path.splitext(os.path.basename(test_file)) - +test_params_file = Path(__file__).parent / "test_rmii_dual_basic/test_params.json" +@pytest.mark.parametrize("params", generate_tests(test_params_file)[0], ids=generate_tests(test_params_file)[1]) +def test_rmii_dual_basic(capfd, seed, params): with capfd.disabled(): - print(f"Running {testname}: {mac} {[phy.get_name() for phy in tx_phy]} phy, {arch}, rx_width {rx_width} arch at {tx_clk.get_name()} (seed = {seed})") - capfd.readouterr() # clear capfd buffer - - profile = f'{mac}_{tx_phy[0].get_name()}' - if rx_width: - profile = profile + f"_rx{rx_width}" - if tx_width: - profile = profile + f"_tx{tx_width}" - profile = profile + f"_{arch}" - - dut_dir = override_dut_dir if override_dut_dir else testname - binary = f'{dut_dir}/bin/{profile}/{dut_dir}_{profile}.xe' - assert os.path.isfile(binary), f"Missing .xe {binary}" - - tx_phy[1].set_packets(packets) - rx_phy[1].set_expected_packets(loopback_packets) - rx_phy[0].set_expected_packets(forwarded_packets) - - - expect_folder = create_if_needed("expect_temp") - if rx_width: - expect_filename = f'{expect_folder}/{testname}_{mac}_{tx_phy[0].get_name()}_{rx_width}_{tx_width}_{tx_clk.get_name()}_{arch}.expect' - else: - expect_filename = f'{expect_folder}/{testname}_{mac}_{tx_phy[0].get_name()}_{tx_clk.get_name()}_{arch}.expect' - - create_expect(packets, expect_filename) - - tester = px.testers.ComparisonTester(open(expect_filename)) - tester = None - - simargs = get_sim_args(testname, mac, tx_clk, tx_phy[0], arch) - print(simargs) - - st = [tx_clk, rx_phy[0], rx_phy[1], tx_phy[0], tx_phy[1]] - - - result = px.run_on_simulator_( binary, - simthreads=st + extra_tasks, - tester=tester, - simargs=simargs, - do_xe_prebuild=False, - capfd=capfd - ) - - assert result is True, f"{result}" + print(params) + if seed == None: + seed = random.randint(0, sys.maxsize) -def rmii_dual_test(capfd, params, seed): + rand = random.Random() + rand.seed(seed) verbose = False - clk = get_rmii_clk(Clock.CLK_50MHz) - tx_rmii_phy = get_rmii_tx_phy(params['rx_width'], - clk, - verbose=verbose - ) - tx_rmii_phy_2 = get_rmii_tx_phy(params['rx_width'], + # Instantiate clk and phys + clk = get_rmii_clk(Clock.CLK_50MHz) + tx_rmii_phy, tx_rmii_phy_2 = get_rmii_tx_phy_dual( + [params['rx_width'], params['rx_width']], clk, verbose=verbose, - second_phy=True + expect_loopback=True ) - rx_rmii_phy = get_rmii_rx_phy(params['tx_width'], + rx_rmii_phy, rx_rmii_phy_2 = get_rmii_rx_phy_dual( + [params['tx_width'], params['tx_width']], clk, packet_fn=check_received_packet, verbose=verbose ) - rx_rmii_phy_2 = get_rmii_rx_phy(params['tx_width'], - clk, - packet_fn=check_received_packet, - verbose=verbose, - second_phy=True - ) - mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, rx_width, tx_width = params["mac"], params["arch"], None, [rx_rmii_phy, rx_rmii_phy_2], clk, [tx_rmii_phy, tx_rmii_phy_2], params['rx_width'],params['tx_width'] - rand = random.Random() - rand.seed(seed) - dut_mac_address = get_dut_mac_address() not_dut_mac_address = [] for i in range(6): not_dut_mac_address.append(dut_mac_address[i]+1) + num_test_packets = 30 packets = [] loopback_packets = [] forwarded_packets = [] @@ -116,38 +61,30 @@ def rmii_dual_test(capfd, params, seed): # Send frames which excercise all of the tail length vals (0, 1, 2, 3 bytes) packet_start_len = 100 # Packets that get looped back on the same port - for i in range(5): + for i in range(num_test_packets): loopback_packets.append(MiiPacket(rand, dst_mac_addr=dut_mac_address, create_data_args=['step', (i, packet_start_len + i)], - inter_frame_gap=packet_processing_time(tx_phy[0], packet_start_len, mac), + inter_frame_gap=200*clk.get_bit_time() )) # packets that get forwarded to the other port - for i in range(5): + for i in range(num_test_packets): forwarded_packets.append(MiiPacket(rand, dst_mac_addr=not_dut_mac_address, create_data_args=['step', (i, packet_start_len + i)], - inter_frame_gap=packet_processing_time(tx_phy[0], packet_start_len, mac), + inter_frame_gap=200*clk.get_bit_time() )) # interleave loopback and forwarded packets - for i in range(5): + for i in range(num_test_packets): packets.append(loopback_packets[i]) packets.append(forwarded_packets[i]) - - do_rx_test_dual(capfd, mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, __file__, seed, loopback_packets, forwarded_packets, rx_width=rx_width, tx_width=tx_width) + tx_phy[1].set_packets(packets) # Send all packets to mac port 1 + rx_phy[1].set_expected_packets(loopback_packets) # Looped back packets show up on port 1 of the sim phy + rx_phy[0].set_expected_packets(forwarded_packets) # Forwarded packets show up on port 0 of the sim phy + do_rx_test_dual(capfd, mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, [forwarded_packets, loopback_packets], __file__, seed, rx_width=rx_width, tx_width=tx_width) -test_params_file = Path(__file__).parent / "test_rmii_dual_basic/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) - - rmii_dual_test(capfd, params, seed) diff --git a/tests/test_rmii_dual_fwd_only.py b/tests/test_rmii_dual_fwd_only.py new file mode 100644 index 00000000..4c516542 --- /dev/null +++ b/tests/test_rmii_dual_fwd_only.py @@ -0,0 +1,103 @@ +# Copyright 2024-2025 XMOS LIMITED. +# This Software is subject to the terms of the XMOS Public Licence: Version 1. + +""" +DUT receives packets on both ports. +None of the packets received by the DUT are meant for the client running on the DUT, so +they get forwarded on the other port. +So, the sim phy port 0, receives packets that were sent to dut mac port 1 and vice versa +""" + +import random +import Pyxsim as px +from pathlib import Path +import pytest +import sys, os +import numpy as np + +from mii_packet import MiiPacket +from mii_clock import Clock +from helpers import packet_processing_time, get_dut_mac_address +from helpers import choose_small_frame_size, run_parametrised_test_rx, check_received_packet +from helpers import generate_tests, create_if_needed, create_expect, get_sim_args +from helpers import get_rmii_clk, get_rmii_tx_phy_dual, get_rmii_rx_phy_dual +from rmii_phy import RMiiTransmitter, RMiiReceiver +from helpers import do_rx_test_dual + + +def rmii_dual_fwd_test(capfd, params, seed): + rand = random.Random() + rand.seed(seed) + verbose = False + + # Instantiate clk and phys + clk = get_rmii_clk(Clock.CLK_50MHz) + tx_rmii_phy, tx_rmii_phy_2 = get_rmii_tx_phy_dual( + [params['rx_width'], params['rx_width']], + clk, + verbose=verbose + ) + + rx_rmii_phy, rx_rmii_phy_2 = get_rmii_rx_phy_dual( + [params['tx_width'], params['tx_width']], + clk, + packet_fn=check_received_packet, + verbose=verbose + ) + + + mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, rx_width, tx_width = params["mac"], params["arch"], None, [rx_rmii_phy, rx_rmii_phy_2], clk, [tx_rmii_phy, tx_rmii_phy_2], params['rx_width'],params['tx_width'] + + + + dut_mac_address = get_dut_mac_address() # Mac address for which the client running on the DUT will register to receive packets + + # non dut mac address, packets destined for which get forwarded on the other port + not_dut_mac_address_0 = [] # Mac address which is different from the one for which the client running on the DUT has registered to receive packets + not_dut_mac_address_1 = [] # Mac address which is different from the one for which the client running on the DUT has registered to receive packets + for i in range(6): + not_dut_mac_address_0.append(dut_mac_address[i]+1) + not_dut_mac_address_1.append(dut_mac_address[i]+2) + + num_test_packets = 50 + + packets_mac_0 = [] # Packets arriving on mac rx port 0. These get forwarded to tx port 1 + packets_mac_1 = [] # Packets arriving on mac rx port 1. These get forwarded to tx port 0 + + + # Send frames which excercise all of the tail length vals (0, 1, 2, 3 bytes) + packet_start_len = 100 + ifg = tx_clk.get_min_ifg() + + for i in range(num_test_packets): + packets_mac_0.append(MiiPacket(rand, + dst_mac_addr=not_dut_mac_address_0, + create_data_args=['step', (i, packet_start_len + i)], + inter_frame_gap=ifg + )) + packets_mac_1.append(MiiPacket(rand, + dst_mac_addr=not_dut_mac_address_1, + create_data_args=['step', (2*i, packet_start_len + 2*i)], + inter_frame_gap=ifg + )) + + tx_phy[0].set_packets(packets_mac_0) + tx_phy[1].set_packets(packets_mac_1) + + rx_phy[0].set_expected_packets(packets_mac_1) + rx_phy[1].set_expected_packets(packets_mac_0) + + do_rx_test_dual(capfd, mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, [packets_mac_0, packets_mac_1], __file__, seed, rx_width=rx_width, tx_width=tx_width, override_dut_dir="test_rmii_dual_basic") + + + +test_params_file = Path(__file__).parent / "test_rmii_dual_basic/test_params.json" +@pytest.mark.parametrize("params", generate_tests(test_params_file)[0], ids=generate_tests(test_params_file)[1]) +def test_rmii_dual_fwd_only(capfd, seed, params): + with capfd.disabled(): + print(params) + + if seed == None: + seed = random.randint(0, sys.maxsize) + + rmii_dual_fwd_test(capfd, params, seed) From 8f4288c27f840000cab20120970c373a6df31f2a Mon Sep 17 00:00:00 2001 From: Shuchita Khare Date: Tue, 21 Jan 2025 21:02:57 +0000 Subject: [PATCH 18/25] Sync between sim threads by writing to ports --- tests/helpers.py | 34 ++++++++++++++++---------- tests/rmii_phy.py | 7 +++++- tests/test_rmii_dual_basic/src/main.xc | 4 +++ 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/tests/helpers.py b/tests/helpers.py index fcd226f6..571adfcb 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -290,10 +290,12 @@ def check_received_packet(packet, phy): if phy.expect_packet_index >= phy.num_expected_packets: print("Test done") - if phy.get_name() == "rmii": - wait_time_us = 200 # In case the other port is receiving, wait sometime before terminating - wait_time_ticks = (wait_time_us * px.Xsi.get_xsi_tick_freq_hz())/1e6 - phy.wait_until(phy.xsi.get_time() + wait_time_ticks) + if phy._sync_send_port != None: + phy.xsi.drive_port_pins(phy._sync_send_port, 1) + + if (phy._sync_recv_port != None): # wait for the other phy to signal that its done as well before terminating + phy.wait(lambda x: phy.xsi.sample_port_pins(phy._sync_recv_port) == 1) + phy.xsi.terminate() def generate_tests(test_params_json): @@ -382,17 +384,22 @@ def get_rmii_rx_phy(tx_width, clk, **kwargs): return rx_rmii_phy def get_rmii_rx_phy_dual(tx_widths, clk, **kwargs): + sync_ports = ['tile[0]:XS1_PORT_1G', 'tile[0]:XS1_PORT_1N'] rx_rmii_phy = get_rmii_rx_phy(tx_widths[0], clk, **kwargs, - id="0" + id="0", + sync_send_port=sync_ports[0], + sync_recv_port=sync_ports[1] ) rx_rmii_phy_2 = get_rmii_rx_phy(tx_widths[1], clk, **kwargs, second_phy=True, - id="1" + id="1", + sync_send_port=sync_ports[1], + sync_recv_port=sync_ports[0] ) return rx_rmii_phy, rx_rmii_phy_2 @@ -488,12 +495,13 @@ def do_rx_test_dual(capfd, mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, t st = [tx_clk, rx_phy[0], rx_phy[1], tx_phy[0], tx_phy[1]] - result = px.run_on_simulator_( binary, - simthreads=st + extra_tasks, - tester=tester, - simargs=simargs, - do_xe_prebuild=False, - capfd=capfd - ) + with capfd.disabled(): + result = px.run_on_simulator_( binary, + simthreads=st + extra_tasks, + tester=tester, + simargs=simargs, + do_xe_prebuild=False, + #capfd=capfd + ) assert result is True, f"{result}" diff --git a/tests/rmii_phy.py b/tests/rmii_phy.py index 5d524fba..89d4dc7f 100644 --- a/tests/rmii_phy.py +++ b/tests/rmii_phy.py @@ -313,11 +313,13 @@ class RMiiReceiver(RMiiRxPhy): def __init__(self, txd, txen, clock, txd_4b_port_pin_assignment="lower_2b", print_packets=False, - packet_fn=None, verbose=False, test_ctrl=None, id=None): + packet_fn=None, verbose=False, test_ctrl=None, id=None, sync_send_port=None, sync_recv_port=None): super(RMiiReceiver, self).__init__('rmii', txd, txen, clock, txd_4b_port_pin_assignment, print_packets, packet_fn, verbose, test_ctrl, id) self._txen_val = None + self._sync_send_port = sync_send_port + self._sync_recv_port = sync_recv_port def run(self): rand = random.Random() @@ -326,6 +328,9 @@ def run(self): crumb_index = 0 xsi = self.xsi + if self._sync_send_port != None: + xsi.drive_port_pins(self._sync_send_port, 0) + self.wait(lambda x: xsi.sample_port_pins(self._txen) == 0) self._txen_val = 0 self.wait(lambda x: self._clock.is_low()) # Wait for clock to go low so we can start sampling at the next rising edge diff --git a/tests/test_rmii_dual_basic/src/main.xc b/tests/test_rmii_dual_basic/src/main.xc index 8cf6f74f..e64e610e 100644 --- a/tests/test_rmii_dual_basic/src/main.xc +++ b/tests/test_rmii_dual_basic/src/main.xc @@ -132,6 +132,9 @@ void test_rx_loopback(client ethernet_cfg_if cfg, #define NUM_RX_LP_IF 1 #define NUM_TX_LP_IF 1 +port p_rx_lp_control_1 = on tile[0]:XS1_PORT_1G; +port p_rx_lp_control_2 = on tile[0]:XS1_PORT_1N; + int main() { ethernet_cfg_if i_cfg[NUM_CFG_IF]; @@ -148,6 +151,7 @@ int main() #endif + par { unsafe{rmii_ethernet_rt_mac_dual(i_cfg, NUM_CFG_IF, From 17e9a5c2c1b849299551bde7bf26d46a9bd322db Mon Sep 17 00:00:00 2001 From: Shuchita Khare Date: Wed, 22 Jan 2025 10:24:31 +0000 Subject: [PATCH 19/25] Use multiprocessing.Pipe for synchronisation between threads --- tests/helpers.py | 41 ++++++++++++++------------ tests/rmii_phy.py | 8 ++--- tests/test_rmii_dual_basic/src/main.xc | 3 -- 3 files changed, 24 insertions(+), 28 deletions(-) diff --git a/tests/helpers.py b/tests/helpers.py index 571adfcb..be63478c 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -10,6 +10,7 @@ import json import copy import numpy as np +import multiprocessing from mii_clock import Clock from mii_phy import MiiTransmitter, MiiReceiver @@ -290,12 +291,15 @@ def check_received_packet(packet, phy): if phy.expect_packet_index >= phy.num_expected_packets: print("Test done") - if phy._sync_send_port != None: - phy.xsi.drive_port_pins(phy._sync_send_port, 1) - - if (phy._sync_recv_port != None): # wait for the other phy to signal that its done as well before terminating - phy.wait(lambda x: phy.xsi.sample_port_pins(phy._sync_recv_port) == 1) - + if phy._sync_pipe != None: + phy._sync_pipe.send(f"done") # Send done to the other phy + while True: # wait for a done from the other end + poll_duration_us = 1 + poll_duration_ticks = (poll_duration_us* px.Xsi.get_xsi_tick_freq_hz())/1e6 + phy.wait_until(phy.xsi.get_time() + poll_duration_ticks) # Thread needs to yield for other threads to run + if phy._sync_pipe.poll(0): # Check if there's something to receive from the other phy + assert phy._sync_pipe.recv() == "done", "Unexpected recv over the pipe from the other phy" + break phy.xsi.terminate() def generate_tests(test_params_json): @@ -384,13 +388,13 @@ def get_rmii_rx_phy(tx_width, clk, **kwargs): return rx_rmii_phy def get_rmii_rx_phy_dual(tx_widths, clk, **kwargs): - sync_ports = ['tile[0]:XS1_PORT_1G', 'tile[0]:XS1_PORT_1N'] + end1, end2 = multiprocessing.Pipe() + rx_rmii_phy = get_rmii_rx_phy(tx_widths[0], clk, **kwargs, id="0", - sync_send_port=sync_ports[0], - sync_recv_port=sync_ports[1] + sync_pipe=end1 ) rx_rmii_phy_2 = get_rmii_rx_phy(tx_widths[1], @@ -398,8 +402,7 @@ def get_rmii_rx_phy_dual(tx_widths, clk, **kwargs): **kwargs, second_phy=True, id="1", - sync_send_port=sync_ports[1], - sync_recv_port=sync_ports[0] + sync_pipe=end2 ) return rx_rmii_phy, rx_rmii_phy_2 @@ -495,13 +498,13 @@ def do_rx_test_dual(capfd, mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, t st = [tx_clk, rx_phy[0], rx_phy[1], tx_phy[0], tx_phy[1]] - with capfd.disabled(): - result = px.run_on_simulator_( binary, - simthreads=st + extra_tasks, - tester=tester, - simargs=simargs, - do_xe_prebuild=False, - #capfd=capfd - ) + + result = px.run_on_simulator_( binary, + simthreads=st + extra_tasks, + tester=tester, + simargs=simargs, + do_xe_prebuild=False, + capfd=capfd + ) assert result is True, f"{result}" diff --git a/tests/rmii_phy.py b/tests/rmii_phy.py index 89d4dc7f..8d128acc 100644 --- a/tests/rmii_phy.py +++ b/tests/rmii_phy.py @@ -313,13 +313,12 @@ class RMiiReceiver(RMiiRxPhy): def __init__(self, txd, txen, clock, txd_4b_port_pin_assignment="lower_2b", print_packets=False, - packet_fn=None, verbose=False, test_ctrl=None, id=None, sync_send_port=None, sync_recv_port=None): + packet_fn=None, verbose=False, test_ctrl=None, id=None, sync_pipe=None): super(RMiiReceiver, self).__init__('rmii', txd, txen, clock, txd_4b_port_pin_assignment, print_packets, packet_fn, verbose, test_ctrl, id) self._txen_val = None - self._sync_send_port = sync_send_port - self._sync_recv_port = sync_recv_port + self._sync_pipe = sync_pipe def run(self): rand = random.Random() @@ -328,9 +327,6 @@ def run(self): crumb_index = 0 xsi = self.xsi - if self._sync_send_port != None: - xsi.drive_port_pins(self._sync_send_port, 0) - self.wait(lambda x: xsi.sample_port_pins(self._txen) == 0) self._txen_val = 0 self.wait(lambda x: self._clock.is_low()) # Wait for clock to go low so we can start sampling at the next rising edge diff --git a/tests/test_rmii_dual_basic/src/main.xc b/tests/test_rmii_dual_basic/src/main.xc index e64e610e..5fc79935 100644 --- a/tests/test_rmii_dual_basic/src/main.xc +++ b/tests/test_rmii_dual_basic/src/main.xc @@ -132,9 +132,6 @@ void test_rx_loopback(client ethernet_cfg_if cfg, #define NUM_RX_LP_IF 1 #define NUM_TX_LP_IF 1 -port p_rx_lp_control_1 = on tile[0]:XS1_PORT_1G; -port p_rx_lp_control_2 = on tile[0]:XS1_PORT_1N; - int main() { ethernet_cfg_if i_cfg[NUM_CFG_IF]; From 7ab897ce671ed428c676ebef532c6e932a031cd1 Mon Sep 17 00:00:00 2001 From: Shuchita Khare Date: Wed, 22 Jan 2025 10:51:24 +0000 Subject: [PATCH 20/25] Add filler thread --- tests/test_rmii_dual_basic.py | 4 ++-- tests/test_rmii_dual_basic/src/main.xc | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/test_rmii_dual_basic.py b/tests/test_rmii_dual_basic.py index fc82b07a..720dfdc0 100644 --- a/tests/test_rmii_dual_basic.py +++ b/tests/test_rmii_dual_basic.py @@ -65,14 +65,14 @@ def test_rmii_dual_basic(capfd, seed, params): loopback_packets.append(MiiPacket(rand, dst_mac_addr=dut_mac_address, create_data_args=['step', (i, packet_start_len + i)], - inter_frame_gap=200*clk.get_bit_time() + inter_frame_gap=201*clk.get_bit_time() )) # packets that get forwarded to the other port for i in range(num_test_packets): forwarded_packets.append(MiiPacket(rand, dst_mac_addr=not_dut_mac_address, create_data_args=['step', (i, packet_start_len + i)], - inter_frame_gap=200*clk.get_bit_time() + inter_frame_gap=201*clk.get_bit_time() )) # interleave loopback and forwarded packets diff --git a/tests/test_rmii_dual_basic/src/main.xc b/tests/test_rmii_dual_basic/src/main.xc index 5fc79935..28943f57 100644 --- a/tests/test_rmii_dual_basic/src/main.xc +++ b/tests/test_rmii_dual_basic/src/main.xc @@ -10,6 +10,7 @@ #include "syscall.h" #include "ports_rmii.h" +#include "helpers.xc" #if ETHERNET_SUPPORT_HP_QUEUES typedef interface loopback_if { @@ -168,6 +169,7 @@ int main() test_rx(i_cfg[0], c_rx_hp, i_loopback); test_loopback(c_tx_hp, i_loopback); #else + filler(0x2222); test_rx_loopback(i_cfg[0], i_rx_lp[0], i_tx_lp[0]); #endif From 980fc1b452239d0ccf121d3b0a27a1600fbd7b2e Mon Sep 17 00:00:00 2001 From: Shuchita Khare Date: Wed, 22 Jan 2025 11:14:23 +0000 Subject: [PATCH 21/25] Remove dependence on NUM_ETHERNET_PORTS define --- lib_ethernet/src/mii_ethernet_rt_mac.xc | 42 +++++++++++++----------- lib_ethernet/src/mii_filter.h | 3 +- lib_ethernet/src/mii_filter.xc | 20 ++++++----- lib_ethernet/src/rmii_ethernet_rt_mac.xc | 12 ++++--- lib_ethernet/src/rmii_master.h | 3 +- tests/test_rmii_dual_basic.py | 4 +-- 6 files changed, 49 insertions(+), 35 deletions(-) diff --git a/lib_ethernet/src/mii_ethernet_rt_mac.xc b/lib_ethernet/src/mii_ethernet_rt_mac.xc index c3057848..d4b8f34b 100644 --- a/lib_ethernet/src/mii_ethernet_rt_mac.xc +++ b/lib_ethernet/src/mii_ethernet_rt_mac.xc @@ -246,7 +246,9 @@ unsafe void mii_ethernet_server(mii_mempool_t * unsafe rx_mem, volatile ethernet_port_state_t * unsafe p_port_state, volatile int * unsafe running_flag_ptr, chanend c_rx_pins_exit[], - phy_100mb_t phy_type) + phy_100mb_t phy_type, + static const unsigned num_mac_ports + ) { uint8_t mac_address[MACADDR_NUM_BYTES] = {0}; rx_client_state_t rx_client_state_lp[n_rx_lp]; @@ -255,9 +257,9 @@ unsafe void mii_ethernet_server(mii_mempool_t * unsafe rx_mem, tx_client_state_t tx_client_state_hp[1]; - unsigned rd_index_hp[NUM_ETHERNET_PORTS], rd_index_lp[NUM_ETHERNET_PORTS]; + unsigned rd_index_hp[num_mac_ports], rd_index_lp[num_mac_ports]; // Server's read index in the rx_packets_lp and rx_packets_hp queues - for(int i=0; i dst_port; if(dst_port == ETHERNET_ALL_INTERFACES) { - dst_port = 0; // TODO FIXME Sending on multiple ports with one send_packet() call when NUM_ETHERNET_PORTS > 1 is not supported yet. + dst_port = 0; // TODO FIXME Sending on multiple ports with one send_packet() call when num_mac_ports > 1 is not supported yet. } mii_packet_t * unsafe buf = tx_client_state_hp[0].send_buffer[dst_port]; @@ -584,7 +586,7 @@ unsafe void mii_ethernet_server(mii_mempool_t * unsafe rx_mem, int request_timestamp, unsigned dst_port) -> unsigned ready: ready = 1; - for(int p=0; p Date: Wed, 22 Jan 2025 11:31:38 +0000 Subject: [PATCH 22/25] Pass mac_ports argument to rmii_master_tx_pins() --- lib_ethernet/src/rmii_ethernet_rt_mac.xc | 9 ++++++--- lib_ethernet/src/rmii_master.h | 3 ++- lib_ethernet/src/rmii_master.xc | 7 ++++--- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/lib_ethernet/src/rmii_ethernet_rt_mac.xc b/lib_ethernet/src/rmii_ethernet_rt_mac.xc index cf546a72..2ea11708 100644 --- a/lib_ethernet/src/rmii_ethernet_rt_mac.xc +++ b/lib_ethernet/src/rmii_ethernet_rt_mac.xc @@ -243,7 +243,8 @@ void rmii_ethernet_rt_mac(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), stati txclk, p_port_state, 0, - running_flag_ptr); + running_flag_ptr, + 1); mii_ethernet_filter(c_conf, incoming_packets_ptr, @@ -518,7 +519,8 @@ void rmii_ethernet_rt_mac_dual(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), txclk_0, &p_port_state[0], 0, - running_flag_ptr); + running_flag_ptr, + 2); rmii_master_tx_pins(tx_mem_lp[1], tx_mem_hp[1], @@ -535,7 +537,8 @@ void rmii_ethernet_rt_mac_dual(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), txclk_1, &p_port_state[1], 1, - running_flag_ptr); + running_flag_ptr, + 2); mii_ethernet_filter(c_conf, diff --git a/lib_ethernet/src/rmii_master.h b/lib_ethernet/src/rmii_master.h index 99934f18..c8b7ce2a 100644 --- a/lib_ethernet/src/rmii_master.h +++ b/lib_ethernet/src/rmii_master.h @@ -63,7 +63,8 @@ unsafe void rmii_master_tx_pins(mii_mempool_t tx_mem_lp, clock txclk, volatile ethernet_port_state_t * unsafe p_port_state, int ifnum, - volatile int * unsafe running_flag_ptr); + volatile int * unsafe running_flag_ptr, + static const unsigned num_mac_ports); // This is re-used by RMII as it is abstracted from the MAC pins diff --git a/lib_ethernet/src/rmii_master.xc b/lib_ethernet/src/rmii_master.xc index b04b833d..81e7e61f 100644 --- a/lib_ethernet/src/rmii_master.xc +++ b/lib_ethernet/src/rmii_master.xc @@ -991,7 +991,8 @@ unsafe void rmii_master_tx_pins(mii_mempool_t tx_mem_lp, clock txclk, volatile ethernet_port_state_t * unsafe p_port_state, int ifnum, - volatile int * unsafe running_flag_ptr) + volatile int * unsafe running_flag_ptr, + static const unsigned num_mac_ports) { // Flag for readability and faster comparison const unsigned use_4b = (tx_port_width == 4); @@ -1026,7 +1027,7 @@ unsafe void rmii_master_tx_pins(mii_mempool_t tx_mem_lp, buf = mii_get_next_buf(packets_hp); if(!buf) { - for (unsigned int i=0; i Date: Wed, 22 Jan 2025 11:53:04 +0000 Subject: [PATCH 23/25] Remove dependence on NUM_ETHERNET_PORTS define --- lib_ethernet/api/ethernet.h | 5 ++++ lib_ethernet/src/client_state.h | 14 +++++----- lib_ethernet/src/client_state.xc | 4 +-- lib_ethernet/src/default_ethernet_conf.h | 4 +-- lib_ethernet/src/mii_buffering.c | 4 --- lib_ethernet/src/rmii_ethernet_rt_mac.xc | 35 ++++++++++++------------ 6 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lib_ethernet/api/ethernet.h b/lib_ethernet/api/ethernet.h index 4d62c9f2..529e08be 100644 --- a/lib_ethernet/api/ethernet.h +++ b/lib_ethernet/api/ethernet.h @@ -721,6 +721,11 @@ void rmii_ethernet_rt_mac(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), stati enum ethernet_enable_shaper_t shaper_enabled); +/** 100 Mbps RT RMII dual mac component. + * It creates two MAC instances, with each MAC connected to a separate, dedicated RMII PHY interface. + * + * Note: This is still WIP and requires additional testing. + */ void rmii_ethernet_rt_mac_dual(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), static_const_unsigned_t n_cfg, SERVER_INTERFACE(ethernet_rx_if, i_rx_lp[n_rx_lp]), static_const_unsigned_t n_rx_lp, SERVER_INTERFACE(ethernet_tx_if, i_tx_lp[n_tx_lp]), static_const_unsigned_t n_tx_lp, diff --git a/lib_ethernet/src/client_state.h b/lib_ethernet/src/client_state.h index e0abd883..b51bb235 100644 --- a/lib_ethernet/src/client_state.h +++ b/lib_ethernet/src/client_state.h @@ -24,10 +24,10 @@ enum status_update_state_t { typedef struct { unsigned dropped_pkt_cnt; - unsigned rd_index[NUM_ETHERNET_PORTS]; - unsigned wr_index[NUM_ETHERNET_PORTS]; - void *fifo[NUM_ETHERNET_PORTS][ETHERNET_RX_CLIENT_QUEUE_SIZE]; - int status_update_state[NUM_ETHERNET_PORTS]; + unsigned rd_index[MAX_ETHERNET_PORTS]; + unsigned wr_index[MAX_ETHERNET_PORTS]; + void *fifo[MAX_ETHERNET_PORTS][ETHERNET_RX_CLIENT_QUEUE_SIZE]; + int status_update_state[MAX_ETHERNET_PORTS]; size_t num_etype_filters; int strip_vlan_tags; uint16_t etype_filters[ETHERNET_MAX_ETHERTYPE_FILTERS]; @@ -37,9 +37,9 @@ typedef struct typedef struct { int requested_send_buffer_size; - mii_packet_t *send_buffer[NUM_ETHERNET_PORTS]; - int has_outgoing_timestamp_info[NUM_ETHERNET_PORTS]; - unsigned outgoing_timestamp[NUM_ETHERNET_PORTS]; + mii_packet_t *send_buffer[MAX_ETHERNET_PORTS]; + int has_outgoing_timestamp_info[MAX_ETHERNET_PORTS]; + unsigned outgoing_timestamp[MAX_ETHERNET_PORTS]; int dst_port; } tx_client_state_t; diff --git a/lib_ethernet/src/client_state.xc b/lib_ethernet/src/client_state.xc index f0fe209a..cf6f7baa 100644 --- a/lib_ethernet/src/client_state.xc +++ b/lib_ethernet/src/client_state.xc @@ -6,7 +6,7 @@ void init_rx_client_state(rx_client_state_t client_state[n], unsigned n) { for (unsigned i = 0; i < n; i ++) { client_state[i].dropped_pkt_cnt = 0; - for(int p=0; p 1) && !defined(DISABLE_ETHERNET_PORT_FORWARDING) - buf->forwarding = 0; -#endif - if (end_ptr > info->last_safe_wrptr) end_ptr = info->start; diff --git a/lib_ethernet/src/rmii_ethernet_rt_mac.xc b/lib_ethernet/src/rmii_ethernet_rt_mac.xc index 2ea11708..e2aab914 100644 --- a/lib_ethernet/src/rmii_ethernet_rt_mac.xc +++ b/lib_ethernet/src/rmii_ethernet_rt_mac.xc @@ -317,7 +317,7 @@ void rmii_ethernet_rt_mac(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), stati } // unsafe block } -#if (NUM_ETHERNET_PORTS == 2) + void rmii_ethernet_rt_mac_dual(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), static_const_unsigned_t n_cfg, SERVER_INTERFACE(ethernet_rx_if, i_rx_lp[n_rx_lp]), static_const_unsigned_t n_rx_lp, SERVER_INTERFACE(ethernet_tx_if, i_tx_lp[n_tx_lp]), static_const_unsigned_t n_tx_lp, @@ -339,11 +339,11 @@ void rmii_ethernet_rt_mac_dual(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), // Establish types of data ports presented unsafe{ // Setup buffering - unsigned int rx_data[rx_bufsize_words ][NUM_ETHERNET_PORTS]; - unsigned int tx_data[tx_bufsize_words][NUM_ETHERNET_PORTS]; - mii_mempool_t rx_mem[NUM_ETHERNET_PORTS]; + unsigned int rx_data[rx_bufsize_words ][2]; + unsigned int tx_data[tx_bufsize_words][2]; + mii_mempool_t rx_mem[2]; mii_mempool_t * unsafe rx_mem_ptr = (mii_mempool_t *)rx_mem; - for(int i=0; i MII_TIMESTAMP_QUEUE_MAX_SIZE) { fail("Exceeded maximum number of transmit clients. Increase MII_TIMESTAMP_QUEUE_MAX_SIZE in ethernet_conf.h"); @@ -398,7 +398,7 @@ void rmii_ethernet_rt_mac_dual(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), fail("Using high priority channels without #define ETHERNET_SUPPORT_HP_QUEUES set true"); } - for(int i=0; i Date: Wed, 22 Jan 2025 11:55:03 +0000 Subject: [PATCH 24/25] Removed examples/test_rmii_dual --- examples/test_rmii_dual/CMakeLists.txt | 29 --- examples/test_rmii_dual/do_sim.sh | 8 - .../test_rmii_dual/src/XCORE-AI-EXPLORER.xn | 75 ------ examples/test_rmii_dual/src/config.xscope | 2 - examples/test_rmii_dual/src/main.xc | 216 ------------------ lib_ethernet/src/default_ethernet_conf.h | 2 +- tests/test_4_2_6.py | 2 +- tests/test_rmii_restart.py | 2 +- 8 files changed, 3 insertions(+), 333 deletions(-) delete mode 100644 examples/test_rmii_dual/CMakeLists.txt delete mode 100644 examples/test_rmii_dual/do_sim.sh delete mode 100644 examples/test_rmii_dual/src/XCORE-AI-EXPLORER.xn delete mode 100644 examples/test_rmii_dual/src/config.xscope delete mode 100644 examples/test_rmii_dual/src/main.xc diff --git a/examples/test_rmii_dual/CMakeLists.txt b/examples/test_rmii_dual/CMakeLists.txt deleted file mode 100644 index 0a134946..00000000 --- a/examples/test_rmii_dual/CMakeLists.txt +++ /dev/null @@ -1,29 +0,0 @@ -cmake_minimum_required(VERSION 3.21) -include($ENV{XMOS_CMAKE_PATH}/xcommon.cmake) -project(test_rmii_dual) - -set(APP_HW_TARGET src/XCORE-AI-EXPLORER.xn) - -include(${CMAKE_CURRENT_LIST_DIR}/../deps.cmake) - -set(APP_PCA_ENABLE ON) - -set(COMPILER_FLAGS_COMMON -g - -report - -DDEBUG_PRINT_ENABLE=1 - -DETHERNET_SUPPORT_HP_QUEUES=1 - -Wno-unused-function - ) - - -set(APP_COMPILER_FLAGS_tx4b_rx4b ${COMPILER_FLAGS_COMMON} -DTX_WIDTH=4 -DRX_WIDTH=4) -set(APP_COMPILER_FLAGS_tx4b_rx4b_upper ${COMPILER_FLAGS_COMMON} -DTX_WIDTH=4 -DRX_WIDTH=4 -DUSE_LOWER=0) -set(APP_COMPILER_FLAGS_tx1b_rx4b ${COMPILER_FLAGS_COMMON} -DTX_WIDTH=1 -DRX_WIDTH=4) -set(APP_COMPILER_FLAGS_tx4b_rx1b ${COMPILER_FLAGS_COMMON} -DTX_WIDTH=4 -DRX_WIDTH=1) -set(APP_COMPILER_FLAGS_tx1b_rx1b ${COMPILER_FLAGS_COMMON} -DTX_WIDTH=1 -DRX_WIDTH=1) - -set(APP_XSCOPE_SRCS src/config.xscope) - -set(XMOS_SANDBOX_DIR ${CMAKE_CURRENT_LIST_DIR}/../../..) - -XMOS_REGISTER_APP() diff --git a/examples/test_rmii_dual/do_sim.sh b/examples/test_rmii_dual/do_sim.sh deleted file mode 100644 index 8a50a872..00000000 --- a/examples/test_rmii_dual/do_sim.sh +++ /dev/null @@ -1,8 +0,0 @@ -xsim bin/tx4b_rx4b/test_rmii_dual_tx4b_rx4b.xe --max-cycles 1000000 \ - --trace-plugin VcdPlugin.dll '-tile tile[0] -o trace.vcd -xe bin/tx4b_rx4b/test_rmii_dual_tx4b_rx4b.xe -ports -ports-detailed -cores -instructions -clock-blocks' \ - --plugin LoopbackPort.dll '-port tile[0] XS1_PORT_1O 1 0 -port tile[0] XS1_PORT_1N 1 0' \ - --plugin LoopbackPort.dll '-port tile[0] XS1_PORT_4A 4 0 -port tile[0] XS1_PORT_4B 4 0' \ - --plugin LoopbackPort.dll '-port tile[0] XS1_PORT_1K 1 0 -port tile[0] XS1_PORT_1L 1 0' \ - # --plugin LoopbackPort.dll '-port tile[0] XS1_PORT_1J 1 0 -port tile[0] XS1_PORT_1M 1 0' \ - # --plugin LoopbackPort.dll '-port tile[0] XS1_PORT_4C 4 0 -port tile[0] XS1_PORT_4D 4 0' \ - --trace-to trace.txt \ No newline at end of file diff --git a/examples/test_rmii_dual/src/XCORE-AI-EXPLORER.xn b/examples/test_rmii_dual/src/XCORE-AI-EXPLORER.xn deleted file mode 100644 index f46d00cb..00000000 --- a/examples/test_rmii_dual/src/XCORE-AI-EXPLORER.xn +++ /dev/null @@ -1,75 +0,0 @@ - - - Board - xcore.ai Explorer Kit - - - tileref tile[2] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/test_rmii_dual/src/config.xscope b/examples/test_rmii_dual/src/config.xscope deleted file mode 100644 index 5c4b0f67..00000000 --- a/examples/test_rmii_dual/src/config.xscope +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/examples/test_rmii_dual/src/main.xc b/examples/test_rmii_dual/src/main.xc deleted file mode 100644 index d1610d33..00000000 --- a/examples/test_rmii_dual/src/main.xc +++ /dev/null @@ -1,216 +0,0 @@ -// Copyright 2024-2025 XMOS LIMITED. -// This Software is subject to the terms of the XMOS Public Licence: Version 1. -#include -#include -#include -#include -#include -#include -#include "ethernet.h" - -port p_eth_clk = XS1_PORT_1O; - -#ifndef USE_LOWER -#define USE_LOWER 1 -#endif - -#if TX_WIDTH == 4 -#if USE_LOWER -rmii_data_port_t p_eth_txd_0 = {{XS1_PORT_4B, USE_LOWER_2B}}; -rmii_data_port_t p_eth_txd_1 = {{XS1_PORT_4D, USE_LOWER_2B}}; -#else -rmii_data_port_t p_eth_txd_0 = {{XS1_PORT_4B, USE_UPPER_2B}}; -rmii_data_port_t p_eth_txd_1 = {{XS1_PORT_4D, USE_UPPER_2B}}; -#endif -#elif TX_WIDTH == 1 -rmii_data_port_t p_eth_txd_0 = {{XS1_PORT_1C, XS1_PORT_1D}}; -rmii_data_port_t p_eth_txd_1 = {{XS1_PORT_1E, XS1_PORT_1F}}; -#else -#error invalid TX_WIDTH -#endif - -#if RX_WIDTH == 4 -#if USE_LOWER -rmii_data_port_t p_eth_rxd_0 = {{XS1_PORT_4A, USE_LOWER_2B}}; -rmii_data_port_t p_eth_rxd_1 = {{XS1_PORT_4C, USE_LOWER_2B}}; -#else -rmii_data_port_t p_eth_rxd_0 = {{XS1_PORT_4A, USE_UPPER_2B}}; -rmii_data_port_t p_eth_rxd_1 = {{XS1_PORT_4C, USE_UPPER_2B}}; -#endif -#elif RX_WIDTH == 1 -rmii_data_port_t p_eth_rxd_0 = {{XS1_PORT_1A, XS1_PORT_1B}}; -rmii_data_port_t p_eth_rxd_1 = {{XS1_PORT_1H, XS1_PORT_1I}}; -#else -#error invalid RX_WIDTH -#endif - -port p_eth_rxdv_0 = XS1_PORT_1K; -port p_eth_rxdv_1 = XS1_PORT_1J; -port p_eth_txen_0 = XS1_PORT_1L; -port p_eth_txen_1 = XS1_PORT_1M; -clock eth_rxclk_0 = XS1_CLKBLK_1; -clock eth_txclk_0 = XS1_CLKBLK_2; -clock eth_rxclk_1 = XS1_CLKBLK_3; -clock eth_txclk_1 = XS1_CLKBLK_4; - - -// Test harness -clock eth_clk_harness = XS1_CLKBLK_5; -port p_eth_clk_harness = XS1_PORT_1N; - -#define MAX_PACKET_WORDS ((ETHERNET_MAX_PACKET_SIZE + 3) / 4) - -#define VLAN_TAGGED 1 - -#define MII_CREDIT_FRACTIONAL_BITS 16 - -static int calc_idle_slope(int bps) -{ - long long slope = ((long long) bps) << (MII_CREDIT_FRACTIONAL_BITS); - slope = slope / 100000000; // bits that should be sent per ref timer tick - - return (int) slope; -} - -static void printbytes(char *b, int n){ - for(int i=0; i> 32; - printhex(b[i]); printstr(", 0x");printhex(p0_val); printstr(", 0x");printhexln(p1_val); - } - printstr("\n"); -} - - - -void test_app(client ethernet_cfg_if i_cfg, - client ethernet_rx_if i_rx, - streaming chanend c_rx_hp, - client ethernet_tx_if tx_lp, - streaming chanend c_tx_hp) -{ - // Request 5Mbits/sec - i_cfg.set_egress_qav_idle_slope(0, calc_idle_slope(5 * 1024 * 1024)); - - unsigned tx_data[MAX_PACKET_WORDS]; - for (size_t i = 0; i < MAX_PACKET_WORDS; i++) { - tx_data[i] = i; - } - - // src/dst MAC addresses - size_t j = 0; - for (; j < 12; j++) - ((char*)tx_data)[j] = j; - - if (VLAN_TAGGED) { - ((char*)tx_data)[j++] = 0x81; - ((char*)tx_data)[j++] = 0x00; - ((char*)tx_data)[j++] = 0x00; - ((char*)tx_data)[j++] = 0x00; - } - - const int length = 61; - const int header_bytes = VLAN_TAGGED ? 18 : 14; - ((char*)tx_data)[j++] = (length - header_bytes) >> 8; - ((char*)tx_data)[j++] = (length - header_bytes) & 0xff; - - timer tmr_tx; - int time_tx_trig; - tmr_tx :> time_tx_trig; - - int start_length = 80; - - - ethernet_macaddr_filter_t macaddr_filter; - size_t index = i_rx.get_index(); - for (int i = 0; i < MACADDR_NUM_BYTES; i++) { - macaddr_filter.addr[i] = i; - } - i_cfg.add_macaddr_filter(index, 1, macaddr_filter); - - while (1) { - uint8_t rxbuf[ETHERNET_MAX_PACKET_SIZE]; - ethernet_packet_info_t packet_info; - printstr("select\n"); - - select { - case ethernet_receive_hp_packet(c_rx_hp, rxbuf, packet_info): - printf("HP packet received: %d bytes\n", packet_info.len); - // printbytes(rxbuf, packet_info.len); - break; - - case i_rx.packet_ready(): - unsigned n; - i_rx.get_packet(packet_info, rxbuf, n); - printf("LP packet received: %d bytes\n", n); - // printbytes(rxbuf, packet_info.len); - break; - - case tmr_tx when timerafter(time_tx_trig) :> time_tx_trig: - printf("TX sending: %d\n", start_length); - // printbytes((char*)data, length); - // printwords_4b(data, (length + 3)/4); - tx_lp.send_packet((char *)tx_data, start_length, ETHERNET_ALL_INTERFACES); - start_length++; - time_tx_trig += 6000; - break; - } - } -} - - -int main() -{ - ethernet_cfg_if i_cfg[1]; - ethernet_rx_if i_rx_lp[1]; - ethernet_tx_if i_tx_lp[1]; - streaming chan c_rx_hp; - streaming chan c_tx_hp; - - - // Setup 50M clock - unsigned divider = 2; // 100 / 2 = 50; - configure_clock_ref(eth_clk_harness, divider / 2); - set_port_clock(p_eth_clk_harness, eth_clk_harness); - set_port_mode_clock(p_eth_clk_harness); - start_clock(eth_clk_harness); - - par { - unsafe{rmii_ethernet_rt_mac_dual(i_cfg, 1, - i_rx_lp, 1, - i_tx_lp, 1, - c_rx_hp, c_tx_hp, - p_eth_clk, - &p_eth_rxd_0, p_eth_rxdv_0, - p_eth_txen_0, &p_eth_txd_0, - eth_rxclk_0, eth_txclk_0, - &p_eth_rxd_1, p_eth_rxdv_1, - p_eth_txen_1, &p_eth_txd_1, - eth_rxclk_1, eth_txclk_1, - 4000, 4000, ETHERNET_ENABLE_SHAPER);} - - test_app(i_cfg[0], i_rx_lp[0], c_rx_hp, i_tx_lp[0], c_tx_hp); - } - - return 0; -} diff --git a/lib_ethernet/src/default_ethernet_conf.h b/lib_ethernet/src/default_ethernet_conf.h index 4e70577f..a6faa611 100644 --- a/lib_ethernet/src/default_ethernet_conf.h +++ b/lib_ethernet/src/default_ethernet_conf.h @@ -76,7 +76,7 @@ #endif #ifndef MAX_ETHERNET_PORTS -#define MAX_ETHERNET_PORTS (1) +#define MAX_ETHERNET_PORTS (2) #endif #endif // __default_ethernet_conf_h__ diff --git a/tests/test_4_2_6.py b/tests/test_4_2_6.py index 46081b66..633132f4 100644 --- a/tests/test_4_2_6.py +++ b/tests/test_4_2_6.py @@ -38,7 +38,7 @@ def do_test(capfd, mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, seed, rx_width=Non # Test shrinking the IFG by different amounts. Use the shrink as the step for debug purposes if tx_phy.get_name() == "rmii": - gap_shrink_list = [5] + gap_shrink_list = [3] else: gap_shrink_list = [5, 10] diff --git a/tests/test_rmii_restart.py b/tests/test_rmii_restart.py index 6664e53d..09a4128e 100644 --- a/tests/test_rmii_restart.py +++ b/tests/test_rmii_restart.py @@ -50,7 +50,7 @@ def do_test(capfd, mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, seed, rx_width=Non if cycle == 0: ifg = 2000 * tx_clk.get_bit_time() # Wait for MAC to restart a few times else: - ifg = 7000 * tx_clk.get_bit_time() # Wait for forwarding completion and a restart + ifg = 9000 * tx_clk.get_bit_time() # Wait for forwarding completion and a restart else: ifg = 96 * tx_clk.get_bit_time() # Min eth spec IFG between packets packets.append(MiiPacket(rand, From 50230da7ce8814b96ea3056af415ed734d18c8d7 Mon Sep 17 00:00:00 2001 From: Shuchita Khare Date: Thu, 23 Jan 2025 16:16:26 +0000 Subject: [PATCH 25/25] review comments --- lib_ethernet/src/mii_buffering.c | 8 -------- lib_ethernet/src/mii_buffering.h | 1 - lib_ethernet/src/mii_ethernet_rt_mac.xc | 2 +- lib_ethernet/src/rmii_ethernet_rt_mac.xc | 2 +- tests/helpers.py | 4 ++++ tests/test_link_status/src/main.xc | 6 +++--- 6 files changed, 9 insertions(+), 14 deletions(-) diff --git a/lib_ethernet/src/mii_buffering.c b/lib_ethernet/src/mii_buffering.c index 95545653..2730012d 100644 --- a/lib_ethernet/src/mii_buffering.c +++ b/lib_ethernet/src/mii_buffering.c @@ -60,14 +60,6 @@ void mii_init_packet_queue(mii_packet_queue_t queue) memset(info->ptrs, 0, sizeof(info->ptrs)); } -void mii_init_packet_queue_new(packet_queue_info_t *queue) -{ - packet_queue_info_t *info = (packet_queue_info_t *)queue; - info->rd_index = 0; - info->wr_index = 0; - memset(info->ptrs, 0, sizeof(info->ptrs)); -} - mii_mempool_t mii_init_mempool(unsigned *buf, int size) { if (size < 4) diff --git a/lib_ethernet/src/mii_buffering.h b/lib_ethernet/src/mii_buffering.h index c40ffba7..5895bfb3 100644 --- a/lib_ethernet/src/mii_buffering.h +++ b/lib_ethernet/src/mii_buffering.h @@ -92,7 +92,6 @@ typedef unsigned * mii_rdptr_t; typedef unsigned * mii_packet_queue_t; void mii_init_packet_queue(mii_packet_queue_t queue); -void mii_init_packet_queue_new(packet_queue_info_t *queue); mii_mempool_t mii_init_mempool(unsigned *buffer, int size); void mii_init_lock(); diff --git a/lib_ethernet/src/mii_ethernet_rt_mac.xc b/lib_ethernet/src/mii_ethernet_rt_mac.xc index d4b8f34b..6c139e5f 100644 --- a/lib_ethernet/src/mii_ethernet_rt_mac.xc +++ b/lib_ethernet/src/mii_ethernet_rt_mac.xc @@ -161,7 +161,7 @@ unsafe static void handle_incoming_hp_packets(mii_mempool_t rxmem, int client_wants_packet = 0; if (buf->filter_result && ethernet_filter_result_is_hp(buf->filter_result)) { - client_wants_packet = (buf->filter_result & 1); // there's only one hp client?? + client_wants_packet = (buf->filter_result & 1); // there's only one hp client } if (client_wants_packet) diff --git a/lib_ethernet/src/rmii_ethernet_rt_mac.xc b/lib_ethernet/src/rmii_ethernet_rt_mac.xc index e2aab914..e415508b 100644 --- a/lib_ethernet/src/rmii_ethernet_rt_mac.xc +++ b/lib_ethernet/src/rmii_ethernet_rt_mac.xc @@ -345,7 +345,7 @@ void rmii_ethernet_rt_mac_dual(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), mii_mempool_t * unsafe rx_mem_ptr = (mii_mempool_t *)rx_mem; for(int i=0; i<2; i++) { - rx_mem[i] = mii_init_mempool(&rx_data[0][0] + i*tx_bufsize_words, rx_bufsize_words*4); + rx_mem[i] = mii_init_mempool(&rx_data[0][0] + i*rx_bufsize_words, rx_bufsize_words*4); } // If the high priority traffic is connected then allocate half the buffer for high priority diff --git a/tests/helpers.py b/tests/helpers.py index be63478c..d39044b0 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -186,6 +186,10 @@ def do_rx_test(capfd, mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, test_f def create_expect(packets, filename): """ Create the expect file for what packets should be reported by the DUT """ + # Check if the packet array is one or 2 dimensional. + # ndim=1 means its an array of packets, all meant for a single ethernet port + # ndim=2 means, its a 2D array of form [num ehthernet ports][packets for a given port] + # Anything other than 1 or 2 is unexpected and should be flagged. ndim = np.array(packets).ndim with open(filename, 'w') as f: if ndim == 1: diff --git a/tests/test_link_status/src/main.xc b/tests/test_link_status/src/main.xc index 69bb7963..0263d85e 100644 --- a/tests/test_link_status/src/main.xc +++ b/tests/test_link_status/src/main.xc @@ -50,13 +50,13 @@ void test_link_status(client ethernet_cfg_if cfg, size_t index = rx.get_index(); - index = 0; // This is the mac port index and not the client index + unsigned mac_index = 0; // This is the mac port index and not the client index - cfg.enable_link_status_notification(index); + cfg.enable_link_status_notification(mac_index); int events_expected = 4; while (events_expected) { - c <: index; + c <: mac_index; select { case rx.packet_ready():