diff --git a/Jenkinsfile b/Jenkinsfile index ba1948cd..201474e3 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -248,4 +248,4 @@ pipeline { } } } // stages -} // pipeline +} // pipeline \ No newline at end of file diff --git a/doc/rst/lib_ethernet.rst b/doc/rst/lib_ethernet.rst index 8edc0cbc..84679ead 100644 --- a/doc/rst/lib_ethernet.rst +++ b/doc/rst/lib_ethernet.rst @@ -1041,7 +1041,7 @@ Real-time Ethernet MAC supporting typedefs .. doxygenenum:: ethernet_enable_shaper_t .. doxygenstruct:: rmii_port_timing_t -.. doxygenenum:: rmii_data_4b_pin_assignment_t +.. doxygenenum:: rmii_data_pin_assignment_t |newpage| diff --git a/examples/app_ethernet_diagnostics/src/main.xc b/examples/app_ethernet_diagnostics/src/main.xc index 5e68d6a0..5eb21c6c 100644 --- a/examples/app_ethernet_diagnostics/src/main.xc +++ b/examples/app_ethernet_diagnostics/src/main.xc @@ -27,7 +27,6 @@ port p_phy_clk = RMII_PHY_CLK_50M; clock phy_rxclk = on tile[0]: XS1_CLKBLK_1; clock phy_txclk = on tile[0]: XS1_CLKBLK_2; - // An enum to manage the array of connections from the ethernet component to its clients. enum eth_clients { ETH_TO_TRAFFIC, diff --git a/lib_ethernet/api/ethernet.h b/lib_ethernet/api/ethernet.h index fbbd9168..80c0ea64 100644 --- a/lib_ethernet/api/ethernet.h +++ b/lib_ethernet/api/ethernet.h @@ -199,8 +199,6 @@ typedef interface ethernet_cfg_if { * * \param ifnum The index of the MAC interface to set the slope (always 0) * \param slope The slope value in bits per 100 MHz ref timer tick in MII_CREDIT_FRACTIONAL_BITS Q format. - * - * */ void set_egress_qav_idle_slope(size_t ifnum, unsigned slope); @@ -209,8 +207,6 @@ typedef interface ethernet_cfg_if { * * \param ifnum The index of the MAC interface to set the slope (always 0) * \param bits_per_second The maximum number of bits per second to be set - * - * */ void set_egress_qav_idle_slope_bps(size_t ifnum, unsigned bits_per_second); @@ -663,11 +659,16 @@ 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 * 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 unused input bits are ignored. For Tx, the unused pins are always driven low. */ -typedef enum rmii_data_4b_pin_assignment_t{ + * port cannot be used. For Rx the input values are ignored. For Tx, the unused pins are always driven low. */ +typedef enum rmii_data_pin_assignment_t{ USE_LOWER_2B = 0, /**< Use bit 0 and bit 1 of the four bit port for data bits 0 and 1*/ USE_UPPER_2B = 1 /**< Use bit 2 and bit 3 of the four bit port for data bits 0 and 1*/ -} rmii_data_4b_pin_assignment_t; +} rmii_data_pin_assignment_t; + + +/** Macro to populate which bits of the 8b port are used in the initialiser. Unused bits are driven low. */ +#define RMII_8B_PINS_INITIALISER(pos_0, pos_1) ((unsigned)pos_0 | ((unsigned)pos_1) << 16) + /** Struct containing the clock delay settings for the Rx and Tx pins. This is needed to adjust * port timings to ensure that the data is captured with sufficient setup and hold margin. @@ -708,13 +709,16 @@ typedef struct rmii_port_timing_t{ * \param rx_pin_map Which pins to use in 4 bit case. USE_LOWER_2B or USE_HIGHER_2B. Ignored if 1 bit ports used. * \param p_rxdv RMII RX data valid port * \param p_txen RMII TX enable port - * \param p_txd_0 Port for data bit 0 (1 bit option) or entire port (4 bit option) + * \param p_txd_0 Port for data bit 0 (1 bit option) or entire port (4 or 8 bit option) * \param p_txd_1 Port for data bit 1 (1 bit option). Pass null if unused. * \param tx_pin_map Which pins to use in 4 bit case. USE_LOWER_2B or USE_HIGHER_2B. Ignored if 1 bit ports used. + * In the case of 8b port usage, the lower 16b word holds the position of the data bit 0 and + * the upper 16b word holds the position of data bit 1. Values 0..7 are valid. You can use the + * RMII_8B_PINS_INITIALISER(pos_0, pos_1) macro to initialise this value. * \param rxclk Clock used for RMII receive timing * \param txclk Clock used for RMII transmit timing * \param port_timing Struct used for initialising the clock blocks to ensure setup and hold times are met - * + * * \param rx_bufsize_words The number of words to used for a receive buffer. * This should be at least 500 long words. * \param tx_bufsize_words The number of words to used for a transmit buffer. @@ -730,10 +734,10 @@ void rmii_ethernet_rt_mac(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), stati nullable_streaming_chanend_t c_rx_hp, nullable_streaming_chanend_t c_tx_hp, in_port_t p_clk, - port p_rxd_0, NULLABLE_RESOURCE(port, p_rxd_1), rmii_data_4b_pin_assignment_t rx_pin_map, + port p_rxd_0, NULLABLE_RESOURCE(port, p_rxd_1), rmii_data_pin_assignment_t rx_pin_map, in_port_t p_rxdv, out_port_t p_txen, - port p_txd_0, NULLABLE_RESOURCE(port, p_txd_1), rmii_data_4b_pin_assignment_t tx_pin_map, + port p_txd_0, NULLABLE_RESOURCE(port, p_txd_1), rmii_data_pin_assignment_t tx_pin_map, clock rxclk, clock txclk, rmii_port_timing_t port_timing, diff --git a/lib_ethernet/src/mii_ethernet_rt_mac.xc b/lib_ethernet/src/mii_ethernet_rt_mac.xc index 793a2468..dcfcca5a 100644 --- a/lib_ethernet/src/mii_ethernet_rt_mac.xc +++ b/lib_ethernet/src/mii_ethernet_rt_mac.xc @@ -437,7 +437,7 @@ unsafe void mii_ethernet_server(mii_mempool_t 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; // div by 10 to get to timer ticks from nanonseconds + p_port_state->ingress_ts_latency[speed] = value / 10; // div by 10 to get to timer ticks from nanonseconds break; } diff --git a/lib_ethernet/src/rmii_ethernet_rt_mac.xc b/lib_ethernet/src/rmii_ethernet_rt_mac.xc index 81b52369..32fa9b35 100644 --- a/lib_ethernet/src/rmii_ethernet_rt_mac.xc +++ b/lib_ethernet/src/rmii_ethernet_rt_mac.xc @@ -45,10 +45,10 @@ void rmii_ethernet_rt_mac(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), stati nullable_streaming_chanend_t c_rx_hp, nullable_streaming_chanend_t c_tx_hp, in_port_t p_clk, - port p_rxd_0, NULLABLE_RESOURCE(port, p_rxd_1), rmii_data_4b_pin_assignment_t rx_pin_map, + port p_rxd_0, NULLABLE_RESOURCE(port, p_rxd_1), rmii_data_pin_assignment_t rx_pin_map, in_port_t p_rxdv, out_port_t p_txen, - port p_txd_0, NULLABLE_RESOURCE(port, p_txd_1), rmii_data_4b_pin_assignment_t tx_pin_map, + port p_txd_0, NULLABLE_RESOURCE(port, p_txd_1), rmii_data_pin_assignment_t tx_pin_map, clock rxclk, clock txclk, rmii_port_timing_t port_timing, @@ -130,12 +130,14 @@ void rmii_ethernet_rt_mac(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), stati out buffered port:32 * unsafe tx_data_0 = NULL; out buffered port:32 * unsafe tx_data_1 = NULL; + // Extract port info unsigned tx_port_width = ((unsigned)(p_txd_0) >> 16) & 0xff; switch(tx_port_width){ + case 8: case 4: tx_data_0 = enable_buffered_out_port((unsigned*)(&p_txd_0), 32); - rmii_master_init_tx_4b(p_clk, tx_data_0, p_txen, txclk, port_timing); + rmii_master_init_tx_4b_8b(p_clk, tx_data_0, p_txen, txclk, port_timing); break; case 1: tx_data_0 = enable_buffered_out_port((unsigned*)&p_txd_0, 32); diff --git a/lib_ethernet/src/rmii_master.h b/lib_ethernet/src/rmii_master.h index 5d6574ce..ec62aa40 100644 --- a/lib_ethernet/src/rmii_master.h +++ b/lib_ethernet/src/rmii_master.h @@ -21,11 +21,11 @@ unsafe void rmii_master_init_rx_1b( in port p_clk, clock rxclk, rmii_port_timing_t port_timing); -unsafe void rmii_master_init_tx_4b( in port p_clk, - out buffered port:32 * unsafe tx_data, - out port p_txen, - clock txclk, - rmii_port_timing_t port_timing); +unsafe void rmii_master_init_tx_4b_8b( in port p_clk, + out buffered port:32 * unsafe tx_data, + out port p_txen, + clock txclk, + rmii_port_timing_t port_timing); unsafe void rmii_master_init_tx_1b( in port p_clk, out buffered port:32 * unsafe tx_data_0, @@ -39,7 +39,7 @@ unsafe void rmii_master_rx_pins_4b(mii_mempool_t rx_mem, unsigned * unsafe rdptr, in port p_mii_rxdv, in buffered port:32 * unsafe p_mii_rxd, - rmii_data_4b_pin_assignment_t rx_port_4b_pins, + rmii_data_pin_assignment_t rx_port_4b_pins, volatile int * unsafe running_flag_ptr, chanend c_rx_pins_exit); @@ -60,7 +60,7 @@ unsafe void rmii_master_tx_pins(mii_mempool_t tx_mem_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, + rmii_data_pin_assignment_t tx_port_pins, clock txclk, volatile ethernet_port_state_t * unsafe p_port_state, volatile int * unsafe running_flag_ptr); diff --git a/lib_ethernet/src/rmii_master.xc b/lib_ethernet/src/rmii_master.xc index 4ec35898..3db618ea 100644 --- a/lib_ethernet/src/rmii_master.xc +++ b/lib_ethernet/src/rmii_master.xc @@ -77,6 +77,12 @@ // So the RMII_ETHERNET_IFG_AS_REF_CLOCK_COUNT_4b is (96 + 30), and // RMII_ETHERNET_IFG_AS_REF_CLOCK_COUNT_4b is (96 + 62) for frames with no tail bytes and (96 + 38) for frames with tail bytes. + +// For 8b TXD port, 32 bits are output on the port, 8bits per 20ns RMII clock tick, so 4 ticks to output one 32 bit word. +// when the last OUT for the CRC word returns, there's 3 ticks before the last word goes from the transfer register to shift register +// and another 4 ticks before the full shift register is shifted out on the wire. So, a total of (3+4)*20ns = 140ns = 14 reference timer ticks +// between the last OUT for CRC word returning and the last bit shifted on the wire, which is when TX_EN goes low. + // Further, there's an adjustment needed due to the fact that // 1. The instruction that reads the timer is in fact the next instruction adter the out of the CRC word. // 2. There's a delay between the timer wait for the next packet and the preamble actually showing up on the wire (TX_EN goes high when the first bit shows up) @@ -94,6 +100,11 @@ #define RMII_ETHERNET_IFG_DELAY_ADJUSTMENT_1b (11) // In reference timer ticks #endif +#ifndef RMII_ETHERNET_IFG_DELAY_ADJUSTMENT_8b + #define RMII_ETHERNET_IFG_DELAY_ADJUSTMENT_8b (0) // In reference timer ticks +#endif + +#define RMII_ETHERNET_IFG_AS_REF_CLOCK_COUNT_8b (96 + 14 - RMII_ETHERNET_IFG_DELAY_ADJUSTMENT_8b) #define RMII_ETHERNET_IFG_AS_REF_CLOCK_COUNT_4b (96 + 30 - RMII_ETHERNET_IFG_DELAY_ADJUSTMENT_4b) #define RMII_ETHERNET_IFG_AS_REF_CLOCK_COUNT_1b_NO_TAIL_BYTES (96 + 62 - RMII_ETHERNET_IFG_DELAY_ADJUSTMENT_1b) #define RMII_ETHERNET_IFG_AS_REF_CLOCK_COUNT_1b_TAIL_BYTES (96 + 38 - RMII_ETHERNET_IFG_DELAY_ADJUSTMENT_1b) @@ -194,11 +205,11 @@ static void rmii_master_init_tx_common( in port p_clk, } -unsafe void rmii_master_init_tx_4b( in port p_clk, - out buffered port:32 * unsafe tx_data, - out port p_txen, - clock txclk, - rmii_port_timing_t port_timing){ +unsafe void rmii_master_init_tx_4b_8b(in port p_clk, + out buffered port:32 * unsafe tx_data, + out port p_txen, + clock txclk, + rmii_port_timing_t port_timing){ *tx_data <: 0; // Ensure lines are low sync(*tx_data); // And wait to empty. This ensures no spurious p_txen on init @@ -243,12 +254,12 @@ unsafe void rmii_master_init_tx_1b( in port p_clk, //////////////////////////////////////// RX //////////////////////////////////// unsigned receive_full_preamble_4b_with_select_asm(in port p_mii_rxdv, in buffered port:32 p_mii_rxd, - rmii_data_4b_pin_assignment_t rx_port_4b_pins); + rmii_data_pin_assignment_t rx_port_4b_pins); unsigned receive_full_preamble_4b_with_select(in port p_mii_rxdv, in buffered port:32 p_mii_rxd, - rmii_data_4b_pin_assignment_t rx_port_4b_pins) + rmii_data_pin_assignment_t rx_port_4b_pins) { unsigned crc = 0x9226F562; unsigned word2, word1; @@ -291,7 +302,7 @@ unsigned receive_full_preamble_4b_with_select(in port p_mii_rxdv, } static inline unsigned rx_word_4b(in buffered port:32 p_mii_rxd, - rmii_data_4b_pin_assignment_t rx_port_4b_pins){ + rmii_data_pin_assignment_t rx_port_4b_pins){ unsigned word1, word2; p_mii_rxd :> word1; p_mii_rxd :> word2; @@ -309,7 +320,7 @@ static inline unsigned rx_word_4b(in buffered port:32 p_mii_rxd, {int, unsigned, unsigned* unsafe} extern master_rx_pins_4b_body_asm( unsigned * unsafe dptr, in port p_mii_rxdv, in buffered port:32 p_mii_rxd, - rmii_data_4b_pin_assignment_t rx_port_4b_pins, + rmii_data_pin_assignment_t rx_port_4b_pins, unsigned * unsafe timestamp, unsigned * unsafe wrap_ptr, unsigned * unsafe write_end_ptr); @@ -319,7 +330,7 @@ static inline unsigned rx_word_4b(in buffered port:32 p_mii_rxd, {int, unsigned, unsigned* unsafe} master_rx_pins_4b_body( unsigned * unsafe dptr, in port p_mii_rxdv, in buffered port:32 p_mii_rxd, - rmii_data_4b_pin_assignment_t rx_port_4b_pins, + rmii_data_pin_assignment_t rx_port_4b_pins, unsigned * unsafe timestamp, unsigned * unsafe wrap_ptr, unsigned * unsafe write_end_ptr){ @@ -445,7 +456,7 @@ unsafe void rmii_master_rx_pins_4b( mii_mempool_t rx_mem, unsigned * unsafe rdptr, in port p_mii_rxdv, in buffered port:32 * unsafe p_mii_rxd, - rmii_data_4b_pin_assignment_t rx_port_4b_pins, + rmii_data_pin_assignment_t rx_port_4b_pins, volatile int * unsafe running_flag_ptr, chanend c_rx_pins_exit){ @@ -482,21 +493,21 @@ unsafe void rmii_master_rx_pins_4b( mii_mempool_t rx_mem, int num_rx_bytes; #if ETH_RX_4B_USE_ASM {num_rx_bytes, crc, dptr} = master_rx_pins_4b_body_asm(dptr, - p_mii_rxdv, - *p_mii_rxd, - rx_port_4b_pins, - (unsigned*)&buf->timestamp, - wrap_ptr, - end_ptr); + p_mii_rxdv, + *p_mii_rxd, + rx_port_4b_pins, + (unsigned*)&buf->timestamp, + wrap_ptr, + end_ptr); #else {num_rx_bytes, crc, dptr} = master_rx_pins_4b_body(dptr, - p_mii_rxdv, - *p_mii_rxd, - rx_port_4b_pins, - (unsigned*)&buf->timestamp, - wrap_ptr, - end_ptr); + p_mii_rxdv, + *p_mii_rxd, + rx_port_4b_pins, + (unsigned*)&buf->timestamp, + wrap_ptr, + end_ptr); #endif // Note: we don't store the last word since it contains the CRC and // we don't need it from this point on. Endin returns the number of bits of data in the port remaining. @@ -765,7 +776,7 @@ unsafe void rmii_master_rx_pins_1b( mii_mempool_t rx_mem, ///////////////////////////////////// TX ///////////////////////////////////////// static inline void tx_4b_word(out buffered port:32 p_mii_txd, unsigned word, - rmii_data_4b_pin_assignment_t tx_port_4b_pins){ + rmii_data_pin_assignment_t tx_port_4b_pins){ uint64_t zipped; if(tx_port_4b_pins == USE_LOWER_2B){ zipped = zip(0, word, 1); @@ -779,7 +790,7 @@ static inline void tx_4b_word(out buffered port:32 p_mii_txd, static inline void tx_4b_byte(out buffered port:32 p_mii_txd, unsigned word, - rmii_data_4b_pin_assignment_t tx_port_4b_pins){ + rmii_data_pin_assignment_t tx_port_4b_pins){ uint64_t zipped; if(tx_port_4b_pins == USE_LOWER_2B){ zipped = zip(0, word, 1); @@ -789,11 +800,71 @@ static inline void tx_4b_byte(out buffered port:32 p_mii_txd, partout(p_mii_txd, 16, zipped & 0xffffffff); } +void rmii_master_tx_pins_8b_asm(unsigned * unsafe dptr, + int byte_count, + out buffered port:32 p_mii_txd, + unsigned lookup_8b_tx[256], + unsigned poly, + unsigned * unsafe wrap_start_ptr, + int byte_count_wrapped); + +unsafe unsigned rmii_transmit_packet_8b(mii_mempool_t tx_mem, + mii_packet_t * unsafe buf, + out buffered port:32 p_mii_txd, + unsigned lookup_8b_tx[256], + hwtimer_t ifg_tmr, + unsigned &ifg_time, + unsigned last_frame_end_time) +{ + unsigned time; + const unsigned poly = 0xEDB88320; + unsigned * unsafe dptr = &buf->data[0]; + unsigned * unsafe wrap_ptr = mii_get_wrap_ptr(tx_mem);; + + // Check to see if we need to wrap or not + int first_chunk_size = buf->length; + int wrap_size = buf->length - ((int)wrap_ptr - (int)dptr); + wrap_size = wrap_size < 0 ? 0 : wrap_size; + + if(wrap_size > 0){ + first_chunk_size -= wrap_size; + wrap_ptr = (unsigned *)*wrap_ptr; // Dereference wrap pointer to get start of wrap memory + // printstrln("wrap_required"); + } + + if (!MII_TX_TIMESTAMP_END_OF_PACKET && buf->timestamp_id) { + ifg_tmr :> time; + } + + // Check that we are out of the inter-frame gap + unsigned now; + ifg_tmr :> now; + unsigned wait = check_if_ifg_wait_required(last_frame_end_time, ifg_time, now); + if(wait) + { + ifg_tmr when timerafter(ifg_time) :> ifg_time; + } + + // Tx all stuff incl preamble and CRC + if(buf->length > 5){ // The ASM always transmits at least 5 bytes. Less than that will break the + // timing on the very tight loops so check in XC before we get there. + rmii_master_tx_pins_8b_asm(dptr, first_chunk_size, p_mii_txd, lookup_8b_tx, poly, wrap_ptr, wrap_size); + } + + ifg_tmr :> ifg_time; + + if (MII_TX_TIMESTAMP_END_OF_PACKET && buf->timestamp_id) { + ifg_tmr :> time; + } + + return time; +} + unsafe unsigned rmii_transmit_packet_4b(mii_mempool_t tx_mem, mii_packet_t * unsafe buf, out buffered port:32 p_mii_txd, - rmii_data_4b_pin_assignment_t tx_port_4b_pins, + rmii_data_pin_assignment_t tx_port_4b_pins, hwtimer_t ifg_tmr, unsigned &ifg_time, unsigned last_frame_end_time) @@ -994,7 +1065,19 @@ unsafe unsigned rmii_transmit_packet_1b(mii_mempool_t tx_mem, return time; } - +static void init_8b_tx_lookup(unsigned lookup[], int bitpos_0, int bitpos_1){ + for(int i = 0; i < 256; i++){ + lookup[i] = 0; // All unused pins driven low + lookup[i] |= (i & 0x1) << (bitpos_0 + 0); + lookup[i] |= (i & 0x2) << (bitpos_1 - 1); + lookup[i] |= (i & 0x4) << (bitpos_0 + 6); + lookup[i] |= (i & 0x8) << (bitpos_1 + 5); + lookup[i] |= (i & 0x10) << (bitpos_0 + 12); + lookup[i] |= (i & 0x20) << (bitpos_1 + 11); + lookup[i] |= (i & 0x40) << (bitpos_0 + 18); + lookup[i] |= (i & 0x80) << (bitpos_1 + 17); + } +} unsafe void rmii_master_tx_pins(mii_mempool_t tx_mem_lp, mii_mempool_t tx_mem_hp, @@ -1004,14 +1087,11 @@ unsafe void rmii_master_tx_pins(mii_mempool_t tx_mem_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, + rmii_data_pin_assignment_t tx_port_pins, clock txclk, volatile ethernet_port_state_t * unsafe p_port_state, volatile int * unsafe running_flag_ptr){ - // Flag for readability and faster comparison - const unsigned use_4b = (tx_port_width == 4); - // Need one timer to be able to read at any time for the shaper timer credit_tmr; // And a second timer to be enforcing the IFG gap @@ -1022,6 +1102,15 @@ unsafe void rmii_master_tx_pins(mii_mempool_t tx_mem_lp, qav_state_t qav_state = {0, 0, 0}; // Set times and credit to zero so it can tx first frame unsigned enable_shaper = p_port_state->qav_shaper_enabled; + // Lookup table for 8b transmit case + unsigned lookup_8b_tx[256]; + unsigned bit_pos_0 = (unsigned)tx_port_pins & 0xffff; + unsigned bit_pos_1 = (unsigned)tx_port_pins >> 16; + if(tx_port_width == 8){ + //printf("bit_pos_0 = %d, bit_pos_1 = %d\n", bit_pos_0, bit_pos_1); + init_8b_tx_lookup(lookup_8b_tx, bit_pos_0, bit_pos_1); + } + if (!ETHERNET_SUPPORT_TRAFFIC_SHAPER) { enable_shaper = 0; } @@ -1058,20 +1147,31 @@ unsafe void rmii_master_tx_pins(mii_mempool_t tx_mem_lp, unsigned time; - if(use_4b) { - time = rmii_transmit_packet_4b(tx_mem, buf, *p_mii_txd_0, tx_port_4b_pins, ifg_tmr, ifg_time, eof_time); - eof_time = ifg_time; - ifg_time += RMII_ETHERNET_IFG_AS_REF_CLOCK_COUNT_4b; - } else { - time = rmii_transmit_packet_1b(tx_mem, buf, *p_mii_txd_0, *p_mii_txd_1, txclk, ifg_tmr, ifg_time, eof_time); - eof_time = ifg_time; - if((buf->length & 0x3)) - { - ifg_time += RMII_ETHERNET_IFG_AS_REF_CLOCK_COUNT_1b_TAIL_BYTES; - } - else - { - ifg_time += RMII_ETHERNET_IFG_AS_REF_CLOCK_COUNT_1b_NO_TAIL_BYTES; + switch(tx_port_width){ + case 8: { + time = rmii_transmit_packet_8b(tx_mem, buf, *p_mii_txd_0, lookup_8b_tx, ifg_tmr, ifg_time, eof_time); + eof_time = ifg_time; + ifg_time += RMII_ETHERNET_IFG_AS_REF_CLOCK_COUNT_8b; // TODO WORK ME OUT + break; + } + case 4: { + time = rmii_transmit_packet_4b(tx_mem, buf, *p_mii_txd_0, tx_port_pins, ifg_tmr, ifg_time, eof_time); + eof_time = ifg_time; + ifg_time += RMII_ETHERNET_IFG_AS_REF_CLOCK_COUNT_4b; + break; + } + case 1: { + time = rmii_transmit_packet_1b(tx_mem, buf, *p_mii_txd_0, *p_mii_txd_1, txclk, ifg_tmr, ifg_time, eof_time); + eof_time = ifg_time; + if((buf->length & 0x3)) + { + ifg_time += RMII_ETHERNET_IFG_AS_REF_CLOCK_COUNT_1b_TAIL_BYTES; + } + else + { + ifg_time += RMII_ETHERNET_IFG_AS_REF_CLOCK_COUNT_1b_NO_TAIL_BYTES; + } + break; } } #if PROBE_TX_TIMESTAMPS @@ -1080,8 +1180,6 @@ unsafe void rmii_master_tx_pins(mii_mempool_t tx_mem_lp, increment_tx_ts_queue_write_index(); #endif - - const int packet_is_high_priority = (p_ts_queue == null); if (enable_shaper && packet_is_high_priority) { shaper_do_send_slope(buf->length, &qav_state); diff --git a/lib_ethernet/src/rmii_master_tx_pins_8b.S b/lib_ethernet/src/rmii_master_tx_pins_8b.S new file mode 100644 index 00000000..dd5fae64 --- /dev/null +++ b/lib_ethernet/src/rmii_master_tx_pins_8b.S @@ -0,0 +1,186 @@ +// Copyright 2025 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + + .section .cp.rodata, "ac", @progbits + .align 4 +.cc_top tx8consts.data +preamble_first: + .word 0x55555555 +preamble_second: + .word 0xD5555555 +.cc_bottom tx8consts.data + +#include + +#define STACK_WORDS 6 + +//Call: void rmii_master_tx_pins_8b_asm(unsigned * unsafe dptr, +// int byte_count, +// out buffered port:32 p_mii_txd, +// unsigned lookup_8b_tx[256], +// unsigned poly, +// unsigned * unsafe wrap_start_ptr, +// int byte_count_wrapped); + +#define DPTR r0 +#define NUM_BYTES r1 +#define PORT_RES_ID r2 +#define LOOKUP r3 +#define POLY_PASSED_IN sp[STACK_WORDS+1] +#define WRAP_START_PTR_PASSED_IN sp[STACK_WORDS+2] +#define WRAP_SZ_PASSED_IN sp[STACK_WORDS+3] // 0 or positive set by callee +#define CRC r4 +#define POLY r5 +#define TMP1 r6 +#define TMP2 r7 +#define COUNTER r8 +#define TMP4 r9 +#define TMP3 r11 + + +.cc_top rmii_master_tx_pins_8b_asm.func, rmii_master_tx_pins_8b_asm + + +.globl rmii_master_tx_pins_8b_asm.nstackwords +.globl rmii_master_tx_pins_8b_asm.maxthreads +.globl rmii_master_tx_pins_8b_asm.maxtimers +.globl rmii_master_tx_pins_8b_asm.maxchanends +.globl rmii_master_tx_pins_8b_asm.maxsync +.type rmii_master_tx_pins_8b_asm, @function +.linkset rmii_master_tx_pins_8b_asm.locnoside, 0 +.linkset rmii_master_tx_pins_8b_asm.nstackwords, STACK_WORDS +.linkset rmii_master_tx_pins_8b_asm.maxchanends, 0 +.linkset rmii_master_tx_pins_8b_asm.maxtimers, 0 +.linkset rmii_master_tx_pins_8b_asm.maxthreads, 0 +.linkset rmii_master_tx_pins_8b_asm.maxsync, 0 + +.globl rmii_master_tx_pins_8b_asm + + .align 8 + .issue_mode dual +rmii_master_tx_pins_8b_asm: + DUALENTSP_lu6 STACK_WORDS + + std r4, r5, sp[0] // Save r4 and r5 + std r6, r7, sp[1] // Save r6 and r7 + std r8, r9, sp[2] // Save r8 and r9 + + // Load poly and init CRC + {ldw POLY, sp[STACK_WORDS+1]; ldc CRC, 0} + + +tx_8_first_preamble: + // First preamble + ldw TMP2, cp[preamble_first] // We could in theory DI this but if we try we are too far from the CP so get link error + mkmsk TMP1, 8 + and TMP3, TMP2, TMP1 + ldw TMP3, LOOKUP[TMP3] + out res[PORT_RES_ID], TMP3 + shr TMP2, TMP2, 8 + and TMP3, TMP2, TMP1 + ldw TMP3, LOOKUP[TMP3] + out res[PORT_RES_ID], TMP3 + shr TMP2, TMP2, 8 + and TMP3, TMP2, TMP1 + ldw TMP3, LOOKUP[TMP3] + out res[PORT_RES_ID], TMP3 + shr TMP2, TMP2, 8 + and TMP3, TMP2, TMP1 + ldw TMP3, LOOKUP[TMP3] + out res[PORT_RES_ID], TMP3 // Ideally get to next OUT 6 slots later + + // Do second preamble +tx_8_second_preamble: + ldw TMP2, cp[preamble_second] + and TMP3, TMP2, TMP1 + ldw TMP3, LOOKUP[TMP3] + out res[PORT_RES_ID], TMP3 + shr TMP2, TMP2, 8 + and TMP3, TMP2, TMP1 + ldw TMP3, LOOKUP[TMP3] + out res[PORT_RES_ID], TMP3 + shr TMP2, TMP2, 8 + and TMP3, TMP2, TMP1 + ldw TMP3, LOOKUP[TMP3] + out res[PORT_RES_ID], TMP3 + shr TMP2, TMP2, 8 + and TMP3, TMP2, TMP1 + ldw TMP3, LOOKUP[TMP3] + out res[PORT_RES_ID], TMP3 // Ideally get to loop OUT 6 slots later + +#define BYTE_TO_TX TMP1 +#define EXPANDED_WORD TMP3 +#define WRAP_SIZE TMP4 + + // Special case for first word because we need to NOT the data value for the CRC +tx_8_first_word: + {ldw TMP2, DPTR[0]; mkmsk TMP4, 8} + and BYTE_TO_TX, TMP2, TMP4 + ldw EXPANDED_WORD, LOOKUP[BYTE_TO_TX] + {out res[PORT_RES_ID], EXPANDED_WORD; shr TMP2, TMP2, 8} + and BYTE_TO_TX, TMP2, TMP4 + ldw EXPANDED_WORD, LOOKUP[BYTE_TO_TX] + {out res[PORT_RES_ID], EXPANDED_WORD; shr TMP2, TMP2, 8} + and BYTE_TO_TX, TMP2, TMP4 + ldw EXPANDED_WORD, LOOKUP[BYTE_TO_TX] + {out res[PORT_RES_ID], EXPANDED_WORD; shr TMP2, TMP2, 8} + {and BYTE_TO_TX, TMP2, TMP4; ldw TMP2, DPTR[0]} // Now reload the data word since it has been shifted away + {ldw EXPANDED_WORD, LOOKUP[BYTE_TO_TX]; not TMP2, TMP2} // Invert it + crc32 CRC, TMP2, POLY // And CRC it + {out res[PORT_RES_ID], EXPANDED_WORD; ldw WRAP_SIZE, WRAP_SZ_PASSED_IN} // Out final word and load in the wrap size + + +#define BREAK_LOOP TMP2 + + // Do main body +tx8_main_loop_init: + ldc COUNTER, 4 // We have already sent a word + {ld8u BYTE_TO_TX, DPTR[COUNTER]; add COUNTER, COUNTER, 1} // Load initial byte to tx + Inital increment + +tx8_main_loop: + {ldw EXPANDED_WORD, LOOKUP[BYTE_TO_TX]; eq BREAK_LOOP, COUNTER, NUM_BYTES} + crc8 CRC, BYTE_TO_TX, BYTE_TO_TX, POLY // This trashes BYTE_TO_TX with BYTE_TO_TX >> 8 but we don't care now + {out res[PORT_RES_ID], EXPANDED_WORD; ld8u BYTE_TO_TX, DPTR[COUNTER]} + {add COUNTER, COUNTER, 1; bf BREAK_LOOP, tx8_main_loop} + + // We take 7 slots to get to the next OUT - OK since we know TR and SR are full at the last OUT +tx_8_wrap_loop_check_and_init: + {bf WRAP_SIZE, tx8_crc; ldc COUNTER, 0} + ldw DPTR, WRAP_START_PTR_PASSED_IN + {ld8u BYTE_TO_TX, DPTR[COUNTER]; add COUNTER, COUNTER, 1} + +tx8_wrap_loop: + {ldw EXPANDED_WORD, LOOKUP[BYTE_TO_TX]; eq BREAK_LOOP, COUNTER, WRAP_SIZE} + crc8 CRC, BYTE_TO_TX, BYTE_TO_TX, POLY // This trashes BYTE_TO_TX with BYTE_TO_TX >> 8 but we don't care now + {out res[PORT_RES_ID], EXPANDED_WORD; ld8u BYTE_TO_TX, DPTR[COUNTER]} + {add COUNTER, COUNTER, 1; bf BREAK_LOOP, tx8_wrap_loop} + +tx8_crc: + // CRC. CRC gets shifted away but we don't care now + {mkmsk TMP1, 8; mkmsk TMP2, 32} // Load byte mask and 0xFFFFFFFF for final CRC calc + crc32 CRC, TMP2, POLY + and TMP3, CRC, TMP1 + ldw TMP3, LOOKUP[TMP3] + out res[PORT_RES_ID], TMP3 // Must get here 6 slots after last loop OUT, which we do + shr CRC, CRC, 8 + and TMP3, CRC, TMP1 + ldw TMP3, LOOKUP[TMP3] + out res[PORT_RES_ID], TMP3 + shr CRC, CRC, 8 + and TMP3, CRC, TMP1 + ldw TMP3, LOOKUP[TMP3] + out res[PORT_RES_ID], TMP3 + shr CRC, CRC, 8 + and TMP3, CRC, TMP1 + ldw TMP3, LOOKUP[TMP3] + out res[PORT_RES_ID], TMP3 + + ldd r4, r5, sp[0] + ldd r6, r7, sp[1] + ldd r8, r9, sp[2] + + retsp STACK_WORDS + + + +.cc_bottom rmii_master_tx_pins_8b_asm.func diff --git a/tests/bringup_xk_eth_xu316_dual_100m/src/icmp.h b/tests/bringup_xk_eth_xu316_dual_100m/src/icmp.h index 295c92a6..886890d2 100644 --- a/tests/bringup_xk_eth_xu316_dual_100m/src/icmp.h +++ b/tests/bringup_xk_eth_xu316_dual_100m/src/icmp.h @@ -4,7 +4,6 @@ #define __icmp_h__ #include - [[combinable]] void icmp_server(client ethernet_cfg_if cfg, client ethernet_rx_if rx, diff --git a/tests/bringup_xk_eth_xu316_dual_100m/src/main.xc b/tests/bringup_xk_eth_xu316_dual_100m/src/main.xc index 485e47da..958505d9 100644 --- a/tests/bringup_xk_eth_xu316_dual_100m/src/main.xc +++ b/tests/bringup_xk_eth_xu316_dual_100m/src/main.xc @@ -29,13 +29,13 @@ port p_phy0_clk = PHY_0_CLK_50M; // PHY 1 - Clock slave port p_phy1_rxd_0 = PHY_1_RXD_0; port p_phy1_rxd_1 = PHY_1_RXD_1; -#if PHY1_USE_8B +#if PHY1_8B_TX port p_phy1_txd_0 = PHY_1_TXD_8BIT; in port p_unused_0 = PHY_1_TXD_0; // set to Hi-Z in port p_unused_1 = PHY_1_TXD_1; #define TX8_BIT_0 6 #define TX8_BIT_1 7 - #define TX_PINS ((TX8_BIT_0 << 16) | (TX8_BIT_1)) + #define TX_PINS RMII_8B_PINS_INITIALISER(TX8_BIT_0, TX8_BIT_1) #define p_phy1_txd_1 null #else port p_phy1_txd_0 = PHY_1_TXD_0; @@ -133,7 +133,7 @@ int main() #if PHY1 { // If Tx pins for 8b and 1b commoned, then ensure unused ports are Hi-Z -#if PHY1_USE_8B +#if PHY1_8B_TX p_unused_0 :> void; p_unused_1 :> void; #else diff --git a/tests/helpers.cmake b/tests/helpers.cmake index 8d22a769..242f7d2c 100644 --- a/tests/helpers.cmake +++ b/tests/helpers.cmake @@ -23,7 +23,7 @@ macro(set_app_hw_target arch) set(APP_HW_TARGET ${target}) endmacro() -macro(set_app_tx_width tx_width) +macro(set_app_tx_width) if(tx_width STREQUAL "4b_lower") list(APPEND APP_COMPILER_FLAGS_${config} -DTX_WIDTH=4) list(APPEND APP_COMPILER_FLAGS_${config} -DTX_USE_LOWER_2B=1) @@ -32,6 +32,12 @@ macro(set_app_tx_width tx_width) list(APPEND APP_COMPILER_FLAGS_${config} -DTX_USE_UPPER_2B=1) elseif(tx_width STREQUAL "1b") list(APPEND APP_COMPILER_FLAGS_${config} -DTX_WIDTH=1) + elseif(tx_width MATCHES "^8b_") + string(REPLACE "_" ";" parts ${tx_width}) + list(GET parts 0 width) + list(GET parts 1 bit0_pos) + list(GET parts 2 bit1_pos) + list(APPEND APP_COMPILER_FLAGS_${config} -DTX_WIDTH=8 -DTX8_BIT_0=${bit0_pos} -DTX8_BIT_1=${bit1_pos}) endif() endmacro() diff --git a/tests/helpers.py b/tests/helpers.py index 41c2c75a..e244aaa6 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -343,6 +343,13 @@ def get_rmii_rx_phy(tx_width, clk, **kwargs): rx_rmii_phy = get_rmii_1b_port_rx_phy(clk, **kwargs ) + elif tx_width.startswith("8b_"): + bit0_pos = int(tx_width.split("_")[1]) + bit1_pos = int(tx_width.split("_")[2]) + rx_rmii_phy = get_rmii_8b_port_rx_phy(clk, + [bit0_pos, bit1_pos], + **kwargs + ) else: assert False, f"get_rmii_rx_phy(): Invalid tx_width {tx_width}" return rx_rmii_phy @@ -369,10 +376,15 @@ def get_rmii_1b_port_tx_phy(clk, **kwargs): return phy def get_rmii_4b_port_rx_phy(clk, txd_4b_port_pin_assignment, **kwargs): + assert txd_4b_port_pin_assignment in ["lower_2b", "upper_2b"], f"Invalid txd_4b_port_pin_assignment {txd_4b_port_pin_assignment}. Only 'lower_2b' and 'upper_2b' are supported" + if txd_4b_port_pin_assignment == "lower_2b": + bit_positions = [0,1] + else: + bit_positions = [2,3] phy = RMiiReceiver('tile[0]:XS1_PORT_4B', 'tile[0]:XS1_PORT_1L', clk, - txd_4b_port_pin_assignment=txd_4b_port_pin_assignment, + pin_assignment=bit_positions, **kwargs ) return phy @@ -385,3 +397,11 @@ def get_rmii_1b_port_rx_phy(clk, **kwargs): ) return phy +def get_rmii_8b_port_rx_phy(clk, bit_positions, **kwargs): + phy = RMiiReceiver('tile[0]:XS1_PORT_8C', + 'tile[0]:XS1_PORT_1L', + clk, + pin_assignment=bit_positions, + **kwargs + ) + return phy diff --git a/tests/include/ports_rmii.h b/tests/include/ports_rmii.h index a583a193..746252e6 100644 --- a/tests/include/ports_rmii.h +++ b/tests/include/ports_rmii.h @@ -10,7 +10,7 @@ #define RX_USE_UPPER_2B (0) #endif -#if (!defined TX_WIDTH || (TX_WIDTH != 4 && TX_WIDTH != 1)) +#if (!defined TX_WIDTH || (TX_WIDTH != 4 && TX_WIDTH != 1 && TX_WIDTH != 8)) #warning TX_WIDTH not defined. Setting default to TX_WIDTH = 4 and USE_LOWER_2B #define TX_WIDTH (4) #define TX_USE_LOWER_2B (1) @@ -44,28 +44,38 @@ port p_eth_rxd_1 = on tile[0]:XS1_PORT_1B; #if TX_WIDTH == 4 -#if ((TX_USE_LOWER_2B == 1) && (TX_USE_UPPER_2B == 1)) - #error Both TX_USE_LOWER_2B and TX_USE_UPPER_2B set -#endif + #if ((TX_USE_LOWER_2B == 1) && (TX_USE_UPPER_2B == 1)) + #error Both TX_USE_LOWER_2B and TX_USE_UPPER_2B set + #endif -#if ((TX_USE_LOWER_2B == 0) && (TX_USE_UPPER_2B == 0)) - #error Both TX_USE_LOWER_2B and TX_USE_UPPER_2B are 0 when TX_WIDTH is 4 -#endif + #if ((TX_USE_LOWER_2B == 0) && (TX_USE_UPPER_2B == 0)) + #error Both TX_USE_LOWER_2B and TX_USE_UPPER_2B are 0 when TX_WIDTH is 4 + #endif -port p_eth_txd_0 = on tile[0]:XS1_PORT_4B; -#define p_eth_txd_1 null -#if TX_USE_LOWER_2B - #define TX_PINS USE_LOWER_2B -#elif TX_USE_UPPER_2B - #define TX_PINS USE_UPPER_2B -#endif + port p_eth_txd_0 = on tile[0]:XS1_PORT_4B; + #define p_eth_txd_1 null + #if TX_USE_LOWER_2B + #define TX_PINS USE_LOWER_2B + #elif TX_USE_UPPER_2B + #define TX_PINS USE_UPPER_2B + #endif #elif TX_WIDTH == 1 -port p_eth_txd_0 = on tile[0]:XS1_PORT_1C; -port p_eth_txd_1 = on tile[0]:XS1_PORT_1D; -#define TX_PINS 0 + port p_eth_txd_0 = on tile[0]:XS1_PORT_1C; + port p_eth_txd_1 = on tile[0]:XS1_PORT_1D; + #define TX_PINS 0 +#elif TX_WIDTH == 8 + port p_eth_txd_0 = on tile[0]:XS1_PORT_8C; + #ifndef TX8_BIT_0 + #error TX8_BIT_0 not defined + #endif + #ifndef TX8_BIT_1 + #error TX8_BIT_1 not defined + #endif + #define TX_PINS RMII_8B_PINS_INITIALISER(TX8_BIT_0, TX8_BIT_1) + #define p_eth_txd_1 null #else -#error invalid TX_WIDTH + #error invalid TX_WIDTH #endif port p_eth_clk = on tile[0]: XS1_PORT_1J; diff --git a/tests/rmii_phy.py b/tests/rmii_phy.py index 3339397c..caa0903d 100644 --- a/tests/rmii_phy.py +++ b/tests/rmii_phy.py @@ -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, pin_assignment, print_packets, packet_fn, verbose, test_ctrl): self._name = name # Check if txd is a string or an array of strings if not isinstance(txd, (list, tuple)): @@ -262,7 +262,7 @@ def __init__(self, name, txd, txen, clock, txd_4b_port_pin_assignment, print_pac self._txd = txd self._txen = txen self._clock = clock - self._txd_4b_port_pin_assignment = txd_4b_port_pin_assignment + self._pin_assignment = pin_assignment self._print_packets = print_packets self._verbose = verbose self._test_ctrl = test_ctrl @@ -274,11 +274,11 @@ def __init__(self, name, txd, txen, clock, txd_4b_port_pin_assignment, print_pac port_width_check = get_port_width_from_name(self._txd[1]) assert self._txd_port_width == port_width_check, f"When specifying 2 ports, both need to be of width 1bit. {self._txd}" else: - assert self._txd_port_width == 4, f"Only 4bit port allowed when specifying only 1 port. {self._txd}" + assert self._txd_port_width in [4,8], f"Only 4bit or 8bit port allowed when specifying only 1 port. {self._txd}" - if self._txd_port_width == 4: - assert self._txd_4b_port_pin_assignment == "lower_2b" or self._txd_4b_port_pin_assignment == "upper_2b", \ - f"Invalid txd_4b_port_pin_assignment (self._txd_4b_port_pin_assignment). Allowed values lower_2b or upper_2b" + if self._txd_port_width == 4: # extra checks for 4b port + assert self._pin_assignment == [0,1] or self._pin_assignment == [2,3], \ + f"Invalid pin assignment {self._pin_assignment} for 4b port. Only lower 2 pins [0,1] and upper 2 pins [2,3] supported. " self.expected_packets = None self.expect_packet_index = 0 @@ -287,7 +287,6 @@ def __init__(self, name, txd, txen, clock, txd_4b_port_pin_assignment, print_pac self.expected_packets = None self.expect_packet_index = 0 self.num_expected_packets = 0 - #print(f"self._txd = {self._txd}, self._txd_port_width = {self._txd_port_width}, self._txd_4b_port_pin_assignment = {self._txd_4b_port_pin_assignment}") def get_name(self): return self._name @@ -307,10 +306,10 @@ def set_expected_packets(self, packets): class RMiiReceiver(RMiiRxPhy): def __init__(self, txd, txen, clock, - txd_4b_port_pin_assignment="lower_2b", + pin_assignment = None, print_packets=False, packet_fn=None, verbose=False, test_ctrl=None): - super(RMiiReceiver, self).__init__('rmii', txd, txen, clock, txd_4b_port_pin_assignment, + super(RMiiReceiver, self).__init__('rmii', txd, txen, clock, pin_assignment, print_packets, packet_fn, verbose, test_ctrl) self._txen_val = None @@ -361,15 +360,18 @@ def run(self): if self._txen_val == 1: # Sample data if self._txd_port_width == 4: - if self._txd_4b_port_pin_assignment == "lower_2b": + if self._pin_assignment == [0,1]: # lower_2b crumb = xsi.sample_port_pins(self._txd[0]) & 0x3 #print(f"crumb = {crumb}") - else: + else: # upper_2b crumb = (xsi.sample_port_pins(self._txd[0]) >> 2) & 0x3 - else: # 2, 1bit ports + elif self._txd_port_width == 1: # 2, 1bit ports cr0 = xsi.sample_port_pins(self._txd[0]) & 0x1 cr1 = xsi.sample_port_pins(self._txd[1]) & 0x1 crumb = (cr1 << 1) | cr0 + elif self._txd_port_width == 8: # always lower 2 bits for 8bit port + data = xsi.sample_port_pins(self._txd[0]) + crumb = ((data >> self._pin_assignment[0]) & 0x1) | (((data >> self._pin_assignment[1]) & 0x1) << 1) nibble = nibble | (crumb << (crumb_index*2)) if crumb_index == 1: if self._verbose: diff --git a/tests/test_rmii_restart/CMakeLists.txt b/tests/test_rmii_restart/CMakeLists.txt index a8c24a3f..21ca160e 100644 --- a/tests/test_rmii_restart/CMakeLists.txt +++ b/tests/test_rmii_restart/CMakeLists.txt @@ -53,7 +53,7 @@ foreach(PROFILE ${profile_list}) set_app_rx_width(rx_width) - set_app_tx_width(tx_width) + set_app_tx_width() string(FIND "${PROFILE}" "rt" position) if(position GREATER -1) diff --git a/tests/test_rmii_timing/CMakeLists.txt b/tests/test_rmii_timing/CMakeLists.txt index b8e48af2..e61d58a0 100644 --- a/tests/test_rmii_timing/CMakeLists.txt +++ b/tests/test_rmii_timing/CMakeLists.txt @@ -53,7 +53,7 @@ foreach(PROFILE ${profile_list}) set_app_rx_width(rx_width) - set_app_tx_width(tx_width) + set_app_tx_width() string(FIND "${PROFILE}" "rt" position) if(position GREATER -1) diff --git a/tests/test_rmii_timing/test_params.json b/tests/test_rmii_timing/test_params.json index 5e66e0ea..c202efa5 100644 --- a/tests/test_rmii_timing/test_params.json +++ b/tests/test_rmii_timing/test_params.json @@ -3,13 +3,15 @@ {"phy":"rmii", "mac":"rt", "arch":["xs3"], "rx_width":"4b_lower", "tx_width":"4b_lower"}, {"phy":"rmii", "mac":"rt", "arch":["xs3"], "rx_width":"4b_upper", "tx_width":"4b_lower"}, {"phy":"rmii", "mac":"rt", "arch":["xs3"], "rx_width":"1b", "tx_width":"4b_lower"}, - + {"phy":"rmii", "mac":"rt", "arch":["xs3"], "rx_width":"4b_lower", "tx_width":"4b_upper"}, {"phy":"rmii", "mac":"rt", "arch":["xs3"], "rx_width":"4b_upper", "tx_width":"4b_upper"}, {"phy":"rmii", "mac":"rt", "arch":["xs3"], "rx_width":"1b", "tx_width":"4b_upper"}, - + {"phy":"rmii", "mac":"rt", "arch":["xs3"], "rx_width":"4b_lower", "tx_width":"1b"}, {"phy":"rmii", "mac":"rt", "arch":["xs3"], "rx_width":"4b_upper", "tx_width":"1b"}, - {"phy":"rmii", "mac":"rt", "arch":["xs3"], "rx_width":"1b", "tx_width":"1b"} + {"phy":"rmii", "mac":"rt", "arch":["xs3"], "rx_width":"1b", "tx_width":"1b"}, + + {"phy":"rmii", "mac":"rt", "arch":["xs3"], "rx_width":"4b_lower", "tx_width":"8b_3_1"} ] } diff --git a/tests/test_rx/CMakeLists.txt b/tests/test_rx/CMakeLists.txt index 8bf3bc19..fcb4036d 100644 --- a/tests/test_rx/CMakeLists.txt +++ b/tests/test_rx/CMakeLists.txt @@ -53,7 +53,7 @@ foreach(PROFILE ${profile_list}) set_app_rx_width(rx_width) - set_app_tx_width(tx_width) + set_app_tx_width() string(FIND "${PROFILE}" "rt" position) if(position GREATER -1) diff --git a/tests/test_shaper/CMakeLists.txt b/tests/test_shaper/CMakeLists.txt index ef2ba37f..09a87349 100644 --- a/tests/test_shaper/CMakeLists.txt +++ b/tests/test_shaper/CMakeLists.txt @@ -51,7 +51,7 @@ foreach(PROFILE ${profile_list}) set(APP_COMPILER_FLAGS_${config} ${COMPILER_FLAGS_COMMON}) - set_app_tx_width(tx_width) + set_app_tx_width() string(FIND "${PROFILE}" "rt" position) if(position GREATER -1) diff --git a/tests/test_time_rx_tx/CMakeLists.txt b/tests/test_time_rx_tx/CMakeLists.txt index 3bd16781..2b633e35 100644 --- a/tests/test_time_rx_tx/CMakeLists.txt +++ b/tests/test_time_rx_tx/CMakeLists.txt @@ -54,7 +54,7 @@ foreach(PROFILE ${profile_list}) set(APP_COMPILER_FLAGS_${config} ${COMPILER_FLAGS_COMMON}) set_app_rx_width(rx_width) - set_app_tx_width(tx_width) + set_app_tx_width() string(FIND "${PROFILE}" "rt" position) if(position GREATER -1) diff --git a/tests/test_time_tx/CMakeLists.txt b/tests/test_time_tx/CMakeLists.txt index 4f7ef4ef..ad0c0535 100644 --- a/tests/test_time_tx/CMakeLists.txt +++ b/tests/test_time_tx/CMakeLists.txt @@ -47,7 +47,7 @@ foreach(PROFILE ${profile_list}) set(APP_COMPILER_FLAGS_${config} ${COMPILER_FLAGS_COMMON}) - set_app_tx_width(tx_width) + set_app_tx_width() string(FIND "${PROFILE}" "rt" position) if(position GREATER -1) diff --git a/tests/test_time_tx/test_params.json b/tests/test_time_tx/test_params.json index 19cc511a..6874203b 100644 --- a/tests/test_time_tx/test_params.json +++ b/tests/test_time_tx/test_params.json @@ -11,6 +11,7 @@ {"phy":"rmii", "mac":"rt", "arch":["xs3"], "tx_width":"4b_lower"}, {"phy":"rmii", "mac":"rt", "arch":["xs3"], "tx_width":"4b_upper"}, {"phy":"rmii", "mac":"rt", "arch":["xs3"], "tx_width":"1b"}, + {"phy":"rmii", "mac":"rt", "arch":["xs3"], "tx_width":"8b_1_5"}, {"phy":"rmii", "mac":"rt_hp", "arch":["xs3"], "tx_width":"4b_lower"}, {"phy":"rmii", "mac":"rt_hp", "arch":["xs3"], "tx_width":"4b_upper"}, diff --git a/tests/test_timestamp_tx/CMakeLists.txt b/tests/test_timestamp_tx/CMakeLists.txt index 61549fec..b48bc0ad 100644 --- a/tests/test_timestamp_tx/CMakeLists.txt +++ b/tests/test_timestamp_tx/CMakeLists.txt @@ -47,7 +47,7 @@ foreach(PROFILE ${profile_list}) set(APP_COMPILER_FLAGS_${config} ${COMPILER_FLAGS_COMMON}) - set_app_tx_width(tx_width) + set_app_tx_width() string(FIND "${PROFILE}" "rt" position) if(position GREATER -1) diff --git a/tests/test_tx/CMakeLists.txt b/tests/test_tx/CMakeLists.txt index edcfae60..e9b3817f 100644 --- a/tests/test_tx/CMakeLists.txt +++ b/tests/test_tx/CMakeLists.txt @@ -48,7 +48,7 @@ foreach(PROFILE ${profile_list}) set(APP_COMPILER_FLAGS_${config} ${COMPILER_FLAGS_COMMON}) - set_app_tx_width(tx_width) + set_app_tx_width() string(FIND "${PROFILE}" "rt" position) if(position GREATER -1) diff --git a/tests/test_tx/src/main.xc b/tests/test_tx/src/main.xc index b6d361e6..beb78549 100644 --- a/tests/test_tx/src/main.xc +++ b/tests/test_tx/src/main.xc @@ -12,16 +12,14 @@ port p_test_ctrl = on tile[0]: XS1_PORT_1C; #endif - - struct test_packet { int len; int step; int tagged; } test_packets[] = - { - { 60, 1, 0 }, - { ETHERNET_MAX_PACKET_SIZE, 5, 0 }, - { 60, 1, 1 }, - { ETHERNET_MAX_PACKET_SIZE, 5, 1 }, - }; +{ + { 60, 1, 0 }, + { ETHERNET_MAX_PACKET_SIZE, 5, 0 }, + { 60, 1, 1 }, + { ETHERNET_MAX_PACKET_SIZE, 5, 1 }, +}; void test_tx(client ethernet_tx_if tx, streaming chanend ? c_tx_hp) { @@ -135,7 +133,8 @@ int main() eth_rxclk, eth_txclk, 4000, 4000, ETHERNET_DISABLE_SHAPER); #elif RMII - on tile[0]: rmii_ethernet_rt_mac( i_cfg, NUM_CFG_IF, + on tile[0]: { + rmii_ethernet_rt_mac( i_cfg, NUM_CFG_IF, i_rx_lp, NUM_RX_LP_IF, i_tx_lp, NUM_TX_LP_IF, c_rx_hp, c_tx_hp, @@ -153,6 +152,7 @@ int main() port_timing, 4000, 4000, ETHERNET_DISABLE_SHAPER); + } #endif on tile[0]: filler(0x1111); diff --git a/tests/test_tx/test_params.json b/tests/test_tx/test_params.json index 19cc511a..3bd4610b 100644 --- a/tests/test_tx/test_params.json +++ b/tests/test_tx/test_params.json @@ -14,6 +14,8 @@ {"phy":"rmii", "mac":"rt_hp", "arch":["xs3"], "tx_width":"4b_lower"}, {"phy":"rmii", "mac":"rt_hp", "arch":["xs3"], "tx_width":"4b_upper"}, - {"phy":"rmii", "mac":"rt_hp", "arch":["xs3"], "tx_width":"1b"} + {"phy":"rmii", "mac":"rt_hp", "arch":["xs3"], "tx_width":"1b"}, + {"phy":"rmii", "mac":"rt_hp", "arch":["xs3"], "tx_width":"8b_6_7"}, + {"phy":"rmii", "mac":"rt_hp", "arch":["xs3"], "tx_width":"8b_5_1"} ] } diff --git a/tests/test_tx_ifg/CMakeLists.txt b/tests/test_tx_ifg/CMakeLists.txt index 492ec0a1..6f1c69f7 100644 --- a/tests/test_tx_ifg/CMakeLists.txt +++ b/tests/test_tx_ifg/CMakeLists.txt @@ -49,7 +49,7 @@ foreach(PROFILE ${profile_list}) set(APP_COMPILER_FLAGS_${config} ${COMPILER_FLAGS_COMMON}) - set_app_tx_width(tx_width) + set_app_tx_width() string(FIND "${PROFILE}" "rt" position) if(position GREATER -1)