Transition delay calculation. TBC...
--- a/TODO Wed Apr 29 14:03:01 2009 +0000
+++ b/TODO Thu Apr 30 14:12:47 2009 +0000
@@ -11,7 +11,6 @@
Version 1.5.0:
* Distributed clocks:
- - Delay calculation.
- Use common application time offset when setting start times.
- Check 32/64 bit operations.
- Set system time offset only when application time available.
--- a/master/cdev.c Wed Apr 29 14:03:01 2009 +0000
+++ b/master/cdev.c Thu Apr 30 14:12:47 2009 +0000
@@ -257,21 +257,23 @@
data.general_flags = slave->sii.general_flags;
data.current_on_ebus = slave->sii.current_on_ebus;
for (i = 0; i < EC_MAX_PORTS; i++) {
- data.port_descs[i] = slave->base_ports[i];
- data.ports[i].dl_link = slave->ports[i].dl_link;
- data.ports[i].dl_loop = slave->ports[i].dl_loop;
- data.ports[i].dl_signal = slave->ports[i].dl_signal;
- data.dc_receive_times[i] = slave->dc_receive_times[i];
- if (slave->next_slave[i]) {
- data.next_slave[i] = slave->next_slave[i]->ring_position;
+ data.ports[i].desc = slave->ports[i].desc;
+ data.ports[i].link.link_up = slave->ports[i].link.link_up;
+ data.ports[i].link.loop_closed = slave->ports[i].link.loop_closed;
+ data.ports[i].link.signal_detected = slave->ports[i].link.signal_detected;
+ data.ports[i].receive_time = slave->ports[i].receive_time;
+ if (slave->ports[i].next_slave) {
+ data.ports[i].next_slave = slave->ports[i].next_slave->ring_position;
} else {
- data.next_slave[i] = 0xffff;
+ data.ports[i].next_slave = 0xffff;
}
+ data.ports[i].delay_to_next_dc = slave->ports[i].delay_to_next_dc;
}
data.fmmu_bit = slave->base_fmmu_bit_operation;
data.dc_supported = slave->base_dc_supported;
data.dc_range = slave->base_dc_range;
data.has_dc_system_time = slave->has_dc_system_time;
+ data.transition_delay = slave->transition_delay;
data.al_state = slave->current_state;
data.error_flag = slave->error_flag;
--- a/master/fsm_master.c Wed Apr 29 14:03:01 2009 +0000
+++ b/master/fsm_master.c Thu Apr 30 14:12:47 2009 +0000
@@ -865,11 +865,7 @@
master->scan_busy = 0;
wake_up_interruptible(&master->scan_queue);
- // find DC reference clock
- ec_master_find_dc_ref_clock(master);
-
- // calculate bus topology
- ec_master_calc_topology(master);
+ ec_master_calc_dc(master);
// Attach slave configurations
ec_master_attach_slave_configs(master);
--- a/master/fsm_slave_scan.c Wed Apr 29 14:03:01 2009 +0000
+++ b/master/fsm_slave_scan.c Thu Apr 30 14:12:47 2009 +0000
@@ -311,7 +311,7 @@
octet = EC_READ_U8(datagram->data + 7);
for (i = 0; i < EC_MAX_PORTS; i++) {
- slave->base_ports[i] = (octet >> (2 * i)) & 0x03;
+ slave->ports[i].desc = (octet >> (2 * i)) & 0x03;
}
octet = EC_READ_U8(datagram->data + 8);
@@ -417,7 +417,7 @@
}
for (i = 0; i < EC_MAX_PORTS; i++) {
- slave->dc_receive_times[i] = EC_READ_U32(datagram->data + 4 * i);
+ slave->ports[i].receive_time = EC_READ_U32(datagram->data + 4 * i);
}
ec_fsm_slave_scan_enter_datalink(fsm);
@@ -478,9 +478,9 @@
dl_status = EC_READ_U16(datagram->data);
for (i = 0; i < EC_MAX_PORTS; i++) {
- slave->ports[i].dl_link = dl_status & (1 << (4 + i)) ? 1 : 0;
- slave->ports[i].dl_loop = dl_status & (1 << (8 + i * 2)) ? 1 : 0;
- slave->ports[i].dl_signal = dl_status & (1 << (9 + i * 2)) ? 1 : 0;
+ slave->ports[i].link.link_up = dl_status & (1 << (4 + i)) ? 1 : 0;
+ slave->ports[i].link.loop_closed = dl_status & (1 << (8 + i * 2)) ? 1 : 0;
+ slave->ports[i].link.signal_detected = dl_status & (1 << (9 + i * 2)) ? 1 : 0;
}
// Start fetching SII size
--- a/master/globals.h Wed Apr 29 14:03:01 2009 +0000
+++ b/master/globals.h Thu Apr 30 14:12:47 2009 +0000
@@ -169,10 +169,10 @@
/** EtherCAT slave port information.
*/
typedef struct {
- uint8_t dl_link; /**< Link detected. */
- uint8_t dl_loop; /**< Loop closed. */
- uint8_t dl_signal; /**< Detected signal on RX port. */
-} ec_slave_port_t;
+ uint8_t link_up; /**< Link detected. */
+ uint8_t loop_closed; /**< Loop closed. */
+ uint8_t signal_detected; /**< Detected signal on RX port. */
+} ec_slave_port_link_t;
/** EtherCAT slave distributed clocks range.
*/
--- a/master/ioctl.h Wed Apr 29 14:03:01 2009 +0000
+++ b/master/ioctl.h Thu Apr 30 14:12:47 2009 +0000
@@ -165,14 +165,18 @@
ec_sii_coe_details_t coe_details;
ec_sii_general_flags_t general_flags;
int16_t current_on_ebus;
- ec_slave_port_desc_t port_descs[EC_MAX_PORTS];
- ec_slave_port_t ports[EC_MAX_PORTS];
- uint16_t next_slave[EC_MAX_PORTS];
+ struct {
+ ec_slave_port_desc_t desc;
+ ec_slave_port_link_t link;
+ uint32_t receive_time;
+ uint16_t next_slave;
+ uint32_t delay_to_next_dc;
+ } ports[EC_MAX_PORTS];
uint8_t fmmu_bit;
uint8_t dc_supported;
ec_slave_dc_range_t dc_range;
uint8_t has_dc_system_time;
- uint32_t dc_receive_times[EC_MAX_PORTS];
+ uint32_t transition_delay;
uint8_t al_state;
uint8_t error_flag;
uint8_t sync_count;
--- a/master/master.c Wed Apr 29 14:03:01 2009 +0000
+++ b/master/master.c Thu Apr 30 14:12:47 2009 +0000
@@ -77,6 +77,7 @@
#ifdef EC_EOE
void ec_master_eoe_run(unsigned long);
#endif
+void ec_master_find_dc_ref_clock(ec_master_t *);
/*****************************************************************************/
@@ -342,6 +343,8 @@
{
ec_slave_t *slave;
+ master->dc_ref_clock = NULL;
+
for (slave = master->slaves;
slave < master->slaves + master->slave_count;
slave++) {
@@ -1357,20 +1360,22 @@
ec_master_t *master /**< EtherCAT master. */
)
{
- ec_slave_t *slave;
- uint16_t ref_clock_addr = 0xffff;
+ ec_slave_t *slave, *ref = NULL;
for (slave = master->slaves;
slave < master->slaves + master->slave_count;
slave++) {
- if (slave->base_dc_supported && slave->has_dc_system_time) {
- ref_clock_addr = slave->station_address;
- break;
- }
- }
-
- // This call always succeeds, because the datagram has been pre-allocated.
- ec_datagram_frmw(&master->sync_datagram, ref_clock_addr, 0x0910, 4);
+ if (slave->base_dc_supported && slave->has_dc_system_time) {
+ ref = slave;
+ break;
+ }
+ }
+
+ master->dc_ref_clock = ref;
+
+ // This call always succeeds, because the datagram has been pre-allocated.
+ ec_datagram_frmw(&master->sync_datagram,
+ ref ? ref->station_address : 0xffff, 0x0910, 4);
}
/*****************************************************************************/
@@ -1387,13 +1392,13 @@
unsigned int i;
int ret;
- slave->next_slave[0] = port0_slave;
+ slave->ports[0].next_slave = port0_slave;
for (i = 1; i < EC_MAX_PORTS; i++) {
- if (!slave->ports[i].dl_loop) {
+ if (!slave->ports[i].link.loop_closed) {
*slave_position = *slave_position + 1;
if (*slave_position < master->slave_count) {
- slave->next_slave[i] = master->slaves + *slave_position;
+ slave->ports[i].next_slave = master->slaves + *slave_position;
ret = ec_master_calc_topology_rec(master,
slave, slave_position);
if (ret)
@@ -1424,6 +1429,45 @@
EC_ERR("Failed to calculate bus topology.\n");
}
+/*****************************************************************************/
+
+/** Calculates the bus transition delays.
+ */
+void ec_master_calc_transition_delays(
+ ec_master_t *master /**< EtherCAT master. */
+ )
+{
+ ec_slave_t *slave;
+
+ for (slave = master->slaves;
+ slave < master->slaves + master->slave_count;
+ slave++) {
+ ec_slave_calc_port_delays(slave);
+ }
+
+ if (master->dc_ref_clock) {
+ uint32_t delay = 0;
+ ec_slave_calc_transition_delays_rec(master->dc_ref_clock, &delay);
+ }
+}
+
+/*****************************************************************************/
+
+/** Distributed-clocks calculations.
+ */
+void ec_master_calc_dc(
+ ec_master_t *master /**< EtherCAT master. */
+ )
+{
+ // find DC reference clock
+ ec_master_find_dc_ref_clock(master);
+
+ // calculate bus topology
+ ec_master_calc_topology(master);
+
+ ec_master_calc_transition_delays(master);
+}
+
/******************************************************************************
* Application interface
*****************************************************************************/
--- a/master/master.h Wed Apr 29 14:03:01 2009 +0000
+++ b/master/master.h Thu Apr 30 14:12:47 2009 +0000
@@ -122,6 +122,7 @@
reference clock to the master clock. */
ec_datagram_t sync_datagram; /**< Datagram used for DC drift
compensation. */
+ ec_slave_t *dc_ref_clock; /**< DC reference clock slave. */
unsigned int scan_busy; /**< Current scan state. */
unsigned int allow_scan; /**< \a True, if slave scanning is allowed. */
@@ -233,9 +234,8 @@
ec_slave_config_t *ecrt_master_slave_config_err(ec_master_t *, uint16_t,
uint16_t, uint32_t, uint32_t);
-void ec_master_find_dc_ref_clock(ec_master_t *);
-void ec_master_calc_topology(ec_master_t *);
-
-/*****************************************************************************/
-
-#endif
+void ec_master_calc_dc(ec_master_t *);
+
+/*****************************************************************************/
+
+#endif
--- a/master/slave.c Wed Apr 29 14:03:01 2009 +0000
+++ b/master/slave.c Thu Apr 30 14:12:47 2009 +0000
@@ -89,22 +89,24 @@
slave->base_sync_count = 0;
for (i = 0; i < EC_MAX_PORTS; i++) {
- slave->base_ports[i] = EC_PORT_NOT_IMPLEMENTED;
-
- slave->ports[i].dl_link = 0;
- slave->ports[i].dl_loop = 0;
- slave->ports[i].dl_signal = 0;
+ slave->ports[i].desc = EC_PORT_NOT_IMPLEMENTED;
+
+ slave->ports[i].link.link_up = 0;
+ slave->ports[i].link.loop_closed = 0;
+ slave->ports[i].link.signal_detected = 0;
slave->sii.physical_layer[i] = 0xFF;
- slave->dc_receive_times[i] = 0U;
-
- slave->next_slave[i] = NULL;
+ slave->ports[i].receive_time = 0U;
+
+ slave->ports[i].next_slave = NULL;
+ slave->ports[i].delay_to_next_dc = 0U;
}
slave->base_fmmu_bit_operation = 0;
slave->base_dc_supported = 0;
slave->base_dc_range = EC_DC_32;
slave->has_dc_system_time = 0;
+ slave->transition_delay = 0U;
slave->sii_words = NULL;
slave->sii_nwords = 0;
@@ -740,3 +742,126 @@
}
/*****************************************************************************/
+
+/** Calculates the sum of round-trip-times of connected ports 1-3.
+ */
+uint32_t ec_slave_calc_rtt_sum(
+ ec_slave_t *slave /**< EtherCAT slave. */
+ )
+{
+ uint32_t rtt_sum = 0, rtt;
+ unsigned int i;
+
+ for (i = 1; i < EC_MAX_PORTS; i++) {
+ if (slave->ports[i].next_slave) {
+ rtt = slave->ports[i].receive_time - slave->ports[i - 1].receive_time;
+ rtt_sum += rtt;
+ }
+ }
+
+ return rtt_sum;
+}
+
+/*****************************************************************************/
+
+/** Finds the next slave supporting DC delay measurement.
+ */
+ec_slave_t *ec_slave_find_next_dc_slave(
+ ec_slave_t *slave /**< EtherCAT slave. */
+ )
+{
+ ec_slave_t *dc_slave = NULL;
+
+ if (slave->base_dc_supported) {
+ dc_slave = slave;
+ } else {
+ unsigned int i;
+
+ for (i = 1; i < EC_MAX_PORTS; i++) {
+ ec_slave_t *next = slave->ports[i].next_slave;
+ if (next) {
+ dc_slave = ec_slave_find_next_dc_slave(next);
+ if (dc_slave)
+ break;
+ }
+ }
+ }
+
+ return dc_slave;
+}
+
+/*****************************************************************************/
+
+/** Calculates the port transition delays.
+ */
+void ec_slave_calc_port_delays(
+ ec_slave_t *slave /**< EtherCAT slave. */
+ )
+{
+ unsigned int i;
+ ec_slave_t *next, *next_dc;
+ uint32_t rtt, next_rtt_sum;
+
+ if (!slave->base_dc_supported)
+ return;
+
+ for (i = 1; i < EC_MAX_PORTS; i++) {
+ next = slave->ports[i].next_slave;
+ if (!next)
+ continue;
+ next_dc = ec_slave_find_next_dc_slave(next);
+ if (!next_dc)
+ continue;
+
+ rtt = slave->ports[i].receive_time - slave->ports[i - 1].receive_time;
+ next_rtt_sum = ec_slave_calc_rtt_sum(next_dc);
+
+ slave->ports[i].delay_to_next_dc = (rtt - next_rtt_sum) / 2; // FIXME
+ next_dc->ports[0].delay_to_next_dc = (rtt - next_rtt_sum) / 2;
+
+#if 0
+ EC_DBG("delay %u:%u rtt=%u next_rtt_sum=%u delay=%u\n",
+ slave->ring_position, i, rtt, next_rtt_sum,
+ slave->ports[i].delay_to_next_dc);
+#endif
+ }
+}
+
+/*****************************************************************************/
+
+/** Calculates the bus topology; recursion function.
+ */
+void ec_slave_calc_transition_delays_rec(
+ ec_slave_t *slave, /**< Current slave. */
+ uint32_t *delay /**< Sum of delays. */
+ )
+{
+ unsigned int i;
+ ec_slave_t *next, *next_dc;
+
+#if 0
+ EC_DBG("%u: %u\n", slave->ring_position, *delay);
+#endif
+
+ slave->transition_delay = *delay;
+
+ for (i = 1; i < EC_MAX_PORTS; i++) {
+ ec_slave_port_t *port = &slave->ports[i];
+ next = port->next_slave;
+ if (!next)
+ continue;
+ next_dc = ec_slave_find_next_dc_slave(next);
+ if (!next_dc)
+ continue;
+
+ *delay = *delay + port->delay_to_next_dc;
+#if 0
+ EC_DBG("%u:%u %u\n", slave->ring_position, i, *delay);
+#endif
+ ec_slave_calc_transition_delays_rec(next_dc, delay);
+ }
+
+ *delay = *delay + slave->ports[0].delay_to_next_dc;
+}
+
+/*****************************************************************************/
--- a/master/slave.h Wed Apr 29 14:03:01 2009 +0000
+++ b/master/slave.h Thu Apr 30 14:12:47 2009 +0000
@@ -48,6 +48,20 @@
/*****************************************************************************/
+/** Slave port.
+ */
+typedef struct {
+ ec_slave_port_desc_t desc; /**< Port descriptors. */
+ ec_slave_port_link_t link; /**< Port link status. */
+ ec_slave_t *next_slave; /**< Connected slaves. */
+ uint32_t receive_time; /**< Port receive times for delay
+ measurement. */
+ uint32_t delay_to_next_dc; /**< Delay to next slave with DC support behind
+ this port [ns]. */
+} ec_slave_port_t;
+
+/*****************************************************************************/
+
/** Slave information interface data.
*/
typedef struct {
@@ -102,6 +116,8 @@
uint16_t ring_position; /**< Ring position. */
uint16_t station_address; /**< Configured station address. */
+ ec_slave_port_t ports[EC_MAX_PORTS]; /**< Ports. */
+
// configuration
ec_slave_config_t *config; /**< Current configuration. */
ec_slave_state_t requested_state; /**< Requested application state. */
@@ -119,19 +135,14 @@
uint16_t base_build; /**< Build number. */
uint8_t base_fmmu_count; /**< Number of supported FMMUs. */
uint8_t base_sync_count; /**< Number of supported sync managers. */
- ec_slave_port_desc_t base_ports[EC_MAX_PORTS]; /**< Port descriptors. */
uint8_t base_fmmu_bit_operation; /**< FMMU bit operation is supported. */
uint8_t base_dc_supported; /**< Distributed clocks are supported. */
ec_slave_dc_range_t base_dc_range; /**< DC range. */
uint8_t has_dc_system_time; /**< The slave supports the DC system time
register. Otherwise it can only be used for
delay measurement. */
- uint32_t dc_receive_times[EC_MAX_PORTS]; /**< Port receive times for delay
- measurement. */
-
- // data link status
- ec_slave_port_t ports[EC_MAX_PORTS]; /**< Port link status. */
- ec_slave_t *next_slave[EC_MAX_PORTS]; /**< Connected slaves. */
+ uint32_t transition_delay; /**< DC transition delay (from reference
+ clock). */
// SII
uint16_t *sii_words; /**< Complete SII image. */
@@ -175,6 +186,9 @@
const ec_pdo_t *ec_slave_find_pdo(const ec_slave_t *, uint16_t);
void ec_slave_attach_pdo_names(ec_slave_t *);
+void ec_slave_calc_port_delays(ec_slave_t *);
+void ec_slave_calc_transition_delays_rec(ec_slave_t *, uint32_t *);
+
/*****************************************************************************/
#endif
--- a/tool/CommandGraph.cpp Wed Apr 29 14:03:01 2009 +0000
+++ b/tool/CommandGraph.cpp Thu Apr 30 14:12:47 2009 +0000
@@ -72,7 +72,6 @@
SlaveVector slaves;
ec_ioctl_slave_t slave;
SlaveVector::const_iterator si;
- string font("fontname=\"Helvetica\"");
map<int, string> portMedia;
map<int, string>::const_iterator mi;
map<int, int> mediaWeights;
@@ -102,51 +101,84 @@
<< endl
<< "strict graph bus {" << endl
<< " rankdir=\"LR\"" << endl
+ << " ranksep=0.8" << endl
+ << " nodesep=0.8" << endl
+ << " node [fontname=\"Helvetica\"]" << endl
+ << " edge [fontname=\"Helvetica\",fontsize=\"10\"]" << endl
<< endl
- << " master [" << font << ",label=\"EtherCAT\\nMaster\"]" << endl;
+ << " master [label=\"EtherCAT\\nMaster\"]" << endl;
if (slaves.size()) {
- cout << " master -- slave0 [" << font;
+ cout << " master -- slave0";
+ mi = portMedia.find(slaves.front().ports[0].desc);
+ if (mi != portMedia.end())
+ cout << "[label=\"" << mi->second << "\"]";
- mi = portMedia.find(slaves.front().port_descs[0]);
- if (mi != portMedia.end())
- cout << ",label=\"" << mi->second << "\"";
-
- cout << "]" << endl;
+ cout << endl;
}
cout << endl;
for (si = slaves.begin(); si != slaves.end(); si++) {
- cout << " slave" << si->position << " [" << font <<
- ",shape=\"box\",label=\"" << si->position;
+ cout << " slave" << si->position << " [shape=\"box\""
+ << ",label=\"" << si->position;
if (string(si->order).size())
cout << "\\n" << si->order;
+ if (si->dc_supported) {
+ cout << "\\nDC: ";
+ if (si->has_dc_system_time) {
+ switch (si->dc_range) {
+ case EC_DC_32:
+ cout << "32 bit";
+ break;
+ case EC_DC_64:
+ cout << "64 bit";
+ break;
+ default:
+ break;
+ }
+ } else {
+ cout << "Delay meas.";
+ }
+ cout << "\\nDelay: " << si->transition_delay << " ns";
+ }
cout << "\"]" << endl;
for (i = 1; i < EC_MAX_PORTS; i++) {
- if (si->next_slave[i] == 0xffff)
+ uint16_t next_pos = si->ports[i].next_slave;
+ ec_ioctl_slave_t *next = NULL;
+
+ if (next_pos == 0xffff)
continue;
+ if (next_pos < slaves.size()) {
+ next = &slaves[next_pos];
+ } else {
+ cerr << "Invalid next slave pointer." << endl;
+ }
+
cout << " slave" << si->position << " -- "
- << "slave" << si->next_slave[i] << " [" << font << ","
- << "taillabel=\"" << i << "\"";
+ << "slave" << next_pos << " [taillabel=\"" << i;
- mi = portMedia.find(si->port_descs[i]);
- if (mi == portMedia.end()) {
+ if (si->dc_supported) {
+ cout << " [" << si->ports[i].delay_to_next_dc << "]";
+ }
+ cout << "\",headlabel=\"0";
+
+ if (next && next->dc_supported) {
+ cout << " [" << next->ports[0].delay_to_next_dc << "]";
+ }
+ cout << "\"";
+
+ mi = portMedia.find(si->ports[i].desc);
+ if (mi == portMedia.end() && next) {
/* Try medium of next-hop slave. */
- unsigned int pos = si->next_slave[i];
- if (pos < slaves.size()) {
- ec_ioctl_slave_t *next = &slaves[pos];
- mi = portMedia.find(next->port_descs[0]);
- } else {
- cerr << "Invalid next slave pointer." << endl;
- }
+ mi = portMedia.find(next->ports[0].desc);
}
if (mi != portMedia.end())
cout << ",label=\"" << mi->second << "\"";
- wi = mediaWeights.find(si->port_descs[i]);
+ wi = mediaWeights.find(si->ports[i].desc);
if (wi != mediaWeights.end())
cout << ",weight=\"" << wi->second << "\"";
--- a/tool/CommandSlaves.cpp Wed Apr 29 14:03:01 2009 +0000
+++ b/tool/CommandSlaves.cpp Thu Apr 30 14:12:47 2009 +0000
@@ -262,18 +262,20 @@
} else {
cout << "yes, delay measurement only" << endl;
}
+ cout << " DC transition delay: "
+ << si->transition_delay << " ns" << endl;
} else {
cout << "no" << endl;
}
cout << "Port Type Link Loop Signal NextSlave";
if (si->dc_supported)
- cout << " RxTime Diff";
+ cout << " RxTime [ns] Diff [ns] NextDc [ns]";
cout << endl;
for (i = 0; i < EC_MAX_PORTS; i++) {
cout << " " << i << " " << setfill(' ') << left << setw(4);
- switch (si->port_descs[i]) {
+ switch (si->ports[i].desc) {
case EC_PORT_NOT_IMPLEMENTED:
cout << "N/A";
break;
@@ -291,29 +293,35 @@
}
cout << " " << setw(4)
- << (si->ports[i].dl_link ? "up" : "down")
+ << (si->ports[i].link.link_up ? "up" : "down")
<< " " << setw(6)
- << (si->ports[i].dl_loop ? "closed" : "open")
+ << (si->ports[i].link.loop_closed ? "closed" : "open")
<< " " << setw(6)
- << (si->ports[i].dl_signal ? "yes" : "no")
+ << (si->ports[i].link.signal_detected ? "yes" : "no")
<< " " << setw(9) << right;
- if (si->next_slave[i] != 0xffff) {
- cout << dec << si->next_slave[i];
+ if (si->ports[i].next_slave != 0xffff) {
+ cout << dec << si->ports[i].next_slave;
} else {
cout << "-";
}
if (si->dc_supported) {
- cout << " " << setw(10) << right;
- if (si->ports[i].dl_signal) {
- cout << dec << si->dc_receive_times[i];
+ cout << " " << setw(11) << right;
+ if (!si->ports[i].link.loop_closed) {
+ cout << dec << si->ports[i].receive_time;
} else {
cout << "-";
}
cout << " " << setw(10);
- if (si->ports[i].dl_signal) {
- cout << si->dc_receive_times[i] - si->dc_receive_times[0];
+ if (!si->ports[i].link.loop_closed) {
+ cout << si->ports[i].receive_time - si->ports[0].receive_time;
+ } else {
+ cout << "-";
+ }
+ cout << " " << setw(10);
+ if (!si->ports[i].link.loop_closed) {
+ cout << si->ports[i].delay_to_next_dc;
} else {
cout << "-";
}