diff options
| author | Clément Zrounba <clement.zrounba@ec-lyon.fr> | 2023-11-23 18:49:56 +0000 |
|---|---|---|
| committer | Clément Zrounba <clement.zrounba@ec-lyon.fr> | 2023-11-23 18:56:41 +0000 |
| commit | 36505655a3f8e709b2ea91d43f08b32485d0659f (patch) | |
| tree | b656760f99f682ff0c08d6b2387eba07ade5dfed /src | |
| parent | 7a6345e2a4068de676e879e79f8c31965ecd0771 (diff) | |
| download | specs-36505655a3f8e709b2ea91d43f08b32485d0659f.tar.gz specs-36505655a3f8e709b2ea91d43f08b32485d0659f.zip | |
update PCM device and add parameters to parser
Diffstat (limited to 'src')
| -rw-r--r-- | src/devices/pcm_device.cpp | 21 | ||||
| -rw-r--r-- | src/devices/pcm_device.h | 33 | ||||
| -rw-r--r-- | src/parser/parse_element.cpp | 16 | ||||
| -rw-r--r-- | src/tb/pcm_device_tb.cpp | 4 |
4 files changed, 49 insertions, 25 deletions
diff --git a/src/devices/pcm_device.cpp b/src/devices/pcm_device.cpp index dc018da..f99b0f3 100644 --- a/src/devices/pcm_device.cpp +++ b/src/devices/pcm_device.cpp @@ -12,12 +12,14 @@ void PCMElement::on_input_changed() // setting the transmission for the initial state update_transmission_local(); - if (specsGlobalConfig.verbose_component_initialization) { cout << name() << ":" << endl; cout << "Emelt = " << m_meltEnergy*1e9 << " nJ" << endl; cout << "Nstates = " << m_nStates << "" << endl; + cout << "Tc = " << abs(m_Tc) << "W/W" << endl; + cout << "Ta = " << abs(m_Ta) << "W/W" << endl; + cout << "Initial state = " << m_stateCurrent << "" << endl; cout << (dynamic_cast<spx::oa_signal_type *>(p_in.get_interface()))->name(); cout << " --> "; cout << (dynamic_cast<spx::oa_signal_type *>(p_out.get_interface()))->name(); @@ -41,7 +43,7 @@ void PCMElement::on_input_changed() cur_wavelength_id = s.m_wavelength_id; m_memory_in[cur_wavelength_id] = s.m_field; - // Summing powers of all wavelengths + // Summing powers of all wavelengths (IGNORE heterodyne effects !) total_in_power = 0; for (auto lambdaID_field : m_memory_in) { @@ -83,7 +85,7 @@ void PCMElement::on_input_changed() m_last_pulse_power = total_in_power; // Write attenuated signal to output - s *= m_transmission; + s *= m_Tcurrent_field; s.getNewId(); m_out_writer.delayedWrite(s, SC_ZERO_TIME); @@ -105,7 +107,7 @@ bool PCMElement::phase_change(const vector<pulse_sample_t> &samples, const bool if (samples.empty()) return true; - if (sc_time_stamp().to_seconds() - samples.back().first < influence_time_ns*1e-9) + if (sc_time_stamp().to_seconds() - samples.back().first < m_influence_time_ns*1e-9) return true; if (local) @@ -119,11 +121,11 @@ bool PCMElement::phase_change(const vector<pulse_sample_t> &samples, const bool energy_absorbed += samples[i].second * dur_pulse; } // if enough energy and not saturated - if ((energy_absorbed > m_meltEnergy) && (m_state < m_nStates)) + if ((energy_absorbed > m_meltEnergy) && (m_stateCurrent < m_nStates)) { // cout << sc_time_stamp() << ": \n\t" << name() << " phase changed with " // << energy_absorbed*1e6 << " uJ" << endl; - m_state++; + m_stateCurrent++; // cout << "\tnew state: " << m_state << endl; update_transmission_local(); } @@ -139,12 +141,9 @@ bool PCMElement::phase_change(const vector<pulse_sample_t> &samples, const bool void PCMElement::update_transmission_local() { - double sp = 0.85; - double ep = 0.95; - double speed = 3; - m_transmission = sp+(ep-sp)*tanh(speed*m_state/m_nStates); + m_Tcurrent = m_Tc+(m_Ta-m_Tc)*tanh(m_speed*m_stateCurrent/m_nStates); // cout << "\tnew trans_power: " << m_transmission << "- W/W" << endl; // For field need to do a square root - m_transmission = sqrt(m_transmission); + m_Tcurrent_field = sqrt(m_Tcurrent); } diff --git a/src/devices/pcm_device.h b/src/devices/pcm_device.h index 4510591..f746ace 100644 --- a/src/devices/pcm_device.h +++ b/src/devices/pcm_device.h @@ -24,33 +24,46 @@ public: typedef pair<double,double> pulse_sample_t; // Member variables - double m_meltEnergy; - int m_state; - int m_nStates; - double m_transmission = 1; - double influence_time_ns = 1; + double m_Tc = 0; /* Transmission (power) in initial (fully crystalline) state */ + double m_Ta = 1; /* Transmission (power) in final (fully amorphous) state */ + double m_meltEnergy; /* Programming threshold*/ + int m_nStates; /* Total number of states */ + double m_influence_time_ns = 1; /* Duration for which energy is maintained (hard threshold for representing thermal losses)*/ + double m_speed = 3; /* Parameter affecting the transmission curve and how fast transmission saturates */ + + int m_stateCurrent = 0; /* Current state */ + double m_Tcurrent = 0; /* Current transmission (power) */ + double m_Tcurrent_field = 0; /* Current transmission (field) */ /** Current information about the optical input, before any attenuation and phase shift. */ - double m_last_pulse_power; + double m_last_pulse_power = 0; std::map<uint32_t,OpticalSignal::field_type> m_memory_in; - // Processes void on_input_changed(); + + // Member functions bool phase_change(const vector<pulse_sample_t> &vec, const bool &local); void update_transmission_local(); - // Constructor PCMElement(sc_module_name name, double meltEnergy = 0, int nStates = 0, - int state = 0) + int state = 0, + double Tc = 0, + double Ta = 0, + double influence_window_ns = 1, + double speed = 3) : spx_module(name) , m_out_writer("out_delayed_writer", p_out) + , m_Tc(Tc) + , m_Ta(Ta) , m_meltEnergy(meltEnergy) - , m_state(state) , m_nStates(nStates) + , m_influence_time_ns(influence_window_ns) + , m_speed(speed) + , m_stateCurrent(state) { SC_HAS_PROCESS(PCMElement); diff --git a/src/parser/parse_element.cpp b/src/parser/parse_element.cpp index 14de6e9..5997855 100644 --- a/src/parser/parse_element.cpp +++ b/src/parser/parse_element.cpp @@ -1169,16 +1169,28 @@ sc_module *PCMCellElement::create(ParseTreeCreationHelper &pt_helper) const obj->m_meltEnergy = args[0].as_double(); if(args.size() > 1) obj->m_nStates = args[1].as_integer(); + if(args.size() > 2) + obj->m_Tc = args[2].as_double(); + if(args.size() > 3) + obj->m_Ta = args[3].as_double(); // Parse keyword arguments for (auto &p: kwargs) { string kw = p.first; strutils::toupper(kw); - if (kw == "MELT_ENERGY" || kw == "EMELT") + if (kw == "MELT_ENERGY" || kw == "EMELT" || kw == "E_MELT") obj->m_meltEnergy = p.second.as_double(); - else if (kw == "N" || kw == "NSTATES") + else if (kw == "N" || kw == "NSTATES" || kw == "NLEVELS" || kw == "N_STATES" || kw == "N_LEVELS") obj->m_nStates = p.second.as_integer(); + else if (kw == "K" || kw == "INITIAL_STATE") + obj->m_stateCurrent = p.second.as_integer(); + else if (kw == "SP" || kw == "TC" || kw == "T_C") + obj->m_Tc = p.second.as_double(); + else if (kw == "EP" || kw == "TA" || kw == "T_A") + obj->m_Ta = p.second.as_double(); + else if (kw == "TANH_COEF") + obj->m_speed = p.second.as_double(); else { cerr << "Unknown keyword: " << p.first << endl; exit(1); diff --git a/src/tb/pcm_device_tb.cpp b/src/tb/pcm_device_tb.cpp index b279e6c..156bd67 100644 --- a/src/tb/pcm_device_tb.cpp +++ b/src/tb/pcm_device_tb.cpp @@ -89,7 +89,7 @@ void PCMElement_tb_run() spx::oa_signal_type IN, OUT; - PCMElement pcm("pcm", 25e-6, 63, 0); + PCMElement pcm("pcm", 25e-6, 63, 0, 0.85, 0.95); pcm.p_in(IN); pcm.p_out(OUT); @@ -117,7 +117,7 @@ void PCMElement_tb_run() specsGlobalConfig.prepareSimulation(); // extra traces should come after prepareSimulation - sc_trace(specsGlobalConfig.default_trace_file, pcm.m_state, "STATE"); + sc_trace(specsGlobalConfig.default_trace_file, pcm.m_stateCurrent, "STATE"); // Start simulation sc_start(); |
