summaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/formats/apridisk.h2
-rw-r--r--src/lib/formats/dsk_dsk.cpp6
-rw-r--r--src/lib/formats/hpi_dsk.cpp96
-rw-r--r--src/lib/formats/hpi_dsk.h3
-rw-r--r--src/lib/formats/mtx_dsk.cpp53
-rw-r--r--src/lib/formats/mtx_dsk.h33
-rw-r--r--src/lib/formats/opd_dsk.cpp61
-rw-r--r--src/lib/formats/opd_dsk.h38
-rw-r--r--src/lib/netlist/analog/nld_bjt.cpp632
-rw-r--r--src/lib/netlist/analog/nld_bjt.h2
-rw-r--r--src/lib/netlist/analog/nld_fourterm.h2
-rw-r--r--src/lib/netlist/analog/nld_mosfet.cpp488
-rw-r--r--src/lib/netlist/analog/nld_mosfet.h21
-rw-r--r--src/lib/netlist/analog/nld_opamps.cpp30
-rw-r--r--src/lib/netlist/analog/nld_opamps.h2
-rw-r--r--src/lib/netlist/analog/nld_switches.cpp49
-rw-r--r--src/lib/netlist/analog/nld_switches.h2
-rw-r--r--src/lib/netlist/analog/nld_twoterm.h2
-rw-r--r--src/lib/netlist/analog/nlid_fourterm.cpp52
-rw-r--r--src/lib/netlist/analog/nlid_fourterm.h60
-rw-r--r--src/lib/netlist/analog/nlid_twoterm.cpp233
-rw-r--r--src/lib/netlist/analog/nlid_twoterm.h338
-rw-r--r--src/lib/netlist/build/makefile75
-rw-r--r--src/lib/netlist/devices/net_lib.cpp281
-rw-r--r--src/lib/netlist/devices/net_lib.h46
-rw-r--r--src/lib/netlist/devices/nld_2102A.cpp8
-rw-r--r--src/lib/netlist/devices/nld_2102A.h2
-rw-r--r--src/lib/netlist/devices/nld_2716.cpp6
-rw-r--r--src/lib/netlist/devices/nld_2716.h2
-rw-r--r--src/lib/netlist/devices/nld_4020.cpp7
-rw-r--r--src/lib/netlist/devices/nld_4020.h2
-rw-r--r--src/lib/netlist/devices/nld_4066.cpp37
-rw-r--r--src/lib/netlist/devices/nld_4066.h2
-rw-r--r--src/lib/netlist/devices/nld_4316.cpp18
-rw-r--r--src/lib/netlist/devices/nld_4316.h2
-rw-r--r--src/lib/netlist/devices/nld_74107.cpp20
-rw-r--r--src/lib/netlist/devices/nld_74107.h2
-rw-r--r--src/lib/netlist/devices/nld_74123.cpp26
-rw-r--r--src/lib/netlist/devices/nld_74123.h2
-rw-r--r--src/lib/netlist/devices/nld_74153.cpp12
-rw-r--r--src/lib/netlist/devices/nld_74153.h2
-rw-r--r--src/lib/netlist/devices/nld_74161.cpp8
-rw-r--r--src/lib/netlist/devices/nld_74161.h2
-rw-r--r--src/lib/netlist/devices/nld_74164.cpp6
-rw-r--r--src/lib/netlist/devices/nld_74164.h2
-rw-r--r--src/lib/netlist/devices/nld_74165.cpp7
-rw-r--r--src/lib/netlist/devices/nld_74165.h2
-rw-r--r--src/lib/netlist/devices/nld_74166.cpp6
-rw-r--r--src/lib/netlist/devices/nld_74166.h2
-rw-r--r--src/lib/netlist/devices/nld_74174.cpp6
-rw-r--r--src/lib/netlist/devices/nld_74174.h2
-rw-r--r--src/lib/netlist/devices/nld_74175.cpp6
-rw-r--r--src/lib/netlist/devices/nld_74175.h2
-rw-r--r--src/lib/netlist/devices/nld_74192.cpp8
-rw-r--r--src/lib/netlist/devices/nld_74192.h2
-rw-r--r--src/lib/netlist/devices/nld_74193.cpp8
-rw-r--r--src/lib/netlist/devices/nld_74193.h2
-rw-r--r--src/lib/netlist/devices/nld_74194.cpp6
-rw-r--r--src/lib/netlist/devices/nld_74194.h2
-rw-r--r--src/lib/netlist/devices/nld_74365.cpp14
-rw-r--r--src/lib/netlist/devices/nld_74365.h2
-rw-r--r--src/lib/netlist/devices/nld_7448.cpp24
-rw-r--r--src/lib/netlist/devices/nld_7448.h2
-rw-r--r--src/lib/netlist/devices/nld_7450.cpp18
-rw-r--r--src/lib/netlist/devices/nld_7450.h2
-rw-r--r--src/lib/netlist/devices/nld_7473.cpp10
-rw-r--r--src/lib/netlist/devices/nld_7473.h2
-rw-r--r--src/lib/netlist/devices/nld_7474.cpp132
-rw-r--r--src/lib/netlist/devices/nld_7474.h2
-rw-r--r--src/lib/netlist/devices/nld_7475.cpp12
-rw-r--r--src/lib/netlist/devices/nld_7475.h2
-rw-r--r--src/lib/netlist/devices/nld_7483.cpp47
-rw-r--r--src/lib/netlist/devices/nld_7483.h2
-rw-r--r--src/lib/netlist/devices/nld_7485.cpp6
-rw-r--r--src/lib/netlist/devices/nld_7485.h2
-rw-r--r--src/lib/netlist/devices/nld_7490.cpp35
-rw-r--r--src/lib/netlist/devices/nld_7490.h2
-rw-r--r--src/lib/netlist/devices/nld_7493.cpp87
-rw-r--r--src/lib/netlist/devices/nld_7493.h2
-rw-r--r--src/lib/netlist/devices/nld_7497.cpp174
-rw-r--r--src/lib/netlist/devices/nld_7497.h57
-rw-r--r--src/lib/netlist/devices/nld_74ls629.cpp19
-rw-r--r--src/lib/netlist/devices/nld_74ls629.h2
-rw-r--r--src/lib/netlist/devices/nld_82S115.cpp6
-rw-r--r--src/lib/netlist/devices/nld_82S115.h2
-rw-r--r--src/lib/netlist/devices/nld_82S123.cpp6
-rw-r--r--src/lib/netlist/devices/nld_82S123.h2
-rw-r--r--src/lib/netlist/devices/nld_82S126.cpp6
-rw-r--r--src/lib/netlist/devices/nld_82S126.h2
-rw-r--r--src/lib/netlist/devices/nld_82S16.cpp73
-rw-r--r--src/lib/netlist/devices/nld_82S16.h2
-rw-r--r--src/lib/netlist/devices/nld_9310.cpp42
-rw-r--r--src/lib/netlist/devices/nld_9310.h2
-rw-r--r--src/lib/netlist/devices/nld_9316.cpp138
-rw-r--r--src/lib/netlist/devices/nld_9316.h2
-rw-r--r--src/lib/netlist/devices/nld_9322.cpp14
-rw-r--r--src/lib/netlist/devices/nld_9322.h2
-rw-r--r--src/lib/netlist/devices/nld_am2847.cpp10
-rw-r--r--src/lib/netlist/devices/nld_am2847.h2
-rw-r--r--src/lib/netlist/devices/nld_dm9314.cpp6
-rw-r--r--src/lib/netlist/devices/nld_dm9314.h2
-rw-r--r--src/lib/netlist/devices/nld_dm9334.cpp6
-rw-r--r--src/lib/netlist/devices/nld_dm9334.h2
-rw-r--r--src/lib/netlist/devices/nld_legacy.cpp10
-rw-r--r--src/lib/netlist/devices/nld_legacy.h2
-rw-r--r--src/lib/netlist/devices/nld_log.cpp18
-rw-r--r--src/lib/netlist/devices/nld_log.h4
-rw-r--r--src/lib/netlist/devices/nld_mm5837.cpp16
-rw-r--r--src/lib/netlist/devices/nld_mm5837.h2
-rw-r--r--src/lib/netlist/devices/nld_ne555.cpp101
-rw-r--r--src/lib/netlist/devices/nld_ne555.h8
-rw-r--r--src/lib/netlist/devices/nld_r2r_dac.cpp14
-rw-r--r--src/lib/netlist/devices/nld_r2r_dac.h2
-rw-r--r--src/lib/netlist/devices/nld_schmitt.cpp30
-rw-r--r--src/lib/netlist/devices/nld_schmitt.h2
-rw-r--r--src/lib/netlist/devices/nld_system.cpp95
-rw-r--r--src/lib/netlist/devices/nld_system.h2
-rw-r--r--src/lib/netlist/devices/nld_tms4800.cpp10
-rw-r--r--src/lib/netlist/devices/nld_tms4800.h2
-rw-r--r--src/lib/netlist/devices/nld_tristate.cpp6
-rw-r--r--src/lib/netlist/devices/nld_tristate.h2
-rw-r--r--src/lib/netlist/devices/nlid_cmos.h4
-rw-r--r--src/lib/netlist/devices/nlid_proxy.cpp54
-rw-r--r--src/lib/netlist/devices/nlid_proxy.h24
-rw-r--r--src/lib/netlist/devices/nlid_system.h92
-rw-r--r--src/lib/netlist/devices/nlid_truthtable.cpp141
-rw-r--r--src/lib/netlist/devices/nlid_truthtable.h175
-rw-r--r--src/lib/netlist/macro/nlm_base.cpp39
-rw-r--r--src/lib/netlist/macro/nlm_base.h2
-rw-r--r--src/lib/netlist/macro/nlm_cd4xxx.cpp8
-rw-r--r--src/lib/netlist/macro/nlm_cd4xxx.h2
-rw-r--r--src/lib/netlist/macro/nlm_opamp.cpp2
-rw-r--r--src/lib/netlist/macro/nlm_opamp.h2
-rw-r--r--src/lib/netlist/macro/nlm_other.cpp2
-rw-r--r--src/lib/netlist/macro/nlm_other.h2
-rw-r--r--src/lib/netlist/macro/nlm_ttl74xx.cpp9
-rw-r--r--src/lib/netlist/macro/nlm_ttl74xx.h2
-rw-r--r--src/lib/netlist/netlist_types.h54
-rw-r--r--src/lib/netlist/nl_base.cpp765
-rw-r--r--src/lib/netlist/nl_base.h1307
-rw-r--r--src/lib/netlist/nl_config.h46
-rw-r--r--src/lib/netlist/nl_dice_compat.h17
-rw-r--r--src/lib/netlist/nl_errstr.h3
-rw-r--r--src/lib/netlist/nl_factory.cpp140
-rw-r--r--src/lib/netlist/nl_factory.h87
-rw-r--r--src/lib/netlist/nl_lists.h163
-rw-r--r--src/lib/netlist/nl_parser.cpp43
-rw-r--r--src/lib/netlist/nl_parser.h18
-rw-r--r--src/lib/netlist/nl_setup.cpp838
-rw-r--r--src/lib/netlist/nl_setup.h309
-rw-r--r--src/lib/netlist/nl_time.h145
-rw-r--r--src/lib/netlist/nltypes.h147
-rw-r--r--src/lib/netlist/plib/gmres.h450
-rw-r--r--src/lib/netlist/plib/mat_cr.h530
-rw-r--r--src/lib/netlist/plib/palloc.cpp105
-rw-r--r--src/lib/netlist/plib/palloc.h513
-rw-r--r--src/lib/netlist/plib/parray.h126
-rw-r--r--src/lib/netlist/plib/pchrono.cpp4
-rw-r--r--src/lib/netlist/plib/pchrono.h52
-rw-r--r--src/lib/netlist/plib/pconfig.h51
-rw-r--r--src/lib/netlist/plib/pdynlib.cpp18
-rw-r--r--src/lib/netlist/plib/pdynlib.h15
-rw-r--r--src/lib/netlist/plib/pexception.cpp215
-rw-r--r--src/lib/netlist/plib/pexception.h214
-rw-r--r--src/lib/netlist/plib/pfmtlog.cpp121
-rw-r--r--src/lib/netlist/plib/pfmtlog.h50
-rw-r--r--src/lib/netlist/plib/pfunction.cpp32
-rw-r--r--src/lib/netlist/plib/pfunction.h4
-rw-r--r--src/lib/netlist/plib/plists.h122
-rw-r--r--src/lib/netlist/plib/pmain.cpp13
-rw-r--r--src/lib/netlist/plib/pmain.h20
-rw-r--r--src/lib/netlist/plib/pmatrix2d.h85
-rw-r--r--src/lib/netlist/plib/pmempool.h187
-rw-r--r--src/lib/netlist/plib/pomp.h28
-rw-r--r--src/lib/netlist/plib/poptions.cpp154
-rw-r--r--src/lib/netlist/plib/poptions.h161
-rw-r--r--src/lib/netlist/plib/pparser.cpp278
-rw-r--r--src/lib/netlist/plib/pparser.h107
-rw-r--r--src/lib/netlist/plib/ppmf.h28
-rw-r--r--src/lib/netlist/plib/pstate.cpp35
-rw-r--r--src/lib/netlist/plib/pstate.h67
-rw-r--r--src/lib/netlist/plib/pstream.cpp131
-rw-r--r--src/lib/netlist/plib/pstream.h408
-rw-r--r--src/lib/netlist/plib/pstring.cpp131
-rw-r--r--src/lib/netlist/plib/pstring.h457
-rw-r--r--src/lib/netlist/plib/ptime.h136
-rw-r--r--src/lib/netlist/plib/ptypes.h124
-rw-r--r--src/lib/netlist/plib/putil.cpp75
-rw-r--r--src/lib/netlist/plib/putil.h103
-rw-r--r--src/lib/netlist/plib/vector_ops.h151
-rw-r--r--src/lib/netlist/prg/nltool.cpp374
-rw-r--r--src/lib/netlist/prg/nlwav.cpp591
-rw-r--r--src/lib/netlist/solver/mat_cr.h175
-rw-r--r--src/lib/netlist/solver/nld_matrix_solver.cpp937
-rw-r--r--src/lib/netlist/solver/nld_matrix_solver.h471
-rw-r--r--src/lib/netlist/solver/nld_ms_direct.h386
-rw-r--r--src/lib/netlist/solver/nld_ms_direct1.h50
-rw-r--r--src/lib/netlist/solver/nld_ms_direct2.h59
-rw-r--r--src/lib/netlist/solver/nld_ms_direct_lu.h26
-rw-r--r--src/lib/netlist/solver/nld_ms_gcr.h562
-rw-r--r--src/lib/netlist/solver/nld_ms_gmres.h412
-rw-r--r--src/lib/netlist/solver/nld_ms_sm.h416
-rw-r--r--src/lib/netlist/solver/nld_ms_sor.h112
-rw-r--r--src/lib/netlist/solver/nld_ms_sor_mat.h338
-rw-r--r--src/lib/netlist/solver/nld_ms_w.h165
-rw-r--r--src/lib/netlist/solver/nld_solver.cpp641
-rw-r--r--src/lib/netlist/solver/nld_solver.h178
-rw-r--r--src/lib/netlist/solver/vector_base.h144
-rw-r--r--src/lib/netlist/tools/nl_convert.cpp117
-rw-r--r--src/lib/netlist/tools/nl_convert.h69
-rw-r--r--src/lib/util/corefile.cpp22
-rw-r--r--src/lib/util/corefile.h21
-rw-r--r--src/lib/util/corestr.cpp95
-rw-r--r--src/lib/util/corestr.h7
-rw-r--r--src/lib/util/unicode.cpp170
-rw-r--r--src/lib/util/unicode.h17
216 files changed, 8669 insertions, 12175 deletions
diff --git a/src/lib/formats/apridisk.h b/src/lib/formats/apridisk.h
index 1155a0b4a9a..81db4b41105 100644
--- a/src/lib/formats/apridisk.h
+++ b/src/lib/formats/apridisk.h
@@ -33,7 +33,7 @@ private:
static const int APR_HEADER_SIZE = 128;
// sector types
- enum : uint32_t
+ enum
{
APR_DELETED = 0xe31d0000,
APR_SECTOR = 0xe31d0001,
diff --git a/src/lib/formats/dsk_dsk.cpp b/src/lib/formats/dsk_dsk.cpp
index c90579b68d0..5b019fb53d1 100644
--- a/src/lib/formats/dsk_dsk.cpp
+++ b/src/lib/formats/dsk_dsk.cpp
@@ -362,12 +362,6 @@ bool dsk_format::load(io_generic *io, uint32_t form_factor, floppy_image *image)
skip = 2;
}
int tracks = header[0x30];
-
- int img_tracks, img_heads;
- image->get_maximal_geometry(img_tracks, img_heads);
- if (tracks > img_tracks || heads > img_heads)
- return false;
-
uint64_t track_offsets[84*2];
int cnt =0;
if (!extendformat) {
diff --git a/src/lib/formats/hpi_dsk.cpp b/src/lib/formats/hpi_dsk.cpp
index 50d2653280d..8d23f151862 100644
--- a/src/lib/formats/hpi_dsk.cpp
+++ b/src/lib/formats/hpi_dsk.cpp
@@ -4,10 +4,9 @@
hpi_dsk.cpp
- HP9885/HP9895A "HPI" disk images
+ HP9895A "HPI" disk images
- CHS = 67/1/30 (SSDD)
- CHS = 77/2/30 (DSDD)
+ CHS = 77/2/30
Sector size 256 bytes
Cell size 2 µs
Gap1 = 16 x 0x00
@@ -41,7 +40,7 @@
256 bytes per sector). There's also a "reduced" version holding
just 75 cylinders.
When loading, the disk image is translated to MMFM encoding so
- that it can be loaded into HP9885/HP9895 emulator.
+ that it can be loaded into HP9895 emulator.
*********************************************************************/
@@ -66,14 +65,11 @@ constexpr int ID_DATA_OFFSET = 30 * 16; // Nominal distance (in cells) between I
// Size of image file (holding 77 cylinders)
constexpr unsigned HPI_IMAGE_SIZE = HPI_TRACKS * HPI_HEADS * HPI_SECTORS * HPI_SECTOR_SIZE;
constexpr unsigned HPI_RED_TRACKS = 75; // Reduced number of tracks
-constexpr unsigned HPI_9885_TRACKS = 67; // Tracks visible to HP9885 drives
// Size of reduced image file (holding 75 cylinders)
constexpr unsigned HPI_RED_IMAGE_SIZE = HPI_RED_TRACKS * HPI_HEADS * HPI_SECTORS * HPI_SECTOR_SIZE;
hpi_format::hpi_format()
{
- (void)HPI_IMAGE_SIZE;
- (void)HPI_RED_IMAGE_SIZE;
}
int hpi_format::identify(io_generic *io, uint32_t form_factor)
@@ -83,79 +79,27 @@ int hpi_format::identify(io_generic *io, uint32_t form_factor)
// we try to stay back and give only 50 points, since another image
// format may also have images of the same size (there is no header and no
// magic number for HPI format...
- unsigned dummy_heads;
- unsigned dummy_tracks;
if (((form_factor == floppy_image::FF_8) || (form_factor == floppy_image::FF_UNKNOWN)) &&
- geometry_from_size(size , dummy_heads , dummy_tracks)) {
+ ((size == HPI_RED_IMAGE_SIZE) || (size == HPI_IMAGE_SIZE))) {
return 50;
} else {
return 0;
}
}
-bool hpi_format::geometry_from_size(uint64_t image_size , unsigned& heads , unsigned& tracks)
-{
- if ((image_size % HPI_SECTOR_SIZE) != 0) {
- // Not a whole number of sectors
- return false;
- }
- unsigned sectors = unsigned(image_size / HPI_SECTOR_SIZE);
- if ((sectors % HPI_SECTORS) != 0) {
- // Not a whole number of tracks
- return false;
- }
- unsigned tot_tracks = sectors / HPI_SECTORS;
- // Possible combinations
- //
- // | Tot tracks | Heads | Tracks | Format |
- // |------------+-------+--------+--------|
- // | 67 | 1 | 67 | SSDD |
- // | 77 | 1 | 77 | SSDD |
- // | 150 | 2 | 75 | DSDD |
- // | 154 | 2 | 77 | DSDD |
- //
- switch (tot_tracks) {
- case HPI_9885_TRACKS:
- heads = 1;
- tracks = HPI_9885_TRACKS;
- return true;
-
- case HPI_TRACKS:
- heads = 1;
- tracks = HPI_TRACKS;
- return true;
-
- case HPI_RED_TRACKS * 2:
- heads = 2;
- tracks = HPI_RED_TRACKS;
- return true;
-
- case HPI_TRACKS * 2:
- heads = 2;
- tracks = HPI_TRACKS;
- return true;
-
- default:
- return false;
- }
-}
-
bool hpi_format::load(io_generic *io, uint32_t form_factor, floppy_image *image)
{
- unsigned heads;
- unsigned cylinders;
+ image->set_variant(floppy_image::DSDD); // We actually need to derive the variant from the image size depending on the form factor
uint64_t size = io_generic_size(io);
- if (!geometry_from_size(size, heads, cylinders)) {
- return false;
- }
- int max_tracks;
- int max_heads;
- image->get_maximal_geometry(max_tracks , max_heads);
- if (cylinders > max_tracks || heads > max_heads) {
+ unsigned cylinders;
+ if (size == HPI_RED_IMAGE_SIZE) {
+ cylinders = HPI_RED_TRACKS;
+ } else if (size == HPI_IMAGE_SIZE) {
+ cylinders = HPI_TRACKS;
+ } else {
return false;
}
- image->set_variant(heads == 2 ? floppy_image::DSDD : floppy_image::SSDD);
// Suck in the whole image
std::vector<uint8_t> image_data(size);
@@ -174,11 +118,11 @@ bool hpi_format::load(io_generic *io, uint32_t form_factor, floppy_image *image)
unsigned list_offset = 0;
for (unsigned cyl = 0; cyl < cylinders; cyl++) {
- for (unsigned head = 0; head < heads; head++) {
+ for (unsigned head = 0; head < HPI_HEADS; head++) {
std::vector<uint32_t> track_data;
for (unsigned sector = 0; sector < HPI_SECTORS; sector++) {
unsigned real_sector = sector_list[ (sector + list_offset) % HPI_SECTORS ];
- unsigned offset_in_image = chs_to_lba(cyl, head, real_sector, heads) * HPI_SECTOR_SIZE;
+ unsigned offset_in_image = chs_to_lba(cyl, head, real_sector) * HPI_SECTOR_SIZE;
write_sector(track_data , cyl , real_sector + (head << 7) , &image_data[ offset_in_image ]);
}
fill_with_gap3(track_data);
@@ -191,12 +135,8 @@ bool hpi_format::load(io_generic *io, uint32_t form_factor, floppy_image *image)
bool hpi_format::save(io_generic *io, floppy_image *image)
{
- int tracks;
- int heads;
- image->get_actual_geometry(tracks, heads);
-
- for (int cyl = 0; cyl < tracks; cyl++) {
- for (int head = 0; head < heads; head++) {
+ for (unsigned cyl = 0; cyl < HPI_TRACKS; cyl++) {
+ for (unsigned head = 0; head < HPI_HEADS; head++) {
uint8_t bitstream[ 21000 ];
int bitstream_size;
generate_bitstream_from_track(cyl , head , CELL_SIZE , bitstream , bitstream_size , image , 0);
@@ -205,7 +145,7 @@ bool hpi_format::save(io_generic *io, floppy_image *image)
uint8_t sector_data[ HPI_SECTOR_SIZE ];
while (get_next_sector(bitstream , bitstream_size , pos , track_no , head_no , sector_no , sector_data)) {
if (track_no == cyl && head_no == head && sector_no < HPI_SECTORS) {
- unsigned offset_in_image = chs_to_lba(cyl, head, sector_no, heads) * HPI_SECTOR_SIZE;
+ unsigned offset_in_image = chs_to_lba(cyl, head, sector_no) * HPI_SECTOR_SIZE;
io_generic_write(io, sector_data, offset_in_image, HPI_SECTOR_SIZE);
}
}
@@ -360,9 +300,9 @@ void hpi_format::fill_with_gap3(std::vector<uint32_t> &buffer)
}
}
-unsigned hpi_format::chs_to_lba(unsigned cylinder , unsigned head , unsigned sector , unsigned heads)
+unsigned hpi_format::chs_to_lba(unsigned cylinder , unsigned head , unsigned sector)
{
- return sector + (head + cylinder * heads) * HPI_SECTORS;
+ return sector + (head + cylinder * HPI_HEADS) * HPI_SECTORS;
}
std::vector<uint8_t> hpi_format::get_next_id_n_block(const uint8_t *bitstream , int bitstream_size , int& pos , int& start_pos)
diff --git a/src/lib/formats/hpi_dsk.h b/src/lib/formats/hpi_dsk.h
index 287f37fd302..8457db1ea24 100644
--- a/src/lib/formats/hpi_dsk.h
+++ b/src/lib/formats/hpi_dsk.h
@@ -36,7 +36,6 @@ public:
private:
typedef std::array<uint8_t , HPI_SECTORS> sector_list_t;
- static bool geometry_from_size(uint64_t image_size , unsigned& heads , unsigned& tracks);
static void interleaved_sectors(unsigned il_factor , sector_list_t& sector_list);
void write_mmfm_bit(std::vector<uint32_t> &buffer , bool data_bit , bool clock_bit);
void write_mmfm_byte(std::vector<uint32_t> &buffer , uint8_t data , uint8_t clock = 0);
@@ -44,7 +43,7 @@ private:
void write_crc(std::vector<uint32_t> &buffer , uint16_t crc);
void write_sector(std::vector<uint32_t> &buffer , uint8_t track_no , uint8_t sect_head_no , const uint8_t *sect_data);
void fill_with_gap3(std::vector<uint32_t> &buffer);
- static unsigned chs_to_lba(unsigned cylinder , unsigned head , unsigned sector , unsigned heads);
+ static unsigned chs_to_lba(unsigned cylinder , unsigned head , unsigned sector);
std::vector<uint8_t> get_next_id_n_block(const uint8_t *bitstream , int bitstream_size , int& pos , int& start_pos);
bool get_next_sector(const uint8_t *bitstream , int bitstream_size , int& pos , unsigned& track , unsigned& head , unsigned& sector , uint8_t *sector_data);
diff --git a/src/lib/formats/mtx_dsk.cpp b/src/lib/formats/mtx_dsk.cpp
deleted file mode 100644
index 95420f40aab..00000000000
--- a/src/lib/formats/mtx_dsk.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Nigel Barnes
-/***************************************************************************
-
- Memotech MTX
-
- Disk image format
-
-***************************************************************************/
-
-#include "mtx_dsk.h"
-
-mtx_format::mtx_format() : wd177x_format(formats)
-{
-}
-
-const char *mtx_format::name() const
-{
- return "mtx";
-}
-
-const char *mtx_format::description() const
-{
- return "Memotech MTX disk image";
-}
-
-const char *mtx_format::extensions() const
-{
- return "mfloppy";
-}
-
-const mtx_format::format mtx_format::formats[] =
-{
- { // 320k 5 1/4 inch double density single sided (Type 03)
- floppy_image::FF_525, floppy_image::DSDD, floppy_image::MFM,
- 2000, 16, 40, 2, 256, {}, 1, {}, 32, 22, 54
- },
- { // 640k 5 1/4 inch double density double sided (Type 07)
- floppy_image::FF_525, floppy_image::DSQD, floppy_image::MFM,
- 2000, 16, 80, 2, 256, {}, 1, {}, 32, 22, 54
- },
- { // 320k 3 1/2 inch double density single sided (Type 03)
- floppy_image::FF_35, floppy_image::DSDD, floppy_image::MFM,
- 2000, 16, 40, 2, 256, {}, 1, {}, 32, 22, 54
- },
- { // 640k 3 1/2 inch double density double sided (Type 07)
- floppy_image::FF_35, floppy_image::DSQD, floppy_image::MFM,
- 2000, 16, 80, 2, 256, {}, 1, {}, 32, 22, 54
- },
- {}
-};
-
-const floppy_format_type FLOPPY_MTX_FORMAT = &floppy_image_format_creator<mtx_format>;
diff --git a/src/lib/formats/mtx_dsk.h b/src/lib/formats/mtx_dsk.h
deleted file mode 100644
index 86f74bccfc5..00000000000
--- a/src/lib/formats/mtx_dsk.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Nigel Barnes
-/***************************************************************************
-
- Memotech MTX
-
- Disk image format
-
-***************************************************************************/
-
-#pragma once
-
-#ifndef __MTX_DSK_H__
-#define __MTX_DSK_H__
-
-#include "wd177x_dsk.h"
-
-class mtx_format : public wd177x_format
-{
-public:
- mtx_format();
-
- virtual const char *name() const override;
- virtual const char *description() const override;
- virtual const char *extensions() const override;
-
-private:
- static const format formats[];
-};
-
-extern const floppy_format_type FLOPPY_MTX_FORMAT;
-
-#endif // __MTX_DSK_H__
diff --git a/src/lib/formats/opd_dsk.cpp b/src/lib/formats/opd_dsk.cpp
deleted file mode 100644
index b45b58762ed..00000000000
--- a/src/lib/formats/opd_dsk.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Nigel Barnes
-/***************************************************************************
-
- Sinclair ZX Spectrum
-
- Opus Discovery disk image formats
-
-***************************************************************************/
-
-#include "opd_dsk.h"
-
-
-opd_format::opd_format() : wd177x_format(formats)
-{
-}
-
-const char *opd_format::name() const
-{
- return "opd";
-}
-
-const char *opd_format::description() const
-{
- return "Opus Discovery disk image";
-}
-
-const char *opd_format::extensions() const
-{
- return "opd,opu";
-}
-
-int opd_format::identify(io_generic *io, uint32_t form_factor)
-{
- int type = find_size(io, form_factor);
-
- if (type != -1)
- return 90;
- return 0;
-}
-
-int opd_format::get_image_offset(const format &f, int head, int track)
-{
- return (f.track_count * head + track) * compute_track_size(f);
-}
-
-const opd_format::format opd_format::formats[] =
-{
- { // 180k 40 track single sided double density - gaps unverified
- floppy_image::FF_35, floppy_image::SSSD, floppy_image::MFM,
- 2000, 18, 40, 1, 256, {}, 0, {}, 36, 22, 27
- },
- { // 360k 40 track double sided double density - gaps unverified
- floppy_image::FF_35, floppy_image::DSSD, floppy_image::MFM,
- 2000, 18, 40, 2, 256, {}, 0, {}, 36, 22, 27
- },
- {}
-};
-
-
-const floppy_format_type FLOPPY_OPD_FORMAT = &floppy_image_format_creator<opd_format>;
diff --git a/src/lib/formats/opd_dsk.h b/src/lib/formats/opd_dsk.h
deleted file mode 100644
index 3eb018ca1dc..00000000000
--- a/src/lib/formats/opd_dsk.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Nigel Barnes
-/***************************************************************************
-
- Sinclair ZX Spectrum
-
- Opus Discovery disk image formats
-
-***************************************************************************/
-
-#pragma once
-
-#ifndef OPD_DSK_H
-#define OPD_DSK_H
-
-#include "flopimg.h"
-#include "wd177x_dsk.h"
-
-
-class opd_format : public wd177x_format
-{
-public:
- opd_format();
-
- virtual int identify(io_generic *io, uint32_t form_factor) override;
- virtual int get_image_offset(const format &f, int head, int track) override;
- virtual const char *name() const override;
- virtual const char *description() const override;
- virtual const char *extensions() const override;
-
-private:
- static const format formats[];
-};
-
-
-extern const floppy_format_type FLOPPY_OPD_FORMAT;
-
-#endif // OPD_DSK_H
diff --git a/src/lib/netlist/analog/nld_bjt.cpp b/src/lib/netlist/analog/nld_bjt.cpp
index aef920635fe..6f4a2db86bf 100644
--- a/src/lib/netlist/analog/nld_bjt.cpp
+++ b/src/lib/netlist/analog/nld_bjt.cpp
@@ -5,49 +5,47 @@
*
*/
-#include "netlist/solver/nld_solver.h"
-#include "netlist/nl_setup.h"
+#include "../solver/nld_solver.h"
#include "nlid_twoterm.h"
-
+#include "../nl_setup.h"
#include <cmath>
namespace netlist
{
-namespace analog
-{
- using constants = plib::constants<nl_double>;
+ namespace analog
+ {
- class diode
+class diode
+{
+public:
+ diode() : m_Is(1e-15), m_VT(0.0258), m_VT_inv(1.0 / m_VT) {}
+ diode(const nl_double Is, const nl_double n)
{
- public:
- diode() : m_Is(1e-15), m_VT(0.0258), m_VT_inv(1.0 / m_VT) {}
- diode(const nl_double Is, const nl_double n)
- {
- m_Is = Is;
- m_VT = 0.0258 * n;
- m_VT_inv = 1.0 / m_VT;
- }
- void set(const nl_double Is, const nl_double n)
- {
- m_Is = Is;
- m_VT = 0.0258 * n;
- m_VT_inv = 1.0 / m_VT;
- }
- nl_double I(const nl_double V) const { return m_Is * std::exp(V * m_VT_inv) - m_Is; }
- nl_double g(const nl_double V) const { return m_Is * m_VT_inv * std::exp(V * m_VT_inv); }
- nl_double V(const nl_double I) const { return std::log1p(I / m_Is) * m_VT; } // log1p(x)=log(1.0 + x)
- nl_double gI(const nl_double I) const { return m_VT_inv * (I + m_Is); }
-
- private:
- nl_double m_Is;
- nl_double m_VT;
- nl_double m_VT_inv;
- };
+ m_Is = Is;
+ m_VT = 0.0258 * n;
+ m_VT_inv = 1.0 / m_VT;
+ }
+ void set(const nl_double Is, const nl_double n)
+ {
+ m_Is = Is;
+ m_VT = 0.0258 * n;
+ m_VT_inv = 1.0 / m_VT;
+ }
+ nl_double I(const nl_double V) const { return m_Is * std::exp(V * m_VT_inv) - m_Is; }
+ nl_double g(const nl_double V) const { return m_Is * m_VT_inv * std::exp(V * m_VT_inv); }
+ nl_double V(const nl_double I) const { return std::log1p(I / m_Is) * m_VT; } // log1p(x)=log(1.0 + x)
+ nl_double gI(const nl_double I) const { return m_VT_inv * (I + m_Is); }
- // -----------------------------------------------------------------------------
- // nld_Q - Base classes
- // -----------------------------------------------------------------------------
+private:
+ nl_double m_Is;
+ nl_double m_VT;
+ nl_double m_VT_inv;
+};
+
+// -----------------------------------------------------------------------------
+// nld_Q - Base classes
+// -----------------------------------------------------------------------------
/*! Class representing the bjt model paramers.
*
@@ -75,7 +73,7 @@ namespace analog
* | | RBM | minimum base resistance at high currents | | RB | 10 | * |
* | | RE | emitter resistance | | 0 | 1 | * |
* | | RC | collector resistance | | 0 | 10 | * |
- * | Y | CJE | B-E zero-bias depletion capacitance | F | 0 | 2pF | * |
+ * | | CJE | B-E zero-bias depletion capacitance | F | 0 | 2pF | * |
* | | VJE | B-E built-in potential | V | 0.75 | 0.6 | |
* | | MJE | B-E junction exponential factor | - | 0.33 | 0.33 | |
* | | TF | ideal forward transit time | sec | 0 | 0.1ns | |
@@ -83,7 +81,7 @@ namespace analog
* | | VTF | voltage describing VBC dependence of TF | V | infinite | | |
* | | ITF | high-current parameter for effect on TF | A | 0 | | * |
* | | PTF | excess phase at freq=1.0/(TF*2PI) Hz | deg | 0 | | |
- * | Y | CJC | B-C zero-bias depletion capacitance | F | 0 | 2pF | * |
+ * | | CJC | B-C zero-bias depletion capacitance | F | 0 | 2pF | * |
* | | VJC | B-C built-in potential | V | 0.75 | 0.5 | |
* | | MJC | B-C junction exponential factor | - | 0.33 | 0.5 | |
* | | XCJC | fraction of B-C depletion capacitance connected to internal base node | - | 1 | | |
@@ -97,369 +95,343 @@ namespace analog
* | | KF | flicker-noise coefficient | - | 0 | | |
* | | AF | flicker-noise exponent | - | 1 | | |
* | | FC | coefficient for forward-bias depletion capacitance formula | - | 0.5 | | |
- * | | TNOM | Parameter measurement temperature | C | 27 | 50 | |
- * */
+ * | | TNOM | Parameter measurement temperature | C | 27 | 50 | | */
class bjt_model_t : public param_model_t
{
public:
bjt_model_t(device_t &device, const pstring &name, const pstring &val)
: param_model_t(device, name, val)
- , m_IS (*this, "IS")
- , m_BF (*this, "BF")
- , m_NF (*this, "NF")
- , m_BR (*this, "BR")
- , m_NR (*this, "NR")
- , m_CJE(*this, "CJE")
- , m_CJC(*this, "CJC")
+ , m_IS(*this, "IS")
+ , m_BF(*this, "BF")
+ , m_NF(*this, "NF")
+ , m_BR(*this, "BR")
+ , m_NR(*this, "NR")
{}
- value_t m_IS; //!< transport saturation current
- value_t m_BF; //!< ideal maximum forward beta
- value_t m_NF; //!< forward current emission coefficient
- value_t m_BR; //!< ideal maximum reverse beta
- value_t m_NR; //!< reverse current emission coefficient
- value_t m_CJE; //!< B-E zero-bias depletion capacitance
- value_t m_CJC; //!< B-C zero-bias depletion capacitance
-
+ value_t m_IS; //!< transport saturation current
+ value_t m_BF; //!< ideal maximum forward beta
+ value_t m_NF; //!< forward current emission coefficient
+ value_t m_BR; //!< ideal maximum reverse beta
+ value_t m_NR; //!< reverse current emission coefficient
};
// Have a common start for transistors
- NETLIB_OBJECT(Q)
- {
- public:
- enum q_type {
- BJT_NPN,
- BJT_PNP
- };
-
- NETLIB_CONSTRUCTOR(Q)
- , m_model(*this, "MODEL", "NPN")
- , m_qtype(BJT_NPN)
- {
- }
-
- NETLIB_IS_DYNAMIC(true)
-
- //NETLIB_RESETI();
- NETLIB_UPDATEI();
-
- q_type qtype() const { return m_qtype; }
- bool is_qtype(q_type atype) const { return m_qtype == atype; }
- void set_qtype(q_type atype) { m_qtype = atype; }
- protected:
-
- bjt_model_t m_model;
- private:
- q_type m_qtype;
+NETLIB_OBJECT(Q)
+{
+public:
+ enum q_type {
+ BJT_NPN,
+ BJT_PNP
};
- NETLIB_OBJECT_DERIVED(QBJT, Q)
+ NETLIB_CONSTRUCTOR(Q)
+ , m_model(*this, "MODEL", "NPN")
+ , m_qtype(BJT_NPN)
{
- public:
- NETLIB_CONSTRUCTOR_DERIVED(QBJT, Q)
- { }
+ }
- protected:
+ NETLIB_IS_DYNAMIC(true)
- private:
- };
+ //NETLIB_RESETI();
+ NETLIB_UPDATEI();
+
+ inline q_type qtype() const { return m_qtype; }
+ inline bool is_qtype(q_type atype) const { return m_qtype == atype; }
+ inline void set_qtype(q_type atype) { m_qtype = atype; }
+protected:
+ bjt_model_t m_model;
+private:
+ q_type m_qtype;
+};
+NETLIB_OBJECT_DERIVED(QBJT, Q)
+{
+public:
+ NETLIB_CONSTRUCTOR_DERIVED(QBJT, Q)
+ { }
+protected:
- // -----------------------------------------------------------------------------
- // nld_QBJT_switch
- // -----------------------------------------------------------------------------
+private:
+};
- /*
- * + - C
- * B ----VVV----+ |
- * | |
- * Rb Rc
- * Rb Rc
- * Rb Rc
- * | |
- * +----+----+
- * |
- * E
- */
- NETLIB_OBJECT_DERIVED(QBJT_switch, QBJT)
- {
- NETLIB_CONSTRUCTOR_DERIVED(QBJT_switch, QBJT)
- , m_RB(*this, "m_RB", true)
- , m_RC(*this, "m_RC", true)
- , m_BC_dummy(*this, "m_BC", true)
- , m_gB(1e-9)
- , m_gC(1e-9)
- , m_V(0.0)
- , m_state_on(*this, "m_state_on", 0)
- {
- register_subalias("B", m_RB.m_P);
- register_subalias("E", m_RB.m_N);
- register_subalias("C", m_RC.m_P);
- //register_term("_E1", m_RC.m_N);
-
- //register_term("_B1", m_BC_dummy.m_P);
- //register_term("_C1", m_BC_dummy.m_N);
-
- connect(m_RB.m_N, m_RC.m_N);
-
- connect(m_RB.m_P, m_BC_dummy.m_P);
- connect(m_RC.m_P, m_BC_dummy.m_N);
- }
-
- NETLIB_RESETI();
- NETLIB_UPDATEI();
- NETLIB_UPDATE_PARAMI();
- NETLIB_UPDATE_TERMINALSI();
-
- private:
- nld_twoterm m_RB;
- nld_twoterm m_RC;
-
- // FIXME: this is needed so we have all terminals belong to one net list
-
- nld_twoterm m_BC_dummy;
-
- nl_double m_gB; // base conductance / switch on
- nl_double m_gC; // collector conductance / switch on
- nl_double m_V; // internal voltage source
- state_var<unsigned> m_state_on;
-
- private:
- };
- // -----------------------------------------------------------------------------
- // nld_QBJT_EB
- // -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// nld_QBJT_switch
+// -----------------------------------------------------------------------------
- NETLIB_OBJECT_DERIVED(QBJT_EB, QBJT)
+/*
+ * + - C
+ * B ----VVV----+ |
+ * | |
+ * Rb Rc
+ * Rb Rc
+ * Rb Rc
+ * | |
+ * +----+----+
+ * |
+ * E
+ */
+
+NETLIB_OBJECT_DERIVED(QBJT_switch, QBJT)
+{
+ NETLIB_CONSTRUCTOR_DERIVED(QBJT_switch, QBJT)
+ , m_RB(*this, "m_RB", true)
+ , m_RC(*this, "m_RC", true)
+ , m_BC_dummy(*this, "m_BC", true)
+ , m_gB(NETLIST_GMIN_DEFAULT)
+ , m_gC(NETLIST_GMIN_DEFAULT)
+ , m_V(0.0)
+ , m_state_on(*this, "m_state_on", 0)
{
- public:
- NETLIB_CONSTRUCTOR_DERIVED(QBJT_EB, QBJT)
- , m_gD_BC(*this, "m_D_BC")
- , m_gD_BE(*this, "m_D_BE")
- , m_D_CB(*this, "m_D_CB", true)
- , m_D_EB(*this, "m_D_EB", true)
- , m_D_EC(*this, "m_D_EC", true)
- , m_alpha_f(0)
- , m_alpha_r(0)
- {
- register_subalias("E", m_D_EB.m_P); // Cathode
- register_subalias("B", m_D_EB.m_N); // Anode
-
- register_subalias("C", m_D_CB.m_P); // Cathode
-
- connect(m_D_EB.m_P, m_D_EC.m_P);
- connect(m_D_EB.m_N, m_D_CB.m_N);
- connect(m_D_CB.m_P, m_D_EC.m_N);
-
- if (m_model.m_CJE > 0.0)
- {
- create_and_register_subdevice("m_CJE", m_CJE);
- connect("B", "m_CJE.1");
- connect("E", "m_CJE.2");
- }
- if (m_model.m_CJC > 0.0)
- {
- create_and_register_subdevice("m_CJC", m_CJC);
- connect("B", "m_CJC.1");
- connect("C", "m_CJC.2");
- }
- }
-
- protected:
-
- NETLIB_RESETI();
- NETLIB_UPDATEI();
- NETLIB_UPDATE_PARAMI();
- NETLIB_UPDATE_TERMINALSI();
-
- private:
- generic_diode<diode_e::BIPOLAR> m_gD_BC;
- generic_diode<diode_e::BIPOLAR> m_gD_BE;
-
- nld_twoterm m_D_CB; // gcc, gce - gcc, gec - gcc, gcc - gce | Ic
- nld_twoterm m_D_EB; // gee, gec - gee, gce - gee, gee - gec | Ie
- nld_twoterm m_D_EC; // 0, -gec, -gcc, 0 | 0
-
- nl_double m_alpha_f;
- nl_double m_alpha_r;
-
- NETLIB_SUBXX(analog, C) m_CJE;
- NETLIB_SUBXX(analog, C) m_CJC;
- };
+ register_subalias("B", m_RB.m_P);
+ register_subalias("E", m_RB.m_N);
+ register_subalias("C", m_RC.m_P);
+ //register_term("_E1", m_RC.m_N);
+ //register_term("_B1", m_BC_dummy.m_P);
+ //register_term("_C1", m_BC_dummy.m_N);
- // ----------------------------------------------------------------------------------------
- // nld_Q
- // ----------------------------------------------------------------------------------------
+ connect(m_RB.m_N, m_RC.m_N);
- NETLIB_UPDATE(Q)
- {
- // netlist().solver()->schedule1();
+ connect(m_RB.m_P, m_BC_dummy.m_P);
+ connect(m_RC.m_P, m_BC_dummy.m_N);
}
- // ----------------------------------------------------------------------------------------
- // nld_QBJT_switch
- // ----------------------------------------------------------------------------------------
+ NETLIB_RESETI();
+ NETLIB_UPDATEI();
+ NETLIB_UPDATE_PARAMI();
+ NETLIB_UPDATE_TERMINALSI();
+ nld_twoterm m_RB;
+ nld_twoterm m_RC;
- NETLIB_RESET(QBJT_switch)
- {
- NETLIB_NAME(Q)::reset();
+ // FIXME: this is needed so we have all terminals belong to one net list
- m_state_on = 0;
+ nld_twoterm m_BC_dummy;
- m_RB.set_G_V_I(exec().gmin(), 0.0, 0.0);
- m_RC.set_G_V_I(exec().gmin(), 0.0, 0.0);
+protected:
- m_BC_dummy.set_G_V_I(exec().gmin() / 10.0, 0.0, 0.0);
- }
+ nl_double m_gB; // base conductance / switch on
+ nl_double m_gC; // collector conductance / switch on
+ nl_double m_V; // internal voltage source
+ state_var<unsigned> m_state_on;
+
+private:
+};
+
+// -----------------------------------------------------------------------------
+// nld_QBJT_EB
+// -----------------------------------------------------------------------------
- NETLIB_UPDATE(QBJT_switch)
+
+NETLIB_OBJECT_DERIVED(QBJT_EB, QBJT)
+{
+public:
+ NETLIB_CONSTRUCTOR_DERIVED(QBJT_EB, QBJT)
+ , m_gD_BC(*this, "m_D_BC")
+ , m_gD_BE(*this, "m_D_BE")
+ , m_D_CB(*this, "m_D_CB", true)
+ , m_D_EB(*this, "m_D_EB", true)
+ , m_D_EC(*this, "m_D_EC", true)
+ , m_alpha_f(0)
+ , m_alpha_r(0)
{
- if (!m_RB.m_P.net().isRailNet())
- m_RB.m_P.solve_now(); // Basis
- else if (!m_RB.m_N.net().isRailNet())
- m_RB.m_N.solve_now(); // Emitter
- else if (!m_RC.m_P.net().isRailNet())
- m_RC.m_P.solve_now(); // Collector
+ register_subalias("E", m_D_EB.m_P); // Cathode
+ register_subalias("B", m_D_EB.m_N); // Anode
+
+ register_subalias("C", m_D_CB.m_P); // Cathode
+ //register_term("_B1", m_D_CB.m_N); // Anode
+
+ //register_term("_E1", m_D_EC.m_P);
+ //register_term("_C1", m_D_EC.m_N);
+
+ connect(m_D_EB.m_P, m_D_EC.m_P);
+ connect(m_D_EB.m_N, m_D_CB.m_N);
+ connect(m_D_CB.m_P, m_D_EC.m_N);
}
+protected:
- NETLIB_UPDATE_PARAM(QBJT_switch)
- {
- nl_double IS = m_model.m_IS;
- nl_double BF = m_model.m_BF;
- nl_double NF = m_model.m_NF;
- //nl_double VJE = m_model.dValue("VJE", 0.75);
+ NETLIB_RESETI();
+ NETLIB_UPDATEI();
+ NETLIB_UPDATE_PARAMI();
+ NETLIB_UPDATE_TERMINALSI();
- set_qtype((m_model.model_type() == "NPN") ? BJT_NPN : BJT_PNP);
+ generic_diode m_gD_BC;
+ generic_diode m_gD_BE;
- nl_double alpha = BF / (1.0 + BF);
+private:
+ nld_twoterm m_D_CB; // gcc, gce - gcc, gec - gcc, gcc - gce | Ic
+ nld_twoterm m_D_EB; // gee, gec - gee, gce - gee, gee - gec | Ie
+ nld_twoterm m_D_EC; // 0, -gec, -gcc, 0 | 0
- diode d(IS, NF);
+ nl_double m_alpha_f;
+ nl_double m_alpha_r;
- // Assume 5mA Collector current for switch operation
+};
- m_V = d.V(0.005 / alpha);
- /* Base current is 0.005 / beta
- * as a rough estimate, we just scale the conductance down */
+// ----------------------------------------------------------------------------------------
+// nld_Q
+// ----------------------------------------------------------------------------------------
- m_gB = 1.0 / (m_V/(0.005 / BF));
+NETLIB_UPDATE(Q)
+{
+// netlist().solver()->schedule1();
+}
- //m_gB = d.gI(0.005 / alpha);
+// ----------------------------------------------------------------------------------------
+// nld_QBJT_switch
+// ----------------------------------------------------------------------------------------
- if (m_gB < exec().gmin())
- m_gB = exec().gmin();
- m_gC = d.gI(0.005); // very rough estimate
- }
- NETLIB_UPDATE_TERMINALS(QBJT_switch)
- {
- const nl_double m = (is_qtype( BJT_NPN) ? 1 : -1);
-
- const unsigned new_state = (m_RB.deltaV() * m > m_V ) ? 1 : 0;
- if (m_state_on ^ new_state)
- {
- const nl_double gb = new_state ? m_gB : exec().gmin();
- const nl_double gc = new_state ? m_gC : exec().gmin();
- const nl_double v = new_state ? m_V * m : 0;
-
- m_RB.set_G_V_I(gb, v, 0.0);
- m_RC.set_G_V_I(gc, 0.0, 0.0);
- m_state_on = new_state;
- }
- }
+NETLIB_RESET(QBJT_switch)
+{
+ NETLIB_NAME(Q)::reset();
+ m_state_on = 0;
- // ----------------------------------------------------------------------------------------
- // nld_Q - Ebers Moll
- // ----------------------------------------------------------------------------------------
+ m_RB.set(netlist().gmin(), 0.0, 0.0);
+ m_RC.set(netlist().gmin(), 0.0, 0.0);
+ m_BC_dummy.set(netlist().gmin() / 10.0, 0.0, 0.0);
- NETLIB_UPDATE(QBJT_EB)
- {
- if (!m_D_EB.m_P.net().isRailNet())
- m_D_EB.m_P.solve_now(); // Basis
- else if (!m_D_EB.m_N.net().isRailNet())
- m_D_EB.m_N.solve_now(); // Emitter
- else
- m_D_CB.m_N.solve_now(); // Collector
- }
+}
- NETLIB_RESET(QBJT_EB)
- {
- NETLIB_NAME(Q)::reset();
- if (m_CJE)
- {
- m_CJE->reset();
- m_CJE->m_C.setTo(m_model.m_CJE);
- }
- if (m_CJC)
- {
- m_CJC->reset();
- m_CJC->m_C.setTo(m_model.m_CJC);
- }
+NETLIB_UPDATE(QBJT_switch)
+{
+ if (!m_RB.m_P.net().isRailNet())
+ m_RB.m_P.solve_now(); // Basis
+ else if (!m_RB.m_N.net().isRailNet())
+ m_RB.m_N.solve_now(); // Emitter
+ else if (!m_RC.m_P.net().isRailNet())
+ m_RC.m_P.solve_now(); // Collector
+}
- }
- NETLIB_UPDATE_TERMINALS(QBJT_EB)
+NETLIB_UPDATE_PARAM(QBJT_switch)
+{
+ nl_double IS = m_model.m_IS;
+ nl_double BF = m_model.m_BF;
+ nl_double NF = m_model.m_NF;
+ //nl_double VJE = m_model.dValue("VJE", 0.75);
+
+ set_qtype((m_model.model_type() == "NPN") ? BJT_NPN : BJT_PNP);
+
+ nl_double alpha = BF / (1.0 + BF);
+
+ diode d(IS, NF);
+
+ // Assume 5mA Collector current for switch operation
+
+ m_V = d.V(0.005 / alpha);
+
+ /* Base current is 0.005 / beta
+ * as a rough estimate, we just scale the conductance down */
+
+ m_gB = 1.0 / (m_V/(0.005 / BF));
+
+ //m_gB = d.gI(0.005 / alpha);
+
+ if (m_gB < netlist().gmin())
+ m_gB = netlist().gmin();
+ m_gC = d.gI(0.005); // very rough estimate
+}
+
+NETLIB_UPDATE_TERMINALS(QBJT_switch)
+{
+ const nl_double m = (is_qtype( BJT_NPN) ? 1 : -1);
+
+ const unsigned new_state = (m_RB.deltaV() * m > m_V ) ? 1 : 0;
+ if (m_state_on ^ new_state)
{
- const nl_double polarity = (qtype() == BJT_NPN ? 1.0 : -1.0);
-
- m_gD_BE.update_diode(-m_D_EB.deltaV() * polarity);
- m_gD_BC.update_diode(-m_D_CB.deltaV() * polarity);
-
- const nl_double gee = m_gD_BE.G();
- const nl_double gcc = m_gD_BC.G();
- const nl_double gec = m_alpha_r * gcc;
- const nl_double gce = m_alpha_f * gee;
- const nl_double sIe = -m_gD_BE.I() + m_alpha_r * m_gD_BC.I();
- const nl_double sIc = m_alpha_f * m_gD_BE.I() - m_gD_BC.I();
- const nl_double Ie = (sIe + gee * m_gD_BE.Vd() - gec * m_gD_BC.Vd()) * polarity;
- const nl_double Ic = (sIc - gce * m_gD_BE.Vd() + gcc * m_gD_BC.Vd()) * polarity;
-
- m_D_EB.set_mat( gee, gec - gee, -Ie,
- gce - gee, gee - gec, Ie);
- m_D_CB.set_mat( gcc, gce - gcc, -Ic,
- gec - gcc, gcc - gce, Ic);
- m_D_EC.set_mat( 0, -gec, 0,
- -gce, 0, 0);
+ const nl_double gb = new_state ? m_gB : netlist().gmin();
+ const nl_double gc = new_state ? m_gC : netlist().gmin();
+ const nl_double v = new_state ? m_V * m : 0;
+
+ m_RB.set(gb, v, 0.0);
+ m_RC.set(gc, 0.0, 0.0);
+ m_state_on = new_state;
}
+}
- NETLIB_UPDATE_PARAM(QBJT_EB)
- {
- nl_double IS = m_model.m_IS;
- nl_double BF = m_model.m_BF;
- nl_double NF = m_model.m_NF;
- nl_double BR = m_model.m_BR;
- nl_double NR = m_model.m_NR;
- //nl_double VJE = m_model.dValue("VJE", 0.75);
+// ----------------------------------------------------------------------------------------
+// nld_Q - Ebers Moll
+// ----------------------------------------------------------------------------------------
- set_qtype((m_model.model_type() == "NPN") ? BJT_NPN : BJT_PNP);
- m_alpha_f = BF / (1.0 + BF);
- m_alpha_r = BR / (1.0 + BR);
+NETLIB_UPDATE(QBJT_EB)
+{
+ if (!m_D_EB.m_P.net().isRailNet())
+ m_D_EB.m_P.solve_now(); // Basis
+ else if (!m_D_EB.m_N.net().isRailNet())
+ m_D_EB.m_N.solve_now(); // Emitter
+ else
+ m_D_CB.m_N.solve_now(); // Collector
+}
+
+NETLIB_RESET(QBJT_EB)
+{
+ NETLIB_NAME(Q)::reset();
+}
- m_gD_BE.set_param(IS / m_alpha_f, NF, exec().gmin(), constants::T0());
- m_gD_BC.set_param(IS / m_alpha_r, NR, exec().gmin(), constants::T0());
- }
+NETLIB_UPDATE_TERMINALS(QBJT_EB)
+{
+ const nl_double polarity = (qtype() == BJT_NPN ? 1.0 : -1.0);
+
+ m_gD_BE.update_diode(-m_D_EB.deltaV() * polarity);
+ m_gD_BC.update_diode(-m_D_CB.deltaV() * polarity);
+
+ const nl_double gee = m_gD_BE.G();
+ const nl_double gcc = m_gD_BC.G();
+ const nl_double gec = m_alpha_r * gcc;
+ const nl_double gce = m_alpha_f * gee;
+ const nl_double sIe = -m_gD_BE.I() + m_alpha_r * m_gD_BC.I();
+ const nl_double sIc = m_alpha_f * m_gD_BE.I() - m_gD_BC.I();
+ const nl_double Ie = (sIe + gee * m_gD_BE.Vd() - gec * m_gD_BC.Vd()) * polarity;
+ const nl_double Ic = (sIc - gce * m_gD_BE.Vd() + gcc * m_gD_BC.Vd()) * polarity;
+
+ m_D_EB.set_mat( gee, gec - gee, -Ie,
+ gce - gee, gee - gec, Ie);
+ m_D_CB.set_mat( gcc, gce - gcc, -Ic,
+ gec - gcc, gcc - gce, Ic);
+ m_D_EC.set_mat( 0, -gec, 0,
+ -gce, 0, 0);
+}
+
+
+NETLIB_UPDATE_PARAM(QBJT_EB)
+{
+ nl_double IS = m_model.m_IS;
+ nl_double BF = m_model.m_BF;
+ nl_double NF = m_model.m_NF;
+ nl_double BR = m_model.m_BR;
+ nl_double NR = m_model.m_NR;
+ //nl_double VJE = m_model.dValue("VJE", 0.75);
-} // namespace analog
+ set_qtype((m_model.model_type() == "NPN") ? BJT_NPN : BJT_PNP);
-namespace devices {
- NETLIB_DEVICE_IMPL_NS(analog, QBJT_EB, "QBJT_EB", "MODEL")
- NETLIB_DEVICE_IMPL_NS(analog, QBJT_switch, "QBJT_SW", "MODEL")
-} // namespace devices
+ m_alpha_f = BF / (1.0 + BF);
+ m_alpha_r = BR / (1.0 + BR);
+
+ m_gD_BE.set_param(IS / m_alpha_f, NF, netlist().gmin());
+ m_gD_BC.set_param(IS / m_alpha_r, NR, netlist().gmin());
+}
+
+ } //namespace analog
+
+ namespace devices {
+ NETLIB_DEVICE_IMPL_NS(analog, QBJT_EB)
+ NETLIB_DEVICE_IMPL_NS(analog, QBJT_switch)
+ }
} // namespace netlist
diff --git a/src/lib/netlist/analog/nld_bjt.h b/src/lib/netlist/analog/nld_bjt.h
index 3a8478f19f7..9e1f82afbaa 100644
--- a/src/lib/netlist/analog/nld_bjt.h
+++ b/src/lib/netlist/analog/nld_bjt.h
@@ -8,7 +8,7 @@
#ifndef NLD_BJT_H_
#define NLD_BJT_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
// -----------------------------------------------------------------------------
// Macros
diff --git a/src/lib/netlist/analog/nld_fourterm.h b/src/lib/netlist/analog/nld_fourterm.h
index 66c47c0be29..b4bb5db1059 100644
--- a/src/lib/netlist/analog/nld_fourterm.h
+++ b/src/lib/netlist/analog/nld_fourterm.h
@@ -9,7 +9,7 @@
#define NLD_FOURTERM_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
// ----------------------------------------------------------------------------------------
// Macros
diff --git a/src/lib/netlist/analog/nld_mosfet.cpp b/src/lib/netlist/analog/nld_mosfet.cpp
deleted file mode 100644
index ea717fdefee..00000000000
--- a/src/lib/netlist/analog/nld_mosfet.cpp
+++ /dev/null
@@ -1,488 +0,0 @@
-// license:GPL-2.0+
-// copyright-holders:Couriersud
-/*
- * nld_mosfet.cpp
- *
- * Formulas in here based on the following Sources:
- *
- * https://www.imperial.ac.uk/pls/portallive/docs/1/7292573.PDF
- * http://www3.imperial.ac.uk/pls/portallive/docs/1/56133736.PDF
- * https://people.rit.edu/lffeee/SPICE_MOSFET_Model_Intro.pdf
- * https://people.rit.edu/lffeee/SPICE.pdf
- * http://web.mit.edu/course/6/6.012/SPR98/www/lectures/S98_Lecture10.pdf
- * http://homepages.rpi.edu/~sawyes/Models_review.pdf
- * http://jaco.ec.t.kanazawa-u.ac.jp/edu/mix/pdf/3.pdf
- *
- * Farid N. Naim, Circuit Simulation (Wiley-IEEE Press, 2010).
- * Stefan Jahn, Michael Margraf, Vincent Habchi and Raimund Jacob, "Qucs Technical Papers" (2007)
- *
- */
-
-#include "netlist/solver/nld_solver.h"
-#include "netlist/nl_setup.h"
-#include "nlid_twoterm.h"
-
-#include <cmath>
-
-#define BODY_CONNECTED_TO_SOURCE (1)
-
-namespace netlist
-{
-namespace analog
-{
-
- using constants = plib::constants<nl_double>;
-
- // -----------------------------------------------------------------------------
- // nld_FET - Base classes
- // -----------------------------------------------------------------------------
-
- /*! Class representing the nmos model paramers.
- *
- * This is the model representation of the nmos model. Typically, SPICE uses
- * the following parameters. A "Y" in the first column indicates that the
- * parameter is actually used in netlist.
- *
- * | NL? |Name | Description|Units |Default |Example |
- * |:---:|------|-----------------------------------------------------------------------|-------|---------:|----------------:|
- * | Y |Vto | Zero-bias threshold voltage | V | 0 | 1 |
- * | Y |Kp | Transconductance parameter | A/V² | 0.00002 | 0.00003 |
- * | Y |Gamma | Bulk threshold parameter | V^½ | 0 | 0.37 |
- * | Y |Phi | Surface inversion potential | V | 0.6 | 0.65 |
- * | Y |Lambda| Channel-length modulation (level 1 and 2 only) | 1/V | 0 | 0.02 |
- * | |Rd | Drain ohmic resistance |W|0|1|
- * | |Rs | Source ohmic resistance |W|0|1|
- * | |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|
- * | |Cgso | Gate-source overlap capacitance per meter channel width |F/m|0|0.00000000004|
- * | |Cgdo | Gate-drain overlap capacitance per meter channel width |F/m|0|0.00000000004|*
- * | |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µ|*
- * | 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|*
- * | |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|
- * | |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||
- * | Y |L | Length scaling |-|1.0||
- * | Y |W | Width scaling |-|1.0||
- * */
-
- class fet_model_t : public param_model_t
- {
- public:
- fet_model_t(device_t &device, const pstring &name, const pstring &val)
- : param_model_t(device, name, val)
- , m_VTO(*this, "VTO")
- , m_N(*this, "N")
- , m_ISS(*this, "IS") // Haven't seen a model using ISS / ISD
- , m_ISD(*this, "IS")
- , m_LD(*this, "LD")
- , m_L(*this, "L")
- , m_W(*this, "W")
- , m_TOX(*this, "TOX")
- , m_KP(*this, "KP")
- , m_UO(*this, "UO")
- , m_PHI(*this, "PHI")
- , m_NSUB(*this, "NSUB")
- , m_GAMMA(*this, "GAMMA")
- , m_LAMBDA(*this, "LAMBDA")
- , m_RD(*this, "RD")
- , m_RS(*this, "RS")
- {}
-
- value_t m_VTO; //!< Threshold voltage [V]
- value_t m_N; //!< Bulk diode emission coefficient
- value_t m_ISS; //!< Body diode saturation current
- value_t m_ISD; //!< Body diode saturation current
- value_t m_LD; //!< Lateral diffusion [m]
- value_t m_L; //!< Length scaling
- value_t m_W; //!< Width scaling
- value_t m_TOX; //!< Oxide thickness
- value_t m_KP; //!< Transconductance parameter [A/V²]
- value_t m_UO; //!< Surface mobility [cm²/V/s]
- value_t m_PHI; //!< Surface inversion potential [V]
- value_t m_NSUB;//!< Substrate doping [1/cm³]
- value_t m_GAMMA; //!< Bulk threshold parameter [V^½]
- value_t m_LAMBDA; //!< Channel-length modulation [1/V]
- value_t m_RD; //!< Drain ohmic resistance
- value_t m_RS; //!< Source ohmic resistance
- };
-
- // Have a common start for mosfets
-
- NETLIB_OBJECT(FET)
- {
- public:
- enum q_type {
- FET_NMOS,
- FET_PMOS
- };
-
- NETLIB_CONSTRUCTOR(FET)
- , m_model(*this, "MODEL", "NMOS")
- , m_qtype(FET_NMOS)
- {
- }
-
- NETLIB_IS_DYNAMIC(true)
-
- //NETLIB_RESETI();
- NETLIB_UPDATEI() { }
-
- q_type qtype() const { return m_qtype; }
- bool is_qtype(q_type atype) const { return m_qtype == atype; }
- void set_qtype(q_type atype) { m_qtype = atype; }
- protected:
-
- fet_model_t m_model;
- private:
- q_type m_qtype;
- };
-
- // -----------------------------------------------------------------------------
- // nld_QBJT_EB
- // -----------------------------------------------------------------------------
-
-
- NETLIB_OBJECT_DERIVED(MOSFET, FET)
- {
- public:
- NETLIB_CONSTRUCTOR_DERIVED(MOSFET, FET)
- , m_DG(*this, "m_DG", true)
- , m_SG(*this, "m_SG", true)
- , m_SD(*this, "m_SD", true)
- , m_D_BD(*this, "m_D_BD")
-#if (!BODY_CONNECTED_TO_SOURCE)
- , m_D_BS(*this, "m_D_BS")
-#endif
- , m_phi(0.0)
- , m_gamma(0.0)
- , m_vto(0.0)
- , m_beta(0.0)
- , m_lambda(0.0)
- , m_Leff(0.0)
- , m_Cox(0.0)
- {
- register_subalias("S", m_SG.m_P); // Source
- register_subalias("G", m_SG.m_N); // Gate
-
- register_subalias("D", m_DG.m_P); // Drain
-
- connect(m_SG.m_P, m_SD.m_P);
- connect(m_SG.m_N, m_DG.m_N);
- connect(m_DG.m_P, m_SD.m_N);
-
-#if 0
- if (m_model.m_CJE > 0.0)
- {
- create_and_register_subdevice("m_CJE", m_CJE);
- connect("B", "m_CJE.1");
- connect("E", "m_CJE.2");
- }
- if (m_model.m_CJC > 0.0)
- {
- create_and_register_subdevice("m_CJC", m_CJC);
- connect("B", "m_CJC.1");
- connect("C", "m_CJC.2");
- }
-#endif
- }
-
- protected:
-
- NETLIB_RESETI();
- NETLIB_UPDATEI();
- NETLIB_UPDATE_PARAMI();
- NETLIB_UPDATE_TERMINALSI();
-
- private:
-
- nld_twoterm m_DG;
- nld_twoterm m_SG;
- nld_twoterm m_SD;
-
- generic_diode<diode_e::MOS> m_D_BD;
-#if (!BODY_CONNECTED_TO_SOURCE)
- generic_diode<diode_e::MOS> m_D_BS;
-#endif
-
- nl_double m_phi;
- nl_double m_gamma;
- nl_double m_vto;
- nl_double m_beta;
- nl_double m_lambda;
-
- /* used in capacitance calculation */
- nl_double m_Leff;
- nl_double m_Cox;
-
- //NETLIB_SUBXX(analog, C) m_CJE;
- //NETLIB_SUBXX(analog, C) m_CJC;
- };
-
-
-
- // ----------------------------------------------------------------------------------------
- // nld_Q - Ebers Moll
- // ----------------------------------------------------------------------------------------
-
-
- NETLIB_UPDATE(MOSFET)
- {
- if (!m_SG.m_P.net().isRailNet())
- m_SG.m_P.solve_now(); // Basis
- else if (!m_SG.m_N.net().isRailNet())
- m_SG.m_N.solve_now(); // Emitter
- else
- m_DG.m_N.solve_now(); // Collector
- }
-
- NETLIB_RESET(MOSFET)
- {
- NETLIB_NAME(FET)::reset();
-#if 0
- if (m_CJE)
- {
- m_CJE->reset();
- m_CJE->m_C.setTo(m_model.m_CJE);
- }
- if (m_CJC)
- {
- m_CJC->reset();
- m_CJC->m_C.setTo(m_model.m_CJC);
- }
-#endif
- }
-
- NETLIB_UPDATE_TERMINALS(MOSFET)
- {
- const nl_double polarity = (qtype() == FET_NMOS ? 1.0 : -1.0);
-
- const nl_double Ugd = -m_DG.deltaV() * polarity; // Gate - Drain
- const nl_double Ugs = -m_SG.deltaV() * polarity; // Gate - Source
- const nl_double Ubs = 0.0; // Bulk - Source == 0 if connected
- const nl_double Ubd = m_SD.deltaV() * polarity; // Bulk - Drain = Source - Drain
- const nl_double Uds = Ugs - Ugd;
-
-#if (!BODY_CONNECTED_TO_SOURCE)
- m_D_BS.update_diode(Ubs);
-#endif
- m_D_BD.update_diode(Ubd);
-
- // Are we in forward mode ?
- const bool is_forward = Uds >= 0;
-
- // calculate Vth
- const nl_double Vbulk = is_forward ? Ubs : Ubd;
- const nl_double phi_m_Vbulk = (m_phi > Vbulk) ? std::sqrt(m_phi - Vbulk) : 0.0;
- const nl_double Vth = m_vto * polarity + m_gamma * (phi_m_Vbulk - std::sqrt(m_phi));
-
- const nl_double Vctrl = (is_forward ? Ugs : Ugd) - Vth;
-
- nl_double Ids, gm, gds, gmb;
-
- if (Vctrl <= 0.0)
- {
- // cutoff region
- Ids = 0.0;
- gm = 0.0;
- gds = 0.0;
- gmb = 0.0;
- }
- else
- {
- const nl_double Vds = std::abs(Uds);
- const nl_double b = m_beta * (1.0 + m_lambda * Vds);
- if (Vctrl <= Vds)
- {
- // saturation region
- Ids = b * Vctrl * Vctrl / 2.0;
- gm = b * Vctrl;
- gds = m_lambda * m_beta * Vctrl * Vctrl / 2.0;
- }
- else
- {
- // linear region
- Ids = b * Vds * (Vctrl - Vds / 2);
- gm = b * Vds;
- gds = b * (Vctrl - Vds) + m_lambda * m_beta * Vds * (Vctrl - Vds / 2.0);
- }
-
- // backgate transconductance
- const nl_double bgtc = (phi_m_Vbulk != 0.0) ? (m_gamma / phi_m_Vbulk / 2.0) : 0.0;
- gmb = gm * bgtc;
- }
-
- // FIXME: these are needed to compute capacitance
- // nl_double Udsat = pol * std::max (Utst, 0.0);
- // Uon = pol * Vth;
-
- // compute bulk diode equivalent currents
-
- const nl_double IeqBD = m_D_BD.Ieq();
- const nl_double gbd = m_D_BD.G();
-#if 0
- const nl_double IeqBS = m_D_BS.Ieq();
- const nl_double gbs = m_D_BS.G();
-#else
- const nl_double IeqBS = 0.0;
- const nl_double gbs = 0.0;
-#endif
- // exchange controlling nodes if necessary
- const nl_double gsource = is_forward ? (gm + gmb) : 0;
- const nl_double gdrain = is_forward ? 0.0 : (gm + gmb);
-
- const nl_double IeqDS = (is_forward) ?
- Ids - gm * Ugs - gmb * Ubs - gds * Uds
- : -Ids - gm * Ugd - gmb * Ubd - gds * Uds;
-
- // IG = 0
- const nl_double IG = 0.0;
- const nl_double ID = (+IeqBD - IeqDS) * polarity;
- const nl_double IS = (+IeqBS + IeqDS) * polarity;
- const nl_double IB = (-IeqBD - IeqBS) * polarity;
-
- const nl_double gGG = 0.0; // ok
- const nl_double gGD = 0.0; // ok
- const nl_double gGS = 0.0; // ok
- const nl_double gGB = 0.0; // ok
-
- const nl_double gDG = gm; // ok
- const nl_double gDD = gds + gbd - gdrain; // ok
- const nl_double gDS = -gds - gsource; // ok
- const nl_double gDB = gmb - gbd; // ok
-
- const nl_double gSG = -gm; // ok
- const nl_double gSD = -gds + gdrain; // ok
- const nl_double gSS = gbs + gds + gsource; // ok
- const nl_double gSB = -gbs - gmb;
-
- const nl_double gBG = 0.0; // ok
- const nl_double gBD = -gbd; // ok
- const nl_double gBS = -gbs;
- const nl_double gBB = gbs + gbd; // ok
-
- // Source connected to body, Diode S-B shorted!
- const nl_double gSSBB = gSS + gBB + gBS + gSB;
-
- // S G
- m_SG.set_mat( gSSBB, gSG + gBG, +(IS + IB), // S
- gGS + gGB, gGG, IG ); // G
- // D G
- m_DG.set_mat( gDD, gDG, +ID, // D
- gGD, 0.0, 0.0 ); // G
- // S D
- m_SD.set_mat( 0.0, gSD + gBD, 0.0, // S
- gDS + gDB, 0.0, 0.0); // D
-
- }
-
-
- NETLIB_UPDATE_PARAM(MOSFET)
- {
- set_qtype((m_model.model_type() == "NMOS") ? FET_NMOS : FET_PMOS);
-
- /*
- * From http://ltwiki.org/LTspiceHelp/LTspiceHelp/M_MOSFET.htm :
- *
- * VTO, KP, LAMBDA, PHI and GAMMA. These parameters are computed
- * if the process parameters(NSUB, TOX,...) are given, but
- * user-specified values always override.
- *
- * But couldn't find a formula for lambda anywhere
- *
- */
-
- m_lambda = m_model.m_LAMBDA; // FIXME: m_lambda only set once
-
- // calculate effective channel length
- m_Leff = m_model.m_L - 2 * m_model.m_LD;
- nl_assert_always(m_Leff > 0.0, "Effective Lateral diffusion would be negative for model " + m_model.name());
- if (m_model.m_TOX > 0.0)
- m_Cox = (constants::eps_SiO2() * constants::eps_0() / m_model.m_TOX);
- else
- m_Cox = 0.0;
-
- // calculate DC transconductance coefficient
- if (m_model.m_KP > 0)
- m_beta = m_model.m_KP * m_model.m_W / m_Leff;
- else if (m_Cox > 0 && m_model.m_UO > 0)
- m_beta = m_model.m_UO * 1e-4 * m_Cox * m_model.m_W / m_Leff;
- else
- m_beta = 2e-5 * m_model.m_W / m_Leff;
-
- // Bulk diodes
-
- m_D_BD.set_param(m_model.m_ISD, m_model.m_N, exec().gmin(), constants::T0());
-#if (!BODY_CONNECTED_TO_SOURCE)
- m_D_BS.set_param(m_model.m_ISS, m_model.m_N, exec().gmin(), constants::T0());
-#endif
-
- //FIXME::UT can disappear
- const double Vt = constants::T0() * constants::k_b() / constants::Q_e();
-
- // calculate surface potential if not given
-
- if (m_model.m_PHI > 0.0)
- m_phi = m_model.m_PHI;
- else if (m_model.m_NSUB > 0.0)
- {
- nl_assert_always(m_model.m_NSUB * 1e6 >= constants::NiSi(), "Error calculating phi for model " + m_model.name());
- m_phi = 2 * Vt * std::log (m_model.m_NSUB * 1e6 / constants::NiSi());
- }
- else
- m_phi = 0.6;
-
- // calculate bulk threshold if not given
- if (m_model.m_GAMMA > 0.0)
- m_gamma = m_model.m_GAMMA;
- else
- {
- if (m_Cox > 0 && m_model.m_NSUB > 0)
- m_gamma = std::sqrt (2.0 * constants::Q_e() * constants::eps_Si() * constants::eps_0() * m_model.m_NSUB * 1e6) / m_Cox;
- else
- m_gamma = 0.0;
- }
-
- m_vto = m_model.m_VTO;
- nl_assert_always(m_vto != 0.0, "Threshold voltage not specified for " + m_model.name());
-
- /* FIXME: VTO if missing may be calculated from TPG, NSS and temperature. Usually models
- * specify VTO so skip this here.
- */
-
- m_Cox = m_Cox * m_model.m_W * m_Leff;
-
- }
-
-} // namespace analog
-
-namespace devices {
- NETLIB_DEVICE_IMPL_NS(analog, MOSFET, "MOSFET", "MODEL")
-} // namespace devices
-
-} // namespace netlist
diff --git a/src/lib/netlist/analog/nld_mosfet.h b/src/lib/netlist/analog/nld_mosfet.h
deleted file mode 100644
index 32011d709d8..00000000000
--- a/src/lib/netlist/analog/nld_mosfet.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// license:GPL-2.0+
-// copyright-holders:Couriersud
-/*
- * nld_mosfet.h
- *
- */
-
-#ifndef NLD_MOSFET_H_
-#define NLD_MOSFET_H_
-
-#include "netlist/nl_setup.h"
-
-// -----------------------------------------------------------------------------
-// Macros
-// -----------------------------------------------------------------------------
-
-#define MOSFET(name, model) \
- NET_REGISTER_DEV(MOSFET, name) \
- NETDEV_PARAMI(name, MODEL, model)
-
-#endif /* NLD_MOSFET_H_ */
diff --git a/src/lib/netlist/analog/nld_opamps.cpp b/src/lib/netlist/analog/nld_opamps.cpp
index 8c3c655bfa9..5f55a26f5d0 100644
--- a/src/lib/netlist/analog/nld_opamps.cpp
+++ b/src/lib/netlist/analog/nld_opamps.cpp
@@ -6,10 +6,10 @@
*/
#include "nld_opamps.h"
-#include "netlist/nl_base.h"
-#include "netlist/nl_errstr.h"
-#include "nlid_fourterm.h"
+#include "../nl_base.h"
+#include "../nl_errstr.h"
#include "nlid_twoterm.h"
+#include "nlid_fourterm.h"
#include <cmath>
@@ -129,10 +129,10 @@ namespace netlist
}
else if (m_type == 3)
{
- create_and_register_subdevice("CP1", m_CP);
- create_and_register_subdevice("EBUF", m_EBUF);
- create_and_register_subdevice("DN", m_DN, "D(IS=1e-15 N=1)");
- create_and_register_subdevice("DP", m_DP, "D(IS=1e-15 N=1)");
+ register_sub("CP1", m_CP);
+ register_sub("EBUF", m_EBUF);
+ register_sub("DN", m_DN, "D(IS=1e-15 N=1)");
+ register_sub("DP", m_DP, "D(IS=1e-15 N=1)");
//m_DP->m_model.setTo("D(IS=1e-15 N=1)");
//m_DN->m_model.setTo("D(IS=1e-15 N=1)");
@@ -201,7 +201,7 @@ namespace netlist
NETLIB_RESET(opamp)
{
- m_G1.reset();
+ m_G1.do_reset();
m_G1.m_RI.setTo(m_model.m_RI);
if (m_type == 1)
@@ -213,11 +213,11 @@ namespace netlist
}
else if (m_type == 3)
{
- m_EBUF->reset();
- m_DP->reset();
- m_DN->reset();
- m_CP->reset();
- m_RP.reset();
+ m_EBUF->do_reset();
+ m_DP->do_reset();
+ m_DN->do_reset();
+ m_CP->do_reset();
+ m_RP.do_reset();
m_EBUF->m_G.setTo(1.0);
m_EBUF->m_RO.setTo(m_model.m_RO);
@@ -239,6 +239,6 @@ namespace netlist
} //namespace analog
namespace devices {
- NETLIB_DEVICE_IMPL_NS(analog, opamp, "OPAMP", "MODEL")
- } // namespace devices
+ NETLIB_DEVICE_IMPL_NS(analog, opamp)
+ }
} // namespace netlist
diff --git a/src/lib/netlist/analog/nld_opamps.h b/src/lib/netlist/analog/nld_opamps.h
index 4a07f646587..d05a19aa3dc 100644
--- a/src/lib/netlist/analog/nld_opamps.h
+++ b/src/lib/netlist/analog/nld_opamps.h
@@ -10,7 +10,7 @@
#ifndef NLD_OPAMPS_H_
#define NLD_OPAMPS_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
// ----------------------------------------------------------------------------------------
// Macros
diff --git a/src/lib/netlist/analog/nld_switches.cpp b/src/lib/netlist/analog/nld_switches.cpp
index 0e62fe13952..1575551f260 100644
--- a/src/lib/netlist/analog/nld_switches.cpp
+++ b/src/lib/netlist/analog/nld_switches.cpp
@@ -6,13 +6,10 @@
*/
#include "nlid_twoterm.h"
-#include "netlist/nl_base.h"
-#include "netlist/nl_factory.h"
-#include "netlist/solver/nld_solver.h"
+#include "../nl_base.h"
+#include "../nl_factory.h"
-/* FIXME : convert to parameters */
-
-#define R_OFF (1.0 / exec().gmin())
+#define R_OFF (1.0 / netlist().gmin())
#define R_ON 0.01
namespace netlist
@@ -27,7 +24,7 @@ namespace netlist
{
NETLIB_CONSTRUCTOR(switch1)
, m_R(*this, "R")
- , m_POS(*this, "POS", false)
+ , m_POS(*this, "POS", 0)
{
register_subalias("1", m_R.m_P);
register_subalias("2", m_R.m_N);
@@ -49,11 +46,6 @@ namespace netlist
NETLIB_UPDATE(switch1)
{
- }
-
- NETLIB_UPDATE_PARAM(switch1)
- {
- m_R.solve_now();
if (!m_POS())
{
m_R.set_R(R_OFF);
@@ -62,8 +54,13 @@ namespace netlist
{
m_R.set_R(R_ON);
}
- m_R.solve_later();
+ m_R.update_dev();
+ }
+
+ NETLIB_UPDATE_PARAM(switch1)
+ {
+ update();
}
// ----------------------------------------------------------------------------------------
@@ -75,7 +72,7 @@ namespace netlist
NETLIB_CONSTRUCTOR(switch2)
, m_R1(*this, "R1")
, m_R2(*this, "R2")
- , m_POS(*this, "POS", false)
+ , m_POS(*this, "POS", 0)
{
connect(m_R1.m_N, m_R2.m_N);
@@ -113,31 +110,19 @@ namespace netlist
m_R2.set_R(R_ON);
}
- //m_R1.update_dev(time);
- //m_R2.update_dev(time);
+ m_R1.update_dev();
+ m_R2.update_dev();
}
NETLIB_UPDATE_PARAM(switch2)
{
- if (!m_POS())
- {
- m_R1.set_R(R_ON);
- m_R2.set_R(R_OFF);
- }
- else
- {
- m_R1.set_R(R_OFF);
- m_R2.set_R(R_ON);
- }
-
- m_R1.solve_now();
- m_R2.solve_now();
+ update();
}
} //namespace analog
namespace devices {
- NETLIB_DEVICE_IMPL_NS(analog, switch1, "SWITCH", "")
- NETLIB_DEVICE_IMPL_NS(analog, switch2, "SWITCH2", "")
- } // namespace devices
+ NETLIB_DEVICE_IMPL_NS(analog, switch1)
+ NETLIB_DEVICE_IMPL_NS(analog, switch2)
+ }
} // namespace netlist
diff --git a/src/lib/netlist/analog/nld_switches.h b/src/lib/netlist/analog/nld_switches.h
index 7aa31c925ae..3cd561f84b1 100644
--- a/src/lib/netlist/analog/nld_switches.h
+++ b/src/lib/netlist/analog/nld_switches.h
@@ -10,7 +10,7 @@
#ifndef NLD_SWITCHES_H_
#define NLD_SWITCHES_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
// ----------------------------------------------------------------------------------------
// Macros
diff --git a/src/lib/netlist/analog/nld_twoterm.h b/src/lib/netlist/analog/nld_twoterm.h
index b175f40af97..d5cf6f6d228 100644
--- a/src/lib/netlist/analog/nld_twoterm.h
+++ b/src/lib/netlist/analog/nld_twoterm.h
@@ -4,7 +4,7 @@
#ifndef NLD_TWOTERM_H_
#define NLD_TWOTERM_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
// -----------------------------------------------------------------------------
// Macros
diff --git a/src/lib/netlist/analog/nlid_fourterm.cpp b/src/lib/netlist/analog/nlid_fourterm.cpp
index 7fa6a2f3809..aa2723fe8e1 100644
--- a/src/lib/netlist/analog/nlid_fourterm.cpp
+++ b/src/lib/netlist/analog/nlid_fourterm.cpp
@@ -5,8 +5,8 @@
*
*/
-#include "netlist/solver/nld_solver.h"
-#include "netlist/nl_factory.h"
+#include "../solver/nld_solver.h"
+#include "../nl_factory.h"
#include "nlid_fourterm.h"
#include <cmath>
@@ -24,16 +24,16 @@ namespace netlist
NETLIB_RESET(VCCS)
{
const nl_double m_mult = m_G() * m_gfac; // 1.0 ==> 1V ==> 1A
- const nl_double GI = plib::constants<nl_double>::one() / m_RI();
+ const nl_double GI = NL_FCONST(1.0) / m_RI();
- m_IP.set_conductivity(GI);
- m_IN.set_conductivity(GI);
+ m_IP.set(GI);
+ m_IN.set(GI);
- m_OP.set_go_gt(-m_mult, plib::constants<nl_double>::zero());
- m_OP1.set_go_gt(m_mult, plib::constants<nl_double>::zero());
+ m_OP.set(m_mult, NL_FCONST(0.0));
+ m_OP1.set(-m_mult, NL_FCONST(0.0));
- m_ON.set_go_gt(m_mult, plib::constants<nl_double>::zero());
- m_ON1.set_go_gt(-m_mult, plib::constants<nl_double>::zero());
+ m_ON.set(-m_mult, NL_FCONST(0.0));
+ m_ON1.set(m_mult, NL_FCONST(0.0));
}
NETLIB_UPDATE(VCCS)
@@ -63,6 +63,11 @@ NETLIB_UPDATE_PARAM(LVCCS)
NETLIB_NAME(VCCS)::update_param();
}
+NETLIB_UPDATE(LVCCS)
+{
+ NETLIB_NAME(VCCS)::update();
+}
+
NETLIB_UPDATE_TERMINALS(LVCCS)
{
const nl_double m_mult = m_G() * m_gfac; // 1.0 ==> 1V ==> 1A
@@ -79,11 +84,11 @@ NETLIB_UPDATE_TERMINALS(LVCCS)
const nl_double beta = m_mult * (1.0 - X*X);
const nl_double I = m_cur_limit() * X - beta * m_vi;
- m_OP.set_go_gt_I(-beta, plib::constants<nl_double>::zero(), I);
- m_OP1.set_go_gt(beta, plib::constants<nl_double>::zero());
+ m_OP.set(beta, NL_FCONST(0.0), I);
+ m_OP1.set(-beta, NL_FCONST(0.0));
- m_ON.set_go_gt_I(beta, plib::constants<nl_double>::zero(), -I);
- m_ON1.set_go_gt(-beta, plib::constants<nl_double>::zero());
+ m_ON.set(-beta, NL_FCONST(0.0), -I);
+ m_ON1.set(beta, NL_FCONST(0.0));
}
// ----------------------------------------------------------------------------------------
@@ -100,25 +105,30 @@ NETLIB_UPDATE_PARAM(CCCS)
NETLIB_NAME(VCCS)::update_param();
}
+NETLIB_UPDATE(CCCS)
+{
+ NETLIB_NAME(VCCS)::update();
+}
+
// ----------------------------------------------------------------------------------------
// nld_VCVS
// ----------------------------------------------------------------------------------------
NETLIB_RESET(VCVS)
{
- m_gfac = plib::constants<nl_double>::one() / m_RO();
+ m_gfac = NL_FCONST(1.0) / m_RO();
NETLIB_NAME(VCCS)::reset();
- m_OP2.set_conductivity(plib::constants<nl_double>::one() / m_RO());
- m_ON2.set_conductivity(plib::constants<nl_double>::one() / m_RO());
+ m_OP2.set(NL_FCONST(1.0) / m_RO());
+ m_ON2.set(NL_FCONST(1.0) / m_RO());
}
} //namespace analog
namespace devices {
- NETLIB_DEVICE_IMPL_NS(analog, VCVS, "VCVS", "")
- NETLIB_DEVICE_IMPL_NS(analog, VCCS, "VCCS", "")
- NETLIB_DEVICE_IMPL_NS(analog, CCCS, "CCCS", "")
- NETLIB_DEVICE_IMPL_NS(analog, LVCCS, "LVCCS", "")
- } // namespace devices
+ NETLIB_DEVICE_IMPL_NS(analog, VCVS)
+ NETLIB_DEVICE_IMPL_NS(analog, VCCS)
+ NETLIB_DEVICE_IMPL_NS(analog, CCCS)
+ NETLIB_DEVICE_IMPL_NS(analog, LVCCS)
+ }
} // namespace netlist
diff --git a/src/lib/netlist/analog/nlid_fourterm.h b/src/lib/netlist/analog/nlid_fourterm.h
index 5ca6a747116..641fc72427b 100644
--- a/src/lib/netlist/analog/nlid_fourterm.h
+++ b/src/lib/netlist/analog/nlid_fourterm.h
@@ -8,8 +8,7 @@
#ifndef NLID_FOURTERM_H_
#define NLID_FOURTERM_H_
-#include "netlist/nl_base.h"
-#include "plib/putil.h"
+#include "../nl_base.h"
namespace netlist {
namespace analog {
@@ -41,32 +40,39 @@ namespace netlist {
NETLIB_CONSTRUCTOR(VCCS)
, m_G(*this, "G", 1.0)
, m_RI(*this, "RI", 1e9)
- , m_OP(*this, "OP", &m_IP)
- , m_ON(*this, "ON", &m_IP)
- , m_IP(*this, "IP", &m_IN) // <= this should be NULL and terminal be filtered out prior to solving...
- , m_IN(*this, "IN", &m_IP) // <= this should be NULL and terminal be filtered out prior to solving...
- , m_OP1(*this, "_OP1", &m_IN)
- , m_ON1(*this, "_ON1", &m_IN)
+ , m_OP(*this, "OP")
+ , m_ON(*this, "ON")
+ , m_IP(*this, "IP")
+ , m_IN(*this, "IN")
+ , m_OP1(*this, "_OP1")
+ , m_ON1(*this, "_ON1")
, m_gfac(1.0)
{
+ m_IP.m_otherterm = &m_IN; // <= this should be NULL and terminal be filtered out prior to solving...
+ m_IN.m_otherterm = &m_IP; // <= this should be NULL and terminal be filtered out prior to solving...
+
+ m_OP.m_otherterm = &m_IP;
+ m_OP1.m_otherterm = &m_IN;
+
+ m_ON.m_otherterm = &m_IP;
+ m_ON1.m_otherterm = &m_IN;
+
connect(m_OP, m_OP1);
connect(m_ON, m_ON1);
- m_gfac = plib::constants<nl_double>::one();
+ m_gfac = NL_FCONST(1.0);
}
- NETLIB_RESETI();
-
param_double_t m_G;
param_double_t m_RI;
protected:
+ NETLIB_RESETI();
NETLIB_UPDATEI();
NETLIB_UPDATE_PARAMI()
{
NETLIB_NAME(VCCS)::reset();
}
-
terminal_t m_OP;
terminal_t m_ON;
@@ -92,14 +98,14 @@ namespace netlist {
NETLIB_IS_DYNAMIC(true)
+ param_double_t m_cur_limit; /* current limit */
+
protected:
- //NETLIB_UPDATEI();
+ NETLIB_UPDATEI();
NETLIB_RESETI();
NETLIB_UPDATE_PARAMI();
NETLIB_UPDATE_TERMINALSI();
- private:
- param_double_t m_cur_limit; /* current limit */
nl_double m_vi;
};
@@ -131,13 +137,12 @@ namespace netlist {
public:
NETLIB_CONSTRUCTOR_DERIVED(CCCS, VCCS)
{
- m_gfac = plib::constants<nl_double>::one() / m_RI();
+ m_gfac = NL_FCONST(1.0) / m_RI();
}
- NETLIB_RESETI();
-
protected:
- //NETLIB_UPDATEI();
+ NETLIB_UPDATEI();
+ NETLIB_RESETI();
NETLIB_UPDATE_PARAMI();
};
@@ -175,28 +180,29 @@ namespace netlist {
public:
NETLIB_CONSTRUCTOR_DERIVED(VCVS, VCCS)
, m_RO(*this, "RO", 1.0)
- , m_OP2(*this, "_OP2", &m_ON2)
- , m_ON2(*this, "_ON2", &m_OP2)
+ , m_OP2(*this, "_OP2")
+ , m_ON2(*this, "_ON2")
{
+ m_OP2.m_otherterm = &m_ON2;
+ m_ON2.m_otherterm = &m_OP2;
+
connect(m_OP2, m_OP1);
connect(m_ON2, m_ON1);
}
- NETLIB_RESETI();
-
param_double_t m_RO;
- private:
+ protected:
//NETLIB_UPDATEI();
+ NETLIB_RESETI();
//NETLIB_UPDATE_PARAMI();
terminal_t m_OP2;
terminal_t m_ON2;
-
};
- } // namespace analog
-} // namespace netlist
+ }
+}
#endif /* NLD_FOURTERM_H_ */
diff --git a/src/lib/netlist/analog/nlid_twoterm.cpp b/src/lib/netlist/analog/nlid_twoterm.cpp
index 5019c98c0e4..f54c2b3e68f 100644
--- a/src/lib/netlist/analog/nlid_twoterm.cpp
+++ b/src/lib/netlist/analog/nlid_twoterm.cpp
@@ -5,10 +5,10 @@
*
*/
-#include "netlist/solver/nld_solver.h"
+#include "../solver/nld_solver.h"
-#include "netlist/nl_factory.h"
#include "nlid_twoterm.h"
+#include "../nl_factory.h"
#include <cmath>
@@ -16,34 +16,81 @@ namespace netlist
{
namespace analog
{
-
// ----------------------------------------------------------------------------------------
-// nld_twoterm
+// generic_diode
// ----------------------------------------------------------------------------------------
-void NETLIB_NAME(twoterm)::solve_now()
+generic_diode::generic_diode(device_t &dev, pstring name)
+ : m_Vd(dev, name + ".m_Vd", 0.7)
+ , m_Id(dev, name + ".m_Id", 0.0)
+ , m_G(dev, name + ".m_G", 1e-15)
+ , m_Vt(0.0)
+ , m_Vmin(0.0)
+ , m_Is(0.0)
+ , m_logIs(0.0)
+ , m_n(0.0)
+ , m_gmin(1e-15)
+ , m_VtInv(0.0)
+ , m_Vcrit(0.0)
{
- /* we only need to call the non-rail terminal */
- if (m_P.has_net() && !m_P.net().isRailNet())
- m_P.solve_now();
- else if (m_N.has_net() && !m_N.net().isRailNet())
- m_N.solve_now();
+ set_param(1e-15, 1, 1e-15);
}
-void NETLIB_NAME(twoterm)::solve_later(netlist_time delay)
+void generic_diode::set_param(const nl_double Is, const nl_double n, nl_double gmin)
{
- /* we only need to call the non-rail terminal */
- if (m_P.has_net() && !m_P.net().isRailNet())
- m_P.schedule_solve_after(delay);
- else if (m_N.has_net() && !m_N.net().isRailNet())
- m_N.schedule_solve_after(delay);
+ static constexpr double csqrt2 = 1.414213562373095048801688724209; //std::sqrt(2.0);
+ m_Is = Is;
+ m_logIs = std::log(Is);
+ m_n = n;
+ m_gmin = gmin;
+
+ m_Vt = 0.0258 * m_n;
+ m_Vmin = -5.0 * m_Vt;
+
+ m_Vcrit = m_Vt * std::log(m_Vt / m_Is / csqrt2);
+ m_VtInv = 1.0 / m_Vt;
+}
+
+void generic_diode::update_diode(const nl_double nVd)
+{
+ if (nVd < m_Vmin)
+ {
+ m_Vd = nVd;
+ m_G = m_gmin;
+ m_Id = - m_Is;
+ }
+ else if (nVd < m_Vcrit)
+ {
+ m_Vd = nVd;
+ //m_Vd = m_Vd + 10.0 * m_Vt * std::tanh((nVd - m_Vd) / 10.0 / m_Vt);
+ //const double IseVDVt = m_Is * std::exp(m_Vd * m_VtInv);
+ const double IseVDVt = std::exp(m_logIs + m_Vd * m_VtInv);
+ m_Id = IseVDVt - m_Is;
+ m_G = IseVDVt * m_VtInv + m_gmin;
+ }
+ else
+ {
+ const double a = std::max((nVd - m_Vd) * m_VtInv, NL_FCONST(-0.99));
+ m_Vd = m_Vd + std::log1p(a) * m_Vt;
+ //const double IseVDVt = m_Is * std::exp(m_Vd * m_VtInv);
+ const double IseVDVt = std::exp(m_logIs + m_Vd * m_VtInv);
+ m_Id = IseVDVt - m_Is;
+ m_G = IseVDVt * m_VtInv + m_gmin;
+ }
}
+// ----------------------------------------------------------------------------------------
+// nld_twoterm
+// ----------------------------------------------------------------------------------------
NETLIB_UPDATE(twoterm)
{
/* only called if connected to a rail net ==> notify the solver to recalculate */
- solve_now();
+ /* we only need to call the non-rail terminal */
+ if (m_P.has_net() && !m_P.net().isRailNet())
+ m_P.solve_now();
+ else if (m_N.has_net() && !m_N.net().isRailNet())
+ m_N.solve_now();
}
// ----------------------------------------------------------------------------------------
@@ -53,7 +100,12 @@ NETLIB_UPDATE(twoterm)
NETLIB_RESET(R_base)
{
NETLIB_NAME(twoterm)::reset();
- set_R(1.0 / exec().gmin());
+ set_R(1.0 / netlist().gmin());
+}
+
+NETLIB_UPDATE(R_base)
+{
+ NETLIB_NAME(twoterm)::update();
}
// ----------------------------------------------------------------------------------------
@@ -62,14 +114,14 @@ NETLIB_RESET(R_base)
NETLIB_UPDATE_PARAM(R)
{
- solve_now();
- set_R(std::max(m_R(), exec().gmin()));
+ update_dev();
+ set_R(std::max(m_R(), netlist().gmin()));
}
NETLIB_RESET(R)
{
NETLIB_NAME(twoterm)::reset();
- set_R(std::max(m_R(), exec().gmin()));
+ set_R(std::max(m_R(), netlist().gmin()));
}
// ----------------------------------------------------------------------------------------
@@ -82,22 +134,21 @@ NETLIB_RESET(POT)
if (m_DialIsLog())
v = (std::exp(v) - 1.0) / (std::exp(1.0) - 1.0);
- m_R1.set_R(std::max(m_R() * v, exec().gmin()));
- m_R2.set_R(std::max(m_R() * (plib::constants<nl_double>::one() - v), exec().gmin()));
+ m_R1.set_R(std::max(m_R() * v, netlist().gmin()));
+ m_R2.set_R(std::max(m_R() * (NL_FCONST(1.0) - v), netlist().gmin()));
}
NETLIB_UPDATE_PARAM(POT)
{
- m_R1.solve_now();
- m_R2.solve_now();
+ m_R1.update_dev();
+ m_R2.update_dev();
nl_double v = m_Dial();
if (m_DialIsLog())
v = (std::exp(v) - 1.0) / (std::exp(1.0) - 1.0);
- if (m_Reverse())
- v = 1.0 - v;
- m_R1.set_R(std::max(m_R() * v, exec().gmin()));
- m_R2.set_R(std::max(m_R() * (plib::constants<nl_double>::one() - v), exec().gmin()));
+
+ m_R1.set_R(std::max(m_R() * v, netlist().gmin()));
+ m_R2.set_R(std::max(m_R() * (NL_FCONST(1.0) - v), netlist().gmin()));
}
@@ -113,13 +164,13 @@ NETLIB_RESET(POT2)
v = (std::exp(v) - 1.0) / (std::exp(1.0) - 1.0);
if (m_Reverse())
v = 1.0 - v;
- m_R1.set_R(std::max(m_R() * v, exec().gmin()));
+ m_R1.set_R(std::max(m_R() * v, netlist().gmin()));
}
NETLIB_UPDATE_PARAM(POT2)
{
- m_R1.solve_now();
+ m_R1.update_dev();
nl_double v = m_Dial();
@@ -127,7 +178,38 @@ NETLIB_UPDATE_PARAM(POT2)
v = (std::exp(v) - 1.0) / (std::exp(1.0) - 1.0);
if (m_Reverse())
v = 1.0 - v;
- m_R1.set_R(std::max(m_R() * v, exec().gmin()));
+ m_R1.set_R(std::max(m_R() * v, netlist().gmin()));
+}
+
+// ----------------------------------------------------------------------------------------
+// nld_C
+// ----------------------------------------------------------------------------------------
+
+NETLIB_RESET(C)
+{
+ // FIXME: Startup conditions
+ set(netlist().gmin(), 0.0, -5.0 / netlist().gmin());
+ //set(netlist().gmin(), 0.0, 0.0);
+}
+
+NETLIB_UPDATE_PARAM(C)
+{
+ m_GParallel = netlist().gmin();
+}
+
+NETLIB_UPDATE(C)
+{
+ NETLIB_NAME(twoterm)::update();
+}
+
+NETLIB_TIMESTEP(C)
+{
+ /* Gpar should support convergence */
+ const nl_double G = m_C() / step + m_GParallel;
+ const nl_double I = -G * deltaV();
+ set_mat( G, -G, -I,
+ -G, G, I);
+ //set(G, 0.0, I);
}
// ----------------------------------------------------------------------------------------
@@ -136,9 +218,9 @@ NETLIB_UPDATE_PARAM(POT2)
NETLIB_RESET(L)
{
- m_gmin = exec().gmin();
+ m_GParallel = netlist().gmin();
m_I = 0.0;
- m_G = m_gmin;
+ m_G = m_GParallel;
set_mat( m_G, -m_G, -m_I,
-m_G, m_G, m_I);
//set(1.0/NETLIST_GMIN, 0.0, -5.0 * NETLIST_GMIN);
@@ -148,11 +230,16 @@ NETLIB_UPDATE_PARAM(L)
{
}
+NETLIB_UPDATE(L)
+{
+ NETLIB_NAME(twoterm)::update();
+}
+
NETLIB_TIMESTEP(L)
{
/* Gpar should support convergence */
m_I += m_I + m_G * deltaV();
- m_G = step / m_L() + m_gmin;
+ m_G = step / m_L() + m_GParallel;
set_mat( m_G, -m_G, -m_I,
-m_G, m_G, m_I);
//set(m_G, 0.0, m_I);
@@ -167,8 +254,8 @@ NETLIB_RESET(D)
nl_double Is = m_model.m_IS;
nl_double n = m_model.m_N;
- m_D.set_param(Is, n, exec().gmin(), constants::T0());
- set_G_V_I(m_D.G(), 0.0, m_D.Ieq());
+ m_D.set_param(Is, n, netlist().gmin());
+ set(m_D.G(), 0.0, m_D.Ieq());
}
NETLIB_UPDATE_PARAM(D)
@@ -176,7 +263,12 @@ NETLIB_UPDATE_PARAM(D)
nl_double Is = m_model.m_IS;
nl_double n = m_model.m_N;
- m_D.set_param(Is, n, exec().gmin(), constants::T0());
+ m_D.set_param(Is, n, netlist().gmin());
+}
+
+NETLIB_UPDATE(D)
+{
+ NETLIB_NAME(twoterm)::update();
}
NETLIB_UPDATE_TERMINALS(D)
@@ -189,18 +281,65 @@ NETLIB_UPDATE_TERMINALS(D)
//set(m_D.G(), 0.0, m_D.Ieq());
}
+// ----------------------------------------------------------------------------------------
+// nld_VS
+// ----------------------------------------------------------------------------------------
+
+NETLIB_RESET(VS)
+{
+ NETLIB_NAME(twoterm)::reset();
+ this->set(1.0 / m_R(), m_V(), 0.0);
+}
+
+NETLIB_UPDATE(VS)
+{
+ NETLIB_NAME(twoterm)::update();
+}
+
+NETLIB_TIMESTEP(VS)
+{
+ this->set(1.0 / m_R(),
+ m_compiled.evaluate(std::vector<double>({netlist().time().as_double()})),
+ 0.0);
+}
+
+// ----------------------------------------------------------------------------------------
+// nld_CS
+// ----------------------------------------------------------------------------------------
+
+NETLIB_RESET(CS)
+{
+ NETLIB_NAME(twoterm)::reset();
+ const nl_double I = m_I();
+
+ set_mat(0.0, 0.0, -I,
+ 0.0, 0.0, I);
+ //this->set(0.0, 0.0, m_I());
+}
+
+NETLIB_UPDATE(CS)
+{
+ NETLIB_NAME(twoterm)::update();
+}
+
+NETLIB_TIMESTEP(CS)
+{
+ const double I = m_compiled.evaluate(std::vector<double>({netlist().time().as_double()}));
+ set_mat(0.0, 0.0, -I,
+ 0.0, 0.0, I);
+}
} //namespace analog
namespace devices {
- NETLIB_DEVICE_IMPL_NS(analog, R, "RES", "R")
- NETLIB_DEVICE_IMPL_NS(analog, POT, "POT", "R")
- NETLIB_DEVICE_IMPL_NS(analog, POT2, "POT2", "R")
- NETLIB_DEVICE_IMPL_NS(analog, C, "CAP", "C")
- NETLIB_DEVICE_IMPL_NS(analog, L, "IND", "L")
- NETLIB_DEVICE_IMPL_NS(analog, D, "DIODE", "MODEL")
- NETLIB_DEVICE_IMPL_NS(analog, VS, "VS", "V")
- NETLIB_DEVICE_IMPL_NS(analog, CS, "CS", "I")
- } // namespace devices
+ NETLIB_DEVICE_IMPL_NS(analog, R)
+ NETLIB_DEVICE_IMPL_NS(analog, POT)
+ NETLIB_DEVICE_IMPL_NS(analog, POT2)
+ NETLIB_DEVICE_IMPL_NS(analog, C)
+ NETLIB_DEVICE_IMPL_NS(analog, L)
+ NETLIB_DEVICE_IMPL_NS(analog, D)
+ NETLIB_DEVICE_IMPL_NS(analog, VS)
+ NETLIB_DEVICE_IMPL_NS(analog, CS)
+ }
} // namespace netlist
diff --git a/src/lib/netlist/analog/nlid_twoterm.h b/src/lib/netlist/analog/nlid_twoterm.h
index 470fb35c96e..7778f5f4585 100644
--- a/src/lib/netlist/analog/nlid_twoterm.h
+++ b/src/lib/netlist/analog/nlid_twoterm.h
@@ -33,12 +33,8 @@
#ifndef NLID_TWOTERM_H_
#define NLID_TWOTERM_H_
-#include "netlist/nl_base.h"
-#include "netlist/nl_setup.h"
-#include "netlist/solver/nld_solver.h"
-#include "plib/pfunction.h"
-
-#include <cmath>
+#include "../nl_base.h"
+#include "../plib/pfunction.h"
// -----------------------------------------------------------------------------
// Implementation
@@ -52,27 +48,14 @@ namespace netlist
// nld_twoterm
// -----------------------------------------------------------------------------
- template <class C>
- inline core_device_t &bselect(bool b, C &d1, core_device_t &d2)
- {
- auto *h = dynamic_cast<core_device_t *>(&d1);
- return b ? *h : d2;
- }
- template<>
- inline core_device_t &bselect(bool b, netlist_state_t &d1, core_device_t &d2)
- {
- plib::unused_var(d1);
- if (b)
- throw nl_exception("bselect with netlist and b==true");
- return d2;
- }
-
NETLIB_OBJECT(twoterm)
{
NETLIB_CONSTRUCTOR_EX(twoterm, bool terminals_owned = false)
- , m_P(bselect(terminals_owned, owner, *this), (terminals_owned ? name + "." : "") + "1", &m_N)
- , m_N(bselect(terminals_owned, owner, *this), (terminals_owned ? name + "." : "") + "2", &m_P)
+ , m_P(bselect(terminals_owned, owner, *this), (terminals_owned ? name + "." : "") + "1")
+ , m_N(bselect(terminals_owned, owner, *this), (terminals_owned ? name + "." : "") + "2")
{
+ m_P.m_otherterm = &m_N;
+ m_N.m_otherterm = &m_P;
}
terminal_t m_P;
@@ -80,36 +63,36 @@ NETLIB_OBJECT(twoterm)
//NETLIB_UPDATE_TERMINALSI() { }
//NETLIB_RESETI() { }
-
-public:
-
NETLIB_UPDATEI();
- void solve_now();
-
- void solve_later(netlist_time delay = netlist_time::from_nsec(1));
-
- void set_G_V_I(const nl_double G, const nl_double V, const nl_double I)
+public:
+ /* inline */ void set(const nl_double G, const nl_double V, const nl_double I)
{
/* GO, GT, I */
- m_P.set_go_gt_I( -G, G, ( V) * G - I);
- m_N.set_go_gt_I( -G, G, ( -V) * G + I);
+ m_P.set( G, G, ( V) * G - I);
+ m_N.set( G, G, ( -V) * G + I);
}
- nl_double deltaV() const
+ /* inline */ nl_double deltaV() const
{
return m_P.net().Q_Analog() - m_N.net().Q_Analog();
}
- void set_mat(const nl_double a11, const nl_double a12, const nl_double rhs1,
- const nl_double a21, const nl_double a22, const nl_double rhs2)
+ void set_mat(const nl_double a11, const nl_double a12, const nl_double r1,
+ const nl_double a21, const nl_double a22, const nl_double r2)
{
/* GO, GT, I */
- m_P.set_go_gt_I(a12, a11, rhs1);
- m_N.set_go_gt_I(a21, a22, rhs2);
+ m_P.set(-a12, a11, r1);
+ m_N.set(-a21, a22, r2);
}
private:
+ template <class C>
+ static core_device_t &bselect(bool b, C &d1, core_device_t &d2)
+ {
+ core_device_t *h = dynamic_cast<core_device_t *>(&d1);
+ return b ? *h : d2;
+ }
};
@@ -123,17 +106,17 @@ NETLIB_OBJECT_DERIVED(R_base, twoterm)
{
}
- void set_R(const nl_double R)
+public:
+ inline void set_R(const nl_double R)
{
- const nl_double G = plib::constants<nl_double>::one() / R;
+ const nl_double G = NL_FCONST(1.0) / R;
set_mat( G, -G, 0.0,
-G, G, 0.0);
}
- NETLIB_RESETI();
-
protected:
- //NETLIB_UPDATEI();
+ NETLIB_RESETI();
+ NETLIB_UPDATEI();
};
@@ -144,6 +127,7 @@ NETLIB_OBJECT_DERIVED(R, R_base)
{
}
+ param_double_t m_R;
protected:
@@ -152,7 +136,6 @@ protected:
NETLIB_UPDATE_PARAMI();
private:
- param_double_t m_R;
/* protect set_R ... it's a recipe to desaster when used to bypass the parameter */
using NETLIB_NAME(R_base)::set_R;
};
@@ -168,8 +151,7 @@ NETLIB_OBJECT(POT)
, m_R2(*this, "_R2")
, m_R(*this, "R", 10000)
, m_Dial(*this, "DIAL", 0.5)
- , m_DialIsLog(*this, "DIALLOG", false)
- , m_Reverse(*this, "REVERSE", false)
+ , m_DialIsLog(*this, "DIALLOG", 0)
{
register_subalias("1", m_R1.m_P);
register_subalias("2", m_R1.m_N);
@@ -190,7 +172,6 @@ private:
param_double_t m_R;
param_double_t m_Dial;
param_logic_t m_DialIsLog;
- param_logic_t m_Reverse;
};
NETLIB_OBJECT(POT2)
@@ -199,8 +180,8 @@ NETLIB_OBJECT(POT2)
, m_R1(*this, "_R1")
, m_R(*this, "R", 10000)
, m_Dial(*this, "DIAL", 0.5)
- , m_DialIsLog(*this, "DIALLOG", false)
- , m_Reverse(*this, "REVERSE", false)
+ , m_DialIsLog(*this, "DIALLOG", 0)
+ , m_Reverse(*this, "REVERSE", 0)
{
register_subalias("1", m_R1.m_P);
register_subalias("2", m_R1.m_N);
@@ -220,83 +201,6 @@ private:
param_logic_t m_Reverse;
};
-// -----------------------------------------------------------------------------
-// A generic capacitor model
-// -----------------------------------------------------------------------------
-
-enum class capacitor_e
-{
- CHARGE_CONSERVING,
- CONSTANT_CAPACITY
-};
-
-template <capacitor_e TYPE>
-class generic_capacitor
-{
-};
-
-
-template <>
-class generic_capacitor<capacitor_e::CHARGE_CONSERVING>
-{
-public:
- generic_capacitor(device_t &dev, const pstring &name)
- : m_h(dev, name + ".m_h", 0.0)
- , m_charge(dev, name + ".m_charge", 0.0)
- , m_gmin(0.0)
- {
- }
-
- constexpr capacitor_e type() const { return capacitor_e::CHARGE_CONSERVING; }
-
- constexpr nl_double G(nl_double cap) const
- {
- return cap * m_h + m_gmin;
- }
-
- constexpr nl_double Ieq(nl_double cap, nl_double v) const
- {
- return m_h * (cap * v - m_charge) - G(cap) * v;
- }
-
- void timestep(nl_double cap, nl_double v, nl_double step)
- {
- m_h = 1.0 / step;
- m_charge = cap * v;
- }
-
- void setparams(nl_double gmin) { m_gmin = gmin; }
-
-private:
- state_var<double> m_h;
- state_var<double> m_charge;
- nl_double m_gmin;
-};
-
-template <>
-class generic_capacitor<capacitor_e::CONSTANT_CAPACITY>
-{
-public:
- generic_capacitor(device_t &dev, const pstring &name)
- : m_h(dev, name + ".m_h", 0.0)
- , m_gmin(0.0)
- {
- }
-
- constexpr capacitor_e type() const { return capacitor_e::CONSTANT_CAPACITY; }
- constexpr nl_double G(nl_double cap) const { return cap * m_h + m_gmin; }
- constexpr nl_double Ieq(nl_double cap, nl_double v) const { return - G(cap) * v; }
-
- void timestep(nl_double cap, nl_double v, nl_double step)
- {
- plib::unused_var(cap, v);
- m_h = 1.0 / step;
- }
- void setparams(nl_double gmin) { m_gmin = gmin; }
-private:
- state_var<nl_double> m_h;
- nl_double m_gmin;
-};
// -----------------------------------------------------------------------------
// nld_C
@@ -307,45 +211,25 @@ NETLIB_OBJECT_DERIVED(C, twoterm)
public:
NETLIB_CONSTRUCTOR_DERIVED(C, twoterm)
, m_C(*this, "C", 1e-6)
- , m_cap(*this, "m_cap")
+ , m_GParallel(0.0)
{
+ //register_term("1", m_P);
+ //register_term("2", m_N);
}
NETLIB_IS_TIMESTEP(true)
- NETLIB_TIMESTEPI()
- {
- m_cap.timestep(m_C(), deltaV(), step);
- if (m_cap.type() == capacitor_e::CONSTANT_CAPACITY)
- {
- const nl_double I = m_cap.Ieq(m_C(), deltaV());
- const nl_double G = m_cap.G(m_C());
- set_mat( G, -G, -I,
- -G, G, I);
- }
- }
-
- NETLIB_IS_DYNAMIC(m_cap.type() == capacitor_e::CHARGE_CONSERVING)
- NETLIB_UPDATE_TERMINALSI()
- {
- const nl_double I = m_cap.Ieq(m_C(), deltaV());
- const nl_double G = m_cap.G(m_C());
- set_mat( G, -G, -I,
- -G, G, I);
- }
+ NETLIB_TIMESTEPI();
param_double_t m_C;
- NETLIB_RESETI()
- {
- m_cap.setparams(exec().gmin());
- }
protected:
- //NETLIB_UPDATEI();
- NETLIB_UPDATE_PARAMI() { }
+ NETLIB_RESETI();
+ NETLIB_UPDATEI();
+ NETLIB_UPDATE_PARAMI();
private:
- generic_capacitor<capacitor_e::CHARGE_CONSERVING> m_cap;
- //generic_capacitor<capacitor_e::CONSTANT_CAPACITY> m_cap;
+ nl_double m_GParallel;
+
};
// -----------------------------------------------------------------------------
@@ -357,7 +241,7 @@ NETLIB_OBJECT_DERIVED(L, twoterm)
public:
NETLIB_CONSTRUCTOR_DERIVED(L, twoterm)
, m_L(*this, "L", 1e-6)
- , m_gmin(0.0)
+ , m_GParallel(0.0)
, m_G(0.0)
, m_I(0.0)
{
@@ -367,16 +251,16 @@ public:
NETLIB_IS_TIMESTEP(true)
NETLIB_TIMESTEPI();
- NETLIB_RESETI();
+
+ param_double_t m_L;
protected:
- //NETLIB_UPDATEI();
+ NETLIB_RESETI();
+ NETLIB_UPDATEI();
NETLIB_UPDATE_PARAMI();
private:
- param_double_t m_L;
-
- nl_double m_gmin;
+ nl_double m_GParallel;
nl_double m_G;
nl_double m_I;
};
@@ -385,82 +269,14 @@ private:
// A generic diode model to be used in other devices (Diode, BJT ...)
// -----------------------------------------------------------------------------
-enum class diode_e
-{
- BIPOLAR,
- MOS
-};
-
-template <diode_e TYPE>
class generic_diode
{
public:
- generic_diode(device_t &dev, const pstring &name)
- : m_Vd(dev, name + ".m_Vd", 0.7)
- , m_Id(dev, name + ".m_Id", 0.0)
- , m_G(dev, name + ".m_G", 1e-15)
- , m_Vt(0.0)
- , m_Vmin(0.0) // not used in MOS model
- , m_Is(0.0)
- , m_logIs(0.0)
- , m_n(0.0)
- , m_gmin(1e-15)
- , m_VtInv(0.0)
- , m_Vcrit(0.0)
- {
- set_param(1e-15, 1, 1e-15, 300.0);
- }
-
- void update_diode(const double nVd)
- {
- if (TYPE == diode_e::BIPOLAR && nVd < m_Vmin)
- {
- m_Vd = nVd;
- m_G = m_gmin;
- m_Id = - m_Is;
- }
- else if (TYPE == diode_e::MOS && nVd < constants::zero())
- {
- m_Vd = nVd;
- m_G = m_Is * m_VtInv + m_gmin;
- m_Id = m_G * m_Vd;
- }
- // FIXME: For MOS, stop here, the critical code path will not converge
- else if (TYPE == diode_e::MOS || nVd < m_Vcrit)
- {
- m_Vd = nVd;
- const double IseVDVt = std::exp(std::min(700.0, m_logIs + m_Vd * m_VtInv));
- m_Id = IseVDVt - m_Is;
- m_G = IseVDVt * m_VtInv + m_gmin;
- }
- else
- {
- const double a = std::max((nVd - m_Vd) * m_VtInv, constants::cast(-0.99));
- m_Vd = m_Vd + std::log1p(a) * m_Vt;
- //const double IseVDVt = m_Is * std::exp(m_Vd * m_VtInv);
- const double IseVDVt = std::exp(m_logIs + m_Vd * m_VtInv);
- m_Id = IseVDVt - m_Is;
- m_G = IseVDVt * m_VtInv + m_gmin;
- }
- }
-
-
- void set_param(const double Is, const double n, double gmin, double temp)
- {
- static constexpr double csqrt2 = 1.414213562373095048801688724209; //std::sqrt(2.0);
- m_Is = Is;
- m_logIs = std::log(Is);
- m_n = n;
- m_gmin = gmin;
+ generic_diode(device_t &dev, pstring name);
- m_Vt = m_n * temp * constants::k_b() / constants::Q_e();
-
- m_Vmin = -5.0 * m_Vt;
-
- m_Vcrit = m_Vt * std::log(m_Vt / m_Is / csqrt2);
- m_VtInv = 1.0 / m_Vt;
- }
+ void update_diode(const double nVd);
+ void set_param(const double Is, const double n, double gmin);
double I() const { return m_Id; }
double G() const { return m_G; }
@@ -551,15 +367,15 @@ public:
NETLIB_IS_DYNAMIC(true)
NETLIB_UPDATE_TERMINALSI();
- NETLIB_RESETI();
+
+ diode_model_t m_model;
protected:
- //NETLIB_UPDATEI();
+ NETLIB_RESETI();
+ NETLIB_UPDATEI();
NETLIB_UPDATE_PARAMI();
-private:
- diode_model_t m_model;
- generic_diode<diode_e::BIPOLAR> m_D;
+ generic_diode m_D;
};
@@ -573,11 +389,10 @@ NETLIB_OBJECT_DERIVED(VS, twoterm)
{
public:
NETLIB_CONSTRUCTOR_DERIVED(VS, twoterm)
- , m_t(*this, "m_t", 0.0)
, m_R(*this, "R", 0.1)
, m_V(*this, "V", 0.0)
, m_func(*this,"FUNC", "")
- , m_compiled(this->name() + ".FUNCC", this, this->state().run_state_manager())
+ , m_compiled(this->name() + ".FUNCC", this, this->netlist().state())
{
register_subalias("P", m_P);
register_subalias("N", m_N);
@@ -586,26 +401,12 @@ public:
}
NETLIB_IS_TIMESTEP(m_func() != "")
-
- NETLIB_TIMESTEPI()
- {
- m_t += step;
- this->set_G_V_I(1.0 / m_R(),
- m_compiled.evaluate(std::vector<double>({m_t})),
- 0.0);
- }
+ NETLIB_TIMESTEPI();
protected:
- // NETLIB_UPDATEI() { NETLIB_NAME(twoterm)::update(time); }
-
- NETLIB_RESETI()
- {
- NETLIB_NAME(twoterm)::reset();
- this->set_G_V_I(1.0 / m_R(), m_V(), 0.0);
- }
+ NETLIB_UPDATEI();
+ NETLIB_RESETI();
-private:
- state_var<double> m_t;
param_double_t m_R;
param_double_t m_V;
param_str_t m_func;
@@ -620,10 +421,9 @@ NETLIB_OBJECT_DERIVED(CS, twoterm)
{
public:
NETLIB_CONSTRUCTOR_DERIVED(CS, twoterm)
- , m_t(*this, "m_t", 0.0)
, m_I(*this, "I", 1.0)
, m_func(*this,"FUNC", "")
- , m_compiled(this->name() + ".FUNCC", this, this->state().run_state_manager())
+ , m_compiled(this->name() + ".FUNCC", this, this->netlist().state())
{
register_subalias("P", m_P);
register_subalias("N", m_N);
@@ -632,33 +432,19 @@ public:
}
NETLIB_IS_TIMESTEP(m_func() != "")
- NETLIB_TIMESTEPI()
- {
- m_t += step;
- const double I = m_compiled.evaluate(std::vector<double>({m_t}));
- set_mat(0.0, 0.0, -I,
- 0.0, 0.0, I);
- }
-
+ NETLIB_TIMESTEPI();
protected:
- //NETLIB_UPDATEI() { NETLIB_NAME(twoterm)::update(time); }
- NETLIB_RESETI()
- {
- NETLIB_NAME(twoterm)::reset();
- set_mat(0.0, 0.0, -m_I(),
- 0.0, 0.0, m_I());
- }
+ NETLIB_UPDATEI();
+ NETLIB_RESETI();
-private:
- state_var<double> m_t;
param_double_t m_I;
param_str_t m_func;
plib::pfunction m_compiled;
};
- } // namespace analog
+ } //namespace devices
} // namespace netlist
#endif /* NLD_TWOTERM_H_ */
diff --git a/src/lib/netlist/build/makefile b/src/lib/netlist/build/makefile
index 647c7df6f12..807ddbd6c7a 100644
--- a/src/lib/netlist/build/makefile
+++ b/src/lib/netlist/build/makefile
@@ -12,27 +12,6 @@
SRC = ..
VSBUILD = $(SRC)/buildVS
DOC = $(SRC)/documentation
-TIDY_DB = ../compile_commands.json
-
-TIDY_FLAGSX = -checks=*,-google*,-hicpp*,-readability*,-fuchsia*,cert-*,-android-*,
-TIDY_FLAGSX += -llvm-header-guard,-cppcoreguidelines-pro-type-reinterpret-cast,
-TIDY_FLAGSX += -cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-owning-memory,
-TIDY_FLAGSX += -modernize-use-default-member-init,-cppcoreguidelines-pro-bounds-constant-array-index,
-TIDY_FLAGSX += -modernize-pass-by-value,-cppcoreguidelines-pro-type-static-cast-downcast,
-TIDY_FLAGSX += -cppcoreguidelines-avoid-magic-numbers,
-TIDY_FLAGSX += -cppcoreguidelines-macro-usage,
-TIDY_FLAGSX += -cppcoreguidelines-non-private-member-variables-in-classes,-misc-non-private-member-variables-in-classes,
-TIDY_FLAGSX += -bugprone-macro-parentheses,-misc-macro-parentheses
-
-space :=
-space +=
-TIDY_FLAGS = $(subst $(space),,$(TIDY_FLAGSX))
-
-TIDY_FLAGS = -checks=llvm-include-order,llvm-namespace-comment,modernize-use-override,modernize-use-using -fix
-#TIDY_FLAGS = -checks=llvm-include-order -fix
-#TIDY_FLAGS = -checks=llvm-namespace-comment -fix
-#TIDY_FLAGS = -checks=modernize-use-override -fix
-#TIDY_FLAGS = -checks=modernize-use-using -fix
ifeq ($(subst Windows_NT,windows,$(OS)),windows)
OBJ = obj/mingw
@@ -44,7 +23,7 @@ endif
# LTO = -flto=4 -fuse-linker-plugin -flto-partition=balanced -Wodr
-CFLAGS = $(LTO) -g -O3 -std=c++11 -I$(CURDIR)/.. -I$(CURDIR)/../.. $(CEXTRAFLAGS)
+CFLAGS = $(LTO) -g -O3 -std=c++11 -march=native -I../.. -Wall -Wpedantic -Wsign-compare -Wextra -Wno-unused-parameter $(CEXTRAFLAGS)
LDFLAGS = $(LTO) -g -O3 -std=c++11 $(LDEXTRAFLAGS)
LIBS = -lpthread -ldl
@@ -53,7 +32,6 @@ LD = @g++
MD = @mkdir
RM = @rm
DOXYGEN = @doxygen
-CLANG_TIDY = clang-tidy-9
TARGETS = nltool nlwav
@@ -75,6 +53,7 @@ OBJS = $(POBJS) $(NLOBJS)
POBJS := \
$(POBJ)/pstring.o \
+ $(POBJ)/palloc.o \
$(POBJ)/pchrono.o \
$(POBJ)/pdynlib.o \
$(POBJ)/pexception.o \
@@ -94,7 +73,6 @@ NLOBJS := \
$(NLOBJ)/nl_setup.o \
$(NLOBJ)/nl_factory.o \
$(NLOBJ)/analog/nld_bjt.o \
- $(NLOBJ)/analog/nld_mosfet.o \
$(NLOBJ)/analog/nlid_fourterm.o \
$(NLOBJ)/analog/nld_switches.o \
$(NLOBJ)/analog/nlid_twoterm.o \
@@ -114,7 +92,6 @@ NLOBJS := \
$(NLOBJ)/devices/nld_7485.o \
$(NLOBJ)/devices/nld_7490.o \
$(NLOBJ)/devices/nld_7493.o \
- $(NLOBJ)/devices/nld_7497.o \
$(NLOBJ)/devices/nld_74107.o \
$(NLOBJ)/devices/nld_74123.o \
$(NLOBJ)/devices/nld_74153.o \
@@ -176,12 +153,10 @@ DOCS = \
$(DOC)/test1-50r.svg \
ALL_OBJS = $(OBJS) $(PMAIN) $(NLOBJ)/prg/nltool.o $(NLOBJ)/prg/nlwav.o
-
-ALL_TIDY_FILES = $(ALL_OBJS:.o=.json)
SOURCES = $(patsubst $(OBJ)%, $(SRC)%, $(ALL_OBJS:.o=.cpp))
ALLFILES = $(SOURCES) $(VSBUILDS) $(DOCS)
-MAKEFILE_TARGETS_WITHOUT_INCLUDE := clean doc clang mingw nvcc
+MAKEFILE_TARGETS_WITHOUT_INCLUDE := clean doc clang mingw
# git archive HEAD --prefix=project-name-version/ \
@@ -225,33 +200,19 @@ maketree: $(sort $(OBJDIRS))
# Special targets
#-------------------------------------------------
-.PHONY: clang clang-5 mingw doc native
-
-native:
- $(MAKE) CEXTRAFLAGS="-march=native -msse4.2 -Wall -Wpedantic -Wsign-compare -Wextra "
+.PHONY: clang clang-5 mingw doc
clang:
- $(MAKE) CC=clang++-9 LD=clang++-9 CEXTRAFLAGS="-march=native -Weverything -Werror -Wno-padded -Wno-weak-vtables -Wno-unused-template -Wno-missing-variable-declarations -Wno-float-equal -Wconversion -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-format-nonliteral -Wno-exit-time-destructors"
+ $(MAKE) CC=clang++ LD=clang++ CEXTRAFLAGS="-march=native -Weverything -Werror -override -Wno-unreachable-code -Wno-padded -Wno-weak-vtables -Wno-missing-variable-declarations -Wconversion -Wno-c++98-compat -Wno-float-equal -Wno-global-constructors -Wno-c++98-compat-pedantic -Wno-format-nonliteral -Wno-weak-template-vtables -Wno-exit-time-destructors"
clang-5:
$(MAKE) CC=clang++-5.0 LD=clang++-5.0 CEXTRAFLAGS="-march=native -Weverything -Werror -Wno-inconsistent-missing-destructor-override -Wno-unreachable-code -Wno-padded -Wno-weak-vtables -Wno-missing-variable-declarations -Wconversion -Wno-c++98-compat -Wno-float-equal -Wno-global-constructors -Wno-c++98-compat-pedantic -Wno-format-nonliteral -Wno-weak-template-vtables -Wno-exit-time-destructors"
-nvcc:
- $(MAKE) CC=/usr/local/cuda-9.0/bin/nvcc LD=/usr/local/cuda-9.2/bin/nvcc \
- CEXTRAFLAGS="-x cu -DNVCCBUILD=1 --expt-extended-lambda --expt-relaxed-constexpr --default-stream per-thread --restrict"
-
-tidy_db: compile_commands_prefix $(ALL_TIDY_FILES) compile_commands_postfix
-
#
-# -Wno-c++11-narrowing : seems a bit broken
# Mostly done: -Wno-weak-vtables -Wno-cast-align
# FIXME: -Wno-weak-vtables -Wno-missing-variable-declarations -Wno-conversion -Wno-exit-time-destructors
# FIXME: -Winconsistent-missing-destructor-override : c++ community has diverging opinions on this https://github.com/isocpp/CppCoreGuidelines/issues/721
# FIXME: -Wunreachable-code : False warnings, this a documented clang bug: https://llvm.org/bugs/show_bug.cgi?id=28994
-# -Wweak-template-vtables
-#
-# These have to be given:
-# -Wno-missing-variable-declarations : Device factory code, on purpose
mingw:
$(MAKE) CEXTRAFLAGS="-DUNICODE -D_UNICODE -D_WIN32_WINNT=0x0501 -DWIN32_LEAN_AND_MEAN" \
@@ -276,7 +237,7 @@ doc: nltool
@echo creating .depend
@rm -f ./.depend
@for i in $(SOURCES); do \
- $(CC) $(CFLAGS) -MM $$i -MT `echo $$i | sed -e 's+$(SRC)+$(OBJ)+' -e 's+.cpp+.o+' ` >> ./.depend; \
+ $(CC) $(CFLAGS) -MM $$i -MT `echo $$i | sed -e 's+$(SRC)+$(OBJ)+' -e 's+.cpp+.o+' ` >>./.depend; \
done
depend: .depend
@@ -287,18 +248,6 @@ ifeq ($(filter $(MAKECMDGOALS),$(MAKEFILE_TARGETS_WITHOUT_INCLUDE)),)
endif
#-------------------------------------------------
-# clang tidy
-#-------------------------------------------------
-tidy: tidy_db
- @echo running tidy
- @for i in $(SOURCES); do \
- $(CLANG_TIDY) $$i $(TIDY_FLAGS) -header-filter=.*; \
- done
-
-tidy_db: compile_commands_prefix $(ALL_TIDY_FILES) compile_commands_postfix
-
-
-#-------------------------------------------------
# generic rules
#-------------------------------------------------
@@ -319,15 +268,3 @@ $(OBJ)/%.a:
$(RM) $@
$(AR) $(ARFLAGS) $@ $^
-$(OBJ)/%.json: $(SRC)/%.cpp
- @echo Building compile database entry for $< ...
- @echo { \"directory\": \".\", >> $(TIDY_DB)
- @echo \"command\": \"$(CC) $(CDEFS) $(CFLAGS) -c $< -o dummy.o\", >> $(TIDY_DB)
- @echo \"file\": \"$(CURDIR)/$<\" } >> $(TIDY_DB)
- @echo "," >> $(TIDY_DB)
-
-compile_commands_prefix:
- @echo "[" > $(TIDY_DB)
-
-compile_commands_postfix:
- @echo "]" >> $(TIDY_DB)
diff --git a/src/lib/netlist/devices/net_lib.cpp b/src/lib/netlist/devices/net_lib.cpp
index c0353f2489a..e0f0277daac 100644
--- a/src/lib/netlist/devices/net_lib.cpp
+++ b/src/lib/netlist/devices/net_lib.cpp
@@ -9,159 +9,152 @@
****************************************************************************/
#include "net_lib.h"
-#include "netlist/nl_factory.h"
-#include "netlist/solver/nld_solver.h"
+#include "../nl_factory.h"
+#include "../solver/nld_solver.h"
#define xstr(s) # s
-#define NETLIB_DEVICE_DECL(chip) extern factory::constructor_ptr_t decl_ ## chip
+#define NETLIB_DEVICE_DECL(chip) extern factory::constructor_ptr_t decl_ ## chip;
-#define LIB_DECL(nic, decl) factory.register_device( decl ( pstring(xstr(nic))) );
-#define LIB_ENTRY(nic) { NETLIB_DEVICE_DECL(nic); LIB_DECL(NETLIB_NAME(nic), decl_ ## nic) }
+#define ENTRYX1(nic, name, defparam, decl) factory.register_device( decl (pstring(# name), pstring(xstr(nic)), pstring(defparam)) );
+#define ENTRYX(nic, name, defparam) { NETLIB_DEVICE_DECL(nic) ENTRYX1(NETLIB_NAME(nic), name, defparam, decl_ ## nic) }
namespace netlist
{
-namespace devices
-{
-
- void initialize_factory(factory::list_t &factory)
+ namespace devices
{
- LIB_ENTRY(R)
- LIB_ENTRY(POT)
- LIB_ENTRY(POT2)
- LIB_ENTRY(C)
- LIB_ENTRY(L)
- LIB_ENTRY(D)
- LIB_ENTRY(VS)
- LIB_ENTRY(CS)
- LIB_ENTRY(VCVS)
- LIB_ENTRY(VCCS)
- LIB_ENTRY(CCCS)
- LIB_ENTRY(LVCCS)
- LIB_ENTRY(opamp)
- LIB_ENTRY(dummy_input)
- LIB_ENTRY(frontier) // not intended to be used directly
- LIB_ENTRY(function) // only for macro devices - NO FEEDBACK loops
- LIB_ENTRY(QBJT_EB)
- LIB_ENTRY(QBJT_switch)
- LIB_ENTRY(MOSFET)
- LIB_ENTRY(logic_input_ttl)
- LIB_ENTRY(logic_input)
- LIB_ENTRY(analog_input)
- LIB_ENTRY(log)
- LIB_ENTRY(logD)
- LIB_ENTRY(clock)
- LIB_ENTRY(extclock)
- LIB_ENTRY(mainclock)
- LIB_ENTRY(gnd)
- LIB_ENTRY(netlistparams)
- LIB_ENTRY(solver)
- LIB_ENTRY(res_sw)
- LIB_ENTRY(switch1)
- LIB_ENTRY(switch2)
- LIB_ENTRY(nicRSFF)
- LIB_ENTRY(nicDelay)
- LIB_ENTRY(2102A)
- LIB_ENTRY(2102A_dip)
- LIB_ENTRY(2716)
- LIB_ENTRY(2716_dip)
- LIB_ENTRY(7448)
- LIB_ENTRY(7448_dip)
- LIB_ENTRY(7450)
- LIB_ENTRY(7450_dip)
- LIB_ENTRY(7473)
- LIB_ENTRY(7473_dip)
- LIB_ENTRY(7473A)
- LIB_ENTRY(7473A_dip)
- LIB_ENTRY(7474)
- LIB_ENTRY(7474_dip)
- LIB_ENTRY(7475)
- LIB_ENTRY(7475_dip)
- LIB_ENTRY(7477)
- LIB_ENTRY(7477_dip)
- LIB_ENTRY(7483)
- LIB_ENTRY(7483_dip)
- LIB_ENTRY(7485)
- LIB_ENTRY(7485_dip)
- LIB_ENTRY(7490)
- LIB_ENTRY(7490_dip)
- LIB_ENTRY(7493)
- LIB_ENTRY(7493_dip)
- LIB_ENTRY(7497)
- LIB_ENTRY(7497_dip)
- LIB_ENTRY(74107)
- LIB_ENTRY(74107_dip)
- LIB_ENTRY(74107A) // FIXME: implement missing DIP
- LIB_ENTRY(74123)
- LIB_ENTRY(74123_dip)
- LIB_ENTRY(74153)
- LIB_ENTRY(74153_dip)
- LIB_ENTRY(74161)
- LIB_ENTRY(74161_dip)
- LIB_ENTRY(74164)
- LIB_ENTRY(74164_dip)
- LIB_ENTRY(74165)
- LIB_ENTRY(74165_dip)
- LIB_ENTRY(74166)
- LIB_ENTRY(74166_dip)
- LIB_ENTRY(74174)
- LIB_ENTRY(74175)
- LIB_ENTRY(74192)
- LIB_ENTRY(74193)
- LIB_ENTRY(74194)
- LIB_ENTRY(74365)
- //ENTRY(74279, TTL_74279, "") // only dip available
- LIB_ENTRY(SN74LS629)
- LIB_ENTRY(82S16)
- LIB_ENTRY(82S115)
- LIB_ENTRY(82S123)
- LIB_ENTRY(82S126)
- LIB_ENTRY(9310)
- LIB_ENTRY(9314)
- LIB_ENTRY(9316)
- LIB_ENTRY(9322)
- LIB_ENTRY(9334)
- LIB_ENTRY(AM2847)
- // FIXME: duplicate?
- LIB_ENTRY(CD4020_WI)
- LIB_ENTRY(CD4020)
- LIB_ENTRY(CD4066_GATE)
- LIB_ENTRY(CD4316_GATE)
- LIB_ENTRY(4538_dip)
- LIB_ENTRY(schmitt_trigger)
- /* entries with suffix WI are legacy only */
- //ENTRY(4066, CD_4066, "+A,B")
- LIB_ENTRY(NE555)
- LIB_ENTRY(NE555_dip)
- LIB_ENTRY(MC1455P)
- LIB_ENTRY(MC1455P_dip)
- LIB_ENTRY(TMS4800)
- LIB_ENTRY(TMS4800_dip)
- LIB_ENTRY(r2r_dac)
- LIB_ENTRY(tristate)
- LIB_ENTRY(tristate3)
- LIB_ENTRY(74174_dip)
- LIB_ENTRY(74175_dip)
- LIB_ENTRY(74192_dip)
- LIB_ENTRY(74193_dip)
- LIB_ENTRY(74194_dip)
- LIB_ENTRY(74365_dip)
- LIB_ENTRY(82S16_dip)
- LIB_ENTRY(82S115_dip)
- LIB_ENTRY(82S123_dip)
- LIB_ENTRY(82S126_dip)
- LIB_ENTRY(9602_dip)
- LIB_ENTRY(9310_dip)
- LIB_ENTRY(9314_dip)
- LIB_ENTRY(9316_dip)
- LIB_ENTRY(9322_dip)
- LIB_ENTRY(9334_dip)
- LIB_ENTRY(AM2847_dip)
- LIB_ENTRY(SN74LS629_dip)
- LIB_ENTRY(MM5837_dip)
- }
+ void initialize_factory(factory::list_t &factory)
+{
+ ENTRYX(R, RES, "R")
+ ENTRYX(POT, POT, "R")
+ ENTRYX(POT2, POT2, "R")
+ ENTRYX(C, CAP, "C")
+ ENTRYX(L, IND, "L")
+ ENTRYX(D, DIODE, "MODEL")
+ ENTRYX(VS, VS, "V")
+ ENTRYX(CS, CS, "I")
+ ENTRYX(VCVS, VCVS, "")
+ ENTRYX(VCCS, VCCS, "")
+ ENTRYX(CCCS, CCCS, "")
+ ENTRYX(LVCCS, LVCCS, "")
+ ENTRYX(opamp, OPAMP, "MODEL")
+ ENTRYX(dummy_input, DUMMY_INPUT, "")
+ ENTRYX(frontier, FRONTIER_DEV, "+I,+G,+Q") // not intended to be used directly
+ ENTRYX(function, AFUNC, "N,FUNC") // only for macro devices - NO FEEDBACK loops
+ ENTRYX(QBJT_EB, QBJT_EB, "MODEL")
+ ENTRYX(QBJT_switch, QBJT_SW, "MODEL")
+ ENTRYX(logic_input, TTL_INPUT, "IN")
+ ENTRYX(logic_input, LOGIC_INPUT, "IN,FAMILY")
+ ENTRYX(analog_input, ANALOG_INPUT, "IN")
+ ENTRYX(log, LOG, "+I")
+ ENTRYX(logD, LOGD, "+I,+I2")
+ ENTRYX(clock, CLOCK, "FREQ")
+ ENTRYX(extclock, EXTCLOCK, "FREQ,PATTERN")
+ ENTRYX(mainclock, MAINCLOCK, "FREQ")
+ ENTRYX(gnd, GND, "")
+ ENTRYX(netlistparams, PARAMETER, "")
+ ENTRYX(solver, SOLVER, "FREQ")
+ ENTRYX(res_sw, RES_SWITCH, "+IN,+P1,+P2")
+ ENTRYX(switch1, SWITCH, "")
+ ENTRYX(switch2, SWITCH2, "")
+ ENTRYX(nicRSFF, NETDEV_RSFF, "")
+ ENTRYX(nicDelay, NETDEV_DELAY, "")
+ ENTRYX(2716, EPROM_2716, "+GQ,+EPQ,+A0,+A1,+A2,+A3,+A4,+A5,+A6,+A7,+A8,+A9,+A10")
+ ENTRYX(TMS4800, ROM_TMS4800, "+AR,+OE1,+OE2,+A0,+A1,+A2,+A3,+A4,+A5,+A6,+A7,+A8,+A9,+A10")
+ ENTRYX(2102A, RAM_2102A, "+CEQ,+A0,+A1,+A2,+A3,+A4,+A5,+A6,+A7,+A8,+A9,+RWQ,+DI")
+ ENTRYX(7450, TTL_7450_ANDORINVERT, "+A,+B,+C,+D")
+ ENTRYX(7448, TTL_7448, "+A,+B,+C,+D,+LTQ,+BIQ,+RBIQ")
+ ENTRYX(7473, TTL_7473, "+CLK,+J,+K,+CLRQ")
+ ENTRYX(7473A, TTL_7473A, "+CLK,+J,+K,+CLRQ")
+ ENTRYX(7474, TTL_7474, "+CLK,+D,+CLRQ,+PREQ")
+ ENTRYX(7475, TTL_7475, "")
+ ENTRYX(7477, TTL_7477, "")
+ ENTRYX(7483, TTL_7483, "+A1,+A2,+A3,+A4,+B1,+B2,+B3,+B4,+C0")
+ ENTRYX(7485, TTL_7485, "+A0,+A1,+A2,+A3,+B0,+B1,+B2,+B3,+LTIN,+EQIN,+GTIN")
+ ENTRYX(7490, TTL_7490, "+A,+B,+R1,+R2,+R91,+R92")
+ ENTRYX(7493, TTL_7493, "+CLKA,+CLKB,+R1,+R2")
+ ENTRYX(74107, TTL_74107, "+CLK,+J,+K,+CLRQ")
+ ENTRYX(74107A, TTL_74107A, "+CLK,+J,+K,+CLRQ")
+ ENTRYX(74123, TTL_74123, "")
+ ENTRYX(74153, TTL_74153, "+C0,+C1,+C2,+C3,+A,+B,+G")
+ ENTRYX(74161, TTL_74161, "+A,+B,+C,+D,+CLRQ,+LOADQ,+CLK,+ENABLEP,+ENABLET")
+ ENTRYX(74164, TTL_74164, "+A,+B,+CLRQ,+CLK")
+ ENTRYX(74165, TTL_74165, "+CLK,+CLKINH,+SH_LDQ,+SER,+A,+B,+C,+D,+E,+F,+G,+H")
+ ENTRYX(74166, TTL_74166, "+CLK,+CLKINH,+SH_LDQ,+SER,+A,+B,+C,+D,+E,+F,+G,+H,+CLRQ")
+ ENTRYX(74174, TTL_74174, "+CLK,+D1,+D2,+D3,+D4,+D5,+D6,+CLRQ")
+ ENTRYX(74175, TTL_74175, "+CLK,+D1,+D2,+D3,+D4,+CLRQ")
+ ENTRYX(74192, TTL_74192, "+A,+B,+C,+D,+CLEAR,+LOADQ,+CU,+CD")
+ ENTRYX(74193, TTL_74193, "+A,+B,+C,+D,+CLEAR,+LOADQ,+CU,+CD")
+ ENTRYX(74194, TTL_74194, "+CLK,+S0,+S1,+SRIN,+A,+B,+C,+D,+SLIN,+CLRQ")
+ ENTRYX(74365, TTL_74365, "+G1Q,+G2Q,+A1,+A2,+A3,+A4,+A5,+A6")
+ //ENTRY(74279, TTL_74279, "") // only dip available
+ ENTRYX(SN74LS629, SN74LS629, "CAP")
+ ENTRYX(82S16, TTL_82S16, "")
+ ENTRYX(82S115, PROM_82S115, "+CE1Q,+CE2,+A0,+A1,+A2,+A3,+A4,+A5,+A6,+A7,+A8,+STROBE")
+ ENTRYX(82S123, PROM_82S123, "+CEQ,+A0,+A1,+A2,+A3,+A4")
+ ENTRYX(82S126, PROM_82S126, "+CE1Q,+CE2Q,+A0,+A1,+A2,+A3,+A4,+A5,+A6,+A7")
+ ENTRYX(9310, TTL_9310, "")
+ ENTRYX(9314, TTL_9314, "+EQ,+MRQ,+S0Q,+S1Q,+S2Q,+S3Q,+D0,+D1,+D2,+D3")
+ ENTRYX(9316, TTL_9316, "+CLK,+ENP,+ENT,+CLRQ,+LOADQ,+A,+B,+C,+D")
+ ENTRYX(9322, TTL_9322, "+SELECT,+A1,+B1,+A2,+B2,+A3,+B3,+A4,+B4,+STROBE")
+ ENTRYX(9334, TTL_9334, "+CQ,+EQ,+D,+A0,+A1,+A2")
+ ENTRYX(AM2847, TTL_AM2847, "+CP,+INA,+INB,+INC,+IND,+RCA,+RCB,+RCC,+RCD")
+ ENTRYX(CD4020, CD4020, "")
+ ENTRYX(CD4066_GATE, CD4066_GATE, "")
+ ENTRYX(CD4316_GATE, CD4316_GATE, "")
+ ENTRYX(schmitt_trigger, SCHMITT_TRIGGER, "MODEL")
+ /* entries with suffix WI are legacy only */
+ ENTRYX(CD4020, CD4020_WI, "+IP,+RESET,+VDD,+VSS")
+ //ENTRY(4066, CD_4066, "+A,B")
+ ENTRYX(NE555, NE555, "")
+ ENTRYX(r2r_dac, R2R_DAC, "VIN,R,N")
+ ENTRYX(tristate, TTL_TRISTATE, "+CEQ1,+D1,+CEQ2,+D2")
+ ENTRYX(tristate3, TTL_TRISTATE3, "")
+ ENTRYX(2102A_dip, RAM_2102A_DIP, "")
+ ENTRYX(2716_dip, EPROM_2716_DIP, "")
+ ENTRYX(tms4800_dip, ROM_TMS4800_DIP, "")
+ ENTRYX(4538_dip, CD4538_DIP, "")
+ ENTRYX(7448_dip, TTL_7448_DIP, "")
+ ENTRYX(7450_dip, TTL_7450_DIP, "")
+ ENTRYX(7473_dip, TTL_7473_DIP, "")
+ ENTRYX(7473A_dip, TTL_7473A_DIP, "")
+ ENTRYX(7474_dip, TTL_7474_DIP, "")
+ ENTRYX(7475_dip, TTL_7475_DIP, "")
+ ENTRYX(7477_dip, TTL_7477_DIP, "")
+ ENTRYX(7483_dip, TTL_7483_DIP, "")
+ ENTRYX(7485_dip, TTL_7485_DIP, "")
+ ENTRYX(7490_dip, TTL_7490_DIP, "")
+ ENTRYX(7493_dip, TTL_7493_DIP, "")
+ ENTRYX(74107_dip, TTL_74107_DIP, "")
+ ENTRYX(74123_dip, TTL_74123_DIP, "")
+ ENTRYX(74153_dip, TTL_74153_DIP, "")
+ ENTRYX(74161_dip, TTL_74161_DIP, "")
+ ENTRYX(74164_dip, TTL_74164_DIP, "")
+ ENTRYX(74165_dip, TTL_74165_DIP, "")
+ ENTRYX(74166_dip, TTL_74166_DIP, "")
+ ENTRYX(74174_dip, TTL_74174_DIP, "")
+ ENTRYX(74175_dip, TTL_74175_DIP, "")
+ ENTRYX(74192_dip, TTL_74192_DIP, "")
+ ENTRYX(74193_dip, TTL_74193_DIP, "")
+ ENTRYX(74194_dip, TTL_74194_DIP, "")
+ ENTRYX(74365_dip, TTL_74365_DIP, "")
+ ENTRYX(82S16_dip, TTL_82S16_DIP, "")
+ ENTRYX(82S115_dip, PROM_82S115_DIP, "")
+ ENTRYX(82S123_dip, PROM_82S123_DIP, "")
+ ENTRYX(82S126_dip, PROM_82S126_DIP, "")
+ ENTRYX(9602_dip, TTL_9602_DIP, "")
+ ENTRYX(9310_dip, TTL_9310_DIP, "")
+ ENTRYX(9314_dip, TTL_9314_DIP, "")
+ ENTRYX(9316_dip, TTL_9316_DIP, "")
+ ENTRYX(9322_dip, TTL_9322_DIP, "")
+ ENTRYX(9334_dip, TTL_9334_DIP, "")
+ ENTRYX(AM2847_dip, TTL_AM2847_DIP, "")
+ ENTRYX(SN74LS629_dip, SN74LS629_DIP, "1.CAP1,2.CAP2")
+ ENTRYX(NE555_dip, NE555_DIP, "")
+ ENTRYX(MM5837_dip, MM5837_DIP, "")
+}
-} //namespace devices
+ } //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/net_lib.h b/src/lib/netlist/devices/net_lib.h
index abf58ccee16..4dead624fc2 100644
--- a/src/lib/netlist/devices/net_lib.h
+++ b/src/lib/netlist/devices/net_lib.h
@@ -35,8 +35,18 @@
#include "nld_2102A.h"
#include "nld_2716.h"
+#include "nld_tms4800.h"
#include "nld_4020.h"
#include "nld_4066.h"
+#include "nld_7448.h"
+#include "nld_7450.h"
+#include "nld_7473.h"
+#include "nld_7474.h"
+#include "nld_7475.h"
+#include "nld_7483.h"
+#include "nld_7485.h"
+#include "nld_7490.h"
+#include "nld_7493.h"
#include "nld_74107.h"
#include "nld_74123.h"
#include "nld_74153.h"
@@ -50,32 +60,21 @@
#include "nld_74193.h"
#include "nld_74194.h"
#include "nld_74365.h"
-#include "nld_7448.h"
-#include "nld_7450.h"
-#include "nld_7473.h"
-#include "nld_7474.h"
-#include "nld_7475.h"
-#include "nld_7483.h"
-#include "nld_7485.h"
-#include "nld_7490.h"
-#include "nld_7493.h"
-#include "nld_7497.h"
#include "nld_74ls629.h"
+#include "nld_82S16.h"
#include "nld_82S115.h"
#include "nld_82S123.h"
#include "nld_82S126.h"
-#include "nld_82S16.h"
#include "nld_9310.h"
#include "nld_9316.h"
#include "nld_9322.h"
-#include "nld_tms4800.h"
#include "nld_am2847.h"
#include "nld_dm9314.h"
#include "nld_dm9334.h"
-#include "nld_mm5837.h"
#include "nld_ne555.h"
+#include "nld_mm5837.h"
#include "nld_r2r_dac.h"
@@ -85,17 +84,16 @@
#include "nld_log.h"
-#include "netlist/macro/nlm_cd4xxx.h"
-#include "netlist/macro/nlm_opamp.h"
-#include "netlist/macro/nlm_other.h"
-#include "netlist/macro/nlm_ttl74xx.h"
-
-#include "netlist/analog/nld_bjt.h"
-#include "netlist/analog/nld_fourterm.h"
-#include "netlist/analog/nld_mosfet.h"
-#include "netlist/analog/nld_opamps.h"
-#include "netlist/analog/nld_switches.h"
-#include "netlist/analog/nld_twoterm.h"
+#include "../macro/nlm_cd4xxx.h"
+#include "../macro/nlm_ttl74xx.h"
+#include "../macro/nlm_opamp.h"
+#include "../macro/nlm_other.h"
+
+#include "../analog/nld_bjt.h"
+#include "../analog/nld_fourterm.h"
+#include "../analog/nld_switches.h"
+#include "../analog/nld_twoterm.h"
+#include "../analog/nld_opamps.h"
#include "nld_legacy.h"
#endif
diff --git a/src/lib/netlist/devices/nld_2102A.cpp b/src/lib/netlist/devices/nld_2102A.cpp
index 0ec7132b401..5296bf2d029 100644
--- a/src/lib/netlist/devices/nld_2102A.cpp
+++ b/src/lib/netlist/devices/nld_2102A.cpp
@@ -6,7 +6,7 @@
*/
#include "nld_2102A.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
#define ADDR2BYTE(a) ((a) >> 3)
#define ADDR2BIT(a) ((a) & 0x7)
@@ -39,7 +39,7 @@ namespace netlist
logic_output_t m_DO;
- state_array<uint8_t, 128> m_ram; // 1024x1 bits
+ state_var<uint8_t[128]> m_ram; // 1024x1 bits
param_ptr_t m_RAM;
};
@@ -97,8 +97,8 @@ namespace netlist
m_ram[i] = 0;
}
- NETLIB_DEVICE_IMPL(2102A, "RAM_2102A", "+CEQ,+A0,+A1,+A2,+A3,+A4,+A5,+A6,+A7,+A8,+A9,+RWQ,+DI")
- NETLIB_DEVICE_IMPL(2102A_dip,"RAM_2102A_DIP","")
+ NETLIB_DEVICE_IMPL(2102A)
+ NETLIB_DEVICE_IMPL(2102A_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_2102A.h b/src/lib/netlist/devices/nld_2102A.h
index aa53efde47d..52d892d4d40 100644
--- a/src/lib/netlist/devices/nld_2102A.h
+++ b/src/lib/netlist/devices/nld_2102A.h
@@ -24,7 +24,7 @@
#ifndef NLD_2102A_H_
#define NLD_2102A_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define RAM_2102A(name, cCEQ, cA0, cA1, cA2, cA3, cA4, cA5, cA6, cA7, cA8, cA9, cRWQ, cDI) \
NET_REGISTER_DEV(RAM_2102A, name) \
diff --git a/src/lib/netlist/devices/nld_2716.cpp b/src/lib/netlist/devices/nld_2716.cpp
index b021bc95003..cb53d60e205 100644
--- a/src/lib/netlist/devices/nld_2716.cpp
+++ b/src/lib/netlist/devices/nld_2716.cpp
@@ -6,7 +6,7 @@
*/
#include "nld_2716.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
@@ -92,8 +92,8 @@ namespace netlist
m_D[i].push((d >> i) & 1, delay);
}
- NETLIB_DEVICE_IMPL(2716, "EPROM_2716", "+GQ,+EPQ,+A0,+A1,+A2,+A3,+A4,+A5,+A6,+A7,+A8,+A9,+A10")
- NETLIB_DEVICE_IMPL(2716_dip, "EPROM_2716_DIP", "")
+ NETLIB_DEVICE_IMPL(2716)
+ NETLIB_DEVICE_IMPL(2716_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_2716.h b/src/lib/netlist/devices/nld_2716.h
index 363086d6a37..f4776242e6a 100644
--- a/src/lib/netlist/devices/nld_2716.h
+++ b/src/lib/netlist/devices/nld_2716.h
@@ -28,7 +28,7 @@
#ifndef NLD_2716_H_
#define NLD_2716_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define EPROM_2716(name, cGQ, cEPQ, cA0, cA1, cA2, cA3, cA4, cA5, cA6, cA7, cA8, cA9, cA10) \
NET_REGISTER_DEV(EPROM_2716, name) \
diff --git a/src/lib/netlist/devices/nld_4020.cpp b/src/lib/netlist/devices/nld_4020.cpp
index 13518f9d3cb..8403d42bef2 100644
--- a/src/lib/netlist/devices/nld_4020.cpp
+++ b/src/lib/netlist/devices/nld_4020.cpp
@@ -96,9 +96,9 @@ namespace netlist
m_sub.m_IP.activate_hl();
}
- NETLIB_FUNC_VOID(CD4020_sub, update_outputs, (const unsigned cnt))
+ inline NETLIB_FUNC_VOID(CD4020_sub, update_outputs, (const unsigned cnt))
{
- static constexpr const std::array<netlist_time, 14> out_delayQn = {
+ /* static */ const netlist_time out_delayQn[14] = {
NLTIME_FROM_NS(180), NLTIME_FROM_NS(280),
NLTIME_FROM_NS(380), NLTIME_FROM_NS(480),
NLTIME_FROM_NS(580), NLTIME_FROM_NS(680),
@@ -113,8 +113,7 @@ namespace netlist
m_Q[i].push((cnt >> i) & 1, out_delayQn[i]);
}
- NETLIB_DEVICE_IMPL(CD4020, "CD4020", "")
- NETLIB_DEVICE_IMPL_ALIAS(CD4020_WI, CD4020, "CD4020_WI", "+IP,+RESET,+VDD,+VSS")
+ NETLIB_DEVICE_IMPL(CD4020)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_4020.h b/src/lib/netlist/devices/nld_4020.h
index f24251fb1dc..fd6b234da46 100644
--- a/src/lib/netlist/devices/nld_4020.h
+++ b/src/lib/netlist/devices/nld_4020.h
@@ -27,7 +27,7 @@
#ifndef NLD_4020_H_
#define NLD_4020_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
/* FIXME: only used in mario.c */
#define CD4020_WI(name, cIP, cRESET, cVDD, cVSS) \
diff --git a/src/lib/netlist/devices/nld_4066.cpp b/src/lib/netlist/devices/nld_4066.cpp
index 0c7511ca438..ebd269a023a 100644
--- a/src/lib/netlist/devices/nld_4066.cpp
+++ b/src/lib/netlist/devices/nld_4066.cpp
@@ -5,11 +5,9 @@
*
*/
-#include "nld_4066.h"
-
-#include "netlist/analog/nlid_twoterm.h"
-#include "netlist/solver/nld_solver.h"
#include "nlid_cmos.h"
+#include "../analog/nlid_twoterm.h"
+#include "nld_4066.h"
namespace netlist
{
@@ -29,7 +27,7 @@ namespace netlist
NETLIB_RESETI();
NETLIB_UPDATEI();
- private:
+ public:
NETLIB_SUB(vdd_vss) m_supply;
analog::NETLIB_SUB(R_base) m_R;
@@ -41,36 +39,45 @@ namespace netlist
{
// Start in off condition
// FIXME: is ROFF correct?
- m_R.set_R(plib::constants<nl_double>::one() / exec().gmin());
+ m_R.set_R(NL_FCONST(1.0) / netlist().gmin());
}
NETLIB_UPDATE(CD4066_GATE)
{
nl_double sup = (m_supply.vdd() - m_supply.vss());
- nl_double low = plib::constants<nl_double>::cast(0.45) * sup;
- nl_double high = plib::constants<nl_double>::cast(0.55) * sup;
+ nl_double low = NL_FCONST(0.45) * sup;
+ nl_double high = NL_FCONST(0.55) * sup;
nl_double in = m_control() - m_supply.vss();
- nl_double rON = m_base_r() * plib::constants<nl_double>::cast(5.0) / sup;
+ nl_double rON = m_base_r() * NL_FCONST(5.0) / sup;
nl_double R = -1.0;
if (in < low)
{
- R = plib::constants<nl_double>::one() / exec().gmin();
+ R = NL_FCONST(1.0) / netlist().gmin();
}
else if (in > high)
{
R = rON;
}
- if (R > plib::constants<nl_double>::zero())
+ if (R > NL_FCONST(0.0))
{
- m_R.update();
- m_R.set_R(R);
- m_R.solve_later();
+ // 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())
+ {
+ m_R.update_dev();
+ m_R.set_R(R);
+ m_R.m_P.schedule_solve_after(NLTIME_FROM_NS(1));
+ }
+ else
+ {
+ m_R.set_R(R);
+ m_R.update_dev();
+ }
}
}
- NETLIB_DEVICE_IMPL(CD4066_GATE, "CD4066_GATE", "")
+ NETLIB_DEVICE_IMPL(CD4066_GATE)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_4066.h b/src/lib/netlist/devices/nld_4066.h
index d339464a108..e9fd579496c 100644
--- a/src/lib/netlist/devices/nld_4066.h
+++ b/src/lib/netlist/devices/nld_4066.h
@@ -24,7 +24,7 @@
#ifndef NLD_4066_H_
#define NLD_4066_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define CD4066_GATE(name) \
NET_REGISTER_DEV(CD4066_GATE, name)
diff --git a/src/lib/netlist/devices/nld_4316.cpp b/src/lib/netlist/devices/nld_4316.cpp
index c8ee1a90643..b9758ff036b 100644
--- a/src/lib/netlist/devices/nld_4316.cpp
+++ b/src/lib/netlist/devices/nld_4316.cpp
@@ -5,10 +5,9 @@
*
*/
-#include "nld_4316.h"
-#include "netlist/analog/nlid_twoterm.h"
-#include "netlist/solver/nld_solver.h"
#include "nlid_cmos.h"
+#include "../analog/nlid_twoterm.h"
+#include "nld_4316.h"
namespace netlist { namespace devices {
@@ -38,20 +37,19 @@ namespace netlist { namespace devices {
NETLIB_RESET(CD4316_GATE)
{
- m_R.set_R(plib::constants<nl_double>::one() / exec().gmin());
+ m_R.set_R(NL_FCONST(1.0) / netlist().gmin());
}
NETLIB_UPDATE(CD4316_GATE)
{
- m_R.update();
+ m_R.update_dev();
if (m_S() && !m_E())
m_R.set_R(m_base_r());
else
- m_R.set_R(plib::constants<nl_double>::one() / exec().gmin());
- m_R.solve_later(NLTIME_FROM_NS(1));
+ m_R.set_R(NL_FCONST(1.0) / netlist().gmin());
+ m_R.m_P.schedule_solve_after(NLTIME_FROM_NS(1));
}
- NETLIB_DEVICE_IMPL(CD4316_GATE, "CD4316_GATE", "")
+ NETLIB_DEVICE_IMPL(CD4316_GATE)
-} // namespace devices
- } // namespace netlist
+} } // namesapce netlist::devices
diff --git a/src/lib/netlist/devices/nld_4316.h b/src/lib/netlist/devices/nld_4316.h
index 278a2793a6f..eb1d13f5542 100644
--- a/src/lib/netlist/devices/nld_4316.h
+++ b/src/lib/netlist/devices/nld_4316.h
@@ -25,7 +25,7 @@
#ifndef NLD_4316_H_
#define NLD_4316_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define CD4316_GATE(name) \
NET_REGISTER_DEV(CD4316_GATE, name)
diff --git a/src/lib/netlist/devices/nld_74107.cpp b/src/lib/netlist/devices/nld_74107.cpp
index 763760e2c6a..c5a12a15fb4 100644
--- a/src/lib/netlist/devices/nld_74107.cpp
+++ b/src/lib/netlist/devices/nld_74107.cpp
@@ -6,15 +6,15 @@
*/
#include "nld_74107.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
namespace devices
{
- static constexpr const netlist_time delay_107[2] = { NLTIME_FROM_NS(16), NLTIME_FROM_NS(25) };
- static constexpr const netlist_time delay_107A[2] = { NLTIME_FROM_NS(15), NLTIME_FROM_NS(15) };
+ static constexpr netlist_time delay_107[2] = { NLTIME_FROM_NS(16), NLTIME_FROM_NS(25) };
+ static constexpr netlist_time delay_107A[2] = { NLTIME_FROM_NS(15), NLTIME_FROM_NS(15) };
NETLIB_OBJECT(74107A)
{
@@ -22,12 +22,11 @@ namespace netlist
, m_clk(*this, "CLK", NETLIB_DELEGATE(74107A, clk))
, m_Q(*this, "Q")
, m_QQ(*this, "QQ")
+ , m_delay(delay_107A)
, m_J(*this, "J")
, m_K(*this, "K")
, m_clrQ(*this, "CLRQ")
{
- m_delay[0] = delay_107A[0];
- m_delay[1] = delay_107A[1];
}
friend class NETLIB_NAME(74107_dip);
@@ -44,7 +43,7 @@ namespace netlist
logic_output_t m_Q;
logic_output_t m_QQ;
- netlist_time m_delay[2];
+ const netlist_time *m_delay;
logic_input_t m_J;
logic_input_t m_K;
@@ -62,8 +61,7 @@ namespace netlist
public:
NETLIB_CONSTRUCTOR_DERIVED(74107, 74107A)
{
- m_delay[0] = delay_107[0];
- m_delay[1] = delay_107[1];
+ m_delay = delay_107;
}
};
@@ -139,9 +137,9 @@ namespace netlist
m_clk.activate_hl();
}
- NETLIB_DEVICE_IMPL(74107, "TTL_74107", "+CLK,+J,+K,+CLRQ")
- NETLIB_DEVICE_IMPL(74107A, "TTL_74107A", "+CLK,+J,+K,+CLRQ")
- NETLIB_DEVICE_IMPL(74107_dip, "TTL_74107_DIP", "")
+ NETLIB_DEVICE_IMPL(74107)
+ NETLIB_DEVICE_IMPL(74107A)
+ NETLIB_DEVICE_IMPL(74107_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_74107.h b/src/lib/netlist/devices/nld_74107.h
index c6f8864610a..b59848cbb05 100644
--- a/src/lib/netlist/devices/nld_74107.h
+++ b/src/lib/netlist/devices/nld_74107.h
@@ -64,7 +64,7 @@
#ifndef NLD_74107_H_
#define NLD_74107_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define TTL_74107A(name, cCLK, cJ, cK, cCLRQ) \
NET_REGISTER_DEV(TTL_74107A, name) \
diff --git a/src/lib/netlist/devices/nld_74123.cpp b/src/lib/netlist/devices/nld_74123.cpp
index 32e47a47ef2..9055c5ce140 100644
--- a/src/lib/netlist/devices/nld_74123.cpp
+++ b/src/lib/netlist/devices/nld_74123.cpp
@@ -6,7 +6,7 @@
*/
#include "nlid_system.h"
-#include "netlist/analog/nlid_twoterm.h"
+#include "../analog/nlid_twoterm.h"
#include <cmath>
@@ -257,8 +257,8 @@ namespace netlist
{
m_KP = 1.0 / (1.0 + exp(m_K()));
- m_RP.reset();
- m_RN.reset();
+ m_RP.do_reset();
+ m_RN.do_reset();
//m_RP.set_R(R_OFF);
//m_RN.set_R(R_OFF);
@@ -276,8 +276,8 @@ namespace netlist
NETLIB_RESET(74123_dip)
{
- //m_1.reset();
- //m_2.reset();
+ //m_1.do_reset();
+ //m_2.do_reset();
}
NETLIB_UPDATE(9602_dip)
@@ -289,8 +289,8 @@ namespace netlist
NETLIB_RESET(9602_dip)
{
- //m_1.reset();
- //m_2.reset();
+ //m_1.do_reset();
+ //m_2.do_reset();
}
NETLIB_UPDATE(4538_dip)
@@ -302,14 +302,14 @@ namespace netlist
NETLIB_RESET(4538_dip)
{
- m_1.reset();
- m_2.reset();
+ m_1.do_reset();
+ m_2.do_reset();
}
- NETLIB_DEVICE_IMPL(74123, "TTL_74123", "")
- NETLIB_DEVICE_IMPL(74123_dip, "TTL_74123_DIP", "")
- NETLIB_DEVICE_IMPL(4538_dip, "CD4538_DIP", "")
- NETLIB_DEVICE_IMPL(9602_dip, "TTL_9602_DIP", "")
+ NETLIB_DEVICE_IMPL(74123)
+ NETLIB_DEVICE_IMPL(74123_dip)
+ NETLIB_DEVICE_IMPL(4538_dip)
+ NETLIB_DEVICE_IMPL(9602_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_74123.h b/src/lib/netlist/devices/nld_74123.h
index 3eca141b613..dfd75f746c7 100644
--- a/src/lib/netlist/devices/nld_74123.h
+++ b/src/lib/netlist/devices/nld_74123.h
@@ -49,7 +49,7 @@
#ifndef NLD_74123_H_
#define NLD_74123_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define TTL_74123(name) \
NET_REGISTER_DEV(TTL_74123, name)
diff --git a/src/lib/netlist/devices/nld_74153.cpp b/src/lib/netlist/devices/nld_74153.cpp
index 136fe61520b..b74c09f8cc0 100644
--- a/src/lib/netlist/devices/nld_74153.cpp
+++ b/src/lib/netlist/devices/nld_74153.cpp
@@ -6,7 +6,7 @@
*/
#include "nld_74153.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
@@ -120,19 +120,19 @@ namespace netlist
NETLIB_UPDATE(74153)
{
m_sub.m_chan = (m_A() | (m_B()<<1));
- m_sub.update();
+ m_sub.update_dev();
}
NETLIB_UPDATE(74153_dip)
{
m_2.m_chan = m_1.m_chan = (m_A() | (m_B()<<1));
- m_1.update();
- m_2.update();
+ m_1.update_dev();
+ m_2.update_dev();
}
- NETLIB_DEVICE_IMPL(74153, "TTL_74153", "+C0,+C1,+C2,+C3,+A,+B,+G")
- NETLIB_DEVICE_IMPL(74153_dip, "TTL_74153_DIP", "")
+ NETLIB_DEVICE_IMPL(74153)
+ NETLIB_DEVICE_IMPL(74153_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_74153.h b/src/lib/netlist/devices/nld_74153.h
index f1c0f056cf7..ee77d4224ce 100644
--- a/src/lib/netlist/devices/nld_74153.h
+++ b/src/lib/netlist/devices/nld_74153.h
@@ -45,7 +45,7 @@
#ifndef NLD_74153_H_
#define NLD_74153_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define TTL_74153(name, cC0, cC1, cC2, cC3, cA, cB, cG) \
NET_REGISTER_DEV(TTL_74153, name) \
diff --git a/src/lib/netlist/devices/nld_74161.cpp b/src/lib/netlist/devices/nld_74161.cpp
index 7a3b54d6368..5eb711fb456 100644
--- a/src/lib/netlist/devices/nld_74161.cpp
+++ b/src/lib/netlist/devices/nld_74161.cpp
@@ -6,7 +6,7 @@
*/
#include "nld_74161.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
@@ -85,7 +85,7 @@ namespace netlist
}
// FIXME: Timing
- static constexpr const netlist_time delay[4] =
+ static constexpr netlist_time delay[4] =
{
NLTIME_FROM_NS(40),
NLTIME_FROM_NS(40),
@@ -126,8 +126,8 @@ namespace netlist
m_RCO.push(tRippleCarryOut, NLTIME_FROM_NS(20)); //FIXME
}
- NETLIB_DEVICE_IMPL(74161, "TTL_74161", "+A,+B,+C,+D,+CLRQ,+LOADQ,+CLK,+ENABLEP,+ENABLET")
- NETLIB_DEVICE_IMPL(74161_dip, "TTL_74161_DIP", "")
+ NETLIB_DEVICE_IMPL(74161)
+ NETLIB_DEVICE_IMPL(74161_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_74161.h b/src/lib/netlist/devices/nld_74161.h
index f3fa3eab043..363bc3c7f0d 100644
--- a/src/lib/netlist/devices/nld_74161.h
+++ b/src/lib/netlist/devices/nld_74161.h
@@ -25,7 +25,7 @@
#ifndef NLD_74161_H_
#define NLD_74161_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define TTL_74161(name, cA, cB, cC, cD, cCLRQ, cLOADQ, cCLK, cENABLEP, cENABLET) \
NET_REGISTER_DEV(TTL_74161, name) \
diff --git a/src/lib/netlist/devices/nld_74164.cpp b/src/lib/netlist/devices/nld_74164.cpp
index b1eb30bb1ba..5b2b1d8d080 100644
--- a/src/lib/netlist/devices/nld_74164.cpp
+++ b/src/lib/netlist/devices/nld_74164.cpp
@@ -9,7 +9,7 @@
*/
#include "nld_74164.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
@@ -97,8 +97,8 @@ namespace netlist
}
}
- NETLIB_DEVICE_IMPL(74164, "TTL_74164", "+A,+B,+CLRQ,+CLK")
- NETLIB_DEVICE_IMPL(74164_dip, "TTL_74164_DIP", "")
+ NETLIB_DEVICE_IMPL(74164)
+ NETLIB_DEVICE_IMPL(74164_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_74164.h b/src/lib/netlist/devices/nld_74164.h
index dd4e6bd1303..d7f29d386de 100644
--- a/src/lib/netlist/devices/nld_74164.h
+++ b/src/lib/netlist/devices/nld_74164.h
@@ -42,7 +42,7 @@
#ifndef NLD_74164_H_
#define NLD_74164_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define TTL_74164(name, cA, cB, cCLRQ, cCLK) \
NET_REGISTER_DEV(TTL_74164, name) \
diff --git a/src/lib/netlist/devices/nld_74165.cpp b/src/lib/netlist/devices/nld_74165.cpp
index 521bf4d63d2..678c1b1782e 100644
--- a/src/lib/netlist/devices/nld_74165.cpp
+++ b/src/lib/netlist/devices/nld_74165.cpp
@@ -6,7 +6,7 @@
*/
#include "nld_74165.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
@@ -86,7 +86,6 @@ namespace netlist
}
else if (!m_CLK() || m_CLKINH())
{
- // FIXME: qh is overwritten below?
qh = old_qh;
}
else if (!m_last_CLK)
@@ -102,8 +101,8 @@ namespace netlist
m_QH.push(qh, NLTIME_FROM_NS(20)); // FIXME: Timing
}
- NETLIB_DEVICE_IMPL(74165, "TTL_74165", "+CLK,+CLKINH,+SH_LDQ,+SER,+A,+B,+C,+D,+E,+F,+G,+H")
- NETLIB_DEVICE_IMPL(74165_dip, "TTL_74165_DIP", "")
+ NETLIB_DEVICE_IMPL(74165)
+ NETLIB_DEVICE_IMPL(74165_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_74165.h b/src/lib/netlist/devices/nld_74165.h
index d282bab622b..e38ca7bab86 100644
--- a/src/lib/netlist/devices/nld_74165.h
+++ b/src/lib/netlist/devices/nld_74165.h
@@ -27,7 +27,7 @@
#ifndef NLD_74165_H_
#define NLD_74165_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define TTL_74165(name, cCLK, cCLKINH, cSH_LDQ, cSER, cA, cB, cC, cD, cE, cF, cG, cH) \
NET_REGISTER_DEV(TTL_74165, name) \
diff --git a/src/lib/netlist/devices/nld_74166.cpp b/src/lib/netlist/devices/nld_74166.cpp
index a5049014576..32f075c4da5 100644
--- a/src/lib/netlist/devices/nld_74166.cpp
+++ b/src/lib/netlist/devices/nld_74166.cpp
@@ -6,7 +6,7 @@
*/
#include "nld_74166.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
@@ -121,8 +121,8 @@ namespace netlist
m_QH.push(qh, delay); //FIXME
}
- NETLIB_DEVICE_IMPL(74166, "TTL_74166", "+CLK,+CLKINH,+SH_LDQ,+SER,+A,+B,+C,+D,+E,+F,+G,+H,+CLRQ")
- NETLIB_DEVICE_IMPL(74166_dip,"TTL_74166_DIP", "")
+ NETLIB_DEVICE_IMPL(74166)
+ NETLIB_DEVICE_IMPL(74166_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_74166.h b/src/lib/netlist/devices/nld_74166.h
index 80c86bb3422..b8a8a204374 100644
--- a/src/lib/netlist/devices/nld_74166.h
+++ b/src/lib/netlist/devices/nld_74166.h
@@ -27,7 +27,7 @@
#ifndef NLD_74166_H_
#define NLD_74166_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define TTL_74166(name, cCLK, cCLKINH, cSH_LDQ, cSER, cA, cB, cC, cD, cE, cF, cG, cH, cCLRQ) \
NET_REGISTER_DEV(TTL_74166, name) \
diff --git a/src/lib/netlist/devices/nld_74174.cpp b/src/lib/netlist/devices/nld_74174.cpp
index 83369075db6..5f4573942bd 100644
--- a/src/lib/netlist/devices/nld_74174.cpp
+++ b/src/lib/netlist/devices/nld_74174.cpp
@@ -6,7 +6,7 @@
*/
#include "nld_74174.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
@@ -134,8 +134,8 @@ namespace netlist
//m_sub.do_reset();
}
- NETLIB_DEVICE_IMPL(74174, "TTL_74174", "+CLK,+D1,+D2,+D3,+D4,+D5,+D6,+CLRQ")
- NETLIB_DEVICE_IMPL(74174_dip,"TTL_74174_DIP", "")
+ NETLIB_DEVICE_IMPL(74174)
+ NETLIB_DEVICE_IMPL(74174_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_74174.h b/src/lib/netlist/devices/nld_74174.h
index f1854801291..66824abb7aa 100644
--- a/src/lib/netlist/devices/nld_74174.h
+++ b/src/lib/netlist/devices/nld_74174.h
@@ -36,7 +36,7 @@
#ifndef NLD_74174_H_
#define NLD_74174_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define TTL_74174(name, cCLK, cD1, cD2, cD3, cD4, cD5, cD6, cCLRQ) \
NET_REGISTER_DEV(TTL_74174, name) \
diff --git a/src/lib/netlist/devices/nld_74175.cpp b/src/lib/netlist/devices/nld_74175.cpp
index a15adb5c60f..5955bcb389e 100644
--- a/src/lib/netlist/devices/nld_74175.cpp
+++ b/src/lib/netlist/devices/nld_74175.cpp
@@ -6,7 +6,7 @@
*/
#include "nld_74175.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
@@ -111,8 +111,8 @@ namespace netlist
m_data = 0xFF;
}
- NETLIB_DEVICE_IMPL(74175, "TTL_74175", "+CLK,+D1,+D2,+D3,+D4,+CLRQ")
- NETLIB_DEVICE_IMPL(74175_dip,"TTL_74175_DIP", "")
+ NETLIB_DEVICE_IMPL(74175)
+ NETLIB_DEVICE_IMPL(74175_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_74175.h b/src/lib/netlist/devices/nld_74175.h
index 4bc8c1175ba..27e01b55b05 100644
--- a/src/lib/netlist/devices/nld_74175.h
+++ b/src/lib/netlist/devices/nld_74175.h
@@ -36,7 +36,7 @@
#ifndef NLD_74175_H_
#define NLD_74175_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define TTL_74175(name, cCLK, cD1, cD2, cD3, cD4, cCLRQ) \
NET_REGISTER_DEV(TTL_74175, name) \
diff --git a/src/lib/netlist/devices/nld_74192.cpp b/src/lib/netlist/devices/nld_74192.cpp
index 954fc351179..1af605d4776 100644
--- a/src/lib/netlist/devices/nld_74192.cpp
+++ b/src/lib/netlist/devices/nld_74192.cpp
@@ -6,7 +6,7 @@
*/
#include "nld_74192.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
@@ -110,7 +110,7 @@ namespace netlist
}
// FIXME: Timing
- static constexpr const netlist_time delay[4] =
+ static constexpr netlist_time delay[4] =
{
NLTIME_FROM_NS(40),
NLTIME_FROM_NS(40),
@@ -162,8 +162,8 @@ namespace netlist
m_CARRYQ.push(tCarry, NLTIME_FROM_NS(20)); //FIXME
}
- NETLIB_DEVICE_IMPL(74192, "TTL_74192", "+A,+B,+C,+D,+CLEAR,+LOADQ,+CU,+CD")
- NETLIB_DEVICE_IMPL(74192_dip,"TTL_74192_DIP", "")
+ NETLIB_DEVICE_IMPL(74192)
+ NETLIB_DEVICE_IMPL(74192_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_74192.h b/src/lib/netlist/devices/nld_74192.h
index 9b0139070b8..613d463cf47 100644
--- a/src/lib/netlist/devices/nld_74192.h
+++ b/src/lib/netlist/devices/nld_74192.h
@@ -29,7 +29,7 @@
#ifndef NLD_74192_H_
#define NLD_74192_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define TTL_74192(name, cA, cB, cC, cD, cCLEAR, cLOADQ, cCU, cCD) \
NET_REGISTER_DEV(TTL_74192, name) \
diff --git a/src/lib/netlist/devices/nld_74193.cpp b/src/lib/netlist/devices/nld_74193.cpp
index 16d7438d799..55d18f3dc1b 100644
--- a/src/lib/netlist/devices/nld_74193.cpp
+++ b/src/lib/netlist/devices/nld_74193.cpp
@@ -6,7 +6,7 @@
*/
#include "nld_74193.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
@@ -87,7 +87,7 @@ namespace netlist
}
// FIXME: Timing
- static constexpr const netlist_time delay[4] =
+ static constexpr netlist_time delay[4] =
{
NLTIME_FROM_NS(40),
NLTIME_FROM_NS(40),
@@ -139,8 +139,8 @@ namespace netlist
m_CARRYQ.push(tCarry, NLTIME_FROM_NS(20)); //FIXME timing
}
- NETLIB_DEVICE_IMPL(74193, "TTL_74193", "+A,+B,+C,+D,+CLEAR,+LOADQ,+CU,+CD")
- NETLIB_DEVICE_IMPL(74193_dip, "TTL_74193_DIP", "")
+ NETLIB_DEVICE_IMPL(74193)
+ NETLIB_DEVICE_IMPL(74193_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_74193.h b/src/lib/netlist/devices/nld_74193.h
index a4c745d5386..bb14a301f38 100644
--- a/src/lib/netlist/devices/nld_74193.h
+++ b/src/lib/netlist/devices/nld_74193.h
@@ -26,7 +26,7 @@
#ifndef NLD_74193_H_
#define NLD_74193_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define TTL_74193(name, cA, cB, cC, cD, cCLEAR, cLOADQ, cCU, cCD) \
NET_REGISTER_DEV(TTL_74193, name) \
diff --git a/src/lib/netlist/devices/nld_74194.cpp b/src/lib/netlist/devices/nld_74194.cpp
index 9876aa6b170..d531e792885 100644
--- a/src/lib/netlist/devices/nld_74194.cpp
+++ b/src/lib/netlist/devices/nld_74194.cpp
@@ -6,7 +6,7 @@
*/
#include "nld_74194.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
@@ -116,8 +116,8 @@ namespace netlist
m_Q[i].push((q >> i) & 1, NLTIME_FROM_NS(26)); // FIXME: Timing
}
- NETLIB_DEVICE_IMPL(74194, "TTL_74194", "+CLK,+S0,+S1,+SRIN,+A,+B,+C,+D,+SLIN,+CLRQ")
- NETLIB_DEVICE_IMPL(74194_dip, "TTL_74194_DIP", "")
+ NETLIB_DEVICE_IMPL(74194)
+ NETLIB_DEVICE_IMPL(74194_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_74194.h b/src/lib/netlist/devices/nld_74194.h
index 5a507982b81..5124a66bcc0 100644
--- a/src/lib/netlist/devices/nld_74194.h
+++ b/src/lib/netlist/devices/nld_74194.h
@@ -26,7 +26,7 @@
#ifndef NLD_74194_H_
#define NLD_74194_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define TTL_74194(name, cCLK, cS0, cS1, cSRIN, cA, cB, cC, cD, cSLIN, cCLRQ) \
NET_REGISTER_DEV(TTL_74194, name) \
diff --git a/src/lib/netlist/devices/nld_74365.cpp b/src/lib/netlist/devices/nld_74365.cpp
index 753f16bfd22..10456ebbc21 100644
--- a/src/lib/netlist/devices/nld_74365.cpp
+++ b/src/lib/netlist/devices/nld_74365.cpp
@@ -6,20 +6,12 @@
*/
#include "nld_74365.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
namespace devices
{
-
- /* FIXME: This should be a single device, i.e. one tristate buffer only.
- *
- * FIXME: Implement tristate output.
- *
- */
-
-
NETLIB_OBJECT(74365)
{
NETLIB_CONSTRUCTOR(74365)
@@ -76,8 +68,8 @@ namespace netlist
}
}
- NETLIB_DEVICE_IMPL(74365, "TTL_74365", "+G1Q,+G2Q,+A1,+A2,+A3,+A4,+A5,+A6")
- NETLIB_DEVICE_IMPL(74365_dip, "TTL_74365_DIP", "")
+ NETLIB_DEVICE_IMPL(74365)
+ NETLIB_DEVICE_IMPL(74365_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_74365.h b/src/lib/netlist/devices/nld_74365.h
index a50b535383f..ca0eacf6ba1 100644
--- a/src/lib/netlist/devices/nld_74365.h
+++ b/src/lib/netlist/devices/nld_74365.h
@@ -25,7 +25,7 @@
#ifndef NLD_74365_H_
#define NLD_74365_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define TTL_74365(name, cG1Q, cG2Q, cA1, cA2, cA3, cA4, cA5, cA6) \
NET_REGISTER_DEV(TTL_74365, name) \
diff --git a/src/lib/netlist/devices/nld_7448.cpp b/src/lib/netlist/devices/nld_7448.cpp
index 4500229a1c5..cc2e60f23b7 100644
--- a/src/lib/netlist/devices/nld_7448.cpp
+++ b/src/lib/netlist/devices/nld_7448.cpp
@@ -5,10 +5,8 @@
*
*/
+#include "nlid_truthtable.h"
#include "nld_7448.h"
-#include "nlid_truthtable.h"
-
-#include <array>
namespace netlist
{
@@ -135,9 +133,9 @@ namespace netlist
#else
-#define BITS7(b6,b5,b4,b3,b2,b1,b0) ((b6)<<6) | ((b5)<<5) | ((b4)<<4) | ((b3)<<3) | ((b2)<<2) | ((b1)<<1) | ((b0)<<0)
+#define BITS7(b6,b5,b4,b3,b2,b1,b0) (b6<<6) | (b5<<5) | (b4<<4) | (b3<<3) | (b2<<2) | (b1<<1) | (b0<<0)
- static constexpr const std::array<uint8_t, 16> tab7448 =
+ static constexpr uint8_t tab7448[16] =
{
BITS7( 1, 1, 1, 1, 1, 1, 0 ), /* 00 - not blanked ! */
BITS7( 0, 1, 1, 0, 0, 0, 0 ), /* 01 */
@@ -190,13 +188,11 @@ namespace netlist
NETLIB_RESET(7448)
{
m_state = 0;
-#if 0
- m_A.set_state(logic_t::STATE_INP_PASSIVE);
- m_B.set_state(logic_t::STATE_INP_PASSIVE);
- m_C.set_state(logic_t::STATE_INP_PASSIVE);
- m_D.set_state(logic_t::STATE_INP_PASSIVE);
- m_RBIQ.set_state(logic_t::STATE_INP_PASSIVE);
-#endif
+ m_A.inactivate();
+ m_B.inactivate();
+ m_C.inactivate();
+ m_D.inactivate();
+ m_RBIQ.inactivate();
}
NETLIB_FUNC_VOID(7448, update_outputs, (unsigned v))
@@ -215,8 +211,8 @@ namespace netlist
#endif
- NETLIB_DEVICE_IMPL(7448, "TTL_7448", "+A,+B,+C,+D,+LTQ,+BIQ,+RBIQ")
- NETLIB_DEVICE_IMPL(7448_dip, "TTL_7448_DIP", "")
+ NETLIB_DEVICE_IMPL(7448)
+ NETLIB_DEVICE_IMPL(7448_dip)
} //namespace devices
diff --git a/src/lib/netlist/devices/nld_7448.h b/src/lib/netlist/devices/nld_7448.h
index b9c03ae6360..89528707bc1 100644
--- a/src/lib/netlist/devices/nld_7448.h
+++ b/src/lib/netlist/devices/nld_7448.h
@@ -24,7 +24,7 @@
#ifndef NLD_7448_H_
#define NLD_7448_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#ifndef NL_AUTO_DEVICES
diff --git a/src/lib/netlist/devices/nld_7450.cpp b/src/lib/netlist/devices/nld_7450.cpp
index aacab46a021..af9b9afada1 100644
--- a/src/lib/netlist/devices/nld_7450.cpp
+++ b/src/lib/netlist/devices/nld_7450.cpp
@@ -6,7 +6,7 @@
*/
#include "nld_7450.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
@@ -68,10 +68,10 @@ namespace netlist
m_B.activate();
m_C.activate();
m_D.activate();
- auto t1 = m_A() & m_B();
- auto t2 = m_C() & m_D();
+ unsigned t1 = m_A() & m_B();
+ unsigned t2 = m_C() & m_D();
- const netlist_time times[2] = { NLTIME_FROM_NS(15), NLTIME_FROM_NS(22) };
+ const netlist_time times[2] = { NLTIME_FROM_NS(22), NLTIME_FROM_NS(15) };
uint_fast8_t res = 0;
if (t1 ^ 1)
@@ -85,20 +85,18 @@ namespace netlist
m_A.inactivate();
m_B.inactivate();
}
- }
- else
- {
+ } else {
if (t2 ^ 1)
{
m_C.inactivate();
m_D.inactivate();
}
}
- m_Q.push(res, times[res]);// ? 22000 : 15000);
+ m_Q.push(res, times[1 - res]);// ? 22000 : 15000);
}
- NETLIB_DEVICE_IMPL(7450, "TTL_7450_ANDORINVERT", "+A,+B,+C,+D")
- NETLIB_DEVICE_IMPL(7450_dip, "TTL_7450_DIP", "")
+ NETLIB_DEVICE_IMPL(7450)
+ NETLIB_DEVICE_IMPL(7450_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_7450.h b/src/lib/netlist/devices/nld_7450.h
index 6718afd8f9e..652516758ad 100644
--- a/src/lib/netlist/devices/nld_7450.h
+++ b/src/lib/netlist/devices/nld_7450.h
@@ -24,7 +24,7 @@
#ifndef NLD_7450_H_
#define NLD_7450_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define TTL_7450_ANDORINVERT(name, cI1, cI2, cI3, cI4) \
NET_REGISTER_DEV(TTL_7450_ANDORINVERT, name) \
diff --git a/src/lib/netlist/devices/nld_7473.cpp b/src/lib/netlist/devices/nld_7473.cpp
index c8abd829264..d9efb9fb710 100644
--- a/src/lib/netlist/devices/nld_7473.cpp
+++ b/src/lib/netlist/devices/nld_7473.cpp
@@ -6,7 +6,7 @@
*/
#include "nld_7473.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
@@ -142,10 +142,10 @@ namespace netlist
m_QQ.push(m_q ^ 1, NLTIME_FROM_NS(20)); // FIXME: timing
}
- NETLIB_DEVICE_IMPL(7473, "TTL_7473", "+CLK,+J,+K,+CLRQ")
- NETLIB_DEVICE_IMPL(7473A, "TTL_7473A", "+CLK,+J,+K,+CLRQ")
- NETLIB_DEVICE_IMPL(7473_dip, "TTL_7473_DIP", "")
- NETLIB_DEVICE_IMPL(7473A_dip, "TTL_7473A_DIP", "")
+ NETLIB_DEVICE_IMPL(7473)
+ NETLIB_DEVICE_IMPL(7473A)
+ NETLIB_DEVICE_IMPL(7473_dip)
+ NETLIB_DEVICE_IMPL(7473A_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_7473.h b/src/lib/netlist/devices/nld_7473.h
index 3fbaaf4efbc..5313d18570c 100644
--- a/src/lib/netlist/devices/nld_7473.h
+++ b/src/lib/netlist/devices/nld_7473.h
@@ -60,7 +60,7 @@
#ifndef NLD_7473_H_
#define NLD_7473_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define TTL_7473(name, cCLK, cJ, cK, cCLRQ) \
NET_REGISTER_DEV(TTL_7473, name) \
diff --git a/src/lib/netlist/devices/nld_7474.cpp b/src/lib/netlist/devices/nld_7474.cpp
index 740af6ad3c1..9d020663f46 100644
--- a/src/lib/netlist/devices/nld_7474.cpp
+++ b/src/lib/netlist/devices/nld_7474.cpp
@@ -1,4 +1,3 @@
-
// license:GPL-2.0+
// copyright-holders:Couriersud
/*
@@ -7,47 +6,60 @@
*/
#include "nld_7474.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
namespace devices
{
-
- NETLIB_OBJECT(7474)
+ NETLIB_OBJECT(7474sub)
{
- NETLIB_CONSTRUCTOR(7474)
- , m_D(*this, "D")
- , m_CLRQ(*this, "CLRQ")
- , m_PREQ(*this, "PREQ")
- , m_CLK(*this, "CLK", NETLIB_DELEGATE(7474, clk))
+ NETLIB_CONSTRUCTOR(7474sub)
+ , m_CLK(*this, "CLK")
, m_Q(*this, "Q")
, m_QQ(*this, "QQ")
, m_nextD(*this, "m_nextD", 0)
{
}
- private:
NETLIB_RESETI();
NETLIB_UPDATEI();
- NETLIB_HANDLERI(clk);
- logic_input_t m_D;
- logic_input_t m_CLRQ;
- logic_input_t m_PREQ;
+ public:
logic_input_t m_CLK;
logic_output_t m_Q;
logic_output_t m_QQ;
+ state_var<unsigned> m_nextD;
+
+ inline void newstate(const netlist_sig_t stateQ, const netlist_sig_t stateQQ);
- state_var<netlist_sig_t> m_nextD;
+ private:
+
+ };
- void newstate(const netlist_sig_t stateQ, const netlist_sig_t stateQQ)
+ NETLIB_OBJECT(7474)
+ {
+ NETLIB_CONSTRUCTOR(7474)
+ , sub(*this, "sub")
+ , m_D(*this, "D")
+ , m_CLRQ(*this, "CLRQ")
+ , m_PREQ(*this, "PREQ")
{
- // 0: High-to-low 40 ns, 1: Low-to-high 25 ns
- static constexpr const netlist_time delay[2] = { NLTIME_FROM_NS(40), NLTIME_FROM_NS(25) };
- m_Q.push(stateQ, delay[stateQ]);
- m_QQ.push(stateQQ, delay[stateQQ]);
+ register_subalias("CLK", sub.m_CLK);
+
+ register_subalias("Q", sub.m_Q);
+ register_subalias("QQ", sub.m_QQ);
}
+
+ NETLIB_RESETI();
+ NETLIB_UPDATEI();
+
+ public:
+ NETLIB_SUB(7474sub) sub;
+
+ logic_input_t m_D;
+ logic_input_t m_CLRQ;
+ logic_input_t m_PREQ;
};
NETLIB_OBJECT(7474_dip)
@@ -56,20 +68,20 @@ namespace netlist
, m_1(*this, "1")
, m_2(*this, "2")
{
- register_subalias("1", "1.CLRQ");
- register_subalias("2", "1.D");
- register_subalias("3", "1.CLK");
- register_subalias("4", "1.PREQ");
- register_subalias("5", "1.Q");
- register_subalias("6", "1.QQ");
+ register_subalias("1", m_1.m_CLRQ);
+ register_subalias("2", m_1.m_D);
+ register_subalias("3", m_1.sub.m_CLK);
+ register_subalias("4", m_1.m_PREQ);
+ register_subalias("5", m_1.sub.m_Q);
+ register_subalias("6", m_1.sub.m_QQ);
// register_subalias("7", ); ==> GND
- register_subalias("8", "2.QQ");
- register_subalias("9", "2.Q");
- register_subalias("10", "2.PREQ");
- register_subalias("11", "2.CLK");
- register_subalias("12", "2.D");
- register_subalias("13", "2.CLRQ");
+ register_subalias("8", m_2.sub.m_QQ);
+ register_subalias("9", m_2.sub.m_Q);
+ register_subalias("10", m_2.m_PREQ);
+ register_subalias("11", m_2.sub.m_CLK);
+ register_subalias("12", m_2.m_D);
+ register_subalias("13", m_2.m_CLRQ);
// register_subalias("14", ); ==> VCC
}
NETLIB_UPDATEI();
@@ -80,47 +92,77 @@ namespace netlist
NETLIB_SUB(7474) m_2;
};
- NETLIB_HANDLER(7474, clk)
+ inline void NETLIB_NAME(7474sub)::newstate(const netlist_sig_t stateQ, const netlist_sig_t stateQQ)
{
- newstate(m_nextD, !m_nextD);
- m_CLK.inactivate();
+ // 0: High-to-low 40 ns, 1: Low-to-high 25 ns
+ const netlist_time delay[2] = { NLTIME_FROM_NS(40), NLTIME_FROM_NS(25) };
+ m_Q.push(stateQ, delay[stateQ]);
+ m_QQ.push(stateQQ, delay[stateQQ]);
+ }
+
+ NETLIB_UPDATE(7474sub)
+ {
+ //if (INP_LH(m_CLK))
+ {
+ newstate(m_nextD, !m_nextD);
+ m_CLK.inactivate();
+ }
}
NETLIB_UPDATE(7474)
{
- const auto preq(m_PREQ());
- const auto clrq(m_CLRQ());
- if (preq & clrq)
+ if (m_PREQ() && m_CLRQ())
{
m_D.activate();
- m_nextD = m_D();
- m_CLK.activate_lh();
+ sub.m_nextD = m_D();
+ sub.m_CLK.activate_lh();
+ }
+ else if (!m_PREQ())
+ {
+ sub.newstate(1, 0);
+ sub.m_CLK.inactivate();
+ m_D.inactivate();
+ }
+ else if (!m_CLRQ())
+ {
+ sub.newstate(0, 1);
+ sub.m_CLK.inactivate();
+ m_D.inactivate();
}
else
{
- newstate(preq ^ 1, clrq ^ 1);
- m_CLK.inactivate();
+ sub.newstate(1, 1);
+ sub.m_CLK.inactivate();
m_D.inactivate();
}
}
NETLIB_RESET(7474)
{
+ sub.do_reset();
+ }
+
+ NETLIB_RESET(7474sub)
+ {
m_CLK.set_state(logic_t::STATE_INP_LH);
- m_D.set_state(logic_t::STATE_INP_ACTIVE);
+
m_nextD = 0;
}
NETLIB_RESET(7474_dip)
{
+ // m_1.do_reset();
+ //m_2.do_reset();
}
NETLIB_UPDATE(7474_dip)
{
+ //m_1.update_dev();
+ //m_2.update_dev();
}
- NETLIB_DEVICE_IMPL(7474, "TTL_7474", "+CLK,+D,+CLRQ,+PREQ")
- NETLIB_DEVICE_IMPL(7474_dip, "TTL_7474_DIP", "")
+ NETLIB_DEVICE_IMPL(7474)
+ NETLIB_DEVICE_IMPL(7474_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_7474.h b/src/lib/netlist/devices/nld_7474.h
index 48fd4f3d842..aa48e240387 100644
--- a/src/lib/netlist/devices/nld_7474.h
+++ b/src/lib/netlist/devices/nld_7474.h
@@ -42,7 +42,7 @@
#ifndef NLD_7474_H_
#define NLD_7474_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define TTL_7474(name, cCLK, cD, cCLRQ, cPREQ) \
NET_REGISTER_DEV(TTL_7474, name) \
diff --git a/src/lib/netlist/devices/nld_7475.cpp b/src/lib/netlist/devices/nld_7475.cpp
index 63fd355d406..b2d28048513 100644
--- a/src/lib/netlist/devices/nld_7475.cpp
+++ b/src/lib/netlist/devices/nld_7475.cpp
@@ -7,7 +7,7 @@
*/
#include "nld_7475.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
@@ -101,7 +101,7 @@ namespace netlist
{
unsigned start_q = m_last_Q;
- NETLIB_NAME(7477)::update();
+ NETLIB_PARENT_UPDATE(7477);
for (std::size_t i=0; i<4; i++)
{
@@ -148,10 +148,10 @@ namespace netlist
}
- NETLIB_DEVICE_IMPL(7475, "TTL_7475", "")
- NETLIB_DEVICE_IMPL(7475_dip, "TTL_7475_DIP", "")
- NETLIB_DEVICE_IMPL(7477, "TTL_7477", "")
- NETLIB_DEVICE_IMPL(7477_dip, "TTL_7477_DIP", "")
+ NETLIB_DEVICE_IMPL(7475)
+ NETLIB_DEVICE_IMPL(7475_dip)
+ NETLIB_DEVICE_IMPL(7477)
+ NETLIB_DEVICE_IMPL(7477_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_7475.h b/src/lib/netlist/devices/nld_7475.h
index b16fabe61b6..51d09e75a66 100644
--- a/src/lib/netlist/devices/nld_7475.h
+++ b/src/lib/netlist/devices/nld_7475.h
@@ -35,7 +35,7 @@
#ifndef NLD_7475_H_
#define NLD_7475_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define PARAMS_7475_7477(name, cC1C2, cC3C4, cD1, cD2, cD3, cD4) \
NET_CONNECT(name, C1C2, cC1C2) \
diff --git a/src/lib/netlist/devices/nld_7483.cpp b/src/lib/netlist/devices/nld_7483.cpp
index 5f820162209..72c86c003d5 100644
--- a/src/lib/netlist/devices/nld_7483.cpp
+++ b/src/lib/netlist/devices/nld_7483.cpp
@@ -6,7 +6,7 @@
*/
#include "nld_7483.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
@@ -16,16 +16,14 @@ namespace netlist
{
NETLIB_CONSTRUCTOR(7483)
, m_C0(*this, "C0")
- , m_A1(*this, "A1", NETLIB_DELEGATE(7483, upd_a))
- , m_A2(*this, "A2", NETLIB_DELEGATE(7483, upd_a))
- , m_A3(*this, "A3", NETLIB_DELEGATE(7483, upd_a))
- , m_A4(*this, "A4", NETLIB_DELEGATE(7483, upd_a))
- , m_B1(*this, "B1", NETLIB_DELEGATE(7483, upd_b))
- , m_B2(*this, "B2", NETLIB_DELEGATE(7483, upd_b))
- , m_B3(*this, "B3", NETLIB_DELEGATE(7483, upd_b))
- , m_B4(*this, "B4", NETLIB_DELEGATE(7483, upd_b))
- , m_a(*this, "m_a", 0)
- , m_b(*this, "m_b", 0)
+ , m_A1(*this, "A1")
+ , m_A2(*this, "A2")
+ , m_A3(*this, "A3")
+ , m_A4(*this, "A4")
+ , m_B1(*this, "B1")
+ , m_B2(*this, "B2")
+ , m_B3(*this, "B3")
+ , m_B4(*this, "B4")
, m_lastr(*this, "m_lastr", 0)
, m_S1(*this, "S1")
, m_S2(*this, "S2")
@@ -36,8 +34,6 @@ namespace netlist
}
NETLIB_RESETI();
NETLIB_UPDATEI();
- NETLIB_HANDLERI(upd_a);
- NETLIB_HANDLERI(upd_b);
protected:
logic_input_t m_C0;
@@ -50,9 +46,7 @@ namespace netlist
logic_input_t m_B3;
logic_input_t m_B4;
- state_var_u8 m_a;
- state_var_u8 m_b;
- state_var_u8 m_lastr;
+ state_var<unsigned> m_lastr;
logic_output_t m_S1;
logic_output_t m_S2;
@@ -93,21 +87,12 @@ namespace netlist
m_lastr = 0;
}
- NETLIB_HANDLER(7483, upd_a)
- {
- m_a = static_cast<uint8_t>((m_A1() << 0) | (m_A2() << 1) | (m_A3() << 2) | (m_A4() << 3));
- NETLIB_NAME(7483)::update();
- }
-
- NETLIB_HANDLER(7483, upd_b)
- {
- m_b = static_cast<uint8_t>((m_B1() << 0) | (m_B2() << 1) | (m_B3() << 2) | (m_B4() << 3));
- NETLIB_NAME(7483)::update();
- }
-
NETLIB_UPDATE(7483)
{
- auto r = static_cast<uint8_t>(m_a + m_b + m_C0());
+ netlist_sig_t a = (m_A1() << 0) | (m_A2() << 1) | (m_A3() << 2) | (m_A4() << 3);
+ netlist_sig_t b = (m_B1() << 0) | (m_B2() << 1) | (m_B3() << 2) | (m_B4() << 3);
+
+ unsigned r = a + b + m_C0();
if (r != m_lastr)
{
@@ -120,8 +105,8 @@ namespace netlist
}
}
- NETLIB_DEVICE_IMPL(7483, "TTL_7483", "+A1,+A2,+A3,+A4,+B1,+B2,+B3,+B4,+C0")
- NETLIB_DEVICE_IMPL(7483_dip, "TTL_7483_DIP", "")
+ NETLIB_DEVICE_IMPL(7483)
+ NETLIB_DEVICE_IMPL(7483_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_7483.h b/src/lib/netlist/devices/nld_7483.h
index ba82d5bbb9c..24952bf0501 100644
--- a/src/lib/netlist/devices/nld_7483.h
+++ b/src/lib/netlist/devices/nld_7483.h
@@ -27,7 +27,7 @@
#ifndef NLD_7483_H_
#define NLD_7483_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define TTL_7483(name, cA1, cA2, cA3, cA4, cB1, cB2, cB3, cB4, cCI) \
NET_REGISTER_DEV(TTL_7483, name) \
diff --git a/src/lib/netlist/devices/nld_7485.cpp b/src/lib/netlist/devices/nld_7485.cpp
index cadb73000ff..320cf762f26 100644
--- a/src/lib/netlist/devices/nld_7485.cpp
+++ b/src/lib/netlist/devices/nld_7485.cpp
@@ -6,7 +6,7 @@
*/
#include "nld_7485.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
@@ -101,8 +101,8 @@ namespace netlist
update_outputs(1, 1, 0);
}
- NETLIB_DEVICE_IMPL(7485, "TTL_7485", "+A0,+A1,+A2,+A3,+B0,+B1,+B2,+B3,+LTIN,+EQIN,+GTIN")
- NETLIB_DEVICE_IMPL(7485_dip, "TTL_7485_DIP", "")
+ NETLIB_DEVICE_IMPL(7485)
+ NETLIB_DEVICE_IMPL(7485_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_7485.h b/src/lib/netlist/devices/nld_7485.h
index 7890f4dbd2a..61b87c37ba3 100644
--- a/src/lib/netlist/devices/nld_7485.h
+++ b/src/lib/netlist/devices/nld_7485.h
@@ -23,7 +23,7 @@
#ifndef NLD_7485_H_
#define NLD_7485_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define TTL_7485(name, cA0, cA1, cA2, cA3, cB0, cB1, cB2, cB3, cLTIN, cEQIN, cGTIN) \
NET_REGISTER_DEV(TTL_7485, name) \
diff --git a/src/lib/netlist/devices/nld_7490.cpp b/src/lib/netlist/devices/nld_7490.cpp
index acbe0fa4d7a..13e69c6aa31 100644
--- a/src/lib/netlist/devices/nld_7490.cpp
+++ b/src/lib/netlist/devices/nld_7490.cpp
@@ -6,7 +6,7 @@
*/
#include "nld_7490.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
@@ -28,10 +28,10 @@ namespace netlist
{
}
- private:
NETLIB_UPDATEI();
NETLIB_RESETI();
+ protected:
void update_outputs();
logic_input_t m_A;
@@ -52,22 +52,22 @@ namespace netlist
{
NETLIB_CONSTRUCTOR_DERIVED(7490_dip, 7490)
{
- register_subalias("1", "B");
- register_subalias("2", "R1");
- register_subalias("3", "R2");
+ register_subalias("1", m_B);
+ register_subalias("2", m_R1);
+ register_subalias("3", m_R2);
// register_subalias("4", ); --> NC
// register_subalias("5", ); --> VCC
- register_subalias("6", "R91");
- register_subalias("7", "R92");
+ register_subalias("6", m_R91);
+ register_subalias("7", m_R92);
- register_subalias("8", "QC");
- register_subalias("9", "QB");
+ register_subalias("8", m_Q[2]);
+ register_subalias("9", m_Q[1]);
// register_subalias("10", ); --> GND
- register_subalias("11", "QD");
- register_subalias("12", "QA");
+ register_subalias("11", m_Q[3]);
+ register_subalias("12", m_Q[0]);
// register_subalias("13", ); --> NC
- register_subalias("14", "A");
+ register_subalias("14", m_A);
}
};
@@ -78,13 +78,12 @@ namespace netlist
m_last_B = 0;
}
- static constexpr const netlist_time delay[4] =
+ static C14CONSTEXPR const netlist_time delay[4] =
{
NLTIME_FROM_NS(18),
NLTIME_FROM_NS(36) - NLTIME_FROM_NS(18),
NLTIME_FROM_NS(54) - NLTIME_FROM_NS(18),
- NLTIME_FROM_NS(72) - NLTIME_FROM_NS(18)
- };
+ NLTIME_FROM_NS(72) - NLTIME_FROM_NS(18)};
NETLIB_UPDATE(7490)
{
@@ -120,14 +119,14 @@ namespace netlist
m_last_B = new_B;
}
- NETLIB_FUNC_VOID(7490, update_outputs, ())
+ NETLIB_FUNC_VOID(7490, update_outputs, (void))
{
for (std::size_t i=0; i<4; i++)
m_Q[i].push((m_cnt >> i) & 1, delay[i]);
}
- NETLIB_DEVICE_IMPL(7490, "TTL_7490", "+A,+B,+R1,+R2,+R91,+R92")
- NETLIB_DEVICE_IMPL(7490_dip, "TTL_7490_DIP", "")
+ NETLIB_DEVICE_IMPL(7490)
+ NETLIB_DEVICE_IMPL(7490_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_7490.h b/src/lib/netlist/devices/nld_7490.h
index e2fa5094911..5ff18543b03 100644
--- a/src/lib/netlist/devices/nld_7490.h
+++ b/src/lib/netlist/devices/nld_7490.h
@@ -55,7 +55,7 @@
#ifndef NLD_7490_H_
#define NLD_7490_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define TTL_7490(name, cA, cB, cR1, cR2, cR91, cR92) \
NET_REGISTER_DEV(TTL_7490, name) \
diff --git a/src/lib/netlist/devices/nld_7493.cpp b/src/lib/netlist/devices/nld_7493.cpp
index f26e1c237d5..f3c68f7a5c2 100644
--- a/src/lib/netlist/devices/nld_7493.cpp
+++ b/src/lib/netlist/devices/nld_7493.cpp
@@ -6,22 +6,23 @@
*/
#include "nld_7493.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
namespace devices
{
- static constexpr const netlist_time out_delay = NLTIME_FROM_NS(18);
- static constexpr const netlist_time out_delay2 = NLTIME_FROM_NS(36);
- static constexpr const netlist_time out_delay3 = NLTIME_FROM_NS(54);
+ static constexpr netlist_time out_delay = NLTIME_FROM_NS(18);
+ static constexpr netlist_time out_delay2 = NLTIME_FROM_NS(36);
+ static constexpr netlist_time out_delay3 = NLTIME_FROM_NS(54);
NETLIB_OBJECT(7493)
{
NETLIB_CONSTRUCTOR(7493)
, m_R1(*this, "R1")
, m_R2(*this, "R2")
+ , m_reset(*this, "_m_reset", 0)
, m_a(*this, "_m_a", 0)
, m_bcd(*this, "_m_b", 0)
, m_CLKA(*this, "CLKA", NETLIB_DELEGATE(7493, updA))
@@ -34,51 +35,35 @@ namespace netlist
}
private:
- NETLIB_RESETI()
- {
- m_a = m_bcd = 0;
- m_CLKA.set_state(logic_t::STATE_INP_HL);
- m_CLKB.set_state(logic_t::STATE_INP_HL);
- }
+ NETLIB_RESETI();
+ NETLIB_UPDATEI();
- NETLIB_UPDATEI()
+ NETLIB_HANDLERI(updA)
{
- if (!(m_R1() & m_R2()))
- {
- m_CLKA.activate_hl();
- m_CLKB.activate_hl();
- }
- else
+ if (m_reset)
{
- m_CLKA.inactivate();
- m_CLKB.inactivate();
- m_QA.push(0, NLTIME_FROM_NS(40));
- m_QB.push(0, NLTIME_FROM_NS(40));
- m_QC.push(0, NLTIME_FROM_NS(40));
- m_QD.push(0, NLTIME_FROM_NS(40));
- m_a = m_bcd = 0;
+ m_a ^= 1;
+ m_QA.push(m_a, out_delay);
}
}
- NETLIB_HANDLERI(updA)
- {
- m_a ^= 1;
- m_QA.push(m_a, out_delay);
- }
-
NETLIB_HANDLERI(updB)
{
- auto cnt = (++m_bcd &= 0x07);
- m_QD.push((cnt >> 2) & 1, out_delay3);
- m_QC.push((cnt >> 1) & 1, out_delay2);
- m_QB.push(cnt & 1, out_delay);
+ if (m_reset)
+ {
+ ++m_bcd &= static_cast<std::uint8_t>(0x07);
+ m_QD.push((m_bcd >> 2) & 1, out_delay3);
+ m_QC.push((m_bcd >> 1) & 1, out_delay2);
+ m_QB.push(m_bcd & 1, out_delay);
+ }
}
logic_input_t m_R1;
logic_input_t m_R2;
+ state_var_sig m_reset;
state_var_sig m_a;
- state_var_u8 m_bcd;
+ state_var_sig m_bcd;
logic_input_t m_CLKA;
logic_input_t m_CLKB;
@@ -112,9 +97,37 @@ namespace netlist
}
};
+ NETLIB_RESET(7493)
+ {
+ m_reset = 1;
+ m_a = m_bcd = 0;
+ m_CLKA.set_state(logic_t::STATE_INP_HL);
+ m_CLKB.set_state(logic_t::STATE_INP_HL);
+ }
+
+ NETLIB_UPDATE(7493)
+ {
+ m_reset = (m_R1() & m_R2()) ^ 1;
+
+ if (m_reset)
+ {
+ m_CLKA.activate_hl();
+ m_CLKB.activate_hl();
+ }
+ else
+ {
+ m_CLKA.inactivate();
+ m_CLKB.inactivate();
+ m_QA.push_force(0, NLTIME_FROM_NS(40));
+ m_QB.push_force(0, NLTIME_FROM_NS(40));
+ m_QC.push_force(0, NLTIME_FROM_NS(40));
+ m_QD.push_force(0, NLTIME_FROM_NS(40));
+ m_a = m_bcd = 0;
+ }
+ }
- NETLIB_DEVICE_IMPL(7493, "TTL_7493", "+CLKA,+CLKB,+R1,+R2")
- NETLIB_DEVICE_IMPL(7493_dip, "TTL_7493_DIP", "")
+ NETLIB_DEVICE_IMPL(7493)
+ NETLIB_DEVICE_IMPL(7493_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_7493.h b/src/lib/netlist/devices/nld_7493.h
index 68ad90885ec..ce9566aa28f 100644
--- a/src/lib/netlist/devices/nld_7493.h
+++ b/src/lib/netlist/devices/nld_7493.h
@@ -57,7 +57,7 @@
#ifndef NLD_7493_H_
#define NLD_7493_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define TTL_7493(name, cCLKA, cCLKB, cR1, cR2) \
NET_REGISTER_DEV(TTL_7493, name) \
diff --git a/src/lib/netlist/devices/nld_7497.cpp b/src/lib/netlist/devices/nld_7497.cpp
deleted file mode 100644
index 1432884b8dd..00000000000
--- a/src/lib/netlist/devices/nld_7497.cpp
+++ /dev/null
@@ -1,174 +0,0 @@
-// license:GPL-2.0+
-// copyright-holders:Sergey Svishchev
-/*
- * nld_7497.cpp
- *
- * To do:
- *
- * - STRB and EN
- * - Timing
- */
-
-#include "nld_7497.h"
-#include "netlist/nl_base.h"
-
-namespace netlist
-{
- namespace devices
- {
-
- static constexpr const netlist_time out_delay_CLK_Y[2] = { NLTIME_FROM_NS(20), NLTIME_FROM_NS(26) }; // tPHL, tPLH
- static constexpr const netlist_time out_delay_CLK_Z[2] = { NLTIME_FROM_NS(17), NLTIME_FROM_NS(12) };
-
- NETLIB_OBJECT(7497)
- {
- NETLIB_CONSTRUCTOR(7497)
- , m_B(*this, {{"B5", "B4", "B3", "B2", "B1", "B0"}})
- , m_CLK(*this, "CLK", NETLIB_DELEGATE(7497, clk_strb))
- , m_STRBQ(*this, "STRBQ", NETLIB_DELEGATE(7497, clk_strb))
- , m_ENQ(*this, "ENQ")
- , m_UNITYQ(*this, "UNITYQ", NETLIB_DELEGATE(7497, unity))
- , m_CLR(*this, "CLR", NETLIB_DELEGATE(7497, clr))
- , m_Y(*this, "Y")
- , m_ZQ(*this, "ZQ")
- , m_ENOUTQ(*this, "ENOUTQ")
- , m_cnt(*this, "_m_cnt", 0)
- , m_rate(*this, "_m_rate", 0)
- , m_state(*this, "_m_state", 0)
- , m_lastclock(*this, "_m_lastclock", 0)
- {
- }
-
- private:
- NETLIB_RESETI();
- NETLIB_UPDATEI();
-
- NETLIB_HANDLERI(noop) { }
- NETLIB_HANDLERI(unity);
- NETLIB_HANDLERI(clr);
- NETLIB_HANDLERI(clk_strb);
-
- protected:
- object_array_t<logic_input_t, 6> m_B;
- logic_input_t m_CLK;
- logic_input_t m_STRBQ;
- logic_input_t m_ENQ;
- logic_input_t m_UNITYQ;
- logic_input_t m_CLR;
-
- logic_output_t m_Y;
- logic_output_t m_ZQ;
- logic_output_t m_ENOUTQ;
-
- state_var_u8 m_cnt;
- state_var_u8 m_rate;
- state_var_sig m_state;
- state_var_sig m_lastclock;
-
- void newstate(const netlist_sig_t state)
- {
- m_state = state;
- m_ZQ.push(state, out_delay_CLK_Z[state]);
- //netlist_sig_t y = (state ^ 1) | (m_UNITY() ^ 1); // OR with negated inputs == NAND
- netlist_sig_t y = (state & m_UNITYQ()) ^ 1; // OR with negated inputs == NAND
- m_Y.push(y, out_delay_CLK_Y[y]);
- }
-
- uint8_t rate()
- {
- uint8_t a = 0;
-
- for (std::size_t i = 0; i < 6; i++)
- a |= (m_B[i]() << i);
-
- return a;
- }
- };
-
- NETLIB_RESET(7497)
- {
- m_cnt = 0;
- m_rate = 0;
- m_lastclock = 0;
- }
-
- NETLIB_UPDATE(7497)
- {
- m_rate = rate();
- clk_strb();
- }
-
- NETLIB_HANDLER(7497, unity)
- {
- newstate (m_state);
- }
-
- NETLIB_HANDLER(7497, clr)
- {
- m_cnt = 0;
- clk_strb();
- }
-
- NETLIB_HANDLER(7497, clk_strb)
- {
- netlist_sig_t clk = m_CLK();
-
- if (!m_lastclock && clk && !m_ENQ() && !m_CLR())
- {
- m_cnt++;
- m_cnt &= 63;
- }
- m_lastclock = clk;
-
- const netlist_sig_t clk_strb = (clk ^ 1) & (m_STRBQ() ^ 1);
-
- const netlist_sig_t cntQ = m_cnt;
-
- // NOR GATE
- netlist_sig_t p1 = ((cntQ & 63) == 31 && (m_rate & 32)) ||
- ((cntQ & 31) == 15 && (m_rate & 16)) ||
- ((cntQ & 15) == 7 && (m_rate & 8)) ||
- ((cntQ & 7) == 3 && (m_rate & 4)) ||
- ((cntQ & 3) == 1 && (m_rate & 2)) ||
- ((cntQ & 1) == 0 && (m_rate & 1));
-
- p1 = (p1 & clk_strb) ^ 1;
-
- newstate(p1);
-
- // NAND gate
- if ((m_cnt == 63) && !m_ENQ())
- m_ENOUTQ.push(0, out_delay_CLK_Y[0]); // XXX timing
- else
- m_ENOUTQ.push(1, out_delay_CLK_Y[1]);
-
- }
-
- NETLIB_OBJECT_DERIVED(7497_dip, 7497)
- {
- NETLIB_CONSTRUCTOR_DERIVED(7497_dip, 7497)
- {
- register_subalias("1", m_B[4]); // B0
- register_subalias("2", m_B[1]); // B4
- register_subalias("3", m_B[0]); // B5
- register_subalias("4", m_B[5]); // B0
- register_subalias("5", m_ZQ);
- register_subalias("6", m_Y);
- register_subalias("7", m_ENOUTQ);
-
- register_subalias("9", m_CLK);
- register_subalias("10", m_STRBQ);
- register_subalias("11", m_UNITYQ);
- register_subalias("12", m_ENQ);
- register_subalias("13", m_CLR);
- register_subalias("14", m_B[3]); // B2
- register_subalias("15", m_B[2]); // B3
- }
- };
-
-
- NETLIB_DEVICE_IMPL(7497, "TTL_7497", "+CLK,+STRBQ,+ENQ,+UNITYQ,+CLR,+B0,+B1,+B2,+B3,+B4,+B5")
- NETLIB_DEVICE_IMPL(7497_dip, "TTL_7497_DIP", "")
-
- } //namespace devices
-} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_7497.h b/src/lib/netlist/devices/nld_7497.h
deleted file mode 100644
index 8d14e08a49b..00000000000
--- a/src/lib/netlist/devices/nld_7497.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// license:GPL-2.0+
-// copyright-holders:Sergey Svishchev
-/*
- * nld_7497.h
- *
- * SN7497: Synchronous 6-Bit Binary Rate Multiplier
- *
- * +--------------+
- * B1 |1 16| VCC
- * B4 |2 15| B3
- * B5 |3 14| B2
- * B0 |4 7497 13| CLR
- * Z |5 12| UNITY/CAS
- * Y |6 11| ENin (EN)
- * ENout |7 10| STRB
- * GND |8 9| CLK
- * +--------------+
- *
- * Naming conventions follow TI datasheet
- *
- * The counter is enabled when the clear, strobe, and enable inputs are low.
- *
- * When the rate input is binary 0 (all rate inputs low), Z remains high [and Y low].
- *
- * The unity/cascade input, when connected to the clock input, passes
- * clock frequency (inverted) to the Y output when the rate input/decoding
- * gates are inhibited by the strobe.
- *
- * When CLR is H, states of CLK and STRB can affect Y and Z. Default are
- * Y L, Z H, ENout H.
- *
- * Unity/cascade is used to inhibit output Y (UNITY L -> Y H)
- */
-
-#ifndef NLD_7497_H_
-#define NLD_7497_H_
-
-#include "netlist/nl_setup.h"
-
-#define TTL_7497(name, cCLK, cSTRB, cEN, cUNITY, cCLR, cB0, cB1, cB2, cB3, cB4, cB5) \
- NET_REGISTER_DEV(TTL_7497, name) \
- NET_CONNECT(name, CLK, cCLK) \
- NET_CONNECT(name, STRBQ, cSTRB) \
- NET_CONNECT(name, ENQ, cEN) \
- NET_CONNECT(name, UNITYQ,cUNITY) \
- NET_CONNECT(name, CLR, cCLR) \
- NET_CONNECT(name, B0, cB0) \
- NET_CONNECT(name, B1, cB1) \
- NET_CONNECT(name, B2, cB2) \
- NET_CONNECT(name, B3, cB3) \
- NET_CONNECT(name, B4, cB4) \
- NET_CONNECT(name, B5, cB5)
-
-#define TTL_7497_DIP(name) \
- NET_REGISTER_DEV(TTL_7497_DIP, name)
-
-#endif /* NLD_7497_H_ */
diff --git a/src/lib/netlist/devices/nld_74ls629.cpp b/src/lib/netlist/devices/nld_74ls629.cpp
index b7bb729b334..d6dc268ed28 100644
--- a/src/lib/netlist/devices/nld_74ls629.cpp
+++ b/src/lib/netlist/devices/nld_74ls629.cpp
@@ -40,7 +40,7 @@
#include "nld_74ls629.h"
-#include "netlist/analog/nlid_twoterm.h"
+#include "../analog/nlid_twoterm.h"
namespace netlist
{
@@ -100,14 +100,11 @@ namespace netlist
{
m_R_FC.set_R(90000.0);
m_R_RNG.set_R(90000.0);
- m_clock.reset();
+ m_clock.do_reset();
}
NETLIB_UPDATEI();
- NETLIB_UPDATE_PARAMI()
- {
- /* update param may be called from anywhere, update_dev(time) is not a good idea */
- }
+ NETLIB_UPDATE_PARAMI() { update_dev(); }
public:
NETLIB_SUB(SN74LS629clk) m_clock;
@@ -148,8 +145,8 @@ namespace netlist
NETLIB_RESETI()
{
- m_1.reset();
- m_2.reset();
+ m_1.do_reset();
+ m_2.do_reset();
}
private:
@@ -210,7 +207,7 @@ namespace netlist
freq += k9 * v_rng * v_freq_3;
freq += k10 * v_rng * v_freq_4;
- freq *= plib::constants<nl_double>::cast(0.1e-6) / m_CAP();
+ freq *= NL_FCONST(0.1e-6) / m_CAP();
// FIXME: we need a possibility to remove entries from queue ...
// or an exact model ...
@@ -234,8 +231,8 @@ namespace netlist
}
}
- NETLIB_DEVICE_IMPL(SN74LS629, "SN74LS629", "CAP")
- NETLIB_DEVICE_IMPL(SN74LS629_dip, "SN74LS629_DIP", "1.CAP1,2.CAP2")
+ NETLIB_DEVICE_IMPL(SN74LS629)
+ NETLIB_DEVICE_IMPL(SN74LS629_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_74ls629.h b/src/lib/netlist/devices/nld_74ls629.h
index 30d15d70865..3351524a60b 100644
--- a/src/lib/netlist/devices/nld_74ls629.h
+++ b/src/lib/netlist/devices/nld_74ls629.h
@@ -28,7 +28,7 @@
#ifndef NLD_74LS629_H_
#define NLD_74LS629_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define SN74LS629(name, p_cap) \
NET_REGISTER_DEV(SN74LS629, name) \
diff --git a/src/lib/netlist/devices/nld_82S115.cpp b/src/lib/netlist/devices/nld_82S115.cpp
index 8ae6cbb6097..2e24bbf9fed 100644
--- a/src/lib/netlist/devices/nld_82S115.cpp
+++ b/src/lib/netlist/devices/nld_82S115.cpp
@@ -6,7 +6,7 @@
*/
#include "nld_82S115.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
@@ -106,8 +106,8 @@ namespace netlist
m_O[i].push((o >> i) & 1, NLTIME_FROM_NS(40)); // FIXME: Timing
}
- NETLIB_DEVICE_IMPL(82S115, "PROM_82S115", "+CE1Q,+CE2,+A0,+A1,+A2,+A3,+A4,+A5,+A6,+A7,+A8,+STROBE")
- NETLIB_DEVICE_IMPL(82S115_dip, "PROM_82S115_DIP", "")
+ NETLIB_DEVICE_IMPL(82S115)
+ NETLIB_DEVICE_IMPL(82S115_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_82S115.h b/src/lib/netlist/devices/nld_82S115.h
index 8c13fd8b51e..ef7f1ec3910 100644
--- a/src/lib/netlist/devices/nld_82S115.h
+++ b/src/lib/netlist/devices/nld_82S115.h
@@ -28,7 +28,7 @@
#ifndef NLD_82S115_H_
#define NLD_82S115_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define PROM_82S115(name, cCE1Q, cCE2, cA0, cA1, cA2, cA3, cA4, cA5, cA6, cA7, cA8, cSTROBE) \
NET_REGISTER_DEV(PROM_82S115, name) \
diff --git a/src/lib/netlist/devices/nld_82S123.cpp b/src/lib/netlist/devices/nld_82S123.cpp
index 4a80b57e349..a8a6bfc9b57 100644
--- a/src/lib/netlist/devices/nld_82S123.cpp
+++ b/src/lib/netlist/devices/nld_82S123.cpp
@@ -6,7 +6,7 @@
*/
#include "nld_82S123.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
@@ -77,8 +77,8 @@ namespace netlist
m_O[i].push((o >> i) & 1, delay);
}
- NETLIB_DEVICE_IMPL(82S123, "PROM_82S123", "+CEQ,+A0,+A1,+A2,+A3,+A4")
- NETLIB_DEVICE_IMPL(82S123_dip, "PROM_82S123_DIP", "")
+ NETLIB_DEVICE_IMPL(82S123)
+ NETLIB_DEVICE_IMPL(82S123_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_82S123.h b/src/lib/netlist/devices/nld_82S123.h
index 2c18377934d..dbf6bf63180 100644
--- a/src/lib/netlist/devices/nld_82S123.h
+++ b/src/lib/netlist/devices/nld_82S123.h
@@ -25,7 +25,7 @@
#ifndef NLD_82S123_H_
#define NLD_82S123_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define PROM_82S123(name, cCEQ, cA0, cA1, cA2, cA3, cA4) \
NET_REGISTER_DEV(PROM_82S123, name) \
diff --git a/src/lib/netlist/devices/nld_82S126.cpp b/src/lib/netlist/devices/nld_82S126.cpp
index b1752908645..dcacd1ec876 100644
--- a/src/lib/netlist/devices/nld_82S126.cpp
+++ b/src/lib/netlist/devices/nld_82S126.cpp
@@ -6,7 +6,7 @@
*/
#include "nld_82S126.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
@@ -79,8 +79,8 @@ namespace netlist
m_O[i].push((o >> i) & 1, delay);
}
- NETLIB_DEVICE_IMPL(82S126, "PROM_82S126", "+CE1Q,+CE2Q,+A0,+A1,+A2,+A3,+A4,+A5,+A6,+A7")
- NETLIB_DEVICE_IMPL(82S126_dip, "PROM_82S126_DIP", "")
+ NETLIB_DEVICE_IMPL(82S126)
+ NETLIB_DEVICE_IMPL(82S126_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_82S126.h b/src/lib/netlist/devices/nld_82S126.h
index ed7aa131819..3079bb8e2e0 100644
--- a/src/lib/netlist/devices/nld_82S126.h
+++ b/src/lib/netlist/devices/nld_82S126.h
@@ -24,7 +24,7 @@
#ifndef NLD_82S126_H_
#define NLD_82S126_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define PROM_82S126(name, cCE1Q, cCE2Q, cA0, cA1, cA2, cA3, cA4, cA5, cA6, cA7) \
NET_REGISTER_DEV(PROM_82S126, name) \
diff --git a/src/lib/netlist/devices/nld_82S16.cpp b/src/lib/netlist/devices/nld_82S16.cpp
index e3176c7b30f..7441f6c677e 100644
--- a/src/lib/netlist/devices/nld_82S16.cpp
+++ b/src/lib/netlist/devices/nld_82S16.cpp
@@ -6,7 +6,7 @@
*/
#include "nld_82S16.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
@@ -15,55 +15,19 @@ namespace netlist
NETLIB_OBJECT(82S16)
{
NETLIB_CONSTRUCTOR(82S16)
- , m_A(*this, {{"A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7" }}, NETLIB_DELEGATE(82S16, addr))
- , m_CE1Q(*this, "CE1Q", NETLIB_DELEGATE(82S16, enq))
- , m_CE2Q(*this, "CE2Q", NETLIB_DELEGATE(82S16, enq))
- , m_CE3Q(*this, "CE3Q", NETLIB_DELEGATE(82S16, enq))
+ , m_A(*this, {{"A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7" }})
+ , m_CE1Q(*this, "CE1Q")
+ , m_CE2Q(*this, "CE2Q")
+ , m_CE3Q(*this, "CE3Q")
, m_WEQ(*this, "WEQ")
, m_DIN(*this, "DIN")
, m_DOUTQ(*this, "DOUTQ")
, m_ram(*this, "m_ram", 0)
- , m_addr(*this, "m_addr", 0)
- , m_enq(*this, "m_enq", 0)
{
}
NETLIB_RESETI();
NETLIB_UPDATEI();
- NETLIB_HANDLERI(addr)
- {
- uint8_t adr = 0;
- for (std::size_t i=0; i<8; i++)
- {
- //m_A[i].activate();
- adr |= (m_A[i]() << i);
- }
- m_addr = adr;
- NETLIB_NAME(82S16)::update();
- }
- NETLIB_HANDLERI(enq)
- {
- const auto last = m_enq;
- m_enq = m_CE1Q() || m_CE2Q() || m_CE3Q();
- if (!last && m_enq)
- {
- // FIXME: Outputs are tristate. This needs to be properly implemented
- m_DOUTQ.push(1, NLTIME_FROM_NS(20));
- for (std::size_t i=0; i<8; i++)
- m_A[i].inactivate();
- m_WEQ.inactivate();
- m_DIN.inactivate();
- }
- else if (last && !m_enq)
- {
- for (std::size_t i=0; i<8; i++)
- m_A[i].activate();
- m_WEQ.activate();
- m_DIN.activate();
- NETLIB_NAME(82S16)::update();
- }
- }
-
protected:
object_array_t<logic_input_t, 8> m_A;
@@ -74,9 +38,7 @@ namespace netlist
logic_input_t m_DIN;
logic_output_t m_DOUTQ;
- state_array<uint64_t, 4> m_ram; // 256 bits
- state_var_u8 m_addr; // 256 bits
- state_var_sig m_enq;
+ state_var<uint64_t[4]> m_ram; // 256 bits
};
NETLIB_OBJECT_DERIVED(82S16_dip, 82S16)
@@ -107,9 +69,22 @@ namespace netlist
// FIXME: optimize device (separate address decoder!)
NETLIB_UPDATE(82S16)
{
- if (!m_enq)
+ if (m_CE1Q() || m_CE2Q() || m_CE3Q())
{
- const auto adr(m_addr);
+ // FIXME: Outputs are tristate. This needs to be properly implemented
+ m_DOUTQ.push(1, NLTIME_FROM_NS(20));
+ //for (int i=0; i<8; i++)
+ //m_A[i].inactivate();
+ }
+ else
+ {
+ unsigned int adr = 0;
+ for (std::size_t i=0; i<8; i++)
+ {
+ //m_A[i].activate();
+ adr |= (m_A[i]() << i);
+ }
+
if (!m_WEQ())
{
m_ram[adr >> 6] = (m_ram[adr >> 6]
@@ -126,12 +101,10 @@ namespace netlist
{
m_ram[i] = 0;
}
- m_addr = 0;
- m_enq = 0;
}
- NETLIB_DEVICE_IMPL(82S16, "TTL_82S16", "")
- NETLIB_DEVICE_IMPL(82S16_dip, "TTL_82S16_DIP", "")
+ NETLIB_DEVICE_IMPL(82S16)
+ NETLIB_DEVICE_IMPL(82S16_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_82S16.h b/src/lib/netlist/devices/nld_82S16.h
index 47d6189a79b..d1117246d87 100644
--- a/src/lib/netlist/devices/nld_82S16.h
+++ b/src/lib/netlist/devices/nld_82S16.h
@@ -24,7 +24,7 @@
#ifndef NLD_82S16_H_
#define NLD_82S16_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define TTL_82S16(name) \
NET_REGISTER_DEV(TTL_82S16, name)
diff --git a/src/lib/netlist/devices/nld_9310.cpp b/src/lib/netlist/devices/nld_9310.cpp
index b416015df24..ad752adb605 100644
--- a/src/lib/netlist/devices/nld_9310.cpp
+++ b/src/lib/netlist/devices/nld_9310.cpp
@@ -6,7 +6,7 @@
*/
#include "nld_9310.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
#define MAXCNT 9
@@ -14,7 +14,6 @@ namespace netlist
{
namespace devices
{
- //FIXME: Convert sub devices into NETDEV_DELEGATE logic
NETLIB_OBJECT(9310_subABCD)
{
NETLIB_CONSTRUCTOR(9310_subABCD)
@@ -140,8 +139,8 @@ namespace netlist
NETLIB_RESET(9310)
{
- sub.reset();
- subABCD.reset();
+ sub.do_reset();
+ subABCD.do_reset();
}
NETLIB_RESET(9310_subABCD)
@@ -158,35 +157,32 @@ namespace netlist
NETLIB_UPDATE(9310_sub)
{
- auto cnt(m_cnt);
-
if (m_loadq)
{
- if (cnt < MAXCNT - 1)
+ if (m_cnt < MAXCNT - 1)
{
- ++cnt;
- update_outputs(cnt);
+ ++m_cnt;
+ update_outputs(m_cnt);
}
- else if (cnt == MAXCNT - 1)
+ else if (m_cnt == MAXCNT - 1)
{
- cnt = MAXCNT;
+ m_cnt = MAXCNT;
m_RC.push(m_ent, NLTIME_FROM_NS(20));
m_QA.push(1, NLTIME_FROM_NS(20));
}
else // MAXCNT
{
m_RC.push(0, NLTIME_FROM_NS(20));
- cnt = 0;
- update_outputs_all(cnt, NLTIME_FROM_NS(20));
+ m_cnt = 0;
+ update_outputs_all(m_cnt, NLTIME_FROM_NS(20));
}
}
else
{
- cnt = m_ABCD->read_ABCD();
- m_RC.push(m_ent & (cnt == MAXCNT), NLTIME_FROM_NS(27));
- update_outputs_all(cnt, NLTIME_FROM_NS(22));
+ m_cnt = m_ABCD->read_ABCD();
+ m_RC.push(m_ent & (m_cnt == MAXCNT), NLTIME_FROM_NS(27));
+ update_outputs_all(m_cnt, NLTIME_FROM_NS(22));
}
- m_cnt = cnt;
}
NETLIB_UPDATE(9310)
@@ -227,10 +223,10 @@ namespace netlist
#if 0
// for (int i=0; i<4; i++)
// m_Q[i], (cnt >> i) & 1, delay[i]);
- m_QA.push((cnt >> 0) & 1, out_delay);
- m_QB.push((cnt >> 1) & 1, out_delay);
- m_QC.push((cnt >> 2) & 1, out_delay);
- m_QD.push((cnt >> 3) & 1, out_delay);
+ m_QA, (cnt >> 0) & 1, out_delay);
+ m_QB, (cnt >> 1) & 1, out_delay);
+ m_QC, (cnt >> 2) & 1, out_delay);
+ m_QD, (cnt >> 3) & 1, out_delay);
#else
if ((cnt & 1) == 1)
m_QA.push(1, out_delay);
@@ -266,8 +262,8 @@ namespace netlist
#endif
}
- NETLIB_DEVICE_IMPL(9310, "TTL_9310", "")
- NETLIB_DEVICE_IMPL(9310_dip, "TTL_9310_DIP", "")
+ NETLIB_DEVICE_IMPL(9310)
+ NETLIB_DEVICE_IMPL(9310_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_9310.h b/src/lib/netlist/devices/nld_9310.h
index 65df9c04ce4..02cb45b2d86 100644
--- a/src/lib/netlist/devices/nld_9310.h
+++ b/src/lib/netlist/devices/nld_9310.h
@@ -45,7 +45,7 @@
#ifndef NLD_9310_H_
#define NLD_9310_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define TTL_9310(name, cCLK, cENP, cENT, cCLRQ, cLOADQ, cA, cB, cC, cD) \
NET_REGISTER_DEV(TTL_9310, name) \
diff --git a/src/lib/netlist/devices/nld_9316.cpp b/src/lib/netlist/devices/nld_9316.cpp
index 2b17eabb3ec..7c478fd4b05 100644
--- a/src/lib/netlist/devices/nld_9316.cpp
+++ b/src/lib/netlist/devices/nld_9316.cpp
@@ -6,7 +6,7 @@
*/
#include "nld_9316.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
@@ -20,73 +20,32 @@ namespace netlist
NETLIB_CONSTRUCTOR(9316)
, m_CLK(*this, "CLK", NETLIB_DELEGATE(9316, clk))
, m_ENT(*this, "ENT")
- , m_RC(*this, "RC")
, m_LOADQ(*this, "LOADQ")
+ , m_cnt(*this, "m_cnt", 0)
, m_ENP(*this, "ENP")
, m_CLRQ(*this, "CLRQ")
- , m_A(*this, "A", NETLIB_DELEGATE(9316, abcd))
- , m_B(*this, "B", NETLIB_DELEGATE(9316, abcd))
- , m_C(*this, "C", NETLIB_DELEGATE(9316, abcd))
- , m_D(*this, "D", NETLIB_DELEGATE(9316, abcd))
+ , m_A(*this, "A", NETLIB_DELEGATE(9316, noop))
+ , m_B(*this, "B", NETLIB_DELEGATE(9316, noop))
+ , m_C(*this, "C", NETLIB_DELEGATE(9316, noop))
+ , m_D(*this, "D", NETLIB_DELEGATE(9316, noop))
, m_Q(*this, {{ "QA", "QB", "QC", "QD" }})
- , m_cnt(*this, "m_cnt", 0)
- , m_abcd(*this, "m_abcd", 0)
- , m_loadq(*this, "m_loadq", 0)
- , m_ent(*this, "m_ent", 0)
+ , m_RC(*this, "RC")
{
}
private:
- NETLIB_RESETI()
- {
- m_CLK.set_state(logic_t::STATE_INP_LH);
- m_cnt = 0;
- m_abcd = 0;
- }
-
- NETLIB_UPDATEI()
- {
- const auto CLRQ(m_CLRQ());
- m_ent = m_ENT();
- m_loadq = m_LOADQ();
-
- if (((m_loadq ^ 1) || (m_ent && m_ENP())) && CLRQ)
- {
- m_CLK.activate_lh();
- }
- else
- {
- m_CLK.inactivate();
- if (!CLRQ && (m_cnt>0))
- {
- m_cnt = 0;
- update_outputs_all(m_cnt, NLTIME_FROM_NS(36));
- }
- }
- m_RC.push(m_ent && (m_cnt == MAXCNT), NLTIME_FROM_NS(27));
- }
-
-
- NETLIB_HANDLERI(clk)
- {
- auto cnt = (m_loadq ? m_cnt + 1 : m_abcd) & MAXCNT;
- m_RC.push(m_ent && (cnt == MAXCNT), NLTIME_FROM_NS(27));
- update_outputs_all(cnt, NLTIME_FROM_NS(20));
- m_cnt = cnt;
- }
-
- NETLIB_HANDLERI(abcd)
- {
- m_abcd = static_cast<uint8_t>((m_D() << 3) | (m_C() << 2) | (m_B() << 1) | (m_A() << 0));
- }
+ NETLIB_RESETI();
+ NETLIB_UPDATEI();
+ NETLIB_HANDLERI(clk);
+ NETLIB_HANDLERI(noop) { }
logic_input_t m_CLK;
- logic_input_t m_ENT;
-
- logic_output_t m_RC;
+ logic_input_t m_ENT;
logic_input_t m_LOADQ;
+ state_var<unsigned> m_cnt;
+
logic_input_t m_ENP;
logic_input_t m_CLRQ;
@@ -96,15 +55,12 @@ namespace netlist
logic_input_t m_D;
object_array_t<logic_output_t, 4> m_Q;
+ logic_output_t m_RC;
- /* counter state */
- state_var<unsigned> m_cnt;
- /* cached pins */
- state_var_u8 m_abcd;
- state_var_sig m_loadq;
- state_var_sig m_ent;
- void update_outputs_all(unsigned cnt, netlist_time out_delay) noexcept
+ private:
+ //inline void update_outputs_all(const unsigned &cnt, const netlist_time &out_delay) noexcept
+ inline void update_outputs_all(const unsigned &cnt, const netlist_time &out_delay) noexcept
{
m_Q[0].push((cnt >> 0) & 1, out_delay);
m_Q[1].push((cnt >> 1) & 1, out_delay);
@@ -137,9 +93,63 @@ namespace netlist
}
};
+ NETLIB_RESET(9316)
+ {
+ m_CLK.set_state(logic_t::STATE_INP_LH);
+ m_cnt = 0;
+ }
+
+ NETLIB_HANDLER(9316, clk)
+ {
+ if (m_LOADQ())
+ {
+ ++m_cnt &= MAXCNT;
+ //m_RC.push(m_ENT() && (m_cnt == MAXCNT), NLTIME_FROM_NS(27));
+ if (m_cnt == MAXCNT)
+ {
+ m_RC.push(m_ENT(), NLTIME_FROM_NS(27));
+ update_outputs_all(MAXCNT, NLTIME_FROM_NS(20));
+ }
+ else if (m_cnt == 0)
+ {
+ m_RC.push(0, NLTIME_FROM_NS(27));
+ update_outputs_all(0, NLTIME_FROM_NS(20));
+ }
+ else
+ update_outputs_all(m_cnt, NLTIME_FROM_NS(20));
+ }
+ else
+ {
+ m_cnt = (m_D() << 3) | (m_C() << 2) | (m_B() << 1) | (m_A() << 0);
+ m_RC.push(m_ENT() && (m_cnt == MAXCNT), NLTIME_FROM_NS(27));
+ update_outputs_all(m_cnt, NLTIME_FROM_NS(22));
+ }
+ }
+
+ NETLIB_UPDATE(9316)
+ {
+ const netlist_sig_t CLRQ(m_CLRQ());
+ const netlist_sig_t ENT(m_ENT());
+
+ if (((m_LOADQ() ^ 1) || (ENT && m_ENP())) && CLRQ)
+ {
+ m_CLK.activate_lh();
+ }
+ else
+ {
+ m_CLK.inactivate();
+ if (!CLRQ && (m_cnt>0))
+ {
+ m_cnt = 0;
+ update_outputs_all(m_cnt, NLTIME_FROM_NS(36));
+ }
+ }
+ m_RC.push(ENT && (m_cnt == MAXCNT), NLTIME_FROM_NS(27));
+ }
+
- NETLIB_DEVICE_IMPL(9316, "TTL_9316", "+CLK,+ENP,+ENT,+CLRQ,+LOADQ,+A,+B,+C,+D")
- NETLIB_DEVICE_IMPL(9316_dip, "TTL_9316_DIP", "")
+ NETLIB_DEVICE_IMPL(9316)
+ NETLIB_DEVICE_IMPL(9316_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_9316.h b/src/lib/netlist/devices/nld_9316.h
index 8ab1789d7c7..8deb21dfccd 100644
--- a/src/lib/netlist/devices/nld_9316.h
+++ b/src/lib/netlist/devices/nld_9316.h
@@ -51,7 +51,7 @@
#ifndef NLD_9316_H_
#define NLD_9316_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define TTL_9316(name, cCLK, cENP, cENT, cCLRQ, cLOADQ, cA, cB, cC, cD) \
NET_REGISTER_DEV(TTL_9316, name) \
diff --git a/src/lib/netlist/devices/nld_9322.cpp b/src/lib/netlist/devices/nld_9322.cpp
index abf9bf9f6ef..6c408498be7 100644
--- a/src/lib/netlist/devices/nld_9322.cpp
+++ b/src/lib/netlist/devices/nld_9322.cpp
@@ -6,7 +6,7 @@
*/
#include "nld_9322.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
@@ -105,14 +105,14 @@ namespace netlist
NETLIB_UPDATE(9322)
{
- m_1.update();
- m_2.update();
- m_3.update();
- m_4.update();
+ m_1.update_dev();
+ m_2.update_dev();
+ m_3.update_dev();
+ m_4.update_dev();
}
- NETLIB_DEVICE_IMPL(9322, "TTL_9322", "+SELECT,+A1,+B1,+A2,+B2,+A3,+B3,+A4,+B4,+STROBE")
- NETLIB_DEVICE_IMPL(9322_dip, "TTL_9322_DIP", "")
+ NETLIB_DEVICE_IMPL(9322)
+ NETLIB_DEVICE_IMPL(9322_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_9322.h b/src/lib/netlist/devices/nld_9322.h
index 986c6b9e7f7..7de0f053b05 100644
--- a/src/lib/netlist/devices/nld_9322.h
+++ b/src/lib/netlist/devices/nld_9322.h
@@ -21,7 +21,7 @@
#ifndef NLD_9322_H_
#define NLD_9322_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define TTL_9322(name, cSELECT, cA1, cB1, cA2, cB2, cA3, cB3, cA4, cB4, cSTROBE) \
NET_REGISTER_DEV(TTL_9322, name) \
diff --git a/src/lib/netlist/devices/nld_am2847.cpp b/src/lib/netlist/devices/nld_am2847.cpp
index 825696f0938..5d0c5cb71a3 100644
--- a/src/lib/netlist/devices/nld_am2847.cpp
+++ b/src/lib/netlist/devices/nld_am2847.cpp
@@ -6,7 +6,7 @@
*/
#include "nld_am2847.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
@@ -30,7 +30,7 @@ namespace netlist
logic_input_t m_RC;
logic_input_t m_IN;
- state_array<uint16_t, 5> m_buffer;
+ state_var<uint16_t[5]> m_buffer;
logic_output_t m_OUT;
};
@@ -116,7 +116,7 @@ namespace netlist
/* do nothing */
}
- NETLIB_FUNC_VOID(Am2847_shifter, shift, ())
+ inline NETLIB_FUNC_VOID(Am2847_shifter, shift, (void))
{
uint32_t out = m_buffer[0] & 1;
uint32_t in = (m_RC() ? out : m_IN());
@@ -130,8 +130,8 @@ namespace netlist
m_OUT.push(out, NLTIME_FROM_NS(200));
}
- NETLIB_DEVICE_IMPL(AM2847, "TTL_AM2847", "+CP,+INA,+INB,+INC,+IND,+RCA,+RCB,+RCC,+RCD")
- NETLIB_DEVICE_IMPL(AM2847_dip, "TTL_AM2847_DIP", "")
+ NETLIB_DEVICE_IMPL(AM2847)
+ NETLIB_DEVICE_IMPL(AM2847_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_am2847.h b/src/lib/netlist/devices/nld_am2847.h
index ff4a95b8e81..70d288d3eec 100644
--- a/src/lib/netlist/devices/nld_am2847.h
+++ b/src/lib/netlist/devices/nld_am2847.h
@@ -21,7 +21,7 @@
#ifndef NLD_AM2847_H_
#define NLD_AM2847_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define TTL_AM2847(name, cCP, cINA, cINB, cINC, cIND, cRCA, cRCB, cRCC, cRCD) \
NET_REGISTER_DEV(TTL_AM2847, name) \
diff --git a/src/lib/netlist/devices/nld_dm9314.cpp b/src/lib/netlist/devices/nld_dm9314.cpp
index 93b958de539..fd3b8666078 100644
--- a/src/lib/netlist/devices/nld_dm9314.cpp
+++ b/src/lib/netlist/devices/nld_dm9314.cpp
@@ -6,7 +6,7 @@
*/
#include "nld_dm9314.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
@@ -107,8 +107,8 @@ namespace netlist
}
}
- NETLIB_DEVICE_IMPL(9314, "TTL_9314", "+EQ,+MRQ,+S0Q,+S1Q,+S2Q,+S3Q,+D0,+D1,+D2,+D3")
- NETLIB_DEVICE_IMPL(9314_dip, "TTL_9314_DIP", "")
+ NETLIB_DEVICE_IMPL(9314)
+ NETLIB_DEVICE_IMPL(9314_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_dm9314.h b/src/lib/netlist/devices/nld_dm9314.h
index 59c60591ce7..6188bbef42f 100644
--- a/src/lib/netlist/devices/nld_dm9314.h
+++ b/src/lib/netlist/devices/nld_dm9314.h
@@ -21,7 +21,7 @@
#ifndef NLD_DM9314_H_
#define NLD_DM9314_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define TTL_9314(name, cEQ, cMRQ, cS0Q, cS1Q, cS2Q, cS3Q, cD0, cD1, cD2, cD3) \
NET_REGISTER_DEV(TTL_9314, name) \
diff --git a/src/lib/netlist/devices/nld_dm9334.cpp b/src/lib/netlist/devices/nld_dm9334.cpp
index c08ce53efed..8dceded5390 100644
--- a/src/lib/netlist/devices/nld_dm9334.cpp
+++ b/src/lib/netlist/devices/nld_dm9334.cpp
@@ -6,7 +6,7 @@
*/
#include "nld_dm9334.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
@@ -143,8 +143,8 @@ namespace netlist
m_Q[i].push((q >> i) & 1, delay);
}
- NETLIB_DEVICE_IMPL(9334, "TTL_9334", "+CQ,+EQ,+D,+A0,+A1,+A2")
- NETLIB_DEVICE_IMPL(9334_dip, "TTL_9334_DIP", "")
+ NETLIB_DEVICE_IMPL(9334)
+ NETLIB_DEVICE_IMPL(9334_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_dm9334.h b/src/lib/netlist/devices/nld_dm9334.h
index e54208e3ba4..1a07e051333 100644
--- a/src/lib/netlist/devices/nld_dm9334.h
+++ b/src/lib/netlist/devices/nld_dm9334.h
@@ -65,7 +65,7 @@
#ifndef NLD_DM9334_H_
#define NLD_DM9334_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define TTL_9334(name, cCQ, cEQ, cD, cA0, cA1, cA2) \
NET_REGISTER_DEV(TTL_9334, name) \
diff --git a/src/lib/netlist/devices/nld_legacy.cpp b/src/lib/netlist/devices/nld_legacy.cpp
index 738230646e0..28fe0ad8188 100644
--- a/src/lib/netlist/devices/nld_legacy.cpp
+++ b/src/lib/netlist/devices/nld_legacy.cpp
@@ -6,7 +6,7 @@
*/
#include "nld_legacy.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
@@ -25,7 +25,7 @@ namespace netlist
NETLIB_RESETI();
NETLIB_UPDATEI();
- private:
+ protected:
logic_input_t m_S;
logic_input_t m_R;
@@ -49,7 +49,7 @@ namespace netlist
NETLIB_RESETI();
NETLIB_UPDATEI();
- private:
+ protected:
logic_input_t m_I;
logic_output_t m_Q;
@@ -100,8 +100,8 @@ namespace netlist
m_last = nval;
}
- NETLIB_DEVICE_IMPL(nicRSFF, "NETDEV_RSFF", "")
- NETLIB_DEVICE_IMPL(nicDelay, "NETDEV_DELAY", "")
+ NETLIB_DEVICE_IMPL(nicRSFF)
+ NETLIB_DEVICE_IMPL(nicDelay)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_legacy.h b/src/lib/netlist/devices/nld_legacy.h
index aa3aec6f147..33f7d0caaf8 100644
--- a/src/lib/netlist/devices/nld_legacy.h
+++ b/src/lib/netlist/devices/nld_legacy.h
@@ -13,7 +13,7 @@
#ifndef NLD_LEGACY_H_
#define NLD_LEGACY_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
// ----------------------------------------------------------------------------------------
// Macros
diff --git a/src/lib/netlist/devices/nld_log.cpp b/src/lib/netlist/devices/nld_log.cpp
index 6b1b3d8efc1..29218aaa09a 100644
--- a/src/lib/netlist/devices/nld_log.cpp
+++ b/src/lib/netlist/devices/nld_log.cpp
@@ -5,10 +5,10 @@
*
*/
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
+#include "../plib/pstream.h"
+#include "../plib/pfmtlog.h"
#include "nld_log.h"
-#include "plib/pfmtlog.h"
-#include "plib/pstream.h"
//#include "sound/wavwrite.h"
namespace netlist
@@ -19,15 +19,15 @@ namespace netlist
{
NETLIB_CONSTRUCTOR(log)
, m_I(*this, "I")
- , m_strm(pstring(plib::pfmt("{1}.log")(this->name())))
- , m_writer(&m_strm)
+ , m_strm(plib::pfmt("{1}.log")(this->name()))
+ , m_writer(m_strm)
{
}
NETLIB_UPDATEI()
{
/* use pstring::sprintf, it is a LOT faster */
- m_writer.writeline(plib::pfmt("{1:.9} {2}").e(exec().time().as_double()).e(static_cast<double>(m_I())));
+ m_writer.writeline(plib::pfmt("{1:.9} {2}").e(netlist().time().as_double()).e(static_cast<double>(m_I())));
}
NETLIB_RESETI() { }
@@ -46,7 +46,7 @@ namespace netlist
NETLIB_UPDATEI()
{
- m_writer.writeline(plib::pfmt("{1:.9} {2}").e(exec().time().as_double()).e(static_cast<double>(m_I() - m_I2())));
+ m_writer.writeline(plib::pfmt("{1:.9} {2}").e(netlist().time().as_double()).e(static_cast<double>(m_I() - m_I2())));
}
NETLIB_RESETI() { }
@@ -89,8 +89,8 @@ namespace netlist
#endif
- NETLIB_DEVICE_IMPL(log, "LOG", "+I")
- NETLIB_DEVICE_IMPL(logD, "LOGD", "+I,+I2")
+ NETLIB_DEVICE_IMPL(log)
+ NETLIB_DEVICE_IMPL(logD)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_log.h b/src/lib/netlist/devices/nld_log.h
index 13c71ea7257..6364022cea2 100644
--- a/src/lib/netlist/devices/nld_log.h
+++ b/src/lib/netlist/devices/nld_log.h
@@ -18,10 +18,10 @@
#ifndef NLD_LOG_H_
#define NLD_LOG_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define LOG(name, cI) \
- NET_REGISTER_DEV(LOG, name) \
+ NET_REGISTER_DEV(??PG, name) \
NET_CONNECT(name, I, cI)
#define LOGD(name, cI, cI2) \
diff --git a/src/lib/netlist/devices/nld_mm5837.cpp b/src/lib/netlist/devices/nld_mm5837.cpp
index f6c2566bd43..e97ae41e437 100644
--- a/src/lib/netlist/devices/nld_mm5837.cpp
+++ b/src/lib/netlist/devices/nld_mm5837.cpp
@@ -6,8 +6,8 @@
*/
#include "nld_mm5837.h"
-#include "netlist/analog/nlid_twoterm.h"
-#include "netlist/solver/nld_matrix_solver.h"
+#include "../solver/nld_matrix_solver.h"
+#include "../analog/nlid_twoterm.h"
#define R_LOW (1000.0)
#define R_HIGH (1000.0)
@@ -69,13 +69,13 @@ namespace netlist
{
//m_V0.initial(0.0);
//m_RV.do_reset();
- m_RV.set_G_V_I(plib::constants<nl_double>::one() / R_LOW, 0.0, 0.0);
+ m_RV.set(NL_FCONST(1.0) / R_LOW, 0.0, 0.0);
m_inc = netlist_time::from_double(1.0 / m_FREQ());
if (m_FREQ() < 24000 || m_FREQ() > 56000)
log().warning(MW_1_FREQUENCY_OUTSIDE_OF_SPECS_1, m_FREQ());
m_shift = 0x1ffff;
- m_is_timestep = m_RV.m_P.net().solver()->has_timestep_devices();
+ m_is_timestep = m_RV.m_P.net().solver()->is_timestep();
}
NETLIB_UPDATE_PARAM(MM5837_dip)
@@ -107,14 +107,14 @@ namespace netlist
// We only need to update the net first if this is a time stepping net
if (m_is_timestep)
- m_RV.update();
- m_RV.set_G_V_I(plib::constants<nl_double>::one() / R, V, plib::constants<nl_double>::zero());
- m_RV.solve_later(NLTIME_FROM_NS(1));
+ m_RV.update_dev();
+ m_RV.set(NL_FCONST(1.0) / R, V, 0.0);
+ m_RV.m_P.schedule_solve_after(NLTIME_FROM_NS(1));
}
}
- NETLIB_DEVICE_IMPL(MM5837_dip, "MM5837_DIP", "")
+ NETLIB_DEVICE_IMPL(MM5837_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_mm5837.h b/src/lib/netlist/devices/nld_mm5837.h
index 8f764aa651f..4af397d9965 100644
--- a/src/lib/netlist/devices/nld_mm5837.h
+++ b/src/lib/netlist/devices/nld_mm5837.h
@@ -19,7 +19,7 @@
#ifndef NLD_MM5837_H_
#define NLD_MM5837_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define MM5837_DIP(name) \
NET_REGISTER_DEV(MM5837_DIP, name)
diff --git a/src/lib/netlist/devices/nld_ne555.cpp b/src/lib/netlist/devices/nld_ne555.cpp
index 5e990d2e974..8795197bd57 100644
--- a/src/lib/netlist/devices/nld_ne555.cpp
+++ b/src/lib/netlist/devices/nld_ne555.cpp
@@ -46,8 +46,8 @@
*/
#include "nld_ne555.h"
-#include "netlist/analog/nlid_twoterm.h"
-#include "netlist/solver/nld_solver.h"
+#include "../analog/nlid_twoterm.h"
+#include "../solver/nld_solver.h"
#define R_OFF (1E20)
#define R_ON (25) // Datasheet states a maximum discharge of 200mA, R = 5V / 0.2
@@ -62,37 +62,31 @@ namespace netlist
, m_R1(*this, "R1")
, m_R2(*this, "R2")
, m_R3(*this, "R3")
- , m_ROUT(*this, "ROUT")
, m_RDIS(*this, "RDIS")
, m_RESET(*this, "RESET") // Pin 4
, m_THRES(*this, "THRESH") // Pin 6
, m_TRIG(*this, "TRIG") // Pin 2
- , m_OUT(*this, "_OUT") // to Pin 3 via ROUT
+ , m_OUT(*this, "OUT") // Pin 3
, m_last_out(*this, "m_last_out", false)
, m_ff(*this, "m_ff", false)
- , m_last_reset(*this, "m_last_reset", false)
{
register_subalias("GND", m_R3.m_N); // Pin 1
register_subalias("CONT", m_R1.m_N); // Pin 5
register_subalias("DISCH", m_RDIS.m_P); // Pin 7
register_subalias("VCC", m_R1.m_P); // Pin 8
- register_subalias("OUT", m_ROUT.m_P); // Pin 3
connect(m_R1.m_N, m_R2.m_P);
- connect(m_R1.m_N, m_R2.m_P);
connect(m_R2.m_N, m_R3.m_P);
connect(m_RDIS.m_N, m_R3.m_N);
- connect(m_OUT, m_ROUT.m_N);
}
NETLIB_UPDATEI();
NETLIB_RESETI();
- private:
+ protected:
analog::NETLIB_SUB(R_base) m_R1;
analog::NETLIB_SUB(R_base) m_R2;
analog::NETLIB_SUB(R_base) m_R3;
- analog::NETLIB_SUB(R_base) m_ROUT;
analog::NETLIB_SUB(R_base) m_RDIS;
logic_input_t m_RESET;
@@ -100,51 +94,52 @@ namespace netlist
analog_input_t m_TRIG;
analog_output_t m_OUT;
+ private:
state_var<bool> m_last_out;
state_var<bool> m_ff;
- state_var<bool> m_last_reset;
- nl_double clamp(const nl_double v, const nl_double a, const nl_double b)
- {
- nl_double ret = v;
- nl_double vcc = m_R1.m_P();
-
- if (ret > vcc - a)
- ret = vcc - a;
- if (ret < b)
- ret = b;
- return ret;
- }
+ inline nl_double clamp(const nl_double v, const nl_double a, const nl_double b);
+
};
NETLIB_OBJECT_DERIVED(NE555_dip, NE555)
{
NETLIB_CONSTRUCTOR_DERIVED(NE555_dip, NE555)
{
- register_subalias("1", "GND"); // Pin 1
- register_subalias("2", "TRIG"); // Pin 2
- register_subalias("3", "OUT"); // Pin 3
- register_subalias("4", "RESET"); // Pin 4
- register_subalias("5", "CONT"); // Pin 5
- register_subalias("6", "THRESH"); // Pin 6
- register_subalias("7", "DISCH"); // Pin 7
- register_subalias("8", "VCC"); // Pin 8
+ register_subalias("1", m_R3.m_N); // Pin 1
+ register_subalias("2", m_TRIG); // Pin 2
+ register_subalias("3", m_OUT); // Pin 3
+ register_subalias("4", m_RESET); // Pin 4
+ register_subalias("5", m_R1.m_N); // Pin 5
+ register_subalias("6", m_THRES); // Pin 6
+ register_subalias("7", m_RDIS.m_P); // Pin 7
+ register_subalias("8", m_R1.m_P); // Pin 8
}
};
+ inline nl_double NETLIB_NAME(NE555)::clamp(const nl_double v, const nl_double a, const nl_double b)
+ {
+ nl_double ret = v;
+ nl_double vcc = m_R1.m_P();
+
+ if (ret > vcc - a)
+ ret = vcc - a;
+ if (ret < b)
+ ret = b;
+ return ret;
+ }
+
NETLIB_RESET(NE555)
{
- m_R1.reset();
- m_R2.reset();
- m_R3.reset();
- m_ROUT.reset();
- m_RDIS.reset();
+ m_R1.do_reset();
+ m_R2.do_reset();
+ m_R3.do_reset();
+ m_RDIS.do_reset();
- /* FIXME make resistances a parameter, properly model other variants */
+ /* FIXME make resistance a parameter, properly model other variants */
m_R1.set_R(5000);
m_R2.set_R(5000);
m_R3.set_R(5000);
- m_ROUT.set_R(20);
m_RDIS.set_R(R_OFF);
m_last_out = true;
@@ -154,47 +149,39 @@ namespace netlist
{
// FIXME: assumes GND is connected to 0V.
- const auto reset = m_RESET();
+ nl_double vt = clamp(m_R2.m_P(), 0.7, 1.4);
+ bool bthresh = (m_THRES() > vt);
+ bool btrig = (m_TRIG() > clamp(m_R2.m_N(), 0.7, 1.4));
- if (!reset && m_last_reset)
+ if (!btrig)
{
- m_ff = false;
+ m_ff = true;
}
- else
+ else if (bthresh)
{
- const nl_double vt = clamp(m_R2.m_P(), 0.7, 1.4);
- const bool bthresh = (m_THRES() > vt);
- const bool btrig = (m_TRIG() > clamp(m_R2.m_N(), 0.7, 1.4));
-
- if (!btrig)
- m_ff = true;
- else if (bthresh)
- m_ff = false;
+ m_ff = false;
}
- const bool out = (!reset ? false : m_ff);
+ bool out = (!m_RESET() ? false : m_ff);
if (m_last_out && !out)
{
- m_RDIS.update();
+ m_RDIS.update_dev();
m_OUT.push(m_R3.m_N());
m_RDIS.set_R(R_ON);
}
else if (!m_last_out && out)
{
- m_RDIS.update();
+ m_RDIS.update_dev();
// FIXME: Should be delayed by 100ns
m_OUT.push(m_R1.m_P());
m_RDIS.set_R(R_OFF);
}
- m_last_reset = reset;
m_last_out = out;
}
- NETLIB_DEVICE_IMPL(NE555, "NE555", "")
- NETLIB_DEVICE_IMPL(NE555_dip, "NE555_DIP", "")
+ NETLIB_DEVICE_IMPL(NE555)
+ NETLIB_DEVICE_IMPL(NE555_dip)
- NETLIB_DEVICE_IMPL_ALIAS(MC1455P, NE555, "MC1455P", "")
- NETLIB_DEVICE_IMPL_ALIAS(MC1455P_dip, NE555_dip, "MC1455P_DIP", "")
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_ne555.h b/src/lib/netlist/devices/nld_ne555.h
index fc575d914b7..c629253f08f 100644
--- a/src/lib/netlist/devices/nld_ne555.h
+++ b/src/lib/netlist/devices/nld_ne555.h
@@ -4,7 +4,7 @@
#ifndef NLD_NE555_H_
#define NLD_NE555_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define NE555(name) \
NET_REGISTER_DEV(NE555, name)
@@ -12,10 +12,4 @@
#define NE555_DIP(name) \
NET_REGISTER_DEV(NE555_DIP, name)
-#define MC1455P(name) \
- NET_REGISTER_DEV(MC1455P, name)
-
-#define MC1455P_DIP(name) \
- NET_REGISTER_DEV(MC1455P_DIP, name)
-
#endif /* NLD_NE555_H_ */
diff --git a/src/lib/netlist/devices/nld_r2r_dac.cpp b/src/lib/netlist/devices/nld_r2r_dac.cpp
index 284b6673f76..4c29389d491 100644
--- a/src/lib/netlist/devices/nld_r2r_dac.cpp
+++ b/src/lib/netlist/devices/nld_r2r_dac.cpp
@@ -5,9 +5,9 @@
*
*/
-#include "netlist/nl_base.h"
-#include "netlist/analog/nlid_twoterm.h"
-#include "netlist/nl_factory.h"
+#include "../nl_base.h"
+#include "../nl_factory.h"
+#include "../analog/nlid_twoterm.h"
namespace netlist
{
@@ -39,17 +39,17 @@ namespace netlist
NETLIB_UPDATE_PARAM(r2r_dac)
{
- solve_now();
+ update_dev();
double V = m_VIN() / static_cast<double>(1 << m_num())
* static_cast<double>(m_val());
- this->set_G_V_I(1.0 / m_R(), V, 0.0);
+ this->set(1.0 / m_R(), V, 0.0);
}
} //namespace analog
namespace devices {
- NETLIB_DEVICE_IMPL_NS(analog, r2r_dac, "R2R_DAC", "VIN,R,N")
- } // namespace devices
+ NETLIB_DEVICE_IMPL_NS(analog, r2r_dac)
+ }
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_r2r_dac.h b/src/lib/netlist/devices/nld_r2r_dac.h
index 8a4257a3cbf..18e5bddc053 100644
--- a/src/lib/netlist/devices/nld_r2r_dac.h
+++ b/src/lib/netlist/devices/nld_r2r_dac.h
@@ -46,7 +46,7 @@
#ifndef NLD_R2R_DAC_H_
#define NLD_R2R_DAC_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define R2R_DAC(name, p_VIN, p_R, p_N) \
NET_REGISTER_DEV(R2R_DAC, name) \
diff --git a/src/lib/netlist/devices/nld_schmitt.cpp b/src/lib/netlist/devices/nld_schmitt.cpp
index f219d215520..4bc41075f89 100644
--- a/src/lib/netlist/devices/nld_schmitt.cpp
+++ b/src/lib/netlist/devices/nld_schmitt.cpp
@@ -7,10 +7,10 @@
#include "nld_schmitt.h"
-#include "netlist/analog/nlid_twoterm.h"
-#include "netlist/nl_base.h"
-#include "netlist/nl_errstr.h"
-#include "netlist/solver/nld_solver.h"
+#include "../nl_base.h"
+#include "../nl_errstr.h"
+#include "../analog/nlid_twoterm.h"
+#include "../solver/nld_solver.h"
#include <cmath>
@@ -82,11 +82,11 @@ namespace netlist
NETLIB_RESETI()
{
m_last_state = 1;
- m_RVI.reset();
- m_RVO.reset();
+ m_RVI.do_reset();
+ m_RVO.do_reset();
m_is_timestep = m_RVO.m_P.net().solver()->has_timestep_devices();
- m_RVI.set_G_V_I(plib::constants<nl_double>::one() / m_model.m_RI, m_model.m_VI, 0.0);
- m_RVO.set_G_V_I(plib::constants<nl_double>::one() / m_model.m_ROL, m_model.m_VOL, 0.0);
+ m_RVI.set(NL_FCONST(1.0) / m_model.m_RI, m_model.m_VI, 0.0);
+ m_RVO.set(NL_FCONST(1.0) / m_model.m_ROL, m_model.m_VOL, 0.0);
}
NETLIB_UPDATEI()
@@ -97,9 +97,9 @@ namespace netlist
{
m_last_state = 0;
if (m_is_timestep)
- m_RVO.update();
- m_RVO.set_G_V_I(plib::constants<nl_double>::one() / m_model.m_ROH, m_model.m_VOH, 0.0);
- m_RVO.solve_later();
+ m_RVO.update_dev();
+ m_RVO.set(NL_FCONST(1.0) / m_model.m_ROH, m_model.m_VOH, 0.0);
+ m_RVO.m_P.schedule_solve_after(NLTIME_FROM_NS(1));
}
}
else
@@ -108,9 +108,9 @@ namespace netlist
{
m_last_state = 1;
if (m_is_timestep)
- m_RVO.update();
- m_RVO.set_G_V_I(plib::constants<nl_double>::one() / m_model.m_ROL, m_model.m_VOL, 0.0);
- m_RVO.solve_later();
+ m_RVO.update_dev();
+ m_RVO.set(NL_FCONST(1.0) / m_model.m_ROL, m_model.m_VOL, 0.0);
+ m_RVO.m_P.schedule_solve_after(NLTIME_FROM_NS(1));
}
}
}
@@ -125,7 +125,7 @@ namespace netlist
bool m_is_timestep;
};
- NETLIB_DEVICE_IMPL(schmitt_trigger, "SCHMITT_TRIGGER", "MODEL")
+ NETLIB_DEVICE_IMPL(schmitt_trigger)
} // namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_schmitt.h b/src/lib/netlist/devices/nld_schmitt.h
index 20666b29cf7..ecce59be616 100644
--- a/src/lib/netlist/devices/nld_schmitt.h
+++ b/src/lib/netlist/devices/nld_schmitt.h
@@ -11,7 +11,7 @@
#define NLD_SCHMITT_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
// ----------------------------------------------------------------------------------------
// Macros
diff --git a/src/lib/netlist/devices/nld_system.cpp b/src/lib/netlist/devices/nld_system.cpp
index 03aa5c678f1..eabc4b4fbff 100644
--- a/src/lib/netlist/devices/nld_system.cpp
+++ b/src/lib/netlist/devices/nld_system.cpp
@@ -5,8 +5,8 @@
*
*/
-#include "netlist/solver/nld_solver.h"
-#include "netlist/solver/nld_matrix_solver.h"
+#include "../solver/nld_solver.h"
+#include "../solver/nld_matrix_solver.h"
#include "nlid_system.h"
namespace netlist
@@ -40,40 +40,54 @@ namespace netlist
{
m_cnt = 0;
m_off = netlist_time::from_double(m_offset());
- m_feedback.m_delegate = NETLIB_DELEGATE(extclock, update);
-
- //m_feedback.m_delegate .set(&NETLIB_NAME(extclock)::update, this);
//m_Q.initial(0);
}
- NETLIB_HANDLER(extclock, clk2)
+ NETLIB_UPDATE(extclock)
{
- m_Q.push((m_cnt & 1) ^ 1, m_inc[m_cnt]);
+ m_Q.push((m_cnt & 1) ^ 1, m_inc[m_cnt] + m_off);
+ m_off = netlist_time::zero();
if (++m_cnt >= m_size)
m_cnt = 0;
}
- NETLIB_HANDLER(extclock, clk2_pow2)
+ // ----------------------------------------------------------------------------------------
+ // logic_input
+ // ----------------------------------------------------------------------------------------
+
+ NETLIB_RESET(logic_input)
{
- m_Q.push((m_cnt & 1) ^ 1, m_inc[m_cnt]);
- m_cnt = (++m_cnt) & (m_size-1);
+ m_Q.initial(0);
}
- NETLIB_UPDATE(extclock)
+ NETLIB_UPDATE(logic_input)
{
- m_Q.push((m_cnt & 1) ^ 1, m_inc[m_cnt] + m_off);
- m_off = netlist_time::zero();
- if (++m_cnt >= m_size)
- m_cnt = 0;
+ m_Q.push(m_IN() & 1, netlist_time::from_nsec(1));
+ }
- // continue with optimized clock handlers ....
+ NETLIB_UPDATE_PARAM(logic_input)
+ {
+ }
+
+ // ----------------------------------------------------------------------------------------
+ // analog_input
+ // ----------------------------------------------------------------------------------------
- if ((m_size & (m_size-1)) == 0) // power of 2?
- m_feedback.m_delegate.set(&NETLIB_NAME(extclock)::clk2_pow2, this);
- else
- m_feedback.m_delegate.set(&NETLIB_NAME(extclock)::clk2, this);
+ NETLIB_RESET(analog_input)
+ {
+ m_Q.initial(0.0);
}
+ NETLIB_UPDATE(analog_input)
+ {
+ m_Q.push(m_IN());
+ }
+
+ NETLIB_UPDATE_PARAM(analog_input)
+ {
+ }
+
+
// -----------------------------------------------------------------------------
// nld_res_sw
// -----------------------------------------------------------------------------
@@ -92,10 +106,19 @@ namespace netlist
m_last_state = state;
const nl_double 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();
+ // 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())
+ {
+ m_R.update_dev();
+ m_R.set_R(R);
+ m_R.m_P.schedule_solve_after(NLTIME_FROM_NS(1));
+ }
+ else
+ {
+ m_R.set_R(R);
+ m_R.m_P.schedule_solve_after(NLTIME_FROM_NS(1));
+ //m_R->update_dev();
+ }
}
}
@@ -118,19 +141,17 @@ namespace netlist
}
- 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(extclock, "EXTCLOCK", "FREQ,PATTERN")
- NETLIB_DEVICE_IMPL(res_sw, "RES_SWITCH", "+IN,+P1,+P2")
- NETLIB_DEVICE_IMPL(mainclock, "MAINCLOCK", "FREQ")
- NETLIB_DEVICE_IMPL(gnd, "GND", "")
- NETLIB_DEVICE_IMPL(netlistparams, "PARAMETER", "")
-
- NETLIB_DEVICE_IMPL(logic_input, "LOGIC_INPUT", "IN,FAMILY")
- NETLIB_DEVICE_IMPL_ALIAS(logic_input_ttl, logic_input, "TTL_INPUT", "IN")
+ NETLIB_DEVICE_IMPL(dummy_input)
+ NETLIB_DEVICE_IMPL(frontier)
+ NETLIB_DEVICE_IMPL(function)
+ NETLIB_DEVICE_IMPL(logic_input)
+ NETLIB_DEVICE_IMPL(analog_input)
+ NETLIB_DEVICE_IMPL(clock)
+ NETLIB_DEVICE_IMPL(extclock)
+ NETLIB_DEVICE_IMPL(res_sw)
+ NETLIB_DEVICE_IMPL(mainclock)
+ NETLIB_DEVICE_IMPL(gnd)
+ NETLIB_DEVICE_IMPL(netlistparams)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_system.h b/src/lib/netlist/devices/nld_system.h
index 5158e098cfa..69a7c75dbf3 100644
--- a/src/lib/netlist/devices/nld_system.h
+++ b/src/lib/netlist/devices/nld_system.h
@@ -9,7 +9,7 @@
#ifndef NLD_SYSTEM_H_
#define NLD_SYSTEM_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
// -----------------------------------------------------------------------------
// Macros
diff --git a/src/lib/netlist/devices/nld_tms4800.cpp b/src/lib/netlist/devices/nld_tms4800.cpp
index 24729b10e72..29a9bd836ab 100644
--- a/src/lib/netlist/devices/nld_tms4800.cpp
+++ b/src/lib/netlist/devices/nld_tms4800.cpp
@@ -6,7 +6,7 @@
*/
#include "nld_tms4800.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
@@ -39,9 +39,9 @@ namespace netlist
param_rom_t<uint8_t, 11, 8> m_ROM; // 16 Kbits, used as 2 Kbit x 8
};
- NETLIB_OBJECT_DERIVED(TMS4800_dip, TMS4800)
+ NETLIB_OBJECT_DERIVED(tms4800_dip, TMS4800)
{
- NETLIB_CONSTRUCTOR_DERIVED(TMS4800_dip, TMS4800)
+ NETLIB_CONSTRUCTOR_DERIVED(tms4800_dip, TMS4800)
{
register_subalias("2", m_A[0]);
register_subalias("3", m_A[1]);
@@ -97,8 +97,8 @@ namespace netlist
}
}
- NETLIB_DEVICE_IMPL(TMS4800, "ROM_TMS4800", "+AR,+OE1,+OE2,+A0,+A1,+A2,+A3,+A4,+A5,+A6,+A7,+A8,+A9,+A10")
- NETLIB_DEVICE_IMPL(TMS4800_dip, "ROM_TMS4800_DIP", "")
+ NETLIB_DEVICE_IMPL(TMS4800)
+ NETLIB_DEVICE_IMPL(tms4800_dip)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_tms4800.h b/src/lib/netlist/devices/nld_tms4800.h
index c5bcd1337f0..dc72354cb03 100644
--- a/src/lib/netlist/devices/nld_tms4800.h
+++ b/src/lib/netlist/devices/nld_tms4800.h
@@ -28,7 +28,7 @@
#ifndef NLD_TMS4800_H_
#define NLD_TMS4800_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define ROM_TMS4800(name, cAR, cOE1, cOE2, cA0, cA1, cA2, cA3, cA4, cA5, cA6, cA7, cA8, cA9, cA10) \
NET_REGISTER_DEV(ROM_TMS4800, name) \
diff --git a/src/lib/netlist/devices/nld_tristate.cpp b/src/lib/netlist/devices/nld_tristate.cpp
index b05d09ea71e..74fbb206feb 100644
--- a/src/lib/netlist/devices/nld_tristate.cpp
+++ b/src/lib/netlist/devices/nld_tristate.cpp
@@ -6,7 +6,7 @@
*/
#include "nld_tristate.h"
-#include "netlist/nl_base.h"
+#include "../nl_base.h"
namespace netlist
{
@@ -70,8 +70,8 @@ namespace netlist
m_Q.push(q, NLTIME_FROM_NS(1));
}
- NETLIB_DEVICE_IMPL(tristate, "TTL_TRISTATE", "+CEQ1,+D1,+CEQ2,+D2")
- NETLIB_DEVICE_IMPL(tristate3, "TTL_TRISTATE3", "")
+ NETLIB_DEVICE_IMPL(tristate)
+ NETLIB_DEVICE_IMPL(tristate3)
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nld_tristate.h b/src/lib/netlist/devices/nld_tristate.h
index 71f97d9812d..a5ff22fac96 100644
--- a/src/lib/netlist/devices/nld_tristate.h
+++ b/src/lib/netlist/devices/nld_tristate.h
@@ -10,7 +10,7 @@
#ifndef NLD_TRISTATE_H_
#define NLD_TRISTATE_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#define TTL_TRISTATE(name, cCEQ1, cD1, cCEQ2, cD2) \
NET_REGISTER_DEV(TTL_TRISTATE, name) \
diff --git a/src/lib/netlist/devices/nlid_cmos.h b/src/lib/netlist/devices/nlid_cmos.h
index d91d691453a..f9999aebcc0 100644
--- a/src/lib/netlist/devices/nlid_cmos.h
+++ b/src/lib/netlist/devices/nlid_cmos.h
@@ -8,8 +8,8 @@
#ifndef NLID_CMOS_H_
#define NLID_CMOS_H_
-#include "netlist/nl_base.h"
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
+#include "../nl_base.h"
namespace netlist
{
diff --git a/src/lib/netlist/devices/nlid_proxy.cpp b/src/lib/netlist/devices/nlid_proxy.cpp
index a2fd18e85a7..4c3ec6f67aa 100644
--- a/src/lib/netlist/devices/nlid_proxy.cpp
+++ b/src/lib/netlist/devices/nlid_proxy.cpp
@@ -6,7 +6,7 @@
*/
#include "nlid_proxy.h"
-#include "netlist/solver/nld_solver.h"
+#include "../solver/nld_solver.h"
//#include "plib/pstream.h"
//#include "plib/pfmtlog.h"
//#include "nld_log.h"
@@ -20,7 +20,7 @@ namespace netlist
// nld_base_proxy
// -----------------------------------------------------------------------------
- nld_base_proxy::nld_base_proxy(netlist_state_t &anetlist, const pstring &name,
+ nld_base_proxy::nld_base_proxy(netlist_t &anetlist, const pstring &name,
logic_t *inout_proxied, detail::core_terminal_t *proxy_inout)
: device_t(anetlist, name)
{
@@ -29,23 +29,33 @@ namespace netlist
m_proxy_term = proxy_inout;
}
+ nld_base_proxy::~nld_base_proxy()
+ {
+ }
+
// ----------------------------------------------------------------------------------------
// nld_a_to_d_proxy
// ----------------------------------------------------------------------------------------
- nld_base_a_to_d_proxy::nld_base_a_to_d_proxy(netlist_state_t &anetlist, const pstring &name,
+ nld_base_a_to_d_proxy::nld_base_a_to_d_proxy(netlist_t &anetlist, const pstring &name,
logic_input_t *in_proxied, detail::core_terminal_t *in_proxy)
: nld_base_proxy(anetlist, name, in_proxied, in_proxy)
, m_Q(*this, "Q")
{
}
- nld_a_to_d_proxy::nld_a_to_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *in_proxied)
+ nld_base_a_to_d_proxy::~nld_base_a_to_d_proxy() {}
+
+ nld_a_to_d_proxy::nld_a_to_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *in_proxied)
: nld_base_a_to_d_proxy(anetlist, name, in_proxied, &m_I)
, m_I(*this, "I")
{
}
+ nld_a_to_d_proxy::~nld_a_to_d_proxy()
+ {
+ }
+
NETLIB_RESET(a_to_d_proxy)
{
}
@@ -71,32 +81,39 @@ namespace netlist
// nld_d_to_a_proxy
// ----------------------------------------------------------------------------------------
- nld_base_d_to_a_proxy::nld_base_d_to_a_proxy(netlist_state_t &anetlist, const pstring &name,
+ nld_base_d_to_a_proxy::nld_base_d_to_a_proxy(netlist_t &anetlist, const pstring &name,
logic_output_t *out_proxied, detail::core_terminal_t &proxy_out)
: nld_base_proxy(anetlist, name, out_proxied, &proxy_out)
, m_I(*this, "I")
{
}
- nld_d_to_a_proxy::nld_d_to_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *out_proxied)
+ nld_base_d_to_a_proxy::~nld_base_d_to_a_proxy()
+ {
+ }
+
+ nld_d_to_a_proxy::nld_d_to_a_proxy(netlist_t &anetlist, const pstring &name, logic_output_t *out_proxied)
: nld_base_d_to_a_proxy(anetlist, name, out_proxied, m_RV.m_P)
, m_GNDHack(*this, "_Q")
, m_RV(*this, "RV")
, m_last_state(*this, "m_last_var", -1)
, m_is_timestep(false)
{
- const std::vector<std::pair<pstring, pstring>> power_syms = { {"VCC", "VEE"}, {"VCC", "GND"}, {"VDD", "VSS"}};
+ const pstring power_syms[3][2] ={ {"VCC", "VEE"}, {"VCC", "GND"}, {"VDD", "VSS"}};
+ //register_sub(m_RV);
+ //register_term("1", m_RV.m_P);
+ //register_term("2", m_RV.m_N);
register_subalias("Q", m_RV.m_P);
connect(m_RV.m_N, m_GNDHack);
bool f = false;
- for (auto & pwr_sym : power_syms)
+ for (int i = 0; i < 3; i++)
{
pstring devname = out_proxied->device().name();
- auto tp = setup().find_terminal(devname + "." + pwr_sym.first,
+ auto tp = netlist().setup().find_terminal(devname + "." + power_syms[i][0],
detail::terminal_type::INPUT, false);
- auto tn = setup().find_terminal(devname + "." + pwr_sym.second,
+ auto tn = netlist().setup().find_terminal(devname + "." + power_syms[i][1],
detail::terminal_type::INPUT, false);
if (tp != nullptr && tn != nullptr)
{
@@ -109,6 +126,11 @@ namespace netlist
log().warning(MW_1_NO_POWER_TERMINALS_ON_DEVICE_1, out_proxied->device().name());
else
log().verbose("D/A Proxy: Found power terminals on device {1}", out_proxied->device().name());
+#if (0)
+ printf("%s %s\n", out_proxied->name().c_str(), out_proxied->device().name().c_str());
+ auto x = netlist().setup().find_terminal(out_proxied->name(), detail::device_object_t::terminal_type::OUTPUT, false);
+ if (x) printf("==> %s\n", x->name().c_str());
+#endif
}
@@ -120,15 +142,15 @@ namespace netlist
//m_Q.initial(0.0);
m_last_state = -1;
- m_RV.reset();
+ m_RV.do_reset();
m_is_timestep = m_RV.m_P.net().solver()->has_timestep_devices();
- m_RV.set_G_V_I(plib::constants<nl_double>::one() / logic_family()->R_low(),
+ m_RV.set(NL_FCONST(1.0) / logic_family()->R_low(),
logic_family()->low_V(0.0, supply_V), 0.0);
}
NETLIB_UPDATE(d_to_a_proxy)
{
- const auto state = static_cast<int>(m_I());
+ const int state = static_cast<int>(m_I());
if (state != m_last_state)
{
// FIXME: Variable voltage
@@ -141,10 +163,10 @@ namespace netlist
// We only need to update the net first if this is a time stepping net
if (m_is_timestep)
{
- m_RV.update();
+ m_RV.update_dev();
}
- m_RV.set_G_V_I(plib::constants<nl_double>::one() / R, V, 0.0);
- m_RV.solve_later();
+ m_RV.set(NL_FCONST(1.0) / R, V, 0.0);
+ m_RV.m_P.schedule_solve_after(NLTIME_FROM_NS(1));
}
}
diff --git a/src/lib/netlist/devices/nlid_proxy.h b/src/lib/netlist/devices/nlid_proxy.h
index 9543b8db234..821cfa56d9d 100644
--- a/src/lib/netlist/devices/nlid_proxy.h
+++ b/src/lib/netlist/devices/nlid_proxy.h
@@ -11,8 +11,8 @@
#ifndef NLID_PROXY_H_
#define NLID_PROXY_H_
-#include "netlist/analog/nlid_twoterm.h"
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
+#include "../analog/nlid_twoterm.h"
namespace netlist
{
@@ -26,9 +26,11 @@ namespace netlist
NETLIB_OBJECT(base_proxy)
{
public:
- nld_base_proxy(netlist_state_t &anetlist, const pstring &name,
+ nld_base_proxy(netlist_t &anetlist, const pstring &name,
logic_t *inout_proxied, detail::core_terminal_t *proxy_inout);
+ virtual ~nld_base_proxy();
+
logic_t &term_proxied() const { return *m_term_proxied; }
detail::core_terminal_t &proxy_term() const { return *m_proxy_term; }
@@ -47,11 +49,13 @@ namespace netlist
{
public:
+ virtual ~nld_base_a_to_d_proxy();
+
virtual logic_output_t &out() { return m_Q; }
protected:
- nld_base_a_to_d_proxy(netlist_state_t &anetlist, const pstring &name,
+ nld_base_a_to_d_proxy(netlist_t &anetlist, const pstring &name,
logic_input_t *in_proxied, detail::core_terminal_t *in_proxy);
private:
@@ -63,7 +67,9 @@ namespace netlist
NETLIB_OBJECT_DERIVED(a_to_d_proxy, base_a_to_d_proxy)
{
public:
- nld_a_to_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *in_proxied);
+ nld_a_to_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *in_proxied);
+
+ virtual ~nld_a_to_d_proxy() override;
analog_input_t m_I;
@@ -82,20 +88,24 @@ namespace netlist
NETLIB_OBJECT_DERIVED(base_d_to_a_proxy, base_proxy)
{
public:
+ virtual ~nld_base_d_to_a_proxy();
virtual logic_input_t &in() { return m_I; }
protected:
- nld_base_d_to_a_proxy(netlist_state_t &anetlist, const pstring &name,
+ nld_base_d_to_a_proxy(netlist_t &anetlist, const pstring &name,
logic_output_t *out_proxied, detail::core_terminal_t &proxy_out);
logic_input_t m_I;
+
+ private:
};
NETLIB_OBJECT_DERIVED(d_to_a_proxy, base_d_to_a_proxy)
{
public:
- nld_d_to_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *out_proxied);
+ nld_d_to_a_proxy(netlist_t &anetlist, const pstring &name, logic_output_t *out_proxied);
+ virtual ~nld_d_to_a_proxy() override {}
protected:
diff --git a/src/lib/netlist/devices/nlid_system.h b/src/lib/netlist/devices/nlid_system.h
index f1f2af1b31e..326cd3dbf2c 100644
--- a/src/lib/netlist/devices/nlid_system.h
+++ b/src/lib/netlist/devices/nlid_system.h
@@ -11,10 +11,10 @@
#ifndef NLID_SYSTEM_H_
#define NLID_SYSTEM_H_
-#include "netlist/analog/nlid_twoterm.h"
-#include "netlist/nl_base.h"
-#include "netlist/nl_setup.h"
-#include "plib/putil.h"
+#include "../nl_base.h"
+#include "../nl_setup.h"
+#include "../analog/nlid_twoterm.h"
+#include "../plib/putil.h"
namespace netlist
{
@@ -27,8 +27,7 @@ namespace netlist
NETLIB_OBJECT(netlistparams)
{
NETLIB_CONSTRUCTOR(netlistparams)
- , m_use_deactivate(*this, "USE_DEACTIVATE", false)
- , m_startup_strategy(*this, "STARTUP_STRATEGY", 1)
+ , m_use_deactivate(*this, "USE_DEACTIVATE", 0)
{
}
NETLIB_UPDATEI() { }
@@ -36,7 +35,6 @@ namespace netlist
//NETLIB_UPDATE_PARAMI() { }
public:
param_logic_t m_use_deactivate;
- param_int_t m_startup_strategy;
};
// -----------------------------------------------------------------------------
@@ -54,7 +52,7 @@ namespace netlist
NETLIB_RESETI()
{
- m_Q.net().set_next_scheduled_time(netlist_time::zero());
+ m_Q.net().set_time(netlist_time::zero());
}
NETLIB_UPDATE_PARAMI()
@@ -67,14 +65,16 @@ namespace netlist
logic_net_t &net = m_Q.net();
// this is only called during setup ...
net.toggle_new_Q();
- net.set_next_scheduled_time(exec().time() + m_inc);
+ net.set_time(netlist().time() + m_inc);
}
public:
logic_output_t m_Q;
- netlist_time m_inc;
- private:
+
param_double_t m_freq;
+ netlist_time m_inc;
+
+ inline static void mc_update(logic_net_t &net);
};
// -----------------------------------------------------------------------------
@@ -96,7 +96,7 @@ namespace netlist
//NETLIB_RESETI();
NETLIB_UPDATE_PARAMI();
- private:
+ protected:
logic_input_t m_feedback;
logic_output_t m_Q;
@@ -127,35 +127,31 @@ namespace netlist
std::vector<pstring> pat(plib::psplit(m_pattern(),","));
m_off = netlist_time::from_double(m_offset());
- std::array<std::int64_t, 32> pati = { 0 };
-
+ unsigned long pati[32];
+ for (int pI = 0; pI < 32; pI++)
+ {
+ pati[pI] = 0;
+ }
m_size = static_cast<std::uint8_t>(pat.size());
- netlist_time::mult_type total = 0;
+ unsigned long total = 0;
for (unsigned i=0; i<m_size; i++)
{
- // FIXME: use pstonum_ne
- //pati[i] = plib::pstonum<decltype(pati[i])>(pat[i]);
- pati[i] = plib::pstonum<std::int64_t>(pat[i]);
+ pati[i] = static_cast<unsigned long>(pat[i].as_long());
total += pati[i];
}
netlist_time ttotal = netlist_time::zero();
- auto sm1 = static_cast<uint8_t>(m_size - 1);
- for (unsigned i=0; i < sm1; i++)
+ for (unsigned i=0; i<m_size - 1; i++)
{
m_inc[i] = base * pati[i];
ttotal += m_inc[i];
}
- m_inc[sm1] = base * total - ttotal;
+ m_inc[m_size - 1] = base * total - ttotal;
}
}
NETLIB_UPDATEI();
NETLIB_RESETI();
//NETLIB_UPDATE_PARAMI();
-
- NETLIB_HANDLERI(clk2);
- NETLIB_HANDLERI(clk2_pow2);
-
- private:
+ protected:
param_double_t m_freq;
param_str_t m_pattern;
@@ -166,7 +162,7 @@ namespace netlist
state_var_u8 m_cnt;
std::uint8_t m_size;
state_var<netlist_time> m_off;
- std::array<netlist_time, 32> m_inc;
+ netlist_time m_inc[32];
};
// -----------------------------------------------------------------------------
@@ -177,19 +173,20 @@ namespace netlist
{
NETLIB_CONSTRUCTOR(logic_input)
, m_Q(*this, "Q")
- , m_IN(*this, "IN", false)
+ , m_IN(*this, "IN", 0)
/* make sure we get the family first */
, m_FAMILY(*this, "FAMILY", "FAMILY(TYPE=TTL)")
{
set_logic_family(setup().family_from_model(m_FAMILY()));
- m_Q.set_logic_family(this->logic_family());
}
- NETLIB_UPDATEI() { }
- NETLIB_RESETI() { m_Q.initial(0); }
- NETLIB_UPDATE_PARAMI() { m_Q.push(m_IN() & 1, netlist_time::from_nsec(1)); }
+ NETLIB_UPDATE_AFTER_PARAM_CHANGE()
- private:
+ NETLIB_UPDATEI();
+ NETLIB_RESETI();
+ NETLIB_UPDATE_PARAMI();
+
+ protected:
logic_output_t m_Q;
param_logic_t m_IN;
@@ -203,12 +200,12 @@ namespace netlist
, m_IN(*this, "IN", 0.0)
{
}
+ NETLIB_UPDATE_AFTER_PARAM_CHANGE()
- NETLIB_UPDATEI() { }
- NETLIB_RESETI() { m_Q.initial(0.0); }
- NETLIB_UPDATE_PARAMI() { m_Q.push(m_IN()); }
-
- private:
+ NETLIB_UPDATEI();
+ NETLIB_RESETI();
+ NETLIB_UPDATE_PARAMI();
+ protected:
analog_output_t m_Q;
param_double_t m_IN;
};
@@ -281,8 +278,8 @@ namespace netlist
NETLIB_RESETI()
{
- m_RIN.set_G_V_I(1.0 / m_p_RIN(),0,0);
- m_ROUT.set_G_V_I(1.0 / m_p_ROUT(),0,0);
+ m_RIN.set(1.0 / m_p_RIN(),0,0);
+ m_ROUT.set(1.0 / m_p_ROUT(),0,0);
}
NETLIB_UPDATEI()
@@ -313,13 +310,13 @@ namespace netlist
, m_N(*this, "N", 1)
, m_func(*this, "FUNC", "A0")
, m_Q(*this, "Q")
- , m_compiled(this->name() + ".FUNCC", this, this->state().run_state_manager())
+ , m_compiled(this->name() + ".FUNCC", this, this->netlist().state())
{
std::vector<pstring> inps;
for (int i=0; i < m_N(); i++)
{
pstring n = plib::pfmt("A{1}")(i);
- m_I.push_back(pool().make_poolptr<analog_input_t>(*this, n));
+ m_I.push_back(plib::make_unique<analog_input_t>(*this, n));
inps.push_back(n);
m_vals.push_back(0.0);
}
@@ -336,7 +333,7 @@ namespace netlist
param_int_t m_N;
param_str_t m_func;
analog_output_t m_Q;
- std::vector<pool_owned_ptr<analog_input_t>> m_I;
+ std::vector<std::unique_ptr<analog_input_t>> m_I;
std::vector<double> m_vals;
plib::pfunction m_compiled;
@@ -360,17 +357,16 @@ namespace netlist
register_subalias("2", m_R.m_N);
}
- NETLIB_RESETI();
- //NETLIB_UPDATE_PARAMI();
- NETLIB_UPDATEI();
-
analog::NETLIB_SUB(R_base) m_R;
logic_input_t m_I;
param_double_t m_RON;
param_double_t m_ROFF;
- private:
+ NETLIB_RESETI();
+ //NETLIB_UPDATE_PARAMI();
+ NETLIB_UPDATEI();
+ private:
state_var<netlist_sig_t> m_last_state;
};
diff --git a/src/lib/netlist/devices/nlid_truthtable.cpp b/src/lib/netlist/devices/nlid_truthtable.cpp
index 2221d855880..bf7d03fe3d7 100644
--- a/src/lib/netlist/devices/nlid_truthtable.cpp
+++ b/src/lib/netlist/devices/nlid_truthtable.cpp
@@ -6,9 +6,9 @@
*/
#include "nlid_truthtable.h"
-#include "netlist/nl_setup.h"
-#include "plib/palloc.h"
-#include "plib/plists.h"
+#include "../plib/plists.h"
+#include "../nl_setup.h"
+#include "../plib/palloc.h"
#include <bitset>
@@ -24,7 +24,7 @@ namespace netlist
template <typename T>
struct sbitset
{
- using type = T;
+ typedef T type;
sbitset() : m_bs(0) { }
/* explicit */ sbitset(T v) : m_bs(v) { }
@@ -77,8 +77,8 @@ namespace netlist
return ret;
}
- static constexpr const sbitset all_bits() noexcept { return sbitset(~static_cast<T>(0)); }
- static constexpr const sbitset no_bits() noexcept{ return sbitset(static_cast<T>(0)); }
+ static constexpr sbitset all_bits() { return sbitset(~static_cast<T>(0)); }
+ static constexpr sbitset no_bits() { return sbitset(static_cast<T>(0)); }
private:
T m_bs;
};
@@ -122,18 +122,8 @@ namespace netlist
}
}
- uint_least64_t mask() const
- {
- switch (m_size)
- {
- case 8: return static_cast<uint_least8_t>(-1);
- case 16: return static_cast<uint_least16_t>(-1);
- case 32: return static_cast<uint_least32_t>(-1);
- case 64: return static_cast<uint_least64_t>(-1);
- default:
- return 0; //should never happen
- }
- }
+ uint_least64_t mask() const { return static_cast<uint_least64_t>(-1); }
+
private:
void *m_data;
size_t m_size;
@@ -144,7 +134,7 @@ namespace netlist
truthtable_parser(unsigned NO, unsigned NI, bool *initialized,
packed_int outs, uint_least8_t *timing, netlist_time *timing_nt)
: m_NO(NO), m_NI(NI), m_initialized(initialized),
- m_out_state(outs), m_timing(timing), m_timing_nt(timing_nt),
+ m_outs(outs), m_timing(timing), m_timing_nt(timing_nt),
m_num_bits(m_NI),
m_size(1 << (m_num_bits))
{
@@ -161,7 +151,7 @@ namespace netlist
unsigned m_NO;
unsigned m_NI;
bool *m_initialized;
- packed_int m_out_state;
+ packed_int m_outs;
uint_least8_t *m_timing;
netlist_time *m_timing_nt;
@@ -188,27 +178,51 @@ namespace netlist
nl_assert_always(io.size() == 2, "too many '|'");
std::vector<pstring> inout(plib::psplit(io[0], ","));
nl_assert_always(inout.size() == m_num_bits, "bitcount wrong");
- std::vector<pstring> outputs(plib::psplit(io[1], ","));
- nl_assert_always(outputs.size() == m_NO, "output count wrong");
+ std::vector<pstring> out(plib::psplit(io[1], ","));
+ nl_assert_always(out.size() == m_NO, "output count wrong");
for (std::size_t i=0; i < m_NI; i++)
{
- inout[i] = plib::trim(inout[i]);
+ inout[i] = inout[i].trim();
m_I.emplace(i, *this, inout[i]);
}
for (std::size_t i=0; i < m_NO; i++)
{
- outputs[i] = plib::trim(outputs[i]);
- m_Q.emplace(i, *this, outputs[i]);
- // Connect output "Q" to input "_Q" if this exists
- // This enables timed state without having explicit state ....
- pstring tmp = "_" + outputs[i];
+ out[i] = out[i].trim();
+ m_Q.emplace(i, *this, out[i]);
+ }
+ // Connect output "Q" to input "_Q" if this exists
+ // This enables timed state without having explicit state ....
+ tt_bitset disabled_ignore = 0;
+ for (std::size_t i=0; i < m_NO; i++)
+ {
+ pstring tmp = "_" + out[i];
const std::size_t idx = plib::container::indexof(inout, tmp);
if (idx != plib::container::npos)
+ {
connect(m_Q[i], m_I[idx]);
+ // disable ignore for theses inputs altogether.
+ // FIXME: This shouldn't be necessary
+ disabled_ignore.set(idx);
+ }
}
m_ign = 0;
+
+#if 0
+ for (size_t i=0; i<m_size; i++)
+ {
+ m_ttp.m_outs[i] &= ~(disabled_ignore << m_NO);
+ }
+#endif
+#if 0
+ printf("%s\n", name().c_str());
+ for (int j=0; j < m_size; j++)
+ printf("%05x %04x %04x %04x\n", j, m_ttp->m_outs[j] & ((1 << m_NO)-1),
+ m_ttp->m_outs[j] >> m_NO, m_ttp->m_timing[j * m_NO + 0]);
+ for (int k=0; m_ttp->m_timing_nt[k] != netlist_time::zero(); k++)
+ printf("%d %f\n", k, m_ttp->m_timing_nt[k].as_double() * 1000000.0);
+#endif
}
// ----------------------------------------------------------------------------------------
@@ -224,20 +238,15 @@ namespace netlist
: netlist_base_factory_truthtable_t(name, classname, def_param, sourcefile)
{ }
- pool_owned_ptr<device_t> Create(netlist_state_t &anetlist, const pstring &name) override
+ plib::owned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) override
{
- using tt_type = nld_truthtable_t<m_NI, m_NO>;
+ typedef nld_truthtable_t<m_NI, m_NO> tt_type;
truthtable_parser desc_s(m_NO, m_NI, &m_ttbl.m_initialized,
- packed_int(m_ttbl.m_out_state.data(), sizeof(m_ttbl.m_out_state[0]) * 8),
- m_ttbl.m_timing_index.data(), m_ttbl.m_timing_nt.data());
+ packed_int(m_ttbl.m_outs, sizeof(m_ttbl.m_outs[0]) * 8),
+ m_ttbl.m_timing, m_ttbl.m_timing_nt);
desc_s.parse(m_desc);
-
- /* update truthtable family definitions */
- if (m_family_name != "")
- m_family_desc = anetlist.setup().family_from_model(m_family_name);
-
- return pool().make_poolptr<tt_type>(anetlist, name, m_family_desc, m_ttbl, m_desc);
+ return plib::owned_ptr<device_t>::Create<tt_type>(anetlist, name, m_family, m_ttbl, m_desc);
}
private:
typename nld_truthtable_t<m_NI, m_NO>::truthtable_t m_ttbl;
@@ -250,7 +259,7 @@ namespace netlist
for (std::size_t j=0; j<m_NI; j++)
{
// if changing the input directly doesn't change outputs we can ignore
- if (m_out_state[state] == m_out_state[tt_bitset(state).set(j)])
+ if (m_outs[state] == m_outs[tt_bitset(state).set(j)])
ignore.set(j);
}
@@ -276,7 +285,7 @@ namespace netlist
{
tt_bitset b = tign.expand_and(k);
// will any of the inputs ignored change the output if changed?
- if (m_out_state[state] != m_out_state[(state & tign.invert()) | b])
+ if (m_outs[state] != m_outs[(state & tign.invert()) | b])
{
t[j] = true;
break;
@@ -309,21 +318,21 @@ namespace netlist
void truthtable_parser::parseline(unsigned cur, std::vector<pstring> list,
tt_bitset state, uint_least64_t val, std::vector<uint_least8_t> &timing_index)
{
- pstring elem = plib::trim(list[cur]);
+ pstring elem = list[cur].trim();
uint_least64_t start = 0;
uint_least64_t end = 0;
- if (elem == "0")
+ if (elem.equals("0"))
{
start = 0;
end = 0;
}
- else if (elem == "1")
+ else if (elem.equals("1"))
{
start = 1;
end = 1;
}
- else if (elem == "X")
+ else if (elem.equals("X"))
{
start = 0;
end = 1;
@@ -343,10 +352,10 @@ void truthtable_parser::parseline(unsigned cur, std::vector<pstring> list,
else
{
// cutoff previous inputs and outputs for ignore
- if (m_out_state[nstate] != m_out_state.mask() && m_out_state[nstate] != val)
- throw nl_exception(plib::pfmt("Error in truthtable: State {1:04} already set, {2} != {3}\n")
- .x(nstate.as_uint())(m_out_state[nstate])(val) );
- m_out_state.set(nstate, val);
+ if (m_outs[nstate] != m_outs.mask() && m_outs[nstate] != val)
+ nl_exception(plib::pfmt("Error in truthtable: State {1:04} already set, {2} != {3}\n")
+ .x(nstate.as_uint())(m_outs[nstate])(val) );
+ m_outs.set(nstate, val);
for (std::size_t j=0; j<m_NO; j++)
m_timing[nstate * m_NO + j] = timing_index[j];
}
@@ -366,12 +375,12 @@ void truthtable_parser::parse(const std::vector<pstring> &truthtable)
line++;
for (unsigned j=0; j < m_size; j++)
- m_out_state.set(j, tt_bitset::all_bits());
+ m_outs.set(j, tt_bitset::all_bits());
for (int j=0; j < 16; j++)
m_timing_nt[j] = netlist_time::zero();
- while (!(ttline == ""))
+ while (!ttline.equals(""))
{
std::vector<pstring> io(plib::psplit(ttline,"|"));
// checks
@@ -393,13 +402,12 @@ void truthtable_parser::parse(const std::vector<pstring> &truthtable)
*/
for (unsigned j=0; j<m_NO; j++)
{
- pstring outs = plib::trim(out[j]);
- if (outs == "1")
+ pstring outs = out[j].trim();
+ if (outs.equals("1"))
val.set(j);
else
- nl_assert_always(outs == "0", "Unknown value (not 0 or 1");
- // FIXME: error handling
- netlist_time t = netlist_time::from_nsec(plib::pstonum<std::int64_t>(plib::trim(times[j])));
+ nl_assert_always(outs.equals("0"), "Unknown value (not 0 or 1");
+ netlist_time t = netlist_time::from_nsec(static_cast<unsigned long>(times[j].trim().as_long()));
uint_least8_t k=0;
while (m_timing_nt[k] != netlist_time::zero() && m_timing_nt[k] != t)
k++;
@@ -442,9 +450,9 @@ void truthtable_parser::parse(const std::vector<pstring> &truthtable)
}
for (size_t i=0; i<m_size; i++)
{
- if (m_out_state[i] == m_out_state.mask())
+ if (m_outs[i] == m_outs.mask())
throw nl_exception(plib::pfmt("truthtable: found element not set {1}\n").x(i) );
- m_out_state.set(i, m_out_state[i] | (ign[i] << m_NO));
+ m_outs.set(i, m_outs[i] | (ign[i] << m_NO));;
}
*m_initialized = true;
@@ -452,21 +460,26 @@ void truthtable_parser::parse(const std::vector<pstring> &truthtable)
netlist_base_factory_truthtable_t::netlist_base_factory_truthtable_t(const pstring &name, const pstring &classname,
const pstring &def_param, const pstring &sourcefile)
-: factory::element_t(name, classname, def_param, sourcefile), m_family_desc(family_TTL())
+: factory::element_t(name, classname, def_param, sourcefile), m_family(family_TTL())
+{
+}
+
+netlist_base_factory_truthtable_t::~netlist_base_factory_truthtable_t()
{
}
+
#define ENTRYY(n, m, s) case (n * 100 + m): \
{ using xtype = netlist_factory_truthtable_t<n, m>; \
- ret = plib::make_unique<xtype>(desc.name, desc.classname, desc.def_param, s); } break
+ ret = plib::palloc<xtype>(desc.name, desc.classname, desc.def_param, s); } break
#define ENTRY(n, s) ENTRYY(n, 1, s); ENTRYY(n, 2, s); ENTRYY(n, 3, s); \
ENTRYY(n, 4, s); ENTRYY(n, 5, s); ENTRYY(n, 6, s); \
ENTRYY(n, 7, s); ENTRYY(n, 8, s)
-plib::unique_ptr<netlist_base_factory_truthtable_t> tt_factory_create(tt_desc &desc, const pstring &sourcefile)
+void tt_factory_create(setup_t &setup, tt_desc &desc, const pstring &sourcefile)
{
- plib::unique_ptr<netlist_base_factory_truthtable_t> ret;
+ netlist_base_factory_truthtable_t *ret;
switch (desc.ni * 100 + desc.no)
{
@@ -487,9 +500,9 @@ plib::unique_ptr<netlist_base_factory_truthtable_t> tt_factory_create(tt_desc &d
nl_assert_always(false, msg);
}
ret->m_desc = desc.desc;
- ret->m_family_name = desc.family;
-
- return ret;
+ if (desc.family != "")
+ ret->m_family = setup.family_from_model(desc.family);
+ setup.factory().register_device(std::unique_ptr<netlist_base_factory_truthtable_t>(ret));
}
} //namespace devices
diff --git a/src/lib/netlist/devices/nlid_truthtable.h b/src/lib/netlist/devices/nlid_truthtable.h
index 1217d7ee873..311f5ebd8ca 100644
--- a/src/lib/netlist/devices/nlid_truthtable.h
+++ b/src/lib/netlist/devices/nlid_truthtable.h
@@ -10,9 +10,9 @@
#ifndef NLID_TRUTHTABLE_H_
#define NLID_TRUTHTABLE_H_
-#include "netlist/nl_base.h"
-#include "netlist/nl_setup.h"
-#include "plib/putil.h"
+#include "../nl_setup.h"
+#include "../nl_base.h"
+#include "../plib/putil.h"
#define NETLIB_TRUTHTABLE(cname, nIN, nOUT) \
class NETLIB_NAME(cname) : public nld_truthtable_t<nIN, nOUT> \
@@ -29,9 +29,17 @@
namespace netlist
{
-namespace devices
-{
+ namespace devices
+ {
+#if 0
+ template<unsigned bits> struct uint_for_size { typedef uint_least32_t type; };
+ template<unsigned bits>
+ struct need_bytes_for_bits
+ {
+ enum { value = 4 };
+ };
+#else
template<unsigned bits>
struct need_bytes_for_bits
{
@@ -44,35 +52,11 @@ namespace devices
};
template<unsigned bits> struct uint_for_size;
- template<> struct uint_for_size<1> { using type = uint_least8_t; };
- template<> struct uint_for_size<2> { using type = uint_least16_t; };
- template<> struct uint_for_size<4> { using type = uint_least32_t; };
- template<> struct uint_for_size<8> { using type = uint_least64_t; };
-
- template<std::size_t NUM, typename R>
- struct aa
- {
- template<typename T>
- R f(T &arr, const R ign)
- {
- R r = aa<NUM-1, R>().f(arr, ign);
- if (ign & (1 << (NUM-1)))
- arr[NUM-1].activate();
- return r | (arr[NUM-1]() << (NUM-1));
- }
- };
-
- template<typename R>
- struct aa<1, R>
- {
- template<typename T>
- R f(T &arr, const R ign)
- {
- if ((ign & 1))
- arr[0].activate();
- return arr[0]();
- }
- };
+ template<> struct uint_for_size<1> { typedef uint_least8_t type; };
+ template<> struct uint_for_size<2> { typedef uint_least16_t type; };
+ template<> struct uint_for_size<4> { typedef uint_least32_t type; };
+ template<> struct uint_for_size<8> { typedef uint_least64_t type; };
+#endif
template<std::size_t m_NI, std::size_t m_NO>
NETLIB_OBJECT(truthtable_t)
@@ -81,23 +65,22 @@ namespace devices
detail::family_setter_t m_fam;
public:
- using type_t = typename uint_for_size<need_bytes_for_bits<m_NO + m_NI>::value>::type;
+ typedef typename uint_for_size<need_bytes_for_bits<m_NO + m_NI>::value>::type type_t;
static constexpr const std::size_t m_num_bits = m_NI;
static constexpr const std::size_t m_size = (1 << (m_num_bits));
static constexpr const type_t m_outmask = ((1 << m_NO) - 1);
+ static constexpr const std::size_t m_min_devices_for_deactivate = 2;
struct truthtable_t
{
truthtable_t()
- : m_timing_index{0}
- , m_initialized(false)
+ : m_initialized(false)
{}
-
- std::array<type_t, m_size> m_out_state;
- std::array<uint_least8_t, m_size * m_NO> m_timing_index;
- std::array<netlist_time, 16> m_timing_nt;
bool m_initialized;
+ type_t m_outs[m_size];
+ uint_least8_t m_timing[m_size * m_NO];
+ netlist_time m_timing_nt[16];
};
template <class C>
@@ -107,6 +90,7 @@ namespace devices
: device_t(owner, name)
, m_fam(*this, fam)
, m_ign(*this, "m_ign", 0)
+ , m_active(*this, "m_active", 1)
, m_ttp(ttp)
{
init(desc);
@@ -116,14 +100,13 @@ namespace devices
NETLIB_RESETI()
{
- int active_outputs = 0;
+ m_active = 0;
m_ign = 0;
for (auto &i : m_I)
i.activate();
for (auto &q : m_Q)
if (q.has_net() && q.net().num_cons() > 0)
- active_outputs++;
- set_active_outputs(active_outputs);
+ m_active++;
}
NETLIB_UPDATEI()
@@ -133,14 +116,28 @@ namespace devices
void inc_active() NL_NOEXCEPT override
{
- process<false>();
+ if (m_NI >= m_min_devices_for_deactivate)
+ if (++m_active == 1)
+ {
+ process<false>();
+ }
}
void dec_active() NL_NOEXCEPT override
{
- for (std::size_t i = 0; i< m_NI; i++)
- m_I[i].inactivate();
- m_ign = (1<<m_NI)-1;
+ /* FIXME:
+ * Based on current measurements there is no point to disable
+ * 1 input devices. This should actually be a parameter so that we
+ * can decide for each individual gate whether it is beneficial to
+ * ignore deactivation.
+ */
+ if (m_NI >= m_min_devices_for_deactivate)
+ if (--m_active == 0)
+ {
+ for (std::size_t i = 0; i< m_NI; i++)
+ m_I[i].inactivate();
+ m_ign = (1<<m_NI)-1;
+ }
}
plib::uninitialised_array_t<logic_input_t, m_NI> m_I;
@@ -156,44 +153,46 @@ namespace devices
netlist_time mt(netlist_time::zero());
type_t nstate(0);
- type_t ign(m_ign);
-#if 1
- if (!doOUT)
- for (std::size_t i = 0; i < m_NI; i++)
- {
- m_I[i].activate();
- //nstate |= (m_I[i]() ? (1 << i) : 0);
- nstate |= (m_I[i]() << i);
- mt = std::max(this->m_I[i].net().next_scheduled_time(), mt);
- }
- else
- for (std::size_t i = 0; i < m_NI; i++)
- {
- if ((ign & 1))
- m_I[i].activate();
- //nstate |= (m_I[i]() ? (1 << i) : 0);
- nstate |= (m_I[i]() << i);
- ign >>= 1;
- }
-#else
- if (!doOUT)
+ if (m_NI >= m_min_devices_for_deactivate)
{
- nstate = aa<m_NI, type_t>().f(m_I, ~0);
- for (std::size_t i = 0; i < m_NI; i++)
- mt = std::max(this->m_I[i].net().time(), mt);
+ type_t ign(m_ign);
+ if (!doOUT)
+ for (std::size_t i = 0; i < m_NI; i++)
+ {
+ m_I[i].activate();
+ nstate |= (m_I[i]() ? (1 << i) : 0);
+ mt = std::max(this->m_I[i].net().time(), mt);
+ }
+ else
+ for (std::size_t i = 0; i < m_NI; i++)
+ {
+ if ((ign & 1))
+ m_I[i].activate();
+ nstate |= (m_I[i]() ? (1 << i) : 0);
+ ign >>= 1;
+ }
}
else
- nstate = aa<m_NI, type_t>().f(m_I, ign);
-#endif
+ {
+ if (!doOUT)
+ for (std::size_t i = 0; i < m_NI; i++)
+ {
+ nstate |= (m_I[i]() ? (1 << i) : 0);
+ mt = std::max(this->m_I[i].net().time(), mt);
+ }
+ else
+ for (std::size_t i = 0; i < m_NI; i++)
+ nstate |= (m_I[i]() ? (1 << i) : 0);
+ }
- const type_t outstate(m_ttp.m_out_state[nstate]);
+ const type_t outstate(m_ttp.m_outs[nstate]);
type_t out(outstate & m_outmask);
m_ign = outstate >> m_NO;
const std::size_t timebase(nstate * m_NO);
- const auto *t(&m_ttp.m_timing_index[timebase]);
- const auto *tim = m_ttp.m_timing_nt.data();
+ const auto *t(&m_ttp.m_timing[timebase]);
+ const auto *tim = m_ttp.m_timing_nt;
if (doOUT)
for (std::size_t i = 0; i < m_NO; out >>= 1, ++i)
@@ -202,14 +201,18 @@ namespace devices
for (std::size_t i = 0; i < m_NO; out >>= 1, ++i)
m_Q[i].set_Q_time(out & 1, mt + tim[t[i]]);
- ign = m_ign;
- for (auto I = m_I.begin(); ign != 0; ign >>= 1, ++I)
- if (ign & 1)
- I->inactivate();
+ if (m_NI >= m_min_devices_for_deactivate)
+ {
+ type_t ign(m_ign);
+ for (auto I = m_I.begin(); ign != 0; ign >>= 1, ++I)
+ if (ign & 1)
+ I->inactivate();
+ }
}
/* FIXME: check width */
state_var<type_t> m_ign;
+ state_var_s32 m_active;
const truthtable_t &m_ttp;
};
@@ -219,15 +222,15 @@ namespace devices
netlist_base_factory_truthtable_t(const pstring &name, const pstring &classname,
const pstring &def_param, const pstring &sourcefile);
+ virtual ~netlist_base_factory_truthtable_t();
+
std::vector<pstring> m_desc;
- pstring m_family_name;
- const logic_family_desc_t *m_family_desc;
+ const logic_family_desc_t *m_family;
};
- /* the returned element is still missing a pointer to the family ... */
- plib::unique_ptr<netlist_base_factory_truthtable_t> tt_factory_create(tt_desc &desc, const pstring &sourcefile);
+ void tt_factory_create(setup_t &setup, tt_desc &desc, const pstring &sourcefile);
-} //namespace devices
+ } //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/macro/nlm_base.cpp b/src/lib/netlist/macro/nlm_base.cpp
index 86f2450d301..8ea6f148864 100644
--- a/src/lib/netlist/macro/nlm_base.cpp
+++ b/src/lib/netlist/macro/nlm_base.cpp
@@ -1,7 +1,7 @@
// license:GPL-2.0+
// copyright-holders:Couriersud
-#include "netlist/nl_setup.h"
-#include "netlist/devices/net_lib.h"
+#include "../nl_setup.h"
+#include "../devices/net_lib.h"
#include "nlm_base.h"
/* ----------------------------------------------------------------------------
@@ -12,14 +12,9 @@ static NETLIST_START(diode_models)
NET_MODEL("D _(IS=1e-15 N=1)")
NET_MODEL("1N914 D(Is=2.52n Rs=.568 N=1.752 Cjo=4p M=.4 tt=20n Iave=200m Vpk=75 mfg=OnSemi type=silicon)")
- // FIXME: 1N916 currently only a copy of 1N914!
- NET_MODEL("1N916 D(Is=2.52n Rs=.568 N=1.752 Cjo=4p M=.4 tt=20n Iave=200m Vpk=75 mfg=OnSemi type=silicon)")
NET_MODEL("1N4001 D(Is=14.11n N=1.984 Rs=33.89m Ikf=94.81 Xti=3 Eg=1.11 Cjo=25.89p M=.44 Vj=.3245 Fc=.5 Bv=75 Ibv=10u Tt=5.7u Iave=1 Vpk=50 mfg=GI type=silicon)")
NET_MODEL("1N4148 D(Is=2.52n Rs=.568 N=1.752 Cjo=4p M=.4 tt=20n Iave=200m Vpk=75 mfg=OnSemi type=silicon)")
NET_MODEL("1S1588 D(Is=2.52n Rs=.568 N=1.752 Cjo=4p M=.4 tt=20n Iave=200m Vpk=75)")
-
- NET_MODEL("1N34A D( Bv=75 Cjo=0.5e-12 Eg=0.67 Ibv=18e-3 Is=2e-7 Rs=7 N=1.3 Vj=0.1 M=0.27 type=germanium)")
-
NET_MODEL("LedRed D(IS=93.2p RS=42M N=3.73 BV=4 IBV=10U CJO=2.97P VJ=.75 M=.333 TT=4.32U Iave=40m Vpk=4 type=LED)")
NET_MODEL("LedGreen D(IS=93.2p RS=42M N=4.61 BV=4 IBV=10U CJO=2.97P VJ=.75 M=.333 TT=4.32U Iave=40m Vpk=4 type=LED)")
NET_MODEL("LedBlue D(IS=93.2p RS=42M N=7.47 BV=5 IBV=10U CJO=2.97P VJ=.75 M=.333 TT=4.32U Iave=40m Vpk=5 type=LED)")
@@ -31,16 +26,9 @@ NETLIST_END()
* BJT Models
* ---------------------------------------------------------------------------*/
-static NETLIST_START(mosfet_models)
- //NET_MODEL("NMOS _(VTO=0.0 N=1.0 IS=1E-14 KP=2E-5 UO=600 PHI=0.6 LD=0.0 L=1.0 TOX=1E-7 W=1.0 NSUB=0.0 GAMMA=0.0 RD=0.0 RS=0.0 LAMBDA=0.0)")
- //NET_MODEL("PMOS _(VTO=0.0 N=1.0 IS=1E-14 KP=2E-5 UO=600 PHI=0.6 LD=0.0 L=1.0 TOX=1E-7 W=1.0 NSUB=0.0 GAMMA=0.0 RD=0.0 RS=0.0 LAMBDA=0.0)")
- NET_MODEL("NMOS _(VTO=0.0 N=1.0 IS=1E-14 KP=0.0 UO=600 PHI=0.0 LD=0.0 L=1.0 TOX=1E-7 W=1.0 NSUB=0.0 GAMMA=0.0 RD=0.0 RS=0.0 LAMBDA=0.0)")
- NET_MODEL("PMOS _(VTO=0.0 N=1.0 IS=1E-14 KP=0.0 UO=600 PHI=0.0 LD=0.0 L=1.0 TOX=1E-7 W=1.0 NSUB=0.0 GAMMA=0.0 RD=0.0 RS=0.0 LAMBDA=0.0)")
-NETLIST_END()
-
static NETLIST_START(bjt_models)
- NET_MODEL("NPN _(IS=1e-15 BF=100 NF=1 BR=1 NR=1 CJE=0 CJC=0)")
- NET_MODEL("PNP _(IS=1e-15 BF=100 NF=1 BR=1 NR=1 CJE=0 CJC=0)")
+ NET_MODEL("NPN _(IS=1e-15 BF=100 NF=1 BR=1 NR=1)")
+ NET_MODEL("PNP _(IS=1e-15 BF=100 NF=1 BR=1 NR=1)")
NET_MODEL("2SA1015 PNP(Is=295.1E-18 Xti=3 Eg=1.11 Vaf=100 Bf=110 Xtb=1.5 Br=10.45 Rc=15 Cjc=66.2p Mjc=1.054 Vjc=.75 Fc=.5 Cje=5p Mje=.3333 Vje=.75 Tr=10n Tf=1.661n VCEO=45V ICrating=150M MFG=Toshiba)")
NET_MODEL("2SC1815 NPN(Is=2.04f Xti=3 Eg=1.11 Vaf=6 Bf=400 Ikf=20m Xtb=1.5 Br=3.377 Rc=1 Cjc=1p Mjc=.3333 Vjc=.75 Fc=.5 Cje=25p Mje=.3333 Vje=.75 Tr=450n Tf=20n Itf=0 Vtf=0 Xtf=0 VCEO=45V ICrating=150M MFG=Toshiba)")
@@ -58,8 +46,6 @@ static NETLIST_START(bjt_models)
NET_MODEL("BC556B PNP(IS=3.83E-14 NF=1.008 ISE=1.22E-14 NE=1.528 BF=344.4 IKF=0.08039 VAF=21.11 NR=1.005 ISC=2.85E-13 NC=1.28 BR=14.84 IKR=0.047 VAR=32.02 RB=1 IRB=1.00E-06 RBM=1 RE=0.6202 RC=0.5713 XTB=0 EG=1.11 XTI=3 CJE=1.23E-11 VJE=0.6106 MJE=0.378 TF=5.60E-10 XTF=3.414 VTF=5.23 ITF=0.1483 PTF=0 CJC=1.08E-11 VJC=0.1022 MJC=0.3563 XCJC=0.6288 TR=1.00E-32 CJS=0 VJS=0.75 MJS=0.333 FC=0.8027 Vceo=65 Icrating=100m mfg=Philips)")
NET_MODEL("BC548C NPN(IS=1.95E-14 ISE=1.31E-15 ISC=1.0E-13 XTI=3 BF=466 BR=2.42 IKF=0.18 IKR=1 XTB=1.5 VAF=91.7 VAR=24.7 VJE=0.632 VJC=0.339 RE=1 RC=1.73 RB=26.5 RBM=10 IRB=10 CJE=1.33E-11 CJC=5.17E-12 XCJC=1 FC=0.9 NF=0.993 NR=1.2 NE=1.32 NC=2.00 MJE=0.326 MJC=0.319 TF=6.52E-10 TR=0 PTF=0 ITF=1.03 VTF=1.65 XTF=100 EG=1.11 KF=1E-9 AF=1 VCEO=40 ICrating=800M MFG=Siemens)")
NET_MODEL("BC817-25 NPN(IS=9.198E-14 NF=1.003 ISE=4.468E-16 NE=1.65 BF=338.8 IKF=0.4913 VAF=107.9 NR=1.002 ISC=5.109E-15 NC=1.071 BR=29.48 IKR=0.193 VAR=25 RB=1 IRB=1000 RBM=1 RE=0.2126 RC=0.143 XTB=0 EG=1.11 XTI=3 CJE=3.825E-11 VJE=0.7004 MJE=0.364 TF=5.229E-10 XTF=219.7 VTF=3.502 ITF=7.257 PTF=0 CJC=1.27E-11 VJC=0.4431 MJC=0.3983 XCJC=0.4555 TR=7E-11 CJS=0 VJS=0.75 MJS=0.333 FC=0.905 Vceo=45 Icrating=500m mfg=Philips)")
-
- NET_MODEL("9013 NPN(IS=3.40675E-14 BF=166 VAF=67 IKF=1.164 ISE=12.37e-15 NE=2 BR=15.17 VAR=40.84 IKR=0.261352 ISC=1.905E-15 NC=1.066 RB=63.2 IRB=5.62E-6 RBM=22.1 RE=0.02 RC=0.7426 CJE=3.53E-11 VJE=0.808 MJE=0.372 CJC=1.74E-11 VJC=0.614 MJC=0.388 XCJC=0.349 XTB=1.4025 EG=1.0999 XTI=3 VC=0.5 VCEO=20)")
NETLIST_END()
/* ----------------------------------------------------------------------------
@@ -88,22 +74,19 @@ NETLIST_START(base)
LOCAL_SOURCE(diode_models)
LOCAL_SOURCE(bjt_models)
- LOCAL_SOURCE(mosfet_models)
LOCAL_SOURCE(family_models)
-
LOCAL_SOURCE(TTL74XX_lib)
LOCAL_SOURCE(CD4XXX_lib)
LOCAL_SOURCE(OPAMP_lib)
LOCAL_SOURCE(otheric_lib)
- INCLUDE(diode_models)
- INCLUDE(bjt_models)
- INCLUDE(mosfet_models)
- INCLUDE(family_models)
- INCLUDE(TTL74XX_lib)
- INCLUDE(CD4XXX_lib)
- INCLUDE(OPAMP_lib)
- INCLUDE(otheric_lib)
+ INCLUDE(diode_models);
+ INCLUDE(bjt_models);
+ INCLUDE(family_models);
+ INCLUDE(TTL74XX_lib);
+ INCLUDE(CD4XXX_lib);
+ INCLUDE(OPAMP_lib);
+ INCLUDE(otheric_lib);
NETLIST_END()
diff --git a/src/lib/netlist/macro/nlm_base.h b/src/lib/netlist/macro/nlm_base.h
index 6a88ad5a1be..5ecf8071e98 100644
--- a/src/lib/netlist/macro/nlm_base.h
+++ b/src/lib/netlist/macro/nlm_base.h
@@ -10,7 +10,7 @@
#ifndef __PLIB_PREPROCESSOR__
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
/* ----------------------------------------------------------------------------
* Netlist Macros
diff --git a/src/lib/netlist/macro/nlm_cd4xxx.cpp b/src/lib/netlist/macro/nlm_cd4xxx.cpp
index 5ebd5593123..9ce786ca85e 100644
--- a/src/lib/netlist/macro/nlm_cd4xxx.cpp
+++ b/src/lib/netlist/macro/nlm_cd4xxx.cpp
@@ -2,10 +2,10 @@
// copyright-holders:Couriersud
#include "nlm_cd4xxx.h"
-#include "netlist/devices/nld_4020.h"
-#include "netlist/devices/nld_4066.h"
-#include "netlist/devices/nld_4316.h"
-#include "netlist/devices/nld_system.h"
+#include "../devices/nld_system.h"
+#include "../devices/nld_4020.h"
+#include "../devices/nld_4066.h"
+#include "../devices/nld_4316.h"
/*
* CD4001BC: Quad 2-Input NOR Buffered B Series Gate
diff --git a/src/lib/netlist/macro/nlm_cd4xxx.h b/src/lib/netlist/macro/nlm_cd4xxx.h
index d4d9c97fdc2..527336c1e8e 100644
--- a/src/lib/netlist/macro/nlm_cd4xxx.h
+++ b/src/lib/netlist/macro/nlm_cd4xxx.h
@@ -3,7 +3,7 @@
#ifndef NLD_CD4XXX_H_
#define NLD_CD4XXX_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
/*
* Devices:
diff --git a/src/lib/netlist/macro/nlm_opamp.cpp b/src/lib/netlist/macro/nlm_opamp.cpp
index 849f7820046..122b324f777 100644
--- a/src/lib/netlist/macro/nlm_opamp.cpp
+++ b/src/lib/netlist/macro/nlm_opamp.cpp
@@ -1,7 +1,7 @@
// license:GPL-2.0+
// copyright-holders:Couriersud
#include "nlm_opamp.h"
-#include "netlist/devices/net_lib.h"
+#include "../devices/net_lib.h"
/*
* Generic layout with 4 opamps, VCC on pin 4 and GND on pin 11
diff --git a/src/lib/netlist/macro/nlm_opamp.h b/src/lib/netlist/macro/nlm_opamp.h
index fbd7547c976..9cffbb29c87 100644
--- a/src/lib/netlist/macro/nlm_opamp.h
+++ b/src/lib/netlist/macro/nlm_opamp.h
@@ -3,7 +3,7 @@
#ifndef NLM_OPAMP_H_
#define NLM_OPAMP_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#ifndef __PLIB_PREPROCESSOR__
diff --git a/src/lib/netlist/macro/nlm_other.cpp b/src/lib/netlist/macro/nlm_other.cpp
index ea0eb1539a8..7e31ae27bb4 100644
--- a/src/lib/netlist/macro/nlm_other.cpp
+++ b/src/lib/netlist/macro/nlm_other.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Couriersud
#include "nlm_other.h"
-#include "netlist/devices/nld_system.h"
+#include "../devices/nld_system.h"
/*
* MC14584B: Hex Schmitt Trigger
diff --git a/src/lib/netlist/macro/nlm_other.h b/src/lib/netlist/macro/nlm_other.h
index ee231fbd6db..7c38d8ad363 100644
--- a/src/lib/netlist/macro/nlm_other.h
+++ b/src/lib/netlist/macro/nlm_other.h
@@ -3,7 +3,7 @@
#ifndef NLM_OTHER_H_
#define NLM_OTHER_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#ifndef __PLIB_PREPROCESSOR__
diff --git a/src/lib/netlist/macro/nlm_ttl74xx.cpp b/src/lib/netlist/macro/nlm_ttl74xx.cpp
index 58cab049ae7..df1b873a468 100644
--- a/src/lib/netlist/macro/nlm_ttl74xx.cpp
+++ b/src/lib/netlist/macro/nlm_ttl74xx.cpp
@@ -2,8 +2,8 @@
// copyright-holders:Couriersud
#include "nlm_ttl74xx.h"
-#include "netlist/devices/nld_schmitt.h"
-#include "netlist/devices/nld_system.h"
+#include "../devices/nld_schmitt.h"
+#include "../devices/nld_system.h"
/*
@@ -825,9 +825,8 @@ NETLIST_END()
NETLIST_START(TTL74XX_lib)
- NET_MODEL("DM7414 SCHMITT_TRIGGER(VTP=1.7 VTM=0.9 VI=4.35 RI=6.15k VOH=3.5 ROH=120 VOL=0.1 ROL=37.5 TPLH=15 TPHL=15)")
- NET_MODEL("TTL_7414_GATE SCHMITT_TRIGGER(VTP=1.7 VTM=0.9 VI=4.35 RI=6.15k VOH=3.5 ROH=120 VOL=0.1 ROL=37.5 TPLH=15 TPHL=15)")
- NET_MODEL("DM74LS14 SCHMITT_TRIGGER(VTP=1.6 VTM=0.8 VI=4.4 RI=19.3k VOH=3.45 ROH=130 VOL=0.1 ROL=31.2 TPLH=15 TPHL=15)")
+ NET_MODEL("DM7414 SCHMITT_TRIGGER(VTP=1.7 VTM=0.9 VI=4.35 RI=6.15k VOH=3.5 ROH=120 VOL=0.1 ROL=37.5 TPLH=15 TPHL=15)")
+ NET_MODEL("DM74LS14 SCHMITT_TRIGGER(VTP=1.6 VTM=0.8 VI=4.4 RI=19.3k VOH=3.45 ROH=130 VOL=0.1 ROL=31.2 TPLH=15 TPHL=15)")
//NET_MODEL("DM7414 FAMILY(FV=5 IVL=0.16 IVH=0.4 OVL=0.1 OVH=0.05 ORL=10.0 ORH=1.0e8)")
diff --git a/src/lib/netlist/macro/nlm_ttl74xx.h b/src/lib/netlist/macro/nlm_ttl74xx.h
index 21ff99f2efe..c8868e45f7f 100644
--- a/src/lib/netlist/macro/nlm_ttl74xx.h
+++ b/src/lib/netlist/macro/nlm_ttl74xx.h
@@ -3,7 +3,7 @@
#ifndef NLD_TTL74XX_H_
#define NLD_TTL74XX_H_
-#include "netlist/nl_setup.h"
+#include "../nl_setup.h"
#ifndef __PLIB_PREPROCESSOR__
diff --git a/src/lib/netlist/netlist_types.h b/src/lib/netlist/netlist_types.h
new file mode 100644
index 00000000000..0bd32be21be
--- /dev/null
+++ b/src/lib/netlist/netlist_types.h
@@ -0,0 +1,54 @@
+// license:GPL-2.0+
+// copyright-holders:Couriersud
+/*!
+ *
+ * \file netlist_types.h
+ *
+ */
+
+#ifndef NETLIST_TYPES_H_
+#define NETLIST_TYPES_H_
+
+#include "nl_config.h"
+#include "plib/pchrono.h"
+#include "plib/pstring.h"
+
+#include <cstdint>
+#include <unordered_map>
+
+namespace netlist
+{
+ //============================================================
+ // Performance tracking
+ //============================================================
+
+#if NL_KEEP_STATISTICS
+ using nperftime_t = plib::chrono::timer<plib::chrono::exact_ticks, true>;
+ using nperfcount_t = plib::chrono::counter<true>;
+#else
+ using nperftime_t = plib::chrono::timer<plib::chrono::exact_ticks, false>;
+ using nperfcount_t = plib::chrono::counter<false>;
+#endif
+
+ //============================================================
+ // Types needed by various includes
+ //============================================================
+
+ namespace detail {
+
+ /*! Enum specifying the type of object */
+ enum terminal_type {
+ TERMINAL = 0, /*!< object is an analog terminal */
+ INPUT = 1, /*!< object is an input */
+ OUTPUT = 2, /*!< object is an output */
+ };
+
+ /*! Type of the model map used.
+ * This is used to hold all #Models in an unordered map
+ */
+ using model_map_t = std::unordered_map<pstring, pstring>;
+
+ }
+}
+
+#endif /* NETLIST_TYPES_H_ */
diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp
index ad048e899bf..9a513c00804 100644
--- a/src/lib/netlist/nl_base.cpp
+++ b/src/lib/netlist/nl_base.cpp
@@ -8,19 +8,18 @@
#include "solver/nld_matrix_solver.h"
#include "solver/nld_solver.h"
-#include "plib/palloc.h"
-#include "plib/pmempool.h"
#include "plib/putil.h"
+#include "plib/palloc.h"
-#include "devices/nlid_proxy.h"
+#include "nl_base.h"
#include "devices/nlid_system.h"
+#include "devices/nlid_proxy.h"
#include "macro/nlm_base.h"
-#include "nl_base.h"
#include "nl_errstr.h"
-#include <cmath>
#include <cstring>
+#include <cmath>
#include <limits>
namespace netlist
@@ -28,13 +27,14 @@ namespace netlist
namespace detail
{
- //static plib::mempool *pool()
- //{
- // static plib::mempool s_pool(655360, 32);
- // return &s_pool;
- //}
+ static plib::mempool *pool()
+ {
+ static plib::mempool *s_pool = nullptr;
+ if (s_pool == nullptr)
+ s_pool = new plib::mempool(65536, 16);
+ return s_pool;
+ }
-#if 0
void * object_t::operator new (size_t size)
{
void *ret = nullptr;
@@ -44,30 +44,38 @@ namespace detail
ret = ::operator new(size);
return ret;
}
+
void object_t::operator delete (void * mem)
{
if (mem)
{
- //if ((USE_MEMPOOL))
- // pool()->free(mem);
- //else
+ if ((USE_MEMPOOL))
+ pool()->free(mem);
+ else
::operator delete(mem);
}
}
-#endif
-} // namespace detail
+}
+
+nl_exception::~nl_exception()
+{
+}
// ----------------------------------------------------------------------------------------
// logic_family_ttl_t
// ----------------------------------------------------------------------------------------
-// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init, modernize-use-equals-default)
logic_family_desc_t::logic_family_desc_t()
{
}
+logic_family_desc_t::~logic_family_desc_t()
+{
+}
+
+
class logic_family_ttl_t : public logic_family_desc_t
{
public:
@@ -82,17 +90,17 @@ public:
m_R_low = 1.0;
m_R_high = 130.0;
}
- pool_owned_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const override;
- pool_owned_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const override;
+ virtual plib::owned_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_t &anetlist, const pstring &name, logic_output_t *proxied) const override;
+ virtual plib::owned_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *proxied) const override;
};
-pool_owned_ptr<devices::nld_base_d_to_a_proxy> logic_family_ttl_t::create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const
+plib::owned_ptr<devices::nld_base_d_to_a_proxy> logic_family_ttl_t::create_d_a_proxy(netlist_t &anetlist, const pstring &name, logic_output_t *proxied) const
{
- return pool().make_poolptr<devices::nld_d_to_a_proxy>(anetlist, name, proxied);
+ return plib::owned_ptr<devices::nld_base_d_to_a_proxy>::Create<devices::nld_d_to_a_proxy>(anetlist, name, proxied);
}
-pool_owned_ptr<devices::nld_base_a_to_d_proxy> logic_family_ttl_t::create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const
+plib::owned_ptr<devices::nld_base_a_to_d_proxy> logic_family_ttl_t::create_a_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *proxied) const
{
- return pool().make_poolptr<devices::nld_a_to_d_proxy>(anetlist, name, proxied);
+ return plib::owned_ptr<devices::nld_base_a_to_d_proxy>::Create<devices::nld_a_to_d_proxy>(anetlist, name, proxied);
}
class logic_family_cd4xxx_t : public logic_family_desc_t
@@ -109,18 +117,17 @@ public:
m_R_low = 10.0;
m_R_high = 10.0;
}
- pool_owned_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const override;
- pool_owned_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const override;
+ virtual plib::owned_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_t &anetlist, const pstring &name, logic_output_t *proxied) const override;
+ virtual plib::owned_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *proxied) const override;
};
-pool_owned_ptr<devices::nld_base_d_to_a_proxy> logic_family_cd4xxx_t::create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const
+plib::owned_ptr<devices::nld_base_d_to_a_proxy> logic_family_cd4xxx_t::create_d_a_proxy(netlist_t &anetlist, const pstring &name, logic_output_t *proxied) const
{
- return pool().make_poolptr<devices::nld_d_to_a_proxy>(anetlist, name, proxied);
+ return plib::owned_ptr<devices::nld_base_d_to_a_proxy>::Create<devices::nld_d_to_a_proxy>(anetlist, name, proxied);
}
-
-pool_owned_ptr<devices::nld_base_a_to_d_proxy> logic_family_cd4xxx_t::create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const
+plib::owned_ptr<devices::nld_base_a_to_d_proxy> logic_family_cd4xxx_t::create_a_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *proxied) const
{
- return pool().make_poolptr<devices::nld_a_to_d_proxy>(anetlist, name, proxied);
+ return plib::owned_ptr<devices::nld_base_a_to_d_proxy>::Create<devices::nld_a_to_d_proxy>(anetlist, name, proxied);
}
const logic_family_desc_t *family_TTL()
@@ -139,10 +146,10 @@ const logic_family_desc_t *family_CD4XXX()
// queue_t
// ----------------------------------------------------------------------------------------
-detail::queue_t::queue_t(netlist_state_t &nl)
- : timed_queue<pqentry_t<net_t *, netlist_time>, false, NL_KEEP_STATISTICS>(512)
+detail::queue_t::queue_t(netlist_t &nl)
+ : timed_queue<pqentry_t<net_t *, netlist_time>, false>(512)
, netlist_ref(nl)
-// , plib::state_manager_t::callback_t()
+ , plib::state_manager_t::callback_t()
, m_qsize(0)
, m_times(512)
, m_net_ids(512)
@@ -151,56 +158,52 @@ detail::queue_t::queue_t(netlist_state_t &nl)
void detail::queue_t::register_state(plib::state_manager_t &manager, const pstring &module)
{
- //state().log().debug("register_state\n");
+ netlist().log().debug("register_state\n");
manager.save_item(this, m_qsize, module + "." + "qsize");
manager.save_item(this, &m_times[0], module + "." + "times", m_times.size());
manager.save_item(this, &m_net_ids[0], module + "." + "names", m_net_ids.size());
}
-void detail::queue_t::on_pre_save(plib::state_manager_t &manager)
+void detail::queue_t::on_pre_save()
{
- plib::unused_var(manager);
+ netlist().log().debug("on_pre_save\n");
m_qsize = this->size();
+ netlist().log().debug("current time {1} qsize {2}\n", netlist().time().as_double(), m_qsize);
for (std::size_t i = 0; i < m_qsize; i++ )
{
m_times[i] = this->listptr()[i].m_exec_time.as_raw();
- m_net_ids[i] = state().find_net_id(this->listptr()[i].m_object);
+ m_net_ids[i] = netlist().find_net_id(this->listptr()[i].m_object);
}
}
-void detail::queue_t::on_post_load(plib::state_manager_t &manager)
+void detail::queue_t::on_post_load()
{
- plib::unused_var(manager);
this->clear();
+ netlist().log().debug("current time {1} qsize {2}\n", netlist().time().as_double(), m_qsize);
for (std::size_t i = 0; i < m_qsize; i++ )
{
- detail::net_t *n = state().nets()[m_net_ids[i]].get();
+ detail::net_t *n = netlist().m_nets[m_net_ids[i]].get();
this->push(queue_t::entry_t(netlist_time::from_raw(m_times[i]),n));
}
}
// ----------------------------------------------------------------------------------------
-// netlist_ref_t
-// ----------------------------------------------------------------------------------------
-
-detail::netlist_ref::netlist_ref(netlist_state_t &nl)
-: m_netlist(nl.exec()) { }
-
-// ----------------------------------------------------------------------------------------
// object_t
// ----------------------------------------------------------------------------------------
detail::object_t::object_t(const pstring &aname)
-// : m_name(aname)
+ : m_name(plib::make_unique<pstring>(aname))
{
- name_hash().insert({this, aname});
}
-pstring detail::object_t::name() const
+detail::object_t::~object_t()
{
- return name_hash().find(this)->second;
- //return m_name;
+}
+
+const pstring &detail::object_t::name() const
+{
+ return *m_name;
}
// ----------------------------------------------------------------------------------------
@@ -227,7 +230,7 @@ detail::terminal_type detail::core_terminal_t::type() const
return terminal_type::OUTPUT;
else
{
- state().log().fatal(MF_1_UNKNOWN_TYPE_FOR_OBJECT, name());
+ netlist().log().fatal(MF_1_UNKNOWN_TYPE_FOR_OBJECT, name());
return terminal_type::TERMINAL; // please compiler
}
}
@@ -236,37 +239,158 @@ detail::terminal_type detail::core_terminal_t::type() const
// netlist_t
// ----------------------------------------------------------------------------------------
-netlist_t::netlist_t(const pstring &aname, plib::unique_ptr<callbacks_t> callbacks)
- : m_state(plib::make_unique<netlist_state_t>(aname, *this, std::move(callbacks)))
- , m_solver(nullptr)
- , m_time(netlist_time::zero())
+netlist_t::netlist_t(const pstring &aname)
+ : m_time(netlist_time::zero())
+ , m_queue(*this)
, m_mainclock(nullptr)
- , m_queue(*m_state)
+ , m_solver(nullptr)
+ , m_params(nullptr)
+ , m_name(aname)
+ , m_log(*this)
+ , m_lib(nullptr)
+ , m_state()
{
- devices::initialize_factory(nlstate().setup().factory());
- NETLIST_NAME(base)(nlstate().setup());
- run_state_manager().save_item(this, static_cast<plib::state_manager_t::callback_t &>(m_queue), "m_queue");
- run_state_manager().save_item(this, m_time, "m_time");
+ state().save_item(this, static_cast<plib::state_manager_t::callback_t &>(m_queue), "m_queue");
+ state().save_item(this, m_time, "m_time");
+ m_setup = plib::make_unique<setup_t>(*this);
+ /* FIXME: doesn't really belong here */
+ NETLIST_NAME(base)(*m_setup);
}
-// ----------------------------------------------------------------------------------------
-// netlist_t
-// ----------------------------------------------------------------------------------------
+netlist_t::~netlist_t()
+{
+ m_nets.clear();
+ m_devices.clear();
+}
-netlist_state_t::netlist_state_t(const pstring &aname,
- netlist_t & anetlist,
- plib::unique_ptr<callbacks_t> &&callbacks)
-: m_name(aname)
-, m_netlist(anetlist)
-, m_state()
-, m_callbacks(std::move(callbacks)) // Order is important here
-, m_log(*m_callbacks)
-, m_setup(plib::make_unique<setup_t>(*this))
+nl_double netlist_t::gmin() const NL_NOEXCEPT
{
+ return solver()->gmin();
+}
+
+void netlist_t::register_dev(plib::owned_ptr<core_device_t> dev)
+{
+ for (auto & d : m_devices)
+ if (d->name() == dev->name())
+ log().fatal(MF_1_DUPLICATE_NAME_DEVICE_LIST, d->name());
+ m_devices.push_back(std::move(dev));
+}
+
+void netlist_t::remove_dev(core_device_t *dev)
+{
+ m_devices.erase(
+ std::remove_if(
+ m_devices.begin(),
+ m_devices.end(),
+ [&] (plib::owned_ptr<core_device_t> const& p)
+ {
+ return p.get() == dev;
+ }),
+ m_devices.end()
+ );
+}
+
+
+
+void netlist_t::start()
+{
+ setup().start_devices();
+
+ /* load the library ... */
+
+ /* make sure the solver and parameters are started first! */
+
+ for (auto & e : setup().m_device_factory)
+ {
+ if ( setup().factory().is_class<devices::NETLIB_NAME(solver)>(e.second)
+ || setup().factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second))
+ {
+ auto dev = plib::owned_ptr<device_t>(e.second->Create(*this, e.first));
+ register_dev(std::move(dev));
+ }
+ }
+
+ log().debug("Searching for mainclock and solver ...\n");
+
+ m_solver = get_single_device<devices::NETLIB_NAME(solver)>("solver");
+ m_params = get_single_device<devices::NETLIB_NAME(netlistparams)>("parameter");
+
+ /* create devices */
+
+ log().debug("Creating devices ...\n");
+ for (auto & e : setup().m_device_factory)
+ {
+ if ( !setup().factory().is_class<devices::NETLIB_NAME(solver)>(e.second)
+ && !setup().factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second))
+ {
+ auto dev = plib::owned_ptr<device_t>(e.second->Create(*this, e.first));
+ register_dev(std::move(dev));
+ }
+ }
+
+ log().debug("Searching for mainclock\n");
+ m_mainclock = get_single_device<devices::NETLIB_NAME(mainclock)>("mainclock");
+
+ bool use_deactivate = (m_params->m_use_deactivate() ? true : false);
+
+ for (auto &d : m_devices)
+ {
+ if (use_deactivate)
+ {
+ auto p = setup().m_param_values.find(d->name() + ".HINT_NO_DEACTIVATE");
+ if (p != setup().m_param_values.end())
+ {
+ //FIXME: turn this into a proper function
+ bool error;
+ auto v = p->second.as_double(&error);
+ if (error || std::abs(v - std::floor(v)) > 1e-6 )
+ log().fatal(MF_1_HND_VAL_NOT_SUPPORTED, p->second);
+ d->set_hint_deactivate(v == 0.0);
+ }
+ }
+ else
+ d->set_hint_deactivate(false);
+ }
+
pstring libpath = plib::util::environment("NL_BOOSTLIB", plib::util::buildpath({".", "nlboost.so"}));
m_lib = plib::make_unique<plib::dynlib>(libpath);
-}
+ /* resolve inputs */
+ setup().resolve_inputs();
+
+ log().verbose("looking for two terms connected to rail nets ...");
+ for (auto & t : get_device_list<analog::NETLIB_NAME(twoterm)>())
+ {
+ if (t->m_N.net().isRailNet() && t->m_P.net().isRailNet())
+ {
+ log().warning(MW_3_REMOVE_DEVICE_1_CONNECTED_ONLY_TO_RAILS_2_3,
+ t->name(), t->m_N.net().name(), t->m_P.net().name());
+ t->m_N.net().remove_terminal(t->m_N);
+ t->m_P.net().remove_terminal(t->m_P);
+ remove_dev(t);
+ }
+ }
+
+ log().verbose("initialize solver ...\n");
+
+ if (m_solver == nullptr)
+ {
+ for (auto &p : m_nets)
+ if (p->is_analog())
+ log().fatal(MF_0_NO_SOLVER);
+ }
+ else
+ m_solver->post_start();
+
+ for (auto &n : m_nets)
+ for (auto & term : n->m_core_terms)
+ {
+ //core_device_t *dev = reinterpret_cast<core_device_t *>(term->m_delegate.object());
+ core_device_t *dev = &term->device();
+ dev->set_default_delegate(*term);
+ }
+
+}
void netlist_t::stop()
{
@@ -277,7 +401,7 @@ void netlist_t::stop()
m_solver->stop();
}
-detail::net_t *netlist_state_t::find_net(const pstring &name) const
+detail::net_t *netlist_t::find_net(const pstring &name) const
{
for (auto & net : m_nets)
if (net->name() == name)
@@ -286,7 +410,7 @@ detail::net_t *netlist_state_t::find_net(const pstring &name) const
return nullptr;
}
-std::size_t netlist_state_t::find_net_id(const detail::net_t *net) const
+std::size_t netlist_t::find_net_id(const detail::net_t *net) const
{
for (std::size_t i = 0; i < m_nets.size(); i++)
if (m_nets[i].get() == net)
@@ -296,7 +420,7 @@ std::size_t netlist_state_t::find_net_id(const detail::net_t *net) const
-void netlist_state_t::rebuild_lists()
+void netlist_t::rebuild_lists()
{
for (auto & net : m_nets)
net->rebuild_list();
@@ -305,44 +429,32 @@ void netlist_state_t::rebuild_lists()
void netlist_t::reset()
{
- log().debug("Searching for mainclock\n");
- m_mainclock = m_state->get_single_device<devices::NETLIB_NAME(mainclock)>("mainclock");
-
- log().debug("Searching for solver\n");
- m_solver = m_state->get_single_device<devices::NETLIB_NAME(solver)>("solver");
-
m_time = netlist_time::zero();
m_queue.clear();
if (m_mainclock != nullptr)
- m_mainclock->m_Q.net().set_next_scheduled_time(netlist_time::zero());
+ m_mainclock->m_Q.net().set_time(netlist_time::zero());
//if (m_solver != nullptr)
- // m_solver->reset();
-
- m_state->reset();
-}
+ // m_solver->do_reset();
-void netlist_state_t::reset()
-{
- //FIXME: never used ???
std::unordered_map<core_device_t *, bool> m;
+ for (auto &d : m_devices)
+ {
+ m[d.get()] = d->get_hint_deactivate();
+ }
+
+
// Reset all nets once !
- log().verbose("Call reset on all nets:");
- for (auto & n : nets())
+ for (auto & n : m_nets)
n->reset();
// Reset all devices once !
- log().verbose("Call reset on all devices:");
for (auto & dev : m_devices)
- dev.second->reset();
+ dev->do_reset();
// Make sure everything depending on parameters is set
- // Currently analog input and logic input also
- // push their outputs to queue.
-
- log().verbose("Call update_param on all devices:");
for (auto & dev : m_devices)
- dev.second->update_param();
+ dev->update_param();
// Step all devices once !
/*
@@ -350,9 +462,9 @@ void netlist_state_t::reset()
* variations are explicitly stated in the breakout manual.
*/
- auto *netlist_params = get_single_device<devices::NETLIB_NAME(netlistparams)>("parameter");
+ const unsigned startup_strategy = 1; //! \note make this a parameter
- switch (netlist_params->m_startup_strategy())
+ switch (startup_strategy)
{
case 0:
{
@@ -360,7 +472,7 @@ void netlist_state_t::reset()
std::vector<nldelegate *> t;
log().verbose("Using default startup strategy");
for (auto &n : m_nets)
- for (auto & term : n->core_terms())
+ for (auto & term : n->m_core_terms)
if (term->m_delegate.has_object())
{
if (!plib::container::contains(t, &term->m_delegate))
@@ -368,68 +480,70 @@ void netlist_state_t::reset()
t.push_back(&term->m_delegate);
term->m_delegate();
}
- auto *dev = reinterpret_cast<core_device_t *>(term->m_delegate.object());
+ core_device_t *dev = reinterpret_cast<core_device_t *>(term->m_delegate.object());
if (!plib::container::contains(d, dev))
d.push_back(dev);
}
- log().verbose("Devices not yet updated:");
- for (auto &dev : m_devices)
- if (!plib::container::contains(d, dev.second.get()))
+ log().verbose("Call update on devices which need parameter update:");
+ for (auto & dev : m_devices)
+ if (dev->needs_update_after_param_change())
{
- log().verbose("\t ...{1}", dev.second->name());
- dev.second->update();
+ if (!plib::container::contains(d, dev.get()))
+ {
+ d.push_back(dev.get());
+ log().verbose("\t ...{1}", dev->name());
+ dev->update_dev();
+ }
}
+ log().verbose("Devices not yet updated:");
+ for (auto &dev : m_devices)
+ if (!plib::container::contains(d, dev.get()))
+ log().verbose("\t ...{1}", dev->name());
+ //x->update_dev();
}
break;
case 1: // brute force backward
{
- log().verbose("Using brute force backward startup strategy");
-
- for (auto &n : m_nets) // only used if USE_COPY_INSTEAD_OF_REFERENCE == 1
- n->update_inputs();
-
std::size_t i = m_devices.size();
while (i>0)
- m_devices[--i].second->update();
-
- for (auto &n : m_nets) // only used if USE_COPY_INSTEAD_OF_REFERENCE == 1
- n->update_inputs();
-
+ m_devices[--i]->update_dev();
}
break;
case 2: // brute force forward
{
- log().verbose("Using brute force forward startup strategy");
for (auto &d : m_devices)
- d.second->update();
+ d->update_dev();
}
break;
}
#if 1
/* the above may screw up m_active and the list */
- rebuild_lists();
+ for (auto &n : m_nets)
+ n->rebuild_list();
#endif
}
-void netlist_t::process_queue(const netlist_time delta) NL_NOEXCEPT
+void netlist_t::process_queue(const netlist_time &delta) NL_NOEXCEPT
{
- auto sm_guard(m_stat_mainloop.guard());
netlist_time stop(m_time + delta);
m_queue.push(detail::queue_t::entry_t(stop, nullptr));
+ m_stat_mainloop.start();
if (m_mainclock == nullptr)
{
- detail::queue_t::entry_t e(m_queue.pop());
+ detail::queue_t::entry_t e(m_queue.top());
+ m_queue.pop();
m_time = e.m_exec_time;
while (e.m_object != nullptr)
{
e.m_object->update_devs();
m_perf_out_processed.inc();
- e = m_queue.pop();
+ e = m_queue.top();
+ m_queue.pop();
m_time = e.m_exec_time;
}
}
@@ -437,7 +551,9 @@ void netlist_t::process_queue(const netlist_time delta) NL_NOEXCEPT
{
logic_net_t &mc_net(m_mainclock->m_Q.net());
const netlist_time inc(m_mainclock->m_inc);
- netlist_time mc_time(mc_net.next_scheduled_time());
+ netlist_time mc_time(mc_net.time());
+
+ detail::queue_t::entry_t e;
do
{
@@ -449,37 +565,37 @@ void netlist_t::process_queue(const netlist_time delta) NL_NOEXCEPT
mc_time += inc;
}
- detail::queue_t::entry_t e(m_queue.pop());
+ e = m_queue.top();
+ m_queue.pop();
m_time = e.m_exec_time;
if (e.m_object != nullptr)
{
e.m_object->update_devs();
m_perf_out_processed.inc();
}
- else
- break;
- } while (true); //while (e.m_object != nullptr);
- mc_net.set_next_scheduled_time(mc_time);
+ } while (e.m_object != nullptr);
+ mc_net.set_time(mc_time);
}
+ m_stat_mainloop.stop();
}
void netlist_t::print_stats() const
{
- if (nperftime_t<NL_KEEP_STATISTICS>::enabled)
+ if (nperftime_t::enabled)
{
std::vector<size_t> index;
- for (size_t i=0; i < m_state->m_devices.size(); i++)
+ for (size_t i=0; i<m_devices.size(); i++)
index.push_back(i);
std::sort(index.begin(), index.end(),
- [&](size_t i1, size_t i2) { return m_state->m_devices[i1].second->m_stat_total_time.total() < m_state->m_devices[i2].second->m_stat_total_time.total(); });
+ [&](size_t i1, size_t i2) { return m_devices[i1]->m_stat_total_time.total() < m_devices[i2]->m_stat_total_time.total(); });
- nperftime_t<NL_KEEP_STATISTICS>::type total_time(0);
- nperftime_t<NL_KEEP_STATISTICS>::ctype total_count(0);
+ nperftime_t::type total_time(0);
+ uint_least64_t total_count(0);
for (auto & j : index)
{
- auto entry = m_state->m_devices[j].second.get();
+ auto entry = m_devices[j].get();
log().verbose("Device {1:20} : {2:12} {3:12} {4:15} {5:12}", entry->name(),
entry->m_stat_call_count(), entry->m_stat_total_time.count(),
entry->m_stat_total_time.total(), entry->m_stat_inc_active());
@@ -487,27 +603,22 @@ void netlist_t::print_stats() const
total_count += entry->m_stat_total_time.count();
}
- log().verbose("Total calls : {1:12} {2:12} {3:12}", total_count,
- total_time, total_time / static_cast<decltype(total_time)>(total_count));
-
- nperftime_t<NL_KEEP_STATISTICS> overhead;
- nperftime_t<NL_KEEP_STATISTICS> test;
+ nperftime_t overhead;
+ nperftime_t test;
+ overhead.start();
+ for (int j=0; j<100000;j++)
{
- auto overhead_guard(overhead.guard());
- for (int j=0; j<100000;j++)
- {
- auto test_guard(test.guard());
- }
+ test.start();
+ test.stop();
}
+ overhead.stop();
- nperftime_t<NL_KEEP_STATISTICS>::type total_overhead = overhead()
- * static_cast<nperftime_t<NL_KEEP_STATISTICS>::type>(total_count)
- / static_cast<nperftime_t<NL_KEEP_STATISTICS>::type>(200000);
+ nperftime_t::type total_overhead = overhead()
+ * static_cast<nperftime_t::type>(total_count)
+ / static_cast<nperftime_t::type>(200000);
- log().verbose("Queue Pushes {1:15}", m_queue.m_prof_call());
- log().verbose("Queue Moves {1:15}", m_queue.m_prof_sortmove());
- log().verbose("Queue Removes {1:15}", m_queue.m_prof_remove());
- log().verbose("Queue Retimes {1:15}", m_queue.m_prof_retime());
+ log().verbose("Queue Pushes {1:15}", queue().m_prof_call());
+ log().verbose("Queue Moves {1:15}", queue().m_prof_sortmove());
log().verbose("Total loop {1:15}", m_stat_mainloop());
/* Only one serialization should be counted in total time */
@@ -516,36 +627,29 @@ void netlist_t::print_stats() const
log().verbose("");
log().verbose("Take the next lines with a grain of salt. They depend on the measurement implementation.");
log().verbose("Total overhead {1:15}", total_overhead);
- nperftime_t<NL_KEEP_STATISTICS>::type overhead_per_pop = (m_stat_mainloop()-2*total_overhead - (total_time - total_overhead))
- / static_cast<nperftime_t<NL_KEEP_STATISTICS>::type>(m_queue.m_prof_call());
+ nperftime_t::type overhead_per_pop = (m_stat_mainloop()-2*total_overhead - (total_time - total_overhead))
+ / static_cast<nperftime_t::type>(queue().m_prof_call());
log().verbose("Overhead per pop {1:11}", overhead_per_pop );
log().verbose("");
-
- auto trigger = total_count * 200 / 1000000; // 200 ppm
- for (auto &entry : m_state->m_devices)
+ for (auto &entry : m_devices)
{
- auto ep = entry.second.get();
- // Factor of 3 offers best performace increase
- if (ep->m_stat_inc_active() > 3 * ep->m_stat_total_time.count()
- && ep->m_stat_inc_active() > trigger)
- log().verbose("HINT({}, NO_DEACTIVATE) // {} {} {}", ep->name(),
- static_cast<double>(ep->m_stat_inc_active()) / static_cast<double>(ep->m_stat_total_time.count()),
- ep->m_stat_inc_active(), ep->m_stat_total_time.count());
+ if (entry->m_stat_inc_active() > 3 * entry->m_stat_total_time.count())
+ log().verbose("HINT({}, NO_DEACTIVATE)", entry->name());
}
}
}
-core_device_t *netlist_state_t::get_single_device(const pstring &classname, bool (*cc)(core_device_t *)) const
+core_device_t *netlist_t::get_single_device(const pstring &classname, bool (*cc)(core_device_t *)) const
{
core_device_t *ret = nullptr;
for (auto &d : m_devices)
{
- if (cc(d.second.get()))
+ if (cc(d.get()))
{
if (ret != nullptr)
- m_log.fatal(MF_1_MORE_THAN_ONE_1_DEVICE_FOUND, classname);
+ this->log().fatal(MF_1_MORE_THAN_ONE_1_DEVICE_FOUND, classname);
else
- ret = d.second.get();
+ ret = d.get();
}
}
return ret;
@@ -556,12 +660,11 @@ core_device_t *netlist_state_t::get_single_device(const pstring &classname, bool
// core_device_t
// ----------------------------------------------------------------------------------------
-core_device_t::core_device_t(netlist_state_t &owner, const pstring &name)
+core_device_t::core_device_t(netlist_t &owner, const pstring &name)
: object_t(name)
, logic_family_t()
, netlist_ref(owner)
, m_hint_deactivate(false)
- , m_active_outputs(*this, "m_active_outputs", 1)
{
if (logic_family() == nullptr)
set_logic_family(family_TTL());
@@ -570,14 +673,17 @@ core_device_t::core_device_t(netlist_state_t &owner, const pstring &name)
core_device_t::core_device_t(core_device_t &owner, const pstring &name)
: object_t(owner.name() + "." + name)
, logic_family_t()
- , netlist_ref(owner.state())
+ , netlist_ref(owner.netlist())
, m_hint_deactivate(false)
- , m_active_outputs(*this, "m_active_outputs", 1)
{
set_logic_family(owner.logic_family());
if (logic_family() == nullptr)
set_logic_family(family_TTL());
- state().add_dev(this->name(), pool_owned_ptr<core_device_t>(this, false));
+ owner.netlist().register_dev(plib::owned_ptr<core_device_t>(this, false));
+}
+
+core_device_t::~core_device_t()
+{
}
void core_device_t::set_default_delegate(detail::core_terminal_t &term)
@@ -586,16 +692,16 @@ void core_device_t::set_default_delegate(detail::core_terminal_t &term)
term.m_delegate.set(&core_device_t::update, this);
}
-log_type & core_device_t::log()
+plib::plog_base<netlist_t, NL_DEBUG> &core_device_t::log()
{
- return state().log();
+ return netlist().log();
}
// ----------------------------------------------------------------------------------------
// device_t
// ----------------------------------------------------------------------------------------
-device_t::device_t(netlist_state_t &owner, const pstring &name)
+device_t::device_t(netlist_t &owner, const pstring &name)
: core_device_t(owner, name)
{
}
@@ -605,14 +711,14 @@ device_t::device_t(core_device_t &owner, const pstring &name)
{
}
-setup_t &device_t::setup()
+device_t::~device_t()
{
- return state().setup();
+ //log().debug("~net_device_t\n");
}
-const setup_t &device_t::setup() const
+setup_t &device_t::setup()
{
- return state().setup();
+ return netlist().setup();
}
void device_t::register_subalias(const pstring &name, detail::core_terminal_t &term)
@@ -656,14 +762,9 @@ void device_t::connect_post_start(detail::core_terminal_t &t1, detail::core_term
// family_setter_t
// -----------------------------------------------------------------------------
-// NOLINTNEXTLINE(modernize-use-equals-default)
-detail::family_setter_t::family_setter_t()
-{
-}
-
detail::family_setter_t::family_setter_t(core_device_t &dev, const pstring &desc)
{
- dev.set_logic_family(dev.setup().family_from_model(desc));
+ dev.set_logic_family(dev.netlist().setup().family_from_model(desc));
}
detail::family_setter_t::family_setter_t(core_device_t &dev, const logic_family_desc_t *desc)
@@ -675,45 +776,81 @@ detail::family_setter_t::family_setter_t(core_device_t &dev, const logic_family_
// net_t
// ----------------------------------------------------------------------------------------
-detail::net_t::net_t(netlist_state_t &nl, const pstring &aname, core_terminal_t *mr)
+detail::net_t::net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr)
: object_t(aname)
, netlist_ref(nl)
, m_new_Q(*this, "m_new_Q", 0)
, m_cur_Q (*this, "m_cur_Q", 0)
- , m_in_queue(*this, "m_in_queue", queue_status::DELIVERED)
- , m_next_scheduled_time(*this, "m_time", netlist_time::zero())
+ , m_in_queue(*this, "m_in_queue", QS_DELIVERED)
+ , m_active(*this, "m_active", 0)
+ , m_time(*this, "m_time", netlist_time::zero())
, m_railterminal(mr)
{
}
+detail::net_t::~net_t()
+{
+ netlist().state().remove_save_items(this);
+}
+
+void detail::net_t::inc_active(core_terminal_t &term) NL_NOEXCEPT
+{
+ m_list_active.push_front(&term);
+ ++m_active;
+ nl_assert(m_active <= static_cast<int>(num_cons()));
+ if (m_active == 1)
+ {
+ railterminal().device().do_inc_active();
+ if (m_in_queue == QS_DELAYED_DUE_TO_INACTIVE)
+ {
+ if (m_time > netlist().time())
+ {
+ m_in_queue = QS_QUEUED; /* pending */
+ netlist().queue().push({m_time, this});
+ }
+ else
+ {
+ m_in_queue = QS_DELIVERED;
+ m_cur_Q = m_new_Q;
+ }
+ }
+ }
+}
+
+void detail::net_t::dec_active(core_terminal_t &term) NL_NOEXCEPT
+{
+ --m_active;
+ nl_assert(m_active >= 0);
+ m_list_active.remove(&term);
+ if (m_active == 0)
+ railterminal().device().do_dec_active();
+}
+
void detail::net_t::rebuild_list()
{
/* rebuild m_list */
+ int cnt = 0;
m_list_active.clear();
for (auto & term : m_core_terms)
- if (term->terminal_state() != logic_t::STATE_INP_PASSIVE)
+ if (term->state() != logic_t::STATE_INP_PASSIVE)
{
m_list_active.push_back(term);
- term->set_copied_input(m_cur_Q);
+ cnt++;
}
+ m_active = cnt;
}
-template <typename T>
-void detail::net_t::process(const T mask, netlist_sig_t sig)
-{
- m_cur_Q = sig;
+void detail::net_t::process(unsigned Mask)
+{
for (auto & p : m_list_active)
{
- p.set_copied_input(sig);
-
p.device().m_stat_call_count.inc();
- if ((p.terminal_state() & mask))
+ if ((p.state() & Mask) != 0)
{
- auto g(p.device().m_stat_total_time.guard());
- //p.device().m_stat_total_time.start();
+ p.device().m_stat_total_time.start();
p.m_delegate();
- //p.device().m_stat_total_time.stop();
+ p.device().m_stat_total_time.stop();
}
}
}
@@ -722,59 +859,67 @@ void detail::net_t::update_devs() NL_NOEXCEPT
{
nl_assert(this->isRailNet());
- const auto new_Q(m_new_Q);
+ const unsigned mask((m_new_Q << core_terminal_t::INP_LH_SHIFT)
+ | (m_cur_Q<<core_terminal_t::INP_HL_SHIFT));
- const auto mask((new_Q << core_terminal_t::INP_LH_SHIFT)
- | (m_cur_Q << core_terminal_t::INP_HL_SHIFT));
+ m_in_queue = QS_DELIVERED; /* mark as taken ... */
- m_in_queue = queue_status::DELIVERED; /* mark as taken ... */
switch (mask)
{
case core_terminal_t::STATE_INP_HL:
+ m_cur_Q = m_new_Q;
+ process(core_terminal_t::STATE_INP_HL | core_terminal_t::STATE_INP_ACTIVE);
+ break;
case core_terminal_t::STATE_INP_LH:
- process(mask | core_terminal_t::STATE_INP_ACTIVE, new_Q);
+ m_cur_Q = m_new_Q;
+ process(core_terminal_t::STATE_INP_LH | core_terminal_t::STATE_INP_ACTIVE);
break;
default:
- /* do nothing */
break;
}
}
void detail::net_t::reset()
{
- m_next_scheduled_time = netlist_time::zero();
- m_in_queue = queue_status::DELIVERED;
+ m_time = netlist_time::zero();
+ m_active = 0;
+ m_in_queue = QS_DELIVERED;
m_new_Q = 0;
m_cur_Q = 0;
- auto *p = dynamic_cast<analog_net_t *>(this);
+ analog_net_t *p = dynamic_cast<analog_net_t *>(this);
if (p != nullptr)
p->m_cur_Analog = 0.0;
- /* rebuild m_list and reset terminals to active or analog out state */
+ /* rebuild m_list */
m_list_active.clear();
for (core_terminal_t *ct : m_core_terms)
- {
+ m_list_active.push_back(ct);
+
+ for (core_terminal_t *ct : m_core_terms)
ct->reset();
- if (ct->terminal_state() != logic_t::STATE_INP_PASSIVE)
- m_list_active.push_back(ct);
- ct->set_copied_input(m_cur_Q);
- }
+
+ for (core_terminal_t *ct : m_core_terms)
+ if (ct->state() != logic_t::STATE_INP_PASSIVE)
+ m_active++;
}
void detail::net_t::add_terminal(detail::core_terminal_t &terminal)
{
for (auto &t : m_core_terms)
if (t == &terminal)
- state().log().fatal(MF_2_NET_1_DUPLICATE_TERMINAL_2, name(),
+ netlist().log().fatal(MF_2_NET_1_DUPLICATE_TERMINAL_2, name(),
t->name());
terminal.set_net(this);
m_core_terms.push_back(&terminal);
+
+ if (terminal.state() != logic_t::STATE_INP_PASSIVE)
+ m_active++;
}
void detail::net_t::remove_terminal(detail::core_terminal_t &terminal)
@@ -785,8 +930,10 @@ void detail::net_t::remove_terminal(detail::core_terminal_t &terminal)
plib::container::remove(m_core_terms, &terminal);
}
else
- state().log().fatal(MF_2_REMOVE_TERMINAL_1_FROM_NET_2, terminal.name(),
+ netlist().log().fatal(MF_2_REMOVE_TERMINAL_1_FROM_NET_2, terminal.name(),
this->name());
+ if (terminal.state() != logic_t::STATE_INP_PASSIVE)
+ m_active--;
}
void detail::net_t::move_connections(detail::net_t &dest_net)
@@ -794,28 +941,37 @@ void detail::net_t::move_connections(detail::net_t &dest_net)
for (auto &ct : m_core_terms)
dest_net.add_terminal(*ct);
m_core_terms.clear();
+ m_active = 0;
}
// ----------------------------------------------------------------------------------------
// logic_net_t
// ----------------------------------------------------------------------------------------
-logic_net_t::logic_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *mr)
+logic_net_t::logic_net_t(netlist_t &nl, const pstring &aname, detail::core_terminal_t *mr)
: net_t(nl, aname, mr)
{
}
+logic_net_t::~logic_net_t()
+{
+}
+
// ----------------------------------------------------------------------------------------
// analog_net_t
// ----------------------------------------------------------------------------------------
-analog_net_t::analog_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *mr)
+analog_net_t::analog_net_t(netlist_t &nl, const pstring &aname, detail::core_terminal_t *mr)
: net_t(nl, aname, mr)
, m_cur_Analog(*this, "m_cur_Analog", 0.0)
, m_solver(nullptr)
{
}
+analog_net_t::~analog_net_t()
+{
+}
+
// ----------------------------------------------------------------------------------------
// core_terminal_t
// ----------------------------------------------------------------------------------------
@@ -825,19 +981,42 @@ detail::core_terminal_t::core_terminal_t(core_device_t &dev, const pstring &anam
: device_object_t(dev, dev.name() + "." + aname)
, plib::linkedlist_t<core_terminal_t>::element_t()
, m_delegate(delegate)
-#if USE_COPY_INSTEAD_OF_REFERENCE
-, m_Q(*this, "m_Q", 0)
-#endif
, m_net(nullptr)
, m_state(*this, "m_state", state)
{
}
+detail::core_terminal_t::~core_terminal_t()
+{
+}
+
+void detail::core_terminal_t::reset()
+{
+ if (is_type(OUTPUT))
+ set_state(STATE_OUT);
+ else
+ set_state(STATE_INP_ACTIVE);
+}
+
+void detail::core_terminal_t::set_net(net_t *anet)
+{
+ m_net = anet;
+}
+
+void detail::core_terminal_t::clear_net()
+{
+ m_net = nullptr;
+}
+
analog_t::analog_t(core_device_t &dev, const pstring &aname, const state_e state)
: core_terminal_t(dev, aname, state)
{
}
+analog_t::~analog_t()
+{
+}
+
logic_t::logic_t(core_device_t &dev, const pstring &aname, const state_e state,
nldelegate delegate)
: core_terminal_t(dev, aname, state, delegate)
@@ -846,18 +1025,26 @@ logic_t::logic_t(core_device_t &dev, const pstring &aname, const state_e state,
{
}
+logic_t::~logic_t()
+{
+}
+
// ----------------------------------------------------------------------------------------
// terminal_t
// ----------------------------------------------------------------------------------------
-terminal_t::terminal_t(core_device_t &dev, const pstring &aname, terminal_t *otherterm)
+terminal_t::terminal_t(core_device_t &dev, const pstring &aname)
: analog_t(dev, aname, STATE_BIDIR)
+, m_otherterm(nullptr)
, m_Idr1(nullptr)
, m_go1(nullptr)
, m_gt1(nullptr)
-, m_connected_terminal(otherterm)
{
- state().setup().register_term(*this);
+ netlist().setup().register_term(*this);
+}
+
+terminal_t::~terminal_t()
+{
}
void terminal_t::solve_now()
@@ -868,7 +1055,7 @@ void terminal_t::solve_now()
net().solver()->update_forced();
}
-void terminal_t::schedule_solve_after(const netlist_time after)
+void terminal_t::schedule_solve_after(const netlist_time &after)
{
// Nets may belong to railnets which do not have a solver attached
if (this->has_net())
@@ -890,12 +1077,16 @@ void terminal_t::schedule_solve_after(const netlist_time after)
logic_output_t::logic_output_t(core_device_t &dev, const pstring &aname)
: logic_t(dev, aname, STATE_OUT)
- , m_my_net(dev.state(), name() + ".net", this)
+ , m_my_net(dev.netlist(), name() + ".net", this)
{
this->set_net(&m_my_net);
- state().register_net(pool_owned_ptr<logic_net_t>(&m_my_net, false));
+ netlist().m_nets.push_back(plib::owned_ptr<logic_net_t>(&m_my_net, false));
set_logic_family(dev.logic_family());
- state().setup().register_term(*this);
+ netlist().setup().register_term(*this);
+}
+
+logic_output_t::~logic_output_t()
+{
}
void logic_output_t::initial(const netlist_sig_t val)
@@ -911,7 +1102,11 @@ void logic_output_t::initial(const netlist_sig_t val)
analog_input_t::analog_input_t(core_device_t &dev, const pstring &aname)
: analog_t(dev, aname, STATE_INP_ACTIVE)
{
- state().setup().register_term(*this);
+ netlist().setup().register_term(*this);
+}
+
+analog_input_t::~analog_input_t()
+{
}
// ----------------------------------------------------------------------------------------
@@ -920,13 +1115,17 @@ analog_input_t::analog_input_t(core_device_t &dev, const pstring &aname)
analog_output_t::analog_output_t(core_device_t &dev, const pstring &aname)
: analog_t(dev, aname, STATE_OUT)
- , m_my_net(dev.state(), name() + ".net", this)
+ , m_my_net(dev.netlist(), name() + ".net", this)
{
- state().register_net(pool_owned_ptr<analog_net_t>(&m_my_net, false));
+ netlist().m_nets.push_back(plib::owned_ptr<analog_net_t>(&m_my_net, false));
this->set_net(&m_my_net);
//net().m_cur_Analog = NL_FCONST(0.0);
- state().setup().register_term(*this);
+ netlist().setup().register_term(*this);
+}
+
+analog_output_t::~analog_output_t()
+{
}
void analog_output_t::initial(const nl_double val)
@@ -943,7 +1142,11 @@ logic_input_t::logic_input_t(core_device_t &dev, const pstring &aname,
: logic_t(dev, aname, STATE_INP_ACTIVE, delegate)
{
set_logic_family(dev.logic_family());
- state().setup().register_term(*this);
+ netlist().setup().register_term(*this);
+}
+
+logic_input_t::~logic_input_t()
+{
}
// ----------------------------------------------------------------------------------------
@@ -953,7 +1156,11 @@ logic_input_t::logic_input_t(core_device_t &dev, const pstring &aname,
param_t::param_t(device_t &device, const pstring &name)
: device_object_t(device, device.name() + "." + name)
{
- device.setup().register_param_t(this->name(), *this);
+ device.setup().register_param(this->name(), *this);
+}
+
+param_t::~param_t()
+{
}
param_t::param_type_t param_t::param_type() const
@@ -970,7 +1177,7 @@ param_t::param_type_t param_t::param_type() const
return POINTER;
else
{
- state().log().fatal(MF_1_UNKNOWN_PARAM_TYPE, name());
+ netlist().log().fatal(MF_1_UNKNOWN_PARAM_TYPE, name());
return POINTER; /* Please compiler */
}
}
@@ -979,18 +1186,15 @@ param_t::param_type_t param_t::param_type() const
void param_t::update_param()
{
device().update_param();
-}
-
-pstring param_t::get_initial(const device_t &dev, bool *found)
-{
- pstring res = dev.setup().get_initial_param_val(this->name(), "");
- *found = (res != "");
- return res;
+ if (device().needs_update_after_param_change())
+ device().update_dev();
}
const pstring param_model_t::model_type()
{
- return state().setup().models().model_type(value());
+ if (m_map.size() == 0)
+ netlist().setup().model_parse(this->Value(), m_map);
+ return m_map["COREMODEL"];
}
param_str_t::param_str_t(device_t &device, const pstring &name, const pstring &val)
@@ -999,10 +1203,35 @@ param_str_t::param_str_t(device_t &device, const pstring &name, const pstring &v
m_param = device.setup().get_initial_param_val(this->name(),val);
}
+param_str_t::~param_str_t()
+{
+}
+
void param_str_t::changed()
{
}
+param_double_t::param_double_t(device_t &device, const pstring &name, const double val)
+: param_t(device, name)
+{
+ m_param = device.setup().get_initial_param_val(this->name(),val);
+ netlist().save(*this, m_param, "m_param");
+}
+
+param_int_t::param_int_t(device_t &device, const pstring &name, const int val)
+: param_t(device, name)
+{
+ m_param = device.setup().get_initial_param_val(this->name(),val);
+ netlist().save(*this, m_param, "m_param");
+}
+
+param_logic_t::param_logic_t(device_t &device, const pstring &name, const bool val)
+: param_t(device, name)
+{
+ m_param = device.setup().get_initial_param_val(this->name(),val);
+ netlist().save(*this, m_param, "m_param");
+}
+
param_ptr_t::param_ptr_t(device_t &device, const pstring &name, uint8_t * val)
: param_t(device, name)
{
@@ -1012,25 +1241,53 @@ param_ptr_t::param_ptr_t(device_t &device, const pstring &name, uint8_t * val)
void param_model_t::changed()
{
- state().log().fatal(MF_1_MODEL_1_CAN_NOT_BE_CHANGED_AT_RUNTIME, name());
+ netlist().log().fatal(MF_1_MODEL_1_CAN_NOT_BE_CHANGED_AT_RUNTIME, name());
+ m_map.clear();
}
const pstring param_model_t::model_value_str(const pstring &entity)
{
- return state().setup().models().model_value_str(value(), entity);
+ if (m_map.size() == 0)
+ netlist().setup().model_parse(this->Value(), m_map);
+ return netlist().setup().model_value_str(m_map, entity);
}
nl_double param_model_t::model_value(const pstring &entity)
{
- return state().setup().models().model_value(value(), entity);
+ if (m_map.size() == 0)
+ netlist().setup().model_parse(this->Value(), m_map);
+ return netlist().setup().model_value(m_map, entity);
}
+param_data_t::param_data_t(device_t &device, const pstring &name)
+: param_str_t(device, name, "")
+{
+}
+
+void param_data_t::changed()
+{
+}
-plib::unique_ptr<plib::pistream> param_data_t::stream()
+std::unique_ptr<plib::pistream> param_data_t::stream()
{
- return device().setup().get_data_stream(value());
+ return device().netlist().setup().get_data_stream(Value());
}
+ namespace devices
+ {
+ // ----------------------------------------------------------------------------------------
+ // mainclock
+ // ----------------------------------------------------------------------------------------
+
+ void NETLIB_NAME(mainclock)::mc_update(logic_net_t &net)
+ {
+ net.toggle_new_Q();
+ net.update_devs();
+ }
+
+
+ } //namespace devices
+
bool detail::core_terminal_t::is_logic() const NL_NOEXCEPT
{
return dynamic_cast<const logic_t *>(this) != nullptr;
diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h
index 9d0eed869e0..e56fde89f88 100644
--- a/src/lib/netlist/nl_base.h
+++ b/src/lib/netlist/nl_base.h
@@ -9,25 +9,27 @@
#ifndef NLBASE_H_
#define NLBASE_H_
-#ifdef NL_PROHIBIT_BASEH_INCLUDE
-#error "nl_base.h included. Please correct."
-#endif
-
+#include "nl_lists.h"
+#include "nl_time.h"
#include "plib/palloc.h" // owned_ptr
#include "plib/pdynlib.h"
-#include "plib/pfmtlog.h"
-#include "plib/pmempool.h"
-#include "plib/ppmf.h"
#include "plib/pstate.h"
+#include "plib/pfmtlog.h"
#include "plib/pstream.h"
-
-#include "nl_errstr.h"
-#include "nl_lists.h"
-#include "nltypes.h"
-#include "plib/ptime.h"
+#include "plib/ppmf.h"
#include <unordered_map>
-#include <vector>
+
+#ifdef NL_PROHIBIT_BASEH_INCLUDE
+#error "nl_base.h included. Please correct."
+#endif
+
+// ----------------------------------------------------------------------------------------
+// Type definitions
+// ----------------------------------------------------------------------------------------
+
+/*! netlist_sig_t is the type used for logic signals. */
+using netlist_sig_t = std::uint32_t;
//============================================================
// MACROS / New Syntax
@@ -71,7 +73,7 @@ class NETLIB_NAME(name) : public device_t
/*! 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 NETLIB_DESTRUCTOR(name) public: virtual ~NETLIB_NAME(name)()
/*! Define an extended constructor and add further parameters to it.
* The macro allows to add further parameters to a device constructor. This is
@@ -83,15 +85,14 @@ class NETLIB_NAME(name) : public device_t
: 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.
- */
+ * 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.
+ */
#define NETLIB_IS_DYNAMIC(expr) \
public: virtual bool is_dynamic() const override { return expr; }
@@ -126,30 +127,36 @@ class NETLIB_NAME(name) : public device_t
#define NETLIB_TIMESTEPI() \
public: virtual void timestep(const nl_double step) override
+#define NETLIB_UPDATE_AFTER_PARAM_CHANGE() \
+ public: virtual bool needs_update_after_param_change() const override { return true; }
+
#define NETLIB_FAMILY(family) , m_famsetter(*this, family)
#define NETLIB_DELEGATE(chip, name) nldelegate(&NETLIB_NAME(chip) :: name, this)
-#define NETLIB_UPDATE_TERMINALSI() virtual void update_terminals() override
-#define NETLIB_HANDLERI(name) virtual void name() NL_NOEXCEPT
-#define NETLIB_UPDATEI() virtual void update() NL_NOEXCEPT override
-#define NETLIB_UPDATE_PARAMI() virtual void update_param() override
-#define NETLIB_RESETI() virtual void reset() override
+#define NETLIB_UPDATE_TERMINALSI() public: virtual void update_terminals() override
+#define NETLIB_HANDLERI(name) private: virtual void name() NL_NOEXCEPT
+#define NETLIB_UPDATEI() protected: virtual void update() NL_NOEXCEPT override
+#define NETLIB_UPDATE_PARAMI() public: virtual void update_param() override
+#define NETLIB_RESETI() protected: virtual void reset() override
#define NETLIB_TIMESTEP(chip) void NETLIB_NAME(chip) :: timestep(const nl_double step)
#define NETLIB_SUB(chip) nld_ ## chip
-#define NETLIB_SUBXX(ns, chip) pool_owned_ptr< ns :: nld_ ## chip >
+#define NETLIB_SUBXX(ns, chip) std::unique_ptr< ns :: nld_ ## chip >
-#define NETLIB_HANDLER(chip, name) void NETLIB_NAME(chip) :: name() NL_NOEXCEPT
+#define NETLIB_HANDLER(chip, name) void NETLIB_NAME(chip) :: name(void) NL_NOEXCEPT
#define NETLIB_UPDATE(chip) NETLIB_HANDLER(chip, update)
+// FIXME: NETLIB_PARENT_UPDATE should disappear
+#define NETLIB_PARENT_UPDATE(chip) NETLIB_NAME(chip) :: update();
+
#define NETLIB_RESET(chip) void NETLIB_NAME(chip) :: reset(void)
-#define NETLIB_UPDATE_PARAM(chip) void NETLIB_NAME(chip) :: update_param()
+#define NETLIB_UPDATE_PARAM(chip) void NETLIB_NAME(chip) :: update_param(void)
#define NETLIB_FUNC_VOID(chip, name, params) void NETLIB_NAME(chip) :: name params
-#define NETLIB_UPDATE_TERMINALS(chip) void NETLIB_NAME(chip) :: update_terminals()
+#define NETLIB_UPDATE_TERMINALS(chip) void NETLIB_NAME(chip) :: update_terminals(void)
//============================================================
// Asserts
@@ -162,7 +169,7 @@ class NETLIB_NAME(name) : public device_t
#define nl_assert(x) do { if (0) if (!(x)) { /*throw nl_exception(plib::pfmt("assert: {1}:{2}: {3}")(__FILE__)(__LINE__)(#x) ); */} } while (0)
#define NL_NOEXCEPT noexcept
#endif
-#define nl_assert_always(x, msg) do { if (!(x)) throw nl_exception("Fatal error: {1}\nCaused by assert: {2}:{3}: {4}", msg, __FILE__, __LINE__, #x); } while (0)
+#define nl_assert_always(x, msg) do { if (!(x)) throw nl_exception(plib::pfmt("Fatal error: {1}\nCaused by assert: {2}:{3}: {4}")(msg)(__FILE__)(__LINE__)(#x)); } while (0)
//============================================================
// Namespace starts
@@ -170,11 +177,6 @@ class NETLIB_NAME(name) : public device_t
namespace netlist
{
- /*! Delegate type for device notification.
- *
- */
- using nldelegate = plib::pmfp<void>;
-
// -----------------------------------------------------------------------------
// forward definitions
// -----------------------------------------------------------------------------
@@ -189,23 +191,27 @@ namespace netlist
class NETLIB_NAME(base_proxy);
class NETLIB_NAME(base_d_to_a_proxy);
class NETLIB_NAME(base_a_to_d_proxy);
- } // namespace devices
+ }
namespace detail {
+ class object_t;
+ class device_object_t;
+ struct netlist_ref;
+ class core_terminal_t;
struct family_setter_t;
class queue_t;
- } // namespace detail
+ class net_t;
+ }
class logic_output_t;
class logic_input_t;
class analog_net_t;
class logic_net_t;
+ class net_t;
class setup_t;
class netlist_t;
- class netlist_state_t;
class core_device_t;
class device_t;
- class callbacks_t;
//============================================================
// Exceptions
@@ -223,12 +229,9 @@ namespace netlist
explicit nl_exception(const pstring &text //!< text to be passed
)
: plib::pexception(text) { }
-
- template<typename... Args>
- explicit nl_exception(const pstring &fmt //!< format to be used
- , Args&&... args //!< arguments to be passed
- )
- : plib::pexception(plib::pfmt(fmt)(std::forward<Args>(args)...)) { }
+ /*! Copy constructor. */
+ nl_exception(const nl_exception &e) : plib::pexception(e) { }
+ virtual ~nl_exception();
};
/*! Logic families descriptors are used to create proxy devices.
@@ -239,21 +242,18 @@ namespace netlist
{
public:
logic_family_desc_t();
+ virtual ~logic_family_desc_t();
- COPYASSIGNMOVE(logic_family_desc_t, delete)
-
- virtual ~logic_family_desc_t() noexcept = default;
-
- virtual pool_owned_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_state_t &anetlist, const pstring &name,
+ virtual plib::owned_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_t &anetlist, const pstring &name,
logic_output_t *proxied) const = 0;
- virtual pool_owned_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_state_t &anetlist, const pstring &name,
+ virtual plib::owned_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_t &anetlist, const pstring &name,
logic_input_t *proxied) const = 0;
double fixed_V() const { return m_fixed_V; }
double low_thresh_V(const double VN, const double VP) const { return VN + (VP - VN) * m_low_thresh_PCNT; }
double high_thresh_V(const double VN, const double VP) const { return VN + (VP - VN) * m_high_thresh_PCNT; }
- double low_V(const double VN, const double VP) const { plib::unused_var(VP); return VN + m_low_VO; }
- double high_V(const double VN, const double VP) const { plib::unused_var(VN); return VP - m_high_VO; }
+ double low_V(const double VN, const double VP) const { return VN + m_low_VO; }
+ double high_V(const double VN, const double VP) const { return VP - m_high_VO; }
double R_low() const { return m_R_low; }
double R_high() const { return m_R_high; }
@@ -282,14 +282,12 @@ namespace netlist
public:
logic_family_t() : m_logic_family(nullptr) {}
- COPYASSIGNMOVE(logic_family_t, delete)
-
const logic_family_desc_t *logic_family() const { return m_logic_family; }
void set_logic_family(const logic_family_desc_t *fam) { m_logic_family = fam; }
protected:
- ~logic_family_t() noexcept = default; // prohibit polymorphic destruction
+ ~logic_family_t() { } // prohibit polymorphic destruction
const logic_family_desc_t *m_logic_family;
};
@@ -319,15 +317,12 @@ namespace netlist
const pstring &name, //!< identifier/name for this state variable
const T &value //!< Initial value after construction
);
-
- //! Destructor.
- ~state_var() noexcept = default;
//! Copy Constructor.
- constexpr state_var(const state_var &rhs) = default;
+ constexpr state_var(const state_var &rhs) noexcept = default;
//! 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) = default;
+ C14CONSTEXPR state_var &operator=(const state_var &rhs) noexcept = default;
//! 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.
@@ -350,29 +345,25 @@ namespace netlist
* Please refer to \ref state_var.
*/
template <typename T, std::size_t N>
- struct state_array
+ struct state_var<T[N]>
{
public:
//! Constructor.
template <typename O>
- state_array(O &owner, //!< owner must have a netlist() method.
+ state_var(O &owner, //!< owner must have a netlist() method.
const pstring &name, //!< identifier/name for this state variable
const T &value //!< Initial value after construction
);
//! Copy Constructor.
- state_array(const state_array &rhs) noexcept = default;
- //! Destructor.
- ~state_array() noexcept = default;
+ state_var(const state_var &rhs) NL_NOEXCEPT = default;
//! Move Constructor.
- state_array(state_array &&rhs) noexcept = default;
- state_array &operator=(const state_array &rhs) noexcept = default;
- state_array &operator=(state_array &&rhs) noexcept = default;
-
- state_array &operator=(const T &rhs) noexcept { m_value = rhs; return *this; }
- T & operator[](const std::size_t i) noexcept { return m_value[i]; }
- constexpr const T & operator[](const std::size_t i) const noexcept { return m_value[i]; }
+ state_var(state_var &&rhs) NL_NOEXCEPT = default;
+ state_var &operator=(const state_var &rhs) NL_NOEXCEPT = default;
+ state_var &operator=(const T &rhs) NL_NOEXCEPT { m_value = rhs; return *this; }
+ T & operator[](const std::size_t i) NL_NOEXCEPT { return m_value[i]; }
+ constexpr T & operator[](const std::size_t i) const NL_NOEXCEPT { return m_value[i]; }
private:
- std::array<T, N> m_value;
+ T m_value[N];
};
// -----------------------------------------------------------------------------
@@ -391,324 +382,164 @@ namespace netlist
/*! predefined state variable type for sig_t */
using state_var_sig = state_var<netlist_sig_t>;
- namespace detail {
+ // -----------------------------------------------------------------------------
+ // object_t
+ // -----------------------------------------------------------------------------
- // -----------------------------------------------------------------------------
- // 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.
+ */
+ class detail::object_t
+ {
+ public:
- /*! The base class for netlist devices, terminals and parameters.
+ /*! Constructor.
*
- * 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.
+ * Every class derived from the object_t class must have a name.
*/
- 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 */);
-
- COPYASSIGNMOVE(object_t, delete)
- /*! return name of the object
- *
- * \returns name of the object.
- */
- pstring name() const;
-
- #if 0
- void * operator new (size_t size, void *ptr) { plib::unused_var(size); return ptr; }
- void operator delete (void *ptr, void *) { plib::unused_var(ptr); }
- void * operator new (size_t size) = delete;
- void operator delete (void * mem) = delete;
- #endif
- protected:
- ~object_t() noexcept = default; // only childs should be destructible
+ explicit object_t(const pstring &aname /*!< string containing name of the object */);
- private:
- //pstring m_name;
- static std::unordered_map<const object_t *, pstring> &name_hash()
- {
- static std::unordered_map<const object_t *, pstring> lhash;
- return lhash;
- }
- };
-
- struct netlist_ref
- {
- explicit netlist_ref(netlist_state_t &nl);
+ /*! return name of the object
+ *
+ * \returns name of the object.
+ */
+ const pstring &name() const;
- COPYASSIGNMOVE(netlist_ref, delete)
+ void * operator new (size_t size, void *ptr) { return ptr; }
+ void operator delete (void *ptr, void *) { }
+ void * operator new (size_t size);
+ void operator delete (void * mem);
+ protected:
+ ~object_t(); // only childs should be destructible
- netlist_state_t & state() noexcept;
- const netlist_state_t & state() const noexcept;
+ private:
+ std::unique_ptr<pstring> m_name;
+ };
- setup_t & setup() noexcept;
- const setup_t & setup() const noexcept;
+ struct detail::netlist_ref
+ {
+ explicit constexpr netlist_ref(netlist_t &nl) : m_netlist(nl) { }
- netlist_t & exec() noexcept { return m_netlist; }
- const netlist_t & exec() const noexcept { return m_netlist; }
+ C14CONSTEXPR netlist_t & netlist() NL_NOEXCEPT { return m_netlist; }
+ constexpr const netlist_t & netlist() const NL_NOEXCEPT { return m_netlist; }
- protected:
- ~netlist_ref() noexcept = default; // prohibit polymorphic destruction
+ protected:
+ ~netlist_ref() = default; // prohibit polymorphic destruction
- private:
- netlist_t & m_netlist;
+ private:
+ netlist_t & m_netlist;
- };
+ };
- // -----------------------------------------------------------------------------
- // device_object_t
- // -----------------------------------------------------------------------------
+ // -----------------------------------------------------------------------------
+ // 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.
+ /*! Base class for all objects being owned by a device.
+ *
+ * Serves as the base class of all objects being owned by a device.
+ *
+ */
+ class detail::device_object_t : public detail::object_t
+ {
+ public:
+ /*! Constructor.
*
+ * \param dev device owning the object.
+ * \param name string holding the name of the 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
- */
- device_object_t(core_device_t &dev, const pstring &name);
-
- /*! 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.
- */
- netlist_state_t &state() NL_NOEXCEPT;
- const netlist_state_t &state() const NL_NOEXCEPT;
-
- netlist_t &exec() NL_NOEXCEPT;
- const netlist_t &exec() const NL_NOEXCEPT;
+ device_object_t(core_device_t &dev, const pstring &name);
- private:
- core_device_t & m_device;
- };
-
- // -----------------------------------------------------------------------------
- // core_terminal_t
- // -----------------------------------------------------------------------------
-
- /*! Base class for all terminals.
- *
- * All terminals are derived from this class.
- *
+ /*! returns reference to owning device.
+ * \returns reference to owning device.
*/
+ core_device_t &device() NL_NOEXCEPT { return m_device; }
+ const core_device_t &device() const NL_NOEXCEPT { return m_device; }
- class net_t;
-
- class core_terminal_t : public device_object_t,
- public plib::linkedlist_t<core_terminal_t>::element_t
- {
- public:
-
- using list_t = std::vector<core_terminal_t *>;
-
- static constexpr const auto INP_HL_SHIFT = 0;
- static constexpr const auto INP_LH_SHIFT = 1;
- static constexpr const auto INP_ACTIVE_SHIFT = 2;
-
- enum state_e {
- STATE_INP_PASSIVE = 0,
- STATE_INP_HL = (1 << INP_HL_SHIFT),
- STATE_INP_LH = (1 << INP_LH_SHIFT),
- STATE_INP_ACTIVE = (1 << INP_ACTIVE_SHIFT),
- STATE_OUT = 128,
- STATE_BIDIR = 256
- };
-
- core_terminal_t(core_device_t &dev, const pstring &aname,
- const state_e state, nldelegate delegate = nldelegate());
- virtual ~core_terminal_t() noexcept = default;
-
- COPYASSIGNMOVE(core_terminal_t, delete)
-
- /*! The object type.
- * \returns type of the object
- */
- terminal_type type() const;
- /*! 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; }
- void clear_net() noexcept { m_net = nullptr; }
- bool has_net() const noexcept { return (m_net != nullptr); }
+ /*! The netlist owning the owner of this object.
+ * \returns reference to netlist object.
+ */
+ netlist_t &netlist() NL_NOEXCEPT;
+ const netlist_t &netlist() const NL_NOEXCEPT;
- const net_t & net() const noexcept { return *m_net;}
- net_t & net() noexcept { return *m_net;}
+ private:
+ core_device_t & m_device;
+};
- bool is_logic() const NL_NOEXCEPT;
- bool is_analog() const NL_NOEXCEPT;
+ /*! Delegate type for device notification.
+ *
+ */
+ typedef plib::pmfp<void> nldelegate;
- bool is_state(state_e astate) const noexcept { return (m_state == astate); }
- state_e terminal_state() const noexcept { return m_state; }
- void set_state(state_e astate) noexcept { m_state = astate; }
+ // -----------------------------------------------------------------------------
+ // core_terminal_t
+ // -----------------------------------------------------------------------------
- void reset() noexcept { set_state(is_type(OUTPUT) ? STATE_OUT : STATE_INP_ACTIVE); }
+ /*! Base class for all terminals.
+ *
+ * All terminals are derived from this class.
+ *
+ */
+ class detail::core_terminal_t : public device_object_t,
+ public plib::linkedlist_t<core_terminal_t>::element_t
+ {
+ public:
- nldelegate m_delegate;
- #if USE_COPY_INSTEAD_OF_REFERENCE
- void set_copied_input(netlist_sig_t val)
- {
- m_Q = val;
- }
+ using list_t = std::vector<core_terminal_t *>;
- state_var_sig m_Q;
- #else
- void set_copied_input(netlist_sig_t val) const { plib::unused_var(val); }
- #endif
+ static constexpr const unsigned INP_HL_SHIFT = 0;
+ static constexpr const unsigned INP_LH_SHIFT = 1;
+ static constexpr const unsigned INP_ACTIVE_SHIFT = 2;
- private:
- net_t * m_net;
- state_var<state_e> m_state;
+ enum state_e {
+ STATE_INP_PASSIVE = 0,
+ STATE_INP_HL = (1 << INP_HL_SHIFT),
+ STATE_INP_LH = (1 << INP_LH_SHIFT),
+ STATE_INP_ACTIVE = (1 << INP_ACTIVE_SHIFT),
+ STATE_OUT = 128,
+ STATE_BIDIR = 256
};
- // -----------------------------------------------------------------------------
- // net_t
- // -----------------------------------------------------------------------------
-
- class net_t :
- public object_t,
- public netlist_ref
- {
- public:
-
- enum class queue_status
- {
- DELAYED_DUE_TO_INACTIVE = 0,
- QUEUED,
- DELIVERED
- };
-
- net_t(netlist_state_t &nl, const pstring &aname, core_terminal_t *mr = nullptr);
-
- COPYASSIGNMOVE(net_t, delete)
-
- virtual ~net_t() noexcept = default;
-
- void reset();
-
- void toggle_new_Q() noexcept { m_new_Q = (m_cur_Q ^ 1); }
-
- void toggle_and_push_to_queue(netlist_time delay) NL_NOEXCEPT
- {
- toggle_new_Q();
- push_to_queue(delay);
- }
-
- void push_to_queue(netlist_time delay) NL_NOEXCEPT;
- bool is_queued() const noexcept { return m_in_queue == queue_status::QUEUED; }
-
- void update_devs() NL_NOEXCEPT;
-
- netlist_time next_scheduled_time() const noexcept { return m_next_scheduled_time; }
- void set_next_scheduled_time(netlist_time ntime) noexcept { m_next_scheduled_time = ntime; }
-
- bool isRailNet() const noexcept { return !(m_railterminal == nullptr); }
- core_terminal_t & railterminal() const noexcept { return *m_railterminal; }
-
- std::size_t num_cons() const noexcept { return m_core_terms.size(); }
-
- void add_to_active_list(core_terminal_t &term) NL_NOEXCEPT;
- void remove_from_active_list(core_terminal_t &term) NL_NOEXCEPT;
-
- /* setup stuff */
-
- void add_terminal(core_terminal_t &terminal);
- void remove_terminal(core_terminal_t &terminal);
-
- bool is_logic() const NL_NOEXCEPT;
- bool is_analog() const NL_NOEXCEPT;
-
- void rebuild_list(); /* rebuild m_list after a load */
- void move_connections(net_t &dest_net);
-
- std::vector<core_terminal_t *> &core_terms() { return m_core_terms; }
- #if USE_COPY_INSTEAD_OF_REFERENCE
- void update_inputs()
- {
- for (auto & term : m_core_terms)
- term->m_Q = m_cur_Q;
- }
- #else
- void update_inputs() const
- {
- /* nothing needs to be done */
- }
- #endif
-
- protected:
+ core_terminal_t(core_device_t &dev, const pstring &aname,
+ const state_e state, nldelegate delegate = nldelegate());
+ virtual ~core_terminal_t();
- /* only used for logic nets */
- netlist_sig_t Q() const noexcept { return m_cur_Q; }
+ /*! The object type.
+ * \returns type of the object
+ */
+ terminal_type type() const;
+ /*! 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 { return (type() == atype); }
- /* only used for logic nets */
- void initial(const netlist_sig_t val) noexcept
- {
- m_cur_Q = m_new_Q = val;
- update_inputs();
- }
+ void set_net(net_t *anet);
+ void clear_net();
+ bool has_net() const NL_NOEXCEPT { return (m_net != nullptr); }
- /* only used for logic nets */
- void set_Q_and_push(const netlist_sig_t newQ, const netlist_time delay) NL_NOEXCEPT
- {
- if (newQ != m_new_Q)
- {
- m_new_Q = newQ;
- push_to_queue(delay);
- }
- }
+ const net_t & net() const NL_NOEXCEPT { return *m_net;}
+ net_t & net() NL_NOEXCEPT { return *m_net;}
- /* only used for logic nets */
- void set_Q_time(const netlist_sig_t newQ, const netlist_time at) NL_NOEXCEPT
- {
- if (newQ != m_new_Q)
- {
- m_in_queue = queue_status::DELAYED_DUE_TO_INACTIVE;
- m_next_scheduled_time = at;
- }
- m_cur_Q = m_new_Q = newQ;
- update_inputs();
- }
+ bool is_logic() const NL_NOEXCEPT;
+ bool is_analog() const NL_NOEXCEPT;
- /* 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() { return m_cur_Q.ptr(); }
+ bool is_state(const state_e &astate) const NL_NOEXCEPT { return (m_state == astate); }
+ const state_e &state() const NL_NOEXCEPT { return m_state; }
+ void set_state(const state_e &astate) NL_NOEXCEPT { m_state = astate; }
- 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<netlist_time> m_next_scheduled_time;
+ void reset();
- core_terminal_t * m_railterminal;
- plib::linkedlist_t<core_terminal_t> m_list_active;
- std::vector<core_terminal_t *> m_core_terms; // save post-start m_list ...
+ nldelegate m_delegate;
- template <typename T>
- void process(const T mask, netlist_sig_t sig);
- };
- } // namespace detail
+ private:
+ net_t * m_net;
+ state_var<state_e> m_state;
+ };
// -----------------------------------------------------------------------------
// analog_t
@@ -719,6 +550,7 @@ namespace netlist
public:
analog_t(core_device_t &dev, const pstring &aname, const state_e state);
+ virtual ~analog_t();
const analog_net_t & net() const NL_NOEXCEPT;
analog_net_t & net() NL_NOEXCEPT;
@@ -732,44 +564,53 @@ namespace netlist
{
public:
- terminal_t(core_device_t &dev, const pstring &aname, terminal_t *otherterm);
+ terminal_t(core_device_t &dev, const pstring &aname);
+ virtual ~terminal_t();
nl_double operator ()() const NL_NOEXCEPT;
- void set_conductivity(const nl_double G) noexcept
+ void set(const nl_double &G) NL_NOEXCEPT
{
- set_go_gt_I(-G, G, 0.0);
+ set(G,G, 0.0);
}
- void set_go_gt(const nl_double GO, const nl_double GT) noexcept
+ void set(const nl_double &GO, const nl_double &GT) NL_NOEXCEPT
{
- set_go_gt_I(GO, GT, 0.0);
+ set(GO, GT, 0.0);
}
- void set_go_gt_I(const nl_double GO, const nl_double GT, const nl_double I) noexcept
+ void set(const nl_double &GO, const nl_double &GT, const nl_double &I) NL_NOEXCEPT
{
- if (m_go1 != nullptr)
- {
- if (*m_Idr1 != I) *m_Idr1 = I;
- if (*m_go1 != GO) *m_go1 = GO;
- if (*m_gt1 != GT) *m_gt1 = GT;
- }
+ set_ptr(m_Idr1, I);
+ set_ptr(m_go1, GO);
+ set_ptr(m_gt1, GT);
}
void solve_now();
- void schedule_solve_after(const netlist_time after);
+ void schedule_solve_after(const netlist_time &after);
- void set_ptrs(nl_double *gt, nl_double *go, nl_double *Idr) noexcept;
+ void set_ptrs(nl_double *gt, nl_double *go, nl_double *Idr) NL_NOEXCEPT
+ {
+ m_gt1 = gt;
+ m_go1 = go;
+ m_Idr1 = Idr;
+ }
+
+ terminal_t *m_otherterm;
- terminal_t *connected_terminal() const noexcept { return m_connected_terminal; }
private:
+ void set_ptr(nl_double *ptr, const nl_double &val) NL_NOEXCEPT
+ {
+ if (ptr != nullptr && *ptr != val)
+ {
+ *ptr = val;
+ }
+ }
nl_double *m_Idr1; // drive current
nl_double *m_go1; // conductance for Voltage from other term
nl_double *m_gt1; // conductance for total conductance
- terminal_t *m_connected_terminal;
-
};
@@ -782,6 +623,7 @@ namespace netlist
public:
logic_t(core_device_t &dev, const pstring &aname,
const state_e state, nldelegate delegate = nldelegate());
+ virtual ~logic_t();
bool has_proxy() const { return (m_proxy != nullptr); }
devices::nld_base_proxy *get_proxy() const { return m_proxy; }
@@ -805,6 +647,7 @@ namespace netlist
public:
logic_input_t(core_device_t &dev, const pstring &aname,
nldelegate delegate = nldelegate());
+ virtual ~logic_input_t();
netlist_sig_t operator()() const NL_NOEXCEPT
{
@@ -836,6 +679,9 @@ namespace netlist
const pstring &aname /*!< name of terminal */
);
+ /*! Destructor */
+ virtual ~analog_input_t();
+
/*! returns voltage at terminal.
* \returns voltage at terminal.
*/
@@ -848,18 +694,124 @@ namespace netlist
};
+ // -----------------------------------------------------------------------------
+ // net_t
+ // -----------------------------------------------------------------------------
+
+ class detail::net_t :
+ public detail::object_t,
+ public detail::netlist_ref
+ {
+ public:
+
+ enum queue_status
+ {
+ QS_DELAYED_DUE_TO_INACTIVE = 0,
+ QS_QUEUED,
+ QS_DELIVERED
+ };
+
+ net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr = nullptr);
+ virtual ~net_t();
+
+ void reset();
+
+ void toggle_new_Q() NL_NOEXCEPT { m_new_Q = (m_cur_Q ^ 1); }
+
+ void toggle_and_push_to_queue(const netlist_time &delay) NL_NOEXCEPT
+ {
+ toggle_new_Q();
+ push_to_queue(delay);
+ }
+
+ void push_to_queue(const netlist_time &delay) NL_NOEXCEPT;
+ bool is_queued() const NL_NOEXCEPT { return m_in_queue == QS_QUEUED; }
+
+ void update_devs() NL_NOEXCEPT;
+
+ const netlist_time &time() const NL_NOEXCEPT { return m_time; }
+ void set_time(const netlist_time &ntime) NL_NOEXCEPT { m_time = ntime; }
+
+ bool isRailNet() const NL_NOEXCEPT { return !(m_railterminal == nullptr); }
+ core_terminal_t & railterminal() const NL_NOEXCEPT { return *m_railterminal; }
+
+ std::size_t num_cons() const NL_NOEXCEPT { return m_core_terms.size(); }
+
+ void inc_active(core_terminal_t &term) NL_NOEXCEPT;
+ void dec_active(core_terminal_t &term) NL_NOEXCEPT;
+
+ /* setup stuff */
+
+ void add_terminal(core_terminal_t &terminal);
+ void remove_terminal(core_terminal_t &terminal);
+
+ bool is_logic() const NL_NOEXCEPT;
+ bool is_analog() const NL_NOEXCEPT;
+
+ void rebuild_list(); /* rebuild m_list after a load */
+ void move_connections(net_t &dest_net);
+
+ std::vector<core_terminal_t *> m_core_terms; // save post-start m_list ...
+
+ protected:
+ 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_s32 m_active;
+
+ state_var<netlist_time> m_time;
+
+ private:
+ plib::linkedlist_t<core_terminal_t> m_list_active;
+ core_terminal_t * m_railterminal;
+
+ void process(unsigned Mask);
+ };
class logic_net_t : public detail::net_t
{
public:
- logic_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *mr = nullptr);
+ logic_net_t(netlist_t &nl, const pstring &aname, detail::core_terminal_t *mr = nullptr);
+ virtual ~logic_net_t();
+
+ netlist_sig_t Q() const NL_NOEXCEPT { return m_cur_Q; }
+ void initial(const netlist_sig_t val) NL_NOEXCEPT { m_cur_Q = m_new_Q = val; }
+
+ void set_Q_and_push(const netlist_sig_t newQ, const netlist_time &delay) NL_NOEXCEPT
+ {
+ if (newQ != m_new_Q )
+ {
+ m_new_Q = newQ;
+ push_to_queue(delay);
+ }
+ }
+ void set_Q_and_push_force(const netlist_sig_t newQ, const netlist_time &delay) NL_NOEXCEPT
+ {
+ if (newQ != m_new_Q || is_queued())
+ {
+ m_new_Q = newQ;
+ push_to_queue(delay);
+ }
+ }
+
+ void set_Q_time(const netlist_sig_t newQ, const netlist_time &at) NL_NOEXCEPT
+ {
+ if (newQ != m_new_Q)
+ {
+ m_in_queue = QS_DELAYED_DUE_TO_INACTIVE;
+ m_time = at;
+ }
+ m_cur_Q = m_new_Q = newQ;
+ }
+
+ /* internal state support
+ * FIXME: get rid of this and implement export/import in MAME
+ */
+ netlist_sig_t *Q_state_ptr() { return m_cur_Q.ptr(); }
- using detail::net_t::Q;
- using detail::net_t::initial;
- using detail::net_t::set_Q_and_push;
- using detail::net_t::set_Q_time;
- using detail::net_t::Q_state_ptr;
+ protected:
+ private:
};
@@ -871,7 +823,9 @@ namespace netlist
friend class detail::net_t;
- analog_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *mr = nullptr);
+ analog_net_t(netlist_t &nl, const pstring &aname, detail::core_terminal_t *mr = nullptr);
+
+ virtual ~analog_net_t();
nl_double Q_Analog() const NL_NOEXCEPT { return m_cur_Analog; }
void set_Q_Analog(const nl_double v) NL_NOEXCEPT { m_cur_Analog = v; }
@@ -895,15 +849,21 @@ namespace netlist
public:
logic_output_t(core_device_t &dev, const pstring &aname);
+ virtual ~logic_output_t();
void initial(const netlist_sig_t val);
- void push(const netlist_sig_t newQ, const netlist_time delay) NL_NOEXCEPT
+ void push(const netlist_sig_t newQ, const netlist_time &delay) NL_NOEXCEPT
{
m_my_net.set_Q_and_push(newQ, delay); // take the shortcut
}
- void set_Q_time(const netlist_sig_t newQ, const netlist_time at) NL_NOEXCEPT
+ void push_force(const netlist_sig_t newQ, const netlist_time &delay) NL_NOEXCEPT
+ {
+ m_my_net.set_Q_and_push_force(newQ, delay); // take the shortcut
+ }
+
+ void set_Q_time(const netlist_sig_t newQ, const netlist_time &at) NL_NOEXCEPT
{
m_my_net.set_Q_time(newQ, at); // take the shortcut
}
@@ -916,6 +876,7 @@ namespace netlist
{
public:
analog_output_t(core_device_t &dev, const pstring &aname);
+ virtual ~analog_output_t();
void push(const nl_double val) NL_NOEXCEPT { set_Q(val); }
void initial(const nl_double val);
@@ -943,17 +904,13 @@ namespace netlist
param_t(device_t &device, const pstring &name);
- COPYASSIGNMOVE(param_t, delete)
-
param_type_t param_type() const;
protected:
- virtual ~param_t() noexcept = default; /* not intended to be destroyed */
+ virtual ~param_t(); /* not intended to be destroyed */
void update_param();
- pstring get_initial(const device_t &dev, bool *found);
-
template<typename C>
void set(C &p, const C v)
{
@@ -966,51 +923,53 @@ namespace netlist
};
- // -----------------------------------------------------------------------------
- // numeric parameter template
- // -----------------------------------------------------------------------------
-
- template <typename T>
- class param_num_t final: public param_t
+ class param_ptr_t final: public param_t
{
public:
- param_num_t(device_t &device, const pstring &name, const T val);
-
- const T operator()() const NL_NOEXCEPT { return m_param; }
- void setTo(const T &param) { set(m_param, param); }
+ param_ptr_t(device_t &device, const pstring &name, std::uint8_t* val);
+ std::uint8_t * operator()() const NL_NOEXCEPT { return m_param; }
+ void setTo(std::uint8_t *param) { set(m_param, param); }
private:
- T m_param;
+ std::uint8_t* m_param;
};
- /* FIXME: these should go as well */
- using param_logic_t = param_num_t<bool>;
- using param_int_t = param_num_t<int>;
- using param_double_t = param_num_t<double>;
-
- // -----------------------------------------------------------------------------
- // pointer parameter
- // -----------------------------------------------------------------------------
+ class param_logic_t final: public param_t
+ {
+ public:
+ param_logic_t(device_t &device, const pstring &name, const bool val);
+ const bool &operator()() const NL_NOEXCEPT { return m_param; }
+ void setTo(const bool &param) { set(m_param, param); }
+ private:
+ bool m_param;
+ };
- class param_ptr_t final: public param_t
+ class param_int_t final: public param_t
{
public:
- param_ptr_t(device_t &device, const pstring &name, std::uint8_t* val);
- std::uint8_t * operator()() const NL_NOEXCEPT { return m_param; }
- void setTo(std::uint8_t *param) { set(m_param, param); }
+ param_int_t(device_t &device, const pstring &name, const int val);
+ const int &operator()() const NL_NOEXCEPT { return m_param; }
+ void setTo(const int &param) { set(m_param, param); }
private:
- std::uint8_t* m_param;
+ int m_param;
};
- // -----------------------------------------------------------------------------
- // string parameter
- // -----------------------------------------------------------------------------
+ class param_double_t final: public param_t
+ {
+ public:
+ param_double_t(device_t &device, const pstring &name, const double val);
+ const double &operator()() const NL_NOEXCEPT { return m_param; }
+ void setTo(const double &param) { set(m_param, param); }
+ private:
+ double m_param;
+ };
class param_str_t : public param_t
{
public:
param_str_t(device_t &device, const pstring &name, const pstring &val);
+ virtual ~param_str_t();
- const pstring &operator()() const NL_NOEXCEPT { return value(); }
+ const pstring &operator()() const NL_NOEXCEPT { return Value(); }
void setTo(const pstring &param) NL_NOEXCEPT
{
if (m_param != param)
@@ -1022,16 +981,11 @@ namespace netlist
}
protected:
virtual void changed();
- const pstring &value() const NL_NOEXCEPT { return m_param; }
+ const pstring &Value() const NL_NOEXCEPT { return m_param; }
private:
- PALIGNAS_CACHELINE()
pstring m_param;
};
- // -----------------------------------------------------------------------------
- // model parameter
- // -----------------------------------------------------------------------------
-
class param_model_t : public param_str_t
{
public:
@@ -1043,8 +997,8 @@ namespace netlist
: m_value(param.model_value(name))
{
}
- double operator()() const noexcept { return m_value; }
- operator double() const noexcept { return m_value; }
+ const double &operator()() const NL_NOEXCEPT { return m_value; }
+ operator const double&() const NL_NOEXCEPT { return m_value; }
private:
const double m_value;
};
@@ -1056,29 +1010,24 @@ namespace netlist
const pstring model_value_str(const pstring &entity) /*const*/;
const pstring model_type() /*const*/;
- /* hide this */
- void setTo(const pstring &param) = delete;
protected:
- void changed() override;
+ virtual void changed() override;
nl_double model_value(const pstring &entity) /*const*/;
private:
+ /* hide this */
+ void setTo(const pstring &param) = delete;
+ detail::model_map_t m_map;
};
- // -----------------------------------------------------------------------------
- // data parameter
- // -----------------------------------------------------------------------------
class param_data_t : public param_str_t
{
public:
- param_data_t(device_t &device, const pstring &name)
- : param_str_t(device, name, "")
- {
- }
+ param_data_t(device_t &device, const pstring &name);
- plib::unique_ptr<plib::pistream> stream();
+ std::unique_ptr<plib::pistream> stream();
protected:
- void changed() override { }
+ virtual void changed() override;
};
// -----------------------------------------------------------------------------
@@ -1092,15 +1041,15 @@ namespace netlist
param_rom_t(device_t &device, const pstring &name);
- ST operator[] (std::size_t n) const NL_NOEXCEPT { return m_data[n]; }
+ const ST & operator[] (std::size_t n) NL_NOEXCEPT { return m_data[n]; }
protected:
- void changed() override
+ virtual void changed() override
{
- stream()->read(reinterpret_cast<plib::pistream::value_type *>(&m_data[0]),1<<AW);
+ stream()->read(&m_data[0],1<<AW);
}
private:
- std::array<ST, 1 << AW> m_data;
+ ST m_data[1 << AW];
};
// -----------------------------------------------------------------------------
@@ -1113,67 +1062,68 @@ namespace netlist
public detail::netlist_ref
{
public:
- core_device_t(netlist_state_t &owner, const pstring &name);
+ core_device_t(netlist_t &owner, const pstring &name);
core_device_t(core_device_t &owner, const pstring &name);
- COPYASSIGNMOVE(core_device_t, delete)
+ virtual ~core_device_t();
- virtual ~core_device_t() noexcept = default;
+ void update_dev() NL_NOEXCEPT
+ {
+ do_update();
+ }
void do_inc_active() NL_NOEXCEPT
{
if (m_hint_deactivate)
{
- if (++m_active_outputs == 1)
- {
- m_stat_inc_active.inc();
- inc_active();
- }
+ m_stat_inc_active.inc();
+ inc_active();
}
}
void do_dec_active() NL_NOEXCEPT
{
if (m_hint_deactivate)
- if (--m_active_outputs == 0)
- {
- dec_active();
- }
+ dec_active();
}
+ void do_reset() { reset(); }
void set_hint_deactivate(bool v) { m_hint_deactivate = v; }
bool get_hint_deactivate() { return m_hint_deactivate; }
- /* Has to be set in device reset */
- void set_active_outputs(int n) { m_active_outputs = n; }
void set_default_delegate(detail::core_terminal_t &term);
/* stats */
- nperftime_t<NL_KEEP_STATISTICS> m_stat_total_time;
- nperfcount_t<NL_KEEP_STATISTICS> m_stat_call_count;
- nperfcount_t<NL_KEEP_STATISTICS> m_stat_inc_active;
+ nperftime_t m_stat_total_time;
+ nperfcount_t m_stat_call_count;
+ nperfcount_t m_stat_inc_active;
- virtual void update() NL_NOEXCEPT { }
- virtual void reset() { }
protected:
+ virtual void update() NL_NOEXCEPT { }
virtual void inc_active() NL_NOEXCEPT { }
virtual void dec_active() NL_NOEXCEPT { }
+ virtual void reset() { }
- log_type & log();
+ void do_update() NL_NOEXCEPT
+ {
+ update();
+ }
+
+ plib::plog_base<netlist_t, NL_DEBUG> &log();
public:
- virtual void timestep(const nl_double st) { plib::unused_var(st); }
+ virtual void timestep(ATTR_UNUSED const nl_double st) { }
virtual void update_terminals() { }
virtual void update_param() {}
virtual bool is_dynamic() const { return false; }
virtual bool is_timestep() const { return false; }
+ virtual bool needs_update_after_param_change() const { return false; }
private:
- bool m_hint_deactivate;
- state_var_s32 m_active_outputs;
+ bool m_hint_deactivate;
};
// -----------------------------------------------------------------------------
@@ -1184,20 +1134,17 @@ namespace netlist
{
public:
- device_t(netlist_state_t &owner, const pstring &name);
+ device_t(netlist_t &owner, const pstring &name);
device_t(core_device_t &owner, const pstring &name);
- COPYASSIGNMOVE(device_t, delete)
-
- ~device_t() noexcept override = default;
+ virtual ~device_t() override;
setup_t &setup();
- const setup_t &setup() const;
template<class C, typename... Args>
- void create_and_register_subdevice(const pstring &name, pool_owned_ptr<C> &dev, Args&&... args)
+ void register_sub(const pstring &name, std::unique_ptr<C> &dev, const Args&... args)
{
- dev = pool().make_poolptr<C>(*this, name, std::forward<Args>(args)...);
+ dev.reset(plib::palloc<C>(*this, name, args...));
}
void register_subalias(const pstring &name, detail::core_terminal_t &term);
@@ -1220,18 +1167,13 @@ namespace netlist
struct detail::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() { }
family_setter_t(core_device_t &dev, const pstring &desc);
family_setter_t(core_device_t &dev, const logic_family_desc_t *desc);
};
// -----------------------------------------------------------------------------
// nld_base_dummy : basis for dummy devices
- // FIXME: this is not the right place to define this
// -----------------------------------------------------------------------------
NETLIB_OBJECT(base_dummy)
@@ -1248,25 +1190,19 @@ namespace netlist
* solvers will update inputs after parallel processing.
*/
class detail::queue_t :
- public timed_queue<pqentry_t<net_t *, netlist_time>, false, NL_KEEP_STATISTICS>,
+ public timed_queue<pqentry_t<net_t *, netlist_time>, false>,
public detail::netlist_ref,
public plib::state_manager_t::callback_t
{
public:
- using entry_t = pqentry_t<net_t *, netlist_time>;
- explicit queue_t(netlist_state_t &nl);
- virtual ~queue_t() noexcept = default;
-
- queue_t(const queue_t &) = delete;
- queue_t(queue_t &&) = delete;
- queue_t &operator=(const queue_t &) = delete;
- queue_t &operator=(queue_t &&) = delete;
+ typedef pqentry_t<net_t *, netlist_time> entry_t;
+ explicit queue_t(netlist_t &nl);
protected:
void register_state(plib::state_manager_t &manager, const pstring &module) override;
- void on_pre_save(plib::state_manager_t &manager) override;
- void on_post_load(plib::state_manager_t &manager) override;
+ void on_pre_save() override;
+ void on_post_load() override;
private:
std::size_t m_qsize;
@@ -1275,214 +1211,139 @@ namespace netlist
};
// -----------------------------------------------------------------------------
- // netlist_state__t
+ // netlist_t
// -----------------------------------------------------------------------------
- class netlist_state_t
+
+ class netlist_t : private plib::nocopyassignmove
{
public:
- using nets_collection_type = std::vector<pool_owned_ptr<detail::net_t>>;
-
- /* need to preserve order of device creation ... */
- using devices_collection_type = std::vector<std::pair<pstring, pool_owned_ptr<core_device_t>>>;
- netlist_state_t(const pstring &aname,
- netlist_t & anetlist,
- plib::unique_ptr<callbacks_t> &&callbacks);
-
- COPYASSIGNMOVE(netlist_state_t, delete)
-
- ~netlist_state_t() noexcept = default;
-
- friend class netlist_t; // allow access to private members
+ explicit netlist_t(const pstring &aname);
+ virtual ~netlist_t();
- template<class C>
- static bool check_class(core_device_t *p)
- {
- return dynamic_cast<C *>(p) != nullptr;
- }
+ /* run functions */
- template<class C>
- C *get_single_device(const pstring &classname) const
- {
- return dynamic_cast<C *>(get_single_device(classname, check_class<C>));
- }
+ const netlist_time &time() const NL_NOEXCEPT { return m_time; }
+ devices::NETLIB_NAME(solver) *solver() const NL_NOEXCEPT { return m_solver; }
- /* logging and name */
+ /* never use this in constructors! */
+ nl_double gmin() const NL_NOEXCEPT;
- pstring name() const { return m_name; }
+ void process_queue(const netlist_time &delta) NL_NOEXCEPT;
+ void abort_current_queue_slice() NL_NOEXCEPT { m_queue.retime(detail::queue_t::entry_t(m_time, nullptr)); }
- log_type & log() { return m_log; }
- const log_type &log() const { return m_log; }
+ /* Control functions */
- plib::dynlib &lib() { return *m_lib; }
+ void start();
+ void stop();
+ void reset();
- netlist_t &exec() { return m_netlist; }
- const netlist_t &exec() const { return m_netlist; }
+ const detail::queue_t &queue() const NL_NOEXCEPT { return m_queue; }
+ detail::queue_t &queue() NL_NOEXCEPT { return m_queue; }
- /* state handling */
- plib::state_manager_t &run_state_manager() { return m_state; }
+ /* netlist build functions */
- template<typename O, typename C>
- void save(O &owner, C &state, const pstring &module, const pstring &stname)
- {
- this->run_state_manager().save_item(static_cast<void *>(&owner), state, module + pstring(".") + stname);
- }
- template<typename O, typename C>
- void save(O &owner, C *state, const pstring &module, const pstring &stname, const std::size_t count)
- {
- this->run_state_manager().save_state_ptr(static_cast<void *>(&owner), module + pstring(".") + stname, plib::state_manager_t::dtype<C>(), count, state);
- }
+ setup_t &setup() NL_NOEXCEPT { return *m_setup; }
- core_device_t *get_single_device(const pstring &classname, bool (*cc)(core_device_t *)) const;
+ void register_dev(plib::owned_ptr<core_device_t> dev);
+ void remove_dev(core_device_t *dev);
detail::net_t *find_net(const pstring &name) const;
std::size_t find_net_id(const detail::net_t *net) const;
- template <typename T>
- void register_net(pool_owned_ptr<T> &&net) { m_nets.push_back(std::move(net)); }
-
template<class device_class>
- inline std::vector<device_class *> get_device_list()
+ std::vector<device_class *> get_device_list() const
{
std::vector<device_class *> tmp;
for (auto &d : m_devices)
{
- auto dev = dynamic_cast<device_class *>(d.second.get());
+ device_class *dev = dynamic_cast<device_class *>(d.get());
if (dev != nullptr)
tmp.push_back(dev);
}
return tmp;
}
- template <typename T>
- void add_dev(const pstring &name, pool_owned_ptr<T> &&dev)
+ template<class C>
+ static bool check_class(core_device_t *p)
{
- for (auto & d : m_devices)
- if (d.first == name)
- log().fatal(MF_1_DUPLICATE_NAME_DEVICE_LIST, d.first);
- //m_devices.push_back(std::move(dev));
- m_devices.insert(m_devices.end(), { name, std::move(dev) });
+ return dynamic_cast<C *>(p) != nullptr;
}
- /**
- * @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_dev(core_device_t *dev)
+ template<class C>
+ C *get_single_device(const pstring &classname) const
{
- for (auto it = m_devices.begin(); it != m_devices.end(); it++)
- if (it->second.get() == dev)
- {
- m_state.remove_save_items(dev);
- m_devices.erase(it);
- return;
- }
+ return dynamic_cast<C *>(get_single_device(classname, check_class<C>));
}
- /* sole use is to manage lifetime of family objects */
- std::vector<std::pair<pstring, plib::unique_ptr<logic_family_desc_t>>> m_family_cache;
-
- setup_t &setup() NL_NOEXCEPT { return *m_setup; }
- const setup_t &setup() const NL_NOEXCEPT { return *m_setup; }
+ /* logging and name */
- nets_collection_type & nets() { return m_nets; }
- devices_collection_type & devices() { return m_devices; }
+ pstring name() const { return m_name; }
+ plib::plog_base<netlist_t, NL_DEBUG> &log() { return m_log; }
+ const plib::plog_base<netlist_t, NL_DEBUG> &log() const { return m_log; }
- // FIXME: make a postload member and include code there
- void rebuild_lists(); /* must be called after post_load ! */
+ /* state related */
- private:
+ plib::state_manager_t &state() { return m_state; }
- void reset();
+ template<typename O, typename C> void save(O &owner, C &state, const pstring &stname)
+ {
+ this->state().save_item(static_cast<void *>(&owner), state, from_utf8(owner.name()) + pstring(".") + stname);
+ }
+ template<typename O, typename C> void save(O &owner, C *state, const pstring &stname, const std::size_t count)
+ {
+ this->state().save_state_ptr(static_cast<void *>(&owner), from_utf8(owner.name()) + pstring(".") + stname, plib::state_manager_t::datatype_f<C>::f(), count, state);
+ }
- pstring m_name;
- netlist_t &m_netlist;
- plib::unique_ptr<plib::dynlib> m_lib; // external lib needs to be loaded as long as netlist exists
- plib::state_manager_t m_state;
- plib::unique_ptr<callbacks_t> m_callbacks;
- log_type m_log;
- plib::unique_ptr<setup_t> m_setup;
+ plib::dynlib &lib() { return *m_lib; }
- nets_collection_type m_nets;
+ // FIXME: find something better
/* sole use is to manage lifetime of net objects */
- devices_collection_type m_devices;
-
-
-
- };
-
- // -----------------------------------------------------------------------------
- // netlist_t
- // -----------------------------------------------------------------------------
-
- class netlist_t
- {
- public:
-
- explicit netlist_t(const pstring &aname, plib::unique_ptr<callbacks_t> callbacks);
-
- COPYASSIGNMOVE(netlist_t, delete)
-
- ~netlist_t() noexcept = default;
-
- /* run functions */
-
- netlist_time time() const NL_NOEXCEPT { return m_time; }
-
- void process_queue(const netlist_time delta) NL_NOEXCEPT;
- void abort_current_queue_slice() NL_NOEXCEPT { m_queue.retime(detail::queue_t::entry_t(m_time, nullptr)); }
-
- const detail::queue_t &queue() const NL_NOEXCEPT { return m_queue; }
- detail::queue_t &queue() NL_NOEXCEPT { return m_queue; }
+ std::vector<plib::owned_ptr<detail::net_t>> m_nets;
+ /* sole use is to manage lifetime of family objects */
+ std::vector<std::pair<pstring, std::unique_ptr<logic_family_desc_t>>> m_family_cache;
- /* Control functions */
+ // FIXME: sort rebuild_lists out
+ void rebuild_lists(); /* must be called after post_load ! */
- void stop();
- void reset();
+ /* logging callback */
+ virtual void vlog(const plib::plog_level &l, const pstring &ls) const = 0;
- /* state handling */
+ protected:
- plib::state_manager_t &run_state_manager() { return m_state->run_state_manager(); }
+ void print_stats() const;
- /* only used by nltool to create static c-code */
- devices::NETLIB_NAME(solver) *solver() const NL_NOEXCEPT { return m_solver; }
+ private:
- /* force late type resolution */
- template <typename X = devices::NETLIB_NAME(solver)>
- nl_double gmin(X *solv = nullptr) const NL_NOEXCEPT
- {
- plib::unused_var(solv);
- return static_cast<X *>(m_solver)->gmin();
- }
+ /* helper for save above */
+ static pstring from_utf8(const char *c) { return pstring(c, pstring::UTF8); }
+ static pstring from_utf8(const pstring &c) { return c; }
- netlist_state_t &nlstate() NL_NOEXCEPT { return *m_state; }
- const netlist_state_t &nlstate() const { return *m_state; }
+ core_device_t *get_single_device(const pstring &classname, bool (*cc)(core_device_t *)) const;
- log_type & log() { return m_state->log(); }
- const log_type &log() const { return m_state->log(); }
+ /* mostly rw */
+ netlist_time m_time;
+ detail::queue_t m_queue;
- void print_stats() const;
+ /* mostly ro */
- private:
- plib::unique_ptr<netlist_state_t> m_state;
- devices::NETLIB_NAME(solver) * m_solver;
+ devices::NETLIB_NAME(mainclock) * m_mainclock;
+ devices::NETLIB_NAME(solver) * m_solver;
+ devices::NETLIB_NAME(netlistparams) *m_params;
- /* mostly rw */
- PALIGNAS_CACHELINE()
- netlist_time m_time;
- devices::NETLIB_NAME(mainclock) * m_mainclock;
+ pstring m_name;
+ std::unique_ptr<setup_t> m_setup;
+ plib::plog_base<netlist_t, NL_DEBUG> m_log;
+ std::unique_ptr<plib::dynlib> m_lib; // external lib needs to be loaded as long as netlist exists
- PALIGNAS_CACHELINE()
- detail::queue_t m_queue;
+ plib::state_manager_t m_state;
// performance
- nperftime_t<NL_KEEP_STATISTICS> m_stat_mainloop;
- nperfcount_t<NL_KEEP_STATISTICS> m_perf_out_processed;
+ nperftime_t m_stat_mainloop;
+ nperfcount_t m_perf_out_processed;
+
+ std::vector<plib::owned_ptr<core_device_t>> m_devices;
};
// -----------------------------------------------------------------------------
@@ -1495,13 +1356,12 @@ namespace netlist
public:
struct init
{
- std::array<const char *, N> p;
+ const char *p[N];
};
- template<typename... Args>
- object_array_t(core_device_t &dev, init names, Args&&... args)
+ object_array_t(core_device_t &dev, init names)
{
for (std::size_t i = 0; i<N; i++)
- this->emplace(i, dev, pstring(names.p[i]), std::forward<Args>(args)...);
+ this->emplace(i, dev, pstring(names.p[i], pstring::UTF8));
}
};
@@ -1509,56 +1369,15 @@ namespace netlist
// inline implementations
// -----------------------------------------------------------------------------
- inline netlist_state_t & detail::netlist_ref::state() noexcept
- {
- return m_netlist.nlstate();
- }
-
- inline const netlist_state_t & detail::netlist_ref::state() const noexcept
- {
- return m_netlist.nlstate();
- }
-
- inline setup_t & detail::netlist_ref::setup() noexcept
- {
- return m_netlist.nlstate().setup();
- }
-
- inline const setup_t & detail::netlist_ref::setup() const noexcept
- {
- return m_netlist.nlstate().setup();
- }
-
- template <typename T>
- param_num_t<T>::param_num_t(device_t &device, const pstring &name, const T val)
- : param_t(device, name)
- {
- //m_param = device.setup().get_initial_param_val(this->name(),val);
- bool found = false;
- pstring p = this->get_initial(device, &found);
- if (found)
- {
- bool err = false;
- auto vald = plib::pstonum_ne<T>(p, err);
- if (err)
- device.state().log().fatal(MF_2_INVALID_NUMBER_CONVERSION_1_2, name, p);
- m_param = vald;
- }
- else
- m_param = val;
-
- device.state().save(*this, m_param, this->name(), "m_param");
- }
-
template <typename ST, std::size_t AW, std::size_t DW>
- param_rom_t<ST, AW, DW>::param_rom_t(device_t &device, const pstring &name)
+ inline param_rom_t<ST, AW, DW>::param_rom_t(device_t &device, const pstring &name)
: param_data_t(device, name)
{
auto f = stream();
if (f != nullptr)
- f->read(reinterpret_cast<plib::pistream::value_type *>(&m_data[0]),1<<AW);
+ f->read(&m_data[0],1<<AW);
else
- device.state().log().warning("Rom {1} not found", value());
+ device.netlist().log().warning("Rom {1} not found", Value());
}
inline void logic_input_t::inactivate() NL_NOEXCEPT
@@ -1566,7 +1385,7 @@ namespace netlist
if (!is_state(STATE_INP_PASSIVE))
{
set_state(STATE_INP_PASSIVE);
- net().remove_from_active_list(*this);
+ net().dec_active(*this);
}
}
@@ -1574,7 +1393,7 @@ namespace netlist
{
if (is_state(STATE_INP_PASSIVE))
{
- net().add_to_active_list(*this);
+ net().inc_active(*this);
set_state(STATE_INP_ACTIVE);
}
}
@@ -1583,7 +1402,7 @@ namespace netlist
{
if (is_state(STATE_INP_PASSIVE))
{
- net().add_to_active_list(*this);
+ net().inc_active(*this);
set_state(STATE_INP_HL);
}
}
@@ -1592,68 +1411,24 @@ namespace netlist
{
if (is_state(STATE_INP_PASSIVE))
{
- net().add_to_active_list(*this);
+ net().inc_active(*this);
set_state(STATE_INP_LH);
}
}
- inline void detail::net_t::push_to_queue(const netlist_time delay) NL_NOEXCEPT
+ inline void detail::net_t::push_to_queue(const netlist_time &delay) NL_NOEXCEPT
{
if ((num_cons() != 0))
{
- auto &lexec(exec());
- auto &q(lexec.queue());
- auto nst(lexec.time() + delay);
-
if (is_queued())
- q.remove(this);
- m_in_queue = (!m_list_active.empty()) ?
- queue_status::QUEUED : queue_status::DELAYED_DUE_TO_INACTIVE; /* queued ? */
- if (m_in_queue == queue_status::QUEUED)
- q.push(queue_t::entry_t(nst, this));
- else
- update_inputs();
- m_next_scheduled_time = nst;
- }
- }
-
- inline void detail::net_t::add_to_active_list(core_terminal_t &term) NL_NOEXCEPT
- {
- if (m_list_active.empty())
- {
- m_list_active.push_front(&term);
- railterminal().device().do_inc_active();
- if (m_in_queue == queue_status::DELAYED_DUE_TO_INACTIVE)
- {
- if (m_next_scheduled_time > exec().time())
- {
- m_in_queue = queue_status::QUEUED; /* pending */
- exec().queue().push({m_next_scheduled_time, this});
- }
- else
- {
- m_in_queue = queue_status::DELIVERED;
- m_cur_Q = m_new_Q;
- }
- update_inputs();
- }
- else
- term.set_copied_input(m_cur_Q);
- }
- else
- {
- term.set_copied_input(m_cur_Q);
- m_list_active.push_front(&term);
+ netlist().queue().remove(this);
+ m_time = netlist().time() + delay;
+ m_in_queue = (m_active > 0) ? QS_QUEUED : QS_DELAYED_DUE_TO_INACTIVE; /* queued ? */
+ if (m_in_queue == QS_QUEUED)
+ netlist().queue().push(queue_t::entry_t(m_time, this));
}
}
- inline void detail::net_t::remove_from_active_list(core_terminal_t &term) NL_NOEXCEPT
- {
- m_list_active.remove(&term);
- if (m_list_active.empty())
- railterminal().device().do_dec_active();
- }
-
inline const analog_net_t & analog_t::net() const NL_NOEXCEPT
{
return static_cast<const analog_net_t &>(core_terminal_t::net());
@@ -1666,18 +1441,6 @@ namespace netlist
inline nl_double terminal_t::operator ()() const NL_NOEXCEPT { return net().Q_Analog(); }
- inline void terminal_t::set_ptrs(nl_double *gt, nl_double *go, nl_double *Idr) noexcept
- {
- if (!(gt && go && Idr) && (gt || go || Idr))
- state().log().fatal("Inconsistent nullptrs for terminal {}", name());
- else
- {
- m_gt1 = gt;
- m_go1 = go;
- m_Idr1 = Idr;
- }
- }
-
inline logic_net_t & logic_t::net() NL_NOEXCEPT
{
return static_cast<logic_net_t &>(core_terminal_t::net());
@@ -1690,14 +1453,8 @@ namespace netlist
inline netlist_sig_t logic_input_t::Q() const NL_NOEXCEPT
{
- nl_assert(terminal_state() != STATE_INP_PASSIVE);
- //if (net().Q() != m_Q)
- // printf("term: %s, %d %d TS %d\n", this->name().c_str(), net().Q(), m_Q, terminal_state());
-#if USE_COPY_INSTEAD_OF_REFERENCE
- return m_Q;
-#else
+ nl_assert(state() != STATE_INP_PASSIVE);
return net().Q();
-#endif
}
inline nl_double analog_input_t::Q_Analog() const NL_NOEXCEPT
@@ -1714,24 +1471,14 @@ namespace netlist
}
}
- inline netlist_state_t &detail::device_object_t::state() NL_NOEXCEPT
- {
- return m_device.state();
- }
-
- inline const netlist_state_t &detail::device_object_t::state() const NL_NOEXCEPT
- {
- return m_device.state();
- }
-
- inline netlist_t &detail::device_object_t::exec() NL_NOEXCEPT
+ inline netlist_t &detail::device_object_t::netlist() NL_NOEXCEPT
{
- return m_device.exec();
+ return m_device.netlist();
}
- inline const netlist_t &detail::device_object_t::exec() const NL_NOEXCEPT
+ inline const netlist_t &detail::device_object_t::netlist() const NL_NOEXCEPT
{
- return m_device.exec();
+ return m_device.netlist();
}
template <typename T>
@@ -1739,18 +1486,18 @@ namespace netlist
state_var<T>::state_var(O &owner, const pstring &name, const T &value)
: m_value(value)
{
- owner.state().save(owner, m_value, owner.name(), name);
+ owner.netlist().save(owner, m_value, name);
}
template <typename T, std::size_t N>
template <typename O>
- state_array<T,N>::state_array(O &owner, const pstring &name, const T & value)
+ state_var<T[N]>::state_var(O &owner, const pstring &name, const T & value)
{
- owner.state().save(owner, m_value, owner.name(), name);
+ owner.netlist().save(owner, m_value, name);
for (std::size_t i=0; i<N; i++)
m_value[i] = value;
}
-} // namespace netlist
+}
namespace plib
{
@@ -1758,7 +1505,7 @@ namespace plib
struct ptype_traits<netlist::state_var<X>> : ptype_traits<X>
{
};
-} // namespace plib
+}
diff --git a/src/lib/netlist/nl_config.h b/src/lib/netlist/nl_config.h
index faa5008ff56..6a65abac40a 100644
--- a/src/lib/netlist/nl_config.h
+++ b/src/lib/netlist/nl_config.h
@@ -26,21 +26,10 @@
* linear memory pool. This is based of the assumption that
* due to enhanced locality there will be less cache misses.
* Your mileage may vary.
+ * This will cause crashes on OSX and thus is ignored on OSX.
*
*/
-#define USE_MEMPOOL (1)
-
-/*! 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 5% slower.
- *
- */
-#define USE_COPY_INSTEAD_OF_REFERENCE (0)
+#define USE_MEMPOOL (0)
/*
* FIXME: Using truthtable is a lot slower than the explicit device
@@ -54,13 +43,23 @@
#define NL_MAX_LINK_RESOLVE_LOOPS (100)
//============================================================
+// Solver defines
+//============================================================
+
+#define USE_GABS (1)
+// savings are eaten up by effort
+// FIXME: Convert into solver parameter
+#define USE_LINEAR_PREDICTION (0)
+#define NETLIST_GMIN_DEFAULT (1e-9)
+
+
+
+//============================================================
// DEBUGGING
//============================================================
#define NL_DEBUG (false)
#define NL_KEEP_STATISTICS (0)
-//#define NL_DEBUG (true)
-//#define NL_KEEP_STATISTICS (1)
//============================================================
// General Macros
@@ -87,19 +86,24 @@
#endif // !defined(USE_OPENMP)
// Use nano-second resolution - Sufficient for now
-
-static constexpr const auto NETLIST_INTERNAL_RES = 1000000000;
-static constexpr const auto NETLIST_CLOCK = NETLIST_INTERNAL_RES;
-
-//#define NETLIST_INTERNAL_RES (UINT64_C(1000000000))
-//#define NETLIST_CLOCK (NETLIST_INTERNAL_RES)
+#define NETLIST_INTERNAL_RES (UINT64_C(1000000000))
+#define NETLIST_CLOCK (NETLIST_INTERNAL_RES)
//#define NETLIST_INTERNAL_RES (UINT64_C(1000000000000))
//#define NETLIST_CLOCK (UINT64_C(1000000000))
//#define nl_double float
+//#define NL_FCONST(x) (x ## f)
+
+//#define nl_double double
+#define NL_FCONST(x) x
using nl_double = double;
+/* The following option determines how object::update is called.
+ * If set to 1, a virtual call is used. If it is left undefined, the best
+ * approach will be automatically selected.
+ */
+
//============================================================
// WARNINGS
//============================================================
diff --git a/src/lib/netlist/nl_dice_compat.h b/src/lib/netlist/nl_dice_compat.h
index 48695e393ec..b0ebdb2e371 100644
--- a/src/lib/netlist/nl_dice_compat.h
+++ b/src/lib/netlist/nl_dice_compat.h
@@ -29,7 +29,6 @@ sed -e 's/#define \(.*\)"\(.*\)"[ \t]*,[ \t]*\(.*\)/NET_ALIAS(\1,\2.\3)/' src/ma
#include "analog/nld_twoterm.h"
#include <cmath>
-
#endif
@@ -112,8 +111,8 @@ public:
#define CHIP(n, t) TTL_ ## t ## _DIP(n)
#define OHM(x) x
-#define K_OHM(x) RES_K(x)
-#define M_OHM(x) RES_M(x)
+#define K_OHM(x) RES_K(X)
+#define M_OHM(x) RES_M(X)
#define U_FARAD(x) CAP_U(x)
#define N_FARAD(x) CAP_N(x)
#define P_FARAD(x) CAP_P(x)
@@ -132,9 +131,9 @@ public:
NET_C(name.6, name ## _R.1) \
NET_C(name.6, name ## _C.1) \
NET_C(name ## _R.2, V5) \
- NET_C(name ## _C.2, GND) \
+ NET_CSTR(# name "_C.2", "GND") \
NET_C(name.8, V5) \
- NET_C(name.1, GND)
+ NET_CSTR(# name ".1", "GND")
#define CHIP_555_Astable(name, pdesc) \
NE555_DIP(name) \
@@ -147,9 +146,9 @@ public:
NET_C(name.6, name ## _C.1) \
NET_C(name.2, name ## _C.1) \
NET_C(name ## _R1.2, V5) \
- NET_C(name ## _C.2, GND) \
+ NET_CSTR(# name "_C.2", "GND") \
NET_C(name.8, V5) \
- NET_C(name.1, GND)
+ NET_CSTR(# name ".1", "GND")
#define CHIP_9602_Mono(name, pdesc) \
CHIP(# name, 9602) \
@@ -179,13 +178,13 @@ public:
#define CHIP_INPUT_ACTIVE_LOW(name) \
SWITCH2(name ## _SW) \
NET_C(name ## _SW.1, V5) \
- NET_C(name ## _SW.2, GND) \
+ NET_CSTR(# name "_SW.2", "GND") \
ALIAS(name.1, name ## _SW.Q)
#define CHIP_INPUT_ACTIVE_HIGH(name) \
SWITCH2(name ## _SW) \
NET_C(name ## _SW.2, V5) \
- NET_C(name ## _SW.1, GND) \
+ NET_CSTR(# name "_SW.1", "GND") \
ALIAS(name.1, name ## _SW.Q)
#define CHIP_LATCH(name) \
diff --git a/src/lib/netlist/nl_errstr.h b/src/lib/netlist/nl_errstr.h
index ee3c47f3339..35b1e4f6c60 100644
--- a/src/lib/netlist/nl_errstr.h
+++ b/src/lib/netlist/nl_errstr.h
@@ -58,8 +58,7 @@
//#define MF_1_CLASS_1_NOT_FOUND "Class {1} not found!"
#define MF_1_UNABLE_TO_PARSE_MODEL_1 "Unable to parse model: {1}"
#define MF_1_MODEL_ALREADY_EXISTS_1 "Model already exists: {1}"
-#define MF_1_DEVICE_ALREADY_EXISTS_1 "Device already exists: {1}"
-#define MF_1_ADDING_ALI1_TO_ALIAS_LIST "Error adding alias {1} to alias list"
+#define MF_1_ADDING_ALI1_TO_ALIAS_LIST "Error adding alias {1} to alias list"
#define MF_1_DIP_PINS_MUST_BE_AN_EQUAL_NUMBER_OF_PINS_1 "You must pass an equal number of pins to DIPPINS {1}"
#define MF_1_UNKNOWN_OBJECT_TYPE_1 "Unknown object type {1}"
#define MF_2_INVALID_NUMBER_CONVERSION_1_2 "Invalid number conversion {1} : {2}"
diff --git a/src/lib/netlist/nl_factory.cpp b/src/lib/netlist/nl_factory.cpp
index 1f0ac35c6c4..2bb49590c4b 100644
--- a/src/lib/netlist/nl_factory.cpp
+++ b/src/lib/netlist/nl_factory.cpp
@@ -10,84 +10,102 @@
#include "nl_factory.h"
#include "nl_base.h"
-#include "nl_errstr.h"
#include "nl_setup.h"
#include "plib/putil.h"
+#include "nl_errstr.h"
namespace netlist { namespace factory
{
- class NETLIB_NAME(wrapper) : public device_t
- {
- public:
- NETLIB_NAME(wrapper)(netlist_state_t &anetlist, const pstring &name)
- : device_t(anetlist, name)
- {
- }
- protected:
- NETLIB_RESETI() { }
- NETLIB_UPDATEI() { }
- };
-
- element_t::element_t(const pstring &name, const pstring &classname,
- const pstring &def_param, const pstring &sourcefile)
- : m_name(name), m_classname(classname), m_def_param(def_param),
- m_sourcefile(sourcefile)
+class NETLIB_NAME(wrapper) : public device_t
+{
+public:
+ NETLIB_NAME(wrapper)(netlist_t &anetlist, const pstring &name)
+ : device_t(anetlist, name)
{
}
+protected:
+ NETLIB_RESETI();
+ NETLIB_UPDATEI();
+};
- element_t::element_t(const pstring &name, const pstring &classname,
- const pstring &def_param)
- : m_name(name), m_classname(classname), m_def_param(def_param),
- m_sourcefile("<unknown>")
- {
- }
- // ----------------------------------------------------------------------------------------
- // net_device_t_base_factory
- // ----------------------------------------------------------------------------------------
- list_t::list_t(log_type &alog)
- : m_log(alog)
- {
- }
+element_t::element_t(const pstring &name, const pstring &classname,
+ const pstring &def_param, const pstring &sourcefile)
+ : m_name(name), m_classname(classname), m_def_param(def_param),
+ m_sourcefile(sourcefile)
+{
+}
- void list_t::register_device(plib::unique_ptr<element_t> &&factory)
- {
- for (auto & e : *this)
- if (e->name() == factory->name())
- m_log.fatal(MF_1_FACTORY_ALREADY_CONTAINS_1, factory->name());
- push_back(std::move(factory));
- }
+element_t::element_t(const pstring &name, const pstring &classname,
+ const pstring &def_param)
+ : m_name(name), m_classname(classname), m_def_param(def_param),
+ m_sourcefile("<unknown>")
+{
+}
- factory::element_t * list_t::factory_by_name(const pstring &devname)
- {
- for (auto & e : *this)
- {
- if (e->name() == devname)
- return e.get();
- }
-
- m_log.fatal(MF_1_CLASS_1_NOT_FOUND, devname);
- return nullptr; // appease code analysis
- }
+element_t::~element_t()
+{
+}
- // -----------------------------------------------------------------------------
- // factory_lib_entry_t: factory class to wrap macro based chips/elements
- // -----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------------------
+// net_device_t_base_factory
+// ----------------------------------------------------------------------------------------
- pool_owned_ptr<device_t> library_element_t::Create(netlist_state_t &anetlist, const pstring &name)
- {
- return pool().make_poolptr<NETLIB_NAME(wrapper)>(anetlist, name);
- }
+list_t::list_t( setup_t &setup)
+: m_setup(setup)
+{
+}
+
+list_t::~list_t()
+{
+ clear();
+}
+
+void list_t::register_device(std::unique_ptr<element_t> &&factory)
+{
+ for (auto & e : *this)
+ if (e->name() == factory->name())
+ m_setup.log().fatal(MF_1_FACTORY_ALREADY_CONTAINS_1, factory->name());
+ push_back(std::move(factory));
+}
- void library_element_t::macro_actions(nlparse_t &nparser, const pstring &name)
+factory::element_t * list_t::factory_by_name(const pstring &devname)
+{
+ for (auto & e : *this)
{
- nparser.namespace_push(name);
- nparser.include(this->name());
- nparser.namespace_pop();
+ if (e->name() == devname)
+ return e.get();
}
+ m_setup.log().fatal(MF_1_CLASS_1_NOT_FOUND, devname);
+ return nullptr; // appease code analysis
+}
+
+// -----------------------------------------------------------------------------
+// factory_lib_entry_t: factory class to wrap macro based chips/elements
+// -----------------------------------------------------------------------------
+
+plib::owned_ptr<device_t> library_element_t::Create(netlist_t &anetlist, const pstring &name)
+{
+ return plib::owned_ptr<device_t>::Create<NETLIB_NAME(wrapper)>(anetlist, name);
+}
+
+void library_element_t::macro_actions(netlist_t &anetlist, const pstring &name)
+{
+ anetlist.setup().namespace_push(name);
+ anetlist.setup().include(this->name());
+ anetlist.setup().namespace_pop();
+}
+
+NETLIB_RESET(wrapper)
+{
+}
+
+NETLIB_UPDATE(wrapper)
+{
+}
+
-} // namespace factory
- } // namespace netlist
+} }
diff --git a/src/lib/netlist/nl_factory.h b/src/lib/netlist/nl_factory.h
index 271bf72bf90..6dad6c5e171 100644
--- a/src/lib/netlist/nl_factory.h
+++ b/src/lib/netlist/nl_factory.h
@@ -9,58 +9,46 @@
#ifndef NLFACTORY_H_
#define NLFACTORY_H_
-#include "nltypes.h"
#include "plib/palloc.h"
#include "plib/ptypes.h"
-#include <vector>
-
-#define NETLIB_DEVICE_IMPL_ALIAS(p_alias, chip, p_name, p_def_param) \
- NETLIB_DEVICE_IMPL_BASE(devices, p_alias, chip, p_name, p_def_param) \
-
-#define NETLIB_DEVICE_IMPL(chip, p_name, p_def_param) \
- NETLIB_DEVICE_IMPL_NS(devices, chip, p_name, p_def_param)
-
-#define NETLIB_DEVICE_IMPL_NS(ns, chip, p_name, p_def_param) \
- NETLIB_DEVICE_IMPL_BASE(ns, chip, chip, p_name, p_def_param) \
+#define NETLIB_DEVICE_IMPL(chip) \
+ static std::unique_ptr<factory::element_t> NETLIB_NAME(chip ## _c)( \
+ const pstring &name, const pstring &classname, const pstring &def_param) \
+ { \
+ return std::unique_ptr<factory::element_t>(plib::palloc<factory::device_element_t<NETLIB_NAME(chip)>>(name, classname, def_param, pstring(__FILE__))); \
+ } \
+ factory::constructor_ptr_t decl_ ## chip = NETLIB_NAME(chip ## _c);
-#define NETLIB_DEVICE_IMPL_BASE(ns, p_alias, chip, p_name, p_def_param) \
- static plib::unique_ptr<factory::element_t> NETLIB_NAME(p_alias ## _c) \
- (const pstring &classname) \
+#define NETLIB_DEVICE_IMPL_NS(ns, chip) \
+ static std::unique_ptr<factory::element_t> NETLIB_NAME(chip ## _c)( \
+ const pstring &name, const pstring &classname, const pstring &def_param) \
{ \
- return plib::make_unique<factory::device_element_t<ns :: NETLIB_NAME(chip)>>(p_name, classname, p_def_param, pstring(__FILE__)); \
+ return std::unique_ptr<factory::element_t>(plib::palloc<factory::device_element_t<ns :: NETLIB_NAME(chip)>>(name, classname, def_param, pstring(__FILE__))); \
} \
- \
- factory::constructor_ptr_t decl_ ## p_alias = NETLIB_NAME(p_alias ## _c);
+ factory::constructor_ptr_t decl_ ## chip = NETLIB_NAME(chip ## _c);
namespace netlist {
+ class netlist_t;
class device_t;
- class nlparse_t;
class setup_t;
- class netlist_state_t;
namespace factory {
// -----------------------------------------------------------------------------
// net_dev class factory
// -----------------------------------------------------------------------------
- class element_t
+ class element_t : plib::nocopyassignmove
{
public:
element_t(const pstring &name, const pstring &classname,
const pstring &def_param);
element_t(const pstring &name, const pstring &classname,
const pstring &def_param, const pstring &sourcefile);
- virtual ~element_t() = default;
+ virtual ~element_t();
- COPYASSIGNMOVE(element_t, default)
-
- virtual pool_owned_ptr<device_t> Create(netlist_state_t &anetlist, const pstring &name) = 0;
- virtual void macro_actions(nlparse_t &nparser, const pstring &name)
- {
- plib::unused_var(nparser);
- plib::unused_var(name);
- }
+ virtual plib::owned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) = 0;
+ virtual void macro_actions(netlist_t &anetlist, const pstring &name) {}
const pstring &name() const { return m_name; }
const pstring &classname() const { return m_classname; }
@@ -85,28 +73,26 @@ namespace factory {
const pstring &def_param, const pstring &sourcefile)
: element_t(name, classname, def_param, sourcefile) { }
- pool_owned_ptr<device_t> Create(netlist_state_t &anetlist, const pstring &name) override
+ plib::owned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) override
{
- return pool().make_poolptr<C>(anetlist, name);
+ return plib::owned_ptr<device_t>::Create<C>(anetlist, name);
}
};
- class list_t : public std::vector<plib::unique_ptr<element_t>>
+ class list_t : public std::vector<std::unique_ptr<element_t>>
{
public:
- explicit list_t(log_type &alog);
- ~list_t() = default;
-
- COPYASSIGNMOVE(list_t, delete)
+ explicit list_t(setup_t &m_setup);
+ ~list_t();
template<class device_class>
void register_device(const pstring &name, const pstring &classname,
const pstring &def_param)
{
- register_device(plib::make_unique<device_element_t<device_class>>(name, classname, def_param));
+ register_device(std::unique_ptr<element_t>(plib::palloc<device_element_t<device_class>>(name, classname, def_param)));
}
- void register_device(plib::unique_ptr<element_t> &&factory);
+ void register_device(std::unique_ptr<element_t> &&factory);
element_t * factory_by_name(const pstring &devname);
@@ -117,20 +103,21 @@ namespace factory {
}
private:
- log_type &m_log;
+ setup_t &m_setup;
};
// -----------------------------------------------------------------------------
// factory_creator_ptr_t
// -----------------------------------------------------------------------------
- using constructor_ptr_t = plib::unique_ptr<element_t> (*)(const pstring &classname);
+ using constructor_ptr_t = std::unique_ptr<element_t> (*)(const pstring &name, const pstring &classname,
+ const pstring &def_param);
template <typename T>
- plib::unique_ptr<element_t> constructor_t(const pstring &name, const pstring &classname,
+ std::unique_ptr<element_t> constructor_t(const pstring &name, const pstring &classname,
const pstring &def_param)
{
- return plib::make_unique<device_element_t<T>>(name, classname, def_param);
+ return std::unique_ptr<element_t>(plib::palloc<device_element_t<T>>(name, classname, def_param));
}
// -----------------------------------------------------------------------------
@@ -141,24 +128,22 @@ namespace factory {
{
public:
- library_element_t(const pstring &name, const pstring &classname,
+ library_element_t(setup_t &setup, const pstring &name, const pstring &classname,
const pstring &def_param, const pstring &source)
- : element_t(name, classname, def_param, source)
- {
- }
+ : element_t(name, classname, def_param, source) { }
- pool_owned_ptr<device_t> Create(netlist_state_t &anetlist, const pstring &name) override;
+ plib::owned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) override;
- void macro_actions(nlparse_t &nparser, const pstring &name) override;
+ void macro_actions(netlist_t &anetlist, const pstring &name) override;
private:
};
- } // namespace factory
+ }
namespace devices {
void initialize_factory(factory::list_t &factory);
- } // namespace devices
-} // namespace netlist
+ }
+}
#endif /* NLFACTORY_H_ */
diff --git a/src/lib/netlist/nl_lists.h b/src/lib/netlist/nl_lists.h
index 325f8a67c72..1eae38b25fb 100644
--- a/src/lib/netlist/nl_lists.h
+++ b/src/lib/netlist/nl_lists.h
@@ -10,24 +10,32 @@
#ifndef NLLISTS_H_
#define NLLISTS_H_
-#include "plib/pchrono.h"
+#include "nl_config.h"
+#include "netlist_types.h"
#include "plib/plists.h"
+#include "plib/pchrono.h"
#include "plib/ptypes.h"
-#include "nl_config.h"
-#include "nltypes.h"
-
-#include <algorithm>
#include <atomic>
-#include <mutex>
#include <thread>
+#include <mutex>
+#include <algorithm>
#include <utility>
-
// ----------------------------------------------------------------------------------------
// timed queue
// ----------------------------------------------------------------------------------------
+/*
+ * Use -DUSE_HEAP=1 to use stdc++ heap functions instead of linear processing.
+ *
+ * This slows down processing by about 25% on a Kaby Lake.
+ */
+
+#ifndef USE_HEAP
+#define USE_HEAP (0)
+#endif
+
namespace netlist
{
//FIXME: move to an appropriate place
@@ -35,11 +43,10 @@ namespace netlist
class pspin_mutex
{
public:
- pspin_mutex() noexcept = default;
+ pspin_mutex() noexcept { }
void lock() noexcept{ while (m_lock.test_and_set(std::memory_order_acquire)) { } }
void unlock() noexcept { m_lock.clear(std::memory_order_release); }
private:
- PALIGNAS_CACHELINE()
std::atomic_flag m_lock = ATOMIC_FLAG_INIT;
};
@@ -55,11 +62,10 @@ namespace netlist
struct pqentry_t final
{
constexpr pqentry_t() noexcept : m_exec_time(), m_object(nullptr) { }
- constexpr pqentry_t(const Time t, const Element o) noexcept : m_exec_time(t), m_object(o) { }
-#if 0
+ constexpr pqentry_t(const Time &t, const Element &o) noexcept : m_exec_time(t), m_object(o) { }
~pqentry_t() = default;
constexpr pqentry_t(const pqentry_t &e) noexcept = default;
- constexpr pqentry_t(pqentry_t &&e) noexcept = default;
+ constexpr pqentry_t(pqentry_t &&e) = default;
pqentry_t& operator=(pqentry_t && other) noexcept = default;
pqentry_t& operator=(const pqentry_t &other) noexcept = default;
@@ -68,97 +74,91 @@ namespace netlist
std::swap(m_exec_time, other.m_exec_time);
std::swap(m_object, other.m_object);
}
-#endif
+
struct QueueOp
{
- inline static constexpr bool less(const pqentry_t &lhs, const pqentry_t &rhs) noexcept
+ static constexpr bool less(const pqentry_t &lhs, const pqentry_t &rhs) noexcept
{
return (lhs.m_exec_time < rhs.m_exec_time);
}
- inline static constexpr bool lessequal(const pqentry_t &lhs, const pqentry_t &rhs) noexcept
- {
- return (lhs.m_exec_time <= rhs.m_exec_time);
- }
-
- inline static constexpr bool equal(const pqentry_t &lhs, const pqentry_t &rhs) noexcept
+ static constexpr bool equal(const pqentry_t &lhs, const pqentry_t &rhs) noexcept
{
return lhs.m_object == rhs.m_object;
}
- inline static constexpr bool equal(const pqentry_t &lhs, const Element &rhs) noexcept
+ static constexpr bool equal(const pqentry_t &lhs, const Element &rhs) noexcept
{
return lhs.m_object == rhs;
}
- inline static constexpr pqentry_t never() noexcept { return pqentry_t(Time::never(), nullptr); }
+ static constexpr pqentry_t never() noexcept { return pqentry_t(Time::never(), nullptr); }
};
Time m_exec_time;
Element m_object;
};
+#if !USE_HEAP
/* Use TS = true for a threadsafe queue */
- template <class T, bool TS, bool KEEPSTAT, class QueueOp = typename T::QueueOp>
- class timed_queue_linear : plib::nocopyassignmove
+ template <class T, bool TS, class QueueOp = typename T::QueueOp>
+ class timed_queue : plib::nocopyassignmove
{
public:
- explicit timed_queue_linear(const std::size_t list_size)
+ explicit timed_queue(const std::size_t list_size)
: m_list(list_size)
{
clear();
}
- std::size_t capacity() const noexcept { return m_list.capacity() - 1; }
- bool empty() const noexcept { return (m_end == &m_list[1]); }
+ constexpr std::size_t capacity() const noexcept { return m_list.capacity() - 1; }
+ constexpr bool empty() const noexcept { return (m_end == &m_list[1]); }
- void push(T && e) noexcept
+ void push(T &&e) noexcept
{
/* Lock */
- lock_guard_type lck(m_lock);
- T * i(m_end-1);
- for (; QueueOp::less(*(i), e); --i)
+ tqlock lck(m_lock);
+ T * i(m_end);
+ for (; QueueOp::less(*(i - 1), e); --i)
{
- *(i+1) = *(i);
+ *(i) = std::move(*(i-1));
m_prof_sortmove.inc();
}
- *(i+1) = std::move(e);
+ *i = std::move(e);
++m_end;
m_prof_call.inc();
}
- T pop() noexcept { return *(--m_end); }
+ void pop() noexcept { --m_end; }
const T &top() const noexcept { return *(m_end-1); }
template <class R>
void remove(const R &elem) noexcept
{
/* Lock */
- lock_guard_type lck(m_lock);
- m_prof_remove.inc();
-
+ tqlock lck(m_lock);
for (T * i = m_end - 1; i > &m_list[0]; --i)
{
if (QueueOp::equal(*i, elem))
{
- std::copy(i+1, m_end--, i);
+ --m_end;
+ for (;i < m_end; ++i)
+ *i = std::move(*(i+1));
return;
}
}
}
- void retime(T && elem) noexcept
+ void retime(const T &elem) noexcept
{
/* Lock */
- lock_guard_type lck(m_lock);
- m_prof_retime.inc();
-
+ tqlock lck(m_lock);
for (T * i = m_end - 1; i > &m_list[0]; --i)
{
if (QueueOp::equal(*i, elem)) // partial equal!
{
- *i = std::move(elem);
+ *i = elem;
while (QueueOp::less(*(i-1), *i))
{
std::swap(*(i-1), *i);
@@ -174,9 +174,9 @@ namespace netlist
}
}
- void clear() noexcept
+ void clear()
{
- lock_guard_type lck(m_lock);
+ tqlock lck(m_lock);
m_end = &m_list[0];
/* put an empty element with maximum time into the queue.
* the insert algo above will run into this element and doesn't
@@ -188,61 +188,55 @@ namespace netlist
// save state support & mame disasm
- const T *listptr() const noexcept { return &m_list[1]; }
- std::size_t size() const noexcept { return static_cast<std::size_t>(m_end - &m_list[1]); }
- const T & operator[](const std::size_t index) const noexcept { return m_list[ 1 + index]; }
+ constexpr const T *listptr() const noexcept { return &m_list[1]; }
+ constexpr std::size_t size() const noexcept { return static_cast<std::size_t>(m_end - &m_list[1]); }
+ constexpr const T & operator[](const std::size_t index) const noexcept { return m_list[ 1 + index]; }
private:
- using mutex_type = pspin_mutex<TS>;
- using lock_guard_type = std::lock_guard<mutex_type>;
+ using tqmutex = pspin_mutex<TS>;
+ using tqlock = std::lock_guard<tqmutex>;
- mutex_type m_lock;
- PALIGNAS_CACHELINE()
- T * m_end;
- //std::vector<T> m_list;
- plib::aligned_vector<T> m_list;
+ tqmutex m_lock;
+ T * m_end;
+ std::vector<T> m_list;
public:
// profiling
- nperfcount_t<KEEPSTAT> m_prof_sortmove;
- nperfcount_t<KEEPSTAT> m_prof_call;
- nperfcount_t<KEEPSTAT> m_prof_remove;
- nperfcount_t<KEEPSTAT> m_prof_retime;
+ nperfcount_t m_prof_sortmove;
+ nperfcount_t m_prof_call;
};
-
- template <class T, bool TS, bool KEEPSTAT, class QueueOp = typename T::QueueOp>
- class timed_queue_heap : plib::nocopyassignmove
+#else
+ template <class T, bool TS, class QueueOp = typename T::QueueOp>
+ class timed_queue : plib::nocopyassignmove
{
public:
struct compare
{
- constexpr bool operator()(const T &a, const T &b) const { return QueueOp::lessequal(b,a); }
+ constexpr bool operator()(const T &a, const T &b) const { return QueueOp::less(b,a); }
};
- explicit timed_queue_heap(const std::size_t list_size)
+ explicit timed_queue(const std::size_t list_size)
: m_list(list_size)
{
clear();
}
- std::size_t capacity() const noexcept { return m_list.capacity(); }
- bool empty() const noexcept { return &m_list[0] == m_end; }
+ constexpr std::size_t capacity() const noexcept { return m_list.capacity(); }
+ constexpr bool empty() const noexcept { return &m_list[0] == m_end; }
void push(T &&e) noexcept
{
/* Lock */
- lock_guard_type lck(m_lock);
+ tqlock lck(m_lock);
*m_end++ = e;
std::push_heap(&m_list[0], m_end, compare());
m_prof_call.inc();
}
- T pop() noexcept
+ void pop() noexcept
{
- T ret(m_list[0]);
std::pop_heap(&m_list[0], m_end, compare());
m_end--;
- return ret;
}
const T &top() const noexcept { return m_list[0]; }
@@ -251,7 +245,7 @@ namespace netlist
void remove(const R &elem) noexcept
{
/* Lock */
- lock_guard_type lck(m_lock);
+ tqlock lck(m_lock);
for (T * i = m_end - 1; i >= &m_list[0]; i--)
{
if (QueueOp::equal(*i, elem))
@@ -268,7 +262,7 @@ namespace netlist
void retime(const T &elem) noexcept
{
/* Lock */
- lock_guard_type lck(m_lock);
+ tqlock lck(m_lock);
for (T * i = m_end - 1; i >= &m_list[0]; i--)
{
if (QueueOp::equal(*i, elem)) // partial equal!
@@ -282,7 +276,7 @@ namespace netlist
void clear()
{
- lock_guard_type lck(m_lock);
+ tqlock lck(m_lock);
m_list.clear();
m_end = &m_list[0];
}
@@ -293,28 +287,19 @@ namespace netlist
constexpr std::size_t size() const noexcept { return m_list.size(); }
constexpr const T & operator[](const std::size_t index) const { return m_list[ 0 + index]; }
private:
- using mutex_type = pspin_mutex<TS>;
- using lock_guard_type = std::lock_guard<mutex_type>;
+ using tqmutex = pspin_mutex<TS>;
+ using tqlock = std::lock_guard<tqmutex>;
- mutex_type m_lock;
+ tqmutex m_lock;
std::vector<T> m_list;
T *m_end;
public:
// profiling
- nperfcount_t<KEEPSTAT> m_prof_sortmove;
- nperfcount_t<KEEPSTAT> m_prof_call;
+ nperfcount_t m_prof_sortmove;
+ nperfcount_t m_prof_call;
};
-
- /*
- * 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, bool KEEPSTAT, class QueueOp = typename T::QueueOp>
- using timed_queue = timed_queue_linear<T, TS, KEEPSTAT, QueueOp>;
-
-} // namespace netlist
+#endif
+}
#endif /* NLLISTS_H_ */
diff --git a/src/lib/netlist/nl_parser.cpp b/src/lib/netlist/nl_parser.cpp
index cecfbe862bf..4685a13c354 100644
--- a/src/lib/netlist/nl_parser.cpp
+++ b/src/lib/netlist/nl_parser.cpp
@@ -6,9 +6,9 @@
*/
#include "nl_parser.h"
-#include "nl_base.h"
-#include "nl_errstr.h"
#include "nl_factory.h"
+#include "nl_errstr.h"
+#include "nl_base.h"
namespace netlist
{
@@ -24,13 +24,13 @@ void parser_t::verror(const pstring &msg, int line_num, const pstring &line)
//throw error;
}
+
bool parser_t::parse(const pstring &nlname)
{
- this->identifier_chars("abcdefghijklmnopqrstuvwvxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_.-")
- .number_chars(".0123456789", "0123456789eE-.") //FIXME: processing of numbers
- //set_whitespace(pstring("").cat(' ').cat(9).cat(10).cat(13));
- .whitespace(pstring("") + ' ' + static_cast<char>(9) + static_cast<char>(10) + static_cast<char>(13))
- .comment("/*", "*/", "//");
+ set_identifier_chars("abcdefghijklmnopqrstuvwvxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_.-");
+ set_number_chars(".0123456789", "0123456789eE-."); //FIXME: processing of numbers
+ set_whitespace(pstring("").cat(' ').cat(9).cat(10).cat(13));
+ set_comment("/*", "*/", "//");
m_tok_param_left = register_token("(");
m_tok_param_right = register_token(")");
m_tok_comma = register_token(",");
@@ -357,10 +357,10 @@ void parser_t::device(const pstring &dev_type)
m_setup.register_dev(dev_type, devname);
m_setup.log().debug("Parser: IC: {1}\n", devname);
- for (const pstring &tp : paramlist)
+ for (pstring tp : paramlist)
{
require_token(m_tok_comma);
- if (plib::startsWith(tp, "+"))
+ if (tp.startsWith("+"))
{
pstring output_name = get_identifier();
m_setup.log().debug("Link: {1} {2}\n", tp, output_name);
@@ -395,15 +395,18 @@ void parser_t::device(const pstring &dev_type)
// ----------------------------------------------------------------------------------------
-nl_double parser_t::eval_param(const token_t &tok)
+nl_double parser_t::eval_param(const token_t tok)
{
- static std::array<pstring, 6> macs = {"", "RES_K", "RES_M", "CAP_U", "CAP_N", "CAP_P"};
- static std::array<nl_double, 6> facs = {1, 1e3, 1e6, 1e-6, 1e-9, 1e-12};
- std::size_t f=0;
+ static pstring macs[6] = {"", "RES_K", "RES_M", "CAP_U", "CAP_N", "CAP_P"};
+ static nl_double facs[6] = {1, 1e3, 1e6, 1e-6, 1e-9, 1e-12};
+ int i;
+ int f=0;
+ bool e;
nl_double ret;
+ pstring val;
- for (std::size_t i=1; i<macs.size();i++)
- if (tok.str() == macs[i])
+ for (i=1; i<6;i++)
+ if (tok.str().equals(macs[i]))
f = i;
if (f>0)
{
@@ -413,13 +416,13 @@ nl_double parser_t::eval_param(const token_t &tok)
}
else
{
- bool err;
- ret = plib::pstonum_ne<nl_double>(tok.str(), err);
- if (err)
- error(plib::pfmt("Parameter value <{1}> not double \n")(tok.str()));
+ val = tok.str();
+ ret = val.as_double(&e);
+ if (e)
+ error(plib::pfmt("Parameter value <{1}> not double \n")(val));
}
return ret * facs[f];
}
-} // namespace netlist
+}
diff --git a/src/lib/netlist/nl_parser.h b/src/lib/netlist/nl_parser.h
index 92459c4b87b..a813629faa0 100644
--- a/src/lib/netlist/nl_parser.h
+++ b/src/lib/netlist/nl_parser.h
@@ -16,12 +16,8 @@ namespace netlist
class parser_t : public plib::ptokenizer
{
public:
- template <typename T>
- parser_t(T &&strm, nlparse_t &setup)
- : plib::ptokenizer(std::forward<T>(strm))
- , m_setup(setup)
- {
- }
+ parser_t(plib::putf8_reader &strm, setup_t &setup)
+ : plib::ptokenizer(strm), m_setup(setup) {}
bool parse(const pstring &nlname = "");
@@ -43,12 +39,12 @@ namespace netlist
void net_truthtable_start(const pstring &nlname);
/* for debugging messages */
- //netlist_state_t &netlist() { return m_setup.netlist(); }
+ netlist_t &netlist() { return m_setup.netlist(); }
- void verror(const pstring &msg, int line_num, const pstring &line) override;
+ virtual void verror(const pstring &msg, int line_num, const pstring &line) override;
private:
- nl_double eval_param(const token_t &tok);
+ nl_double eval_param(const token_t tok);
token_id_t m_tok_param_left;
token_id_t m_tok_param_right;
@@ -72,9 +68,9 @@ namespace netlist
token_id_t m_tok_TT_LINE;
token_id_t m_tok_TT_FAMILY;
- nlparse_t &m_setup;
+ setup_t &m_setup;
};
-} // namespace netlist
+}
#endif /* NL_PARSER_H_ */
diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp
index b9300f5ad9c..df761bc3f88 100644
--- a/src/lib/netlist/nl_setup.cpp
+++ b/src/lib/netlist/nl_setup.cpp
@@ -6,243 +6,128 @@
*/
#include "plib/palloc.h"
-#include "analog/nld_twoterm.h"
-#include "devices/nlid_proxy.h"
-#include "devices/nlid_system.h"
-#include "devices/nlid_truthtable.h"
+#include "plib/putil.h"
#include "nl_base.h"
-#include "nl_factory.h"
-#include "nl_parser.h"
#include "nl_setup.h"
-#include "plib/putil.h"
+#include "nl_parser.h"
+#include "nl_factory.h"
+#include "devices/nlid_system.h"
+#include "devices/nlid_proxy.h"
+#include "analog/nld_twoterm.h"
#include "solver/nld_solver.h"
+#include "devices/nlid_truthtable.h"
-#include <cmath>
+// ----------------------------------------------------------------------------------------
+// setup_t
+// ----------------------------------------------------------------------------------------
namespace netlist
{
- // ----------------------------------------------------------------------------------------
- // nl_parse_t
- // ----------------------------------------------------------------------------------------
-
- nlparse_t::nlparse_t(setup_t &setup, log_type &log)
- : m_factory(log)
- , m_setup(setup)
- , m_log(log)
+setup_t::setup_t(netlist_t &netlist)
+ : m_netlist(netlist)
+ , m_factory(*this)
+ , m_proxy_cnt(0)
, m_frontier_cnt(0)
- { }
-
- void nlparse_t::register_alias(const pstring &alias, const pstring &out)
- {
- pstring alias_fqn = build_fqn(alias);
- pstring out_fqn = build_fqn(out);
- register_alias_nofqn(alias_fqn, out_fqn);
- }
-
- void nlparse_t::register_dippins_arr(const pstring &terms)
- {
- std::vector<pstring> list(plib::psplit(terms,", "));
- if (list.size() == 0 || (list.size() % 2) == 1)
- log().fatal(MF_1_DIP_PINS_MUST_BE_AN_EQUAL_NUMBER_OF_PINS_1,
- build_fqn(""));
- std::size_t n = list.size();
- for (std::size_t i = 0; i < n / 2; i++)
- {
- register_alias(plib::pfmt("{1}")(i+1), list[i * 2]);
- register_alias(plib::pfmt("{1}")(n-i), list[i * 2 + 1]);
- }
- }
-
- void nlparse_t::register_dev(const pstring &classname, const pstring &name)
- {
- auto f = m_factory.factory_by_name(classname);
- if (f == nullptr)
- log().fatal(MF_1_CLASS_1_NOT_FOUND, classname);
- else
- {
- /* make sure we parse macro library entries */
- f->macro_actions(*this, name);
- pstring key = build_fqn(name);
- if (device_exists(key))
- log().fatal(MF_1_DEVICE_ALREADY_EXISTS_1, name);
- else
- m_device_factory.insert(m_device_factory.end(), {key, f});
- }
- }
-
- void nlparse_t::register_link(const pstring &sin, const pstring &sout)
- {
- register_link_fqn(build_fqn(sin), build_fqn(sout));
- }
-
- void nlparse_t::register_link_arr(const pstring &terms)
- {
- std::vector<pstring> list(plib::psplit(terms,", "));
- if (list.size() < 2)
- log().fatal(MF_2_NET_C_NEEDS_AT_LEAST_2_TERMINAL);
- for (std::size_t i = 1; i < list.size(); i++)
- {
- register_link(list[0], list[i]);
- }
- }
-
- void nlparse_t::include(const pstring &netlist_name)
- {
- for (auto &source : m_sources)
- {
- if (source->parse(*this, netlist_name))
- return;
- }
- log().fatal(MF_1_NOT_FOUND_IN_SOURCE_COLLECTION, netlist_name);
- }
-
-
- void nlparse_t::namespace_push(const pstring &aname)
- {
- if (m_namespace_stack.empty())
- //m_namespace_stack.push(netlist().name() + "." + aname);
- m_namespace_stack.push(aname);
- else
- m_namespace_stack.push(m_namespace_stack.top() + "." + aname);
- }
-
- void nlparse_t::namespace_pop()
- {
- m_namespace_stack.pop();
- }
-
- void nlparse_t::register_param(const pstring &param, const double value)
- {
- if (std::abs(value - std::floor(value)) > 1e-30 || std::abs(value) > 1e9)
- register_param(param, plib::pfmt("{1:.9}").e(value));
- else
- register_param(param, plib::pfmt("{1}")(static_cast<long>(value)));
- }
-
- void nlparse_t::register_param(const pstring &param, const pstring &value)
- {
- pstring fqn = build_fqn(param);
-
- auto idx = m_param_values.find(fqn);
- if (idx == m_param_values.end())
- {
- if (!m_param_values.insert({fqn, value}).second)
- log().fatal(MF_1_ADDING_PARAMETER_1_TO_PARAMETER_LIST,
- param);
- }
- else
- {
- log().warning(MW_3_OVERWRITING_PARAM_1_OLD_2_NEW_3, fqn, idx->second,
- value);
- m_param_values[fqn] = value;
- }
- }
+{
+ devices::initialize_factory(m_factory);
+}
- void nlparse_t::register_lib_entry(const pstring &name, const pstring &sourcefile)
- {
- m_factory.register_device(plib::make_unique<factory::library_element_t>(name, name, "", sourcefile));
- }
+setup_t::~setup_t()
+{
+ m_links.clear();
+ m_alias.clear();
+ m_params.clear();
+ m_terminals.clear();
+ m_param_values.clear();
- void nlparse_t::register_frontier(const pstring &attach, const double r_IN, const double r_OUT)
- {
- pstring frontier_name = plib::pfmt("frontier_{1}")(m_frontier_cnt);
- m_frontier_cnt++;
- register_dev("FRONTIER_DEV", frontier_name);
- register_param(frontier_name + ".RIN", r_IN);
- register_param(frontier_name + ".ROUT", r_OUT);
- register_link(frontier_name + ".G", "GND");
- pstring attfn = build_fqn(attach);
- pstring front_fqn = build_fqn(frontier_name);
- bool found = false;
- for (auto & link : m_links)
- {
- if (link.first == attfn)
- {
- link.first = front_fqn + ".I";
- found = true;
- }
- else if (link.second == attfn)
- {
- link.second = front_fqn + ".I";
- found = true;
- }
- }
- if (!found)
- log().fatal(MF_1_FOUND_NO_OCCURRENCE_OF_1, attach);
- register_link(attach, frontier_name + ".Q");
- }
+ m_sources.clear();
+}
- void nlparse_t::tt_factory_create(tt_desc &desc, const pstring &sourcefile)
- {
- auto fac = devices::tt_factory_create(desc, sourcefile);
- m_factory.register_device(std::move(fac));
- }
+pstring setup_t::build_fqn(const pstring &obj_name) const
+{
+ if (m_namespace_stack.empty())
+ //return netlist().name() + "." + obj_name;
+ return obj_name;
+ else
+ return m_namespace_stack.top() + "." + obj_name;
+}
- pstring nlparse_t::build_fqn(const pstring &obj_name) const
- {
- if (m_namespace_stack.empty())
- //return netlist().name() + "." + obj_name;
- return obj_name;
- else
- return m_namespace_stack.top() + "." + obj_name;
- }
+void setup_t::namespace_push(const pstring &aname)
+{
+ if (m_namespace_stack.empty())
+ //m_namespace_stack.push(netlist().name() + "." + aname);
+ m_namespace_stack.push(aname);
+ else
+ m_namespace_stack.push(m_namespace_stack.top() + "." + aname);
+}
- void nlparse_t::register_alias_nofqn(const pstring &alias, const pstring &out)
- {
- if (!m_alias.insert({alias, out}).second)
- log().fatal(MF_1_ADDING_ALI1_TO_ALIAS_LIST, alias);
- }
+void setup_t::namespace_pop()
+{
+ m_namespace_stack.pop();
+}
- void nlparse_t::register_link_fqn(const pstring &sin, const pstring &sout)
- {
- link_t temp = link_t(sin, sout);
- log().debug("link {1} <== {2}\n", sin, sout);
- m_links.push_back(temp);
- }
+void setup_t::register_lib_entry(const pstring &name, const pstring &sourcefile)
+{
+ factory().register_device(plib::make_unique_base<factory::element_t, factory::library_element_t>(*this, name, name, "", sourcefile));
+}
- bool nlparse_t::device_exists(const pstring &name) const
- {
- for (auto &d : m_device_factory)
- if (d.first == name)
- return true;
- return false;
- }
+void setup_t::register_dev(const pstring &classname, const pstring &name)
+{
+ auto f = factory().factory_by_name(classname);
+ if (f == nullptr)
+ log().fatal(MF_1_CLASS_1_NOT_FOUND, classname);
+ /* make sure we parse macro library entries */
+ f->macro_actions(netlist(), name);
+ m_device_factory.push_back(std::pair<pstring, factory::element_t *>(build_fqn(name), f));
+}
- bool nlparse_t::parse_stream(plib::unique_ptr<plib::pistream> &&istrm, const pstring &name)
+bool setup_t::device_exists(const pstring &name) const
+{
+ for (auto e : m_device_factory)
{
- return parser_t(std::move(plib::ppreprocessor(&m_defines).process(std::move(istrm))), *this).parse(name);
+ if (e.first == name)
+ return true;
}
+ return false;
+}
- void nlparse_t::add_define(const pstring &defstr)
- {
- auto p = defstr.find("=");
- if (p != pstring::npos)
- add_define(plib::left(defstr, p), defstr.substr(p+1));
- else
- add_define(defstr, "1");
- }
- // ----------------------------------------------------------------------------------------
- // setup_t
- // ----------------------------------------------------------------------------------------
+void setup_t::register_model(const pstring &model_in)
+{
+ auto pos = model_in.find(" ");
+ if (pos == pstring::npos)
+ log().fatal(MF_1_UNABLE_TO_PARSE_MODEL_1, model_in);
+ pstring model = model_in.left(pos).trim().ucase();
+ pstring def = model_in.substr(pos + 1).trim();
+ if (!m_models.insert({model, def}).second)
+ log().fatal(MF_1_MODEL_ALREADY_EXISTS_1, model_in);
+}
+void setup_t::register_alias_nofqn(const pstring &alias, const pstring &out)
+{
+ if (!m_alias.insert({alias, out}).second)
+ log().fatal(MF_1_ADDING_ALI1_TO_ALIAS_LIST, alias);
+}
-setup_t::setup_t(netlist_state_t &nlstate)
- : nlparse_t(*this, nlstate.log())
- , m_nlstate(nlstate)
- , m_netlist_params(nullptr)
- , m_proxy_cnt(0)
+void setup_t::register_alias(const pstring &alias, const pstring &out)
{
+ pstring alias_fqn = build_fqn(alias);
+ pstring out_fqn = build_fqn(out);
+ register_alias_nofqn(alias_fqn, out_fqn);
}
-setup_t::~setup_t() noexcept
+void setup_t::register_dippins_arr(const pstring &terms)
{
- // FIXME: can't see a need any longer
- m_links.clear();
- m_params.clear();
- m_terminals.clear();
- m_param_values.clear();
- m_sources.clear();
+ std::vector<pstring> list(plib::psplit(terms,", "));
+ if (list.size() == 0 || (list.size() % 2) == 1)
+ log().fatal(MF_1_DIP_PINS_MUST_BE_AN_EQUAL_NUMBER_OF_PINS_1,
+ build_fqn(""));
+ std::size_t n = list.size();
+ for (std::size_t i = 0; i < n / 2; i++)
+ {
+ register_alias(plib::pfmt("{1}")(i+1), list[i * 2]);
+ register_alias(plib::pfmt("{1}")(n-i), list[i * 2 + 1]);
+ }
}
pstring setup_t::termtype_as_str(detail::core_terminal_t &in) const
@@ -260,7 +145,7 @@ pstring setup_t::termtype_as_str(detail::core_terminal_t &in) const
return pstring("Error");
}
-pstring setup_t::get_initial_param_val(const pstring &name, const pstring &def) const
+pstring setup_t::get_initial_param_val(const pstring &name, const pstring &def)
{
auto i = m_param_values.find(name);
if (i != m_param_values.end())
@@ -269,6 +154,40 @@ pstring setup_t::get_initial_param_val(const pstring &name, const pstring &def)
return def;
}
+double setup_t::get_initial_param_val(const pstring &name, const double def)
+{
+ auto i = m_param_values.find(name);
+ if (i != m_param_values.end())
+ {
+ double vald = 0;
+ if (sscanf(i->second.c_str(), "%lf", &vald) != 1)
+ log().fatal(MF_2_INVALID_NUMBER_CONVERSION_1_2, name, i->second);
+ return vald;
+ }
+ else
+ return def;
+}
+
+int setup_t::get_initial_param_val(const pstring &name, const int def)
+{
+ auto i = m_param_values.find(name);
+ if (i != m_param_values.end())
+ {
+ double vald = 0;
+ if (sscanf(i->second.c_str(), "%lf", &vald) != 1)
+ log().fatal(MF_2_INVALID_NUMBER_CONVERSION_1_2, name, i->second);
+ return static_cast<int>(vald);
+ }
+ else
+ return def;
+}
+
+void setup_t::register_param(const pstring &name, param_t &param)
+{
+ if (!m_params.insert({param.name(), param_ref_t(param.name(), param.device(), param)}).second)
+ log().fatal(MF_1_ADDING_PARAMETER_1_TO_PARAMETER_LIST, name);
+}
+
void setup_t::register_term(detail::core_terminal_t &term)
{
if (!m_terminals.insert({term.name(), &term}).second)
@@ -277,6 +196,30 @@ void setup_t::register_term(detail::core_terminal_t &term)
log().debug("{1} {2}\n", termtype_as_str(term), term.name());
}
+void setup_t::register_link_arr(const pstring &terms)
+{
+ std::vector<pstring> list(plib::psplit(terms,", "));
+ if (list.size() < 2)
+ log().fatal(MF_2_NET_C_NEEDS_AT_LEAST_2_TERMINAL);
+ for (std::size_t i = 1; i < list.size(); i++)
+ {
+ register_link(list[0], list[i]);
+ }
+}
+
+
+void setup_t::register_link_fqn(const pstring &sin, const pstring &sout)
+{
+ link_t temp = link_t(sin, sout);
+ log().debug("link {1} <== {2}\n", sin, sout);
+ m_links.push_back(temp);
+}
+
+void setup_t::register_link(const pstring &sin, const pstring &sout)
+{
+ register_link_fqn(build_fqn(sin), build_fqn(sout));
+}
+
void setup_t::remove_connections(const pstring &pin)
{
pstring pinfn = build_fqn(pin);
@@ -298,14 +241,59 @@ void setup_t::remove_connections(const pstring &pin)
}
+void setup_t::register_frontier(const pstring &attach, const double r_IN, const double r_OUT)
+{
+ pstring frontier_name = plib::pfmt("frontier_{1}")(m_frontier_cnt);
+ m_frontier_cnt++;
+ register_dev("FRONTIER_DEV", frontier_name);
+ register_param(frontier_name + ".RIN", r_IN);
+ register_param(frontier_name + ".ROUT", r_OUT);
+ register_link(frontier_name + ".G", "GND");
+ pstring attfn = build_fqn(attach);
+ pstring front_fqn = build_fqn(frontier_name);
+ bool found = false;
+ for (auto & link : m_links)
+ {
+ if (link.first == attfn)
+ {
+ link.first = front_fqn + ".I";
+ found = true;
+ }
+ else if (link.second == attfn)
+ {
+ link.second = front_fqn + ".I";
+ found = true;
+ }
+ }
+ if (!found)
+ log().fatal(MF_1_FOUND_NO_OCCURRENCE_OF_1, attach);
+ register_link(attach, frontier_name + ".Q");
+}
+
-void setup_t::register_param_t(const pstring &name, param_t &param)
+void setup_t::register_param(const pstring &param, const double value)
{
- if (!m_params.insert({param.name(), param_ref_t(param.name(), param.device(), param)}).second)
- log().fatal(MF_1_ADDING_PARAMETER_1_TO_PARAMETER_LIST, name);
+ register_param(param, plib::pfmt("{1:.9}").e(value));
}
+void setup_t::register_param(const pstring &param, const pstring &value)
+{
+ pstring fqn = build_fqn(param);
+ auto idx = m_param_values.find(fqn);
+ if (idx == m_param_values.end())
+ {
+ if (!m_param_values.insert({fqn, value}).second)
+ log().fatal(MF_1_ADDING_PARAMETER_1_TO_PARAMETER_LIST,
+ param);
+ }
+ else
+ {
+ log().warning(MW_3_OVERWRITING_PARAM_1_OLD_2_NEW_3, fqn, idx->second,
+ value);
+ m_param_values[fqn] = value;
+ }
+}
const pstring setup_t::resolve_alias(const pstring &name) const
{
@@ -323,42 +311,6 @@ const pstring setup_t::resolve_alias(const pstring &name) const
return ret;
}
-std::vector<pstring> setup_t::get_terminals_for_device_name(const pstring &devname)
-{
- std::vector<pstring> terms;
- for (auto & t : m_terminals)
- {
- if (plib::startsWith(t.second->name(), devname))
- {
- pstring tn(t.second->name().substr(devname.length()+1));
- if (tn.find(".") == pstring::npos)
- terms.push_back(tn);
- }
- }
-
- for (auto & t : m_alias)
- {
- if (plib::startsWith(t.first, devname))
- {
- pstring tn(t.first.substr(devname.length()+1));
- //printf("\t%s %s %s\n", t.first.c_str(), t.second.c_str(), tn.c_str());
- if (tn.find(".") == pstring::npos)
- {
- terms.push_back(tn);
- pstring resolved = resolve_alias(t.first);
- //printf("\t%s %s %s\n", t.first.c_str(), t.second.c_str(), resolved.c_str());
- if (resolved != t.first)
- {
- auto found = std::find(terms.begin(), terms.end(), resolved.substr(devname.length()+1));
- if (found!=terms.end())
- terms.erase(found);
- }
- }
- }
- }
- return terms;
-}
-
detail::core_terminal_t *setup_t::find_terminal(const pstring &terminal_in, bool required)
{
const pstring &tname = resolve_alias(terminal_in);
@@ -425,7 +377,7 @@ devices::nld_base_proxy *setup_t::get_d_a_proxy(detail::core_terminal_t &out)
{
nl_assert(out.is_logic());
- auto &out_cast = static_cast<logic_output_t &>(out);
+ logic_output_t &out_cast = static_cast<logic_output_t &>(out);
devices::nld_base_proxy *proxy = out_cast.get_proxy();
if (proxy == nullptr)
@@ -433,25 +385,28 @@ devices::nld_base_proxy *setup_t::get_d_a_proxy(detail::core_terminal_t &out)
// create a new one ...
pstring x = plib::pfmt("proxy_da_{1}_{2}")(out.name())(m_proxy_cnt);
auto new_proxy =
- out_cast.logic_family()->create_d_a_proxy(m_nlstate, x, &out_cast);
+ out_cast.logic_family()->create_d_a_proxy(netlist(), x, &out_cast);
m_proxy_cnt++;
+
+ //new_proxy->start_dev();
+
/* connect all existing terminals to new net */
- for (auto & p : out.net().core_terms())
+ for (auto & p : out.net().m_core_terms)
{
p->clear_net(); // de-link from all nets ...
if (!connect(new_proxy->proxy_term(), *p))
log().fatal(MF_2_CONNECTING_1_TO_2,
new_proxy->proxy_term().name(), (*p).name());
}
- out.net().core_terms().clear(); // clear the list
+ out.net().m_core_terms.clear(); // clear the list
out.net().add_terminal(new_proxy->in());
out_cast.set_proxy(proxy);
proxy = new_proxy.get();
- m_nlstate.add_dev(new_proxy->name(), std::move(new_proxy));
+ netlist().register_dev(std::move(new_proxy));
}
return proxy;
}
@@ -460,7 +415,7 @@ devices::nld_base_proxy *setup_t::get_a_d_proxy(detail::core_terminal_t &inp)
{
nl_assert(inp.is_logic());
- auto &incast = dynamic_cast<logic_input_t &>(inp);
+ logic_input_t &incast = dynamic_cast<logic_input_t &>(inp);
devices::nld_base_proxy *proxy = incast.get_proxy();
if (proxy != nullptr)
@@ -469,7 +424,7 @@ devices::nld_base_proxy *setup_t::get_a_d_proxy(detail::core_terminal_t &inp)
{
log().debug("connect_terminal_input: connecting proxy\n");
pstring x = plib::pfmt("proxy_ad_{1}_{2}")(inp.name())(m_proxy_cnt);
- auto new_proxy = incast.logic_family()->create_a_d_proxy(m_nlstate, x, &incast);
+ auto new_proxy = incast.logic_family()->create_a_d_proxy(netlist(), x, &incast);
//auto new_proxy = plib::owned_ptr<devices::nld_a_to_d_proxy>::Create(netlist(), x, &incast);
incast.set_proxy(new_proxy.get());
m_proxy_cnt++;
@@ -480,17 +435,17 @@ devices::nld_base_proxy *setup_t::get_a_d_proxy(detail::core_terminal_t &inp)
if (inp.has_net())
{
- for (auto & p : inp.net().core_terms())
+ for (auto & p : inp.net().m_core_terms)
{
p->clear_net(); // de-link from all nets ...
if (!connect(ret->proxy_term(), *p))
log().fatal(MF_2_CONNECTING_1_TO_2,
ret->proxy_term().name(), (*p).name());
}
- inp.net().core_terms().clear(); // clear the list
+ inp.net().m_core_terms.clear(); // clear the list
}
ret->out().net().add_terminal(inp);
- m_nlstate.add_dev(new_proxy->name(), std::move(new_proxy));
+ netlist().register_dev(std::move(new_proxy));
return ret;
}
}
@@ -613,12 +568,11 @@ void setup_t::connect_terminals(detail::core_terminal_t &t1, detail::core_termin
{
log().debug("adding analog net ...\n");
// FIXME: Nets should have a unique name
- auto anet = pool().make_poolptr<analog_net_t>(m_nlstate,"net." + t1.name());
- auto anetp = anet.get();
- m_nlstate.register_net(std::move(anet));
- t1.set_net(anetp);
- anetp->add_terminal(t2);
- anetp->add_terminal(t1);
+ auto anet = plib::palloc<analog_net_t>(netlist(),"net." + t1.name());
+ netlist().m_nets.push_back(plib::owned_ptr<analog_net_t>(anet, true));
+ t1.set_net(anet);
+ anet->add_terminal(t2);
+ anet->add_terminal(t1);
}
}
@@ -626,7 +580,7 @@ static detail::core_terminal_t &resolve_proxy(detail::core_terminal_t &term)
{
if (term.is_logic())
{
- auto &out = dynamic_cast<logic_t &>(term);
+ logic_t &out = dynamic_cast<logic_t &>(term);
if (out.has_proxy())
return out.get_proxy()->proxy_term();
}
@@ -642,7 +596,7 @@ bool setup_t::connect_input_input(detail::core_terminal_t &t1, detail::core_term
ret = connect(t2, t1.net().railterminal());
if (!ret)
{
- for (auto & t : t1.net().core_terms())
+ for (auto & t : t1.net().m_core_terms)
{
if (t->is_type(detail::terminal_type::TERMINAL))
ret = connect(t2, *t);
@@ -657,7 +611,7 @@ bool setup_t::connect_input_input(detail::core_terminal_t &t1, detail::core_term
ret = connect(t1, t2.net().railterminal());
if (!ret)
{
- for (auto & t : t2.net().core_terms())
+ for (auto & t : t2.net().m_core_terms)
{
if (t->is_type(detail::terminal_type::TERMINAL))
ret = connect(t1, *t);
@@ -669,6 +623,8 @@ bool setup_t::connect_input_input(detail::core_terminal_t &t1, detail::core_term
return ret;
}
+
+
bool setup_t::connect(detail::core_terminal_t &t1_in, detail::core_terminal_t &t2_in)
{
log().debug("Connecting {1} to {2}\n", t1_in.name(), t2_in.name());
@@ -756,7 +712,18 @@ void setup_t::resolve_inputs()
// delete empty nets
- delete_empty_nets();
+ netlist().m_nets.erase(
+ std::remove_if(netlist().m_nets.begin(), netlist().m_nets.end(),
+ [](plib::owned_ptr<detail::net_t> &x)
+ {
+ if (x->num_cons() == 0)
+ {
+ x->netlist().log().verbose("Deleting net {1} ...", x->name());
+ return true;
+ }
+ else
+ return false;
+ }), netlist().m_nets.end());
pstring errstr("");
@@ -777,7 +744,7 @@ void setup_t::resolve_inputs()
}
-void setup_t::register_dynamic_log_devices()
+void setup_t::start_devices()
{
pstring env = plib::util::environment("NL_LOGS", "");
@@ -785,43 +752,41 @@ void setup_t::register_dynamic_log_devices()
{
log().debug("Creating dynamic logs ...");
std::vector<pstring> loglist(plib::psplit(env, ":"));
- for (const pstring &ll : loglist)
+ for (pstring ll : loglist)
{
pstring name = "log_" + ll;
- auto nc = factory().factory_by_name("LOG")->Create(m_nlstate, name);
+ auto nc = factory().factory_by_name("LOG")->Create(netlist(), name);
register_link(name + ".I", ll);
log().debug(" dynamic link {1}: <{2}>\n",ll, name);
- m_nlstate.add_dev(nc->name(), std::move(nc));
+ netlist().register_dev(std::move(nc));
}
}
}
-log_type &setup_t::log()
+plib::plog_base<netlist_t, NL_DEBUG> &setup_t::log()
{
- return m_nlstate.log();
+ return netlist().log();
}
-const log_type &setup_t::log() const
+const plib::plog_base<netlist_t, NL_DEBUG> &setup_t::log() const
{
- return m_nlstate.log();
+ return netlist().log();
}
// ----------------------------------------------------------------------------------------
-// Models
+// Model
// ----------------------------------------------------------------------------------------
-void models_t::register_model(pstring model_in)
+static pstring model_string(detail::model_map_t &map)
{
- auto pos = model_in.find(" ");
- if (pos == pstring::npos)
- throw nl_exception(MF_1_UNABLE_TO_PARSE_MODEL_1, model_in);
- pstring model = plib::ucase(plib::trim(plib::left(model_in, pos)));
- pstring def = plib::trim(model_in.substr(pos + 1));
- if (!m_models.insert({model, def}).second)
- throw nl_exception(MF_1_MODEL_ALREADY_EXISTS_1, model_in);
+ pstring ret = map["COREMODEL"] + "(";
+ for (auto & i : map)
+ ret = ret + i.first + "=" + i.second + " ";
+
+ return ret + ")";
}
-void models_t::model_parse(const pstring &model_in, model_map_t &map)
+void setup_t::model_parse(const pstring &model_in, detail::model_map_t &map)
{
pstring model = model_in;
std::size_t pos = 0;
@@ -832,15 +797,15 @@ void models_t::model_parse(const pstring &model_in, model_map_t &map)
pos = model.find("(");
if (pos != pstring::npos) break;
- key = plib::ucase(model);
+ key = model.ucase();
auto i = m_models.find(key);
if (i == m_models.end())
- throw nl_exception(MF_1_MODEL_NOT_FOUND, model);
+ log().fatal(MF_1_MODEL_NOT_FOUND, model);
model = i->second;
}
- pstring xmodel = plib::left(model, pos);
+ pstring xmodel = model.left(pos);
- if (xmodel == "_")
+ if (xmodel.equals("_"))
map["COREMODEL"] = key;
else
{
@@ -848,65 +813,46 @@ void models_t::model_parse(const pstring &model_in, model_map_t &map)
if (i != m_models.end())
model_parse(xmodel, map);
else
- throw nl_exception(MF_1_MODEL_NOT_FOUND, model_in);
+ log().fatal(MF_1_MODEL_NOT_FOUND, model_in);
}
- pstring remainder = plib::trim(model.substr(pos + 1));
- if (!plib::endsWith(remainder, ")"))
- throw nl_exception(MF_1_MODEL_ERROR_1, model);
+ pstring remainder = model.substr(pos + 1).trim();
+ if (!remainder.endsWith(")"))
+ log().fatal(MF_1_MODEL_ERROR_1, model);
// FIMXE: Not optimal
- remainder = plib::left(remainder, remainder.size() - 1);
+ remainder = remainder.left(remainder.length() - 1);
std::vector<pstring> pairs(plib::psplit(remainder," ", true));
for (pstring &pe : pairs)
{
auto pose = pe.find("=");
if (pose == pstring::npos)
- throw nl_exception(MF_1_MODEL_ERROR_ON_PAIR_1, model);
- map[plib::ucase(plib::left(pe, pose))] = pe.substr(pose + 1);
+ log().fatal(MF_1_MODEL_ERROR_ON_PAIR_1, model);
+ map[pe.left(pose).ucase()] = pe.substr(pose + 1);
}
}
-pstring models_t::model_string(model_map_t &map)
-{
- pstring ret = map["COREMODEL"] + "(";
- for (auto & i : map)
- ret = ret + i.first + "=" + i.second + " ";
-
- return ret + ")";
-}
-
-pstring models_t::model_value_str(pstring model, pstring entity)
+const pstring setup_t::model_value_str(detail::model_map_t &map, const pstring &entity)
{
- model_map_t &map = m_cache[model];
-
- if (map.size() == 0)
- model_parse(model , map);
-
pstring ret;
- if (entity != plib::ucase(entity))
- throw nl_exception(MF_2_MODEL_PARAMETERS_NOT_UPPERCASE_1_2, entity,
+ if (entity != entity.ucase())
+ log().fatal(MF_2_MODEL_PARAMETERS_NOT_UPPERCASE_1_2, entity,
model_string(map));
if (map.find(entity) == map.end())
- throw nl_exception(MF_2_ENTITY_1_NOT_FOUND_IN_MODEL_2, entity, model_string(map));
+ log().fatal(MF_2_ENTITY_1_NOT_FOUND_IN_MODEL_2, entity, model_string(map));
else
ret = map[entity];
return ret;
}
-nl_double models_t::model_value(pstring model, pstring entity)
+nl_double setup_t::model_value(detail::model_map_t &map, const pstring &entity)
{
- model_map_t &map = m_cache[model];
-
- if (map.size() == 0)
- model_parse(model , map);
+ pstring tmp = model_value_str(map, entity);
- pstring tmp = model_value_str(model, entity);
-
- nl_double factor = plib::constants<nl_double>::one();
- auto p = std::next(tmp.begin(), static_cast<pstring::difference_type>(tmp.size() - 1));
+ nl_double factor = NL_FCONST(1.0);
+ auto p = std::next(tmp.begin(), static_cast<pstring::difference_type>(tmp.length() - 1));
switch (*p)
{
case 'M': factor = 1e6; break;
@@ -919,69 +865,85 @@ nl_double models_t::model_value(pstring model, pstring entity)
case 'a': factor = 1e-18; break;
default:
if (*p < '0' || *p > '9')
- throw nl_exception(MF_1_UNKNOWN_NUMBER_FACTOR_IN_1, entity);
+ log().fatal(MF_1_UNKNOWN_NUMBER_FACTOR_IN_1, entity);
}
- if (factor != plib::constants<nl_double>::one())
- tmp = plib::left(tmp, tmp.size() - 1);
- // FIXME: check for errors
- //printf("%s %s %e %e\n", entity.c_str(), tmp.c_str(), plib::pstonum<nl_double>(tmp), factor);
- return plib::pstonum<nl_double>(tmp) * factor;
+ if (factor != NL_FCONST(1.0))
+ tmp = tmp.left(tmp.length() - 1);
+ return tmp.as_double() * factor;
}
class logic_family_std_proxy_t : public logic_family_desc_t
{
public:
- logic_family_std_proxy_t() = default;
- pool_owned_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_state_t &anetlist,
+ logic_family_std_proxy_t() { }
+ virtual plib::owned_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_t &anetlist,
const pstring &name, logic_output_t *proxied) const override;
- pool_owned_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const override;
+ virtual plib::owned_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *proxied) const override;
};
-pool_owned_ptr<devices::nld_base_d_to_a_proxy> logic_family_std_proxy_t::create_d_a_proxy(netlist_state_t &anetlist,
+plib::owned_ptr<devices::nld_base_d_to_a_proxy> logic_family_std_proxy_t::create_d_a_proxy(netlist_t &anetlist,
const pstring &name, logic_output_t *proxied) const
{
- return pool().make_poolptr<devices::nld_d_to_a_proxy>(anetlist, name, proxied);
+ return plib::owned_ptr<devices::nld_base_d_to_a_proxy>::Create<devices::nld_d_to_a_proxy>(anetlist, name, proxied);
}
-pool_owned_ptr<devices::nld_base_a_to_d_proxy> logic_family_std_proxy_t::create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const
+plib::owned_ptr<devices::nld_base_a_to_d_proxy> logic_family_std_proxy_t::create_a_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *proxied) const
{
- return pool().make_poolptr<devices::nld_a_to_d_proxy>(anetlist, name, proxied);
+ return plib::owned_ptr<devices::nld_base_a_to_d_proxy>::Create<devices::nld_a_to_d_proxy>(anetlist, name, proxied);
}
const logic_family_desc_t *setup_t::family_from_model(const pstring &model)
{
+ detail::model_map_t map;
+ model_parse(model, map);
- if (m_models.model_value_str(model, "TYPE") == "TTL")
+ if (model_value_str(map, "TYPE") == "TTL")
return family_TTL();
- if (m_models.model_value_str(model, "TYPE") == "CD4XXX")
+ if (model_value_str(map, "TYPE") == "CD4XXX")
return family_CD4XXX();
- for (auto & e : m_nlstate.m_family_cache)
+ for (auto & e : netlist().m_family_cache)
if (e.first == model)
return e.second.get();
- auto ret = plib::make_unique<logic_family_std_proxy_t>();
+ auto ret = plib::make_unique_base<logic_family_desc_t, logic_family_std_proxy_t>();
- ret->m_fixed_V = m_models.model_value(model, "FV");
- ret->m_low_thresh_PCNT = m_models.model_value(model, "IVL");
- ret->m_high_thresh_PCNT = m_models.model_value(model, "IVH");
- ret->m_low_VO = m_models.model_value(model, "OVL");
- ret->m_high_VO = m_models. model_value(model, "OVH");
- ret->m_R_low = m_models.model_value(model, "ORL");
- ret->m_R_high = m_models.model_value(model, "ORH");
+ ret->m_fixed_V = model_value(map, "FV");
+ ret->m_low_thresh_PCNT = model_value(map, "IVL");
+ ret->m_high_thresh_PCNT = model_value(map, "IVH");
+ ret->m_low_VO = model_value(map, "OVL");
+ ret->m_high_VO = model_value(map, "OVH");
+ ret->m_R_low = model_value(map, "ORL");
+ ret->m_R_high = model_value(map, "ORH");
auto retp = ret.get();
- m_nlstate.m_family_cache.emplace_back(model, std::move(ret));
+ netlist().m_family_cache.emplace_back(model, std::move(ret));
return retp;
}
+void setup_t::tt_factory_create(tt_desc &desc, const pstring &sourcefile)
+{
+ devices::tt_factory_create(*this, desc, sourcefile);
+}
+
+
// ----------------------------------------------------------------------------------------
// Sources
// ----------------------------------------------------------------------------------------
-plib::unique_ptr<plib::pistream> setup_t::get_data_stream(const pstring &name)
+void setup_t::include(const pstring &netlist_name)
+{
+ for (auto &source : m_sources)
+ {
+ if (source->parse(netlist_name))
+ return;
+ }
+ log().fatal(MF_1_NOT_FOUND_IN_SOURCE_COLLECTION, netlist_name);
+}
+
+std::unique_ptr<plib::pistream> setup_t::get_data_stream(const pstring &name)
{
for (auto &source : m_sources)
{
@@ -993,189 +955,77 @@ plib::unique_ptr<plib::pistream> setup_t::get_data_stream(const pstring &name)
}
}
log().warning(MW_1_DATA_1_NOT_FOUND, name);
- return plib::unique_ptr<plib::pistream>(nullptr);
+ return std::unique_ptr<plib::pistream>(nullptr);
}
-// ----------------------------------------------------------------------------------------
-// Device handling
-// ----------------------------------------------------------------------------------------
-
-void setup_t::delete_empty_nets()
+bool setup_t::parse_stream(plib::putf8_reader &istrm, const pstring &name)
{
- m_nlstate.nets().erase(
- std::remove_if(m_nlstate.nets().begin(), m_nlstate.nets().end(),
- [](pool_owned_ptr<detail::net_t> &x)
- {
- if (x->num_cons() == 0)
- {
- x->state().log().verbose("Deleting net {1} ...", x->name());
- x->state().run_state_manager().remove_save_items(x.get());
- return true;
- }
- else
- return false;
- }), m_nlstate.nets().end());
-}
+ plib::pomemstream ostrm;
+ plib::putf8_writer owrt(ostrm);
-// ----------------------------------------------------------------------------------------
-// Run preparation
-// ----------------------------------------------------------------------------------------
+ plib::ppreprocessor(&m_defines).process(istrm, owrt);
+ plib::pimemstream istrm2(ostrm);
+ plib::putf8_reader reader2(istrm2);
+ return parser_t(reader2, *this).parse(name);
+}
-void setup_t::prepare_to_run()
+void setup_t::register_define(pstring defstr)
{
- register_dynamic_log_devices();
-
- /* make sure the solver and parameters are started first! */
-
- for (auto & e : m_device_factory)
- {
- if ( factory().is_class<devices::NETLIB_NAME(solver)>(e.second)
- || factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second))
- {
- m_nlstate.add_dev(e.first, pool_owned_ptr<device_t>(e.second->Create(m_nlstate, e.first)));
- }
- }
-
- log().debug("Searching for solver and parameters ...\n");
-
- auto solver = m_nlstate.get_single_device<devices::NETLIB_NAME(solver)>("solver");
- m_netlist_params = m_nlstate.get_single_device<devices::NETLIB_NAME(netlistparams)>("parameter");
-
- /* create devices */
-
- log().debug("Creating devices ...\n");
- for (auto & e : m_device_factory)
- {
- if ( !factory().is_class<devices::NETLIB_NAME(solver)>(e.second)
- && !factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second))
- {
- auto dev = pool_owned_ptr<device_t>(e.second->Create(m_nlstate, e.first));
- m_nlstate.add_dev(dev->name(), std::move(dev));
- }
- }
-
- log().debug("Looking for unknown parameters ...\n");
- for (auto &p : m_param_values)
- {
- auto f = m_params.find(p.first);
- if (f == m_params.end())
- {
- if (plib::endsWith(p.first, pstring(".HINT_NO_DEACTIVATE")))
- {
- // FIXME: get device name, check for device
- }
- else
- log().info("Unknown parameter: {}", p.first);
- }
- }
-
- bool use_deactivate = m_netlist_params->m_use_deactivate() ? true : false;
-
- for (auto &d : m_nlstate.devices())
- {
- if (use_deactivate)
- {
- auto p = m_param_values.find(d.second->name() + ".HINT_NO_DEACTIVATE");
- if (p != m_param_values.end())
- {
- //FIXME: check for errors ...
- auto v = plib::pstonum<double>(p->second);
- if (std::abs(v - std::floor(v)) > 1e-6 )
- log().fatal(MF_1_HND_VAL_NOT_SUPPORTED, p->second);
- d.second->set_hint_deactivate(v == 0.0);
- }
- }
- else
- d.second->set_hint_deactivate(false);
- }
-
- /* resolve inputs */
- resolve_inputs();
-
- log().verbose("looking for two terms connected to rail nets ...");
- for (auto & t : m_nlstate.get_device_list<analog::NETLIB_NAME(twoterm)>())
- {
- if (t->m_N.net().isRailNet() && t->m_P.net().isRailNet())
- {
- log().warning(MW_3_REMOVE_DEVICE_1_CONNECTED_ONLY_TO_RAILS_2_3,
- t->name(), t->m_N.net().name(), t->m_P.net().name());
- t->m_N.net().remove_terminal(t->m_N);
- t->m_P.net().remove_terminal(t->m_P);
- m_nlstate.remove_dev(t);
- }
- }
-
- log().verbose("initialize solver ...\n");
-
- if (solver == nullptr)
- {
- for (auto &p : m_nlstate.nets())
- if (p->is_analog())
- log().fatal(MF_0_NO_SOLVER);
- }
+ auto p = defstr.find("=");
+ if (p != pstring::npos)
+ register_define(defstr.left(p), defstr.substr(p+1));
else
- solver->post_start();
-
- for (auto &n : m_nlstate.nets())
- for (auto & term : n->core_terms())
- {
- //core_device_t *dev = reinterpret_cast<core_device_t *>(term->m_delegate.object());
- core_device_t *dev = &term->device();
- dev->set_default_delegate(*term);
- }
-
+ register_define(defstr, "1");
}
// ----------------------------------------------------------------------------------------
// base sources
// ----------------------------------------------------------------------------------------
-bool source_t::parse(nlparse_t &setup, const pstring &name)
+bool source_t::parse(const pstring &name)
{
if (m_type != SOURCE)
return false;
else
{
- return setup.parse_stream(stream(name), name);
+ auto rstream = stream(name);
+ plib::putf8_reader reader(*rstream);
+ return m_setup.parse_stream(reader, name);
}
}
-plib::unique_ptr<plib::pistream> source_string_t::stream(const pstring &name)
+std::unique_ptr<plib::pistream> source_string_t::stream(const pstring &name)
{
- plib::unused_var(name);
- return plib::make_unique<plib::pimemstream>(m_str.c_str(), std::strlen(m_str.c_str()));
+ return plib::make_unique_base<plib::pistream, plib::pimemstream>(m_str.c_str(), m_str.mem_t_size());
}
-plib::unique_ptr<plib::pistream> source_mem_t::stream(const pstring &name)
+std::unique_ptr<plib::pistream> source_mem_t::stream(const pstring &name)
{
- plib::unused_var(name);
- return plib::make_unique<plib::pimemstream>(m_str.c_str(), std::strlen(m_str.c_str()));
+ return plib::make_unique_base<plib::pistream, plib::pimemstream>(m_str.c_str(), m_str.mem_t_size());
}
-plib::unique_ptr<plib::pistream> source_file_t::stream(const pstring &name)
+std::unique_ptr<plib::pistream> source_file_t::stream(const pstring &name)
{
- plib::unused_var(name);
- return plib::make_unique<plib::pifilestream>(m_filename);
+ return plib::make_unique_base<plib::pistream, plib::pifilestream>(m_filename);
}
-bool source_proc_t::parse(nlparse_t &setup, const pstring &name)
+bool source_proc_t::parse(const pstring &name)
{
if (name == m_setup_func_name)
{
- m_setup_func(setup);
+ m_setup_func(setup());
return true;
}
else
return false;
}
-plib::unique_ptr<plib::pistream> source_proc_t::stream(const pstring &name)
+std::unique_ptr<plib::pistream> source_proc_t::stream(const pstring &name)
{
- plib::unused_var(name);
- plib::unique_ptr<plib::pistream> p(nullptr);
+ std::unique_ptr<plib::pistream> p(nullptr);
return p;
}
-} // namespace netlist
+}
diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h
index ed0248a48e6..d0359928711 100644
--- a/src/lib/netlist/nl_setup.h
+++ b/src/lib/netlist/nl_setup.h
@@ -8,20 +8,18 @@
#ifndef NLSETUP_H_
#define NLSETUP_H_
-#include "plib/pparser.h"
-#include "plib/pstream.h"
#include "plib/pstring.h"
#include "plib/putil.h"
+#include "plib/pstream.h"
+#include "plib/pparser.h"
-#include "nl_config.h"
#include "nl_factory.h"
-#include "nltypes.h"
+#include "nl_config.h"
+#include "netlist_types.h"
-#include <memory>
#include <stack>
-#include <unordered_map>
#include <vector>
-
+#include <memory>
//============================================================
// MACROS / inline netlist definitions
@@ -29,46 +27,46 @@
#define NET_STR(x) # x
-#define NET_MODEL(model) \
+#define NET_MODEL(model) \
setup.register_model(model);
-#define ALIAS(alias, name) \
+#define ALIAS(alias, name) \
setup.register_alias(# alias, # name);
-#define DIPPINS(pin1, ...) \
+#define DIPPINS(pin1, ...) \
setup.register_dippins_arr( # pin1 ", " # __VA_ARGS__);
/* to be used to reference new library truthtable devices */
-#define NET_REGISTER_DEV(type, name) \
+#define NET_REGISTER_DEV(type, name) \
setup.register_dev(# type, # name);
-#define NET_CONNECT(name, input, output) \
+#define NET_CONNECT(name, input, output) \
setup.register_link(# name "." # input, # output);
-#define NET_C(term1, ...) \
+#define NET_C(term1, ...) \
setup.register_link_arr( # term1 ", " # __VA_ARGS__);
-#define PARAM(name, val) \
+#define PARAM(name, val) \
setup.register_param(# name, val);
#define HINT(name, val) \
setup.register_param(# name ".HINT_" # val, 1);
-#define NETDEV_PARAMI(name, param, val) \
+#define NETDEV_PARAMI(name, param, val) \
setup.register_param(# name "." # param, val);
#define NETLIST_NAME(name) netlist ## _ ## name
#define NETLIST_EXTERNAL(name) \
- void NETLIST_NAME(name)(netlist::nlparse_t &setup);
+ void NETLIST_NAME(name)(netlist::setup_t &setup);
#define NETLIST_START(name) \
-void NETLIST_NAME(name)(netlist::nlparse_t &setup) \
+void NETLIST_NAME(name)(netlist::setup_t &setup) \
{
#define NETLIST_END() }
#define LOCAL_SOURCE(name) \
- setup.register_source(plib::make_unique<netlist::source_proc_t>(# name, &NETLIST_NAME(name)));
+ setup.register_source(plib::make_unique_base<netlist::source_t, netlist::source_proc_t>(setup, # name, &NETLIST_NAME(name)));
#define LOCAL_LIB_ENTRY(name) \
LOCAL_SOURCE(name) \
@@ -82,7 +80,7 @@ void NETLIST_NAME(name)(netlist::nlparse_t &setup) \
NETLIST_NAME(model)(setup); \
setup.namespace_pop();
-#define OPTIMIZE_FRONTIER(attach, r_in, r_out) \
+#define OPTIMIZE_FRONTIER(attach, r_in, r_out) \
setup.register_frontier(# attach, r_in, r_out);
// -----------------------------------------------------------------------------
@@ -100,10 +98,10 @@ void NETLIST_NAME(name)(netlist::nlparse_t &setup) \
desc.family = "";
#define TT_HEAD(x) \
- desc.desc.emplace_back(x);
+ desc.desc.push_back(x);
#define TT_LINE(x) \
- desc.desc.emplace_back(x);
+ desc.desc.push_back(x);
#define TT_FAMILY(x) \
desc.family = x;
@@ -112,23 +110,22 @@ void NETLIST_NAME(name)(netlist::nlparse_t &setup) \
setup.tt_factory_create(desc, __FILE__); \
}
+
namespace netlist
{
namespace detail {
class core_terminal_t;
class net_t;
- } // namespace detail
+ }
namespace devices {
class nld_base_proxy;
- class nld_netlistparams;
- } // namespace devices
+ }
class core_device_t;
class param_t;
class setup_t;
- class netlist_state_t;
class netlist_t;
class logic_family_desc_t;
class terminal_t;
@@ -139,7 +136,6 @@ namespace netlist
struct tt_desc
{
- tt_desc() : ni(0), no(0) { }
pstring name;
pstring classname;
unsigned long ni;
@@ -172,222 +168,138 @@ namespace netlist
class source_t
{
public:
-
- friend class setup_t;
-
enum type_t
{
SOURCE,
DATA
};
- using list_t = std::vector<plib::unique_ptr<source_t>>;
+ using list_t = std::vector<std::unique_ptr<source_t>>;
- source_t(const type_t type = SOURCE)
- : m_type(type)
+ source_t(setup_t &setup, const type_t type = SOURCE)
+ : m_setup(setup), m_type(type)
{}
- COPYASSIGNMOVE(source_t, delete)
-
- virtual ~source_t() noexcept = default;
+ virtual ~source_t() { }
- virtual bool parse(nlparse_t &setup, const pstring &name);
+ virtual bool parse(const pstring &name);
+ virtual std::unique_ptr<plib::pistream> stream(const pstring &name) = 0;
+ setup_t &setup() { return m_setup; }
type_t type() const { return m_type; }
-
- protected:
- virtual plib::unique_ptr<plib::pistream> stream(const pstring &name) = 0;
-
private:
+ setup_t &m_setup;
const type_t m_type;
};
-
// ----------------------------------------------------------------------------------------
- // Collection of models
+ // setup_t
// ----------------------------------------------------------------------------------------
- class models_t
+
+ class setup_t : plib::nocopyassignmove
{
public:
- void register_model(pstring model_in);
- /* model / family related */
-
- pstring model_value_str(pstring model, pstring entity);
- double model_value(pstring model, pstring entity);
+ using link_t = std::pair<pstring, pstring>;
- pstring model_type(pstring model) { return model_value_str(model, "COREMODEL"); }
+ explicit setup_t(netlist_t &netlist);
+ ~setup_t();
- private:
- using model_map_t = std::unordered_map<pstring, pstring>;
+ netlist_t &netlist() { return m_netlist; }
+ const netlist_t &netlist() const { return m_netlist; }
- void model_parse(const pstring &model, model_map_t &map);
- pstring model_string(model_map_t &map);
+ pstring build_fqn(const pstring &obj_name) const;
- std::unordered_map<pstring, pstring> m_models;
- std::unordered_map<pstring, model_map_t> m_cache;
- };
+ void register_param(const pstring &name, param_t &param);
+ pstring get_initial_param_val(const pstring &name, const pstring &def);
+ double get_initial_param_val(const pstring &name, const double def);
+ int get_initial_param_val(const pstring &name, const int def);
- // ----------------------------------------------------------------------------------------
- // nlparse_t
- // ----------------------------------------------------------------------------------------
+ void register_term(detail::core_terminal_t &obj);
- class nlparse_t
- {
- public:
- using link_t = std::pair<pstring, pstring>;
+ void register_dev(const pstring &classname, const pstring &name);
- nlparse_t(setup_t &netlist, log_type &log);
+ void register_lib_entry(const pstring &name, const pstring &sourcefile);
- void register_model(const pstring &model_in) { m_models.register_model(model_in); }
+ void register_model(const pstring &model_in);
void register_alias(const pstring &alias, const pstring &out);
void register_dippins_arr(const pstring &terms);
- void register_dev(const pstring &classname, const pstring &name);
- void register_link(const pstring &sin, const pstring &sout);
+
+ void register_alias_nofqn(const pstring &alias, const pstring &out);
+
void register_link_arr(const pstring &terms);
+ void register_link_fqn(const pstring &sin, const pstring &sout);
+ void register_link(const pstring &sin, const pstring &sout);
+
void register_param(const pstring &param, const pstring &value);
void register_param(const pstring &param, const double value);
- void register_lib_entry(const pstring &name, const pstring &sourcefile);
+
void register_frontier(const pstring &attach, const double r_IN, const double r_OUT);
- /* register a source */
- void register_source(plib::unique_ptr<source_t> &&src)
- {
- m_sources.push_back(std::move(src));
- }
+ void remove_connections(const pstring &attach);
- void tt_factory_create(tt_desc &desc, const pstring &sourcefile);
+ bool connect(detail::core_terminal_t &t1, detail::core_terminal_t &t2);
+
+ bool device_exists(const pstring &name) const;
+
+ param_t *find_param(const pstring &param_in, bool required = true) const;
+
+ void start_devices();
+ void resolve_inputs();
/* handle namespace */
void namespace_push(const pstring &aname);
void namespace_pop();
- /* include other files */
+ /* parse a source */
void include(const pstring &netlist_name);
- pstring build_fqn(const pstring &obj_name) const;
- void register_alias_nofqn(const pstring &alias, const pstring &out);
-
- /* also called from devices for latebinding connected terminals */
- void register_link_fqn(const pstring &sin, const pstring &sout);
+ std::unique_ptr<plib::pistream> get_data_stream(const pstring &name);
- /* used from netlist.cpp (mame) */
- bool device_exists(const pstring &name) const;
+ bool parse_stream(plib::putf8_reader &istrm, const pstring &name);
- /* FIXME: used by source_t - need a different approach at some time */
- bool parse_stream(plib::unique_ptr<plib::pistream> &&istrm, const pstring &name);
+ /* register a source */
- void add_define(const pstring &def, const pstring &val)
+ void register_source(std::unique_ptr<source_t> &&src)
{
- m_defines.insert({ def, plib::ppreprocessor::define_t(def, val)});
+ m_sources.push_back(std::move(src));
}
- void add_define(const pstring &defstr);
+ 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; }
const factory::list_t &factory() const { return m_factory; }
- log_type &log() { return m_log; }
- const log_type &log() const { return m_log; }
-
- /* FIXME: sources may need access to the netlist parent type
- * since they may be created in a context in which they don't
- * have access to their environment.
- * Example is the MAME memregion source.
- * We thus need a better approach to creating netlists in a context
- * other than static procedures.
- */
- setup_t &setup() { return m_setup; }
- const setup_t &setup() const { return m_setup; }
-
- models_t &models() { return m_models; }
- const models_t &models() const { return m_models; }
-
- protected:
- models_t m_models;
- std::stack<pstring> m_namespace_stack;
- std::unordered_map<pstring, pstring> m_alias;
- std::vector<link_t> m_links;
- std::unordered_map<pstring, pstring> m_param_values;
-
- source_t::list_t m_sources;
-
- factory::list_t m_factory;
-
- /* need to preserve order of device creation ... */
- std::vector<std::pair<pstring, factory::element_t *>> m_device_factory;
-
-
- private:
- plib::ppreprocessor::defines_map_type m_defines;
-
- setup_t &m_setup;
- log_type &m_log;
- unsigned m_frontier_cnt;
- };
-
- // ----------------------------------------------------------------------------------------
- // setup_t
- // ----------------------------------------------------------------------------------------
-
- class setup_t : public nlparse_t
- {
- public:
-
- explicit setup_t(netlist_state_t &nlstate);
- ~setup_t() noexcept;
-
- COPYASSIGNMOVE(setup_t, delete)
-
- netlist_state_t &nlstate() { return m_nlstate; }
- const netlist_state_t &nlstate() const { return m_nlstate; }
-
- void register_param_t(const pstring &name, param_t &param);
-
- pstring get_initial_param_val(const pstring &name, const pstring &def) const;
-
- void register_term(detail::core_terminal_t &obj);
-
- void remove_connections(const pstring &attach);
+ /* model / family related */
- bool connect(detail::core_terminal_t &t1, detail::core_terminal_t &t2);
+ const pstring model_value_str(detail::model_map_t &map, const pstring &entity);
+ double model_value(detail::model_map_t &map, const pstring &entity);
- param_t *find_param(const pstring &param_in, bool required = true) const;
+ void model_parse(const pstring &model, detail::model_map_t &map);
- /* get family */
const logic_family_desc_t *family_from_model(const pstring &model);
- void register_dynamic_log_devices();
- void resolve_inputs();
-
- plib::unique_ptr<plib::pistream> get_data_stream(const pstring &name);
-
- factory::list_t &factory() { return m_factory; }
- const factory::list_t &factory() const { return m_factory; }
+ void tt_factory_create(tt_desc &desc, const pstring &sourcefile);
/* helper - also used by nltool */
const pstring resolve_alias(const pstring &name) const;
- /* needed by nltool */
- std::vector<pstring> get_terminals_for_device_name(const pstring &devname);
+ plib::plog_base<netlist_t, NL_DEBUG> &log();
+ const plib::plog_base<netlist_t, NL_DEBUG> &log() const;
+
+ std::vector<std::pair<pstring, factory::element_t *>> m_device_factory;
- log_type &log();
- const log_type &log() const;
+ std::unordered_map<pstring, pstring> m_alias;
+ std::unordered_map<pstring, pstring> m_param_values;
+ std::unordered_map<pstring, detail::core_terminal_t *> m_terminals;
/* needed by proxy */
detail::core_terminal_t *find_terminal(const pstring &outname_in, const detail::terminal_type atype, bool required = true);
- /* core net handling */
-
- void delete_empty_nets();
-
- /* run preparation */
-
- void prepare_to_run();
-
private:
detail::core_terminal_t *find_terminal(const pstring &outname_in, bool required = true);
@@ -406,30 +318,35 @@ namespace netlist
devices::nld_base_proxy *get_d_a_proxy(detail::core_terminal_t &out);
devices::nld_base_proxy *get_a_d_proxy(detail::core_terminal_t &inp);
- std::unordered_map<pstring, detail::core_terminal_t *> m_terminals;
-
- netlist_state_t &m_nlstate;
- devices::nld_netlistparams *m_netlist_params;
+ netlist_t &m_netlist;
std::unordered_map<pstring, param_ref_t> m_params;
+ std::vector<link_t> m_links;
+ factory::list_t m_factory;
+ std::unordered_map<pstring, pstring> m_models;
+
+ std::stack<pstring> m_namespace_stack;
+ source_t::list_t m_sources;
+ std::vector<plib::ppreprocessor::define_t> m_defines;
unsigned m_proxy_cnt;
- };
+ unsigned m_frontier_cnt;
+};
// ----------------------------------------------------------------------------------------
// base sources
// ----------------------------------------------------------------------------------------
+
class source_string_t : public source_t
{
public:
- source_string_t(const pstring &source)
- : source_t(), m_str(source)
+ source_string_t(setup_t &setup, const pstring &source)
+ : source_t(setup), m_str(source)
{
}
- protected:
- plib::unique_ptr<plib::pistream> stream(const pstring &name) override;
+ virtual std::unique_ptr<plib::pistream> stream(const pstring &name) override;
private:
pstring m_str;
@@ -439,13 +356,12 @@ namespace netlist
{
public:
- source_file_t(const pstring &filename)
- : source_t(), m_filename(filename)
+ source_file_t(setup_t &setup, const pstring &filename)
+ : source_t(setup), m_filename(filename)
{
}
- protected:
- plib::unique_ptr<plib::pistream> stream(const pstring &name) override;
+ virtual std::unique_ptr<plib::pistream> stream(const pstring &name) override;
private:
pstring m_filename;
@@ -454,13 +370,12 @@ namespace netlist
class source_mem_t : public source_t
{
public:
- source_mem_t(const char *mem)
- : source_t(), m_str(mem)
+ source_mem_t(setup_t &setup, const char *mem)
+ : source_t(setup), m_str(mem, pstring::UTF8)
{
}
- protected:
- plib::unique_ptr<plib::pistream> stream(const pstring &name) override;
+ virtual std::unique_ptr<plib::pistream> stream(const pstring &name) override;
private:
pstring m_str;
@@ -469,28 +384,22 @@ namespace netlist
class source_proc_t : public source_t
{
public:
- source_proc_t(const pstring &name, void (*setup_func)(nlparse_t &))
- : source_t(),
+ source_proc_t(setup_t &setup, pstring name, void (*setup_func)(setup_t &))
+ : source_t(setup),
m_setup_func(setup_func),
m_setup_func_name(name)
{
}
- bool parse(nlparse_t &setup, const pstring &name) override;
-
- protected:
- plib::unique_ptr<plib::pistream> stream(const pstring &name) override;
+ virtual bool parse(const pstring &name) override;
+ virtual std::unique_ptr<plib::pistream> stream(const pstring &name) override;
private:
- void (*m_setup_func)(nlparse_t &);
+ void (*m_setup_func)(setup_t &);
pstring m_setup_func_name;
};
- // -----------------------------------------------------------------------------
- // inline implementations
- // -----------------------------------------------------------------------------
-
-} // namespace netlist
+}
#endif /* NLSETUP_H_ */
diff --git a/src/lib/netlist/nl_time.h b/src/lib/netlist/nl_time.h
new file mode 100644
index 00000000000..7c81f890e07
--- /dev/null
+++ b/src/lib/netlist/nl_time.h
@@ -0,0 +1,145 @@
+// license:GPL-2.0+
+// copyright-holders:Couriersud
+/*
+ * nltime.h
+ */
+
+#ifndef NLTIME_H_
+#define NLTIME_H_
+
+#include "nl_config.h"
+#include "plib/ptypes.h"
+#include "plib/pstate.h"
+
+#include <cstdint>
+
+//============================================================
+// MACROS
+//============================================================
+
+#define NLTIME_FROM_NS(t) netlist_time::from_nsec(t)
+#define NLTIME_FROM_US(t) netlist_time::from_usec(t)
+#define NLTIME_FROM_MS(t) netlist_time::from_msec(t)
+#define NLTIME_IMMEDIATE netlist_time::from_nsec(1)
+
+// ----------------------------------------------------------------------------------------
+// netlist_time
+// ----------------------------------------------------------------------------------------
+
+namespace netlist
+{
+ template <typename TYPE, TYPE RES>
+ struct ptime final
+ {
+ public:
+
+ using internal_type = TYPE;
+ using mult_type = std::uint64_t;
+
+ constexpr ptime() noexcept : m_time(0) {}
+
+ constexpr ptime(const ptime &rhs) noexcept = default;
+ constexpr ptime(ptime &&rhs) noexcept = default;
+ C14CONSTEXPR ptime &operator=(const ptime &rhs) noexcept = default;
+ C14CONSTEXPR ptime &operator=(ptime &&rhs) noexcept = default;
+
+ constexpr explicit ptime(const double t) = delete;
+ //: m_time((internal_type) ( t * (double) resolution)) { }
+ constexpr explicit ptime(const internal_type &nom, const internal_type &den) noexcept
+ : m_time(nom * (RES / den)) { }
+
+ C14CONSTEXPR ptime &operator+=(const ptime &rhs) noexcept { m_time += rhs.m_time; return *this; }
+ C14CONSTEXPR ptime &operator-=(const ptime &rhs) noexcept { m_time -= rhs.m_time; return *this; }
+ C14CONSTEXPR ptime &operator*=(const mult_type &factor) noexcept { m_time *= static_cast<internal_type>(factor); return *this; }
+
+ friend C14CONSTEXPR ptime operator-(ptime lhs, const ptime &rhs) noexcept
+ {
+ return lhs -= rhs;
+ }
+
+ friend C14CONSTEXPR ptime operator+(ptime lhs, const ptime &rhs) noexcept
+ {
+ return lhs += rhs;
+ }
+
+ friend C14CONSTEXPR ptime operator*(ptime lhs, const mult_type &factor) noexcept
+ {
+ return lhs *= factor;
+ }
+
+ friend constexpr mult_type operator/(const ptime &lhs, const ptime &rhs) noexcept
+ {
+ return static_cast<mult_type>(lhs.m_time / rhs.m_time);
+ }
+
+ friend constexpr bool operator<(const ptime &lhs, const ptime &rhs) noexcept
+ {
+ return (lhs.m_time < rhs.m_time);
+ }
+
+ friend constexpr bool operator>(const ptime &lhs, const ptime &rhs) noexcept
+ {
+ return (rhs < lhs);
+ }
+
+ friend constexpr bool operator<=(const ptime &lhs, const ptime &rhs) noexcept
+ {
+ return !(lhs > rhs);
+ }
+
+ friend constexpr bool operator>=(const ptime &lhs, const ptime &rhs) noexcept
+ {
+ return !(lhs < rhs);
+ }
+
+ friend constexpr bool operator==(const ptime &lhs, const ptime &rhs) noexcept
+ {
+ return lhs.m_time == rhs.m_time;
+ }
+
+ friend constexpr bool operator!=(const ptime &lhs, const ptime &rhs) noexcept
+ {
+ return !(lhs == rhs);
+ }
+
+ constexpr internal_type as_raw() const noexcept { return m_time; }
+ constexpr double as_double() const noexcept
+ {
+ return static_cast<double>(m_time) / static_cast<double>(RES);
+ }
+
+ // for save states ....
+ C14CONSTEXPR internal_type *get_internaltype_ptr() noexcept { return &m_time; }
+
+ static constexpr ptime from_nsec(const internal_type &ns) noexcept { return ptime(ns, UINT64_C(1000000000)); }
+ static constexpr ptime from_usec(const internal_type &us) noexcept { return ptime(us, UINT64_C(1000000)); }
+ static constexpr ptime from_msec(const internal_type &ms) noexcept { return ptime(ms, UINT64_C(1000)); }
+ static constexpr ptime from_hz(const internal_type &hz) noexcept { return ptime(1 , hz); }
+ static constexpr ptime from_raw(const internal_type &raw) noexcept { return ptime(raw); }
+ static constexpr ptime from_double(const double t) noexcept { return ptime(static_cast<internal_type>( t * static_cast<double>(RES)), RES); }
+
+ static constexpr ptime zero() noexcept { return ptime(0, RES); }
+ static constexpr ptime quantum() noexcept { return ptime(1, RES); }
+ static constexpr ptime never() noexcept { return ptime(plib::numeric_limits<internal_type>::max(), RES); }
+ static constexpr internal_type resolution() noexcept { return RES; }
+ private:
+ constexpr explicit ptime(const internal_type &time) : m_time(time) {}
+ constexpr explicit ptime(internal_type &&time) : m_time(time) {}
+ internal_type m_time;
+ };
+
+#if (PHAS_INT128)
+ using netlist_time = ptime<UINT128, NETLIST_INTERNAL_RES>;
+#else
+ using netlist_time = ptime<std::uint64_t, NETLIST_INTERNAL_RES>;
+#endif
+}
+
+namespace plib {
+template<> inline void state_manager_t::save_item(const void *owner, netlist::netlist_time &nlt, const pstring &stname)
+{
+ save_state_ptr(owner, stname, datatype_t(sizeof(netlist::netlist_time::internal_type), true, false), 1, nlt.get_internaltype_ptr());
+}
+}
+
+#endif /* NLTIME_H_ */
diff --git a/src/lib/netlist/nltypes.h b/src/lib/netlist/nltypes.h
deleted file mode 100644
index 7d7582774b1..00000000000
--- a/src/lib/netlist/nltypes.h
+++ /dev/null
@@ -1,147 +0,0 @@
-// license:GPL-2.0+
-// copyright-holders:Couriersud
-/*!
- *
- * \file nltypes.h
- *
- */
-
-/* \note never change the name to nl_types.h. This creates a conflict
- * with nl_types.h file provided by libc++ (clang, macosx)
- */
-
-#ifndef NLTYPES_H_
-#define NLTYPES_H_
-
-#include "nl_config.h"
-#include "plib/pchrono.h"
-#include "plib/pfmtlog.h"
-#include "plib/pmempool.h"
-#include "plib/pstate.h"
-#include "plib/pstring.h"
-#include "plib/ptime.h"
-#include "plib/putil.h"
-
-#include <cstdint>
-#include <unordered_map>
-
-namespace netlist
-{
- /*! @brief plib::constants struct specialized for nl_double
- *
- * This may be any of bool, uint8_t, uint16_t, uin32_t and uint64_t.
- * The choice has little to no impact on performance.
- */
- using constants = plib::constants<nl_double>;
-
- /*! @brief netlist_sig_t is the type used for logic signals.
- *
- * This may be any of bool, uint8_t, uint16_t, uin32_t and uint64_t.
- * The choice has little to no impact on performance.
- */
- using netlist_sig_t = std::uint32_t;
-
- /* FIXME: belongs into nl_base.h to nlstate */
- /**
- * @brief Interface definition for netlist callbacks into calling code
- *
- * A class inheriting from netlist_callbacks_t has to be passed to the netlist_t
- * constructor. Netlist does processing during construction and thus needs
- * the object passed completely constructed.
- *
- */
- class callbacks_t
- {
- public:
-
- callbacks_t() = default;
- /* what is done before this is passed as a unique_ptr to netlist
- * we should not limit.
- */
- virtual ~callbacks_t() = default;
- COPYASSIGNMOVE(callbacks_t, default)
-
- /* logging callback */
- virtual void vlog(const plib::plog_level &l, const pstring &ls) const = 0;
-
- };
-
- using log_type = plib::plog_base<callbacks_t, NL_DEBUG>;
-
-
- //============================================================
- // Performance tracking
- //============================================================
-
- template<bool enabled_>
- using nperftime_t = plib::chrono::timer<plib::chrono::exact_ticks, enabled_>;
-
- template<bool enabled_>
- using nperfcount_t = plib::chrono::counter<enabled_>;
-
- //============================================================
- // Types needed by various includes
- //============================================================
-
- /*! The memory pool for netlist objects
- *
- * \note This is not the right location yet.
- *
- */
-
-#if (USE_MEMPOOL)
- using nlmempool = plib::mempool;
-#else
- using nlmempool = plib::aligned_arena;
-#endif
-
- /*! Owned pointer type for pooled allocations.
- *
- */
- template <typename T>
- using pool_owned_ptr = nlmempool::owned_pool_ptr<T>;
-
- inline nlmempool &pool()
- {
- static nlmempool static_pool;
- return static_pool;
- }
-
- namespace detail {
-
- /*! Enum specifying the type of object */
- enum terminal_type {
- TERMINAL = 0, /*!< object is an analog terminal */
- INPUT = 1, /*!< object is an input */
- OUTPUT = 2, /*!< object is an output */
- };
-
- } // namespace detail
-
-#if (PHAS_INT128)
- using netlist_time = ptime<INT128, NETLIST_INTERNAL_RES>;
-#else
- using netlist_time = plib::ptime<std::int64_t, NETLIST_INTERNAL_RES>;
- static_assert(noexcept(netlist_time::from_nsec(1)) == true, "Not evaluated as constexpr");
-#endif
-
- //============================================================
- // MACROS
- //============================================================
-
- template <typename T> inline constexpr const netlist_time NLTIME_FROM_NS(T &&t) noexcept { return netlist_time::from_nsec(t); }
- template <typename T> inline constexpr const netlist_time NLTIME_FROM_US(T &&t) noexcept { return netlist_time::from_usec(t); }
- template <typename T> inline constexpr const netlist_time NLTIME_FROM_MS(T &&t) noexcept { return netlist_time::from_msec(t); }
-
-} // namespace netlist
-
-namespace plib {
-
- template<>
- inline void state_manager_t::save_item(const void *owner, netlist::netlist_time &nlt, const pstring &stname)
- {
- save_state_ptr(owner, stname, datatype_t(sizeof(netlist::netlist_time::internal_type), true, false), 1, nlt.get_internaltype_ptr());
- }
-} // namespace plib
-
-#endif /* NLTYPES_H_ */
diff --git a/src/lib/netlist/plib/gmres.h b/src/lib/netlist/plib/gmres.h
deleted file mode 100644
index 2c357e97624..00000000000
--- a/src/lib/netlist/plib/gmres.h
+++ /dev/null
@@ -1,450 +0,0 @@
-// license:GPL-2.0+
-// copyright-holders:Couriersud
-/*
- * gmres.h
- *
- */
-
-#ifndef PLIB_GMRES_H_
-#define PLIB_GMRES_H_
-
-#include "mat_cr.h"
-#include "parray.h"
-#include "pconfig.h"
-#include "vector_ops.h"
-
-#include <algorithm>
-#include <cmath>
-
-
-namespace plib
-{
-
- template <typename FT, int SIZE>
- struct mat_precondition_ILU
- {
- using mat_type = plib::matrix_compressed_rows_t<FT, SIZE>;
-
- mat_precondition_ILU(std::size_t size, int ilu_scale = 4
- , std::size_t bw = plib::matrix_compressed_rows_t<FT, SIZE>::FILL_INFINITY)
- : m_mat(static_cast<typename mat_type::index_type>(size))
- , m_LU(static_cast<typename mat_type::index_type>(size))
- , m_use_iLU_preconditioning(ilu_scale >= 0)
- , m_ILU_scale(static_cast<std::size_t>(ilu_scale))
- , m_band_width(bw)
- {
- }
-
- template <typename M>
- void build(M &fill)
- {
- m_mat.build_from_fill_mat(fill, 0);
- if (m_use_iLU_preconditioning)
- {
- m_LU.gaussian_extend_fill_mat(fill);
- m_LU.build_from_fill_mat(fill, m_ILU_scale, m_band_width); // ILU(2)
- //m_LU.build_from_fill_mat(fill, 9999, 20); // Band matrix width 20
- }
- }
-
-
- template<typename R, typename V>
- void calc_rhs(R &rhs, const V &v)
- {
- m_mat.mult_vec(rhs, v);
- }
-
- void precondition()
- {
- if (m_use_iLU_preconditioning)
- {
- if (m_ILU_scale < 1)
- m_LU.raw_copy_from(m_mat);
- else
- m_LU.reduction_copy_from(m_mat);
- m_LU.incomplete_LU_factorization();
- }
- }
-
- template<typename V>
- void solve_LU_inplace(V &v)
- {
- if (m_use_iLU_preconditioning)
- {
- m_LU.solveLUx(v);
- }
- }
-
- PALIGNAS_VECTOROPT()
- mat_type m_mat;
- PALIGNAS_VECTOROPT()
- mat_type m_LU;
- bool m_use_iLU_preconditioning;
- std::size_t m_ILU_scale;
- std::size_t m_band_width;
- };
-
- template <typename FT, int SIZE>
- struct mat_precondition_diag
- {
- mat_precondition_diag(std::size_t size)
- : m_mat(size)
- , m_diag(size)
- , m_use_iLU_preconditioning(true)
- {
- }
-
- template <typename M>
- void build(M &fill)
- {
- m_mat.build_from_fill_mat(fill, 0);
- }
-
- template<typename R, typename V>
- void calc_rhs(R &rhs, const V &v)
- {
- m_mat.mult_vec(rhs, v);
- }
-
- void precondition()
- {
- if (m_use_iLU_preconditioning)
- {
- for (std::size_t i = 0; i< m_diag.size(); i++)
- {
- m_diag[i] = 1.0 / m_mat.A[m_mat.diag[i]];
- }
- }
- }
-
- template<typename V>
- void solve_LU_inplace(V &v)
- {
- if (m_use_iLU_preconditioning)
- {
- for (std::size_t i = 0; i< m_diag.size(); i++)
- v[i] = v[i] * m_diag[i];
- }
- }
-
- plib::matrix_compressed_rows_t<FT, SIZE> m_mat;
- plib::parray<FT, SIZE> m_diag;
- bool m_use_iLU_preconditioning;
- };
-
- /* FIXME: hardcoding RESTART to 20 becomes an issue on very large
- * systems.
- */
- template <typename FT, int SIZE, int RESTART = 20>
- struct gmres_t
- {
- public:
-
- using float_type = FT;
- // FIXME: dirty hack to make this compile
- static constexpr const std::size_t storage_N = plib::sizeabs<FT, SIZE>::ABS();
-
- gmres_t(std::size_t size)
- : residual(size)
- , Ax(size)
- , m_size(size)
- , m_use_more_precise_stop_condition(false)
- {
- }
-
- void givens_mult( const FT c, const FT s, FT & g0, FT & g1 )
- {
- const FT g0_last(g0);
-
- g0 = c * g0 - s * g1;
- g1 = s * g0_last + c * g1;
- }
-
- std::size_t size() const { return (SIZE<=0) ? m_size : static_cast<std::size_t>(SIZE); }
-
- template <typename OPS, typename VT, typename VRHS>
- std::size_t solve(OPS &ops, VT &x, const VRHS & rhs, const std::size_t itr_max, float_type accuracy)
- {
- /*-------------------------------------------------------------------------
- * The code below was inspired by code published by John Burkardt under
- * the LPGL here:
- *
- * http://people.sc.fsu.edu/~jburkardt/cpp_src/mgmres/mgmres.html
- *
- * The code below was completely written from scratch based on the pseudo code
- * found here:
- *
- * http://de.wikipedia.org/wiki/GMRES-Verfahren
- *
- * The Algorithm itself is described in
- *
- * Yousef Saad,
- * Iterative Methods for Sparse Linear Systems,
- * Second Edition,
- * SIAM, 20003,
- * ISBN: 0898715342,
- * LC: QA188.S17.
- *
- *------------------------------------------------------------------------*/
-
- std::size_t itr_used = 0;
- double rho_delta = 0.0;
-
- const std::size_t n = size();
-
- ops.precondition();
-
- if (m_use_more_precise_stop_condition)
- {
- /* derive residual for a given delta x
- *
- * LU y = A dx
- *
- * ==> rho / accuracy = sqrt(y * y)
- *
- * This approach will approximate the iterative stop condition
- * based |xnew - xold| pretty precisely. But it is slow, or expressed
- * differently: The invest doesn't pay off.
- */
-
- vec_set_scalar(n, residual, accuracy);
- ops.calc_rhs(Ax, residual);
-
- ops.solve_LU_inplace(Ax);
-
- const float_type rho_to_accuracy = std::sqrt(vec_mult2<FT>(n, Ax)) / accuracy;
-
- rho_delta = accuracy * rho_to_accuracy;
- }
- else
- rho_delta = accuracy * std::sqrt(static_cast<FT>(n));
-
- /*
- * Using
- *
- * vec_set(n, x, rhs);
- * ops.solve_LU_inplace(x);
- *
- * to get a starting point for x degrades convergence speed compared
- * to using the last solution for x.
- *
- * LU x = b; solve for x;
- *
- */
-
- while (itr_used < itr_max)
- {
- std::size_t last_k = RESTART;
- float_type rho;
-
- ops.calc_rhs(Ax, x);
-
- vec_sub(n, residual, rhs, Ax);
-
- ops.solve_LU_inplace(residual);
-
- rho = std::sqrt(vec_mult2<FT>(n, residual));
-
- if (rho < rho_delta)
- return itr_used + 1;
-
- /* FIXME: The "+" is necessary to avoid link issues
- * on some systems / compiler versions. Issue reported by
- * AJR, no details known yet.
- */
- vec_set_scalar(RESTART+1, m_g, +constants<FT>::zero());
- m_g[0] = rho;
-
- //for (std::size_t i = 0; i < mr + 1; i++)
- // vec_set_scalar(mr, m_ht[i], NL_FCONST(0.0));
-
- vec_mult_scalar(n, m_v[0], residual, constants<FT>::one() / rho);
-
- for (std::size_t k = 0; k < RESTART; k++)
- {
- const std::size_t kp1 = k + 1;
-
- ops.calc_rhs(m_v[kp1], m_v[k]);
- ops.solve_LU_inplace(m_v[kp1]);
-
- for (std::size_t j = 0; j <= k; j++)
- {
- m_ht[j][k] = vec_mult<FT>(n, m_v[kp1], m_v[j]);
- vec_add_mult_scalar(n, m_v[kp1], m_v[j], -m_ht[j][k]);
- }
- m_ht[kp1][k] = std::sqrt(vec_mult2<FT>(n, m_v[kp1]));
-
- if (m_ht[kp1][k] != 0.0)
- vec_scale(n, m_v[kp1], constants<FT>::one() / m_ht[kp1][k]);
-
- for (std::size_t j = 0; j < k; j++)
- givens_mult(m_c[j], m_s[j], m_ht[j][k], m_ht[j+1][k]);
-
- const float_type mu = 1.0 / std::hypot(m_ht[k][k], m_ht[kp1][k]);
-
- m_c[k] = m_ht[k][k] * mu;
- m_s[k] = -m_ht[kp1][k] * mu;
- m_ht[k][k] = m_c[k] * m_ht[k][k] - m_s[k] * m_ht[kp1][k];
- m_ht[kp1][k] = 0.0;
-
- givens_mult(m_c[k], m_s[k], m_g[k], m_g[kp1]);
-
- rho = std::abs(m_g[kp1]);
-
- itr_used = itr_used + 1;
-
- if (rho <= rho_delta)
- {
- last_k = k;
- break;
- }
- }
-
- if (last_k >= RESTART)
- /* didn't converge within accuracy */
- last_k = RESTART - 1;
-
- /* Solve the system H * y = g */
- /* x += m_v[j] * m_y[j] */
- for (std::size_t i = last_k + 1; i-- > 0;)
- {
- double tmp = m_g[i];
- for (std::size_t j = i + 1; j <= last_k; j++)
- tmp -= m_ht[i][j] * m_y[j];
- m_y[i] = tmp / m_ht[i][i];
- }
-
- for (std::size_t i = 0; i <= last_k; i++)
- vec_add_mult_scalar(n, x, m_v[i], m_y[i]);
-
- if (rho <= rho_delta)
- break;
-
- }
- return itr_used;
- }
-
- private:
-
- //typedef typename plib::mat_cr_t<FT, SIZE>::index_type mattype;
-
- plib::parray<float_type, SIZE> residual;
- plib::parray<float_type, SIZE> Ax;
-
- plib::parray<float_type, RESTART + 1> m_c; /* mr + 1 */
- plib::parray<float_type, RESTART + 1> m_g; /* mr + 1 */
- plib::parray<plib::parray<float_type, RESTART>, RESTART + 1> m_ht; /* (mr + 1), mr */
- plib::parray<float_type, RESTART + 1> m_s; /* mr + 1 */
- plib::parray<float_type, RESTART + 1> m_y; /* mr + 1 */
-
- //plib::parray<float_type, SIZE> m_v[RESTART + 1]; /* mr + 1, n */
- plib::parray<plib::parray<float_type, storage_N>, RESTART + 1> m_v; /* mr + 1, n */
-
- std::size_t m_size;
-
- bool m_use_more_precise_stop_condition;
-
-
- };
-
-
-#if 0
- /* Example of a Chebyshev iteration solver. This one doesn't work yet,
- * it needs to be extended for non-symmetric matrix operation and
- * depends on spectral radius estimates - which we don't have.
- *
- * Left here as another example.
- */
-
- template <typename FT, int SIZE>
- struct ch_t
- {
- public:
-
- typedef FT float_type;
- // FIXME: dirty hack to make this compile
- static constexpr const std::size_t storage_N = plib::sizeabs<FT, SIZE>::ABS();
-
- // Maximum iterations before a restart ...
- static constexpr const std::size_t restart_N = (storage_N > 0 ? 20 : 0);
-
- ch_t(std::size_t size)
- : residual(size)
- , Ax(size)
- , m_size(size)
- {
- }
-
- std::size_t size() const { return (SIZE<=0) ? m_size : static_cast<std::size_t>(SIZE); }
-
- template <typename OPS, typename VT, typename VRHS>
- std::size_t solve(OPS &ops, VT &x0, const VRHS & rhs, const std::size_t iter_max, float_type accuracy)
- {
- /*-------------------------------------------------------------------------
- *
- *
- *------------------------------------------------------------------------*/
-
- ops.precondition();
-
- const FT lmax = 20.0;
- const FT lmin = 0.0001;
-
- const FT d = (lmax+lmin)/2.0;
- const FT c = (lmax-lmin)/2.0;
- FT alpha = 0;
- FT beta = 0;
- std::size_t itr_used = 0;
-
- plib::parray<FT, SIZE> x(size());
- plib::parray<FT, SIZE> p(size());
-
- plib::vec_set(size(), x, x0);
-
- ops.calc_rhs(Ax, x);
- vec_sub(size(), rhs, Ax, residual);
-
- FT rho_delta = accuracy * std::sqrt(static_cast<FT>(size()));
-
- rho_delta = 1e-9;
-
- for (int i = 0; i < iter_max; i++)
- {
- ops.solve_LU_inplace(residual);
- if (i==0)
- {
- vec_set(size(), p, residual);
- alpha = 2.0 / d;
- }
- else
- {
- beta = alpha * ( c / 2.0)*( c / 2.0);
- alpha = 1.0 / (d - beta);
- for (std::size_t k = 0; k < size(); k++)
- p[k] = residual[k] + beta * p[k];
- }
- plib::vec_add_mult_scalar(size(), p, alpha, x);
- ops.calc_rhs(Ax, x);
- plib::vec_sub(size(), rhs, Ax, residual);
- FT rho = std::sqrt(plib::vec_mult2<FT>(size(), residual));
- if (rho < rho_delta)
- break;
- itr_used++;
- }
- return itr_used;
- }
- private:
-
- //typedef typename plib::mat_cr_t<FT, SIZE>::index_type mattype;
-
- plib::parray<float_type, SIZE> residual;
- plib::parray<float_type, SIZE> Ax;
-
- std::size_t m_size;
-
- };
-#endif
-
-} // namespace plib
-
-#endif /* PLIB_GMRES_H_ */
diff --git a/src/lib/netlist/plib/mat_cr.h b/src/lib/netlist/plib/mat_cr.h
deleted file mode 100644
index 4cc027f0d8f..00000000000
--- a/src/lib/netlist/plib/mat_cr.h
+++ /dev/null
@@ -1,530 +0,0 @@
-// license:GPL-2.0+
-// copyright-holders:Couriersud
-/*
- * mat_cr.h
- *
- * Compressed row format matrices
- *
- */
-
-#ifndef MAT_CR_H_
-#define MAT_CR_H_
-
-#include "palloc.h"
-#include "parray.h"
-#include "pconfig.h"
-#include "pomp.h"
-#include "pstate.h"
-#include "ptypes.h"
-#include "putil.h"
-
-#include <algorithm>
-#include <array>
-#include <cmath>
-#include <cstdlib>
-#include <type_traits>
-#include <vector>
-
-namespace plib
-{
-
- // FIXME: causes a crash with GMRES handler
- // template<typename T, int N, typename C = std::size_t>
-
- template<typename T, int N, typename C = uint16_t>
- struct matrix_compressed_rows_t
- {
- using index_type = C;
- using value_type = T;
-
- COPYASSIGNMOVE(matrix_compressed_rows_t, default)
-
- enum constants_e
- {
- FILL_INFINITY = 9999999
- };
-
- parray<index_type, N> diag; // diagonal index pointer n
- parray<index_type, (N == 0) ? 0 : (N < 0 ? N - 1 : N + 1)> row_idx; // row index pointer n + 1
- parray<index_type, N < 0 ? -N * N : N *N> col_idx; // column index array nz_num, initially (n * n)
- parray<value_type, N < 0 ? -N * N : N *N> A; // Matrix elements nz_num, initially (n * n)
- //parray<C, N < 0 ? -N * (N-1) / 2 : N * (N+1) / 2 > nzbd; // Support for gaussian elimination
- parray<std::vector<index_type>, N > nzbd; // Support for gaussian elimination
- // contains elimination rows below the diagonal
- // FIXME: convert to pvector
- std::vector<std::vector<index_type>> m_ge_par;
-
- index_type nz_num;
-
- explicit matrix_compressed_rows_t(const index_type n)
- : diag(n)
- , row_idx(n+1)
- , col_idx(n*n)
- , A(n*n)
- //, nzbd(n * (n+1) / 2)
- , nzbd(n)
- , nz_num(0)
- , m_size(n)
- {
- for (index_type i=0; i<n+1; i++)
- row_idx[i] = 0;
- }
-
- ~matrix_compressed_rows_t() = default;
-
- constexpr index_type size() const { return static_cast<index_type>((N>0) ? N : m_size); }
-
- void clear()
- {
- nz_num = 0;
- for (index_type i=0; i < size() + 1; i++)
- row_idx[i] = 0;
- }
-
- void set_scalar(const T scalar)
- {
- for (index_type i=0, e=nz_num; i<e; i++)
- A[i] = scalar;
- }
-
- void set(C r, C c, T val)
- {
- C ri = row_idx[r];
- while (ri < row_idx[r+1] && col_idx[ri] < c)
- ri++;
- // we have the position now;
- if (ri < row_idx[r+1] && col_idx[ri] == c)
- A[ri] = val;
- else
- {
- for (C i = nz_num; i>ri; i--)
- {
- A[i] = A[i-1];
- col_idx[i] = col_idx[i-1];
- }
- A[ri] = val;
- col_idx[ri] = c;
- for (C i = r + 1; i < size() + 1; i++)
- row_idx[i]++;
- nz_num++;
- if (c==r)
- diag[r] = ri;
- }
- }
-
- template <typename M>
- std::pair<std::size_t, std::size_t> gaussian_extend_fill_mat(M &fill)
- {
- std::size_t ops = 0;
- std::size_t fill_max = 0;
-
- for (std::size_t k = 0; k < fill.size(); k++)
- {
- ops++; // 1/A(k,k)
- for (std::size_t row = k + 1; row < fill.size(); row++)
- {
- if (fill[row][k] < FILL_INFINITY)
- {
- ops++;
- for (std::size_t col = k + 1; col < fill[row].size(); col++)
- //if (fill[k][col] < FILL_INFINITY)
- {
- auto f = std::min(fill[row][col], 1 + fill[row][k] + fill[k][col]);
- if (f < FILL_INFINITY)
- {
- if (f > fill_max)
- fill_max = f;
- ops += 2;
- }
- fill[row][col] = f;
- }
- }
- }
- }
- build_parallel_gaussian_execution_scheme(fill);
- return { fill_max, ops };
- }
-
- template <typename M>
- void build_from_fill_mat(const M &f, std::size_t max_fill = FILL_INFINITY - 1,
- std::size_t band_width = FILL_INFINITY)
- {
- C nz = 0;
- if (nz_num != 0)
- throw pexception("build_from_mat only allowed on empty CR matrix");
- for (std::size_t k=0; k < size(); k++)
- {
- row_idx[k] = nz;
-
- for (std::size_t j=0; j < size(); j++)
- if (f[k][j] <= max_fill && std::abs(static_cast<int>(k)-static_cast<int>(j)) <= static_cast<int>(band_width))
- {
- col_idx[nz] = static_cast<C>(j);
- if (j == k)
- diag[k] = nz;
- nz++;
- }
- }
-
- row_idx[size()] = nz;
- nz_num = nz;
- /* build nzbd */
-
- for (std::size_t k=0; k < size(); k++)
- {
- for (std::size_t j=k + 1; j < size(); j++)
- if (f[j][k] < FILL_INFINITY)
- nzbd[k].push_back(static_cast<C>(j));
- nzbd[k].push_back(0); // end of sequence
- }
- }
-
- template <typename V>
- void gaussian_elimination(V & RHS)
- {
- const std::size_t iN = size();
-
- for (std::size_t i = 0; i < iN - 1; i++)
- {
- std::size_t nzbdp = 0;
- std::size_t pi = diag[i];
- const value_type f = 1.0 / A[pi++];
- const std::size_t piie = row_idx[i+1];
- const auto &nz = nzbd[i];
-
- while (auto j = nz[nzbdp++])
- {
- // proceed to column i
-
- std::size_t pj = row_idx[j];
-
- while (col_idx[pj] < i)
- pj++;
-
- const value_type f1 = - A[pj++] * f;
-
- // subtract row i from j
- // fill-in available assumed, i.e. matrix was prepared
-
- for (std::size_t pii = pi; pii<piie; pii++)
- {
- while (col_idx[pj] < col_idx[pii])
- pj++;
- if (col_idx[pj] == col_idx[pii])
- A[pj++] += A[pii] * f1;
- }
-
- RHS[j] += f1 * RHS[i];
- }
- }
- }
-
- template <typename V>
- void gaussian_elimination_parallel(V & RHS)
- {
- // FIXME: move into solver creation ...
- plib::omp::set_num_threads(4);
- for (auto l = 0ul; l < m_ge_par.size(); l++)
- plib::omp::for_static(0ul, m_ge_par[l].size(), [this, &RHS, &l] (unsigned ll)
- {
- auto &i = m_ge_par[l][ll];
- {
- std::size_t nzbdp = 0;
- std::size_t pi = diag[i];
- const value_type f = 1.0 / A[pi++];
- const std::size_t piie = row_idx[i+1];
-
- while (auto j = nzbd[i][nzbdp++])
- {
- // proceed to column i
-
- std::size_t pj = row_idx[j];
-
- while (col_idx[pj] < i)
- pj++;
-
- const value_type f1 = - A[pj++] * f;
-
- // subtract row i from j
- // fill-in available assumed, i.e. matrix was prepared
- for (std::size_t pii = pi; pii<piie; pii++)
- {
- while (col_idx[pj] < col_idx[pii])
- pj++;
- if (col_idx[pj] == col_idx[pii])
- A[pj++] += A[pii] * f1;
- }
- RHS[j] += f1 * RHS[i];
- }
- }
- });
- }
-
- template <typename V1, typename V2>
- void gaussian_back_substitution(V1 &V, const V2 &RHS)
- {
- const std::size_t iN = size();
- /* row n-1 */
- V[iN - 1] = RHS[iN - 1] / A[diag[iN - 1]];
-
- for (std::size_t j = iN - 1; j-- > 0;)
- {
- value_type tmp = 0;
- const auto jdiag = diag[j];
- const std::size_t e = row_idx[j+1];
- for (std::size_t pk = jdiag + 1; pk < e; pk++)
- tmp += A[pk] * V[col_idx[pk]];
- V[j] = (RHS[j] - tmp) / A[jdiag];
- }
- }
-
- template <typename V1>
- void gaussian_back_substitution(V1 &V)
- {
- const std::size_t iN = size();
- /* row n-1 */
- V[iN - 1] = V[iN - 1] / A[diag[iN - 1]];
-
- for (std::size_t j = iN - 1; j-- > 0;)
- {
- value_type tmp = 0;
- const auto jdiag = diag[j];
- const std::size_t e = row_idx[j+1];
- for (std::size_t pk = jdiag + 1; pk < e; pk++)
- tmp += A[pk] * V[col_idx[pk]];
- V[j] = (V[j] - tmp) / A[jdiag];
- }
- }
-
-
- template <typename VTV, typename VTR>
- void mult_vec(VTR & res, const VTV & x)
- {
- /*
- * res = A * x
- */
-
- std::size_t row = 0;
- std::size_t k = 0;
- const std::size_t oe = nz_num;
-
- while (k < oe)
- {
- T tmp = 0.0;
- const std::size_t e = row_idx[row+1];
- for (; k < e; k++)
- tmp += A[k] * x[col_idx[k]];
- res[row++] = tmp;
- }
- }
-
- /* throws error if P(source)>P(destination) */
- template <typename LUMAT>
- void slim_copy_from(LUMAT & src)
- {
- for (std::size_t r=0; r<src.size(); r++)
- {
- C dp = row_idx[r];
- for (C sp = src.row_idx[r]; sp < src.row_idx[r+1]; sp++)
- {
- /* advance dp to source column and fill 0s if necessary */
- while (col_idx[dp] < src.col_idx[sp])
- A[dp++] = 0;
- if (row_idx[r+1] <= dp || col_idx[dp] != src.col_idx[sp])
- throw plib::pexception("slim_copy_from error");
- A[dp++] = src.A[sp];
- }
- /* fill remaining elements in row */
- while (dp < row_idx[r+1])
- A[dp++] = 0;
- }
- }
-
- /* only copies common elements */
- template <typename LUMAT>
- void reduction_copy_from(LUMAT & src)
- {
- C sp = 0;
- for (std::size_t r=0; r<src.size(); r++)
- {
- C dp = row_idx[r];
- while(sp < src.row_idx[r+1])
- {
- /* advance dp to source column and fill 0s if necessary */
- if (col_idx[dp] < src.col_idx[sp])
- A[dp++] = 0;
- else if (col_idx[dp] == src.col_idx[sp])
- A[dp++] = src.A[sp++];
- else
- sp++;
- }
- /* fill remaining elements in row */
- while (dp < row_idx[r+1])
- A[dp++] = 0;
- }
- }
-
- /* checks at all - may crash */
- template <typename LUMAT>
- void raw_copy_from(LUMAT & src)
- {
- for (std::size_t k = 0; k < nz_num; k++)
- A[k] = src.A[k];
- }
-
- void incomplete_LU_factorization()
- {
- /*
- * incomplete LU Factorization according to http://de.wikipedia.org/wiki/ILU-Zerlegung
- *
- * Result is stored in matrix LU
- *
- * For i = 1,...,N-1
- * For k = 0, ... , i - 1
- * If a[i,k] != 0
- * a[i,k] = a[i,k] / a[k,k]
- * For j = k + 1, ... , N - 1
- * If a[i,j] != 0
- * a[i,j] = a[i,j] - a[i,k] * a[k,j]
- * j=j+1
- * k=k+1
- * i=i+1
- *
- */
-
- for (std::size_t i = 1; i < size(); i++) // row i
- {
- const std::size_t p_i_end = row_idx[i + 1];
- // loop over all columns k left of diag in row i
- for (std::size_t i_k = row_idx[i]; i_k < diag[i]; i_k++)
- {
- const std::size_t k = col_idx[i_k];
- const std::size_t p_k_end = row_idx[k + 1];
- const T LUp_i_k = A[i_k] = A[i_k] / A[diag[k]];
-
- std::size_t k_j = diag[k] + 1;
- std::size_t i_j = i_k + 1;
-
- while (i_j < p_i_end && k_j < p_k_end ) // pj = (i, j)
- {
- // we can assume that within a row ja increases continuously */
- const std::size_t c_i_j = col_idx[i_j]; // row i, column j
- const std::size_t c_k_j = col_idx[k_j]; // row i, column j
- if (c_k_j < c_i_j)
- k_j++;
- else if (c_k_j == c_i_j)
- A[i_j++] -= LUp_i_k * A[k_j++];
- else
- i_j++;
- }
- }
- }
- }
-
- template <typename R>
- void solveLUx (R &r)
- {
- /*
- * Solve a linear equation Ax = r
- * where
- * A = L*U
- *
- * L unit lower triangular
- * U upper triangular
- *
- * ==> LUx = r
- *
- * ==> Ux = L⁻¹ r = w
- *
- * ==> r = Lw
- *
- * This can be solved for w using backwards elimination in L.
- *
- * Now Ux = w
- *
- * This can be solved for x using backwards elimination in U.
- *
- */
- for (std::size_t i = 1; i < size(); ++i )
- {
- T tmp = 0.0;
- const std::size_t j1 = row_idx[i];
- const std::size_t j2 = diag[i];
-
- for (std::size_t j = j1; j < j2; ++j )
- tmp += A[j] * r[col_idx[j]];
- r[i] -= tmp;
- }
- // i now is equal to n;
- for (std::size_t i = size(); i-- > 0; )
- {
- T tmp = 0.0;
- const std::size_t di = diag[i];
- const std::size_t j2 = row_idx[i+1];
- for (std::size_t j = di + 1; j < j2; j++ )
- tmp += A[j] * r[col_idx[j]];
- r[i] = (r[i] - tmp) / A[di];
- }
- }
- private:
- template <typename M>
- void build_parallel_gaussian_execution_scheme(const M &fill)
- {
- // calculate parallel scheme for gaussian elimination
- std::vector<std::vector<index_type>> rt(size());
- for (index_type k = 0; k < size(); k++)
- {
- for (index_type j = k+1; j < size(); j++)
- {
- if (fill[j][k] < FILL_INFINITY)
- {
- rt[k].push_back(j);
- }
- }
- }
-
- std::vector<index_type> levGE(size(), 0);
- index_type cl = 0;
-
- for (index_type k = 0; k < size(); k++ )
- {
- if (levGE[k] >= cl)
- {
- std::vector<index_type> t = rt[k];
- for (index_type j = k+1; j < size(); j++ )
- {
- bool overlap = false;
- // is there overlap
- if (plib::container::contains(t, j))
- overlap = true;
- for (auto &x : rt[j])
- if (plib::container::contains(t, x))
- {
- overlap = true;
- break;
- }
- if (overlap)
- levGE[j] = cl + 1;
- else
- {
- t.push_back(j);
- for (auto &x : rt[j])
- t.push_back(x);
- }
- }
- cl++;
- }
- }
-
- m_ge_par.clear();
- m_ge_par.resize(cl+1);
- for (index_type k = 0; k < size(); k++)
- m_ge_par[levGE[k]].push_back(k);
- }
-
- index_type m_size;
- };
-
-} // namespace plib
-
-#endif /* MAT_CR_H_ */
diff --git a/src/lib/netlist/plib/palloc.cpp b/src/lib/netlist/plib/palloc.cpp
new file mode 100644
index 00000000000..e4d31985b23
--- /dev/null
+++ b/src/lib/netlist/plib/palloc.cpp
@@ -0,0 +1,105 @@
+// license:GPL-2.0+
+// copyright-holders:Couriersud
+/*
+ * palloc.c
+ *
+ */
+
+#include "pconfig.h"
+#include "palloc.h"
+#include "pfmtlog.h"
+
+#include <algorithm>
+
+namespace plib {
+
+//============================================================
+// Memory pool
+//============================================================
+
+mempool::mempool(size_t min_alloc, size_t min_align)
+: m_min_alloc(min_alloc), m_min_align(min_align)
+{
+}
+mempool::~mempool()
+{
+ for (auto & b : m_blocks)
+ {
+ if (b.m_num_alloc != 0)
+ {
+ fprintf(stderr, "Found block with %d dangling allocations\n", static_cast<int>(b.m_num_alloc));
+ }
+ ::operator delete(b.data);
+ }
+ m_blocks.clear();
+}
+
+size_t mempool::new_block()
+{
+ block b;
+ b.data = static_cast<char *>(::operator new(m_min_alloc));
+ b.cur_ptr = b.data;
+ b.m_free = m_min_alloc;
+ b.m_num_alloc = 0;
+ m_blocks.push_back(b);
+ return m_blocks.size() - 1;
+}
+
+size_t mempool::mininfosize()
+{
+ size_t sinfo = sizeof(mempool::info);
+#ifdef __APPLE__
+ size_t ma = 16;
+#else
+ size_t ma = 8;
+#endif
+ return ((std::max(m_min_align, sinfo) + ma - 1) / ma) * ma;
+}
+
+void *mempool::alloc(size_t size)
+{
+ size_t rs = (size + mininfosize() + m_min_align - 1) & ~(m_min_align - 1);
+ for (size_t bn=0; bn < m_blocks.size(); bn++)
+ {
+ auto &b = m_blocks[bn];
+ if (b.m_free > rs)
+ {
+ b.m_free -= rs;
+ b.m_num_alloc++;
+ auto i = reinterpret_cast<info *>(b.cur_ptr);
+ i->m_block = bn;
+ auto ret = reinterpret_cast<void *>(b.cur_ptr + mininfosize());
+ b.cur_ptr += rs;
+ return ret;
+ }
+ }
+ {
+ size_t bn = new_block();
+ auto &b = m_blocks[bn];
+ b.m_num_alloc = 1;
+ b.m_free = m_min_alloc - rs;
+ auto i = reinterpret_cast<info *>(b.cur_ptr);
+ i->m_block = bn;
+ auto ret = reinterpret_cast<void *>(b.cur_ptr + mininfosize());
+ b.cur_ptr += rs;
+ return ret;
+ }
+}
+
+void mempool::free(void *ptr)
+{
+ auto p = reinterpret_cast<char *>(ptr);
+
+ auto i = reinterpret_cast<info *>(p - mininfosize());
+ block *b = &m_blocks[i->m_block];
+ if (b->m_num_alloc == 0)
+ fprintf(stderr, "Argh .. double free\n");
+ else
+ {
+ //b->m_free = m_min_alloc;
+ //b->cur_ptr = b->data;
+ }
+ b->m_num_alloc--;
+}
+
+}
diff --git a/src/lib/netlist/plib/palloc.h b/src/lib/netlist/plib/palloc.h
index 15fede3a99b..a35bc50ff17 100644
--- a/src/lib/netlist/plib/palloc.h
+++ b/src/lib/netlist/plib/palloc.h
@@ -8,427 +8,172 @@
#ifndef PALLOC_H_
#define PALLOC_H_
-#include "pconfig.h"
#include "pstring.h"
-#include "ptypes.h"
-#include <cstddef>
-#include <cstdlib>
-#include <memory>
-#include <type_traits>
-#include <utility>
#include <vector>
-
-#if defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)
-#include <malloc.h>
-#endif
+#include <memory>
namespace plib {
- //============================================================
- // Standard arena_deleter
- //============================================================
-
- template <typename P, typename T>
- struct arena_deleter
- {
- //using arena_storage_type = P *;
- using arena_storage_type = typename std::conditional<P::is_stateless, P, P *>::type;
- template <typename X, typename Y = void>
- typename std::enable_if<!X::is_stateless, X&>::type getref(X *x) { return *x;}
- template <typename X, typename Y = void *>
- typename std::enable_if<std::remove_pointer<X>::type::is_stateless, X&>::type
- getref(X &x, Y y = nullptr)
- {
- unused_var(y);
- return x;
- }
-
- constexpr arena_deleter(arena_storage_type a = arena_storage_type()) noexcept
- : m_a(a) { }
-
- template<typename PU, typename U, typename = typename
- std::enable_if<std::is_convertible< U*, T*>::value>::type>
- arena_deleter(const arena_deleter<PU, U> &rhs) noexcept : m_a(rhs.m_a) { }
-
- void operator()(T *p) //const
- {
- /* call destructor */
- p->~T();
- getref(m_a).deallocate(p);
- }
- //private:
- arena_storage_type m_a;
- };
-
- //============================================================
- // owned_ptr: smart pointer with ownership information
- //============================================================
-
- template <typename SC, typename D>
- class owned_ptr
- {
- public:
-
- using pointer = SC *;
- using element_type = SC;
- using deleter_type = D;
-
- owned_ptr()
- : m_ptr(nullptr), m_deleter(), m_is_owned(true) { }
-
- template <typename, typename>
- friend class owned_ptr;
-
- owned_ptr(pointer p, bool owned) noexcept
- : m_ptr(p), m_deleter(), m_is_owned(owned)
- { }
-
- owned_ptr(pointer p, bool owned, D deleter) noexcept
- : m_ptr(p), m_deleter(deleter), m_is_owned(owned)
- { }
-
-
- owned_ptr(const owned_ptr &r) = delete;
- owned_ptr & operator =(owned_ptr &r) = delete;
-
- template<typename DC, typename DC_D>
- owned_ptr & operator =(owned_ptr<DC, DC_D> &&r)
- {
- if (m_is_owned && (m_ptr != nullptr))
- //delete m_ptr;
- m_deleter(m_ptr);
- m_is_owned = r.m_is_owned;
- m_ptr = r.m_ptr;
- m_deleter = r.m_deleter;
- r.m_is_owned = false;
- r.m_ptr = nullptr;
- return *this;
- }
-
- owned_ptr(owned_ptr &&r) noexcept
- : m_ptr(r.m_ptr)
- , m_deleter(r.m_deleter)
- , m_is_owned(r.m_is_owned)
- {
- r.m_is_owned = false;
- r.m_ptr = nullptr;
- }
-
- owned_ptr &operator=(owned_ptr &&r) noexcept
- {
- if (m_is_owned && (m_ptr != nullptr))
- //delete m_ptr;
- m_deleter(m_ptr);
- m_is_owned = r.m_is_owned;
- m_ptr = r.m_ptr;
- m_deleter = std::move(r.m_deleter);
- r.m_is_owned = false;
- r.m_ptr = nullptr;
- return *this;
- }
-
- template<typename DC, typename DC_D>
- owned_ptr(owned_ptr<DC, DC_D> &&r) noexcept
- : m_ptr(static_cast<pointer >(r.get()))
- , m_deleter(r.m_deleter)
- , m_is_owned(r.is_owned())
- {
- r.release();
- }
-
- ~owned_ptr() noexcept
- {
- if (m_is_owned && (m_ptr != nullptr))
- {
- //delete m_ptr;
- m_deleter(m_ptr);
- }
- m_is_owned = false;
- m_ptr = nullptr;
- }
-
- /**
- * \brief Return @c true if the stored pointer is not null.
- */
- explicit operator bool() const noexcept { return m_ptr != nullptr; }
-
- pointer release()
- {
- pointer tmp = m_ptr;
- m_is_owned = false;
- m_ptr = nullptr;
- return tmp;
- }
-
- bool is_owned() const { return m_is_owned; }
-
- pointer operator ->() const noexcept { return m_ptr; }
- typename std::add_lvalue_reference<element_type>::type operator *() const noexcept { return *m_ptr; }
- pointer get() const noexcept { return m_ptr; }
-
- deleter_type& get_deleter() noexcept { return m_deleter; }
- const deleter_type& get_deleter() const noexcept { return m_deleter; }
-
- private:
- pointer m_ptr;
- D m_deleter;
- bool m_is_owned;
- };
-
- //============================================================
- // Arena allocator for use with containers
- //============================================================
-
- template <class ARENA, class T, std::size_t ALIGN = alignof(T)>
- class arena_allocator
+//============================================================
+// Memory allocation
+//============================================================
+
+template<typename T, typename... Args>
+T *palloc(Args&&... args)
+{
+ return new T(std::forward<Args>(args)...);
+}
+
+template<typename T>
+void pfree(T *ptr)
+{
+ delete ptr;
+}
+
+template<typename T>
+T* palloc_array(const std::size_t num)
+{
+ return new T[num]();
+}
+
+template<typename T>
+void pfree_array(T *ptr)
+{
+ delete [] ptr;
+}
+
+template<typename T, typename... Args>
+std::unique_ptr<T> make_unique(Args&&... args)
+{
+ return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
+}
+
+template<typename BC, typename DC, typename... Args>
+static std::unique_ptr<BC> make_unique_base(Args&&... args)
+{
+ std::unique_ptr<BC> ret(new DC(std::forward<Args>(args)...));
+ return ret;
+}
+
+template <typename SC>
+class owned_ptr
+{
+private:
+ owned_ptr()
+ : m_ptr(nullptr), m_is_owned(true) { }
+public:
+ owned_ptr(SC *p, bool owned) noexcept
+ : m_ptr(p), m_is_owned(owned)
+ { }
+
+ owned_ptr(const owned_ptr &r) = delete;
+ owned_ptr & operator =(owned_ptr &r) = delete;
+
+ template<typename DC>
+ owned_ptr & operator =(owned_ptr<DC> &&r)
{
- public:
- using value_type = T;
- static constexpr const std::size_t align_size = ALIGN;
- using arena_type = ARENA;
-
- static_assert(align_size >= alignof(T) && (align_size % alignof(T)) == 0,
- "ALIGN must be greater than alignof(T) and a multiple");
-
- arena_allocator() noexcept
- : m_a(arena_type::instance())
- { }
-
- ~arena_allocator() noexcept = default;
-
- arena_allocator(const arena_allocator &rhs) noexcept = default;
- arena_allocator& operator=(const arena_allocator&) noexcept = delete;
-
- arena_allocator(arena_allocator&&) noexcept = default;
- arena_allocator& operator=(arena_allocator&&) = delete;
-
- arena_allocator(arena_type & a) noexcept : m_a(a)
- {
- }
-
- template <class U>
- arena_allocator(const arena_allocator<ARENA, U, ALIGN>& rhs) noexcept
- : m_a(rhs.m_a)
- {
- }
-
- template <class U> struct rebind
- {
- using other = arena_allocator<ARENA, U, ALIGN>;
- };
-
- T* allocate(std::size_t n)
- {
- return reinterpret_cast<T *>(m_a.allocate(ALIGN, sizeof(T) * n));
- }
-
- void deallocate(T* p, std::size_t n) noexcept
- {
- unused_var(n);
- m_a.deallocate(p);
- }
-
- template <class AR1, class T1, std::size_t A1, class AR2, class T2, std::size_t A2>
- friend bool operator==(const arena_allocator<AR1, T1, A1>& lhs,
- const arena_allocator<AR2, T2, A2>& rhs) noexcept;
-
- template <class AU, class U, std::size_t A> friend class arena_allocator;
- private:
- arena_type &m_a;
- };
-
- template <class AR1, class T1, std::size_t A1, class AR2, class T2, std::size_t A2>
- inline bool operator==(const arena_allocator<AR1, T1, A1>& lhs,
- const arena_allocator<AR2, T2, A2>& rhs) noexcept
- {
- return A1 == A2 && rhs.m_a == lhs.m_a;
- }
- template <class AR1, class T1, std::size_t A1, class AR2, class T2, std::size_t A2>
- inline bool operator!=(const arena_allocator<AR1, T1, A1>& lhs,
- const arena_allocator<AR2, T2, A2>& rhs) noexcept
- {
- return !(lhs == rhs);
+ if (m_is_owned && (m_ptr != nullptr))
+ delete m_ptr;
+ m_is_owned = r.m_is_owned;
+ m_ptr = r.m_ptr;
+ r.m_is_owned = false;
+ r.m_ptr = nullptr;
+ return *this;
}
- //============================================================
- // Memory allocation
- //============================================================
-
- struct aligned_arena
+ owned_ptr(owned_ptr &&r) noexcept
{
- static constexpr const bool is_stateless = true;
- template <class T, std::size_t ALIGN = alignof(T)>
- using allocator_type = arena_allocator<aligned_arena, T, ALIGN>;
-
- template <typename T>
- using owned_pool_ptr = plib::owned_ptr<T, arena_deleter<aligned_arena, T>>;
-
- static inline aligned_arena &instance()
- {
- static aligned_arena s_arena;
- return s_arena;
- }
-
- static inline void *allocate( size_t alignment, size_t size )
- {
- #if (USE_ALIGNED_ALLOCATION)
- #if defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)
- return _aligned_malloc(size, alignment);
- #elif defined(__APPLE__)
- void* p;
- if (::posix_memalign(&p, alignment, size) != 0) {
- p = nullptr;
- }
- return p;
- #else
- return aligned_alloc(alignment, size);
- #endif
- #else
- unused_var(alignment);
- return ::operator new(size);
- #endif
- }
-
- static inline void deallocate( void *ptr )
- {
- #if (USE_ALIGNED_ALLOCATION)
- // NOLINTNEXTLINE(cppcoreguidelines-no-malloc)
- free(ptr);
- #else
- ::operator delete(ptr);
- #endif
- }
-
- template<typename T, typename... Args>
- owned_pool_ptr<T> make_poolptr(Args&&... args)
- {
- auto *mem = allocate(alignof(T), sizeof(T));
- return owned_pool_ptr<T>(new (mem) T(std::forward<Args>(args)...), true, arena_deleter<aligned_arena, T>(*this));
- }
-
- };
-
- template <typename T, std::size_t ALIGN>
- /*inline */ C14CONSTEXPR T *assume_aligned_ptr(T *p) noexcept
- {
- static_assert(ALIGN >= alignof(T), "Alignment must be greater or equal to alignof(T)");
- static_assert(is_pow2(ALIGN), "Alignment must be a power of 2");
- //auto t = reinterpret_cast<std::uintptr_t>(p);
- //if (t & (ALIGN-1))
- // printf("alignment error!");
-#if (USE_ALIGNED_HINTS)
- return reinterpret_cast<T *>(__builtin_assume_aligned(p, ALIGN));
-#else
- return p;
-#endif
+ m_is_owned = r.m_is_owned;
+ m_ptr = r.m_ptr;
+ r.m_is_owned = false;
+ r.m_ptr = nullptr;
}
- template <typename T, std::size_t ALIGN>
- constexpr const T *assume_aligned_ptr(const T *p) noexcept
+ template<typename DC>
+ owned_ptr(owned_ptr<DC> &&r) noexcept
{
- static_assert(ALIGN >= alignof(T), "Alignment must be greater or equal to alignof(T)");
- static_assert(is_pow2(ALIGN), "Alignment must be a power of 2");
-#if (USE_ALIGNED_HINTS)
- return reinterpret_cast<const T *>(__builtin_assume_aligned(p, ALIGN));
-#else
- return p;
-#endif
+ m_ptr = static_cast<SC *>(r.get());
+ m_is_owned = r.is_owned();
+ r.release();
}
- // FIXME: remove
- template<typename T, typename... Args>
- inline T *pnew(Args&&... args)
+ ~owned_ptr()
{
- auto *p = aligned_arena::allocate(alignof(T), sizeof(T));
- return new(p) T(std::forward<Args>(args)...);
+ if (m_is_owned && (m_ptr != nullptr))
+ delete m_ptr;
+ m_is_owned = false;
+ m_ptr = nullptr;
}
-
- template<typename T>
- inline void pdelete(T *ptr)
+ template<typename DC, typename... Args>
+ static owned_ptr Create(Args&&... args)
{
- ptr->~T();
- aligned_arena::deallocate(ptr);
+ owned_ptr a;
+ DC *x = new DC(std::forward<Args>(args)...);
+ a.m_ptr = static_cast<SC *>(x);
+ return std::move(a);
}
-
- template <typename T>
- using unique_ptr = std::unique_ptr<T, arena_deleter<aligned_arena, T>>;
-
- template<typename T, typename... Args>
- plib::unique_ptr<T> make_unique(Args&&... args)
+ template<typename... Args>
+ static owned_ptr Create(Args&&... args)
{
- return plib::unique_ptr<T>(pnew<T>(std::forward<Args>(args)...));
+ owned_ptr a;
+ a.m_ptr = new SC(std::forward<Args>(args)...);
+ return std::move(a);
}
-
-#if 0
- template<typename T, typename... Args>
- static owned_ptr<T> make_owned(Args&&... args)
+ SC * release()
{
- return owned_ptr<T>(pnew<T>(std::forward<Args>(args)...), true);
+ SC *tmp = m_ptr;
+ m_is_owned = false;
+ m_ptr = nullptr;
+ return tmp;
}
-#endif
-
-
- template <class T, std::size_t ALIGN = alignof(T)>
- using aligned_allocator = aligned_arena::allocator_type<T, ALIGN>;
-
- //============================================================
- // traits to determine alignment size and stride size
- // from types supporting alignment
- //============================================================
- PDEFINE_HAS_MEMBER(has_align, align_size);
+ bool is_owned() const { return m_is_owned; }
- template <typename T, typename X = void>
- struct align_traits
- {
- static constexpr const std::size_t align_size = alignof(std::max_align_t);
- static constexpr const std::size_t value_size = sizeof(typename T::value_type);
- static constexpr const std::size_t stride_size = lcm(align_size, value_size) / value_size;
- };
+ SC * operator ->() const { return m_ptr; }
+ SC & operator *() const { return *m_ptr; }
+ SC * get() const { return m_ptr; }
+private:
+ SC *m_ptr;
+ bool m_is_owned;
+};
- template <typename T>
- struct align_traits<T, typename std::enable_if<has_align<T>::value, void>::type>
+class mempool
+{
+private:
+ struct block
{
- static constexpr const std::size_t align_size = T::align_size;
- static constexpr const std::size_t value_size = sizeof(typename T::value_type);
- static constexpr const std::size_t stride_size = lcm(align_size, value_size) / value_size;
+ block() : m_num_alloc(0), m_free(0), cur_ptr(nullptr), data(nullptr) { }
+ std::size_t m_num_alloc;
+ std::size_t m_free;
+ char *cur_ptr;
+ char *data;
};
- //============================================================
- // Aligned vector
- //============================================================
+ size_t new_block();
+ size_t mininfosize();
- // FIXME: needs a separate file
- template <class T, std::size_t ALIGN = alignof(T)>
- class aligned_vector : public std::vector<T, aligned_allocator<T, ALIGN>>
+ struct info
{
- public:
- using base = std::vector<T, aligned_allocator<T, ALIGN>>;
+ info() : m_block(0) { }
+ size_t m_block;
+ };
- using reference = typename base::reference;
- using const_reference = typename base::const_reference;
- using pointer = typename base::pointer;
- using const_pointer = typename base::const_pointer;
- using size_type = typename base::size_type;
+ size_t m_min_alloc;
+ size_t m_min_align;
- using base::base;
+ std::vector<block> m_blocks;
- C14CONSTEXPR reference operator[](size_type i) noexcept
- {
- return assume_aligned_ptr<T, ALIGN>(&(base::operator[](0)))[i];
- }
- constexpr const_reference operator[](size_type i) const noexcept
- {
- return assume_aligned_ptr<T, ALIGN>(&(base::operator[](0)))[i];
- }
+public:
+ mempool(size_t min_alloc, size_t min_align);
+ ~mempool();
- pointer data() noexcept { return assume_aligned_ptr<T, ALIGN>(base::data()); }
- const_pointer data() const noexcept { return assume_aligned_ptr<T, ALIGN>(base::data()); }
+ void *alloc(size_t size);
+ void free(void *ptr);
- };
+};
-} // namespace plib
+}
#endif /* PALLOC_H_ */
diff --git a/src/lib/netlist/plib/parray.h b/src/lib/netlist/plib/parray.h
deleted file mode 100644
index 1be37b908cd..00000000000
--- a/src/lib/netlist/plib/parray.h
+++ /dev/null
@@ -1,126 +0,0 @@
-// license:GPL-2.0+
-// copyright-holders:Couriersud
-/*
- * parray.h
- *
- */
-
-#ifndef PARRAY_H_
-#define PARRAY_H_
-
-#include "palloc.h"
-#include "pconfig.h"
-#include "pexception.h"
-
-#include <array>
-#include <memory>
-#include <type_traits>
-#include <utility>
-#include <vector>
-
-namespace plib {
-
- template <typename FT, int SIZE>
- struct sizeabs
- {
- static constexpr std::size_t ABS() { return (SIZE < 0) ? static_cast<std::size_t>(0 - SIZE) : static_cast<std::size_t>(SIZE); }
- using container = typename std::array<FT, ABS()> ;
- };
-
- template <typename FT>
- struct sizeabs<FT, 0>
- {
- static constexpr const std::size_t ABS = 0;
- using container = typename std::vector<FT, aligned_allocator<FT, PALIGN_VECTOROPT>>;
- };
-
- /**
- * \brief Array with preallocated or dynamic allocation
- *
- * Passing SIZE > 0 has the same functionality as a std::array.
- * SIZE = 0 is pure dynamic allocation, the actual array size is passed to the
- * constructor.
- * SIZE < 0 reserves std::abs(SIZE) elements statically in place allocated. The
- * actual size is passed in by the constructor.
- * This array is purely intended for HPC application where depending on the
- * architecture a preference dynamic/static has to be made.
- *
- * This struct is not intended to be a full replacement to std::array.
- * It is a subset to enable switching between dynamic and static allocation.
- * I consider > 10% performance difference to be a use case.
- */
-
- template <typename FT, int SIZE>
- struct parray
- {
- public:
- static constexpr std::size_t SIZEABS() { return sizeabs<FT, SIZE>::ABS(); }
-
- using base_type = typename sizeabs<FT, SIZE>::container;
- using size_type = typename base_type::size_type;
- using reference = typename base_type::reference;
- using const_reference = typename base_type::const_reference;
- using value_type = typename base_type::value_type;
-
- template <int X = SIZE >
- parray(size_type size, typename std::enable_if<X==0, int>::type = 0)
- : m_a(size), m_size(size)
- {
- }
-
-#if 1
- /* allow construction in fixed size arrays */
- template <int X = SIZE >
- parray(typename std::enable_if<(X > 0), int>::type = 0)
- : m_size(X)
- {
- }
-#endif
- template <int X = SIZE >
- parray(size_type size, typename std::enable_if<X!=0, int>::type = 0)
- : m_size(size)
- {
- if (SIZE < 0 && size > SIZEABS())
- throw plib::pexception("parray: size error " + plib::to_string(size) + ">" + plib::to_string(SIZEABS()));
- else if (SIZE > 0 && size != SIZEABS())
- throw plib::pexception("parray: size error");
- }
-
- inline size_type size() const noexcept { return SIZE <= 0 ? m_size : SIZEABS(); }
-
- constexpr size_type max_size() const noexcept { return base_type::max_size(); }
-
- bool empty() const noexcept { return size() == 0; }
-
-#if 0
- reference operator[](size_type i) /*noexcept*/
- {
- if (i >= m_size) throw plib::pexception("limits error " + to_string(i) + ">=" + to_string(m_size));
- return m_a[i];
- }
- const_reference operator[](size_type i) const /*noexcept*/
- {
- if (i >= m_size) throw plib::pexception("limits error " + to_string(i) + ">=" + to_string(m_size));
- return m_a[i];
- }
-#else
- C14CONSTEXPR reference operator[](size_type i) noexcept
- {
- return assume_aligned_ptr<FT, PALIGN_VECTOROPT>(&m_a[0])[i];
- }
- constexpr const_reference operator[](size_type i) const noexcept
- {
- return assume_aligned_ptr<FT, PALIGN_VECTOROPT>(&m_a[0])[i];
- }
-#endif
- FT * data() noexcept { return assume_aligned_ptr<FT, PALIGN_VECTOROPT>(m_a.data()); }
- const FT * data() const noexcept { return assume_aligned_ptr<FT, PALIGN_VECTOROPT>(m_a.data()); }
-
- private:
- PALIGNAS_VECTOROPT()
- base_type m_a;
- size_type m_size;
- };
-} // namespace plib
-
-#endif /* PARRAY_H_ */
diff --git a/src/lib/netlist/plib/pchrono.cpp b/src/lib/netlist/plib/pchrono.cpp
index 953d948e062..971d19b3645 100644
--- a/src/lib/netlist/plib/pchrono.cpp
+++ b/src/lib/netlist/plib/pchrono.cpp
@@ -49,5 +49,5 @@ exact_ticks::type exact_ticks::per_second()
#endif
-} // namespace chrono
-} // namespace plib
+}
+}
diff --git a/src/lib/netlist/plib/pchrono.h b/src/lib/netlist/plib/pchrono.h
index 8ce0eca23b3..a229128e7b8 100644
--- a/src/lib/netlist/plib/pchrono.h
+++ b/src/lib/netlist/plib/pchrono.h
@@ -9,17 +9,16 @@
#define PCHRONO_H_
#include "pconfig.h"
-#include "ptypes.h"
-#include <chrono>
#include <cstdint>
+#include <chrono>
namespace plib {
namespace chrono {
template <typename T>
struct sys_ticks
{
- using type = typename T::rep;
+ typedef typename T::rep type;
static inline type start() { return T::now().time_since_epoch().count(); }
static inline type stop() { return T::now().time_since_epoch().count(); }
static inline constexpr type per_second() { return T::period::den / T::period::num; }
@@ -146,7 +145,7 @@ namespace chrono {
struct counter
{
counter() : m_count(0) { }
- using type = uint_least64_t;
+ typedef uint_least64_t type;
type operator()() const { return m_count; }
void inc() { ++m_count; }
void reset() { m_count = 0; }
@@ -158,7 +157,7 @@ namespace chrono {
template<>
struct counter<false>
{
- using type = uint_least64_t;
+ typedef uint_least64_t type;
constexpr type operator()() const { return 0; }
void inc() const { }
void reset() const { }
@@ -169,28 +168,15 @@ namespace chrono {
template< typename T, bool enabled_ = true>
struct timer
{
- using type = typename T::type;
- using ctype = uint_least64_t;
- constexpr static bool enabled = enabled_;
-
- struct guard_t
- {
- guard_t() = delete;
- guard_t(timer &m) noexcept : m_m(m) { m_m.m_time -= T::start(); }
- ~guard_t() { m_m.m_time += T::stop(); ++m_m.m_count; }
-
- COPYASSIGNMOVE(guard_t, default)
-
- private:
- timer &m_m;
- };
-
- friend struct guard_t;
+ typedef typename T::type type;
+ typedef uint_least64_t ctype;
timer() : m_time(0), m_count(0) { }
type operator()() const { return m_time; }
+ void start() { m_time -= T::start(); }
+ void stop() { m_time += T::stop(); ++m_count; }
void reset() { m_time = 0; m_count = 0; }
type average() const { return (m_count == 0) ? 0 : m_time / m_count; }
type total() const { return m_time; }
@@ -199,7 +185,7 @@ namespace chrono {
double as_seconds() const { return static_cast<double>(total())
/ static_cast<double>(T::per_second()); }
- guard_t guard() { return guard_t(*this); }
+ constexpr static bool enabled = enabled_;
private:
type m_time;
ctype m_count;
@@ -208,31 +194,19 @@ namespace chrono {
template<typename T>
struct timer<T, false>
{
- using type = typename T::type;
- using ctype = uint_least64_t;
-
- struct guard_t
- {
- guard_t() = default;
- COPYASSIGNMOVE(guard_t, default)
- /* using default constructor will trigger warning on
- * unused local variable.
- */
- // NOLINTNEXTLINE(modernize-use-equals-default)
- ~guard_t() { }
- };
-
+ typedef typename T::type type;
+ typedef uint_least64_t ctype;
constexpr type operator()() const { return 0; }
+ void start() const { }
+ void stop() const { }
void reset() const { }
constexpr type average() const { return 0; }
constexpr type total() const { return 0; }
constexpr ctype count() const { return 0; }
constexpr double as_seconds() const { return 0.0; }
constexpr static bool enabled = false;
- guard_t guard() { return guard_t(); }
};
-
} // namespace chrono
} // namespace plib
diff --git a/src/lib/netlist/plib/pconfig.h b/src/lib/netlist/plib/pconfig.h
index d66b342f815..0200c305ecd 100644
--- a/src/lib/netlist/plib/pconfig.h
+++ b/src/lib/netlist/plib/pconfig.h
@@ -21,46 +21,18 @@
* if PHAS_RDTSCP == 1
*/
#ifndef PUSE_ACCURATE_STATS
-#define PUSE_ACCURATE_STATS (0)
+#define PUSE_ACCURATE_STATS (1)
#endif
/*
* Set this to one if you want to use 128 bit int for ptime.
- * This is about 5% slower on a kaby lake processor.
+ * This is for tests only.
*/
#ifndef PHAS_INT128
#define PHAS_INT128 (0)
#endif
-/*
- * Set this to one if you want to use aligned storage optimizations.
- */
-
-#ifndef USE_ALIGNED_OPTIMIZATIONS
-#define USE_ALIGNED_OPTIMIZATIONS (0)
-#endif
-
-#define USE_ALIGNED_ALLOCATION (USE_ALIGNED_OPTIMIZATIONS)
-#define USE_ALIGNED_HINTS (USE_ALIGNED_OPTIMIZATIONS)
-/*
- * Standard alignment macros
- */
-
-#define PALIGN_CACHELINE (64)
-#define PALIGN_VECTOROPT (64)
-
-#define PALIGNAS_CACHELINE() PALIGNAS(PALIGN_CACHELINE)
-#define PALIGNAS_VECTOROPT() PALIGNAS(PALIGN_VECTOROPT)
-
-/* Breaks mame build on windows due to -Wattribute
- * FIXME: no error on cross-compile - need further checks */
-#if defined(_WIN32) && defined(__GNUC__)
-#define PALIGNAS(x)
-#else
-#define PALIGNAS(x) alignas(x)
-#endif
-
/*============================================================
* Check for CPP Version
*
@@ -75,13 +47,6 @@
*
*============================================================*/
-#ifndef NVCCBUILD
-#define NVCCBUILD (0)
-#endif
-
-#if NVCCBUILD
-#define C14CONSTEXPR
-#else
#if __cplusplus == 201103L
#define C14CONSTEXPR
#elif __cplusplus == 201402L
@@ -93,7 +58,6 @@
#else
#error "C++ version not supported"
#endif
-#endif
#ifndef PHAS_INT128
#define PHAS_INT128 (0)
@@ -104,6 +68,17 @@ typedef __uint128_t UINT128;
typedef __int128_t INT128;
#endif
+#if defined(__GNUC__)
+#ifdef RESTRICT
+#undef RESTRICT
+#endif
+#define RESTRICT __restrict__
+#define ATTR_UNUSED __attribute__((__unused__))
+#else
+#define RESTRICT
+#define ATTR_UNUSED
+#endif
+
//============================================================
// Standard defines
//============================================================
diff --git a/src/lib/netlist/plib/pdynlib.cpp b/src/lib/netlist/plib/pdynlib.cpp
index 0d32bead51d..13827eaf24c 100644
--- a/src/lib/netlist/plib/pdynlib.cpp
+++ b/src/lib/netlist/plib/pdynlib.cpp
@@ -25,7 +25,7 @@ CHAR *astring_from_utf8(const char *utf8string)
// convert UTF-16 to "ANSI code page" string
char_count = WideCharToMultiByte(CP_ACP, 0, wstring, -1, nullptr, 0, nullptr, nullptr);
- result = new CHAR[char_count];
+ result = palloc_array<CHAR>(char_count);
if (result != nullptr)
WideCharToMultiByte(CP_ACP, 0, wstring, -1, result, char_count, nullptr, nullptr);
@@ -39,7 +39,7 @@ WCHAR *wstring_from_utf8(const char *utf8string)
// convert MAME string (UTF-8) to UTF-16
char_count = MultiByteToWideChar(CP_UTF8, 0, utf8string, -1, nullptr, 0);
- result = new WCHAR[char_count];
+ result = palloc_array<WCHAR>(char_count);
if (result != nullptr)
MultiByteToWideChar(CP_UTF8, 0, utf8string, -1, result, char_count);
@@ -58,7 +58,7 @@ WCHAR *wstring_from_utf8(const char *utf8string)
#endif
namespace plib {
-dynlib::dynlib(const pstring &libname)
+dynlib::dynlib(const pstring libname)
: m_isLoaded(false), m_lib(nullptr)
{
#ifdef _WIN32
@@ -72,7 +72,7 @@ dynlib::dynlib(const pstring &libname)
m_isLoaded = true;
//else
// fprintf(stderr, "win: library <%s> not found!\n", libname.c_str());
- delete [] buffer;
+ pfree_array(buffer);
#elif defined(EMSCRIPTEN)
//no-op
#else
@@ -88,11 +88,9 @@ dynlib::dynlib(const pstring &libname)
#endif
}
-dynlib::dynlib(const pstring &path, const pstring &libname)
+dynlib::dynlib(const pstring path, const pstring libname)
: m_isLoaded(false), m_lib(nullptr)
{
- // FIXME: implement path search
- plib::unused_var(path);
// printf("win: loading <%s>\n", libname.c_str());
#ifdef _WIN32
TCHAR *buffer = tstring_from_utf8(libname.c_str());
@@ -106,7 +104,7 @@ dynlib::dynlib(const pstring &path, const pstring &libname)
{
//printf("win: library <%s> not found!\n", libname.c_str());
}
- delete [] buffer;
+ pfree_array(buffer);
#elif defined(EMSCRIPTEN)
//no-op
#else
@@ -141,7 +139,7 @@ bool dynlib::isLoaded() const
return m_isLoaded;
}
-void *dynlib::getsym_p(const pstring &name)
+void *dynlib::getsym_p(const pstring name)
{
#ifdef _WIN32
return (void *) GetProcAddress((HMODULE) m_lib, name.c_str());
@@ -150,4 +148,4 @@ void *dynlib::getsym_p(const pstring &name)
#endif
}
-} // namespace plib
+}
diff --git a/src/lib/netlist/plib/pdynlib.h b/src/lib/netlist/plib/pdynlib.h
index 1454c053298..7c9412593c9 100644
--- a/src/lib/netlist/plib/pdynlib.h
+++ b/src/lib/netlist/plib/pdynlib.h
@@ -8,31 +8,28 @@
#define PDYNLIB_H_
#include "pstring.h"
-#include "ptypes.h"
namespace plib {
// ----------------------------------------------------------------------------------------
// pdynlib: dynamic loading of libraries ...
// ----------------------------------------------------------------------------------------
-class dynlib : public nocopyassignmove
+class dynlib
{
public:
- explicit dynlib(const pstring &libname);
- dynlib(const pstring &path, const pstring &libname);
-
+ explicit dynlib(const pstring libname);
+ dynlib(const pstring path, const pstring libname);
~dynlib();
- COPYASSIGNMOVE(dynlib, delete)
bool isLoaded() const;
template <typename T>
- T getsym(const pstring &name)
+ T getsym(const pstring name)
{
return reinterpret_cast<T>(getsym_p(name));
}
private:
- void *getsym_p(const pstring &name);
+ void *getsym_p(const pstring name);
bool m_isLoaded;
void *m_lib;
@@ -67,6 +64,6 @@ private:
calltype m_sym;
};
-} // namespace plib
+}
#endif /* PSTRING_H_ */
diff --git a/src/lib/netlist/plib/pexception.cpp b/src/lib/netlist/plib/pexception.cpp
index 8d6907d66f2..a4ed8f367e0 100644
--- a/src/lib/netlist/plib/pexception.cpp
+++ b/src/lib/netlist/plib/pexception.cpp
@@ -9,7 +9,6 @@
#include "pfmtlog.h"
#include <cfenv>
-#include <iostream>
#if (defined(__x86_64__) || defined(__i386__)) && defined(__linux__)
#define HAS_FEENABLE_EXCEPT (1)
@@ -18,113 +17,127 @@
#endif
namespace plib {
-
- //============================================================
- // terminate
- //============================================================
-
- void terminate(const pstring &msg) noexcept
- {
- std::cerr << msg.c_str() << "\n";
- std::terminate();
- }
-
-
- //============================================================
- // Exceptions
- //============================================================
-
- pexception::pexception(const pstring &text)
- : m_text(text)
- {
- }
-
-
- file_e::file_e(const pstring &fmt, const pstring &filename)
- : pexception(pfmt(fmt)(filename))
- {
- }
-
-
- file_open_e::file_open_e(const pstring &filename)
- : file_e("File open failed: {}", filename)
- {
- }
-
-
- file_read_e::file_read_e(const pstring &filename)
- : file_e("File read failed: {}", filename)
- {
- }
-
-
- file_write_e::file_write_e(const pstring &filename)
- : file_e("File write failed: {}", filename)
+//============================================================
+// Exceptions
+//============================================================
+
+pexception::pexception(const pstring &text)
+: m_text(text)
+{
+}
+
+pexception::~pexception() noexcept
+{
+}
+
+file_e::file_e(const pstring &fmt, const pstring &filename)
+ : pexception(pfmt(fmt)(filename))
+{
+}
+
+file_e::~file_e() noexcept
+{
+}
+
+file_open_e::file_open_e(const pstring &filename)
+ : file_e("File open failed: {}", filename)
+{
+}
+
+file_open_e::~file_open_e() noexcept
+{
+
+}
+
+file_read_e::file_read_e(const pstring &filename)
+ : file_e("File read failed: {}", filename)
+{
+}
+
+file_read_e::~file_read_e() noexcept
+{
+
+}
+
+file_write_e::file_write_e(const pstring &filename)
+ : file_e("File write failed: {}", filename)
+{
+}
+
+file_write_e::~file_write_e() noexcept
+{
+}
+
+null_argument_e::null_argument_e(const pstring &argument)
+ : pexception(pfmt("Null argument passed: {}")(argument))
+{
+}
+
+null_argument_e::~null_argument_e() noexcept
+{
+}
+
+out_of_mem_e::out_of_mem_e(const pstring &location)
+ : pexception(pfmt("Out of memory: {}")(location))
+{
+}
+
+out_of_mem_e::~out_of_mem_e() noexcept
+{
+}
+
+fpexception_e::fpexception_e(const pstring &text)
+ : pexception(pfmt("Out of memory: {}")(text))
+{
+}
+
+fpexception_e::~fpexception_e() noexcept
+{
+}
+
+bool fpsignalenabler::m_enable = false;
+
+fpsignalenabler::fpsignalenabler(unsigned fpexceptions)
+{
+#if HAS_FEENABLE_EXCEPT
+ if (m_enable)
{
+ int b = 0;
+ if (fpexceptions & plib::FP_INEXACT) b = b | FE_INEXACT;
+ if (fpexceptions & plib::FP_DIVBYZERO) b = b | FE_DIVBYZERO;
+ if (fpexceptions & plib::FP_UNDERFLOW) b = b | FE_UNDERFLOW;
+ if (fpexceptions & plib::FP_OVERFLOW) b = b | FE_OVERFLOW;
+ if (fpexceptions & plib::FP_INVALID) b = b | FE_INVALID;
+ m_last_enabled = feenableexcept(b);
}
+#else
+ m_last_enabled = 0;
+#endif
+}
- null_argument_e::null_argument_e(const pstring &argument)
- : pexception(pfmt("Null argument passed: {}")(argument))
- {
- }
-
-
- out_of_mem_e::out_of_mem_e(const pstring &location)
- : pexception(pfmt("Out of memory: {}")(location))
- {
- }
-
-
- fpexception_e::fpexception_e(const pstring &text)
- : pexception(pfmt("Out of memory: {}")(text))
- {
- }
-
-
- bool fpsignalenabler::m_enable = false;
-
- fpsignalenabler::fpsignalenabler(unsigned fpexceptions)
- {
- #if HAS_FEENABLE_EXCEPT
- if (m_enable)
- {
- int b = 0;
- if (fpexceptions & plib::FP_INEXACT) b = b | FE_INEXACT;
- if (fpexceptions & plib::FP_DIVBYZERO) b = b | FE_DIVBYZERO;
- if (fpexceptions & plib::FP_UNDERFLOW) b = b | FE_UNDERFLOW;
- if (fpexceptions & plib::FP_OVERFLOW) b = b | FE_OVERFLOW;
- if (fpexceptions & plib::FP_INVALID) b = b | FE_INVALID;
- m_last_enabled = feenableexcept(b);
- }
- #else
- m_last_enabled = 0;
- #endif
- }
-
-
- fpsignalenabler::~fpsignalenabler()
+fpsignalenabler::~fpsignalenabler()
+{
+#if HAS_FEENABLE_EXCEPT
+ if (m_enable)
{
- #if HAS_FEENABLE_EXCEPT
- if (m_enable)
- {
- fedisableexcept(FE_ALL_EXCEPT); // Enable all floating point exceptions but FE_INEXACT
- feenableexcept(m_last_enabled); // Enable all floating point exceptions but FE_INEXACT
- }
- #endif
+ fedisableexcept(FE_ALL_EXCEPT); // Enable all floating point exceptions but FE_INEXACT
+ feenableexcept(m_last_enabled); // Enable all floating point exceptions but FE_INEXACT
}
+#endif
+}
- bool fpsignalenabler::supported()
- {
- return true;
- }
+bool fpsignalenabler::supported()
+{
+ return true;
+}
- bool fpsignalenabler::global_enable(bool enable)
- {
- bool old = m_enable;
- m_enable = enable;
- return old;
- }
+bool fpsignalenabler::global_enable(bool enable)
+{
+ bool old = m_enable;
+ m_enable = enable;
+ return old;
+}
-} // namespace plib
+}
diff --git a/src/lib/netlist/plib/pexception.h b/src/lib/netlist/plib/pexception.h
index 28a3ac1adf1..4827081b754 100644
--- a/src/lib/netlist/plib/pexception.h
+++ b/src/lib/netlist/plib/pexception.h
@@ -9,116 +9,118 @@
#define PEXCEPTION_H_
#include "pstring.h"
-#include "ptypes.h"
#include <exception>
namespace plib {
+//============================================================
+// exception base
+//============================================================
+
+class pexception : public std::exception
+{
+public:
+ explicit pexception(const pstring &text);
+ pexception(const pexception &e) : std::exception(e), m_text(e.m_text) { }
+
+ virtual ~pexception() noexcept;
+
+ const pstring &text() { return m_text; }
+ const char* what() const noexcept override { return m_text.c_str(); }
+
+private:
+ pstring m_text;
+};
+
+class file_e : public plib::pexception
+{
+public:
+ file_e(const pstring &fmt, const pstring &filename);
+ file_e(const file_e &e) : pexception(e) { }
+ virtual ~file_e() noexcept;
+};
+
+class file_open_e : public file_e
+{
+public:
+ explicit file_open_e(const pstring &filename);
+ file_open_e(const file_open_e &e) : file_e(e) { }
+ virtual ~file_open_e() noexcept;
+};
+
+class file_read_e : public file_e
+{
+public:
+ explicit file_read_e(const pstring &filename);
+ file_read_e(const file_read_e &e) : file_e(e) { }
+ virtual ~file_read_e() noexcept;
+};
+
+class file_write_e : public file_e
+{
+public:
+ explicit file_write_e(const pstring &filename);
+ file_write_e(const file_write_e &e) : file_e(e) { }
+ virtual ~file_write_e() noexcept;
+};
+
+class null_argument_e : public plib::pexception
+{
+public:
+ explicit null_argument_e(const pstring &argument);
+ null_argument_e(const null_argument_e &e) : pexception(e) { }
+ virtual ~null_argument_e() noexcept;
+};
+
+class out_of_mem_e : public plib::pexception
+{
+public:
+ explicit out_of_mem_e(const pstring &location);
+ out_of_mem_e(const out_of_mem_e &e) : pexception(e) { }
+ virtual ~out_of_mem_e() noexcept;
+};
+
+/* FIXME: currently only a stub for later use. More use could be added by
+ * using “-fnon-call-exceptions" and sigaction to enable c++ exception supported.
+ */
+
+class fpexception_e : public pexception
+{
+public:
+ explicit fpexception_e(const pstring &text);
+ fpexception_e(const fpexception_e &e) : pexception(e) { }
+ virtual ~fpexception_e() noexcept;
+};
+
+static constexpr unsigned FP_INEXACT = 0x0001;
+static constexpr unsigned FP_DIVBYZERO = 0x0002;
+static constexpr unsigned FP_UNDERFLOW = 0x0004;
+static constexpr unsigned FP_OVERFLOW = 0x0008;
+static constexpr unsigned FP_INVALID = 0x00010;
+static constexpr unsigned FP_ALL = 0x0001f;
+
+/*
+ * Catch SIGFPE on linux for debugging purposes.
+ */
+
+class fpsignalenabler
+{
+public:
+ explicit fpsignalenabler(unsigned fpexceptions);
+ ~fpsignalenabler();
+
+ /* is the functionality supported ? */
+ static bool supported();
+ /* returns last global enable state */
+ static bool global_enable(bool enable);
+
+private:
+ int m_last_enabled;
+
+ static bool m_enable;
+};
+
- //==========================================