|
@@ -144,7 +144,8 @@ class OpticalChannel(layers.Layer):
|
|
|
lpf_cutoff=32e9,
|
|
lpf_cutoff=32e9,
|
|
|
rx_stddev=0.01,
|
|
rx_stddev=0.01,
|
|
|
sig_avg=0.5,
|
|
sig_avg=0.5,
|
|
|
- enob=10):
|
|
|
|
|
|
|
+ enob=10,
|
|
|
|
|
+ atten=0.2):
|
|
|
"""
|
|
"""
|
|
|
A channel model that simulates chromatic dispersion, non-linear photodiode detection, finite bandwidth of
|
|
A channel model that simulates chromatic dispersion, non-linear photodiode detection, finite bandwidth of
|
|
|
ADC/DAC as well as additive white gaussian noise in optical communication channels.
|
|
ADC/DAC as well as additive white gaussian noise in optical communication channels.
|
|
@@ -168,6 +169,7 @@ class OpticalChannel(layers.Layer):
|
|
|
self.rx_stddev = rx_stddev
|
|
self.rx_stddev = rx_stddev
|
|
|
self.sig_avg = sig_avg
|
|
self.sig_avg = sig_avg
|
|
|
self.enob = enob
|
|
self.enob = enob
|
|
|
|
|
+ self.total_atten = tf.cast(10**(-0.1*atten*fiber_length), dtype=tf.float32)
|
|
|
|
|
|
|
|
self.noise_layer = layers.GaussianNoise(self.rx_stddev)
|
|
self.noise_layer = layers.GaussianNoise(self.rx_stddev)
|
|
|
self.fiber_length_noise = layers.GaussianNoise(self.fiber_length_stddev)
|
|
self.fiber_length_noise = layers.GaussianNoise(self.fiber_length_stddev)
|
|
@@ -181,6 +183,12 @@ class OpticalChannel(layers.Layer):
|
|
|
self.freq = tf.convert_to_tensor(np.fft.fftfreq(self.num_of_samples, d=1/fs), dtype=tf.complex64)
|
|
self.freq = tf.convert_to_tensor(np.fft.fftfreq(self.num_of_samples, d=1/fs), dtype=tf.complex64)
|
|
|
# self.multiplier = tf.math.exp(0.5j*self.dispersion_factor*self.fiber_length*tf.math.square(2*math.pi*self.freq))
|
|
# self.multiplier = tf.math.exp(0.5j*self.dispersion_factor*self.fiber_length*tf.math.square(2*math.pi*self.freq))
|
|
|
|
|
|
|
|
|
|
+ def compute_snr(self):
|
|
|
|
|
+ average_optical_power = (2*self.sig_avg*self.total_atten) / 3
|
|
|
|
|
+ signal_var = self.rx_stddev**2
|
|
|
|
|
+
|
|
|
|
|
+ return 10*math.log(average_optical_power/signal_var)
|
|
|
|
|
+
|
|
|
def call(self, inputs, **kwargs):
|
|
def call(self, inputs, **kwargs):
|
|
|
# DAC LPF and noise
|
|
# DAC LPF and noise
|
|
|
dac_out = self.digitization_layer(inputs)
|
|
dac_out = self.digitization_layer(inputs)
|
|
@@ -191,7 +199,8 @@ class OpticalChannel(layers.Layer):
|
|
|
|
|
|
|
|
len = tf.cast(self.fiber_length_noise.call(self.fiber_length), dtype=tf.complex64)
|
|
len = tf.cast(self.fiber_length_noise.call(self.fiber_length), dtype=tf.complex64)
|
|
|
|
|
|
|
|
- multiplier = tf.math.exp(0.5j*self.dispersion_factor*len*tf.math.square(2*math.pi*self.freq))
|
|
|
|
|
|
|
+ # Applying fiber dispersion and attenuation
|
|
|
|
|
+ multiplier = self.total_atten * tf.math.exp(0.5j*self.dispersion_factor*len*tf.math.square(2*math.pi*self.freq))
|
|
|
|
|
|
|
|
disp_f = tf.math.multiply(val_f, multiplier)
|
|
disp_f = tf.math.multiply(val_f, multiplier)
|
|
|
disp_t = tf.signal.ifft(disp_f)
|
|
disp_t = tf.signal.ifft(disp_f)
|