From ae2cad64f4744b13a9e776c087da227dc13d9104 Mon Sep 17 00:00:00 2001 From: couriersud Date: Thu, 7 Nov 2019 20:25:51 +0100 Subject: netlist: code and documentation maintenance fixes. [Couriersud] - "nltool -c docheader" now scans sources and creates usage focussed doxy documentation for devices. Very early stage, but works. For an example, please see ne555 source. - Started migrating to pure C++, i.e. "//" comments. - Various documentation fixes. - Added cppcheck configuration to netlist/build - Some smaller code changes. --- src/lib/netlist/analog/nld_bjt.cpp | 4 +- src/lib/netlist/analog/nld_mosfet.cpp | 30 +- src/lib/netlist/analog/nld_opamps.cpp | 8 +- src/lib/netlist/build/doxygen.conf | 9 +- src/lib/netlist/build/makefile | 2 +- src/lib/netlist/devices/nld_7493.cpp | 64 ++- src/lib/netlist/devices/nld_ne555.cpp | 95 +++-- src/lib/netlist/devices/nld_system.cpp | 57 +-- src/lib/netlist/devices/nlid_system.h | 70 +++- src/lib/netlist/documentation/primer_1.dox.h | 4 +- src/lib/netlist/documentation/structure.dox.h | 34 +- src/lib/netlist/macro/nlm_base.h | 3 + src/lib/netlist/macro/nlm_cd4xxx.h | 3 + src/lib/netlist/netlist.cppcheck | 26 ++ src/lib/netlist/nl_base.cpp | 2 +- src/lib/netlist/nl_base.h | 550 +++++++++++++------------- src/lib/netlist/nl_config.h | 152 +++---- src/lib/netlist/nl_errstr.h | 2 + src/lib/netlist/nl_setup.h | 8 +- src/lib/netlist/prg/nltool.cpp | 186 ++++++++- 20 files changed, 809 insertions(+), 500 deletions(-) create mode 100644 src/lib/netlist/netlist.cppcheck (limited to 'src/lib') diff --git a/src/lib/netlist/analog/nld_bjt.cpp b/src/lib/netlist/analog/nld_bjt.cpp index 635225769fb..0785ba56b37 100644 --- a/src/lib/netlist/analog/nld_bjt.cpp +++ b/src/lib/netlist/analog/nld_bjt.cpp @@ -270,8 +270,8 @@ namespace analog nl_fptype m_alpha_f; nl_fptype m_alpha_r; - NETLIB_SUBXX(analog, C) m_CJE; - NETLIB_SUBXX(analog, C) m_CJC; + NETLIB_SUB_UPTR(analog, C) m_CJE; + NETLIB_SUB_UPTR(analog, C) m_CJC; }; diff --git a/src/lib/netlist/analog/nld_mosfet.cpp b/src/lib/netlist/analog/nld_mosfet.cpp index bb3116a6960..78f4b4df615 100644 --- a/src/lib/netlist/analog/nld_mosfet.cpp +++ b/src/lib/netlist/analog/nld_mosfet.cpp @@ -59,38 +59,38 @@ namespace analog * | |Cbd | Zero-bias B-D junction capacitance |F|0|20f| * | |Cbs | Zero-bias B-S junction capacitance |F|0|20f| * | Y |Is | Bulk junction saturation current |A|0.00000000000001|1E-015| - * | Y |N | Bulk diode emission coefficient |-|1|* - * | |Pb | Bulk junction potential |V|0.8|0.87|8| + * | Y |N | Bulk diode emission coefficient |-|1|*| + * | |Pb | Bulk junction potential |V|0.8|0.87| * | Y |Cgso | Gate-source overlap capacitance per meter channel width |F/m|0|0.00000000004| - * | Y |Cgdo | Gate-drain overlap capacitance per meter channel width |F/m|0|0.00000000004|* - * | Y |Cgbo | Gate-bulk overlap capacitance per meter channel width |F/m|0|0.0000000002|* - * | |Rsh | Drain and source diffusion sheet resistance |W|0|10|* - * | |Cj | Zero-bias bulk junction bottom capacitance per square meter of junction area|F/m²|0|0.0002|* - * | |Mj | Bulk junction bottom grading coefficient |-|0.5|0.5|* - * | |Cjsw | Zero-bias bulk junction sidewall capacitance per meter of junction perimeter|F/m|0|1p|* + * | Y |Cgdo | Gate-drain overlap capacitance per meter channel width |F/m|0|0.00000000004*| + * | Y |Cgbo | Gate-bulk overlap capacitance per meter channel width |F/m|0|0.0000000002*| + * | |Rsh | Drain and source diffusion sheet resistance |W|0|10*| + * | |Cj | Zero-bias bulk junction bottom capacitance per square meter of junction area|F/m²|0|0.0002*| + * | |Mj | Bulk junction bottom grading coefficient |-|0.5|0.5*| + * | |Cjsw | Zero-bias bulk junction sidewall capacitance per meter of junction perimeter|F/m|0|1p*| * | |Mjsw | Bulk junction sidewall grading coefficient |-|.50 level 1 .33 level 2,3|| * | |Js | Bulk junction saturation current per square-meter of junction area|A/m|0|0.00000001| * | Y |Tox | Oxide thickness |m|0.0000001|0.0000001| * | Y |Nsub | Substrate doping |1/cm³|0|4000000000000000| * | |Nss | Surface state density |1/cm²|0|10000000000| - * | |Nfs | Fast surface state |1/cm²|0|10000000000|* - * | |TPG | Type of gate material: +1 opp. to substrate -1 same as substrate 0 Al gate|-|1| - * | |Xj | Metallurgical junction depth |m|0|1µ|* + * | |Nfs | Fast surface state |1/cm²|0|10000000000*| + * | |TPG | Type of gate material: +1 opp. to substrate -1 same as substrate |Al gate|-|1| + * | |Xj | Metallurgical junction depth |m|0|1µ*| * | Y |Ld | Lateral diffusion |m|0|0.8µ| * | Y |Uo | Surface mobility |cm²/V/s|600|700| * | |Ucrit | Critical field for mobility degradation (level 2 only) |V/cm|10000|10000| * | |Uexp | Critical field exponent in mobility degradation (level 2 only) |-|0|0.1| - * | |Utra | Transverse field coefficient (level 2 only) |-|0|0.3|* + * | |Utra | Transverse field coefficient (level 2 only) |-|0|0.3*| * | |Vmax | Maximum carrier drift velocity (levels 2 & 3 only) |m/s|0|50000| * | |Neff | Total channel-charge exponent (level 2 only) |-|1|5| * | |Kf | Flicker noise coefficient |-|0|1E-026| * | |Af | Flicker noise exponent |-|1|1.2| - * | |Fc | Coefficient for forward-bias depletion capacitance formula |-|0.5| + * | |Fc | Coefficient for forward-bias depletion capacitance formula |-|0.5|| * | |Delta | Width effect on threshold voltage(levels 2 and 3) |-|0|1| * | |Theta | Mobility modulation (level 3 only) |-|0|0.1| * | |Eta | Static feedback (level 3 only) |-|0|1| - * | |Kappa | Saturation field (level 3 only) |0.2|0.5| - * | |Tnom | Parameter measurement temperature |ºC|27|50|| + * | |Kappa | Saturation field (level 3 only) |-|0.2|0.5| + * | |Tnom | Parameter measurement temperature |ºC|27|50| * | Y |L | Length scaling |-|100e-6|| * | Y |W | Width scaling |-|100e-6|| * */ diff --git a/src/lib/netlist/analog/nld_opamps.cpp b/src/lib/netlist/analog/nld_opamps.cpp index e2d7d5d4cb7..ac21037671f 100644 --- a/src/lib/netlist/analog/nld_opamps.cpp +++ b/src/lib/netlist/analog/nld_opamps.cpp @@ -179,10 +179,10 @@ namespace netlist analog::NETLIB_SUB(R_base) m_RP; analog::NETLIB_SUB(VCCS) m_G1; - NETLIB_SUBXX(analog, C) m_CP; - NETLIB_SUBXX(analog, VCVS) m_EBUF; - NETLIB_SUBXX(analog, D) m_DP; - NETLIB_SUBXX(analog, D) m_DN; + NETLIB_SUB_UPTR(analog, C) m_CP; + NETLIB_SUB_UPTR(analog, VCVS) m_EBUF; + NETLIB_SUB_UPTR(analog, D) m_DP; + NETLIB_SUB_UPTR(analog, D) m_DN; analog_input_t m_VCC; analog_input_t m_GND; diff --git a/src/lib/netlist/build/doxygen.conf b/src/lib/netlist/build/doxygen.conf index 6fb0b377e7b..6c592f3fdae 100644 --- a/src/lib/netlist/build/doxygen.conf +++ b/src/lib/netlist/build/doxygen.conf @@ -32,7 +32,7 @@ DOXYFILE_ENCODING = UTF-8 # title of most generated pages and in a few other places. # The default value is: My Project. -PROJECT_NAME = Netlist documentation +PROJECT_NAME = "Netlist documentation" # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version @@ -475,7 +475,7 @@ HIDE_UNDOC_MEMBERS = YES # has no effect if EXTRACT_ALL is enabled. # The default value is: NO. -HIDE_UNDOC_CLASSES = YES +HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend # (class|struct|union) declarations. If set to NO, these declarations will be @@ -771,7 +771,7 @@ WARN_LOGFILE = # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. -INPUT = .. ../analog ../documentation ../devices +INPUT = .. ../analog ../documentation ../devices ../macro # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses @@ -2019,7 +2019,7 @@ SEARCH_INCLUDES = YES # preprocessor. # This tag requires that the tag SEARCH_INCLUDES is set to YES. -INCLUDE_PATH = +INCLUDE_PATH = .. ../.. # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the @@ -2145,6 +2145,7 @@ DIA_PATH = HIDE_UNDOC_RELATIONS = YES + # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz (see: # http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent diff --git a/src/lib/netlist/build/makefile b/src/lib/netlist/build/makefile index 51f43550a8d..d2a9245de60 100644 --- a/src/lib/netlist/build/makefile +++ b/src/lib/netlist/build/makefile @@ -58,7 +58,7 @@ CC = g++ LD = @g++ MD = @mkdir RM = @rm -DOXYGEN = @doxygen +DOXYGEN = @./doxygen CLANG_TIDY = clang-tidy-9 TARGETS = nltool nlwav diff --git a/src/lib/netlist/devices/nld_7493.cpp b/src/lib/netlist/devices/nld_7493.cpp index 003c3291096..855bd8a3770 100644 --- a/src/lib/netlist/devices/nld_7493.cpp +++ b/src/lib/netlist/devices/nld_7493.cpp @@ -9,6 +9,67 @@ #include "netlist/nl_base.h" #include "nlid_system.h" +//- Identifier: TTL_7493_DIP +//- Title: 7493 Binary Counters +//- Description: +//- Each of these monolithic counters contains four master-slave +//- flip-flops and additional gating to provide a divide-by-two +//- counter and a three-stage binary counter for which the +//- count cycle length is divide-by-five for the 90A and divide-by-eight +//- for the 93A. +//- +//- All of these counters have a gated zero reset and the 90A +//- also has gated set-to-nine inputs for use in BCD nine’s complement +//- applications. +//- +//- To use their maximum count length (decade or four-bit binary), +//- the B input is connected to the Q A output. The input count pulses +//- are applied to input A and the outputs are as described in the +//- appropriate truth table. A symmetrical divide-by-ten count can be +//- obtained from the 90A counters by connecting the Q D output to the +//- A input and applying the input count to the B input which gives +//- a divide-by-ten square wave at output Q A. +//- +//- Pinalias: B,R01,R02,NC,VCC,NC,NC,QC,QB,GND,QD,QA,NC,A +//- Package: DIP +//- NamingConvention: Naming conventions follow National Semiconductor datasheet +//- Limitations: Internal resistor network currently fixed to 5k +//- more limitations +//- Example: ne555_astable.c,ne555_example +//- FunctionTable: +//- Counter Sequence +//- +//- | COUNT || QD | QC | QB | QA | +//- |------:||:--:|:--:|:--:|:--:| +//- | 0 || 0 | 0 | 0 | 0 | +//- | 1 || 0 | 0 | 0 | 1 | +//- | 2 || 0 | 0 | 1 | 0 | +//- | 3 || 0 | 0 | 1 | 1 | +//- | 4 || 0 | 1 | 0 | 0 | +//- | 5 || 0 | 1 | 0 | 1 | +//- | 6 || 0 | 1 | 1 | 0 | +//- | 7 || 0 | 1 | 1 | 1 | +//- | 8 || 1 | 0 | 0 | 0 | +//- | 9 || 1 | 0 | 0 | 1 | +//- | 10 || 1 | 0 | 1 | 0 | +//- | 11 || 1 | 0 | 1 | 1 | +//- | 12 || 1 | 1 | 0 | 0 | +//- | 13 || 1 | 1 | 0 | 1 | +//- | 14 || 1 | 1 | 1 | 0 | +//- | 15 || 1 | 1 | 1 | 1 | +//- +//- Note C Output QA is connected to input B +//- +//- Reset Count Function table +//- +//- | R01 | R02 | QD | QC | QB | QA | +//- |:---:|:---:|:--:|:--:|:--:|:--:| +//- | 1 | 1 | 0 | 0 | 0 | 0 | +//- | 0 | X | COUNT |||| +//- | X | 0 | COUNT |||| +//- +//- + namespace netlist { namespace devices @@ -115,9 +176,8 @@ namespace netlist } }; - NETLIB_DEVICE_IMPL(7493, "TTL_7493", "+CLKA,+CLKB,+R1,+R2,@VCC,@GND") NETLIB_DEVICE_IMPL(7493_dip, "TTL_7493_DIP", "") - } //namespace devices + } // namespace devices } // namespace netlist diff --git a/src/lib/netlist/devices/nld_ne555.cpp b/src/lib/netlist/devices/nld_ne555.cpp index 6a6834df5d5..59eed00b02d 100644 --- a/src/lib/netlist/devices/nld_ne555.cpp +++ b/src/lib/netlist/devices/nld_ne555.cpp @@ -1,48 +1,69 @@ // license:GPL-2.0+ // copyright-holders:Couriersud -/*! - * \file nld_NE555.cpp - * - * \page NE555 NE555: PRECISION TIMERS - * - * The Swiss army knife for timing purposes - * - * \section ne555_1 Synopsis - * - * \snippet devsyn.dox.h NE555 synopsis - * \snippet devsyn.dox.h NE555_DIP synopsis - * \section ne555_11 "C" Synopsis - * - * \snippet devsyn.dox.h NE555 csynopsis - * \snippet devsyn.dox.h NE555_DIP csynopsis - * - * For the \c NE555 use verbose pin assignments like \c name.TRIG or \c name.OUT. - * For the \c NE555_DIP use pin numbers like \c name.1. - * - * \section ne555_2 Connection Diagram - * - *
- *          +--------+
- *      GND |1  ++  8| VCC
- *     TRIG |2      7| DISCH
- *      OUT |3      6| THRES
- *    RESET |4      5| CONT
- *          +--------+
- *  
- * - * Naming conventions follow Texas Instruments datasheet +//- Identifier: NE555_DIP +//- Title: NE555 PRECISION TIMERS +//- Description: +//- These devices are precision timing circuits capable of producing accurate +//- time delays or oscillation. In the time-delay or monostable mode of +//- operation, the timed interval is controlled by a single external resistor +//- and capacitor network. In the astable mode of operation, the frequency and +//- duty cycle can be controlled independently with two external resistors and +//- a single external capacitor. +//- +//- The threshold and trigger levels normally are two-thirds and one-third, +//- respectively, of V CC. These levels can be altered by use of the +//- control-voltage terminal. When the trigger input falls below the trigger +//- level, the flip-flop is set and NC – No internal connection the output +//- goes high. If the trigger input is above the trigger level and the +//- threshold input is above the threshold level, the flip-flop is reset and +//- the output is low. The reset (RESET) input can override all other +//- inputs and can be used to initiate a new timing cycle. When RESET goes +//- low, the flip-flop is reset and the output goes low. When the output is low, +//- a low-impedance path is provided between discharge (DISCH) and ground. +//- +//- The output circuit is capable of sinking or sourcing current up to 200 mA. +//- Operation is specified for supplies of 5 V to 15 V. With a 5-V supply, +//- output levels are compatible with TTL inputs. +//- +//- The NE555 is characterized for operation from 0°C to 70°C. The SA555 is +//- characterized for operation from –40°C to 85°C. The SE555 is characterized +//- for operation over the full military range of –55°C to 125°C. +//- +//- Pinalias: GND,TRIG,OUT,RESET,CONT,THRES,DISCH,VCC +//- Package: DIP +//- NamingConvention: Naming conventions follow Texas instrument datasheet +//- Limitations: Internal resistor network currently fixed to 5k +//- Example: ne555_astable.c,ne555_example +//- FunctionTable: +//- +//- |RESET|TRIGGER VOLTAGE|THRESHOLD VOLTAGE|OUTPUT|DISCHARGE SWITCH| +//- |:---:|:-------------:|:---------------:|:----:|:--------------:| +//- |Low | Irrelevant | Irrelevant | Low | On | +//- |High | <1/3 VDD | Irrelevant | High | Off | +//- |High | >1/3 VDD | >2/3 VDD | Low | On | +//- |High | >1/3 VDD | <2/3 VDD | As previously established|| +//- + + +/* + * "Description: The Swiss army knife for timing purposes\n" + * " which has a ton of applications.\n" + * "DipAlias: GND,TRIG,OUT,RESET,VCC,DISCH,THRES,CONT\n" + * "Package: DIP\n" + * "NamingConvention: Naming conventions follow Texas Instruments datasheet\n" + * "Limitations: Internal resistor network currently fixed to 5k\n" + * " more limitations\n" + * "Function Table:\n" * - * \section ne555_3 Function Table + * Function table created from truthtable if missing. * - * Please refer to the datasheet. + * For package, refer to: * - * \section ne555_4 Limitations + * https://en.wikipedia.org/wiki/List_of_integrated_circuit_packaging_types * - * Internal resistor network currently fixed to 5k. + * Special case: GATE -> use symbolic names * - * \section ne555_5 Example - * \snippet ne555_astable.c ne555 example */ #include "nld_ne555.h" diff --git a/src/lib/netlist/devices/nld_system.cpp b/src/lib/netlist/devices/nld_system.cpp index 54ef14fa1d0..e81824cc1b9 100644 --- a/src/lib/netlist/devices/nld_system.cpp +++ b/src/lib/netlist/devices/nld_system.cpp @@ -11,8 +11,8 @@ namespace netlist { - namespace devices - { +namespace devices +{ // ---------------------------------------------------------------------------------------- // netlistparams // ---------------------------------------------------------------------------------------- @@ -60,53 +60,10 @@ namespace netlist m_feedback.m_delegate.set(&NETLIB_NAME(extclock)::clk2, this); } - // ----------------------------------------------------------------------------- - // nld_res_sw - // ----------------------------------------------------------------------------- - - NETLIB_RESET(res_sw) - { - m_last_state = 0; - m_R.set_R(m_ROFF()); - } - - NETLIB_UPDATE(res_sw) - { - const netlist_sig_t state = m_I(); - if (state != m_last_state) - { - m_last_state = state; - const nl_fptype R = state ? m_RON() : m_ROFF(); - - // FIXME: We only need to update the net first if this is a time stepping net - m_R.update(); - m_R.set_R(R); - m_R.solve_later(); - } - } - - /* ----------------------------------------------------------------------------- - * nld_function - * ----------------------------------------------------------------------------- */ - - NETLIB_RESET(function) - { - //m_Q.initial(0.0); - } - - NETLIB_UPDATE(function) - { - for (std::size_t i=0; i < static_cast(m_N()); i++) - { - m_vals[i] = (*m_I[i])(); - } - m_Q.push(m_compiled.evaluate(m_vals)); - } - - NETLIB_DEVICE_IMPL(dummy_input, "DUMMY_INPUT", "") - NETLIB_DEVICE_IMPL(frontier, "FRONTIER_DEV", "+I,+G,+Q") - NETLIB_DEVICE_IMPL(function, "AFUNC", "N,FUNC") + NETLIB_DEVICE_IMPL(dummy_input, "DUMMY_INPUT", "") + NETLIB_DEVICE_IMPL(frontier, "FRONTIER_DEV", "+I,+G,+Q") + NETLIB_DEVICE_IMPL(function, "AFUNC", "N,FUNC") NETLIB_DEVICE_IMPL(analog_input, "ANALOG_INPUT", "IN") NETLIB_DEVICE_IMPL(clock, "CLOCK", "FREQ") NETLIB_DEVICE_IMPL(varclock, "VARCLOCK", "FUNC") @@ -116,8 +73,8 @@ namespace netlist NETLIB_DEVICE_IMPL(gnd, "GND", "") NETLIB_DEVICE_IMPL(netlistparams, "PARAMETER", "") - NETLIB_DEVICE_IMPL(logic_input, "LOGIC_INPUT", "IN,FAMILY") + NETLIB_DEVICE_IMPL(logic_input, "LOGIC_INPUT", "IN,FAMILY") NETLIB_DEVICE_IMPL_ALIAS(logic_input_ttl, logic_input, "TTL_INPUT", "IN") - } //namespace devices +} // namespace devices } // namespace netlist diff --git a/src/lib/netlist/devices/nlid_system.h b/src/lib/netlist/devices/nlid_system.h index 65c0437c020..6d0d0325feb 100644 --- a/src/lib/netlist/devices/nlid_system.h +++ b/src/lib/netlist/devices/nlid_system.h @@ -351,11 +351,11 @@ namespace devices param_fp_t m_p_ROUT; }; - /* ----------------------------------------------------------------------------- - * nld_function - * - * FIXME: Currently a proof of concept to get congo bongo working - * ----------------------------------------------------------------------------- */ + // ----------------------------------------------------------------------------- + // nld_function + // + // FIXME: Currently a proof of concept to get congo bongo working + // ----------------------------------------------------------------------------- */ NETLIB_OBJECT(function) { @@ -378,9 +378,19 @@ namespace devices protected: - NETLIB_RESETI(); - NETLIB_UPDATEI(); + NETLIB_RESETI() + { + //m_Q.initial(0.0); + } + NETLIB_UPDATEI() + { + for (std::size_t i = 0; i < static_cast(m_N()); i++) + { + m_vals[i] = (*m_I[i])(); + } + m_Q.push(m_compiled.evaluate(m_vals)); + } private: param_int_t m_N; @@ -410,9 +420,28 @@ namespace devices register_subalias("2", m_R.m_N); } - NETLIB_RESETI(); + NETLIB_RESETI() + { + m_last_state = 0; + m_R.set_R(m_ROFF()); + } + + NETLIB_UPDATEI() + { + const netlist_sig_t state = m_I(); + if (state != m_last_state) + { + m_last_state = state; + const nl_fptype R = state ? m_RON() : m_ROFF(); + + // FIXME: We only need to update the net first if this is a time stepping net + m_R.update(); + m_R.set_R(R); + m_R.solve_later(); + } + } + //NETLIB_UPDATE_PARAMI(); - NETLIB_UPDATEI(); analog::NETLIB_SUB(R_base) m_R; logic_input_t m_I; @@ -420,7 +449,6 @@ namespace devices param_fp_t m_ROFF; private: - state_var m_last_state; }; @@ -435,19 +463,19 @@ namespace devices class nld_power_pins { public: - explicit nld_power_pins(device_t &owner, const pstring &sVCC = "VCC", - const pstring &sGND = "GND", bool force_analog_input = false) + explicit nld_power_pins(device_t &owner, const pstring &sVCC = sPowerVCC, + const pstring &sGND = sPowerGND, bool force_analog_input = false) { if (owner.state().setup().is_extended_validation() || force_analog_input) { - m_GND = plib::make_unique(owner, sGND, NETLIB_DELEGATE(power_pins, noop)); - m_VCC = plib::make_unique(owner, sVCC, NETLIB_DELEGATE(power_pins, noop)); + m_GND = pool().make_unique(owner, sGND, NETLIB_DELEGATE(power_pins, noop)); + m_VCC = pool().make_unique(owner, sVCC, NETLIB_DELEGATE(power_pins, noop)); } else { owner.create_and_register_subdevice(sPowerDevRes, m_RVG); - owner.register_subalias(sVCC, "_RVG.1"); - owner.register_subalias(sGND, "_RVG.2"); + owner.register_subalias(sVCC, pstring(sPowerDevRes) + ".1"); + owner.register_subalias(sGND, pstring(sPowerDevRes) + ".2"); } } @@ -455,15 +483,15 @@ namespace devices nl_fptype VCC() const NL_NOEXCEPT { return m_VCC->Q_Analog(); } nl_fptype GND() const NL_NOEXCEPT { return m_GND->Q_Analog(); } - NETLIB_SUBXX(analog, R) m_RVG; // dummy resistor between VCC and GND - private: void noop() { } - plib::unique_ptr m_VCC; // only used during validation or force_analog_input - plib::unique_ptr m_GND; // only used during validation or force_analog_input + unique_pool_ptr m_VCC; // only used during validation or force_analog_input + unique_pool_ptr m_GND; // only used during validation or force_analog_input + + NETLIB_SUB_UPTR(analog, R) m_RVG; // dummy resistor between VCC and GND }; -} //namespace devices +} // namespace devices } // namespace netlist #endif /* NLD_SYSTEM_H_ */ diff --git a/src/lib/netlist/documentation/primer_1.dox.h b/src/lib/netlist/documentation/primer_1.dox.h index 8df612e242d..33f0bf64759 100644 --- a/src/lib/netlist/documentation/primer_1.dox.h +++ b/src/lib/netlist/documentation/primer_1.dox.h @@ -1,6 +1,6 @@ /*! \page primer_1 nltool primer -## First example +# First example Let's start with a simple charge/discharge circuit. I denotes the input, O denotes the output. @@ -53,7 +53,7 @@ Next, run and enjoy the results. -##Recap +# Recap We have created our first netlist fragment. nltool was used to model the periodically forced charge/discharge circuit for 50ms. Finally we plotted both input diff --git a/src/lib/netlist/documentation/structure.dox.h b/src/lib/netlist/documentation/structure.dox.h index 41dd9507717..d284208a51b 100644 --- a/src/lib/netlist/documentation/structure.dox.h +++ b/src/lib/netlist/documentation/structure.dox.h @@ -1,20 +1,34 @@ -/*! The netlist namespace. - * All netlist related code is contained in the netlist namespace - */ +/// +/// \defgroup compiledefine Compilation defines +/// +/// Compilation defines can be specified using -DDEFINE=VALUE during compilation. +/// If this is not done, a default is set, e.g. +/// \code +/// #ifndef DEFINE +/// #define DEFINE (0) +/// #endif +/// \endcode +/// +/// The define statements below thus show the default value. +/// +///@{ +///@} + +/// \brief The netlist namespace. +/// All netlist related code is contained in the netlist namespace + namespace netlist { - /*! The netlist::devices namespace. - * All netlist devices are contained in the netlist::devices namespace. - */ + /// \brief The netlist::devices namespace. + /// All netlist devices are contained in the netlist::devices namespace. namespace devices { } - /*! Internal support classes you should not use in code using netlist api. - * This namespace contains all internal support classes not intended - * to be used outside of the core. - */ + /// \brief Internal support classes you should not use in code using netlist api. + /// This namespace contains all internal support classes not intended + /// to be used outside of the core. namespace detail { } diff --git a/src/lib/netlist/macro/nlm_base.h b/src/lib/netlist/macro/nlm_base.h index 6a88ad5a1be..2b5596b5410 100644 --- a/src/lib/netlist/macro/nlm_base.h +++ b/src/lib/netlist/macro/nlm_base.h @@ -3,6 +3,9 @@ #ifndef NLM_BASE_H_ #define NLM_BASE_H_ +/// \file nlm_base.h +/// + /* * Provide base environment for netlist * diff --git a/src/lib/netlist/macro/nlm_cd4xxx.h b/src/lib/netlist/macro/nlm_cd4xxx.h index d4d9c97fdc2..afb78706ea6 100644 --- a/src/lib/netlist/macro/nlm_cd4xxx.h +++ b/src/lib/netlist/macro/nlm_cd4xxx.h @@ -3,6 +3,9 @@ #ifndef NLD_CD4XXX_H_ #define NLD_CD4XXX_H_ +/// \file nlm_cd4xxx.h +/// + #include "netlist/nl_setup.h" /* diff --git a/src/lib/netlist/netlist.cppcheck b/src/lib/netlist/netlist.cppcheck new file mode 100644 index 00000000000..642815cb052 --- /dev/null +++ b/src/lib/netlist/netlist.cppcheck @@ -0,0 +1,26 @@ + + + Native + false + true + false + 10 + + + + + + + + + bsd + cppcheck-lib + gnu + posix + zlib + + + threadsafety + cert + + diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp index 85939d3c19c..4fabac4810e 100644 --- a/src/lib/netlist/nl_base.cpp +++ b/src/lib/netlist/nl_base.cpp @@ -943,7 +943,7 @@ namespace netlist { } - const pstring param_model_t::value_str(const pstring &entity) + pstring param_model_t::value_str(const pstring &entity) { return state().setup().models().value_str(str(), entity); } diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index 0260b096a8c..536f97f8106 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -1,14 +1,12 @@ // license:GPL-2.0+ // copyright-holders:Couriersud -/*! - * - * \file nl_base.h - * - */ #ifndef NLBASE_H_ #define NLBASE_H_ +/// \file nl_base.h +/// + #ifdef NL_PROHIBIT_BASEH_INCLUDE #error "nl_base.h included. Please correct." #endif @@ -34,24 +32,25 @@ // MACROS / New Syntax //============================================================ -/*! Construct a netlist device name */ +/// Construct a netlist device name #define NETLIB_NAME(chip) nld_ ## chip #define NETLIB_OBJECT_DERIVED(name, pclass) \ class NETLIB_NAME(name) : public NETLIB_NAME(pclass) -/*! Start a netlist device class. - * Used to start defining a netlist device class. - * The simplest device without inputs or outputs would look like this: - * - * NETLIB_OBJECT(some_object) - * { - * public: - * NETLIB_CONSTRUCTOR(some_object) { } - * }; - * - * Also refer to #NETLIB_CONSTRUCTOR. - */ +/// \brief Start a netlist device class. +/// +/// Used to start defining a netlist device class. +/// The simplest device without inputs or outputs would look like this: +/// +/// NETLIB_OBJECT(some_object) +/// { +/// public: +/// NETLIB_CONSTRUCTOR(some_object) { } +/// }; +/// +/// Also refer to #NETLIB_CONSTRUCTOR. + #define NETLIB_OBJECT(name) \ class NETLIB_NAME(name) : public device_t @@ -65,73 +64,87 @@ class NETLIB_NAME(name) : public device_t public: template NETLIB_NAME(cname)(CLASS &owner, const pstring &name, __VA_ARGS__) \ : NETLIB_NAME(pclass)(owner, name) -/*! Used to define the constructor of a netlist device. - * Use this to define the constructor of a netlist device. Please refer to - * #NETLIB_OBJECT for an example. - */ +/// \brief Used to define the constructor of a netlist device. +/// Use this to define the constructor of a netlist device. Please refer to +/// #NETLIB_OBJECT for an example. + #define NETLIB_CONSTRUCTOR(cname) \ private: detail::family_setter_t m_famsetter; \ public: template NETLIB_NAME(cname)(CLASS &owner, const pstring &name) \ : device_t(owner, name) - /*! Used to define the destructor of a netlist device. - * The use of a destructor for netlist device should normally not be necessary. - */ +/// \brief Used to define the destructor of a netlist device. +/// The use of a destructor for netlist device should normally not be necessary. + #define NETLIB_DESTRUCTOR(name) public: virtual ~NETLIB_NAME(name)() noexcept - /*! Define an extended constructor and add further parameters to it. - * The macro allows to add further parameters to a device constructor. This is - * normally used for sub-devices and system devices only. - */ +/// \brief Define an extended constructor and add further parameters to it. +/// The macro allows to add further parameters to a device constructor. This is +/// normally used for sub-devices and system devices only. + #define NETLIB_CONSTRUCTOR_EX(cname, ...) \ private: detail::family_setter_t m_famsetter; \ public: template NETLIB_NAME(cname)(CLASS &owner, const pstring &name, __VA_ARGS__) \ : device_t(owner, name) - /*! Add this to a device definition to mark the device as dynamic. - * - * If NETLIB_IS_DYNAMIC(true) is added to the device definition the device - * is treated as an analog dynamic device, i.e. #NETLIB_UPDATE_TERMINALSI - * is called on a each step of the Newton-Raphson step - * of solving the linear equations. - * - * You may also use e.g. NETLIB_IS_DYNAMIC(m_func() != "") to only make the - * device a dynamic device if parameter m_func is set. - */ +/// \brief Add this to a device definition to mark the device as dynamic. +/// +/// If NETLIB_IS_DYNAMIC(true) is added to the device definition the device +/// is treated as an analog dynamic device, i.e. \ref NETLIB_UPDATE_TERMINALSI +/// is called on a each step of the Newton-Raphson step +/// of solving the linear equations. +/// +/// You may also use e.g. NETLIB_IS_DYNAMIC(m_func() != "") to only make the +/// device a dynamic device if parameter m_func is set. +/// +/// \param expr boolean expression +/// #define NETLIB_IS_DYNAMIC(expr) \ public: virtual bool is_dynamic() const noexcept override { return expr; } - /*! Add this to a device definition to mark the device as a time-stepping device. - * - * You have to implement NETLIB_TIMESTEP in this case as well. Currently, only - * the capacitor and inductor devices uses this. - * - * You may also use e.g. NETLIB_IS_TIMESTEP(m_func() != "") to only make the - * device a dynamic device if parameter m_func is set. This is used by the - * Voltage Source element. - * - * Example: - * - * NETLIB_TIMESTEP_IS_TIMESTEP() - * NETLIB_TIMESTEPI() - * { - * // Gpar should support convergence - * const nl_fptype G = m_C.Value() / step + m_GParallel; - * const nl_fptype I = -G * deltaV(); - * set(G, 0.0, I); - * } - * - */ +/// \brief Add this to a device definition to mark the device as a time-stepping device. +/// +/// You have to implement NETLIB_TIMESTEP in this case as well. Currently, only +/// the capacitor and inductor devices uses this. +/// +/// You may also use e.g. NETLIB_IS_TIMESTEP(m_func() != "") to only make the +/// device a dynamic device if parameter m_func is set. This is used by the +/// Voltage Source element. +/// +/// Example: +/// +/// \code +/// NETLIB_TIMESTEP_IS_TIMESTEP() +/// NETLIB_TIMESTEPI() +/// { +/// // Gpar should support convergence +/// const nl_fptype G = m_C.Value() / step + m_GParallel; +/// const nl_fptype I = -G/// deltaV(); +/// set(G, 0.0, I); +/// } +/// \endcode + #define NETLIB_IS_TIMESTEP(expr) \ public: virtual bool is_timestep() const noexcept override { return expr; } - /*! Used to implement the time stepping code. - * - * Please see NETLIB_IS_TIMESTEP for an example. - */ +/// \brief Used to implement the time stepping code. +/// +/// Please see \ref NETLIB_IS_TIMESTEP for an example. + #define NETLIB_TIMESTEPI() \ public: virtual void timestep(const nl_fptype step) noexcept override +/// \brief Used to implement the body of the time stepping code. +/// +/// Used when the implementation is outside the class definition +/// +/// Please see \ref NETLIB_IS_TIMESTEP for an example. +/// +/// \param cname Name of object as given to \ref NETLIB_OBJECT +/// +#define NETLIB_TIMESTEP(cname) \ + void NETLIB_NAME(cname) :: timestep(nl_fptype step) noexcept + #define NETLIB_FAMILY(family) , m_famsetter(*this, family) #define NETLIB_DELEGATE(chip, name) nldelegate(&NETLIB_NAME(chip) :: name, this) @@ -142,10 +155,8 @@ class NETLIB_NAME(name) : public device_t #define NETLIB_UPDATE_PARAMI() virtual void update_param() noexcept override #define NETLIB_RESETI() virtual void reset() override -#define NETLIB_TIMESTEP(chip) void NETLIB_NAME(chip) :: timestep(nl_fptype step) noexcept - #define NETLIB_SUB(chip) nld_ ## chip -#define NETLIB_SUBXX(ns, chip) unique_pool_ptr< ns :: nld_ ## chip > +#define NETLIB_SUB_UPTR(ns, chip) unique_pool_ptr< ns :: nld_ ## chip > #define NETLIB_HANDLER(chip, name) void NETLIB_NAME(chip) :: name() NL_NOEXCEPT #define NETLIB_UPDATE(chip) NETLIB_HANDLER(chip, update) @@ -175,9 +186,9 @@ class NETLIB_NAME(name) : public device_t namespace netlist { - /*! Delegate type for device notification. - * - */ + /// \brief Delegate type for device notification. + /// + using nldelegate = plib::pmfp; // ----------------------------------------------------------------------------- @@ -212,19 +223,22 @@ namespace netlist // Exceptions //============================================================ - /*! Generic netlist exception. - * The exception is used in all events which are considered fatal. - */ + /// \brief Generic netlist exception. + /// The exception is used in all events which are considered fatal. + class nl_exception : public plib::pexception { public: - /*! Constructor. - * Allows a descriptive text to be assed to the exception - */ + /// \brief Constructor. + /// Allows a descriptive text to be assed to the exception + explicit nl_exception(const pstring &text //!< text to be passed ) : plib::pexception(text) { } + /// \brief Constructor. + /// Allows to use \ref plib::pfmt logic to be used in exception + template explicit nl_exception(const pstring &fmt //!< format to be used , Args&&... args //!< arguments to be passed @@ -232,10 +246,10 @@ namespace netlist : plib::pexception(plib::pfmt(fmt)(std::forward(args)...)) { } }; - /*! Logic families descriptors are used to create proxy devices. - * The logic family describes the analog capabilities of logic devices, - * inputs and outputs. - */ + /// \brief Logic families descriptors are used to create proxy devices. + /// The logic family describes the analog capabilities of logic devices, + /// inputs and outputs. + class logic_family_desc_t { public: @@ -258,7 +272,7 @@ namespace netlist nl_fptype R_low() const noexcept{ return m_R_low; } nl_fptype R_high() const noexcept{ return m_R_high; } - nl_fptype m_fixed_V; //!< For variable voltage families, specify 0. For TTL this would be 5. */ + nl_fptype m_fixed_V; //!< For variable voltage families, specify 0. For TTL this would be 5. nl_fptype m_low_thresh_PCNT; //!< low input threshhold offset. If the input voltage is below this value times supply voltage, a "0" input is signalled nl_fptype m_high_thresh_PCNT; //!< high input threshhold offset. If the input voltage is above the value times supply voltage, a "0" input is signalled nl_fptype m_low_VO; //!< low output voltage offset. This voltage is output if the ouput is "0" @@ -267,17 +281,17 @@ namespace netlist nl_fptype m_R_high; //!< high output resistance. Value of series resistor used for high output }; - /*! Base class for devices, terminals, outputs and inputs which support - * logic families. - * This class is a storage container to store the logic family for a - * netlist object. You will not directly use it. Please refer to - * #NETLIB_FAMILY to learn how to define a logic family for a device. - * - * All terminals inherit the family description from the device - * The default is the ttl family, but any device can override the family. - * For individual terminals, the family can be overwritten as well. - * - */ + /// \brief Base class for devices, terminals, outputs and inputs which support + /// logic families. + /// This class is a storage container to store the logic family for a + /// netlist object. You will not directly use it. Please refer to + /// \ref NETLIB_FAMILY to learn how to define a logic family for a device. + /// + /// All terminals inherit the family description from the device + /// The default is the ttl family, but any device can override the family. + /// For individual terminals, the family can be overwritten as well. + /// + class logic_family_t { public: @@ -292,21 +306,21 @@ namespace netlist const logic_family_desc_t *m_logic_family; }; - const logic_family_desc_t *family_TTL(); //*!< logic family for TTL devices. - const logic_family_desc_t *family_CD4XXX(); //*!< logic family for CD4XXX CMOS devices. - - /*! A persistent variable template. - * Use the state_var template to define a variable whose value is saved. - * Within a device definition use - * - * NETLIB_OBJECT(abc) - * { - * NETLIB_CONSTRUCTOR(abc) - * , m_var(*this, "myvar", 0) - * ... - * state_var m_var; - * } - */ + const logic_family_desc_t *family_TTL(); ///< logic family for TTL devices. + const logic_family_desc_t *family_CD4XXX(); ///< logic family for CD4XXX CMOS devices. + + /// \brief A persistent variable template. + /// Use the state_var template to define a variable whose value is saved. + /// Within a device definition use + /// + /// NETLIB_OBJECT(abc) + /// { + /// NETLIB_CONSTRUCTOR(abc) + /// , m_var(*this, "myvar", 0) + /// ... + /// state_var m_var; + /// } + template struct state_var { @@ -325,28 +339,32 @@ namespace netlist //! Move Constructor. constexpr state_var(state_var &&rhs) noexcept = default; //! Assignment operator to assign value of a state var. - C14CONSTEXPR state_var &operator=(const state_var &rhs) /*noexcept*/ = default; // OSX doesn't like noexcept + C14CONSTEXPR state_var &operator=(const state_var &rhs) = default; // OSX doesn't like noexcept //! Assignment move operator to assign value of a state var. C14CONSTEXPR state_var &operator=(state_var &&rhs) noexcept = default; //! Assignment operator to assign value of type T. C14CONSTEXPR state_var &operator=(const T &rhs) noexcept { m_value = rhs; return *this; } //! Assignment move operator to assign value of type T. C14CONSTEXPR state_var &operator=(T &&rhs) noexcept { std::swap(m_value, rhs); return *this; } - //! Return value of state variable. + //! Return non-const value of state variable. C14CONSTEXPR operator T & () noexcept { return m_value; } //! Return const value of state variable. constexpr operator const T & () const noexcept { return m_value; } + //! Return pointer to state variable. C14CONSTEXPR T * ptr() noexcept { return &m_value; } + //! Return const pointer to state variable. constexpr const T * ptr() const noexcept{ return &m_value; } private: T m_value; }; - /*! A persistent array template. - * Use this state_var template to define an array whose contents are saved. - * Please refer to \ref state_var. - */ + /// \brief A persistent array template. + /// Use this state_var template to define an array whose contents are saved. + /// Please refer to \ref state_var. + /// + /// \tparam C container class to use. + template struct state_container : public C { @@ -379,16 +397,16 @@ namespace netlist // State variables - predefined and c++11 non-optional // ----------------------------------------------------------------------------- - /*! predefined state variable type for uint8_t */ + /// \brief predefined state variable type for uint8_t using state_var_u8 = state_var; - /*! predefined state variable type for int8_t */ + /// \brief predefined state variable type for int8_t using state_var_s8 = state_var; - /*! predefined state variable type for uint32_t */ + /// \brief predefined state variable type for uint32_t using state_var_u32 = state_var; - /*! predefined state variable type for int32_t */ + /// \brief predefined state variable type for int32_t using state_var_s32 = state_var; - /*! predefined state variable type for sig_t */ + /// \brief predefined state variable type for sig_t using state_var_sig = state_var; namespace detail { @@ -423,31 +441,32 @@ namespace netlist // object_t // ----------------------------------------------------------------------------- - /*! The base class for netlist devices, terminals and parameters. - * - * This class serves as the base class for all device, terminal and - * objects. It provides new and delete operators to support e.g. pooled - * memory allocation to enhance locality. Please refer to \ref USE_MEMPOOL as - * well. - */ + /// \brief The base class for netlist devices, terminals and parameters. + /// + /// This class serves as the base class for all device, terminal and + /// objects. It provides new and delete operators to support e.g. pooled + /// memory allocation to enhance locality. Please refer to \ref NL_USE_MEMPOOL as + /// well. + class object_t { public: - /*! Constructor. - * - * Every class derived from the object_t class must have a name. - */ - explicit object_t(const pstring &aname /*!< string containing name of the object */) + /// \brief Constructor. + /// Every class derived from the object_t class must have a name. + /// + /// \param aname string containing name of the object + + explicit object_t(const pstring &aname) { props::add(this, aname); } COPYASSIGNMOVE(object_t, delete) - /*! return name of the object - * - * \returns name of the object. - */ + /// \brief return name of the object + /// + /// \returns name of the object. + pstring name() const noexcept { return props::get(this); @@ -490,30 +509,30 @@ namespace netlist // device_object_t // ----------------------------------------------------------------------------- - /*! Base class for all objects being owned by a device. - * - * Serves as the base class of all objects being owned by a device. - * - */ + /// \brief Base class for all objects being owned by a device. + /// + /// Serves as the base class of all objects being owned by a device. + /// + class device_object_t : public object_t { public: - /*! Constructor. - * - * \param dev device owning the object. - * \param name string holding the name of the device - */ + /// \brief Constructor. + /// + /// \param dev device owning the object. + /// \param name string holding the name of the device + device_object_t(core_device_t &dev, const pstring &name); - /*! returns reference to owning device. - * \returns reference to owning device. - */ + /// \brief returns reference to owning device. + /// \returns reference to owning device. + core_device_t &device() noexcept { return m_device; } const core_device_t &device() const noexcept { return m_device; } - /*! The netlist owning the owner of this object. - * \returns reference to netlist object. - */ + /// \brief The netlist owning the owner of this object. + /// \returns reference to netlist object. + netlist_state_t &state() noexcept; const netlist_state_t &state() const noexcept; @@ -528,11 +547,11 @@ namespace netlist // core_terminal_t // ----------------------------------------------------------------------------- - /*! Base class for all terminals. - * - * All terminals are derived from this class. - * - */ + /// \brief Base class for all terminals. + /// + /// All terminals are derived from this class. + /// + class net_t; @@ -559,14 +578,14 @@ namespace netlist COPYASSIGNMOVE(core_terminal_t, delete) - /*! The object type. - * \returns type of the object - */ + /// \brief The object type. + /// \returns type of the object + terminal_type type() const noexcept(false); - /*! Checks if object is of specified type. - * \param atype type to check object against. - * \returns true if object is of specified type else false. - */ + /// \brief Checks if object is of specified type. + /// \param atype type to check object against. + /// \returns true if object is of specified type else false. + bool is_type(const terminal_type atype) const noexcept { return (type() == atype); } void set_net(net_t *anet) noexcept { m_net = anet; } @@ -656,7 +675,7 @@ namespace netlist void add_to_active_list(core_terminal_t &term) noexcept; void remove_from_active_list(core_terminal_t &term) noexcept; - /* setup stuff */ + // setup stuff void add_terminal(core_terminal_t &terminal) noexcept(false); void remove_terminal(core_terminal_t &terminal) noexcept(false); @@ -664,7 +683,7 @@ namespace netlist bool is_logic() const noexcept; bool is_analog() const noexcept; - void rebuild_list(); /* rebuild m_list after a load */ + void rebuild_list(); // rebuild m_list after a load void move_connections(net_t &dest_net); std::vector &core_terms() noexcept { return m_core_terms; } @@ -677,23 +696,23 @@ namespace netlist #else void update_inputs() const noexcept { - /* nothing needs to be done */ + // nothing needs to be done } #endif protected: - /* only used for logic nets */ + // only used for logic nets netlist_sig_t Q() const noexcept { return m_cur_Q; } - /* only used for logic nets */ + // only used for logic nets void initial(netlist_sig_t val) noexcept { m_cur_Q = m_new_Q = val; update_inputs(); } - /* only used for logic nets */ + // only used for logic nets void set_Q_and_push(netlist_sig_t newQ, netlist_time delay) noexcept { if (newQ != m_new_Q) @@ -703,7 +722,7 @@ namespace netlist } } - /* only used for logic nets */ + // only used for logic nets void set_Q_time(netlist_sig_t newQ, netlist_time at) noexcept { if (newQ != m_new_Q) @@ -715,16 +734,16 @@ namespace netlist update_inputs(); } - /* internal state support - * FIXME: get rid of this and implement export/import in MAME - */ - /* only used for logic nets */ + // internal state support + // FIXME: get rid of this and implement export/import in MAME + + // only used for logic nets netlist_sig_t *Q_state_ptr() noexcept { return m_cur_Q.ptr(); } private: state_var m_new_Q; state_var m_cur_Q; - state_var m_in_queue; /* 0: not in queue, 1: in queue, 2: last was taken */ + state_var m_in_queue; // 0: not in queue, 1: in queue, 2: last was taken state_var m_next_scheduled_time; core_terminal_t * m_railterminal; @@ -851,28 +870,28 @@ namespace netlist // analog_input_t // ----------------------------------------------------------------------------- - /*! terminal providing analog input voltage. - * - * This terminal class provides a voltage measurement. The conductance against - * ground is infinite. - */ + /// \brief terminal providing analog input voltage. + /// + /// This terminal class provides a voltage measurement. The conductance against + /// ground is infinite. + class analog_input_t : public analog_t { public: - /*! Constructor */ - analog_input_t(core_device_t &dev, /*!< owning device */ - const pstring &aname, /*!< name of terminal */ - nldelegate delegate = nldelegate() /*!< delegate */ + /// \brief Constructor + analog_input_t(core_device_t &dev, ///< owning device + const pstring &aname, ///< name of terminal + nldelegate delegate = nldelegate() ///< delegate ); - /*! returns voltage at terminal. - * \returns voltage at terminal. - */ + /// \brief returns voltage at terminal. + /// \returns voltage at terminal. + nl_fptype operator()() const noexcept { return Q_Analog(); } - /*! returns voltage at terminal. - * \returns voltage at terminal. - */ + /// \brief returns voltage at terminal. + /// \returns voltage at terminal. + nl_fptype Q_Analog() const noexcept; }; @@ -977,7 +996,7 @@ namespace netlist param_type_t param_type() const noexcept(false); protected: - virtual ~param_t() noexcept = default; /* not intended to be destroyed */ + virtual ~param_t() noexcept = default; // not intended to be destroyed void update_param() noexcept; @@ -1026,7 +1045,7 @@ namespace netlist int m_param; }; - /* FIXME: these should go as well */ + // FIXME: these should go as well using param_logic_t = param_num_t; using param_int_t = param_num_t; using param_fp_t = param_num_t; @@ -1102,10 +1121,10 @@ namespace netlist param_model_t(device_t &device, const pstring &name, const pstring &val) : param_str_t(device, name, val) { } - const pstring value_str(const pstring &entity) /*const*/; - nl_fptype value(const pstring &entity) /*const*/; - const pstring type() /*const*/; - /* hide this */ + pstring value_str(const pstring &entity); + nl_fptype value(const pstring &entity); + const pstring type(); + // hide this void setTo(const pstring ¶m) = delete; protected: void changed() noexcept override; @@ -1174,7 +1193,7 @@ namespace netlist { if (++m_active_outputs == 1) { - if (m_stats/*NL_KEEP_STATISTICS*/) + if (m_stats) m_stats->m_stat_inc_active.inc(); inc_active(); } @@ -1192,12 +1211,12 @@ namespace netlist void set_hint_deactivate(bool v) noexcept { m_hint_deactivate = v; } bool get_hint_deactivate() const noexcept { return m_hint_deactivate; } - /* Has to be set in device reset */ + // Has to be set in device reset void set_active_outputs(int n) noexcept { m_active_outputs = n; } void set_default_delegate(detail::core_terminal_t &term); - /* stats */ + // stats struct stats_t { // NL_KEEP_STATISTICS @@ -1274,9 +1293,6 @@ namespace netlist struct family_setter_t { - /* clang will complain about an unused private field if - * a defaulted constructor is used - */ // NOLINTNEXTLINE(modernize-use-equals-default) family_setter_t(); family_setter_t(core_device_t &dev, const pstring &desc); @@ -1286,9 +1302,9 @@ namespace netlist template using timed_queue = plib::timed_queue_linear; - /* Use timed_queue_heap to use stdc++ heap functions instead of linear processing. - * This slows down processing by about 25% on a Kaby Lake. - */ + // Use timed_queue_heap to use stdc++ heap functions instead of linear processing. + /// This slows down processing by about 25% on a Kaby Lake. + //template //using timed_queue = timed_queue_heap; @@ -1297,9 +1313,9 @@ namespace netlist // queue_t // ----------------------------------------------------------------------------- - /* We don't need a thread-safe queue currently. Parallel processing of - * solvers will update inputs after parallel processing. - */ + // We don't need a thread-safe queue currently. Parallel processing of + /// solvers will update inputs after parallel processing. + class queue_t : //public timed_queue, false, NL_KEEP_STATISTICS>, public timed_queue, false>, @@ -1341,7 +1357,7 @@ namespace netlist using nets_collection_type = std::vector>; - /* need to preserve order of device creation ... */ + // need to preserve order of device creation ... using devices_collection_type = std::vector>>; netlist_state_t(const pstring &aname, netlist_t & anetlist, @@ -1361,27 +1377,25 @@ namespace netlist core_device_t *get_single_device(const pstring &classname, bool (*cc)(core_device_t *)) const; - /** - * @brief Get single device filtered by class and name - * - * @tparam C Device class for which devices will be returned - * @param name Name of the device - * - * @return pointers to device - */ + /// \brief Get single device filtered by class and name + /// + /// \tparam C Device class for which devices will be returned + /// \param name Name of the device + /// + /// \return pointers to device + template C *get_single_device(const pstring &name) const { return dynamic_cast(get_single_device(name, check_class)); } - /** - * @brief Get vector of devices - * - * @tparam C Device class for which devices will be returned - * - * @return vector with pointers to devices - */ + /// \brief Get vector of devices + /// + /// \tparam C Device class for which devices will be returned + /// + /// \return vector with pointers to devices + template inline std::vector get_device_list() { @@ -1395,7 +1409,7 @@ namespace netlist return tmp; } - /* logging and name */ + // logging and name pstring name() const noexcept { return m_name; } @@ -1407,7 +1421,7 @@ namespace netlist netlist_t &exec() { return m_netlist; } const netlist_t &exec() const { return m_netlist; } - /* state handling */ + // state handling plib::state_manager_t &run_state_manager() { return m_state; } template @@ -1427,14 +1441,13 @@ namespace netlist template void register_net(owned_pool_ptr &&net) { m_nets.push_back(std::move(net)); } - /** - * @brief Get device pointer by name - * - * - * @param name Name of the device - * - * @return core_device_t pointer if device exists, else nullptr - */ + /// \brief Get device pointer by name + /// + /// + /// \param name Name of the device + /// + /// \return core_device_t pointer if device exists, else nullptr + core_device_t *find_device(const pstring &name) { for (auto & d : m_devices) @@ -1443,15 +1456,14 @@ namespace netlist return nullptr; } - /** - * @brief Register device using owned_ptr - * - * Used to register owned devices. These are devices declared as objects - * in another devices. - * - * @param name Name of the device - * @param dev Device to be registered - */ + /// \brief Register device using owned_ptr + /// + /// Used to register owned devices. These are devices declared as objects + /// in another devices. + /// + /// \param name Name of the device + /// \param dev Device to be registered + template void register_device(const pstring &name, owned_pool_ptr &&dev) noexcept(false) { @@ -1466,28 +1478,26 @@ namespace netlist m_devices.insert(m_devices.end(), { name, std::move(dev) }); } - /** - * @brief Register device using unique_ptr - * - * Used to register devices. - * - * @param name Name of the device - * @param dev Device to be registered - */ + /// \brief Register device using unique_ptr + /// + /// Used to register devices. + /// + /// \param name Name of the device + /// \param dev Device to be registered + template void register_device(const pstring &name, unique_pool_ptr &&dev) { register_device(name, owned_pool_ptr(dev.release(), true, dev.get_deleter())); } - /** - * @brief Remove device - * - * Care needs to be applied if this is called to remove devices with - * sub-devices which may have registered state. - * - * @param dev Device to be removed - */ + /// \brief Remove device + /// + /// Care needs to be applied if this is called to remove devices with + /// sub-devices which may have registered state. + /// + /// \param dev Device to be removed + void remove_device(core_device_t *dev) { for (auto it = m_devices.begin(); it != m_devices.end(); it++) @@ -1503,7 +1513,7 @@ namespace netlist const setup_t &setup() const noexcept { return *m_setup; } // FIXME: make a postload member and include code there - void rebuild_lists(); /* must be called after post_load ! */ + void rebuild_lists(); // must be called after post_load ! static void compile_defines(std::vector> &defs); @@ -1513,7 +1523,7 @@ namespace netlist devices_collection_type & devices() noexcept { return m_devices; } const devices_collection_type & devices() const noexcept { return m_devices; } - /* sole use is to manage lifetime of family objects */ + // sole use is to manage lifetime of family objects std::unordered_map> m_family_cache; private: @@ -1529,7 +1539,7 @@ namespace netlist plib::unique_ptr m_setup; nets_collection_type m_nets; - /* sole use is to manage lifetime of net objects */ + // sole use is to manage lifetime of net objects devices_collection_type m_devices; @@ -1550,7 +1560,7 @@ namespace netlist virtual ~netlist_t() noexcept = default; - /* run functions */ + // run functions netlist_time time() const noexcept { return m_time; } @@ -1583,19 +1593,19 @@ namespace netlist m_queue.remove(elem); } - /* Control functions */ + // Control functions void stop(); void reset(); - /* state handling */ + // state handling plib::state_manager_t &run_state_manager() noexcept { return m_state->run_state_manager(); } - /* only used by nltool to create static c-code */ + // only used by nltool to create static c-code devices::NETLIB_NAME(solver) *solver() const noexcept { return m_solver; } - /* force late type resolution */ + // force late type resolution template nl_fptype gmin(X *solv = nullptr) const noexcept { @@ -1622,7 +1632,7 @@ namespace netlist plib::unique_ptr m_state; devices::NETLIB_NAME(solver) * m_solver; - /* mostly rw */ + // mostly rw PALIGNAS_CACHELINE() netlist_time m_time; devices::NETLIB_NAME(mainclock) * m_mainclock; @@ -1794,7 +1804,7 @@ namespace netlist { if (m_next_scheduled_time > exec().time()) { - m_in_queue = queue_status::QUEUED; /* pending */ + m_in_queue = queue_status::QUEUED; // pending exec().qpush(detail::queue_t::entry_t(m_next_scheduled_time, this)); } else @@ -1972,7 +1982,7 @@ namespace netlist { nl_assert(this->isRailNet()); - m_in_queue = queue_status::DELIVERED; /* mark as taken ... */ + m_in_queue = queue_status::DELIVERED; // mark as taken ... if (m_new_Q ^ m_cur_Q) process((m_new_Q << core_terminal_t::INP_LH_SHIFT) | (m_cur_Q << core_terminal_t::INP_HL_SHIFT), m_new_Q); @@ -2042,4 +2052,4 @@ namespace plib -#endif /* NLBASE_H_ */ +#endif // NLBASE_H_ diff --git a/src/lib/netlist/nl_config.h b/src/lib/netlist/nl_config.h index bbd32490c30..65c8052a95d 100644 --- a/src/lib/netlist/nl_config.h +++ b/src/lib/netlist/nl_config.h @@ -1,89 +1,82 @@ // license:GPL-2.0+ // copyright-holders:Couriersud -/*! - * - * \file nl_config.h - * - */ + +/// \file nl_config.h +/// #ifndef NLCONFIG_H_ #define NLCONFIG_H_ #include "plib/pconfig.h" -//============================================================ -// SETUP -//============================================================ - +/// \addtogroup compiledefine +/// @{ //============================================================ // GENERAL //============================================================ -/*! Make use of a memory pool for performance related objects. - * - * Set to 1 to compile netlist with memory allocations from a - * linear memory pool. This is based of the assumption that - * due to enhanced locality there will be less cache misses. - * Your mileage may vary. - * - */ +/// \brief Make use of a memory pool for performance related objects. +/// +/// Set to 1 to compile netlist with memory allocations from a +/// linear memory pool. This is based of the assumption that +/// due to enhanced locality there will be less cache misses. +/// Your mileage may vary. +/// + #ifndef NL_USE_MEMPOOL #define NL_USE_MEMPOOL (1) #endif -/*! Enable queue statistics. - * - * Queue statistics come at a performance cost. Although - * the cost is low, we disable them here since they are - * only needed during development. - * - */ +/// \brief Enable queue statistics. +/// +/// Queue statistics come at a performance cost. Although +/// the cost is low, we disable them here since they are +/// only needed during development. +/// + #ifndef NL_USE_QUEUE_STATS #define NL_USE_QUEUE_STATS (0) #endif -/*! Store input values in logic_terminal_t. - * - * Set to 1 to store values in logic_terminal_t instead of - * accessing them indirectly by pointer from logic_net_t. - * This approach is stricter and should identify bugs in - * the netlist core faster. - * By default it is disabled since it is not as fast as - * the default approach. It is up to 10% slower. - * - */ +/// \brief Store input values in logic_terminal_t. +/// +/// Set to 1 to store values in logic_terminal_t instead of +/// accessing them indirectly by pointer from logic_net_t. +/// This approach is stricter and should identify bugs in +/// the netlist core faster. +/// By default it is disabled since it is not as fast as +/// the default approach. It is up to 10% slower. +/// + #ifndef NL_USE_COPY_INSTEAD_OF_REFERENCE #define NL_USE_COPY_INSTEAD_OF_REFERENCE (0) #endif -/*! Use the truthtable implementation of 7448 instead of the coded device - * - * FIXME: Using truthtable is a lot slower than the explicit device - * in breakout. Performance drops by 20%. This can be fixed by - * setting param USE_DEACTIVATE for the device. - */ +/// \brief Use the truthtable implementation of 7448 instead of the coded device +/// +/// FIXME: Using truthtable is a lot slower than the explicit device +/// in breakout. Performance drops by 20%. This can be fixed by +/// setting param USE_DEACTIVATE for the device. #ifndef NL_USE_TRUTHTABLE_7448 #define NL_USE_TRUTHTABLE_7448 (0) #endif -/*! Use the truthtable implementation of 74107 instead of the coded device - * - * FIXME: The truthtable implementation of 74107 (JK-Flipflop) - * is included for educational purposes to demonstrate how - * to implement state holding devices as truthtables. - * It will completely nuke performance for pong. - */ +/// \brief Use the truthtable implementation of 74107 instead of the coded device +/// +/// FIXME: The truthtable implementation of 74107 (JK-Flipflop) +/// is included for educational purposes to demonstrate how +/// to implement state holding devices as truthtables. +/// It will completely nuke performance for pong. #ifndef NL_USE_TRUTHTABLE_74107 #define NL_USE_TRUTHTABLE_74107 (0) #endif -/*! Use the __float128 type for matrix calculations. - * - * Defaults to PUSE_FLOAT128 - */ +/// \brief Use the __float128 type for matrix calculations. +/// +/// Defaults to \ref PUSE_FLOAT128 #ifndef NL_USE_FLOAT128 #define NL_USE_FLOAT128 PUSE_FLOAT128 @@ -93,6 +86,9 @@ // DEBUGGING //============================================================ +/// \brief Enable compile time debugging code +/// + #ifndef NL_DEBUG #define NL_DEBUG (false) //#define NL_DEBUG (true) @@ -102,37 +98,43 @@ // Time resolution //============================================================ -// Use nano-second resolution - Sufficient for now +/// \brief Resolution as clocks per second for timing +/// +/// Uses nano-second resolution - Sufficient for now static constexpr const auto NETLIST_INTERNAL_RES = 1000000000; + +// FIXME: Belongs into MAME netlist.h static constexpr const auto NETLIST_CLOCK = NETLIST_INTERNAL_RES; -/*! Floating point types used - * - * nl_fptype is the floating point type used throughout the - * netlist core. - * - * Don't change this! Simple analog circuits like pong - * work with float. Kidniki just doesn't work at all. - * - * FIXME: More work needed. Review magic numbers. - * - */ +/// @} + +/// \brief Floating point types used +/// +/// nl_fptype is the floating point type used throughout the +/// netlist core. +/// +/// Don't change this! Simple analog circuits like pong +/// work with float. Kidniki just doesn't work at all. +/// +/// FIXME: More work needed. Review magic numbers. +/// +/// using nl_fptype = double; namespace netlist { - /*! Specific constants depending on floating type - * - * @tparam FT floating point type: double/float - */ + /// \brief Specific constants depending on floating type + /// + /// @tparam FT floating point type: double/float + /// template struct fp_constants { }; - /*! Specific constants for long double floating point type - */ + /// \brief Specific constants for long double floating point type + /// template <> struct fp_constants { @@ -146,8 +148,8 @@ namespace netlist static inline constexpr const char * suffix() noexcept { return "L"; } }; - /*! Specific constants for double floating point type - */ + /// \brief Specific constants for double floating point type + /// template <> struct fp_constants { @@ -161,8 +163,8 @@ namespace netlist static inline constexpr const char * suffix() noexcept { return ""; } }; - /*! Specific constants for float floating point type - */ + /// \brief Specific constants for float floating point type + /// template <> struct fp_constants { @@ -177,8 +179,8 @@ namespace netlist }; #if (NL_USE_FLOAT128) - /*! Specific constants for __float128 floating point type - */ + /// \brief Specific constants for __float128 floating point type + /// template <> struct fp_constants<__float128> { diff --git a/src/lib/netlist/nl_errstr.h b/src/lib/netlist/nl_errstr.h index 4681d027d79..7f336385d4b 100644 --- a/src/lib/netlist/nl_errstr.h +++ b/src/lib/netlist/nl_errstr.h @@ -32,6 +32,8 @@ namespace netlist static constexpr const char sHINT_NO_DEACTIVATE[] = ".HINT_NO_DEACTIVATE"; static constexpr const char sPowerDevRes[] = "_RVG"; + static constexpr const char sPowerGND[] = "GND"; + static constexpr const char sPowerVCC[] = "VCC"; // nl_base.cpp diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h index 695c9553193..728a8e656d0 100644 --- a/src/lib/netlist/nl_setup.h +++ b/src/lib/netlist/nl_setup.h @@ -1,9 +1,9 @@ // license:GPL-2.0+ // copyright-holders:Couriersud -/* - * nlsetup.h - * - */ + +/// +/// \file nl_setup.h +/// #ifndef NLSETUP_H_ #define NLSETUP_H_ diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp index 0bfb324c607..31cbecf2bb4 100644 --- a/src/lib/netlist/prg/nltool.cpp +++ b/src/lib/netlist/prg/nltool.cpp @@ -9,6 +9,7 @@ ****************************************************************************/ #include "netlist/plib/pmain.h" +#include "netlist/plib/pstrutil.h" #include "netlist/devices/net_lib.h" #include "netlist/nl_errstr.h" #include "netlist/nl_parser.h" @@ -114,6 +115,18 @@ public: int execute() override; pstring usage() override; + template + void poutprefix(pstring prefix, pstring fmt, ARGS&&... args) + { + pstring res = plib::pfmt(fmt)(std::forward(args)...); + auto lines(plib::psplit(res, "\n", false)); + if (lines.size() == 0) + pout(prefix + "\n"); + else + for (auto &l : lines) + pout(prefix + l + "\n"); + } + int m_warnings; int m_errors; private: @@ -529,6 +542,103 @@ void tool_app_t::static_compile() } + + +/* "Description: The Swiss army knife for timing purposes\n" +* " which has a ton of applications.\n" +* "DipAlias: GND,TRIG,OUT,RESET,VCC,DISCH,THRES,CONT\n" +* "Package: DIP\n" +* "NamingConvention: Naming conventions follow Texas Instruments datasheet\n" +* "Limitations: Internal resistor network currently fixed to 5k\n" +* " more limitations\n" +* "FunctionTable:\n" +*/ + +struct doc_ext +{ + pstring id; + pstring title; + pstring description; + std::vector pinalias; + pstring package; + pstring namingconventions; + pstring limitations; + pstring functiontable; + std::vector example; +}; + +static doc_ext read_docsrc(const pstring &fname, const pstring &id) +{ + //printf("file %s\n", fname.c_str()); + plib::putf8_reader r = plib::putf8_reader(std::ifstream(plib::filesystem::u8path(fname))); + if (r.stream().fail()) + plib::pthrow(netlist::MF_FILE_OPEN_ERROR(fname)); + r.stream().imbue(std::locale::classic()); + doc_ext ret; + + pstring l; + if (!r.readline(l)) + return ret; + do + { + l = plib::trim(l); + if (plib::startsWith(l, "//-")) + { + l = plib::trim(l.substr(3)); + if (l != "") + { + auto a(plib::psplit(l, ":", true)); + if ((a.size() < 1) || (a.size() > 2)) + plib::pthrow(l+" size mismatch"); + pstring n(plib::trim(a[0])); + pstring v(a.size() < 2 ? "" : plib::trim(a[1])); + if (n == "Identifier") + { + ret.id = v; + if (!r.readline(l)) + return (ret.id == id ? ret : doc_ext()); + } + else + { + while (r.readline(l)) + { + l = plib::ltrim(l); + if (!(plib::startsWith(l, "//- ") || plib::startsWith(l, "//-\t")) + && !(plib::rtrim(l) == "//-")) + break; + v = v + "\n" + l.substr(3); + } + if (n == "Title") + ret.title = plib::trim(v); + else if (n == "Pinalias") + ret.pinalias = plib::psplit(plib::trim(v),",",true); + else if (n == "Description") + ret.description = v; + else if (n == "Package") + ret.package = plib::trim(v); + else if (n == "NamingConvention") + ret.namingconventions = v; + else if (n == "Limitations") + ret.limitations = v; + else if (n == "FunctionTable") + ret.functiontable = v; + else if (n == "Example") + { + ret.example = plib::psplit(plib::trim(v),",",true); + if (ret.example.size() != 2 && ret.example.size() != 0) + plib::pthrow("Example requires 2 parameters, but found {1}", ret.example.size()); + } + else + plib::pthrow(n); + } + } + } + else if (!r.readline(l)) + return (ret.id == id ? ret : doc_ext()); + } while (true); + //return ret; +} + void tool_app_t::mac_out(const pstring &s, const bool cont) { if (cont) @@ -674,9 +784,9 @@ void tool_app_t::create_docheader() pout(" *\n"); for (auto &s : devs) - pout(" * - \\subpage {1}\n", s); + pout(" * - @subpage {1}\n", s); - pout(" *\n"); + pout(" */\n"); for (auto &e : nt.setup().factory()) { @@ -687,6 +797,78 @@ void tool_app_t::create_docheader() mac(e.get()); pout("//! [{1} synopsis]\n", e->name()); } + + poutprefix("", ""); + poutprefix("///", ""); + //poutprefix("///", " @file "); + poutprefix("///", " @page '' "); // FIXME: snippets and pages need to be separate files + poutprefix("", ""); + + for (auto &e : nt.setup().factory()) + { + auto d(read_docsrc(e->sourcefile(), e->name())); + + if (d.id != "") + { + + poutprefix("///", ""); + //poutprefix("///", " @file {}", e->sourcefile()); + poutprefix("///", ""); + poutprefix("///", " @page {} {}", d.id, d.title); + poutprefix("///", ""); + poutprefix("///", " {}", d.description); + poutprefix("///", ""); + poutprefix("///", " @section {}_1 Synopsis", d.id); + poutprefix("///", ""); + poutprefix("///", " @snippet devsyn.dox.h {} synopsis", d.id); + poutprefix("///", ""); + poutprefix("///", " @section {}_11 C Synopsis", d.id); + poutprefix("///", ""); + poutprefix("///", " @snippet devsyn.dox.h {} csynopsis", d.id); + poutprefix("///", ""); + poutprefix("///", " @section {}_2 Connection Diagram", d.id); + poutprefix("///", ""); + + if (d.pinalias.size() > 0) + { + poutprefix("///", "
");
+				if (d.package == "DIP")
+				{
+					auto & pins = d.pinalias;
+					//const int w = 8;
+					poutprefix("///", " {1:10} +--------+", " ");
+					for (std::size_t i=0; i");
+			}
+			poutprefix("///", "");
+			poutprefix("///", "  {}", d.namingconventions);
+			poutprefix("///", "");
+			poutprefix("///", "  @section {}_3 Function Table", d.id);
+			poutprefix("///", "");
+			if (d.functiontable == "")
+				poutprefix("///", "  Please refer to the datasheet.");
+			else
+				poutprefix("///", "  {}", d.functiontable);
+			poutprefix("///", "");
+			poutprefix("///", "  @section {}_4 Limitations", d.id);
+			poutprefix("///", "");
+			poutprefix("///", "  {}", d.limitations);
+			if (d.example.size() > 0)
+			{
+				poutprefix("///", "");
+				poutprefix("///", "  @section {}_5 Example", d.id);
+				poutprefix("///", "  @snippet {1} {2}", d.example[0], d.example[1]);
+				poutprefix("///", "");
+				poutprefix("", "");
+			}
+		}
+	}
 	nt.stop();
 }
 
-- 
cgit v1.2.3