mirror of
https://github.com/holub/mame
synced 2025-10-04 08:28:39 +03:00
Netlist improvements:
- nltool now accepts -Ddefine=value to pass on to netlists - improved option handling and added "dummy" options to add grouping and examples in help output. - improved --cmd=listdevices output - Fix dynamic timestepping. This will work with breakout using real capacitor modelling instead of delay devices. Really slow, but very useful to calibrate timings. - Fix an awful bug in timing for delay devices. - Switched to clang 3.8 and made code compile with -Weverything -Werror -Wno-old-style-cast -Wno-padded -Wno-weak-vtables -Wno-missing-variable-declarations -Wno-conversion -Wno-c++98-compat -Wno-float-equal -Wno-cast-align -Wno-global-constructors -Wno-c++98-compat-pedantic -Wno-exit-time-destructors -Wno-format-nonliteral -Wno-weak-template-vtables This was a helpful exercise since it brought forward some serious issues with implicit constructors. [Couriersud]
This commit is contained in:
parent
1f0dc8903f
commit
caafc0f782
@ -17,8 +17,15 @@ NETLIST_START(perf)
|
|||||||
|
|
||||||
NETLIST_END()
|
NETLIST_END()
|
||||||
|
|
||||||
|
#ifndef P_FREQ
|
||||||
|
#define P_FREQ 4800
|
||||||
|
#endif
|
||||||
|
|
||||||
NETLIST_START(7400_astable)
|
#ifndef P_DTS
|
||||||
|
#define P_DTS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NETLIST_START(cap_delay)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* delay circuit
|
* delay circuit
|
||||||
@ -27,18 +34,20 @@ NETLIST_START(7400_astable)
|
|||||||
|
|
||||||
/* Standard stuff */
|
/* Standard stuff */
|
||||||
|
|
||||||
SOLVER(Solver, 48000)
|
SOLVER(Solver, P_FREQ)
|
||||||
PARAM(Solver.ACCURACY, 1e-20)
|
PARAM(Solver.ACCURACY, 1e-20)
|
||||||
|
PARAM(Solver.DYNAMIC_TS, P_DTS)
|
||||||
|
PARAM(Solver.MIN_TIMESTEP, 1e-6)
|
||||||
CLOCK(clk, 5000)
|
CLOCK(clk, 5000)
|
||||||
|
|
||||||
TTL_7400_NAND(n1,clk,clk)
|
TTL_7400_NAND(n1,clk,clk)
|
||||||
CAP(C, 1e-9)
|
CAP(C, 1e-6)
|
||||||
NET_C(n1.Q, C.2)
|
NET_C(n1.Q, C.2)
|
||||||
NET_C(GND, C.1)
|
NET_C(GND, C.1)
|
||||||
TTL_7400_NAND(n2,n1.Q, n1.Q)
|
TTL_7400_NAND(n2,n1.Q, n1.Q)
|
||||||
|
|
||||||
LOG(logclk, clk)
|
LOG(logclk, clk)
|
||||||
LOG(logn1Q, C.2)
|
LOG(logn1Q, C.2)
|
||||||
LOG(logn2Q, n2.Q)
|
LOG(logn2Q, n1.Q)
|
||||||
|
|
||||||
NETLIST_END()
|
NETLIST_END()
|
||||||
|
@ -676,11 +676,7 @@ void netlist_mame_sound_device_t::sound_stream_update(sound_stream &stream, stre
|
|||||||
|
|
||||||
bool netlist_source_memregion_t::parse(netlist::setup_t &setup, const pstring &name)
|
bool netlist_source_memregion_t::parse(netlist::setup_t &setup, const pstring &name)
|
||||||
{
|
{
|
||||||
// FIXME: preprocessor should be a stream!
|
|
||||||
memory_region *mem = downcast<netlist_mame_t &>(setup.netlist()).machine().root_device().memregion(m_name.cstr());
|
memory_region *mem = downcast<netlist_mame_t &>(setup.netlist()).machine().root_device().memregion(m_name.cstr());
|
||||||
plib::pimemstream istrm(mem->base(),mem->bytes() );
|
plib::pimemstream istrm(mem->base(),mem->bytes() );
|
||||||
plib::pomemstream ostrm;
|
return setup.parse_stream(istrm, name);
|
||||||
|
|
||||||
plib::pimemstream istrm2(plib::ppreprocessor().process(istrm, ostrm));
|
|
||||||
return netlist::parser_t(istrm2, setup).parse(name);
|
|
||||||
}
|
}
|
||||||
|
@ -14,14 +14,15 @@ SRC = ..
|
|||||||
|
|
||||||
#-fuse-ld=gold -Wpedantic -march=native -march=native
|
#-fuse-ld=gold -Wpedantic -march=native -march=native
|
||||||
|
|
||||||
LTO = -flto=4 -fuse-linker-plugin -flto-partition=balanced -Wodr
|
# LTO = -flto=4 -fuse-linker-plugin -flto-partition=balanced -Wodr
|
||||||
|
|
||||||
CDEFS = -DPSTANDALONE=1 -DPTR64=1
|
|
||||||
#-Werror
|
#-Werror
|
||||||
#CFLAGS = $(LTO) -g -O3 -std=c++98 -Doverride="" -march=native -msse4.2 -Wall -Wpedantic -Wsign-compare -Wextra -Wno-long-long -Wno-unused-parameter -Wno-unused-result -Wno-variadic-macros -I..
|
#CFLAGS = $(LTO) -g -O3 -std=c++98 -Doverride="" -march=native -msse4.2 -Wall -Wpedantic -Wsign-compare -Wextra -Wno-long-long -Wno-unused-parameter -Wno-unused-result -Wno-variadic-macros -I..
|
||||||
#LDFLAGS = $(LTO) -g -O3 -std=c++98
|
#LDFLAGS = $(LTO) -g -O3 -std=c++98
|
||||||
CFLAGS = $(LTO) -g -O3 -std=c++11 -march=native -I.. -Wall -Wpedantic -Wsign-compare -Wextra -Wno-unused-parameter
|
|
||||||
LDFLAGS = $(LTO) -g -O3 -std=c++11 -lpthread -ldl
|
CFLAGS = $(CEXTRAFLAGS) $(LTO) -g -O3 -std=c++11 -march=native -I.. -Wall -Wpedantic -Wsign-compare -Wextra -Wno-unused-parameter
|
||||||
|
LDFLAGS = $(LTO) -g -O3 -std=c++11
|
||||||
|
LIBS = -lpthread -ldl
|
||||||
|
|
||||||
CC = g++-5
|
CC = g++-5
|
||||||
LD = @g++-5
|
LD = @g++-5
|
||||||
@ -125,11 +126,11 @@ clean:
|
|||||||
|
|
||||||
nltool: $(OBJ)/prg/nltool.o $(OBJS)
|
nltool: $(OBJ)/prg/nltool.o $(OBJS)
|
||||||
@echo Linking $@...
|
@echo Linking $@...
|
||||||
$(LD) -o $@ $(LDFLAGS) $^ $(LIBS)
|
@$(LD) -o $@ $(LDFLAGS) $^ $(LIBS)
|
||||||
|
|
||||||
nlwav: $(OBJ)/prg/nlwav.o $(OBJS)
|
nlwav: $(OBJ)/prg/nlwav.o $(OBJS)
|
||||||
@echo Linking $@...
|
@echo Linking $@...
|
||||||
$(LD) -o $@ $(LDFLAGS) $^ $(LIBS)
|
@$(LD) -o $@ $(LDFLAGS) $^ $(LIBS)
|
||||||
|
|
||||||
#-------------------------------------------------
|
#-------------------------------------------------
|
||||||
# directories
|
# directories
|
||||||
@ -155,6 +156,17 @@ depend: .depend
|
|||||||
|
|
||||||
-include .depend
|
-include .depend
|
||||||
|
|
||||||
|
#-------------------------------------------------
|
||||||
|
# Special targets
|
||||||
|
#-------------------------------------------------
|
||||||
|
|
||||||
|
.PHONY: clang
|
||||||
|
clang:
|
||||||
|
$(MAKE) CC=clang++ LD=clang++ CEXTRAFLAGS="-Weverything -Werror -Wno-padded -Wno-weak-vtables -Wno-missing-variable-declarations -Wno-conversion -Wno-c++98-compat -Wno-float-equal -Wno-cast-align -Wno-global-constructors -Wno-c++98-compat-pedantic -Wno-exit-time-destructors -Wno-format-nonliteral -Wno-weak-template-vtables"
|
||||||
|
|
||||||
|
# -Wno-old-style-cast
|
||||||
|
# FIX: -Wno-weak-vtables -Wno-missing-variable-declarations -Wno-conversion -Wno-old-style-cast -Wno-exit-time-destructors
|
||||||
|
|
||||||
#-------------------------------------------------
|
#-------------------------------------------------
|
||||||
# generic rules
|
# generic rules
|
||||||
#-------------------------------------------------
|
#-------------------------------------------------
|
||||||
@ -163,11 +175,11 @@ $(OBJ)/%.o: $(SRC)/%.cpp
|
|||||||
@echo Compiling $<...
|
@echo Compiling $<...
|
||||||
@$(CC) $(CDEFS) $(CFLAGS) -c $< -o $@
|
@$(CC) $(CDEFS) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
$(OBJ)/%.pp: $(SRC)/%.cpp | $(OSPREBUILD)
|
$(OBJ)/%.pp: $(SRC)/%.cpp
|
||||||
@echo Compiling $<...
|
@echo Compiling $<...
|
||||||
@$(CC) $(CDEFS) $(CFLAGS) -E $< -o $@
|
@$(CC) $(CDEFS) $(CFLAGS) -E $< -o $@
|
||||||
|
|
||||||
$(OBJ)/%.s: $(SRC)/%.cpp | $(OSPREBUILD)
|
$(OBJ)/%.s: $(SRC)/%.cpp
|
||||||
@echo Compiling $<...
|
@echo Compiling $<...
|
||||||
@$(CC) $(CDEFS) $(CFLAGS) -S $< -o $@
|
@$(CC) $(CDEFS) $(CFLAGS) -S $< -o $@
|
||||||
|
|
||||||
|
@ -71,7 +71,8 @@ namespace netlist
|
|||||||
{
|
{
|
||||||
namespace devices
|
namespace devices
|
||||||
{
|
{
|
||||||
void initialize_factory(factory_list_t &factory)
|
|
||||||
|
static void initialize_factory(factory_list_t &factory)
|
||||||
{
|
{
|
||||||
ENTRY(R, RES, "R")
|
ENTRY(R, RES, "R")
|
||||||
ENTRY(POT, POT, "R")
|
ENTRY(POT, POT, "R")
|
||||||
|
@ -55,7 +55,7 @@ namespace netlist
|
|||||||
if (R > NL_FCONST(0.0))
|
if (R > NL_FCONST(0.0))
|
||||||
{
|
{
|
||||||
// We only need to update the net first if this is a time stepping net
|
// We only need to update the net first if this is a time stepping net
|
||||||
if (1) // m_R.m_P.net().as_analog().solver().is_timestep())
|
if ((1)) // m_R.m_P.net().as_analog().solver().is_timestep())
|
||||||
{
|
{
|
||||||
m_R.update_dev();
|
m_R.update_dev();
|
||||||
m_R.set_R(R);
|
m_R.set_R(R);
|
||||||
|
@ -10,9 +10,6 @@
|
|||||||
#include "nlid_system.h"
|
#include "nlid_system.h"
|
||||||
#include "analog/nld_twoterm.h"
|
#include "analog/nld_twoterm.h"
|
||||||
|
|
||||||
#define R_OFF (1E20)
|
|
||||||
#define R_ON (m_RI.Value())
|
|
||||||
|
|
||||||
namespace netlist
|
namespace netlist
|
||||||
{
|
{
|
||||||
namespace devices
|
namespace devices
|
||||||
|
@ -159,7 +159,7 @@ namespace netlist
|
|||||||
{
|
{
|
||||||
if (m_loadq)
|
if (m_loadq)
|
||||||
{
|
{
|
||||||
switch (m_cnt)
|
switch (m_cnt())
|
||||||
{
|
{
|
||||||
case MAXCNT - 1:
|
case MAXCNT - 1:
|
||||||
m_cnt = MAXCNT;
|
m_cnt = MAXCNT;
|
||||||
|
@ -162,7 +162,7 @@ namespace netlist
|
|||||||
{
|
{
|
||||||
if (m_loadq)
|
if (m_loadq)
|
||||||
{
|
{
|
||||||
switch (m_cnt)
|
switch (m_cnt())
|
||||||
{
|
{
|
||||||
case MAXCNT - 1:
|
case MAXCNT - 1:
|
||||||
m_cnt = MAXCNT;
|
m_cnt = MAXCNT;
|
||||||
|
@ -133,7 +133,7 @@ namespace netlist
|
|||||||
const nl_double R = state ? m_RON.Value() : m_ROFF.Value();
|
const nl_double R = state ? m_RON.Value() : m_ROFF.Value();
|
||||||
|
|
||||||
// We only need to update the net first if this is a time stepping net
|
// We only need to update the net first if this is a time stepping net
|
||||||
if (0) // m_R->m_P.net().as_analog().solver()->is_timestep())
|
if ((0)) // m_R->m_P.net().as_analog().solver()->is_timestep())
|
||||||
{
|
{
|
||||||
m_R.update_dev();
|
m_R.update_dev();
|
||||||
m_R.set_R(R);
|
m_R.set_R(R);
|
||||||
|
@ -229,7 +229,7 @@ void truthtable_desc_t::setup(const plib::pstring_vector_t &truthtable, uint_lea
|
|||||||
if (ign[i] == all_set)
|
if (ign[i] == all_set)
|
||||||
{
|
{
|
||||||
int tign;
|
int tign;
|
||||||
if (0)
|
if ((0))
|
||||||
{
|
{
|
||||||
tign = get_ignored_simple(i);
|
tign = get_ignored_simple(i);
|
||||||
ign[i] = tign;
|
ign[i] = tign;
|
||||||
|
@ -22,8 +22,8 @@ namespace netlist
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
NETLIB_UPDATEI() {};
|
NETLIB_UPDATEI() {}
|
||||||
NETLIB_RESETI() {};
|
NETLIB_RESETI() {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline nl_double vdd() { return INPANALOG(m_vdd); }
|
inline nl_double vdd() { return INPANALOG(m_vdd); }
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NETLIST_START(CD4001_DIP)
|
static NETLIST_START(CD4001_DIP)
|
||||||
CD4001_NOR(s1)
|
CD4001_NOR(s1)
|
||||||
CD4001_NOR(s2)
|
CD4001_NOR(s2)
|
||||||
CD4001_NOR(s3)
|
CD4001_NOR(s3)
|
||||||
@ -63,7 +63,7 @@ NETLIST_END()
|
|||||||
* This needs a cmos d-a/a-d proxy implementation.
|
* This needs a cmos d-a/a-d proxy implementation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NETLIST_START(CD4020_DIP)
|
static NETLIST_START(CD4020_DIP)
|
||||||
|
|
||||||
CD4020(s1)
|
CD4020(s1)
|
||||||
DIPPINS( /* +--------------+ */
|
DIPPINS( /* +--------------+ */
|
||||||
@ -101,7 +101,7 @@ NETLIST_END()
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NETLIST_START(CD4066_DIP)
|
static NETLIST_START(CD4066_DIP)
|
||||||
CD4066_GATE(A)
|
CD4066_GATE(A)
|
||||||
CD4066_GATE(B)
|
CD4066_GATE(B)
|
||||||
CD4066_GATE(C)
|
CD4066_GATE(C)
|
||||||
@ -127,7 +127,7 @@ NETLIST_START(CD4066_DIP)
|
|||||||
)
|
)
|
||||||
NETLIST_END()
|
NETLIST_END()
|
||||||
|
|
||||||
NETLIST_START(CD4016_DIP)
|
static NETLIST_START(CD4016_DIP)
|
||||||
CD4066_GATE(A)
|
CD4066_GATE(A)
|
||||||
CD4066_GATE(B)
|
CD4066_GATE(B)
|
||||||
CD4066_GATE(C)
|
CD4066_GATE(C)
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* Generic layout with 4 opamps, VCC on pint 4 and GND on pin 11
|
* Generic layout with 4 opamps, VCC on pint 4 and GND on pin 11
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NETLIST_START(opamp_layout_4_4_11)
|
static NETLIST_START(opamp_layout_4_4_11)
|
||||||
DIPPINS( /* +--------------+ */
|
DIPPINS( /* +--------------+ */
|
||||||
A.OUT, /* |1 ++ 14| */ D.OUT,
|
A.OUT, /* |1 ++ 14| */ D.OUT,
|
||||||
A.MINUS, /* |2 13| */ D.MINUS,
|
A.MINUS, /* |2 13| */ D.MINUS,
|
||||||
@ -28,7 +28,7 @@ NETLIST_END()
|
|||||||
* Generic layout with 2 opamps, VCC on pint 8 and GND on pin 4
|
* Generic layout with 2 opamps, VCC on pint 8 and GND on pin 4
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NETLIST_START(opamp_layout_2_8_4)
|
static NETLIST_START(opamp_layout_2_8_4)
|
||||||
DIPPINS( /* +--------------+ */
|
DIPPINS( /* +--------------+ */
|
||||||
A.OUT, /* |1 ++ 8| */ A.VCC,
|
A.OUT, /* |1 ++ 8| */ A.VCC,
|
||||||
A.MINUS, /* |2 7| */ B.OUT,
|
A.MINUS, /* |2 7| */ B.OUT,
|
||||||
@ -40,7 +40,7 @@ NETLIST_START(opamp_layout_2_8_4)
|
|||||||
NET_C(A.VCC, B.VCC)
|
NET_C(A.VCC, B.VCC)
|
||||||
NETLIST_END()
|
NETLIST_END()
|
||||||
|
|
||||||
NETLIST_START(MB3614_DIP)
|
static NETLIST_START(MB3614_DIP)
|
||||||
OPAMP(A, "MB3614")
|
OPAMP(A, "MB3614")
|
||||||
OPAMP(B, "MB3614")
|
OPAMP(B, "MB3614")
|
||||||
OPAMP(C, "MB3614")
|
OPAMP(C, "MB3614")
|
||||||
@ -50,7 +50,7 @@ NETLIST_START(MB3614_DIP)
|
|||||||
|
|
||||||
NETLIST_END()
|
NETLIST_END()
|
||||||
|
|
||||||
NETLIST_START(LM324_DIP)
|
static NETLIST_START(LM324_DIP)
|
||||||
OPAMP(A, "LM324")
|
OPAMP(A, "LM324")
|
||||||
OPAMP(B, "LM324")
|
OPAMP(B, "LM324")
|
||||||
OPAMP(C, "LM324")
|
OPAMP(C, "LM324")
|
||||||
@ -60,7 +60,7 @@ NETLIST_START(LM324_DIP)
|
|||||||
|
|
||||||
NETLIST_END()
|
NETLIST_END()
|
||||||
|
|
||||||
NETLIST_START(LM358_DIP)
|
static NETLIST_START(LM358_DIP)
|
||||||
OPAMP(A, "LM358")
|
OPAMP(A, "LM358")
|
||||||
OPAMP(B, "LM358")
|
OPAMP(B, "LM358")
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NETLIST_START(MC14584B_DIP)
|
static NETLIST_START(MC14584B_DIP)
|
||||||
MC14584B_GATE(s1)
|
MC14584B_GATE(s1)
|
||||||
MC14584B_GATE(s2)
|
MC14584B_GATE(s2)
|
||||||
MC14584B_GATE(s3)
|
MC14584B_GATE(s3)
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NETLIST_START(TTL_7400_DIP)
|
static NETLIST_START(TTL_7400_DIP)
|
||||||
TTL_7400_GATE(s1)
|
TTL_7400_GATE(s1)
|
||||||
TTL_7400_GATE(s2)
|
TTL_7400_GATE(s2)
|
||||||
TTL_7400_GATE(s3)
|
TTL_7400_GATE(s3)
|
||||||
@ -62,7 +62,7 @@ NETLIST_END()
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NETLIST_START(TTL_7402_DIP)
|
static NETLIST_START(TTL_7402_DIP)
|
||||||
TTL_7402_GATE(s1)
|
TTL_7402_GATE(s1)
|
||||||
TTL_7402_GATE(s2)
|
TTL_7402_GATE(s2)
|
||||||
TTL_7402_GATE(s3)
|
TTL_7402_GATE(s3)
|
||||||
@ -98,7 +98,7 @@ NETLIST_END()
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NETLIST_START(TTL_7404_DIP)
|
static NETLIST_START(TTL_7404_DIP)
|
||||||
TTL_7404_GATE(s1)
|
TTL_7404_GATE(s1)
|
||||||
TTL_7404_GATE(s2)
|
TTL_7404_GATE(s2)
|
||||||
TTL_7404_GATE(s3)
|
TTL_7404_GATE(s3)
|
||||||
@ -139,7 +139,7 @@ NETLIST_END()
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NETLIST_START(TTL_7408_DIP)
|
static NETLIST_START(TTL_7408_DIP)
|
||||||
TTL_7408_GATE(s1)
|
TTL_7408_GATE(s1)
|
||||||
TTL_7408_GATE(s2)
|
TTL_7408_GATE(s2)
|
||||||
TTL_7408_GATE(s3)
|
TTL_7408_GATE(s3)
|
||||||
@ -177,7 +177,7 @@ NETLIST_END()
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NETLIST_START(TTL_7410_DIP)
|
static NETLIST_START(TTL_7410_DIP)
|
||||||
TTL_7410_GATE(s1)
|
TTL_7410_GATE(s1)
|
||||||
TTL_7410_GATE(s2)
|
TTL_7410_GATE(s2)
|
||||||
TTL_7410_GATE(s3)
|
TTL_7410_GATE(s3)
|
||||||
@ -214,7 +214,7 @@ NETLIST_END()
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NETLIST_START(TTL_7411_DIP)
|
static NETLIST_START(TTL_7411_DIP)
|
||||||
TTL_7411_GATE(s1)
|
TTL_7411_GATE(s1)
|
||||||
TTL_7411_GATE(s2)
|
TTL_7411_GATE(s2)
|
||||||
TTL_7411_GATE(s3)
|
TTL_7411_GATE(s3)
|
||||||
@ -240,7 +240,7 @@ NETLIST_END()
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NETLIST_START(TTL_7416_DIP)
|
static NETLIST_START(TTL_7416_DIP)
|
||||||
TTL_7416_GATE(s1)
|
TTL_7416_GATE(s1)
|
||||||
TTL_7416_GATE(s2)
|
TTL_7416_GATE(s2)
|
||||||
TTL_7416_GATE(s3)
|
TTL_7416_GATE(s3)
|
||||||
@ -281,7 +281,7 @@ NETLIST_END()
|
|||||||
* Naming conventions follow National Semiconductor datasheet *
|
* Naming conventions follow National Semiconductor datasheet *
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NETLIST_START(TTL_7420_DIP)
|
static NETLIST_START(TTL_7420_DIP)
|
||||||
TTL_7420_GATE(s1)
|
TTL_7420_GATE(s1)
|
||||||
TTL_7420_GATE(s2)
|
TTL_7420_GATE(s2)
|
||||||
|
|
||||||
@ -323,7 +323,7 @@ NETLIST_END()
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NETLIST_START(TTL_7425_DIP)
|
static NETLIST_START(TTL_7425_DIP)
|
||||||
TTL_7425_GATE(s1)
|
TTL_7425_GATE(s1)
|
||||||
TTL_7425_GATE(s2)
|
TTL_7425_GATE(s2)
|
||||||
|
|
||||||
@ -361,7 +361,7 @@ NETLIST_END()
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NETLIST_START(TTL_7427_DIP)
|
static NETLIST_START(TTL_7427_DIP)
|
||||||
TTL_7427_GATE(s1)
|
TTL_7427_GATE(s1)
|
||||||
TTL_7427_GATE(s2)
|
TTL_7427_GATE(s2)
|
||||||
TTL_7427_GATE(s3)
|
TTL_7427_GATE(s3)
|
||||||
@ -402,7 +402,7 @@ NETLIST_END()
|
|||||||
* Naming conventions follow National Semiconductor datasheet
|
* Naming conventions follow National Semiconductor datasheet
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NETLIST_START(TTL_7430_DIP)
|
static NETLIST_START(TTL_7430_DIP)
|
||||||
TTL_7430_GATE(s1)
|
TTL_7430_GATE(s1)
|
||||||
|
|
||||||
DUMMY_INPUT(GND)
|
DUMMY_INPUT(GND)
|
||||||
@ -439,7 +439,7 @@ NETLIST_END()
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NETLIST_START(TTL_7432_DIP)
|
static NETLIST_START(TTL_7432_DIP)
|
||||||
TTL_7432_GATE(s1)
|
TTL_7432_GATE(s1)
|
||||||
TTL_7432_GATE(s2)
|
TTL_7432_GATE(s2)
|
||||||
TTL_7432_GATE(s3)
|
TTL_7432_GATE(s3)
|
||||||
@ -481,7 +481,7 @@ NETLIST_END()
|
|||||||
* Netlist currently does not model over currents (should it ever?)
|
* Netlist currently does not model over currents (should it ever?)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NETLIST_START(TTL_7437_DIP)
|
static NETLIST_START(TTL_7437_DIP)
|
||||||
TTL_7437_GATE(s1)
|
TTL_7437_GATE(s1)
|
||||||
TTL_7437_GATE(s2)
|
TTL_7437_GATE(s2)
|
||||||
TTL_7437_GATE(s3)
|
TTL_7437_GATE(s3)
|
||||||
@ -519,7 +519,7 @@ NETLIST_END()
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NETLIST_START(TTL_7486_DIP)
|
static NETLIST_START(TTL_7486_DIP)
|
||||||
TTL_7486_GATE(s1)
|
TTL_7486_GATE(s1)
|
||||||
TTL_7486_GATE(s2)
|
TTL_7486_GATE(s2)
|
||||||
TTL_7486_GATE(s3)
|
TTL_7486_GATE(s3)
|
||||||
|
@ -273,8 +273,9 @@ namespace netlist
|
|||||||
class fatalerror_e : public plib::pexception
|
class fatalerror_e : public plib::pexception
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
fatalerror_e(const pstring &text) : plib::pexception(text) { }
|
explicit fatalerror_e(const pstring text) : plib::pexception(text) { }
|
||||||
virtual ~fatalerror_e() throw() {}
|
fatalerror_e(const fatalerror_e &e) : plib::pexception(e) { }
|
||||||
|
virtual ~fatalerror_e() noexcept {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class logic_output_t;
|
class logic_output_t;
|
||||||
@ -663,6 +664,7 @@ namespace netlist
|
|||||||
bool is_analog() const;
|
bool is_analog() const;
|
||||||
|
|
||||||
void toggle_new_Q() { m_new_Q ^= 1; }
|
void toggle_new_Q() { m_new_Q ^= 1; }
|
||||||
|
void force_queue_execution() { m_new_Q = (m_cur_Q ^ 1); }
|
||||||
|
|
||||||
void push_to_queue(const netlist_time delay) NOEXCEPT;
|
void push_to_queue(const netlist_time delay) NOEXCEPT;
|
||||||
void reschedule_in_queue(const netlist_time delay) NOEXCEPT;
|
void reschedule_in_queue(const netlist_time delay) NOEXCEPT;
|
||||||
@ -711,7 +713,7 @@ namespace netlist
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
logic_net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr = nullptr);
|
logic_net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr = nullptr);
|
||||||
virtual ~logic_net_t() { };
|
virtual ~logic_net_t() { }
|
||||||
|
|
||||||
netlist_sig_t Q() const { return m_cur_Q; }
|
netlist_sig_t Q() const { return m_cur_Q; }
|
||||||
netlist_sig_t new_Q() const { return m_new_Q; }
|
netlist_sig_t new_Q() const { return m_new_Q; }
|
||||||
@ -755,7 +757,7 @@ namespace netlist
|
|||||||
|
|
||||||
analog_net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr = nullptr);
|
analog_net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr = nullptr);
|
||||||
|
|
||||||
virtual ~analog_net_t() { };
|
virtual ~analog_net_t() { }
|
||||||
|
|
||||||
nl_double Q_Analog() const { return m_cur_Analog; }
|
nl_double Q_Analog() const { return m_cur_Analog; }
|
||||||
nl_double &Q_Analog_state_ptr() { return m_cur_Analog; }
|
nl_double &Q_Analog_state_ptr() { return m_cur_Analog; }
|
||||||
@ -1139,11 +1141,11 @@ namespace netlist
|
|||||||
|
|
||||||
template<typename O, typename C> void save(O &owner, C &state, const pstring &stname)
|
template<typename O, typename C> void save(O &owner, C &state, const pstring &stname)
|
||||||
{
|
{
|
||||||
this->state().save_item((void *)&owner, state, pstring(owner.name()) + "." + stname);
|
this->state().save_item(static_cast<void *>(&owner), state, pstring(owner.name()) + "." + stname);
|
||||||
}
|
}
|
||||||
template<typename O, typename C> void save(O &owner, C *state, const pstring &stname, const int count)
|
template<typename O, typename C> void save(O &owner, C *state, const pstring &stname, const int count)
|
||||||
{
|
{
|
||||||
this->state().save_state_ptr((void *)&owner, pstring(owner.name()) + "." + stname, plib::state_manager_t::datatype_f<C>::f(), count, state);
|
this->state().save_state_ptr(static_cast<void *>(&owner), pstring(owner.name()) + "." + stname, plib::state_manager_t::datatype_f<C>::f(), count, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void reset();
|
virtual void reset();
|
||||||
@ -1160,13 +1162,6 @@ namespace netlist
|
|||||||
/* sole use is to manage lifetime of family objects */
|
/* sole use is to manage lifetime of family objects */
|
||||||
std::vector<std::pair<pstring, std::unique_ptr<logic_family_desc_t>>> m_family_cache;
|
std::vector<std::pair<pstring, std::unique_ptr<logic_family_desc_t>>> m_family_cache;
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
// performance
|
|
||||||
nperfcount_t m_perf_out_processed;
|
|
||||||
nperfcount_t m_perf_inp_processed;
|
|
||||||
nperfcount_t m_perf_inp_active;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
plib::state_manager_t m_state;
|
plib::state_manager_t m_state;
|
||||||
/* mostly rw */
|
/* mostly rw */
|
||||||
@ -1185,6 +1180,11 @@ namespace netlist
|
|||||||
setup_t *m_setup;
|
setup_t *m_setup;
|
||||||
plib::plog_base<NL_DEBUG> m_log;
|
plib::plog_base<NL_DEBUG> m_log;
|
||||||
plib::dynlib *m_lib; // external lib needs to be loaded as long as netlist exists
|
plib::dynlib *m_lib; // external lib needs to be loaded as long as netlist exists
|
||||||
|
|
||||||
|
// performance
|
||||||
|
nperfcount_t m_perf_out_processed;
|
||||||
|
nperfcount_t m_perf_inp_processed;
|
||||||
|
nperfcount_t m_perf_inp_active;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -105,7 +105,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define CHIP(n, t) TTL_ ## t ## DIP(n)
|
#define CHIP(n, t) TTL_ ## t ## _DIP(n)
|
||||||
|
|
||||||
#define OHM(x) x
|
#define OHM(x) x
|
||||||
#define K_OHM(x) RES_K(X)
|
#define K_OHM(x) RES_K(X)
|
||||||
@ -200,8 +200,8 @@ inline int CAPACITOR_tc_hl(const double c, const double r)
|
|||||||
* Vt = (VH-VL)*exp(-t/RC)
|
* Vt = (VH-VL)*exp(-t/RC)
|
||||||
* ln(Vt/(VH-VL))*RC = -t
|
* ln(Vt/(VH-VL))*RC = -t
|
||||||
*/
|
*/
|
||||||
static const double TIME_CONSTANT = -std::log(2.0 / (3.7-0.3));
|
static const double TIME_CONSTANT = -std::log(0.8 / (4.0-0.1));
|
||||||
int ret = (int) (TIME_CONSTANT * (130.0 + r) * c * 1e9);
|
int ret = (int) (TIME_CONSTANT * (1.0 + r) * c * 1e9);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,14 +211,30 @@ inline int CAPACITOR_tc_lh(const double c, const double r)
|
|||||||
* Vt = (VH-VL)*(1-exp(-t/RC))
|
* Vt = (VH-VL)*(1-exp(-t/RC))
|
||||||
* -t=ln(1-Vt/(VH-VL))*RC
|
* -t=ln(1-Vt/(VH-VL))*RC
|
||||||
*/
|
*/
|
||||||
static const double TIME_CONSTANT = -std::log(1.0 - 0.8 / (3.7-0.3));
|
static const double TIME_CONSTANT = -std::log(1.0 - 2.0 / (4.0-0.1));
|
||||||
int ret = (int) (TIME_CONSTANT * (1.0 + r) * c * 1e9);
|
int ret = (int) (TIME_CONSTANT * (130.0 + r) * c * 1e9);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
#define CHIP_CAPACITOR(name, pdesc) \
|
#define CHIP_CAPACITOR(name, pdesc) \
|
||||||
NETDEV_DELAY(name) \
|
NETDEV_DELAY(name) \
|
||||||
NETDEV_PARAMI(name, L_TO_H, CAPACITOR_tc_lh((pdesc)->c, (pdesc)->r)) \
|
NETDEV_PARAMI(name, L_TO_H, CAPACITOR_tc_lh((pdesc)->c, (pdesc)->r)) \
|
||||||
NETDEV_PARAMI(name, H_TO_L, CAPACITOR_tc_hl((pdesc)->c, (pdesc)->r))
|
NETDEV_PARAMI(name, H_TO_L, CAPACITOR_tc_hl((pdesc)->c, (pdesc)->r))
|
||||||
|
#elif 1
|
||||||
|
// slow, very slow
|
||||||
|
#define CHIP_CAPACITOR(name, pdesc) \
|
||||||
|
CAP(name ## _C, (pdesc)->c) \
|
||||||
|
ALIAS(name.1, name ## _C.1 ) \
|
||||||
|
ALIAS(name.2, name ## _C.1) \
|
||||||
|
NET_C(GND, name ## _C.2)
|
||||||
|
#else
|
||||||
|
// fast, might work
|
||||||
|
#define CHIP_CAPACITOR(name, pdesc) \
|
||||||
|
RES(name ## _C, RES_K(1000)) \
|
||||||
|
ALIAS(name.1, name ## _C.1 ) \
|
||||||
|
ALIAS(name.2, name ## _C.1) \
|
||||||
|
NET_C(GND, name ## _C.2)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* NL_DICE_COMPAT_H_ */
|
#endif /* NL_DICE_COMPAT_H_ */
|
||||||
|
@ -223,8 +223,8 @@ void setup_t::register_and_set_param(pstring name, param_t ¶m)
|
|||||||
static_cast<param_str_t &>(param).initial(val);
|
static_cast<param_str_t &>(param).initial(val);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
//default:
|
||||||
log().fatal("Parameter is not supported {1} : {2}\n", name, val);
|
// log().fatal("Parameter is not supported {1} : {2}\n", name, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!m_params.insert({param.name(), param_ref_t(param.name(), param.device(), param)}).second)
|
if (!m_params.insert({param.name(), param_ref_t(param.name(), param.device(), param)}).second)
|
||||||
@ -1002,6 +1002,23 @@ void setup_t::include(const pstring &netlist_name)
|
|||||||
log().fatal("unable to find {1} in source collection", netlist_name);
|
log().fatal("unable to find {1} in source collection", netlist_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool setup_t::parse_stream(plib::pistream &istrm, const pstring &name)
|
||||||
|
{
|
||||||
|
plib::pomemstream ostrm;
|
||||||
|
|
||||||
|
plib::pimemstream istrm2(plib::ppreprocessor(&m_defines).process(istrm, ostrm));
|
||||||
|
return parser_t(istrm2, *this).parse(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup_t::register_define(pstring defstr)
|
||||||
|
{
|
||||||
|
auto p = defstr.find("=");
|
||||||
|
if (p>0)
|
||||||
|
register_define(defstr.left(p), defstr.substr(p+1));
|
||||||
|
else
|
||||||
|
register_define(defstr, "1");
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
// base sources
|
// base sources
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
@ -1009,28 +1026,19 @@ void setup_t::include(const pstring &netlist_name)
|
|||||||
bool source_string_t::parse(setup_t &setup, const pstring &name)
|
bool source_string_t::parse(setup_t &setup, const pstring &name)
|
||||||
{
|
{
|
||||||
plib::pimemstream istrm(m_str.cstr(), m_str.len());
|
plib::pimemstream istrm(m_str.cstr(), m_str.len());
|
||||||
plib::pomemstream ostrm;
|
return setup.parse_stream(istrm, name);
|
||||||
|
|
||||||
plib::pimemstream istrm2(plib::ppreprocessor().process(istrm, ostrm));
|
|
||||||
return parser_t(istrm2, setup).parse(name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool source_mem_t::parse(setup_t &setup, const pstring &name)
|
bool source_mem_t::parse(setup_t &setup, const pstring &name)
|
||||||
{
|
{
|
||||||
plib::pimemstream istrm(m_str.cstr(), m_str.len());
|
plib::pimemstream istrm(m_str.cstr(), m_str.len());
|
||||||
plib::pomemstream ostrm;
|
return setup.parse_stream(istrm, name);
|
||||||
|
|
||||||
plib::pimemstream istrm2(plib::ppreprocessor().process(istrm, ostrm));
|
|
||||||
return parser_t(istrm2, setup).parse(name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool source_file_t::parse(setup_t &setup, const pstring &name)
|
bool source_file_t::parse(setup_t &setup, const pstring &name)
|
||||||
{
|
{
|
||||||
plib::pifilestream istrm(m_filename);
|
plib::pifilestream istrm(m_filename);
|
||||||
plib::pomemstream ostrm;
|
return setup.parse_stream(istrm, name);
|
||||||
|
|
||||||
plib::pimemstream istrm2(plib::ppreprocessor().process(istrm, ostrm));
|
|
||||||
return parser_t(istrm2, setup).parse(name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,9 @@
|
|||||||
#include "plib/pstring.h"
|
#include "plib/pstring.h"
|
||||||
#include "plib/palloc.h"
|
#include "plib/palloc.h"
|
||||||
#include "plib/pfmtlog.h"
|
#include "plib/pfmtlog.h"
|
||||||
|
#include "plib/pstream.h"
|
||||||
#include "plib/putil.h"
|
#include "plib/putil.h"
|
||||||
|
#include "plib/pparser.h"
|
||||||
#include "nl_config.h"
|
#include "nl_config.h"
|
||||||
#include "nl_base.h"
|
#include "nl_base.h"
|
||||||
#include "nl_factory.h"
|
#include "nl_factory.h"
|
||||||
@ -156,6 +158,7 @@ namespace netlist
|
|||||||
virtual ~source_t() { }
|
virtual ~source_t() { }
|
||||||
|
|
||||||
virtual bool parse(setup_t &setup, const pstring &name) = 0;
|
virtual bool parse(setup_t &setup, const pstring &name) = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -222,6 +225,8 @@ namespace netlist
|
|||||||
|
|
||||||
void include(const pstring &netlist_name);
|
void include(const pstring &netlist_name);
|
||||||
|
|
||||||
|
bool parse_stream(plib::pistream &istrm, const pstring &name);
|
||||||
|
|
||||||
/* register a source */
|
/* register a source */
|
||||||
|
|
||||||
void register_source(std::unique_ptr<source_t> &&src)
|
void register_source(std::unique_ptr<source_t> &&src)
|
||||||
@ -229,6 +234,9 @@ namespace netlist
|
|||||||
m_sources.push_back(std::move(src));
|
m_sources.push_back(std::move(src));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void register_define(pstring def, pstring val) { m_defines.push_back(plib::ppreprocessor::define_t(def, val)); }
|
||||||
|
void register_define(pstring defstr);
|
||||||
|
|
||||||
factory_list_t &factory() { return m_factory; }
|
factory_list_t &factory() { return m_factory; }
|
||||||
const factory_list_t &factory() const { return m_factory; }
|
const factory_list_t &factory() const { return m_factory; }
|
||||||
|
|
||||||
@ -251,6 +259,9 @@ namespace netlist
|
|||||||
|
|
||||||
void tt_factory_create(tt_desc &desc);
|
void tt_factory_create(tt_desc &desc);
|
||||||
|
|
||||||
|
/* helper - also used by nltool */
|
||||||
|
const pstring resolve_alias(const pstring &name) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -267,7 +278,6 @@ namespace netlist
|
|||||||
// helpers
|
// helpers
|
||||||
pstring objtype_as_str(device_object_t &in) const;
|
pstring objtype_as_str(device_object_t &in) const;
|
||||||
|
|
||||||
const pstring resolve_alias(const pstring &name) const;
|
|
||||||
devices::nld_base_proxy *get_d_a_proxy(core_terminal_t &out);
|
devices::nld_base_proxy *get_d_a_proxy(core_terminal_t &out);
|
||||||
|
|
||||||
netlist_t &m_netlist;
|
netlist_t &m_netlist;
|
||||||
@ -290,6 +300,7 @@ namespace netlist
|
|||||||
|
|
||||||
std::stack<pstring> m_namespace_stack;
|
std::stack<pstring> m_namespace_stack;
|
||||||
source_t::list_t m_sources;
|
source_t::list_t m_sources;
|
||||||
|
std::vector<plib::ppreprocessor::define_t> m_defines;
|
||||||
std::vector<pstring> m_lib;
|
std::vector<pstring> m_lib;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -15,7 +15,7 @@ namespace plib {
|
|||||||
// Exceptions
|
// Exceptions
|
||||||
//============================================================
|
//============================================================
|
||||||
|
|
||||||
pexception::pexception(const pstring &text)
|
pexception::pexception(const pstring text)
|
||||||
{
|
{
|
||||||
m_text = text;
|
m_text = text;
|
||||||
fprintf(stderr, "%s\n", m_text.cstr());
|
fprintf(stderr, "%s\n", m_text.cstr());
|
||||||
|
@ -24,8 +24,10 @@ namespace plib {
|
|||||||
class pexception : public std::exception
|
class pexception : public std::exception
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
pexception(const pstring &text);
|
explicit pexception(const pstring text);
|
||||||
virtual ~pexception() throw() {}
|
pexception(const pexception &e) : std::exception(e) { m_text = e.m_text; }
|
||||||
|
|
||||||
|
virtual ~pexception() noexcept {}
|
||||||
|
|
||||||
const pstring &text() { return m_text; }
|
const pstring &text() { return m_text; }
|
||||||
|
|
||||||
|
@ -277,7 +277,7 @@ public:
|
|||||||
error(proxy),
|
error(proxy),
|
||||||
fatal(proxy)
|
fatal(proxy)
|
||||||
{}
|
{}
|
||||||
virtual ~plog_base() {};
|
virtual ~plog_base() {}
|
||||||
|
|
||||||
plog_channel<plog_level::DEBUG, debug_enabled> debug;
|
plog_channel<plog_level::DEBUG, debug_enabled> debug;
|
||||||
plog_channel<plog_level::INFO> info;
|
plog_channel<plog_level::INFO> info;
|
||||||
|
@ -12,17 +12,18 @@ namespace plib {
|
|||||||
Options
|
Options
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
option::option()
|
option_base::option_base(options &parent, pstring help)
|
||||||
: m_short(""), m_long(""), m_help(""), m_has_argument(false)
|
: m_help(help)
|
||||||
{}
|
|
||||||
|
|
||||||
option::option(options &parent, pstring ashort, pstring along, pstring help, bool has_argument)
|
|
||||||
: m_short(ashort), m_long(along), m_help(help), m_has_argument(has_argument)
|
|
||||||
{
|
{
|
||||||
parent.register_option(this);
|
parent.register_option(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
option::~option()
|
option_base::~option_base()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
option::option(options &parent, pstring ashort, pstring along, pstring help, bool has_argument)
|
||||||
|
: option_base(parent, help), m_short(ashort), m_long(along), m_has_argument(has_argument)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,6 +57,13 @@ namespace plib {
|
|||||||
return (err ? 1 : 0);
|
return (err ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int option_vec::parse(pstring argument)
|
||||||
|
{
|
||||||
|
bool err = false;
|
||||||
|
m_val.push_back(argument);
|
||||||
|
return (err ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
options::options()
|
options::options()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -75,7 +83,7 @@ namespace plib {
|
|||||||
m_opts.clear();
|
m_opts.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void options::register_option(option *opt)
|
void options::register_option(option_base *opt)
|
||||||
{
|
{
|
||||||
m_opts.push_back(opt);
|
m_opts.push_back(opt);
|
||||||
}
|
}
|
||||||
@ -96,11 +104,21 @@ namespace plib {
|
|||||||
auto v = pstring_vector_t(arg.substr(2),"=");
|
auto v = pstring_vector_t(arg.substr(2),"=");
|
||||||
opt = getopt_long(v[0]);
|
opt = getopt_long(v[0]);
|
||||||
has_equal_arg = (v.size() > 1);
|
has_equal_arg = (v.size() > 1);
|
||||||
if (has_equal_arg) opt_arg = v[1];
|
if (has_equal_arg)
|
||||||
|
{
|
||||||
|
for (unsigned j = 1; j < v.size() - 1; j++)
|
||||||
|
opt_arg = opt_arg + v[j] + "=";
|
||||||
|
opt_arg += v[v.size()-1];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (arg.startsWith("-"))
|
else if (arg.startsWith("-"))
|
||||||
{
|
{
|
||||||
opt = getopt_short(arg.substr(1));
|
opt = getopt_short(arg.substr(1,1));
|
||||||
|
if (arg.len() > 2)
|
||||||
|
{
|
||||||
|
has_equal_arg = true;
|
||||||
|
opt_arg = arg.substr(2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return i;
|
return i;
|
||||||
@ -131,21 +149,21 @@ namespace plib {
|
|||||||
return argc;
|
return argc;
|
||||||
}
|
}
|
||||||
|
|
||||||
pstring options::split_paragraphs(pstring text, unsigned width, unsigned ident,
|
pstring options::split_paragraphs(pstring text, unsigned width, unsigned indent,
|
||||||
unsigned firstline_ident)
|
unsigned firstline_indent)
|
||||||
{
|
{
|
||||||
auto paragraphs = pstring_vector_t(text,"\n");
|
auto paragraphs = pstring_vector_t(text,"\n");
|
||||||
pstring ret("");
|
pstring ret("");
|
||||||
|
|
||||||
for (auto &p : paragraphs)
|
for (auto &p : paragraphs)
|
||||||
{
|
{
|
||||||
pstring line = pstring("").rpad(" ", firstline_ident);
|
pstring line = pstring("").rpad(" ", firstline_indent);
|
||||||
for (auto &s : pstring_vector_t(p, " "))
|
for (auto &s : pstring_vector_t(p, " "))
|
||||||
{
|
{
|
||||||
if (line.len() + s.len() > width)
|
if (line.len() + s.len() > width)
|
||||||
{
|
{
|
||||||
ret += line + "\n";
|
ret += line + "\n";
|
||||||
line = pstring("").rpad(" ", ident);
|
line = pstring("").rpad(" ", indent);
|
||||||
}
|
}
|
||||||
line += s + " ";
|
line += s + " ";
|
||||||
}
|
}
|
||||||
@ -155,67 +173,91 @@ namespace plib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pstring options::help(pstring description, pstring usage,
|
pstring options::help(pstring description, pstring usage,
|
||||||
unsigned width, unsigned ident)
|
unsigned width, unsigned indent)
|
||||||
{
|
{
|
||||||
pstring ret;
|
pstring ret;
|
||||||
|
|
||||||
ret = split_paragraphs(description, width, 0, 0) + "\n";
|
ret = split_paragraphs(description, width, 0, 0) + "\n";
|
||||||
ret += "Usage:\t" + usage + "\n\nOptions:\n";
|
ret += "Usage:\t" + usage + "\n\nOptions:\n\n";
|
||||||
|
|
||||||
for (auto & opt : m_opts )
|
for (auto & optbase : m_opts )
|
||||||
{
|
{
|
||||||
pstring line = "";
|
if (auto opt = dynamic_cast<option *>(optbase))
|
||||||
if (opt->short_opt() != "")
|
|
||||||
line += " -" + opt->short_opt();
|
|
||||||
if (opt->long_opt() != "")
|
|
||||||
{
|
{
|
||||||
if (line != "")
|
pstring line = "";
|
||||||
line += ", ";
|
if (opt->short_opt() != "")
|
||||||
else
|
line += " -" + opt->short_opt();
|
||||||
line = " ";
|
if (opt->long_opt() != "")
|
||||||
line += "--" + opt->long_opt();
|
|
||||||
if (opt->has_argument())
|
|
||||||
{
|
{
|
||||||
line += "=";
|
if (line != "")
|
||||||
option_str_limit *ol = dynamic_cast<option_str_limit *>(opt);
|
line += ", ";
|
||||||
if (ol)
|
|
||||||
{
|
|
||||||
for (auto &v : ol->limit())
|
|
||||||
{
|
|
||||||
line += v + "|";
|
|
||||||
}
|
|
||||||
line = line.left(line.len() - 1);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
line += "Value";
|
line = " ";
|
||||||
|
line += "--" + opt->long_opt();
|
||||||
|
if (opt->has_argument())
|
||||||
|
{
|
||||||
|
line += "=";
|
||||||
|
option_str_limit *ol = dynamic_cast<option_str_limit *>(opt);
|
||||||
|
if (ol)
|
||||||
|
{
|
||||||
|
for (auto &v : ol->limit())
|
||||||
|
{
|
||||||
|
line += v + "|";
|
||||||
|
}
|
||||||
|
line = line.left(line.len() - 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
line += "Value";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
line = line.rpad(" ", indent - 2) + " ";
|
||||||
|
if (line.len() > indent)
|
||||||
|
{
|
||||||
|
//ret += "TestGroup abc\n def gef\nxyz\n\n" ;
|
||||||
|
ret += line + "\n";
|
||||||
|
ret += split_paragraphs(opt->help(), width, indent, indent);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret += split_paragraphs(line + opt->help(), width, indent, 0);
|
||||||
}
|
}
|
||||||
line = line.rpad(" ", 20) + " ";
|
else if (auto grp = dynamic_cast<option_group *>(optbase))
|
||||||
if (line.len() > 21)
|
|
||||||
{
|
{
|
||||||
ret += line + "\n";
|
ret += "\n" + grp->group() + ":\n";
|
||||||
ret += split_paragraphs(opt->help(), 72, 21, 21);
|
if (grp->help() != "") ret += split_paragraphs(grp->help(), width, 4, 4) + "\n";
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
ret += split_paragraphs(line + opt->help(), 72, 21, 0);
|
pstring ex("");
|
||||||
|
for (auto & optbase : m_opts )
|
||||||
|
{
|
||||||
|
if (auto example = dynamic_cast<option_example *>(optbase))
|
||||||
|
{
|
||||||
|
ex += "> " + example->example()+"\n\n";
|
||||||
|
ex += split_paragraphs(example->help(), width, 4, 4) + "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ex.len() > 0)
|
||||||
|
{
|
||||||
|
ret += "\n\nExamples:\n\n" + ex;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
option *options::getopt_short(pstring arg)
|
option *options::getopt_short(pstring arg)
|
||||||
{
|
{
|
||||||
for (auto & opt : m_opts)
|
for (auto & optbase : m_opts)
|
||||||
{
|
{
|
||||||
if (opt->short_opt() == arg)
|
auto opt = dynamic_cast<option *>(optbase);
|
||||||
|
if (opt && opt->short_opt() == arg)
|
||||||
return opt;
|
return opt;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
option *options::getopt_long(pstring arg)
|
option *options::getopt_long(pstring arg)
|
||||||
{
|
{
|
||||||
for (auto & opt : m_opts)
|
for (auto & optbase : m_opts)
|
||||||
{
|
{
|
||||||
if (opt->long_opt() == arg)
|
auto opt = dynamic_cast<option *>(optbase);
|
||||||
|
if (opt && opt->long_opt() == arg)
|
||||||
return opt;
|
return opt;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -23,13 +23,44 @@ namespace plib {
|
|||||||
|
|
||||||
class options;
|
class options;
|
||||||
|
|
||||||
class option
|
class option_base
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
option();
|
option_base(options &parent, pstring help);
|
||||||
option(options &parent, pstring ashort, pstring along, pstring help, bool has_argument);
|
virtual ~option_base();
|
||||||
|
|
||||||
virtual ~option();
|
pstring help() { return m_help; }
|
||||||
|
private:
|
||||||
|
pstring m_help;
|
||||||
|
};
|
||||||
|
|
||||||
|
class option_group : public option_base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
option_group(options &parent, pstring group, pstring help)
|
||||||
|
: option_base(parent, help), m_group(group) { }
|
||||||
|
|
||||||
|
pstring group() { return m_group; }
|
||||||
|
private:
|
||||||
|
pstring m_group;
|
||||||
|
};
|
||||||
|
|
||||||
|
class option_example : public option_base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
option_example(options &parent, pstring group, pstring help)
|
||||||
|
: option_base(parent, help), m_example(group) { }
|
||||||
|
|
||||||
|
pstring example() { return m_example; }
|
||||||
|
private:
|
||||||
|
pstring m_example;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class option : public option_base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
option(options &parent, pstring ashort, pstring along, pstring help, bool has_argument);
|
||||||
|
|
||||||
/* no_argument options will be called with "" argument */
|
/* no_argument options will be called with "" argument */
|
||||||
|
|
||||||
@ -37,12 +68,10 @@ public:
|
|||||||
|
|
||||||
pstring short_opt() { return m_short; }
|
pstring short_opt() { return m_short; }
|
||||||
pstring long_opt() { return m_long; }
|
pstring long_opt() { return m_long; }
|
||||||
pstring help() { return m_help; }
|
|
||||||
bool has_argument() { return m_has_argument ; }
|
bool has_argument() { return m_has_argument ; }
|
||||||
private:
|
private:
|
||||||
pstring m_short;
|
pstring m_short;
|
||||||
pstring m_long;
|
pstring m_long;
|
||||||
pstring m_help;
|
|
||||||
bool m_has_argument;
|
bool m_has_argument;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -105,6 +134,20 @@ private:
|
|||||||
double m_val;
|
double m_val;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class option_vec : public option
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
option_vec(options &parent, pstring ashort, pstring along, pstring help)
|
||||||
|
: option(parent, ashort, along, help, true)
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual int parse(pstring argument) override;
|
||||||
|
|
||||||
|
std::vector<pstring> operator ()() { return m_val; }
|
||||||
|
private:
|
||||||
|
std::vector<pstring> m_val;
|
||||||
|
};
|
||||||
|
|
||||||
class options
|
class options
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -114,22 +157,22 @@ public:
|
|||||||
|
|
||||||
~options();
|
~options();
|
||||||
|
|
||||||
void register_option(option *opt);
|
void register_option(option_base *opt);
|
||||||
int parse(int argc, char *argv[]);
|
int parse(int argc, char *argv[]);
|
||||||
|
|
||||||
pstring help(pstring description, pstring usage,
|
pstring help(pstring description, pstring usage,
|
||||||
unsigned width = 72, unsigned ident = 20);
|
unsigned width = 72, unsigned indent = 20);
|
||||||
|
|
||||||
pstring app() { return m_app; }
|
pstring app() { return m_app; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static pstring split_paragraphs(pstring text, unsigned width, unsigned ident,
|
static pstring split_paragraphs(pstring text, unsigned width, unsigned indent,
|
||||||
unsigned firstline_ident);
|
unsigned firstline_indent);
|
||||||
|
|
||||||
option *getopt_short(pstring arg);
|
option *getopt_short(pstring arg);
|
||||||
option *getopt_long(pstring arg);
|
option *getopt_long(pstring arg);
|
||||||
|
|
||||||
std::vector<option *> m_opts;
|
std::vector<option_base *> m_opts;
|
||||||
pstring m_app;
|
pstring m_app;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -253,7 +253,7 @@ void ptokenizer::error(const pstring &errs)
|
|||||||
// A simple preprocessor
|
// A simple preprocessor
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
ppreprocessor::ppreprocessor()
|
ppreprocessor::ppreprocessor(std::vector<define_t> *defines)
|
||||||
: m_ifflag(0), m_level(0), m_lineno(0)
|
: m_ifflag(0), m_level(0), m_lineno(0)
|
||||||
{
|
{
|
||||||
m_expr_sep.push_back("!");
|
m_expr_sep.push_back("!");
|
||||||
@ -268,6 +268,13 @@ ppreprocessor::ppreprocessor()
|
|||||||
m_expr_sep.push_back("\t");
|
m_expr_sep.push_back("\t");
|
||||||
|
|
||||||
m_defines.insert({"__PLIB_PREPROCESSOR__", define_t("__PLIB_PREPROCESSOR__", "1")});
|
m_defines.insert({"__PLIB_PREPROCESSOR__", define_t("__PLIB_PREPROCESSOR__", "1")});
|
||||||
|
if (defines != nullptr)
|
||||||
|
{
|
||||||
|
for (auto & p : *defines)
|
||||||
|
{
|
||||||
|
m_defines.insert({p.m_name, p});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ppreprocessor::error(const pstring &err)
|
void ppreprocessor::error(const pstring &err)
|
||||||
|
@ -158,7 +158,6 @@ public:
|
|||||||
|
|
||||||
struct define_t
|
struct define_t
|
||||||
{
|
{
|
||||||
define_t() { };
|
|
||||||
define_t(const pstring &name, const pstring &replace)
|
define_t(const pstring &name, const pstring &replace)
|
||||||
: m_name(name), m_replace(replace)
|
: m_name(name), m_replace(replace)
|
||||||
{}
|
{}
|
||||||
@ -166,7 +165,7 @@ public:
|
|||||||
pstring m_replace;
|
pstring m_replace;
|
||||||
};
|
};
|
||||||
|
|
||||||
ppreprocessor();
|
ppreprocessor(std::vector<define_t> *defines = nullptr);
|
||||||
virtual ~ppreprocessor() {}
|
virtual ~ppreprocessor() {}
|
||||||
|
|
||||||
template<class ISTR, class OSTR>
|
template<class ISTR, class OSTR>
|
||||||
|
@ -62,7 +62,7 @@ public:
|
|||||||
public:
|
public:
|
||||||
using list_t = std::vector<callback_t *>;
|
using list_t = std::vector<callback_t *>;
|
||||||
|
|
||||||
virtual ~callback_t() { };
|
virtual ~callback_t() { }
|
||||||
|
|
||||||
virtual void register_state(state_manager_t &manager, const pstring &module) = 0;
|
virtual void register_state(state_manager_t &manager, const pstring &module) = 0;
|
||||||
virtual void on_pre_save() = 0;
|
virtual void on_pre_save() = 0;
|
||||||
|
@ -22,30 +22,6 @@ pstr_t pstring_t<putf8_traits>::m_zero = pstr_t(0);
|
|||||||
template<>
|
template<>
|
||||||
pstr_t pstring_t<pu8_traits>::m_zero = pstr_t(0);
|
pstr_t pstring_t<pu8_traits>::m_zero = pstr_t(0);
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Uncomment the following to override defaults
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define IMMEDIATE_MODE (1)
|
|
||||||
//#define DEBUG_MODE (0)
|
|
||||||
|
|
||||||
#ifdef MAME_DEBUG
|
|
||||||
#ifndef IMMEDIATE_MODE
|
|
||||||
#define IMMEDIATE_MODE (1)
|
|
||||||
#endif
|
|
||||||
#ifndef DEBUG_MODE
|
|
||||||
#define DEBUG_MODE (0)
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#ifndef IMMEDIATE_MODE
|
|
||||||
#define IMMEDIATE_MODE (1)
|
|
||||||
#endif
|
|
||||||
#ifndef DEBUG_MODE
|
|
||||||
#define DEBUG_MODE (0)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
pstring_t<F>::~pstring_t()
|
pstring_t<F>::~pstring_t()
|
||||||
{
|
{
|
||||||
@ -117,29 +93,22 @@ void pstring_t<F>::pcopy(const mem_t *from, int size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
const pstring_t<F> pstring_t<F>::substr(int start, int count) const
|
const pstring_t<F> pstring_t<F>::substr(unsigned start, unsigned count) const
|
||||||
{
|
{
|
||||||
pstring_t ret;
|
pstring_t ret;
|
||||||
int alen = (int) len();
|
unsigned alen = len();
|
||||||
if (start < 0)
|
if (start >= alen || count == 0)
|
||||||
start = 0;
|
|
||||||
if (start >= alen)
|
|
||||||
return ret;
|
return ret;
|
||||||
if (count <0 || start + count > alen)
|
if (start + count > alen)
|
||||||
count = alen - start;
|
count = alen - start;
|
||||||
const char *p = cstr();
|
const mem_t *p = cstr();
|
||||||
if (count <= 0)
|
// find start
|
||||||
ret.pcopy(p, 0);
|
for (unsigned i=0; i<start; i++)
|
||||||
else
|
p += F::codelen(p);
|
||||||
{
|
const char *e = p;
|
||||||
// find start
|
for (unsigned i=0; i<count; i++)
|
||||||
for (int i=0; i<start; i++)
|
e += F::codelen(e);
|
||||||
p += F::codelen(p);
|
ret.pcopy(p, e-p);
|
||||||
const char *e = p;
|
|
||||||
for (int i=0; i<count; i++)
|
|
||||||
e += F::codelen(e);
|
|
||||||
ret.pcopy(p, e-p);
|
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -446,9 +415,9 @@ int pstring_t<F>::find(const pstring_t &search, unsigned start) const
|
|||||||
{
|
{
|
||||||
const unsigned tlen = len();
|
const unsigned tlen = len();
|
||||||
const unsigned slen = search.len();
|
const unsigned slen = search.len();
|
||||||
const char *s = search.cstr();
|
const mem_t *s = search.cstr();
|
||||||
const unsigned startt = std::min(start, tlen);
|
const unsigned startt = std::min(start, tlen);
|
||||||
const char *t = cstr();
|
const mem_t *t = cstr();
|
||||||
for (std::size_t i=0; i<startt; i++)
|
for (std::size_t i=0; i<startt; i++)
|
||||||
t += F::codelen(t);
|
t += F::codelen(t);
|
||||||
for (int i=0; i <= (int) tlen - (int) startt - (int) slen; i++)
|
for (int i=0; i <= (int) tlen - (int) startt - (int) slen; i++)
|
||||||
|
@ -113,40 +113,41 @@ public:
|
|||||||
double as_double(bool *error = nullptr) const;
|
double as_double(bool *error = nullptr) const;
|
||||||
long as_long(bool *error = nullptr) const;
|
long as_long(bool *error = nullptr) const;
|
||||||
|
|
||||||
/*
|
|
||||||
* everything below MAY not work for utf8.
|
|
||||||
* Example a=s.find(EUROSIGN); b=s.substr(a,1); will deliver invalid utf8
|
|
||||||
*/
|
|
||||||
|
|
||||||
unsigned len() const
|
unsigned len() const
|
||||||
{
|
{
|
||||||
return F::len(m_ptr);
|
return F::len(m_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
pstring_t& operator+=(const code_t c) { mem_t buf[F::MAXCODELEN+1] = { 0 }; F::encode(c, buf); pcat(buf); return *this; }
|
pstring_t& operator+=(const code_t c) { mem_t buf[F::MAXCODELEN+1] = { 0 }; F::encode(c, buf); pcat(buf); return *this; }
|
||||||
friend pstring_t operator+(const pstring_t &lhs, const mem_t rhs) { return pstring_t(lhs) += rhs; }
|
friend pstring_t operator+(const pstring_t &lhs, const code_t rhs) { return pstring_t(lhs) += rhs; }
|
||||||
|
|
||||||
int find(const pstring_t &search, unsigned start = 0) const;
|
int find(const pstring_t &search, unsigned start = 0) const;
|
||||||
int find(const mem_t *search, unsigned start = 0) const;
|
int find(const mem_t *search, unsigned start = 0) const;
|
||||||
int find(const code_t search, unsigned start = 0) const { mem_t buf[F::MAXCODELEN+1] = { 0 }; F::encode(search, buf); return find(buf, start); };
|
int find(const code_t search, unsigned start = 0) const { mem_t buf[F::MAXCODELEN+1] = { 0 }; F::encode(search, buf); return find(buf, start); }
|
||||||
|
|
||||||
const pstring_t substr(int start, int count = -1) const ;
|
const pstring_t substr(unsigned start, unsigned count) const ;
|
||||||
|
const pstring_t substr(unsigned start) const { if (start>=len()) return pstring_t(""); else return substr(start, len()-start); }
|
||||||
|
|
||||||
const pstring_t left(unsigned count) const { return substr(0, count); }
|
const pstring_t left(unsigned count) const { return substr(0, count); }
|
||||||
const pstring_t right(unsigned count) const { return substr((int) len() - (int) count, count); }
|
const pstring_t right(unsigned count) const { if (len()<count) return pstring_t(*this); else return substr(len() - count, count); }
|
||||||
|
|
||||||
int find_first_not_of(const pstring_t &no) const;
|
int find_first_not_of(const pstring_t &no) const;
|
||||||
int find_last_not_of(const pstring_t &no) const;
|
int find_last_not_of(const pstring_t &no) const;
|
||||||
|
|
||||||
// FIXME:
|
|
||||||
code_t code_at(const unsigned pos) const { return F::code(F::nthcode(m_ptr->str(),pos)); }
|
|
||||||
|
|
||||||
const pstring_t ltrim(const pstring_t &ws = " \t\n\r") const;
|
const pstring_t ltrim(const pstring_t &ws = " \t\n\r") const;
|
||||||
const pstring_t rtrim(const pstring_t &ws = " \t\n\r") const;
|
const pstring_t rtrim(const pstring_t &ws = " \t\n\r") const;
|
||||||
const pstring_t trim(const pstring_t &ws = " \t\n\r") const { return this->ltrim(ws).rtrim(ws); }
|
const pstring_t trim(const pstring_t &ws = " \t\n\r") const { return this->ltrim(ws).rtrim(ws); }
|
||||||
|
|
||||||
const pstring_t rpad(const pstring_t &ws, const unsigned cnt) const;
|
const pstring_t rpad(const pstring_t &ws, const unsigned cnt) const;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* everything below MAY not work for utf8.
|
||||||
|
* Example a=s.find(EUROSIGN); b=s.substr(a,1); will deliver invalid utf8
|
||||||
|
*/
|
||||||
|
|
||||||
|
// FIXME:
|
||||||
|
code_t code_at(const unsigned pos) const { return F::code(F::nthcode(m_ptr->str(),pos)); }
|
||||||
|
|
||||||
const pstring_t ucase() const;
|
const pstring_t ucase() const;
|
||||||
|
|
||||||
static void resetmem();
|
static void resetmem();
|
||||||
@ -332,6 +333,8 @@ public:
|
|||||||
// construction with copy
|
// construction with copy
|
||||||
pstringbuffer(const char *string) {init(); if (string != nullptr) pcopy(string); }
|
pstringbuffer(const char *string) {init(); if (string != nullptr) pcopy(string); }
|
||||||
pstringbuffer(const pstring &string) {init(); pcopy(string); }
|
pstringbuffer(const pstring &string) {init(); pcopy(string); }
|
||||||
|
pstringbuffer(const pstringbuffer &stringb) {init(); pcopy(stringb); }
|
||||||
|
pstringbuffer(pstringbuffer &&b) : m_ptr(b.m_ptr), m_size(b.m_size), m_len(b.m_len) { b.m_ptr = nullptr; b.m_size = 0; b.m_len = 0; }
|
||||||
|
|
||||||
// assignment operators
|
// assignment operators
|
||||||
pstringbuffer &operator=(const char *string) { pcopy(string); return *this; }
|
pstringbuffer &operator=(const char *string) { pcopy(string); return *this; }
|
||||||
|
@ -26,39 +26,56 @@ class tool_options_t : public plib::options
|
|||||||
public:
|
public:
|
||||||
tool_options_t() :
|
tool_options_t() :
|
||||||
plib::options(),
|
plib::options(),
|
||||||
opt_ttr (*this, "t", "time_to_run", 1.0, "time to run the emulation (seconds)"),
|
opt_grp1(*this, "General options", "The following options apply to all commands."),
|
||||||
opt_name(*this, "n", "name", "", "netlist in file to run; default is first one"),
|
|
||||||
opt_logs(*this, "l", "logs", "", "colon separated list of terminals to log"),
|
|
||||||
opt_file(*this, "f", "file", "-", "file to process (default is stdin)"),
|
|
||||||
opt_type(*this, "y", "type", "spice", "spice:eagle", "type of file to be converted: spice,eagle"),
|
|
||||||
opt_cmd (*this, "c", "cmd", "run", "run:convert:listdevices:static", "run|convert|listdevices|static"),
|
opt_cmd (*this, "c", "cmd", "run", "run:convert:listdevices:static", "run|convert|listdevices|static"),
|
||||||
opt_inp(*this, "i", "input", "", "input file to process (default is none)"),
|
opt_file(*this, "f", "file", "-", "file to process (default is stdin)"),
|
||||||
|
opt_defines(*this, "D", "define", "predefine value as macro, e.g. -Dname=value. If '=value' is omitted predefine it as 1. This option may be specified repeatedly."),
|
||||||
opt_verb(*this, "v", "verbose", "be verbose - this produces lots of output"),
|
opt_verb(*this, "v", "verbose", "be verbose - this produces lots of output"),
|
||||||
opt_quiet(*this, "q", "quiet", "be quiet - no warnings"),
|
opt_quiet(*this, "q", "quiet", "be quiet - no warnings"),
|
||||||
opt_version(*this, "", "version", "display version and exit"),
|
opt_version(*this, "", "version", "display version and exit"),
|
||||||
opt_help(*this, "h", "help", "display help and exit")
|
opt_help(*this, "h", "help", "display help and exit"),
|
||||||
{}
|
opt_grp2(*this, "Options for run and static commands", "These options apply to run and static commands."),
|
||||||
|
opt_name(*this, "n", "name", "", "the netlist in file specified by ""-f"" option to run; default is first one"),
|
||||||
|
opt_grp3(*this, "Options for run command", "These options are only used by the run command."),
|
||||||
|
opt_ttr (*this, "t", "time_to_run", 1.0, "time to run the emulation (seconds)"),
|
||||||
|
opt_logs(*this, "l", "log" , "define terminal to log. This option may be specified repeatedly."),
|
||||||
|
opt_inp(*this, "i", "input", "", "input file to process (default is none)"),
|
||||||
|
opt_grp4(*this, "Options for convert command", "These options are only used by the convert command."),
|
||||||
|
opt_type(*this, "y", "type", "spice", "spice:eagle", "type of file to be converted: spice,eagle"),
|
||||||
|
|
||||||
plib::option_double opt_ttr;
|
opt_ex1(*this, "nltool -c run -t 3.5 -f nl_examples/cdelay.c -n cap_delay",
|
||||||
plib::option_str opt_name;
|
"Run netlist \"cap_delay\" from file nl_examples/cdelay.c for 3.5 seconds"),
|
||||||
plib::option_str opt_logs;
|
opt_ex2(*this, "nltool --cmd=listdevices",
|
||||||
plib::option_str opt_file;
|
"List all known devices.")
|
||||||
plib::option_str_limit opt_type;
|
{}
|
||||||
|
|
||||||
|
plib::option_group opt_grp1;
|
||||||
plib::option_str_limit opt_cmd;
|
plib::option_str_limit opt_cmd;
|
||||||
plib::option_str opt_inp;
|
plib::option_str opt_file;
|
||||||
|
plib::option_vec opt_defines;
|
||||||
plib::option_bool opt_verb;
|
plib::option_bool opt_verb;
|
||||||
plib::option_bool opt_quiet;
|
plib::option_bool opt_quiet;
|
||||||
plib::option_bool opt_version;
|
plib::option_bool opt_version;
|
||||||
plib::option_bool opt_help;
|
plib::option_bool opt_help;
|
||||||
|
plib::option_group opt_grp2;
|
||||||
|
plib::option_str opt_name;
|
||||||
|
plib::option_group opt_grp3;
|
||||||
|
plib::option_double opt_ttr;
|
||||||
|
plib::option_vec opt_logs;
|
||||||
|
plib::option_str opt_inp;
|
||||||
|
plib::option_group opt_grp4;
|
||||||
|
plib::option_str_limit opt_type;
|
||||||
|
plib::option_example opt_ex1;
|
||||||
|
plib::option_example opt_ex2;
|
||||||
};
|
};
|
||||||
|
|
||||||
plib::pstdout pout_strm;
|
static plib::pstdout pout_strm;
|
||||||
plib::pstderr perr_strm;
|
static plib::pstderr perr_strm;
|
||||||
|
|
||||||
plib::pstream_fmt_writer_t pout(pout_strm);
|
static plib::pstream_fmt_writer_t pout(pout_strm);
|
||||||
plib::pstream_fmt_writer_t perr(perr_strm);
|
static plib::pstream_fmt_writer_t perr(perr_strm);
|
||||||
|
|
||||||
NETLIST_START(dummy)
|
static NETLIST_START(dummy)
|
||||||
/* Standard stuff */
|
/* Standard stuff */
|
||||||
|
|
||||||
CLOCK(clk, 1000) // 1000 Hz
|
CLOCK(clk, 1000) // 1000 Hz
|
||||||
@ -75,7 +92,7 @@ class netlist_tool_t : public netlist::netlist_t
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
netlist_tool_t(const pstring &aname)
|
netlist_tool_t(const pstring &aname)
|
||||||
: netlist::netlist_t(aname), m_opts(nullptr), m_setup(nullptr)
|
: netlist::netlist_t(aname), m_setup(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,21 +100,26 @@ public:
|
|||||||
{
|
{
|
||||||
if (m_setup != nullptr)
|
if (m_setup != nullptr)
|
||||||
plib::pfree(m_setup);
|
plib::pfree(m_setup);
|
||||||
};
|
}
|
||||||
|
|
||||||
void init()
|
void init()
|
||||||
{
|
{
|
||||||
m_setup = plib::palloc<netlist::setup_t>(*this);
|
m_setup = plib::palloc<netlist::setup_t>(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void read_netlist(const pstring &filename, const pstring &name)
|
void read_netlist(const pstring &filename, const pstring &name,
|
||||||
|
const std::vector<pstring> &logs,
|
||||||
|
const std::vector<pstring> &defines)
|
||||||
{
|
{
|
||||||
// read the netlist ...
|
// read the netlist ...
|
||||||
|
|
||||||
|
for (auto & d : defines)
|
||||||
|
m_setup->register_define(d);
|
||||||
|
|
||||||
m_setup->register_source(plib::make_unique_base<netlist::source_t,
|
m_setup->register_source(plib::make_unique_base<netlist::source_t,
|
||||||
netlist::source_file_t>(filename));
|
netlist::source_file_t>(filename));
|
||||||
m_setup->include(name);
|
m_setup->include(name);
|
||||||
log_setup();
|
log_setup(logs);
|
||||||
|
|
||||||
// start devices
|
// start devices
|
||||||
m_setup->start_devices();
|
m_setup->start_devices();
|
||||||
@ -106,11 +128,10 @@ public:
|
|||||||
this->reset();
|
this->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void log_setup()
|
void log_setup(const std::vector<pstring> &logs)
|
||||||
{
|
{
|
||||||
log().debug("Creating dynamic logs ...\n");
|
log().debug("Creating dynamic logs ...\n");
|
||||||
plib::pstring_vector_t ll(m_opts ? m_opts->opt_logs() : "" , ":");
|
for (auto & log : logs)
|
||||||
for (auto & log : ll)
|
|
||||||
{
|
{
|
||||||
pstring name = "log_" + log;
|
pstring name = "log_" + log;
|
||||||
/*netlist_device_t *nc = */ m_setup->register_dev("LOG", name);
|
/*netlist_device_t *nc = */ m_setup->register_dev("LOG", name);
|
||||||
@ -120,8 +141,6 @@ public:
|
|||||||
|
|
||||||
netlist::setup_t &setup() { return *m_setup; }
|
netlist::setup_t &setup() { return *m_setup; }
|
||||||
|
|
||||||
tool_options_t *m_opts;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void vlog(const plib::plog_level &l, const pstring &ls) const override
|
void vlog(const plib::plog_level &l, const pstring &ls) const override
|
||||||
@ -136,6 +155,9 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// FIXME: usage should go elsewhere
|
||||||
|
void usage(tool_options_t &opts);
|
||||||
|
|
||||||
void usage(tool_options_t &opts)
|
void usage(tool_options_t &opts)
|
||||||
{
|
{
|
||||||
pout("{}\n", opts.help(
|
pout("{}\n", opts.help(
|
||||||
@ -208,13 +230,12 @@ static std::vector<input_t> read_input(const netlist::setup_t &setup, pstring fn
|
|||||||
|
|
||||||
static void run(tool_options_t &opts)
|
static void run(tool_options_t &opts)
|
||||||
{
|
{
|
||||||
netlist_tool_t nt("netlist");
|
|
||||||
plib::chrono::timer<plib::chrono::system_ticks> t;
|
plib::chrono::timer<plib::chrono::system_ticks> t;
|
||||||
//plib::perftime_t<plib::exact_ticks> t;
|
|
||||||
|
|
||||||
t.start();
|
t.start();
|
||||||
|
|
||||||
nt.m_opts = &opts;
|
netlist_tool_t nt("netlist");
|
||||||
|
//plib::perftime_t<plib::exact_ticks> t;
|
||||||
|
|
||||||
nt.init();
|
nt.init();
|
||||||
|
|
||||||
if (!opts.opt_verb())
|
if (!opts.opt_verb())
|
||||||
@ -222,7 +243,9 @@ static void run(tool_options_t &opts)
|
|||||||
if (opts.opt_quiet())
|
if (opts.opt_quiet())
|
||||||
nt.log().warning.set_enabled(false);
|
nt.log().warning.set_enabled(false);
|
||||||
|
|
||||||
nt.read_netlist(opts.opt_file(), opts.opt_name());
|
nt.read_netlist(opts.opt_file(), opts.opt_name(),
|
||||||
|
opts.opt_logs(),
|
||||||
|
opts.opt_defines());
|
||||||
|
|
||||||
std::vector<input_t> inps = read_input(nt.setup(), opts.opt_inp());
|
std::vector<input_t> inps = read_input(nt.setup(), opts.opt_inp());
|
||||||
|
|
||||||
@ -258,13 +281,14 @@ static void static_compile(tool_options_t &opts)
|
|||||||
{
|
{
|
||||||
netlist_tool_t nt("netlist");
|
netlist_tool_t nt("netlist");
|
||||||
|
|
||||||
nt.m_opts = &opts;
|
|
||||||
nt.init();
|
nt.init();
|
||||||
|
|
||||||
nt.log().verbose.set_enabled(false);
|
nt.log().verbose.set_enabled(false);
|
||||||
nt.log().warning.set_enabled(false);
|
nt.log().warning.set_enabled(false);
|
||||||
|
|
||||||
nt.read_netlist(opts.opt_file(), opts.opt_name());
|
nt.read_netlist(opts.opt_file(), opts.opt_name(),
|
||||||
|
opts.opt_logs(),
|
||||||
|
opts.opt_defines());
|
||||||
|
|
||||||
nt.solver()->create_solver_code(pout_strm);
|
nt.solver()->create_solver_code(pout_strm);
|
||||||
|
|
||||||
@ -276,16 +300,22 @@ static void static_compile(tool_options_t &opts)
|
|||||||
listdevices - list all known devices
|
listdevices - list all known devices
|
||||||
-------------------------------------------------*/
|
-------------------------------------------------*/
|
||||||
|
|
||||||
static void listdevices()
|
static void listdevices(tool_options_t &opts)
|
||||||
{
|
{
|
||||||
netlist_tool_t nt("netlist");
|
netlist_tool_t nt("netlist");
|
||||||
nt.init();
|
nt.init();
|
||||||
|
if (!opts.opt_verb())
|
||||||
|
nt.log().verbose.set_enabled(false);
|
||||||
|
if (opts.opt_quiet())
|
||||||
|
nt.log().warning.set_enabled(false);
|
||||||
|
|
||||||
netlist::factory_list_t &list = nt.setup().factory();
|
netlist::factory_list_t &list = nt.setup().factory();
|
||||||
|
|
||||||
nt.setup().register_source(plib::make_unique_base<netlist::source_t,
|
nt.setup().register_source(plib::make_unique_base<netlist::source_t,
|
||||||
netlist::source_proc_t>("dummy", &netlist_dummy));
|
netlist::source_proc_t>("dummy", &netlist_dummy));
|
||||||
nt.setup().include("dummy");
|
nt.setup().include("dummy");
|
||||||
|
|
||||||
|
|
||||||
nt.setup().start_devices();
|
nt.setup().start_devices();
|
||||||
nt.setup().resolve_inputs();
|
nt.setup().resolve_inputs();
|
||||||
|
|
||||||
@ -294,7 +324,7 @@ static void listdevices()
|
|||||||
for (auto & f : list)
|
for (auto & f : list)
|
||||||
{
|
{
|
||||||
pstring out = plib::pfmt("{1} {2}(<id>")(f->classname(),"-20")(f->name());
|
pstring out = plib::pfmt("{1} {2}(<id>")(f->classname(),"-20")(f->name());
|
||||||
pstring terms("");
|
std::vector<pstring> terms;
|
||||||
|
|
||||||
auto d = f->Create(nt.setup().netlist(), f->name() + "_lc");
|
auto d = f->Create(nt.setup().netlist(), f->name() + "_lc");
|
||||||
// get the list of terminals ...
|
// get the list of terminals ...
|
||||||
@ -305,7 +335,7 @@ static void listdevices()
|
|||||||
{
|
{
|
||||||
pstring tn(t.second->name().substr(d->name().len()+1));
|
pstring tn(t.second->name().substr(d->name().len()+1));
|
||||||
if (tn.find(".")<0)
|
if (tn.find(".")<0)
|
||||||
terms += ", " + tn;
|
terms.push_back(tn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,14 +345,23 @@ static void listdevices()
|
|||||||
{
|
{
|
||||||
pstring tn(t.first.substr(d->name().len()+1));
|
pstring tn(t.first.substr(d->name().len()+1));
|
||||||
if (tn.find(".")<0)
|
if (tn.find(".")<0)
|
||||||
terms += ", " + tn;
|
{
|
||||||
|
terms.push_back(tn);
|
||||||
|
pstring resolved = nt.setup().resolve_alias(t.first);
|
||||||
|
if (resolved != t.first)
|
||||||
|
{
|
||||||
|
auto found = std::find(terms.begin(), terms.end(), resolved.substr(d->name().len()+1));
|
||||||
|
if (found!=terms.end())
|
||||||
|
terms.erase(found);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f->param_desc().startsWith("+"))
|
if (f->param_desc().startsWith("+"))
|
||||||
{
|
{
|
||||||
out += "," + f->param_desc().substr(1);
|
out += "," + f->param_desc().substr(1);
|
||||||
terms = "";
|
terms.clear();
|
||||||
}
|
}
|
||||||
else if (f->param_desc() == "-")
|
else if (f->param_desc() == "-")
|
||||||
{
|
{
|
||||||
@ -334,8 +373,13 @@ static void listdevices()
|
|||||||
}
|
}
|
||||||
out += ")";
|
out += ")";
|
||||||
printf("%s\n", out.cstr());
|
printf("%s\n", out.cstr());
|
||||||
if (terms != "")
|
if (terms.size() > 0)
|
||||||
printf("Terminals: %s\n", terms.substr(1).cstr());
|
{
|
||||||
|
pstring t = "";
|
||||||
|
for (auto & j : terms)
|
||||||
|
t += "," + j;
|
||||||
|
printf("Terminals: %s\n", t.substr(1).cstr());
|
||||||
|
}
|
||||||
devs.push_back(std::move(d));
|
devs.push_back(std::move(d));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -390,7 +434,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
pstring cmd = opts.opt_cmd();
|
pstring cmd = opts.opt_cmd();
|
||||||
if (cmd == "listdevices")
|
if (cmd == "listdevices")
|
||||||
listdevices();
|
listdevices(opts);
|
||||||
else if (cmd == "run")
|
else if (cmd == "run")
|
||||||
run(opts);
|
run(opts);
|
||||||
else if (cmd == "static")
|
else if (cmd == "static")
|
||||||
|
@ -126,7 +126,7 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void convert(nlwav_options_t &opts)
|
static void convert(nlwav_options_t &opts)
|
||||||
{
|
{
|
||||||
plib::pofilestream fo(opts.opt_out());
|
plib::pofilestream fo(opts.opt_out());
|
||||||
if (fo.bad())
|
if (fo.bad())
|
||||||
@ -157,8 +157,8 @@ void convert(nlwav_options_t &opts)
|
|||||||
while(fin.readline(line))
|
while(fin.readline(line))
|
||||||
{
|
{
|
||||||
#if 1
|
#if 1
|
||||||
float t = 0.0; float v = 0.0;
|
double t = 0.0; double v = 0.0;
|
||||||
sscanf(line.cstr(), "%f %f", &t, &v);
|
sscanf(line.cstr(), "%lf %lf", &t, &v);
|
||||||
while (t >= ct)
|
while (t >= ct)
|
||||||
{
|
{
|
||||||
outsam += (ct - lt) * cursam;
|
outsam += (ct - lt) * cursam;
|
||||||
@ -214,7 +214,7 @@ void convert(nlwav_options_t &opts)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void usage(plib::pstream_fmt_writer_t &fw, nlwav_options_t &opts)
|
static void usage(plib::pstream_fmt_writer_t &fw, nlwav_options_t &opts)
|
||||||
{
|
{
|
||||||
fw("{}\n", opts.help("Convert netlist log files into wav files.\n",
|
fw("{}\n", opts.help("Convert netlist log files into wav files.\n",
|
||||||
"nltool [options]").cstr());
|
"nltool [options]").cstr());
|
||||||
|
@ -126,8 +126,7 @@ public:
|
|||||||
, m_stat_vsolver_calls(*this, "m_stat_vsolver_calls", 0)
|
, m_stat_vsolver_calls(*this, "m_stat_vsolver_calls", 0)
|
||||||
, m_iterative_fail(*this, "m_iterative_fail", 0)
|
, m_iterative_fail(*this, "m_iterative_fail", 0)
|
||||||
, m_iterative_total(*this, "m_iterative_total", 0)
|
, m_iterative_total(*this, "m_iterative_total", 0)
|
||||||
, m_last_step(*this, "m_last_step", netlist_time::quantum())
|
, m_last_step(*this, "m_last_step", netlist_time::zero())
|
||||||
, m_cur_ts(*this, "m_cur_ts", 0)
|
|
||||||
, m_fb_sync(*this, "FB_sync")
|
, m_fb_sync(*this, "FB_sync")
|
||||||
, m_Q_sync(*this, "Q_sync")
|
, m_Q_sync(*this, "Q_sync")
|
||||||
, m_sort(sort)
|
, m_sort(sort)
|
||||||
@ -139,7 +138,7 @@ public:
|
|||||||
|
|
||||||
void setup(analog_net_t::list_t &nets) { vsetup(nets); }
|
void setup(analog_net_t::list_t &nets) { vsetup(nets); }
|
||||||
|
|
||||||
const netlist_time solve_base();
|
void solve_base();
|
||||||
|
|
||||||
const netlist_time solve();
|
const netlist_time solve();
|
||||||
|
|
||||||
@ -149,7 +148,7 @@ public:
|
|||||||
void update_forced();
|
void update_forced();
|
||||||
void update_after(const netlist_time &after)
|
void update_after(const netlist_time &after)
|
||||||
{
|
{
|
||||||
m_Q_sync.net().toggle_new_Q();
|
m_Q_sync.net().force_queue_execution();
|
||||||
m_Q_sync.net().reschedule_in_queue(after);
|
m_Q_sync.net().reschedule_in_queue(after);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,7 +176,7 @@ protected:
|
|||||||
virtual void vsetup(analog_net_t::list_t &nets) = 0;
|
virtual void vsetup(analog_net_t::list_t &nets) = 0;
|
||||||
virtual int vsolve_non_dynamic(const bool newton_raphson) = 0;
|
virtual int vsolve_non_dynamic(const bool newton_raphson) = 0;
|
||||||
|
|
||||||
/* virtual */ netlist_time compute_next_timestep();
|
netlist_time compute_next_timestep(const double cur_ts);
|
||||||
/* virtual */ void add_term(int net_idx, terminal_t *term);
|
/* virtual */ void add_term(int net_idx, terminal_t *term);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -204,11 +203,9 @@ protected:
|
|||||||
state_var<int> m_iterative_fail;
|
state_var<int> m_iterative_fail;
|
||||||
state_var<int> m_iterative_total;
|
state_var<int> m_iterative_total;
|
||||||
|
|
||||||
inline nl_double current_timestep() { return m_cur_ts; }
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
state_var<netlist_time> m_last_step;
|
state_var<netlist_time> m_last_step;
|
||||||
state_var<nl_double> m_cur_ts;
|
|
||||||
std::vector<core_device_t *> m_step_devices;
|
std::vector<core_device_t *> m_step_devices;
|
||||||
std::vector<core_device_t *> m_dynamic_devices;
|
std::vector<core_device_t *> m_dynamic_devices;
|
||||||
|
|
||||||
|
@ -377,7 +377,7 @@ void matrix_solver_direct_t<m_N, storage_N>::LE_back_subst(
|
|||||||
|
|
||||||
|
|
||||||
template <unsigned m_N, unsigned storage_N>
|
template <unsigned m_N, unsigned storage_N>
|
||||||
int matrix_solver_direct_t<m_N, storage_N>::solve_non_dynamic(ATTR_UNUSED const bool newton_raphson)
|
int matrix_solver_direct_t<m_N, storage_N>::solve_non_dynamic(const bool newton_raphson)
|
||||||
{
|
{
|
||||||
nl_double new_V[storage_N]; // = { 0.0 };
|
nl_double new_V[storage_N]; // = { 0.0 };
|
||||||
|
|
||||||
|
@ -198,6 +198,8 @@ nl_double matrix_solver_direct_t<m_N, storage_N>::compute_next_timestep()
|
|||||||
}
|
}
|
||||||
if (new_solver_timestep < m_params.m_min_timestep)
|
if (new_solver_timestep < m_params.m_min_timestep)
|
||||||
new_solver_timestep = m_params.m_min_timestep;
|
new_solver_timestep = m_params.m_min_timestep;
|
||||||
|
if (new_solver_timestep > m_params.m_max_timestep)
|
||||||
|
new_solver_timestep = m_params.m_max_timestep;
|
||||||
}
|
}
|
||||||
//if (new_solver_timestep > 10.0 * hn)
|
//if (new_solver_timestep > 10.0 * hn)
|
||||||
// new_solver_timestep = 10.0 * hn;
|
// new_solver_timestep = 10.0 * hn;
|
||||||
@ -566,7 +568,7 @@ void matrix_solver_direct_t<m_N, storage_N>::store(
|
|||||||
|
|
||||||
|
|
||||||
template <unsigned m_N, unsigned storage_N>
|
template <unsigned m_N, unsigned storage_N>
|
||||||
int matrix_solver_direct_t<m_N, storage_N>::solve_non_dynamic(ATTR_UNUSED const bool newton_raphson)
|
int matrix_solver_direct_t<m_N, storage_N>::solve_non_dynamic(const bool newton_raphson)
|
||||||
{
|
{
|
||||||
nl_double new_V[storage_N]; // = { 0.0 };
|
nl_double new_V[storage_N]; // = { 0.0 };
|
||||||
|
|
||||||
|
@ -219,7 +219,7 @@ void matrix_solver_sm_t<m_N, storage_N>::LE_compute_x(
|
|||||||
|
|
||||||
|
|
||||||
template <unsigned m_N, unsigned storage_N>
|
template <unsigned m_N, unsigned storage_N>
|
||||||
int matrix_solver_sm_t<m_N, storage_N>::solve_non_dynamic(ATTR_UNUSED const bool newton_raphson)
|
int matrix_solver_sm_t<m_N, storage_N>::solve_non_dynamic(const bool newton_raphson)
|
||||||
{
|
{
|
||||||
static const bool incremental = true;
|
static const bool incremental = true;
|
||||||
static unsigned cnt = 0;
|
static unsigned cnt = 0;
|
||||||
|
@ -227,7 +227,7 @@ void matrix_solver_w_t<m_N, storage_N>::LE_compute_x(
|
|||||||
|
|
||||||
|
|
||||||
template <unsigned m_N, unsigned storage_N>
|
template <unsigned m_N, unsigned storage_N>
|
||||||
int matrix_solver_w_t<m_N, storage_N>::solve_non_dynamic(ATTR_UNUSED const bool newton_raphson)
|
int matrix_solver_w_t<m_N, storage_N>::solve_non_dynamic(const bool newton_raphson)
|
||||||
{
|
{
|
||||||
const auto iN = N();
|
const auto iN = N();
|
||||||
|
|
||||||
|
@ -172,7 +172,8 @@ void matrix_solver_t::setup_base(analog_net_t::list_t &nets)
|
|||||||
log().debug("Added input\n");
|
log().debug("Added input\n");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
case terminal_t::OUTPUT:
|
||||||
|
case terminal_t::PARAM:
|
||||||
log().fatal("unhandled element found\n");
|
log().fatal("unhandled element found\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -335,7 +336,7 @@ void matrix_solver_t::setup_matrix()
|
|||||||
}
|
}
|
||||||
log().verbose("Number of mults/adds for {1}: {2}", name(), ops);
|
log().verbose("Number of mults/adds for {1}: {2}", name(), ops);
|
||||||
|
|
||||||
if (0)
|
if ((0))
|
||||||
for (unsigned k = 0; k < iN; k++)
|
for (unsigned k = 0; k < iN; k++)
|
||||||
{
|
{
|
||||||
pstring line = plib::pfmt("{1}")(k, "3");
|
pstring line = plib::pfmt("{1}")(k, "3");
|
||||||
@ -390,7 +391,7 @@ void matrix_solver_t::update() NOEXCEPT
|
|||||||
|
|
||||||
if (m_params.m_dynamic && has_timestep_devices() && new_timestep > netlist_time::zero())
|
if (m_params.m_dynamic && has_timestep_devices() && new_timestep > netlist_time::zero())
|
||||||
{
|
{
|
||||||
m_Q_sync.net().toggle_new_Q();
|
m_Q_sync.net().force_queue_execution();
|
||||||
m_Q_sync.net().reschedule_in_queue(new_timestep);
|
m_Q_sync.net().reschedule_in_queue(new_timestep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -401,7 +402,7 @@ void matrix_solver_t::update_forced()
|
|||||||
|
|
||||||
if (m_params.m_dynamic && has_timestep_devices())
|
if (m_params.m_dynamic && has_timestep_devices())
|
||||||
{
|
{
|
||||||
m_Q_sync.net().toggle_new_Q();
|
m_Q_sync.net().force_queue_execution();
|
||||||
m_Q_sync.net().reschedule_in_queue(netlist_time::from_double(m_params.m_min_timestep));
|
m_Q_sync.net().reschedule_in_queue(netlist_time::from_double(m_params.m_min_timestep));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -413,7 +414,7 @@ void matrix_solver_t::step(const netlist_time &delta)
|
|||||||
m_step_devices[k]->step_time(dd);
|
m_step_devices[k]->step_time(dd);
|
||||||
}
|
}
|
||||||
|
|
||||||
const netlist_time matrix_solver_t::solve_base()
|
void matrix_solver_t::solve_base()
|
||||||
{
|
{
|
||||||
m_stat_vsolver_calls++;
|
m_stat_vsolver_calls++;
|
||||||
if (has_dynamic_devices())
|
if (has_dynamic_devices())
|
||||||
@ -441,7 +442,6 @@ const netlist_time matrix_solver_t::solve_base()
|
|||||||
{
|
{
|
||||||
this->vsolve_non_dynamic(false);
|
this->vsolve_non_dynamic(false);
|
||||||
}
|
}
|
||||||
return this->compute_next_timestep();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const netlist_time matrix_solver_t::solve()
|
const netlist_time matrix_solver_t::solve()
|
||||||
@ -451,18 +451,17 @@ const netlist_time matrix_solver_t::solve()
|
|||||||
|
|
||||||
// We are already up to date. Avoid oscillations.
|
// We are already up to date. Avoid oscillations.
|
||||||
// FIXME: Make this a parameter!
|
// FIXME: Make this a parameter!
|
||||||
if (delta < netlist_time::from_nsec(1)) // 20000
|
if (delta < netlist_time::quantum())
|
||||||
return netlist_time::from_nsec(0);
|
return netlist_time::zero();
|
||||||
|
|
||||||
/* update all terminals for new time step */
|
/* update all terminals for new time step */
|
||||||
m_last_step = now;
|
m_last_step = now;
|
||||||
m_cur_ts = delta.as_double();
|
|
||||||
|
|
||||||
step(delta);
|
step(delta);
|
||||||
|
solve_base();
|
||||||
const netlist_time next_time_step = solve_base();
|
const netlist_time next_time_step = compute_next_timestep(delta.as_double());
|
||||||
|
|
||||||
update_inputs();
|
update_inputs();
|
||||||
|
|
||||||
return next_time_step;
|
return next_time_step;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -496,7 +495,7 @@ void matrix_solver_t::add_term(int k, terminal_t *term)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
netlist_time matrix_solver_t::compute_next_timestep()
|
netlist_time matrix_solver_t::compute_next_timestep(const double cur_ts)
|
||||||
{
|
{
|
||||||
nl_double new_solver_timestep = m_params.m_max_timestep;
|
nl_double new_solver_timestep = m_params.m_max_timestep;
|
||||||
|
|
||||||
@ -512,15 +511,15 @@ netlist_time matrix_solver_t::compute_next_timestep()
|
|||||||
terms_t *t = m_terms[k];
|
terms_t *t = m_terms[k];
|
||||||
|
|
||||||
const nl_double DD_n = (n->Q_Analog() - t->m_last_V);
|
const nl_double DD_n = (n->Q_Analog() - t->m_last_V);
|
||||||
const nl_double hn = current_timestep();
|
const nl_double hn = cur_ts;
|
||||||
|
|
||||||
nl_double DD2 = (DD_n / hn - t->m_DD_n_m_1 / t->m_h_n_m_1) / (hn + t->m_h_n_m_1);
|
nl_double DD2 = (DD_n / hn - t->m_DD_n_m_1 / t->m_h_n_m_1) / (hn + t->m_h_n_m_1);
|
||||||
nl_double new_net_timestep;
|
nl_double new_net_timestep;
|
||||||
|
|
||||||
t->m_h_n_m_1 = hn;
|
t->m_h_n_m_1 = hn;
|
||||||
t->m_DD_n_m_1 = DD_n;
|
t->m_DD_n_m_1 = DD_n;
|
||||||
if (std::abs(DD2) > NL_FCONST(1e-30)) // avoid div-by-zero
|
if (std::fabs(DD2) > NL_FCONST(1e-60)) // avoid div-by-zero
|
||||||
new_net_timestep = std::sqrt(m_params.m_lte / std::abs(NL_FCONST(0.5)*DD2));
|
new_net_timestep = std::sqrt(m_params.m_lte / std::fabs(NL_FCONST(0.5)*DD2));
|
||||||
else
|
else
|
||||||
new_net_timestep = m_params.m_max_timestep;
|
new_net_timestep = m_params.m_max_timestep;
|
||||||
|
|
||||||
@ -534,7 +533,10 @@ netlist_time matrix_solver_t::compute_next_timestep()
|
|||||||
}
|
}
|
||||||
//if (new_solver_timestep > 10.0 * hn)
|
//if (new_solver_timestep > 10.0 * hn)
|
||||||
// new_solver_timestep = 10.0 * hn;
|
// new_solver_timestep = 10.0 * hn;
|
||||||
return netlist_time::from_double(new_solver_timestep);
|
/*
|
||||||
|
* FIXME: Factor 2 below is important. Without, we get timing issues. This must be a bug elsewhere.
|
||||||
|
*/
|
||||||
|
return std::max(netlist_time::from_double(new_solver_timestep), netlist_time::quantum() * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -713,13 +715,15 @@ void NETLIB_NAME(solver)::post_start()
|
|||||||
|
|
||||||
if (m_params.m_dynamic)
|
if (m_params.m_dynamic)
|
||||||
{
|
{
|
||||||
m_params.m_max_timestep *= NL_FCONST(1000.0);
|
m_params.m_max_timestep *= 1;//NL_FCONST(1000.0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_params.m_min_timestep = m_params.m_max_timestep;
|
m_params.m_min_timestep = m_params.m_max_timestep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//m_params.m_max_timestep = std::max(m_params.m_max_timestep, m_params.m_max_timestep::)
|
||||||
|
|
||||||
// Override log statistics
|
// Override log statistics
|
||||||
pstring p = plib::util::environment("NL_STATS");
|
pstring p = plib::util::environment("NL_STATS");
|
||||||
if (p != "")
|
if (p != "")
|
||||||
|
@ -23,7 +23,7 @@ class nl_convert_base_t
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
nl_convert_base_t() : out(m_buf) {};
|
nl_convert_base_t() : out(m_buf) {}
|
||||||
virtual ~nl_convert_base_t()
|
virtual ~nl_convert_base_t()
|
||||||
{
|
{
|
||||||
m_nets.clear();
|
m_nets.clear();
|
||||||
@ -143,7 +143,7 @@ class nl_convert_spice_t : public nl_convert_base_t
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
nl_convert_spice_t() : nl_convert_base_t() {};
|
nl_convert_spice_t() : nl_convert_base_t() {}
|
||||||
~nl_convert_spice_t()
|
~nl_convert_spice_t()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -162,7 +162,7 @@ class nl_convert_eagle_t : public nl_convert_base_t
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
nl_convert_eagle_t() : nl_convert_base_t() {};
|
nl_convert_eagle_t() : nl_convert_base_t() {}
|
||||||
~nl_convert_eagle_t()
|
~nl_convert_eagle_t()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ static Astable555Desc b2_555_desc(OHM(560.0), M_OHM(1.8), U_FARAD(0.1));
|
|||||||
static Mono555Desc c9_555_desc(OHM(47000.0), U_FARAD(1.0)); // R33, C21
|
static Mono555Desc c9_555_desc(OHM(47000.0), U_FARAD(1.0)); // R33, C21
|
||||||
|
|
||||||
static CapacitorDesc c32_desc(U_FARAD(0.1));
|
static CapacitorDesc c32_desc(U_FARAD(0.1));
|
||||||
static CapacitorDesc c36_desc(N_FARAD(1.0)); //0.001uF = 1nF
|
static CapacitorDesc c36_desc(N_FARAD(1.0*.7)); //0.001uF = 1nF - determines horizontal gap between bricks
|
||||||
static CapacitorDesc c37_desc(P_FARAD(330.0));
|
static CapacitorDesc c37_desc(P_FARAD(330.0));
|
||||||
|
|
||||||
static Mono9602Desc n8_desc(K_OHM(33.0), U_FARAD(100.0), K_OHM(5.6), P_FARAD(0)); // No capacitor on 2nd 9602
|
static Mono9602Desc n8_desc(K_OHM(33.0), U_FARAD(100.0), K_OHM(5.6), P_FARAD(0)); // No capacitor on 2nd 9602
|
||||||
@ -96,8 +96,10 @@ CIRCUIT_LAYOUT( breakout )
|
|||||||
SOLVER(Solver, 48000)
|
SOLVER(Solver, 48000)
|
||||||
PARAM(Solver.ACCURACY, 1e-6)
|
PARAM(Solver.ACCURACY, 1e-6)
|
||||||
PARAM(Solver.GS_THRESHOLD, 6)
|
PARAM(Solver.GS_THRESHOLD, 6)
|
||||||
// FIXME: PARALLEL Doesn't work in breakout.
|
PARAM(Solver.DYNAMIC_TS, 0)
|
||||||
PARAM(Solver.PARALLEL, 0)
|
//PARAM(Solver.LTE, 1e-10)
|
||||||
|
PARAM(Solver.MIN_TIMESTEP, 1e-8)
|
||||||
|
PARAM(Solver.ITERATIVE, "MAT_CR")
|
||||||
#endif
|
#endif
|
||||||
PARAM(NETLIST.USE_DEACTIVATE, 1)
|
PARAM(NETLIST.USE_DEACTIVATE, 1)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user