aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Zrounba <clement.zrounba@ec-lyon.fr>2023-12-07 10:47:23 +0000
committerClément Zrounba <clement.zrounba@ec-lyon.fr>2023-12-07 10:48:56 +0000
commit0e4b33a965e8eabb687ba07580be749e5f0ffe4c (patch)
treec5dfd6564a6b8809dd23aba06e5b165af7bbe766
parent4b1c60c90936b52093d287f59eb118f93bc82407 (diff)
downloadspecs-0e4b33a965e8eabb687ba07580be749e5f0ffe4c.tar.gz
specs-0e4b33a965e8eabb687ba07580be749e5f0ffe4c.zip
Add power meter element to measure DC optical power
This device replaces photodetector in cases where the DC power should be measured efficiently, without considering realistic effects (bandwidth, noise, responsivity...). * Syntax in netlist: `PWRnnnn <optical net>` * Parameters: none
-rw-r--r--src/devices/alldevices.h1
-rw-r--r--src/parser/parse_element.cpp44
-rw-r--r--src/parser/parse_element.h4
-rw-r--r--src/parser/parser.l6
-rw-r--r--src/parser/parser.y12
-rw-r--r--src/specs.cpp9
6 files changed, 73 insertions, 3 deletions
diff --git a/src/devices/alldevices.h b/src/devices/alldevices.h
index daa7ee1..ca1e4f3 100644
--- a/src/devices/alldevices.h
+++ b/src/devices/alldevices.h
@@ -32,6 +32,7 @@
#include <probe.h>
//#include <ring.h>
#include <time_monitor.h>
+#include <power_meter.h>
/** ******************************************* **/
/** Circuits **/
diff --git a/src/parser/parse_element.cpp b/src/parser/parse_element.cpp
index bbd284c..e03eee8 100644
--- a/src/parser/parse_element.cpp
+++ b/src/parser/parse_element.cpp
@@ -1134,6 +1134,50 @@ sc_module *MLProbeElement::create(ParseTreeCreationHelper &pt_helper) const
}
/** ******************************************* **/
+/** Power meter **/
+/** ******************************************* **/
+INSTANTIATE_AND_CONNECT_UNI(PowerMeterElement, pt_helper)
+{
+ element_type_uni *obj = new element_type_uni(name.c_str());
+
+ // connect p_in
+ pt_helper.connect_uni<spx::oa_signal_type>(obj->p_in, nets[0], AS_READER);
+
+ // return the module
+ return obj;
+}
+
+sc_module *PowerMeterElement::create(ParseTreeCreationHelper &pt_helper) const
+{
+ element_type_base *obj = nullptr;
+
+ // Verify number of nets
+ assert(nets.size() == n_nets);
+
+ // Verify number of positional args
+ assert(args.size() == 0);
+
+ // Create signals if they don't exist
+ pt_helper.create_signals(this);
+
+ // Create the object and connect ports to signals
+ INSTANTIATE(pt_helper, false);
+
+ // Parse positional args
+ // nothing
+
+ // Parse keyword arguments
+ for (auto &p: kwargs)
+ {
+ cerr << name << ": unknown keyword: " << p.first << endl;
+ exit(1);
+ }
+
+ return obj;
+}
+
+
+/** ******************************************* **/
/** Phase-change cell **/
/** ******************************************* **/
INSTANTIATE_AND_CONNECT_UNI(PCMCellElement, pt_helper)
diff --git a/src/parser/parse_element.h b/src/parser/parse_element.h
index ebd08ab..8bd3bf3 100644
--- a/src/parser/parse_element.h
+++ b/src/parser/parse_element.h
@@ -1,6 +1,7 @@
#pragma once
#include "alldevices.h"
+#include "power_meter.h"
#include "subcircuit_instance.h"
#include "parse_tree.h"
#include "specs.h"
@@ -95,6 +96,7 @@ DECLARE_UNIDIR_ELEMENT(PCMCellElement, "PCM CELL", PCMElement, 2);
DECLARE_UNIDIR_ELEMENT(PhotodetectorElement, "PHOTODETECTOR", Detector, 2);
DECLARE_UNIDIR_ELEMENT(ProbeElement, "PROBE", Probe, 1);
DECLARE_UNIDIR_ELEMENT(MLProbeElement, "MULTIWAVELENGTH PROBE", MLambdaProbe, 1);
+DECLARE_UNIDIR_ELEMENT(PowerMeterElement, "POWER METER", PowerMeter, 1);
// TODO: take care of subcircuit instance...
DECLARE_UNIDIR_ELEMENT(XElement, "SUBCIRCUIT", SubcircuitInstance, 1);
@@ -103,4 +105,4 @@ DECLARE_UNIDIR_ELEMENT(XElement, "SUBCIRCUIT", SubcircuitInstance, 1);
/** Undefine macros **/
/** ******************************************* **/
#undef DECLARE_UNIDIR_ELEMENT
-#undef DECLARE_BIDIR_ELEMENT \ No newline at end of file
+#undef DECLARE_BIDIR_ELEMENT
diff --git a/src/parser/parser.l b/src/parser/parser.l
index 04a820a..e104b56 100644
--- a/src/parser/parser.l
+++ b/src/parser/parser.l
@@ -450,6 +450,12 @@ string convert_special_char(char c)
return T_ELEM_PCMCELL;
}
+^PWR({ALPHA_PLUS_NUM})+ {
+ /* Power meter instance */
+ yylval_param->s_ptr = new string(yytext);
+ return T_ELEM_PWR_METER;
+}
+
^\.ASSIGN { return T_LOCAL_ASSIGNMENT; }
^\.PARAM { return T_LOCAL_ASSIGNMENT; }
^\.SAVE { return T_DIRECTIVE_SAVE; }
diff --git a/src/parser/parser.y b/src/parser/parser.y
index e8602a7..9208dc8 100644
--- a/src/parser/parser.y
+++ b/src/parser/parser.y
@@ -73,7 +73,7 @@ int yyerror(yyscan_t scanner, ParseTree *pt, const char *err);
%token <s_ptr> T_ELEM_CWSRC T_ELEM_VLSRC T_ELEM_EVLSRC
%token <s_ptr> T_ELEM_WG T_ELEM_COUPLER T_ELEM_MERGER T_ELEM_SPLITTER
%token <s_ptr> T_ELEM_PSHIFT T_ELEM_MZI T_ELEM_CROSSING T_ELEM_PCMCELL
-%token <s_ptr> T_ELEM_PROBE T_ELEM_MLPROBE T_ELEM_PDET
+%token <s_ptr> T_ELEM_PROBE T_ELEM_MLPROBE T_ELEM_PDET T_ELEM_PWR_METER
%token <s_ptr> T_ELEM_X
%token <i_val> T_ANALYSIS_OP T_ANALYSIS_DC T_ANALYSIS_TRAN
%token <i_val> T_DIRECTIVE_OPTIONS T_DIRECTIVE_NODESET
@@ -98,6 +98,7 @@ int yyerror(yyscan_t scanner, ParseTree *pt, const char *err);
%type <i_val> element.evlsrc
%type <i_val> element.probe
%type <i_val> element.mlprobe
+%type <i_val> element.power_meter
%type <i_val> element.pdet
%type <i_val> element.x
@@ -375,6 +376,14 @@ element.pdet: T_ELEM_PDET net.oa.in net.eanalog
}
;
+element.power_meter: T_ELEM_PWR_METER net.oa.in
+ {
+ $$ = cur_pt->register_element(new PowerMeterElement(*$1, {*$2}));
+ delete $1;
+ delete $2;
+ }
+;
+
element.x: T_ELEM_X
{
$$ = cur_pt->register_element(new XElement(*$1));
@@ -456,6 +465,7 @@ atomelement: element.wg { $$ = $1; }
| element.evlsrc { $$ = $1; }
| element.probe { $$ = $1; }
| element.mlprobe { $$ = $1; }
+ | element.power_meter { $$ = $1; }
| element.pdet { $$ = $1; }
;
diff --git a/src/specs.cpp b/src/specs.cpp
index c58fd10..7e2ccfb 100644
--- a/src/specs.cpp
+++ b/src/specs.cpp
@@ -12,6 +12,7 @@
#include <cw_source.h>
#include <probe.h>
#include <detector.h>
+#include <power_meter.h>
#include <generic_transmission_device.h>
using std::string;
@@ -303,7 +304,13 @@ void SPECSConfig::applyDefaultTraceFileToAllSignals() {
string detname = pdet->name();
cout << detname << endl;
pdet->trace(default_trace_file);
- //sc_trace(default_trace_file, , (string(pdet->name()) + ".readout").c_str());
+ }
+
+ auto all_pwr_meters = sc_get_all_object_by_type<PowerMeter>();
+ for (auto &pwr_meter: all_pwr_meters) {
+ string pwr_meter_name = pwr_meter->name();
+ cout << pwr_meter_name << endl;
+ pwr_meter->trace(default_trace_file);
}
}