mirror of
https://github.com/holub/mame
synced 2025-04-20 23:42:22 +03:00
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.
This commit is contained in:
parent
8564977f3b
commit
ae2cad64f4
@ -1,12 +1,12 @@
|
||||
// license:GPL-2.0+
|
||||
// copyright-holders:Couriersud
|
||||
|
||||
//! [ne555 example]
|
||||
/*
|
||||
* ne555_astable.c
|
||||
*
|
||||
*/
|
||||
|
||||
//! [ne555_example]
|
||||
#include "netlist/devices/net_lib.h"
|
||||
|
||||
NETLIST_START(ne555_astable)
|
||||
@ -16,14 +16,6 @@ NETLIST_START(ne555_astable)
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
*
|
||||
* abc | def
|
||||
* ghj | ddd
|
||||
* iop | xyz
|
||||
*
|
||||
*
|
||||
*/
|
||||
/* Standard stuff */
|
||||
|
||||
SOLVER(Solver, 48000)
|
||||
@ -58,4 +50,4 @@ NETLIST_START(ne555_astable)
|
||||
LOG(log3, 555.OUT)
|
||||
|
||||
NETLIST_END()
|
||||
//! [ne555 example]
|
||||
//! [ne555_example]
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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||
|
||||
* */
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -58,7 +58,7 @@ CC = g++
|
||||
LD = @g++
|
||||
MD = @mkdir
|
||||
RM = @rm
|
||||
DOXYGEN = @doxygen
|
||||
DOXYGEN = @./doxygen
|
||||
CLANG_TIDY = clang-tidy-9
|
||||
|
||||
TARGETS = nltool nlwav
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
//- 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"
|
||||
*
|
||||
* \snippet devsyn.dox.h NE555 csynopsis
|
||||
* \snippet devsyn.dox.h NE555_DIP csynopsis
|
||||
* Function table created from truthtable if missing.
|
||||
*
|
||||
* 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.
|
||||
* For package, refer to:
|
||||
*
|
||||
* \section ne555_2 Connection Diagram
|
||||
* https://en.wikipedia.org/wiki/List_of_integrated_circuit_packaging_types
|
||||
*
|
||||
* <pre>
|
||||
* +--------+
|
||||
* GND |1 ++ 8| VCC
|
||||
* TRIG |2 7| DISCH
|
||||
* OUT |3 6| THRES
|
||||
* RESET |4 5| CONT
|
||||
* +--------+
|
||||
* </pre>
|
||||
* Special case: GATE -> use symbolic names
|
||||
*
|
||||
* Naming conventions follow Texas Instruments datasheet
|
||||
*
|
||||
* \section ne555_3 Function Table
|
||||
*
|
||||
* Please refer to the datasheet.
|
||||
*
|
||||
* \section ne555_4 Limitations
|
||||
*
|
||||
* Internal resistor network currently fixed to 5k.
|
||||
*
|
||||
* \section ne555_5 Example
|
||||
* \snippet ne555_astable.c ne555 example
|
||||
*/
|
||||
|
||||
#include "nld_ne555.h"
|
||||
|
@ -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<unsigned>(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
|
||||
|
@ -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<unsigned>(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<netlist_sig_t> 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<analog_input_t>(owner, sGND, NETLIB_DELEGATE(power_pins, noop));
|
||||
m_VCC = plib::make_unique<analog_input_t>(owner, sVCC, NETLIB_DELEGATE(power_pins, noop));
|
||||
m_GND = pool().make_unique<analog_input_t>(owner, sGND, NETLIB_DELEGATE(power_pins, noop));
|
||||
m_VCC = pool().make_unique<analog_input_t>(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<analog_input_t> m_VCC; // only used during validation or force_analog_input
|
||||
plib::unique_ptr<analog_input_t> m_GND; // only used during validation or force_analog_input
|
||||
unique_pool_ptr<analog_input_t> m_VCC; // only used during validation or force_analog_input
|
||||
unique_pool_ptr<analog_input_t> 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_ */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
{
|
||||
}
|
||||
|
@ -3,6 +3,9 @@
|
||||
#ifndef NLM_BASE_H_
|
||||
#define NLM_BASE_H_
|
||||
|
||||
/// \file nlm_base.h
|
||||
///
|
||||
|
||||
/*
|
||||
* Provide base environment for netlist
|
||||
*
|
||||
|
@ -3,6 +3,9 @@
|
||||
#ifndef NLD_CD4XXX_H_
|
||||
#define NLD_CD4XXX_H_
|
||||
|
||||
/// \file nlm_cd4xxx.h
|
||||
///
|
||||
|
||||
#include "netlist/nl_setup.h"
|
||||
|
||||
/*
|
||||
|
26
src/lib/netlist/netlist.cppcheck
Normal file
26
src/lib/netlist/netlist.cppcheck
Normal file
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="1">
|
||||
<platform>Native</platform>
|
||||
<analyze-all-vs-configs>false</analyze-all-vs-configs>
|
||||
<check-headers>true</check-headers>
|
||||
<check-unused-templates>false</check-unused-templates>
|
||||
<max-ctu-depth>10</max-ctu-depth>
|
||||
<includedir>
|
||||
<dir name="plib/"/>
|
||||
<dir name="../"/>
|
||||
</includedir>
|
||||
<paths>
|
||||
<dir name="/mnt/mfhome/andre/mame/mamegit/src/lib/netlist"/>
|
||||
</paths>
|
||||
<libraries>
|
||||
<library>bsd</library>
|
||||
<library>cppcheck-lib</library>
|
||||
<library>gnu</library>
|
||||
<library>posix</library>
|
||||
<library>zlib</library>
|
||||
</libraries>
|
||||
<addons>
|
||||
<addon>threadsafety</addon>
|
||||
<addon>cert</addon>
|
||||
</addons>
|
||||
</project>
|
@ -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);
|
||||
}
|
||||
|
@ -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 <class CLASS> 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 <class CLASS> 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 <class CLASS> 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<void>;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -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<typename... Args>
|
||||
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>(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.
|
||||
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<unsigned> m_var;
|
||||
/// }
|
||||
|
||||
/*! 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<unsigned> m_var;
|
||||
* }
|
||||
*/
|
||||
template <typename T>
|
||||
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 <typename C>
|
||||
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<std::uint8_t>;
|
||||
/*! predefined state variable type for int8_t */
|
||||
/// \brief predefined state variable type for int8_t
|
||||
using state_var_s8 = state_var<std::int8_t>;
|
||||
|
||||
/*! predefined state variable type for uint32_t */
|
||||
/// \brief predefined state variable type for uint32_t
|
||||
using state_var_u32 = state_var<std::uint32_t>;
|
||||
/*! predefined state variable type for int32_t */
|
||||
/// \brief predefined state variable type for int32_t
|
||||
using state_var_s32 = state_var<std::int32_t>;
|
||||
/*! predefined state variable type for sig_t */
|
||||
/// \brief predefined state variable type for sig_t
|
||||
using state_var_sig = state_var<netlist_sig_t>;
|
||||
|
||||
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_terminal_t *> &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<netlist_sig_t> m_new_Q;
|
||||
state_var<netlist_sig_t> m_cur_Q;
|
||||
state_var<queue_status> m_in_queue; /* 0: not in queue, 1: in queue, 2: last was taken */
|
||||
state_var<queue_status> m_in_queue; // 0: not in queue, 1: in queue, 2: last was taken
|
||||
state_var<netlist_time> 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<bool>;
|
||||
using param_int_t = param_num_t<int>;
|
||||
using param_fp_t = param_num_t<nl_fptype>;
|
||||
@ -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 <class T, bool TS>
|
||||
using timed_queue = plib::timed_queue_linear<T, TS>;
|
||||
|
||||
/* 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 <class T, bool TS>
|
||||
//using timed_queue = timed_queue_heap<T, TS>;
|
||||
@ -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<pqentry_t<net_t *, netlist_time>, false, NL_KEEP_STATISTICS>,
|
||||
public timed_queue<plib::pqentry_t<net_t *, netlist_time>, false>,
|
||||
@ -1341,7 +1357,7 @@ namespace netlist
|
||||
|
||||
using nets_collection_type = std::vector<owned_pool_ptr<detail::net_t>>;
|
||||
|
||||
/* need to preserve order of device creation ... */
|
||||
// need to preserve order of device creation ...
|
||||
using devices_collection_type = std::vector<std::pair<pstring, owned_pool_ptr<core_device_t>>>;
|
||||
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<class C>
|
||||
C *get_single_device(const pstring &name) const
|
||||
{
|
||||
return dynamic_cast<C *>(get_single_device(name, check_class<C>));
|
||||
}
|
||||
|
||||
/**
|
||||
* @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<class C>
|
||||
inline std::vector<C *> 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<typename O, typename C>
|
||||
@ -1427,14 +1441,13 @@ namespace netlist
|
||||
template <typename T>
|
||||
void register_net(owned_pool_ptr<T> &&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 <typename T>
|
||||
void register_device(const pstring &name, owned_pool_ptr<T> &&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 <typename T>
|
||||
void register_device(const pstring &name, unique_pool_ptr<T> &&dev)
|
||||
{
|
||||
register_device(name, owned_pool_ptr<T>(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<std::pair<pstring, pstring>> &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<pstring, plib::unique_ptr<logic_family_desc_t>> m_family_cache;
|
||||
|
||||
private:
|
||||
@ -1529,7 +1539,7 @@ namespace netlist
|
||||
plib::unique_ptr<setup_t> 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<true>(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 <typename X = devices::NETLIB_NAME(solver)>
|
||||
nl_fptype gmin(X *solv = nullptr) const noexcept
|
||||
{
|
||||
@ -1622,7 +1632,7 @@ namespace netlist
|
||||
plib::unique_ptr<netlist_state_t> 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<KEEP_STATS>((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_
|
||||
|
@ -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 <typename FT>
|
||||
struct fp_constants
|
||||
{ };
|
||||
|
||||
/*! Specific constants for long double floating point type
|
||||
*/
|
||||
/// \brief Specific constants for long double floating point type
|
||||
///
|
||||
template <>
|
||||
struct fp_constants<long double>
|
||||
{
|
||||
@ -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<double>
|
||||
{
|
||||
@ -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<float>
|
||||
{
|
||||
@ -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>
|
||||
{
|
||||
|
@ -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
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
// license:GPL-2.0+
|
||||
// copyright-holders:Couriersud
|
||||
/*
|
||||
* nlsetup.h
|
||||
*
|
||||
*/
|
||||
|
||||
///
|
||||
/// \file nl_setup.h
|
||||
///
|
||||
|
||||
#ifndef NLSETUP_H_
|
||||
#define NLSETUP_H_
|
||||
|
@ -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<typename... ARGS>
|
||||
void poutprefix(pstring prefix, pstring fmt, ARGS&&... args)
|
||||
{
|
||||
pstring res = plib::pfmt(fmt)(std::forward<ARGS>(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<pstring> pinalias;
|
||||
pstring package;
|
||||
pstring namingconventions;
|
||||
pstring limitations;
|
||||
pstring functiontable;
|
||||
std::vector<pstring> 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::nl_exception>(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<netlist::nl_exception>(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<netlist::nl_exception>("Example requires 2 parameters, but found {1}", ret.example.size());
|
||||
}
|
||||
else
|
||||
plib::pthrow<netlist::nl_exception>(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("///", " <pre>");
|
||||
if (d.package == "DIP")
|
||||
{
|
||||
auto & pins = d.pinalias;
|
||||
//const int w = 8;
|
||||
poutprefix("///", " {1:10} +--------+", " ");
|
||||
for (std::size_t i=0; i<pins.size()/2; i++)
|
||||
{
|
||||
poutprefix("///", " {1:10} |{2:-2} {3:2}| {4:-10}",
|
||||
pins[i], i+1, pins.size()-i, pins[pins.size()-i-1]);
|
||||
}
|
||||
poutprefix("///", " {1:10} +--------+", " ");
|
||||
}
|
||||
poutprefix("///", " </pre>");
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user