/* * top_occam_like_xc.h * * Created on: 3. mars 2021 * Author: teig */ #ifndef TOP_OCCAM_LIKE_XC_H_ #define TOP_OCCAM_LIKE_XC_H_ #if (TOPOLOGY != TOP_20_HAS_2_TILE_004_T0_2N_BY3SUB_T1_2N_BY3SUB_RUNS_FAIR) #error #endif #define CLIENT_ROOT_STR "R" #define CLIENT_STR "C" #define SERVER_STR "S" typedef unsigned value_t; typedef struct node_context_t { unsigned iof_row; unsigned iof_col; value_t value; value_t value_init; value_t values[NUM_CONNS_PER_NODE]; } node_context_t; void Init ( const unsigned iof_row, unsigned iof_col, node_context_t &context) { context.iof_row = iof_row; context.iof_col = iof_col; context.value = row_col_to_number (iof_row, iof_col); context.value_init = context.value; } void Node_Calculate (node_context_t &context) { context.value = context.value + context.values[0] + context.values[1] + context.values[2]; if (context.value > VALUE_MAX) { context.value = context.value_init; } else {} } #define DEBUG_PRINT_BANNER_ROOT(context,str1,str2) \ debug_print_extra ("(%u %u):%s[%u] %s _xc_test_combinable.xc compiled on %s %s as TOP_20_HAS_2_TILE_004_T0_2N_BY3SUB_T1_2N_BY3SUB_RUNS_FAIR\n", \ context.iof_row, context.iof_col, str1, \ context.value, str2, \ __DATE__, __TIME__) #define DEBUG_PRINT_BANNER(context,str1,str2) \ debug_print_extra ("(%u %u):%s[%u] %s\n", \ context.iof_row, context.iof_col, str1, \ context.value, str2) #define DEBUG_PRINT_VALUES_WITH_TIME(context,str1,tmr) do { \ time32_t time_now_ticks; \ tmr :> time_now_ticks; \ debug_print_extra ("(%u %u):%s[%5u] from [%5u][%5u][%5u] at %u ms\n", \ context.iof_row, context.iof_col, str1, \ context.value, context.values[0], context.values[1], context.values[2], time_now_ticks/XS1_TIMER_KHZ); \ } while(0) #define DEBUG_PRINT_VALUES(context,str1) \ debug_print_extra ("(%u %u):%s[%5u] from [%5u][%5u][%5u]\n", \ context.iof_row, context.iof_col, str1, \ context.value, context.values[0], context.values[1], context.values[2]) #if (DO_XSCOPE == 0) #define XSCOPE_INT(name,val) #elif (DO_XSCOPE==1) // This takes about 0.2 us, but DELTA_TIME_US must have some real // value for data to be corrected (XScope would say "missing data" if it's too fast) #define XSCOPE_INT(name,val) xscope_int(name,val) // In "config.xscope" DISCRETE, which must be handled in offline mode, see // "xTIMEcomposer User Guide for tools version 14.0.x" page 133: // "Only continous probes can be displayed real-time." // If DECRETE not used here, values are interpolated (saw tooth curve is not of much value) // Log file is generated as "xscope.xmt" and opens on after I stop the RUN // // xScope scaling, if not top and bottom is not seen: #define XSCOPE_SCALE_MAX 1100 #define XSCOPE_VALUE_TRUE 1000 #define XSCOPE_VALUE_FALSE 100 #define XSCOPE_SCALE_MIN 0 #endif void Client_node_3_composite_par_root ( // With DELTA_TIME_TICKS=0 round trip about 1.24 us const unsigned iof_row, const unsigned iof_col, chanend chan_0, chanend chan_1, chanend chan_2, out buffered port:4 outP4_leds) { node_context_t context; timer tmr; time32_t time_ticks; time32_t time_start_ticks; time32_t time_stop_ticks; Init (iof_row, iof_col, context); unsigned leds = BOARD_LEDS_INIT; outP4_leds <: leds; DEBUG_PRINT_BANNER_ROOT (context, CLIENT_ROOT_STR, "Client_node_3_composite_par_root"); XSCOPE_INT (VALUE, XSCOPE_SCALE_MAX); XSCOPE_INT (VALUE, XSCOPE_SCALE_MIN); tmr :> time_ticks; while (1) { select { case tmr when timerafter (time_ticks) :> time_start_ticks : { // No skew here par { { // subtask 1 chan_0 <: context.value; chan_0 :> context.values[0]; } { // subtask 2 chan_1 <: context.value; chan_1 :> context.values[1]; } { // subtask 3 chan_2 <: context.value; chan_2 :> context.values[2]; } } Node_Calculate (context); DEBUG_PRINT_VALUES_WITH_TIME (context, CLIENT_ROOT_STR, tmr); // Swap LED leds xor_eq BOARD_LED_MASK_GREEN_ONLY; // J1.7 CH1 XCORE-200-EXPLORER outP4_leds <: leds; XSCOPE_INT (VALUE, leds ? XSCOPE_VALUE_TRUE : XSCOPE_VALUE_FALSE); tmr :> time_stop_ticks; { // timerafter always has to be "the future", that value must NEVER lag behind! const time32_t time_used_ticks = time_stop_ticks - time_start_ticks; if (time_used_ticks >= DELTA_TIME_TICKS) { // Re-read "now" when DELTA_TIME_TICKS is shorter than round trip (here 0 or 1 us). // Round trip is about 1.25 us, almost "unbelievably" fast since all the other // three nodes also start and stop their communication subtasks and communicate back // and forth, even across tiles tmr :> time_ticks; // This seems to take "no time" } else { // DELTA_TIME_TICKS here typically 2 us and above time_ticks += DELTA_TIME_TICKS; // No skew } } } break; } } } void Client_node_3_composite_par ( const unsigned iof_row, const unsigned iof_col, chanend chan_0, chanend chan_1, chanend chan_2) { node_context_t context; Init (iof_row, iof_col, context); DEBUG_PRINT_BANNER (context, CLIENT_STR, "Client_node_3_composite_par"); while (1) { // Client_node_3_composite_par par { { // subtask 1 chan_0 <: context.value; chan_0 :> context.values[0]; } { // subtask 2 chan_1 <: context.value; chan_1 :> context.values[1]; } { // subtask 3 chan_2 <: context.value; chan_2 :> context.values[2]; } } Node_Calculate (context); DEBUG_PRINT_VALUES (context, CLIENT_STR); } } void Server_node_3_composite_par ( const unsigned iof_row, const unsigned iof_col, chanend chan_0, chanend chan_1, chanend chan_2) { node_context_t context; Init (iof_row, iof_col, context); DEBUG_PRINT_BANNER (context, SERVER_STR," Server_node_3_composite_par"); while (1) { // Server_node_3_composite_par par { { // subtask 1 chan_0 :> context.values[0]; chan_0 <: context.value; } { // subtask 2 chan_1 :> context.values[1]; chan_1 <: context.value; } { // subtask 3 chan_2 :> context.values[2]; chan_2 <: context.value; } } Node_Calculate (context); DEBUG_PRINT_VALUES (context, SERVER_STR); } } #endif /* TOP_OCCAM_LIKE_XC_H_ */