1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
#pragma once
#include <systemc.h>
#include <fstream>
#include <algorithm>
#include <vector>
#include <utility>
#include "strutils.h"
#include "optical_output_port.h"
#include "optical_signal.h"
#include "specs.h"
#include "spx_module.h"
using std::vector;
using std::pair;
class VLSource : public spx_module {
public:
typedef pair<double, spx::oa_value_type> time_value_pair_type;
// Ports
spx::oa_port_out_type p_out;
// Timed ports writers
OpticalOutputPort m_out_writer;
// Signal to emit
vector<time_value_pair_type> m_values_queue;
// Source emission control
spx::ed_signal_type enable;
// Processes
void runner();
VLSource(sc_module_name name, const vector<time_value_pair_type> &values = {})
: spx_module(name)
, m_out_writer((string(this->name()) + "_out_writer").c_str(), p_out)
, m_values_queue(values)
{
sortValues();
enable = sc_logic(0);
SC_HAS_PROCESS(VLSource);
SC_THREAD(runner);
}
void setValues(const vector<time_value_pair_type> &values)
{
m_values_queue = values;
sortValues();
}
void setValues(const string &filename)
{
std::ifstream file(filename);
if (!file.is_open()) {
cerr << "Error: Cannot open the file." << endl;
exit(1);
}
string line;
getline(file, line);
int lineNumber = 0;
while (getline(file, line)) {
++lineNumber;
istringstream s(line);
string field;
double t, P, WL;
// Skip if line is empty or starts with ;
if (line.empty())
{
cout << "Skipping empty line." << endl;
continue;
}
// Skip if line starts with ;
if (line[0] == ';')
{
cout << "Skipping commented line: " << line << endl;
continue;
}
// Read first field (time)
getline(s, field, ',');
strutils::trim(field);
// Skip header line if it exists
if(lineNumber == 1 && field == "time")
{
cout << "Skipping header line: " << line << endl;
continue;
}
try {
t = stod(field);
} catch (std::invalid_argument const& ex) {
cerr << "Invalid value for time: \"" << field << "\"" << endl;
exit(1);
}
// Read second field (P)
getline(s, field, ',');
try {
P = stod(field);
} catch (std::invalid_argument const& ex) {
cerr << "Invalid value for power: \"" << field << "\"" << endl;
exit(1);
}
// Read wavelength (WL)
std::getline(s, field);
try {
WL = stod(field);
} catch (std::invalid_argument const& ex) {
cerr << "Invalid value for wavelength: \"" << field << "\"" << endl;
exit(1);
}
cout << t << ": " << P << "W @" << WL*1e9 << "nm" << endl;
m_values_queue.emplace_back(t, OpticalSignal(sqrt(P), WL));
}
file.close();
sortValues();
}
void sortValues()
{
auto cmp = [](const time_value_pair_type& p1, const time_value_pair_type& p2) {
return p1.first < p2.first;
};
// Stable sort will keep initial ordering for values with identical time
std::stable_sort(m_values_queue.begin(), m_values_queue.end(), cmp);
}
};
|