Basic Concepts
WDMSim provides a platform for multi-microring lock sequence defined by the user - as we call it a custom arbiter. From a simplified OOP perspective, the simulator models each component with a dedicated class, such as microrings, lasers, arbiters, system-under-test, etc.
System Components
Each component in the system is designed to retain its local view of the system, and interact with other components through a logical interface. WDMSim provides a set of pre-defined model templates that are used to assemble the system-under-test during the simulation runtime. We explain the different tiers of system components below:
Barebone components are defined to encapsulate the core parameters, and are more for the stricter object-orientedness.
Microring: barebone microring parameter capsule (
wdmsim.models.ring_row.Ring)Laser: barebone laser parameter capsule (
wdmsim.models.laser_row.Laser)
Functional unit components model the component-level behaviors, mostly centric to updating the wavelength states (wdmsim.models.optical_wave.OpticalWave).
Optical ports are defined for the directivity of the light propagation (wdmsim.models.optical_port.OpticalPort).
Microring Row: microring array with ports (
wdmsim.models.ring_row.RingRxWDMandwdmsim.models.ring_row.RingRxWDMRow)Laser Grid: aggregated CW laser array with ports (
wdmsim.models.laser_row.LaserGrid)Tuner: local tuner for a single microring control (
wdmsim.models.tuner.Tuner)
System components are the top-level components that are built off the functional units or their interfaces. Note that some of the definitions may seem redundant, they are kept for the sake of modularity idiom where no single components overstep their physical boundaries.
RxSlice: microring + tuner slice (
wdmsim.models.rx_slice.RxSlice)Arbiter: arbiter controlling the slices with the implementing algorithm, see next section
System-Under-Test: assembled system-under-test for the allocation experiments (
wdmsim.models.system_under_test.SystemUnderTest)
Defining Arbiter
While other components are mostly passive in their interfaces, the arbiter has the distinct features of 1) controlling the system components, and 2) implementing the lock-step algorithm.
Subclassing the base arbiter class (wdmsim.arbiter.base_arbiter.BaseArbiter), the user can define their own algorithm.
In particular, a predefined set of instructions (wdmsim.arbiter.arbiter_instr.InstTemplate) provides a closed interface for the arbiter to interact with the attached slices.
This includes SearchInst, LockInst and UnlockInst instructions:
SearchInst: issues wavelength sweep on the target slice and updates the search table
LockInst: locks the slice to the target wavelength
UnlockInst: unlocks the slice
To implement a custom arbiter, the user can simply:
Subclass the BaseArbiter class
Override the
algorithm()method to implement the lock-step algorithmSet
end_stateorlock_error_stateto True to indicate the end of the lock sequence
After such instructions are issued in algorithm(), corresponding information is updated in the arbiter’s internal state (as ArbiterMemory) which the arbiter can decide the final allocation.
Using the interface allows the arbiter to operate without knowing the “absolute” wavelength state in floating-point values, and instead rely on the logical state of the system only.
However, as python allows any objects’ internals to be accessed, and as we also implemented a “backdoor” access to the tuner state (Tuner.search_wavelength), it is possible to write a code that operates on the absolute wavelength numbers.
Simulator Lock-Step Update
Lastly, we explain the lock-step update mechanism.
It is non-trivial to write an efficient state update mechanism, our update mechanism is designed to be simplistic since the major state update is only native to the system-level. A relaxed form of lock-step update is implemented in the SystemUnderTest and the BaseArbiter. Note that WDMSim is not designed to be waveform-accurate; if the user needs to simulate those details, they should consider using a more detailed simulator.
For example, inside SystemUnderTest.run_lock_sequence():
# First, arbiter advances by a tick
# Then, the internal wavelength state is updated by light propagation in the microrings
# which is then polled/used by any other components in the system
while self.arbiter.tick():
self.ring_wdm_row.propagate_wave()
At update, the arbiter should advance its FSM state by a tick. There are many ways to implement this state-machine behaviors in python, one of which is the state-machine pattern. However, we observed that the state-machine pattern easily becomes cumbersome and hard to write (with possible bloating classes corresponding to the number of states). Instead, we opted for a simpler approach: using yield to pause the execution of the algorithm at each tick.
See below snippets as an example implementation:
class ArbiterA(BaseArbiter):
def algorithm(self):
slice_sequence = [i for i in range(8)]
for slice_idx in slice_sequence:
# Issue a lock instruction to the target slice
LockInst(self, slice_idx, "least_significant", 0).run()
# Pause the execution and let the system update the wavelength states
yield
class ArbiterB(BaseArbiter):
def algorithm(self):
slice_sequence = [i for i in range(8)]
# Issue lock instructions to all slices at once
for slice_idx in slice_sequence:
LockInst(self, slice_idx, "least_significant", 0).run()
# System update is done at the end
yield
The yield statement marks the point where the arbiter pauses its execution and returns to the SystemUnderTest to update the wavelength states.
Here, ArbiterA locks the slices one by one, while ArbiterB locks all slices at once.
Using this style, a more complicated algorithm along with the arbitraty mix of SearchInst, LockInst and UnlockInst can be implemented in a more readable manner.
Better off, the user can freely use function-local variables and share between states, and implement a multi-level FSM using nested generators (in this case, caller should use yield from to call the callee, while callee should use either yield or return to return to the caller).
What’s Next?
In the next section, we will walk-through a simple run example of the WDMSim.