NED File src/inet/physicallayer/wired/ethernet/EthernetPlca.ned¶
Name |
Type |
Description |
|---|---|---|
simple module |
Implements the Ethernet Phyisical Layer Collision Avoidance (PLCA) protocol defined in the IEEE 802.3cg-2019 standard. It can be used to build an Ethernet network interface that can be connected to 10BASE-T1S multidrop links. |
Source code¶
//
// Copyright (C) 2023 OpenSim Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
package inet.physicallayer.wired.ethernet;
import inet.common.SimpleModule;
import inet.protocolelement.contract.IProtocolLayer;
//
// Implements the Ethernet Phyisical Layer Collision Avoidance (PLCA)
// protocol defined in the IEEE 802.3cg-2019 standard. It can be used to build an
// Ethernet network interface that can be connected to 10BASE-T1S multidrop links.
//
// The PLCA protocol is implemented with the following features:
// - control state machine (with minor modifications)
// - data state machine (with some modifications)
// - periodic beacons to synchronize cycle start
// - keeping track of the current transmit opportunity
// - various timing parameters (beacon length, to length, etc.)
// - packet bursts with configurable maximum number of packets
// - configurable delay line to temporarily hold the frame from the MAC
// - carrier sense and collision signals
// - various end signal delimiters
//
// The PLCA protocol is implemented with several limitations:
// - PHY collisions are not supported (avoidance assumed)
// - status state machine is not implemented (plca_status)
// - PLCA mode cannot be enabled/disabled dynamically (plca_en), it's always active
// - PLCA cannot be reset (plca_reset)
// - special handling of local_nodeID 255 is missing
// - beacons are assumed to be never lost (no invalid_beacon_timer)
// - data state machine cannot abort transmissions
// - mixed operation with CSMA/CD nodes on the same multidrop link is not supported
// - controller immediately starts sending a beacon
// - nodes start with waiting to receive a beacon
//
// All ~EthernetPlca modules in the network interfaces on the same multidrop link
// must have the same plca_node_count parameter value set. Also, the local_nodeID
// parameter must be set to a uniqe value in the [0, plca_node_count - 1] range.
//
// This module requires that the modules connected to it implement certain C++
// interfaces. The upper layer must be connected to a module implementing the
// ~IEthernetCsmaMac C++ interface. One such module is the ~EthernetCsmaMac module.
// The lower layer must be connected to a module implementing the ~IEthernetCsmaPhy
// C++ interface. One such module is the ~EthernetCsmaPhy module.
//
// @see ~EthernetCsmaMac, ~EthernetCsmaPhy, ~EthernetPlcaInterface
//
simple EthernetPlca extends SimpleModule like IProtocolLayer
{
parameters:
@class(EthernetPlca);
// Maximum number of PLCA nodes on the mixing segment receiving transmit
// opportunities before the node with local_nodeID = 0 generates a new
// BEACON.
int plca_node_count;
// ID representing the PLCA transmit opportunity number assigned to the
// node.
int local_nodeID;
// Maximum number of additional packets the node is allowed to transmit
// in a single burst.
int max_bc = default(0);
// The maximum number of nibbles that the PLCA RS variable delay line
// can hold.
int delay_line_length = default(100);
// The transmit opportunity timer should be set equal across the mixing
// segment for PLCA to work properly.
int to_timer_length @unit(b) = default(32b);
// This timer determines how long to wait for the MAC to send a new packet
// before yielding the transmit opportunity. For PLCA burst mode to work
// properly this timer should be set greater than one IPG.
int burst_timer_length @unit(b) = default(128b);
// Times the duration of the BEACON signal.
int beacon_timer_length @unit(b) = default(20b);
// Timer for detecting received BEACONs.
int beacon_det_timer_length @unit(b) = default(22b);
// Defines the time the PLCA Data state diagram waits in the DELAY_PENDING
// state before switching to PENDING state.
int pending_timer_length @unit(b) = default(512b);
// Defines the maximum time the PLCA Data state machine is allowed to stay
// in WAIT_MAC state.
int commit_timer_length @unit(b) = default(288b);
// emitted when the current transmit opportunity ID changes, the value
// is the node ID of the owner of the current transmit opportunity
@signal[curID](type=int);
// emitted when the incoming carrier signal changes, the value is 1 or 0
@signal[carrierSenseChanged](type=int);
// emitted when the incoming collision signal changes, the value is 1 or 0
@signal[collisionChanged](type=int);
// emitted when the state of the control state machine changes, the value is one of DISABLE, RESYNC, RECOVER, SEND_BEACON, SYNCING, WAIT_TO, EARLY_RECEIVE, COMMIT, YIELD, RECEIVE, TRANSMIT, BURST, ABORT, NEXT_TX_OPPORTUNITY
@signal[controlStateChanged](type=long);
// emitted when the state of the data state machine changes, the value is one of WAIT_IDLE, IDLE, RECEIVE, HOLD, COLLIDE, DELAY_PENDING, PENDING, WAIT_MAC, TRANSMIT
@signal[dataStateChanged](type=long);
// emitted when the value of the rx_cmd variable changes, the value is one of NONE, BEACON, COMMIT
@signal[rxCmd](type=long);
// emitted when the value of the tx_cmd variable changes, the value is one of NONE, BEACON, COMMIT
@signal[txCmd](type=long);
// emitted when a packet is sent to the PHY, the value is the delay from when the packet was received from the MAC
@signal[packetPendingDelay](type=simtime_t);
// emitted when a packet is sent to the PHY, the value is the time elapsed since the last packet was sent
@signal[packetInterval](type=simtime_t);
// emitted when a transmit opportunity starts, the value is 1 or 0
@signal[transmitOpportunityUsed](type=int);
// emitted when a transmit opportunity ends for any node, the value is the number of packets sent or received during the transmit opportunity
@signal[numPacketsPerTo](type=int);
// emitted when a transmit opportunity ends for this node, the value is the number of packets sent during the transmit opportunity
@signal[numPacketsPerOwnTo](type=int);
// emitted when a cycle ends, the value is the number of packets sent or received during the cycle
@signal[numPacketsPerCycle](type=int);
// emitted when a transmit opportunity ends for any node, the value is the duration of the transmit opportunity
@signal[toLength](type=simtime_t);
// emitted when a transmit opportunity ends for this node, the value is the duration of the transmit opportunity
@signal[ownToLength](type=simtime_t);
// emitted when a cycle ends, the value is the duration of the cycle
@signal[cycleLength](type=simtime_t);
@signal[packetSentToLower](type=inet::Packet);
@signal[packetReceivedFromLower](type=inet::Packet);
// the time evolution of the current transmit opportunity ID
@statistic[curID](title="current transmit opportunity ID"; record=vector; interpolationmode=sample-hold);
// the time evolution of the incoming carrier sense signal
@statistic[carrierSense](title="carrier sense"; type=int; source=carrierSenseChanged; record=count,vector; interpolationmode=sample-hold);
// the time evolution of the incoming collision signal
@statistic[collision](title="collision"; type=int; source=collisionChanged; record=count,vector; interpolationmode=sample-hold);
// the time evolution of the state of the control state machine
@statistic[controlState](title="control state"; type=enum; enum=DISABLE, RESYNC, RECOVER, SEND_BEACON, SYNCING, WAIT_TO, EARLY_RECEIVE, COMMIT, YIELD, RECEIVE, TRANSMIT, BURST, ABORT, NEXT_TX_OPPORTUNITY; source=controlStateChanged; record=count,vector; interpolationmode=sample-hold);
// the time evolution of the state of the data state machine
@statistic[dataState](title="data state"; type=enum; enum=WAIT_IDLE, IDLE, RECEIVE, HOLD, COLLIDE, DELAY_PENDING, PENDING, WAIT_MAC, TRANSMIT; source=dataStateChanged; record=count,vector; interpolationmode=sample-hold);
@statistic[rxCmd](title="RX command"; type=enum; enum=NONE, BEACON, COMMIT; record=count,vector; interpolationmode=sample-hold);
@statistic[txCmd](title="TX command"; type=enum; enum=NONE, BEACON, COMMIT; record=count,vector; interpolationmode=sample-hold);
@statistic[packetPendingDelay](title="packet pending delay"; unit=s; record=count,histogram,vector; interpolationmode=none);
@statistic[packetInterval](title="packet interval"; unit=s; record=count,histogram,vector; interpolationmode=none);
@statistic[transmitOpportunityUsed](title="transmit opportunity used"; record=count,vector; interpolationmode=none);
// the time evolution of the number of packets sent or received per transmit opportunity for any node
@statistic[numPacketsPerTo](title="number of packets per transmit opportunity"; record=vector; interpolationmode=none);
// the time evolution of the number of packets sent per transmit opportunity for this node
@statistic[numPacketsPerOwnTo](title="number of packets per transmit opportunity"; record=vector; interpolationmode=none);
// the time evolution of the number of packets sent or received per cycle
@statistic[numPacketsPerCycle](title="number of packets per cycle"; record=vector; interpolationmode=none);
// the time evolution of the transmit opportunity length for any node
@statistic[toLength](title="transmit opportunity length"; record=vector; interpolationmode=none);
// the time evolution of the transmit opportunity length for any node
@statistic[ownToLength](title="own transmit opportunity length"; record=vector; interpolationmode=none);
// the time evolution of the cycle length
@statistic[cycleLength](title="cycle length"; record=vector; interpolationmode=none);
displayStringTextFormat = default("{curID}/{plca_node_count} ({local_nodeID})\n{controlFsmState} - {dataFsmState}");
@display("i=block/rxtx");
gates:
input upperLayerIn @labels(EtherFrame);
output upperLayerOut @labels(EtherFrame);
input lowerLayerIn @labels(EtherFrame);
output lowerLayerOut @labels(EtherFrame);
}