aboutsummaryrefslogtreecommitdiff
path: root/src/devices/directional_coupler.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/directional_coupler.h')
-rw-r--r--src/devices/directional_coupler.h133
1 files changed, 133 insertions, 0 deletions
diff --git a/src/devices/directional_coupler.h b/src/devices/directional_coupler.h
new file mode 100644
index 0000000..1e907a6
--- /dev/null
+++ b/src/devices/directional_coupler.h
@@ -0,0 +1,133 @@
+#pragma once
+
+#include <systemc.h>
+#include <map>
+#include <optical_output_port.h>
+#include <optical_signal.h>
+#include "spx_module.h"
+
+
+class DirectionalCouplerBase : public spx_module {
+public:
+ // Member variables
+ double m_delay_ns = 0;
+ double m_through_phase_rad = 0;
+ double m_cross_phase_rad = M_PI/2;
+ double m_dc_through_coupling_power;
+
+ double m_through_power_dB;
+ double m_cross_power_dB;
+ double m_dc_loss; // is in dB
+
+ // Constructor
+ DirectionalCouplerBase(sc_module_name name,
+ double dc_through_coupling_power = 0.5,
+ double dc_loss = 0)
+ : spx_module(name)
+ , m_dc_through_coupling_power(dc_through_coupling_power)
+ , m_dc_loss(dc_loss)
+ {
+ // nothing to do
+ }
+};
+
+class DirectionalCouplerUni : public DirectionalCouplerBase {
+public:
+ // Ports
+ spx::oa_port_in_type p_in1;
+ spx::oa_port_in_type p_in2;
+ spx::oa_port_out_type p_out1;
+ spx::oa_port_out_type p_out2;
+
+ // Timed ports writers
+ OpticalOutputPort m_out1_writer;
+ OpticalOutputPort m_out2_writer;
+
+ // Memory for multi-wavelength purposes
+ // maybe with vector it has better performance
+ std::map<uint32_t,OpticalSignal::field_type> m_memory_in1;
+ std::map<uint32_t,OpticalSignal::field_type> m_memory_in2;
+
+ // Processes
+ void on_port_in1_changed();
+ void on_port_in2_changed();
+
+ // Constructor
+ DirectionalCouplerUni(sc_module_name name,
+ double dc_through_coupling_power = 0.5,
+ double dc_loss = 0)
+ : DirectionalCouplerBase(name, dc_through_coupling_power, dc_loss)
+ , m_out1_writer("out1_delayed_writer", p_out1)
+ , m_out2_writer("out2_delayed_writer", p_out2)
+ {
+ SC_HAS_PROCESS(DirectionalCouplerUni);
+
+ SC_THREAD(on_port_in1_changed);
+ sensitive << p_in1;
+
+ SC_THREAD(on_port_in2_changed);
+ sensitive << p_in2;
+ }
+};
+
+typedef DirectionalCouplerUni DirectionalCoupler;
+
+class DirectionalCouplerBi : public DirectionalCouplerBase {
+public:
+ // Ports
+ /** The optical input ports. */
+ spx::oa_port_in_type p0_in;
+ spx::oa_port_in_type p1_in;
+ spx::oa_port_in_type p2_in;
+ spx::oa_port_in_type p3_in;
+
+ /** The optical output ports. */
+ spx::oa_port_out_type p0_out;
+ spx::oa_port_out_type p1_out;
+ spx::oa_port_out_type p2_out;
+ spx::oa_port_out_type p3_out;
+
+ // Timed ports writers
+ OpticalOutputPort m_p0_out_writer;
+ OpticalOutputPort m_p1_out_writer;
+ OpticalOutputPort m_p2_out_writer;
+ OpticalOutputPort m_p3_out_writer;
+
+ // Memory for multi-wavelength purposes
+ // maybe with vector it has better performance
+ std::map<uint32_t,OpticalSignal::field_type> m_memory_in0;
+ std::map<uint32_t,OpticalSignal::field_type> m_memory_in1;
+ std::map<uint32_t,OpticalSignal::field_type> m_memory_in2;
+ std::map<uint32_t,OpticalSignal::field_type> m_memory_in3;
+
+ // Processes
+ void on_p0_in_changed();
+ void on_p1_in_changed();
+ void on_p2_in_changed();
+ void on_p3_in_changed();
+
+ // Constructor
+ DirectionalCouplerBi(sc_module_name name,
+ double dc_through_coupling_power = 0.5,
+ double dc_loss = 0)
+ : DirectionalCouplerBase(name, dc_through_coupling_power, dc_loss)
+ , m_p0_out_writer("p0_out_delayed_writer", p0_out)
+ , m_p1_out_writer("p1_out_delayed_writer", p1_out)
+ , m_p2_out_writer("p2_out_delayed_writer", p2_out)
+ , m_p3_out_writer("p3_out_delayed_writer", p3_out)
+ {
+ SC_HAS_PROCESS(DirectionalCouplerBi);
+
+ SC_THREAD(on_p0_in_changed);
+ sensitive << p0_in;
+
+ SC_THREAD(on_p1_in_changed);
+ sensitive << p1_in;
+
+ SC_THREAD(on_p2_in_changed);
+ sensitive << p2_in;
+
+ SC_THREAD(on_p3_in_changed);
+ sensitive << p3_in;
+ }
+};