summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/systemc/AUTHORS26
-rw-r--r--ext/systemc/ChangeLog51
-rw-r--r--ext/systemc/INSTALL765
-rw-r--r--ext/systemc/LICENSE202
-rw-r--r--ext/systemc/NEWS107
-rw-r--r--ext/systemc/NOTICE66
-rw-r--r--ext/systemc/README.gem5.md21
-rw-r--r--ext/systemc/README.md43
-rw-r--r--ext/systemc/README.sysc132
-rw-r--r--ext/systemc/RELEASENOTES685
-rw-r--r--ext/systemc/SConscript64
-rw-r--r--ext/systemc/src/README_TLM.txt33
-rw-r--r--ext/systemc/src/sysc/communication/sc_buffer.h194
-rw-r--r--ext/systemc/src/sysc/communication/sc_clock.cpp409
-rw-r--r--ext/systemc/src/sysc/communication/sc_clock.h275
-rw-r--r--ext/systemc/src/sysc/communication/sc_clock_ports.h72
-rw-r--r--ext/systemc/src/sysc/communication/sc_communication_ids.h164
-rw-r--r--ext/systemc/src/sysc/communication/sc_event_finder.cpp113
-rw-r--r--ext/systemc/src/sysc/communication/sc_event_finder.h178
-rw-r--r--ext/systemc/src/sysc/communication/sc_event_queue.cpp146
-rw-r--r--ext/systemc/src/sysc/communication/sc_event_queue.h181
-rw-r--r--ext/systemc/src/sysc/communication/sc_export.cpp305
-rw-r--r--ext/systemc/src/sysc/communication/sc_export.h299
-rw-r--r--ext/systemc/src/sysc/communication/sc_fifo.h479
-rw-r--r--ext/systemc/src/sysc/communication/sc_fifo_ifs.h209
-rw-r--r--ext/systemc/src/sysc/communication/sc_fifo_ports.h296
-rw-r--r--ext/systemc/src/sysc/communication/sc_host_mutex.h160
-rw-r--r--ext/systemc/src/sysc/communication/sc_interface.cpp100
-rw-r--r--ext/systemc/src/sysc/communication/sc_interface.h107
-rw-r--r--ext/systemc/src/sysc/communication/sc_mutex.cpp140
-rw-r--r--ext/systemc/src/sysc/communication/sc_mutex.h124
-rw-r--r--ext/systemc/src/sysc/communication/sc_mutex_if.h146
-rw-r--r--ext/systemc/src/sysc/communication/sc_port.cpp835
-rw-r--r--ext/systemc/src/sysc/communication/sc_port.h732
-rw-r--r--ext/systemc/src/sysc/communication/sc_prim_channel.cpp429
-rw-r--r--ext/systemc/src/sysc/communication/sc_prim_channel.h420
-rw-r--r--ext/systemc/src/sysc/communication/sc_semaphore.cpp148
-rw-r--r--ext/systemc/src/sysc/communication/sc_semaphore.h133
-rw-r--r--ext/systemc/src/sysc/communication/sc_semaphore_if.h100
-rw-r--r--ext/systemc/src/sysc/communication/sc_signal.cpp456
-rw-r--r--ext/systemc/src/sysc/communication/sc_signal.h741
-rw-r--r--ext/systemc/src/sysc/communication/sc_signal_ifs.h305
-rw-r--r--ext/systemc/src/sysc/communication/sc_signal_ports.cpp441
-rw-r--r--ext/systemc/src/sysc/communication/sc_signal_ports.h1931
-rw-r--r--ext/systemc/src/sysc/communication/sc_signal_resolved.cpp152
-rw-r--r--ext/systemc/src/sysc/communication/sc_signal_resolved.h153
-rw-r--r--ext/systemc/src/sysc/communication/sc_signal_resolved_ports.cpp107
-rw-r--r--ext/systemc/src/sysc/communication/sc_signal_resolved_ports.h349
-rw-r--r--ext/systemc/src/sysc/communication/sc_signal_rv.h255
-rw-r--r--ext/systemc/src/sysc/communication/sc_signal_rv_ports.h401
-rw-r--r--ext/systemc/src/sysc/communication/sc_writer_policy.h143
-rw-r--r--ext/systemc/src/sysc/datatypes/bit/sc_bit.cpp138
-rw-r--r--ext/systemc/src/sysc/datatypes/bit/sc_bit.h407
-rw-r--r--ext/systemc/src/sysc/datatypes/bit/sc_bit_ids.h106
-rw-r--r--ext/systemc/src/sysc/datatypes/bit/sc_bit_proxies.h3884
-rw-r--r--ext/systemc/src/sysc/datatypes/bit/sc_bv.h201
-rw-r--r--ext/systemc/src/sysc/datatypes/bit/sc_bv_base.cpp388
-rw-r--r--ext/systemc/src/sysc/datatypes/bit/sc_bv_base.h339
-rw-r--r--ext/systemc/src/sysc/datatypes/bit/sc_logic.cpp175
-rw-r--r--ext/systemc/src/sysc/datatypes/bit/sc_logic.h384
-rw-r--r--ext/systemc/src/sysc/datatypes/bit/sc_lv.h205
-rw-r--r--ext/systemc/src/sysc/datatypes/bit/sc_lv_base.cpp173
-rw-r--r--ext/systemc/src/sysc/datatypes/bit/sc_lv_base.h1827
-rw-r--r--ext/systemc/src/sysc/datatypes/bit/sc_proxy.h1609
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/fx.h61
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/sc_context.h316
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/sc_fix.h1938
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/sc_fixed.h660
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/sc_fx_ids.h96
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/sc_fxcast_switch.cpp88
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/sc_fxcast_switch.h174
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/sc_fxdefs.cpp175
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/sc_fxdefs.h308
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/sc_fxnum.cpp958
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/sc_fxnum.h5102
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/sc_fxnum_observer.cpp74
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/sc_fxnum_observer.h219
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/sc_fxtype_params.cpp108
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/sc_fxtype_params.h342
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/sc_fxval.cpp884
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/sc_fxval.h2269
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/sc_fxval_observer.cpp76
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/sc_fxval_observer.h223
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/sc_ufix.h1941
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/sc_ufixed.h660
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/scfx_ieee.h701
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/scfx_mant.cpp125
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/scfx_mant.h490
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/scfx_other_defs.h433
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/scfx_params.h222
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/scfx_pow10.cpp147
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/scfx_pow10.h95
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/scfx_rep.cpp2926
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/scfx_rep.h842
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/scfx_string.h232
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/scfx_utils.cpp176
-rw-r--r--ext/systemc/src/sysc/datatypes/fx/scfx_utils.h534
-rw-r--r--ext/systemc/src/sysc/datatypes/int/sc_bigint.h271
-rw-r--r--ext/systemc/src/sysc/datatypes/int/sc_biguint.h272
-rw-r--r--ext/systemc/src/sysc/datatypes/int/sc_int.h312
-rw-r--r--ext/systemc/src/sysc/datatypes/int/sc_int32_mask.cpp665
-rw-r--r--ext/systemc/src/sysc/datatypes/int/sc_int64_io.cpp182
-rw-r--r--ext/systemc/src/sysc/datatypes/int/sc_int64_mask.cpp4502
-rw-r--r--ext/systemc/src/sysc/datatypes/int/sc_int_base.cpp749
-rw-r--r--ext/systemc/src/sysc/datatypes/int/sc_int_base.h1382
-rw-r--r--ext/systemc/src/sysc/datatypes/int/sc_int_ids.h80
-rw-r--r--ext/systemc/src/sysc/datatypes/int/sc_length_param.cpp97
-rw-r--r--ext/systemc/src/sysc/datatypes/int/sc_length_param.h203
-rw-r--r--ext/systemc/src/sysc/datatypes/int/sc_nbcommon.inc2989
-rw-r--r--ext/systemc/src/sysc/datatypes/int/sc_nbdefs.cpp93
-rw-r--r--ext/systemc/src/sysc/datatypes/int/sc_nbdefs.h282
-rw-r--r--ext/systemc/src/sysc/datatypes/int/sc_nbexterns.cpp894
-rw-r--r--ext/systemc/src/sysc/datatypes/int/sc_nbexterns.h123
-rw-r--r--ext/systemc/src/sysc/datatypes/int/sc_nbfriends.inc727
-rw-r--r--ext/systemc/src/sysc/datatypes/int/sc_nbutils.cpp1892
-rw-r--r--ext/systemc/src/sysc/datatypes/int/sc_nbutils.h1051
-rw-r--r--ext/systemc/src/sysc/datatypes/int/sc_signed.cpp4134
-rw-r--r--ext/systemc/src/sysc/datatypes/int/sc_signed.h2382
-rw-r--r--ext/systemc/src/sysc/datatypes/int/sc_signed_bitref.inc163
-rw-r--r--ext/systemc/src/sysc/datatypes/int/sc_signed_subref.inc408
-rw-r--r--ext/systemc/src/sysc/datatypes/int/sc_uint.h312
-rw-r--r--ext/systemc/src/sysc/datatypes/int/sc_uint_base.cpp727
-rw-r--r--ext/systemc/src/sysc/datatypes/int/sc_uint_base.h1352
-rw-r--r--ext/systemc/src/sysc/datatypes/int/sc_unsigned.cpp2240
-rw-r--r--ext/systemc/src/sysc/datatypes/int/sc_unsigned.h2191
-rw-r--r--ext/systemc/src/sysc/datatypes/int/sc_unsigned_bitref.inc162
-rw-r--r--ext/systemc/src/sysc/datatypes/int/sc_unsigned_subref.inc407
-rw-r--r--ext/systemc/src/sysc/datatypes/misc/sc_concatref.cpp59
-rw-r--r--ext/systemc/src/sysc/datatypes/misc/sc_concatref.h855
-rw-r--r--ext/systemc/src/sysc/datatypes/misc/sc_value_base.cpp138
-rw-r--r--ext/systemc/src/sysc/datatypes/misc/sc_value_base.h129
-rw-r--r--ext/systemc/src/sysc/kernel/sc_attribute.cpp191
-rw-r--r--ext/systemc/src/sysc/kernel/sc_attribute.h209
-rw-r--r--ext/systemc/src/sysc/kernel/sc_boost.h94
-rw-r--r--ext/systemc/src/sysc/kernel/sc_cmnhdr.h138
-rw-r--r--ext/systemc/src/sysc/kernel/sc_constants.h82
-rw-r--r--ext/systemc/src/sysc/kernel/sc_cor.h157
-rw-r--r--ext/systemc/src/sysc/kernel/sc_cor_fiber.cpp224
-rw-r--r--ext/systemc/src/sysc/kernel/sc_cor_fiber.h169
-rw-r--r--ext/systemc/src/sysc/kernel/sc_cor_pthread.cpp313
-rw-r--r--ext/systemc/src/sysc/kernel/sc_cor_pthread.h157
-rw-r--r--ext/systemc/src/sysc/kernel/sc_cor_qt.cpp271
-rw-r--r--ext/systemc/src/sysc/kernel/sc_cor_qt.h154
-rw-r--r--ext/systemc/src/sysc/kernel/sc_cthread_process.cpp123
-rw-r--r--ext/systemc/src/sysc/kernel/sc_cthread_process.h144
-rw-r--r--ext/systemc/src/sysc/kernel/sc_dynamic_processes.h67
-rw-r--r--ext/systemc/src/sysc/kernel/sc_event.cpp759
-rw-r--r--ext/systemc/src/sysc/kernel/sc_event.h884
-rw-r--r--ext/systemc/src/sysc/kernel/sc_except.cpp142
-rw-r--r--ext/systemc/src/sysc/kernel/sc_except.h178
-rw-r--r--ext/systemc/src/sysc/kernel/sc_externs.h65
-rw-r--r--ext/systemc/src/sysc/kernel/sc_join.cpp143
-rw-r--r--ext/systemc/src/sysc/kernel/sc_join.h136
-rw-r--r--ext/systemc/src/sysc/kernel/sc_kernel_ids.h321
-rw-r--r--ext/systemc/src/sysc/kernel/sc_macros.h136
-rw-r--r--ext/systemc/src/sysc/kernel/sc_main.cpp58
-rw-r--r--ext/systemc/src/sysc/kernel/sc_main_main.cpp167
-rw-r--r--ext/systemc/src/sysc/kernel/sc_method_process.cpp1023
-rw-r--r--ext/systemc/src/sysc/kernel/sc_method_process.h467
-rw-r--r--ext/systemc/src/sysc/kernel/sc_module.cpp846
-rw-r--r--ext/systemc/src/sysc/kernel/sc_module.h583
-rw-r--r--ext/systemc/src/sysc/kernel/sc_module_name.cpp123
-rw-r--r--ext/systemc/src/sysc/kernel/sc_module_name.h140
-rw-r--r--ext/systemc/src/sysc/kernel/sc_module_registry.cpp184
-rw-r--r--ext/systemc/src/sysc/kernel/sc_module_registry.h124
-rw-r--r--ext/systemc/src/sysc/kernel/sc_name_gen.cpp109
-rw-r--r--ext/systemc/src/sysc/kernel/sc_name_gen.h93
-rw-r--r--ext/systemc/src/sysc/kernel/sc_object.cpp568
-rw-r--r--ext/systemc/src/sysc/kernel/sc_object.h244
-rw-r--r--ext/systemc/src/sysc/kernel/sc_object_int.h99
-rw-r--r--ext/systemc/src/sysc/kernel/sc_object_manager.cpp462
-rw-r--r--ext/systemc/src/sysc/kernel/sc_object_manager.h139
-rw-r--r--ext/systemc/src/sysc/kernel/sc_phase_callback_registry.cpp301
-rw-r--r--ext/systemc/src/sysc/kernel/sc_phase_callback_registry.h276
-rw-r--r--ext/systemc/src/sysc/kernel/sc_process.cpp854
-rw-r--r--ext/systemc/src/sysc/kernel/sc_process.h887
-rw-r--r--ext/systemc/src/sysc/kernel/sc_process_handle.h608
-rw-r--r--ext/systemc/src/sysc/kernel/sc_reset.cpp440
-rw-r--r--ext/systemc/src/sysc/kernel/sc_reset.h164
-rw-r--r--ext/systemc/src/sysc/kernel/sc_runnable.h144
-rw-r--r--ext/systemc/src/sysc/kernel/sc_runnable_int.h574
-rw-r--r--ext/systemc/src/sysc/kernel/sc_sensitive.cpp959
-rw-r--r--ext/systemc/src/sysc/kernel/sc_sensitive.h306
-rw-r--r--ext/systemc/src/sysc/kernel/sc_simcontext.cpp2284
-rw-r--r--ext/systemc/src/sysc/kernel/sc_simcontext.h903
-rw-r--r--ext/systemc/src/sysc/kernel/sc_simcontext_int.h365
-rw-r--r--ext/systemc/src/sysc/kernel/sc_spawn.h337
-rw-r--r--ext/systemc/src/sysc/kernel/sc_spawn_options.cpp124
-rw-r--r--ext/systemc/src/sysc/kernel/sc_spawn_options.h161
-rw-r--r--ext/systemc/src/sysc/kernel/sc_status.h83
-rw-r--r--ext/systemc/src/sysc/kernel/sc_thread_process.cpp1127
-rw-r--r--ext/systemc/src/sysc/kernel/sc_thread_process.h635
-rw-r--r--ext/systemc/src/sysc/kernel/sc_time.cpp465
-rw-r--r--ext/systemc/src/sysc/kernel/sc_time.h414
-rw-r--r--ext/systemc/src/sysc/kernel/sc_ver.cpp228
-rw-r--r--ext/systemc/src/sysc/kernel/sc_ver.h186
-rw-r--r--ext/systemc/src/sysc/kernel/sc_wait.cpp446
-rw-r--r--ext/systemc/src/sysc/kernel/sc_wait.h277
-rw-r--r--ext/systemc/src/sysc/kernel/sc_wait_cthread.cpp169
-rw-r--r--ext/systemc/src/sysc/kernel/sc_wait_cthread.h126
-rw-r--r--ext/systemc/src/sysc/qt/CHANGES15
-rw-r--r--ext/systemc/src/sysc/qt/INSTALL81
-rw-r--r--ext/systemc/src/sysc/qt/README89
-rw-r--r--ext/systemc/src/sysc/qt/README.MISC56
-rw-r--r--ext/systemc/src/sysc/qt/README.PORT112
-rw-r--r--ext/systemc/src/sysc/qt/b.h11
-rwxr-xr-xext/systemc/src/sysc/qt/config392
-rw-r--r--ext/systemc/src/sysc/qt/copyright.h12
-rw-r--r--ext/systemc/src/sysc/qt/md/axp.1.Makefile5
-rw-r--r--ext/systemc/src/sysc/qt/md/axp.2.Makefile5
-rw-r--r--ext/systemc/src/sysc/qt/md/axp.Makefile5
-rw-r--r--ext/systemc/src/sysc/qt/md/axp.README10
-rw-r--r--ext/systemc/src/sysc/qt/md/axp.c133
-rw-r--r--ext/systemc/src/sysc/qt/md/axp.h160
-rw-r--r--ext/systemc/src/sysc/qt/md/axp.s160
-rw-r--r--ext/systemc/src/sysc/qt/md/axp_b.s111
-rw-r--r--ext/systemc/src/sysc/qt/md/default.Makefile8
-rw-r--r--ext/systemc/src/sysc/qt/md/hppa-cnx.Makefile9
-rw-r--r--ext/systemc/src/sysc/qt/md/hppa.Makefile12
-rw-r--r--ext/systemc/src/sysc/qt/md/hppa.h196
-rw-r--r--ext/systemc/src/sysc/qt/md/hppa.s237
-rw-r--r--ext/systemc/src/sysc/qt/md/hppa_b.s203
-rw-r--r--ext/systemc/src/sysc/qt/md/i386.README7
-rw-r--r--ext/systemc/src/sysc/qt/md/i386.h132
-rw-r--r--ext/systemc/src/sysc/qt/md/i386.s119
-rw-r--r--ext/systemc/src/sysc/qt/md/i386_b.s30
-rw-r--r--ext/systemc/src/sysc/qt/md/iX86_64.h140
-rw-r--r--ext/systemc/src/sysc/qt/md/iX86_64.s74
-rw-r--r--ext/systemc/src/sysc/qt/md/ksr1.Makefile6
-rw-r--r--ext/systemc/src/sysc/qt/md/ksr1.h164
-rw-r--r--ext/systemc/src/sysc/qt/md/ksr1.s424
-rw-r--r--ext/systemc/src/sysc/qt/md/ksr1_b.s49
-rw-r--r--ext/systemc/src/sysc/qt/md/m88k.Makefile6
-rw-r--r--ext/systemc/src/sysc/qt/md/m88k.c111
-rw-r--r--ext/systemc/src/sysc/qt/md/m88k.h159
-rw-r--r--ext/systemc/src/sysc/qt/md/m88k.s132
-rw-r--r--ext/systemc/src/sysc/qt/md/m88k_b.s117
-rw-r--r--ext/systemc/src/sysc/qt/md/mips-irix5.s182
-rw-r--r--ext/systemc/src/sysc/qt/md/mips.h134
-rw-r--r--ext/systemc/src/sysc/qt/md/mips.s164
-rw-r--r--ext/systemc/src/sysc/qt/md/mips_b.s99
-rw-r--r--ext/systemc/src/sysc/qt/md/null.README0
-rw-r--r--ext/systemc/src/sysc/qt/md/null.c14
-rw-r--r--ext/systemc/src/sysc/qt/md/null.s12
-rw-r--r--ext/systemc/src/sysc/qt/md/powerpc.README27
-rw-r--r--ext/systemc/src/sysc/qt/md/powerpc.c69
-rw-r--r--ext/systemc/src/sysc/qt/md/powerpc_mach.h611
-rw-r--r--ext/systemc/src/sysc/qt/md/powerpc_mach.s641
-rw-r--r--ext/systemc/src/sysc/qt/md/powerpc_mach_b.s290
-rw-r--r--ext/systemc/src/sysc/qt/md/powerpc_sys5.h566
-rw-r--r--ext/systemc/src/sysc/qt/md/powerpc_sys5.s639
-rw-r--r--ext/systemc/src/sysc/qt/md/powerpc_sys5_b.s290
-rw-r--r--ext/systemc/src/sysc/qt/md/pthreads.Makefile108
-rw-r--r--ext/systemc/src/sysc/qt/md/solaris.README19
-rw-r--r--ext/systemc/src/sysc/qt/md/sparc.h140
-rw-r--r--ext/systemc/src/sysc/qt/md/sparc.s142
-rw-r--r--ext/systemc/src/sysc/qt/md/sparc_b.s106
-rw-r--r--ext/systemc/src/sysc/qt/md/vax.h130
-rw-r--r--ext/systemc/src/sysc/qt/md/vax.s69
-rw-r--r--ext/systemc/src/sysc/qt/md/vax_b.s92
-rw-r--r--ext/systemc/src/sysc/qt/meas.c1049
-rw-r--r--ext/systemc/src/sysc/qt/qt.c56
-rw-r--r--ext/systemc/src/sysc/qt/qt.h192
-rw-r--r--ext/systemc/src/sysc/qt/qtmd.h13
-rw-r--r--ext/systemc/src/sysc/qt/stp.c199
-rw-r--r--ext/systemc/src/sysc/qt/stp.h51
-rw-r--r--ext/systemc/src/sysc/qt/time/README.time17
-rwxr-xr-xext/systemc/src/sysc/qt/time/assim42
-rwxr-xr-xext/systemc/src/sysc/qt/time/cswap37
-rwxr-xr-xext/systemc/src/sysc/qt/time/go43
-rwxr-xr-xext/systemc/src/sysc/qt/time/init42
-rwxr-xr-xext/systemc/src/sysc/qt/time/prim41
-rwxr-xr-xext/systemc/src/sysc/qt/time/raw58
-rw-r--r--ext/systemc/src/sysc/systemc.pc.in41
-rw-r--r--ext/systemc/src/sysc/tracing/sc_trace.cpp217
-rw-r--r--ext/systemc/src/sysc/tracing/sc_trace.h397
-rw-r--r--ext/systemc/src/sysc/tracing/sc_trace_file_base.cpp273
-rw-r--r--ext/systemc/src/sysc/tracing/sc_trace_file_base.h140
-rw-r--r--ext/systemc/src/sysc/tracing/sc_tracing_ids.h79
-rw-r--r--ext/systemc/src/sysc/tracing/sc_vcd_trace.cpp2175
-rw-r--r--ext/systemc/src/sysc/tracing/sc_vcd_trace.h228
-rw-r--r--ext/systemc/src/sysc/tracing/sc_wif_trace.cpp1911
-rw-r--r--ext/systemc/src/sysc/tracing/sc_wif_trace.h222
-rw-r--r--ext/systemc/src/sysc/utils/sc_hash.cpp670
-rw-r--r--ext/systemc/src/sysc/utils/sc_hash.h460
-rw-r--r--ext/systemc/src/sysc/utils/sc_iostream.h91
-rw-r--r--ext/systemc/src/sysc/utils/sc_list.cpp343
-rw-r--r--ext/systemc/src/sysc/utils/sc_list.h188
-rw-r--r--ext/systemc/src/sysc/utils/sc_machine.h81
-rw-r--r--ext/systemc/src/sysc/utils/sc_mempool.cpp338
-rw-r--r--ext/systemc/src/sysc/utils/sc_mempool.h93
-rw-r--r--ext/systemc/src/sysc/utils/sc_pq.cpp133
-rw-r--r--ext/systemc/src/sysc/utils/sc_pq.h154
-rw-r--r--ext/systemc/src/sysc/utils/sc_pvector.h187
-rw-r--r--ext/systemc/src/sysc/utils/sc_report.cpp330
-rw-r--r--ext/systemc/src/sysc/utils/sc_report.h299
-rw-r--r--ext/systemc/src/sysc/utils/sc_report_handler.cpp799
-rw-r--r--ext/systemc/src/sysc/utils/sc_report_handler.h197
-rw-r--r--ext/systemc/src/sysc/utils/sc_stop_here.cpp124
-rw-r--r--ext/systemc/src/sysc/utils/sc_stop_here.h82
-rw-r--r--ext/systemc/src/sysc/utils/sc_string.cpp612
-rw-r--r--ext/systemc/src/sysc/utils/sc_string.h254
-rw-r--r--ext/systemc/src/sysc/utils/sc_temporary.h228
-rw-r--r--ext/systemc/src/sysc/utils/sc_utils_ids.cpp147
-rw-r--r--ext/systemc/src/sysc/utils/sc_utils_ids.h113
-rw-r--r--ext/systemc/src/sysc/utils/sc_vector.cpp178
-rw-r--r--ext/systemc/src/sysc/utils/sc_vector.h724
-rw-r--r--ext/systemc/src/systemc128
-rw-r--r--ext/systemc/src/systemc.h348
-rw-r--r--ext/systemc/src/tlm33
-rw-r--r--ext/systemc/src/tlm.h22
-rw-r--r--ext/systemc/src/tlm_core/tlm.pc.in38
-rw-r--r--ext/systemc/src/tlm_core/tlm_1/README.txt97
-rw-r--r--ext/systemc/src/tlm_core/tlm_1/tlm_analysis/tlm_analysis.h33
-rw-r--r--ext/systemc/src/tlm_core/tlm_1/tlm_analysis/tlm_analysis_fifo.h54
-rw-r--r--ext/systemc/src/tlm_core/tlm_1/tlm_analysis/tlm_analysis_if.h39
-rw-r--r--ext/systemc/src/tlm_core/tlm_1/tlm_analysis/tlm_analysis_port.h84
-rw-r--r--ext/systemc/src/tlm_core/tlm_1/tlm_analysis/tlm_analysis_triple.h53
-rw-r--r--ext/systemc/src/tlm_core/tlm_1/tlm_analysis/tlm_write_if.h42
-rw-r--r--ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_core_ifs.h149
-rw-r--r--ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_fifo_ifs.h85
-rw-r--r--ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_master_slave_ifs.h73
-rw-r--r--ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_tag.h31
-rw-r--r--ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_adapters/tlm_adapters.h105
-rw-r--r--ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/circular_buffer.h268
-rw-r--r--ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo.h263
-rw-r--r--ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_peek.h98
-rw-r--r--ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_put_get.h140
-rw-r--r--ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_resize.h93
-rw-r--r--ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_req_rsp_channels/tlm_put_get_imp.h114
-rw-r--r--ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_req_rsp_channels/tlm_req_rsp_channels.h155
-rw-r--r--ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_ports/tlm_event_finder.h94
-rw-r--r--ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_ports/tlm_nonblocking_port.h91
-rw-r--r--ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_req_rsp.h37
-rw-r--r--ext/systemc/src/tlm_core/tlm_2/README.txt111
-rw-r--r--ext/systemc/src/tlm_core/tlm_2/tlm_2_interfaces/tlm_2_interfaces.h27
-rw-r--r--ext/systemc/src/tlm_core/tlm_2/tlm_2_interfaces/tlm_dmi.h114
-rw-r--r--ext/systemc/src/tlm_core/tlm_2/tlm_2_interfaces/tlm_fw_bw_ifs.h223
-rw-r--r--ext/systemc/src/tlm_core/tlm_2/tlm_generic_payload/tlm_array.h125
-rw-r--r--ext/systemc/src/tlm_core/tlm_2/tlm_generic_payload/tlm_endian_conv.h792
-rw-r--r--ext/systemc/src/tlm_core/tlm_2/tlm_generic_payload/tlm_generic_payload.h29
-rw-r--r--ext/systemc/src/tlm_core/tlm_2/tlm_generic_payload/tlm_gp.h642
-rw-r--r--ext/systemc/src/tlm_core/tlm_2/tlm_generic_payload/tlm_helpers.h80
-rw-r--r--ext/systemc/src/tlm_core/tlm_2/tlm_generic_payload/tlm_phase.h87
-rw-r--r--ext/systemc/src/tlm_core/tlm_2/tlm_quantum/tlm_global_quantum.h97
-rw-r--r--ext/systemc/src/tlm_core/tlm_2/tlm_quantum/tlm_quantum.h25
-rw-r--r--ext/systemc/src/tlm_core/tlm_2/tlm_sockets/tlm_initiator_socket.h252
-rw-r--r--ext/systemc/src/tlm_core/tlm_2/tlm_sockets/tlm_sockets.h26
-rw-r--r--ext/systemc/src/tlm_core/tlm_2/tlm_sockets/tlm_target_socket.h275
-rw-r--r--ext/systemc/src/tlm_core/tlm_2/tlm_version.h180
-rw-r--r--ext/systemc/src/tlm_utils/README.txt85
-rw-r--r--ext/systemc/src/tlm_utils/instance_specific_extensions.h306
-rw-r--r--ext/systemc/src/tlm_utils/multi_passthrough_initiator_socket.h299
-rw-r--r--ext/systemc/src/tlm_utils/multi_passthrough_target_socket.h340
-rw-r--r--ext/systemc/src/tlm_utils/multi_socket_bases.h418
-rw-r--r--ext/systemc/src/tlm_utils/passthrough_target_socket.h479
-rw-r--r--ext/systemc/src/tlm_utils/peq_with_cb_and_phase.h301
-rw-r--r--ext/systemc/src/tlm_utils/peq_with_get.h94
-rw-r--r--ext/systemc/src/tlm_utils/simple_initiator_socket.h292
-rw-r--r--ext/systemc/src/tlm_utils/simple_target_socket.h1114
-rwxr-xr-xext/systemc/src/tlm_utils/tlm2_base_protocol_checker.h1055
-rw-r--r--ext/systemc/src/tlm_utils/tlm_quantumkeeper.h172
362 files changed, 138299 insertions, 0 deletions
diff --git a/ext/systemc/AUTHORS b/ext/systemc/AUTHORS
new file mode 100644
index 000000000..c19bf35aa
--- /dev/null
+++ b/ext/systemc/AUTHORS
@@ -0,0 +1,26 @@
+
+ Authors of SystemC
+ ------------------
+
+ John Aynsley Doulos, Inc.
+ Bishnupriya Bhattacharya Cadence Design Systems, Inc.
+ David Black Doulos, Inc.
+ Gene Bushuyev Synopsys, Inc.
+ Jerome Cornet STMicroelectronics
+ Ali Dasdan Synopsys, Inc.
+ Alan Fitch Doulos, Inc.
+ Abhijit Ghosh Synopsys, Inc.
+ Andy Goodrich Forte Design Systems, Inc.
+ Philipp A.Hartmann OFFIS Institute for Information Technology
+ Ulrich Holtmann Synopsys, Inc.
+ Martin Janssen Synopsys, Inc.
+ Vijay Kumar CoWare, Inc.
+ Stan Y. Liao Synopsys, Inc.
+ David Long Doulos, Inc.
+ Torsten Maehne Université Pierre et Marie Curie, Paris
+ Eric Paire STMicroelectronics
+ Cesar Quiroz CoWare, Inc.
+ Amit Rao Synopsys, Inc.
+ Harish Sarin CoWare, Inc.
+ Stuart Swan Cadence Design Systems, Inc.
+ Dirk Vermeersch CoWare, Inc.
diff --git a/ext/systemc/ChangeLog b/ext/systemc/ChangeLog
new file mode 100644
index 000000000..cdd59ddc0
--- /dev/null
+++ b/ext/systemc/ChangeLog
@@ -0,0 +1,51 @@
+See also docs/tlm/ChangeLog.
+
+2014-04-17 Philipp A. Hartmann <philipp.hartmann@offis.de>
+
+ * Combined SystemC 2.3.1 / TLM 2.0.3 officially released.
+
+2012-07-01 Andy Goodrich <acg@forteds.com>
+
+ * Combined SystemC 2.3.0 / TLM-2.0.2 officially released.
+
+2007-03-14 Andy Goodrich <acg@forteds.com>
+
+ * SystemC 2.2 released.
+
+2006-06-05 Andy Goodrich <acg@forteds.com>
+
+ * SystemC 2.2 Beta released to the public.
+
+2005-07-14 Andy Goodrich <acg@forteds.com>
+
+ * SystemC 2.1v1 released.
+
+2003-12-02 Andy Goodrich <acg@forteds.com>
+
+ * SystemC 2.1 Beta-7 released.
+
+2003-06-13 Andy Goodrich <acg@forteds.com>
+
+ * SystemC 2.1 Beta-1 released.
+
+2002-04-05 Martin Janssen <martin.janssen@synopsys.com>
+
+ * SystemC 2.0.1 released.
+
+2001-10-05 Martin Janssen <mjanssen@synopsys.com>
+
+ * SystemC 2.0 released.
+
+2001-09-05 Martin Janssen <mjanssen@synopsys.com>
+
+ * SystemC 2.0 Beta-2 released.
+
+2001-07-13 Martin Janssen <mjanssen@synopsys.com>
+
+ * SystemC 2.0 Beta-1 released.
+
+2001-02-23 Release 1.0.2 of SystemC
+2000-09-26 Release 1.0.1 of SystemC
+2000-03-28 Release 1.0 of SystemC
+2000-01-31 Release 0.91 of SystemC
+1999-09-27 Release 0.9 of SystemC
diff --git a/ext/systemc/INSTALL b/ext/systemc/INSTALL
new file mode 100644
index 000000000..a5231d489
--- /dev/null
+++ b/ext/systemc/INSTALL
@@ -0,0 +1,765 @@
+ INSTALL NOTES FOR SystemC Release 2.3
+ -------------------------------------
+
+Contents:
+
+ 1. Installation Notes for Unix
+
+ 2. Installation Notes for Windows
+
+ 3. SystemC Library Configuration Switches
+
+
+1. Installation Notes for Unix
+------------------------------
+
+
+System Requirements
+===================
+
+SystemC can be installed on the following UNIX, or UNIX-like platforms:
+
+ o Linux
+ * Architectures
+ - x86 (32-bit)
+ - x86_64 (64-bit)
+ - x86 (32-bit) application running on x86_64 (64-bit) kernel
+ (../configure --host=i686-linux-gnu)
+ * Compilers
+ - GNU C++ compiler
+ - Clang C++ compiler
+ - or compatible
+
+ o Mac OS X
+ * Architectures
+ - x86 (32-bit)
+ - x86_64 (64-bit)
+ - powerpc (32-bit) [deprecated]
+ - powerpc64 (64-bit) [deprecated]
+ * Compilers
+ - GNU C++ compiler
+ - Clang C++ compiler
+ - or compatible
+
+ o Solaris
+ * Architectures
+ - SPARC (32-bit)
+ * Compilers
+ - GNU C++ compiler
+ - Sun/Solaris Studio
+
+ o BSD
+ * Architectures
+ - x86 (32-bit)
+ - x86_64 (64-bit)
+ * Compilers
+ - GNU C++ compiler
+ - Clang C++ compiler
+ - or compatible
+
+ o Windows
+ * Compatibility layer
+ - Cygwin
+ - MinGW / MSYS
+ * Architectures
+ - x86 (32-bit)
+ - x86_64 (64-bit)
+ * Compilers
+ - GNU C++ compiler
+ - or compatible
+
+Note: Not all combinations are equally well-tested and some combinations
+ may not work as expected. Please report your findings by following
+ the instructions in the README file.
+
+The README file contains a list of detailed platforms, architectures,
+and compiler versions that have been used for testing this release.
+
+
+Sources for Compilers and Related Tools
+=======================================
+
+To build, install, and use SystemC on UNIX platforms, you need
+the following tools:
+
+ 1. GNU C++ compiler, version 3.4 or later
+ or
+ Clang C++ compiler version 3.0 or later
+
+ 2. GNU Make (gmake)
+
+GCC, Clang, and gmake are free software that you can
+obtain from the following sources:
+
+ GCC http://www.gnu.org/software/gcc/gcc.html
+
+ Clang http://clang.llvm.org/
+
+ gmake http://www.gnu.org/software/make/make.html
+
+
+Basic SystemC Installation
+==========================
+
+To install SystemC on a UNIX system, do the following steps:
+
+ 1. Change to the top level directory (systemc-2.3.1)
+
+ 2. Create a temporary directory, e.g.,
+
+ > mkdir objdir
+
+ 3. Change to the temporary directory, e.g.,
+
+ > cd objdir
+
+ 4. Choose your compiler by setting the CXX environment variable
+ (the configure script tries to guess the default compiler, if
+ this step is omitted):
+
+ If you use a POSIX-compatible shell (e.g. bash):
+
+ > export CXX="<compiler>"
+
+ e.g. for GCC compilers
+
+ > export CXX=g++
+
+ The Clang compiler is usually named 'clang++', thus e.g.
+
+ > export CXX=clang++
+
+ When using a C shell (e.g. csh/tcsh), the syntax to set the
+ environment variable is different:
+
+ > setenv CXX g++
+
+ For the Sun/Solaris Studio compilers, use
+
+ > setenv CXX CC
+
+ You can also specify an absolute path to the compiler of your choice.
+
+ See also the Section "Compilation and Linking Options" below.
+
+
+ 5. Configure the package for your system, e.g.,
+ (The configure script is explained below.)
+
+ > ../configure
+
+ While the 'configure' script is running, which takes a few moments,
+ it prints messages to inform you of the features it is checking.
+ It also detects the platform.
+
+ Note for System V users:
+ If you are using `csh' on an older version of System V, you might
+ need to use the `sh ../configure' command instead of '../configure'.
+ Otherwise, `csh' will attempt to `configure' itself.
+
+ SystemC 2.3 includes a fixed-point package that is always built.
+ When compiling your applications with fixed-point types, you still have
+ to use compiler flag -DSC_INCLUDE_FX. Note that compile times increase
+ significantly when using this compiler flag.
+
+ In case you want to install the package in another place than the
+ top level directory (systemc-2.3.1), configure the package e.g. as
+ follows:
+
+ > ../configure --prefix=/usr/local/systemc-2.3.1
+
+ Note: make sure you have created the target directory before installing
+ the package. Do _not_ use /usr/local as a prefix, unless you
+ follow the Unix/FHS directory layouts (see below).
+
+ A fine grained configuration of the installation directories can
+ be achieved via additional options, given to the configure script.
+
+ By default, the files are installed directly to the PREFIX directory
+ root and the library is installed to PREFIX/lib-<TARGETARCH>,
+ depending on the current target architecture. This may be undesired
+ in cases where the package is meant to be installed in a system-wide
+ location as part of shared (default) library and include hierarchies
+ (e.g. /usr/local, /usr, /opt, ...). To follow the Unix/FHS directory
+ standards, you can use the following options:
+
+ --with-unix-layout use Unix directory layout for installation
+ [default=no]
+ when "yes", the following (fine-grained) settings will be used:
+
+ --includedir=DIR C++ header files [PREFIX/include]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/systemc]
+
+ The library destination itself can be further and separately configured
+ by using the following option:
+
+ --with-arch-suffix add suffix to library installation directory
+ [default=-<TARGETARCH>]
+
+ With this option, one can easily follow e.g. the "multi-arch"
+ conventions on some platforms:
+
+ ../configure --with-arch-suffix=32 # lib32
+ ../configure --with-arch-suffix=/x86_64-linux-gnu # lib/x86_64-linux-gnu
+
+
+
+ Several options are available to the configure script to modify
+ the compiler configuration and the selection of certain features:
+
+ --disable-shared do not build shared library (libsystemc.so)
+ --enable-debug include debugging symbols
+ --disable-optimize disable compiler optimization
+ --disable-async-updates disable request_async_update support
+ --enable-pthreads use POSIX threads for SystemC processes
+ --enable-phase-callbacks
+ enable simulation phase callbacks (experimental)
+
+
+ See the section on the general usage of the configure script and
+ "../configure --help" for more information.
+
+ Note: If you change the configuration after having compiled the
+ package already, you should run a "gmake clean" before
+ recompiling.
+
+ 6. Compile the package.
+
+ > gmake
+
+ Note: The explicit gmake targets "opt" and "debug", etc. have
+ been removed in this package. Use the corresponding
+ options to the configure script instead.
+
+ 7. At this point you may wish to verify the compiled package by
+ testing the example suite.
+
+ > gmake check
+
+ This will compile and run the examples in the subdirectory
+ examples.
+
+ 8. Install the package.
+
+ > gmake install
+
+ 9. You can now remove the temporary directory, .e.g,
+
+ > cd ..
+ > rm -rf objdir
+
+ Alternatively, you can keep the temporary directory to allow you to:
+
+ a) Experiment with the examples.
+
+ b) Later uninstall the package. To clean up the temporary
+ directory, enter:
+
+ > gmake clean
+
+ To uninstall the package, enter:
+
+ > gmake uninstall
+
+
+Running the Examples
+====================
+
+Copies of the examples reside in the temporary directory - see
+instruction 7 above for details on building and running them.
+
+In addition, a copy of the example code resides in the directory
+examples at the highest level of the installation (or in the
+shared documentation install directory).
+
+Use the makefiles provided in the 'examples' directory as templates
+for makefiles you need for compiling your own examples.
+
+
+Using the Configure Script
+==========================
+
+The `configure' shell script tries to determine the correct values for
+various system-dependent variables used during compilation. It uses
+these values to create a `Makefile' in each directory of the package.
+It also creates one or more `.h' files containing system-dependent
+definitions if needed. Then, it creates the following files:
+
+ config.status A shell script that you can run at another time to
+ recreate the current configuration.
+
+ config.cache A file in which the configure test results are
+ saved to speed up reconfiguration.
+
+ Data is appended to the config.cache file.
+ You can remove unwanted data.
+
+ config.log A file in which compiler output is saved.
+ This is used to debug the configure script.
+
+If you need to use other commands to successfully compile the package
+on your system, please try to determine if the configure script can be used
+for these commands. Then, send either a diff file or instructions about
+the commands you used to the email address provided in the README file.
+This information will be used to improve the installation process in
+the next release.
+
+The `configure.ac' file is provided in case you want to change or regenerate
+the `configure' script, for example to use a newer version of `autoconf'.
+The `configure.ac' file is used by the `autoconf' program to create the
+`configure' script.
+
+Note for (key) developers:
+
+ In case you have changed the `configure.ac' file or one of the
+ `Makefile.am' files:
+
+ - Use the `config/distclean' script to remove the generated `configure'
+ script, the generated `aclocal.m4' file and the generated `Makefile.in'
+ files.
+
+ - Use the `config/bootstrap' script to generate the `configure' script
+ and the necessary `Makefile.in' files. This script makes use of the
+ GNU auto-tools `aclocal', `automake', and `autoconf'.
+
+
+Compilation and Linking Options
+===============================
+
+Some systems require compilation or linking options that the `configure'
+script does not define. You can define the initial values for these
+options by setting them in your environment before running the
+`configure' script.
+
+Instead of passing the variables via the environment, it is preferred
+to pass the values as options to the configure script:
+
+ > ../configure CXX=g++-4.4 LIBS=-lposix
+
+
+Specifying the System Type
+==========================
+
+Some features cannot be automatically determined by `configure' unless
+it can detect the host type on which the package will run.
+If it prints a message that it cannot determine the host type,
+use the `--host=TYPE' option to define it. TYPE can either be a
+short system name, such as `sun4', or a canonical name with three fields:
+
+ CPU-COMPANY-SYSTEM
+
+See the `config.sub' file for details about the values of each field. If
+the `config.sub' file is not included in the package, the package does not
+need to know the host type.
+
+If you are building compiler tools for cross-compiling, you can also
+use the `--target=TYPE' option to select the type of system for which
+the code is produced and the `--build=TYPE' option to select the type of
+system on which you are compiling the package.
+
+
+Sharing Defaults
+================
+
+You can set the default values that `configure' scripts share by
+creating a site shell script called `config.site'. This file contains the
+default values for variables like `CC', `cache_file', and `prefix'.
+The `configure' script looks for the `config.site' file in the following
+search precedence:
+
+ 1. PREFIX/share/config.site
+
+ 2. PREFIX/etc/config.site
+
+Alternatively, you can set the `CONFIG_SITE' environment variable to the
+site script path.
+
+Note: The `configure' script for some systems does not look for a site script.
+
+
+Operation Controls
+==================
+
+The `configure' script recognizes the following additional options to control
+its operation:
+
+`--cache-file=FILE'
+ Use and save the test results in FILE instead of
+ `./config.cache'. Set FILE to `/dev/null' to disable caching
+ when debugging `configure'.
+
+`--help'
+ Print a summary of `configure' options and exit.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages about checks being made.
+ To suppress all normal output, redirect it to `/dev/null'.
+ Error messages continue to print.
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR.
+ Typically `configure' determines the directory automatically.
+
+`--version'
+ Print the version of `autoconf' used to generate the `configure'
+ script and exit.
+
+Other options that are rarely used are available in the `configure' script.
+Use the `--help' option to print a list.
+
+
+
+2. Installation Notes for Windows
+---------------------------------
+
+This release has been tested on Visual C++ versions 2005 through 2013,
+running on Windows 7.
+
+
+Note: This section covers the installation based on Microsoft Visual C++.
+ For Cygwin or MinGW-based installations, see Section 1.
+
+
+Note: If you experience spurious errors about missing files in the
+ downloaded archive, please make sure to either download the
+ ZIP archive from accellera.org or use a reliable archive software,
+ fully supporting modern tar archive versions.
+
+ Some paths in the SystemC archive are longer than the historical
+ 99 character limit, and several Windows archivers (e.g. WinZip)
+ have been reported to trip over this. The open source archiver
+ 7-zip (http://7-zip.org) is known to work.
+
+
+Microsoft Visual C++ 2005 (compiler version 8.0) or later
+---------------------------------------------------------
+
+The download directory contains two subdirectories: 'msvc80' and
+'examples'.
+
+The 'msvc80' directory contains the project and workspace files to
+compile the 'systemc.lib' library. Double-click on the 'SystemC.sln'
+file to launch Visual C++ 2005 with the workspace file. The workspace file
+will have the proper switches set to compile for Visual C++ 2005.
+Select `Build SystemC' under the Build menu or press F7 to build
+`systemc.lib'.
+
+The `examples' directory contains the project and workspace files to
+compile the SystemC examples. Go to one of the examples subdirectories
+and double-click on the .vcproj file to launch Visual C++ with the
+workspace file. The workspace file will have the proper switches set
+to compile for Visual C++ 2005. Select 'Build <example>.exe' under the
+Build menu or press F7 to build the example executable.
+
+For convenience, a combined solution file 'SystemC-examples.sln' with
+all example projects can be found in the 'msvc80' directory. A similar
+solution file for the TLM examples is located in 'examples/tlm/build-msvc'.
+
+The provided project files are prepared for both the 32-bit 'Win32' and
+64-bit 'x64' configurations. Please refer to the Microsoft Visual Studio
+documentation for details about 64-bit builds.
+
+
+Creating SystemC Applications
+-----------------------------
+
+1. Start Visual Studio. From the Start Page select New Project and Win32
+ Console Project. Type the project name and select a suitable location
+ then click OK.
+
+2. Select the Application Settings page of the Win32 Application Wizard
+ and make sure the 'Empty project' box is ticked. Click 'Finish' to
+ complete the wizard.
+
+3. Add new/existing C++ files to the project and edit code.
+
+4. Display the project Property Pages by selecting 'Properties...' from
+ the Project menu.
+
+5. From the C/C++ tab, select the General properties and set
+ 'Detect 64-bit Portability Issues' to No
+
+6. From the C/C++ tab, select the Language properties and set
+ 'Enable Run-Time Type Info' to Yes
+
+7. From the C/C++ tab, select the Command Line properties and add /vmg
+ to the 'Additional Options:' box.
+
+8. From the Linker tab, select the Input properties and type 'systemc.lib'
+ in the 'Additional Dependencies' box.
+
+9. Click OK
+
+
+Also make sure that the compiler and linker can find the SystemC header
+and library files respectively. There are two ways to do this:
+
+To update the include file and library directory search paths for all
+projects:
+
+1. Select Tools -> Options... and the Projects -> VC++ Directories tab
+
+2. Select show directories for: Library files
+
+3. Select the 'New' icon and browse to: C:\systemc-2.3.1\msvc80\systemc\debug
+
+4. Select show directories for: Include files
+
+5. Select the 'New' icon and browse to: C:\systemc-2.3.1\src
+
+To add the include file and library directory search paths for the current
+project only:
+
+1. Display the project Property Pages by selecting 'Properties...' from
+ the Project menu.
+
+2. From the C/C++ tab, select the General properties and type the path to the
+ SystemC 'src' directory in the text entry field labeled
+ 'Additional include directories' (e.g. the examples use '..\..\..\src').
+
+3. From the Linker tab, select the General properties and type the path to
+ the SystemC library: ...\systemc-2.3.1\msvc80\systemc\debug'systemc.lib'
+ in the 'Additional Library Directories:' box.
+
+9. Click OK
+
+
+
+
+3. SystemC Library Configuration Switches
+-----------------------------------------
+
+In addition to the explicitly selectable feature given as options to
+the `configure' script (see 1.), some aspects of the library
+implementation can be controlled via
+
+ - preprocessor switches given during library build
+ - preprocessor switches added while building a SystemC application
+ - environment variables
+
+The currently supported switches are documented in this section.
+
+Preprocessor switches
+=====================
+
+Additional preprocessor switches for the library build can be passed
+to the configure script via the CXXFLAGS variable:
+
+ ../configure CXXFLAGS="-DSC_OVERRIDE_DEFAULT_STACK_SIZE=0x80000"
+
+In Visual C++, the preprocessor symbols can be added to the project
+configuration via the 'C/C++' tab under the 'Preprocessor' properties
+in the 'Preprocessor definitions' setting.
+
+
+ * SC_DEFAULT_WRITER_POLICY=<sc_writer_policy> -
+ Override default value for the signal writer policy
+
+ This setting allows deactivating the multiple writer checks for
+ sc_signals at (application) compile time. This mechanism supersedes
+ the old environment variable SC_SIGNAL_WRITE_CHECK (see below).
+
+ Supported values:
+ SC_ONE_WRITER (default)
+ SC_MANY_WRITERS (allow multiple writers in different deltas)
+ SC_UNCHECKED_WRITERS (non-standard, disable all checks)
+
+ Note: Only effective when building an application.
+
+ Note: This setting needs to be consistently set across all
+ translation units of an application.
+
+
+ * SC_DISABLE_ASYNC_UPDATES -
+ Exclude the "async_request_update" support
+
+ Note: This option is usually set by the `configure` option
+ --disable-async-update, or
+ --enable-async-update=no
+
+ On non-Automake platforms (e.g. Visual C++), this preprocessor
+ symbol can be used to manually build the library with this feature.
+
+ Note: Only effective during library build.
+
+
+ * SC_DISABLE_VIRTUAL_BIND -
+ Keep the "bind" function of sc_ports non-virtual
+
+ When this symbol is defined, the "bind" function in sc_ports is
+ kept non-virtual (although it is required to be 'virtual' since
+ IEEE 1666-2011).
+
+ Note: This symbol needs to be consistently defined in the library
+ and any application linking against the built library.
+
+
+ * SC_DISABLE_COPYRIGHT_MESSAGE -
+ Do not print the copyright message when starting the application
+
+ Note: This does not remove the copyright from the binary.
+ sc_core::sc_copyright() still works as expected.
+ Note: Only effective during library build.
+ See : Environment variable SC_COPYRIGHT_MESSAGE
+
+
+ * SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS -
+ Allow a process to trigger itself immediately
+
+ Allow a method process to trigger itself immediately by using
+ next_trigger( ev ); // or a static sensitivity
+ ev.notify();
+
+ This behaviour has been disabled by default in IEEE 1666-2011 and
+ can be reenabled by this option.
+
+ Note: Only effective during library build.
+
+
+ * SC_ENABLE_EARLY_MAXTIME_CREATION -
+ Allow creation of sc_time objects with a value of sc_max_time()
+ before finalizing the time resolution
+
+ In IEEE 1666-2011, it is not allowed to create sc_time objects with
+ a non-SC_ZERO_TIME value before setting/changing the time resolution.
+
+ This preprocessor switch activates an extension to allow the
+ initialization of sc_time variables with sc_max_time() while
+ still accepting changes to the time resolution afterwards.
+
+ sc_time t = sc_max_time();
+ sc_set_time_resolution( 1, SC_NS ); // OK, with this extension
+
+ The time resolution will still be fixed, once you have explicitly or
+ implicitly relied on the physical value (i.e. the relation to seconds)
+ of any sc_time object.
+
+ Note: Only effective during library build.
+
+
+ * SC_ENABLE_SIMULATION_PHASE_CALLBACKS (experimental)
+ SC_ENABLE_SIMULATION_PHASE_CALLBACKS_TRACING (experimental) -
+ Enable a generic simulation phase callback mechanism.
+
+ Note: This option is usually set by the `configure` option
+ --enable-phase-callbacks, or
+ --enable-phase-callbacks=tracing
+
+ See the RELEASENOTES for more information about this feature.
+
+ The *_TRACING variant of this flag enables the sc_trace
+ implementation use these callbacks, instead of hard-coded updates
+ from the main simulator loop.
+
+ Note: Setting tracing flag includes the generic phase callback
+ infrastructure automatically.
+ Note: Only effective during library build.
+
+
+ * SC_INCLUDE_DYNAMIC_PROCESSES -
+ Enable dynamic process support (sc_spawn, sc_bind)
+
+ To improve compilation times, the functions for spawing dynamic
+ processes are not included by default in an SystemC application.
+
+ Define this symbol before including the SystemC header in your
+ application, if you want to use dynamically spawned processes.
+
+ Note: Can be optionally set per translation unit in an application.
+
+ Note: Some TLM convenience sockets require this feature and define
+ the symbol for you if needed.
+
+
+ * SC_INCLUDE_FX -
+ Enable SystemC fix-point datatypes
+
+ To improve compilation times, the fixpoint datatypes are not enabled
+ by default in an SystemC application.
+
+ Define this symbol before including the SystemC header in your
+ application, if you want to use the SystemC fixpoint types.
+
+ Note: Is by default always defined during the library build to enable
+ later use of the fixpoint datatypes in an application.
+
+ Note: Can be optionally set per translation unit in an application.
+
+
+ * SC_INCLUDE_STRSTREAM -
+ Include (deprecated) <strstream> header from <systemc.h>
+
+ Pre-standard C++ compilers had support for an old stringstream
+ implementation called 'strstream'. In the unlikely case that your
+ application still relies on this deprecated class and that <systemc.h>
+ includes this header for you automatically, you now need to define this
+ symbol when building your application.
+
+ Note: Only effective when building an application.
+
+
+ * SC_INCLUDE_WINDOWS_H -
+ Explicitly include <windows.h> header from <systemc> header
+
+ Previous versions of SystemC always included the full <windows.h>
+ header on all Windows platforms. This adds unnecessary bloat to
+ many SystemC applications, reducing compilation times.
+
+ If you rely on the inclusion of the <windows.h> header in your
+ application, you can add this symbol to the list of preprocessor
+ switches for your compiler.
+
+ Note: Only effective when building an application.
+
+
+ * SC_OVERRIDE_DEFAULT_STACK_SIZE=<size> -
+ Define the default stack size used for SystemC (thread) processes
+
+ Note: Only effective during library build.
+
+
+ * SC_USE_SC_STRING_OLD / SC_USE_STD_STRING -
+ Define 'sc_string' symbol.
+
+ Pre-IEEE-1666 versions of SystemC included an 'sc_string' class for
+ string objects. This class has been superseeded by 'std::string' these
+ days.
+
+ If your application still relies on 'sc_string' being available, set one
+ of the two supported preprocessor switches to provide it:
+
+ SC_USE_SC_STRING_OLD -
+ Uses old implementation `sc_string_old' to provide `sc_string':
+ typedef sc_string_old sc_string;
+
+ SC_USE_STD_STRING -
+ Provide `sc_string' as an alias to `std::string':
+ typedef std::string sc_string;
+
+
+Influential environment variables
+=================================
+
+Currently, three environment variables are checked at library load time
+and influence the SystemC library's behaviour:
+
+ 1) SC_COPYRIGHT_MESSAGE=DISABLE -
+ Run-time alternative to SC_DISABLE_COPYRIGHT_MESSAGE (see above).
+
+ 2) SC_SIGNAL_WRITE_CHECK=DISABLE
+ Run-time alternative to SC_DEFAULT_WRITER_POLICY=SC_UNCHECKED_WRITERS
+ (see above)
+
+ 3) SC_DEPRECATION_WARNINGS=DISABLE
+ Do not issue warnings about using deprecated features as of
+ IEEE 1666-2011.
+
+Usually, it is not recommended to use any of these variables in new or
+on-going projects. They have been added to simplify the transition of
+legacy code.
+
+
+// Taf!
diff --git a/ext/systemc/LICENSE b/ext/systemc/LICENSE
new file mode 100644
index 000000000..d64569567
--- /dev/null
+++ b/ext/systemc/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/ext/systemc/NEWS b/ext/systemc/NEWS
new file mode 100644
index 000000000..49aa2fdc7
--- /dev/null
+++ b/ext/systemc/NEWS
@@ -0,0 +1,107 @@
+* SystemC 2.3.1a
+ Relicensed under Apache License, Version 2.0.
+ No functional changes.
+
+* SystemC 2.3.1
+ Release of SystemC 2.3.1
+ - Bug fixes.
+ - Code cleanup.
+ - Some experimental new features.
+
+* SystemC 2.3.0
+ Release of SystemC 2.3.0
+ - Compliance to IEEE Std 1666-2011
+ - Per LRM, includes TLM-2.0.2
+ - Bug fixes.
+ - Code cleanup.
+
+* SystemC 2.2
+ Production release of SystemC 2.2
+ - Compliance to IEEE Std 1666-2005
+
+* SystemC 2.2 Beta
+ Beta release of SystemC 2.2
+ - Bug fixes.
+ - Code cleanup.
+ - Major new functionality
+ o Compliance with the IEEE 1666 SystemC Language reference module.
+ - Platforms and compilers supported (added since 2.1):
+ o Support for 64-bit Linux systems gcc-3.4.3.
+ o Linux with GNU C++ compiler version gcc-4.0.1.
+ o MacOS X with GNU C++ compiler version gcc-4.0.0.
+
+* SystemC 2.1
+ Release of SystemC 2.1
+ - Bug fixes.
+ - Code cleanup.
+ - Major new functionality
+ o Dynamic process support, including synchronization primitives.
+ o Mixed concatenation and concatenation of long types.
+ o Event queue support.
+ o Exported interfaces: sc_export.
+ o New error reporting API.
+ - Platforms and compilers supported (added since 2.0.1 Production):
+ o Solaris 2.8 with Sun CC compiler version Forte 7 and gcc-3.2.3
+ o Linux (Redhat 9.0) with GNU C++ compiler version gcc-3.2.2
+ o Linux (Redhat 8.0) with GNU C++ compiler version gcc-2.95.3 and gcc-3.2.3
+ o MacOS X with GNU C++ compiler version gcc-3.1 and gcc-3.3.
+ o Windows NT 4.0 (SP6a) with VC++ 7.0
+
+* SystemC 2.0.1
+ Production release of SystemC 2.0.1
+ - Bug fixes.
+ - Code cleanup.
+ - Simple bus example included.
+ - Platforms supported (changed from 2.0 Production):
+ o Sun Solaris 2.7 and 2.8 with GNU C++ compiler version gcc-2.95.3
+ o Linux (Redhat 6.2) with GNU C++ compiler version gcc-2.95.3
+ o Linux (Redhat 7.2) with GNU C++ compiler version gcc-2.95.3
+ o HP-UX 11.00 with HP C++ compiler version A.03.33
+ (Note: +O1 is the highest safe optimization level)
+ o Windows NT 4.0 (SP6a) with VC++ 6.0 (SP5)
+ - First release of a regression test suite for SystemC.
+ The SystemC regression test suite is released separately.
+
+* SystemC 2.0
+ Production release of SystemC 2.0.
+ - All new SystemC 2.0 core language features.
+ - All SystemC 1.0.2 functionality (except obsoleted SystemC 0.9 features).
+ - No methodology-specific channels as in SystemC 1.2.1 beta.
+ (Note: starting with this release, the 2.0 Core Language Features
+ will be released separately from the methodology-specific libraries,
+ an example of which is the Master-Slave Library of 1.2.1 beta.
+ The release of the Master-Slave Library will follow this release.
+ You would be able to use the Master-Slave Library in conjunction with
+ this release).
+ - Dynamic thread creation example provided.
+ - Directory structure changed from 1.0.2, but same as 2.0 beta-2.
+ - Build process changed from 1.0.2 but same as 2.0 beta-2.
+ - Bug fixes for 2.0 beta-2.
+ - Platforms supported (changed from 2.0 beta-2):
+ o Sun Solaris 2.7 and 2.8 with GNU C++ compiler version 2.95.2
+ o Sun Solaris 2.7 and 2.8 with SC6.1 and SC6.2
+ o Linux (Redhat 6.2) with GNU C++ compiler version 2.95.2
+ o HP-UX 11.00 with aCC C++ compiler versions A.03.31 and A.03.15
+ (Note: +O1 is the highest safe optimization level)
+ o Windows NT 4.0 (SP3 and higher) with VC++6.0
+
+* SystemC 2.0 Beta-2
+ Second beta release of SystemC 2.0.
+
+* SystemC 2.0 Beta-1
+ First beta release of SystemC 2.0.
+
+* SystemC 1.0.2
+ Bug fix release.
+
+* SystemC 1.0.1
+ Bug fix release.
+
+* SystemC 1.0
+ First release of new SystemC syntax and fixed-point package.
+
+* SystemC 0.91
+ Second release of SystemC.
+
+* SystemC 0.9
+ This is the first release of SystemC.
diff --git a/ext/systemc/NOTICE b/ext/systemc/NOTICE
new file mode 100644
index 000000000..b42be393f
--- /dev/null
+++ b/ext/systemc/NOTICE
@@ -0,0 +1,66 @@
+=========================================================================
+== NOTICE file corresponding to section 4 d of the Apache License, ==
+== Version 2.0, in this case for the SystemC Class Library ==
+== Proof of Concept implementation ==
+=========================================================================
+
+This product includes software developed by Accellera Systems Initiative
+8698 Elk Grove Bldv Suite 1, #114, Elk Grove, CA 95624, USA
+Copyright 2011-2016 Accellera Systems Initiative Inc. (Accellera)
+All rights reserved.
+
+This product includes software developed by Cadence Design Systems Inc.
+2655 Seely Ave., San Jose, CA, USA
+Copyright 2006-2016 Cadence Design Systems Inc.
+All rights reserved.
+
+This product includes software developed by Circuitsutra Technologies Pvt Ltd.
+Regus, Ground Floor, Tapasya Corp Heights, Sector 126, Noida, 201303, UP, India
+Copyright 2011-2016 Circuitsutra Technologies Pvt Ltd.
+All rights reserved.
+
+This product includes software developed by Doulos
+Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, United Kingdom
+Copyright 2006-2016 Doulos
+All rights reserved.
+
+This product includes software developed by Fraunhofer-Gesellschaft
+Postfach 20 07 33, 80007 Munich, Germany
+Copyright 2014-2016 Fraunhofer-Gesellschaft
+All rights reserved.
+
+This product includes software developed by Intel Corp.
+2200 Mission College Blvd., Santa Clara, CA 95054-1549, USA
+Copyright 2007-2016 Intel Corp.
+All rights reserved.
+
+This product includes software developed by Mentor Graphics Corporation
+8005 SW Boeckman Road, Wilsonville, OR 97070, USA
+Copyright 2006-2016 Mentor Graphics Corporation
+All rights reserved.
+
+This product includes software developed by OFFIS eV
+Escherweg 2, 26121 Oldenburg, Germany
+Copyright 2009-2016 OFFIS eV
+All rights reserved.
+
+This product includes software developed by STMicroelectronics International NV
+39, Chemin de Champ-des-Filles, Plan-Les-Ouates, Geneva, Switzerland
+Copyright 2011-2016 STMicroelectronics International NV
+All rights reserved.
+
+This product includes software developed by Synopsys, Inc.
+690 East Middlefield Road Mountain View, CA 94043, USA
+Copyright 1999-2016 Synopsys, Inc.
+All rights reserved.
+
+This product includes software developed by Universite Pierre et Marie Curie
+b.c. 167, 4 place Jussieu, 75252 Paris, France
+Copyright 2011-2016 Universite Pierre et Marie Curie (UPMC)
+All rights reserved.
+
+This product includes software developed by XtremeEDA Corporation
+201-1339 Wellington St. West, Ottowa, Ontario K1Y3B8, Canada
+Copyright 2011-2016 XtremeEDA Corporation. All rights reserved.
+
+
diff --git a/ext/systemc/README.gem5.md b/ext/systemc/README.gem5.md
new file mode 100644
index 000000000..b966b7d65
--- /dev/null
+++ b/ext/systemc/README.gem5.md
@@ -0,0 +1,21 @@
+Overview
+========
+
+This subfolder (/ext/systemc) is a custom redistribution of the Accellera
+SystemC 2.3.1 library [[1]][sysc]. This distribution replaces Accellera's
+Autoconf build system with a SCons build system, which is used by gem5.
+
+In the past it happened several times that some changes in gem5 broke the
+SystemC coupling. Recently Accelera has changed the licence for SystemC from
+their own licence to Apache2.0, which is compatible with gem5. However, SystemC
+usually relies on the Boost library. The repository contains all the source
+files from the Accellera distribution, but strips down the boost dependencies,
+shown here:[[3]][strip]. All references to the boost library are replaced by
+calls to the C++11 STL. This repository also contains the TLM 2.0
+protocol-checker from Doulos [[4]][doulos].
+
+
+[sysc]: http://accellera.org/downloads/standards/systemc
+[gem5]: http://www.gem5.org/Main_Page
+[doulos]: https://www.doulos.com/knowhow/systemc/tlm2/base_protocol_checker/
+[strip]: https://github.com/tud-ccc/systemc-scons/commit/913a7451939dc4d4bd752df7081064f9f870517a
diff --git a/ext/systemc/README.md b/ext/systemc/README.md
new file mode 100644
index 000000000..d4b084591
--- /dev/null
+++ b/ext/systemc/README.md
@@ -0,0 +1,43 @@
+Overview
+========
+
+This repository is a redistribution of the Accellera SystemC 2.3.1 library
+[[1]][sysc]. This distribution replaces Accellera's Autoconf build system with
+a SCons build system, which is very useful for integration of SystemC in other
+SCons based projects, e.g., gem5 [[2]][gem5].
+
+The repository contains all the source files from the Accellera distribution,
+but strips down the boost dependencies. All references to the boost library
+are replaced by calls to the C++11 STL. This repository also contains the
+TLM 2.0 protocl checker from Doulos [[3]][doulos].
+
+Build
+=====
+
+To build libsystemc-2.3.1.so, simply type scons. Optionally you can specify the
+number of jobs.
+
+```
+scons -j N
+```
+
+To build and link to SystemC from another SCons project, simply call the
+SConscript located in `src/`. Be sure to add `-std=c++11` to the `CXXFLAGS` of
+your environment and to export the environment as `'env'`. In case you build on
+OS X, you will need to add `-undefined dynamic lookup` to your `LINKFLAGS`.
+This is how a minimal SConstruct for your SystemC project could look:
+
+```python
+env = Environment()
+
+env.Append(CXXFLAGS=['-std=c++11'])
+if env['PLATFORM'] == 'darwin':
+ env.Append(LINKFLAGS=['-undefined', 'dynamic_lookup'])
+
+systemc = env.SConscript('<path_to_systemc>/src/SConscript', exports=['env'])
+env.Program('example', ['example.cc', systemc])
+```
+
+[sysc]: http://accellera.org/downloads/standards/systemc
+[gem5]: http://www.gem5.org/Main_Page
+[doulos]: https://www.doulos.com/knowhow/systemc/tlm2/base_protocol_checker/
diff --git a/ext/systemc/README.sysc b/ext/systemc/README.sysc
new file mode 100644
index 000000000..a2729db83
--- /dev/null
+++ b/ext/systemc/README.sysc
@@ -0,0 +1,132 @@
+ SystemC Class Library (Rel. 2.3.1)
+ ==================================
+
+This is the release of the SystemC 2.3.1 Class Library.
+This release includes TLM 2.0.3 (Transaction Level Modeling) code,
+as described in the IEEE 1666-2011 Language Reference Manual.
+
+-------------------------------------------------------------------------------
+ IMPORTANT
+
+1. This is the release of SystemC 2.3.1. This release contains bug fixes
+ for SystemC 2.3.0 as well as adding some minor and experimental features.
+
+2. This release is supported on the following platform combinations for
+ which it has been well tested:
+
+ o 64-bit Linux (x86_64)
+ (RedHat Enterprise Linux 5, 6; Scientific Linux 5, 6; Debian 7; Ubuntu 12)
+ - GNU C++ compiler versions gcc-3.4.6 through gcc-4.9.0;
+ - Clang C++ compiler versions clang-3.0 through clang-3.5
+
+ o 64-bit Linux (x86_64) with 32-bit compiler (--host=i686-linux-gnu)
+ (RedHat Enterprise Linux 5, 6; Debian 7; Ubuntu 12)
+ - GNU C++ compiler versions gcc-4.4.7 through gcc-4.9.0;
+ - Clang C++ compiler versions clang-3.0 through clang-3.5
+
+ o 32-bit Linux (x86)
+ (Scientific Linux 5, 6; Debian 6, 7; Ubuntu 12)
+ - GNU C++ compiler versions gcc-3.4.6 through gcc-4.9.0;
+ - Clang C++ compiler versions clang-3.0 through clang-3.4
+
+ o 64-bit Mac OS X (x86_64)
+ (10.6 Snow Leopard, 10.8 Mountain Lion, 10.9 Mavericks)
+ - Apple LLVM version 5.0 (based on LLVM 3.3svn);
+ - Apple GNU C++ compiler version gcc-4.2.1
+
+ o 32-bit Mac OS X (x86)
+ (10.6 Snow Leopard, 10.8 Mountain Lion)
+ - Apple LLVM version 5.0 (based on LLVM 3.3svn);
+ - Apple GNU C++ compiler version gcc-4.2.1
+
+ o 32-bit Mac OS X (powerpc)
+ (10.6 Snow Leopard, executed with Rosetta)
+ - Apple GNU C++ compiler version gcc-4.2.1
+
+ o 64-bit FreeBSD 9.0 (x86_64)
+ - GNU C++ compiler versions gcc-4.2.1 through gcc-4.8.2;
+ - Clang C++ compiler version clang-3.3
+
+ o 32-bit FreeBSD 9.0 (x86)
+ - GNU C++ compiler versions gcc-4.2.1 through gcc-4.8.2;
+ - Clang C++ compiler version clang-3.3
+
+ o 32-bit Solaris (SPARC)
+ (Sun Solaris 10, Oracle Solaris 11)
+ - GNU C++ compiler versions gcc-3.4.3 through gcc-4.8.1;
+ - Sun/Solaris Studio compiler versions 12, 12.1, 12.2, 12.3
+
+ o Windows 7 SP1 (WoW64)
+ - Microsoft Visual Studio 2005 SP1 (8.0) (Win32 and x64);
+ - Microsoft Visual Studio 2008 Express SP1 (9.0) (Win32);
+ - Microsoft Visual Studio 2010 Express SP1 (10.0) (Win32);
+ - Microsoft Visual Studio 2012 Express Update 4 (11.0) (Win32 and x64)
+ - Microsoft Visual Studio 2013 Express Update 1 (12.0) (Win32 and x64)
+
+ o Windows 7 SP1 (WoW64), (Cygwin 1.7.17)
+ - GNU C++ compiler versions gcc-3.4.4 through gcc-4.3.4 (x86)
+
+ o Windows 7 SP1 (WoW64), Msys 1.0.17(0.48/3/2)
+ - MinGW32 GNU C++ compiler versions 4.5.2 through 4.7.0 (x86);
+ - MinGW-w64 GNU C++ compiler version 4.8.1 (x86 and x86_64)
+
+
+ This release has not yet been tested or is known not to work as expected
+ on the following formerly supported platforms:
+
+ o GNU C++ compiler versions prior to 3.4.x (all platforms)
+ o HP-UX 11.00 or later with GNU C++ or HP C++ compiler
+ o Sun/Oracle Solaris with Sun Studio C++ compiler prior to 12.x
+ o Mac OS X prior 10.6 Snow Leopard with GNU C++ compiler
+ o Microsoft Visual C++ versions prior to 8.0 (2005)
+
+
+-------------------------------------------------------------------------------
+
+For details, see the separate RELEASENOTES file.
+
+
+Licensing and Copyright
+
+ See the separate LICENSE file to determine your rights
+ and responsiblities for using SystemC.
+
+User Documentation
+
+ You can find documentation for this release in the docs directory.
+
+Installation
+
+ See the separate INSTALL file that provides system
+ information and installation instructions.
+
+Release Notes
+
+ See the separate RELEASENOTES file that provides upto date
+ information about this release of SystemC.
+
+Additional information
+
+ SystemC has a web site at
+
+ http://www.accellera.org
+
+ Discussion forum: http://forums.accellera.org/forum/9-systemc/
+
+ You can post the bugs and suggestions of general interest to the forum.
+ When reporting bugs please specify the following information (if
+ applicable):
+
+ 1) SystemC version
+ 2) platform, compiler, flags
+ 3) description of the problem
+ 4) steps to reproduce the problem
+ 5) compile/runtime warnings and errors
+ 6) code sample, not more than 100 lines to demonstrate the problem
+
+ Note: All bugs will only be tested against the latest publicly available
+ version of the product.
+
+ Note: All C++ compilers that SystemC supports have bugs of different
+ degree of severity. We cannot fix those bugs. Please report them
+ to the compiler vendor.
diff --git a/ext/systemc/RELEASENOTES b/ext/systemc/RELEASENOTES
new file mode 100644
index 000000000..2dd93b34c
--- /dev/null
+++ b/ext/systemc/RELEASENOTES
@@ -0,0 +1,685 @@
+ Release Notes for SystemC 2.3.1
+ ===============================
+
+ Andrew C. Goodrich, Forte Design Systems
+ Philipp A. Hartmann, OFFIS Institute for Information Technology
+
+CONTENTS
+========
+
+ 1) What's new in this release?
+
+ 2) Bug fixes and enhancements
+
+ 3) New features
+
+ 4) Incompatibitilies with previous releases
+
+ 5) Expanded dynamic process support
+
+ 6) Experimental features
+
+ 7) Known problems
+
+ 8) Fixed-point library
+
+ 9) TLM Release Notes
+
+
+1) What's new in this release?
+==============================
+
+This version of SystemC contains the "Proof of Concept" simulator
+for the IEEE 1666-2011 SystemC standard. Please consult the IEEE Std
+1666-2011 SystemC Language Reference Manual for details about the
+current SystemC standard.
+
+TLM-2.0 is merged into the main SystemC release since 2.3.0.
+Please see section 9) below for more details related to TLM.
+
+Compared to the 2.3.0, this release has the following new items:
+
+ - New features, partly beyond the current IEEE 1666-2011 standard,
+ see section 3.
+
+ - Experimental features (disabled by default), see section 5.
+ Testing and feedback welcome via the Accellera SystemC forums
+ at http://forums.accellera.org/forum/9-systemc/.
+
+ - Bug fixes, see section 2.
+
+ - Expanded platform support, see the README.
+
+
+
+2) Bug fixes and enhancements
+=============================
+
+Following is the list of bug fixes and enhancements for this release:
+
+ - For fixes and enhancements of the embedded TLM-2.0 implementation,
+ please see section 9.
+
+ - Additional changes and cleanups leading to incompatibilities with
+ previous versions of SystemC are described in section 4.
+
+ - Fix nested SC_METHOD preemptions caused by resetting a method, which
+ throws an exception in a thread process. The control now correctly
+ goes back to the throwing method.
+
+ - Handle the case of a suppressed multiple-writer error in sc_signal
+ (and related channels) consistently with SystemC 2.2.0 again.
+
+ - The 'sc_buffer<bool>' and 'sc_buffer<sc_logic>' channels now correctly
+ notify their (pos|neg)edge_events, if someone is waiting on them.
+
+ - Cleanup the renaming of the internal Boost namespaces. The embedded
+ Boost implementation resides in the (renamed) top-level namespaces
+ - sc_boost
+ - sc_unnamed (for placeholders, part of IEEE 1666-2011)
+ - sc_mpl_ (internal ADL barrier)
+
+ - Minor fixes in sc_vector-related classes
+ - correctly determine instantiation context
+ - sc_vector_iter: addition/substraction operators fixed
+ - sc_vector_assembly: add swap, fix missing return statement in
+ assignment
+
+ - WIF tracing of 64-bit integers: fix widths and masks on some
+ 64-bit platforms.
+
+ - Suppressed a warning in case of calling sc_start in case of pending
+ delta notifications without any pending (or resulting) process
+ activations afterwards (1666-2011 compatbility).
+
+ - Fix sc_string_old implementation to handle very long strings (>1024)
+ (known issue in <=2.3.0). Note, that sc_string_old is no longer
+ included by default, see section 4.
+
+ - Add "risc_cpu" example to Automake build system ("make check").
+
+ - Add missing files to the MS Visual C++ SystemC.vcproj project file.
+
+ - Add a missing "break" statement to "scfx_utils.h" in the "SC_CSD"
+ format parsing logic.
+
+ - Fix several integer conversion warnings raised by some compilers
+ throughout the SystemC implementation.
+
+ - Fixed incorrect GCC i386/x86_64 function call stack alignment when
+ using the QuickThreads/WinFiber-based process implementations (16-byte
+ boundary). This avoids segmentation faults in some cases where the
+ stricter stack requirement is implicitly assumed by the compiler.
+
+ - The default stack size for threads, SC_DEFAULT_STACK_SIZE, has been
+ increased on 64-bit platforms and is overridable at library build
+ time (see INSTALL).
+
+ - The sc_report implementation now correctly handles empty and NULL
+ message type arguments (avoiding a segmentation fault in these cases).
+ The sc_report default constructor is made private to follow IEEE 1666.
+
+ - Missing namespace qualifiers added to all reporting macros, namely
+ - SC_DEFAULT_*_ACTIONS
+ - SC_REPORT_INFO_VERB
+ to make them usable again while including <systemc> instead of
+ <systemc.h>
+
+ - VCD/WIF tracing: fix support for very long values
+
+ The sc_(un)signed and sc_fxnum(_fast) data types can potentially hold
+ longer values than 1000 bit, which used to be the fixed size of the
+ intermediate buffers in sc_(vcd,wif)_trace for these types.
+
+ - Cleanup systemc.h
+
+ - Drop any in-library dependencies on the old 'sc_string' class,
+ removing the need to provide the corresponding header externally
+ (see section 4).
+ - Drop explicit in-header dependencies on <windows.h> on Windows
+ platforms, removing the automatic inclusion from <systemc[.h]>
+ (see section 4).
+ - Drop inclusion of 'strstream' by default on some platforms
+ (see section 4)
+ - assume working C++ standard library on all platforms
+ - assume working argument-dependent lookup on MSVC
+ (which should be working since MSVC 2003 already)
+ - see section 4 and INSTALL file
+
+ - Improved compile/runtime check of the SystemC library config
+
+ Some preprocessor switches need to be consistent between the application
+ and the library (e.g. if sizes of classes are affected or other parts of
+ the ABI are affected). These can now be checked at link-time.
+
+ Secondly, some preprocessor switches need to be consistent between
+ different translation units of an application, which is checked at
+ runtime startup.
+
+ - sc_context: avoid reinterpret_cast from integer to pointer
+
+ - The SC_VERSION_ORIGINATOR has been renamed from "ASI" to "Accellera"
+ to follow the naming policies of the Accellera Systems Initiative.
+
+ - Cleanups of the VCD/WIF tracing implementation
+
+ - Removal of internal files from the public headers (see section 4)
+ - Report any information (infos, warnings, errors) via the SystemC
+ reporting mechanism instead of directl printing to std::cout/cerr
+ - Automatically unregister trace updates when closing a trace file
+ during the simulation
+
+ - Drop the 'register' storage class specifier, which has been
+ deprecated in the C++11 standard (and therefore might cause warnings
+ on some compilers).
+
+ - Expanded naming of traced objects in VCD traces to use 5 characters
+ rather than 3 to accommodate more signals (incomplete in 2.3.0).
+
+ - Fix sc_signed/sc_unsigned conversion bug on GCC 4.8 or later, coming
+ from its aggressive optimization in case of integer over/underflows
+ (by avoiding the C++ undefined behaviour in the implementation).
+
+ - An output stream operator<< for sc_status is added to enable
+ pretty-printing of sc_status values (and bitwise combinations of
+ such values).
+
+ - Various minor code cleanups and compiler warning fixes
+ - removal of some workarounds for very old versions of some
+ compilers (e.g. MSVC < 8.0).
+ - removal of unused variables and macros
+ - some deduplication of redundant code paths
+
+
+3) New features
+===============
+
+Here is an overview of changes in 2.3.1 compared to 2.3.0.
+
+Note: These features partly add functionality beyond the current
+ IEEE Std. 1666-2011.
+
+
+ - Major rewrite of the Autoconf/Automake build system
+ - better control of the installation directories
+ - improved libtool library dependency detection, especially
+ in cross-compilation scenarios (--host=...)
+ - support for pkg-config for SystemC and TLM
+ (see http://www.freedesktop.org/wiki/Software/pkg-config/)
+ - accept arbitrary GCC-compatible compilers
+ (e.g. Clang, Intel compiler, compiler-wrappers like scan-build)
+ - avoid deprecation warnings, cleanup implementation
+ - less recursive build, silent rules by default
+ - improved "make check" test handling
+
+
+ - Updated MS Visual C++ project and solution files to include
+ support for Visual Studio 2012 and 64-bit builds on Windows
+ platforms.
+
+
+ - Improved conversion between the underlying integral time
+ representation and sc_time objects:
+
+ - Add a nested typedef "value_type" to sc_time to enable an
+ implementation-independent use of the underlying integral
+ time representation (see IEEE 1666-2011, 5.11.1).
+
+ - Adding an inverse to the 'sc_time::value()' function to
+ convert a plain value back to an sc_time object:
+ static sc_time sc_time::from_value( value_type t );
+
+ - Adding modulus operators (%, %=) to compute time offsets from
+ clock or quantum boundaries:
+
+ sc_time operator%(const sc_time& lhs, const sc_time& rhs);
+
+ sc_time& sc_time::operator%=();
+
+ Note: These operators are missing from IEEE 1666-2011, which
+ make e.g. the tlm_global_quantum implementation nearly
+ impossible within the limits of the SystemC standard.
+
+
+ - Add function to determine the current object hierarchy:
+
+ sc_object* sc_core::sc_get_current_object()
+
+ Returns a pointer to the sc_object instance (or NULL) that would
+ currently become the parent object of a newly created sc_object
+ instance (i.e. the current module during elaboration, and the
+ currently active process during simulation).
+
+
+ - Add compile-time configurable default signal writer policy
+ (see INSTALL).
+
+ Defining SC_DEFAULT_WRITER_POLICY to one of the sc_writer_policy
+ values before including systemc(.h) allows application-wide selection
+ of the default sc_writer_policy used for signals.
+
+ Defining SC_NO_WRITE_CHECK is equivalent to
+ SC_DEFAULT WRITER_POLICY=SC_UNCHECKED_WRITERS
+
+ By default, the writer policy still disallows multiple
+ writers (SC_ONE_WRITER).
+
+
+ - Add an sc_signal initialization which does not create an event
+ via newly provided constructors to the signal classes:
+
+ sc_signal<T>::sc_signal( const char* name
+ , const T& initial_value );
+
+ (similarly for sc_buffer and sc_signal_resolved)
+
+ Compared to calling the "write()" function on a signal during
+ the elaboration, these constructors will set the initial value
+ of the signal without triggering an event at the beginning of the
+ simulation (and therefore may avoid triggering sensitive processes).
+
+
+ - Add a static function to sc_report_handler to query the current
+ report handler function:
+
+ static sc_report_handler_proc sc_report_handler::get_handler();
+
+ Additionally, sc_report_handler::set_handler() now returns the
+ previously set handler (c.f. sc_report_handler::set_actions).
+
+
+ - Improved conversion from bitvector element references to bool
+
+ As it is surprising to the user that a reference to an explicit
+ element of a sc_bv could not be used in a boolean context, a safe
+ conversion has been added to this release.
+
+ This enables the following coding style:
+
+ sc_bv<8> mybits;
+ // ...
+ if( mybits[0] ) // no longer a compiler error here!
+ /* do something */ ;
+
+ Note: For logic vectors, the bit-references still need to be
+ converted to bool explicitly (e.g. via the "to_bool()"
+ function.
+
+
+
+4) Incompatibilities with previous releases
+===========================================
+
+Here is a list of known incompatibilities between this release and
+2.3.0 (or earlier):
+
+ - The non-standard sc_time constructors
+ - sc_time( uint64, bool scale )
+ - sc_time( double, bool scale )
+ have been deprecated and issue a warning when being used.
+ Use the new 'sc_time::from_value' function instead (see section 3).
+
+ - The non-standard function 'sc_object::get_parent()' has been
+ deprecated, use 'sc_object::get_parent_object()' instead.
+
+ - The non-standard function 'sc_signal::get_new_value()' has been
+ deprecated (as required by IEEE 1666-2011).
+
+ - The non-standard implementation classes for the VCD and WIF tracing
+ (vcd_trace_file, wif_trace_file) are now hidden from an application
+ and no longer part of the public headers.
+ Use the IEEE 1666-2011 functions
+ - sc_trace
+ - sc_create_[vcd|wif]_trace_file
+ - sc_close_[vcd|wif]_trace_file
+ - sc_trace_file::set_time_unit
+ to set up the tracing in your application.
+
+ - The non-standard header 'src/sysc/communication/sc_reset.h' is
+ no longer part of the public headers.
+
+ - The 'sc_string_old' class is no longer available by default.
+ Define 'SC_USE_SC_STRING_OLD' before including "systemc.h",
+ see INSTALL.
+
+ - The implicit inclusion of the system-headers "windows.h" (on Windows)
+ and (deprecated) "strstream" have been removed. See INSTALL.
+
+ - The incomplete implementation of old "W_*" watching macros and the
+ non-standard struct sc_watch have been removed.
+
+Here is a list of known incompatibilities between this release and 2.2.0:
+
+ - The order that processes (SC_METHODs and SC_THREADs) are dispatched
+ for execution may be different than the order with SystemC 2.2.0 for
+ some SystemC programs. This is related to the new starvation policy
+ support for the sc_start() function introduced with IEEE 1666_2011.
+
+ - The various bind() functions for ports and exports are "virtual" as
+ of IEEE 1666-2011. This leads to an incompatibility with the
+ TLM 2.0.x release. To use SystemC 2.3 together with TLM 2.0.{0,1},
+ define SC_DISABLE_VIRTUAL_BIND during the build of the simulator and
+ before including systemc.h (see INSTALL).
+
+
+5) Expanded Dynamic Process Support
+===================================
+
+This version implements the dynamic process extensions described in the
+IEEE Std 1666-2011 Language Reference Manual.
+
+Compared to SystemC 2.3.0, some bugs in corner cases of the
+specification have been fixed (see section 2).
+
+
+6) Experimental features
+========================
+
+In this section the experimental features of this release are listed.
+
+Note: These features are not enabled in the default library
+ configuration and need to be explicitly activated during at
+ library build time. See INSTALL file.
+
+
+ - Extended Simulation Phase Callbacks
+
+ This release adds an optional mechanism to register callbacks
+ to several simulation phases. This can be used to integrate
+ custom introspection techniques in a non-invasive manner.
+
+ New phases are added to the sc_status enumeration:
+
+ SC_END_OF_INITIALIZATION,
+ SC_END_OF_UPDATE,
+ SC_BEFORE_TIMESTEP
+
+ to enable a more fine-grained view to the SystemC simulation phases.
+
+ When the phase callback mechanism is activated (see the INSTALL file),
+ any sc_object can subscribe to a (set of) elaboration/simulation phases
+ for dynamic callbacks explicitly:
+
+ // trigger current object before updating the simulation time
+ this->register_simulation_phase_callback( SC_BEFORE_TIMESTEP );
+
+ // trigger current object before returning to "sc_start"
+ this->register_simulation_phase_callback( SC_PAUSED | SC_STOPPED );
+
+ Unsubscribing from any simulation phase is possible via the corresponding
+ unregister_simulation_phase_callback( phase_cb_mask )
+ function.
+
+ Both functions return the effective mask after the requested callback mask
+ update. Therefore, querying the currently active mask can be achieved by
+ calling the (un)registration functions with an empty mask:
+
+ sc_object::phase_cb_mask current_cb_mask =
+ this->register_simulation_phase_callback( 0u );
+
+ To enable the external (un)registration of callbacks for a user-defined
+ sc_object class, the (un)registration functions can be made public by
+ adding the following using directives to a 'public:' section of the
+ class definition:
+
+ using sc_core::sc_object::register_simulation_phase_callback;
+ using sc_core::sc_object::unregister_simulation_phase_callback;
+
+ When the simulation passes a phase where dynamic callbacks are registered,
+ the subscribed objects are triggered via the function:
+
+ virtual void sc_object::simulation_phase_callback();
+
+ which should then be implemented by the subscribing object's class.
+
+ Within a simulation callback, the triggering phase can be determined
+ via the IEEE 1666-2011 'sc_get_status()' function:
+
+ void simulation_phase_callback() {
+ std::cout << sc_core::sc_get_status() << std::endl;
+ }
+
+ A related feature is the triggering of sc_trace updates via these
+ simulation phase callbacks instead of the hard-coded calls in various
+ places of the simulation loop. This feature has to be enabled separately,
+ see INSTALL file.
+
+
+ - Allow creation of sc_max_time() objects before fixing the sc_time
+ resolution
+
+ Currently. IEEE 1666-2011 requires that any call to
+
+ sc_core::sc_set_time_resolution( double, sc_time_unit )
+
+ happens before the construction of the first non-SC_ZERO_TIME
+ sc_time object.
+
+ This can be inconvenient in cases, where an "uninitialized sc_time value"
+ is needed, which needs to be separate from SC_ZERO_TIME in some cases.
+
+ A relaxation of the strict sc_time construction rules wrt. to
+ the simulation time resolution can be optionally enabled via the
+ preprocessor switch SC_ENABLE_EARLY_MAXTIME_CREATION (see INSTALL).
+
+ When this option is enabled, the creation of time objects with the
+ values SC_ZERO_TIME and 'sc_max_time()' are allowed before fixing the
+ time resolution. The resolution is still fixed once the actual
+ relationship between the internal time representation and the physical
+ time units (SC_FS, SC_PS, ...) is used or observed by the application.
+
+
+
+
+7) Known Problems
+=================
+
+ - When building the SystemC library with QuickThreads support, the
+ resulting shared library is marked as requiring an executable stack
+ by certain compilers/assemblers (or rather not marked as not needing
+ one). As a result, some system security systems (like SELinux) might
+ refuse to load the library. As a workaround for GNU (compatible)
+ assemblers, pass the assembler flags variable with the option
+ CCASFLAGS="-Wa,--noexecstack"
+ to the `configure' script call before building the SystemC library.
+
+
+ - IEEE 1666-2011 does not explicitly define the behaviour in the corner
+ cases of attempting to create sc_time objects smaller than the time
+ resolution or bigger than sc_max_time(). This implementation currently
+ truncates "small" sc_time objects to SC_ZERO_TIME, while "too big"
+ objects wrap-around sc_max_time() and lead to a value modulo the
+ maximum time. In both cases, no warning is generated.
+
+
+ - The sign-extension of mixed-signedness logic expressions (&,|)
+ involving one sc_bigint<> operand and C++ builtin integral types
+ (int, short, etc.) is inconsistent between 32-bit and 64-bit
+ platforms in some cases. Convert both operands to sc_bigint<> first.
+
+
+ - The definition of sc_dt::(u)int64 differs from std::(u)int64_t types
+ on some platforms. This may lead to problems with function overloads
+ and/or format-string placeholders. As a workaround, convert these
+ values explicitly to the correct type before passing them to functions
+ expecting one of these types. For sc_time, use the new nested type
+ sc_time::value_type to hold values of the underlying representation.
+
+
+ - Bit/logic-vector reductions (or_reduce, and_reduce, etc.) return an
+ 'sc_logic_value_t' enum value, instead of a bool or sc_logic (as required
+ by IEEE 1666-2011). Using the return value of these functions in a
+ boolean context, e.g.
+ if( lv.or_reduce() ) { /* ... */ }
+ might lead to wrong results in case of 'X' or 'Z' bits in the vector.
+ Avoid this by converting the result to an 'sc_logic' first and perform
+ a safe conversion to bool:
+ if( sc_logic( lv.or_reduce() ).to_bool() ) { /* ... */ }
+
+
+ - The use of the DEBUG_SYSTEMC macro does not work properly with certain
+ compilers (e.g., gcc 2.95.x) if it was not also specified when the
+ SystemC library was built. The problem is caused by the use of the
+ library compiled version of some inline methods. This problem does not
+ appear to be present in the gcc 3.3, Solaris, and aCC compilers.
+ The work-around is to specify DEBUG_SYSTEMC when the SystemC library
+ is built.
+
+
+ - On some recent compilers (e.g. Clang, Solaris Studio), warnings are
+ generated about the "hidden overloaded virtual function" bind of the
+ sc_port(_b) class templates in the 'specialized_signals' example.
+ These warnings are caused by the introduction of the virtual bind
+ implementation in IEEE 1666-2011.
+ As a workaround, check your compiler documentation how to suppress
+ the warning (e.g. 'CXXFLAGS=-Wno-overloaded-virtual') or mark
+ the SystemC include directory as "system directory" by using
+ '-isystem ${SYSTEMC_HOME}/include' (or equivalent) instead of
+ the usual '-I'.
+
+ This also affects the TLM-2.0 sockets, see Section 9.3.
+
+
+ - Some paths in this release are longer than the historical 99 character
+ limit of tar archives, and several Windows archivers (e.g. WinZip)
+ have been reported to trip over this. The open source archiver 7-zip
+ (http://7-zip.org) is known to work.
+
+
+8) Fixed-point library
+======================
+
+SystemC contains a fixed-point datatypes package.
+
+Changes compared to SystemC 2.0.1
+
+ - support for explicit construction from "float" values
+
+ - removing a conversion ambiguity by marking some constructors of
+ sc_fxval[_fast] classes as 'explicit'
+
+Compile-time macro SC_INCLUDE_FX must be defined in order to build
+applications that use fixed point types. You can specify a compiler
+flag, e.g., g++ -DSC_INCLUDE_FX ... or use a define statement before
+you include systemc.h, e.g.:
+
+ #define SC_INCLUDE_FX
+ #include "systemc.h"
+
+Due to the large size of the fixed-point datatypes header files,
+compilation can take considerably more time.
+
+If you want to use the fixed-point data types only (i.e., not data-
+types sc_int, sc_uint, sc_bigint, sc_biguint), compilation time can be
+reduced by defining compile-time macro SC_FX_EXCLUDE_OTHER (in addition
+to SC_INCLUDE_FX).
+
+
+9) TLM Release Notes
+====================
+
+CONTENTS
+========
+
+ 1) Supported SystemC versions
+ 2) What's changed in this kit?
+ 3) Known issues
+
+
+9.1) Supported SystemC versions
+===============================
+
+SystemC 2.2.0 and 2.3.x are supported and have been tested.
+SystemC 2.1.v1 is still supported in principle, but has not
+been tested extensively.
+
+
+9.2) What's changed in this kit?
+================================
+
+Compared to TLM 2.0.2 kit (part of SystemC 2.3.0), the following has changed:
+
+
+ - The tlm_utils headers have been cleaned up to include <tlm>,
+ instead of <tlm.h>
+
+
+ - The convenience sockets with base-protocol NB/B conversion support
+ now automatically define the required SC_INCLUDE_DYNAMIC_PROCESSES,
+ if not already provided by the user (since the B/NB conversion
+ depends on the SystemC dynamic process support).
+
+
+ - Improve the NB/B conversion in the simple_target_socket to avoid
+ the dynamic allocation (and deletion) of sc_event instances in the
+ use of the spawned helper processes for the converesion.
+
+
+ - Fix a bug in the same simple_target_socket NB/B conversion thread,
+ where the target socket may not detect the early completion of the
+ response phase via a "TLM_UPDATED" return value and a "TLM_END_RESP"
+ phase (base protocol violation).
+
+
+ - Fix the "get_base_interface()" implementation provided by the
+ multi_passthrough_target_socket. Prior to this release, a
+ dummy interface object has been used as a return value in case
+ of a hierarchical bind. Return the first bound interface instead.
+
+
+ - Fixed missing initialization of some member variables in the
+ callback_binder_fw|bw implementations, that caused segfaults
+ in some cases.
+
+
+ - The implementation-defined tlm::circular_buffer class has been
+ updated with the following changes
+ - now provides a "clear()" member function to drop the current
+ contents,
+ - fix a segmentation fault due to freeing invalid memory in
+ "resize()", which could happen in some cases,
+ - work around a parsing error on some EDG-based C++ frontends.
+
+
+ - tlm_global_quantum: use sc_time::operator%
+
+ Instead of relying on a manual remainder calculation based on
+ sc_time::value and the non-standard backwards conversion, the new
+ sc_time::operator% is used to compute the remaining time in the
+ current quantum (see section 3).
+
+
+ - The internal tlm_array class (to hold payload extensions) has been
+ reimplemented based on std::vector (fixes copy constructor bug).
+
+
+ - The TLM_VERSION_ORIGINATOR has been renamed from "ASI" to "Accellera"
+ to follow the naming policies of the Accellera Systems Initiative.
+
+
+
+
+9.3) Known issues
+=================
+
+a. The tlm_simple_target_socket in tlm_utils does not obey the END_REQ rule
+ when only an nb_ call is registered, an b_ call is being handled in the
+ socket and there is an nb_ call coming in at the same time. In this case
+ the incoming nb_ call will be forwarded to the registered nb_ call without
+ checking whether the earlier b_ call has passed the END_REQ timing point.
+
+b. The implementation of the PEQ 'peq_with_get' in tlm_utils does not properly
+ distinguish between immediate notifications and delta notifications. In the
+ case that a immediate and delta notification happen at the same simulation
+ time both types of notifications emerge from the PEQ in the same evaluation
+ phase. This is wrong immediate notifications should overtake delta
+ notifications.
+
+c. On some recent compilers (e.g. Clang, Solaris Studio), warnings are generated
+ about the "hidden overloaded virtual function" bind of the sc_port(_b)
+ class templates when using the TLM-2.0 sockets. These warnings are caused by
+ the introduction of the virtual bind implementation in IEEE 1666-2011.
+ As a workaround in your application, check your compiler documentation how to
+ suppress the warning (e.g. adding the flag -Wno-overloaded-virtual), or mark
+ the SystemC include directory as "system directory" by using
+ '-isystem ${SYSTEMC_HOME}/include' (or equivalent) instead of the usual '-I'.
diff --git a/ext/systemc/SConscript b/ext/systemc/SConscript
new file mode 100644
index 000000000..804f7abfc
--- /dev/null
+++ b/ext/systemc/SConscript
@@ -0,0 +1,64 @@
+# Copyright (c) 2017, TU Dresden
+# Copyright (c) 2017, University of Kaiserslautern
+# All rights reserved.
+
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+# Authors: Christian Menard
+# Matthias Jung
+
+import os
+
+Import('main')
+
+main.Prepend(CPPPATH=Dir('./src'))
+main.Prepend(CPATH=Dir('./src'))
+
+main.Prepend(CXXFLAGS=['-DSC_INCLUDE_FX', '-pthread'])
+main.Prepend(CFLAGS=['-DSC_INCLUDE_FX', '-pthread'])
+
+conf = Configure(main)
+
+if main['PLATFORM'] == 'darwin':
+ main.Append(LINKFLAGS=['-undefined', 'dynamic_lookup'])
+
+s_file = None
+if conf.CheckDeclaration("__i386__"):
+ s_file = 'i386.s'
+if conf.CheckDeclaration("__x86_64__"):
+ s_file = 'iX86_64.s'
+conf.Finish()
+
+if s_file is None:
+ print 'Unsupported CPU architecture!'
+ Exit(1)
+
+systemc_files = Glob('src/sysc/kernel/*.cpp')
+systemc_files += ['src/sysc/qt/qt.c', 'src/sysc/qt/md/' + s_file]
+systemc_files += Glob('src/sysc/communication/*.cpp')
+systemc_files += Glob('src/sysc/tracing/*.cpp')
+systemc_files += Glob('src/sysc/utils/*.cpp')
+systemc_files += Glob('src/sysc/datatypes/bit/*.cpp')
+systemc_files += Glob('src/sysc/datatypes/fx/*.cpp')
+systemc_files += Glob('src/sysc/datatypes/int/*.cpp')
+systemc_files += Glob('src/sysc/datatypes/misc/*.cpp')
+
+main.Library('libsystemc', systemc_files)
+main.SharedLibrary('libsystemc', systemc_files)
+
diff --git a/ext/systemc/src/README_TLM.txt b/ext/systemc/src/README_TLM.txt
new file mode 100644
index 000000000..f8174e7a0
--- /dev/null
+++ b/ext/systemc/src/README_TLM.txt
@@ -0,0 +1,33 @@
+
+TLM-2.0 standard header files
+=============================
+
+Dir: include/
+
+SubDirs: tlm_core/
+ tlm_1/
+ tlm_2/
+ tlm_utils/
+
+Files: README.txt
+ tlm
+ tlm.h
+
+
+Comments
+========
+
+To use the TLM-2.0 interoperability standard, a user should only include the tlm
+or tlm.h header file. The same holds for the TLM-1.0 implementation that is
+included as part of this kit; only include tlm or tlm.h. These header files
+refer to all the header files within the tlm_core/ subdirectory, everything
+within tlm or tlm.h is contained in the tlm namespace.
+
+The tlm_utils subdirectory contains a set of additional definitions supported
+by the TLM-2.0 standard, but which are not part of the interoperability
+requirements. It contains ease-of-use and convenience implementations for the
+interoperability standard. All objects defined in the tlm_utils directory are
+contained in the tlm_util namespace.
+
+See the README.txt files in the subdirectories for an explanation of the
+internal organization of the header files.
diff --git a/ext/systemc/src/sysc/communication/sc_buffer.h b/ext/systemc/src/sysc/communication/sc_buffer.h
new file mode 100644
index 000000000..e91c1a7c9
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_buffer.h
@@ -0,0 +1,194 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_buffer.h -- The sc_buffer<T> primitive channel class.
+ Like sc_signal<T>, but *every* write causes an event.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_BUFFER_H
+#define SC_BUFFER_H
+
+
+#include "sysc/communication/sc_signal.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_buffer<T>
+//
+// The sc_buffer<T> primitive channel class.
+// ----------------------------------------------------------------------------
+
+template< typename T, sc_writer_policy POL = SC_DEFAULT_WRITER_POLICY >
+class sc_buffer
+: public sc_signal<T,POL>
+{
+public:
+
+ // typedefs
+
+ typedef sc_buffer<T,POL> this_type;
+ typedef sc_signal<T,POL> base_type;
+
+public:
+
+ // constructors
+
+ sc_buffer()
+ : base_type( sc_gen_unique_name( "buffer" ) )
+ {}
+
+ explicit sc_buffer( const char* name_ )
+ : base_type( name_ )
+ {}
+
+ sc_buffer( const char* name_, const T& initial_value_ )
+ : base_type( name_, initial_value_ )
+ {}
+
+ // interface methods
+
+ // write the new value
+ virtual void write( const T& );
+
+
+ // other methods
+
+ this_type& operator = ( const T& a )
+ { write( a ); return *this; }
+
+ this_type& operator = ( const sc_signal_in_if<T>& a )
+ { write( a.read() ); return *this; }
+
+ this_type& operator = ( const this_type& a )
+ { write( a.read() ); return *this; }
+
+ virtual const char* kind() const
+ { return "sc_buffer"; }
+
+protected:
+
+ virtual void update();
+
+private:
+
+ // disabled
+ sc_buffer( const this_type& );
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+// write the new value
+
+template< typename T, sc_writer_policy POL >
+inline
+void
+sc_buffer<T,POL>::write( const T& value_ )
+{
+ if( !base_type::policy_type::check_write(this,true) )
+ return;
+
+ this->m_new_val = value_;
+ this->request_update();
+}
+
+
+template< typename T, sc_writer_policy POL >
+inline
+void
+sc_buffer<T,POL>::update()
+{
+ base_type::policy_type::update();
+ base_type::do_update();
+}
+
+} // namespace sc_core
+
+#endif
+
+//$Log: sc_buffer.h,v $
+//Revision 1.7 2011/08/26 20:45:39 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+//Revision 1.6 2011/04/08 18:22:45 acg
+// Philipp A. Hartmann: use the context of the primitive channel to get
+// the change stamp value.
+//
+//Revision 1.5 2011/04/05 20:48:09 acg
+// Andy Goodrich: changes to make sure that event(), posedge() and negedge()
+// only return true if the clock has not moved.
+//
+//Revision 1.4 2011/04/05 06:15:18 acg
+// Philipp A. Hartmann: sc_writer_policy: ignore no-ops in delta check.
+//
+//Revision 1.3 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+//Revision 1.2 2010/12/07 19:50:36 acg
+// Andy Goodrich: addition of writer policies, courtesy of Philipp Hartmann.
+//
+//Revision 1.1.1.1 2006/12/15 20:20:04 acg
+//SystemC 2.3
+//
+//Revision 1.8 2006/03/13 20:19:43 acg
+// Andy Goodrich: changed sc_event instances into pointers to sc_event instances
+// that are allocated as needed. This saves considerable storage for large
+// numbers of signals, etc.
+//
+//Revision 1.7 2006/01/26 21:00:49 acg
+// Andy Goodrich: conversion to use sc_event::notify(SC_ZERO_TIME) instead of
+// sc_event::notify_delayed()
+//
+//Revision 1.6 2006/01/24 20:46:31 acg
+//Andy Goodrich: changes to eliminate use of deprecated features. For instance,
+//using notify(SC_ZERO_TIME) in place of notify_delayed().
+//
+//Revision 1.5 2006/01/19 19:18:25 acg
+//Andy Goodrich: eliminated check_writer in favor of inline code within the
+//write() method since we always execute the check_writer code even when
+//check writing is turned off.
+//
+//Revision 1.4 2006/01/19 00:30:57 acg
+//Andy Goodrich: Yet another implementation for disabling write checks on
+//signals. This version uses an environment variable, SC_SIGNAL_WRITE_CHECK,
+//that when set to DISABLE will turn off write checking.
+//
+//Revision 1.3 2006/01/13 18:47:20 acg
+//Reversed sense of multiwriter signal check. It now defaults to ON unless the
+//user defines SC_NO_WRITE_CHEK before inclusion of the file.
+//
+//Revision 1.2 2006/01/03 23:18:26 acg
+//Changed copyright to include 2006.
+//
+//Revision 1.1.1.1 2005/12/19 23:16:43 acg
+//First check in of SystemC 2.1 into its own archive.
+//
+//Revision 1.9 2005/06/10 22:43:55 acg
+//Added CVS change log annotation.
+//
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_clock.cpp b/ext/systemc/src/sysc/communication/sc_clock.cpp
new file mode 100644
index 000000000..158d54b7a
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_clock.cpp
@@ -0,0 +1,409 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_clock.cpp -- The clock channel.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+// using notify_delayed().
+//
+// Revision 1.4 2006/01/18 21:42:26 acg
+// Andy Goodrich: Changes for check writer support, and tightening up sc_clock
+// port usage.
+//
+// Revision 1.3 2006/01/13 18:47:41 acg
+// Added $Log command so that CVS comments are reproduced in the source.
+//
+
+#include "sysc/communication/sc_clock.h"
+#include "sysc/communication/sc_communication_ids.h"
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_process.h"
+#include "sysc/kernel/sc_spawn.h"
+#include "sysc/utils/sc_utils_ids.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_clock
+//
+// The clock channel.
+// ----------------------------------------------------------------------------
+
+// constructors
+
+sc_clock::sc_clock() :
+ base_type( sc_gen_unique_name( "clock" ) ),
+ m_period(), m_duty_cycle(), m_start_time(), m_posedge_first(),
+ m_posedge_time(), m_negedge_time(),
+ m_next_posedge_event( (std::string(SC_KERNEL_EVENT_PREFIX) +
+ "_next_posedge_event").c_str()),
+ m_next_negedge_event( (std::string(SC_KERNEL_EVENT_PREFIX) +
+ "_next_negedge_event").c_str())
+
+{
+ init( sc_time::from_value(simcontext()->m_time_params->default_time_unit),
+ 0.5,
+ SC_ZERO_TIME,
+ true );
+
+ m_next_posedge_event.notify_internal( m_start_time );
+}
+
+sc_clock::sc_clock( const char* name_ ) :
+ base_type( name_ ),
+ m_period(), m_duty_cycle(), m_start_time(), m_posedge_first(),
+ m_posedge_time(), m_negedge_time(),
+ m_next_posedge_event( (std::string(SC_KERNEL_EVENT_PREFIX) +
+ std::string(name_) + "_next_posedge_event").c_str()),
+ m_next_negedge_event( (std::string(SC_KERNEL_EVENT_PREFIX) +
+ std::string(name_) + "_next_negedge_event").c_str())
+{
+ init( sc_time::from_value(simcontext()->m_time_params->default_time_unit),
+ 0.5,
+ SC_ZERO_TIME,
+ true );
+
+ m_next_posedge_event.notify_internal( m_start_time );
+}
+
+sc_clock::sc_clock( const char* name_,
+ const sc_time& period_,
+ double duty_cycle_,
+ const sc_time& start_time_,
+ bool posedge_first_ ) :
+ base_type( name_ ),
+ m_period(), m_duty_cycle(), m_start_time(), m_posedge_first(),
+ m_posedge_time(), m_negedge_time(),
+ m_next_posedge_event( (std::string(SC_KERNEL_EVENT_PREFIX) +
+ std::string(name_) + "_next_posedge_event").c_str()),
+ m_next_negedge_event( (std::string(SC_KERNEL_EVENT_PREFIX) +
+ std::string(name_) + "_next_negedge_event").c_str())
+{
+ init( period_,
+ duty_cycle_,
+ start_time_,
+ posedge_first_ );
+
+ if( posedge_first_ ) {
+ // posedge first
+ m_next_posedge_event.notify_internal( m_start_time );
+ } else {
+ // negedge first
+ m_next_negedge_event.notify_internal( m_start_time );
+ }
+}
+
+sc_clock::sc_clock( const char* name_,
+ double period_v_,
+ sc_time_unit period_tu_,
+ double duty_cycle_ ) :
+ base_type( name_ ),
+ m_period(), m_duty_cycle(), m_start_time(), m_posedge_first(),
+ m_posedge_time(), m_negedge_time(),
+ m_next_posedge_event( (std::string(SC_KERNEL_EVENT_PREFIX) +
+ std::string(name_) + "_next_posedge_event").c_str()),
+ m_next_negedge_event( (std::string(SC_KERNEL_EVENT_PREFIX) +
+ std::string(name_) + "_next_negedge_event").c_str())
+{
+ init( sc_time( period_v_, period_tu_, simcontext() ),
+ duty_cycle_,
+ SC_ZERO_TIME,
+ true );
+
+ // posedge first
+ m_next_posedge_event.notify_internal( m_start_time );
+}
+
+sc_clock::sc_clock( const char* name_,
+ double period_v_,
+ sc_time_unit period_tu_,
+ double duty_cycle_,
+ double start_time_v_,
+ sc_time_unit start_time_tu_,
+ bool posedge_first_ ) :
+ base_type( name_ ),
+ m_period(), m_duty_cycle(), m_start_time(), m_posedge_first(),
+ m_posedge_time(), m_negedge_time(),
+ m_next_posedge_event( (std::string(SC_KERNEL_EVENT_PREFIX) +
+ std::string(name_) + "_next_posedge_event").c_str()),
+ m_next_negedge_event( (std::string(SC_KERNEL_EVENT_PREFIX) +
+ std::string(name_) + "_next_negedge_event").c_str())
+{
+ init( sc_time( period_v_, period_tu_, simcontext() ),
+ duty_cycle_,
+ sc_time( start_time_v_, start_time_tu_, simcontext() ),
+ posedge_first_ );
+
+ if( posedge_first_ ) {
+ // posedge first
+ m_next_posedge_event.notify_internal( m_start_time );
+ } else {
+ // negedge first
+ m_next_negedge_event.notify_internal( m_start_time );
+ }
+}
+
+// for backward compatibility with 1.0
+sc_clock::sc_clock( const char* name_,
+ double period_, // in default time units
+ double duty_cycle_,
+ double start_time_, // in default time units
+ bool posedge_first_ ) :
+ base_type( name_ ),
+ m_period(), m_duty_cycle(), m_start_time(), m_posedge_first(),
+ m_posedge_time(), m_negedge_time(),
+ m_next_posedge_event( (std::string(SC_KERNEL_EVENT_PREFIX) +
+ std::string(name_) + "_next_posedge_event").c_str()),
+ m_next_negedge_event( (std::string(SC_KERNEL_EVENT_PREFIX) +
+ std::string(name_) + "_next_negedge_event").c_str())
+{
+ static bool warn_sc_clock=true;
+ if ( warn_sc_clock )
+ {
+ warn_sc_clock = false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "\n sc_clock(const char*, double, double, double, bool)\n"
+ " is deprecated use a form that includes sc_time or\n"
+ " sc_time_unit");
+ }
+
+ sc_time default_time =
+ sc_time::from_value( simcontext()->m_time_params->default_time_unit );
+
+ init( ( period_ * default_time ),
+ duty_cycle_,
+ ( start_time_ * default_time ),
+ posedge_first_ );
+
+ if( posedge_first_ ) {
+ // posedge first
+ m_next_posedge_event.notify_internal( m_start_time );
+ } else {
+ // negedge first
+ m_next_negedge_event.notify_internal( m_start_time );
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_clock::before_end_of_elaboration"
+//
+// This callback is used to spawn the edge processes for this object instance.
+// The processes are created here rather than the constructor for the object
+// so that the processes are registered with the global simcontext rather
+// than the scope of the clock's parent.
+//------------------------------------------------------------------------------
+#if ( defined(_MSC_VER) && _MSC_VER < 1300 ) //VC++6.0 doesn't support sc_spawn with functor.
+# define sc_clock_posedge_callback(ptr) sc_clock_posedge_callback
+
+# define sc_clock_negedge_callback(ptr) sc_clock_negedge_callback
+
+# define sc_spawn(a,b,c) { \
+ sc_process_handle result(new sc_spawn_object<a>(a(this),b,c)); \
+ }
+#endif // ( defined(_MSC_VER) && _MSC_VER < 1300 )
+
+void sc_clock::before_end_of_elaboration()
+{
+ std::string gen_base;
+ sc_spawn_options posedge_options; // Options for posedge process.
+ sc_spawn_options negedge_options; // Options for negedge process.
+
+ posedge_options.spawn_method();
+ posedge_options.dont_initialize();
+ posedge_options.set_sensitivity(&m_next_posedge_event);
+ gen_base = basename();
+ gen_base += "_posedge_action";
+ sc_spawn(sc_clock_posedge_callback(this),
+ sc_gen_unique_name( gen_base.c_str() ), &posedge_options);
+
+ negedge_options.spawn_method();
+ negedge_options.dont_initialize();
+ negedge_options.set_sensitivity(&m_next_negedge_event);
+ gen_base = basename();
+ gen_base += "_negedge_action";
+ sc_spawn( sc_clock_negedge_callback(this),
+ sc_gen_unique_name( gen_base.c_str() ), &negedge_options );
+}
+
+//clear VC++6.0 macros
+#undef sc_clock_posedge_callback
+#undef sc_clock_negedge_callback
+#undef sc_spawn
+
+// destructor (does nothing)
+
+sc_clock::~sc_clock()
+{}
+
+void sc_clock::register_port( sc_port_base& /*port*/, const char* if_typename_ )
+{
+ std::string nm( if_typename_ );
+ if( nm == typeid( sc_signal_inout_if<bool> ).name() ) {
+ SC_REPORT_ERROR(SC_ID_ATTEMPT_TO_BIND_CLOCK_TO_OUTPUT_, "");
+ }
+}
+
+void
+sc_clock::write( const bool& /* value */ )
+{
+ SC_REPORT_ERROR(SC_ID_ATTEMPT_TO_WRITE_TO_CLOCK_, "");
+}
+
+// interface methods
+
+// get the current time
+
+const sc_time&
+sc_clock::time_stamp()
+{
+ return sc_time_stamp();
+}
+
+
+// error reporting
+
+void
+sc_clock::report_error( const char* id, const char* add_msg ) const
+{
+ char msg[BUFSIZ];
+ if( add_msg != 0 ) {
+ std::sprintf( msg, "%s: clock '%s'", add_msg, name() );
+ } else {
+ std::sprintf( msg, "clock '%s'", name() );
+ }
+ SC_REPORT_ERROR( id, msg );
+}
+
+
+void
+sc_clock::init( const sc_time& period_,
+ double duty_cycle_,
+ const sc_time& start_time_,
+ bool posedge_first_ )
+{
+ if( period_ == SC_ZERO_TIME ) {
+ report_error( SC_ID_CLOCK_PERIOD_ZERO_,
+ "increase the period" );
+ }
+ m_period = period_;
+ m_posedge_first = posedge_first_;
+
+ if( duty_cycle_ <= 0.0 || duty_cycle_ >= 1.0 ) {
+ m_duty_cycle = 0.5;
+ } else {
+ m_duty_cycle = duty_cycle_;
+ }
+
+ m_negedge_time = m_period * m_duty_cycle;
+ m_posedge_time = m_period - m_negedge_time;
+
+ if( m_negedge_time == SC_ZERO_TIME ) {
+ report_error( SC_ID_CLOCK_HIGH_TIME_ZERO_,
+ "increase the period or increase the duty cycle" );
+ }
+ if( m_posedge_time == SC_ZERO_TIME ) {
+ report_error( SC_ID_CLOCK_LOW_TIME_ZERO_,
+ "increase the period or decrease the duty cycle" );
+ }
+
+ if( posedge_first_ ) {
+ this->m_cur_val = false;
+ this->m_new_val = false;
+ } else {
+ this->m_cur_val = true;
+ this->m_new_val = true;
+ }
+
+ m_start_time = start_time_;
+
+}
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Bishnupriya Bhattacharya, Cadence Design Systems,
+ Andy Goodrich, Forte Design Systems,
+ 3 October, 2003
+ Description of Modification: sc_clock inherits from sc_signal<bool> only
+ instead of sc_signal_in_if<bool> and sc_module.
+ The 2 methods posedge_action() and
+ negedge_action() are created using sc_spawn().
+ boost::bind() is not required, instead a local
+ bind function can be used since the signatures
+ of the spawned functions are statically known.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_clock.cpp,v $
+// Revision 1.7 2011/08/26 20:45:39 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.6 2011/08/24 22:05:35 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.5 2011/08/15 16:43:24 acg
+// Torsten Maehne: changes to remove unused argument warnings.
+//
+// Revision 1.4 2011/03/12 21:07:42 acg
+// Andy Goodrich: changes to kernel generated event support.
+//
+// Revision 1.3 2011/03/06 15:55:08 acg
+// Andy Goodrich: Changes for named events.
+//
+// Revision 1.2 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.8 2006/04/18 23:36:50 acg
+// Andy Goodrich: made add_trace_internal public until I can figure out
+// how to do a friend specification for sc_trace in an environment where
+// there are partial template and full template specifications for its
+// arguments.
+//
+// Revision 1.7 2006/04/17 16:38:42 acg
+// Andy Goodrich: added more context to the deprecation message for the
+// sc_clock constructor.
+//
+// Revision 1.6 2006/01/25 00:31:11 acg
+// Andy Goodrich: Changed over to use a standard message id of
+// SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
+//
+// Revision 1.5 2006/01/24 20:43:24 acg
+// Andy Goodrich: convert notify_delayed() calls into notify_internal() calls.
+// notify_internal() is an implementation dependent version of notify_delayed()
+// that is simpler, and does not trigger the deprecation warning one would get
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_clock.h b/ext/systemc/src/sysc/communication/sc_clock.h
new file mode 100644
index 000000000..634936ce6
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_clock.h
@@ -0,0 +1,275 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_clock.h -- The clock channel.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_CLOCK_H
+#define SC_CLOCK_H
+
+
+#include "sysc/kernel/sc_module.h"
+#include "sysc/communication/sc_signal.h"
+#include "sysc/tracing/sc_trace.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_clock
+//
+// The clock channel.
+// ----------------------------------------------------------------------------
+
+class sc_clock
+ : public sc_signal<bool,SC_ONE_WRITER>
+{
+ typedef sc_signal<bool,SC_ONE_WRITER> base_type;
+public:
+
+ friend class sc_clock_posedge_callback;
+ friend class sc_clock_negedge_callback;
+
+ // constructors
+
+ sc_clock();
+
+ explicit sc_clock( const char* name_ );
+
+ sc_clock( const char* name_,
+ const sc_time& period_,
+ double duty_cycle_ = 0.5,
+ const sc_time& start_time_ = SC_ZERO_TIME,
+ bool posedge_first_ = true );
+
+ sc_clock( const char* name_,
+ double period_v_,
+ sc_time_unit period_tu_,
+ double duty_cycle_ = 0.5 );
+
+ sc_clock( const char* name_,
+ double period_v_,
+ sc_time_unit period_tu_,
+ double duty_cycle_,
+ double start_time_v_,
+ sc_time_unit start_time_tu_,
+ bool posedge_first_ = true );
+
+ // for backward compatibility with 1.0
+ sc_clock( const char* name_,
+ double period_, // in default time units
+ double duty_cycle_ = 0.5,
+ double start_time_ = 0.0, // in default time units
+ bool posedge_first_ = true );
+
+ // destructor (does nothing)
+ virtual ~sc_clock();
+
+ virtual void register_port( sc_port_base&, const char* if_type );
+ virtual void write( const bool& );
+
+ // get the period
+ const sc_time& period() const
+ { return m_period; }
+
+ // get the duty cycle
+ double duty_cycle() const
+ { return m_duty_cycle; }
+
+
+ // get the current time / clock characteristics
+
+ bool posedge_first() const
+ { return m_posedge_first; }
+
+ sc_time start_time() const
+ { return m_start_time; }
+
+ static const sc_time& time_stamp();
+
+ virtual const char* kind() const
+ { return "sc_clock"; }
+
+
+#if 0 // @@@@#### REMOVE
+ // for backward compatibility with 1.0
+
+ sc_signal_in_if<bool>& signal()
+ { return *this; }
+
+ const sc_signal_in_if<bool>& signal() const
+ { return *this; }
+
+ static void start( const sc_time& duration )
+ { sc_start( duration ); }
+
+ static void start( double v, sc_time_unit tu )
+ { sc_start( sc_time(v, tu) ); }
+
+ static void start( double duration = -1 )
+ { sc_start( duration ); }
+
+ static void stop()
+ { sc_stop(); }
+#endif
+
+protected:
+
+ void before_end_of_elaboration();
+
+ // processes
+ void posedge_action();
+ void negedge_action();
+
+
+ // error reporting
+ void report_error( const char* id, const char* add_msg = 0 ) const;
+
+
+ void init( const sc_time&, double, const sc_time&, bool );
+
+ bool is_clock() const { return true; }
+
+protected:
+
+ sc_time m_period; // the period of this clock
+ double m_duty_cycle; // the duty cycle (fraction of period)
+ sc_time m_start_time; // the start time of the first edge
+ bool m_posedge_first; // true if first edge is positive
+ sc_time m_posedge_time; // time till next positive edge
+ sc_time m_negedge_time; // time till next negative edge
+
+ sc_event m_next_posedge_event;
+ sc_event m_next_negedge_event;
+
+private:
+
+ // disabled
+ sc_clock( const sc_clock& );
+ sc_clock& operator = ( const sc_clock& );
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+// processes
+
+inline
+void
+sc_clock::posedge_action()
+{
+ m_next_negedge_event.notify_internal( m_negedge_time );
+ m_new_val = true;
+ request_update();
+}
+
+inline
+void
+sc_clock::negedge_action()
+{
+ m_next_posedge_event.notify_internal( m_posedge_time );
+ m_new_val = false;
+ request_update();
+}
+
+
+// ----------------------------------------------------------------------------
+
+class sc_clock_posedge_callback {
+public:
+ sc_clock_posedge_callback(sc_clock* target_p) : m_target_p(target_p) {}
+ inline void operator () () { m_target_p->posedge_action(); }
+ protected:
+ sc_clock* m_target_p;
+};
+
+class sc_clock_negedge_callback {
+ public:
+ sc_clock_negedge_callback(sc_clock* target_p) : m_target_p(target_p) {}
+ inline void operator () () { m_target_p->negedge_action(); }
+ protected:
+ sc_clock* m_target_p;
+};
+
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Bishnupriya Bhattacharya, Cadence Design Systems,
+ 3 October, 2003
+ Description of Modification: sc_clock inherits from sc_signal<bool> only
+ instead of sc_signal_in_if<bool> and sc_module.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+//$Log: sc_clock.h,v $
+//Revision 1.5 2011/08/26 20:45:39 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+//Revision 1.4 2011/08/24 22:05:35 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+//Revision 1.3 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+//Revision 1.2 2011/01/20 16:52:15 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+//Revision 1.1.1.1 2006/12/15 20:20:04 acg
+//SystemC 2.3
+//
+//Revision 1.5 2006/01/25 00:31:11 acg
+// Andy Goodrich: Changed over to use a standard message id of
+// SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
+//
+//Revision 1.4 2006/01/24 20:43:25 acg
+// Andy Goodrich: convert notify_delayed() calls into notify_internal() calls.
+// notify_internal() is an implementation dependent version of notify_delayed()
+// that is simpler, and does not trigger the deprecation warning one would get
+// using notify_delayed().
+//
+//Revision 1.3 2006/01/18 21:42:26 acg
+//Andy Goodrich: Changes for check writer support, and tightening up sc_clock
+//port usage.
+//
+//Revision 1.2 2006/01/03 23:18:26 acg
+//Changed copyright to include 2006.
+//
+//Revision 1.1.1.1 2005/12/19 23:16:43 acg
+//First check in of SystemC 2.1 into its own archive.
+//
+//Revision 1.14 2005/06/10 22:43:55 acg
+//Added CVS change log annotation.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_clock_ports.h b/ext/systemc/src/sysc/communication/sc_clock_ports.h
new file mode 100644
index 000000000..70ac80c1d
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_clock_ports.h
@@ -0,0 +1,72 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_clock_ports.h -- The clock ports.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_CLOCK_PORTS_H
+#define SC_CLOCK_PORTS_H
+
+
+#include "sysc/communication/sc_signal_ports.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// The clock ports.
+//
+// (Provided for backward compatibility reasons.)
+// ----------------------------------------------------------------------------
+
+typedef sc_in<bool> sc_in_clk;
+typedef sc_inout<bool> sc_inout_clk;
+typedef sc_out<bool> sc_out_clk;
+
+} // namespace sc_core
+
+//$Log: sc_clock_ports.h,v $
+//Revision 1.3 2011/08/26 20:45:39 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+//Revision 1.2 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+//Revision 1.1.1.1 2006/12/15 20:20:04 acg
+//SystemC 2.3
+//
+//Revision 1.2 2006/01/03 23:18:26 acg
+//Changed copyright to include 2006.
+//
+//Revision 1.1.1.1 2005/12/19 23:16:43 acg
+//First check in of SystemC 2.1 into its own archive.
+//
+//Revision 1.8 2005/06/10 22:43:55 acg
+//Added CVS change log annotation.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_communication_ids.h b/ext/systemc/src/sysc/communication/sc_communication_ids.h
new file mode 100644
index 000000000..fe9995775
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_communication_ids.h
@@ -0,0 +1,164 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_communication_ids.h -- Report ids for the communication code.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2002-01-17
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_COMMUNICATION_IDS_H
+#define SC_COMMUNICATION_IDS_H
+
+
+#include "sysc/utils/sc_report.h"
+
+
+// ----------------------------------------------------------------------------
+// Report ids (communication)
+//
+// Report ids in the range of 100-199.
+// ----------------------------------------------------------------------------
+
+#ifndef SC_DEFINE_MESSAGE
+#define SC_DEFINE_MESSAGE(id,unused1,unused2) \
+ namespace sc_core { extern const char id[]; }
+namespace sc_core {
+ extern const char SC_ID_REGISTER_ID_FAILED_[]; // in sc_report_handler.cpp
+} // namespace sc_core
+#endif
+
+SC_DEFINE_MESSAGE( SC_ID_PORT_OUTSIDE_MODULE_, 100,
+ "port specified outside of module" )
+SC_DEFINE_MESSAGE( SC_ID_CLOCK_PERIOD_ZERO_, 101,
+ "sc_clock period is zero" )
+SC_DEFINE_MESSAGE( SC_ID_CLOCK_HIGH_TIME_ZERO_, 102,
+ "sc_clock high time is zero" )
+SC_DEFINE_MESSAGE( SC_ID_CLOCK_LOW_TIME_ZERO_, 103,
+ "sc_clock low time is zero" )
+SC_DEFINE_MESSAGE( SC_ID_MORE_THAN_ONE_FIFO_READER_, 104,
+ "sc_fifo<T> cannot have more than one reader" )
+SC_DEFINE_MESSAGE( SC_ID_MORE_THAN_ONE_FIFO_WRITER_, 105,
+ "sc_fifo<T> cannot have more than one writer" )
+SC_DEFINE_MESSAGE( SC_ID_INVALID_FIFO_SIZE_, 106,
+ "sc_fifo<T> must have a size of at least 1" )
+SC_DEFINE_MESSAGE( SC_ID_BIND_IF_TO_PORT_, 107,
+ "bind interface to port failed" )
+SC_DEFINE_MESSAGE( SC_ID_BIND_PORT_TO_PORT_, 108,
+ "bind parent port to port failed" )
+SC_DEFINE_MESSAGE( SC_ID_COMPLETE_BINDING_, 109,
+ "complete binding failed" )
+SC_DEFINE_MESSAGE( SC_ID_INSERT_PORT_, 110,
+ "insert port failed" )
+SC_DEFINE_MESSAGE( SC_ID_REMOVE_PORT_, 111,
+ "remove port failed" )
+SC_DEFINE_MESSAGE( SC_ID_GET_IF_, 112,
+ "get interface failed" )
+SC_DEFINE_MESSAGE( SC_ID_INSERT_PRIM_CHANNEL_, 113,
+ "insert primitive channel failed" )
+SC_DEFINE_MESSAGE( SC_ID_REMOVE_PRIM_CHANNEL_, 114,
+ "remove primitive channel failed" )
+SC_DEFINE_MESSAGE( SC_ID_MORE_THAN_ONE_SIGNAL_DRIVER_, 115,
+ "sc_signal<T> cannot have more than one driver" )
+SC_DEFINE_MESSAGE( SC_ID_NO_DEFAULT_EVENT_, 116,
+ "channel doesn't have a default event" )
+SC_DEFINE_MESSAGE( SC_ID_RESOLVED_PORT_NOT_BOUND_, 117,
+ "resolved port not bound to resolved signal" )
+SC_DEFINE_MESSAGE( SC_ID_FIND_EVENT_, 118,
+ "find event failed" )
+SC_DEFINE_MESSAGE( SC_ID_INVALID_SEMAPHORE_VALUE_, 119,
+ "sc_semaphore requires an initial value >= 0" )
+SC_DEFINE_MESSAGE( SC_ID_SC_EXPORT_HAS_NO_INTERFACE_, 120,
+ "sc_export instance has no interface" )
+SC_DEFINE_MESSAGE( SC_ID_INSERT_EXPORT_, 121,
+ "insert sc_export failed" )
+SC_DEFINE_MESSAGE( SC_ID_SC_EXPORT_NOT_REGISTERED_, 123,
+ "remove sc_export failed, sc_export not registered" )
+SC_DEFINE_MESSAGE( SC_ID_SC_EXPORT_NOT_BOUND_AFTER_CONSTRUCTION_, 124,
+ "sc_export instance not bound to interface at end of construction" )
+SC_DEFINE_MESSAGE( SC_ID_ATTEMPT_TO_WRITE_TO_CLOCK_, 125,
+ "attempt to write the value of an sc_clock instance" )
+SC_DEFINE_MESSAGE( SC_ID_SC_EXPORT_ALREADY_BOUND_, 126,
+ "sc_export instance already bound" )
+SC_DEFINE_MESSAGE( SC_ID_OPERATION_ON_NON_SPECIALIZED_SIGNAL_, 127,
+ "attempted specalized signal operation on non-specialized signal" )
+SC_DEFINE_MESSAGE( SC_ID_ATTEMPT_TO_BIND_CLOCK_TO_OUTPUT_, 128,
+ "attempted to bind sc_clock instance to sc_inout or sc_out" )
+SC_DEFINE_MESSAGE( SC_ID_NO_ASYNC_UPDATE_, 129,
+ "this build has no asynchronous update support" )
+
+/*
+$Log: sc_communication_ids.h,v $
+Revision 1.5 2011/08/26 20:45:39 acg
+ Andy Goodrich: moved the modification log to the end of the file to
+ eliminate source line number skew when check-ins are done.
+
+Revision 1.4 2011/04/19 02:36:26 acg
+ Philipp A. Hartmann: new aysnc_update and mutex support.
+
+Revision 1.3 2011/02/18 20:23:45 acg
+ Andy Goodrich: Copyright update.
+
+Revision 1.2 2011/02/14 17:50:16 acg
+ Andy Goodrich: testing for sc_port and sc_export instantiations during
+ end of elaboration and issuing appropriate error messages.
+
+Revision 1.1.1.1 2006/12/15 20:20:04 acg
+SystemC 2.3
+
+Revision 1.5 2006/01/25 00:31:11 acg
+ Andy Goodrich: Changed over to use a standard message id of
+ SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
+
+Revision 1.4 2006/01/24 20:46:31 acg
+Andy Goodrich: changes to eliminate use of deprecated features. For instance,
+using notify(SC_ZERO_TIME) in place of notify_delayed().
+
+Revision 1.3 2006/01/18 21:42:26 acg
+Andy Goodrich: Changes for check writer support, and tightening up sc_clock
+port usage.
+
+Revision 1.2 2006/01/03 23:18:26 acg
+Changed copyright to include 2006.
+
+Revision 1.1.1.1 2005/12/19 23:16:43 acg
+First check in of SystemC 2.1 into its own archive.
+
+Revision 1.12 2005/04/03 22:52:51 acg
+Namespace changes.
+
+Revision 1.11 2005/03/21 22:31:32 acg
+Changes to sc_core namespace.
+
+Revision 1.10 2004/10/28 00:21:48 acg
+Added check that sc_export instances are not bound twice.
+
+Revision 1.9 2004/09/27 21:02:54 acg
+Andy Goodrich - Forte Design Systems, Inc.
+ - Added a $Log comment so that CVS checkin comments will appear in
+ checked out source.
+
+*/
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_event_finder.cpp b/ext/systemc/src/sysc/communication/sc_event_finder.cpp
new file mode 100644
index 000000000..25d16a1f5
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_event_finder.cpp
@@ -0,0 +1,113 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_event_finder.cpp --
+
+ Original Author: Martin Janssen, Synopsys, Inc.
+ Stan Y. Liao, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include "sysc/communication/sc_event_finder.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_event_finder
+//
+// Event finder base class.
+// ----------------------------------------------------------------------------
+
+// error reporting
+
+void
+sc_event_finder::report_error( const char* id, const char* add_msg ) const
+{
+ char msg[BUFSIZ];
+ if( add_msg != 0 ) {
+ std::sprintf( msg, "%s: port '%s' (%s)",
+ add_msg, m_port.name(), m_port.kind() );
+ } else {
+ std::sprintf( msg, "port '%s' (%s)", m_port.name(), m_port.kind() );
+ }
+ SC_REPORT_ERROR( id, msg );
+}
+
+
+// constructor
+
+sc_event_finder::sc_event_finder( const sc_port_base& port_ )
+: m_port( port_ )
+{
+}
+
+
+// destructor (does nothing)
+
+sc_event_finder::~sc_event_finder()
+{}
+
+} // namespace sc_core
+
+// $Log: sc_event_finder.cpp,v $
+// Revision 1.3 2011/08/26 20:45:39 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.2 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.7 2006/02/02 23:42:37 acg
+// Andy Goodrich: implemented a much better fix to the sc_event_finder
+// proliferation problem. This new version allocates only a single event
+// finder for each port for each type of event, e.g., pos(), neg(), and
+// value_change(). The event finder persists as long as the port does,
+// which is what the LRM dictates. Because only a single instance is
+// allocated for each event type per port there is not a potential
+// explosion of storage as was true in the 2.0.1/2.1 versions.
+//
+// Revision 1.6 2006/02/02 21:26:34 acg
+// Andy Goodrich: pulled out the check I just stuck into the
+// sc_event_finder::free_instances() method. It turns out the LRM says that
+// sc_event_finder instances are valid as long as the sc_module hierarchy is
+// valid, so we can't give the user a call to free the instances.
+//
+// Revision 1.5 2006/02/02 21:10:52 acg
+// Andy Goodrich: added check for end of elaboration to the static method
+// sc_event_finder::free_instances(). This will allow the method to be
+// made public if that is desired.
+//
+// Revision 1.4 2006/02/02 20:43:09 acg
+// Andy Goodrich: Added an existence linked list to sc_event_finder so that
+// the dynamically allocated instances can be freed after port binding
+// completes. This replaces the individual deletions in ~sc_bind_ef, as these
+// caused an exception if an sc_event_finder instance was used more than
+// once, due to a double freeing of the instance.
+//
+// Revision 1.3 2006/01/13 18:47:41 acg
+// Added $Log command so that CVS comments are reproduced in the source.
+//
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_event_finder.h b/ext/systemc/src/sysc/communication/sc_event_finder.h
new file mode 100644
index 000000000..15205553f
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_event_finder.h
@@ -0,0 +1,178 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_event_finder.h --
+
+ Original Author: Martin Janssen, Synopsys, Inc.
+ Stan Y. Liao, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_EVENT_FINDER
+#define SC_EVENT_FINDER
+
+
+#include "sysc/communication/sc_port.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_event_finder
+//
+// Event finder base class.
+// ----------------------------------------------------------------------------
+
+class sc_event_finder
+{
+ friend class sc_simcontext;
+
+public:
+
+ const sc_port_base& port() const
+ { return m_port; }
+
+ // destructor (does nothing)
+ virtual ~sc_event_finder();
+
+ virtual const sc_event& find_event( sc_interface* if_p = 0 ) const = 0;
+
+protected:
+
+ // constructor
+ sc_event_finder( const sc_port_base& );
+
+ // error reporting
+ void report_error( const char* id, const char* add_msg = 0 ) const;
+
+
+private:
+ const sc_port_base& m_port; // port providing the event.
+
+private:
+
+ // disabled
+ sc_event_finder();
+ sc_event_finder( const sc_event_finder& );
+ sc_event_finder& operator = ( const sc_event_finder& );
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_event_finder_t<IF>
+//
+// Interface specific event finder class.
+// ----------------------------------------------------------------------------
+
+template <class IF>
+class sc_event_finder_t
+: public sc_event_finder
+{
+public:
+
+ // constructor
+
+ sc_event_finder_t( const sc_port_base& port_,
+ const sc_event& (IF::*event_method_) () const )
+ : sc_event_finder( port_ ), m_event_method( event_method_ )
+ {}
+
+ // destructor (does nothing)
+
+ virtual ~sc_event_finder_t()
+ {}
+
+ virtual const sc_event& find_event( sc_interface* if_p = 0 ) const;
+
+private:
+
+ const sc_event& (IF::*m_event_method) () const;
+
+private:
+
+ // disabled
+ sc_event_finder_t();
+ sc_event_finder_t( const sc_event_finder_t<IF>& );
+ sc_event_finder_t<IF>& operator = ( const sc_event_finder_t<IF>& );
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+template <class IF>
+inline
+const sc_event&
+sc_event_finder_t<IF>::find_event( sc_interface* if_p ) const
+{
+ const IF* iface = ( if_p ) ? DCAST<const IF*>( if_p ) :
+ DCAST<const IF*>( port().get_interface() );
+ if( iface == 0 ) {
+ report_error( SC_ID_FIND_EVENT_, "port is not bound" );
+ }
+ return (CCAST<IF*>( iface )->*m_event_method) ();
+}
+
+} // namespace sc_core
+
+//$Log: sc_event_finder.h,v $
+//Revision 1.3 2011/08/26 20:45:39 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+//Revision 1.2 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+//Revision 1.1.1.1 2006/12/15 20:20:04 acg
+//SystemC 2.3
+//
+//Revision 1.4 2006/02/02 23:42:37 acg
+// Andy Goodrich: implemented a much better fix to the sc_event_finder
+// proliferation problem. This new version allocates only a single event
+// finder for each port for each type of event, e.g., pos(), neg(), and
+// value_change(). The event finder persists as long as the port does,
+// which is what the LRM dictates. Because only a single instance is
+// allocated for each event type per port there is not a potential
+// explosion of storage as was true in the 2.0.1/2.1 versions.
+//
+//Revision 1.3 2006/02/02 20:43:09 acg
+// Andy Goodrich: Added an existence linked list to sc_event_finder so that
+// the dynamically allocated instances can be freed after port binding
+// completes. This replaces the individual deletions in ~sc_bind_ef, as these
+// caused an exception if an sc_event_finder instance was used more than
+// once, due to a double freeing of the instance.
+//
+//Revision 1.2 2006/01/03 23:18:26 acg
+//Changed copyright to include 2006.
+//
+//Revision 1.1.1.1 2005/12/19 23:16:43 acg
+//First check in of SystemC 2.1 into its own archive.
+//
+//Revision 1.10 2005/09/15 23:01:51 acg
+//Added std:: prefix to appropriate methods and types to get around
+//issues with the Edison Front End.
+//
+//Revision 1.9 2005/06/10 22:43:55 acg
+//Added CVS change log annotation.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_event_queue.cpp b/ext/systemc/src/sysc/communication/sc_event_queue.cpp
new file mode 100644
index 000000000..7e1ebc864
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_event_queue.cpp
@@ -0,0 +1,146 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_event_queue.cpp -- Event Queue Support
+
+ Original Author: Stuart Swan, Cadence Inc.
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include "sysc/communication/sc_event_queue.h"
+#include "sysc/kernel/sc_method_process.h"
+
+namespace sc_core {
+
+static int
+sc_time_compare( const void* p1, const void* p2 )
+{
+ const sc_time* t1 = static_cast<const sc_time*>( p1 );
+ const sc_time* t2 = static_cast<const sc_time*>( p2 );
+
+ if( *t1 < *t2 ) {
+ return 1;
+ } else if( *t1 > *t2 ) {
+ return -1;
+ } else {
+ return 0;
+ }
+}
+
+sc_event_queue::sc_event_queue( sc_module_name name_ )
+ : sc_module( name_ ),
+ m_ppq( 128, sc_time_compare ),
+ m_e( (std::string(SC_KERNEL_EVENT_PREFIX)+"_event").c_str() ),
+ m_change_stamp(0),
+ m_pending_delta(0)
+{
+ SC_METHOD( fire_event );
+ sensitive << m_e;
+ dont_initialize();
+}
+
+sc_event_queue::~sc_event_queue()
+{
+ while (m_ppq.size() > 0) {
+ delete m_ppq.extract_top();
+ }
+}
+
+void sc_event_queue::cancel_all()
+{
+ m_pending_delta = 0;
+ while( m_ppq.size() > 0 )
+ delete m_ppq.extract_top();
+ m_e.cancel();
+}
+
+void sc_event_queue::notify (const sc_time& when)
+{
+ m_change_stamp = simcontext()->change_stamp();
+ sc_time* t = new sc_time( when+sc_time_stamp() );
+ if ( m_ppq.size()==0 || *t < *m_ppq.top() ) {
+ m_e.notify( when );
+ }
+ m_ppq.insert( t );
+}
+
+void sc_event_queue::fire_event()
+{
+ if ( m_ppq.empty() ) { // event has been cancelled
+ return;
+ }
+ sc_time* t = m_ppq.extract_top();
+ assert( *t==sc_time_stamp() );
+ delete t;
+
+ if ( m_ppq.size() > 0 ) {
+ m_e.notify( *m_ppq.top() - sc_time_stamp() );
+ }
+}
+
+} // namespace sc_core
+
+// $Log: sc_event_queue.cpp,v $
+// Revision 1.9 2011/08/26 22:45:53 acg
+// Torsten Maehne: remove redundant initialization assignment.
+//
+// Revision 1.8 2011/08/26 21:44:58 acg
+// Andy Goodrich: fix internal event naming.
+//
+// Revision 1.7 2011/08/26 20:45:39 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.6 2011/08/24 22:05:35 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.5 2011/04/08 18:22:46 acg
+// Philipp A. Hartmann: use the context of the primitive channel to get
+// the change stamp value.
+//
+// Revision 1.4 2011/04/05 20:48:09 acg
+// Andy Goodrich: changes to make sure that event(), posedge() and negedge()
+// only return true if the clock has not moved.
+//
+// Revision 1.3 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+// Revision 1.2 2010/07/22 20:02:30 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.5 2006/11/28 20:30:48 acg
+// Andy Goodrich: updated from 2.2 source. sc_event_queue constructors
+// collapsed into a single constructor with an optional argument to get
+// the sc_module_name stack done correctly. Class name prefixing added
+// to sc_semaphore calls to wait() to keep gcc 4.x happy.
+//
+// Revision 1.4 2006/01/26 21:00:50 acg
+// Andy Goodrich: conversion to use sc_event::notify(SC_ZERO_TIME) instead of
+// sc_event::notify_delayed()
+//
+// Revision 1.3 2006/01/13 18:47:42 acg
+// Added $Log command so that CVS comments are reproduced in the source.
+
+// taf
diff --git a/ext/systemc/src/sysc/communication/sc_event_queue.h b/ext/systemc/src/sysc/communication/sc_event_queue.h
new file mode 100644
index 000000000..4438de9ef
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_event_queue.h
@@ -0,0 +1,181 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_event_queue.h -- Event Queue Facility Definitions
+
+ Original Author: Ulli Holtmann, Synopsys, Inc.
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_EVENT_QUEUE_H
+#define SC_EVENT_QUEUE_H
+
+
+/*
+ Class sc_event_queue
+
+ A queue that can contain any number of pending notifications.
+ The queue has a similiar interface like an sc_event but has different
+ semantics: it can carry any number of pending notification. The
+ general rule is that _every_ call to notify() will cause a
+ corresponding trigger at the specified wall-clock time that can be
+ observed (the only exception is when notifications are explicitly
+ cancelled).
+
+ If multiple notifications are pending at the same wall-clock
+ time, then the event queue will trigger in different delta cycles
+ in order to ensure that sensitive processes can notice each
+ trigger. The first trigger happens in the earliest delta cycle
+ possible which is the same behavior as a normal timed event.
+
+*/
+
+#include "sysc/communication/sc_interface.h"
+#include "sysc/kernel/sc_module.h"
+#include "sysc/kernel/sc_event.h"
+#include "sysc/communication/sc_port.h"
+
+namespace sc_core {
+
+
+// ---------------------------------------------------------------------------
+// sc_event_queue_if
+// ---------------------------------------------------------------------------
+
+class sc_event_queue_if : public virtual sc_interface
+{
+public:
+ virtual void notify (double when, sc_time_unit base) =0;
+ virtual void notify (const sc_time& when) =0;
+ virtual void cancel_all() =0;
+};
+
+// ---------------------------------------------------------------------------
+// sc_event_queue: a queue that can contain any number of pending
+// delta, or timed events.
+// ---------------------------------------------------------------------------
+
+class sc_event_queue:
+ public sc_event_queue_if,
+ public sc_module
+{
+ public:
+
+ SC_HAS_PROCESS( sc_event_queue );
+
+ sc_event_queue( sc_module_name name_ = sc_gen_unique_name("event_queue") );
+ ~sc_event_queue();
+
+ // API of sc_object
+ inline virtual const char* kind() const { return "sc_event_queue"; }
+
+ //
+ // API of sc_event_queue_if
+ //
+ inline virtual void notify (double when, sc_time_unit base);
+ virtual void notify (const sc_time& when);
+ virtual void cancel_all();
+
+ //
+ // API for using the event queue in processes
+ //
+
+ // get the default event
+ inline virtual const sc_event& default_event() const;
+
+/*
+ //
+ // Possible extensions:
+ //
+
+ // Cancel an events at a specific time
+ void cancel (const sc_time& when);
+ void cancel (double when, sc_time_unit base);
+
+ // How many events are pending altogether?
+ unsigned pending() const;
+
+ // How many events are pending at the specific time?
+ unsigned pending(const sc_time& when) const;
+ unsigned pending(double when, sc_time_unit base) const;
+*/
+
+ private:
+ void fire_event();
+
+ private:
+ sc_ppq<sc_time*> m_ppq;
+ sc_event m_e;
+ sc_dt::uint64 m_change_stamp;
+ unsigned m_pending_delta;
+};
+
+inline
+void sc_event_queue::notify (double when, sc_time_unit base )
+{
+ notify( sc_time(when,base) );
+}
+
+inline
+const sc_event& sc_event_queue::default_event() const
+{
+ return m_e;
+}
+
+
+//
+// Using event queue as a port
+//
+typedef sc_port<sc_event_queue_if,1,SC_ONE_OR_MORE_BOUND> sc_event_queue_port;
+
+} // namespace sc_core
+
+// $Log: sc_event_queue.h,v $
+// Revision 1.5 2011/08/26 20:45:40 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.4 2011/04/05 20:48:09 acg
+// Andy Goodrich: changes to make sure that event(), posedge() and negedge()
+// only return true if the clock has not moved.
+//
+// Revision 1.3 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+// Revision 1.2 2008/05/20 16:45:52 acg
+// Andy Goodrich: changed which unique name generator is used from the
+// global one to the one for sc_modules.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.4 2006/11/28 20:30:48 acg
+// Andy Goodrich: updated from 2.2 source. sc_event_queue constructors
+// collapsed into a single constructor with an optional argument to get
+// the sc_module_name stack done correctly. Class name prefixing added
+// to sc_semaphore calls to wait() to keep gcc 4.x happy.
+//
+// Revision 1.3 2006/01/13 18:47:42 acg
+// Added $Log command so that CVS comments are reproduced in the source.
+//
+
+#endif // SC_EVENT_QUEUE_H
diff --git a/ext/systemc/src/sysc/communication/sc_export.cpp b/ext/systemc/src/sysc/communication/sc_export.cpp
new file mode 100644
index 000000000..2da7a1533
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_export.cpp
@@ -0,0 +1,305 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_export.cpp --
+
+ Original Author: Bishnupriya Bhattachary, Cadence, Design Systems,
+ 25 August, 2003
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include "sysc/communication/sc_export.h"
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_module.h"
+#include "sysc/kernel/sc_object_int.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_export_base
+//
+// ----------------------------------------------------------------------------
+
+sc_export_base::sc_export_base() : sc_object(sc_gen_unique_name("export"))
+{
+ simcontext()->get_export_registry()->insert(this);
+}
+
+sc_export_base::sc_export_base(const char* name_) : sc_object(name_)
+{
+ simcontext()->get_export_registry()->insert(this);
+}
+
+sc_export_base::~sc_export_base()
+{
+ simcontext()->get_export_registry()->remove(this);
+}
+
+// called by construction_done() (does nothing by default)
+
+void
+sc_export_base::before_end_of_elaboration()
+{
+}
+
+// called when construction is done
+
+void
+sc_export_base::construction_done()
+{
+ if ( get_interface() == 0 )
+ {
+ report_error( SC_ID_SC_EXPORT_NOT_BOUND_AFTER_CONSTRUCTION_, 0);
+ }
+
+ sc_module* parent = static_cast<sc_module*>( get_parent_object() );
+ sc_object::hierarchy_scope scope( parent );
+ before_end_of_elaboration();
+}
+
+// called by elaboration_done() (does nothing by default)
+
+void
+sc_export_base::end_of_elaboration()
+{}
+
+// called when elaboration is done
+
+void
+sc_export_base::elaboration_done()
+{
+ sc_module* parent = static_cast<sc_module*>( get_parent_object() );
+ sc_object::hierarchy_scope scope( parent );
+ end_of_elaboration();
+}
+
+// called by start_simulation (does nothing)
+
+void
+sc_export_base::start_of_simulation()
+{}
+
+// called before simulation starts
+
+void
+sc_export_base::start_simulation()
+{
+ sc_module* parent = static_cast<sc_module*>( get_parent_object() );
+ sc_object::hierarchy_scope scope( parent );
+ start_of_simulation();
+}
+
+// called by simulation_done (does nothing)
+
+void
+sc_export_base::end_of_simulation()
+{}
+
+// called after simulation ends
+
+void
+sc_export_base::simulation_done()
+{
+ sc_module* parent = static_cast<sc_module*>( get_parent_object() );
+ sc_object::hierarchy_scope scope( parent );
+ end_of_simulation();
+}
+
+void
+sc_export_base::report_error( const char* id, const char* add_msg ) const
+{
+ char msg[BUFSIZ];
+ if( add_msg != 0 ) {
+ std::sprintf( msg, "%s: export '%s' (%s)", add_msg, name(), kind() );
+ } else {
+ std::sprintf( msg, "export '%s' (%s)", name(), kind() );
+ }
+ SC_REPORT_ERROR( id, msg );
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_export_registry
+//
+// Registry for all exports.
+// FOR INTERNAL USE ONLY!
+// ----------------------------------------------------------------------------
+
+void
+sc_export_registry::insert( sc_export_base* export_ )
+{
+ if( sc_is_running() ) {
+ export_->report_error(SC_ID_INSERT_EXPORT_, "simulation running");
+ }
+
+ if( m_simc->elaboration_done() ) {
+ export_->report_error(SC_ID_INSERT_EXPORT_, "elaboration done");
+ }
+
+
+#ifdef DEBUG_SYSTEMC
+ // check if port_ is already inserted
+ for( int i = size() - 1; i >= 0; -- i ) {
+ if( export_ == m_export_vec[i] ) {
+ export_->report_error( SC_ID_INSERT_EXPORT_,
+ "export already inserted ");
+ }
+ }
+#endif
+
+/*
+ //TBD: maybe we want to do this stuf for later
+
+ // append the port to the current module's vector of ports
+ sc_module* curr_module = m_simc->hierarchy_curr();
+ if( curr_module == 0 ) {
+ port_->report_error( SC_ID_PORT_OUTSIDE_MODULE_ );
+ }
+ curr_module->append_port( port_ );
+*/
+
+ // insert
+ m_export_vec.push_back( export_ );
+}
+
+void
+sc_export_registry::remove( sc_export_base* export_ )
+{
+ if (size()==0) return;
+ int i;
+ for( i = size() - 1; i >= 0; -- i ) {
+ if( export_ == m_export_vec[i] ) {
+ break;
+ }
+ }
+ if( i == -1 ) {
+ export_->report_error( SC_ID_SC_EXPORT_NOT_REGISTERED_ );
+ }
+
+ // remove
+ m_export_vec[i] = m_export_vec[size() - 1];
+ m_export_vec.resize(size()-1);
+}
+
+// constructor
+
+sc_export_registry::sc_export_registry( sc_simcontext& simc_ )
+: m_construction_done(0),
+ m_export_vec(),
+ m_simc( &simc_ )
+{
+}
+
+
+// destructor
+
+sc_export_registry::~sc_export_registry()
+{
+}
+
+// called when construction is done
+
+bool
+sc_export_registry::construction_done()
+{
+ if( m_construction_done == size() )
+ // nothing has been updated
+ return true;
+
+ for( int i = size()-1; i >= m_construction_done; --i ) {
+ m_export_vec[i]->construction_done();
+ }
+
+ m_construction_done = size();
+ return false;
+}
+
+// called when elaboration is done
+
+void
+sc_export_registry::elaboration_done()
+{
+ for( int i = size() - 1; i >= 0; -- i ) {
+ m_export_vec[i]->elaboration_done();
+ }
+}
+
+// called before simulation begins
+
+void
+sc_export_registry::start_simulation()
+{
+ for( int i = size() - 1; i >= 0; -- i ) {
+ m_export_vec[i]->start_simulation();
+ }
+}
+
+void
+sc_export_registry::simulation_done()
+{
+ for( int i = size() - 1; i >= 0; -- i ) {
+ m_export_vec[i]->simulation_done();
+ }
+}
+
+} // namespace sc_core
+
+// $Log: sc_export.cpp,v $
+// Revision 1.8 2011/08/26 20:45:40 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.7 2011/08/24 22:05:36 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.6 2011/05/09 04:07:37 acg
+// Philipp A. Hartmann:
+// (1) Restore hierarchy in all phase callbacks.
+// (2) Ensure calls to before_end_of_elaboration.
+//
+// Revision 1.5 2011/02/18 20:31:05 acg
+// Philipp A. Hartmann: added error messages for calls that cannot be done
+// after elaboration.
+//
+// Revision 1.4 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+// Revision 1.3 2011/02/18 20:07:04 acg
+// Philipp A. Hartmann: Patch to revert to sprintf from snprintf to keep
+// some versions of MSVC happy.
+//
+// Revision 1.2 2011/02/14 17:50:16 acg
+// Andy Goodrich: testing for sc_port and sc_export instantiations during
+// end of elaboration and issuing appropriate error messages.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.4 2006/01/26 21:00:50 acg
+// Andy Goodrich: conversion to use sc_event::notify(SC_ZERO_TIME) instead of
+// sc_event::notify_delayed()
+//
+// Revision 1.3 2006/01/13 18:47:42 acg
+// Added $Log command so that CVS comments are reproduced in the source.
+//
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_export.h b/ext/systemc/src/sysc/communication/sc_export.h
new file mode 100644
index 000000000..81edc8cc2
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_export.h
@@ -0,0 +1,299 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_export.h -- Base classes of all export classes.
+
+ Original Author: Andy Goodrich, Forte Design Systems
+ Bishnupriya Bhattacharya, Cadence Design Systems
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_EXPORT_H
+#define SC_EXPORT_H
+#include <typeinfo>
+
+#include "sysc/communication/sc_communication_ids.h"
+#include "sysc/communication/sc_interface.h"
+#include "sysc/kernel/sc_object.h"
+
+#if ! defined( SC_DISABLE_VIRTUAL_BIND )
+# define SC_VIRTUAL_ virtual
+#else
+# define SC_VIRTUAL_ /* non-virtual */
+#endif
+
+namespace sc_core {
+
+//=============================================================================
+// CLASS : sc_export_base
+//
+// Abstract base class for class sc_export<IF>.
+//=============================================================================
+
+class sc_export_base : public sc_object
+{
+ friend class sc_export_registry;
+public:
+
+ // typedefs
+
+ typedef sc_export_base this_type;
+
+public:
+
+ virtual sc_interface* get_interface() = 0;
+ virtual const sc_interface* get_interface() const = 0;
+
+protected:
+
+ // constructors
+
+ sc_export_base();
+ sc_export_base(const char* name);
+
+ // destructor
+
+ virtual ~sc_export_base();
+
+protected:
+
+ // called when construction is done
+ virtual void before_end_of_elaboration();
+
+ // called when elaboration is done (does nothing by default)
+ virtual void end_of_elaboration();
+
+ // called before simulation starts (does nothing by default)
+ virtual void start_of_simulation();
+
+ // called after simulation ends (does nothing)
+ virtual void end_of_simulation();
+
+ virtual const char* if_typename() const = 0;
+
+ // error reporting
+ void report_error( const char* id, const char* add_msg = 0) const;
+
+private:
+
+ void construction_done();
+ void elaboration_done();
+ void start_simulation();
+ void simulation_done();
+
+ // disabled
+ sc_export_base(const this_type&);
+ this_type& operator = (const this_type& );
+
+};
+
+//=============================================================================
+// CLASS : sc_export
+//
+// Generic export class for other export classes. This
+// class provides a binding point for access to an interface.
+//=============================================================================
+template<class IF>
+class sc_export : public sc_export_base
+{
+ typedef sc_export<IF> this_type;
+
+public: // constructors:
+ sc_export() : sc_export_base()
+ {
+ m_interface_p = 0;
+ }
+
+ explicit sc_export( const char* name_ ) : sc_export_base(name_)
+ {
+ m_interface_p = 0;
+ }
+
+public: // destructor:
+ virtual ~sc_export()
+ {
+ }
+
+public: // interface access:
+
+ virtual sc_interface* get_interface()
+ {
+ return m_interface_p;
+ }
+
+ virtual const sc_interface* get_interface() const
+ {
+ return m_interface_p;
+ }
+
+ const IF* operator -> () const {
+ if ( m_interface_p == 0 )
+ {
+ SC_REPORT_ERROR(SC_ID_SC_EXPORT_HAS_NO_INTERFACE_,name());
+ }
+ return m_interface_p;
+ }
+
+ IF* operator -> () {
+ if ( m_interface_p == 0 )
+ {
+ SC_REPORT_ERROR(SC_ID_SC_EXPORT_HAS_NO_INTERFACE_,name());
+ }
+ return m_interface_p;
+ }
+
+ operator IF& ()
+ {
+ if ( m_interface_p == 0 )
+ {
+ SC_REPORT_ERROR(SC_ID_SC_EXPORT_HAS_NO_INTERFACE_,name());
+ }
+ return *m_interface_p;
+ }
+ operator const IF&() const
+ { return *const_cast<this_type*>(this); }
+
+
+public: // binding:
+ SC_VIRTUAL_ void bind( IF& interface_ )
+ {
+ if ( m_interface_p )
+ {
+ SC_REPORT_ERROR(SC_ID_SC_EXPORT_ALREADY_BOUND_,name());
+ }
+ else
+ {
+ m_interface_p = &interface_;
+ }
+ }
+
+ void operator () ( IF& interface_ )
+ {
+ this->bind(interface_);
+ }
+
+public: // identification:
+ virtual const char* kind() const { return "sc_export"; }
+
+protected:
+ const char* if_typename() const {
+ return typeid( IF ).name();
+ }
+
+private: // disabled
+ sc_export( const this_type& );
+ this_type& operator = ( const this_type& );
+
+protected: // data fields:
+ IF* m_interface_p; // Interface this port provides.
+};
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_export_registry
+//
+// Registry for all exports.
+// FOR INTERNAL USE ONLY!
+// ----------------------------------------------------------------------------
+
+class sc_export_registry
+{
+ friend class sc_simcontext;
+
+public:
+
+ void insert( sc_export_base* );
+ void remove( sc_export_base* );
+
+ int size() const
+ { return m_export_vec.size(); }
+
+private:
+
+ // constructor
+ explicit sc_export_registry( sc_simcontext& simc_ );
+
+ // destructor
+ ~sc_export_registry();
+
+ // called when construction is done
+ bool construction_done();
+
+ // called when elaboration is done
+ void elaboration_done();
+
+ // called before simulation starts
+ void start_simulation();
+
+ // called after simulation ends
+ void simulation_done();
+
+private:
+
+ int m_construction_done;
+ std::vector<sc_export_base*> m_export_vec;
+ sc_simcontext* m_simc;
+
+private:
+
+ // disabled
+ sc_export_registry();
+ sc_export_registry( const sc_export_registry& );
+ sc_export_registry& operator = ( const sc_export_registry& );
+};
+
+} // namespace sc_core
+
+#undef SC_VIRTUAL_
+
+// $Log: sc_export.h,v $
+// Revision 1.7 2011/08/26 20:45:40 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.6 2011/05/09 04:07:37 acg
+// Philipp A. Hartmann:
+// (1) Restore hierarchy in all phase callbacks.
+// (2) Ensure calls to before_end_of_elaboration.
+//
+// Revision 1.5 2011/04/02 00:02:14 acg
+// Philipp A. Hartmann: add const overload for sc_export::operator IF&
+//
+// Revision 1.4 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+// Revision 1.3 2011/02/14 17:50:16 acg
+// Andy Goodrich: testing for sc_port and sc_export instantiations during
+// end of elaboration and issuing appropriate error messages.
+//
+// Revision 1.2 2011/01/20 16:52:15 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:47:42 acg
+// Added $Log command so that CVS comments are reproduced in the source.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_fifo.h b/ext/systemc/src/sysc/communication/sc_fifo.h
new file mode 100644
index 000000000..868c0304e
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_fifo.h
@@ -0,0 +1,479 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_fifo.h -- The sc_fifo<T> primitive channel class.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_FIFO_H
+#define SC_FIFO_H
+
+
+#include "sysc/communication/sc_communication_ids.h"
+#include "sysc/communication/sc_prim_channel.h"
+#include "sysc/communication/sc_fifo_ifs.h"
+#include "sysc/kernel/sc_event.h"
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/tracing/sc_trace.h"
+#include <typeinfo>
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fifo<T>
+//
+// The sc_fifo<T> primitive channel class.
+// ----------------------------------------------------------------------------
+
+template <class T>
+class sc_fifo
+: public sc_fifo_in_if<T>,
+ public sc_fifo_out_if<T>,
+ public sc_prim_channel
+{
+public:
+
+ // constructors
+
+ explicit sc_fifo( int size_ = 16 )
+ : sc_prim_channel( sc_gen_unique_name( "fifo" ) ),
+ m_data_read_event(
+ (std::string(SC_KERNEL_EVENT_PREFIX)+"_read_event").c_str()),
+ m_data_written_event(
+ (std::string(SC_KERNEL_EVENT_PREFIX)+"_write_event").c_str())
+ { init( size_ ); }
+
+ explicit sc_fifo( const char* name_, int size_ = 16 )
+ : sc_prim_channel( name_ ),
+ m_data_read_event(
+ (std::string(SC_KERNEL_EVENT_PREFIX)+"_read_event").c_str()),
+ m_data_written_event(
+ (std::string(SC_KERNEL_EVENT_PREFIX)+"_write_event").c_str())
+ { init( size_ ); }
+
+
+ // destructor
+
+ virtual ~sc_fifo()
+ { delete [] m_buf; }
+
+
+ // interface methods
+
+ virtual void register_port( sc_port_base&, const char* );
+
+
+ // blocking read
+ virtual void read( T& );
+ virtual T read();
+
+ // non-blocking read
+ virtual bool nb_read( T& );
+
+
+ // get the number of available samples
+
+ virtual int num_available() const
+ { return ( m_num_readable - m_num_read ); }
+
+
+ // get the data written event
+
+ virtual const sc_event& data_written_event() const
+ { return m_data_written_event; }
+
+
+ // blocking write
+ virtual void write( const T& );
+
+ // non-blocking write
+ virtual bool nb_write( const T& );
+
+
+ // get the number of free spaces
+
+ virtual int num_free() const
+ { return ( m_size - m_num_readable - m_num_written ); }
+
+
+ // get the data read event
+
+ virtual const sc_event& data_read_event() const
+ { return m_data_read_event; }
+
+
+ // other methods
+
+ operator T ()
+ { return read(); }
+
+
+ sc_fifo<T>& operator = ( const T& a )
+ { write( a ); return *this; }
+
+
+ void trace( sc_trace_file* tf ) const;
+
+
+ virtual void print( ::std::ostream& = ::std::cout ) const;
+ virtual void dump( ::std::ostream& = ::std::cout ) const;
+
+ virtual const char* kind() const
+ { return "sc_fifo"; }
+
+protected:
+
+ virtual void update();
+
+ // support methods
+
+ void init( int );
+
+ void buf_init( int );
+ bool buf_write( const T& );
+ bool buf_read( T& );
+
+protected:
+
+ int m_size; // size of the buffer
+ T* m_buf; // the buffer
+ int m_free; // number of free spaces
+ int m_ri; // index of next read
+ int m_wi; // index of next write
+
+ sc_port_base* m_reader; // used for static design rule checking
+ sc_port_base* m_writer; // used for static design rule checking
+
+ int m_num_readable; // #samples readable
+ int m_num_read; // #samples read during this delta cycle
+ int m_num_written; // #samples written during this delta cycle
+
+ sc_event m_data_read_event;
+ sc_event m_data_written_event;
+
+private:
+
+ // disabled
+ sc_fifo( const sc_fifo<T>& );
+ sc_fifo& operator = ( const sc_fifo<T>& );
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+template <class T>
+inline
+void
+sc_fifo<T>::register_port( sc_port_base& port_,
+ const char* if_typename_ )
+{
+ std::string nm( if_typename_ );
+ if( nm == typeid( sc_fifo_in_if<T> ).name() ||
+ nm == typeid( sc_fifo_blocking_in_if<T> ).name()
+ ) {
+ // only one reader can be connected
+ if( m_reader != 0 ) {
+ SC_REPORT_ERROR( SC_ID_MORE_THAN_ONE_FIFO_READER_, 0 );
+ }
+ m_reader = &port_;
+ } else if( nm == typeid( sc_fifo_out_if<T> ).name() ||
+ nm == typeid( sc_fifo_blocking_out_if<T> ).name()
+ ) {
+ // only one writer can be connected
+ if( m_writer != 0 ) {
+ SC_REPORT_ERROR( SC_ID_MORE_THAN_ONE_FIFO_WRITER_, 0 );
+ }
+ m_writer = &port_;
+ }
+ else
+ {
+ SC_REPORT_ERROR( SC_ID_BIND_IF_TO_PORT_,
+ "sc_fifo<T> port not recognized" );
+ }
+}
+
+
+// blocking read
+
+template <class T>
+inline
+void
+sc_fifo<T>::read( T& val_ )
+{
+ while( num_available() == 0 ) {
+ sc_core::wait( m_data_written_event );
+ }
+ m_num_read ++;
+ buf_read( val_ );
+ request_update();
+}
+
+template <class T>
+inline
+T
+sc_fifo<T>::read()
+{
+ T tmp;
+ read( tmp );
+ return tmp;
+}
+
+// non-blocking read
+
+template <class T>
+inline
+bool
+sc_fifo<T>::nb_read( T& val_ )
+{
+ if( num_available() == 0 ) {
+ return false;
+ }
+ m_num_read ++;
+ buf_read( val_ );
+ request_update();
+ return true;
+}
+
+
+// blocking write
+
+template <class T>
+inline
+void
+sc_fifo<T>::write( const T& val_ )
+{
+ while( num_free() == 0 ) {
+ sc_core::wait( m_data_read_event );
+ }
+ m_num_written ++;
+ buf_write( val_ );
+ request_update();
+}
+
+// non-blocking write
+
+template <class T>
+inline
+bool
+sc_fifo<T>::nb_write( const T& val_ )
+{
+ if( num_free() == 0 ) {
+ return false;
+ }
+ m_num_written ++;
+ buf_write( val_ );
+ request_update();
+ return true;
+}
+
+
+template <class T>
+inline
+void
+sc_fifo<T>::trace( sc_trace_file* tf ) const
+{
+#if defined(DEBUG_SYSTEMC)
+ char buf[32];
+ std::string nm = name();
+ for( int i = 0; i < m_size; ++ i ) {
+ std::sprintf( buf, "_%d", i );
+ sc_trace( tf, m_buf[i], nm + buf );
+ }
+#endif
+}
+
+
+template <class T>
+inline
+void
+sc_fifo<T>::print( ::std::ostream& os ) const
+{
+ if( m_free != m_size ) {
+ int i = m_ri;
+ do {
+ os << m_buf[i] << ::std::endl;
+ i = ( i + 1 ) % m_size;
+ } while( i != m_wi );
+ }
+}
+
+template <class T>
+inline
+void
+sc_fifo<T>::dump( ::std::ostream& os ) const
+{
+ os << "name = " << name() << ::std::endl;
+ if( m_free != m_size ) {
+ int i = m_ri;
+ int j = 0;
+ do {
+ os << "value[" << i << "] = " << m_buf[i] << ::std::endl;
+ i = ( i + 1 ) % m_size;
+ j ++;
+ } while( i != m_wi );
+ }
+}
+
+
+template <class T>
+inline
+void
+sc_fifo<T>::update()
+{
+ if( m_num_read > 0 ) {
+ m_data_read_event.notify(SC_ZERO_TIME);
+ }
+
+ if( m_num_written > 0 ) {
+ m_data_written_event.notify(SC_ZERO_TIME);
+ }
+
+ m_num_readable = m_size - m_free;
+ m_num_read = 0;
+ m_num_written = 0;
+}
+
+
+// support methods
+
+template <class T>
+inline
+void
+sc_fifo<T>::init( int size_ )
+{
+ buf_init( size_ );
+
+ m_reader = 0;
+ m_writer = 0;
+
+ m_num_readable = 0;
+ m_num_read = 0;
+ m_num_written = 0;
+}
+
+
+template <class T>
+inline
+void
+sc_fifo<T>::buf_init( int size_ )
+{
+ if( size_ <= 0 ) {
+ SC_REPORT_ERROR( SC_ID_INVALID_FIFO_SIZE_, 0 );
+ }
+ m_size = size_;
+ m_buf = new T[m_size];
+ m_free = m_size;
+ m_ri = 0;
+ m_wi = 0;
+}
+
+template <class T>
+inline
+bool
+sc_fifo<T>::buf_write( const T& val_ )
+{
+ if( m_free == 0 ) {
+ return false;
+ }
+ m_buf[m_wi] = val_;
+ m_wi = ( m_wi + 1 ) % m_size;
+ m_free --;
+ return true;
+}
+
+template <class T>
+inline
+bool
+sc_fifo<T>::buf_read( T& val_ )
+{
+ if( m_free == m_size ) {
+ return false;
+ }
+ val_ = m_buf[m_ri];
+ m_buf[m_ri] = T(); // clear entry for boost::shared_ptr, et al.
+ m_ri = ( m_ri + 1 ) % m_size;
+ m_free ++;
+ return true;
+}
+
+
+// ----------------------------------------------------------------------------
+
+template <class T>
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, const sc_fifo<T>& a )
+{
+ a.print( os );
+ return os;
+}
+
+} // namespace sc_core
+
+//$Log: sc_fifo.h,v $
+//Revision 1.6 2011/08/26 20:45:40 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+//Revision 1.5 2011/03/23 16:17:22 acg
+// Andy Goodrich: hide the sc_events that are kernel related.
+//
+//Revision 1.4 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+//Revision 1.3 2009/10/14 19:05:40 acg
+// Andy Goodrich: added check for blocking interfaces in addition to the
+// combined blocking/nonblocking interface.
+//
+//Revision 1.2 2009/05/22 16:06:24 acg
+// Andy Goodrich: process control updates.
+//
+//Revision 1.1.1.1 2006/12/15 20:20:04 acg
+//SystemC 2.3
+//
+//Revision 1.4 2006/01/24 20:46:31 acg
+//Andy Goodrich: changes to eliminate use of deprecated features. For instance,
+//using notify(SC_ZERO_TIME) in place of notify_delayed().
+//
+//Revision 1.3 2006/01/13 20:41:59 acg
+//Andy Goodrich: Changes to add port registration to the things that are
+//checked when SC_NO_WRITE_CHECK is not defined.
+//
+//Revision 1.2 2006/01/03 23:18:26 acg
+//Changed copyright to include 2006.
+//
+//Revision 1.1.1.1 2005/12/19 23:16:43 acg
+//First check in of SystemC 2.1 into its own archive.
+//
+//Revision 1.12 2005/09/15 23:01:51 acg
+//Added std:: prefix to appropriate methods and types to get around
+//issues with the Edison Front End.
+//
+//Revision 1.11 2005/06/10 22:43:55 acg
+//Added CVS change log annotation.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_fifo_ifs.h b/ext/systemc/src/sysc/communication/sc_fifo_ifs.h
new file mode 100644
index 000000000..915fc9f0c
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_fifo_ifs.h
@@ -0,0 +1,209 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_fifo_ifs.h -- The sc_fifo<T> interface classes.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_FIFO_IFS_H
+#define SC_FIFO_IFS_H
+
+
+#include "sysc/communication/sc_interface.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fifo_nonblocking_in_if<T>
+//
+// The sc_fifo<T> input nonblocking interface class.
+// ----------------------------------------------------------------------------
+
+template <class T>
+class sc_fifo_nonblocking_in_if
+: virtual public sc_interface
+{
+public:
+
+ // non-blocking read
+ virtual bool nb_read( T& ) = 0;
+
+ // get the data written event
+ virtual const sc_event& data_written_event() const = 0;
+};
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fifo_blocking_in_if<T>
+//
+// The sc_fifo<T> input blocking interface class.
+// ----------------------------------------------------------------------------
+
+template <class T>
+class sc_fifo_blocking_in_if
+: virtual public sc_interface
+{
+public:
+
+ // blocking read
+ virtual void read( T& ) = 0;
+ virtual T read() = 0;
+};
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fifo_in_if<T>
+//
+// The sc_fifo<T> input interface class.
+// ----------------------------------------------------------------------------
+
+template <class T>
+class sc_fifo_in_if
+: public sc_fifo_nonblocking_in_if<T>,
+ public sc_fifo_blocking_in_if<T>
+{
+public:
+
+ // get the number of available samples
+ virtual int num_available() const = 0;
+
+protected:
+
+ // constructor
+
+ sc_fifo_in_if()
+ {}
+
+private:
+
+ // disabled
+ sc_fifo_in_if( const sc_fifo_in_if<T>& );
+ sc_fifo_in_if<T>& operator = ( const sc_fifo_in_if<T>& );
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fifo_nonblocking_out_if<T>
+//
+// The sc_fifo<T> nonblocking output interface class.
+// ----------------------------------------------------------------------------
+
+template <class T>
+class sc_fifo_nonblocking_out_if
+: virtual public sc_interface
+{
+public:
+
+ // non-blocking write
+ virtual bool nb_write( const T& ) = 0;
+
+ // get the data read event
+ virtual const sc_event& data_read_event() const = 0;
+};
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fifo_blocking_out_if<T>
+//
+// The sc_fifo<T> blocking output interface class.
+// ----------------------------------------------------------------------------
+
+template <class T>
+class sc_fifo_blocking_out_if
+: virtual public sc_interface
+{
+public:
+
+ // blocking write
+ virtual void write( const T& ) = 0;
+
+};
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fifo_out_if<T>
+//
+// The sc_fifo<T> output interface class.
+// ----------------------------------------------------------------------------
+
+template <class T>
+class sc_fifo_out_if
+: public sc_fifo_nonblocking_out_if<T>,
+ public sc_fifo_blocking_out_if<T>
+{
+public:
+
+ // get the number of free spaces
+ virtual int num_free() const = 0;
+
+protected:
+
+ // constructor
+
+ sc_fifo_out_if()
+ {}
+
+private:
+
+ // disabled
+ sc_fifo_out_if( const sc_fifo_out_if<T>& );
+ sc_fifo_out_if<T>& operator = ( const sc_fifo_out_if<T>& );
+};
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Bishnupriya Bhattacharye, Cadence Design Systems,
+ 30 Jan, 2004
+ Description of Modification: Split up the interfaces into blocking and
+ non blocking parts
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+//$Log: sc_fifo_ifs.h,v $
+//Revision 1.3 2011/08/26 20:45:40 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+//Revision 1.2 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+//Revision 1.1.1.1 2006/12/15 20:20:04 acg
+//SystemC 2.3
+//
+//Revision 1.2 2006/01/03 23:18:26 acg
+//Changed copyright to include 2006.
+//
+//Revision 1.1.1.1 2005/12/19 23:16:43 acg
+//First check in of SystemC 2.1 into its own archive.
+//
+//Revision 1.10 2005/06/10 22:43:55 acg
+//Added CVS change log annotation.
+//
+
+} // namespace sc_core
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_fifo_ports.h b/ext/systemc/src/sysc/communication/sc_fifo_ports.h
new file mode 100644
index 000000000..72727d4be
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_fifo_ports.h
@@ -0,0 +1,296 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_fifo_ports.h -- The sc_fifo<T> port classes.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_FIFO_PORTS_H
+#define SC_FIFO_PORTS_H
+
+
+#include "sysc/communication/sc_port.h"
+#include "sysc/communication/sc_fifo_ifs.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fifo_in<T>
+//
+// The sc_fifo<T> input port class.
+// ----------------------------------------------------------------------------
+
+template <class T>
+class sc_fifo_in
+: public sc_port<sc_fifo_in_if<T>,0,SC_ONE_OR_MORE_BOUND>
+{
+public:
+
+ // typedefs
+
+ typedef T data_type;
+
+ typedef sc_fifo_in_if<data_type> if_type;
+ typedef sc_port<if_type,0,SC_ONE_OR_MORE_BOUND> base_type;
+ typedef sc_fifo_in<data_type> this_type;
+
+ typedef if_type in_if_type;
+ typedef sc_port_b<in_if_type> in_port_type;
+
+public:
+
+ // constructors
+
+ sc_fifo_in()
+ : base_type()
+ {}
+
+ explicit sc_fifo_in( const char* name_ )
+ : base_type( name_ )
+ {}
+
+ explicit sc_fifo_in( in_if_type& interface_ )
+ : base_type( interface_ )
+ {}
+
+ sc_fifo_in( const char* name_, in_if_type& interface_ )
+ : base_type( name_, interface_ )
+ {}
+
+ explicit sc_fifo_in( in_port_type& parent_ )
+ : base_type( parent_ )
+ {}
+
+ sc_fifo_in( const char* name_, in_port_type& parent_ )
+ : base_type( name_, parent_ )
+ {}
+
+ sc_fifo_in( this_type& parent_ )
+ : base_type( parent_ )
+ {}
+
+ sc_fifo_in( const char* name_, this_type& parent_ )
+ : base_type( name_, parent_ )
+ {}
+
+
+ // destructor (does nothing)
+
+ virtual ~sc_fifo_in()
+ {}
+
+
+ // interface access shortcut methods
+
+ // blocking read
+
+ void read( data_type& value_ )
+ { (*this)->read( value_ ); }
+
+ data_type read()
+ { return (*this)->read(); }
+
+
+ // non-blocking read
+
+ bool nb_read( data_type& value_ )
+ { return (*this)->nb_read( value_ ); }
+
+
+ // get the number of available samples
+
+ int num_available() const
+ { return (*this)->num_available(); }
+
+
+ // get the data written event
+
+ const sc_event& data_written_event() const
+ { return (*this)->data_written_event(); }
+
+
+ // use for static sensitivity to data written event
+
+ sc_event_finder& data_written() const
+ {
+ return *new sc_event_finder_t<in_if_type>(
+ *this, &in_if_type::data_written_event );
+ }
+
+ virtual const char* kind() const
+ { return "sc_fifo_in"; }
+
+private:
+
+ // disabled
+ sc_fifo_in( const this_type& );
+ this_type& operator = ( const this_type& );
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fifo_out<T>
+//
+// The sc_fifo<T> output port class.
+// ----------------------------------------------------------------------------
+
+template <class T>
+class sc_fifo_out
+: public sc_port<sc_fifo_out_if<T>,0,SC_ONE_OR_MORE_BOUND>
+{
+public:
+
+ // typedefs
+
+ typedef T data_type;
+
+ typedef sc_fifo_out_if<data_type> if_type;
+ typedef sc_port<if_type,0,SC_ONE_OR_MORE_BOUND> base_type;
+ typedef sc_fifo_out<data_type> this_type;
+
+ typedef if_type out_if_type;
+ typedef sc_port_b<out_if_type> out_port_type;
+
+public:
+
+ // constructors
+
+ sc_fifo_out()
+ : base_type()
+ {}
+
+ explicit sc_fifo_out( const char* name_ )
+ : base_type( name_ )
+ {}
+
+ explicit sc_fifo_out( out_if_type& interface_ )
+ : base_type( interface_ )
+ {}
+
+ sc_fifo_out( const char* name_, out_if_type& interface_ )
+ : base_type( name_, interface_ )
+ {}
+
+ explicit sc_fifo_out( out_port_type& parent_ )
+ : base_type( parent_ )
+ {}
+
+ sc_fifo_out( const char* name_, out_port_type& parent_ )
+ : base_type( name_, parent_ )
+ {}
+
+ sc_fifo_out( this_type& parent_ )
+ : base_type( parent_ )
+ {}
+
+ sc_fifo_out( const char* name_, this_type& parent_ )
+ : base_type( name_, parent_ )
+ {}
+
+
+ // destructor (does nothing)
+
+ virtual ~sc_fifo_out()
+ {}
+
+
+ // interface access shortcut methods
+
+ // blocking write
+
+ void write( const data_type& value_ )
+ { (*this)->write( value_ ); }
+
+
+ // non-blocking write
+
+ bool nb_write( const data_type& value_ )
+ { return (*this)->nb_write( value_ ); }
+
+
+ // get the number of free spaces
+
+ int num_free() const
+ { return (*this)->num_free(); }
+
+
+ // get the data read event
+
+ const sc_event& data_read_event() const
+ { return (*this)->data_read_event(); }
+
+
+ // use for static sensitivity to data read event
+
+ sc_event_finder& data_read() const
+ {
+ return *new sc_event_finder_t<out_if_type>(
+ *this, &out_if_type::data_read_event );
+ }
+
+ virtual const char* kind() const
+ { return "sc_fifo_out"; }
+
+private:
+
+ // disabled
+ sc_fifo_out( const this_type& );
+ this_type& operator = ( const this_type& );
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+} // namespace sc_core
+
+//$Log: sc_fifo_ports.h,v $
+//Revision 1.3 2011/08/26 20:45:40 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+//Revision 1.2 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+//Revision 1.1.1.1 2006/12/15 20:20:04 acg
+//SystemC 2.3
+//
+//Revision 1.2 2006/01/03 23:18:26 acg
+//Changed copyright to include 2006.
+//
+//Revision 1.1.1.1 2005/12/19 23:16:43 acg
+//First check in of SystemC 2.1 into its own archive.
+//
+//Revision 1.10 2005/09/15 23:01:51 acg
+//Added std:: prefix to appropriate methods and types to get around
+//issues with the Edison Front End.
+//
+//Revision 1.9 2005/06/10 22:43:55 acg
+//Added CVS change log annotation.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_host_mutex.h b/ext/systemc/src/sysc/communication/sc_host_mutex.h
new file mode 100644
index 000000000..58f1c4c3a
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_host_mutex.h
@@ -0,0 +1,160 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_host_mutex.h -- A "real" mutex for the underlying host system
+
+ Original Author: Philipp A. Hartmann, OFFIS
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_HOST_MUTEX_H_INCLUDED_
+#define SC_HOST_MUTEX_H_INCLUDED_
+
+#ifndef SC_INCLUDE_WINDOWS_H
+# define SC_INCLUDE_WINDOWS_H // include Windows.h, if needed
+#endif
+#include "sysc/kernel/sc_cmnhdr.h"
+#include "sysc/communication/sc_mutex_if.h"
+
+#if defined(WIN32) || defined(_WIN32)
+
+#define SC_MTX_TYPE_ CRITICAL_SECTION
+
+#define SC_MTX_INIT_( Mutex ) \
+ InitializeCriticalSection( &(Mutex) )
+#define SC_MTX_LOCK_( Mutex ) \
+ EnterCriticalSection( &(Mutex) )
+#define SC_MTX_UNLOCK_( Mutex ) \
+ LeaveCriticalSection( &(Mutex) )
+#define SC_MTX_TRYLOCK_( Mutex ) \
+ ( TryEnterCriticalSection( &(Mutex) ) != 0 )
+#define SC_MTX_DESTROY_( Mutex ) \
+ DeleteCriticalSection( &(Mutex) )
+
+#else // use pthread mutex
+
+#include <pthread.h>
+#define SC_MTX_TYPE_ pthread_mutex_t
+
+#if defined(__hpux)
+# define SC_PTHREAD_NULL_ cma_c_null
+#else // !defined(__hpux)
+# define SC_PTHREAD_NULL_ NULL
+#endif
+
+#define SC_MTX_INIT_( Mutex ) \
+ pthread_mutex_init( &(Mutex), SC_PTHREAD_NULL_ )
+#define SC_MTX_LOCK_( Mutex ) \
+ pthread_mutex_lock( &(Mutex) )
+#define SC_MTX_UNLOCK_( Mutex ) \
+ pthread_mutex_unlock( &(Mutex) )
+
+#ifdef _XOPEN_SOURCE
+# define SC_MTX_TRYLOCK_( Mutex ) \
+ ( pthread_mutex_trylock( &(Mutex) ) == 0 )
+#else // no try_lock available
+# define SC_MTX_TRYLOCK_( Mutex ) \
+ ( false )
+#endif
+
+#define SC_MTX_DESTROY_( Mutex ) \
+ pthread_mutex_destroy( &(Mutex) )
+
+#endif
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_host_mutex
+//
+// The sc_host_mutex class, wrapping an OS mutex on the simulation host
+// ----------------------------------------------------------------------------
+
+class sc_host_mutex : public sc_mutex_if
+{
+ typedef SC_MTX_TYPE_ underlying_type;
+public:
+
+ // constructors and destructor
+
+ sc_host_mutex()
+ { SC_MTX_INIT_(m_mtx); }
+ virtual ~sc_host_mutex()
+ { SC_MTX_DESTROY_(m_mtx); }
+
+
+ // interface methods
+
+ // blocks until mutex could be locked
+ virtual int lock()
+ { SC_MTX_LOCK_(m_mtx); return 0; }
+
+ // returns -1 if mutex could not be locked
+ virtual int trylock()
+ { return SC_MTX_TRYLOCK_(m_mtx) ? 0 : -1; }
+
+ // should return -1 if mutex was not locked by caller,
+ // but is not yet able to check this
+ virtual int unlock()
+ { SC_MTX_UNLOCK_(m_mtx); return 0; }
+
+private:
+ underlying_type m_mtx;
+};
+
+} // namespace sc_core
+
+#undef SC_MTX_TYPE_
+#undef SC_MTX_INIT_
+#undef SC_MTX_DESTROY_
+#undef SC_MTX_LOCK_
+#undef SC_MTX_TRYLOCK_
+#undef SC_MTX_UNLOCK_
+#undef SC_PTHREAD_NULL_
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+ *****************************************************************************/
+//$Log: sc_host_mutex.h,v $
+//Revision 1.4 2011/08/30 21:53:23 acg
+// Jerome Cornet: include window.h for gnu c in windows case.
+//
+//Revision 1.3 2011/08/07 19:08:01 acg
+// Andy Goodrich: moved logs to end of file so line number synching works
+// better between versions.
+//
+//Revision 1.2 2011/06/25 17:08:38 acg
+// Andy Goodrich: Jerome Cornet's changes to use libtool to build the
+// library.
+//
+//Revision 1.1 2011/04/18 19:04:11 acg
+// Philipp A. Hartmann: first check in of file.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_interface.cpp b/ext/systemc/src/sysc/communication/sc_interface.cpp
new file mode 100644
index 000000000..eabe870e9
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_interface.cpp
@@ -0,0 +1,100 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_interface.cpp -- Abstract base class of all interface classes.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include "sysc/communication/sc_interface.h"
+#include "sysc/communication/sc_communication_ids.h"
+#include "sysc/kernel/sc_event.h"
+
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_interface
+//
+// Abstract base class of all interface classes.
+// BEWARE: Direct inheritance from this class must be done virtual.
+// ----------------------------------------------------------------------------
+
+// register a port with this interface (does nothing by default)
+
+void
+sc_interface::register_port( sc_port_base&, const char* )
+{}
+
+
+// get the default event
+
+const sc_event&
+sc_interface::default_event() const
+{
+ SC_REPORT_WARNING( SC_ID_NO_DEFAULT_EVENT_, 0 );
+ return m_never_notified;
+}
+
+
+// destructor (does nothing)
+
+sc_interface::~sc_interface()
+{}
+
+
+// constructor (does nothing)
+
+sc_interface::sc_interface()
+{}
+
+
+// special event for never notified cases, note the special name to keep
+// it out of the named event structures.
+
+sc_event sc_interface::m_never_notified(SC_KERNEL_EVENT_PREFIX);
+
+} // namespace sc_core
+
+// $Log: sc_interface.cpp,v $
+// Revision 1.5 2011/08/26 20:45:40 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.4 2011/03/12 21:07:42 acg
+// Andy Goodrich: changes to kernel generated event support.
+//
+// Revision 1.3 2011/03/06 15:55:08 acg
+// Andy Goodrich: Changes for named events.
+//
+// Revision 1.2 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:47:42 acg
+// Added $Log command so that CVS comments are reproduced in the source.
+//
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_interface.h b/ext/systemc/src/sysc/communication/sc_interface.h
new file mode 100644
index 000000000..b21d3c27d
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_interface.h
@@ -0,0 +1,107 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_interface.h -- Abstract base class of all interface classes.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_INTERFACE_H
+#define SC_INTERFACE_H
+
+namespace sc_core {
+
+class sc_event;
+class sc_port_base;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_interface
+//
+// Abstract base class of all interface classes.
+// BEWARE: Direct inheritance from this class must be done virtual.
+// ----------------------------------------------------------------------------
+
+class sc_interface
+{
+public:
+
+ // register a port with this interface (does nothing by default)
+ virtual void register_port( sc_port_base& port_,
+ const char* if_typename_ );
+
+ // get the default event
+ virtual const sc_event& default_event() const;
+
+ // destructor (does nothing)
+ virtual ~sc_interface();
+
+protected:
+
+ // constructor (does nothing)
+ sc_interface();
+
+private:
+
+ // disabled
+ sc_interface( const sc_interface& );
+ sc_interface& operator = ( const sc_interface& );
+
+private:
+
+ static sc_event m_never_notified;
+
+#if defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x520)
+ // Workaround for a bug in the Sun WorkShop 6 update 2 compiler.
+ // An empty virtual base class can cause the optimizer to
+ // generate wrong code.
+ char dummy;
+#endif
+};
+
+} // namespace sc_core
+
+//$Log: sc_interface.h,v $
+//Revision 1.3 2011/08/26 20:45:40 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+//Revision 1.2 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+//Revision 1.1.1.1 2006/12/15 20:20:04 acg
+//SystemC 2.3
+//
+//Revision 1.2 2006/01/03 23:18:26 acg
+//Changed copyright to include 2006.
+//
+//Revision 1.1.1.1 2005/12/19 23:16:43 acg
+//First check in of SystemC 2.1 into its own archive.
+//
+//Revision 1.7 2005/06/10 22:43:55 acg
+//Added CVS change log annotation.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_mutex.cpp b/ext/systemc/src/sysc/communication/sc_mutex.cpp
new file mode 100644
index 000000000..d2c43244c
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_mutex.cpp
@@ -0,0 +1,140 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_mutex.cpp -- The sc_mutex primitive channel class.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include "sysc/communication/sc_mutex.h"
+#include "sysc/kernel/sc_simcontext.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_mutex
+//
+// The sc_mutex primitive channel class.
+// ----------------------------------------------------------------------------
+
+// constructors
+
+sc_mutex::sc_mutex()
+: sc_object( sc_gen_unique_name( "mutex" ) ),
+ m_owner( 0 ),
+ m_free( (std::string(SC_KERNEL_EVENT_PREFIX)+"_free_event").c_str() )
+{}
+
+sc_mutex::sc_mutex( const char* name_ )
+: sc_object( name_ ),
+ m_owner( 0 ),
+ m_free( (std::string(SC_KERNEL_EVENT_PREFIX)+"_free_event").c_str() )
+{}
+
+
+// destructor
+
+sc_mutex::~sc_mutex()
+{}
+
+// interface methods
+
+// blocks until mutex could be locked
+
+int
+sc_mutex::lock()
+{
+ if ( m_owner == sc_get_current_process_b()) return 0;
+ while( in_use() ) {
+ sc_core::wait( m_free, sc_get_curr_simcontext() );
+ }
+ m_owner = sc_get_current_process_b();
+ return 0;
+}
+
+
+// returns -1 if mutex could not be locked
+
+int
+sc_mutex::trylock()
+{
+ if ( m_owner == sc_get_current_process_b()) return 0;
+ if( in_use() ) {
+ return -1;
+ }
+ m_owner = sc_get_current_process_b();
+ return 0;
+}
+
+
+// returns -1 if mutex was not locked by caller
+
+int
+sc_mutex::unlock()
+{
+ if( m_owner != sc_get_current_process_b() ) {
+ return -1;
+ }
+ m_owner = 0;
+ m_free.notify();
+ return 0;
+}
+
+} // namespace sc_core
+
+// $Log: sc_mutex.cpp,v $
+// Revision 1.7 2011/08/26 20:45:40 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.6 2011/03/28 13:02:29 acg
+// Andy Goodrich: removed sc_event in sc_mutex class from the object
+// hierarchy since it is considered a "kernel" event.
+//
+// Revision 1.5 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+// Revision 1.4 2010/11/02 16:31:01 acg
+// Andy Goodrich: changed object derivation to use sc_object rather than
+// sc_prim_channel as the parent class.
+//
+// Revision 1.3 2008/11/13 15:29:46 acg
+// David C. Black, ESLX, Inc: lock & trylock now allow owner to apply
+// lock more than once without incident. Previous behavior locked up the
+// owning process.
+//
+// Revision 1.2 2008/05/20 16:46:18 acg
+// Andy Goodrich: added checks for multiple writers.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.4 2006/03/21 00:00:27 acg
+// Andy Goodrich: changed name of sc_get_current_process_base() to be
+// sc_get_current_process_b() since its returning an sc_process_b instance.
+//
+// Revision 1.3 2006/01/13 18:47:42 acg
+// Added $Log command so that CVS comments are reproduced in the source.
+//
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_mutex.h b/ext/systemc/src/sysc/communication/sc_mutex.h
new file mode 100644
index 000000000..e3cef36c3
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_mutex.h
@@ -0,0 +1,124 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_mutex.h -- The sc_mutex primitive channel class.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_MUTEX_H
+#define SC_MUTEX_H
+
+#include "sysc/kernel/sc_event.h"
+#include "sysc/kernel/sc_object.h"
+#include "sysc/kernel/sc_wait.h"
+#include "sysc/communication/sc_mutex_if.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_mutex
+//
+// The sc_mutex primitive channel class.
+// ----------------------------------------------------------------------------
+
+class sc_mutex
+: public sc_mutex_if,
+ public sc_object
+{
+public:
+
+ // constructors and destructor
+
+ sc_mutex();
+ explicit sc_mutex( const char* name_ );
+ virtual ~sc_mutex();
+
+
+ // interface methods
+
+ // blocks until mutex could be locked
+ virtual int lock();
+
+ // returns -1 if mutex could not be locked
+ virtual int trylock();
+
+ // returns -1 if mutex was not locked by caller
+ virtual int unlock();
+
+ virtual const char* kind() const
+ { return "sc_mutex"; }
+
+protected:
+
+ // support methods
+
+ bool in_use() const
+ { return ( m_owner != 0 ); }
+
+protected:
+
+ sc_process_b* m_owner;
+ sc_event m_free;
+
+private:
+
+ // disabled
+ sc_mutex( const sc_mutex& );
+ sc_mutex& operator = ( const sc_mutex& );
+};
+
+} // namespace sc_core
+
+//$Log: sc_mutex.h,v $
+//Revision 1.4 2011/08/26 20:45:41 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+//Revision 1.3 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+//Revision 1.2 2010/11/02 16:31:01 acg
+// Andy Goodrich: changed object derivation to use sc_object rather than
+// sc_prim_channel as the parent class.
+//
+//Revision 1.1.1.1 2006/12/15 20:20:04 acg
+//SystemC 2.3
+//
+//Revision 1.2 2006/01/03 23:18:26 acg
+//Changed copyright to include 2006.
+//
+//Revision 1.1.1.1 2005/12/19 23:16:43 acg
+//First check in of SystemC 2.1 into its own archive.
+//
+//Revision 1.10 2005/09/15 23:01:51 acg
+//Added std:: prefix to appropriate methods and types to get around
+//issues with the Edison Front End.
+//
+//Revision 1.9 2005/06/10 22:43:55 acg
+//Added CVS change log annotation.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_mutex_if.h b/ext/systemc/src/sysc/communication/sc_mutex_if.h
new file mode 100644
index 000000000..6fa934135
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_mutex_if.h
@@ -0,0 +1,146 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_mutex_if.h -- The sc_mutex_if interface class.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_MUTEX_IF_H
+#define SC_MUTEX_IF_H
+
+#include "sysc/communication/sc_interface.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_mutex_if
+//
+// The sc_mutex_if interface class.
+// ----------------------------------------------------------------------------
+
+class sc_mutex_if
+: virtual public sc_interface
+{
+public:
+
+ // the classical operations: lock(), trylock(), and unlock()
+
+ // blocks until mutex could be locked
+ virtual int lock() = 0;
+
+ // returns -1 if mutex could not be locked
+ virtual int trylock() = 0;
+
+ // returns -1 if mutex was not locked by caller
+ virtual int unlock() = 0;
+
+protected:
+
+ // constructor
+
+ sc_mutex_if()
+ {}
+
+private:
+
+ // disabled
+ sc_mutex_if( const sc_mutex_if& );
+ sc_mutex_if& operator = ( const sc_mutex_if& );
+};
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_scoped_lock
+//
+// The sc_scoped_lock class to lock (and automatically release) a mutex.
+// ----------------------------------------------------------------------------
+
+//template< typename Lockable = sc_mutex_if >
+class sc_scoped_lock
+{
+public:
+ //typedef Lockable lockable_type;
+ typedef sc_mutex_if lockable_type;
+
+ explicit
+ sc_scoped_lock( lockable_type& mtx )
+ : m_ref(mtx)
+ , m_active(true)
+ {
+ m_ref.lock();
+ }
+
+ bool release()
+ {
+ if( m_active )
+ {
+ m_ref.unlock();
+ m_active = false;
+ return true;
+ }
+ return false;
+ }
+
+ ~sc_scoped_lock()
+ {
+ release();
+ }
+
+private:
+ // disabled
+ sc_scoped_lock( const sc_scoped_lock& );
+ sc_scoped_lock& operator=( const sc_scoped_lock& );
+
+ lockable_type& m_ref;
+ bool m_active;
+};
+
+} // namespace sc_core
+
+//$Log: sc_mutex_if.h,v $
+//Revision 1.4 2011/08/26 20:45:41 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+//Revision 1.3 2011/04/19 02:36:26 acg
+// Philipp A. Hartmann: new aysnc_update and mutex support.
+//
+//Revision 1.2 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+//Revision 1.1.1.1 2006/12/15 20:20:04 acg
+//SystemC 2.3
+//
+//Revision 1.2 2006/01/03 23:18:26 acg
+//Changed copyright to include 2006.
+//
+//Revision 1.1.1.1 2005/12/19 23:16:43 acg
+//First check in of SystemC 2.1 into its own archive.
+//
+//Revision 1.8 2005/06/10 22:43:55 acg
+//Added CVS change log annotation.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_port.cpp b/ext/systemc/src/sysc/communication/sc_port.cpp
new file mode 100644
index 000000000..01291e6b5
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_port.cpp
@@ -0,0 +1,835 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_port.cpp -- Base classes of all port classes.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_module.h"
+#include "sysc/kernel/sc_object_int.h"
+#include "sysc/kernel/sc_method_process.h"
+#include "sysc/kernel/sc_thread_process.h"
+#include "sysc/communication/sc_communication_ids.h"
+#include "sysc/utils/sc_utils_ids.h"
+#include "sysc/communication/sc_event_finder.h"
+#include "sysc/communication/sc_port.h"
+#include "sysc/communication/sc_signal_ifs.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// STRUCT : sc_bind_elem
+// ----------------------------------------------------------------------------
+
+struct sc_bind_elem
+{
+ // constructors
+ sc_bind_elem();
+ explicit sc_bind_elem( sc_interface* interface_ );
+ explicit sc_bind_elem( sc_port_base* parent_ );
+
+ sc_interface* iface;
+ sc_port_base* parent;
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+// constructors
+
+sc_bind_elem::sc_bind_elem()
+: iface( 0 ),
+ parent( 0 )
+{}
+
+sc_bind_elem::sc_bind_elem( sc_interface* interface_ )
+: iface( interface_ ),
+ parent( 0 )
+{}
+
+sc_bind_elem::sc_bind_elem( sc_port_base* parent_ )
+: iface( 0 ),
+ parent( parent_ )
+{}
+
+
+// ----------------------------------------------------------------------------
+// STRUCT : sc_bind_ef
+// ----------------------------------------------------------------------------
+
+struct sc_bind_ef
+{
+ // constructor
+ sc_bind_ef( sc_process_b* , sc_event_finder* );
+
+ // destructor
+ ~sc_bind_ef();
+
+ sc_process_b* handle;
+ sc_event_finder* event_finder;
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+// constructor
+
+sc_bind_ef::sc_bind_ef( sc_process_b* handle_,
+ sc_event_finder* event_finder_ )
+: handle( handle_ ),
+ event_finder( event_finder_ )
+{}
+
+
+// destructor
+
+sc_bind_ef::~sc_bind_ef()
+{
+}
+
+
+// ----------------------------------------------------------------------------
+// STRUCT : sc_bind_info
+// ----------------------------------------------------------------------------
+
+struct sc_bind_info
+{
+ // constructor
+ explicit sc_bind_info( int max_size_,
+ sc_port_policy policy_=SC_ONE_OR_MORE_BOUND );
+
+ // destructor
+ ~sc_bind_info();
+
+ int max_size() const;
+ sc_port_policy policy() const;
+ int size() const;
+
+ int m_max_size;
+ sc_port_policy m_policy;
+ std::vector<sc_bind_elem*> vec;
+ bool has_parent;
+ int last_add;
+ bool is_leaf;
+ bool complete;
+
+ std::vector<sc_bind_ef*> thread_vec;
+ std::vector<sc_bind_ef*> method_vec;
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+// constructor
+
+sc_bind_info::sc_bind_info( int max_size_, sc_port_policy policy_ )
+: m_max_size( max_size_ ),
+ m_policy( policy_ ),
+ vec(),
+ has_parent( false ),
+ last_add( -1 ),
+ is_leaf( true ),
+ complete( false ),
+ thread_vec(),
+ method_vec()
+{}
+
+
+// destructor
+
+sc_bind_info::~sc_bind_info()
+{
+ for( int i = size() - 1; i >= 0; -- i ) {
+ delete vec[i];
+ }
+}
+
+
+int
+sc_bind_info::max_size() const
+{
+ return m_max_size ? m_max_size : (int) vec.size();
+}
+
+sc_port_policy
+sc_bind_info::policy() const
+{
+ return m_policy;
+}
+
+int
+sc_bind_info::size() const
+{
+ return vec.size();
+}
+
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_port_base
+//
+// Abstract base class for class sc_port_b.
+// ----------------------------------------------------------------------------
+
+// This method exists to get around a problem in VCC 6.0 where you cannot
+// have a friend class that is templated. So sc_port_b<IF> calls this class
+// instead of sc_process_b::add_static_event.
+
+void sc_port_base::add_static_event(
+ sc_method_handle process_p, const sc_event& event ) const
+{
+ process_p->add_static_event( event );
+}
+
+void sc_port_base::add_static_event(
+ sc_thread_handle process_p, const sc_event& event ) const
+{
+ process_p->add_static_event( event );
+}
+
+// return number of interfaces that will be bound, or are bound:
+
+int sc_port_base::bind_count()
+{
+ if ( m_bind_info )
+ return m_bind_info->size();
+ else
+ return interface_count();
+}
+
+// error reporting
+
+void
+sc_port_base::report_error( const char* id, const char* add_msg ) const
+{
+ char msg[BUFSIZ];
+ if( add_msg != 0 ) {
+ std::sprintf( msg, "%s: port '%s' (%s)", add_msg, name(), kind() );
+ } else {
+ std::sprintf( msg, "port '%s' (%s)", name(), kind() );
+ }
+ SC_REPORT_ERROR( id, msg );
+}
+
+
+// constructors
+
+sc_port_base::sc_port_base(
+ int max_size_, sc_port_policy policy
+) :
+ sc_object( sc_gen_unique_name( "port" ) ),
+ m_bind_info(NULL)
+{
+ simcontext()->get_port_registry()->insert( this );
+ m_bind_info = new sc_bind_info( max_size_, policy );
+}
+
+sc_port_base::sc_port_base(
+ const char* name_, int max_size_, sc_port_policy policy
+) :
+ sc_object( name_ ),
+ m_bind_info(NULL)
+{
+ simcontext()->get_port_registry()->insert( this );
+ m_bind_info = new sc_bind_info( max_size_, policy );
+}
+
+
+// destructor
+
+sc_port_base::~sc_port_base()
+{
+ simcontext()->get_port_registry()->remove( this );
+ delete m_bind_info;
+}
+
+
+// bind interface to this port
+
+void
+sc_port_base::bind( sc_interface& interface_ )
+{
+ if( m_bind_info == 0 ) {
+ // cannot bind an interface after elaboration
+ report_error( SC_ID_BIND_IF_TO_PORT_, "simulation running" );
+ }
+
+ m_bind_info->vec.push_back( new sc_bind_elem( &interface_ ) );
+
+ if( ! m_bind_info->has_parent ) {
+ // add (cache) the interface
+ add_interface( &interface_ );
+ m_bind_info->last_add ++;
+ }
+}
+
+
+// bind parent port to this port
+
+void
+sc_port_base::bind( this_type& parent_ )
+{
+ if( m_bind_info == 0 ) {
+ // cannot bind a parent port after elaboration
+ report_error( SC_ID_BIND_PORT_TO_PORT_, "simulation running" );
+ }
+
+ if( &parent_ == this ) {
+ report_error( SC_ID_BIND_PORT_TO_PORT_, "same port" );
+ }
+
+ // check if parent port is already bound to this port
+#if 0
+ for( int i = m_bind_info->size() - 1; i >= 0; -- i ) {
+ if( &parent_ == m_bind_info->vec[i]->parent ) {
+ report_error( SC_ID_BIND_PORT_TO_PORT_, "already bound" );
+ }
+ }
+#endif //
+
+ m_bind_info->vec.push_back( new sc_bind_elem( &parent_ ) );
+ m_bind_info->has_parent = true;
+ parent_.m_bind_info->is_leaf = false;
+}
+
+// called by construction_done (null by default)
+
+void sc_port_base::before_end_of_elaboration()
+{}
+
+// called by elaboration_done (does nothing)
+
+void
+sc_port_base::end_of_elaboration()
+{}
+
+// called by sc_port_registry::start_simulation (does nothing by default)
+
+void sc_port_base::start_of_simulation()
+{}
+
+// called by sc_port_registry::simulation_done (does nothing by default)
+
+void sc_port_base::end_of_simulation()
+{}
+
+
+// called by class sc_module for positional binding
+
+int
+sc_port_base::pbind( sc_interface& interface_ )
+{
+ if( m_bind_info == 0 ) {
+ // cannot bind an interface after elaboration
+ report_error( SC_ID_BIND_IF_TO_PORT_, "simulation running" );
+ }
+
+ if( m_bind_info->size() != 0 ) {
+ // first interface already bound
+ return 1;
+ }
+
+ return vbind( interface_ );
+}
+
+int
+sc_port_base::pbind( sc_port_base& parent_ )
+{
+ if( m_bind_info == 0 ) {
+ // cannot bind a parent port after elaboration
+ report_error( SC_ID_BIND_PORT_TO_PORT_, "simulation running" );
+ }
+
+ if( m_bind_info->size() != 0 ) {
+ // first interface already bound
+ return 1;
+ }
+
+ return vbind( parent_ );
+}
+
+
+// called by the sc_sensitive* classes
+
+void
+sc_port_base::make_sensitive( sc_thread_handle handle_,
+ sc_event_finder* event_finder_ ) const
+{
+ assert( m_bind_info != 0 );
+ m_bind_info->thread_vec.push_back(
+ new sc_bind_ef( (sc_process_b*)handle_, event_finder_ ) );
+}
+
+void
+sc_port_base::make_sensitive( sc_method_handle handle_,
+ sc_event_finder* event_finder_ ) const
+{
+ assert( m_bind_info != 0 );
+ m_bind_info->method_vec.push_back(
+ new sc_bind_ef( (sc_process_b*)handle_, event_finder_ ) );
+}
+
+
+// support methods
+
+int
+sc_port_base::first_parent()
+{
+ for( int i = 0; i < m_bind_info->size(); ++ i ) {
+ if( m_bind_info->vec[i]->parent != 0 ) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+void
+sc_port_base::insert_parent( int i )
+{
+ std::vector<sc_bind_elem*>& vec = m_bind_info->vec;
+
+ this_type* parent = vec[i]->parent;
+
+
+ // IF OUR PARENT HAS NO BINDING THEN IGNORE IT:
+ //
+ // Note that the zeroing of the parent pointer must occur before this
+ // test
+
+ vec[i]->parent = 0;
+ if ( parent->m_bind_info->vec.size() == 0 ) return;
+
+ vec[i]->iface = parent->m_bind_info->vec[0]->iface;
+ int n = parent->m_bind_info->size() - 1;
+ if( n > 0 ) {
+ // resize the bind vector (by adding new elements)
+ for( int k = 0; k < n; ++ k ) {
+ vec.push_back( new sc_bind_elem() );
+ }
+ // move elements in the bind vector
+ for( int k = m_bind_info->size() - n - 1; k > i; -- k ) {
+ vec[k + n]->iface = vec[k]->iface;
+ vec[k + n]->parent = vec[k]->parent;
+ }
+ // insert parent interfaces into the bind vector
+ for( int k = i + 1; k <= i + n; ++ k ) {
+ vec[k]->iface = parent->m_bind_info->vec[k - i]->iface;
+ vec[k]->parent = 0;
+ }
+ }
+}
+
+
+// called when elaboration is done
+
+void
+sc_port_base::complete_binding()
+{
+ char msg_buffer[128]; // For error message construction.
+
+ // IF BINDING HAS ALREADY BEEN COMPLETED IGNORE THIS CALL:
+
+ assert( m_bind_info != 0 );
+ if( m_bind_info->complete ) {
+ return;
+ }
+
+ // COMPLETE BINDING OF OUR PARENT PORTS SO THAT WE CAN USE THAT INFORMATION:
+
+ int i = first_parent();
+ while( i >= 0 ) {
+ m_bind_info->vec[i]->parent->complete_binding();
+ insert_parent( i );
+ i = first_parent();
+ }
+
+ // LOOP OVER BINDING INFORMATION TO COMPLETE THE BINDING PROCESS:
+
+ int size;
+ for( int j = 0; j < m_bind_info->size(); ++ j ) {
+ sc_interface* iface = m_bind_info->vec[j]->iface;
+
+ // if the interface is zero this was for an unbound port.
+ if ( iface == 0 ) continue;
+
+ // add (cache) the interface
+ if( j > m_bind_info->last_add ) {
+ add_interface( iface );
+ }
+
+ // only register "leaf" ports (ports without children)
+ if( m_bind_info->is_leaf ) {
+ iface->register_port( *this, if_typename() );
+ }
+
+ // complete static sensitivity for methods
+ size = m_bind_info->method_vec.size();
+ for( int k = 0; k < size; ++ k ) {
+ sc_bind_ef* p = m_bind_info->method_vec[k];
+ const sc_event& event = ( p->event_finder != 0 )
+ ? p->event_finder->find_event(iface)
+ : iface->default_event();
+ p->handle->add_static_event( event );
+ }
+
+ // complete static sensitivity for threads
+ size = m_bind_info->thread_vec.size();
+ for( int k = 0; k < size; ++ k ) {
+ sc_bind_ef* p = m_bind_info->thread_vec[k];
+ const sc_event& event = ( p->event_finder != 0 )
+ ? p->event_finder->find_event(iface)
+ : iface->default_event();
+ p->handle->add_static_event( event );
+ }
+
+ }
+
+ // MAKE SURE THE PROPER NUMBER OF BINDINGS OCCURRED:
+ //
+ // Make sure there are enough bindings, and not too many.
+
+ int actual_binds = interface_count();
+
+ if ( actual_binds > m_bind_info->max_size() )
+ {
+ sprintf(msg_buffer, "%d binds exceeds maximum of %d allowed",
+ actual_binds, m_bind_info->max_size() );
+ report_error( SC_ID_COMPLETE_BINDING_, msg_buffer );
+ }
+ switch ( m_bind_info->policy() )
+ {
+ case SC_ONE_OR_MORE_BOUND:
+ if ( actual_binds < 1 ) {
+ report_error( SC_ID_COMPLETE_BINDING_, "port not bound" );
+ }
+ break;
+ case SC_ALL_BOUND:
+ if ( actual_binds < m_bind_info->max_size() || actual_binds < 1 ) {
+ sprintf(msg_buffer, "%d actual binds is less than required %d",
+ actual_binds, m_bind_info->max_size() );
+ report_error( SC_ID_COMPLETE_BINDING_, msg_buffer );
+ }
+ break;
+ default: // SC_ZERO_OR_MORE_BOUND:
+ break;
+ }
+
+
+ // CLEAN UP: FREE BINDING STORAGE:
+
+ size = m_bind_info->method_vec.size();
+ for( int k = 0; k < size; ++ k ) {
+ delete m_bind_info->method_vec[k];
+ }
+ m_bind_info->method_vec.resize(0);
+
+ size = m_bind_info->thread_vec.size();
+ for( int k = 0; k < size; ++ k ) {
+ delete m_bind_info->thread_vec[k];
+ }
+ m_bind_info->thread_vec.resize(0);
+
+ m_bind_info->complete = true;
+}
+
+void
+sc_port_base::construction_done()
+{
+ sc_module* parent = static_cast<sc_module*>( get_parent_object() );
+ sc_object::hierarchy_scope scope( parent );
+ before_end_of_elaboration();
+}
+
+void
+sc_port_base::elaboration_done()
+{
+ assert( m_bind_info != 0 && m_bind_info->complete );
+ delete m_bind_info;
+ m_bind_info = 0;
+
+ sc_module* parent = static_cast<sc_module*>( get_parent_object() );
+ sc_object::hierarchy_scope scope( parent );
+ end_of_elaboration();
+}
+
+void
+sc_port_base::start_simulation()
+{
+ sc_module* parent = static_cast<sc_module*>( get_parent_object() );
+ sc_object::hierarchy_scope scope( parent );
+ start_of_simulation();
+}
+
+void
+sc_port_base::simulation_done()
+{
+ sc_module* parent = static_cast<sc_module*>( get_parent_object() );
+ sc_object::hierarchy_scope scope( parent );
+ end_of_simulation();
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_port_registry
+//
+// Registry for all ports.
+// FOR INTERNAL USE ONLY!
+// ----------------------------------------------------------------------------
+
+void
+sc_port_registry::insert( sc_port_base* port_ )
+{
+ if( sc_is_running() ) {
+ port_->report_error( SC_ID_INSERT_PORT_, "simulation running" );
+ }
+
+ if( m_simc->elaboration_done() ) {
+ port_->report_error( SC_ID_INSERT_PORT_, "elaboration done" );
+ }
+
+#if defined(DEBUG_SYSTEMC)
+ // check if port_ is already inserted
+ for( int i = size() - 1; i >= 0; -- i ) {
+ if( port_ == m_port_vec[i] ) {
+ port_->report_error( SC_ID_INSERT_PORT_, "port already inserted" );
+ }
+ }
+#endif
+
+ // append the port to the current module's vector of ports
+ sc_module* curr_module = m_simc->hierarchy_curr();
+ if( curr_module == 0 ) {
+ port_->report_error( SC_ID_PORT_OUTSIDE_MODULE_ );
+ }
+ curr_module->append_port( port_ );
+
+ // insert
+ m_port_vec.push_back( port_ );
+}
+
+void
+sc_port_registry::remove( sc_port_base* port_ )
+{
+ int i;
+ for( i = size() - 1; i >= 0; -- i ) {
+ if( port_ == m_port_vec[i] ) {
+ break;
+ }
+ }
+ if( i == -1 ) {
+ port_->report_error( SC_ID_REMOVE_PORT_, "port not registered" );
+ }
+
+ // remove
+ m_port_vec[i] = m_port_vec[size() - 1];
+ m_port_vec.resize(size()-1);
+}
+
+
+// constructor
+
+sc_port_registry::sc_port_registry( sc_simcontext& simc_ )
+: m_construction_done(0),
+ m_port_vec(),
+ m_simc( &simc_ )
+{
+}
+
+
+// destructor
+
+sc_port_registry::~sc_port_registry()
+{
+}
+
+// called when construction is done
+
+bool
+sc_port_registry::construction_done()
+{
+ if( size() == m_construction_done )
+ // nothing has been updated
+ return true;
+
+ for( int i = size()-1; i >= m_construction_done; --i ) {
+ m_port_vec[i]->construction_done();
+ }
+
+ m_construction_done = size();
+ return false;
+}
+
+// called when when elaboration is done
+
+void
+sc_port_registry::complete_binding()
+{
+ for( int i = size() - 1; i >= 0; -- i ) {
+ m_port_vec[i]->complete_binding();
+ }
+}
+
+
+// called when elaboration is done
+
+void
+sc_port_registry::elaboration_done()
+{
+ complete_binding();
+
+ for( int i = size() - 1; i >= 0; -- i ) {
+ m_port_vec[i]->elaboration_done();
+ }
+}
+
+// called before simulation begins
+
+void
+sc_port_registry::start_simulation()
+{
+ for( int i = size() - 1; i >= 0; -- i ) {
+ m_port_vec[i]->start_simulation();
+ }
+}
+
+// called after simulation ends
+
+void
+sc_port_registry::simulation_done()
+{
+ for( int i = size() - 1; i >= 0; -- i ) {
+ m_port_vec[i]->simulation_done();
+ }
+}
+
+// This is a static member function.
+
+void
+sc_port_registry::replace_port( sc_port_registry* /* registry */ )
+{
+}
+
+void sc_warn_port_constructor()
+{
+ static bool warn_port_constructor=true;
+ if ( warn_port_constructor )
+ {
+ warn_port_constructor = false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "interface and/or port binding in port constructors is deprecated"
+ );
+ }
+}
+
+} // namespace sc_core
+
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Andy Goodrich, Forte Design Systems
+ Bishnupriya Bhattacharya, Cadence Design Systems,
+ 25 August, 2003
+ Description of Modification: phase callbacks
+
+ Name, Affiliation, Date: Andy Goodrich, Forte Design Systems
+ 12 December, 2005
+ Description of Modification: multiport binding policy changes
+
+ *****************************************************************************/
+
+
+// $Log: sc_port.cpp,v $
+// Revision 1.8 2011/08/24 22:05:36 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.7 2011/08/15 16:43:24 acg
+// Torsten Maehne: changes to remove unused argument warnings.
+//
+// Revision 1.6 2011/08/07 19:08:01 acg
+// Andy Goodrich: moved logs to end of file so line number synching works
+// better between versions.
+//
+// Revision 1.5 2011/08/07 18:53:09 acg
+// Philipp A. Hartmann: add virtual instances of the bind function for
+// base classes to eliminate warning messages for clang platforms.
+//
+// Revision 1.4 2011/05/09 04:07:37 acg
+// Philipp A. Hartmann:
+// (1) Restore hierarchy in all phase callbacks.
+// (2) Ensure calls to before_end_of_elaboration.
+//
+// Revision 1.3 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+// Revision 1.2 2011/02/14 17:50:16 acg
+// Andy Goodrich: testing for sc_port and sc_export instantiations during
+// end of elaboration and issuing appropriate error messages.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.11 2006/08/29 23:34:59 acg
+// Andy Goodrich: added bind_count() method to allow users to determine which
+// ports are connected in before_end_of_elaboration().
+//
+// Revision 1.10 2006/05/08 17:52:47 acg
+// Andy Goodrich:
+// (1) added David Long's forward declarations for friend functions,
+// methods, and operators to keep the Microsoft compiler happy.
+// (2) Added delta_count() method to sc_prim_channel for use by
+// sc_signal so that the friend declaration in sc_simcontext.h
+// can be for a non-templated class (i.e., sc_prim_channel.)
+//
+// Revision 1.9 2006/02/02 20:43:09 acg
+// Andy Goodrich: Added an existence linked list to sc_event_finder so that
+// the dynamically allocated instances can be freed after port binding
+// completes. This replaces the individual deletions in ~sc_bind_ef, as these
+// caused an exception if an sc_event_finder instance was used more than
+// once, due to a double freeing of the instance.
+//
+// Revision 1.7 2006/01/26 21:00:50 acg
+// Andy Goodrich: conversion to use sc_event::notify(SC_ZERO_TIME) instead of
+// sc_event::notify_delayed()
+//
+// Revision 1.6 2006/01/25 00:31:11 acg
+// Andy Goodrich: Changed over to use a standard message id of
+// SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
+//
+// Revision 1.5 2006/01/24 20:46:31 acg
+// Andy Goodrich: changes to eliminate use of deprecated features. For instance,
+// using notify(SC_ZERO_TIME) in place of notify_delayed().
+//
+// Revision 1.4 2006/01/13 20:41:59 acg
+// Andy Goodrich: Changes to add port registration to the things that are
+// checked when SC_NO_WRITE_CHECK is not defined.
+//
+// Revision 1.3 2006/01/13 18:47:42 acg
+// Added $Log command so that CVS comments are reproduced in the source.
+//
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_port.h b/ext/systemc/src/sysc/communication/sc_port.h
new file mode 100644
index 000000000..a126657e6
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_port.h
@@ -0,0 +1,732 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_port.h -- Base classes of all port classes.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_PORT_H
+#define SC_PORT_H
+
+
+#include "sysc/communication/sc_communication_ids.h"
+#include "sysc/communication/sc_interface.h"
+#include "sysc/kernel/sc_event.h"
+#include "sysc/kernel/sc_object.h"
+#include "sysc/kernel/sc_process.h"
+#include <typeinfo>
+
+#if ! defined( SC_DISABLE_VIRTUAL_BIND )
+# define SC_VIRTUAL_ virtual
+#else
+# define SC_VIRTUAL_ /* non-virtual */
+#endif
+
+namespace sc_core {
+
+class sc_event_finder;
+
+struct sc_bind_info;
+
+enum sc_port_policy
+{
+ SC_ONE_OR_MORE_BOUND, // Default
+ SC_ZERO_OR_MORE_BOUND,
+ SC_ALL_BOUND
+};
+
+
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+// BEWARE: Ports can only be created and bound during elaboration.
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_port_base
+//
+// Abstract base class for class sc_port_b.
+// ----------------------------------------------------------------------------
+
+class sc_port_base
+: public sc_object
+{
+ friend class sc_module;
+ friend class sc_port_registry;
+ friend class sc_sensitive;
+ friend class sc_sensitive_pos;
+ friend class sc_sensitive_neg;
+
+public:
+
+ // typedefs
+
+ typedef sc_port_base this_type;
+
+public:
+
+ int bind_count();
+
+ // get the first interface without checking for nil
+ virtual sc_interface* get_interface() = 0;
+ virtual const sc_interface* get_interface() const = 0;
+
+ virtual const char* kind() const
+ { return "sc_port_base"; }
+
+protected:
+
+ // constructors
+ explicit sc_port_base( int max_size_,
+ sc_port_policy policy=SC_ONE_OR_MORE_BOUND );
+ sc_port_base( const char* name_, int max_size_,
+ sc_port_policy policy=SC_ONE_OR_MORE_BOUND );
+
+ // destructor
+ virtual ~sc_port_base();
+
+ // bind interface to this port
+ void bind( sc_interface& interface_ );
+
+ // bind parent port to this port
+ void bind( this_type& parent_ );
+
+ // called by pbind (for internal use only)
+ virtual int vbind( sc_interface& ) = 0;
+ virtual int vbind( sc_port_base& ) = 0;
+
+ // called by complete_binding (for internal use only)
+ virtual void add_interface( sc_interface* ) = 0;
+ virtual int interface_count() = 0;
+ virtual const char* if_typename() const = 0;
+
+ // called by construction_done (does nothing by default)
+ virtual void before_end_of_elaboration();
+
+ // called by elaboration_done (does nothing)
+ virtual void end_of_elaboration();
+
+ // called by start_simulation (does nothing by default)
+ virtual void start_of_simulation();
+
+ // called by simulation_done (does nothing by default)
+ virtual void end_of_simulation();
+
+ // error reporting
+ void report_error( const char* id, const char* add_msg = 0) const;
+
+protected:
+ // called by the sc_sensitive* classes
+ virtual void make_sensitive( sc_thread_handle, sc_event_finder* = 0 ) const;
+ virtual void make_sensitive( sc_method_handle, sc_event_finder* = 0 ) const;
+ void add_static_event(
+ sc_method_handle process_p, const sc_event& event) const;
+ void add_static_event(
+ sc_thread_handle process_p, const sc_event& event) const;
+
+private:
+
+ // called by class sc_module for positional binding
+ int pbind( sc_interface& );
+ int pbind( sc_port_base& );
+
+
+ // support methods
+ int first_parent();
+ void insert_parent( int );
+
+ // called when construction is done
+ void construction_done();
+
+ // called when elaboration is done
+ void complete_binding();
+ void elaboration_done();
+
+ // called before simulation starts
+ void start_simulation();
+
+ // called after simulation ends
+ void simulation_done();
+
+protected:
+
+ sc_bind_info* m_bind_info;
+
+private:
+
+ // disabled
+ sc_port_base();
+ sc_port_base( const this_type& );
+ this_type& operator = ( const this_type& );
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_port_registry
+//
+// Registry for all ports.
+// FOR INTERNAL USE ONLY!
+// ----------------------------------------------------------------------------
+
+class sc_port_registry
+{
+ friend class sc_simcontext;
+
+public:
+
+ void insert( sc_port_base* );
+ void remove( sc_port_base* );
+
+ int size() const
+ { return m_port_vec.size(); }
+
+private:
+
+ // constructor
+ explicit sc_port_registry( sc_simcontext& simc_ );
+
+ // destructor
+ ~sc_port_registry();
+
+ // called when by construction_done and elaboration done
+ void complete_binding();
+
+ // called when construction is done
+ bool construction_done();
+
+ // called when elaboration is done
+ void elaboration_done();
+
+ // called before simulation starts
+ void start_simulation();
+
+ // called after simulation ends
+ void simulation_done();
+
+ static void replace_port( sc_port_registry* );
+
+private:
+
+ int m_construction_done;
+ std::vector<sc_port_base*> m_port_vec;
+ sc_simcontext* m_simc;
+
+private:
+
+ // disabled
+ sc_port_registry();
+ sc_port_registry( const sc_port_registry& );
+ sc_port_registry& operator = ( const sc_port_registry& );
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_port_b
+//
+// Abstract base class for class sc_port.
+// ----------------------------------------------------------------------------
+
+template <class IF>
+class sc_port_b
+: public sc_port_base
+{
+public:
+
+ friend class sc_sensitive;
+ friend class sc_sensitive_neg;
+ friend class sc_sensitive_pos;
+
+ // typedefs
+
+ typedef sc_port_base base_type;
+ typedef sc_port_b<IF> this_type;
+ typedef this_type port_type;
+
+public:
+
+ // bind an interface of type IF to this port
+
+ SC_VIRTUAL_ void bind( IF& interface_ )
+ { base_type::bind( interface_ ); }
+
+ void operator () ( IF& interface_ )
+ { this->bind( interface_ ); }
+
+
+ // bind a parent port with type IF to this port
+
+ SC_VIRTUAL_ void bind( port_type& parent_ )
+ { base_type::bind( parent_ ); }
+
+ void operator () ( port_type& parent_ )
+ { this->bind( parent_ ); }
+
+
+ // number of connected interfaces
+
+ int size() const
+ { return m_interface_vec.size(); }
+
+
+ // allow to call methods provided by the first interface
+ IF* operator -> ();
+ const IF* operator -> () const;
+
+
+ // allow to call methods provided by interface at index
+ inline const IF* get_interface( int iface_i ) const;
+ inline IF* get_interface( int iface_i );
+ IF* operator [] ( int index_ )
+ { return get_interface( index_ ); }
+ const IF* operator [] ( int index_ ) const
+ { return get_interface( index_ ); }
+
+
+ // get the first interface without checking for nil
+
+ virtual sc_interface* get_interface()
+ { return m_interface; }
+
+ virtual const sc_interface* get_interface() const
+ { return m_interface; }
+
+protected:
+
+ // constructors
+
+ explicit sc_port_b( int max_size_,
+ sc_port_policy policy=SC_ONE_OR_MORE_BOUND ) :
+ base_type( max_size_, policy ), m_interface( 0 ), m_interface_vec()
+ {}
+
+ sc_port_b( const char* name_, int max_size_,
+ sc_port_policy policy=SC_ONE_OR_MORE_BOUND ) :
+ base_type( name_, max_size_, policy ), m_interface( 0 ),
+ m_interface_vec()
+ {}
+
+
+ // destructor (does nothing)
+
+ virtual ~sc_port_b()
+ {}
+
+
+ // called by pbind (for internal use only)
+ virtual int vbind( sc_interface& );
+ virtual int vbind( sc_port_base& );
+
+protected:
+
+ // called by the sc_sensitive* classes
+ virtual void make_sensitive( sc_thread_handle, sc_event_finder* = 0 ) const;
+ virtual void make_sensitive( sc_method_handle, sc_event_finder* = 0 ) const;
+
+private:
+
+ // called by complete_binding (for internal use only)
+ virtual void add_interface( sc_interface* );
+ virtual const char* if_typename() const;
+ virtual int interface_count();
+
+ // disabled
+ sc_port_b();
+ sc_port_b( const this_type& );
+ this_type& operator = ( const this_type& );
+
+private:
+
+ IF* m_interface; // first interface in interface vec
+ std::vector<IF*> m_interface_vec;
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_port
+//
+// Generic port class and base class for other port classes.
+// N is the maximum number of channels (with interface IF) that can be bound
+// to this port. N <= 0 means no maximum.
+// ----------------------------------------------------------------------------
+
+extern void sc_warn_port_constructor();
+
+template <class IF, int N = 1, sc_port_policy P=SC_ONE_OR_MORE_BOUND>
+class sc_port
+: public sc_port_b<IF>
+{
+ // typdefs
+
+ typedef sc_port_b<IF> base_type;
+ typedef sc_port<IF,N,P> this_type;
+
+public:
+
+ // constructors
+
+ sc_port()
+ : base_type( N, P )
+ {}
+
+ explicit sc_port( const char* name_ )
+ : base_type( name_, N, P )
+ {}
+
+ explicit sc_port( IF& interface_ )
+ : base_type( N, P )
+ { sc_warn_port_constructor(); base_type::bind( interface_ ); }
+
+ sc_port( const char* name_, IF& interface_ )
+ : base_type( name_, N, P )
+ { sc_warn_port_constructor(); base_type::bind( interface_ ); }
+
+ explicit sc_port( base_type& parent_ )
+ : base_type( N, P )
+ { sc_warn_port_constructor(); base_type::bind( parent_ ); }
+
+ sc_port( const char* name_, base_type& parent_ )
+ : base_type( name_, N, P )
+ { sc_warn_port_constructor(); base_type::bind( parent_ ); }
+
+ sc_port( this_type& parent_ )
+ : base_type( N, P )
+ { sc_warn_port_constructor(); base_type::bind( parent_ ); }
+
+ sc_port( const char* name_, this_type& parent_ )
+ : base_type( name_, N, P )
+ { sc_warn_port_constructor(); base_type::bind( parent_ ); }
+
+
+ // destructor (does nothing)
+
+ virtual ~sc_port()
+ {}
+
+ virtual const char* kind() const
+ { return "sc_port"; }
+
+private:
+
+ // disabled
+ sc_port( const this_type& );
+ this_type& operator = ( const this_type& );
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_port_b
+//
+// Abstract base class for class sc_port.
+// ----------------------------------------------------------------------------
+
+// allow to call methods provided by the first interface
+
+template <class IF>
+inline
+IF*
+sc_port_b<IF>::operator -> ()
+{
+ if( m_interface == 0 ) {
+ report_error( SC_ID_GET_IF_, "port is not bound" );
+ }
+ return m_interface;
+}
+
+template <class IF>
+inline
+const IF*
+sc_port_b<IF>::operator -> () const
+{
+ if( m_interface == 0 ) {
+ report_error( SC_ID_GET_IF_, "port is not bound" );
+ }
+ return m_interface;
+}
+
+
+// allow to call methods provided by interface at index
+//
+// note that we special-case index of zero, since the method may be
+// called before binding has occurred, and we need to return a zero
+// in that case not an error.
+
+template <class IF>
+inline
+IF*
+sc_port_b<IF>::get_interface( int index_ )
+{
+ if ( index_ == 0 ) {
+ return m_interface;
+ }
+ else if( index_ < 0 || index_ >= size() ) {
+ report_error( SC_ID_GET_IF_, "index out of range" );
+ }
+ return m_interface_vec[index_];
+}
+
+template <class IF>
+inline
+const IF*
+sc_port_b<IF>::get_interface( int index_ ) const
+{
+ if ( index_ == 0 ) {
+ return m_interface;
+ }
+ else if( index_ < 0 || index_ >= size() ) {
+ report_error( SC_ID_GET_IF_, "index out of range" );
+ }
+ return m_interface_vec[index_];
+}
+
+
+// called by pbind (for internal use only)
+
+template <class IF>
+inline
+int
+sc_port_b<IF>::vbind( sc_interface& interface_ )
+{
+ IF* iface = DCAST<IF*>( &interface_ );
+ if( iface == 0 ) {
+ // type mismatch
+ return 2;
+ }
+ base_type::bind( *iface );
+ return 0;
+}
+
+template <class IF>
+inline
+int
+sc_port_b<IF>::vbind( sc_port_base& parent_ )
+{
+ this_type* parent = DCAST<this_type*>( &parent_ );
+ if( parent == 0 ) {
+ // type mismatch
+ return 2;
+ }
+ base_type::bind( *parent );
+ return 0;
+}
+
+
+// called by complete_binding (for internal use only)
+
+template <class IF>
+inline
+void
+sc_port_b<IF>::add_interface( sc_interface* interface_ )
+{
+ IF* iface = DCAST<IF*>( interface_ );
+ assert( iface != 0 );
+
+ // make sure that the interface is not already bound:
+
+ int size = m_interface_vec.size();
+ for ( int i = 0; i < size; i++ )
+ {
+ if ( iface == m_interface_vec[i] )
+ {
+ report_error( SC_ID_BIND_IF_TO_PORT_,
+ "interface already bound to port" );
+ }
+ }
+
+ // "bind" the interface and make sure our short cut for 0 is set up.
+
+ m_interface_vec.push_back( iface );
+ m_interface = m_interface_vec[0];
+}
+
+template <class IF>
+inline
+const char*
+sc_port_b<IF>::if_typename() const
+{
+ return typeid( IF ).name();
+}
+
+template <class IF>
+inline
+int
+sc_port_b<IF>::interface_count()
+{
+ return m_interface_vec.size();
+}
+
+template <class IF>
+void
+sc_port_b<IF>::make_sensitive( sc_thread_handle handle_p,
+ sc_event_finder* event_finder_ ) const
+{
+ if ( m_bind_info == 0 )
+ {
+ int if_n = m_interface_vec.size();
+ for ( int if_i = 0; if_i < if_n; if_i++ )
+ {
+ IF* iface_p = m_interface_vec[if_i];
+ assert( iface_p != 0 );
+ add_static_event( handle_p, iface_p->default_event() );
+ }
+ }
+ else
+ {
+ sc_port_base::make_sensitive( handle_p, event_finder_ );
+ }
+}
+
+template <class IF>
+void
+sc_port_b<IF>::make_sensitive( sc_method_handle handle_p,
+ sc_event_finder* event_finder_ ) const
+{
+ if ( m_bind_info == 0 )
+ {
+ int if_n = m_interface_vec.size();
+ for ( int if_i = 0; if_i < if_n; if_i++ )
+ {
+ IF* iface_p = m_interface_vec[if_i];
+ assert( iface_p != 0 );
+ add_static_event( handle_p, iface_p->default_event() );
+ }
+ }
+ else
+ {
+ sc_port_base::make_sensitive( handle_p, event_finder_ );
+ }
+}
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_port
+//
+// Generic port class and base class for other port classes.
+// N is the maximum number of channels (with interface IF) that can be bound
+// to this port. N <= 0 means no maximum.
+// ----------------------------------------------------------------------------
+
+} // namespace sc_core
+
+#undef SC_VIRTUAL_
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Andy Goodrich, Forte,
+ Bishnupriya Bhattacharya, Cadence Design Systems,
+ 25 August, 2003
+ Description of Modification: phase callbacks
+
+ Name, Affiliation, Date: Andy Goodrich, Forte Design Systems
+ 12 December, 2005
+ Description of Modification: multiport binding policy changes
+
+
+ *****************************************************************************/
+
+/*
+$Log: sc_port.h,v $
+Revision 1.10 2011/08/26 20:45:41 acg
+ Andy Goodrich: moved the modification log to the end of the file to
+ eliminate source line number skew when check-ins are done.
+
+Revision 1.9 2011/08/24 22:05:36 acg
+ Torsten Maehne: initialization changes to remove warnings.
+
+Revision 1.8 2011/08/07 19:08:01 acg
+ Andy Goodrich: moved logs to end of file so line number synching works
+ better between versions.
+
+Revision 1.7 2011/08/07 18:53:09 acg
+ Philipp A. Hartmann: add virtual instances of the bind function for
+ base classes to eliminate warning messages for clang platforms.
+
+Revision 1.6 2011/05/09 04:07:37 acg
+ Philipp A. Hartmann:
+ (1) Restore hierarchy in all phase callbacks.
+ (2) Ensure calls to before_end_of_elaboration.
+
+Revision 1.5 2011/03/30 16:46:10 acg
+ Andy Goodrich: added a signature and removed a virtual specification
+ to eliminate warnings with certain compilers.
+
+Revision 1.4 2011/02/18 20:23:45 acg
+ Andy Goodrich: Copyright update.
+
+Revision 1.3 2011/01/20 16:52:15 acg
+ Andy Goodrich: changes for IEEE 1666 2011.
+
+Revision 1.2 2010/08/03 18:01:11 acg
+ Andy Goodrich: formatting.
+
+Revision 1.1.1.1 2006/12/15 20:20:04 acg
+SystemC 2.3
+
+Revision 1.5 2006/08/29 23:35:00 acg
+ Andy Goodrich: added bind_count() method to allow users to determine which
+ ports are connected in before_end_of_elaboration().
+
+Revision 1.4 2006/05/08 17:52:47 acg
+ Andy Goodrich:
+ (1) added David Long's forward declarations for friend functions,
+ methods, and operators to keep the Microsoft compiler happy.
+ (2) Added delta_count() method to sc_prim_channel for use by
+ sc_signal so that the friend declaration in sc_simcontext.h
+ can be for a non-templated class (i.e., sc_prim_channel.)
+
+Revision 1.3 2006/01/24 20:46:31 acg
+Andy Goodrich: changes to eliminate use of deprecated features. For instance,
+using notify(SC_ZERO_TIME) in place of notify_delayed().
+
+Revision 1.2 2006/01/03 23:18:26 acg
+Changed copyright to include 2006.
+
+Revision 1.1.1.1 2005/12/19 23:16:43 acg
+First check in of SystemC 2.1 into its own archive.
+
+Revision 1.10 2005/09/15 23:01:51 acg
+Added std:: prefix to appropriate methods and types to get around
+issues with the Edison Front End.
+
+Revision 1.9 2005/08/10 01:35:59 acg
+Changes for 64-bit support.
+
+Revision 1.8 2005/04/03 22:52:51 acg
+Namespace changes.
+
+Revision 1.7 2005/03/21 22:31:32 acg
+Changes to sc_core namespace.
+
+Revision 1.6 2004/09/27 21:02:54 acg
+Andy Goodrich - Forte Design Systems, Inc.
+ - Added a $Log comment so that CVS checkin comments will appear in
+ checked out source.
+
+*/
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_prim_channel.cpp b/ext/systemc/src/sysc/communication/sc_prim_channel.cpp
new file mode 100644
index 000000000..067884281
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_prim_channel.cpp
@@ -0,0 +1,429 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_prim_channel.cpp -- Abstract base class of all primitive channel
+ classes.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include "sysc/communication/sc_prim_channel.h"
+#include "sysc/communication/sc_communication_ids.h"
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_module.h"
+#include "sysc/kernel/sc_object_int.h"
+
+#ifndef SC_DISABLE_ASYNC_UPDATES
+# include "sysc/communication/sc_host_mutex.h"
+#endif
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_prim_channel
+//
+// Abstract base class of all primitive channel classes.
+// ----------------------------------------------------------------------------
+
+// constructors
+
+sc_prim_channel::sc_prim_channel()
+: sc_object( 0 ),
+ m_registry( simcontext()->get_prim_channel_registry() ),
+ m_update_next_p( 0 )
+{
+ m_registry->insert( *this );
+}
+
+sc_prim_channel::sc_prim_channel( const char* name_ )
+: sc_object( name_ ),
+ m_registry( simcontext()->get_prim_channel_registry() ),
+ m_update_next_p( 0 )
+{
+ m_registry->insert( *this );
+}
+
+
+// destructor
+
+sc_prim_channel::~sc_prim_channel()
+{
+ m_registry->remove( *this );
+}
+
+
+// the update method (does nothing by default)
+
+void
+sc_prim_channel::update()
+{}
+
+
+// called by construction_done (does nothing by default)
+
+void sc_prim_channel::before_end_of_elaboration()
+{}
+
+// called when construction is done
+
+void
+sc_prim_channel::construction_done()
+{
+ sc_object::hierarchy_scope scope( get_parent_object() );
+ before_end_of_elaboration();
+}
+
+// called by elaboration_done (does nothing by default)
+
+void
+sc_prim_channel::end_of_elaboration()
+{}
+
+
+// called when elaboration is done
+
+void
+sc_prim_channel::elaboration_done()
+{
+ sc_object::hierarchy_scope scope( get_parent_object() );
+ end_of_elaboration();
+}
+
+// called by start_simulation (does nothing)
+
+void
+sc_prim_channel::start_of_simulation()
+{}
+
+// called before simulation begins
+
+void
+sc_prim_channel::start_simulation()
+{
+ sc_object::hierarchy_scope scope( get_parent_object() );
+ start_of_simulation();
+}
+
+// called by simulation_done (does nothing)
+
+void
+sc_prim_channel::end_of_simulation()
+{}
+
+// called after simulation ends
+
+void
+sc_prim_channel::simulation_done()
+{
+ sc_object::hierarchy_scope scope( get_parent_object() );
+ end_of_simulation();
+}
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_prim_channel_registry::async_update_list
+//
+// Thread-safe list of pending external updates
+// FOR INTERNAL USE ONLY!
+// ----------------------------------------------------------------------------
+
+class sc_prim_channel_registry::async_update_list
+{
+#ifndef SC_DISABLE_ASYNC_UPDATES
+public:
+
+ bool pending() const
+ {
+ return m_push_queue.size() != 0;
+ }
+
+ void append( sc_prim_channel& prim_channel_ )
+ {
+ sc_scoped_lock lock( m_mutex );
+ m_push_queue.push_back( &prim_channel_ );
+ // return releases the mutex
+ }
+
+ void accept_updates()
+ {
+ sc_assert( ! m_pop_queue.size() );
+ {
+ sc_scoped_lock lock( m_mutex );
+ m_push_queue.swap( m_pop_queue );
+ // leaving the block releases the mutex
+ }
+
+ std::vector< sc_prim_channel* >::const_iterator
+ it = m_pop_queue.begin(), end = m_pop_queue.end();
+ while( it!= end )
+ {
+ // we use request_update instead of perform_update
+ // to skip duplicates
+ (*it++)->request_update();
+ }
+ m_pop_queue.clear();
+ }
+
+private:
+ sc_host_mutex m_mutex;
+ std::vector< sc_prim_channel* > m_push_queue;
+ std::vector< sc_prim_channel* > m_pop_queue;
+
+#endif // ! SC_DISABLE_ASYNC_UPDATES
+};
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_prim_channel_registry
+//
+// Registry for all primitive channels.
+// FOR INTERNAL USE ONLY!
+// ----------------------------------------------------------------------------
+
+void
+sc_prim_channel_registry::insert( sc_prim_channel& prim_channel_ )
+{
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_INSERT_PRIM_CHANNEL_, "simulation running" );
+ }
+
+ if( m_simc->elaboration_done() ) {
+
+ SC_REPORT_ERROR( SC_ID_INSERT_PRIM_CHANNEL_, "elaboration done" );
+ }
+
+#ifdef DEBUG_SYSTEMC
+ // check if prim_channel_ is already inserted
+ for( int i = 0; i < size(); ++ i ) {
+ if( &prim_channel_ == m_prim_channel_vec[i] ) {
+ SC_REPORT_ERROR( SC_ID_INSERT_PRIM_CHANNEL_, "already inserted" );
+ }
+ }
+#endif
+
+ // insert
+ m_prim_channel_vec.push_back( &prim_channel_ );
+
+}
+
+void
+sc_prim_channel_registry::remove( sc_prim_channel& prim_channel_ )
+{
+ int i;
+ for( i = 0; i < size(); ++ i ) {
+ if( &prim_channel_ == m_prim_channel_vec[i] ) {
+ break;
+ }
+ }
+ if( i == size() ) {
+ SC_REPORT_ERROR( SC_ID_REMOVE_PRIM_CHANNEL_, 0 );
+ }
+
+ // remove
+ m_prim_channel_vec[i] = m_prim_channel_vec[size() - 1];
+ m_prim_channel_vec.resize(size()-1);
+}
+
+bool
+sc_prim_channel_registry::pending_async_updates() const
+{
+#ifndef SC_DISABLE_ASYNC_UPDATES
+ return m_async_update_list_p->pending();
+#else
+ return false;
+#endif
+}
+
+void
+sc_prim_channel_registry::async_request_update( sc_prim_channel& prim_channel_ )
+{
+#ifndef SC_DISABLE_ASYNC_UPDATES
+ m_async_update_list_p->append( prim_channel_ );
+#else
+ SC_REPORT_ERROR( SC_ID_NO_ASYNC_UPDATE_, prim_channel_.name() );
+#endif
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_prim_channel_registry::perform_update"
+// |
+// | This method updates the values of the primitive channels in its update
+// | lists.
+// +----------------------------------------------------------------------------
+void
+sc_prim_channel_registry::perform_update()
+{
+ // Update the values for the primitive channels set external to the
+ // simulator.
+
+#ifndef SC_DISABLE_ASYNC_UPDATES
+ if( m_async_update_list_p->pending() )
+ m_async_update_list_p->accept_updates();
+#endif
+
+ sc_prim_channel* next_p; // Next update to perform.
+ sc_prim_channel* now_p; // Update now performing.
+
+ // Update the values for the primitive channels in the simulator's list.
+
+ now_p = m_update_list_p;
+ m_update_list_p = (sc_prim_channel*)sc_prim_channel::list_end;
+ for ( ; now_p != (sc_prim_channel*)sc_prim_channel::list_end;
+ now_p = next_p )
+ {
+ next_p = now_p->m_update_next_p;
+ now_p->perform_update();
+ }
+}
+
+// constructor
+
+sc_prim_channel_registry::sc_prim_channel_registry( sc_simcontext& simc_ )
+ : m_async_update_list_p(0)
+ , m_construction_done(0)
+ , m_prim_channel_vec()
+ , m_simc( &simc_ )
+ , m_update_list_p((sc_prim_channel*)sc_prim_channel::list_end)
+{
+# ifndef SC_DISABLE_ASYNC_UPDATES
+ m_async_update_list_p = new async_update_list();
+# endif
+}
+
+
+// destructor
+
+sc_prim_channel_registry::~sc_prim_channel_registry()
+{
+ delete m_async_update_list_p;
+}
+
+// called when construction is done
+
+bool
+sc_prim_channel_registry::construction_done()
+{
+ if( size() == m_construction_done )
+ // nothing has been updated
+ return true;
+
+ for( ; m_construction_done < size(); ++m_construction_done ) {
+ m_prim_channel_vec[m_construction_done]->construction_done();
+ }
+
+ return false;
+}
+
+
+// called when elaboration is done
+
+void
+sc_prim_channel_registry::elaboration_done()
+{
+ for( int i = 0; i < size(); ++ i ) {
+ m_prim_channel_vec[i]->elaboration_done();
+ }
+}
+
+// called before simulation begins
+
+void
+sc_prim_channel_registry::start_simulation()
+{
+ for( int i = 0; i < size(); ++ i ) {
+ m_prim_channel_vec[i]->start_simulation();
+ }
+}
+
+// called after simulation ends
+
+void
+sc_prim_channel_registry::simulation_done()
+{
+ for( int i = 0; i < size(); ++ i ) {
+ m_prim_channel_vec[i]->simulation_done();
+ }
+}
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Andy Goodrich, Forte,
+ Bishnupriya Bhattacharya, Cadence Design Systems,
+ 25 August, 2003
+
+ Description of Modification: phase callbacks
+
+ *****************************************************************************/
+
+
+// $Log: sc_prim_channel.cpp,v $
+// Revision 1.11 2011/08/26 21:38:32 acg
+// Philipp A. Hartmann: removed unused switch m_construction_done.
+//
+// Revision 1.10 2011/08/26 20:45:41 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.9 2011/08/24 22:05:36 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.8 2011/05/09 04:07:37 acg
+// Philipp A. Hartmann:
+// (1) Restore hierarchy in all phase callbacks.
+// (2) Ensure calls to before_end_of_elaboration.
+//
+// Revision 1.7 2011/04/19 02:36:26 acg
+// Philipp A. Hartmann: new aysnc_update and mutex support.
+//
+// Revision 1.6 2011/02/18 20:31:05 acg
+// Philipp A. Hartmann: added error messages for calls that cannot be done
+// after elaboration.
+//
+// Revision 1.5 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+// Revision 1.4 2011/02/14 17:50:16 acg
+// Andy Goodrich: testing for sc_port and sc_export instantiations during
+// end of elaboration and issuing appropriate error messages.
+//
+// Revision 1.3 2010/12/07 20:36:49 acg
+// Andy Goodrich: fix pointer that should have been initialized to zero.
+//
+// Revision 1.2 2010/12/07 19:50:36 acg
+// Andy Goodrich: addition of writer policies, courtesy of Philipp Hartmann.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.4 2006/01/26 21:00:50 acg
+// Andy Goodrich: conversion to use sc_event::notify(SC_ZERO_TIME) instead of
+// sc_event::notify_delayed()
+//
+// Revision 1.3 2006/01/13 18:47:42 acg
+// Added $Log command so that CVS comments are reproduced in the source.
+//
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_prim_channel.h b/ext/systemc/src/sysc/communication/sc_prim_channel.h
new file mode 100644
index 000000000..4a52fe7cb
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_prim_channel.h
@@ -0,0 +1,420 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_prim_channel.h -- Abstract base class of all primitive channel classes.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_PRIM_CHANNEL_H
+#define SC_PRIM_CHANNEL_H
+
+#include "sysc/kernel/sc_object.h"
+#include "sysc/kernel/sc_wait.h"
+#include "sysc/kernel/sc_wait_cthread.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_prim_channel
+//
+// Abstract base class of all primitive channel classes.
+// ----------------------------------------------------------------------------
+
+class sc_prim_channel
+: public sc_object
+{
+ friend class sc_prim_channel_registry;
+
+public:
+ enum { list_end = 0xdb };
+public:
+ virtual const char* kind() const
+ { return "sc_prim_channel"; }
+
+ inline bool update_requested()
+ { return m_update_next_p != (sc_prim_channel*)list_end; }
+
+ // request the update method to be executed during the update phase
+ inline void request_update();
+
+ // request the update method to be executed during the update phase
+ // from a process external to the simulator.
+ void async_request_update();
+
+protected:
+
+ // constructors
+ sc_prim_channel();
+ explicit sc_prim_channel( const char* );
+
+ // destructor
+ virtual ~sc_prim_channel();
+
+ // the update method (does nothing by default)
+ virtual void update();
+
+ // called by construction_done (does nothing by default)
+ virtual void before_end_of_elaboration();
+
+ // called by elaboration_done (does nothing by default)
+ virtual void end_of_elaboration();
+
+ // called by start_simulation (does nothing by default)
+ virtual void start_of_simulation();
+
+ // called by simulation_done (does nothing by default)
+ virtual void end_of_simulation();
+
+protected:
+
+ // to avoid calling sc_get_curr_simcontext()
+
+ // static sensitivity for SC_THREADs and SC_CTHREADs
+
+ void wait()
+ { sc_core::wait( simcontext() ); }
+
+
+ // dynamic sensitivity for SC_THREADs and SC_CTHREADs
+
+ void wait( const sc_event& e )
+ { sc_core::wait( e, simcontext() ); }
+
+ void wait( const sc_event_or_list& el )
+ { sc_core::wait( el, simcontext() ); }
+
+ void wait( const sc_event_and_list& el )
+ { sc_core::wait( el, simcontext() ); }
+
+ void wait( const sc_time& t )
+ { sc_core::wait( t, simcontext() ); }
+
+ void wait( double v, sc_time_unit tu )
+ { sc_core::wait( sc_time( v, tu, simcontext() ), simcontext() ); }
+
+ void wait( const sc_time& t, const sc_event& e )
+ { sc_core::wait( t, e, simcontext() ); }
+
+ void wait( double v, sc_time_unit tu, const sc_event& e )
+ { sc_core::wait( sc_time( v, tu, simcontext() ), e, simcontext() ); }
+
+ void wait( const sc_time& t, const sc_event_or_list& el )
+ { sc_core::wait( t, el, simcontext() ); }
+
+ void wait( double v, sc_time_unit tu, const sc_event_or_list& el )
+ { sc_core::wait( sc_time( v, tu, simcontext() ), el, simcontext() ); }
+
+ void wait( const sc_time& t, const sc_event_and_list& el )
+ { sc_core::wait( t, el, simcontext() ); }
+
+ void wait( double v, sc_time_unit tu, const sc_event_and_list& el )
+ { sc_core::wait( sc_time( v, tu, simcontext() ), el, simcontext() ); }
+
+ void wait( int n )
+ { sc_core::wait( n, simcontext() ); }
+
+
+ // static sensitivity for SC_METHODs
+
+ void next_trigger()
+ { sc_core::next_trigger( simcontext() ); }
+
+
+ // dynamic sensitivity for SC_METHODs
+
+ void next_trigger( const sc_event& e )
+ { sc_core::next_trigger( e, simcontext() ); }
+
+ void next_trigger( const sc_event_or_list& el )
+ { sc_core::next_trigger( el, simcontext() ); }
+
+ void next_trigger( const sc_event_and_list& el )
+ { sc_core::next_trigger( el, simcontext() ); }
+
+ void next_trigger( const sc_time& t )
+ { sc_core::next_trigger( t, simcontext() ); }
+
+ void next_trigger( double v, sc_time_unit tu )
+ {sc_core::next_trigger( sc_time( v, tu, simcontext() ), simcontext() );}
+
+ void next_trigger( const sc_time& t, const sc_event& e )
+ { sc_core::next_trigger( t, e, simcontext() ); }
+
+ void next_trigger( double v, sc_time_unit tu, const sc_event& e )
+ { sc_core::next_trigger(
+ sc_time( v, tu, simcontext() ), e, simcontext() ); }
+
+ void next_trigger( const sc_time& t, const sc_event_or_list& el )
+ { sc_core::next_trigger( t, el, simcontext() ); }
+
+ void next_trigger( double v, sc_time_unit tu, const sc_event_or_list& el )
+ { sc_core::next_trigger(
+ sc_time( v, tu, simcontext() ), el, simcontext() ); }
+
+ void next_trigger( const sc_time& t, const sc_event_and_list& el )
+ { sc_core::next_trigger( t, el, simcontext() ); }
+
+ void next_trigger( double v, sc_time_unit tu, const sc_event_and_list& el )
+ { sc_core::next_trigger(
+ sc_time( v, tu, simcontext() ), el, simcontext() ); }
+
+
+ // for SC_METHODs and SC_THREADs and SC_CTHREADs
+
+ bool timed_out()
+ { return sc_core::timed_out( simcontext() ); }
+
+
+#if 0 // @@@@####
+ // delta count maintenance
+ sc_dt::uint64 delta_count()
+ { return simcontext()->m_delta_count; }
+#endif
+
+private:
+
+ // called during the update phase of a delta cycle (if requested)
+ void perform_update();
+
+ // called when construction is done
+ void construction_done();
+
+ // called when elaboration is done
+ void elaboration_done();
+
+ // called before simulation starts
+ void start_simulation();
+
+ // called after simulation ends
+ void simulation_done();
+
+ // disabled
+ sc_prim_channel( const sc_prim_channel& );
+ sc_prim_channel& operator = ( const sc_prim_channel& );
+
+private:
+
+ sc_prim_channel_registry* m_registry; // Update list manager.
+ sc_prim_channel* m_update_next_p; // Next entry in update list.
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_prim_channel_registry
+//
+// Registry for all primitive channels.
+// FOR INTERNAL USE ONLY!
+// ----------------------------------------------------------------------------
+
+class sc_prim_channel_registry
+{
+ friend class sc_simcontext;
+
+public:
+
+ void insert( sc_prim_channel& );
+ void remove( sc_prim_channel& );
+
+
+ int size() const
+ { return m_prim_channel_vec.size(); }
+
+ inline void request_update( sc_prim_channel& );
+ void async_request_update( sc_prim_channel& );
+
+ bool pending_updates() const
+ {
+ return m_update_list_p != (sc_prim_channel*)sc_prim_channel::list_end
+ || pending_async_updates();
+ }
+
+ bool pending_async_updates() const;
+
+private:
+
+ // constructor
+ explicit sc_prim_channel_registry( sc_simcontext& simc_ );
+
+ // destructor
+ ~sc_prim_channel_registry();
+
+ // called during the update phase of a delta cycle
+ void perform_update();
+
+ // called when construction is done
+ bool construction_done();
+
+ // called when elaboration is done
+ void elaboration_done();
+
+ // called before simulation starts
+ void start_simulation();
+
+ // called after simulation ends
+ void simulation_done();
+
+ // disabled
+ sc_prim_channel_registry();
+ sc_prim_channel_registry( const sc_prim_channel_registry& );
+ sc_prim_channel_registry& operator = ( const sc_prim_channel_registry& );
+
+private:
+ class async_update_list;
+
+ async_update_list* m_async_update_list_p; // external updates.
+ int m_construction_done; // # of constructs.
+ std::vector<sc_prim_channel*> m_prim_channel_vec; // existing channels.
+ sc_simcontext* m_simc; // simulator context.
+ sc_prim_channel* m_update_list_p; // internal updates.
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_prim_channel_registry
+//
+// Registry for all primitive channels.
+// FOR INTERNAL USE ONLY!
+// ----------------------------------------------------------------------------
+
+inline
+void
+sc_prim_channel_registry::request_update( sc_prim_channel& prim_channel_ )
+{
+ prim_channel_.m_update_next_p = m_update_list_p;
+ m_update_list_p = &prim_channel_;
+}
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_prim_channel
+//
+// Abstract base class of all primitive channel classes.
+// ----------------------------------------------------------------------------
+
+// request the update method (to be executed during the update phase)
+
+inline
+void
+sc_prim_channel::request_update()
+{
+ if( ! m_update_next_p ) {
+ m_registry->request_update( *this );
+ }
+}
+
+// request the update method from external to the simulator (to be executed
+// during the update phase)
+
+inline
+void
+sc_prim_channel::async_request_update()
+{
+ m_registry->async_request_update(*this);
+}
+
+
+// called during the update phase of a delta cycle (if requested)
+
+inline
+void
+sc_prim_channel::perform_update()
+{
+ update();
+ m_update_next_p = 0;
+}
+
+
+} // namespace sc_core
+
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Andy Goodrich, Forte,
+ Bishnupriya Bhattacharya, Cadence Design Systems,
+ 25 August, 2003
+ Description of Modification: phase callbacks
+
+ *****************************************************************************/
+//$Log: sc_prim_channel.h,v $
+//Revision 1.10 2011/08/26 21:38:32 acg
+// Philipp A. Hartmann: removed unused switch m_construction_done.
+//
+//Revision 1.9 2011/08/07 19:08:01 acg
+// Andy Goodrich: moved logs to end of file so line number synching works
+// better between versions.
+//
+//Revision 1.8 2011/05/09 04:07:37 acg
+// Philipp A. Hartmann:
+// (1) Restore hierarchy in all phase callbacks.
+// (2) Ensure calls to before_end_of_elaboration.
+//
+//Revision 1.7 2011/05/05 17:44:01 acg
+// Philip A. Hartmann: change in the name of pending_async_updates.
+//
+//Revision 1.6 2011/04/19 15:03:48 acg
+// Philipp A. Hartmann: remove ASYNC_UPDATE preprocessor check from header.
+//
+//Revision 1.5 2011/04/19 02:36:26 acg
+// Philipp A. Hartmann: new aysnc_update and mutex support.
+//
+//Revision 1.4 2011/04/05 20:48:09 acg
+// Andy Goodrich: changes to make sure that event(), posedge() and negedge()
+// only return true if the clock has not moved.
+//
+//Revision 1.3 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+//Revision 1.2 2011/01/20 16:52:15 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+//Revision 1.1.1.1 2006/12/15 20:20:04 acg
+//SystemC 2.3
+//
+//Revision 1.3 2006/05/08 17:52:47 acg
+// Andy Goodrich:
+// (1) added David Long's forward declarations for friend functions,
+// methods, and operators to keep the Microsoft compiler happy.
+// (2) Added delta_count() method to sc_prim_channel for use by
+// sc_signal so that the friend declaration in sc_simcontext.h
+// can be for a non-templated class (i.e., sc_prim_channel.)
+//
+//Revision 1.2 2006/01/03 23:18:26 acg
+//Changed copyright to include 2006.
+//
+//Revision 1.1.1.1 2005/12/19 23:16:43 acg
+//First check in of SystemC 2.1 into its own archive.
+//
+//Revision 1.10 2005/07/30 03:44:11 acg
+//Changes from 2.1.
+//
+//Revision 1.9 2005/06/10 22:43:55 acg
+//Added CVS change log annotation.
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_semaphore.cpp b/ext/systemc/src/sysc/communication/sc_semaphore.cpp
new file mode 100644
index 000000000..d90424431
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_semaphore.cpp
@@ -0,0 +1,148 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_semaphore.cpp -- The sc_semaphore primitive channel class.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include "sysc/communication/sc_communication_ids.h"
+#include "sysc/communication/sc_semaphore.h"
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_wait.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_semaphore
+//
+// The sc_semaphore primitive channel class.
+// ----------------------------------------------------------------------------
+
+// error reporting
+
+void
+sc_semaphore::report_error( const char* id, const char* add_msg ) const
+{
+ char msg[BUFSIZ];
+ if( add_msg != 0 ) {
+ std::sprintf( msg, "%s: semaphore '%s'", add_msg, name() );
+ } else {
+ std::sprintf( msg, "semaphore '%s'", name() );
+ }
+ SC_REPORT_ERROR( id, msg );
+}
+
+
+// constructors
+
+sc_semaphore::sc_semaphore( int init_value_ )
+: sc_object( sc_gen_unique_name( "semaphore" ) ),
+ m_free( (std::string(SC_KERNEL_EVENT_PREFIX)+"_free_event").c_str() ),
+ m_value( init_value_ )
+{
+ if( m_value < 0 ) {
+ report_error( SC_ID_INVALID_SEMAPHORE_VALUE_ );
+ }
+}
+
+sc_semaphore::sc_semaphore( const char* name_, int init_value_ )
+: sc_object( name_ ),
+ m_free( (std::string(SC_KERNEL_EVENT_PREFIX)+"_free_event").c_str() ),
+ m_value( init_value_ )
+{
+ if( m_value < 0 ) {
+ report_error( SC_ID_INVALID_SEMAPHORE_VALUE_ );
+ }
+}
+
+
+// interface methods
+
+// lock (take) the semaphore, block if not available
+
+int
+sc_semaphore::wait()
+{
+ while( in_use() ) {
+ sc_core::wait( m_free, sc_get_curr_simcontext() );
+ }
+ -- m_value;
+ return 0;
+}
+
+
+// lock (take) the semaphore, return -1 if not available
+
+int
+sc_semaphore::trywait()
+{
+ if( in_use() ) {
+ return -1;
+ }
+ -- m_value;
+ return 0;
+}
+
+
+// unlock (give) the semaphore
+
+int
+sc_semaphore::post()
+{
+ ++m_value;
+ m_free.notify();
+ return 0;
+}
+
+} // namespace sc_core
+
+// $Log: sc_semaphore.cpp,v $
+// Revision 1.5 2011/08/26 20:45:42 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.4 2011/03/23 16:17:22 acg
+// Andy Goodrich: hide the sc_events that are kernel related.
+//
+// Revision 1.3 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+// Revision 1.2 2010/11/02 16:31:01 acg
+// Andy Goodrich: changed object derivation to use sc_object rather than
+// sc_prim_channel as the parent class.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.6 2006/11/28 20:30:49 acg
+// Andy Goodrich: updated from 2.2 source. sc_event_queue constructors
+// collapsed into a single constructor with an optional argument to get
+// the sc_module_name stack done correctly. Class name prefixing added
+// to sc_semaphore calls to wait() to keep gcc 4.x happy.
+//
+// Revision 1.3 2006/01/13 18:47:42 acg
+// Added $Log command so that CVS comments are reproduced in the source.
+//
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_semaphore.h b/ext/systemc/src/sysc/communication/sc_semaphore.h
new file mode 100644
index 000000000..3ce991ebf
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_semaphore.h
@@ -0,0 +1,133 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_semaphore.h -- The sc_semaphore primitive channel class.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_SEMAPHORE_H
+#define SC_SEMAPHORE_H
+
+
+#include "sysc/kernel/sc_event.h"
+#include "sysc/kernel/sc_object.h"
+#include "sysc/communication/sc_semaphore_if.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_semaphore
+//
+// The sc_semaphore primitive channel class.
+// ----------------------------------------------------------------------------
+
+class sc_semaphore
+: public sc_semaphore_if,
+ public sc_object
+{
+public:
+
+ // constructors
+
+ explicit sc_semaphore( int init_value_ );
+ sc_semaphore( const char* name_, int init_value_ );
+
+
+ // interface methods
+
+ // lock (take) the semaphore, block if not available
+ virtual int wait();
+
+ // lock (take) the semaphore, return -1 if not available
+ virtual int trywait();
+
+ // unlock (give) the semaphore
+ virtual int post();
+
+ // get the value of the semaphore
+ virtual int get_value() const
+ { return m_value; }
+
+ virtual const char* kind() const
+ { return "sc_semaphore"; }
+
+protected:
+
+ // support methods
+
+ bool in_use() const
+ { return ( m_value <= 0 ); }
+
+
+ // error reporting
+ void report_error( const char* id, const char* add_msg = 0 ) const;
+
+protected:
+
+ sc_event m_free; // event to block on when m_value is negative
+ int m_value; // current value of the semaphore
+
+private:
+
+ // disabled
+ sc_semaphore( const sc_semaphore& );
+ sc_semaphore& operator = ( const sc_semaphore& );
+};
+
+} // namespace sc_core
+
+//$Log: sc_semaphore.h,v $
+//Revision 1.4 2011/08/26 20:45:42 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+//Revision 1.3 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+//Revision 1.2 2010/11/02 16:31:01 acg
+// Andy Goodrich: changed object derivation to use sc_object rather than
+// sc_prim_channel as the parent class.
+//
+//Revision 1.1.1.1 2006/12/15 20:20:04 acg
+//SystemC 2.3
+//
+//Revision 1.4 2006/11/28 20:30:49 acg
+// Andy Goodrich: updated from 2.2 source. sc_event_queue constructors
+// collapsed into a single constructor with an optional argument to get
+// the sc_module_name stack done correctly. Class name prefixing added
+// to sc_semaphore calls to wait() to keep gcc 4.x happy.
+//
+//Revision 1.2 2006/01/03 23:18:26 acg
+//Changed copyright to include 2006.
+//
+//Revision 1.1.1.1 2005/12/19 23:16:43 acg
+//First check in of SystemC 2.1 into its own archive.
+//
+//Revision 1.9 2005/06/10 22:43:55 acg
+//Added CVS change log annotation.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_semaphore_if.h b/ext/systemc/src/sysc/communication/sc_semaphore_if.h
new file mode 100644
index 000000000..b0839e40a
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_semaphore_if.h
@@ -0,0 +1,100 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_semaphore_if.h -- The sc_semaphore_if interface class.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_SEMAPHORE_IF_H
+#define SC_SEMAPHORE_IF_H
+
+#include "sysc/communication/sc_interface.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_semaphore_if
+//
+// The sc_semaphore_if interface class.
+// ----------------------------------------------------------------------------
+
+class sc_semaphore_if
+: virtual public sc_interface
+{
+public:
+
+ // the classical operations: wait(), trywait(), and post()
+
+ // lock (take) the semaphore, block if not available
+ virtual int wait() = 0;
+
+ // lock (take) the semaphore, return -1 if not available
+ virtual int trywait() = 0;
+
+ // unlock (give) the semaphore
+ virtual int post() = 0;
+
+ // get the value of the semphore
+ virtual int get_value() const = 0;
+
+protected:
+
+ // constructor
+
+ sc_semaphore_if()
+ {}
+
+private:
+
+ // disabled
+ sc_semaphore_if( const sc_semaphore_if& );
+ sc_semaphore_if& operator = ( const sc_semaphore_if& );
+};
+
+} // namespace sc_core
+
+//$Log: sc_semaphore_if.h,v $
+//Revision 1.3 2011/08/26 20:45:42 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+//Revision 1.2 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+//Revision 1.1.1.1 2006/12/15 20:20:04 acg
+//SystemC 2.3
+//
+//Revision 1.2 2006/01/03 23:18:26 acg
+//Changed copyright to include 2006.
+//
+//Revision 1.1.1.1 2005/12/19 23:16:43 acg
+//First check in of SystemC 2.1 into its own archive.
+//
+//Revision 1.8 2005/06/10 22:43:55 acg
+//Added CVS change log annotation.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_signal.cpp b/ext/systemc/src/sysc/communication/sc_signal.cpp
new file mode 100644
index 000000000..3b2df8a7c
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_signal.cpp
@@ -0,0 +1,456 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_signal.cpp -- The sc_signal<T> primitive channel class.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#include "sysc/communication/sc_communication_ids.h"
+#include "sysc/utils/sc_utils_ids.h"
+#include "sysc/communication/sc_signal.h"
+#include "sysc/datatypes/int/sc_signed.h"
+#include "sysc/datatypes/int/sc_unsigned.h"
+#include "sysc/datatypes/bit/sc_lv_base.h"
+#include "sysc/kernel/sc_reset.h"
+
+#include <sstream>
+
+using sc_dt::sc_lv_base;
+using sc_dt::sc_signed;
+using sc_dt::sc_unsigned;
+using sc_dt::int64;
+using sc_dt::uint64;
+
+namespace sc_core {
+
+// to avoid code bloat in sc_signal<T>
+
+void
+sc_signal_invalid_writer( sc_object* target, sc_object* first_writer,
+ sc_object* second_writer, bool check_delta )
+{
+ if ( second_writer )
+ {
+ std::stringstream msg;
+
+ msg
+ << "\n signal "
+ "`" << target->name() << "' "
+ "(" << target->kind() << ")"
+ << "\n first driver "
+ "`" << first_writer->name() << "' "
+ " (" << first_writer->kind() << ")"
+ << "\n second driver "
+ "`" << second_writer->name() << "' "
+ "(" << second_writer->kind() << ")";
+
+ if( check_delta )
+ {
+ msg << "\n first conflicting write in delta cycle "
+ << sc_delta_count();
+ }
+ SC_REPORT_ERROR( SC_ID_MORE_THAN_ONE_SIGNAL_DRIVER_,
+ msg.str().c_str() );
+ }
+}
+
+bool
+sc_writer_policy_check_port::
+ check_port( sc_object* target, sc_port_base * port_, bool is_output )
+{
+ if ( is_output && sc_get_curr_simcontext()->write_check() )
+ {
+ // an out or inout port; only one can be connected
+ if( m_output != 0) {
+ sc_signal_invalid_writer( target, m_output, port_, false );
+ return false;
+ } else {
+ m_output = port_;
+ }
+ }
+ return true;
+}
+
+void sc_deprecated_get_data_ref()
+{
+ static bool warn_get_data_ref_deprecated=true;
+ if ( warn_get_data_ref_deprecated )
+ {
+ warn_get_data_ref_deprecated=false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "get_data_ref() is deprecated, use read() instead" );
+ }
+}
+
+void sc_deprecated_get_new_value()
+{
+ static bool warn_new_value=true;
+ if ( warn_new_value )
+ {
+ warn_new_value=false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "sc_signal<T>::get_new_value() is deprecated");
+ }
+}
+
+void sc_deprecated_trace()
+{
+ static bool warn_trace_deprecated=true;
+ if ( warn_trace_deprecated )
+ {
+ warn_trace_deprecated=false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "sc_signal<T>::trace() is deprecated");
+ }
+}
+
+sc_event*
+sc_lazy_kernel_event( sc_event** ev, const char* name )
+{
+ if ( !*ev ) {
+ std::string kernel_name = SC_KERNEL_EVENT_PREFIX "_";
+ kernel_name.append( name );
+ *ev = new sc_event( kernel_name.c_str() );
+ }
+ return *ev;
+
+}
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+template< sc_writer_policy POL >
+void
+sc_signal<bool,POL>::register_port( sc_port_base& port_,
+ const char* if_typename_ )
+{
+ bool is_output = std::string( if_typename_ ) == typeid(if_type).name();
+ if( !policy_type::check_port( this, &port_, is_output ) )
+ ((void)0); // fallback? error has been suppressed ...
+}
+
+
+// write the new value
+
+template< sc_writer_policy POL >
+void
+sc_signal<bool,POL>::write( const bool& value_ )
+{
+ bool value_changed = !( m_cur_val == value_ );
+ if ( !policy_type::check_write(this, value_changed) )
+ return;
+ m_new_val = value_;
+ if( value_changed ) {
+ request_update();
+ }
+}
+
+template< sc_writer_policy POL >
+inline
+void
+sc_signal<bool,POL>::print( ::std::ostream& os ) const
+{
+ os << m_cur_val;
+}
+
+template< sc_writer_policy POL >
+void
+sc_signal<bool,POL>::dump( ::std::ostream& os ) const
+{
+ os << " name = " << name() << ::std::endl;
+ os << " value = " << m_cur_val << ::std::endl;
+ os << "new value = " << m_new_val << ::std::endl;
+}
+
+
+template< sc_writer_policy POL >
+void
+sc_signal<bool,POL>::update()
+{
+ policy_type::update();
+ if( !( m_new_val == m_cur_val ) ) {
+ do_update();
+ }
+}
+
+template< sc_writer_policy POL >
+void
+sc_signal<bool,POL>::do_update()
+{
+ // order of execution below is important, the notify_processes() call
+ // must come after the update of m_cur_val for things to work properly!
+
+ m_cur_val = m_new_val;
+
+ if ( m_reset_p ) m_reset_p->notify_processes();
+
+ if ( m_change_event_p ) m_change_event_p->notify_next_delta();
+
+ sc_event* event_p = this->m_cur_val
+ ? m_posedge_event_p : m_negedge_event_p;
+ if ( event_p ) event_p->notify_next_delta();
+
+ m_change_stamp = simcontext()->change_stamp();
+}
+
+// (edge) event methods
+
+template< sc_writer_policy POL >
+const sc_event&
+sc_signal<bool,POL>::value_changed_event() const
+{
+ return *sc_lazy_kernel_event(&m_change_event_p,"value_changed_event");
+}
+
+template< sc_writer_policy POL >
+const sc_event&
+sc_signal<bool,POL>::posedge_event() const
+{
+ return *sc_lazy_kernel_event(&m_posedge_event_p,"posedge_event");
+}
+
+template< sc_writer_policy POL >
+const sc_event&
+sc_signal<bool,POL>::negedge_event() const
+{
+ return *sc_lazy_kernel_event(&m_negedge_event_p,"negedge_event");
+}
+
+
+// reset support:
+
+template< sc_writer_policy POL >
+sc_reset*
+sc_signal<bool,POL>::is_reset() const
+{
+ sc_reset* result_p;
+ if ( !m_reset_p ) m_reset_p = new sc_reset( this );
+ result_p = m_reset_p;
+ return result_p;
+}
+
+// destructor
+
+template< sc_writer_policy POL >
+sc_signal<bool,POL>::~sc_signal()
+{
+ delete m_change_event_p;
+ delete m_negedge_event_p;
+ delete m_posedge_event_p;
+ delete m_reset_p;
+}
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+template< sc_writer_policy POL >
+void
+sc_signal<sc_dt::sc_logic,POL>::register_port( sc_port_base& port_,
+ const char* if_typename_ )
+{
+ bool is_output = std::string( if_typename_ ) == typeid(if_type).name();
+ if( !policy_type::check_port( this, &port_, is_output ) )
+ ((void)0); // fallback? error has been suppressed ...
+}
+
+
+// write the new value
+
+template< sc_writer_policy POL >
+inline
+void
+sc_signal<sc_dt::sc_logic,POL>::write( const sc_dt::sc_logic& value_ )
+{
+ bool value_changed = !( m_cur_val == value_ );
+ if ( !policy_type::check_write(this, value_changed) )
+ return;
+
+ m_new_val = value_;
+ if( value_changed ) {
+ request_update();
+ }
+}
+
+template< sc_writer_policy POL >
+inline
+void
+sc_signal<sc_dt::sc_logic,POL>::print( ::std::ostream& os ) const
+{
+ os << m_cur_val;
+}
+
+template< sc_writer_policy POL >
+void
+sc_signal<sc_dt::sc_logic,POL>::dump( ::std::ostream& os ) const
+{
+ os << " name = " << name() << ::std::endl;
+ os << " value = " << m_cur_val << ::std::endl;
+ os << "new value = " << m_new_val << ::std::endl;
+}
+
+
+template< sc_writer_policy POL >
+void
+sc_signal<sc_dt::sc_logic,POL>::update()
+{
+ policy_type::update();
+ if( !( m_new_val == m_cur_val ) ) {
+ do_update();
+ }
+}
+
+template< sc_writer_policy POL >
+void
+sc_signal<sc_dt::sc_logic,POL>::do_update()
+{
+ m_cur_val = m_new_val;
+
+ if ( m_change_event_p ) m_change_event_p->notify_next_delta();
+
+ if( m_posedge_event_p && (this->m_cur_val == sc_dt::SC_LOGIC_1) ) {
+ m_posedge_event_p->notify_next_delta();
+ }
+ else if( m_negedge_event_p && (this->m_cur_val == sc_dt::SC_LOGIC_0) ) {
+ m_negedge_event_p->notify_next_delta();
+ }
+
+ m_change_stamp = simcontext()->change_stamp();
+}
+
+// (edge) event methods
+
+template< sc_writer_policy POL >
+const sc_event&
+sc_signal<sc_dt::sc_logic,POL>::value_changed_event() const
+{
+ return *sc_lazy_kernel_event(&m_change_event_p,"value_changed_event");
+}
+
+template< sc_writer_policy POL >
+const sc_event&
+sc_signal<sc_dt::sc_logic,POL>::posedge_event() const
+{
+ return *sc_lazy_kernel_event(&m_posedge_event_p,"posedge_event");
+}
+
+template< sc_writer_policy POL >
+const sc_event&
+sc_signal<sc_dt::sc_logic,POL>::negedge_event() const
+{
+ return *sc_lazy_kernel_event(&m_negedge_event_p,"negedge_event");
+}
+
+
+// template instantiations for writer policies
+
+template class sc_signal<bool,SC_ONE_WRITER>;
+template class sc_signal<bool,SC_MANY_WRITERS>;
+template class sc_signal<bool,SC_UNCHECKED_WRITERS>;
+
+template class sc_signal<sc_dt::sc_logic,SC_ONE_WRITER>;
+template class sc_signal<sc_dt::sc_logic,SC_MANY_WRITERS>;
+template class sc_signal<sc_dt::sc_logic,SC_UNCHECKED_WRITERS>;
+
+} // namespace sc_core
+
+/*
+$Log: sc_signal.cpp,v $
+Revision 1.9 2011/08/26 20:45:42 acg
+ Andy Goodrich: moved the modification log to the end of the file to
+ eliminate source line number skew when check-ins are done.
+
+Revision 1.8 2011/02/18 20:23:45 acg
+ Andy Goodrich: Copyright update.
+
+Revision 1.7 2011/02/18 20:08:14 acg
+ Philipp A. Hartmann: addition of include for sstream for MSVC.
+
+Revision 1.6 2011/01/25 20:50:37 acg
+ Andy Goodrich: changes for IEEE 1666 2011.
+
+Revision 1.5 2010/12/07 19:50:36 acg
+ Andy Goodrich: addition of writer policies, courtesy of Philipp Hartmann.
+
+Revision 1.3 2007/04/09 21:59:49 acg
+ Andy Goodrich: fixed multiple write notification bug where writes
+ done outside the simulator were being treated as multiple writes.
+
+Revision 1.2 2007/04/02 17:24:01 acg
+ Andy Goodrich: added check for null writer pointers in sc_signal invalid
+ writer method.
+
+Revision 1.1.1.1 2006/12/15 20:20:04 acg
+SystemC 2.3
+
+Revision 1.7 2006/04/11 23:11:57 acg
+ Andy Goodrich: Changes for reset support that only includes
+ sc_cthread_process instances.
+
+Revision 1.6 2006/03/13 20:19:44 acg
+ Andy Goodrich: changed sc_event instances into pointers to sc_event instances
+ that are allocated as needed. This saves considerable storage for large
+ numbers of signals, etc.
+
+Revision 1.5 2006/01/25 00:31:11 acg
+ Andy Goodrich: Changed over to use a standard message id of
+ SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
+
+Revision 1.4 2006/01/24 20:46:32 acg
+Andy Goodrich: changes to eliminate use of deprecated features. For instance,
+using notify(SC_ZERO_TIME) in place of notify_delayed().
+
+Revision 1.3 2006/01/18 21:42:26 acg
+Andy Goodrich: Changes for check writer support, and tightening up sc_clock
+port usage.
+
+Revision 1.2 2006/01/03 23:18:26 acg
+Changed copyright to include 2006.
+
+Revision 1.1.1.1 2005/12/19 23:16:43 acg
+First check in of SystemC 2.1 into its own archive.
+
+Revision 1.14 2005/09/15 23:01:51 acg
+Added std:: prefix to appropriate methods and types to get around
+issues with the Edison Front End.
+
+Revision 1.13 2005/05/08 19:04:06 acg
+Fix bug in concat_set(int64,off). Other changes from 2.1 examples usage.
+
+Revision 1.12 2005/04/04 00:15:51 acg
+Changes for directory name change to sys from systemc.
+Changes for sc_string going to std::string.
+Changes for sc_pvector going to std::vector.
+Changes for reference pools for bit and part selections.
+Changes for const sc_concatref support.
+
+Revision 1.10 2005/03/21 22:31:32 acg
+Changes to sc_core namespace.
+
+Revision 1.9 2004/09/27 21:02:54 acg
+Andy Goodrich - Forte Design Systems, Inc.
+ - Added a $Log comment so that CVS checkin comments will appear in
+ checked out source.
+
+*/
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_signal.h b/ext/systemc/src/sysc/communication/sc_signal.h
new file mode 100644
index 000000000..2a72ef55e
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_signal.h
@@ -0,0 +1,741 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_signal.h -- The sc_signal<T> primitive channel class.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_SIGNAL_H
+#define SC_SIGNAL_H
+
+#include "sysc/communication/sc_port.h"
+#include "sysc/communication/sc_prim_channel.h"
+#include "sysc/communication/sc_signal_ifs.h"
+#include "sysc/communication/sc_writer_policy.h"
+#include "sysc/kernel/sc_event.h"
+#include "sysc/kernel/sc_process.h"
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/datatypes/bit/sc_logic.h"
+#include "sysc/tracing/sc_trace.h"
+#include <typeinfo>
+
+namespace sc_core {
+
+// to avoid code bloat in sc_signal<T>
+
+extern void sc_deprecated_get_data_ref();
+extern void sc_deprecated_get_new_value();
+extern void sc_deprecated_trace();
+extern sc_event * sc_lazy_kernel_event( sc_event**, const char* name );
+
+inline
+bool
+sc_writer_policy_check_write::check_write( sc_object* target, bool )
+{
+ sc_object* writer_p = sc_get_curr_simcontext()->get_current_writer();
+ if( SC_UNLIKELY_(m_writer_p == 0) ) {
+ m_writer_p = writer_p;
+ } else if( SC_UNLIKELY_(m_writer_p != writer_p && writer_p != 0) ) {
+ sc_signal_invalid_writer( target, m_writer_p, writer_p, m_check_delta );
+ // error has been suppressed, ignore check as well
+ // return false;
+ }
+ return true;
+}
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_signal<T>
+//
+// The sc_signal<T> primitive channel class.
+// ----------------------------------------------------------------------------
+
+template< class T, sc_writer_policy POL /* = SC_DEFAULT_WRITER_POLICY */ >
+class sc_signal
+ : public sc_signal_inout_if<T>
+ , public sc_prim_channel
+ , protected sc_writer_policy_check<POL>
+{
+protected:
+ typedef sc_signal_inout_if<T> if_type;
+ typedef sc_signal<T,POL> this_type;
+ typedef sc_writer_policy_check<POL> policy_type;
+
+public: // constructors and destructor:
+
+ sc_signal()
+ : sc_prim_channel( sc_gen_unique_name( "signal" ) ),
+ m_change_event_p( 0 ), m_cur_val( T() ),
+ m_change_stamp( ~sc_dt::UINT64_ONE ), m_new_val( T() )
+ {}
+
+ explicit sc_signal( const char* name_)
+ : sc_prim_channel( name_ ),
+ m_change_event_p( 0 ), m_cur_val( T() ),
+ m_change_stamp( ~sc_dt::UINT64_ONE ), m_new_val( T() )
+ {}
+
+ sc_signal( const char* name_, const T& initial_value_ )
+ : sc_prim_channel( name_ )
+ , m_change_event_p( 0 )
+ , m_cur_val( initial_value_ )
+ , m_change_stamp( ~sc_dt::UINT64_ONE )
+ , m_new_val( initial_value_ )
+ {}
+
+ virtual ~sc_signal()
+ {
+ delete m_change_event_p;
+ }
+
+
+ // interface methods
+
+ virtual void register_port( sc_port_base&, const char* );
+
+ virtual sc_writer_policy get_writer_policy() const
+ { return POL; }
+
+ // get the default event
+ virtual const sc_event& default_event() const
+ { return value_changed_event(); }
+
+ // get the value changed event
+ virtual const sc_event& value_changed_event() const
+ {
+ return *sc_lazy_kernel_event( &m_change_event_p
+ , "value_changed_event");
+ }
+
+
+ // read the current value
+ virtual const T& read() const
+ { return m_cur_val; }
+
+ // get a reference to the current value (for tracing)
+ virtual const T& get_data_ref() const
+ { sc_deprecated_get_data_ref(); return m_cur_val; }
+
+
+ // was there an event?
+ virtual bool event() const
+ { return simcontext()->event_occurred(m_change_stamp); }
+
+ // write the new value
+ virtual void write( const T& );
+
+
+ // other methods
+
+ operator const T& () const
+ { return read(); }
+
+
+ this_type& operator = ( const T& a )
+ { write( a ); return *this; }
+
+ this_type& operator = ( const sc_signal_in_if<T>& a )
+ { write( a.read() ); return *this; }
+
+ this_type& operator = ( const this_type& a )
+ { write( a.read() ); return *this; }
+
+
+ const T& get_new_value() const
+ { sc_deprecated_get_new_value(); return m_new_val; }
+
+
+ void trace( sc_trace_file* tf ) const
+ {
+ sc_deprecated_trace();
+# ifdef DEBUG_SYSTEMC
+ sc_trace( tf, read(), name() );
+# else
+ if ( tf ) {}
+# endif
+ }
+
+
+ virtual void print( ::std::ostream& = ::std::cout ) const;
+ virtual void dump( ::std::ostream& = ::std::cout ) const;
+
+ virtual const char* kind() const
+ { return "sc_signal"; }
+
+protected:
+
+ virtual void update();
+ void do_update();
+
+protected:
+
+ mutable sc_event* m_change_event_p;
+ T m_cur_val;
+ sc_dt::uint64 m_change_stamp; // delta of last event
+ T m_new_val;
+
+private:
+
+ // disabled
+ sc_signal( const this_type& );
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+
+template< class T, sc_writer_policy POL >
+inline
+void
+sc_signal<T,POL>::register_port( sc_port_base& port_
+ , const char* if_typename_ )
+{
+
+ bool is_output = std::string( if_typename_ ) == typeid(if_type).name();
+ if( !policy_type::check_port( this, &port_, is_output ) )
+ ((void)0); // fallback? error has been suppressed ...
+}
+
+
+// write the new value
+
+template< class T, sc_writer_policy POL >
+inline
+void
+sc_signal<T,POL>::write( const T& value_ )
+{
+ bool value_changed = !( m_cur_val == value_ );
+ if ( !policy_type::check_write(this, value_changed) )
+ return;
+
+ m_new_val = value_;
+ if( value_changed ) {
+ request_update();
+ }
+}
+
+
+template< class T, sc_writer_policy POL >
+inline
+void
+sc_signal<T,POL>::print( ::std::ostream& os ) const
+{
+ os << m_cur_val;
+}
+
+template< class T, sc_writer_policy POL >
+void
+sc_signal<T,POL>::dump( ::std::ostream& os ) const
+{
+ os << " name = " << name() << ::std::endl;
+ os << " value = " << m_cur_val << ::std::endl;
+ os << "new value = " << m_new_val << ::std::endl;
+}
+
+
+template< class T, sc_writer_policy POL >
+void
+sc_signal<T,POL>::update()
+{
+ policy_type::update();
+ if( !( m_new_val == m_cur_val ) ) {
+ do_update();
+ }
+}
+
+template< class T, sc_writer_policy POL >
+void
+sc_signal<T,POL>::do_update()
+{
+ m_cur_val = m_new_val;
+ if ( m_change_event_p ) m_change_event_p->notify_next_delta();
+ m_change_stamp = simcontext()->change_stamp();
+}
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_signal<bool>
+//
+// Specialization of sc_signal<T> for type bool.
+// ----------------------------------------------------------------------------
+
+class sc_reset;
+
+template< sc_writer_policy POL >
+class sc_signal<bool,POL>
+ : public sc_signal_inout_if<bool>
+ , public sc_prim_channel
+ , protected sc_writer_policy_check<POL>
+{
+protected:
+ typedef sc_signal_inout_if<bool> if_type;
+ typedef sc_signal<bool,POL> this_type;
+ typedef sc_writer_policy_check<POL> policy_type;
+
+public: // constructors and destructor:
+
+ sc_signal()
+ : sc_prim_channel( sc_gen_unique_name( "signal" ) ),
+ m_change_event_p( 0 ),
+ m_cur_val( false ),
+ m_change_stamp( ~sc_dt::UINT64_ONE ),
+ m_negedge_event_p( 0 ),
+ m_new_val( false ),
+ m_posedge_event_p( 0 ),
+ m_reset_p( 0 )
+ {}
+
+ explicit sc_signal( const char* name_ )
+ : sc_prim_channel( name_ ),
+ m_change_event_p( 0 ),
+ m_cur_val( false ),
+ m_change_stamp( ~sc_dt::UINT64_ONE ),
+ m_negedge_event_p( 0 ),
+ m_new_val( false ),
+ m_posedge_event_p( 0 ),
+ m_reset_p( 0 )
+ {}
+
+ sc_signal( const char* name_, bool initial_value_ )
+ : sc_prim_channel( name_ )
+ , m_change_event_p( 0 )
+ , m_cur_val( initial_value_ )
+ , m_change_stamp( ~sc_dt::UINT64_ONE )
+ , m_negedge_event_p( 0 )
+ , m_new_val( initial_value_ )
+ , m_posedge_event_p( 0 )
+ , m_reset_p( 0 )
+ {}
+
+ virtual ~sc_signal();
+
+
+ // interface methods
+
+ virtual void register_port( sc_port_base&, const char* );
+
+ virtual sc_writer_policy get_writer_policy() const
+ { return POL; }
+
+ // get the default event
+ virtual const sc_event& default_event() const
+ { return value_changed_event(); }
+
+ // get the value changed event
+ virtual const sc_event& value_changed_event() const;
+
+ // get the positive edge event
+ virtual const sc_event& posedge_event() const;
+
+ // get the negative edge event
+ virtual const sc_event& negedge_event() const;
+
+
+ // read the current value
+ virtual const bool& read() const
+ { return m_cur_val; }
+
+ // get a reference to the current value (for tracing)
+ virtual const bool& get_data_ref() const
+ { sc_deprecated_get_data_ref(); return m_cur_val; }
+
+
+ // was there a value changed event?
+ virtual bool event() const
+ { return simcontext()->event_occurred(m_change_stamp); }
+
+ // was there a positive edge event?
+ virtual bool posedge() const
+ { return ( event() && m_cur_val ); }
+
+ // was there a negative edge event?
+ virtual bool negedge() const
+ { return ( event() && ! m_cur_val ); }
+
+ // write the new value
+ virtual void write( const bool& );
+
+ // other methods
+
+ operator const bool& () const
+ { return read(); }
+
+
+ this_type& operator = ( const bool& a )
+ { write( a ); return *this; }
+
+ this_type& operator = ( const sc_signal_in_if<bool>& a )
+ { write( a.read() ); return *this; }
+
+ this_type& operator = ( const this_type& a )
+ { write( a.read() ); return *this; }
+
+
+ const bool& get_new_value() const
+ { sc_deprecated_get_new_value(); return m_new_val; }
+
+
+ void trace( sc_trace_file* tf ) const
+ {
+ sc_deprecated_trace();
+# ifdef DEBUG_SYSTEMC
+ sc_trace( tf, read(), name() );
+# else
+ if ( tf ) {}
+# endif
+ }
+
+
+ virtual void print( ::std::ostream& = ::std::cout ) const;
+ virtual void dump( ::std::ostream& = ::std::cout ) const;
+
+ virtual const char* kind() const
+ { return "sc_signal"; }
+
+protected:
+
+ virtual void update();
+ void do_update();
+
+ virtual bool is_clock() const { return false; }
+
+protected:
+ mutable sc_event* m_change_event_p; // value change event if present.
+ bool m_cur_val; // current value of object.
+ sc_dt::uint64 m_change_stamp; // delta of last event
+ mutable sc_event* m_negedge_event_p; // negative edge event if present.
+ bool m_new_val; // next value of object.
+ mutable sc_event* m_posedge_event_p; // positive edge event if present.
+ mutable sc_reset* m_reset_p; // reset mechanism if present.
+
+private:
+
+ // reset creation
+ virtual sc_reset* is_reset() const;
+
+ // disabled
+ sc_signal( const this_type& );
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_signal<sc_dt::sc_logic>
+//
+// Specialization of sc_signal<T> for type sc_dt::sc_logic.
+// ----------------------------------------------------------------------------
+
+template< sc_writer_policy POL >
+class sc_signal<sc_dt::sc_logic,POL>
+ : public sc_signal_inout_if<sc_dt::sc_logic>
+ , public sc_prim_channel
+ , protected sc_writer_policy_check<POL>
+{
+protected:
+ typedef sc_signal_inout_if<sc_dt::sc_logic> if_type;
+ typedef sc_signal<sc_dt::sc_logic,POL> this_type;
+ typedef sc_writer_policy_check<POL> policy_type;
+
+public: // constructors and destructor:
+
+ sc_signal()
+ : sc_prim_channel( sc_gen_unique_name( "signal" ) ),
+ m_change_event_p( 0 ),
+ m_cur_val(),
+ m_change_stamp( ~sc_dt::UINT64_ONE ),
+ m_negedge_event_p( 0 ),
+ m_new_val(),
+ m_posedge_event_p( 0 )
+ {}
+
+ explicit sc_signal( const char* name_ )
+ : sc_prim_channel( name_ ),
+ m_change_event_p( 0 ),
+ m_cur_val(),
+ m_change_stamp( ~sc_dt::UINT64_ONE ),
+ m_negedge_event_p( 0 ),
+ m_new_val(),
+ m_posedge_event_p( 0 )
+ {}
+
+ sc_signal( const char* name_, sc_dt::sc_logic initial_value_ )
+ : sc_prim_channel( name_ )
+ , m_change_event_p( 0 )
+ , m_cur_val( initial_value_ )
+ , m_change_stamp( ~sc_dt::UINT64_ONE )
+ , m_negedge_event_p( 0 )
+ , m_new_val( initial_value_ )
+ , m_posedge_event_p( 0 )
+ {}
+
+ virtual ~sc_signal()
+ {
+ delete m_change_event_p;
+ delete m_negedge_event_p;
+ delete m_posedge_event_p;
+ }
+
+
+ // interface methods
+
+ virtual void register_port( sc_port_base&, const char* );
+
+ virtual sc_writer_policy get_writer_policy() const
+ { return POL; }
+
+ // get the default event
+ virtual const sc_event& default_event() const
+ { return value_changed_event(); }
+
+ // get the value changed event
+ virtual const sc_event& value_changed_event() const;
+
+ // get the positive edge event
+ virtual const sc_event& posedge_event() const;
+
+ // get the negative edge event
+ virtual const sc_event& negedge_event() const;
+
+
+ // read the current value
+ virtual const sc_dt::sc_logic& read() const
+ { return m_cur_val; }
+
+ // get a reference to the current value (for tracing)
+ virtual const sc_dt::sc_logic& get_data_ref() const
+ { sc_deprecated_get_data_ref(); return m_cur_val; }
+
+
+ // was there an event?
+ virtual bool event() const
+ { return simcontext()->event_occurred(m_change_stamp); }
+
+ // was there a positive edge event?
+ virtual bool posedge() const
+ { return ( event() && m_cur_val == sc_dt::SC_LOGIC_1 ); }
+
+ // was there a negative edge event?
+ virtual bool negedge() const
+ { return ( event() && m_cur_val == sc_dt::SC_LOGIC_0 ); }
+
+
+ // write the new value
+ virtual void write( const sc_dt::sc_logic& );
+
+
+ // other methods
+
+ operator const sc_dt::sc_logic& () const
+ { return read(); }
+
+
+ this_type& operator = ( const sc_dt::sc_logic& a )
+ { write( a ); return *this; }
+
+ this_type& operator = ( const sc_signal_in_if<sc_dt::sc_logic>& a )
+ { write( a.read() ); return *this; }
+
+ this_type& operator = (const this_type& a)
+ { write( a.read() ); return *this; }
+
+
+ const sc_dt::sc_logic& get_new_value() const
+ { sc_deprecated_get_new_value(); return m_new_val; }
+
+
+ void trace( sc_trace_file* tf ) const
+ {
+ sc_deprecated_trace();
+# ifdef DEBUG_SYSTEMC
+ sc_trace( tf, read(), name() );
+# else
+ if ( tf ) {}
+# endif
+ }
+
+ virtual void print( ::std::ostream& = ::std::cout ) const;
+ virtual void dump( ::std::ostream& = ::std::cout ) const;
+
+ virtual const char* kind() const
+ { return "sc_signal"; }
+
+protected:
+
+ virtual void update();
+ void do_update();
+
+protected:
+
+ mutable sc_event* m_change_event_p; // value change event if present.
+ sc_dt::sc_logic m_cur_val; // current value of object.
+ sc_dt::uint64 m_change_stamp; // delta of last event
+ mutable sc_event* m_negedge_event_p; // negative edge event if present.
+ sc_dt::sc_logic m_new_val; // next value of object.
+ mutable sc_event* m_posedge_event_p; // positive edge event if present.
+
+private:
+
+ // disabled
+ sc_signal( const this_type& );
+};
+
+// ----------------------------------------------------------------------------
+
+template< typename T, sc_writer_policy POL >
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, const sc_signal<T,POL>& a )
+{
+ return ( os << a.read() );
+}
+
+
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+//$Log: sc_signal.h,v $
+//Revision 1.16 2011/08/26 20:45:42 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+//Revision 1.15 2011/08/15 16:43:24 acg
+// Torsten Maehne: changes to remove unused argument warnings.
+//
+//Revision 1.14 2011/06/25 17:08:38 acg
+// Andy Goodrich: Jerome Cornet's changes to use libtool to build the
+// library.
+//
+//Revision 1.13 2011/04/13 02:59:09 acg
+// Andy Goodrich: made events internal to signals into kernel events.
+//
+//Revision 1.12 2011/04/08 18:22:46 acg
+// Philipp A. Hartmann: use the context of the primitive channel to get
+// the change stamp value.
+//
+//Revision 1.11 2011/04/05 20:48:09 acg
+// Andy Goodrich: changes to make sure that event(), posedge() and negedge()
+// only return true if the clock has not moved.
+//
+//Revision 1.10 2011/04/05 07:10:55 acg
+// Andy Goodrich: added line that I dropped in sc_signal<sc_dt::sc_logic>.
+//
+//Revision 1.9 2011/04/05 06:15:18 acg
+// Philipp A. Hartmann: sc_writer_policy: ignore no-ops in delta check.
+//
+//Revision 1.8 2011/03/23 16:17:22 acg
+// Andy Goodrich: hide the sc_events that are kernel related.
+//
+//Revision 1.7 2011/03/06 15:55:08 acg
+// Andy Goodrich: Changes for named events.
+//
+//Revision 1.6 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+//Revision 1.5 2011/02/07 19:16:50 acg
+// Andy Goodrich: changes for handling multiple writers.
+//
+//Revision 1.4 2011/01/25 20:50:37 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+//Revision 1.3 2010/12/07 19:50:37 acg
+// Andy Goodrich: addition of writer policies, courtesy of Philipp Hartmann.
+//
+//Revision 1.1.1.1 2006/12/15 20:20:04 acg
+//SystemC 2.3
+//
+//Revision 1.14 2006/05/08 17:52:47 acg
+// Andy Goodrich:
+// (1) added David Long's forward declarations for friend functions,
+// methods, and operators to keep the Microsoft compiler happy.
+// (2) Added delta_count() method to sc_prim_channel for use by
+// sc_signal so that the friend declaration in sc_simcontext.h
+// can be for a non-templated class (i.e., sc_prim_channel.)
+//
+//Revision 1.12 2006/04/11 23:11:57 acg
+// Andy Goodrich: Changes for reset support that only includes
+// sc_cthread_process instances.
+//
+//Revision 1.11 2006/03/13 20:19:44 acg
+// Andy Goodrich: changed sc_event instances into pointers to sc_event instances
+// that are allocated as needed. This saves considerable storage for large
+// numbers of signals, etc.
+//
+//Revision 1.10 2006/01/26 21:00:50 acg
+// Andy Goodrich: conversion to use sc_event::notify(SC_ZERO_TIME) instead of
+// sc_event::notify_delayed()
+//
+//Revision 1.9 2006/01/24 20:45:41 acg
+//Andy Goodrich: converted notify_delayed() calls into notify_next_delta() calls
+//to eliminate deprecation warnings. notify_next_delta() is an implemenation-
+//dependent method of sc_event. It is simpler than notify_delayed(), and should
+//speed up simulation speeds.
+//
+//Revision 1.8 2006/01/19 19:18:25 acg
+//Andy Goodrich: eliminated check_writer in favor of inline code within the
+//write() method since we always execute the check_writer code even when
+//check writing is turned off.
+//
+//Revision 1.7 2006/01/19 00:30:57 acg
+//Andy Goodrich: Yet another implementation for disabling write checks on
+//signals. This version uses an environment variable, SC_SIGNAL_WRITE_CHECK,
+//that when set to DISABLE will turn off write checking.
+//
+//Revision 1.6 2006/01/18 21:42:26 acg
+//Andy Goodrich: Changes for check writer support, and tightening up sc_clock
+//port usage.
+//
+//Revision 1.5 2006/01/13 20:41:59 acg
+//Andy Goodrich: Changes to add port registration to the things that are
+//checked when SC_NO_WRITE_CHECK is not defined.
+//
+//Revision 1.4 2006/01/13 18:47:20 acg
+//Reversed sense of multiwriter signal check. It now defaults to ON unless the
+//user defines SC_NO_WRITE_CHEK before inclusion of the file.
+//
+//Revision 1.3 2006/01/03 23:18:26 acg
+//Changed copyright to include 2006.
+//
+//Revision 1.2 2005/12/20 21:58:18 acg
+//Removed Makefile.in, changed the event() methods to use sc_simcontext::event_occurred.
+//
+//Revision 1.1.1.1 2005/12/19 23:16:43 acg
+//First check in of SystemC 2.1 into its own archive.
+//
+//Revision 1.19 2005/09/15 23:01:51 acg
+//Added std:: prefix to appropriate methods and types to get around
+//issues with the Edison Front End.
+//
+//Revision 1.18 2005/06/10 22:43:55 acg
+//Added CVS change log annotation.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_signal_ifs.h b/ext/systemc/src/sysc/communication/sc_signal_ifs.h
new file mode 100644
index 000000000..ad703aaa7
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_signal_ifs.h
@@ -0,0 +1,305 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_signal_ifs.h -- The sc_signal<T> interface classes.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_SIGNAL_IFS_H
+#define SC_SIGNAL_IFS_H
+
+
+#include "sysc/communication/sc_interface.h"
+#include "sysc/communication/sc_writer_policy.h"
+
+
+namespace sc_dt
+{
+ class sc_logic;
+}
+
+namespace sc_core {
+
+class sc_signal_bool_deval;
+class sc_signal_logic_deval;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_signal_in_if<T>
+//
+// The sc_signal<T> input interface class.
+// ----------------------------------------------------------------------------
+
+template <class T>
+class sc_signal_in_if
+: virtual public sc_interface
+{
+public:
+
+ // get the value changed event
+ virtual const sc_event& value_changed_event() const = 0;
+
+
+ // read the current value
+ virtual const T& read() const = 0;
+
+ // get a reference to the current value (for tracing)
+ virtual const T& get_data_ref() const = 0;
+
+
+ // was there a value changed event?
+ virtual bool event() const = 0;
+
+protected:
+
+ // constructor
+
+ sc_signal_in_if()
+ {}
+
+private:
+
+ // disabled
+ sc_signal_in_if( const sc_signal_in_if<T>& );
+ sc_signal_in_if<T>& operator = ( const sc_signal_in_if<T>& );
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_signal_in_if<bool>
+//
+// Specialization of sc_signal_in_if<T> for type bool.
+// ----------------------------------------------------------------------------
+
+class sc_reset;
+
+template <>
+class sc_signal_in_if<bool>
+: virtual public sc_interface
+{
+ friend class sc_reset;
+public:
+
+ // get the value changed event
+ virtual const sc_event& value_changed_event() const = 0;
+
+ // get the positive edge event
+ virtual const sc_event& posedge_event() const = 0;
+
+ // get the negative edge event
+ virtual const sc_event& negedge_event() const = 0;
+
+
+ // read the current value
+ virtual const bool& read() const = 0;
+
+ // get a reference to the current value (for tracing)
+ virtual const bool& get_data_ref() const = 0;
+
+
+ // was there a value changed event?
+ virtual bool event() const = 0;
+
+ // was there a positive edge event?
+ virtual bool posedge() const = 0;
+
+ // was there a negative edge event?
+ virtual bool negedge() const = 0;
+
+protected:
+
+ // constructor
+
+ sc_signal_in_if()
+ {}
+
+private:
+
+ // disabled
+ sc_signal_in_if( const sc_signal_in_if<bool>& );
+ sc_signal_in_if<bool>& operator = ( const sc_signal_in_if<bool>& );
+
+ // designate this object as a reset signal
+ virtual sc_reset* is_reset() const
+ { return NULL; }
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_signal_in_if<sc_dt::sc_logic>
+//
+// Specialization of sc_signal_in_if<T> for type sc_dt::sc_logic.
+// ----------------------------------------------------------------------------
+
+template <>
+class sc_signal_in_if<sc_dt::sc_logic>
+: virtual public sc_interface
+{
+public:
+
+ // get the value changed event
+ virtual const sc_event& value_changed_event() const = 0;
+
+ // get the positive edge event
+ virtual const sc_event& posedge_event() const = 0;
+
+ // get the negative edge event
+ virtual const sc_event& negedge_event() const = 0;
+
+
+ // read the current value
+ virtual const sc_dt::sc_logic& read() const = 0;
+
+ // get a reference to the current value (for tracing)
+ virtual const sc_dt::sc_logic& get_data_ref() const = 0;
+
+
+ // was there a value changed event?
+ virtual bool event() const = 0;
+
+ // was there a positive edge event?
+ virtual bool posedge() const = 0;
+
+ // was there a negative edge event?
+ virtual bool negedge() const = 0;
+
+
+protected:
+
+ // constructor
+
+ sc_signal_in_if()
+ {}
+
+private:
+
+ // disabled
+ sc_signal_in_if( const sc_signal_in_if<sc_dt::sc_logic>& );
+ sc_signal_in_if<sc_dt::sc_logic>& operator = (
+ const sc_signal_in_if<sc_dt::sc_logic>& );
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_signal_write_if<T>
+//
+// The standard output interface class.
+// ----------------------------------------------------------------------------
+template< typename T >
+class sc_signal_write_if : public virtual sc_interface
+{
+public:
+ sc_signal_write_if() {}
+ // write the new value
+ virtual void write( const T& ) = 0;
+ virtual sc_writer_policy get_writer_policy() const
+ { return SC_DEFAULT_WRITER_POLICY; }
+private:
+ // disabled
+ sc_signal_write_if( const sc_signal_write_if<T>& );
+ sc_signal_write_if<T>& operator = ( const sc_signal_write_if<T>& );
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_signal_inout_if<T>
+//
+// The sc_signal<T> input/output interface class.
+// ----------------------------------------------------------------------------
+
+template <class T>
+class sc_signal_inout_if
+: public sc_signal_in_if<T>, public sc_signal_write_if<T>
+{
+
+protected:
+
+ // constructor
+
+ sc_signal_inout_if()
+ {}
+
+private:
+
+ // disabled
+ sc_signal_inout_if( const sc_signal_inout_if<T>& );
+ sc_signal_inout_if<T>& operator = ( const sc_signal_inout_if<T>& );
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_signal_out_if<T>
+//
+// The sc_signal<T> output interface class.
+// ----------------------------------------------------------------------------
+
+// sc_signal_out_if can also be read from, hence no difference with
+// sc_signal_inout_if.
+
+#define sc_signal_out_if sc_signal_inout_if
+
+} // namespace sc_core
+
+//$Log: sc_signal_ifs.h,v $
+//Revision 1.4 2011/08/26 20:45:43 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+//Revision 1.3 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+//Revision 1.2 2010/12/07 19:50:37 acg
+// Andy Goodrich: addition of writer policies, courtesy of Philipp Hartmann.
+//
+//Revision 1.1.1.1 2006/12/15 20:20:04 acg
+//SystemC 2.3
+//
+//Revision 1.4 2006/08/29 23:35:00 acg
+// Andy Goodrich: added bind_count() method to allow users to determine which
+// ports are connected in before_end_of_elaboration().
+//
+//Revision 1.3 2006/04/11 23:11:57 acg
+// Andy Goodrich: Changes for reset support that only includes
+// sc_cthread_process instances.
+//
+//Revision 1.2 2006/01/03 23:18:26 acg
+//Changed copyright to include 2006.
+//
+//Revision 1.1.1.1 2005/12/19 23:16:43 acg
+//First check in of SystemC 2.1 into its own archive.
+//
+//Revision 1.10 2005/09/15 23:01:51 acg
+//Added std:: prefix to appropriate methods and types to get around
+//issues with the Edison Front End.
+//
+//Revision 1.9 2005/06/29 18:12:12 acg
+//Added $log.
+//
+//Revision 1.8 2005/06/10 22:43:55 acg
+//Added CVS change log annotation.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_signal_ports.cpp b/ext/systemc/src/sysc/communication/sc_signal_ports.cpp
new file mode 100644
index 000000000..d3a182e54
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_signal_ports.cpp
@@ -0,0 +1,441 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_signal_ports.cpp -- The sc_signal<T> port classes.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-08-20
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include "sysc/communication/sc_signal_ports.h"
+#include "sysc/datatypes/int/sc_signed.h"
+#include "sysc/datatypes/int/sc_unsigned.h"
+#include "sysc/datatypes/bit/sc_lv_base.h"
+#include "sysc/utils/sc_utils_ids.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_in<bool>
+//
+// Specialization of sc_in<T> for type bool.
+// ----------------------------------------------------------------------------
+
+// called when elaboration is done
+
+void
+sc_in<bool>::end_of_elaboration()
+{
+ if( m_traces != 0 ) {
+ for( int i = 0; i < (int)m_traces->size(); ++ i ) {
+ sc_trace_params* p = (*m_traces)[i];
+ in_if_type* iface = DCAST<in_if_type*>( get_interface() );
+ sc_trace( p->tf, iface->read(), p->name );
+ }
+ remove_traces();
+ }
+}
+
+// called by sc_trace
+
+void
+sc_in<bool>::add_trace_internal(sc_trace_file* tf_,
+ const std::string& name_) const
+{
+ if( tf_ != 0 ) {
+ if( m_traces == 0 ) {
+ m_traces = new sc_trace_params_vec;
+ }
+ m_traces->push_back( new sc_trace_params( tf_, name_ ) );
+ }
+}
+
+void
+sc_in<bool>::add_trace(sc_trace_file* tf_,
+ const std::string& name_) const
+{
+ sc_deprecated_add_trace();
+ add_trace_internal(tf_, name_);
+}
+
+void
+sc_in<bool>::remove_traces() const
+{
+ if( m_traces != 0 ) {
+ for( int i = m_traces->size() - 1; i >= 0; -- i ) {
+ delete (*m_traces)[i];
+ }
+ delete m_traces;
+ m_traces = 0;
+ }
+}
+
+
+// called by pbind (for internal use only)
+
+int
+sc_in<bool>::vbind( sc_interface& interface_ )
+{
+ return sc_port_b<if_type>::vbind( interface_ );
+}
+
+int
+sc_in<bool>::vbind( sc_port_base& parent_ )
+{
+ in_port_type* in_parent = DCAST<in_port_type*>( &parent_ );
+ if( in_parent != 0 ) {
+ sc_port_base::bind( *in_parent );
+ return 0;
+ }
+ inout_port_type* inout_parent = DCAST<inout_port_type*>( &parent_ );
+ if( inout_parent != 0 ) {
+ sc_port_base::bind( *inout_parent );
+ return 0;
+ }
+ // type mismatch
+ return 2;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_in<sc_logic>
+//
+// Specialization of sc_in<T> for type sc_logic.
+// ----------------------------------------------------------------------------
+
+// called when elaboration is done
+
+void
+sc_in<sc_dt::sc_logic>::end_of_elaboration()
+{
+ if( m_traces != 0 ) {
+ for( int i = 0; i < (int)m_traces->size(); ++ i ) {
+ sc_trace_params* p = (*m_traces)[i];
+ in_if_type* iface = DCAST<in_if_type*>( get_interface() );
+ sc_trace( p->tf, iface->read(), p->name );
+ }
+ remove_traces();
+ }
+}
+
+
+// called by sc_trace
+
+void
+sc_in<sc_dt::sc_logic>::add_trace_internal( sc_trace_file* tf_,
+ const std::string& name_ ) const
+{
+ if( tf_ != 0 ) {
+ if( m_traces == 0 ) {
+ m_traces = new sc_trace_params_vec;
+ }
+ m_traces->push_back( new sc_trace_params( tf_, name_ ) );
+ }
+}
+
+void
+sc_in<sc_dt::sc_logic>::add_trace( sc_trace_file* tf_,
+ const std::string& name_ ) const
+{
+ sc_deprecated_add_trace();
+ add_trace_internal(tf_, name_);
+}
+
+void
+sc_in<sc_dt::sc_logic>::remove_traces() const
+{
+ if( m_traces != 0 ) {
+ for( int i = m_traces->size() - 1; i >= 0; -- i ) {
+ delete (*m_traces)[i];
+ }
+ delete m_traces;
+ m_traces = 0;
+ }
+}
+
+
+// called by pbind (for internal use only)
+
+int
+sc_in<sc_dt::sc_logic>::vbind( sc_interface& interface_ )
+{
+ return sc_port_b<if_type>::vbind( interface_ );
+}
+
+int
+sc_in<sc_dt::sc_logic>::vbind( sc_port_base& parent_ )
+{
+ in_port_type* in_parent = DCAST<in_port_type*>( &parent_ );
+ if( in_parent != 0 ) {
+ sc_port_base::bind( *in_parent );
+ return 0;
+ }
+ inout_port_type* inout_parent = DCAST<inout_port_type*>( &parent_ );
+ if( inout_parent != 0 ) {
+ sc_port_base::bind( *inout_parent );
+ return 0;
+ }
+ // type mismatch
+ return 2;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_inout<bool>
+//
+// Specialization of sc_inout<T> for type bool.
+// ----------------------------------------------------------------------------
+
+// destructor
+
+sc_inout<bool>::~sc_inout()
+{
+ delete m_change_finder_p;
+ delete m_neg_finder_p;
+ delete m_pos_finder_p;
+ delete m_init_val;
+ remove_traces();
+}
+
+
+// set initial value (can also be called when port is not bound yet)
+
+void
+sc_inout<bool>::initialize( const data_type& value_ )
+{
+ inout_if_type* iface = DCAST<inout_if_type*>( get_interface() );
+ if( iface != 0 ) {
+ iface->write( value_ );
+ } else {
+ if( m_init_val == 0 ) {
+ m_init_val = new data_type;
+ }
+ *m_init_val = value_;
+ }
+}
+
+
+// called when elaboration is done
+
+void
+sc_inout<bool>::end_of_elaboration()
+{
+ if( m_init_val != 0 ) {
+ write( *m_init_val );
+ delete m_init_val;
+ m_init_val = 0;
+ }
+ if( m_traces != 0 ) {
+ for( int i = 0; i < (int)m_traces->size(); ++ i ) {
+ sc_trace_params* p = (*m_traces)[i];
+ in_if_type* iface = DCAST<in_if_type*>( get_interface() );
+ sc_trace( p->tf, iface->read(), p->name );
+ }
+ remove_traces();
+ }
+}
+
+
+// called by sc_trace
+
+void
+sc_inout<bool>::add_trace_internal( sc_trace_file* tf_,
+ const std::string& name_ ) const
+{
+ if( tf_ != 0 ) {
+ if( m_traces == 0 ) {
+ m_traces = new sc_trace_params_vec;
+ }
+ m_traces->push_back( new sc_trace_params( tf_, name_ ) );
+ }
+}
+
+void
+sc_inout<bool>::add_trace( sc_trace_file* tf_,
+ const std::string& name_ ) const
+{
+ sc_deprecated_add_trace();
+ add_trace_internal(tf_, name_);
+}
+
+void
+sc_inout<bool>::remove_traces() const
+{
+ if( m_traces != 0 ) {
+ for( int i = m_traces->size() - 1; i >= 0; -- i ) {
+ delete (*m_traces)[i];
+ }
+ delete m_traces;
+ m_traces = 0;
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_inout<sc_dt::sc_logic>
+//
+// Specialization of sc_inout<T> for type sc_dt::sc_logic.
+// ----------------------------------------------------------------------------
+
+// destructor
+
+sc_inout<sc_dt::sc_logic>::~sc_inout()
+{
+ delete m_change_finder_p;
+ delete m_neg_finder_p;
+ delete m_pos_finder_p;
+ delete m_init_val;
+ remove_traces();
+}
+
+
+// set initial value (can also be called when port is not bound yet)
+
+void
+sc_inout<sc_dt::sc_logic>::initialize( const data_type& value_ )
+{
+ inout_if_type* iface = DCAST<inout_if_type*>( get_interface() );
+ if( iface != 0 ) {
+ iface->write( value_ );
+ } else {
+ if( m_init_val == 0 ) {
+ m_init_val = new data_type;
+ }
+ *m_init_val = value_;
+ }
+}
+
+
+// called when elaboration is done
+
+void
+sc_inout<sc_dt::sc_logic>::end_of_elaboration()
+{
+ if( m_init_val != 0 ) {
+ write( *m_init_val );
+ delete m_init_val;
+ m_init_val = 0;
+ }
+ if( m_traces != 0 ) {
+ for( int i = 0; i < (int)m_traces->size(); ++ i ) {
+ sc_trace_params* p = (*m_traces)[i];
+ in_if_type* iface = DCAST<in_if_type*>( get_interface() );
+ sc_trace( p->tf, iface->read(), p->name );
+ }
+ remove_traces();
+ }
+}
+
+
+// called by sc_trace
+
+void
+sc_inout<sc_dt::sc_logic>::add_trace_internal( sc_trace_file* tf_,
+ const std::string& name_ ) const
+{
+ if( tf_ != 0 ) {
+ if( m_traces == 0 ) {
+ m_traces = new sc_trace_params_vec;
+ }
+ m_traces->push_back( new sc_trace_params( tf_, name_ ) );
+ }
+}
+
+
+void
+sc_inout<sc_dt::sc_logic>::add_trace( sc_trace_file* tf_,
+ const std::string& name_ ) const
+{
+ sc_deprecated_add_trace();
+ add_trace_internal(tf_, name_);
+}
+
+void
+sc_inout<sc_dt::sc_logic>::remove_traces() const
+{
+ if( m_traces != 0 ) {
+ for( int i = m_traces->size() - 1; i >= 0; -- i ) {
+ delete (*m_traces)[i];
+ }
+ delete m_traces;
+ m_traces = 0;
+ }
+}
+
+void sc_deprecated_add_trace()
+{
+ static bool warn_add_trace_deprecated=true;
+ if ( warn_add_trace_deprecated )
+ {
+ warn_add_trace_deprecated=false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "sc_signal<T>::addtrace() is deprecated");
+ }
+}
+} // namespace sc_core
+
+// $Log: sc_signal_ports.cpp,v $
+// Revision 1.3 2011/08/26 20:45:43 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.2 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.8 2006/05/08 17:52:47 acg
+// Andy Goodrich:
+// (1) added David Long's forward declarations for friend functions,
+// methods, and operators to keep the Microsoft compiler happy.
+// (2) Added delta_count() method to sc_prim_channel for use by
+// sc_signal so that the friend declaration in sc_simcontext.h
+// can be for a non-templated class (i.e., sc_prim_channel.)
+//
+// Revision 1.7 2006/04/18 18:01:26 acg
+// Andy Goodrich: added an add_trace_internal() method to the various port
+// classes so that sc_trace has something to call that won't emit an
+// IEEE 1666 deprecation message.
+//
+// Revision 1.6 2006/02/02 23:42:37 acg
+// Andy Goodrich: implemented a much better fix to the sc_event_finder
+// proliferation problem. This new version allocates only a single event
+// finder for each port for each type of event, e.g., pos(), neg(), and
+// value_change(). The event finder persists as long as the port does,
+// which is what the LRM dictates. Because only a single instance is
+// allocated for each event type per port there is not a potential
+// explosion of storage as was true in the 2.0.1/2.1 versions.
+//
+// Revision 1.5 2006/01/25 00:31:11 acg
+// Andy Goodrich: Changed over to use a standard message id of
+// SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
+//
+// Revision 1.4 2006/01/24 20:46:32 acg
+// Andy Goodrich: changes to eliminate use of deprecated features. For instance,
+// using notify(SC_ZERO_TIME) in place of notify_delayed().
+//
+// Revision 1.3 2006/01/13 18:47:42 acg
+// Added $Log command so that CVS comments are reproduced in the source.
+//
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_signal_ports.h b/ext/systemc/src/sysc/communication/sc_signal_ports.h
new file mode 100644
index 000000000..22c83c583
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_signal_ports.h
@@ -0,0 +1,1931 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_signal_ports.h -- The sc_signal<T> port classes.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG APPEARS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_SIGNAL_PORTS_H
+#define SC_SIGNAL_PORTS_H
+
+
+#include "sysc/communication/sc_event_finder.h"
+#include "sysc/communication/sc_port.h"
+#include "sysc/communication/sc_signal_ifs.h"
+#include "sysc/datatypes/bit/sc_logic.h"
+#include "sysc/tracing/sc_trace.h"
+
+#if ! defined( SC_DISABLE_VIRTUAL_BIND )
+# define SC_VIRTUAL_ virtual
+#else
+# define SC_VIRTUAL_ /* non-virtual */
+#endif
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// STRUCT : sc_trace_params
+//
+// Struct for storing the trace file and object name of an sc_trace call.
+// FOR INTERNAL USE ONLY!
+// ----------------------------------------------------------------------------
+
+extern void sc_deprecated_add_trace();
+
+struct sc_trace_params
+{
+ sc_trace_file* tf;
+ std::string name;
+
+ sc_trace_params( sc_trace_file* tf_, const std::string& name_ )
+ : tf( tf_ ), name( name_ )
+ {}
+};
+
+
+typedef std::vector<sc_trace_params*> sc_trace_params_vec;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_in<T>
+//
+// The sc_signal<T> input port class.
+// ----------------------------------------------------------------------------
+
+template <class T>
+class sc_in
+: public sc_port<sc_signal_in_if<T>,1,SC_ONE_OR_MORE_BOUND>
+{
+public:
+
+ // typedefs
+
+ typedef T data_type;
+
+ typedef sc_signal_in_if<data_type> if_type;
+ typedef sc_port<if_type,1,SC_ONE_OR_MORE_BOUND> base_type;
+ typedef sc_in<data_type> this_type;
+ typedef typename base_type::port_type base_port_type;
+
+ typedef if_type in_if_type;
+ typedef base_type in_port_type;
+ typedef sc_signal_inout_if<data_type> inout_if_type;
+ typedef sc_port<inout_if_type,1,SC_ONE_OR_MORE_BOUND> inout_port_type;
+
+public:
+
+ // constructors
+
+ sc_in()
+ : base_type(), m_traces( 0 ),
+ m_change_finder_p(0)
+ {}
+
+ explicit sc_in( const char* name_ )
+ : base_type( name_ ), m_traces( 0 ),
+ m_change_finder_p(0)
+ {}
+
+ explicit sc_in( const in_if_type& interface_ )
+ : base_type( CCAST<in_if_type&>( interface_ ) ), m_traces( 0 ),
+ m_change_finder_p(0)
+ {}
+
+ sc_in( const char* name_, const in_if_type& interface_ )
+ : base_type( name_, CCAST<in_if_type&>( interface_ ) ), m_traces( 0 ),
+ m_change_finder_p(0)
+ {}
+
+ explicit sc_in( in_port_type& parent_ )
+ : base_type( parent_ ), m_traces( 0 ),
+ m_change_finder_p(0)
+ {}
+
+ sc_in( const char* name_, in_port_type& parent_ )
+ : base_type( name_, parent_ ), m_traces( 0 ),
+ m_change_finder_p(0)
+ {}
+
+ explicit sc_in( inout_port_type& parent_ )
+ : base_type(), m_traces( 0 ),
+ m_change_finder_p(0)
+ { sc_port_base::bind( parent_ ); }
+
+ sc_in( const char* name_, inout_port_type& parent_ )
+ : base_type( name_ ), m_traces( 0 ),
+ m_change_finder_p(0)
+ { sc_port_base::bind( parent_ ); }
+
+ sc_in( this_type& parent_ )
+ : base_type( parent_ ), m_traces( 0 ),
+ m_change_finder_p(0)
+ {}
+
+ sc_in( const char* name_, this_type& parent_ )
+ : base_type( name_, parent_ ), m_traces( 0 ),
+ m_change_finder_p(0)
+ {}
+
+
+ // destructor
+
+ virtual ~sc_in()
+ {
+ remove_traces();
+ delete m_change_finder_p;
+ }
+
+
+ // bind to in interface
+
+ SC_VIRTUAL_ void bind( const in_if_type& interface_ )
+ { sc_port_base::bind( CCAST<in_if_type&>( interface_ ) ); }
+
+ SC_VIRTUAL_ void bind( in_if_type& interface_ )
+ { this->bind( CCAST<const in_if_type&>( interface_ ) ); }
+
+ void operator () ( const in_if_type& interface_ )
+ { this->bind( interface_ ); }
+
+
+ // bind to parent in port
+
+ SC_VIRTUAL_ void bind( in_port_type& parent_ )
+ { sc_port_base::bind( parent_ ); }
+
+ void operator () ( in_port_type& parent_ )
+ { this->bind( parent_ ); }
+
+
+ // bind to parent inout port
+
+ SC_VIRTUAL_ void bind( inout_port_type& parent_ )
+ { sc_port_base::bind( parent_ ); }
+
+ void operator () ( inout_port_type& parent_ )
+ { this->bind( parent_ ); }
+
+
+ // interface access shortcut methods
+
+ // get the default event
+
+ const sc_event& default_event() const
+ { return (*this)->default_event(); }
+
+
+ // get the value changed event
+
+ const sc_event& value_changed_event() const
+ { return (*this)->value_changed_event(); }
+
+
+ // read the current value
+
+ const data_type& read() const
+ { return (*this)->read(); }
+
+ operator const data_type& () const
+ { return (*this)->read(); }
+
+
+ // was there a value changed event?
+
+ bool event() const
+ { return (*this)->event(); }
+
+
+ // (other) event finder method(s)
+
+ sc_event_finder& value_changed() const
+ {
+ if ( !m_change_finder_p )
+ {
+ m_change_finder_p = new sc_event_finder_t<in_if_type>(
+ *this, &in_if_type::value_changed_event );
+ }
+ return *m_change_finder_p;
+ }
+
+
+ // called when elaboration is done
+ /* WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
+ /* MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
+
+ virtual void end_of_elaboration();
+
+ virtual const char* kind() const
+ { return "sc_in"; }
+
+
+ void add_trace( sc_trace_file*, const std::string& ) const;
+
+ // called by sc_trace
+ void add_trace_internal( sc_trace_file*, const std::string& ) const;
+
+protected:
+
+ void remove_traces() const;
+
+ mutable sc_trace_params_vec* m_traces;
+
+protected:
+
+ // called by pbind (for internal use only)
+ virtual int vbind( sc_interface& );
+ virtual int vbind( sc_port_base& );
+
+ // implement virtual base_type port-binding function
+ // - avoids warnings on some compilers
+ // - should only be called, when using sc_port_b explicitly
+ // - errors are detected during elaboration
+
+ SC_VIRTUAL_ void bind( base_port_type& parent_ )
+ { sc_port_base::bind( parent_ ); }
+
+
+private:
+ mutable sc_event_finder* m_change_finder_p;
+
+private:
+
+ // disabled
+ sc_in( const this_type& );
+ this_type& operator = ( const this_type& );
+
+#ifdef __GNUC__
+ // Needed to circumvent a problem in the g++-2.95.2 compiler:
+ // This unused variable forces the compiler to instantiate
+ // an object of T template so an implicit conversion from
+ // read() to a C++ intrinsic data type will work.
+ static data_type dummy;
+#endif
+};
+
+template<typename T>
+::std::ostream& operator << ( ::std::ostream& os, const sc_in<T>& a )
+{
+ return os << a->read();
+}
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+
+// called when elaboration is done
+
+template <class T>
+inline
+void
+sc_in<T>::end_of_elaboration()
+{
+ if( m_traces != 0 ) {
+ for( int i = 0; i < (int)m_traces->size(); ++ i ) {
+ sc_trace_params* p = (*m_traces)[i];
+ in_if_type* iface = DCAST<in_if_type*>( this->get_interface() );
+ sc_trace( p->tf, iface->read(), p->name );
+ }
+ remove_traces();
+ }
+}
+
+
+// called by sc_trace
+
+template <class T>
+inline
+void
+sc_in<T>::add_trace_internal( sc_trace_file* tf_, const std::string& name_ )
+const
+{
+ if( tf_ != 0 ) {
+ if( m_traces == 0 ) {
+ m_traces = new sc_trace_params_vec;
+ }
+ m_traces->push_back( new sc_trace_params( tf_, name_ ) );
+ }
+}
+
+template <class T>
+inline
+void
+sc_in<T>::add_trace( sc_trace_file* tf_, const std::string& name_ )
+const
+{
+ sc_deprecated_add_trace();
+ add_trace_internal(tf_, name_);
+}
+
+template <class T>
+inline
+void
+sc_in<T>::remove_traces() const
+{
+ if( m_traces != 0 ) {
+ for( int i = (int)m_traces->size() - 1; i >= 0; -- i ) {
+ delete (*m_traces)[i];
+ }
+ delete m_traces;
+ m_traces = 0;
+ }
+}
+
+
+// called by pbind (for internal use only)
+
+template <class T>
+inline
+int
+sc_in<T>::vbind( sc_interface& interface_ )
+{
+ return sc_port_b<if_type>::vbind( interface_ );
+}
+
+template <class T>
+inline
+int
+sc_in<T>::vbind( sc_port_base& parent_ )
+{
+ in_port_type* in_parent = DCAST<in_port_type*>( &parent_ );
+ if( in_parent != 0 ) {
+ sc_port_base::bind( *in_parent );
+ return 0;
+ }
+ inout_port_type* inout_parent = DCAST<inout_port_type*>( &parent_ );
+ if( inout_parent != 0 ) {
+ sc_port_base::bind( *inout_parent );
+ return 0;
+ }
+ // type mismatch
+ return 2;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_in<bool>
+//
+// Specialization of sc_in<T> for type bool.
+// ----------------------------------------------------------------------------
+
+template <>
+class sc_in<bool> :
+ public sc_port<sc_signal_in_if<bool>,1,SC_ONE_OR_MORE_BOUND>
+{
+public:
+
+ // typedefs
+
+ typedef bool data_type;
+
+ typedef sc_signal_in_if<data_type> if_type;
+ typedef sc_port<if_type,1,SC_ONE_OR_MORE_BOUND> base_type;
+ typedef sc_in<data_type> this_type;
+ typedef /* typename */ base_type::port_type base_port_type;
+
+ typedef if_type in_if_type;
+ typedef base_type in_port_type;
+ typedef sc_signal_inout_if<data_type> inout_if_type;
+ typedef sc_port<inout_if_type,1,SC_ONE_OR_MORE_BOUND> inout_port_type;
+
+public:
+
+ // constructors
+
+ sc_in()
+ : base_type(), m_traces( 0 ), m_change_finder_p(0),
+ m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+ explicit sc_in( const char* name_ )
+ : base_type( name_ ), m_traces( 0 ), m_change_finder_p(0),
+ m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+ explicit sc_in( const in_if_type& interface_ )
+ : base_type( CCAST<in_if_type&>( interface_ ) ), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+ sc_in( const char* name_, const in_if_type& interface_ )
+ : base_type( name_, CCAST<in_if_type&>( interface_ ) ), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+ explicit sc_in( in_port_type& parent_ )
+ : base_type( parent_ ), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+ sc_in( const char* name_, in_port_type& parent_ )
+ : base_type( name_, parent_ ), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+ explicit sc_in( inout_port_type& parent_ )
+ : base_type(), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ { sc_port_base::bind( parent_ ); }
+
+ sc_in( const char* name_, inout_port_type& parent_ )
+ : base_type( name_ ), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ { sc_port_base::bind( parent_ ); }
+
+ sc_in( this_type& parent_ )
+ : base_type( parent_ ), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+#if defined(TESTING)
+ sc_in( const this_type& parent_ )
+ : base_type( *(in_if_type*)parent_.get_interface() ) , m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+#endif
+
+ sc_in( const char* name_, this_type& parent_ )
+ : base_type( name_, parent_ ), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+
+ // destructor
+
+ virtual ~sc_in()
+ {
+ remove_traces();
+ delete m_change_finder_p;
+ delete m_neg_finder_p;
+ delete m_pos_finder_p;
+ }
+
+
+ // bind to in interface
+
+ SC_VIRTUAL_ void bind( const in_if_type& interface_ )
+ { sc_port_base::bind( CCAST<in_if_type&>( interface_ ) ); }
+
+ SC_VIRTUAL_ void bind( in_if_type& interface_ )
+ { this->bind( CCAST<const in_if_type&>( interface_ ) ); }
+
+ void operator () ( const in_if_type& interface_ )
+ { this->bind( interface_ ); }
+
+
+ // bind to parent in port
+
+ SC_VIRTUAL_ void bind( in_port_type& parent_ )
+ { sc_port_base::bind( parent_ ); }
+
+ void operator () ( in_port_type& parent_ )
+ { this->bind( parent_ ); }
+
+
+ // bind to parent inout port
+
+ SC_VIRTUAL_ void bind( inout_port_type& parent_ )
+ { sc_port_base::bind( parent_ ); }
+
+ void operator () ( inout_port_type& parent_ )
+ { this->bind( parent_ ); }
+
+
+ // interface access shortcut methods
+
+ // get the default event
+
+ const sc_event& default_event() const
+ { return (*this)->default_event(); }
+
+
+ // get the value changed event
+
+ const sc_event& value_changed_event() const
+ { return (*this)->value_changed_event(); }
+
+ // get the positive edge event
+
+ const sc_event& posedge_event() const
+ { return (*this)->posedge_event(); }
+
+ // get the negative edge event
+
+ const sc_event& negedge_event() const
+ { return (*this)->negedge_event(); }
+
+
+ // read the current value
+
+ const data_type& read() const
+ { return (*this)->read(); }
+
+ operator const data_type& () const
+ { return (*this)->read(); }
+
+
+ // use for positive edge sensitivity
+
+ sc_event_finder& pos() const
+ {
+ if ( !m_pos_finder_p )
+ {
+ m_pos_finder_p = new sc_event_finder_t<in_if_type>(
+ *this, &in_if_type::posedge_event );
+ }
+ return *m_pos_finder_p;
+ }
+
+ // use for negative edge sensitivity
+
+ sc_event_finder& neg() const
+ {
+ if ( !m_neg_finder_p )
+ {
+ m_neg_finder_p = new sc_event_finder_t<in_if_type>(
+ *this, &in_if_type::negedge_event );
+ }
+ return *m_neg_finder_p;
+ }
+
+
+ // was there a value changed event?
+
+ bool event() const
+ { return (*this)->event(); }
+
+ // was there a positive edge event?
+
+ bool posedge() const
+ { return (*this)->posedge(); }
+
+ // was there a negative edge event?
+
+ bool negedge() const
+ { return (*this)->negedge(); }
+
+ // (other) event finder method(s)
+
+ sc_event_finder& value_changed() const
+ {
+ if ( !m_change_finder_p )
+ {
+ m_change_finder_p = new sc_event_finder_t<in_if_type>(
+ *this, &in_if_type::value_changed_event );
+ }
+ return *m_change_finder_p;
+ }
+
+
+ // called when elaboration is done
+ /* WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
+ /* MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
+
+ virtual void end_of_elaboration();
+
+ virtual const char* kind() const
+ { return "sc_in"; }
+
+
+ void add_trace( sc_trace_file*, const std::string& ) const;
+
+ // called by sc_trace
+ void add_trace_internal( sc_trace_file*, const std::string& ) const;
+
+protected:
+
+ void remove_traces() const;
+
+ mutable sc_trace_params_vec* m_traces;
+
+protected:
+
+ // called by pbind (for internal use only)
+ virtual int vbind( sc_interface& );
+ virtual int vbind( sc_port_base& );
+
+ // implement virtual base_type port-binding function
+ // - avoids warnings on some compilers
+ // - should only be called, when using sc_port_b explicitly
+ // - errors are detected during elaboration
+
+ SC_VIRTUAL_ void bind( base_port_type& parent_ )
+ { sc_port_base::bind( parent_ ); }
+
+private:
+ mutable sc_event_finder* m_change_finder_p;
+ mutable sc_event_finder* m_neg_finder_p;
+ mutable sc_event_finder* m_pos_finder_p;
+
+private:
+
+ // disabled
+#if defined(TESTING)
+#else
+ sc_in( const this_type& );
+#endif
+ this_type& operator = ( const this_type& );
+
+#ifdef __GNUC__
+ // Needed to circumvent a problem in the g++-2.95.2 compiler:
+ // This unused variable forces the compiler to instantiate
+ // an object of T template so an implicit conversion from
+ // read() to a C++ intrinsic data type will work.
+ static data_type dummy;
+#endif
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_in<sc_dt::sc_logic>
+//
+// Specialization of sc_in<T> for type sc_dt::sc_logic.
+// ----------------------------------------------------------------------------
+
+template <>
+class sc_in<sc_dt::sc_logic>
+: public sc_port<sc_signal_in_if<sc_dt::sc_logic>,1,SC_ONE_OR_MORE_BOUND>
+{
+public:
+
+ // typedefs
+
+ typedef sc_dt::sc_logic data_type;
+
+ typedef sc_signal_in_if<data_type> if_type;
+ typedef sc_port<if_type,1,SC_ONE_OR_MORE_BOUND> base_type;
+ typedef sc_in<data_type> this_type;
+ typedef /* typename */ base_type::port_type base_port_type;
+
+ typedef if_type in_if_type;
+ typedef base_type in_port_type;
+ typedef sc_signal_inout_if<data_type> inout_if_type;
+ typedef sc_port<inout_if_type,1,SC_ONE_OR_MORE_BOUND> inout_port_type;
+
+public:
+
+ // constructors
+
+ sc_in()
+ : base_type(), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+ explicit sc_in( const char* name_ )
+ : base_type( name_ ), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+ explicit sc_in( const in_if_type& interface_ )
+ : base_type( CCAST<in_if_type&>( interface_ ) ), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+ sc_in( const char* name_, const in_if_type& interface_ )
+ : base_type( name_, CCAST<in_if_type&>( interface_ ) ), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+ explicit sc_in( in_port_type& parent_ )
+ : base_type( parent_ ), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+ sc_in( const char* name_, in_port_type& parent_ )
+ : base_type( name_, parent_ ), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+ explicit sc_in( inout_port_type& parent_ )
+ : base_type(), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ { sc_port_base::bind( parent_ ); }
+
+ sc_in( const char* name_, inout_port_type& parent_ )
+ : base_type( name_ ), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ { sc_port_base::bind( parent_ ); }
+
+ sc_in( this_type& parent_ )
+ : base_type( parent_ ), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+ sc_in( const char* name_, this_type& parent_ )
+ : base_type( name_, parent_ ), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+
+ // destructor
+
+ virtual ~sc_in()
+ {
+ remove_traces();
+ delete m_change_finder_p;
+ delete m_neg_finder_p;
+ delete m_pos_finder_p;
+ }
+
+
+ // bind to in interface
+
+ SC_VIRTUAL_ void bind( const in_if_type& interface_ )
+ { sc_port_base::bind( CCAST<in_if_type&>( interface_ ) ); }
+
+ SC_VIRTUAL_ void bind( in_if_type& interface_ )
+ { this->bind( CCAST<const in_if_type&>( interface_ ) ); }
+
+ void operator () ( const in_if_type& interface_ )
+ { this->bind( interface_ ); }
+
+
+ // bind to parent in port
+
+ SC_VIRTUAL_ void bind( in_port_type& parent_ )
+ { sc_port_base::bind( parent_ ); }
+
+ void operator () ( in_port_type& parent_ )
+ { this->bind( parent_ ); }
+
+
+ // bind to parent inout port
+
+ SC_VIRTUAL_ void bind( inout_port_type& parent_ )
+ { sc_port_base::bind( parent_ ); }
+
+ void operator () ( inout_port_type& parent_ )
+ { this->bind( parent_ ); }
+
+
+ // interface access shortcut methods
+
+ // get the default event
+
+ const sc_event& default_event() const
+ { return (*this)->default_event(); }
+
+
+ // get the value changed event
+
+ const sc_event& value_changed_event() const
+ { return (*this)->value_changed_event(); }
+
+ // get the positive edge event
+
+ const sc_event& posedge_event() const
+ { return (*this)->posedge_event(); }
+
+ // get the negative edge event
+
+ const sc_event& negedge_event() const
+ { return (*this)->negedge_event(); }
+
+
+ // read the current value
+
+ const data_type& read() const
+ { return (*this)->read(); }
+
+ operator const data_type& () const
+ { return (*this)->read(); }
+
+
+ // use for positive edge sensitivity
+
+ sc_event_finder& pos() const
+ {
+ if ( !m_pos_finder_p )
+ {
+ m_pos_finder_p = new sc_event_finder_t<in_if_type>(
+ *this, &in_if_type::posedge_event );
+ }
+ return *m_pos_finder_p;
+ }
+
+ // use for negative edge sensitivity
+
+ sc_event_finder& neg() const
+ {
+ if ( !m_neg_finder_p )
+ {
+ m_neg_finder_p = new sc_event_finder_t<in_if_type>(
+ *this, &in_if_type::negedge_event );
+ }
+ return *m_neg_finder_p;
+ }
+
+
+ // was there a value changed event?
+
+ bool event() const
+ { return (*this)->event(); }
+
+ // was there a positive edge event?
+
+ bool posedge() const
+ { return (*this)->posedge(); }
+
+ // was there a negative edge event?
+
+ bool negedge() const
+ { return (*this)->negedge(); }
+
+ // (other) event finder method(s)
+
+ sc_event_finder& value_changed() const
+ {
+ if ( !m_change_finder_p )
+ {
+ m_change_finder_p = new sc_event_finder_t<in_if_type>(
+ *this, &in_if_type::value_changed_event );
+ }
+ return *m_change_finder_p;
+ }
+
+
+ // called when elaboration is done
+ /* WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
+ /* MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
+
+ virtual void end_of_elaboration();
+
+ virtual const char* kind() const
+ { return "sc_in"; }
+
+
+ void add_trace( sc_trace_file*, const std::string& ) const;
+
+ // called by sc_trace
+ void add_trace_internal( sc_trace_file*, const std::string& ) const;
+
+protected:
+
+ void remove_traces() const;
+
+ mutable sc_trace_params_vec* m_traces;
+
+protected:
+
+ // called by pbind (for internal use only)
+ virtual int vbind( sc_interface& );
+ virtual int vbind( sc_port_base& );
+
+ // implement virtual base_type port-binding function
+ // - avoids warnings on some compilers
+ // - should only be called, when using sc_port_b explicitly
+ // - errors are detected during elaboration
+
+ SC_VIRTUAL_ void bind( base_port_type& parent_ )
+ { sc_port_base::bind( parent_ ); }
+
+private:
+ mutable sc_event_finder* m_change_finder_p;
+ mutable sc_event_finder* m_neg_finder_p;
+ mutable sc_event_finder* m_pos_finder_p;
+
+private:
+
+ // disabled
+ sc_in( const this_type& );
+ this_type& operator = ( const this_type& );
+
+#ifdef __GNUC__
+ // Needed to circumvent a problem in the g++-2.95.2 compiler:
+ // This unused variable forces the compiler to instantiate
+ // an object of T template so an implicit conversion from
+ // read() to a C++ intrinsic data type will work.
+ static data_type dummy;
+#endif
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_inout<T>
+//
+// The sc_signal<T> input/output port class.
+// ----------------------------------------------------------------------------
+
+template <class T>
+class sc_inout
+: public sc_port<sc_signal_inout_if<T>,1,SC_ONE_OR_MORE_BOUND>
+{
+public:
+
+ // typedefs
+
+ typedef T data_type;
+
+ typedef sc_signal_inout_if<data_type> if_type;
+ typedef sc_port<if_type,1,SC_ONE_OR_MORE_BOUND> base_type;
+ typedef sc_inout<data_type> this_type;
+
+ typedef sc_signal_in_if<data_type> in_if_type;
+ typedef sc_port<in_if_type,1,SC_ONE_OR_MORE_BOUND> in_port_type;
+ typedef if_type inout_if_type;
+ typedef base_type inout_port_type;
+
+public:
+
+ // constructors
+
+ sc_inout()
+ : base_type(), m_init_val( 0 ), m_traces( 0 ),
+ m_change_finder_p(0)
+ {}
+
+ explicit sc_inout( const char* name_ )
+ : base_type( name_ ), m_init_val( 0 ), m_traces( 0 ),
+ m_change_finder_p(0)
+ {}
+
+ explicit sc_inout( inout_if_type& interface_ )
+ : base_type( interface_ ), m_init_val( 0 ), m_traces( 0 ),
+ m_change_finder_p(0)
+ {}
+
+ sc_inout( const char* name_, inout_if_type& interface_ )
+ : base_type( name_, interface_ ), m_init_val( 0 ), m_traces( 0 ),
+ m_change_finder_p(0)
+ {}
+
+ explicit sc_inout( inout_port_type& parent_ )
+ : base_type( parent_ ), m_init_val( 0 ), m_traces( 0 ),
+ m_change_finder_p(0)
+ {}
+
+ sc_inout( const char* name_, inout_port_type& parent_ )
+ : base_type( name_, parent_ ), m_init_val( 0 ), m_traces( 0 ),
+ m_change_finder_p(0)
+ {}
+
+ sc_inout( this_type& parent_ )
+ : base_type( parent_ ), m_init_val( 0 ), m_traces( 0 ),
+ m_change_finder_p(0)
+ {}
+
+ sc_inout( const char* name_, this_type& parent_ )
+ : base_type( name_, parent_ ), m_init_val( 0 ), m_traces( 0 ),
+ m_change_finder_p(0)
+ {}
+
+
+ // destructor
+
+ virtual ~sc_inout();
+
+
+ // interface access shortcut methods
+
+ // get the default event
+
+ const sc_event& default_event() const
+ { return (*this)->default_event(); }
+
+
+ // get the value changed event
+
+ const sc_event& value_changed_event() const
+ { return (*this)->value_changed_event(); }
+
+
+ // read the current value
+
+ const data_type& read() const
+ { return (*this)->read(); }
+
+ operator const data_type& () const
+ { return (*this)->read(); }
+
+
+ // was there a value changed event?
+
+ bool event() const
+ { return (*this)->event(); }
+
+
+ // write the new value
+
+ void write( const data_type& value_ )
+ { (*this)->write( value_ ); }
+
+ this_type& operator = ( const data_type& value_ )
+ { (*this)->write( value_ ); return *this; }
+
+ this_type& operator = ( const in_if_type& interface_ )
+ { (*this)->write( interface_.read() ); return *this; }
+
+ this_type& operator = ( const in_port_type& port_ )
+ { (*this)->write( port_->read() ); return *this; }
+
+ this_type& operator = ( const inout_port_type& port_ )
+ { (*this)->write( port_->read() ); return *this; }
+
+ this_type& operator = ( const this_type& port_ )
+ { (*this)->write( port_->read() ); return *this; }
+
+
+ // set initial value (can also be called when port is not bound yet)
+
+ void initialize( const data_type& value_ );
+
+ void initialize( const in_if_type& interface_ )
+ { initialize( interface_.read() ); }
+
+
+ // called when elaboration is done
+ /* WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
+ /* MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
+
+ virtual void end_of_elaboration();
+
+
+ // (other) event finder method(s)
+
+ sc_event_finder& value_changed() const
+ {
+ if ( !m_change_finder_p )
+ {
+ m_change_finder_p = new sc_event_finder_t<in_if_type>(
+ *this, &in_if_type::value_changed_event );
+ }
+ return *m_change_finder_p;
+ }
+
+ virtual const char* kind() const
+ { return "sc_inout"; }
+
+protected:
+
+ data_type* m_init_val;
+
+public:
+
+ // called by sc_trace
+ void add_trace_internal( sc_trace_file*, const std::string& ) const;
+
+ void add_trace( sc_trace_file*, const std::string& ) const;
+
+protected:
+
+ void remove_traces() const;
+
+ mutable sc_trace_params_vec* m_traces;
+
+private:
+ mutable sc_event_finder* m_change_finder_p;
+
+private:
+
+ // disabled
+ sc_inout( const this_type& );
+
+#ifdef __GNUC__
+ // Needed to circumvent a problem in the g++-2.95.2 compiler:
+ // This unused variable forces the compiler to instantiate
+ // an object of T template so an implicit conversion from
+ // read() to a C++ intrinsic data type will work.
+ static data_type dummy;
+#endif
+};
+
+template<typename T>
+::std::ostream& operator << ( ::std::ostream& os, const sc_inout<T>& a )
+{
+ return os << a->read();
+}
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+
+// destructor
+
+template <class T>
+inline
+sc_inout<T>::~sc_inout()
+{
+ delete m_change_finder_p;
+ delete m_init_val;
+ remove_traces();
+}
+
+
+// set initial value (can also be called when port is not bound yet)
+
+template <class T>
+inline
+void
+sc_inout<T>::initialize( const data_type& value_ )
+{
+ inout_if_type* iface = DCAST<inout_if_type*>( this->get_interface() );
+ if( iface != 0 ) {
+ iface->write( value_ );
+ } else {
+ if( m_init_val == 0 ) {
+ m_init_val = new data_type;
+ }
+ *m_init_val = value_;
+ }
+}
+
+
+// called when elaboration is done
+
+template <class T>
+inline
+void
+sc_inout<T>::end_of_elaboration()
+{
+ if( m_init_val != 0 ) {
+ write( *m_init_val );
+ delete m_init_val;
+ m_init_val = 0;
+ }
+ if( m_traces != 0 ) {
+ for( int i = 0; i < (int)m_traces->size(); ++ i ) {
+ sc_trace_params* p = (*m_traces)[i];
+ in_if_type* iface = DCAST<in_if_type*>( this->get_interface() );
+ sc_trace( p->tf, iface->read(), p->name );
+ }
+ remove_traces();
+ }
+}
+
+
+// called by sc_trace
+
+template <class T>
+inline
+void
+sc_inout<T>::add_trace_internal( sc_trace_file* tf_, const std::string& name_)
+const
+{
+ if( tf_ != 0 ) {
+ if( m_traces == 0 ) {
+ m_traces = new sc_trace_params_vec;
+ }
+ m_traces->push_back( new sc_trace_params( tf_, name_ ) );
+ }
+}
+
+template <class T>
+inline
+void
+sc_inout<T>::add_trace( sc_trace_file* tf_, const std::string& name_) const
+{
+ sc_deprecated_add_trace();
+ add_trace_internal(tf_, name_);
+}
+
+template <class T>
+inline
+void
+sc_inout<T>::remove_traces() const
+{
+ if( m_traces != 0 ) {
+ for( int i = m_traces->size() - 1; i >= 0; -- i ) {
+ delete (*m_traces)[i];
+ }
+ delete m_traces;
+ m_traces = 0;
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_inout<bool>
+//
+// Specialization of sc_inout<T> for type bool.
+// ----------------------------------------------------------------------------
+
+template <>
+class sc_inout<bool> :
+ public sc_port<sc_signal_inout_if<bool>,1,SC_ONE_OR_MORE_BOUND>
+{
+public:
+
+ // typedefs
+
+ typedef bool data_type;
+
+ typedef sc_signal_inout_if<data_type> if_type;
+ typedef sc_port<if_type,1,SC_ONE_OR_MORE_BOUND> base_type;
+ typedef sc_inout<data_type> this_type;
+
+ typedef sc_signal_in_if<data_type> in_if_type;
+ typedef sc_port<in_if_type,1,SC_ONE_OR_MORE_BOUND> in_port_type;
+ typedef if_type inout_if_type;
+ typedef base_type inout_port_type;
+
+public:
+
+ // constructors
+
+ sc_inout()
+ : base_type(), m_init_val( 0 ), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+ explicit sc_inout( const char* name_ )
+ : base_type( name_ ), m_init_val( 0 ), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+ explicit sc_inout( inout_if_type& interface_ )
+ : base_type( interface_ ), m_init_val( 0 ), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+ sc_inout( const char* name_, inout_if_type& interface_ )
+ : base_type( name_, interface_ ), m_init_val( 0 ), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+ explicit sc_inout( inout_port_type& parent_ )
+ : base_type( parent_ ), m_init_val( 0 ), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+ sc_inout( const char* name_, inout_port_type& parent_ )
+ : base_type( name_, parent_ ), m_init_val( 0 ), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+ sc_inout( this_type& parent_ )
+ : base_type( parent_ ), m_init_val( 0 ), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+ sc_inout( const char* name_, this_type& parent_ )
+ : base_type( name_, parent_ ), m_init_val( 0 ), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+
+ // destructor
+
+ virtual ~sc_inout();
+
+
+ // interface access shortcut methods
+
+ // get the default event
+
+ const sc_event& default_event() const
+ { return (*this)->default_event(); }
+
+
+ // get the value changed event
+
+ const sc_event& value_changed_event() const
+ { return (*this)->value_changed_event(); }
+
+ // get the positive edge event
+
+ const sc_event& posedge_event() const
+ { return (*this)->posedge_event(); }
+
+ // get the negative edge event
+
+ const sc_event& negedge_event() const
+ { return (*this)->negedge_event(); }
+
+
+ // read the current value
+
+ const data_type& read() const
+ { return (*this)->read(); }
+
+ operator const data_type& () const
+ { return (*this)->read(); }
+
+
+ // use for positive edge sensitivity
+
+ sc_event_finder& pos() const
+ {
+ if ( !m_pos_finder_p )
+ {
+ m_pos_finder_p = new sc_event_finder_t<in_if_type>(
+ *this, &in_if_type::posedge_event );
+ }
+ return *m_pos_finder_p;
+ }
+
+ // use for negative edge sensitivity
+
+ sc_event_finder& neg() const
+ {
+ if ( !m_neg_finder_p )
+ {
+ m_neg_finder_p = new sc_event_finder_t<in_if_type>(
+ *this, &in_if_type::negedge_event );
+ }
+ return *m_neg_finder_p;
+ }
+
+
+ // was there a value changed event?
+
+ bool event() const
+ { return (*this)->event(); }
+
+ // was there a positive edge event?
+
+ bool posedge() const
+ { return (*this)->posedge(); }
+
+ // was there a negative edge event?
+
+ bool negedge() const
+ { return (*this)->negedge(); }
+
+ // write the new value
+
+ void write( const data_type& value_ )
+ { (*this)->write( value_ ); }
+
+ this_type& operator = ( const data_type& value_ )
+ { (*this)->write( value_ ); return *this; }
+
+ this_type& operator = ( const in_if_type& interface_ )
+ { (*this)->write( interface_.read() ); return *this; }
+
+ this_type& operator = ( const in_port_type& port_ )
+ { (*this)->write( port_->read() ); return *this; }
+
+ this_type& operator = ( const inout_port_type& port_ )
+ { (*this)->write( port_->read() ); return *this; }
+
+ this_type& operator = ( const this_type& port_ )
+ { (*this)->write( port_->read() ); return *this; }
+
+
+ // set initial value (can also be called when port is not bound yet)
+
+ void initialize( const data_type& value_ );
+
+ void initialize( const in_if_type& interface_ )
+ { initialize( interface_.read() ); }
+
+
+ // called when elaboration is done
+ /* WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
+ /* MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
+
+ virtual void end_of_elaboration();
+
+
+ // (other) event finder method(s)
+
+ sc_event_finder& value_changed() const
+ {
+ if ( !m_change_finder_p )
+ {
+ m_change_finder_p = new sc_event_finder_t<in_if_type>(
+ *this, &in_if_type::value_changed_event );
+ }
+ return *m_change_finder_p;
+ }
+
+ virtual const char* kind() const
+ { return "sc_inout"; }
+
+protected:
+
+ data_type* m_init_val;
+
+public:
+
+ // called by sc_trace
+ void add_trace_internal( sc_trace_file*, const std::string& ) const;
+
+ void add_trace( sc_trace_file*, const std::string& ) const;
+
+protected:
+
+ void remove_traces() const;
+
+ mutable sc_trace_params_vec* m_traces;
+
+private:
+ mutable sc_event_finder* m_change_finder_p;
+ mutable sc_event_finder* m_neg_finder_p;
+ mutable sc_event_finder* m_pos_finder_p;
+
+private:
+
+ // disabled
+ sc_inout( const this_type& );
+
+#ifdef __GNUC__
+ // Needed to circumvent a problem in the g++-2.95.2 compiler:
+ // This unused variable forces the compiler to instantiate
+ // an object of T template so an implicit conversion from
+ // read() to a C++ intrinsic data type will work.
+ static data_type dummy;
+#endif
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_inout<sc_dt::sc_logic>
+//
+// Specialization of sc_inout<T> for type sc_dt::sc_logic.
+// ----------------------------------------------------------------------------
+
+template <>
+class sc_inout<sc_dt::sc_logic>
+: public sc_port<sc_signal_inout_if<sc_dt::sc_logic>,1,SC_ONE_OR_MORE_BOUND>
+{
+public:
+
+ // typedefs
+
+ typedef sc_dt::sc_logic data_type;
+
+ typedef sc_signal_inout_if<data_type> if_type;
+ typedef sc_port<if_type,1,SC_ONE_OR_MORE_BOUND> base_type;
+ typedef sc_inout<data_type> this_type;
+
+ typedef sc_signal_in_if<data_type> in_if_type;
+ typedef sc_port<in_if_type,1,SC_ONE_OR_MORE_BOUND> in_port_type;
+ typedef if_type inout_if_type;
+ typedef base_type inout_port_type;
+
+public:
+
+ // constructors
+
+ sc_inout()
+ : base_type(), m_init_val( 0 ), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+ explicit sc_inout( const char* name_ )
+ : base_type( name_ ), m_init_val( 0 ), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+ explicit sc_inout( inout_if_type& interface_ )
+ : base_type( interface_ ), m_init_val( 0 ), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+ sc_inout( const char* name_, inout_if_type& interface_ )
+ : base_type( name_, interface_ ), m_init_val( 0 ), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+ explicit sc_inout( inout_port_type& parent_ )
+ : base_type( parent_ ), m_init_val( 0 ), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+ sc_inout( const char* name_, inout_port_type& parent_ )
+ : base_type( name_, parent_ ), m_init_val( 0 ), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+ sc_inout( this_type& parent_ )
+ : base_type( parent_ ), m_init_val( 0 ), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+ sc_inout( const char* name_, this_type& parent_ )
+ : base_type( name_, parent_ ), m_init_val( 0 ), m_traces( 0 ),
+ m_change_finder_p(0), m_neg_finder_p(0), m_pos_finder_p(0)
+ {}
+
+
+ // destructor
+
+ virtual ~sc_inout();
+
+
+ // interface access shortcut methods
+
+ // get the default event
+
+ const sc_event& default_event() const
+ { return (*this)->default_event(); }
+
+
+ // get the value changed event
+
+ const sc_event& value_changed_event() const
+ { return (*this)->value_changed_event(); }
+
+ // get the positive edge event
+
+ const sc_event& posedge_event() const
+ { return (*this)->posedge_event(); }
+
+ // get the negative edge event
+
+ const sc_event& negedge_event() const
+ { return (*this)->negedge_event(); }
+
+
+ // read the current value
+
+ const data_type& read() const
+ { return (*this)->read(); }
+
+ operator const data_type& () const
+ { return (*this)->read(); }
+
+
+ // use for positive edge sensitivity
+
+ sc_event_finder& pos() const
+ {
+ if ( !m_pos_finder_p )
+ {
+ m_pos_finder_p = new sc_event_finder_t<in_if_type>(
+ *this, &in_if_type::posedge_event );
+ }
+ return *m_pos_finder_p;
+ }
+
+ // use for negative edge sensitivity
+
+ sc_event_finder& neg() const
+ {
+ if ( !m_neg_finder_p )
+ {
+ m_neg_finder_p = new sc_event_finder_t<in_if_type>(
+ *this, &in_if_type::negedge_event );
+ }
+ return *m_neg_finder_p;
+ }
+
+
+ // was there a value changed event?
+
+ bool event() const
+ { return (*this)->event(); }
+
+ // was there a positive edge event?
+
+ bool posedge() const
+ { return (*this)->posedge(); }
+
+ // was there a negative edge event?
+
+ bool negedge() const
+ { return (*this)->negedge(); }
+
+ // write the new value
+
+ void write( const data_type& value_ )
+ { (*this)->write( value_ ); }
+
+ this_type& operator = ( const data_type& value_ )
+ { (*this)->write( value_ ); return *this; }
+
+ this_type& operator = ( const in_if_type& interface_ )
+ { (*this)->write( interface_.read() ); return *this; }
+
+ this_type& operator = ( const in_port_type& port_ )
+ { (*this)->write( port_->read() ); return *this; }
+
+ this_type& operator = ( const inout_port_type& port_ )
+ { (*this)->write( port_->read() ); return *this; }
+
+ this_type& operator = ( const this_type& port_ )
+ { (*this)->write( port_->read() ); return *this; }
+
+
+ // set initial value (can also be called when port is not bound yet)
+
+ void initialize( const data_type& value_ );
+
+ void initialize( const in_if_type& interface_ )
+ { initialize( interface_.read() ); }
+
+
+ // called when elaboration is done
+ /* WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
+ /* MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
+
+ virtual void end_of_elaboration();
+
+
+ // (other) event finder method(s)
+
+ sc_event_finder& value_changed() const
+ {
+ if ( !m_change_finder_p )
+ {
+ m_change_finder_p = new sc_event_finder_t<in_if_type>(
+ *this, &in_if_type::value_changed_event );
+ }
+ return *m_change_finder_p;
+ }
+
+ virtual const char* kind() const
+ { return "sc_inout"; }
+
+protected:
+
+ data_type* m_init_val;
+
+public:
+
+ // called by sc_trace
+ void add_trace_internal( sc_trace_file*, const std::string& ) const;
+
+ void add_trace( sc_trace_file*, const std::string& ) const;
+
+protected:
+
+ void remove_traces() const;
+
+ mutable sc_trace_params_vec* m_traces;
+
+private:
+ mutable sc_event_finder* m_change_finder_p;
+ mutable sc_event_finder* m_neg_finder_p;
+ mutable sc_event_finder* m_pos_finder_p;
+
+private:
+
+ // disabled
+ sc_inout( const this_type& );
+
+#ifdef __GNUC__
+ // Needed to circumvent a problem in the g++-2.95.2 compiler:
+ // This unused variable forces the compiler to instantiate
+ // an object of T template so an implicit conversion from
+ // read() to a C++ intrinsic data type will work.
+ static data_type dummy;
+#endif
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_out<T>
+//
+// The sc_signal<T> output port class.
+// ----------------------------------------------------------------------------
+
+// sc_out can also read from its port, hence no difference with sc_inout.
+// For debugging reasons, a class is provided instead of a define.
+
+template <class T>
+class sc_out
+: public sc_inout<T>
+{
+public:
+
+ // typedefs
+
+ typedef T data_type;
+
+ typedef sc_out<data_type> this_type;
+ typedef sc_inout<data_type> base_type;
+
+ typedef typename base_type::in_if_type in_if_type;
+ typedef typename base_type::in_port_type in_port_type;
+ typedef typename base_type::inout_if_type inout_if_type;
+ typedef typename base_type::inout_port_type inout_port_type;
+
+public:
+
+ // constructors
+
+ sc_out()
+ : base_type()
+ {}
+
+ explicit sc_out( const char* name_ )
+ : base_type( name_ )
+ {}
+
+ explicit sc_out( inout_if_type& interface_ )
+ : base_type( interface_ )
+ {}
+
+ sc_out( const char* name_, inout_if_type& interface_ )
+ : base_type( name_, interface_ )
+ {}
+
+ explicit sc_out( inout_port_type& parent_ )
+ : base_type( parent_ )
+ {}
+
+ sc_out( const char* name_, inout_port_type& parent_ )
+ : base_type( name_, parent_ )
+ {}
+
+ sc_out( this_type& parent_ )
+ : base_type( parent_ )
+ {}
+
+ sc_out( const char* name_, this_type& parent_ )
+ : base_type( name_, parent_ )
+ {}
+
+
+ // destructor (does nothing)
+
+ virtual ~sc_out()
+ {}
+
+
+ // write the new value
+
+ this_type& operator = ( const data_type& value_ )
+ { (*this)->write( value_ ); return *this; }
+
+ this_type& operator = ( const in_if_type& interface_ )
+ { (*this)->write( interface_.read() ); return *this; }
+
+ this_type& operator = ( const in_port_type& port_ )
+ { (*this)->write( port_->read() ); return *this; }
+
+ this_type& operator = ( const inout_port_type& port_ )
+ { (*this)->write( port_->read() ); return *this; }
+
+ this_type& operator = ( const this_type& port_ )
+ { (*this)->write( port_->read() ); return *this; }
+
+ virtual const char* kind() const
+ { return "sc_out"; }
+
+private:
+
+ // disabled
+ sc_out( const this_type& );
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+
+// ----------------------------------------------------------------------------
+// FUNCTION : sc_trace
+// ----------------------------------------------------------------------------
+
+template <class T>
+inline
+void
+sc_trace(sc_trace_file* tf, const sc_in<T>& port, const std::string& name)
+{
+ const sc_signal_in_if<T>* iface = 0;
+ if (sc_get_curr_simcontext()->elaboration_done() )
+ {
+ iface = DCAST<const sc_signal_in_if<T>*>( port.get_interface() );
+ }
+
+ if ( iface )
+ sc_trace( tf, iface->read(), name );
+ else
+ port.add_trace_internal( tf, name );
+}
+
+template <class T>
+inline
+void
+sc_trace( sc_trace_file* tf, const sc_inout<T>& port,
+ const std::string& name )
+{
+ const sc_signal_in_if<T>* iface = 0;
+ if (sc_get_curr_simcontext()->elaboration_done() )
+ {
+ iface =DCAST<const sc_signal_in_if<T>*>( port.get_interface() );
+ }
+
+ if ( iface )
+ sc_trace( tf, iface->read(), name );
+ else
+ port.add_trace_internal( tf, name );
+}
+
+} // namespace sc_core
+
+#undef SC_VIRTUAL_
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Jason Elbaum, Motorola, Inc., 2001-11-12
+ Description of Modification: Added a static, private, otherwise
+ unused data member to the sc_in
+ and sc_inout classes to address
+ a bug in the GNU compiler *only*.
+ This works around a bug in g++ 2.95.2
+ regarding implicit casting from a
+ templated class to a C++ intrinsic type.
+
+ *****************************************************************************/
+//$Log: sc_signal_ports.h,v $
+//Revision 1.10 2011/08/29 18:04:32 acg
+// Philipp A. Hartmann: miscellaneous clean ups.
+//
+//Revision 1.9 2011/08/26 20:45:43 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+//Revision 1.8 2011/08/07 19:08:01 acg
+// Andy Goodrich: moved logs to end of file so line number synching works
+// better between versions.
+//
+//Revision 1.7 2011/08/07 18:53:09 acg
+// Philipp A. Hartmann: add virtual instances of the bind function for
+// base classes to eliminate warning messages for clang platforms.
+//
+//Revision 1.6 2011/04/02 00:03:23 acg
+// Andy Goodrich: catch the other bind()'s that I missed in Philipp's update.
+//
+//Revision 1.5 2011/04/01 22:33:31 acg
+// Philipp A. Harmann: Use const interface signature to implement non-const
+// interface signature for virtual bind(...).
+//
+//Revision 1.4 2011/03/30 16:46:10 acg
+// Andy Goodrich: added a signature and removed a virtual specification
+// to eliminate warnings with certain compilers.
+//
+//Revision 1.3 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+//Revision 1.2 2011/01/20 16:52:15 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+//Revision 1.1.1.1 2006/12/15 20:20:04 acg
+//SystemC 2.3
+//
+//Revision 1.11 2006/04/18 23:36:50 acg
+// Andy Goodrich: made add_trace_internal public until I can figure out
+// how to do a friend specification for sc_trace in an environment where
+// there are partial template and full template specifications for its
+// arguments.
+//
+//Revision 1.10 2006/04/18 18:01:26 acg
+// Andy Goodrich: added an add_trace_internal() method to the various port
+// classes so that sc_trace has something to call that won't emit an
+// IEEE 1666 deprecation message.
+//
+//Revision 1.9 2006/03/13 20:19:44 acg
+// Andy Goodrich: changed sc_event instances into pointers to sc_event instances
+// that are allocated as needed. This saves considerable storage for large
+// numbers of signals, etc.
+//
+//Revision 1.8 2006/02/02 23:42:37 acg
+// Andy Goodrich: implemented a much better fix to the sc_event_finder
+// proliferation problem. This new version allocates only a single event
+// finder for each port for each type of event, e.g., pos(), neg(), and
+// value_change(). The event finder persists as long as the port does,
+// which is what the LRM dictates. Because only a single instance is
+// allocated for each event type per port there is not a potential
+// explosion of storage as was true in the 2.0.1/2.1 versions.
+//
+//Revision 1.7 2006/02/02 21:38:12 acg
+// Andy Goodrich: fix to the comment log.
+//
+//Revision 1.4 2006/01/24 20:46:32 acg
+//Andy Goodrich: changes to eliminate use of deprecated features. For instance,
+//using notify(SC_ZERO_TIME) in place of notify_delayed().
+//
+//Revision 1.3 2006/01/13 18:47:42 acg
+//Added $Log command so that CVS comments are reproduced in the source.
+//
+//Revision 1.2 2006/01/03 23:18:26 acg
+//Changed copyright to include 2006.
+//
+//Revision 1.1.1.1 2005/12/19 23:16:43 acg
+//First check in of SystemC 2.1 into its own archive.
+//
+//Revision 1.18 2005/09/15 23:01:52 acg
+//Added std:: prefix to appropriate methods and types to get around
+//issues with the Edison Front End.
+//
+//Revision 1.17 2005/06/10 22:43:55 acg
+//Added CVS change log annotation.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_signal_resolved.cpp b/ext/systemc/src/sysc/communication/sc_signal_resolved.cpp
new file mode 100644
index 000000000..2b0aeca0b
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_signal_resolved.cpp
@@ -0,0 +1,152 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_signal_resolved.cpp -- The resolved signal class.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_process_handle.h"
+#include "sysc/communication/sc_signal_resolved.h"
+
+namespace sc_core {
+
+// Note that we assume that two drivers driving the resolved signal to a 1 or
+// 0 is O.K. This might not be true for all technologies, but is certainly
+// true for CMOS, the predominant technology in use today.
+
+const sc_dt::sc_logic_value_t
+sc_logic_resolution_tbl[4][4] =
+{ // 0 1 Z X
+ { sc_dt::Log_0, sc_dt::Log_X, sc_dt::Log_0, sc_dt::Log_X }, // 0
+ { sc_dt::Log_X, sc_dt::Log_1, sc_dt::Log_1, sc_dt::Log_X }, // 1
+ { sc_dt::Log_0, sc_dt::Log_1, sc_dt::Log_Z, sc_dt::Log_X }, // Z
+ { sc_dt::Log_X, sc_dt::Log_X, sc_dt::Log_X, sc_dt::Log_X } // X
+};
+
+
+// ----------------------------------------------------------------------------
+// FUNCTION : sc_logic_resolve
+//
+// Resolution function for sc_dt::sc_logic.
+// ----------------------------------------------------------------------------
+
+// resolves sc_dt::sc_logic values and returns the resolved value
+
+static void
+sc_logic_resolve( sc_dt::sc_logic& result_,
+ const std::vector<sc_dt::sc_logic>& values_ )
+{
+ int sz = values_.size();
+
+ assert( sz != 0 );
+
+ if( sz == 1 ) {
+ result_ = values_[0];
+ return;
+ }
+
+ sc_dt::sc_logic_value_t res = values_[0].value();
+ for( int i = sz - 1; i > 0 && res != sc_dt::Log_X; -- i ) {
+ res = sc_logic_resolution_tbl[res][values_[i].value()];
+ }
+ result_ = res;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_signal_resolved
+//
+// The resolved signal class.
+// ----------------------------------------------------------------------------
+
+// write the new value
+
+void
+sc_signal_resolved::write( const data_type& value_ )
+{
+ sc_process_b* cur_proc = sc_get_current_process_b();
+
+ bool value_changed = false;
+ bool found = false;
+
+ for( int i = m_proc_vec.size() - 1; i >= 0; -- i ) {
+ if( cur_proc == m_proc_vec[i] ) {
+ if( value_ != m_val_vec[i] ) {
+ m_val_vec[i] = value_;
+ value_changed = true;
+ }
+ found = true;
+ break;
+ }
+ }
+
+ if( ! found ) {
+ m_proc_vec.push_back( cur_proc );
+ m_val_vec.push_back( value_ );
+ value_changed = true;
+ }
+
+ if( value_changed ) {
+ request_update();
+ }
+}
+
+
+void
+sc_signal_resolved::update()
+{
+ sc_logic_resolve( m_new_val, m_val_vec );
+ base_type::update();
+}
+
+
+} // namespace sc_core
+
+// $Log: sc_signal_resolved.cpp,v $
+// Revision 1.5 2011/08/26 20:45:44 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.4 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+// Revision 1.3 2011/02/07 19:16:50 acg
+// Andy Goodrich: changes for handling multiple writers.
+//
+// Revision 1.2 2011/01/20 16:52:15 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.4 2006/03/21 00:00:27 acg
+// Andy Goodrich: changed name of sc_get_current_process_base() to be
+// sc_get_current_process_b() since its returning an sc_process_b instance.
+//
+// Revision 1.3 2006/01/13 18:47:42 acg
+// Added $Log command so that CVS comments are reproduced in the source.
+//
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_signal_resolved.h b/ext/systemc/src/sysc/communication/sc_signal_resolved.h
new file mode 100644
index 000000000..f5e8c714e
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_signal_resolved.h
@@ -0,0 +1,153 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_signal_resolved.h -- The resolved signal class.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_SIGNAL_RESOLVED_H
+#define SC_SIGNAL_RESOLVED_H
+
+
+#include "sysc/communication/sc_signal.h"
+
+namespace sc_core {
+
+class sc_process_b;
+
+extern const sc_dt::sc_logic_value_t sc_logic_resolution_tbl[4][4];
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_signal_resolved
+//
+// The resolved signal class.
+// ----------------------------------------------------------------------------
+
+class sc_signal_resolved
+: public sc_signal<sc_dt::sc_logic,SC_MANY_WRITERS>
+{
+public:
+
+ // typedefs
+
+ typedef sc_signal_resolved this_type;
+ typedef sc_signal<sc_dt::sc_logic,SC_MANY_WRITERS> base_type;
+ typedef sc_dt::sc_logic data_type;
+
+public:
+
+ // constructors
+
+ sc_signal_resolved() :
+ base_type( sc_gen_unique_name( "signal_resolved" ) ), m_proc_vec(),
+ m_val_vec()
+ {}
+
+ explicit sc_signal_resolved( const char* name_ ):
+ base_type( name_ ), m_proc_vec(), m_val_vec()
+ {}
+
+ sc_signal_resolved( const char* name_, const data_type & initial_value_ )
+ : base_type( name_, initial_value_ )
+ , m_proc_vec()
+ , m_val_vec()
+ {}
+
+ // interface methods
+
+ virtual void register_port( sc_port_base&, const char* )
+ {}
+
+
+ // write the new value
+ virtual void write( const data_type& );
+
+
+ // other methods
+
+ this_type& operator = ( const data_type& a )
+ { write( a ); return *this; }
+
+ this_type& operator = ( const this_type& a )
+ { write( a.read() ); return *this; }
+
+ virtual const char* kind() const
+ { return "sc_signal_resolved"; }
+
+protected:
+
+ virtual void update();
+
+protected:
+
+ std::vector<sc_process_b*> m_proc_vec; // processes writing this signal
+ std::vector<data_type> m_val_vec; // new values written this signal
+
+private:
+
+ // disabled
+ sc_signal_resolved( const this_type& );
+};
+
+} // namespace sc_core
+
+//$Log: sc_signal_resolved.h,v $
+//Revision 1.6 2011/08/26 20:45:44 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+//Revision 1.5 2011/08/24 22:05:36 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+//Revision 1.4 2011/04/19 02:36:26 acg
+// Philipp A. Hartmann: new aysnc_update and mutex support.
+//
+//Revision 1.3 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+//Revision 1.2 2011/01/20 16:52:15 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+//Revision 1.1.1.1 2006/12/15 20:20:04 acg
+//SystemC 2.3
+//
+//Revision 1.2 2006/01/03 23:18:26 acg
+//Changed copyright to include 2006.
+//
+//Revision 1.1.1.1 2005/12/19 23:16:43 acg
+//First check in of SystemC 2.1 into its own archive.
+//
+//Revision 1.10 2005/09/15 23:01:52 acg
+//Added std:: prefix to appropriate methods and types to get around
+//issues with the Edison Front End.
+//
+//Revision 1.9 2005/06/10 22:43:55 acg
+//Added CVS change log annotation.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_signal_resolved_ports.cpp b/ext/systemc/src/sysc/communication/sc_signal_resolved_ports.cpp
new file mode 100644
index 000000000..17da6396a
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_signal_resolved_ports.cpp
@@ -0,0 +1,107 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_signal_resolved_ports.cpp -- The sc_signal_resolved port classes.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-08-20
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include <cstdio>
+
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_process_handle.h"
+#include "sysc/communication/sc_communication_ids.h"
+#include "sysc/communication/sc_signal_resolved.h"
+#include "sysc/communication/sc_signal_resolved_ports.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_in_resolved
+//
+// The sc_signal_resolved input port class.
+// ----------------------------------------------------------------------------
+
+// called when elaboration is done
+
+void
+sc_in_resolved::end_of_elaboration()
+{
+ base_type::end_of_elaboration();
+ // check if bound channel is a resolved signal
+ if( DCAST<sc_signal_resolved*>( get_interface() ) == 0 ) {
+ char msg[BUFSIZ];
+ std::sprintf( msg, "%s (%s)", name(), kind() );
+ SC_REPORT_ERROR( SC_ID_RESOLVED_PORT_NOT_BOUND_, msg );
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_inout_resolved
+//
+// The sc_signal_resolved input/output port class.
+// ----------------------------------------------------------------------------
+
+// called when elaboration is done
+
+void
+sc_inout_resolved::end_of_elaboration()
+{
+ base_type::end_of_elaboration();
+ // check if bound channel is a resolved signal
+ if( DCAST<sc_signal_resolved*>( get_interface() ) == 0 ) {
+ char msg[BUFSIZ];
+ std::sprintf( msg, "%s (%s)", name(), kind() );
+ SC_REPORT_ERROR( SC_ID_RESOLVED_PORT_NOT_BOUND_, msg );
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_out_resolved
+//
+// The sc_signal_resolved output port class.
+// ----------------------------------------------------------------------------
+
+} // namespace sc_core
+
+// $Log: sc_signal_resolved_ports.cpp,v $
+// Revision 1.4 2011/08/26 20:45:44 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.3 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+// Revision 1.2 2011/02/07 19:16:50 acg
+// Andy Goodrich: changes for handling multiple writers.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:47:42 acg
+// Added $Log command so that CVS comments are reproduced in the source.
+//
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_signal_resolved_ports.h b/ext/systemc/src/sysc/communication/sc_signal_resolved_ports.h
new file mode 100644
index 000000000..6b0d777d7
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_signal_resolved_ports.h
@@ -0,0 +1,349 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_signal_resolved_ports.h -- The sc_signal_resolved port classes.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-08-20
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_SIGNAL_RESOLVED_PORTS_H
+#define SC_SIGNAL_RESOLVED_PORTS_H
+
+
+#include "sysc/communication/sc_signal_ports.h"
+#include "sysc/datatypes/bit/sc_logic.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_in_resolved
+//
+// The sc_signal_resolved input port class.
+// ----------------------------------------------------------------------------
+
+class sc_in_resolved
+ : public sc_in<sc_dt::sc_logic>
+{
+public:
+
+ // typedefs
+
+ typedef sc_dt::sc_logic data_type;
+
+ typedef sc_in_resolved this_type;
+ typedef sc_in<data_type> base_type;
+
+ typedef base_type::in_if_type in_if_type;
+ typedef base_type::in_port_type in_port_type;
+ typedef base_type::inout_port_type inout_port_type;
+
+public:
+
+ // constructors
+
+ sc_in_resolved()
+ : base_type()
+ {}
+
+ explicit sc_in_resolved( const char* name_ )
+ : base_type( name_ )
+ {}
+
+ explicit sc_in_resolved( const in_if_type& interface_ )
+ : base_type( interface_ )
+ {}
+
+ sc_in_resolved( const char* name_, const in_if_type& interface_ )
+ : base_type( name_, interface_ )
+ {}
+
+ explicit sc_in_resolved( in_port_type& parent_ )
+ : base_type( parent_ )
+ {}
+
+ sc_in_resolved( const char* name_, in_port_type& parent_ )
+ : base_type( name_, parent_ )
+ {}
+
+ explicit sc_in_resolved( inout_port_type& parent_ )
+ : base_type( parent_ )
+ {}
+
+ sc_in_resolved( const char* name_, inout_port_type& parent_ )
+ : base_type( name_, parent_ )
+ {}
+
+ sc_in_resolved( this_type& parent_ )
+ : base_type( parent_ )
+ {}
+
+ sc_in_resolved( const char* name_, this_type& parent_ )
+ : base_type( name_, parent_ )
+ {}
+
+
+ // destructor (does nothing)
+
+ virtual ~sc_in_resolved()
+ {}
+
+
+ // called when elaboration is done
+ /* WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
+ /* MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
+
+ virtual void end_of_elaboration();
+
+ virtual const char* kind() const
+ { return "sc_in_resolved"; }
+
+private:
+
+ // disabled
+ sc_in_resolved( const this_type& );
+ this_type& operator = ( const this_type& );
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_inout_resolved
+//
+// The sc_signal_resolved input/output port class.
+// ----------------------------------------------------------------------------
+
+class sc_inout_resolved
+ : public sc_inout<sc_dt::sc_logic>
+{
+public:
+
+ // typedefs
+
+ typedef sc_dt::sc_logic data_type;
+
+ typedef sc_inout_resolved this_type;
+ typedef sc_inout<data_type> base_type;
+
+ typedef base_type::in_if_type in_if_type;
+ typedef base_type::in_port_type in_port_type;
+ typedef base_type::inout_if_type inout_if_type;
+ typedef base_type::inout_port_type inout_port_type;
+
+public:
+
+ // constructors
+
+ sc_inout_resolved()
+ : base_type()
+ {}
+
+ explicit sc_inout_resolved( const char* name_ )
+ : base_type( name_ )
+ {}
+
+ explicit sc_inout_resolved( inout_if_type& interface_ )
+ : base_type( interface_ )
+ {}
+
+ sc_inout_resolved( const char* name_, inout_if_type& interface_ )
+ : base_type( name_, interface_ )
+ {}
+
+ explicit sc_inout_resolved( inout_port_type& parent_ )
+ : base_type( parent_ )
+ {}
+
+ sc_inout_resolved( const char* name_, inout_port_type& parent_ )
+ : base_type( name_, parent_ )
+ {}
+
+ sc_inout_resolved( this_type& parent_ )
+ : base_type( parent_ )
+ {}
+
+ sc_inout_resolved( const char* name_, this_type& parent_ )
+ : base_type( name_, parent_ )
+ {}
+
+
+ // destructor (does nothing)
+
+ virtual ~sc_inout_resolved()
+ {}
+
+
+ // write the new value
+
+ this_type& operator = ( const data_type& value_ )
+ { (*this)->write( value_ ); return *this; }
+
+ this_type& operator = ( const in_if_type& interface_ )
+ { (*this)->write( interface_.read() ); return *this; }
+
+ this_type& operator = ( const in_port_type& port_ )
+ { (*this)->write( port_->read() ); return *this; }
+
+ this_type& operator = ( const inout_port_type& port_ )
+ { (*this)->write( port_->read() ); return *this; }
+
+ this_type& operator = ( const this_type& port_ )
+ { (*this)->write( port_->read() ); return *this; }
+
+
+ // called when elaboration is done
+ /* WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
+ /* MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
+
+ virtual void end_of_elaboration();
+
+ virtual const char* kind() const
+ { return "sc_inout_resolved"; }
+
+private:
+
+ // disabled
+ sc_inout_resolved( const this_type& );
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_out_resolved
+//
+// The sc_signal_resolved output port class.
+// ----------------------------------------------------------------------------
+
+// sc_out_resolved can also read from its port, hence no difference with
+// sc_inout_resolved. For debugging reasons, a class is provided instead
+// of a typedef.
+
+class sc_out_resolved
+ : public sc_inout_resolved
+{
+public:
+
+ // typedefs
+
+ typedef sc_out_resolved this_type;
+ typedef sc_inout_resolved base_type;
+
+ typedef base_type::data_type data_type;
+
+ typedef base_type::in_if_type in_if_type;
+ typedef base_type::in_port_type in_port_type;
+ typedef base_type::inout_if_type inout_if_type;
+ typedef base_type::inout_port_type inout_port_type;
+
+public:
+
+ // constructors
+
+ sc_out_resolved()
+ : base_type()
+ {}
+
+ explicit sc_out_resolved( const char* name_ )
+ : base_type( name_ )
+ {}
+
+ explicit sc_out_resolved( inout_if_type& interface_ )
+ : base_type( interface_ )
+ {}
+
+ sc_out_resolved( const char* name_, inout_if_type& interface_ )
+ : base_type( name_, interface_ )
+ {}
+
+ explicit sc_out_resolved( inout_port_type& parent_ )
+ : base_type( parent_ )
+ {}
+
+ sc_out_resolved( const char* name_, inout_port_type& parent_ )
+ : base_type( name_, parent_ )
+ {}
+
+ sc_out_resolved( this_type& parent_ )
+ : base_type( parent_ )
+ {}
+
+ sc_out_resolved( const char* name_, this_type& parent_ )
+ : base_type( name_, parent_ )
+ {}
+
+
+ // destructor (does nothing)
+
+ virtual ~sc_out_resolved()
+ {}
+
+
+ // write the new value
+
+ this_type& operator = ( const data_type& value_ )
+ { (*this)->write( value_ ); return *this; }
+
+ this_type& operator = ( const in_if_type& interface_ )
+ { (*this)->write( interface_.read() ); return *this; }
+
+ this_type& operator = ( const in_port_type& port_ )
+ { (*this)->write( port_->read() ); return *this; }
+
+ this_type& operator = ( const inout_port_type& port_ )
+ { (*this)->write( port_->read() ); return *this; }
+
+ this_type& operator = ( const this_type& port_ )
+ { (*this)->write( port_->read() ); return *this; }
+
+ virtual const char* kind() const
+ { return "sc_out_resolved"; }
+
+private:
+
+ // disabled
+ sc_out_resolved( const this_type& );
+};
+
+} // namespace sc_core
+
+//$Log: sc_signal_resolved_ports.h,v $
+//Revision 1.3 2011/08/26 20:45:44 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+//Revision 1.2 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+//Revision 1.1.1.1 2006/12/15 20:20:04 acg
+//SystemC 2.3
+//
+//Revision 1.2 2006/01/03 23:18:26 acg
+//Changed copyright to include 2006.
+//
+//Revision 1.1.1.1 2005/12/19 23:16:43 acg
+//First check in of SystemC 2.1 into its own archive.
+//
+//Revision 1.9 2005/06/10 22:43:55 acg
+//Added CVS change log annotation.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_signal_rv.h b/ext/systemc/src/sysc/communication/sc_signal_rv.h
new file mode 100644
index 000000000..0d870e78e
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_signal_rv.h
@@ -0,0 +1,255 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_signal_rv.h -- The resolved vector signal class.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_SIGNAL_RV_H
+#define SC_SIGNAL_RV_H
+
+#include "sysc/communication/sc_signal.h"
+#include "sysc/datatypes/bit/sc_lv.h"
+
+namespace sc_core {
+
+class sc_process_b;
+
+
+// ----------------------------------------------------------------------------
+// CLASS sc_lv_resolve<W>
+//
+// Resolution function for sc_dt::sc_lv<W>.
+// ----------------------------------------------------------------------------
+
+extern const sc_dt::sc_logic_value_t sc_logic_resolution_tbl[4][4];
+
+
+template <int W>
+class sc_lv_resolve
+{
+public:
+
+ // resolves sc_dt::sc_lv<W> values and returns the resolved value
+ static void resolve(sc_dt::sc_lv<W>&, const std::vector<sc_dt::sc_lv<W>*>&);
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+// resolves sc_dt::sc_lv<W> values and returns the resolved value
+
+template <int W>
+inline
+void
+sc_lv_resolve<W>::resolve( sc_dt::sc_lv<W>& result_,
+ const std::vector<sc_dt::sc_lv<W>*>& values_ )
+{
+ int sz = values_.size();
+
+ assert( sz != 0 );
+
+ if( sz == 1 ) {
+ result_ = *values_[0];
+ return;
+ }
+
+ for( int j = result_.length() - 1; j >= 0; -- j ) {
+ sc_dt::sc_logic_value_t res = (*values_[0])[j].value();
+ for( int i = sz - 1; i > 0 && res != 3; -- i ) {
+ res = sc_logic_resolution_tbl[res][(*values_[i])[j].value()];
+ }
+ result_[j] = res;
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_signal_rv<W>
+//
+// The resolved vector signal class.
+// ----------------------------------------------------------------------------
+
+template <int W>
+class sc_signal_rv
+: public sc_signal<sc_dt::sc_lv<W>, SC_MANY_WRITERS>
+{
+public:
+
+ // typedefs
+
+ typedef sc_signal_rv<W> this_type;
+ typedef sc_signal<sc_dt::sc_lv<W>, SC_MANY_WRITERS> base_type;
+ typedef sc_dt::sc_lv<W> data_type;
+
+public:
+
+ // constructors
+
+ sc_signal_rv()
+ : base_type( sc_gen_unique_name( "signal_rv" ) )
+ {}
+
+ explicit sc_signal_rv( const char* name_ )
+ : base_type( name_ )
+ {}
+
+
+ // destructor
+ virtual ~sc_signal_rv();
+
+
+ // interface methods
+
+ virtual void register_port( sc_port_base&, const char* )
+ {}
+
+
+ // write the new value
+ virtual void write( const data_type& );
+
+
+ // other methods
+
+ this_type& operator = ( const data_type& a )
+ { write( a ); return *this; }
+
+ this_type& operator = ( const this_type& a )
+ { write( a.read() ); return *this; }
+
+ virtual const char* kind() const
+ { return "sc_signal_rv"; }
+
+protected:
+
+ virtual void update();
+
+protected:
+
+ std::vector<sc_process_b*> m_proc_vec; // processes writing this signal
+ std::vector<data_type*> m_val_vec; // new values written this signal
+
+private:
+
+ // disabled
+ sc_signal_rv( const this_type& );
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+
+// destructor
+
+template <int W>
+inline
+sc_signal_rv<W>::~sc_signal_rv()
+{
+ for( int i = m_val_vec.size() - 1; i >= 0; -- i ) {
+ delete m_val_vec[i];
+ }
+}
+
+
+// write the new value
+
+template <int W>
+inline
+void
+sc_signal_rv<W>::write( const data_type& value_ )
+{
+ sc_process_b* cur_proc = sc_get_current_process_b();
+
+ bool value_changed = false;
+ bool found = false;
+
+ for( int i = m_proc_vec.size() - 1; i >= 0; -- i ) {
+ if( cur_proc == m_proc_vec[i] ) {
+ if( value_ != *m_val_vec[i] ) {
+ *m_val_vec[i] = value_;
+ value_changed = true;
+ }
+ found = true;
+ break;
+ }
+ }
+
+ if( ! found ) {
+ m_proc_vec.push_back( cur_proc );
+ m_val_vec.push_back( new data_type( value_ ) );
+ value_changed = true;
+ }
+
+ if( value_changed ) {
+ this->request_update();
+ }
+}
+
+
+template <int W>
+inline
+void
+sc_signal_rv<W>::update()
+{
+ sc_lv_resolve<W>::resolve( this->m_new_val, m_val_vec );
+ base_type::update();
+}
+
+} // namespace sc_core
+
+//$Log: sc_signal_rv.h,v $
+//Revision 1.4 2011/08/26 20:45:44 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+//Revision 1.3 2011/04/19 02:36:26 acg
+// Philipp A. Hartmann: new aysnc_update and mutex support.
+//
+//Revision 1.2 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+//Revision 1.1.1.1 2006/12/15 20:20:04 acg
+//SystemC 2.3
+//
+//Revision 1.3 2006/03/21 00:00:27 acg
+// Andy Goodrich: changed name of sc_get_current_process_base() to be
+// sc_get_current_process_b() since its returning an sc_process_b instance.
+//
+//Revision 1.2 2006/01/03 23:18:26 acg
+//Changed copyright to include 2006.
+//
+//Revision 1.1.1.1 2005/12/19 23:16:43 acg
+//First check in of SystemC 2.1 into its own archive.
+//
+//Revision 1.10 2005/09/15 23:01:52 acg
+//Added std:: prefix to appropriate methods and types to get around
+//issues with the Edison Front End.
+//
+//Revision 1.9 2005/06/10 22:43:55 acg
+//Added CVS change log annotation.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_signal_rv_ports.h b/ext/systemc/src/sysc/communication/sc_signal_rv_ports.h
new file mode 100644
index 000000000..ee6d17b25
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_signal_rv_ports.h
@@ -0,0 +1,401 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_signal_rv_ports.h -- The resolved vector signal ports.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_SIGNAL_RV_PORTS_H
+#define SC_SIGNAL_RV_PORTS_H
+
+
+#include <cstdio>
+
+#include "sysc/communication/sc_communication_ids.h"
+#include "sysc/communication/sc_signal_ports.h"
+#include "sysc/communication/sc_signal_rv.h"
+#include "sysc/datatypes/bit/sc_lv.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_in_rv<W>
+//
+// The sc_signal_rv<W> input port class.
+// ----------------------------------------------------------------------------
+
+template <int W>
+class sc_in_rv
+ : public sc_in<sc_dt::sc_lv<W> >
+{
+public:
+
+ // typedefs
+
+ typedef sc_dt::sc_lv<W> data_type;
+
+ typedef sc_in_rv<W> this_type;
+ typedef sc_in<data_type> base_type;
+
+ typedef typename base_type::in_if_type in_if_type;
+ typedef typename base_type::in_port_type in_port_type;
+ typedef typename base_type::inout_port_type inout_port_type;
+
+public:
+
+ // constructors
+
+ sc_in_rv()
+ : base_type()
+ {}
+
+ explicit sc_in_rv( const char* name_ )
+ : base_type( name_ )
+ {}
+
+ explicit sc_in_rv( const in_if_type& interface_ )
+ : base_type( interface_ )
+ {}
+
+ sc_in_rv( const char* name_, const in_if_type& interface_ )
+ : base_type( name_, interface_ )
+ {}
+
+ explicit sc_in_rv( in_port_type& parent_ )
+ : base_type( parent_ )
+ {}
+
+ sc_in_rv( const char* name_, in_port_type& parent_ )
+ : base_type( name_, parent_ )
+ {}
+
+ explicit sc_in_rv( inout_port_type& parent_ )
+ : base_type( parent_ )
+ {}
+
+ sc_in_rv( const char* name_, inout_port_type& parent_ )
+ : base_type( name_, parent_ )
+ {}
+
+ sc_in_rv( this_type& parent_ )
+ : base_type( parent_ )
+ {}
+
+ sc_in_rv( const char* name_, this_type& parent_ )
+ : base_type( name_, parent_ )
+ {}
+
+
+ // destructor (does nothing)
+
+ virtual ~sc_in_rv()
+ {}
+
+
+ // called when elaboration is done
+ /* WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
+ /* MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
+
+ virtual void end_of_elaboration();
+
+ virtual const char* kind() const
+ { return "sc_in_rv"; }
+
+private:
+
+ // disabled
+ sc_in_rv( const this_type& );
+ this_type& operator = ( const this_type& );
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+
+// called when elaboration is done
+
+template <int W>
+void
+sc_in_rv<W>::end_of_elaboration()
+{
+ base_type::end_of_elaboration();
+ // check if bound channel is a resolved signal
+ if( DCAST<sc_signal_rv<W>*>( this->get_interface() ) == 0 ) {
+ char msg[BUFSIZ];
+ std::sprintf( msg, "%s (%s)", this->name(), kind() );
+ SC_REPORT_ERROR( SC_ID_RESOLVED_PORT_NOT_BOUND_, msg );
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_inout_rv<W>
+//
+// The sc_signal_rv<W> input/output port class.
+// ----------------------------------------------------------------------------
+
+template <int W>
+class sc_inout_rv
+ : public sc_inout<sc_dt::sc_lv<W> >
+{
+public:
+
+ // typedefs
+
+ typedef sc_dt::sc_lv<W> data_type;
+
+ typedef sc_inout_rv<W> this_type;
+ typedef sc_inout<data_type> base_type;
+
+ typedef typename base_type::in_if_type in_if_type;
+ typedef typename base_type::in_port_type in_port_type;
+ typedef typename base_type::inout_if_type inout_if_type;
+ typedef typename base_type::inout_port_type inout_port_type;
+
+public:
+
+ // constructors
+
+ sc_inout_rv()
+ : base_type()
+ {}
+
+ explicit sc_inout_rv( const char* name_ )
+ : base_type( name_ )
+ {}
+
+ explicit sc_inout_rv( inout_if_type& interface_ )
+ : base_type( interface_ )
+ {}
+
+ sc_inout_rv( const char* name_, inout_if_type& interface_ )
+ : base_type( name_, interface_ )
+ {}
+
+ explicit sc_inout_rv( inout_port_type& parent_ )
+ : base_type( parent_ )
+ {}
+
+ sc_inout_rv( const char* name_, inout_port_type& parent_ )
+ : base_type( name_, parent_ )
+ {}
+
+ sc_inout_rv( this_type& parent_ )
+ : base_type( parent_ )
+ {}
+
+ sc_inout_rv( const char* name_, this_type& parent_ )
+ : base_type( name_, parent_ )
+ {}
+
+
+ // destructor (does nothing)
+
+ virtual ~sc_inout_rv()
+ {}
+
+
+ // write the new value
+
+ this_type& operator = ( const data_type& value_ )
+ { (*this)->write( value_ ); return *this; }
+
+ this_type& operator = ( const in_if_type& interface_ )
+ { (*this)->write( interface_.read() ); return *this; }
+
+ this_type& operator = ( const in_port_type& port_ )
+ { (*this)->write( port_->read() ); return *this; }
+
+ this_type& operator = ( const inout_port_type& port_ )
+ { (*this)->write( port_->read() ); return *this; }
+
+ this_type& operator = ( const this_type& port_ )
+ { (*this)->write( port_->read() ); return *this; }
+
+
+ // called when elaboration is done
+ /* WHEN DEFINING THIS METHOD IN A DERIVED CLASS, */
+ /* MAKE SURE THAT THIS METHOD IS CALLED AS WELL. */
+
+ virtual void end_of_elaboration();
+
+ virtual const char* kind() const
+ { return "sc_inout_rv"; }
+
+private:
+
+ // disabled
+ sc_inout_rv( const this_type& );
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+
+// called when elaboration is done
+
+template <int W>
+void
+sc_inout_rv<W>::end_of_elaboration()
+{
+ base_type::end_of_elaboration();
+ // check if bound channel is a resolved signal
+ if( DCAST<sc_signal_rv<W>*>( this->get_interface() ) == 0 ) {
+ char msg[BUFSIZ];
+ std::sprintf( msg, "%s (%s)", this->name(), kind() );
+ SC_REPORT_ERROR( SC_ID_RESOLVED_PORT_NOT_BOUND_, msg );
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_out_rv<W>
+//
+// The sc_signal_rv<W> output port class.
+// ----------------------------------------------------------------------------
+
+// sc_out_rv can also read from its port, hence no difference with
+// sc_inout_rv. For debugging reasons, a class is provided instead
+// of a define.
+
+template <int W>
+class sc_out_rv
+ : public sc_inout_rv<W>
+{
+public:
+
+ // typedefs
+
+ typedef sc_out_rv<W> this_type;
+ typedef sc_inout_rv<W> base_type;
+
+ typedef typename base_type::data_type data_type;
+
+ typedef typename base_type::in_if_type in_if_type;
+ typedef typename base_type::in_port_type in_port_type;
+ typedef typename base_type::inout_if_type inout_if_type;
+ typedef typename base_type::inout_port_type inout_port_type;
+
+public:
+
+ // constructors
+
+ sc_out_rv()
+ : base_type()
+ {}
+
+ explicit sc_out_rv( const char* name_ )
+ : base_type( name_ )
+ {}
+
+ explicit sc_out_rv( inout_if_type& interface_ )
+ : base_type( interface_ )
+ {}
+
+ sc_out_rv( const char* name_, inout_if_type& interface_ )
+ : base_type( name_, interface_ )
+ {}
+
+ explicit sc_out_rv( inout_port_type& parent_ )
+ : base_type( parent_ )
+ {}
+
+ sc_out_rv( const char* name_, inout_port_type& parent_ )
+ : base_type( name_, parent_ )
+ {}
+
+ sc_out_rv( this_type& parent_ )
+ : base_type( parent_ )
+ {}
+
+ sc_out_rv( const char* name_, this_type& parent_ )
+ : base_type( name_, parent_ )
+ {}
+
+
+ // destructor (does nothing)
+
+ virtual ~sc_out_rv()
+ {}
+
+
+ // write the new value
+
+ this_type& operator = ( const data_type& value_ )
+ { (*this)->write( value_ ); return *this; }
+
+ this_type& operator = ( const in_if_type& interface_ )
+ { (*this)->write( interface_.read() ); return *this; }
+
+ this_type& operator = ( const in_port_type& port_ )
+ { (*this)->write( port_->read() ); return *this; }
+
+ this_type& operator = ( const inout_port_type& port_ )
+ { (*this)->write( port_->read() ); return *this; }
+
+ this_type& operator = ( const this_type& port_ )
+ { (*this)->write( port_->read() ); return *this; }
+
+ virtual const char* kind() const
+ { return "sc_out_rv"; }
+
+private:
+
+ // disabled
+ sc_out_rv( const this_type& );
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+} // namespace sc_core
+
+//$Log: sc_signal_rv_ports.h,v $
+//Revision 1.3 2011/08/26 20:45:44 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+//Revision 1.2 2011/02/18 20:23:45 acg
+// Andy Goodrich: Copyright update.
+//
+//Revision 1.1.1.1 2006/12/15 20:20:04 acg
+//SystemC 2.3
+//
+//Revision 1.2 2006/01/03 23:18:27 acg
+//Changed copyright to include 2006.
+//
+//Revision 1.1.1.1 2005/12/19 23:16:43 acg
+//First check in of SystemC 2.1 into its own archive.
+//
+//Revision 1.11 2005/09/15 23:01:52 acg
+//Added std:: prefix to appropriate methods and types to get around
+//issues with the Edison Front End.
+//
+//Revision 1.10 2005/06/10 22:43:56 acg
+//Added CVS change log annotation.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/communication/sc_writer_policy.h b/ext/systemc/src/sysc/communication/sc_writer_policy.h
new file mode 100644
index 000000000..93b80f861
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_writer_policy.h
@@ -0,0 +1,143 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_writer_policy.h -- The sc_signal<T> writer policy definition
+
+ Original Author: Philipp A: Hartmann, OFFIS
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_WRITER_POLICY_H_INCLUDED_
+#define SC_WRITER_POLICY_H_INCLUDED_
+
+#if !defined(SC_DEFAULT_WRITER_POLICY)
+# if defined(SC_NO_WRITE_CHECK)
+# define SC_DEFAULT_WRITER_POLICY SC_UNCHECKED_WRITERS
+# else
+# define SC_DEFAULT_WRITER_POLICY SC_ONE_WRITER
+# endif
+#endif
+
+namespace sc_core {
+
+class sc_object;
+class sc_port_base;
+extern
+void
+sc_signal_invalid_writer( sc_object* target, sc_object* first_writer,
+ sc_object* second_writer, bool check_delta );
+
+// SIGNAL WRITING POLICIES
+//
+// Note: if you add a new policy to the enum below you will need to add
+// an additional overload of sc_reset::reset_signal_is() for the sc_signal<bool>
+// instance. That will require changes to sysc/kernel/sc_reset.cpp and
+// sysc/kernel/sc_reset.h
+
+enum sc_writer_policy
+{
+ SC_ONE_WRITER = 0, ///< unique writer (from a unique port)
+ SC_MANY_WRITERS = 1, ///< allow multiple writers (with different ports)
+ SC_UNCHECKED_WRITERS = 3 ///< even allow delta cycle conflicts (non-standard)
+};
+
+// signal forward declaration
+template< typename T, sc_writer_policy POL = SC_DEFAULT_WRITER_POLICY >
+class sc_signal;
+
+template< sc_writer_policy >
+struct sc_writer_policy_check;
+
+struct sc_writer_policy_nocheck_write
+{
+ bool check_write( sc_object* /* target */, bool /* value_changed */ )
+ { return true; }
+ void update(){}
+};
+
+struct sc_writer_policy_check_write
+{
+ bool check_write( sc_object* target, bool value_changed );
+ void update(){}
+protected:
+ sc_writer_policy_check_write( bool check_delta = false )
+ : m_check_delta( check_delta ), m_writer_p(NULL) {}
+ const bool m_check_delta;
+ sc_object* m_writer_p;
+};
+
+struct sc_writer_policy_check_delta
+ : sc_writer_policy_check_write
+{
+
+ sc_writer_policy_check_delta()
+ : sc_writer_policy_check_write(true) {}
+
+ bool check_write( sc_object* target, bool value_changed )
+ {
+ if( value_changed )
+ return sc_writer_policy_check_write::check_write( target, true );
+ return true;
+ }
+
+ void update(){ m_writer_p = NULL; }
+};
+
+struct sc_writer_policy_nocheck_port
+{
+ bool check_port( sc_object*, sc_port_base*, bool )
+ { return true; }
+};
+
+struct sc_writer_policy_check_port
+{
+ bool check_port( sc_object* target, sc_port_base* port, bool is_output );
+
+protected:
+ sc_writer_policy_check_port() : m_output(0) {}
+ sc_port_base* m_output;
+};
+
+template<>
+struct sc_writer_policy_check<SC_ONE_WRITER>
+ : sc_writer_policy_check_port
+ , sc_writer_policy_check_write
+{};
+
+template<>
+struct sc_writer_policy_check<SC_MANY_WRITERS>
+ : sc_writer_policy_nocheck_port
+ , sc_writer_policy_check_delta
+{};
+
+template<>
+struct sc_writer_policy_check<SC_UNCHECKED_WRITERS>
+ : sc_writer_policy_nocheck_port
+ , sc_writer_policy_nocheck_write
+{};
+
+} // namespace sc_core
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/bit/sc_bit.cpp b/ext/systemc/src/sysc/datatypes/bit/sc_bit.cpp
new file mode 100644
index 000000000..5401eaead
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/bit/sc_bit.cpp
@@ -0,0 +1,138 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_bit.cpp -- Bit class.
+
+ Original Author: Gene Bushuyev, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// $Log: sc_bit.cpp,v $
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.6 2006/04/12 20:17:52 acg
+// Andy Goodrich: enabled deprecation message for sc_bit.
+//
+// Revision 1.5 2006/01/25 00:31:15 acg
+// Andy Goodrich: Changed over to use a standard message id of
+// SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
+//
+// Revision 1.4 2006/01/24 20:50:55 acg
+// Andy Goodrich: added warnings indicating that sc_bit is deprecated and that
+// the C bool data type should be used in its place.
+//
+// Revision 1.3 2006/01/13 18:53:53 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#include "sysc/datatypes/bit/sc_bit.h"
+#include "sysc/datatypes/bit/sc_bit_ids.h"
+#include "sysc/utils/sc_utils_ids.h"
+#include "sysc/datatypes/bit/sc_logic.h"
+
+#include <cstdio>
+
+
+namespace sc_dt
+{
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_bit
+//
+// Bit class.
+// Note: VSIA compatibility indicated.
+// ----------------------------------------------------------------------------
+
+// support methods
+
+void
+sc_bit::invalid_value( char c )
+{
+ char msg[BUFSIZ];
+ std::sprintf( msg, "sc_bit( '%c' )", c );
+ SC_REPORT_ERROR( sc_core::SC_ID_VALUE_NOT_VALID_, msg );
+}
+
+void
+sc_bit::invalid_value( int i )
+{
+ char msg[BUFSIZ];
+ std::sprintf( msg, "sc_bit( %d )", i );
+ SC_REPORT_ERROR( sc_core::SC_ID_VALUE_NOT_VALID_, msg );
+}
+
+
+// constructors
+
+sc_bit::sc_bit( const sc_logic& a ) // non-VSIA
+ : m_val( a.to_bool() )
+{
+ sc_deprecated_sc_bit();
+}
+
+
+// assignment operators
+
+sc_bit&
+sc_bit::operator = ( const sc_logic& b ) // non-VSIA
+{
+ return ( *this = sc_bit( b ) );
+}
+
+
+// other methods
+
+void
+sc_bit::scan( ::std::istream& is )
+{
+ bool b;
+ is >> b;
+ *this = b;
+}
+
+void sc_deprecated_sc_bit()
+{
+ static bool warn_sc_bit_deprecated=true;
+ if ( warn_sc_bit_deprecated )
+ {
+ warn_sc_bit_deprecated=false;
+ SC_REPORT_INFO(sc_core::SC_ID_IEEE_1666_DEPRECATION_,
+ "sc_bit is deprecated, use bool instead");
+ }
+}
+
+} // namespace sc_dt
+
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/bit/sc_bit.h b/ext/systemc/src/sysc/datatypes/bit/sc_bit.h
new file mode 100644
index 000000000..2703971b6
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/bit/sc_bit.h
@@ -0,0 +1,407 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_bit.h -- Bit class.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_bit.h,v $
+// Revision 1.2 2011/08/07 18:54:19 acg
+// Philipp A. Hartmann: remove friend function declarations that implement
+// code, and clean up how bit and logic operators are defined in general.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.6 2006/05/08 17:49:59 acg
+// Andy Goodrich: Added David Long's declarations for friend operators,
+// functions, and methods, to keep the Microsoft compiler happy.
+//
+// Revision 1.5 2006/04/12 20:17:52 acg
+// Andy Goodrich: enabled deprecation message for sc_bit.
+//
+// Revision 1.4 2006/01/24 20:50:55 acg
+// Andy Goodrich: added warnings indicating that sc_bit is deprecated and that
+// the C bool data type should be used in its place.
+//
+// Revision 1.3 2006/01/13 18:53:53 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#ifndef SC_BIT_H
+#define SC_BIT_H
+
+
+#include "sysc/datatypes/int/sc_nbdefs.h"
+#include "sysc/utils/sc_iostream.h"
+
+
+namespace sc_dt
+{
+
+// classes defined in this module
+class sc_bit;
+
+// forward class declarations
+class sc_logic;
+
+extern void sc_deprecated_sc_bit();
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_bit
+//
+// Bit class.
+// Note: VSIA compatibility indicated.
+// ----------------------------------------------------------------------------
+
+class sc_bit
+{
+ // support methods
+
+ static void invalid_value( char );
+ static void invalid_value( int );
+
+ static bool to_value( char c )
+ {
+ if( c != '0' && c != '1' ) {
+ invalid_value( c );
+ }
+ return ( c == '0' ? false : true );
+ }
+
+ static bool to_value( int i )
+ {
+ if( i != 0 && i != 1 ) {
+ invalid_value( i );
+ }
+ return ( i == 0 ? false : true );
+ }
+ static bool to_value( bool b )
+ { return b; }
+
+#define DEFN_TO_VALUE_T(tp) \
+ static bool to_value( tp i ) \
+ { return to_value( (int) i); }
+
+ DEFN_TO_VALUE_T(unsigned)
+ DEFN_TO_VALUE_T(long)
+ DEFN_TO_VALUE_T(unsigned long)
+ DEFN_TO_VALUE_T(int64)
+ DEFN_TO_VALUE_T(uint64)
+
+#undef DEFN_TO_VALUE_T
+
+public:
+
+ // constructors
+ // MANDATORY
+
+ sc_bit()
+ : m_val( false )
+ {
+ sc_deprecated_sc_bit();
+ }
+
+#define DEFN_CTOR_T(tp) \
+ explicit sc_bit( tp a ) \
+ : m_val( to_value(a) ) \
+ { sc_deprecated_sc_bit(); }
+
+ DEFN_CTOR_T(bool)
+ DEFN_CTOR_T(char)
+ DEFN_CTOR_T(int)
+ DEFN_CTOR_T(unsigned)
+ DEFN_CTOR_T(long)
+ DEFN_CTOR_T(unsigned long)
+ DEFN_CTOR_T(int64)
+ DEFN_CTOR_T(uint64)
+
+#undef DEFN_CTOR_T
+
+ explicit sc_bit( const sc_logic& a ); // non-VSIA
+
+
+ // copy constructor
+ // MANDATORY
+
+ sc_bit( const sc_bit& a )
+ : m_val( a.m_val )
+ {}
+
+
+ // destructor
+ // MANDATORY
+
+ ~sc_bit()
+ {}
+
+
+ // assignment operators
+ // MANDATORY
+
+ sc_bit& operator = ( const sc_bit& b )
+ { m_val = b.m_val; return *this; }
+
+#define DEFN_ASN_OP_T(op,tp) \
+ sc_bit& operator op( tp b ) \
+ { return ( *this op sc_bit( b ) ); }
+#define DEFN_ASN_OP(op) \
+ DEFN_ASN_OP_T(op,int) \
+ DEFN_ASN_OP_T(op,bool) \
+ DEFN_ASN_OP_T(op,char)
+
+ DEFN_ASN_OP(=)
+ DEFN_ASN_OP_T(=,int64)
+ DEFN_ASN_OP_T(=,uint64)
+ DEFN_ASN_OP_T(=,long)
+ DEFN_ASN_OP_T(=,unsigned long)
+
+ sc_bit& operator = ( const sc_logic& b ); // non-VSIA
+
+
+ // bitwise assignment operators
+
+ sc_bit& operator &= ( const sc_bit& b )
+ { m_val = ( m_val && b.m_val ); return *this; }
+
+ sc_bit& operator |= ( const sc_bit& b )
+ { m_val = ( m_val || b.m_val ); return *this; }
+
+ sc_bit& operator ^= ( const sc_bit& b )
+ { m_val = ( m_val != b.m_val ); return *this; }
+
+ DEFN_ASN_OP(&=)
+ DEFN_ASN_OP(|=)
+ DEFN_ASN_OP(^=)
+
+#undef DEFN_ASN_OP_T
+#undef DEFN_ASN_OP
+
+ // conversions
+ // MANDATORY
+
+ // implicit conversion to bool
+
+ operator bool () const
+ { return m_val; }
+
+ bool operator ! () const // non-VSIA
+ { return ! m_val; }
+
+
+ // explicit conversions
+
+ bool to_bool() const // non-VSIA
+ { return m_val; }
+
+ char to_char() const
+ { return ( m_val ? '1' : '0' ); }
+
+
+ // relational operators and functions
+
+ // MANDATORY
+
+ friend bool operator == ( const sc_bit& a, const sc_bit& b );
+ friend bool operator != ( const sc_bit& a, const sc_bit& b );
+
+ // bitwise operators and functions
+
+ // bitwise complement
+
+ // MANDATORY
+
+ friend const sc_bit operator ~ ( const sc_bit& a );
+
+ // RECOMMENDED
+
+ sc_bit& b_not()
+ { m_val = ( ! m_val ); return *this; }
+
+ // binary bit-wise operations
+
+ friend const sc_bit operator | ( const sc_bit& a, const sc_bit& b );
+ friend const sc_bit operator & ( const sc_bit& a, const sc_bit& b );
+ friend const sc_bit operator ^ ( const sc_bit& a, const sc_bit& b );
+
+ // other methods
+
+ void print( ::std::ostream& os = ::std::cout ) const
+ { os << to_bool(); }
+
+ void scan( ::std::istream& = ::std::cin );
+
+private:
+ bool m_val;
+};
+
+// ----------------------------------------------------------------------------
+// relational operators and functions
+
+#define DEFN_BIN_FUN_T(ret,fun,tp) \
+ inline ret fun( const sc_bit& a, tp b ) \
+ { return fun(a, sc_bit(b) ); } \
+ inline ret fun( tp b, const sc_bit& a ) \
+ { return fun( sc_bit(a), b ); }
+
+#define DEFN_BIN_FUN(ret,fun) \
+ DEFN_BIN_FUN_T(ret,fun,bool) \
+ DEFN_BIN_FUN_T(ret,fun,char) \
+ DEFN_BIN_FUN_T(ret,fun,int)
+
+// MANDATORY
+
+inline bool operator == ( const sc_bit& a, const sc_bit& b )
+ { return ( a.m_val == b.m_val ); }
+
+inline bool operator != ( const sc_bit& a, const sc_bit& b )
+ { return ( a.m_val != b.m_val ); }
+
+DEFN_BIN_FUN(bool,operator==)
+DEFN_BIN_FUN(bool,operator!=)
+
+// OPTIONAL
+
+inline bool equal( const sc_bit& a, const sc_bit& b )
+ { return ( a == b ); }
+
+inline bool not_equal( const sc_bit& a, const sc_bit& b )
+ { return ( a != b ); }
+
+DEFN_BIN_FUN(bool,equal)
+DEFN_BIN_FUN(bool,not_equal)
+
+// ----------------------------------------------------------------------------
+// bitwise operators and functions
+
+// bitwise complement
+
+ // MANDATORY
+
+ inline const sc_bit operator ~ ( const sc_bit& a )
+ { return sc_bit( ! a.m_val ); }
+
+
+ // OPTIONAL
+
+ inline const sc_bit b_not( const sc_bit& a )
+ { return ( ~ a ); }
+
+
+ // RECOMMENDED
+
+ inline void b_not( sc_bit& r, const sc_bit& a )
+ { r = ( ~ a ); }
+
+ // binary bit-wise operations
+
+ // MANDATORY
+
+ inline const sc_bit operator & ( const sc_bit& a, const sc_bit& b )
+ { return sc_bit( a.m_val && b.m_val ); }
+
+ inline const sc_bit operator | ( const sc_bit& a, const sc_bit& b )
+ { return sc_bit( a.m_val || b.m_val ); }
+
+ inline const sc_bit operator ^ ( const sc_bit& a, const sc_bit& b )
+ { return sc_bit( a.m_val != b.m_val ); }
+
+ DEFN_BIN_FUN(const sc_bit,operator&)
+ DEFN_BIN_FUN(const sc_bit,operator|)
+ DEFN_BIN_FUN(const sc_bit,operator^)
+
+ // OPTIONAL
+
+ inline const sc_bit b_and ( const sc_bit& a, const sc_bit& b )
+ { return a & b; }
+
+ inline const sc_bit b_or ( const sc_bit& a, const sc_bit& b )
+ { return a | b; }
+
+ inline const sc_bit b_xor ( const sc_bit& a, const sc_bit& b )
+ { return a ^ b; }
+
+ DEFN_BIN_FUN(const sc_bit,b_and)
+ DEFN_BIN_FUN(const sc_bit,b_or)
+ DEFN_BIN_FUN(const sc_bit,b_xor)
+
+ // RECOMMENDED
+
+#define DEFN_TRN_FUN_T(fun,tp) \
+ inline void fun( sc_bit& r, const sc_bit& a, tp b ) \
+ { r = fun( a, sc_bit(b) ); } \
+ inline void fun( sc_bit& r, tp a, const sc_bit& b ) \
+ { r = fun( sc_bit(a), b ); }
+
+#define DEFN_TRN_FUN(fun) \
+ inline void fun( sc_bit& r, const sc_bit& a, const sc_bit& b ) \
+ { r = fun( a , b ); } \
+ DEFN_TRN_FUN_T(fun,int) \
+ DEFN_TRN_FUN_T(fun,bool) \
+ DEFN_TRN_FUN_T(fun,char)
+
+ DEFN_TRN_FUN( b_and )
+ DEFN_TRN_FUN( b_or )
+ DEFN_TRN_FUN( b_xor )
+
+#undef DEFN_BIN_FUN_T
+#undef DEFN_BIN_FUN
+#undef DEFN_TRN_FUN_T
+#undef DEFN_TRN_FUN
+
+
+// ----------------------------------------------------------------------------
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, const sc_bit& a )
+{
+ a.print( os );
+ return os;
+}
+
+inline
+::std::istream&
+operator >> ( ::std::istream& is, sc_bit& a )
+{
+ a.scan( is );
+ return is;
+}
+
+} // namespace sc_dt
+
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/bit/sc_bit_ids.h b/ext/systemc/src/sysc/datatypes/bit/sc_bit_ids.h
new file mode 100644
index 000000000..0e77e9078
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/bit/sc_bit_ids.h
@@ -0,0 +1,106 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_bit_ids.h -- Report ids for the datatypes/bit code.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2002-01-17
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_bit_ids.h,v $
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.5 2006/01/25 00:31:15 acg
+// Andy Goodrich: Changed over to use a standard message id of
+// SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
+//
+// Revision 1.4 2006/01/24 20:50:55 acg
+// Andy Goodrich: added warnings indicating that sc_bit is deprecated and that
+// the C bool data type should be used in its place.
+//
+// Revision 1.3 2006/01/13 18:53:53 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#ifndef SC_BIT_IDS_H
+#define SC_BIT_IDS_H
+
+
+#include "sysc/utils/sc_report.h"
+
+
+// ----------------------------------------------------------------------------
+// Report ids (datatypes/bit)
+//
+// Report ids in the range of 200-299.
+// ----------------------------------------------------------------------------
+
+#ifndef SC_DEFINE_MESSAGE
+#define SC_DEFINE_MESSAGE(id,unused1,unused2) \
+ namespace sc_core { extern const char id[]; }
+namespace sc_core {
+ extern const char SC_ID_REGISTER_ID_FAILED_[]; // in sc_report_handler.cpp
+}
+#endif
+
+
+SC_DEFINE_MESSAGE( SC_ID_LENGTH_MISMATCH_, 200,
+ "length mismatch in bit/logic vector assignment" )
+SC_DEFINE_MESSAGE( SC_ID_INCOMPATIBLE_TYPES_, 201,
+ "incompatible types" )
+SC_DEFINE_MESSAGE( SC_ID_CANNOT_CONVERT_, 202,
+ "cannot perform conversion" )
+SC_DEFINE_MESSAGE( SC_ID_INCOMPATIBLE_VECTORS_, 203,
+ "incompatible vectors" )
+SC_DEFINE_MESSAGE( SC_ID_VALUE_NOT_VALID_, 204,
+ "value is not valid" )
+SC_DEFINE_MESSAGE( SC_ID_ZERO_LENGTH_, 205,
+ "zero length" )
+SC_DEFINE_MESSAGE( SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 206,
+ "vector contains 4-value logic" )
+SC_DEFINE_MESSAGE( SC_ID_SC_BV_CANNOT_CONTAIN_X_AND_Z_, 207,
+ "sc_bv cannot contain values X and Z" )
+SC_DEFINE_MESSAGE( SC_ID_VECTOR_TOO_LONG_, 208,
+ "vector is too long: truncated" )
+SC_DEFINE_MESSAGE( SC_ID_VECTOR_TOO_SHORT_, 209,
+ "vector is too short: 0-padded" )
+SC_DEFINE_MESSAGE( SC_ID_WRONG_VALUE_, 210,
+ "wrong value" )
+SC_DEFINE_MESSAGE( SC_ID_LOGIC_Z_TO_BOOL_, 211,
+ "sc_logic value 'Z' cannot be converted to bool" )
+SC_DEFINE_MESSAGE( SC_ID_LOGIC_X_TO_BOOL_, 212,
+ "sc_logic value 'X' cannot be converted to bool" )
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/bit/sc_bit_proxies.h b/ext/systemc/src/sysc/datatypes/bit/sc_bit_proxies.h
new file mode 100644
index 000000000..59d997181
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/bit/sc_bit_proxies.h
@@ -0,0 +1,3884 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_bit_proxies.h -- Proxy classes for vector data types.
+
+ Original Author: Gene Bushuyev, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_BIT_PROXIES_H
+#define SC_BIT_PROXIES_H
+
+
+#include "sysc/datatypes/bit/sc_bit_ids.h"
+#include "sysc/datatypes/bit/sc_proxy.h"
+
+
+namespace sc_dt
+{
+
+// classes defined in this module
+template <class X> class sc_bitref_r;
+template <class X> class sc_bitref;
+template <class X> class sc_subref_r;
+template <class X> class sc_subref;
+template <class X, class Y> class sc_concref_r;
+template <class X, class Y> class sc_concref;
+
+
+// ----------------------------------------------------------------------------
+// CLASS TEMPLATE : sc_bitref_r<T>
+//
+// Proxy class for sc_proxy bit selection (r-value only).
+// ----------------------------------------------------------------------------
+
+template <class T>
+class sc_bitref_r
+{
+ friend class sc_bv_base;
+ friend class sc_lv_base;
+
+public:
+
+ // typedefs
+
+ typedef typename T::traits_type traits_type;
+ typedef typename traits_type::bit_type bit_type;
+
+ // constructor
+
+ sc_bitref_r( const T& obj_, int index_ )
+ : m_obj( CCAST<T&>( obj_ ) ), m_index( index_ )
+ {}
+
+
+ // copy constructor
+
+ sc_bitref_r( const sc_bitref_r<T>& a )
+ : m_obj( a.m_obj ), m_index( a.m_index )
+ {}
+
+ // cloning
+
+ sc_bitref_r<T>* clone() const
+ { return new sc_bitref_r<T>( *this ); }
+
+
+ // bitwise operators and functions
+
+ // bitwise complement
+
+ const bit_type operator ~ () const
+ { return bit_type( sc_logic::not_table[value()] ); }
+
+
+ // implicit conversion to bit_type
+
+ operator const bit_type() const
+ { return bit_type( m_obj.get_bit( m_index ) ); }
+
+
+ // explicit conversions
+
+ sc_logic_value_t value() const
+ { return m_obj.get_bit( m_index ); }
+
+
+ bool is_01() const
+ { return sc_logic( value() ).is_01(); }
+
+ bool to_bool() const
+ { return sc_logic( value() ).to_bool(); }
+
+ char to_char() const
+ { return sc_logic( value() ).to_char(); }
+
+
+ // common methods
+
+ int length() const
+ { return 1; }
+
+ int size() const
+ { return ( (length() - 1) / SC_DIGIT_SIZE + 1 ); }
+
+ sc_logic_value_t get_bit( int n ) const;
+
+ sc_digit get_word( int i ) const;
+ sc_digit get_cword( int i ) const;
+
+
+ // other methods
+
+ void print( ::std::ostream& os = ::std::cout ) const
+ { os << to_char(); }
+
+protected:
+
+ T& m_obj;
+ int m_index;
+
+private:
+
+ // disabled
+ sc_bitref_r();
+ sc_bitref_r<T>& operator = ( const sc_bitref_r<T>& );
+};
+
+
+// bitwise operators and functions
+
+// bitwise and
+
+template <class T1, class T2>
+inline
+const sc_logic
+operator & ( const sc_bitref_r<T1>& a, const sc_bitref_r<T2>& b );
+
+
+// bitwise or
+
+template <class T1, class T2>
+inline
+const sc_logic
+operator | ( const sc_bitref_r<T1>& a, const sc_bitref_r<T2>& b );
+
+
+// bitwise xor
+
+template <class T1, class T2>
+inline
+const sc_logic
+operator ^ ( const sc_bitref_r<T1>& a, const sc_bitref_r<T2>& b );
+
+
+// relational operators and functions
+
+template <class T1, class T2>
+inline
+bool
+operator == ( const sc_bitref_r<T1>& a, const sc_bitref_r<T2>& b );
+
+template <class T1, class T2>
+inline
+bool
+operator != ( const sc_bitref_r<T1>& a, const sc_bitref_r<T2>& b );
+
+
+// r-value concatenation operators and functions
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> >
+operator , ( sc_bitref_r<T1>, sc_bitref_r<T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> >
+operator , ( sc_bitref_r<T1>, sc_subref_r<T2> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> >
+operator , ( sc_bitref_r<T1>, sc_concref_r<T2,T3> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,T2>
+operator , ( sc_bitref_r<T1>, const sc_proxy<T2>& );
+
+template <class T>
+inline
+sc_concref_r<sc_bitref_r<T>,sc_lv_base>
+operator , ( sc_bitref_r<T>, const char* );
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_bitref_r<T> >
+operator , ( const char*, sc_bitref_r<T> );
+
+template <class T>
+inline
+sc_concref_r<sc_bitref_r<T>,sc_lv_base>
+operator , ( sc_bitref_r<T>, const sc_logic& );
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_bitref_r<T> >
+operator , ( const sc_logic&, sc_bitref_r<T> );
+
+template <class T>
+inline
+sc_concref_r<sc_bitref_r<T>,sc_lv_base>
+operator , ( sc_bitref_r<T>, bool );
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_bitref_r<T> >
+operator , ( bool, sc_bitref_r<T> );
+
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> >
+concat( sc_bitref_r<T1>, sc_bitref_r<T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> >
+concat( sc_bitref_r<T1>, sc_subref_r<T2> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> >
+concat( sc_bitref_r<T1>, sc_concref_r<T2,T3> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,T2>
+concat( sc_bitref_r<T1>, const sc_proxy<T2>& );
+
+template <class T>
+inline
+sc_concref_r<sc_bitref_r<T>,sc_lv_base>
+concat( sc_bitref_r<T>, const char* );
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_bitref_r<T> >
+concat( const char*, sc_bitref_r<T> );
+
+template <class T>
+inline
+sc_concref_r<sc_bitref_r<T>,sc_lv_base>
+concat( sc_bitref_r<T>, const sc_logic& );
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_bitref_r<T> >
+concat( const sc_logic&, sc_bitref_r<T> );
+
+template <class T>
+inline
+sc_concref_r<sc_bitref_r<T>,sc_lv_base>
+concat( sc_bitref_r<T>, bool );
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_bitref_r<T> >
+concat( bool, sc_bitref_r<T> );
+
+
+#ifdef SC_DT_MIXED_COMMA_OPERATORS
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> >
+operator , ( sc_bitref_r<T1>, sc_bitref<T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> >
+operator , ( sc_bitref<T1>, sc_bitref_r<T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> >
+operator , ( sc_bitref_r<T1>, sc_subref<T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> >
+operator , ( sc_bitref<T1>, sc_subref_r<T2> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> >
+operator , ( sc_bitref_r<T1>, sc_concref<T2,T3> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> >
+operator , ( sc_bitref<T1>, sc_concref_r<T2,T3> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,T2>
+operator , ( sc_bitref<T1>, const sc_proxy<T2>& );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,T2>
+operator , ( sc_bitref_r<T1>, sc_proxy<T2>& );
+
+template <class T>
+inline
+sc_concref_r<sc_bitref_r<T>,sc_lv_base>
+operator , ( sc_bitref<T>, const char* );
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_bitref_r<T> >
+operator , ( const char*, sc_bitref<T> );
+
+template <class T>
+inline
+sc_concref_r<sc_bitref_r<T>,sc_lv_base>
+operator , ( sc_bitref<T>, const sc_logic& );
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_bitref_r<T> >
+operator , ( const sc_logic&, sc_bitref<T> );
+
+template <class T>
+inline
+sc_concref_r<sc_bitref_r<T>,sc_lv_base>
+operator , ( sc_bitref<T>, bool );
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_bitref_r<T> >
+operator , ( bool, sc_bitref<T> );
+
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> >
+concat( sc_bitref_r<T1>, sc_bitref<T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> >
+concat( sc_bitref<T1>, sc_bitref_r<T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> >
+concat( sc_bitref_r<T1>, sc_subref<T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> >
+concat( sc_bitref<T1>, sc_subref_r<T2> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> >
+concat( sc_bitref_r<T1>, sc_concref<T2,T3> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> >
+concat( sc_bitref<T1>, sc_concref_r<T2,T3> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,T2>
+concat( sc_bitref<T1>, const sc_proxy<T2>& );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,T2>
+concat( sc_bitref_r<T1>, sc_proxy<T2>& );
+
+template <class T>
+inline
+sc_concref_r<sc_bitref_r<T>,sc_lv_base>
+concat( sc_bitref<T>, const char* );
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_bitref_r<T> >
+concat( const char*, sc_bitref<T> );
+
+template <class T>
+inline
+sc_concref_r<sc_bitref_r<T>,sc_lv_base>
+concat( sc_bitref<T>, const sc_logic& );
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_bitref_r<T> >
+concat( const sc_logic&, sc_bitref<T> );
+
+template <class T>
+inline
+sc_concref_r<sc_bitref_r<T>,sc_lv_base>
+concat( sc_bitref<T>, bool );
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_bitref_r<T> >
+concat( bool, sc_bitref<T> );
+
+#endif
+
+
+// ----------------------------------------------------------------------------
+// CLASS TEMPLATE : sc_bitref<X>
+//
+// Proxy class for sc_proxy bit selection (r-value and l-value).
+// ----------------------------------------------------------------------------
+
+template <class X>
+class sc_bitref
+ : public sc_bitref_r<X>
+{
+ friend class sc_bv_base;
+ friend class sc_lv_base;
+
+public:
+
+ // constructor
+
+ sc_bitref( X& obj_, int index_ )
+ : sc_bitref_r<X>( obj_, index_ )
+ {}
+
+
+ // copy constructor
+
+ sc_bitref( const sc_bitref<X>& a )
+ : sc_bitref_r<X>( a )
+ {}
+
+
+ // cloning
+
+ sc_bitref<X>* clone() const
+ { return new sc_bitref<X>( *this ); }
+
+
+ // assignment operators
+
+ sc_bitref<X>& operator = ( const sc_bitref_r<X>& a );
+ sc_bitref<X>& operator = ( const sc_bitref<X>& a );
+
+ sc_bitref<X>& operator = ( const sc_logic& a )
+ { this->m_obj.set_bit( this->m_index, a.value() ); return *this; }
+
+ sc_bitref<X>& operator = ( sc_logic_value_t v )
+ { *this = sc_logic( v ); return *this; }
+
+ sc_bitref<X>& operator = ( bool a )
+ { *this = sc_logic( a ); return *this; }
+
+ sc_bitref<X>& operator = ( char a )
+ { *this = sc_logic( a ); return *this; }
+
+ sc_bitref<X>& operator = ( int a )
+ { *this = sc_logic( a ); return *this; }
+
+ sc_bitref<X>& operator = ( const sc_bit& a )
+ { *this = sc_logic( a ); return *this; }
+
+
+ // bitwise assignment operators
+
+ sc_bitref<X>& operator &= ( const sc_bitref_r<X>& a );
+ sc_bitref<X>& operator &= ( const sc_logic& a );
+
+ sc_bitref<X>& operator &= ( sc_logic_value_t v )
+ { *this &= sc_logic( v ); return *this; }
+
+ sc_bitref<X>& operator &= ( bool a )
+ { *this &= sc_logic( a ); return *this; }
+
+ sc_bitref<X>& operator &= ( char a )
+ { *this &= sc_logic( a ); return *this; }
+
+ sc_bitref<X>& operator &= ( int a )
+ { *this &= sc_logic( a ); return *this; }
+
+
+ sc_bitref<X>& operator |= ( const sc_bitref_r<X>& a );
+ sc_bitref<X>& operator |= ( const sc_logic& a );
+
+ sc_bitref<X>& operator |= ( sc_logic_value_t v )
+ { *this |= sc_logic( v ); return *this; }
+
+ sc_bitref<X>& operator |= ( bool a )
+ { *this |= sc_logic( a ); return *this; }
+
+ sc_bitref<X>& operator |= ( char a )
+ { *this |= sc_logic( a ); return *this; }
+
+ sc_bitref<X>& operator |= ( int a )
+ { *this |= sc_logic( a ); return *this; }
+
+
+ sc_bitref<X>& operator ^= ( const sc_bitref_r<X>& a );
+ sc_bitref<X>& operator ^= ( const sc_logic& a );
+
+ sc_bitref<X>& operator ^= ( sc_logic_value_t v )
+ { *this ^= sc_logic( v ); return *this; }
+
+ sc_bitref<X>& operator ^= ( bool a )
+ { *this ^= sc_logic( a ); return *this; }
+
+ sc_bitref<X>& operator ^= ( char a )
+ { *this ^= sc_logic( a ); return *this; }
+
+ sc_bitref<X>& operator ^= ( int a )
+ { *this ^= sc_logic( a ); return *this; }
+
+
+ // bitwise operators and functions
+
+ // bitwise complement
+
+ sc_bitref<X>& b_not();
+
+
+ // common methods
+
+ void set_bit( int n, sc_logic_value_t value );
+
+ void set_word( int i, sc_digit w );
+ void set_cword( int i, sc_digit w );
+
+ void clean_tail()
+ { this->m_obj.clean_tail(); }
+
+
+ // other methods
+
+ void scan( ::std::istream& is = ::std::cin );
+
+private:
+
+ // disabled
+ sc_bitref();
+};
+
+
+// l-value concatenation operators and functions
+
+template <class T1, class T2>
+inline
+sc_concref<sc_bitref<T1>,sc_bitref<T2> >
+operator , ( sc_bitref<T1>, sc_bitref<T2> );
+
+template <class T1, class T2>
+inline
+sc_concref<sc_bitref<T1>,sc_subref<T2> >
+operator , ( sc_bitref<T1>, sc_subref<T2> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref<sc_bitref<T1>,sc_concref<T2,T3> >
+operator , ( sc_bitref<T1>, sc_concref<T2,T3> );
+
+template <class T1, class T2>
+inline
+sc_concref<sc_bitref<T1>,T2>
+operator , ( sc_bitref<T1>, sc_proxy<T2>& );
+
+
+template <class T1, class T2>
+inline
+sc_concref<sc_bitref<T1>,sc_bitref<T2> >
+concat( sc_bitref<T1>, sc_bitref<T2> );
+
+template <class T1, class T2>
+inline
+sc_concref<sc_bitref<T1>,sc_subref<T2> >
+concat( sc_bitref<T1>, sc_subref<T2> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref<sc_bitref<T1>,sc_concref<T2,T3> >
+concat( sc_bitref<T1>, sc_concref<T2,T3> );
+
+template <class T1, class T2>
+inline
+sc_concref<sc_bitref<T1>,T2>
+concat( sc_bitref<T1>, sc_proxy<T2>& );
+
+
+template <class T>
+::std::istream&
+operator >> ( ::std::istream&, sc_bitref<T> );
+
+
+// ----------------------------------------------------------------------------
+// CLASS TEMPLATE : sc_subref_r<X>
+//
+// Proxy class for sc_proxy part selection (r-value only).
+// ----------------------------------------------------------------------------
+
+template <class X>
+class sc_subref_r
+ : public sc_proxy<sc_subref_r<X> >
+{
+ void check_bounds();
+
+public:
+
+ // constructor
+
+ sc_subref_r( const X& obj_, int hi_, int lo_ )
+ : m_obj( CCAST<X&>( obj_ ) ), m_hi( hi_ ), m_lo( lo_ ), m_len( 0 )
+ { check_bounds(); }
+
+
+ // copy constructor
+
+ sc_subref_r( const sc_subref_r<X>& a )
+ : m_obj( a.m_obj ), m_hi( a.m_hi ), m_lo( a.m_lo ), m_len( a.m_len )
+ {}
+
+
+ // cloning
+
+ sc_subref_r<X>* clone() const
+ { return new sc_subref_r<X>( *this ); }
+
+
+ // common methods
+
+ int length() const
+ { return m_len; }
+
+ int size() const
+ { return ( (length() - 1) / SC_DIGIT_SIZE + 1 ); }
+
+ sc_logic_value_t get_bit( int n ) const;
+ void set_bit( int n, sc_logic_value_t value );
+
+ sc_digit get_word( int i )const;
+ void set_word( int i, sc_digit w );
+
+ sc_digit get_cword( int i ) const;
+ void set_cword( int i, sc_digit w );
+
+ void clean_tail()
+ { m_obj.clean_tail(); }
+
+
+ // other methods
+
+ bool is_01() const;
+
+ bool reversed() const
+ { return m_lo > m_hi; }
+
+protected:
+
+ X& m_obj;
+ int m_hi;
+ int m_lo;
+ int m_len;
+
+private:
+
+ // disabled
+ sc_subref_r();
+ sc_subref_r<X>& operator = ( const sc_subref_r<X>& );
+};
+
+
+// r-value concatenation operators and functions
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> >
+operator , ( sc_subref_r<T1>, sc_bitref_r<T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> >
+operator , ( sc_subref_r<T1>, sc_subref_r<T2> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> >
+operator , ( sc_subref_r<T1>, sc_concref_r<T2,T3> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,T2>
+operator , ( sc_subref_r<T1>, const sc_proxy<T2>& );
+
+template <class T>
+inline
+sc_concref_r<sc_subref_r<T>,sc_lv_base>
+operator , ( sc_subref_r<T>, const char* );
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_subref_r<T> >
+operator , ( const char*, sc_subref_r<T> );
+
+template <class T>
+inline
+sc_concref_r<sc_subref_r<T>,sc_lv_base>
+operator , ( sc_subref_r<T>, const sc_logic& );
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_subref_r<T> >
+operator , ( const sc_logic&, sc_subref_r<T> );
+
+template <class T>
+inline
+sc_concref_r<sc_subref_r<T>,sc_bv_base>
+operator , ( sc_subref_r<T>, bool );
+
+template <class T>
+inline
+sc_concref_r<sc_bv_base,sc_subref_r<T> >
+operator , ( bool, sc_subref_r<T> );
+
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> >
+concat( sc_subref_r<T1>, sc_bitref_r<T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> >
+concat( sc_subref_r<T1>, sc_subref_r<T2> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> >
+concat( sc_subref_r<T1>, sc_concref_r<T2,T3> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,T2>
+concat( sc_subref_r<T1>, const sc_proxy<T2>& );
+
+template <class T>
+inline
+sc_concref_r<sc_subref_r<T>,sc_lv_base>
+concat( sc_subref_r<T>, const char* );
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_subref_r<T> >
+concat( const char*, sc_subref_r<T> );
+
+template <class T>
+inline
+sc_concref_r<sc_subref_r<T>,sc_lv_base>
+concat( sc_subref_r<T>, const sc_logic& );
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_subref_r<T> >
+concat( const sc_logic&, sc_subref_r<T> );
+
+template <class T>
+inline
+sc_concref_r<sc_subref_r<T>,sc_bv_base>
+concat( sc_subref_r<T>, bool );
+
+template <class T>
+inline
+sc_concref_r<sc_bv_base,sc_subref_r<T> >
+concat( bool, sc_subref_r<T> );
+
+
+#ifdef SC_DT_MIXED_COMMA_OPERATORS
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> >
+operator , ( sc_subref_r<T1>, sc_bitref<T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> >
+operator , ( sc_subref<T1>, sc_bitref_r<T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> >
+operator , ( sc_subref_r<T1>, sc_subref<T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> >
+operator , ( sc_subref<T1>, sc_subref_r<T2> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> >
+operator , ( sc_subref_r<T1>, sc_concref<T2,T3> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> >
+operator , ( sc_subref<T1>, sc_concref_r<T2,T3> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,T2>
+operator , ( sc_subref<T1>, const sc_proxy<T2>& );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,T2>
+operator , ( sc_subref_r<T1>, sc_proxy<T2>& );
+
+template <class T>
+inline
+sc_concref_r<sc_subref_r<T>,sc_lv_base>
+operator , ( sc_subref<T>, const char* );
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_subref_r<T> >
+operator , ( const char*, sc_subref<T> );
+
+template <class T>
+inline
+sc_concref_r<sc_subref_r<T>,sc_lv_base>
+operator , ( sc_subref<T>, const sc_logic& );
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_subref_r<T> >
+operator , ( const sc_logic&, sc_subref<T> );
+
+template <class T>
+inline
+sc_concref_r<sc_subref_r<T>,sc_bv_base>
+operator , ( sc_subref<T>, bool );
+
+template <class T>
+inline
+sc_concref_r<sc_bv_base,sc_subref_r<T> >
+operator , ( bool, sc_subref<T> );
+
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> >
+concat( sc_subref_r<T1>, sc_bitref<T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> >
+concat( sc_subref<T1>, sc_bitref_r<T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> >
+concat( sc_subref_r<T1>, sc_subref<T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> >
+concat( sc_subref<T1>, sc_subref_r<T2> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> >
+concat( sc_subref_r<T1>, sc_concref<T2,T3> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> >
+concat( sc_subref<T1>, sc_concref_r<T2,T3> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,T2>
+concat( sc_subref<T1>, const sc_proxy<T2>& );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,T2>
+concat( sc_subref_r<T1>, sc_proxy<T2>& );
+
+template <class T>
+inline
+sc_concref_r<sc_subref_r<T>,sc_lv_base>
+concat( sc_subref<T>, const char* );
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_subref_r<T> >
+concat( const char*, sc_subref<T> );
+
+template <class T>
+inline
+sc_concref_r<sc_subref_r<T>,sc_lv_base>
+concat( sc_subref<T>, const sc_logic& );
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_subref_r<T> >
+concat( const sc_logic&, sc_subref<T> );
+
+template <class T>
+inline
+sc_concref_r<sc_subref_r<T>,sc_bv_base>
+concat( sc_subref<T>, bool );
+
+template <class T>
+inline
+sc_concref_r<sc_bv_base,sc_subref_r<T> >
+concat( bool, sc_subref<T> );
+
+#endif
+
+
+// ----------------------------------------------------------------------------
+// CLASS TEMPLATE : sc_subref<X>
+//
+// Proxy class for sc_proxy part selection (r-value and l-value).
+// ----------------------------------------------------------------------------
+
+template <class X>
+class sc_subref
+ : public sc_subref_r<X>
+{
+public:
+
+ // typedefs
+
+ typedef sc_subref_r<X> base_type;
+
+
+ // constructor
+
+ sc_subref( X& obj_, int hi_, int lo_ )
+ : sc_subref_r<X>( obj_, hi_, lo_ )
+ {}
+
+
+ // copy constructor
+
+ sc_subref( const sc_subref<X>& a )
+ : sc_subref_r<X>( a )
+ {}
+
+
+ // cloning
+
+ sc_subref<X>* clone() const
+ { return new sc_subref<X>( *this ); }
+
+
+ // assignment operators
+
+ template <class Y>
+ sc_subref<X>& operator = ( const sc_proxy<Y>& a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_subref<X>& operator = ( const sc_subref_r<X>& a );
+ sc_subref<X>& operator = ( const sc_subref<X>& a );
+
+ sc_subref<X>& operator = ( const char* a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_subref<X>& operator = ( const bool* a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_subref<X>& operator = ( const sc_logic* a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_subref<X>& operator = ( const sc_unsigned& a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_subref<X>& operator = ( const sc_signed& a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_subref<X>& operator = ( const sc_uint_base& a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_subref<X>& operator = ( const sc_int_base& a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_subref<X>& operator = ( unsigned long a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_subref<X>& operator = ( long a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_subref<X>& operator = ( unsigned int a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_subref<X>& operator = ( int a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_subref<X>& operator = ( uint64 a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_subref<X>& operator = ( int64 a )
+ { base_type::assign_( a ); return *this; }
+
+
+ // other methods
+
+ void scan( ::std::istream& = ::std::cin );
+
+private:
+
+ // disabled
+ sc_subref();
+};
+
+
+// l-value concatenation operators and functions
+
+template <class T1, class T2>
+inline
+sc_concref<sc_subref<T1>,sc_bitref<T2> >
+operator , ( sc_subref<T1>, sc_bitref<T2> );
+
+template <class T1, class T2>
+inline
+sc_concref<sc_subref<T1>,sc_subref<T2> >
+operator , ( sc_subref<T1>, sc_subref<T2> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref<sc_subref<T1>,sc_concref<T2,T3> >
+operator , ( sc_subref<T1>, sc_concref<T2,T3> );
+
+template <class T1, class T2>
+inline
+sc_concref<sc_subref<T1>,T2>
+operator , ( sc_subref<T1>, sc_proxy<T2>& );
+
+
+template <class T1, class T2>
+inline
+sc_concref<sc_subref<T1>,sc_bitref<T2> >
+concat( sc_subref<T1>, sc_bitref<T2> );
+
+template <class T1, class T2>
+inline
+sc_concref<sc_subref<T1>,sc_subref<T2> >
+concat( sc_subref<T1>, sc_subref<T2> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref<sc_subref<T1>,sc_concref<T2,T3> >
+concat( sc_subref<T1>, sc_concref<T2,T3> );
+
+template <class T1, class T2>
+inline
+sc_concref<sc_subref<T1>,T2>
+concat( sc_subref<T1>, sc_proxy<T2>& );
+
+
+template <class T>
+inline
+::std::istream&
+operator >> ( ::std::istream&, sc_subref<T> );
+
+
+// ----------------------------------------------------------------------------
+// CLASS TEMPLATE : sc_concref_r<X,Y>
+//
+// Proxy class for sc_proxy concatenation (r-value only).
+// ----------------------------------------------------------------------------
+
+template <class X, class Y>
+class sc_concref_r
+ : public sc_proxy<sc_concref_r<X,Y> >
+{
+public:
+
+ // constructor
+
+ sc_concref_r( const X& left_, const Y& right_, int delete_ = 0 )
+ : m_left( CCAST<X&>( left_ ) ), m_right( CCAST<Y&>( right_ ) ),
+ m_delete( delete_ ), m_refs( *new int( 1 ) )
+ {}
+
+
+ // copy constructor
+
+ sc_concref_r( const sc_concref_r<X,Y>& a )
+ : m_left( a.m_left ), m_right( a.m_right ),
+ m_delete( a.m_delete ), m_refs( a.m_refs )
+ { ++ m_refs; }
+
+
+ // destructor
+
+ virtual ~sc_concref_r();
+
+
+ // cloning
+
+ sc_concref_r<X,Y>* clone() const
+ { return new sc_concref_r<X,Y>( *this ); }
+
+
+ // common methods
+
+ int length() const
+ { return ( m_left.length() + m_right.length() ); }
+
+ int size() const
+ { return ( (length() - 1) / SC_DIGIT_SIZE + 1 ); }
+
+ sc_logic_value_t get_bit( int n ) const;
+ void set_bit( int n, sc_logic_value_t value );
+
+ sc_digit get_word( int i ) const;
+ void set_word( int i, sc_digit w );
+
+ sc_digit get_cword( int i ) const;
+ void set_cword( int i, sc_digit w );
+
+ void clean_tail()
+ { m_left.clean_tail(); m_right.clean_tail(); }
+
+
+ // other methods
+
+ bool is_01() const
+ { return ( m_left.is_01() && m_right.is_01() ); }
+
+protected:
+
+ X& m_left;
+ Y& m_right;
+ mutable int m_delete;
+ int& m_refs;
+
+private:
+
+ // disabled
+ sc_concref_r();
+ sc_concref_r<X,Y>& operator = ( const sc_concref_r<X,Y>& );
+};
+
+
+// r-value concatenation operators and functions
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> >
+operator , ( sc_concref_r<T1,T2>, sc_bitref_r<T3> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> >
+operator , ( sc_concref_r<T1,T2>, sc_subref_r<T3> );
+
+template <class T1, class T2, class T3, class T4>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> >
+operator , ( sc_concref_r<T1,T2>, sc_concref_r<T3,T4> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,T3>
+operator , ( sc_concref_r<T1,T2>, const sc_proxy<T3>& );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
+operator , ( sc_concref_r<T1,T2>, const char* );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
+operator , ( const char*, sc_concref_r<T1,T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
+operator , ( sc_concref_r<T1,T2>, const sc_logic& );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
+operator , ( const sc_logic&, sc_concref_r<T1,T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base>
+operator , ( sc_concref_r<T1,T2>, bool );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> >
+operator , ( bool, sc_concref_r<T1,T2> );
+
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> >
+concat( sc_concref_r<T1,T2>, sc_bitref_r<T3> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> >
+concat( sc_concref_r<T1,T2>, sc_subref_r<T3> );
+
+template <class T1, class T2, class T3, class T4>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> >
+concat( sc_concref_r<T1,T2>, sc_concref_r<T3,T4> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,T3>
+concat( sc_concref_r<T1,T2>, const sc_proxy<T3>& );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
+concat( sc_concref_r<T1,T2>, const char* );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
+concat( const char*, sc_concref_r<T1,T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
+concat( sc_concref_r<T1,T2>, const sc_logic& );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
+concat( const sc_logic&, sc_concref_r<T1,T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base>
+concat( sc_concref_r<T1,T2>, bool );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> >
+concat( bool, sc_concref_r<T1,T2> );
+
+
+#ifdef SC_DT_MIXED_COMMA_OPERATORS
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> >
+operator , ( sc_concref_r<T1,T2>, sc_bitref<T3> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> >
+operator , ( sc_concref<T1,T2>, sc_bitref_r<T3> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> >
+operator , ( sc_concref_r<T1,T2>, sc_subref<T3> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> >
+operator , ( sc_concref<T1,T2>, sc_subref_r<T3> );
+
+template <class T1, class T2, class T3, class T4>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> >
+operator , ( sc_concref_r<T1,T2>, sc_concref<T3,T4> );
+
+template <class T1, class T2, class T3, class T4>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> >
+operator , ( sc_concref<T1,T2>, sc_concref_r<T3,T4> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,T3>
+operator , ( sc_concref<T1,T2>, const sc_proxy<T3>& );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,T3>
+operator , ( sc_concref_r<T1,T2>, sc_proxy<T3>& );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
+operator , ( sc_concref<T1,T2>, const char* );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
+operator , ( const char*, sc_concref<T1,T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
+operator , ( sc_concref<T1,T2>, const sc_logic& );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
+operator , ( const sc_logic&, sc_concref<T1,T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base>
+operator , ( sc_concref<T1,T2>, bool );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> >
+operator , ( bool, sc_concref<T1,T2> );
+
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> >
+concat( sc_concref_r<T1,T2>, sc_bitref<T3> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> >
+concat( sc_concref<T1,T2>, sc_bitref_r<T3> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> >
+concat( sc_concref_r<T1,T2>, sc_subref<T3> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> >
+concat( sc_concref<T1,T2>, sc_subref_r<T3> );
+
+template <class T1, class T2, class T3, class T4>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> >
+concat( sc_concref_r<T1,T2>, sc_concref<T3,T4> );
+
+template <class T1, class T2, class T3, class T4>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> >
+concat( sc_concref<T1,T2>, sc_concref_r<T3,T4> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,T3>
+concat( sc_concref<T1,T2>, const sc_proxy<T3>& );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,T3>
+concat( sc_concref_r<T1,T2>, sc_proxy<T3>& );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
+concat( sc_concref<T1,T2>, const char* );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
+concat( const char*, sc_concref<T1,T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
+concat( sc_concref<T1,T2>, const sc_logic& );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
+concat( const sc_logic&, sc_concref<T1,T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base>
+concat( sc_concref<T1,T2>, bool );
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> >
+concat( bool, sc_concref<T1,T2> );
+
+#endif
+
+
+// ----------------------------------------------------------------------------
+// CLASS TEMPLATE : sc_concref<X,Y>
+//
+// Proxy class for sc_proxy concatenation (r-value and l-value).
+// ----------------------------------------------------------------------------
+
+template <class X, class Y>
+class sc_concref
+ : public sc_concref_r<X,Y>
+{
+public:
+
+ // typedefs
+
+ typedef sc_concref_r<X,Y> base_type;
+
+
+ // constructor
+
+ sc_concref( X& left_, Y& right_, int delete_ = 0 )
+ : sc_concref_r<X,Y>( left_, right_, delete_ )
+ {}
+
+
+ // copy constructor
+
+ sc_concref( const sc_concref<X,Y>& a )
+ : sc_concref_r<X,Y>( a )
+ {}
+
+
+ // cloning
+
+ sc_concref<X,Y>* clone() const
+ { return new sc_concref<X,Y>( *this ); }
+
+
+ // assignment operators
+
+ template <class Z>
+ sc_concref<X,Y>& operator = ( const sc_proxy<Z>& a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_concref<X,Y>& operator = ( const sc_concref<X,Y>& a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_concref<X,Y>& operator = ( const char* a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_concref<X,Y>& operator = ( const bool* a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_concref<X,Y>& operator = ( const sc_logic* a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_concref<X,Y>& operator = ( const sc_unsigned& a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_concref<X,Y>& operator = ( const sc_signed& a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_concref<X,Y>& operator = ( const sc_uint_base& a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_concref<X,Y>& operator = ( const sc_int_base& a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_concref<X,Y>& operator = ( unsigned long a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_concref<X,Y>& operator = ( long a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_concref<X,Y>& operator = ( unsigned int a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_concref<X,Y>& operator = ( int a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_concref<X,Y>& operator = ( uint64 a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_concref<X,Y>& operator = ( int64 a )
+ { base_type::assign_( a ); return *this; }
+
+
+ // other methods
+
+ void scan( ::std::istream& = ::std::cin );
+
+private:
+
+ // disabled
+ sc_concref();
+};
+
+
+// l-value concatenation operators and functions
+
+template <class T1, class T2, class T3>
+inline
+sc_concref<sc_concref<T1,T2>,sc_bitref<T3> >
+operator , ( sc_concref<T1,T2>, sc_bitref<T3> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref<sc_concref<T1,T2>,sc_subref<T3> >
+operator , ( sc_concref<T1,T2>, sc_subref<T3> );
+
+template <class T1, class T2, class T3, class T4>
+inline
+sc_concref<sc_concref<T1,T2>,sc_concref<T3,T4> >
+operator , ( sc_concref<T1,T2>, sc_concref<T3,T4> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref<sc_concref<T1,T2>,T3>
+operator , ( sc_concref<T1,T2>, sc_proxy<T3>& );
+
+
+template <class T1, class T2, class T3>
+inline
+sc_concref<sc_concref<T1,T2>,sc_bitref<T3> >
+concat( sc_concref<T1,T2>, sc_bitref<T3> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref<sc_concref<T1,T2>,sc_subref<T3> >
+concat( sc_concref<T1,T2>, sc_subref<T3> );
+
+template <class T1, class T2, class T3, class T4>
+inline
+sc_concref<sc_concref<T1,T2>,sc_concref<T3,T4> >
+concat( sc_concref<T1,T2>, sc_concref<T3,T4> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref<sc_concref<T1,T2>,T3>
+concat( sc_concref<T1,T2>, sc_proxy<T3>& );
+
+
+template <class T1, class T2>
+inline
+::std::istream&
+operator >> ( ::std::istream&, sc_concref<T1,T2> );
+
+
+// ----------------------------------------------------------------------------
+// CLASS TEMPLATE : sc_proxy<T>
+//
+// Base class template for bit/logic vector classes.
+// (Barton/Nackmann implementation)
+// ----------------------------------------------------------------------------
+
+// r-value concatenation operators and functions
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,sc_bitref_r<T2> >
+operator , ( const sc_proxy<T1>&, sc_bitref_r<T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,sc_subref_r<T2> >
+operator , ( const sc_proxy<T1>&, sc_subref_r<T2> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<T1,sc_concref_r<T2,T3> >
+operator , ( const sc_proxy<T1>&, sc_concref_r<T2,T3> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,T2>
+operator , ( const sc_proxy<T1>&, const sc_proxy<T2>& );
+
+template <class T>
+inline
+sc_concref_r<T,sc_lv_base>
+operator , ( const sc_proxy<T>&, const char* );
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,T>
+operator , ( const char*, const sc_proxy<T>& );
+
+template <class T>
+inline
+sc_concref_r<T,sc_lv_base>
+operator , ( const sc_proxy<T>&, const sc_logic& );
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,T>
+operator , ( const sc_logic&, const sc_proxy<T>& );
+
+template <class T>
+inline
+sc_concref_r<T,sc_bv_base>
+operator , ( const sc_proxy<T>&, bool );
+
+template <class T>
+inline
+sc_concref_r<sc_bv_base,T>
+operator , ( bool, const sc_proxy<T>& );
+
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,sc_bitref_r<T2> >
+concat( const sc_proxy<T1>&, sc_bitref_r<T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,sc_subref_r<T2> >
+concat( const sc_proxy<T1>&, sc_subref_r<T2> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<T1,sc_concref_r<T2,T3> >
+concat( const sc_proxy<T1>&, sc_concref_r<T2,T3> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,T2>
+concat( const sc_proxy<T1>&, const sc_proxy<T2>& );
+
+template <class T>
+inline
+sc_concref_r<T,sc_lv_base>
+concat( const sc_proxy<T>&, const char* );
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,T>
+concat( const char*, const sc_proxy<T>& );
+
+template <class T>
+inline
+sc_concref_r<T,sc_lv_base>
+concat( const sc_proxy<T>&, const sc_logic& );
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,T>
+concat( const sc_logic&, const sc_proxy<T>& );
+
+template <class T>
+inline
+sc_concref_r<T,sc_bv_base>
+concat( const sc_proxy<T>&, bool );
+
+template <class T>
+inline
+sc_concref_r<sc_bv_base,T>
+concat( bool, const sc_proxy<T>& );
+
+
+#ifdef SC_DT_MIXED_COMMA_OPERATORS
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,sc_bitref_r<T2> >
+operator , ( const sc_proxy<T1>&, sc_bitref<T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,sc_bitref_r<T2> >
+operator , ( sc_proxy<T1>&, sc_bitref_r<T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,sc_subref_r<T2> >
+operator , ( const sc_proxy<T1>&, sc_subref<T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,sc_subref_r<T2> >
+operator , ( sc_proxy<T1>&, sc_subref_r<T2> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<T1,sc_concref_r<T2,T3> >
+operator , ( const sc_proxy<T1>&, sc_concref<T2,T3> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<T1,sc_concref_r<T2,T3> >
+operator , ( sc_proxy<T1>&, sc_concref_r<T2,T3> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,T2>
+operator , ( const sc_proxy<T1>&, sc_proxy<T2>& );
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,T2>
+operator , ( sc_proxy<T1>&, const sc_proxy<T2>& );
+
+template <class T>
+inline
+sc_concref_r<T,sc_lv_base>
+operator , ( sc_proxy<T>&, const char* );
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,T>
+operator , ( const char*, sc_proxy<T>& );
+
+template <class T>
+inline
+sc_concref_r<T,sc_lv_base>
+operator , ( sc_proxy<T>&, const sc_logic& );
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,T>
+operator , ( const sc_logic&, sc_proxy<T>& );
+
+template <class T>
+inline
+sc_concref_r<T,sc_bv_base>
+operator , ( sc_proxy<T>&, bool );
+
+template <class T>
+inline
+sc_concref_r<sc_bv_base,T>
+operator , ( bool, sc_proxy<T>& );
+
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,sc_bitref_r<T2> >
+concat( const sc_proxy<T1>&, sc_bitref<T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,sc_bitref_r<T2> >
+concat( sc_proxy<T1>&, sc_bitref_r<T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,sc_subref_r<T2> >
+concat( const sc_proxy<T1>&, sc_subref<T2> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,sc_subref_r<T2> >
+concat( sc_proxy<T1>&, sc_subref_r<T2> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<T1,sc_concref_r<T2,T3> >
+concat( const sc_proxy<T1>&, sc_concref<T2,T3> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<T1,sc_concref_r<T2,T3> >
+concat( sc_proxy<T1>&, sc_concref_r<T2,T3> );
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,T2>
+concat( const sc_proxy<T1>&, sc_proxy<T2>& );
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,T2>
+concat( sc_proxy<T1>&, const sc_proxy<T2>& );
+
+template <class T>
+inline
+sc_concref_r<T,sc_lv_base>
+concat( sc_proxy<T>&, const char* );
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,T>
+concat( const char*, sc_proxy<T>& );
+
+template <class T>
+inline
+sc_concref_r<T,sc_lv_base>
+concat( sc_proxy<T>&, const sc_logic& );
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,T>
+concat( const sc_logic&, sc_proxy<T>& );
+
+template <class T>
+inline
+sc_concref_r<T,sc_bv_base>
+concat( sc_proxy<T>&, bool );
+
+template <class T>
+inline
+sc_concref_r<sc_bv_base,T>
+concat( bool, sc_proxy<T>& );
+
+#endif
+
+
+// l-value concatenation operators and functions
+
+template <class T1, class T2>
+inline
+sc_concref<T1,sc_bitref<T2> >
+operator , ( sc_proxy<T1>&, sc_bitref<T2> );
+
+template <class T1, class T2>
+inline
+sc_concref<T1,sc_subref<T2> >
+operator , ( sc_proxy<T1>&, sc_subref<T2> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref<T1,sc_concref<T2,T3> >
+operator , ( sc_proxy<T1>&, sc_concref<T2,T3> );
+
+template <class T1, class T2>
+inline
+sc_concref<T1,T2>
+operator , ( sc_proxy<T1>&, sc_proxy<T2>& );
+
+
+template <class T1, class T2>
+inline
+sc_concref<T1,sc_bitref<T2> >
+concat( sc_proxy<T1>&, sc_bitref<T2> );
+
+template <class T1, class T2>
+inline
+sc_concref<T1,sc_subref<T2> >
+concat( sc_proxy<T1>&, sc_subref<T2> );
+
+template <class T1, class T2, class T3>
+inline
+sc_concref<T1,sc_concref<T2,T3> >
+concat( sc_proxy<T1>&, sc_concref<T2,T3> );
+
+template <class T1, class T2>
+inline
+sc_concref<T1,T2>
+concat( sc_proxy<T1>&, sc_proxy<T2>& );
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+// ----------------------------------------------------------------------------
+// CLASS TEMPLATE : sc_bitref_r<T>
+//
+// Proxy class for sc_proxy bit selection (r-value only).
+// ----------------------------------------------------------------------------
+
+// bitwise operators and functions
+
+// bitwise and
+
+template <class T1, class T2>
+inline
+const sc_logic
+operator & ( const sc_bitref_r<T1>& a, const sc_bitref_r<T2>& b )
+{
+ return sc_logic( sc_logic::and_table[a.value()][b.value()] );
+}
+
+
+// bitwise or
+
+template <class T1, class T2>
+inline
+const sc_logic
+operator | ( const sc_bitref_r<T1>& a, const sc_bitref_r<T2>& b )
+{
+ return sc_logic( sc_logic::or_table[a.value()][b.value()] );
+}
+
+
+// bitwise xor
+
+template <class T1, class T2>
+inline
+const sc_logic
+operator ^ ( const sc_bitref_r<T1>& a, const sc_bitref_r<T2>& b )
+{
+ return sc_logic( sc_logic::xor_table[a.value()][b.value()] );
+}
+
+
+// relational operators and functions
+
+template <class T1, class T2>
+inline
+bool
+operator == ( const sc_bitref_r<T1>& a, const sc_bitref_r<T2>& b )
+{
+ return ( (int) a.value() == b.value() );
+}
+
+template <class T1, class T2>
+inline
+bool
+operator != ( const sc_bitref_r<T1>& a, const sc_bitref_r<T2>& b )
+{
+ return ( (int) a.value() != b.value() );
+}
+
+
+// common methods
+
+template <class T>
+inline
+sc_logic_value_t
+sc_bitref_r<T>::get_bit( int n ) const
+{
+ if( n == 0 ) {
+ return m_obj.get_bit( m_index );
+ } else {
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_ , 0 );
+ // never reached
+ return Log_0;
+ }
+}
+
+
+template <class T>
+inline
+sc_digit
+sc_bitref_r<T>::get_word( int n ) const
+{
+ if( n == 0 ) {
+ return ( get_bit( n ) & SC_DIGIT_ONE );
+ } else {
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 );
+ // never reached
+ return 0;
+ }
+}
+
+template <class T>
+inline
+sc_digit
+sc_bitref_r<T>::get_cword( int n ) const
+{
+ if( n == 0 ) {
+ return ( (get_bit( n ) & SC_DIGIT_TWO) >> 1 );
+ } else {
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 );
+ // never reached
+ return 0;
+ }
+}
+
+
+// r-value concatenation operators and functions
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> >
+operator , ( sc_bitref_r<T1> a, sc_bitref_r<T2> b )
+{
+ return sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> >
+operator , ( sc_bitref_r<T1> a, sc_subref_r<T2> b )
+{
+ return sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> >
+operator , ( sc_bitref_r<T1> a, sc_concref_r<T2,T3> b )
+{
+ return sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,T2>
+operator , ( sc_bitref_r<T1> a, const sc_proxy<T2>& b )
+{
+ return sc_concref_r<sc_bitref_r<T1>,T2>(
+ *a.clone(), b.back_cast(), 1 );
+}
+
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> >
+concat( sc_bitref_r<T1> a, sc_bitref_r<T2> b )
+{
+ return sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> >
+concat( sc_bitref_r<T1> a, sc_subref_r<T2> b )
+{
+ return sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> >
+concat( sc_bitref_r<T1> a, sc_concref_r<T2,T3> b )
+{
+ return sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,T2>
+concat( sc_bitref_r<T1> a, const sc_proxy<T2>& b )
+{
+ return sc_concref_r<sc_bitref_r<T1>,T2>(
+ *a.clone(), b.back_cast(), 1 );
+}
+
+
+#ifdef SC_DT_MIXED_COMMA_OPERATORS
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> >
+operator , ( sc_bitref_r<T1> a, sc_bitref<T2> b )
+{
+ return sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> >
+operator , ( sc_bitref<T1> a, sc_bitref_r<T2> b )
+{
+ return sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> >
+operator , ( sc_bitref_r<T1> a, sc_subref<T2> b )
+{
+ return sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> >
+operator , ( sc_bitref<T1> a, sc_subref_r<T2> b )
+{
+ return sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> >
+operator , ( sc_bitref_r<T1> a, sc_concref<T2,T3> b )
+{
+ return sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> >
+operator , ( sc_bitref<T1> a, sc_concref_r<T2,T3> b )
+{
+ return sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,T2>
+operator , ( sc_bitref<T1> a, const sc_proxy<T2>& b )
+{
+ return sc_concref_r<sc_bitref_r<T1>,T2>(
+ *a.clone(), b.back_cast(), 1 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,T2>
+operator , ( sc_bitref_r<T1> a, sc_proxy<T2>& b )
+{
+ return sc_concref_r<sc_bitref_r<T1>,T2>(
+ *a.clone(), b.back_cast(), 1 );
+}
+
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> >
+concat( sc_bitref_r<T1> a, sc_bitref<T2> b )
+{
+ return sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> >
+concat( sc_bitref<T1> a, sc_bitref_r<T2> b )
+{
+ return sc_concref_r<sc_bitref_r<T1>,sc_bitref_r<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> >
+concat( sc_bitref_r<T1> a, sc_subref<T2> b )
+{
+ return sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> >
+concat( sc_bitref<T1> a, sc_subref_r<T2> b )
+{
+ return sc_concref_r<sc_bitref_r<T1>,sc_subref_r<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> >
+concat( sc_bitref_r<T1> a, sc_concref<T2,T3> b )
+{
+ return sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> >
+concat( sc_bitref<T1> a, sc_concref_r<T2,T3> b )
+{
+ return sc_concref_r<sc_bitref_r<T1>,sc_concref_r<T2,T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,T2>
+concat( sc_bitref<T1> a, const sc_proxy<T2>& b )
+{
+ return sc_concref_r<sc_bitref_r<T1>,T2>(
+ *a.clone(), b.back_cast(), 1 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bitref_r<T1>,T2>
+concat( sc_bitref_r<T1> a, sc_proxy<T2>& b )
+{
+ return sc_concref_r<sc_bitref_r<T1>,T2>(
+ *a.clone(), b.back_cast(), 1 );
+}
+
+#endif
+
+
+// ----------------------------------------------------------------------------
+// CLASS TEMPLATE : sc_bitref<X>
+//
+// Proxy class for sc_proxy bit selection (r-value and l-value).
+// ----------------------------------------------------------------------------
+
+// assignment operators
+
+template <class X>
+inline
+sc_bitref<X>&
+sc_bitref<X>::operator = ( const sc_bitref_r<X>& a )
+{
+ this->m_obj.set_bit( this->m_index, a.value() );
+ return *this;
+}
+
+template <class X>
+inline
+sc_bitref<X>&
+sc_bitref<X>::operator = ( const sc_bitref<X>& a )
+{
+ if( &a != this ) {
+ this->m_obj.set_bit( this->m_index, a.value() );
+ }
+ return *this;
+}
+
+
+// bitwise assignment operators
+
+template <class X>
+inline
+sc_bitref<X>&
+sc_bitref<X>::operator &= ( const sc_bitref_r<X>& a )
+{
+ if( &a != this ) {
+ this->m_obj.set_bit( this->m_index,
+ sc_logic::and_table[this->value()][a.value()] );
+ }
+ return *this;
+}
+
+template <class X>
+inline
+sc_bitref<X>&
+sc_bitref<X>::operator &= ( const sc_logic& a )
+{
+ this->m_obj.set_bit( this->m_index,
+ sc_logic::and_table[this->value()][a.value()] );
+ return *this;
+}
+
+
+template <class X>
+inline
+sc_bitref<X>&
+sc_bitref<X>::operator |= ( const sc_bitref_r<X>& a )
+{
+ if( &a != this ) {
+ this->m_obj.set_bit( this->m_index,
+ sc_logic::or_table[this->value()][a.value()] );
+ }
+ return *this;
+}
+
+template <class X>
+inline
+sc_bitref<X>&
+sc_bitref<X>::operator |= ( const sc_logic& a )
+{
+ this->m_obj.set_bit( this->m_index,
+ sc_logic::or_table[this->value()][a.value()] );
+ return *this;
+}
+
+
+template <class X>
+inline
+sc_bitref<X>&
+sc_bitref<X>::operator ^= ( const sc_bitref_r<X>& a )
+{
+ if( &a != this ) {
+ this->m_obj.set_bit( this->m_index,
+ sc_logic::xor_table[this->value()][a.value()] );
+ }
+ return *this;
+}
+
+template <class X>
+inline
+sc_bitref<X>&
+sc_bitref<X>::operator ^= ( const sc_logic& a )
+{
+ this->m_obj.set_bit( this->m_index,
+ sc_logic::xor_table[this->value()][a.value()] );
+ return *this;
+}
+
+
+// bitwise operators and functions
+
+// bitwise complement
+
+template <class X>
+inline
+sc_bitref<X>&
+sc_bitref<X>::b_not()
+{
+ this->m_obj.set_bit( this->m_index,
+ sc_logic::not_table[this->value()] );
+ return *this;
+}
+
+
+// common methods
+
+template <class X>
+inline
+void
+sc_bitref<X>::set_bit( int n, sc_logic_value_t value )
+{
+ if( n == 0 ) {
+ this->m_obj.set_bit( this->m_index, value );
+ } else {
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 );
+ }
+}
+
+template <class X>
+inline
+void
+sc_bitref<X>::set_word( int n, sc_digit w )
+{
+ unsigned int bi = this->m_index % (8*sizeof(sc_digit));
+ sc_digit temp;
+ unsigned int wi = this->m_index / (8*sizeof(sc_digit));
+ if( n == 0 ) {
+ temp = this->m_obj.get_word(wi);
+ temp = (temp & ~(1 << bi)) | ((w&1) << bi);
+ this->m_obj.set_word(wi, temp);
+ } else {
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 );
+ }
+
+}
+
+template <class X>
+inline
+void
+sc_bitref<X>::set_cword( int n, sc_digit w )
+{
+ unsigned int bi = this->m_index % (8*sizeof(sc_digit));
+ sc_digit temp;
+ unsigned int wi = this->m_index / (8*sizeof(sc_digit));
+ if( n == 0 ) {
+ temp = this->m_obj.get_cword(wi);
+ temp = (temp & ~(1 << bi)) | ((w&1) << bi);
+ this->m_obj.set_cword(wi, temp);
+ } else {
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 );
+ }
+}
+
+// other methods
+
+template <class X>
+inline
+void
+sc_bitref<X>::scan( ::std::istream& is )
+{
+ char c;
+ is >> c;
+ *this = c;
+}
+
+
+// l-value concatenation operators and functions
+
+template <class T1, class T2>
+inline
+sc_concref<sc_bitref<T1>,sc_bitref<T2> >
+operator , ( sc_bitref<T1> a, sc_bitref<T2> b )
+{
+ return sc_concref<sc_bitref<T1>,sc_bitref<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref<sc_bitref<T1>,sc_subref<T2> >
+operator , ( sc_bitref<T1> a, sc_subref<T2> b )
+{
+ return sc_concref<sc_bitref<T1>,sc_subref<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref<sc_bitref<T1>,sc_concref<T2,T3> >
+operator , ( sc_bitref<T1> a, sc_concref<T2,T3> b )
+{
+ return sc_concref<sc_bitref<T1>,sc_concref<T2,T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref<sc_bitref<T1>,T2>
+operator , ( sc_bitref<T1> a, sc_proxy<T2>& b )
+{
+ return sc_concref<sc_bitref<T1>,T2>(
+ *a.clone(), b.back_cast(), 1 );
+}
+
+
+template <class T1, class T2>
+inline
+sc_concref<sc_bitref<T1>,sc_bitref<T2> >
+concat( sc_bitref<T1> a, sc_bitref<T2> b )
+{
+ return sc_concref<sc_bitref<T1>,sc_bitref<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref<sc_bitref<T1>,sc_subref<T2> >
+concat( sc_bitref<T1> a, sc_subref<T2> b )
+{
+ return sc_concref<sc_bitref<T1>,sc_subref<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref<sc_bitref<T1>,sc_concref<T2,T3> >
+concat( sc_bitref<T1> a, sc_concref<T2,T3> b )
+{
+ return sc_concref<sc_bitref<T1>,sc_concref<T2,T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref<sc_bitref<T1>,T2>
+concat( sc_bitref<T1> a, sc_proxy<T2>& b )
+{
+ return sc_concref<sc_bitref<T1>,T2>(
+ *a.clone(), b.back_cast(), 1 );
+}
+
+
+template <class X>
+inline
+::std::istream&
+operator >> ( ::std::istream& is, sc_bitref<X> a )
+{
+ a.scan( is );
+ return is;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS TEMPLATE : sc_subref_r<X>
+//
+// Proxy class for sc_proxy part selection (r-value only).
+// ----------------------------------------------------------------------------
+
+template <class X>
+inline
+void
+sc_subref_r<X>::check_bounds()
+{
+ int len = m_obj.length();
+ if( m_hi < 0 || m_hi >= len || m_lo < 0 || m_lo >= len ) {
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 );
+ }
+ if( reversed() ) {
+ m_len = m_lo - m_hi + 1;
+ } else {
+ m_len = m_hi - m_lo + 1;
+ }
+}
+
+
+// common methods
+
+template <class X>
+inline
+sc_logic_value_t
+sc_subref_r<X>::get_bit( int n ) const
+{
+ if( reversed() ) {
+ return m_obj.get_bit( m_lo - n );
+ } else {
+ return m_obj.get_bit( m_lo + n );
+ }
+}
+
+template <class X>
+inline
+void
+sc_subref_r<X>::set_bit( int n, sc_logic_value_t value )
+{
+ if( reversed() ) {
+ m_obj.set_bit( m_lo - n, value );
+ } else {
+ m_obj.set_bit( m_lo + n, value );
+ }
+}
+
+
+template <class X>
+inline
+sc_digit
+sc_subref_r<X>::get_word( int i ) const
+{
+ int n1 = 0;
+ int n2 = 0;
+ sc_digit result = 0;
+ int k = 0;
+ if( reversed() ) {
+ n1 = m_lo - i * SC_DIGIT_SIZE;
+ n2 = sc_max( n1 - SC_DIGIT_SIZE, m_hi - 1 );
+ for( int n = n1; n > n2; n -- ) {
+ result |= (m_obj[n].value() & SC_DIGIT_ONE) << k ++;
+ }
+ } else {
+ n1 = m_lo + i * SC_DIGIT_SIZE;
+ n2 = sc_min( n1 + SC_DIGIT_SIZE, m_hi + 1 );
+ for( int n = n1; n < n2; n ++ ) {
+ result |= (m_obj[n].value() & SC_DIGIT_ONE) << k ++;
+ }
+ }
+ return result;
+}
+
+template <class X>
+inline
+void
+sc_subref_r<X>::set_word( int i, sc_digit w )
+{
+ int n1 = 0;
+ int n2 = 0;
+ int k = 0;
+ if( reversed() ) {
+ n1 = m_lo - i * SC_DIGIT_SIZE;
+ n2 = sc_max( n1 - SC_DIGIT_SIZE, m_hi - 1 );
+ for( int n = n1; n > n2; n -- ) {
+ m_obj.set_bit( n, sc_logic_value_t(
+ ( (w >> k ++) & SC_DIGIT_ONE ) |
+ ( m_obj[n].value() & SC_DIGIT_TWO ) ) );
+ }
+ } else {
+ n1 = m_lo + i * SC_DIGIT_SIZE;
+ n2 = sc_min( n1 + SC_DIGIT_SIZE, m_hi + 1 );
+ for( int n = n1; n < n2; n ++ ) {
+ m_obj.set_bit( n, sc_logic_value_t(
+ ( (w >> k ++) & SC_DIGIT_ONE ) |
+ ( m_obj[n].value() & SC_DIGIT_TWO ) ) );
+ }
+ }
+}
+
+
+template <class X>
+inline
+sc_digit
+sc_subref_r<X>::get_cword( int i ) const
+{
+ int n1 = 0;
+ int n2 = 0;
+ sc_digit result = 0;
+ int k = 0;
+ if( reversed() ) {
+ n1 = m_lo - i * SC_DIGIT_SIZE;
+ n2 = sc_max( n1 - SC_DIGIT_SIZE, m_hi - 1 );
+ for( int n = n1; n > n2; n -- ) {
+ result |= ((m_obj[n].value() & SC_DIGIT_TWO) >> 1) << k ++;
+ }
+ } else {
+ n1 = m_lo + i * SC_DIGIT_SIZE;
+ n2 = sc_min( n1 + SC_DIGIT_SIZE, m_hi + 1 );
+ for( int n = n1; n < n2; n ++ ) {
+ result |= ((m_obj[n].value() & SC_DIGIT_TWO) >> 1) << k ++;
+ }
+ }
+ return result;
+}
+
+template <class X>
+inline
+void
+sc_subref_r<X>::set_cword( int i, sc_digit w )
+{
+ int n1 = 0;
+ int n2 = 0;
+ int k = 0;
+ if( reversed() ) {
+ n1 = m_lo - i * SC_DIGIT_SIZE;
+ n2 = sc_max( n1 - SC_DIGIT_SIZE, m_hi - 1 );
+ for( int n = n1; n > n2; n -- ) {
+ m_obj.set_bit( n, sc_logic_value_t(
+ ( ((w >> k ++) & SC_DIGIT_ONE) << 1 ) |
+ ( m_obj[n].value() & SC_DIGIT_ONE ) ) );
+ }
+ } else {
+ n1 = m_lo + i * SC_DIGIT_SIZE;
+ n2 = sc_min( n1 + SC_DIGIT_SIZE, m_hi + 1 );
+ for( int n = n1; n < n2; n ++ ) {
+ m_obj.set_bit( n, sc_logic_value_t(
+ ( ((w >> k ++) & SC_DIGIT_ONE) << 1 ) |
+ ( m_obj[n].value() & SC_DIGIT_ONE ) ) );
+ }
+ }
+}
+
+
+// other methods
+
+template <class X>
+inline
+bool
+sc_subref_r<X>::is_01() const
+{
+ int sz = size();
+ for( int i = 0; i < sz; ++ i ) {
+ if( get_cword( i ) != SC_DIGIT_ZERO ) {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+// r-value concatenation operators and functions
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> >
+operator , ( sc_subref_r<T1> a, sc_bitref_r<T2> b )
+{
+ return sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> >
+operator , ( sc_subref_r<T1> a, sc_subref_r<T2> b )
+{
+ return sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> >
+operator , ( sc_subref_r<T1> a, sc_concref_r<T2,T3> b )
+{
+ return sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,T2>
+operator , ( sc_subref_r<T1> a, const sc_proxy<T2>& b )
+{
+ return sc_concref_r<sc_subref_r<T1>,T2>(
+ *a.clone(), b.back_cast(), 1 );
+}
+
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> >
+concat( sc_subref_r<T1> a, sc_bitref_r<T2> b )
+{
+ return sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> >
+concat( sc_subref_r<T1> a, sc_subref_r<T2> b )
+{
+ return sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> >
+concat( sc_subref_r<T1> a, sc_concref_r<T2,T3> b )
+{
+ return sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,T2>
+concat( sc_subref_r<T1> a, const sc_proxy<T2>& b )
+{
+ return sc_concref_r<sc_subref_r<T1>,T2>(
+ *a.clone(), b.back_cast(), 1 );
+}
+
+
+#ifdef SC_DT_MIXED_COMMA_OPERATORS
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> >
+operator , ( sc_subref_r<T1> a, sc_bitref<T2> b )
+{
+ return sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> >
+operator , ( sc_subref<T1> a, sc_bitref_r<T2> b )
+{
+ return sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> >
+operator , ( sc_subref_r<T1> a, sc_subref<T2> b )
+{
+ return sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> >
+operator , ( sc_subref<T1> a, sc_subref_r<T2> b )
+{
+ return sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> >
+operator , ( sc_subref_r<T1> a, sc_concref<T2,T3> b )
+{
+ return sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> >
+operator , ( sc_subref<T1> a, sc_concref_r<T2,T3> b )
+{
+ return sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,T2>
+operator , ( sc_subref<T1> a, const sc_proxy<T2>& b )
+{
+ return sc_concref_r<sc_subref_r<T1>,T2>(
+ *a.clone(), b.back_cast(), 1 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,T2>
+operator , ( sc_subref_r<T1> a, sc_proxy<T2>& b )
+{
+ return sc_concref_r<sc_subref_r<T1>,T2>(
+ *a.clone(), b.back_cast(), 1 );
+}
+
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> >
+concat( sc_subref_r<T1> a, sc_bitref<T2> b )
+{
+ return sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> >
+concat( sc_subref<T1> a, sc_bitref_r<T2> b )
+{
+ return sc_concref_r<sc_subref_r<T1>,sc_bitref_r<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> >
+concat( sc_subref_r<T1> a, sc_subref<T2> b )
+{
+ return sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> >
+concat( sc_subref<T1> a, sc_subref_r<T2> b )
+{
+ return sc_concref_r<sc_subref_r<T1>,sc_subref_r<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> >
+concat( sc_subref_r<T1> a, sc_concref<T2,T3> b )
+{
+ return sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> >
+concat( sc_subref<T1> a, sc_concref_r<T2,T3> b )
+{
+ return sc_concref_r<sc_subref_r<T1>,sc_concref_r<T2,T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,T2>
+concat( sc_subref<T1> a, const sc_proxy<T2>& b )
+{
+ return sc_concref_r<sc_subref_r<T1>,T2>(
+ *a.clone(), b.back_cast(), 1 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_subref_r<T1>,T2>
+concat( sc_subref_r<T1> a, sc_proxy<T2>& b )
+{
+ return sc_concref_r<sc_subref_r<T1>,T2>(
+ *a.clone(), b.back_cast(), 1 );
+}
+
+#endif
+
+
+// ----------------------------------------------------------------------------
+// CLASS TEMPLATE : sc_subref<X>
+//
+// Proxy class for sc_proxy part selection (r-value and l-value).
+// ----------------------------------------------------------------------------
+
+// assignment operators
+
+// sc_subref<X>::operator = ( const sc_subref_r<X>& ) in sc_lv_base.h
+// sc_subref<X>::operator = ( const sc_subref<X>& ) in sc_lv_base.h
+
+
+// other methods
+
+template <class T>
+inline
+void
+sc_subref<T>::scan( ::std::istream& is )
+{
+ std::string s;
+ is >> s;
+ *this = s.c_str();
+}
+
+
+// l-value concatenation operators and functions
+
+template <class T1, class T2>
+inline
+sc_concref<sc_subref<T1>,sc_bitref<T2> >
+operator , ( sc_subref<T1> a, sc_bitref<T2> b )
+{
+ return sc_concref<sc_subref<T1>,sc_bitref<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref<sc_subref<T1>,sc_subref<T2> >
+operator , ( sc_subref<T1> a, sc_subref<T2> b )
+{
+ return sc_concref<sc_subref<T1>,sc_subref<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref<sc_subref<T1>,sc_concref<T2,T3> >
+operator , ( sc_subref<T1> a, sc_concref<T2,T3> b )
+{
+ return sc_concref<sc_subref<T1>,sc_concref<T2,T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref<sc_subref<T1>,T2>
+operator , ( sc_subref<T1> a, sc_proxy<T2>& b )
+{
+ return sc_concref<sc_subref<T1>,T2>(
+ *a.clone(), b.back_cast(), 1 );
+}
+
+
+template <class T1, class T2>
+inline
+sc_concref<sc_subref<T1>,sc_bitref<T2> >
+concat( sc_subref<T1> a, sc_bitref<T2> b )
+{
+ return sc_concref<sc_subref<T1>,sc_bitref<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref<sc_subref<T1>,sc_subref<T2> >
+concat( sc_subref<T1> a, sc_subref<T2> b )
+{
+ return sc_concref<sc_subref<T1>,sc_subref<T2> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref<sc_subref<T1>,sc_concref<T2,T3> >
+concat( sc_subref<T1> a, sc_concref<T2,T3> b )
+{
+ return sc_concref<sc_subref<T1>,sc_concref<T2,T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref<sc_subref<T1>,T2>
+concat( sc_subref<T1> a, sc_proxy<T2>& b )
+{
+ return sc_concref<sc_subref<T1>,T2>(
+ *a.clone(), b.back_cast(), 1 );
+}
+
+
+template <class X>
+inline
+::std::istream&
+operator >> ( ::std::istream& is, sc_subref<X> a )
+{
+ a.scan( is );
+ return is;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS TEMPLATE : sc_concref_r<X,Y>
+//
+// Proxy class for sc_proxy concatenation (r-value only).
+// ----------------------------------------------------------------------------
+
+// destructor
+
+template <class X, class Y>
+inline
+sc_concref_r<X,Y>::~sc_concref_r()
+{
+ if( -- m_refs == 0 ) {
+ delete &m_refs;
+ if( m_delete == 0 ) {
+ return;
+ }
+ if( m_delete & 1 ) {
+ delete &m_left;
+ }
+ if( m_delete & 2 ) {
+ delete &m_right;
+ }
+ }
+}
+
+
+// common methods
+
+template <class X, class Y>
+inline
+sc_logic_value_t
+sc_concref_r<X,Y>::get_bit( int n ) const
+{
+ int r_len = m_right.length();
+ if( n < r_len ) {
+ return m_right.get_bit( n );
+ } else if( n < r_len + m_left.length() ) {
+ return m_left.get_bit( n - r_len );
+ } else {
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 );
+ // never reached
+ return Log_0;
+ }
+}
+
+template <class X, class Y>
+inline
+void
+sc_concref_r<X,Y>::set_bit( int n, sc_logic_value_t v )
+{
+ int r_len = m_right.length();
+ if( n < r_len ) {
+ m_right.set_bit( n, v );
+ } else if( n < r_len + m_left.length() ) {
+ m_left.set_bit( n - r_len, v );
+ } else {
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 );
+ }
+}
+
+
+template <class X, class Y>
+inline
+sc_digit
+sc_concref_r<X,Y>::get_word( int i ) const
+{
+ if( i < 0 || i >= size() ) {
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 );
+ }
+ // 0 <= i < size()
+ Y& r = m_right;
+ int r_len = r.length();
+ int border = r_len / SC_DIGIT_SIZE;
+ if( i < border ) {
+ return r.get_word( i );
+ }
+ // border <= i < size()
+ X& l = m_left;
+ int shift = r_len % SC_DIGIT_SIZE;
+ int j = i - border;
+ if( shift == 0 ) {
+ return l.get_word( j );
+ }
+ // border <= i < size() && shift != 0
+ int nshift = SC_DIGIT_SIZE - shift;
+ if( i == border ) {
+ sc_digit rl_mask = ~SC_DIGIT_ZERO >> nshift;
+ return ( (r.get_word( i ) & rl_mask) | (l.get_word( 0 ) << shift) );
+ }
+ // border < i < size() && shift != 0
+ if ( j < l.size() )
+ return ( (l.get_word( j - 1 ) >> nshift) | (l.get_word( j ) << shift) );
+ else
+ return (l.get_word( j - 1 ) >> nshift);
+}
+
+template <class X, class Y>
+inline
+void
+sc_concref_r<X,Y>::set_word( int i, sc_digit w )
+{
+ if( i < 0 || i >= size() ) {
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 );
+ }
+ // 0 <= i < size()
+ Y& r = m_right;
+ int r_len = r.length();
+ int border = r_len / SC_DIGIT_SIZE;
+ if( i < border ) {
+ r.set_word( i, w );
+ return;
+ }
+ // border <= i < size()
+ X& l = m_left;
+ int shift = r_len % SC_DIGIT_SIZE;
+ int j = i - border;
+ if( shift == 0 ) {
+ l.set_word( j, w );
+ return;
+ }
+ // border <= i < size() && shift != 0
+ int nshift = SC_DIGIT_SIZE - shift;
+ sc_digit lh_mask = ~SC_DIGIT_ZERO << nshift;
+ if( i == border ) {
+ sc_digit rl_mask = ~SC_DIGIT_ZERO >> nshift;
+ r.set_word( i, w & rl_mask );
+ l.set_word( 0, (l.get_word( 0 ) & lh_mask) | (w >> shift) );
+ return;
+ }
+ // border < i < size() && shift != 0
+ sc_digit ll_mask = ~SC_DIGIT_ZERO >> shift;
+ l.set_word( j - 1, (l.get_word( j - 1 ) & ll_mask) | (w << nshift) );
+ if ( j < l.size() )
+ l.set_word( j, (l.get_word( j ) & lh_mask) | (w >> shift) );
+}
+
+
+template <class X, class Y>
+inline
+sc_digit
+sc_concref_r<X,Y>::get_cword( int i ) const
+{
+ if( i < 0 || i >= size() ) {
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 );
+ }
+ // 0 <= i < size()
+ Y& r = m_right;
+ int r_len = r.length();
+ int border = r_len / SC_DIGIT_SIZE;
+ if( i < border ) {
+ return r.get_cword( i );
+ }
+ // border <= i < size()
+ X& l = m_left;
+ int shift = r_len % SC_DIGIT_SIZE;
+ int j = i - border;
+ if( shift == 0 ) {
+ return l.get_cword( j );
+ }
+ // border <= i < size() && shift != 0
+ int nshift = SC_DIGIT_SIZE - shift;
+ if( i == border ) {
+ sc_digit rl_mask = ~SC_DIGIT_ZERO >> nshift;
+ return ( (r.get_cword( i ) & rl_mask) | (l.get_cword( 0 ) << shift) );
+ }
+ // border < i < size() && shift != 0
+ if ( j < l.size() )
+ return ( (l.get_cword(j - 1) >> nshift) | (l.get_cword(j) << shift) );
+ else
+ return (l.get_cword( j - 1 ) >> nshift);
+}
+
+template <class X, class Y>
+inline
+void
+sc_concref_r<X,Y>::set_cword( int i, sc_digit w )
+{
+ if( i < 0 || i >= size() ) {
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 );
+ }
+ // 0 <= i < size()
+ Y& r = m_right;
+ int r_len = r.length();
+ int border = r_len / SC_DIGIT_SIZE;
+ if( i < border ) {
+ r.set_cword( i, w );
+ return;
+ }
+ // border <= i < size()
+ X& l = m_left;
+ int shift = r_len % SC_DIGIT_SIZE;
+ int j = i - border;
+ if( shift == 0 ) {
+ l.set_cword( j, w );
+ return;
+ }
+ // border <= i < size() && shift != 0
+ int nshift = SC_DIGIT_SIZE - shift;
+ sc_digit lh_mask = ~SC_DIGIT_ZERO << nshift;
+ if( i == border ) {
+ sc_digit rl_mask = ~SC_DIGIT_ZERO >> nshift;
+ r.set_cword( i, w & rl_mask );
+ l.set_cword( 0, (l.get_cword( 0 ) & lh_mask) | (w >> shift) );
+ return;
+ }
+ // border < i < size() && shift != 0
+ sc_digit ll_mask = ~SC_DIGIT_ZERO >> shift;
+ l.set_cword( j - 1, (l.get_cword( j - 1 ) & ll_mask) | (w << nshift) );
+ if ( j < l.size() )
+ l.set_cword( j, (l.get_cword( j ) & lh_mask) | (w >> shift) );
+}
+
+
+// r-value concatenation operators and functions
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> >
+operator , ( sc_concref_r<T1,T2> a, sc_bitref_r<T3> b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> >
+operator , ( sc_concref_r<T1,T2> a, sc_subref_r<T3> b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3, class T4>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> >
+operator , ( sc_concref_r<T1,T2> a, sc_concref_r<T3,T4> b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,T3>
+operator , ( sc_concref_r<T1,T2> a, const sc_proxy<T3>& b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,T3>(
+ *a.clone(), b.back_cast(), 1 );
+}
+
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> >
+concat( sc_concref_r<T1,T2> a, sc_bitref_r<T3> b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> >
+concat( sc_concref_r<T1,T2> a, sc_subref_r<T3> b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3, class T4>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> >
+concat( sc_concref_r<T1,T2> a, sc_concref_r<T3,T4> b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,T3>
+concat( sc_concref_r<T1,T2> a, const sc_proxy<T3>& b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,T3>(
+ *a.clone(), b.back_cast(), 1 );
+}
+
+
+#ifdef SC_DT_MIXED_COMMA_OPERATORS
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> >
+operator , ( sc_concref_r<T1,T2> a, sc_bitref<T3> b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> >
+operator , ( sc_concref<T1,T2> a, sc_bitref_r<T3> b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> >
+operator , ( sc_concref_r<T1,T2> a, sc_subref<T3> b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> >
+operator , ( sc_concref<T1,T2> a, sc_subref_r<T3> b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3, class T4>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> >
+operator , ( sc_concref_r<T1,T2> a, sc_concref<T3,T4> b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3, class T4>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> >
+operator , ( sc_concref<T1,T2> a, sc_concref_r<T3,T4> b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,T3>
+operator , ( sc_concref<T1,T2> a, const sc_proxy<T3>& b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,T3>(
+ *a.clone(), b.back_cast(), 1 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,T3>
+operator , ( sc_concref_r<T1,T2> a, sc_proxy<T3>& b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,T3>(
+ *a.clone(), b.back_cast(), 1 );
+}
+
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> >
+concat( sc_concref_r<T1,T2> a, sc_bitref<T3> b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> >
+concat( sc_concref<T1,T2> a, sc_bitref_r<T3> b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,sc_bitref_r<T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> >
+concat( sc_concref_r<T1,T2> a, sc_subref<T3> b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> >
+concat( sc_concref<T1,T2> a, sc_subref_r<T3> b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,sc_subref_r<T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3, class T4>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> >
+concat( sc_concref_r<T1,T2> a, sc_concref<T3,T4> b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3, class T4>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> >
+concat( sc_concref<T1,T2> a, sc_concref_r<T3,T4> b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,sc_concref_r<T3,T4> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,T3>
+concat( sc_concref<T1,T2> a, const sc_proxy<T3>& b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,T3>(
+ *a.clone(), b.back_cast(), 1 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,T3>
+concat( sc_concref_r<T1,T2> a, sc_proxy<T3>& b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,T3>(
+ *a.clone(), b.back_cast(), 1 );
+}
+
+#endif
+
+
+// ----------------------------------------------------------------------------
+// CLASS TEMPLATE : sc_concref<X,Y>
+//
+// Proxy class for sc_proxy concatenation (r-value and l-value).
+// ----------------------------------------------------------------------------
+
+// other methods
+
+template <class T1, class T2>
+inline
+void
+sc_concref<T1,T2>::scan( ::std::istream& is )
+{
+ std::string s;
+ is >> s;
+ *this = s.c_str();
+}
+
+
+// l-value concatenation operators and functions
+
+template <class T1, class T2, class T3>
+inline
+sc_concref<sc_concref<T1,T2>,sc_bitref<T3> >
+operator , ( sc_concref<T1,T2> a, sc_bitref<T3> b )
+{
+ return sc_concref<sc_concref<T1,T2>,sc_bitref<T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref<sc_concref<T1,T2>,sc_subref<T3> >
+operator , ( sc_concref<T1,T2> a, sc_subref<T3> b )
+{
+ return sc_concref<sc_concref<T1,T2>,sc_subref<T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3, class T4>
+inline
+sc_concref<sc_concref<T1,T2>,sc_concref<T3,T4> >
+operator , ( sc_concref<T1,T2> a, sc_concref<T3,T4> b )
+{
+ return sc_concref<sc_concref<T1,T2>,sc_concref<T3,T4> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref<sc_concref<T1,T2>,T3>
+operator , ( sc_concref<T1,T2> a, sc_proxy<T3>& b )
+{
+ return sc_concref<sc_concref<T1,T2>,T3>(
+ *a.clone(), b.back_cast(), 1 );
+}
+
+
+template <class T1, class T2, class T3>
+inline
+sc_concref<sc_concref<T1,T2>,sc_bitref<T3> >
+concat( sc_concref<T1,T2> a, sc_bitref<T3> b )
+{
+ return sc_concref<sc_concref<T1,T2>,sc_bitref<T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref<sc_concref<T1,T2>,sc_subref<T3> >
+concat( sc_concref<T1,T2> a, sc_subref<T3> b )
+{
+ return sc_concref<sc_concref<T1,T2>,sc_subref<T3> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3, class T4>
+inline
+sc_concref<sc_concref<T1,T2>,sc_concref<T3,T4> >
+concat( sc_concref<T1,T2> a, sc_concref<T3,T4> b )
+{
+ return sc_concref<sc_concref<T1,T2>,sc_concref<T3,T4> >(
+ *a.clone(), *b.clone(), 3 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref<sc_concref<T1,T2>,T3>
+concat( sc_concref<T1,T2> a, sc_proxy<T3>& b )
+{
+ return sc_concref<sc_concref<T1,T2>,T3>(
+ *a.clone(), b.back_cast(), 1 );
+}
+
+
+template <class X, class Y>
+inline
+::std::istream&
+operator >> ( ::std::istream& is, sc_concref<X,Y> a )
+{
+ a.scan( is );
+ return is;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS TEMPLATE : sc_proxy<T>
+//
+// Base class template for bit/logic vector classes.
+// (Barton/Nackmann implementation)
+// ----------------------------------------------------------------------------
+
+// r-value concatenation operators and functions
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,sc_bitref_r<T2> >
+operator , ( const sc_proxy<T1>& a, sc_bitref_r<T2> b )
+{
+ return sc_concref_r<T1,sc_bitref_r<T2> >(
+ a.back_cast(), *b.clone(), 2 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,sc_subref_r<T2> >
+operator , ( const sc_proxy<T1>& a, sc_subref_r<T2> b )
+{
+ return sc_concref_r<T1,sc_subref_r<T2> >(
+ a.back_cast(), *b.clone(), 2 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<T1,sc_concref_r<T2,T3> >
+operator , ( const sc_proxy<T1>& a, sc_concref_r<T2,T3> b )
+{
+ return sc_concref_r<T1,sc_concref_r<T2,T3> >(
+ a.back_cast(), *b.clone(), 2 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,T2>
+operator , ( const sc_proxy<T1>& a, const sc_proxy<T2>& b )
+{
+ return sc_concref_r<T1,T2>(
+ a.back_cast(), b.back_cast() );
+}
+
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,sc_bitref_r<T2> >
+concat( const sc_proxy<T1>& a, sc_bitref_r<T2> b )
+{
+ return sc_concref_r<T1,sc_bitref_r<T2> >(
+ a.back_cast(), *b.clone(), 2 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,sc_subref_r<T2> >
+concat( const sc_proxy<T1>& a, sc_subref_r<T2> b )
+{
+ return sc_concref_r<T1,sc_subref_r<T2> >(
+ a.back_cast(), *b.clone(), 2 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<T1,sc_concref_r<T2,T3> >
+concat( const sc_proxy<T1>& a, sc_concref_r<T2,T3> b )
+{
+ return sc_concref_r<T1,sc_concref_r<T2,T3> >(
+ a.back_cast(), *b.clone(), 2 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,T2>
+concat( const sc_proxy<T1>& a, const sc_proxy<T2>& b )
+{
+ return sc_concref_r<T1,T2>(
+ a.back_cast(), b.back_cast() );
+}
+
+
+#ifdef SC_DT_MIXED_COMMA_OPERATORS
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,sc_bitref_r<T2> >
+operator , ( const sc_proxy<T1>& a, sc_bitref<T2> b )
+{
+ return sc_concref_r<T1,sc_bitref_r<T2> >(
+ a.back_cast(), *b.clone(), 2 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,sc_bitref_r<T2> >
+operator , ( sc_proxy<T1>& a, sc_bitref_r<T2> b )
+{
+ return sc_concref_r<T1,sc_bitref_r<T2> >(
+ a.back_cast(), *b.clone(), 2 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,sc_subref_r<T2> >
+operator , ( const sc_proxy<T1>& a, sc_subref<T2> b )
+{
+ return sc_concref_r<T1,sc_subref_r<T2> >(
+ a.back_cast(), *b.clone(), 2 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,sc_subref_r<T2> >
+operator , ( sc_proxy<T1>& a, sc_subref_r<T2> b )
+{
+ return sc_concref_r<T1,sc_subref_r<T2> >(
+ a.back_cast(), *b.clone(), 2 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<T1,sc_concref_r<T2,T3> >
+operator , ( const sc_proxy<T1>& a, sc_concref<T2,T3> b )
+{
+ return sc_concref_r<T1,sc_concref_r<T2,T3> >(
+ a.back_cast(), *b.clone(), 2 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<T1,sc_concref_r<T2,T3> >
+operator , ( sc_proxy<T1>& a, sc_concref_r<T2,T3> b )
+{
+ return sc_concref_r<T1,sc_concref_r<T2,T3> >(
+ a.back_cast(), *b.clone(), 2 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,T2>
+operator , ( const sc_proxy<T1>& a, sc_proxy<T2>& b )
+{
+ return sc_concref_r<T1,T2>(
+ a.back_cast(), b.back_cast() );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,T2>
+operator , ( sc_proxy<T1>& a, const sc_proxy<T2>& b )
+{
+ return sc_concref_r<T1,T2>(
+ a.back_cast(), b.back_cast() );
+}
+
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,sc_bitref_r<T2> >
+concat( const sc_proxy<T1>& a, sc_bitref<T2> b )
+{
+ return sc_concref_r<T1,sc_bitref_r<T2> >(
+ a.back_cast(), *b.clone(), 2 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,sc_bitref_r<T2> >
+concat( sc_proxy<T1>& a, sc_bitref_r<T2> b )
+{
+ return sc_concref_r<T1,sc_bitref_r<T2> >(
+ a.back_cast(), *b.clone(), 2 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,sc_subref_r<T2> >
+concat( const sc_proxy<T1>& a, sc_subref<T2> b )
+{
+ return sc_concref_r<T1,sc_subref_r<T2> >(
+ a.back_cast(), *b.clone(), 2 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,sc_subref_r<T2> >
+concat( sc_proxy<T1>& a, sc_subref_r<T2> b )
+{
+ return sc_concref_r<T1,sc_subref_r<T2> >(
+ a.back_cast(), *b.clone(), 2 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<T1,sc_concref_r<T2,T3> >
+concat( const sc_proxy<T1>& a, sc_concref<T2,T3> b )
+{
+ return sc_concref_r<T1,sc_concref_r<T2,T3> >(
+ a.back_cast(), *b.clone(), 2 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref_r<T1,sc_concref_r<T2,T3> >
+concat( sc_proxy<T1>& a, sc_concref_r<T2,T3> b )
+{
+ return sc_concref_r<T1,sc_concref_r<T2,T3> >(
+ a.back_cast(), *b.clone(), 2 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,T2>
+concat( const sc_proxy<T1>& a, sc_proxy<T2>& b )
+{
+ return sc_concref_r<T1,T2>(
+ a.back_cast(), b.back_cast() );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<T1,T2>
+concat( sc_proxy<T1>& a, const sc_proxy<T2>& b )
+{
+ return sc_concref_r<T1,T2>(
+ a.back_cast(), b.back_cast() );
+}
+
+#endif
+
+
+// l-value concatenation operators and functions
+
+template <class T1, class T2>
+inline
+sc_concref<T1,sc_bitref<T2> >
+operator , ( sc_proxy<T1>& a, sc_bitref<T2> b )
+{
+ return sc_concref<T1,sc_bitref<T2> >(
+ a.back_cast(), *b.clone(), 2 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref<T1,sc_subref<T2> >
+operator , ( sc_proxy<T1>& a, sc_subref<T2> b )
+{
+ return sc_concref<T1,sc_subref<T2> >(
+ a.back_cast(), *b.clone(), 2 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref<T1,sc_concref<T2,T3> >
+operator , ( sc_proxy<T1>& a, sc_concref<T2,T3> b )
+{
+ return sc_concref<T1,sc_concref<T2,T3> >(
+ a.back_cast(), *b.clone(), 2 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref<T1,T2>
+operator , ( sc_proxy<T1>& a, sc_proxy<T2>& b )
+{
+ return sc_concref<T1,T2>(
+ a.back_cast(), b.back_cast() );
+}
+
+
+template <class T1, class T2>
+inline
+sc_concref<T1,sc_bitref<T2> >
+concat( sc_proxy<T1>& a, sc_bitref<T2> b )
+{
+ return sc_concref<T1,sc_bitref<T2> >(
+ a.back_cast(), *b.clone(), 2 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref<T1,sc_subref<T2> >
+concat( sc_proxy<T1>& a, sc_subref<T2> b )
+{
+ return sc_concref<T1,sc_subref<T2> >(
+ a.back_cast(), *b.clone(), 2 );
+}
+
+template <class T1, class T2, class T3>
+inline
+sc_concref<T1,sc_concref<T2,T3> >
+concat( sc_proxy<T1>& a, sc_concref<T2,T3> b )
+{
+ return sc_concref<T1,sc_concref<T2,T3> >(
+ a.back_cast(), *b.clone(), 2 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref<T1,T2>
+concat( sc_proxy<T1>& a, sc_proxy<T2>& b )
+{
+ return sc_concref<T1,T2>(
+ a.back_cast(), b.back_cast() );
+}
+
+} // namespace sc_dt
+
+// $Log: sc_bit_proxies.h,v $
+// Revision 1.10 2011/09/05 21:19:53 acg
+// Philipp A. Hartmann: added parentheses to expressions to eliminate
+// compiler warnings.
+//
+// Revision 1.9 2011/09/01 15:03:42 acg
+// Philipp A. Hartmann: add parentheses to eliminate compiler warnings.
+//
+// Revision 1.8 2011/08/29 18:04:32 acg
+// Philipp A. Hartmann: miscellaneous clean ups.
+//
+// Revision 1.7 2011/08/24 22:05:40 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.6 2010/02/22 14:25:43 acg
+// Andy Goodrich: removed 'mutable' directive from references, since it
+// is not a legal C++ construct.
+//
+// Revision 1.5 2009/02/28 00:26:14 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.4 2007/03/14 17:48:37 acg
+// Andy Goodrich: fixed bug.
+//
+// Revision 1.3 2007/01/18 19:29:18 acg
+// Andy Goodrich: fixed bug in concatenations of bit selects on sc_lv and
+// sc_bv types. The offending code was in sc_bitref<X>::set_word and
+// sc_bitref<X>::get_word. These methods were not writing the bit they
+// represented, but rather writing an entire word whose index was the
+// index of the bit they represented. This not only did not write the
+// correct bit, but clobbered a word that might not even be in the
+// variable the reference was for.
+//
+// Revision 1.2 2007/01/17 22:45:08 acg
+// Andy Goodrich: fixed sc_bitref<X>::set_bit().
+//
+// Revision 1.1.1.1 2006/12/15 20:31:36 acg
+// SystemC 2.2
+//
+// Revision 1.3 2006/01/13 18:53:53 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+
+#endif
diff --git a/ext/systemc/src/sysc/datatypes/bit/sc_bv.h b/ext/systemc/src/sysc/datatypes/bit/sc_bv.h
new file mode 100644
index 000000000..de4221c7f
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/bit/sc_bv.h
@@ -0,0 +1,201 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_bv.h -- Arbitrary size bit vector class.
+
+ Original Author: Gene Bushuyev, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_bv.h,v $
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:53 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#ifndef SC_BV_H
+#define SC_BV_H
+
+
+#include "sysc/datatypes/bit/sc_bv_base.h"
+
+
+namespace sc_dt
+{
+
+// classes defined in this module
+template <int W> class sc_bv;
+
+
+// ----------------------------------------------------------------------------
+// CLASS TEMPLATE : sc_bv<W>
+//
+// Arbitrary size bit vector class.
+// ----------------------------------------------------------------------------
+
+template <int W>
+class sc_bv
+ : public sc_bv_base
+{
+public:
+
+ // constructors
+
+ sc_bv()
+ :sc_bv_base( W )
+ {}
+
+ explicit sc_bv( bool init_value )
+ : sc_bv_base( init_value, W )
+ {}
+
+ explicit sc_bv( char init_value )
+ : sc_bv_base( (init_value != '0'), W )
+ {}
+
+ sc_bv( const char* a )
+ : sc_bv_base( W )
+ { sc_bv_base::operator = ( a ); }
+
+ sc_bv( const bool* a )
+ : sc_bv_base( W )
+ { sc_bv_base::operator = ( a ); }
+
+ sc_bv( const sc_logic* a )
+ : sc_bv_base( W )
+ { sc_bv_base::operator = ( a ); }
+
+ sc_bv( const sc_unsigned& a )
+ : sc_bv_base( W )
+ { sc_bv_base::operator = ( a ); }
+
+ sc_bv( const sc_signed& a )
+ : sc_bv_base( W )
+ { sc_bv_base::operator = ( a ); }
+
+ sc_bv( const sc_uint_base& a )
+ : sc_bv_base( W )
+ { sc_bv_base::operator = ( a ); }
+
+ sc_bv( const sc_int_base& a )
+ : sc_bv_base( W )
+ { sc_bv_base::operator = ( a ); }
+
+ sc_bv( unsigned long a )
+ : sc_bv_base( W )
+ { sc_bv_base::operator = ( a ); }
+
+ sc_bv( long a )
+ : sc_bv_base( W )
+ { sc_bv_base::operator = ( a ); }
+
+ sc_bv( unsigned int a )
+ : sc_bv_base( W )
+ { sc_bv_base::operator = ( a ); }
+
+ sc_bv( int a )
+ : sc_bv_base( W )
+ { sc_bv_base::operator = ( a ); }
+
+ sc_bv( uint64 a )
+ : sc_bv_base( W )
+ { sc_bv_base::operator = ( a ); }
+
+ sc_bv( int64 a )
+ : sc_bv_base( W )
+ { sc_bv_base::operator = ( a ); }
+
+ template <class X>
+ sc_bv( const sc_proxy<X>& a )
+ : sc_bv_base( W )
+ { sc_bv_base::operator = ( a ); }
+
+ sc_bv( const sc_bv<W>& a )
+ : sc_bv_base( a )
+ {}
+
+
+ // assignment operators
+
+ template <class X>
+ sc_bv<W>& operator = ( const sc_proxy<X>& a )
+ { sc_bv_base::operator = ( a ); return *this; }
+
+ sc_bv<W>& operator = ( const sc_bv<W>& a )
+ { sc_bv_base::operator = ( a ); return *this; }
+
+ sc_bv<W>& operator = ( const char* a )
+ { sc_bv_base::operator = ( a ); return *this; }
+
+ sc_bv<W>& operator = ( const bool* a )
+ { sc_bv_base::operator = ( a ); return *this; }
+
+ sc_bv<W>& operator = ( const sc_logic* a )
+ { sc_bv_base::operator = ( a ); return *this; }
+
+ sc_bv<W>& operator = ( const sc_unsigned& a )
+ { sc_bv_base::operator = ( a ); return *this; }
+
+ sc_bv<W>& operator = ( const sc_signed& a )
+ { sc_bv_base::operator = ( a ); return *this; }
+
+ sc_bv<W>& operator = ( const sc_uint_base& a )
+ { sc_bv_base::operator = ( a ); return *this; }
+
+ sc_bv<W>& operator = ( const sc_int_base& a )
+ { sc_bv_base::operator = ( a ); return *this; }
+
+ sc_bv<W>& operator = ( unsigned long a )
+ { sc_bv_base::operator = ( a ); return *this; }
+
+ sc_bv<W>& operator = ( long a )
+ { sc_bv_base::operator = ( a ); return *this; }
+
+ sc_bv<W>& operator = ( unsigned int a )
+ { sc_bv_base::operator = ( a ); return *this; }
+
+ sc_bv<W>& operator = ( int a )
+ { sc_bv_base::operator = ( a ); return *this; }
+
+ sc_bv<W>& operator = ( uint64 a )
+ { sc_bv_base::operator = ( a ); return *this; }
+
+ sc_bv<W>& operator = ( int64 a )
+ { sc_bv_base::operator = ( a ); return *this; }
+};
+
+} // namespace sc_dt
+
+
+#endif
diff --git a/ext/systemc/src/sysc/datatypes/bit/sc_bv_base.cpp b/ext/systemc/src/sysc/datatypes/bit/sc_bv_base.cpp
new file mode 100644
index 000000000..b6ffaa32b
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/bit/sc_bv_base.cpp
@@ -0,0 +1,388 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_bv_base.cpp -- Arbitrary size bit vector class.
+
+ Original Author: Gene Bushuyev, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// $Log: sc_bv_base.cpp,v $
+// Revision 1.2 2011/08/24 22:05:40 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.4 2006/04/11 23:12:26 acg
+// Andy Goodrich: Fixed bug in parsing of extended string constants like
+// 0bus1110011.
+//
+// Revision 1.3 2006/01/13 18:53:53 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#include <string.h>
+
+#include "sysc/datatypes/bit/sc_bit_ids.h"
+#include "sysc/datatypes/bit/sc_bv_base.h"
+#include "sysc/datatypes/fx/sc_fix.h"
+#include "sysc/datatypes/fx/sc_ufix.h"
+
+
+namespace sc_dt
+{
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_bv_base
+//
+// Arbitrary size bit vector base class.
+// ----------------------------------------------------------------------------
+
+void
+sc_bv_base::init( int length_, bool init_value )
+{
+ // check the length
+ if( length_ <= 0 ) {
+ SC_REPORT_ERROR( sc_core::SC_ID_ZERO_LENGTH_, 0 );
+ }
+ // allocate memory for the data and control words
+ m_len = length_;
+ m_size = (m_len - 1) / SC_DIGIT_SIZE + 1;
+ m_data = new sc_digit[m_size];
+ // initialize the bits to 'init_value'
+ sc_digit dw = init_value ? ~SC_DIGIT_ZERO : SC_DIGIT_ZERO;
+ int sz = m_size;
+ for( int i = 0; i < sz; ++ i ) {
+ m_data[i] = dw;
+ }
+ clean_tail();
+}
+
+
+void
+sc_bv_base::assign_from_string( const std::string& s )
+{
+ // s must have been converted to bin
+ int len = m_len;
+ int s_len = s.length() - 1;
+ int min_len = sc_min( len, s_len );
+ int i = 0;
+ for( ; i < min_len; ++ i ) {
+ char c = s[s_len - i - 1];
+ if( c != '0' && c != '1' ) {
+ SC_REPORT_ERROR( sc_core::SC_ID_CANNOT_CONVERT_,
+ "string can contain only '0' and '1' characters" );
+ }
+ set_bit( i, sc_logic_value_t( c - '0' ) );
+ }
+ // if formatted, fill the rest with sign(s), otherwise fill with zeros
+ sc_logic_value_t fill = (s[s_len] == 'F' ? sc_logic_value_t( s[0] - '0' )
+ : sc_logic_value_t( 0 ));
+ for( ; i < len; ++ i ) {
+ set_bit( i, fill );
+ }
+}
+
+
+// constructors
+
+sc_bv_base::sc_bv_base( const char* a )
+ : m_len( 0 ), m_size( 0 ), m_data( 0 )
+{
+ std::string s = convert_to_bin( a );
+ init( s.length() - 1 );
+ assign_from_string( s );
+}
+
+sc_bv_base::sc_bv_base( const char* a, int length_ )
+ : m_len( 0 ), m_size( 0 ), m_data( 0 )
+{
+ init( length_ );
+ assign_from_string( convert_to_bin( a ) );
+}
+
+sc_bv_base::sc_bv_base( const sc_bv_base& a )
+ : sc_proxy<sc_bv_base>(),
+ m_len( a.m_len ),
+ m_size( a.m_size ),
+ m_data( new sc_digit[m_size] )
+{
+ // copy the bits
+ int sz = m_size;
+ for( int i = 0; i < sz; ++ i ) {
+ m_data[i] = a.m_data[i];
+ }
+}
+
+
+// assignment operators
+
+sc_bv_base&
+sc_bv_base::operator = ( const char* a )
+{
+ assign_from_string( convert_to_bin( a ) );
+ return *this;
+}
+
+
+#if 0
+
+// bitwise complement
+
+sc_bv_base&
+sc_bv_base::b_not()
+{
+ int sz = m_size;
+ for( int i = 0; i < sz; ++ i ) {
+ m_data[i] = ~m_data[i];
+ }
+ clean_tail();
+ return *this;
+}
+
+
+// bitwise left shift
+
+sc_bv_base&
+sc_bv_base::operator <<= ( int n )
+{
+ if( n < 0 ) {
+ char msg[BUFSIZ];
+ std::sprintf( msg,
+ "left shift operation is only allowed with positive "
+ "shift values, shift value = %d", n );
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
+ }
+ int sz = m_size;
+ if( n >= m_len ) {
+ for( int i = 0; i < sz; ++ i ) {
+ m_data[i] = SC_DIGIT_ZERO;
+ }
+ // clean_tail();
+ return *this;
+ }
+ int wn = n / SC_DIGIT_SIZE;
+ int bn = n % SC_DIGIT_SIZE;
+ if( wn != 0 ) {
+ // shift words
+ int i = sz - 1;
+ for( ; i >= wn; -- i ) {
+ m_data[i] = m_data[i - wn];
+ }
+ for( ; i >= 0; -- i ) {
+ m_data[i] = SC_DIGIT_ZERO;
+ }
+ }
+ if( bn != 0 ) {
+ // shift bits
+ for( int i = sz - 1; i >= 1; -- i ) {
+ m_data[i] <<= bn;
+ m_data[i] |= m_data[i - 1] >> (SC_DIGIT_SIZE - bn);
+ }
+ m_data[0] <<= bn;
+ }
+ clean_tail();
+ return *this;
+}
+
+
+// bitwise right shift
+
+sc_bv_base&
+sc_bv_base::operator >>= ( int n )
+{
+ if( n < 0 ) {
+ char msg[BUFSIZ];
+ std::sprintf( msg,
+ "right shift operation is only allowed with positive "
+ "shift values, shift value = %d", n );
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
+ }
+ int sz = m_size;
+ if( n >= m_len ) {
+ for( int i = 0; i < sz; ++ i ) {
+ m_data[i] = SC_DIGIT_ZERO;
+ }
+ // clean_tail();
+ return *this;
+ }
+ int wn = n / SC_DIGIT_SIZE;
+ int bn = n % SC_DIGIT_SIZE;
+ if( wn != 0 ) {
+ // shift words
+ int i = 0;
+ for( ; i < (sz - wn); ++ i ) {
+ m_data[i] = m_data[i + wn];
+ }
+ for( ; i < sz; ++ i ) {
+ m_data[i] = SC_DIGIT_ZERO;
+ }
+ }
+ if( bn != 0 ) {
+ // shift bits
+ for( int i = 0; i < (sz - 1); ++ i ) {
+ m_data[i] >>= bn;
+ m_data[i] |= m_data[i + 1] << (SC_DIGIT_SIZE - bn);
+ }
+ m_data[sz - 1] >>= bn;
+ }
+ clean_tail();
+ return *this;
+}
+
+
+// bitwise left rotate
+
+sc_bv_base&
+sc_bv_base::lrotate( int n )
+{
+ if( n < 0 ) {
+ char msg[BUFSIZ];
+ std::sprintf( msg,
+ "left rotate operation is only allowed with positive "
+ "rotate values, rotate value = %d", n );
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
+ }
+ int len = m_len;
+ n %= len;
+ *this = (*this << n) | (*this >> (len - n));
+ return *this;
+}
+
+
+// bitwise right rotate
+
+sc_bv_base&
+sc_bv_base::rrotate( int n )
+{
+ if( n < 0 ) {
+ char msg[BUFSIZ];
+ std::sprintf( msg,
+ "right rotate operation is only allowed with positive "
+ "rotate values, rotate value = %d", n );
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
+ }
+ int len = m_len;
+ n %= len;
+ *this = (*this >> n) | (*this << (len - n));
+ return *this;
+}
+
+#endif
+
+
+// ----------------------------------------------------------------------------
+
+// convert formatted string to binary string
+
+const std::string
+convert_to_bin( const char* s )
+{
+ // Beware: logic character strings cannot start with '0x' or '0X',
+ // because this is seen as a hexadecimal encoding prefix!
+
+ if( s == 0 ) {
+ SC_REPORT_ERROR(sc_core::SC_ID_CANNOT_CONVERT_,
+ "character string is zero" );
+ }
+ if( *s == 0 ) {
+ SC_REPORT_ERROR(sc_core::SC_ID_CANNOT_CONVERT_,
+ "character string is empty");
+ }
+
+ int n = strlen( s );
+ int i = 0;
+ if( s[0] == '-' || s[0] == '+' ) {
+ ++ i;
+ }
+ if( n > (i + 2) && s[i] == '0' )
+ {
+ if (s[i+1] == 'b' || s[i+1] == 'B' )
+ {
+ if ( s[i+2] == '0' || s[i+2] == '1' )
+ {
+ std::string str( &s[2] );
+ str += "F";
+ return str;
+ }
+ }
+ if ( s[i+1] == 'b' || s[i+1] == 'B' ||
+ s[i+1] == 'c' || s[i+1] == 'C' ||
+ s[i+1] == 'd' || s[i+1] == 'D' ||
+ s[i+1] == 'o' || s[i+1] == 'O' ||
+ s[i+1] == 'x' || s[i+1] == 'X')
+ {
+ try {
+ // worst case length = n * 4
+ sc_fix a( s, n * 4, n * 4, SC_TRN, SC_WRAP, 0, SC_ON );
+ std::string str = a.to_bin();
+ str += "F"; // mark the string as formatted
+ // get rid of prefix (0b) and redundant leading bits
+ const char* p = str.c_str() + 2;
+ while( p[1] && p[0] == p[1] ) {
+ ++ p;
+ }
+ return std::string( p );
+ } catch( sc_core::sc_report ) {
+ char msg[BUFSIZ];
+ std::sprintf( msg, "character string '%s' is not valid", s );
+ SC_REPORT_ERROR( sc_core::SC_ID_CANNOT_CONVERT_, msg );
+ // never reached
+ return std::string();
+ }
+ }
+
+ }
+
+ // bin by default
+
+ std::string str( s );
+ str += "U"; // mark the string as unformatted
+ return str;
+}
+
+// convert binary string to formatted string
+
+const std::string
+convert_to_fmt( const std::string& s, sc_numrep numrep, bool w_prefix )
+{
+ int n = s.length();
+ std::string str("0bus");
+ // str += "0bus";
+ str += s;
+ sc_ufix a( str.c_str(), n, n, SC_TRN, SC_WRAP, 0, SC_ON );
+ return a.to_string( numrep, w_prefix );
+}
+
+} // namespace sc_dt
diff --git a/ext/systemc/src/sysc/datatypes/bit/sc_bv_base.h b/ext/systemc/src/sysc/datatypes/bit/sc_bv_base.h
new file mode 100644
index 000000000..279001da5
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/bit/sc_bv_base.h
@@ -0,0 +1,339 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_bv_base.h -- Arbitrary size bit vector class.
+
+ Original Author: Gene Bushuyev, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_bv_base.h,v $
+// Revision 1.3 2011/08/26 22:32:00 acg
+// Torsten Maehne: added parentheses to make opearator ordering more obvious.
+//
+// Revision 1.2 2011/08/15 16:43:24 acg
+// Torsten Maehne: changes to remove unused argument warnings.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:53 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#ifndef SC_BV_BASE_H
+#define SC_BV_BASE_H
+
+
+#include "sysc/datatypes/bit/sc_bit_ids.h"
+#include "sysc/datatypes/bit/sc_bit_proxies.h"
+#include "sysc/datatypes/bit/sc_proxy.h"
+#include "sysc/datatypes/int/sc_length_param.h"
+
+
+namespace sc_dt
+{
+
+// classes defined in this module
+class sc_bv_base;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_bv_base
+//
+// Arbitrary size bit vector base class.
+// ----------------------------------------------------------------------------
+
+class sc_bv_base
+ : public sc_proxy<sc_bv_base>
+{
+ friend class sc_lv_base;
+
+
+ void init( int length_, bool init_value = false );
+
+ void assign_from_string( const std::string& );
+
+public:
+
+ // typedefs
+
+ typedef sc_proxy<sc_bv_base> base_type;
+
+
+ // constructors
+
+ explicit sc_bv_base( int length_ = sc_length_param().len() )
+ : m_len( 0 ), m_size( 0 ), m_data( 0 )
+ { init( length_ ); }
+
+ explicit sc_bv_base( bool a,
+ int length_ = sc_length_param().len() )
+ : m_len( 0 ), m_size( 0 ), m_data( 0 )
+ { init( length_, a ); }
+
+ sc_bv_base( const char* a );
+
+ sc_bv_base( const char* a, int length_ );
+
+ template <class X>
+ sc_bv_base( const sc_proxy<X>& a )
+ : m_len( 0 ), m_size( 0 ), m_data( 0 )
+ { init( a.back_cast().length() ); base_type::assign_( a ); }
+
+ sc_bv_base( const sc_bv_base& a );
+
+#ifdef SC_DT_DEPRECATED
+
+ explicit sc_bv_base( const sc_unsigned& a )
+ : m_len( 0 ), m_size( 0 ), m_data( 0 )
+ { init( a.length() ); base_type::assign_( a ); }
+
+ explicit sc_bv_base( const sc_signed& a )
+ : m_len( 0 ), m_size( 0 ), m_data( 0 )
+ { init( a.length() ); base_type::assign_( a ); }
+
+ explicit sc_bv_base( const sc_uint_base& a)
+ : m_len( 0 ), m_size( 0 ), m_data( 0 )
+ { init( a.length() ); base_type::assign_( a ); }
+
+ explicit sc_bv_base( const sc_int_base& a)
+ : m_len( 0 ), m_size( 0 ), m_data( 0 )
+ { init( a.length() ); base_type::assign_( a ); }
+
+#endif
+
+
+ // destructor
+
+ virtual ~sc_bv_base()
+ { delete [] m_data; }
+
+
+ // assignment operators
+
+ template <class X>
+ sc_bv_base& operator = ( const sc_proxy<X>& a )
+ { assign_p_( *this, a ); return *this; }
+
+ sc_bv_base& operator = ( const sc_bv_base& a )
+ { assign_p_( *this, a ); return *this; }
+
+ sc_bv_base& operator = ( const char* a );
+
+ sc_bv_base& operator = ( const bool* a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_bv_base& operator = ( const sc_logic* a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_bv_base& operator = ( const sc_unsigned& a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_bv_base& operator = ( const sc_signed& a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_bv_base& operator = ( const sc_uint_base& a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_bv_base& operator = ( const sc_int_base& a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_bv_base& operator = ( unsigned long a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_bv_base& operator = ( long a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_bv_base& operator = ( unsigned int a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_bv_base& operator = ( int a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_bv_base& operator = ( uint64 a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_bv_base& operator = ( int64 a )
+ { base_type::assign_( a ); return *this; }
+
+
+#if 0
+
+ // bitwise complement
+
+ sc_bv_base& b_not();
+
+ const sc_bv_base operator ~ () const
+ { sc_bv_base a( *this ); return a.b_not(); }
+
+
+ // bitwise left shift
+
+ sc_bv_base& operator <<= ( int n );
+
+ const sc_bv_base operator << ( int n ) const
+ { sc_bv_base a( *this ); return ( a <<= n ); }
+
+
+ // bitwise right shift
+
+ sc_bv_base& operator >>= ( int n );
+
+ const sc_bv_base operator >> ( int n ) const
+ { sc_bv_base a( *this ); return ( a >>= n ); }
+
+
+ // bitwise left rotate
+
+ sc_bv_base& lrotate( int n );
+
+
+ // bitwise right rotate
+
+ sc_bv_base& rrotate( int n );
+
+#endif
+
+
+ // common methods
+
+ int length() const
+ { return m_len; }
+
+ int size() const
+ { return m_size; }
+
+ sc_logic_value_t get_bit( int i ) const;
+ void set_bit( int i, sc_logic_value_t value );
+
+ sc_digit get_word( int i ) const
+ { return m_data[i]; }
+
+ void set_word( int i, sc_digit w )
+ { m_data[i] = w; }
+
+ sc_digit get_cword( int /*i*/ ) const
+ { return SC_DIGIT_ZERO; }
+
+ void set_cword( int i, sc_digit w );
+
+ void clean_tail();
+
+
+ // other methods
+
+ bool is_01() const
+ { return true; }
+
+protected:
+
+ int m_len; // length in bits
+ int m_size; // size of data array
+ sc_digit* m_data; // data array
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+#if 0
+
+// bitwise left rotate
+
+inline
+const sc_bv_base
+lrotate( const sc_bv_base& x, int n )
+{
+ sc_bv_base a( x );
+ return a.lrotate( n );
+}
+
+
+// bitwise right rotate
+
+inline
+const sc_bv_base
+rrotate( const sc_bv_base& x, int n )
+{
+ sc_bv_base a( x );
+ return a.rrotate( n );
+}
+
+#endif
+
+
+// common methods
+
+inline
+sc_logic_value_t
+sc_bv_base::get_bit( int i ) const
+{
+ int wi = i / SC_DIGIT_SIZE;
+ int bi = i % SC_DIGIT_SIZE;
+ return sc_logic_value_t( (m_data[wi] >> bi) & SC_DIGIT_ONE );
+}
+
+inline
+void
+sc_bv_base::set_bit( int i, sc_logic_value_t value )
+{
+ int wi = i / SC_DIGIT_SIZE;
+ int bi = i % SC_DIGIT_SIZE;
+ sc_digit mask = SC_DIGIT_ONE << bi;
+ m_data[wi] |= mask; // set bit to 1
+ m_data[wi] &= value << bi | ~mask;
+}
+
+
+inline
+void
+sc_bv_base::set_cword( int /*i*/, sc_digit w )
+{
+ if( w ) {
+ SC_REPORT_WARNING( sc_core::SC_ID_SC_BV_CANNOT_CONTAIN_X_AND_Z_, 0 );
+ }
+}
+
+
+inline
+void
+sc_bv_base::clean_tail()
+{
+ int wi = m_size - 1;
+ int bi = m_len % SC_DIGIT_SIZE;
+ if ( bi != 0 ) m_data[wi] &= ~SC_DIGIT_ZERO >> (SC_DIGIT_SIZE - bi);
+}
+
+} // namespace sc_dt
+
+
+#endif
diff --git a/ext/systemc/src/sysc/datatypes/bit/sc_logic.cpp b/ext/systemc/src/sysc/datatypes/bit/sc_logic.cpp
new file mode 100644
index 000000000..15525f5c5
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/bit/sc_logic.cpp
@@ -0,0 +1,175 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_logic.cpp -- C++ implementation of logic type. Behaves
+ pretty much the same way as HDLs logic type.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// $Log: sc_logic.cpp,v $
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:53 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#include "sysc/datatypes/bit/sc_bit_ids.h"
+#include "sysc/datatypes/bit/sc_logic.h"
+
+
+namespace sc_dt
+{
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_logic
+//
+// Four-valued logic type.
+// ----------------------------------------------------------------------------
+
+// support methods
+
+void
+sc_logic::invalid_value( sc_logic_value_t v )
+{
+ char msg[BUFSIZ];
+ std::sprintf( msg, "sc_logic( %d )", v );
+ SC_REPORT_ERROR( sc_core::SC_ID_VALUE_NOT_VALID_, msg );
+}
+
+void
+sc_logic::invalid_value( char c )
+{
+ char msg[BUFSIZ];
+ std::sprintf( msg, "sc_logic( '%c' )", c );
+ SC_REPORT_ERROR( sc_core::SC_ID_VALUE_NOT_VALID_, msg );
+}
+
+void
+sc_logic::invalid_value( int i )
+{
+ char msg[BUFSIZ];
+ std::sprintf( msg, "sc_logic( %d )", i );
+ SC_REPORT_ERROR( sc_core::SC_ID_VALUE_NOT_VALID_, msg );
+}
+
+
+void
+sc_logic::invalid_01() const
+{
+ if( (int) m_val == Log_Z ) {
+ SC_REPORT_WARNING( sc_core::SC_ID_LOGIC_Z_TO_BOOL_, 0 );
+ } else {
+ SC_REPORT_WARNING( sc_core::SC_ID_LOGIC_X_TO_BOOL_, 0 );
+ }
+}
+
+
+// conversion tables
+
+const sc_logic_value_t sc_logic::char_to_logic[128] =
+{
+ Log_0, Log_1, Log_Z, Log_X, Log_X, Log_X, Log_X, Log_X,
+ Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X,
+ Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X,
+ Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X,
+ Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X,
+ Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X,
+ Log_0, Log_1, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X,
+ Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X,
+ Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X,
+ Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X,
+ Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X,
+ Log_X, Log_X, Log_Z, Log_X, Log_X, Log_X, Log_X, Log_X,
+ Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X,
+ Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X,
+ Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X, Log_X,
+ Log_X, Log_X, Log_Z, Log_X, Log_X, Log_X, Log_X, Log_X
+};
+
+const char sc_logic::logic_to_char[4] = { '0', '1', 'Z', 'X' };
+
+const sc_logic_value_t sc_logic::and_table[4][4] =
+{
+ { Log_0, Log_0, Log_0, Log_0 },
+ { Log_0, Log_1, Log_X, Log_X },
+ { Log_0, Log_X, Log_X, Log_X },
+ { Log_0, Log_X, Log_X, Log_X }
+};
+
+const sc_logic_value_t sc_logic::or_table[4][4] =
+{
+ { Log_0, Log_1, Log_X, Log_X },
+ { Log_1, Log_1, Log_1, Log_1 },
+ { Log_X, Log_1, Log_X, Log_X },
+ { Log_X, Log_1, Log_X, Log_X }
+};
+
+const sc_logic_value_t sc_logic::xor_table[4][4] =
+{
+ { Log_0, Log_1, Log_X, Log_X },
+ { Log_1, Log_0, Log_X, Log_X },
+ { Log_X, Log_X, Log_X, Log_X },
+ { Log_X, Log_X, Log_X, Log_X }
+};
+
+const sc_logic_value_t sc_logic::not_table[4] =
+ { Log_1, Log_0, Log_X, Log_X };
+
+
+// other methods
+
+void
+sc_logic::scan( ::std::istream& is )
+{
+ char c;
+ is >> c;
+ *this = c;
+}
+
+
+// #ifdef SC_DT_DEPRECATED
+const sc_logic sc_logic_0( Log_0 );
+const sc_logic sc_logic_1( Log_1 );
+const sc_logic sc_logic_Z( Log_Z );
+const sc_logic sc_logic_X( Log_X );
+// #endif
+
+const sc_logic SC_LOGIC_0( Log_0 );
+const sc_logic SC_LOGIC_1( Log_1 );
+const sc_logic SC_LOGIC_Z( Log_Z );
+const sc_logic SC_LOGIC_X( Log_X );
+
+} // namespace sc_dt
diff --git a/ext/systemc/src/sysc/datatypes/bit/sc_logic.h b/ext/systemc/src/sysc/datatypes/bit/sc_logic.h
new file mode 100644
index 000000000..6008e3e2e
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/bit/sc_logic.h
@@ -0,0 +1,384 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_logic.h -- C++ implementation of logic type. Behaves
+ pretty much the same way as HDLs except with 4 values.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_logic.h,v $
+// Revision 1.3 2011/08/07 18:54:19 acg
+// Philipp A. Hartmann: remove friend function declarations that implement
+// code, and clean up how bit and logic operators are defined in general.
+//
+// Revision 1.2 2011/01/25 20:50:37 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.5 2006/12/02 21:00:57 acg
+// Andy Goodrich: fixes for concatenation support.
+//
+// Revision 1.4 2006/05/08 17:49:59 acg
+// Andy Goodrich: Added David Long's declarations for friend operators,
+// functions, and methods, to keep the Microsoft compiler happy.
+//
+// Revision 1.3 2006/01/13 18:53:53 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#ifndef SC_LOGIC_H
+#define SC_LOGIC_H
+
+
+#include <cstdio>
+
+#include "sysc/utils/sc_iostream.h"
+#include "sysc/kernel/sc_macros.h"
+#include "sysc/utils/sc_mempool.h"
+#include "sysc/datatypes/bit/sc_bit.h"
+
+
+namespace sc_dt
+{
+
+// classes defined in this module
+class sc_logic;
+
+
+// ----------------------------------------------------------------------------
+// ENUM : sc_logic_value_t
+//
+// Enumeration of values for sc_logic.
+// ----------------------------------------------------------------------------
+
+enum sc_logic_value_t
+{
+ Log_0 = 0,
+ Log_1,
+ Log_Z,
+ Log_X
+};
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_logic
+//
+// Four-valued logic type.
+// ----------------------------------------------------------------------------
+
+class sc_logic
+{
+private:
+
+ // support methods
+
+ static void invalid_value( sc_logic_value_t );
+ static void invalid_value( char );
+ static void invalid_value( int );
+
+ static sc_logic_value_t to_value( sc_logic_value_t v )
+ {
+ if( v < Log_0 || v > Log_X ) {
+ invalid_value( v );
+ }
+ return v;
+ }
+
+ static sc_logic_value_t to_value( bool b )
+ { return ( b ? Log_1 : Log_0 ); }
+
+ static sc_logic_value_t to_value( char c )
+ {
+ sc_logic_value_t v;
+ unsigned int index = (int)c;
+ if ( index > 127 )
+ {
+ invalid_value(c);
+ v = Log_X;
+ }
+ else
+ {
+ v = char_to_logic[index];
+ if( v < Log_0 || v > Log_X ) {
+ invalid_value( c );
+ }
+ }
+ return v;
+ }
+
+ static sc_logic_value_t to_value( int i )
+ {
+ if( i < 0 || i > 3 ) {
+ invalid_value( i );
+ }
+ return sc_logic_value_t( i );
+ }
+
+
+ void invalid_01() const;
+
+public:
+
+ // conversion tables
+
+ static const sc_logic_value_t char_to_logic[128];
+ static const char logic_to_char[4];
+ static const sc_logic_value_t and_table[4][4];
+ static const sc_logic_value_t or_table[4][4];
+ static const sc_logic_value_t xor_table[4][4];
+ static const sc_logic_value_t not_table[4];
+
+
+ // constructors
+
+ sc_logic()
+ : m_val( Log_X )
+ {}
+
+ sc_logic( const sc_logic& a )
+ : m_val( a.m_val )
+ {}
+
+ sc_logic( sc_logic_value_t v )
+ : m_val( to_value( v ) )
+ {}
+
+ explicit sc_logic( bool a )
+ : m_val( to_value( a ) )
+ {}
+
+ explicit sc_logic( char a )
+ : m_val( to_value( a ) )
+ {}
+
+ explicit sc_logic( int a )
+ : m_val( to_value( a ) )
+ {}
+
+ explicit sc_logic( const sc_bit& a )
+ : m_val( to_value( a.to_bool() ) )
+ {}
+
+
+ // destructor
+
+ ~sc_logic()
+ {}
+
+
+ // (bitwise) assignment operators
+
+#define DEFN_ASN_OP_T(op,tp) \
+ sc_logic& operator op ( tp v ) \
+ { *this op sc_logic( v ); return *this; }
+
+#define DEFN_ASN_OP(op) \
+ DEFN_ASN_OP_T(op, sc_logic_value_t) \
+ DEFN_ASN_OP_T(op, bool) \
+ DEFN_ASN_OP_T(op, char) \
+ DEFN_ASN_OP_T(op, int ) \
+ DEFN_ASN_OP_T(op, const sc_bit& )
+
+ sc_logic& operator = ( const sc_logic& a )
+ { m_val = a.m_val; return *this; }
+
+ sc_logic& operator &= ( const sc_logic& b )
+ { m_val = and_table[m_val][b.m_val]; return *this; }
+
+ sc_logic& operator |= ( const sc_logic& b )
+ { m_val = or_table[m_val][b.m_val]; return *this; }
+
+ sc_logic& operator ^= ( const sc_logic& b )
+ { m_val = xor_table[m_val][b.m_val]; return *this; }
+
+ DEFN_ASN_OP(=)
+ DEFN_ASN_OP(&=)
+ DEFN_ASN_OP(|=)
+ DEFN_ASN_OP(^=)
+
+#undef DEFN_ASN_OP_T
+#undef DEFN_ASN_OP
+
+
+ // bitwise operators and functions
+
+
+ friend const sc_logic operator & ( const sc_logic&, const sc_logic& );
+ friend const sc_logic operator | ( const sc_logic&, const sc_logic& );
+ friend const sc_logic operator ^ ( const sc_logic&, const sc_logic& );
+
+ // relational operators
+
+ friend bool operator == ( const sc_logic&, const sc_logic& );
+ friend bool operator != ( const sc_logic&, const sc_logic& );
+
+ // bitwise complement
+
+ const sc_logic operator ~ () const
+ { return sc_logic( not_table[m_val] ); }
+
+ sc_logic& b_not()
+ { m_val = not_table[m_val]; return *this; }
+
+
+ // explicit conversions
+
+ sc_logic_value_t value() const
+ { return m_val; }
+
+
+ bool is_01() const
+ { return ( (int) m_val == Log_0 || (int) m_val == Log_1 ); }
+
+ bool to_bool() const
+ { if( ! is_01() ) { invalid_01(); } return ( (int) m_val != Log_0 ); }
+
+ char to_char() const
+ { return logic_to_char[m_val]; }
+
+
+ // other methods
+
+ void print( ::std::ostream& os = ::std::cout ) const
+ { os << to_char(); }
+
+ void scan( ::std::istream& is = ::std::cin );
+
+
+ // memory (de)allocation
+
+ static void* operator new( std::size_t, void* p ) // placement new
+ { return p; }
+
+ static void* operator new( std::size_t sz )
+ { return sc_core::sc_mempool::allocate( sz ); }
+
+ static void operator delete( void* p, std::size_t sz )
+ { sc_core::sc_mempool::release( p, sz ); }
+
+ static void* operator new [] ( std::size_t sz )
+ { return sc_core::sc_mempool::allocate( sz ); }
+
+ static void operator delete [] ( void* p, std::size_t sz )
+ { sc_core::sc_mempool::release( p, sz ); }
+
+private:
+
+ sc_logic_value_t m_val;
+
+private:
+
+ // disabled
+ explicit sc_logic( const char* );
+ sc_logic& operator = ( const char* );
+};
+
+// ----------------------------------------------------------------------------
+
+// bitwise operators
+
+inline const sc_logic operator & ( const sc_logic& a, const sc_logic& b )
+ { return sc_logic( sc_logic::and_table[a.m_val][b.m_val] ); }
+
+inline const sc_logic operator | ( const sc_logic& a, const sc_logic& b )
+ { return sc_logic( sc_logic::or_table[a.m_val][b.m_val] ); }
+
+inline const sc_logic operator ^ ( const sc_logic& a, const sc_logic& b )
+ { return sc_logic( sc_logic::xor_table[a.m_val][b.m_val] ); }
+
+#define DEFN_BIN_OP_T(ret,op,tp) \
+ inline ret operator op ( const sc_logic& a, tp b ) \
+ { return ( a op sc_logic( b ) ); } \
+ inline ret operator op ( tp a, const sc_logic& b ) \
+ { return ( sc_logic( a ) op b ); }
+
+#define DEFN_BIN_OP(ret,op) \
+ DEFN_BIN_OP_T(ret,op,sc_logic_value_t) \
+ DEFN_BIN_OP_T(ret,op,bool) \
+ DEFN_BIN_OP_T(ret,op,char) \
+ DEFN_BIN_OP_T(ret,op,int)
+
+DEFN_BIN_OP(const sc_logic,&)
+DEFN_BIN_OP(const sc_logic,|)
+DEFN_BIN_OP(const sc_logic,^)
+
+// relational operators and functions
+
+inline bool operator == ( const sc_logic& a, const sc_logic& b )
+ { return ( (int) a.m_val == b.m_val ); }
+
+inline bool operator != ( const sc_logic& a, const sc_logic& b )
+ { return ( (int) a.m_val != b.m_val ); }
+
+DEFN_BIN_OP(bool,==)
+DEFN_BIN_OP(bool,!=)
+
+#undef DEFN_BIN_OP_T
+#undef DEFN_BIN_OP
+
+// ----------------------------------------------------------------------------
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, const sc_logic& a )
+{
+ a.print( os );
+ return os;
+}
+
+inline
+::std::istream&
+operator >> ( ::std::istream& is, sc_logic& a )
+{
+ a.scan( is );
+ return is;
+}
+
+
+extern const sc_logic SC_LOGIC_0;
+extern const sc_logic SC_LOGIC_1;
+extern const sc_logic SC_LOGIC_Z;
+extern const sc_logic SC_LOGIC_X;
+
+// #ifdef SC_DT_DEPRECATED
+extern const sc_logic sc_logic_0;
+extern const sc_logic sc_logic_1;
+extern const sc_logic sc_logic_Z;
+extern const sc_logic sc_logic_X;
+// #endif
+
+} // namespace sc_dt
+
+#endif
diff --git a/ext/systemc/src/sysc/datatypes/bit/sc_lv.h b/ext/systemc/src/sysc/datatypes/bit/sc_lv.h
new file mode 100644
index 000000000..8eae23b73
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/bit/sc_lv.h
@@ -0,0 +1,205 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_lv.h -- Arbitrary size logic vector class.
+
+ Original Author: Gene Bushuyev, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_lv.h,v $
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:53 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#ifndef SC_LV_H
+#define SC_LV_H
+
+
+#include "sysc/datatypes/bit/sc_lv_base.h"
+
+
+namespace sc_dt
+{
+
+// classes defined in this module
+template <int W> class sc_lv;
+
+
+// ----------------------------------------------------------------------------
+// CLASS TEMPLATE : sc_lv<W>
+//
+// Arbitrary size logic vector class.
+// ----------------------------------------------------------------------------
+
+template <int W>
+class sc_lv
+ : public sc_lv_base
+{
+public:
+
+ // constructors
+
+ sc_lv()
+ : sc_lv_base( W )
+ {}
+
+ explicit sc_lv( const sc_logic& init_value )
+ : sc_lv_base( init_value, W )
+ {}
+
+ explicit sc_lv( bool init_value )
+ : sc_lv_base( sc_logic( init_value ), W )
+ {}
+
+ explicit sc_lv( char init_value )
+ : sc_lv_base( sc_logic( init_value ), W )
+ {}
+
+ sc_lv( const char* a )
+ : sc_lv_base( W )
+ { sc_lv_base::operator = ( a ); }
+
+ sc_lv( const bool* a )
+ : sc_lv_base( W )
+ { sc_lv_base::operator = ( a ); }
+
+ sc_lv( const sc_logic* a )
+ : sc_lv_base( W )
+ { sc_lv_base::operator = ( a ); }
+
+ sc_lv( const sc_unsigned& a )
+ : sc_lv_base( W )
+ { sc_lv_base::operator = ( a ); }
+
+ sc_lv( const sc_signed& a )
+ : sc_lv_base( W )
+ { sc_lv_base::operator = ( a ); }
+
+ sc_lv( const sc_uint_base& a )
+ : sc_lv_base( W )
+ { sc_lv_base::operator = ( a ); }
+
+ sc_lv( const sc_int_base& a )
+ : sc_lv_base( W )
+ { sc_lv_base::operator = ( a ); }
+
+ sc_lv( unsigned long a )
+ : sc_lv_base( W )
+ { sc_lv_base::operator = ( a ); }
+
+ sc_lv( long a )
+ : sc_lv_base( W )
+ { sc_lv_base::operator = ( a ); }
+
+ sc_lv( unsigned int a )
+ : sc_lv_base( W )
+ { sc_lv_base::operator = ( a ); }
+
+ sc_lv( int a )
+ : sc_lv_base( W )
+ { sc_lv_base::operator = ( a ); }
+
+ sc_lv( uint64 a )
+ : sc_lv_base( W )
+ { sc_lv_base::operator = ( a ); }
+
+ sc_lv( int64 a )
+ : sc_lv_base( W )
+ { sc_lv_base::operator = ( a ); }
+
+ template <class X>
+ sc_lv( const sc_proxy<X>& a )
+ : sc_lv_base( W )
+ { sc_lv_base::operator = ( a ); }
+
+ sc_lv( const sc_lv<W>& a )
+ : sc_lv_base( a )
+ {}
+
+
+ // assignment operators
+
+ template <class X>
+ sc_lv<W>& operator = ( const sc_proxy<X>& a )
+ { sc_lv_base::operator = ( a ); return *this; }
+
+ sc_lv<W>& operator = ( const sc_lv<W>& a )
+ { sc_lv_base::operator = ( a ); return *this; }
+
+ sc_lv<W>& operator = ( const char* a )
+ { sc_lv_base::operator = ( a ); return *this; }
+
+ sc_lv<W>& operator = ( const bool* a )
+ { sc_lv_base::operator = ( a ); return *this; }
+
+ sc_lv<W>& operator = ( const sc_logic* a )
+ { sc_lv_base::operator = ( a ); return *this; }
+
+ sc_lv<W>& operator = ( const sc_unsigned& a )
+ { sc_lv_base::operator = ( a ); return *this; }
+
+ sc_lv<W>& operator = ( const sc_signed& a )
+ { sc_lv_base::operator = ( a ); return *this; }
+
+ sc_lv<W>& operator = ( const sc_uint_base& a )
+ { sc_lv_base::operator = ( a ); return *this; }
+
+ sc_lv<W>& operator = ( const sc_int_base& a )
+ { sc_lv_base::operator = ( a ); return *this; }
+
+ sc_lv<W>& operator = ( unsigned long a )
+ { sc_lv_base::operator = ( a ); return *this; }
+
+ sc_lv<W>& operator = ( long a )
+ { sc_lv_base::operator = ( a ); return *this; }
+
+ sc_lv<W>& operator = ( unsigned int a )
+ { sc_lv_base::operator = ( a ); return *this; }
+
+ sc_lv<W>& operator = ( int a )
+ { sc_lv_base::operator = ( a ); return *this; }
+
+ sc_lv<W>& operator = ( uint64 a )
+ { sc_lv_base::operator = ( a ); return *this; }
+
+ sc_lv<W>& operator = ( int64 a )
+ { sc_lv_base::operator = ( a ); return *this; }
+};
+
+} // namespace sc_dt
+
+
+#endif
diff --git a/ext/systemc/src/sysc/datatypes/bit/sc_lv_base.cpp b/ext/systemc/src/sysc/datatypes/bit/sc_lv_base.cpp
new file mode 100644
index 000000000..617d74d03
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/bit/sc_lv_base.cpp
@@ -0,0 +1,173 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_lv_base.cpp -- Arbitrary size logic vector class.
+
+ Original Author: Gene Bushuyev, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// $Log: sc_lv_base.cpp,v $
+// Revision 1.2 2011/08/24 22:05:40 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:53 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#include "sysc/datatypes/bit/sc_bit_ids.h"
+#include "sysc/datatypes/bit/sc_lv_base.h"
+
+
+namespace sc_dt
+{
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_lv_base
+//
+// Arbitrary size logic vector base class.
+// ----------------------------------------------------------------------------
+
+static const sc_digit data_array[] =
+ { SC_DIGIT_ZERO, ~SC_DIGIT_ZERO, SC_DIGIT_ZERO, ~SC_DIGIT_ZERO };
+
+static const sc_digit ctrl_array[] =
+ { SC_DIGIT_ZERO, SC_DIGIT_ZERO, ~SC_DIGIT_ZERO, ~SC_DIGIT_ZERO };
+
+
+void
+sc_lv_base::init( int length_, const sc_logic& init_value )
+{
+ // check the length
+ if( length_ <= 0 ) {
+ SC_REPORT_ERROR( sc_core::SC_ID_ZERO_LENGTH_, 0 );
+ }
+ // allocate memory for the data and control words
+ m_len = length_;
+ m_size = (m_len - 1) / SC_DIGIT_SIZE + 1;
+ m_data = new sc_digit[m_size * 2];
+ m_ctrl = m_data + m_size;
+ // initialize the bits to 'init_value'
+ sc_digit dw = data_array[init_value.value()];
+ sc_digit cw = ctrl_array[init_value.value()];
+ int sz = m_size;
+ for( int i = 0; i < sz; ++ i ) {
+ m_data[i] = dw;
+ m_ctrl[i] = cw;
+ }
+ clean_tail();
+}
+
+
+void
+sc_lv_base::assign_from_string( const std::string& s )
+{
+ // s must have been converted to bin
+ int len = m_len;
+ int s_len = s.length() - 1;
+ int min_len = sc_min( len, s_len );
+ int i = 0;
+ for( ; i < min_len; ++ i ) {
+ char c = s[s_len - i - 1];
+ set_bit( i, sc_logic::char_to_logic[(int)c] );
+ }
+ // if formatted, fill the rest with sign(s), otherwise fill with zeros
+ sc_logic_value_t fill = (s[s_len] == 'F' ? sc_logic_value_t( s[0] - '0' )
+ : sc_logic_value_t( 0 ));
+ for( ; i < len; ++ i ) {
+ set_bit( i, fill );
+ }
+}
+
+
+// constructors
+
+sc_lv_base::sc_lv_base( const char* a )
+ : m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 )
+{
+ std::string s = convert_to_bin( a );
+ init( s.length() - 1 );
+ assign_from_string( s );
+}
+
+sc_lv_base::sc_lv_base( const char* a, int length_ )
+ : m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 )
+{
+ init( length_ );
+ assign_from_string( convert_to_bin( a ) );
+}
+
+sc_lv_base::sc_lv_base( const sc_lv_base& a )
+ : sc_proxy<sc_lv_base>(),
+ m_len( a.m_len ),
+ m_size( a.m_size ),
+ m_data( new sc_digit[m_size * 2] ),
+ m_ctrl( m_data + m_size )
+{
+ // copy the bits
+ int sz = m_size;
+ for( int i = 0; i < sz; ++ i ) {
+ m_data[i] = a.m_data[i];
+ m_ctrl[i] = a.m_ctrl[i];
+ }
+}
+
+
+// assignment operators
+
+sc_lv_base&
+sc_lv_base::operator = ( const char* a )
+{
+ assign_from_string( convert_to_bin( a ) );
+ return *this;
+}
+
+
+// returns true if logic vector contains only 0's and 1's
+
+bool
+sc_lv_base::is_01() const
+{
+ int sz = m_size;
+ for( int i = 0; i < sz; ++ i ) {
+ if( m_ctrl[i] != 0 ) {
+ return false;
+ }
+ }
+ return true;
+}
+
+} // namespace sc_dt
diff --git a/ext/systemc/src/sysc/datatypes/bit/sc_lv_base.h b/ext/systemc/src/sysc/datatypes/bit/sc_lv_base.h
new file mode 100644
index 000000000..313afa56e
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/bit/sc_lv_base.h
@@ -0,0 +1,1827 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_lv_base.h -- Arbitrary size logic vector class.
+
+ Original Author: Gene Bushuyev, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+ Andy Goodrich, Forte Design Systems
+ Fixed bug in clean_tail for sizes that are modulo 32, which caused
+ zeroing of values.
+
+ *****************************************************************************/
+
+// $Log: sc_lv_base.h,v $
+// Revision 1.4 2011/08/26 22:32:00 acg
+// Torsten Maehne: added parentheses to make opearator ordering more obvious.
+//
+// Revision 1.3 2010/01/27 19:41:29 acg
+// Andy Goodrich: fix 8 instances of sc_concref constructor invocations
+// that failed to indicate that their arguments should be freed when the
+// object was freed.
+//
+// Revision 1.2 2009/02/28 00:26:14 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.2 2007/03/14 17:47:49 acg
+// Andy Goodrich: Formatting.
+//
+// Revision 1.1.1.1 2006/12/15 20:31:36 acg
+// SystemC 2.2
+//
+// Revision 1.3 2006/01/13 18:53:53 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#ifndef SC_LV_BASE_H
+#define SC_LV_BASE_H
+
+
+#include "sysc/datatypes/bit/sc_bit_ids.h"
+#include "sysc/datatypes/bit/sc_bv_base.h"
+#include "sysc/datatypes/bit/sc_logic.h"
+#include "sysc/datatypes/int/sc_length_param.h"
+
+
+namespace sc_dt
+{
+
+// classes defined in this module
+class sc_lv_base;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_lv_base
+//
+// Arbitrary size logic vector base class.
+// ----------------------------------------------------------------------------
+
+class sc_lv_base
+ : public sc_proxy<sc_lv_base>
+{
+ friend class sc_bv_base;
+
+
+ void init( int length_, const sc_logic& init_value = SC_LOGIC_X );
+
+ void assign_from_string( const std::string& );
+
+public:
+
+ // typedefs
+
+ typedef sc_proxy<sc_lv_base> base_type;
+
+
+ // constructors
+
+ explicit sc_lv_base( int length_ = sc_length_param().len() )
+ : m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 )
+ { init( length_ ); }
+
+ explicit sc_lv_base( const sc_logic& a,
+ int length_ = sc_length_param().len() )
+ : m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 )
+ { init( length_, a ); }
+
+ sc_lv_base( const char* a );
+
+ sc_lv_base( const char* a, int length_ );
+
+ template <class X>
+ sc_lv_base( const sc_proxy<X>& a )
+ : m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 )
+ { init( a.back_cast().length() ); base_type::assign_( a ); }
+
+ sc_lv_base( const sc_lv_base& a );
+
+#ifdef SC_DT_DEPRECATED
+
+ explicit sc_lv_base( const sc_unsigned& a )
+ : m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 )
+ { init( a.length() ); base_type::assign_( a ); }
+
+ explicit sc_lv_base( const sc_signed& a )
+ : m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 )
+ { init( a.length() ); base_type::assign_( a ); }
+
+ explicit sc_lv_base( const sc_uint_base& a )
+ : m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 )
+ { init( a.length() ); base_type::assign_( a ); }
+
+ explicit sc_lv_base( const sc_int_base& a )
+ : m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 )
+ { init( a.length() ); base_type::assign_( a ); }
+
+#endif
+
+
+ // destructor
+
+ virtual ~sc_lv_base()
+ { delete [] m_data; }
+
+
+ // assignment operators
+
+ template <class X>
+ sc_lv_base& operator = ( const sc_proxy<X>& a )
+ { assign_p_( *this, a ); return *this; }
+
+ sc_lv_base& operator = ( const sc_lv_base& a )
+ { assign_p_( *this, a ); return *this; }
+
+ sc_lv_base& operator = ( const char* a );
+
+ sc_lv_base& operator = ( const bool* a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_lv_base& operator = ( const sc_logic* a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_lv_base& operator = ( const sc_unsigned& a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_lv_base& operator = ( const sc_signed& a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_lv_base& operator = ( const sc_uint_base& a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_lv_base& operator = ( const sc_int_base& a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_lv_base& operator = ( unsigned long a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_lv_base& operator = ( long a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_lv_base& operator = ( unsigned int a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_lv_base& operator = ( int a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_lv_base& operator = ( uint64 a )
+ { base_type::assign_( a ); return *this; }
+
+ sc_lv_base& operator = ( int64 a )
+ { base_type::assign_( a ); return *this; }
+
+
+#if 0
+
+ // bitwise complement
+
+ sc_lv_base& b_not()
+ { return sc_proxy<sc_lv_base>::b_not(); }
+
+ const sc_lv_base operator ~ () const
+ { sc_lv_base a( *this ); return a.b_not(); }
+
+
+ // bitwise left shift
+
+ sc_lv_base& operator <<= ( int n )
+ { return sc_proxy<sc_lv_base>::operator <<= ( n ); }
+
+ const sc_lv_base operator << ( int n ) const
+ { sc_lv_base a( *this ); return ( a <<= n ); }
+
+
+ // bitwise right shift
+
+ sc_lv_base& operator >>= ( int n )
+ { return sc_proxy<sc_lv_base>::operator >>= ( n ); }
+
+ const sc_lv_base operator >> ( int n ) const
+ { sc_lv_base a( *this ); return ( a >>= n ); }
+
+
+ // bitwise left rotate
+
+ sc_lv_base& lrotate( int n )
+ { return sc_proxy<sc_lv_base>::lrotate( n ); }
+
+
+ // bitwise right rotate
+
+ sc_lv_base& rrotate( int n )
+ { return sc_proxy<sc_lv_base>::rrotate( n ); }
+
+#endif
+
+
+ // common methods
+
+ int length() const
+ { return m_len; }
+
+ int size() const
+ { return m_size; }
+
+ sc_logic_value_t get_bit( int i ) const;
+ void set_bit( int i, sc_logic_value_t value );
+
+ sc_digit get_word( int wi ) const
+ { return m_data[wi]; }
+
+ // note the test for out of range access here. this is necessary
+ // because of the hair-brained way concatenations are set up.
+ // an extend_sign on a concatenation uses the whole length of
+ // the concatenation to determine how many words to set.
+ void set_word( int wi, sc_digit w )
+ { assert ( wi < m_size ); m_data[wi] = w; }
+
+
+ sc_digit get_cword( int wi ) const
+ { return m_ctrl[wi]; }
+
+ void set_cword( int wi, sc_digit w )
+ { assert ( wi < m_size ); m_ctrl[wi] = w; }
+
+ void clean_tail();
+
+
+ // other methods
+
+ bool is_01() const;
+
+protected:
+
+ int m_len; // length in bits
+ int m_size; // size of the data array
+ sc_digit* m_data; // data array
+ sc_digit* m_ctrl; // dito (control part)
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+#if 0
+
+// bitwise left rotate
+
+inline
+const sc_lv_base
+lrotate( const sc_lv_base& x, int n )
+{
+ sc_lv_base a( x );
+ return a.lrotate( n );
+}
+
+
+// bitwise right rotate
+
+inline
+const sc_lv_base
+rrotate( const sc_lv_base& x, int n )
+{
+ sc_lv_base a( x );
+ return a.rrotate( n );
+}
+
+#endif
+
+
+inline
+sc_logic_value_t
+sc_lv_base::get_bit( int i ) const
+{
+ int wi = i / SC_DIGIT_SIZE;
+ int bi = i % SC_DIGIT_SIZE;
+ return sc_logic_value_t( ((m_data[wi] >> bi) & SC_DIGIT_ONE) |
+ (((m_ctrl[wi] >> bi) << 1) & SC_DIGIT_TWO) );
+}
+
+inline
+void
+sc_lv_base::set_bit( int i, sc_logic_value_t value )
+{
+ int wi = i / SC_DIGIT_SIZE; // word index
+ int bi = i % SC_DIGIT_SIZE; // bit index
+ sc_digit mask = SC_DIGIT_ONE << bi;
+ m_data[wi] |= mask; // set bit to 1
+ m_ctrl[wi] |= mask; // set bit to 1
+ m_data[wi] &= value << bi | ~mask;
+ m_ctrl[wi] &= value >> 1 << bi | ~mask;
+}
+
+
+inline
+void
+sc_lv_base::clean_tail()
+{
+ int wi = m_size - 1;
+ int bi = m_len % SC_DIGIT_SIZE;
+ sc_digit mask = ~SC_DIGIT_ZERO >> (SC_DIGIT_SIZE - bi);
+ if ( mask )
+ {
+ m_data[wi] &= mask;
+ m_ctrl[wi] &= mask;
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS TEMPLATE : sc_proxy
+//
+// Base class template for bit/logic vector classes.
+// (Barton/Nackmann implementation)
+// ----------------------------------------------------------------------------
+
+// bitwise operators and functions
+
+// bitwise complement
+
+template <class X>
+inline
+const sc_lv_base
+sc_proxy<X>::operator ~ () const
+{
+ sc_lv_base a( back_cast() );
+ return a.b_not();
+}
+
+
+// bitwise and
+
+template <class X, class Y>
+inline
+X&
+operator &= ( sc_proxy<X>& px, const sc_proxy<Y>& py )
+{
+ X& x = px.back_cast();
+ sc_lv_base a( x.length() );
+ a = py.back_cast();
+ return b_and_assign_( x, a );
+}
+
+
+#define DEFN_BITWISE_AND_ASN_OP_T(tp) \
+template <class X> \
+inline \
+X& \
+sc_proxy<X>::operator &= ( tp b ) \
+{ \
+ X& x = back_cast(); \
+ sc_lv_base a( x.length() ); \
+ a = b; \
+ return b_and_assign_( x, a ); \
+}
+
+DEFN_BITWISE_AND_ASN_OP_T(const char*)
+DEFN_BITWISE_AND_ASN_OP_T(const bool*)
+DEFN_BITWISE_AND_ASN_OP_T(const sc_logic*)
+DEFN_BITWISE_AND_ASN_OP_T(const sc_unsigned&)
+DEFN_BITWISE_AND_ASN_OP_T(const sc_signed&)
+DEFN_BITWISE_AND_ASN_OP_T(unsigned long)
+DEFN_BITWISE_AND_ASN_OP_T(long)
+DEFN_BITWISE_AND_ASN_OP_T(uint64)
+DEFN_BITWISE_AND_ASN_OP_T(int64)
+
+#undef DEFN_BITWISE_AND_ASN_OP_T
+
+
+template <class X, class Y>
+inline
+const sc_lv_base
+operator & ( const sc_proxy<X>& px, const sc_proxy<Y>& py )
+{
+ sc_lv_base a( px.back_cast() );
+ return ( a &= py.back_cast() );
+}
+
+
+#define DEFN_BITWISE_AND_OP_T_A(tp) \
+template <class X> \
+inline \
+const sc_lv_base \
+sc_proxy<X>::operator & ( tp b ) const \
+{ \
+ sc_lv_base a( back_cast() ); \
+ return ( a &= b ); \
+}
+
+DEFN_BITWISE_AND_OP_T_A(const char*)
+DEFN_BITWISE_AND_OP_T_A(const bool*)
+DEFN_BITWISE_AND_OP_T_A(const sc_logic*)
+DEFN_BITWISE_AND_OP_T_A(const sc_unsigned&)
+DEFN_BITWISE_AND_OP_T_A(const sc_signed&)
+DEFN_BITWISE_AND_OP_T_A(const sc_uint_base&)
+DEFN_BITWISE_AND_OP_T_A(const sc_int_base&)
+DEFN_BITWISE_AND_OP_T_A(unsigned long)
+DEFN_BITWISE_AND_OP_T_A(long)
+DEFN_BITWISE_AND_OP_T_A(unsigned int)
+DEFN_BITWISE_AND_OP_T_A(int)
+DEFN_BITWISE_AND_OP_T_A(uint64)
+DEFN_BITWISE_AND_OP_T_A(int64)
+
+#undef DEFN_BITWISE_AND_OP_T_A
+
+
+#define DEFN_BITWISE_AND_OP_T_B(tp) \
+template <class X> \
+inline \
+const sc_lv_base \
+operator & ( tp b, const sc_proxy<X>& px ) \
+{ \
+ return ( px & b ); \
+}
+
+DEFN_BITWISE_AND_OP_T_B(const char*)
+DEFN_BITWISE_AND_OP_T_B(const bool*)
+DEFN_BITWISE_AND_OP_T_B(const sc_logic*)
+DEFN_BITWISE_AND_OP_T_B(const sc_unsigned&)
+DEFN_BITWISE_AND_OP_T_B(const sc_signed&)
+DEFN_BITWISE_AND_OP_T_B(const sc_uint_base&)
+DEFN_BITWISE_AND_OP_T_B(const sc_int_base&)
+DEFN_BITWISE_AND_OP_T_B(unsigned long)
+DEFN_BITWISE_AND_OP_T_B(long)
+DEFN_BITWISE_AND_OP_T_B(unsigned int)
+DEFN_BITWISE_AND_OP_T_B(int)
+DEFN_BITWISE_AND_OP_T_B(uint64)
+DEFN_BITWISE_AND_OP_T_B(int64)
+
+#undef DEFN_BITWISE_AND_OP_T_B
+
+
+// bitwise or
+
+template <class X, class Y>
+inline
+X&
+operator |= ( sc_proxy<X>& px, const sc_proxy<Y>& py )
+{
+ X& x = px.back_cast();
+ sc_lv_base a( x.length() );
+ a = py.back_cast();
+ return b_or_assign_( x, a );
+}
+
+
+#define DEFN_BITWISE_OR_ASN_OP_T(tp) \
+template <class X> \
+inline \
+X& \
+sc_proxy<X>::operator |= ( tp b ) \
+{ \
+ X& x = back_cast(); \
+ sc_lv_base a( x.length() ); \
+ a = b; \
+ return b_or_assign_( x, a ); \
+}
+
+DEFN_BITWISE_OR_ASN_OP_T(const char*)
+DEFN_BITWISE_OR_ASN_OP_T(const bool*)
+DEFN_BITWISE_OR_ASN_OP_T(const sc_logic*)
+DEFN_BITWISE_OR_ASN_OP_T(const sc_unsigned&)
+DEFN_BITWISE_OR_ASN_OP_T(const sc_signed&)
+DEFN_BITWISE_OR_ASN_OP_T(unsigned long)
+DEFN_BITWISE_OR_ASN_OP_T(long)
+DEFN_BITWISE_OR_ASN_OP_T(uint64)
+DEFN_BITWISE_OR_ASN_OP_T(int64)
+
+#undef DEFN_BITWISE_OR_ASN_OP_T
+
+
+template <class X, class Y>
+inline
+const sc_lv_base
+operator | ( const sc_proxy<X>& px, const sc_proxy<Y>& py )
+{
+ sc_lv_base a( px.back_cast() );
+ return ( a |= py.back_cast() );
+}
+
+
+#define DEFN_BITWISE_OR_OP_T_A(tp) \
+template <class X> \
+inline \
+const sc_lv_base \
+sc_proxy<X>::operator | ( tp b ) const \
+{ \
+ sc_lv_base a( back_cast() ); \
+ return ( a |= b ); \
+}
+
+DEFN_BITWISE_OR_OP_T_A(const char*)
+DEFN_BITWISE_OR_OP_T_A(const bool*)
+DEFN_BITWISE_OR_OP_T_A(const sc_logic*)
+DEFN_BITWISE_OR_OP_T_A(const sc_unsigned&)
+DEFN_BITWISE_OR_OP_T_A(const sc_signed&)
+DEFN_BITWISE_OR_OP_T_A(const sc_uint_base&)
+DEFN_BITWISE_OR_OP_T_A(const sc_int_base&)
+DEFN_BITWISE_OR_OP_T_A(unsigned long)
+DEFN_BITWISE_OR_OP_T_A(long)
+DEFN_BITWISE_OR_OP_T_A(unsigned int)
+DEFN_BITWISE_OR_OP_T_A(int)
+DEFN_BITWISE_OR_OP_T_A(uint64)
+DEFN_BITWISE_OR_OP_T_A(int64)
+
+#undef DEFN_BITWISE_OR_OP_T_A
+
+
+#define DEFN_BITWISE_OR_OP_T_B(tp) \
+template <class X> \
+inline \
+const sc_lv_base \
+operator | ( tp b, const sc_proxy<X>& px ) \
+{ \
+ return ( px | b ); \
+}
+
+DEFN_BITWISE_OR_OP_T_B(const char*)
+DEFN_BITWISE_OR_OP_T_B(const bool*)
+DEFN_BITWISE_OR_OP_T_B(const sc_logic*)
+DEFN_BITWISE_OR_OP_T_B(const sc_unsigned&)
+DEFN_BITWISE_OR_OP_T_B(const sc_signed&)
+DEFN_BITWISE_OR_OP_T_B(const sc_uint_base&)
+DEFN_BITWISE_OR_OP_T_B(const sc_int_base&)
+DEFN_BITWISE_OR_OP_T_B(unsigned long)
+DEFN_BITWISE_OR_OP_T_B(long)
+DEFN_BITWISE_OR_OP_T_B(unsigned int)
+DEFN_BITWISE_OR_OP_T_B(int)
+DEFN_BITWISE_OR_OP_T_B(uint64)
+DEFN_BITWISE_OR_OP_T_B(int64)
+
+#undef DEFN_BITWISE_OR_OP_T_B
+
+
+// bitwise xor
+
+template <class X, class Y>
+inline
+X&
+operator ^= ( sc_proxy<X>& px, const sc_proxy<Y>& py )
+{
+ X& x = px.back_cast();
+ sc_lv_base a( x.length() );
+ a = py.back_cast();
+ return b_xor_assign_( x, a );
+}
+
+
+#define DEFN_BITWISE_XOR_ASN_OP_T(tp) \
+template <class X> \
+inline \
+X& \
+sc_proxy<X>::operator ^= ( tp b ) \
+{ \
+ X& x = back_cast(); \
+ sc_lv_base a( x.length() ); \
+ a = b; \
+ return b_xor_assign_( x, a ); \
+}
+
+DEFN_BITWISE_XOR_ASN_OP_T(const char*)
+DEFN_BITWISE_XOR_ASN_OP_T(const bool*)
+DEFN_BITWISE_XOR_ASN_OP_T(const sc_logic*)
+DEFN_BITWISE_XOR_ASN_OP_T(const sc_unsigned&)
+DEFN_BITWISE_XOR_ASN_OP_T(const sc_signed&)
+DEFN_BITWISE_XOR_ASN_OP_T(unsigned long)
+DEFN_BITWISE_XOR_ASN_OP_T(long)
+DEFN_BITWISE_XOR_ASN_OP_T(uint64)
+DEFN_BITWISE_XOR_ASN_OP_T(int64)
+
+#undef DEFN_BITWISE_XOR_ASN_OP_T
+
+
+template <class X, class Y>
+inline
+const sc_lv_base
+operator ^ ( const sc_proxy<X>& px, const sc_proxy<Y>& py )
+{
+ sc_lv_base a( px.back_cast() );
+ return ( a ^= py.back_cast() );
+}
+
+
+#define DEFN_BITWISE_XOR_OP_T_A(tp) \
+template <class X> \
+inline \
+const sc_lv_base \
+sc_proxy<X>::operator ^ ( tp b ) const \
+{ \
+ sc_lv_base a( back_cast() ); \
+ return ( a ^= b ); \
+}
+
+DEFN_BITWISE_XOR_OP_T_A(const char*)
+DEFN_BITWISE_XOR_OP_T_A(const bool*)
+DEFN_BITWISE_XOR_OP_T_A(const sc_logic*)
+DEFN_BITWISE_XOR_OP_T_A(const sc_unsigned&)
+DEFN_BITWISE_XOR_OP_T_A(const sc_signed&)
+DEFN_BITWISE_XOR_OP_T_A(const sc_uint_base&)
+DEFN_BITWISE_XOR_OP_T_A(const sc_int_base&)
+DEFN_BITWISE_XOR_OP_T_A(unsigned long)
+DEFN_BITWISE_XOR_OP_T_A(long)
+DEFN_BITWISE_XOR_OP_T_A(unsigned int)
+DEFN_BITWISE_XOR_OP_T_A(int)
+DEFN_BITWISE_XOR_OP_T_A(uint64)
+DEFN_BITWISE_XOR_OP_T_A(int64)
+
+#undef DEFN_BITWISE_XOR_OP_T_A
+
+
+#define DEFN_BITWISE_XOR_OP_T_B(tp) \
+template <class X> \
+inline \
+const sc_lv_base \
+operator ^ ( tp b, const sc_proxy<X>& px ) \
+{ \
+ return ( px ^ b ); \
+}
+
+DEFN_BITWISE_XOR_OP_T_B(const char*)
+DEFN_BITWISE_XOR_OP_T_B(const bool*)
+DEFN_BITWISE_XOR_OP_T_B(const sc_logic*)
+DEFN_BITWISE_XOR_OP_T_B(const sc_unsigned&)
+DEFN_BITWISE_XOR_OP_T_B(const sc_signed&)
+DEFN_BITWISE_XOR_OP_T_B(const sc_uint_base&)
+DEFN_BITWISE_XOR_OP_T_B(const sc_int_base&)
+DEFN_BITWISE_XOR_OP_T_B(unsigned long)
+DEFN_BITWISE_XOR_OP_T_B(long)
+DEFN_BITWISE_XOR_OP_T_B(unsigned int)
+DEFN_BITWISE_XOR_OP_T_B(int)
+DEFN_BITWISE_XOR_OP_T_B(uint64)
+DEFN_BITWISE_XOR_OP_T_B(int64)
+
+#undef DEFN_BITWISE_XOR_OP_T_B
+
+
+// bitwise left shift
+
+template <class X>
+inline
+const sc_lv_base
+sc_proxy<X>::operator << ( int n ) const
+{
+ sc_lv_base a( back_cast().length()+n );
+ a = back_cast();
+ return ( a <<= n );
+}
+
+
+// bitwise right shift
+
+template <class X>
+inline
+const sc_lv_base
+sc_proxy<X>::operator >> ( int n ) const
+{
+ sc_lv_base a( back_cast() );
+ return ( a >>= n );
+}
+
+
+// bitwise left rotate
+
+template <class X>
+inline
+X&
+sc_proxy<X>::lrotate( int n )
+{
+ X& x = back_cast();
+ if( n < 0 ) {
+ char msg[BUFSIZ];
+ std::sprintf( msg,
+ "left rotate operation is only allowed with positive "
+ "rotate values, rotate value = %d", n );
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
+ }
+ int len = x.length();
+ n %= len;
+ // x = (x << n) | (x >> (len - n));
+ sc_lv_base a( x << n );
+ sc_lv_base b( x >> (len - n) );
+ int sz = x.size();
+ for( int i = 0; i < sz; ++ i ) {
+ x.set_word( i, a.get_word( i ) | b.get_word( i ) );
+ x.set_cword( i, a.get_cword( i ) | b.get_cword( i ) );
+ }
+ x.clean_tail();
+ return x;
+}
+
+template <class X>
+inline
+const sc_lv_base
+lrotate( const sc_proxy<X>& x, int n )
+{
+ sc_lv_base a( x.back_cast() );
+ return a.lrotate( n );
+}
+
+
+// bitwise right rotate
+
+template <class X>
+inline
+X&
+sc_proxy<X>::rrotate( int n )
+{
+ X& x = back_cast();
+ if( n < 0 ) {
+ char msg[BUFSIZ];
+ std::sprintf( msg,
+ "right rotate operation is only allowed with positive "
+ "rotate values, rotate value = %d", n );
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
+ }
+ int len = x.length();
+ n %= len;
+ // x = (x >> n) | (x << (len - n));
+ sc_lv_base a( x >> n );
+ sc_lv_base b( x << (len - n) );
+ int sz = x.size();
+ for( int i = 0; i < sz; ++ i ) {
+ x.set_word( i, a.get_word( i ) | b.get_word( i ) );
+ x.set_cword( i, a.get_cword( i ) | b.get_cword( i ) );
+ }
+ x.clean_tail();
+ return x;
+}
+
+template <class X>
+inline
+const sc_lv_base
+rrotate( const sc_proxy<X>& x, int n )
+{
+ sc_lv_base a( x.back_cast() );
+ return a.rrotate( n );
+}
+
+
+// bitwise reverse
+
+template <class X>
+inline
+const sc_lv_base
+reverse( const sc_proxy<X>& x )
+{
+ sc_lv_base a( x.back_cast() );
+ return a.reverse();
+}
+
+
+// relational operators
+
+template <class X, class Y>
+inline
+bool
+operator == ( const sc_proxy<X>& px, const sc_proxy<Y>& py )
+{
+ const X& x = px.back_cast();
+ const Y& y = py.back_cast();
+ int x_len = x.length();
+ int y_len = y.length();
+ if( x_len != y_len ) {
+ return false;
+ }
+ int sz = x.size();
+ for( int i = 0; i < sz; ++ i ) {
+ if( x.get_word( i ) != y.get_word( i ) ||
+ x.get_cword( i ) != y.get_cword( i ) ) {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+#define DEFN_REL_OP_T(tp) \
+template <class X> \
+inline \
+bool \
+sc_proxy<X>::operator == ( tp b ) const \
+{ \
+ const X& x = back_cast(); \
+ sc_lv_base y( x.length() ); \
+ y = b; \
+ return ( x == y ); \
+}
+
+DEFN_REL_OP_T(const char*)
+DEFN_REL_OP_T(const bool*)
+DEFN_REL_OP_T(const sc_logic*)
+DEFN_REL_OP_T(const sc_unsigned&)
+DEFN_REL_OP_T(const sc_signed&)
+DEFN_REL_OP_T(const sc_uint_base&)
+DEFN_REL_OP_T(const sc_int_base&)
+DEFN_REL_OP_T(unsigned long)
+DEFN_REL_OP_T(long)
+DEFN_REL_OP_T(unsigned int)
+DEFN_REL_OP_T(int)
+DEFN_REL_OP_T(uint64)
+DEFN_REL_OP_T(int64)
+
+#undef DEFN_REL_OP_T
+
+
+// ----------------------------------------------------------------------------
+// CLASS TEMPLATE : sc_bitref_r<X>
+//
+// Proxy class for sc_proxy bit selection (r-value only).
+// ----------------------------------------------------------------------------
+
+// r-value concatenation operators and functions
+
+template <class T>
+inline
+sc_concref_r<sc_bitref_r<T>,sc_lv_base>
+operator , ( sc_bitref_r<T> a, const char* b )
+{
+ return sc_concref_r<sc_bitref_r<T>,sc_lv_base>(
+ *a.clone(), *new sc_lv_base( b ), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_bitref_r<T> >
+operator , ( const char* a, sc_bitref_r<T> b )
+{
+ return sc_concref_r<sc_lv_base,sc_bitref_r<T> >(
+ *new sc_lv_base( a ), *b.clone(), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_bitref_r<T>,sc_lv_base>
+operator , ( sc_bitref_r<T> a, const sc_logic& b )
+{
+ return sc_concref_r<sc_bitref_r<T>,sc_lv_base>(
+ *a.clone(), *new sc_lv_base( b, 1 ), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_bitref_r<T> >
+operator , ( const sc_logic& a, sc_bitref_r<T> b )
+{
+ return sc_concref_r<sc_lv_base,sc_bitref_r<T> >(
+ *new sc_lv_base( a, 1 ), *b.clone(), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_bitref_r<T>,sc_bv_base>
+operator , ( sc_bitref_r<T> a, bool b )
+{
+ return sc_concref_r<sc_bitref_r<T>,sc_bv_base>
+ ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_bv_base,sc_bitref_r<T> >
+operator , ( bool a, sc_bitref_r<T> b )
+{
+ return sc_concref_r<sc_bv_base,sc_bitref_r<T> >
+ ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
+}
+
+
+template <class T>
+inline
+sc_concref_r<sc_bitref_r<T>,sc_lv_base>
+concat( sc_bitref_r<T> a, const char* b )
+{
+ return sc_concref_r<sc_bitref_r<T>,sc_lv_base>(
+ *a.clone(), *new sc_lv_base( b ), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_bitref_r<T> >
+concat( const char* a, sc_bitref_r<T> b )
+{
+ return sc_concref_r<sc_lv_base,sc_bitref_r<T> >(
+ *new sc_lv_base( a ), *b.clone(), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_bitref_r<T>,sc_lv_base>
+concat( sc_bitref_r<T> a, const sc_logic& b )
+{
+ return sc_concref_r<sc_bitref_r<T>,sc_lv_base>(
+ *a.clone(), *new sc_lv_base( b, 1 ), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_bitref_r<T> >
+concat( const sc_logic& a, sc_bitref_r<T> b )
+{
+ return sc_concref_r<sc_lv_base,sc_bitref_r<T> >(
+ *new sc_lv_base( a, 1 ), *b.clone(), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_bitref_r<T>,sc_bv_base>
+concat( sc_bitref_r<T> a, bool b )
+{
+ return sc_concref_r<sc_bitref_r<T>,sc_bv_base>
+ ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_bv_base,sc_bitref_r<T> >
+concat( bool a, sc_bitref_r<T> b )
+{
+ return sc_concref_r<sc_bv_base,sc_bitref_r<T> >
+ ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
+}
+
+
+#ifdef SC_DT_MIXED_COMMA_OPERATORS
+
+template <class T>
+inline
+sc_concref_r<sc_bitref_r<T>,sc_lv_base>
+operator , ( sc_bitref<T> a, const char* b )
+{
+ return sc_concref_r<sc_bitref_r<T>,sc_lv_base>(
+ *a.clone(), *new sc_lv_base( b ), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_bitref_r<T> >
+operator , ( const char* a, sc_bitref<T> b )
+{
+ return sc_concref_r<sc_lv_base,sc_bitref_r<T> >(
+ *new sc_lv_base( a ), *b.clone(), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_bitref_r<T>,sc_lv_base>
+operator , ( sc_bitref<T> a, const sc_logic& b )
+{
+ return sc_concref_r<sc_bitref_r<T>,sc_lv_base>(
+ *a.clone(), *new sc_lv_base( b, 1 ), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_bitref_r<T> >
+operator , ( const sc_logic& a, sc_bitref<T> b )
+{
+ return sc_concref_r<sc_lv_base,sc_bitref_r<T> >(
+ *new sc_lv_base( a, 1 ), *b.clone(), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_bitref_r<T>,sc_bv_base>
+operator , ( sc_bitref<T> a, bool b )
+{
+ return sc_concref_r<sc_bitref_r<T>,sc_bv_base>
+ ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_bv_base,sc_bitref_r<T> >
+operator , ( bool a, sc_bitref<T> b )
+{
+ return sc_concref_r<sc_bv_base,sc_bitref_r<T> >
+ ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
+}
+
+
+template <class T>
+inline
+sc_concref_r<sc_bitref_r<T>,sc_lv_base>
+concat( sc_bitref<T> a, const char* b )
+{
+ return sc_concref_r<sc_bitref_r<T>,sc_lv_base>(
+ *a.clone(), *new sc_lv_base( b ), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_bitref_r<T> >
+concat( const char* a, sc_bitref<T> b )
+{
+ return sc_concref_r<sc_lv_base,sc_bitref_r<T> >(
+ *new sc_lv_base( a ), *b.clone(), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_bitref_r<T>,sc_lv_base>
+concat( sc_bitref<T> a, const sc_logic& b )
+{
+ return sc_concref_r<sc_bitref_r<T>,sc_lv_base>(
+ *a.clone(), *new sc_lv_base( b, 1 ), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_bitref_r<T> >
+concat( const sc_logic& a, sc_bitref<T> b )
+{
+ return sc_concref_r<sc_lv_base,sc_bitref_r<T> >(
+ *new sc_lv_base( a, 1 ), *b.clone(), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_bitref_r<T>,sc_bv_base>
+concat( sc_bitref<T> a, bool b )
+{
+ return sc_concref_r<sc_bitref_r<T>,sc_bv_base>
+ ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_bv_base,sc_bitref_r<T> >
+concat( bool a, sc_bitref<T> b )
+{
+ return sc_concref_r<sc_bv_base,sc_bitref_r<T> >
+ ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
+}
+
+#endif
+
+
+// ----------------------------------------------------------------------------
+// CLASS TEMPLATE : sc_subref_r<X>
+//
+// Proxy class for sc_proxy part selection (r-value only).
+// ----------------------------------------------------------------------------
+
+// r-value concatenation operators and functions
+
+template <class T>
+inline
+sc_concref_r<sc_subref_r<T>,sc_lv_base>
+operator , ( sc_subref_r<T> a, const char* b )
+{
+ return sc_concref_r<sc_subref_r<T>,sc_lv_base>(
+ *a.clone(), *new sc_lv_base( b ), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_subref_r<T> >
+operator , ( const char* a, sc_subref_r<T> b )
+{
+ return sc_concref_r<sc_lv_base,sc_subref_r<T> >(
+ *new sc_lv_base( a ), *b.clone(), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_subref_r<T>,sc_lv_base>
+operator , ( sc_subref_r<T> a, const sc_logic& b )
+{
+ return sc_concref_r<sc_subref_r<T>,sc_lv_base>(
+ *a.clone(), *new sc_lv_base( b, 1 ), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_subref_r<T> >
+operator , ( const sc_logic& a, sc_subref_r<T> b )
+{
+ return sc_concref_r<sc_lv_base,sc_subref_r<T> >(
+ *new sc_lv_base( a, 1 ), *b.clone(), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_subref_r<T>,sc_bv_base>
+operator , ( sc_subref_r<T> a, bool b )
+{
+ return sc_concref_r<sc_subref_r<T>,sc_bv_base>
+ ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_bv_base,sc_subref_r<T> >
+operator , ( bool a, sc_subref_r<T> b )
+{
+ return sc_concref_r<sc_bv_base,sc_subref_r<T> >
+ ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
+}
+
+
+template <class T>
+inline
+sc_concref_r<sc_subref_r<T>,sc_lv_base>
+concat( sc_subref_r<T> a, const char* b )
+{
+ return sc_concref_r<sc_subref_r<T>,sc_lv_base>(
+ *a.clone(), *new sc_lv_base( b ), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_subref_r<T> >
+concat( const char* a, sc_subref_r<T> b )
+{
+ return sc_concref_r<sc_lv_base,sc_subref_r<T> >(
+ *new sc_lv_base( a ), *b.clone(), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_subref_r<T>,sc_lv_base>
+concat( sc_subref_r<T> a, const sc_logic& b )
+{
+ return sc_concref_r<sc_subref_r<T>,sc_lv_base>(
+ *a.clone(), *new sc_lv_base( b, 1 ), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_subref_r<T> >
+concat( const sc_logic& a, sc_subref_r<T> b )
+{
+ return sc_concref_r<sc_lv_base,sc_subref_r<T> >(
+ *new sc_lv_base( a, 1 ), *b.clone(), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_subref_r<T>,sc_bv_base>
+concat( sc_subref_r<T> a, bool b )
+{
+ return sc_concref_r<sc_subref_r<T>,sc_bv_base>
+ ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_bv_base,sc_subref_r<T> >
+concat( bool a, sc_subref_r<T> b )
+{
+ return sc_concref_r<sc_bv_base,sc_subref_r<T> >
+ ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
+}
+
+
+#ifdef SC_DT_MIXED_COMMA_OPERATORS
+
+template <class T>
+inline
+sc_concref_r<sc_subref_r<T>,sc_lv_base>
+operator , ( sc_subref<T> a, const char* b )
+{
+ return sc_concref_r<sc_subref_r<T>,sc_lv_base>(
+ *a.clone(), *new sc_lv_base( b ), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_subref_r<T> >
+operator , ( const char* a, sc_subref<T> b )
+{
+ return sc_concref_r<sc_lv_base,sc_subref_r<T> >(
+ *new sc_lv_base( a ), *b.clone(), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_subref_r<T>,sc_lv_base>
+operator , ( sc_subref<T> a, const sc_logic& b )
+{
+ return sc_concref_r<sc_subref_r<T>,sc_lv_base>(
+ *a.clone(), *new sc_lv_base( b, 1 ), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_subref_r<T> >
+operator , ( const sc_logic& a, sc_subref<T> b )
+{
+ return sc_concref_r<sc_lv_base,sc_subref_r<T> >(
+ *new sc_lv_base( a, 1 ), *b.clone(), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_subref_r<T>,sc_bv_base>
+operator , ( sc_subref<T> a, bool b )
+{
+ return sc_concref_r<sc_subref_r<T>,sc_bv_base>
+ ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_bv_base,sc_subref_r<T> >
+operator , ( bool a, sc_subref<T> b )
+{
+ return sc_concref_r<sc_bv_base,sc_subref_r<T> >
+ ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
+}
+
+
+template <class T>
+inline
+sc_concref_r<sc_subref_r<T>,sc_lv_base>
+concat( sc_subref<T> a, const char* b )
+{
+ return sc_concref_r<sc_subref_r<T>,sc_lv_base>(
+ *a.clone(), *new sc_lv_base( b ), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_subref_r<T> >
+concat( const char* a, sc_subref<T> b )
+{
+ return sc_concref_r<sc_lv_base,sc_subref_r<T> >(
+ *new sc_lv_base( a ), *b.clone(), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_subref_r<T>,sc_lv_base>
+concat( sc_subref<T> a, const sc_logic& b )
+{
+ return sc_concref_r<sc_subref_r<T>,sc_lv_base>(
+ *a.clone(), *new sc_lv_base( b, 1 ), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,sc_subref_r<T> >
+concat( const sc_logic& a, sc_subref<T> b )
+{
+ return sc_concref_r<sc_lv_base,sc_subref_r<T> >(
+ *new sc_lv_base( a, 1 ), *b.clone(), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_subref_r<T>,sc_bv_base>
+concat( sc_subref<T> a, bool b )
+{
+ return sc_concref_r<sc_subref_r<T>,sc_bv_base>
+ ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_bv_base,sc_subref_r<T> >
+concat( bool a, sc_subref<T> b )
+{
+ return sc_concref_r<sc_bv_base,sc_subref_r<T> >
+ ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
+}
+
+#endif
+
+
+// ----------------------------------------------------------------------------
+// CLASS TEMPLATE : sc_subref<X>
+//
+// Proxy class for sc_proxy part selection (r-value and l-value).
+// ----------------------------------------------------------------------------
+
+template <class X>
+inline
+sc_subref<X>&
+sc_subref<X>::operator = ( const sc_subref_r<X>& b )
+{
+ sc_lv_base t( b ); // (partial) self assignment protection
+ int len = sc_min( this->length(), t.length() );
+ if( ! this->reversed() ) {
+ for( int i = len - 1; i >= 0; -- i ) {
+ this->m_obj.set_bit( this->m_lo + i, t[i].value() );
+ }
+ } else {
+ for( int i = len - 1; i >= 0; -- i ) {
+ this->m_obj.set_bit( this->m_lo - i, t[i].value() );
+ }
+ }
+ return *this;
+}
+
+template <class X>
+inline
+sc_subref<X>&
+sc_subref<X>::operator = ( const sc_subref<X>& b )
+{
+ sc_lv_base t( b ); // (partial) self assignment protection
+ int len = sc_min( this->length(), t.length() );
+ if( ! this->reversed() ) {
+ for( int i = len - 1; i >= 0; -- i ) {
+ this->m_obj.set_bit( this->m_lo + i, t[i].value() );
+ }
+ } else {
+ for( int i = len - 1; i >= 0; -- i ) {
+ this->m_obj.set_bit( this->m_lo - i, t[i].value() );
+ }
+ }
+ return *this;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS TEMPLATE : sc_concref_r<X,Y>
+//
+// Proxy class for sc_proxy concatenation (r-value only).
+// ----------------------------------------------------------------------------
+
+// r-value concatenation operators and functions
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
+operator , ( sc_concref_r<T1,T2> a, const char* b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>(
+ *a.clone(), *new sc_lv_base( b ), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
+operator , ( const char* a, sc_concref_r<T1,T2> b )
+{
+ return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >(
+ *new sc_lv_base( a ), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
+operator , ( sc_concref_r<T1,T2> a, const sc_logic& b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>(
+ *a.clone(), *new sc_lv_base( b, 1 ), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
+operator , ( const sc_logic& a, sc_concref_r<T1,T2> b )
+{
+ return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >(
+ *new sc_lv_base( a, 1 ), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base>
+operator , ( sc_concref_r<T1,T2> a, bool b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base>
+ ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> >
+operator , ( bool a, sc_concref_r<T1,T2> b )
+{
+ return sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> >
+ ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
+}
+
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
+concat( sc_concref_r<T1,T2> a, const char* b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
+ ( *a.clone(), *new sc_lv_base( b ), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
+concat( const char* a, sc_concref_r<T1,T2> b )
+{
+ return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
+ ( *new sc_lv_base( a ), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
+concat( sc_concref_r<T1,T2> a, const sc_logic& b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
+ ( *a.clone(), *new sc_lv_base( b, 1 ), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
+concat( const sc_logic& a, sc_concref_r<T1,T2> b )
+{
+ return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
+ ( *new sc_lv_base( a, 1 ), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base>
+concat( sc_concref_r<T1,T2> a, bool b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base>
+ ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> >
+concat( bool a, sc_concref_r<T1,T2> b )
+{
+ return sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> >
+ ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
+}
+
+
+#ifdef SC_DT_MIXED_COMMA_OPERATORS
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
+operator , ( sc_concref<T1,T2> a, const char* b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
+ ( *a.clone(), *new sc_lv_base( b ), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
+operator , ( const char* a, sc_concref<T1,T2> b )
+{
+ return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
+ ( *new sc_lv_base( a ), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
+operator , ( sc_concref<T1,T2> a, const sc_logic& b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
+ ( *a.clone(), *new sc_lv_base( b, 1 ), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
+operator , ( const sc_logic& a, sc_concref<T1,T2> b )
+{
+ return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
+ ( *new sc_lv_base( a, 1 ), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base>
+operator , ( sc_concref<T1,T2> a, bool b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base>
+ ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> >
+operator , ( bool a, sc_concref<T1,T2> b )
+{
+ return sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> >
+ ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
+}
+
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
+concat( sc_concref<T1,T2> a, const char* b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
+ ( *a.clone(), *new sc_lv_base( b ), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
+concat( const char* a, sc_concref<T1,T2> b )
+{
+ return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
+ ( *new sc_lv_base( a ), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
+concat( sc_concref<T1,T2> a, const sc_logic& b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
+ ( *a.clone(), *new sc_lv_base( b, 1 ), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
+concat( const sc_logic& a, sc_concref<T1,T2> b )
+{
+ return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
+ ( *new sc_lv_base( a, 1 ), *b.clone(), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base>
+concat( sc_concref<T1,T2> a, bool b )
+{
+ return sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base>
+ ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
+}
+
+template <class T1, class T2>
+inline
+sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> >
+concat( bool a, sc_concref<T1,T2> b )
+{
+ return sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> >
+ ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
+}
+
+#endif
+
+
+// ----------------------------------------------------------------------------
+// CLASS TEMPLATE : sc_proxy<T>
+//
+// Base class template for bit/logic vector classes.
+// (Barton/Nackmann implementation)
+// ----------------------------------------------------------------------------
+
+// r-value concatenation operators and functions
+
+template <class T>
+inline
+sc_concref_r<T,sc_lv_base>
+operator , ( const sc_proxy<T>& a, const char* b )
+{
+ return sc_concref_r<T,sc_lv_base>
+ ( a.back_cast(), *new sc_lv_base( b ), 2 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,T>
+operator , ( const char* a, const sc_proxy<T>& b )
+{
+ return sc_concref_r<sc_lv_base,T>
+ ( *new sc_lv_base( a ), b.back_cast(), 1 );
+}
+
+template <class T>
+inline
+sc_concref_r<T,sc_lv_base>
+operator , ( const sc_proxy<T>& a, const sc_logic& b )
+{
+ return sc_concref_r<T,sc_lv_base>
+ ( a.back_cast(), *new sc_lv_base( b, 1 ), 2 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,T>
+operator , ( const sc_logic& a, const sc_proxy<T>& b )
+{
+ return sc_concref_r<sc_lv_base,T>
+ ( *new sc_lv_base( a, 1 ), b.back_cast(), 1 );
+}
+
+template <class T>
+inline
+sc_concref_r<T,sc_bv_base>
+operator , ( const sc_proxy<T>& a, bool b )
+{
+ return sc_concref_r<T,sc_bv_base>
+ ( a.back_cast(), *new sc_bv_base( b, 1 ), 2 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_bv_base,T>
+operator , ( bool a, const sc_proxy<T>& b )
+{
+ return sc_concref_r<sc_bv_base,T>
+ ( *new sc_bv_base( a, 1 ), b.back_cast(), 1 );
+}
+
+
+template <class T>
+inline
+sc_concref_r<T,sc_lv_base>
+concat( const sc_proxy<T>& a, const char* b )
+{
+ return sc_concref_r<T,sc_lv_base>
+ ( a.back_cast(), *new sc_lv_base( b ), 2 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,T>
+concat( const char* a, const sc_proxy<T>& b )
+{
+ return sc_concref_r<sc_lv_base,T>
+ ( *new sc_lv_base( a ), b.back_cast(), 1 );
+}
+
+template <class T>
+inline
+sc_concref_r<T,sc_lv_base>
+concat( const sc_proxy<T>& a, const sc_logic& b )
+{
+ return sc_concref_r<T,sc_lv_base>
+ ( a.back_cast(), *new sc_lv_base( b, 1 ), 2 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,T>
+concat( const sc_logic& a, const sc_proxy<T>& b )
+{
+ return sc_concref_r<sc_lv_base,T>
+ ( *new sc_lv_base( a, 1 ), b.back_cast(), 1 );
+}
+
+template <class T>
+inline
+sc_concref_r<T,sc_bv_base>
+concat( const sc_proxy<T>& a, bool b )
+{
+ return sc_concref_r<T,sc_bv_base>
+ ( a.back_cast(), *new sc_bv_base( b, 1 ), 2 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_bv_base,T>
+concat( bool a, const sc_proxy<T>& b )
+{
+ return sc_concref_r<sc_bv_base,T>
+ ( *new sc_bv_base( a, 1 ), b.back_cast(), 1 );
+}
+
+
+#ifdef SC_DT_MIXED_COMMA_OPERATORS
+
+template <class T>
+inline
+sc_concref_r<T,sc_lv_base>
+operator , ( sc_proxy<T>& a, const char* b )
+{
+ return sc_concref_r<T,sc_lv_base>
+ ( a.back_cast(), *new sc_lv_base( b ), 2 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,T>
+operator , ( const char* a, sc_proxy<T>& b )
+{
+ return sc_concref_r<sc_lv_base,T>
+ ( *new sc_lv_base( a ), b.back_cast(), 1 );
+}
+
+template <class T>
+inline
+sc_concref_r<T,sc_lv_base>
+operator , ( sc_proxy<T>& a, const sc_logic& b )
+{
+ return sc_concref_r<T,sc_lv_base>
+ ( a.back_cast(), *new sc_lv_base( b, 1 ), 2 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,T>
+operator , ( const sc_logic& a, sc_proxy<T>& b )
+{
+ return sc_concref_r<sc_lv_base,T>
+ ( *new sc_lv_base( a, 1 ), b.back_cast(), 1 );
+}
+
+template <class T>
+inline
+sc_concref_r<T,sc_bv_base>
+operator , ( sc_proxy<T>& a, bool b )
+{
+ return sc_concref_r<T,sc_bv_base>
+ ( a.back_cast(), *new sc_bv_base( b, 1 ), 2 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_bv_base,T>
+operator , ( bool a, sc_proxy<T>& b )
+{
+ return sc_concref_r<sc_bv_base,T>
+ ( *new sc_bv_base( a, 1 ), b.back_cast(), 1 );
+}
+
+
+template <class T>
+inline
+sc_concref_r<T,sc_lv_base>
+concat( sc_proxy<T>& a, const char* b )
+{
+ return sc_concref_r<T,sc_lv_base>
+ ( a.back_cast(), *new sc_lv_base( b ), 2 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,T>
+concat( const char* a, sc_proxy<T>& b )
+{
+ return sc_concref_r<sc_lv_base,T>
+ ( *new sc_lv_base( a ), b.back_cast(), 1 );
+}
+
+template <class T>
+inline
+sc_concref_r<T,sc_lv_base>
+concat( sc_proxy<T>& a, const sc_logic& b )
+{
+ return sc_concref_r<T,sc_lv_base>
+ ( a.back_cast(), *new sc_lv_base( b, 1 ), 2 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_lv_base,T>
+concat( const sc_logic& a, sc_proxy<T>& b )
+{
+ return sc_concref_r<sc_lv_base,T>
+ ( *new sc_lv_base( a, 1 ), b.back_cast(), 1 );
+}
+
+template <class T>
+inline
+sc_concref_r<T,sc_bv_base>
+concat( sc_proxy<T>& a, bool b )
+{
+ return sc_concref_r<T,sc_bv_base>
+ ( a.back_cast(), *new sc_bv_base( b, 1 ), 2 );
+}
+
+template <class T>
+inline
+sc_concref_r<sc_bv_base,T>
+concat( bool a, sc_proxy<T>& b )
+{
+ return sc_concref_r<sc_bv_base,T>
+ ( *new sc_bv_base( a, 1 ), b.back_cast(), 1 );
+}
+
+#endif
+
+} // namespace sc_dt
+
+
+#endif
diff --git a/ext/systemc/src/sysc/datatypes/bit/sc_proxy.h b/ext/systemc/src/sysc/datatypes/bit/sc_proxy.h
new file mode 100644
index 000000000..7c67b447d
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/bit/sc_proxy.h
@@ -0,0 +1,1609 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_proxy.h -- Proxy base class for vector data types.
+
+ This class is created for several purposes:
+ 1) hiding operators from the global namespace that would be
+ otherwise found by Koenig lookup
+ 2) avoiding repeating the same operations in every class
+ including proxies that could also be achieved by common
+ base class, but this method allows
+ 3) improve performance by using non-virtual functions
+
+ Original Author: Gene Bushuyev, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_proxy.h,v $
+// Revision 1.3 2010/12/07 20:09:07 acg
+// Andy Goodrich: Fix for returning enough data
+//
+// Revision 1.2 2009/02/28 00:26:14 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.1.1.1 2006/12/15 20:31:36 acg
+// SystemC 2.2
+//
+// Revision 1.3 2006/01/13 18:53:53 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#ifndef SC_PROXY_H
+#define SC_PROXY_H
+
+
+#include "sysc/kernel/sc_cmnhdr.h"
+#include "sysc/utils/sc_iostream.h"
+#include "sysc/datatypes/int/sc_signed.h"
+#include "sysc/datatypes/int/sc_unsigned.h"
+#include "sysc/datatypes/int/sc_int_base.h"
+#include "sysc/datatypes/int/sc_uint_base.h"
+#include "sysc/datatypes/bit/sc_bit.h"
+#include "sysc/datatypes/bit/sc_bit_ids.h"
+#include "sysc/datatypes/bit/sc_logic.h"
+#include "sysc/kernel/sc_macros.h"
+
+
+namespace sc_dt
+{
+
+// classes defined in this module
+template <class X> class sc_proxy;
+
+// forward class declarations
+class sc_bv_base;
+class sc_lv_base;
+template <class X> class sc_bitref_r;
+template <class X> class sc_bitref;
+template <class X> class sc_subref_r;
+template <class X> class sc_subref;
+template <class X, class Y> class sc_concref_r;
+template <class X, class Y> class sc_concref;
+
+
+const int SC_DIGIT_SIZE = BITS_PER_BYTE * sizeof( sc_digit );
+
+const sc_digit SC_DIGIT_ZERO = (sc_digit)0;
+const sc_digit SC_DIGIT_ONE = (sc_digit)1;
+const sc_digit SC_DIGIT_TWO = (sc_digit)2;
+
+
+// assignment functions; forward declarations
+
+template <class X, class Y>
+inline
+void
+assign_p_( sc_proxy<X>& px, const sc_proxy<Y>& py );
+
+// Vector types that are not derived from sc_proxy must have a length()
+// function and an operator [].
+
+template <class X, class T>
+inline
+void
+assign_v_( sc_proxy<X>& px, const T& a );
+
+
+// other functions; forward declarations
+
+const std::string convert_to_bin( const char* s );
+const std::string convert_to_fmt( const std::string& s, sc_numrep numrep, bool );
+
+// ----------------------------------------------------------------------------
+// CLASS TEMPLATE : sc_proxy_traits
+//
+// Template traits helper to select the correct bit/value/vector_types for
+// sc_proxy-based vector classes.
+//
+// All types derived from/based on a bit-vector contain typedef to a plain bool,
+// all others point to the sc_logic_value_t/sc_logic/sc_lv_base types.
+// ----------------------------------------------------------------------------
+
+template<typename X> struct sc_proxy_traits;
+
+template<> struct sc_proxy_traits<sc_bv_base>
+{
+ typedef sc_proxy_traits<sc_bv_base> traits_type;
+ typedef bool value_type;
+ typedef bool bit_type;
+ typedef sc_bv_base vector_type;
+ typedef traits_type type;
+};
+
+template<> struct sc_proxy_traits<sc_lv_base>
+{
+ typedef sc_proxy_traits<sc_lv_base> traits_type;
+ typedef sc_logic_value_t value_type;
+ typedef sc_logic bit_type;
+ typedef sc_lv_base vector_type;
+ typedef traits_type type;
+};
+
+
+template<typename X> struct sc_proxy_traits<sc_bitref_r<X> >
+ : sc_proxy_traits<X> {};
+
+template<typename X> struct sc_proxy_traits<sc_bitref<X> >
+ : sc_proxy_traits<X> {};
+
+
+template<typename X> struct sc_proxy_traits<sc_subref_r<X> >
+ : sc_proxy_traits<X> {};
+
+template<typename X> struct sc_proxy_traits<sc_subref<X> >
+ : sc_proxy_traits<X> {};
+
+
+template<typename X> struct sc_proxy_traits<sc_proxy<X> >
+ : sc_proxy_traits<X> {};
+
+
+template< typename X, typename Y > struct sc_mixed_proxy_traits_helper
+ : sc_proxy_traits<sc_lv_base> {}; // logic vector by default
+
+template<typename X> struct sc_mixed_proxy_traits_helper<X,X>
+ : X {};
+
+
+template<typename X, typename Y> struct sc_proxy_traits< sc_concref_r<X,Y> >
+ : sc_mixed_proxy_traits_helper< typename X::traits_type::type
+ , typename Y::traits_type::type >
+{};
+
+template<typename X, typename Y> struct sc_proxy_traits<sc_concref<X,Y> >
+ : sc_mixed_proxy_traits_helper< typename X::traits_type::type
+ , typename Y::traits_type::type >
+{};
+
+
+// ----------------------------------------------------------------------------
+// CLASS TEMPLATE : sc_proxy
+//
+// Base class template for bit/logic vector classes.
+// (Barton/Nackmann implementation)
+// ----------------------------------------------------------------------------
+
+template <class X>
+class sc_proxy // #### : public sc_value_base
+{
+public:
+ typedef typename sc_proxy_traits<X>::type traits_type;
+ typedef typename traits_type::bit_type bit_type;
+
+ // virtual destructor
+
+ virtual ~sc_proxy() {}
+
+
+ // casts
+
+ X& back_cast()
+ { return SCAST<X&>( *this ); }
+
+ const X& back_cast() const
+ { return SCAST<const X&>( *this ); }
+
+
+ // assignment operators
+
+ template <class Y>
+ X& assign_( const sc_proxy<Y>& a )
+ { assign_p_( *this, a ); return back_cast(); }
+
+ X& assign_( const char* a );
+ X& assign_( const bool* a );
+ X& assign_( const sc_logic* a );
+
+ X& assign_( const sc_unsigned& a )
+ { assign_v_( *this, a ); return back_cast(); }
+
+ X& assign_( const sc_signed& a )
+ { assign_v_( *this, a ); return back_cast(); }
+
+ X& assign_( const sc_uint_base& a )
+ { return assign_( (uint64) a ); }
+
+ X& assign_( const sc_int_base& a )
+ { return assign_( (int64) a ); }
+
+ X& assign_( unsigned int a );
+ X& assign_( int a );
+
+ X& assign_( unsigned long a );
+
+ X& assign_( long a );
+
+ X& assign_( uint64 a );
+ X& assign_( int64 a );
+
+
+ // bitwise operators and functions
+
+ // bitwise complement
+
+ X& b_not();
+
+ const sc_lv_base operator ~ () const;
+
+
+ // bitwise and
+
+ X& operator &= ( const char* b );
+ X& operator &= ( const bool* b );
+ X& operator &= ( const sc_logic* b );
+ X& operator &= ( const sc_unsigned& b );
+ X& operator &= ( const sc_signed& b );
+
+ X& operator &= ( const sc_uint_base& b )
+ { return operator &= ( (uint64) b ); }
+
+ X& operator &= ( const sc_int_base& b )
+ { return operator &= ( (int64) b ); }
+
+ X& operator &= ( unsigned long b );
+ X& operator &= ( long b );
+
+ X& operator &= ( unsigned int b )
+ { return operator &= ( (unsigned long) b ); }
+
+ X& operator &= ( int b )
+ { return operator &= ( (long) b ); }
+
+ X& operator &= ( uint64 b );
+ X& operator &= ( int64 b );
+
+
+ const sc_lv_base operator & ( const char* b ) const;
+ const sc_lv_base operator & ( const bool* b ) const;
+ const sc_lv_base operator & ( const sc_logic* b ) const;
+ const sc_lv_base operator & ( const sc_unsigned& b ) const;
+ const sc_lv_base operator & ( const sc_signed& b ) const;
+ const sc_lv_base operator & ( const sc_uint_base& b ) const;
+ const sc_lv_base operator & ( const sc_int_base& b ) const;
+ const sc_lv_base operator & ( unsigned long b ) const;
+ const sc_lv_base operator & ( long b ) const;
+ const sc_lv_base operator & ( unsigned int b ) const;
+ const sc_lv_base operator & ( int b ) const;
+ const sc_lv_base operator & ( uint64 b ) const;
+ const sc_lv_base operator & ( int64 b ) const;
+
+
+ // bitwise or
+
+ X& operator |= ( const char* b );
+ X& operator |= ( const bool* b );
+ X& operator |= ( const sc_logic* b );
+ X& operator |= ( const sc_unsigned& b );
+ X& operator |= ( const sc_signed& b );
+
+ X& operator |= ( const sc_uint_base& b )
+ { return operator |= ( (uint64) b ); }
+
+ X& operator |= ( const sc_int_base& b )
+ { return operator |= ( (int64) b ); }
+
+ X& operator |= ( unsigned long b );
+ X& operator |= ( long b );
+
+ X& operator |= ( unsigned int b )
+ { return operator |= ( (unsigned long) b ); }
+
+ X& operator |= ( int b )
+ { return operator |= ( (long) b ); }
+
+ X& operator |= ( uint64 b );
+ X& operator |= ( int64 b );
+
+
+ const sc_lv_base operator | ( const char* b ) const;
+ const sc_lv_base operator | ( const bool* b ) const;
+ const sc_lv_base operator | ( const sc_logic* b ) const;
+ const sc_lv_base operator | ( const sc_unsigned& b ) const;
+ const sc_lv_base operator | ( const sc_signed& b ) const;
+ const sc_lv_base operator | ( const sc_uint_base& b ) const;
+ const sc_lv_base operator | ( const sc_int_base& b ) const;
+ const sc_lv_base operator | ( unsigned long b ) const;
+ const sc_lv_base operator | ( long b ) const;
+ const sc_lv_base operator | ( unsigned int b ) const;
+ const sc_lv_base operator | ( int b ) const;
+ const sc_lv_base operator | ( uint64 b ) const;
+ const sc_lv_base operator | ( int64 b ) const;
+
+
+ // bitwise xor
+
+ X& operator ^= ( const char* b );
+ X& operator ^= ( const bool* b );
+ X& operator ^= ( const sc_logic* b );
+ X& operator ^= ( const sc_unsigned& b );
+ X& operator ^= ( const sc_signed& b );
+
+ X& operator ^= ( const sc_uint_base& b )
+ { return operator ^= ( (uint64) b ); }
+
+ X& operator ^= ( const sc_int_base& b )
+ { return operator ^= ( (int64) b ); }
+
+ X& operator ^= ( unsigned long b );
+ X& operator ^= ( long b );
+
+ X& operator ^= ( unsigned int b )
+ { return operator ^= ( (unsigned long) b ); }
+
+ X& operator ^= ( int b )
+ { return operator ^= ( (long) b ); }
+
+ X& operator ^= ( uint64 b );
+ X& operator ^= ( int64 b );
+
+
+ const sc_lv_base operator ^ ( const char* b ) const;
+ const sc_lv_base operator ^ ( const bool* b ) const;
+ const sc_lv_base operator ^ ( const sc_logic* b ) const;
+ const sc_lv_base operator ^ ( const sc_unsigned& b ) const;
+ const sc_lv_base operator ^ ( const sc_signed& b ) const;
+ const sc_lv_base operator ^ ( const sc_uint_base& b ) const;
+ const sc_lv_base operator ^ ( const sc_int_base& b ) const;
+ const sc_lv_base operator ^ ( unsigned long b ) const;
+ const sc_lv_base operator ^ ( long b ) const;
+ const sc_lv_base operator ^ ( unsigned int b ) const;
+ const sc_lv_base operator ^ ( int b ) const;
+ const sc_lv_base operator ^ ( uint64 b ) const;
+ const sc_lv_base operator ^ ( int64 b ) const;
+
+
+ // bitwise left shift
+
+ X& operator <<= ( int n );
+
+ const sc_lv_base operator << ( int n ) const;
+
+
+ // bitwise right shift
+
+ X& operator >>= ( int n );
+
+ const sc_lv_base operator >> ( int n ) const;
+
+
+ // bitwise left rotate
+
+ X& lrotate( int n );
+
+
+ // bitwise right rotate
+
+ X& rrotate( int n );
+
+
+ // bitwise reverse
+
+ X& reverse();
+
+
+ // bit selection
+
+ sc_bitref<X> operator [] ( int i )
+ { return sc_bitref<X>( back_cast(), i ); }
+
+ sc_bitref_r<X> operator [] ( int i ) const
+ { return sc_bitref_r<X>( back_cast(), i ); }
+
+ sc_bitref<X> bit( int i )
+ { return sc_bitref<X>( back_cast(), i ); }
+
+ sc_bitref_r<X> bit( int i ) const
+ { return sc_bitref_r<X>( back_cast(), i ); }
+
+
+ // part selection
+
+ sc_subref<X> operator () ( int hi, int lo )
+ { return sc_subref<X>( back_cast(), hi, lo ); }
+
+ sc_subref_r<X> operator () ( int hi, int lo ) const
+ { return sc_subref_r<X>( back_cast(), hi, lo ); }
+
+ sc_subref<X> range( int hi, int lo )
+ { return sc_subref<X>( back_cast(), hi, lo ); }
+
+ sc_subref_r<X> range( int hi, int lo ) const
+ { return sc_subref_r<X>( back_cast(), hi, lo ); }
+
+
+ // reduce functions
+
+ sc_logic_value_t and_reduce() const;
+
+ sc_logic_value_t nand_reduce() const
+ { return sc_logic::not_table[and_reduce()]; }
+
+ sc_logic_value_t or_reduce() const;
+
+ sc_logic_value_t nor_reduce() const
+ { return sc_logic::not_table[or_reduce()]; }
+
+ sc_logic_value_t xor_reduce() const;
+
+ sc_logic_value_t xnor_reduce() const
+ { return sc_logic::not_table[xor_reduce()]; }
+
+
+ // relational operators
+
+ bool operator == ( const char* b ) const;
+ bool operator == ( const bool* b ) const;
+ bool operator == ( const sc_logic* b ) const;
+ bool operator == ( const sc_unsigned& b ) const;
+ bool operator == ( const sc_signed& b ) const;
+ bool operator == ( const sc_uint_base& b ) const;
+ bool operator == ( const sc_int_base& b ) const;
+ bool operator == ( unsigned long b ) const;
+ bool operator == ( long b ) const;
+ bool operator == ( unsigned int b ) const;
+ bool operator == ( int b ) const;
+ bool operator == ( uint64 b ) const;
+ bool operator == ( int64 b ) const;
+
+
+ // explicit conversions to character string
+
+ const std::string to_string() const;
+ const std::string to_string( sc_numrep ) const;
+ const std::string to_string( sc_numrep, bool ) const;
+
+
+ // explicit conversions
+
+ inline int64 to_int64() const
+ { return to_anything_signed(); }
+ inline uint64 to_uint64() const;
+ int to_int() const
+ { return (int)to_anything_signed(); }
+
+ unsigned int to_uint() const
+ { return (unsigned int)to_anything_unsigned(); }
+
+ long to_long() const
+ { return (long)to_anything_signed(); }
+
+ unsigned long to_ulong() const
+ { return (unsigned long)to_anything_unsigned(); }
+
+#ifdef SC_DT_DEPRECATED
+
+ int to_signed() const
+ { return to_int(); }
+
+ sc_digit to_unsigned() const
+ { return to_uint(); }
+
+#endif
+
+
+ // other methods
+
+ void print( ::std::ostream& os = ::std::cout ) const
+ {
+ // the test below will force printing in binary if decimal is
+ // specified.
+ if ( sc_io_base(os, SC_DEC) == SC_DEC )
+ os << to_string();
+ else
+ os << to_string(sc_io_base(os,SC_BIN),sc_io_show_base(os));
+ }
+
+ void scan( ::std::istream& is = ::std::cin );
+
+protected:
+
+ void check_bounds( int n ) const; // check if bit n accessible
+ void check_wbounds( int n ) const; // check if word n accessible
+
+ sc_digit to_anything_unsigned() const;
+ int64 to_anything_signed() const;
+};
+
+
+// ----------------------------------------------------------------------------
+
+// bitwise operators and functions
+
+// bitwise and
+
+template <class X, class Y>
+inline
+X&
+operator &= ( sc_proxy<X>& px, const sc_proxy<Y>& py );
+
+
+template <class X, class Y>
+inline
+const sc_lv_base
+operator & ( const sc_proxy<X>& px, const sc_proxy<Y>& py );
+
+
+#define DECL_BITWISE_AND_OP_T(tp) \
+template <class X> \
+inline \
+const sc_lv_base \
+operator & ( tp b, const sc_proxy<X>& px );
+
+DECL_BITWISE_AND_OP_T(const char*)
+DECL_BITWISE_AND_OP_T(const bool*)
+DECL_BITWISE_AND_OP_T(const sc_logic*)
+DECL_BITWISE_AND_OP_T(const sc_unsigned&)
+DECL_BITWISE_AND_OP_T(const sc_signed&)
+DECL_BITWISE_AND_OP_T(const sc_uint_base&)
+DECL_BITWISE_AND_OP_T(const sc_int_base&)
+DECL_BITWISE_AND_OP_T(unsigned long)
+DECL_BITWISE_AND_OP_T(long)
+DECL_BITWISE_AND_OP_T(unsigned int)
+DECL_BITWISE_AND_OP_T(int)
+DECL_BITWISE_AND_OP_T(uint64)
+DECL_BITWISE_AND_OP_T(int64)
+
+#undef DECL_BITWISE_AND_OP_T
+
+
+// bitwise or
+
+template <class X, class Y>
+inline
+X&
+operator |= ( sc_proxy<X>& px, const sc_proxy<Y>& py );
+
+
+template <class X, class Y>
+inline
+const sc_lv_base
+operator | ( const sc_proxy<X>& px, const sc_proxy<Y>& py );
+
+
+#define DECL_BITWISE_OR_OP_T(tp) \
+template <class X> \
+inline \
+const sc_lv_base \
+operator | ( tp a, const sc_proxy<X>& px );
+
+DECL_BITWISE_OR_OP_T(const char*)
+DECL_BITWISE_OR_OP_T(const bool*)
+DECL_BITWISE_OR_OP_T(const sc_logic*)
+DECL_BITWISE_OR_OP_T(const sc_unsigned&)
+DECL_BITWISE_OR_OP_T(const sc_signed&)
+DECL_BITWISE_OR_OP_T(const sc_uint_base&)
+DECL_BITWISE_OR_OP_T(const sc_int_base&)
+DECL_BITWISE_OR_OP_T(unsigned long)
+DECL_BITWISE_OR_OP_T(long)
+DECL_BITWISE_OR_OP_T(unsigned int)
+DECL_BITWISE_OR_OP_T(int)
+DECL_BITWISE_OR_OP_T(uint64)
+DECL_BITWISE_OR_OP_T(int64)
+
+#undef DECL_BITWISE_OR_OP_T
+
+
+// bitwise xor
+
+template <class X, class Y>
+inline
+X&
+operator ^= ( sc_proxy<X>& px, const sc_proxy<Y>& py );
+
+
+template <class X, class Y>
+inline
+const sc_lv_base
+operator ^ ( const sc_proxy<X>& px, const sc_proxy<Y>& py );
+
+
+#define DECL_BITWISE_XOR_OP_T(tp) \
+template <class X> \
+inline \
+const sc_lv_base \
+operator ^ ( tp a, const sc_proxy<X>& px );
+
+DECL_BITWISE_XOR_OP_T(const char*)
+DECL_BITWISE_XOR_OP_T(const bool*)
+DECL_BITWISE_XOR_OP_T(const sc_logic*)
+DECL_BITWISE_XOR_OP_T(const sc_unsigned&)
+DECL_BITWISE_XOR_OP_T(const sc_signed&)
+DECL_BITWISE_XOR_OP_T(const sc_uint_base&)
+DECL_BITWISE_XOR_OP_T(const sc_int_base&)
+DECL_BITWISE_XOR_OP_T(unsigned long)
+DECL_BITWISE_XOR_OP_T(long)
+DECL_BITWISE_XOR_OP_T(unsigned int)
+DECL_BITWISE_XOR_OP_T(int)
+DECL_BITWISE_XOR_OP_T(uint64)
+DECL_BITWISE_XOR_OP_T(int64)
+
+#undef DECL_BITWISE_XOR_OP_T
+
+
+// relational operators
+
+template <class X, class Y>
+inline
+bool
+operator == ( const sc_proxy<X>& px, const sc_proxy<Y>& py );
+
+template <class X, class Y>
+inline
+bool
+operator != ( const sc_proxy<X>& px, const sc_proxy<Y>& py );
+
+
+#define DECL_REL_OP_T(tp) \
+template <class X> \
+inline \
+bool \
+operator == ( tp b, const sc_proxy<X>& px ); \
+ \
+template <class X> \
+inline \
+bool \
+operator != ( const sc_proxy<X>& px, tp b ); \
+ \
+template <class X> \
+inline \
+bool \
+operator != ( tp b, const sc_proxy<X>& px );
+
+DECL_REL_OP_T(const char*)
+DECL_REL_OP_T(const bool*)
+DECL_REL_OP_T(const sc_logic*)
+DECL_REL_OP_T(const sc_unsigned&)
+DECL_REL_OP_T(const sc_signed&)
+DECL_REL_OP_T(const sc_uint_base&)
+DECL_REL_OP_T(const sc_int_base&)
+DECL_REL_OP_T(unsigned long)
+DECL_REL_OP_T(long)
+DECL_REL_OP_T(unsigned int)
+DECL_REL_OP_T(int)
+DECL_REL_OP_T(uint64)
+DECL_REL_OP_T(int64)
+
+#undef DECL_REL_OP_T
+
+
+// l-value concatenation
+
+// Due to the fact that temporary objects cannot be passed to non-const
+// references, we have to enumerate, use call by value, and use dynamic
+// memory allocation (and deallocation).
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+template <class X>
+inline
+void
+get_words_( const X& x, int wi, sc_digit& x_dw, sc_digit& x_cw )
+{
+ x_dw = x.get_word( wi );
+ x_cw = x.get_cword( wi );
+}
+
+template <class X>
+inline
+void
+set_words_( X& x, int wi, sc_digit x_dw, sc_digit x_cw )
+{
+ x.set_word( wi, x_dw );
+ x.set_cword( wi, x_cw );
+}
+
+template <class X>
+inline
+void
+extend_sign_w_( X& x, int wi, bool sign )
+{
+ int sz = x.size();
+ unsigned int sgn = (sign ? ~SC_DIGIT_ZERO : SC_DIGIT_ZERO);
+ for( int i = wi; i < sz; ++ i ) {
+ set_words_( x, i, sgn, SC_DIGIT_ZERO );
+ }
+}
+
+
+// assignment functions
+
+template <class X, class Y>
+inline
+void
+assign_p_( sc_proxy<X>& px, const sc_proxy<Y>& py )
+{
+ if( (void*) &px != (void*) &py ) {
+ X& x = px.back_cast();
+ const Y& y = py.back_cast();
+ int sz = x.size();
+ int min_sz = sc_min( sz, y.size() );
+ int i = 0;
+ for( ; i < min_sz; ++ i ) {
+ set_words_( x, i, y.get_word( i ), y.get_cword( i ) );
+ }
+ // extend with zeros
+ extend_sign_w_( x, i, false );
+ x.clean_tail();
+ }
+}
+
+// Vector types that are not derived from sc_proxy, sc_int_base,
+// sc_uint_base, sc_signed, or sc_unsigned, must have a length()
+// function and an operator []. The vector argument type must support
+// accessing bits that are beyond the msb. The vector argument type
+// decides what to do there (e.g. sign extension or zero padding).
+
+template <class X, class T>
+inline
+void
+assign_v_( sc_proxy<X>& px, const T& a )
+{
+ X& x = px.back_cast();
+ int i;
+ int len_x = x.length();
+ int len_a = a.length();
+ if ( len_a > len_x ) len_a = len_x;
+ for( i = 0 ; i < len_a; ++ i ) {
+ x.set_bit( i, sc_logic_value_t( (bool) a[i] ) );
+ }
+ for( ; i < len_x; ++ i ) {
+ x.set_bit( i, sc_logic_value_t( false ) );
+ }
+}
+
+template <class X>
+inline
+void
+assign_v_( sc_proxy<X>& px, const sc_int_base& a )
+{
+ X& x = px.back_cast();
+ int i;
+ bool sign = a < 0;
+ int len_x = x.length();
+ int len_a = a.length();
+ if ( len_a > len_x ) len_a = len_x;
+ for( i = 0 ; i < len_a; ++ i ) {
+ x.set_bit( i, sc_logic_value_t( (bool) a[i] ) );
+ }
+ for( ; i < len_x; ++ i ) {
+ x.set_bit( i, sc_logic_value_t( sign ) );
+ }
+}
+
+template <class X>
+inline
+void
+assign_v_( sc_proxy<X>& px, const sc_signed& a )
+{
+ X& x = px.back_cast();
+ int i;
+ bool sign = a < 0;
+ int len_x = x.length();
+ int len_a = a.length();
+ if ( len_a > len_x ) len_a = len_x;
+ for( i = 0 ; i < len_a; ++ i ) {
+ x.set_bit( i, sc_logic_value_t( (bool) a[i] ) );
+ }
+ for( ; i < len_x; ++ i ) {
+ x.set_bit( i, sc_logic_value_t( sign ) );
+ }
+}
+
+template <class X>
+inline
+void
+assign_v_( sc_proxy<X>& px, const sc_uint_base& a )
+{
+ X& x = px.back_cast();
+ int i;
+ int len_x = x.length();
+ int len_a = a.length();
+ if ( len_a > len_x ) len_a = len_x;
+ for( i = 0 ; i < len_a; ++ i ) {
+ x.set_bit( i, sc_logic_value_t( (bool) a[i] ) );
+ }
+ for( ; i < len_x; ++ i ) {
+ x.set_bit( i, sc_logic_value_t( false ) );
+ }
+}
+
+template <class X>
+inline
+void
+assign_v_( sc_proxy<X>& px, const sc_unsigned& a )
+{
+ X& x = px.back_cast();
+ int i;
+ int len_x = x.length();
+ int len_a = a.length();
+ if ( len_a > len_x ) len_a = len_x;
+ for( i = 0 ; i < len_a; ++ i ) {
+ x.set_bit( i, sc_logic_value_t( (bool) a[i] ) );
+ }
+ for( ; i < len_x; ++ i ) {
+ x.set_bit( i, sc_logic_value_t( false ) );
+ }
+}
+
+
+// assignment operators
+
+template <class X>
+inline
+X&
+sc_proxy<X>::assign_( const char* a )
+{
+ X& x = back_cast();
+ std::string s = convert_to_bin( a );
+ int len = x.length();
+ int s_len = s.length() - 1;
+ int min_len = sc_min( len, s_len );
+ int i = 0;
+ for( ; i < min_len; ++ i ) {
+ char c = s[s_len - i - 1];
+ x.set_bit( i, sc_logic::char_to_logic[(int)c] );
+ }
+ // if formatted, fill the rest with sign(s), otherwise fill with zeros
+ sc_logic_value_t fill = (s[s_len] == 'F' ? sc_logic_value_t( s[0] - '0' )
+ : sc_logic_value_t( 0 ));
+ for( ; i < len; ++ i ) {
+ x.set_bit( i, fill );
+ }
+ return x;
+}
+
+template <class X>
+inline
+X&
+sc_proxy<X>::assign_( const bool* a )
+{
+ // the length of 'a' must be larger than or equal to the length of 'this'
+ X& x = back_cast();
+ int len = x.length();
+ for( int i = 0; i < len; ++ i ) {
+ x.set_bit( i, sc_logic_value_t( a[i] ) );
+ }
+ return x;
+}
+
+template <class X>
+inline
+X&
+sc_proxy<X>::assign_( const sc_logic* a )
+{
+ // the length of 'a' must be larger than or equal to the length of 'this'
+ X& x = back_cast();
+ int len = x.length();
+ for( int i = 0; i < len; ++ i ) {
+ x.set_bit( i, a[i].value() );
+ }
+ return x;
+}
+
+template <class X>
+inline
+X&
+sc_proxy<X>::assign_( unsigned int a )
+{
+ X& x = back_cast();
+ set_words_( x, 0, (sc_digit)a, SC_DIGIT_ZERO );
+ // extend with zeros
+ extend_sign_w_( x, 1, false );
+ x.clean_tail();
+ return x;
+}
+
+template <class X>
+inline
+X&
+sc_proxy<X>::assign_( int a )
+{
+ X& x = back_cast();
+ set_words_( x, 0, (sc_digit) a, SC_DIGIT_ZERO );
+ // extend with sign(a)
+ extend_sign_w_( x, 1, (a < 0) );
+ x.clean_tail();
+ return x;
+}
+
+#if defined(SC_LONG_64)
+ template <class X>
+ inline
+ X&
+ sc_proxy<X>::assign_( unsigned long a )
+ {
+ X& x = back_cast();
+ set_words_( x, 0, ((sc_digit) a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO );
+ if( x.size() > 1 ) {
+ set_words_( x, 1,
+ ((sc_digit) (a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO),
+ SC_DIGIT_ZERO );
+ // extend with zeros
+ extend_sign_w_( x, 2, false );
+ }
+ x.clean_tail();
+ return x;
+ }
+
+ template <class X>
+ inline
+ X&
+ sc_proxy<X>::assign_( long a )
+ {
+ X& x = back_cast();
+ set_words_( x, 0, ((sc_digit) a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO );
+ if( x.size() > 1 ) {
+ set_words_( x, 1,
+ ((sc_digit) ((uint64) a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO),
+ SC_DIGIT_ZERO );
+ // extend with sign(a)
+ extend_sign_w_( x, 2, (a < 0) );
+ }
+ x.clean_tail();
+ return x;
+ }
+
+#else
+ template <class X>
+ inline
+ X&
+ sc_proxy<X>::assign_( unsigned long a )
+ {
+ X& x = back_cast();
+ set_words_( x, 0, (sc_digit)a, SC_DIGIT_ZERO );
+ // extend with zeros
+ extend_sign_w_( x, 1, false );
+ x.clean_tail();
+ return x;
+ }
+
+ template <class X>
+ inline
+ X&
+ sc_proxy<X>::assign_( long a )
+ {
+ X& x = back_cast();
+ set_words_( x, 0, (sc_digit) a, SC_DIGIT_ZERO );
+ // extend with sign(a)
+ extend_sign_w_( x, 1, (a < 0) );
+ x.clean_tail();
+ return x;
+ }
+#endif
+template <class X>
+inline
+X&
+sc_proxy<X>::assign_( uint64 a )
+{
+ X& x = back_cast();
+ set_words_( x, 0, ((sc_digit) a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO );
+ if( x.size() > 1 ) {
+ set_words_( x, 1,
+ ((sc_digit) (a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO),
+ SC_DIGIT_ZERO );
+ // extend with zeros
+ extend_sign_w_( x, 2, false );
+ }
+ x.clean_tail();
+ return x;
+}
+
+template <class X>
+inline
+X&
+sc_proxy<X>::assign_( int64 a )
+{
+ X& x = back_cast();
+ set_words_( x, 0, ((sc_digit) a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO );
+ if( x.size() > 1 ) {
+ set_words_( x, 1,
+ ((sc_digit) ((uint64) a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO),
+ SC_DIGIT_ZERO );
+ // extend with sign(a)
+ extend_sign_w_( x, 2, (a < 0) );
+ }
+ x.clean_tail();
+ return x;
+}
+
+
+// bitwise operators and functions
+
+// bitwise complement
+
+template <class X>
+inline
+X&
+sc_proxy<X>::b_not()
+{
+ X& x = back_cast();
+ int sz = x.size();
+ for( int i = 0; i < sz; ++ i ) {
+ sc_digit x_dw, x_cw;
+ get_words_( x, i, x_dw, x_cw );
+ x.set_word( i, x_cw | ~x_dw );
+ }
+ x.clean_tail();
+ return x;
+}
+
+
+// bitwise and
+
+template <class X, class Y>
+inline
+X&
+b_and_assign_( sc_proxy<X>& px, const sc_proxy<Y>& py )
+{
+ X& x = px.back_cast();
+ const Y& y = py.back_cast();
+ assert( x.length() == y.length() );
+ int sz = x.size();
+ for( int i = 0; i < sz; ++ i ) {
+ sc_digit x_dw, x_cw, y_dw, y_cw;
+ get_words_( x, i, x_dw, x_cw );
+ get_words_( y, i, y_dw, y_cw );
+ sc_digit cw = (x_dw & y_cw) | (x_cw & y_dw) | (x_cw & y_cw);
+ sc_digit dw = cw | (x_dw & y_dw);
+ set_words_( x, i, dw, cw );
+ }
+ // tail cleaning not needed
+ return x;
+}
+
+
+// bitwise or
+
+template <class X, class Y>
+inline
+X&
+b_or_assign_( sc_proxy<X>& px, const sc_proxy<Y>& py )
+{
+ X& x = px.back_cast();
+ const Y& y = py.back_cast();
+ assert( x.length() == y.length() );
+ int sz = x.size();
+ for( int i = 0; i < sz; ++ i ) {
+ sc_digit x_dw, x_cw, y_dw, y_cw;
+ get_words_( x, i, x_dw, x_cw );
+ get_words_( y, i, y_dw, y_cw );
+ sc_digit cw = (x_cw & y_cw) | (x_cw & ~y_dw) | (~x_dw & y_cw);
+ sc_digit dw = cw | x_dw | y_dw;
+ set_words_( x, i, dw, cw );
+ }
+ // tail cleaning not needed
+ return x;
+}
+
+
+// bitwise xor
+
+template <class X, class Y>
+inline
+X&
+b_xor_assign_( sc_proxy<X>& a, const sc_proxy<Y>& b )
+{
+ X& x = a.back_cast();
+ const Y& y = b.back_cast();
+ assert( x.length() == y.length() );
+ int sz = x.size();
+ for( int i = 0; i < sz; ++ i ) {
+ sc_digit x_dw, x_cw, y_dw, y_cw;
+ get_words_( x, i, x_dw, x_cw );
+ get_words_( y, i, y_dw, y_cw );
+ sc_digit cw = x_cw | y_cw;
+ sc_digit dw = cw | (x_dw ^ y_dw);
+ set_words_( x, i, dw, cw );
+ }
+ // tail cleaning not needed
+ return x;
+}
+
+
+// bitwise left shift
+
+template <class X>
+inline
+X&
+sc_proxy<X>::operator <<= ( int n )
+{
+ X& x = back_cast();
+ if( n < 0 ) {
+ char msg[BUFSIZ];
+ std::sprintf( msg,
+ "left shift operation is only allowed with positive "
+ "shift values, shift value = %d", n );
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
+ }
+ if( n >= x.length() ) {
+ extend_sign_w_( x, 0, false );
+ // no tail cleaning needed
+ return x;
+ }
+ int sz = x.size();
+ int wn = n / SC_DIGIT_SIZE;
+ int bn = n % SC_DIGIT_SIZE;
+ if( wn != 0 ) {
+ // shift words
+ int i = sz - 1;
+ for( ; i >= wn; -- i ) {
+ set_words_( x, i, x.get_word( i - wn ), x.get_cword( i - wn ) );
+ }
+ for( ; i >= 0; -- i ) {
+ set_words_( x, i, SC_DIGIT_ZERO, SC_DIGIT_ZERO );
+ }
+ }
+ if( bn != 0 ) {
+ // shift bits
+ for( int i = sz - 1; i >= 1; -- i ) {
+ sc_digit x_dw, x_cw;
+ get_words_( x, i, x_dw, x_cw );
+ x_dw <<= bn;
+ x_dw |= x.get_word( i - 1 ) >> (SC_DIGIT_SIZE - bn);
+ x_cw <<= bn;
+ x_cw |= x.get_cword( i - 1 ) >> (SC_DIGIT_SIZE - bn);
+ set_words_( x, i, x_dw, x_cw );
+ }
+ sc_digit x_dw, x_cw;
+ get_words_( x, 0, x_dw, x_cw );
+ x_dw <<= bn;
+ x_cw <<= bn;
+ set_words_( x, 0, x_dw, x_cw );
+ }
+ x.clean_tail();
+ return x;
+}
+
+
+// bitwise right shift
+
+
+template <class X>
+inline
+X&
+sc_proxy<X>::operator >>= ( int n )
+{
+ X& x = back_cast();
+ if( n < 0 ) {
+ char msg[BUFSIZ];
+ std::sprintf( msg,
+ "right shift operation is only allowed with positive "
+ "shift values, shift value = %d", n );
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
+ }
+ if( n >= x.length() ) {
+ extend_sign_w_( x, 0, false );
+ // no tail cleaning needed
+ return x;
+ }
+ int sz = x.size();
+ int wn = n / SC_DIGIT_SIZE;
+ int bn = n % SC_DIGIT_SIZE;
+ if( wn != 0 ) {
+ // shift words
+ int i = 0;
+ for( ; i < (sz - wn); ++ i ) {
+ set_words_( x, i, x.get_word( i + wn ), x.get_cword( i + wn ) );
+ }
+ for( ; i < sz; ++ i ) {
+ set_words_( x, i, SC_DIGIT_ZERO, SC_DIGIT_ZERO );
+ }
+ }
+ if( bn != 0 ) {
+ // shift bits
+ for( int i = 0; i < (sz - 1); ++ i ) {
+ sc_digit x_dw, x_cw;
+ get_words_( x, i, x_dw, x_cw );
+ x_dw >>= bn;
+ x_dw |= x.get_word( i + 1 ) << (SC_DIGIT_SIZE - bn);
+ x_cw >>= bn;
+ x_cw |= x.get_cword( i + 1 ) << (SC_DIGIT_SIZE - bn);
+ set_words_( x, i, x_dw, x_cw );
+ }
+ sc_digit x_dw, x_cw;
+ get_words_( x, sz - 1, x_dw, x_cw );
+ x_dw >>= bn;
+ x_cw >>= bn;
+ set_words_( x, sz - 1, x_dw, x_cw );
+ }
+ x.clean_tail();
+ return x;
+}
+
+
+// bitwise left rotate
+
+template <class X>
+inline
+const sc_lv_base
+lrotate( const sc_proxy<X>& x, int n );
+
+
+// bitwise right rotate
+
+template <class X>
+inline
+const sc_lv_base
+rrotate( const sc_proxy<X>& x, int n );
+
+
+// bitwise reverse
+
+template <class X>
+inline
+X&
+sc_proxy<X>::reverse()
+{
+ X& x = back_cast();
+ int len = x.length();
+ int half_len = len / 2;
+ for( int i = 0, j = len - 1; i < half_len; ++ i, --j ) {
+ sc_logic_value_t t = x.get_bit( i );
+ x.set_bit( i, x.get_bit( j ) );
+ x.set_bit( j, t );
+ }
+ return x;
+}
+
+template <class X>
+inline
+const sc_lv_base
+reverse( const sc_proxy<X>& a );
+
+
+// reduce functions
+
+template <class X>
+inline
+sc_logic_value_t
+sc_proxy<X>::and_reduce() const
+{
+ const X& x = back_cast();
+ sc_logic_value_t result = sc_logic_value_t( 1 );
+ int len = x.length();
+ for( int i = 0; i < len; ++ i ) {
+ result = sc_logic::and_table[result][x.get_bit( i )];
+ }
+ return result;
+}
+
+template <class X>
+inline
+sc_logic_value_t
+sc_proxy<X>::or_reduce() const
+{
+ const X& x = back_cast();
+ sc_logic_value_t result = sc_logic_value_t( 0 );
+ int len = x.length();
+ for( int i = 0; i < len; ++ i ) {
+ result = sc_logic::or_table[result][x.get_bit( i )];
+ }
+ return result;
+}
+
+template <class X>
+inline
+sc_logic_value_t
+sc_proxy<X>::xor_reduce() const
+{
+ const X& x = back_cast();
+ sc_logic_value_t result = sc_logic_value_t( 0 );
+ int len = x.length();
+ for( int i = 0; i < len; ++ i ) {
+ result = sc_logic::xor_table[result][x.get_bit( i )];
+ }
+ return result;
+}
+
+
+// relational operators
+
+template <class X, class Y>
+inline
+bool
+operator != ( const sc_proxy<X>& px, const sc_proxy<Y>& py )
+{
+ return !( px == py );
+}
+
+
+#define DEFN_REL_OP_T(tp) \
+template <class X> \
+inline \
+bool \
+operator == ( tp b, const sc_proxy<X>& px ) \
+{ \
+ return ( px == b ); \
+} \
+ \
+template <class X> \
+inline \
+bool \
+operator != ( const sc_proxy<X>& px, tp b ) \
+{ \
+ return !( px == b ); \
+} \
+ \
+template <class X> \
+inline \
+bool \
+operator != ( tp b, const sc_proxy<X>& px ) \
+{ \
+ return !( px == b ); \
+}
+
+DEFN_REL_OP_T(const char*)
+DEFN_REL_OP_T(const bool*)
+DEFN_REL_OP_T(const sc_logic*)
+DEFN_REL_OP_T(const sc_unsigned&)
+DEFN_REL_OP_T(const sc_signed&)
+DEFN_REL_OP_T(const sc_uint_base&)
+DEFN_REL_OP_T(const sc_int_base&)
+DEFN_REL_OP_T(unsigned long)
+DEFN_REL_OP_T(long)
+DEFN_REL_OP_T(unsigned int)
+DEFN_REL_OP_T(int)
+DEFN_REL_OP_T(uint64)
+DEFN_REL_OP_T(int64)
+
+#undef DEFN_REL_OP_T
+
+
+// explicit conversions to character string
+
+template <class X>
+inline
+const std::string
+sc_proxy<X>::to_string() const
+{
+ const X& x = back_cast();
+ int len = x.length();
+ std::string s; // ( len + 1 );
+ for( int i = 0; i < len; ++ i ) {
+ s += sc_logic::logic_to_char[x.get_bit( len - i - 1 )];
+ }
+ return s;
+}
+
+template <class X>
+inline
+const std::string
+sc_proxy<X>::to_string( sc_numrep numrep ) const
+{
+ return convert_to_fmt( to_string(), numrep, true );
+}
+
+template <class X>
+inline
+const std::string
+sc_proxy<X>::to_string( sc_numrep numrep, bool w_prefix ) const
+{
+ return convert_to_fmt( to_string(), numrep, w_prefix );
+}
+
+
+// other methods
+
+template <class X>
+inline
+void
+sc_proxy<X>::scan( ::std::istream& is )
+{
+ std::string s;
+ is >> s;
+ back_cast() = s.c_str();
+}
+
+
+template <class X>
+inline
+void
+sc_proxy<X>::check_bounds( int n ) const // check if bit n accessible
+{
+ if( n < 0 || n >= back_cast().length() ) {
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 );
+ }
+}
+
+template <class X>
+inline
+void
+sc_proxy<X>::check_wbounds( int n ) const // check if word n accessible
+{
+ if( n < 0 || n >= back_cast().size() ) {
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 );
+ }
+}
+
+
+template <class X>
+inline
+sc_digit
+sc_proxy<X>::to_anything_unsigned() const
+{
+ // only 0 word is returned
+ // can't convert logic values other than 0 and 1
+ const X& x = back_cast();
+ int len = x.length();
+ if( x.get_cword( 0 ) != SC_DIGIT_ZERO ) {
+ SC_REPORT_WARNING( sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0 );
+ }
+ sc_digit w = x.get_word( 0 );
+ if( len >= SC_DIGIT_SIZE ) {
+ return w;
+ }
+ return ( w & (~SC_DIGIT_ZERO >> (SC_DIGIT_SIZE - len)) );
+}
+
+template <class X>
+inline
+uint64
+sc_proxy<X>::to_uint64() const
+{
+ // words 1 and 0 returned.
+ // can't convert logic values other than 0 and 1
+ const X& x = back_cast();
+ int len = x.length();
+ if( x.get_cword( 0 ) != SC_DIGIT_ZERO ) {
+ SC_REPORT_WARNING( sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0 );
+ }
+ uint64 w = x.get_word( 0 );
+ if( len > SC_DIGIT_SIZE )
+ {
+ if( x.get_cword( 1 ) != SC_DIGIT_ZERO ) {
+ SC_REPORT_WARNING( sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0 );
+ }
+ uint64 w1 = x.get_word( 1 );
+ w = w | (w1 << SC_DIGIT_SIZE);
+ return w;
+ }
+ else if( len == SC_DIGIT_SIZE )
+ {
+ return w;
+ }
+ else
+ {
+ return ( w & (~SC_DIGIT_ZERO >> (SC_DIGIT_SIZE - len)) );
+ }
+}
+
+template <class X>
+inline
+int64
+sc_proxy<X>::to_anything_signed() const
+{
+ const X& x = back_cast();
+ int len = x.length();
+ int64 w = 0;
+
+ if( len > SC_DIGIT_SIZE )
+ {
+ if( x.get_cword( 1 ) != SC_DIGIT_ZERO )
+ SC_REPORT_WARNING( sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0 );
+ w = x.get_word(1);
+ }
+ if( x.get_cword( 0 ) != SC_DIGIT_ZERO )
+ SC_REPORT_WARNING( sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0 );
+ w = (w << SC_DIGIT_SIZE) | x.get_word( 0 );
+ if( len >= 64 ) {
+ return w;
+ }
+
+ uint64 zero = 0;
+ sc_logic_value_t sgn = x.get_bit( len - 1 );
+ if( sgn == 0 ) {
+ return (int64)( w & (~zero >> (64 - len)) );
+ } else {
+ return (int64)( w | (~zero << len) );
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+
+// functional notation for the reduce methods
+
+template <class X>
+inline
+sc_logic_value_t
+and_reduce( const sc_proxy<X>& a )
+{
+ return a.and_reduce();
+}
+
+template <class X>
+inline
+sc_logic_value_t
+nand_reduce( const sc_proxy<X>& a )
+{
+ return a.nand_reduce();
+}
+
+template <class X>
+inline
+sc_logic_value_t
+or_reduce( const sc_proxy<X>& a )
+{
+ return a.or_reduce();
+}
+
+template <class X>
+inline
+sc_logic_value_t
+nor_reduce( const sc_proxy<X>& a )
+{
+ return a.nor_reduce();
+}
+
+template <class X>
+inline
+sc_logic_value_t
+xor_reduce( const sc_proxy<X>& a )
+{
+ return a.xor_reduce();
+}
+
+template <class X>
+inline
+sc_logic_value_t
+xnor_reduce( const sc_proxy<X>& a )
+{
+ return a.xnor_reduce();
+}
+
+
+// ----------------------------------------------------------------------------
+
+template <class X>
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, const sc_proxy<X>& a )
+{
+ a.print( os );
+ return os;
+}
+
+template <class X>
+inline
+::std::istream&
+operator >> ( ::std::istream& is, sc_proxy<X>& a )
+{
+ a.scan( is );
+ return is;
+}
+
+} // namespace sc_dt
+
+
+#endif
diff --git a/ext/systemc/src/sysc/datatypes/fx/fx.h b/ext/systemc/src/sysc/datatypes/fx/fx.h
new file mode 100644
index 000000000..9c35014fa
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/fx.h
@@ -0,0 +1,61 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ fx.h - Master include file for the fixed-point types.
+
+ Original Author: Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: fx.h,v $
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:57 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#ifndef FX_H
+#define FX_H
+
+
+#include "sysc/datatypes/fx/sc_fixed.h"
+#include "sysc/datatypes/fx/sc_fxcast_switch.h"
+#include "sysc/datatypes/fx/sc_fxtype_params.h"
+#include "sysc/datatypes/fx/sc_ufixed.h"
+
+#include "sysc/datatypes/fx/scfx_other_defs.h"
+
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_context.h b/ext/systemc/src/sysc/datatypes/fx/sc_context.h
new file mode 100644
index 000000000..1e313a486
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/sc_context.h
@@ -0,0 +1,316 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_context.h -
+
+ Original Author: Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_context.h,v $
+// Revision 1.2 2011/08/24 22:05:43 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.5 2006/05/26 20:36:52 acg
+// Andy Goodrich: added a using for sc_core::default_ptr_hash_fn to keep HP
+// aCC happy.
+//
+// Revision 1.4 2006/03/21 00:00:31 acg
+// Andy Goodrich: changed name of sc_get_current_process_base() to be
+// sc_get_current_process_b() since its returning an sc_process_b instance.
+//
+// Revision 1.3 2006/01/13 18:53:57 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#ifndef SC_CONTEXT_H
+#define SC_CONTEXT_H
+
+
+#include "sysc/datatypes/fx/sc_fx_ids.h"
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/utils/sc_hash.h"
+
+
+namespace sc_core {
+ class sc_process_b;
+}
+
+using sc_core::default_ptr_hash_fn; // To keep HP aCC happy.
+
+namespace sc_dt
+{
+
+// classes defined in this module
+class sc_without_context;
+template <class T> class sc_global;
+template <class T> class sc_context;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_without_context
+//
+// Empty class that is used for its type only.
+// ----------------------------------------------------------------------------
+
+class sc_without_context {};
+
+
+// ----------------------------------------------------------------------------
+// TEMPLATE CLASS : sc_global
+//
+// Template global variable class; singleton; co-routine safe.
+// ----------------------------------------------------------------------------
+
+template <class T>
+class sc_global
+{
+
+ sc_global();
+
+ void update();
+
+public:
+
+ static sc_global<T>* instance();
+
+ const T*& value_ptr();
+
+private:
+ static sc_global<T>* m_instance;
+
+ sc_core::sc_phash<void*,const T*> m_map;
+ void* m_proc; // context (current process or NULL)
+ const T* m_value_ptr;
+
+};
+
+
+// ----------------------------------------------------------------------------
+// ENUM : sc_context_begin
+//
+// Enumeration of context begin options.
+// ----------------------------------------------------------------------------
+
+enum sc_context_begin
+{
+ SC_NOW,
+ SC_LATER
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_context
+//
+// Template context class; co-routine safe.
+// ----------------------------------------------------------------------------
+
+template <class T>
+class sc_context
+{
+ // disabled
+ sc_context( const sc_context<T>& );
+ void* operator new( std::size_t );
+
+public:
+
+ explicit sc_context( const T&, sc_context_begin = SC_NOW );
+ ~sc_context();
+
+ void begin();
+ void end();
+
+ static const T& default_value();
+ const T& value() const;
+
+private:
+
+ const T m_value;
+ const T*& m_def_value_ptr;
+ const T* m_old_value_ptr;
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+// ----------------------------------------------------------------------------
+// TEMPLATE CLASS : sc_global
+//
+// Template global variable class; singleton; co-routine safe.
+// ----------------------------------------------------------------------------
+
+template <class T>
+sc_global<T>* sc_global<T>::m_instance = 0;
+
+template <class T>
+inline
+sc_global<T>::sc_global()
+ : m_map()
+ // use &m_instance as unique "non-process" key (NULL denotes 'sc_main' context)
+ , m_proc( &m_instance )
+ , m_value_ptr( 0 )
+{}
+
+
+template <class T>
+inline
+void
+sc_global<T>::update()
+{
+ void* p = sc_core::sc_get_current_process_b();
+ if( p != m_proc )
+ {
+ const T* vp = m_map[p];
+ if( vp == 0 )
+ {
+ vp = new T( sc_without_context() );
+ m_map.insert( p, vp );
+ }
+ m_proc = p;
+ m_value_ptr = vp;
+ }
+}
+
+
+template <class T>
+inline
+sc_global<T>*
+sc_global<T>::instance()
+{
+ if( m_instance == 0 )
+ {
+ m_instance = new sc_global<T>;
+ }
+ return m_instance;
+}
+
+
+template <class T>
+inline
+const T*&
+sc_global<T>::value_ptr()
+{
+ update();
+ return m_value_ptr;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_context
+//
+// Template context class; co-routine safe.
+// ----------------------------------------------------------------------------
+
+template <class T>
+inline
+sc_context<T>::sc_context( const T& value_, sc_context_begin begin )
+: m_value( value_ ),
+ m_def_value_ptr( sc_global<T>::instance()->value_ptr() ),
+ m_old_value_ptr( 0 )
+{
+ if( begin == SC_NOW )
+ {
+ m_old_value_ptr = m_def_value_ptr;
+ m_def_value_ptr = &m_value;
+ }
+}
+
+template <class T>
+inline
+sc_context<T>::~sc_context()
+{
+ if( m_old_value_ptr != 0 )
+ {
+ m_def_value_ptr = m_old_value_ptr;
+ m_old_value_ptr = 0;
+ }
+}
+
+
+template <class T>
+inline
+void
+sc_context<T>::begin()
+{
+ if( m_old_value_ptr == 0 )
+ {
+ m_old_value_ptr = m_def_value_ptr;
+ m_def_value_ptr = &m_value;
+ }
+ else
+ {
+ SC_REPORT_ERROR( sc_core::SC_ID_CONTEXT_BEGIN_FAILED_, 0 );
+ }
+}
+
+template <class T>
+inline
+void
+sc_context<T>::end()
+{
+ if( m_old_value_ptr != 0 )
+ {
+ m_def_value_ptr = m_old_value_ptr;
+ m_old_value_ptr = 0;
+ }
+ else
+ {
+ SC_REPORT_ERROR( sc_core::SC_ID_CONTEXT_END_FAILED_, 0 );
+ }
+}
+
+
+template <class T>
+inline
+const T&
+sc_context<T>::default_value()
+{
+ return *sc_global<T>::instance()->value_ptr();
+}
+
+template <class T>
+inline
+const T&
+sc_context<T>::value() const
+{
+ return m_value;
+}
+
+} // namespace sc_dt
+
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fix.h b/ext/systemc/src/sysc/datatypes/fx/sc_fix.h
new file mode 100644
index 000000000..80df65a2c
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/sc_fix.h
@@ -0,0 +1,1938 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_fix.h -
+
+ Original Author: Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_fix.h,v $
+// Revision 1.2 2011/01/19 18:57:40 acg
+// Andy Goodrich: changes for IEEE_1666_2011.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:57 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#ifndef SC_FIX_H
+#define SC_FIX_H
+
+
+#include "sysc/datatypes/fx/sc_fxnum.h"
+
+
+namespace sc_dt
+{
+
+// classes defined in this module
+class sc_fix;
+class sc_fix_fast;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fix
+//
+// "Unconstrained" signed fixed-point class; arbitrary precision.
+// ----------------------------------------------------------------------------
+
+class sc_fix : public sc_fxnum
+{
+
+public:
+
+ // constructors
+
+ explicit sc_fix( sc_fxnum_observer* = 0 );
+ sc_fix( int, int,
+ sc_fxnum_observer* = 0 );
+ sc_fix( sc_q_mode, sc_o_mode,
+ sc_fxnum_observer* = 0 );
+ sc_fix( sc_q_mode, sc_o_mode, int,
+ sc_fxnum_observer* = 0 );
+ sc_fix( int, int, sc_q_mode, sc_o_mode,
+ sc_fxnum_observer* = 0 );
+ sc_fix( int, int, sc_q_mode, sc_o_mode, int,
+ sc_fxnum_observer* = 0 );
+ explicit sc_fix( const sc_fxcast_switch&,
+ sc_fxnum_observer* = 0 );
+ sc_fix( int, int,
+ const sc_fxcast_switch&,
+ sc_fxnum_observer* = 0 );
+ sc_fix( sc_q_mode, sc_o_mode,
+ const sc_fxcast_switch&,
+ sc_fxnum_observer* = 0 );
+ sc_fix( sc_q_mode, sc_o_mode, int,
+ const sc_fxcast_switch&,
+ sc_fxnum_observer* = 0 );
+ sc_fix( int, int, sc_q_mode, sc_o_mode,
+ const sc_fxcast_switch&,
+ sc_fxnum_observer* = 0 );
+ sc_fix( int, int, sc_q_mode, sc_o_mode, int,
+ const sc_fxcast_switch&,
+ sc_fxnum_observer* = 0 );
+ explicit sc_fix( const sc_fxtype_params&,
+ sc_fxnum_observer* = 0 );
+ sc_fix( const sc_fxtype_params&,
+ const sc_fxcast_switch&,
+ sc_fxnum_observer* = 0 );
+
+#define DECL_CTORS_T(tp) \
+ sc_fix( tp, \
+ int, int, \
+ sc_fxnum_observer* = 0 ); \
+ sc_fix( tp, \
+ sc_q_mode, sc_o_mode, \
+ sc_fxnum_observer* = 0 ); \
+ sc_fix( tp, \
+ sc_q_mode, sc_o_mode, int, \
+ sc_fxnum_observer* = 0 ); \
+ sc_fix( tp, \
+ int, int, sc_q_mode, sc_o_mode, \
+ sc_fxnum_observer* = 0 ); \
+ sc_fix( tp, \
+ int, int, sc_q_mode, sc_o_mode, int, \
+ sc_fxnum_observer* = 0 ); \
+ sc_fix( tp, \
+ const sc_fxcast_switch&, \
+ sc_fxnum_observer* = 0 ); \
+ sc_fix( tp, \
+ int, int, \
+ const sc_fxcast_switch&, \
+ sc_fxnum_observer* = 0 ); \
+ sc_fix( tp, \
+ sc_q_mode, sc_o_mode, \
+ const sc_fxcast_switch&, \
+ sc_fxnum_observer* = 0 ); \
+ sc_fix( tp, \
+ sc_q_mode, sc_o_mode, int, \
+ const sc_fxcast_switch&, \
+ sc_fxnum_observer* = 0 ); \
+ sc_fix( tp, \
+ int, int, sc_q_mode, sc_o_mode, \
+ const sc_fxcast_switch&, \
+ sc_fxnum_observer* = 0 ); \
+ sc_fix( tp, \
+ int, int, sc_q_mode, sc_o_mode, int, \
+ const sc_fxcast_switch&, \
+ sc_fxnum_observer* = 0 ); \
+ sc_fix( tp, \
+ const sc_fxtype_params&, \
+ sc_fxnum_observer* = 0 ); \
+ sc_fix( tp, \
+ const sc_fxtype_params&, \
+ const sc_fxcast_switch&, \
+ sc_fxnum_observer* = 0 );
+
+#define DECL_CTORS_T_A(tp) \
+ sc_fix( tp, \
+ sc_fxnum_observer* = 0 ); \
+ DECL_CTORS_T(tp)
+
+#define DECL_CTORS_T_B(tp) \
+ explicit sc_fix( tp, \
+ sc_fxnum_observer* = 0 ); \
+ DECL_CTORS_T(tp)
+
+ DECL_CTORS_T_A(int)
+ DECL_CTORS_T_A(unsigned int)
+ DECL_CTORS_T_A(long)
+ DECL_CTORS_T_A(unsigned long)
+ DECL_CTORS_T_A(float)
+ DECL_CTORS_T_A(double)
+ DECL_CTORS_T_A(const char*)
+ DECL_CTORS_T_A(const sc_fxval&)
+ DECL_CTORS_T_A(const sc_fxval_fast&)
+ DECL_CTORS_T_A(const sc_fxnum&)
+ DECL_CTORS_T_A(const sc_fxnum_fast&)
+#ifndef SC_FX_EXCLUDE_OTHER
+ DECL_CTORS_T_B(int64)
+ DECL_CTORS_T_B(uint64)
+ DECL_CTORS_T_B(const sc_int_base&)
+ DECL_CTORS_T_B(const sc_uint_base&)
+ DECL_CTORS_T_B(const sc_signed&)
+ DECL_CTORS_T_B(const sc_unsigned&)
+#endif
+
+#undef DECL_CTORS_T
+#undef DECL_CTORS_T_A
+#undef DECL_CTORS_T_B
+
+ // copy constructor
+
+ sc_fix( const sc_fix& );
+
+
+ // unary bitwise operators
+
+ const sc_fix operator ~ () const;
+
+
+ // unary bitwise functions
+
+ friend void b_not( sc_fix&, const sc_fix& );
+
+
+ // binary bitwise operators
+
+ friend const sc_fix operator & ( const sc_fix&, const sc_fix& );
+ friend const sc_fix operator & ( const sc_fix&, const sc_fix_fast& );
+ friend const sc_fix operator & ( const sc_fix_fast&, const sc_fix& );
+ friend const sc_fix operator | ( const sc_fix&, const sc_fix& );
+ friend const sc_fix operator | ( const sc_fix&, const sc_fix_fast& );
+ friend const sc_fix operator | ( const sc_fix_fast&, const sc_fix& );
+ friend const sc_fix operator ^ ( const sc_fix&, const sc_fix& );
+ friend const sc_fix operator ^ ( const sc_fix&, const sc_fix_fast& );
+ friend const sc_fix operator ^ ( const sc_fix_fast&, const sc_fix& );
+
+
+ // binary bitwise functions
+
+ friend void b_and( sc_fix&, const sc_fix&, const sc_fix& );
+ friend void b_and( sc_fix&, const sc_fix&, const sc_fix_fast& );
+ friend void b_and( sc_fix&, const sc_fix_fast&, const sc_fix& );
+ friend void b_or ( sc_fix&, const sc_fix&, const sc_fix& );
+ friend void b_or ( sc_fix&, const sc_fix&, const sc_fix_fast& );
+ friend void b_or ( sc_fix&, const sc_fix_fast&, const sc_fix& );
+ friend void b_xor( sc_fix&, const sc_fix&, const sc_fix& );
+ friend void b_xor( sc_fix&, const sc_fix&, const sc_fix_fast& );
+ friend void b_xor( sc_fix&, const sc_fix_fast&, const sc_fix& );
+
+
+ // assignment operators
+
+ sc_fix& operator = ( const sc_fix& );
+
+#define DECL_ASN_OP_T(op,tp) \
+ sc_fix& operator op ( tp );
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DECL_ASN_OP_OTHER(op) \
+ DECL_ASN_OP_T(op,int64) \
+ DECL_ASN_OP_T(op,uint64) \
+ DECL_ASN_OP_T(op,const sc_int_base&) \
+ DECL_ASN_OP_T(op,const sc_uint_base&) \
+ DECL_ASN_OP_T(op,const sc_signed&) \
+ DECL_ASN_OP_T(op,const sc_unsigned&)
+#else
+#define DECL_ASN_OP_OTHER(op)
+#endif
+
+#define DECL_ASN_OP(op) \
+ DECL_ASN_OP_T(op,int) \
+ DECL_ASN_OP_T(op,unsigned int) \
+ DECL_ASN_OP_T(op,long) \
+ DECL_ASN_OP_T(op,unsigned long) \
+ DECL_ASN_OP_T(op,float) \
+ DECL_ASN_OP_T(op,double) \
+ DECL_ASN_OP_T(op,const char*) \
+ DECL_ASN_OP_T(op,const sc_fxval&) \
+ DECL_ASN_OP_T(op,const sc_fxval_fast&) \
+ DECL_ASN_OP_T(op,const sc_fxnum&) \
+ DECL_ASN_OP_T(op,const sc_fxnum_fast&) \
+ DECL_ASN_OP_OTHER(op)
+
+ DECL_ASN_OP(=)
+
+ DECL_ASN_OP(*=)
+ DECL_ASN_OP(/=)
+ DECL_ASN_OP(+=)
+ DECL_ASN_OP(-=)
+
+ DECL_ASN_OP_T(<<=,int)
+ DECL_ASN_OP_T(>>=,int)
+
+ DECL_ASN_OP_T(&=,const sc_fix&)
+ DECL_ASN_OP_T(&=,const sc_fix_fast&)
+ DECL_ASN_OP_T(|=,const sc_fix&)
+ DECL_ASN_OP_T(|=,const sc_fix_fast&)
+ DECL_ASN_OP_T(^=,const sc_fix&)
+ DECL_ASN_OP_T(^=,const sc_fix_fast&)
+
+#undef DECL_ASN_OP_T
+#undef DECL_ASN_OP_OTHER
+#undef DECL_ASN_OP
+
+
+ // auto-increment and auto-decrement
+
+ const sc_fxval operator ++ ( int );
+ const sc_fxval operator -- ( int );
+
+ sc_fix& operator ++ ();
+ sc_fix& operator -- ();
+
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fix_fast
+//
+// "Unconstrained" signed fixed-point class; limited precision.
+// ----------------------------------------------------------------------------
+
+class sc_fix_fast : public sc_fxnum_fast
+{
+
+public:
+
+ // constructors
+
+ explicit sc_fix_fast( sc_fxnum_fast_observer* = 0 );
+ sc_fix_fast( int, int,
+ sc_fxnum_fast_observer* = 0 );
+ sc_fix_fast( sc_q_mode, sc_o_mode,
+ sc_fxnum_fast_observer* = 0 );
+ sc_fix_fast( sc_q_mode, sc_o_mode, int,
+ sc_fxnum_fast_observer* = 0 );
+ sc_fix_fast( int, int, sc_q_mode, sc_o_mode,
+ sc_fxnum_fast_observer* = 0 );
+ sc_fix_fast( int, int, sc_q_mode, sc_o_mode, int,
+ sc_fxnum_fast_observer* = 0 );
+ explicit sc_fix_fast( const sc_fxcast_switch&,
+ sc_fxnum_fast_observer* = 0 );
+ sc_fix_fast( int, int,
+ const sc_fxcast_switch&,
+ sc_fxnum_fast_observer* = 0 );
+ sc_fix_fast( sc_q_mode, sc_o_mode,
+ const sc_fxcast_switch&,
+ sc_fxnum_fast_observer* = 0 );
+ sc_fix_fast( sc_q_mode, sc_o_mode, int,
+ const sc_fxcast_switch&,
+ sc_fxnum_fast_observer* = 0 );
+ sc_fix_fast( int, int, sc_q_mode, sc_o_mode,
+ const sc_fxcast_switch&,
+ sc_fxnum_fast_observer* = 0 );
+ sc_fix_fast( int, int, sc_q_mode, sc_o_mode, int,
+ const sc_fxcast_switch&,
+ sc_fxnum_fast_observer* = 0 );
+ explicit sc_fix_fast( const sc_fxtype_params&,
+ sc_fxnum_fast_observer* = 0 );
+ sc_fix_fast( const sc_fxtype_params&,
+ const sc_fxcast_switch&,
+ sc_fxnum_fast_observer* = 0 );
+
+#define DECL_CTORS_T(tp) \
+ sc_fix_fast( tp, \
+ int, int, \
+ sc_fxnum_fast_observer* = 0 ); \
+ sc_fix_fast( tp, \
+ sc_q_mode, sc_o_mode, \
+ sc_fxnum_fast_observer* = 0 ); \
+ sc_fix_fast( tp, \
+ sc_q_mode, sc_o_mode, int, \
+ sc_fxnum_fast_observer* = 0 ); \
+ sc_fix_fast( tp, \
+ int, int, sc_q_mode, sc_o_mode, \
+ sc_fxnum_fast_observer* = 0 ); \
+ sc_fix_fast( tp, \
+ int, int, sc_q_mode, sc_o_mode, int, \
+ sc_fxnum_fast_observer* = 0 ); \
+ sc_fix_fast( tp, \
+ const sc_fxcast_switch&, \
+ sc_fxnum_fast_observer* = 0 ); \
+ sc_fix_fast( tp, \
+ int, int, \
+ const sc_fxcast_switch&, \
+ sc_fxnum_fast_observer* = 0 ); \
+ sc_fix_fast( tp, \
+ sc_q_mode, sc_o_mode, \
+ const sc_fxcast_switch&, \
+ sc_fxnum_fast_observer* = 0 ); \
+ sc_fix_fast( tp, \
+ sc_q_mode, sc_o_mode, int, \
+ const sc_fxcast_switch&, \
+ sc_fxnum_fast_observer* = 0 ); \
+ sc_fix_fast( tp, \
+ int, int, sc_q_mode, sc_o_mode, \
+ const sc_fxcast_switch&, \
+ sc_fxnum_fast_observer* = 0 ); \
+ sc_fix_fast( tp, \
+ int, int, sc_q_mode, sc_o_mode, int, \
+ const sc_fxcast_switch&, \
+ sc_fxnum_fast_observer* = 0 ); \
+ sc_fix_fast( tp, \
+ const sc_fxtype_params&, \
+ sc_fxnum_fast_observer* = 0 ); \
+ sc_fix_fast( tp, \
+ const sc_fxtype_params&, \
+ const sc_fxcast_switch&, \
+ sc_fxnum_fast_observer* = 0 );
+
+#define DECL_CTORS_T_A(tp) \
+ sc_fix_fast( tp, \
+ sc_fxnum_fast_observer* = 0 ); \
+ DECL_CTORS_T(tp)
+
+#define DECL_CTORS_T_B(tp) \
+ explicit sc_fix_fast( tp, \
+ sc_fxnum_fast_observer* = 0 ); \
+ DECL_CTORS_T(tp)
+
+ DECL_CTORS_T_A(int)
+ DECL_CTORS_T_A(unsigned int)
+ DECL_CTORS_T_A(long)
+ DECL_CTORS_T_A(unsigned long)
+ DECL_CTORS_T_A(float)
+ DECL_CTORS_T_A(double)
+ DECL_CTORS_T_A(const char*)
+ DECL_CTORS_T_A(const sc_fxval&)
+ DECL_CTORS_T_A(const sc_fxval_fast&)
+ DECL_CTORS_T_A(const sc_fxnum&)
+ DECL_CTORS_T_A(const sc_fxnum_fast&)
+#ifndef SC_FX_EXCLUDE_OTHER
+ DECL_CTORS_T_B(int64)
+ DECL_CTORS_T_B(uint64)
+ DECL_CTORS_T_B(const sc_int_base&)
+ DECL_CTORS_T_B(const sc_uint_base&)
+ DECL_CTORS_T_B(const sc_signed&)
+ DECL_CTORS_T_B(const sc_unsigned&)
+#endif
+
+#undef DECL_CTORS_T
+#undef DECL_CTORS_T_A
+#undef DECL_CTORS_T_B
+
+ // copy constructor
+
+ sc_fix_fast( const sc_fix_fast& );
+
+
+ // unary bitwise operators
+
+ const sc_fix_fast operator ~ () const;
+
+
+ // unary bitwise functions
+
+ friend void b_not( sc_fix_fast&, const sc_fix_fast& );
+
+
+ // binary bitwise operators
+
+ friend const sc_fix_fast operator & ( const sc_fix_fast&,
+ const sc_fix_fast& );
+ friend const sc_fix_fast operator ^ ( const sc_fix_fast&,
+ const sc_fix_fast& );
+ friend const sc_fix_fast operator | ( const sc_fix_fast&,
+ const sc_fix_fast& );
+
+
+ // binary bitwise functions
+
+ friend void b_and( sc_fix_fast&, const sc_fix_fast&, const sc_fix_fast& );
+ friend void b_or ( sc_fix_fast&, const sc_fix_fast&, const sc_fix_fast& );
+ friend void b_xor( sc_fix_fast&, const sc_fix_fast&, const sc_fix_fast& );
+
+
+ // assignment operators
+
+ sc_fix_fast& operator = ( const sc_fix_fast& );
+
+#define DECL_ASN_OP_T(op,tp) \
+ sc_fix_fast& operator op ( tp );
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DECL_ASN_OP_OTHER(op) \
+ DECL_ASN_OP_T(op,int64) \
+ DECL_ASN_OP_T(op,uint64) \
+ DECL_ASN_OP_T(op,const sc_int_base&) \
+ DECL_ASN_OP_T(op,const sc_uint_base&) \
+ DECL_ASN_OP_T(op,const sc_signed&) \
+ DECL_ASN_OP_T(op,const sc_unsigned&)
+#else
+#define DECL_ASN_OP_OTHER(op)
+#endif
+
+#define DECL_ASN_OP(op) \
+ DECL_ASN_OP_T(op,int) \
+ DECL_ASN_OP_T(op,unsigned int) \
+ DECL_ASN_OP_T(op,long) \
+ DECL_ASN_OP_T(op,unsigned long) \
+ DECL_ASN_OP_T(op,float) \
+ DECL_ASN_OP_T(op,double) \
+ DECL_ASN_OP_T(op,const char*) \
+ DECL_ASN_OP_T(op,const sc_fxval&) \
+ DECL_ASN_OP_T(op,const sc_fxval_fast&) \
+ DECL_ASN_OP_T(op,const sc_fxnum&) \
+ DECL_ASN_OP_T(op,const sc_fxnum_fast&) \
+ DECL_ASN_OP_OTHER(op)
+
+ DECL_ASN_OP(=)
+
+ DECL_ASN_OP(*=)
+ DECL_ASN_OP(/=)
+ DECL_ASN_OP(+=)
+ DECL_ASN_OP(-=)
+
+ DECL_ASN_OP_T(<<=,int)
+ DECL_ASN_OP_T(>>=,int)
+
+ DECL_ASN_OP_T(&=,const sc_fix&)
+ DECL_ASN_OP_T(&=,const sc_fix_fast&)
+ DECL_ASN_OP_T(|=,const sc_fix&)
+ DECL_ASN_OP_T(|=,const sc_fix_fast&)
+ DECL_ASN_OP_T(^=,const sc_fix&)
+ DECL_ASN_OP_T(^=,const sc_fix_fast&)
+
+#undef DECL_ASN_OP_T
+#undef DECL_ASN_OP_OTHER
+#undef DECL_ASN_OP
+
+
+ // auto-increment and auto-decrement
+
+ const sc_fxval_fast operator ++ ( int );
+ const sc_fxval_fast operator -- ( int );
+
+ sc_fix_fast& operator ++ ();
+ sc_fix_fast& operator -- ();
+
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fix
+//
+// "Unconstrained" signed fixed-point class; arbitrary precision.
+// ----------------------------------------------------------------------------
+
+// constructors
+
+inline
+sc_fix::sc_fix( sc_fxnum_observer* observer_ )
+: sc_fxnum( sc_fxtype_params(),
+ SC_TC_,
+ sc_fxcast_switch(),
+ observer_ )
+{}
+
+inline
+sc_fix::sc_fix( int wl_, int iwl_,
+ sc_fxnum_observer* observer_ )
+: sc_fxnum( sc_fxtype_params( wl_, iwl_ ),
+ SC_TC_,
+ sc_fxcast_switch(),
+ observer_ )
+{}
+
+inline
+sc_fix::sc_fix( sc_q_mode qm, sc_o_mode om,
+ sc_fxnum_observer* observer_ )
+: sc_fxnum( sc_fxtype_params( qm, om ),
+ SC_TC_,
+ sc_fxcast_switch(),
+ observer_ )
+{}
+
+inline
+sc_fix::sc_fix( sc_q_mode qm, sc_o_mode om, int nb,
+ sc_fxnum_observer* observer_ )
+: sc_fxnum( sc_fxtype_params( qm, om, nb ),
+ SC_TC_,
+ sc_fxcast_switch(),
+ observer_ )
+{}
+
+inline
+sc_fix::sc_fix( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om,
+ sc_fxnum_observer* observer_ )
+: sc_fxnum( sc_fxtype_params( wl_, iwl_, qm, om ),
+ SC_TC_,
+ sc_fxcast_switch(),
+ observer_ )
+{}
+
+inline
+sc_fix::sc_fix( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb,
+ sc_fxnum_observer* observer_ )
+: sc_fxnum( sc_fxtype_params( wl_, iwl_, qm, om, nb ),
+ SC_TC_,
+ sc_fxcast_switch(),
+ observer_ )
+{}
+
+inline
+sc_fix::sc_fix( const sc_fxcast_switch& cast_sw,
+ sc_fxnum_observer* observer_ )
+: sc_fxnum( sc_fxtype_params(),
+ SC_TC_,
+ cast_sw,
+ observer_ )
+{}
+
+inline
+sc_fix::sc_fix( int wl_, int iwl_,
+ const sc_fxcast_switch& cast_sw,
+ sc_fxnum_observer* observer_ )
+: sc_fxnum( sc_fxtype_params( wl_, iwl_ ),
+ SC_TC_,
+ cast_sw,
+ observer_ )
+{}
+
+inline
+sc_fix::sc_fix( sc_q_mode qm, sc_o_mode om,
+ const sc_fxcast_switch& cast_sw,
+ sc_fxnum_observer* observer_ )
+: sc_fxnum( sc_fxtype_params( qm, om ),
+ SC_TC_,
+ cast_sw,
+ observer_ )
+{}
+
+inline
+sc_fix::sc_fix( sc_q_mode qm, sc_o_mode om, int nb,
+ const sc_fxcast_switch& cast_sw,
+ sc_fxnum_observer* observer_ )
+: sc_fxnum( sc_fxtype_params( qm, om, nb ),
+ SC_TC_,
+ cast_sw,
+ observer_ )
+{}
+
+inline
+sc_fix::sc_fix( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om,
+ const sc_fxcast_switch& cast_sw,
+ sc_fxnum_observer* observer_ )
+: sc_fxnum( sc_fxtype_params( wl_, iwl_, qm, om ),
+ SC_TC_,
+ cast_sw,
+ observer_ )
+{}
+
+inline
+sc_fix::sc_fix( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb,
+ const sc_fxcast_switch& cast_sw,
+ sc_fxnum_observer* observer_ )
+: sc_fxnum( sc_fxtype_params( wl_, iwl_, qm, om, nb ),
+ SC_TC_,
+ cast_sw,
+ observer_ )
+{}
+
+inline
+sc_fix::sc_fix( const sc_fxtype_params& type_params,
+ sc_fxnum_observer* observer_ )
+: sc_fxnum( type_params,
+ SC_TC_,
+ sc_fxcast_switch(),
+ observer_ )
+{}
+
+inline
+sc_fix::sc_fix( const sc_fxtype_params& type_params,
+ const sc_fxcast_switch& cast_sw,
+ sc_fxnum_observer* observer_ )
+: sc_fxnum( type_params,
+ SC_TC_,
+ cast_sw,
+ observer_ )
+{}
+
+#define DEFN_CTORS_T_A(tp) \
+inline \
+sc_fix::sc_fix( tp a, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params(), \
+ SC_TC_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix::sc_fix( tp a, \
+ int wl_, int iwl_, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( wl_, iwl_ ), \
+ SC_TC_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix::sc_fix( tp a, \
+ sc_q_mode qm, sc_o_mode om, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( qm, om ), \
+ SC_TC_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix::sc_fix( tp a, \
+ sc_q_mode qm, sc_o_mode om, int nb, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( qm, om, nb ), \
+ SC_TC_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix::sc_fix( tp a, \
+ int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om ), \
+ SC_TC_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix::sc_fix( tp a, \
+ int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om, nb ), \
+ SC_TC_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix::sc_fix( tp a, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params(), \
+ SC_TC_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix::sc_fix( tp a, \
+ int wl_, int iwl_, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( wl_, iwl_ ), \
+ SC_TC_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix::sc_fix( tp a, \
+ sc_q_mode qm, sc_o_mode om, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( qm, om ), \
+ SC_TC_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix::sc_fix( tp a, \
+ sc_q_mode qm, sc_o_mode om, int nb, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( qm, om, nb ), \
+ SC_TC_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix::sc_fix( tp a, \
+ int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om ), \
+ SC_TC_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix::sc_fix( tp a, \
+ int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om, nb ), \
+ SC_TC_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix::sc_fix( tp a, \
+ const sc_fxtype_params& type_params, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ type_params, \
+ SC_TC_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix::sc_fix( tp a, \
+ const sc_fxtype_params& type_params, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ type_params, \
+ SC_TC_, \
+ cast_sw, \
+ observer_ ) \
+{}
+
+#define DEFN_CTORS_T_B(tp) \
+inline \
+sc_fix::sc_fix( tp a, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ a.type_params(), \
+ SC_TC_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix::sc_fix( tp a, \
+ int wl_, int iwl_, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( a.type_params(), wl_, iwl_ ), \
+ SC_TC_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix::sc_fix( tp a, \
+ sc_q_mode qm, sc_o_mode om, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( a.type_params(), qm, om ), \
+ SC_TC_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix::sc_fix( tp a, \
+ sc_q_mode qm, sc_o_mode om, int nb, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( a.type_params(), qm, om, nb ), \
+ SC_TC_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix::sc_fix( tp a, \
+ int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om ), \
+ SC_TC_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix::sc_fix( tp a, \
+ int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om, nb ), \
+ SC_TC_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix::sc_fix( tp a, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ a.type_params(), \
+ SC_TC_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix::sc_fix( tp a, \
+ int wl_, int iwl_, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( a.type_params(), wl_, iwl_ ), \
+ SC_TC_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix::sc_fix( tp a, \
+ sc_q_mode qm, sc_o_mode om, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( a.type_params(), qm, om ), \
+ SC_TC_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix::sc_fix( tp a, \
+ sc_q_mode qm, sc_o_mode om, int nb, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( a.type_params(), qm, om, nb ), \
+ SC_TC_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix::sc_fix( tp a, \
+ int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om ), \
+ SC_TC_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix::sc_fix( tp a, \
+ int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om, nb ), \
+ SC_TC_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix::sc_fix( tp a, \
+ const sc_fxtype_params& type_params, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ type_params, \
+ SC_TC_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix::sc_fix( tp a, \
+ const sc_fxtype_params& type_params, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ type_params, \
+ SC_TC_, \
+ cast_sw, \
+ observer_ ) \
+{}
+
+DEFN_CTORS_T_A(int)
+DEFN_CTORS_T_A(unsigned int)
+DEFN_CTORS_T_A(long)
+DEFN_CTORS_T_A(unsigned long)
+DEFN_CTORS_T_A(float)
+DEFN_CTORS_T_A(double)
+DEFN_CTORS_T_A(const char*)
+DEFN_CTORS_T_A(const sc_fxval&)
+DEFN_CTORS_T_A(const sc_fxval_fast&)
+DEFN_CTORS_T_B(const sc_fxnum&)
+DEFN_CTORS_T_B(const sc_fxnum_fast&)
+#ifndef SC_FX_EXCLUDE_OTHER
+DEFN_CTORS_T_A(int64)
+DEFN_CTORS_T_A(uint64)
+DEFN_CTORS_T_A(const sc_int_base&)
+DEFN_CTORS_T_A(const sc_uint_base&)
+DEFN_CTORS_T_A(const sc_signed&)
+DEFN_CTORS_T_A(const sc_unsigned&)
+#endif
+
+#undef DEFN_CTORS_T_A
+#undef DEFN_CTORS_T_B
+
+// copy constructor
+
+inline
+sc_fix::sc_fix( const sc_fix& a )
+: sc_fxnum( a,
+ a.type_params(),
+ SC_TC_,
+ sc_fxcast_switch(),
+ 0 )
+{}
+
+
+// unary bitwise operators
+
+inline
+const sc_fix
+sc_fix::operator ~ () const
+{
+ SC_FXNUM_OBSERVER_READ_( *this )
+ int iwl_c = iwl();
+ int wl_c = wl();
+ sc_fix c( wl_c, iwl_c );
+ for( int i = iwl_c - wl_c; i < iwl_c; ++ i )
+ c.set_bit( i, ! get_bit( i ) );
+ return sc_fix( c, wl_c, iwl_c );
+}
+
+
+// unary bitwise functions
+
+inline
+void
+b_not( sc_fix& c, const sc_fix& a )
+{
+ SC_FXNUM_OBSERVER_READ_( a )
+ int iwl_c = c.iwl();
+ for( int i = iwl_c - c.wl(); i < iwl_c; ++ i )
+ c.set_bit( i, ! a.get_bit( i ) );
+ c.cast();
+ SC_FXNUM_OBSERVER_WRITE_( c )
+}
+
+
+// binary bitwise operators
+
+#define DEFN_BIN_OP_T(op,op2,tp1,tp2) \
+inline \
+const sc_fix \
+operator op ( const tp1& a, const tp2& b ) \
+{ \
+ a.observer_read(); \
+ b.observer_read(); \
+ int iwl_a = a.iwl(); \
+ int iwl_b = b.iwl(); \
+ int iwl_c = sc_max( iwl_a, iwl_b ); \
+ int fwl_c = sc_max( a.wl() - iwl_a, b.wl() - iwl_b ); \
+ sc_fix c( iwl_c + fwl_c, iwl_c ); \
+ for( int i = -fwl_c; i < iwl_c; ++ i ) \
+ c.set_bit( i, a.get_bit( i ) op2 b.get_bit( i ) ); \
+ return sc_fix( c, iwl_c + fwl_c, iwl_c ); \
+}
+
+DEFN_BIN_OP_T(&,&&,sc_fix,sc_fix)
+DEFN_BIN_OP_T(&,&&,sc_fix,sc_fix_fast)
+DEFN_BIN_OP_T(&,&&,sc_fix_fast,sc_fix)
+
+DEFN_BIN_OP_T(|,||,sc_fix,sc_fix)
+DEFN_BIN_OP_T(|,||,sc_fix,sc_fix_fast)
+DEFN_BIN_OP_T(|,||,sc_fix_fast,sc_fix)
+
+DEFN_BIN_OP_T(^,!=,sc_fix,sc_fix)
+DEFN_BIN_OP_T(^,!=,sc_fix,sc_fix_fast)
+DEFN_BIN_OP_T(^,!=,sc_fix_fast,sc_fix)
+
+#undef DEFN_BIN_OP_T
+
+
+// binary bitwise functions
+
+#define DEFN_BIN_FNC_T(fnc,op2,tp1,tp2) \
+inline \
+void \
+fnc ( sc_fix& c, const tp1& a, const tp2& b ) \
+{ \
+ a.observer_read(); \
+ b.observer_read(); \
+ int iwl_c = c.iwl(); \
+ for( int i = iwl_c - c.wl(); i < iwl_c; ++ i ) \
+ c.set_bit( i, a.get_bit( i ) op2 b.get_bit( i ) ); \
+ c.cast(); \
+ SC_FXNUM_OBSERVER_WRITE_( c ) \
+}
+
+DEFN_BIN_FNC_T(b_and,&&,sc_fix,sc_fix)
+DEFN_BIN_FNC_T(b_and,&&,sc_fix,sc_fix_fast)
+DEFN_BIN_FNC_T(b_and,&&,sc_fix_fast,sc_fix)
+
+DEFN_BIN_FNC_T(b_or,||,sc_fix,sc_fix)
+DEFN_BIN_FNC_T(b_or,||,sc_fix,sc_fix_fast)
+DEFN_BIN_FNC_T(b_or,||,sc_fix_fast,sc_fix)
+
+DEFN_BIN_FNC_T(b_xor,!=,sc_fix,sc_fix)
+DEFN_BIN_FNC_T(b_xor,!=,sc_fix,sc_fix_fast)
+DEFN_BIN_FNC_T(b_xor,!=,sc_fix_fast,sc_fix)
+
+#undef DEFN_BIN_FNC_T
+
+
+// assignment operators
+
+inline
+sc_fix&
+sc_fix::operator = ( const sc_fix& a )
+{
+ sc_fxnum::operator = ( a );
+ return *this;
+}
+
+#define DEFN_ASN_OP_T(op,tp) \
+inline \
+sc_fix& \
+sc_fix::operator op ( tp a ) \
+{ \
+ sc_fxnum::operator op( a ); \
+ return *this; \
+}
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DEFN_ASN_OP_OTHER(op) \
+DEFN_ASN_OP_T(op,int64) \
+DEFN_ASN_OP_T(op,uint64) \
+DEFN_ASN_OP_T(op,const sc_int_base&) \
+DEFN_ASN_OP_T(op,const sc_uint_base&) \
+DEFN_ASN_OP_T(op,const sc_signed&) \
+DEFN_ASN_OP_T(op,const sc_unsigned&)
+#else
+#define DEFN_ASN_OP_OTHER(op)
+#endif
+
+#define DEFN_ASN_OP(op) \
+DEFN_ASN_OP_T(op,int) \
+DEFN_ASN_OP_T(op,unsigned int) \
+DEFN_ASN_OP_T(op,long) \
+DEFN_ASN_OP_T(op,unsigned long) \
+DEFN_ASN_OP_T(op,float) \
+DEFN_ASN_OP_T(op,double) \
+DEFN_ASN_OP_T(op,const char*) \
+DEFN_ASN_OP_T(op,const sc_fxval&) \
+DEFN_ASN_OP_T(op,const sc_fxval_fast&) \
+DEFN_ASN_OP_T(op,const sc_fxnum&) \
+DEFN_ASN_OP_T(op,const sc_fxnum_fast&) \
+DEFN_ASN_OP_OTHER(op)
+
+DEFN_ASN_OP(=)
+
+DEFN_ASN_OP(*=)
+DEFN_ASN_OP(/=)
+DEFN_ASN_OP(+=)
+DEFN_ASN_OP(-=)
+
+DEFN_ASN_OP_T(<<=,int)
+DEFN_ASN_OP_T(>>=,int)
+
+#undef DEFN_ASN_OP_T
+#undef DEFN_ASN_OP_OTHER
+#undef DEFN_ASN_OP
+
+
+#define DEFN_ASN_OP_T(op,op2,tp) \
+inline \
+sc_fix& \
+sc_fix::operator op ( const tp& b ) \
+{ \
+ SC_FXNUM_OBSERVER_READ_( *this ) \
+ b.observer_read(); \
+ int iwl_c = iwl(); \
+ for( int i = iwl_c - wl(); i < iwl_c; ++ i ) \
+ set_bit( i, get_bit( i ) op2 b.get_bit( i ) ); \
+ cast(); \
+ SC_FXNUM_OBSERVER_WRITE_( *this ) \
+ return *this; \
+}
+
+DEFN_ASN_OP_T(&=,&&,sc_fix)
+DEFN_ASN_OP_T(&=,&&,sc_fix_fast)
+DEFN_ASN_OP_T(|=,||,sc_fix)
+DEFN_ASN_OP_T(|=,||,sc_fix_fast)
+DEFN_ASN_OP_T(^=,!=,sc_fix)
+DEFN_ASN_OP_T(^=,!=,sc_fix_fast)
+
+#undef DEFN_ASN_OP_T
+
+
+// auto-increment and auto-decrement
+
+inline
+const sc_fxval
+sc_fix::operator ++ ( int )
+{
+ return sc_fxval( sc_fxnum::operator ++ ( 0 ) );
+}
+
+inline
+const sc_fxval
+sc_fix::operator -- ( int )
+{
+ return sc_fxval( sc_fxnum::operator -- ( 0 ) );
+}
+
+inline
+sc_fix&
+sc_fix::operator ++ ()
+{
+ sc_fxnum::operator ++ ();
+ return *this;
+}
+
+inline
+sc_fix&
+sc_fix::operator -- ()
+{
+ sc_fxnum::operator -- ();
+ return *this;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fix_fast
+//
+// "Unconstrained" signed fixed-point class; limited precision.
+// ----------------------------------------------------------------------------
+
+// constructors
+
+inline
+sc_fix_fast::sc_fix_fast( sc_fxnum_fast_observer* observer_ )
+: sc_fxnum_fast( sc_fxtype_params(),
+ SC_TC_,
+ sc_fxcast_switch(),
+ observer_ )
+{}
+
+inline
+sc_fix_fast::sc_fix_fast( int wl_, int iwl_,
+ sc_fxnum_fast_observer* observer_ )
+: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_ ),
+ SC_TC_,
+ sc_fxcast_switch(),
+ observer_ )
+{}
+
+inline
+sc_fix_fast::sc_fix_fast( sc_q_mode qm, sc_o_mode om,
+ sc_fxnum_fast_observer* observer_ )
+: sc_fxnum_fast( sc_fxtype_params( qm, om ),
+ SC_TC_,
+ sc_fxcast_switch(),
+ observer_ )
+{}
+
+inline
+sc_fix_fast::sc_fix_fast( sc_q_mode qm, sc_o_mode om, int nb,
+ sc_fxnum_fast_observer* observer_ )
+: sc_fxnum_fast( sc_fxtype_params( qm, om, nb ),
+ SC_TC_,
+ sc_fxcast_switch(),
+ observer_ )
+{}
+
+inline
+sc_fix_fast::sc_fix_fast( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om,
+ sc_fxnum_fast_observer* observer_ )
+: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_, qm, om ),
+ SC_TC_,
+ sc_fxcast_switch(),
+ observer_ )
+{}
+
+inline
+sc_fix_fast::sc_fix_fast( int wl_, int iwl_,
+ sc_q_mode qm, sc_o_mode om, int nb,
+ sc_fxnum_fast_observer* observer_ )
+: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_, qm, om, nb ),
+ SC_TC_,
+ sc_fxcast_switch(),
+ observer_ )
+{}
+
+inline
+sc_fix_fast::sc_fix_fast( const sc_fxcast_switch& cast_sw,
+ sc_fxnum_fast_observer* observer_ )
+: sc_fxnum_fast( sc_fxtype_params(),
+ SC_TC_,
+ cast_sw,
+ observer_ )
+{}
+
+inline
+sc_fix_fast::sc_fix_fast( int wl_, int iwl_,
+ const sc_fxcast_switch& cast_sw,
+ sc_fxnum_fast_observer* observer_ )
+: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_ ),
+ SC_TC_,
+ cast_sw,
+ observer_ )
+{}
+
+inline
+sc_fix_fast::sc_fix_fast( sc_q_mode qm, sc_o_mode om,
+ const sc_fxcast_switch& cast_sw,
+ sc_fxnum_fast_observer* observer_ )
+: sc_fxnum_fast( sc_fxtype_params( qm, om ),
+ SC_TC_,
+ cast_sw,
+ observer_ )
+{}
+
+inline
+sc_fix_fast::sc_fix_fast( sc_q_mode qm, sc_o_mode om, int nb,
+ const sc_fxcast_switch& cast_sw,
+ sc_fxnum_fast_observer* observer_ )
+: sc_fxnum_fast( sc_fxtype_params( qm, om, nb ),
+ SC_TC_,
+ cast_sw,
+ observer_ )
+{}
+
+inline
+sc_fix_fast::sc_fix_fast( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om,
+ const sc_fxcast_switch& cast_sw,
+ sc_fxnum_fast_observer* observer_ )
+: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_, qm, om ),
+ SC_TC_,
+ cast_sw,
+ observer_ )
+{}
+
+inline
+sc_fix_fast::sc_fix_fast( int wl_, int iwl_,
+ sc_q_mode qm, sc_o_mode om, int nb,
+ const sc_fxcast_switch& cast_sw,
+ sc_fxnum_fast_observer* observer_ )
+: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_, qm, om, nb ),
+ SC_TC_,
+ cast_sw,
+ observer_ )
+{}
+
+inline
+sc_fix_fast::sc_fix_fast( const sc_fxtype_params& type_params,
+ sc_fxnum_fast_observer* observer_ )
+: sc_fxnum_fast( type_params,
+ SC_TC_,
+ sc_fxcast_switch(),
+ observer_ )
+{}
+
+inline
+sc_fix_fast::sc_fix_fast( const sc_fxtype_params& type_params,
+ const sc_fxcast_switch& cast_sw,
+ sc_fxnum_fast_observer* observer_ )
+: sc_fxnum_fast( type_params,
+ SC_TC_,
+ cast_sw,
+ observer_ )
+{}
+
+#define DEFN_CTORS_T_A(tp) \
+inline \
+sc_fix_fast::sc_fix_fast( tp a, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params(), \
+ SC_TC_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix_fast::sc_fix_fast( tp a, \
+ int wl_, int iwl_, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( wl_, iwl_ ), \
+ SC_TC_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix_fast::sc_fix_fast( tp a, \
+ sc_q_mode qm, sc_o_mode om, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( qm, om ), \
+ SC_TC_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix_fast::sc_fix_fast( tp a, \
+ sc_q_mode qm, sc_o_mode om, int nb, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( qm, om, nb ), \
+ SC_TC_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix_fast::sc_fix_fast( tp a, \
+ int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om ), \
+ SC_TC_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix_fast::sc_fix_fast( tp a, \
+ int wl_, int iwl_, \
+ sc_q_mode qm, sc_o_mode om, int nb, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om, nb ), \
+ SC_TC_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix_fast::sc_fix_fast( tp a, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params(), \
+ SC_TC_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix_fast::sc_fix_fast( tp a, \
+ int wl_, int iwl_, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( wl_, iwl_ ), \
+ SC_TC_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix_fast::sc_fix_fast( tp a, \
+ sc_q_mode qm, sc_o_mode om, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( qm, om ), \
+ SC_TC_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix_fast::sc_fix_fast( tp a, \
+ sc_q_mode qm, sc_o_mode om, int nb, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( qm, om, nb ), \
+ SC_TC_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix_fast::sc_fix_fast( tp a, \
+ int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om ), \
+ SC_TC_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix_fast::sc_fix_fast( tp a, \
+ int wl_, int iwl_, \
+ sc_q_mode qm, sc_o_mode om, int nb, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om, nb ), \
+ SC_TC_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix_fast::sc_fix_fast( tp a, \
+ const sc_fxtype_params& type_params, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ type_params, \
+ SC_TC_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix_fast::sc_fix_fast( tp a, \
+ const sc_fxtype_params& type_params, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ type_params, \
+ SC_TC_, \
+ cast_sw, \
+ observer_ ) \
+{}
+
+#define DEFN_CTORS_T_B(tp) \
+inline \
+sc_fix_fast::sc_fix_fast( tp a, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ a.type_params(), \
+ SC_TC_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix_fast::sc_fix_fast( tp a, \
+ int wl_, int iwl_, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( a.type_params(), wl_, iwl_ ), \
+ SC_TC_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix_fast::sc_fix_fast( tp a, \
+ sc_q_mode qm, sc_o_mode om, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( a.type_params(), qm, om ), \
+ SC_TC_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix_fast::sc_fix_fast( tp a, \
+ sc_q_mode qm, sc_o_mode om, int nb, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( a.type_params(), qm, om, nb ), \
+ SC_TC_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix_fast::sc_fix_fast( tp a, \
+ int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om ), \
+ SC_TC_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix_fast::sc_fix_fast( tp a, \
+ int wl_, int iwl_, \
+ sc_q_mode qm, sc_o_mode om, int nb, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om, nb ), \
+ SC_TC_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix_fast::sc_fix_fast( tp a, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ a.type_params(), \
+ SC_TC_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix_fast::sc_fix_fast( tp a, \
+ int wl_, int iwl_, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( a.type_params(), wl_, iwl_ ), \
+ SC_TC_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix_fast::sc_fix_fast( tp a, \
+ sc_q_mode qm, sc_o_mode om, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( a.type_params(), qm, om ), \
+ SC_TC_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix_fast::sc_fix_fast( tp a, \
+ sc_q_mode qm, sc_o_mode om, int nb, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( a.type_params(), qm, om, nb ), \
+ SC_TC_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix_fast::sc_fix_fast( tp a, \
+ int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om ), \
+ SC_TC_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix_fast::sc_fix_fast( tp a, \
+ int wl_, int iwl_, \
+ sc_q_mode qm, sc_o_mode om, int nb, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om, nb ), \
+ SC_TC_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix_fast::sc_fix_fast( tp a, \
+ const sc_fxtype_params& type_params, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ type_params, \
+ SC_TC_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_fix_fast::sc_fix_fast( tp a, \
+ const sc_fxtype_params& type_params, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ type_params, \
+ SC_TC_, \
+ cast_sw, \
+ observer_ ) \
+{}
+
+DEFN_CTORS_T_A(int)
+DEFN_CTORS_T_A(unsigned int)
+DEFN_CTORS_T_A(long)
+DEFN_CTORS_T_A(unsigned long)
+DEFN_CTORS_T_A(float)
+DEFN_CTORS_T_A(double)
+DEFN_CTORS_T_A(const char*)
+DEFN_CTORS_T_A(const sc_fxval&)
+DEFN_CTORS_T_A(const sc_fxval_fast&)
+DEFN_CTORS_T_B(const sc_fxnum&)
+DEFN_CTORS_T_B(const sc_fxnum_fast&)
+#ifndef SC_FX_EXCLUDE_OTHER
+DEFN_CTORS_T_A(int64)
+DEFN_CTORS_T_A(uint64)
+DEFN_CTORS_T_A(const sc_int_base&)
+DEFN_CTORS_T_A(const sc_uint_base&)
+DEFN_CTORS_T_A(const sc_signed&)
+DEFN_CTORS_T_A(const sc_unsigned&)
+#endif
+
+#undef DEFN_CTORS_T_A
+#undef DEFN_CTORS_T_B
+
+// copy constructor
+
+inline
+sc_fix_fast::sc_fix_fast( const sc_fix_fast& a )
+: sc_fxnum_fast( a,
+ a.type_params(),
+ SC_TC_,
+ sc_fxcast_switch(),
+ 0 )
+{}
+
+
+// unary bitwise operators
+
+inline
+const sc_fix_fast
+sc_fix_fast::operator ~ () const
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( *this )
+ int iwl_c = iwl();
+ int wl_c = wl();
+ sc_fix_fast c( wl_c, iwl_c );
+ for( int i = iwl_c - wl_c; i < iwl_c; ++ i )
+ c.set_bit( i, ! get_bit( i ) );
+ return sc_fix_fast( c, wl_c, iwl_c );
+}
+
+
+// unary bitwise functions
+
+inline
+void
+b_not( sc_fix_fast& c, const sc_fix_fast& a )
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( a )
+ int iwl_c = c.iwl();
+ for( int i = iwl_c - c.wl(); i < iwl_c; ++ i )
+ c.set_bit( i, ! a.get_bit( i ) );
+ c.cast();
+ SC_FXNUM_FAST_OBSERVER_WRITE_( c )
+}
+
+
+// binary bitwise operators
+
+#define DEFN_BIN_OP_T(op,op2,tp1,tp2) \
+inline \
+const sc_fix_fast \
+operator op ( const tp1& a, const tp2& b ) \
+{ \
+ a.observer_read(); \
+ b.observer_read(); \
+ int iwl_a = a.iwl(); \
+ int iwl_b = b.iwl(); \
+ int iwl_c = sc_max( iwl_a, iwl_b ); \
+ int fwl_c = sc_max( a.wl() - iwl_a, b.wl() - iwl_b ); \
+ sc_fix_fast c( iwl_c + fwl_c, iwl_c ); \
+ for( int i = -fwl_c; i < iwl_c; ++ i ) \
+ c.set_bit( i, a.get_bit( i ) op2 b.get_bit( i ) ); \
+ return sc_fix_fast( c, iwl_c + fwl_c, iwl_c ); \
+}
+
+DEFN_BIN_OP_T(&,&&,sc_fix_fast,sc_fix_fast)
+DEFN_BIN_OP_T(|,||,sc_fix_fast,sc_fix_fast)
+DEFN_BIN_OP_T(^,!=,sc_fix_fast,sc_fix_fast)
+
+#undef DEFN_BIN_OP_T
+
+
+// binary bitwise functions
+
+#define DEFN_BIN_FNC_T(fnc,op2,tp1,tp2) \
+inline \
+void \
+fnc ( sc_fix_fast& c, const tp1& a, const tp2& b ) \
+{ \
+ a.observer_read(); \
+ b.observer_read(); \
+ int iwl_c = c.iwl(); \
+ for( int i = iwl_c - c.wl(); i < iwl_c; ++ i ) \
+ c.set_bit( i, a.get_bit( i ) op2 b.get_bit( i ) ); \
+ c.cast(); \
+ SC_FXNUM_FAST_OBSERVER_WRITE_( c ) \
+}
+
+DEFN_BIN_FNC_T(b_and,&&,sc_fix_fast,sc_fix_fast)
+DEFN_BIN_FNC_T(b_or,||,sc_fix_fast,sc_fix_fast)
+DEFN_BIN_FNC_T(b_xor,!=,sc_fix_fast,sc_fix_fast)
+
+#undef DEFN_BIN_FNC_T
+
+
+// assignment operators
+
+inline
+sc_fix_fast&
+sc_fix_fast::operator = ( const sc_fix_fast& a )
+{
+ sc_fxnum_fast::operator = ( a );
+ return *this;
+}
+
+#define DEFN_ASN_OP_T(op,tp) \
+inline \
+sc_fix_fast& \
+sc_fix_fast::operator op ( tp a ) \
+{ \
+ sc_fxnum_fast::operator op( a ); \
+ return *this; \
+}
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DEFN_ASN_OP_OTHER(op) \
+DEFN_ASN_OP_T(op,int64) \
+DEFN_ASN_OP_T(op,uint64) \
+DEFN_ASN_OP_T(op,const sc_int_base&) \
+DEFN_ASN_OP_T(op,const sc_uint_base&) \
+DEFN_ASN_OP_T(op,const sc_signed&) \
+DEFN_ASN_OP_T(op,const sc_unsigned&)
+#else
+#define DEFN_ASN_OP_OTHER(op)
+#endif
+
+#define DEFN_ASN_OP(op) \
+DEFN_ASN_OP_T(op,int) \
+DEFN_ASN_OP_T(op,unsigned int) \
+DEFN_ASN_OP_T(op,long) \
+DEFN_ASN_OP_T(op,unsigned long) \
+DEFN_ASN_OP_T(op,float) \
+DEFN_ASN_OP_T(op,double) \
+DEFN_ASN_OP_T(op,const char*) \
+DEFN_ASN_OP_T(op,const sc_fxval&) \
+DEFN_ASN_OP_T(op,const sc_fxval_fast&) \
+DEFN_ASN_OP_T(op,const sc_fxnum&) \
+DEFN_ASN_OP_T(op,const sc_fxnum_fast&) \
+DEFN_ASN_OP_OTHER(op)
+
+DEFN_ASN_OP(=)
+
+DEFN_ASN_OP(*=)
+DEFN_ASN_OP(/=)
+DEFN_ASN_OP(+=)
+DEFN_ASN_OP(-=)
+
+DEFN_ASN_OP_T(<<=,int)
+DEFN_ASN_OP_T(>>=,int)
+
+#undef DEFN_ASN_OP_T
+#undef DEFN_ASN_OP_OTHER
+#undef DEFN_ASN_OP
+
+
+#define DEFN_ASN_OP_T(op,op2,tp) \
+inline \
+sc_fix_fast& \
+sc_fix_fast::operator op ( const tp& b ) \
+{ \
+ SC_FXNUM_FAST_OBSERVER_READ_( *this ) \
+ b.observer_read(); \
+ int iwl_c = iwl(); \
+ for( int i = iwl_c - wl(); i < iwl_c; ++ i ) \
+ set_bit( i, get_bit( i ) op2 b.get_bit( i ) ); \
+ cast(); \
+ SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) \
+ return *this; \
+}
+
+DEFN_ASN_OP_T(&=,&&,sc_fix)
+DEFN_ASN_OP_T(&=,&&,sc_fix_fast)
+DEFN_ASN_OP_T(|=,||,sc_fix)
+DEFN_ASN_OP_T(|=,||,sc_fix_fast)
+DEFN_ASN_OP_T(^=,!=,sc_fix)
+DEFN_ASN_OP_T(^=,!=,sc_fix_fast)
+
+#undef DEFN_ASN_OP_T
+
+
+// auto-increment and auto-decrement
+
+inline
+const sc_fxval_fast
+sc_fix_fast::operator ++ ( int )
+{
+ return sc_fxval_fast( sc_fxnum_fast::operator ++ ( 0 ) );
+}
+
+inline
+const sc_fxval_fast
+sc_fix_fast::operator -- ( int )
+{
+ return sc_fxval_fast( sc_fxnum_fast::operator -- ( 0 ) );
+}
+
+inline
+sc_fix_fast&
+sc_fix_fast::operator ++ ()
+{
+ sc_fxnum_fast::operator ++ ();
+ return *this;
+}
+
+inline
+sc_fix_fast&
+sc_fix_fast::operator -- ()
+{
+ sc_fxnum_fast::operator -- ();
+ return *this;
+}
+
+} // namespace sc_dt
+
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fixed.h b/ext/systemc/src/sysc/datatypes/fx/sc_fixed.h
new file mode 100644
index 000000000..b885da1f9
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/sc_fixed.h
@@ -0,0 +1,660 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_fixed.h -
+
+ Original Author: Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_fixed.h,v $
+// Revision 1.2 2011/01/19 18:57:40 acg
+// Andy Goodrich: changes for IEEE_1666_2011.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:57 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#ifndef SC_FIXED_H
+#define SC_FIXED_H
+
+
+#include "sysc/datatypes/fx/sc_fix.h"
+
+
+namespace sc_dt
+{
+
+// classes defined in this module
+template <int W, int I, sc_q_mode Q, sc_o_mode O, int N> class sc_fixed;
+template <int W, int I, sc_q_mode Q, sc_o_mode O, int N> class sc_fixed_fast;
+
+
+// ----------------------------------------------------------------------------
+// TEMPLATE CLASS : sc_fixed
+//
+// "Constrained" signed fixed-point class; arbitrary precision.
+// ----------------------------------------------------------------------------
+
+template <int W, int I,
+ sc_q_mode Q = SC_DEFAULT_Q_MODE_,
+ sc_o_mode O = SC_DEFAULT_O_MODE_, int N = SC_DEFAULT_N_BITS_>
+class sc_fixed : public sc_fix
+{
+
+public:
+
+ // constructors
+
+ explicit sc_fixed( sc_fxnum_observer* = 0 );
+ explicit sc_fixed( const sc_fxcast_switch&, sc_fxnum_observer* = 0 );
+
+#define DECL_CTORS_T_A(tp) \
+ sc_fixed( tp, sc_fxnum_observer* = 0 ); \
+ sc_fixed( tp, const sc_fxcast_switch&, sc_fxnum_observer* = 0 );
+
+#define DECL_CTORS_T_B(tp) \
+ explicit sc_fixed( tp, sc_fxnum_observer* = 0 ); \
+ sc_fixed( tp, const sc_fxcast_switch&, sc_fxnum_observer* = 0 );
+
+ DECL_CTORS_T_A(int)
+ DECL_CTORS_T_A(unsigned int)
+ DECL_CTORS_T_A(long)
+ DECL_CTORS_T_A(unsigned long)
+ DECL_CTORS_T_A(float)
+ DECL_CTORS_T_A(double)
+ DECL_CTORS_T_A(const char*)
+ DECL_CTORS_T_A(const sc_fxval&)
+ DECL_CTORS_T_A(const sc_fxval_fast&)
+ DECL_CTORS_T_A(const sc_fxnum&)
+ DECL_CTORS_T_A(const sc_fxnum_fast&)
+#ifndef SC_FX_EXCLUDE_OTHER
+ DECL_CTORS_T_B(int64)
+ DECL_CTORS_T_B(uint64)
+ DECL_CTORS_T_B(const sc_int_base&)
+ DECL_CTORS_T_B(const sc_uint_base&)
+ DECL_CTORS_T_B(const sc_signed&)
+ DECL_CTORS_T_B(const sc_unsigned&)
+#endif
+
+#undef DECL_CTORS_T_A
+#undef DECL_CTORS_T_B
+
+ // copy constructor
+
+ sc_fixed( const sc_fixed<W,I,Q,O,N>& );
+
+
+ // assignment operators
+
+ sc_fixed& operator = ( const sc_fixed<W,I,Q,O,N>& );
+
+#define DECL_ASN_OP_T(op,tp) \
+ sc_fixed& operator op ( tp );
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DECL_ASN_OP_OTHER(op) \
+ DECL_ASN_OP_T(op,int64) \
+ DECL_ASN_OP_T(op,uint64) \
+ DECL_ASN_OP_T(op,const sc_int_base&) \
+ DECL_ASN_OP_T(op,const sc_uint_base&) \
+ DECL_ASN_OP_T(op,const sc_signed&) \
+ DECL_ASN_OP_T(op,const sc_unsigned&)
+#else
+#define DECL_ASN_OP_OTHER(op)
+#endif
+
+#define DECL_ASN_OP(op) \
+ DECL_ASN_OP_T(op,int) \
+ DECL_ASN_OP_T(op,unsigned int) \
+ DECL_ASN_OP_T(op,long) \
+ DECL_ASN_OP_T(op,unsigned long) \
+ DECL_ASN_OP_T(op,float) \
+ DECL_ASN_OP_T(op,double) \
+ DECL_ASN_OP_T(op,const char*) \
+ DECL_ASN_OP_T(op,const sc_fxval&) \
+ DECL_ASN_OP_T(op,const sc_fxval_fast&) \
+ DECL_ASN_OP_T(op,const sc_fxnum&) \
+ DECL_ASN_OP_T(op,const sc_fxnum_fast&) \
+ DECL_ASN_OP_OTHER(op)
+
+ DECL_ASN_OP(=)
+
+ DECL_ASN_OP(*=)
+ DECL_ASN_OP(/=)
+ DECL_ASN_OP(+=)
+ DECL_ASN_OP(-=)
+
+ DECL_ASN_OP_T(<<=,int)
+ DECL_ASN_OP_T(>>=,int)
+
+ DECL_ASN_OP_T(&=,const sc_fix&)
+ DECL_ASN_OP_T(&=,const sc_fix_fast&)
+ DECL_ASN_OP_T(|=,const sc_fix&)
+ DECL_ASN_OP_T(|=,const sc_fix_fast&)
+ DECL_ASN_OP_T(^=,const sc_fix&)
+ DECL_ASN_OP_T(^=,const sc_fix_fast&)
+
+#undef DECL_ASN_OP_T
+#undef DECL_ASN_OP_OTHER
+#undef DECL_ASN_OP
+
+
+ // auto-increment and auto-decrement
+
+ const sc_fxval operator ++ ( int );
+ const sc_fxval operator -- ( int );
+
+ sc_fixed& operator ++ ();
+ sc_fixed& operator -- ();
+
+};
+
+
+// ----------------------------------------------------------------------------
+// TEMPLATE CLASS : sc_fixed_fast
+//
+// "Constrained" signed fixed-point class; limited precision.
+// ----------------------------------------------------------------------------
+
+template <int W, int I,
+ sc_q_mode Q = SC_DEFAULT_Q_MODE_,
+ sc_o_mode O = SC_DEFAULT_O_MODE_, int N = SC_DEFAULT_N_BITS_>
+class sc_fixed_fast : public sc_fix_fast
+{
+
+public:
+
+ // constructors
+
+ explicit sc_fixed_fast( sc_fxnum_fast_observer* = 0 );
+ explicit sc_fixed_fast( const sc_fxcast_switch&,
+ sc_fxnum_fast_observer* = 0 );
+
+#define DECL_CTORS_T_A(tp) \
+ sc_fixed_fast( tp, sc_fxnum_fast_observer* = 0 ); \
+ sc_fixed_fast( tp, const sc_fxcast_switch&, \
+ sc_fxnum_fast_observer* = 0 );
+
+#define DECL_CTORS_T_B(tp) \
+ explicit sc_fixed_fast( tp, sc_fxnum_fast_observer* = 0 ); \
+ sc_fixed_fast( tp, const sc_fxcast_switch&, \
+ sc_fxnum_fast_observer* = 0 );
+
+ DECL_CTORS_T_A(int)
+ DECL_CTORS_T_A(unsigned int)
+ DECL_CTORS_T_A(long)
+ DECL_CTORS_T_A(unsigned long)
+ DECL_CTORS_T_A(float)
+ DECL_CTORS_T_A(double)
+ DECL_CTORS_T_A(const char*)
+ DECL_CTORS_T_A(const sc_fxval&)
+ DECL_CTORS_T_A(const sc_fxval_fast&)
+ DECL_CTORS_T_A(const sc_fxnum&)
+ DECL_CTORS_T_A(const sc_fxnum_fast&)
+#ifndef SC_FX_EXCLUDE_OTHER
+ DECL_CTORS_T_B(int64)
+ DECL_CTORS_T_B(uint64)
+ DECL_CTORS_T_B(const sc_int_base&)
+ DECL_CTORS_T_B(const sc_uint_base&)
+ DECL_CTORS_T_B(const sc_signed&)
+ DECL_CTORS_T_B(const sc_unsigned&)
+#endif
+
+#undef DECL_CTORS_T_A
+#undef DECL_CTORS_T_B
+
+ // copy constructor
+
+ sc_fixed_fast( const sc_fixed_fast<W,I,Q,O,N>& );
+
+
+ // assignment operators
+
+ sc_fixed_fast& operator = ( const sc_fixed_fast<W,I,Q,O,N>& );
+
+#define DECL_ASN_OP_T(op,tp) \
+ sc_fixed_fast& operator op ( tp );
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DECL_ASN_OP_OTHER(op) \
+ DECL_ASN_OP_T(op,int64) \
+ DECL_ASN_OP_T(op,uint64) \
+ DECL_ASN_OP_T(op,const sc_int_base&) \
+ DECL_ASN_OP_T(op,const sc_uint_base&) \
+ DECL_ASN_OP_T(op,const sc_signed&) \
+ DECL_ASN_OP_T(op,const sc_unsigned&)
+#else
+#define DECL_ASN_OP_OTHER(op)
+#endif
+
+#define DECL_ASN_OP(op) \
+ DECL_ASN_OP_T(op,int) \
+ DECL_ASN_OP_T(op,unsigned int) \
+ DECL_ASN_OP_T(op,long) \
+ DECL_ASN_OP_T(op,unsigned long) \
+ DECL_ASN_OP_T(op,float) \
+ DECL_ASN_OP_T(op,double) \
+ DECL_ASN_OP_T(op,const char*) \
+ DECL_ASN_OP_T(op,const sc_fxval&) \
+ DECL_ASN_OP_T(op,const sc_fxval_fast&) \
+ DECL_ASN_OP_T(op,const sc_fxnum&) \
+ DECL_ASN_OP_T(op,const sc_fxnum_fast&) \
+ DECL_ASN_OP_OTHER(op)
+
+ DECL_ASN_OP(=)
+
+ DECL_ASN_OP(*=)
+ DECL_ASN_OP(/=)
+ DECL_ASN_OP(+=)
+ DECL_ASN_OP(-=)
+
+ DECL_ASN_OP_T(<<=,int)
+ DECL_ASN_OP_T(>>=,int)
+
+ DECL_ASN_OP_T(&=,const sc_fix&)
+ DECL_ASN_OP_T(&=,const sc_fix_fast&)
+ DECL_ASN_OP_T(|=,const sc_fix&)
+ DECL_ASN_OP_T(|=,const sc_fix_fast&)
+ DECL_ASN_OP_T(^=,const sc_fix&)
+ DECL_ASN_OP_T(^=,const sc_fix_fast&)
+
+#undef DECL_ASN_OP_T
+#undef DECL_ASN_OP_OTHER
+#undef DECL_ASN_OP
+
+
+ // auto-increment and auto-decrement
+
+ const sc_fxval_fast operator ++ ( int );
+ const sc_fxval_fast operator -- ( int );
+
+ sc_fixed_fast& operator ++ ();
+ sc_fixed_fast& operator -- ();
+
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+// ----------------------------------------------------------------------------
+// TEMPLATE CLASS : sc_fixed
+//
+// "Constrained" signed fixed-point class; arbitrary precision.
+// ----------------------------------------------------------------------------
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+sc_fixed<W,I,Q,O,N>::sc_fixed( sc_fxnum_observer* observer_ )
+: sc_fix( W, I, Q, O, N, observer_ )
+{}
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+sc_fixed<W,I,Q,O,N>::sc_fixed( const sc_fxcast_switch& cast_sw,
+ sc_fxnum_observer* observer_ )
+: sc_fix( W, I, Q, O, N, cast_sw, observer_ )
+{}
+
+#define DEFN_CTORS_T(tp) \
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \
+inline \
+sc_fixed<W,I,Q,O,N>::sc_fixed( tp a, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fix( a, W, I, Q, O, N, observer_ ) \
+{} \
+ \
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \
+inline \
+sc_fixed<W,I,Q,O,N>::sc_fixed( tp a, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fix( a, W, I, Q, O, N, cast_sw, observer_ ) \
+{}
+
+DEFN_CTORS_T(int)
+DEFN_CTORS_T(unsigned int)
+DEFN_CTORS_T(long)
+DEFN_CTORS_T(unsigned long)
+DEFN_CTORS_T(float)
+DEFN_CTORS_T(double)
+DEFN_CTORS_T(const char*)
+DEFN_CTORS_T(const sc_fxval&)
+DEFN_CTORS_T(const sc_fxval_fast&)
+DEFN_CTORS_T(const sc_fxnum&)
+DEFN_CTORS_T(const sc_fxnum_fast&)
+#ifndef SC_FX_EXCLUDE_OTHER
+DEFN_CTORS_T(int64)
+DEFN_CTORS_T(uint64)
+DEFN_CTORS_T(const sc_int_base&)
+DEFN_CTORS_T(const sc_uint_base&)
+DEFN_CTORS_T(const sc_signed&)
+DEFN_CTORS_T(const sc_unsigned&)
+#endif
+
+#undef DEFN_CTORS_T
+
+// copy constructor
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+sc_fixed<W,I,Q,O,N>::sc_fixed( const sc_fixed<W,I,Q,O,N>& a )
+: sc_fix( a, W, I, Q, O, N )
+{}
+
+
+// assignment operators
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+sc_fixed<W,I,Q,O,N>&
+sc_fixed<W,I,Q,O,N>::operator = ( const sc_fixed<W,I,Q,O,N>& a )
+{
+ sc_fix::operator = ( a );
+ return *this;
+}
+
+#define DEFN_ASN_OP_T(op,tp) \
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \
+inline \
+sc_fixed<W,I,Q,O,N>& \
+sc_fixed<W,I,Q,O,N>::operator op ( tp a ) \
+{ \
+ sc_fix::operator op ( a ); \
+ return *this; \
+}
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DEFN_ASN_OP_OTHER(op) \
+DEFN_ASN_OP_T(op,int64) \
+DEFN_ASN_OP_T(op,uint64) \
+DEFN_ASN_OP_T(op,const sc_int_base&) \
+DEFN_ASN_OP_T(op,const sc_uint_base&) \
+DEFN_ASN_OP_T(op,const sc_signed&) \
+DEFN_ASN_OP_T(op,const sc_unsigned&)
+#else
+#define DEFN_ASN_OP_OTHER(op)
+#endif
+
+#define DEFN_ASN_OP(op) \
+DEFN_ASN_OP_T(op,int) \
+DEFN_ASN_OP_T(op,unsigned int) \
+DEFN_ASN_OP_T(op,long) \
+DEFN_ASN_OP_T(op,unsigned long) \
+DEFN_ASN_OP_T(op,float) \
+DEFN_ASN_OP_T(op,double) \
+DEFN_ASN_OP_T(op,const char*) \
+DEFN_ASN_OP_T(op,const sc_fxval&) \
+DEFN_ASN_OP_T(op,const sc_fxval_fast&) \
+DEFN_ASN_OP_T(op,const sc_fxnum&) \
+DEFN_ASN_OP_T(op,const sc_fxnum_fast&) \
+DEFN_ASN_OP_OTHER(op)
+
+DEFN_ASN_OP(=)
+
+DEFN_ASN_OP(*=)
+DEFN_ASN_OP(/=)
+DEFN_ASN_OP(+=)
+DEFN_ASN_OP(-=)
+
+DEFN_ASN_OP_T(<<=,int)
+DEFN_ASN_OP_T(>>=,int)
+
+DEFN_ASN_OP_T(&=,const sc_fix&)
+DEFN_ASN_OP_T(&=,const sc_fix_fast&)
+DEFN_ASN_OP_T(|=,const sc_fix&)
+DEFN_ASN_OP_T(|=,const sc_fix_fast&)
+DEFN_ASN_OP_T(^=,const sc_fix&)
+DEFN_ASN_OP_T(^=,const sc_fix_fast&)
+
+#undef DEFN_ASN_OP_T
+#undef DEFN_ASN_OP_OTHER
+#undef DEFN_ASN_OP
+
+
+// auto-increment and auto-decrement
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+const sc_fxval
+sc_fixed<W,I,Q,O,N>::operator ++ ( int )
+{
+ return sc_fxval( sc_fix::operator ++ ( 0 ) );
+}
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+const sc_fxval
+sc_fixed<W,I,Q,O,N>::operator -- ( int )
+{
+ return sc_fxval( sc_fix::operator -- ( 0 ) );
+}
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+sc_fixed<W,I,Q,O,N>&
+sc_fixed<W,I,Q,O,N>::operator ++ ()
+{
+ sc_fix::operator ++ ();
+ return *this;
+}
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+sc_fixed<W,I,Q,O,N>&
+sc_fixed<W,I,Q,O,N>::operator -- ()
+{
+ sc_fix::operator -- ();
+ return *this;
+}
+
+
+// ----------------------------------------------------------------------------
+// TEMPLATE CLASS : sc_fixed_fast
+//
+// "Constrained" signed fixed-point class; limited precision.
+// ----------------------------------------------------------------------------
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+sc_fixed_fast<W,I,Q,O,N>::sc_fixed_fast( sc_fxnum_fast_observer* observer_ )
+: sc_fix_fast( W, I, Q, O, N, observer_ )
+{}
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+sc_fixed_fast<W,I,Q,O,N>::sc_fixed_fast( const sc_fxcast_switch& cast_sw,
+ sc_fxnum_fast_observer* observer_ )
+: sc_fix_fast( W, I, Q, O, N, cast_sw, observer_ )
+{}
+
+#define DEFN_CTORS_T(tp) \
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \
+inline \
+sc_fixed_fast<W,I,Q,O,N>::sc_fixed_fast( tp a, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fix_fast( a, W, I, Q, O, N, observer_ ) \
+{} \
+ \
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \
+inline \
+sc_fixed_fast<W,I,Q,O,N>::sc_fixed_fast( tp a, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fix_fast( a, W, I, Q, O, N, cast_sw, observer_ ) \
+{}
+
+DEFN_CTORS_T(int)
+DEFN_CTORS_T(unsigned int)
+DEFN_CTORS_T(long)
+DEFN_CTORS_T(unsigned long)
+DEFN_CTORS_T(float)
+DEFN_CTORS_T(double)
+DEFN_CTORS_T(const char*)
+DEFN_CTORS_T(const sc_fxval&)
+DEFN_CTORS_T(const sc_fxval_fast&)
+DEFN_CTORS_T(const sc_fxnum&)
+DEFN_CTORS_T(const sc_fxnum_fast&)
+#ifndef SC_FX_EXCLUDE_OTHER
+DEFN_CTORS_T(int64)
+DEFN_CTORS_T(uint64)
+DEFN_CTORS_T(const sc_int_base&)
+DEFN_CTORS_T(const sc_uint_base&)
+DEFN_CTORS_T(const sc_signed&)
+DEFN_CTORS_T(const sc_unsigned&)
+#endif
+
+#undef DEFN_CTORS_T
+
+// copy constructor
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+sc_fixed_fast<W,I,Q,O,N>::sc_fixed_fast( const sc_fixed_fast<W,I,Q,O,N>& a )
+: sc_fix_fast( a, W, I, Q, O, N )
+{}
+
+
+// assignment operators
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+sc_fixed_fast<W,I,Q,O,N>&
+sc_fixed_fast<W,I,Q,O,N>::operator = ( const sc_fixed_fast<W,I,Q,O,N>& a )
+{
+ sc_fix_fast::operator = ( a );
+ return *this;
+}
+
+#define DEFN_ASN_OP_T(op,tp) \
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \
+inline \
+sc_fixed_fast<W,I,Q,O,N>& \
+sc_fixed_fast<W,I,Q,O,N>::operator op ( tp a ) \
+{ \
+ sc_fix_fast::operator op ( a ); \
+ return *this; \
+}
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DEFN_ASN_OP_OTHER(op) \
+DEFN_ASN_OP_T(op,int64) \
+DEFN_ASN_OP_T(op,uint64) \
+DEFN_ASN_OP_T(op,const sc_int_base&) \
+DEFN_ASN_OP_T(op,const sc_uint_base&) \
+DEFN_ASN_OP_T(op,const sc_signed&) \
+DEFN_ASN_OP_T(op,const sc_unsigned&)
+#else
+#define DEFN_ASN_OP_OTHER(op)
+#endif
+
+#define DEFN_ASN_OP(op) \
+DEFN_ASN_OP_T(op,int) \
+DEFN_ASN_OP_T(op,unsigned int) \
+DEFN_ASN_OP_T(op,long) \
+DEFN_ASN_OP_T(op,unsigned long) \
+DEFN_ASN_OP_T(op,float) \
+DEFN_ASN_OP_T(op,double) \
+DEFN_ASN_OP_T(op,const char*) \
+DEFN_ASN_OP_T(op,const sc_fxval&) \
+DEFN_ASN_OP_T(op,const sc_fxval_fast&) \
+DEFN_ASN_OP_T(op,const sc_fxnum&) \
+DEFN_ASN_OP_T(op,const sc_fxnum_fast&) \
+DEFN_ASN_OP_OTHER(op)
+
+DEFN_ASN_OP(=)
+
+DEFN_ASN_OP(*=)
+DEFN_ASN_OP(/=)
+DEFN_ASN_OP(+=)
+DEFN_ASN_OP(-=)
+
+DEFN_ASN_OP_T(<<=,int)
+DEFN_ASN_OP_T(>>=,int)
+
+DEFN_ASN_OP_T(&=,const sc_fix&)
+DEFN_ASN_OP_T(&=,const sc_fix_fast&)
+DEFN_ASN_OP_T(|=,const sc_fix&)
+DEFN_ASN_OP_T(|=,const sc_fix_fast&)
+DEFN_ASN_OP_T(^=,const sc_fix&)
+DEFN_ASN_OP_T(^=,const sc_fix_fast&)
+
+#undef DEFN_ASN_OP_T
+#undef DEFN_ASN_OP_OTHER
+#undef DEFN_ASN_OP
+
+
+// auto-increment and auto-decrement
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+const sc_fxval_fast
+sc_fixed_fast<W,I,Q,O,N>::operator ++ ( int )
+{
+ return sc_fxval_fast( sc_fix_fast::operator ++ ( 0 ) );
+}
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+const sc_fxval_fast
+sc_fixed_fast<W,I,Q,O,N>::operator -- ( int )
+{
+ return sc_fxval_fast( sc_fix_fast::operator -- ( 0 ) );
+}
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+sc_fixed_fast<W,I,Q,O,N>&
+sc_fixed_fast<W,I,Q,O,N>::operator ++ ()
+{
+ sc_fix_fast::operator ++ ();
+ return *this;
+}
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+sc_fixed_fast<W,I,Q,O,N>&
+sc_fixed_fast<W,I,Q,O,N>::operator -- ()
+{
+ sc_fix_fast::operator -- ();
+ return *this;
+}
+
+} // namespace sc_dt
+
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fx_ids.h b/ext/systemc/src/sysc/datatypes/fx/sc_fx_ids.h
new file mode 100644
index 000000000..b40c2dc48
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/sc_fx_ids.h
@@ -0,0 +1,96 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_fx_ids.h -- Report ids for the datatypes/fx code.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2002-01-17
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_fx_ids.h,v $
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:57 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#ifndef SC_FX_IDS_H
+#define SC_FX_IDS_H
+
+
+#include "sysc/utils/sc_report.h"
+
+
+// ----------------------------------------------------------------------------
+// Report ids (datatypes/fx)
+//
+// Report ids in the range of 300-399.
+// ----------------------------------------------------------------------------
+
+#ifndef SC_DEFINE_MESSAGE
+#define SC_DEFINE_MESSAGE(id,unused1,unused2) \
+ namespace sc_core { extern const char id[]; }
+namespace sc_core {
+ extern const char SC_ID_REGISTER_ID_FAILED_[]; // in sc_report_handler.cpp
+}
+#endif
+
+
+SC_DEFINE_MESSAGE( SC_ID_INVALID_WL_, 300,
+ "total wordlength <= 0 is not valid" )
+SC_DEFINE_MESSAGE( SC_ID_INVALID_N_BITS_, 301,
+ "number of bits < 0 is not valid" )
+SC_DEFINE_MESSAGE( SC_ID_INVALID_DIV_WL_, 302,
+ "division wordlength <= 0 is not valid" )
+SC_DEFINE_MESSAGE( SC_ID_INVALID_CTE_WL_, 303,
+ "constant wordlength <= 0 is not valid" )
+SC_DEFINE_MESSAGE( SC_ID_INVALID_MAX_WL_, 304,
+ "maximum wordlength <= 0 and != -1 is not valid" )
+SC_DEFINE_MESSAGE( SC_ID_INVALID_FX_VALUE_, 305,
+ "invalid fixed-point value" )
+SC_DEFINE_MESSAGE( SC_ID_INVALID_O_MODE_, 306,
+ "invalid overflow mode" )
+SC_DEFINE_MESSAGE( SC_ID_OUT_OF_RANGE_, 307,
+ "index out of range" )
+SC_DEFINE_MESSAGE( SC_ID_CONTEXT_BEGIN_FAILED_, 308,
+ "context begin failed" )
+SC_DEFINE_MESSAGE( SC_ID_CONTEXT_END_FAILED_, 309,
+ "context end failed" )
+SC_DEFINE_MESSAGE( SC_ID_WRAP_SM_NOT_DEFINED_, 310,
+ "SC_WRAP_SM not defined for unsigned numbers" )
+
+
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxcast_switch.cpp b/ext/systemc/src/sysc/datatypes/fx/sc_fxcast_switch.cpp
new file mode 100644
index 000000000..c5c5a939c
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxcast_switch.cpp
@@ -0,0 +1,88 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_fxcast_switch.cpp -
+
+ Original Author: Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Gene Bushuyev, Synopsys, Inc.
+ Description of Modification: - fix explicit instantiation syntax.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// $Log: sc_fxcast_switch.cpp,v $
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:57 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#include "sysc/datatypes/fx/sc_fxcast_switch.h"
+
+
+namespace sc_dt
+{
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxcast_switch
+//
+// Fixed-point cast switch class.
+// ----------------------------------------------------------------------------
+
+const std::string
+sc_fxcast_switch::to_string() const
+{
+ return sc_dt::to_string( m_sw );
+}
+
+
+void
+sc_fxcast_switch::print( ::std::ostream& os ) const
+{
+ os << sc_dt::to_string( m_sw );
+}
+
+void
+sc_fxcast_switch::dump( ::std::ostream& os ) const
+{
+ os << "sc_fxcast_switch" << ::std::endl;
+ os << "(" << ::std::endl;
+ os << "sw = " << sc_dt::to_string( m_sw ) << ::std::endl;
+ os << ")" << ::std::endl;
+}
+
+} // namespace sc_dt
+
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxcast_switch.h b/ext/systemc/src/sysc/datatypes/fx/sc_fxcast_switch.h
new file mode 100644
index 000000000..6bfbd25a4
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxcast_switch.h
@@ -0,0 +1,174 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_fxcast_switch.h -
+
+ Original Author: Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_fxcast_switch.h,v $
+// Revision 1.2 2011/08/24 22:05:43 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:57 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#ifndef SC_FXCAST_SWITCH_H
+#define SC_FXCAST_SWITCH_H
+
+
+#include "sysc/datatypes/fx/sc_context.h"
+
+
+namespace sc_dt
+{
+
+// classes defined in this module
+class sc_fxcast_switch;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxcast_switch
+//
+// Fixed-point cast switch class.
+// ----------------------------------------------------------------------------
+
+class sc_fxcast_switch
+{
+
+public:
+
+ sc_fxcast_switch();
+ sc_fxcast_switch( sc_switch );
+ sc_fxcast_switch( const sc_fxcast_switch& );
+ explicit sc_fxcast_switch( sc_without_context );
+
+ sc_fxcast_switch& operator = ( const sc_fxcast_switch& );
+
+ friend bool operator == ( const sc_fxcast_switch&,
+ const sc_fxcast_switch& );
+ friend bool operator != ( const sc_fxcast_switch&,
+ const sc_fxcast_switch& );
+
+ const std::string to_string() const;
+
+ void print( ::std::ostream& = ::std::cout ) const;
+ void dump( ::std::ostream& = ::std::cout ) const;
+
+private:
+
+ sc_switch m_sw;
+
+};
+
+
+// ----------------------------------------------------------------------------
+// TYPEDEF : sc_fxcast_context
+//
+// Context type for the fixed-point cast switch parameter.
+// ----------------------------------------------------------------------------
+
+typedef sc_context<sc_fxcast_switch> sc_fxcast_context;
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+inline
+sc_fxcast_switch::sc_fxcast_switch()
+: m_sw()
+{
+ *this = sc_fxcast_context::default_value();
+}
+
+inline
+sc_fxcast_switch::sc_fxcast_switch( sc_switch sw_ )
+: m_sw( sw_ )
+{}
+
+inline
+sc_fxcast_switch::sc_fxcast_switch( const sc_fxcast_switch& a )
+: m_sw( a.m_sw )
+{}
+
+inline
+sc_fxcast_switch::sc_fxcast_switch( sc_without_context )
+: m_sw( SC_DEFAULT_CAST_SWITCH_ )
+{}
+
+
+inline
+sc_fxcast_switch&
+sc_fxcast_switch::operator = ( const sc_fxcast_switch& a )
+{
+ if( &a != this )
+ {
+ m_sw = a.m_sw;
+ }
+ return *this;
+}
+
+
+inline
+bool
+operator == ( const sc_fxcast_switch& a, const sc_fxcast_switch& b )
+{
+ return ( a.m_sw == b.m_sw );
+}
+
+
+inline
+bool
+operator != ( const sc_fxcast_switch& a, const sc_fxcast_switch& b )
+{
+ return ( a.m_sw != b.m_sw );
+}
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, const sc_fxcast_switch& a )
+{
+ a.print( os );
+ return os;
+}
+
+} // namespace sc_dt
+
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxdefs.cpp b/ext/systemc/src/sysc/datatypes/fx/sc_fxdefs.cpp
new file mode 100644
index 000000000..66ade2076
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxdefs.cpp
@@ -0,0 +1,175 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_fxdefs.cpp -
+
+ Original Author: Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// $Log: sc_fxdefs.cpp,v $
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:57 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#include "sysc/datatypes/fx/sc_fxdefs.h"
+
+
+namespace sc_dt
+{
+
+// ----------------------------------------------------------------------------
+// ENUM : sc_enc
+//
+// Enumeration of sign encodings.
+// ----------------------------------------------------------------------------
+
+const std::string
+to_string( sc_enc enc )
+{
+ switch( enc )
+ {
+ case SC_TC_:
+ return std::string( "SC_TC_" );
+ case SC_US_:
+ return std::string( "SC_US_" );
+ default:
+ return std::string( "unknown" );
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// ENUM : sc_q_mode
+//
+// Enumeration of quantization modes.
+// ----------------------------------------------------------------------------
+
+const std::string
+to_string( sc_q_mode q_mode )
+{
+ switch( q_mode )
+ {
+ case SC_RND:
+ return std::string( "SC_RND" );
+ case SC_RND_ZERO:
+ return std::string( "SC_RND_ZERO" );
+ case SC_RND_MIN_INF:
+ return std::string( "SC_RND_MIN_INF" );
+ case SC_RND_INF:
+ return std::string( "SC_RND_INF" );
+ case SC_RND_CONV:
+ return std::string( "SC_RND_CONV" );
+ case SC_TRN:
+ return std::string( "SC_TRN" );
+ case SC_TRN_ZERO:
+ return std::string( "SC_TRN_ZERO" );
+ default:
+ return std::string( "unknown" );
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// ENUM : sc_o_mode
+//
+// Enumeration of overflow modes.
+// ----------------------------------------------------------------------------
+
+const std::string
+to_string( sc_o_mode o_mode )
+{
+ switch( o_mode )
+ {
+ case SC_SAT:
+ return std::string( "SC_SAT" );
+ case SC_SAT_ZERO:
+ return std::string( "SC_SAT_ZERO" );
+ case SC_SAT_SYM:
+ return std::string( "SC_SAT_SYM" );
+ case SC_WRAP:
+ return std::string( "SC_WRAP" );
+ case SC_WRAP_SM:
+ return std::string( "SC_WRAP_SM" );
+ default:
+ return std::string( "unknown" );
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// ENUM : sc_switch
+//
+// Enumeration of switch states.
+// ----------------------------------------------------------------------------
+
+const std::string
+to_string( sc_switch sw )
+{
+ switch( sw ) {
+ case SC_OFF:
+ return std::string( "SC_OFF" );
+ case SC_ON:
+ return std::string( "SC_ON" );
+ default:
+ return std::string( "unknown" );
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// ENUM : sc_fmt
+//
+// Enumeration of formats for character string conversion.
+// ----------------------------------------------------------------------------
+
+const std::string
+to_string( sc_fmt fmt )
+{
+ switch( fmt ) {
+ case SC_F:
+ return std::string( "SC_F" );
+ case SC_E:
+ return std::string( "SC_E" );
+ default:
+ return std::string( "unknown" );
+ }
+}
+
+} // namespace sc_dt
+
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxdefs.h b/ext/systemc/src/sysc/datatypes/fx/sc_fxdefs.h
new file mode 100644
index 000000000..1ac1bb707
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxdefs.h
@@ -0,0 +1,308 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_fxdefs.h -
+
+ Original Author: Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_fxdefs.h,v $
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:57 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#ifndef SC_FXDEFS_H
+#define SC_FXDEFS_H
+
+
+#include "sysc/utils/sc_machine.h"
+#include "sysc/datatypes/fx/sc_fx_ids.h"
+#include "sysc/datatypes/int/sc_nbutils.h"
+
+
+namespace sc_dt
+{
+
+// ----------------------------------------------------------------------------
+// ENUM : sc_enc
+//
+// Enumeration of sign encodings.
+// ----------------------------------------------------------------------------
+
+enum sc_enc
+{
+ SC_TC_, // two's complement
+ SC_US_ // unsigned
+};
+
+
+const std::string to_string( sc_enc );
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, sc_enc enc )
+{
+ return os << to_string( enc );
+}
+
+
+// ----------------------------------------------------------------------------
+// ENUM : sc_q_mode
+//
+// Enumeration of quantization modes.
+// ----------------------------------------------------------------------------
+
+enum sc_q_mode
+{
+ SC_RND, // rounding to plus infinity
+ SC_RND_ZERO, // rounding to zero
+ SC_RND_MIN_INF, // rounding to minus infinity
+ SC_RND_INF, // rounding to infinity
+ SC_RND_CONV, // convergent rounding
+ SC_TRN, // truncation
+ SC_TRN_ZERO // truncation to zero
+};
+
+
+const std::string to_string( sc_q_mode );
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, sc_q_mode q_mode )
+{
+ return os << to_string( q_mode );
+}
+
+
+// ----------------------------------------------------------------------------
+// ENUM : sc_o_mode
+//
+// Enumeration of overflow modes.
+// ----------------------------------------------------------------------------
+
+enum sc_o_mode
+{
+ SC_SAT, // saturation
+ SC_SAT_ZERO, // saturation to zero
+ SC_SAT_SYM, // symmetrical saturation
+ SC_WRAP, // wrap-around (*)
+ SC_WRAP_SM // sign magnitude wrap-around (*)
+};
+
+// (*) uses the number of saturated bits argument, see the documentation.
+
+
+const std::string to_string( sc_o_mode );
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, sc_o_mode o_mode )
+{
+ return os << to_string( o_mode );
+}
+
+
+// ----------------------------------------------------------------------------
+// ENUM : sc_switch
+//
+// Enumeration of switch states.
+// ----------------------------------------------------------------------------
+
+enum sc_switch
+{
+ SC_OFF,
+ SC_ON
+};
+
+
+const std::string to_string( sc_switch );
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, sc_switch sw )
+{
+ return os << to_string( sw );
+}
+
+
+// ----------------------------------------------------------------------------
+// ENUM : sc_fmt
+//
+// Enumeration of formats for character string conversion.
+// ----------------------------------------------------------------------------
+
+enum sc_fmt
+{
+ SC_F, // fixed
+ SC_E // scientific
+};
+
+
+const std::string to_string( sc_fmt );
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, sc_fmt fmt )
+{
+ return os << to_string( fmt );
+}
+
+
+// ----------------------------------------------------------------------------
+// Built-in & default fixed-point type parameter values.
+// ----------------------------------------------------------------------------
+
+const int SC_BUILTIN_WL_ = 32;
+const int SC_BUILTIN_IWL_ = 32;
+const sc_q_mode SC_BUILTIN_Q_MODE_ = SC_TRN;
+const sc_o_mode SC_BUILTIN_O_MODE_ = SC_WRAP;
+const int SC_BUILTIN_N_BITS_ = 0;
+
+
+const int SC_DEFAULT_WL_ = SC_BUILTIN_WL_;
+const int SC_DEFAULT_IWL_ = SC_BUILTIN_IWL_;
+const sc_q_mode SC_DEFAULT_Q_MODE_ = SC_BUILTIN_Q_MODE_;
+const sc_o_mode SC_DEFAULT_O_MODE_ = SC_BUILTIN_O_MODE_;
+const int SC_DEFAULT_N_BITS_ = SC_BUILTIN_N_BITS_;
+
+
+// ----------------------------------------------------------------------------
+// Built-in & default fixed-point cast switch parameter values.
+// ----------------------------------------------------------------------------
+
+const sc_switch SC_BUILTIN_CAST_SWITCH_ = SC_ON;
+
+
+const sc_switch SC_DEFAULT_CAST_SWITCH_ = SC_BUILTIN_CAST_SWITCH_;
+
+
+// ----------------------------------------------------------------------------
+// Built-in & default fixed-point value type parameter values.
+// ----------------------------------------------------------------------------
+
+const int SC_BUILTIN_DIV_WL_ = 64;
+const int SC_BUILTIN_CTE_WL_ = 64;
+const int SC_BUILTIN_MAX_WL_ = 1024;
+
+
+#if defined( SC_FXDIV_WL ) && ( SC_FXDIV_WL > 0 )
+const int SC_DEFAULT_DIV_WL_ = SC_FXDIV_WL;
+#else
+const int SC_DEFAULT_DIV_WL_ = SC_BUILTIN_DIV_WL_;
+#endif
+
+#if defined( SC_FXCTE_WL ) && ( SC_FXCTE_WL > 0 )
+const int SC_DEFAULT_CTE_WL_ = SC_FXCTE_WL;
+#else
+const int SC_DEFAULT_CTE_WL_ = SC_BUILTIN_CTE_WL_;
+#endif
+
+#if defined( SC_FXMAX_WL ) && ( SC_FXMAX_WL > 0 || SC_FXMAX_WL == -1 )
+const int SC_DEFAULT_MAX_WL_ = SC_FXMAX_WL;
+#else
+const int SC_DEFAULT_MAX_WL_ = SC_BUILTIN_MAX_WL_;
+#endif
+
+
+// ----------------------------------------------------------------------------
+// Dedicated error reporting and checking.
+// ----------------------------------------------------------------------------
+
+#ifdef DEBUG_SYSTEMC
+#define SC_ASSERT_(cnd,msg) \
+{ \
+ if( ! (cnd) ) \
+ SC_REPORT_ERROR( sc_core::SC_ID_INTERNAL_ERROR_, msg ); \
+}
+#else
+#define SC_ASSERT_(cnd,msg)
+#endif
+
+#define SC_ERROR_IF_(cnd,id) \
+{ \
+ if( cnd ) \
+ SC_REPORT_ERROR( id, 0 ); \
+}
+
+
+#define SC_CHECK_WL_(wl) \
+ SC_ERROR_IF_( (wl) <= 0, sc_core::SC_ID_INVALID_WL_ )
+
+#define SC_CHECK_N_BITS_(n_bits) \
+ SC_ERROR_IF_( (n_bits) < 0, sc_core::SC_ID_INVALID_N_BITS_ )
+
+#define SC_CHECK_DIV_WL_(div_wl) \
+ SC_ERROR_IF_( (div_wl) <= 0, sc_core::SC_ID_INVALID_DIV_WL_ )
+
+#define SC_CHECK_CTE_WL_(cte_wl) \
+ SC_ERROR_IF_( (cte_wl) <= 0, sc_core::SC_ID_INVALID_CTE_WL_ )
+
+#define SC_CHECK_MAX_WL_(max_wl) \
+ SC_ERROR_IF_( (max_wl) <= 0 && (max_wl) != -1, \
+ sc_core::SC_ID_INVALID_MAX_WL_ )
+
+
+// ----------------------------------------------------------------------------
+// Generic observer macros.
+// ----------------------------------------------------------------------------
+
+#define SC_OBSERVER_(object,observer_type,event) \
+{ \
+ if( (object).observer() != 0 ) \
+ { \
+ observer_type observer = (object).lock_observer(); \
+ observer->event( (object) ); \
+ (object).unlock_observer( observer ); \
+ } \
+}
+
+#define SC_OBSERVER_DEFAULT_(observer_type) \
+{ \
+ if( m_observer == 0 && observer_type ## ::default_observer != 0 ) \
+ m_observer = (* ## observer_type ## ::default_observer)(); \
+}
+
+} // namespace sc_dt
+
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxnum.cpp b/ext/systemc/src/sysc/datatypes/fx/sc_fxnum.cpp
new file mode 100644
index 000000000..520c41854
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxnum.cpp
@@ -0,0 +1,958 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_fxnum.cpp -
+
+ Original Author: Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// $Log: sc_fxnum.cpp,v $
+// Revision 1.3 2011/01/19 18:57:40 acg
+// Andy Goodrich: changes for IEEE_1666_2011.
+//
+// Revision 1.2 2010/12/07 20:09:08 acg
+// Andy Goodrich: Philipp Hartmann's constructor disambiguation fix
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:57 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#include <math.h>
+
+#include "sysc/datatypes/fx/sc_fxnum.h"
+
+
+namespace sc_dt
+{
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxnum_bitref
+//
+// Proxy class for bit-selection in class sc_fxnum, behaves like sc_bit.
+// ----------------------------------------------------------------------------
+
+bool
+sc_fxnum_bitref::get() const
+{
+ return m_num.get_bit( m_idx );
+}
+
+void
+sc_fxnum_bitref::set( bool high )
+{
+ m_num.set_bit( m_idx, high );
+}
+
+
+// print or dump content
+
+void
+sc_fxnum_bitref::print( ::std::ostream& os ) const
+{
+ os << get();
+}
+
+void
+sc_fxnum_bitref::scan( ::std::istream& is )
+{
+ bool b;
+ is >> b;
+ *this = b;
+}
+
+void
+sc_fxnum_bitref::dump( ::std::ostream& os ) const
+{
+ os << "sc_fxnum_bitref" << ::std::endl;
+ os << "(" << ::std::endl;
+ os << "num = ";
+ m_num.dump( os );
+ os << "idx = " << m_idx << ::std::endl;
+ os << ")" << ::std::endl;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxnum_fast_bitref
+//
+// Proxy class for bit-selection in class sc_fxnum_fast, behaves like sc_bit.
+// ----------------------------------------------------------------------------
+
+bool
+sc_fxnum_fast_bitref::get() const
+{
+ return m_num.get_bit( m_idx );
+}
+
+void
+sc_fxnum_fast_bitref::set( bool high )
+{
+ m_num.set_bit( m_idx, high );
+}
+
+
+// print or dump content
+
+void
+sc_fxnum_fast_bitref::print( ::std::ostream& os ) const
+{
+ os << get();
+}
+
+void
+sc_fxnum_fast_bitref::scan( ::std::istream& is )
+{
+ bool b;
+ is >> b;
+ *this = b;
+}
+
+void
+sc_fxnum_fast_bitref::dump( ::std::ostream& os ) const
+{
+ os << "sc_fxnum_fast_bitref" << ::std::endl;
+ os << "(" << ::std::endl;
+ os << "num = ";
+ m_num.dump( os );
+ os << "idx = " << m_idx << ::std::endl;
+ os << ")" << ::std::endl;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxnum_subref
+//
+// Proxy class for part-selection in class sc_fxnum,
+// behaves like sc_bv_base.
+// ----------------------------------------------------------------------------
+
+bool
+sc_fxnum_subref::get() const
+{
+ return m_num.get_slice( m_from, m_to, m_bv );
+}
+
+bool
+sc_fxnum_subref::set()
+{
+ return m_num.set_slice( m_from, m_to, m_bv );
+}
+
+
+// print or dump content
+
+void
+sc_fxnum_subref::print( ::std::ostream& os ) const
+{
+ get();
+ m_bv.print( os );
+}
+
+void
+sc_fxnum_subref::scan( ::std::istream& is )
+{
+ m_bv.scan( is );
+ set();
+}
+
+void
+sc_fxnum_subref::dump( ::std::ostream& os ) const
+{
+ os << "sc_fxnum_subref" << ::std::endl;
+ os << "(" << ::std::endl;
+ os << "num = ";
+ m_num.dump( os );
+ os << "from = " << m_from << ::std::endl;
+ os << "to = " << m_to << ::std::endl;
+ os << ")" << ::std::endl;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxnum_fast_subref
+//
+// Proxy class for part-selection in class sc_fxnum_fast,
+// behaves like sc_bv_base.
+// ----------------------------------------------------------------------------
+
+bool
+sc_fxnum_fast_subref::get() const
+{
+ return m_num.get_slice( m_from, m_to, m_bv );
+}
+
+bool
+sc_fxnum_fast_subref::set()
+{
+ return m_num.set_slice( m_from, m_to, m_bv );
+}
+
+
+// print or dump content
+
+void
+sc_fxnum_fast_subref::print( ::std::ostream& os ) const
+{
+ get();
+ m_bv.print( os );
+}
+
+void
+sc_fxnum_fast_subref::scan( ::std::istream& is )
+{
+ m_bv.scan( is );
+ set();
+}
+
+void
+sc_fxnum_fast_subref::dump( ::std::ostream& os ) const
+{
+ os << "sc_fxnum_fast_subref" << ::std::endl;
+ os << "(" << ::std::endl;
+ os << "num = ";
+ m_num.dump( os );
+ os << "from = " << m_from << ::std::endl;
+ os << "to = " << m_to << ::std::endl;
+ os << ")" << ::std::endl;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxnum
+//
+// Base class for the fixed-point types; arbitrary precision.
+// ----------------------------------------------------------------------------
+
+// explicit conversion to character string
+
+const std::string
+sc_fxnum::to_string() const
+{
+ return std::string( m_rep->to_string( SC_DEC, -1, SC_F, &m_params ) );
+}
+
+const std::string
+sc_fxnum::to_string( sc_numrep numrep ) const
+{
+ return std::string( m_rep->to_string( numrep, -1, SC_F, &m_params ) );
+}
+
+const std::string
+sc_fxnum::to_string( sc_numrep numrep, bool w_prefix ) const
+{
+ return std::string( m_rep->to_string( numrep, (w_prefix ? 1 : 0),
+ SC_F, &m_params ) );
+}
+
+const std::string
+sc_fxnum::to_string( sc_fmt fmt ) const
+{
+ return std::string( m_rep->to_string( SC_DEC, -1, fmt, &m_params ) );
+}
+
+const std::string
+sc_fxnum::to_string( sc_numrep numrep, sc_fmt fmt ) const
+{
+ return std::string( m_rep->to_string( numrep, -1, fmt, &m_params ) );
+}
+
+const std::string
+sc_fxnum::to_string( sc_numrep numrep, bool w_prefix, sc_fmt fmt ) const
+{
+ return std::string( m_rep->to_string( numrep, (w_prefix ? 1 : 0),
+ fmt, &m_params ) );
+}
+
+
+const std::string
+sc_fxnum::to_dec() const
+{
+ return std::string( m_rep->to_string( SC_DEC, -1, SC_F, &m_params ) );
+}
+
+const std::string
+sc_fxnum::to_bin() const
+{
+ return std::string( m_rep->to_string( SC_BIN, -1, SC_F, &m_params ) );
+}
+
+const std::string
+sc_fxnum::to_oct() const
+{
+ return std::string( m_rep->to_string( SC_OCT, -1, SC_F, &m_params ) );
+}
+
+const std::string
+sc_fxnum::to_hex() const
+{
+ return std::string( m_rep->to_string( SC_HEX, -1, SC_F, &m_params ) );
+}
+
+
+// print or dump content
+
+void
+sc_fxnum::print( ::std::ostream& os ) const
+{
+ os << m_rep->to_string( SC_DEC, -1, SC_F, &m_params );
+}
+
+void
+sc_fxnum::scan( ::std::istream& is )
+{
+ std::string s;
+ is >> s;
+ *this = s.c_str();
+}
+
+void
+sc_fxnum::dump( ::std::ostream& os ) const
+{
+ os << "sc_fxnum" << ::std::endl;
+ os << "(" << ::std::endl;
+ os << "rep = ";
+ m_rep->dump( os );
+ os << "params = ";
+ m_params.dump( os );
+ os << "q_flag = " << m_q_flag << ::std::endl;
+ os << "o_flag = " << m_o_flag << ::std::endl;
+ // TO BE COMPLETED
+ // os << "observer = ";
+ // if( m_observer != 0 )
+ // m_observer->dump( os );
+ // else
+ // os << "0" << ::std::endl;
+ os << ")" << ::std::endl;
+}
+
+
+sc_fxnum_observer*
+sc_fxnum::lock_observer() const
+{
+ SC_ASSERT_( m_observer != 0, "lock observer failed" );
+ sc_fxnum_observer* tmp = m_observer;
+ m_observer = 0;
+ return tmp;
+}
+
+void
+sc_fxnum::unlock_observer( sc_fxnum_observer* observer_ ) const
+{
+ SC_ASSERT_( observer_ != 0, "unlock observer failed" );
+ m_observer = observer_;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxnum_fast
+//
+// Base class for the fixed-point types; limited precision.
+// ----------------------------------------------------------------------------
+
+static
+void
+quantization( double& c, const scfx_params& params, bool& q_flag )
+{
+ int fwl = params.wl() - params.iwl();
+ double scale = scfx_pow2( fwl );
+ double val = scale * c;
+ double int_part;
+ double frac_part = modf( val, &int_part );
+
+ q_flag = ( frac_part != 0.0 );
+
+ if( q_flag )
+ {
+ val = int_part;
+
+ switch( params.q_mode() )
+ {
+ case SC_TRN: // truncation
+ {
+ if( c < 0.0 )
+ val -= 1.0;
+ break;
+ }
+ case SC_RND: // rounding to plus infinity
+ {
+ if( frac_part >= 0.5 )
+ val += 1.0;
+ else if( frac_part < -0.5 )
+ val -= 1.0;
+ break;
+ }
+ case SC_TRN_ZERO: // truncation to zero
+ {
+ break;
+ }
+ case SC_RND_INF: // rounding to infinity
+ {
+ if( frac_part >= 0.5 )
+ val += 1.0;
+ else if( frac_part <= -0.5 )
+ val -= 1.0;
+ break;
+ }
+ case SC_RND_CONV: // convergent rounding
+ {
+ if( frac_part > 0.5 ||
+ ( frac_part == 0.5 && fmod( int_part, 2.0 ) != 0.0 ) )
+ val += 1.0;
+ else if( frac_part < -0.5 ||
+ ( frac_part == -0.5 && fmod( int_part, 2.0 ) != 0.0 ) )
+ val -= 1.0;
+ break;
+ }
+ case SC_RND_ZERO: // rounding to zero
+ {
+ if( frac_part > 0.5 )
+ val += 1.0;
+ else if( frac_part < -0.5 )
+ val -= 1.0;
+ break;
+ }
+ case SC_RND_MIN_INF: // rounding to minus infinity
+ {
+ if( frac_part > 0.5 )
+ val += 1.0;
+ else if( frac_part <= -0.5 )
+ val -= 1.0;
+ break;
+ }
+ default:
+ ;
+ }
+ }
+
+ val /= scale;
+ c = val;
+}
+
+static
+void
+overflow( double& c, const scfx_params& params, bool& o_flag )
+{
+ int iwl = params.iwl();
+ int fwl = params.wl() - iwl;
+ double full_circle = scfx_pow2( iwl );
+ double resolution = scfx_pow2( -fwl );
+ double low, high;
+ if( params.enc() == SC_TC_ )
+ {
+ high = full_circle / 2.0 - resolution;
+ if( params.o_mode() == SC_SAT_SYM )
+ low = - high;
+ else
+ low = - full_circle / 2.0;
+ }
+ else
+ {
+ low = 0.0;
+ high = full_circle - resolution;
+ }
+ double val = c;
+ sc_fxval_fast c2(c);
+
+ bool under = ( val < low );
+ bool over = ( val > high );
+
+ o_flag = ( under || over );
+
+ if( o_flag )
+ {
+ switch( params.o_mode() )
+ {
+ case SC_WRAP: // wrap-around
+ {
+ int n_bits = params.n_bits();
+
+ if( n_bits == 0 )
+ {
+ // wrap-around all 'wl' bits
+ val -= floor( val / full_circle ) * full_circle;
+ if( val > high )
+ val -= full_circle;
+ }
+ else if( n_bits < params.wl() )
+ {
+ double X = scfx_pow2( iwl - n_bits );
+
+ // wrap-around least significant 'wl - n_bits' bits
+ val -= floor( val / X ) * X;
+ if( val > ( X - resolution ) )
+ val -= X;
+
+ // saturate most significant 'n_bits' bits
+ if( under )
+ val += low;
+ else
+ {
+ if( params.enc() == SC_TC_ )
+ val += full_circle / 2.0 - X;
+ else
+ val += full_circle - X;
+ }
+ }
+ else
+ {
+ // saturate all 'wl' bits
+ if( under )
+ val = low;
+ else
+ val = high;
+ }
+ break;
+ }
+ case SC_SAT: // saturation
+ case SC_SAT_SYM: // symmetrical saturation
+ {
+ if( under )
+ val = low;
+ else
+ val = high;
+ break;
+ }
+ case SC_SAT_ZERO: // saturation to zero
+ {
+ val = 0.0;
+ break;
+ }
+ case SC_WRAP_SM: // sign magnitude wrap-around
+ {
+ SC_ERROR_IF_( params.enc() == SC_US_,
+ sc_core::SC_ID_WRAP_SM_NOT_DEFINED_ );
+
+ int n_bits = params.n_bits();
+
+ if( n_bits == 0 )
+ {
+ // invert conditionally
+ if( c2.get_bit( iwl ) != c2.get_bit( iwl - 1 ) )
+ val = -val - resolution;
+
+ // wrap-around all 'wl' bits
+ val -= floor( val / full_circle ) * full_circle;
+ if( val > high )
+ val -= full_circle;
+ }
+ else if( n_bits == 1 )
+ {
+ // invert conditionally
+ if( c2.is_neg() != c2.get_bit( iwl - 1 ) )
+ val = -val - resolution;
+
+ // wrap-around all 'wl' bits
+ val -= floor( val / full_circle ) * full_circle;
+ if( val > high )
+ val -= full_circle;
+ }
+ else if( n_bits < params.wl() )
+ {
+ // invert conditionally
+ if( c2.is_neg() == c2.get_bit( iwl - n_bits ) )
+ val = -val - resolution;
+
+ double X = scfx_pow2( iwl - n_bits );
+
+ // wrap-around least significant 'wl - n_bits' bits
+ val -= floor( val / X ) * X;
+ if( val > ( X - resolution ) )
+ val -= X;
+
+ // saturate most significant 'n_bits' bits
+ if( under )
+ val += low;
+ else
+ val += full_circle / 2.0 - X;
+ } else {
+ // saturate all 'wl' bits
+ if( under )
+ val = low;
+ else
+ val = high;
+ }
+ break;
+ }
+ default:
+ ;
+ }
+
+ c = val;
+ }
+}
+
+
+void
+sc_fxnum_fast::cast()
+{
+ scfx_ieee_double id( m_val );
+ SC_ERROR_IF_( id.is_nan() || id.is_inf(), sc_core::SC_ID_INVALID_FX_VALUE_);
+
+ if( m_params.cast_switch() == SC_ON )
+ {
+ m_q_flag = false;
+ m_o_flag = false;
+
+ // check for special cases
+
+ if( id.is_zero() )
+ {
+ if( id.negative() != 0 )
+ m_val = -m_val;
+ return;
+ }
+
+ // perform casting
+
+ sc_dt::quantization( m_val, m_params, m_q_flag );
+ sc_dt::overflow( m_val, m_params, m_o_flag );
+
+ // check for special case: -0
+
+ id = m_val;
+ if( id.is_zero() && id.negative() != 0 ) {
+ m_val = -m_val;
+ }
+
+ // check for special case: NaN of Inf
+
+ if( id.is_nan() || id.is_inf() ) {
+ m_val = 0.0;
+ }
+ }
+}
+
+
+// defined in sc_fxval.cpp;
+extern
+const char*
+to_string( const scfx_ieee_double&,
+ sc_numrep,
+ int,
+ sc_fmt,
+ const scfx_params* = 0 );
+
+
+// explicit conversion to character string
+
+const std::string
+sc_fxnum_fast::to_string() const
+{
+ return std::string( sc_dt::to_string( m_val, SC_DEC, -1, SC_F, &m_params ) );
+}
+
+const std::string
+sc_fxnum_fast::to_string( sc_numrep numrep ) const
+{
+ return std::string( sc_dt::to_string( m_val, numrep, -1, SC_F, &m_params ) );
+}
+
+const std::string
+sc_fxnum_fast::to_string( sc_numrep numrep, bool w_prefix ) const
+{
+ return std::string( sc_dt::to_string( m_val, numrep, (w_prefix ? 1 : 0),
+ SC_F, &m_params ) );
+}
+
+const std::string
+sc_fxnum_fast::to_string( sc_fmt fmt ) const
+{
+ return std::string( sc_dt::to_string( m_val, SC_DEC, -1, fmt, &m_params ) );
+}
+
+const std::string
+sc_fxnum_fast::to_string( sc_numrep numrep, sc_fmt fmt ) const
+{
+ return std::string( sc_dt::to_string( m_val, numrep, -1, fmt, &m_params ) );
+}
+
+const std::string
+sc_fxnum_fast::to_string( sc_numrep numrep, bool w_prefix, sc_fmt fmt ) const
+{
+ return std::string( sc_dt::to_string( m_val, numrep, (w_prefix ? 1 : 0),
+ fmt, &m_params ) );
+}
+
+
+const std::string
+sc_fxnum_fast::to_dec() const
+{
+ return std::string( sc_dt::to_string( m_val, SC_DEC, -1, SC_F, &m_params ) );
+}
+
+const std::string
+sc_fxnum_fast::to_bin() const
+{
+ return std::string( sc_dt::to_string( m_val, SC_BIN, -1, SC_F, &m_params ) );
+}
+
+const std::string
+sc_fxnum_fast::to_oct() const
+{
+ return std::string( sc_dt::to_string( m_val, SC_OCT, -1, SC_F, &m_params ) );
+}
+
+const std::string
+sc_fxnum_fast::to_hex() const
+{
+ return std::string( sc_dt::to_string( m_val, SC_HEX, -1, SC_F, &m_params ) );
+}
+
+
+// print or dump content
+
+void
+sc_fxnum_fast::print( ::std::ostream& os ) const
+{
+ os << sc_dt::to_string( m_val, SC_DEC, -1, SC_F, &m_params );
+}
+
+void
+sc_fxnum_fast::scan( ::std::istream& is )
+{
+ std::string s;
+ is >> s;
+ *this = s.c_str();
+}
+
+void
+sc_fxnum_fast::dump( ::std::ostream& os ) const
+{
+ os << "sc_fxnum_fast" << ::std::endl;
+ os << "(" << ::std::endl;
+ os << "val = " << m_val << ::std::endl;
+ os << "params = ";
+ m_params.dump( os );
+ os << "q_flag = " << m_q_flag << ::std::endl;
+ os << "o_flag = " << m_o_flag << ::std::endl;
+ // TO BE COMPLETED
+ // os << "observer = ";
+ // if( m_observer != 0 )
+ // m_observer->dump( os );
+ // else
+ // os << "0" << ::std::endl;
+ os << ")" << ::std::endl;
+}
+
+
+// internal use only;
+bool
+sc_fxnum_fast::get_bit( int i ) const
+{
+ scfx_ieee_double id( m_val );
+ if( id.is_zero() || id.is_nan() || id.is_inf() )
+ return false;
+
+ // convert to two's complement
+
+ unsigned int m0 = id.mantissa0();
+ unsigned int m1 = id.mantissa1();
+
+ if( id.is_normal() )
+ m0 += 1U << 20;
+
+ if( id.negative() != 0 )
+ {
+ m0 = ~ m0;
+ m1 = ~ m1;
+ unsigned int tmp = m1;
+ m1 += 1U;
+ if( m1 <= tmp )
+ m0 += 1U;
+ }
+
+ // get the right bit
+
+ int j = i - id.exponent();
+ if( ( j += 20 ) >= 32 )
+ return ( ( m0 & 1U << 31 ) != 0 );
+ else if( j >= 0 )
+ return ( ( m0 & 1U << j ) != 0 );
+ else if( ( j += 32 ) >= 0 )
+ return ( ( m1 & 1U << j ) != 0 );
+ else
+ return false;
+}
+
+
+bool
+sc_fxnum_fast::set_bit( int i, bool high )
+{
+ scfx_ieee_double id( m_val );
+ if( id.is_nan() || id.is_inf() )
+ return false;
+
+ if( high )
+ {
+ if( get_bit( i ) )
+ return true;
+
+ if( m_params.enc() == SC_TC_ && i == m_params.iwl() - 1 )
+ m_val -= scfx_pow2( i );
+ else
+ m_val += scfx_pow2( i );
+ }
+ else
+ {
+ if( ! get_bit( i ) )
+ return true;
+
+ if( m_params.enc() == SC_TC_ && i == m_params.iwl() - 1 )
+ m_val += scfx_pow2( i );
+ else
+ m_val -= scfx_pow2( i );
+ }
+
+ return true;
+}
+
+
+bool
+sc_fxnum_fast::get_slice( int i, int j, sc_bv_base& bv ) const
+{
+ scfx_ieee_double id( m_val );
+ if( id.is_nan() || id.is_inf() )
+ return false;
+
+ // convert to two's complement
+
+ unsigned int m0 = id.mantissa0();
+ unsigned int m1 = id.mantissa1();
+
+ if( id.is_normal() )
+ m0 += 1U << 20;
+
+ if( id.negative() != 0 )
+ {
+ m0 = ~ m0;
+ m1 = ~ m1;
+ unsigned int tmp = m1;
+ m1 += 1U;
+ if( m1 <= tmp )
+ m0 += 1U;
+ }
+
+ // get the bits
+
+ int l = j;
+ for( int k = 0; k < bv.length(); ++ k )
+ {
+ bool b = false;
+
+ int n = l - id.exponent();
+ if( ( n += 20 ) >= 32 )
+ b = ( ( m0 & 1U << 31 ) != 0 );
+ else if( n >= 0 )
+ b = ( ( m0 & 1U << n ) != 0 );
+ else if( ( n += 32 ) >= 0 )
+ b = ( ( m1 & 1U << n ) != 0 );
+
+ bv[k] = b;
+
+ if( i >= j )
+ ++ l;
+ else
+ -- l;
+ }
+
+ return true;
+}
+
+bool
+sc_fxnum_fast::set_slice( int i, int j, const sc_bv_base& bv )
+{
+ scfx_ieee_double id( m_val );
+ if( id.is_nan() || id.is_inf() )
+ return false;
+
+ // set the bits
+
+ int l = j;
+ for( int k = 0; k < bv.length(); ++ k )
+ {
+ if( bv[k].to_bool() )
+ {
+ if( ! get_bit( l ) )
+ {
+ if( m_params.enc() == SC_TC_ && l == m_params.iwl() - 1 )
+ m_val -= scfx_pow2( l );
+ else
+ m_val += scfx_pow2( l );
+ }
+ }
+ else
+ {
+ if( get_bit( l ) )
+ {
+ if( m_params.enc() == SC_TC_ && l == m_params.iwl() - 1 )
+ m_val += scfx_pow2( l );
+ else
+ m_val -= scfx_pow2( l );
+ }
+ }
+
+
+ if( i >= j )
+ ++ l;
+ else
+ -- l;
+ }
+
+ return true;
+}
+
+
+sc_fxnum_fast_observer*
+sc_fxnum_fast::lock_observer() const
+{
+ SC_ASSERT_( m_observer != 0, "lock observer failed" );
+ sc_fxnum_fast_observer* tmp = m_observer;
+ m_observer = 0;
+ return tmp;
+}
+
+void
+sc_fxnum_fast::unlock_observer( sc_fxnum_fast_observer* observer_ ) const
+{
+ SC_ASSERT_( observer_ != 0, "unlock observer failed" );
+ m_observer = observer_;
+}
+
+} // namespace sc_dt
+
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxnum.h b/ext/systemc/src/sysc/datatypes/fx/sc_fxnum.h
new file mode 100644
index 000000000..ed3750811
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxnum.h
@@ -0,0 +1,5102 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_fxnum.h -
+
+ Original Author: Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_fxnum.h,v $
+// Revision 1.5 2011/08/29 18:04:32 acg
+// Philipp A. Hartmann: miscellaneous clean ups.
+//
+// Revision 1.4 2011/08/24 22:05:43 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.3 2011/01/19 18:57:40 acg
+// Andy Goodrich: changes for IEEE_1666_2011.
+//
+// Revision 1.2 2009/03/09 17:26:46 acg
+// Andy Goodrich: removed ; from namespace { }
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:58 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#ifndef SC_FXNUM_H
+#define SC_FXNUM_H
+
+
+#include "sysc/datatypes/bit/sc_lv_base.h"
+#include "sysc/datatypes/fx/sc_fxval.h"
+#include "sysc/datatypes/fx/scfx_params.h"
+#include "sysc/datatypes/fx/sc_fxnum_observer.h"
+
+
+namespace sc_core {
+ class vcd_sc_fxnum_trace;
+ class vcd_sc_fxnum_fast_trace;
+ class wif_sc_fxnum_trace;
+ class wif_sc_fxnum_fast_trace;
+}
+
+
+namespace sc_dt
+{
+
+// classes defined in this module
+class sc_fxnum_bitref;
+class sc_fxnum_fast_bitref;
+class sc_fxnum_subref;
+class sc_fxnum_fast_subref;
+class sc_fxnum;
+class sc_fxnum_fast;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxnum_bitref
+//
+// Proxy class for bit-selection in class sc_fxnum, behaves like sc_bit.
+// ----------------------------------------------------------------------------
+
+class sc_fxnum_bitref
+{
+ friend class sc_fxnum;
+ friend class sc_fxnum_fast_bitref;
+
+
+ bool get() const;
+ void set( bool );
+
+
+ // constructor
+
+ sc_fxnum_bitref( sc_fxnum&, int );
+
+public:
+
+ // copy constructor
+
+ sc_fxnum_bitref( const sc_fxnum_bitref& );
+
+
+ // assignment operators
+
+#define DECL_ASN_OP_T(op,tp) \
+ sc_fxnum_bitref& operator op ( tp );
+
+#define DECL_ASN_OP(op) \
+ DECL_ASN_OP_T(op,const sc_fxnum_bitref&) \
+ DECL_ASN_OP_T(op,const sc_fxnum_fast_bitref&) \
+ DECL_ASN_OP_T(op,const sc_bit&) \
+ DECL_ASN_OP_T(op,bool)
+
+ DECL_ASN_OP(=)
+
+ DECL_ASN_OP(&=)
+ DECL_ASN_OP(|=)
+ DECL_ASN_OP(^=)
+
+#undef DECL_ASN_OP_T
+#undef DECL_ASN_OP
+
+
+ // implicit conversion
+
+ operator bool() const;
+
+
+ // print or dump content
+
+ void print( ::std::ostream& = ::std::cout ) const;
+ void scan( ::std::istream& = ::std::cin );
+ void dump( ::std::ostream& = ::std::cout ) const;
+
+private:
+
+ sc_fxnum& m_num;
+ int m_idx;
+
+private:
+
+ // disabled
+ sc_fxnum_bitref();
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxnum_fast_bitref
+//
+// Proxy class for bit-selection in class sc_fxnum_fast, behaves like sc_bit.
+// ----------------------------------------------------------------------------
+
+class sc_fxnum_fast_bitref
+{
+ friend class sc_fxnum_fast;
+ friend class sc_fxnum_bitref;
+
+
+ bool get() const;
+ void set( bool );
+
+
+ // constructor
+
+ sc_fxnum_fast_bitref( sc_fxnum_fast&, int );
+
+public:
+
+ // copy constructor
+
+ sc_fxnum_fast_bitref( const sc_fxnum_fast_bitref& );
+
+
+ // assignment operators
+
+#define DECL_ASN_OP_T(op,tp) \
+ sc_fxnum_fast_bitref& operator op ( tp );
+
+#define DECL_ASN_OP(op) \
+ DECL_ASN_OP_T(op,const sc_fxnum_bitref&) \
+ DECL_ASN_OP_T(op,const sc_fxnum_fast_bitref&) \
+ DECL_ASN_OP_T(op,const sc_bit&) \
+ DECL_ASN_OP_T(op,bool)
+
+ DECL_ASN_OP(=)
+
+ DECL_ASN_OP(&=)
+ DECL_ASN_OP(|=)
+ DECL_ASN_OP(^=)
+
+#undef DECL_ASN_OP_T
+#undef DECL_ASN_OP
+
+
+ // implicit conversion
+
+ operator bool() const;
+
+
+ // print or dump content
+
+ void print( ::std::ostream& = ::std::cout ) const;
+ void scan( ::std::istream& = ::std::cin );
+ void dump( ::std::ostream& = ::std::cout ) const;
+
+private:
+
+ sc_fxnum_fast& m_num;
+ int m_idx;
+
+private:
+
+ // disabled
+ sc_fxnum_fast_bitref();
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxnum_subref
+//
+// Proxy class for part-selection in class sc_fxnum,
+// behaves like sc_bv_base.
+// ----------------------------------------------------------------------------
+
+class sc_fxnum_subref
+{
+ friend class sc_fxnum;
+ friend class sc_fxnum_fast_subref;
+
+ bool get() const;
+ bool set();
+
+
+ // constructor
+
+ sc_fxnum_subref( sc_fxnum&, int, int );
+
+public:
+
+ // copy constructor
+
+ sc_fxnum_subref( const sc_fxnum_subref& );
+
+
+ // destructor
+
+ ~sc_fxnum_subref();
+
+
+ // assignment operators
+
+#define DECL_ASN_OP_T(tp) \
+ sc_fxnum_subref& operator = ( tp );
+
+ DECL_ASN_OP_T(const sc_fxnum_subref&)
+ DECL_ASN_OP_T(const sc_fxnum_fast_subref&)
+ DECL_ASN_OP_T(const sc_bv_base&)
+ DECL_ASN_OP_T(const sc_lv_base&)
+ DECL_ASN_OP_T(const char*)
+ DECL_ASN_OP_T(const bool*)
+ DECL_ASN_OP_T(const sc_signed&)
+ DECL_ASN_OP_T(const sc_unsigned&)
+ DECL_ASN_OP_T(const sc_int_base&)
+ DECL_ASN_OP_T(const sc_uint_base&)
+ DECL_ASN_OP_T(int64)
+ DECL_ASN_OP_T(uint64)
+ DECL_ASN_OP_T(int)
+ DECL_ASN_OP_T(unsigned int)
+ DECL_ASN_OP_T(long)
+ DECL_ASN_OP_T(unsigned long)
+ DECL_ASN_OP_T(char)
+
+#undef DECL_ASN_OP_T
+
+#define DECL_ASN_OP_T_A(op,tp) \
+ sc_fxnum_subref& operator op ## = ( tp );
+
+#define DECL_ASN_OP_A(op) \
+ DECL_ASN_OP_T_A(op,const sc_fxnum_subref&) \
+ DECL_ASN_OP_T_A(op,const sc_fxnum_fast_subref&) \
+ DECL_ASN_OP_T_A(op,const sc_bv_base&) \
+ DECL_ASN_OP_T_A(op,const sc_lv_base&)
+
+ DECL_ASN_OP_A(&)
+ DECL_ASN_OP_A(|)
+ DECL_ASN_OP_A(^)
+
+#undef DECL_ASN_OP_T_A
+#undef DECL_ASN_OP_A
+
+
+ // relational operators
+
+#define DECL_REL_OP_T(op,tp) \
+ friend bool operator op ( const sc_fxnum_subref&, tp ); \
+ friend bool operator op ( tp, const sc_fxnum_subref& );
+
+#define DECL_REL_OP(op) \
+ friend bool operator op ( const sc_fxnum_subref&, \
+ const sc_fxnum_subref& ); \
+ friend bool operator op ( const sc_fxnum_subref&, \
+ const sc_fxnum_fast_subref& ); \
+ DECL_REL_OP_T(op,const sc_bv_base&) \
+ DECL_REL_OP_T(op,const sc_lv_base&) \
+ DECL_REL_OP_T(op,const char*) \
+ DECL_REL_OP_T(op,const bool*) \
+ DECL_REL_OP_T(op,const sc_signed&) \
+ DECL_REL_OP_T(op,const sc_unsigned&) \
+ DECL_REL_OP_T(op,int) \
+ DECL_REL_OP_T(op,unsigned int) \
+ DECL_REL_OP_T(op,long) \
+ DECL_REL_OP_T(op,unsigned long)
+
+ DECL_REL_OP(==)
+ DECL_REL_OP(!=)
+
+#undef DECL_REL_OP_T
+#undef DECL_REL_OP
+
+
+ // reduce functions
+
+ bool and_reduce() const;
+ bool nand_reduce() const;
+ bool or_reduce() const;
+ bool nor_reduce() const;
+ bool xor_reduce() const;
+ bool xnor_reduce() const;
+
+
+ // query parameter
+
+ int length() const;
+
+
+ // explicit conversions
+
+ int to_int() const;
+ unsigned int to_uint() const;
+ long to_long() const;
+ unsigned long to_ulong() const;
+ int64 to_int64() const;
+ uint64 to_uint64() const;
+
+#ifdef SC_DT_DEPRECATED
+ int to_signed() const;
+ unsigned int to_unsigned() const;
+#endif
+
+ const std::string to_string() const;
+ const std::string to_string( sc_numrep ) const;
+ const std::string to_string( sc_numrep, bool ) const;
+
+
+ // implicit conversion
+
+ operator sc_bv_base() const;
+
+
+ // print or dump content
+
+ void print( ::std::ostream& = ::std::cout ) const;
+ void scan( ::std::istream& = ::std::cin );
+ void dump( ::std::ostream& = ::std::cout ) const;
+
+private:
+
+ sc_fxnum& m_num;
+ int m_from;
+ int m_to;
+
+ sc_bv_base& m_bv;
+
+private:
+
+ // disabled
+ sc_fxnum_subref();
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxnum_fast_subref
+//
+// Proxy class for part-selection in class sc_fxnum_fast,
+// behaves like sc_bv_base.
+// ----------------------------------------------------------------------------
+
+class sc_fxnum_fast_subref
+{
+ friend class sc_fxnum_fast;
+ friend class sc_fxnum_subref;
+
+ bool get() const;
+ bool set();
+
+
+ // constructor
+
+ sc_fxnum_fast_subref( sc_fxnum_fast&, int, int );
+
+public:
+
+ // copy constructor
+
+ sc_fxnum_fast_subref( const sc_fxnum_fast_subref& );
+
+
+ // destructor
+
+ ~sc_fxnum_fast_subref();
+
+
+ // assignment operators
+
+#define DECL_ASN_OP_T(tp) \
+ sc_fxnum_fast_subref& operator = ( tp );
+
+ DECL_ASN_OP_T(const sc_fxnum_subref&)
+ DECL_ASN_OP_T(const sc_fxnum_fast_subref&)
+ DECL_ASN_OP_T(const sc_bv_base&)
+ DECL_ASN_OP_T(const sc_lv_base&)
+ DECL_ASN_OP_T(const char*)
+ DECL_ASN_OP_T(const bool*)
+ DECL_ASN_OP_T(const sc_signed&)
+ DECL_ASN_OP_T(const sc_unsigned&)
+ DECL_ASN_OP_T(const sc_int_base&)
+ DECL_ASN_OP_T(const sc_uint_base&)
+ DECL_ASN_OP_T(int64)
+ DECL_ASN_OP_T(uint64)
+ DECL_ASN_OP_T(int)
+ DECL_ASN_OP_T(unsigned int)
+ DECL_ASN_OP_T(long)
+ DECL_ASN_OP_T(unsigned long)
+ DECL_ASN_OP_T(char)
+
+#undef DECL_ASN_OP_T
+
+#define DECL_ASN_OP_T_A(op,tp) \
+ sc_fxnum_fast_subref& operator op ## = ( tp );
+
+#define DECL_ASN_OP_A(op) \
+ DECL_ASN_OP_T_A(op,const sc_fxnum_subref&) \
+ DECL_ASN_OP_T_A(op,const sc_fxnum_fast_subref&) \
+ DECL_ASN_OP_T_A(op,const sc_bv_base&) \
+ DECL_ASN_OP_T_A(op,const sc_lv_base&)
+
+ DECL_ASN_OP_A(&)
+ DECL_ASN_OP_A(|)
+ DECL_ASN_OP_A(^)
+
+#undef DECL_ASN_OP_T_A
+#undef DECL_ASN_OP_A
+
+
+ // relational operators
+
+#define DECL_REL_OP_T(op,tp) \
+ friend bool operator op ( const sc_fxnum_fast_subref&, tp ); \
+ friend bool operator op ( tp, const sc_fxnum_fast_subref& );
+
+#define DECL_REL_OP(op) \
+ friend bool operator op ( const sc_fxnum_fast_subref&, \
+ const sc_fxnum_fast_subref& ); \
+ friend bool operator op ( const sc_fxnum_fast_subref&, \
+ const sc_fxnum_subref& ); \
+ DECL_REL_OP_T(op,const sc_bv_base&) \
+ DECL_REL_OP_T(op,const sc_lv_base&) \
+ DECL_REL_OP_T(op,const char*) \
+ DECL_REL_OP_T(op,const bool*) \
+ DECL_REL_OP_T(op,const sc_signed&) \
+ DECL_REL_OP_T(op,const sc_unsigned&) \
+ DECL_REL_OP_T(op,int) \
+ DECL_REL_OP_T(op,unsigned int) \
+ DECL_REL_OP_T(op,long) \
+ DECL_REL_OP_T(op,unsigned long)
+
+ DECL_REL_OP(==)
+ DECL_REL_OP(!=)
+
+#undef DECL_REL_OP_T
+#undef DECL_REL_OP
+
+
+ // reduce functions
+
+ bool and_reduce() const;
+ bool nand_reduce() const;
+ bool or_reduce() const;
+ bool nor_reduce() const;
+ bool xor_reduce() const;
+ bool xnor_reduce() const;
+
+
+ // query parameter
+
+ int length() const;
+
+
+ // explicit conversions
+
+ int to_int() const;
+ unsigned int to_uint() const;
+ long to_long() const;
+ unsigned long to_ulong() const;
+ int64 to_int64() const;
+ uint64 to_uint64() const;
+
+#ifdef SC_DT_DEPRECATED
+ int to_signed() const;
+ unsigned int to_unsigned() const;
+#endif
+
+ const std::string to_string() const;
+ const std::string to_string( sc_numrep ) const;
+ const std::string to_string( sc_numrep, bool ) const;
+
+
+ // implicit conversion
+
+ operator sc_bv_base() const;
+
+
+ // print or dump content
+
+ void print( ::std::ostream& = ::std::cout ) const;
+ void scan( ::std::istream& = ::std::cin );
+ void dump( ::std::ostream& = ::std::cout ) const;
+
+private:
+
+ sc_fxnum_fast& m_num;
+ int m_from;
+ int m_to;
+
+ sc_bv_base& m_bv;
+
+private:
+
+ // disabled
+ sc_fxnum_fast_subref();
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxnum
+//
+// Base class for the fixed-point types; arbitrary precision.
+// ----------------------------------------------------------------------------
+
+class sc_fxnum
+{
+ friend class sc_fxval;
+
+ friend class sc_fxnum_bitref;
+ friend class sc_fxnum_subref;
+ friend class sc_fxnum_fast_bitref;
+ friend class sc_fxnum_fast_subref;
+
+ friend class sc_core::vcd_sc_fxnum_trace;
+ friend class sc_core::wif_sc_fxnum_trace;
+
+protected:
+
+ sc_fxnum_observer* observer() const;
+
+
+ void cast();
+
+
+ // constructors
+
+ sc_fxnum( const sc_fxtype_params&,
+ sc_enc,
+ const sc_fxcast_switch&,
+ sc_fxnum_observer* );
+
+#define DECL_CTOR_T(tp) \
+ sc_fxnum( tp, \
+ const sc_fxtype_params&, \
+ sc_enc, \
+ const sc_fxcast_switch&, \
+ sc_fxnum_observer* );
+
+ DECL_CTOR_T(int)
+ DECL_CTOR_T(unsigned int)
+ DECL_CTOR_T(long)
+ DECL_CTOR_T(unsigned long)
+ DECL_CTOR_T(float)
+ DECL_CTOR_T(double)
+ DECL_CTOR_T(const char*)
+ DECL_CTOR_T(const sc_fxval&)
+ DECL_CTOR_T(const sc_fxval_fast&)
+ DECL_CTOR_T(const sc_fxnum&)
+ DECL_CTOR_T(const sc_fxnum_fast&)
+#ifndef SC_FX_EXCLUDE_OTHER
+ DECL_CTOR_T(int64)
+ DECL_CTOR_T(uint64)
+ DECL_CTOR_T(const sc_int_base&)
+ DECL_CTOR_T(const sc_uint_base&)
+ DECL_CTOR_T(const sc_signed&)
+ DECL_CTOR_T(const sc_unsigned&)
+#endif
+
+#undef DECL_CTOR_T
+
+ ~sc_fxnum();
+
+
+ // internal use only;
+ const scfx_rep* get_rep() const;
+
+public:
+
+ // unary operators
+
+ const sc_fxval operator - () const;
+ const sc_fxval operator + () const;
+
+
+ // unary functions
+
+ friend void neg( sc_fxval&, const sc_fxnum& );
+ friend void neg( sc_fxnum&, const sc_fxnum& );
+
+
+ // binary operators
+
+#define DECL_BIN_OP_T(op,tp) \
+ friend const sc_fxval operator op ( const sc_fxnum&, tp ); \
+ friend const sc_fxval operator op ( tp, const sc_fxnum& );
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DECL_BIN_OP_OTHER(op) \
+ DECL_BIN_OP_T(op,int64) \
+ DECL_BIN_OP_T(op,uint64) \
+ DECL_BIN_OP_T(op,const sc_int_base&) \
+ DECL_BIN_OP_T(op,const sc_uint_base&) \
+ DECL_BIN_OP_T(op,const sc_signed&) \
+ DECL_BIN_OP_T(op,const sc_unsigned&)
+#else
+#define DECL_BIN_OP_OTHER(op)
+#endif
+
+#define DECL_BIN_OP(op,dummy) \
+ friend const sc_fxval operator op ( const sc_fxnum&, const sc_fxnum& ); \
+ DECL_BIN_OP_T(op,int) \
+ DECL_BIN_OP_T(op,unsigned int) \
+ DECL_BIN_OP_T(op,long) \
+ DECL_BIN_OP_T(op,unsigned long) \
+ DECL_BIN_OP_T(op,float) \
+ DECL_BIN_OP_T(op,double) \
+ DECL_BIN_OP_T(op,const char*) \
+ DECL_BIN_OP_T(op,const sc_fxval&) \
+ DECL_BIN_OP_T(op,const sc_fxval_fast&) \
+ DECL_BIN_OP_T(op,const sc_fxnum_fast&) \
+ DECL_BIN_OP_OTHER(op)
+
+ DECL_BIN_OP(*,mult)
+ DECL_BIN_OP(+,add)
+ DECL_BIN_OP(-,sub)
+// don't use macros
+// DECL_BIN_OP(/,div)
+ friend const sc_fxval operator / ( const sc_fxnum&, const sc_fxnum& );
+ DECL_BIN_OP_T(/,int)
+ DECL_BIN_OP_T(/,unsigned int)
+ DECL_BIN_OP_T(/,long)
+ DECL_BIN_OP_T(/,unsigned long)
+ DECL_BIN_OP_T(/,float)
+ DECL_BIN_OP_T(/,double)
+ DECL_BIN_OP_T(/,const char*)
+ DECL_BIN_OP_T(/,const sc_fxval&)
+ DECL_BIN_OP_T(/,const sc_fxval_fast&)
+ DECL_BIN_OP_T(/,const sc_fxnum_fast&)
+// DECL_BIN_OP_OTHER(op)
+#ifndef SC_FX_EXCLUDE_OTHER
+ DECL_BIN_OP_T(/,int64)
+ DECL_BIN_OP_T(/,uint64)
+ DECL_BIN_OP_T(/,const sc_int_base&)
+ DECL_BIN_OP_T(/,const sc_uint_base&)
+ DECL_BIN_OP_T(/,const sc_signed&)
+ DECL_BIN_OP_T(/,const sc_unsigned&)
+#endif
+
+#undef DECL_BIN_OP_T
+#undef DECL_BIN_OP_OTHER
+#undef DECL_BIN_OP
+
+ friend const sc_fxval operator << ( const sc_fxnum&, int );
+ friend const sc_fxval operator >> ( const sc_fxnum&, int );
+
+
+ // binary functions
+
+#define DECL_BIN_FNC_T(fnc,tp) \
+ friend void fnc ( sc_fxval&, const sc_fxnum&, tp ); \
+ friend void fnc ( sc_fxval&, tp, const sc_fxnum& ); \
+ friend void fnc ( sc_fxnum&, const sc_fxnum&, tp ); \
+ friend void fnc ( sc_fxnum&, tp, const sc_fxnum& );
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DECL_BIN_FNC_OTHER(fnc) \
+ DECL_BIN_FNC_T(fnc,int64) \
+ DECL_BIN_FNC_T(fnc,uint64) \
+ DECL_BIN_FNC_T(fnc,const sc_int_base&) \
+ DECL_BIN_FNC_T(fnc,const sc_uint_base&) \
+ DECL_BIN_FNC_T(fnc,const sc_signed&) \
+ DECL_BIN_FNC_T(fnc,const sc_unsigned&)
+#else
+#define DECL_BIN_FNC_OTHER(fnc)
+#endif
+
+#define DECL_BIN_FNC(fnc) \
+ friend void fnc ( sc_fxval&, const sc_fxnum&, const sc_fxnum& ); \
+ friend void fnc ( sc_fxnum&, const sc_fxnum&, const sc_fxnum& ); \
+ DECL_BIN_FNC_T(fnc,int) \
+ DECL_BIN_FNC_T(fnc,unsigned int) \
+ DECL_BIN_FNC_T(fnc,long) \
+ DECL_BIN_FNC_T(fnc,unsigned long) \
+ DECL_BIN_FNC_T(fnc,float) \
+ DECL_BIN_FNC_T(fnc,double) \
+ DECL_BIN_FNC_T(fnc,const char*) \
+ DECL_BIN_FNC_T(fnc,const sc_fxval&) \
+ DECL_BIN_FNC_T(fnc,const sc_fxval_fast&) \
+ DECL_BIN_FNC_T(fnc,const sc_fxnum_fast&) \
+ DECL_BIN_FNC_OTHER(fnc)
+
+ DECL_BIN_FNC(mult)
+ DECL_BIN_FNC(div)
+ DECL_BIN_FNC(add)
+ DECL_BIN_FNC(sub)
+
+#undef DECL_BIN_FNC_T
+#undef DECL_BIN_FNC_OTHER
+#undef DECL_BIN_FNC
+
+ friend void lshift( sc_fxval&, const sc_fxnum&, int );
+ friend void rshift( sc_fxval&, const sc_fxnum&, int );
+ friend void lshift( sc_fxnum&, const sc_fxnum&, int );
+ friend void rshift( sc_fxnum&, const sc_fxnum&, int );
+
+
+ // relational (including equality) operators
+
+#define DECL_REL_OP_T(op,tp) \
+ friend bool operator op ( const sc_fxnum&, tp ); \
+ friend bool operator op ( tp, const sc_fxnum& );
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DECL_REL_OP_OTHER(op) \
+ DECL_REL_OP_T(op,int64) \
+ DECL_REL_OP_T(op,uint64) \
+ DECL_REL_OP_T(op,const sc_int_base&) \
+ DECL_REL_OP_T(op,const sc_uint_base&) \
+ DECL_REL_OP_T(op,const sc_signed&) \
+ DECL_REL_OP_T(op,const sc_unsigned&)
+#else
+#define DECL_REL_OP_OTHER(op)
+#endif
+
+#define DECL_REL_OP(op) \
+ friend bool operator op ( const sc_fxnum&, const sc_fxnum& ); \
+ DECL_REL_OP_T(op,int) \
+ DECL_REL_OP_T(op,unsigned int) \
+ DECL_REL_OP_T(op,long) \
+ DECL_REL_OP_T(op,unsigned long) \
+ DECL_REL_OP_T(op,float) \
+ DECL_REL_OP_T(op,double) \
+ DECL_REL_OP_T(op,const char*) \
+ DECL_REL_OP_T(op,const sc_fxval&) \
+ DECL_REL_OP_T(op,const sc_fxval_fast&) \
+ DECL_REL_OP_T(op,const sc_fxnum_fast&) \
+ DECL_REL_OP_OTHER(op)
+
+ DECL_REL_OP(<)
+ DECL_REL_OP(<=)
+ DECL_REL_OP(>)
+ DECL_REL_OP(>=)
+ DECL_REL_OP(==)
+ DECL_REL_OP(!=)
+
+#undef DECL_REL_OP_T
+#undef DECL_REL_OP_OTHER
+#undef DECL_REL_OP
+
+
+ // assignment operators
+
+#define DECL_ASN_OP_T(op,tp) \
+ sc_fxnum& operator op( tp );
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DECL_ASN_OP_OTHER(op) \
+ DECL_ASN_OP_T(op,int64) \
+ DECL_ASN_OP_T(op,uint64) \
+ DECL_ASN_OP_T(op,const sc_int_base&) \
+ DECL_ASN_OP_T(op,const sc_uint_base&) \
+ DECL_ASN_OP_T(op,const sc_signed&) \
+ DECL_ASN_OP_T(op,const sc_unsigned&)
+#else
+#define DECL_ASN_OP_OTHER(op)
+#endif
+
+#define DECL_ASN_OP(op) \
+ DECL_ASN_OP_T(op,int) \
+ DECL_ASN_OP_T(op,unsigned int) \
+ DECL_ASN_OP_T(op,long) \
+ DECL_ASN_OP_T(op,unsigned long) \
+ DECL_ASN_OP_T(op,float) \
+ DECL_ASN_OP_T(op,double) \
+ DECL_ASN_OP_T(op,const char*) \
+ DECL_ASN_OP_T(op,const sc_fxval&) \
+ DECL_ASN_OP_T(op,const sc_fxval_fast&) \
+ DECL_ASN_OP_T(op,const sc_fxnum&) \
+ DECL_ASN_OP_T(op,const sc_fxnum_fast&) \
+ DECL_ASN_OP_OTHER(op)
+
+ DECL_ASN_OP(=)
+
+ DECL_ASN_OP(*=)
+ DECL_ASN_OP(/=)
+ DECL_ASN_OP(+=)
+ DECL_ASN_OP(-=)
+
+ DECL_ASN_OP_T(<<=,int)
+ DECL_ASN_OP_T(>>=,int)
+
+#undef DECL_ASN_OP_T
+#undef DECL_ASN_OP_OTHER
+#undef DECL_ASN_OP
+
+
+ // auto-increment and auto-decrement
+
+ const sc_fxval operator ++ ( int );
+ const sc_fxval operator -- ( int );
+
+ sc_fxnum& operator ++ ();
+ sc_fxnum& operator -- ();
+
+
+ // bit selection
+
+ const sc_fxnum_bitref operator [] ( int ) const;
+ sc_fxnum_bitref operator [] ( int );
+
+ const sc_fxnum_bitref bit( int ) const;
+ sc_fxnum_bitref bit( int );
+
+
+ // part selection
+
+ const sc_fxnum_subref operator () ( int, int ) const;
+ sc_fxnum_subref operator () ( int, int );
+
+ const sc_fxnum_subref range( int, int ) const;
+ sc_fxnum_subref range( int, int );
+
+
+ const sc_fxnum_subref operator () () const;
+ sc_fxnum_subref operator () ();
+
+ const sc_fxnum_subref range() const;
+ sc_fxnum_subref range();
+
+
+ // implicit conversion
+
+ operator double() const; // necessary evil!
+
+
+ // explicit conversion to primitive types
+
+ short to_short() const;
+ unsigned short to_ushort() const;
+ int to_int() const;
+ unsigned int to_uint() const;
+ long to_long() const;
+ unsigned long to_ulong() const;
+ int64 to_int64() const;
+ uint64 to_uint64() const;
+ float to_float() const;
+ double to_double() const;
+
+
+ // explicit conversion to character string
+
+ const std::string to_string() const;
+ const std::string to_string( sc_numrep ) const;
+ const std::string to_string( sc_numrep, bool ) const;
+ const std::string to_string( sc_fmt ) const;
+ const std::string to_string( sc_numrep, sc_fmt ) const;
+ const std::string to_string( sc_numrep, bool, sc_fmt ) const;
+
+ const std::string to_dec() const;
+ const std::string to_bin() const;
+ const std::string to_oct() const;
+ const std::string to_hex() const;
+
+
+ // query value
+
+ bool is_neg() const;
+ bool is_zero() const;
+
+ // internal use only;
+ bool is_normal() const;
+
+ bool quantization_flag() const;
+ bool overflow_flag() const;
+
+ const sc_fxval value() const;
+
+
+ // query parameters
+
+ int wl() const;
+ int iwl() const;
+ sc_q_mode q_mode() const;
+ sc_o_mode o_mode() const;
+ int n_bits() const;
+
+ const sc_fxtype_params& type_params() const;
+
+ const sc_fxcast_switch& cast_switch() const;
+
+
+ // print or dump content
+
+ void print( ::std::ostream& = ::std::cout ) const;
+ void scan( ::std::istream& = ::std::cin );
+ void dump( ::std::ostream& = ::std::cout ) const;
+
+
+ // internal use only;
+ void observer_read() const;
+
+
+ // internal use only;
+ bool get_bit( int ) const;
+
+protected:
+
+ bool set_bit( int, bool );
+
+
+ bool get_slice( int, int, sc_bv_base& ) const;
+ bool set_slice( int, int, const sc_bv_base& );
+
+
+ sc_fxnum_observer* lock_observer() const;
+ void unlock_observer( sc_fxnum_observer* ) const;
+
+private:
+
+ scfx_rep* m_rep;
+
+ scfx_params m_params;
+ bool m_q_flag;
+ bool m_o_flag;
+
+ mutable sc_fxnum_observer* m_observer;
+
+private:
+
+ // disabled
+ sc_fxnum();
+ sc_fxnum( const sc_fxnum& );
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxnum_fast
+//
+// Base class for the fixed-point types; limited precision.
+// ----------------------------------------------------------------------------
+
+class sc_fxnum_fast
+{
+ friend class sc_fxval_fast;
+
+ friend class sc_fxnum_bitref;
+ friend class sc_fxnum_subref;
+ friend class sc_fxnum_fast_bitref;
+ friend class sc_fxnum_fast_subref;
+
+ friend class sc_core::vcd_sc_fxnum_fast_trace;
+ friend class sc_core::wif_sc_fxnum_fast_trace;
+
+protected:
+
+ sc_fxnum_fast_observer* observer() const;
+
+
+ void cast();
+
+
+ // constructors
+
+ sc_fxnum_fast( const sc_fxtype_params&,
+ sc_enc,
+ const sc_fxcast_switch&,
+ sc_fxnum_fast_observer* );
+
+#define DECL_CTOR_T(tp) \
+ sc_fxnum_fast( tp, \
+ const sc_fxtype_params&, \
+ sc_enc, \
+ const sc_fxcast_switch&, \
+ sc_fxnum_fast_observer* );
+
+ DECL_CTOR_T(int)
+ DECL_CTOR_T(unsigned int)
+ DECL_CTOR_T(long)
+ DECL_CTOR_T(unsigned long)
+ DECL_CTOR_T(float)
+ DECL_CTOR_T(double)
+ DECL_CTOR_T(const char*)
+ DECL_CTOR_T(const sc_fxval&)
+ DECL_CTOR_T(const sc_fxval_fast&)
+ DECL_CTOR_T(const sc_fxnum&)
+ DECL_CTOR_T(const sc_fxnum_fast&)
+#ifndef SC_FX_EXCLUDE_OTHER
+ DECL_CTOR_T(int64)
+ DECL_CTOR_T(uint64)
+ DECL_CTOR_T(const sc_int_base&)
+ DECL_CTOR_T(const sc_uint_base&)
+ DECL_CTOR_T(const sc_signed&)
+ DECL_CTOR_T(const sc_unsigned&)
+#endif
+
+#undef DECL_CTOR_T
+
+ ~sc_fxnum_fast();
+
+
+ // internal use only;
+ double get_val() const;
+
+public:
+
+ // unary operators
+
+ const sc_fxval_fast operator - () const;
+ const sc_fxval_fast operator + () const;
+
+
+ // unary functions
+
+ friend void neg( sc_fxval_fast&, const sc_fxnum_fast& );
+ friend void neg( sc_fxnum_fast&, const sc_fxnum_fast& );
+
+
+ // binary operators
+
+#define DECL_BIN_OP_T(op,tp) \
+ friend const sc_fxval_fast operator op ( const sc_fxnum_fast&, tp ); \
+ friend const sc_fxval_fast operator op ( tp, const sc_fxnum_fast& );
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DECL_BIN_OP_OTHER(op) \
+ DECL_BIN_OP_T(op,int64) \
+ DECL_BIN_OP_T(op,uint64) \
+ DECL_BIN_OP_T(op,const sc_int_base&) \
+ DECL_BIN_OP_T(op,const sc_uint_base&) \
+ DECL_BIN_OP_T(op,const sc_signed&) \
+ DECL_BIN_OP_T(op,const sc_unsigned&)
+#else
+#define DECL_BIN_OP_OTHER(op)
+#endif
+
+#define DECL_BIN_OP(op,dummy) \
+ friend const sc_fxval_fast operator op ( const sc_fxnum_fast&, \
+ const sc_fxnum_fast& ); \
+ DECL_BIN_OP_T(op,int) \
+ DECL_BIN_OP_T(op,unsigned int) \
+ DECL_BIN_OP_T(op,long) \
+ DECL_BIN_OP_T(op,unsigned long) \
+ DECL_BIN_OP_T(op,float) \
+ DECL_BIN_OP_T(op,double) \
+ DECL_BIN_OP_T(op,const char*) \
+ DECL_BIN_OP_T(op,const sc_fxval_fast&) \
+ DECL_BIN_OP_OTHER(op)
+
+ DECL_BIN_OP(*,mult)
+ DECL_BIN_OP(+,add)
+ DECL_BIN_OP(-,sub)
+// DECL_BIN_OP(/,div)
+ friend const sc_fxval_fast operator / ( const sc_fxnum_fast&,
+ const sc_fxnum_fast& );
+ DECL_BIN_OP_T(/,int)
+ DECL_BIN_OP_T(/,unsigned int)
+ DECL_BIN_OP_T(/,long)
+ DECL_BIN_OP_T(/,unsigned long)
+ DECL_BIN_OP_T(/,float)
+ DECL_BIN_OP_T(/,double)
+ DECL_BIN_OP_T(/,const char*)
+ DECL_BIN_OP_T(/,const sc_fxval_fast&)
+// DECL_BIN_OP_OTHER(op)
+#ifndef SC_FX_EXCLUDE_OTHER
+ DECL_BIN_OP_T(/,int64) \
+ DECL_BIN_OP_T(/,uint64) \
+ DECL_BIN_OP_T(/,const sc_int_base&) \
+ DECL_BIN_OP_T(/,const sc_uint_base&) \
+ DECL_BIN_OP_T(/,const sc_signed&) \
+ DECL_BIN_OP_T(/,const sc_unsigned&)
+#endif
+
+#undef DECL_BIN_OP_T
+#undef DECL_BIN_OP_OTHER
+#undef DECL_BIN_OP
+
+ friend const sc_fxval_fast operator << ( const sc_fxnum_fast&, int );
+ friend const sc_fxval_fast operator >> ( const sc_fxnum_fast&, int );
+
+
+ // binary functions
+
+#define DECL_BIN_FNC_T(fnc,tp) \
+ friend void fnc ( sc_fxval_fast&, const sc_fxnum_fast&, tp ); \
+ friend void fnc ( sc_fxval_fast&, tp, const sc_fxnum_fast& ); \
+ friend void fnc ( sc_fxnum_fast&, const sc_fxnum_fast&, tp ); \
+ friend void fnc ( sc_fxnum_fast&, tp, const sc_fxnum_fast& );
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DECL_BIN_FNC_OTHER(fnc) \
+ DECL_BIN_FNC_T(fnc,int64) \
+ DECL_BIN_FNC_T(fnc,uint64) \
+ DECL_BIN_FNC_T(fnc,const sc_int_base&) \
+ DECL_BIN_FNC_T(fnc,const sc_uint_base&) \
+ DECL_BIN_FNC_T(fnc,const sc_signed&) \
+ DECL_BIN_FNC_T(fnc,const sc_unsigned&)
+#else
+#define DECL_BIN_FNC_OTHER(fnc)
+#endif
+
+#define DECL_BIN_FNC(fnc) \
+ friend void fnc ( sc_fxval_fast&, const sc_fxnum_fast&, \
+ const sc_fxnum_fast& ); \
+ friend void fnc ( sc_fxnum_fast&, const sc_fxnum_fast&, \
+ const sc_fxnum_fast& ); \
+ DECL_BIN_FNC_T(fnc,int) \
+ DECL_BIN_FNC_T(fnc,unsigned int) \
+ DECL_BIN_FNC_T(fnc,long) \
+ DECL_BIN_FNC_T(fnc,unsigned long) \
+ DECL_BIN_FNC_T(fnc,float) \
+ DECL_BIN_FNC_T(fnc,double) \
+ DECL_BIN_FNC_T(fnc,const char*) \
+ DECL_BIN_FNC_T(fnc,const sc_fxval&) \
+ DECL_BIN_FNC_T(fnc,const sc_fxval_fast&) \
+ DECL_BIN_FNC_T(fnc,const sc_fxnum&) \
+ DECL_BIN_FNC_OTHER(fnc)
+
+ DECL_BIN_FNC(mult)
+ DECL_BIN_FNC(div)
+ DECL_BIN_FNC(add)
+ DECL_BIN_FNC(sub)
+
+#undef DECL_BIN_FNC_T
+#undef DECL_BIN_FNC_OTHER
+#undef DECL_BIN_FNC
+
+ friend void lshift( sc_fxval_fast&, const sc_fxnum_fast&, int );
+ friend void rshift( sc_fxval_fast&, const sc_fxnum_fast&, int );
+ friend void lshift( sc_fxnum_fast&, const sc_fxnum_fast&, int );
+ friend void rshift( sc_fxnum_fast&, const sc_fxnum_fast&, int );
+
+
+ // relational (including equality) operators
+
+#define DECL_REL_OP_T(op,tp) \
+ friend bool operator op ( const sc_fxnum_fast&, tp ); \
+ friend bool operator op ( tp, const sc_fxnum_fast& );
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DECL_REL_OP_OTHER(op) \
+ DECL_REL_OP_T(op,int64) \
+ DECL_REL_OP_T(op,uint64) \
+ DECL_REL_OP_T(op,const sc_int_base&) \
+ DECL_REL_OP_T(op,const sc_uint_base&) \
+ DECL_REL_OP_T(op,const sc_signed&) \
+ DECL_REL_OP_T(op,const sc_unsigned&)
+#else
+#define DECL_REL_OP_OTHER(op)
+#endif
+
+#define DECL_REL_OP(op) \
+ friend bool operator op ( const sc_fxnum_fast&, const sc_fxnum_fast& ); \
+ DECL_REL_OP_T(op,int) \
+ DECL_REL_OP_T(op,unsigned int) \
+ DECL_REL_OP_T(op,long) \
+ DECL_REL_OP_T(op,unsigned long) \
+ DECL_REL_OP_T(op,float) \
+ DECL_REL_OP_T(op,double) \
+ DECL_REL_OP_T(op,const char*) \
+ DECL_REL_OP_T(op,const sc_fxval_fast&) \
+ DECL_REL_OP_OTHER(op)
+
+ DECL_REL_OP(<)
+ DECL_REL_OP(<=)
+ DECL_REL_OP(>)
+ DECL_REL_OP(>=)
+ DECL_REL_OP(==)
+ DECL_REL_OP(!=)
+
+#undef DECL_REL_OP_T
+#undef DECL_REL_OP_OTHER
+#undef DECL_REL_OP
+
+
+ // assignment operators
+
+#define DECL_ASN_OP_T(op,tp) \
+ sc_fxnum_fast& operator op( tp );
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DECL_ASN_OP_OTHER(op) \
+ DECL_ASN_OP_T(op,int64) \
+ DECL_ASN_OP_T(op,uint64) \
+ DECL_ASN_OP_T(op,const sc_int_base&) \
+ DECL_ASN_OP_T(op,const sc_uint_base&) \
+ DECL_ASN_OP_T(op,const sc_signed&) \
+ DECL_ASN_OP_T(op,const sc_unsigned&)
+#else
+#define DECL_ASN_OP_OTHER(op)
+#endif
+
+#define DECL_ASN_OP(op) \
+ DECL_ASN_OP_T(op,int) \
+ DECL_ASN_OP_T(op,unsigned int) \
+ DECL_ASN_OP_T(op,long) \
+ DECL_ASN_OP_T(op,unsigned long) \
+ DECL_ASN_OP_T(op,float) \
+ DECL_ASN_OP_T(op,double) \
+ DECL_ASN_OP_T(op,const char*) \
+ DECL_ASN_OP_T(op,const sc_fxval&) \
+ DECL_ASN_OP_T(op,const sc_fxval_fast&) \
+ DECL_ASN_OP_T(op,const sc_fxnum&) \
+ DECL_ASN_OP_T(op,const sc_fxnum_fast&) \
+ DECL_ASN_OP_OTHER(op)
+
+ DECL_ASN_OP(=)
+
+ DECL_ASN_OP(*=)
+ DECL_ASN_OP(/=)
+ DECL_ASN_OP(+=)
+ DECL_ASN_OP(-=)
+
+ DECL_ASN_OP_T(<<=,int)
+ DECL_ASN_OP_T(>>=,int)
+
+#undef DECL_ASN_OP_T
+#undef DECL_ASN_OP_OTHER
+#undef DECL_ASN_OP
+
+
+ // auto-increment and auto-decrement
+
+ const sc_fxval_fast operator ++ ( int );
+ const sc_fxval_fast operator -- ( int );
+
+ sc_fxnum_fast& operator ++ ();
+ sc_fxnum_fast& operator -- ();
+
+
+ // bit selection
+
+ const sc_fxnum_fast_bitref operator [] ( int ) const;
+ sc_fxnum_fast_bitref operator [] ( int );
+
+ const sc_fxnum_fast_bitref bit( int ) const;
+ sc_fxnum_fast_bitref bit( int );
+
+
+ // part selection
+
+ const sc_fxnum_fast_subref operator () ( int, int ) const;
+ sc_fxnum_fast_subref operator () ( int, int );
+
+ const sc_fxnum_fast_subref range( int, int ) const;
+ sc_fxnum_fast_subref range( int, int );
+
+
+ const sc_fxnum_fast_subref operator () () const;
+ sc_fxnum_fast_subref operator () ();
+
+ const sc_fxnum_fast_subref range() const;
+ sc_fxnum_fast_subref range();
+
+
+ // implicit conversion
+
+ operator double() const; // necessary evil!
+
+
+ // explicit conversion to primitive types
+
+ short to_short() const;
+ unsigned short to_ushort() const;
+ int to_int() const;
+ unsigned int to_uint() const;
+ long to_long() const;
+ unsigned long to_ulong() const;
+ int64 to_int64() const;
+ uint64 to_uint64() const;
+ float to_float() const;
+ double to_double() const;
+
+
+ // explicit conversion to character string
+
+ const std::string to_string() const;
+ const std::string to_string( sc_numrep ) const;
+ const std::string to_string( sc_numrep, bool ) const;
+ const std::string to_string( sc_fmt ) const;
+ const std::string to_string( sc_numrep, sc_fmt ) const;
+ const std::string to_string( sc_numrep, bool, sc_fmt ) const;
+
+ const std::string to_dec() const;
+ const std::string to_bin() const;
+ const std::string to_oct() const;
+ const std::string to_hex() const;
+
+
+ // query value
+
+ bool is_neg() const;
+ bool is_zero() const;
+
+ // internal use only;
+ bool is_normal() const;
+
+ bool quantization_flag() const;
+ bool overflow_flag() const;
+
+ const sc_fxval_fast value() const;
+
+
+ // query parameters
+
+ int wl() const;
+ int iwl() const;
+ sc_q_mode q_mode() const;
+ sc_o_mode o_mode() const;
+ int n_bits() const;
+
+ const sc_fxtype_params& type_params() const;
+
+ const sc_fxcast_switch& cast_switch() const;
+
+
+ // print or dump content
+
+ void print( ::std::ostream& = ::std::cout ) const;
+ void scan( ::std::istream& = ::std::cin );
+ void dump( ::std::ostream& = ::std::cout ) const;
+
+
+ // internal use only;
+ void observer_read() const;
+
+
+ // internal use only;
+ bool get_bit( int ) const;
+
+protected:
+
+ bool set_bit( int, bool );
+
+
+ bool get_slice( int, int, sc_bv_base& ) const;
+ bool set_slice( int, int, const sc_bv_base& );
+
+
+ sc_fxnum_fast_observer* lock_observer() const;
+ void unlock_observer( sc_fxnum_fast_observer* ) const;
+
+private:
+
+ double m_val;
+
+ scfx_params m_params;
+ bool m_q_flag;
+ bool m_o_flag;
+
+ mutable sc_fxnum_fast_observer* m_observer;
+
+private:
+
+ // disabled
+ sc_fxnum_fast();
+ sc_fxnum_fast( const sc_fxnum_fast& );
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxnum_bitref
+//
+// Proxy class for bit-selection in class sc_fxnum, behaves like sc_bit.
+// ----------------------------------------------------------------------------
+
+// constructor
+
+inline
+sc_fxnum_bitref::sc_fxnum_bitref( sc_fxnum& num_, int idx_ )
+ : m_num( num_ ), m_idx( idx_ )
+{}
+
+
+// copy constructor
+
+inline
+sc_fxnum_bitref::sc_fxnum_bitref( const sc_fxnum_bitref& a )
+ : m_num( a.m_num ), m_idx( a.m_idx )
+{}
+
+
+// assignment operators
+
+inline
+sc_fxnum_bitref&
+sc_fxnum_bitref::operator = ( const sc_fxnum_bitref& a )
+{
+ if( &a != this )
+ {
+ SC_FXNUM_OBSERVER_READ_( a.m_num )
+ set( a.get() );
+ SC_FXNUM_OBSERVER_WRITE_( m_num )
+ }
+ return *this;
+}
+
+inline
+sc_fxnum_bitref&
+sc_fxnum_bitref::operator = ( const sc_fxnum_fast_bitref& a )
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( a.m_num )
+ set( a.get() );
+ SC_FXNUM_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+inline
+sc_fxnum_bitref&
+sc_fxnum_bitref::operator = ( const sc_bit& a )
+{
+ set( static_cast<bool>( a ) );
+ SC_FXNUM_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+inline
+sc_fxnum_bitref&
+sc_fxnum_bitref::operator = ( bool a )
+{
+ set( a );
+ SC_FXNUM_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+
+inline
+sc_fxnum_bitref&
+sc_fxnum_bitref::operator &= ( const sc_fxnum_bitref& b )
+{
+ SC_FXNUM_OBSERVER_READ_( m_num )
+ SC_FXNUM_OBSERVER_READ_( b.m_num )
+ set( get() && b.get() );
+ SC_FXNUM_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+inline
+sc_fxnum_bitref&
+sc_fxnum_bitref::operator &= ( const sc_fxnum_fast_bitref& b )
+{
+ SC_FXNUM_OBSERVER_READ_( m_num )
+ SC_FXNUM_FAST_OBSERVER_READ_( b.m_num )
+ set( get() && b.get() );
+ SC_FXNUM_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+inline
+sc_fxnum_bitref&
+sc_fxnum_bitref::operator &= ( const sc_bit& b )
+{
+ SC_FXNUM_OBSERVER_READ_( m_num )
+ set( get() && static_cast<bool>( b ) );
+ SC_FXNUM_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+inline
+sc_fxnum_bitref&
+sc_fxnum_bitref::operator &= ( bool b )
+{
+ SC_FXNUM_OBSERVER_READ_( m_num )
+ set( get() && b );
+ SC_FXNUM_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+
+inline
+sc_fxnum_bitref&
+sc_fxnum_bitref::operator |= ( const sc_fxnum_bitref& b )
+{
+ SC_FXNUM_OBSERVER_READ_( m_num )
+ SC_FXNUM_OBSERVER_READ_( b.m_num )
+ set( get() || b.get() );
+ SC_FXNUM_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+inline
+sc_fxnum_bitref&
+sc_fxnum_bitref::operator |= ( const sc_fxnum_fast_bitref& b )
+{
+ SC_FXNUM_OBSERVER_READ_( m_num )
+ SC_FXNUM_FAST_OBSERVER_READ_( b.m_num )
+ set( get() || b.get() );
+ SC_FXNUM_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+inline
+sc_fxnum_bitref&
+sc_fxnum_bitref::operator |= ( const sc_bit& b )
+{
+ SC_FXNUM_OBSERVER_READ_( m_num )
+ set( get() || static_cast<bool>( b ) );
+ SC_FXNUM_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+inline
+sc_fxnum_bitref&
+sc_fxnum_bitref::operator |= ( bool b )
+{
+ SC_FXNUM_OBSERVER_READ_( m_num )
+ set( get() || b );
+ SC_FXNUM_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+
+inline
+sc_fxnum_bitref&
+sc_fxnum_bitref::operator ^= ( const sc_fxnum_bitref& b )
+{
+ SC_FXNUM_OBSERVER_READ_( m_num )
+ SC_FXNUM_OBSERVER_READ_( b.m_num )
+ set( get() != b.get() );
+ SC_FXNUM_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+inline
+sc_fxnum_bitref&
+sc_fxnum_bitref::operator ^= ( const sc_fxnum_fast_bitref& b )
+{
+ SC_FXNUM_OBSERVER_READ_( m_num )
+ SC_FXNUM_FAST_OBSERVER_READ_( b.m_num )
+ set( get() != b.get() );
+ SC_FXNUM_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+inline
+sc_fxnum_bitref&
+sc_fxnum_bitref::operator ^= ( const sc_bit& b )
+{
+ SC_FXNUM_OBSERVER_READ_( m_num )
+ set( get() != static_cast<bool>( b ) );
+ SC_FXNUM_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+inline
+sc_fxnum_bitref&
+sc_fxnum_bitref::operator ^= ( bool b )
+{
+ SC_FXNUM_OBSERVER_READ_( m_num )
+ set( get() != b );
+ SC_FXNUM_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+
+// implicit conversion
+
+inline
+sc_fxnum_bitref::operator bool() const
+{
+ SC_FXNUM_OBSERVER_READ_( m_num )
+ return get();
+}
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, const sc_fxnum_bitref& a )
+{
+ a.print( os );
+ return os;
+}
+
+inline
+::std::istream&
+operator >> ( ::std::istream& is, sc_fxnum_bitref& a )
+{
+ a.scan( is );
+ return is;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxnum_fast_bitref
+//
+// Proxy class for bit-selection in class sc_fxnum_fast, behaves like sc_bit.
+// ----------------------------------------------------------------------------
+
+// constructor
+
+inline
+sc_fxnum_fast_bitref::sc_fxnum_fast_bitref( sc_fxnum_fast& num_, int idx_ )
+ : m_num( num_ ), m_idx( idx_ )
+{}
+
+
+// copy constructor
+
+inline
+sc_fxnum_fast_bitref::sc_fxnum_fast_bitref( const sc_fxnum_fast_bitref& a )
+ : m_num( a.m_num ), m_idx( a.m_idx )
+{}
+
+
+// assignment operators
+
+inline
+sc_fxnum_fast_bitref&
+sc_fxnum_fast_bitref::operator = ( const sc_fxnum_bitref& a )
+{
+ SC_FXNUM_OBSERVER_READ_( a.m_num )
+ set( a.get() );
+ SC_FXNUM_FAST_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+inline
+sc_fxnum_fast_bitref&
+sc_fxnum_fast_bitref::operator = ( const sc_fxnum_fast_bitref& a )
+{
+ if( &a != this )
+ {
+ SC_FXNUM_FAST_OBSERVER_READ_( a.m_num )
+ set( a.get() );
+ SC_FXNUM_FAST_OBSERVER_WRITE_( m_num )
+ }
+ return *this;
+}
+
+inline
+sc_fxnum_fast_bitref&
+sc_fxnum_fast_bitref::operator = ( const sc_bit& a )
+{
+ set( static_cast<bool>( a ) );
+ SC_FXNUM_FAST_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+inline
+sc_fxnum_fast_bitref&
+sc_fxnum_fast_bitref::operator = ( bool a )
+{
+ set( a );
+ SC_FXNUM_FAST_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+
+inline
+sc_fxnum_fast_bitref&
+sc_fxnum_fast_bitref::operator &= ( const sc_fxnum_bitref& b )
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( m_num )
+ SC_FXNUM_OBSERVER_READ_( b.m_num )
+ set( get() && b.get() );
+ SC_FXNUM_FAST_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+inline
+sc_fxnum_fast_bitref&
+sc_fxnum_fast_bitref::operator &= ( const sc_fxnum_fast_bitref& b )
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( m_num )
+ SC_FXNUM_FAST_OBSERVER_READ_( b.m_num )
+ set( get() && b.get() );
+ SC_FXNUM_FAST_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+inline
+sc_fxnum_fast_bitref&
+sc_fxnum_fast_bitref::operator &= ( const sc_bit& b )
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( m_num )
+ set( get() && static_cast<bool>( b ) );
+ SC_FXNUM_FAST_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+inline
+sc_fxnum_fast_bitref&
+sc_fxnum_fast_bitref::operator &= ( bool b )
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( m_num )
+ set( get() && b );
+ SC_FXNUM_FAST_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+
+inline
+sc_fxnum_fast_bitref&
+sc_fxnum_fast_bitref::operator |= ( const sc_fxnum_bitref& b )
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( m_num )
+ SC_FXNUM_OBSERVER_READ_( b.m_num )
+ set( get() || b.get() );
+ SC_FXNUM_FAST_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+inline
+sc_fxnum_fast_bitref&
+sc_fxnum_fast_bitref::operator |= ( const sc_fxnum_fast_bitref& b )
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( m_num )
+ SC_FXNUM_FAST_OBSERVER_READ_( b.m_num )
+ set( get() || b.get() );
+ SC_FXNUM_FAST_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+inline
+sc_fxnum_fast_bitref&
+sc_fxnum_fast_bitref::operator |= ( const sc_bit& b )
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( m_num )
+ set( get() || static_cast<bool>( b ) );
+ SC_FXNUM_FAST_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+inline
+sc_fxnum_fast_bitref&
+sc_fxnum_fast_bitref::operator |= ( bool b )
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( m_num )
+ set( get() || b );
+ SC_FXNUM_FAST_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+
+inline
+sc_fxnum_fast_bitref&
+sc_fxnum_fast_bitref::operator ^= ( const sc_fxnum_bitref& b )
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( m_num )
+ SC_FXNUM_OBSERVER_READ_( b.m_num )
+ set( get() != b.get() );
+ SC_FXNUM_FAST_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+inline
+sc_fxnum_fast_bitref&
+sc_fxnum_fast_bitref::operator ^= ( const sc_fxnum_fast_bitref& b )
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( m_num )
+ SC_FXNUM_FAST_OBSERVER_READ_( b.m_num )
+ set( get() != b.get() );
+ SC_FXNUM_FAST_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+inline
+sc_fxnum_fast_bitref&
+sc_fxnum_fast_bitref::operator ^= ( const sc_bit& b )
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( m_num )
+ set( get() != static_cast<bool>( b ) );
+ SC_FXNUM_FAST_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+inline
+sc_fxnum_fast_bitref&
+sc_fxnum_fast_bitref::operator ^= ( bool b )
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( m_num )
+ set( get() != b );
+ SC_FXNUM_FAST_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+
+// implicit conversion
+
+inline
+sc_fxnum_fast_bitref::operator bool() const
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( m_num )
+ return get();
+}
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, const sc_fxnum_fast_bitref& a )
+{
+ a.print( os );
+ return os;
+}
+
+inline
+::std::istream&
+operator >> ( ::std::istream& is, sc_fxnum_fast_bitref& a )
+{
+ a.scan( is );
+ return is;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxnum_subref
+//
+// Proxy class for part-selection in class sc_fxnum,
+// behaves like sc_bv_base.
+// ----------------------------------------------------------------------------
+
+// constructor
+
+inline
+sc_fxnum_subref::sc_fxnum_subref( sc_fxnum& num_, int from_, int to_ )
+ : m_num( num_ ), m_from( from_ ), m_to( to_ ),
+ m_bv( *new sc_bv_base( sc_max( m_from, m_to ) -
+ sc_min( m_from, m_to ) + 1 ) )
+{}
+
+
+// copy constructor
+
+inline
+sc_fxnum_subref::sc_fxnum_subref( const sc_fxnum_subref& a )
+ : m_num( a.m_num ), m_from( a.m_from ), m_to( a.m_to ),
+ m_bv( *new sc_bv_base( a.m_bv ) )
+{}
+
+
+// destructor
+
+inline
+sc_fxnum_subref::~sc_fxnum_subref()
+{
+ delete &m_bv;
+}
+
+
+// assignment operators
+
+inline
+sc_fxnum_subref&
+sc_fxnum_subref::operator = ( const sc_fxnum_subref& a )
+{
+ if( &a != this )
+ {
+ m_bv = static_cast<sc_bv_base>( a );
+ set();
+ SC_FXNUM_OBSERVER_WRITE_( m_num )
+ }
+ return *this;
+}
+
+inline
+sc_fxnum_subref&
+sc_fxnum_subref::operator = ( const sc_fxnum_fast_subref& a )
+{
+ m_bv = static_cast<sc_bv_base>( a );
+ set();
+ SC_FXNUM_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+#define DEFN_ASN_OP_T(tp) \
+inline \
+sc_fxnum_subref& \
+sc_fxnum_subref::operator = ( tp a ) \
+{ \
+ m_bv = a; \
+ set(); \
+ SC_FXNUM_OBSERVER_WRITE_( m_num ) \
+ return *this; \
+}
+
+DEFN_ASN_OP_T(const sc_bv_base&)
+DEFN_ASN_OP_T(const sc_lv_base&)
+DEFN_ASN_OP_T(const char*)
+DEFN_ASN_OP_T(const bool*)
+DEFN_ASN_OP_T(const sc_signed&)
+DEFN_ASN_OP_T(const sc_unsigned&)
+DEFN_ASN_OP_T(const sc_int_base&)
+DEFN_ASN_OP_T(const sc_uint_base&)
+DEFN_ASN_OP_T(int64)
+DEFN_ASN_OP_T(uint64)
+DEFN_ASN_OP_T(int)
+DEFN_ASN_OP_T(unsigned int)
+DEFN_ASN_OP_T(long)
+DEFN_ASN_OP_T(unsigned long)
+DEFN_ASN_OP_T(char)
+
+#undef DEFN_ASN_OP_T
+
+
+#define DEFN_ASN_OP_T(op,tp) \
+inline \
+sc_fxnum_subref& \
+sc_fxnum_subref::operator op ## = ( tp a ) \
+{ \
+ SC_FXNUM_OBSERVER_READ_( m_num ) \
+ get(); \
+ m_bv = m_bv op a; \
+ set(); \
+ SC_FXNUM_OBSERVER_WRITE_( m_num ) \
+ return *this; \
+}
+
+#define DEFN_ASN_OP(op) \
+inline \
+sc_fxnum_subref& \
+sc_fxnum_subref::operator op ## = ( const sc_fxnum_subref& a ) \
+{ \
+ SC_FXNUM_OBSERVER_READ_( m_num ) \
+ get(); \
+ m_bv = m_bv op static_cast<sc_bv_base>( a ); \
+ set(); \
+ SC_FXNUM_OBSERVER_WRITE_( m_num ) \
+ return *this; \
+} \
+ \
+inline \
+sc_fxnum_subref& \
+sc_fxnum_subref::operator op ## = ( const sc_fxnum_fast_subref& a ) \
+{ \
+ SC_FXNUM_OBSERVER_READ_( m_num ) \
+ get(); \
+ m_bv = m_bv op static_cast<sc_bv_base>( a ); \
+ set(); \
+ SC_FXNUM_OBSERVER_WRITE_( m_num ) \
+ return *this; \
+} \
+ \
+DEFN_ASN_OP_T(op,const sc_bv_base&) \
+DEFN_ASN_OP_T(op,const sc_lv_base&)
+
+DEFN_ASN_OP(&)
+DEFN_ASN_OP(|)
+DEFN_ASN_OP(^)
+
+#undef DEFN_ASN_OP_T
+#undef DEFN_ASN_OP
+
+
+// relational operators
+
+#define DEFN_REL_OP_T(op,tp) \
+inline \
+bool \
+operator op ( const sc_fxnum_subref& a, tp b ) \
+{ \
+ return ( static_cast<sc_bv_base>( a ) op b ); \
+} \
+ \
+inline \
+bool \
+operator op ( tp a, const sc_fxnum_subref& b ) \
+{ \
+ return ( static_cast<sc_bv_base>( b ) op a ); \
+}
+
+#define DEFN_REL_OP(op) \
+inline \
+bool \
+operator op ( const sc_fxnum_subref& a, const sc_fxnum_subref& b ) \
+{ \
+ return ( static_cast<sc_bv_base>( a ) op static_cast<sc_bv_base>( b ) ); \
+} \
+ \
+inline \
+bool \
+operator op ( const sc_fxnum_subref& a, const sc_fxnum_fast_subref& b ) \
+{ \
+ return ( static_cast<sc_bv_base>( a ) op static_cast<sc_bv_base>( b ) ); \
+} \
+ \
+DEFN_REL_OP_T(op,const sc_bv_base&) \
+DEFN_REL_OP_T(op,const sc_lv_base&) \
+DEFN_REL_OP_T(op,const char*) \
+DEFN_REL_OP_T(op,const bool*) \
+DEFN_REL_OP_T(op,const sc_signed&) \
+DEFN_REL_OP_T(op,const sc_unsigned&) \
+DEFN_REL_OP_T(op,int) \
+DEFN_REL_OP_T(op,unsigned int) \
+DEFN_REL_OP_T(op,long) \
+DEFN_REL_OP_T(op,unsigned long)
+
+DEFN_REL_OP(==)
+DEFN_REL_OP(!=)
+
+#undef DEFN_REL_OP_T
+#undef DEFN_REL_OP
+
+
+// reduce functions
+
+#define DEFN_RED_FNC(fnc) \
+inline \
+bool \
+sc_fxnum_subref::fnc() const \
+{ \
+ SC_FXNUM_OBSERVER_READ_( m_num ) \
+ get(); \
+ return static_cast<bool>( m_bv.fnc() ); \
+}
+
+DEFN_RED_FNC(and_reduce)
+DEFN_RED_FNC(nand_reduce)
+DEFN_RED_FNC(or_reduce)
+DEFN_RED_FNC(nor_reduce)
+DEFN_RED_FNC(xor_reduce)
+DEFN_RED_FNC(xnor_reduce)
+
+#undef DEFN_RED_FNC
+
+
+// query parameter
+
+inline
+int
+sc_fxnum_subref::length() const
+{
+ return m_bv.length();
+}
+
+
+// explicit conversions
+
+inline
+int
+sc_fxnum_subref::to_int() const
+{
+ SC_FXNUM_OBSERVER_READ_( m_num )
+ get();
+ return m_bv.to_int();
+}
+
+inline
+int64
+sc_fxnum_subref::to_int64() const
+{
+ SC_FXNUM_OBSERVER_READ_( m_num )
+ get();
+ return m_bv.to_int64();
+}
+
+inline
+unsigned int
+sc_fxnum_subref::to_uint() const
+{
+ SC_FXNUM_OBSERVER_READ_( m_num )
+ get();
+ return m_bv.to_uint();
+}
+
+inline
+uint64
+sc_fxnum_subref::to_uint64() const
+{
+ SC_FXNUM_OBSERVER_READ_( m_num )
+ get();
+ return m_bv.to_uint64();
+}
+
+inline
+long
+sc_fxnum_subref::to_long() const
+{
+ SC_FXNUM_OBSERVER_READ_( m_num )
+ get();
+ return m_bv.to_long();
+}
+
+inline
+unsigned long
+sc_fxnum_subref::to_ulong() const
+{
+ SC_FXNUM_OBSERVER_READ_( m_num )
+ get();
+ return m_bv.to_ulong();
+}
+
+
+#ifdef SC_DT_DEPRECATED
+
+inline
+int
+sc_fxnum_subref::to_signed() const
+{
+ return to_int();
+}
+
+inline
+unsigned int
+sc_fxnum_subref::to_unsigned() const
+{
+ return to_uint();
+}
+
+#endif
+
+
+inline
+const std::string
+sc_fxnum_subref::to_string() const
+{
+ get();
+ return m_bv.to_string();
+}
+
+inline
+const std::string
+sc_fxnum_subref::to_string( sc_numrep numrep ) const
+{
+ get();
+ return m_bv.to_string( numrep );
+}
+
+inline
+const std::string
+sc_fxnum_subref::to_string( sc_numrep numrep, bool w_prefix ) const
+{
+ get();
+ return m_bv.to_string( numrep, w_prefix );
+}
+
+
+// implicit conversion
+
+inline
+sc_fxnum_subref::operator sc_bv_base () const
+{
+ SC_FXNUM_OBSERVER_READ_( m_num )
+ get();
+ return m_bv;
+}
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, const sc_fxnum_subref& a )
+{
+ a.print( os );
+ return os;
+}
+
+inline
+::std::istream&
+operator >> ( ::std::istream& is, sc_fxnum_subref& a )
+{
+ a.scan( is );
+ return is;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxnum_fast_subref
+//
+// Proxy class for part-selection in class sc_fxnum_fast,
+// behaves like sc_bv_base.
+// ----------------------------------------------------------------------------
+
+// constructor
+
+inline
+sc_fxnum_fast_subref::sc_fxnum_fast_subref( sc_fxnum_fast& num_,
+ int from_, int to_ )
+ : m_num( num_ ), m_from( from_ ), m_to( to_ ),
+ m_bv( *new sc_bv_base( sc_max( m_from, m_to ) -
+ sc_min( m_from, m_to ) + 1 ) )
+{}
+
+
+// copy constructor
+
+inline
+sc_fxnum_fast_subref::sc_fxnum_fast_subref( const sc_fxnum_fast_subref& a )
+ : m_num( a.m_num ), m_from( a.m_from ), m_to( a.m_to ),
+ m_bv( *new sc_bv_base( a.m_bv ) )
+{}
+
+
+// destructor
+
+inline
+sc_fxnum_fast_subref::~sc_fxnum_fast_subref()
+{
+ delete &m_bv;
+}
+
+
+// assignment operators
+
+inline
+sc_fxnum_fast_subref&
+sc_fxnum_fast_subref::operator = ( const sc_fxnum_subref& a )
+{
+ m_bv = static_cast<sc_bv_base>( a );
+ set();
+ SC_FXNUM_FAST_OBSERVER_WRITE_( m_num )
+ return *this;
+}
+
+inline
+sc_fxnum_fast_subref&
+sc_fxnum_fast_subref::operator = ( const sc_fxnum_fast_subref& a )
+{
+ if( &a != this )
+ {
+ m_bv = static_cast<sc_bv_base>( a );
+ set();
+ SC_FXNUM_FAST_OBSERVER_WRITE_( m_num )
+ }
+ return *this;
+}
+
+#define DEFN_ASN_OP_T(tp) \
+inline \
+sc_fxnum_fast_subref& \
+sc_fxnum_fast_subref::operator = ( tp a ) \
+{ \
+ m_bv = a; \
+ set(); \
+ SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) \
+ return *this; \
+}
+
+DEFN_ASN_OP_T(const sc_bv_base&)
+DEFN_ASN_OP_T(const sc_lv_base&)
+DEFN_ASN_OP_T(const char*)
+DEFN_ASN_OP_T(const bool*)
+DEFN_ASN_OP_T(const sc_signed&)
+DEFN_ASN_OP_T(const sc_unsigned&)
+DEFN_ASN_OP_T(const sc_int_base&)
+DEFN_ASN_OP_T(const sc_uint_base&)
+DEFN_ASN_OP_T(int64)
+DEFN_ASN_OP_T(uint64)
+DEFN_ASN_OP_T(int)
+DEFN_ASN_OP_T(unsigned int)
+DEFN_ASN_OP_T(long)
+DEFN_ASN_OP_T(unsigned long)
+DEFN_ASN_OP_T(char)
+
+#undef DEFN_ASN_OP_T
+
+
+#define DEFN_ASN_OP_T(op,tp) \
+inline \
+sc_fxnum_fast_subref& \
+sc_fxnum_fast_subref::operator op ## = ( tp a ) \
+{ \
+ SC_FXNUM_FAST_OBSERVER_READ_( m_num ) \
+ get(); \
+ m_bv = m_bv op a; \
+ set(); \
+ SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) \
+ return *this; \
+}
+
+#define DEFN_ASN_OP(op) \
+inline \
+sc_fxnum_fast_subref& \
+sc_fxnum_fast_subref::operator op ## = ( const sc_fxnum_subref& a ) \
+{ \
+ SC_FXNUM_FAST_OBSERVER_READ_( m_num ) \
+ get(); \
+ m_bv = m_bv op static_cast<sc_bv_base>( a ); \
+ set(); \
+ SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) \
+ return *this; \
+} \
+ \
+inline \
+sc_fxnum_fast_subref& \
+sc_fxnum_fast_subref::operator op ## = ( const sc_fxnum_fast_subref& a ) \
+{ \
+ SC_FXNUM_FAST_OBSERVER_READ_( m_num ) \
+ get(); \
+ m_bv = m_bv op static_cast<sc_bv_base>( a ); \
+ set(); \
+ SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) \
+ return *this; \
+} \
+ \
+DEFN_ASN_OP_T(op,const sc_bv_base&) \
+DEFN_ASN_OP_T(op,const sc_lv_base&)
+
+DEFN_ASN_OP(&)
+DEFN_ASN_OP(|)
+DEFN_ASN_OP(^)
+
+#undef DEFN_ASN_OP_T
+#undef DEFN_ASN_OP
+
+
+// relational operators
+
+#define DEFN_REL_OP_T(op,tp) \
+inline \
+bool \
+operator op ( const sc_fxnum_fast_subref& a, tp b ) \
+{ \
+ return ( static_cast<sc_bv_base>( a ) op b ); \
+} \
+ \
+inline \
+bool \
+operator op ( tp a, const sc_fxnum_fast_subref& b ) \
+{ \
+ return ( static_cast<sc_bv_base>( b ) op a ); \
+}
+
+#define DEFN_REL_OP(op) \
+inline \
+bool \
+operator op ( const sc_fxnum_fast_subref& a, const sc_fxnum_fast_subref& b ) \
+{ \
+ return ( static_cast<sc_bv_base>( a ) op static_cast<sc_bv_base>( b ) ); \
+} \
+ \
+inline \
+bool \
+operator op ( const sc_fxnum_fast_subref& a, const sc_fxnum_subref& b ) \
+{ \
+ return ( static_cast<sc_bv_base>( a ) op static_cast<sc_bv_base>( b ) ); \
+} \
+ \
+DEFN_REL_OP_T(op,const sc_bv_base&) \
+DEFN_REL_OP_T(op,const sc_lv_base&) \
+DEFN_REL_OP_T(op,const char*) \
+DEFN_REL_OP_T(op,const bool*) \
+DEFN_REL_OP_T(op,const sc_signed&) \
+DEFN_REL_OP_T(op,const sc_unsigned&) \
+DEFN_REL_OP_T(op,int) \
+DEFN_REL_OP_T(op,unsigned int) \
+DEFN_REL_OP_T(op,long) \
+DEFN_REL_OP_T(op,unsigned long)
+
+DEFN_REL_OP(==)
+DEFN_REL_OP(!=)
+
+#undef DEFN_REL_OP_T
+#undef DEFN_REL_OP
+
+
+// reduce functions
+
+#define DEFN_RED_FNC(fnc) \
+inline \
+bool \
+sc_fxnum_fast_subref::fnc() const \
+{ \
+ SC_FXNUM_FAST_OBSERVER_READ_( m_num ) \
+ get(); \
+ return static_cast<bool>( m_bv.fnc() ); \
+}
+
+DEFN_RED_FNC(and_reduce)
+DEFN_RED_FNC(nand_reduce)
+DEFN_RED_FNC(or_reduce)
+DEFN_RED_FNC(nor_reduce)
+DEFN_RED_FNC(xor_reduce)
+DEFN_RED_FNC(xnor_reduce)
+
+#undef DEFN_RED_FNC
+
+
+// query parameter
+
+inline
+int
+sc_fxnum_fast_subref::length() const
+{
+ return m_bv.length();
+}
+
+
+// explicit conversions
+
+inline
+int
+sc_fxnum_fast_subref::to_int() const
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( m_num )
+ get();
+ return m_bv.to_int();
+}
+
+inline
+int64
+sc_fxnum_fast_subref::to_int64() const
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( m_num )
+ get();
+ return m_bv.to_int64();
+}
+
+inline
+unsigned int
+sc_fxnum_fast_subref::to_uint() const
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( m_num )
+ get();
+ return m_bv.to_uint();
+}
+
+inline
+uint64
+sc_fxnum_fast_subref::to_uint64() const
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( m_num )
+ get();
+ return m_bv.to_uint64();
+}
+
+inline
+long
+sc_fxnum_fast_subref::to_long() const
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( m_num )
+ get();
+ return m_bv.to_long();
+}
+
+inline
+unsigned long
+sc_fxnum_fast_subref::to_ulong() const
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( m_num )
+ get();
+ return m_bv.to_ulong();
+}
+
+
+#ifdef SC_DT_DEPRECATED
+
+inline
+int
+sc_fxnum_fast_subref::to_signed() const
+{
+ return to_int();
+}
+
+inline
+unsigned int
+sc_fxnum_fast_subref::to_unsigned() const
+{
+ return to_uint();
+}
+
+#endif
+
+
+inline
+const std::string
+sc_fxnum_fast_subref::to_string() const
+{
+ get();
+ return m_bv.to_string();
+}
+
+inline
+const std::string
+sc_fxnum_fast_subref::to_string( sc_numrep numrep ) const
+{
+ get();
+ return m_bv.to_string( numrep );
+}
+
+inline
+const std::string
+sc_fxnum_fast_subref::to_string( sc_numrep numrep, bool w_prefix ) const
+{
+ get();
+ return m_bv.to_string( numrep, w_prefix );
+}
+
+
+// implicit conversion
+
+inline
+sc_fxnum_fast_subref::operator sc_bv_base () const
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( m_num )
+ get();
+ return m_bv;
+}
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, const sc_fxnum_fast_subref& a )
+{
+ a.print( os );
+ return os;
+}
+
+inline
+::std::istream&
+operator >> ( ::std::istream& is, sc_fxnum_fast_subref& a )
+{
+ a.scan( is );
+ return is;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxnum
+//
+// Base class for the fixed-point types; arbitrary precision.
+// ----------------------------------------------------------------------------
+
+inline
+sc_fxnum_observer*
+sc_fxnum::observer() const
+{
+ return m_observer;
+}
+
+
+inline
+void
+sc_fxnum::cast()
+{
+ SC_ERROR_IF_( ! m_rep->is_normal(), sc_core::SC_ID_INVALID_FX_VALUE_ );
+
+ if( m_params.cast_switch() == SC_ON )
+ m_rep->cast( m_params, m_q_flag, m_o_flag );
+}
+
+
+// constructors
+
+inline
+sc_fxnum::sc_fxnum( const sc_fxtype_params& type_params_,
+ sc_enc enc_,
+ const sc_fxcast_switch& cast_sw,
+ sc_fxnum_observer* observer_ )
+: m_rep( new scfx_rep ),
+ m_params( type_params_, enc_, cast_sw ),
+ m_q_flag( false ),
+ m_o_flag( false ),
+ m_observer( observer_ )
+{
+ SC_FXNUM_OBSERVER_DEFAULT_
+ SC_FXNUM_OBSERVER_CONSTRUCT_( *this )
+}
+
+#define DEFN_CTOR_T(tp,arg) \
+inline \
+sc_fxnum::sc_fxnum( tp a, \
+ const sc_fxtype_params& type_params_, \
+ sc_enc enc_, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_observer* observer_ ) \
+: m_rep( new scfx_rep( arg ) ), \
+ m_params( type_params_, enc_, cast_sw ), \
+ m_q_flag( false ), \
+ m_o_flag( false ), \
+ m_observer( observer_ ) \
+{ \
+ SC_FXNUM_OBSERVER_DEFAULT_ \
+ cast(); \
+ SC_FXNUM_OBSERVER_CONSTRUCT_( *this ) \
+ SC_FXNUM_OBSERVER_WRITE_( *this ) \
+}
+
+#define DEFN_CTOR_T_A(tp) DEFN_CTOR_T(tp,a)
+#define DEFN_CTOR_T_B(tp) DEFN_CTOR_T(tp,*a.m_rep)
+#define DEFN_CTOR_T_C(tp) DEFN_CTOR_T(tp,a.to_double())
+#define DEFN_CTOR_T_D(tp) DEFN_CTOR_T(tp,a.value())
+
+DEFN_CTOR_T_A(int)
+DEFN_CTOR_T_A(unsigned int)
+DEFN_CTOR_T_A(long)
+DEFN_CTOR_T_A(unsigned long)
+DEFN_CTOR_T_A(float)
+DEFN_CTOR_T_A(double)
+DEFN_CTOR_T_A(const char*)
+DEFN_CTOR_T_B(const sc_fxval&)
+DEFN_CTOR_T_C(const sc_fxval_fast&)
+DEFN_CTOR_T_B(const sc_fxnum&)
+DEFN_CTOR_T_C(const sc_fxnum_fast&)
+#ifndef SC_FX_EXCLUDE_OTHER
+DEFN_CTOR_T_A(int64)
+DEFN_CTOR_T_A(uint64)
+DEFN_CTOR_T_D(const sc_int_base&)
+DEFN_CTOR_T_D(const sc_uint_base&)
+DEFN_CTOR_T_A(const sc_signed&)
+DEFN_CTOR_T_A(const sc_unsigned&)
+#endif
+
+#undef DEFN_CTOR_T
+#undef DEFN_CTOR_T_A
+#undef DEFN_CTOR_T_B
+#undef DEFN_CTOR_T_C
+#undef DEFN_CTOR_T_D
+
+
+inline
+sc_fxnum::~sc_fxnum()
+{
+ SC_FXNUM_OBSERVER_DESTRUCT_( *this )
+ delete m_rep;
+}
+
+
+// internal use only;
+inline
+const scfx_rep*
+sc_fxnum::get_rep() const
+{
+ SC_FXNUM_OBSERVER_READ_( *this )
+ return m_rep;
+}
+
+
+// unary operators
+
+inline
+const sc_fxval
+sc_fxnum::operator - () const
+{
+ SC_FXNUM_OBSERVER_READ_( *this )
+ return sc_fxval( sc_dt::neg_scfx_rep( *m_rep ) );
+}
+
+inline
+const sc_fxval
+sc_fxnum::operator + () const
+{
+ SC_FXNUM_OBSERVER_READ_( *this )
+ return sc_fxval( new scfx_rep( *m_rep ) );
+}
+
+
+// unary functions
+
+inline
+void
+neg( sc_fxval& c, const sc_fxnum& a )
+{
+ SC_FXNUM_OBSERVER_READ_( a )
+ c.set_rep( sc_dt::neg_scfx_rep( *a.m_rep ) );
+}
+
+inline
+void
+neg( sc_fxnum& c, const sc_fxnum& a )
+{
+ SC_FXNUM_OBSERVER_READ_( a )
+ delete c.m_rep;
+ c.m_rep = sc_dt::neg_scfx_rep( *a.m_rep );
+ c.cast();
+ SC_FXNUM_OBSERVER_WRITE_( c )
+}
+
+
+// binary operators
+
+#define DEFN_BIN_OP_T(op,fnc,tp) \
+inline \
+const sc_fxval \
+operator op ( const sc_fxnum& a, tp b ) \
+{ \
+ SC_FXNUM_OBSERVER_READ_( a ) \
+ sc_fxval tmp( b ); \
+ return sc_fxval( sc_dt::fnc ## _scfx_rep( *a.m_rep, *tmp.get_rep() ) ); \
+} \
+ \
+inline \
+const sc_fxval \
+operator op ( tp a, const sc_fxnum& b ) \
+{ \
+ SC_FXNUM_OBSERVER_READ_( b ) \
+ sc_fxval tmp( a ); \
+ return sc_fxval( sc_dt::fnc ## _scfx_rep( *tmp.get_rep(), *b.m_rep ) ); \
+}
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DEFN_BIN_OP_OTHER(op,fnc) \
+DEFN_BIN_OP_T(op,fnc,int64) \
+DEFN_BIN_OP_T(op,fnc,uint64) \
+DEFN_BIN_OP_T(op,fnc,const sc_int_base&) \
+DEFN_BIN_OP_T(op,fnc,const sc_uint_base&) \
+DEFN_BIN_OP_T(op,fnc,const sc_signed&) \
+DEFN_BIN_OP_T(op,fnc,const sc_unsigned&)
+#else
+#define DEFN_BIN_OP_OTHER(op,fnc)
+#endif
+
+#define DEFN_BIN_OP(op,fnc) \
+inline \
+const sc_fxval \
+operator op ( const sc_fxnum& a, const sc_fxnum& b ) \
+{ \
+ SC_FXNUM_OBSERVER_READ_( a ) \
+ SC_FXNUM_OBSERVER_READ_( b ) \
+ return sc_fxval( sc_dt::fnc ## _scfx_rep( *a.m_rep, *b.m_rep ) ); \
+} \
+ \
+inline \
+const sc_fxval \
+operator op ( const sc_fxnum& a, const sc_fxval& b ) \
+{ \
+ SC_FXNUM_OBSERVER_READ_( a ) \
+ return sc_fxval( sc_dt::fnc ## _scfx_rep( *a.m_rep, *b.get_rep() ) ); \
+} \
+ \
+inline \
+const sc_fxval \
+operator op ( const sc_fxval& a, const sc_fxnum& b ) \
+{ \
+ SC_FXNUM_OBSERVER_READ_( b ) \
+ return sc_fxval( sc_dt::fnc ## _scfx_rep( *a.get_rep(), *b.m_rep ) ); \
+} \
+ \
+DEFN_BIN_OP_T(op,fnc,int) \
+DEFN_BIN_OP_T(op,fnc,unsigned int) \
+DEFN_BIN_OP_T(op,fnc,long) \
+DEFN_BIN_OP_T(op,fnc,unsigned long) \
+DEFN_BIN_OP_T(op,fnc,float) \
+DEFN_BIN_OP_T(op,fnc,double) \
+DEFN_BIN_OP_T(op,fnc,const char*) \
+DEFN_BIN_OP_T(op,fnc,const sc_fxval_fast&) \
+DEFN_BIN_OP_T(op,fnc,const sc_fxnum_fast&) \
+DEFN_BIN_OP_OTHER(op,fnc)
+
+DEFN_BIN_OP(*,mult)
+DEFN_BIN_OP(+,add)
+DEFN_BIN_OP(-,sub)
+// don't use macros
+//DEFN_BIN_OP(/,div)
+inline
+const sc_fxval
+operator / ( const sc_fxnum& a, const sc_fxnum& b )
+{
+ SC_FXNUM_OBSERVER_READ_( a )
+ SC_FXNUM_OBSERVER_READ_( b )
+ return sc_fxval( sc_dt::div_scfx_rep( *a.m_rep, *b.m_rep ) );
+}
+
+inline
+const sc_fxval
+operator / ( const sc_fxnum& a, const sc_fxval& b )
+{
+ SC_FXNUM_OBSERVER_READ_( a )
+ return sc_fxval( sc_dt::div_scfx_rep( *a.m_rep, *b.get_rep() ) );
+}
+
+inline
+const sc_fxval
+operator / ( const sc_fxval& a, const sc_fxnum& b )
+{
+ SC_FXNUM_OBSERVER_READ_( b )
+ return sc_fxval( sc_dt::div_scfx_rep( *a.get_rep(), *b.m_rep ) );
+}
+
+DEFN_BIN_OP_T(/,div,int)
+DEFN_BIN_OP_T(/,div,unsigned int)
+DEFN_BIN_OP_T(/,div,long)
+DEFN_BIN_OP_T(/,div,unsigned long)
+DEFN_BIN_OP_T(/,div,float)
+DEFN_BIN_OP_T(/,div,double)
+DEFN_BIN_OP_T(/,div,const char*)
+DEFN_BIN_OP_T(/,div,const sc_fxval_fast&)
+DEFN_BIN_OP_T(/,div,const sc_fxnum_fast&)
+//DEFN_BIN_OP_OTHER(/,div)
+#ifndef SC_FX_EXCLUDE_OTHER
+DEFN_BIN_OP_T(/,div,int64)
+DEFN_BIN_OP_T(/,div,uint64)
+DEFN_BIN_OP_T(/,div,const sc_int_base&)
+DEFN_BIN_OP_T(/,div,const sc_uint_base&)
+DEFN_BIN_OP_T(/,div,const sc_signed&)
+DEFN_BIN_OP_T(/,div,const sc_unsigned&)
+#endif
+
+#undef DEFN_BIN_OP_T
+#undef DEFN_BIN_OP_OTHER
+#undef DEFN_BIN_OP
+
+
+inline
+const sc_fxval
+operator << ( const sc_fxnum& a, int b )
+{
+ SC_FXNUM_OBSERVER_READ_( a )
+ return sc_fxval( sc_dt::lsh_scfx_rep( *a.m_rep, b ) );
+}
+
+inline
+const sc_fxval
+operator >> ( const sc_fxnum& a, int b )
+{
+ SC_FXNUM_OBSERVER_READ_( a )
+ return sc_fxval( sc_dt::rsh_scfx_rep( *a.m_rep, b ) );
+}
+
+
+// binary functions
+
+#define DEFN_BIN_FNC_T(fnc,tp) \
+inline \
+void \
+fnc ( sc_fxval& c, const sc_fxnum& a, tp b ) \
+{ \
+ SC_FXNUM_OBSERVER_READ_( a ) \
+ sc_fxval tmp( b ); \
+ c.set_rep( sc_dt::fnc ## _scfx_rep( *a.m_rep, *tmp.get_rep() ) ); \
+} \
+ \
+inline \
+void \
+fnc ( sc_fxval& c, tp a, const sc_fxnum& b ) \
+{ \
+ SC_FXNUM_OBSERVER_READ_( b ) \
+ sc_fxval tmp( a ); \
+ c.set_rep( sc_dt::fnc ## _scfx_rep( *tmp.get_rep(), *b.m_rep ) ); \
+} \
+ \
+inline \
+void \
+fnc ( sc_fxnum& c, const sc_fxnum& a, tp b ) \
+{ \
+ SC_FXNUM_OBSERVER_READ_( a ) \
+ sc_fxval tmp( b ); \
+ delete c.m_rep; \
+ c.m_rep = sc_dt::fnc ## _scfx_rep( *a.m_rep, *tmp.get_rep() ); \
+ c.cast(); \
+ SC_FXNUM_OBSERVER_WRITE_( c ) \
+} \
+ \
+inline \
+void \
+fnc ( sc_fxnum& c, tp a, const sc_fxnum& b ) \
+{ \
+ SC_FXNUM_OBSERVER_READ_( b ) \
+ sc_fxval tmp( a ); \
+ delete c.m_rep; \
+ c.m_rep = sc_dt::fnc ## _scfx_rep( *tmp.get_rep(), *b.m_rep ); \
+ c.cast(); \
+ SC_FXNUM_OBSERVER_WRITE_( c ) \
+}
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DEFN_BIN_FNC_OTHER(fnc) \
+DEFN_BIN_FNC_T(fnc,int64) \
+DEFN_BIN_FNC_T(fnc,uint64) \
+DEFN_BIN_FNC_T(fnc,const sc_int_base&) \
+DEFN_BIN_FNC_T(fnc,const sc_uint_base&) \
+DEFN_BIN_FNC_T(fnc,const sc_signed&) \
+DEFN_BIN_FNC_T(fnc,const sc_unsigned&)
+#else
+#define DEFN_BIN_FNC_OTHER(fnc)
+#endif
+
+#define DEFN_BIN_FNC(fnc) \
+inline \
+void \
+fnc ( sc_fxval& c, const sc_fxnum& a, const sc_fxnum& b ) \
+{ \
+ SC_FXNUM_OBSERVER_READ_( a ) \
+ SC_FXNUM_OBSERVER_READ_( b ) \
+ c.set_rep( sc_dt::fnc ## _scfx_rep( *a.m_rep, *b.m_rep ) ); \
+} \
+ \
+inline \
+void \
+fnc ( sc_fxnum& c, const sc_fxnum& a, const sc_fxnum& b ) \
+{ \
+ SC_FXNUM_OBSERVER_READ_( a ) \
+ SC_FXNUM_OBSERVER_READ_( b ) \
+ delete c.m_rep; \
+ c.m_rep = sc_dt::fnc ## _scfx_rep( *a.m_rep, *b.m_rep ); \
+ c.cast(); \
+ SC_FXNUM_OBSERVER_WRITE_( c ) \
+} \
+ \
+inline \
+void \
+fnc ( sc_fxval& c, const sc_fxnum& a, const sc_fxval& b ) \
+{ \
+ SC_FXNUM_OBSERVER_READ_( a ) \
+ c.set_rep( sc_dt::fnc ## _scfx_rep( *a.m_rep, *b.get_rep() ) ); \
+} \
+ \
+inline \
+void \
+fnc ( sc_fxval& c, const sc_fxval& a, const sc_fxnum& b ) \
+{ \
+ SC_FXNUM_OBSERVER_READ_( b ) \
+ c.set_rep( sc_dt::fnc ## _scfx_rep( *a.get_rep(), *b.m_rep ) ); \
+} \
+ \
+inline \
+void \
+fnc ( sc_fxnum& c, const sc_fxnum& a, const sc_fxval& b ) \
+{ \
+ SC_FXNUM_OBSERVER_READ_( a ) \
+ delete c.m_rep; \
+ c.m_rep = sc_dt::fnc ## _scfx_rep( *a.m_rep, *b.get_rep() ); \
+ c.cast(); \
+ SC_FXNUM_OBSERVER_WRITE_( c ) \
+} \
+ \
+inline \
+void \
+fnc ( sc_fxnum& c, const sc_fxval& a, const sc_fxnum& b ) \
+{ \
+ SC_FXNUM_OBSERVER_READ_( b ) \
+ delete c.m_rep; \
+ c.m_rep = sc_dt::fnc ## _scfx_rep( *a.get_rep(), *b.m_rep ); \
+ c.cast(); \
+ SC_FXNUM_OBSERVER_WRITE_( c ) \
+} \
+ \
+DEFN_BIN_FNC_T(fnc,int) \
+DEFN_BIN_FNC_T(fnc,unsigned int) \
+DEFN_BIN_FNC_T(fnc,long) \
+DEFN_BIN_FNC_T(fnc,unsigned long) \
+DEFN_BIN_FNC_T(fnc,float) \
+DEFN_BIN_FNC_T(fnc,double) \
+DEFN_BIN_FNC_T(fnc,const char*) \
+DEFN_BIN_FNC_T(fnc,const sc_fxval_fast&) \
+DEFN_BIN_FNC_T(fnc,const sc_fxnum_fast&) \
+DEFN_BIN_FNC_OTHER(fnc)
+
+DEFN_BIN_FNC(mult)
+DEFN_BIN_FNC(div)
+DEFN_BIN_FNC(add)
+DEFN_BIN_FNC(sub)
+
+#undef DEFN_BIN_FNC_T
+#undef DEFN_BIN_FNC_OTHER
+#undef DEFN_BIN_FNC
+
+
+inline
+void
+lshift( sc_fxval& c, const sc_fxnum& a, int b )
+{
+ SC_FXNUM_OBSERVER_READ_( a )
+ c.set_rep( sc_dt::lsh_scfx_rep( *a.m_rep, b ) );
+}
+
+inline
+void
+rshift( sc_fxval& c, const sc_fxnum& a, int b )
+{
+ SC_FXNUM_OBSERVER_READ_( a )
+ c.set_rep( sc_dt::rsh_scfx_rep( *a.m_rep, b ) );
+}
+
+inline
+void
+lshift( sc_fxnum& c, const sc_fxnum& a, int b )
+{
+ SC_FXNUM_OBSERVER_READ_( a )
+ delete c.m_rep;
+ c.m_rep = sc_dt::lsh_scfx_rep( *a.m_rep, b );
+ c.cast();
+ SC_FXNUM_OBSERVER_WRITE_( c )
+}
+
+inline
+void
+rshift( sc_fxnum& c, const sc_fxnum& a, int b )
+{
+ SC_FXNUM_OBSERVER_READ_( a )
+ delete c.m_rep;
+ c.m_rep = sc_dt::rsh_scfx_rep( *a.m_rep, b );
+ c.cast();
+ SC_FXNUM_OBSERVER_WRITE_( c )
+}
+
+
+// relational (including equality) operators
+
+#define DEFN_REL_OP_T(op,ret,tp) \
+inline \
+bool \
+operator op ( const sc_fxnum& a, tp b ) \
+{ \
+ SC_FXNUM_OBSERVER_READ_( a ) \
+ sc_fxval tmp( b ); \
+ int result = sc_dt::cmp_scfx_rep( *a.m_rep, *tmp.get_rep() ); \
+ return ( ret ); \
+} \
+ \
+inline \
+bool \
+operator op ( tp a, const sc_fxnum& b ) \
+{ \
+ SC_FXNUM_OBSERVER_READ_( b ) \
+ sc_fxval tmp( a ); \
+ int result = sc_dt::cmp_scfx_rep( *tmp.get_rep(), *b.m_rep ); \
+ return ( ret ); \
+}
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DEFN_REL_OP_OTHER(op,ret) \
+DEFN_REL_OP_T(op,ret,int64) \
+DEFN_REL_OP_T(op,ret,uint64) \
+DEFN_REL_OP_T(op,ret,const sc_int_base&) \
+DEFN_REL_OP_T(op,ret,const sc_uint_base&) \
+DEFN_REL_OP_T(op,ret,const sc_signed&) \
+DEFN_REL_OP_T(op,ret,const sc_unsigned&)
+#else
+#define DEFN_REL_OP_OTHER(op,ret)
+#endif
+
+#define DEFN_REL_OP(op,ret) \
+inline \
+bool \
+operator op ( const sc_fxnum& a, const sc_fxnum& b ) \
+{ \
+ SC_FXNUM_OBSERVER_READ_( a ) \
+ SC_FXNUM_OBSERVER_READ_( b ) \
+ int result = sc_dt::cmp_scfx_rep( *a.m_rep, *b.m_rep ); \
+ return ( ret ); \
+} \
+ \
+inline \
+bool \
+operator op ( const sc_fxnum& a, const sc_fxval& b ) \
+{ \
+ SC_FXNUM_OBSERVER_READ_( a ) \
+ int result = sc_dt::cmp_scfx_rep( *a.m_rep, *b.get_rep() ); \
+ return ( ret ); \
+} \
+ \
+inline \
+bool \
+operator op ( const sc_fxval& a, const sc_fxnum& b ) \
+{ \
+ SC_FXNUM_OBSERVER_READ_( b ) \
+ int result = sc_dt::cmp_scfx_rep( *a.get_rep(), *b.m_rep ); \
+ return ( ret ); \
+} \
+ \
+DEFN_REL_OP_T(op,ret,int) \
+DEFN_REL_OP_T(op,ret,unsigned int) \
+DEFN_REL_OP_T(op,ret,long) \
+DEFN_REL_OP_T(op,ret,unsigned long) \
+DEFN_REL_OP_T(op,ret,float) \
+DEFN_REL_OP_T(op,ret,double) \
+DEFN_REL_OP_T(op,ret,const char*) \
+DEFN_REL_OP_T(op,ret,const sc_fxval_fast&) \
+DEFN_REL_OP_T(op,ret,const sc_fxnum_fast&) \
+DEFN_REL_OP_OTHER(op,ret)
+
+DEFN_REL_OP(<,result < 0)
+DEFN_REL_OP(<=,result <= 0)
+DEFN_REL_OP(>,result > 0 && result != 2)
+DEFN_REL_OP(>=,result >= 0 && result != 2)
+DEFN_REL_OP(==,result == 0)
+DEFN_REL_OP(!=,result != 0)
+
+#undef DEFN_REL_OP_T
+#undef DEFN_REL_OP_OTHER
+#undef DEFN_REL_OP
+
+
+// assignment operators
+
+inline
+sc_fxnum&
+sc_fxnum::operator = ( const sc_fxnum& a )
+{
+ if( &a != this )
+ {
+ SC_FXNUM_OBSERVER_READ_( a )
+ *m_rep = *a.m_rep;
+ cast();
+ SC_FXNUM_OBSERVER_WRITE_( *this )
+ }
+ return *this;
+}
+
+inline
+sc_fxnum&
+sc_fxnum::operator = ( const sc_fxval& a )
+{
+ *m_rep = *a.get_rep();
+ cast();
+ SC_FXNUM_OBSERVER_WRITE_( *this )
+ return *this;
+}
+
+#define DEFN_ASN_OP_T(tp) \
+inline \
+sc_fxnum& \
+sc_fxnum::operator = ( tp a ) \
+{ \
+ sc_fxval tmp( a ); \
+ *m_rep = *tmp.get_rep(); \
+ cast(); \
+ SC_FXNUM_OBSERVER_WRITE_( *this ) \
+ return *this; \
+}
+
+DEFN_ASN_OP_T(int)
+DEFN_ASN_OP_T(unsigned int)
+DEFN_ASN_OP_T(long)
+DEFN_ASN_OP_T(unsigned long)
+DEFN_ASN_OP_T(float)
+DEFN_ASN_OP_T(double)
+DEFN_ASN_OP_T(const char*)
+DEFN_ASN_OP_T(const sc_fxval_fast&)
+DEFN_ASN_OP_T(const sc_fxnum_fast&)
+#ifndef SC_FX_EXCLUDE_OTHER
+DEFN_ASN_OP_T(int64)
+DEFN_ASN_OP_T(uint64)
+DEFN_ASN_OP_T(const sc_int_base&)
+DEFN_ASN_OP_T(const sc_uint_base&)
+DEFN_ASN_OP_T(const sc_signed&)
+DEFN_ASN_OP_T(const sc_unsigned&)
+#endif
+
+#undef DEFN_ASN_OP_T
+
+
+#define DEFN_ASN_OP_T(op,fnc,tp) \
+inline \
+sc_fxnum& \
+sc_fxnum::operator op ( tp b ) \
+{ \
+ SC_FXNUM_OBSERVER_READ_( *this ) \
+ sc_fxval tmp( b ); \
+ scfx_rep* new_rep = sc_dt::fnc ## _scfx_rep( *m_rep, *tmp.get_rep() ); \
+ delete m_rep; \
+ m_rep = new_rep; \
+ cast(); \
+ SC_FXNUM_OBSERVER_WRITE_( *this ) \
+ return *this; \
+}
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DEFN_ASN_OP_OTHER(op,fnc) \
+DEFN_ASN_OP_T(op,fnc,int64) \
+DEFN_ASN_OP_T(op,fnc,uint64) \
+DEFN_ASN_OP_T(op,fnc,const sc_int_base&) \
+DEFN_ASN_OP_T(op,fnc,const sc_uint_base&) \
+DEFN_ASN_OP_T(op,fnc,const sc_signed&) \
+DEFN_ASN_OP_T(op,fnc,const sc_unsigned&)
+#else
+#define DEFN_ASN_OP_OTHER(op,fnc)
+#endif
+
+#define DEFN_ASN_OP(op,fnc) \
+inline \
+sc_fxnum& \
+sc_fxnum::operator op ( const sc_fxnum& b ) \
+{ \
+ SC_FXNUM_OBSERVER_READ_( *this ) \
+ SC_FXNUM_OBSERVER_READ_( b ) \
+ scfx_rep* new_rep = sc_dt::fnc ## _scfx_rep( *m_rep, *b.m_rep ); \
+ delete m_rep; \
+ m_rep = new_rep; \
+ cast(); \
+ SC_FXNUM_OBSERVER_WRITE_( *this ) \
+ return *this; \
+} \
+ \
+inline \
+sc_fxnum& \
+sc_fxnum::operator op ( const sc_fxval& b ) \
+{ \
+ SC_FXNUM_OBSERVER_READ_( *this ) \
+ scfx_rep* new_rep = sc_dt::fnc ## _scfx_rep( *m_rep, *b.get_rep() ); \
+ delete m_rep; \
+ m_rep = new_rep; \
+ cast(); \
+ SC_FXNUM_OBSERVER_WRITE_( *this ) \
+ return *this; \
+} \
+ \
+DEFN_ASN_OP_T(op,fnc,int) \
+DEFN_ASN_OP_T(op,fnc,unsigned int) \
+DEFN_ASN_OP_T(op,fnc,long) \
+DEFN_ASN_OP_T(op,fnc,unsigned long) \
+DEFN_ASN_OP_T(op,fnc,float) \
+DEFN_ASN_OP_T(op,fnc,double) \
+DEFN_ASN_OP_T(op,fnc,const char*) \
+DEFN_ASN_OP_T(op,fnc,const sc_fxval_fast&) \
+DEFN_ASN_OP_T(op,fnc,const sc_fxnum_fast&) \
+DEFN_ASN_OP_OTHER(op,fnc)
+
+DEFN_ASN_OP(*=,mult)
+DEFN_ASN_OP(/=,div)
+DEFN_ASN_OP(+=,add)
+DEFN_ASN_OP(-=,sub)
+
+#undef DEFN_ASN_OP_T
+#undef DEFN_ASN_OP_OTHER
+#undef DEFN_ASN_OP
+
+
+inline
+sc_fxnum&
+sc_fxnum::operator <<= ( int b )
+{
+ SC_FXNUM_OBSERVER_READ_( *this )
+ m_rep->lshift( b );
+ cast();
+ SC_FXNUM_OBSERVER_WRITE_( *this )
+ return *this;
+}
+
+inline
+sc_fxnum&
+sc_fxnum::operator >>= ( int b )
+{
+ SC_FXNUM_OBSERVER_READ_( *this )
+ m_rep->rshift( b );
+ cast();
+ SC_FXNUM_OBSERVER_WRITE_( *this )
+ return *this;
+}
+
+
+// auto-increment and auto-decrement
+
+inline
+const sc_fxval
+sc_fxnum::operator ++ ( int )
+{
+ sc_fxval c( *this );
+ (*this) += 1;
+ return c;
+}
+
+inline
+const sc_fxval
+sc_fxnum::operator -- ( int )
+{
+ sc_fxval c( *this );
+ (*this) -= 1;
+ return c;
+}
+
+inline
+sc_fxnum&
+sc_fxnum::operator ++ ()
+{
+ (*this) += 1;
+ return *this;
+}
+
+inline
+sc_fxnum&
+sc_fxnum::operator -- ()
+{
+ (*this) -= 1;
+ return *this;
+}
+
+
+// bit selection
+
+inline
+const sc_fxnum_bitref
+sc_fxnum::operator [] ( int i ) const
+{
+ SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ );
+ return sc_fxnum_bitref( const_cast<sc_fxnum&>( *this ),
+ i - m_params.fwl() );
+}
+
+inline
+sc_fxnum_bitref
+sc_fxnum::operator [] ( int i )
+{
+ SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ );
+ return sc_fxnum_bitref( *this, i - m_params.fwl() );
+}
+
+inline
+const sc_fxnum_bitref
+sc_fxnum::bit( int i ) const
+{
+ SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ );
+ return sc_fxnum_bitref( const_cast<sc_fxnum&>( *this ),
+ i - m_params.fwl() );
+}
+
+inline
+sc_fxnum_bitref
+sc_fxnum::bit( int i )
+{
+ SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ );
+ return sc_fxnum_bitref( *this, i - m_params.fwl() );
+}
+
+
+// part selection
+
+inline
+const sc_fxnum_subref
+sc_fxnum::operator () ( int i, int j ) const
+{
+ SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ );
+ SC_ERROR_IF_( j < 0 || j >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ );
+
+ return sc_fxnum_subref( const_cast<sc_fxnum&>( *this ),
+ i - m_params.fwl(), j - m_params.fwl() );
+}
+
+inline
+sc_fxnum_subref
+sc_fxnum::operator () ( int i, int j )
+{
+ SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ );
+ SC_ERROR_IF_( j < 0 || j >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ );
+
+ return sc_fxnum_subref( *this, i - m_params.fwl(), j - m_params.fwl() );
+}
+
+inline
+const sc_fxnum_subref
+sc_fxnum::range( int i, int j ) const
+{
+ SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ );
+ SC_ERROR_IF_( j < 0 || j >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ );
+
+ return sc_fxnum_subref( const_cast<sc_fxnum&>( *this ),
+ i - m_params.fwl(), j - m_params.fwl() );
+}
+
+inline
+sc_fxnum_subref
+sc_fxnum::range( int i, int j )
+{
+ SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ );
+ SC_ERROR_IF_( j < 0 || j >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ );
+
+ return sc_fxnum_subref( *this, i - m_params.fwl(), j - m_params.fwl() );
+}
+
+
+inline
+const sc_fxnum_subref
+sc_fxnum::operator () () const
+{
+ return this->operator () ( m_params.wl() - 1, 0 );
+}
+
+inline
+sc_fxnum_subref
+sc_fxnum::operator () ()
+{
+ return this->operator () ( m_params.wl() - 1, 0 );
+}
+
+inline
+const sc_fxnum_subref
+sc_fxnum::range() const
+{
+ return this->range( m_params.wl() - 1, 0 );
+}
+
+inline
+sc_fxnum_subref
+sc_fxnum::range()
+{
+ return this->range( m_params.wl() - 1, 0 );
+}
+
+
+// implicit conversion
+
+inline
+sc_fxnum::operator double() const
+{
+ SC_FXNUM_OBSERVER_READ_( *this )
+ return m_rep->to_double();
+}
+
+
+// explicit conversion to primitive types
+
+inline
+short
+sc_fxnum::to_short() const
+{
+ SC_FXNUM_OBSERVER_READ_( *this )
+ return static_cast<short>( m_rep->to_double() );
+}
+
+inline
+unsigned short
+sc_fxnum::to_ushort() const
+{
+ SC_FXNUM_OBSERVER_READ_( *this )
+ return static_cast<unsigned short>( m_rep->to_double() );
+}
+
+inline
+int
+sc_fxnum::to_int() const
+{
+ SC_FXNUM_OBSERVER_READ_( *this )
+ return static_cast<int>( m_rep->to_double() );
+}
+
+inline
+int64
+sc_fxnum::to_int64() const
+{
+ SC_FXNUM_OBSERVER_READ_( *this )
+ return static_cast<int64>( m_rep->to_double() );
+}
+
+inline
+unsigned int
+sc_fxnum::to_uint() const
+{
+ SC_FXNUM_OBSERVER_READ_( *this )
+ return static_cast<unsigned int>( m_rep->to_double() );
+}
+
+inline
+uint64
+sc_fxnum::to_uint64() const
+{
+ SC_FXNUM_OBSERVER_READ_( *this )
+ return static_cast<uint64>( m_rep->to_double() );
+}
+
+inline
+long
+sc_fxnum::to_long() const
+{
+ SC_FXNUM_OBSERVER_READ_( *this )
+ return static_cast<long>( m_rep->to_double() );
+}
+
+inline
+unsigned long
+sc_fxnum::to_ulong() const
+{
+ SC_FXNUM_OBSERVER_READ_( *this )
+ return static_cast<unsigned long>( m_rep->to_double() );
+}
+
+inline
+float
+sc_fxnum::to_float() const
+{
+ SC_FXNUM_OBSERVER_READ_( *this )
+ return static_cast<float>( m_rep->to_double() );
+}
+
+inline
+double
+sc_fxnum::to_double() const
+{
+ SC_FXNUM_OBSERVER_READ_( *this )
+ return m_rep->to_double();
+}
+
+
+// query value
+
+inline
+bool
+sc_fxnum::is_neg() const
+{
+ SC_FXNUM_OBSERVER_READ_( *this )
+ return m_rep->is_neg();
+}
+
+inline
+bool
+sc_fxnum::is_zero() const
+{
+ SC_FXNUM_OBSERVER_READ_( *this )
+ return m_rep->is_zero();
+}
+
+// internal use only;
+inline
+bool
+sc_fxnum::is_normal() const
+{
+ SC_FXNUM_OBSERVER_READ_( *this )
+ return m_rep->is_normal();
+}
+
+inline
+bool
+sc_fxnum::quantization_flag() const
+{
+ return m_q_flag;
+}
+
+inline
+bool
+sc_fxnum::overflow_flag() const
+{
+ return m_o_flag;
+}
+
+
+inline
+const sc_fxval
+sc_fxnum::value() const
+{
+ SC_FXNUM_OBSERVER_READ_( *this )
+ return sc_fxval( new scfx_rep( *m_rep ) );
+}
+
+
+// query parameters
+
+inline
+int
+sc_fxnum::wl() const
+{
+ return m_params.wl();
+}
+
+inline
+int
+sc_fxnum::iwl() const
+{
+ return m_params.iwl();
+}
+
+inline
+sc_q_mode
+sc_fxnum::q_mode() const
+{
+ return m_params.q_mode();
+}
+
+inline
+sc_o_mode
+sc_fxnum::o_mode() const
+{
+ return m_params.o_mode();
+}
+
+inline
+int
+sc_fxnum::n_bits() const
+{
+ return m_params.n_bits();
+}
+
+
+inline
+const sc_fxtype_params&
+sc_fxnum::type_params() const
+{
+ return m_params.type_params();
+}
+
+
+inline
+const sc_fxcast_switch&
+sc_fxnum::cast_switch() const
+{
+ return m_params.cast_switch();
+}
+
+
+// internal use only;
+inline
+void
+sc_fxnum::observer_read() const
+{
+ SC_FXNUM_OBSERVER_READ_( *this );
+}
+
+
+// internal use only;
+inline
+bool
+sc_fxnum::get_bit( int i ) const
+{
+ return m_rep->get_bit( i );
+}
+
+
+// protected methods and friend functions
+
+inline
+bool
+sc_fxnum::set_bit( int i, bool high )
+{
+ if( high )
+ return m_rep->set( i, m_params );
+ else
+ return m_rep->clear( i, m_params );
+}
+
+
+inline
+bool
+sc_fxnum::get_slice( int i, int j, sc_bv_base& bv ) const
+{
+ return m_rep->get_slice( i, j, m_params, bv );
+}
+
+inline
+bool
+sc_fxnum::set_slice( int i, int j, const sc_bv_base& bv )
+{
+ return m_rep->set_slice( i, j, m_params, bv );
+}
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, const sc_fxnum& a )
+{
+ a.print( os );
+ return os;
+}
+
+inline
+::std::istream&
+operator >> ( ::std::istream& is, sc_fxnum& a )
+{
+ a.scan( is );
+ return is;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxnum_fast
+//
+// Base class for the fixed-point types; limited precision.
+// ----------------------------------------------------------------------------
+
+inline
+sc_fxnum_fast_observer*
+sc_fxnum_fast::observer() const
+{
+ return m_observer;
+}
+
+
+// constructors
+
+inline
+sc_fxnum_fast::sc_fxnum_fast( const sc_fxtype_params& type_params_,
+ sc_enc enc_,
+ const sc_fxcast_switch& cast_sw,
+ sc_fxnum_fast_observer* observer_ )
+: m_val( 0.0 ),
+ m_params( type_params_, enc_, cast_sw ),
+ m_q_flag( false ),
+ m_o_flag( false ),
+ m_observer( observer_ )
+{
+ SC_FXNUM_FAST_OBSERVER_DEFAULT_
+ SC_FXNUM_FAST_OBSERVER_CONSTRUCT_(*this)
+}
+
+inline
+sc_fxnum_fast::sc_fxnum_fast( const sc_fxnum_fast& a,
+ const sc_fxtype_params& type_params_,
+ sc_enc enc_,
+ const sc_fxcast_switch& cast_sw,
+ sc_fxnum_fast_observer* observer_ )
+: m_val( a.m_val ),
+ m_params( type_params_, enc_, cast_sw ),
+ m_q_flag( false ),
+ m_o_flag( false ),
+ m_observer( observer_ )
+{
+ SC_FXNUM_FAST_OBSERVER_DEFAULT_
+ SC_FXNUM_FAST_OBSERVER_READ_( a )
+ cast();
+ SC_FXNUM_FAST_OBSERVER_CONSTRUCT_( *this )
+ SC_FXNUM_FAST_OBSERVER_WRITE_( *this )
+}
+
+#define DEFN_CTOR_T(tp,arg) \
+inline \
+sc_fxnum_fast::sc_fxnum_fast( tp a, \
+ const sc_fxtype_params& type_params_, \
+ sc_enc enc_, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_fast_observer* observer_ ) \
+: m_val( arg ), \
+ m_params( type_params_, enc_, cast_sw ), \
+ m_q_flag( false ), \
+ m_o_flag( false ), \
+ m_observer( observer_ ) \
+{ \
+ SC_FXNUM_FAST_OBSERVER_DEFAULT_ \
+ cast(); \
+ SC_FXNUM_FAST_OBSERVER_CONSTRUCT_(*this) \
+ SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) \
+}
+
+#define DEFN_CTOR_T_A(tp) DEFN_CTOR_T(tp,static_cast<double>( a ))
+#define DEFN_CTOR_T_B(tp) DEFN_CTOR_T(tp,sc_fxval_fast::from_string( a ))
+#define DEFN_CTOR_T_C(tp) DEFN_CTOR_T(tp,a.to_double())
+
+DEFN_CTOR_T_A(int)
+DEFN_CTOR_T_A(unsigned int)
+DEFN_CTOR_T_A(long)
+DEFN_CTOR_T_A(unsigned long)
+DEFN_CTOR_T_A(float)
+DEFN_CTOR_T_A(double)
+DEFN_CTOR_T_B(const char*)
+DEFN_CTOR_T_C(const sc_fxval&)
+DEFN_CTOR_T_C(const sc_fxval_fast&)
+DEFN_CTOR_T_C(const sc_fxnum&)
+#ifndef SC_FX_EXCLUDE_OTHER
+DEFN_CTOR_T_A(int64)
+DEFN_CTOR_T_A(uint64)
+DEFN_CTOR_T_C(const sc_int_base&)
+DEFN_CTOR_T_C(const sc_uint_base&)
+DEFN_CTOR_T_C(const sc_signed&)
+DEFN_CTOR_T_C(const sc_unsigned&)
+#endif
+
+#undef DEFN_CTOR_T
+#undef DEFN_CTOR_T_A
+#undef DEFN_CTOR_T_B
+#undef DEFN_CTOR_T_C
+#undef DEFN_CTOR_T_D
+#undef DEFN_CTOR_T_E
+
+
+inline
+sc_fxnum_fast::~sc_fxnum_fast()
+{
+ SC_FXNUM_FAST_OBSERVER_DESTRUCT_( *this )
+}
+
+
+// internal use only;
+inline
+double
+sc_fxnum_fast::get_val() const
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( *this )
+ return m_val;
+}
+
+
+// unary operators
+
+inline
+const sc_fxval_fast
+sc_fxnum_fast::operator - () const
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( *this )
+ return sc_fxval_fast( - m_val );
+}
+
+inline
+const sc_fxval_fast
+sc_fxnum_fast::operator + () const
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( *this )
+ return sc_fxval_fast( m_val );
+}
+
+
+// unary functions
+
+inline
+void
+neg( sc_fxval_fast& c, const sc_fxnum_fast& a )
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( a )
+ c.set_val( - a.m_val );
+}
+
+inline
+void
+neg( sc_fxnum_fast& c, const sc_fxnum_fast& a )
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( a )
+ c.m_val = - a.m_val;
+ c.cast();
+ SC_FXNUM_FAST_OBSERVER_WRITE_( c )
+}
+
+
+// binary operators
+
+#define DEFN_BIN_OP_T(op,tp) \
+inline \
+const sc_fxval_fast \
+operator op ( const sc_fxnum_fast& a, tp b ) \
+{ \
+ SC_FXNUM_FAST_OBSERVER_READ_( a ) \
+ sc_fxval_fast tmp( b ); \
+ return sc_fxval_fast( a.m_val op tmp.get_val() ); \
+} \
+ \
+inline \
+const sc_fxval_fast \
+operator op ( tp a, const sc_fxnum_fast& b ) \
+{ \
+ SC_FXNUM_FAST_OBSERVER_READ_( b ) \
+ sc_fxval_fast tmp( a ); \
+ return sc_fxval_fast( tmp.get_val() op b.m_val ); \
+}
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DEFN_BIN_OP_OTHER(op) \
+DEFN_BIN_OP_T(op,int64) \
+DEFN_BIN_OP_T(op,uint64) \
+DEFN_BIN_OP_T(op,const sc_int_base&) \
+DEFN_BIN_OP_T(op,const sc_uint_base&) \
+DEFN_BIN_OP_T(op,const sc_signed&) \
+DEFN_BIN_OP_T(op,const sc_unsigned&)
+#else
+#define DEFN_BIN_OP_OTHER(op)
+#endif
+
+#define DEFN_BIN_OP(op,dummy) \
+inline \
+const sc_fxval_fast \
+operator op ( const sc_fxnum_fast& a, const sc_fxnum_fast& b ) \
+{ \
+ SC_FXNUM_FAST_OBSERVER_READ_( a ) \
+ SC_FXNUM_FAST_OBSERVER_READ_( b ) \
+ return sc_fxval_fast( a.m_val op b.m_val ); \
+} \
+ \
+inline \
+const sc_fxval_fast \
+operator op ( const sc_fxnum_fast& a, const sc_fxval_fast& b ) \
+{ \
+ SC_FXNUM_FAST_OBSERVER_READ_( a ) \
+ return sc_fxval_fast( a.m_val op b.get_val() ); \
+} \
+ \
+inline \
+const sc_fxval_fast \
+operator op ( const sc_fxval_fast& a, const sc_fxnum_fast& b ) \
+{ \
+ SC_FXNUM_FAST_OBSERVER_READ_( b ) \
+ return sc_fxval_fast( a.get_val() op b.m_val ); \
+} \
+ \
+DEFN_BIN_OP_T(op,int) \
+DEFN_BIN_OP_T(op,unsigned int) \
+DEFN_BIN_OP_T(op,long) \
+DEFN_BIN_OP_T(op,unsigned long) \
+DEFN_BIN_OP_T(op,float) \
+DEFN_BIN_OP_T(op,double) \
+DEFN_BIN_OP_T(op,const char*) \
+DEFN_BIN_OP_OTHER(op)
+
+DEFN_BIN_OP(*,mult)
+DEFN_BIN_OP(+,add)
+DEFN_BIN_OP(-,sub)
+//DEFN_BIN_OP(/,div)
+inline
+const sc_fxval_fast
+operator / ( const sc_fxnum_fast& a, const sc_fxnum_fast& b )
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( a )
+ SC_FXNUM_FAST_OBSERVER_READ_( b )
+ return sc_fxval_fast( a.m_val / b.m_val );
+}
+
+inline
+const sc_fxval_fast
+operator / ( const sc_fxnum_fast& a, const sc_fxval_fast& b )
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( a )
+ return sc_fxval_fast( a.m_val / b.get_val() );
+}
+
+inline
+const sc_fxval_fast
+operator / ( const sc_fxval_fast& a, const sc_fxnum_fast& b )
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( b )
+ return sc_fxval_fast( a.get_val() / b.m_val );
+}
+
+DEFN_BIN_OP_T(/,int)
+DEFN_BIN_OP_T(/,unsigned int)
+DEFN_BIN_OP_T(/,long)
+DEFN_BIN_OP_T(/,unsigned long)
+DEFN_BIN_OP_T(/,float)
+DEFN_BIN_OP_T(/,double)
+DEFN_BIN_OP_T(/,const char*)
+//DEFN_BIN_OP_OTHER(/)
+#ifndef SC_FX_EXCLUDE_OTHER
+DEFN_BIN_OP_T(/,int64)
+DEFN_BIN_OP_T(/,uint64)
+DEFN_BIN_OP_T(/,const sc_int_base&)
+DEFN_BIN_OP_T(/,const sc_uint_base&)
+DEFN_BIN_OP_T(/,const sc_signed&)
+DEFN_BIN_OP_T(/,const sc_unsigned&)
+#endif
+
+#undef DEFN_BIN_OP_T
+#undef DEFN_BIN_OP_OTHER
+#undef DEFN_BIN_OP
+
+
+inline
+const sc_fxval_fast
+operator << ( const sc_fxnum_fast& a, int b )
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( a )
+ return sc_fxval_fast( a.m_val * scfx_pow2( b ) );
+}
+
+inline
+const sc_fxval_fast
+operator >> ( const sc_fxnum_fast& a, int b )
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( a )
+ return sc_fxval_fast( a.m_val * scfx_pow2( -b ) );
+}
+
+
+// binary functions
+
+#define DEFN_BIN_FNC_T(fnc,op,tp) \
+inline \
+void \
+fnc ( sc_fxval_fast& c, const sc_fxnum_fast& a, tp b ) \
+{ \
+ SC_FXNUM_FAST_OBSERVER_READ_( a ) \
+ sc_fxval_fast tmp( b ); \
+ c.set_val( a.m_val op tmp.get_val() ); \
+} \
+ \
+inline \
+void \
+fnc ( sc_fxval_fast& c, tp a, const sc_fxnum_fast& b ) \
+{ \
+ SC_FXNUM_FAST_OBSERVER_READ_( b ) \
+ sc_fxval_fast tmp( a ); \
+ c.set_val( tmp.get_val() op b.m_val ); \
+} \
+ \
+inline \
+void \
+fnc ( sc_fxnum_fast& c, const sc_fxnum_fast& a, tp b ) \
+{ \
+ SC_FXNUM_FAST_OBSERVER_READ_( a ) \
+ sc_fxval_fast tmp( b ); \
+ c.m_val = a.m_val op tmp.get_val(); \
+ c.cast(); \
+ SC_FXNUM_FAST_OBSERVER_WRITE_( c ) \
+} \
+ \
+inline \
+void \
+fnc ( sc_fxnum_fast& c, tp a, const sc_fxnum_fast& b ) \
+{ \
+ SC_FXNUM_FAST_OBSERVER_READ_( b ) \
+ sc_fxval_fast tmp( a ); \
+ c.m_val = tmp.get_val() op b.m_val; \
+ c.cast(); \
+ SC_FXNUM_FAST_OBSERVER_WRITE_( c ) \
+}
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DEFN_BIN_FNC_OTHER(fnc,op) \
+DEFN_BIN_FNC_T(fnc,op,int64) \
+DEFN_BIN_FNC_T(fnc,op,uint64) \
+DEFN_BIN_FNC_T(fnc,op,const sc_int_base&) \
+DEFN_BIN_FNC_T(fnc,op,const sc_uint_base&) \
+DEFN_BIN_FNC_T(fnc,op,const sc_signed&) \
+DEFN_BIN_FNC_T(fnc,op,const sc_unsigned&)
+#else
+#define DEFN_BIN_FNC_OTHER(fnc,op)
+#endif
+
+#define DEFN_BIN_FNC(fnc,op) \
+inline \
+void \
+fnc ( sc_fxval_fast& c, const sc_fxnum_fast& a, const sc_fxnum_fast& b ) \
+{ \
+ SC_FXNUM_FAST_OBSERVER_READ_( a ) \
+ SC_FXNUM_FAST_OBSERVER_READ_( b ) \
+ c.set_val( a.m_val op b.m_val ); \
+} \
+ \
+inline \
+void \
+fnc ( sc_fxnum_fast& c, const sc_fxnum_fast& a, const sc_fxnum_fast& b ) \
+{ \
+ SC_FXNUM_FAST_OBSERVER_READ_( a ) \
+ SC_FXNUM_FAST_OBSERVER_READ_( b ) \
+ c.m_val = a.m_val op b.m_val; \
+ c.cast(); \
+ SC_FXNUM_FAST_OBSERVER_WRITE_( c ) \
+} \
+ \
+inline \
+void \
+fnc ( sc_fxval_fast& c, const sc_fxnum_fast& a, const sc_fxval_fast& b ) \
+{ \
+ SC_FXNUM_FAST_OBSERVER_READ_( a ) \
+ c.set_val( a.m_val op b.get_val() ); \
+} \
+ \
+inline \
+void \
+fnc ( sc_fxval_fast& c, const sc_fxval_fast& a, const sc_fxnum_fast& b ) \
+{ \
+ SC_FXNUM_FAST_OBSERVER_READ_( b ) \
+ c.set_val( a.get_val() op b.m_val ); \
+} \
+ \
+inline \
+void \
+fnc ( sc_fxnum_fast& c, const sc_fxnum_fast& a, const sc_fxval_fast& b ) \
+{ \
+ SC_FXNUM_FAST_OBSERVER_READ_( a ) \
+ c.m_val = a.m_val op b.get_val(); \
+ c.cast(); \
+ SC_FXNUM_FAST_OBSERVER_WRITE_( c ) \
+} \
+ \
+inline \
+void \
+fnc ( sc_fxnum_fast& c, const sc_fxval_fast& a, const sc_fxnum_fast& b ) \
+{ \
+ SC_FXNUM_FAST_OBSERVER_READ_( b ) \
+ c.m_val = a.get_val() op b.m_val; \
+ c.cast(); \
+ SC_FXNUM_FAST_OBSERVER_WRITE_( c ) \
+} \
+ \
+DEFN_BIN_FNC_T(fnc,op,int) \
+DEFN_BIN_FNC_T(fnc,op,unsigned int) \
+DEFN_BIN_FNC_T(fnc,op,long) \
+DEFN_BIN_FNC_T(fnc,op,unsigned long) \
+DEFN_BIN_FNC_T(fnc,op,float) \
+DEFN_BIN_FNC_T(fnc,op,double) \
+DEFN_BIN_FNC_T(fnc,op,const char*) \
+DEFN_BIN_FNC_T(fnc,op,const sc_fxval&) \
+DEFN_BIN_FNC_T(fnc,op,const sc_fxnum&) \
+DEFN_BIN_FNC_OTHER(fnc,op)
+
+DEFN_BIN_FNC(mult,*)
+DEFN_BIN_FNC(div,/)
+DEFN_BIN_FNC(add,+)
+DEFN_BIN_FNC(sub,-)
+
+#undef DEFN_BIN_FNC_T
+#undef DEFN_BIN_FNC_OTHER
+#undef DEFN_BIN_FNC
+
+
+inline
+void
+lshift( sc_fxval_fast& c, const sc_fxnum_fast& a, int b )
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( a )
+ c.set_val( a.m_val * scfx_pow2( b ) );
+}
+
+inline
+void
+rshift( sc_fxval_fast& c, const sc_fxnum_fast& a, int b )
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( a )
+ c.set_val( a.m_val * scfx_pow2( -b ) );
+}
+
+inline
+void
+lshift( sc_fxnum_fast& c, const sc_fxnum_fast& a, int b )
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( a )
+ c.m_val = a.m_val * scfx_pow2( b );
+ c.cast();
+ SC_FXNUM_FAST_OBSERVER_WRITE_( c )
+}
+
+inline
+void
+rshift( sc_fxnum_fast& c, const sc_fxnum_fast& a, int b )
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( a )
+ c.m_val = a.m_val * scfx_pow2( -b );
+ c.cast();
+ SC_FXNUM_FAST_OBSERVER_WRITE_( c )
+}
+
+
+// relational (including equality) operators
+
+#define DEFN_REL_OP_T(op,tp) \
+inline \
+bool \
+operator op ( const sc_fxnum_fast& a, tp b ) \
+{ \
+ SC_FXNUM_FAST_OBSERVER_READ_( a ) \
+ sc_fxval_fast tmp( b ); \
+ return ( a.m_val op tmp.get_val() ); \
+} \
+ \
+inline \
+bool \
+operator op ( tp a, const sc_fxnum_fast& b ) \
+{ \
+ SC_FXNUM_FAST_OBSERVER_READ_( b ) \
+ sc_fxval_fast tmp( a ); \
+ return ( tmp.get_val() op b.m_val ); \
+}
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DEFN_REL_OP_OTHER(op) \
+DEFN_REL_OP_T(op,int64) \
+DEFN_REL_OP_T(op,uint64) \
+DEFN_REL_OP_T(op,const sc_int_base&) \
+DEFN_REL_OP_T(op,const sc_uint_base&) \
+DEFN_REL_OP_T(op,const sc_signed&) \
+DEFN_REL_OP_T(op,const sc_unsigned&)
+#else
+#define DEFN_REL_OP_OTHER(op)
+#endif
+
+#define DEFN_REL_OP(op) \
+inline \
+bool \
+operator op ( const sc_fxnum_fast& a, const sc_fxnum_fast& b ) \
+{ \
+ SC_FXNUM_FAST_OBSERVER_READ_( a ) \
+ SC_FXNUM_FAST_OBSERVER_READ_( b ) \
+ return ( a.m_val op b.m_val ); \
+} \
+ \
+inline \
+bool \
+operator op ( const sc_fxnum_fast& a, const sc_fxval_fast& b ) \
+{ \
+ SC_FXNUM_FAST_OBSERVER_READ_( a ) \
+ return ( a.m_val op b.get_val() ); \
+} \
+ \
+inline \
+bool \
+operator op ( const sc_fxval_fast& a, const sc_fxnum_fast& b ) \
+{ \
+ SC_FXNUM_FAST_OBSERVER_READ_( b ) \
+ return ( a.get_val() op b.m_val ); \
+} \
+ \
+DEFN_REL_OP_T(op,int) \
+DEFN_REL_OP_T(op,unsigned int) \
+DEFN_REL_OP_T(op,long) \
+DEFN_REL_OP_T(op,unsigned long) \
+DEFN_REL_OP_T(op,float) \
+DEFN_REL_OP_T(op,double) \
+DEFN_REL_OP_T(op,const char*) \
+DEFN_REL_OP_OTHER(op)
+
+DEFN_REL_OP(<)
+DEFN_REL_OP(<=)
+DEFN_REL_OP(>)
+DEFN_REL_OP(>=)
+DEFN_REL_OP(==)
+DEFN_REL_OP(!=)
+
+#undef DEFN_REL_OP_T
+#undef DEFN_REL_OP_OTHER
+#undef DEFN_REL_OP
+
+
+// assignment operators
+
+inline
+sc_fxnum_fast&
+sc_fxnum_fast::operator = ( const sc_fxnum_fast& a )
+{
+ if( &a != this )
+ {
+ SC_FXNUM_FAST_OBSERVER_READ_( a )
+ m_val = a.m_val;
+ cast();
+ SC_FXNUM_FAST_OBSERVER_WRITE_( *this )
+ }
+ return *this;
+}
+
+inline
+sc_fxnum_fast&
+sc_fxnum_fast::operator = ( const sc_fxval_fast& a )
+{
+ m_val = a.get_val();
+ cast();
+ SC_FXNUM_FAST_OBSERVER_WRITE_( *this )
+ return *this;
+}
+
+#define DEFN_ASN_OP_T(tp) \
+inline \
+sc_fxnum_fast& \
+sc_fxnum_fast::operator = ( tp a ) \
+{ \
+ sc_fxval_fast tmp( a ); \
+ m_val = tmp.get_val(); \
+ cast(); \
+ SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) \
+ return *this; \
+}
+
+DEFN_ASN_OP_T(int)
+DEFN_ASN_OP_T(unsigned int)
+DEFN_ASN_OP_T(long)
+DEFN_ASN_OP_T(unsigned long)
+DEFN_ASN_OP_T(float)
+DEFN_ASN_OP_T(double)
+DEFN_ASN_OP_T(const char*)
+DEFN_ASN_OP_T(const sc_fxval&)
+DEFN_ASN_OP_T(const sc_fxnum&)
+#ifndef SC_FX_EXCLUDE_OTHER
+DEFN_ASN_OP_T(int64)
+DEFN_ASN_OP_T(uint64)
+DEFN_ASN_OP_T(const sc_int_base&)
+DEFN_ASN_OP_T(const sc_uint_base&)
+DEFN_ASN_OP_T(const sc_signed&)
+DEFN_ASN_OP_T(const sc_unsigned&)
+#endif
+
+#undef DEFN_ASN_OP_T
+
+
+#define DEFN_ASN_OP_T(op,tp) \
+inline \
+sc_fxnum_fast& \
+sc_fxnum_fast::operator op ( tp b ) \
+{ \
+ SC_FXNUM_FAST_OBSERVER_READ_( *this ) \
+ sc_fxval_fast tmp( b ); \
+ m_val op tmp.get_val(); \
+ cast(); \
+ SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) \
+ return *this; \
+}
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DEFN_ASN_OP_OTHER(op) \
+DEFN_ASN_OP_T(op,int64) \
+DEFN_ASN_OP_T(op,uint64) \
+DEFN_ASN_OP_T(op,const sc_int_base&) \
+DEFN_ASN_OP_T(op,const sc_uint_base&) \
+DEFN_ASN_OP_T(op,const sc_signed&) \
+DEFN_ASN_OP_T(op,const sc_unsigned&)
+#else
+#define DEFN_ASN_OP_OTHER(op)
+#endif
+
+#define DEFN_ASN_OP(op) \
+inline \
+sc_fxnum_fast& \
+sc_fxnum_fast::operator op ( const sc_fxnum_fast& b ) \
+{ \
+ SC_FXNUM_FAST_OBSERVER_READ_( *this ) \
+ SC_FXNUM_FAST_OBSERVER_READ_( b ) \
+ m_val op b.m_val; \
+ cast(); \
+ SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) \
+ return *this; \
+} \
+ \
+inline \
+sc_fxnum_fast& \
+sc_fxnum_fast::operator op ( const sc_fxval_fast& b ) \
+{ \
+ SC_FXNUM_FAST_OBSERVER_READ_( *this ) \
+ m_val op b.get_val(); \
+ cast(); \
+ SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) \
+ return *this; \
+} \
+ \
+DEFN_ASN_OP_T(op,int) \
+DEFN_ASN_OP_T(op,unsigned int) \
+DEFN_ASN_OP_T(op,long) \
+DEFN_ASN_OP_T(op,unsigned long) \
+DEFN_ASN_OP_T(op,float) \
+DEFN_ASN_OP_T(op,double) \
+DEFN_ASN_OP_T(op,const char*) \
+DEFN_ASN_OP_T(op,const sc_fxval&) \
+DEFN_ASN_OP_T(op,const sc_fxnum&) \
+DEFN_ASN_OP_OTHER(op)
+
+DEFN_ASN_OP(*=)
+DEFN_ASN_OP(/=)
+DEFN_ASN_OP(+=)
+DEFN_ASN_OP(-=)
+
+#undef DEFN_ASN_OP_T
+#undef DEFN_ASN_OP_OTHER
+#undef DEFN_ASN_OP
+
+
+inline
+sc_fxnum_fast&
+sc_fxnum_fast::operator <<= ( int b )
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( *this )
+ m_val *= scfx_pow2( b );
+ cast();
+ SC_FXNUM_FAST_OBSERVER_WRITE_( *this )
+ return *this;
+}
+
+inline
+sc_fxnum_fast&
+sc_fxnum_fast::operator >>= ( int b )
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( *this )
+ m_val *= scfx_pow2( -b );
+ cast();
+ SC_FXNUM_FAST_OBSERVER_WRITE_( *this )
+ return *this;
+}
+
+
+// auto-increment and auto-decrement
+
+inline
+const sc_fxval_fast
+sc_fxnum_fast::operator ++ ( int )
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( *this )
+ SC_FXNUM_FAST_OBSERVER_READ_( *this )
+ double c = m_val;
+ m_val = m_val + 1;
+ cast();
+ SC_FXNUM_FAST_OBSERVER_WRITE_( *this )
+ return sc_fxval_fast( c );
+}
+
+inline
+const sc_fxval_fast
+sc_fxnum_fast::operator -- ( int )
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( *this )
+ SC_FXNUM_FAST_OBSERVER_READ_( *this )
+ double c = m_val;
+ m_val = m_val - 1;
+ cast();
+ SC_FXNUM_FAST_OBSERVER_WRITE_( *this )
+ return sc_fxval_fast( c );
+}
+
+inline
+sc_fxnum_fast&
+sc_fxnum_fast::operator ++ ()
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( *this )
+ m_val = m_val + 1;
+ cast();
+ SC_FXNUM_FAST_OBSERVER_WRITE_( *this )
+ return *this;
+}
+
+inline
+sc_fxnum_fast&
+sc_fxnum_fast::operator -- ()
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( *this )
+ m_val = m_val - 1;
+ cast();
+ SC_FXNUM_FAST_OBSERVER_WRITE_( *this )
+ return *this;
+}
+
+
+// bit selection
+
+inline
+const sc_fxnum_fast_bitref
+sc_fxnum_fast::operator [] ( int i ) const
+{
+ SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ );
+ return sc_fxnum_fast_bitref( const_cast<sc_fxnum_fast&>( *this ),
+ i - m_params.fwl() );
+}
+
+inline
+sc_fxnum_fast_bitref
+sc_fxnum_fast::operator [] ( int i )
+{
+ SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ );
+ return sc_fxnum_fast_bitref( *this, i - m_params.fwl() );
+}
+
+inline
+const sc_fxnum_fast_bitref
+sc_fxnum_fast::bit( int i ) const
+{
+ SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ );
+ return sc_fxnum_fast_bitref( const_cast<sc_fxnum_fast&>( *this ),
+ i - m_params.fwl() );
+}
+
+inline
+sc_fxnum_fast_bitref
+sc_fxnum_fast::bit( int i )
+{
+ SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ );
+ return sc_fxnum_fast_bitref( *this, i - m_params.fwl() );
+}
+
+
+// part selection
+
+inline
+const sc_fxnum_fast_subref
+sc_fxnum_fast::operator () ( int i, int j ) const
+{
+ SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ );
+ SC_ERROR_IF_( j < 0 || j >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ );
+
+ return sc_fxnum_fast_subref( const_cast<sc_fxnum_fast&>( *this ),
+ i - m_params.fwl(), j - m_params.fwl() );
+}
+
+inline
+sc_fxnum_fast_subref
+sc_fxnum_fast::operator () ( int i, int j )
+{
+ SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ );
+ SC_ERROR_IF_( j < 0 || j >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ );
+
+ return sc_fxnum_fast_subref( *this,
+ i - m_params.fwl(), j - m_params.fwl() );
+}
+
+inline
+const sc_fxnum_fast_subref
+sc_fxnum_fast::range( int i, int j ) const
+{
+ SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ );
+ SC_ERROR_IF_( j < 0 || j >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ );
+
+ return sc_fxnum_fast_subref( const_cast<sc_fxnum_fast&>( *this ),
+ i - m_params.fwl(), j - m_params.fwl() );
+}
+
+inline
+sc_fxnum_fast_subref
+sc_fxnum_fast::range( int i, int j )
+{
+ SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ );
+ SC_ERROR_IF_( j < 0 || j >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ );
+
+ return sc_fxnum_fast_subref( *this,
+ i - m_params.fwl(), j - m_params.fwl() );
+}
+
+inline
+const sc_fxnum_fast_subref
+sc_fxnum_fast::operator () () const
+{
+ return this->operator () ( m_params.wl() - 1, 0 );
+}
+
+inline
+sc_fxnum_fast_subref
+sc_fxnum_fast::operator () ()
+{
+ return this->operator () ( m_params.wl() - 1, 0 );
+}
+
+inline
+const sc_fxnum_fast_subref
+sc_fxnum_fast::range() const
+{
+ return this->range( m_params.wl() - 1, 0 );
+}
+
+inline
+sc_fxnum_fast_subref
+sc_fxnum_fast::range()
+{
+ return this->range( m_params.wl() - 1, 0 );
+}
+
+
+// implicit conversion
+
+inline
+sc_fxnum_fast::operator double() const
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( *this )
+ return m_val;
+}
+
+
+// explicit conversion to primitive types
+
+inline
+short
+sc_fxnum_fast::to_short() const
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( *this )
+ return static_cast<short>( m_val );
+}
+
+inline
+unsigned short
+sc_fxnum_fast::to_ushort() const
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( *this )
+ return static_cast<unsigned short>( m_val );
+}
+
+inline
+int
+sc_fxnum_fast::to_int() const
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( *this )
+ return static_cast<int>( m_val );
+}
+
+inline
+int64
+sc_fxnum_fast::to_int64() const
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( *this )
+ return static_cast<int64>( m_val );
+}
+
+inline
+unsigned int
+sc_fxnum_fast::to_uint() const
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( *this )
+ return static_cast<unsigned int>( m_val );
+}
+
+inline
+uint64
+sc_fxnum_fast::to_uint64() const
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( *this )
+ return static_cast<uint64>( m_val );
+}
+
+inline
+long
+sc_fxnum_fast::to_long() const
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( *this )
+ return static_cast<long>( m_val );
+}
+
+inline
+unsigned long
+sc_fxnum_fast::to_ulong() const
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( *this )
+ return static_cast<unsigned long>( m_val );
+}
+
+inline
+float
+sc_fxnum_fast::to_float() const
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( *this )
+ return static_cast<float>( m_val );
+}
+
+inline
+double
+sc_fxnum_fast::to_double() const
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( *this )
+ return m_val;
+}
+
+
+// query value
+
+inline
+bool
+sc_fxnum_fast::is_neg() const
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( *this )
+ scfx_ieee_double id( m_val );
+ return ( id.negative() != 0 );
+}
+
+inline
+bool
+sc_fxnum_fast::is_zero() const
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( *this )
+ scfx_ieee_double id( m_val );
+ return id.is_zero();
+}
+
+// internal use only;
+inline
+bool
+sc_fxnum_fast::is_normal() const
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( *this )
+ scfx_ieee_double id( m_val );
+ return ( id.is_normal() || id.is_subnormal() || id.is_zero() );
+}
+
+
+inline
+bool
+sc_fxnum_fast::quantization_flag() const
+{
+ return m_q_flag;
+}
+
+inline
+bool
+sc_fxnum_fast::overflow_flag() const
+{
+ return m_o_flag;
+}
+
+
+inline
+const sc_fxval_fast
+sc_fxnum_fast::value() const
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( *this )
+ return sc_fxval_fast( m_val );
+}
+
+
+// query parameters
+
+inline
+int
+sc_fxnum_fast::wl() const
+{
+ return m_params.wl();
+}
+
+inline
+int
+sc_fxnum_fast::iwl() const
+{
+ return m_params.iwl();
+}
+
+inline
+sc_q_mode
+sc_fxnum_fast::q_mode() const
+{
+ return m_params.q_mode();
+}
+
+inline
+sc_o_mode
+sc_fxnum_fast::o_mode() const
+{
+ return m_params.o_mode();
+}
+
+inline
+int
+sc_fxnum_fast::n_bits() const
+{
+ return m_params.n_bits();
+}
+
+
+inline
+const sc_fxtype_params&
+sc_fxnum_fast::type_params() const
+{
+ return m_params.type_params();
+}
+
+
+inline
+const sc_fxcast_switch&
+sc_fxnum_fast::cast_switch() const
+{
+ return m_params.cast_switch();
+}
+
+
+// internal use only;
+inline
+void
+sc_fxnum_fast::observer_read() const
+{
+ SC_FXNUM_OBSERVER_READ_( *this );
+}
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, const sc_fxnum_fast& a )
+{
+ a.print( os );
+ return os;
+}
+
+inline
+::std::istream&
+operator >> ( ::std::istream& is, sc_fxnum_fast& a )
+{
+ a.scan( is );
+ return is;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxval
+//
+// Fixed-point value type; arbitrary precision.
+// ----------------------------------------------------------------------------
+
+// public constructors
+
+inline
+sc_fxval::sc_fxval( const sc_fxnum& a,
+ sc_fxval_observer* observer_ )
+: m_rep( new scfx_rep( *a.get_rep() ) ),
+ m_observer( observer_ )
+{
+ SC_FXVAL_OBSERVER_DEFAULT_
+ SC_FXVAL_OBSERVER_CONSTRUCT_( *this )
+ SC_FXVAL_OBSERVER_WRITE_( *this )
+}
+
+inline
+sc_fxval::sc_fxval( const sc_fxnum_fast& a,
+ sc_fxval_observer* observer_ )
+: m_rep( new scfx_rep( a.to_double() ) ),
+ m_observer( observer_ )
+{
+ SC_FXVAL_OBSERVER_DEFAULT_
+ SC_FXVAL_OBSERVER_CONSTRUCT_( *this )
+ SC_FXVAL_OBSERVER_WRITE_( *this )
+}
+
+
+// binary operators
+
+#define DEFN_BIN_OP_T(op,fnc,tp) \
+inline \
+const sc_fxval \
+operator op ( const sc_fxval& a, tp b ) \
+{ \
+ SC_FXVAL_OBSERVER_READ_( a ) \
+ sc_fxval tmp( b ); \
+ return sc_fxval( sc_dt::fnc ## _scfx_rep( *a.m_rep, *tmp.m_rep ) ); \
+} \
+ \
+inline \
+const sc_fxval \
+operator op ( tp a, const sc_fxval& b ) \
+{ \
+ SC_FXVAL_OBSERVER_READ_( b ) \
+ sc_fxval tmp( a ); \
+ return sc_fxval( sc_dt::fnc ## _scfx_rep( *tmp.m_rep, *b.m_rep ) ); \
+}
+
+#define DEFN_BIN_OP(op,fnc) \
+DEFN_BIN_OP_T(op,fnc,const sc_fxnum_fast&)
+
+DEFN_BIN_OP(*,mult)
+DEFN_BIN_OP(+,add)
+DEFN_BIN_OP(-,sub)
+//DEFN_BIN_OP(/,div)
+DEFN_BIN_OP_T(/,div,const sc_fxnum_fast&)
+
+#undef DEFN_BIN_OP_T
+#undef DEFN_BIN_OP
+
+
+// binary functions
+
+#define DEFN_BIN_FNC_T(fnc,tp) \
+inline \
+void \
+fnc ( sc_fxval& c, const sc_fxval& a, tp b ) \
+{ \
+ SC_FXVAL_OBSERVER_READ_( a ) \
+ sc_fxval tmp( b ); \
+ delete c.m_rep; \
+ c.m_rep = sc_dt::fnc ## _scfx_rep( *a.m_rep, *tmp.m_rep ); \
+ SC_FXVAL_OBSERVER_WRITE_( c ) \
+} \
+ \
+inline \
+void \
+fnc ( sc_fxval& c, tp a, const sc_fxval& b ) \
+{ \
+ SC_FXVAL_OBSERVER_READ_( b ) \
+ sc_fxval tmp( a ); \
+ delete c.m_rep; \
+ c.m_rep = sc_dt::fnc ## _scfx_rep( *tmp.m_rep, *b.m_rep ); \
+ SC_FXVAL_OBSERVER_WRITE_( c ) \
+}
+
+#define DEFN_BIN_FNC(fnc) \
+DEFN_BIN_FNC_T(fnc,const sc_fxnum_fast&)
+
+DEFN_BIN_FNC(mult)
+DEFN_BIN_FNC(div)
+DEFN_BIN_FNC(add)
+DEFN_BIN_FNC(sub)
+
+#undef DEFN_BIN_FNC_T
+#undef DEFN_BIN_FNC
+
+
+// relational (including equality) operators
+
+#define DEFN_REL_OP_T(op,ret,tp) \
+inline \
+bool \
+operator op ( const sc_fxval& a, tp b ) \
+{ \
+ SC_FXVAL_OBSERVER_READ_( a ) \
+ sc_fxval tmp( b ); \
+ int result = sc_dt::cmp_scfx_rep( *a.m_rep, *tmp.m_rep ); \
+ return ( ret ); \
+} \
+ \
+inline \
+bool \
+operator op ( tp a, const sc_fxval& b ) \
+{ \
+ SC_FXVAL_OBSERVER_READ_( b ) \
+ sc_fxval tmp( a ); \
+ int result = sc_dt::cmp_scfx_rep( *tmp.m_rep, *b.m_rep ); \
+ return ( ret ); \
+}
+
+
+#define DEFN_REL_OP(op,ret) \
+DEFN_REL_OP_T(op,ret,const sc_fxnum_fast&)
+
+DEFN_REL_OP(<,result < 0)
+DEFN_REL_OP(<=,result <= 0)
+DEFN_REL_OP(>,result > 0 && result != 2)
+DEFN_REL_OP(>=,result >= 0 && result != 2)
+DEFN_REL_OP(==,result == 0)
+DEFN_REL_OP(!=,result != 0)
+
+#undef DEFN_REL_OP_T
+#undef DEFN_REL_OP
+
+
+// assignment operators
+
+inline
+sc_fxval&
+sc_fxval::operator = ( const sc_fxnum& a )
+{
+ *m_rep = *a.get_rep();
+ SC_FXVAL_OBSERVER_WRITE_( *this )
+ return *this;
+}
+
+#define DEFN_ASN_OP_T(tp) \
+inline \
+sc_fxval& \
+sc_fxval::operator = ( tp b ) \
+{ \
+ sc_fxval tmp( b ); \
+ *m_rep = *tmp.m_rep; \
+ SC_FXVAL_OBSERVER_WRITE_( *this ) \
+ return *this; \
+}
+
+DEFN_ASN_OP_T(const sc_fxnum_fast&)
+
+#undef DEFN_ASN_OP_T
+
+
+#define DEFN_ASN_OP_T(op,fnc,tp) \
+inline \
+sc_fxval& \
+sc_fxval::operator op ( tp b ) \
+{ \
+ SC_FXVAL_OBSERVER_READ_( *this ) \
+ sc_fxval tmp( b ); \
+ scfx_rep* new_rep = sc_dt::fnc ## _scfx_rep( *m_rep, *tmp.m_rep ); \
+ delete m_rep; \
+ m_rep = new_rep; \
+ SC_FXVAL_OBSERVER_WRITE_( *this ) \
+ return *this; \
+}
+
+#define DEFN_ASN_OP(op,fnc) \
+inline \
+sc_fxval& \
+sc_fxval::operator op ( const sc_fxnum& b ) \
+{ \
+ SC_FXVAL_OBSERVER_READ_( *this ) \
+ scfx_rep* new_rep = sc_dt::fnc ## _scfx_rep( *m_rep, *b.get_rep() ); \
+ delete m_rep; \
+ m_rep = new_rep; \
+ SC_FXVAL_OBSERVER_WRITE_( *this ) \
+ return *this; \
+} \
+ \
+DEFN_ASN_OP_T(op,fnc,const sc_fxnum_fast&)
+
+DEFN_ASN_OP(*=,mult)
+DEFN_ASN_OP(/=,div)
+DEFN_ASN_OP(+=,add)
+DEFN_ASN_OP(-=,sub)
+
+#undef DEFN_ASN_OP_T
+#undef DEFN_ASN_OP
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxval_fast
+//
+// Fixed-point value types; limited precision.
+// ----------------------------------------------------------------------------
+
+// public constructors
+
+inline
+sc_fxval_fast::sc_fxval_fast( const sc_fxnum& a,
+ sc_fxval_fast_observer* observer_ )
+: m_val( a.to_double() ),
+ m_observer( observer_ )
+{
+ SC_FXVAL_FAST_OBSERVER_DEFAULT_
+ SC_FXVAL_FAST_OBSERVER_CONSTRUCT_( *this )
+ SC_FXVAL_FAST_OBSERVER_WRITE_( *this )
+}
+
+inline
+sc_fxval_fast::sc_fxval_fast( const sc_fxnum_fast& a,
+ sc_fxval_fast_observer* observer_ )
+: m_val( a.get_val() ),
+ m_observer( observer_ )
+{
+ SC_FXVAL_FAST_OBSERVER_DEFAULT_
+ SC_FXVAL_FAST_OBSERVER_CONSTRUCT_( *this )
+ SC_FXVAL_FAST_OBSERVER_WRITE_( *this )
+}
+
+
+// binary functions
+
+#define DEFN_BIN_FNC_T(fnc,op,tp) \
+inline \
+void \
+fnc ( sc_fxval_fast& c, const sc_fxval_fast& a, tp b ) \
+{ \
+ SC_FXVAL_FAST_OBSERVER_READ_( a ) \
+ sc_fxval_fast tmp( b ); \
+ c.m_val = a.m_val op tmp.m_val; \
+ SC_FXVAL_FAST_OBSERVER_WRITE_( c ) \
+} \
+ \
+inline \
+void \
+fnc ( sc_fxval_fast& c, tp a, const sc_fxval_fast& b ) \
+{ \
+ SC_FXVAL_FAST_OBSERVER_READ_( b ) \
+ sc_fxval_fast tmp( a ); \
+ c.m_val = tmp.m_val op b.m_val; \
+ SC_FXVAL_FAST_OBSERVER_WRITE_( c ) \
+}
+
+#define DEFN_BIN_FNC(fnc,op) \
+DEFN_BIN_FNC_T(fnc,op,const sc_fxval&) \
+DEFN_BIN_FNC_T(fnc,op,const sc_fxnum&)
+
+DEFN_BIN_FNC(mult,*)
+DEFN_BIN_FNC(div,/)
+DEFN_BIN_FNC(add,+)
+DEFN_BIN_FNC(sub,-)
+
+#undef DEFN_BIN_FNC_T
+#undef DEFN_BIN_FNC
+
+
+// assignment operators
+
+inline
+sc_fxval_fast&
+sc_fxval_fast::operator = ( const sc_fxnum_fast& a )
+{
+ m_val = a.get_val();
+ SC_FXVAL_FAST_OBSERVER_WRITE_( *this )
+ return *this;
+}
+
+#define DEFN_ASN_OP_T(tp) \
+inline \
+sc_fxval_fast& \
+sc_fxval_fast::operator = ( tp a ) \
+{ \
+ sc_fxval_fast tmp( a ); \
+ m_val = tmp.m_val; \
+ SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) \
+ return *this; \
+}
+
+DEFN_ASN_OP_T(const sc_fxnum&)
+
+#undef DEFN_ASN_OP_T
+
+
+#define DEFN_ASN_OP_T(op,tp) \
+inline \
+sc_fxval_fast& \
+sc_fxval_fast::operator op ( tp b ) \
+{ \
+ SC_FXVAL_FAST_OBSERVER_READ_( *this ) \
+ sc_fxval_fast tmp( b ); \
+ m_val op tmp.m_val; \
+ SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) \
+ return *this; \
+}
+
+#define DEFN_ASN_OP(op) \
+inline \
+sc_fxval_fast& \
+sc_fxval_fast::operator op ( const sc_fxnum_fast& b ) \
+{ \
+ SC_FXVAL_FAST_OBSERVER_READ_( *this ) \
+ m_val op b.get_val(); \
+ SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) \
+ return *this; \
+} \
+ \
+DEFN_ASN_OP_T(op,const sc_fxnum&)
+
+DEFN_ASN_OP(*=)
+DEFN_ASN_OP(/=)
+DEFN_ASN_OP(+=)
+DEFN_ASN_OP(-=)
+
+#undef DEFN_ASN_OP_T
+#undef DEFN_ASN_OP
+
+} // namespace sc_dt
+
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxnum_observer.cpp b/ext/systemc/src/sysc/datatypes/fx/sc_fxnum_observer.cpp
new file mode 100644
index 000000000..709a3c50b
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxnum_observer.cpp
@@ -0,0 +1,74 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_fxnum_observer.cpp -
+
+ Original Author: Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// $Log: sc_fxnum_observer.cpp,v $
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:58 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#include "sysc/datatypes/fx/sc_fxnum_observer.h"
+
+
+namespace sc_dt
+{
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxnum_observer
+//
+// Abstract base class for fixed-point types observers; arbitrary precision.
+// ----------------------------------------------------------------------------
+
+sc_fxnum_observer* (*sc_fxnum_observer::default_observer) () = 0;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxnum_fast_observer
+//
+// Abstract base class for fixed-point types observers; limited precision.
+// ----------------------------------------------------------------------------
+
+sc_fxnum_fast_observer* (*sc_fxnum_fast_observer::default_observer) () = 0;
+
+} // namespace sc_dt
+
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxnum_observer.h b/ext/systemc/src/sysc/datatypes/fx/sc_fxnum_observer.h
new file mode 100644
index 000000000..2769df31b
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxnum_observer.h
@@ -0,0 +1,219 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_fxnum_observer.h -
+
+ Original Author: Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_fxnum_observer.h,v $
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:58 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#ifndef SC_FXNUM_OBSERVER_H
+#define SC_FXNUM_OBSERVER_H
+
+
+#include "sysc/datatypes/fx/sc_fxdefs.h"
+
+
+namespace sc_dt
+{
+
+// classes defined in this module
+class sc_fxnum_observer;
+class sc_fxnum_fast_observer;
+
+// forward class declarations
+class sc_fxnum;
+class sc_fxnum_fast;
+
+
+#ifdef SC_ENABLE_OBSERVERS
+
+#define SC_FXNUM_OBSERVER_CONSTRUCT_(object) \
+ SC_OBSERVER_(object,sc_fxnum_observer*,construct)
+#define SC_FXNUM_OBSERVER_DESTRUCT_(object) \
+ SC_OBSERVER_(object,sc_fxnum_observer*,destruct)
+#define SC_FXNUM_OBSERVER_READ_(object) \
+ SC_OBSERVER_(object,sc_fxnum_observer*,read)
+#define SC_FXNUM_OBSERVER_WRITE_(object) \
+ SC_OBSERVER_(object,sc_fxnum_observer*,write)
+#define SC_FXNUM_OBSERVER_DEFAULT_ \
+ SC_OBSERVER_DEFAULT_(sc_fxnum_observer)
+
+#define SC_FXNUM_FAST_OBSERVER_CONSTRUCT_(object) \
+ SC_OBSERVER_(object,sc_fxnum_fast_observer*,construct)
+#define SC_FXNUM_FAST_OBSERVER_DESTRUCT_(object) \
+ SC_OBSERVER_(object,sc_fxnum_fast_observer*,destruct)
+#define SC_FXNUM_FAST_OBSERVER_READ_(object) \
+ SC_OBSERVER_(object,sc_fxnum_fast_observer*,read)
+#define SC_FXNUM_FAST_OBSERVER_WRITE_(object) \
+ SC_OBSERVER_(object,sc_fxnum_fast_observer*,write)
+#define SC_FXNUM_FAST_OBSERVER_DEFAULT_ \
+ SC_OBSERVER_DEFAULT_(sc_fxnum_fast_observer)
+
+#else
+
+#define SC_FXNUM_OBSERVER_CONSTRUCT_(object)
+#define SC_FXNUM_OBSERVER_DESTRUCT_(object)
+#define SC_FXNUM_OBSERVER_READ_(object)
+#define SC_FXNUM_OBSERVER_WRITE_(object)
+#define SC_FXNUM_OBSERVER_DEFAULT_
+
+#define SC_FXNUM_FAST_OBSERVER_CONSTRUCT_(object)
+#define SC_FXNUM_FAST_OBSERVER_DESTRUCT_(object)
+#define SC_FXNUM_FAST_OBSERVER_READ_(object)
+#define SC_FXNUM_FAST_OBSERVER_WRITE_(object)
+#define SC_FXNUM_FAST_OBSERVER_DEFAULT_
+
+#endif
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxnum_observer
+//
+// Abstract base class for fixed-point types observers; arbitrary precision.
+// ----------------------------------------------------------------------------
+
+class sc_fxnum_observer
+{
+
+protected:
+
+ sc_fxnum_observer() {}
+ virtual ~sc_fxnum_observer() {}
+
+public:
+
+ virtual void construct( const sc_fxnum& );
+ virtual void destruct( const sc_fxnum& );
+ virtual void read( const sc_fxnum& );
+ virtual void write( const sc_fxnum& );
+
+ static sc_fxnum_observer* (*default_observer) ();
+
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxnum_fast_observer
+//
+// Abstract base class for fixed-point types observers; limited precision.
+// ----------------------------------------------------------------------------
+
+class sc_fxnum_fast_observer
+{
+
+protected:
+
+ sc_fxnum_fast_observer() {}
+ virtual ~sc_fxnum_fast_observer() {}
+
+public:
+
+ virtual void construct( const sc_fxnum_fast& );
+ virtual void destruct( const sc_fxnum_fast& );
+ virtual void read( const sc_fxnum_fast& );
+ virtual void write( const sc_fxnum_fast& );
+
+ static sc_fxnum_fast_observer* (*default_observer) ();
+
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxnum_observer
+//
+// Abstract base class for fixed-point types observers; arbitrary precision.
+// ----------------------------------------------------------------------------
+
+inline
+void
+sc_fxnum_observer::construct( const sc_fxnum& )
+{}
+
+inline
+void
+sc_fxnum_observer::destruct( const sc_fxnum& )
+{}
+
+inline
+void
+sc_fxnum_observer::read( const sc_fxnum& )
+{}
+
+inline
+void
+sc_fxnum_observer::write( const sc_fxnum& )
+{}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxnum_fast_observer
+//
+// Abstract base class for fixed-point types observers; limited precision.
+// ----------------------------------------------------------------------------
+
+inline
+void
+sc_fxnum_fast_observer::construct( const sc_fxnum_fast& )
+{}
+
+inline
+void
+sc_fxnum_fast_observer::destruct( const sc_fxnum_fast& )
+{}
+
+inline
+void
+sc_fxnum_fast_observer::read( const sc_fxnum_fast& )
+{}
+
+inline
+void
+sc_fxnum_fast_observer::write( const sc_fxnum_fast& )
+{}
+
+} // namespace sc_dt
+
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxtype_params.cpp b/ext/systemc/src/sysc/datatypes/fx/sc_fxtype_params.cpp
new file mode 100644
index 000000000..60c18a2b5
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxtype_params.cpp
@@ -0,0 +1,108 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_fxtype_params.cpp -
+
+ Original Author: Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// $Log: sc_fxtype_params.cpp,v $
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:58 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#include "sysc/datatypes/fx/sc_fxtype_params.h"
+
+
+namespace sc_dt
+{
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxtype_params
+//
+// Fixed-point type parameters class.
+// ----------------------------------------------------------------------------
+
+const std::string
+sc_fxtype_params::to_string() const
+{
+ std::string s;
+
+ char buf[BUFSIZ];
+
+ s += "(";
+ std::sprintf( buf, "%d", m_wl );
+ s += buf;
+ s += ",";
+ std::sprintf( buf, "%d", m_iwl );
+ s += buf;
+ s += ",";
+ s += sc_dt::to_string( m_q_mode );
+ s += ",";
+ s += sc_dt::to_string( m_o_mode );
+ s += ",";
+ std::sprintf( buf, "%d", m_n_bits );
+ s += buf;
+ s += ")";
+
+ return s;
+}
+
+
+void
+sc_fxtype_params::print( ::std::ostream& os ) const
+{
+ os << to_string();
+}
+
+void
+sc_fxtype_params::dump( ::std::ostream& os ) const
+{
+ os << "sc_fxtype_params" << ::std::endl;
+ os << "(" << ::std::endl;
+ os << "wl = " << m_wl << ::std::endl;
+ os << "iwl = " << m_iwl << ::std::endl;
+ os << "q_mode = " << m_q_mode << ::std::endl;
+ os << "o_mode = " << m_o_mode << ::std::endl;
+ os << "n_bits = " << m_n_bits << ::std::endl;
+ os << ")" << ::std::endl;
+}
+
+} // namespace sc_dt
+
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxtype_params.h b/ext/systemc/src/sysc/datatypes/fx/sc_fxtype_params.h
new file mode 100644
index 000000000..a59ba293b
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxtype_params.h
@@ -0,0 +1,342 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_fxtype_params.h -
+
+ Original Author: Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_fxtype_params.h,v $
+// Revision 1.2 2011/08/24 22:05:43 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:58 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#ifndef SC_FXTYPE_PARAMS_H
+#define SC_FXTYPE_PARAMS_H
+
+
+#include "sysc/datatypes/fx/sc_context.h"
+
+
+namespace sc_dt
+{
+
+// classes defined in this module
+class sc_fxtype_params;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxtype_params
+//
+// Fixed-point type parameters class.
+// ----------------------------------------------------------------------------
+
+class sc_fxtype_params
+{
+public:
+
+ sc_fxtype_params();
+ sc_fxtype_params( int, int );
+ sc_fxtype_params( sc_q_mode, sc_o_mode, int = 0 );
+ sc_fxtype_params( int, int, sc_q_mode, sc_o_mode, int = 0 );
+ sc_fxtype_params( const sc_fxtype_params& );
+ sc_fxtype_params( const sc_fxtype_params&,
+ int, int );
+ sc_fxtype_params( const sc_fxtype_params&,
+ sc_q_mode, sc_o_mode, int = 0 );
+ explicit sc_fxtype_params( sc_without_context );
+
+ sc_fxtype_params& operator = ( const sc_fxtype_params& );
+
+ friend bool operator == ( const sc_fxtype_params&,
+ const sc_fxtype_params& );
+ friend bool operator != ( const sc_fxtype_params&,
+ const sc_fxtype_params& );
+
+ int wl() const;
+ void wl( int );
+
+ int iwl() const;
+ void iwl( int );
+
+ sc_q_mode q_mode() const;
+ void q_mode( sc_q_mode );
+
+ sc_o_mode o_mode() const;
+ void o_mode( sc_o_mode );
+
+ int n_bits() const;
+ void n_bits( int );
+
+ const std::string to_string() const;
+
+ void print( ::std::ostream& = ::std::cout ) const;
+ void dump( ::std::ostream& = ::std::cout ) const;
+
+private:
+
+ int m_wl;
+ int m_iwl;
+ sc_q_mode m_q_mode;
+ sc_o_mode m_o_mode;
+ int m_n_bits;
+};
+
+
+// ----------------------------------------------------------------------------
+// TYPEDEF : sc_fxtype_context
+//
+// Context type for the fixed-point type parameters.
+// ----------------------------------------------------------------------------
+
+typedef sc_context<sc_fxtype_params> sc_fxtype_context;
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+inline
+sc_fxtype_params::sc_fxtype_params()
+: m_wl(), m_iwl(), m_q_mode(), m_o_mode(), m_n_bits()
+{
+ *this = sc_fxtype_context::default_value();
+}
+
+inline
+sc_fxtype_params::sc_fxtype_params( int wl_, int iwl_ )
+: m_wl(), m_iwl(), m_q_mode(), m_o_mode(), m_n_bits()
+{
+ *this = sc_fxtype_context::default_value();
+
+ SC_CHECK_WL_( wl_ );
+ m_wl = wl_;
+ m_iwl = iwl_;
+}
+
+inline
+sc_fxtype_params::sc_fxtype_params( sc_q_mode q_mode_,
+ sc_o_mode o_mode_, int n_bits_ )
+: m_wl(), m_iwl(), m_q_mode(), m_o_mode(), m_n_bits()
+{
+ *this = sc_fxtype_context::default_value();
+
+ SC_CHECK_N_BITS_( n_bits_ );
+ m_q_mode = q_mode_;
+ m_o_mode = o_mode_;
+ m_n_bits = n_bits_;
+}
+
+inline
+sc_fxtype_params::sc_fxtype_params( int wl_, int iwl_,
+ sc_q_mode q_mode_,
+ sc_o_mode o_mode_, int n_bits_ )
+: m_wl(), m_iwl(), m_q_mode(), m_o_mode(), m_n_bits()
+{
+ SC_CHECK_WL_( wl_ );
+ SC_CHECK_N_BITS_( n_bits_ );
+ m_wl = wl_;
+ m_iwl = iwl_;
+ m_q_mode = q_mode_;
+ m_o_mode = o_mode_;
+ m_n_bits = n_bits_;
+}
+
+inline
+sc_fxtype_params::sc_fxtype_params( const sc_fxtype_params& a )
+: m_wl( a.m_wl ), m_iwl( a.m_iwl ),
+ m_q_mode( a.m_q_mode ),
+ m_o_mode( a.m_o_mode ), m_n_bits( a.m_n_bits )
+{}
+
+inline
+sc_fxtype_params::sc_fxtype_params( const sc_fxtype_params& a,
+ int wl_, int iwl_ )
+: m_wl( wl_ ), m_iwl( iwl_ ),
+ m_q_mode( a.m_q_mode ),
+ m_o_mode( a.m_o_mode ), m_n_bits( a.m_n_bits )
+{}
+
+inline
+sc_fxtype_params::sc_fxtype_params( const sc_fxtype_params& a,
+ sc_q_mode q_mode_,
+ sc_o_mode o_mode_, int n_bits_ )
+: m_wl( a.m_wl ), m_iwl( a.m_iwl ),
+ m_q_mode( q_mode_ ),
+ m_o_mode( o_mode_ ), m_n_bits( n_bits_ )
+{}
+
+inline
+sc_fxtype_params::sc_fxtype_params( sc_without_context )
+: m_wl ( SC_DEFAULT_WL_ ),
+ m_iwl ( SC_DEFAULT_IWL_ ),
+ m_q_mode( SC_DEFAULT_Q_MODE_ ),
+ m_o_mode( SC_DEFAULT_O_MODE_ ),
+ m_n_bits( SC_DEFAULT_N_BITS_ )
+{}
+
+
+inline
+sc_fxtype_params&
+sc_fxtype_params::operator = ( const sc_fxtype_params& a )
+{
+ if( &a != this )
+ {
+ m_wl = a.m_wl;
+ m_iwl = a.m_iwl;
+ m_q_mode = a.m_q_mode;
+ m_o_mode = a.m_o_mode;
+ m_n_bits = a.m_n_bits;
+ }
+ return *this;
+}
+
+
+inline
+bool
+operator == ( const sc_fxtype_params& a, const sc_fxtype_params& b )
+{
+ return ( a.m_wl == b.m_wl &&
+ a.m_iwl == b.m_iwl &&
+ a.m_q_mode == b.m_q_mode &&
+ a.m_o_mode == b.m_o_mode &&
+ a.m_n_bits == b.m_n_bits );
+}
+
+inline
+bool
+operator != ( const sc_fxtype_params& a, const sc_fxtype_params& b )
+{
+ return ( a.m_wl != b.m_wl ||
+ a.m_iwl != b.m_iwl ||
+ a.m_q_mode != b.m_q_mode ||
+ a.m_o_mode != b.m_o_mode ||
+ a.m_n_bits != b.m_n_bits );
+}
+
+
+inline
+int
+sc_fxtype_params::wl() const
+{
+ return m_wl;
+}
+
+inline
+void
+sc_fxtype_params::wl( int wl_ )
+{
+ SC_CHECK_WL_( wl_ );
+ m_wl = wl_;
+}
+
+
+inline
+int
+sc_fxtype_params::iwl() const
+{
+ return m_iwl;
+}
+
+inline
+void
+sc_fxtype_params::iwl( int iwl_ )
+{
+ m_iwl = iwl_;
+}
+
+
+inline
+sc_q_mode
+sc_fxtype_params::q_mode() const
+{
+ return m_q_mode;
+}
+
+inline
+void
+sc_fxtype_params::q_mode( sc_q_mode q_mode_ )
+{
+ m_q_mode = q_mode_;
+}
+
+
+inline
+sc_o_mode
+sc_fxtype_params::o_mode() const
+{
+ return m_o_mode;
+}
+
+inline
+void
+sc_fxtype_params::o_mode( sc_o_mode o_mode_ )
+{
+ m_o_mode = o_mode_;
+}
+
+
+inline
+int
+sc_fxtype_params::n_bits() const
+{
+ return m_n_bits;
+}
+
+inline
+void
+sc_fxtype_params::n_bits( int n_bits_ )
+{
+ SC_CHECK_N_BITS_( n_bits_ );
+ m_n_bits = n_bits_;
+}
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, const sc_fxtype_params& a )
+{
+ a.print( os );
+ return os;
+}
+
+} // namespace sc_dt
+
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxval.cpp b/ext/systemc/src/sysc/datatypes/fx/sc_fxval.cpp
new file mode 100644
index 000000000..3ba5fbacd
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxval.cpp
@@ -0,0 +1,884 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_fxval.cpp -
+
+ Original Author: Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// $Log: sc_fxval.cpp,v $
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:58 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <math.h>
+#include <float.h>
+
+#include "sysc/datatypes/fx/sc_fxval.h"
+
+
+namespace sc_dt
+{
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxval
+//
+// Fixed-point value type; arbitrary precision.
+// ----------------------------------------------------------------------------
+
+// explicit conversion to character string
+
+const std::string
+sc_fxval::to_string() const
+{
+ return std::string( m_rep->to_string( SC_DEC, -1, SC_E ) );
+}
+
+const std::string
+sc_fxval::to_string( sc_numrep numrep ) const
+{
+ return std::string( m_rep->to_string( numrep, -1, SC_E ) );
+}
+
+const std::string
+sc_fxval::to_string( sc_numrep numrep, bool w_prefix ) const
+{
+ return std::string( m_rep->to_string( numrep, (w_prefix ? 1 : 0), SC_E ) );
+}
+
+const std::string
+sc_fxval::to_string( sc_fmt fmt ) const
+{
+ return std::string( m_rep->to_string( SC_DEC, -1, fmt ) );
+}
+
+const std::string
+sc_fxval::to_string( sc_numrep numrep, sc_fmt fmt ) const
+{
+ return std::string( m_rep->to_string( numrep, -1, fmt ) );
+}
+
+const std::string
+sc_fxval::to_string( sc_numrep numrep, bool w_prefix, sc_fmt fmt ) const
+{
+ return std::string( m_rep->to_string( numrep, (w_prefix ? 1 : 0), fmt ) );
+}
+
+
+const std::string
+sc_fxval::to_dec() const
+{
+ return std::string( m_rep->to_string( SC_DEC, -1, SC_E ) );
+}
+
+const std::string
+sc_fxval::to_bin() const
+{
+ return std::string( m_rep->to_string( SC_BIN, -1, SC_E ) );
+}
+
+const std::string
+sc_fxval::to_oct() const
+{
+ return std::string( m_rep->to_string( SC_OCT, -1, SC_E ) );
+}
+
+const std::string
+sc_fxval::to_hex() const
+{
+ return std::string( m_rep->to_string( SC_HEX, -1, SC_E ) );
+}
+
+
+// print or dump content
+
+void
+sc_fxval::print( ::std::ostream& os ) const
+{
+ m_rep->print( os );
+}
+
+void
+sc_fxval::scan( ::std::istream& is )
+{
+ std::string s;
+ is >> s;
+ *this = s.c_str();
+}
+
+void
+sc_fxval::dump( ::std::ostream& os ) const
+{
+ os << "sc_fxval" << ::std::endl;
+ os << "(" << ::std::endl;
+ os << "rep = ";
+ m_rep->dump( os );
+ // TO BE COMPLETED
+ // os << "r_flag = " << m_r_flag << ::std::endl;
+ // os << "observer = ";
+ // if( m_observer != 0 )
+ // m_observer->dump( os );
+ // else
+ // os << "0" << ::std::endl;
+ os << ")" << ::std::endl;
+}
+
+
+// protected methods and friend functions
+
+sc_fxval_observer*
+sc_fxval::lock_observer() const
+{
+ SC_ASSERT_( m_observer != 0, "lock observer failed" );
+ sc_fxval_observer* tmp = m_observer;
+ m_observer = 0;
+ return tmp;
+}
+
+void
+sc_fxval::unlock_observer( sc_fxval_observer* observer_ ) const
+{
+ SC_ASSERT_( observer_ != 0, "unlock observer failed" );
+ m_observer = observer_;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxval_fast
+//
+// Fixed-point value types; limited precision.
+// ----------------------------------------------------------------------------
+
+static
+void
+print_dec( scfx_string& s, scfx_ieee_double id, int w_prefix, sc_fmt fmt )
+{
+ if( id.negative() != 0 )
+ {
+ id.negative( 0 );
+ s += '-';
+ }
+
+ if( w_prefix == 1 ) {
+ scfx_print_prefix( s, SC_DEC );
+ }
+
+ if( id.is_zero() )
+ {
+ s += '0';
+ return;
+ }
+
+ // split 'id' into its integer and fractional part
+
+ double int_part;
+ double frac_part = modf( static_cast<double>( id ), &int_part );
+
+ int i;
+
+ // print integer part
+
+ int int_digits = 0;
+ int int_zeros = 0;
+
+ if( int_part != 0.0 )
+ {
+ int_digits = (int) ceil( log10( int_part + 1.0 ) );
+
+ int len = s.length();
+ s.append( int_digits );
+
+ bool zero_digits = ( frac_part == 0.0 && fmt != SC_F );
+
+ for( i = int_digits + len - 1; i >= len; i-- )
+ {
+ unsigned int remainder = (unsigned int) fmod( int_part, 10.0 );
+ s[i] = static_cast<char>( '0' + remainder );
+
+ if( zero_digits )
+ {
+ if( remainder == 0 )
+ int_zeros ++;
+ else
+ zero_digits = false;
+ }
+
+ int_part /= 10.0;
+ }
+
+ // discard trailing zeros from int_part
+ s.discard( int_zeros );
+
+ if( s[len] == '0' )
+ {
+ // int_digits was overestimated by one
+ s.remove( len );
+ -- int_digits;
+ }
+ }
+
+ // print fractional part
+
+ int frac_digits = 0;
+ int frac_zeros = 0;
+
+ if( frac_part != 0.0 )
+ {
+ s += '.';
+
+ bool zero_digits = ( int_digits == 0 && fmt != SC_F );
+
+ frac_zeros = (int) floor( - log10( frac_part + DBL_EPSILON ) );
+
+ frac_part *= pow( 10.0, frac_zeros );
+
+ frac_digits = frac_zeros;
+ if( ! zero_digits )
+ {
+ for( i = 0; i < frac_zeros; i ++ )
+ s += '0';
+ frac_zeros = 0;
+ }
+
+ while( frac_part != 0.0 )
+ {
+ frac_part *= 10.0;
+ int n = static_cast<int>( frac_part );
+
+ if( zero_digits )
+ {
+ if( n == 0 )
+ frac_zeros ++;
+ else
+ zero_digits = false;
+ }
+
+ if( ! zero_digits )
+ s += static_cast<char>( '0' + n );
+
+ frac_part -= n;
+ frac_digits ++;
+ }
+ }
+
+ // print exponent
+
+ if( fmt != SC_F )
+ {
+ if( frac_digits == 0 )
+ scfx_print_exp( s, int_zeros );
+ else if( int_digits == 0 )
+ scfx_print_exp( s, - frac_zeros );
+ }
+}
+
+
+static
+void
+print_other( scfx_string& s, const scfx_ieee_double& id, sc_numrep numrep,
+ int w_prefix, sc_fmt fmt, const scfx_params* params )
+{
+ scfx_ieee_double id2 = id;
+
+ sc_numrep numrep2 = numrep;
+
+ bool numrep_is_sm = ( numrep == SC_BIN_SM ||
+ numrep == SC_OCT_SM ||
+ numrep == SC_HEX_SM );
+
+ if( numrep_is_sm )
+ {
+ if( id2.negative() != 0 )
+ {
+ s += '-';
+ id2.negative( 0 );
+ }
+ switch( numrep )
+ {
+ case SC_BIN_SM:
+ numrep2 = SC_BIN_US;
+ break;
+ case SC_OCT_SM:
+ numrep2 = SC_OCT_US;
+ break;
+ case SC_HEX_SM:
+ numrep2 = SC_HEX_US;
+ break;
+ default:
+ ;
+ }
+ }
+
+ if( w_prefix != 0 ) {
+ scfx_print_prefix( s, numrep );
+ }
+
+ numrep = numrep2;
+
+ sc_fxval_fast a( id2 );
+
+ int msb, lsb;
+
+ if( params != 0 )
+ {
+ msb = params->iwl() - 1;
+ lsb = params->iwl() - params->wl();
+
+ if( params->enc() == SC_TC_ &&
+ ( numrep == SC_BIN_US ||
+ numrep == SC_OCT_US ||
+ numrep == SC_HEX_US ) &&
+ ! numrep_is_sm &&
+ params->wl() > 1 )
+ -- msb;
+ else if( params->enc() == SC_US_ &&
+ ( numrep == SC_BIN ||
+ numrep == SC_OCT ||
+ numrep == SC_HEX ||
+ numrep == SC_CSD ) )
+ ++ msb;
+ }
+ else
+ {
+ if( a.is_zero() )
+ {
+ msb = 0;
+ lsb = 0;
+ }
+ else
+ {
+ msb = id2.exponent() + 1;
+ while( a.get_bit( msb ) == a.get_bit( msb - 1 ) )
+ -- msb;
+
+ if( numrep == SC_BIN_US ||
+ numrep == SC_OCT_US ||
+ numrep == SC_HEX_US )
+ -- msb;
+
+ lsb = id2.exponent() - 52;
+ while( ! a.get_bit( lsb ) )
+ ++ lsb;
+ }
+ }
+
+ int step;
+
+ switch( numrep )
+ {
+ case SC_BIN:
+ case SC_BIN_US:
+ case SC_CSD:
+ step = 1;
+ break;
+ case SC_OCT:
+ case SC_OCT_US:
+ step = 3;
+ break;
+ case SC_HEX:
+ case SC_HEX_US:
+ step = 4;
+ break;
+ default:
+ step = 0;
+ }
+
+ msb = (int) ceil( double( msb + 1 ) / step ) * step - 1;
+
+ lsb = (int) floor( double( lsb ) / step ) * step;
+
+ if( msb < 0 )
+ {
+ s += '.';
+ if( fmt == SC_F )
+ {
+ int sign = ( id2.negative() != 0 ) ? ( 1 << step ) - 1 : 0;
+ for( int i = ( msb + 1 ) / step; i < 0; i ++ )
+ {
+ if( sign < 10 )
+ s += static_cast<char>( sign + '0' );
+ else
+ s += static_cast<char>( sign + 'a' - 10 );
+ }
+ }
+ }
+
+ int i = msb;
+ while( i >= lsb )
+ {
+ int value = 0;
+ for( int j = step - 1; j >= 0; -- j )
+ {
+ value += static_cast<int>( a.get_bit( i ) ) << j;
+ -- i;
+ }
+ if( value < 10 )
+ s += static_cast<char>( value + '0' );
+ else
+ s += static_cast<char>( value + 'a' - 10 );
+ if( i == -1 )
+ s += '.';
+ }
+
+ if( lsb > 0 && fmt == SC_F )
+ {
+ for( int i = lsb / step; i > 0; i -- )
+ s += '0';
+ }
+
+ if( s[s.length() - 1] == '.' )
+ s.discard( 1 );
+
+ if( fmt != SC_F )
+ {
+ if( msb < 0 )
+ scfx_print_exp( s, ( msb + 1 ) / step );
+ else if( lsb > 0 )
+ scfx_print_exp( s, lsb / step );
+ }
+
+ if( numrep == SC_CSD )
+ scfx_tc2csd( s, w_prefix );
+}
+
+
+const char*
+to_string( const scfx_ieee_double& id, sc_numrep numrep, int w_prefix,
+ sc_fmt fmt, const scfx_params* params = 0 )
+{
+ static scfx_string s;
+
+ s.clear();
+
+ if( id.is_nan() )
+ scfx_print_nan( s );
+ else if( id.is_inf() )
+ scfx_print_inf( s, static_cast<bool>( id.negative() ) );
+ else if( id.negative() && ! id.is_zero() &&
+ ( numrep == SC_BIN_US ||
+ numrep == SC_OCT_US ||
+ numrep == SC_HEX_US ) )
+ s += "negative";
+ else if( numrep == SC_DEC )
+ sc_dt::print_dec( s, id, w_prefix, fmt );
+ else
+ sc_dt::print_other( s, id, numrep, w_prefix, fmt, params );
+
+ return s;
+}
+
+
+// explicit conversion to character string
+
+const std::string
+sc_fxval_fast::to_string() const
+{
+ return std::string( sc_dt::to_string( m_val, SC_DEC, -1, SC_E ) );
+}
+
+const std::string
+sc_fxval_fast::to_string( sc_numrep numrep ) const
+{
+ return std::string( sc_dt::to_string( m_val, numrep, -1, SC_E ) );
+}
+
+const std::string
+sc_fxval_fast::to_string( sc_numrep numrep, bool w_prefix ) const
+{
+ return std::string( sc_dt::to_string( m_val, numrep, (w_prefix ? 1 : 0),
+ SC_E ) );
+}
+
+const std::string
+sc_fxval_fast::to_string( sc_fmt fmt ) const
+{
+ return std::string( sc_dt::to_string( m_val, SC_DEC, -1, fmt ) );
+}
+
+const std::string
+sc_fxval_fast::to_string( sc_numrep numrep, sc_fmt fmt ) const
+{
+ return std::string( sc_dt::to_string( m_val, numrep, -1, fmt ) );
+}
+
+const std::string
+sc_fxval_fast::to_string( sc_numrep numrep, bool w_prefix, sc_fmt fmt ) const
+{
+ return std::string( sc_dt::to_string( m_val, numrep, (w_prefix ? 1 : 0),
+ fmt ) );
+}
+
+
+const std::string
+sc_fxval_fast::to_dec() const
+{
+ return std::string( sc_dt::to_string( m_val, SC_DEC, -1, SC_E ) );
+}
+
+const std::string
+sc_fxval_fast::to_bin() const
+{
+ return std::string( sc_dt::to_string( m_val, SC_BIN, -1, SC_E ) );
+}
+
+const std::string
+sc_fxval_fast::to_oct() const
+{
+ return std::string( sc_dt::to_string( m_val, SC_OCT, -1, SC_E ) );
+}
+
+const std::string
+sc_fxval_fast::to_hex() const
+{
+ return std::string( sc_dt::to_string( m_val, SC_HEX, -1, SC_E ) );
+}
+
+
+// print or dump content
+
+void
+sc_fxval_fast::print( ::std::ostream& os ) const
+{
+ os << sc_dt::to_string( m_val, SC_DEC, -1, SC_E );
+}
+
+void
+sc_fxval_fast::scan( ::std::istream& is )
+{
+ std::string s;
+ is >> s;
+ *this = s.c_str();
+}
+
+void
+sc_fxval_fast::dump( ::std::ostream& os ) const
+{
+ os << "sc_fxval_fast" << ::std::endl;
+ os << "(" << ::std::endl;
+ os << "val = " << m_val << ::std::endl;
+ // TO BE COMPLETED
+ // os << "r_flag = " << m_r_flag << ::std::endl;
+ // os << "observer = ";
+ // if( m_observer != 0 )
+ // m_observer->dump( os );
+ // else
+ // os << "0" << ::std::endl;
+ os << ")" << ::std::endl;
+}
+
+
+// internal use only;
+bool
+sc_fxval_fast::get_bit( int i ) const
+{
+ scfx_ieee_double id( m_val );
+ if( id.is_zero() || id.is_nan() || id.is_inf() )
+ return false;
+
+ // convert to two's complement
+
+ unsigned int m0 = id.mantissa0();
+ unsigned int m1 = id.mantissa1();
+
+ if( id.is_normal() )
+ m0 += 1U << 20;
+
+ if( id.negative() != 0 )
+ {
+ m0 = ~ m0;
+ m1 = ~ m1;
+ unsigned int tmp = m1;
+ m1 += 1U;
+ if( m1 <= tmp )
+ m0 += 1U;
+ }
+
+ // get the right bit
+
+ int j = i - id.exponent();
+ if( ( j += 20 ) >= 32 )
+ return ( ( m0 & 1U << 31 ) != 0 );
+ else if( j >= 0 )
+ return ( ( m0 & 1U << j ) != 0 );
+ else if( ( j += 32 ) >= 0 )
+ return ( ( m1 & 1U << j ) != 0 );
+ else
+ return false;
+}
+
+
+// protected methods and friend functions
+
+sc_fxval_fast_observer*
+sc_fxval_fast::lock_observer() const
+{
+ SC_ASSERT_( m_observer != 0, "lock observer failed" );
+ sc_fxval_fast_observer* tmp = m_observer;
+ m_observer = 0;
+ return tmp;
+}
+
+void
+sc_fxval_fast::unlock_observer( sc_fxval_fast_observer* observer_ ) const
+{
+ SC_ASSERT_( observer_ != 0, "unlock observer failed" );
+ m_observer = observer_;
+}
+
+
+#define SCFX_FAIL_IF_(cnd) \
+{ \
+ if( ( cnd ) ) \
+ return static_cast<double>( scfx_ieee_double::nan() ); \
+}
+
+double
+sc_fxval_fast::from_string( const char* s )
+{
+ SCFX_FAIL_IF_( s == 0 || *s == 0 );
+
+ scfx_string s2;
+ s2 += s;
+ s2 += '\0';
+
+ bool sign_char;
+ int sign = scfx_parse_sign( s, sign_char );
+
+ sc_numrep numrep = scfx_parse_prefix( s );
+
+ int base = 0;
+
+ switch( numrep )
+ {
+ case SC_DEC:
+ {
+ base = 10;
+ if( scfx_is_nan( s ) ) // special case: NaN
+ return static_cast<double>( scfx_ieee_double::nan() );
+ if( scfx_is_inf( s ) ) // special case: Infinity
+ return static_cast<double>( scfx_ieee_double::inf( sign ) );
+ break;
+ }
+ case SC_BIN:
+ case SC_BIN_US:
+ {
+ SCFX_FAIL_IF_( sign_char );
+ base = 2;
+ break;
+ }
+
+ case SC_BIN_SM:
+ {
+ base = 2;
+ break;
+ }
+ case SC_OCT:
+ case SC_OCT_US:
+ {
+ SCFX_FAIL_IF_( sign_char );
+ base = 8;
+ break;
+ }
+ case SC_OCT_SM:
+ {
+ base = 8;
+ break;
+ }
+ case SC_HEX:
+ case SC_HEX_US:
+ {
+ SCFX_FAIL_IF_( sign_char );
+ base = 16;
+ break;
+ }
+ case SC_HEX_SM:
+ {
+ base = 16;
+ break;
+ }
+ case SC_CSD:
+ {
+ SCFX_FAIL_IF_( sign_char );
+ base = 2;
+ scfx_csd2tc( s2 );
+ s = (const char*) s2 + 4;
+ numrep = SC_BIN;
+ break;
+ }
+ default:;// Martin, what is default???
+ }
+
+ //
+ // find end of mantissa and count the digits and points
+ //
+
+ const char *end = s;
+ bool based_point = false;
+ int int_digits = 0;
+ int frac_digits = 0;
+
+ while( *end )
+ {
+ if( scfx_exp_start( end ) )
+ break;
+
+ if( *end == '.' )
+ {
+ SCFX_FAIL_IF_( based_point );
+ based_point = true;
+ }
+ else
+ {
+ SCFX_FAIL_IF_( ! scfx_is_digit( *end, numrep ) );
+ if( based_point )
+ frac_digits ++;
+ else
+ int_digits ++;
+ }
+
+ end ++;
+ }
+
+ SCFX_FAIL_IF_( int_digits == 0 && frac_digits == 0 );
+
+ // [ exponent ]
+
+ int exponent = 0;
+
+ if( *end )
+ {
+ for( const char *e = end + 2; *e; e ++ )
+ SCFX_FAIL_IF_( ! scfx_is_digit( *e, SC_DEC ) );
+ exponent = atoi( end + 1 );
+ }
+
+ //
+ // convert the mantissa
+ //
+
+ double integer = 0.0;
+
+ if( int_digits != 0 )
+ {
+
+ bool first_digit = true;
+
+ for( ; s < end; s ++ )
+ {
+ if( *s == '.' )
+ break;
+
+ if( first_digit )
+ {
+ integer = scfx_to_digit( *s, numrep );
+ switch( numrep )
+ {
+ case SC_BIN:
+ case SC_OCT:
+ case SC_HEX:
+ {
+ if( integer >= ( base >> 1 ) )
+ integer -= base; // two's complement
+ break;
+ }
+ default:
+ ;
+ }
+ first_digit = false;
+ }
+ else
+ {
+ integer *= base;
+ integer += scfx_to_digit( *s, numrep );
+ }
+ }
+ }
+
+ // [ . fraction ]
+
+ double fraction = 0.0;
+
+ if( frac_digits != 0 )
+ {
+ s ++; // skip '.'
+
+ bool first_digit = ( int_digits == 0 );
+
+ double scale = 1.0;
+
+ for( ; s < end; s ++ )
+ {
+ scale /= base;
+
+ if( first_digit )
+ {
+ fraction = scfx_to_digit( *s, numrep );
+ switch( numrep )
+ {
+ case SC_BIN:
+ case SC_OCT:
+ case SC_HEX:
+ {
+ if( fraction >= ( base >> 1 ) )
+ fraction -= base; // two's complement
+ break;
+ }
+ default:
+ ;
+ }
+ fraction *= scale;
+ first_digit = false;
+ }
+ else
+ fraction += scfx_to_digit( *s, numrep ) * scale;
+ }
+ }
+
+ double exp = ( exponent != 0 ) ? pow( (double) base, (double) exponent )
+ : 1;
+
+ return ( sign * ( integer + fraction ) * exp );
+}
+
+#undef SCFX_FAIL_IF_
+
+} // namespace sc_dt
+
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxval.h b/ext/systemc/src/sysc/datatypes/fx/sc_fxval.h
new file mode 100644
index 000000000..1f199875c
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxval.h
@@ -0,0 +1,2269 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_fxval.h -
+
+ Original Author: Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_fxval.h,v $
+// Revision 1.3 2011/01/19 18:57:40 acg
+// Andy Goodrich: changes for IEEE_1666_2011.
+//
+// Revision 1.2 2010/12/07 20:09:08 acg
+// Andy Goodrich: Philipp Hartmann's constructor disambiguation fix
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:58 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#ifndef SC_FXVAL_H
+#define SC_FXVAL_H
+
+
+#include "sysc/datatypes/fx/scfx_rep.h"
+#ifndef SC_FX_EXCLUDE_OTHER
+#include "sysc/datatypes/int/sc_int_base.h"
+#include "sysc/datatypes/int/sc_uint_base.h"
+#include "sysc/datatypes/int/sc_signed.h"
+#include "sysc/datatypes/int/sc_unsigned.h"
+#endif
+#include "sysc/datatypes/fx/sc_fxval_observer.h"
+
+#ifdef SC_FXVAL_IMPLICIT_CONV
+# define SCFX_EXPLICIT_ // nothing
+#else
+# define SCFX_EXPLICIT_ explicit
+#endif
+#ifdef SC_FXVAL_IMPLICIT_OTHER
+# define SCFX_EXPLICIT_OTHER_
+#else
+# define SCFX_EXPLICIT_OTHER_ explicit
+#endif
+
+namespace sc_dt
+{
+
+// classes defined in this module
+class sc_fxval;
+class sc_fxval_fast;
+
+// forward class declarations
+class sc_fxnum;
+class sc_fxnum_fast;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxval
+//
+// Fixed-point value type; arbitrary precision.
+// ----------------------------------------------------------------------------
+
+class sc_fxval
+{
+
+ friend class sc_fxnum;
+
+protected:
+
+ sc_fxval_observer* observer() const;
+
+public:
+
+ // internal use only;
+ explicit sc_fxval( scfx_rep* );
+
+
+ explicit sc_fxval( sc_fxval_observer* = 0 );
+ SCFX_EXPLICIT_ sc_fxval( int, sc_fxval_observer* = 0 );
+ SCFX_EXPLICIT_ sc_fxval( unsigned int, sc_fxval_observer* = 0 );
+ SCFX_EXPLICIT_ sc_fxval( long, sc_fxval_observer* = 0 );
+ SCFX_EXPLICIT_ sc_fxval( unsigned long, sc_fxval_observer* = 0 );
+ SCFX_EXPLICIT_ sc_fxval( float, sc_fxval_observer* = 0 );
+ SCFX_EXPLICIT_ sc_fxval( double, sc_fxval_observer* = 0 );
+ SCFX_EXPLICIT_ sc_fxval( const char*, sc_fxval_observer* = 0 );
+ sc_fxval( const sc_fxval&, sc_fxval_observer* = 0 );
+ sc_fxval( const sc_fxval_fast&, sc_fxval_observer* = 0 );
+ sc_fxval( const sc_fxnum&, sc_fxval_observer* = 0 );
+ sc_fxval( const sc_fxnum_fast&, sc_fxval_observer* = 0 );
+#ifndef SC_FX_EXCLUDE_OTHER
+ SCFX_EXPLICIT_OTHER_ sc_fxval( int64, sc_fxval_observer* = 0 );
+ SCFX_EXPLICIT_OTHER_ sc_fxval( uint64, sc_fxval_observer* = 0 );
+ SCFX_EXPLICIT_OTHER_ sc_fxval( const sc_int_base&, sc_fxval_observer* = 0 );
+ SCFX_EXPLICIT_OTHER_ sc_fxval( const sc_uint_base&, sc_fxval_observer* = 0 );
+ SCFX_EXPLICIT_OTHER_ sc_fxval( const sc_signed&, sc_fxval_observer* = 0 );
+ SCFX_EXPLICIT_OTHER_ sc_fxval( const sc_unsigned&, sc_fxval_observer* = 0 );
+#endif
+
+ ~sc_fxval();
+
+
+ // internal use only;
+ const scfx_rep* get_rep() const;
+ void set_rep( scfx_rep* );
+
+
+ // unary operators
+
+ const sc_fxval operator - () const;
+ const sc_fxval& operator + () const;
+
+
+ // unary functions
+
+ friend void neg( sc_fxval&, const sc_fxval& );
+
+
+ // binary operators
+
+#define DECL_BIN_OP_T(op,tp) \
+ friend const sc_fxval operator op ( const sc_fxval&, tp ); \
+ friend const sc_fxval operator op ( tp, const sc_fxval& );
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DECL_BIN_OP_OTHER(op) \
+ DECL_BIN_OP_T(op,int64) \
+ DECL_BIN_OP_T(op,uint64) \
+ DECL_BIN_OP_T(op,const sc_int_base&) \
+ DECL_BIN_OP_T(op,const sc_uint_base&) \
+ DECL_BIN_OP_T(op,const sc_signed&) \
+ DECL_BIN_OP_T(op,const sc_unsigned&)
+#else
+#define DECL_BIN_OP_OTHER(op)
+#endif
+
+#define DECL_BIN_OP(op,dummy) \
+ friend const sc_fxval operator op ( const sc_fxval&, const sc_fxval& ); \
+ DECL_BIN_OP_T(op,int) \
+ DECL_BIN_OP_T(op,unsigned int) \
+ DECL_BIN_OP_T(op,long) \
+ DECL_BIN_OP_T(op,unsigned long) \
+ DECL_BIN_OP_T(op,float) \
+ DECL_BIN_OP_T(op,double) \
+ DECL_BIN_OP_T(op,const char*) \
+ DECL_BIN_OP_T(op,const sc_fxval_fast&) \
+ DECL_BIN_OP_T(op,const sc_fxnum_fast&) \
+ DECL_BIN_OP_OTHER(op)
+
+ DECL_BIN_OP(*,mult)
+ DECL_BIN_OP(+,add)
+ DECL_BIN_OP(-,sub)
+// declaration below doesn't compile with BCB5 (E2206)
+// DECL_BIN_OP(/,div)
+// previous macro expanded
+ friend const sc_fxval operator / ( const sc_fxval&, const sc_fxval& );
+ DECL_BIN_OP_T(/,int)
+ DECL_BIN_OP_T(/,unsigned int)
+ DECL_BIN_OP_T(/,long)
+ DECL_BIN_OP_T(/,unsigned long)
+ DECL_BIN_OP_T(/,float)
+ DECL_BIN_OP_T(/,double)
+ DECL_BIN_OP_T(/,const char*)
+ DECL_BIN_OP_T(/,const sc_fxval_fast&)
+ DECL_BIN_OP_T(/,const sc_fxnum_fast&)
+// DECL_BIN_OP_OTHER(/)
+#ifndef SC_FX_EXCLUDE_OTHER
+ DECL_BIN_OP_T(/,int64) \
+ DECL_BIN_OP_T(/,uint64) \
+ DECL_BIN_OP_T(/,const sc_int_base&) \
+ DECL_BIN_OP_T(/,const sc_uint_base&) \
+ DECL_BIN_OP_T(/,const sc_signed&) \
+ DECL_BIN_OP_T(/,const sc_unsigned&)
+#endif
+
+
+#undef DECL_BIN_OP_T
+#undef DECL_BIN_OP_OTHER
+#undef DECL_BIN_OP
+
+ friend const sc_fxval operator << ( const sc_fxval&, int );
+ friend const sc_fxval operator >> ( const sc_fxval&, int );
+
+
+ // binary functions
+
+#define DECL_BIN_FNC_T(fnc,tp) \
+ friend void fnc ( sc_fxval&, const sc_fxval&, tp ); \
+ friend void fnc ( sc_fxval&, tp, const sc_fxval& );
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DECL_BIN_FNC_OTHER(fnc) \
+ DECL_BIN_FNC_T(fnc,int64) \
+ DECL_BIN_FNC_T(fnc,uint64) \
+ DECL_BIN_FNC_T(fnc,const sc_int_base&) \
+ DECL_BIN_FNC_T(fnc,const sc_uint_base&) \
+ DECL_BIN_FNC_T(fnc,const sc_signed&) \
+ DECL_BIN_FNC_T(fnc,const sc_unsigned&)
+#else
+#define DECL_BIN_FNC_OTHER(fnc)
+#endif
+
+#define DECL_BIN_FNC(fnc) \
+ friend void fnc ( sc_fxval&, const sc_fxval&, const sc_fxval& ); \
+ DECL_BIN_FNC_T(fnc,int) \
+ DECL_BIN_FNC_T(fnc,unsigned int) \
+ DECL_BIN_FNC_T(fnc,long) \
+ DECL_BIN_FNC_T(fnc,unsigned long) \
+ DECL_BIN_FNC_T(fnc,float) \
+ DECL_BIN_FNC_T(fnc,double) \
+ DECL_BIN_FNC_T(fnc,const char*) \
+ DECL_BIN_FNC_T(fnc,const sc_fxval_fast&) \
+ DECL_BIN_FNC_T(fnc,const sc_fxnum_fast&) \
+ DECL_BIN_FNC_OTHER(fnc)
+
+ DECL_BIN_FNC(mult)
+ DECL_BIN_FNC(div)
+ DECL_BIN_FNC(add)
+ DECL_BIN_FNC(sub)
+
+#undef DECL_BIN_FNC_T
+#undef DECL_BIN_FNC_OTHER
+#undef DECL_BIN_FNC
+
+ friend void lshift( sc_fxval&, const sc_fxval&, int );
+ friend void rshift( sc_fxval&, const sc_fxval&, int );
+
+
+ // relational (including equality) operators
+
+#define DECL_REL_OP_T(op,tp) \
+ friend bool operator op ( const sc_fxval&, tp ); \
+ friend bool operator op ( tp, const sc_fxval& );
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DECL_REL_OP_OTHER(op) \
+ DECL_REL_OP_T(op,int64) \
+ DECL_REL_OP_T(op,uint64) \
+ DECL_REL_OP_T(op,const sc_int_base&) \
+ DECL_REL_OP_T(op,const sc_uint_base&) \
+ DECL_REL_OP_T(op,const sc_signed&) \
+ DECL_REL_OP_T(op,const sc_unsigned&)
+#else
+#define DECL_REL_OP_OTHER(op)
+#endif
+
+#define DECL_REL_OP(op) \
+ friend bool operator op ( const sc_fxval&, const sc_fxval& ); \
+ DECL_REL_OP_T(op,int) \
+ DECL_REL_OP_T(op,unsigned int) \
+ DECL_REL_OP_T(op,long) \
+ DECL_REL_OP_T(op,unsigned long) \
+ DECL_REL_OP_T(op,float) \
+ DECL_REL_OP_T(op,double) \
+ DECL_REL_OP_T(op,const char*) \
+ DECL_REL_OP_T(op,const sc_fxval_fast&) \
+ DECL_REL_OP_T(op,const sc_fxnum_fast&) \
+ DECL_REL_OP_OTHER(op)
+
+ DECL_REL_OP(<)
+ DECL_REL_OP(<=)
+ DECL_REL_OP(>)
+ DECL_REL_OP(>=)
+ DECL_REL_OP(==)
+ DECL_REL_OP(!=)
+
+#undef DECL_REL_OP_T
+#undef DECL_REL_OP_OTHER
+#undef DECL_REL_OP
+
+
+ // assignment operators
+
+#define DECL_ASN_OP_T(op,tp) \
+ sc_fxval& operator op( tp );
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DECL_ASN_OP_OTHER(op) \
+ DECL_ASN_OP_T(op,int64) \
+ DECL_ASN_OP_T(op,uint64) \
+ DECL_ASN_OP_T(op,const sc_int_base&) \
+ DECL_ASN_OP_T(op,const sc_uint_base&) \
+ DECL_ASN_OP_T(op,const sc_signed&) \
+ DECL_ASN_OP_T(op,const sc_unsigned&)
+#else
+#define DECL_ASN_OP_OTHER(op)
+#endif
+
+#define DECL_ASN_OP(op) \
+ DECL_ASN_OP_T(op,int) \
+ DECL_ASN_OP_T(op,unsigned int) \
+ DECL_ASN_OP_T(op,long) \
+ DECL_ASN_OP_T(op,unsigned long) \
+ DECL_ASN_OP_T(op,float) \
+ DECL_ASN_OP_T(op,double) \
+ DECL_ASN_OP_T(op,const char*) \
+ DECL_ASN_OP_T(op,const sc_fxval&) \
+ DECL_ASN_OP_T(op,const sc_fxval_fast&) \
+ DECL_ASN_OP_T(op,const sc_fxnum&) \
+ DECL_ASN_OP_T(op,const sc_fxnum_fast&) \
+ DECL_ASN_OP_OTHER(op)
+
+ DECL_ASN_OP(=)
+
+ DECL_ASN_OP(*=)
+ DECL_ASN_OP(/=)
+ DECL_ASN_OP(+=)
+ DECL_ASN_OP(-=)
+
+ DECL_ASN_OP_T(<<=,int)
+ DECL_ASN_OP_T(>>=,int)
+
+#undef DECL_ASN_OP_T
+#undef DECL_ASN_OP_OTHER
+#undef DECL_ASN_OP
+
+
+ // auto-increment and auto-decrement
+
+ const sc_fxval operator ++ ( int );
+ const sc_fxval operator -- ( int );
+
+ sc_fxval& operator ++ ();
+ sc_fxval& operator -- ();
+
+
+ // implicit conversion
+
+ operator double() const; // necessary evil!
+
+
+ // explicit conversion to primitive types
+
+ short to_short() const;
+ unsigned short to_ushort() const;
+ int to_int() const;
+ unsigned int to_uint() const;
+ long to_long() const;
+ unsigned long to_ulong() const;
+ int64 to_int64() const;
+ uint64 to_uint64() const;
+ float to_float() const;
+ double to_double() const;
+
+
+ // explicit conversion to character string
+
+ const std::string to_string() const;
+ const std::string to_string( sc_numrep ) const;
+ const std::string to_string( sc_numrep, bool ) const;
+ const std::string to_string( sc_fmt ) const;
+ const std::string to_string( sc_numrep, sc_fmt ) const;
+ const std::string to_string( sc_numrep, bool, sc_fmt ) const;
+
+ const std::string to_dec() const;
+ const std::string to_bin() const;
+ const std::string to_oct() const;
+ const std::string to_hex() const;
+
+
+ // query value
+
+ bool is_neg() const;
+ bool is_zero() const;
+ bool is_nan() const;
+ bool is_inf() const;
+ bool is_normal() const;
+
+ bool rounding_flag() const;
+
+
+ // print or dump content
+
+ void print( ::std::ostream& = ::std::cout ) const;
+ void scan( ::std::istream& = ::std::cin );
+ void dump( ::std::ostream& = ::std::cout ) const;
+
+
+ // internal use only;
+ bool get_bit( int ) const;
+
+protected:
+
+ sc_fxval_observer* lock_observer() const;
+ void unlock_observer( sc_fxval_observer* ) const;
+
+
+ void get_type( int&, int&, sc_enc& ) const;
+
+ const sc_fxval quantization( const scfx_params&, bool& ) const;
+ const sc_fxval overflow( const scfx_params&, bool& ) const;
+
+private:
+
+ scfx_rep* m_rep;
+
+ mutable sc_fxval_observer* m_observer;
+
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxval_fast
+//
+// Fixed-point value type; limited precision.
+// ----------------------------------------------------------------------------
+
+class sc_fxval_fast
+{
+
+ friend class sc_fxnum_fast;
+
+protected:
+
+ sc_fxval_fast_observer* observer() const;
+
+public:
+
+ explicit sc_fxval_fast( sc_fxval_fast_observer* = 0 );
+ SCFX_EXPLICIT_ sc_fxval_fast( int, sc_fxval_fast_observer* = 0 );
+ SCFX_EXPLICIT_ sc_fxval_fast( unsigned int, sc_fxval_fast_observer* = 0 );
+ SCFX_EXPLICIT_ sc_fxval_fast( long, sc_fxval_fast_observer* = 0 );
+ SCFX_EXPLICIT_ sc_fxval_fast( unsigned long, sc_fxval_fast_observer* = 0 );
+ SCFX_EXPLICIT_ sc_fxval_fast( float, sc_fxval_fast_observer* = 0 );
+ SCFX_EXPLICIT_ sc_fxval_fast( double, sc_fxval_fast_observer* = 0 );
+ SCFX_EXPLICIT_ sc_fxval_fast( const char*, sc_fxval_fast_observer* = 0 );
+ sc_fxval_fast( const sc_fxval&, sc_fxval_fast_observer* = 0 );
+ sc_fxval_fast( const sc_fxval_fast&, sc_fxval_fast_observer* = 0 );
+ sc_fxval_fast( const sc_fxnum&, sc_fxval_fast_observer* = 0 );
+ sc_fxval_fast( const sc_fxnum_fast&, sc_fxval_fast_observer* = 0 );
+#ifndef SC_FX_EXCLUDE_OTHER
+ SCFX_EXPLICIT_OTHER_ sc_fxval_fast( int64, sc_fxval_fast_observer* = 0 );
+ SCFX_EXPLICIT_OTHER_ sc_fxval_fast( uint64, sc_fxval_fast_observer* = 0 );
+ SCFX_EXPLICIT_OTHER_ sc_fxval_fast( const sc_int_base&, sc_fxval_fast_observer* = 0 );
+ SCFX_EXPLICIT_OTHER_ sc_fxval_fast( const sc_uint_base&, sc_fxval_fast_observer* = 0 );
+ SCFX_EXPLICIT_OTHER_ sc_fxval_fast( const sc_signed&, sc_fxval_fast_observer* = 0 );
+ SCFX_EXPLICIT_OTHER_ sc_fxval_fast( const sc_unsigned&, sc_fxval_fast_observer* = 0 );
+#endif
+
+ ~sc_fxval_fast();
+
+ // internal use only;
+ double get_val() const;
+ void set_val( double );
+
+
+ // unary operators
+
+ const sc_fxval_fast operator - () const;
+ const sc_fxval_fast& operator + () const;
+
+
+ // unary functions
+
+ friend void neg( sc_fxval_fast&, const sc_fxval_fast& );
+
+
+ // binary operators
+
+#define DECL_BIN_OP_T(op,tp) \
+ friend const sc_fxval_fast operator op ( const sc_fxval_fast&, tp ); \
+ friend const sc_fxval_fast operator op ( tp, const sc_fxval_fast& );
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DECL_BIN_OP_OTHER(op) \
+ DECL_BIN_OP_T(op,int64) \
+ DECL_BIN_OP_T(op,uint64) \
+ DECL_BIN_OP_T(op,const sc_int_base&) \
+ DECL_BIN_OP_T(op,const sc_uint_base&) \
+ DECL_BIN_OP_T(op,const sc_signed&) \
+ DECL_BIN_OP_T(op,const sc_unsigned&)
+#else
+#define DECL_BIN_OP_OTHER(op)
+#endif
+
+#define DECL_BIN_OP(op,dummy) \
+ friend const sc_fxval_fast operator op ( const sc_fxval_fast&, \
+ const sc_fxval_fast& ); \
+ DECL_BIN_OP_T(op,int) \
+ DECL_BIN_OP_T(op,unsigned int) \
+ DECL_BIN_OP_T(op,long) \
+ DECL_BIN_OP_T(op,unsigned long) \
+ DECL_BIN_OP_T(op,float) \
+ DECL_BIN_OP_T(op,double) \
+ DECL_BIN_OP_T(op,const char*) \
+ DECL_BIN_OP_OTHER(op)
+
+ DECL_BIN_OP(*,mult)
+ DECL_BIN_OP(+,add)
+ DECL_BIN_OP(-,sub)
+// don't use macro
+// DECL_BIN_OP(/,div)
+ friend const sc_fxval_fast operator / ( const sc_fxval_fast&,
+ const sc_fxval_fast& );
+ DECL_BIN_OP_T(/,int)
+ DECL_BIN_OP_T(/,unsigned int)
+ DECL_BIN_OP_T(/,long)
+ DECL_BIN_OP_T(/,unsigned long)
+ DECL_BIN_OP_T(/,float)
+ DECL_BIN_OP_T(/,double)
+ DECL_BIN_OP_T(/,const char*)
+// DECL_BIN_OP_OTHER(/)
+#ifndef SC_FX_EXCLUDE_OTHER
+ DECL_BIN_OP_T(/,int64) \
+ DECL_BIN_OP_T(/,uint64) \
+ DECL_BIN_OP_T(/,const sc_int_base&) \
+ DECL_BIN_OP_T(/,const sc_uint_base&) \
+ DECL_BIN_OP_T(/,const sc_signed&) \
+ DECL_BIN_OP_T(/,const sc_unsigned&)
+#endif
+
+#undef DECL_BIN_OP_T
+#undef DECL_BIN_OP_OTHER
+#undef DECL_BIN_OP
+
+ friend const sc_fxval_fast operator << ( const sc_fxval_fast&, int );
+ friend const sc_fxval_fast operator >> ( const sc_fxval_fast&, int );
+
+
+ // binary functions
+
+#define DECL_BIN_FNC_T(fnc,tp) \
+ friend void fnc ( sc_fxval_fast&, const sc_fxval_fast&, tp ); \
+ friend void fnc ( sc_fxval_fast&, tp, const sc_fxval_fast& );
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DECL_BIN_FNC_OTHER(fnc) \
+ DECL_BIN_FNC_T(fnc,int64) \
+ DECL_BIN_FNC_T(fnc,uint64) \
+ DECL_BIN_FNC_T(fnc,const sc_int_base&) \
+ DECL_BIN_FNC_T(fnc,const sc_uint_base&) \
+ DECL_BIN_FNC_T(fnc,const sc_signed&) \
+ DECL_BIN_FNC_T(fnc,const sc_unsigned&)
+#else
+#define DECL_BIN_FNC_OTHER(fnc)
+#endif
+
+#define DECL_BIN_FNC(fnc) \
+ friend void fnc ( sc_fxval_fast&, const sc_fxval_fast&, \
+ const sc_fxval_fast& ); \
+ DECL_BIN_FNC_T(fnc,int) \
+ DECL_BIN_FNC_T(fnc,unsigned int) \
+ DECL_BIN_FNC_T(fnc,long) \
+ DECL_BIN_FNC_T(fnc,unsigned long) \
+ DECL_BIN_FNC_T(fnc,float) \
+ DECL_BIN_FNC_T(fnc,double) \
+ DECL_BIN_FNC_T(fnc,const char*) \
+ DECL_BIN_FNC_T(fnc,const sc_fxval&) \
+ DECL_BIN_FNC_T(fnc,const sc_fxnum&) \
+ DECL_BIN_FNC_OTHER(fnc)
+
+ DECL_BIN_FNC(mult)
+ DECL_BIN_FNC(div)
+ DECL_BIN_FNC(add)
+ DECL_BIN_FNC(sub)
+
+#undef DECL_BIN_FNC_T
+#undef DECL_BIN_FNC_OTHER
+#undef DECL_BIN_FNC
+
+ friend void lshift( sc_fxval_fast&, const sc_fxval_fast&, int );
+ friend void rshift( sc_fxval_fast&, const sc_fxval_fast&, int );
+
+
+ // relational (including equality) operators
+
+#define DECL_REL_OP_T(op,tp) \
+ friend bool operator op ( const sc_fxval_fast&, tp ); \
+ friend bool operator op ( tp, const sc_fxval_fast& );
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DECL_REL_OP_OTHER(op) \
+ DECL_REL_OP_T(op,int64) \
+ DECL_REL_OP_T(op,uint64) \
+ DECL_REL_OP_T(op,const sc_int_base&) \
+ DECL_REL_OP_T(op,const sc_uint_base&) \
+ DECL_REL_OP_T(op,const sc_signed&) \
+ DECL_REL_OP_T(op,const sc_unsigned&)
+#else
+#define DECL_REL_OP_OTHER(op)
+#endif
+
+#define DECL_REL_OP(op) \
+ friend bool operator op ( const sc_fxval_fast&, const sc_fxval_fast& ); \
+ DECL_REL_OP_T(op,int) \
+ DECL_REL_OP_T(op,unsigned int) \
+ DECL_REL_OP_T(op,long) \
+ DECL_REL_OP_T(op,unsigned long) \
+ DECL_REL_OP_T(op,float) \
+ DECL_REL_OP_T(op,double) \
+ DECL_REL_OP_T(op,const char*) \
+ DECL_REL_OP_OTHER(op)
+
+ DECL_REL_OP(<)
+ DECL_REL_OP(<=)
+ DECL_REL_OP(>)
+ DECL_REL_OP(>=)
+ DECL_REL_OP(==)
+ DECL_REL_OP(!=)
+
+#undef DECL_REL_OP_T
+#undef DECL_REL_OP_OTHER
+#undef DECL_REL_OP
+
+
+ // assignment operators
+
+#define DECL_ASN_OP_T(op,tp) \
+ sc_fxval_fast& operator op( tp );
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DECL_ASN_OP_OTHER(op) \
+ DECL_ASN_OP_T(op,int64) \
+ DECL_ASN_OP_T(op,uint64) \
+ DECL_ASN_OP_T(op,const sc_int_base&) \
+ DECL_ASN_OP_T(op,const sc_uint_base&) \
+ DECL_ASN_OP_T(op,const sc_signed&) \
+ DECL_ASN_OP_T(op,const sc_unsigned&)
+#else
+#define DECL_ASN_OP_OTHER(op)
+#endif
+
+#define DECL_ASN_OP(op) \
+ DECL_ASN_OP_T(op,int) \
+ DECL_ASN_OP_T(op,unsigned int) \
+ DECL_ASN_OP_T(op,long) \
+ DECL_ASN_OP_T(op,unsigned long) \
+ DECL_ASN_OP_T(op,float) \
+ DECL_ASN_OP_T(op,double) \
+ DECL_ASN_OP_T(op,const char*) \
+ DECL_ASN_OP_T(op,const sc_fxval&) \
+ DECL_ASN_OP_T(op,const sc_fxval_fast&) \
+ DECL_ASN_OP_T(op,const sc_fxnum&) \
+ DECL_ASN_OP_T(op,const sc_fxnum_fast&) \
+ DECL_ASN_OP_OTHER(op)
+
+ DECL_ASN_OP(=)
+
+ DECL_ASN_OP(*=)
+ DECL_ASN_OP(/=)
+ DECL_ASN_OP(+=)
+ DECL_ASN_OP(-=)
+
+ DECL_ASN_OP_T(<<=,int)
+ DECL_ASN_OP_T(>>=,int)
+
+#undef DECL_ASN_OP_T
+#undef DECL_ASN_OP_OTHER
+#undef DECL_ASN_OP
+
+
+ // auto-increment and auto-decrement
+
+ const sc_fxval_fast operator ++ ( int );
+ const sc_fxval_fast operator -- ( int );
+
+ sc_fxval_fast& operator ++ ();
+ sc_fxval_fast& operator -- ();
+
+
+ // implicit conversion
+
+ operator double() const; // necessary evil!
+
+
+ // explicit conversion to primitive types
+
+ short to_short() const;
+ unsigned short to_ushort() const;
+ int to_int() const;
+ unsigned int to_uint() const;
+ long to_long() const;
+ unsigned long to_ulong() const;
+ int64 to_int64() const;
+ uint64 to_uint64() const;
+ float to_float() const;
+ double to_double() const;
+
+
+ // explicit conversion to character string
+
+ const std::string to_string() const;
+ const std::string to_string( sc_numrep ) const;
+ const std::string to_string( sc_numrep, bool ) const;
+ const std::string to_string( sc_fmt ) const;
+ const std::string to_string( sc_numrep, sc_fmt ) const;
+ const std::string to_string( sc_numrep, bool, sc_fmt ) const;
+
+ const std::string to_dec() const;
+ const std::string to_bin() const;
+ const std::string to_oct() const;
+ const std::string to_hex() const;
+
+
+ // query value
+
+ bool is_neg() const;
+ bool is_zero() const;
+ bool is_nan() const;
+ bool is_inf() const;
+ bool is_normal() const;
+
+ bool rounding_flag() const;
+
+
+ // print or dump content
+
+ void print( ::std::ostream& = ::std::cout ) const;
+ void scan( ::std::istream& = ::std::cin );
+ void dump( ::std::ostream& = ::std::cout ) const;
+
+
+ // internal use only;
+ bool get_bit( int ) const;
+
+protected:
+
+ sc_fxval_fast_observer* lock_observer() const;
+ void unlock_observer( sc_fxval_fast_observer* ) const;
+
+
+ static double from_string( const char* );
+
+private:
+
+ double m_val;
+
+ mutable sc_fxval_fast_observer* m_observer;
+
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxval
+//
+// Fixed-point value type; arbitrary precision.
+// ----------------------------------------------------------------------------
+
+// protected method
+
+inline
+sc_fxval_observer*
+sc_fxval::observer() const
+{
+ return m_observer;
+}
+
+
+// internal use only;
+inline
+sc_fxval::sc_fxval( scfx_rep* a )
+: m_rep( a != 0 ? a : new scfx_rep ),
+ m_observer( 0 )
+{}
+
+
+// public constructors
+
+inline
+sc_fxval::sc_fxval( sc_fxval_observer* observer_ )
+: m_rep( new scfx_rep ),
+ m_observer( observer_ )
+{
+ SC_FXVAL_OBSERVER_DEFAULT_
+ SC_FXVAL_OBSERVER_CONSTRUCT_( *this )
+}
+
+inline
+sc_fxval::sc_fxval( const sc_fxval& a,
+ sc_fxval_observer* observer_ )
+: m_rep( new scfx_rep( *a.m_rep ) ),
+ m_observer( observer_ )
+{
+ SC_FXVAL_OBSERVER_DEFAULT_
+ SC_FXVAL_OBSERVER_READ_( a )
+ SC_FXVAL_OBSERVER_CONSTRUCT_( *this )
+ SC_FXVAL_OBSERVER_WRITE_( *this )
+}
+
+#define DEFN_CTOR_T(tp,arg) \
+inline \
+sc_fxval::sc_fxval( tp a, \
+ sc_fxval_observer* observer_ ) \
+: m_rep( new scfx_rep( arg ) ), \
+ m_observer( observer_ ) \
+{ \
+ SC_FXVAL_OBSERVER_DEFAULT_ \
+ SC_FXVAL_OBSERVER_CONSTRUCT_( *this ) \
+ SC_FXVAL_OBSERVER_WRITE_( *this ) \
+}
+
+#define DEFN_CTOR_T_A(tp) DEFN_CTOR_T(tp,a)
+#define DEFN_CTOR_T_B(tp) DEFN_CTOR_T(tp,a.to_double())
+#define DEFN_CTOR_T_C(tp) DEFN_CTOR_T(tp,a.value())
+
+DEFN_CTOR_T_A(int)
+DEFN_CTOR_T_A(unsigned int)
+DEFN_CTOR_T_A(long)
+DEFN_CTOR_T_A(unsigned long)
+DEFN_CTOR_T_A(float)
+DEFN_CTOR_T_A(double)
+DEFN_CTOR_T_A(const char*)
+DEFN_CTOR_T_B(const sc_fxval_fast&)
+#ifndef SC_FX_EXCLUDE_OTHER
+DEFN_CTOR_T_A(int64)
+DEFN_CTOR_T_A(uint64)
+DEFN_CTOR_T_C(const sc_int_base&)
+DEFN_CTOR_T_C(const sc_uint_base&)
+DEFN_CTOR_T_A(const sc_signed&)
+DEFN_CTOR_T_A(const sc_unsigned&)
+#endif
+
+#undef DEFN_CTOR_T
+#undef DEFN_CTOR_T_A
+#undef DEFN_CTOR_T_B
+#undef DEFN_CTOR_T_C
+
+
+inline
+sc_fxval::~sc_fxval()
+{
+ SC_FXVAL_OBSERVER_DESTRUCT_( *this )
+ delete m_rep;
+}
+
+
+// internal use only;
+inline
+const scfx_rep*
+sc_fxval::get_rep() const
+{
+ SC_FXVAL_OBSERVER_READ_( *this )
+ return m_rep;
+}
+
+// internal use only;
+inline
+void
+sc_fxval::set_rep( scfx_rep* rep_ )
+{
+ delete m_rep;
+ m_rep = rep_;
+ SC_FXVAL_OBSERVER_WRITE_( *this )
+}
+
+
+// unary operators
+
+inline
+const sc_fxval
+sc_fxval::operator - () const
+{
+ SC_FXVAL_OBSERVER_READ_( *this )
+ return sc_fxval( sc_dt::neg_scfx_rep( *m_rep ) );
+}
+
+inline
+const sc_fxval&
+sc_fxval::operator + () const
+{
+ // SC_FXVAL_OBSERVER_READ_( *this )
+ return *this;
+}
+
+
+// unary functions
+
+inline
+void
+neg( sc_fxval& c, const sc_fxval& a )
+{
+ SC_FXVAL_OBSERVER_READ_( a )
+ delete c.m_rep;
+ c.m_rep = sc_dt::neg_scfx_rep( *a.m_rep );
+ SC_FXVAL_OBSERVER_WRITE_( c )
+}
+
+
+// binary operators
+
+#define DEFN_BIN_OP_T(op,fnc,tp) \
+inline \
+const sc_fxval \
+operator op ( const sc_fxval& a, tp b ) \
+{ \
+ SC_FXVAL_OBSERVER_READ_( a ) \
+ sc_fxval tmp( b ); \
+ return sc_fxval( sc_dt::fnc ## _scfx_rep( *a.m_rep, *tmp.m_rep ) ); \
+} \
+ \
+inline \
+const sc_fxval \
+operator op ( tp a, const sc_fxval& b ) \
+{ \
+ SC_FXVAL_OBSERVER_READ_( b ) \
+ sc_fxval tmp( a ); \
+ return sc_fxval( sc_dt::fnc ## _scfx_rep( *tmp.m_rep, *b.m_rep ) ); \
+}
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DEFN_BIN_OP_OTHER(op,fnc) \
+DEFN_BIN_OP_T(op,fnc,int64) \
+DEFN_BIN_OP_T(op,fnc,uint64) \
+DEFN_BIN_OP_T(op,fnc,const sc_int_base&) \
+DEFN_BIN_OP_T(op,fnc,const sc_uint_base&) \
+DEFN_BIN_OP_T(op,fnc,const sc_signed&) \
+DEFN_BIN_OP_T(op,fnc,const sc_unsigned&)
+#else
+#define DEFN_BIN_OP_OTHER(op,fnc)
+#endif
+
+#define DEFN_BIN_OP(op,fnc) \
+inline \
+const sc_fxval \
+operator op ( const sc_fxval& a, const sc_fxval& b ) \
+{ \
+ SC_FXVAL_OBSERVER_READ_( a ) \
+ SC_FXVAL_OBSERVER_READ_( b ) \
+ return sc_fxval( sc_dt::fnc ## _scfx_rep( *a.m_rep, *b.m_rep ) ); \
+} \
+ \
+DEFN_BIN_OP_T(op,fnc,int) \
+DEFN_BIN_OP_T(op,fnc,unsigned int) \
+DEFN_BIN_OP_T(op,fnc,long) \
+DEFN_BIN_OP_T(op,fnc,unsigned long) \
+DEFN_BIN_OP_T(op,fnc,float) \
+DEFN_BIN_OP_T(op,fnc,double) \
+DEFN_BIN_OP_T(op,fnc,const char*) \
+DEFN_BIN_OP_T(op,fnc,const sc_fxval_fast&) \
+DEFN_BIN_OP_OTHER(op,fnc)
+
+DEFN_BIN_OP(*,mult)
+DEFN_BIN_OP(+,add)
+DEFN_BIN_OP(-,sub)
+// don't use macro
+//DEFN_BIN_OP(/,div)
+inline
+const sc_fxval
+operator / ( const sc_fxval& a, const sc_fxval& b )
+{
+ SC_FXVAL_OBSERVER_READ_( a )
+ SC_FXVAL_OBSERVER_READ_( b )
+ return sc_fxval( sc_dt::div_scfx_rep( *a.m_rep, *b.m_rep ) );
+}
+
+DEFN_BIN_OP_T(/,div,int)
+DEFN_BIN_OP_T(/,div,unsigned int)
+DEFN_BIN_OP_T(/,div,long)
+DEFN_BIN_OP_T(/,div,unsigned long)
+DEFN_BIN_OP_T(/,div,float)
+DEFN_BIN_OP_T(/,div,double)
+DEFN_BIN_OP_T(/,div,const char*)
+DEFN_BIN_OP_T(/,div,const sc_fxval_fast&)
+//DEFN_BIN_OP_OTHER(/,div)
+#ifndef SC_FX_EXCLUDE_OTHER
+DEFN_BIN_OP_T(/,div,int64) \
+DEFN_BIN_OP_T(/,div,uint64) \
+DEFN_BIN_OP_T(/,div,const sc_int_base&) \
+DEFN_BIN_OP_T(/,div,const sc_uint_base&) \
+DEFN_BIN_OP_T(/,div,const sc_signed&) \
+DEFN_BIN_OP_T(/,div,const sc_unsigned&)
+#endif
+
+#undef DEFN_BIN_OP_T
+#undef DEFN_BIN_OP_OTHER
+#undef DEFN_BIN_OP
+
+
+inline
+const sc_fxval
+operator << ( const sc_fxval& a, int b )
+{
+ SC_FXVAL_OBSERVER_READ_( a )
+ return sc_fxval( sc_dt::lsh_scfx_rep( *a.m_rep, b ) );
+}
+
+inline
+const sc_fxval
+operator >> ( const sc_fxval& a, int b )
+{
+ SC_FXVAL_OBSERVER_READ_( a )
+ return sc_fxval( sc_dt::rsh_scfx_rep( *a.m_rep, b ) );
+}
+
+
+// binary functions
+
+#define DEFN_BIN_FNC_T(fnc,tp) \
+inline \
+void \
+fnc ( sc_fxval& c, const sc_fxval& a, tp b ) \
+{ \
+ SC_FXVAL_OBSERVER_READ_( a ) \
+ sc_fxval tmp( b ); \
+ delete c.m_rep; \
+ c.m_rep = sc_dt::fnc ## _scfx_rep( *a.m_rep, *tmp.m_rep ); \
+ SC_FXVAL_OBSERVER_WRITE_( c ) \
+} \
+ \
+inline \
+void \
+fnc ( sc_fxval& c, tp a, const sc_fxval& b ) \
+{ \
+ SC_FXVAL_OBSERVER_READ_( b ) \
+ sc_fxval tmp( a ); \
+ delete c.m_rep; \
+ c.m_rep = sc_dt::fnc ## _scfx_rep( *tmp.m_rep, *b.m_rep ); \
+ SC_FXVAL_OBSERVER_WRITE_( c ) \
+}
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DEFN_BIN_FNC_OTHER(fnc) \
+DEFN_BIN_FNC_T(fnc,int64) \
+DEFN_BIN_FNC_T(fnc,uint64) \
+DEFN_BIN_FNC_T(fnc,const sc_int_base&) \
+DEFN_BIN_FNC_T(fnc,const sc_uint_base&) \
+DEFN_BIN_FNC_T(fnc,const sc_signed&) \
+DEFN_BIN_FNC_T(fnc,const sc_unsigned&)
+#else
+#define DEFN_BIN_FNC_OTHER(fnc)
+#endif
+
+#define DEFN_BIN_FNC(fnc) \
+inline \
+void \
+fnc( sc_fxval& c, const sc_fxval& a, const sc_fxval& b ) \
+{ \
+ SC_FXVAL_OBSERVER_READ_( a ) \
+ SC_FXVAL_OBSERVER_READ_( b ) \
+ delete c.m_rep; \
+ c.m_rep = sc_dt::fnc ## _scfx_rep( *a.m_rep, *b.m_rep ); \
+ SC_FXVAL_OBSERVER_WRITE_( c ) \
+} \
+ \
+DEFN_BIN_FNC_T(fnc,int) \
+DEFN_BIN_FNC_T(fnc,unsigned int) \
+DEFN_BIN_FNC_T(fnc,long) \
+DEFN_BIN_FNC_T(fnc,unsigned long) \
+DEFN_BIN_FNC_T(fnc,float) \
+DEFN_BIN_FNC_T(fnc,double) \
+DEFN_BIN_FNC_T(fnc,const char*) \
+DEFN_BIN_FNC_T(fnc,const sc_fxval_fast&) \
+DEFN_BIN_FNC_OTHER(fnc)
+
+DEFN_BIN_FNC(mult)
+DEFN_BIN_FNC(div)
+DEFN_BIN_FNC(add)
+DEFN_BIN_FNC(sub)
+
+#undef DEFN_BIN_FNC_T
+#undef DEFN_BIN_FNC_OTHER
+#undef DEFN_BIN_FNC
+
+
+inline
+void
+lshift( sc_fxval& c, const sc_fxval& a, int b )
+{
+ SC_FXVAL_OBSERVER_READ_( a )
+ delete c.m_rep;
+ c.m_rep = sc_dt::lsh_scfx_rep( *a.m_rep, b );
+ SC_FXVAL_OBSERVER_WRITE_( c )
+}
+
+inline
+void
+rshift( sc_fxval& c, const sc_fxval& a, int b )
+{
+ SC_FXVAL_OBSERVER_READ_( a )
+ delete c.m_rep;
+ c.m_rep = sc_dt::rsh_scfx_rep( *a.m_rep, b );
+ SC_FXVAL_OBSERVER_WRITE_( c )
+}
+
+
+// relational (including equality) operators
+
+#define DEFN_REL_OP_T(op,ret,tp) \
+inline \
+bool \
+operator op ( const sc_fxval& a, tp b ) \
+{ \
+ SC_FXVAL_OBSERVER_READ_( a ) \
+ sc_fxval tmp( b ); \
+ int result = sc_dt::cmp_scfx_rep( *a.m_rep, *tmp.m_rep ); \
+ return ( ret ); \
+} \
+ \
+inline \
+bool \
+operator op ( tp a, const sc_fxval& b ) \
+{ \
+ SC_FXVAL_OBSERVER_READ_( b ) \
+ sc_fxval tmp( a ); \
+ int result = sc_dt::cmp_scfx_rep( *tmp.m_rep, *b.m_rep ); \
+ return ( ret ); \
+}
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DEFN_REL_OP_OTHER(op,ret) \
+DEFN_REL_OP_T(op,ret,int64) \
+DEFN_REL_OP_T(op,ret,uint64) \
+DEFN_REL_OP_T(op,ret,const sc_int_base&) \
+DEFN_REL_OP_T(op,ret,const sc_uint_base&) \
+DEFN_REL_OP_T(op,ret,const sc_signed&) \
+DEFN_REL_OP_T(op,ret,const sc_unsigned&)
+#else
+#define DEFN_REL_OP_OTHER(op,ret)
+#endif
+
+#define DEFN_REL_OP(op,ret) \
+inline \
+bool \
+operator op ( const sc_fxval& a, const sc_fxval& b) \
+{ \
+ SC_FXVAL_OBSERVER_READ_( a ) \
+ SC_FXVAL_OBSERVER_READ_( b ) \
+ int result = sc_dt::cmp_scfx_rep( *a.m_rep, *b.m_rep ); \
+ return ( ret ); \
+} \
+ \
+DEFN_REL_OP_T(op,ret,int) \
+DEFN_REL_OP_T(op,ret,unsigned int) \
+DEFN_REL_OP_T(op,ret,long) \
+DEFN_REL_OP_T(op,ret,unsigned long) \
+DEFN_REL_OP_T(op,ret,float) \
+DEFN_REL_OP_T(op,ret,double) \
+DEFN_REL_OP_T(op,ret,const char*) \
+DEFN_REL_OP_T(op,ret,const sc_fxval_fast&) \
+DEFN_REL_OP_OTHER(op,ret)
+
+DEFN_REL_OP(<,result < 0)
+DEFN_REL_OP(<=,result <= 0)
+DEFN_REL_OP(>,result > 0 && result != 2)
+DEFN_REL_OP(>=,result >= 0 && result != 2)
+DEFN_REL_OP(==,result == 0)
+DEFN_REL_OP(!=,result != 0)
+
+#undef DEFN_REL_OP_T
+#undef DEFN_REL_OP_OTHER
+#undef DEFN_REL_OP
+
+
+// assignment operators
+
+inline
+sc_fxval&
+sc_fxval::operator = ( const sc_fxval& a )
+{
+ if( &a != this )
+ {
+ SC_FXVAL_OBSERVER_READ_( a )
+ *m_rep = *a.m_rep;
+ SC_FXVAL_OBSERVER_WRITE_( *this )
+ }
+ return *this;
+}
+
+#define DEFN_ASN_OP_T(tp) \
+inline \
+sc_fxval& \
+sc_fxval::operator = ( tp b ) \
+{ \
+ sc_fxval tmp( b ); \
+ *m_rep = *tmp.m_rep; \
+ SC_FXVAL_OBSERVER_WRITE_( *this ) \
+ return *this; \
+}
+
+DEFN_ASN_OP_T(int)
+DEFN_ASN_OP_T(unsigned int)
+DEFN_ASN_OP_T(long)
+DEFN_ASN_OP_T(unsigned long)
+DEFN_ASN_OP_T(float)
+DEFN_ASN_OP_T(double)
+DEFN_ASN_OP_T(const char*)
+DEFN_ASN_OP_T(const sc_fxval_fast&)
+#ifndef SC_FX_EXCLUDE_OTHER
+DEFN_ASN_OP_T(int64)
+DEFN_ASN_OP_T(uint64)
+DEFN_ASN_OP_T(const sc_int_base&)
+DEFN_ASN_OP_T(const sc_uint_base&)
+DEFN_ASN_OP_T(const sc_signed&)
+DEFN_ASN_OP_T(const sc_unsigned&)
+#endif
+
+#undef DEFN_ASN_OP_T
+
+
+#define DEFN_ASN_OP_T(op,fnc,tp) \
+inline \
+sc_fxval& \
+sc_fxval::operator op ( tp b ) \
+{ \
+ SC_FXVAL_OBSERVER_READ_( *this ) \
+ sc_fxval tmp( b ); \
+ scfx_rep* new_rep = sc_dt::fnc ## _scfx_rep( *m_rep, *tmp.m_rep ); \
+ delete m_rep; \
+ m_rep = new_rep; \
+ SC_FXVAL_OBSERVER_WRITE_( *this ) \
+ return *this; \
+}
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DEFN_ASN_OP_OTHER(op,fnc) \
+DEFN_ASN_OP_T(op,fnc,int64) \
+DEFN_ASN_OP_T(op,fnc,uint64) \
+DEFN_ASN_OP_T(op,fnc,const sc_int_base&) \
+DEFN_ASN_OP_T(op,fnc,const sc_uint_base&) \
+DEFN_ASN_OP_T(op,fnc,const sc_signed&) \
+DEFN_ASN_OP_T(op,fnc,const sc_unsigned&)
+#else
+#define DEFN_ASN_OP_OTHER(op,fnc)
+#endif
+
+#define DEFN_ASN_OP(op,fnc) \
+inline \
+sc_fxval& \
+sc_fxval::operator op ( const sc_fxval& b ) \
+{ \
+ SC_FXVAL_OBSERVER_READ_( *this ) \
+ SC_FXVAL_OBSERVER_READ_( b ) \
+ scfx_rep* new_rep = sc_dt::fnc ## _scfx_rep( *m_rep, *b.m_rep ); \
+ delete m_rep; \
+ m_rep = new_rep; \
+ SC_FXVAL_OBSERVER_WRITE_( *this ) \
+ return *this; \
+} \
+ \
+DEFN_ASN_OP_T(op,fnc,int) \
+DEFN_ASN_OP_T(op,fnc,unsigned int) \
+DEFN_ASN_OP_T(op,fnc,long) \
+DEFN_ASN_OP_T(op,fnc,unsigned long) \
+DEFN_ASN_OP_T(op,fnc,float) \
+DEFN_ASN_OP_T(op,fnc,double) \
+DEFN_ASN_OP_T(op,fnc,const char*) \
+DEFN_ASN_OP_T(op,fnc,const sc_fxval_fast&) \
+DEFN_ASN_OP_OTHER(op,fnc)
+
+DEFN_ASN_OP(*=,mult)
+DEFN_ASN_OP(/=,div)
+DEFN_ASN_OP(+=,add)
+DEFN_ASN_OP(-=,sub)
+
+#undef DEFN_ASN_OP_T
+#undef DEFN_ASN_OP_OTHER
+#undef DEFN_ASN_OP
+
+
+inline
+sc_fxval&
+sc_fxval::operator <<= ( int b )
+{
+ SC_FXVAL_OBSERVER_READ_( *this )
+ m_rep->lshift( b );
+ SC_FXVAL_OBSERVER_WRITE_( *this )
+ return *this;
+}
+
+inline
+sc_fxval&
+sc_fxval::operator >>= ( int b )
+{
+ SC_FXVAL_OBSERVER_READ_( *this )
+ m_rep->rshift( b );
+ SC_FXVAL_OBSERVER_WRITE_( *this )
+ return *this;
+}
+
+
+// auto-increment and auto-decrement
+
+inline
+const sc_fxval
+sc_fxval::operator ++ ( int )
+{
+ sc_fxval c = *this;
+ (*this) += 1;
+ return c;
+}
+
+inline
+const sc_fxval
+sc_fxval::operator -- ( int )
+{
+ sc_fxval c = *this;
+ (*this) -= 1;
+ return c;
+}
+
+inline
+sc_fxval&
+sc_fxval::operator ++ ()
+{
+ (*this) += 1;
+ return *this;
+}
+
+inline
+sc_fxval&
+sc_fxval::operator -- ()
+{
+ (*this) -= 1;
+ return *this;
+}
+
+
+// implicit conversion
+
+inline
+sc_fxval::operator double() const
+{
+ SC_FXVAL_OBSERVER_READ_( *this )
+ return m_rep->to_double();
+}
+
+
+// explicit conversion to primitive types
+
+inline
+short
+sc_fxval::to_short() const
+{
+ SC_FXVAL_OBSERVER_READ_( *this )
+ return static_cast<short>( m_rep->to_double() );
+}
+
+inline
+unsigned short
+sc_fxval::to_ushort() const
+{
+ SC_FXVAL_OBSERVER_READ_( *this )
+ return static_cast<unsigned short>( m_rep->to_double() );
+}
+
+inline
+int
+sc_fxval::to_int() const
+{
+ SC_FXVAL_OBSERVER_READ_( *this )
+ return static_cast<int>( m_rep->to_double() );
+}
+
+inline
+int64
+sc_fxval::to_int64() const
+{
+ SC_FXVAL_OBSERVER_READ_( *this )
+ return static_cast<int64>( m_rep->to_double() );
+}
+
+inline
+uint64
+sc_fxval::to_uint64() const
+{
+ SC_FXVAL_OBSERVER_READ_( *this )
+ return static_cast<uint64>( m_rep->to_double() );
+}
+
+inline
+long
+sc_fxval::to_long() const
+{
+ SC_FXVAL_OBSERVER_READ_( *this )
+ return static_cast<long>( m_rep->to_double() );
+}
+
+inline
+unsigned int
+sc_fxval::to_uint() const
+{
+ SC_FXVAL_OBSERVER_READ_( *this )
+ return static_cast<unsigned int>( m_rep->to_double() );
+}
+
+inline
+unsigned long
+sc_fxval::to_ulong() const
+{
+ SC_FXVAL_OBSERVER_READ_( *this )
+ return static_cast<unsigned long>( m_rep->to_double() );
+}
+
+inline
+float
+sc_fxval::to_float() const
+{
+ SC_FXVAL_OBSERVER_READ_( *this )
+ return static_cast<float>( m_rep->to_double() );
+}
+
+inline
+double
+sc_fxval::to_double() const
+{
+ SC_FXVAL_OBSERVER_READ_( *this )
+ return m_rep->to_double();
+}
+
+
+// query value
+
+inline
+bool
+sc_fxval::is_neg() const
+{
+ SC_FXVAL_OBSERVER_READ_( *this )
+ return m_rep->is_neg();
+}
+
+inline
+bool
+sc_fxval::is_zero() const
+{
+ SC_FXVAL_OBSERVER_READ_( *this )
+ return m_rep->is_zero();
+}
+
+inline
+bool
+sc_fxval::is_nan() const
+{
+ SC_FXVAL_OBSERVER_READ_( *this )
+ return m_rep->is_nan();
+}
+
+inline
+bool
+sc_fxval::is_inf() const
+{
+ SC_FXVAL_OBSERVER_READ_( *this )
+ return m_rep->is_inf();
+}
+
+inline
+bool
+sc_fxval::is_normal() const
+{
+ SC_FXVAL_OBSERVER_READ_( *this )
+ return m_rep->is_normal();
+}
+
+
+inline
+bool
+sc_fxval::rounding_flag() const
+{
+ return m_rep->rounding_flag();
+}
+
+
+// internal use only;
+inline
+bool
+sc_fxval::get_bit( int i ) const
+{
+ return m_rep->get_bit( i );
+}
+
+
+// protected methods and friend functions
+
+inline
+void
+sc_fxval::get_type( int& wl, int& iwl, sc_enc& enc ) const
+{
+ m_rep->get_type( wl, iwl, enc );
+}
+
+
+inline
+const sc_fxval
+sc_fxval::quantization( const scfx_params& params, bool& q_flag ) const
+{
+ return sc_fxval( sc_dt::quantization_scfx_rep( *m_rep, params, q_flag ) );
+}
+
+inline
+const sc_fxval
+sc_fxval::overflow( const scfx_params& params, bool& o_flag ) const
+{
+ return sc_fxval( sc_dt::overflow_scfx_rep( *m_rep, params, o_flag ) );
+}
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, const sc_fxval& a )
+{
+ a.print( os );
+ return os;
+}
+
+inline
+::std::istream&
+operator >> ( ::std::istream& is, sc_fxval& a )
+{
+ a.scan( is );
+ return is;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxval_fast
+//
+// Fixed-point value type; limited precision.
+// ----------------------------------------------------------------------------
+
+// protected method
+
+inline
+sc_fxval_fast_observer*
+sc_fxval_fast::observer() const
+{
+ return m_observer;
+}
+
+
+// public constructors
+
+inline
+sc_fxval_fast::sc_fxval_fast( sc_fxval_fast_observer* observer_ )
+: m_val( 0.0 ),
+ m_observer( observer_ )
+{
+ SC_FXVAL_FAST_OBSERVER_DEFAULT_
+ SC_FXVAL_FAST_OBSERVER_CONSTRUCT_( *this )
+}
+
+inline
+sc_fxval_fast::sc_fxval_fast( const sc_fxval_fast& a,
+ sc_fxval_fast_observer* observer_ )
+: m_val( a.m_val ),
+ m_observer( observer_ )
+{
+ SC_FXVAL_FAST_OBSERVER_DEFAULT_
+ SC_FXVAL_FAST_OBSERVER_READ_( a )
+ SC_FXVAL_FAST_OBSERVER_CONSTRUCT_( *this )
+ SC_FXVAL_FAST_OBSERVER_WRITE_( *this )
+}
+
+#define DEFN_CTOR_T(tp,arg) \
+inline \
+sc_fxval_fast::sc_fxval_fast( tp a, \
+ sc_fxval_fast_observer* observer_ ) \
+: m_val( arg ), \
+ m_observer( observer_ ) \
+{ \
+ SC_FXVAL_FAST_OBSERVER_DEFAULT_ \
+ SC_FXVAL_FAST_OBSERVER_CONSTRUCT_( *this ) \
+ SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) \
+}
+
+#define DEFN_CTOR_T_A(tp) DEFN_CTOR_T(tp,static_cast<double>( a ))
+#define DEFN_CTOR_T_B(tp) DEFN_CTOR_T(tp,from_string( a ))
+#define DEFN_CTOR_T_C(tp) DEFN_CTOR_T(tp,a.to_double())
+
+DEFN_CTOR_T_A(int)
+DEFN_CTOR_T_A(unsigned int)
+DEFN_CTOR_T_A(long)
+DEFN_CTOR_T_A(unsigned long)
+DEFN_CTOR_T_A(float)
+DEFN_CTOR_T_A(double)
+DEFN_CTOR_T_B(const char*)
+DEFN_CTOR_T_C(const sc_fxval&)
+#ifndef SC_FX_EXCLUDE_OTHER
+DEFN_CTOR_T_A(int64)
+DEFN_CTOR_T_A(uint64)
+DEFN_CTOR_T_C(const sc_int_base&)
+DEFN_CTOR_T_C(const sc_uint_base&)
+DEFN_CTOR_T_C(const sc_signed&)
+DEFN_CTOR_T_C(const sc_unsigned&)
+#endif
+
+#undef DEFN_CTOR_T
+#undef DEFN_CTOR_T_A
+#undef DEFN_CTOR_T_B
+#undef DEFN_CTOR_T_C
+#undef DEFN_CTOR_T_D
+#undef DEFN_CTOR_T_E
+
+
+inline
+sc_fxval_fast::~sc_fxval_fast()
+{
+ SC_FXVAL_FAST_OBSERVER_DESTRUCT_( *this )
+}
+
+
+// internal use only;
+inline
+double
+sc_fxval_fast::get_val() const
+{
+ SC_FXVAL_FAST_OBSERVER_READ_( *this )
+ return m_val;
+}
+
+// internal use only;
+inline
+void
+sc_fxval_fast::set_val( double val_ )
+{
+ m_val = val_;
+ SC_FXVAL_FAST_OBSERVER_WRITE_( *this )
+}
+
+
+// unary operators
+
+inline
+const sc_fxval_fast
+sc_fxval_fast::operator - () const
+{
+ SC_FXVAL_FAST_OBSERVER_READ_( *this )
+ return sc_fxval_fast( - m_val );
+}
+
+inline
+const sc_fxval_fast&
+sc_fxval_fast::operator + () const
+{
+ // SC_FXVAL_FAST_OBSERVER_READ_( *this )
+ return *this;
+}
+
+
+// unary functions
+
+inline
+void
+neg( sc_fxval_fast& c, const sc_fxval_fast& a )
+{
+ SC_FXVAL_FAST_OBSERVER_READ_( a )
+ c.m_val = - a.m_val;
+ SC_FXVAL_FAST_OBSERVER_WRITE_( c )
+}
+
+
+// binary operators
+
+#define DEFN_BIN_OP_T(op,tp) \
+inline \
+const sc_fxval_fast \
+operator op ( const sc_fxval_fast& a, tp b ) \
+{ \
+ SC_FXVAL_FAST_OBSERVER_READ_( a ) \
+ sc_fxval_fast tmp( b ); \
+ return sc_fxval_fast( a.m_val op tmp.m_val ); \
+} \
+ \
+inline \
+const sc_fxval_fast \
+operator op ( tp a, const sc_fxval_fast& b ) \
+{ \
+ SC_FXVAL_FAST_OBSERVER_READ_( b ) \
+ sc_fxval_fast tmp( a ); \
+ return sc_fxval_fast( tmp.m_val op b.m_val ); \
+}
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DEFN_BIN_OP_OTHER(op) \
+DEFN_BIN_OP_T(op,int64) \
+DEFN_BIN_OP_T(op,uint64) \
+DEFN_BIN_OP_T(op,const sc_int_base&) \
+DEFN_BIN_OP_T(op,const sc_uint_base&) \
+DEFN_BIN_OP_T(op,const sc_signed&) \
+DEFN_BIN_OP_T(op,const sc_unsigned&)
+#else
+#define DEFN_BIN_OP_OTHER(op)
+#endif
+
+#define DEFN_BIN_OP(op,dummy) \
+inline \
+const sc_fxval_fast \
+operator op ( const sc_fxval_fast& a, const sc_fxval_fast& b ) \
+{ \
+ SC_FXVAL_FAST_OBSERVER_READ_( a ) \
+ SC_FXVAL_FAST_OBSERVER_READ_( b ) \
+ return sc_fxval_fast( a.m_val op b.m_val ); \
+} \
+ \
+DEFN_BIN_OP_T(op,int) \
+DEFN_BIN_OP_T(op,unsigned int) \
+DEFN_BIN_OP_T(op,long) \
+DEFN_BIN_OP_T(op,unsigned long) \
+DEFN_BIN_OP_T(op,float) \
+DEFN_BIN_OP_T(op,double) \
+DEFN_BIN_OP_T(op,const char*) \
+DEFN_BIN_OP_OTHER(op)
+
+DEFN_BIN_OP(*,mult)
+DEFN_BIN_OP(+,add)
+DEFN_BIN_OP(-,sub)
+//DEFN_BIN_OP(/,div)
+inline
+const sc_fxval_fast
+operator / ( const sc_fxval_fast& a, const sc_fxval_fast& b )
+{
+ SC_FXVAL_FAST_OBSERVER_READ_( a )
+ SC_FXVAL_FAST_OBSERVER_READ_( b )
+ return sc_fxval_fast( a.m_val / b.m_val );
+}
+
+DEFN_BIN_OP_T(/,int)
+DEFN_BIN_OP_T(/,unsigned int)
+DEFN_BIN_OP_T(/,long)
+DEFN_BIN_OP_T(/,unsigned long)
+DEFN_BIN_OP_T(/,float)
+DEFN_BIN_OP_T(/,double)
+DEFN_BIN_OP_T(/,const char*)
+//DEFN_BIN_OP_OTHER(/)
+#ifndef SC_FX_EXCLUDE_OTHER
+DEFN_BIN_OP_T(/,int64)
+DEFN_BIN_OP_T(/,uint64)
+DEFN_BIN_OP_T(/,const sc_int_base&)
+DEFN_BIN_OP_T(/,const sc_uint_base&)
+DEFN_BIN_OP_T(/,const sc_signed&)
+DEFN_BIN_OP_T(/,const sc_unsigned&)
+#endif
+
+
+#undef DEFN_BIN_OP_T
+#undef DEFN_BIN_OP_OTHER
+#undef DEFN_BIN_OP
+
+
+inline
+const sc_fxval_fast
+operator << ( const sc_fxval_fast& a, int b )
+{
+ SC_FXVAL_FAST_OBSERVER_READ_( a )
+ return sc_fxval_fast( a.m_val * scfx_pow2( b ) );
+}
+
+inline
+const sc_fxval_fast
+operator >> ( const sc_fxval_fast& a, int b )
+{
+ SC_FXVAL_FAST_OBSERVER_READ_( a )
+ return sc_fxval_fast( a.m_val * scfx_pow2( -b ) );
+}
+
+
+// binary functions
+
+#define DEFN_BIN_FNC_T(fnc,op,tp) \
+inline \
+void \
+fnc ( sc_fxval_fast& c, const sc_fxval_fast& a, tp b ) \
+{ \
+ SC_FXVAL_FAST_OBSERVER_READ_( a ) \
+ sc_fxval_fast tmp( b ); \
+ c.m_val = a.m_val op tmp.m_val; \
+ SC_FXVAL_FAST_OBSERVER_WRITE_( c ) \
+} \
+ \
+inline \
+void \
+fnc ( sc_fxval_fast& c, tp a, const sc_fxval_fast& b ) \
+{ \
+ SC_FXVAL_FAST_OBSERVER_READ_( b ) \
+ sc_fxval_fast tmp( a ); \
+ c.m_val = tmp.m_val op b.m_val; \
+ SC_FXVAL_FAST_OBSERVER_WRITE_( c ) \
+}
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DEFN_BIN_FNC_OTHER(fnc,op) \
+DEFN_BIN_FNC_T(fnc,op,int64) \
+DEFN_BIN_FNC_T(fnc,op,uint64) \
+DEFN_BIN_FNC_T(fnc,op,const sc_int_base&) \
+DEFN_BIN_FNC_T(fnc,op,const sc_uint_base&) \
+DEFN_BIN_FNC_T(fnc,op,const sc_signed&) \
+DEFN_BIN_FNC_T(fnc,op,const sc_unsigned&)
+#else
+#define DEFN_BIN_FNC_OTHER(fnc,op)
+#endif
+
+#define DEFN_BIN_FNC(fnc,op) \
+inline \
+void \
+fnc ( sc_fxval_fast& c, const sc_fxval_fast& a, const sc_fxval_fast& b ) \
+{ \
+ SC_FXVAL_FAST_OBSERVER_READ_( a ) \
+ SC_FXVAL_FAST_OBSERVER_READ_( b ) \
+ c.m_val = a.m_val op b.m_val; \
+ SC_FXVAL_FAST_OBSERVER_WRITE_( c ) \
+} \
+ \
+DEFN_BIN_FNC_T(fnc,op,int) \
+DEFN_BIN_FNC_T(fnc,op,unsigned int) \
+DEFN_BIN_FNC_T(fnc,op,long) \
+DEFN_BIN_FNC_T(fnc,op,unsigned long) \
+DEFN_BIN_FNC_T(fnc,op,float) \
+DEFN_BIN_FNC_T(fnc,op,double) \
+DEFN_BIN_FNC_T(fnc,op,const char*) \
+DEFN_BIN_FNC_OTHER(fnc,op)
+
+DEFN_BIN_FNC(mult,*)
+DEFN_BIN_FNC(div,/)
+DEFN_BIN_FNC(add,+)
+DEFN_BIN_FNC(sub,-)
+
+#undef DEFN_BIN_FNC_T
+#undef DEFN_BIN_FNC_OTHER
+#undef DEFN_BIN_FNC
+
+
+inline
+void
+lshift( sc_fxval_fast& c, const sc_fxval_fast& a, int b )
+{
+ SC_FXVAL_FAST_OBSERVER_READ_( a )
+ c.m_val = a.m_val * scfx_pow2( b );
+ SC_FXVAL_FAST_OBSERVER_WRITE_( c )
+}
+
+inline
+void
+rshift( sc_fxval_fast& c, const sc_fxval_fast& a, int b )
+{
+ SC_FXVAL_FAST_OBSERVER_READ_( a )
+ c.m_val = a.m_val * scfx_pow2( -b );
+ SC_FXVAL_FAST_OBSERVER_WRITE_( c )
+}
+
+
+// relational (including equality) operators
+
+#define DEFN_REL_OP_T(op,tp) \
+inline \
+bool \
+operator op ( const sc_fxval_fast& a, tp b ) \
+{ \
+ SC_FXVAL_FAST_OBSERVER_READ_( a ) \
+ sc_fxval_fast tmp( b ); \
+ return ( a.m_val op tmp.m_val ); \
+} \
+ \
+inline \
+bool \
+operator op ( tp a, const sc_fxval_fast& b ) \
+{ \
+ SC_FXVAL_FAST_OBSERVER_READ_( b ) \
+ sc_fxval_fast tmp( a ); \
+ return ( tmp.m_val op b.m_val ); \
+}
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DEFN_REL_OP_OTHER(op) \
+DEFN_REL_OP_T(op,int64) \
+DEFN_REL_OP_T(op,uint64) \
+DEFN_REL_OP_T(op,const sc_int_base&) \
+DEFN_REL_OP_T(op,const sc_uint_base&) \
+DEFN_REL_OP_T(op,const sc_signed&) \
+DEFN_REL_OP_T(op,const sc_unsigned&)
+#else
+#define DEFN_REL_OP_OTHER(op)
+#endif
+
+#define DEFN_REL_OP(op) \
+inline \
+bool \
+operator op ( const sc_fxval_fast& a, const sc_fxval_fast& b ) \
+{ \
+ SC_FXVAL_FAST_OBSERVER_READ_( a ) \
+ SC_FXVAL_FAST_OBSERVER_READ_( b ) \
+ return ( a.m_val op b.m_val ); \
+} \
+ \
+DEFN_REL_OP_T(op,int) \
+DEFN_REL_OP_T(op,unsigned int) \
+DEFN_REL_OP_T(op,long) \
+DEFN_REL_OP_T(op,unsigned long) \
+DEFN_REL_OP_T(op,float) \
+DEFN_REL_OP_T(op,double) \
+DEFN_REL_OP_T(op,const char*) \
+DEFN_REL_OP_OTHER(op)
+
+DEFN_REL_OP(<)
+DEFN_REL_OP(<=)
+DEFN_REL_OP(>)
+DEFN_REL_OP(>=)
+DEFN_REL_OP(==)
+DEFN_REL_OP(!=)
+
+#undef DEFN_REL_OP_T
+#undef DEFN_REL_OP_OTHER
+#undef DEFN_REL_OP
+
+
+// assignment operators
+
+inline
+sc_fxval_fast&
+sc_fxval_fast::operator = ( const sc_fxval_fast& a )
+{
+ if( &a != this )
+ {
+ SC_FXVAL_FAST_OBSERVER_READ_( a )
+ m_val = a.m_val;
+ SC_FXVAL_FAST_OBSERVER_WRITE_( *this )
+ }
+ return *this;
+}
+
+#define DEFN_ASN_OP_T(tp) \
+inline \
+sc_fxval_fast& \
+sc_fxval_fast::operator = ( tp a ) \
+{ \
+ sc_fxval_fast tmp( a ); \
+ m_val = tmp.m_val; \
+ SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) \
+ return *this; \
+}
+
+DEFN_ASN_OP_T(int)
+DEFN_ASN_OP_T(unsigned int)
+DEFN_ASN_OP_T(long)
+DEFN_ASN_OP_T(unsigned long)
+DEFN_ASN_OP_T(float)
+DEFN_ASN_OP_T(double)
+DEFN_ASN_OP_T(const char*)
+DEFN_ASN_OP_T(const sc_fxval&)
+#ifndef SC_FX_EXCLUDE_OTHER
+DEFN_ASN_OP_T(int64)
+DEFN_ASN_OP_T(uint64)
+DEFN_ASN_OP_T(const sc_int_base&)
+DEFN_ASN_OP_T(const sc_uint_base&)
+DEFN_ASN_OP_T(const sc_signed&)
+DEFN_ASN_OP_T(const sc_unsigned&)
+#endif
+
+#undef DEFN_ASN_OP_T
+
+
+#define DEFN_ASN_OP_T(op,tp) \
+inline \
+sc_fxval_fast& \
+sc_fxval_fast::operator op ( tp b ) \
+{ \
+ SC_FXVAL_FAST_OBSERVER_READ_( *this ) \
+ sc_fxval_fast tmp( b ); \
+ m_val op tmp.m_val; \
+ SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) \
+ return *this; \
+}
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DEFN_ASN_OP_OTHER(op) \
+DEFN_ASN_OP_T(op,int64) \
+DEFN_ASN_OP_T(op,uint64) \
+DEFN_ASN_OP_T(op,const sc_int_base&) \
+DEFN_ASN_OP_T(op,const sc_uint_base&) \
+DEFN_ASN_OP_T(op,const sc_signed&) \
+DEFN_ASN_OP_T(op,const sc_unsigned&)
+#else
+#define DEFN_ASN_OP_OTHER(op)
+#endif
+
+#define DEFN_ASN_OP(op) \
+inline \
+sc_fxval_fast& \
+sc_fxval_fast::operator op ( const sc_fxval_fast& b ) \
+{ \
+ SC_FXVAL_FAST_OBSERVER_READ_( *this ) \
+ SC_FXVAL_FAST_OBSERVER_READ_( b ) \
+ m_val op b.m_val; \
+ SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) \
+ return *this; \
+} \
+ \
+DEFN_ASN_OP_T(op,int) \
+DEFN_ASN_OP_T(op,unsigned int) \
+DEFN_ASN_OP_T(op,long) \
+DEFN_ASN_OP_T(op,unsigned long) \
+DEFN_ASN_OP_T(op,float) \
+DEFN_ASN_OP_T(op,double) \
+DEFN_ASN_OP_T(op,const char*) \
+DEFN_ASN_OP_T(op,const sc_fxval&) \
+DEFN_ASN_OP_OTHER(op)
+
+DEFN_ASN_OP(*=)
+DEFN_ASN_OP(/=)
+DEFN_ASN_OP(+=)
+DEFN_ASN_OP(-=)
+
+#undef DEFN_ASN_OP_T
+#undef DEFN_ASN_OP_OTHER
+#undef DEFN_ASN_OP
+
+
+inline
+sc_fxval_fast&
+sc_fxval_fast::operator <<= ( int b )
+{
+ SC_FXVAL_FAST_OBSERVER_READ_( *this )
+ m_val *= scfx_pow2( b );
+ SC_FXVAL_FAST_OBSERVER_WRITE_( *this )
+ return *this;
+}
+
+inline
+sc_fxval_fast&
+sc_fxval_fast::operator >>= ( int b )
+{
+ SC_FXVAL_FAST_OBSERVER_READ_( *this )
+ m_val *= scfx_pow2( -b );
+ SC_FXVAL_FAST_OBSERVER_WRITE_( *this )
+ return *this;
+}
+
+
+// auto-increment and auto-decrement
+
+inline
+const sc_fxval_fast
+sc_fxval_fast::operator ++ ( int )
+{
+ SC_FXVAL_FAST_OBSERVER_READ_( *this )
+ SC_FXVAL_FAST_OBSERVER_READ_( *this )
+ double c = m_val;
+ m_val = m_val + 1;
+ SC_FXVAL_FAST_OBSERVER_WRITE_( *this )
+ return sc_fxval_fast( c );
+}
+
+inline
+const sc_fxval_fast
+sc_fxval_fast::operator -- ( int )
+{
+ SC_FXVAL_FAST_OBSERVER_READ_( *this )
+ SC_FXVAL_FAST_OBSERVER_READ_( *this )
+ double c = m_val;
+ m_val = m_val - 1;
+ SC_FXVAL_FAST_OBSERVER_WRITE_( *this )
+ return sc_fxval_fast( c );
+}
+
+inline
+sc_fxval_fast&
+sc_fxval_fast::operator ++ ()
+{
+ SC_FXVAL_FAST_OBSERVER_READ_( *this )
+ m_val = m_val + 1;
+ SC_FXVAL_FAST_OBSERVER_WRITE_( *this )
+ return *this;
+}
+
+inline
+sc_fxval_fast&
+sc_fxval_fast::operator -- ()
+{
+ SC_FXVAL_FAST_OBSERVER_READ_( *this )
+ m_val = m_val - 1;
+ SC_FXVAL_FAST_OBSERVER_WRITE_( *this )
+ return *this;
+}
+
+
+// implicit conversion
+
+inline
+sc_fxval_fast::operator double() const
+{
+ SC_FXVAL_FAST_OBSERVER_READ_( *this )
+ return m_val;
+}
+
+
+// explicit conversion to primitive types
+
+inline
+short
+sc_fxval_fast::to_short() const
+{
+ SC_FXVAL_FAST_OBSERVER_READ_( *this )
+ return static_cast<short>( m_val );
+}
+
+inline
+unsigned short
+sc_fxval_fast::to_ushort() const
+{
+ SC_FXVAL_FAST_OBSERVER_READ_( *this )
+ return static_cast<unsigned short>( m_val );
+}
+
+inline
+int64
+sc_fxval_fast::to_int64() const
+{
+ SC_FXVAL_FAST_OBSERVER_READ_( *this )
+ return static_cast<int64>( m_val );
+}
+
+inline
+int
+sc_fxval_fast::to_int() const
+{
+ SC_FXVAL_FAST_OBSERVER_READ_( *this )
+ return static_cast<int>( m_val );
+}
+
+inline
+unsigned int
+sc_fxval_fast::to_uint() const
+{
+ SC_FXVAL_FAST_OBSERVER_READ_( *this )
+ return static_cast<unsigned int>( m_val );
+}
+
+inline
+uint64
+sc_fxval_fast::to_uint64() const
+{
+ SC_FXVAL_FAST_OBSERVER_READ_( *this )
+ return static_cast<uint64>( m_val );
+}
+
+inline
+long
+sc_fxval_fast::to_long() const
+{
+ SC_FXVAL_FAST_OBSERVER_READ_( *this )
+ return static_cast<long>( m_val );
+}
+
+inline
+unsigned long
+sc_fxval_fast::to_ulong() const
+{
+ SC_FXVAL_FAST_OBSERVER_READ_( *this )
+ return static_cast<unsigned long>( m_val );
+}
+
+inline
+float
+sc_fxval_fast::to_float() const
+{
+ SC_FXVAL_FAST_OBSERVER_READ_( *this )
+ return static_cast<float>( m_val );
+}
+
+inline
+double
+sc_fxval_fast::to_double() const
+{
+ SC_FXVAL_FAST_OBSERVER_READ_( *this )
+ return m_val;
+}
+
+
+// query value
+
+inline
+bool
+sc_fxval_fast::is_neg() const
+{
+ SC_FXVAL_FAST_OBSERVER_READ_( *this )
+ scfx_ieee_double id( m_val );
+ return ( id.negative() != 0 );
+}
+
+inline
+bool
+sc_fxval_fast::is_zero() const
+{
+ SC_FXVAL_FAST_OBSERVER_READ_( *this )
+ scfx_ieee_double id( m_val );
+ return id.is_zero();
+}
+
+inline
+bool
+sc_fxval_fast::is_nan() const
+{
+ SC_FXVAL_FAST_OBSERVER_READ_( *this )
+ scfx_ieee_double id( m_val );
+ return id.is_nan();
+}
+
+inline
+bool
+sc_fxval_fast::is_inf() const
+{
+ SC_FXVAL_FAST_OBSERVER_READ_( *this )
+ scfx_ieee_double id( m_val );
+ return id.is_inf();
+}
+
+inline
+bool
+sc_fxval_fast::is_normal() const
+{
+ SC_FXVAL_FAST_OBSERVER_READ_( *this )
+ scfx_ieee_double id( m_val );
+ return ( id.is_normal() || id.is_subnormal() || id.is_zero() );
+}
+
+
+inline
+bool
+sc_fxval_fast::rounding_flag() const
+{
+ // does not apply to sc_fxval_fast; included for API compatibility
+ return false;
+}
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, const sc_fxval_fast& a )
+{
+ a.print( os );
+ return os;
+}
+
+inline
+::std::istream&
+operator >> ( ::std::istream& is, sc_fxval_fast& a )
+{
+ a.scan( is );
+ return is;
+}
+
+} // namespace sc_dt
+
+#undef SCFX_EXPLICIT_
+#undef SCFX_EXPLICIT_OTHER_
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxval_observer.cpp b/ext/systemc/src/sysc/datatypes/fx/sc_fxval_observer.cpp
new file mode 100644
index 000000000..ae651cc14
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxval_observer.cpp
@@ -0,0 +1,76 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_fxval_observer.cpp -
+
+ Original Author: Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// $Log: sc_fxval_observer.cpp,v $
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:58 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#include "sysc/datatypes/fx/sc_fxval_observer.h"
+
+
+namespace sc_dt
+{
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxval_observer
+//
+// Abstract base class for fixed-point value type observers;
+// arbitrary precision.
+// ----------------------------------------------------------------------------
+
+sc_fxval_observer* (*sc_fxval_observer::default_observer) () = 0;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxval_fast_observer
+//
+// Abstract base class for fixed-point value type observers;
+// limited precision.
+// ----------------------------------------------------------------------------
+
+sc_fxval_fast_observer* (*sc_fxval_fast_observer::default_observer) () = 0;
+
+} // namespace sc_dt
+
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxval_observer.h b/ext/systemc/src/sysc/datatypes/fx/sc_fxval_observer.h
new file mode 100644
index 000000000..e34d85c1b
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxval_observer.h
@@ -0,0 +1,223 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_fxval_observer.h -
+
+ Original Author: Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_fxval_observer.h,v $
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:58 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#ifndef SC_FXVAL_OBSERVER_H
+#define SC_FXVAL_OBSERVER_H
+
+
+#include "sysc/datatypes/fx/sc_fxdefs.h"
+
+
+namespace sc_dt
+{
+
+// classes defined in this module
+class sc_fxval_observer;
+class sc_fxval_fast_observer;
+
+// forward class declarations
+class sc_fxval;
+class sc_fxval_fast;
+
+
+#ifdef SC_ENABLE_OBSERVERS
+
+#define SC_FXVAL_OBSERVER_CONSTRUCT_(object) \
+ SC_OBSERVER_(object,sc_fxval_observer*,construct)
+#define SC_FXVAL_OBSERVER_DESTRUCT_(object) \
+ SC_OBSERVER_(object,sc_fxval_observer*,destruct)
+#define SC_FXVAL_OBSERVER_READ_(object) \
+ SC_OBSERVER_(object,sc_fxval_observer*,read)
+#define SC_FXVAL_OBSERVER_WRITE_(object) \
+ SC_OBSERVER_(object,sc_fxval_observer*,write)
+#define SC_FXVAL_OBSERVER_DEFAULT_ \
+ SC_OBSERVER_DEFAULT_(sc_fxval_observer)
+
+#define SC_FXVAL_FAST_OBSERVER_CONSTRUCT_(object) \
+ SC_OBSERVER_(object,sc_fxval_fast_observer*,construct)
+#define SC_FXVAL_FAST_OBSERVER_DESTRUCT_(object) \
+ SC_OBSERVER_(object,sc_fxval_fast_observer*,destruct)
+#define SC_FXVAL_FAST_OBSERVER_READ_(object) \
+ SC_OBSERVER_(object,sc_fxval_fast_observer*,read)
+#define SC_FXVAL_FAST_OBSERVER_WRITE_(object) \
+ SC_OBSERVER_(object,sc_fxval_fast_observer*,write)
+#define SC_FXVAL_FAST_OBSERVER_DEFAULT_ \
+ SC_OBSERVER_DEFAULT_(sc_fxval_fast_observer)
+
+#else
+
+#define SC_FXVAL_OBSERVER_CONSTRUCT_(object)
+#define SC_FXVAL_OBSERVER_DESTRUCT_(object)
+#define SC_FXVAL_OBSERVER_READ_(object)
+#define SC_FXVAL_OBSERVER_WRITE_(object)
+#define SC_FXVAL_OBSERVER_DEFAULT_
+
+#define SC_FXVAL_FAST_OBSERVER_CONSTRUCT_(object)
+#define SC_FXVAL_FAST_OBSERVER_DESTRUCT_(object)
+#define SC_FXVAL_FAST_OBSERVER_READ_(object)
+#define SC_FXVAL_FAST_OBSERVER_WRITE_(object)
+#define SC_FXVAL_FAST_OBSERVER_DEFAULT_
+
+#endif
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxval_observer
+//
+// Abstract base class for fixed-point value type observers;
+// arbitrary precision.
+// ----------------------------------------------------------------------------
+
+class sc_fxval_observer
+{
+
+protected:
+
+ sc_fxval_observer() {}
+ virtual ~sc_fxval_observer() {}
+
+public:
+
+ virtual void construct( const sc_fxval& );
+ virtual void destruct( const sc_fxval& );
+ virtual void read( const sc_fxval& );
+ virtual void write( const sc_fxval& );
+
+ static sc_fxval_observer* (*default_observer) ();
+
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxval_fast_observer
+//
+// Abstract base class for fixed-point value type observers;
+// limited precision.
+// ----------------------------------------------------------------------------
+
+class sc_fxval_fast_observer
+{
+
+protected:
+
+ sc_fxval_fast_observer() {}
+ virtual ~sc_fxval_fast_observer() {}
+
+public:
+
+ virtual void construct( const sc_fxval_fast& );
+ virtual void destruct( const sc_fxval_fast& );
+ virtual void read( const sc_fxval_fast& );
+ virtual void write( const sc_fxval_fast& );
+
+ static sc_fxval_fast_observer* (*default_observer) ();
+
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxval_observer
+//
+// Abstract base class for fixed-point value type observers;
+// arbitrary precision.
+// ----------------------------------------------------------------------------
+
+inline
+void
+sc_fxval_observer::construct( const sc_fxval& )
+{}
+
+inline
+void
+sc_fxval_observer::destruct( const sc_fxval& )
+{}
+
+inline
+void
+sc_fxval_observer::read( const sc_fxval& )
+{}
+
+inline
+void
+sc_fxval_observer::write( const sc_fxval& )
+{}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_fxval_fast_observer
+//
+// Abstract base class for fixed-point value type observers;
+// limited precision.
+// ----------------------------------------------------------------------------
+
+inline
+void
+sc_fxval_fast_observer::construct( const sc_fxval_fast& )
+{}
+
+inline
+void
+sc_fxval_fast_observer::destruct( const sc_fxval_fast& )
+{}
+
+inline
+void
+sc_fxval_fast_observer::read( const sc_fxval_fast& )
+{}
+
+inline
+void
+sc_fxval_fast_observer::write( const sc_fxval_fast& )
+{}
+
+} // namespace sc_dt
+
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_ufix.h b/ext/systemc/src/sysc/datatypes/fx/sc_ufix.h
new file mode 100644
index 000000000..b8d9acaa1
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/sc_ufix.h
@@ -0,0 +1,1941 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_ufix.h -
+
+ Original Author: Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_ufix.h,v $
+// Revision 1.2 2011/01/20 22:52:30 acg
+// Andy Goodrich: Add float constructors.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:58 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#ifndef SC_UFIX_H
+#define SC_UFIX_H
+
+
+#include "sysc/datatypes/fx/sc_fxnum.h"
+
+
+namespace sc_dt
+{
+
+// classes defined in this module
+class sc_ufix;
+class sc_ufix_fast;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_ufix
+//
+// "Unconstrained" unsigned fixed-point class; arbitrary precision.
+// ----------------------------------------------------------------------------
+
+class sc_ufix : public sc_fxnum
+{
+
+public:
+
+ // constructors
+
+ explicit sc_ufix( sc_fxnum_observer* = 0 );
+ sc_ufix( int, int,
+ sc_fxnum_observer* = 0 );
+ sc_ufix( sc_q_mode, sc_o_mode,
+ sc_fxnum_observer* = 0 );
+ sc_ufix( sc_q_mode, sc_o_mode, int,
+ sc_fxnum_observer* = 0 );
+ sc_ufix( int, int, sc_q_mode, sc_o_mode,
+ sc_fxnum_observer* = 0 );
+ sc_ufix( int, int, sc_q_mode, sc_o_mode, int,
+ sc_fxnum_observer* = 0 );
+ explicit sc_ufix( const sc_fxcast_switch&,
+ sc_fxnum_observer* = 0 );
+ sc_ufix( int, int,
+ const sc_fxcast_switch&,
+ sc_fxnum_observer* = 0 );
+ sc_ufix( sc_q_mode, sc_o_mode,
+ const sc_fxcast_switch&,
+ sc_fxnum_observer* = 0 );
+ sc_ufix( sc_q_mode, sc_o_mode, int,
+ const sc_fxcast_switch&,
+ sc_fxnum_observer* = 0 );
+ sc_ufix( int, int, sc_q_mode, sc_o_mode,
+ const sc_fxcast_switch&,
+ sc_fxnum_observer* = 0 );
+ sc_ufix( int, int, sc_q_mode, sc_o_mode, int,
+ const sc_fxcast_switch&,
+ sc_fxnum_observer* = 0 );
+ explicit sc_ufix( const sc_fxtype_params&,
+ sc_fxnum_observer* = 0 );
+ sc_ufix( const sc_fxtype_params&,
+ const sc_fxcast_switch&,
+ sc_fxnum_observer* = 0 );
+
+#define DECL_CTORS_T(tp) \
+ sc_ufix( tp, \
+ int, int, \
+ sc_fxnum_observer* = 0 ); \
+ sc_ufix( tp, \
+ sc_q_mode, sc_o_mode, \
+ sc_fxnum_observer* = 0 ); \
+ sc_ufix( tp, \
+ sc_q_mode, sc_o_mode, int, \
+ sc_fxnum_observer* = 0 ); \
+ sc_ufix( tp, \
+ int, int, sc_q_mode, sc_o_mode, \
+ sc_fxnum_observer* = 0 ); \
+ sc_ufix( tp, \
+ int, int, sc_q_mode, sc_o_mode, int, \
+ sc_fxnum_observer* = 0 ); \
+ sc_ufix( tp, \
+ const sc_fxcast_switch&, \
+ sc_fxnum_observer* = 0 ); \
+ sc_ufix( tp, \
+ int, int, \
+ const sc_fxcast_switch&, \
+ sc_fxnum_observer* = 0 ); \
+ sc_ufix( tp, \
+ sc_q_mode, sc_o_mode, \
+ const sc_fxcast_switch&, \
+ sc_fxnum_observer* = 0 ); \
+ sc_ufix( tp, \
+ sc_q_mode, sc_o_mode, int, \
+ const sc_fxcast_switch&, \
+ sc_fxnum_observer* = 0 ); \
+ sc_ufix( tp, \
+ int, int, sc_q_mode, sc_o_mode, \
+ const sc_fxcast_switch&, \
+ sc_fxnum_observer* = 0 ); \
+ sc_ufix( tp, \
+ int, int, sc_q_mode, sc_o_mode, int, \
+ const sc_fxcast_switch&, \
+ sc_fxnum_observer* = 0 ); \
+ sc_ufix( tp, \
+ const sc_fxtype_params&, \
+ sc_fxnum_observer* = 0 ); \
+ sc_ufix( tp, \
+ const sc_fxtype_params&, \
+ const sc_fxcast_switch&, \
+ sc_fxnum_observer* = 0 );
+
+#define DECL_CTORS_T_A(tp) \
+ sc_ufix( tp, \
+ sc_fxnum_observer* = 0 ); \
+ DECL_CTORS_T(tp)
+
+#define DECL_CTORS_T_B(tp) \
+ explicit sc_ufix( tp, \
+ sc_fxnum_observer* = 0 ); \
+ DECL_CTORS_T(tp)
+
+ DECL_CTORS_T_A(int)
+ DECL_CTORS_T_A(unsigned int)
+ DECL_CTORS_T_A(long)
+ DECL_CTORS_T_A(unsigned long)
+ DECL_CTORS_T_A(float)
+ DECL_CTORS_T_A(double)
+ DECL_CTORS_T_A(const char*)
+ DECL_CTORS_T_A(const sc_fxval&)
+ DECL_CTORS_T_A(const sc_fxval_fast&)
+ DECL_CTORS_T_A(const sc_fxnum&)
+ DECL_CTORS_T_A(const sc_fxnum_fast&)
+#ifndef SC_FX_EXCLUDE_OTHER
+ DECL_CTORS_T_B(int64)
+ DECL_CTORS_T_B(uint64)
+ DECL_CTORS_T_B(const sc_int_base&)
+ DECL_CTORS_T_B(const sc_uint_base&)
+ DECL_CTORS_T_B(const sc_signed&)
+ DECL_CTORS_T_B(const sc_unsigned&)
+#endif
+
+#undef DECL_CTORS_T
+#undef DECL_CTORS_T_A
+#undef DECL_CTORS_T_B
+
+ // copy constructor
+
+ sc_ufix( const sc_ufix& );
+
+
+ // unary bitwise operators
+
+ const sc_ufix operator ~ () const;
+
+
+ // unary bitwise functions
+
+ friend void b_not( sc_ufix&, const sc_ufix& );
+
+
+ // binary bitwise operators
+
+ friend const sc_ufix operator & ( const sc_ufix&, const sc_ufix& );
+ friend const sc_ufix operator & ( const sc_ufix&, const sc_ufix_fast& );
+ friend const sc_ufix operator & ( const sc_ufix_fast&, const sc_ufix& );
+ friend const sc_ufix operator | ( const sc_ufix&, const sc_ufix& );
+ friend const sc_ufix operator | ( const sc_ufix&, const sc_ufix_fast& );
+ friend const sc_ufix operator | ( const sc_ufix_fast&, const sc_ufix& );
+ friend const sc_ufix operator ^ ( const sc_ufix&, const sc_ufix& );
+ friend const sc_ufix operator ^ ( const sc_ufix&, const sc_ufix_fast& );
+ friend const sc_ufix operator ^ ( const sc_ufix_fast&, const sc_ufix& );
+
+
+ // binary bitwise functions
+
+ friend void b_and( sc_ufix&, const sc_ufix&, const sc_ufix& );
+ friend void b_and( sc_ufix&, const sc_ufix&, const sc_ufix_fast& );
+ friend void b_and( sc_ufix&, const sc_ufix_fast&, const sc_ufix& );
+ friend void b_or ( sc_ufix&, const sc_ufix&, const sc_ufix& );
+ friend void b_or ( sc_ufix&, const sc_ufix&, const sc_ufix_fast& );
+ friend void b_or ( sc_ufix&, const sc_ufix_fast&, const sc_ufix& );
+ friend void b_xor( sc_ufix&, const sc_ufix&, const sc_ufix& );
+ friend void b_xor( sc_ufix&, const sc_ufix&, const sc_ufix_fast& );
+ friend void b_xor( sc_ufix&, const sc_ufix_fast&, const sc_ufix& );
+
+
+ // assignment operators
+
+ sc_ufix& operator = ( const sc_ufix& );
+
+#define DECL_ASN_OP_T(op,tp) \
+ sc_ufix& operator op ( tp );
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DECL_ASN_OP_OTHER(op) \
+ DECL_ASN_OP_T(op,int64) \
+ DECL_ASN_OP_T(op,uint64) \
+ DECL_ASN_OP_T(op,const sc_int_base&) \
+ DECL_ASN_OP_T(op,const sc_uint_base&) \
+ DECL_ASN_OP_T(op,const sc_signed&) \
+ DECL_ASN_OP_T(op,const sc_unsigned&)
+#else
+#define DECL_ASN_OP_OTHER(op)
+#endif
+
+#define DECL_ASN_OP(op) \
+ DECL_ASN_OP_T(op,int) \
+ DECL_ASN_OP_T(op,unsigned int) \
+ DECL_ASN_OP_T(op,long) \
+ DECL_ASN_OP_T(op,unsigned long) \
+ DECL_ASN_OP_T(op,float) \
+ DECL_ASN_OP_T(op,double) \
+ DECL_ASN_OP_T(op,const char*) \
+ DECL_ASN_OP_T(op,const sc_fxval&) \
+ DECL_ASN_OP_T(op,const sc_fxval_fast&) \
+ DECL_ASN_OP_T(op,const sc_fxnum&) \
+ DECL_ASN_OP_T(op,const sc_fxnum_fast&) \
+ DECL_ASN_OP_OTHER(op)
+
+ DECL_ASN_OP(=)
+
+ DECL_ASN_OP(*=)
+ DECL_ASN_OP(/=)
+ DECL_ASN_OP(+=)
+ DECL_ASN_OP(-=)
+
+ DECL_ASN_OP_T(<<=,int)
+ DECL_ASN_OP_T(>>=,int)
+
+ DECL_ASN_OP_T(&=,const sc_ufix&)
+ DECL_ASN_OP_T(&=,const sc_ufix_fast&)
+ DECL_ASN_OP_T(|=,const sc_ufix&)
+ DECL_ASN_OP_T(|=,const sc_ufix_fast&)
+ DECL_ASN_OP_T(^=,const sc_ufix&)
+ DECL_ASN_OP_T(^=,const sc_ufix_fast&)
+
+#undef DECL_ASN_OP_T
+#undef DECL_ASN_OP_OTHER
+#undef DECL_ASN_OP
+
+
+ // auto-increment and auto-decrement
+
+ const sc_fxval operator ++ ( int );
+ const sc_fxval operator -- ( int );
+
+ sc_ufix& operator ++ ();
+ sc_ufix& operator -- ();
+
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_ufix_fast
+//
+// "Unconstrained" unsigned fixed-point class; limited precision.
+// ----------------------------------------------------------------------------
+
+class sc_ufix_fast : public sc_fxnum_fast
+{
+
+public:
+
+ // constructors
+
+ explicit sc_ufix_fast( sc_fxnum_fast_observer* = 0 );
+ sc_ufix_fast( int, int,
+ sc_fxnum_fast_observer* = 0 );
+ sc_ufix_fast( sc_q_mode, sc_o_mode,
+ sc_fxnum_fast_observer* = 0 );
+ sc_ufix_fast( sc_q_mode, sc_o_mode, int,
+ sc_fxnum_fast_observer* = 0 );
+ sc_ufix_fast( int, int, sc_q_mode, sc_o_mode,
+ sc_fxnum_fast_observer* = 0 );
+ sc_ufix_fast( int, int, sc_q_mode, sc_o_mode, int,
+ sc_fxnum_fast_observer* = 0 );
+ explicit sc_ufix_fast( const sc_fxcast_switch&,
+ sc_fxnum_fast_observer* = 0 );
+ sc_ufix_fast( int, int,
+ const sc_fxcast_switch&,
+ sc_fxnum_fast_observer* = 0 );
+ sc_ufix_fast( sc_q_mode, sc_o_mode,
+ const sc_fxcast_switch&,
+ sc_fxnum_fast_observer* = 0 );
+ sc_ufix_fast( sc_q_mode, sc_o_mode, int,
+ const sc_fxcast_switch&,
+ sc_fxnum_fast_observer* = 0 );
+ sc_ufix_fast( int, int, sc_q_mode, sc_o_mode,
+ const sc_fxcast_switch&,
+ sc_fxnum_fast_observer* = 0 );
+ sc_ufix_fast( int, int, sc_q_mode, sc_o_mode, int,
+ const sc_fxcast_switch&,
+ sc_fxnum_fast_observer* = 0 );
+ explicit sc_ufix_fast( const sc_fxtype_params&,
+ sc_fxnum_fast_observer* = 0 );
+ sc_ufix_fast( const sc_fxtype_params&,
+ const sc_fxcast_switch&,
+ sc_fxnum_fast_observer* = 0 );
+
+#define DECL_CTORS_T(tp) \
+ sc_ufix_fast( tp, \
+ int, int, \
+ sc_fxnum_fast_observer* = 0 ); \
+ sc_ufix_fast( tp, \
+ sc_q_mode, sc_o_mode, \
+ sc_fxnum_fast_observer* = 0 ); \
+ sc_ufix_fast( tp, \
+ sc_q_mode, sc_o_mode, int, \
+ sc_fxnum_fast_observer* = 0 ); \
+ sc_ufix_fast( tp, \
+ int, int, sc_q_mode, sc_o_mode, \
+ sc_fxnum_fast_observer* = 0 ); \
+ sc_ufix_fast( tp, \
+ int, int, sc_q_mode, sc_o_mode, int, \
+ sc_fxnum_fast_observer* = 0 ); \
+ sc_ufix_fast( tp, \
+ const sc_fxcast_switch&, \
+ sc_fxnum_fast_observer* = 0 ); \
+ sc_ufix_fast( tp, \
+ int, int, \
+ const sc_fxcast_switch&, \
+ sc_fxnum_fast_observer* = 0 ); \
+ sc_ufix_fast( tp, \
+ sc_q_mode, sc_o_mode, \
+ const sc_fxcast_switch&, \
+ sc_fxnum_fast_observer* = 0 ); \
+ sc_ufix_fast( tp, \
+ sc_q_mode, sc_o_mode, int, \
+ const sc_fxcast_switch&, \
+ sc_fxnum_fast_observer* = 0 ); \
+ sc_ufix_fast( tp, \
+ int, int, sc_q_mode, sc_o_mode, \
+ const sc_fxcast_switch&, \
+ sc_fxnum_fast_observer* = 0 ); \
+ sc_ufix_fast( tp, \
+ int, int, sc_q_mode, sc_o_mode, int, \
+ const sc_fxcast_switch&, \
+ sc_fxnum_fast_observer* = 0 ); \
+ sc_ufix_fast( tp, \
+ const sc_fxtype_params&, \
+ sc_fxnum_fast_observer* = 0 ); \
+ sc_ufix_fast( tp, \
+ const sc_fxtype_params&, \
+ const sc_fxcast_switch&, \
+ sc_fxnum_fast_observer* = 0 );
+
+#define DECL_CTORS_T_A(tp) \
+ sc_ufix_fast( tp, \
+ sc_fxnum_fast_observer* = 0 ); \
+ DECL_CTORS_T(tp)
+
+#define DECL_CTORS_T_B(tp) \
+ explicit sc_ufix_fast( tp, \
+ sc_fxnum_fast_observer* = 0 ); \
+ DECL_CTORS_T(tp)
+
+ DECL_CTORS_T_A(int)
+ DECL_CTORS_T_A(unsigned int)
+ DECL_CTORS_T_A(long)
+ DECL_CTORS_T_A(unsigned long)
+ DECL_CTORS_T_A(float)
+ DECL_CTORS_T_A(double)
+ DECL_CTORS_T_A(const char*)
+ DECL_CTORS_T_A(const sc_fxval&)
+ DECL_CTORS_T_A(const sc_fxval_fast&)
+ DECL_CTORS_T_A(const sc_fxnum&)
+ DECL_CTORS_T_A(const sc_fxnum_fast&)
+#ifndef SC_FX_EXCLUDE_OTHER
+ DECL_CTORS_T_B(int64)
+ DECL_CTORS_T_B(uint64)
+ DECL_CTORS_T_B(const sc_int_base&)
+ DECL_CTORS_T_B(const sc_uint_base&)
+ DECL_CTORS_T_B(const sc_signed&)
+ DECL_CTORS_T_B(const sc_unsigned&)
+#endif
+
+#undef DECL_CTORS_T
+#undef DECL_CTORS_T_A
+#undef DECL_CTORS_T_B
+
+ // copy constructor
+
+ sc_ufix_fast( const sc_ufix_fast& );
+
+
+ // unary bitwise operators
+
+ const sc_ufix_fast operator ~ () const;
+
+
+ // unary bitwise functions
+
+ friend void b_not( sc_ufix_fast&, const sc_ufix_fast& );
+
+
+ // binary bitwise operators
+
+ friend const sc_ufix_fast operator & ( const sc_ufix_fast&,
+ const sc_ufix_fast& );
+ friend const sc_ufix_fast operator ^ ( const sc_ufix_fast&,
+ const sc_ufix_fast& );
+ friend const sc_ufix_fast operator | ( const sc_ufix_fast&,
+ const sc_ufix_fast& );
+
+
+ // binary bitwise functions
+
+ friend void b_and( sc_ufix_fast&, const sc_ufix_fast&,
+ const sc_ufix_fast& );
+ friend void b_or ( sc_ufix_fast&, const sc_ufix_fast&,
+ const sc_ufix_fast& );
+ friend void b_xor( sc_ufix_fast&, const sc_ufix_fast&,
+ const sc_ufix_fast& );
+
+
+ // assignment operators
+
+ sc_ufix_fast& operator = ( const sc_ufix_fast& );
+
+#define DECL_ASN_OP_T(op,tp) \
+ sc_ufix_fast& operator op ( tp );
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DECL_ASN_OP_OTHER(op) \
+ DECL_ASN_OP_T(op,int64) \
+ DECL_ASN_OP_T(op,uint64) \
+ DECL_ASN_OP_T(op,const sc_int_base&) \
+ DECL_ASN_OP_T(op,const sc_uint_base&) \
+ DECL_ASN_OP_T(op,const sc_signed&) \
+ DECL_ASN_OP_T(op,const sc_unsigned&)
+#else
+#define DECL_ASN_OP_OTHER(op)
+#endif
+
+#define DECL_ASN_OP(op) \
+ DECL_ASN_OP_T(op,int) \
+ DECL_ASN_OP_T(op,unsigned int) \
+ DECL_ASN_OP_T(op,long) \
+ DECL_ASN_OP_T(op,unsigned long) \
+ DECL_ASN_OP_T(op,float) \
+ DECL_ASN_OP_T(op,double) \
+ DECL_ASN_OP_T(op,const char*) \
+ DECL_ASN_OP_T(op,const sc_fxval&) \
+ DECL_ASN_OP_T(op,const sc_fxval_fast&) \
+ DECL_ASN_OP_T(op,const sc_fxnum&) \
+ DECL_ASN_OP_T(op,const sc_fxnum_fast&) \
+ DECL_ASN_OP_OTHER(op)
+
+ DECL_ASN_OP(=)
+
+ DECL_ASN_OP(*=)
+ DECL_ASN_OP(/=)
+ DECL_ASN_OP(+=)
+ DECL_ASN_OP(-=)
+
+ DECL_ASN_OP_T(<<=,int)
+ DECL_ASN_OP_T(>>=,int)
+
+ DECL_ASN_OP_T(&=,const sc_ufix&)
+ DECL_ASN_OP_T(&=,const sc_ufix_fast&)
+ DECL_ASN_OP_T(|=,const sc_ufix&)
+ DECL_ASN_OP_T(|=,const sc_ufix_fast&)
+ DECL_ASN_OP_T(^=,const sc_ufix&)
+ DECL_ASN_OP_T(^=,const sc_ufix_fast&)
+
+#undef DECL_ASN_OP_T
+#undef DECL_ASN_OP_OTHER
+#undef DECL_ASN_OP
+
+
+ // auto-increment and auto-decrement
+
+ const sc_fxval_fast operator ++ ( int );
+ const sc_fxval_fast operator -- ( int );
+
+ sc_ufix_fast& operator ++ ();
+ sc_ufix_fast& operator -- ();
+
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_ufix
+//
+// "Unconstrained" unsigned fixed-point class; arbitrary precision.
+// ----------------------------------------------------------------------------
+
+// constructors
+
+inline
+sc_ufix::sc_ufix( sc_fxnum_observer* observer_ )
+: sc_fxnum( sc_fxtype_params(),
+ SC_US_,
+ sc_fxcast_switch(),
+ observer_ )
+{}
+
+inline
+sc_ufix::sc_ufix( int wl_, int iwl_,
+ sc_fxnum_observer* observer_ )
+: sc_fxnum( sc_fxtype_params( wl_, iwl_ ),
+ SC_US_,
+ sc_fxcast_switch(),
+ observer_ )
+{}
+
+inline
+sc_ufix::sc_ufix( sc_q_mode qm, sc_o_mode om,
+ sc_fxnum_observer* observer_ )
+: sc_fxnum( sc_fxtype_params( qm, om ),
+ SC_US_,
+ sc_fxcast_switch(),
+ observer_ )
+{}
+
+inline
+sc_ufix::sc_ufix( sc_q_mode qm, sc_o_mode om, int nb,
+ sc_fxnum_observer* observer_ )
+: sc_fxnum( sc_fxtype_params( qm, om, nb ),
+ SC_US_,
+ sc_fxcast_switch(),
+ observer_ )
+{}
+
+inline
+sc_ufix::sc_ufix( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om,
+ sc_fxnum_observer* observer_ )
+: sc_fxnum( sc_fxtype_params( wl_, iwl_, qm, om ),
+ SC_US_,
+ sc_fxcast_switch(),
+ observer_ )
+{}
+
+inline
+sc_ufix::sc_ufix( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb,
+ sc_fxnum_observer* observer_ )
+: sc_fxnum( sc_fxtype_params( wl_, iwl_, qm, om, nb ),
+ SC_US_,
+ sc_fxcast_switch(),
+ observer_ )
+{}
+
+inline
+sc_ufix::sc_ufix( const sc_fxcast_switch& cast_sw,
+ sc_fxnum_observer* observer_ )
+: sc_fxnum( sc_fxtype_params(),
+ SC_US_,
+ cast_sw,
+ observer_ )
+{}
+
+inline
+sc_ufix::sc_ufix( int wl_, int iwl_,
+ const sc_fxcast_switch& cast_sw,
+ sc_fxnum_observer* observer_ )
+: sc_fxnum( sc_fxtype_params( wl_, iwl_ ),
+ SC_US_,
+ cast_sw,
+ observer_ )
+{}
+
+inline
+sc_ufix::sc_ufix( sc_q_mode qm, sc_o_mode om,
+ const sc_fxcast_switch& cast_sw,
+ sc_fxnum_observer* observer_ )
+: sc_fxnum( sc_fxtype_params( qm, om ),
+ SC_US_,
+ cast_sw,
+ observer_ )
+{}
+
+inline
+sc_ufix::sc_ufix( sc_q_mode qm, sc_o_mode om, int nb,
+ const sc_fxcast_switch& cast_sw,
+ sc_fxnum_observer* observer_ )
+: sc_fxnum( sc_fxtype_params( qm, om, nb ),
+ SC_US_,
+ cast_sw,
+ observer_ )
+{}
+
+inline
+sc_ufix::sc_ufix( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om,
+ const sc_fxcast_switch& cast_sw,
+ sc_fxnum_observer* observer_ )
+: sc_fxnum( sc_fxtype_params( wl_, iwl_, qm, om ),
+ SC_US_,
+ cast_sw,
+ observer_ )
+{}
+
+inline
+sc_ufix::sc_ufix( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb,
+ const sc_fxcast_switch& cast_sw,
+ sc_fxnum_observer* observer_ )
+: sc_fxnum( sc_fxtype_params( wl_, iwl_, qm, om, nb ),
+ SC_US_,
+ cast_sw,
+ observer_ )
+{}
+
+inline
+sc_ufix::sc_ufix( const sc_fxtype_params& type_params,
+ sc_fxnum_observer* observer_ )
+: sc_fxnum( type_params,
+ SC_US_,
+ sc_fxcast_switch(),
+ observer_ )
+{}
+
+inline
+sc_ufix::sc_ufix( const sc_fxtype_params& type_params,
+ const sc_fxcast_switch& cast_sw,
+ sc_fxnum_observer* observer_ )
+: sc_fxnum( type_params,
+ SC_US_,
+ cast_sw,
+ observer_ )
+{}
+
+#define DEFN_CTORS_T_A(tp) \
+inline \
+sc_ufix::sc_ufix( tp a, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params(), \
+ SC_US_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix::sc_ufix( tp a, \
+ int wl_, int iwl_, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( wl_, iwl_ ), \
+ SC_US_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix::sc_ufix( tp a, \
+ sc_q_mode qm, sc_o_mode om, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( qm, om ), \
+ SC_US_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix::sc_ufix( tp a, \
+ sc_q_mode qm, sc_o_mode om, int nb, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( qm, om, nb ), \
+ SC_US_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix::sc_ufix( tp a, \
+ int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om ), \
+ SC_US_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix::sc_ufix( tp a, \
+ int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om, nb ), \
+ SC_US_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix::sc_ufix( tp a, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params(), \
+ SC_US_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix::sc_ufix( tp a, \
+ int wl_, int iwl_, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( wl_, iwl_ ), \
+ SC_US_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix::sc_ufix( tp a, \
+ sc_q_mode qm, sc_o_mode om, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( qm, om ), \
+ SC_US_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix::sc_ufix( tp a, \
+ sc_q_mode qm, sc_o_mode om, int nb, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( qm, om, nb ), \
+ SC_US_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix::sc_ufix( tp a, \
+ int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om ), \
+ SC_US_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix::sc_ufix( tp a, \
+ int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om, nb ), \
+ SC_US_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix::sc_ufix( tp a, \
+ const sc_fxtype_params& type_params, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ type_params, \
+ SC_US_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix::sc_ufix( tp a, \
+ const sc_fxtype_params& type_params, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ type_params, \
+ SC_US_, \
+ cast_sw, \
+ observer_ ) \
+{}
+
+#define DEFN_CTORS_T_B(tp) \
+inline \
+sc_ufix::sc_ufix( tp a, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ a.type_params(), \
+ SC_US_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix::sc_ufix( tp a, \
+ int wl_, int iwl_, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( a.type_params(), wl_, iwl_ ), \
+ SC_US_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix::sc_ufix( tp a, \
+ sc_q_mode qm, sc_o_mode om, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( a.type_params(), qm, om ), \
+ SC_US_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix::sc_ufix( tp a, \
+ sc_q_mode qm, sc_o_mode om, int nb, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( a.type_params(), qm, om, nb ), \
+ SC_US_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix::sc_ufix( tp a, \
+ int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om ), \
+ SC_US_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix::sc_ufix( tp a, \
+ int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om, nb ), \
+ SC_US_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix::sc_ufix( tp a, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ a.type_params(), \
+ SC_US_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix::sc_ufix( tp a, \
+ int wl_, int iwl_, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( a.type_params(), wl_, iwl_ ), \
+ SC_US_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix::sc_ufix( tp a, \
+ sc_q_mode qm, sc_o_mode om, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( a.type_params(), qm, om ), \
+ SC_US_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix::sc_ufix( tp a, \
+ sc_q_mode qm, sc_o_mode om, int nb, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( a.type_params(), qm, om, nb ), \
+ SC_US_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix::sc_ufix( tp a, \
+ int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om ), \
+ SC_US_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix::sc_ufix( tp a, \
+ int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om, nb ), \
+ SC_US_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix::sc_ufix( tp a, \
+ const sc_fxtype_params& type_params, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ type_params, \
+ SC_US_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix::sc_ufix( tp a, \
+ const sc_fxtype_params& type_params, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_observer* observer_ ) \
+: sc_fxnum( a, \
+ type_params, \
+ SC_US_, \
+ cast_sw, \
+ observer_ ) \
+{}
+
+DEFN_CTORS_T_A(int)
+DEFN_CTORS_T_A(unsigned int)
+DEFN_CTORS_T_A(long)
+DEFN_CTORS_T_A(unsigned long)
+DEFN_CTORS_T_A(float)
+DEFN_CTORS_T_A(double)
+DEFN_CTORS_T_A(const char*)
+DEFN_CTORS_T_A(const sc_fxval&)
+DEFN_CTORS_T_A(const sc_fxval_fast&)
+DEFN_CTORS_T_B(const sc_fxnum&)
+DEFN_CTORS_T_B(const sc_fxnum_fast&)
+#ifndef SC_FX_EXCLUDE_OTHER
+DEFN_CTORS_T_A(int64)
+DEFN_CTORS_T_A(uint64)
+DEFN_CTORS_T_A(const sc_int_base&)
+DEFN_CTORS_T_A(const sc_uint_base&)
+DEFN_CTORS_T_A(const sc_signed&)
+DEFN_CTORS_T_A(const sc_unsigned&)
+#endif
+
+#undef DEFN_CTORS_T_A
+#undef DEFN_CTORS_T_B
+
+// copy constructor
+
+inline
+sc_ufix::sc_ufix( const sc_ufix& a )
+: sc_fxnum( a,
+ a.type_params(),
+ SC_US_,
+ sc_fxcast_switch(),
+ 0 )
+{}
+
+
+// unary bitwise operators
+
+inline
+const sc_ufix
+sc_ufix::operator ~ () const
+{
+ SC_FXNUM_OBSERVER_READ_( *this )
+ int iwl_c = iwl();
+ int wl_c = wl();
+ sc_ufix c( wl_c, iwl_c );
+ for( int i = iwl_c - wl_c; i < iwl_c; ++ i )
+ c.set_bit( i, ! get_bit( i ) );
+ return sc_ufix( c, wl_c, iwl_c );
+}
+
+
+// unary bitwise functions
+
+inline
+void
+b_not( sc_ufix& c, const sc_ufix& a )
+{
+ SC_FXNUM_OBSERVER_READ_( a )
+ int iwl_c = c.iwl();
+ for( int i = iwl_c - c.wl(); i < iwl_c; ++ i )
+ c.set_bit( i, ! a.get_bit( i ) );
+ c.cast();
+ SC_FXNUM_OBSERVER_WRITE_( c )
+}
+
+
+// binary bitwise operators
+
+#define DEFN_BIN_OP_T(op,op2,tp1,tp2) \
+inline \
+const sc_ufix \
+operator op ( const tp1& a, const tp2& b ) \
+{ \
+ a.observer_read(); \
+ b.observer_read(); \
+ int iwl_a = a.iwl(); \
+ int iwl_b = b.iwl(); \
+ int iwl_c = sc_max( iwl_a, iwl_b ); \
+ int fwl_c = sc_max( a.wl() - iwl_a, b.wl() - iwl_b ); \
+ sc_ufix c( iwl_c + fwl_c, iwl_c ); \
+ for( int i = -fwl_c; i < iwl_c; ++ i ) \
+ c.set_bit( i, a.get_bit( i ) op2 b.get_bit( i ) ); \
+ return sc_ufix( c, iwl_c + fwl_c, iwl_c ); \
+}
+
+DEFN_BIN_OP_T(&,&&,sc_ufix,sc_ufix)
+DEFN_BIN_OP_T(&,&&,sc_ufix,sc_ufix_fast)
+DEFN_BIN_OP_T(&,&&,sc_ufix_fast,sc_ufix)
+
+DEFN_BIN_OP_T(|,||,sc_ufix,sc_ufix)
+DEFN_BIN_OP_T(|,||,sc_ufix,sc_ufix_fast)
+DEFN_BIN_OP_T(|,||,sc_ufix_fast,sc_ufix)
+
+DEFN_BIN_OP_T(^,!=,sc_ufix,sc_ufix)
+DEFN_BIN_OP_T(^,!=,sc_ufix,sc_ufix_fast)
+DEFN_BIN_OP_T(^,!=,sc_ufix_fast,sc_ufix)
+
+#undef DEFN_BIN_OP_T
+
+
+// binary bitwise functions
+
+#define DEFN_BIN_FNC_T(fnc,op2,tp1,tp2) \
+inline \
+void \
+fnc ( sc_ufix& c, const tp1& a, const tp2& b ) \
+{ \
+ a.observer_read(); \
+ b.observer_read(); \
+ int iwl_c = c.iwl(); \
+ for( int i = iwl_c - c.wl(); i < iwl_c; ++ i ) \
+ c.set_bit( i, a.get_bit( i ) op2 b.get_bit( i ) ); \
+ c.cast(); \
+ SC_FXNUM_OBSERVER_WRITE_( c ) \
+}
+
+DEFN_BIN_FNC_T(b_and,&&,sc_ufix,sc_ufix)
+DEFN_BIN_FNC_T(b_and,&&,sc_ufix,sc_ufix_fast)
+DEFN_BIN_FNC_T(b_and,&&,sc_ufix_fast,sc_ufix)
+
+DEFN_BIN_FNC_T(b_or,||,sc_ufix,sc_ufix)
+DEFN_BIN_FNC_T(b_or,||,sc_ufix,sc_ufix_fast)
+DEFN_BIN_FNC_T(b_or,||,sc_ufix_fast,sc_ufix)
+
+DEFN_BIN_FNC_T(b_xor,!=,sc_ufix,sc_ufix)
+DEFN_BIN_FNC_T(b_xor,!=,sc_ufix,sc_ufix_fast)
+DEFN_BIN_FNC_T(b_xor,!=,sc_ufix_fast,sc_ufix)
+
+#undef DEFN_BIN_FNC_T
+
+
+// assignment operators
+
+inline
+sc_ufix&
+sc_ufix::operator = ( const sc_ufix& a )
+{
+ sc_fxnum::operator = ( a );
+ return *this;
+}
+
+#define DEFN_ASN_OP_T(op,tp) \
+inline \
+sc_ufix& \
+sc_ufix::operator op ( tp a ) \
+{ \
+ sc_fxnum::operator op( a ); \
+ return *this; \
+}
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DEFN_ASN_OP_OTHER(op) \
+DEFN_ASN_OP_T(op,int64) \
+DEFN_ASN_OP_T(op,uint64) \
+DEFN_ASN_OP_T(op,const sc_int_base&) \
+DEFN_ASN_OP_T(op,const sc_uint_base&) \
+DEFN_ASN_OP_T(op,const sc_signed&) \
+DEFN_ASN_OP_T(op,const sc_unsigned&)
+#else
+#define DEFN_ASN_OP_OTHER(op)
+#endif
+
+#define DEFN_ASN_OP(op) \
+DEFN_ASN_OP_T(op,int) \
+DEFN_ASN_OP_T(op,unsigned int) \
+DEFN_ASN_OP_T(op,long) \
+DEFN_ASN_OP_T(op,unsigned long) \
+DEFN_ASN_OP_T(op,float) \
+DEFN_ASN_OP_T(op,double) \
+DEFN_ASN_OP_T(op,const char*) \
+DEFN_ASN_OP_T(op,const sc_fxval&) \
+DEFN_ASN_OP_T(op,const sc_fxval_fast&) \
+DEFN_ASN_OP_T(op,const sc_fxnum&) \
+DEFN_ASN_OP_T(op,const sc_fxnum_fast&) \
+DEFN_ASN_OP_OTHER(op)
+
+DEFN_ASN_OP(=)
+
+DEFN_ASN_OP(*=)
+DEFN_ASN_OP(/=)
+DEFN_ASN_OP(+=)
+DEFN_ASN_OP(-=)
+
+DEFN_ASN_OP_T(<<=,int)
+DEFN_ASN_OP_T(>>=,int)
+
+#undef DEFN_ASN_OP_T
+#undef DEFN_ASN_OP_OTHER
+#undef DEFN_ASN_OP
+
+
+#define DEFN_ASN_OP_T(op,op2,tp) \
+inline \
+sc_ufix& \
+sc_ufix::operator op ( const tp& b ) \
+{ \
+ SC_FXNUM_OBSERVER_READ_( *this ) \
+ b.observer_read(); \
+ int iwl_c = iwl(); \
+ for( int i = iwl_c - wl(); i < iwl_c; ++ i ) \
+ set_bit( i, get_bit( i ) op2 b.get_bit( i ) ); \
+ cast(); \
+ SC_FXNUM_OBSERVER_WRITE_( *this ) \
+ return *this; \
+}
+
+DEFN_ASN_OP_T(&=,&&,sc_ufix)
+DEFN_ASN_OP_T(&=,&&,sc_ufix_fast)
+DEFN_ASN_OP_T(|=,||,sc_ufix)
+DEFN_ASN_OP_T(|=,||,sc_ufix_fast)
+DEFN_ASN_OP_T(^=,!=,sc_ufix)
+DEFN_ASN_OP_T(^=,!=,sc_ufix_fast)
+
+#undef DEFN_ASN_OP_T
+
+
+// auto-increment and auto-decrement
+
+inline
+const sc_fxval
+sc_ufix::operator ++ ( int )
+{
+ return sc_fxval( sc_fxnum::operator ++ ( 0 ) );
+}
+
+inline
+const sc_fxval
+sc_ufix::operator -- ( int )
+{
+ return sc_fxval( sc_fxnum::operator -- ( 0 ) );
+}
+
+inline
+sc_ufix&
+sc_ufix::operator ++ ()
+{
+ sc_fxnum::operator ++ ();
+ return *this;
+}
+
+inline
+sc_ufix&
+sc_ufix::operator -- ()
+{
+ sc_fxnum::operator -- ();
+ return *this;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_ufix_fast
+//
+// "Unconstrained" unsigned fixed-point class; limited precision.
+// ----------------------------------------------------------------------------
+
+// constructors
+
+inline
+sc_ufix_fast::sc_ufix_fast( sc_fxnum_fast_observer* observer_ )
+: sc_fxnum_fast( sc_fxtype_params(),
+ SC_US_,
+ sc_fxcast_switch(),
+ observer_ )
+{}
+
+inline
+sc_ufix_fast::sc_ufix_fast( int wl_, int iwl_,
+ sc_fxnum_fast_observer* observer_ )
+: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_ ),
+ SC_US_,
+ sc_fxcast_switch(),
+ observer_ )
+{}
+
+inline
+sc_ufix_fast::sc_ufix_fast( sc_q_mode qm, sc_o_mode om,
+ sc_fxnum_fast_observer* observer_ )
+: sc_fxnum_fast( sc_fxtype_params( qm, om ),
+ SC_US_,
+ sc_fxcast_switch(),
+ observer_ )
+{}
+
+inline
+sc_ufix_fast::sc_ufix_fast( sc_q_mode qm, sc_o_mode om, int nb,
+ sc_fxnum_fast_observer* observer_ )
+: sc_fxnum_fast( sc_fxtype_params( qm, om, nb ),
+ SC_US_,
+ sc_fxcast_switch(),
+ observer_ )
+{}
+
+inline
+sc_ufix_fast::sc_ufix_fast( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om,
+ sc_fxnum_fast_observer* observer_ )
+: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_, qm, om ),
+ SC_US_,
+ sc_fxcast_switch(),
+ observer_ )
+{}
+
+inline
+sc_ufix_fast::sc_ufix_fast( int wl_, int iwl_,
+ sc_q_mode qm, sc_o_mode om, int nb,
+ sc_fxnum_fast_observer* observer_ )
+: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_, qm, om, nb ),
+ SC_US_,
+ sc_fxcast_switch(),
+ observer_ )
+{}
+
+inline
+sc_ufix_fast::sc_ufix_fast( const sc_fxcast_switch& cast_sw,
+ sc_fxnum_fast_observer* observer_ )
+: sc_fxnum_fast( sc_fxtype_params(),
+ SC_US_,
+ cast_sw,
+ observer_ )
+{}
+
+inline
+sc_ufix_fast::sc_ufix_fast( int wl_, int iwl_,
+ const sc_fxcast_switch& cast_sw,
+ sc_fxnum_fast_observer* observer_ )
+: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_ ),
+ SC_US_,
+ cast_sw,
+ observer_ )
+{}
+
+inline
+sc_ufix_fast::sc_ufix_fast( sc_q_mode qm, sc_o_mode om,
+ const sc_fxcast_switch& cast_sw,
+ sc_fxnum_fast_observer* observer_ )
+: sc_fxnum_fast( sc_fxtype_params( qm, om ),
+ SC_US_,
+ cast_sw,
+ observer_ )
+{}
+
+inline
+sc_ufix_fast::sc_ufix_fast( sc_q_mode qm, sc_o_mode om, int nb,
+ const sc_fxcast_switch& cast_sw,
+ sc_fxnum_fast_observer* observer_ )
+: sc_fxnum_fast( sc_fxtype_params( qm, om, nb ),
+ SC_US_,
+ cast_sw,
+ observer_ )
+{}
+
+inline
+sc_ufix_fast::sc_ufix_fast( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om,
+ const sc_fxcast_switch& cast_sw,
+ sc_fxnum_fast_observer* observer_ )
+: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_, qm, om ),
+ SC_US_,
+ cast_sw,
+ observer_ )
+{}
+
+inline
+sc_ufix_fast::sc_ufix_fast( int wl_, int iwl_,
+ sc_q_mode qm, sc_o_mode om, int nb,
+ const sc_fxcast_switch& cast_sw,
+ sc_fxnum_fast_observer* observer_ )
+: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_, qm, om, nb ),
+ SC_US_,
+ cast_sw,
+ observer_ )
+{}
+
+inline
+sc_ufix_fast::sc_ufix_fast( const sc_fxtype_params& type_params,
+ sc_fxnum_fast_observer* observer_ )
+: sc_fxnum_fast( type_params,
+ SC_US_,
+ sc_fxcast_switch(),
+ observer_ )
+{}
+
+inline
+sc_ufix_fast::sc_ufix_fast( const sc_fxtype_params& type_params,
+ const sc_fxcast_switch& cast_sw,
+ sc_fxnum_fast_observer* observer_ )
+: sc_fxnum_fast( type_params,
+ SC_US_,
+ cast_sw,
+ observer_ )
+{}
+
+#define DEFN_CTORS_T_A(tp) \
+inline \
+sc_ufix_fast::sc_ufix_fast( tp a, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params(), \
+ SC_US_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix_fast::sc_ufix_fast( tp a, \
+ int wl_, int iwl_, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( wl_, iwl_ ), \
+ SC_US_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix_fast::sc_ufix_fast( tp a, \
+ sc_q_mode qm, sc_o_mode om, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( qm, om ), \
+ SC_US_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix_fast::sc_ufix_fast( tp a, \
+ sc_q_mode qm, sc_o_mode om, int nb, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( qm, om, nb ), \
+ SC_US_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix_fast::sc_ufix_fast( tp a, \
+ int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om ), \
+ SC_US_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix_fast::sc_ufix_fast( tp a, \
+ int wl_, int iwl_, \
+ sc_q_mode qm, sc_o_mode om, int nb, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om, nb ), \
+ SC_US_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix_fast::sc_ufix_fast( tp a, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params(), \
+ SC_US_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix_fast::sc_ufix_fast( tp a, \
+ int wl_, int iwl_, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( wl_, iwl_ ), \
+ SC_US_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix_fast::sc_ufix_fast( tp a, \
+ sc_q_mode qm, sc_o_mode om, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( qm, om ), \
+ SC_US_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix_fast::sc_ufix_fast( tp a, \
+ sc_q_mode qm, sc_o_mode om, int nb, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( qm, om, nb ), \
+ SC_US_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix_fast::sc_ufix_fast( tp a, \
+ int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om ), \
+ SC_US_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix_fast::sc_ufix_fast( tp a, \
+ int wl_, int iwl_, \
+ sc_q_mode qm, sc_o_mode om, int nb, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om, nb ), \
+ SC_US_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix_fast::sc_ufix_fast( tp a, \
+ const sc_fxtype_params& type_params, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ type_params, \
+ SC_US_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix_fast::sc_ufix_fast( tp a, \
+ const sc_fxtype_params& type_params, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ type_params, \
+ SC_US_, \
+ cast_sw, \
+ observer_ ) \
+{}
+
+#define DEFN_CTORS_T_B(tp) \
+inline \
+sc_ufix_fast::sc_ufix_fast( tp a, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ a.type_params(), \
+ SC_US_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix_fast::sc_ufix_fast( tp a, \
+ int wl_, int iwl_, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( a.type_params(), wl_, iwl_ ), \
+ SC_US_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix_fast::sc_ufix_fast( tp a, \
+ sc_q_mode qm, sc_o_mode om, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( a.type_params(), qm, om ), \
+ SC_US_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix_fast::sc_ufix_fast( tp a, \
+ sc_q_mode qm, sc_o_mode om, int nb, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( a.type_params(), qm, om, nb ), \
+ SC_US_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix_fast::sc_ufix_fast( tp a, \
+ int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om ), \
+ SC_US_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix_fast::sc_ufix_fast( tp a, \
+ int wl_, int iwl_, \
+ sc_q_mode qm, sc_o_mode om, int nb, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om, nb ), \
+ SC_US_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix_fast::sc_ufix_fast( tp a, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ a.type_params(), \
+ SC_US_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix_fast::sc_ufix_fast( tp a, \
+ int wl_, int iwl_, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( a.type_params(), wl_, iwl_ ), \
+ SC_US_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix_fast::sc_ufix_fast( tp a, \
+ sc_q_mode qm, sc_o_mode om, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( a.type_params(), qm, om ), \
+ SC_US_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix_fast::sc_ufix_fast( tp a, \
+ sc_q_mode qm, sc_o_mode om, int nb, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( a.type_params(), qm, om, nb ), \
+ SC_US_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix_fast::sc_ufix_fast( tp a, \
+ int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om ), \
+ SC_US_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix_fast::sc_ufix_fast( tp a, \
+ int wl_, int iwl_, \
+ sc_q_mode qm, sc_o_mode om, int nb, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ sc_fxtype_params( wl_, iwl_, qm, om, nb ), \
+ SC_US_, \
+ cast_sw, \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix_fast::sc_ufix_fast( tp a, \
+ const sc_fxtype_params& type_params, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ type_params, \
+ SC_US_, \
+ sc_fxcast_switch(), \
+ observer_ ) \
+{} \
+ \
+inline \
+sc_ufix_fast::sc_ufix_fast( tp a, \
+ const sc_fxtype_params& type_params, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_fast_observer* observer_ ) \
+: sc_fxnum_fast( a, \
+ type_params, \
+ SC_US_, \
+ cast_sw, \
+ observer_ ) \
+{}
+
+DEFN_CTORS_T_A(int)
+DEFN_CTORS_T_A(unsigned int)
+DEFN_CTORS_T_A(long)
+DEFN_CTORS_T_A(unsigned long)
+DEFN_CTORS_T_A(float)
+DEFN_CTORS_T_A(double)
+DEFN_CTORS_T_A(const char*)
+DEFN_CTORS_T_A(const sc_fxval&)
+DEFN_CTORS_T_A(const sc_fxval_fast&)
+DEFN_CTORS_T_B(const sc_fxnum&)
+DEFN_CTORS_T_B(const sc_fxnum_fast&)
+#ifndef SC_FX_EXCLUDE_OTHER
+DEFN_CTORS_T_A(int64)
+DEFN_CTORS_T_A(uint64)
+DEFN_CTORS_T_A(const sc_int_base&)
+DEFN_CTORS_T_A(const sc_uint_base&)
+DEFN_CTORS_T_A(const sc_signed&)
+DEFN_CTORS_T_A(const sc_unsigned&)
+#endif
+
+#undef DEFN_CTORS_T_A
+#undef DEFN_CTORS_T_B
+
+// copy constructor
+
+inline
+sc_ufix_fast::sc_ufix_fast( const sc_ufix_fast& a )
+: sc_fxnum_fast( a,
+ a.type_params(),
+ SC_US_,
+ sc_fxcast_switch(),
+ 0 )
+{}
+
+
+// unary bitwise operators
+
+inline
+const sc_ufix_fast
+sc_ufix_fast::operator ~ () const
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( *this )
+ int iwl_c = iwl();
+ int wl_c = wl();
+ sc_ufix_fast c( wl_c, iwl_c );
+ for( int i = iwl_c - wl_c; i < iwl_c; ++ i )
+ c.set_bit( i, ! get_bit( i ) );
+ return sc_ufix_fast( c, wl_c, iwl_c );
+}
+
+
+// unary bitwise functions
+
+inline
+void
+b_not( sc_ufix_fast& c, const sc_ufix_fast& a )
+{
+ SC_FXNUM_FAST_OBSERVER_READ_( a )
+ int iwl_c = c.iwl();
+ for( int i = iwl_c - c.wl(); i < iwl_c; ++ i )
+ c.set_bit( i, ! a.get_bit( i ) );
+ c.cast();
+ SC_FXNUM_FAST_OBSERVER_WRITE_( c )
+}
+
+
+// binary bitwise operators
+
+#define DEFN_BIN_OP_T(op,op2,tp1,tp2) \
+inline \
+const sc_ufix_fast \
+operator op ( const tp1& a, const tp2& b ) \
+{ \
+ a.observer_read(); \
+ b.observer_read(); \
+ int iwl_a = a.iwl(); \
+ int iwl_b = b.iwl(); \
+ int iwl_c = sc_max( iwl_a, iwl_b ); \
+ int fwl_c = sc_max( a.wl() - iwl_a, b.wl() - iwl_b ); \
+ sc_ufix_fast c( iwl_c + fwl_c, iwl_c ); \
+ for( int i = -fwl_c; i < iwl_c; ++ i ) \
+ c.set_bit( i, a.get_bit( i ) op2 b.get_bit( i ) ); \
+ return sc_ufix_fast( c, iwl_c + fwl_c, iwl_c ); \
+}
+
+DEFN_BIN_OP_T(&,&&,sc_ufix_fast,sc_ufix_fast)
+DEFN_BIN_OP_T(|,||,sc_ufix_fast,sc_ufix_fast)
+DEFN_BIN_OP_T(^,!=,sc_ufix_fast,sc_ufix_fast)
+
+#undef DEFN_BIN_OP_T
+
+
+// binary bitwise functions
+
+#define DEFN_BIN_FNC_T(fnc,op2,tp1,tp2) \
+inline \
+void \
+fnc ( sc_ufix_fast& c, const tp1& a, const tp2& b ) \
+{ \
+ a.observer_read(); \
+ b.observer_read(); \
+ int iwl_c = c.iwl(); \
+ for( int i = iwl_c - c.wl(); i < iwl_c; ++ i ) \
+ c.set_bit( i, a.get_bit( i ) op2 b.get_bit( i ) ); \
+ c.cast(); \
+ SC_FXNUM_FAST_OBSERVER_WRITE_( c ) \
+}
+
+DEFN_BIN_FNC_T(b_and,&&,sc_ufix_fast,sc_ufix_fast)
+DEFN_BIN_FNC_T(b_or,||,sc_ufix_fast,sc_ufix_fast)
+DEFN_BIN_FNC_T(b_xor,!=,sc_ufix_fast,sc_ufix_fast)
+
+#undef DEFN_BIN_FNC_T
+
+
+// assignment operators
+
+inline
+sc_ufix_fast&
+sc_ufix_fast::operator = ( const sc_ufix_fast& a )
+{
+ sc_fxnum_fast::operator = ( a );
+ return *this;
+}
+
+#define DEFN_ASN_OP_T(op,tp) \
+inline \
+sc_ufix_fast& \
+sc_ufix_fast::operator op ( tp a ) \
+{ \
+ sc_fxnum_fast::operator op( a ); \
+ return *this; \
+}
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DEFN_ASN_OP_OTHER(op) \
+DEFN_ASN_OP_T(op,int64) \
+DEFN_ASN_OP_T(op,uint64) \
+DEFN_ASN_OP_T(op,const sc_int_base&) \
+DEFN_ASN_OP_T(op,const sc_uint_base&) \
+DEFN_ASN_OP_T(op,const sc_signed&) \
+DEFN_ASN_OP_T(op,const sc_unsigned&)
+#else
+#define DEFN_ASN_OP_OTHER(op)
+#endif
+
+#define DEFN_ASN_OP(op) \
+DEFN_ASN_OP_T(op,int) \
+DEFN_ASN_OP_T(op,unsigned int) \
+DEFN_ASN_OP_T(op,long) \
+DEFN_ASN_OP_T(op,unsigned long) \
+DEFN_ASN_OP_T(op,float) \
+DEFN_ASN_OP_T(op,double) \
+DEFN_ASN_OP_T(op,const char*) \
+DEFN_ASN_OP_T(op,const sc_fxval&) \
+DEFN_ASN_OP_T(op,const sc_fxval_fast&) \
+DEFN_ASN_OP_T(op,const sc_fxnum&) \
+DEFN_ASN_OP_T(op,const sc_fxnum_fast&) \
+DEFN_ASN_OP_OTHER(op)
+
+DEFN_ASN_OP(=)
+
+DEFN_ASN_OP(*=)
+DEFN_ASN_OP(/=)
+DEFN_ASN_OP(+=)
+DEFN_ASN_OP(-=)
+
+DEFN_ASN_OP_T(<<=,int)
+DEFN_ASN_OP_T(>>=,int)
+
+#undef DEFN_ASN_OP_T
+#undef DEFN_ASN_OP_OTHER
+#undef DEFN_ASN_OP
+
+
+#define DEFN_ASN_OP_T(op,op2,tp) \
+inline \
+sc_ufix_fast& \
+sc_ufix_fast::operator op ( const tp& b ) \
+{ \
+ SC_FXNUM_FAST_OBSERVER_READ_( *this ) \
+ b.observer_read(); \
+ int iwl_c = iwl(); \
+ for( int i = iwl_c - wl(); i < iwl_c; ++ i ) \
+ set_bit( i, get_bit( i ) op2 b.get_bit( i ) ); \
+ cast(); \
+ SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) \
+ return *this; \
+}
+
+DEFN_ASN_OP_T(&=,&&,sc_ufix)
+DEFN_ASN_OP_T(&=,&&,sc_ufix_fast)
+DEFN_ASN_OP_T(|=,||,sc_ufix)
+DEFN_ASN_OP_T(|=,||,sc_ufix_fast)
+DEFN_ASN_OP_T(^=,!=,sc_ufix)
+DEFN_ASN_OP_T(^=,!=,sc_ufix_fast)
+
+#undef DEFN_ASN_OP_T
+
+
+// auto-increment and auto-decrement
+
+inline
+const sc_fxval_fast
+sc_ufix_fast::operator ++ ( int )
+{
+ return sc_fxval_fast( sc_fxnum_fast::operator ++ ( 0 ) );
+}
+
+inline
+const sc_fxval_fast
+sc_ufix_fast::operator -- ( int )
+{
+ return sc_fxval_fast( sc_fxnum_fast::operator -- ( 0 ) );
+}
+
+inline
+sc_ufix_fast&
+sc_ufix_fast::operator ++ ()
+{
+ sc_fxnum_fast::operator ++ ();
+ return *this;
+}
+
+inline
+sc_ufix_fast&
+sc_ufix_fast::operator -- ()
+{
+ sc_fxnum_fast::operator -- ();
+ return *this;
+}
+
+} // namespace sc_dt
+
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_ufixed.h b/ext/systemc/src/sysc/datatypes/fx/sc_ufixed.h
new file mode 100644
index 000000000..266e4b7bb
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/sc_ufixed.h
@@ -0,0 +1,660 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_ufixed.h -
+
+ Original Author: Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_ufixed.h,v $
+// Revision 1.2 2011/01/19 18:57:40 acg
+// Andy Goodrich: changes for IEEE_1666_2011.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:58 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#ifndef SC_UFIXED_H
+#define SC_UFIXED_H
+
+
+#include "sysc/datatypes/fx/sc_ufix.h"
+
+
+namespace sc_dt
+{
+
+// classes defined in this module
+template <int W, int I, sc_q_mode Q, sc_o_mode O, int N> class sc_ufixed;
+template <int W, int I, sc_q_mode Q, sc_o_mode O, int N> class sc_ufixed_fast;
+
+
+// ----------------------------------------------------------------------------
+// TEMPLATE CLASS : sc_ufixed
+//
+// "Constrained" unsigned fixed-point class; arbitrary precision.
+// ----------------------------------------------------------------------------
+
+template <int W, int I,
+ sc_q_mode Q = SC_DEFAULT_Q_MODE_,
+ sc_o_mode O = SC_DEFAULT_O_MODE_, int N = SC_DEFAULT_N_BITS_>
+class sc_ufixed : public sc_ufix
+{
+
+public:
+
+ // constructors
+
+ explicit sc_ufixed( sc_fxnum_observer* = 0 );
+ explicit sc_ufixed( const sc_fxcast_switch&, sc_fxnum_observer* = 0 );
+
+#define DECL_CTORS_T_A(tp) \
+ sc_ufixed( tp, sc_fxnum_observer* = 0 ); \
+ sc_ufixed( tp, const sc_fxcast_switch&, sc_fxnum_observer* = 0 );
+
+#define DECL_CTORS_T_B(tp) \
+ explicit sc_ufixed( tp, sc_fxnum_observer* = 0 ); \
+ sc_ufixed( tp, const sc_fxcast_switch&, sc_fxnum_observer* = 0 );
+
+ DECL_CTORS_T_A(int)
+ DECL_CTORS_T_A(unsigned int)
+ DECL_CTORS_T_A(long)
+ DECL_CTORS_T_A(unsigned long)
+ DECL_CTORS_T_A(float)
+ DECL_CTORS_T_A(double)
+ DECL_CTORS_T_A(const char*)
+ DECL_CTORS_T_A(const sc_fxval&)
+ DECL_CTORS_T_A(const sc_fxval_fast&)
+ DECL_CTORS_T_A(const sc_fxnum&)
+ DECL_CTORS_T_A(const sc_fxnum_fast&)
+#ifndef SC_FX_EXCLUDE_OTHER
+ DECL_CTORS_T_B(int64)
+ DECL_CTORS_T_B(uint64)
+ DECL_CTORS_T_B(const sc_int_base&)
+ DECL_CTORS_T_B(const sc_uint_base&)
+ DECL_CTORS_T_B(const sc_signed&)
+ DECL_CTORS_T_B(const sc_unsigned&)
+#endif
+
+#undef DECL_CTORS_T_A
+#undef DECL_CTORS_T_B
+
+ // copy constructor
+
+ sc_ufixed( const sc_ufixed<W,I,Q,O,N>& );
+
+
+ // assignment operators
+
+ sc_ufixed& operator = ( const sc_ufixed<W,I,Q,O,N>& );
+
+#define DECL_ASN_OP_T(op,tp) \
+ sc_ufixed& operator op ( tp );
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DECL_ASN_OP_OTHER(op) \
+ DECL_ASN_OP_T(op,int64) \
+ DECL_ASN_OP_T(op,uint64) \
+ DECL_ASN_OP_T(op,const sc_int_base&) \
+ DECL_ASN_OP_T(op,const sc_uint_base&) \
+ DECL_ASN_OP_T(op,const sc_signed&) \
+ DECL_ASN_OP_T(op,const sc_unsigned&)
+#else
+#define DECL_ASN_OP_OTHER(op)
+#endif
+
+#define DECL_ASN_OP(op) \
+ DECL_ASN_OP_T(op,int) \
+ DECL_ASN_OP_T(op,unsigned int) \
+ DECL_ASN_OP_T(op,long) \
+ DECL_ASN_OP_T(op,unsigned long) \
+ DECL_ASN_OP_T(op,float) \
+ DECL_ASN_OP_T(op,double) \
+ DECL_ASN_OP_T(op,const char*) \
+ DECL_ASN_OP_T(op,const sc_fxval&) \
+ DECL_ASN_OP_T(op,const sc_fxval_fast&) \
+ DECL_ASN_OP_T(op,const sc_fxnum&) \
+ DECL_ASN_OP_T(op,const sc_fxnum_fast&) \
+ DECL_ASN_OP_OTHER(op)
+
+ DECL_ASN_OP(=)
+
+ DECL_ASN_OP(*=)
+ DECL_ASN_OP(/=)
+ DECL_ASN_OP(+=)
+ DECL_ASN_OP(-=)
+
+ DECL_ASN_OP_T(<<=,int)
+ DECL_ASN_OP_T(>>=,int)
+
+ DECL_ASN_OP_T(&=,const sc_ufix&)
+ DECL_ASN_OP_T(&=,const sc_ufix_fast&)
+ DECL_ASN_OP_T(|=,const sc_ufix&)
+ DECL_ASN_OP_T(|=,const sc_ufix_fast&)
+ DECL_ASN_OP_T(^=,const sc_ufix&)
+ DECL_ASN_OP_T(^=,const sc_ufix_fast&)
+
+#undef DECL_ASN_OP_T
+#undef DECL_ASN_OP_OTHER
+#undef DECL_ASN_OP
+
+
+ // auto-increment and auto-decrement
+
+ const sc_fxval operator ++ ( int );
+ const sc_fxval operator -- ( int );
+
+ sc_ufixed& operator ++ ();
+ sc_ufixed& operator -- ();
+
+};
+
+
+// ----------------------------------------------------------------------------
+// TEMPLATE CLASS : sc_ufixed_fast
+//
+// "Constrained" unsigned fixed-point class; limited precision.
+// ----------------------------------------------------------------------------
+
+template <int W, int I,
+ sc_q_mode Q = SC_DEFAULT_Q_MODE_,
+ sc_o_mode O = SC_DEFAULT_O_MODE_, int N = SC_DEFAULT_N_BITS_>
+class sc_ufixed_fast : public sc_ufix_fast
+{
+
+public:
+
+ // constructors
+
+ explicit sc_ufixed_fast( sc_fxnum_fast_observer* = 0 );
+ explicit sc_ufixed_fast( const sc_fxcast_switch&,
+ sc_fxnum_fast_observer* = 0 );
+
+#define DECL_CTORS_T_A(tp) \
+ sc_ufixed_fast( tp, sc_fxnum_fast_observer* = 0 ); \
+ sc_ufixed_fast( tp, const sc_fxcast_switch&, \
+ sc_fxnum_fast_observer* = 0 );
+
+#define DECL_CTORS_T_B(tp) \
+ explicit sc_ufixed_fast( tp, sc_fxnum_fast_observer* = 0 ); \
+ sc_ufixed_fast( tp, const sc_fxcast_switch&, \
+ sc_fxnum_fast_observer* = 0 );
+
+ DECL_CTORS_T_A(int)
+ DECL_CTORS_T_A(unsigned int)
+ DECL_CTORS_T_A(long)
+ DECL_CTORS_T_A(unsigned long)
+ DECL_CTORS_T_A(float)
+ DECL_CTORS_T_A(double)
+ DECL_CTORS_T_A(const char*)
+ DECL_CTORS_T_A(const sc_fxval&)
+ DECL_CTORS_T_A(const sc_fxval_fast&)
+ DECL_CTORS_T_A(const sc_fxnum&)
+ DECL_CTORS_T_A(const sc_fxnum_fast&)
+#ifndef SC_FX_EXCLUDE_OTHER
+ DECL_CTORS_T_B(int64)
+ DECL_CTORS_T_B(uint64)
+ DECL_CTORS_T_B(const sc_int_base&)
+ DECL_CTORS_T_B(const sc_uint_base&)
+ DECL_CTORS_T_B(const sc_signed&)
+ DECL_CTORS_T_B(const sc_unsigned&)
+#endif
+
+#undef DECL_CTORS_T_A
+#undef DECL_CTORS_T_B
+
+ // copy constructor
+
+ sc_ufixed_fast( const sc_ufixed_fast<W,I,Q,O,N>& );
+
+
+ // assignment operators
+
+ sc_ufixed_fast& operator = ( const sc_ufixed_fast<W,I,Q,O,N>& );
+
+#define DECL_ASN_OP_T(op,tp) \
+ sc_ufixed_fast& operator op ( tp );
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DECL_ASN_OP_OTHER(op) \
+ DECL_ASN_OP_T(op,int64) \
+ DECL_ASN_OP_T(op,uint64) \
+ DECL_ASN_OP_T(op,const sc_int_base&) \
+ DECL_ASN_OP_T(op,const sc_uint_base&) \
+ DECL_ASN_OP_T(op,const sc_signed&) \
+ DECL_ASN_OP_T(op,const sc_unsigned&)
+#else
+#define DECL_ASN_OP_OTHER(op)
+#endif
+
+#define DECL_ASN_OP(op) \
+ DECL_ASN_OP_T(op,int) \
+ DECL_ASN_OP_T(op,unsigned int) \
+ DECL_ASN_OP_T(op,long) \
+ DECL_ASN_OP_T(op,unsigned long) \
+ DECL_ASN_OP_T(op,float) \
+ DECL_ASN_OP_T(op,double) \
+ DECL_ASN_OP_T(op,const char*) \
+ DECL_ASN_OP_T(op,const sc_fxval&) \
+ DECL_ASN_OP_T(op,const sc_fxval_fast&) \
+ DECL_ASN_OP_T(op,const sc_fxnum&) \
+ DECL_ASN_OP_T(op,const sc_fxnum_fast&) \
+ DECL_ASN_OP_OTHER(op)
+
+ DECL_ASN_OP(=)
+
+ DECL_ASN_OP(*=)
+ DECL_ASN_OP(/=)
+ DECL_ASN_OP(+=)
+ DECL_ASN_OP(-=)
+
+ DECL_ASN_OP_T(<<=,int)
+ DECL_ASN_OP_T(>>=,int)
+
+ DECL_ASN_OP_T(&=,const sc_ufix&)
+ DECL_ASN_OP_T(&=,const sc_ufix_fast&)
+ DECL_ASN_OP_T(|=,const sc_ufix&)
+ DECL_ASN_OP_T(|=,const sc_ufix_fast&)
+ DECL_ASN_OP_T(^=,const sc_ufix&)
+ DECL_ASN_OP_T(^=,const sc_ufix_fast&)
+
+#undef DECL_ASN_OP_T
+#undef DECL_ASN_OP_OTHER
+#undef DECL_ASN_OP
+
+
+ // auto-increment and auto-decrement
+
+ const sc_fxval_fast operator ++ ( int );
+ const sc_fxval_fast operator -- ( int );
+
+ sc_ufixed_fast& operator ++ ();
+ sc_ufixed_fast& operator -- ();
+
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+// ----------------------------------------------------------------------------
+// TEMPLATE CLASS : sc_ufixed
+//
+// "Constrained" unsigned fixed-point class; arbitrary precision.
+// ----------------------------------------------------------------------------
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+sc_ufixed<W,I,Q,O,N>::sc_ufixed( sc_fxnum_observer* observer_ )
+: sc_ufix( W, I, Q, O, N, observer_ )
+{}
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+sc_ufixed<W,I,Q,O,N>::sc_ufixed( const sc_fxcast_switch& cast_sw,
+ sc_fxnum_observer* observer_ )
+: sc_ufix( W, I, Q, O, N, cast_sw, observer_ )
+{}
+
+#define DEFN_CTORS_T(tp) \
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \
+inline \
+sc_ufixed<W,I,Q,O,N>::sc_ufixed( tp a, \
+ sc_fxnum_observer* observer_ ) \
+: sc_ufix( a, W, I, Q, O, N, observer_ ) \
+{} \
+ \
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \
+inline \
+sc_ufixed<W,I,Q,O,N>::sc_ufixed( tp a, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_observer* observer_ ) \
+: sc_ufix( a, W, I, Q, O, N, cast_sw, observer_ ) \
+{}
+
+DEFN_CTORS_T(int)
+DEFN_CTORS_T(unsigned int)
+DEFN_CTORS_T(long)
+DEFN_CTORS_T(unsigned long)
+DEFN_CTORS_T(float)
+DEFN_CTORS_T(double)
+DEFN_CTORS_T(const char*)
+DEFN_CTORS_T(const sc_fxval&)
+DEFN_CTORS_T(const sc_fxval_fast&)
+DEFN_CTORS_T(const sc_fxnum&)
+DEFN_CTORS_T(const sc_fxnum_fast&)
+#ifndef SC_FX_EXCLUDE_OTHER
+DEFN_CTORS_T(int64)
+DEFN_CTORS_T(uint64)
+DEFN_CTORS_T(const sc_int_base&)
+DEFN_CTORS_T(const sc_uint_base&)
+DEFN_CTORS_T(const sc_signed&)
+DEFN_CTORS_T(const sc_unsigned&)
+#endif
+
+#undef DEFN_CTORS_T
+
+// copy constructor
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+sc_ufixed<W,I,Q,O,N>::sc_ufixed( const sc_ufixed<W,I,Q,O,N>& a )
+: sc_ufix( a, W, I, Q, O, N )
+{}
+
+
+// assignment operators
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+sc_ufixed<W,I,Q,O,N>&
+sc_ufixed<W,I,Q,O,N>::operator = ( const sc_ufixed<W,I,Q,O,N>& a )
+{
+ sc_ufix::operator = ( a );
+ return *this;
+}
+
+#define DEFN_ASN_OP_T(op,tp) \
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \
+inline \
+sc_ufixed<W,I,Q,O,N>& \
+sc_ufixed<W,I,Q,O,N>::operator op ( tp a ) \
+{ \
+ sc_ufix::operator op ( a ); \
+ return *this; \
+}
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DEFN_ASN_OP_OTHER(op) \
+DEFN_ASN_OP_T(op,int64) \
+DEFN_ASN_OP_T(op,uint64) \
+DEFN_ASN_OP_T(op,const sc_int_base&) \
+DEFN_ASN_OP_T(op,const sc_uint_base&) \
+DEFN_ASN_OP_T(op,const sc_signed&) \
+DEFN_ASN_OP_T(op,const sc_unsigned&)
+#else
+#define DEFN_ASN_OP_OTHER(op)
+#endif
+
+#define DEFN_ASN_OP(op) \
+DEFN_ASN_OP_T(op,int) \
+DEFN_ASN_OP_T(op,unsigned int) \
+DEFN_ASN_OP_T(op,long) \
+DEFN_ASN_OP_T(op,unsigned long) \
+DEFN_ASN_OP_T(op,float) \
+DEFN_ASN_OP_T(op,double) \
+DEFN_ASN_OP_T(op,const char*) \
+DEFN_ASN_OP_T(op,const sc_fxval&) \
+DEFN_ASN_OP_T(op,const sc_fxval_fast&) \
+DEFN_ASN_OP_T(op,const sc_fxnum&) \
+DEFN_ASN_OP_T(op,const sc_fxnum_fast&) \
+DEFN_ASN_OP_OTHER(op)
+
+DEFN_ASN_OP(=)
+
+DEFN_ASN_OP(*=)
+DEFN_ASN_OP(/=)
+DEFN_ASN_OP(+=)
+DEFN_ASN_OP(-=)
+
+DEFN_ASN_OP_T(<<=,int)
+DEFN_ASN_OP_T(>>=,int)
+
+DEFN_ASN_OP_T(&=,const sc_ufix&)
+DEFN_ASN_OP_T(&=,const sc_ufix_fast&)
+DEFN_ASN_OP_T(|=,const sc_ufix&)
+DEFN_ASN_OP_T(|=,const sc_ufix_fast&)
+DEFN_ASN_OP_T(^=,const sc_ufix&)
+DEFN_ASN_OP_T(^=,const sc_ufix_fast&)
+
+#undef DEFN_ASN_OP_T
+#undef DEFN_ASN_OP_OTHER
+#undef DEFN_ASN_OP
+
+
+// auto-increment and auto-decrement
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+const sc_fxval
+sc_ufixed<W,I,Q,O,N>::operator ++ ( int )
+{
+ return sc_fxval( sc_ufix::operator ++ ( 0 ) );
+}
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+const sc_fxval
+sc_ufixed<W,I,Q,O,N>::operator -- ( int )
+{
+ return sc_fxval( sc_ufix::operator -- ( 0 ) );
+}
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+sc_ufixed<W,I,Q,O,N>&
+sc_ufixed<W,I,Q,O,N>::operator ++ ()
+{
+ sc_ufix::operator ++ ();
+ return *this;
+}
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+sc_ufixed<W,I,Q,O,N>&
+sc_ufixed<W,I,Q,O,N>::operator -- ()
+{
+ sc_ufix::operator -- ();
+ return *this;
+}
+
+
+// ----------------------------------------------------------------------------
+// TEMPLATE CLASS : sc_ufixed_fast
+//
+// "Constrained" unsigned fixed-point class; limited precision.
+// ----------------------------------------------------------------------------
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+sc_ufixed_fast<W,I,Q,O,N>::sc_ufixed_fast( sc_fxnum_fast_observer* observer_ )
+: sc_ufix_fast( W, I, Q, O, N, observer_ )
+{}
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+sc_ufixed_fast<W,I,Q,O,N>::sc_ufixed_fast( const sc_fxcast_switch& cast_sw,
+ sc_fxnum_fast_observer* observer_ )
+: sc_ufix_fast( W, I, Q, O, N, cast_sw, observer_ )
+{}
+
+#define DEFN_CTORS_T(tp) \
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \
+inline \
+sc_ufixed_fast<W,I,Q,O,N>::sc_ufixed_fast( tp a, \
+ sc_fxnum_fast_observer* observer_ )\
+: sc_ufix_fast( a, W, I, Q, O, N, observer_ ) \
+{} \
+ \
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \
+inline \
+sc_ufixed_fast<W,I,Q,O,N>::sc_ufixed_fast( tp a, \
+ const sc_fxcast_switch& cast_sw, \
+ sc_fxnum_fast_observer* observer_ )\
+: sc_ufix_fast( a, W, I, Q, O, N, cast_sw, observer_ ) \
+{}
+
+DEFN_CTORS_T(int)
+DEFN_CTORS_T(unsigned int)
+DEFN_CTORS_T(long)
+DEFN_CTORS_T(unsigned long)
+DEFN_CTORS_T(float)
+DEFN_CTORS_T(double)
+DEFN_CTORS_T(const char*)
+DEFN_CTORS_T(const sc_fxval&)
+DEFN_CTORS_T(const sc_fxval_fast&)
+DEFN_CTORS_T(const sc_fxnum&)
+DEFN_CTORS_T(const sc_fxnum_fast&)
+#ifndef SC_FX_EXCLUDE_OTHER
+DEFN_CTORS_T(int64)
+DEFN_CTORS_T(uint64)
+DEFN_CTORS_T(const sc_int_base&)
+DEFN_CTORS_T(const sc_uint_base&)
+DEFN_CTORS_T(const sc_signed&)
+DEFN_CTORS_T(const sc_unsigned&)
+#endif
+
+#undef DEFN_CTORS_T
+
+// copy constructor
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+sc_ufixed_fast<W,I,Q,O,N>::sc_ufixed_fast( const sc_ufixed_fast<W,I,Q,O,N>& a )
+: sc_ufix_fast( a, W, I, Q, O, N )
+{}
+
+
+// assignment operators
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+sc_ufixed_fast<W,I,Q,O,N>&
+sc_ufixed_fast<W,I,Q,O,N>::operator = ( const sc_ufixed_fast<W,I,Q,O,N>& a )
+{
+ sc_ufix_fast::operator = ( a );
+ return *this;
+}
+
+#define DEFN_ASN_OP_T(op,tp) \
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \
+inline \
+sc_ufixed_fast<W,I,Q,O,N>& \
+sc_ufixed_fast<W,I,Q,O,N>::operator op ( tp a ) \
+{ \
+ sc_ufix_fast::operator op ( a ); \
+ return *this; \
+}
+
+#ifndef SC_FX_EXCLUDE_OTHER
+#define DEFN_ASN_OP_OTHER(op) \
+DEFN_ASN_OP_T(op,int64) \
+DEFN_ASN_OP_T(op,uint64) \
+DEFN_ASN_OP_T(op,const sc_int_base&) \
+DEFN_ASN_OP_T(op,const sc_uint_base&) \
+DEFN_ASN_OP_T(op,const sc_signed&) \
+DEFN_ASN_OP_T(op,const sc_unsigned&)
+#else
+#define DEFN_ASN_OP_OTHER(op)
+#endif
+
+#define DEFN_ASN_OP(op) \
+DEFN_ASN_OP_T(op,int) \
+DEFN_ASN_OP_T(op,unsigned int) \
+DEFN_ASN_OP_T(op,long) \
+DEFN_ASN_OP_T(op,unsigned long) \
+DEFN_ASN_OP_T(op,float) \
+DEFN_ASN_OP_T(op,double) \
+DEFN_ASN_OP_T(op,const char*) \
+DEFN_ASN_OP_T(op,const sc_fxval&) \
+DEFN_ASN_OP_T(op,const sc_fxval_fast&) \
+DEFN_ASN_OP_T(op,const sc_fxnum&) \
+DEFN_ASN_OP_T(op,const sc_fxnum_fast&) \
+DEFN_ASN_OP_OTHER(op)
+
+DEFN_ASN_OP(=)
+
+DEFN_ASN_OP(*=)
+DEFN_ASN_OP(/=)
+DEFN_ASN_OP(+=)
+DEFN_ASN_OP(-=)
+
+DEFN_ASN_OP_T(<<=,int)
+DEFN_ASN_OP_T(>>=,int)
+
+DEFN_ASN_OP_T(&=,const sc_ufix&)
+DEFN_ASN_OP_T(&=,const sc_ufix_fast&)
+DEFN_ASN_OP_T(|=,const sc_ufix&)
+DEFN_ASN_OP_T(|=,const sc_ufix_fast&)
+DEFN_ASN_OP_T(^=,const sc_ufix&)
+DEFN_ASN_OP_T(^=,const sc_ufix_fast&)
+
+#undef DEFN_ASN_OP_T
+#undef DEFN_ASN_OP_OTHER
+#undef DEFN_ASN_OP
+
+
+// auto-increment and auto-decrement
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+const sc_fxval_fast
+sc_ufixed_fast<W,I,Q,O,N>::operator ++ ( int )
+{
+ return sc_fxval_fast( sc_ufix_fast::operator ++ ( 0 ) );
+}
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+const sc_fxval_fast
+sc_ufixed_fast<W,I,Q,O,N>::operator -- ( int )
+{
+ return sc_fxval_fast( sc_ufix_fast::operator -- ( 0 ) );
+}
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+sc_ufixed_fast<W,I,Q,O,N>&
+sc_ufixed_fast<W,I,Q,O,N>::operator ++ ()
+{
+ sc_ufix_fast::operator ++ ();
+ return *this;
+}
+
+template<int W, int I, sc_q_mode Q, sc_o_mode O, int N>
+inline
+sc_ufixed_fast<W,I,Q,O,N>&
+sc_ufixed_fast<W,I,Q,O,N>::operator -- ()
+{
+ sc_ufix_fast::operator -- ();
+ return *this;
+}
+
+} // namespace sc_dt
+
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_ieee.h b/ext/systemc/src/sysc/datatypes/fx/scfx_ieee.h
new file mode 100644
index 000000000..b2da95432
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/scfx_ieee.h
@@ -0,0 +1,701 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ scfx_ieee.h -
+
+ Original Author: Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: scfx_ieee.h,v $
+// Revision 1.3 2011/08/24 22:05:43 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.2 2011/08/07 18:55:24 acg
+// Philipp A. Hartmann: added guard for __clang__ to get the clang platform
+// working.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:58 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#ifndef SCFX_IEEE_H
+#define SCFX_IEEE_H
+
+
+#include "sysc/datatypes/fx/sc_fxdefs.h"
+
+
+namespace sc_dt
+{
+
+// classes defined in this module
+union ieee_double;
+class scfx_ieee_double;
+union ieee_float;
+class scfx_ieee_float;
+
+#define SCFX_MASK_(Size) \
+ ((1u << (Size))-1u)
+
+// ----------------------------------------------------------------------------
+// UNION : ieee_double
+//
+// IEEE 754 double-precision format.
+// ----------------------------------------------------------------------------
+
+union ieee_double
+{
+
+ double d;
+
+ struct
+ {
+#if defined( SC_BIG_ENDIAN )
+ unsigned negative:1;
+ unsigned exponent:11;
+ unsigned mantissa0:20;
+ unsigned mantissa1:32;
+#elif defined( SC_LITTLE_ENDIAN )
+ unsigned mantissa1:32;
+ unsigned mantissa0:20;
+ unsigned exponent:11;
+ unsigned negative:1;
+#endif
+ } s;
+
+};
+
+
+const unsigned int SCFX_IEEE_DOUBLE_BIAS = 1023U;
+
+const int SCFX_IEEE_DOUBLE_E_MAX = 1023;
+const int SCFX_IEEE_DOUBLE_E_MIN = -1022;
+
+const unsigned int SCFX_IEEE_DOUBLE_M_SIZE = 52;
+const unsigned int SCFX_IEEE_DOUBLE_M0_SIZE = 20;
+const unsigned int SCFX_IEEE_DOUBLE_M1_SIZE = 32;
+const unsigned int SCFX_IEEE_DOUBLE_E_SIZE = 11;
+
+
+
+// ----------------------------------------------------------------------------
+// CLASS : scfx_ieee_double
+//
+// Convenient interface to union ieee_double.
+// ----------------------------------------------------------------------------
+
+class scfx_ieee_double
+{
+
+ ieee_double m_id;
+
+public:
+
+ scfx_ieee_double();
+ scfx_ieee_double( double );
+ scfx_ieee_double( const scfx_ieee_double& );
+
+ scfx_ieee_double& operator = ( double );
+ scfx_ieee_double& operator = ( const scfx_ieee_double& );
+
+ operator double() const;
+
+ unsigned int negative() const;
+ void negative( unsigned int );
+ int exponent() const;
+ void exponent( int );
+ unsigned int mantissa0() const;
+ void mantissa0( unsigned int );
+ unsigned int mantissa1() const;
+ void mantissa1( unsigned int );
+
+ bool is_zero() const;
+ bool is_subnormal() const;
+ bool is_normal() const;
+ bool is_inf() const;
+ bool is_nan() const;
+
+ void set_inf();
+ void set_nan();
+
+ int msb() const; // most significant non-zero bit
+ int lsb() const; // least significant non-zero bit
+
+ static const scfx_ieee_double nan();
+ static const scfx_ieee_double inf( int );
+
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+inline
+scfx_ieee_double::scfx_ieee_double() : m_id()
+{
+ m_id.d = 0.0;
+}
+
+inline
+scfx_ieee_double::scfx_ieee_double( double d ) : m_id()
+{
+ m_id.d = d;
+}
+
+inline
+scfx_ieee_double::scfx_ieee_double( const scfx_ieee_double& a ) : m_id(a.m_id)
+{
+ // m_id.d = a.m_id.d;
+}
+
+
+inline
+scfx_ieee_double&
+scfx_ieee_double::operator = ( double d )
+{
+ m_id.d = d;
+ return *this;
+}
+
+inline
+scfx_ieee_double&
+scfx_ieee_double::operator = ( const scfx_ieee_double& a )
+{
+ m_id.d = a.m_id.d;
+ return *this;
+}
+
+
+inline
+scfx_ieee_double::operator double() const
+{
+ return m_id.d;
+}
+
+
+inline
+unsigned int
+scfx_ieee_double::negative() const
+{
+ return m_id.s.negative;
+}
+
+inline
+void
+scfx_ieee_double::negative( unsigned int a )
+{
+ m_id.s.negative = a & SCFX_MASK_(1);
+}
+
+inline
+int
+scfx_ieee_double::exponent() const
+{
+ return m_id.s.exponent - SCFX_IEEE_DOUBLE_BIAS;
+}
+
+inline
+void
+scfx_ieee_double::exponent( int a )
+{
+ m_id.s.exponent = (SCFX_IEEE_DOUBLE_BIAS + a)
+ & SCFX_MASK_(SCFX_IEEE_DOUBLE_E_SIZE);
+}
+
+inline
+unsigned int
+scfx_ieee_double::mantissa0() const
+{
+ return m_id.s.mantissa0;
+}
+
+inline
+void
+scfx_ieee_double::mantissa0( unsigned int a )
+{
+ m_id.s.mantissa0 = a & SCFX_MASK_(SCFX_IEEE_DOUBLE_M0_SIZE);
+}
+
+inline
+unsigned int
+scfx_ieee_double::mantissa1() const
+{
+ return m_id.s.mantissa1;
+}
+
+inline
+void
+scfx_ieee_double::mantissa1( unsigned int a )
+{
+ m_id.s.mantissa1 = a; // & SCFX_MASK_(SCFX_IEEE_DOUBLE_M1_SIZE);
+}
+
+
+inline
+bool
+scfx_ieee_double::is_zero() const
+{
+ return ( exponent() == SCFX_IEEE_DOUBLE_E_MIN - 1 &&
+ mantissa0() == 0U && mantissa1() == 0U );
+}
+
+inline
+bool
+scfx_ieee_double::is_subnormal() const
+{
+ return ( exponent() == SCFX_IEEE_DOUBLE_E_MIN - 1 &&
+ ( mantissa0() != 0U || mantissa1() != 0U ) );
+}
+
+inline
+bool
+scfx_ieee_double::is_normal() const
+{
+ return ( exponent() >= SCFX_IEEE_DOUBLE_E_MIN &&
+ exponent() <= SCFX_IEEE_DOUBLE_E_MAX );
+}
+
+inline
+bool
+scfx_ieee_double::is_inf() const
+{
+ return ( exponent() == SCFX_IEEE_DOUBLE_E_MAX + 1 &&
+ mantissa0() == 0U && mantissa1() == 0U );
+}
+
+inline
+bool
+scfx_ieee_double::is_nan() const
+{
+ return ( exponent() == SCFX_IEEE_DOUBLE_E_MAX + 1 &&
+ ( mantissa0() != 0U || mantissa1() != 0U ) );
+}
+
+
+inline
+void
+scfx_ieee_double::set_inf()
+{
+ exponent( SCFX_IEEE_DOUBLE_E_MAX + 1 );
+ mantissa0( 0U );
+ mantissa1( 0U );
+}
+
+inline
+void
+scfx_ieee_double::set_nan()
+{
+ exponent( SCFX_IEEE_DOUBLE_E_MAX + 1 );
+ mantissa0( (unsigned int) -1 );
+ mantissa1( (unsigned int) -1 );
+}
+
+
+#define MSB_STATEMENT(x,n) if( x >> n ) { x >>= n; i += n; }
+
+inline
+int
+scfx_ieee_double::msb() const
+{
+ unsigned int m0 = mantissa0();
+ unsigned int m1 = mantissa1();
+ if( m0 != 0 )
+ {
+ int i = 0;
+ MSB_STATEMENT(m0,16);
+ MSB_STATEMENT(m0,8);
+ MSB_STATEMENT(m0,4);
+ MSB_STATEMENT(m0,2);
+ MSB_STATEMENT(m0,1);
+ return ( i - 20 );
+ }
+ else if( m1 != 0 )
+ {
+ int i = 0;
+ MSB_STATEMENT(m1,16);
+ MSB_STATEMENT(m1,8);
+ MSB_STATEMENT(m1,4);
+ MSB_STATEMENT(m1,2);
+ MSB_STATEMENT(m1,1);
+ return ( i - 52 );
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+#undef MSB_STATEMENT
+
+#define LSB_STATEMENT(x,n) if( x << n ) { x <<= n; i -= n; }
+
+inline
+int
+scfx_ieee_double::lsb() const
+{
+ unsigned int m0 = mantissa0();
+ unsigned int m1 = mantissa1();
+ if( m1 != 0 )
+ {
+ int i = 31;
+ LSB_STATEMENT(m1,16);
+ LSB_STATEMENT(m1,8);
+ LSB_STATEMENT(m1,4);
+ LSB_STATEMENT(m1,2);
+ LSB_STATEMENT(m1,1);
+ return ( i - 52 );
+ }
+ else if( m0 != 0 )
+ {
+ int i = 31;
+ LSB_STATEMENT(m0,16);
+ LSB_STATEMENT(m0,8);
+ LSB_STATEMENT(m0,4);
+ LSB_STATEMENT(m0,2);
+ LSB_STATEMENT(m0,1);
+ return ( i - 20 );
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+#undef LSB_STATEMENT
+
+
+inline
+const scfx_ieee_double
+scfx_ieee_double::nan()
+{
+ scfx_ieee_double id;
+ id.set_nan();
+ return id;
+}
+
+inline
+const scfx_ieee_double
+scfx_ieee_double::inf( int sign )
+{
+ scfx_ieee_double id( sign );
+ id.set_inf();
+ return id;
+}
+
+
+// ----------------------------------------------------------------------------
+// UNION : ieee_float
+//
+// IEEE 754 single-precision format.
+// ----------------------------------------------------------------------------
+
+union ieee_float
+{
+
+ float f;
+
+ struct
+ {
+#if defined( SC_BIG_ENDIAN )
+ unsigned negative:1;
+ unsigned exponent:8;
+ unsigned mantissa:23;
+#elif defined( SC_LITTLE_ENDIAN )
+ unsigned mantissa:23;
+ unsigned exponent:8;
+ unsigned negative:1;
+#endif
+ } s;
+
+};
+
+
+const unsigned int SCFX_IEEE_FLOAT_BIAS = 127U;
+
+const int SCFX_IEEE_FLOAT_E_MAX = 127;
+const int SCFX_IEEE_FLOAT_E_MIN = -126;
+
+const unsigned int SCFX_IEEE_FLOAT_M_SIZE = 23;
+const unsigned int SCFX_IEEE_FLOAT_E_SIZE = 8;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : scfx_ieee_float
+//
+// Convenient wrapper to union ieee_float.
+// ----------------------------------------------------------------------------
+
+class scfx_ieee_float
+{
+
+ ieee_float m_if;
+
+public:
+
+ scfx_ieee_float();
+ scfx_ieee_float( float );
+ scfx_ieee_float( const scfx_ieee_float& );
+
+ scfx_ieee_float& operator = ( float );
+ scfx_ieee_float& operator = ( const scfx_ieee_float& );
+
+ operator float() const;
+
+ unsigned int negative() const;
+ void negative( unsigned int );
+ int exponent() const;
+ void exponent( int );
+ unsigned int mantissa() const;
+ void mantissa( unsigned int );
+
+ bool is_zero() const;
+ bool is_subnormal() const;
+ bool is_normal() const;
+ bool is_inf() const;
+ bool is_nan() const;
+
+ void set_inf();
+ void set_nan();
+
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+inline
+scfx_ieee_float::scfx_ieee_float() : m_if()
+{
+ m_if.f = 0.0;
+}
+
+inline
+scfx_ieee_float::scfx_ieee_float( float f ) : m_if()
+{
+ m_if.f = f;
+}
+
+inline
+scfx_ieee_float::scfx_ieee_float( const scfx_ieee_float& a ) : m_if(a.m_if)
+{
+ // m_if.f = a.m_if.f;
+}
+
+
+inline
+scfx_ieee_float&
+scfx_ieee_float::operator = ( float f )
+{
+ m_if.f = f;
+ return *this;
+}
+
+inline
+scfx_ieee_float&
+scfx_ieee_float::operator = ( const scfx_ieee_float& a )
+{
+ m_if.f = a.m_if.f;
+ return *this;
+}
+
+
+inline
+scfx_ieee_float::operator float() const
+{
+ return m_if.f;
+}
+
+
+inline
+unsigned int
+scfx_ieee_float::negative() const
+{
+ return m_if.s.negative;
+}
+
+inline
+void
+scfx_ieee_float::negative( unsigned int a )
+{
+ m_if.s.negative = a & SCFX_MASK_(1);
+}
+
+inline
+int
+scfx_ieee_float::exponent() const
+{
+ return m_if.s.exponent - SCFX_IEEE_FLOAT_BIAS;
+}
+
+inline
+void
+scfx_ieee_float::exponent( int a )
+{
+ m_if.s.exponent = (SCFX_IEEE_FLOAT_BIAS + a)
+ & SCFX_MASK_(SCFX_IEEE_FLOAT_E_SIZE);
+}
+
+inline
+unsigned int
+scfx_ieee_float::mantissa() const
+{
+ return m_if.s.mantissa;
+}
+
+inline
+void
+scfx_ieee_float::mantissa( unsigned int a )
+{
+ m_if.s.mantissa = a & SCFX_MASK_(SCFX_IEEE_FLOAT_M_SIZE);
+}
+
+
+inline
+bool
+scfx_ieee_float::is_zero() const
+{
+ return ( exponent() == SCFX_IEEE_FLOAT_E_MIN - 1 && mantissa() == 0U );
+}
+
+inline
+bool
+scfx_ieee_float::is_subnormal() const
+{
+ return ( exponent() == SCFX_IEEE_FLOAT_E_MIN - 1 && mantissa() != 0U );
+}
+
+inline
+bool
+scfx_ieee_float::is_normal() const
+{
+ return ( exponent() >= SCFX_IEEE_FLOAT_E_MIN &&
+ exponent() <= SCFX_IEEE_FLOAT_E_MAX );
+}
+
+inline
+bool
+scfx_ieee_float::is_inf() const
+{
+ return ( exponent() == SCFX_IEEE_FLOAT_E_MAX + 1 && mantissa() == 0U );
+}
+
+inline
+bool
+scfx_ieee_float::is_nan() const
+{
+ return ( exponent() == SCFX_IEEE_FLOAT_E_MAX + 1 && mantissa() != 0U );
+}
+
+
+inline
+void
+scfx_ieee_float::set_inf()
+{
+ exponent( SCFX_IEEE_FLOAT_E_MAX + 1 );
+ mantissa( 0U );
+}
+
+inline
+void
+scfx_ieee_float::set_nan()
+{
+ exponent( SCFX_IEEE_FLOAT_E_MAX + 1 );
+ mantissa( (unsigned int) -1 );
+}
+
+
+// ----------------------------------------------------------------------------
+// FUNCTION : scfx_pow2
+//
+// Computes 2.0**exp in double-precision.
+// ----------------------------------------------------------------------------
+
+inline
+double scfx_pow2( int exp )
+{
+ scfx_ieee_double r;
+ if( exp < SCFX_IEEE_DOUBLE_E_MIN )
+ {
+ r = 0.0;
+ // handle subnormal case
+ exp -= SCFX_IEEE_DOUBLE_E_MIN;
+ if( ( exp += 20 ) >= 0 )
+ {
+ r.mantissa0( 1U << exp );
+ }
+ else if( ( exp += 32 ) >= 0 )
+ {
+ r.mantissa1( 1U << exp );
+ }
+ }
+ else if( exp > SCFX_IEEE_DOUBLE_E_MAX )
+ {
+ r.set_inf();
+ }
+ else
+ {
+ r = 1.0;
+ r.exponent( exp );
+ }
+ return r;
+}
+
+
+// ----------------------------------------------------------------------------
+// FUNCTION : uint64_to_double
+//
+// Platform independent conversion from double uint64 to double.
+// Needed because VC++6 doesn't support this conversion.
+// ----------------------------------------------------------------------------
+
+inline
+double
+uint64_to_double( uint64 a )
+{
+#if defined( _MSC_VER ) || defined( __clang__ )
+ // conversion from uint64 to double not implemented; use int64
+ double tmp = static_cast<double>( static_cast<int64>( a ) );
+ return ( tmp >= 0 ) ? tmp : tmp + sc_dt::scfx_pow2( 64 );
+#else
+ return static_cast<double>( a );
+#endif
+}
+
+} // namespace sc_dt
+
+#undef SCFX_MASK_
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_mant.cpp b/ext/systemc/src/sysc/datatypes/fx/scfx_mant.cpp
new file mode 100644
index 000000000..fc29764f6
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/scfx_mant.cpp
@@ -0,0 +1,125 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ scfx_mant.cpp -
+
+ Original Author: Robert Graulich, Synopsys, Inc.
+ Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// $Log: scfx_mant.cpp,v $
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:58 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#include "sysc/datatypes/fx/scfx_mant.h"
+
+
+namespace sc_dt
+{
+
+// ----------------------------------------------------------------------------
+// word memory management
+// ----------------------------------------------------------------------------
+
+class word_list { // Entry in free_words bucket.
+ public:
+ word_list* m_next_p;
+};
+
+static inline
+int
+next_pow2_index( std::size_t size )
+{
+ int index = scfx_find_msb( size );
+ // If this was a power of 2 we are one bucket too low.
+ if( ~ (1 << index) & size ) index ++;
+ // If this is a 64-bit machine and we are using 32-bit words go down
+ // one slot size, as all the slots are 2x in size.
+ if ( index != 0 && ( sizeof(word_list) != sizeof(word) ) )
+ {
+ index -= 1;
+ }
+ return index;
+}
+
+static word_list* free_words[32] = { 0 };
+
+word*
+scfx_mant::alloc_word( std::size_t size )
+{
+ const int ALLOC_SIZE = 128;
+
+ int slot_index = next_pow2_index( size );
+
+ int alloc_size = ( 1 << slot_index );
+
+ word_list*& slot = free_words[slot_index];
+
+ if( ! slot )
+ {
+ slot = new word_list[ALLOC_SIZE * alloc_size];
+ int i;
+ for( i = 0; i < alloc_size*(ALLOC_SIZE-1) ; i+=alloc_size )
+ {
+ slot[i].m_next_p = &slot[i+alloc_size];
+ }
+ slot[i].m_next_p = 0;
+ }
+
+ word* result = (word*)slot;
+ free_words[slot_index] = slot[0].m_next_p;
+ return result;
+}
+
+void
+scfx_mant::free_word( word* array, std::size_t size )
+{
+ if( array && size )
+ {
+ int slot_index = next_pow2_index( size );
+ word_list* wl_p = (word_list*)array;
+
+ wl_p->m_next_p = free_words[slot_index];
+ free_words[slot_index] = wl_p;
+ }
+}
+
+} // namespace sc_dt
+
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_mant.h b/ext/systemc/src/sysc/datatypes/fx/scfx_mant.h
new file mode 100644
index 000000000..84d9b0bd8
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/scfx_mant.h
@@ -0,0 +1,490 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ scfx_mant.h -
+
+ Original Author: Robert Graulich, Synopsys, Inc.
+ Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: scfx_mant.h,v $
+// Revision 1.2 2011/08/24 22:05:43 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:58 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#ifndef SCFX_MANT_H
+#define SCFX_MANT_H
+
+
+#include "sysc/datatypes/fx/scfx_ieee.h"
+#include "sysc/datatypes/fx/scfx_utils.h"
+#include "sysc/kernel/sc_macros.h"
+
+
+namespace sc_dt
+{
+
+// classes defined in this module
+class scfx_mant;
+class scfx_mant_ref;
+
+
+typedef unsigned int word; // Using int because of 64-bit machines.
+typedef unsigned short half_word;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : scfx_mant
+//
+// Mantissa class.
+// ----------------------------------------------------------------------------
+
+class scfx_mant
+{
+
+ word* m_array;
+ int m_size;
+
+public:
+
+ explicit scfx_mant( std::size_t );
+ scfx_mant( const scfx_mant& );
+
+ scfx_mant& operator = ( const scfx_mant& );
+
+ ~scfx_mant();
+
+ void clear();
+
+ void resize_to( int, int = 0 );
+
+ int size() const;
+
+ word operator [] ( int ) const;
+ word& operator [] ( int );
+
+ half_word half_at( int ) const;
+ half_word& half_at( int );
+
+ half_word* half_addr( int = 0 ) const;
+
+private:
+
+ static word* alloc( std::size_t );
+ static void free( word*, std::size_t );
+
+ static word* alloc_word( std::size_t size );
+ static void free_word( word* array, std::size_t size );
+
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+inline
+int
+scfx_mant::size() const
+{
+ return m_size;
+}
+
+
+inline
+word*
+scfx_mant::alloc( std::size_t size )
+{
+#if defined( SC_BIG_ENDIAN )
+ return alloc_word( size ) + ( size - 1 );
+#elif defined( SC_LITTLE_ENDIAN )
+ return alloc_word( size );
+#endif
+}
+
+inline
+void
+scfx_mant::free( word* mant, std::size_t size )
+{
+#if defined( SC_BIG_ENDIAN )
+ free_word( mant - ( size - 1 ), size );
+#elif defined( SC_LITTLE_ENDIAN )
+ free_word( mant, size );
+#endif
+}
+
+inline
+word
+scfx_mant::operator[]( int i ) const
+{
+ SC_ASSERT_( i >= 0 && i < m_size, "mantissa index out of range" );
+#if defined( SC_BIG_ENDIAN )
+ return m_array[-i];
+#elif defined( SC_LITTLE_ENDIAN )
+ return m_array[i];
+#endif
+}
+
+inline
+word&
+scfx_mant::operator[]( int i )
+{
+ SC_ASSERT_( i >= 0 && i < m_size, "mantissa index out of range" );
+#if defined( SC_BIG_ENDIAN )
+ return m_array[-i];
+#elif defined( SC_LITTLE_ENDIAN )
+ return m_array[i];
+#endif
+}
+
+inline
+scfx_mant::scfx_mant( std::size_t size )
+: m_array(0), m_size(size)
+{
+ m_array = alloc( size );
+}
+
+inline
+scfx_mant::scfx_mant( const scfx_mant& rhs )
+: m_array(0), m_size(rhs.m_size)
+{
+ m_array = alloc( m_size );
+ for( int i = 0; i < m_size; i ++ )
+ {
+ (*this)[i] = rhs[i];
+ }
+}
+
+inline
+scfx_mant&
+scfx_mant::operator = ( const scfx_mant& rhs )
+{
+ if( &rhs != this )
+ {
+ if( m_size != rhs.m_size )
+ {
+ free( m_array, m_size );
+ m_array = alloc( m_size = rhs.m_size );
+ }
+
+ for( int i = 0; i < m_size; i ++ )
+ {
+ (*this)[i] = rhs[i];
+ }
+ }
+ return *this;
+}
+
+inline
+scfx_mant::~scfx_mant()
+{
+ if( m_array != 0 )
+ {
+ free( m_array, m_size );
+ }
+}
+
+inline
+void
+scfx_mant::clear()
+{
+ for( int i = 0; i < m_size; i ++ )
+ {
+ (*this)[i] = 0;
+ }
+}
+
+inline
+void
+scfx_mant::resize_to( int size, int restore )
+{
+ if( size == m_size )
+ {
+ return;
+ }
+
+ if( ! m_array )
+ {
+ m_array = alloc( m_size = size );
+ }
+ else
+ {
+ word* p = alloc( size );
+
+ if( restore )
+ {
+ int end = sc_min( size, m_size );
+ if( restore == 1 ) // msb resized -> align at 0
+ {
+ for( int i = 0; i < size; i ++ )
+ {
+ if( i < end )
+ {
+#if defined( SC_BIG_ENDIAN )
+ p[-i] = m_array[-i];
+#elif defined( SC_LITTLE_ENDIAN )
+ p[i] = m_array[i];
+#endif
+ }
+ else
+ {
+#if defined( SC_BIG_ENDIAN )
+ p[-i] = 0;
+#elif defined( SC_LITTLE_ENDIAN )
+ p[i] = 0;
+#endif
+ }
+ }
+ }
+ else // lsb resized -> align at size-1
+ {
+ for( int i = 0; i < size; i ++ )
+ {
+ if( i < end )
+ {
+#if defined( SC_BIG_ENDIAN )
+ p[-size+1+i] = m_array[-m_size+1+i];
+#elif defined( SC_LITTLE_ENDIAN )
+ p[size-1-i] = m_array[m_size-1-i];
+#endif
+ }
+ else
+ {
+#if defined( SC_BIG_ENDIAN )
+ p[-size+1+i] = 0;
+#elif defined( SC_LITTLE_ENDIAN )
+ p[size-1-i] = 0;
+#endif
+ }
+ }
+ }
+ }
+
+ free( m_array, m_size );
+ m_array = p;
+ m_size = size;
+ }
+}
+
+inline
+half_word
+scfx_mant::half_at( int i ) const
+{
+ SC_ASSERT_( ( i >> 1 ) >= 0 && ( i >> 1 ) < m_size,
+ "mantissa index out of range" );
+#if defined( SC_BIG_ENDIAN )
+ return reinterpret_cast<half_word*>( m_array )[-i];
+#elif defined( SC_LITTLE_ENDIAN )
+ return reinterpret_cast<half_word*>( m_array )[i];
+#endif
+}
+
+inline
+half_word&
+scfx_mant::half_at( int i )
+{
+ SC_ASSERT_( ( i >> 1 ) >= 0 && ( i >> 1 ) < m_size,
+ "mantissa index out of range" );
+#if defined( SC_BIG_ENDIAN )
+ return reinterpret_cast<half_word*>( m_array )[-i];
+#elif defined( SC_LITTLE_ENDIAN )
+ return reinterpret_cast<half_word*>( m_array )[i];
+#endif
+}
+
+inline
+half_word*
+scfx_mant::half_addr( int i ) const
+{
+ SC_ASSERT_( i >= 0 && i < m_size, "mantissa index out of range" );
+#if defined( SC_BIG_ENDIAN )
+ return reinterpret_cast<half_word*>( m_array - i ) + 1;
+#elif defined( SC_LITTLE_ENDIAN )
+ return reinterpret_cast<half_word*>( m_array + i );
+#endif
+}
+
+
+// ----------------------------------------------------------------------------
+// one's complement of a mantissa
+// ----------------------------------------------------------------------------
+
+inline
+void
+complement( scfx_mant& target, const scfx_mant& source, int size )
+{
+ for( int i = 0; i < size; i ++ )
+ {
+ target[i] = ~source[i];
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// increment mantissa
+// ----------------------------------------------------------------------------
+
+inline
+void
+inc( scfx_mant& mant )
+{
+ for( int i = 0; i < mant.size(); i ++ )
+ {
+ if( ++ mant[i] )
+ {
+ break;
+ }
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : scfx_mant_ref
+//
+// Mantissa reference class.
+// ----------------------------------------------------------------------------
+
+class scfx_mant_ref
+{
+
+ scfx_mant* m_mant;
+ bool m_not_const;
+
+public:
+
+ scfx_mant_ref();
+ scfx_mant_ref( const scfx_mant& );
+ scfx_mant_ref( scfx_mant* );
+
+ scfx_mant_ref& operator = ( const scfx_mant& );
+ scfx_mant_ref& operator = ( scfx_mant* );
+
+ ~scfx_mant_ref();
+
+ operator scfx_mant&();
+
+ word operator [] ( int );
+
+private:
+
+ void remove_it();
+
+ scfx_mant_ref( const scfx_mant_ref& );
+ scfx_mant_ref& operator = ( const scfx_mant_ref& );
+
+ void* operator new( std::size_t sz ) { return ::operator new( sz ); }
+
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+inline
+void
+scfx_mant_ref::remove_it()
+{
+ if( m_not_const )
+ {
+ delete m_mant;
+ }
+}
+
+inline
+scfx_mant_ref::scfx_mant_ref()
+: m_mant( 0 ), m_not_const( false )
+{}
+
+inline
+scfx_mant_ref::scfx_mant_ref( const scfx_mant& mant )
+: m_mant( const_cast<scfx_mant*>( &mant ) ), m_not_const( false )
+{}
+
+inline
+scfx_mant_ref::scfx_mant_ref( scfx_mant* mant )
+: m_mant( mant ), m_not_const( true )
+{}
+
+inline
+scfx_mant_ref&
+scfx_mant_ref::operator = ( const scfx_mant& mant )
+{
+ remove_it();
+
+ m_mant = const_cast<scfx_mant*>( &mant );
+ m_not_const = false;
+
+ return *this;
+}
+
+inline
+scfx_mant_ref&
+scfx_mant_ref::operator = ( scfx_mant* mant )
+{
+ remove_it();
+
+ m_mant = mant;
+ m_not_const = true;
+
+ return *this;
+}
+
+inline
+scfx_mant_ref::~scfx_mant_ref()
+{
+ remove_it();
+}
+
+inline
+scfx_mant_ref::operator scfx_mant&()
+{
+ // SC_ASSERT_( m_not_const, "not allowed to modify mant" );
+ return *m_mant;
+}
+
+inline
+word
+scfx_mant_ref::operator [] ( int i )
+{
+ return (*m_mant)[i];
+}
+
+} // namespace sc_dt
+
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_other_defs.h b/ext/systemc/src/sysc/datatypes/fx/scfx_other_defs.h
new file mode 100644
index 000000000..a52d74b6b
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/scfx_other_defs.h
@@ -0,0 +1,433 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ scfx_other_defs.h -
+
+ Original Author: Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: scfx_other_defs.h,v $
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:58 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#ifndef SCFX_OTHER_DEFS_H
+#define SCFX_OTHER_DEFS_H
+
+
+#include "sysc/datatypes/fx/sc_fx_ids.h"
+#include "sysc/datatypes/int/sc_signed.h"
+#include "sysc/datatypes/int/sc_unsigned.h"
+#include "sysc/datatypes/int/sc_int_base.h"
+#include "sysc/datatypes/int/sc_uint_base.h"
+#include "sysc/tracing/sc_trace.h"
+
+
+namespace sc_dt
+{
+
+#ifdef SC_INCLUDE_FX
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_signed
+// ----------------------------------------------------------------------------
+
+// assignment operators
+
+inline
+const sc_signed&
+sc_signed::operator = ( const sc_fxval& v )
+{
+ if( ! v.is_normal() ) /* also triggers OBSERVER_READ call */
+ {
+ SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_,
+ "sc_signed::operator = ( const sc_fxval& )" );
+ }
+
+ for( int i = 0; i < length(); ++ i )
+ (*this)[i] = v.get_bit( i );
+
+ return *this;
+}
+
+inline
+const sc_signed&
+sc_signed::operator = ( const sc_fxval_fast& v )
+{
+ if( ! v.is_normal() ) /* also triggers OBSERVER_READ call */
+ {
+ SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_,
+ "sc_signed::operator = ( const sc_fxval_fast& )" );
+ }
+
+ for( int i = 0; i < length(); ++ i )
+ (*this)[i] = v.get_bit( i );
+
+ return *this;
+}
+
+inline
+const sc_signed&
+sc_signed::operator = ( const sc_fxnum& v )
+{
+ if( ! v.is_normal() ) /* also triggers OBSERVER_READ call */
+ {
+ SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_,
+ "sc_signed::operator = ( const sc_fxnum& )" );
+ }
+
+ for( int i = 0; i < length(); ++ i )
+ (*this)[i] = v.get_bit( i );
+
+ return *this;
+}
+
+inline
+const sc_signed&
+sc_signed::operator = ( const sc_fxnum_fast& v )
+{
+ if( ! v.is_normal() ) /* also triggers OBSERVER_READ call */
+ {
+ SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_,
+ "sc_signed::operator = ( const sc_fxnum_fast& )" );
+ }
+
+ for( int i = 0; i < length(); ++ i )
+ (*this)[i] = v.get_bit( i );
+
+ return *this;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_unsigned
+// ----------------------------------------------------------------------------
+
+// assignment operators
+
+inline
+const sc_unsigned&
+sc_unsigned::operator = ( const sc_fxval& v )
+{
+ if( ! v.is_normal() ) /* also triggers OBSERVER_READ call */
+ {
+ SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_,
+ "sc_unsigned::operator = ( const sc_fxval& )" );
+ }
+
+ for( int i = 0; i < length(); ++ i )
+ (*this)[i] = v.get_bit( i );
+
+ return *this;
+}
+
+inline
+const sc_unsigned&
+sc_unsigned::operator = ( const sc_fxval_fast& v )
+{
+ if( ! v.is_normal() ) /* also triggers OBSERVER_READ call */
+ {
+ SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_,
+ "sc_unsigned::operator = ( const sc_fxval_fast& )" );
+ }
+
+ for( int i = 0; i < length(); ++ i )
+ (*this)[i] = v.get_bit( i );
+
+ return *this;
+}
+
+inline
+const sc_unsigned&
+sc_unsigned::operator = ( const sc_fxnum& v )
+{
+ if( ! v.is_normal() ) /* also triggers OBSERVER_READ call */
+ {
+ SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_,
+ "sc_unsigned::operator = ( const sc_fxnum& )" );
+ }
+
+ for( int i = 0; i < length(); ++ i )
+ (*this)[i] = v.get_bit( i );
+
+ return *this;
+}
+
+inline
+const sc_unsigned&
+sc_unsigned::operator = ( const sc_fxnum_fast& v )
+{
+ if( ! v.is_normal() ) /* also triggers OBSERVER_READ call */
+ {
+ SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_,
+ "sc_unsigned::operator = ( const sc_fxnum_fast& )" );
+ }
+
+ for( int i = 0; i < length(); ++ i )
+ (*this)[i] = v.get_bit( i );
+
+ return *this;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_int_base
+// ----------------------------------------------------------------------------
+
+#ifndef _32BIT_
+#define NUM_WIDTH LLWIDTH
+#else
+#define NUM_WIDTH INTWIDTH
+#endif
+
+
+// assignment operators
+
+inline
+sc_int_base&
+sc_int_base::operator = ( const sc_fxval& v )
+{
+ if( ! v.is_normal() ) { /* also triggers OBSERVER_READ call */
+ SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_,
+ "sc_int_base::operator = ( const sc_fxval& )" );
+ }
+ for( int i = 0; i < m_len; ++ i ) {
+ set( i, v.get_bit( i ) );
+ }
+ extend_sign();
+ return *this;
+}
+
+inline
+sc_int_base&
+sc_int_base::operator = ( const sc_fxval_fast& v )
+{
+ if( ! v.is_normal() ) { /* also triggers OBSERVER_READ call */
+ SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_,
+ "sc_int_base::operator = ( const sc_fxval_fast& )" );
+ }
+ for( int i = 0; i < m_len; ++ i ) {
+ set( i, v.get_bit( i ) );
+ }
+ extend_sign();
+ return *this;
+}
+
+inline
+sc_int_base&
+sc_int_base::operator = ( const sc_fxnum& v )
+{
+ if( ! v.is_normal() ) { /* also triggers OBSERVER_READ call */
+ SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_,
+ "sc_int_base::operator = ( const sc_fxnum& )" );
+ }
+ for( int i = 0; i < m_len; ++ i ) {
+ set( i, v.get_bit( i ) );
+ }
+ extend_sign();
+ return *this;
+}
+
+inline
+sc_int_base&
+sc_int_base::operator = ( const sc_fxnum_fast& v )
+{
+ if( ! v.is_normal() ) { /* also triggers OBSERVER_READ call */
+ SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_,
+ "sc_int_base::operator = ( const sc_fxnum_fast& )" );
+ }
+ for( int i = 0; i < m_len; ++ i ) {
+ set( i, v.get_bit( i ) );
+ }
+ extend_sign();
+ return *this;
+}
+
+#undef NUM_WIDTH
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_uint_base
+// ----------------------------------------------------------------------------
+
+// assignment operators
+
+inline
+sc_uint_base&
+sc_uint_base::operator = ( const sc_fxval& v )
+{
+ if( ! v.is_normal() ) { /* also triggers OBSERVER_READ call */
+ SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_,
+ "sc_uint_base::operator = ( const sc_fxval& )" );
+ }
+ for( int i = 0; i < m_len; ++ i ) {
+ set( i, v.get_bit( i ) );
+ }
+ extend_sign();
+ return *this;
+}
+
+inline
+sc_uint_base&
+sc_uint_base::operator = ( const sc_fxval_fast& v )
+{
+ if( ! v.is_normal() ) { /* also triggers OBSERVER_READ call */
+ SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_,
+ "sc_uint_base::operator = ( const sc_fxval_fast& )" );
+ }
+ for( int i = 0; i < m_len; ++ i ) {
+ set( i, v.get_bit( i ) );
+ }
+ extend_sign();
+ return *this;
+}
+
+inline
+sc_uint_base&
+sc_uint_base::operator = ( const sc_fxnum& v )
+{
+ if( ! v.is_normal() ) { /* also triggers OBSERVER_READ call */
+ SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_,
+ "sc_uint_base::operator = ( const sc_fxnum& )" );
+ }
+ for( int i = 0; i < m_len; ++ i ) {
+ set( i, v.get_bit( i ) );
+ }
+ extend_sign();
+ return *this;
+}
+
+inline
+sc_uint_base&
+sc_uint_base::operator = ( const sc_fxnum_fast& v )
+{
+ if( ! v.is_normal() ) { /* also triggers OBSERVER_READ call */
+ SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_,
+ "sc_uint_base::operator = ( const sc_fxnum_fast& )" );
+ }
+ for( int i = 0; i < m_len; ++ i ) {
+ set( i, v.get_bit( i ) );
+ }
+ extend_sign();
+ return *this;
+}
+
+
+#endif
+
+
+// ----------------------------------------------------------------------------
+// FUNCTION : sc_trace
+// ----------------------------------------------------------------------------
+
+inline
+void
+sc_trace( sc_core::sc_trace_file* tf,
+ const sc_fxval& object, const std::string& name )
+{
+ if( tf )
+ tf->trace( object, name );
+}
+
+inline
+void
+sc_trace( sc_core::sc_trace_file* tf,
+ const sc_fxval* object, const std::string& name )
+{
+ if( tf )
+ tf->trace( *object, name );
+}
+
+inline
+void
+sc_trace( sc_core::sc_trace_file* tf,
+ const sc_fxval_fast& object, const std::string& name )
+{
+ if( tf )
+ tf->trace( object, name );
+}
+
+inline
+void
+sc_trace( sc_core::sc_trace_file* tf,
+ const sc_fxval_fast* object, const std::string& name )
+{
+ if( tf )
+ tf->trace( *object, name );
+}
+
+inline
+void
+sc_trace( sc_core::sc_trace_file* tf,
+ const sc_fxnum& object, const std::string& name )
+{
+ if( tf )
+ tf->trace( object, name );
+}
+
+inline
+void
+sc_trace( sc_core::sc_trace_file* tf,
+ const sc_fxnum* object, const std::string& name )
+{
+ if( tf )
+ tf->trace( *object, name );
+}
+
+inline
+void
+sc_trace( sc_core::sc_trace_file* tf,
+ const sc_fxnum_fast& object, const std::string& name )
+{
+ if( tf )
+ tf->trace( object, name );
+}
+
+inline
+void
+sc_trace( sc_core::sc_trace_file* tf,
+ const sc_fxnum_fast* object, const std::string& name )
+{
+ if( tf )
+ tf->trace( *object, name );
+}
+
+} // namespace sc_dt
+
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_params.h b/ext/systemc/src/sysc/datatypes/fx/scfx_params.h
new file mode 100644
index 000000000..8cd646651
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/scfx_params.h
@@ -0,0 +1,222 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ scfx_params.h -
+
+ Original Author: Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: scfx_params.h,v $
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:58 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#ifndef SCFX_PARAMS_H
+#define SCFX_PARAMS_H
+
+
+#include "sysc/datatypes/fx/sc_fx_ids.h"
+#include "sysc/datatypes/fx/sc_fxcast_switch.h"
+#include "sysc/datatypes/fx/sc_fxtype_params.h"
+
+
+namespace sc_dt
+{
+
+// classes defined in this module
+class scfx_params;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : scfx_params
+//
+// ...
+// ----------------------------------------------------------------------------
+
+class scfx_params
+{
+
+public:
+
+ // constructor
+
+ scfx_params( const sc_fxtype_params&,
+ sc_enc,
+ const sc_fxcast_switch& );
+
+
+ // query functions
+
+ const sc_fxtype_params& type_params() const;
+ sc_enc enc() const;
+ const sc_fxcast_switch& cast_switch() const;
+
+
+ // shortcuts
+
+ int wl() const;
+ int iwl() const;
+ int fwl() const;
+ sc_q_mode q_mode() const;
+ sc_o_mode o_mode() const;
+ int n_bits() const;
+
+
+ // dump content
+
+ void dump( ::std::ostream& ) const;
+
+private:
+
+ sc_fxtype_params m_type_params;
+ sc_enc m_enc;
+ sc_fxcast_switch m_cast_switch;
+
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+// constructor
+
+inline
+scfx_params::scfx_params( const sc_fxtype_params& type_params_,
+ sc_enc enc_,
+ const sc_fxcast_switch& cast_sw )
+: m_type_params( type_params_ ),
+ m_enc( enc_ ),
+ m_cast_switch( cast_sw )
+{
+ if( m_enc == SC_US_ && m_type_params.o_mode() == SC_WRAP_SM )
+ {
+ SC_REPORT_ERROR( sc_core::SC_ID_INVALID_O_MODE_,
+ "SC_WRAP_SM not defined for unsigned numbers" );
+ }
+
+}
+
+
+// query functions
+
+inline
+const sc_fxtype_params&
+scfx_params::type_params() const
+{
+ return m_type_params;
+}
+
+inline
+sc_enc
+scfx_params::enc() const
+{
+ return m_enc;
+}
+
+inline
+const sc_fxcast_switch&
+scfx_params::cast_switch() const
+{
+ return m_cast_switch;
+}
+
+
+// shortcuts
+
+inline
+int
+scfx_params::wl() const
+{
+ return m_type_params.wl();
+}
+
+inline
+int
+scfx_params::iwl() const
+{
+ return m_type_params.iwl();
+}
+
+inline
+int
+scfx_params::fwl() const
+{
+ return ( m_type_params.wl() - m_type_params.iwl() );
+}
+
+inline
+sc_q_mode
+scfx_params::q_mode() const
+{
+ return m_type_params.q_mode();
+}
+
+inline
+sc_o_mode
+scfx_params::o_mode() const
+{
+ return m_type_params.o_mode();
+}
+
+inline
+int
+scfx_params::n_bits() const
+{
+ return m_type_params.n_bits();
+}
+
+
+// dump content
+
+inline
+void
+scfx_params::dump( ::std::ostream& os ) const
+{
+ os << "scfx_params" << ::std::endl;
+ os << "(" << ::std::endl;
+ os << "type_params = ";
+ m_type_params.dump( os );
+ os << "enc = " << m_enc << ::std::endl;
+ os << "cast_switch = ";
+ m_cast_switch.dump( os );
+ os << ")" << ::std::endl;
+}
+
+} // namespace sc_dt
+
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_pow10.cpp b/ext/systemc/src/sysc/datatypes/fx/scfx_pow10.cpp
new file mode 100644
index 000000000..ac931763b
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/scfx_pow10.cpp
@@ -0,0 +1,147 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ scfx_pow10.cpp -
+
+ Original Author: Robert Graulich, Synopsys, Inc.
+ Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// $Log: scfx_pow10.cpp,v $
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:58 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#include "sysc/datatypes/fx/scfx_pow10.h"
+
+
+namespace sc_dt
+{
+
+// ----------------------------------------------------------------------------
+// CLASS : scfx_pow10
+//
+// Class to compute (and cache) powers of 10 in arbitrary precision.
+// ----------------------------------------------------------------------------
+
+scfx_pow10::scfx_pow10()
+{
+ m_pos[0] = scfx_rep( 10.0 );
+ m_neg[0] = scfx_rep( 0.1 );
+
+ for( int i = 1; i < SCFX_POW10_TABLE_SIZE; i ++ )
+ {
+ m_pos[i].set_nan();
+ m_neg[i].set_nan();
+ }
+}
+
+scfx_pow10::~scfx_pow10()
+{}
+
+
+const scfx_rep
+scfx_pow10::operator() ( int i )
+{
+ if( i == 0 ) {
+ return scfx_rep( 1.0 );
+ }
+
+ if( i > 0 )
+ {
+ int bit = scfx_find_msb( i );
+ scfx_rep result = *pos( bit );
+ if( bit )
+ {
+ while( -- bit >= 0 )
+ {
+ if( ( 1 << bit ) & i )
+ {
+ scfx_rep* tmp = mult_scfx_rep( result, *pos( bit ) );
+ result = *tmp;
+ delete tmp;
+ }
+ }
+ }
+ return result;
+ }
+ else
+ {
+ i = -i;
+ int bit = scfx_find_msb( i );
+ scfx_rep result = *neg( bit );
+ if( bit )
+ {
+ while( -- bit >= 0 )
+ {
+ if( ( 1 << bit ) & i )
+ {
+ scfx_rep* tmp = mult_scfx_rep( result, *neg( bit ) );
+ result = *tmp;
+ delete tmp;
+ }
+ }
+ }
+ return result;
+ }
+}
+
+
+scfx_rep*
+scfx_pow10::pos( int i )
+{
+ if( ! m_pos[i].is_normal() )
+ {
+ multiply( m_pos[i], *pos( i - 1 ), *pos( i - 1 ) );
+ }
+ return &m_pos[i];
+}
+
+scfx_rep*
+scfx_pow10::neg( int i )
+{
+ if( ! m_neg[i].is_normal() )
+ {
+ multiply( m_neg[i], *neg( i - 1 ), *neg( i - 1 ) );
+ }
+ return &m_neg[i];
+}
+
+} // namespace sc_dt
+
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_pow10.h b/ext/systemc/src/sysc/datatypes/fx/scfx_pow10.h
new file mode 100644
index 000000000..c9b278561
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/scfx_pow10.h
@@ -0,0 +1,95 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ scfx_pow10.h -
+
+ Original Author: Robert Graulich, Synopsys, Inc.
+ Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: scfx_pow10.h,v $
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:58 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#ifndef SCFX_POW10_H
+#define SCFX_POW10_H
+
+
+#include "sysc/datatypes/fx/scfx_rep.h"
+
+
+namespace sc_dt
+{
+
+// classes defined in this module
+class scfx_pow10;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : scfx_pow10
+//
+// Class to compute (and cache) powers of 10 in arbitrary precision.
+// ----------------------------------------------------------------------------
+
+const int SCFX_POW10_TABLE_SIZE = 32;
+
+
+class scfx_pow10
+{
+
+public:
+
+ scfx_pow10();
+ ~scfx_pow10();
+
+ const scfx_rep operator() ( int );
+
+private:
+
+ scfx_rep* pos( int );
+ scfx_rep* neg( int );
+
+ scfx_rep m_pos[SCFX_POW10_TABLE_SIZE];
+ scfx_rep m_neg[SCFX_POW10_TABLE_SIZE];
+};
+
+} // namespace sc_dt
+
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_rep.cpp b/ext/systemc/src/sysc/datatypes/fx/scfx_rep.cpp
new file mode 100644
index 000000000..772835e6d
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/scfx_rep.cpp
@@ -0,0 +1,2926 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ scfx_rep.cpp -
+
+ Original Author: Robert Graulich, Synopsys, Inc.
+ Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// $Log: scfx_rep.cpp,v $
+// Revision 1.4 2011/08/24 22:05:43 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.3 2011/08/15 16:43:24 acg
+// Torsten Maehne: changes to remove unused argument warnings.
+//
+// Revision 1.2 2009/02/28 00:26:20 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.2 2008/11/06 17:22:47 acg
+// Andy Goodrich: bug fixes for 2.2.1.
+//
+// Revision 1.1.1.1 2006/12/15 20:31:36 acg
+// SystemC 2.2
+//
+// Revision 1.3 2006/01/13 18:53:58 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#include "sysc/utils/sc_machine.h"
+#include "sysc/datatypes/fx/scfx_rep.h"
+
+#include "sysc/datatypes/fx/scfx_ieee.h"
+#include "sysc/datatypes/fx/scfx_pow10.h"
+#include "sysc/datatypes/fx/scfx_utils.h"
+
+#include "sysc/datatypes/bit/sc_bv_base.h"
+
+#include <ctype.h>
+#include <cstdio>
+#include <stdlib.h>
+#include <math.h>
+
+
+namespace sc_dt
+{
+
+// ----------------------------------------------------------------------------
+// some utilities
+// ----------------------------------------------------------------------------
+
+static scfx_pow10 pow10_fx;
+
+static const int mantissa0_size = SCFX_IEEE_DOUBLE_M_SIZE - bits_in_int;
+
+static inline
+int
+n_word( int x )
+{
+ return ( x + bits_in_word - 1 ) / bits_in_word;
+}
+
+
+// ----------------------------------------------------------------------------
+// CONSTRUCTORS
+// ----------------------------------------------------------------------------
+
+scfx_rep::scfx_rep()
+: m_mant( min_mant ), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
+ m_r_flag( false )
+{
+ set_zero();
+}
+
+scfx_rep::scfx_rep( int a )
+: m_mant( min_mant ), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
+ m_r_flag( false )
+{
+ if( a != 0 )
+ {
+ m_mant.clear();
+ m_wp = m_msw = m_lsw = 2;
+ m_state = normal;
+ if( a > 0 )
+ {
+ m_mant[2] = a;
+ m_sign = 1;
+ }
+ else
+ {
+ m_mant[2] = -a;
+ m_sign = -1;
+ }
+ }
+ else
+ set_zero();
+}
+
+scfx_rep::scfx_rep( unsigned int a )
+: m_mant( min_mant ), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
+ m_r_flag( false )
+{
+ if( a != 0 )
+ {
+ m_mant.clear();
+ m_wp = m_msw = m_lsw = 2;
+ m_state = normal;
+ m_mant[2] = a;
+ m_sign = 1;
+ }
+ else
+ set_zero();
+}
+
+scfx_rep::scfx_rep( long a )
+: m_mant( min_mant ), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
+ m_r_flag( false )
+{
+ if( a != 0 )
+ {
+ m_mant.clear();
+ m_state = normal;
+ if ( a > 0 )
+ {
+ m_sign = 1;
+ }
+ else
+ {
+ a = -a;
+ m_sign = -1;
+ }
+# if defined(SC_LONG_64)
+ m_wp = 1;
+ m_mant[1] = static_cast<word>( a );
+ m_mant[2] = static_cast<word>( a >> bits_in_word );
+ find_sw();
+# else
+ m_wp = 2;
+ m_msw = 2;
+ m_lsw = 2;
+ m_mant[2] = a;
+# endif
+
+ }
+ else
+ set_zero();
+}
+
+scfx_rep::scfx_rep( unsigned long a )
+: m_mant( min_mant ), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
+ m_r_flag( false )
+{
+ if( a != 0 )
+ {
+ m_mant.clear();
+ m_wp = m_msw = m_lsw = 2;
+ m_state = normal;
+# if defined(SC_LONG_64)
+ m_wp = 1;
+ m_mant[1] = static_cast<word>( a );
+ m_mant[2] = static_cast<word>( a >> bits_in_word );
+ find_sw();
+# else
+ m_wp = 2;
+ m_msw = 2;
+ m_lsw = 2;
+ m_mant[2] = a;
+# endif
+ m_sign = 1;
+ }
+ else
+ set_zero();
+}
+
+scfx_rep::scfx_rep( double a )
+: m_mant( min_mant ), m_wp( 0 ), m_sign(), m_state( normal ), m_msw( 0 ),
+ m_lsw( 0 ), m_r_flag( false )
+{
+ m_mant.clear();
+
+ scfx_ieee_double id( a );
+
+ m_sign = id.negative() ? -1 : 1;
+
+ if( id.is_nan() )
+ m_state = not_a_number;
+ else if( id.is_inf() )
+ m_state = infinity;
+ else if( id.is_subnormal() )
+ {
+ m_mant[0] = id.mantissa1();
+ m_mant[1] = id.mantissa0();
+ normalize( id.exponent() + 1 - SCFX_IEEE_DOUBLE_M_SIZE );
+ }
+ else if( id.is_normal() )
+ {
+ m_mant[0] = id.mantissa1();
+ m_mant[1] = id.mantissa0() | ( 1 << mantissa0_size );
+ normalize( id.exponent() - SCFX_IEEE_DOUBLE_M_SIZE );
+ }
+}
+
+scfx_rep::scfx_rep( int64 a )
+: m_mant( min_mant ), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
+ m_r_flag( false )
+{
+ if( a != 0 )
+ {
+ m_mant.clear();
+ m_wp = 1;
+ m_state = normal;
+ if( a > 0 )
+ {
+ m_mant[1] = static_cast<word>( a );
+ m_mant[2] = static_cast<word>( a >> bits_in_word );
+ m_sign = 1;
+ }
+ else
+ {
+ m_mant[1] = static_cast<word>( -a );
+ m_mant[2] = static_cast<word>( (-a) >> bits_in_word );
+ m_sign = -1;
+ }
+ find_sw();
+ }
+ else
+ set_zero();
+}
+
+scfx_rep::scfx_rep( uint64 a )
+: m_mant( min_mant ), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
+ m_r_flag( false )
+{
+ if( a != 0 )
+ {
+ m_mant.clear();
+ m_wp = 1;
+ m_state = normal;
+ m_mant[1] = static_cast<word>( a );
+ m_mant[2] = static_cast<word>( a >> bits_in_word );
+ m_sign = 1;
+ find_sw();
+ }
+ else
+ set_zero();
+}
+
+scfx_rep::scfx_rep( const sc_signed& a )
+: m_mant( min_mant ), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
+ m_r_flag( false )
+{
+ if( a.iszero() )
+ set_zero();
+ else
+ {
+ int words = n_word( a.length() );
+ if( words > size() )
+ resize_to( words );
+ m_mant.clear();
+ m_wp = 0;
+ m_state = normal;
+ if( a.sign() )
+ {
+ sc_signed a2 = -a;
+ for( int i = 0; i < a2.length(); ++ i )
+ {
+ if( a2[i] )
+ {
+ scfx_index x = calc_indices( i );
+ m_mant[x.wi()] |= 1 << x.bi();
+ }
+ }
+ m_sign = -1;
+ }
+ else
+ {
+ for( int i = 0; i < a.length(); ++ i )
+ {
+ if( a[i] )
+ {
+ scfx_index x = calc_indices( i );
+ m_mant[x.wi()] |= 1 << x.bi();
+ }
+ }
+ m_sign = 1;
+ }
+ find_sw();
+ }
+}
+
+scfx_rep::scfx_rep( const sc_unsigned& a )
+: m_mant( min_mant ), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
+ m_r_flag( false )
+{
+ if( a.iszero() )
+ set_zero();
+ else
+ {
+ int words = n_word( a.length() );
+ if( words > size() )
+ resize_to( words );
+ m_mant.clear();
+ m_wp = 0;
+ m_state = normal;
+ for( int i = 0; i < a.length(); ++ i )
+ {
+ if( a[i] )
+ {
+ scfx_index x = calc_indices( i );
+ m_mant[x.wi()] |= 1 << x.bi();
+ }
+ }
+ m_sign = 1;
+ find_sw();
+ }
+}
+
+
+// copy constructor
+
+scfx_rep::scfx_rep( const scfx_rep& a )
+: m_mant( a.m_mant ), m_wp( a.m_wp ), m_sign( a.m_sign ), m_state( a.m_state ),
+ m_msw( a.m_msw ), m_lsw( a.m_lsw ), m_r_flag( false )
+{}
+
+
+// ----------------------------------------------------------------------------
+// OPERATORS : new, delete
+//
+// Memory management for class scfx_rep.
+// ----------------------------------------------------------------------------
+
+union scfx_rep_node
+{
+ char data[sizeof( scfx_rep )];
+ scfx_rep_node* next;
+};
+
+
+static scfx_rep_node* list = 0;
+
+
+void*
+scfx_rep::operator new( std::size_t size )
+{
+ const int ALLOC_SIZE = 1024;
+
+ if( size != sizeof( scfx_rep ) )
+ return ::operator new( size );
+
+ if( ! list )
+ {
+ list = new scfx_rep_node[ALLOC_SIZE];
+ for( int i = 0; i < ALLOC_SIZE - 1; i ++ )
+ list[i].next = list + i + 1;
+ list[ALLOC_SIZE - 1].next = 0;
+ }
+
+ scfx_rep* ptr = reinterpret_cast<scfx_rep*>( list->data );
+ list = list->next;
+
+ return ptr;
+}
+
+
+void scfx_rep::operator delete( void* ptr, std::size_t size )
+{
+ if( size != sizeof( scfx_rep ) )
+ {
+ ::operator delete( ptr );
+ return;
+ }
+
+ scfx_rep_node* node = static_cast<scfx_rep_node*>( ptr );
+ node->next = list;
+ list = node;
+}
+
+
+// ----------------------------------------------------------------------------
+// METHOD : from_string
+//
+// Convert from character string to sc_fxrep.
+// ----------------------------------------------------------------------------
+
+#define SCFX_FAIL_IF_(cnd) \
+{ \
+ if( ( cnd ) ) \
+ { \
+ m_state = not_a_number; \
+ m_mant.clear(); /* to avoid Purify UMRs during assignment */ \
+ return; \
+ } \
+}
+
+
+void
+scfx_rep::from_string( const char* s, int cte_wl )
+{
+ SCFX_FAIL_IF_( s == 0 || *s == 0 );
+
+ scfx_string s2;
+ s2 += s;
+ s2 += '\0';
+
+ bool sign_char;
+ m_sign = scfx_parse_sign( s, sign_char );
+
+ sc_numrep numrep = scfx_parse_prefix( s );
+
+ int base = 0;
+
+ switch( numrep )
+ {
+ case SC_DEC:
+ {
+ base = 10;
+ if( scfx_is_nan( s ) )
+ { // special case: NaN
+ m_state = not_a_number;
+ m_mant.clear(); /* to avoid Purify UMRs during assignment */
+ return;
+ }
+ if( scfx_is_inf( s ) )
+ { // special case: Infinity
+ m_state = infinity;
+ m_mant.clear(); /* to avoid Purify UMRs during assignment */
+ return;
+ }
+ break;
+ }
+ case SC_BIN:
+ case SC_BIN_US:
+ {
+ SCFX_FAIL_IF_( sign_char );
+ base = 2;
+ break;
+ }
+
+ case SC_BIN_SM:
+ {
+ base = 2;
+ break;
+ }
+ case SC_OCT:
+ case SC_OCT_US:
+ {
+ SCFX_FAIL_IF_( sign_char );
+ base = 8;
+ break;
+ }
+ case SC_OCT_SM:
+ {
+ base = 8;
+ break;
+ }
+ case SC_HEX:
+ case SC_HEX_US:
+ {
+ SCFX_FAIL_IF_( sign_char );
+ base = 16;
+ break;
+ }
+ case SC_HEX_SM:
+ {
+ base = 16;
+ break;
+ }
+ case SC_CSD:
+ {
+ SCFX_FAIL_IF_( sign_char );
+ base = 2;
+ scfx_csd2tc( s2 );
+ s = (const char*) s2 + 4;
+ numrep = SC_BIN;
+ break;
+ }
+ default:;
+ }
+
+ //
+ // find end of mantissa and count the digits and points
+ //
+
+ const char *end = s;
+ bool based_point = false;
+ int int_digits = 0;
+ int frac_digits = 0;
+
+ while( *end )
+ {
+ if( scfx_exp_start( end ) )
+ break;
+
+ if( *end == '.' )
+ {
+ SCFX_FAIL_IF_( based_point );
+ based_point = true;
+ }
+ else
+ {
+ SCFX_FAIL_IF_( ! scfx_is_digit( *end, numrep ) );
+ if( based_point )
+ frac_digits ++;
+ else
+ int_digits ++;
+ }
+
+ ++ end;
+ }
+
+ SCFX_FAIL_IF_( int_digits == 0 && frac_digits == 0 );
+
+ // [ exponent ]
+
+ int exponent = 0;
+
+ if( *end )
+ {
+ for( const char *e = end + 2; *e; ++ e )
+ SCFX_FAIL_IF_( ! scfx_is_digit( *e, SC_DEC ) );
+ exponent = atoi( end + 1 );
+ }
+
+ //
+ // check if the mantissa is negative
+ //
+
+ bool mant_is_neg = false;
+
+ switch( numrep )
+ {
+ case SC_BIN:
+ case SC_OCT:
+ case SC_HEX:
+ {
+ const char* p = s;
+ if( *p == '.' )
+ ++ p;
+
+ mant_is_neg = ( scfx_to_digit( *p, numrep ) >= ( base >> 1 ) );
+
+ break;
+ }
+ default:
+ ;
+ }
+
+ //
+ // convert the mantissa
+ //
+
+ switch( base )
+ {
+ case 2:
+ {
+ int bit_offset = exponent % bits_in_word;
+ int word_offset = exponent / bits_in_word;
+
+ int_digits += bit_offset;
+ frac_digits -= bit_offset;
+
+ int words = n_word( int_digits ) + n_word( frac_digits );
+ if( words > size() )
+ resize_to( words );
+ m_mant.clear();
+
+ int j = n_word( frac_digits ) * bits_in_word + int_digits - 1;
+
+ for( ; s < end; s ++ )
+ {
+ switch( *s )
+ {
+ case '1':
+ set_bin( j );
+ case '0':
+ j --;
+ case '.':
+ break;
+ default:
+ SCFX_FAIL_IF_( true ); // should not happen
+ }
+ }
+
+ m_wp = n_word( frac_digits ) - word_offset;
+ break;
+ }
+ case 8:
+ {
+ exponent *= 3;
+ int_digits *= 3;
+ frac_digits *= 3;
+
+ int bit_offset = exponent % bits_in_word;
+ int word_offset = exponent / bits_in_word;
+
+ int_digits += bit_offset;
+ frac_digits -= bit_offset;
+
+ int words = n_word( int_digits ) + n_word( frac_digits );
+ if( words > size() )
+ resize_to( words );
+ m_mant.clear();
+
+ int j = n_word( frac_digits ) * bits_in_word + int_digits - 3;
+
+ for( ; s < end; s ++ )
+ {
+ switch( *s )
+ {
+ case '7': case '6': case '5': case '4':
+ case '3': case '2': case '1':
+ set_oct( j, *s - '0' );
+ case '0':
+ j -= 3;
+ case '.':
+ break;
+ default:
+ SCFX_FAIL_IF_( true ); // should not happen
+ }
+ }
+
+ m_wp = n_word( frac_digits ) - word_offset;
+ break;
+ }
+ case 10:
+ {
+ word carry, temp;
+ int length = int_digits + frac_digits;
+ resize_to( sc_max( min_mant, n_word( 4 * length ) ) );
+
+ m_mant.clear();
+ m_msw = m_lsw = 0;
+
+ for( ; s < end; s ++ )
+ {
+ switch( *s )
+ {
+ case '9': case '8': case '7': case '6': case '5':
+ case '4': case '3': case '2': case '1': case '0':
+ multiply_by_ten();
+ carry = *s - '0';
+ for ( int i = 0; carry && i < m_mant.size(); i++ )
+ {
+ temp = m_mant[i];
+ temp += carry;
+ carry = temp < m_mant[i];
+ m_mant[i] = temp;
+ }
+ case '.':
+ break;
+ default:
+ SCFX_FAIL_IF_( true ); // should not happen
+ }
+ }
+
+ m_wp = 0;
+ find_sw();
+
+ int denominator = frac_digits - exponent;
+
+ if( denominator )
+ {
+ scfx_rep frac_num = pow10_fx( denominator );
+ scfx_rep* temp_num =
+ div_scfx_rep( const_cast<const scfx_rep&>( *this ),
+ frac_num, cte_wl );
+ *this = *temp_num;
+ delete temp_num;
+ }
+
+ break;
+ }
+ case 16:
+ {
+ exponent *= 4;
+ int_digits *= 4;
+ frac_digits *= 4;
+
+ int bit_offset = exponent % bits_in_word;
+ int word_offset = exponent / bits_in_word;
+
+ int_digits += bit_offset;
+ frac_digits -= bit_offset;
+
+ int words = n_word( int_digits ) + n_word( frac_digits );
+ if( words > size() )
+ resize_to( words );
+ m_mant.clear();
+
+ int j = n_word( frac_digits ) * bits_in_word + int_digits - 4;
+
+ for( ; s < end; s ++ )
+ {
+ switch( *s )
+ {
+ case 'f': case 'e': case 'd': case 'c': case 'b': case 'a':
+ set_hex( j, *s - 'a' + 10 );
+ j -= 4;
+ break;
+ case 'F': case 'E': case 'D': case 'C': case 'B': case 'A':
+ set_hex( j, *s - 'A' + 10 );
+ j -= 4;
+ break;
+ case '9': case '8': case '7': case '6': case '5':
+ case '4': case '3': case '2': case '1':
+ set_hex( j, *s - '0' );
+ case '0':
+ j -= 4;
+ case '.':
+ break;
+ default:
+ SCFX_FAIL_IF_( true ); // should not happen
+ }
+ }
+
+ m_wp = n_word( frac_digits ) - word_offset;
+ break;
+ }
+ }
+
+ m_state = normal;
+ find_sw();
+
+ //
+ // two's complement of mantissa if it is negative
+ //
+
+ if( mant_is_neg )
+ {
+ m_mant[m_msw] |= -1 << scfx_find_msb( m_mant[m_msw] );
+ for( int i = m_msw + 1; i < m_mant.size(); ++ i )
+ m_mant[i] = static_cast<word>( -1 );
+ complement( m_mant, m_mant, m_mant.size() );
+ inc( m_mant );
+ m_sign *= -1;
+ find_sw();
+ }
+}
+
+
+#undef SCFX_FAIL_IF_
+
+
+// ----------------------------------------------------------------------------
+// METHOD : to_double
+//
+// Convert from scfx_rep to double.
+// ----------------------------------------------------------------------------
+
+double
+scfx_rep::to_double() const
+{
+ scfx_ieee_double id;
+
+ // handle special cases
+
+ if( is_nan() )
+ {
+ id.set_nan();
+ return id;
+ }
+
+ if( is_inf() )
+ {
+ id.set_inf();
+ id.negative( m_sign < 0 );
+ return id;
+ }
+
+ if( is_zero() )
+ {
+ id = 0.;
+ id.negative( m_sign < 0 );
+ return id;
+ }
+
+ int msb = scfx_find_msb( m_mant[m_msw] );
+
+ int exp = (m_msw - m_wp) * bits_in_word + msb;
+
+ if( exp > SCFX_IEEE_DOUBLE_E_MAX )
+ {
+ id.set_inf();
+ id.negative( m_sign < 0 );
+ return id;
+ }
+
+ if( exp < SCFX_IEEE_DOUBLE_E_MIN
+ - static_cast<int>( SCFX_IEEE_DOUBLE_M_SIZE ) )
+ {
+ id = 0.;
+ return id;
+ }
+
+ int shift = mantissa0_size - msb;
+
+ unsigned int m0;
+ unsigned int m1 = 0;
+ unsigned int guard = 0;
+
+ if( shift == 0 )
+ {
+ m0 = m_mant[m_msw] & ~( 1 << mantissa0_size );
+ if( m_msw > m_lsw )
+ {
+ m1 = m_mant[m_msw - 1];
+ if( m_msw - 1 > m_lsw )
+ guard = m_mant[m_msw - 2] >> ( bits_in_word - 1 );
+ }
+ }
+ else if( shift < 0 )
+ {
+ m0 = ( m_mant[m_msw] >> -shift ) & ~( 1 << mantissa0_size );
+ m1 = m_mant[m_msw] << ( bits_in_word + shift );
+ if( m_msw > m_lsw )
+ {
+ m1 |= m_mant[m_msw - 1] >> -shift;
+ guard = ( m_mant[m_msw - 1] >> ( -shift - 1 ) ) & 1;
+ }
+ }
+ else
+ {
+ m0 = ( m_mant[m_msw] << shift ) & ~( 1 << mantissa0_size );
+ if( m_msw > m_lsw )
+ {
+ m0 |= m_mant[m_msw - 1] >> ( bits_in_word - shift );
+ m1 = m_mant[m_msw - 1] << shift;
+ if( m_msw - 1 > m_lsw )
+ {
+ m1 |= m_mant[m_msw - 2] >> ( bits_in_word - shift );
+ guard = ( m_mant[m_msw - 2] >> (bits_in_word - shift - 1) )
+ & 1;
+ }
+ }
+ }
+
+ if( exp < SCFX_IEEE_DOUBLE_E_MIN )
+ {
+ m0 |= ( 1 << mantissa0_size );
+
+ int subnormal_shift = SCFX_IEEE_DOUBLE_E_MIN - exp;
+
+ if( subnormal_shift < bits_in_word )
+ {
+ m1 = m1 >> subnormal_shift
+ | m0 << ( bits_in_word - subnormal_shift );
+ m0 = m0 >> subnormal_shift;
+ }
+ else
+ {
+ m1 = m0 >> ( subnormal_shift - bits_in_word );
+ m0 = 0;
+ }
+
+ guard = 0;
+
+ exp = SCFX_IEEE_DOUBLE_E_MIN - 1;
+ }
+
+ id.mantissa0( m0 );
+ id.mantissa1( m1 );
+ id.exponent( exp );
+ id.negative( m_sign < 0 );
+
+ double result = id;
+
+ if( guard != 0 )
+ result += m_sign * scfx_pow2( exp - SCFX_IEEE_DOUBLE_M_SIZE );
+
+ return result;
+}
+
+
+// ----------------------------------------------------------------------------
+// METHOD : to_string
+//
+// Convert from scfx_rep to character string.
+// ----------------------------------------------------------------------------
+
+void
+print_dec( scfx_string& s, const scfx_rep& num, int w_prefix, sc_fmt fmt )
+{
+ if( num.is_neg() )
+ s += '-';
+
+ if( w_prefix == 1 ) {
+ scfx_print_prefix( s, SC_DEC );
+ }
+
+ if( num.is_zero() )
+ {
+ s += '0';
+ return;
+ }
+
+ // split 'num' into its integer and fractional part
+
+ scfx_rep int_part = num;
+ scfx_rep frac_part = num;
+
+ int i;
+
+ for( i = int_part.m_lsw; i <= int_part.m_msw && i < int_part.m_wp; i ++ )
+ int_part.m_mant[i] = 0;
+ int_part.find_sw();
+ if( int_part.m_wp < int_part.m_lsw )
+ int_part.resize_to( int_part.size() - int_part.m_wp, -1 );
+
+ for( i = frac_part.m_msw;
+ i >= frac_part.m_lsw && i >= frac_part.m_wp;
+ i -- )
+ frac_part.m_mant[i] = 0;
+ frac_part.find_sw();
+ if( frac_part.m_msw == frac_part.size() - 1 )
+ frac_part.resize_to( frac_part.size() + 1, 1 );
+
+ // print integer part
+
+ int int_digits = 0;
+ int int_zeros = 0;
+
+ if( ! int_part.is_zero() )
+ {
+ double int_wl = ( int_part.m_msw - int_part.m_wp ) * bits_in_word
+ + scfx_find_msb( int_part.m_mant[int_part.m_msw] ) + 1;
+ int_digits = (int) ceil( int_wl * log10( 2. ) );
+
+ int len = s.length();
+ s.append( int_digits );
+
+ bool zero_digits = ( frac_part.is_zero() && fmt != SC_F );
+
+ for( i = int_digits + len - 1; i >= len; i-- )
+ {
+ unsigned int remainder = int_part.divide_by_ten();
+ s[i] = static_cast<char>( '0' + remainder );
+
+ if( zero_digits )
+ {
+ if( remainder == 0 )
+ int_zeros ++;
+ else
+ zero_digits = false;
+ }
+ }
+
+ // discard trailing zeros from int_part
+ s.discard( int_zeros );
+
+ if( s[len] == '0' )
+ {
+ // int_digits was overestimated by one
+ s.remove( len );
+ -- int_digits;
+ }
+ }
+
+ // print fractional part
+
+ int frac_digits = 0;
+ int frac_zeros = 0;
+
+ if( ! frac_part.is_zero() )
+ {
+ s += '.';
+
+ bool zero_digits = ( int_digits == 0 && fmt != SC_F );
+
+ double frac_wl = ( frac_part.m_wp - frac_part.m_msw ) * bits_in_word
+ - scfx_find_msb( frac_part.m_mant[frac_part.m_msw] )
+ - 1;
+ frac_zeros = (int) floor( frac_wl * log10( 2. ) );
+
+ scfx_rep temp;
+ sc_dt::multiply( temp, frac_part, pow10_fx( frac_zeros ) );
+ frac_part = temp;
+ if( frac_part.m_msw == frac_part.size() - 1 )
+ frac_part.resize_to( frac_part.size() + 1, 1 );
+
+ frac_digits = frac_zeros;
+ if( ! zero_digits )
+ {
+ for( i = 0; i < frac_zeros; i ++ )
+ s += '0';
+ frac_zeros = 0;
+ }
+
+ while( ! frac_part.is_zero() )
+ {
+ frac_part.multiply_by_ten();
+ int n = frac_part.m_mant[frac_part.m_msw + 1];
+
+ if( zero_digits )
+ {
+ if( n == 0 )
+ frac_zeros ++;
+ else
+ zero_digits = false;
+ }
+
+ if( ! zero_digits )
+ s += static_cast<char>( '0' + n );
+
+ frac_part.m_mant[frac_part.m_msw + 1] = 0;
+ frac_digits ++;
+ }
+ }
+
+ // print exponent
+
+ if( fmt != SC_F )
+ {
+ if( frac_digits == 0 )
+ scfx_print_exp( s, int_zeros );
+ else if( int_digits == 0 )
+ scfx_print_exp( s, - frac_zeros );
+ }
+}
+
+void
+print_other( scfx_string& s, const scfx_rep& a, sc_numrep numrep, int w_prefix,
+ sc_fmt fmt, const scfx_params* params )
+{
+ scfx_rep b = a;
+
+ sc_numrep numrep2 = numrep;
+
+ bool numrep_is_sm = ( numrep == SC_BIN_SM ||
+ numrep == SC_OCT_SM ||
+ numrep == SC_HEX_SM );
+
+ if( numrep_is_sm )
+ {
+ if( b.is_neg() )
+ {
+ s += '-';
+ b = *neg_scfx_rep( a );
+ }
+ switch( numrep )
+ {
+ case SC_BIN_SM:
+ numrep2 = SC_BIN_US;
+ break;
+ case SC_OCT_SM:
+ numrep2 = SC_OCT_US;
+ break;
+ case SC_HEX_SM:
+ numrep2 = SC_HEX_US;
+ break;
+ default:
+ ;
+ }
+ }
+
+ if( w_prefix != 0 ) {
+ scfx_print_prefix( s, numrep );
+ }
+
+ numrep = numrep2;
+
+ int msb, lsb;
+
+ if( params != 0 )
+ {
+ msb = params->iwl() - 1;
+ lsb = params->iwl() - params->wl();
+
+ if( params->enc() == SC_TC_ &&
+ ( numrep == SC_BIN_US ||
+ numrep == SC_OCT_US ||
+ numrep == SC_HEX_US ) &&
+ ! numrep_is_sm &&
+ params->wl() > 1 )
+ -- msb;
+ else if( params->enc() == SC_US_ &&
+ ( numrep == SC_BIN ||
+ numrep == SC_OCT ||
+ numrep == SC_HEX ||
+ numrep == SC_CSD ) )
+ ++ msb;
+ }
+ else
+ {
+ if( b.is_zero() )
+ {
+ msb = 0;
+ lsb = 0;
+ }
+ else
+ {
+ msb = ( b.m_msw - b.m_wp ) * bits_in_word
+ + scfx_find_msb( b.m_mant[ b.m_msw ] ) + 1;
+ while( b.get_bit( msb ) == b.get_bit( msb - 1 ) )
+ -- msb;
+
+ if( numrep == SC_BIN_US ||
+ numrep == SC_OCT_US ||
+ numrep == SC_HEX_US )
+ -- msb;
+
+ lsb = ( b.m_lsw - b.m_wp ) * bits_in_word
+ + scfx_find_lsb( b.m_mant[ b.m_lsw ] );
+ }
+ }
+
+ int step;
+
+ switch( numrep )
+ {
+ case SC_BIN:
+ case SC_BIN_US:
+ case SC_CSD:
+ step = 1;
+ break;
+ case SC_OCT:
+ case SC_OCT_US:
+ step = 3;
+ break;
+ case SC_HEX:
+ case SC_HEX_US:
+ step = 4;
+ break;
+ default:
+ step = 0;
+ }
+
+ msb = (int) ceil( double( msb + 1 ) / step ) * step - 1;
+
+ lsb = (int) floor( double( lsb ) / step ) * step;
+
+ if( msb < 0 )
+ {
+ s += '.';
+ if( fmt == SC_F )
+ {
+ int sign = ( b.is_neg() ) ? ( 1 << step ) - 1 : 0;
+ for( int i = ( msb + 1 ) / step; i < 0; i ++ )
+ {
+ if( sign < 10 )
+ s += static_cast<char>( sign + '0' );
+ else
+ s += static_cast<char>( sign + 'a' - 10 );
+ }
+ }
+ }
+
+ int i = msb;
+ while( i >= lsb )
+ {
+ int value = 0;
+ for( int j = step - 1; j >= 0; -- j )
+ {
+ value += static_cast<int>( b.get_bit( i ) ) << j;
+ -- i;
+ }
+ if( value < 10 )
+ s += static_cast<char>( value + '0' );
+ else
+ s += static_cast<char>( value + 'a' - 10 );
+ if( i == -1 )
+ s += '.';
+ }
+
+ if( lsb > 0 && fmt == SC_F )
+ {
+ for( int i = lsb / step; i > 0; i -- )
+ s += '0';
+ }
+
+ if( s[s.length() - 1] == '.' )
+ s.discard( 1 );
+
+ if( fmt != SC_F )
+ {
+ if( msb < 0 )
+ scfx_print_exp( s, ( msb + 1 ) / step );
+ else if( lsb > 0 )
+ scfx_print_exp( s, lsb / step );
+ }
+
+ if( numrep == SC_CSD )
+ scfx_tc2csd( s, w_prefix );
+}
+
+const char*
+scfx_rep::to_string( sc_numrep numrep, int w_prefix,
+ sc_fmt fmt, const scfx_params* params ) const
+{
+ static scfx_string s;
+
+ s.clear();
+
+ if( is_nan() )
+ scfx_print_nan( s );
+ else if( is_inf() )
+ scfx_print_inf( s, is_neg() );
+ else if( is_neg() && ! is_zero() &&
+ ( numrep == SC_BIN_US ||
+ numrep == SC_OCT_US ||
+ numrep == SC_HEX_US ) )
+ s += "negative";
+ else if( numrep == SC_DEC || numrep == SC_NOBASE )
+ sc_dt::print_dec( s, *this, w_prefix, fmt );
+ else
+ sc_dt::print_other( s, *this, numrep, w_prefix, fmt, params );
+
+ return s;
+}
+
+
+// ----------------------------------------------------------------------------
+// ADD
+//
+// add two mantissas of the same size
+// result has the same size
+// returns carry of operation
+// ----------------------------------------------------------------------------
+
+static inline
+int
+add_mants( int size, scfx_mant& result,
+ const scfx_mant& a, const scfx_mant& b )
+{
+ unsigned int carry = 0;
+
+ int index = 0;
+
+ do
+ {
+ word x = a[index];
+ word y = b[index];
+
+ y += carry;
+ carry = y < carry;
+ y += x;
+ carry += y < x;
+ result[index] = y;
+ }
+ while( ++ index < size );
+
+ return ( carry ? 1 : 0 );
+}
+
+
+static inline
+int
+sub_mants( int size, scfx_mant& result,
+ const scfx_mant& a, const scfx_mant& b )
+{
+ unsigned carry = 0;
+
+ int index = 0;
+
+ do
+ {
+ word x = a[index];
+ word y = b[index];
+
+ y += carry;
+ carry = y < carry;
+ y = x - y;
+ carry += y > x;
+ result[index] = y;
+ }
+ while( ++ index < size );
+
+ return ( carry ? 1 : 0 );
+}
+
+
+scfx_rep*
+add_scfx_rep( const scfx_rep& lhs, const scfx_rep& rhs, int max_wl )
+{
+ scfx_rep& result = *new scfx_rep;
+
+ //
+ // check for special cases
+ //
+
+ if( lhs.is_nan() || rhs.is_nan()
+ || ( lhs.is_inf() && rhs.is_inf() && lhs.m_sign != rhs.m_sign ) )
+ {
+ result.set_nan();
+ return &result;
+ }
+
+ if( lhs.is_inf() )
+ {
+ result.set_inf( lhs.m_sign );
+ return &result;
+ }
+
+ if( rhs.is_inf() )
+ {
+ result.set_inf( rhs.m_sign );
+ return &result;
+ }
+
+ //
+ // align operands if needed
+ //
+
+ scfx_mant_ref lhs_mant;
+ scfx_mant_ref rhs_mant;
+
+ int len_mant = lhs.size();
+ int new_wp = lhs.m_wp;
+
+ align( lhs, rhs, new_wp, len_mant, lhs_mant, rhs_mant );
+
+ //
+ // size the result mantissa
+ //
+
+ result.resize_to( len_mant );
+ result.m_wp = new_wp;
+
+ //
+ // do it
+ //
+
+ if( lhs.m_sign == rhs.m_sign )
+ {
+ add_mants( len_mant, result.m_mant, lhs_mant, rhs_mant );
+ result.m_sign = lhs.m_sign;
+ }
+ else
+ {
+ int cmp = compare_abs( lhs, rhs );
+
+ if( cmp == 1 )
+ {
+ sub_mants( len_mant, result.m_mant, lhs_mant, rhs_mant );
+ result.m_sign = lhs.m_sign;
+ }
+ else if ( cmp == -1 )
+ {
+ sub_mants( len_mant, result.m_mant, rhs_mant, lhs_mant );
+ result.m_sign = rhs.m_sign;
+ }
+ else
+ {
+ result.m_mant.clear();
+ result.m_sign = 1;
+ }
+ }
+
+ result.find_sw();
+ result.round( max_wl );
+
+ return &result;
+}
+
+
+// ----------------------------------------------------------------------------
+// SUB
+//
+// sub two word's of the same size
+// result has the same size
+// returns carry of operation
+// ----------------------------------------------------------------------------
+
+static inline
+int
+sub_with_index( scfx_mant& a, int a_msw, int /*a_lsw*/,
+ const scfx_mant& b, int b_msw, int b_lsw )
+{
+ unsigned carry = 0;
+
+ int size = b_msw - b_lsw;
+ int a_index = a_msw - size;
+ int b_index = b_msw - size;
+
+ do
+ {
+ word x = a[a_index];
+ word y = b[b_index];
+
+ y += carry;
+ carry = y < carry;
+ y = x - y;
+ carry += y > x;
+ a[a_index] = y;
+
+ a_index ++;
+ b_index ++;
+ }
+ while( size -- );
+
+ if( carry )
+ {
+ // special case: a[a_msw + 1 ] == 1
+ a[a_msw + 1] = 0;
+ }
+
+ return ( carry ? 1 : 0 );
+}
+
+
+scfx_rep*
+sub_scfx_rep( const scfx_rep& lhs, const scfx_rep& rhs, int max_wl )
+{
+ scfx_rep& result = *new scfx_rep;
+
+ //
+ // check for special cases
+ //
+
+ if( lhs.is_nan() || rhs.is_nan()
+ || ( lhs.is_inf() && rhs.is_inf() && lhs.m_sign == rhs.m_sign ) )
+ {
+ result.set_nan();
+ return &result;
+ }
+
+ if( lhs.is_inf() )
+ {
+ result.set_inf( lhs.m_sign );
+ return &result;
+ }
+
+ if( rhs.is_inf() )
+ {
+ result.set_inf( -1 * rhs.m_sign );
+ return &result;
+ }
+
+ //
+ // align operands if needed
+ //
+
+ scfx_mant_ref lhs_mant;
+ scfx_mant_ref rhs_mant;
+
+ int len_mant = lhs.size();
+ int new_wp = lhs.m_wp;
+
+ align( lhs, rhs, new_wp, len_mant, lhs_mant, rhs_mant );
+
+ //
+ // size the result mantissa
+ //
+
+ result.resize_to( len_mant );
+ result.m_wp = new_wp;
+
+ //
+ // do it
+ //
+
+ if( lhs.m_sign != rhs.m_sign )
+ {
+ add_mants( len_mant, result.m_mant, lhs_mant, rhs_mant );
+ result.m_sign = lhs.m_sign;
+ }
+ else
+ {
+ int cmp = compare_abs( lhs, rhs );
+
+ if( cmp == 1 )
+ {
+ sub_mants( len_mant, result.m_mant, lhs_mant, rhs_mant );
+ result.m_sign = lhs.m_sign;
+ }
+ else if ( cmp == -1 )
+ {
+ sub_mants( len_mant, result.m_mant, rhs_mant, lhs_mant );
+ result.m_sign = -rhs.m_sign;
+ } else {
+ result.m_mant.clear();
+ result.m_sign = 1;
+ }
+ }
+
+ result.find_sw();
+ result.round( max_wl );
+
+ return &result;
+}
+
+
+// ----------------------------------------------------------------------------
+// MUL
+// ----------------------------------------------------------------------------
+
+union word_short
+{
+ word l;
+ struct
+ {
+#if defined( SC_BIG_ENDIAN )
+ half_word u;
+ half_word l;
+#elif defined( SC_LITTLE_ENDIAN )
+ half_word l;
+ half_word u;
+#endif
+ } s;
+};
+
+
+#if defined( SC_BIG_ENDIAN )
+static const int half_word_incr = -1;
+#elif defined( SC_LITTLE_ENDIAN )
+static const int half_word_incr = 1;
+#endif
+
+
+void
+multiply( scfx_rep& result, const scfx_rep& lhs, const scfx_rep& rhs,
+ int max_wl )
+{
+ //
+ // check for special cases
+ //
+
+ if( lhs.is_nan() || rhs.is_nan()
+ || (lhs.is_inf() && rhs.is_zero())
+ || (lhs.is_zero() && rhs.is_inf()) )
+ {
+ result.set_nan();
+ return;
+ }
+
+ if( lhs.is_inf() || rhs.is_inf() )
+ {
+ result.set_inf( lhs.m_sign * rhs.m_sign );
+ return;
+ }
+
+ if( lhs.is_zero() || rhs.is_zero() ) {
+ result.set_zero( lhs.m_sign * rhs.m_sign );
+ return;
+ }
+
+ //
+ // do it
+ //
+
+ int len_lhs = lhs.m_msw - lhs.m_lsw + 1;
+ int len_rhs = rhs.m_msw - rhs.m_lsw + 1;
+
+ int new_size = sc_max( min_mant, len_lhs + len_rhs );
+ int new_wp = ( lhs.m_wp - lhs.m_lsw ) + ( rhs.m_wp - rhs.m_lsw );
+ int new_sign = lhs.m_sign * rhs.m_sign;
+
+ result.resize_to( new_size );
+ result.m_mant.clear();
+ result.m_wp = new_wp;
+ result.m_sign = new_sign;
+ result.m_state = scfx_rep::normal;
+
+ half_word *s1 = lhs.m_mant.half_addr( lhs.m_lsw );
+ half_word *s2 = rhs.m_mant.half_addr( rhs.m_lsw );
+
+ half_word *t = result.m_mant.half_addr();
+
+ len_lhs <<= 1;
+ len_rhs <<= 1;
+
+ int i1, i2;
+
+ for( i1 = 0; i1 * half_word_incr < len_lhs; i1 += half_word_incr )
+ {
+ word_short ls;
+ ls.l = 0;
+
+ half_word v1 = s1[i1];
+
+ for( i2 = 0; i2 * half_word_incr < len_rhs; i2 += half_word_incr )
+ {
+ ls.l += v1 * s2[i2];
+ ls.s.l = ls.s.u + ( ( t[i2] += ls.s.l ) < ls.s.l );
+ ls.s.u = 0;
+ }
+
+ t[i2] = ls.s.l;
+ t += half_word_incr;
+ }
+
+ result.find_sw();
+ result.round( max_wl );
+}
+
+
+// ----------------------------------------------------------------------------
+// DIV
+// ----------------------------------------------------------------------------
+
+scfx_rep*
+div_scfx_rep( const scfx_rep& lhs, const scfx_rep& rhs, int div_wl )
+{
+ scfx_rep& result = *new scfx_rep;
+
+ //
+ // check for special cases
+ //
+
+ if( lhs.is_nan() || rhs.is_nan() || (lhs.is_inf() && rhs.is_inf()) ||
+ (lhs.is_zero() && rhs.is_zero()) )
+ {
+ result.set_nan();
+ return &result;
+ }
+
+ if( lhs.is_inf() || rhs.is_zero() )
+ {
+ result.set_inf( lhs.m_sign * rhs.m_sign );
+ return &result;
+ }
+
+ if( lhs.is_zero() || rhs.is_inf() )
+ {
+ result.set_zero( lhs.m_sign * rhs.m_sign );
+ return &result;
+ }
+
+ //
+ // do it
+ //
+
+ // compute one bit more for rounding
+ div_wl ++;
+
+ result.resize_to( sc_max( n_word( div_wl ) + 1, min_mant ) );
+ result.m_mant.clear();
+ result.m_sign = lhs.m_sign * rhs.m_sign;
+
+ int msb_lhs = scfx_find_msb( lhs.m_mant[lhs.m_msw] )
+ + ( lhs.m_msw - lhs.m_wp ) * bits_in_word;
+ int msb_rhs = scfx_find_msb( rhs.m_mant[rhs.m_msw] )
+ + ( rhs.m_msw - rhs.m_wp ) * bits_in_word;
+
+ int msb_res = msb_lhs - msb_rhs;
+ int to_shift = -msb_res % bits_in_word;
+ int result_index;
+
+ int c = ( msb_res % bits_in_word >= 0 ) ? 1 : 0;
+
+ result_index = (result.size() - c) * bits_in_word + msb_res % bits_in_word;
+ result.m_wp = (result.size() - c) - msb_res / bits_in_word;
+
+ scfx_rep remainder = lhs;
+
+ // align msb from remainder to msb from rhs
+ remainder.lshift( to_shift );
+
+ // make sure msw( remainder ) < size - 1
+ if( remainder.m_msw == remainder.size() - 1 )
+ remainder.resize_to( remainder.size() + 1, 1 );
+
+ // make sure msw( remainder ) >= msw( rhs )!
+ int msw_diff = rhs.m_msw - remainder.m_msw;
+ if (msw_diff > 0)
+ remainder.resize_to( remainder.size() + msw_diff, -1 );
+
+ int counter;
+
+ for( counter = div_wl; counter && ! remainder.is_zero(); counter -- )
+ {
+ if( compare_msw_ff( rhs, remainder ) <= 0 )
+ {
+ result.set_bin( result_index );
+ sub_with_index( remainder.m_mant, remainder.m_msw, remainder.m_lsw,
+ rhs.m_mant, rhs.m_msw, rhs.m_lsw );
+ }
+ result_index --;
+ remainder.shift_left( 1 );
+ remainder.m_lsw = remainder.find_lsw();
+ }
+
+ // perform convergent rounding, if needed
+ if( counter == 0 )
+ {
+ int index = result_index + 1 - result.m_wp * bits_in_word;
+
+ scfx_index x = result.calc_indices( index );
+ scfx_index x1 = result.calc_indices( index + 1 );
+
+ if( result.o_bit_at( x ) && result.o_bit_at( x1 ) )
+ result.q_incr( x );
+
+ result.m_r_flag = true;
+ }
+
+ result.find_sw();
+
+ return &result;
+}
+
+
+// ----------------------------------------------------------------------------
+// destructive shift mantissa to the left
+// ----------------------------------------------------------------------------
+
+void
+scfx_rep::lshift( int n )
+{
+ if( n == 0 )
+ return;
+
+ if( n < 0 )
+ {
+ rshift( -n );
+ return;
+ }
+
+ if( is_normal() )
+ {
+ int shift_bits = n % bits_in_word;
+ int shift_words = n / bits_in_word;
+
+ // resize if needed
+ if( m_msw == size() - 1 &&
+ scfx_find_msb( m_mant[m_msw] ) >= bits_in_word - shift_bits )
+ resize_to( size() + 1, 1 );
+
+ // do it
+ m_wp -= shift_words;
+ shift_left( shift_bits );
+ find_sw();
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// destructive shift mantissa to the right
+// ----------------------------------------------------------------------------
+
+void
+scfx_rep::rshift( int n )
+{
+ if( n == 0 )
+ return;
+
+ if( n < 0 )
+ {
+ lshift( -n );
+ return;
+ }
+
+ if( is_normal() )
+ {
+ int shift_bits = n % bits_in_word;
+ int shift_words = n / bits_in_word;
+
+ // resize if needed
+ if( m_lsw == 0 && scfx_find_lsb( m_mant[m_lsw] ) < shift_bits )
+ resize_to( size() + 1, -1 );
+
+ // do it
+ m_wp += shift_words;
+ shift_right( shift_bits );
+ find_sw();
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// FRIEND FUNCTION : compare_abs
+//
+// Compares the absolute values of two scfx_reps, excluding the special cases.
+// ----------------------------------------------------------------------------
+
+int
+compare_abs( const scfx_rep& a, const scfx_rep& b )
+{
+ // check for zero
+
+ word a_word = a.m_mant[a.m_msw];
+ word b_word = b.m_mant[b.m_msw];
+
+ if( a_word == 0 || b_word == 0 )
+ {
+ if( a_word != 0 )
+ return 1;
+ if( b_word != 0 )
+ return -1;
+ return 0;
+ }
+
+ // compare msw index
+
+ int a_msw = a.m_msw - a.m_wp;
+ int b_msw = b.m_msw - b.m_wp;
+
+ if( a_msw > b_msw )
+ return 1;
+
+ if( a_msw < b_msw )
+ return -1;
+
+ // compare content
+
+ int a_i = a.m_msw;
+ int b_i = b.m_msw;
+
+ while( a_i >= a.m_lsw && b_i >= b.m_lsw )
+ {
+ a_word = a.m_mant[a_i];
+ b_word = b.m_mant[b_i];
+ if( a_word > b_word )
+ return 1;
+ if( a_word < b_word )
+ return -1;
+ -- a_i;
+ -- b_i;
+ }
+
+ bool a_zero = true;
+ while( a_i >= a.m_lsw )
+ {
+ a_zero = a_zero && ( a.m_mant[a_i] == 0 );
+ -- a_i;
+ }
+
+ bool b_zero = true;
+ while( b_i >= b.m_lsw )
+ {
+ b_zero = b_zero && ( b.m_mant[b_i] == 0 );
+ -- b_i;
+ }
+
+ // assertion: a_zero || b_zero == true
+
+ if( ! a_zero && b_zero )
+ return 1;
+
+ if( a_zero && ! b_zero )
+ return -1;
+
+ return 0;
+}
+
+
+// ----------------------------------------------------------------------------
+// FRIEND FUNCTION : cmp_scfx_rep
+//
+// Compares the values of two scfx_reps, including the special cases.
+// ----------------------------------------------------------------------------
+
+int
+cmp_scfx_rep( const scfx_rep& a, const scfx_rep& b )
+{
+ // handle special cases
+
+ if( a.is_nan() || b.is_nan() )
+ {
+#if 0
+ if( a.is_nan() && b.is_nan() )
+ {
+ return 0;
+ }
+#endif
+ return 2;
+ }
+
+ if( a.is_inf() || b.is_inf() )
+ {
+ if( a.is_inf() )
+ {
+ if( ! a.is_neg() )
+ {
+ if( b.is_inf() && ! b.is_neg() )
+ {
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+ }
+ else
+ {
+ if( b.is_inf() && b.is_neg() )
+ {
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+ }
+ }
+ if( b.is_inf() )
+ {
+ if( ! b.is_neg() )
+ {
+ return -1;
+ }
+ else
+ {
+ return 1;
+ }
+ }
+ }
+
+ if( a.is_zero() && b.is_zero() )
+ {
+ return 0;
+ }
+
+ // compare sign
+
+ if( a.m_sign != b.m_sign )
+ {
+ return a.m_sign;
+ }
+
+ return ( a.m_sign * compare_abs( a, b ) );
+}
+
+
+// ----------------------------------------------------------------------------
+// PRIVATE METHOD : quantization
+//
+// Performs destructive quantization.
+// ----------------------------------------------------------------------------
+
+void
+scfx_rep::quantization( const scfx_params& params, bool& q_flag )
+{
+ scfx_index x = calc_indices( params.iwl() - params.wl() );
+
+ if( x.wi() < 0 )
+ return;
+
+ if( x.wi() >= size() )
+ resize_to( x.wi() + 1, 1 );
+
+ bool qb = q_bit( x );
+ bool qz = q_zero( x );
+
+ q_flag = ( qb || ! qz );
+
+ if( q_flag )
+ {
+ switch( params.q_mode() )
+ {
+ case SC_TRN: // truncation
+ {
+ if( is_neg() )
+ q_incr( x );
+ break;
+ }
+ case SC_RND: // rounding to plus infinity
+ {
+ if( ! is_neg() )
+ {
+ if( qb )
+ q_incr( x );
+ }
+ else
+ {
+ if( qb && ! qz )
+ q_incr( x );
+ }
+ break;
+ }
+ case SC_TRN_ZERO: // truncation to zero
+ {
+ break;
+ }
+ case SC_RND_INF: // rounding to infinity
+ {
+ if( qb )
+ q_incr( x );
+ break;
+ }
+ case SC_RND_CONV: // convergent rounding
+ {
+ if( (qb && ! qz) || (qb && qz && q_odd( x )) )
+ q_incr( x );
+ break;
+ }
+ case SC_RND_ZERO: // rounding to zero
+ {
+ if( qb && ! qz )
+ q_incr( x );
+ break;
+ }
+ case SC_RND_MIN_INF: // rounding to minus infinity
+ {
+ if( ! is_neg() )
+ {
+ if( qb && ! qz )
+ q_incr( x );
+ }
+ else
+ {
+ if( qb )
+ q_incr( x );
+ }
+ break;
+ }
+ default:
+ ;
+ }
+ q_clear( x );
+
+ find_sw();
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// PRIVATE METHOD : overflow
+//
+// Performs destructive overflow handling.
+// ----------------------------------------------------------------------------
+
+void
+scfx_rep::overflow( const scfx_params& params, bool& o_flag )
+{
+ scfx_index x = calc_indices( params.iwl() - 1 );
+
+ if( x.wi() >= size() )
+ resize_to( x.wi() + 1, 1 );
+
+ if( x.wi() < 0 )
+ {
+ resize_to( size() - x.wi(), -1 );
+ x.wi( 0 );
+ }
+
+ bool zero_left = o_zero_left( x );
+ bool bit_at = o_bit_at( x );
+ bool zero_right = o_zero_right( x );
+
+ bool under = false;
+ bool over = false;
+
+ sc_enc enc = params.enc();
+
+ if( enc == SC_TC_ )
+ {
+ if( is_neg() )
+ {
+ if( params.o_mode() == SC_SAT_SYM )
+ under = ( ! zero_left || bit_at );
+ else
+ under = (! zero_left || (zero_left && bit_at && ! zero_right));
+ }
+ else
+ over = ( ! zero_left || bit_at );
+ }
+ else
+ {
+ if( is_neg() )
+ under = ( ! is_zero() );
+ else
+ over = ( ! zero_left );
+ }
+
+ o_flag = ( under || over );
+
+ if( o_flag )
+ {
+ scfx_index x2 = calc_indices( params.iwl() - params.wl() );
+
+ if( x2.wi() < 0 )
+ {
+ resize_to( size() - x2.wi(), -1 );
+ x.wi( x.wi() - x2.wi() );
+ x2.wi( 0 );
+ }
+
+ switch( params.o_mode() )
+ {
+ case SC_WRAP: // wrap-around
+ {
+ int n_bits = params.n_bits();
+
+ if( n_bits == 0 )
+ {
+ // wrap-around all 'wl' bits
+ toggle_tc();
+ o_extend( x, enc );
+ toggle_tc();
+ }
+ else if( n_bits < params.wl() )
+ {
+ scfx_index x3 = calc_indices( params.iwl() - 1 - n_bits );
+
+ // wrap-around least significant 'wl - n_bits' bits;
+ // saturate most significant 'n_bits' bits
+ toggle_tc();
+ o_set( x, x3, enc, under );
+ o_extend( x, enc );
+ toggle_tc();
+ }
+ else
+ {
+ // saturate all 'wl' bits
+ if( under )
+ o_set_low( x, enc );
+ else
+ o_set_high( x, x2, enc );
+ }
+ break;
+ }
+ case SC_SAT: // saturation
+ {
+ if( under )
+ o_set_low( x, enc );
+ else
+ o_set_high( x, x2, enc );
+ break;
+ }
+ case SC_SAT_SYM: // symmetrical saturation
+ {
+ if( under )
+ {
+ if( enc == SC_TC_ )
+ o_set_high( x, x2, SC_TC_, -1 );
+ else
+ o_set_low( x, SC_US_ );
+ }
+ else
+ o_set_high( x, x2, enc );
+ break;
+ }
+ case SC_SAT_ZERO: // saturation to zero
+ {
+ set_zero();
+ break;
+ }
+ case SC_WRAP_SM: // sign magnitude wrap-around
+ {
+ SC_ERROR_IF_( enc == SC_US_,
+ sc_core::SC_ID_WRAP_SM_NOT_DEFINED_ );
+
+ int n_bits = params.n_bits();
+
+ if( n_bits == 0 )
+ {
+ scfx_index x4 = calc_indices( params.iwl() );
+
+ if( x4.wi() >= size() )
+ resize_to( x4.wi() + 1, 1 );
+
+ toggle_tc();
+ if( o_bit_at( x4 ) != o_bit_at( x ) )
+ o_invert( x2 );
+ o_extend( x, SC_TC_ );
+ toggle_tc();
+ }
+ else if( n_bits == 1 )
+ {
+ toggle_tc();
+ if( is_neg() != o_bit_at( x ) )
+ o_invert( x2 );
+ o_extend( x, SC_TC_ );
+ toggle_tc();
+ }
+ else if( n_bits < params.wl() )
+ {
+ scfx_index x3 = calc_indices( params.iwl() - 1 - n_bits );
+ scfx_index x4 = calc_indices( params.iwl() - n_bits );
+
+ // wrap-around least significant 'wl - n_bits' bits;
+ // saturate most significant 'n_bits' bits
+ toggle_tc();
+ if( is_neg() == o_bit_at( x4 ) )
+ o_invert( x2 );
+ o_set( x, x3, SC_TC_, under );
+ o_extend( x, SC_TC_ );
+ toggle_tc();
+ }
+ else
+ {
+ if( under )
+ o_set_low( x, SC_TC_ );
+ else
+ o_set_high( x, x2, SC_TC_ );
+ }
+ break;
+ }
+ default:
+ ;
+ }
+
+ find_sw();
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// PUBLIC METHOD : cast
+//
+// Performs a destructive cast operation on a scfx_rep.
+// ----------------------------------------------------------------------------
+
+void
+scfx_rep::cast( const scfx_params& params, bool& q_flag, bool& o_flag )
+{
+ q_flag = false;
+ o_flag = false;
+
+ // check for special cases
+
+ if( is_zero() )
+ {
+ if( is_neg() )
+ m_sign = 1;
+ return;
+ }
+
+ // perform casting
+
+ quantization( params, q_flag );
+ overflow( params, o_flag );
+
+ // check for special case: -0
+
+ if( is_zero() && is_neg() )
+ m_sign = 1;
+}
+
+
+// ----------------------------------------------------------------------------
+// make sure, the two mantissas are aligned
+// ----------------------------------------------------------------------------
+
+void
+align( const scfx_rep& lhs, const scfx_rep& rhs, int& new_wp,
+ int& len_mant, scfx_mant_ref& lhs_mant, scfx_mant_ref& rhs_mant )
+{
+ bool need_lhs = true;
+ bool need_rhs = true;
+
+ if( lhs.m_wp != rhs.m_wp || lhs.size() != rhs.size() )
+ {
+ int lower_bound_lhs = lhs.m_lsw - lhs.m_wp;
+ int upper_bound_lhs = lhs.m_msw - lhs.m_wp;
+ int lower_bound_rhs = rhs.m_lsw - rhs.m_wp;
+ int upper_bound_rhs = rhs.m_msw - rhs.m_wp;
+
+ int lower_bound = sc_min( lower_bound_lhs, lower_bound_rhs );
+ int upper_bound = sc_max( upper_bound_lhs, upper_bound_rhs );
+
+ new_wp = -lower_bound;
+ len_mant = sc_max( min_mant, upper_bound - lower_bound + 1 );
+
+ if( new_wp != lhs.m_wp || len_mant != lhs.size() )
+ {
+ lhs_mant = lhs.resize( len_mant, new_wp );
+ need_lhs = false;
+ }
+
+ if( new_wp != rhs.m_wp || len_mant != rhs.size() )
+ {
+ rhs_mant = rhs.resize( len_mant, new_wp );
+ need_rhs = false;
+ }
+ }
+
+ if( need_lhs )
+ {
+ lhs_mant = lhs.m_mant;
+ }
+
+ if( need_rhs )
+ {
+ rhs_mant = rhs.m_mant;
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// compare two mantissas
+// ----------------------------------------------------------------------------
+
+int
+compare_msw_ff( const scfx_rep& lhs, const scfx_rep& rhs )
+{
+ // special case: rhs.m_mant[rhs.m_msw + 1] == 1
+ if( rhs.m_msw < rhs.size() - 1 && rhs.m_mant[rhs.m_msw + 1 ] != 0 )
+ {
+ return -1;
+ }
+
+ int lhs_size = lhs.m_msw - lhs.m_lsw + 1;
+ int rhs_size = rhs.m_msw - rhs.m_lsw + 1;
+
+ int size = sc_min( lhs_size, rhs_size );
+
+ int lhs_index = lhs.m_msw;
+ int rhs_index = rhs.m_msw;
+
+ int i;
+
+ for( i = 0;
+ i < size && lhs.m_mant[lhs_index] == rhs.m_mant[rhs_index];
+ i ++ )
+ {
+ lhs_index --;
+ rhs_index --;
+ }
+
+ if( i == size )
+ {
+ if( lhs_size == rhs_size )
+ {
+ return 0;
+ }
+
+ if( lhs_size < rhs_size )
+ {
+ return -1;
+ }
+ else
+ {
+ return 1;
+ }
+ }
+
+ if( lhs.m_mant[lhs_index] < rhs.m_mant[rhs_index] )
+ {
+ return -1;
+ } else {
+ return 1;
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// divide the mantissa by ten
+// ----------------------------------------------------------------------------
+
+unsigned int
+scfx_rep::divide_by_ten()
+{
+#if defined( SC_BIG_ENDIAN )
+ half_word* hw = (half_word*) &m_mant[m_msw];
+#elif defined( SC_LITTLE_ENDIAN )
+ half_word* hw = ( (half_word*) &m_mant[m_msw] ) + 1;
+#endif
+
+ unsigned int remainder = 0;
+
+ word_short ls;
+ ls.l = 0;
+
+#if defined( SC_BIG_ENDIAN )
+ for( int i = 0, end = ( m_msw - m_wp + 1 ) * 2; i < end; i ++ )
+#elif defined( SC_LITTLE_ENDIAN )
+ for( int i = 0, end = -( m_msw - m_wp + 1 ) * 2; i > end; i -- )
+#endif
+ {
+ ls.s.u = static_cast<half_word>( remainder );
+ ls.s.l = hw[i];
+ remainder = ls.l % 10;
+ ls.l /= 10;
+ hw[i] = ls.s.l;
+ }
+
+ return remainder;
+}
+
+
+// ----------------------------------------------------------------------------
+// multiply the mantissa by ten
+// ----------------------------------------------------------------------------
+
+void
+scfx_rep::multiply_by_ten()
+{
+ int size = m_mant.size() + 1;
+
+ scfx_mant mant8( size );
+ scfx_mant mant2( size );
+
+ size --;
+
+ mant8[size] = (m_mant[size - 1] >> (bits_in_word - 3));
+ mant2[size] = (m_mant[size - 1] >> (bits_in_word - 1));
+
+ while( -- size )
+ {
+ mant8[size] = ( m_mant[size] << 3 ) |
+ ( m_mant[size - 1] >> ( bits_in_word - 3 ) );
+ mant2[size] = ( m_mant[size] << 1 ) |
+ ( m_mant[size - 1] >> ( bits_in_word - 1 ) );
+ }
+
+ mant8[0] = ( m_mant[0] << 3 );
+ mant2[0] = ( m_mant[0] << 1 );
+
+ add_mants( m_mant.size(), m_mant, mant8, mant2 );
+
+#if 0
+ for( int i = size() - 1; i > 0; i -- )
+ {
+ m_mant[i] = ( m_mant[i] << 3 ) |
+ ( m_mant[i-1] >> ( bits_in_word - 3 ) )
+ + ( m_mant[i] << 1 ) |
+ ( m_mant[i-1] >> ( bits_in_word - 1 ) );
+ }
+ m_mant[0] = ( m_mant[0] << 3 ) + ( m_mant[0] << 1 );
+#endif
+}
+
+
+// ----------------------------------------------------------------------------
+// normalize
+// ----------------------------------------------------------------------------
+
+void
+scfx_rep::normalize( int exponent )
+{
+ int shift = exponent % bits_in_word;
+ if( shift < 0 )
+ {
+ shift += bits_in_word;
+ }
+
+ if( shift )
+ {
+ shift_left( shift );
+ }
+
+ find_sw();
+
+ m_wp = (shift - exponent) / bits_in_word;
+}
+
+
+// ----------------------------------------------------------------------------
+// return a new mantissa that is aligned and resized
+// ----------------------------------------------------------------------------
+
+scfx_mant*
+scfx_rep::resize( int new_size, int new_wp ) const
+{
+ scfx_mant *result = new scfx_mant( new_size );
+
+ result->clear();
+
+ int shift = new_wp - m_wp;
+
+ for( int j = m_lsw; j <= m_msw; j ++ )
+ {
+ (*result)[j+shift] = m_mant[j];
+ }
+
+ return result;
+}
+
+
+// ----------------------------------------------------------------------------
+// set a single bit
+// ----------------------------------------------------------------------------
+
+void
+scfx_rep::set_bin( int i )
+{
+ m_mant[i >> 5] |= 1 << ( i & 31 );
+}
+
+
+// ----------------------------------------------------------------------------
+// set three bits
+// ----------------------------------------------------------------------------
+
+void
+scfx_rep::set_oct( int i, int n )
+{
+ if( n & 1 )
+ {
+ m_mant[i >> 5] |= 1 << ( i & 31 );
+ }
+ i ++;
+ if( n & 2 )
+ {
+ m_mant[i >> 5] |= 1 << ( i & 31 );
+ }
+ i ++;
+ if( n & 4 )
+ {
+ m_mant[i >> 5] |= 1 << ( i & 31 );
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// set four bits
+// ----------------------------------------------------------------------------
+
+void
+scfx_rep::set_hex( int i, int n )
+{
+ if( n & 1 )
+ {
+ m_mant[i >> 5] |= 1 << ( i & 31 );
+ }
+ i ++;
+ if( n & 2 )
+ {
+ m_mant[i >> 5] |= 1 << ( i & 31 );
+ }
+ i ++;
+ if( n & 4 )
+ {
+ m_mant[i >> 5] |= 1 << ( i & 31 );
+ }
+ i ++;
+ if( n & 8 )
+ {
+ m_mant[i >> 5] |= 1 << ( i & 31 );
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// PRIVATE METHOD : shift_left
+//
+// Shifts a scfx_rep to the left by a MAXIMUM of bits_in_word - 1 bits.
+// ----------------------------------------------------------------------------
+
+void
+scfx_rep::shift_left( int n )
+{
+ if( n != 0 )
+ {
+ int shift_left = n;
+ int shift_right = bits_in_word - n;
+
+ SC_ASSERT_( !(m_mant[size()-1] >> shift_right),
+ "shift_left overflow" );
+
+ for( int i = size() - 1; i > 0; i -- )
+ {
+ m_mant[i] = ( m_mant[i] << shift_left ) |
+ ( m_mant[i-1] >> shift_right );
+ }
+ m_mant[0] <<= shift_left;
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// PRIVATE METHOD : shift_right
+//
+// Shifts a scfx_rep to the right by a MAXIMUM of bits_in_word - 1 bits.
+// ----------------------------------------------------------------------------
+
+void
+scfx_rep::shift_right( int n )
+{
+ if( n != 0 )
+ {
+ int shift_left = bits_in_word - n;
+ int shift_right = n;
+
+ SC_ASSERT_( !(m_mant[0] << shift_left), "shift_right overflow" );
+
+ for( int i = 0; i < size() - 1; i ++ )
+ {
+ m_mant[i] = ( m_mant[i] >> shift_right ) |
+ ( m_mant[i+1] << shift_left );
+ }
+ m_mant[size()-1] >>= shift_right;
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// METHOD : get_bit
+//
+// Tests a bit, in two's complement.
+// ----------------------------------------------------------------------------
+
+bool
+scfx_rep::get_bit( int i ) const
+{
+ if( ! is_normal() )
+ return false;
+
+ scfx_index x = calc_indices( i );
+
+ if( x.wi() >= size() )
+ return is_neg();
+
+ if( x.wi() < 0 )
+ return false;
+
+ const_cast<scfx_rep*>( this )->toggle_tc();
+
+ bool result = ( m_mant[x.wi()] & ( 1 << x.bi() ) ) != 0;
+
+ const_cast<scfx_rep*>( this )->toggle_tc();
+
+ return result;
+}
+
+
+// ----------------------------------------------------------------------------
+// METHOD : set
+//
+// Sets a bit, in two's complement, between iwl-1 and -fwl.
+// ----------------------------------------------------------------------------
+
+bool
+scfx_rep::set( int i, const scfx_params& params )
+{
+ if( ! is_normal() )
+ return false;
+
+ scfx_index x = calc_indices( i );
+
+ if( x.wi() >= size() )
+ {
+ if( is_neg() )
+ return true;
+ else
+ resize_to( x.wi() + 1, 1 );
+ }
+ else if( x.wi() < 0 )
+ {
+ resize_to( size() - x.wi(), -1 );
+ x.wi( 0 );
+ }
+
+ toggle_tc();
+
+ m_mant[x.wi()] |= 1 << x.bi();
+
+ if( i == params.iwl() - 1 )
+ o_extend( x, params.enc() ); // sign extension
+
+ toggle_tc();
+
+ find_sw();
+
+ return true;
+}
+
+
+// ----------------------------------------------------------------------------
+// METHOD : clear
+//
+// Clears a bit, in two's complement, between iwl-1 and -fwl.
+// ----------------------------------------------------------------------------
+
+bool
+scfx_rep::clear( int i, const scfx_params& params )
+{
+ if( ! is_normal() )
+ return false;
+
+ scfx_index x = calc_indices( i );
+
+ if( x.wi() >= size() )
+ {
+ if( ! is_neg() )
+ return true;
+ else
+ resize_to( x.wi() + 1, 1 );
+ }
+ else if( x.wi() < 0 )
+ return true;
+
+ toggle_tc();
+
+ m_mant[x.wi()] &= ~( 1 << x.bi() );
+
+ if( i == params.iwl() - 1 )
+ o_extend( x, params.enc() ); // sign extension
+
+ toggle_tc();
+
+ find_sw();
+
+ return true;
+}
+
+
+// ----------------------------------------------------------------------------
+// METHOD : get_slice
+// ----------------------------------------------------------------------------
+
+bool
+scfx_rep::get_slice( int i, int j, const scfx_params&,
+ sc_bv_base& bv ) const
+{
+ if( is_nan() || is_inf() )
+ return false;
+
+ // get the bits
+
+ int l = j;
+ for( int k = 0; k < bv.length(); ++ k )
+ {
+ bv[k] = get_bit( l );
+
+ if( i >= j )
+ ++ l;
+ else
+ -- l;
+ }
+
+ return true;
+}
+
+bool
+scfx_rep::set_slice( int i, int j, const scfx_params& params,
+ const sc_bv_base& bv )
+{
+ if( is_nan() || is_inf() )
+ return false;
+
+ // set the bits
+
+ int l = j;
+ for( int k = 0; k < bv.length(); ++ k )
+ {
+ if( bv[k].to_bool() )
+ set( l, params );
+ else
+ clear( l, params );
+
+ if( i >= j )
+ ++ l;
+ else
+ -- l;
+ }
+
+ return true;
+}
+
+
+// ----------------------------------------------------------------------------
+// METHOD : print
+// ----------------------------------------------------------------------------
+
+void
+scfx_rep::print( ::std::ostream& os ) const
+{
+ os << to_string( SC_DEC, -1, SC_E );
+}
+
+
+// ----------------------------------------------------------------------------
+// METHOD : dump
+// ----------------------------------------------------------------------------
+
+void
+scfx_rep::dump( ::std::ostream& os ) const
+{
+ os << "scfx_rep" << ::std::endl;
+ os << "(" << ::std::endl;
+
+ os << "mant =" << ::std::endl;
+ for( int i = size() - 1; i >= 0; i -- )
+ {
+ char buf[BUFSIZ];
+ std::sprintf( buf, " %d: %10u (%8x)", i, (int) m_mant[i], (int) m_mant[i] );
+ os << buf << ::std::endl;
+ }
+
+ os << "wp = " << m_wp << ::std::endl;
+ os << "sign = " << m_sign << ::std::endl;
+
+ os << "state = ";
+ switch( m_state )
+ {
+ case normal:
+ os << "normal";
+ break;
+ case infinity:
+ os << "infinity";
+ break;
+ case not_a_number:
+ os << "not_a_number";
+ break;
+ default:
+ os << "unknown";
+ }
+ os << ::std::endl;
+
+ os << "msw = " << m_msw << ::std::endl;
+ os << "lsw = " << m_lsw << ::std::endl;
+
+ os << ")" << ::std::endl;
+}
+
+
+// ----------------------------------------------------------------------------
+// METHOD : get_type
+// ----------------------------------------------------------------------------
+
+void
+scfx_rep::get_type( int& wl, int& iwl, sc_enc& enc ) const
+{
+ if( is_nan() || is_inf() )
+ {
+ wl = 0;
+ iwl = 0;
+ enc = SC_TC_;
+ return;
+ }
+
+ if( is_zero() )
+ {
+ wl = 1;
+ iwl = 1;
+ enc = SC_US_;
+ return;
+ }
+
+ int msb = ( m_msw - m_wp ) * bits_in_word
+ + scfx_find_msb( m_mant[ m_msw ] ) + 1;
+ while( get_bit( msb ) == get_bit( msb - 1 ) )
+ {
+ -- msb;
+ }
+
+ int lsb = ( m_lsw - m_wp ) * bits_in_word
+ + scfx_find_lsb( m_mant[ m_lsw ] );
+
+ if( is_neg() )
+ {
+ wl = msb - lsb + 1;
+ iwl = msb + 1;
+ enc = SC_TC_;
+ }
+ else
+ {
+ wl = msb - lsb;
+ iwl = msb;
+ enc = SC_US_;
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// PRIVATE METHOD : round
+//
+// Performs convergent rounding (rounding to even) as in floating-point.
+// ----------------------------------------------------------------------------
+
+void
+scfx_rep::round( int wl )
+{
+ // check for special cases
+
+ if( is_nan() || is_inf() || is_zero() )
+ return;
+
+ // estimate effective wordlength and compare
+
+ int wl_effective;
+
+ wl_effective = ( m_msw - m_lsw + 1 ) * bits_in_word;
+ if( wl_effective <= wl )
+ return;
+
+ // calculate effective wordlength and compare
+
+ int msb = scfx_find_msb( m_mant[m_msw] );
+ int lsb = scfx_find_lsb( m_mant[m_lsw] );
+
+ wl_effective = ( m_msw * bits_in_word + msb ) -
+ ( m_lsw * bits_in_word + lsb ) + 1;
+ if( wl_effective <= wl )
+ return;
+
+ // perform rounding
+
+ int wi = m_msw - ( wl - 1 ) / bits_in_word;
+ int bi = msb - ( wl - 1 ) % bits_in_word;
+ if( bi < 0 )
+ {
+ -- wi;
+ bi += bits_in_word;
+ }
+
+ scfx_index x( wi, bi );
+
+ if( (q_bit( x ) && ! q_zero( x )) ||
+ (q_bit( x ) && q_zero( x ) && q_odd( x )) )
+ q_incr( x );
+ q_clear( x );
+
+ find_sw();
+
+ m_r_flag = true;
+}
+
+} // namespace sc_dt
+
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_rep.h b/ext/systemc/src/sysc/datatypes/fx/scfx_rep.h
new file mode 100644
index 000000000..c5b76ce54
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/scfx_rep.h
@@ -0,0 +1,842 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ scfx_rep.h -
+
+ Original Author: Robert Graulich, Synopsys, Inc.
+ Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: scfx_rep.h,v $
+// Revision 1.6 2011/08/24 22:05:43 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.5 2011/07/25 10:20:29 acg
+// Andy Goodrich: check in aftermath of call to automake.
+//
+// Revision 1.4 2010/12/07 20:09:08 acg
+// Andy Goodrich: Philipp Hartmann's constructor disambiguation fix
+//
+// Revision 1.3 2010/08/03 15:54:52 acg
+// Andy Goodrich: formatting.
+//
+// Revision 1.2 2010/03/15 18:29:01 acg
+// Andy Goodrich: Moved default argument specifications from friend
+// declarations to the actual function signatures.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.4 2006/03/13 20:24:27 acg
+// Andy Goodrich: Addition of function declarations, e.g., neg_scfx_rep(),
+// to keep gcc 4.x happy.
+//
+// Revision 1.3 2006/01/13 18:53:58 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#ifndef SCFX_REP_H
+#define SCFX_REP_H
+
+
+#include <climits>
+
+#include "sysc/datatypes/fx/scfx_mant.h"
+#include "sysc/datatypes/fx/scfx_params.h"
+#include "sysc/datatypes/fx/scfx_string.h"
+
+
+namespace sc_dt
+{
+
+// classes defined in this module
+class scfx_index;
+class scfx_rep;
+
+// forward class declarations
+class sc_bv_base;
+class sc_signed;
+class sc_unsigned;
+
+// function declarations
+void multiply( scfx_rep&, const scfx_rep&, const scfx_rep&,
+ int max_wl = SC_DEFAULT_MAX_WL_ );
+scfx_rep* neg_scfx_rep( const scfx_rep& );
+scfx_rep* mult_scfx_rep( const scfx_rep&, const scfx_rep&,
+ int max_wl = SC_DEFAULT_MAX_WL_ );
+scfx_rep* div_scfx_rep( const scfx_rep&, const scfx_rep&,
+ int max_wl = SC_DEFAULT_DIV_WL_ );
+scfx_rep* add_scfx_rep( const scfx_rep&, const scfx_rep&,
+ int max_wl = SC_DEFAULT_MAX_WL_ );
+scfx_rep* sub_scfx_rep( const scfx_rep&, const scfx_rep&,
+ int max_wl = SC_DEFAULT_MAX_WL_ );
+scfx_rep* lsh_scfx_rep( const scfx_rep&, int );
+scfx_rep* rsh_scfx_rep( const scfx_rep&, int );
+int cmp_scfx_rep( const scfx_rep&, const scfx_rep& );
+
+
+const int min_mant = 4;
+
+const int bits_in_int = sizeof(int) * CHAR_BIT;
+const int bits_in_word = sizeof(word) * CHAR_BIT;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : scfx_index
+// ----------------------------------------------------------------------------
+
+class scfx_index
+{
+
+public:
+
+ scfx_index( int wi_, int bi_ ) : m_wi( wi_ ), m_bi( bi_ ) {}
+
+ int wi() const { return m_wi; }
+ int bi() const { return m_bi; }
+
+ void wi( int wi_ ) { m_wi = wi_; }
+
+private:
+
+ int m_wi;
+ int m_bi;
+
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : scfx_rep
+//
+// Arbitrary-precision fixed-point implementation class.
+// ----------------------------------------------------------------------------
+
+class scfx_rep
+{
+ enum state
+ {
+ normal,
+ infinity,
+ not_a_number
+ };
+
+public:
+
+ // constructors
+
+ scfx_rep();
+ explicit scfx_rep( int );
+ explicit scfx_rep( unsigned int );
+ explicit scfx_rep( long );
+ explicit scfx_rep( unsigned long );
+ explicit scfx_rep( double );
+ explicit scfx_rep( const char* );
+ explicit scfx_rep( int64 );
+ explicit scfx_rep( uint64 );
+ explicit scfx_rep( const sc_signed& );
+ explicit scfx_rep( const sc_unsigned& );
+
+
+ // copy constructor
+
+ scfx_rep( const scfx_rep& );
+
+
+ // destructor
+
+ ~scfx_rep();
+
+
+ void* operator new( std::size_t );
+ void operator delete( void*, std::size_t );
+
+
+ void from_string( const char*, int );
+
+ double to_double() const;
+
+ const char* to_string( sc_numrep,
+ int,
+ sc_fmt,
+ const scfx_params* = 0 ) const;
+
+
+ // assignment operator
+
+ void operator = ( const scfx_rep& );
+
+ friend void multiply( scfx_rep&, const scfx_rep&, const scfx_rep&, int );
+
+ friend scfx_rep* neg_scfx_rep( const scfx_rep& );
+ friend scfx_rep* mult_scfx_rep( const scfx_rep&, const scfx_rep&, int );
+ friend scfx_rep* div_scfx_rep( const scfx_rep&, const scfx_rep&, int );
+ friend scfx_rep* add_scfx_rep( const scfx_rep&, const scfx_rep&, int );
+ friend scfx_rep* sub_scfx_rep( const scfx_rep&, const scfx_rep&, int );
+ friend scfx_rep* lsh_scfx_rep( const scfx_rep&, int );
+ friend scfx_rep* rsh_scfx_rep( const scfx_rep&, int );
+
+ void lshift( int );
+ void rshift( int );
+
+ friend int cmp_scfx_rep( const scfx_rep&, const scfx_rep& );
+
+ void cast( const scfx_params&, bool&, bool& );
+
+ bool is_neg() const;
+ bool is_zero() const;
+ bool is_nan() const;
+ bool is_inf() const;
+ bool is_normal() const;
+
+ void set_zero( int = 1 );
+ void set_nan();
+ void set_inf( int );
+
+ bool get_bit( int ) const;
+ bool set( int, const scfx_params& );
+ bool clear( int, const scfx_params& );
+
+ bool get_slice( int, int, const scfx_params&, sc_bv_base& ) const;
+ bool set_slice( int, int, const scfx_params&, const sc_bv_base& );
+
+ void print( ::std::ostream& ) const;
+ void dump( ::std::ostream& ) const;
+
+ void get_type( int&, int&, sc_enc& ) const;
+
+ friend scfx_rep* quantization_scfx_rep( const scfx_rep&,
+ const scfx_params&,
+ bool& );
+ friend scfx_rep* overflow_scfx_rep( const scfx_rep&,
+ const scfx_params&,
+ bool& );
+
+ bool rounding_flag() const;
+
+private:
+
+ friend void align( const scfx_rep&, const scfx_rep&, int&, int&,
+ scfx_mant_ref&, scfx_mant_ref& );
+ friend int compare_msw( const scfx_rep&, const scfx_rep& );
+ friend int compare_msw_ff( const scfx_rep& lhs, const scfx_rep& rhs );
+ unsigned int divide_by_ten();
+ int find_lsw() const;
+ int find_msw() const;
+ void find_sw();
+ void multiply_by_ten();
+ void normalize( int );
+ scfx_mant* resize( int, int ) const;
+ void set_bin( int );
+ void set_oct( int, int );
+ void set_hex( int, int );
+ void shift_left( int );
+ void shift_right( int );
+
+ const scfx_index calc_indices( int ) const;
+
+ void o_extend( const scfx_index&, sc_enc );
+ bool o_bit_at( const scfx_index& ) const;
+ bool o_zero_left( const scfx_index& ) const;
+ bool o_zero_right( const scfx_index& ) const;
+ void o_set_low( const scfx_index&, sc_enc );
+ void o_set_high( const scfx_index&, const scfx_index&, sc_enc, int = 1 );
+ void o_set( const scfx_index&, const scfx_index&, sc_enc, bool );
+ void o_invert( const scfx_index& );
+ bool q_bit( const scfx_index& ) const;
+ void q_clear( const scfx_index& );
+ void q_incr( const scfx_index& );
+ bool q_odd( const scfx_index& ) const;
+ bool q_zero( const scfx_index& ) const;
+
+ void resize_to( int, int = 0 );
+ int size() const;
+ void toggle_tc();
+
+ friend void print_dec( scfx_string&, const scfx_rep&, int, sc_fmt );
+ friend void print_other( scfx_string&, const scfx_rep&, sc_numrep, int,
+ sc_fmt, const scfx_params* );
+
+ void quantization( const scfx_params&, bool& );
+ void overflow( const scfx_params&, bool& );
+
+ friend int compare_abs( const scfx_rep&, const scfx_rep& );
+
+ void round( int );
+
+private:
+
+ scfx_mant m_mant; // mantissa (bits of the value).
+ int m_wp; // index of highest order word in value.
+ int m_sign; // sign of value.
+ state m_state; // value state, e.g., normal, inf, etc.
+ int m_msw; // index of most significant non-zero word.
+ int m_lsw; // index of least significant non-zero word.
+ bool m_r_flag; // true if founding occurred.
+
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+inline
+void
+scfx_rep::set_zero( int sign )
+{
+ m_mant.clear();
+ m_wp = m_msw = m_lsw = 0;
+ m_sign = sign;
+ m_state = normal;
+}
+
+inline
+void
+scfx_rep::set_nan()
+{
+ m_mant.resize_to( min_mant );
+ m_state = not_a_number;
+}
+
+inline
+void
+scfx_rep::set_inf( int sign )
+{
+ m_mant.resize_to( min_mant );
+ m_state = infinity;
+ m_sign = sign;
+}
+
+
+// constructors
+
+inline
+scfx_rep::scfx_rep( const char* s )
+: m_mant( min_mant ), m_wp( 2 ), m_sign( 1 ), m_state( normal ),
+ m_msw(0), m_lsw(0), m_r_flag( false )
+{
+ from_string( s, SC_DEFAULT_CTE_WL_ );
+}
+
+
+// destructor
+
+inline
+scfx_rep::~scfx_rep()
+{}
+
+
+// assignment operator
+
+inline
+void
+scfx_rep::operator = ( const scfx_rep& f )
+{
+ if( &f != this )
+ {
+ m_mant = f.m_mant;
+ m_wp = f.m_wp;
+ m_sign = f.m_sign;
+ m_state = f.m_state;
+ m_msw = f.m_msw;
+ m_lsw = f.m_lsw;
+ round( SC_DEFAULT_MAX_WL_ );
+ }
+}
+
+inline
+scfx_rep*
+neg_scfx_rep( const scfx_rep& a )
+{
+ scfx_rep& c = *new scfx_rep( a );
+ c.m_sign = - c.m_sign;
+ return &c;
+}
+
+inline
+scfx_rep*
+mult_scfx_rep( const scfx_rep& a, const scfx_rep& b, int max_wl )
+{
+ scfx_rep& c = *new scfx_rep;
+ sc_dt::multiply( c, a, b, max_wl );
+ return &c;
+}
+
+inline
+scfx_rep*
+lsh_scfx_rep( const scfx_rep& a, int b )
+{
+ scfx_rep& c = *new scfx_rep( a );
+ c.lshift( b );
+ return &c;
+}
+
+inline
+scfx_rep*
+rsh_scfx_rep( const scfx_rep& a, int b )
+{
+ scfx_rep& c = *new scfx_rep( a );
+ c.rshift( b );
+ return &c;
+}
+
+inline
+int
+scfx_rep::size() const
+{
+ return m_mant.size();
+}
+
+inline
+bool
+scfx_rep::is_neg() const
+{
+ return ( m_sign == -1 );
+}
+
+inline
+bool
+scfx_rep::is_zero() const
+{
+ if( m_state != normal )
+ return false;
+
+ for( int i = 0; i < size(); i ++ )
+ {
+ if( m_mant[i] )
+ return false;
+ }
+
+ return true;
+}
+
+inline
+bool
+scfx_rep::is_nan() const
+{
+ return ( m_state == not_a_number );
+}
+
+inline
+bool
+scfx_rep::is_inf() const
+{
+ return ( m_state == infinity );
+}
+
+inline
+bool
+scfx_rep::is_normal() const
+{
+ return ( m_state == normal );
+}
+
+inline
+scfx_rep*
+quantization_scfx_rep( const scfx_rep& a,
+ const scfx_params& params,
+ bool& q_flag )
+{
+ scfx_rep& c = *new scfx_rep( a );
+ c.quantization( params, q_flag );
+ return &c;
+}
+
+inline
+scfx_rep*
+overflow_scfx_rep( const scfx_rep& a,
+ const scfx_params& params,
+ bool& o_flag )
+{
+ scfx_rep& c = *new scfx_rep( a );
+ c.overflow( params, o_flag );
+ return &c;
+}
+
+inline
+bool
+scfx_rep::rounding_flag() const
+{
+ return m_r_flag;
+}
+
+inline
+void
+scfx_rep::resize_to( int new_size, int restore )
+{
+ if( restore == -1 )
+ {
+ int size_incr = new_size - size();
+ m_wp += size_incr;
+ m_msw += size_incr;
+ m_lsw += size_incr;
+ }
+ m_mant.resize_to( new_size, restore );
+}
+
+inline
+const scfx_index
+scfx_rep::calc_indices( int n ) const
+{
+ int wi = n / bits_in_word + m_wp;
+ int bi = n % bits_in_word;
+
+ if( bi < 0 )
+ {
+ bi += bits_in_word;
+ -- wi;
+ }
+
+ return scfx_index( wi, bi );
+}
+
+inline
+void
+scfx_rep::o_extend( const scfx_index& x, sc_enc enc )
+{
+ int wi = x.wi();
+ int bi = x.bi();
+
+ SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" );
+
+ if( enc == SC_US_ || ( m_mant[wi] & ( ((word)1) << bi ) ) == 0 )
+ {
+ if( bi != bits_in_word - 1 )
+ m_mant[wi] &= ~( ((word)-1) << ( bi + 1 ) );
+ for( int i = wi + 1; i < size(); ++ i )
+ m_mant[i] = 0;
+ m_sign = 1;
+ }
+ else
+ {
+ if( bi != bits_in_word - 1 )
+ m_mant[wi] |= ( ((word)-1) << ( bi + 1 ) );
+ for( int i = wi + 1; i < size(); ++ i )
+ m_mant[i] = static_cast<word>( -1 );
+ m_sign = -1;
+ }
+}
+
+inline
+bool
+scfx_rep::o_bit_at( const scfx_index& x ) const
+{
+ int wi = x.wi();
+ int bi = x.bi();
+
+ SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" );
+
+ return ( m_mant[wi] & ( ((word)1) << bi ) ) != 0;
+}
+
+inline
+bool
+scfx_rep::o_zero_left( const scfx_index& x ) const
+{
+ int wi = x.wi();
+ int bi = x.bi();
+
+ SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" );
+
+ bool zero = true;
+ if( bi != bits_in_word - 1 )
+ zero = ( m_mant[wi] & ( ((word)-1) << ( bi + 1 ) ) ) == 0;
+ for( int i = wi + 1; i < size(); ++ i )
+ zero = zero && m_mant[i] == 0;
+
+ return zero;
+}
+
+inline
+bool
+scfx_rep::o_zero_right( const scfx_index& x ) const
+{
+ int wi = x.wi();
+ int bi = x.bi();
+
+ SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" );
+
+ bool zero = ( m_mant[wi] & ~( ((word)-1) << bi ) ) == 0;
+ for( int i = wi - 1; i >= 0; -- i )
+ zero = zero && m_mant[i] == 0;
+
+ return zero;
+}
+
+inline
+void
+scfx_rep::o_set_low( const scfx_index& x, sc_enc enc )
+{
+ int wi = x.wi();
+ int bi = x.bi();
+
+ SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" );
+
+ m_mant.clear();
+
+ if( enc == SC_TC_ )
+ {
+ m_mant[wi] |= ( ((word)1) << bi );
+ m_sign = -1;
+ }
+ else
+ m_sign = 1;
+}
+
+inline
+void
+scfx_rep::o_set_high( const scfx_index& x, const scfx_index& x2,
+ sc_enc enc, int sign )
+{
+ int wi = x.wi();
+ int bi = x.bi();
+ int wi2 = x2.wi();
+ int bi2 = x2.bi();
+
+ SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" );
+ SC_ASSERT_( wi2 >= 0 && wi2 < size(), "word index out of range" );
+
+ int i;
+
+ for( i = 0; i < size(); ++ i )
+ m_mant[i] = static_cast<word>( -1 );
+
+ m_mant[wi] &= ~( ((word)-1) << bi );
+ for( i = wi + 1; i < size(); ++ i )
+ m_mant[i] = 0;
+
+ m_mant[wi2] &= ( ((word)-1) << bi2 );
+ for( i = wi2 - 1; i >= 0; -- i )
+ m_mant[i] = 0;
+
+ if( enc == SC_TC_ )
+ m_sign = sign;
+ else
+ {
+ m_mant[wi] |= ( ((word)1) << bi );
+ m_sign = 1;
+ }
+}
+
+inline
+void
+scfx_rep::o_set( const scfx_index& x, const scfx_index& x3,
+ sc_enc enc, bool under )
+{
+ int wi = x.wi();
+ int bi = x.bi();
+ int wi3 = x3.wi();
+ int bi3 = x3.bi();
+
+ SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" );
+ SC_ASSERT_( wi3 >= 0 && wi3 < size(), "word index out of range" );
+
+ if( bi3 != bits_in_word - 1 )
+ {
+ if( under )
+ m_mant[wi3] &= ~( ((word)-1) << ( bi3 + 1 ) );
+ else
+ m_mant[wi3] |= ( ((word)-1) << ( bi3 + 1 ) );
+ }
+ for( int i = wi3 + 1; i < size(); ++ i )
+ {
+ if( under )
+ m_mant[i] = 0;
+ else
+ m_mant[i] = static_cast<word>( -1 );
+ }
+
+ if( enc == SC_TC_ )
+ {
+ if( under )
+ m_mant[wi] |= ( ((word)1) << bi );
+ else
+ m_mant[wi] &= ~( ((word)1) << bi );
+ }
+}
+
+inline
+void
+scfx_rep::o_invert( const scfx_index& x2 )
+{
+ int wi2 = x2.wi();
+ int bi2 = x2.bi();
+
+ m_mant[wi2] ^= ( ((word)-1) << bi2 );
+ for( int i = wi2 + 1; i < size(); ++ i )
+ m_mant[i] = ~ m_mant[i];
+}
+
+inline
+bool
+scfx_rep::q_bit( const scfx_index& x ) const
+{
+ int wi = x.wi();
+ int bi = x.bi();
+
+ SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" );
+
+ if( bi != 0 )
+ return ( m_mant[wi] & ( ((word)1) << ( bi - 1 ) ) ) != 0;
+ else if( wi != 0 )
+ return ( m_mant[wi - 1] & ( ((word)1) << ( bits_in_word - 1 ) ) ) != 0;
+ else
+ return false;
+}
+
+inline
+void
+scfx_rep::q_clear( const scfx_index& x )
+{
+ int wi = x.wi();
+ int bi = x.bi();
+
+ SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" );
+
+ m_mant[wi] &= ( ((word)-1) << bi );
+ for( int i = wi - 1; i >= 0; -- i )
+ m_mant[i] = 0;
+}
+
+inline
+void
+scfx_rep::q_incr( const scfx_index& x )
+{
+ int wi = x.wi();
+ int bi = x.bi();
+
+ SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" );
+
+ word old_val = m_mant[wi];
+ m_mant[wi] += ( ((word)1) << bi );
+ if( m_mant[wi] <= old_val )
+ {
+ if( wi + 1 == size() )
+ resize_to( size() + 1, 1 );
+
+ for( int i = wi + 1; i < size(); ++ i )
+ {
+ if( ++ m_mant[i] != 0 )
+ break;
+ }
+ }
+}
+
+inline
+bool
+scfx_rep::q_odd( const scfx_index& x ) const
+{
+ int wi = x.wi();
+ int bi = x.bi();
+
+ SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" );
+
+ return ( m_mant[wi] & ( ((word)1) << bi ) ) != 0;
+}
+
+inline
+bool
+scfx_rep::q_zero( const scfx_index& x ) const
+{
+ int wi = x.wi();
+ int bi = x.bi();
+
+ SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" );
+
+ bool zero;
+
+ if( bi != 0 )
+ {
+ zero = ( m_mant[wi] & ~( ((word)-1) << (bi - 1) ) ) == 0;
+ for( int i = wi - 1; i >= 0; -- i )
+ zero = zero && m_mant[i] == 0;
+ }
+ else if( wi != 0 )
+ {
+ zero = ( m_mant[wi - 1] & ~( ((word)-1) << (bits_in_word - 1) ) ) == 0;
+ for( int i = wi - 2; i >= 0; -- i )
+ zero = zero && m_mant[i] == 0;
+ }
+ else
+ zero = true;
+
+ return zero;
+}
+
+inline
+int
+scfx_rep::find_lsw() const
+{
+ for( int i = 0; i < size(); i ++ )
+ {
+ if( m_mant[i] )
+ return i;
+ }
+ return 0;
+}
+
+inline
+int
+scfx_rep::find_msw() const
+{
+ for( int i = size() - 1; i >= 0; i -- )
+ {
+ if( m_mant[i] )
+ return i;
+ }
+ return 0;
+}
+
+inline
+void
+scfx_rep::find_sw()
+{
+ m_lsw = find_lsw();
+ m_msw = find_msw();
+}
+
+inline
+void
+scfx_rep::toggle_tc()
+{
+ if( is_neg() )
+ {
+ complement( m_mant, m_mant, m_mant.size() );
+ inc( m_mant );
+ }
+}
+
+} // namespace sc_dt
+
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_string.h b/ext/systemc/src/sysc/datatypes/fx/scfx_string.h
new file mode 100644
index 000000000..338031ccc
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/scfx_string.h
@@ -0,0 +1,232 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ scfx_string.h -
+
+ Original Author: Robert Graulich, Synopsys, Inc.
+ Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+// $Log: scfx_string.h,v $
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.2 2006/01/03 23:18:34 acg
+// Changed copyright to include 2006.
+//
+// Revision 1.1.1.1 2005/12/19 23:16:43 acg
+// First check in of SystemC 2.1 into its own archive.
+//
+// Revision 1.9 2005/09/15 23:02:03 acg
+// Added std:: prefix to appropriate methods and types to get around
+// issues with the Edison Front End.
+//
+// Revision 1.8 2005/06/07 17:27:02 acg
+// Fixed bug in scfx_string::operator += where an array reference was used
+// rather than the [] operator. This meant that the buffer may have been
+// accessed beyond its allocated storage.
+//
+
+#ifndef SCFX_STRING_H
+#define SCFX_STRING_H
+
+#include <cstdio>
+
+
+namespace sc_dt
+{
+
+// classes defined in this module
+class scfx_string;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : scfx_string
+//
+// Simple string class for internal use.
+// ----------------------------------------------------------------------------
+
+class scfx_string
+{
+ void resize( std::size_t );
+
+public:
+
+ scfx_string();
+
+ ~scfx_string();
+
+ int length() const;
+
+ void clear();
+
+ char& operator [] ( int );
+
+ void append( int );
+ void discard( int );
+ void remove( int );
+
+ void operator += ( char );
+ void operator += ( const char* );
+
+ operator const char* ();
+
+private:
+
+ std::size_t m_len;
+ std::size_t m_alloc;
+ char* m_buffer;
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+inline
+void
+scfx_string::resize( std::size_t i )
+{
+ do {
+ m_alloc *= 2;
+ } while( i >= m_alloc );
+
+ char* temp = new char[m_alloc];
+
+ for( int j = 0; j < (int) m_len; ++ j ) {
+ temp[j] = m_buffer[j];
+ }
+ temp[m_len] = 0;
+
+ delete [] m_buffer;
+ m_buffer = temp;
+}
+
+
+inline
+scfx_string::scfx_string()
+: m_len( 0 ), m_alloc( BUFSIZ ), m_buffer( new char[m_alloc] )
+{
+ m_buffer[m_len] = 0;
+}
+
+
+inline
+scfx_string::~scfx_string()
+{
+ delete [] m_buffer;
+}
+
+
+inline
+int
+scfx_string::length() const
+{
+ return m_len;
+}
+
+
+inline
+void
+scfx_string::clear()
+{
+ m_len = 0;
+ m_buffer[m_len] = 0;
+}
+
+
+inline
+char&
+scfx_string::operator [] ( int i )
+{
+ if( i >= (int) m_alloc ) {
+ resize( i );
+ }
+ return m_buffer[i];
+}
+
+
+inline
+void
+scfx_string::append( int n )
+{
+ m_len += n;
+ m_buffer[m_len] = 0;
+}
+
+inline
+void
+scfx_string::discard( int n )
+{
+ m_len -= n;
+ m_buffer[m_len] = 0;
+}
+
+inline
+void
+scfx_string::remove( int i )
+{
+ for( int j = i + 1; j < (int) m_len; ++ j )
+ m_buffer[j - 1] = m_buffer[j];
+ -- m_len;
+ m_buffer[m_len] = 0;
+}
+
+
+inline
+void
+scfx_string::operator += ( char c )
+{
+ this->operator [] ( m_len ) = c;
+ m_len ++;
+ this->operator [] ( m_len ) = 0;
+}
+
+inline
+void
+scfx_string::operator += ( const char* s )
+{
+ while( *s )
+ (*this) += *s ++;
+}
+
+
+inline
+scfx_string::operator const char*()
+{
+ m_buffer[m_len] = 0;
+ return m_buffer;
+}
+
+} // namespace sc_dt
+
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_utils.cpp b/ext/systemc/src/sysc/datatypes/fx/scfx_utils.cpp
new file mode 100644
index 000000000..0735a6c25
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/scfx_utils.cpp
@@ -0,0 +1,176 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ scfx_utils.cpp -
+
+ Original Author: Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// $Log: scfx_utils.cpp,v $
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:58 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#include "sysc/datatypes/fx/scfx_utils.h"
+
+
+namespace sc_dt
+{
+
+void
+scfx_tc2csd( scfx_string& s, int w_prefix )
+{
+ if( w_prefix != 0 ) {
+ SC_ASSERT_( s[0] == '0' && s[1] == 'c' &&
+ s[2] == 's' && s[3] == 'd', "invalid prefix" );
+ }
+
+ scfx_string csd;
+
+ // copy bits from 's' into 'csd'; skip prefix, point, and exponent
+ int i = 0;
+ int j = (w_prefix != 0 ? 4 : 0);
+ while( s[j] )
+ {
+ if( s[j] == '0' || s[j] == '1' )
+ csd[i ++] = s[j];
+ else if( s[j] != '.' )
+ break;
+ ++ j;
+ }
+ csd[i] = '\0';
+
+ // convert 'csd' from two's complement to csd
+ -- i;
+ while( i >= 0 )
+ {
+ if( csd[i] == '0' )
+ -- i;
+ else
+ {
+ if( i > 0 && csd[i - 1] == '0' )
+ -- i;
+ else if( i == 0 )
+ csd[i --] = '-';
+ else
+ { // i > 0 && csd[i - 1] == '1'
+ csd[i --] = '-';
+ while( i >= 0 && csd[i] == '1' )
+ csd[i --] = '0';
+ if( i > 0 )
+ csd[i] = '1';
+ else if( i == 0 )
+ csd[i --] = '1';
+ }
+ }
+ }
+
+ // copy bits from 'csd' back into 's'
+ i = 0;
+ j = (w_prefix != 0 ? 4 : 0);
+ while( csd[i] )
+ {
+ if( s[j] == '.' )
+ ++ j;
+ s[j ++] = csd[i ++];
+ }
+}
+
+
+void
+scfx_csd2tc( scfx_string& csd )
+{
+ SC_ASSERT_( csd[0] == '0' && csd[1] == 'c' &&
+ csd[2] == 's' && csd[3] == 'd', "invalid prefix" );
+
+ scfx_string s;
+
+ // copy bits from 'csd' into 's'; skip prefix, point, and exponent
+ int i = 0;
+ s[i ++] = '0';
+ int j = 4;
+ while( csd[j] )
+ {
+ if( csd[j] == '-' || csd[j] == '0' || csd[j] == '1' )
+ s[i ++] = csd[j];
+ else if( csd[j] != '.' )
+ break;
+ ++ j;
+ }
+ s[i] = '\0';
+
+ // convert 's' from csd to two's complement
+ int len = i;
+ i = 1;
+ while( i < len )
+ {
+ while( i < len && s[i] != '-' )
+ i ++;
+ if( i < len )
+ {
+ j = i ++;
+ s[j --] = '1';
+ while( j >= 0 && s[j] == '0' )
+ s[j --] = '1';
+ if( j >= 0 )
+ s[j] = '0';
+ }
+ }
+
+ // copy bits from 's' back into 'csd'
+ j = csd.length();
+ csd[j + 1] = '\0';
+ while( j > 4 )
+ {
+ csd[j] = csd[j - 1];
+ -- j;
+ }
+
+ i = 0;
+ j = 4;
+ while( s[i] )
+ {
+ if( csd[j] == '.' )
+ ++ j;
+ csd[j ++] = s[i ++];
+ }
+}
+
+} // namespace sc_dt
+
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_utils.h b/ext/systemc/src/sysc/datatypes/fx/scfx_utils.h
new file mode 100644
index 000000000..55fabe045
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/fx/scfx_utils.h
@@ -0,0 +1,534 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ scfx_utils.h -
+
+ Original Author: Martin Janssen, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: scfx_utils.h,v $
+// Revision 1.2 2009/02/28 00:26:20 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.1.1.1 2006/12/15 20:31:36 acg
+// SystemC 2.2
+//
+// Revision 1.3 2006/01/13 18:53:58 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#ifndef SCFX_UTILS_H
+#define SCFX_UTILS_H
+
+
+#include "sysc/datatypes/fx/sc_fxdefs.h"
+#include "sysc/datatypes/fx/scfx_params.h"
+#include "sysc/datatypes/fx/scfx_string.h"
+
+
+namespace sc_dt
+{
+
+// ----------------------------------------------------------------------------
+// Find the most and least significant non-zero bits in a unsigned long
+// ----------------------------------------------------------------------------
+
+#define MSB_STATEMENT(n) if( x >> n ) { x >>= n; i += n; }
+
+inline
+int
+scfx_find_msb( unsigned long x )
+{
+ int i = 0;
+# if defined(SC_LONG_64)
+ MSB_STATEMENT( 32 );
+# endif // defined(SC_LONG_64)
+ MSB_STATEMENT( 16 );
+ MSB_STATEMENT( 8 );
+ MSB_STATEMENT( 4 );
+ MSB_STATEMENT( 2 );
+ MSB_STATEMENT( 1 );
+ return i;
+}
+
+#undef MSB_STATEMENT
+
+#define LSB_STATEMENT(n) if( x << n ) { x <<= n; i -= n; }
+
+inline
+int
+scfx_find_lsb( unsigned long x )
+{
+ int i;
+# if defined(SC_LONG_64)
+ i = 63;
+ LSB_STATEMENT( 32 );
+# else
+ i = 31;
+# endif // defined(SC_LONG_64)
+ LSB_STATEMENT( 16 );
+ LSB_STATEMENT( 8 );
+ LSB_STATEMENT( 4 );
+ LSB_STATEMENT( 2 );
+ LSB_STATEMENT( 1 );
+ return i;
+}
+
+#undef LSB_STATEMENT
+
+
+// ----------------------------------------------------------------------------
+// Utilities for parsing a character string number
+// ----------------------------------------------------------------------------
+
+inline
+int
+scfx_parse_sign( const char*& s, bool& sign_char )
+{
+ int sign = 1;
+
+ if( *s == '+' )
+ {
+ ++ s;
+ sign_char = true;
+ }
+ else if( *s == '-' )
+ {
+ sign = -1;
+ ++ s;
+ sign_char = true;
+ }
+ else
+ sign_char = false;
+
+ return sign;
+}
+
+inline
+sc_numrep
+scfx_parse_prefix( const char*& s )
+{
+ if( s[0] == '0' ) {
+ switch( s[1] )
+ {
+ case 'b':
+ case 'B':
+ {
+ if( (s[2] == 'u' || s[2] == 'U') && (s[3] == 's' || s[3] == 'S') ) {
+ s += 4;
+ return SC_BIN_US;
+ }
+ if( (s[2] == 's' || s[2] == 'S') && (s[3] == 'm' || s[3] == 'M') ) {
+ s += 4;
+ return SC_BIN_SM;
+ }
+ s += 2;
+ return SC_BIN;
+ }
+ case 'o':
+ case 'O':
+ {
+ if( (s[2] == 'u' || s[2] == 'U') && (s[3] == 's' || s[3] == 'S') ) {
+ s += 4;
+ return SC_OCT_US;
+ }
+ if( (s[2] == 's' || s[2] == 'S') && (s[3] == 'm' || s[3] == 'M') ) {
+ s += 4;
+ return SC_OCT_SM;
+ }
+ s += 2;
+ return SC_OCT;
+ }
+ case 'x':
+ case 'X':
+ {
+ if( (s[2] == 'u' || s[2] == 'U') && (s[3] == 's' || s[3] == 'S') ) {
+ s += 4;
+ return SC_HEX_US;
+ }
+ if( (s[2] == 's' || s[2] == 'S') && (s[3] == 'm' || s[3] == 'M') ) {
+ s += 4;
+ return SC_HEX_SM;
+ }
+ s += 2;
+ return SC_HEX;
+ }
+ case 'd':
+ case 'D':
+ {
+ s += 2;
+ return SC_DEC;
+ }
+ case 'c':
+ case 'C':
+ {
+ if( (s[2] == 's' || s[2] == 'S') && (s[3] == 'd' || s[3] == 'D') ) {
+ s += 4;
+ return SC_CSD;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ return SC_DEC;
+}
+
+
+inline
+int
+scfx_parse_base( const char*& s )
+{
+ const char* s1 = s + 1;
+
+ int base = 10;
+
+ if( *s == '0' )
+ {
+ switch( *s1 )
+ {
+ case 'b':
+ case 'B': base = 2; s += 2; break;
+ case 'o':
+ case 'O': base = 8; s += 2; break;
+ case 'd':
+ case 'D': base = 10; s += 2; break;
+ case 'x':
+ case 'X': base = 16; s += 2; break;
+ }
+ }
+
+ return base;
+}
+
+inline
+bool
+scfx_is_equal( const char* a, const char* b )
+{
+ while( *a != 0 && *b != 0 && *a == *b )
+ {
+ ++ a;
+ ++ b;
+ }
+ return ( *a == 0 && *b == 0 );
+}
+
+inline
+bool
+scfx_is_nan( const char* s )
+{
+ return scfx_is_equal( s, "NaN" );
+}
+
+inline
+bool
+scfx_is_inf( const char* s )
+{
+ return ( scfx_is_equal( s, "Inf" ) || scfx_is_equal( s, "Infinity" ) );
+}
+
+inline
+bool
+scfx_exp_start( const char* s )
+{
+ if( *s == 'e' || *s == 'E' )
+ {
+ ++ s;
+ if( *s == '+' || *s == '-' )
+ return true;
+ }
+ return false;
+}
+
+inline
+bool
+scfx_is_digit( char c, sc_numrep numrep )
+{
+ bool is_digit;
+
+ switch( numrep )
+ {
+ case SC_DEC:
+ {
+ switch( c )
+ {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ {
+ is_digit = true;
+ break;
+ }
+ default:
+ is_digit = false;
+ }
+ break;
+ }
+ case SC_BIN:
+ case SC_BIN_US:
+ case SC_BIN_SM:
+ {
+ switch( c )
+ {
+ case '0': case '1':
+ {
+ is_digit = true;
+ break;
+ }
+ default:
+ is_digit = false;
+ }
+ break;
+ }
+ case SC_OCT:
+ case SC_OCT_US:
+ case SC_OCT_SM:
+ {
+ switch( c )
+ {
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ {
+ is_digit = true;
+ break;
+ }
+ default:
+ is_digit = false;
+ }
+ break;
+ }
+ case SC_HEX:
+ case SC_HEX_US:
+ case SC_HEX_SM:
+ {
+ switch( c )
+ {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+ {
+ is_digit = true;
+ break;
+ }
+ default:
+ is_digit = false;
+ }
+ break;
+ }
+ case SC_CSD:
+ {
+ switch( c )
+ {
+ case '0': case '1': case '-':
+ {
+ is_digit = true;
+ break;
+ }
+ default:
+ is_digit = false;
+ }
+ break;
+ }
+ default:
+ is_digit = false;
+ }
+
+ return is_digit;
+}
+
+inline
+int
+scfx_to_digit( char c, sc_numrep numrep )
+{
+ int to_digit;
+
+ switch( numrep )
+ {
+ case SC_DEC:
+ case SC_BIN:
+ case SC_BIN_US:
+ case SC_BIN_SM:
+ case SC_OCT:
+ case SC_OCT_US:
+ case SC_OCT_SM:
+ {
+ to_digit = c - '0';
+ break;
+ }
+ case SC_HEX:
+ case SC_HEX_US:
+ case SC_HEX_SM:
+ {
+ switch( c )
+ {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ to_digit = c - '0';
+ break;
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+ to_digit = c - 'a' + 10;
+ break;
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+ to_digit = c - 'A' + 10;
+ break;
+ default:
+ to_digit = -2;
+ }
+ break;
+ }
+ case SC_CSD:
+ {
+ if( c == '-' )
+ to_digit = -1;
+ else
+ to_digit = c - '0';
+ break;
+ }
+ default:
+ to_digit = -2;
+ }
+
+ return to_digit;
+}
+
+
+// ----------------------------------------------------------------------------
+// Utilities for printing a character string number
+// ----------------------------------------------------------------------------
+
+inline
+void
+scfx_print_nan( scfx_string& s )
+{
+ s += "NaN";
+}
+
+inline
+void
+scfx_print_inf( scfx_string& s, bool negative )
+{
+ if( negative )
+ s += "-Inf";
+ else
+ s += "Inf";
+}
+
+inline
+void
+scfx_print_prefix( scfx_string& s, sc_numrep numrep )
+{
+ switch( numrep )
+ {
+ case SC_DEC:
+ s += "0d";
+ break;
+ case SC_BIN:
+ s += "0b";
+ break;
+ case SC_BIN_US:
+ s += "0bus";
+ break;
+ case SC_BIN_SM:
+ s += "0bsm";
+ break;
+ case SC_OCT:
+ s += "0o";
+ break;
+ case SC_OCT_US:
+ s += "0ous";
+ break;
+ case SC_OCT_SM:
+ s += "0osm";
+ break;
+ case SC_HEX:
+ s += "0x";
+ break;
+ case SC_HEX_US:
+ s += "0xus";
+ break;
+ case SC_HEX_SM:
+ s += "0xsm";
+ break;
+ case SC_CSD:
+ s += "0csd";
+ break;
+ default:
+ s += "unknown";
+ }
+}
+
+inline
+void
+scfx_print_exp( scfx_string& s, int exp )
+{
+ if( exp != 0 )
+ {
+ s += 'e';
+
+ if( exp < 0 )
+ {
+ exp = - exp;
+ s += '-';
+ }
+ else
+ s += '+';
+
+ bool first = true;
+ int scale = 1000000000;
+ do
+ {
+ int digit = exp / scale;
+ exp = exp % scale;
+ if( digit != 0 || ! first )
+ {
+ s += static_cast<char>( digit + '0' );
+ first = false;
+ }
+ scale /= 10;
+ }
+ while( scale > 0 );
+ }
+}
+
+
+void scfx_tc2csd( scfx_string&, int );
+void scfx_csd2tc( scfx_string& );
+
+} // namespace sc_dt
+
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/int/sc_bigint.h b/ext/systemc/src/sysc/datatypes/int/sc_bigint.h
new file mode 100644
index 000000000..d5445fc84
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/int/sc_bigint.h
@@ -0,0 +1,271 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_bigint.h -- Template version of sc_signed. This class enables
+ compile-time bit widths for sc_signed numbers.
+
+ Original Author: Ali Dasdan, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Gene Bushayev, Synopsys, Inc.
+ Description of Modification: - Interface between sc_bigint and sc_bv/sc_lv.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_bigint.h,v $
+// Revision 1.2 2011/02/18 20:19:14 acg
+// Andy Goodrich: updating Copyright notice.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:49:31 acg
+// Added $Log command so that CVS check in comments are reproduced in the
+// source.
+//
+
+#ifndef SC_BIGINT_H
+#define SC_BIGINT_H
+
+
+#include "sysc/datatypes/int/sc_signed.h"
+#include "sysc/datatypes/int/sc_unsigned.h"
+
+namespace sc_dt
+{
+
+// classes defined in this module
+template <int W> class sc_bigint;
+
+// forward class declarations
+class sc_bv_base;
+class sc_lv_base;
+class sc_fxval;
+class sc_fxval_fast;
+class sc_fxnum;
+class sc_fxnum_fast;
+
+
+// ----------------------------------------------------------------------------
+// CLASS TEMPLATE : sc_bigint<W>
+//
+// Arbitrary size signed integer type.
+// ----------------------------------------------------------------------------
+
+#ifdef SC_MAX_NBITS
+template< int W = SC_MAX_NBITS >
+#else
+template< int W >
+#endif
+class sc_bigint
+ : public sc_signed
+{
+public:
+
+ // constructors
+
+ sc_bigint()
+ : sc_signed( W )
+ {}
+
+ sc_bigint( const sc_bigint<W>& v )
+ : sc_signed( W )
+ { *this = v; }
+
+ sc_bigint( const sc_signed& v )
+ : sc_signed( W )
+ { *this = v; }
+
+ sc_bigint( const sc_signed_subref& v )
+ : sc_signed( W )
+ { *this = v; }
+
+ template< class T >
+ sc_bigint( const sc_generic_base<T>& a )
+ : sc_signed( W )
+ { a->to_sc_signed(*this); }
+
+ sc_bigint( const sc_unsigned& v )
+ : sc_signed( W )
+ { *this = v; }
+
+ sc_bigint( const sc_unsigned_subref& v )
+ : sc_signed( W )
+ { *this = v; }
+
+ sc_bigint( const char* v )
+ : sc_signed( W )
+ { *this = v; }
+
+ sc_bigint( int64 v )
+ : sc_signed( W )
+ { *this = v; }
+
+ sc_bigint( uint64 v )
+ : sc_signed( W )
+ { *this = v; }
+
+ sc_bigint( long v )
+ : sc_signed( W )
+ { *this = v; }
+
+ sc_bigint( unsigned long v )
+ : sc_signed( W )
+ { *this = v; }
+
+ sc_bigint( int v )
+ : sc_signed( W )
+ { *this = v; }
+
+ sc_bigint( unsigned int v )
+ : sc_signed( W )
+ { *this = v; }
+
+ sc_bigint( double v )
+ : sc_signed( W )
+ { *this = v; }
+
+ sc_bigint( const sc_bv_base& v )
+ : sc_signed( W )
+ { *this = v; }
+
+ sc_bigint( const sc_lv_base& v )
+ : sc_signed( W )
+ { *this = v; }
+
+#ifdef SC_INCLUDE_FX
+
+ explicit sc_bigint( const sc_fxval& v )
+ : sc_signed( W )
+ { *this = v; }
+
+ explicit sc_bigint( const sc_fxval_fast& v )
+ : sc_signed( W )
+ { *this = v; }
+
+ explicit sc_bigint( const sc_fxnum& v )
+ : sc_signed( W )
+ { *this = v; }
+
+ explicit sc_bigint( const sc_fxnum_fast& v )
+ : sc_signed( W )
+ { *this = v; }
+
+#endif
+
+
+#ifndef SC_MAX_NBITS
+
+ // destructor
+
+ ~sc_bigint()
+ {}
+
+#endif
+
+ // assignment operators
+
+ sc_bigint<W>& operator = ( const sc_bigint<W>& v )
+ { sc_signed::operator = ( v ); return *this; }
+
+ sc_bigint<W>& operator = ( const sc_signed& v )
+ { sc_signed::operator = ( v ); return *this; }
+
+ sc_bigint<W>& operator = (const sc_signed_subref& v )
+ { sc_signed::operator = ( v ); return *this; }
+
+ template< class T >
+ sc_bigint<W>& operator = ( const sc_generic_base<T>& a )
+ { a->to_sc_signed(*this); return *this;}
+
+ sc_bigint<W>& operator = ( const sc_unsigned& v )
+ { sc_signed::operator = ( v ); return *this; }
+
+ sc_bigint<W>& operator = ( const sc_unsigned_subref& v )
+ { sc_signed::operator = ( v ); return *this; }
+
+ sc_bigint<W>& operator = ( const char* v )
+ { sc_signed::operator = ( v ); return *this; }
+
+ sc_bigint<W>& operator = ( int64 v )
+ { sc_signed::operator = ( v ); return *this; }
+
+ sc_bigint<W>& operator = ( uint64 v )
+ { sc_signed::operator = ( v ); return *this; }
+
+ sc_bigint<W>& operator = ( long v )
+ { sc_signed::operator = ( v ); return *this; }
+
+ sc_bigint<W>& operator = ( unsigned long v )
+ { sc_signed::operator = ( v ); return *this; }
+
+ sc_bigint<W>& operator = ( int v )
+ { sc_signed::operator = ( v ); return *this; }
+
+ sc_bigint<W>& operator = ( unsigned int v )
+ { sc_signed::operator = ( v ); return *this; }
+
+ sc_bigint<W>& operator = ( double v )
+ { sc_signed::operator = ( v ); return *this; }
+
+
+ sc_bigint<W>& operator = ( const sc_bv_base& v )
+ { sc_signed::operator = ( v ); return *this; }
+
+ sc_bigint<W>& operator = ( const sc_lv_base& v )
+ { sc_signed::operator = ( v ); return *this; }
+
+ sc_bigint<W>& operator = ( const sc_int_base& v )
+ { sc_signed::operator = ( v ); return *this; }
+
+ sc_bigint<W>& operator = ( const sc_uint_base& v )
+ { sc_signed::operator = ( v ); return *this; }
+
+#ifdef SC_INCLUDE_FX
+
+ sc_bigint<W>& operator = ( const sc_fxval& v )
+ { sc_signed::operator = ( v ); return *this; }
+
+ sc_bigint<W>& operator = ( const sc_fxval_fast& v )
+ { sc_signed::operator = ( v ); return *this; }
+
+ sc_bigint<W>& operator = ( const sc_fxnum& v )
+ { sc_signed::operator = ( v ); return *this; }
+
+ sc_bigint<W>& operator = ( const sc_fxnum_fast& v )
+ { sc_signed::operator = ( v ); return *this; }
+
+#endif
+};
+
+} // namespace sc_dt
+
+
+#endif
diff --git a/ext/systemc/src/sysc/datatypes/int/sc_biguint.h b/ext/systemc/src/sysc/datatypes/int/sc_biguint.h
new file mode 100644
index 000000000..689f41e63
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/int/sc_biguint.h
@@ -0,0 +1,272 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_biguint.h -- Template version of sc_unsigned. This class
+ enables compile-time bit widths for sc_unsigned numbers.
+
+ Original Author: Ali Dasdan, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Gene Bushayev, Synopsys, Inc.
+ Description of Modification: - Interface between sc_bigint and sc_bv/sc_lv.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_biguint.h,v $
+// Revision 1.2 2011/02/18 20:19:14 acg
+// Andy Goodrich: updating Copyright notice.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:49:31 acg
+// Added $Log command so that CVS check in comments are reproduced in the
+// source.
+//
+
+#ifndef SC_BIGUINT_H
+#define SC_BIGUINT_H
+
+
+#include "sysc/datatypes/int/sc_signed.h"
+#include "sysc/datatypes/int/sc_unsigned.h"
+
+namespace sc_dt
+{
+
+// classes defined in this module
+template <int W> class sc_biguint;
+
+// forward class declarations
+class sc_bv_base;
+class sc_lv_base;
+class sc_fxval;
+class sc_fxval_fast;
+class sc_fxnum;
+class sc_fxnum_fast;
+
+
+// ----------------------------------------------------------------------------
+// CLASS TEMPLATE : sc_biguint<W>
+//
+// Arbitrary size unsigned integer type.
+// ----------------------------------------------------------------------------
+
+#ifdef SC_MAX_NBITS
+template< int W = SC_MAX_NBITS >
+#else
+template< int W >
+#endif
+class sc_biguint
+ : public sc_unsigned
+{
+public:
+
+ // constructors
+
+ sc_biguint()
+ : sc_unsigned( W )
+ {}
+
+ sc_biguint( const sc_biguint<W>& v )
+ : sc_unsigned( W )
+ { *this = v; }
+
+ sc_biguint( const sc_unsigned& v )
+ : sc_unsigned( W )
+ { *this = v; }
+
+ sc_biguint( const sc_unsigned_subref& v )
+ : sc_unsigned( W )
+ { *this = v; }
+
+ template< class T >
+ sc_biguint( const sc_generic_base<T>& a )
+ : sc_unsigned( W )
+ { a->to_sc_unsigned(*this); }
+
+ sc_biguint( const sc_signed& v )
+ : sc_unsigned( W )
+ { *this = v; }
+
+ sc_biguint( const sc_signed_subref& v )
+ : sc_unsigned( W )
+ { *this = v; }
+
+ sc_biguint( const char* v )
+ : sc_unsigned( W )
+ { *this = v; }
+
+ sc_biguint( int64 v )
+ : sc_unsigned( W )
+ { *this = v; }
+
+ sc_biguint( uint64 v )
+ : sc_unsigned( W )
+ { *this = v; }
+
+ sc_biguint( long v )
+ : sc_unsigned( W )
+ { *this = v; }
+
+ sc_biguint( unsigned long v )
+ : sc_unsigned( W )
+ { *this = v; }
+
+ sc_biguint( int v )
+ : sc_unsigned( W )
+ { *this = v; }
+
+ sc_biguint( unsigned int v )
+ : sc_unsigned( W )
+ { *this = v; }
+
+ sc_biguint( double v )
+ : sc_unsigned( W )
+ { *this = v; }
+
+ sc_biguint( const sc_bv_base& v )
+ : sc_unsigned( W )
+ { *this = v; }
+
+ sc_biguint( const sc_lv_base& v )
+ : sc_unsigned( W )
+ { *this = v; }
+
+#ifdef SC_INCLUDE_FX
+
+ explicit sc_biguint( const sc_fxval& v )
+ : sc_unsigned( W )
+ { *this = v; }
+
+ explicit sc_biguint( const sc_fxval_fast& v )
+ : sc_unsigned( W )
+ { *this = v; }
+
+ explicit sc_biguint( const sc_fxnum& v )
+ : sc_unsigned( W )
+ { *this = v; }
+
+ explicit sc_biguint( const sc_fxnum_fast& v )
+ : sc_unsigned( W )
+ { *this = v; }
+
+#endif
+
+
+#ifndef SC_MAX_NBITS
+
+ // destructor
+
+ ~sc_biguint()
+ {}
+
+#endif
+
+
+ // assignment operators
+
+ sc_biguint<W>& operator = ( const sc_biguint<W>& v )
+ { sc_unsigned::operator = ( v ); return *this; }
+
+ sc_biguint<W>& operator = ( const sc_unsigned& v )
+ { sc_unsigned::operator = ( v ); return *this; }
+
+ sc_biguint<W>& operator = ( const sc_unsigned_subref& v )
+ { sc_unsigned::operator = ( v ); return *this; }
+
+ template< class T >
+ sc_biguint<W>& operator = ( const sc_generic_base<T>& a )
+ { a->to_sc_unsigned(*this); return *this; }
+
+ sc_biguint<W>& operator = ( const sc_signed& v )
+ { sc_unsigned::operator = ( v ); return *this; }
+
+ sc_biguint<W>& operator = ( const sc_signed_subref& v )
+ { sc_unsigned::operator = ( v ); return *this; }
+
+ sc_biguint<W>& operator = ( const char* v )
+ { sc_unsigned::operator = ( v ); return *this; }
+
+ sc_biguint<W>& operator = ( int64 v )
+ { sc_unsigned::operator = ( v ); return *this; }
+
+ sc_biguint<W>& operator = ( uint64 v )
+ { sc_unsigned::operator = ( v ); return *this; }
+
+ sc_biguint<W>& operator = ( long v )
+ { sc_unsigned::operator = ( v ); return *this; }
+
+ sc_biguint<W>& operator = ( unsigned long v )
+ { sc_unsigned::operator = ( v ); return *this; }
+
+ sc_biguint<W>& operator = ( int v )
+ { sc_unsigned::operator = ( v ); return *this; }
+
+ sc_biguint<W>& operator = ( unsigned int v )
+ { sc_unsigned::operator = ( v ); return *this; }
+
+ sc_biguint<W>& operator = ( double v )
+ { sc_unsigned::operator = ( v ); return *this; }
+
+
+ sc_biguint<W>& operator = ( const sc_bv_base& v )
+ { sc_unsigned::operator = ( v ); return *this; }
+
+ sc_biguint<W>& operator = ( const sc_lv_base& v )
+ { sc_unsigned::operator = ( v ); return *this; }
+
+ sc_biguint<W>& operator = ( const sc_int_base& v )
+ { sc_unsigned::operator = ( v ); return *this; }
+
+ sc_biguint<W>& operator = ( const sc_uint_base& v )
+ { sc_unsigned::operator = ( v ); return *this; }
+
+#ifdef SC_INCLUDE_FX
+
+ sc_biguint<W>& operator = ( const sc_fxval& v )
+ { sc_unsigned::operator = ( v ); return *this; }
+
+ sc_biguint<W>& operator = ( const sc_fxval_fast& v )
+ { sc_unsigned::operator = ( v ); return *this; }
+
+ sc_biguint<W>& operator = ( const sc_fxnum& v )
+ { sc_unsigned::operator = ( v ); return *this; }
+
+ sc_biguint<W>& operator = ( const sc_fxnum_fast& v )
+ { sc_unsigned::operator = ( v ); return *this; }
+
+#endif
+};
+
+} // namespace sc_dt
+
+
+#endif
diff --git a/ext/systemc/src/sysc/datatypes/int/sc_int.h b/ext/systemc/src/sysc/datatypes/int/sc_int.h
new file mode 100644
index 000000000..adcb6b321
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/int/sc_int.h
@@ -0,0 +1,312 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_int.h -- A sc_int is a signed integer whose length is less than the
+ machine's native integer length. We provide two implementations
+ (i) sc_int with length between 1 - 64, and (ii) sc_int with
+ length between 1 - 32. Implementation (i) is the default
+ implementation, while implementation (ii) can be used only if
+ the class library is compiled with -D_32BIT_. Unlike arbitrary
+ precision, arithmetic and bitwise operations are performed
+ using the native types (hence capped at 32/64 bits). The sc_int
+ integer is useful when the user does not need arbitrary
+ precision and the performance is superior to
+ sc_bigint/sc_biguint.
+
+ Original Author: Amit Rao, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc.
+ Description of Modification: - Resolved ambiguity with sc_(un)signed.
+ - Merged the code for 64- and 32-bit versions
+ via the constants in sc_nbdefs.h.
+ - Eliminated redundant file inclusions.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_int.h,v $
+// Revision 1.2 2011/02/18 20:19:14 acg
+// Andy Goodrich: updating Copyright notice.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:49:31 acg
+// Added $Log command so that CVS check in comments are reproduced in the
+// source.
+//
+
+#ifndef SC_INT_H
+#define SC_INT_H
+
+
+#include "sysc/datatypes/int/sc_int_base.h"
+
+
+namespace sc_dt
+{
+
+// classes defined in this module
+template <int W> class sc_int;
+
+
+// ----------------------------------------------------------------------------
+// CLASS TEMPLATE : sc_int<W>
+//
+// Template class sc_int<W> is the interface that the user sees. It is
+// derived from sc_int_base and most of its methods are just wrappers
+// that call the corresponding method in the parent class. Note that
+// the length of sc_int datatype is specified as a template parameter.
+// ----------------------------------------------------------------------------
+
+template <int W>
+class sc_int
+ : public sc_int_base
+{
+public:
+
+ // constructors
+
+ sc_int()
+ : sc_int_base( W )
+ {}
+
+ sc_int( int_type v )
+ : sc_int_base( v, W )
+ {}
+
+ sc_int( const sc_int<W>& a )
+ : sc_int_base( a )
+ {}
+
+ sc_int( const sc_int_base& a )
+ : sc_int_base( W )
+ { sc_int_base::operator = ( a ); }
+
+ sc_int( const sc_int_subref_r& a )
+ : sc_int_base( W )
+ { sc_int_base::operator = ( a ); }
+
+ template< class T >
+ sc_int( const sc_generic_base<T>& a )
+ : sc_int_base( W )
+ { sc_int_base::operator = ( a->to_int64() ); }
+
+ sc_int( const sc_signed& a )
+ : sc_int_base( W )
+ { sc_int_base::operator = ( a ); }
+
+ sc_int( const sc_unsigned& a )
+ : sc_int_base( W )
+ { sc_int_base::operator = ( a ); }
+
+#ifdef SC_INCLUDE_FX
+
+ explicit sc_int( const sc_fxval& a )
+ : sc_int_base( W )
+ { sc_int_base::operator = ( a ); }
+
+ explicit sc_int( const sc_fxval_fast& a )
+ : sc_int_base( W )
+ { sc_int_base::operator = ( a ); }
+
+ explicit sc_int( const sc_fxnum& a )
+ : sc_int_base( W )
+ { sc_int_base::operator = ( a ); }
+
+ explicit sc_int( const sc_fxnum_fast& a )
+ : sc_int_base( W )
+ { sc_int_base::operator = ( a ); }
+
+#endif
+
+ sc_int( const sc_bv_base& a )
+ : sc_int_base( W )
+ { sc_int_base::operator = ( a ); }
+
+ sc_int( const sc_lv_base& a )
+ : sc_int_base( W )
+ { sc_int_base::operator = ( a ); }
+
+ sc_int( const char* a )
+ : sc_int_base( W )
+ { sc_int_base::operator = ( a ); }
+
+ sc_int( unsigned long a )
+ : sc_int_base( W )
+ { sc_int_base::operator = ( a ); }
+
+ sc_int( long a )
+ : sc_int_base( W )
+ { sc_int_base::operator = ( a ); }
+
+ sc_int( unsigned int a )
+ : sc_int_base( W )
+ { sc_int_base::operator = ( a ); }
+
+ sc_int( int a )
+ : sc_int_base( W )
+ { sc_int_base::operator = ( a ); }
+
+ sc_int( uint64 a )
+ : sc_int_base( W )
+ { sc_int_base::operator = ( a ); }
+
+ sc_int( double a )
+ : sc_int_base( W )
+ { sc_int_base::operator = ( a ); }
+
+
+ // assignment operators
+
+ sc_int<W>& operator = ( int_type v )
+ { sc_int_base::operator = ( v ); return *this; }
+
+ sc_int<W>& operator = ( const sc_int_base& a )
+ { sc_int_base::operator = ( a ); return *this; }
+
+ sc_int<W>& operator = ( const sc_int_subref_r& a )
+ { sc_int_base::operator = ( a ); return *this; }
+
+ sc_int<W>& operator = ( const sc_int<W>& a )
+ { m_val = a.m_val; return *this; }
+
+ template< class T >
+ sc_int<W>& operator = ( const sc_generic_base<T>& a )
+ { sc_int_base::operator = ( a->to_int64() ); return *this; }
+
+ sc_int<W>& operator = ( const sc_signed& a )
+ { sc_int_base::operator = ( a ); return *this; }
+
+ sc_int<W>& operator = ( const sc_unsigned& a )
+ { sc_int_base::operator = ( a ); return *this; }
+
+#ifdef SC_INCLUDE_FX
+
+ sc_int<W>& operator = ( const sc_fxval& a )
+ { sc_int_base::operator = ( a ); return *this; }
+
+ sc_int<W>& operator = ( const sc_fxval_fast& a )
+ { sc_int_base::operator = ( a ); return *this; }
+
+ sc_int<W>& operator = ( const sc_fxnum& a )
+ { sc_int_base::operator = ( a ); return *this; }
+
+ sc_int<W>& operator = ( const sc_fxnum_fast& a )
+ { sc_int_base::operator = ( a ); return *this; }
+
+#endif
+
+ sc_int<W>& operator = ( const sc_bv_base& a )
+ { sc_int_base::operator = ( a ); return *this; }
+
+ sc_int<W>& operator = ( const sc_lv_base& a )
+ { sc_int_base::operator = ( a ); return *this; }
+
+ sc_int<W>& operator = ( const char* a )
+ { sc_int_base::operator = ( a ); return *this; }
+
+ sc_int<W>& operator = ( unsigned long a )
+ { sc_int_base::operator = ( a ); return *this; }
+
+ sc_int<W>& operator = ( long a )
+ { sc_int_base::operator = ( a ); return *this; }
+
+ sc_int<W>& operator = ( unsigned int a )
+ { sc_int_base::operator = ( a ); return *this; }
+
+ sc_int<W>& operator = ( int a )
+ { sc_int_base::operator = ( a ); return *this; }
+
+ sc_int<W>& operator = ( uint64 a )
+ { sc_int_base::operator = ( a ); return *this; }
+
+ sc_int<W>& operator = ( double a )
+ { sc_int_base::operator = ( a ); return *this; }
+
+
+ // arithmetic assignment operators
+
+ sc_int<W>& operator += ( int_type v )
+ { sc_int_base::operator += ( v ); return *this; }
+
+ sc_int<W>& operator -= ( int_type v )
+ { sc_int_base::operator -= ( v ); return *this; }
+
+ sc_int<W>& operator *= ( int_type v )
+ { sc_int_base::operator *= ( v ); return *this; }
+
+ sc_int<W>& operator /= ( int_type v )
+ { sc_int_base::operator /= ( v ); return *this; }
+
+ sc_int<W>& operator %= ( int_type v )
+ { sc_int_base::operator %= ( v ); return *this; }
+
+
+ // bitwise assignment operators
+
+ sc_int<W>& operator &= ( int_type v )
+ { sc_int_base::operator &= ( v ); return *this; }
+
+ sc_int<W>& operator |= ( int_type v )
+ { sc_int_base::operator |= ( v ); return *this; }
+
+ sc_int<W>& operator ^= ( int_type v )
+ { sc_int_base::operator ^= ( v ); return *this; }
+
+
+ sc_int<W>& operator <<= ( int_type v )
+ { sc_int_base::operator <<= ( v ); return *this; }
+
+ sc_int<W>& operator >>= ( int_type v )
+ { sc_int_base::operator >>= ( v ); return *this; }
+
+
+ // prefix and postfix increment and decrement operators
+
+ sc_int<W>& operator ++ () // prefix
+ { sc_int_base::operator ++ (); return *this; }
+
+ const sc_int<W> operator ++ ( int ) // postfix
+ { return sc_int<W>( sc_int_base::operator ++ ( 0 ) ); }
+
+ sc_int<W>& operator -- () // prefix
+ { sc_int_base::operator -- (); return *this; }
+
+ const sc_int<W> operator -- ( int ) // postfix
+ { return sc_int<W>( sc_int_base::operator -- ( 0 ) ); }
+};
+
+} // namespace sc_dt
+
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/int/sc_int32_mask.cpp b/ext/systemc/src/sysc/datatypes/int/sc_int32_mask.cpp
new file mode 100644
index 000000000..5e55dfb87
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/int/sc_int32_mask.cpp
@@ -0,0 +1,665 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_int32_mask.cpp -- Fills the mask_int lookup table to enable efficient
+ part-selection on 32-bit sc_ints and sc_uints.
+
+ Original Author: Amit Rao, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc.
+ Description of Modification: - Resolved ambiguity with sc_(un)signed.
+ - Merged the code for 64- and 32-bit versions
+ via the constants in sc_nbdefs.h.
+ - Eliminated redundant file inclusions.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// $Log: sc_int32_mask.cpp,v $
+// Revision 1.2 2011/02/18 20:19:14 acg
+// Andy Goodrich: updating Copyright notice.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:49:31 acg
+// Added $Log command so that CVS check in comments are reproduced in the
+// source.
+//
+
+#ifdef _32BIT_
+
+#include "sysc/datatypes/int/sc_int_base.h"
+#include "sysc/datatypes/int/sc_uint_base.h"
+
+
+namespace sc_dt
+{
+
+const uint_type mask_int[SC_INTWIDTH][SC_INTWIDTH] =
+{
+{
+0xfffffffeU
+},
+{
+0xfffffffcU,
+0xfffffffdU
+},
+{
+0xfffffff8U,
+0xfffffff9U,
+0xfffffffbU
+},
+{
+0xfffffff0U,
+0xfffffff1U,
+0xfffffff3U,
+0xfffffff7U
+},
+{
+0xffffffe0U,
+0xffffffe1U,
+0xffffffe3U,
+0xffffffe7U,
+0xffffffefU
+},
+{
+0xffffffc0U,
+0xffffffc1U,
+0xffffffc3U,
+0xffffffc7U,
+0xffffffcfU,
+0xffffffdfU
+},
+{
+0xffffff80U,
+0xffffff81U,
+0xffffff83U,
+0xffffff87U,
+0xffffff8fU,
+0xffffff9fU,
+0xffffffbfU
+},
+{
+0xffffff00U,
+0xffffff01U,
+0xffffff03U,
+0xffffff07U,
+0xffffff0fU,
+0xffffff1fU,
+0xffffff3fU,
+0xffffff7fU
+},
+{
+0xfffffe00U,
+0xfffffe01U,
+0xfffffe03U,
+0xfffffe07U,
+0xfffffe0fU,
+0xfffffe1fU,
+0xfffffe3fU,
+0xfffffe7fU,
+0xfffffeffU
+},
+{
+0xfffffc00U,
+0xfffffc01U,
+0xfffffc03U,
+0xfffffc07U,
+0xfffffc0fU,
+0xfffffc1fU,
+0xfffffc3fU,
+0xfffffc7fU,
+0xfffffcffU,
+0xfffffdffU
+},
+{
+0xfffff800U,
+0xfffff801U,
+0xfffff803U,
+0xfffff807U,
+0xfffff80fU,
+0xfffff81fU,
+0xfffff83fU,
+0xfffff87fU,
+0xfffff8ffU,
+0xfffff9ffU,
+0xfffffbffU
+},
+{
+0xfffff000U,
+0xfffff001U,
+0xfffff003U,
+0xfffff007U,
+0xfffff00fU,
+0xfffff01fU,
+0xfffff03fU,
+0xfffff07fU,
+0xfffff0ffU,
+0xfffff1ffU,
+0xfffff3ffU,
+0xfffff7ffU
+},
+{
+0xffffe000U,
+0xffffe001U,
+0xffffe003U,
+0xffffe007U,
+0xffffe00fU,
+0xffffe01fU,
+0xffffe03fU,
+0xffffe07fU,
+0xffffe0ffU,
+0xffffe1ffU,
+0xffffe3ffU,
+0xffffe7ffU,
+0xffffefffU
+},
+{
+0xffffc000U,
+0xffffc001U,
+0xffffc003U,
+0xffffc007U,
+0xffffc00fU,
+0xffffc01fU,
+0xffffc03fU,
+0xffffc07fU,
+0xffffc0ffU,
+0xffffc1ffU,
+0xffffc3ffU,
+0xffffc7ffU,
+0xffffcfffU,
+0xffffdfffU
+},
+{
+0xffff8000U,
+0xffff8001U,
+0xffff8003U,
+0xffff8007U,
+0xffff800fU,
+0xffff801fU,
+0xffff803fU,
+0xffff807fU,
+0xffff80ffU,
+0xffff81ffU,
+0xffff83ffU,
+0xffff87ffU,
+0xffff8fffU,
+0xffff9fffU,
+0xffffbfffU
+},
+{
+0xffff0000U,
+0xffff0001U,
+0xffff0003U,
+0xffff0007U,
+0xffff000fU,
+0xffff001fU,
+0xffff003fU,
+0xffff007fU,
+0xffff00ffU,
+0xffff01ffU,
+0xffff03ffU,
+0xffff07ffU,
+0xffff0fffU,
+0xffff1fffU,
+0xffff3fffU,
+0xffff7fffU
+},
+{
+0xfffe0000U,
+0xfffe0001U,
+0xfffe0003U,
+0xfffe0007U,
+0xfffe000fU,
+0xfffe001fU,
+0xfffe003fU,
+0xfffe007fU,
+0xfffe00ffU,
+0xfffe01ffU,
+0xfffe03ffU,
+0xfffe07ffU,
+0xfffe0fffU,
+0xfffe1fffU,
+0xfffe3fffU,
+0xfffe7fffU,
+0xfffeffffU
+},
+{
+0xfffc0000U,
+0xfffc0001U,
+0xfffc0003U,
+0xfffc0007U,
+0xfffc000fU,
+0xfffc001fU,
+0xfffc003fU,
+0xfffc007fU,
+0xfffc00ffU,
+0xfffc01ffU,
+0xfffc03ffU,
+0xfffc07ffU,
+0xfffc0fffU,
+0xfffc1fffU,
+0xfffc3fffU,
+0xfffc7fffU,
+0xfffcffffU,
+0xfffdffffU
+},
+{
+0xfff80000U,
+0xfff80001U,
+0xfff80003U,
+0xfff80007U,
+0xfff8000fU,
+0xfff8001fU,
+0xfff8003fU,
+0xfff8007fU,
+0xfff800ffU,
+0xfff801ffU,
+0xfff803ffU,
+0xfff807ffU,
+0xfff80fffU,
+0xfff81fffU,
+0xfff83fffU,
+0xfff87fffU,
+0xfff8ffffU,
+0xfff9ffffU,
+0xfffbffffU
+},
+{
+0xfff00000U,
+0xfff00001U,
+0xfff00003U,
+0xfff00007U,
+0xfff0000fU,
+0xfff0001fU,
+0xfff0003fU,
+0xfff0007fU,
+0xfff000ffU,
+0xfff001ffU,
+0xfff003ffU,
+0xfff007ffU,
+0xfff00fffU,
+0xfff01fffU,
+0xfff03fffU,
+0xfff07fffU,
+0xfff0ffffU,
+0xfff1ffffU,
+0xfff3ffffU,
+0xfff7ffffU
+},
+{
+0xffe00000U,
+0xffe00001U,
+0xffe00003U,
+0xffe00007U,
+0xffe0000fU,
+0xffe0001fU,
+0xffe0003fU,
+0xffe0007fU,
+0xffe000ffU,
+0xffe001ffU,
+0xffe003ffU,
+0xffe007ffU,
+0xffe00fffU,
+0xffe01fffU,
+0xffe03fffU,
+0xffe07fffU,
+0xffe0ffffU,
+0xffe1ffffU,
+0xffe3ffffU,
+0xffe7ffffU,
+0xffefffffU
+},
+{
+0xffc00000U,
+0xffc00001U,
+0xffc00003U,
+0xffc00007U,
+0xffc0000fU,
+0xffc0001fU,
+0xffc0003fU,
+0xffc0007fU,
+0xffc000ffU,
+0xffc001ffU,
+0xffc003ffU,
+0xffc007ffU,
+0xffc00fffU,
+0xffc01fffU,
+0xffc03fffU,
+0xffc07fffU,
+0xffc0ffffU,
+0xffc1ffffU,
+0xffc3ffffU,
+0xffc7ffffU,
+0xffcfffffU,
+0xffdfffffU
+},
+{
+0xff800000U,
+0xff800001U,
+0xff800003U,
+0xff800007U,
+0xff80000fU,
+0xff80001fU,
+0xff80003fU,
+0xff80007fU,
+0xff8000ffU,
+0xff8001ffU,
+0xff8003ffU,
+0xff8007ffU,
+0xff800fffU,
+0xff801fffU,
+0xff803fffU,
+0xff807fffU,
+0xff80ffffU,
+0xff81ffffU,
+0xff83ffffU,
+0xff87ffffU,
+0xff8fffffU,
+0xff9fffffU,
+0xffbfffffU
+},
+{
+0xff000000U,
+0xff000001U,
+0xff000003U,
+0xff000007U,
+0xff00000fU,
+0xff00001fU,
+0xff00003fU,
+0xff00007fU,
+0xff0000ffU,
+0xff0001ffU,
+0xff0003ffU,
+0xff0007ffU,
+0xff000fffU,
+0xff001fffU,
+0xff003fffU,
+0xff007fffU,
+0xff00ffffU,
+0xff01ffffU,
+0xff03ffffU,
+0xff07ffffU,
+0xff0fffffU,
+0xff1fffffU,
+0xff3fffffU,
+0xff7fffffU
+},
+{
+0xfe000000U,
+0xfe000001U,
+0xfe000003U,
+0xfe000007U,
+0xfe00000fU,
+0xfe00001fU,
+0xfe00003fU,
+0xfe00007fU,
+0xfe0000ffU,
+0xfe0001ffU,
+0xfe0003ffU,
+0xfe0007ffU,
+0xfe000fffU,
+0xfe001fffU,
+0xfe003fffU,
+0xfe007fffU,
+0xfe00ffffU,
+0xfe01ffffU,
+0xfe03ffffU,
+0xfe07ffffU,
+0xfe0fffffU,
+0xfe1fffffU,
+0xfe3fffffU,
+0xfe7fffffU,
+0xfeffffffU
+},
+{
+0xfc000000U,
+0xfc000001U,
+0xfc000003U,
+0xfc000007U,
+0xfc00000fU,
+0xfc00001fU,
+0xfc00003fU,
+0xfc00007fU,
+0xfc0000ffU,
+0xfc0001ffU,
+0xfc0003ffU,
+0xfc0007ffU,
+0xfc000fffU,
+0xfc001fffU,
+0xfc003fffU,
+0xfc007fffU,
+0xfc00ffffU,
+0xfc01ffffU,
+0xfc03ffffU,
+0xfc07ffffU,
+0xfc0fffffU,
+0xfc1fffffU,
+0xfc3fffffU,
+0xfc7fffffU,
+0xfcffffffU,
+0xfdffffffU
+},
+{
+0xf8000000U,
+0xf8000001U,
+0xf8000003U,
+0xf8000007U,
+0xf800000fU,
+0xf800001fU,
+0xf800003fU,
+0xf800007fU,
+0xf80000ffU,
+0xf80001ffU,
+0xf80003ffU,
+0xf80007ffU,
+0xf8000fffU,
+0xf8001fffU,
+0xf8003fffU,
+0xf8007fffU,
+0xf800ffffU,
+0xf801ffffU,
+0xf803ffffU,
+0xf807ffffU,
+0xf80fffffU,
+0xf81fffffU,
+0xf83fffffU,
+0xf87fffffU,
+0xf8ffffffU,
+0xf9ffffffU,
+0xfbffffffU
+},
+{
+0xf0000000U,
+0xf0000001U,
+0xf0000003U,
+0xf0000007U,
+0xf000000fU,
+0xf000001fU,
+0xf000003fU,
+0xf000007fU,
+0xf00000ffU,
+0xf00001ffU,
+0xf00003ffU,
+0xf00007ffU,
+0xf0000fffU,
+0xf0001fffU,
+0xf0003fffU,
+0xf0007fffU,
+0xf000ffffU,
+0xf001ffffU,
+0xf003ffffU,
+0xf007ffffU,
+0xf00fffffU,
+0xf01fffffU,
+0xf03fffffU,
+0xf07fffffU,
+0xf0ffffffU,
+0xf1ffffffU,
+0xf3ffffffU,
+0xf7ffffffU
+},
+{
+0xe0000000U,
+0xe0000001U,
+0xe0000003U,
+0xe0000007U,
+0xe000000fU,
+0xe000001fU,
+0xe000003fU,
+0xe000007fU,
+0xe00000ffU,
+0xe00001ffU,
+0xe00003ffU,
+0xe00007ffU,
+0xe0000fffU,
+0xe0001fffU,
+0xe0003fffU,
+0xe0007fffU,
+0xe000ffffU,
+0xe001ffffU,
+0xe003ffffU,
+0xe007ffffU,
+0xe00fffffU,
+0xe01fffffU,
+0xe03fffffU,
+0xe07fffffU,
+0xe0ffffffU,
+0xe1ffffffU,
+0xe3ffffffU,
+0xe7ffffffU,
+0xefffffffU
+},
+{
+0xc0000000U,
+0xc0000001U,
+0xc0000003U,
+0xc0000007U,
+0xc000000fU,
+0xc000001fU,
+0xc000003fU,
+0xc000007fU,
+0xc00000ffU,
+0xc00001ffU,
+0xc00003ffU,
+0xc00007ffU,
+0xc0000fffU,
+0xc0001fffU,
+0xc0003fffU,
+0xc0007fffU,
+0xc000ffffU,
+0xc001ffffU,
+0xc003ffffU,
+0xc007ffffU,
+0xc00fffffU,
+0xc01fffffU,
+0xc03fffffU,
+0xc07fffffU,
+0xc0ffffffU,
+0xc1ffffffU,
+0xc3ffffffU,
+0xc7ffffffU,
+0xcfffffffU,
+0xdfffffffU
+},
+{
+0x80000000U,
+0x80000001U,
+0x80000003U,
+0x80000007U,
+0x8000000fU,
+0x8000001fU,
+0x8000003fU,
+0x8000007fU,
+0x800000ffU,
+0x800001ffU,
+0x800003ffU,
+0x800007ffU,
+0x80000fffU,
+0x80001fffU,
+0x80003fffU,
+0x80007fffU,
+0x8000ffffU,
+0x8001ffffU,
+0x8003ffffU,
+0x8007ffffU,
+0x800fffffU,
+0x801fffffU,
+0x803fffffU,
+0x807fffffU,
+0x80ffffffU,
+0x81ffffffU,
+0x83ffffffU,
+0x87ffffffU,
+0x8fffffffU,
+0x9fffffffU,
+0xbfffffffU
+},
+{
+0x0U,
+0x1U,
+0x3U,
+0x7U,
+0xfU,
+0x1fU,
+0x3fU,
+0x7fU,
+0xffU,
+0x1ffU,
+0x3ffU,
+0x7ffU,
+0xfffU,
+0x1fffU,
+0x3fffU,
+0x7fffU,
+0xffffU,
+0x1ffffU,
+0x3ffffU,
+0x7ffffU,
+0xfffffU,
+0x1fffffU,
+0x3fffffU,
+0x7fffffU,
+0xffffffU,
+0x1ffffffU,
+0x3ffffffU,
+0x7ffffffU,
+0xfffffffU,
+0x1fffffffU,
+0x3fffffffU,
+0x7fffffffU
+}
+};
+
+} // namespace sc_dt
+
+#endif
diff --git a/ext/systemc/src/sysc/datatypes/int/sc_int64_io.cpp b/ext/systemc/src/sysc/datatypes/int/sc_int64_io.cpp
new file mode 100644
index 000000000..b43bc6ed8
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/int/sc_int64_io.cpp
@@ -0,0 +1,182 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_int64_io.cpp --
+
+ Original Author: Amit Rao, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// $Log: sc_int64_io.cpp,v $
+// Revision 1.2 2011/02/18 20:19:14 acg
+// Andy Goodrich: updating Copyright notice.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:49:31 acg
+// Added $Log command so that CVS check in comments are reproduced in the
+// source.
+//
+
+#include "sysc/utils/sc_iostream.h"
+#include "sysc/datatypes/int/sc_unsigned.h"
+#include "sysc/datatypes/int/sc_signed.h"
+#include "sysc/datatypes/int/sc_int_base.h"
+#include "sysc/datatypes/int/sc_uint_base.h"
+
+
+#if defined( _MSC_VER )
+
+namespace sc_dt
+{
+
+static void
+write_uint64(::std::ostream& os, uint64 val, int sign)
+{
+ const int WRITE_BUF_SIZE = 10 + sizeof(uint64)*3;
+ char buf[WRITE_BUF_SIZE];
+ char* buf_ptr = buf + WRITE_BUF_SIZE;
+ const char* show_base = "";
+ int show_base_len = 0;
+ int show_pos = 0;
+ fmtflags flags = os.flags();
+
+ if ((flags & ::std::ios::basefield) == ::std::ios::oct) {
+ do {
+ *--buf_ptr = (char)((val & 7) + '0');
+ val = val >> 3;
+ } while (val != 0);
+ if ((flags & ::std::ios::showbase) && (*buf_ptr != '0'))
+ *--buf_ptr = '0';
+ } else if ((flags & ::std::ios::basefield) == ::std::ios::hex) {
+ const char* xdigs = (flags & ::std::ios::uppercase) ?
+ "0123456789ABCDEF0X" :
+ "0123456789abcdef0x";
+ do {
+ *--buf_ptr = xdigs[val & 15];
+ val = val >> 4;
+ } while (val != 0);
+ if ((flags & ::std::ios::showbase)) {
+ show_base = xdigs + 16;
+ show_base_len = 2;
+ }
+ } else {
+ while (val > UINT_MAX) {
+ *--buf_ptr = (char)((val % 10) + '0');
+ val /= 10;
+ }
+ unsigned ival = (unsigned) val;
+ do {
+ *--buf_ptr = (ival % 10) + '0';
+ ival /= 10;
+ } while (ival != 0);
+ if (sign > 0 && (flags & ::std::ios::showpos))
+ show_pos = 1;
+ }
+
+ int buf_len = buf + WRITE_BUF_SIZE - buf_ptr;
+ int w = os.width(0);
+
+ int len = buf_len + show_pos;
+ if (sign < 0) len++;
+ len += show_base_len;
+
+ int padding = len > w ? 0 : w - len;
+ fmtflags pad_kind = flags & ::std::ios::adjustfield;
+ char fill_char = os.fill();
+
+ if (padding > 0 &&
+ ::std::ios::left != pad_kind &&
+ ::std::ios::internal != pad_kind) {
+ for (int i = padding - 1; i >= 0; --i) {
+ if (! os.put(fill_char))
+ goto fail;
+ }
+ }
+ if (sign < 0 || show_pos) {
+ if (! os.put(sign < 0 ? '-' : '+'))
+ goto fail;
+ }
+ if (show_base_len) {
+ if (! os.write(show_base, show_base_len))
+ goto fail;
+ }
+ if ((fmtflags)::std::ios::internal == pad_kind && padding > 0) {
+ for (int i = padding - 1; i >= 0; --i) {
+ if (! os.put(fill_char))
+ goto fail;
+ }
+ }
+ if (! os.write(buf_ptr, buf_len))
+ goto fail;
+ if ((fmtflags)::std::ios::left == pad_kind && padding > 0) {
+ for (int i = padding - 1; i >= 0; --i) {
+ if (! os.put(fill_char))
+ goto fail;
+ }
+ }
+ os.osfx();
+ return;
+fail:
+ //os.set(::std::ios::badbit);
+ os.osfx();
+}
+
+::std::ostream&
+operator << ( ::std::ostream& os, int64 n )
+{
+ if (os.opfx()) {
+ int sign = 1;
+ uint64 abs_n = (uint64) n;
+ if (n < 0 && (os.flags() & (::std::ios::oct|::std::ios::hex)) == 0) {
+ abs_n = -1*((uint64) n);
+ sign = -1;
+ }
+ sc_dt::write_uint64(os, abs_n, sign);
+ }
+ return os;
+}
+
+::std::ostream&
+operator << ( ::std::ostream& os, uint64 n )
+{
+ if (os.opfx()) {
+ sc_dt::write_uint64(os, n, 0);
+ }
+ return os;
+}
+
+} // namespace sc_dt
+
+
+#endif
diff --git a/ext/systemc/src/sysc/datatypes/int/sc_int64_mask.cpp b/ext/systemc/src/sysc/datatypes/int/sc_int64_mask.cpp
new file mode 100644
index 000000000..df69a6dda
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/int/sc_int64_mask.cpp
@@ -0,0 +1,4502 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_int64_mask.cpp -- Fills the mask_int lookup table to enable efficient
+ part-selection on 64-bit sc_ints and sc_uints.
+
+ Original Author: Amit Rao, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc.
+ Description of Modification: - Resolved ambiguity with sc_(un)signed.
+ - Merged the code for 64- and 32-bit versions
+ via the constants in sc_nbdefs.h.
+ - Eliminated redundant file inclusions.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// $Log: sc_int64_mask.cpp,v $
+// Revision 1.3 2011/02/18 20:19:14 acg
+// Andy Goodrich: updating Copyright notice.
+//
+// Revision 1.2 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:49:31 acg
+// Added $Log command so that CVS check in comments are reproduced in the
+// source.
+//
+
+#ifndef _32BIT_
+
+#include "sysc/datatypes/int/sc_int_base.h"
+#include "sysc/datatypes/int/sc_uint_base.h"
+
+
+namespace sc_dt
+{
+
+#if !defined(_WIN32) || defined(__MINGW32__)
+
+const uint_type mask_int[SC_INTWIDTH][SC_INTWIDTH] =
+{
+{
+0xfffffffffffffffeULL
+},
+{
+0xfffffffffffffffcULL,
+0xfffffffffffffffdULL
+},
+{
+0xfffffffffffffff8ULL,
+0xfffffffffffffff9ULL,
+0xfffffffffffffffbULL
+},
+{
+0xfffffffffffffff0ULL,
+0xfffffffffffffff1ULL,
+0xfffffffffffffff3ULL,
+0xfffffffffffffff7ULL
+},
+{
+0xffffffffffffffe0ULL,
+0xffffffffffffffe1ULL,
+0xffffffffffffffe3ULL,
+0xffffffffffffffe7ULL,
+0xffffffffffffffefULL
+},
+{
+0xffffffffffffffc0ULL,
+0xffffffffffffffc1ULL,
+0xffffffffffffffc3ULL,
+0xffffffffffffffc7ULL,
+0xffffffffffffffcfULL,
+0xffffffffffffffdfULL
+},
+{
+0xffffffffffffff80ULL,
+0xffffffffffffff81ULL,
+0xffffffffffffff83ULL,
+0xffffffffffffff87ULL,
+0xffffffffffffff8fULL,
+0xffffffffffffff9fULL,
+0xffffffffffffffbfULL
+},
+{
+0xffffffffffffff00ULL,
+0xffffffffffffff01ULL,
+0xffffffffffffff03ULL,
+0xffffffffffffff07ULL,
+0xffffffffffffff0fULL,
+0xffffffffffffff1fULL,
+0xffffffffffffff3fULL,
+0xffffffffffffff7fULL
+},
+{
+0xfffffffffffffe00ULL,
+0xfffffffffffffe01ULL,
+0xfffffffffffffe03ULL,
+0xfffffffffffffe07ULL,
+0xfffffffffffffe0fULL,
+0xfffffffffffffe1fULL,
+0xfffffffffffffe3fULL,
+0xfffffffffffffe7fULL,
+0xfffffffffffffeffULL
+},
+{
+0xfffffffffffffc00ULL,
+0xfffffffffffffc01ULL,
+0xfffffffffffffc03ULL,
+0xfffffffffffffc07ULL,
+0xfffffffffffffc0fULL,
+0xfffffffffffffc1fULL,
+0xfffffffffffffc3fULL,
+0xfffffffffffffc7fULL,
+0xfffffffffffffcffULL,
+0xfffffffffffffdffULL
+},
+{
+0xfffffffffffff800ULL,
+0xfffffffffffff801ULL,
+0xfffffffffffff803ULL,
+0xfffffffffffff807ULL,
+0xfffffffffffff80fULL,
+0xfffffffffffff81fULL,
+0xfffffffffffff83fULL,
+0xfffffffffffff87fULL,
+0xfffffffffffff8ffULL,
+0xfffffffffffff9ffULL,
+0xfffffffffffffbffULL
+},
+{
+0xfffffffffffff000ULL,
+0xfffffffffffff001ULL,
+0xfffffffffffff003ULL,
+0xfffffffffffff007ULL,
+0xfffffffffffff00fULL,
+0xfffffffffffff01fULL,
+0xfffffffffffff03fULL,
+0xfffffffffffff07fULL,
+0xfffffffffffff0ffULL,
+0xfffffffffffff1ffULL,
+0xfffffffffffff3ffULL,
+0xfffffffffffff7ffULL
+},
+{
+0xffffffffffffe000ULL,
+0xffffffffffffe001ULL,
+0xffffffffffffe003ULL,
+0xffffffffffffe007ULL,
+0xffffffffffffe00fULL,
+0xffffffffffffe01fULL,
+0xffffffffffffe03fULL,
+0xffffffffffffe07fULL,
+0xffffffffffffe0ffULL,
+0xffffffffffffe1ffULL,
+0xffffffffffffe3ffULL,
+0xffffffffffffe7ffULL,
+0xffffffffffffefffULL
+},
+{
+0xffffffffffffc000ULL,
+0xffffffffffffc001ULL,
+0xffffffffffffc003ULL,
+0xffffffffffffc007ULL,
+0xffffffffffffc00fULL,
+0xffffffffffffc01fULL,
+0xffffffffffffc03fULL,
+0xffffffffffffc07fULL,
+0xffffffffffffc0ffULL,
+0xffffffffffffc1ffULL,
+0xffffffffffffc3ffULL,
+0xffffffffffffc7ffULL,
+0xffffffffffffcfffULL,
+0xffffffffffffdfffULL
+},
+{
+0xffffffffffff8000ULL,
+0xffffffffffff8001ULL,
+0xffffffffffff8003ULL,
+0xffffffffffff8007ULL,
+0xffffffffffff800fULL,
+0xffffffffffff801fULL,
+0xffffffffffff803fULL,
+0xffffffffffff807fULL,
+0xffffffffffff80ffULL,
+0xffffffffffff81ffULL,
+0xffffffffffff83ffULL,
+0xffffffffffff87ffULL,
+0xffffffffffff8fffULL,
+0xffffffffffff9fffULL,
+0xffffffffffffbfffULL
+},
+{
+0xffffffffffff0000ULL,
+0xffffffffffff0001ULL,
+0xffffffffffff0003ULL,
+0xffffffffffff0007ULL,
+0xffffffffffff000fULL,
+0xffffffffffff001fULL,
+0xffffffffffff003fULL,
+0xffffffffffff007fULL,
+0xffffffffffff00ffULL,
+0xffffffffffff01ffULL,
+0xffffffffffff03ffULL,
+0xffffffffffff07ffULL,
+0xffffffffffff0fffULL,
+0xffffffffffff1fffULL,
+0xffffffffffff3fffULL,
+0xffffffffffff7fffULL
+},
+{
+0xfffffffffffe0000ULL,
+0xfffffffffffe0001ULL,
+0xfffffffffffe0003ULL,
+0xfffffffffffe0007ULL,
+0xfffffffffffe000fULL,
+0xfffffffffffe001fULL,
+0xfffffffffffe003fULL,
+0xfffffffffffe007fULL,
+0xfffffffffffe00ffULL,
+0xfffffffffffe01ffULL,
+0xfffffffffffe03ffULL,
+0xfffffffffffe07ffULL,
+0xfffffffffffe0fffULL,
+0xfffffffffffe1fffULL,
+0xfffffffffffe3fffULL,
+0xfffffffffffe7fffULL,
+0xfffffffffffeffffULL
+},
+{
+0xfffffffffffc0000ULL,
+0xfffffffffffc0001ULL,
+0xfffffffffffc0003ULL,
+0xfffffffffffc0007ULL,
+0xfffffffffffc000fULL,
+0xfffffffffffc001fULL,
+0xfffffffffffc003fULL,
+0xfffffffffffc007fULL,
+0xfffffffffffc00ffULL,
+0xfffffffffffc01ffULL,
+0xfffffffffffc03ffULL,
+0xfffffffffffc07ffULL,
+0xfffffffffffc0fffULL,
+0xfffffffffffc1fffULL,
+0xfffffffffffc3fffULL,
+0xfffffffffffc7fffULL,
+0xfffffffffffcffffULL,
+0xfffffffffffdffffULL
+},
+{
+0xfffffffffff80000ULL,
+0xfffffffffff80001ULL,
+0xfffffffffff80003ULL,
+0xfffffffffff80007ULL,
+0xfffffffffff8000fULL,
+0xfffffffffff8001fULL,
+0xfffffffffff8003fULL,
+0xfffffffffff8007fULL,
+0xfffffffffff800ffULL,
+0xfffffffffff801ffULL,
+0xfffffffffff803ffULL,
+0xfffffffffff807ffULL,
+0xfffffffffff80fffULL,
+0xfffffffffff81fffULL,
+0xfffffffffff83fffULL,
+0xfffffffffff87fffULL,
+0xfffffffffff8ffffULL,
+0xfffffffffff9ffffULL,
+0xfffffffffffbffffULL
+},
+{
+0xfffffffffff00000ULL,
+0xfffffffffff00001ULL,
+0xfffffffffff00003ULL,
+0xfffffffffff00007ULL,
+0xfffffffffff0000fULL,
+0xfffffffffff0001fULL,
+0xfffffffffff0003fULL,
+0xfffffffffff0007fULL,
+0xfffffffffff000ffULL,
+0xfffffffffff001ffULL,
+0xfffffffffff003ffULL,
+0xfffffffffff007ffULL,
+0xfffffffffff00fffULL,
+0xfffffffffff01fffULL,
+0xfffffffffff03fffULL,
+0xfffffffffff07fffULL,
+0xfffffffffff0ffffULL,
+0xfffffffffff1ffffULL,
+0xfffffffffff3ffffULL,
+0xfffffffffff7ffffULL
+},
+{
+0xffffffffffe00000ULL,
+0xffffffffffe00001ULL,
+0xffffffffffe00003ULL,
+0xffffffffffe00007ULL,
+0xffffffffffe0000fULL,
+0xffffffffffe0001fULL,
+0xffffffffffe0003fULL,
+0xffffffffffe0007fULL,
+0xffffffffffe000ffULL,
+0xffffffffffe001ffULL,
+0xffffffffffe003ffULL,
+0xffffffffffe007ffULL,
+0xffffffffffe00fffULL,
+0xffffffffffe01fffULL,
+0xffffffffffe03fffULL,
+0xffffffffffe07fffULL,
+0xffffffffffe0ffffULL,
+0xffffffffffe1ffffULL,
+0xffffffffffe3ffffULL,
+0xffffffffffe7ffffULL,
+0xffffffffffefffffULL
+},
+{
+0xffffffffffc00000ULL,
+0xffffffffffc00001ULL,
+0xffffffffffc00003ULL,
+0xffffffffffc00007ULL,
+0xffffffffffc0000fULL,
+0xffffffffffc0001fULL,
+0xffffffffffc0003fULL,
+0xffffffffffc0007fULL,
+0xffffffffffc000ffULL,
+0xffffffffffc001ffULL,
+0xffffffffffc003ffULL,
+0xffffffffffc007ffULL,
+0xffffffffffc00fffULL,
+0xffffffffffc01fffULL,
+0xffffffffffc03fffULL,
+0xffffffffffc07fffULL,
+0xffffffffffc0ffffULL,
+0xffffffffffc1ffffULL,
+0xffffffffffc3ffffULL,
+0xffffffffffc7ffffULL,
+0xffffffffffcfffffULL,
+0xffffffffffdfffffULL
+},
+{
+0xffffffffff800000ULL,
+0xffffffffff800001ULL,
+0xffffffffff800003ULL,
+0xffffffffff800007ULL,
+0xffffffffff80000fULL,
+0xffffffffff80001fULL,
+0xffffffffff80003fULL,
+0xffffffffff80007fULL,
+0xffffffffff8000ffULL,
+0xffffffffff8001ffULL,
+0xffffffffff8003ffULL,
+0xffffffffff8007ffULL,
+0xffffffffff800fffULL,
+0xffffffffff801fffULL,
+0xffffffffff803fffULL,
+0xffffffffff807fffULL,
+0xffffffffff80ffffULL,
+0xffffffffff81ffffULL,
+0xffffffffff83ffffULL,
+0xffffffffff87ffffULL,
+0xffffffffff8fffffULL,
+0xffffffffff9fffffULL,
+0xffffffffffbfffffULL
+},
+{
+0xffffffffff000000ULL,
+0xffffffffff000001ULL,
+0xffffffffff000003ULL,
+0xffffffffff000007ULL,
+0xffffffffff00000fULL,
+0xffffffffff00001fULL,
+0xffffffffff00003fULL,
+0xffffffffff00007fULL,
+0xffffffffff0000ffULL,
+0xffffffffff0001ffULL,
+0xffffffffff0003ffULL,
+0xffffffffff0007ffULL,
+0xffffffffff000fffULL,
+0xffffffffff001fffULL,
+0xffffffffff003fffULL,
+0xffffffffff007fffULL,
+0xffffffffff00ffffULL,
+0xffffffffff01ffffULL,
+0xffffffffff03ffffULL,
+0xffffffffff07ffffULL,
+0xffffffffff0fffffULL,
+0xffffffffff1fffffULL,
+0xffffffffff3fffffULL,
+0xffffffffff7fffffULL
+},
+{
+0xfffffffffe000000ULL,
+0xfffffffffe000001ULL,
+0xfffffffffe000003ULL,
+0xfffffffffe000007ULL,
+0xfffffffffe00000fULL,
+0xfffffffffe00001fULL,
+0xfffffffffe00003fULL,
+0xfffffffffe00007fULL,
+0xfffffffffe0000ffULL,
+0xfffffffffe0001ffULL,
+0xfffffffffe0003ffULL,
+0xfffffffffe0007ffULL,
+0xfffffffffe000fffULL,
+0xfffffffffe001fffULL,
+0xfffffffffe003fffULL,
+0xfffffffffe007fffULL,
+0xfffffffffe00ffffULL,
+0xfffffffffe01ffffULL,
+0xfffffffffe03ffffULL,
+0xfffffffffe07ffffULL,
+0xfffffffffe0fffffULL,
+0xfffffffffe1fffffULL,
+0xfffffffffe3fffffULL,
+0xfffffffffe7fffffULL,
+0xfffffffffeffffffULL
+},
+{
+0xfffffffffc000000ULL,
+0xfffffffffc000001ULL,
+0xfffffffffc000003ULL,
+0xfffffffffc000007ULL,
+0xfffffffffc00000fULL,
+0xfffffffffc00001fULL,
+0xfffffffffc00003fULL,
+0xfffffffffc00007fULL,
+0xfffffffffc0000ffULL,
+0xfffffffffc0001ffULL,
+0xfffffffffc0003ffULL,
+0xfffffffffc0007ffULL,
+0xfffffffffc000fffULL,
+0xfffffffffc001fffULL,
+0xfffffffffc003fffULL,
+0xfffffffffc007fffULL,
+0xfffffffffc00ffffULL,
+0xfffffffffc01ffffULL,
+0xfffffffffc03ffffULL,
+0xfffffffffc07ffffULL,
+0xfffffffffc0fffffULL,
+0xfffffffffc1fffffULL,
+0xfffffffffc3fffffULL,
+0xfffffffffc7fffffULL,
+0xfffffffffcffffffULL,
+0xfffffffffdffffffULL
+},
+{
+0xfffffffff8000000ULL,
+0xfffffffff8000001ULL,
+0xfffffffff8000003ULL,
+0xfffffffff8000007ULL,
+0xfffffffff800000fULL,
+0xfffffffff800001fULL,
+0xfffffffff800003fULL,
+0xfffffffff800007fULL,
+0xfffffffff80000ffULL,
+0xfffffffff80001ffULL,
+0xfffffffff80003ffULL,
+0xfffffffff80007ffULL,
+0xfffffffff8000fffULL,
+0xfffffffff8001fffULL,
+0xfffffffff8003fffULL,
+0xfffffffff8007fffULL,
+0xfffffffff800ffffULL,
+0xfffffffff801ffffULL,
+0xfffffffff803ffffULL,
+0xfffffffff807ffffULL,
+0xfffffffff80fffffULL,
+0xfffffffff81fffffULL,
+0xfffffffff83fffffULL,
+0xfffffffff87fffffULL,
+0xfffffffff8ffffffULL,
+0xfffffffff9ffffffULL,
+0xfffffffffbffffffULL
+},
+{
+0xfffffffff0000000ULL,
+0xfffffffff0000001ULL,
+0xfffffffff0000003ULL,
+0xfffffffff0000007ULL,
+0xfffffffff000000fULL,
+0xfffffffff000001fULL,
+0xfffffffff000003fULL,
+0xfffffffff000007fULL,
+0xfffffffff00000ffULL,
+0xfffffffff00001ffULL,
+0xfffffffff00003ffULL,
+0xfffffffff00007ffULL,
+0xfffffffff0000fffULL,
+0xfffffffff0001fffULL,
+0xfffffffff0003fffULL,
+0xfffffffff0007fffULL,
+0xfffffffff000ffffULL,
+0xfffffffff001ffffULL,
+0xfffffffff003ffffULL,
+0xfffffffff007ffffULL,
+0xfffffffff00fffffULL,
+0xfffffffff01fffffULL,
+0xfffffffff03fffffULL,
+0xfffffffff07fffffULL,
+0xfffffffff0ffffffULL,
+0xfffffffff1ffffffULL,
+0xfffffffff3ffffffULL,
+0xfffffffff7ffffffULL
+},
+{
+0xffffffffe0000000ULL,
+0xffffffffe0000001ULL,
+0xffffffffe0000003ULL,
+0xffffffffe0000007ULL,
+0xffffffffe000000fULL,
+0xffffffffe000001fULL,
+0xffffffffe000003fULL,
+0xffffffffe000007fULL,
+0xffffffffe00000ffULL,
+0xffffffffe00001ffULL,
+0xffffffffe00003ffULL,
+0xffffffffe00007ffULL,
+0xffffffffe0000fffULL,
+0xffffffffe0001fffULL,
+0xffffffffe0003fffULL,
+0xffffffffe0007fffULL,
+0xffffffffe000ffffULL,
+0xffffffffe001ffffULL,
+0xffffffffe003ffffULL,
+0xffffffffe007ffffULL,
+0xffffffffe00fffffULL,
+0xffffffffe01fffffULL,
+0xffffffffe03fffffULL,
+0xffffffffe07fffffULL,
+0xffffffffe0ffffffULL,
+0xffffffffe1ffffffULL,
+0xffffffffe3ffffffULL,
+0xffffffffe7ffffffULL,
+0xffffffffefffffffULL
+},
+{
+0xffffffffc0000000ULL,
+0xffffffffc0000001ULL,
+0xffffffffc0000003ULL,
+0xffffffffc0000007ULL,
+0xffffffffc000000fULL,
+0xffffffffc000001fULL,
+0xffffffffc000003fULL,
+0xffffffffc000007fULL,
+0xffffffffc00000ffULL,
+0xffffffffc00001ffULL,
+0xffffffffc00003ffULL,
+0xffffffffc00007ffULL,
+0xffffffffc0000fffULL,
+0xffffffffc0001fffULL,
+0xffffffffc0003fffULL,
+0xffffffffc0007fffULL,
+0xffffffffc000ffffULL,
+0xffffffffc001ffffULL,
+0xffffffffc003ffffULL,
+0xffffffffc007ffffULL,
+0xffffffffc00fffffULL,
+0xffffffffc01fffffULL,
+0xffffffffc03fffffULL,
+0xffffffffc07fffffULL,
+0xffffffffc0ffffffULL,
+0xffffffffc1ffffffULL,
+0xffffffffc3ffffffULL,
+0xffffffffc7ffffffULL,
+0xffffffffcfffffffULL,
+0xffffffffdfffffffULL
+},
+{
+0xffffffff80000000ULL,
+0xffffffff80000001ULL,
+0xffffffff80000003ULL,
+0xffffffff80000007ULL,
+0xffffffff8000000fULL,
+0xffffffff8000001fULL,
+0xffffffff8000003fULL,
+0xffffffff8000007fULL,
+0xffffffff800000ffULL,
+0xffffffff800001ffULL,
+0xffffffff800003ffULL,
+0xffffffff800007ffULL,
+0xffffffff80000fffULL,
+0xffffffff80001fffULL,
+0xffffffff80003fffULL,
+0xffffffff80007fffULL,
+0xffffffff8000ffffULL,
+0xffffffff8001ffffULL,
+0xffffffff8003ffffULL,
+0xffffffff8007ffffULL,
+0xffffffff800fffffULL,
+0xffffffff801fffffULL,
+0xffffffff803fffffULL,
+0xffffffff807fffffULL,
+0xffffffff80ffffffULL,
+0xffffffff81ffffffULL,
+0xffffffff83ffffffULL,
+0xffffffff87ffffffULL,
+0xffffffff8fffffffULL,
+0xffffffff9fffffffULL,
+0xffffffffbfffffffULL
+},
+{
+0xffffffff00000000ULL,
+0xffffffff00000001ULL,
+0xffffffff00000003ULL,
+0xffffffff00000007ULL,
+0xffffffff0000000fULL,
+0xffffffff0000001fULL,
+0xffffffff0000003fULL,
+0xffffffff0000007fULL,
+0xffffffff000000ffULL,
+0xffffffff000001ffULL,
+0xffffffff000003ffULL,
+0xffffffff000007ffULL,
+0xffffffff00000fffULL,
+0xffffffff00001fffULL,
+0xffffffff00003fffULL,
+0xffffffff00007fffULL,
+0xffffffff0000ffffULL,
+0xffffffff0001ffffULL,
+0xffffffff0003ffffULL,
+0xffffffff0007ffffULL,
+0xffffffff000fffffULL,
+0xffffffff001fffffULL,
+0xffffffff003fffffULL,
+0xffffffff007fffffULL,
+0xffffffff00ffffffULL,
+0xffffffff01ffffffULL,
+0xffffffff03ffffffULL,
+0xffffffff07ffffffULL,
+0xffffffff0fffffffULL,
+0xffffffff1fffffffULL,
+0xffffffff3fffffffULL,
+0xffffffff7fffffffULL
+},
+{
+0xfffffffe00000000ULL,
+0xfffffffe00000001ULL,
+0xfffffffe00000003ULL,
+0xfffffffe00000007ULL,
+0xfffffffe0000000fULL,
+0xfffffffe0000001fULL,
+0xfffffffe0000003fULL,
+0xfffffffe0000007fULL,
+0xfffffffe000000ffULL,
+0xfffffffe000001ffULL,
+0xfffffffe000003ffULL,
+0xfffffffe000007ffULL,
+0xfffffffe00000fffULL,
+0xfffffffe00001fffULL,
+0xfffffffe00003fffULL,
+0xfffffffe00007fffULL,
+0xfffffffe0000ffffULL,
+0xfffffffe0001ffffULL,
+0xfffffffe0003ffffULL,
+0xfffffffe0007ffffULL,
+0xfffffffe000fffffULL,
+0xfffffffe001fffffULL,
+0xfffffffe003fffffULL,
+0xfffffffe007fffffULL,
+0xfffffffe00ffffffULL,
+0xfffffffe01ffffffULL,
+0xfffffffe03ffffffULL,
+0xfffffffe07ffffffULL,
+0xfffffffe0fffffffULL,
+0xfffffffe1fffffffULL,
+0xfffffffe3fffffffULL,
+0xfffffffe7fffffffULL,
+0xfffffffeffffffffULL
+},
+{
+0xfffffffc00000000ULL,
+0xfffffffc00000001ULL,
+0xfffffffc00000003ULL,
+0xfffffffc00000007ULL,
+0xfffffffc0000000fULL,
+0xfffffffc0000001fULL,
+0xfffffffc0000003fULL,
+0xfffffffc0000007fULL,
+0xfffffffc000000ffULL,
+0xfffffffc000001ffULL,
+0xfffffffc000003ffULL,
+0xfffffffc000007ffULL,
+0xfffffffc00000fffULL,
+0xfffffffc00001fffULL,
+0xfffffffc00003fffULL,
+0xfffffffc00007fffULL,
+0xfffffffc0000ffffULL,
+0xfffffffc0001ffffULL,
+0xfffffffc0003ffffULL,
+0xfffffffc0007ffffULL,
+0xfffffffc000fffffULL,
+0xfffffffc001fffffULL,
+0xfffffffc003fffffULL,
+0xfffffffc007fffffULL,
+0xfffffffc00ffffffULL,
+0xfffffffc01ffffffULL,
+0xfffffffc03ffffffULL,
+0xfffffffc07ffffffULL,
+0xfffffffc0fffffffULL,
+0xfffffffc1fffffffULL,
+0xfffffffc3fffffffULL,
+0xfffffffc7fffffffULL,
+0xfffffffcffffffffULL,
+0xfffffffdffffffffULL
+},
+{
+0xfffffff800000000ULL,
+0xfffffff800000001ULL,
+0xfffffff800000003ULL,
+0xfffffff800000007ULL,
+0xfffffff80000000fULL,
+0xfffffff80000001fULL,
+0xfffffff80000003fULL,
+0xfffffff80000007fULL,
+0xfffffff8000000ffULL,
+0xfffffff8000001ffULL,
+0xfffffff8000003ffULL,
+0xfffffff8000007ffULL,
+0xfffffff800000fffULL,
+0xfffffff800001fffULL,
+0xfffffff800003fffULL,
+0xfffffff800007fffULL,
+0xfffffff80000ffffULL,
+0xfffffff80001ffffULL,
+0xfffffff80003ffffULL,
+0xfffffff80007ffffULL,
+0xfffffff8000fffffULL,
+0xfffffff8001fffffULL,
+0xfffffff8003fffffULL,
+0xfffffff8007fffffULL,
+0xfffffff800ffffffULL,
+0xfffffff801ffffffULL,
+0xfffffff803ffffffULL,
+0xfffffff807ffffffULL,
+0xfffffff80fffffffULL,
+0xfffffff81fffffffULL,
+0xfffffff83fffffffULL,
+0xfffffff87fffffffULL,
+0xfffffff8ffffffffULL,
+0xfffffff9ffffffffULL,
+0xfffffffbffffffffULL
+},
+{
+0xfffffff000000000ULL,
+0xfffffff000000001ULL,
+0xfffffff000000003ULL,
+0xfffffff000000007ULL,
+0xfffffff00000000fULL,
+0xfffffff00000001fULL,
+0xfffffff00000003fULL,
+0xfffffff00000007fULL,
+0xfffffff0000000ffULL,
+0xfffffff0000001ffULL,
+0xfffffff0000003ffULL,
+0xfffffff0000007ffULL,
+0xfffffff000000fffULL,
+0xfffffff000001fffULL,
+0xfffffff000003fffULL,
+0xfffffff000007fffULL,
+0xfffffff00000ffffULL,
+0xfffffff00001ffffULL,
+0xfffffff00003ffffULL,
+0xfffffff00007ffffULL,
+0xfffffff0000fffffULL,
+0xfffffff0001fffffULL,
+0xfffffff0003fffffULL,
+0xfffffff0007fffffULL,
+0xfffffff000ffffffULL,
+0xfffffff001ffffffULL,
+0xfffffff003ffffffULL,
+0xfffffff007ffffffULL,
+0xfffffff00fffffffULL,
+0xfffffff01fffffffULL,
+0xfffffff03fffffffULL,
+0xfffffff07fffffffULL,
+0xfffffff0ffffffffULL,
+0xfffffff1ffffffffULL,
+0xfffffff3ffffffffULL,
+0xfffffff7ffffffffULL
+},
+{
+0xffffffe000000000ULL,
+0xffffffe000000001ULL,
+0xffffffe000000003ULL,
+0xffffffe000000007ULL,
+0xffffffe00000000fULL,
+0xffffffe00000001fULL,
+0xffffffe00000003fULL,
+0xffffffe00000007fULL,
+0xffffffe0000000ffULL,
+0xffffffe0000001ffULL,
+0xffffffe0000003ffULL,
+0xffffffe0000007ffULL,
+0xffffffe000000fffULL,
+0xffffffe000001fffULL,
+0xffffffe000003fffULL,
+0xffffffe000007fffULL,
+0xffffffe00000ffffULL,
+0xffffffe00001ffffULL,
+0xffffffe00003ffffULL,
+0xffffffe00007ffffULL,
+0xffffffe0000fffffULL,
+0xffffffe0001fffffULL,
+0xffffffe0003fffffULL,
+0xffffffe0007fffffULL,
+0xffffffe000ffffffULL,
+0xffffffe001ffffffULL,
+0xffffffe003ffffffULL,
+0xffffffe007ffffffULL,
+0xffffffe00fffffffULL,
+0xffffffe01fffffffULL,
+0xffffffe03fffffffULL,
+0xffffffe07fffffffULL,
+0xffffffe0ffffffffULL,
+0xffffffe1ffffffffULL,
+0xffffffe3ffffffffULL,
+0xffffffe7ffffffffULL,
+0xffffffefffffffffULL
+},
+{
+0xffffffc000000000ULL,
+0xffffffc000000001ULL,
+0xffffffc000000003ULL,
+0xffffffc000000007ULL,
+0xffffffc00000000fULL,
+0xffffffc00000001fULL,
+0xffffffc00000003fULL,
+0xffffffc00000007fULL,
+0xffffffc0000000ffULL,
+0xffffffc0000001ffULL,
+0xffffffc0000003ffULL,
+0xffffffc0000007ffULL,
+0xffffffc000000fffULL,
+0xffffffc000001fffULL,
+0xffffffc000003fffULL,
+0xffffffc000007fffULL,
+0xffffffc00000ffffULL,
+0xffffffc00001ffffULL,
+0xffffffc00003ffffULL,
+0xffffffc00007ffffULL,
+0xffffffc0000fffffULL,
+0xffffffc0001fffffULL,
+0xffffffc0003fffffULL,
+0xffffffc0007fffffULL,
+0xffffffc000ffffffULL,
+0xffffffc001ffffffULL,
+0xffffffc003ffffffULL,
+0xffffffc007ffffffULL,
+0xffffffc00fffffffULL,
+0xffffffc01fffffffULL,
+0xffffffc03fffffffULL,
+0xffffffc07fffffffULL,
+0xffffffc0ffffffffULL,
+0xffffffc1ffffffffULL,
+0xffffffc3ffffffffULL,
+0xffffffc7ffffffffULL,
+0xffffffcfffffffffULL,
+0xffffffdfffffffffULL
+},
+{
+0xffffff8000000000ULL,
+0xffffff8000000001ULL,
+0xffffff8000000003ULL,
+0xffffff8000000007ULL,
+0xffffff800000000fULL,
+0xffffff800000001fULL,
+0xffffff800000003fULL,
+0xffffff800000007fULL,
+0xffffff80000000ffULL,
+0xffffff80000001ffULL,
+0xffffff80000003ffULL,
+0xffffff80000007ffULL,
+0xffffff8000000fffULL,
+0xffffff8000001fffULL,
+0xffffff8000003fffULL,
+0xffffff8000007fffULL,
+0xffffff800000ffffULL,
+0xffffff800001ffffULL,
+0xffffff800003ffffULL,
+0xffffff800007ffffULL,
+0xffffff80000fffffULL,
+0xffffff80001fffffULL,
+0xffffff80003fffffULL,
+0xffffff80007fffffULL,
+0xffffff8000ffffffULL,
+0xffffff8001ffffffULL,
+0xffffff8003ffffffULL,
+0xffffff8007ffffffULL,
+0xffffff800fffffffULL,
+0xffffff801fffffffULL,
+0xffffff803fffffffULL,
+0xffffff807fffffffULL,
+0xffffff80ffffffffULL,
+0xffffff81ffffffffULL,
+0xffffff83ffffffffULL,
+0xffffff87ffffffffULL,
+0xffffff8fffffffffULL,
+0xffffff9fffffffffULL,
+0xffffffbfffffffffULL
+},
+{
+0xffffff0000000000ULL,
+0xffffff0000000001ULL,
+0xffffff0000000003ULL,
+0xffffff0000000007ULL,
+0xffffff000000000fULL,
+0xffffff000000001fULL,
+0xffffff000000003fULL,
+0xffffff000000007fULL,
+0xffffff00000000ffULL,
+0xffffff00000001ffULL,
+0xffffff00000003ffULL,
+0xffffff00000007ffULL,
+0xffffff0000000fffULL,
+0xffffff0000001fffULL,
+0xffffff0000003fffULL,
+0xffffff0000007fffULL,
+0xffffff000000ffffULL,
+0xffffff000001ffffULL,
+0xffffff000003ffffULL,
+0xffffff000007ffffULL,
+0xffffff00000fffffULL,
+0xffffff00001fffffULL,
+0xffffff00003fffffULL,
+0xffffff00007fffffULL,
+0xffffff0000ffffffULL,
+0xffffff0001ffffffULL,
+0xffffff0003ffffffULL,
+0xffffff0007ffffffULL,
+0xffffff000fffffffULL,
+0xffffff001fffffffULL,
+0xffffff003fffffffULL,
+0xffffff007fffffffULL,
+0xffffff00ffffffffULL,
+0xffffff01ffffffffULL,
+0xffffff03ffffffffULL,
+0xffffff07ffffffffULL,
+0xffffff0fffffffffULL,
+0xffffff1fffffffffULL,
+0xffffff3fffffffffULL,
+0xffffff7fffffffffULL
+},
+{
+0xfffffe0000000000ULL,
+0xfffffe0000000001ULL,
+0xfffffe0000000003ULL,
+0xfffffe0000000007ULL,
+0xfffffe000000000fULL,
+0xfffffe000000001fULL,
+0xfffffe000000003fULL,
+0xfffffe000000007fULL,
+0xfffffe00000000ffULL,
+0xfffffe00000001ffULL,
+0xfffffe00000003ffULL,
+0xfffffe00000007ffULL,
+0xfffffe0000000fffULL,
+0xfffffe0000001fffULL,
+0xfffffe0000003fffULL,
+0xfffffe0000007fffULL,
+0xfffffe000000ffffULL,
+0xfffffe000001ffffULL,
+0xfffffe000003ffffULL,
+0xfffffe000007ffffULL,
+0xfffffe00000fffffULL,
+0xfffffe00001fffffULL,
+0xfffffe00003fffffULL,
+0xfffffe00007fffffULL,
+0xfffffe0000ffffffULL,
+0xfffffe0001ffffffULL,
+0xfffffe0003ffffffULL,
+0xfffffe0007ffffffULL,
+0xfffffe000fffffffULL,
+0xfffffe001fffffffULL,
+0xfffffe003fffffffULL,
+0xfffffe007fffffffULL,
+0xfffffe00ffffffffULL,
+0xfffffe01ffffffffULL,
+0xfffffe03ffffffffULL,
+0xfffffe07ffffffffULL,
+0xfffffe0fffffffffULL,
+0xfffffe1fffffffffULL,
+0xfffffe3fffffffffULL,
+0xfffffe7fffffffffULL,
+0xfffffeffffffffffULL
+},
+{
+0xfffffc0000000000ULL,
+0xfffffc0000000001ULL,
+0xfffffc0000000003ULL,
+0xfffffc0000000007ULL,
+0xfffffc000000000fULL,
+0xfffffc000000001fULL,
+0xfffffc000000003fULL,
+0xfffffc000000007fULL,
+0xfffffc00000000ffULL,
+0xfffffc00000001ffULL,
+0xfffffc00000003ffULL,
+0xfffffc00000007ffULL,
+0xfffffc0000000fffULL,
+0xfffffc0000001fffULL,
+0xfffffc0000003fffULL,
+0xfffffc0000007fffULL,
+0xfffffc000000ffffULL,
+0xfffffc000001ffffULL,
+0xfffffc000003ffffULL,
+0xfffffc000007ffffULL,
+0xfffffc00000fffffULL,
+0xfffffc00001fffffULL,
+0xfffffc00003fffffULL,
+0xfffffc00007fffffULL,
+0xfffffc0000ffffffULL,
+0xfffffc0001ffffffULL,
+0xfffffc0003ffffffULL,
+0xfffffc0007ffffffULL,
+0xfffffc000fffffffULL,
+0xfffffc001fffffffULL,
+0xfffffc003fffffffULL,
+0xfffffc007fffffffULL,
+0xfffffc00ffffffffULL,
+0xfffffc01ffffffffULL,
+0xfffffc03ffffffffULL,
+0xfffffc07ffffffffULL,
+0xfffffc0fffffffffULL,
+0xfffffc1fffffffffULL,
+0xfffffc3fffffffffULL,
+0xfffffc7fffffffffULL,
+0xfffffcffffffffffULL,
+0xfffffdffffffffffULL
+},
+{
+0xfffff80000000000ULL,
+0xfffff80000000001ULL,
+0xfffff80000000003ULL,
+0xfffff80000000007ULL,
+0xfffff8000000000fULL,
+0xfffff8000000001fULL,
+0xfffff8000000003fULL,
+0xfffff8000000007fULL,
+0xfffff800000000ffULL,
+0xfffff800000001ffULL,
+0xfffff800000003ffULL,
+0xfffff800000007ffULL,
+0xfffff80000000fffULL,
+0xfffff80000001fffULL,
+0xfffff80000003fffULL,
+0xfffff80000007fffULL,
+0xfffff8000000ffffULL,
+0xfffff8000001ffffULL,
+0xfffff8000003ffffULL,
+0xfffff8000007ffffULL,
+0xfffff800000fffffULL,
+0xfffff800001fffffULL,
+0xfffff800003fffffULL,
+0xfffff800007fffffULL,
+0xfffff80000ffffffULL,
+0xfffff80001ffffffULL,
+0xfffff80003ffffffULL,
+0xfffff80007ffffffULL,
+0xfffff8000fffffffULL,
+0xfffff8001fffffffULL,
+0xfffff8003fffffffULL,
+0xfffff8007fffffffULL,
+0xfffff800ffffffffULL,
+0xfffff801ffffffffULL,
+0xfffff803ffffffffULL,
+0xfffff807ffffffffULL,
+0xfffff80fffffffffULL,
+0xfffff81fffffffffULL,
+0xfffff83fffffffffULL,
+0xfffff87fffffffffULL,
+0xfffff8ffffffffffULL,
+0xfffff9ffffffffffULL,
+0xfffffbffffffffffULL
+},
+{
+0xfffff00000000000ULL,
+0xfffff00000000001ULL,
+0xfffff00000000003ULL,
+0xfffff00000000007ULL,
+0xfffff0000000000fULL,
+0xfffff0000000001fULL,
+0xfffff0000000003fULL,
+0xfffff0000000007fULL,
+0xfffff000000000ffULL,
+0xfffff000000001ffULL,
+0xfffff000000003ffULL,
+0xfffff000000007ffULL,
+0xfffff00000000fffULL,
+0xfffff00000001fffULL,
+0xfffff00000003fffULL,
+0xfffff00000007fffULL,
+0xfffff0000000ffffULL,
+0xfffff0000001ffffULL,
+0xfffff0000003ffffULL,
+0xfffff0000007ffffULL,
+0xfffff000000fffffULL,
+0xfffff000001fffffULL,
+0xfffff000003fffffULL,
+0xfffff000007fffffULL,
+0xfffff00000ffffffULL,
+0xfffff00001ffffffULL,
+0xfffff00003ffffffULL,
+0xfffff00007ffffffULL,
+0xfffff0000fffffffULL,
+0xfffff0001fffffffULL,
+0xfffff0003fffffffULL,
+0xfffff0007fffffffULL,
+0xfffff000ffffffffULL,
+0xfffff001ffffffffULL,
+0xfffff003ffffffffULL,
+0xfffff007ffffffffULL,
+0xfffff00fffffffffULL,
+0xfffff01fffffffffULL,
+0xfffff03fffffffffULL,
+0xfffff07fffffffffULL,
+0xfffff0ffffffffffULL,
+0xfffff1ffffffffffULL,
+0xfffff3ffffffffffULL,
+0xfffff7ffffffffffULL
+},
+{
+0xffffe00000000000ULL,
+0xffffe00000000001ULL,
+0xffffe00000000003ULL,
+0xffffe00000000007ULL,
+0xffffe0000000000fULL,
+0xffffe0000000001fULL,
+0xffffe0000000003fULL,
+0xffffe0000000007fULL,
+0xffffe000000000ffULL,
+0xffffe000000001ffULL,
+0xffffe000000003ffULL,
+0xffffe000000007ffULL,
+0xffffe00000000fffULL,
+0xffffe00000001fffULL,
+0xffffe00000003fffULL,
+0xffffe00000007fffULL,
+0xffffe0000000ffffULL,
+0xffffe0000001ffffULL,
+0xffffe0000003ffffULL,
+0xffffe0000007ffffULL,
+0xffffe000000fffffULL,
+0xffffe000001fffffULL,
+0xffffe000003fffffULL,
+0xffffe000007fffffULL,
+0xffffe00000ffffffULL,
+0xffffe00001ffffffULL,
+0xffffe00003ffffffULL,
+0xffffe00007ffffffULL,
+0xffffe0000fffffffULL,
+0xffffe0001fffffffULL,
+0xffffe0003fffffffULL,
+0xffffe0007fffffffULL,
+0xffffe000ffffffffULL,
+0xffffe001ffffffffULL,
+0xffffe003ffffffffULL,
+0xffffe007ffffffffULL,
+0xffffe00fffffffffULL,
+0xffffe01fffffffffULL,
+0xffffe03fffffffffULL,
+0xffffe07fffffffffULL,
+0xffffe0ffffffffffULL,
+0xffffe1ffffffffffULL,
+0xffffe3ffffffffffULL,
+0xffffe7ffffffffffULL,
+0xffffefffffffffffULL
+},
+{
+0xffffc00000000000ULL,
+0xffffc00000000001ULL,
+0xffffc00000000003ULL,
+0xffffc00000000007ULL,
+0xffffc0000000000fULL,
+0xffffc0000000001fULL,
+0xffffc0000000003fULL,
+0xffffc0000000007fULL,
+0xffffc000000000ffULL,
+0xffffc000000001ffULL,
+0xffffc000000003ffULL,
+0xffffc000000007ffULL,
+0xffffc00000000fffULL,
+0xffffc00000001fffULL,
+0xffffc00000003fffULL,
+0xffffc00000007fffULL,
+0xffffc0000000ffffULL,
+0xffffc0000001ffffULL,
+0xffffc0000003ffffULL,
+0xffffc0000007ffffULL,
+0xffffc000000fffffULL,
+0xffffc000001fffffULL,
+0xffffc000003fffffULL,
+0xffffc000007fffffULL,
+0xffffc00000ffffffULL,
+0xffffc00001ffffffULL,
+0xffffc00003ffffffULL,
+0xffffc00007ffffffULL,
+0xffffc0000fffffffULL,
+0xffffc0001fffffffULL,
+0xffffc0003fffffffULL,
+0xffffc0007fffffffULL,
+0xffffc000ffffffffULL,
+0xffffc001ffffffffULL,
+0xffffc003ffffffffULL,
+0xffffc007ffffffffULL,
+0xffffc00fffffffffULL,
+0xffffc01fffffffffULL,
+0xffffc03fffffffffULL,
+0xffffc07fffffffffULL,
+0xffffc0ffffffffffULL,
+0xffffc1ffffffffffULL,
+0xffffc3ffffffffffULL,
+0xffffc7ffffffffffULL,
+0xffffcfffffffffffULL,
+0xffffdfffffffffffULL
+},
+{
+0xffff800000000000ULL,
+0xffff800000000001ULL,
+0xffff800000000003ULL,
+0xffff800000000007ULL,
+0xffff80000000000fULL,
+0xffff80000000001fULL,
+0xffff80000000003fULL,
+0xffff80000000007fULL,
+0xffff8000000000ffULL,
+0xffff8000000001ffULL,
+0xffff8000000003ffULL,
+0xffff8000000007ffULL,
+0xffff800000000fffULL,
+0xffff800000001fffULL,
+0xffff800000003fffULL,
+0xffff800000007fffULL,
+0xffff80000000ffffULL,
+0xffff80000001ffffULL,
+0xffff80000003ffffULL,
+0xffff80000007ffffULL,
+0xffff8000000fffffULL,
+0xffff8000001fffffULL,
+0xffff8000003fffffULL,
+0xffff8000007fffffULL,
+0xffff800000ffffffULL,
+0xffff800001ffffffULL,
+0xffff800003ffffffULL,
+0xffff800007ffffffULL,
+0xffff80000fffffffULL,
+0xffff80001fffffffULL,
+0xffff80003fffffffULL,
+0xffff80007fffffffULL,
+0xffff8000ffffffffULL,
+0xffff8001ffffffffULL,
+0xffff8003ffffffffULL,
+0xffff8007ffffffffULL,
+0xffff800fffffffffULL,
+0xffff801fffffffffULL,
+0xffff803fffffffffULL,
+0xffff807fffffffffULL,
+0xffff80ffffffffffULL,
+0xffff81ffffffffffULL,
+0xffff83ffffffffffULL,
+0xffff87ffffffffffULL,
+0xffff8fffffffffffULL,
+0xffff9fffffffffffULL,
+0xffffbfffffffffffULL
+},
+{
+0xffff000000000000ULL,
+0xffff000000000001ULL,
+0xffff000000000003ULL,
+0xffff000000000007ULL,
+0xffff00000000000fULL,
+0xffff00000000001fULL,
+0xffff00000000003fULL,
+0xffff00000000007fULL,
+0xffff0000000000ffULL,
+0xffff0000000001ffULL,
+0xffff0000000003ffULL,
+0xffff0000000007ffULL,
+0xffff000000000fffULL,
+0xffff000000001fffULL,
+0xffff000000003fffULL,
+0xffff000000007fffULL,
+0xffff00000000ffffULL,
+0xffff00000001ffffULL,
+0xffff00000003ffffULL,
+0xffff00000007ffffULL,
+0xffff0000000fffffULL,
+0xffff0000001fffffULL,
+0xffff0000003fffffULL,
+0xffff0000007fffffULL,
+0xffff000000ffffffULL,
+0xffff000001ffffffULL,
+0xffff000003ffffffULL,
+0xffff000007ffffffULL,
+0xffff00000fffffffULL,
+0xffff00001fffffffULL,
+0xffff00003fffffffULL,
+0xffff00007fffffffULL,
+0xffff0000ffffffffULL,
+0xffff0001ffffffffULL,
+0xffff0003ffffffffULL,
+0xffff0007ffffffffULL,
+0xffff000fffffffffULL,
+0xffff001fffffffffULL,
+0xffff003fffffffffULL,
+0xffff007fffffffffULL,
+0xffff00ffffffffffULL,
+0xffff01ffffffffffULL,
+0xffff03ffffffffffULL,
+0xffff07ffffffffffULL,
+0xffff0fffffffffffULL,
+0xffff1fffffffffffULL,
+0xffff3fffffffffffULL,
+0xffff7fffffffffffULL
+},
+{
+0xfffe000000000000ULL,
+0xfffe000000000001ULL,
+0xfffe000000000003ULL,
+0xfffe000000000007ULL,
+0xfffe00000000000fULL,
+0xfffe00000000001fULL,
+0xfffe00000000003fULL,
+0xfffe00000000007fULL,
+0xfffe0000000000ffULL,
+0xfffe0000000001ffULL,
+0xfffe0000000003ffULL,
+0xfffe0000000007ffULL,
+0xfffe000000000fffULL,
+0xfffe000000001fffULL,
+0xfffe000000003fffULL,
+0xfffe000000007fffULL,
+0xfffe00000000ffffULL,
+0xfffe00000001ffffULL,
+0xfffe00000003ffffULL,
+0xfffe00000007ffffULL,
+0xfffe0000000fffffULL,
+0xfffe0000001fffffULL,
+0xfffe0000003fffffULL,
+0xfffe0000007fffffULL,
+0xfffe000000ffffffULL,
+0xfffe000001ffffffULL,
+0xfffe000003ffffffULL,
+0xfffe000007ffffffULL,
+0xfffe00000fffffffULL,
+0xfffe00001fffffffULL,
+0xfffe00003fffffffULL,
+0xfffe00007fffffffULL,
+0xfffe0000ffffffffULL,
+0xfffe0001ffffffffULL,
+0xfffe0003ffffffffULL,
+0xfffe0007ffffffffULL,
+0xfffe000fffffffffULL,
+0xfffe001fffffffffULL,
+0xfffe003fffffffffULL,
+0xfffe007fffffffffULL,
+0xfffe00ffffffffffULL,
+0xfffe01ffffffffffULL,
+0xfffe03ffffffffffULL,
+0xfffe07ffffffffffULL,
+0xfffe0fffffffffffULL,
+0xfffe1fffffffffffULL,
+0xfffe3fffffffffffULL,
+0xfffe7fffffffffffULL,
+0xfffeffffffffffffULL
+},
+{
+0xfffc000000000000ULL,
+0xfffc000000000001ULL,
+0xfffc000000000003ULL,
+0xfffc000000000007ULL,
+0xfffc00000000000fULL,
+0xfffc00000000001fULL,
+0xfffc00000000003fULL,
+0xfffc00000000007fULL,
+0xfffc0000000000ffULL,
+0xfffc0000000001ffULL,
+0xfffc0000000003ffULL,
+0xfffc0000000007ffULL,
+0xfffc000000000fffULL,
+0xfffc000000001fffULL,
+0xfffc000000003fffULL,
+0xfffc000000007fffULL,
+0xfffc00000000ffffULL,
+0xfffc00000001ffffULL,
+0xfffc00000003ffffULL,
+0xfffc00000007ffffULL,
+0xfffc0000000fffffULL,
+0xfffc0000001fffffULL,
+0xfffc0000003fffffULL,
+0xfffc0000007fffffULL,
+0xfffc000000ffffffULL,
+0xfffc000001ffffffULL,
+0xfffc000003ffffffULL,
+0xfffc000007ffffffULL,
+0xfffc00000fffffffULL,
+0xfffc00001fffffffULL,
+0xfffc00003fffffffULL,
+0xfffc00007fffffffULL,
+0xfffc0000ffffffffULL,
+0xfffc0001ffffffffULL,
+0xfffc0003ffffffffULL,
+0xfffc0007ffffffffULL,
+0xfffc000fffffffffULL,
+0xfffc001fffffffffULL,
+0xfffc003fffffffffULL,
+0xfffc007fffffffffULL,
+0xfffc00ffffffffffULL,
+0xfffc01ffffffffffULL,
+0xfffc03ffffffffffULL,
+0xfffc07ffffffffffULL,
+0xfffc0fffffffffffULL,
+0xfffc1fffffffffffULL,
+0xfffc3fffffffffffULL,
+0xfffc7fffffffffffULL,
+0xfffcffffffffffffULL,
+0xfffdffffffffffffULL
+},
+{
+0xfff8000000000000ULL,
+0xfff8000000000001ULL,
+0xfff8000000000003ULL,
+0xfff8000000000007ULL,
+0xfff800000000000fULL,
+0xfff800000000001fULL,
+0xfff800000000003fULL,
+0xfff800000000007fULL,
+0xfff80000000000ffULL,
+0xfff80000000001ffULL,
+0xfff80000000003ffULL,
+0xfff80000000007ffULL,
+0xfff8000000000fffULL,
+0xfff8000000001fffULL,
+0xfff8000000003fffULL,
+0xfff8000000007fffULL,
+0xfff800000000ffffULL,
+0xfff800000001ffffULL,
+0xfff800000003ffffULL,
+0xfff800000007ffffULL,
+0xfff80000000fffffULL,
+0xfff80000001fffffULL,
+0xfff80000003fffffULL,
+0xfff80000007fffffULL,
+0xfff8000000ffffffULL,
+0xfff8000001ffffffULL,
+0xfff8000003ffffffULL,
+0xfff8000007ffffffULL,
+0xfff800000fffffffULL,
+0xfff800001fffffffULL,
+0xfff800003fffffffULL,
+0xfff800007fffffffULL,
+0xfff80000ffffffffULL,
+0xfff80001ffffffffULL,
+0xfff80003ffffffffULL,
+0xfff80007ffffffffULL,
+0xfff8000fffffffffULL,
+0xfff8001fffffffffULL,
+0xfff8003fffffffffULL,
+0xfff8007fffffffffULL,
+0xfff800ffffffffffULL,
+0xfff801ffffffffffULL,
+0xfff803ffffffffffULL,
+0xfff807ffffffffffULL,
+0xfff80fffffffffffULL,
+0xfff81fffffffffffULL,
+0xfff83fffffffffffULL,
+0xfff87fffffffffffULL,
+0xfff8ffffffffffffULL,
+0xfff9ffffffffffffULL,
+0xfffbffffffffffffULL
+},
+{
+0xfff0000000000000ULL,
+0xfff0000000000001ULL,
+0xfff0000000000003ULL,
+0xfff0000000000007ULL,
+0xfff000000000000fULL,
+0xfff000000000001fULL,
+0xfff000000000003fULL,
+0xfff000000000007fULL,
+0xfff00000000000ffULL,
+0xfff00000000001ffULL,
+0xfff00000000003ffULL,
+0xfff00000000007ffULL,
+0xfff0000000000fffULL,
+0xfff0000000001fffULL,
+0xfff0000000003fffULL,
+0xfff0000000007fffULL,
+0xfff000000000ffffULL,
+0xfff000000001ffffULL,
+0xfff000000003ffffULL,
+0xfff000000007ffffULL,
+0xfff00000000fffffULL,
+0xfff00000001fffffULL,
+0xfff00000003fffffULL,
+0xfff00000007fffffULL,
+0xfff0000000ffffffULL,
+0xfff0000001ffffffULL,
+0xfff0000003ffffffULL,
+0xfff0000007ffffffULL,
+0xfff000000fffffffULL,
+0xfff000001fffffffULL,
+0xfff000003fffffffULL,
+0xfff000007fffffffULL,
+0xfff00000ffffffffULL,
+0xfff00001ffffffffULL,
+0xfff00003ffffffffULL,
+0xfff00007ffffffffULL,
+0xfff0000fffffffffULL,
+0xfff0001fffffffffULL,
+0xfff0003fffffffffULL,
+0xfff0007fffffffffULL,
+0xfff000ffffffffffULL,
+0xfff001ffffffffffULL,
+0xfff003ffffffffffULL,
+0xfff007ffffffffffULL,
+0xfff00fffffffffffULL,
+0xfff01fffffffffffULL,
+0xfff03fffffffffffULL,
+0xfff07fffffffffffULL,
+0xfff0ffffffffffffULL,
+0xfff1ffffffffffffULL,
+0xfff3ffffffffffffULL,
+0xfff7ffffffffffffULL
+},
+{
+0xffe0000000000000ULL,
+0xffe0000000000001ULL,
+0xffe0000000000003ULL,
+0xffe0000000000007ULL,
+0xffe000000000000fULL,
+0xffe000000000001fULL,
+0xffe000000000003fULL,
+0xffe000000000007fULL,
+0xffe00000000000ffULL,
+0xffe00000000001ffULL,
+0xffe00000000003ffULL,
+0xffe00000000007ffULL,
+0xffe0000000000fffULL,
+0xffe0000000001fffULL,
+0xffe0000000003fffULL,
+0xffe0000000007fffULL,
+0xffe000000000ffffULL,
+0xffe000000001ffffULL,
+0xffe000000003ffffULL,
+0xffe000000007ffffULL,
+0xffe00000000fffffULL,
+0xffe00000001fffffULL,
+0xffe00000003fffffULL,
+0xffe00000007fffffULL,
+0xffe0000000ffffffULL,
+0xffe0000001ffffffULL,
+0xffe0000003ffffffULL,
+0xffe0000007ffffffULL,
+0xffe000000fffffffULL,
+0xffe000001fffffffULL,
+0xffe000003fffffffULL,
+0xffe000007fffffffULL,
+0xffe00000ffffffffULL,
+0xffe00001ffffffffULL,
+0xffe00003ffffffffULL,
+0xffe00007ffffffffULL,
+0xffe0000fffffffffULL,
+0xffe0001fffffffffULL,
+0xffe0003fffffffffULL,
+0xffe0007fffffffffULL,
+0xffe000ffffffffffULL,
+0xffe001ffffffffffULL,
+0xffe003ffffffffffULL,
+0xffe007ffffffffffULL,
+0xffe00fffffffffffULL,
+0xffe01fffffffffffULL,
+0xffe03fffffffffffULL,
+0xffe07fffffffffffULL,
+0xffe0ffffffffffffULL,
+0xffe1ffffffffffffULL,
+0xffe3ffffffffffffULL,
+0xffe7ffffffffffffULL,
+0xffefffffffffffffULL
+},
+{
+0xffc0000000000000ULL,
+0xffc0000000000001ULL,
+0xffc0000000000003ULL,
+0xffc0000000000007ULL,
+0xffc000000000000fULL,
+0xffc000000000001fULL,
+0xffc000000000003fULL,
+0xffc000000000007fULL,
+0xffc00000000000ffULL,
+0xffc00000000001ffULL,
+0xffc00000000003ffULL,
+0xffc00000000007ffULL,
+0xffc0000000000fffULL,
+0xffc0000000001fffULL,
+0xffc0000000003fffULL,
+0xffc0000000007fffULL,
+0xffc000000000ffffULL,
+0xffc000000001ffffULL,
+0xffc000000003ffffULL,
+0xffc000000007ffffULL,
+0xffc00000000fffffULL,
+0xffc00000001fffffULL,
+0xffc00000003fffffULL,
+0xffc00000007fffffULL,
+0xffc0000000ffffffULL,
+0xffc0000001ffffffULL,
+0xffc0000003ffffffULL,
+0xffc0000007ffffffULL,
+0xffc000000fffffffULL,
+0xffc000001fffffffULL,
+0xffc000003fffffffULL,
+0xffc000007fffffffULL,
+0xffc00000ffffffffULL,
+0xffc00001ffffffffULL,
+0xffc00003ffffffffULL,
+0xffc00007ffffffffULL,
+0xffc0000fffffffffULL,
+0xffc0001fffffffffULL,
+0xffc0003fffffffffULL,
+0xffc0007fffffffffULL,
+0xffc000ffffffffffULL,
+0xffc001ffffffffffULL,
+0xffc003ffffffffffULL,
+0xffc007ffffffffffULL,
+0xffc00fffffffffffULL,
+0xffc01fffffffffffULL,
+0xffc03fffffffffffULL,
+0xffc07fffffffffffULL,
+0xffc0ffffffffffffULL,
+0xffc1ffffffffffffULL,
+0xffc3ffffffffffffULL,
+0xffc7ffffffffffffULL,
+0xffcfffffffffffffULL,
+0xffdfffffffffffffULL
+},
+{
+0xff80000000000000ULL,
+0xff80000000000001ULL,
+0xff80000000000003ULL,
+0xff80000000000007ULL,
+0xff8000000000000fULL,
+0xff8000000000001fULL,
+0xff8000000000003fULL,
+0xff8000000000007fULL,
+0xff800000000000ffULL,
+0xff800000000001ffULL,
+0xff800000000003ffULL,
+0xff800000000007ffULL,
+0xff80000000000fffULL,
+0xff80000000001fffULL,
+0xff80000000003fffULL,
+0xff80000000007fffULL,
+0xff8000000000ffffULL,
+0xff8000000001ffffULL,
+0xff8000000003ffffULL,
+0xff8000000007ffffULL,
+0xff800000000fffffULL,
+0xff800000001fffffULL,
+0xff800000003fffffULL,
+0xff800000007fffffULL,
+0xff80000000ffffffULL,
+0xff80000001ffffffULL,
+0xff80000003ffffffULL,
+0xff80000007ffffffULL,
+0xff8000000fffffffULL,
+0xff8000001fffffffULL,
+0xff8000003fffffffULL,
+0xff8000007fffffffULL,
+0xff800000ffffffffULL,
+0xff800001ffffffffULL,
+0xff800003ffffffffULL,
+0xff800007ffffffffULL,
+0xff80000fffffffffULL,
+0xff80001fffffffffULL,
+0xff80003fffffffffULL,
+0xff80007fffffffffULL,
+0xff8000ffffffffffULL,
+0xff8001ffffffffffULL,
+0xff8003ffffffffffULL,
+0xff8007ffffffffffULL,
+0xff800fffffffffffULL,
+0xff801fffffffffffULL,
+0xff803fffffffffffULL,
+0xff807fffffffffffULL,
+0xff80ffffffffffffULL,
+0xff81ffffffffffffULL,
+0xff83ffffffffffffULL,
+0xff87ffffffffffffULL,
+0xff8fffffffffffffULL,
+0xff9fffffffffffffULL,
+0xffbfffffffffffffULL
+},
+{
+0xff00000000000000ULL,
+0xff00000000000001ULL,
+0xff00000000000003ULL,
+0xff00000000000007ULL,
+0xff0000000000000fULL,
+0xff0000000000001fULL,
+0xff0000000000003fULL,
+0xff0000000000007fULL,
+0xff000000000000ffULL,
+0xff000000000001ffULL,
+0xff000000000003ffULL,
+0xff000000000007ffULL,
+0xff00000000000fffULL,
+0xff00000000001fffULL,
+0xff00000000003fffULL,
+0xff00000000007fffULL,
+0xff0000000000ffffULL,
+0xff0000000001ffffULL,
+0xff0000000003ffffULL,
+0xff0000000007ffffULL,
+0xff000000000fffffULL,
+0xff000000001fffffULL,
+0xff000000003fffffULL,
+0xff000000007fffffULL,
+0xff00000000ffffffULL,
+0xff00000001ffffffULL,
+0xff00000003ffffffULL,
+0xff00000007ffffffULL,
+0xff0000000fffffffULL,
+0xff0000001fffffffULL,
+0xff0000003fffffffULL,
+0xff0000007fffffffULL,
+0xff000000ffffffffULL,
+0xff000001ffffffffULL,
+0xff000003ffffffffULL,
+0xff000007ffffffffULL,
+0xff00000fffffffffULL,
+0xff00001fffffffffULL,
+0xff00003fffffffffULL,
+0xff00007fffffffffULL,
+0xff0000ffffffffffULL,
+0xff0001ffffffffffULL,
+0xff0003ffffffffffULL,
+0xff0007ffffffffffULL,
+0xff000fffffffffffULL,
+0xff001fffffffffffULL,
+0xff003fffffffffffULL,
+0xff007fffffffffffULL,
+0xff00ffffffffffffULL,
+0xff01ffffffffffffULL,
+0xff03ffffffffffffULL,
+0xff07ffffffffffffULL,
+0xff0fffffffffffffULL,
+0xff1fffffffffffffULL,
+0xff3fffffffffffffULL,
+0xff7fffffffffffffULL
+},
+{
+0xfe00000000000000ULL,
+0xfe00000000000001ULL,
+0xfe00000000000003ULL,
+0xfe00000000000007ULL,
+0xfe0000000000000fULL,
+0xfe0000000000001fULL,
+0xfe0000000000003fULL,
+0xfe0000000000007fULL,
+0xfe000000000000ffULL,
+0xfe000000000001ffULL,
+0xfe000000000003ffULL,
+0xfe000000000007ffULL,
+0xfe00000000000fffULL,
+0xfe00000000001fffULL,
+0xfe00000000003fffULL,
+0xfe00000000007fffULL,
+0xfe0000000000ffffULL,
+0xfe0000000001ffffULL,
+0xfe0000000003ffffULL,
+0xfe0000000007ffffULL,
+0xfe000000000fffffULL,
+0xfe000000001fffffULL,
+0xfe000000003fffffULL,
+0xfe000000007fffffULL,
+0xfe00000000ffffffULL,
+0xfe00000001ffffffULL,
+0xfe00000003ffffffULL,
+0xfe00000007ffffffULL,
+0xfe0000000fffffffULL,
+0xfe0000001fffffffULL,
+0xfe0000003fffffffULL,
+0xfe0000007fffffffULL,
+0xfe000000ffffffffULL,
+0xfe000001ffffffffULL,
+0xfe000003ffffffffULL,
+0xfe000007ffffffffULL,
+0xfe00000fffffffffULL,
+0xfe00001fffffffffULL,
+0xfe00003fffffffffULL,
+0xfe00007fffffffffULL,
+0xfe0000ffffffffffULL,
+0xfe0001ffffffffffULL,
+0xfe0003ffffffffffULL,
+0xfe0007ffffffffffULL,
+0xfe000fffffffffffULL,
+0xfe001fffffffffffULL,
+0xfe003fffffffffffULL,
+0xfe007fffffffffffULL,
+0xfe00ffffffffffffULL,
+0xfe01ffffffffffffULL,
+0xfe03ffffffffffffULL,
+0xfe07ffffffffffffULL,
+0xfe0fffffffffffffULL,
+0xfe1fffffffffffffULL,
+0xfe3fffffffffffffULL,
+0xfe7fffffffffffffULL,
+0xfeffffffffffffffULL
+},
+{
+0xfc00000000000000ULL,
+0xfc00000000000001ULL,
+0xfc00000000000003ULL,
+0xfc00000000000007ULL,
+0xfc0000000000000fULL,
+0xfc0000000000001fULL,
+0xfc0000000000003fULL,
+0xfc0000000000007fULL,
+0xfc000000000000ffULL,
+0xfc000000000001ffULL,
+0xfc000000000003ffULL,
+0xfc000000000007ffULL,
+0xfc00000000000fffULL,
+0xfc00000000001fffULL,
+0xfc00000000003fffULL,
+0xfc00000000007fffULL,
+0xfc0000000000ffffULL,
+0xfc0000000001ffffULL,
+0xfc0000000003ffffULL,
+0xfc0000000007ffffULL,
+0xfc000000000fffffULL,
+0xfc000000001fffffULL,
+0xfc000000003fffffULL,
+0xfc000000007fffffULL,
+0xfc00000000ffffffULL,
+0xfc00000001ffffffULL,
+0xfc00000003ffffffULL,
+0xfc00000007ffffffULL,
+0xfc0000000fffffffULL,
+0xfc0000001fffffffULL,
+0xfc0000003fffffffULL,
+0xfc0000007fffffffULL,
+0xfc000000ffffffffULL,
+0xfc000001ffffffffULL,
+0xfc000003ffffffffULL,
+0xfc000007ffffffffULL,
+0xfc00000fffffffffULL,
+0xfc00001fffffffffULL,
+0xfc00003fffffffffULL,
+0xfc00007fffffffffULL,
+0xfc0000ffffffffffULL,
+0xfc0001ffffffffffULL,
+0xfc0003ffffffffffULL,
+0xfc0007ffffffffffULL,
+0xfc000fffffffffffULL,
+0xfc001fffffffffffULL,
+0xfc003fffffffffffULL,
+0xfc007fffffffffffULL,
+0xfc00ffffffffffffULL,
+0xfc01ffffffffffffULL,
+0xfc03ffffffffffffULL,
+0xfc07ffffffffffffULL,
+0xfc0fffffffffffffULL,
+0xfc1fffffffffffffULL,
+0xfc3fffffffffffffULL,
+0xfc7fffffffffffffULL,
+0xfcffffffffffffffULL,
+0xfdffffffffffffffULL
+},
+{
+0xf800000000000000ULL,
+0xf800000000000001ULL,
+0xf800000000000003ULL,
+0xf800000000000007ULL,
+0xf80000000000000fULL,
+0xf80000000000001fULL,
+0xf80000000000003fULL,
+0xf80000000000007fULL,
+0xf8000000000000ffULL,
+0xf8000000000001ffULL,
+0xf8000000000003ffULL,
+0xf8000000000007ffULL,
+0xf800000000000fffULL,
+0xf800000000001fffULL,
+0xf800000000003fffULL,
+0xf800000000007fffULL,
+0xf80000000000ffffULL,
+0xf80000000001ffffULL,
+0xf80000000003ffffULL,
+0xf80000000007ffffULL,
+0xf8000000000fffffULL,
+0xf8000000001fffffULL,
+0xf8000000003fffffULL,
+0xf8000000007fffffULL,
+0xf800000000ffffffULL,
+0xf800000001ffffffULL,
+0xf800000003ffffffULL,
+0xf800000007ffffffULL,
+0xf80000000fffffffULL,
+0xf80000001fffffffULL,
+0xf80000003fffffffULL,
+0xf80000007fffffffULL,
+0xf8000000ffffffffULL,
+0xf8000001ffffffffULL,
+0xf8000003ffffffffULL,
+0xf8000007ffffffffULL,
+0xf800000fffffffffULL,
+0xf800001fffffffffULL,
+0xf800003fffffffffULL,
+0xf800007fffffffffULL,
+0xf80000ffffffffffULL,
+0xf80001ffffffffffULL,
+0xf80003ffffffffffULL,
+0xf80007ffffffffffULL,
+0xf8000fffffffffffULL,
+0xf8001fffffffffffULL,
+0xf8003fffffffffffULL,
+0xf8007fffffffffffULL,
+0xf800ffffffffffffULL,
+0xf801ffffffffffffULL,
+0xf803ffffffffffffULL,
+0xf807ffffffffffffULL,
+0xf80fffffffffffffULL,
+0xf81fffffffffffffULL,
+0xf83fffffffffffffULL,
+0xf87fffffffffffffULL,
+0xf8ffffffffffffffULL,
+0xf9ffffffffffffffULL,
+0xfbffffffffffffffULL
+},
+{
+0xf000000000000000ULL,
+0xf000000000000001ULL,
+0xf000000000000003ULL,
+0xf000000000000007ULL,
+0xf00000000000000fULL,
+0xf00000000000001fULL,
+0xf00000000000003fULL,
+0xf00000000000007fULL,
+0xf0000000000000ffULL,
+0xf0000000000001ffULL,
+0xf0000000000003ffULL,
+0xf0000000000007ffULL,
+0xf000000000000fffULL,
+0xf000000000001fffULL,
+0xf000000000003fffULL,
+0xf000000000007fffULL,
+0xf00000000000ffffULL,
+0xf00000000001ffffULL,
+0xf00000000003ffffULL,
+0xf00000000007ffffULL,
+0xf0000000000fffffULL,
+0xf0000000001fffffULL,
+0xf0000000003fffffULL,
+0xf0000000007fffffULL,
+0xf000000000ffffffULL,
+0xf000000001ffffffULL,
+0xf000000003ffffffULL,
+0xf000000007ffffffULL,
+0xf00000000fffffffULL,
+0xf00000001fffffffULL,
+0xf00000003fffffffULL,
+0xf00000007fffffffULL,
+0xf0000000ffffffffULL,
+0xf0000001ffffffffULL,
+0xf0000003ffffffffULL,
+0xf0000007ffffffffULL,
+0xf000000fffffffffULL,
+0xf000001fffffffffULL,
+0xf000003fffffffffULL,
+0xf000007fffffffffULL,
+0xf00000ffffffffffULL,
+0xf00001ffffffffffULL,
+0xf00003ffffffffffULL,
+0xf00007ffffffffffULL,
+0xf0000fffffffffffULL,
+0xf0001fffffffffffULL,
+0xf0003fffffffffffULL,
+0xf0007fffffffffffULL,
+0xf000ffffffffffffULL,
+0xf001ffffffffffffULL,
+0xf003ffffffffffffULL,
+0xf007ffffffffffffULL,
+0xf00fffffffffffffULL,
+0xf01fffffffffffffULL,
+0xf03fffffffffffffULL,
+0xf07fffffffffffffULL,
+0xf0ffffffffffffffULL,
+0xf1ffffffffffffffULL,
+0xf3ffffffffffffffULL,
+0xf7ffffffffffffffULL
+},
+{
+0xe000000000000000ULL,
+0xe000000000000001ULL,
+0xe000000000000003ULL,
+0xe000000000000007ULL,
+0xe00000000000000fULL,
+0xe00000000000001fULL,
+0xe00000000000003fULL,
+0xe00000000000007fULL,
+0xe0000000000000ffULL,
+0xe0000000000001ffULL,
+0xe0000000000003ffULL,
+0xe0000000000007ffULL,
+0xe000000000000fffULL,
+0xe000000000001fffULL,
+0xe000000000003fffULL,
+0xe000000000007fffULL,
+0xe00000000000ffffULL,
+0xe00000000001ffffULL,
+0xe00000000003ffffULL,
+0xe00000000007ffffULL,
+0xe0000000000fffffULL,
+0xe0000000001fffffULL,
+0xe0000000003fffffULL,
+0xe0000000007fffffULL,
+0xe000000000ffffffULL,
+0xe000000001ffffffULL,
+0xe000000003ffffffULL,
+0xe000000007ffffffULL,
+0xe00000000fffffffULL,
+0xe00000001fffffffULL,
+0xe00000003fffffffULL,
+0xe00000007fffffffULL,
+0xe0000000ffffffffULL,
+0xe0000001ffffffffULL,
+0xe0000003ffffffffULL,
+0xe0000007ffffffffULL,
+0xe000000fffffffffULL,
+0xe000001fffffffffULL,
+0xe000003fffffffffULL,
+0xe000007fffffffffULL,
+0xe00000ffffffffffULL,
+0xe00001ffffffffffULL,
+0xe00003ffffffffffULL,
+0xe00007ffffffffffULL,
+0xe0000fffffffffffULL,
+0xe0001fffffffffffULL,
+0xe0003fffffffffffULL,
+0xe0007fffffffffffULL,
+0xe000ffffffffffffULL,
+0xe001ffffffffffffULL,
+0xe003ffffffffffffULL,
+0xe007ffffffffffffULL,
+0xe00fffffffffffffULL,
+0xe01fffffffffffffULL,
+0xe03fffffffffffffULL,
+0xe07fffffffffffffULL,
+0xe0ffffffffffffffULL,
+0xe1ffffffffffffffULL,
+0xe3ffffffffffffffULL,
+0xe7ffffffffffffffULL,
+0xefffffffffffffffULL
+},
+{
+0xc000000000000000ULL,
+0xc000000000000001ULL,
+0xc000000000000003ULL,
+0xc000000000000007ULL,
+0xc00000000000000fULL,
+0xc00000000000001fULL,
+0xc00000000000003fULL,
+0xc00000000000007fULL,
+0xc0000000000000ffULL,
+0xc0000000000001ffULL,
+0xc0000000000003ffULL,
+0xc0000000000007ffULL,
+0xc000000000000fffULL,
+0xc000000000001fffULL,
+0xc000000000003fffULL,
+0xc000000000007fffULL,
+0xc00000000000ffffULL,
+0xc00000000001ffffULL,
+0xc00000000003ffffULL,
+0xc00000000007ffffULL,
+0xc0000000000fffffULL,
+0xc0000000001fffffULL,
+0xc0000000003fffffULL,
+0xc0000000007fffffULL,
+0xc000000000ffffffULL,
+0xc000000001ffffffULL,
+0xc000000003ffffffULL,
+0xc000000007ffffffULL,
+0xc00000000fffffffULL,
+0xc00000001fffffffULL,
+0xc00000003fffffffULL,
+0xc00000007fffffffULL,
+0xc0000000ffffffffULL,
+0xc0000001ffffffffULL,
+0xc0000003ffffffffULL,
+0xc0000007ffffffffULL,
+0xc000000fffffffffULL,
+0xc000001fffffffffULL,
+0xc000003fffffffffULL,
+0xc000007fffffffffULL,
+0xc00000ffffffffffULL,
+0xc00001ffffffffffULL,
+0xc00003ffffffffffULL,
+0xc00007ffffffffffULL,
+0xc0000fffffffffffULL,
+0xc0001fffffffffffULL,
+0xc0003fffffffffffULL,
+0xc0007fffffffffffULL,
+0xc000ffffffffffffULL,
+0xc001ffffffffffffULL,
+0xc003ffffffffffffULL,
+0xc007ffffffffffffULL,
+0xc00fffffffffffffULL,
+0xc01fffffffffffffULL,
+0xc03fffffffffffffULL,
+0xc07fffffffffffffULL,
+0xc0ffffffffffffffULL,
+0xc1ffffffffffffffULL,
+0xc3ffffffffffffffULL,
+0xc7ffffffffffffffULL,
+0xcfffffffffffffffULL,
+0xdfffffffffffffffULL
+},
+{
+0x8000000000000000ULL,
+0x8000000000000001ULL,
+0x8000000000000003ULL,
+0x8000000000000007ULL,
+0x800000000000000fULL,
+0x800000000000001fULL,
+0x800000000000003fULL,
+0x800000000000007fULL,
+0x80000000000000ffULL,
+0x80000000000001ffULL,
+0x80000000000003ffULL,
+0x80000000000007ffULL,
+0x8000000000000fffULL,
+0x8000000000001fffULL,
+0x8000000000003fffULL,
+0x8000000000007fffULL,
+0x800000000000ffffULL,
+0x800000000001ffffULL,
+0x800000000003ffffULL,
+0x800000000007ffffULL,
+0x80000000000fffffULL,
+0x80000000001fffffULL,
+0x80000000003fffffULL,
+0x80000000007fffffULL,
+0x8000000000ffffffULL,
+0x8000000001ffffffULL,
+0x8000000003ffffffULL,
+0x8000000007ffffffULL,
+0x800000000fffffffULL,
+0x800000001fffffffULL,
+0x800000003fffffffULL,
+0x800000007fffffffULL,
+0x80000000ffffffffULL,
+0x80000001ffffffffULL,
+0x80000003ffffffffULL,
+0x80000007ffffffffULL,
+0x8000000fffffffffULL,
+0x8000001fffffffffULL,
+0x8000003fffffffffULL,
+0x8000007fffffffffULL,
+0x800000ffffffffffULL,
+0x800001ffffffffffULL,
+0x800003ffffffffffULL,
+0x800007ffffffffffULL,
+0x80000fffffffffffULL,
+0x80001fffffffffffULL,
+0x80003fffffffffffULL,
+0x80007fffffffffffULL,
+0x8000ffffffffffffULL,
+0x8001ffffffffffffULL,
+0x8003ffffffffffffULL,
+0x8007ffffffffffffULL,
+0x800fffffffffffffULL,
+0x801fffffffffffffULL,
+0x803fffffffffffffULL,
+0x807fffffffffffffULL,
+0x80ffffffffffffffULL,
+0x81ffffffffffffffULL,
+0x83ffffffffffffffULL,
+0x87ffffffffffffffULL,
+0x8fffffffffffffffULL,
+0x9fffffffffffffffULL,
+0xbfffffffffffffffULL
+},
+{
+0x0ULL,
+0x1ULL,
+0x3ULL,
+0x7ULL,
+0xfULL,
+0x1fULL,
+0x3fULL,
+0x7fULL,
+0xffULL,
+0x1ffULL,
+0x3ffULL,
+0x7ffULL,
+0xfffULL,
+0x1fffULL,
+0x3fffULL,
+0x7fffULL,
+0xffffULL,
+0x1ffffULL,
+0x3ffffULL,
+0x7ffffULL,
+0xfffffULL,
+0x1fffffULL,
+0x3fffffULL,
+0x7fffffULL,
+0xffffffULL,
+0x1ffffffULL,
+0x3ffffffULL,
+0x7ffffffULL,
+0xfffffffULL,
+0x1fffffffULL,
+0x3fffffffULL,
+0x7fffffffULL,
+0xffffffffULL,
+0x1ffffffffULL,
+0x3ffffffffULL,
+0x7ffffffffULL,
+0xfffffffffULL,
+0x1fffffffffULL,
+0x3fffffffffULL,
+0x7fffffffffULL,
+0xffffffffffULL,
+0x1ffffffffffULL,
+0x3ffffffffffULL,
+0x7ffffffffffULL,
+0xfffffffffffULL,
+0x1fffffffffffULL,
+0x3fffffffffffULL,
+0x7fffffffffffULL,
+0xffffffffffffULL,
+0x1ffffffffffffULL,
+0x3ffffffffffffULL,
+0x7ffffffffffffULL,
+0xfffffffffffffULL,
+0x1fffffffffffffULL,
+0x3fffffffffffffULL,
+0x7fffffffffffffULL,
+0xffffffffffffffULL,
+0x1ffffffffffffffULL,
+0x3ffffffffffffffULL,
+0x7ffffffffffffffULL,
+0xfffffffffffffffULL,
+0x1fffffffffffffffULL,
+0x3fffffffffffffffULL,
+0x7fffffffffffffffULL
+}
+};
+
+#else //end of #ifndef WIN32
+
+const uint_type mask_int[SC_INTWIDTH][SC_INTWIDTH] =
+{
+{
+0xfffffffffffffffei64
+},
+{
+0xfffffffffffffffci64,
+0xfffffffffffffffdi64
+},
+{
+0xfffffffffffffff8i64,
+0xfffffffffffffff9i64,
+0xfffffffffffffffbi64
+},
+{
+0xfffffffffffffff0i64,
+0xfffffffffffffff1i64,
+0xfffffffffffffff3i64,
+0xfffffffffffffff7i64
+},
+{
+0xffffffffffffffe0i64,
+0xffffffffffffffe1i64,
+0xffffffffffffffe3i64,
+0xffffffffffffffe7i64,
+0xffffffffffffffefi64
+},
+{
+0xffffffffffffffc0i64,
+0xffffffffffffffc1i64,
+0xffffffffffffffc3i64,
+0xffffffffffffffc7i64,
+0xffffffffffffffcfi64,
+0xffffffffffffffdfi64
+},
+{
+0xffffffffffffff80i64,
+0xffffffffffffff81i64,
+0xffffffffffffff83i64,
+0xffffffffffffff87i64,
+0xffffffffffffff8fi64,
+0xffffffffffffff9fi64,
+0xffffffffffffffbfi64
+},
+{
+0xffffffffffffff00i64,
+0xffffffffffffff01i64,
+0xffffffffffffff03i64,
+0xffffffffffffff07i64,
+0xffffffffffffff0fi64,
+0xffffffffffffff1fi64,
+0xffffffffffffff3fi64,
+0xffffffffffffff7fi64
+},
+{
+0xfffffffffffffe00i64,
+0xfffffffffffffe01i64,
+0xfffffffffffffe03i64,
+0xfffffffffffffe07i64,
+0xfffffffffffffe0fi64,
+0xfffffffffffffe1fi64,
+0xfffffffffffffe3fi64,
+0xfffffffffffffe7fi64,
+0xfffffffffffffeffi64
+},
+{
+0xfffffffffffffc00i64,
+0xfffffffffffffc01i64,
+0xfffffffffffffc03i64,
+0xfffffffffffffc07i64,
+0xfffffffffffffc0fi64,
+0xfffffffffffffc1fi64,
+0xfffffffffffffc3fi64,
+0xfffffffffffffc7fi64,
+0xfffffffffffffcffi64,
+0xfffffffffffffdffi64
+},
+{
+0xfffffffffffff800i64,
+0xfffffffffffff801i64,
+0xfffffffffffff803i64,
+0xfffffffffffff807i64,
+0xfffffffffffff80fi64,
+0xfffffffffffff81fi64,
+0xfffffffffffff83fi64,
+0xfffffffffffff87fi64,
+0xfffffffffffff8ffi64,
+0xfffffffffffff9ffi64,
+0xfffffffffffffbffi64
+},
+{
+0xfffffffffffff000i64,
+0xfffffffffffff001i64,
+0xfffffffffffff003i64,
+0xfffffffffffff007i64,
+0xfffffffffffff00fi64,
+0xfffffffffffff01fi64,
+0xfffffffffffff03fi64,
+0xfffffffffffff07fi64,
+0xfffffffffffff0ffi64,
+0xfffffffffffff1ffi64,
+0xfffffffffffff3ffi64,
+0xfffffffffffff7ffi64
+},
+{
+0xffffffffffffe000i64,
+0xffffffffffffe001i64,
+0xffffffffffffe003i64,
+0xffffffffffffe007i64,
+0xffffffffffffe00fi64,
+0xffffffffffffe01fi64,
+0xffffffffffffe03fi64,
+0xffffffffffffe07fi64,
+0xffffffffffffe0ffi64,
+0xffffffffffffe1ffi64,
+0xffffffffffffe3ffi64,
+0xffffffffffffe7ffi64,
+0xffffffffffffefffi64
+},
+{
+0xffffffffffffc000i64,
+0xffffffffffffc001i64,
+0xffffffffffffc003i64,
+0xffffffffffffc007i64,
+0xffffffffffffc00fi64,
+0xffffffffffffc01fi64,
+0xffffffffffffc03fi64,
+0xffffffffffffc07fi64,
+0xffffffffffffc0ffi64,
+0xffffffffffffc1ffi64,
+0xffffffffffffc3ffi64,
+0xffffffffffffc7ffi64,
+0xffffffffffffcfffi64,
+0xffffffffffffdfffi64
+},
+{
+0xffffffffffff8000i64,
+0xffffffffffff8001i64,
+0xffffffffffff8003i64,
+0xffffffffffff8007i64,
+0xffffffffffff800fi64,
+0xffffffffffff801fi64,
+0xffffffffffff803fi64,
+0xffffffffffff807fi64,
+0xffffffffffff80ffi64,
+0xffffffffffff81ffi64,
+0xffffffffffff83ffi64,
+0xffffffffffff87ffi64,
+0xffffffffffff8fffi64,
+0xffffffffffff9fffi64,
+0xffffffffffffbfffi64
+},
+{
+0xffffffffffff0000i64,
+0xffffffffffff0001i64,
+0xffffffffffff0003i64,
+0xffffffffffff0007i64,
+0xffffffffffff000fi64,
+0xffffffffffff001fi64,
+0xffffffffffff003fi64,
+0xffffffffffff007fi64,
+0xffffffffffff00ffi64,
+0xffffffffffff01ffi64,
+0xffffffffffff03ffi64,
+0xffffffffffff07ffi64,
+0xffffffffffff0fffi64,
+0xffffffffffff1fffi64,
+0xffffffffffff3fffi64,
+0xffffffffffff7fffi64
+},
+{
+0xfffffffffffe0000i64,
+0xfffffffffffe0001i64,
+0xfffffffffffe0003i64,
+0xfffffffffffe0007i64,
+0xfffffffffffe000fi64,
+0xfffffffffffe001fi64,
+0xfffffffffffe003fi64,
+0xfffffffffffe007fi64,
+0xfffffffffffe00ffi64,
+0xfffffffffffe01ffi64,
+0xfffffffffffe03ffi64,
+0xfffffffffffe07ffi64,
+0xfffffffffffe0fffi64,
+0xfffffffffffe1fffi64,
+0xfffffffffffe3fffi64,
+0xfffffffffffe7fffi64,
+0xfffffffffffeffffi64
+},
+{
+0xfffffffffffc0000i64,
+0xfffffffffffc0001i64,
+0xfffffffffffc0003i64,
+0xfffffffffffc0007i64,
+0xfffffffffffc000fi64,
+0xfffffffffffc001fi64,
+0xfffffffffffc003fi64,
+0xfffffffffffc007fi64,
+0xfffffffffffc00ffi64,
+0xfffffffffffc01ffi64,
+0xfffffffffffc03ffi64,
+0xfffffffffffc07ffi64,
+0xfffffffffffc0fffi64,
+0xfffffffffffc1fffi64,
+0xfffffffffffc3fffi64,
+0xfffffffffffc7fffi64,
+0xfffffffffffcffffi64,
+0xfffffffffffdffffi64
+},
+{
+0xfffffffffff80000i64,
+0xfffffffffff80001i64,
+0xfffffffffff80003i64,
+0xfffffffffff80007i64,
+0xfffffffffff8000fi64,
+0xfffffffffff8001fi64,
+0xfffffffffff8003fi64,
+0xfffffffffff8007fi64,
+0xfffffffffff800ffi64,
+0xfffffffffff801ffi64,
+0xfffffffffff803ffi64,
+0xfffffffffff807ffi64,
+0xfffffffffff80fffi64,
+0xfffffffffff81fffi64,
+0xfffffffffff83fffi64,
+0xfffffffffff87fffi64,
+0xfffffffffff8ffffi64,
+0xfffffffffff9ffffi64,
+0xfffffffffffbffffi64
+},
+{
+0xfffffffffff00000i64,
+0xfffffffffff00001i64,
+0xfffffffffff00003i64,
+0xfffffffffff00007i64,
+0xfffffffffff0000fi64,
+0xfffffffffff0001fi64,
+0xfffffffffff0003fi64,
+0xfffffffffff0007fi64,
+0xfffffffffff000ffi64,
+0xfffffffffff001ffi64,
+0xfffffffffff003ffi64,
+0xfffffffffff007ffi64,
+0xfffffffffff00fffi64,
+0xfffffffffff01fffi64,
+0xfffffffffff03fffi64,
+0xfffffffffff07fffi64,
+0xfffffffffff0ffffi64,
+0xfffffffffff1ffffi64,
+0xfffffffffff3ffffi64,
+0xfffffffffff7ffffi64
+},
+{
+0xffffffffffe00000i64,
+0xffffffffffe00001i64,
+0xffffffffffe00003i64,
+0xffffffffffe00007i64,
+0xffffffffffe0000fi64,
+0xffffffffffe0001fi64,
+0xffffffffffe0003fi64,
+0xffffffffffe0007fi64,
+0xffffffffffe000ffi64,
+0xffffffffffe001ffi64,
+0xffffffffffe003ffi64,
+0xffffffffffe007ffi64,
+0xffffffffffe00fffi64,
+0xffffffffffe01fffi64,
+0xffffffffffe03fffi64,
+0xffffffffffe07fffi64,
+0xffffffffffe0ffffi64,
+0xffffffffffe1ffffi64,
+0xffffffffffe3ffffi64,
+0xffffffffffe7ffffi64,
+0xffffffffffefffffi64
+},
+{
+0xffffffffffc00000i64,
+0xffffffffffc00001i64,
+0xffffffffffc00003i64,
+0xffffffffffc00007i64,
+0xffffffffffc0000fi64,
+0xffffffffffc0001fi64,
+0xffffffffffc0003fi64,
+0xffffffffffc0007fi64,
+0xffffffffffc000ffi64,
+0xffffffffffc001ffi64,
+0xffffffffffc003ffi64,
+0xffffffffffc007ffi64,
+0xffffffffffc00fffi64,
+0xffffffffffc01fffi64,
+0xffffffffffc03fffi64,
+0xffffffffffc07fffi64,
+0xffffffffffc0ffffi64,
+0xffffffffffc1ffffi64,
+0xffffffffffc3ffffi64,
+0xffffffffffc7ffffi64,
+0xffffffffffcfffffi64,
+0xffffffffffdfffffi64
+},
+{
+0xffffffffff800000i64,
+0xffffffffff800001i64,
+0xffffffffff800003i64,
+0xffffffffff800007i64,
+0xffffffffff80000fi64,
+0xffffffffff80001fi64,
+0xffffffffff80003fi64,
+0xffffffffff80007fi64,
+0xffffffffff8000ffi64,
+0xffffffffff8001ffi64,
+0xffffffffff8003ffi64,
+0xffffffffff8007ffi64,
+0xffffffffff800fffi64,
+0xffffffffff801fffi64,
+0xffffffffff803fffi64,
+0xffffffffff807fffi64,
+0xffffffffff80ffffi64,
+0xffffffffff81ffffi64,
+0xffffffffff83ffffi64,
+0xffffffffff87ffffi64,
+0xffffffffff8fffffi64,
+0xffffffffff9fffffi64,
+0xffffffffffbfffffi64
+},
+{
+0xffffffffff000000i64,
+0xffffffffff000001i64,
+0xffffffffff000003i64,
+0xffffffffff000007i64,
+0xffffffffff00000fi64,
+0xffffffffff00001fi64,
+0xffffffffff00003fi64,
+0xffffffffff00007fi64,
+0xffffffffff0000ffi64,
+0xffffffffff0001ffi64,
+0xffffffffff0003ffi64,
+0xffffffffff0007ffi64,
+0xffffffffff000fffi64,
+0xffffffffff001fffi64,
+0xffffffffff003fffi64,
+0xffffffffff007fffi64,
+0xffffffffff00ffffi64,
+0xffffffffff01ffffi64,
+0xffffffffff03ffffi64,
+0xffffffffff07ffffi64,
+0xffffffffff0fffffi64,
+0xffffffffff1fffffi64,
+0xffffffffff3fffffi64,
+0xffffffffff7fffffi64
+},
+{
+0xfffffffffe000000i64,
+0xfffffffffe000001i64,
+0xfffffffffe000003i64,
+0xfffffffffe000007i64,
+0xfffffffffe00000fi64,
+0xfffffffffe00001fi64,
+0xfffffffffe00003fi64,
+0xfffffffffe00007fi64,
+0xfffffffffe0000ffi64,
+0xfffffffffe0001ffi64,
+0xfffffffffe0003ffi64,
+0xfffffffffe0007ffi64,
+0xfffffffffe000fffi64,
+0xfffffffffe001fffi64,
+0xfffffffffe003fffi64,
+0xfffffffffe007fffi64,
+0xfffffffffe00ffffi64,
+0xfffffffffe01ffffi64,
+0xfffffffffe03ffffi64,
+0xfffffffffe07ffffi64,
+0xfffffffffe0fffffi64,
+0xfffffffffe1fffffi64,
+0xfffffffffe3fffffi64,
+0xfffffffffe7fffffi64,
+0xfffffffffeffffffi64
+},
+{
+0xfffffffffc000000i64,
+0xfffffffffc000001i64,
+0xfffffffffc000003i64,
+0xfffffffffc000007i64,
+0xfffffffffc00000fi64,
+0xfffffffffc00001fi64,
+0xfffffffffc00003fi64,
+0xfffffffffc00007fi64,
+0xfffffffffc0000ffi64,
+0xfffffffffc0001ffi64,
+0xfffffffffc0003ffi64,
+0xfffffffffc0007ffi64,
+0xfffffffffc000fffi64,
+0xfffffffffc001fffi64,
+0xfffffffffc003fffi64,
+0xfffffffffc007fffi64,
+0xfffffffffc00ffffi64,
+0xfffffffffc01ffffi64,
+0xfffffffffc03ffffi64,
+0xfffffffffc07ffffi64,
+0xfffffffffc0fffffi64,
+0xfffffffffc1fffffi64,
+0xfffffffffc3fffffi64,
+0xfffffffffc7fffffi64,
+0xfffffffffcffffffi64,
+0xfffffffffdffffffi64
+},
+{
+0xfffffffff8000000i64,
+0xfffffffff8000001i64,
+0xfffffffff8000003i64,
+0xfffffffff8000007i64,
+0xfffffffff800000fi64,
+0xfffffffff800001fi64,
+0xfffffffff800003fi64,
+0xfffffffff800007fi64,
+0xfffffffff80000ffi64,
+0xfffffffff80001ffi64,
+0xfffffffff80003ffi64,
+0xfffffffff80007ffi64,
+0xfffffffff8000fffi64,
+0xfffffffff8001fffi64,
+0xfffffffff8003fffi64,
+0xfffffffff8007fffi64,
+0xfffffffff800ffffi64,
+0xfffffffff801ffffi64,
+0xfffffffff803ffffi64,
+0xfffffffff807ffffi64,
+0xfffffffff80fffffi64,
+0xfffffffff81fffffi64,
+0xfffffffff83fffffi64,
+0xfffffffff87fffffi64,
+0xfffffffff8ffffffi64,
+0xfffffffff9ffffffi64,
+0xfffffffffbffffffi64
+},
+{
+0xfffffffff0000000i64,
+0xfffffffff0000001i64,
+0xfffffffff0000003i64,
+0xfffffffff0000007i64,
+0xfffffffff000000fi64,
+0xfffffffff000001fi64,
+0xfffffffff000003fi64,
+0xfffffffff000007fi64,
+0xfffffffff00000ffi64,
+0xfffffffff00001ffi64,
+0xfffffffff00003ffi64,
+0xfffffffff00007ffi64,
+0xfffffffff0000fffi64,
+0xfffffffff0001fffi64,
+0xfffffffff0003fffi64,
+0xfffffffff0007fffi64,
+0xfffffffff000ffffi64,
+0xfffffffff001ffffi64,
+0xfffffffff003ffffi64,
+0xfffffffff007ffffi64,
+0xfffffffff00fffffi64,
+0xfffffffff01fffffi64,
+0xfffffffff03fffffi64,
+0xfffffffff07fffffi64,
+0xfffffffff0ffffffi64,
+0xfffffffff1ffffffi64,
+0xfffffffff3ffffffi64,
+0xfffffffff7ffffffi64
+},
+{
+0xffffffffe0000000i64,
+0xffffffffe0000001i64,
+0xffffffffe0000003i64,
+0xffffffffe0000007i64,
+0xffffffffe000000fi64,
+0xffffffffe000001fi64,
+0xffffffffe000003fi64,
+0xffffffffe000007fi64,
+0xffffffffe00000ffi64,
+0xffffffffe00001ffi64,
+0xffffffffe00003ffi64,
+0xffffffffe00007ffi64,
+0xffffffffe0000fffi64,
+0xffffffffe0001fffi64,
+0xffffffffe0003fffi64,
+0xffffffffe0007fffi64,
+0xffffffffe000ffffi64,
+0xffffffffe001ffffi64,
+0xffffffffe003ffffi64,
+0xffffffffe007ffffi64,
+0xffffffffe00fffffi64,
+0xffffffffe01fffffi64,
+0xffffffffe03fffffi64,
+0xffffffffe07fffffi64,
+0xffffffffe0ffffffi64,
+0xffffffffe1ffffffi64,
+0xffffffffe3ffffffi64,
+0xffffffffe7ffffffi64,
+0xffffffffefffffffi64
+},
+{
+0xffffffffc0000000i64,
+0xffffffffc0000001i64,
+0xffffffffc0000003i64,
+0xffffffffc0000007i64,
+0xffffffffc000000fi64,
+0xffffffffc000001fi64,
+0xffffffffc000003fi64,
+0xffffffffc000007fi64,
+0xffffffffc00000ffi64,
+0xffffffffc00001ffi64,
+0xffffffffc00003ffi64,
+0xffffffffc00007ffi64,
+0xffffffffc0000fffi64,
+0xffffffffc0001fffi64,
+0xffffffffc0003fffi64,
+0xffffffffc0007fffi64,
+0xffffffffc000ffffi64,
+0xffffffffc001ffffi64,
+0xffffffffc003ffffi64,
+0xffffffffc007ffffi64,
+0xffffffffc00fffffi64,
+0xffffffffc01fffffi64,
+0xffffffffc03fffffi64,
+0xffffffffc07fffffi64,
+0xffffffffc0ffffffi64,
+0xffffffffc1ffffffi64,
+0xffffffffc3ffffffi64,
+0xffffffffc7ffffffi64,
+0xffffffffcfffffffi64,
+0xffffffffdfffffffi64
+},
+{
+0xffffffff80000000i64,
+0xffffffff80000001i64,
+0xffffffff80000003i64,
+0xffffffff80000007i64,
+0xffffffff8000000fi64,
+0xffffffff8000001fi64,
+0xffffffff8000003fi64,
+0xffffffff8000007fi64,
+0xffffffff800000ffi64,
+0xffffffff800001ffi64,
+0xffffffff800003ffi64,
+0xffffffff800007ffi64,
+0xffffffff80000fffi64,
+0xffffffff80001fffi64,
+0xffffffff80003fffi64,
+0xffffffff80007fffi64,
+0xffffffff8000ffffi64,
+0xffffffff8001ffffi64,
+0xffffffff8003ffffi64,
+0xffffffff8007ffffi64,
+0xffffffff800fffffi64,
+0xffffffff801fffffi64,
+0xffffffff803fffffi64,
+0xffffffff807fffffi64,
+0xffffffff80ffffffi64,
+0xffffffff81ffffffi64,
+0xffffffff83ffffffi64,
+0xffffffff87ffffffi64,
+0xffffffff8fffffffi64,
+0xffffffff9fffffffi64,
+0xffffffffbfffffffi64
+},
+{
+0xffffffff00000000i64,
+0xffffffff00000001i64,
+0xffffffff00000003i64,
+0xffffffff00000007i64,
+0xffffffff0000000fi64,
+0xffffffff0000001fi64,
+0xffffffff0000003fi64,
+0xffffffff0000007fi64,
+0xffffffff000000ffi64,
+0xffffffff000001ffi64,
+0xffffffff000003ffi64,
+0xffffffff000007ffi64,
+0xffffffff00000fffi64,
+0xffffffff00001fffi64,
+0xffffffff00003fffi64,
+0xffffffff00007fffi64,
+0xffffffff0000ffffi64,
+0xffffffff0001ffffi64,
+0xffffffff0003ffffi64,
+0xffffffff0007ffffi64,
+0xffffffff000fffffi64,
+0xffffffff001fffffi64,
+0xffffffff003fffffi64,
+0xffffffff007fffffi64,
+0xffffffff00ffffffi64,
+0xffffffff01ffffffi64,
+0xffffffff03ffffffi64,
+0xffffffff07ffffffi64,
+0xffffffff0fffffffi64,
+0xffffffff1fffffffi64,
+0xffffffff3fffffffi64,
+0xffffffff7fffffffi64
+},
+{
+0xfffffffe00000000i64,
+0xfffffffe00000001i64,
+0xfffffffe00000003i64,
+0xfffffffe00000007i64,
+0xfffffffe0000000fi64,
+0xfffffffe0000001fi64,
+0xfffffffe0000003fi64,
+0xfffffffe0000007fi64,
+0xfffffffe000000ffi64,
+0xfffffffe000001ffi64,
+0xfffffffe000003ffi64,
+0xfffffffe000007ffi64,
+0xfffffffe00000fffi64,
+0xfffffffe00001fffi64,
+0xfffffffe00003fffi64,
+0xfffffffe00007fffi64,
+0xfffffffe0000ffffi64,
+0xfffffffe0001ffffi64,
+0xfffffffe0003ffffi64,
+0xfffffffe0007ffffi64,
+0xfffffffe000fffffi64,
+0xfffffffe001fffffi64,
+0xfffffffe003fffffi64,
+0xfffffffe007fffffi64,
+0xfffffffe00ffffffi64,
+0xfffffffe01ffffffi64,
+0xfffffffe03ffffffi64,
+0xfffffffe07ffffffi64,
+0xfffffffe0fffffffi64,
+0xfffffffe1fffffffi64,
+0xfffffffe3fffffffi64,
+0xfffffffe7fffffffi64,
+0xfffffffeffffffffi64
+},
+{
+0xfffffffc00000000i64,
+0xfffffffc00000001i64,
+0xfffffffc00000003i64,
+0xfffffffc00000007i64,
+0xfffffffc0000000fi64,
+0xfffffffc0000001fi64,
+0xfffffffc0000003fi64,
+0xfffffffc0000007fi64,
+0xfffffffc000000ffi64,
+0xfffffffc000001ffi64,
+0xfffffffc000003ffi64,
+0xfffffffc000007ffi64,
+0xfffffffc00000fffi64,
+0xfffffffc00001fffi64,
+0xfffffffc00003fffi64,
+0xfffffffc00007fffi64,
+0xfffffffc0000ffffi64,
+0xfffffffc0001ffffi64,
+0xfffffffc0003ffffi64,
+0xfffffffc0007ffffi64,
+0xfffffffc000fffffi64,
+0xfffffffc001fffffi64,
+0xfffffffc003fffffi64,
+0xfffffffc007fffffi64,
+0xfffffffc00ffffffi64,
+0xfffffffc01ffffffi64,
+0xfffffffc03ffffffi64,
+0xfffffffc07ffffffi64,
+0xfffffffc0fffffffi64,
+0xfffffffc1fffffffi64,
+0xfffffffc3fffffffi64,
+0xfffffffc7fffffffi64,
+0xfffffffcffffffffi64,
+0xfffffffdffffffffi64
+},
+{
+0xfffffff800000000i64,
+0xfffffff800000001i64,
+0xfffffff800000003i64,
+0xfffffff800000007i64,
+0xfffffff80000000fi64,
+0xfffffff80000001fi64,
+0xfffffff80000003fi64,
+0xfffffff80000007fi64,
+0xfffffff8000000ffi64,
+0xfffffff8000001ffi64,
+0xfffffff8000003ffi64,
+0xfffffff8000007ffi64,
+0xfffffff800000fffi64,
+0xfffffff800001fffi64,
+0xfffffff800003fffi64,
+0xfffffff800007fffi64,
+0xfffffff80000ffffi64,
+0xfffffff80001ffffi64,
+0xfffffff80003ffffi64,
+0xfffffff80007ffffi64,
+0xfffffff8000fffffi64,
+0xfffffff8001fffffi64,
+0xfffffff8003fffffi64,
+0xfffffff8007fffffi64,
+0xfffffff800ffffffi64,
+0xfffffff801ffffffi64,
+0xfffffff803ffffffi64,
+0xfffffff807ffffffi64,
+0xfffffff80fffffffi64,
+0xfffffff81fffffffi64,
+0xfffffff83fffffffi64,
+0xfffffff87fffffffi64,
+0xfffffff8ffffffffi64,
+0xfffffff9ffffffffi64,
+0xfffffffbffffffffi64
+},
+{
+0xfffffff000000000i64,
+0xfffffff000000001i64,
+0xfffffff000000003i64,
+0xfffffff000000007i64,
+0xfffffff00000000fi64,
+0xfffffff00000001fi64,
+0xfffffff00000003fi64,
+0xfffffff00000007fi64,
+0xfffffff0000000ffi64,
+0xfffffff0000001ffi64,
+0xfffffff0000003ffi64,
+0xfffffff0000007ffi64,
+0xfffffff000000fffi64,
+0xfffffff000001fffi64,
+0xfffffff000003fffi64,
+0xfffffff000007fffi64,
+0xfffffff00000ffffi64,
+0xfffffff00001ffffi64,
+0xfffffff00003ffffi64,
+0xfffffff00007ffffi64,
+0xfffffff0000fffffi64,
+0xfffffff0001fffffi64,
+0xfffffff0003fffffi64,
+0xfffffff0007fffffi64,
+0xfffffff000ffffffi64,
+0xfffffff001ffffffi64,
+0xfffffff003ffffffi64,
+0xfffffff007ffffffi64,
+0xfffffff00fffffffi64,
+0xfffffff01fffffffi64,
+0xfffffff03fffffffi64,
+0xfffffff07fffffffi64,
+0xfffffff0ffffffffi64,
+0xfffffff1ffffffffi64,
+0xfffffff3ffffffffi64,
+0xfffffff7ffffffffi64
+},
+{
+0xffffffe000000000i64,
+0xffffffe000000001i64,
+0xffffffe000000003i64,
+0xffffffe000000007i64,
+0xffffffe00000000fi64,
+0xffffffe00000001fi64,
+0xffffffe00000003fi64,
+0xffffffe00000007fi64,
+0xffffffe0000000ffi64,
+0xffffffe0000001ffi64,
+0xffffffe0000003ffi64,
+0xffffffe0000007ffi64,
+0xffffffe000000fffi64,
+0xffffffe000001fffi64,
+0xffffffe000003fffi64,
+0xffffffe000007fffi64,
+0xffffffe00000ffffi64,
+0xffffffe00001ffffi64,
+0xffffffe00003ffffi64,
+0xffffffe00007ffffi64,
+0xffffffe0000fffffi64,
+0xffffffe0001fffffi64,
+0xffffffe0003fffffi64,
+0xffffffe0007fffffi64,
+0xffffffe000ffffffi64,
+0xffffffe001ffffffi64,
+0xffffffe003ffffffi64,
+0xffffffe007ffffffi64,
+0xffffffe00fffffffi64,
+0xffffffe01fffffffi64,
+0xffffffe03fffffffi64,
+0xffffffe07fffffffi64,
+0xffffffe0ffffffffi64,
+0xffffffe1ffffffffi64,
+0xffffffe3ffffffffi64,
+0xffffffe7ffffffffi64,
+0xffffffefffffffffi64
+},
+{
+0xffffffc000000000i64,
+0xffffffc000000001i64,
+0xffffffc000000003i64,
+0xffffffc000000007i64,
+0xffffffc00000000fi64,
+0xffffffc00000001fi64,
+0xffffffc00000003fi64,
+0xffffffc00000007fi64,
+0xffffffc0000000ffi64,
+0xffffffc0000001ffi64,
+0xffffffc0000003ffi64,
+0xffffffc0000007ffi64,
+0xffffffc000000fffi64,
+0xffffffc000001fffi64,
+0xffffffc000003fffi64,
+0xffffffc000007fffi64,
+0xffffffc00000ffffi64,
+0xffffffc00001ffffi64,
+0xffffffc00003ffffi64,
+0xffffffc00007ffffi64,
+0xffffffc0000fffffi64,
+0xffffffc0001fffffi64,
+0xffffffc0003fffffi64,
+0xffffffc0007fffffi64,
+0xffffffc000ffffffi64,
+0xffffffc001ffffffi64,
+0xffffffc003ffffffi64,
+0xffffffc007ffffffi64,
+0xffffffc00fffffffi64,
+0xffffffc01fffffffi64,
+0xffffffc03fffffffi64,
+0xffffffc07fffffffi64,
+0xffffffc0ffffffffi64,
+0xffffffc1ffffffffi64,
+0xffffffc3ffffffffi64,
+0xffffffc7ffffffffi64,
+0xffffffcfffffffffi64,
+0xffffffdfffffffffi64
+},
+{
+0xffffff8000000000i64,
+0xffffff8000000001i64,
+0xffffff8000000003i64,
+0xffffff8000000007i64,
+0xffffff800000000fi64,
+0xffffff800000001fi64,
+0xffffff800000003fi64,
+0xffffff800000007fi64,
+0xffffff80000000ffi64,
+0xffffff80000001ffi64,
+0xffffff80000003ffi64,
+0xffffff80000007ffi64,
+0xffffff8000000fffi64,
+0xffffff8000001fffi64,
+0xffffff8000003fffi64,
+0xffffff8000007fffi64,
+0xffffff800000ffffi64,
+0xffffff800001ffffi64,
+0xffffff800003ffffi64,
+0xffffff800007ffffi64,
+0xffffff80000fffffi64,
+0xffffff80001fffffi64,
+0xffffff80003fffffi64,
+0xffffff80007fffffi64,
+0xffffff8000ffffffi64,
+0xffffff8001ffffffi64,
+0xffffff8003ffffffi64,
+0xffffff8007ffffffi64,
+0xffffff800fffffffi64,
+0xffffff801fffffffi64,
+0xffffff803fffffffi64,
+0xffffff807fffffffi64,
+0xffffff80ffffffffi64,
+0xffffff81ffffffffi64,
+0xffffff83ffffffffi64,
+0xffffff87ffffffffi64,
+0xffffff8fffffffffi64,
+0xffffff9fffffffffi64,
+0xffffffbfffffffffi64
+},
+{
+0xffffff0000000000i64,
+0xffffff0000000001i64,
+0xffffff0000000003i64,
+0xffffff0000000007i64,
+0xffffff000000000fi64,
+0xffffff000000001fi64,
+0xffffff000000003fi64,
+0xffffff000000007fi64,
+0xffffff00000000ffi64,
+0xffffff00000001ffi64,
+0xffffff00000003ffi64,
+0xffffff00000007ffi64,
+0xffffff0000000fffi64,
+0xffffff0000001fffi64,
+0xffffff0000003fffi64,
+0xffffff0000007fffi64,
+0xffffff000000ffffi64,
+0xffffff000001ffffi64,
+0xffffff000003ffffi64,
+0xffffff000007ffffi64,
+0xffffff00000fffffi64,
+0xffffff00001fffffi64,
+0xffffff00003fffffi64,
+0xffffff00007fffffi64,
+0xffffff0000ffffffi64,
+0xffffff0001ffffffi64,
+0xffffff0003ffffffi64,
+0xffffff0007ffffffi64,
+0xffffff000fffffffi64,
+0xffffff001fffffffi64,
+0xffffff003fffffffi64,
+0xffffff007fffffffi64,
+0xffffff00ffffffffi64,
+0xffffff01ffffffffi64,
+0xffffff03ffffffffi64,
+0xffffff07ffffffffi64,
+0xffffff0fffffffffi64,
+0xffffff1fffffffffi64,
+0xffffff3fffffffffi64,
+0xffffff7fffffffffi64
+},
+{
+0xfffffe0000000000i64,
+0xfffffe0000000001i64,
+0xfffffe0000000003i64,
+0xfffffe0000000007i64,
+0xfffffe000000000fi64,
+0xfffffe000000001fi64,
+0xfffffe000000003fi64,
+0xfffffe000000007fi64,
+0xfffffe00000000ffi64,
+0xfffffe00000001ffi64,
+0xfffffe00000003ffi64,
+0xfffffe00000007ffi64,
+0xfffffe0000000fffi64,
+0xfffffe0000001fffi64,
+0xfffffe0000003fffi64,
+0xfffffe0000007fffi64,
+0xfffffe000000ffffi64,
+0xfffffe000001ffffi64,
+0xfffffe000003ffffi64,
+0xfffffe000007ffffi64,
+0xfffffe00000fffffi64,
+0xfffffe00001fffffi64,
+0xfffffe00003fffffi64,
+0xfffffe00007fffffi64,
+0xfffffe0000ffffffi64,
+0xfffffe0001ffffffi64,
+0xfffffe0003ffffffi64,
+0xfffffe0007ffffffi64,
+0xfffffe000fffffffi64,
+0xfffffe001fffffffi64,
+0xfffffe003fffffffi64,
+0xfffffe007fffffffi64,
+0xfffffe00ffffffffi64,
+0xfffffe01ffffffffi64,
+0xfffffe03ffffffffi64,
+0xfffffe07ffffffffi64,
+0xfffffe0fffffffffi64,
+0xfffffe1fffffffffi64,
+0xfffffe3fffffffffi64,
+0xfffffe7fffffffffi64,
+0xfffffeffffffffffi64
+},
+{
+0xfffffc0000000000i64,
+0xfffffc0000000001i64,
+0xfffffc0000000003i64,
+0xfffffc0000000007i64,
+0xfffffc000000000fi64,
+0xfffffc000000001fi64,
+0xfffffc000000003fi64,
+0xfffffc000000007fi64,
+0xfffffc00000000ffi64,
+0xfffffc00000001ffi64,
+0xfffffc00000003ffi64,
+0xfffffc00000007ffi64,
+0xfffffc0000000fffi64,
+0xfffffc0000001fffi64,
+0xfffffc0000003fffi64,
+0xfffffc0000007fffi64,
+0xfffffc000000ffffi64,
+0xfffffc000001ffffi64,
+0xfffffc000003ffffi64,
+0xfffffc000007ffffi64,
+0xfffffc00000fffffi64,
+0xfffffc00001fffffi64,
+0xfffffc00003fffffi64,
+0xfffffc00007fffffi64,
+0xfffffc0000ffffffi64,
+0xfffffc0001ffffffi64,
+0xfffffc0003ffffffi64,
+0xfffffc0007ffffffi64,
+0xfffffc000fffffffi64,
+0xfffffc001fffffffi64,
+0xfffffc003fffffffi64,
+0xfffffc007fffffffi64,
+0xfffffc00ffffffffi64,
+0xfffffc01ffffffffi64,
+0xfffffc03ffffffffi64,
+0xfffffc07ffffffffi64,
+0xfffffc0fffffffffi64,
+0xfffffc1fffffffffi64,
+0xfffffc3fffffffffi64,
+0xfffffc7fffffffffi64,
+0xfffffcffffffffffi64,
+0xfffffdffffffffffi64
+},
+{
+0xfffff80000000000i64,
+0xfffff80000000001i64,
+0xfffff80000000003i64,
+0xfffff80000000007i64,
+0xfffff8000000000fi64,
+0xfffff8000000001fi64,
+0xfffff8000000003fi64,
+0xfffff8000000007fi64,
+0xfffff800000000ffi64,
+0xfffff800000001ffi64,
+0xfffff800000003ffi64,
+0xfffff800000007ffi64,
+0xfffff80000000fffi64,
+0xfffff80000001fffi64,
+0xfffff80000003fffi64,
+0xfffff80000007fffi64,
+0xfffff8000000ffffi64,
+0xfffff8000001ffffi64,
+0xfffff8000003ffffi64,
+0xfffff8000007ffffi64,
+0xfffff800000fffffi64,
+0xfffff800001fffffi64,
+0xfffff800003fffffi64,
+0xfffff800007fffffi64,
+0xfffff80000ffffffi64,
+0xfffff80001ffffffi64,
+0xfffff80003ffffffi64,
+0xfffff80007ffffffi64,
+0xfffff8000fffffffi64,
+0xfffff8001fffffffi64,
+0xfffff8003fffffffi64,
+0xfffff8007fffffffi64,
+0xfffff800ffffffffi64,
+0xfffff801ffffffffi64,
+0xfffff803ffffffffi64,
+0xfffff807ffffffffi64,
+0xfffff80fffffffffi64,
+0xfffff81fffffffffi64,
+0xfffff83fffffffffi64,
+0xfffff87fffffffffi64,
+0xfffff8ffffffffffi64,
+0xfffff9ffffffffffi64,
+0xfffffbffffffffffi64
+},
+{
+0xfffff00000000000i64,
+0xfffff00000000001i64,
+0xfffff00000000003i64,
+0xfffff00000000007i64,
+0xfffff0000000000fi64,
+0xfffff0000000001fi64,
+0xfffff0000000003fi64,
+0xfffff0000000007fi64,
+0xfffff000000000ffi64,
+0xfffff000000001ffi64,
+0xfffff000000003ffi64,
+0xfffff000000007ffi64,
+0xfffff00000000fffi64,
+0xfffff00000001fffi64,
+0xfffff00000003fffi64,
+0xfffff00000007fffi64,
+0xfffff0000000ffffi64,
+0xfffff0000001ffffi64,
+0xfffff0000003ffffi64,
+0xfffff0000007ffffi64,
+0xfffff000000fffffi64,
+0xfffff000001fffffi64,
+0xfffff000003fffffi64,
+0xfffff000007fffffi64,
+0xfffff00000ffffffi64,
+0xfffff00001ffffffi64,
+0xfffff00003ffffffi64,
+0xfffff00007ffffffi64,
+0xfffff0000fffffffi64,
+0xfffff0001fffffffi64,
+0xfffff0003fffffffi64,
+0xfffff0007fffffffi64,
+0xfffff000ffffffffi64,
+0xfffff001ffffffffi64,
+0xfffff003ffffffffi64,
+0xfffff007ffffffffi64,
+0xfffff00fffffffffi64,
+0xfffff01fffffffffi64,
+0xfffff03fffffffffi64,
+0xfffff07fffffffffi64,
+0xfffff0ffffffffffi64,
+0xfffff1ffffffffffi64,
+0xfffff3ffffffffffi64,
+0xfffff7ffffffffffi64
+},
+{
+0xffffe00000000000i64,
+0xffffe00000000001i64,
+0xffffe00000000003i64,
+0xffffe00000000007i64,
+0xffffe0000000000fi64,
+0xffffe0000000001fi64,
+0xffffe0000000003fi64,
+0xffffe0000000007fi64,
+0xffffe000000000ffi64,
+0xffffe000000001ffi64,
+0xffffe000000003ffi64,
+0xffffe000000007ffi64,
+0xffffe00000000fffi64,
+0xffffe00000001fffi64,
+0xffffe00000003fffi64,
+0xffffe00000007fffi64,
+0xffffe0000000ffffi64,
+0xffffe0000001ffffi64,
+0xffffe0000003ffffi64,
+0xffffe0000007ffffi64,
+0xffffe000000fffffi64,
+0xffffe000001fffffi64,
+0xffffe000003fffffi64,
+0xffffe000007fffffi64,
+0xffffe00000ffffffi64,
+0xffffe00001ffffffi64,
+0xffffe00003ffffffi64,
+0xffffe00007ffffffi64,
+0xffffe0000fffffffi64,
+0xffffe0001fffffffi64,
+0xffffe0003fffffffi64,
+0xffffe0007fffffffi64,
+0xffffe000ffffffffi64,
+0xffffe001ffffffffi64,
+0xffffe003ffffffffi64,
+0xffffe007ffffffffi64,
+0xffffe00fffffffffi64,
+0xffffe01fffffffffi64,
+0xffffe03fffffffffi64,
+0xffffe07fffffffffi64,
+0xffffe0ffffffffffi64,
+0xffffe1ffffffffffi64,
+0xffffe3ffffffffffi64,
+0xffffe7ffffffffffi64,
+0xffffefffffffffffi64
+},
+{
+0xffffc00000000000i64,
+0xffffc00000000001i64,
+0xffffc00000000003i64,
+0xffffc00000000007i64,
+0xffffc0000000000fi64,
+0xffffc0000000001fi64,
+0xffffc0000000003fi64,
+0xffffc0000000007fi64,
+0xffffc000000000ffi64,
+0xffffc000000001ffi64,
+0xffffc000000003ffi64,
+0xffffc000000007ffi64,
+0xffffc00000000fffi64,
+0xffffc00000001fffi64,
+0xffffc00000003fffi64,
+0xffffc00000007fffi64,
+0xffffc0000000ffffi64,
+0xffffc0000001ffffi64,
+0xffffc0000003ffffi64,
+0xffffc0000007ffffi64,
+0xffffc000000fffffi64,
+0xffffc000001fffffi64,
+0xffffc000003fffffi64,
+0xffffc000007fffffi64,
+0xffffc00000ffffffi64,
+0xffffc00001ffffffi64,
+0xffffc00003ffffffi64,
+0xffffc00007ffffffi64,
+0xffffc0000fffffffi64,
+0xffffc0001fffffffi64,
+0xffffc0003fffffffi64,
+0xffffc0007fffffffi64,
+0xffffc000ffffffffi64,
+0xffffc001ffffffffi64,
+0xffffc003ffffffffi64,
+0xffffc007ffffffffi64,
+0xffffc00fffffffffi64,
+0xffffc01fffffffffi64,
+0xffffc03fffffffffi64,
+0xffffc07fffffffffi64,
+0xffffc0ffffffffffi64,
+0xffffc1ffffffffffi64,
+0xffffc3ffffffffffi64,
+0xffffc7ffffffffffi64,
+0xffffcfffffffffffi64,
+0xffffdfffffffffffi64
+},
+{
+0xffff800000000000i64,
+0xffff800000000001i64,
+0xffff800000000003i64,
+0xffff800000000007i64,
+0xffff80000000000fi64,
+0xffff80000000001fi64,
+0xffff80000000003fi64,
+0xffff80000000007fi64,
+0xffff8000000000ffi64,
+0xffff8000000001ffi64,
+0xffff8000000003ffi64,
+0xffff8000000007ffi64,
+0xffff800000000fffi64,
+0xffff800000001fffi64,
+0xffff800000003fffi64,
+0xffff800000007fffi64,
+0xffff80000000ffffi64,
+0xffff80000001ffffi64,
+0xffff80000003ffffi64,
+0xffff80000007ffffi64,
+0xffff8000000fffffi64,
+0xffff8000001fffffi64,
+0xffff8000003fffffi64,
+0xffff8000007fffffi64,
+0xffff800000ffffffi64,
+0xffff800001ffffffi64,
+0xffff800003ffffffi64,
+0xffff800007ffffffi64,
+0xffff80000fffffffi64,
+0xffff80001fffffffi64,
+0xffff80003fffffffi64,
+0xffff80007fffffffi64,
+0xffff8000ffffffffi64,
+0xffff8001ffffffffi64,
+0xffff8003ffffffffi64,
+0xffff8007ffffffffi64,
+0xffff800fffffffffi64,
+0xffff801fffffffffi64,
+0xffff803fffffffffi64,
+0xffff807fffffffffi64,
+0xffff80ffffffffffi64,
+0xffff81ffffffffffi64,
+0xffff83ffffffffffi64,
+0xffff87ffffffffffi64,
+0xffff8fffffffffffi64,
+0xffff9fffffffffffi64,
+0xffffbfffffffffffi64
+},
+{
+0xffff000000000000i64,
+0xffff000000000001i64,
+0xffff000000000003i64,
+0xffff000000000007i64,
+0xffff00000000000fi64,
+0xffff00000000001fi64,
+0xffff00000000003fi64,
+0xffff00000000007fi64,
+0xffff0000000000ffi64,
+0xffff0000000001ffi64,
+0xffff0000000003ffi64,
+0xffff0000000007ffi64,
+0xffff000000000fffi64,
+0xffff000000001fffi64,
+0xffff000000003fffi64,
+0xffff000000007fffi64,
+0xffff00000000ffffi64,
+0xffff00000001ffffi64,
+0xffff00000003ffffi64,
+0xffff00000007ffffi64,
+0xffff0000000fffffi64,
+0xffff0000001fffffi64,
+0xffff0000003fffffi64,
+0xffff0000007fffffi64,
+0xffff000000ffffffi64,
+0xffff000001ffffffi64,
+0xffff000003ffffffi64,
+0xffff000007ffffffi64,
+0xffff00000fffffffi64,
+0xffff00001fffffffi64,
+0xffff00003fffffffi64,
+0xffff00007fffffffi64,
+0xffff0000ffffffffi64,
+0xffff0001ffffffffi64,
+0xffff0003ffffffffi64,
+0xffff0007ffffffffi64,
+0xffff000fffffffffi64,
+0xffff001fffffffffi64,
+0xffff003fffffffffi64,
+0xffff007fffffffffi64,
+0xffff00ffffffffffi64,
+0xffff01ffffffffffi64,
+0xffff03ffffffffffi64,
+0xffff07ffffffffffi64,
+0xffff0fffffffffffi64,
+0xffff1fffffffffffi64,
+0xffff3fffffffffffi64,
+0xffff7fffffffffffi64
+},
+{
+0xfffe000000000000i64,
+0xfffe000000000001i64,
+0xfffe000000000003i64,
+0xfffe000000000007i64,
+0xfffe00000000000fi64,
+0xfffe00000000001fi64,
+0xfffe00000000003fi64,
+0xfffe00000000007fi64,
+0xfffe0000000000ffi64,
+0xfffe0000000001ffi64,
+0xfffe0000000003ffi64,
+0xfffe0000000007ffi64,
+0xfffe000000000fffi64,
+0xfffe000000001fffi64,
+0xfffe000000003fffi64,
+0xfffe000000007fffi64,
+0xfffe00000000ffffi64,
+0xfffe00000001ffffi64,
+0xfffe00000003ffffi64,
+0xfffe00000007ffffi64,
+0xfffe0000000fffffi64,
+0xfffe0000001fffffi64,
+0xfffe0000003fffffi64,
+0xfffe0000007fffffi64,
+0xfffe000000ffffffi64,
+0xfffe000001ffffffi64,
+0xfffe000003ffffffi64,
+0xfffe000007ffffffi64,
+0xfffe00000fffffffi64,
+0xfffe00001fffffffi64,
+0xfffe00003fffffffi64,
+0xfffe00007fffffffi64,
+0xfffe0000ffffffffi64,
+0xfffe0001ffffffffi64,
+0xfffe0003ffffffffi64,
+0xfffe0007ffffffffi64,
+0xfffe000fffffffffi64,
+0xfffe001fffffffffi64,
+0xfffe003fffffffffi64,
+0xfffe007fffffffffi64,
+0xfffe00ffffffffffi64,
+0xfffe01ffffffffffi64,
+0xfffe03ffffffffffi64,
+0xfffe07ffffffffffi64,
+0xfffe0fffffffffffi64,
+0xfffe1fffffffffffi64,
+0xfffe3fffffffffffi64,
+0xfffe7fffffffffffi64,
+0xfffeffffffffffffi64
+},
+{
+0xfffc000000000000i64,
+0xfffc000000000001i64,
+0xfffc000000000003i64,
+0xfffc000000000007i64,
+0xfffc00000000000fi64,
+0xfffc00000000001fi64,
+0xfffc00000000003fi64,
+0xfffc00000000007fi64,
+0xfffc0000000000ffi64,
+0xfffc0000000001ffi64,
+0xfffc0000000003ffi64,
+0xfffc0000000007ffi64,
+0xfffc000000000fffi64,
+0xfffc000000001fffi64,
+0xfffc000000003fffi64,
+0xfffc000000007fffi64,
+0xfffc00000000ffffi64,
+0xfffc00000001ffffi64,
+0xfffc00000003ffffi64,
+0xfffc00000007ffffi64,
+0xfffc0000000fffffi64,
+0xfffc0000001fffffi64,
+0xfffc0000003fffffi64,
+0xfffc0000007fffffi64,
+0xfffc000000ffffffi64,
+0xfffc000001ffffffi64,
+0xfffc000003ffffffi64,
+0xfffc000007ffffffi64,
+0xfffc00000fffffffi64,
+0xfffc00001fffffffi64,
+0xfffc00003fffffffi64,
+0xfffc00007fffffffi64,
+0xfffc0000ffffffffi64,
+0xfffc0001ffffffffi64,
+0xfffc0003ffffffffi64,
+0xfffc0007ffffffffi64,
+0xfffc000fffffffffi64,
+0xfffc001fffffffffi64,
+0xfffc003fffffffffi64,
+0xfffc007fffffffffi64,
+0xfffc00ffffffffffi64,
+0xfffc01ffffffffffi64,
+0xfffc03ffffffffffi64,
+0xfffc07ffffffffffi64,
+0xfffc0fffffffffffi64,
+0xfffc1fffffffffffi64,
+0xfffc3fffffffffffi64,
+0xfffc7fffffffffffi64,
+0xfffcffffffffffffi64,
+0xfffdffffffffffffi64
+},
+{
+0xfff8000000000000i64,
+0xfff8000000000001i64,
+0xfff8000000000003i64,
+0xfff8000000000007i64,
+0xfff800000000000fi64,
+0xfff800000000001fi64,
+0xfff800000000003fi64,
+0xfff800000000007fi64,
+0xfff80000000000ffi64,
+0xfff80000000001ffi64,
+0xfff80000000003ffi64,
+0xfff80000000007ffi64,
+0xfff8000000000fffi64,
+0xfff8000000001fffi64,
+0xfff8000000003fffi64,
+0xfff8000000007fffi64,
+0xfff800000000ffffi64,
+0xfff800000001ffffi64,
+0xfff800000003ffffi64,
+0xfff800000007ffffi64,
+0xfff80000000fffffi64,
+0xfff80000001fffffi64,
+0xfff80000003fffffi64,
+0xfff80000007fffffi64,
+0xfff8000000ffffffi64,
+0xfff8000001ffffffi64,
+0xfff8000003ffffffi64,
+0xfff8000007ffffffi64,
+0xfff800000fffffffi64,
+0xfff800001fffffffi64,
+0xfff800003fffffffi64,
+0xfff800007fffffffi64,
+0xfff80000ffffffffi64,
+0xfff80001ffffffffi64,
+0xfff80003ffffffffi64,
+0xfff80007ffffffffi64,
+0xfff8000fffffffffi64,
+0xfff8001fffffffffi64,
+0xfff8003fffffffffi64,
+0xfff8007fffffffffi64,
+0xfff800ffffffffffi64,
+0xfff801ffffffffffi64,
+0xfff803ffffffffffi64,
+0xfff807ffffffffffi64,
+0xfff80fffffffffffi64,
+0xfff81fffffffffffi64,
+0xfff83fffffffffffi64,
+0xfff87fffffffffffi64,
+0xfff8ffffffffffffi64,
+0xfff9ffffffffffffi64,
+0xfffbffffffffffffi64
+},
+{
+0xfff0000000000000i64,
+0xfff0000000000001i64,
+0xfff0000000000003i64,
+0xfff0000000000007i64,
+0xfff000000000000fi64,
+0xfff000000000001fi64,
+0xfff000000000003fi64,
+0xfff000000000007fi64,
+0xfff00000000000ffi64,
+0xfff00000000001ffi64,
+0xfff00000000003ffi64,
+0xfff00000000007ffi64,
+0xfff0000000000fffi64,
+0xfff0000000001fffi64,
+0xfff0000000003fffi64,
+0xfff0000000007fffi64,
+0xfff000000000ffffi64,
+0xfff000000001ffffi64,
+0xfff000000003ffffi64,
+0xfff000000007ffffi64,
+0xfff00000000fffffi64,
+0xfff00000001fffffi64,
+0xfff00000003fffffi64,
+0xfff00000007fffffi64,
+0xfff0000000ffffffi64,
+0xfff0000001ffffffi64,
+0xfff0000003ffffffi64,
+0xfff0000007ffffffi64,
+0xfff000000fffffffi64,
+0xfff000001fffffffi64,
+0xfff000003fffffffi64,
+0xfff000007fffffffi64,
+0xfff00000ffffffffi64,
+0xfff00001ffffffffi64,
+0xfff00003ffffffffi64,
+0xfff00007ffffffffi64,
+0xfff0000fffffffffi64,
+0xfff0001fffffffffi64,
+0xfff0003fffffffffi64,
+0xfff0007fffffffffi64,
+0xfff000ffffffffffi64,
+0xfff001ffffffffffi64,
+0xfff003ffffffffffi64,
+0xfff007ffffffffffi64,
+0xfff00fffffffffffi64,
+0xfff01fffffffffffi64,
+0xfff03fffffffffffi64,
+0xfff07fffffffffffi64,
+0xfff0ffffffffffffi64,
+0xfff1ffffffffffffi64,
+0xfff3ffffffffffffi64,
+0xfff7ffffffffffffi64
+},
+{
+0xffe0000000000000i64,
+0xffe0000000000001i64,
+0xffe0000000000003i64,
+0xffe0000000000007i64,
+0xffe000000000000fi64,
+0xffe000000000001fi64,
+0xffe000000000003fi64,
+0xffe000000000007fi64,
+0xffe00000000000ffi64,
+0xffe00000000001ffi64,
+0xffe00000000003ffi64,
+0xffe00000000007ffi64,
+0xffe0000000000fffi64,
+0xffe0000000001fffi64,
+0xffe0000000003fffi64,
+0xffe0000000007fffi64,
+0xffe000000000ffffi64,
+0xffe000000001ffffi64,
+0xffe000000003ffffi64,
+0xffe000000007ffffi64,
+0xffe00000000fffffi64,
+0xffe00000001fffffi64,
+0xffe00000003fffffi64,
+0xffe00000007fffffi64,
+0xffe0000000ffffffi64,
+0xffe0000001ffffffi64,
+0xffe0000003ffffffi64,
+0xffe0000007ffffffi64,
+0xffe000000fffffffi64,
+0xffe000001fffffffi64,
+0xffe000003fffffffi64,
+0xffe000007fffffffi64,
+0xffe00000ffffffffi64,
+0xffe00001ffffffffi64,
+0xffe00003ffffffffi64,
+0xffe00007ffffffffi64,
+0xffe0000fffffffffi64,
+0xffe0001fffffffffi64,
+0xffe0003fffffffffi64,
+0xffe0007fffffffffi64,
+0xffe000ffffffffffi64,
+0xffe001ffffffffffi64,
+0xffe003ffffffffffi64,
+0xffe007ffffffffffi64,
+0xffe00fffffffffffi64,
+0xffe01fffffffffffi64,
+0xffe03fffffffffffi64,
+0xffe07fffffffffffi64,
+0xffe0ffffffffffffi64,
+0xffe1ffffffffffffi64,
+0xffe3ffffffffffffi64,
+0xffe7ffffffffffffi64,
+0xffefffffffffffffi64
+},
+{
+0xffc0000000000000i64,
+0xffc0000000000001i64,
+0xffc0000000000003i64,
+0xffc0000000000007i64,
+0xffc000000000000fi64,
+0xffc000000000001fi64,
+0xffc000000000003fi64,
+0xffc000000000007fi64,
+0xffc00000000000ffi64,
+0xffc00000000001ffi64,
+0xffc00000000003ffi64,
+0xffc00000000007ffi64,
+0xffc0000000000fffi64,
+0xffc0000000001fffi64,
+0xffc0000000003fffi64,
+0xffc0000000007fffi64,
+0xffc000000000ffffi64,
+0xffc000000001ffffi64,
+0xffc000000003ffffi64,
+0xffc000000007ffffi64,
+0xffc00000000fffffi64,
+0xffc00000001fffffi64,
+0xffc00000003fffffi64,
+0xffc00000007fffffi64,
+0xffc0000000ffffffi64,
+0xffc0000001ffffffi64,
+0xffc0000003ffffffi64,
+0xffc0000007ffffffi64,
+0xffc000000fffffffi64,
+0xffc000001fffffffi64,
+0xffc000003fffffffi64,
+0xffc000007fffffffi64,
+0xffc00000ffffffffi64,
+0xffc00001ffffffffi64,
+0xffc00003ffffffffi64,
+0xffc00007ffffffffi64,
+0xffc0000fffffffffi64,
+0xffc0001fffffffffi64,
+0xffc0003fffffffffi64,
+0xffc0007fffffffffi64,
+0xffc000ffffffffffi64,
+0xffc001ffffffffffi64,
+0xffc003ffffffffffi64,
+0xffc007ffffffffffi64,
+0xffc00fffffffffffi64,
+0xffc01fffffffffffi64,
+0xffc03fffffffffffi64,
+0xffc07fffffffffffi64,
+0xffc0ffffffffffffi64,
+0xffc1ffffffffffffi64,
+0xffc3ffffffffffffi64,
+0xffc7ffffffffffffi64,
+0xffcfffffffffffffi64,
+0xffdfffffffffffffi64
+},
+{
+0xff80000000000000i64,
+0xff80000000000001i64,
+0xff80000000000003i64,
+0xff80000000000007i64,
+0xff8000000000000fi64,
+0xff8000000000001fi64,
+0xff8000000000003fi64,
+0xff8000000000007fi64,
+0xff800000000000ffi64,
+0xff800000000001ffi64,
+0xff800000000003ffi64,
+0xff800000000007ffi64,
+0xff80000000000fffi64,
+0xff80000000001fffi64,
+0xff80000000003fffi64,
+0xff80000000007fffi64,
+0xff8000000000ffffi64,
+0xff8000000001ffffi64,
+0xff8000000003ffffi64,
+0xff8000000007ffffi64,
+0xff800000000fffffi64,
+0xff800000001fffffi64,
+0xff800000003fffffi64,
+0xff800000007fffffi64,
+0xff80000000ffffffi64,
+0xff80000001ffffffi64,
+0xff80000003ffffffi64,
+0xff80000007ffffffi64,
+0xff8000000fffffffi64,
+0xff8000001fffffffi64,
+0xff8000003fffffffi64,
+0xff8000007fffffffi64,
+0xff800000ffffffffi64,
+0xff800001ffffffffi64,
+0xff800003ffffffffi64,
+0xff800007ffffffffi64,
+0xff80000fffffffffi64,
+0xff80001fffffffffi64,
+0xff80003fffffffffi64,
+0xff80007fffffffffi64,
+0xff8000ffffffffffi64,
+0xff8001ffffffffffi64,
+0xff8003ffffffffffi64,
+0xff8007ffffffffffi64,
+0xff800fffffffffffi64,
+0xff801fffffffffffi64,
+0xff803fffffffffffi64,
+0xff807fffffffffffi64,
+0xff80ffffffffffffi64,
+0xff81ffffffffffffi64,
+0xff83ffffffffffffi64,
+0xff87ffffffffffffi64,
+0xff8fffffffffffffi64,
+0xff9fffffffffffffi64,
+0xffbfffffffffffffi64
+},
+{
+0xff00000000000000i64,
+0xff00000000000001i64,
+0xff00000000000003i64,
+0xff00000000000007i64,
+0xff0000000000000fi64,
+0xff0000000000001fi64,
+0xff0000000000003fi64,
+0xff0000000000007fi64,
+0xff000000000000ffi64,
+0xff000000000001ffi64,
+0xff000000000003ffi64,
+0xff000000000007ffi64,
+0xff00000000000fffi64,
+0xff00000000001fffi64,
+0xff00000000003fffi64,
+0xff00000000007fffi64,
+0xff0000000000ffffi64,
+0xff0000000001ffffi64,
+0xff0000000003ffffi64,
+0xff0000000007ffffi64,
+0xff000000000fffffi64,
+0xff000000001fffffi64,
+0xff000000003fffffi64,
+0xff000000007fffffi64,
+0xff00000000ffffffi64,
+0xff00000001ffffffi64,
+0xff00000003ffffffi64,
+0xff00000007ffffffi64,
+0xff0000000fffffffi64,
+0xff0000001fffffffi64,
+0xff0000003fffffffi64,
+0xff0000007fffffffi64,
+0xff000000ffffffffi64,
+0xff000001ffffffffi64,
+0xff000003ffffffffi64,
+0xff000007ffffffffi64,
+0xff00000fffffffffi64,
+0xff00001fffffffffi64,
+0xff00003fffffffffi64,
+0xff00007fffffffffi64,
+0xff0000ffffffffffi64,
+0xff0001ffffffffffi64,
+0xff0003ffffffffffi64,
+0xff0007ffffffffffi64,
+0xff000fffffffffffi64,
+0xff001fffffffffffi64,
+0xff003fffffffffffi64,
+0xff007fffffffffffi64,
+0xff00ffffffffffffi64,
+0xff01ffffffffffffi64,
+0xff03ffffffffffffi64,
+0xff07ffffffffffffi64,
+0xff0fffffffffffffi64,
+0xff1fffffffffffffi64,
+0xff3fffffffffffffi64,
+0xff7fffffffffffffi64
+},
+{
+0xfe00000000000000i64,
+0xfe00000000000001i64,
+0xfe00000000000003i64,
+0xfe00000000000007i64,
+0xfe0000000000000fi64,
+0xfe0000000000001fi64,
+0xfe0000000000003fi64,
+0xfe0000000000007fi64,
+0xfe000000000000ffi64,
+0xfe000000000001ffi64,
+0xfe000000000003ffi64,
+0xfe000000000007ffi64,
+0xfe00000000000fffi64,
+0xfe00000000001fffi64,
+0xfe00000000003fffi64,
+0xfe00000000007fffi64,
+0xfe0000000000ffffi64,
+0xfe0000000001ffffi64,
+0xfe0000000003ffffi64,
+0xfe0000000007ffffi64,
+0xfe000000000fffffi64,
+0xfe000000001fffffi64,
+0xfe000000003fffffi64,
+0xfe000000007fffffi64,
+0xfe00000000ffffffi64,
+0xfe00000001ffffffi64,
+0xfe00000003ffffffi64,
+0xfe00000007ffffffi64,
+0xfe0000000fffffffi64,
+0xfe0000001fffffffi64,
+0xfe0000003fffffffi64,
+0xfe0000007fffffffi64,
+0xfe000000ffffffffi64,
+0xfe000001ffffffffi64,
+0xfe000003ffffffffi64,
+0xfe000007ffffffffi64,
+0xfe00000fffffffffi64,
+0xfe00001fffffffffi64,
+0xfe00003fffffffffi64,
+0xfe00007fffffffffi64,
+0xfe0000ffffffffffi64,
+0xfe0001ffffffffffi64,
+0xfe0003ffffffffffi64,
+0xfe0007ffffffffffi64,
+0xfe000fffffffffffi64,
+0xfe001fffffffffffi64,
+0xfe003fffffffffffi64,
+0xfe007fffffffffffi64,
+0xfe00ffffffffffffi64,
+0xfe01ffffffffffffi64,
+0xfe03ffffffffffffi64,
+0xfe07ffffffffffffi64,
+0xfe0fffffffffffffi64,
+0xfe1fffffffffffffi64,
+0xfe3fffffffffffffi64,
+0xfe7fffffffffffffi64,
+0xfeffffffffffffffi64
+},
+{
+0xfc00000000000000i64,
+0xfc00000000000001i64,
+0xfc00000000000003i64,
+0xfc00000000000007i64,
+0xfc0000000000000fi64,
+0xfc0000000000001fi64,
+0xfc0000000000003fi64,
+0xfc0000000000007fi64,
+0xfc000000000000ffi64,
+0xfc000000000001ffi64,
+0xfc000000000003ffi64,
+0xfc000000000007ffi64,
+0xfc00000000000fffi64,
+0xfc00000000001fffi64,
+0xfc00000000003fffi64,
+0xfc00000000007fffi64,
+0xfc0000000000ffffi64,
+0xfc0000000001ffffi64,
+0xfc0000000003ffffi64,
+0xfc0000000007ffffi64,
+0xfc000000000fffffi64,
+0xfc000000001fffffi64,
+0xfc000000003fffffi64,
+0xfc000000007fffffi64,
+0xfc00000000ffffffi64,
+0xfc00000001ffffffi64,
+0xfc00000003ffffffi64,
+0xfc00000007ffffffi64,
+0xfc0000000fffffffi64,
+0xfc0000001fffffffi64,
+0xfc0000003fffffffi64,
+0xfc0000007fffffffi64,
+0xfc000000ffffffffi64,
+0xfc000001ffffffffi64,
+0xfc000003ffffffffi64,
+0xfc000007ffffffffi64,
+0xfc00000fffffffffi64,
+0xfc00001fffffffffi64,
+0xfc00003fffffffffi64,
+0xfc00007fffffffffi64,
+0xfc0000ffffffffffi64,
+0xfc0001ffffffffffi64,
+0xfc0003ffffffffffi64,
+0xfc0007ffffffffffi64,
+0xfc000fffffffffffi64,
+0xfc001fffffffffffi64,
+0xfc003fffffffffffi64,
+0xfc007fffffffffffi64,
+0xfc00ffffffffffffi64,
+0xfc01ffffffffffffi64,
+0xfc03ffffffffffffi64,
+0xfc07ffffffffffffi64,
+0xfc0fffffffffffffi64,
+0xfc1fffffffffffffi64,
+0xfc3fffffffffffffi64,
+0xfc7fffffffffffffi64,
+0xfcffffffffffffffi64,
+0xfdffffffffffffffi64
+},
+{
+0xf800000000000000i64,
+0xf800000000000001i64,
+0xf800000000000003i64,
+0xf800000000000007i64,
+0xf80000000000000fi64,
+0xf80000000000001fi64,
+0xf80000000000003fi64,
+0xf80000000000007fi64,
+0xf8000000000000ffi64,
+0xf8000000000001ffi64,
+0xf8000000000003ffi64,
+0xf8000000000007ffi64,
+0xf800000000000fffi64,
+0xf800000000001fffi64,
+0xf800000000003fffi64,
+0xf800000000007fffi64,
+0xf80000000000ffffi64,
+0xf80000000001ffffi64,
+0xf80000000003ffffi64,
+0xf80000000007ffffi64,
+0xf8000000000fffffi64,
+0xf8000000001fffffi64,
+0xf8000000003fffffi64,
+0xf8000000007fffffi64,
+0xf800000000ffffffi64,
+0xf800000001ffffffi64,
+0xf800000003ffffffi64,
+0xf800000007ffffffi64,
+0xf80000000fffffffi64,
+0xf80000001fffffffi64,
+0xf80000003fffffffi64,
+0xf80000007fffffffi64,
+0xf8000000ffffffffi64,
+0xf8000001ffffffffi64,
+0xf8000003ffffffffi64,
+0xf8000007ffffffffi64,
+0xf800000fffffffffi64,
+0xf800001fffffffffi64,
+0xf800003fffffffffi64,
+0xf800007fffffffffi64,
+0xf80000ffffffffffi64,
+0xf80001ffffffffffi64,
+0xf80003ffffffffffi64,
+0xf80007ffffffffffi64,
+0xf8000fffffffffffi64,
+0xf8001fffffffffffi64,
+0xf8003fffffffffffi64,
+0xf8007fffffffffffi64,
+0xf800ffffffffffffi64,
+0xf801ffffffffffffi64,
+0xf803ffffffffffffi64,
+0xf807ffffffffffffi64,
+0xf80fffffffffffffi64,
+0xf81fffffffffffffi64,
+0xf83fffffffffffffi64,
+0xf87fffffffffffffi64,
+0xf8ffffffffffffffi64,
+0xf9ffffffffffffffi64,
+0xfbffffffffffffffi64
+},
+{
+0xf000000000000000i64,
+0xf000000000000001i64,
+0xf000000000000003i64,
+0xf000000000000007i64,
+0xf00000000000000fi64,
+0xf00000000000001fi64,
+0xf00000000000003fi64,
+0xf00000000000007fi64,
+0xf0000000000000ffi64,
+0xf0000000000001ffi64,
+0xf0000000000003ffi64,
+0xf0000000000007ffi64,
+0xf000000000000fffi64,
+0xf000000000001fffi64,
+0xf000000000003fffi64,
+0xf000000000007fffi64,
+0xf00000000000ffffi64,
+0xf00000000001ffffi64,
+0xf00000000003ffffi64,
+0xf00000000007ffffi64,
+0xf0000000000fffffi64,
+0xf0000000001fffffi64,
+0xf0000000003fffffi64,
+0xf0000000007fffffi64,
+0xf000000000ffffffi64,
+0xf000000001ffffffi64,
+0xf000000003ffffffi64,
+0xf000000007ffffffi64,
+0xf00000000fffffffi64,
+0xf00000001fffffffi64,
+0xf00000003fffffffi64,
+0xf00000007fffffffi64,
+0xf0000000ffffffffi64,
+0xf0000001ffffffffi64,
+0xf0000003ffffffffi64,
+0xf0000007ffffffffi64,
+0xf000000fffffffffi64,
+0xf000001fffffffffi64,
+0xf000003fffffffffi64,
+0xf000007fffffffffi64,
+0xf00000ffffffffffi64,
+0xf00001ffffffffffi64,
+0xf00003ffffffffffi64,
+0xf00007ffffffffffi64,
+0xf0000fffffffffffi64,
+0xf0001fffffffffffi64,
+0xf0003fffffffffffi64,
+0xf0007fffffffffffi64,
+0xf000ffffffffffffi64,
+0xf001ffffffffffffi64,
+0xf003ffffffffffffi64,
+0xf007ffffffffffffi64,
+0xf00fffffffffffffi64,
+0xf01fffffffffffffi64,
+0xf03fffffffffffffi64,
+0xf07fffffffffffffi64,
+0xf0ffffffffffffffi64,
+0xf1ffffffffffffffi64,
+0xf3ffffffffffffffi64,
+0xf7ffffffffffffffi64
+},
+{
+0xe000000000000000i64,
+0xe000000000000001i64,
+0xe000000000000003i64,
+0xe000000000000007i64,
+0xe00000000000000fi64,
+0xe00000000000001fi64,
+0xe00000000000003fi64,
+0xe00000000000007fi64,
+0xe0000000000000ffi64,
+0xe0000000000001ffi64,
+0xe0000000000003ffi64,
+0xe0000000000007ffi64,
+0xe000000000000fffi64,
+0xe000000000001fffi64,
+0xe000000000003fffi64,
+0xe000000000007fffi64,
+0xe00000000000ffffi64,
+0xe00000000001ffffi64,
+0xe00000000003ffffi64,
+0xe00000000007ffffi64,
+0xe0000000000fffffi64,
+0xe0000000001fffffi64,
+0xe0000000003fffffi64,
+0xe0000000007fffffi64,
+0xe000000000ffffffi64,
+0xe000000001ffffffi64,
+0xe000000003ffffffi64,
+0xe000000007ffffffi64,
+0xe00000000fffffffi64,
+0xe00000001fffffffi64,
+0xe00000003fffffffi64,
+0xe00000007fffffffi64,
+0xe0000000ffffffffi64,
+0xe0000001ffffffffi64,
+0xe0000003ffffffffi64,
+0xe0000007ffffffffi64,
+0xe000000fffffffffi64,
+0xe000001fffffffffi64,
+0xe000003fffffffffi64,
+0xe000007fffffffffi64,
+0xe00000ffffffffffi64,
+0xe00001ffffffffffi64,
+0xe00003ffffffffffi64,
+0xe00007ffffffffffi64,
+0xe0000fffffffffffi64,
+0xe0001fffffffffffi64,
+0xe0003fffffffffffi64,
+0xe0007fffffffffffi64,
+0xe000ffffffffffffi64,
+0xe001ffffffffffffi64,
+0xe003ffffffffffffi64,
+0xe007ffffffffffffi64,
+0xe00fffffffffffffi64,
+0xe01fffffffffffffi64,
+0xe03fffffffffffffi64,
+0xe07fffffffffffffi64,
+0xe0ffffffffffffffi64,
+0xe1ffffffffffffffi64,
+0xe3ffffffffffffffi64,
+0xe7ffffffffffffffi64,
+0xefffffffffffffffi64
+},
+{
+0xc000000000000000i64,
+0xc000000000000001i64,
+0xc000000000000003i64,
+0xc000000000000007i64,
+0xc00000000000000fi64,
+0xc00000000000001fi64,
+0xc00000000000003fi64,
+0xc00000000000007fi64,
+0xc0000000000000ffi64,
+0xc0000000000001ffi64,
+0xc0000000000003ffi64,
+0xc0000000000007ffi64,
+0xc000000000000fffi64,
+0xc000000000001fffi64,
+0xc000000000003fffi64,
+0xc000000000007fffi64,
+0xc00000000000ffffi64,
+0xc00000000001ffffi64,
+0xc00000000003ffffi64,
+0xc00000000007ffffi64,
+0xc0000000000fffffi64,
+0xc0000000001fffffi64,
+0xc0000000003fffffi64,
+0xc0000000007fffffi64,
+0xc000000000ffffffi64,
+0xc000000001ffffffi64,
+0xc000000003ffffffi64,
+0xc000000007ffffffi64,
+0xc00000000fffffffi64,
+0xc00000001fffffffi64,
+0xc00000003fffffffi64,
+0xc00000007fffffffi64,
+0xc0000000ffffffffi64,
+0xc0000001ffffffffi64,
+0xc0000003ffffffffi64,
+0xc0000007ffffffffi64,
+0xc000000fffffffffi64,
+0xc000001fffffffffi64,
+0xc000003fffffffffi64,
+0xc000007fffffffffi64,
+0xc00000ffffffffffi64,
+0xc00001ffffffffffi64,
+0xc00003ffffffffffi64,
+0xc00007ffffffffffi64,
+0xc0000fffffffffffi64,
+0xc0001fffffffffffi64,
+0xc0003fffffffffffi64,
+0xc0007fffffffffffi64,
+0xc000ffffffffffffi64,
+0xc001ffffffffffffi64,
+0xc003ffffffffffffi64,
+0xc007ffffffffffffi64,
+0xc00fffffffffffffi64,
+0xc01fffffffffffffi64,
+0xc03fffffffffffffi64,
+0xc07fffffffffffffi64,
+0xc0ffffffffffffffi64,
+0xc1ffffffffffffffi64,
+0xc3ffffffffffffffi64,
+0xc7ffffffffffffffi64,
+0xcfffffffffffffffi64,
+0xdfffffffffffffffi64
+},
+{
+0x8000000000000000i64,
+0x8000000000000001i64,
+0x8000000000000003i64,
+0x8000000000000007i64,
+0x800000000000000fi64,
+0x800000000000001fi64,
+0x800000000000003fi64,
+0x800000000000007fi64,
+0x80000000000000ffi64,
+0x80000000000001ffi64,
+0x80000000000003ffi64,
+0x80000000000007ffi64,
+0x8000000000000fffi64,
+0x8000000000001fffi64,
+0x8000000000003fffi64,
+0x8000000000007fffi64,
+0x800000000000ffffi64,
+0x800000000001ffffi64,
+0x800000000003ffffi64,
+0x800000000007ffffi64,
+0x80000000000fffffi64,
+0x80000000001fffffi64,
+0x80000000003fffffi64,
+0x80000000007fffffi64,
+0x8000000000ffffffi64,
+0x8000000001ffffffi64,
+0x8000000003ffffffi64,
+0x8000000007ffffffi64,
+0x800000000fffffffi64,
+0x800000001fffffffi64,
+0x800000003fffffffi64,
+0x800000007fffffffi64,
+0x80000000ffffffffi64,
+0x80000001ffffffffi64,
+0x80000003ffffffffi64,
+0x80000007ffffffffi64,
+0x8000000fffffffffi64,
+0x8000001fffffffffi64,
+0x8000003fffffffffi64,
+0x8000007fffffffffi64,
+0x800000ffffffffffi64,
+0x800001ffffffffffi64,
+0x800003ffffffffffi64,
+0x800007ffffffffffi64,
+0x80000fffffffffffi64,
+0x80001fffffffffffi64,
+0x80003fffffffffffi64,
+0x80007fffffffffffi64,
+0x8000ffffffffffffi64,
+0x8001ffffffffffffi64,
+0x8003ffffffffffffi64,
+0x8007ffffffffffffi64,
+0x800fffffffffffffi64,
+0x801fffffffffffffi64,
+0x803fffffffffffffi64,
+0x807fffffffffffffi64,
+0x80ffffffffffffffi64,
+0x81ffffffffffffffi64,
+0x83ffffffffffffffi64,
+0x87ffffffffffffffi64,
+0x8fffffffffffffffi64,
+0x9fffffffffffffffi64,
+0xbfffffffffffffffi64
+},
+{
+0x0i64,
+0x1i64,
+0x3i64,
+0x7i64,
+0xfi64,
+0x1fi64,
+0x3fi64,
+0x7fi64,
+0xffi64,
+0x1ffi64,
+0x3ffi64,
+0x7ffi64,
+0xfffi64,
+0x1fffi64,
+0x3fffi64,
+0x7fffi64,
+0xffffi64,
+0x1ffffi64,
+0x3ffffi64,
+0x7ffffi64,
+0xfffffi64,
+0x1fffffi64,
+0x3fffffi64,
+0x7fffffi64,
+0xffffffi64,
+0x1ffffffi64,
+0x3ffffffi64,
+0x7ffffffi64,
+0xfffffffi64,
+0x1fffffffi64,
+0x3fffffffi64,
+0x7fffffffi64,
+0xffffffffi64,
+0x1ffffffffi64,
+0x3ffffffffi64,
+0x7ffffffffi64,
+0xfffffffffi64,
+0x1fffffffffi64,
+0x3fffffffffi64,
+0x7fffffffffi64,
+0xffffffffffi64,
+0x1ffffffffffi64,
+0x3ffffffffffi64,
+0x7ffffffffffi64,
+0xfffffffffffi64,
+0x1fffffffffffi64,
+0x3fffffffffffi64,
+0x7fffffffffffi64,
+0xffffffffffffi64,
+0x1ffffffffffffi64,
+0x3ffffffffffffi64,
+0x7ffffffffffffi64,
+0xfffffffffffffi64,
+0x1fffffffffffffi64,
+0x3fffffffffffffi64,
+0x7fffffffffffffi64,
+0xffffffffffffffi64,
+0x1ffffffffffffffi64,
+0x3ffffffffffffffi64,
+0x7ffffffffffffffi64,
+0xfffffffffffffffi64,
+0x1fffffffffffffffi64,
+0x3fffffffffffffffi64,
+0x7fffffffffffffffi64
+}
+};
+
+#endif // end of #ifndef WIN32
+
+} // namespace sc_dt
+
+#endif
diff --git a/ext/systemc/src/sysc/datatypes/int/sc_int_base.cpp b/ext/systemc/src/sysc/datatypes/int/sc_int_base.cpp
new file mode 100644
index 000000000..fb28d44a2
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/int/sc_int_base.cpp
@@ -0,0 +1,749 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_int_base.cpp -- contains interface definitions between sc_int and
+ sc_signed, sc_unsigned, and definitions for sc_int_subref.
+
+ Original Author: Ali Dasdan, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// $Log: sc_int_base.cpp,v $
+// Revision 1.5 2011/02/18 20:19:14 acg
+// Andy Goodrich: updating Copyright notice.
+//
+// Revision 1.4 2010/02/04 22:23:29 acg
+// Andy Goodrich: fixed bug in concatenation reads for part selections,
+// the mask being used was 32 bits and should have been 64 bits.
+//
+// Revision 1.3 2008/06/19 17:47:56 acg
+// Andy Goodrich: fixes for bugs. See 2.2.1 RELEASENOTES.
+//
+// Revision 1.2 2007/11/04 21:27:00 acg
+// Andy Goodrich: changes to make sure the proper value is returned from
+// concat_get_data().
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:49:31 acg
+// Added $Log command so that CVS check in comments are reproduced in the
+// source.
+//
+
+#include "sysc/kernel/sc_macros.h"
+#include "sysc/datatypes/int/sc_signed.h"
+#include "sysc/datatypes/int/sc_unsigned.h"
+#include "sysc/datatypes/int/sc_int_base.h"
+#include "sysc/datatypes/int/sc_uint_base.h"
+#include "sysc/datatypes/int/sc_signed.h"
+#include "sysc/datatypes/int/sc_int_ids.h"
+#include "sysc/datatypes/bit/sc_bv_base.h"
+#include "sysc/datatypes/bit/sc_lv_base.h"
+#include "sysc/datatypes/misc/sc_concatref.h"
+#include "sysc/datatypes/fx/sc_fix.h"
+#include "sysc/datatypes/fx/scfx_other_defs.h"
+
+
+namespace sc_dt
+{
+
+// to avoid code bloat in sc_int_concref<T1,T2>
+
+void
+sc_int_concref_invalid_length( int length )
+{
+ char msg[BUFSIZ];
+ std::sprintf( msg,
+ "sc_int_concref<T1,T2> initialization: length = %d "
+ "violates 1 <= length <= %d",
+ length, SC_INTWIDTH );
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_int_bitref
+//
+// Proxy class for sc_int bit selection (r-value and l-value).
+// ----------------------------------------------------------------------------
+
+sc_core::sc_vpool<sc_int_bitref> sc_int_bitref::m_pool(9);
+
+// concatenation methods:
+
+// #### OPTIMIZE
+void sc_int_bitref::concat_set(int64 src, int low_i)
+{
+ sc_int_base aa( 1 );
+ *this = aa = (low_i < 64) ? src >> low_i : src >> 63;
+}
+
+void sc_int_bitref::concat_set(const sc_signed& src, int low_i)
+{
+ sc_int_base aa( 1 );
+ if ( low_i < src.length() )
+ *this = aa = 1 & (src >> low_i);
+ else
+ *this = aa = (src < 0) ? (int_type)-1 : 0;
+}
+
+void sc_int_bitref::concat_set(const sc_unsigned& src, int low_i)
+{
+ sc_int_base aa( 1 );
+ if ( low_i < src.length() )
+ *this = aa = 1 & (src >> low_i);
+ else
+ *this = aa = 0;
+}
+
+void sc_int_bitref::concat_set(uint64 src, int low_i)
+{
+ sc_int_base aa( 1 );
+ *this = aa = (low_i < 64) ? src >> low_i : 0;
+}
+
+
+// other methods
+
+void
+sc_int_bitref::scan( ::std::istream& is )
+{
+ bool b;
+ is >> b;
+ *this = b;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_int_subref_r
+//
+// Proxy class for sc_int part selection (l-value).
+// ----------------------------------------------------------------------------
+
+bool sc_int_subref_r::concat_get_ctrl( sc_digit* dst_p, int low_i ) const
+{
+ int dst_i; // Word in dst_p now processing.
+ int end_i; // Highest order word in dst_p to process.
+ int high_i; // Index of high order bit in dst_p to set.
+ uint_type mask; // Mask for bits to extract or keep.
+
+ dst_i = low_i / BITS_PER_DIGIT;
+ high_i = low_i + (m_left-m_right);
+ end_i = high_i / BITS_PER_DIGIT;
+ mask = ~mask_int[m_left][m_right];
+
+
+ // PROCESS THE FIRST WORD:
+
+ dst_p[dst_i] = (sc_digit)(dst_p[dst_i] & mask);
+ switch ( end_i - dst_i )
+ {
+ // BITS ARE ACROSS TWO WORDS:
+
+ case 1:
+ dst_i++;
+ dst_p[dst_i] = 0;
+ break;
+
+ // BITS ARE ACROSS THREE WORDS:
+
+ case 2:
+ dst_i++;
+ dst_p[dst_i++] = 0;
+ dst_p[dst_i] = 0;
+ break;
+
+ // BITS ARE ACROSS FOUR WORDS:
+
+ case 3:
+ dst_i++;
+ dst_p[dst_i++] = 0;
+ dst_p[dst_i++] = 0;
+ dst_p[dst_i] = 0;
+ break;
+ }
+ return false;
+}
+
+
+bool sc_int_subref_r::concat_get_data( sc_digit* dst_p, int low_i ) const
+{
+ int dst_i; // Word in dst_p now processing.
+ int end_i; // Highest order word in dst_p to process.
+ int high_i; // Index of high order bit in dst_p to set.
+ int left_shift; // Left shift for val.
+ uint_type mask; // Mask for bits to extract or keep.
+ bool non_zero; // True if value inserted is non-zero.
+ uint_type val; // Selection value extracted from m_obj_p.
+
+ dst_i = low_i / BITS_PER_DIGIT;
+ left_shift = low_i % BITS_PER_DIGIT;
+ high_i = low_i + (m_left-m_right);
+ end_i = high_i / BITS_PER_DIGIT;
+ mask = ~mask_int[m_left][m_right];
+ val = (m_obj_p->m_val & mask) >> m_right;
+ non_zero = val != 0;
+
+
+ // PROCESS THE FIRST WORD:
+
+ mask = ~(-1 << left_shift);
+ dst_p[dst_i] = (sc_digit)((dst_p[dst_i] & mask) |
+ ((val << left_shift) & DIGIT_MASK));
+
+ switch ( end_i - dst_i )
+ {
+ // BITS ARE ACROSS TWO WORDS:
+
+ case 1:
+ dst_i++;
+ val >>= (BITS_PER_DIGIT-left_shift);
+ dst_p[dst_i] = (sc_digit)(val & DIGIT_MASK);
+ break;
+
+ // BITS ARE ACROSS THREE WORDS:
+
+ case 2:
+ dst_i++;
+ val >>= (BITS_PER_DIGIT-left_shift);
+ dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
+ val >>= BITS_PER_DIGIT;
+ dst_p[dst_i] = (sc_digit)val;
+ break;
+
+ // BITS ARE ACROSS FOUR WORDS:
+
+ case 3:
+ dst_i++;
+ val >>= (BITS_PER_DIGIT-left_shift);
+ dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
+ val >>= BITS_PER_DIGIT;
+ dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
+ val >>= BITS_PER_DIGIT;
+ dst_p[dst_i] = (sc_digit)val;
+ break;
+ }
+ return non_zero;
+}
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_int_subref
+//
+// Proxy class for sc_int part selection (r-value and l-value).
+// ----------------------------------------------------------------------------
+
+sc_core::sc_vpool<sc_int_subref> sc_int_subref::m_pool(9);
+
+// assignment operators
+
+sc_int_subref&
+sc_int_subref::operator = ( int_type v )
+{
+ int_type val = m_obj_p->m_val;
+ uint_type mask = mask_int[m_left][m_right];
+ val &= mask;
+ val |= (v << m_right) & ~mask;
+ m_obj_p->m_val = val;
+ m_obj_p->extend_sign();
+ return *this;
+}
+
+sc_int_subref&
+sc_int_subref::operator = ( const sc_signed& a )
+{
+ sc_int_base aa( length() );
+ return ( *this = aa = a );
+}
+
+sc_int_subref&
+sc_int_subref::operator = ( const sc_unsigned& a )
+{
+ sc_int_base aa( length() );
+ return ( *this = aa = a );
+}
+
+sc_int_subref&
+sc_int_subref::operator = ( const sc_bv_base& a )
+{
+ sc_int_base aa( length() );
+ return ( *this = aa = a );
+}
+
+sc_int_subref&
+sc_int_subref::operator = ( const sc_lv_base& a )
+{
+ sc_int_base aa( length() );
+ return ( *this = aa = a );
+}
+
+
+// concatenation methods:
+
+// #### OPTIMIZE
+void sc_int_subref::concat_set(int64 src, int low_i)
+{
+ sc_int_base aa ( length() );
+ *this = aa = (low_i < 64) ? src >> low_i : src >> 63;
+}
+
+void sc_int_subref::concat_set(const sc_signed& src, int low_i)
+{
+ sc_int_base aa( length() );
+ if ( low_i < src.length() )
+ *this = aa = src >> low_i;
+ else
+ *this = (src < 0) ? (int_type)-1 : 0;
+}
+
+void sc_int_subref::concat_set(const sc_unsigned& src, int low_i)
+{
+ sc_int_base aa( length() );
+ if ( low_i < src.length() )
+ *this = aa = src >> low_i;
+ else
+ *this = 0;
+}
+
+void sc_int_subref::concat_set(uint64 src, int low_i)
+{
+ sc_int_base aa ( length() );
+ *this = aa = (low_i < 64) ? src >> low_i : 0;
+}
+
+
+// other methods
+
+void
+sc_int_subref::scan( ::std::istream& is )
+{
+ std::string s;
+ is >> s;
+ *this = s.c_str();
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_int_base
+//
+// Base class for sc_int.
+// ----------------------------------------------------------------------------
+
+// support methods
+
+void
+sc_int_base::invalid_length() const
+{
+ char msg[BUFSIZ];
+ std::sprintf( msg,
+ "sc_int[_base] initialization: length = %d violates "
+ "1 <= length <= %d",
+ m_len, SC_INTWIDTH );
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
+}
+
+void
+sc_int_base::invalid_index( int i ) const
+{
+ char msg[BUFSIZ];
+ std::sprintf( msg,
+ "sc_int[_base] bit selection: index = %d violates "
+ "0 <= index <= %d",
+ i, m_len - 1 );
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
+}
+
+void
+sc_int_base::invalid_range( int l, int r ) const
+{
+ char msg[BUFSIZ];
+ std::sprintf( msg,
+ "sc_int[_base] part selection: left = %d, right = %d violates "
+ "%d >= left >= right >= 0",
+ l, r, m_len - 1 );
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
+}
+
+
+void
+sc_int_base::check_value() const
+{
+ int_type limit = (int_type) 1 << ( m_len - 1 );
+ if( m_val < -limit || m_val >= limit ) {
+ char msg[BUFSIZ];
+ std::sprintf( msg, "sc_int[_base]: value does not fit into a length of %d",
+ m_len );
+ SC_REPORT_WARNING( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
+ }
+}
+
+
+// constructors
+sc_int_base::sc_int_base( const sc_bv_base& v )
+ : m_val(0), m_len( v.length() ), m_ulen( SC_INTWIDTH - m_len )
+{
+ check_length();
+ *this = v;
+}
+sc_int_base::sc_int_base( const sc_lv_base& v )
+ : m_val(0), m_len( v.length() ), m_ulen( SC_INTWIDTH - m_len )
+{
+ check_length();
+ *this = v;
+}
+sc_int_base::sc_int_base( const sc_uint_subref_r& v )
+ : m_val(0), m_len( v.length() ), m_ulen( SC_INTWIDTH - m_len )
+{
+ check_length();
+ *this = v.to_uint64();
+}
+sc_int_base::sc_int_base( const sc_signed_subref_r& v )
+ : m_val(0), m_len( v.length() ), m_ulen( SC_INTWIDTH - m_len )
+{
+ check_length();
+ *this = v.to_uint64();
+}
+sc_int_base::sc_int_base( const sc_unsigned_subref_r& v )
+ : m_val(0), m_len( v.length() ), m_ulen( SC_INTWIDTH - m_len )
+{
+ check_length();
+ *this = v.to_uint64();
+}
+
+sc_int_base::sc_int_base( const sc_signed& a )
+ : m_val( 0 ), m_len( a.length() ), m_ulen( SC_INTWIDTH - m_len )
+{
+ check_length();
+#if 0
+ for( int i = m_len - 1; i >= 0; -- i ) {
+ set( i, a.test( i ) );
+ }
+ extend_sign();
+#else
+ *this = a.to_int64();
+#endif
+}
+
+sc_int_base::sc_int_base( const sc_unsigned& a )
+ : m_val( 0 ), m_len( a.length() ), m_ulen( SC_INTWIDTH - m_len )
+{
+ check_length();
+#if 0
+ for( int i = m_len - 1; i >= 0; -- i ) {
+ set( i, a.test( i ) );
+ }
+ extend_sign();
+#else
+ *this = a.to_int64();
+#endif
+}
+
+
+// assignment operators
+
+sc_int_base&
+sc_int_base::operator = ( const sc_signed& a )
+{
+ int minlen = sc_min( m_len, a.length() );
+ int i = 0;
+ for( ; i < minlen; ++ i ) {
+ set( i, a.test( i ) );
+ }
+ bool sgn = a.sign();
+ for( ; i < m_len; ++ i ) {
+ // sign extension
+ set( i, sgn );
+ }
+ extend_sign();
+ return *this;
+}
+
+sc_int_base&
+sc_int_base::operator = ( const sc_unsigned& a )
+{
+ int minlen = sc_min( m_len, a.length() );
+ int i = 0;
+ for( ; i < minlen; ++ i ) {
+ set( i, a.test( i ) );
+ }
+ for( ; i < m_len; ++ i ) {
+ // zero extension
+ set( i, 0 );
+ }
+ extend_sign();
+ return *this;
+}
+
+
+sc_int_base&
+sc_int_base::operator = ( const sc_bv_base& a )
+{
+ int minlen = sc_min( m_len, a.length() );
+ int i = 0;
+ for( ; i < minlen; ++ i ) {
+ set( i, a.get_bit( i ) );
+ }
+ for( ; i < m_len; ++ i ) {
+ // zero extension
+ set( i, 0 );
+ }
+ extend_sign();
+ return *this;
+}
+
+sc_int_base&
+sc_int_base::operator = ( const sc_lv_base& a )
+{
+ int minlen = sc_min( m_len, a.length() );
+ int i = 0;
+ for( ; i < minlen; ++ i ) {
+ set( i, sc_logic( a.get_bit( i ) ).to_bool() );
+ }
+ for( ; i < m_len; ++ i ) {
+ // zero extension
+ set( i, 0 );
+ }
+ extend_sign();
+ return *this;
+}
+
+sc_int_base&
+sc_int_base::operator = ( const char* a )
+{
+ if( a == 0 ) {
+ SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_,
+ "character string is zero" );
+ }
+ if( *a == 0 ) {
+ SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_,
+ "character string is empty" );
+ }
+ try {
+ int len = m_len;
+ sc_fix aa( a, len, len, SC_TRN, SC_WRAP, 0, SC_ON );
+ return this->operator = ( aa );
+ } catch( sc_core::sc_report ) {
+ char msg[BUFSIZ];
+ std::sprintf( msg, "character string '%s' is not valid", a );
+ SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
+ // never reached
+ return *this;
+ }
+}
+
+// explicit conversion to character string
+
+const std::string
+sc_int_base::to_string( sc_numrep numrep ) const
+{
+ int len = m_len;
+ sc_fix aa( *this, len, len, SC_TRN, SC_WRAP, 0, SC_ON );
+ return aa.to_string( numrep );
+}
+
+const std::string
+sc_int_base::to_string( sc_numrep numrep, bool w_prefix ) const
+{
+ int len = m_len;
+ sc_fix aa( *this, len, len, SC_TRN, SC_WRAP, 0, SC_ON );
+ return aa.to_string( numrep, w_prefix );
+}
+
+
+// reduce methods
+
+bool
+sc_int_base::and_reduce() const
+{
+ return ( m_val == int_type( -1 ) );
+}
+
+bool
+sc_int_base::or_reduce() const
+{
+ return ( m_val != int_type( 0 ) );
+}
+
+bool
+sc_int_base::xor_reduce() const
+{
+ uint_type mask = ~UINT_ZERO;
+ uint_type val = m_val & (mask >> m_ulen);
+ int n = SC_INTWIDTH;
+ do {
+ n >>= 1;
+ mask >>= n;
+ val = ((val & (mask << n)) >> n) ^ (val & mask);
+ } while( n != 1 );
+ return ( val != uint_type( 0 ) );
+}
+
+
+bool sc_int_base::concat_get_ctrl( sc_digit* dst_p, int low_i ) const
+{
+ int dst_i; // Word in dst_p now processing.
+ int end_i; // Highest order word in dst_p to process.
+ int left_shift; // Left shift for val.
+ uint_type mask; // Mask for bits to extract or keep.
+
+ dst_i = low_i / BITS_PER_DIGIT;
+ left_shift = low_i % BITS_PER_DIGIT;
+ end_i = (low_i + (m_len-1)) / BITS_PER_DIGIT;
+
+ mask = ~(-1 << left_shift);
+ dst_p[dst_i] = (sc_digit)(dst_p[dst_i] & mask);
+ dst_i++;
+ for ( ; dst_i <= end_i; dst_i++ ) dst_p[dst_i] = 0;
+ return false;
+}
+
+//------------------------------------------------------------------------------
+//"sc_int_base::concat_get_data"
+//
+// This method transfers the value of this object instance to the supplied
+// array of sc_unsigned digits starting with the bit specified by low_i within
+// the array of digits.
+//
+// Notes:
+// (1) we don't worry about masking the high order data we transfer since
+// concat_get_data() is called from low order bit to high order bit. So
+// the bits above where we place ours will be filled in by someone else.
+//
+// dst_p -> array of sc_unsigned digits to be filled in.
+// low_i = first bit within dst_p to be set.
+//------------------------------------------------------------------------------
+bool sc_int_base::concat_get_data( sc_digit* dst_p, int low_i ) const
+{
+ int dst_i; // Word in dst_p now processing.
+ int end_i; // Highest order word in dst_p to process.
+ int high_i; // Index of high order bit in dst_p to set.
+ int left_shift; // Left shift for val.
+ uint_type mask; // Mask for bits to extract or keep.
+ bool non_zero; // True if value inserted is non-zero.
+ uint_type val; // Value for this object.
+
+ dst_i = low_i / BITS_PER_DIGIT;
+ left_shift = low_i % BITS_PER_DIGIT;
+ high_i = low_i + (m_len-1);
+ end_i = high_i / BITS_PER_DIGIT;
+ val = m_val;
+ non_zero = val != 0;
+
+ // MASK OFF DATA TO BE TRANSFERRED BASED ON WIDTH:
+
+ if ( m_len < 64 )
+ {
+ mask = ~((uint_type)-1 << m_len);
+ val &= mask;
+ }
+
+ // PROCESS THE FIRST WORD:
+
+ mask = (-1 << left_shift);
+ dst_p[dst_i] = (sc_digit)((dst_p[dst_i] & ~mask) |
+ ((val <<left_shift) & DIGIT_MASK));
+ switch ( end_i - dst_i )
+ {
+ // BITS ARE ACROSS TWO WORDS:
+
+ case 1:
+ dst_i++;
+ val >>= (BITS_PER_DIGIT-left_shift);
+ dst_p[dst_i] = (sc_digit)val;
+ break;
+
+ // BITS ARE ACROSS THREE WORDS:
+
+ case 2:
+ dst_i++;
+ val >>= (BITS_PER_DIGIT-left_shift);
+ dst_p[dst_i++] = ((sc_digit)val) & DIGIT_MASK;
+ val >>= BITS_PER_DIGIT;
+ dst_p[dst_i] = (sc_digit)val;
+ break;
+
+ // BITS ARE ACROSS FOUR WORDS:
+
+ case 3:
+ dst_i++;
+ val >>= (BITS_PER_DIGIT-left_shift);
+ dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
+ val >>= BITS_PER_DIGIT;
+ dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
+ val >>= BITS_PER_DIGIT;
+ dst_p[dst_i] = (sc_digit)val;
+ break;
+ }
+ return non_zero;
+}
+
+// #### OPTIMIZE
+void sc_int_base::concat_set(int64 src, int low_i)
+{
+ *this = (low_i < 64) ? src >> low_i : src >> 63;
+}
+
+void sc_int_base::concat_set(const sc_signed& src, int low_i)
+{
+ if ( low_i < src.length() )
+ *this = src >> low_i;
+ else
+ *this = (src < 0) ? (int_type)-1 : 0;
+}
+
+void sc_int_base::concat_set(const sc_unsigned& src, int low_i)
+{
+ if ( low_i < src.length() )
+ *this = src >> low_i;
+ else
+ *this = 0;
+}
+
+void sc_int_base::concat_set(uint64 src, int low_i)
+{
+ *this = (low_i < 64) ? src >> low_i : 0;
+}
+
+// other methods
+
+void
+sc_int_base::scan( ::std::istream& is )
+{
+ std::string s;
+ is >> s;
+ *this = s.c_str();
+}
+
+} // namespace sc_dt;
+
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/int/sc_int_base.h b/ext/systemc/src/sysc/datatypes/int/sc_int_base.h
new file mode 100644
index 000000000..a9b8a6457
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/int/sc_int_base.h
@@ -0,0 +1,1382 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_int_base.h -- A sc_int is a signed integer whose length is less than the
+ machine's native integer length. We provide two implementations
+ (i) sc_int with length between 1 - 64, and (ii) sc_int with
+ length between 1 - 32. Implementation (i) is the default
+ implementation, while implementation (ii) can be used only if
+ the class library is compiled with -D_32BIT_. Unlike arbitrary
+ precision, arithmetic and bitwise operations are performed
+ using the native types (hence capped at 32/64 bits). The sc_int
+ integer is useful when the user does not need arbitrary
+ precision and the performance is superior to
+ sc_bigint/sc_biguint.
+
+ Original Author: Amit Rao, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc.
+ Description of Modification: - Resolved ambiguity with sc_(un)signed.
+ - Merged the code for 64- and 32-bit versions
+ via the constants in sc_nbdefs.h.
+ - Eliminated redundant file inclusions.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_int_base.h,v $
+// Revision 1.3 2011/08/24 22:05:45 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.2 2011/02/18 20:19:15 acg
+// Andy Goodrich: updating Copyright notice.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.4 2006/05/08 17:50:01 acg
+// Andy Goodrich: Added David Long's declarations for friend operators,
+// functions, and methods, to keep the Microsoft compiler happy.
+//
+// Revision 1.3 2006/01/13 18:49:31 acg
+// Added $Log command so that CVS check in comments are reproduced in the
+// source.
+//
+
+#ifndef SC_INT_BASE_H
+#define SC_INT_BASE_H
+
+#include "sysc/kernel/sc_object.h"
+#include "sysc/datatypes/misc/sc_value_base.h"
+#include "sysc/datatypes/int/sc_int_ids.h"
+#include "sysc/datatypes/int/sc_length_param.h"
+#include "sysc/datatypes/int/sc_nbdefs.h"
+#include "sysc/datatypes/int/sc_uint_base.h"
+#include "sysc/utils/sc_iostream.h"
+#include "sysc/utils/sc_temporary.h"
+
+
+namespace sc_dt
+{
+
+class sc_concatref;
+
+// classes defined in this module
+class sc_int_bitref_r;
+class sc_int_bitref;
+class sc_int_subref_r;
+class sc_int_subref;
+class sc_int_base;
+class sc_signed_subref_r;
+class sc_unsigned_subref_r;
+
+// forward class declarations
+class sc_bv_base;
+class sc_lv_base;
+class sc_signed;
+class sc_unsigned;
+class sc_fxval;
+class sc_fxval_fast;
+class sc_fxnum;
+class sc_fxnum_fast;
+
+
+extern const uint_type mask_int[SC_INTWIDTH][SC_INTWIDTH];
+
+// friend operator declarations
+ // relational operators
+
+ inline bool operator == ( const sc_int_base& a, const sc_int_base& b );
+
+ inline bool operator != ( const sc_int_base& a, const sc_int_base& b );
+
+ inline bool operator < ( const sc_int_base& a, const sc_int_base& b );
+
+ inline bool operator <= ( const sc_int_base& a, const sc_int_base& b );
+
+ inline bool operator > ( const sc_int_base& a, const sc_int_base& b );
+
+ inline bool operator >= ( const sc_int_base& a, const sc_int_base& b );
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_int_bitref_r
+//
+// Proxy class for sc_int bit selection (r-value only).
+// ----------------------------------------------------------------------------
+
+class sc_int_bitref_r : public sc_value_base
+{
+ friend class sc_int_base;
+
+protected:
+
+ // constructor
+
+ sc_int_bitref_r() : sc_value_base(), m_index(), m_obj_p()
+ {}
+
+ // initializer for sc_core::sc_vpool:
+
+ void initialize( const sc_int_base* obj_p, int index_ )
+ {
+ m_obj_p = (sc_int_base*)obj_p;
+ m_index = index_;
+ }
+
+public:
+
+ // copy constructor
+
+ sc_int_bitref_r( const sc_int_bitref_r& a ) :
+ sc_value_base(a), m_index(a.m_index), m_obj_p(a.m_obj_p)
+ {}
+
+ // destructor
+
+ virtual ~sc_int_bitref_r()
+ {}
+
+ // capacity
+
+ int length() const
+ { return 1; }
+
+#ifdef SC_DT_DEPRECATED
+ int bitwidth() const
+ { return length(); }
+#endif
+
+ // concatenation support
+
+ virtual int concat_length( bool *xz_present_p ) const
+ { if (xz_present_p) *xz_present_p = false; return 1; }
+ virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const
+ {
+ int bit_mask = 1 << (low_i % BITS_PER_DIGIT);
+ int word_i = low_i / BITS_PER_DIGIT;
+
+ dst_p[word_i] &= ~bit_mask;
+ return false;
+ }
+ virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const
+ {
+ bool non_zero;
+ int bit_mask = 1 << (low_i % BITS_PER_DIGIT);
+ int word_i = low_i / BITS_PER_DIGIT;
+
+ if ( operator uint64() )
+ {
+ dst_p[word_i] |= bit_mask;
+ non_zero = true;
+ }
+ else
+ {
+ dst_p[word_i] &= ~bit_mask;
+ non_zero = false;
+ }
+ return non_zero;
+ }
+ virtual uint64 concat_get_uint64() const
+ { return operator uint64(); }
+
+
+
+
+ // implicit conversions
+
+ operator uint64 () const;
+ bool operator ! () const;
+ bool operator ~ () const;
+
+
+ // explicit conversions
+
+ uint64 value() const
+ { return operator uint64(); }
+
+ bool to_bool() const
+ { return operator uint64(); }
+
+
+ // other methods
+
+ void print( ::std::ostream& os = ::std::cout ) const
+ { os << to_bool(); }
+
+protected:
+ int m_index;
+ sc_int_base* m_obj_p;
+
+private:
+
+ // disabled
+ sc_int_bitref_r& operator = ( const sc_int_bitref_r& );
+};
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream&, const sc_int_bitref_r& );
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_int_bitref
+//
+// Proxy class for sc_int bit selection (r-value and l-value).
+// ----------------------------------------------------------------------------
+
+class sc_int_bitref
+ : public sc_int_bitref_r
+{
+ friend class sc_int_base;
+ friend class sc_core::sc_vpool<sc_int_bitref>;
+
+
+ // constructor
+
+ sc_int_bitref() : sc_int_bitref_r()
+ {}
+
+
+public:
+
+ // copy constructor
+
+ sc_int_bitref( const sc_int_bitref& a ) : sc_int_bitref_r( a )
+ {}
+
+ // assignment operators
+
+ sc_int_bitref& operator = ( const sc_int_bitref_r& b );
+ sc_int_bitref& operator = ( const sc_int_bitref& b );
+ sc_int_bitref& operator = ( bool b );
+
+ sc_int_bitref& operator &= ( bool b );
+ sc_int_bitref& operator |= ( bool b );
+ sc_int_bitref& operator ^= ( bool b );
+
+ // concatenation methods
+
+ virtual void concat_set(int64 src, int low_i);
+ virtual void concat_set(const sc_signed& src, int low_i);
+ virtual void concat_set(const sc_unsigned& src, int low_i);
+ virtual void concat_set(uint64 src, int low_i);
+
+
+ // other methods
+
+ void scan( ::std::istream& is = ::std::cin );
+
+public:
+ static sc_core::sc_vpool<sc_int_bitref> m_pool;
+
+};
+
+
+
+inline
+::std::istream&
+operator >> ( ::std::istream&, sc_int_bitref& );
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_int_subref_r
+//
+// Proxy class for sc_int part selection (r-value only).
+// ----------------------------------------------------------------------------
+
+class sc_int_subref_r : public sc_value_base
+{
+ friend class sc_int_base;
+ friend class sc_int_signal;
+ friend class sc_int_subref;
+
+protected:
+
+ // constructor
+
+ sc_int_subref_r() : sc_value_base(), m_left(0), m_obj_p(0), m_right(0)
+ {}
+
+ // initializer for sc_core::sc_vpool:
+
+ void initialize( const sc_int_base* obj_p, int left_i, int right_i )
+ {
+ m_obj_p = (sc_int_base*)obj_p;
+ m_left = left_i;
+ m_right = right_i;
+ }
+
+
+public:
+ // copy constructor
+
+ sc_int_subref_r( const sc_int_subref_r& a ) :
+ sc_value_base(a), m_left( a.m_left ), m_obj_p( a.m_obj_p ),
+ m_right( a.m_right )
+ {}
+
+ // destructor
+
+ virtual ~sc_int_subref_r()
+ {}
+
+ // capacity
+
+ int length() const
+ { return ( m_left - m_right + 1 ); }
+
+#ifdef SC_DT_DEPRECATED
+ int bitwidth() const
+ { return length(); }
+#endif
+
+ // concatenation support
+
+ virtual int concat_length(bool* xz_present_p) const
+ { if ( xz_present_p ) *xz_present_p = false; return length(); }
+ virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const;
+ virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const;
+ virtual uint64 concat_get_uint64() const
+ {
+ int len = length();
+ uint64 val = operator uint_type();
+ if ( len < 64 )
+ return (uint64)(val & ~((uint_type)-1 << len));
+ else
+ return (uint64)val;
+ }
+
+ // reduce methods
+
+ bool and_reduce() const;
+
+ bool nand_reduce() const
+ { return ( ! and_reduce() ); }
+
+ bool or_reduce() const;
+
+ bool nor_reduce() const
+ { return ( ! or_reduce() ); }
+
+ bool xor_reduce() const;
+
+ bool xnor_reduce() const
+ { return ( ! xor_reduce() ); }
+
+
+ // implicit conversion to uint_type
+
+ operator uint_type () const;
+
+
+ // explicit conversions
+
+ uint_type value() const
+ { return operator uint_type(); }
+
+
+ int to_int() const;
+ unsigned int to_uint() const;
+ long to_long() const;
+ unsigned long to_ulong() const;
+ int64 to_int64() const;
+ uint64 to_uint64() const;
+ double to_double() const;
+
+
+ // explicit conversion to character string
+
+ const std::string to_string( sc_numrep numrep = SC_DEC ) const;
+ const std::string to_string( sc_numrep numrep, bool w_prefix ) const;
+
+
+ // other methods
+
+ void print( ::std::ostream& os = ::std::cout ) const
+ { os << to_string(sc_io_base(os,SC_DEC),sc_io_show_base(os)); }
+
+protected:
+
+ int m_left;
+ sc_int_base* m_obj_p;
+ int m_right;
+
+private:
+ const sc_int_subref_r& operator = ( const sc_int_subref_r& );
+};
+
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream&, const sc_int_subref_r& );
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_int_subref
+//
+// Proxy class for sc_int part selection (r-value and l-value).
+// ----------------------------------------------------------------------------
+
+class sc_int_subref
+ : public sc_int_subref_r
+{
+ friend class sc_int_base;
+ friend class sc_core::sc_vpool<sc_int_subref>;
+
+
+protected:
+
+ // constructor
+ sc_int_subref() : sc_int_subref_r()
+ {}
+
+public:
+
+ // copy constructor
+
+ sc_int_subref( const sc_int_subref& a ) : sc_int_subref_r( a )
+ {}
+
+ // assignment operators
+
+ sc_int_subref& operator = ( int_type v );
+ sc_int_subref& operator = ( const sc_int_base& a );
+
+ sc_int_subref& operator = ( const sc_int_subref_r& a )
+ { return operator = ( a.operator uint_type() ); }
+
+ sc_int_subref& operator = ( const sc_int_subref& a )
+ { return operator = ( a.operator uint_type() ); }
+
+ template< class T >
+ sc_int_subref& operator = ( const sc_generic_base<T>& a )
+ { return operator = ( a->to_int64() ); }
+
+ sc_int_subref& operator = ( const char* a );
+
+ sc_int_subref& operator = ( unsigned long a )
+ { return operator = ( (int_type) a ); }
+
+ sc_int_subref& operator = ( long a )
+ { return operator = ( (int_type) a ); }
+
+ sc_int_subref& operator = ( unsigned int a )
+ { return operator = ( (int_type) a ); }
+
+ sc_int_subref& operator = ( int a )
+ { return operator = ( (int_type) a ); }
+
+ sc_int_subref& operator = ( uint64 a )
+ { return operator = ( (int_type) a ); }
+
+ sc_int_subref& operator = ( double a )
+ { return operator = ( (int_type) a ); }
+
+ sc_int_subref& operator = ( const sc_signed& );
+ sc_int_subref& operator = ( const sc_unsigned& );
+ sc_int_subref& operator = ( const sc_bv_base& );
+ sc_int_subref& operator = ( const sc_lv_base& );
+
+ // concatenation methods
+
+ virtual void concat_set(int64 src, int low_i);
+ virtual void concat_set(const sc_signed& src, int low_i);
+ virtual void concat_set(const sc_unsigned& src, int low_i);
+ virtual void concat_set(uint64 src, int low_i);
+
+ // other methods
+
+ void scan( ::std::istream& is = ::std::cin );
+
+public:
+ static sc_core::sc_vpool<sc_int_subref> m_pool;
+
+};
+
+
+
+inline
+::std::istream&
+operator >> ( ::std::istream&, sc_int_subref& );
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_int_base
+//
+// Base class for sc_int.
+// ----------------------------------------------------------------------------
+
+class sc_int_base : public sc_value_base
+{
+ friend class sc_int_bitref_r;
+ friend class sc_int_bitref;
+ friend class sc_int_subref_r;
+ friend class sc_int_subref;
+
+
+ // support methods
+
+ void invalid_length() const;
+ void invalid_index( int i ) const;
+ void invalid_range( int l, int r ) const;
+
+ void check_length() const
+ { if( m_len <= 0 || m_len > SC_INTWIDTH ) { invalid_length(); } }
+
+ void check_index( int i ) const
+ { if( i < 0 || i >= m_len ) { invalid_index( i ); } }
+
+ void check_range( int l, int r ) const
+ { if( r < 0 || l >= m_len || l < r ) { invalid_range( l, r ); } }
+
+ void check_value() const;
+
+ void extend_sign()
+ {
+#ifdef DEBUG_SYSTEMC
+ check_value();
+#endif
+ m_val = ( m_val << m_ulen >> m_ulen );
+ }
+
+public:
+
+ // constructors
+
+ explicit sc_int_base( int w = sc_length_param().len() )
+ : m_val( 0 ), m_len( w ), m_ulen( SC_INTWIDTH - m_len )
+ { check_length(); }
+
+ sc_int_base( int_type v, int w )
+ : m_val( v ), m_len( w ), m_ulen( SC_INTWIDTH - m_len )
+ { check_length(); extend_sign(); }
+
+ sc_int_base( const sc_int_base& a )
+ : sc_value_base(a), m_val( a.m_val ), m_len( a.m_len ),
+ m_ulen( a.m_ulen )
+ {}
+
+ explicit sc_int_base( const sc_int_subref_r& a )
+ : m_val( a ), m_len( a.length() ), m_ulen( SC_INTWIDTH - m_len )
+ { extend_sign(); }
+
+ template< class T >
+ explicit sc_int_base( const sc_generic_base<T>& a ) :
+ m_val( a->to_int64() ), m_len( a->length() ),
+ m_ulen( SC_INTWIDTH - m_len )
+ { check_length(); extend_sign(); }
+
+ explicit sc_int_base( const sc_signed& a );
+ explicit sc_int_base( const sc_unsigned& a );
+ explicit sc_int_base( const sc_bv_base& v );
+ explicit sc_int_base( const sc_lv_base& v );
+ explicit sc_int_base( const sc_uint_subref_r& v );
+ explicit sc_int_base( const sc_signed_subref_r& v );
+ explicit sc_int_base( const sc_unsigned_subref_r& v );
+
+
+
+ // destructor
+
+ virtual ~sc_int_base()
+ {}
+
+ // assignment operators
+
+ sc_int_base& operator = ( int_type v )
+ { m_val = v; extend_sign(); return *this; }
+
+ sc_int_base& operator = ( const sc_int_base& a )
+ { m_val = a.m_val; extend_sign(); return *this; }
+
+ sc_int_base& operator = ( const sc_int_subref_r& a )
+ { m_val = a; extend_sign(); return *this; }
+
+ template<class T>
+ sc_int_base& operator = ( const sc_generic_base<T>& a )
+ { m_val = a->to_int64(); extend_sign(); return *this; }
+
+ sc_int_base& operator = ( const sc_signed& a );
+ sc_int_base& operator = ( const sc_unsigned& a );
+
+#ifdef SC_INCLUDE_FX
+ sc_int_base& operator = ( const sc_fxval& a );
+ sc_int_base& operator = ( const sc_fxval_fast& a );
+ sc_int_base& operator = ( const sc_fxnum& a );
+ sc_int_base& operator = ( const sc_fxnum_fast& a );
+#endif
+
+ sc_int_base& operator = ( const sc_bv_base& a );
+ sc_int_base& operator = ( const sc_lv_base& a );
+
+ sc_int_base& operator = ( const char* a );
+
+ sc_int_base& operator = ( unsigned long a )
+ { m_val = a; extend_sign(); return *this; }
+
+ sc_int_base& operator = ( long a )
+ { m_val = a; extend_sign(); return *this; }
+
+ sc_int_base& operator = ( unsigned int a )
+ { m_val = a; extend_sign(); return *this; }
+
+ sc_int_base& operator = ( int a )
+ { m_val = a; extend_sign(); return *this; }
+
+ sc_int_base& operator = ( uint64 a )
+ { m_val = a; extend_sign(); return *this; }
+
+ sc_int_base& operator = ( double a )
+ { m_val = (int_type) a; extend_sign(); return *this; }
+
+
+ // arithmetic assignment operators
+
+ sc_int_base& operator += ( int_type v )
+ { m_val += v; extend_sign(); return *this; }
+
+ sc_int_base& operator -= ( int_type v )
+ { m_val -= v; extend_sign(); return *this; }
+
+ sc_int_base& operator *= ( int_type v )
+ { m_val *= v; extend_sign(); return *this; }
+
+ sc_int_base& operator /= ( int_type v )
+ { m_val /= v; extend_sign(); return *this; }
+
+ sc_int_base& operator %= ( int_type v )
+ { m_val %= v; extend_sign(); return *this; }
+
+
+ // bitwise assignment operators
+
+ sc_int_base& operator &= ( int_type v )
+ { m_val &= v; extend_sign(); return *this; }
+
+ sc_int_base& operator |= ( int_type v )
+ { m_val |= v; extend_sign(); return *this; }
+
+ sc_int_base& operator ^= ( int_type v )
+ { m_val ^= v; extend_sign(); return *this; }
+
+
+ sc_int_base& operator <<= ( int_type v )
+ { m_val <<= v; extend_sign(); return *this; }
+
+ sc_int_base& operator >>= ( int_type v )
+ { m_val >>= v; /* no sign extension needed */ return *this; }
+
+
+ // prefix and postfix increment and decrement operators
+
+ sc_int_base& operator ++ () // prefix
+ { ++ m_val; extend_sign(); return *this; }
+
+ const sc_int_base operator ++ ( int ) // postfix
+ { sc_int_base tmp( *this ); ++ m_val; extend_sign(); return tmp; }
+
+ sc_int_base& operator -- () // prefix
+ { -- m_val; extend_sign(); return *this; }
+
+ const sc_int_base operator -- ( int ) // postfix
+ { sc_int_base tmp( *this ); -- m_val; extend_sign(); return tmp; }
+
+
+ // relational operators
+
+ friend bool operator == ( const sc_int_base& a, const sc_int_base& b )
+ { return a.m_val == b.m_val; }
+
+ friend bool operator != ( const sc_int_base& a, const sc_int_base& b )
+ { return a.m_val != b.m_val; }
+
+ friend bool operator < ( const sc_int_base& a, const sc_int_base& b )
+ { return a.m_val < b.m_val; }
+
+ friend bool operator <= ( const sc_int_base& a, const sc_int_base& b )
+ { return a.m_val <= b.m_val; }
+
+ friend bool operator > ( const sc_int_base& a, const sc_int_base& b )
+ { return a.m_val > b.m_val; }
+
+ friend bool operator >= ( const sc_int_base& a, const sc_int_base& b )
+ { return a.m_val >= b.m_val; }
+
+
+ // bit selection
+
+ sc_int_bitref& operator [] ( int i );
+ const sc_int_bitref_r& operator [] ( int i ) const;
+
+ sc_int_bitref& bit( int i );
+ const sc_int_bitref_r& bit( int i ) const;
+
+
+ // part selection
+
+ sc_int_subref& operator () ( int left, int right );
+ const sc_int_subref_r& operator () ( int left, int right ) const;
+
+ sc_int_subref& range( int left, int right );
+ const sc_int_subref_r& range( int left, int right ) const;
+
+
+ // bit access, without bounds checking or sign extension
+
+ bool test( int i ) const
+ { return ( 0 != (m_val & (UINT_ONE << i)) ); }
+
+ void set( int i )
+ { m_val |= (UINT_ONE << i); }
+
+ void set( int i, bool v )
+ { v ? m_val |= (UINT_ONE << i) : m_val &= ~(UINT_ONE << i); }
+
+
+ // capacity
+
+ int length() const
+ { return m_len; }
+
+#ifdef SC_DT_DEPRECATED
+ int bitwidth() const
+ { return length(); }
+#endif
+
+ // concatenation support
+
+ virtual int concat_length(bool* xz_present_p) const
+ { if ( xz_present_p ) *xz_present_p = false; return length(); }
+ virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const;
+ virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const;
+ virtual uint64 concat_get_uint64() const
+ {
+ if ( m_len < 64 )
+ return (uint64)(m_val & ~((uint_type)-1 << m_len));
+ else
+ return (uint64)m_val;
+ }
+ virtual void concat_set(int64 src, int low_i);
+ virtual void concat_set(const sc_signed& src, int low_i);
+ virtual void concat_set(const sc_unsigned& src, int low_i);
+ virtual void concat_set(uint64 src, int low_i);
+
+
+ // reduce methods
+
+ bool and_reduce() const;
+
+ bool nand_reduce() const
+ { return ( ! and_reduce() ); }
+
+ bool or_reduce() const;
+
+ bool nor_reduce() const
+ { return ( ! or_reduce() ); }
+
+ bool xor_reduce() const;
+
+ bool xnor_reduce() const
+ { return ( ! xor_reduce() ); }
+
+
+ // implicit conversion to int_type
+
+ operator int_type() const
+ { return m_val; }
+
+
+ // explicit conversions
+
+ int_type value() const
+ { return operator int_type(); }
+
+
+ int to_int() const
+ { return (int) m_val; }
+
+ unsigned int to_uint() const
+ { return (unsigned int) m_val; }
+
+ long to_long() const
+ { return (long) m_val; }
+
+ unsigned long to_ulong() const
+ { return (unsigned long) m_val; }
+
+ int64 to_int64() const
+ { return (int64) m_val; }
+
+ uint64 to_uint64() const
+ { return (uint64) m_val; }
+
+ double to_double() const
+ { return (double) m_val; }
+
+
+#ifndef _32BIT_
+ long long_low() const
+ { return (long) (m_val & UINT64_32ONES); }
+
+ long long_high() const
+ { return (long) ((m_val >> 32) & UINT64_32ONES); }
+#endif
+
+
+ // explicit conversion to character string
+
+ const std::string to_string( sc_numrep numrep = SC_DEC ) const;
+ const std::string to_string( sc_numrep numrep, bool w_prefix ) const;
+
+
+ // other methods
+
+ void print( ::std::ostream& os = ::std::cout ) const
+ { os << to_string(sc_io_base(os,SC_DEC),sc_io_show_base(os)); }
+
+ void scan( ::std::istream& is = ::std::cin );
+
+protected:
+
+ int_type m_val; // value
+ int m_len; // length
+ int m_ulen; // unused length
+};
+
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream&, const sc_int_base& );
+
+inline
+::std::istream&
+operator >> ( ::std::istream&, sc_int_base& );
+
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_int_bitref_r
+//
+// Proxy class for sc_int bit selection (r-value only).
+// ----------------------------------------------------------------------------
+
+// implicit conversion to uint64
+
+inline
+sc_int_bitref_r::operator uint64 () const
+{
+ return m_obj_p->test( m_index );
+}
+
+inline
+bool
+sc_int_bitref_r::operator ! () const
+{
+ return ! m_obj_p->test( m_index );
+}
+
+inline
+bool
+sc_int_bitref_r::operator ~ () const
+{
+ return ! m_obj_p->test( m_index );
+}
+
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, const sc_int_bitref_r& a )
+{
+ a.print( os );
+ return os;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_int_bitref
+//
+// Proxy class for sc_int bit selection (r-value and l-value).
+// ----------------------------------------------------------------------------
+
+// assignment operators
+
+inline
+sc_int_bitref&
+sc_int_bitref::operator = ( const sc_int_bitref_r& b )
+{
+ m_obj_p->set( m_index, (bool) b );
+ m_obj_p->extend_sign();
+ return *this;
+}
+
+inline
+sc_int_bitref&
+sc_int_bitref::operator = ( const sc_int_bitref& b )
+{
+ m_obj_p->set( m_index, (bool) b );
+ m_obj_p->extend_sign();
+ return *this;
+}
+
+inline
+sc_int_bitref&
+sc_int_bitref::operator = ( bool b )
+{
+ m_obj_p->set( m_index, b );
+ m_obj_p->extend_sign();
+ return *this;
+}
+
+
+inline
+sc_int_bitref&
+sc_int_bitref::operator &= ( bool b )
+{
+ if( ! b ) {
+ m_obj_p->set( m_index, b );
+ m_obj_p->extend_sign();
+ }
+ return *this;
+}
+
+inline
+sc_int_bitref&
+sc_int_bitref::operator |= ( bool b )
+{
+ if( b ) {
+ m_obj_p->set( m_index, b );
+ m_obj_p->extend_sign();
+ }
+ return *this;
+}
+
+inline
+sc_int_bitref&
+sc_int_bitref::operator ^= ( bool b )
+{
+ if( b ) {
+ m_obj_p->m_val ^= (UINT_ONE << m_index);
+ m_obj_p->extend_sign();
+ }
+ return *this;
+}
+
+
+
+inline
+::std::istream&
+operator >> ( ::std::istream& is, sc_int_bitref& a )
+{
+ a.scan( is );
+ return is;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_int_subref_r
+//
+// Proxy class for sc_int part selection (r-value only).
+// ----------------------------------------------------------------------------
+
+// implicit conversion to int_type
+
+inline
+sc_int_subref_r::operator uint_type() const
+{
+ uint_type /*int_type*/ val = m_obj_p->m_val;
+ int uleft = SC_INTWIDTH - (m_left + 1);
+ int uright = uleft + m_right;
+ return ( val << uleft >> uright );
+}
+
+
+// reduce methods
+
+inline
+bool
+sc_int_subref_r::and_reduce() const
+{
+ sc_int_base a( *this );
+ return a.and_reduce();
+}
+
+inline
+bool
+sc_int_subref_r::or_reduce() const
+{
+ sc_int_base a( *this );
+ return a.or_reduce();
+}
+
+inline
+bool
+sc_int_subref_r::xor_reduce() const
+{
+ sc_int_base a( *this );
+ return a.xor_reduce();
+}
+
+
+// explicit conversions
+
+inline
+int
+sc_int_subref_r::to_int() const
+{
+ int result = static_cast<int>(operator uint_type());
+ return result;
+}
+
+inline
+unsigned int
+sc_int_subref_r::to_uint() const
+{
+ unsigned int result = static_cast<unsigned int>(operator uint_type());
+ return result;
+}
+
+inline
+long
+sc_int_subref_r::to_long() const
+{
+ long result = static_cast<long>(operator uint_type());
+ return result;
+}
+
+inline
+unsigned long
+sc_int_subref_r::to_ulong() const
+{
+ unsigned long result = static_cast<unsigned long>(operator uint_type());
+ return result;
+}
+
+inline
+int64
+sc_int_subref_r::to_int64() const
+{
+ int64 result = operator uint_type();
+ return result;
+}
+
+inline
+uint64
+sc_int_subref_r::to_uint64() const
+{
+ uint64 result = operator uint_type();
+ return result;
+}
+
+inline
+double
+sc_int_subref_r::to_double() const
+{
+ double result = static_cast<double>(operator uint_type());
+ return result;
+}
+
+
+// explicit conversion to character string
+
+inline
+const std::string
+sc_int_subref_r::to_string( sc_numrep numrep ) const
+{
+ sc_uint_base a(length());
+ a = operator uint_type();
+ return a.to_string( numrep );
+}
+
+inline
+const std::string
+sc_int_subref_r::to_string( sc_numrep numrep, bool w_prefix ) const
+{
+ sc_uint_base a(length());
+ a = operator uint_type();
+ return a.to_string( numrep, w_prefix );
+}
+
+
+// functional notation for the reduce methods
+
+inline
+bool
+and_reduce( const sc_int_subref_r& a )
+{
+ return a.and_reduce();
+}
+
+inline
+bool
+nand_reduce( const sc_int_subref_r& a )
+{
+ return a.nand_reduce();
+}
+
+inline
+bool
+or_reduce( const sc_int_subref_r& a )
+{
+ return a.or_reduce();
+}
+
+inline
+bool
+nor_reduce( const sc_int_subref_r& a )
+{
+ return a.nor_reduce();
+}
+
+inline
+bool
+xor_reduce( const sc_int_subref_r& a )
+{
+ return a.xor_reduce();
+}
+
+inline
+bool
+xnor_reduce( const sc_int_subref_r& a )
+{
+ return a.xnor_reduce();
+}
+
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, const sc_int_subref_r& a )
+{
+ a.print( os );
+ return os;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_int_subref
+//
+// Proxy class for sc_int part selection (r-value and l-value).
+// ----------------------------------------------------------------------------
+
+// assignment operators
+
+inline
+sc_int_subref&
+sc_int_subref::operator = ( const sc_int_base& a )
+{
+ return operator = ( a.operator int_type() );
+}
+
+inline
+sc_int_subref&
+sc_int_subref::operator = ( const char* a )
+{
+ sc_int_base aa( length() );
+ return ( *this = aa = a );
+}
+
+
+
+inline
+::std::istream&
+operator >> ( ::std::istream& is, sc_int_subref& a )
+{
+ a.scan( is );
+ return is;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_int_base
+//
+// Base class for sc_int.
+// ----------------------------------------------------------------------------
+
+// bit selection
+
+inline
+sc_int_bitref&
+sc_int_base::operator [] ( int i )
+{
+ check_index( i );
+ sc_int_bitref* result_p = sc_int_bitref::m_pool.allocate();
+ result_p->initialize(this, i);
+ return *result_p;
+}
+
+inline
+const sc_int_bitref_r&
+sc_int_base::operator [] ( int i ) const
+{
+ check_index( i );
+ sc_int_bitref* result_p = sc_int_bitref::m_pool.allocate();
+ result_p->initialize(this, i);
+ return *result_p;
+}
+
+
+inline
+sc_int_bitref&
+sc_int_base::bit( int i )
+{
+ check_index( i );
+ sc_int_bitref* result_p = sc_int_bitref::m_pool.allocate();
+ result_p->initialize(this, i);
+ return *result_p;
+}
+
+inline
+const sc_int_bitref_r&
+sc_int_base::bit( int i ) const
+{
+ check_index( i );
+ sc_int_bitref* result_p = sc_int_bitref::m_pool.allocate();
+ result_p->initialize(this, i);
+ return *result_p;
+}
+
+
+// part selection
+
+inline
+sc_int_subref&
+sc_int_base::operator () ( int left, int right )
+{
+ check_range( left, right );
+ sc_int_subref* result_p = sc_int_subref::m_pool.allocate();
+ result_p->initialize(this, left, right);
+ return *result_p;
+}
+
+inline
+const sc_int_subref_r&
+sc_int_base::operator () ( int left, int right ) const
+{
+ check_range( left, right );
+ sc_int_subref* result_p = sc_int_subref::m_pool.allocate();
+ result_p->initialize(this, left, right);
+ return *result_p;
+}
+
+
+inline
+sc_int_subref&
+sc_int_base::range( int left, int right )
+{
+ check_range( left, right );
+ sc_int_subref* result_p = sc_int_subref::m_pool.allocate();
+ result_p->initialize(this, left, right);
+ return *result_p;
+}
+
+inline
+const sc_int_subref_r&
+sc_int_base::range( int left, int right ) const
+{
+ check_range( left, right );
+ sc_int_subref* result_p = sc_int_subref::m_pool.allocate();
+ result_p->initialize(this, left, right);
+ return *result_p;
+}
+
+
+// functional notation for the reduce methods
+
+inline
+bool
+and_reduce( const sc_int_base& a )
+{
+ return a.and_reduce();
+}
+
+inline
+bool
+nand_reduce( const sc_int_base& a )
+{
+ return a.nand_reduce();
+}
+
+inline
+bool
+or_reduce( const sc_int_base& a )
+{
+ return a.or_reduce();
+}
+
+inline
+bool
+nor_reduce( const sc_int_base& a )
+{
+ return a.nor_reduce();
+}
+
+inline
+bool
+xor_reduce( const sc_int_base& a )
+{
+ return a.xor_reduce();
+}
+
+inline
+bool
+xnor_reduce( const sc_int_base& a )
+{
+ return a.xnor_reduce();
+}
+
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, const sc_int_base& a )
+{
+ a.print( os );
+ return os;
+}
+
+inline
+::std::istream&
+operator >> ( ::std::istream& is, sc_int_base& a )
+{
+ a.scan( is );
+ return is;
+}
+
+} // namespace sc_dt
+
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/int/sc_int_ids.h b/ext/systemc/src/sysc/datatypes/int/sc_int_ids.h
new file mode 100644
index 000000000..13b269590
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/int/sc_int_ids.h
@@ -0,0 +1,80 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_int_ids.h -- Report ids for the datatypes/int code.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2002-01-17
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_int_ids.h,v $
+// Revision 1.2 2011/02/18 20:19:15 acg
+// Andy Goodrich: updating Copyright notice.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:49:31 acg
+// Added $Log command so that CVS check in comments are reproduced in the
+// source.
+//
+
+#ifndef SC_INT_IDS_H
+#define SC_INT_IDS_H
+
+
+#include "sysc/utils/sc_report.h"
+
+
+// ----------------------------------------------------------------------------
+// Report ids (datatypes/int)
+//
+// Report ids in the range of 400-499.
+// ----------------------------------------------------------------------------
+
+#ifndef SC_DEFINE_MESSAGE
+#define SC_DEFINE_MESSAGE(id,unused1,unused2) \
+ namespace sc_core { extern const char id[]; }
+extern const char SC_ID_REGISTER_ID_FAILED_[]; // in sc_report_handler.cpp
+#endif
+
+
+SC_DEFINE_MESSAGE( SC_ID_INIT_FAILED_, 400, "initialization failed" )
+SC_DEFINE_MESSAGE( SC_ID_ASSIGNMENT_FAILED_, 401, "assignment failed" )
+SC_DEFINE_MESSAGE( SC_ID_OPERATION_FAILED_, 402, "operation failed" )
+SC_DEFINE_MESSAGE( SC_ID_CONVERSION_FAILED_, 403, "conversion failed" )
+
+
+
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/int/sc_length_param.cpp b/ext/systemc/src/sysc/datatypes/int/sc_length_param.cpp
new file mode 100644
index 000000000..c0ba66b6b
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/int/sc_length_param.cpp
@@ -0,0 +1,97 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_length_param.cpp -
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2002-03-19
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// $Log: sc_length_param.cpp,v $
+// Revision 1.2 2011/02/18 20:19:15 acg
+// Andy Goodrich: updating Copyright notice.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:49:32 acg
+// Added $Log command so that CVS check in comments are reproduced in the
+// source.
+//
+
+#include "sysc/datatypes/int/sc_length_param.h"
+
+
+namespace sc_dt
+{
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_length_param
+//
+// Length parameter type.
+// ----------------------------------------------------------------------------
+
+const std::string
+sc_length_param::to_string() const
+{
+ std::string s;
+
+ char buf[BUFSIZ];
+
+ s += "(";
+ std::sprintf( buf, "%d", m_len );
+ s += buf;
+ s += ")";
+
+ return s;
+}
+
+
+void
+sc_length_param::print( ::std::ostream& os ) const
+{
+ os << to_string();
+}
+
+void
+sc_length_param::dump( ::std::ostream& os ) const
+{
+ os << "sc_length_param" << ::std::endl;
+ os << "(" << ::std::endl;
+ os << "len = " << m_len << ::std::endl;
+ os << ")" << ::std::endl;
+}
+
+} // namespace sc_dt
+
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/int/sc_length_param.h b/ext/systemc/src/sysc/datatypes/int/sc_length_param.h
new file mode 100644
index 000000000..aadb52bda
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/int/sc_length_param.h
@@ -0,0 +1,203 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_length_param.h -
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2002-03-19
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_length_param.h,v $
+// Revision 1.3 2011/08/24 22:05:46 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.2 2011/02/18 20:19:15 acg
+// Andy Goodrich: updating Copyright notice.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.4 2006/05/08 17:50:01 acg
+// Andy Goodrich: Added David Long's declarations for friend operators,
+// functions, and methods, to keep the Microsoft compiler happy.
+//
+// Revision 1.3 2006/01/13 18:49:32 acg
+// Added $Log command so that CVS check in comments are reproduced in the
+// source.
+//
+
+#ifndef SC_LENGTH_PARAM_H
+#define SC_LENGTH_PARAM_H
+
+
+#include "sysc/datatypes/fx/sc_context.h"
+
+
+namespace sc_dt
+{
+
+// classes defined in this module
+class sc_length_param;
+
+// friend operator declarations
+ bool operator == ( const sc_length_param&,
+ const sc_length_param& );
+ bool operator != ( const sc_length_param&,
+ const sc_length_param& );
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_length_param
+//
+// Length parameter type.
+// ----------------------------------------------------------------------------
+
+class sc_length_param
+{
+public:
+
+ sc_length_param();
+ sc_length_param( int );
+ sc_length_param( const sc_length_param& );
+ explicit sc_length_param( sc_without_context );
+
+ sc_length_param& operator = ( const sc_length_param& );
+
+ friend bool operator == ( const sc_length_param&,
+ const sc_length_param& );
+ friend bool operator != ( const sc_length_param&,
+ const sc_length_param& );
+
+ int len() const;
+ void len( int );
+
+ const std::string to_string() const;
+
+ void print( ::std::ostream& = ::std::cout ) const;
+ void dump( ::std::ostream& = ::std::cout ) const;
+
+private:
+
+ int m_len;
+};
+
+
+// ----------------------------------------------------------------------------
+// TYPEDEF : sc_length_context
+//
+// Context type for the length parameter type.
+// ----------------------------------------------------------------------------
+
+typedef sc_context<sc_length_param> sc_length_context;
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+inline
+sc_length_param::sc_length_param() : m_len()
+{
+ *this = sc_length_context::default_value();
+}
+
+inline
+sc_length_param::sc_length_param( int len_ ) : m_len(len_)
+{
+ SC_CHECK_WL_( len_ );
+}
+
+inline
+sc_length_param::sc_length_param( const sc_length_param& a )
+ : m_len( a.m_len )
+{}
+
+inline
+sc_length_param::sc_length_param( sc_without_context )
+ : m_len( SC_DEFAULT_WL_ )
+{}
+
+
+inline
+sc_length_param&
+sc_length_param::operator = ( const sc_length_param& a )
+{
+ if( &a != this )
+ {
+ m_len = a.m_len;
+ }
+ return *this;
+}
+
+
+inline
+bool
+operator == ( const sc_length_param& a, const sc_length_param& b )
+{
+ return ( a.m_len == b.m_len );
+}
+
+inline
+bool
+operator != ( const sc_length_param& a, const sc_length_param& b )
+{
+ return ( a.m_len != b.m_len );
+}
+
+
+inline
+int
+sc_length_param::len() const
+{
+ return m_len;
+}
+
+inline
+void
+sc_length_param::len( int len_ )
+{
+ SC_CHECK_WL_( len_ );
+ m_len = len_;
+}
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, const sc_length_param& a )
+{
+ a.print( os );
+ return os;
+}
+
+} // namespace sc_dt
+
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/int/sc_nbcommon.inc b/ext/systemc/src/sysc/datatypes/int/sc_nbcommon.inc
new file mode 100644
index 000000000..89fc4ba83
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/int/sc_nbcommon.inc
@@ -0,0 +1,2989 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_nbcommon.cpp -- Functions common to both sc_signed and sc_unsigned.
+ This file is included in sc_signed.cpp and
+ sc_unsigned.cpp after the macros are defined accordingly.
+ For example, sc_signed.cpp will first define CLASS_TYPE
+ as sc_signed before including this file. This file like
+ sc_nbfriends.cpp and sc_nbexterns.cpp is created in order
+ to ensure only one version of each function, regardless
+ of the class that they interface to.
+
+ Original Author: Ali Dasdan, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// ----------------------------------------------------------------------------
+// SECTION : Public members
+// ----------------------------------------------------------------------------
+
+// Create a CLASS_TYPE number with nb bits.
+CLASS_TYPE::CLASS_TYPE( int nb ) :
+ sc_value_base(), sgn(), nbits(), ndigits(), digit()
+{
+ sgn = default_sign();
+ if( nb > 0 ) {
+ nbits = num_bits( nb );
+ } else {
+ char msg[BUFSIZ];
+ std::sprintf( msg, "%s::%s( int nb ) : nb = %d is not valid",
+ CLASS_TYPE_STR, CLASS_TYPE_STR, nb );
+ SC_REPORT_ERROR( sc_core::SC_ID_INIT_FAILED_, msg );
+ }
+ ndigits = DIV_CEIL(nbits);
+#ifdef SC_MAX_NBITS
+ test_bound(nb);
+#else
+ digit = new sc_digit[ndigits];
+#endif
+ makezero();
+}
+
+
+// Create a copy of v with sgn s. v is of the same type.
+CLASS_TYPE::CLASS_TYPE(const CLASS_TYPE& v) :
+ sc_value_base(v), sgn(v.sgn), nbits(v.nbits), ndigits(v.ndigits), digit()
+{
+#ifndef SC_MAX_NBITS
+ digit = new sc_digit[ndigits];
+#endif
+
+ vec_copy(ndigits, digit, v.digit);
+}
+
+
+// Create a copy of v where v is of the different type.
+CLASS_TYPE::CLASS_TYPE(const OTHER_CLASS_TYPE& v) :
+ sc_value_base(v), sgn(v.sgn), nbits(num_bits(v.nbits)), ndigits(), digit()
+{
+#if (IF_SC_SIGNED == 1)
+ ndigits = v.ndigits;
+#else
+ ndigits = DIV_CEIL(nbits);
+#endif
+
+#ifndef SC_MAX_NBITS
+ digit = new sc_digit[ndigits];
+#endif
+
+ copy_digits(v.nbits, v.ndigits, v.digit);
+}
+
+// Create a copy of v where v is an sign-less instance.
+CLASS_TYPE::CLASS_TYPE(const sc_bv_base& v) :
+ sc_value_base(), sgn(), nbits(), ndigits(), digit()
+{
+ int nb = v.length();
+ sgn = default_sign();
+ if( nb > 0 ) {
+ nbits = num_bits( nb );
+ } else {
+ char msg[BUFSIZ];
+ std::sprintf( msg, "%s::%s( sc_bv_base ) : nb = %d is not valid",
+ CLASS_TYPE_STR, CLASS_TYPE_STR, nb );
+ SC_REPORT_ERROR( sc_core::SC_ID_INIT_FAILED_, msg );
+ }
+ ndigits = DIV_CEIL(nbits);
+# ifdef SC_MAX_NBITS
+ test_bound(nb);
+# else
+ digit = new sc_digit[ndigits];
+# endif
+ makezero();
+ *this = v;
+}
+
+CLASS_TYPE::CLASS_TYPE(const sc_lv_base& v) :
+ sc_value_base(), sgn(), nbits(), ndigits(), digit()
+{
+ int nb = v.length();
+ sgn = default_sign();
+ if( nb > 0 ) {
+ nbits = num_bits( nb );
+ } else {
+ char msg[BUFSIZ];
+ std::sprintf( msg, "%s::%s( sc_lv_base ) : nb = %d is not valid",
+ CLASS_TYPE_STR, CLASS_TYPE_STR, nb );
+ SC_REPORT_ERROR( sc_core::SC_ID_INIT_FAILED_, msg );
+ }
+ ndigits = DIV_CEIL(nbits);
+# ifdef SC_MAX_NBITS
+ test_bound(nb);
+# else
+ digit = new sc_digit[ndigits];
+# endif
+ makezero();
+ *this = v;
+}
+
+CLASS_TYPE::CLASS_TYPE(const sc_int_subref_r& v) :
+ sc_value_base(v), sgn(), nbits(), ndigits(), digit()
+{
+ int nb = v.length();
+ sgn = default_sign();
+ if( nb > 0 ) {
+ nbits = num_bits( nb );
+ } else {
+ char msg[BUFSIZ];
+ std::sprintf( msg, "%s::%s( sc_int_subref ) : nb = %d is not valid",
+ CLASS_TYPE_STR, CLASS_TYPE_STR, nb );
+ SC_REPORT_ERROR( sc_core::SC_ID_INIT_FAILED_, msg );
+ }
+ ndigits = DIV_CEIL(nbits);
+# ifdef SC_MAX_NBITS
+ test_bound(nb);
+# else
+ digit = new sc_digit[ndigits];
+# endif
+ makezero();
+ *this = v.to_uint64();
+}
+
+CLASS_TYPE::CLASS_TYPE(const sc_uint_subref_r& v) :
+ sc_value_base(v), sgn(), nbits(), ndigits(), digit()
+{
+ int nb = v.length();
+ sgn = default_sign();
+ if( nb > 0 ) {
+ nbits = num_bits( nb );
+ } else {
+ char msg[BUFSIZ];
+ std::sprintf( msg, "%s::%s( sc_uint_subref ) : nb = %d is not valid",
+ CLASS_TYPE_STR, CLASS_TYPE_STR, nb );
+ SC_REPORT_ERROR( sc_core::SC_ID_INIT_FAILED_, msg );
+ }
+ ndigits = DIV_CEIL(nbits);
+# ifdef SC_MAX_NBITS
+ test_bound(nb);
+# else
+ digit = new sc_digit[ndigits];
+# endif
+ makezero();
+ *this = v.to_uint64();
+}
+
+CLASS_TYPE::CLASS_TYPE(const sc_signed_subref_r& v) :
+ sc_value_base(v), sgn(), nbits(), ndigits(), digit()
+{
+ int nb = v.length();
+ sgn = default_sign();
+ if( nb > 0 ) {
+ nbits = num_bits( nb );
+ } else {
+ char msg[BUFSIZ];
+ std::sprintf( msg, "%s::%s( sc_signed_subref ) : nb = %d is not valid",
+ CLASS_TYPE_STR, CLASS_TYPE_STR, nb );
+ SC_REPORT_ERROR( sc_core::SC_ID_INIT_FAILED_, msg );
+ }
+ ndigits = DIV_CEIL(nbits);
+# ifdef SC_MAX_NBITS
+ test_bound(nb);
+# else
+ digit = new sc_digit[ndigits];
+# endif
+ makezero();
+ *this = sc_unsigned(v.m_obj_p, v.m_left, v.m_right);
+}
+
+CLASS_TYPE::CLASS_TYPE(const sc_unsigned_subref_r& v) :
+ sc_value_base(v), sgn(), nbits(), ndigits(), digit()
+{
+ int nb = v.length();
+ sgn = default_sign();
+ if( nb > 0 ) {
+ nbits = num_bits( nb );
+ } else {
+ char msg[BUFSIZ];
+ std::sprintf( msg, "%s::%s( sc_unsigned_subref ) : nb = %d is not valid",
+ CLASS_TYPE_STR, CLASS_TYPE_STR, nb );
+ SC_REPORT_ERROR( sc_core::SC_ID_INIT_FAILED_, msg );
+ }
+ ndigits = DIV_CEIL(nbits);
+# ifdef SC_MAX_NBITS
+ test_bound(nb);
+# else
+ digit = new sc_digit[ndigits];
+# endif
+ makezero();
+ *this = sc_unsigned(v.m_obj_p, v.m_left, v.m_right);
+}
+
+// ----------------------------------------------------------------------------
+// SECTION: Public members - Concatenation support.
+// ----------------------------------------------------------------------------
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Public members - Assignment operators.
+// ----------------------------------------------------------------------------
+
+// Assignment from v of the same type.
+const CLASS_TYPE&
+CLASS_TYPE::operator=(const CLASS_TYPE& v)
+{
+ if (this != &v) {
+
+ sgn = v.sgn;
+
+ if (sgn == SC_ZERO)
+ vec_zero(ndigits, digit);
+
+ else
+ copy_digits(v.nbits, v.ndigits, v.digit);
+
+ }
+
+ return *this;
+}
+
+
+// Assignment from v of the different type.
+const CLASS_TYPE&
+CLASS_TYPE::operator=(const OTHER_CLASS_TYPE& v)
+{
+ sgn = v.sgn;
+
+ if (sgn == SC_ZERO)
+ vec_zero(ndigits, digit);
+
+ else
+ copy_digits(v.nbits, v.ndigits, v.digit);
+
+ return *this;
+}
+
+
+// Assignment from an sc_unsigned_subref_r
+const CLASS_TYPE&
+CLASS_TYPE::operator=(const sc_unsigned_subref_r& v)
+{
+ return operator=(sc_unsigned(v));
+}
+
+
+// Assignment from an sc_signed_subref_r
+const CLASS_TYPE&
+CLASS_TYPE::operator=(const sc_signed_subref_r& v)
+{
+ return operator=(sc_unsigned(v));
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Input and output operators
+// ----------------------------------------------------------------------------
+
+void
+CLASS_TYPE::scan( ::std::istream& is )
+{
+ std::string s;
+ is >> s;
+ *this = s.c_str();
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: PLUS operators: +, +=, ++
+// ----------------------------------------------------------------------------
+
+// Cases to consider when computing u + v:
+// 1. 0 + v = v
+// 2. u + 0 = u
+// 3. if sgn(u) == sgn(v)
+// 3.1 u + v = +(u + v) = sgn(u) * (u + v)
+// 3.2 (-u) + (-v) = -(u + v) = sgn(u) * (u + v)
+// 4. if sgn(u) != sgn(v)
+// 4.1 u + (-v) = u - v = sgn(u) * (u - v)
+// 4.2 (-u) + v = -(u - v) ==> sgn(u) * (u - v)
+//
+// Specialization of above cases for computing ++u or u++:
+// 1. 0 + 1 = 1
+// 3. u + 1 = u + 1 = sgn(u) * (u + 1)
+// 4. (-u) + 1 = -(u - 1) = sgn(u) * (u - 1)
+
+const CLASS_TYPE&
+CLASS_TYPE::operator+=(const CLASS_TYPE& v)
+{
+ // u = *this
+
+ if (sgn == SC_ZERO) // case 1
+ return (*this = v);
+
+ if (v.sgn == SC_ZERO) // case 2
+ return *this;
+
+ // cases 3 and 4
+ add_on_help(sgn, nbits, ndigits, digit,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+ convert_SM_to_2C_to_SM();
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator+=(const OTHER_CLASS_TYPE& v)
+{
+ // u = *this
+
+ if (sgn == SC_ZERO) // case 1
+ return (*this = v);
+
+ if (v.sgn == SC_ZERO) // case 2
+ return *this;
+
+ // cases 3 and 4
+ add_on_help(sgn, nbits, ndigits, digit,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+ convert_SM_to_2C_to_SM();
+
+ return *this;
+}
+
+
+CLASS_TYPE&
+CLASS_TYPE::operator++() // prefix
+{
+ *this = *this + 1;
+ return *this;
+}
+
+
+const CLASS_TYPE
+CLASS_TYPE::operator++(int) // postfix
+{
+ // Copy digit into d.
+
+#ifdef SC_MAX_NBITS
+ sc_digit d[MAX_NDIGITS];
+#else
+ sc_digit *d = new sc_digit[ndigits];
+#endif
+
+ small_type s = sgn;
+
+ vec_copy(ndigits, d, digit);
+
+ *this = *this + 1;
+
+ return CLASS_TYPE(s, nbits, ndigits, d);
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator+=(int64 v)
+{
+ // u = *this
+
+ if (sgn == SC_ZERO) // case 1
+ return (*this = v);
+
+ if (v == 0) // case 2
+ return *this;
+
+ CONVERT_INT64(v);
+
+ // cases 3 and 4
+ add_on_help(sgn, nbits, ndigits, digit,
+ vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+ convert_SM_to_2C_to_SM();
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator+=(uint64 v)
+{
+ // u = *this
+
+ if (sgn == SC_ZERO) // case 1
+ return (*this = v);
+
+ if (v == 0) // case 2
+ return *this;
+
+ CONVERT_INT64(v);
+
+ // cases 3 and 4
+ add_on_help(sgn, nbits, ndigits, digit,
+ vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+ convert_SM_to_2C_to_SM();
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator+=(long v)
+{
+ // u = *this
+
+ if (sgn == SC_ZERO) // case 1
+ return (*this = v);
+
+ if (v == 0) // case 2
+ return *this;
+
+ CONVERT_LONG(v);
+
+ // cases 3 and 4
+ add_on_help(sgn, nbits, ndigits, digit,
+ vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+ convert_SM_to_2C_to_SM();
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator+=(unsigned long v)
+{
+ // u = *this
+
+ if (sgn == SC_ZERO) // case 1
+ return (*this = v);
+
+ if (v == 0) // case 2
+ return *this;
+
+ CONVERT_LONG(v);
+
+ // cases 3 and 4
+ add_on_help(sgn, nbits, ndigits, digit,
+ vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+ convert_SM_to_2C_to_SM();
+
+ return *this;
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: MINUS operators: -, -=, --
+// ----------------------------------------------------------------------------
+
+// Cases to consider when computing u + v:
+// 1. u - 0 = u
+// 2. 0 - v = -v
+// 3. if sgn(u) != sgn(v)
+// 3.1 u - (-v) = u + v = sgn(u) * (u + v)
+// 3.2 (-u) - v = -(u + v) ==> sgn(u) * (u + v)
+// 4. if sgn(u) == sgn(v)
+// 4.1 u - v = +(u - v) = sgn(u) * (u - v)
+// 4.2 (-u) - (-v) = -(u - v) = sgn(u) * (u - v)
+//
+// Specialization of above cases for computing --u or u--:
+// 1. 0 - 1 = -1
+// 3. (-u) - 1 = -(u + 1) = sgn(u) * (u + 1)
+// 4. u - 1 = u - 1 = sgn(u) * (u - 1)
+
+const CLASS_TYPE&
+CLASS_TYPE::operator-=(const CLASS_TYPE& v)
+{
+ // u = *this
+
+ if (v.sgn == SC_ZERO) // case 1
+ return *this;
+
+ if (sgn == SC_ZERO) { // case 2
+
+ sgn = -v.sgn;
+ copy_digits(v.nbits, v.ndigits, v.digit);
+
+ }
+ else {
+
+ // cases 3 and 4
+ add_on_help(sgn, nbits, ndigits, digit,
+ -v.sgn, v.nbits, v.ndigits, v.digit);
+
+ convert_SM_to_2C_to_SM();
+
+ }
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator-=(const OTHER_CLASS_TYPE& v)
+{
+ // u = *this
+
+ if (v.sgn == SC_ZERO) // case 1
+ return *this;
+
+ if (sgn == SC_ZERO) { // case 2
+
+ sgn = -v.sgn;
+ copy_digits(v.nbits, v.ndigits, v.digit);
+
+ }
+ else {
+
+ // cases 3 and 4
+ add_on_help(sgn, nbits, ndigits, digit,
+ -v.sgn, v.nbits, v.ndigits, v.digit);
+
+ convert_SM_to_2C_to_SM();
+
+ }
+
+ return *this;
+}
+
+
+CLASS_TYPE&
+CLASS_TYPE::operator--() // prefix
+{
+ *this = *this - 1;
+ return *this;
+}
+
+
+const CLASS_TYPE
+CLASS_TYPE::operator--(int) // postfix
+{
+ // Copy digit into d.
+
+#ifdef SC_MAX_NBITS
+ sc_digit d[MAX_NDIGITS];
+#else
+ sc_digit *d = new sc_digit[ndigits];
+#endif
+
+ small_type s = sgn;
+
+ vec_copy(ndigits, d, digit);
+
+ *this = *this - 1;
+
+ return CLASS_TYPE(s, nbits, ndigits, d);
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator-=(int64 v)
+{
+ // u = *this
+
+ if (v == 0) // case 1
+ return *this;
+
+ if (sgn == SC_ZERO) // case 2
+ return (*this = -v);
+
+ CONVERT_INT64(v);
+
+ // cases 3 and 4
+ add_on_help(sgn, nbits, ndigits, digit,
+ -vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+ convert_SM_to_2C_to_SM();
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator-=(uint64 v)
+{
+ // u = *this
+
+ if (v == 0) // case 1
+ return *this;
+
+ int64 v2 = (int64) v;
+
+ if (sgn == SC_ZERO) // case 2
+ return (*this = -v2);
+
+ CONVERT_INT64(v);
+
+ // cases 3 and 4
+ add_on_help(sgn, nbits, ndigits, digit,
+ -vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+ convert_SM_to_2C_to_SM();
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator-=(long v)
+{
+ // u = *this
+
+ if (v == 0) // case 1
+ return *this;
+
+ if (sgn == SC_ZERO) // case 2
+ return (*this = -v);
+
+ CONVERT_LONG(v);
+
+ // cases 3 and 4
+ add_on_help(sgn, nbits, ndigits, digit,
+ -vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+ convert_SM_to_2C_to_SM();
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator-=(unsigned long v)
+{
+ // u = *this
+
+ if (v == 0) // case 1
+ return *this;
+
+ long v2 = (long) v;
+
+ if (sgn == SC_ZERO) // case 2
+ return (*this = -v2);
+
+ CONVERT_LONG(v);
+
+ // cases 3 and 4
+ add_on_help(sgn, nbits, ndigits, digit,
+ -vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+ convert_SM_to_2C_to_SM();
+
+ return *this;
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: MULTIPLICATION operators: *, *=
+// ----------------------------------------------------------------------------
+
+// Cases to consider when computing u * v:
+// 1. u * 0 = 0 * v = 0
+// 2. 1 * v = v and -1 * v = -v
+// 3. u * 1 = u and u * -1 = -u
+// 4. u * v = u * v
+
+const CLASS_TYPE&
+CLASS_TYPE::operator*=(const CLASS_TYPE& v)
+{
+ // u = *this
+
+ sgn = mul_signs(sgn, v.sgn);
+
+ if (sgn == SC_ZERO) // case 1
+ vec_zero(ndigits, digit);
+
+ else
+ // cases 2-4
+ MUL_ON_HELPER(sgn, nbits, ndigits, digit,
+ v.nbits, v.ndigits, v.digit);
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator*=(const OTHER_CLASS_TYPE& v)
+{
+ // u = *this
+
+ sgn = mul_signs(sgn, v.sgn);
+
+ if (sgn == SC_ZERO) // case 1
+ vec_zero(ndigits, digit);
+
+ else
+ // cases 2-4
+ MUL_ON_HELPER(sgn, nbits, ndigits, digit,
+ v.nbits, v.ndigits, v.digit);
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator*=(int64 v)
+{
+ // u = *this
+
+ sgn = mul_signs(sgn, get_sign(v));
+
+ if (sgn == SC_ZERO) // case 1
+ vec_zero(ndigits, digit);
+
+ else { // cases 2-4
+
+ CONVERT_INT64_2(v);
+
+ MUL_ON_HELPER(sgn, nbits, ndigits, digit,
+ BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+ }
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator*=(uint64 v)
+{
+ // u = *this
+
+ sgn = mul_signs(sgn, get_sign(v));
+
+ if (sgn == SC_ZERO) // case 1
+ vec_zero(ndigits, digit);
+
+ else { // cases 2-4
+
+ CONVERT_INT64_2(v);
+
+ MUL_ON_HELPER(sgn, nbits, ndigits, digit,
+ BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+ }
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator*=(long v)
+{
+ // u = *this
+
+ sgn = mul_signs(sgn, get_sign(v));
+
+ if (sgn == SC_ZERO) // case 1
+ vec_zero(ndigits, digit);
+
+ else { // cases 2-4
+
+ CONVERT_LONG_2(v);
+
+ MUL_ON_HELPER(sgn, nbits, ndigits, digit,
+ BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+ }
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator*=(unsigned long v)
+{
+ // u = *this
+
+ sgn = mul_signs(sgn, get_sign(v));
+
+ if (sgn == SC_ZERO) // case 1
+ vec_zero(ndigits, digit);
+
+ else { // cases 2-4
+
+ CONVERT_LONG_2(v);
+
+ MUL_ON_HELPER(sgn, nbits, ndigits, digit,
+ BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+ }
+
+ return *this;
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: DIVISION operators: /, /=
+// ----------------------------------------------------------------------------
+
+// Cases to consider when finding the quotient q = floor(u/v):
+// Note that u = q * v + r for r < q.
+// 1. 0 / 0 or u / 0 => error
+// 2. 0 / v => 0 = 0 * v + 0
+// 3. u / v && u = v => u = 1 * u + 0 - u or v can be 1 or -1
+// 4. u / v && u < v => u = 0 * v + u - u can be 1 or -1
+// 5. u / v && u > v => u = q * v + r - v can be 1 or -1
+
+const CLASS_TYPE&
+CLASS_TYPE::operator/=(const CLASS_TYPE& v)
+{
+ sgn = mul_signs(sgn, v.sgn);
+
+ if (sgn == SC_ZERO) {
+
+ div_by_zero(v.sgn); // case 1
+ vec_zero(ndigits, digit); // case 2
+
+ }
+ else // other cases
+ DIV_ON_HELPER(sgn, nbits, ndigits, digit,
+ v.nbits, v.ndigits, v.digit);
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator/=(const OTHER_CLASS_TYPE& v)
+{
+ sgn = mul_signs(sgn, v.sgn);
+
+ if (sgn == SC_ZERO) {
+
+ div_by_zero(v.sgn); // case 1
+ vec_zero(ndigits, digit); // case 2
+
+ }
+ else // other cases
+ DIV_ON_HELPER(sgn, nbits, ndigits, digit,
+ v.nbits, v.ndigits, v.digit);
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator/=(int64 v)
+{
+ // u = *this
+
+ sgn = mul_signs(sgn, get_sign(v));
+
+ if (sgn == SC_ZERO) {
+
+ div_by_zero(v); // case 1
+ vec_zero(ndigits, digit); // case 2
+
+ }
+ else {
+
+ CONVERT_INT64_2(v);
+
+ // other cases
+ DIV_ON_HELPER(sgn, nbits, ndigits, digit,
+ BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+ }
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator/=(uint64 v)
+{
+ // u = *this
+
+ sgn = mul_signs(sgn, get_sign(v));
+
+ if (sgn == SC_ZERO) {
+
+ div_by_zero(v); // case 1
+ vec_zero(ndigits, digit); // case 2
+
+ }
+ else {
+
+ CONVERT_INT64_2(v);
+
+ // other cases
+ DIV_ON_HELPER(sgn, nbits, ndigits, digit,
+ BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+ }
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator/=(long v)
+{
+ // u = *this
+
+ sgn = mul_signs(sgn, get_sign(v));
+
+ if (sgn == SC_ZERO) {
+
+ div_by_zero(v); // case 1
+ vec_zero(ndigits, digit); // case 2
+
+ }
+ else {
+
+ CONVERT_LONG_2(v);
+
+ // other cases
+ DIV_ON_HELPER(sgn, nbits, ndigits, digit,
+ BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+ }
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator/=(unsigned long v)
+{
+ // u = *this
+
+ sgn = mul_signs(sgn, get_sign(v));
+
+ if (sgn == SC_ZERO) {
+
+ div_by_zero(v); // case 1
+ vec_zero(ndigits, digit); // case 2
+
+ }
+ else {
+
+ CONVERT_LONG_2(v);
+
+ // other cases
+ DIV_ON_HELPER(sgn, nbits, ndigits, digit,
+ BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+ }
+
+ return *this;
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: MOD operators: %, %=.
+// ----------------------------------------------------------------------------
+
+// Cases to consider when finding the remainder r = u % v:
+// Note that u = q * v + r for r < q.
+// 1. 0 % 0 or u % 0 => error
+// 2. 0 % v => 0 = 0 * v + 0
+// 3. u % v && u = v => u = 1 * u + 0 - u or v can be 1 or -1
+// 4. u % v && u < v => u = 0 * v + u - u can be 1 or -1
+// 5. u % v && u > v => u = q * v + r - v can be 1 or -1
+
+const CLASS_TYPE&
+CLASS_TYPE::operator%=(const CLASS_TYPE& v)
+{
+ if ((sgn == SC_ZERO) || (v.sgn == SC_ZERO)) {
+
+ div_by_zero(v.sgn); // case 1
+ vec_zero(ndigits, digit); // case 2
+
+ }
+ else // other cases
+ MOD_ON_HELPER(sgn, nbits, ndigits, digit,
+ v.nbits, v.ndigits, v.digit);
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator%=(const OTHER_CLASS_TYPE& v)
+{
+ if ((sgn == SC_ZERO) || (v.sgn == SC_ZERO)) {
+
+ div_by_zero(v.sgn); // case 1
+ vec_zero(ndigits, digit); // case 2
+
+ }
+ else // other cases
+ MOD_ON_HELPER(sgn, nbits, ndigits, digit,
+ v.nbits, v.ndigits, v.digit);
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator%=(int64 v)
+{
+ small_type vs = get_sign(v);
+
+ if ((sgn == SC_ZERO) || (vs == SC_ZERO)) {
+
+ div_by_zero(v); // case 1
+ vec_zero(ndigits, digit); // case 2
+
+ }
+ else {
+
+ CONVERT_INT64_2(v);
+
+ // other cases
+ MOD_ON_HELPER(sgn, nbits, ndigits, digit,
+ BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+ }
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator%=(uint64 v)
+{
+ if ((sgn == SC_ZERO) || (v == 0)) {
+
+ div_by_zero(v); // case 1
+ vec_zero(ndigits, digit); // case 2
+
+ }
+ else {
+
+ CONVERT_INT64_2(v);
+
+ // other cases
+ MOD_ON_HELPER(sgn, nbits, ndigits, digit,
+ BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+ }
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator%=(long v)
+{
+ small_type vs = get_sign(v);
+
+ if ((sgn == SC_ZERO) || (vs == SC_ZERO)) {
+
+ div_by_zero(v); // case 1
+ vec_zero(ndigits, digit); // case 2
+
+ }
+ else {
+
+ CONVERT_LONG_2(v);
+
+ // other cases
+ MOD_ON_HELPER(sgn, nbits, ndigits, digit,
+ BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+ }
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator%=(unsigned long v)
+{
+ if ((sgn == SC_ZERO) || (v == 0)) {
+
+ div_by_zero(v); // case 1
+ vec_zero(ndigits, digit); // case 2
+
+ }
+ else {
+
+ CONVERT_LONG_2(v);
+
+ // other cases
+ MOD_ON_HELPER(sgn, nbits, ndigits, digit,
+ BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+ }
+
+ return *this;
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Bitwise AND operators: &, &=
+// ----------------------------------------------------------------------------
+
+// Cases to consider when computing u & v:
+// 1. u & 0 = 0 & v = 0
+// 2. u & v => sgn = +
+// 3. (-u) & (-v) => sgn = -
+// 4. u & (-v) => sgn = +
+// 5. (-u) & v => sgn = +
+
+const CLASS_TYPE&
+CLASS_TYPE::operator&=(const CLASS_TYPE& v)
+{
+ // u = *this
+
+ if ((sgn == SC_ZERO) || (v.sgn == SC_ZERO)) // case 1
+ makezero();
+
+ else { // other cases
+
+ and_on_help(sgn, nbits, ndigits, digit,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+ convert_2C_to_SM();
+
+ }
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator&=(const OTHER_CLASS_TYPE& v)
+{
+ // u = *this
+
+ if ((sgn == SC_ZERO) || (v.sgn == SC_ZERO)) // case 1
+ makezero();
+
+ else { // other cases
+
+ and_on_help(sgn, nbits, ndigits, digit,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+ convert_2C_to_SM();
+
+ }
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator&=(int64 v)
+{
+ // u = *this
+
+ if ((sgn == SC_ZERO) || (v == 0)) // case 1
+ makezero();
+
+ else { // other cases
+
+ CONVERT_INT64(v);
+
+ and_on_help(sgn, nbits, ndigits, digit,
+ vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+ convert_2C_to_SM();
+
+ }
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator&=(uint64 v)
+{
+ // u = *this
+
+ if ((sgn == SC_ZERO) || (v == 0)) // case 1
+ makezero();
+
+ else { // other cases
+
+ CONVERT_INT64(v);
+
+ and_on_help(sgn, nbits, ndigits, digit,
+ vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+ convert_2C_to_SM();
+
+ }
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator&=(long v)
+{
+ // u = *this
+
+ if ((sgn == SC_ZERO) || (v == 0)) // case 1
+ makezero();
+
+ else { // other cases
+
+ CONVERT_LONG(v);
+
+ and_on_help(sgn, nbits, ndigits, digit,
+ vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+ convert_2C_to_SM();
+
+ }
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator&=(unsigned long v)
+{
+ // u = *this
+
+ if ((sgn == SC_ZERO) || (v == 0)) // case 1
+ makezero();
+
+ else { // other cases
+
+ CONVERT_LONG(v);
+
+ and_on_help(sgn, nbits, ndigits, digit,
+ vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+ convert_2C_to_SM();
+
+ }
+
+ return *this;
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Bitwise OR operators: |, |=
+// ----------------------------------------------------------------------------
+
+// Cases to consider when computing u | v:
+// 1. u | 0 = u
+// 2. 0 | v = v
+// 3. u | v => sgn = +
+// 4. (-u) | (-v) => sgn = -
+// 5. u | (-v) => sgn = -
+// 6. (-u) | v => sgn = -
+
+const CLASS_TYPE&
+CLASS_TYPE::operator|=(const CLASS_TYPE& v)
+{
+ if (v.sgn == SC_ZERO) // case 1
+ return *this;
+
+ if (sgn == SC_ZERO) // case 2
+ return (*this = v);
+
+ // other cases
+ or_on_help(sgn, nbits, ndigits, digit,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+ convert_2C_to_SM();
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator|=(const OTHER_CLASS_TYPE& v)
+{
+ if (v.sgn == SC_ZERO) // case 1
+ return *this;
+
+ if (sgn == SC_ZERO) // case 2
+ return (*this = v);
+
+ // other cases
+ or_on_help(sgn, nbits, ndigits, digit,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+ convert_2C_to_SM();
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator|=(int64 v)
+{
+ if (v == 0) // case 1
+ return *this;
+
+ if (sgn == SC_ZERO) // case 2
+ return (*this = v);
+
+ // other cases
+
+ CONVERT_INT64(v);
+
+ or_on_help(sgn, nbits, ndigits, digit,
+ vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+ convert_2C_to_SM();
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator|=(uint64 v)
+{
+ if (v == 0) // case 1
+ return *this;
+
+ if (sgn == SC_ZERO) // case 2
+ return (*this = v);
+
+ // other cases
+
+ CONVERT_INT64(v);
+
+ or_on_help(sgn, nbits, ndigits, digit,
+ vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+ convert_2C_to_SM();
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator|=(long v)
+{
+ if (v == 0) // case 1
+ return *this;
+
+ if (sgn == SC_ZERO) // case 2
+ return (*this = v);
+
+ // other cases
+
+ CONVERT_LONG(v);
+
+ or_on_help(sgn, nbits, ndigits, digit,
+ vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+ convert_2C_to_SM();
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator|=(unsigned long v)
+{
+ if (v == 0) // case 1
+ return *this;
+
+ if (sgn == SC_ZERO) // case 2
+ return (*this = v);
+
+ // other cases
+
+ CONVERT_LONG(v);
+
+ or_on_help(sgn, nbits, ndigits, digit,
+ vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+ convert_2C_to_SM();
+
+ return *this;
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Bitwise XOR operators: ^, ^=
+// ----------------------------------------------------------------------------
+
+// Cases to consider when computing u ^ v:
+// Note that u ^ v = (~u & v) | (u & ~v).
+// 1. u ^ 0 = u
+// 2. 0 ^ v = v
+// 3. u ^ v => sgn = +
+// 4. (-u) ^ (-v) => sgn = -
+// 5. u ^ (-v) => sgn = -
+// 6. (-u) ^ v => sgn = +
+
+const CLASS_TYPE&
+CLASS_TYPE::operator^=(const CLASS_TYPE& v)
+{
+ // u = *this
+
+ if (v.sgn == SC_ZERO) // case 1
+ return *this;
+
+ if (sgn == SC_ZERO) // case 2
+ return (*this = v);
+
+ // other cases
+ xor_on_help(sgn, nbits, ndigits, digit,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+ convert_2C_to_SM();
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator^=(const OTHER_CLASS_TYPE& v)
+{
+ // u = *this
+
+ if (v.sgn == SC_ZERO) // case 1
+ return *this;
+
+ if (sgn == SC_ZERO) // case 2
+ return (*this = v);
+
+ // other cases
+ xor_on_help(sgn, nbits, ndigits, digit,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+ convert_2C_to_SM();
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator^=(int64 v)
+{
+ if (v == 0) // case 1
+ return *this;
+
+ if (sgn == SC_ZERO) // case 2
+ return (*this = v);
+
+ // other cases
+
+ CONVERT_INT64(v);
+
+ xor_on_help(sgn, nbits, ndigits, digit,
+ vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+ convert_2C_to_SM();
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator^=(uint64 v)
+{
+ if (v == 0) // case 1
+ return *this;
+
+ if (sgn == SC_ZERO) // case 2
+ return (*this = v);
+
+ // other cases
+
+ CONVERT_INT64(v);
+
+ xor_on_help(sgn, nbits, ndigits, digit,
+ vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+ convert_2C_to_SM();
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator^=(long v)
+{
+ if (v == 0) // case 1
+ return *this;
+
+ if (sgn == SC_ZERO) // case 2
+ return (*this = v);
+
+ // other cases
+
+ CONVERT_LONG(v);
+
+ xor_on_help(sgn, nbits, ndigits, digit,
+ vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+ convert_2C_to_SM();
+
+ return *this;
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator^=(unsigned long v)
+{
+ if (v == 0) // case 1
+ return *this;
+
+ if (sgn == SC_ZERO) // case 2
+ return (*this = v);
+
+ // other cases
+
+ CONVERT_LONG(v);
+
+ xor_on_help(sgn, nbits, ndigits, digit,
+ vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+ convert_2C_to_SM();
+
+ return *this;
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Bitwise NOT operator: ~
+// ----------------------------------------------------------------------------
+
+CLASS_TYPE
+operator~(const CLASS_TYPE& u)
+{
+ small_type s = u.sgn;
+
+ if (s == SC_ZERO) {
+
+ sc_digit d = 1;
+ return CLASS_TYPE(SC_NEG, u.nbits, 1, &d, false);
+
+ }
+
+ int nd = u.ndigits;
+
+#ifdef SC_MAX_NBITS
+ sc_digit d[MAX_NDIGITS];
+#else
+ sc_digit *d = new sc_digit[nd];
+#endif
+
+ vec_copy(nd, d, u.digit);
+
+ if (s == SC_POS) {
+
+ s = SC_NEG;
+ vec_add_small_on(nd, d, 1);
+
+ }
+ else {
+
+ s = SC_POS;
+ vec_sub_small_on(nd, d, 1);
+
+ if (check_for_zero(nd, d))
+ s = SC_ZERO;
+
+ }
+
+ return CLASS_TYPE(s, u.nbits, nd, d);
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: LEFT SHIFT operators: <<, <<=
+// ----------------------------------------------------------------------------
+
+CLASS_TYPE
+operator<<(const CLASS_TYPE& u, const CLASS_TYPE& v)
+{
+ if (v.sgn == SC_ZERO)
+ return CLASS_TYPE(u);
+
+#ifdef SC_SIGNED
+ if (v.sgn == SC_NEG)
+ return CLASS_TYPE(u);
+#endif
+
+ return operator<<(u, v.to_ulong());
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator<<=(const CLASS_TYPE& v)
+{
+ if (v.sgn == SC_ZERO)
+ return *this;
+
+#ifdef SC_SIGNED
+ if (v.sgn == SC_NEG)
+ return *this;
+#endif
+
+ return operator<<=(v.to_ulong());
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator<<=(const OTHER_CLASS_TYPE& v)
+{
+ if (v.sgn == SC_ZERO)
+ return *this;
+
+#ifdef SC_UNSIGNED
+ if (v.sgn == SC_NEG)
+ return *this;
+#endif
+
+ return operator<<=(v.to_ulong());
+}
+
+
+CLASS_TYPE
+operator<<(const CLASS_TYPE& u, int64 v)
+{
+ if (v <= 0)
+ return CLASS_TYPE(u);
+
+ return operator<<(u, (unsigned long) v);
+}
+
+
+CLASS_TYPE
+operator<<(const CLASS_TYPE& u, uint64 v)
+{
+ if (v == 0)
+ return CLASS_TYPE(u);
+
+ return operator<<(u, (unsigned long) v);
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator<<=(int64 v)
+{
+ if (v <= 0)
+ return *this;
+
+ return operator<<=((unsigned long) v);
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator<<=(uint64 v)
+{
+ if (v == 0)
+ return *this;
+
+ return operator<<=((unsigned long) v);
+}
+
+
+CLASS_TYPE
+operator<<(const CLASS_TYPE& u, long v)
+{
+ if (v <= 0)
+ return CLASS_TYPE(u);
+
+ return operator<<(u, (unsigned long) v);
+}
+
+CLASS_TYPE
+operator<<(const CLASS_TYPE& u, unsigned long v)
+{
+ if (v == 0)
+ return CLASS_TYPE(u);
+
+ if (u.sgn == SC_ZERO)
+ return CLASS_TYPE(u);
+
+ int nb = u.nbits + v;
+ int nd = DIV_CEIL(nb);
+
+#ifdef SC_MAX_NBITS
+ test_bound(nb);
+ sc_digit d[MAX_NDIGITS];
+#else
+ sc_digit *d = new sc_digit[nd];
+#endif
+
+ vec_copy_and_zero(nd, d, u.ndigits, u.digit);
+
+ convert_SM_to_2C(u.sgn, nd, d);
+
+ vec_shift_left(nd, d, v);
+
+ small_type s = convert_signed_2C_to_SM(nb, nd, d);
+
+ return CLASS_TYPE(s, nb, nd, d);
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator<<=(long v)
+{
+ if (v <= 0)
+ return *this;
+
+ return operator<<=((unsigned long) v);
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator<<=(unsigned long v)
+{
+ if (v == 0)
+ return *this;
+
+ if (sgn == SC_ZERO)
+ return *this;
+
+ convert_SM_to_2C();
+
+ vec_shift_left(ndigits, digit, v);
+
+ convert_2C_to_SM();
+
+ return *this;
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: RIGHT SHIFT operators: >>, >>=
+// ----------------------------------------------------------------------------
+
+CLASS_TYPE
+operator>>(const CLASS_TYPE& u, const CLASS_TYPE& v)
+{
+ if (v.sgn == SC_ZERO)
+ return CLASS_TYPE(u);
+
+#ifdef SC_SIGNED
+ if (v.sgn == SC_NEG)
+ return CLASS_TYPE(u);
+#endif
+
+ return operator>>(u, v.to_long());
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator>>=(const CLASS_TYPE& v)
+{
+ if (v.sgn == SC_ZERO)
+ return *this;
+
+#ifdef SC_SIGNED
+ if (v.sgn == SC_NEG)
+ return *this;
+#endif
+
+ return operator>>=(v.to_long());
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator>>=(const OTHER_CLASS_TYPE& v)
+{
+ if (v.sgn == SC_ZERO)
+ return *this;
+
+#ifdef SC_UNSIGNED
+ if (v.sgn == SC_NEG)
+ return *this;
+#endif
+
+ return operator>>=(v.to_ulong());
+}
+
+
+CLASS_TYPE
+operator>>(const CLASS_TYPE& u, int64 v)
+{
+ if (v <= 0)
+ return CLASS_TYPE(u);
+
+ return operator>>(u, (unsigned long) v);
+}
+
+
+CLASS_TYPE
+operator>>(const CLASS_TYPE& u, uint64 v)
+{
+ if (v == 0)
+ return CLASS_TYPE(u);
+
+ return operator>>(u, (unsigned long) v);
+}
+
+const CLASS_TYPE&
+CLASS_TYPE::operator>>=(int64 v)
+{
+ if (v <= 0)
+ return *this;
+
+ return operator>>=((unsigned long) v);
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator>>=(uint64 v)
+{
+ if (v == 0)
+ return *this;
+
+ return operator>>=((unsigned long) v);
+}
+
+
+CLASS_TYPE
+operator>>(const CLASS_TYPE& u, long v)
+{
+ if (v <= 0)
+ return CLASS_TYPE(u);
+
+ return operator>>(u, (unsigned long) v);
+}
+
+
+CLASS_TYPE
+operator>>(const CLASS_TYPE& u, unsigned long v)
+{
+ if (v == 0)
+ return CLASS_TYPE(u);
+
+ if (u.sgn == SC_ZERO)
+ return CLASS_TYPE(u);
+
+ int nb = u.nbits;
+ int nd = u.ndigits;
+
+#ifdef SC_MAX_NBITS
+ sc_digit d[MAX_NDIGITS];
+#else
+ sc_digit *d = new sc_digit[nd];
+#endif
+
+ vec_copy(nd, d, u.digit);
+
+ convert_SM_to_2C(u.sgn, nd, d);
+
+ if (u.sgn == SC_NEG)
+ vec_shift_right(nd, d, v, DIGIT_MASK);
+ else
+ vec_shift_right(nd, d, v, 0);
+
+ small_type s = convert_signed_2C_to_SM(nb, nd, d);
+
+ return CLASS_TYPE(s, nb, nd, d);
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator>>=(long v)
+{
+ if (v <= 0)
+ return *this;
+
+ return operator>>=((unsigned long) v);
+}
+
+
+const CLASS_TYPE&
+CLASS_TYPE::operator>>=(unsigned long v)
+{
+ if (v == 0)
+ return *this;
+
+ if (sgn == SC_ZERO)
+ return *this;
+
+ convert_SM_to_2C();
+
+ if (sgn == SC_NEG)
+ vec_shift_right(ndigits, digit, v, DIGIT_MASK);
+ else
+ vec_shift_right(ndigits, digit, v, 0);
+
+ convert_2C_to_SM();
+
+ return *this;
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: EQUAL TO operator: ==
+// ----------------------------------------------------------------------------
+
+// Defined in the sc_signed.cpp and sc_unsigned.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: NOT_EQUAL operator: !=
+// ----------------------------------------------------------------------------
+
+bool
+operator!=(const CLASS_TYPE& u, const CLASS_TYPE& v)
+{
+ return (! operator==(u, v));
+}
+
+
+bool
+operator!=(const CLASS_TYPE& u, int64 v)
+{
+ return (! operator==(u, v));
+}
+
+
+bool
+operator!=(int64 u, const CLASS_TYPE& v)
+{
+ return (! operator==(u, v));
+}
+
+
+bool
+operator!=(const CLASS_TYPE& u, uint64 v)
+{
+ return (! operator==(u, v));
+}
+
+
+bool
+operator!=(uint64 u, const CLASS_TYPE& v)
+{
+ return (! operator==(u, v));
+}
+
+
+bool
+operator!=(const CLASS_TYPE& u, long v)
+{
+ return (! operator==(u, v));
+}
+
+
+bool
+operator!=(long u, const CLASS_TYPE& v)
+{
+ return (! operator==(u, v));
+}
+
+
+bool
+operator!=(const CLASS_TYPE& u, unsigned long v)
+{
+ return (! operator==(u, v));
+}
+
+
+bool
+operator!=(unsigned long u, const CLASS_TYPE& v)
+{
+ return (! operator==(u, v));
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: LESS THAN operator: <
+// ----------------------------------------------------------------------------
+
+// Defined in the sc_signed.cpp and sc_unsigned.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: LESS THAN or EQUAL operator: <=
+// ----------------------------------------------------------------------------
+
+bool
+operator<=(const CLASS_TYPE& u, const CLASS_TYPE& v)
+{
+ return (operator<(u, v) || operator==(u, v));
+}
+
+
+bool
+operator<=(const CLASS_TYPE& u, int64 v)
+{
+ return (operator<(u, v) || operator==(u, v));
+}
+
+
+bool
+operator<=(int64 u, const CLASS_TYPE& v)
+{
+ return (operator<(u, v) || operator==(u, v));
+}
+
+
+bool
+operator<=(const CLASS_TYPE& u, uint64 v)
+{
+ return (operator<(u, v) || operator==(u, v));
+}
+
+
+bool
+operator<=(uint64 u, const CLASS_TYPE& v)
+{
+ return (operator<(u, v) || operator==(u, v));
+}
+
+
+bool
+operator<=(const CLASS_TYPE& u, long v)
+{
+ return (operator<(u, v) || operator==(u, v));
+}
+
+
+bool
+operator<=(long u, const CLASS_TYPE& v)
+{
+ return (operator<(u, v) || operator==(u, v));
+}
+
+
+bool
+operator<=(const CLASS_TYPE& u, unsigned long v)
+{
+ return (operator<(u, v) || operator==(u, v));
+}
+
+
+bool
+operator<=(unsigned long u, const CLASS_TYPE& v)
+{
+ return (operator<(u, v) || operator==(u, v));
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: GREATER THAN operator: >
+// ----------------------------------------------------------------------------
+
+bool
+operator>(const CLASS_TYPE& u, const CLASS_TYPE& v)
+{
+ return (! (operator<=(u, v)));
+}
+
+
+bool
+operator>(const CLASS_TYPE& u, int64 v)
+{
+ return (! (operator<=(u, v)));
+}
+
+
+bool
+operator>(int64 u, const CLASS_TYPE& v)
+{
+ return (! (operator<=(u, v)));
+}
+
+
+bool
+operator>(const CLASS_TYPE& u, uint64 v)
+{
+ return (! (operator<=(u, v)));
+}
+
+
+bool
+operator>(uint64 u, const CLASS_TYPE& v)
+{
+ return (! (operator<=(u, v)));
+}
+
+
+bool
+operator>(const CLASS_TYPE& u, long v)
+{
+ return (! (operator<=(u, v)));
+}
+
+
+bool
+operator>(long u, const CLASS_TYPE& v)
+{
+ return (! (operator<=(u, v)));
+}
+
+
+bool
+operator>(const CLASS_TYPE& u, unsigned long v)
+{
+ return (! (operator<=(u, v)));
+}
+
+
+bool
+operator>(unsigned long u, const CLASS_TYPE& v)
+{
+ return (! (operator<=(u, v)));
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: GREATER THAN or EQUAL operator: >=
+// ----------------------------------------------------------------------------
+
+bool
+operator>=(const CLASS_TYPE& u, const CLASS_TYPE& v)
+{
+ return (! (operator<(u, v)));
+}
+
+
+bool
+operator>=(const CLASS_TYPE& u, int64 v)
+{
+ return (! (operator<(u, v)));
+}
+
+
+bool
+operator>=(int64 u, const CLASS_TYPE& v)
+{
+ return (! (operator<(u, v)));
+}
+
+
+bool
+operator>=(const CLASS_TYPE& u, uint64 v)
+{
+ return (! (operator<(u, v)));
+}
+
+
+bool
+operator>=(uint64 u, const CLASS_TYPE& v)
+{
+ return (! (operator<(u, v)));
+}
+
+
+bool
+operator>=(const CLASS_TYPE& u, long v)
+{
+ return (! (operator<(u, v)));
+}
+
+
+bool
+operator>=(long u, const CLASS_TYPE& v)
+{
+ return (! (operator<(u, v)));
+}
+
+
+bool
+operator>=(const CLASS_TYPE& u, unsigned long v)
+{
+ return (! (operator<(u, v)));
+}
+
+
+bool
+operator>=(unsigned long u, const CLASS_TYPE& v)
+{
+ return (! (operator<(u, v)));
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Public members - Other utils.
+// ----------------------------------------------------------------------------
+
+// Convert to int64, long, or int.
+#define TO_INTX(RET_TYPE, UP_RET_TYPE) \
+ \
+if (sgn == SC_ZERO) \
+return 0; \
+ \
+int vnd = sc_min((int)DIGITS_PER_ ## UP_RET_TYPE, ndigits); \
+ \
+RET_TYPE v = 0; \
+while (--vnd >= 0) \
+v = (v << BITS_PER_DIGIT) + digit[vnd]; \
+ \
+if (sgn == SC_NEG) \
+return -v; \
+else \
+return v;
+
+
+int64
+CLASS_TYPE::to_int64() const
+{
+ TO_INTX(int64, INT64);
+}
+
+
+long
+CLASS_TYPE::to_long() const
+{
+ TO_INTX(long, LONG);
+}
+
+
+int
+CLASS_TYPE::to_int() const
+{
+ TO_INTX(int, INT);
+}
+
+
+// Convert to unsigned int64, unsigned long or unsigned
+// int. to_uint64, to_ulong, and to_uint have the same body except for
+// the type of v defined inside.
+uint64
+CLASS_TYPE::to_uint64() const
+{
+ if (sgn == SC_ZERO)
+ return 0;
+
+ int vnd = sc_min((int)DIGITS_PER_INT64, ndigits);
+
+ uint64 v = 0;
+
+ if (sgn == SC_NEG) {
+
+#ifdef SC_MAX_NBITS
+ sc_digit d[MAX_NDIGITS];
+#else
+ sc_digit *d = new sc_digit[ndigits];
+#endif
+
+ vec_copy(ndigits, d, digit);
+
+ convert_SM_to_2C_trimmed(IF_SC_SIGNED, sgn, nbits, ndigits, d);
+
+ while (--vnd >= 0)
+ v = (v << BITS_PER_DIGIT) + d[vnd];
+
+#ifndef SC_MAX_NBITS
+ delete [] d;
+#endif
+
+ }
+ else {
+
+ while (--vnd >= 0)
+ v = (v << BITS_PER_DIGIT) + digit[vnd];
+
+ }
+
+ return v;
+}
+
+
+unsigned long
+CLASS_TYPE::to_ulong() const
+{
+ if (sgn == SC_ZERO)
+ return 0;
+
+ int vnd = sc_min((int)DIGITS_PER_LONG, ndigits);
+
+ unsigned long v = 0;
+
+ if (sgn == SC_NEG) {
+
+#ifdef SC_MAX_NBITS
+ sc_digit d[MAX_NDIGITS];
+#else
+ sc_digit *d = new sc_digit[ndigits];
+#endif
+
+ vec_copy(ndigits, d, digit);
+
+ convert_SM_to_2C_trimmed(IF_SC_SIGNED, sgn, nbits, ndigits, d);
+
+ while (--vnd >= 0)
+ v = (v << BITS_PER_DIGIT) + d[vnd];
+
+#ifndef SC_MAX_NBITS
+ delete [] d;
+#endif
+
+ }
+ else {
+
+ while (--vnd >= 0)
+ v = (v << BITS_PER_DIGIT) + digit[vnd];
+
+ }
+
+ return v;
+}
+
+
+unsigned int
+CLASS_TYPE::to_uint() const
+{
+ if (sgn == SC_ZERO)
+ return 0;
+
+ int vnd = sc_min((int)DIGITS_PER_INT, ndigits);
+
+ unsigned int v = 0;
+
+ if (sgn == SC_NEG) {
+
+#ifdef SC_MAX_NBITS
+ sc_digit d[MAX_NDIGITS];
+#else
+ sc_digit *d = new sc_digit[ndigits];
+#endif
+
+ vec_copy(ndigits, d, digit);
+
+ convert_SM_to_2C_trimmed(IF_SC_SIGNED, sgn, nbits, ndigits, d);
+
+ while (--vnd >= 0)
+ v = (v << BITS_PER_DIGIT) + d[vnd];
+
+#ifndef SC_MAX_NBITS
+ delete [] d;
+#endif
+
+ }
+ else {
+
+ while (--vnd >= 0)
+ v = (v << BITS_PER_DIGIT) + digit[vnd];
+
+ }
+
+ return v;
+}
+
+
+// Convert to double.
+double
+CLASS_TYPE::to_double() const
+{
+ if (sgn == SC_ZERO)
+ return (double) 0.0;
+
+ int vnd = ndigits;
+
+ double v = 0.0;
+ while (--vnd >= 0)
+ v = v * DIGIT_RADIX + digit[vnd];
+
+ if (sgn == SC_NEG)
+ return -v;
+ else
+ return v;
+}
+
+
+// Return true if the bit i is 1, false otherwise. If i is outside the
+// bounds, return 1/0 according to the sign of the number by assuming
+// that the number has infinite length.
+
+bool
+CLASS_TYPE::test(int i) const
+{
+#ifdef SC_SIGNED
+ if (check_if_outside(i)) {
+ if (sgn == SC_NEG)
+ return 1;
+ else
+ return 0;
+ }
+#else
+ if (check_if_outside(i))
+ return 0;
+#endif
+
+ int bit_num = bit_ord(i);
+ int digit_num = digit_ord(i);
+
+ if (sgn == SC_NEG) {
+
+#ifdef SC_MAX_NBITS
+ sc_digit d[MAX_NDIGITS];
+#else
+ sc_digit *d = new sc_digit[ndigits];
+#endif
+
+ vec_copy(ndigits, d, digit);
+ vec_complement(ndigits, d);
+ bool val = ((d[digit_num] & one_and_zeros(bit_num)) != 0);
+
+#ifndef SC_MAX_NBITS
+ delete [] d;
+#endif
+
+ return val;
+
+ }
+ else
+ return ((digit[digit_num] & one_and_zeros(bit_num)) != 0);
+}
+
+
+// Set the ith bit with 1.
+void
+CLASS_TYPE::set(int i)
+{
+ if (check_if_outside(i))
+ return;
+
+ int bit_num = bit_ord(i);
+ int digit_num = digit_ord(i);
+
+ convert_SM_to_2C();
+ digit[digit_num] |= one_and_zeros(bit_num);
+ digit[digit_num] &= DIGIT_MASK; // Needed to zero the overflow bits.
+ convert_2C_to_SM();
+}
+
+
+// Set the ith bit with 0, i.e., clear the ith bit.
+void
+CLASS_TYPE::clear(int i)
+{
+ if (check_if_outside(i))
+ return;
+
+ int bit_num = bit_ord(i);
+ int digit_num = digit_ord(i);
+
+ convert_SM_to_2C();
+ digit[digit_num] &= ~(one_and_zeros(bit_num));
+ digit[digit_num] &= DIGIT_MASK; // Needed to zero the overflow bits.
+ convert_2C_to_SM();
+}
+
+
+// Create a mirror image of the number.
+void
+CLASS_TYPE::reverse()
+{
+ convert_SM_to_2C();
+ vec_reverse(length(), ndigits, digit, length() - 1);
+ convert_2C_to_SM();
+}
+
+
+// Get a packed bit representation of the number.
+void
+CLASS_TYPE::get_packed_rep(sc_digit *buf) const
+{
+ int buf_ndigits = (length() - 1) / BITS_PER_DIGIT_TYPE + 1;
+
+ // Initialize buf to zero.
+ vec_zero(buf_ndigits, buf);
+
+ if (sgn == SC_ZERO)
+ return;
+
+ const sc_digit *digit_or_d;
+#ifdef SC_MAX_NBITS
+ sc_digit d[MAX_NDIGITS];
+#else
+ sc_digit *d = new sc_digit[ndigits];
+#endif
+
+ if (sgn == SC_POS)
+ digit_or_d = digit;
+
+ else
+ {
+ // If sgn is negative, we have to convert digit to its 2's
+ // complement. Since this function is const, we can not do it on
+ // digit. Since buf doesn't have overflow bits, we cannot also do
+ // it on buf. Thus, we have to do the complementation on a copy of
+ // digit, i.e., on d.
+
+ vec_copy(ndigits, d, digit);
+ vec_complement(ndigits, d);
+
+ buf[buf_ndigits - 1] = ~((sc_digit) 0);
+
+ digit_or_d = d;
+
+ }
+
+ // Copy the bits from digit to buf. The division and mod operations
+ // below can be converted to addition/subtraction and comparison
+ // operations at the expense of complicating the code. We can do it
+ // if we see any performance problems.
+
+ for (int i = length() - 1; i >= 0; --i) {
+
+ if ((digit_or_d[digit_ord(i)] & one_and_zeros(bit_ord(i))) != 0) // Test.
+
+ buf[i / BITS_PER_DIGIT_TYPE] |=
+ one_and_zeros(i % BITS_PER_DIGIT_TYPE); // Set.
+
+ else
+
+ buf[i / BITS_PER_DIGIT_TYPE] &=
+ ~(one_and_zeros(i % BITS_PER_DIGIT_TYPE)); // Clear.
+
+ }
+
+#ifndef SC_MAX_NBITS
+ delete[] d;
+#endif
+}
+
+
+// Set a packed bit representation of the number.
+void
+CLASS_TYPE::set_packed_rep(sc_digit *buf)
+{
+ // Initialize digit to zero.
+ vec_zero(ndigits, digit);
+
+ // Copy the bits from buf to digit.
+ for (int i = length() - 1; i >= 0; --i) {
+
+ if ((buf[i / BITS_PER_DIGIT_TYPE] &
+ one_and_zeros(i % BITS_PER_DIGIT_TYPE)) != 0) // Test.
+
+ digit[digit_ord(i)] |= one_and_zeros(bit_ord(i)); // Set.
+
+ else
+
+ digit[digit_ord(i)] &= ~(one_and_zeros(bit_ord(i))); // Clear
+
+ }
+
+ convert_2C_to_SM();
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Private members.
+// ----------------------------------------------------------------------------
+
+// Create a copy of v with sgn s.
+CLASS_TYPE::CLASS_TYPE(const CLASS_TYPE& v, small_type s) :
+ sc_value_base(v), sgn(s), nbits(v.nbits), ndigits(v.ndigits), digit()
+{
+#ifndef SC_MAX_NBITS
+ digit = new sc_digit[ndigits];
+#endif
+
+ vec_copy(ndigits, digit, v.digit);
+}
+
+
+// Create a copy of v where v is of the different type.
+CLASS_TYPE::CLASS_TYPE(const OTHER_CLASS_TYPE& v, small_type s) :
+ sc_value_base(v), sgn(s), nbits(num_bits(v.nbits)), ndigits(), digit()
+{
+#if (IF_SC_SIGNED == 1)
+ ndigits = v.ndigits;
+#else
+ ndigits = DIV_CEIL(nbits);
+#endif
+
+#ifndef SC_MAX_NBITS
+ digit = new sc_digit[ndigits];
+#endif
+
+ copy_digits(v.nbits, v.ndigits, v.digit);
+}
+
+
+// Create a signed number with (s, nb, nd, d) as its attributes (as
+// defined in class CLASS_TYPE). If alloc is set, delete d.
+CLASS_TYPE::CLASS_TYPE(small_type s, int nb,
+ int nd, sc_digit *d,
+ bool alloc) :
+ sc_value_base(), sgn(s), nbits(num_bits(nb)), ndigits(), digit()
+{
+ ndigits = DIV_CEIL(nbits);
+
+#ifndef SC_MAX_NBITS
+ digit = new sc_digit[ndigits];
+#endif
+
+ if (ndigits <= nd)
+ vec_copy(ndigits, digit, d);
+ else
+ vec_copy_and_zero(ndigits, digit, nd, d);
+
+#ifndef SC_MAX_NBITS
+ if (alloc)
+ delete [] d;
+#endif
+}
+
+// This constructor is mainly used in finding a "range" of bits from a
+// number of type CLASS_TYPE. The function range(l, r) can have
+// arbitrary precedence between l and r. If l is smaller than r, then
+// the output is the reverse of range(r, l).
+CLASS_TYPE::CLASS_TYPE(const CLASS_TYPE* u, int l, int r) :
+ sc_value_base(), sgn(), nbits(), ndigits(), digit()
+{
+ bool reversed = false;
+
+ if( l < r ) {
+ reversed = true;
+ int tmp = l;
+ l = r;
+ r = tmp;
+ }
+
+ // at this point, l >= r
+
+ // make sure that l and r point to the bits of u
+ r = sc_max( r, 0 );
+ l = sc_min( l, u->nbits - 1 );
+
+ nbits = num_bits( l - r + 1 );
+
+ // nbits can still be <= 0 because l and r have just been updated
+ // with the bounds of u.
+
+ // if u == 0 or the range is out of bounds, return 0
+ if( u->sgn == SC_ZERO || nbits <= num_bits( 0 ) ) {
+ sgn = SC_ZERO;
+ if( nbits <= num_bits( 0 ) ) {
+ nbits = 1;
+ }
+ ndigits = DIV_CEIL( nbits );
+#ifndef SC_MAX_NBITS
+ digit = new sc_digit[ndigits];
+#endif
+ vec_zero( ndigits, digit );
+ return;
+ }
+
+ // The rest will be executed if u is not zero.
+
+ ndigits = DIV_CEIL(nbits);
+
+ // The number of bits up to and including l and r, respectively.
+ int nl = l + 1;
+ int nr = r + 1;
+
+ // The indices of the digits that have lth and rth bits, respectively.
+ int left_digit = DIV_CEIL(nl) - 1;
+ int right_digit = DIV_CEIL(nr) - 1;
+
+ int nd;
+
+ // The range is performed on the 2's complement representation, so
+ // first get the indices for that.
+ if (u->sgn == SC_NEG)
+ nd = left_digit + 1;
+ else
+ nd = left_digit - right_digit + 1;
+
+ // Allocate memory for the range.
+#ifdef SC_MAX_NBITS
+ sc_digit d[MAX_NDIGITS];
+#else
+ digit = new sc_digit[ndigits];
+ sc_digit *d = new sc_digit[nd];
+#endif
+
+ // Getting the range on the 2's complement representation.
+ if (u->sgn == SC_NEG) {
+
+ vec_copy(nd, d, u->digit);
+ vec_complement(nd, d); // d = -d;
+ vec_shift_right(nd, d, r, DIGIT_MASK);
+
+ }
+ else {
+
+ for (int i = right_digit; i <= left_digit; ++i)
+ d[i - right_digit] = u->digit[i];
+
+ vec_shift_right(nd, d, r - right_digit * BITS_PER_DIGIT, 0);
+
+ }
+
+ vec_zero(ndigits, digit);
+
+ if (! reversed)
+ vec_copy(sc_min(nd, ndigits), digit, d);
+
+ else {
+
+ // If l < r, i.e., reversed is set, reverse the bits of digit. d
+ // will be used as a temporary store. The following code tries to
+ // minimize the use of bit_ord and digit_ord, which use mod and
+ // div operators. Since these operators are function calls to
+ // standard library routines, they are slow. The main idea in
+ // reversing is "read bits out of d from left to right and push
+ // them into digit using right shifting."
+
+ // Take care of the last digit.
+ int nd_less_1 = nd - 1;
+
+ // Deletions will start from the left end and move one position
+ // after each deletion.
+ sc_digit del_mask = one_and_zeros(bit_ord(l - r));
+
+ while (del_mask) {
+ vec_shift_right(ndigits, digit, 1, ((d[nd_less_1] & del_mask) != 0));
+ del_mask >>= 1;
+ }
+
+ // Take care of the other digits if any.
+
+ // Insertion to digit will always occur at the left end.
+ sc_digit ins_mask = one_and_zeros(BITS_PER_DIGIT - 1);
+
+ for (int j = nd - 2; j >= 0; --j) { // j = nd - 2
+
+ // Deletions will start from the left end and move one position
+ // after each deletion.
+ del_mask = ins_mask;
+
+ while (del_mask) {
+ vec_shift_right(ndigits, digit, 1, ((d[j] & del_mask) != 0));
+ del_mask >>= 1;
+ }
+ }
+
+ if (u->sgn == SC_NEG)
+ vec_shift_right(ndigits, digit,
+ ndigits * BITS_PER_DIGIT - length(), DIGIT_MASK);
+ else
+ vec_shift_right(ndigits, digit,
+ ndigits * BITS_PER_DIGIT - length(), 0);
+
+
+ } // if reversed.
+
+ convert_2C_to_SM();
+
+#ifndef SC_MAX_NBITS
+ delete [] d;
+#endif
+}
+
+// This constructor is mainly used in finding a "range" of bits from a
+// number of type OTHER_CLASS_TYPE. The function range(l, r) can have
+// arbitrary precedence between l and r. If l is smaller than r, then
+// the output is the reverse of range(r, l).
+CLASS_TYPE::CLASS_TYPE(const OTHER_CLASS_TYPE* u, int l, int r) :
+ sc_value_base(), sgn(), nbits(), ndigits(), digit()
+{
+ bool reversed = false;
+
+ if( l < r ) {
+ reversed = true;
+ int tmp = l;
+ l = r;
+ r = tmp;
+ }
+
+ // at this point, l >= r
+
+ // make sure that l and r point to the bits of u
+ r = sc_max( r, 0 );
+ l = sc_min( l, u->nbits - 1 );
+
+ nbits = num_bits( l - r + 1 );
+
+ // nbits can still be <= 0 because l and r have just been updated
+ // with the bounds of u.
+
+ // if u == 0 or the range is out of bounds, return 0
+ if( u->sgn == SC_ZERO || nbits <= num_bits( 0 ) ) {
+ sgn = SC_ZERO;
+ if( nbits <= num_bits( 0 ) ) {
+ nbits = 1;
+ }
+ ndigits = DIV_CEIL( nbits );
+#ifndef SC_MAX_NBITS
+ digit = new sc_digit[ndigits];
+#endif
+ vec_zero( ndigits, digit );
+ return;
+ }
+
+ // The rest will be executed if u is not zero.
+
+ ndigits = DIV_CEIL(nbits);
+
+ // The number of bits up to and including l and r, respectively.
+ int nl = l + 1;
+ int nr = r + 1;
+
+ // The indices of the digits that have lth and rth bits, respectively.
+ int left_digit = DIV_CEIL(nl) - 1;
+ int right_digit = DIV_CEIL(nr) - 1;
+
+ int nd;
+
+ // The range is performed on the 2's complement representation, so
+ // first get the indices for that.
+ if (u->sgn == SC_NEG)
+ nd = left_digit + 1;
+ else
+ nd = left_digit - right_digit + 1;
+
+ // Allocate memory for the range.
+#ifdef SC_MAX_NBITS
+ sc_digit d[MAX_NDIGITS];
+#else
+ digit = new sc_digit[ndigits];
+ sc_digit *d = new sc_digit[nd];
+#endif
+
+ // Getting the range on the 2's complement representation.
+ if (u->sgn == SC_NEG) {
+
+ vec_copy(nd, d, u->digit);
+ vec_complement(nd, d); // d = -d;
+ vec_shift_right(nd, d, r, DIGIT_MASK);
+
+ }
+ else {
+
+ for (int i = right_digit; i <= left_digit; ++i)
+ d[i - right_digit] = u->digit[i];
+
+ vec_shift_right(nd, d, r - right_digit * BITS_PER_DIGIT, 0);
+
+ }
+
+ vec_zero(ndigits, digit);
+
+ if (! reversed)
+ vec_copy(sc_min(nd, ndigits), digit, d);
+
+ else {
+
+ // If l < r, i.e., reversed is set, reverse the bits of digit. d
+ // will be used as a temporary store. The following code tries to
+ // minimize the use of bit_ord and digit_ord, which use mod and
+ // div operators. Since these operators are function calls to
+ // standard library routines, they are slow. The main idea in
+ // reversing is "read bits out of d from left to right and push
+ // them into digit using right shifting."
+
+ // Take care of the last digit.
+ int nd_less_1 = nd - 1;
+
+ // Deletions will start from the left end and move one position
+ // after each deletion.
+ sc_digit del_mask = one_and_zeros(bit_ord(l - r));
+
+ while (del_mask) {
+ vec_shift_right(ndigits, digit, 1, ((d[nd_less_1] & del_mask) != 0));
+ del_mask >>= 1;
+ }
+
+ // Take care of the other digits if any.
+
+ // Insertion to digit will always occur at the left end.
+ sc_digit ins_mask = one_and_zeros(BITS_PER_DIGIT - 1);
+
+ for (int j = nd - 2; j >= 0; --j) { // j = nd - 2
+
+ // Deletions will start from the left end and move one position
+ // after each deletion.
+ del_mask = ins_mask;
+
+ while (del_mask) {
+ vec_shift_right(ndigits, digit, 1, ((d[j] & del_mask) != 0));
+ del_mask >>= 1;
+ }
+ }
+
+ if (u->sgn == SC_NEG)
+ vec_shift_right(ndigits, digit,
+ ndigits * BITS_PER_DIGIT - length(), DIGIT_MASK);
+ else
+ vec_shift_right(ndigits, digit,
+ ndigits * BITS_PER_DIGIT - length(), 0);
+
+
+ } // if reversed.
+
+ convert_2C_to_SM();
+
+#ifndef SC_MAX_NBITS
+ delete [] d;
+#endif
+}
+
+
+// Print out all the physical attributes.
+void
+CLASS_TYPE::dump(::std::ostream& os) const
+{
+ // Save the current setting, and set the base to decimal.
+#if defined(__MINGW32__)
+ std::_Ios_Fmtflags old_flags = os.setf(::std::ios::dec,::std::ios::basefield);
+#else
+ fmtflags old_flags = os.setf(::std::ios::dec, ::std::ios::basefield);
+#endif
+
+ os << "width = " << length() << ::std::endl;
+ os << "value = " << *this << ::std::endl;
+ os << "bits = ";
+
+ int len = length();
+
+ for (int i = len - 1; i >= 0; --i) {
+
+ os << "01"[test(i)];
+ if (--len % 4 == 0)
+ os << " ";
+
+ }
+
+ os << ::std::endl;
+
+ // Restore old_flags.
+ os.setf(old_flags, ::std::ios::basefield);
+}
+
+
+// Checks to see if bit_num is out of bounds.
+bool
+CLASS_TYPE::check_if_outside(int bit_num) const
+{
+ if ((bit_num < 0) || (num_bits(bit_num) >= nbits)) {
+
+#ifdef DEBUG_SYSTEMC
+ if( bit_num < 0 || bit_num >= nbits ) {
+ char msg[BUFSIZ];
+ std::sprintf( msg, "%s::check_if_outside( int bit_num ) : "
+ "bit_num = %d is out of bounds",
+ CLASS_TYPE_STR, bit_num );
+ SC_REPORT_WARNING( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
+ }
+#endif
+
+ return true;
+ }
+
+ return false;
+}
+
+// End of file.
diff --git a/ext/systemc/src/sysc/datatypes/int/sc_nbdefs.cpp b/ext/systemc/src/sysc/datatypes/int/sc_nbdefs.cpp
new file mode 100644
index 000000000..48f2d39de
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/int/sc_nbdefs.cpp
@@ -0,0 +1,93 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_nbdefs.h -- Top level header file for arbitrary precision signed/unsigned
+ arithmetic. This file defines all the constants needed.
+
+ Original Author: Ali Dasdan, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// $Log: sc_nbdefs.cpp,v $
+// Revision 1.3 2011/02/18 20:19:15 acg
+// Andy Goodrich: updating Copyright notice.
+//
+// Revision 1.2 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:49:32 acg
+// Added $Log command so that CVS check in comments are reproduced in the
+// source.
+//
+
+#include "sysc/datatypes/int/sc_nbdefs.h"
+
+
+namespace sc_dt
+{
+
+#ifdef SC_MAX_NBITS
+const int MAX_NDIGITS = DIV_CEIL(SC_MAX_NBITS) + 2;
+// Consider a number with x bits another with y bits. The maximum
+// number of bits happens when we multiply them. The result will have
+// (x + y) bits. Assume that x + y <= SC_MAX_NBITS. Then, DIV_CEIL(x) +
+// DIV_CEIL(y) <= DIV_CEIL(SC_MAX_NBITS) + 2. This is the reason for +2
+// above. With this change, MAX_NDIGITS must be enough to hold the
+// result of any operation.
+#endif
+
+// Support for the long long type. This type is not in the standard
+// but is usually supported by compilers.
+#if !defined(_WIN32) || defined(__MINGW32__)
+const uint64 UINT64_ZERO = 0ULL;
+const uint64 UINT64_ONE = 1ULL;
+const uint64 UINT64_32ONES = 0x00000000ffffffffULL;
+#else
+const uint64 UINT64_ZERO = 0i64;
+const uint64 UINT64_ONE = 1i64;
+const uint64 UINT64_32ONES = 0x00000000ffffffffi64;
+#endif
+
+const small_type NB_DEFAULT_BASE = SC_DEC;
+
+#ifndef _32BIT_
+const uint64 UINT_ZERO = UINT64_ZERO;
+const uint64 UINT_ONE = UINT64_ONE;
+#else
+const unsigned int UINT_ZERO = 0U;
+const unsigned int UINT_ONE = 1U;
+#endif
+
+} // namespace sc_dt
diff --git a/ext/systemc/src/sysc/datatypes/int/sc_nbdefs.h b/ext/systemc/src/sysc/datatypes/int/sc_nbdefs.h
new file mode 100644
index 000000000..0d70b74ea
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/int/sc_nbdefs.h
@@ -0,0 +1,282 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_nbdefs.h -- Top level header file for arbitrary precision signed/unsigned
+ arithmetic. This file defines all the constants needed.
+
+ Original Author: Ali Dasdan, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_nbdefs.h,v $
+// Revision 1.7 2011/02/18 20:19:15 acg
+// Andy Goodrich: updating Copyright notice.
+//
+// Revision 1.6 2011/02/18 20:09:34 acg
+// Philipp A. Hartmann: added alternative #define for Windows to guard.
+//
+// Revision 1.5 2011/01/20 16:52:20 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.4 2010/02/08 18:35:55 acg
+// Andy Goodrich: Philipp Hartmann's changes for Solaris and Linux 64.
+//
+// Revision 1.2 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:49:32 acg
+// Added $Log command so that CVS check in comments are reproduced in the
+// source.
+//
+
+#ifndef SC_NBDEFS_H
+#define SC_NBDEFS_H
+
+
+#include "sysc/kernel/sc_cmnhdr.h"
+
+#include <climits>
+
+#if defined(__sun) || defined(__sun__)
+# include <inttypes.h>
+#elif !defined(WIN32) && !defined(_WIN32)
+# include <stdint.h>
+#endif
+
+#include "sysc/utils/sc_iostream.h"
+#include "sysc/kernel/sc_constants.h" // For SC_MAX_NBITS
+
+// Activate support mixed operands for concatenation via the comma operator
+#define SC_DT_MIXED_COMMA_OPERATORS
+
+
+namespace sc_dt
+{
+
+// ----------------------------------------------------------------------------
+// ENUM : sc_numrep
+//
+// Enumeration of number representations for character string conversion.
+// ----------------------------------------------------------------------------
+
+enum sc_numrep
+{
+ SC_NOBASE = 0,
+ SC_BIN = 2,
+ SC_OCT = 8,
+ SC_DEC = 10,
+ SC_HEX = 16,
+ SC_BIN_US,
+ SC_BIN_SM,
+ SC_OCT_US,
+ SC_OCT_SM,
+ SC_HEX_US,
+ SC_HEX_SM,
+ SC_CSD
+};
+
+
+// Sign of a number:
+#define SC_NEG -1 // Negative number
+#define SC_ZERO 0 // Zero
+#define SC_POS 1 // Positive number
+#define SC_NOSIGN 2 // Uninitialized sc_signed number
+
+typedef unsigned char uchar;
+
+// A small_type number is at least a char. Defining an int is probably
+// better for alignment.
+typedef int small_type;
+
+// Attributes of a byte.
+#define BITS_PER_BYTE 8
+#define BYTE_RADIX 256
+#define BYTE_MASK 255
+
+// LOG2_BITS_PER_BYTE = log2(BITS_PER_BYTE), assuming that
+// BITS_PER_BYTE is a power of 2.
+#define LOG2_BITS_PER_BYTE 3
+
+// Attributes of the unsigned long. These definitions are used mainly in
+// the functions that are aware of the internal representation of
+// digits, e.g., get/set_packed_rep().
+#define BYTES_PER_DIGIT_TYPE 4
+#define BITS_PER_DIGIT_TYPE 32
+
+// Attributes of a digit, i.e., unsigned long less the overflow bits.
+#define BYTES_PER_DIGIT 4
+#define BITS_PER_DIGIT 30
+#define DIGIT_RADIX (1ul << BITS_PER_DIGIT)
+#define DIGIT_MASK (DIGIT_RADIX - 1)
+// Make sure that BYTES_PER_DIGIT = ceil(BITS_PER_DIGIT / BITS_PER_BYTE).
+
+// Similar attributes for the half of a digit. Note that
+// HALF_DIGIT_RADIX is equal to the square root of DIGIT_RADIX. These
+// definitions are used mainly in the multiplication routines.
+#define BITS_PER_HALF_DIGIT (BITS_PER_DIGIT / 2)
+#define HALF_DIGIT_RADIX (1ul << BITS_PER_HALF_DIGIT)
+#define HALF_DIGIT_MASK (HALF_DIGIT_RADIX - 1)
+
+// DIV_CEIL2(x, y) = ceil(x / y). x and y are positive numbers.
+#define DIV_CEIL2(x, y) (((x) - 1) / (y) + 1)
+
+// DIV_CEIL(x) = ceil(x / BITS_PER_DIGIT) = the number of digits to
+// store x bits. x is a positive number.
+#define DIV_CEIL(x) DIV_CEIL2(x, BITS_PER_DIGIT)
+
+#ifdef SC_MAX_NBITS
+extern const int MAX_NDIGITS;
+// Consider a number with x bits another with y bits. The maximum
+// number of bits happens when we multiply them. The result will have
+// (x + y) bits. Assume that x + y <= SC_MAX_NBITS. Then, DIV_CEIL(x) +
+// DIV_CEIL(y) <= DIV_CEIL(SC_MAX_NBITS) + 2. This is the reason for +2
+// above. With this change, MAX_NDIGITS must be enough to hold the
+// result of any operation.
+#endif
+
+// Support for "digit" vectors used to hold the values of sc_signed,
+// sc_unsigned, sc_bv_base, and sc_lv_base data types. This type is also used
+// in the concatenation support. An sc_digit is currently an unsigned 32-bit
+// quantity. The typedef used is an unsigned int, rather than an unsigned long,
+// since the unsigned long data type varies in size between 32-bit and 64-bit
+// machines.
+
+typedef unsigned int sc_digit; // 32-bit unsigned integer
+
+// Support for the long long type. This type is not in the standard
+// but is usually supported by compilers.
+#ifndef _WIN32
+# if defined(__x86_64__)
+ typedef long long int64;
+ typedef unsigned long long uint64;
+# else
+ typedef int64_t int64;
+ typedef uint64_t uint64;
+# endif
+ extern const uint64 UINT64_ZERO;
+ extern const uint64 UINT64_ONE;
+ extern const uint64 UINT64_32ONES;
+#else
+ typedef __int64 int64;
+ typedef unsigned __int64 uint64;
+ extern const uint64 UINT64_ZERO;
+ extern const uint64 UINT64_ONE;
+ extern const uint64 UINT64_32ONES;
+#endif
+
+
+// Bits per ...
+// will be deleted in the future. Use numeric_limits instead
+#define BITS_PER_CHAR 8
+#define BITS_PER_INT (sizeof(int) * BITS_PER_CHAR)
+#define BITS_PER_LONG (sizeof(long) * BITS_PER_CHAR)
+#define BITS_PER_INT64 (sizeof(::sc_dt::int64) * BITS_PER_CHAR)
+#define BITS_PER_UINT (sizeof(unsigned int) * BITS_PER_CHAR)
+#define BITS_PER_ULONG (sizeof(unsigned long) * BITS_PER_CHAR)
+#define BITS_PER_UINT64 (sizeof(::sc_dt::uint64) * BITS_PER_CHAR)
+
+// Digits per ...
+#define DIGITS_PER_CHAR 1
+#define DIGITS_PER_INT ((BITS_PER_INT+29)/30)
+#define DIGITS_PER_LONG ((BITS_PER_LONG+29)/30)
+#define DIGITS_PER_INT64 ((BITS_PER_INT64+29)/30)
+#define DIGITS_PER_UINT ((BITS_PER_UINT+29)/30)
+#define DIGITS_PER_ULONG ((BITS_PER_ULONG+29)/30)
+#define DIGITS_PER_UINT64 ((BITS_PER_UINT64+29)/30)
+
+// Above, BITS_PER_X is mainly used for sc_signed, and BITS_PER_UX is
+// mainly used for sc_unsigned.
+
+#if defined( _WIN32 ) || defined( __HP_aCC )
+typedef unsigned long fmtflags;
+#else
+typedef ::std::ios::fmtflags fmtflags;
+#endif
+
+extern const small_type NB_DEFAULT_BASE ;
+
+// For sc_int code:
+#define LLWIDTH BITS_PER_INT64
+#define INTWIDTH BITS_PER_INT
+
+#ifndef _32BIT_
+
+typedef int64 int_type;
+typedef uint64 uint_type;
+#define SC_INTWIDTH 64
+extern const uint64 UINT_ZERO;
+extern const uint64 UINT_ONE;
+
+#else
+
+typedef int int_type;
+typedef unsigned int uint_type;
+#define SC_INTWIDTH 32
+extern const unsigned int UINT_ZERO;
+extern const unsigned int UINT_ONE;
+
+#endif
+
+
+#if defined(_MSC_VER) && ( _MSC_VER < 1300 )
+ // VC++6 bug
+ ::std::ostream& operator << ( ::std::ostream&, int64 );
+ ::std::ostream& operator << ( ::std::ostream&, uint64 );
+#endif
+
+} // namespace sc_dt
+
+
+#if defined(_MSC_VER) && ( _MSC_VER < 1300 )
+
+ inline
+ ::std::ostream&
+ operator << ( ::std::ostream& os, sc_dt::int64 a )
+ {
+ sc_dt::operator << ( os, a );
+ return os;
+ }
+
+ inline
+ ::std::ostream&
+ operator << ( ::std::ostream& os, sc_dt::uint64 a )
+ {
+ sc_dt::operator << ( os, a );
+ return os;
+ }
+
+#endif
+
+
+#endif
diff --git a/ext/systemc/src/sysc/datatypes/int/sc_nbexterns.cpp b/ext/systemc/src/sysc/datatypes/int/sc_nbexterns.cpp
new file mode 100644
index 000000000..245df73b8
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/int/sc_nbexterns.cpp
@@ -0,0 +1,894 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_nbexterns.cpp -- External functions for both sc_signed and sc_unsigned
+ classes. These functions work on two parameters u and
+ v, and copy the result to the first parameter u. This
+ is also the reason that they are suffixed with _on_help.
+
+ Original Author: Ali Dasdan, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// $Log: sc_nbexterns.cpp,v $
+// Revision 1.2 2011/02/18 20:19:15 acg
+// Andy Goodrich: updating Copyright notice.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:49:32 acg
+// Added $Log command so that CVS check in comments are reproduced in the
+// source.
+//
+
+#include "sysc/datatypes/int/sc_nbexterns.h"
+#include "sysc/kernel/sc_macros.h"
+
+
+namespace sc_dt
+{
+
+// ----------------------------------------------------------------------------
+// SECTION: External functions for PLUS operators.
+// ----------------------------------------------------------------------------
+
+// Handles the cases 3 and 4 and returns the result in u.
+void
+add_on_help(small_type &us, int /* unb */, int und,
+ sc_digit *ud,
+ small_type vs, int /* vnb */, int vnd,
+ const sc_digit *vd)
+{
+
+ vnd = vec_skip_leading_zeros(vnd, vd);
+
+ if (us == vs) { // case 3
+
+ if (und >= vnd)
+ vec_add_on(und, ud, vnd, vd);
+ else
+ vec_add_on2(und, ud, vnd, vd);
+
+ }
+ else { // case 4
+
+ // vec_cmp expects that und is the number of non-zero digits in ud.
+ int new_und = vec_skip_leading_zeros(und, ud);
+ int cmp_res = vec_cmp(new_und, ud, vnd, vd);
+
+ if (cmp_res == 0) { // u == v
+ us = SC_ZERO;
+ vec_zero(und, ud);
+ return;
+ }
+
+ if (cmp_res > 0) // u > v
+ vec_sub_on(und, ud, vnd, vd);
+
+ else { // u < v
+ us = -us;
+ vec_sub_on2(und, ud, vnd, vd);
+ }
+
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+
+/*
+
+mul_on_help_signed and mul_on_help_unsigned have the same body except
+that CONVERT_SM_to_2C_to_SM and COPY_DIGITS are defined for signed and
+unsigned, respectively. This comment also applies to the
+signed/unsigned versions of div_on_help and mod_on_help. It is
+possible to take COPY_DIGITS out of these functions and create a
+single version of each of these helper functions; however, this will
+impose an onverhead on performance. In the versions below, any change
+in the signed version of a helper function must be carried to a
+corresponding change in the unsigned verion of the same function or
+vice versa.
+
+*/
+
+
+// ----------------------------------------------------------------------------
+// SECTION: External functions of MULTIPLICATION operators.
+// ----------------------------------------------------------------------------
+
+void
+mul_on_help_signed(small_type &us,
+ int unb, int und,
+ sc_digit *ud,
+ int vnb, int vnd,
+ const sc_digit *vd)
+{
+#define CONVERT_SM_to_2C_to_SM convert_signed_SM_to_2C_to_SM
+#define COPY_DIGITS copy_digits_signed
+
+ { // Body of mul_on_help
+
+ int old_und = und;
+
+ und = vec_skip_leading_zeros(und, ud);
+ vnd = vec_skip_leading_zeros(vnd, vd);
+
+ sc_digit ud0 = (*ud);
+ sc_digit vd0 = (*vd);
+
+ if ((vnd == 1) && (vd0 == 1)) {
+ us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud);
+ return;
+ }
+
+ if ((und == 1) && (ud0 == 1)) {
+ COPY_DIGITS(us, unb, old_und, ud, vnb, vnd, vd);
+ return;
+ }
+
+ if ((und == 1) && (vnd == 1) &&
+ (ud0 < HALF_DIGIT_RADIX) && (vd0 < HALF_DIGIT_RADIX)) {
+
+ sc_digit d = ud0 * vd0;
+ COPY_DIGITS(us, unb, old_und, ud, unb + vnb, 1, &d);
+ return;
+
+ }
+
+ int nd = und + vnd;
+
+#ifdef SC_MAX_NBITS
+ sc_digit d[MAX_NDIGITS];
+#else
+ sc_digit *d = new sc_digit[nd];
+#endif
+
+ vec_zero(nd, d);
+
+ if ((und == 1) && (ud0 < HALF_DIGIT_RADIX))
+ vec_mul_small(vnd, vd, ud0, d);
+
+ else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
+ vec_mul_small(und, ud, vd0, d);
+
+ else if (vnd < und)
+ vec_mul(und, ud, vnd, vd, d);
+
+ else
+ vec_mul(vnd, vd, und, ud, d);
+
+ COPY_DIGITS(us, unb, old_und, ud, unb + vnb, nd, d);
+
+#ifndef SC_MAX_NBITS
+ delete [] d;
+#endif
+
+ }
+
+#undef COPY_DIGITS
+#undef CONVERT_SM_to_2C_to_SM
+
+}
+
+
+void
+mul_on_help_unsigned(small_type &us,
+ int unb, int und,
+ sc_digit *ud,
+ int vnb, int vnd,
+ const sc_digit *vd)
+{
+#define CONVERT_SM_to_2C_to_SM convert_unsigned_SM_to_2C_to_SM
+#define COPY_DIGITS copy_digits_unsigned
+
+ { // Body of mul_on_help
+
+ int old_und = und;
+
+ und = vec_skip_leading_zeros(und, ud);
+ vnd = vec_skip_leading_zeros(vnd, vd);
+
+ sc_digit ud0 = (*ud);
+ sc_digit vd0 = (*vd);
+
+ if ((vnd == 1) && (vd0 == 1)) {
+ us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud);
+ return;
+ }
+
+ if ((und == 1) && (ud0 == 1)) {
+ COPY_DIGITS(us, unb, old_und, ud, vnb, vnd, vd);
+ return;
+ }
+
+ if ((und == 1) && (vnd == 1) &&
+ (ud0 < HALF_DIGIT_RADIX) && (vd0 < HALF_DIGIT_RADIX)) {
+
+ sc_digit d = ud0 * vd0;
+ COPY_DIGITS(us, unb, old_und, ud, unb + vnb, 1, &d);
+ return;
+
+ }
+
+ int nd = und + vnd;
+
+#ifdef SC_MAX_NBITS
+ sc_digit d[MAX_NDIGITS];
+#else
+ sc_digit *d = new sc_digit[nd];
+#endif
+
+ vec_zero(nd, d);
+
+ if ((und == 1) && (ud0 < HALF_DIGIT_RADIX))
+ vec_mul_small(vnd, vd, ud0, d);
+
+ else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
+ vec_mul_small(und, ud, vd0, d);
+
+ else if (vnd < und)
+ vec_mul(und, ud, vnd, vd, d);
+
+ else
+ vec_mul(vnd, vd, und, ud, d);
+
+ COPY_DIGITS(us, unb, old_und, ud, unb + vnb, nd, d);
+
+#ifndef SC_MAX_NBITS
+ delete [] d;
+#endif
+
+ }
+
+#undef COPY_DIGITS
+#undef CONVERT_SM_to_2C_to_SM
+
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: External functions for DIVISION operators.
+// ----------------------------------------------------------------------------
+
+void
+div_on_help_signed(small_type &us,
+ int unb, int und,
+ sc_digit *ud,
+ int vnb, int vnd,
+ const sc_digit *vd)
+{
+#define CONVERT_SM_to_2C_to_SM convert_signed_SM_to_2C_to_SM
+#define COPY_DIGITS copy_digits_signed
+
+ { // Body of div_on_help
+
+ int old_und = und;
+
+ und = vec_skip_leading_zeros(und, ud);
+ vnd = vec_skip_leading_zeros(vnd, vd);
+
+ int cmp_res = vec_cmp(und, ud, vnd, vd);
+
+ if (cmp_res < 0) { // u < v => u / v = 0 - case 4
+ us = SC_ZERO;
+ vec_zero(old_und, ud);
+ return;
+ }
+
+ sc_digit vd0 = (*vd);
+
+ if ((cmp_res > 0) && (vnd == 1) && (vd0 == 1)) {
+ us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud);
+ return;
+ }
+
+ // One extra digit for d is allocated to simplify vec_div_*().
+ int nd = sc_max(und, vnd) + 1;
+
+#ifdef SC_MAX_NBITS
+ sc_digit d[MAX_NDIGITS + 1];
+#else
+ sc_digit *d = new sc_digit[nd];
+#endif
+
+ vec_zero(nd, d);
+
+ // u = v => u / v = 1 - case 3
+ if (cmp_res == 0)
+ d[0] = 1;
+
+ else if ((vnd == 1) && (und == 1))
+ d[0] = (*ud) / vd0;
+
+ else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
+ vec_div_small(und, ud, vd0, d);
+
+ else
+ vec_div_large(und, ud, vnd, vd, d);
+
+ COPY_DIGITS(us, unb, old_und, ud, sc_max(unb, vnb), nd - 1, d);
+
+#ifndef SC_MAX_NBITS
+ delete [] d;
+#endif
+
+ }
+
+#undef COPY_DIGITS
+#undef CONVERT_SM_to_2C_to_SM
+
+}
+
+
+void
+div_on_help_unsigned(small_type &us,
+ int unb, int und,
+ sc_digit *ud,
+ int vnb, int vnd,
+ const sc_digit *vd)
+{
+#define CONVERT_SM_to_2C_to_SM convert_unsigned_SM_to_2C_to_SM
+#define COPY_DIGITS copy_digits_unsigned
+
+ { // Body of div_on_help
+
+ int old_und = und;
+
+ und = vec_skip_leading_zeros(und, ud);
+ vnd = vec_skip_leading_zeros(vnd, vd);
+
+ int cmp_res = vec_cmp(und, ud, vnd, vd);
+
+ if (cmp_res < 0) { // u < v => u / v = 0 - case 4
+ us = SC_ZERO;
+ vec_zero(old_und, ud);
+ return;
+ }
+
+ sc_digit vd0 = (*vd);
+
+ if ((cmp_res > 0) && (vnd == 1) && (vd0 == 1)) {
+ us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud);
+ return;
+ }
+
+ // One extra digit for d is allocated to simplify vec_div_*().
+ int nd = sc_max(und, vnd) + 1;
+
+#ifdef SC_MAX_NBITS
+ sc_digit d[MAX_NDIGITS + 1];
+#else
+ sc_digit *d = new sc_digit[nd];
+#endif
+
+ vec_zero(nd, d);
+
+ // u = v => u / v = 1 - case 3
+ if (cmp_res == 0)
+ d[0] = 1;
+
+ else if ((vnd == 1) && (und == 1))
+ d[0] = (*ud) / vd0;
+
+ else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
+ vec_div_small(und, ud, vd0, d);
+
+ else
+ vec_div_large(und, ud, vnd, vd, d);
+
+ COPY_DIGITS(us, unb, old_und, ud, sc_max(unb, vnb), nd - 1, d);
+
+#ifndef SC_MAX_NBITS
+ delete [] d;
+#endif
+
+ }
+
+#undef COPY_DIGITS
+#undef CONVERT_SM_to_2C_to_SM
+
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: External functions for MOD operators.
+// ----------------------------------------------------------------------------
+
+void
+mod_on_help_signed(small_type &us,
+ int unb, int und,
+ sc_digit *ud,
+ int /* vnb */, int vnd,
+ const sc_digit *vd)
+{
+
+#define COPY_DIGITS copy_digits_signed
+
+ { // Body of mod_on_help
+
+ int old_und = und;
+
+ und = vec_skip_leading_zeros(und, ud);
+ vnd = vec_skip_leading_zeros(vnd, vd);
+
+ int cmp_res = vec_cmp(und, ud, vnd, vd);
+
+ // u < v => u % v = u - case 4
+ if (cmp_res < 0)
+ return;
+
+ // u = v => u % v = 0 - case 3
+ if (cmp_res == 0) {
+ us = SC_ZERO;
+ vec_zero(old_und, ud);
+ return;
+ }
+
+ // else if u > v - case 5
+
+ sc_digit vd0 = (*vd);
+
+ if ((vnd == 1) && (vd0 == 1)) {
+ us = SC_ZERO;
+ vec_zero(old_und, ud);
+ return;
+ }
+
+ // One extra digit for d is allocated to simplify vec_div_*().
+ int nd = sc_max(und, vnd) + 1;
+
+#ifdef SC_MAX_NBITS
+ sc_digit d[MAX_NDIGITS + 1];
+#else
+ sc_digit *d = new sc_digit[nd];
+#endif
+
+ vec_zero(nd, d);
+
+ if ((vnd == 1) && (und == 1))
+ d[0] = (*ud) % vd0;
+
+ if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
+ d[0] = vec_rem_small(und, ud, vd0);
+
+ else
+ vec_rem_large(und, ud, vnd, vd, d);
+
+ us = check_for_zero(us, nd - 1, d);
+
+ if (us == SC_ZERO)
+ vec_zero(old_und, ud);
+ else
+ COPY_DIGITS(us, unb, old_und, ud, sc_min(unb, vnd), nd - 1, d);
+
+#ifndef SC_MAX_NBITS
+ delete [] d;
+#endif
+
+ }
+
+#undef COPY_DIGITS
+
+}
+
+
+void
+mod_on_help_unsigned(small_type &us,
+ int unb, int und,
+ sc_digit *ud,
+ int /* vnb */, int vnd,
+ const sc_digit *vd)
+{
+
+#define COPY_DIGITS copy_digits_unsigned
+
+ { // Body of mod_on_help
+
+ int old_und = und;
+
+ und = vec_skip_leading_zeros(und, ud);
+ vnd = vec_skip_leading_zeros(vnd, vd);
+
+ int cmp_res = vec_cmp(und, ud, vnd, vd);
+
+ // u < v => u % v = u - case 4
+ if (cmp_res < 0)
+ return;
+
+ // u = v => u % v = 0 - case 3
+ if (cmp_res == 0) {
+ us = SC_ZERO;
+ vec_zero(old_und, ud);
+ return;
+ }
+
+ // else if u > v - case 5
+
+ sc_digit vd0 = (*vd);
+
+ if ((vnd == 1) && (vd0 == 1)) {
+ us = SC_ZERO;
+ vec_zero(old_und, ud);
+ return;
+ }
+
+ // One extra digit for d is allocated to simplify vec_div_*().
+ int nd = sc_max(und, vnd) + 1;
+
+#ifdef SC_MAX_NBITS
+ sc_digit d[MAX_NDIGITS + 1];
+#else
+ sc_digit *d = new sc_digit[nd];
+#endif
+
+ vec_zero(nd, d);
+
+ if ((vnd == 1) && (und == 1))
+ d[0] = (*ud) % vd0;
+
+ if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
+ d[0] = vec_rem_small(und, ud, vd0);
+
+ else
+ vec_rem_large(und, ud, vnd, vd, d);
+
+ us = check_for_zero(us, nd - 1, d);
+
+ if (us == SC_ZERO)
+ vec_zero(old_und, ud);
+ else
+ COPY_DIGITS(us, unb, old_und, ud, sc_min(unb, vnd), nd - 1, d);
+
+#ifndef SC_MAX_NBITS
+ delete [] d;
+#endif
+
+ }
+
+#undef COPY_DIGITS
+
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: External functions for AND operators.
+// ----------------------------------------------------------------------------
+
+// Handles the cases 2-5 and returns the result in u.
+void
+and_on_help(small_type us,
+ int /* unb */, int und,
+ sc_digit *ud,
+ small_type vs,
+ int /* vnb */, int vnd,
+ const sc_digit *vd)
+{
+
+ sc_digit *x = ud;
+ const sc_digit *y = vd;
+ int xnd = und;
+ int ynd = vnd;
+
+ // Truncate y.
+ if (xnd < ynd)
+ ynd = xnd;
+
+ const sc_digit *xend = (x + xnd);
+ const sc_digit *yend = (y + ynd);
+
+ // x is longer than y.
+
+ small_type s = mul_signs(us, vs);
+
+ if (s > 0) {
+
+ if (us > 0) { // case 2
+
+ while (y < yend)
+ (*x++) &= (*y++);
+
+ while (x < xend)
+ (*x++) = 0;
+
+ }
+ else { // case 3
+
+ sc_digit xcarry = 1;
+ sc_digit ycarry = 1;
+
+ while (y < yend) {
+ xcarry += (~(*x) & DIGIT_MASK);
+ ycarry += (~(*y++) & DIGIT_MASK);
+ (*x++) = (xcarry & ycarry) & DIGIT_MASK;
+ xcarry >>= BITS_PER_DIGIT;
+ ycarry >>= BITS_PER_DIGIT;
+ }
+
+ while (x < xend) {
+ xcarry += (~(*x) & DIGIT_MASK);
+ ycarry += DIGIT_MASK;
+ (*x++) = (xcarry & ycarry) & DIGIT_MASK;
+ xcarry >>= BITS_PER_DIGIT;
+ ycarry >>= BITS_PER_DIGIT;
+ }
+
+ }
+ }
+ else {
+
+ if (us > 0) { // case 4
+
+ sc_digit ycarry = 1;
+
+ while (y < yend) {
+ ycarry += (~(*y++) & DIGIT_MASK);
+ (*x++) &= ycarry & DIGIT_MASK;
+ ycarry >>= BITS_PER_DIGIT;
+ }
+
+ while (x < xend) {
+ ycarry += DIGIT_MASK;
+ (*x++) &= ycarry & DIGIT_MASK;
+ ycarry >>= BITS_PER_DIGIT;
+ }
+
+ }
+ else { // case 5
+
+ sc_digit xcarry = 1;
+
+ while (y < yend) {
+ xcarry += (~(*x) & DIGIT_MASK);
+ (*x++) = (xcarry & (*y++)) & DIGIT_MASK;
+ xcarry >>= BITS_PER_DIGIT;
+ }
+
+ while (x < xend)
+ (*x++) = 0;
+
+ }
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: External functions for OR operators.
+// ----------------------------------------------------------------------------
+
+// Handles the cases 3-5 and returns the result in u.
+void
+or_on_help(small_type us,
+ int /* unb */, int und,
+ sc_digit *ud,
+ small_type vs,
+ int /* vnb */, int vnd,
+ const sc_digit *vd)
+{
+
+ sc_digit *x = ud;
+ const sc_digit *y = vd;
+ int xnd = und;
+ int ynd = vnd;
+
+ if (xnd < ynd)
+ ynd = xnd;
+
+ const sc_digit *xend = (x + xnd);
+ const sc_digit *yend = (y + ynd);
+
+ // x is longer than y.
+
+ small_type s = mul_signs(us, vs);
+
+ if (s > 0) {
+
+ if (us > 0) { // case 3
+
+ while (y < yend)
+ (*x++) |= (*y++);
+
+ // No change for the rest of x.
+
+ }
+ else { // case 4
+
+ sc_digit xcarry = 1;
+ sc_digit ycarry = 1;
+
+ while (y < yend) {
+ xcarry += (~(*x) & DIGIT_MASK);
+ ycarry += (~(*y++) & DIGIT_MASK);
+ (*x++) = (xcarry | ycarry) & DIGIT_MASK;
+ xcarry >>= BITS_PER_DIGIT;
+ ycarry >>= BITS_PER_DIGIT;
+ }
+
+ while (x < xend) {
+ xcarry += (~(*x) & DIGIT_MASK);
+ ycarry += DIGIT_MASK;
+ (*x++) = (xcarry | ycarry) & DIGIT_MASK;
+ xcarry >>= BITS_PER_DIGIT;
+ ycarry >>= BITS_PER_DIGIT;
+ }
+ }
+
+ }
+ else {
+
+ if (us > 0) { // case 5
+
+ sc_digit ycarry = 1;
+
+ while (y < yend) {
+ ycarry += (~(*y++) & DIGIT_MASK);
+ (*x) = ((*x) | ycarry) & DIGIT_MASK;
+ x++;
+ ycarry >>= BITS_PER_DIGIT;
+ }
+
+ while (x < xend) {
+ ycarry += DIGIT_MASK;
+ (*x) = ((*x) | ycarry) & DIGIT_MASK;
+ x++;
+ ycarry >>= BITS_PER_DIGIT;
+ }
+
+ }
+ else { // case 6
+
+ sc_digit xcarry = 1;
+
+ while (y < yend) {
+ xcarry += (~(*x) & DIGIT_MASK);
+ (*x++) = (xcarry | (*y++)) & DIGIT_MASK;
+ xcarry >>= BITS_PER_DIGIT;
+ }
+
+ while (x < xend) {
+ xcarry += (~(*x) & DIGIT_MASK);
+ (*x++) = xcarry & DIGIT_MASK;
+ xcarry >>= BITS_PER_DIGIT;
+ }
+ }
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: External functions for XOR operators.
+// ----------------------------------------------------------------------------
+
+// Handles the cases 3-5 and returns the result in u.
+void
+xor_on_help(small_type us,
+ int /* unb */, int und,
+ sc_digit *ud,
+ small_type vs,
+ int /* vnb */, int vnd,
+ const sc_digit *vd)
+{
+
+ sc_digit *x = ud;
+ const sc_digit *y = vd;
+ int xnd = und;
+ int ynd = vnd;
+
+ if (xnd < ynd)
+ ynd = xnd;
+
+ const sc_digit *xend = (x + xnd);
+ const sc_digit *yend = (y + ynd);
+
+ // x is longer than y.
+
+ small_type s = mul_signs(us, vs);
+
+ if (s > 0) {
+
+ if (us > 0) { // case 3
+
+ while (y < yend) {
+ (*x) = ((*x) ^ (*y)) & DIGIT_MASK;
+ x++;
+ y++;
+ }
+
+ // No change for the rest of x.
+
+ }
+ else { // case 4
+
+ sc_digit xcarry = 1;
+ sc_digit ycarry = 1;
+
+ while (y < yend) {
+ xcarry += (~(*x) & DIGIT_MASK);
+ ycarry += (~(*y++) & DIGIT_MASK);
+ (*x++) = (xcarry ^ ycarry) & DIGIT_MASK;
+ xcarry >>= BITS_PER_DIGIT;
+ ycarry >>= BITS_PER_DIGIT;
+ }
+
+ while (x < xend) {
+ xcarry += (~(*x) & DIGIT_MASK);
+ ycarry += DIGIT_MASK;
+ (*x++) = (xcarry ^ ycarry) & DIGIT_MASK;
+ xcarry >>= BITS_PER_DIGIT;
+ ycarry >>= BITS_PER_DIGIT;
+ }
+ }
+ }
+ else {
+
+ if (us > 0) { // case 5
+
+ sc_digit ycarry = 1;
+
+ while (y < yend) {
+ ycarry += (~(*y++) & DIGIT_MASK);
+ (*x) = ((*x) ^ ycarry) & DIGIT_MASK;
+ x++;
+ ycarry >>= BITS_PER_DIGIT;
+ }
+
+ while (x < xend) {
+ ycarry += DIGIT_MASK;
+ (*x) = ((*x) ^ ycarry) & DIGIT_MASK;
+ x++;
+ ycarry >>= BITS_PER_DIGIT;
+ }
+
+ }
+ else { // case 6
+
+ sc_digit xcarry = 1;
+
+ while (y < yend) {
+ xcarry += (~(*x) & DIGIT_MASK);
+ (*x++) = (xcarry ^ (*y++)) & DIGIT_MASK;
+ xcarry >>= BITS_PER_DIGIT;
+ }
+
+ while (x < xend) {
+ xcarry += (~(*x) & DIGIT_MASK);
+ (*x++) = xcarry & DIGIT_MASK;
+ xcarry >>= BITS_PER_DIGIT;
+ }
+ }
+ }
+}
+
+} // namespace sc_dt
+
+
+// End of file
diff --git a/ext/systemc/src/sysc/datatypes/int/sc_nbexterns.h b/ext/systemc/src/sysc/datatypes/int/sc_nbexterns.h
new file mode 100644
index 000000000..98f5cda91
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/int/sc_nbexterns.h
@@ -0,0 +1,123 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_nbexterns.h -- External functions for both sc_signed and sc_unsigned
+ classes. These functions work on two parameters u and
+ v, and copy the result to the first parameter u. This
+ is also the reason that they are suffixed with _on_help.
+
+ The vec_* functions are called through either these
+ functions or those in sc_nbfriends.cpp. The functions in
+ sc_nbfriends.cpp perform their work on two inputs u and v,
+ and return the result object.
+
+ Original Author: Ali Dasdan, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_nbexterns.h,v $
+// Revision 1.2 2011/02/18 20:19:15 acg
+// Andy Goodrich: updating Copyright notice.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:49:32 acg
+// Added $Log command so that CVS check in comments are reproduced in the
+// source.
+//
+
+#ifndef SC_NBEXTERNS_H
+#define SC_NBEXTERNS_H
+
+
+#include "sysc/datatypes/int/sc_nbutils.h"
+
+
+namespace sc_dt
+{
+
+extern
+void add_on_help(small_type &us,
+ int unb, int und, sc_digit *ud,
+ small_type vs,
+ int vnb, int vnd, const sc_digit *vd);
+
+extern
+void mul_on_help_signed(small_type &us,
+ int unb, int und, sc_digit *ud,
+ int vnb, int vnd, const sc_digit *vd);
+
+void div_on_help_signed(small_type &us,
+ int unb, int und, sc_digit *ud,
+ int vnb, int vnd, const sc_digit *vd);
+
+extern
+void mod_on_help_signed(small_type &us,
+ int unb, int und, sc_digit *ud,
+ int vnb, int vnd, const sc_digit *vd);
+
+extern
+void mul_on_help_unsigned(small_type &us,
+ int unb, int und, sc_digit *ud,
+ int vnb, int vnd, const sc_digit *vd);
+
+void div_on_help_unsigned(small_type &us,
+ int unb, int und, sc_digit *ud,
+ int vnb, int vnd, const sc_digit *vd);
+
+extern
+void mod_on_help_unsigned(small_type &us,
+ int unb, int und, sc_digit *ud,
+ int vnb, int vnd, const sc_digit *vd);
+
+extern
+void and_on_help(small_type us,
+ int unb, int und, sc_digit *ud,
+ small_type vs,
+ int vnb, int vnd, const sc_digit *vd);
+
+extern
+void or_on_help(small_type us,
+ int unb, int und, sc_digit *ud,
+ small_type vs,
+ int vnb, int vnd, const sc_digit *vd);
+
+extern
+void xor_on_help(small_type us,
+ int unb, int und, sc_digit *ud,
+ small_type vs,
+ int vnb, int vnd, const sc_digit *vd);
+
+} // namespace sc_dt
+
+
+#endif
diff --git a/ext/systemc/src/sysc/datatypes/int/sc_nbfriends.inc b/ext/systemc/src/sysc/datatypes/int/sc_nbfriends.inc
new file mode 100644
index 000000000..5d67939e5
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/int/sc_nbfriends.inc
@@ -0,0 +1,727 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_nbfriends.inc -- Friend functions for both sc_signed and sc_unsigned
+ classes. The vec_* functions are called through either
+ these functions or those in sc_nbexterns.cpp. These
+ functions perform their work on two inputs u and v, and
+ return the result object. The functions in
+ sc_nbexterns.cpp perform their work on one of their
+ inputs.
+
+ The functions here try to use faster algorithms in case
+ the input numbers are small. The bitwise functions (and,
+ or, and xor) need the 2's complement representations of
+ their inputs. Instead of complementing their inputs
+ first and then processing, they complement their inputs
+ while processing without allocating extra temporary
+ memory.
+
+ Original Author: Ali Dasdan, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// ----------------------------------------------------------------------------
+// Naming conventions:
+// For sc_signed or sc_unsigned number u:
+// us : u's sign, unb : u's number of bits,
+// und : u's number of digits, ud : u's digits array.
+// ----------------------------------------------------------------------------
+
+// ----------------------------------------------------------------------------
+// SECTION: Friend functions for PLUS operators.
+// ----------------------------------------------------------------------------
+
+// Handles cases 3 and 4 and returns the result.
+CLASS_TYPE
+ADD_HELPER(small_type us, int unb, int und,
+ const sc_digit *ud,
+ small_type vs, int vnb, int vnd,
+ const sc_digit *vd)
+{
+
+ und = vec_skip_leading_zeros(und, ud);
+ vnd = vec_skip_leading_zeros(vnd, vd);
+
+ int nb = sc_max(unb, vnb);
+ int nd = sc_max(und, vnd) + 1;
+
+#ifdef SC_MAX_NBITS
+ test_bound(nb);
+ sc_digit d[MAX_NDIGITS];
+#else
+ sc_digit *d = new sc_digit[nd];
+#endif
+
+ d[nd - 1] = d[nd - 2] = 0;
+
+ // case 3
+ if (us == vs) {
+
+ ++nb;
+
+ if ((und == 1) && (vnd == 1)) {
+ sc_digit carry = (*ud) + (*vd);
+ d[0] = carry & DIGIT_MASK;
+ d[1] = carry >> BITS_PER_DIGIT;
+ }
+
+ else if (und >= vnd)
+ vec_add(und, ud, vnd, vd, d);
+
+ else
+ vec_add(vnd, vd, und, ud, d);
+
+ }
+
+ // case 4
+ else {
+
+ int cmp_res = vec_cmp(und, ud, vnd, vd);
+
+ if (cmp_res == 0) { // u == v
+#ifndef SC_MAX_NBITS
+ delete[] d;
+#endif
+ return CLASS_TYPE();
+ }
+
+ if (cmp_res > 0) { // u > v
+
+ if ((und == 1) && (vnd == 1))
+ d[0] = (*ud) - (*vd);
+ else
+ vec_sub(und, ud, vnd, vd, d);
+
+ }
+ else { // u < v
+
+ us = -us;
+
+ if ((und == 1) && (vnd == 1))
+ d[0] = (*vd) - (*ud);
+ else
+ vec_sub(vnd, vd, und, ud, d);
+
+ }
+ }
+
+ return CLASS_TYPE(us, nb, nd, d);
+
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Friend functions of MULTIPLICATION operators.
+// ----------------------------------------------------------------------------
+
+// Handles the case 4 and returns the result.
+CLASS_TYPE
+MUL_HELPER(small_type s,
+ int unb, int und,
+ const sc_digit *ud,
+ int vnb, int vnd,
+ const sc_digit *vd)
+{
+
+ und = vec_skip_leading_zeros(und, ud);
+ vnd = vec_skip_leading_zeros(vnd, vd);
+
+ int nb = unb + vnb;
+ int nd = und + vnd;
+
+#ifdef SC_MAX_NBITS
+ test_bound(nb);
+ sc_digit d[MAX_NDIGITS];
+#else
+ sc_digit *d = new sc_digit[nd];
+#endif
+
+ vec_zero(nd, d);
+
+ sc_digit ud0 = (*ud);
+ sc_digit vd0 = (*vd);
+
+ if ((vnd == 1) && (vd0 == 1))
+ vec_copy(und, d, ud);
+
+ else if ((und == 1) && (ud0 == 1))
+ vec_copy(vnd, d, vd);
+
+ else if ((und == 1) && (vnd == 1) &&
+ (ud0 < HALF_DIGIT_RADIX) && (vd0 < HALF_DIGIT_RADIX))
+ d[0] = ud0 * vd0;
+
+ else if ((und == 1) && (ud0 < HALF_DIGIT_RADIX))
+ vec_mul_small(vnd, vd, ud0, d);
+
+ else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
+ vec_mul_small(und, ud, vd0, d);
+
+ else if (vnd < und)
+ vec_mul(und, ud, vnd, vd, d);
+
+ else
+ vec_mul(vnd, vd, und, ud, d);
+
+ return CLASS_TYPE(s, nb, nd, d);
+
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Friend functions for DIVISION operators.
+// ----------------------------------------------------------------------------
+
+// Handles the cases 3-4 and returns the result.
+CLASS_TYPE
+DIV_HELPER(small_type s,
+ int unb, int und,
+ const sc_digit *ud,
+ int vnb, int vnd,
+ const sc_digit *vd)
+{
+
+ und = vec_skip_leading_zeros(und, ud);
+ vnd = vec_skip_leading_zeros(vnd, vd);
+
+ int cmp_res = vec_cmp(und, ud, vnd, vd);
+
+ // u < v => u / v = 0 - case 4
+ if (cmp_res < 0)
+ return CLASS_TYPE();
+
+ // One extra digit for d is allocated to simplify vec_div_*().
+ int nd = sc_max(und, vnd) + 1;
+
+#ifdef SC_MAX_NBITS
+ sc_digit d[MAX_NDIGITS + 1];
+#else
+ sc_digit *d = new sc_digit[nd];
+#endif
+
+ vec_zero(nd, d);
+
+ sc_digit vd0 = (*vd);
+
+ // u = v => u / v = 1 - case 3
+ if (cmp_res == 0)
+ d[0] = 1;
+
+ // else if u > v - case 5
+
+ else if ((vnd == 1) && (vd0 == 1))
+ vec_copy(und, d, ud);
+
+ else if ((vnd == 1) && (und == 1))
+ d[0] = (*ud) / vd0;
+
+ else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
+ vec_div_small(und, ud, vd0, d);
+
+ else
+ vec_div_large(und, ud, vnd, vd, d);
+
+ return CLASS_TYPE(s, sc_max(unb, vnb), nd - 1, d);
+
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Friend functions for MOD operators.
+// ----------------------------------------------------------------------------
+
+// Handles the cases 3-4 and returns the result.
+CLASS_TYPE
+MOD_HELPER(small_type us,
+ int unb, int und,
+ const sc_digit *ud,
+ int vnb, int vnd,
+ const sc_digit *vd)
+{
+
+ und = vec_skip_leading_zeros(und, ud);
+ vnd = vec_skip_leading_zeros(vnd, vd);
+
+ int cmp_res = vec_cmp(und, ud, vnd, vd);
+
+ // u = v => u % v = 0 - case 3
+ if (cmp_res == 0)
+ return CLASS_TYPE();
+
+ sc_digit vd0 = (*vd);
+
+ if ((cmp_res > 0) && (vnd == 1) && (vd0 == 1))
+ return CLASS_TYPE();
+
+ // One extra digit for d is allocated to simplify vec_div_*().
+ int nd = sc_max(und, vnd) + 1;
+
+#ifdef SC_MAX_NBITS
+ sc_digit d[MAX_NDIGITS + 1];
+#else
+ sc_digit *d = new sc_digit[nd];
+#endif
+
+ vec_zero(nd, d);
+
+ // u < v => u % v = u - case 4
+ if (cmp_res < 0)
+ vec_copy(und, d, ud);
+
+ // else if u > v - case 5
+
+ else if ((vnd == 1) && (und == 1))
+ d[0] = (*ud) % vd0;
+
+ else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
+ d[0] = vec_rem_small(und, ud, vd0);
+
+ else
+ vec_rem_large(und, ud, vnd, vd, d);
+
+ us = check_for_zero(us, nd - 1, d);
+
+ if (us == SC_ZERO) {
+#ifndef SC_MAX_NBITS
+ delete[] d;
+#endif
+ return CLASS_TYPE();
+ } else
+ return CLASS_TYPE(us, sc_min(unb, vnb), nd - 1, d);
+
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Friend functions for AND operators.
+// ----------------------------------------------------------------------------
+
+// Handles the cases 2-5 and returns the result.
+CLASS_TYPE
+AND_HELPER(small_type us,
+ int unb, int und,
+ const sc_digit *ud,
+ small_type vs,
+ int vnb, int vnd,
+ const sc_digit *vd)
+{
+
+ int nb = sc_max(unb, vnb);
+ int nd = sc_max(und, vnd);
+
+#ifdef SC_MAX_NBITS
+ sc_digit dbegin[MAX_NDIGITS];
+#else
+ sc_digit *dbegin = new sc_digit[nd];
+#endif
+
+ sc_digit *d = dbegin;
+
+ const sc_digit *x;
+ const sc_digit *y;
+ int xnd;
+ int ynd;
+ small_type xs;
+ small_type ys;
+
+ if (und >= vnd) {
+ x = ud;
+ y = vd;
+ xnd = und;
+ ynd = vnd;
+ xs = us;
+ ys = vs;
+ }
+ else {
+ y = ud;
+ x = vd;
+ ynd = und;
+ xnd = vnd;
+ ys = us;
+ xs = vs;
+ }
+
+ const sc_digit *xend = (x + xnd);
+ const sc_digit *yend = (y + ynd);
+
+ // x is longer than y.
+
+ small_type s = mul_signs(xs, ys);
+
+ if (s > 0) {
+
+ if (xs > 0) { // case 2
+
+ while (y < yend)
+ (*d++) = (*x++) & (*y++);
+
+ while (x++ < xend)
+ (*d++) = 0;
+
+ }
+ else { // case 3
+
+ sc_digit xcarry = 1;
+ sc_digit ycarry = 1;
+
+ while (y < yend) {
+ xcarry += (~(*x++) & DIGIT_MASK);
+ ycarry += (~(*y++) & DIGIT_MASK);
+ (*d++) = (xcarry & ycarry) & DIGIT_MASK;
+ xcarry >>= BITS_PER_DIGIT;
+ ycarry >>= BITS_PER_DIGIT;
+ }
+
+ while (x < xend) {
+ xcarry += (~(*x++) & DIGIT_MASK);
+ ycarry += DIGIT_MASK;
+ (*d++) = (xcarry & ycarry) & DIGIT_MASK;
+ xcarry >>= BITS_PER_DIGIT;
+ ycarry >>= BITS_PER_DIGIT;
+ }
+
+ }
+ }
+ else {
+
+ if (xs > 0) { // case 4
+
+ sc_digit ycarry = 1;
+
+ while (y < yend) {
+ ycarry += (~(*y++) & DIGIT_MASK);
+ (*d++) = ((*x++) & ycarry) & DIGIT_MASK;
+ ycarry >>= BITS_PER_DIGIT;
+ }
+
+ while (x < xend) {
+ ycarry += DIGIT_MASK;
+ (*d++) = ((*x++) & ycarry) & DIGIT_MASK;
+ ycarry >>= BITS_PER_DIGIT;
+ }
+
+ }
+ else { // case 5
+
+ sc_digit xcarry = 1;
+
+ while (y < yend) {
+ xcarry += (~(*x++) & DIGIT_MASK);
+ (*d++) = (xcarry & (*y++)) & DIGIT_MASK;
+ xcarry >>= BITS_PER_DIGIT;
+ }
+
+ while (x++ < xend)
+ (*d++) = 0;
+
+ }
+ }
+
+ s = convert_signed_2C_to_SM(nb, nd, dbegin);
+
+ return CLASS_TYPE(s, nb, nd, dbegin);
+
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Friend functions for OR operators.
+// ----------------------------------------------------------------------------
+
+// Handles the cases 3-5 and returns the result.
+CLASS_TYPE
+OR_HELPER(small_type us,
+ int unb, int und,
+ const sc_digit *ud,
+ small_type vs,
+ int vnb, int vnd,
+ const sc_digit *vd)
+{
+
+ int nb = sc_max(unb, vnb);
+ int nd = sc_max(und, vnd);
+
+#ifdef SC_MAX_NBITS
+ sc_digit dbegin[MAX_NDIGITS];
+#else
+ sc_digit *dbegin = new sc_digit[nd];
+#endif
+
+ sc_digit *d = dbegin;
+
+ const sc_digit *x;
+ const sc_digit *y;
+ int xnd;
+ int ynd;
+ small_type xs;
+ small_type ys;
+
+ if (und >= vnd) {
+ x = ud;
+ y = vd;
+ xnd = und;
+ ynd = vnd;
+ xs = us;
+ ys = vs;
+ }
+ else {
+ y = ud;
+ x = vd;
+ ynd = und;
+ xnd = vnd;
+ ys = us;
+ xs = vs;
+ }
+
+ const sc_digit *xend = (x + xnd);
+ const sc_digit *yend = (y + ynd);
+
+ // x is longer than y.
+
+ small_type s = mul_signs(xs, ys);
+
+ if (s > 0) {
+
+ if (xs > 0) { // case 3
+
+ while (y < yend)
+ (*d++) = (*x++) | (*y++);
+
+ while (x < xend)
+ (*d++) = (*x++);
+
+ }
+ else { // case 4
+
+ sc_digit xcarry = 1;
+ sc_digit ycarry = 1;
+
+ while (y < yend) {
+ xcarry += (~(*x++) & DIGIT_MASK);
+ ycarry += (~(*y++) & DIGIT_MASK);
+ (*d++) = (xcarry | ycarry) & DIGIT_MASK;
+ xcarry >>= BITS_PER_DIGIT;
+ ycarry >>= BITS_PER_DIGIT;
+ }
+
+ while (x < xend) {
+ xcarry += (~(*x++) & DIGIT_MASK);
+ ycarry += DIGIT_MASK;
+ (*d++) = (xcarry | ycarry) & DIGIT_MASK;
+ xcarry >>= BITS_PER_DIGIT;
+ ycarry >>= BITS_PER_DIGIT;
+ }
+
+ }
+
+ }
+ else {
+
+ if (xs > 0) { // case 5
+
+ sc_digit ycarry = 1;
+
+ while (y < yend) {
+ ycarry += (~(*y++) & DIGIT_MASK);
+ (*d++) = ((*x++) | ycarry) & DIGIT_MASK;
+ ycarry >>= BITS_PER_DIGIT;
+ }
+
+ while (x < xend) {
+ ycarry += DIGIT_MASK;
+ (*d++) = ((*x++) | ycarry) & DIGIT_MASK;
+ ycarry >>= BITS_PER_DIGIT;
+ }
+
+ }
+ else { // case 6
+
+ sc_digit xcarry = 1;
+
+ while (y < yend) {
+ xcarry += (~(*x++) & DIGIT_MASK);
+ (*d++) = (xcarry | (*y++)) & DIGIT_MASK;
+ xcarry >>= BITS_PER_DIGIT;
+ }
+
+ while (x < xend) {
+ xcarry += (~(*x++) & DIGIT_MASK);
+ (*d++) = xcarry & DIGIT_MASK;
+ xcarry >>= BITS_PER_DIGIT;
+ }
+ }
+
+ }
+
+ s = convert_signed_2C_to_SM(nb, nd, dbegin);
+
+ return CLASS_TYPE(s, nb, nd, dbegin);
+
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Friend functions for XOR operators.
+// ----------------------------------------------------------------------------
+
+// Handles the cases 3-5 and returns the result.
+CLASS_TYPE
+XOR_HELPER(small_type us,
+ int unb, int und,
+ const sc_digit *ud,
+ small_type vs,
+ int vnb, int vnd,
+ const sc_digit *vd)
+{
+
+ int nb = sc_max(unb, vnb);
+ int nd = sc_max(und, vnd);
+
+#ifdef SC_MAX_NBITS
+ sc_digit dbegin[MAX_NDIGITS];
+#else
+ sc_digit *dbegin = new sc_digit[nd];
+#endif
+
+ sc_digit *d = dbegin;
+
+ const sc_digit *x;
+ const sc_digit *y;
+ int xnd;
+ int ynd;
+ small_type xs;
+ small_type ys;
+
+ if (und >= vnd) {
+ x = ud;
+ y = vd;
+ xnd = und;
+ ynd = vnd;
+ xs = us;
+ ys = vs;
+ }
+ else {
+ y = ud;
+ x = vd;
+ ynd = und;
+ xnd = vnd;
+ ys = us;
+ xs = vs;
+ }
+
+ const sc_digit *xend = (x + xnd);
+ const sc_digit *yend = (y + ynd);
+
+ // x is longer than y.
+
+ small_type s = mul_signs(xs, ys);
+
+ if (s > 0) {
+
+ if (xs > 0) { // case 3
+
+ while (y < yend)
+ (*d++) = ((*x++) ^ (*y++)) & DIGIT_MASK;
+
+ while (x < xend)
+ (*d++) = (*x++);
+
+ }
+ else { // case 4
+
+ sc_digit xcarry = 1;
+ sc_digit ycarry = 1;
+
+ while (y < yend) {
+ xcarry += (~(*x++) & DIGIT_MASK);
+ ycarry += (~(*y++) & DIGIT_MASK);
+ (*d++) = (xcarry ^ ycarry) & DIGIT_MASK;
+ xcarry >>= BITS_PER_DIGIT;
+ ycarry >>= BITS_PER_DIGIT;
+ }
+
+ while (x < xend) {
+ xcarry += (~(*x++) & DIGIT_MASK);
+ ycarry += DIGIT_MASK;
+ (*d++) = (xcarry ^ ycarry) & DIGIT_MASK;
+ xcarry >>= BITS_PER_DIGIT;
+ ycarry >>= BITS_PER_DIGIT;
+ }
+
+ }
+ }
+ else {
+
+ if (xs > 0) { // case 5
+
+ sc_digit ycarry = 1;
+
+ while (y < yend) {
+ ycarry += (~(*y++) & DIGIT_MASK);
+ (*d++) = ((*x++) ^ ycarry) & DIGIT_MASK;
+ ycarry >>= BITS_PER_DIGIT;
+ }
+
+ while (x < xend) {
+ ycarry += DIGIT_MASK;
+ (*d++) = ((*x++) ^ ycarry) & DIGIT_MASK;
+ ycarry >>= BITS_PER_DIGIT;
+ }
+
+ }
+ else { // case 6
+
+ sc_digit xcarry = 1;
+
+ while (y < yend) {
+ xcarry += (~(*x++) & DIGIT_MASK);
+ (*d++) = (xcarry ^ (*y++)) & DIGIT_MASK;
+ xcarry >>= BITS_PER_DIGIT;
+ }
+
+ while (x < xend) {
+ xcarry += (~(*x++) & DIGIT_MASK);
+ (*d++) = xcarry & DIGIT_MASK;
+ xcarry >>= BITS_PER_DIGIT;
+ }
+ }
+ }
+
+ s = convert_signed_2C_to_SM(nb, nd, dbegin);
+
+ return CLASS_TYPE(s, nb, nd, dbegin);
+
+}
+
+// End of file.
+
diff --git a/ext/systemc/src/sysc/datatypes/int/sc_nbutils.cpp b/ext/systemc/src/sysc/datatypes/int/sc_nbutils.cpp
new file mode 100644
index 000000000..385502aa6
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/int/sc_nbutils.cpp
@@ -0,0 +1,1892 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_nbutils.cpp -- External and friend functions for both sc_signed and
+ sc_unsigned classes.
+
+ Original Author: Ali Dasdan, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// $Log: sc_nbutils.cpp,v $
+// Revision 1.4 2011/08/24 22:05:46 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.3 2011/02/18 20:19:15 acg
+// Andy Goodrich: updating Copyright notice.
+//
+// Revision 1.2 2007/11/04 21:26:40 acg
+// Andy Goodrich: added a buffer to the allocation of the q array to address
+// an issue with references outside the array by 1 byte detected by valgrind.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:49:32 acg
+// Added $Log command so that CVS check in comments are reproduced in the
+// source.
+//
+
+#include <ctype.h>
+#include <cstdio>
+#include <string.h>
+
+#include "sysc/datatypes/int/sc_int_ids.h"
+#include "sysc/datatypes/int/sc_nbutils.h"
+#include "sysc/kernel/sc_macros.h"
+
+
+namespace sc_dt
+{
+
+// ----------------------------------------------------------------------------
+// ENUM : sc_numrep
+//
+// Enumeration of number representations for character string conversion.
+// ----------------------------------------------------------------------------
+
+const std::string
+to_string( sc_numrep numrep )
+{
+ switch( numrep )
+ {
+# define CASE_ENUM2STR( Value ) \
+ case Value: return #Value
+
+ CASE_ENUM2STR(SC_DEC);
+
+ CASE_ENUM2STR(SC_BIN);
+ CASE_ENUM2STR(SC_BIN_US);
+ CASE_ENUM2STR(SC_BIN_SM);
+
+ CASE_ENUM2STR(SC_OCT);
+ CASE_ENUM2STR(SC_OCT_US);
+ CASE_ENUM2STR(SC_OCT_SM);
+
+ CASE_ENUM2STR(SC_HEX);
+ CASE_ENUM2STR(SC_HEX_US);
+ CASE_ENUM2STR(SC_HEX_SM);
+
+ CASE_ENUM2STR(SC_CSD);
+
+# undef CASE_ENUM2STR
+
+ default:
+ return "unknown";
+ }
+}
+
+// ----------------------------------------------------------------------------
+// SECTION: General utility functions.
+// ----------------------------------------------------------------------------
+
+// Return the number of characters to advance the source of c. This
+// function implements one move of the FSM to parse the following
+// regular expressions. Error checking is done in the caller.
+
+small_type
+fsm_move(char c, small_type &b, small_type &s, small_type &state)
+{
+
+ // Possible regular expressions (REs):
+ // Let N = any digit depending on the base.
+ // 1. [0|1|..|9]N*
+ // 2. [+|-][0|1|..|9]N*
+ // 3. 0[b|B|d|D|o|O|x|X][0|1|..|F]N*
+ // 4. [+|-]?0[b|B|d|D|o|O|x|X][0|1|..|F]N*
+ //
+ // The finite state machine (FMS) to parse these regular expressions
+ // has 4 states, 0 to 3. 0 is the initial state and 3 is the final
+ // state.
+ //
+ // Default sign = SC_POS, default base = NB_DEFAULT_BASE.
+
+ switch (state) {
+
+ case 0: // The initial state.
+ switch (c) {
+ case '0': s = SC_POS; state = 1; return 0; // RE 1 or 3
+ case '+': s = SC_POS; state = 2; return 1; // RE 2
+ case '-': s = SC_NEG; state = 2; return 1; // RE 2
+ default: s = SC_POS; b = NB_DEFAULT_BASE; state = 3; return 0; // RE 1
+ }
+ // break; //unreachable code
+ case 1: // 0...
+ switch (c) {
+ case 'x': case 'X': b = SC_HEX; state = 3; return 2; // RE 3 or 4
+ case 'd': case 'D': b = SC_DEC; state = 3; return 2; // RE 3 or 4
+ case 'o': case 'O': b = SC_OCT; state = 3; return 2; // RE 3 or 4
+ case 'b': case 'B': b = SC_BIN; state = 3; return 2; // RE 3 or 4
+ default: b = NB_DEFAULT_BASE; state = 3; return 0; // RE 1
+ }
+ // break; //unreachable code
+ case 2: // +... or -...
+ switch (c) {
+ case '0': state = 1; return 0; // RE 2 or 4
+ default: b = NB_DEFAULT_BASE; state = 3; return 0; // RE 2
+ }
+ // break; //unreachable code
+ case 3: // The final state.
+ break;
+
+ default:
+ // Any other state is not possible.
+ assert((0 <= state) && (state <= 3));
+
+ } // switch
+
+ return 0;
+
+}
+
+
+// Get base b and sign s of the number in the char string v. Return a
+// pointer to the first char after the point where b and s are
+// determined or where the end of v is reached. The input string v has
+// to be null terminated.
+const char
+*get_base_and_sign(const char *v, small_type &b, small_type &s)
+{
+
+#ifdef DEBUG_SYSTEMC
+ assert(v != NULL);
+#endif
+
+ const small_type STATE_START = 0;
+ const small_type STATE_FINISH = 3;
+
+ // Default sign = SC_POS, default base = 10.
+ s = SC_POS;
+ b = NB_DEFAULT_BASE;
+
+ small_type state = STATE_START;
+ small_type nskip = 0; // Skip that many chars.
+ const char *u = v;
+
+ while (*u) {
+ if (isspace(*u)) // Skip white space.
+ ++u;
+ else {
+ nskip += fsm_move(*u, b, s, state);
+ if (state == STATE_FINISH)
+ break;
+ else
+ ++u;
+ }
+ }
+
+#ifdef DEBUG_SYSTEMC
+ // Test to see if the above loop executed more than it should
+ // have. The max number of skipped chars is equal to the length of
+ // the longest format specifier, e.g., "-0x".
+ assert(nskip <= 3);
+#endif
+
+ v += nskip;
+
+ // Handles empty strings or strings without any digits after the
+ // base or base and sign specifier.
+ if (*v == '\0') {
+ char msg[BUFSIZ];
+ std::sprintf( msg,
+ "get_base_and_sign( const char* v, small_type&, small_type& ) : "
+ "v = \"\" is not valid" );
+ SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
+ }
+
+ return v;
+
+}
+
+//------------------------------------------------------------------------------
+//"parse_binary_bits"
+//
+// This function parses the supplied string into the supplied vector as a
+// right justified bit value.
+// src_p -> character string representing the bits to be parsed.
+// dst_n = number of words in data_p and ctrl_p.
+// data_p -> words w/BITS_PER_DIGIT bits to receive the value's data bits.
+// ctrl_p -> words w/BITS_PER_DIGIT bits to receive the value's control bits,
+// or zero.
+// Result is true if value was non-zero.
+//------------------------------------------------------------------------------
+void parse_binary_bits(
+ const char* src_p, int dst_n, sc_digit* data_p, sc_digit* ctrl_p )
+{
+ int bit_i; // Number of bit now processing.
+ sc_digit ctrl; // Control word now assembling.
+ sc_digit data; // Data word now assembling.
+ int delta_n; // src_n - dst_n*BITS_PER_DIGIT.
+ int src_i; // Index in src_p now accessing (left to right).
+ int src_n; // Length of source that is left in bits.
+ int word_i; // Bit within word now accessing (left to right).
+
+ // MAKE SURE WE HAVE A STRING TO PARSE:
+
+ if( src_p == 0 ) {
+ SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_,
+ "character string is zero" );
+ }
+ if( *src_p == 0 ) {
+ SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_,
+ "character string is empty" );
+ }
+
+
+ // INDEX INTO THE SOURCE TO A DEPTH THAT WILL ACCOMODATE OUR SIZE:
+ //
+ // If the source is smaller than our value initialize our value to zero.
+
+ src_n = strlen(src_p);
+ delta_n = src_n - (dst_n*BITS_PER_DIGIT);
+ if ( delta_n > 0 )
+ {
+ src_p = &src_p[delta_n];
+ src_n -= delta_n;
+ }
+ else
+ {
+ for ( word_i = 0; word_i < dst_n; word_i++ ) data_p[word_i] = 0;
+ if ( ctrl_p )
+ for ( word_i = 0; word_i < dst_n; word_i++ ) ctrl_p[word_i] = 0;
+ }
+
+
+ // LOOP OVER THE SOURCE ASSEMBLING WORDS AND PLACING THEM IN OUR VALUE:
+ //
+ // We stride right to left through the source in BITS_PER_DIGIT chunks.
+ // Each of those chunks is processed from left to right a bit at a time.
+ // We process the high order word specially, since there are less bits.
+
+ src_n = src_n - BITS_PER_DIGIT;
+ for (word_i=0; word_i < dst_n; word_i++)
+ {
+ src_i = src_n;
+
+
+ // PARTIAL LAST WORD TO ASSEMBLE:
+
+ if ( src_i < 0 )
+ {
+ src_n += BITS_PER_DIGIT;
+ src_i = 0;
+ data = 0;
+ ctrl = 0;
+ for ( src_i = 0; src_i < src_n; src_i++ )
+ {
+ ctrl = ctrl << 1;
+ data = data << 1;
+ switch( src_p[src_i] )
+ {
+ case 'X':
+ case 'x': ctrl = ctrl | 1; data = data | 1; break;
+ case '1': data = data | 1; break;
+ case 'Z':
+ case 'z': ctrl = ctrl | 1; break;
+ case '0': break;
+ default:
+ {
+ char msg[BUFSIZ];
+ std::sprintf( msg, "character string '%s' is not valid",
+ src_p );
+ SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_, msg);
+ }
+ break;
+ }
+ }
+ if ( ctrl_p ) ctrl_p[word_i] = ctrl;
+ data_p[word_i] = data;
+ break;
+ }
+
+
+ // FULL WORD TO BE ASSEMBLED:
+
+ ctrl = 0;
+ data = 0;
+ for ( bit_i = 0; bit_i < BITS_PER_DIGIT; bit_i++ )
+ {
+ ctrl = ctrl << 1;
+ data = data << 1;
+ switch( src_p[src_i++] )
+ {
+ case 'X':
+ case 'x': ctrl = ctrl | 1; data = data | 1; break;
+ case '1': data = data | 1; break;
+ case 'Z':
+ case 'z': ctrl = ctrl | 1; break;
+ case '0': break;
+ default:
+ {
+ char msg[BUFSIZ];
+ std::sprintf( msg, "character string '%s' is not valid",
+ src_p );
+ SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
+ }
+ break;
+ }
+ }
+ if ( ctrl_p ) ctrl_p[word_i] = ctrl;
+ data_p[word_i] = data;
+ src_n = src_n - BITS_PER_DIGIT;
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"parse_hex_bits"
+//
+// This function parses the supplied string into the supplied vector as a
+// right justified bit value.
+// src_p -> character string representing the bits to be parsed.
+// dst_n = number of words in data_p and ctrl_p.
+// data_p -> words w/32 bits to receive the value's data bits.
+// ctrl_p -> words w/32 bits to receive the value's control bits,
+// or zero.
+// Result is true if value was non-zero.
+//------------------------------------------------------------------------------
+void parse_hex_bits(
+ const char* src_p, int dst_n, sc_digit* data_p, sc_digit* ctrl_p )
+{
+ sc_digit ctrl; // Control word now assembling.
+ sc_digit data; // Data word now assembling.
+ int delta_n; // src_n - dst_n*BITS_PER_DIGIT.
+ int digit_i; // Number of digit now processing.
+ int src_i; // Index in src_p now accessing (left to right).
+ int src_n; // Length of source that is left in bits.
+ int word_i; // Bit within word now accessing (left to right).
+
+ // MAKE SURE WE HAVE A STRING TO PARSE:
+
+ if( src_p == 0 ) {
+ SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_,
+ "character string is zero" );
+ }
+ if( *src_p == 0 ) {
+ SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_,
+ "character string is empty" );
+ }
+
+
+ // INDEX INTO THE SOURCE TO A DEPTH THAT WILL ACCOMODATE OUR SIZE:
+ //
+ // If the source is smaller than our value initialize our value to zero.
+
+ src_n = strlen(src_p);
+ delta_n = src_n - (dst_n*8);
+ if ( delta_n > 0 )
+ {
+ src_p = &src_p[delta_n];
+ src_n -= delta_n;
+ }
+ else
+ {
+ for ( word_i = 0; word_i < dst_n; word_i++ ) data_p[word_i] = 0;
+ if ( ctrl_p )
+ for ( word_i = 0; word_i < dst_n; word_i++ ) ctrl_p[word_i] = 0;
+ }
+
+
+ // LOOP OVER THE SOURCE ASSEMBLING WORDS AND PLACING THEM IN OUR VALUE:
+ //
+ // We stride right to left through the source in BITS_PER_DIGIT chunks.
+ // Each of those chunks is processed from left to right a bit at a time.
+ // We process the high order word specially, since there are less bits.
+
+ src_n = src_n - 8;
+ for (word_i=0; word_i < dst_n; word_i++)
+ {
+ src_i = src_n;
+
+
+ // PARTIAL LAST WORD TO ASSEMBLE:
+
+ if ( src_i < 0 )
+ {
+ src_n += 8;
+ src_i = 0;
+ data = 0;
+ ctrl = 0;
+ for ( src_i = 0; src_i < src_n; src_i++ )
+ {
+ ctrl = ctrl << 4;
+ data = data << 4;
+ switch( src_p[src_i] )
+ {
+ case 'X':
+ case 'x': ctrl = ctrl | 15; data = data | 15; break;
+ case 'F':
+ case 'f': data = data | 15; break;
+ case 'E':
+ case 'e': data = data | 14; break;
+ case 'D':
+ case 'd': data = data | 13; break;
+ case 'C':
+ case 'c': data = data | 12; break;
+ case 'B':
+ case 'b': data = data | 11; break;
+ case 'A':
+ case 'a': data = data | 10; break;
+ case '9': data = data | 9; break;
+ case '8': data = data | 8; break;
+ case '7': data = data | 7; break;
+ case '6': data = data | 6; break;
+ case '5': data = data | 5; break;
+ case '4': data = data | 4; break;
+ case '3': data = data | 3; break;
+ case '2': data = data | 2; break;
+ case '1': data = data | 1; break;
+ case '0': break;
+ case 'Z':
+ case 'z': ctrl = ctrl | 15; break;
+ default:
+ {
+ char msg[BUFSIZ];
+ std::sprintf( msg, "character string '%s' is not valid",
+ src_p );
+ SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_, msg);
+ }
+ break;
+ }
+ }
+ if ( ctrl_p ) ctrl_p[word_i] = ctrl;
+ data_p[word_i] = data;
+ break;
+ }
+
+
+ // FULL WORD TO BE ASSEMBLED:
+
+ ctrl = 0;
+ data = 0;
+ for ( digit_i = 0; digit_i < 8; digit_i++ )
+ {
+ ctrl = ctrl << 4;
+ data = data << 4;
+ switch( src_p[src_i++] )
+ {
+ case 'X':
+ case 'x': ctrl = ctrl | 15; data = data | 15; break;
+ case 'F':
+ case 'f': data = data | 15; break;
+ case 'E':
+ case 'e': data = data | 14; break;
+ case 'D':
+ case 'd': data = data | 13; break;
+ case 'C':
+ case 'c': data = data | 12; break;
+ case 'B':
+ case 'b': data = data | 11; break;
+ case 'A':
+ case 'a': data = data | 10; break;
+ case '9': data = data | 9; break;
+ case '8': data = data | 8; break;
+ case '7': data = data | 7; break;
+ case '6': data = data | 6; break;
+ case '5': data = data | 5; break;
+ case '4': data = data | 4; break;
+ case '3': data = data | 3; break;
+ case '2': data = data | 2; break;
+ case '1': data = data | 1; break;
+ case '0': break;
+ case 'Z':
+ case 'z': ctrl = ctrl | 15; break;
+ default:
+ {
+ char msg[BUFSIZ];
+ std::sprintf( msg, "character string '%s' is not valid",
+ src_p );
+ SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
+ }
+ break;
+ }
+ }
+ if ( ctrl_p ) ctrl_p[word_i] = ctrl;
+ data_p[word_i] = data;
+ src_n = src_n - BITS_PER_DIGIT;
+ }
+}
+
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Utility functions involving unsigned vectors.
+// ----------------------------------------------------------------------------
+
+// Read u from a null terminated char string v. Note that operator>>
+// in sc_nbcommon.cpp is similar to this function.
+small_type
+vec_from_str(int unb, int und, sc_digit *u,
+ const char *v, sc_numrep base)
+{
+
+#ifdef DEBUG_SYSTEMC
+ assert((unb > 0) && (und > 0) && (u != NULL));
+ assert(v != NULL);
+#endif
+
+ is_valid_base(base);
+
+ small_type b, s; // base and sign.
+
+ v = get_base_and_sign(v, b, s);
+
+ if (base != SC_NOBASE) {
+ if (b == NB_DEFAULT_BASE)
+ b = base;
+ else {
+ char msg[BUFSIZ];
+ std::sprintf( msg,
+ "vec_from_str( int, int, sc_digit*, const char*, sc_numrep base ) : "
+ "base = %s does not match the default base",
+ to_string( base ).c_str() );
+ SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
+ }
+ }
+
+ vec_zero(und, u);
+
+ char c;
+
+ for ( ; (c = *v); ++v) {
+
+ if (isalnum(c)) {
+
+ small_type val; // Numeric value of a char.
+
+ if (isalpha(c)) // Hex digit.
+ val = toupper(c) - 'A' + 10;
+ else
+ val = c - '0';
+
+ if (val >= b) {
+ char msg[BUFSIZ];
+ std::sprintf( msg,
+ "vec_from_str( int, int, sc_digit*, const char*, sc_numrep base ) : "
+ "'%c' is not a valid digit in base %d",
+ *v, b );
+ SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
+ }
+
+ // digit = digit * b + val;
+ vec_mul_small_on(und, u, b);
+
+ if (val)
+ vec_add_small_on(und, u, val);
+
+ }
+ else {
+ char msg[BUFSIZ];
+ std::sprintf( msg,
+ "vec_from_str( int, int, sc_digit*, const char*, sc_numrep base ) : "
+ "'%c' is not a valid digit in base %d",
+ *v, b );
+ SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
+ }
+ }
+
+ return convert_signed_SM_to_2C_to_SM(s, unb, und, u);
+}
+
+
+// All vec_ functions assume that the vector to hold the result,
+// called w, has sufficient length to hold the result. For efficiency
+// reasons, we do not test whether or not we are out of bounds.
+
+// Compute w = u + v, where w, u, and v are vectors.
+// - ulen >= vlen
+// - wlen >= sc_max(ulen, vlen) + 1
+void
+vec_add(int ulen, const sc_digit *u,
+ int vlen, const sc_digit *v,
+ sc_digit *w)
+{
+
+#ifdef DEBUG_SYSTEMC
+ assert((ulen > 0) && (u != NULL));
+ assert((vlen > 0) && (v != NULL));
+ assert(w != NULL);
+ assert(ulen >= vlen);
+#endif
+
+ const sc_digit *uend = (u + ulen);
+ const sc_digit *vend = (v + vlen);
+
+ sc_digit carry = 0; // Also used as sum to save space.
+
+ // Add along the shorter v.
+ while (v < vend) {
+ carry += (*u++) + (*v++);
+ (*w++) = carry & DIGIT_MASK;
+ carry >>= BITS_PER_DIGIT;
+ }
+
+ // Propagate the carry.
+ while (carry && (u < uend)) {
+ carry = (*u++) + 1;
+ (*w++) = carry & DIGIT_MASK;
+ carry >>= BITS_PER_DIGIT;
+ }
+
+ // Copy the rest of u to the result.
+ while (u < uend)
+ (*w++) = (*u++);
+
+ // Propagate the carry if it is still 1.
+ if (carry)
+ (*w) = 1;
+
+}
+
+
+// Compute u += v, where u and v are vectors.
+// - ulen >= vlen
+void
+vec_add_on(int ulen, sc_digit *ubegin,
+ int vlen, const sc_digit *v)
+{
+
+#ifdef DEBUG_SYSTEMC
+ assert((ulen > 0) && (ubegin != NULL));
+ assert((vlen > 0) && (v != NULL));
+ assert(ulen >= vlen);
+#endif
+
+ sc_digit *u = ubegin;
+ const sc_digit *uend = (u + ulen);
+ const sc_digit *vend = (v + vlen);
+
+ sc_digit carry = 0; // Also used as sum to save space.
+
+ // Add along the shorter v.
+ while (v < vend) {
+ carry += (*u) + (*v++);
+ (*u++) = carry & DIGIT_MASK;
+ carry >>= BITS_PER_DIGIT;
+ }
+
+ // Propagate the carry.
+ while (carry && (u < uend)) {
+ carry = (*u) + 1;
+ (*u++) = carry & DIGIT_MASK;
+ carry >>= BITS_PER_DIGIT;
+ }
+
+#ifdef DEBUG_SYSTEMC
+ if( carry != 0 ) {
+ SC_REPORT_WARNING( sc_core::SC_ID_WITHOUT_MESSAGE_,
+ "vec_add_on( int, sc_digit*, int, const "
+ "sc_digit* ) : "
+ "result of addition is wrapped around" );
+ }
+#endif
+
+}
+
+
+// Compute u += v, where u and v are vectors.
+// - ulen < vlen
+void
+vec_add_on2(int ulen, sc_digit *ubegin,
+ int
+#ifdef DEBUG_SYSTEMC
+ vlen
+#endif
+ , const sc_digit *v)
+{
+
+#ifdef DEBUG_SYSTEMC
+ assert((ulen > 0) && (ubegin != NULL));
+ assert((vlen > 0) && (v != NULL));
+ assert(ulen < vlen);
+#endif
+
+ sc_digit *u = ubegin;
+ const sc_digit *uend = (u + ulen);
+
+ sc_digit carry = 0; // Also used as sum to save space.
+
+ // Add along the shorter u.
+ while (u < uend) {
+ carry += (*u) + (*v++);
+ (*u++) = carry & DIGIT_MASK;
+ carry >>= BITS_PER_DIGIT;
+ }
+
+#ifdef DEBUG_SYSTEMC
+ if( carry != 0 ) {
+ SC_REPORT_WARNING( sc_core::SC_ID_WITHOUT_MESSAGE_,
+ "vec_add_on2( int, sc_digit*, int, const "
+ "sc_digit* ) : "
+ "result of addition is wrapped around" );
+ }
+#endif
+}
+
+
+// Compute w = u + v, where w and u are vectors, and v is a scalar.
+void
+vec_add_small(int ulen, const sc_digit *u,
+ sc_digit v,
+ sc_digit *w)
+{
+
+#ifdef DEBUG_SYSTEMC
+ assert((ulen > 0) && (u != NULL));
+ assert(w != NULL);
+#endif
+
+ const sc_digit *uend = (u + ulen);
+
+ // Add along the shorter v.
+ sc_digit carry = (*u++) + v;
+ (*w++) = carry & DIGIT_MASK;
+ carry >>= BITS_PER_DIGIT;
+
+ // Propagate the carry.
+ while (carry && (u < uend)) {
+ carry = (*u++) + 1;
+ (*w++) = carry & DIGIT_MASK;
+ carry >>= BITS_PER_DIGIT;
+ }
+
+ // Copy the rest of u to the result.
+ while (u < uend)
+ (*w++) = (*u++);
+
+ // Propagate the carry if it is still 1.
+ if (carry)
+ (*w) = 1;
+
+}
+
+// Compute u += v, where u is vectors, and v is a scalar.
+void
+vec_add_small_on(int ulen, sc_digit *u, sc_digit v)
+{
+
+#ifdef DEBUG_SYSTEMC
+ assert((ulen > 0) && (u != NULL));
+#endif
+
+ int i = 0;
+
+ while (v && (i < ulen)) {
+ v += u[i];
+ u[i++] = v & DIGIT_MASK;
+ v >>= BITS_PER_DIGIT;
+ }
+
+#ifdef DEBUG_SYSTEMC
+ if( v != 0 ) {
+ SC_REPORT_WARNING( sc_core::SC_ID_WITHOUT_MESSAGE_,
+ "vec_add_small_on( int, sc_digit*, unsigned "
+ "long ) : "
+ "result of addition is wrapped around" );
+ }
+#endif
+
+}
+
+// Compute w = u - v, where w, u, and v are vectors.
+// - ulen >= vlen
+// - wlen >= sc_max(ulen, vlen)
+void
+vec_sub(int ulen, const sc_digit *u,
+ int vlen, const sc_digit *v,
+ sc_digit *w)
+{
+
+#ifdef DEBUG_SYSTEMC
+ assert((ulen > 0) && (u != NULL));
+ assert((vlen > 0) && (v != NULL));
+ assert(w != NULL);
+ assert(ulen >= vlen);
+#endif
+
+ const sc_digit *uend = (u + ulen);
+ const sc_digit *vend = (v + vlen);
+
+ sc_digit borrow = 0; // Also used as diff to save space.
+
+ // Subtract along the shorter v.
+ while (v < vend) {
+ borrow = ((*u++) + DIGIT_RADIX) - (*v++) - borrow;
+ (*w++) = borrow & DIGIT_MASK;
+ borrow = 1 - (borrow >> BITS_PER_DIGIT);
+ }
+
+ // Propagate the borrow.
+ while (borrow && (u < uend)) {
+ borrow = ((*u++) + DIGIT_RADIX) - 1;
+ (*w++) = borrow & DIGIT_MASK;
+ borrow = 1 - (borrow >> BITS_PER_DIGIT);
+ }
+
+#ifdef DEBUG_SYSTEMC
+ assert(borrow == 0);
+#endif
+
+ // Copy the rest of u to the result.
+ while (u < uend)
+ (*w++) = (*u++);
+
+}
+
+// Compute u = u - v, where u and v are vectors.
+// - u > v
+// - ulen >= vlen
+void
+vec_sub_on(int ulen, sc_digit *ubegin,
+ int vlen, const sc_digit *v)
+{
+
+#ifdef DEBUG_SYSTEMC
+ assert((ulen > 0) && (ubegin != NULL));
+ assert((vlen > 0) && (v != NULL));
+ assert(ulen >= vlen);
+#endif
+
+ sc_digit *u = ubegin;
+ const sc_digit *uend = (u + ulen);
+ const sc_digit *vend = (v + vlen);
+
+ sc_digit borrow = 0; // Also used as diff to save space.
+
+ // Subtract along the shorter v.
+ while (v < vend) {
+ borrow = ((*u) + DIGIT_RADIX) - (*v++) - borrow;
+ (*u++) = borrow & DIGIT_MASK;
+ borrow = 1 - (borrow >> BITS_PER_DIGIT);
+ }
+
+ // Propagate the borrow.
+ while (borrow && (u < uend)) {
+ borrow = ((*u) + DIGIT_RADIX) - 1;
+ (*u++) = borrow & DIGIT_MASK;
+ borrow = 1 - (borrow >> BITS_PER_DIGIT);
+ }
+
+#ifdef DEBUG_SYSTEMC
+ assert(borrow == 0);
+#endif
+
+}
+
+// Compute u = v - u, where u and v are vectors.
+// - v > u
+// - ulen <= vlen or ulen > ulen
+void
+vec_sub_on2(int ulen, sc_digit *ubegin,
+ int vlen, const sc_digit *v)
+{
+
+#ifdef DEBUG_SYSTEMC
+ assert((ulen > 0) && (ubegin != NULL));
+ assert((vlen > 0) && (v != NULL));
+#endif
+
+ sc_digit *u = ubegin;
+ const sc_digit *uend = (u + sc_min(ulen, vlen));
+
+ sc_digit borrow = 0; // Also used as diff to save space.
+
+ // Subtract along the shorter u.
+ while (u < uend) {
+ borrow = ((*v++) + DIGIT_RADIX) - (*u) - borrow;
+ (*u++) = borrow & DIGIT_MASK;
+ borrow = 1 - (borrow >> BITS_PER_DIGIT);
+ }
+
+#ifdef DEBUG_SYSTEMC
+ if( borrow != 0 ) {
+ SC_REPORT_WARNING( sc_core::SC_ID_WITHOUT_MESSAGE_,
+ "vec_sub_on2( int, sc_digit*, int, const "
+ "sc_digit* ) : "
+ "result of subtraction is wrapped around" );
+ }
+#endif
+}
+
+// Compute w = u - v, where w and u are vectors, and v is a scalar.
+void
+vec_sub_small(int ulen, const sc_digit *u,
+ sc_digit v,
+ sc_digit *w)
+{
+
+#ifdef DEBUG_SYSTEMC
+ assert(ulen > 0);
+ assert(u != NULL);
+#endif
+
+ const sc_digit *uend = (u + ulen);
+
+ // Add along the shorter v.
+ sc_digit borrow = ((*u++) + DIGIT_RADIX) - v;
+ (*w++) = borrow & DIGIT_MASK;
+ borrow = 1 - (borrow >> BITS_PER_DIGIT);
+
+ // Propagate the borrow.
+ while (borrow && (u < uend)) {
+ borrow = ((*u++) + DIGIT_RADIX) - 1;
+ (*w++) = borrow & DIGIT_MASK;
+ borrow = 1 - (borrow >> BITS_PER_DIGIT);
+ }
+
+#ifdef DEBUG_SYSTEMC
+ assert(borrow == 0);
+#endif
+
+ // Copy the rest of u to the result.
+ while (u < uend)
+ (*w++) = (*u++);
+
+}
+
+
+// Compute u -= v, where u is vectors, and v is a scalar.
+void
+vec_sub_small_on(int ulen, sc_digit *u, sc_digit v)
+{
+
+#ifdef DEBUG_SYSTEMC
+ assert((ulen > 0) && (u != NULL));
+#endif
+
+ for (int i = 0; i < ulen; ++i) {
+ v = (u[i] + DIGIT_RADIX) - v;
+ u[i] = v & DIGIT_MASK;
+ v = 1 - (v >> BITS_PER_DIGIT);
+ }
+
+#ifdef DEBUG_SYSTEMC
+ assert(v == 0);
+#endif
+
+}
+
+// Compute w = u * v, where w, u, and v are vectors.
+void
+vec_mul(int ulen, const sc_digit *u,
+ int vlen, const sc_digit *vbegin,
+ sc_digit *wbegin)
+{
+
+ /* Consider u = Ax + B and v = Cx + D where x is equal to
+ HALF_DIGIT_RADIX. In other words, A is the higher half of u and
+ B is the lower half of u. The interpretation for v is
+ similar. Then, we have the following picture:
+
+ u_h u_l
+ u: -------- --------
+ A B
+
+ v_h v_l
+ v: -------- --------
+ C D
+
+ result (d):
+ carry_before: -------- --------
+ carry_h carry_l
+ result_before: -------- -------- -------- --------
+ R1_h R1_l R0_h R0_l
+ -------- --------
+ BD_h BD_l
+ -------- --------
+ AD_h AD_l
+ -------- --------
+ BC_h BC_l
+ -------- --------
+ AC_h AC_l
+ result_after: -------- -------- -------- --------
+ R1_h' R1_l' R0_h' R0_l'
+
+ prod_l = R0_h|R0_l + B * D + 0|carry_l
+ = R0_h|R0_l + BD_h|BD_l + 0|carry_l
+
+ prod_h = A * D + B * C + high_half(prod_l) + carry_h
+ = AD_h|AD_l + BC_h|BC_l + high_half(prod_l) + 0|carry_h
+
+ carry = A * C + high_half(prod_h)
+ = AC_h|AC_l + high_half(prod_h)
+
+ R0_l' = low_half(prod_l)
+
+ R0_h' = low_half(prod_h)
+
+ R0 = high_half(prod_h)|low_half(prod_l)
+
+ where '|' is the concatenation operation and the suffixes 0 and 1
+ show the iteration number, i.e., 0 is the current iteration and 1
+ is the next iteration.
+
+ NOTE: sc_max(prod_l, prod_h, carry) <= 2 * x^2 - 1, so any
+ of these numbers can be stored in a digit.
+
+ NOTE: low_half(u) returns the lower BITS_PER_HALF_DIGIT of u,
+ whereas high_half(u) returns the rest of the bits, which may
+ contain more bits than BITS_PER_HALF_DIGIT.
+ */
+
+#ifdef DEBUG_SYSTEMC
+ assert((ulen > 0) && (u != NULL));
+ assert((vlen > 0) && (vbegin != NULL));
+ assert(wbegin != NULL);
+#endif
+
+#define prod_h carry
+
+ const sc_digit *uend = (u + ulen);
+ const sc_digit *vend = (vbegin + vlen);
+
+ while (u < uend) {
+
+ sc_digit u_h = (*u++); // A|B
+ sc_digit u_l = low_half(u_h); // B
+ u_h = high_half(u_h); // A
+
+#ifdef DEBUG_SYSTEMC
+ // The overflow bits must be zero.
+ assert(u_h == (u_h & HALF_DIGIT_MASK));
+#endif
+
+ sc_digit carry = 0;
+
+ sc_digit *w = (wbegin++);
+
+ const sc_digit *v = vbegin;
+
+ while (v < vend) {
+
+ sc_digit v_h = (*v++); // C|D
+ sc_digit v_l = low_half(v_h); // D
+
+ v_h = high_half(v_h); // C
+
+#ifdef DEBUG_SYSTEMC
+ // The overflow bits must be zero.
+ assert(v_h == (v_h & HALF_DIGIT_MASK));
+#endif
+
+ sc_digit prod_l = (*w) + u_l * v_l + low_half(carry);
+
+ prod_h = u_h * v_l + u_l * v_h + high_half(prod_l) + high_half(carry);
+
+ (*w++) = concat(low_half(prod_h), low_half(prod_l));
+
+ carry = u_h * v_h + high_half(prod_h);
+
+ }
+
+ (*w) = carry;
+
+ }
+
+#undef prod_h
+
+}
+
+// Compute w = u * v, where w and u are vectors, and v is a scalar.
+// - 0 < v < HALF_DIGIT_RADIX.
+void
+vec_mul_small(int ulen, const sc_digit *u,
+ sc_digit v, sc_digit *w)
+{
+
+#ifdef DEBUG_SYSTEMC
+ assert((ulen > 0) && (u != NULL));
+ assert(w != NULL);
+ assert((0 < v) && (v < HALF_DIGIT_RADIX));
+#endif
+
+#define prod_h carry
+
+ const sc_digit *uend = (u + ulen);
+
+ sc_digit carry = 0;
+
+ while (u < uend) {
+
+ sc_digit u_AB = (*u++);
+
+#ifdef DEBUG_SYSTEMC
+ // The overflow bits must be zero.
+ assert(high_half(u_AB) == high_half_masked(u_AB));
+#endif
+
+ sc_digit prod_l = v * low_half(u_AB) + low_half(carry);
+
+ prod_h = v * high_half(u_AB) + high_half(prod_l) + high_half(carry);
+
+ (*w++) = concat(low_half(prod_h), low_half(prod_l));
+
+ carry = high_half(prod_h);
+
+ }
+
+ (*w) = carry;
+
+#undef prod_h
+
+}
+
+// Compute u = u * v, where u is a vector, and v is a scalar.
+// - 0 < v < HALF_DIGIT_RADIX.
+void
+vec_mul_small_on(int ulen, sc_digit *u, sc_digit v)
+{
+
+#ifdef DEBUG_SYSTEMC
+ assert((ulen > 0) && (u != NULL));
+ assert((0 < v) && (v < HALF_DIGIT_RADIX));
+#endif
+
+#define prod_h carry
+
+ sc_digit carry = 0;
+
+ for (int i = 0; i < ulen; ++i) {
+
+#ifdef DEBUG_SYSTEMC
+ // The overflow bits must be zero.
+ assert(high_half(u[i]) == high_half_masked(u[i]));
+#endif
+
+ sc_digit prod_l = v * low_half(u[i]) + low_half(carry);
+
+ prod_h = v * high_half(u[i]) + high_half(prod_l) + high_half(carry);
+
+ u[i] = concat(low_half(prod_h), low_half(prod_l));
+
+ carry = high_half(prod_h);
+
+ }
+
+#undef prod_h
+
+#ifdef DEBUG_SYSTEMC
+ if( carry != 0 ) {
+ SC_REPORT_WARNING( sc_core::SC_ID_WITHOUT_MESSAGE_,
+ "vec_mul_small_on( int, sc_digit*, unsigned "
+ "long ) : "
+ "result of multiplication is wrapped around" );
+ }
+#endif
+}
+
+// Compute w = u / v, where w, u, and v are vectors.
+// - u and v are assumed to have at least two digits as uchars.
+void
+vec_div_large(int ulen, const sc_digit *u,
+ int vlen, const sc_digit *v,
+ sc_digit *w)
+{
+
+#ifdef DEBUG_SYSTEMC
+ assert((ulen > 0) && (u != NULL));
+ assert((vlen > 0) && (v != NULL));
+ assert(w != NULL);
+ assert(BITS_PER_DIGIT >= 3 * BITS_PER_BYTE);
+#endif
+
+ // We will compute q = x / y where x = u and y = v. The reason for
+ // using x and y is that x and y are BYTE_RADIX copies of u and v,
+ // respectively. The use of BYTE_RADIX radix greatly simplifies the
+ // complexity of the division operation. These copies are also
+ // needed even when we use DIGIT_RADIX representation.
+
+ int xlen = BYTES_PER_DIGIT * ulen + 1;
+ int ylen = BYTES_PER_DIGIT * vlen;
+
+#ifdef SC_MAX_NBITS
+ uchar x[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)];
+ uchar y[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)];
+ uchar q[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)];
+#else
+ uchar *x = new uchar[xlen];
+ uchar *y = new uchar[ylen];
+ // valgrind complains about us accessing too far to so leave a buffer.
+ uchar *q = new uchar[(xlen - ylen) + 10];
+#endif
+
+ // q corresponds to w.
+
+ // Set (uchar) x = (sc_digit) u.
+ xlen = vec_to_char(ulen, u, xlen, x);
+
+ // Skip all the leading zeros in x.
+ while ((--xlen >= 0) && (! x[xlen])) continue;
+ xlen++;
+
+ // Set (uchar) y = (sc_digit) v.
+ ylen = vec_to_char(vlen, v, ylen, y);
+
+ // Skip all the leading zeros in y.
+ while ((--ylen >= 0) && (! y[ylen])) continue;
+ ylen++;
+
+#ifdef DEBUG_SYSTEMC
+ assert(xlen > 1);
+ assert(ylen > 1);
+#endif
+
+ // At this point, all the leading zeros are eliminated from x and y.
+
+ // Zero the last digit of x.
+ x[xlen] = 0;
+
+ // The first two digits of y.
+ sc_digit y2 = (y[ylen - 1] << BITS_PER_BYTE) + y[ylen - 2];
+
+ const sc_digit DOUBLE_BITS_PER_BYTE = 2 * BITS_PER_BYTE;
+
+ // Find each q[k].
+ for (int k = (xlen - ylen); k >= 0; --k) {
+
+ // qk is a guess for q[k] such that q[k] = qk or qk - 1.
+ sc_digit qk;
+
+ // Find qk by just using 2 digits of y and 3 digits of x. The
+ // following code assumes that sizeof(sc_digit) >= 3 BYTEs.
+ int k2 = k + ylen;
+
+ qk = ((x[k2] << DOUBLE_BITS_PER_BYTE) +
+ (x[k2 - 1] << BITS_PER_BYTE) + x[k2 - 2]) / y2;
+
+ if (qk >= BYTE_RADIX) // qk cannot be larger than the largest
+ qk = BYTE_RADIX - 1; // digit in BYTE_RADIX.
+
+ // q[k] = qk or qk - 1. The following if-statement determines which:
+ if (qk) {
+
+ uchar *xk = (x + k); // A shortcut for x[k].
+
+ // x = x - y * qk :
+ sc_digit carry = 0;
+
+ for (int i = 0; i < ylen; ++i) {
+ carry += y[i] * qk;
+ sc_digit diff = (xk[i] + BYTE_RADIX) - (carry & BYTE_MASK);
+ xk[i] = (uchar)(diff & BYTE_MASK);
+ carry = (carry >> BITS_PER_BYTE) + (1 - (diff >> BITS_PER_BYTE));
+ }
+
+ // If carry, qk may be one too large.
+ if (carry) {
+
+ // 2's complement the last digit.
+ carry = (xk[ylen] + BYTE_RADIX) - carry;
+ xk[ylen] = (uchar)(carry & BYTE_MASK);
+ carry = 1 - (carry >> BITS_PER_BYTE);
+
+ if (carry) {
+
+ // qk was one too large, so decrement it.
+ --qk;
+
+ // Since qk was decreased by one, y must be added to x:
+ // That is, x = x - y * (qk - 1) = x - y * qk + y = x_above + y.
+ carry = 0;
+
+ for (int i = 0; i < ylen; ++i) {
+ carry += xk[i] + y[i];
+ xk[i] = (uchar)(carry & BYTE_MASK);
+ carry >>= BITS_PER_BYTE;
+ }
+
+ if (carry)
+ xk[ylen] = (uchar)((xk[ylen] + 1) & BYTE_MASK);
+
+ } // second if carry
+ } // first if carry
+ } // if qk
+
+ q[k] = (uchar)qk;
+
+ } // for k
+
+ // Set (sc_digit) w = (uchar) q.
+ vec_from_char(xlen - ylen + 1, q, ulen, w);
+
+#ifndef SC_MAX_NBITS
+ delete [] x;
+ delete [] y;
+ delete [] q;
+#endif
+
+}
+
+// Compute w = u / v, where u and w are vectors, and v is a scalar.
+// - 0 < v < HALF_DIGIT_RADIX. Below, we rename w to q.
+void
+vec_div_small(int ulen, const sc_digit *u,
+ sc_digit v, sc_digit *q)
+{
+
+ // Given (u = u_1u_2...u_n)_b = (q = q_1q_2...q_n) * v + r, where b
+ // is the base, and 0 <= r < v. Then, the algorithm is as follows:
+ //
+ // r = 0;
+ // for (j = 1; j <= n; j++) {
+ // q_j = (r * b + u_j) / v;
+ // r = (r * b + u_j) % v;
+ // }
+ //
+ // In our case, b = DIGIT_RADIX, and u = Ax + B and q = Cx + D where
+ // x = HALF_DIGIT_RADIX. Note that r < v < x and b = x^2. Then, a
+ // typical situation is as follows:
+ //
+ // ---- ----
+ // 0 r
+ // ---- ----
+ // A B
+ // ---- ---- ----
+ // r A B = r * b + u
+ //
+ // Hence, C = (r|A) / v.
+ // D = (((r|A) % v)|B) / v
+ // r = (((r|A) % v)|B) % v
+
+#ifdef DEBUG_SYSTEMC
+ assert((ulen > 0) && (u != NULL));
+ assert(q != NULL);
+ assert((0 < v) && (v < HALF_DIGIT_RADIX));
+#endif
+
+#define q_h r
+
+ sc_digit r = 0;
+ const sc_digit *ubegin = u;
+
+ u += ulen;
+ q += ulen;
+
+ while (ubegin < u) {
+
+ sc_digit u_AB = (*--u); // A|B
+
+#ifdef DEBUG_SYSTEMC
+ // The overflow bits must be zero.
+ assert(high_half(u_AB) == high_half_masked(u_AB));
+#endif
+
+ sc_digit num = concat(r, high_half(u_AB)); // num = r|A
+ q_h = num / v; // C
+ num = concat((num % v), low_half(u_AB)); // num = (((r|A) % v)|B)
+ (*--q) = concat(q_h, num / v); // q = C|D
+ r = num % v;
+
+ }
+
+#undef q_h
+
+}
+
+// Compute w = u % v, where w, u, and v are vectors.
+// - u and v are assumed to have at least two digits as uchars.
+void
+vec_rem_large(int ulen, const sc_digit *u,
+ int vlen, const sc_digit *v,
+ sc_digit *w)
+{
+
+#ifdef DEBUG_SYSTEMC
+ assert((ulen > 0) && (u != NULL));
+ assert((vlen > 0) && (v != NULL));
+ assert(w != NULL);
+ assert(BITS_PER_DIGIT >= 3 * BITS_PER_BYTE);
+#endif
+
+ // This function is adapted from vec_div_large.
+
+ int xlen = BYTES_PER_DIGIT * ulen + 1;
+ int ylen = BYTES_PER_DIGIT * vlen;
+
+#ifdef SC_MAX_NBITS
+ uchar x[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)];
+ uchar y[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)];
+#else
+ uchar *x = new uchar[xlen];
+ uchar *y = new uchar[ylen];
+#endif
+
+ // r corresponds to w.
+
+ // Set (uchar) x = (sc_digit) u.
+ xlen = vec_to_char(ulen, u, xlen, x);
+
+ // Skip all the leading zeros in x.
+ while ((--xlen >= 0) && (! x[xlen])) continue;
+ xlen++;
+
+ // Set (uchar) y = (sc_digit) v.
+ ylen = vec_to_char(vlen, v, ylen, y);
+
+ // Skip all the leading zeros in y.
+ while ((--ylen >= 0) && (! y[ylen])) continue;
+ ylen++;
+
+#ifdef DEBUG_SYSTEMC
+ assert(xlen > 1);
+ assert(ylen > 1);
+#endif
+
+ // At this point, all the leading zeros are eliminated from x and y.
+
+ // Zero the last digit of x.
+ x[xlen] = 0;
+
+ // The first two digits of y.
+ sc_digit y2 = (y[ylen - 1] << BITS_PER_BYTE) + y[ylen - 2];
+
+ const sc_digit DOUBLE_BITS_PER_BYTE = 2 * BITS_PER_BYTE;
+
+ // Find each q[k].
+ for (int k = xlen - ylen; k >= 0; --k) {
+
+ // qk is a guess for q[k] such that q[k] = qk or qk - 1.
+ sc_digit qk;
+
+ // Find qk by just using 2 digits of y and 3 digits of x. The
+ // following code assumes that sizeof(sc_digit) >= 3 BYTEs.
+ int k2 = k + ylen;
+
+ qk = ((x[k2] << DOUBLE_BITS_PER_BYTE) +
+ (x[k2 - 1] << BITS_PER_BYTE) + x[k2 - 2]) / y2;
+
+ if (qk >= BYTE_RADIX) // qk cannot be larger than the largest
+ qk = BYTE_RADIX - 1; // digit in BYTE_RADIX.
+
+ // q[k] = qk or qk - 1. The following if-statement determines which.
+ if (qk) {
+
+ uchar *xk = (x + k); // A shortcut for x[k].
+
+ // x = x - y * qk;
+ sc_digit carry = 0;
+
+ for (int i = 0; i < ylen; ++i) {
+ carry += y[i] * qk;
+ sc_digit diff = (xk[i] + BYTE_RADIX) - (carry & BYTE_MASK);
+ xk[i] = (uchar)(diff & BYTE_MASK);
+ carry = (carry >> BITS_PER_BYTE) + (1 - (diff >> BITS_PER_BYTE));
+ }
+
+ if (carry) {
+
+ // 2's complement the last digit.
+ carry = (xk[ylen] + BYTE_RADIX) - carry;
+ xk[ylen] = (uchar)(carry & BYTE_MASK);
+ carry = 1 - (carry >> BITS_PER_BYTE);
+
+ if (carry) {
+
+ // qk was one too large, so decrement it.
+ // --qk;
+
+ // x = x - y * (qk - 1) = x - y * qk + y = x_above + y.
+ carry = 0;
+
+ for (int i = 0; i < ylen; ++i) {
+ carry += xk[i] + y[i];
+ xk[i] = (uchar)(carry & BYTE_MASK);
+ carry >>= BITS_PER_BYTE;
+ }
+
+ if (carry)
+ xk[ylen] = (uchar)((xk[ylen] + 1) & BYTE_MASK);
+
+ } // second if carry
+ } // first if carry
+ } // if qk
+ } // for k
+
+ // Set (sc_digit) w = (uchar) x for the remainder.
+ vec_from_char(ylen, x, ulen, w);
+
+#ifndef SC_MAX_NBITS
+ delete [] x;
+ delete [] y;
+#endif
+
+}
+
+// Compute r = u % v, where u is a vector, and r and v are scalars.
+// - 0 < v < HALF_DIGIT_RADIX.
+// - The remainder r is returned.
+sc_digit
+vec_rem_small(int ulen, const sc_digit *u, sc_digit v)
+{
+
+#ifdef DEBUG_SYSTEMC
+ assert((ulen > 0) && (u != NULL));
+ assert((0 < v) && (v < HALF_DIGIT_RADIX));
+#endif
+
+ // This function is adapted from vec_div_small().
+
+ sc_digit r = 0;
+ const sc_digit *ubegin = u;
+
+ u += ulen;
+
+ while (ubegin < u) {
+ sc_digit u_AB = (*--u); // A|B
+
+#ifdef DEBUG_SYSTEMC
+ // The overflow bits must be zero.
+ assert(high_half(u_AB) == high_half_masked(u_AB));
+#endif
+
+ // r = (((r|A) % v)|B) % v
+ r = (concat(((concat(r, high_half(u_AB))) % v), low_half(u_AB))) % v;
+ }
+
+ return r;
+
+}
+
+// u = u / v, r = u % v.
+sc_digit
+vec_rem_on_small(int ulen, sc_digit *u, sc_digit v)
+{
+
+#ifdef DEBUG_SYSTEMC
+ assert((ulen > 0) && (u != NULL));
+ assert(v > 0);
+#endif
+
+#define q_h r
+
+ sc_digit r = 0;
+ const sc_digit *ubegin = u;
+
+ u += ulen;
+
+ while (ubegin < u) {
+
+ sc_digit u_AB = (*--u); // A|B
+
+#ifdef DEBUG_SYSTEMC
+ // The overflow bits must be zero.
+ assert(high_half(u_AB) == high_half_masked(u_AB));
+#endif
+
+ sc_digit num = concat(r, high_half(u_AB)); // num = r|A
+ q_h = num / v; // C
+ num = concat((num % v), low_half(u_AB)); // num = (((r|A) % v)|B)
+ (*u) = concat(q_h, num / v); // q = C|D
+ r = num % v;
+
+ }
+
+#undef q_h
+
+ return r;
+
+}
+
+// Set (uchar) v = (sc_digit) u. Return the new vlen.
+int
+vec_to_char(int ulen, const sc_digit *u,
+ int vlen, uchar *v)
+{
+
+#ifdef DEBUG_SYSTEMC
+ assert((ulen > 0) && (u != NULL));
+ assert((vlen > 0) && (v != NULL));
+#endif
+
+ int nbits = ulen * BITS_PER_DIGIT;
+
+ int right = 0;
+ int left = right + BITS_PER_BYTE - 1;
+
+ vlen = 0;
+
+ while (nbits > 0) {
+
+ int left_digit = left / BITS_PER_DIGIT;
+ int right_digit = right / BITS_PER_DIGIT;
+
+ int nsr = ((vlen << LOG2_BITS_PER_BYTE) % BITS_PER_DIGIT);
+
+ int d = u[right_digit] >> nsr;
+
+ if (left_digit != right_digit) {
+
+ if (left_digit < ulen)
+ d |= u[left_digit] << (BITS_PER_DIGIT - nsr);
+
+ }
+
+ v[vlen++] = (uchar)(d & BYTE_MASK);
+
+ left += BITS_PER_BYTE;
+ right += BITS_PER_BYTE;
+ nbits -= BITS_PER_BYTE;
+
+ }
+
+ return vlen;
+
+}
+
+// Set (sc_digit) v = (uchar) u.
+// - sizeof(uchar) <= sizeof(sc_digit),
+void
+vec_from_char(int ulen, const uchar *u,
+ int vlen, sc_digit *v)
+{
+
+#ifdef DEBUG_SYSTEMC
+ assert((ulen > 0) && (u != NULL));
+ assert((vlen > 0) && (v != NULL));
+ assert(sizeof(uchar) <= sizeof(sc_digit));
+#endif
+
+ sc_digit *vend = (v + vlen);
+
+ const int nsr = BITS_PER_DIGIT - BITS_PER_BYTE;
+ const sc_digit mask = one_and_ones(nsr);
+
+ (*v) = (sc_digit) u[ulen - 1];
+
+ for (int i = ulen - 2; i >= 0; --i) {
+
+ // Manual inlining of vec_shift_left().
+
+ sc_digit *viter = v;
+
+ sc_digit carry = 0;
+
+ while (viter < vend) {
+ sc_digit vval = (*viter);
+ (*viter++) = (((vval & mask) << BITS_PER_BYTE) | carry);
+ carry = vval >> nsr;
+ }
+
+ if (viter < vend)
+ (*viter) = carry;
+
+ (*v) |= (sc_digit) u[i];
+
+ }
+
+}
+
+// Set u <<= nsl.
+// If nsl is negative, it is ignored.
+void
+vec_shift_left(int ulen, sc_digit *u, int nsl)
+{
+
+#ifdef DEBUG_SYSTEMC
+ assert((ulen > 0) && (u != NULL));
+#endif
+
+ if (nsl <= 0)
+ return;
+
+ // Shift left whole digits if nsl is large enough.
+ if (nsl >= (int) BITS_PER_DIGIT) {
+
+ int nd;
+
+ if (nsl % BITS_PER_DIGIT == 0) {
+ nd = nsl / BITS_PER_DIGIT; // No need to use DIV_CEIL(nsl).
+ nsl = 0;
+ }
+ else {
+ nd = DIV_CEIL(nsl) - 1;
+ nsl -= nd * BITS_PER_DIGIT;
+ }
+
+ if (nd) {
+
+ // Shift left for nd digits.
+ for (int j = ulen - 1; j >= nd; --j)
+ u[j] = u[j - nd];
+
+ vec_zero( sc_min( nd, ulen ), u );
+
+ }
+
+ if (nsl == 0)
+ return;
+
+ }
+
+ // Shift left if nsl < BITS_PER_DIGIT.
+ sc_digit *uiter = u;
+ sc_digit *uend = uiter + ulen;
+
+ int nsr = BITS_PER_DIGIT - nsl;
+ sc_digit mask = one_and_ones(nsr);
+
+ sc_digit carry = 0;
+
+ while (uiter < uend) {
+ sc_digit uval = (*uiter);
+ (*uiter++) = (((uval & mask) << nsl) | carry);
+ carry = uval >> nsr;
+ }
+
+ if (uiter < uend)
+ (*uiter) = carry;
+
+}
+
+// Set u >>= nsr.
+// If nsr is negative, it is ignored.
+void
+vec_shift_right(int ulen, sc_digit *u, int nsr, sc_digit fill)
+{
+
+#ifdef DEBUG_SYSTEMC
+ assert((ulen > 0) && (u != NULL));
+#endif
+
+ // fill is usually either 0 or DIGIT_MASK; it can be any value.
+
+ if (nsr <= 0)
+ return;
+
+ // Shift right whole digits if nsr is large enough.
+ if (nsr >= (int) BITS_PER_DIGIT) {
+
+ int nd;
+
+ if (nsr % BITS_PER_DIGIT == 0) {
+ nd = nsr / BITS_PER_DIGIT;
+ nsr = 0;
+ }
+ else {
+ nd = DIV_CEIL(nsr) - 1;
+ nsr -= nd * BITS_PER_DIGIT;
+ }
+
+ if (nd) {
+
+ // Shift right for nd digits.
+ for (int j = 0; j < (ulen - nd); ++j)
+ u[j] = u[j + nd];
+
+ if (fill) {
+ for (int j = ulen - sc_min( nd, ulen ); j < ulen; ++j)
+ u[j] = fill;
+ }
+ else
+ vec_zero(ulen - sc_min( nd, ulen ), ulen, u);
+
+ }
+
+ if (nsr == 0)
+ return;
+
+ }
+
+ // Shift right if nsr < BITS_PER_DIGIT.
+ sc_digit *ubegin = u;
+ sc_digit *uiter = (ubegin + ulen);
+
+ int nsl = BITS_PER_DIGIT - nsr;
+ sc_digit mask = one_and_ones(nsr);
+
+ sc_digit carry = (fill & mask) << nsl;
+
+ while (ubegin < uiter) {
+ sc_digit uval = (*--uiter);
+ (*uiter) = (uval >> nsr) | carry;
+ carry = (uval & mask) << nsl;
+ }
+
+}
+
+
+// Let u[l..r], where l and r are left and right bit positions
+// respectively, be equal to its mirror image.
+void
+vec_reverse(int unb, int und, sc_digit *ud,
+ int l, int r)
+{
+
+#ifdef DEBUG_SYSTEMC
+ assert((unb > 0) && (und > 0) && (ud != NULL));
+ assert((0 <= r) && (r <= l) && (l < unb));
+#endif
+
+ if (l < r) {
+ char msg[BUFSIZ];
+ std::sprintf( msg, "vec_reverse( int, int, sc_digit*, int l, int r ) : "
+ "l = %d < r = %d is not valid",
+ l, r );
+ SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
+ }
+
+ // Make sure that l and r are within bounds.
+ r = sc_max(r, 0);
+ l = sc_min(l, unb - 1);
+
+ // Allocate memory for processing.
+#ifdef SC_MAX_NBITS
+ sc_digit d[MAX_NDIGITS];
+#else
+ sc_digit *d = new sc_digit[und];
+#endif
+
+ // d is a copy of ud.
+ vec_copy(und, d, ud);
+
+ // Based on the value of the ith in d, find the value of the jth bit
+ // in ud.
+
+ for (int i = l, j = r; i >= r; --i, ++j) {
+
+ if ((d[digit_ord(i)] & one_and_zeros(bit_ord(i))) != 0) // Test.
+ ud[digit_ord(j)] |= one_and_zeros(bit_ord(j)); // Set.
+ else
+ ud[digit_ord(j)] &= ~(one_and_zeros(bit_ord(j))); // Clear.
+
+ }
+
+#ifndef SC_MAX_NBITS
+ delete [] d;
+#endif
+
+}
+
+} // namespace sc_dt
+
+
+// End of file.
diff --git a/ext/systemc/src/sysc/datatypes/int/sc_nbutils.h b/ext/systemc/src/sysc/datatypes/int/sc_nbutils.h
new file mode 100644
index 000000000..0bd4b4b03
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/int/sc_nbutils.h
@@ -0,0 +1,1051 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_nbutils.h -- External and friend functions for both sc_signed and
+ sc_unsigned classes.
+
+ Original Author: Ali Dasdan, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_nbutils.h,v $
+// Revision 1.6 2011/09/08 16:12:15 acg
+// Philipp A. Hartmann: fix issue with Sun machines wrt real math libraries.
+//
+// Revision 1.5 2011/08/26 23:00:01 acg
+// Torsten Maehne: remove use of ieeefp.h.
+//
+// Revision 1.4 2011/08/15 16:43:24 acg
+// Torsten Maehne: changes to remove unused argument warnings.
+//
+// Revision 1.3 2011/02/18 20:19:15 acg
+// Andy Goodrich: updating Copyright notice.
+//
+// Revision 1.2 2010/09/06 16:35:48 acg
+// Andy Goodrich: changed i386 to __i386__ in ifdef's.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:49:32 acg
+// Added $Log command so that CVS check in comments are reproduced in the
+// source.
+//
+
+#ifndef SC_NBUTILS_H
+#define SC_NBUTILS_H
+
+#include <cmath>
+#include <limits>
+
+#include "sysc/datatypes/bit/sc_bit_ids.h"
+#include "sysc/datatypes/int/sc_int_ids.h"
+#include "sysc/datatypes/int/sc_nbdefs.h"
+#include "sysc/utils/sc_report.h"
+
+
+namespace sc_dt
+{
+
+//-----------------------------------------------------------------------------
+//"sc_io_base"
+//
+// This inline function returns the type of an i/o stream's base as a SystemC
+// base designator.
+// stream_object = reference to the i/o stream whose base is to be returned.
+//
+//"sc_io_show_base"
+//
+// This inline function returns true if the base should be shown when a SystemC
+// value is displayed via the supplied stream operator.
+// stream_object = reference to the i/o stream to return showbase value for.
+//-----------------------------------------------------------------------------
+#if defined(__GNUC__) || defined(_MSC_VER) || defined(__SUNPRO_CC)
+ inline sc_numrep
+ sc_io_base( systemc_ostream& os, sc_numrep def_base )
+ {
+ std::ios::fmtflags flags = os.flags() & std::ios::basefield;
+ if ( flags & ::std::ios::dec ) return SC_DEC;
+ if ( flags & ::std::ios::hex ) return SC_HEX;
+ if ( flags & ::std::ios::oct ) return SC_OCT;
+ return def_base;
+ }
+
+ inline bool
+ sc_io_show_base( systemc_ostream& os )
+ {
+ return (os.flags() & ::std::ios::showbase) != 0 ;
+ }
+#else // Other
+ inline sc_numrep
+ sc_io_base( systemc_ostream& /*unused*/, sc_numrep /*unused*/ )
+ {
+ return SC_DEC;
+ }
+ inline bool
+ sc_io_show_base( systemc_ostream& /*unused*/ )
+ {
+ return false;
+ }
+#endif
+
+const std::string to_string( sc_numrep );
+
+inline
+systemc_ostream&
+operator << ( systemc_ostream& os, sc_numrep numrep )
+{
+ os << to_string( numrep );
+ return os;
+}
+
+// only used within vec_from_str (non-standard, deprecated)
+inline void
+is_valid_base(sc_numrep base)
+{
+ switch (base) {
+ case SC_NOBASE: case SC_BIN:
+ case SC_OCT: case SC_DEC:
+ case SC_HEX:
+ break;
+ case SC_BIN_US: case SC_BIN_SM:
+ case SC_OCT_US: case SC_OCT_SM:
+ case SC_HEX_US: case SC_HEX_SM:
+ case SC_CSD:
+ SC_REPORT_ERROR( sc_core::SC_ID_NOT_IMPLEMENTED_,
+ "is_valid_base( sc_numrep base ) : "
+ "bases SC_CSD, or ending in _US and _SM are not supported" );
+ break;
+ default:
+ char msg[BUFSIZ];
+ std::sprintf( msg, "is_valid_base( sc_numrep base ) : "
+ "base = %s is not valid",
+ to_string( base ).c_str() );
+ SC_REPORT_ERROR( sc_core::SC_ID_VALUE_NOT_VALID_, msg );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+// One transition of the FSM to find base and sign of a number.
+extern
+small_type
+fsm_move(char c, small_type &b, small_type &s, small_type &state);
+
+// Parse a character string into its equivalent binary bits.
+extern
+void parse_binary_bits(
+ const char* src_p, int dst_n, sc_digit* data_p, sc_digit* ctrl_p=0
+);
+
+
+// Parse a character string into its equivalent hexadecimal bits.
+extern
+void parse_hex_bits(
+ const char* src_p, int dst_n, sc_digit* data_p, sc_digit* ctrl_p=0
+);
+
+
+// Find the base and sign of a number in v.
+extern
+const char *
+get_base_and_sign(const char *v, small_type &base, small_type &sign);
+
+// Create a number out of v in base.
+extern
+small_type
+vec_from_str(int unb, int und, sc_digit *u,
+ const char *v, sc_numrep base = SC_NOBASE) ;
+
+
+// ----------------------------------------------------------------------------
+// Naming convention for the vec_ functions below:
+// vec_OP(u, v, w) : computes w = u OP v.
+// vec_OP_on(u, v) : computes u = u OP v if u has more digits than v.
+// vec_OP_on2(u, v) : computes u = u OP v if u has fewer digits than v.
+// _large : parameters are vectors.
+// _small : one of the parameters is a single digit.
+// Xlen : the number of digits in X.
+// ----------------------------------------------------------------------------
+
+// ----------------------------------------------------------------------------
+// Functions for vector addition: w = u + v or u += v.
+// ----------------------------------------------------------------------------
+
+extern
+void
+vec_add(int ulen, const sc_digit *u,
+ int vlen, const sc_digit *v, sc_digit *w);
+
+extern
+void
+vec_add_on(int ulen, sc_digit *u,
+ int vlen, const sc_digit *v);
+
+extern
+void
+vec_add_on2(int ulen, sc_digit *u,
+ int vlen, const sc_digit *v);
+
+extern
+void
+vec_add_small(int ulen, const sc_digit *u,
+ sc_digit v, sc_digit *w);
+
+extern
+void
+vec_add_small_on(int ulen, sc_digit *u, sc_digit v);
+
+
+// ----------------------------------------------------------------------------
+// Functions for vector subtraction: w = u - v, u -= v, or u = v - u.
+// ----------------------------------------------------------------------------
+
+extern
+void
+vec_sub(int ulen, const sc_digit *u,
+ int vlen, const sc_digit *v, sc_digit *w);
+
+extern
+void
+vec_sub_on(int ulen, sc_digit *u,
+ int vlen, const sc_digit *v);
+
+extern
+void
+vec_sub_on2(int ulen, sc_digit *u,
+ int vlen, const sc_digit *v);
+
+extern
+void
+vec_sub_small(int ulen, const sc_digit *u,
+ sc_digit v, sc_digit *w);
+
+extern
+void
+vec_sub_small_on(int ulen, sc_digit *u, sc_digit v);
+
+
+// ----------------------------------------------------------------------------
+// Functions for vector multiplication: w = u * v or u *= v.
+// ----------------------------------------------------------------------------
+
+extern
+void
+vec_mul(int ulen, const sc_digit *u,
+ int vlen, const sc_digit *v, sc_digit *w);
+
+extern
+void
+vec_mul_small(int ulen, const sc_digit *u,
+ sc_digit v, sc_digit *w);
+
+extern
+void
+vec_mul_small_on(int ulen, sc_digit *u, sc_digit v);
+
+
+// ----------------------------------------------------------------------------
+// Functions for vector division: w = u / v.
+// ----------------------------------------------------------------------------
+
+extern
+void
+vec_div_large(int ulen, const sc_digit *u,
+ int vlen, const sc_digit *v, sc_digit *w);
+
+extern
+void
+vec_div_small(int ulen, const sc_digit *u,
+ sc_digit v, sc_digit *w);
+
+
+// ----------------------------------------------------------------------------
+// Functions for vector remainder: w = u % v or u %= v.
+// ----------------------------------------------------------------------------
+
+extern
+void
+vec_rem_large(int ulen, const sc_digit *u,
+ int vlen, const sc_digit *v, sc_digit *w);
+
+extern
+sc_digit
+vec_rem_small(int ulen, const sc_digit *u, sc_digit v);
+
+extern
+sc_digit
+vec_rem_on_small(int ulen, sc_digit *u, sc_digit v);
+
+
+// ----------------------------------------------------------------------------
+// Functions to convert between vectors of char and sc_digit.
+// ----------------------------------------------------------------------------
+
+extern
+int
+vec_to_char(int ulen, const sc_digit *u,
+ int vlen, uchar *v);
+
+extern
+void
+vec_from_char(int ulen, const uchar *u,
+ int vlen, sc_digit *v);
+
+
+// ----------------------------------------------------------------------------
+// Functions to shift left or right, or to create a mirror image of vectors.
+// ----------------------------------------------------------------------------
+
+extern
+void
+vec_shift_left(int ulen, sc_digit *u, int nsl);
+
+extern
+void
+vec_shift_right(int vlen, sc_digit *u, int nsr, sc_digit fill = 0);
+
+extern
+void
+vec_reverse(int unb, int und, sc_digit *ud,
+ int l, int r = 0);
+
+
+// ----------------------------------------------------------------------------
+// Various utility functions.
+// ----------------------------------------------------------------------------
+
+// Return the low half part of d.
+inline
+sc_digit
+low_half(sc_digit d)
+{
+ return (d & HALF_DIGIT_MASK);
+}
+
+// Return the high half part of d. The high part of the digit may have
+// more bits than BITS_PER_HALF_DIGIT due to, e.g., overflow in the
+// multiplication. Hence, in other functions that use high_half(),
+// make sure that the result contains BITS_PER_HALF_DIGIT if
+// necessary. This is done by high_half_masked().
+inline
+sc_digit
+high_half(sc_digit d)
+{
+ return (d >> BITS_PER_HALF_DIGIT);
+}
+
+inline
+sc_digit
+high_half_masked(sc_digit d)
+{
+ return (high_half(d) & HALF_DIGIT_MASK);
+}
+
+// Concatenate the high part h and low part l. Assumes that h and l
+// are less than or equal to HALF_DIGIT_MASK;
+inline
+sc_digit
+concat(sc_digit h, sc_digit l)
+{
+ return ((h << BITS_PER_HALF_DIGIT) | l);
+}
+
+// Create a number with n 1's.
+inline
+sc_digit
+one_and_ones(int n)
+{
+ return (((sc_digit) 1 << n) - 1);
+}
+
+// Create a number with one 1 and n 0's.
+inline
+sc_digit
+one_and_zeros(int n)
+{
+ return ((sc_digit) 1 << n);
+}
+
+
+// ----------------------------------------------------------------------------
+
+// Find the digit that bit i is in.
+inline
+int
+digit_ord(int i)
+{
+ return (i / BITS_PER_DIGIT);
+}
+
+// Find the bit in digit_ord(i) that bit i corressponds to.
+inline
+int
+bit_ord(int i)
+{
+ return (i % BITS_PER_DIGIT);
+}
+
+
+// ----------------------------------------------------------------------------
+// Functions to compare, zero, complement vector(s).
+// ----------------------------------------------------------------------------
+
+// Compare u and v and return r
+// r = 0 if u == v
+// r < 0 if u < v
+// r > 0 if u > v
+// - Assume that all the leading zero digits are already skipped.
+// - ulen and/or vlen can be zero.
+// - Every digit is less than or equal to DIGIT_MASK;
+inline
+int
+vec_cmp(int ulen, const sc_digit *u,
+ int vlen, const sc_digit *v)
+{
+
+#ifdef DEBUG_SYSTEMC
+ // assert((ulen <= 0) || (u != NULL));
+ // assert((vlen <= 0) || (v != NULL));
+
+ // ulen and vlen can be equal to 0 because vec_cmp can be called
+ // after vec_skip_leading_zeros.
+ assert((ulen >= 0) && (u != NULL));
+ assert((vlen >= 0) && (v != NULL));
+ // If ulen > 0, then the leading digit of u must be non-zero.
+ assert((ulen <= 0) || (u[ulen - 1] != 0));
+ assert((vlen <= 0) || (v[vlen - 1] != 0));
+#endif
+
+ if (ulen != vlen)
+ return (ulen - vlen);
+
+ // ulen == vlen >= 1
+ while ((--ulen >= 0) && (u[ulen] == v[ulen]))
+ ;
+
+ if (ulen < 0)
+ return 0;
+
+#ifdef DEBUG_SYSTEMC
+ // Test to see if the result is wrong due to the presence of
+ // overflow bits.
+ assert((u[ulen] & DIGIT_MASK) != (v[ulen] & DIGIT_MASK));
+#endif
+
+ return (int) (u[ulen] - v[ulen]);
+
+}
+
+// Find the index of the first non-zero digit.
+// - ulen (before) = the number of digits in u.
+// - the returned value = the index of the first non-zero digit.
+// A negative value of -1 indicates that every digit in u is zero.
+inline
+int
+vec_find_first_nonzero(int ulen, const sc_digit *u)
+{
+
+#ifdef DEBUG_SYSTEMC
+ // assert((ulen <= 0) || (u != NULL));
+ assert((ulen > 0) && (u != NULL));
+#endif
+
+ while ((--ulen >= 0) && (! u[ulen]))
+ ;
+
+ return ulen;
+
+}
+
+// Skip all the leading zero digits.
+// - ulen (before) = the number of digits in u.
+// - the returned value = the number of non-zero digits in u.
+// - the returned value is non-negative.
+inline
+int
+vec_skip_leading_zeros(int ulen, const sc_digit *u)
+{
+
+#ifdef DEBUG_SYSTEMC
+ // assert((ulen <= 0) || (u != NULL));
+ assert((ulen > 0) && (u != NULL));
+#endif
+
+ return (1 + vec_find_first_nonzero(ulen, u));
+
+}
+
+// Compare u and v and return r
+// r = 0 if u == v
+// r < 0 if u < v
+// r > 0 if u > v
+inline
+int
+vec_skip_and_cmp(int ulen, const sc_digit *u,
+ int vlen, const sc_digit *v)
+{
+
+#ifdef DEBUG_SYSTEMC
+ assert((ulen > 0) && (u != NULL));
+ assert((vlen > 0) && (v != NULL));
+#endif
+
+ ulen = vec_skip_leading_zeros(ulen, u);
+ vlen = vec_skip_leading_zeros(vlen, v);
+ // ulen and/or vlen can be equal to zero here.
+ return vec_cmp(ulen, u, vlen, v);
+
+}
+
+// Set u[i] = 0 where i = from ... (ulen - 1).
+inline
+void
+vec_zero(int from, int ulen, sc_digit *u)
+{
+
+#ifdef DEBUG_SYSTEMC
+ assert((ulen > 0) && (u != NULL));
+#endif
+
+ for(int i = from; i < ulen; i++)
+ u[i] = 0;
+
+}
+
+// Set u[i] = 0 where i = 0 .. (ulen - 1).
+inline
+void
+vec_zero(int ulen, sc_digit *u)
+{
+ vec_zero(0, ulen, u);
+}
+
+// Copy n digits from v to u.
+inline
+void
+vec_copy(int n, sc_digit *u, const sc_digit *v)
+{
+
+#ifdef DEBUG_SYSTEMC
+ assert((n > 0) && (u != NULL) && (v != NULL));
+#endif
+
+ for (int i = 0; i < n; ++i)
+ u[i] = v[i];
+}
+
+// Copy v to u, where ulen >= vlen, and zero the rest of the digits in u.
+inline
+void
+vec_copy_and_zero(int ulen, sc_digit *u,
+ int vlen, const sc_digit *v)
+{
+
+#ifdef DEBUG_SYSTEMC
+ assert((ulen > 0) && (u != NULL));
+ assert((vlen > 0) && (v != NULL));
+ assert(ulen >= vlen);
+#endif
+
+ vec_copy(vlen, u, v);
+ vec_zero(vlen, ulen, u);
+
+}
+
+// 2's-complement the digits in u.
+inline
+void
+vec_complement(int ulen, sc_digit *u)
+{
+
+#ifdef DEBUG_SYSTEMC
+ assert((ulen > 0) && (u != NULL));
+#endif
+
+ sc_digit carry = 1;
+
+ for (int i = 0; i < ulen; ++i) {
+ carry += (~u[i] & DIGIT_MASK);
+ u[i] = carry & DIGIT_MASK;
+ carry >>= BITS_PER_DIGIT;
+ }
+
+}
+
+
+// ----------------------------------------------------------------------------
+// Functions to handle built-in types or signs.
+// ----------------------------------------------------------------------------
+
+// u = v
+// - v is an unsigned long or uint64, and positive integer.
+template< class Type >
+inline
+void
+from_uint(int ulen, sc_digit *u, Type v)
+{
+
+#ifdef DEBUG_SYSTEMC
+ // assert((ulen <= 0) || (u != NULL));
+ assert((ulen > 0) && (u != NULL));
+ assert(v >= 0);
+#endif
+
+ int i = 0;
+
+ while (v && (i < ulen)) {
+#ifndef _WIN32
+ u[i++] = static_cast<sc_digit>( v & DIGIT_MASK );
+#else
+ u[i++] = ((sc_digit) v) & DIGIT_MASK;
+#endif
+ v >>= BITS_PER_DIGIT;
+ }
+
+ vec_zero(i, ulen, u);
+
+}
+
+
+// Get u's sign and return its absolute value.
+// u can be long, unsigned long, int64, or uint64.
+template< class Type >
+inline
+small_type
+get_sign(Type &u)
+{
+ if (u > 0)
+ return SC_POS;
+
+ if (u == 0)
+ return SC_ZERO;
+
+ // no positive number representable for minimum value,
+ // leave as is to avoid Undefined Behaviour
+ if( SC_LIKELY_( u > (std::numeric_limits<Type>::min)() ) )
+ u = -u;
+
+ return SC_NEG;
+}
+
+
+// Return us * vs:
+// - Return SC_ZERO if either sign is SC_ZERO.
+// - Return SC_POS if us == vs
+// - Return SC_NEG if us != vs.
+inline
+small_type
+mul_signs(small_type us, small_type vs)
+{
+ if ((us == SC_ZERO) || (vs == SC_ZERO))
+ return SC_ZERO;
+
+ if (us == vs)
+ return SC_POS;
+
+ return SC_NEG;
+}
+
+
+// ----------------------------------------------------------------------------
+// Functions to test for errors and print out error messages.
+// ----------------------------------------------------------------------------
+
+#ifdef SC_MAX_NBITS
+
+inline
+void
+test_bound(int nb)
+{
+ if (nb > SC_MAX_NBITS) {
+ char msg[BUFSIZ];
+ std::sprintf( msg, "test_bound( int nb ) : "
+ "nb = %d > SC_MAX_NBITS = %d is not valid",
+ nb, SC_MAX_NBITS );
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
+ }
+}
+
+#endif
+
+template< class Type >
+inline
+void
+div_by_zero(Type s)
+{
+ if (s == 0) {
+ SC_REPORT_ERROR( sc_core::SC_ID_OPERATION_FAILED_,
+ "div_by_zero<Type>( Type ) : division by zero" );
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// Functions to check if a given vector is zero or make one.
+// ----------------------------------------------------------------------------
+
+// If u[i] is zero for every i = 0,..., ulen - 1, return SC_ZERO,
+// else return s.
+inline
+small_type
+check_for_zero(small_type s, int ulen, const sc_digit *u)
+{
+
+#ifdef DEBUG_SYSTEMC
+ // assert(ulen >= 0);
+ assert((ulen > 0) && (u != NULL));
+#endif
+
+ if (vec_find_first_nonzero(ulen, u) < 0)
+ return SC_ZERO;
+
+ return s;
+
+}
+
+// If u[i] is zero for every i = 0,..., ulen - 1, return true,
+// else return false.
+inline
+bool
+check_for_zero(int ulen, const sc_digit *u)
+{
+
+#ifdef DEBUG_SYSTEMC
+ // assert(ulen >= 0);
+ assert((ulen > 0) && (u != NULL));
+#endif
+
+ if (vec_find_first_nonzero(ulen, u) < 0)
+ return true;
+
+ return false;
+
+}
+
+inline
+small_type
+make_zero(int nd, sc_digit *d)
+{
+ vec_zero(nd, d);
+ return SC_ZERO;
+}
+
+
+// ----------------------------------------------------------------------------
+// Functions for both signed and unsigned numbers to convert sign-magnitude
+// (SM) and 2's complement (2C) representations.
+// added = 1 => for signed.
+// added = 0 => for unsigned.
+// IF_SC_SIGNED can be used as 'added'.
+// ----------------------------------------------------------------------------
+
+// Trim the extra leading bits of a signed or unsigned number.
+inline
+void
+trim(small_type added, int nb, int nd, sc_digit *d)
+{
+#ifdef DEBUG_SYSTEMC
+ assert((nb > 0) && (nd > 0) && (d != NULL));
+#endif
+
+ d[nd - 1] &= one_and_ones(bit_ord(nb - 1) + added);
+}
+
+// Convert an (un)signed number from sign-magnitude representation to
+// 2's complement representation and trim the extra bits.
+inline
+void
+convert_SM_to_2C_trimmed(small_type added,
+ small_type s, int nb, int nd, sc_digit *d)
+{
+ if (s == SC_NEG) {
+ vec_complement(nd, d);
+ trim(added, nb, nd, d);
+ }
+}
+
+// Convert an (un)signed number from sign-magnitude representation to
+// 2's complement representation but do not trim the extra bits.
+inline
+void
+convert_SM_to_2C(small_type s, int nd, sc_digit *d)
+{
+ if (s == SC_NEG)
+ vec_complement(nd, d);
+}
+
+
+// ----------------------------------------------------------------------------
+// Functions to convert between sign-magnitude (SM) and 2's complement
+// (2C) representations of signed numbers.
+// ----------------------------------------------------------------------------
+
+// Trim the extra leading bits off a signed number.
+inline
+void
+trim_signed(int nb, int nd, sc_digit *d)
+{
+#ifdef DEBUG_SYSTEMC
+ assert((nb > 0) && (nd > 0) && (d != NULL));
+#endif
+
+ d[nd - 1] &= one_and_ones(bit_ord(nb - 1) + 1);
+}
+
+// Convert a signed number from 2's complement representation to
+// sign-magnitude representation, and return its sign. nd is d's
+// actual size, without zeros eliminated.
+inline
+small_type
+convert_signed_2C_to_SM(int nb, int nd, sc_digit *d)
+{
+
+#ifdef DEBUG_SYSTEMC
+ assert((nb > 0) && (nd > 0) && (d != NULL));
+#endif
+
+ small_type s;
+
+ int xnb = bit_ord(nb - 1) + 1;
+
+ // Test the sign bit.
+ if (d[nd - 1] & one_and_zeros(xnb - 1)) {
+ s = SC_NEG;
+ vec_complement(nd, d);
+ }
+ else
+ s = SC_POS;
+
+ // Trim the last digit.
+ d[nd - 1] &= one_and_ones(xnb);
+
+ // Check if the new number is zero.
+ if (s == SC_POS)
+ return check_for_zero(s, nd, d);
+
+ return s;
+
+}
+
+// Convert a signed number from sign-magnitude representation to 2's
+// complement representation, get its sign, convert back to
+// sign-magnitude representation, and return its sign. nd is d's
+// actual size, without zeros eliminated.
+inline
+small_type
+convert_signed_SM_to_2C_to_SM(small_type s, int nb, int nd, sc_digit *d)
+{
+ convert_SM_to_2C(s, nd, d);
+ return convert_signed_2C_to_SM(nb, nd, d);
+}
+
+// Convert a signed number from sign-magnitude representation to 2's
+// complement representation and trim the extra bits.
+inline
+void
+convert_signed_SM_to_2C_trimmed(small_type s, int nb, int nd, sc_digit *d)
+{
+ convert_SM_to_2C_trimmed(1, s, nb, nd, d);
+}
+
+// Convert a signed number from sign-magnitude representation to 2's
+// complement representation but do not trim the extra bits.
+inline
+void
+convert_signed_SM_to_2C(small_type s, int nd, sc_digit *d)
+{
+ convert_SM_to_2C(s, nd, d);
+}
+
+
+// ----------------------------------------------------------------------------
+// Functions to convert between sign-magnitude (SM) and 2's complement
+// (2C) representations of unsigned numbers.
+// ----------------------------------------------------------------------------
+
+// Trim the extra leading bits off an unsigned number.
+inline
+void
+trim_unsigned(int nb, int nd, sc_digit *d)
+{
+#ifdef DEBUG_SYSTEMC
+ assert((nb > 0) && (nd > 0) && (d != NULL));
+#endif
+
+ d[nd - 1] &= one_and_ones(bit_ord(nb - 1));
+}
+
+// Convert an unsigned number from 2's complement representation to
+// sign-magnitude representation, and return its sign. nd is d's
+// actual size, without zeros eliminated.
+inline
+small_type
+convert_unsigned_2C_to_SM(int nb, int nd, sc_digit *d)
+{
+ trim_unsigned(nb, nd, d);
+ return check_for_zero(SC_POS, nd, d);
+}
+
+// Convert an unsigned number from sign-magnitude representation to
+// 2's complement representation, get its sign, convert back to
+// sign-magnitude representation, and return its sign. nd is d's
+// actual size, without zeros eliminated.
+inline
+small_type
+convert_unsigned_SM_to_2C_to_SM(small_type s, int nb, int nd, sc_digit *d)
+{
+ convert_SM_to_2C(s, nd, d);
+ return convert_unsigned_2C_to_SM(nb, nd, d);
+}
+
+// Convert an unsigned number from sign-magnitude representation to
+// 2's complement representation and trim the extra bits.
+inline
+void
+convert_unsigned_SM_to_2C_trimmed(small_type s, int nb, int nd, sc_digit *d)
+{
+ convert_SM_to_2C_trimmed(0, s, nb, nd, d);
+}
+
+// Convert an unsigned number from sign-magnitude representation to
+// 2's complement representation but do not trim the extra bits.
+inline
+void
+convert_unsigned_SM_to_2C(small_type s, int nd, sc_digit *d)
+{
+ convert_SM_to_2C(s, nd, d);
+}
+
+
+// ----------------------------------------------------------------------------
+// Functions to copy one (un)signed number to another.
+// ----------------------------------------------------------------------------
+
+// Copy v to u.
+inline
+void
+copy_digits_signed(small_type &us,
+ int unb, int und, sc_digit *ud,
+ int vnb, int vnd, const sc_digit *vd)
+{
+
+ if (und <= vnd) {
+
+ vec_copy(und, ud, vd);
+
+ if (unb <= vnb)
+ us = convert_signed_SM_to_2C_to_SM(us, unb, und, ud);
+
+ }
+ else // und > vnd
+ vec_copy_and_zero(und, ud, vnd, vd);
+
+}
+
+// Copy v to u.
+inline
+void
+copy_digits_unsigned(small_type &us,
+ int unb, int und, sc_digit *ud,
+ int /* vnb */, int vnd, const sc_digit *vd)
+{
+
+ if (und <= vnd)
+ vec_copy(und, ud, vd);
+
+ else // und > vnd
+ vec_copy_and_zero(und, ud, vnd, vd);
+
+ us = convert_unsigned_SM_to_2C_to_SM(us, unb, und, ud);
+
+}
+
+
+// ----------------------------------------------------------------------------
+// Faster set(i, v), without bound checking.
+// ----------------------------------------------------------------------------
+
+// A version of set(i, v) without bound checking.
+inline
+void
+safe_set(int i, bool v, sc_digit *d)
+{
+
+#ifdef DEBUG_SYSTEMC
+ assert((i >= 0) && (d != NULL));
+#endif
+
+ int bit_num = bit_ord(i);
+ int digit_num = digit_ord(i);
+
+ if (v)
+ d[digit_num] |= one_and_zeros(bit_num);
+ else
+ d[digit_num] &= ~(one_and_zeros(bit_num));
+
+}
+
+
+// ----------------------------------------------------------------------------
+// Function to check if a double number is bad (NaN or infinite).
+// ----------------------------------------------------------------------------
+
+inline
+bool
+is_nan( double v )
+{
+ return std::numeric_limits<double>::has_quiet_NaN && (v != v);
+}
+
+inline
+bool
+is_inf( double v )
+{
+ return v == std::numeric_limits<double>::infinity()
+ || v == -std::numeric_limits<double>::infinity();
+}
+
+inline
+void
+is_bad_double(double v)
+{
+// Windows throws exception.
+ if( is_nan(v) || is_inf(v) )
+ SC_REPORT_ERROR( sc_core::SC_ID_VALUE_NOT_VALID_,
+ "is_bad_double( double v ) : "
+ "v is not finite - NaN or Inf" );
+}
+
+} // namespace sc_dt
+
+
+#endif
diff --git a/ext/systemc/src/sysc/datatypes/int/sc_signed.cpp b/ext/systemc/src/sysc/datatypes/int/sc_signed.cpp
new file mode 100644
index 000000000..7e5cfacff
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/int/sc_signed.cpp
@@ -0,0 +1,4134 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_signed.cpp -- Arbitrary precision signed arithmetic.
+
+ This file includes the definitions of sc_signed_bitref,
+ sc_signed_subref, and sc_signed classes. The first two
+ classes are proxy classes to reference one bit and a range
+ of bits of a sc_signed number, respectively. This file also
+ includes sc_nbcommon.cpp and sc_nbfriends.cpp, which
+ contain the definitions shared by sc_unsigned.
+
+ Original Author: Ali Dasdan, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// $Log: sc_signed.cpp,v $
+// Revision 1.6 2011/02/18 20:19:15 acg
+// Andy Goodrich: updating Copyright notice.
+//
+// Revision 1.5 2008/12/10 20:38:45 acg
+// Andy Goodrich: fixed conversion of double values to the digits vector.
+// The bits above the radix were not being masked off.
+//
+// Revision 1.4 2008/06/19 17:47:56 acg
+// Andy Goodrich: fixes for bugs. See 2.2.1 RELEASENOTES.
+//
+// Revision 1.3 2008/04/29 21:20:41 acg
+// Andy Goodrich: added mask to first word transferred when processing
+// a negative sc_signed value in sc_signed::concat_get_data().
+//
+// Revision 1.2 2007/11/04 21:27:00 acg
+// Andy Goodrich: changes to make sure the proper value is returned from
+// concat_get_data().
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.5 2006/10/23 19:32:47 acg
+// Andy Goodrich: further fix for incorrect value being returned from
+// concat_get_data. This one is in the non-aligned value code.
+//
+// Revision 1.3 2006/01/13 18:49:32 acg
+// Added $Log command so that CVS check in comments are reproduced in the
+// source.
+//
+
+#include <ctype.h>
+#include <math.h>
+
+#include "sysc/kernel/sc_cmnhdr.h"
+#include "sysc/kernel/sc_macros.h"
+#include "sysc/datatypes/int/sc_signed.h"
+#include "sysc/datatypes/int/sc_unsigned.h"
+#include "sysc/datatypes/int/sc_int_base.h"
+#include "sysc/datatypes/int/sc_uint_base.h"
+#include "sysc/datatypes/int/sc_int_ids.h"
+#include "sysc/datatypes/bit/sc_bv_base.h"
+#include "sysc/datatypes/bit/sc_lv_base.h"
+#include "sysc/datatypes/misc/sc_concatref.h"
+#include "sysc/datatypes/fx/sc_fix.h"
+#include "sysc/datatypes/fx/scfx_other_defs.h"
+
+
+namespace sc_dt
+{
+
+// Pool of temporary instances:
+
+sc_core::sc_vpool<sc_signed_bitref> sc_signed_bitref::m_pool(9);
+sc_core::sc_vpool<sc_signed_subref> sc_signed_subref::m_pool(9);
+
+// -----------------------------------------------------------------------------
+// SECTION: Public members - Invalid selections.
+// -----------------------------------------------------------------------------
+
+void
+sc_signed::invalid_index( int i ) const
+{
+ char msg[BUFSIZ];
+ std::sprintf( msg,
+ "sc_bigint bit selection: index = %d violates "
+ "0 <= index <= %d", i, nbits - 1 );
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
+}
+
+void
+sc_signed::invalid_range( int l, int r ) const
+{
+ char msg[BUFSIZ];
+ std::sprintf( msg,
+ "sc_bigint part selection: left = %d, right = %d \n"
+ " violates either (%d >= left >= 0) or (%d >= right >= 0)",
+ l, r, nbits-1, nbits-1 );
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
+}
+
+
+// ----------------------------------------------------------------------------
+
+// ----------------------------------------------------------------------------
+// SECTION: Public members.
+// ----------------------------------------------------------------------------
+
+// Most public members are included from sc_nbcommon.inc. However, some
+// concatenation support appears here to optimize between the signed and
+// unsigned cases.
+
+// Insert this object's value at the specified place in a vector of biguint
+// style values.
+
+bool sc_signed::concat_get_ctrl( sc_digit* dst_p, int low_i ) const
+{
+ int dst_i; // Index to next word to set in dst_p.
+ int end_i; // Index of high order word to set.
+ int left_shift; // Amount to shift value left.
+ sc_digit mask; // Mask for partial word sets.
+
+
+ // CALCULATE METRICS FOR DATA MOVEMENT:
+
+ dst_i = low_i / BITS_PER_DIGIT;
+ end_i = (low_i + nbits - 1) / BITS_PER_DIGIT;
+ left_shift = low_i % BITS_PER_DIGIT;
+
+
+ // ALL DATA TO BE MOVED IS IN A SINGLE WORD:
+
+ mask = ~(-1 << left_shift);
+ dst_p[dst_i] = ( dst_p[dst_i] & ~mask );
+ dst_i++;
+
+ for ( ; dst_i <= end_i; dst_i++ ) dst_p[dst_i] = 0;
+
+ return false;
+}
+
+bool sc_signed::concat_get_data( sc_digit* dst_p, int low_i ) const
+{
+ sc_digit carry; // Carry bit for complements.
+ int dst_i; // Index to next word to set in dst_p.
+ int end_i; // Index of high order word to set.
+ int high_i; // Index w/in word of high order bit.
+ int left_shift; // Amount to shift value left.
+ sc_digit left_word; // High word component for set.
+ sc_digit mask; // Mask for partial word sets.
+ bool result; // True if inserted non-zero data.
+ int right_shift; // Amount to shift value right.
+ sc_digit right_word; // Low word component for set.
+ int src_i; // Index to next word to get from digit.
+
+
+
+ // CALCULATE METRICS FOR DATA MOVEMENT:
+
+ dst_i = low_i / BITS_PER_DIGIT;
+ high_i = low_i + nbits - 1;
+ end_i = high_i / BITS_PER_DIGIT;
+ left_shift = low_i % BITS_PER_DIGIT;
+
+ switch ( sgn )
+ {
+ // POSITIVE SOURCE VALUE:
+
+ case SC_POS:
+
+ result = true;
+
+ // ALL DATA TO BE MOVED IS IN A SINGLE WORD:
+
+ if ( dst_i == end_i )
+ {
+ mask = ~(-1 << left_shift);
+ dst_p[dst_i] = ( ( dst_p[dst_i] & mask ) |
+ (digit[0] << left_shift) ) & DIGIT_MASK;
+ }
+
+
+ // DATA IS IN MORE THAN ONE WORD, BUT IS WORD ALIGNED:
+
+ else if ( left_shift == 0 )
+ {
+ for ( src_i = 0; dst_i < end_i; dst_i++, src_i++ )
+ {
+ dst_p[dst_i] = digit[src_i];
+ }
+ high_i = high_i % BITS_PER_DIGIT;
+ mask = ~(-2 << high_i) & DIGIT_MASK;
+ dst_p[dst_i] = digit[src_i] & mask;
+ }
+
+
+ // DATA IS IN MORE THAN ONE WORD, AND NOT WORD ALIGNED:
+
+ else
+ {
+ high_i = high_i % BITS_PER_DIGIT;
+ right_shift = BITS_PER_DIGIT - left_shift;
+ mask = ~(-1 << left_shift);
+ right_word = digit[0];
+ dst_p[dst_i] = (dst_p[dst_i] & mask) |
+ ((right_word << left_shift) & DIGIT_MASK);
+ for ( src_i = 1, dst_i++; dst_i < end_i; dst_i++, src_i++ )
+ {
+ left_word = digit[src_i];
+ dst_p[dst_i] = ((left_word << left_shift)&DIGIT_MASK) |
+ (right_word >> right_shift);
+ right_word = left_word;
+ }
+ left_word = (src_i < ndigits) ? digit[src_i] : 0;
+ mask = ~(-2 << high_i) & DIGIT_MASK;
+ dst_p[dst_i] = ((left_word << left_shift) |
+ (right_word >> right_shift)) & mask;
+ }
+ break;
+
+
+ // SOURCE VALUE IS NEGATIVE:
+
+ case SC_NEG:
+
+ // ALL DATA TO BE MOVED IS IN A SINGLE WORD:
+
+ result = true;
+ if ( dst_i == end_i )
+ {
+ mask = ~(-1 << nbits);
+ right_word = ((digit[0] ^ DIGIT_MASK) + 1) & mask;
+ mask = ~(-1 << left_shift);
+ dst_p[dst_i] = ( ( dst_p[dst_i] & mask ) |
+ (right_word << left_shift) ) & DIGIT_MASK;
+ }
+
+
+ // DATA IS IN MORE THAN ONE WORD, BUT IS WORD ALIGNED:
+
+ else if ( left_shift == 0 )
+ {
+ carry = 1;
+ for ( src_i = 0; dst_i < end_i; dst_i++, src_i++ )
+ {
+ right_word = (digit[src_i] ^ DIGIT_MASK) + carry;
+ dst_p[dst_i] = right_word & DIGIT_MASK;
+ carry = right_word >> BITS_PER_DIGIT;
+ }
+ high_i = high_i % BITS_PER_DIGIT;
+ mask = (~(-2 << high_i)) & DIGIT_MASK;
+ right_word = (src_i < ndigits) ?
+ (digit[src_i] ^ DIGIT_MASK) + carry : DIGIT_MASK + carry;
+ dst_p[dst_i] = right_word & mask;
+ }
+
+
+ // DATA IS IN MORE THAN ONE WORD, AND NOT WORD ALIGNED:
+
+ else
+ {
+ high_i = high_i % BITS_PER_DIGIT;
+ right_shift = BITS_PER_DIGIT - left_shift;
+ mask = ~(-1 << left_shift);
+ carry = 1;
+ right_word = (digit[0] ^ DIGIT_MASK) + carry;
+ dst_p[dst_i] = (dst_p[dst_i] & mask) |
+ ((right_word << left_shift) & DIGIT_MASK);
+ carry = right_word >> BITS_PER_DIGIT;
+ right_word &= DIGIT_MASK;
+ for ( src_i = 1, dst_i++; dst_i < end_i; dst_i++, src_i++ )
+ {
+ left_word = (digit[src_i] ^ DIGIT_MASK) + carry;
+ dst_p[dst_i] = ((left_word << left_shift)&DIGIT_MASK) |
+ (right_word >> right_shift);
+ carry = left_word >> BITS_PER_DIGIT;
+ right_word = left_word & DIGIT_MASK;
+ }
+ left_word = (src_i < ndigits) ?
+ (digit[src_i] ^ DIGIT_MASK) + carry : carry;
+ mask = ~(-2 << high_i) & DIGIT_MASK;
+ dst_p[dst_i] = ((left_word << left_shift) |
+ (right_word >> right_shift)) & mask;
+ }
+ break;
+
+
+ // VALUE IS ZERO:
+
+ default:
+ result = false;
+
+
+ // ALL DATA TO BE MOVED IS IN A SINGLE WORD:
+
+ if ( dst_i == end_i )
+ {
+ mask = ~(-1 << nbits) << left_shift;
+ dst_p[dst_i] = dst_p[dst_i] & ~mask;
+ }
+
+
+ // DATA IS IN MORE THAN ONE WORD, BUT IS WORD ALIGNED:
+
+ else if ( left_shift == 0 )
+ {
+ carry = 1;
+ for ( src_i = 0; dst_i < end_i; dst_i++, src_i++ )
+ {
+ dst_p[dst_i] = 0;
+ }
+ high_i = high_i % BITS_PER_DIGIT;
+ mask = ~(-2 << high_i) & DIGIT_MASK;
+ dst_p[dst_i] = 0; // #### digit[src_i] & mask;
+ }
+
+
+ // DATA IS IN MORE THAN ONE WORD, AND NOT WORD ALIGNED:
+
+ else
+ {
+ high_i = high_i % BITS_PER_DIGIT;
+ right_shift = BITS_PER_DIGIT - left_shift;
+ mask = ~(-1 << left_shift);
+ dst_p[dst_i] = (dst_p[dst_i] & mask);
+ for ( dst_i++; dst_i <= end_i; dst_i++ )
+ {
+ dst_p[dst_i] = 0;
+ }
+ }
+ break;
+ }
+ return result;
+}
+
+// Return this object instance's bits as a uint64 without sign extension.
+
+uint64 sc_signed::concat_get_uint64() const
+{
+ uint64 result;
+
+ switch ( sgn )
+ {
+ case SC_POS:
+ result = 0;
+ if ( ndigits > 2 )
+ result = digit[2];
+ if ( ndigits > 1 )
+ result = (result << BITS_PER_DIGIT) | digit[1];
+ result = (result << BITS_PER_DIGIT) | digit[0];
+ break;
+ case SC_NEG:
+ result = 0;
+ if ( ndigits > 2 )
+ result = digit[2];
+ if ( ndigits > 1 )
+ result = (result << BITS_PER_DIGIT) | digit[1];
+ result = (result << BITS_PER_DIGIT) | digit[0];
+ result = -result;
+ if ( nbits < 64 )
+ {
+ uint64 mask = ~0;
+ result = result & ~(mask << nbits);
+ }
+ break;
+ default:
+ result = 0;
+ break;
+ }
+ return result;
+}
+
+// #### OPTIMIZE
+void sc_signed::concat_set(int64 src, int low_i)
+{
+ *this = (low_i < 64) ? src >> low_i : src >> 63;
+}
+
+void sc_signed::concat_set(const sc_signed& src, int low_i)
+{
+ if ( low_i < src.length() )
+ *this = src >> low_i;
+ else
+ *this = (src<0) ? (int_type)-1 : 0;
+}
+
+void sc_signed::concat_set(const sc_unsigned& src, int low_i)
+{
+ if ( low_i < src.length() )
+ *this = src >> low_i;
+ else
+ *this = 0;
+}
+
+void sc_signed::concat_set(uint64 src, int low_i)
+{
+ *this = (low_i < 64) ? src >> low_i : 0;
+}
+
+// ----------------------------------------------------------------------------
+// SECTION: Public members - Reduction methods.
+// ----------------------------------------------------------------------------
+
+bool sc_signed::and_reduce() const
+{
+ sc_digit current; // Current digit examining.
+ int i; // Index of digit examining.
+
+ if ( sgn == SC_NEG )
+ {
+ current = (1 << BITS_PER_DIGIT);
+ for ( i = 0; i < ndigits-1; i++ )
+ {
+ current = (current >> BITS_PER_DIGIT) + (digit[i]^DIGIT_MASK);
+ if ( (current & DIGIT_MASK) != DIGIT_MASK ) return false;
+ }
+ current = (current >> BITS_PER_DIGIT) + (digit[i]^DIGIT_MASK);
+ if ( (current & ~(-1 << (nbits % BITS_PER_DIGIT))) ==
+ (sc_digit) ~(-1 << (nbits % BITS_PER_DIGIT)) )
+ return true;
+ }
+ return false;
+}
+
+bool sc_signed::or_reduce() const
+{
+ return sgn == SC_ZERO ? false : true;
+}
+
+bool sc_signed::xor_reduce() const
+{
+ int i; // Digit examining.
+ int odd; // Flag for odd number of digits.
+
+ odd = 0;
+ for ( i = 0; i < nbits; i++ )
+ if ( test(i) ) odd = ~odd;
+ return odd ? true : false;
+}
+
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Public members - Assignment operators.
+// ----------------------------------------------------------------------------
+
+// assignment operators
+
+const sc_signed&
+sc_signed::operator = ( const char* a )
+{
+ if( a == 0 ) {
+ SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_,
+ "character string is zero" );
+ }
+ if( *a == 0 ) {
+ SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_,
+ "character string is empty" );
+ }
+ try {
+ int len = length();
+ sc_fix aa( a, len, len, SC_TRN, SC_WRAP, 0, SC_ON );
+ return this->operator = ( aa );
+ } catch( sc_core::sc_report ) {
+ char msg[BUFSIZ];
+ std::sprintf( msg, "character string '%s' is not valid", a );
+ SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
+ // never reached
+ }
+ return *this;
+}
+
+const sc_signed&
+sc_signed::operator=(int64 v)
+{
+ sgn = get_sign(v);
+ // v >= 0 now.
+ if (sgn == SC_ZERO)
+ vec_zero(ndigits, digit);
+ else {
+ from_uint(ndigits, digit, (uint64) v);
+ if (nbits <= (int)BITS_PER_INT64)
+ convert_SM_to_2C_to_SM();
+ }
+ return *this;
+}
+
+const sc_signed&
+sc_signed::operator=(uint64 v)
+{
+ sgn = get_sign(v);
+ if (sgn == SC_ZERO)
+ vec_zero(ndigits, digit);
+ else {
+ from_uint(ndigits, digit, v);
+ if (nbits <= (int)BITS_PER_INT64)
+ convert_SM_to_2C_to_SM();
+ }
+ return *this;
+}
+
+const sc_signed&
+sc_signed::operator=(long v)
+{
+ sgn = get_sign(v);
+ // v >= 0 now.
+ if (sgn == SC_ZERO)
+ vec_zero(ndigits, digit);
+ else {
+ from_uint(ndigits, digit, (unsigned long) v);
+ if (nbits <= (int)BITS_PER_LONG)
+ convert_SM_to_2C_to_SM();
+ }
+ return *this;
+}
+
+const sc_signed&
+sc_signed::operator=(unsigned long v)
+{
+ sgn = get_sign(v);
+ if (sgn == SC_ZERO)
+ vec_zero(ndigits, digit);
+ else {
+ from_uint(ndigits, digit, v);
+ if (nbits <= (int)BITS_PER_LONG)
+ convert_SM_to_2C_to_SM();
+ }
+ return *this;
+}
+
+const sc_signed&
+sc_signed::operator=(double v)
+{
+ is_bad_double(v);
+ if (v < 0) {
+ v = -v;
+ sgn = SC_NEG;
+ }
+ else
+ sgn = SC_POS;
+ int i = 0;
+ while (floor(v) && (i < ndigits)) {
+#ifndef _WIN32
+ digit[i++] = ((sc_digit)floor(remainder(v, DIGIT_RADIX))) & DIGIT_MASK;
+#else
+ digit[i++] = ((sc_digit)floor(fmod(v, DIGIT_RADIX))) & DIGIT_MASK;
+#endif
+ v /= DIGIT_RADIX;
+ }
+ vec_zero(i, ndigits, digit);
+ convert_SM_to_2C_to_SM();
+ return *this;
+}
+
+
+// ----------------------------------------------------------------------------
+
+const sc_signed&
+sc_signed::operator = ( const sc_bv_base& v )
+{
+ int minlen = sc_min( nbits, v.length() );
+ int i = 0;
+ for( ; i < minlen; ++ i ) {
+ safe_set( i, v.get_bit( i ), digit );
+ }
+ for( ; i < nbits; ++ i ) {
+ safe_set( i, 0, digit ); // zero-extend
+ }
+ convert_2C_to_SM();
+ return *this;
+}
+
+const sc_signed&
+sc_signed::operator = ( const sc_lv_base& v )
+{
+ int minlen = sc_min( nbits, v.length() );
+ int i = 0;
+ for( ; i < minlen; ++ i ) {
+ safe_set( i, sc_logic( v.get_bit( i ) ).to_bool(), digit );
+ }
+ for( ; i < nbits; ++ i ) {
+ safe_set( i, 0, digit ); // zero-extend
+ }
+ convert_2C_to_SM();
+ return *this;
+}
+
+
+// explicit conversion to character string
+
+const std::string
+sc_signed::to_string( sc_numrep numrep ) const
+{
+ int len = length();
+ sc_fix aa( *this, len, len, SC_TRN, SC_WRAP, 0, SC_ON );
+ return aa.to_string( numrep );
+}
+
+const std::string
+sc_signed::to_string( sc_numrep numrep, bool w_prefix ) const
+{
+ int len = length();
+ sc_fix aa( *this, len, len, SC_TRN, SC_WRAP, 0, SC_ON );
+ return aa.to_string( numrep, w_prefix );
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Interfacing with sc_int_base
+// ----------------------------------------------------------------------------
+
+const sc_signed&
+sc_signed::operator = (const sc_int_base& v)
+{ return operator=((int64) v); }
+
+
+sc_signed
+operator + ( const sc_unsigned& u, const sc_int_base& v )
+{ return operator + ( u, SCAST<int64>( v ) ); }
+
+sc_signed
+operator + ( const sc_int_base& u, const sc_unsigned& v )
+{ return operator + ( SCAST<int64>( u ), v ); }
+
+sc_signed
+operator + (const sc_signed& u, const sc_int_base& v)
+{ return operator+(u, (int64) v); }
+
+sc_signed
+operator + (const sc_int_base& u, const sc_signed& v)
+{ return operator+((int64) u, v); }
+
+const sc_signed&
+sc_signed::operator += (const sc_int_base& v)
+{ return operator+=((int64) v); }
+
+
+sc_signed
+operator - (const sc_unsigned& u, const sc_int_base& v)
+{ return operator-(u, (int64) v); }
+
+sc_signed
+operator - (const sc_int_base& u, const sc_unsigned& v)
+{ return operator-((int64) u, v); }
+
+sc_signed
+operator-(const sc_signed& u, const sc_int_base& v)
+{ return operator-(u, (int64) v); }
+
+sc_signed
+operator - (const sc_int_base& u, const sc_signed& v)
+{ return operator-((int64) u, v); }
+
+const sc_signed&
+sc_signed::operator -= (const sc_int_base& v)
+{ return operator-=((int64) v); }
+
+
+sc_signed
+operator * ( const sc_unsigned& u, const sc_int_base& v )
+{ return operator * ( u, SCAST<int64>( v ) ); }
+
+sc_signed
+operator * ( const sc_int_base& u, const sc_unsigned& v )
+{ return operator * ( SCAST<int64>( u ), v ); }
+
+sc_signed
+operator * (const sc_signed& u, const sc_int_base& v)
+{ return operator*(u, (int64) v); }
+
+sc_signed
+operator * (const sc_int_base& u, const sc_signed& v)
+{ return operator*((int64) u, v); }
+
+const sc_signed&
+sc_signed::operator *= (const sc_int_base& v)
+{ return operator*=((int64) v); }
+
+
+sc_signed
+operator / ( const sc_unsigned& u, const sc_int_base& v )
+{ return operator / ( u, SCAST<int64>( v ) ); }
+
+sc_signed
+operator / ( const sc_int_base& u, const sc_unsigned& v )
+{ return operator / ( SCAST<int64>( u ), v ); }
+
+sc_signed
+operator / (const sc_signed& u, const sc_int_base& v)
+{ return operator/(u, (int64) v); }
+
+sc_signed
+operator / (const sc_int_base& u, const sc_signed& v)
+{ return operator/((int64) u, v); }
+
+const sc_signed&
+sc_signed::operator /= (const sc_int_base& v)
+{ return operator/=((int64) v); }
+
+
+sc_signed
+operator % ( const sc_unsigned& u, const sc_int_base& v )
+{ return operator % ( u, SCAST<int64>( v ) ); }
+
+sc_signed
+operator % ( const sc_int_base& u, const sc_unsigned& v )
+{ return operator % ( SCAST<int64>( u ), v ); }
+
+sc_signed
+operator % (const sc_signed& u, const sc_int_base& v)
+{ return operator%(u, (int64) v); }
+
+sc_signed
+operator % (const sc_int_base& u, const sc_signed& v)
+{ return operator%((int64) u, v); }
+
+const sc_signed&
+sc_signed::operator %= (const sc_int_base& v)
+{ return operator%=((int64) v); }
+
+
+sc_signed
+operator & ( const sc_unsigned& u, const sc_int_base& v )
+{ return operator & ( u, SCAST<int64>( v ) ); }
+
+sc_signed
+operator & ( const sc_int_base& u, const sc_unsigned& v )
+{ return operator & ( SCAST<int64>( u ), v ); }
+
+sc_signed
+operator & (const sc_signed& u, const sc_int_base& v)
+{ return operator&(u, (int64) v); }
+
+sc_signed
+operator & (const sc_int_base& u, const sc_signed& v)
+{ return operator&((int64) u, v); }
+
+const sc_signed&
+sc_signed::operator &= (const sc_int_base& v)
+{ return operator&=((int64) v); }
+
+
+sc_signed
+operator | ( const sc_unsigned& u, const sc_int_base& v )
+{ return operator | ( u, SCAST<int64>( v ) ); }
+
+sc_signed
+operator | ( const sc_int_base& u, const sc_unsigned& v )
+{ return operator | ( SCAST<int64>( u ), v ); }
+
+sc_signed
+operator | (const sc_signed& u, const sc_int_base& v)
+{ return operator|(u, (int64) v); }
+
+sc_signed
+operator | (const sc_int_base& u, const sc_signed& v)
+{ return operator|((int64) u, v); }
+
+const sc_signed&
+sc_signed::operator |= (const sc_int_base& v)
+{ return operator|=((int64) v); }
+
+
+sc_signed
+operator ^ ( const sc_unsigned& u, const sc_int_base& v )
+{ return operator ^ ( u, SCAST<int64>( v ) ); }
+
+sc_signed
+operator ^ ( const sc_int_base& u, const sc_unsigned& v )
+{ return operator ^ ( SCAST<int64>( u ), v ); }
+
+sc_signed
+operator ^ (const sc_signed& u, const sc_int_base& v)
+{ return operator^(u, (int64) v); }
+
+sc_signed
+operator ^ (const sc_int_base& u, const sc_signed& v)
+{ return operator^((int64) u, v); }
+
+const sc_signed&
+sc_signed::operator ^= (const sc_int_base& v)
+{ return operator^=((int64) v); }
+
+
+sc_signed
+operator << (const sc_signed& u, const sc_int_base& v)
+{ return operator<<(u, (int64) v); }
+
+const sc_signed&
+sc_signed::operator <<= (const sc_int_base& v)
+{ return operator<<=((int64) v); }
+
+
+sc_signed
+operator >> (const sc_signed& u, const sc_int_base& v)
+{ return operator>>(u, (int64) v); }
+
+const sc_signed&
+sc_signed::operator >>= (const sc_int_base& v)
+{ return operator>>=((int64) v); }
+
+
+bool
+operator == (const sc_signed& u, const sc_int_base& v)
+{ return operator==(u, (int64) v); }
+
+bool
+operator == (const sc_int_base& u, const sc_signed& v)
+{ return operator==((int64) u, v); }
+
+
+bool
+operator != (const sc_signed& u, const sc_int_base& v)
+{ return operator!=(u, (int64) v); }
+
+bool
+operator != (const sc_int_base& u, const sc_signed& v)
+{ return operator!=((int64) u, v); }
+
+
+bool
+operator < (const sc_signed& u, const sc_int_base& v)
+{ return operator<(u, (int64) v); }
+
+bool
+operator < (const sc_int_base& u, const sc_signed& v)
+{ return operator<((int64) u, v); }
+
+
+bool
+operator <= (const sc_signed& u, const sc_int_base& v)
+{ return operator<=(u, (int64) v); }
+
+bool
+operator <= (const sc_int_base& u, const sc_signed& v)
+{ return operator<=((int64) u, v); }
+
+
+bool
+operator > (const sc_signed& u, const sc_int_base& v)
+{ return operator>(u, (int64) v); }
+
+bool
+operator > (const sc_int_base& u, const sc_signed& v)
+{ return operator>((int64) u, v); }
+
+
+bool
+operator >= (const sc_signed& u, const sc_int_base& v)
+{ return operator>=(u, (int64) v); }
+
+bool
+operator >= (const sc_int_base& u, const sc_signed& v)
+{ return operator>=((int64) u, v); }
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Interfacing with sc_uint_base
+// ----------------------------------------------------------------------------
+
+const sc_signed&
+sc_signed::operator = (const sc_uint_base& v)
+{ return operator=((uint64) v); }
+
+
+sc_signed
+operator + (const sc_signed& u, const sc_uint_base& v)
+{ return operator+(u, (uint64) v); }
+
+sc_signed
+operator + (const sc_uint_base& u, const sc_signed& v)
+{ return operator+((uint64) u, v); }
+
+const sc_signed&
+sc_signed::operator += (const sc_uint_base& v)
+{ return operator+=((uint64) v); }
+
+
+sc_signed
+operator - (const sc_unsigned& u, const sc_uint_base& v)
+{ return operator-(u, (uint64) v); }
+
+sc_signed
+operator - (const sc_uint_base& u, const sc_unsigned& v)
+{ return operator-((uint64) u, v); }
+
+sc_signed
+operator - (const sc_signed& u, const sc_uint_base& v)
+{ return operator-(u, (uint64) v); }
+
+sc_signed
+operator - (const sc_uint_base& u, const sc_signed& v)
+{ return operator-((uint64) u, v); }
+
+const sc_signed&
+sc_signed::operator -= (const sc_uint_base& v)
+{ return operator-=((uint64) v); }
+
+
+sc_signed
+operator * (const sc_signed& u, const sc_uint_base& v)
+{ return operator*(u, (uint64) v); }
+
+sc_signed
+operator * (const sc_uint_base& u, const sc_signed& v)
+{ return operator*((uint64) u, v); }
+
+const sc_signed&
+sc_signed::operator *= (const sc_uint_base& v)
+{ return operator*=((uint64) v); }
+
+
+sc_signed
+operator / (const sc_signed& u, const sc_uint_base& v)
+{ return operator/(u, (uint64) v); }
+
+sc_signed
+operator / (const sc_uint_base& u, const sc_signed& v)
+{ return operator/((uint64) u, v); }
+
+const sc_signed&
+sc_signed::operator /= (const sc_uint_base& v)
+{ return operator/=((uint64) v); }
+
+
+sc_signed
+operator % (const sc_signed& u, const sc_uint_base& v)
+{ return operator%(u, (uint64) v); }
+
+sc_signed
+operator % (const sc_uint_base& u, const sc_signed& v)
+{ return operator%((uint64) u, v); }
+
+const sc_signed&
+sc_signed::operator %= (const sc_uint_base& v)
+{ return operator%=((uint64) v); }
+
+
+sc_signed
+operator & (const sc_signed& u, const sc_uint_base& v)
+{ return operator&(u, (uint64) v); }
+
+sc_signed
+operator & (const sc_uint_base& u, const sc_signed& v)
+{ return operator&((uint64) u, v); }
+
+const sc_signed&
+sc_signed::operator &= (const sc_uint_base& v)
+{ return operator&=((uint64) v); }
+
+
+sc_signed
+operator | (const sc_signed& u, const sc_uint_base& v)
+{ return operator|(u, (uint64) v); }
+
+sc_signed
+operator | (const sc_uint_base& u, const sc_signed& v)
+{ return operator|((uint64) u, v); }
+
+const sc_signed&
+sc_signed::operator |= (const sc_uint_base& v)
+{ return operator|=((uint64) v); }
+
+
+sc_signed
+operator ^ (const sc_signed& u, const sc_uint_base& v)
+{ return operator^(u, (uint64) v); }
+
+sc_signed
+operator ^ (const sc_uint_base& u, const sc_signed& v)
+{ return operator^((uint64) u, v); }
+
+const sc_signed&
+sc_signed::operator ^= (const sc_uint_base& v)
+{ return operator^=((uint64) v); }
+
+
+sc_signed
+operator << (const sc_signed& u, const sc_uint_base& v)
+{ return operator<<(u, (uint64) v); }
+
+const sc_signed&
+sc_signed::operator <<= (const sc_uint_base& v)
+{ return operator<<=((uint64) v); }
+
+
+sc_signed
+operator >> (const sc_signed& u, const sc_uint_base& v)
+{ return operator>>(u, (uint64) v); }
+
+const sc_signed&
+sc_signed::operator >>= (const sc_uint_base& v)
+{ return operator>>=((uint64) v); }
+
+
+bool
+operator == (const sc_signed& u, const sc_uint_base& v)
+{ return operator==(u, (uint64) v); }
+
+bool
+operator == (const sc_uint_base& u, const sc_signed& v)
+{ return operator==((uint64) u, v); }
+
+
+bool
+operator != (const sc_signed& u, const sc_uint_base& v)
+{ return operator!=(u, (uint64) v); }
+
+bool
+operator != (const sc_uint_base& u, const sc_signed& v)
+{ return operator!=((uint64) u, v); }
+
+
+bool
+operator < (const sc_signed& u, const sc_uint_base& v)
+{ return operator<(u, (uint64) v); }
+
+bool
+operator < (const sc_uint_base& u, const sc_signed& v)
+{ return operator<((uint64) u, v); }
+
+
+bool
+operator <= (const sc_signed& u, const sc_uint_base& v)
+{ return operator<=(u, (uint64) v); }
+
+bool
+operator <= (const sc_uint_base& u, const sc_signed& v)
+{ return operator<=((uint64) u, v); }
+
+
+bool
+operator > (const sc_signed& u, const sc_uint_base& v)
+{ return operator>(u, (uint64) v); }
+
+bool
+operator > (const sc_uint_base& u, const sc_signed& v)
+{ return operator>((uint64) u, v); }
+
+
+bool
+operator >= (const sc_signed& u, const sc_uint_base& v)
+{ return operator>=(u, (uint64) v); }
+
+bool
+operator >= (const sc_uint_base& u, const sc_signed& v)
+{ return operator>=((uint64) u, v); }
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Input and output operators
+// ----------------------------------------------------------------------------
+
+// Operators in this section are included from sc_nbcommon.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Operator macros.
+// ----------------------------------------------------------------------------
+
+#define CONVERT_LONG(u) \
+small_type u ## s = get_sign(u); \
+sc_digit u ## d[DIGITS_PER_ULONG]; \
+from_uint(DIGITS_PER_ULONG, u ## d, (unsigned long) u);
+
+#define CONVERT_LONG_2(u) \
+sc_digit u ## d[DIGITS_PER_ULONG]; \
+from_uint(DIGITS_PER_ULONG, u ## d, (unsigned long) u);
+
+#define CONVERT_INT(u) \
+small_type u ## s = get_sign(u); \
+sc_digit u ## d[DIGITS_PER_UINT]; \
+from_uint(DIGITS_PER_UINT, u ## d, (unsigned int) u);
+
+#define CONVERT_INT_2(u) \
+sc_digit u ## d[DIGITS_PER_UINT]; \
+from_uint(DIGITS_PER_UINT, u ## d, (unsigned int) u);
+
+#define CONVERT_INT64(u) \
+small_type u ## s = get_sign(u); \
+sc_digit u ## d[DIGITS_PER_UINT64]; \
+from_uint(DIGITS_PER_UINT64, u ## d, (uint64) u);
+
+#define CONVERT_INT64_2(u) \
+sc_digit u ## d[DIGITS_PER_UINT64]; \
+from_uint(DIGITS_PER_UINT64, u ## d, (uint64) u);
+
+
+// ----------------------------------------------------------------------------
+// SECTION: PLUS operators: +, +=, ++
+// ----------------------------------------------------------------------------
+
+// Cases to consider when computing u + v:
+// 1. 0 + v = v
+// 2. u + 0 = u
+// 3. if sgn(u) == sgn(v)
+// 3.1 u + v = +(u + v) = sgn(u) * (u + v)
+// 3.2 (-u) + (-v) = -(u + v) = sgn(u) * (u + v)
+// 4. if sgn(u) != sgn(v)
+// 4.1 u + (-v) = u - v = sgn(u) * (u - v)
+// 4.2 (-u) + v = -(u - v) ==> sgn(u) * (u - v)
+//
+// Specialization of above cases for computing ++u or u++:
+// 1. 0 + 1 = 1
+// 3. u + 1 = u + 1 = sgn(u) * (u + 1)
+// 4. (-u) + 1 = -(u - 1) = sgn(u) * (u - 1)
+
+sc_signed
+operator+(const sc_unsigned& u, const sc_signed& v)
+{
+
+ if (u.sgn == SC_ZERO) // case 1
+ return sc_signed(v);
+
+ if (v.sgn == SC_ZERO) // case 2
+ return sc_signed(u);
+
+ // cases 3 and 4
+ return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator+(const sc_signed& u, const sc_unsigned& v)
+{
+
+ if (u.sgn == SC_ZERO) // case 1
+ return sc_signed(v);
+
+ if (v.sgn == SC_ZERO) // case 2
+ return sc_signed(u);
+
+ // cases 3 and 4
+ return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator+(const sc_signed& u, const sc_signed& v)
+{
+
+ if (u.sgn == SC_ZERO) // case 1
+ return sc_signed(v);
+
+ if (v.sgn == SC_ZERO) // case 2
+ return sc_signed(u);
+
+ // cases 3 and 4
+ return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator+(const sc_signed &u, int64 v)
+{
+
+ if (v == 0) // case 2
+ return sc_signed(u);
+
+ CONVERT_INT64(v);
+
+ if (u.sgn == SC_ZERO) // case 1
+ return sc_signed(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
+
+ // cases 3 and 4
+ return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+
+sc_signed
+operator+(int64 u, const sc_signed &v)
+{
+
+ if (u == 0) // case 1
+ return sc_signed(v);
+
+ CONVERT_INT64(u);
+
+ if (v.sgn == SC_ZERO) // case 2
+ return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
+
+ // cases 3 and 4
+
+ return add_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator+(const sc_unsigned &u, int64 v)
+{
+
+ if (v == 0) // case 2
+ return sc_signed(u);
+
+ CONVERT_INT64(v);
+
+ if (u.sgn == SC_ZERO) // case 1
+ return sc_signed(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
+
+ // cases 3 and 4
+ return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+
+sc_signed
+operator+(int64 u, const sc_unsigned &v)
+{
+
+ if (u == 0) // case 1
+ return sc_signed(v);
+
+ CONVERT_INT64(u);
+
+ if (v.sgn == SC_ZERO) // case 2
+ return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
+
+ // cases 3 and 4
+
+ return add_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator+(const sc_signed &u, uint64 v)
+{
+
+ if (v == 0) // case 2
+ return sc_signed(u);
+
+ CONVERT_INT64(v);
+
+ if (u.sgn == SC_ZERO) // case 1
+ return sc_signed(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
+
+ // cases 3 and 4
+ return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+
+sc_signed
+operator+(uint64 u, const sc_signed &v)
+{
+
+ if (u == 0) // case 1
+ return sc_signed(v);
+
+ CONVERT_INT64(u);
+
+ if (v.sgn == SC_ZERO) // case 2
+ return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
+
+ // cases 3 and 4
+
+ return add_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator+(const sc_signed &u, long v)
+{
+
+ if (v == 0) // case 2
+ return sc_signed(u);
+
+ CONVERT_LONG(v);
+
+ if (u.sgn == SC_ZERO) // case 1
+ return sc_signed(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
+
+ // cases 3 and 4
+ return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+}
+
+
+sc_signed
+operator+(long u, const sc_signed &v)
+{
+
+ if (u == 0) // case 1
+ return sc_signed(v);
+
+ CONVERT_LONG(u);
+
+ if (v.sgn == SC_ZERO) // case 2
+ return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
+
+ // cases 3 and 4
+ return add_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator+(const sc_unsigned &u, long v)
+{
+
+ if (v == 0) // case 2
+ return sc_signed(u);
+
+ CONVERT_LONG(v);
+
+ if (u.sgn == SC_ZERO) // case 1
+ return sc_signed(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
+
+ // cases 3 and 4
+ return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+}
+
+
+sc_signed
+operator+(long u, const sc_unsigned &v)
+{
+
+ if (u == 0) // case 1
+ return sc_signed(v);
+
+ CONVERT_LONG(u);
+
+ if (v.sgn == SC_ZERO) // case 2
+ return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
+
+ // cases 3 and 4
+ return add_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator+(const sc_signed &u, unsigned long v)
+{
+
+ if (v == 0) // case 2
+ return sc_signed(u);
+
+ CONVERT_LONG(v);
+
+ if (u.sgn == SC_ZERO) // case 1
+ return sc_signed(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
+
+ // cases 3 and 4
+ return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+}
+
+
+sc_signed
+operator+(unsigned long u, const sc_signed &v)
+{
+
+ if (u == 0) // case 1
+ return sc_signed(v);
+
+ CONVERT_LONG(u);
+
+ if (v.sgn == SC_ZERO) // case 2
+ return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
+
+ // cases 3 and 4
+ return add_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+// The rest of the operators in this section are included from
+// sc_nbcommon.cpp.
+
+// ----------------------------------------------------------------------------
+// SECTION: MINUS operators: -, -=, --
+// ----------------------------------------------------------------------------
+
+// Cases to consider when computing u + v:
+// 1. u - 0 = u
+// 2. 0 - v = -v
+// 3. if sgn(u) != sgn(v)
+// 3.1 u - (-v) = u + v = sgn(u) * (u + v)
+// 3.2 (-u) - v = -(u + v) ==> sgn(u) * (u + v)
+// 4. if sgn(u) == sgn(v)
+// 4.1 u - v = +(u - v) = sgn(u) * (u - v)
+// 4.2 (-u) - (-v) = -(u - v) = sgn(u) * (u - v)
+//
+// Specialization of above cases for computing --u or u--:
+// 1. 0 - 1 = -1
+// 3. (-u) - 1 = -(u + 1) = sgn(u) * (u + 1)
+// 4. u - 1 = u - 1 = sgn(u) * (u - 1)
+
+sc_signed
+operator-(const sc_unsigned& u, const sc_unsigned& v)
+{
+
+ if (v.sgn == SC_ZERO) // case 1
+ return sc_signed(u);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_signed(v, -v.sgn);
+
+ // cases 3 and 4
+ return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ -v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator-(const sc_unsigned& u, const sc_signed& v)
+{
+
+ if (v.sgn == SC_ZERO) // case 1
+ return sc_signed(u);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_signed(v, -v.sgn);
+
+ // cases 3 and 4
+ return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ -v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator-(const sc_signed& u, const sc_unsigned& v)
+{
+
+ if (v.sgn == SC_ZERO) // case 1
+ return sc_signed(u);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_signed(v, -v.sgn);
+
+ // cases 3 and 4
+ return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ -v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator-(const sc_signed& u, const sc_signed& v)
+{
+
+ if (v.sgn == SC_ZERO) // case 1
+ return sc_signed(u);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_signed(v, -v.sgn);
+
+ // cases 3 and 4
+ return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ -v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator-(const sc_signed &u, int64 v)
+{
+
+ if (v == 0) // case 1
+ return sc_signed(u);
+
+ CONVERT_INT64(v);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_signed(-vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
+
+ // cases 3 and 4
+ return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ -vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+
+sc_signed
+operator-(int64 u, const sc_signed& v)
+{
+
+ if (u == 0) // case 1
+ return sc_signed(v, -v.sgn);
+
+ CONVERT_INT64(u);
+
+ if (v.sgn == SC_ZERO) // case 2
+ return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
+
+ // cases 3 and 4
+
+ return add_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ -v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator-(const sc_unsigned &u, int64 v)
+{
+
+ if (v == 0) // case 1
+ return sc_signed(u);
+
+ CONVERT_INT64(v);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_signed(-vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
+
+ // cases 3 and 4
+ return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ -vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+
+sc_signed
+operator-(int64 u, const sc_unsigned& v)
+{
+
+ if (u == 0) // case 1
+ return sc_signed(v, -v.sgn);
+
+ CONVERT_INT64(u);
+
+ if (v.sgn == SC_ZERO) // case 2
+ return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
+
+ // cases 3 and 4
+
+ return add_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ -v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator-(const sc_signed &u, uint64 v)
+{
+
+ if (v == 0) // case 1
+ return sc_signed(u);
+
+ CONVERT_INT64(v);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_signed(-vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
+
+ // cases 3 and 4
+
+ return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ -vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+
+sc_signed
+operator-(uint64 u, const sc_signed& v)
+{
+
+ if (u == 0) // case 1
+ return sc_signed(v, -v.sgn);
+
+ CONVERT_INT64(u);
+
+ if (v.sgn == SC_ZERO) // case 2
+ return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
+
+ // cases 3 and 4
+ return add_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ -v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator-(const sc_unsigned &u, uint64 v)
+{
+
+ if (v == 0) // case 1
+ return sc_signed(u);
+
+ CONVERT_INT64(v);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_signed(-vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
+
+ // cases 3 and 4
+
+ return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ -vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+
+sc_signed
+operator-(uint64 u, const sc_unsigned& v)
+{
+
+ if (u == 0) // case 1
+ return sc_signed(v, -v.sgn);
+
+ CONVERT_INT64(u);
+
+ if (v.sgn == SC_ZERO) // case 2
+ return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
+
+ // cases 3 and 4
+ return add_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ -v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator-(const sc_signed &u, long v)
+{
+
+ if (v == 0) // case 1
+ return sc_signed(u);
+
+ CONVERT_LONG(v);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_signed(-vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
+
+ // cases 3 and 4
+ return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ -vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+}
+
+
+sc_signed
+operator-(long u, const sc_signed& v)
+{
+
+ if (u == 0) // case 1
+ return sc_signed(v, -v.sgn);
+
+ CONVERT_LONG(u);
+
+ if (v.sgn == SC_ZERO) // case 2
+ return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
+
+ // cases 3 and 4
+ return add_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ -v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator-(const sc_unsigned &u, long v)
+{
+
+ if (v == 0) // case 1
+ return sc_signed(u);
+
+ CONVERT_LONG(v);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_signed(-vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
+
+ // cases 3 and 4
+ return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ -vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+}
+
+
+sc_signed
+operator-(long u, const sc_unsigned& v)
+{
+
+ if (u == 0) // case 1
+ return sc_signed(v, -v.sgn);
+
+ CONVERT_LONG(u);
+
+ if (v.sgn == SC_ZERO) // case 2
+ return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
+
+ // cases 3 and 4
+ return add_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ -v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator-(const sc_signed &u, unsigned long v)
+{
+
+ if (v == 0) // case 1
+ return sc_signed(u);
+
+ CONVERT_LONG(v);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_signed(-vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
+
+ // cases 3 and 4
+ return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ -vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+}
+
+
+sc_signed
+operator-(unsigned long u, const sc_signed& v)
+{
+ if (u == 0) // case 1
+ return sc_signed(v, -v.sgn);
+
+ CONVERT_LONG(u);
+
+ if (v.sgn == SC_ZERO) // case 2
+ return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
+
+ // cases 3 and 4
+ return add_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ -v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator-(const sc_unsigned &u, unsigned long v)
+{
+
+ if (v == 0) // case 1
+ return sc_signed(u);
+
+ CONVERT_LONG(v);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_signed(-vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
+
+ // cases 3 and 4
+ return add_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ -vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+}
+
+
+sc_signed
+operator-(unsigned long u, const sc_unsigned& v)
+{
+ if (u == 0) // case 1
+ return sc_signed(v, -v.sgn);
+
+ CONVERT_LONG(u);
+
+ if (v.sgn == SC_ZERO) // case 2
+ return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
+
+ // cases 3 and 4
+ return add_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ -v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+// The rest of the operators in this section are included from
+// sc_nbcommon.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: MULTIPLICATION operators: *, *=
+// ----------------------------------------------------------------------------
+
+// Cases to consider when computing u * v:
+// 1. u * 0 = 0 * v = 0
+// 2. 1 * v = v and -1 * v = -v
+// 3. u * 1 = u and u * -1 = -u
+// 4. u * v = u * v
+
+sc_signed
+operator*(const sc_unsigned& u, const sc_signed& v)
+{
+
+ small_type s = mul_signs(u.sgn, v.sgn);
+
+ if (s == SC_ZERO) // case 1
+ return sc_signed();
+
+ // cases 2-4
+ return mul_signed_friend(s, u.nbits, u.ndigits, u.digit,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator*(const sc_signed& u, const sc_unsigned& v)
+{
+
+ small_type s = mul_signs(u.sgn, v.sgn);
+
+ if (s == SC_ZERO) // case 1
+ return sc_signed();
+
+ // cases 2-4
+ return mul_signed_friend(s, u.nbits, u.ndigits, u.digit,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator*(const sc_signed& u, const sc_signed& v)
+{
+
+ small_type s = mul_signs(u.sgn, v.sgn);
+
+ if (s == SC_ZERO) // case 1
+ return sc_signed();
+
+ // cases 2-4
+ return mul_signed_friend(s, u.nbits, u.ndigits, u.digit,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator*(const sc_signed& u, int64 v)
+{
+
+ small_type s = mul_signs(u.sgn, get_sign(v));
+
+ if (s == SC_ZERO) // case 1
+ return sc_signed();
+
+ CONVERT_INT64_2(v);
+
+ // cases 2-4
+ return mul_signed_friend(s, u.nbits, u.ndigits, u.digit,
+ BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+
+sc_signed
+operator*(int64 u, const sc_signed& v)
+{
+
+ small_type s = mul_signs(v.sgn, get_sign(u));
+
+ if (s == SC_ZERO) // case 1
+ return sc_signed();
+
+ CONVERT_INT64_2(u);
+
+ // cases 2-4
+ return mul_signed_friend(s, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator*(const sc_unsigned& u, int64 v)
+{
+
+ small_type s = mul_signs(u.sgn, get_sign(v));
+
+ if (s == SC_ZERO) // case 1
+ return sc_signed();
+
+ CONVERT_INT64_2(v);
+
+ // cases 2-4
+ return mul_signed_friend(s, u.nbits, u.ndigits, u.digit,
+ BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+
+sc_signed
+operator*(int64 u, const sc_unsigned& v)
+{
+
+ small_type s = mul_signs(v.sgn, get_sign(u));
+
+ if (s == SC_ZERO) // case 1
+ return sc_signed();
+
+ CONVERT_INT64_2(u);
+
+ // cases 2-4
+ return mul_signed_friend(s, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator*(const sc_signed& u, uint64 v)
+{
+
+ small_type s = mul_signs(u.sgn, get_sign(v));
+
+ if (s == SC_ZERO) // case 1
+ return sc_signed();
+
+ CONVERT_INT64_2(v);
+
+ // cases 2-4
+ return mul_signed_friend(s, u.nbits, u.ndigits, u.digit,
+ BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+
+sc_signed
+operator*(uint64 u, const sc_signed& v)
+{
+
+ small_type s = mul_signs(v.sgn, get_sign(u));
+
+ if (s == SC_ZERO) // case 1
+ return sc_signed();
+
+ CONVERT_INT64_2(u);
+
+ // cases 2-4
+ return mul_signed_friend(s, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator*(const sc_signed& u, long v)
+{
+
+ small_type s = mul_signs(u.sgn, get_sign(v));
+
+ if (s == SC_ZERO) // case 1
+ return sc_signed();
+
+ CONVERT_LONG_2(v);
+
+ // cases 2-4
+ return mul_signed_friend(s, u.nbits, u.ndigits, u.digit,
+ BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+}
+
+
+sc_signed
+operator*(long u, const sc_signed& v)
+{
+
+ small_type s = mul_signs(v.sgn, get_sign(u));
+
+ if (s == SC_ZERO) // case 1
+ return sc_signed();
+
+ CONVERT_LONG_2(u);
+
+ // cases 2-4
+ return mul_signed_friend(s, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator*(const sc_unsigned& u, long v)
+{
+
+ small_type s = mul_signs(u.sgn, get_sign(v));
+
+ if (s == SC_ZERO) // case 1
+ return sc_signed();
+
+ CONVERT_LONG_2(v);
+
+ // cases 2-4
+ return mul_signed_friend(s, u.nbits, u.ndigits, u.digit,
+ BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+}
+
+
+sc_signed
+operator*(long u, const sc_unsigned& v)
+{
+
+ small_type s = mul_signs(v.sgn, get_sign(u));
+
+ if (s == SC_ZERO) // case 1
+ return sc_signed();
+
+ CONVERT_LONG_2(u);
+
+ // cases 2-4
+ return mul_signed_friend(s, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator*(const sc_signed& u, unsigned long v)
+{
+
+ small_type s = mul_signs(u.sgn, get_sign(v));
+
+ if (s == SC_ZERO) // case 1
+ return sc_signed();
+
+ CONVERT_LONG_2(v);
+
+ // else cases 2-4
+ return mul_signed_friend(s, u.nbits, u.ndigits, u.digit,
+ BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+}
+
+sc_signed
+operator*(unsigned long u, const sc_signed& v)
+{
+
+ small_type s = mul_signs(v.sgn, get_sign(u));
+
+ if (s == SC_ZERO) // case 1
+ return sc_signed();
+
+ CONVERT_LONG_2(u);
+
+ // cases 2-4
+ return mul_signed_friend(s, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+// The rest of the operators in this section are included from
+// sc_nbcommon.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: DIVISION operators: /, /=
+// ----------------------------------------------------------------------------
+
+// Cases to consider when finding the quotient q = floor(u/v):
+// Note that u = q * v + r for r < q.
+// 1. 0 / 0 or u / 0 => error
+// 2. 0 / v => 0 = 0 * v + 0
+// 3. u / v && u = v => u = 1 * u + 0 - u or v can be 1 or -1
+// 4. u / v && u < v => u = 0 * v + u - u can be 1 or -1
+// 5. u / v && u > v => u = q * v + r - v can be 1 or -1
+
+sc_signed
+operator/(const sc_unsigned& u, const sc_signed& v)
+{
+
+ small_type s = mul_signs(u.sgn, v.sgn);
+
+ if (s == SC_ZERO) {
+ div_by_zero(v.sgn); // case 1
+ return sc_signed(); // case 2
+ }
+
+ // other cases
+ return div_signed_friend(s, u.nbits, u.ndigits, u.digit,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator/(const sc_signed& u, const sc_unsigned& v)
+{
+
+ small_type s = mul_signs(u.sgn, v.sgn);
+
+ if (s == SC_ZERO) {
+ div_by_zero(v.sgn); // case 1
+ return sc_signed(); // case 2
+ }
+
+ // other cases
+ return div_signed_friend(s, u.nbits, u.ndigits, u.digit,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator/(const sc_signed& u, const sc_signed& v)
+{
+
+ small_type s = mul_signs(u.sgn, v.sgn);
+
+ if (s == SC_ZERO) {
+ div_by_zero(v.sgn); // case 1
+ return sc_signed(); // case 2
+ }
+
+ // other cases
+ return div_signed_friend(s, u.nbits, u.ndigits, u.digit,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator/(const sc_signed& u, int64 v)
+{
+
+ small_type s = mul_signs(u.sgn, get_sign(v));
+
+ if (s == SC_ZERO) {
+ div_by_zero(v); // case 1
+ return sc_signed(); // case 2
+ }
+
+ CONVERT_INT64_2(v);
+
+ // other cases
+ return div_signed_friend(s, u.nbits, u.ndigits, u.digit,
+ BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+
+sc_signed
+operator/(int64 u, const sc_signed& v)
+{
+
+ small_type s = mul_signs(v.sgn, get_sign(u));
+
+ if (s == SC_ZERO) {
+ div_by_zero(v.sgn); // case 1
+ return sc_signed(); // case 2
+ }
+
+ CONVERT_INT64_2(u);
+
+ // other cases
+ return div_signed_friend(s, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator/(const sc_unsigned& u, int64 v)
+{
+
+ small_type s = mul_signs(u.sgn, get_sign(v));
+
+ if (s == SC_ZERO) {
+ div_by_zero(v); // case 1
+ return sc_signed(); // case 2
+ }
+
+ CONVERT_INT64_2(v);
+
+ // other cases
+ return div_signed_friend(s, u.nbits, u.ndigits, u.digit,
+ BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+
+sc_signed
+operator/(int64 u, const sc_unsigned& v)
+{
+
+ small_type s = mul_signs(v.sgn, get_sign(u));
+
+ if (s == SC_ZERO) {
+ div_by_zero(v.sgn); // case 1
+ return sc_signed(); // case 2
+ }
+
+ CONVERT_INT64_2(u);
+
+ // other cases
+ return div_signed_friend(s, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator/(const sc_signed& u, uint64 v)
+{
+
+ small_type s = mul_signs(u.sgn, get_sign(v));
+
+ if (s == SC_ZERO) {
+ div_by_zero(v); // case 1
+ return sc_signed(); // case 2
+ }
+
+ CONVERT_INT64_2(v);
+
+ // other cases
+ return div_signed_friend(s, u.nbits, u.ndigits, u.digit,
+ BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+
+sc_signed
+operator/(uint64 u, const sc_signed& v)
+{
+
+ small_type s = mul_signs(v.sgn, get_sign(u));
+
+ if (s == SC_ZERO) {
+ div_by_zero(v.sgn); // case 1
+ return sc_signed(); // case 2
+
+ }
+
+ CONVERT_INT64_2(u);
+
+ // other cases
+ return div_signed_friend(s, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator/(const sc_signed& u, long v)
+{
+
+ small_type s = mul_signs(u.sgn, get_sign(v));
+
+ if (s == SC_ZERO) {
+ div_by_zero(v); // case 1
+ return sc_signed(); // case 2
+ }
+
+ CONVERT_LONG_2(v);
+
+ // other cases
+ return div_signed_friend(s, u.nbits, u.ndigits, u.digit,
+ BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+}
+
+
+sc_signed
+operator/(long u, const sc_signed& v)
+{
+
+ small_type s = mul_signs(v.sgn, get_sign(u));
+
+ if (s == SC_ZERO) {
+ div_by_zero(v.sgn); // case 1
+ return sc_signed(); // case 2
+ }
+
+ CONVERT_LONG_2(u);
+
+ // other cases
+ return div_signed_friend(s, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator/(const sc_unsigned& u, long v)
+{
+
+ small_type s = mul_signs(u.sgn, get_sign(v));
+
+ if (s == SC_ZERO) {
+ div_by_zero(v); // case 1
+ return sc_signed(); // case 2
+ }
+
+ CONVERT_LONG_2(v);
+
+ // other cases
+ return div_signed_friend(s, u.nbits, u.ndigits, u.digit,
+ BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+}
+
+
+sc_signed
+operator/(long u, const sc_unsigned& v)
+{
+
+ small_type s = mul_signs(v.sgn, get_sign(u));
+
+ if (s == SC_ZERO) {
+ div_by_zero(v.sgn); // case 1
+ return sc_signed(); // case 2
+ }
+
+ CONVERT_LONG_2(u);
+
+ // other cases
+ return div_signed_friend(s, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator/(const sc_signed& u, unsigned long v)
+{
+
+ small_type s = mul_signs(u.sgn, get_sign(v));
+
+ if (s == SC_ZERO) {
+ div_by_zero(v); // case 1
+ return sc_signed(); // case 2
+ }
+
+ CONVERT_LONG_2(v);
+
+ // other cases
+ return div_signed_friend(s, u.nbits, u.ndigits, u.digit,
+ BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+}
+
+
+sc_signed
+operator/(unsigned long u, const sc_signed& v)
+{
+
+ small_type s = mul_signs(v.sgn, get_sign(u));
+
+ if (s == SC_ZERO) {
+ div_by_zero(v.sgn); // case 1
+ return sc_signed(); // case 2
+
+ }
+
+ CONVERT_LONG_2(u);
+
+ // other cases
+ return div_signed_friend(s, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+// The rest of the operators in this section are included from
+// sc_nbcommon.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: MOD operators: %, %=.
+// ----------------------------------------------------------------------------
+
+// Cases to consider when finding the remainder r = u % v:
+// Note that u = q * v + r for r < q.
+// 1. 0 % 0 or u % 0 => error
+// 2. 0 % v => 0 = 0 * v + 0
+// 3. u % v && u = v => u = 1 * u + 0 - u or v can be 1 or -1
+// 4. u % v && u < v => u = 0 * v + u - u can be 1 or -1
+// 5. u % v && u > v => u = q * v + r - v can be 1 or -1
+
+sc_signed
+operator%(const sc_unsigned& u, const sc_signed& v)
+{
+
+ if ((u.sgn == SC_ZERO) || (v.sgn == SC_ZERO)) {
+ div_by_zero(v.sgn); // case 1
+ return sc_signed(); // case 2
+ }
+
+ // other cases
+ return mod_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ v.nbits, v.ndigits, v.digit);
+}
+
+
+sc_signed
+operator%(const sc_signed& u, const sc_unsigned& v)
+{
+
+ if ((u.sgn == SC_ZERO) || (v.sgn == SC_ZERO)) {
+ div_by_zero(v.sgn); // case 1
+ return sc_signed(); // case 2
+ }
+
+ // other cases
+ return mod_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ v.nbits, v.ndigits, v.digit);
+}
+
+
+sc_signed
+operator%(const sc_signed& u, const sc_signed& v)
+{
+
+ if ((u.sgn == SC_ZERO) || (v.sgn == SC_ZERO)) {
+ div_by_zero(v.sgn); // case 1
+ return sc_signed(); // case 2
+ }
+
+ // other cases
+ return mod_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ v.nbits, v.ndigits, v.digit);
+}
+
+
+sc_signed
+operator%(const sc_signed& u, int64 v)
+{
+
+ small_type vs = get_sign(v);
+
+ if ((u.sgn == SC_ZERO) || (vs == SC_ZERO)) {
+ div_by_zero(v); // case 1
+ return sc_signed(); // case 2
+ }
+
+ CONVERT_INT64_2(v);
+
+ // other cases
+ return mod_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+
+sc_signed
+operator%(int64 u, const sc_signed& v)
+{
+
+ small_type us = get_sign(u);
+
+ if ((us == SC_ZERO) || (v.sgn == SC_ZERO)) {
+ div_by_zero(v.sgn); // case 1
+ return sc_signed(); // case 2
+ }
+
+ CONVERT_INT64_2(u);
+
+ // other cases
+ return mod_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator%(const sc_unsigned& u, int64 v)
+{
+
+ small_type vs = get_sign(v);
+
+ if ((u.sgn == SC_ZERO) || (vs == SC_ZERO)) {
+ div_by_zero(v); // case 1
+ return sc_signed(); // case 2
+ }
+
+ CONVERT_INT64_2(v);
+
+ // other cases
+ return mod_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+
+sc_signed
+operator%(int64 u, const sc_unsigned& v)
+{
+
+ small_type us = get_sign(u);
+
+ if ((us == SC_ZERO) || (v.sgn == SC_ZERO)) {
+ div_by_zero(v.sgn); // case 1
+ return sc_signed(); // case 2
+ }
+
+ CONVERT_INT64_2(u);
+
+ // other cases
+ return mod_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator%(const sc_signed& u, uint64 v)
+{
+
+ if ((u.sgn == SC_ZERO) || (v == 0)) {
+ div_by_zero(v); // case 1
+ return sc_signed(); // case 2
+ }
+
+ CONVERT_INT64_2(v);
+
+ // other cases
+ return mod_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+
+sc_signed
+operator%(uint64 u, const sc_signed& v)
+{
+
+ if ((u == 0) || (v.sgn == SC_ZERO)) {
+ div_by_zero(v.sgn); // case 1
+ return sc_signed(); // case 2
+ }
+
+ CONVERT_INT64(u);
+
+ // other cases
+ return mod_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator%(const sc_signed& u, long v)
+{
+
+ small_type vs = get_sign(v);
+
+ if ((u.sgn == SC_ZERO) || (vs == SC_ZERO)) {
+ div_by_zero(v); // case 1
+ return sc_signed(); // case 2
+ }
+
+ CONVERT_LONG_2(v);
+
+ // other cases
+ return mod_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+}
+
+
+sc_signed
+operator%(long u, const sc_signed& v)
+{
+
+ small_type us = get_sign(u);
+
+ if ((us == SC_ZERO) || (v.sgn == SC_ZERO)) {
+ div_by_zero(v.sgn); // case 1
+ return sc_signed(); // case 2
+ }
+
+ CONVERT_LONG_2(u);
+
+ // other cases
+ return mod_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator%(const sc_unsigned& u, long v)
+{
+
+ small_type vs = get_sign(v);
+
+ if ((u.sgn == SC_ZERO) || (vs == SC_ZERO)) {
+ div_by_zero(v); // case 1
+ return sc_signed(); // case 2
+ }
+
+ CONVERT_LONG_2(v);
+
+ // other cases
+ return mod_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+}
+
+
+sc_signed
+operator%(long u, const sc_unsigned& v)
+{
+
+ small_type us = get_sign(u);
+
+ if ((us == SC_ZERO) || (v.sgn == SC_ZERO)) {
+ div_by_zero(v.sgn); // case 1
+ return sc_signed(); // case 2
+ }
+
+ CONVERT_LONG_2(u);
+
+ // other cases
+ return mod_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator%(const sc_signed& u, unsigned long v)
+{
+
+ if ((u.sgn == SC_ZERO) || (v == 0)) {
+ div_by_zero(v); // case 1
+ return sc_signed(); // case 2
+ }
+
+ CONVERT_LONG_2(v);
+
+ // other cases
+ return mod_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+}
+
+
+sc_signed
+operator%(unsigned long u, const sc_signed& v)
+{
+
+ if ((u == 0) || (v.sgn == SC_ZERO)) {
+ div_by_zero(v.sgn); // case 1
+ return sc_signed(); // case 2
+ }
+
+ CONVERT_LONG(u);
+
+ // other cases
+ return mod_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+// The rest of the operators in this section are included from
+// sc_nbcommon.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Bitwise AND operators: &, &=
+// ----------------------------------------------------------------------------
+
+// Cases to consider when computing u & v:
+// 1. u & 0 = 0 & v = 0
+// 2. u & v => sgn = +
+// 3. (-u) & (-v) => sgn = -
+// 4. u & (-v) => sgn = +
+// 5. (-u) & v => sgn = +
+
+sc_signed
+operator&(const sc_unsigned& u, const sc_signed& v)
+{
+
+ if ((u.sgn == SC_ZERO) || (v.sgn == SC_ZERO)) // case 1
+ return sc_signed();
+
+ // other cases
+ return and_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator&(const sc_signed& u, const sc_unsigned& v)
+{
+
+ if ((u.sgn == SC_ZERO) || (v.sgn == SC_ZERO)) // case 1
+ return sc_signed();
+
+ // other cases
+ return and_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator&(const sc_signed& u, const sc_signed& v)
+{
+
+ if ((u.sgn == SC_ZERO) || (v.sgn == SC_ZERO)) // case 1
+ return sc_signed();
+
+ // other cases
+ return and_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator&(const sc_signed& u, int64 v)
+{
+
+ if ((u.sgn == SC_ZERO) || (v == 0)) // case 1
+ return sc_signed();
+
+ CONVERT_INT64(v);
+
+ // other cases
+ return and_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+
+sc_signed
+operator&(int64 u, const sc_signed& v)
+{
+
+ if ((u == 0) || (v.sgn == SC_ZERO)) // case 1
+ return sc_signed();
+
+ CONVERT_INT64(u);
+
+ // other cases
+ return and_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator&(const sc_unsigned& u, int64 v)
+{
+
+ if ((u.sgn == SC_ZERO) || (v == 0)) // case 1
+ return sc_signed();
+
+ CONVERT_INT64(v);
+
+ // other cases
+ return and_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+
+sc_signed
+operator&(int64 u, const sc_unsigned& v)
+{
+
+ if ((u == 0) || (v.sgn == SC_ZERO)) // case 1
+ return sc_signed();
+
+ CONVERT_INT64(u);
+
+ // other cases
+ return and_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator&(const sc_signed& u, uint64 v)
+{
+
+ if ((u.sgn == SC_ZERO) || (v == 0)) // case 1
+ return sc_signed();
+
+ CONVERT_INT64(v);
+
+ // other cases
+ return and_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+
+sc_signed
+operator&(uint64 u, const sc_signed& v)
+{
+
+ if ((u == 0) || (v.sgn == SC_ZERO)) // case 1
+ return sc_signed();
+
+ CONVERT_INT64(u);
+
+ // other cases
+ return and_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator&(const sc_signed& u, long v)
+{
+
+ if ((u.sgn == SC_ZERO) || (v == 0)) // case 1
+ return sc_signed();
+
+ CONVERT_LONG(v);
+
+ // other cases
+ return and_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+}
+
+
+sc_signed
+operator&(long u, const sc_signed& v)
+{
+
+ if ((u == 0) || (v.sgn == SC_ZERO)) // case 1
+ return sc_signed();
+
+ CONVERT_LONG(u);
+
+ // other cases
+ return and_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator&(const sc_unsigned& u, long v)
+{
+
+ if ((u.sgn == SC_ZERO) || (v == 0)) // case 1
+ return sc_signed();
+
+ CONVERT_LONG(v);
+
+ // other cases
+ return and_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+}
+
+
+sc_signed
+operator&(long u, const sc_unsigned& v)
+{
+
+ if ((u == 0) || (v.sgn == SC_ZERO)) // case 1
+ return sc_signed();
+
+ CONVERT_LONG(u);
+
+ // other cases
+ return and_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator&(const sc_signed& u, unsigned long v)
+{
+
+ if ((u.sgn == SC_ZERO) || (v == 0)) // case 1
+ return sc_signed();
+
+ CONVERT_LONG(v);
+
+ // other cases
+ return and_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+}
+
+
+sc_signed
+operator&(unsigned long u, const sc_signed& v)
+{
+
+ if ((u == 0) || (v.sgn == SC_ZERO)) // case 1
+ return sc_signed();
+
+ CONVERT_LONG(u);
+
+ // other cases
+ return and_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+// The rest of the operators in this section are included from
+// sc_nbcommon.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Bitwise OR operators: |, |=
+// ----------------------------------------------------------------------------
+
+// Cases to consider when computing u | v:
+// 1. u | 0 = u
+// 2. 0 | v = v
+// 3. u | v => sgn = +
+// 4. (-u) | (-v) => sgn = -
+// 5. u | (-v) => sgn = -
+// 6. (-u) | v => sgn = -
+
+sc_signed
+operator|(const sc_unsigned& u, const sc_signed& v)
+{
+
+ if (v.sgn == SC_ZERO) // case 1
+ return sc_signed(u);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_signed(v);
+
+ // other cases
+ return or_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator|(const sc_signed& u, const sc_unsigned& v)
+{
+
+ if (v.sgn == SC_ZERO) // case 1
+ return sc_signed(u);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_signed(v);
+
+ // other cases
+ return or_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator|(const sc_signed& u, const sc_signed& v)
+{
+
+ if (v.sgn == SC_ZERO) // case 1
+ return sc_signed(u);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_signed(v);
+
+ // other cases
+ return or_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator|(const sc_signed& u, int64 v)
+{
+
+ if (v == 0) // case 1
+ return sc_signed(u);
+
+ CONVERT_INT64(v);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_signed(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
+
+ // other cases
+ return or_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+
+sc_signed
+operator|(int64 u, const sc_signed& v)
+{
+
+ if (u == 0)
+ return sc_signed(v);
+
+ CONVERT_INT64(u);
+
+ if (v.sgn == SC_ZERO)
+ return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
+
+ // other cases
+ return or_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator|(const sc_unsigned& u, int64 v)
+{
+
+ if (v == 0) // case 1
+ return sc_signed(u);
+
+ CONVERT_INT64(v);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_signed(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
+
+ // other cases
+ return or_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+
+sc_signed
+operator|(int64 u, const sc_unsigned& v)
+{
+
+ if (u == 0)
+ return sc_signed(v);
+
+ CONVERT_INT64(u);
+
+ if (v.sgn == SC_ZERO)
+ return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
+
+ // other cases
+ return or_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator|(const sc_signed& u, uint64 v)
+{
+
+ if (v == 0) // case 1
+ return sc_signed(u);
+
+ CONVERT_INT64(v);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_signed(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
+
+ // other cases
+ return or_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+
+sc_signed
+operator|(uint64 u, const sc_signed& v)
+{
+
+ if (u == 0)
+ return sc_signed(v);
+
+ CONVERT_INT64(u);
+
+ if (v.sgn == SC_ZERO)
+ return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
+
+ // other cases
+ return or_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator|(const sc_signed& u, long v)
+{
+
+ if (v == 0) // case 1
+ return sc_signed(u);
+
+ CONVERT_LONG(v);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_signed(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
+
+ // other cases
+ return or_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+}
+
+
+sc_signed
+operator|(long u, const sc_signed& v)
+{
+
+ if (u == 0)
+ return sc_signed(v);
+
+ CONVERT_LONG(u);
+
+ if (v.sgn == SC_ZERO)
+ return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
+
+ // other cases
+ return or_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator|(const sc_unsigned& u, long v)
+{
+
+ if (v == 0) // case 1
+ return sc_signed(u);
+
+ CONVERT_LONG(v);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_signed(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
+
+ // other cases
+ return or_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+}
+
+
+sc_signed
+operator|(long u, const sc_unsigned& v)
+{
+
+ if (u == 0)
+ return sc_signed(v);
+
+ CONVERT_LONG(u);
+
+ if (v.sgn == SC_ZERO)
+ return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
+
+ // other cases
+ return or_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator|(const sc_signed& u, unsigned long v)
+{
+
+ if (v == 0) // case 1
+ return sc_signed(u);
+
+ CONVERT_LONG(v);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_signed(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
+
+ // other cases
+ return or_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+}
+
+
+sc_signed
+operator|(unsigned long u, const sc_signed& v)
+{
+
+ if (u == 0)
+ return sc_signed(v);
+
+ CONVERT_LONG(u);
+
+ if (v.sgn == SC_ZERO)
+ return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
+
+ // other cases
+ return or_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+// The rest of the operators in this section are included from
+// sc_nbcommon.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Bitwise XOR operators: ^, ^=
+// ----------------------------------------------------------------------------
+
+// Cases to consider when computing u ^ v:
+// Note that u ^ v = (~u & v) | (u & ~v).
+// 1. u ^ 0 = u
+// 2. 0 ^ v = v
+// 3. u ^ v => sgn = +
+// 4. (-u) ^ (-v) => sgn = -
+// 5. u ^ (-v) => sgn = -
+// 6. (-u) ^ v => sgn = +
+
+sc_signed
+operator^(const sc_unsigned& u, const sc_signed& v)
+{
+
+ if (v.sgn == SC_ZERO) // case 1
+ return sc_signed(u);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_signed(v);
+
+ // other cases
+ return xor_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator^(const sc_signed& u, const sc_unsigned& v)
+{
+
+ if (v.sgn == SC_ZERO) // case 1
+ return sc_signed(u);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_signed(v);
+
+ // other cases
+ return xor_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator^(const sc_signed& u, const sc_signed& v)
+{
+
+ if (v.sgn == SC_ZERO) // case 1
+ return sc_signed(u);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_signed(v);
+
+ // other cases
+ return xor_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator^(const sc_signed& u, int64 v)
+{
+
+ if (v == 0) // case 1
+ return sc_signed(u);
+
+ CONVERT_INT64(v);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_signed(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
+
+ // other cases
+ return xor_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+
+sc_signed
+operator^(int64 u, const sc_signed& v)
+{
+
+ if (u == 0)
+ return sc_signed(v);
+
+ CONVERT_INT64(u);
+
+ if (v.sgn == SC_ZERO)
+ return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
+
+ // other cases
+ return xor_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator^(const sc_unsigned& u, int64 v)
+{
+
+ if (v == 0) // case 1
+ return sc_signed(u);
+
+ CONVERT_INT64(v);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_signed(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
+
+ // other cases
+ return xor_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+
+sc_signed
+operator^(int64 u, const sc_unsigned& v)
+{
+
+ if (u == 0)
+ return sc_signed(v);
+
+ CONVERT_INT64(u);
+
+ if (v.sgn == SC_ZERO)
+ return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
+
+ // other cases
+ return xor_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator^(const sc_signed& u, uint64 v)
+{
+
+ if (v == 0) // case 1
+ return sc_signed(u);
+
+ CONVERT_INT64(v);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_signed(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
+
+ // other cases
+ return xor_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+sc_signed
+operator^(uint64 u, const sc_signed& v)
+{
+ if (u == 0)
+ return sc_signed(v);
+
+ CONVERT_INT64(u);
+
+ if (v.sgn == SC_ZERO)
+ return sc_signed(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
+
+ // other cases
+ return xor_signed_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator^(const sc_signed& u, long v)
+{
+
+ if (v == 0) // case 1
+ return sc_signed(u);
+
+ CONVERT_LONG(v);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_signed(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
+
+ // other cases
+ return xor_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+}
+
+
+sc_signed
+operator^(long u, const sc_signed& v)
+{
+
+ if (u == 0)
+ return sc_signed(v);
+
+ CONVERT_LONG(u);
+
+ if (v.sgn == SC_ZERO)
+ return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
+
+ // other cases
+ return xor_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator^(const sc_unsigned& u, long v)
+{
+
+ if (v == 0) // case 1
+ return sc_signed(u);
+
+ CONVERT_LONG(v);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_signed(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
+
+ // other cases
+ return xor_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+}
+
+
+sc_signed
+operator^(long u, const sc_unsigned& v)
+{
+
+ if (u == 0)
+ return sc_signed(v);
+
+ CONVERT_LONG(u);
+
+ if (v.sgn == SC_ZERO)
+ return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
+
+ // other cases
+ return xor_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_signed
+operator^(const sc_signed& u, unsigned long v)
+{
+
+ if (v == 0) // case 1
+ return sc_signed(u);
+
+ CONVERT_LONG(v);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_signed(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
+
+ // other cases
+ return xor_signed_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+}
+
+sc_signed
+operator^(unsigned long u, const sc_signed& v)
+{
+ if (u == 0)
+ return sc_signed(v);
+
+ CONVERT_LONG(u);
+
+ if (v.sgn == SC_ZERO)
+ return sc_signed(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
+
+ // other cases
+ return xor_signed_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+// The rest of the operators in this section are included from
+// sc_nbcommon.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Bitwise NOT operator: ~
+// ----------------------------------------------------------------------------
+
+// Operators in this section are included from sc_nbcommon.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: LEFT SHIFT operators: <<, <<=
+// ----------------------------------------------------------------------------
+
+sc_signed
+operator<<(const sc_signed& u, const sc_unsigned& v)
+{
+ if (v.sgn == SC_ZERO)
+ return sc_signed(u);
+
+ return operator<<(u, v.to_ulong());
+}
+
+// The rest of the operators in this section are included from
+// sc_nbcommon.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: RIGHT SHIFT operators: >>, >>=
+// ----------------------------------------------------------------------------
+
+sc_signed
+operator>>(const sc_signed& u, const sc_unsigned& v)
+{
+
+ if (v.sgn == SC_ZERO)
+ return sc_signed(u);
+
+ return operator>>(u, v.to_ulong());
+
+}
+
+// The rest of the operators in this section are included from
+// sc_nbcommon.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Unary arithmetic operators.
+// ----------------------------------------------------------------------------
+
+sc_signed
+operator+(const sc_signed& u)
+{
+ return sc_signed(u);
+}
+
+sc_signed
+operator-(const sc_signed& u)
+{
+ return sc_signed(u, -u.sgn);
+}
+
+sc_signed
+operator-(const sc_unsigned& u)
+{
+ return sc_signed(u, -u.sgn);
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: EQUAL operator: ==
+// ----------------------------------------------------------------------------
+
+bool
+operator==(const sc_signed& u, const sc_signed& v)
+{
+
+ if (u.sgn != v.sgn)
+ return false;
+
+ if (&u == &v)
+ return true;
+
+ if (vec_skip_and_cmp(u.ndigits, u.digit, v.ndigits, v.digit) != 0)
+ return false;
+
+ return true;
+
+}
+
+
+bool
+operator==(const sc_signed& u, int64 v)
+{
+
+ CONVERT_INT64(v);
+
+ if (u.sgn != vs)
+ return false;
+
+ if (vec_skip_and_cmp(u.ndigits, u.digit, DIGITS_PER_INT64, vd) != 0)
+ return false;
+
+ return true;
+
+}
+
+
+bool
+operator==(int64 u, const sc_signed& v)
+{
+
+ CONVERT_INT64(u);
+
+ if (us != v.sgn)
+ return false;
+
+ if (vec_skip_and_cmp(DIGITS_PER_INT64, ud, v.ndigits, v.digit) != 0)
+ return false;
+
+ return true;
+
+}
+
+
+bool
+operator==(const sc_signed& u, uint64 v)
+{
+
+ CONVERT_INT64(v);
+
+ if (u.sgn != vs)
+ return false;
+
+ if (vec_skip_and_cmp(u.ndigits, u.digit, DIGITS_PER_INT64, vd) != 0)
+ return false;
+
+ return true;
+
+}
+
+
+bool
+operator==(uint64 u, const sc_signed& v)
+{
+
+ CONVERT_INT64(u);
+
+ if (us != v.sgn)
+ return false;
+
+ if (vec_skip_and_cmp(DIGITS_PER_INT64, ud, v.ndigits, v.digit) != 0)
+ return false;
+
+ return true;
+
+}
+
+
+bool
+operator==(const sc_signed& u, long v)
+{
+
+ CONVERT_LONG(v);
+
+ if (u.sgn != vs)
+ return false;
+
+ if (vec_skip_and_cmp(u.ndigits, u.digit, DIGITS_PER_LONG, vd) != 0)
+ return false;
+
+ return true;
+
+}
+
+
+bool
+operator==(long u, const sc_signed& v)
+{
+
+ CONVERT_LONG(u);
+
+ if (us != v.sgn)
+ return false;
+
+ if (vec_skip_and_cmp(DIGITS_PER_LONG, ud, v.ndigits, v.digit) != 0)
+ return false;
+
+ return true;
+
+}
+
+
+bool
+operator==(const sc_signed& u, unsigned long v)
+{
+
+ CONVERT_LONG(v);
+
+ if (u.sgn != vs)
+ return false;
+
+ if (vec_skip_and_cmp(u.ndigits, u.digit, DIGITS_PER_LONG, vd) != 0)
+ return false;
+
+ return true;
+
+}
+
+
+bool
+operator==(unsigned long u, const sc_signed& v)
+{
+
+ CONVERT_LONG(u);
+
+ if (us != v.sgn)
+ return false;
+
+ if (vec_skip_and_cmp(DIGITS_PER_LONG, ud, v.ndigits, v.digit) != 0)
+ return false;
+
+ return true;
+
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: NOT_EQUAL operator: !=
+// ----------------------------------------------------------------------------
+
+// Operators in this section are included from sc_nbcommon.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: LESS THAN operator: <
+// ----------------------------------------------------------------------------
+
+bool
+operator<(const sc_signed& u, const sc_signed& v)
+{
+
+ if (u.sgn < v.sgn)
+ return true;
+
+ if (u.sgn > v.sgn)
+ return false;
+
+ // u.sgn == v.sgn
+
+ if (&u == &v)
+ return false;
+
+ if (u.sgn == SC_POS) {
+
+ if (vec_skip_and_cmp(u.ndigits, u.digit, v.ndigits, v.digit) < 0)
+ return true;
+
+ }
+ else if (u.sgn == SC_NEG) {
+
+ if (vec_skip_and_cmp(u.ndigits, u.digit, v.ndigits, v.digit) > 0)
+ return true;
+
+ }
+
+ return false;
+
+}
+
+
+bool
+operator<(const sc_signed& u, int64 v)
+{
+
+ CONVERT_INT64(v);
+
+ if (u.sgn < vs)
+ return true;
+
+ if (u.sgn > vs)
+ return false;
+
+ // u.sgn == vs
+
+ if (vs == SC_POS) {
+
+ if (vec_skip_and_cmp(u.ndigits, u.digit, DIGITS_PER_INT64, vd) < 0)
+ return true;
+
+ }
+ else if (vs == SC_NEG) {
+
+ if (vec_skip_and_cmp(u.ndigits, u.digit, DIGITS_PER_INT64, vd) > 0)
+ return true;
+
+ }
+
+ return false;
+
+}
+
+
+bool
+operator<(int64 u, const sc_signed& v)
+{
+
+ CONVERT_INT64(u);
+
+ if (us < v.sgn)
+ return true;
+
+ if (us > v.sgn)
+ return false;
+
+ // us == v.sgn
+
+ if (us == SC_POS) {
+
+ if (vec_skip_and_cmp(DIGITS_PER_INT64, ud, v.ndigits, v.digit) < 0)
+ return true;
+
+ }
+ else if (us == SC_NEG) {
+
+ if (vec_skip_and_cmp(DIGITS_PER_INT64, ud, v.ndigits, v.digit) > 0)
+ return true;
+
+ }
+
+ return false;
+
+}
+
+
+bool
+operator<(const sc_signed& u, uint64 v)
+{
+
+ CONVERT_INT64(v);
+
+ if (u.sgn < vs)
+ return true;
+
+ if (u.sgn > vs)
+ return false;
+
+ // u.sgn == vs
+
+ if (vs == SC_POS) {
+
+ if (vec_skip_and_cmp(u.ndigits, u.digit, DIGITS_PER_INT64, vd) < 0)
+ return true;
+
+ }
+
+ return false;
+
+}
+
+
+bool
+operator<(uint64 u, const sc_signed& v)
+{
+
+ CONVERT_INT64(u);
+
+ if (us < v.sgn)
+ return true;
+
+ if (us > v.sgn)
+ return false;
+
+ // us == v.sgn
+
+ if (us == SC_POS) {
+
+ if (vec_skip_and_cmp(DIGITS_PER_INT64, ud, v.ndigits, v.digit) < 0)
+ return true;
+
+ }
+
+ return false;
+
+}
+
+
+bool
+operator<(const sc_signed& u, long v)
+{
+
+ CONVERT_LONG(v);
+
+ if (u.sgn < vs)
+ return true;
+
+ if (u.sgn > vs)
+ return false;
+
+ // u.sgn == vs
+
+ if (vs == SC_POS) {
+
+ if (vec_skip_and_cmp(u.ndigits, u.digit, DIGITS_PER_LONG, vd) < 0)
+ return true;
+
+ }
+ else if (vs == SC_NEG) {
+
+ if (vec_skip_and_cmp(u.ndigits, u.digit, DIGITS_PER_LONG, vd) > 0)
+ return true;
+
+ }
+
+ return false;
+
+}
+
+
+bool
+operator<(long u, const sc_signed& v)
+{
+ CONVERT_LONG(u);
+
+ if (us < v.sgn)
+ return true;
+
+ if (us > v.sgn)
+ return false;
+
+ // us == v.sgn
+
+ if (us == SC_POS) {
+
+ if (vec_skip_and_cmp(DIGITS_PER_LONG, ud, v.ndigits, v.digit) < 0)
+ return true;
+
+ }
+ else if (us == SC_NEG) {
+
+ if (vec_skip_and_cmp(DIGITS_PER_LONG, ud, v.ndigits, v.digit) > 0)
+ return true;
+
+ }
+
+ return false;
+}
+
+
+bool
+operator<(const sc_signed& u, unsigned long v)
+{
+ CONVERT_LONG(v);
+
+ if (u.sgn < vs)
+ return true;
+
+ if (u.sgn > vs)
+ return false;
+
+ // u.sgn == vs
+
+ if (vs == SC_POS) {
+
+ if (vec_skip_and_cmp(u.ndigits, u.digit, DIGITS_PER_LONG, vd) < 0)
+ return true;
+
+ }
+
+ return false;
+}
+
+
+bool
+operator<(unsigned long u, const sc_signed& v)
+{
+ CONVERT_LONG(u);
+
+ if (us < v.sgn)
+ return true;
+
+ if (us > v.sgn)
+ return false;
+
+ // us == v.sgn
+
+ if (us == SC_POS) {
+
+ if (vec_skip_and_cmp(DIGITS_PER_LONG, ud, v.ndigits, v.digit) < 0)
+ return true;
+
+ }
+
+ return false;
+}
+
+
+// ---------------------------------------------------------------------------
+// SECTION: LESS THAN or EQUAL operator: <=
+// ---------------------------------------------------------------------------
+
+// Operators in this section are included from sc_nbcommon.cpp.
+
+
+// ---------------------------------------------------------------------------
+// SECTION: GREATER THAN operator: >
+// ---------------------------------------------------------------------------
+
+// Operators in this section are included from sc_nbcommon.cpp.
+
+
+// ---------------------------------------------------------------------------
+// SECTION: GREATER THAN or EQUAL operator: >=
+// ---------------------------------------------------------------------------
+
+// Operators in this section are included from sc_nbcommon.cpp.
+
+
+// ---------------------------------------------------------------------------
+// SECTION: Public members - Other utils.
+// ---------------------------------------------------------------------------
+
+bool
+sc_signed::iszero() const
+{
+ if (sgn == SC_ZERO)
+ return true;
+ else if (sgn != SC_NOSIGN)
+ return false;
+ else
+ return check_for_zero(ndigits, digit);
+}
+
+
+bool
+sc_signed::sign() const
+{
+ if (sgn == SC_NEG)
+ return 1;
+ else if (sgn != SC_NOSIGN)
+ return 0;
+ else
+ return ((digit[ndigits - 1] & one_and_zeros(bit_ord(nbits - 1))) != 0);
+}
+
+// The rest of the utils in this section are included from sc_nbcommon.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Private members.
+// ----------------------------------------------------------------------------
+
+// The private members in this section are included from sc_nbcommon.cpp.
+
+#define CLASS_TYPE sc_signed
+#define CLASS_TYPE_STR "sc_signed"
+
+#define ADD_HELPER add_signed_friend
+#define SUB_HELPER sub_signed_friend
+#define MUL_HELPER mul_signed_friend
+#define DIV_HELPER div_signed_friend
+#define MOD_HELPER mod_signed_friend
+#define AND_HELPER and_signed_friend
+#define OR_HELPER or_signed_friend
+#define XOR_HELPER xor_signed_friend
+
+#include "sc_nbfriends.inc"
+
+#undef SC_UNSIGNED
+#define SC_SIGNED
+#define IF_SC_SIGNED 1 // 1 = sc_signed
+#define CLASS_TYPE_SUBREF sc_signed_subref_r
+#define OTHER_CLASS_TYPE sc_unsigned
+#define OTHER_CLASS_TYPE_SUBREF sc_unsigned_subref_r
+
+#define MUL_ON_HELPER mul_on_help_signed
+#define DIV_ON_HELPER div_on_help_signed
+#define MOD_ON_HELPER mod_on_help_signed
+
+#include "sc_nbcommon.inc"
+
+#undef MOD_ON_HELPER
+#undef DIV_ON_HELPER
+#undef MUL_ON_HELPER
+
+#undef OTHER_CLASS_TYPE_SUBREF
+#undef OTHER_CLASS_TYPE
+#undef CLASS_TYPE_SUBREF
+#undef IF_SC_SIGNED
+#undef SC_SIGNED
+
+#undef XOR_HELPER
+#undef OR_HELPER
+#undef AND_HELPER
+#undef MOD_HELPER
+#undef DIV_HELPER
+#undef MUL_HELPER
+#undef SUB_HELPER
+#undef ADD_HELPER
+
+#undef CLASS_TYPE
+#undef CLASS_TYPE_STR
+
+#include "sc_signed_bitref.inc"
+#include "sc_signed_subref.inc"
+
+#undef CONVERT_LONG
+#undef CONVERT_LONG_2
+#undef CONVERT_INT64
+#undef CONVERT_INT64_2
+
+} // namespace sc_dt
+
+
+// End of file.
diff --git a/ext/systemc/src/sysc/datatypes/int/sc_signed.h b/ext/systemc/src/sysc/datatypes/int/sc_signed.h
new file mode 100644
index 000000000..8e2d4f541
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/int/sc_signed.h
@@ -0,0 +1,2382 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_signed.h -- Arbitrary precision signed arithmetic.
+
+ This file includes the definitions of sc_signed_bitref,
+ sc_signed_subref, and sc_signed classes. The first two classes are
+ proxy classes to reference one bit and a range of bits of a
+ sc_signed number, respectively.
+
+ An sc_signed number has the sign-magnitude representation
+ internally. However, its interface guarantees a 2's-complement
+ representation. The sign-magnitude representation is chosen
+ because of its efficiency: The sc_signed and sc_unsigned types are
+ optimized for arithmetic rather than bitwise operations. For
+ arithmetic operations, the sign-magnitude representation performs
+ better.
+
+ The implementations of sc_signed and sc_unsigned classes are
+ almost identical: Most of the member and friend functions are
+ defined in sc_nbcommon.cpp and sc_nbfriends.cpp so that they can
+ be shared by both of these classes. These functions are chosed by
+ defining a few macros before including them such as IF_SC_SIGNED
+ and CLASS_TYPE. Our implementation choices are mostly dictated by
+ performance considerations in that we tried to provide the most
+ efficient sc_signed and sc_unsigned types without compromising
+ their interface.
+
+ For the behavior of operators, we have two semantics: the old and
+ new. The most important difference between these two semantics is
+ that the old semantics is closer to C/C++ semantics in that the
+ result type of a binary operator on unsigned and signed arguments
+ is unsigned; the new semantics, on the other hand, requires the
+ result type be signed. The new semantics is required by the VSIA
+ C/C++ data types standard. We have implemented the new semantics.
+
+ Original Author: Ali Dasdan, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_signed.h,v $
+// Revision 1.3 2011/08/24 22:05:46 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.2 2011/02/18 20:19:15 acg
+// Andy Goodrich: updating Copyright notice.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.5 2006/05/08 17:50:01 acg
+// Andy Goodrich: Added David Long's declarations for friend operators,
+// functions, and methods, to keep the Microsoft compiler happy.
+//
+// Revision 1.4 2006/03/13 20:25:27 acg
+// Andy Goodrich: Addition of function declarations, e.g., xor_signed_friend()
+// to keep gcc 4.x happy.
+//
+// Revision 1.3 2006/01/13 18:49:32 acg
+// Added $Log command so that CVS check in comments are reproduced in the
+// source.
+//
+
+#ifndef SC_SIGNED_H
+#define SC_SIGNED_H
+
+
+#include "sysc/kernel/sc_object.h"
+#include "sysc/datatypes/misc/sc_value_base.h"
+#include "sysc/utils/sc_iostream.h"
+#include "sysc/utils/sc_temporary.h"
+#include "sysc/datatypes/int/sc_length_param.h"
+#include "sysc/datatypes/int/sc_nbdefs.h"
+#include "sysc/datatypes/int/sc_nbutils.h"
+#include "sysc/datatypes/int/sc_nbexterns.h"
+#include "sysc/datatypes/int/sc_unsigned.h"
+
+
+namespace sc_dt
+{
+
+// classes defined in this module
+class sc_signed_bitref_r;
+class sc_signed_bitref;
+class sc_signed_subref_r;
+class sc_signed_subref;
+class sc_concatref;
+class sc_signed;
+
+// forward class declarations
+class sc_bv_base;
+class sc_lv_base;
+class sc_int_base;
+class sc_uint_base;
+class sc_int_subref_r;
+class sc_uint_subref_r;
+class sc_signed;
+class sc_unsigned;
+class sc_unsigned_subref_r;
+class sc_fxval;
+class sc_fxval_fast;
+class sc_fxnum;
+class sc_fxnum_fast;
+
+
+// Helper function declarations
+sc_signed add_signed_friend(small_type us,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ small_type vs,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+sc_signed sub_signed_friend(small_type us,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ small_type vs,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+sc_signed mul_signed_friend(small_type s,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+sc_signed div_signed_friend(small_type s,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+sc_signed mod_signed_friend(small_type us,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+sc_signed and_signed_friend(small_type us,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ small_type vs,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+sc_signed or_signed_friend(small_type us,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ small_type vs,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+sc_signed xor_signed_friend(small_type us,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ small_type vs,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+
+// friend operator declarations
+ // ARITHMETIC OPERATORS:
+
+ // ADDition operators:
+
+ sc_signed operator + (const sc_unsigned& u, const sc_signed& v);
+ sc_signed operator + (const sc_signed& u, const sc_unsigned& v);
+
+ sc_signed operator + (const sc_unsigned& u, int64 v);
+ sc_signed operator + (const sc_unsigned& u, long v);
+ inline sc_signed operator + (const sc_unsigned& u, int v);
+
+ sc_signed operator + (int64 u, const sc_unsigned& v);
+ sc_signed operator + (long u, const sc_unsigned& v);
+ inline sc_signed operator + (int u, const sc_unsigned& v);
+
+ sc_signed operator + (const sc_signed& u, const sc_signed& v);
+ sc_signed operator + (const sc_signed& u, int64 v);
+ sc_signed operator + (const sc_signed& u, uint64 v);
+ sc_signed operator + (const sc_signed& u, long v);
+ sc_signed operator + (const sc_signed& u, unsigned long v);
+ inline sc_signed operator + (const sc_signed& u, int v);
+ inline sc_signed operator + (const sc_signed& u, unsigned int v);
+
+ sc_signed operator + (int64 u, const sc_signed& v);
+ sc_signed operator + (uint64 u, const sc_signed& v);
+ sc_signed operator + (long u, const sc_signed& v);
+ sc_signed operator + (unsigned long u, const sc_signed& v);
+ inline sc_signed operator + (int u, const sc_signed& v);
+ inline sc_signed operator + (unsigned int u, const sc_signed& v);
+
+ sc_signed operator + (const sc_unsigned& u, const sc_int_base& v);
+ sc_signed operator + (const sc_int_base& u, const sc_unsigned& v);
+ sc_signed operator + (const sc_signed& u, const sc_int_base& v);
+ sc_signed operator + (const sc_signed& u, const sc_uint_base& v);
+ sc_signed operator + (const sc_int_base& u, const sc_signed& v);
+ sc_signed operator + (const sc_uint_base& u, const sc_signed& v);
+
+
+
+ // SUBtraction operators:
+
+ sc_signed operator - (const sc_unsigned& u, const sc_signed& v);
+ sc_signed operator - (const sc_signed& u, const sc_unsigned& v);
+
+ sc_signed operator - (const sc_unsigned& u, const sc_unsigned& v);
+ sc_signed operator - (const sc_unsigned& u, int64 v);
+ sc_signed operator - (const sc_unsigned& u, uint64 v);
+ sc_signed operator - (const sc_unsigned& u, long v);
+ sc_signed operator - (const sc_unsigned& u, unsigned long v);
+ inline sc_signed operator - (const sc_unsigned& u, int v);
+ inline sc_signed operator - (const sc_unsigned& u, unsigned int v);
+
+ sc_signed operator - (int64 u, const sc_unsigned& v);
+ sc_signed operator - (uint64 u, const sc_unsigned& v);
+ sc_signed operator - (long u, const sc_unsigned& v);
+ sc_signed operator - (unsigned long u, const sc_unsigned& v);
+ inline sc_signed operator - (int u, const sc_unsigned& v);
+ inline sc_signed operator - (unsigned int u, const sc_unsigned& v);
+
+ sc_signed operator - (const sc_signed& u, const sc_signed& v);
+ sc_signed operator - (const sc_signed& u, int64 v);
+ sc_signed operator - (const sc_signed& u, uint64 v);
+ sc_signed operator - (const sc_signed& u, long v);
+ sc_signed operator - (const sc_signed& u, unsigned long v);
+ inline sc_signed operator - (const sc_signed& u, int v);
+ inline sc_signed operator - (const sc_signed& u, unsigned int v);
+
+ sc_signed operator - (int64 u, const sc_signed& v);
+ sc_signed operator - (uint64 u, const sc_signed& v);
+ sc_signed operator - (long u, const sc_signed& v);
+ sc_signed operator - (unsigned long u, const sc_signed& v);
+ inline sc_signed operator - (int u, const sc_signed& v);
+ inline sc_signed operator - (unsigned int u, const sc_signed& v);
+
+
+ sc_signed operator - (const sc_unsigned& u, const sc_int_base& v);
+ sc_signed operator - (const sc_unsigned& u, const sc_uint_base& v);
+ sc_signed operator - (const sc_int_base& u, const sc_unsigned& v);
+ sc_signed operator - (const sc_uint_base& u, const sc_unsigned& v);
+ sc_signed operator - (const sc_signed& u, const sc_int_base& v);
+ sc_signed operator - (const sc_signed& u, const sc_uint_base& v);
+ sc_signed operator - (const sc_int_base& u, const sc_signed& v);
+ sc_signed operator - (const sc_uint_base& u, const sc_signed& v);
+
+
+
+ // MULtiplication operators:
+
+ sc_signed operator * (const sc_unsigned& u, const sc_signed& v);
+ sc_signed operator * (const sc_signed& u, const sc_unsigned& v);
+
+ sc_signed operator * (const sc_unsigned& u, int64 v);
+ sc_signed operator * (const sc_unsigned& u, long v);
+ inline sc_signed operator * (const sc_unsigned& u, int v);
+
+ sc_signed operator * (int64 u, const sc_unsigned& v);
+ sc_signed operator * (long u, const sc_unsigned& v);
+ inline sc_signed operator * (int u, const sc_unsigned& v);
+
+ sc_signed operator * (const sc_signed& u, const sc_signed& v);
+ sc_signed operator * (const sc_signed& u, int64 v);
+ sc_signed operator * (const sc_signed& u, uint64 v);
+ sc_signed operator * (const sc_signed& u, long v);
+ sc_signed operator * (const sc_signed& u, unsigned long v);
+ inline sc_signed operator * (const sc_signed& u, int v);
+ inline sc_signed operator * (const sc_signed& u, unsigned int v);
+
+ sc_signed operator * (int64 u, const sc_signed& v);
+ sc_signed operator * (uint64 u, const sc_signed& v);
+ sc_signed operator * (long u, const sc_signed& v);
+ sc_signed operator * (unsigned long u, const sc_signed& v);
+ inline sc_signed operator * (int u, const sc_signed& v);
+ inline sc_signed operator * (unsigned int u, const sc_signed& v);
+
+ sc_signed operator * (const sc_unsigned& u, const sc_int_base& v);
+ sc_signed operator * (const sc_int_base& u, const sc_unsigned& v);
+ sc_signed operator * (const sc_signed& u, const sc_int_base& v);
+ sc_signed operator * (const sc_signed& u, const sc_uint_base& v);
+ sc_signed operator * (const sc_int_base& u, const sc_signed& v);
+ sc_signed operator * (const sc_uint_base& u, const sc_signed& v);
+
+
+
+ // DIVision operators:
+
+ sc_signed operator / (const sc_unsigned& u, const sc_signed& v);
+ sc_signed operator / (const sc_signed& u, const sc_unsigned& v);
+
+ sc_signed operator / (const sc_unsigned& u, int64 v);
+ sc_signed operator / (const sc_unsigned& u, long v);
+ inline sc_signed operator / (const sc_unsigned& u, int v);
+
+ sc_signed operator / (int64 u, const sc_unsigned& v);
+ sc_signed operator / (long u, const sc_unsigned& v);
+ inline sc_signed operator / (int u, const sc_unsigned& v);
+
+ sc_signed operator / (const sc_signed& u, const sc_signed& v);
+ sc_signed operator / (const sc_signed& u, int64 v);
+ sc_signed operator / (const sc_signed& u, uint64 v);
+ sc_signed operator / (const sc_signed& u, long v);
+ sc_signed operator / (const sc_signed& u, unsigned long v);
+ inline sc_signed operator / (const sc_signed& u, int v);
+ inline sc_signed operator / (const sc_signed& u, unsigned int v);
+
+ sc_signed operator / (int64 u, const sc_signed& v);
+ sc_signed operator / (uint64 u, const sc_signed& v);
+ sc_signed operator / (long u, const sc_signed& v);
+ sc_signed operator / (unsigned long u, const sc_signed& v);
+ inline sc_signed operator / (int u, const sc_signed& v);
+ inline sc_signed operator / (unsigned int u, const sc_signed& v);
+
+ sc_signed operator / (const sc_unsigned& u, const sc_int_base& v);
+ sc_signed operator / (const sc_int_base& u, const sc_unsigned& v);
+ sc_signed operator / (const sc_signed& u, const sc_int_base& v);
+ sc_signed operator / (const sc_signed& u, const sc_uint_base& v);
+ sc_signed operator / (const sc_int_base& u, const sc_signed& v);
+ sc_signed operator / (const sc_uint_base& u, const sc_signed& v);
+
+
+
+ // MODulo operators:
+
+ sc_signed operator % (const sc_unsigned& u, const sc_signed& v);
+ sc_signed operator % (const sc_signed& u, const sc_unsigned& v);
+
+ sc_signed operator % (const sc_unsigned& u, int64 v);
+ sc_signed operator % (const sc_unsigned& u, long v);
+ inline sc_signed operator % (const sc_unsigned& u, int v);
+
+ sc_signed operator % (int64 u, const sc_unsigned& v);
+ sc_signed operator % (long u, const sc_unsigned& v);
+ inline sc_signed operator % (int u, const sc_unsigned& v);
+
+ sc_signed operator % (const sc_signed& u, const sc_signed& v);
+ sc_signed operator % (const sc_signed& u, int64 v);
+ sc_signed operator % (const sc_signed& u, uint64 v);
+ sc_signed operator % (const sc_signed& u, long v);
+ sc_signed operator % (const sc_signed& u, unsigned long v);
+ inline sc_signed operator % (const sc_signed& u, int v);
+ inline sc_signed operator % (const sc_signed& u, unsigned int v);
+
+ sc_signed operator % (int64 u, const sc_signed& v);
+ sc_signed operator % (uint64 u, const sc_signed& v);
+ sc_signed operator % (long u, const sc_signed& v);
+ sc_signed operator % (unsigned long u, const sc_signed& v);
+ inline sc_signed operator % (int u, const sc_signed& v);
+ inline sc_signed operator % (unsigned int u, const sc_signed& v);
+
+ sc_signed operator % (const sc_unsigned& u, const sc_int_base& v);
+ sc_signed operator % (const sc_int_base& u, const sc_unsigned& v);
+ sc_signed operator % (const sc_signed& u, const sc_int_base& v);
+ sc_signed operator % (const sc_signed& u, const sc_uint_base& v);
+ sc_signed operator % (const sc_int_base& u, const sc_signed& v);
+ sc_signed operator % (const sc_uint_base& u, const sc_signed& v);
+
+
+
+ // BITWISE OPERATORS:
+
+ // Bitwise AND operators:
+
+ sc_signed operator & (const sc_unsigned& u, const sc_signed& v);
+ sc_signed operator & (const sc_signed& u, const sc_unsigned& v);
+
+ sc_signed operator & (const sc_unsigned& u, int64 v);
+ sc_signed operator & (const sc_unsigned& u, long v);
+ inline sc_signed operator & (const sc_unsigned& u, int v);
+
+ sc_signed operator & (int64 u, const sc_unsigned& v);
+ sc_signed operator & (long u, const sc_unsigned& v);
+ inline sc_signed operator & (int u, const sc_unsigned& v);
+
+ sc_signed operator & (const sc_signed& u, const sc_signed& v);
+ sc_signed operator & (const sc_signed& u, int64 v);
+ sc_signed operator & (const sc_signed& u, uint64 v);
+ sc_signed operator & (const sc_signed& u, long v);
+ sc_signed operator & (const sc_signed& u, unsigned long v);
+ inline sc_signed operator & (const sc_signed& u, int v);
+ inline sc_signed operator & (const sc_signed& u, unsigned int v);
+
+ sc_signed operator & (int64 u, const sc_signed& v);
+ sc_signed operator & (uint64 u, const sc_signed& v);
+ sc_signed operator & (long u, const sc_signed& v);
+ sc_signed operator & (unsigned long u, const sc_signed& v);
+ inline sc_signed operator & (int u, const sc_signed& v);
+ inline sc_signed operator & (unsigned int u, const sc_signed& v);
+
+ sc_signed operator & (const sc_unsigned& u, const sc_int_base& v);
+ sc_signed operator & (const sc_int_base& u, const sc_unsigned& v);
+ sc_signed operator & (const sc_signed& u, const sc_int_base& v);
+ sc_signed operator & (const sc_signed& u, const sc_uint_base& v);
+ sc_signed operator & (const sc_int_base& u, const sc_signed& v);
+ sc_signed operator & (const sc_uint_base& u, const sc_signed& v);
+
+
+
+ // Bitwise OR operators:
+
+ sc_signed operator | (const sc_unsigned& u, const sc_signed& v);
+ sc_signed operator | (const sc_signed& u, const sc_unsigned& v);
+
+ sc_signed operator | (const sc_unsigned& u, int64 v);
+ sc_signed operator | (const sc_unsigned& u, long v);
+ inline sc_signed operator | (const sc_unsigned& u, int v);
+
+ sc_signed operator | (int64 u, const sc_unsigned& v);
+ sc_signed operator | (long u, const sc_unsigned& v);
+ inline sc_signed operator | (int u, const sc_unsigned& v);
+
+ sc_signed operator | (const sc_signed& u, const sc_signed& v);
+ sc_signed operator | (const sc_signed& u, int64 v);
+ sc_signed operator | (const sc_signed& u, uint64 v);
+ sc_signed operator | (const sc_signed& u, long v);
+ sc_signed operator | (const sc_signed& u, unsigned long v);
+ inline sc_signed operator | (const sc_signed& u, int v);
+ inline sc_signed operator | (const sc_signed& u, unsigned int v);
+
+ sc_signed operator | (int64 u, const sc_signed& v);
+ sc_signed operator | (uint64 u, const sc_signed& v);
+ sc_signed operator | (long u, const sc_signed& v);
+ sc_signed operator | (unsigned long u, const sc_signed& v);
+ inline sc_signed operator | (int u, const sc_signed& v);
+ inline sc_signed operator | (unsigned int u, const sc_signed& v);
+
+ sc_signed operator | (const sc_unsigned& u, const sc_int_base& v);
+ sc_signed operator | (const sc_int_base& u, const sc_unsigned& v);
+ sc_signed operator | (const sc_signed& u, const sc_int_base& v);
+ sc_signed operator | (const sc_signed& u, const sc_uint_base& v);
+ sc_signed operator | (const sc_int_base& u, const sc_signed& v);
+ sc_signed operator | (const sc_uint_base& u, const sc_signed& v);
+
+
+
+ // Bitwise XOR operators:
+
+ sc_signed operator ^ (const sc_unsigned& u, const sc_signed& v);
+ sc_signed operator ^ (const sc_signed& u, const sc_unsigned& v);
+
+ sc_signed operator ^ (const sc_unsigned& u, int64 v);
+ sc_signed operator ^ (const sc_unsigned& u, long v);
+ inline sc_signed operator ^ (const sc_unsigned& u, int v);
+
+ sc_signed operator ^ (int64 u, const sc_unsigned& v);
+ sc_signed operator ^ (long u, const sc_unsigned& v);
+ inline sc_signed operator ^ (int u, const sc_unsigned& v);
+
+ sc_signed operator ^ (const sc_signed& u, const sc_signed& v);
+ sc_signed operator ^ (const sc_signed& u, int64 v);
+ sc_signed operator ^ (const sc_signed& u, uint64 v);
+ sc_signed operator ^ (const sc_signed& u, long v);
+ sc_signed operator ^ (const sc_signed& u, unsigned long v);
+ inline sc_signed operator ^ (const sc_signed& u, int v);
+ inline sc_signed operator ^ (const sc_signed& u, unsigned int v);
+
+ sc_signed operator ^ (int64 u, const sc_signed& v);
+ sc_signed operator ^ (uint64 u, const sc_signed& v);
+ sc_signed operator ^ (long u, const sc_signed& v);
+ sc_signed operator ^ (unsigned long u, const sc_signed& v);
+ inline sc_signed operator ^ (int u, const sc_signed& v);
+ inline sc_signed operator ^ (unsigned int u, const sc_signed& v);
+
+ sc_signed operator ^ (const sc_unsigned& u, const sc_int_base& v);
+ sc_signed operator ^ (const sc_int_base& u, const sc_unsigned& v);
+ sc_signed operator ^ (const sc_signed& u, const sc_int_base& v);
+ sc_signed operator ^ (const sc_signed& u, const sc_uint_base& v);
+ sc_signed operator ^ (const sc_int_base& u, const sc_signed& v);
+ sc_signed operator ^ (const sc_uint_base& u, const sc_signed& v);
+
+
+
+ // SHIFT OPERATORS:
+
+ // LEFT SHIFT operators:
+
+ sc_unsigned operator << (const sc_unsigned& u, const sc_signed& v);
+ sc_signed operator << (const sc_signed& u, const sc_unsigned& v);
+
+ sc_signed operator << (const sc_signed& u, const sc_signed& v);
+ sc_signed operator << (const sc_signed& u, int64 v);
+ sc_signed operator << (const sc_signed& u, uint64 v);
+ sc_signed operator << (const sc_signed& u, long v);
+ sc_signed operator << (const sc_signed& u, unsigned long v);
+ inline sc_signed operator << (const sc_signed& u, int v);
+ inline sc_signed operator << (const sc_signed& u, unsigned int v);
+
+ sc_signed operator << (const sc_signed& u, const sc_int_base& v);
+ sc_signed operator << (const sc_signed& u, const sc_uint_base& v);
+
+
+
+ // RIGHT SHIFT operators:
+
+ sc_unsigned operator >> (const sc_unsigned& u, const sc_signed& v);
+ sc_signed operator >> (const sc_signed& u, const sc_unsigned& v);
+
+ sc_signed operator >> (const sc_signed& u, const sc_signed& v);
+ sc_signed operator >> (const sc_signed& u, int64 v);
+ sc_signed operator >> (const sc_signed& u, uint64 v);
+ sc_signed operator >> (const sc_signed& u, long v);
+ sc_signed operator >> (const sc_signed& u, unsigned long v);
+ inline sc_signed operator >> (const sc_signed& u, int v);
+ inline sc_signed operator >> (const sc_signed& u, unsigned int v);
+
+ sc_signed operator >> (const sc_signed& u, const sc_int_base& v);
+ sc_signed operator >> (const sc_signed& u, const sc_uint_base& v);
+
+
+
+ // Unary arithmetic operators
+ sc_signed operator + (const sc_signed& u);
+ sc_signed operator - (const sc_signed& u);
+ sc_signed operator - (const sc_unsigned& u);
+
+ // LOGICAL OPERATORS:
+
+ // Logical EQUAL operators:
+
+ bool operator == (const sc_unsigned& u, const sc_signed& v);
+ bool operator == (const sc_signed& u, const sc_unsigned& v);
+
+ bool operator == (const sc_signed& u, const sc_signed& v);
+ bool operator == (const sc_signed& u, int64 v);
+ bool operator == (const sc_signed& u, uint64 v);
+ bool operator == (const sc_signed& u, long v);
+ bool operator == (const sc_signed& u, unsigned long v);
+ inline bool operator == (const sc_signed& u, int v);
+ inline bool operator == (const sc_signed& u, unsigned int v);
+
+ bool operator == (int64 u, const sc_signed& v);
+ bool operator == (uint64 u, const sc_signed& v);
+ bool operator == (long u, const sc_signed& v);
+ bool operator == (unsigned long u, const sc_signed& v);
+ inline bool operator == (int u, const sc_signed& v);
+ inline bool operator == (unsigned int u, const sc_signed& v);
+
+ bool operator == (const sc_signed& u, const sc_int_base& v);
+ bool operator == (const sc_signed& u, const sc_uint_base& v);
+ bool operator == (const sc_int_base& u, const sc_signed& v);
+ bool operator == (const sc_uint_base& u, const sc_signed& v);
+
+ // Logical NOT_EQUAL operators:
+
+ bool operator != (const sc_unsigned& u, const sc_signed& v);
+ bool operator != (const sc_signed& u, const sc_unsigned& v);
+
+ bool operator != (const sc_signed& u, const sc_signed& v);
+ bool operator != (const sc_signed& u, int64 v);
+ bool operator != (const sc_signed& u, uint64 v);
+ bool operator != (const sc_signed& u, long v);
+ bool operator != (const sc_signed& u, unsigned long v);
+ inline bool operator != (const sc_signed& u, int v);
+ inline bool operator != (const sc_signed& u, unsigned int v);
+
+ bool operator != (int64 u, const sc_signed& v);
+ bool operator != (uint64 u, const sc_signed& v);
+ bool operator != (long u, const sc_signed& v);
+ bool operator != (unsigned long u, const sc_signed& v);
+ inline bool operator != (int u, const sc_signed& v);
+ inline bool operator != (unsigned int u, const sc_signed& v);
+
+ bool operator != (const sc_signed& u, const sc_int_base& v);
+ bool operator != (const sc_signed& u, const sc_uint_base& v);
+ bool operator != (const sc_int_base& u, const sc_signed& v);
+ bool operator != (const sc_uint_base& u, const sc_signed& v);
+
+ // Logical LESS_THAN operators:
+
+ bool operator < (const sc_unsigned& u, const sc_signed& v);
+ bool operator < (const sc_signed& u, const sc_unsigned& v);
+
+ bool operator < (const sc_signed& u, const sc_signed& v);
+ bool operator < (const sc_signed& u, int64 v);
+ bool operator < (const sc_signed& u, uint64 v);
+ bool operator < (const sc_signed& u, long v);
+ bool operator < (const sc_signed& u, unsigned long v);
+ inline bool operator < (const sc_signed& u, int v);
+ inline bool operator < (const sc_signed& u, unsigned int v);
+
+ bool operator < (int64 u, const sc_signed& v);
+ bool operator < (uint64 u, const sc_signed& v);
+ bool operator < (long u, const sc_signed& v);
+ bool operator < (unsigned long u, const sc_signed& v);
+ inline bool operator < (int u, const sc_signed& v);
+ inline bool operator < (unsigned int u, const sc_signed& v);
+
+ bool operator < (const sc_signed& u, const sc_int_base& v);
+ bool operator < (const sc_signed& u, const sc_uint_base& v);
+ bool operator < (const sc_int_base& u, const sc_signed& v);
+ bool operator < (const sc_uint_base& u, const sc_signed& v);
+
+ // Logical LESS_THAN_AND_EQUAL operators:
+
+ bool operator <= (const sc_unsigned& u, const sc_signed& v);
+ bool operator <= (const sc_signed& u, const sc_unsigned& v);
+
+ bool operator <= (const sc_signed& u, const sc_signed& v);
+ bool operator <= (const sc_signed& u, int64 v);
+ bool operator <= (const sc_signed& u, uint64 v);
+ bool operator <= (const sc_signed& u, long v);
+ bool operator <= (const sc_signed& u, unsigned long v);
+ inline bool operator <= (const sc_signed& u, int v);
+ inline bool operator <= (const sc_signed& u, unsigned int v);
+
+ bool operator <= (int64 u, const sc_signed& v);
+ bool operator <= (uint64 u, const sc_signed& v);
+ bool operator <= (long u, const sc_signed& v);
+ bool operator <= (unsigned long u, const sc_signed& v);
+ inline bool operator <= (int u, const sc_signed& v);
+ inline bool operator <= (unsigned int u, const sc_signed& v);
+
+ bool operator <= (const sc_signed& u, const sc_int_base& v);
+ bool operator <= (const sc_signed& u, const sc_uint_base& v);
+ bool operator <= (const sc_int_base& u, const sc_signed& v);
+ bool operator <= (const sc_uint_base& u, const sc_signed& v);
+
+ // Logical GREATER_THAN operators:
+
+ bool operator > (const sc_unsigned& u, const sc_signed& v);
+ bool operator > (const sc_signed& u, const sc_unsigned& v);
+
+ bool operator > (const sc_signed& u, const sc_signed& v);
+ bool operator > (const sc_signed& u, int64 v);
+ bool operator > (const sc_signed& u, uint64 v);
+ bool operator > (const sc_signed& u, long v);
+ bool operator > (const sc_signed& u, unsigned long v);
+ inline bool operator > (const sc_signed& u, int v);
+ inline bool operator > (const sc_signed& u, unsigned int v);
+
+ bool operator > (int64 u, const sc_signed& v);
+ bool operator > (uint64 u, const sc_signed& v);
+ bool operator > (long u, const sc_signed& v);
+ bool operator > (unsigned long u, const sc_signed& v);
+ inline bool operator > (int u, const sc_signed& v);
+ inline bool operator > (unsigned int u, const sc_signed& v);
+
+ bool operator > (const sc_signed& u, const sc_int_base& v);
+ bool operator > (const sc_signed& u, const sc_uint_base& v);
+ bool operator > (const sc_int_base& u, const sc_signed& v);
+ bool operator > (const sc_uint_base& u, const sc_signed& v);
+
+ // Logical GREATER_THAN_AND_EQUAL operators:
+
+ bool operator >= (const sc_unsigned& u, const sc_signed& v);
+ bool operator >= (const sc_signed& u, const sc_unsigned& v);
+
+ bool operator >= (const sc_signed& u, const sc_signed& v);
+ bool operator >= (const sc_signed& u, int64 v);
+ bool operator >= (const sc_signed& u, uint64 v);
+ bool operator >= (const sc_signed& u, long v);
+ bool operator >= (const sc_signed& u, unsigned long v);
+ inline bool operator >= (const sc_signed& u, int v);
+ inline bool operator >= (const sc_signed& u, unsigned int v);
+
+ bool operator >= (int64 u, const sc_signed& v);
+ bool operator >= (uint64 u, const sc_signed& v);
+ bool operator >= (long u, const sc_signed& v);
+ bool operator >= (unsigned long u, const sc_signed& v);
+ inline bool operator >= (int u, const sc_signed& v);
+ inline bool operator >= (unsigned int u, const sc_signed& v);
+
+ bool operator >= (const sc_signed& u, const sc_int_base& v);
+ bool operator >= (const sc_signed& u, const sc_uint_base& v);
+ bool operator >= (const sc_int_base& u, const sc_signed& v);
+ bool operator >= (const sc_uint_base& u, const sc_signed& v);
+
+ // Bitwise NOT operator (unary).
+ sc_signed operator ~ (const sc_signed& u);
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_signed_bitref_r
+//
+// Proxy class for sc_signed bit selection (r-value only).
+// ----------------------------------------------------------------------------
+
+class sc_signed_bitref_r : public sc_value_base
+{
+ friend class sc_signed;
+
+protected:
+
+ // constructor
+
+ sc_signed_bitref_r() : sc_value_base(), m_index(0), m_obj_p(0)
+ {}
+
+ void initialize( const sc_signed* obj_p, int index_ )
+ {
+ m_index = index_;
+ m_obj_p = ( CCAST<sc_signed*>( obj_p ) );
+ }
+
+public:
+
+ // destructor
+
+ virtual ~sc_signed_bitref_r()
+ {}
+
+ // copy constructor
+
+ sc_signed_bitref_r( const sc_signed_bitref_r& a )
+ : sc_value_base(a), m_index( a.m_index ), m_obj_p( a.m_obj_p )
+ {}
+
+ // capacity
+
+ int length() const
+ { return 1; }
+
+
+ // implicit conversion to bool
+
+ operator uint64 () const;
+ bool operator ! () const;
+ bool operator ~ () const;
+
+
+ // explicit conversions
+
+ bool value() const
+ { return operator uint64(); }
+
+ bool to_bool() const
+ { return operator uint64(); }
+
+ // concatenation support
+
+ virtual int concat_length(bool* xz_present_p) const
+ { if ( xz_present_p ) *xz_present_p = false; return 1; }
+ virtual uint64 concat_get_uint64() const
+ { return (uint64)operator uint64(); }
+ virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const
+ {
+ int bit_mask = 1 << (low_i % BITS_PER_DIGIT);
+ int word_i = low_i / BITS_PER_DIGIT;
+ dst_p[word_i] &= ~bit_mask;
+ return false;
+ }
+ virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const
+ {
+ int bit_mask = 1 << (low_i % BITS_PER_DIGIT);
+ bool result; // True if non-zero.
+ int word_i = low_i / BITS_PER_DIGIT;
+ if ( operator uint64() )
+ {
+ dst_p[word_i] |= bit_mask;
+ result = true;
+ }
+ else
+ {
+ dst_p[word_i] &= ~bit_mask;
+ result = false;
+ }
+ return result;
+ }
+
+
+ // other methods
+
+ void print( ::std::ostream& os = ::std::cout ) const
+ { os << to_bool(); }
+
+protected:
+
+ int m_index; // Bit to be selected.
+ sc_signed* m_obj_p; // Target of this bit selection.
+
+private:
+
+ // disabled
+ const sc_signed_bitref_r& operator = ( const sc_signed_bitref_r& );
+};
+
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream&, const sc_signed_bitref_r& );
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_signed_bitref
+//
+// Proxy class for sc_signed bit selection (r-value and l-value).
+// ----------------------------------------------------------------------------
+
+class sc_signed_bitref
+ : public sc_signed_bitref_r
+{
+ friend class sc_signed;
+ friend class sc_core::sc_vpool<sc_signed_bitref>;
+
+
+ // constructor
+
+protected:
+
+ sc_signed_bitref() : sc_signed_bitref_r()
+ {}
+
+public:
+
+ // copy constructor
+
+ sc_signed_bitref( const sc_signed_bitref& a )
+ : sc_signed_bitref_r( a )
+ {}
+
+ // assignment operators
+
+ const sc_signed_bitref& operator = ( const sc_signed_bitref_r& );
+ const sc_signed_bitref& operator = ( const sc_signed_bitref& );
+ const sc_signed_bitref& operator = ( bool );
+
+ const sc_signed_bitref& operator &= ( bool );
+ const sc_signed_bitref& operator |= ( bool );
+ const sc_signed_bitref& operator ^= ( bool );
+
+ // concatenation methods
+
+ virtual void concat_set(int64 src, int low_i);
+ virtual void concat_set(const sc_signed& src, int low_i);
+ virtual void concat_set(const sc_unsigned& src, int low_i);
+ virtual void concat_set(uint64 src, int low_i);
+
+
+ // other methods
+
+ void scan( ::std::istream& is = ::std::cin );
+
+protected:
+ static sc_core::sc_vpool<sc_signed_bitref> m_pool;
+};
+
+
+
+inline
+::std::istream&
+operator >> ( ::std::istream&, sc_signed_bitref& );
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_signed_subref_r
+//
+// Proxy class for sc_signed part selection (r-value only).
+// ----------------------------------------------------------------------------
+
+class sc_signed_subref_r : public sc_value_base
+{
+ friend class sc_signed;
+ friend class sc_signed_signal;
+ friend class sc_unsigned;
+
+protected:
+
+ // constructor
+
+ sc_signed_subref_r() : sc_value_base(), m_left(0), m_obj_p(0), m_right(0)
+ {}
+
+ void initialize( const sc_signed* obj_p, int left_, int right_ )
+ {
+ m_obj_p = ( CCAST<sc_signed*>( obj_p ));
+ m_left = left_;
+ m_right = right_;
+ }
+
+
+public:
+
+ // destructor
+
+ virtual ~sc_signed_subref_r()
+ {}
+
+ // copy constructor
+
+ sc_signed_subref_r( const sc_signed_subref_r& a )
+ : sc_value_base(a), m_left( a.m_left ), m_obj_p( a.m_obj_p ),
+ m_right( a.m_right )
+ {}
+
+
+ // capacity
+
+ int length() const
+ { return m_left >= m_right ? (m_left-m_right+1) : (m_right-m_left+1 ); }
+
+
+ // implicit conversion to sc_unsigned
+
+ operator sc_unsigned () const;
+
+
+ // explicit conversions
+
+ int to_int() const;
+ unsigned int to_uint() const;
+ long to_long() const;
+ unsigned long to_ulong() const;
+ int64 to_int64() const;
+ uint64 to_uint64() const;
+ double to_double() const;
+
+
+ // explicit conversion to character string
+
+ const std::string to_string( sc_numrep numrep = SC_DEC ) const;
+ const std::string to_string( sc_numrep numrep, bool w_prefix ) const;
+
+ // concatenation support
+
+ virtual int concat_length(bool* xz_present_p) const
+ {
+ if ( xz_present_p ) *xz_present_p = false;
+ return m_left - m_right + 1;
+ }
+ virtual uint64 concat_get_uint64() const;
+ virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const;
+ virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const;
+
+ // reduce methods
+
+ bool and_reduce() const;
+ bool nand_reduce() const;
+ bool or_reduce() const;
+ bool nor_reduce() const;
+ bool xor_reduce() const ;
+ bool xnor_reduce() const;
+
+
+ // other methods
+
+ void print( ::std::ostream& os = ::std::cout ) const
+ { os << to_string(sc_io_base(os,SC_DEC),sc_io_show_base(os)); }
+
+protected:
+
+ int m_left; // Left-most bit in this part selection.
+ sc_signed* m_obj_p; // Target of this part selection.
+ int m_right; // Right-most bit in this part selection.
+
+private:
+ const sc_signed_subref_r& operator = ( const sc_signed_subref_r& );
+
+};
+
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream&, const sc_signed_subref_r& );
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_signed_subref
+//
+// Proxy class for sc_signed part selection (r-value and l-value).
+// ----------------------------------------------------------------------------
+
+class sc_signed_subref
+ : public sc_signed_subref_r
+{
+ friend class sc_signed;
+ friend class sc_core::sc_vpool<sc_signed_subref>;
+
+
+ // constructor
+
+ sc_signed_subref() : sc_signed_subref_r()
+ {}
+
+public:
+
+ // copy constructor
+
+ sc_signed_subref( const sc_signed_subref& a )
+ : sc_signed_subref_r( a )
+ {}
+
+
+ // assignment operators
+
+ const sc_signed_subref& operator = ( const sc_signed_subref_r& a );
+ const sc_signed_subref& operator = ( const sc_signed_subref& a );
+ const sc_signed_subref& operator = ( const sc_signed& a );
+
+ const sc_signed_subref& operator = ( const sc_unsigned_subref_r& a );
+ const sc_signed_subref& operator = ( const sc_unsigned& a );
+
+ template< class T >
+ const sc_signed_subref& operator = ( const sc_generic_base<T>& a )
+ {
+ sc_unsigned temp( length() );
+ a->to_sc_unsigned(temp);
+ return operator = (temp);
+ }
+
+ const sc_signed_subref& operator = ( const char* a );
+ const sc_signed_subref& operator = ( unsigned long a );
+ const sc_signed_subref& operator = ( long a );
+ const sc_signed_subref& operator = ( unsigned int a )
+ { return operator = ( (unsigned long) a ); }
+
+ const sc_signed_subref& operator = ( int a )
+ { return operator = ( (long) a ); }
+
+ const sc_signed_subref& operator = ( uint64 a );
+ const sc_signed_subref& operator = ( int64 a );
+ const sc_signed_subref& operator = ( double a );
+ const sc_signed_subref& operator = ( const sc_int_base& a );
+ const sc_signed_subref& operator = ( const sc_uint_base& a );
+
+ // concatenation methods
+
+ virtual void concat_set(int64 src, int low_i);
+ virtual void concat_set(const sc_signed& src, int low_i);
+ virtual void concat_set(const sc_unsigned& src, int low_i);
+ virtual void concat_set(uint64 src, int low_i);
+
+ // other methods
+
+ void scan( ::std::istream& is = ::std::cin );
+
+protected:
+ static sc_core::sc_vpool<sc_signed_subref> m_pool;
+};
+
+
+
+inline
+::std::istream&
+operator >> ( ::std::istream&, sc_signed_subref& );
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_signed
+//
+// Arbitrary precision signed number.
+// ----------------------------------------------------------------------------
+
+class sc_signed : public sc_value_base
+{
+ friend class sc_concatref;
+ friend class sc_signed_bitref_r;
+ friend class sc_signed_bitref;
+ friend class sc_signed_subref_r;
+ friend class sc_signed_subref;
+ friend class sc_unsigned;
+ friend class sc_unsigned_subref;
+
+ // Needed for types using sc_signed.
+ typedef bool elemtype;
+
+public:
+
+ // constructors
+
+ explicit sc_signed( int nb = sc_length_param().len() );
+ sc_signed( const sc_signed& v );
+ sc_signed( const sc_unsigned& v );
+ template<class T>
+ explicit sc_signed( const sc_generic_base<T>& v );
+ explicit sc_signed( const sc_bv_base& v );
+ explicit sc_signed( const sc_lv_base& v );
+ explicit sc_signed( const sc_int_subref_r& v );
+ explicit sc_signed( const sc_uint_subref_r& v );
+ explicit sc_signed( const sc_signed_subref_r& v );
+ explicit sc_signed( const sc_unsigned_subref_r& v );
+
+ // assignment operators
+
+ const sc_signed& operator = (const sc_signed& v);
+ const sc_signed& operator = (const sc_signed_subref_r& a );
+
+ template< class T >
+ const sc_signed& operator = ( const sc_generic_base<T>& a )
+ { a->to_sc_signed(*this); return *this; }
+
+ const sc_signed& operator = (const sc_unsigned& v);
+ const sc_signed& operator = (const sc_unsigned_subref_r& a );
+
+ const sc_signed& operator = (const char* v);
+ const sc_signed& operator = (int64 v);
+ const sc_signed& operator = (uint64 v);
+ const sc_signed& operator = (long v);
+ const sc_signed& operator = (unsigned long v);
+
+ const sc_signed& operator = (int v)
+ { return operator=((long) v); }
+
+ const sc_signed& operator = (unsigned int v)
+ { return operator=((unsigned long) v); }
+
+ const sc_signed& operator = (double v);
+ const sc_signed& operator = (const sc_int_base& v);
+ const sc_signed& operator = (const sc_uint_base& v);
+
+ const sc_signed& operator = ( const sc_bv_base& );
+ const sc_signed& operator = ( const sc_lv_base& );
+
+#ifdef SC_INCLUDE_FX
+ const sc_signed& operator = ( const sc_fxval& );
+ const sc_signed& operator = ( const sc_fxval_fast& );
+ const sc_signed& operator = ( const sc_fxnum& );
+ const sc_signed& operator = ( const sc_fxnum_fast& );
+#endif
+
+
+ // destructor
+
+ virtual ~sc_signed()
+ {
+#ifndef SC_MAX_NBITS
+ delete [] digit;
+#endif
+ }
+
+ // Concatenation support:
+
+ sc_digit* get_raw() const
+ { return digit; }
+ virtual int concat_length(bool* xz_present_p) const
+ { if ( xz_present_p ) *xz_present_p = false; return nbits; }
+ virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const;
+ virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const;
+ virtual uint64 concat_get_uint64() const;
+ virtual void concat_set(int64 src, int low_i);
+ virtual void concat_set(const sc_signed& src, int low_i);
+ virtual void concat_set(const sc_unsigned& src, int low_i);
+ virtual void concat_set(uint64 src, int low_i);
+
+
+
+ // Increment operators.
+ sc_signed& operator ++ ();
+ const sc_signed operator ++ (int);
+
+ // Decrement operators.
+ sc_signed& operator -- ();
+ const sc_signed operator -- (int);
+
+
+ // bit selection
+
+ inline void check_index( int i ) const
+ { if ( i < 0 || i >= nbits ) invalid_index(i); }
+
+ void invalid_index( int i ) const;
+
+ sc_signed_bitref& operator [] ( int i )
+ {
+ check_index(i);
+ sc_signed_bitref* result_p =
+ sc_signed_bitref::m_pool.allocate();
+ result_p->initialize( this, i );
+ return *result_p;
+ }
+
+ const sc_signed_bitref_r& operator [] ( int i ) const
+ {
+ check_index(i);
+ sc_signed_bitref* result_p =
+ sc_signed_bitref::m_pool.allocate();
+ result_p->initialize( this, i );
+ return *result_p;
+ }
+
+ sc_signed_bitref& bit( int i )
+ {
+ check_index(i);
+ sc_signed_bitref* result_p =
+ sc_signed_bitref::m_pool.allocate();
+ result_p->initialize( this, i );
+ return *result_p;
+ }
+
+ const sc_signed_bitref_r& bit( int i ) const
+ {
+ check_index(i);
+ sc_signed_bitref* result_p =
+ sc_signed_bitref::m_pool.allocate();
+ result_p->initialize( this, i );
+ return *result_p;
+ }
+
+
+ // part selection
+
+ // Subref operators. Help access the range of bits from the ith to
+ // jth. These indices have arbitrary precedence with respect to each
+ // other, i.e., we can have i <= j or i > j. Note the equivalence
+ // between range(i, j) and operator(i, j). Also note that
+ // operator(i, i) returns a signed number that corresponds to the
+ // bit operator[i], so these two forms are not the same.
+
+ inline void check_range( int l, int r ) const
+ {
+ if ( l < r )
+ {
+ if ( l < 0 || r >= nbits ) invalid_range(l,r);
+ }
+ else
+ {
+ if ( r < 0 || l >= nbits ) invalid_range(l,r);
+ }
+ }
+
+ void invalid_range( int l, int r ) const;
+
+ sc_signed_subref& range( int i, int j )
+ {
+ check_range( i, j );
+ sc_signed_subref* result_p =
+ sc_signed_subref::m_pool.allocate();
+ result_p->initialize( this, i, j );
+ return *result_p;
+ }
+
+ const sc_signed_subref_r& range( int i, int j ) const
+ {
+ check_range( i, j );
+ sc_signed_subref* result_p =
+ sc_signed_subref::m_pool.allocate();
+ result_p->initialize( this, i, j );
+ return *result_p;
+ }
+
+ sc_signed_subref& operator () ( int i, int j )
+ {
+ check_range( i, j );
+ sc_signed_subref* result_p =
+ sc_signed_subref::m_pool.allocate();
+ result_p->initialize( this, i, j );
+ return *result_p;
+ }
+
+ const sc_signed_subref_r& operator () ( int i, int j ) const
+ {
+ check_range( i, j );
+ sc_signed_subref* result_p =
+ sc_signed_subref::m_pool.allocate();
+ result_p->initialize( this, i, j );
+ return *result_p;
+ }
+
+
+ // explicit conversions
+
+ int to_int() const;
+ unsigned int to_uint() const;
+ long to_long() const;
+ unsigned long to_ulong() const;
+ int64 to_int64() const;
+ uint64 to_uint64() const;
+ double to_double() const;
+
+#ifdef SC_DT_DEPRECATED
+ int to_signed() const
+ { return to_int(); }
+
+ unsigned int to_unsigned() const
+ { return to_uint(); }
+#endif
+
+ // explicit conversion to character string
+
+ const std::string to_string( sc_numrep numrep = SC_DEC ) const;
+ const std::string to_string( sc_numrep numrep, bool w_prefix ) const;
+
+
+ // Print functions. dump prints the internals of the class.
+
+ void print( ::std::ostream& os = ::std::cout ) const
+ { os << to_string(sc_io_base(os,SC_DEC),sc_io_show_base(os)); }
+
+ void scan( ::std::istream& is = ::std::cin );
+
+ void dump( ::std::ostream& os = ::std::cout ) const;
+
+
+ // Functions to find various properties.
+ int length() const { return nbits; } // Bit width.
+ bool iszero() const; // Is the number zero?
+ bool sign() const; // Sign.
+
+ // reduce methods
+
+ bool and_reduce() const;
+
+ bool nand_reduce() const
+ { return ( ! and_reduce() ); }
+
+ bool or_reduce() const;
+
+ bool nor_reduce() const
+ { return ( ! or_reduce() ); }
+
+ bool xor_reduce() const;
+
+ bool xnor_reduce() const
+ { return ( ! xor_reduce() ); }
+
+ // Functions to access individual bits.
+ bool test(int i) const; // Is the ith bit 0 or 1?
+ void set(int i); // Set the ith bit to 1.
+ void clear(int i); // Set the ith bit to 0.
+ void set(int i, bool v) // Set the ith bit to v.
+ { if (v) set(i); else clear(i); }
+ void invert(int i) // Negate the ith bit.
+ { if (test(i)) clear(i); else set(i); }
+
+ // Make the number equal to its mirror image.
+ void reverse();
+
+ // Get/set a packed bit representation of the number.
+ void get_packed_rep(sc_digit *buf) const;
+ void set_packed_rep(sc_digit *buf);
+
+ /*
+ The comparison of the old and new semantics are as follows:
+
+ Let s = sc_signed,
+ u = sc_unsigned,
+ un = { uint64, unsigned long, unsigned int },
+ sn = { int64, long, int, char* }, and
+ OP = { +, -, *, /, % }.
+
+ Old semantics: New semantics:
+ u OP u -> u u OP u -> u
+ s OP u -> u s OP u -> s
+ u OP s -> u u OP s -> s
+ s OP s -> s s OP s -> s
+
+ u OP un = un OP u -> u u OP un = un OP u -> u
+ u OP sn = sn OP u -> u u OP sn = sn OP u -> s
+
+ s OP un = un OP s -> s s OP un = un OP s -> s
+ s OP sn = sn OP s -> s s OP sn = sn OP s -> s
+
+ In the new semantics, the result is u if both operands are u; the
+ result is s otherwise. The only exception is subtraction. The result
+ of a subtraction is always s.
+
+ The old semantics is like C/C++ semantics on integer types; the
+ new semantics is due to the VSIA C/C++ data types standard.
+ */
+
+ // ARITHMETIC OPERATORS:
+
+ // ADDition operators:
+
+ friend sc_signed operator + (const sc_unsigned& u, const sc_signed& v);
+ friend sc_signed operator + (const sc_signed& u, const sc_unsigned& v);
+
+ friend sc_signed operator + (const sc_unsigned& u, int64 v);
+ friend sc_signed operator + (const sc_unsigned& u, long v);
+ friend sc_signed operator + (const sc_unsigned& u, int v)
+ { return operator+(u, (long) v); }
+
+ friend sc_signed operator + (int64 u, const sc_unsigned& v);
+ friend sc_signed operator + (long u, const sc_unsigned& v);
+ friend sc_signed operator + (int u, const sc_unsigned& v)
+ { return operator+((long) u, v); }
+
+ friend sc_signed operator + (const sc_signed& u, const sc_signed& v);
+ friend sc_signed operator + (const sc_signed& u, int64 v);
+ friend sc_signed operator + (const sc_signed& u, uint64 v);
+ friend sc_signed operator + (const sc_signed& u, long v);
+ friend sc_signed operator + (const sc_signed& u, unsigned long v);
+ friend sc_signed operator + (const sc_signed& u, int v)
+ { return operator+(u, (long) v); }
+ friend sc_signed operator + (const sc_signed& u, unsigned int v)
+ { return operator+(u, (unsigned long) v); }
+
+ friend sc_signed operator + (int64 u, const sc_signed& v);
+ friend sc_signed operator + (uint64 u, const sc_signed& v);
+ friend sc_signed operator + (long u, const sc_signed& v);
+ friend sc_signed operator + (unsigned long u, const sc_signed& v);
+ friend sc_signed operator + (int u, const sc_signed& v)
+ { return operator+((long) u, v); }
+ friend sc_signed operator + (unsigned int u, const sc_signed& v)
+ { return operator+((unsigned long) u, v); }
+
+ const sc_signed& operator += (const sc_signed& v);
+ const sc_signed& operator += (const sc_unsigned& v);
+ const sc_signed& operator += (int64 v);
+ const sc_signed& operator += (uint64 v);
+ const sc_signed& operator += (long v);
+ const sc_signed& operator += (unsigned long v);
+ const sc_signed& operator += (int v)
+ { return operator+=((long) v); }
+ const sc_signed& operator += (unsigned int v)
+ { return operator+=((unsigned long) v); }
+
+ friend sc_signed operator + (const sc_unsigned& u, const sc_int_base& v);
+ friend sc_signed operator + (const sc_int_base& u, const sc_unsigned& v);
+ friend sc_signed operator + (const sc_signed& u, const sc_int_base& v);
+ friend sc_signed operator + (const sc_signed& u, const sc_uint_base& v);
+ friend sc_signed operator + (const sc_int_base& u, const sc_signed& v);
+ friend sc_signed operator + (const sc_uint_base& u, const sc_signed& v);
+ const sc_signed& operator += (const sc_int_base& v);
+ const sc_signed& operator += (const sc_uint_base& v);
+
+ // SUBtraction operators:
+
+ friend sc_signed operator - (const sc_unsigned& u, const sc_signed& v);
+ friend sc_signed operator - (const sc_signed& u, const sc_unsigned& v);
+
+ friend sc_signed operator - (const sc_unsigned& u, const sc_unsigned& v);
+ friend sc_signed operator - (const sc_unsigned& u, int64 v);
+ friend sc_signed operator - (const sc_unsigned& u, uint64 v);
+ friend sc_signed operator - (const sc_unsigned& u, long v);
+ friend sc_signed operator - (const sc_unsigned& u, unsigned long v);
+ friend sc_signed operator - (const sc_unsigned& u, int v)
+ { return operator-(u, (long) v); }
+ friend sc_signed operator - (const sc_unsigned& u, unsigned int v)
+ { return operator-(u, (unsigned long) v); }
+
+ friend sc_signed operator - (int64 u, const sc_unsigned& v);
+ friend sc_signed operator - (uint64 u, const sc_unsigned& v);
+ friend sc_signed operator - (long u, const sc_unsigned& v);
+ friend sc_signed operator - (unsigned long u, const sc_unsigned& v);
+ friend sc_signed operator - (int u, const sc_unsigned& v)
+ { return operator-((long) u, v); }
+ friend sc_signed operator - (unsigned int u, const sc_unsigned& v)
+ { return operator-((unsigned long) u, v); }
+
+ friend sc_signed operator - (const sc_signed& u, const sc_signed& v);
+ friend sc_signed operator - (const sc_signed& u, int64 v);
+ friend sc_signed operator - (const sc_signed& u, uint64 v);
+ friend sc_signed operator - (const sc_signed& u, long v);
+ friend sc_signed operator - (const sc_signed& u, unsigned long v);
+ friend sc_signed operator - (const sc_signed& u, int v)
+ { return operator-(u, (long) v); }
+ friend sc_signed operator - (const sc_signed& u, unsigned int v)
+ { return operator-(u, (unsigned long) v); }
+
+ friend sc_signed operator - (int64 u, const sc_signed& v);
+ friend sc_signed operator - (uint64 u, const sc_signed& v);
+ friend sc_signed operator - (long u, const sc_signed& v);
+ friend sc_signed operator - (unsigned long u, const sc_signed& v);
+ friend sc_signed operator - (int u, const sc_signed& v)
+ { return operator-((long) u, v); }
+ friend sc_signed operator - (unsigned int u, const sc_signed& v)
+ { return operator-((unsigned long) u, v); }
+
+ const sc_signed& operator -= (const sc_signed& v);
+ const sc_signed& operator -= (const sc_unsigned& v);
+ const sc_signed& operator -= (int64 v);
+ const sc_signed& operator -= (uint64 v);
+ const sc_signed& operator -= (long v);
+ const sc_signed& operator -= (unsigned long v);
+ const sc_signed& operator -= (int v)
+ { return operator -= ((long) v); }
+ const sc_signed& operator -= (unsigned int v)
+ { return operator -= ((unsigned long) v); }
+
+ friend sc_signed operator - (const sc_unsigned& u, const sc_int_base& v);
+ friend sc_signed operator - (const sc_unsigned& u, const sc_uint_base& v);
+ friend sc_signed operator - (const sc_int_base& u, const sc_unsigned& v);
+ friend sc_signed operator - (const sc_uint_base& u, const sc_unsigned& v);
+ friend sc_signed operator - (const sc_signed& u, const sc_int_base& v);
+ friend sc_signed operator - (const sc_signed& u, const sc_uint_base& v);
+ friend sc_signed operator - (const sc_int_base& u, const sc_signed& v);
+ friend sc_signed operator - (const sc_uint_base& u, const sc_signed& v);
+ const sc_signed& operator -= (const sc_int_base& v);
+ const sc_signed& operator -= (const sc_uint_base& v);
+
+ // MULtiplication operators:
+
+ friend sc_signed operator * (const sc_unsigned& u, const sc_signed& v);
+ friend sc_signed operator * (const sc_signed& u, const sc_unsigned& v);
+
+ friend sc_signed operator * (const sc_unsigned& u, int64 v);
+ friend sc_signed operator * (const sc_unsigned& u, long v);
+ friend sc_signed operator * (const sc_unsigned& u, int v)
+ { return operator*(u, (long) v); }
+
+ friend sc_signed operator * (int64 u, const sc_unsigned& v);
+ friend sc_signed operator * (long u, const sc_unsigned& v);
+ friend sc_signed operator * (int u, const sc_unsigned& v)
+ { return operator*((long) u, v); }
+
+ friend sc_signed operator * (const sc_signed& u, const sc_signed& v);
+ friend sc_signed operator * (const sc_signed& u, int64 v);
+ friend sc_signed operator * (const sc_signed& u, uint64 v);
+ friend sc_signed operator * (const sc_signed& u, long v);
+ friend sc_signed operator * (const sc_signed& u, unsigned long v);
+ friend sc_signed operator * (const sc_signed& u, int v)
+ { return operator*(u, (long) v); }
+ friend sc_signed operator * (const sc_signed& u, unsigned int v)
+ { return operator*(u, (unsigned long) v); }
+
+ friend sc_signed operator * (int64 u, const sc_signed& v);
+ friend sc_signed operator * (uint64 u, const sc_signed& v);
+ friend sc_signed operator * (long u, const sc_signed& v);
+ friend sc_signed operator * (unsigned long u, const sc_signed& v);
+ friend sc_signed operator * (int u, const sc_signed& v)
+ { return operator*((long) u, v); }
+ friend sc_signed operator * (unsigned int u, const sc_signed& v)
+ { return operator*((unsigned long) u, v); }
+
+ const sc_signed& operator *= (const sc_signed& v);
+ const sc_signed& operator *= (const sc_unsigned& v);
+ const sc_signed& operator *= (int64 v);
+ const sc_signed& operator *= (uint64 v);
+ const sc_signed& operator *= (long v);
+ const sc_signed& operator *= (unsigned long v);
+ const sc_signed& operator *= (int v)
+ { return operator*=((long) v); }
+ const sc_signed& operator *= (unsigned int v)
+ { return operator*=((unsigned long) v); }
+
+ friend sc_signed operator * (const sc_unsigned& u, const sc_int_base& v);
+ friend sc_signed operator * (const sc_int_base& u, const sc_unsigned& v);
+ friend sc_signed operator * (const sc_signed& u, const sc_int_base& v);
+ friend sc_signed operator * (const sc_signed& u, const sc_uint_base& v);
+ friend sc_signed operator * (const sc_int_base& u, const sc_signed& v);
+ friend sc_signed operator * (const sc_uint_base& u, const sc_signed& v);
+ const sc_signed& operator *= (const sc_int_base& v);
+ const sc_signed& operator *= (const sc_uint_base& v);
+
+ // DIVision operators:
+
+ friend sc_signed operator / (const sc_unsigned& u, const sc_signed& v);
+ friend sc_signed operator / (const sc_signed& u, const sc_unsigned& v);
+
+ friend sc_signed operator / (const sc_unsigned& u, int64 v);
+ friend sc_signed operator / (const sc_unsigned& u, long v);
+ friend sc_signed operator / (const sc_unsigned& u, int v)
+ { return operator/(u, (long) v); }
+
+ friend sc_signed operator / (int64 u, const sc_unsigned& v);
+ friend sc_signed operator / (long u, const sc_unsigned& v);
+ friend sc_signed operator / (int u, const sc_unsigned& v)
+ { return operator/((long) u, v); }
+
+ friend sc_signed operator / (const sc_signed& u, const sc_signed& v);
+ friend sc_signed operator / (const sc_signed& u, int64 v);
+ friend sc_signed operator / (const sc_signed& u, uint64 v);
+ friend sc_signed operator / (const sc_signed& u, long v);
+ friend sc_signed operator / (const sc_signed& u, unsigned long v);
+ friend sc_signed operator / (const sc_signed& u, int v)
+ { return operator/(u, (long) v); }
+ friend sc_signed operator / (const sc_signed& u, unsigned int v)
+ { return operator/(u, (unsigned long) v); }
+
+ friend sc_signed operator / (int64 u, const sc_signed& v);
+ friend sc_signed operator / (uint64 u, const sc_signed& v);
+ friend sc_signed operator / (long u, const sc_signed& v);
+ friend sc_signed operator / (unsigned long u, const sc_signed& v);
+ friend sc_signed operator / (int u, const sc_signed& v)
+ { return operator/((long) u, v); }
+ friend sc_signed operator / (unsigned int u, const sc_signed& v)
+ { return operator/((unsigned long) u, v); }
+
+ const sc_signed& operator /= (const sc_signed& v);
+ const sc_signed& operator /= (const sc_unsigned& v);
+ const sc_signed& operator /= (int64 v);
+ const sc_signed& operator /= (uint64 v);
+ const sc_signed& operator /= (long v);
+ const sc_signed& operator /= (unsigned long v);
+ const sc_signed& operator /= (int v)
+ { return operator/=((long) v); }
+ const sc_signed& operator /= (unsigned int v)
+ { return operator/=((unsigned long) v); }
+
+ friend sc_signed operator / (const sc_unsigned& u, const sc_int_base& v);
+ friend sc_signed operator / (const sc_int_base& u, const sc_unsigned& v);
+ friend sc_signed operator / (const sc_signed& u, const sc_int_base& v);
+ friend sc_signed operator / (const sc_signed& u, const sc_uint_base& v);
+ friend sc_signed operator / (const sc_int_base& u, const sc_signed& v);
+ friend sc_signed operator / (const sc_uint_base& u, const sc_signed& v);
+ const sc_signed& operator /= (const sc_int_base& v);
+ const sc_signed& operator /= (const sc_uint_base& v);
+
+ // MODulo operators:
+
+ friend sc_signed operator % (const sc_unsigned& u, const sc_signed& v);
+ friend sc_signed operator % (const sc_signed& u, const sc_unsigned& v);
+
+ friend sc_signed operator % (const sc_unsigned& u, int64 v);
+ friend sc_signed operator % (const sc_unsigned& u, long v);
+ friend sc_signed operator % (const sc_unsigned& u, int v)
+ { return operator%(u, (long) v); }
+
+ friend sc_signed operator % (int64 u, const sc_unsigned& v);
+ friend sc_signed operator % (long u, const sc_unsigned& v);
+ friend sc_signed operator % (int u, const sc_unsigned& v)
+ { return operator%((long) u, v); }
+
+ friend sc_signed operator % (const sc_signed& u, const sc_signed& v);
+ friend sc_signed operator % (const sc_signed& u, int64 v);
+ friend sc_signed operator % (const sc_signed& u, uint64 v);
+ friend sc_signed operator % (const sc_signed& u, long v);
+ friend sc_signed operator % (const sc_signed& u, unsigned long v);
+ friend sc_signed operator % (const sc_signed& u, int v)
+ { return operator%(u, (long) v); }
+ friend sc_signed operator % (const sc_signed& u, unsigned int v)
+ { return operator%(u, (unsigned long) v); }
+
+ friend sc_signed operator % (int64 u, const sc_signed& v);
+ friend sc_signed operator % (uint64 u, const sc_signed& v);
+ friend sc_signed operator % (long u, const sc_signed& v);
+ friend sc_signed operator % (unsigned long u, const sc_signed& v);
+ friend sc_signed operator % (int u, const sc_signed& v)
+ { return operator%((long) u, v); }
+ friend sc_signed operator % (unsigned int u, const sc_signed& v)
+ { return operator%((unsigned long) u, v); }
+
+ const sc_signed& operator %= (const sc_signed& v);
+ const sc_signed& operator %= (const sc_unsigned& v);
+ const sc_signed& operator %= (int64 v);
+ const sc_signed& operator %= (uint64 v);
+ const sc_signed& operator %= (long v);
+ const sc_signed& operator %= (unsigned long v);
+ const sc_signed& operator %= (int v)
+ { return operator%=((long) v); }
+ const sc_signed& operator %= (unsigned int v)
+ { return operator%=((unsigned long) v); }
+
+ friend sc_signed operator % (const sc_unsigned& u, const sc_int_base& v);
+ friend sc_signed operator % (const sc_int_base& u, const sc_unsigned& v);
+ friend sc_signed operator % (const sc_signed& u, const sc_int_base& v);
+ friend sc_signed operator % (const sc_signed& u, const sc_uint_base& v);
+ friend sc_signed operator % (const sc_int_base& u, const sc_signed& v);
+ friend sc_signed operator % (const sc_uint_base& u, const sc_signed& v);
+ const sc_signed& operator %= (const sc_int_base& v);
+ const sc_signed& operator %= (const sc_uint_base& v);
+
+ // BITWISE OPERATORS:
+
+ // Bitwise AND operators:
+
+ friend sc_signed operator & (const sc_unsigned& u, const sc_signed& v);
+ friend sc_signed operator & (const sc_signed& u, const sc_unsigned& v);
+
+ friend sc_signed operator & (const sc_unsigned& u, int64 v);
+ friend sc_signed operator & (const sc_unsigned& u, long v);
+ friend sc_signed operator & (const sc_unsigned& u, int v)
+ { return operator&(u, (long) v); }
+
+ friend sc_signed operator & (int64 u, const sc_unsigned& v);
+ friend sc_signed operator & (long u, const sc_unsigned& v);
+ friend sc_signed operator & (int u, const sc_unsigned& v)
+ { return operator&((long) u, v); }
+
+ friend sc_signed operator & (const sc_signed& u, const sc_signed& v);
+ friend sc_signed operator & (const sc_signed& u, int64 v);
+ friend sc_signed operator & (const sc_signed& u, uint64 v);
+ friend sc_signed operator & (const sc_signed& u, long v);
+ friend sc_signed operator & (const sc_signed& u, unsigned long v);
+ friend sc_signed operator & (const sc_signed& u, int v)
+ { return operator&(u, (long) v); }
+ friend sc_signed operator & (const sc_signed& u, unsigned int v)
+ { return operator&(u, (unsigned long) v); }
+
+ friend sc_signed operator & (int64 u, const sc_signed& v);
+ friend sc_signed operator & (uint64 u, const sc_signed& v);
+ friend sc_signed operator & (long u, const sc_signed& v);
+ friend sc_signed operator & (unsigned long u, const sc_signed& v);
+ friend sc_signed operator & (int u, const sc_signed& v)
+ { return operator&((long) u, v); }
+ friend sc_signed operator & (unsigned int u, const sc_signed& v)
+ { return operator&((unsigned long) u, v); }
+
+ const sc_signed& operator &= (const sc_signed& v);
+ const sc_signed& operator &= (const sc_unsigned& v);
+ const sc_signed& operator &= (int64 v);
+ const sc_signed& operator &= (uint64 v);
+ const sc_signed& operator &= (long v);
+ const sc_signed& operator &= (unsigned long v);
+ const sc_signed& operator &= (int v)
+ { return operator&=((long) v); }
+ const sc_signed& operator &= (unsigned int v)
+ { return operator&=((unsigned long) v); }
+
+ friend sc_signed operator & (const sc_unsigned& u, const sc_int_base& v);
+ friend sc_signed operator & (const sc_int_base& u, const sc_unsigned& v);
+ friend sc_signed operator & (const sc_signed& u, const sc_int_base& v);
+ friend sc_signed operator & (const sc_signed& u, const sc_uint_base& v);
+ friend sc_signed operator & (const sc_int_base& u, const sc_signed& v);
+ friend sc_signed operator & (const sc_uint_base& u, const sc_signed& v);
+ const sc_signed& operator &= (const sc_int_base& v);
+ const sc_signed& operator &= (const sc_uint_base& v);
+
+ // Bitwise OR operators:
+
+ friend sc_signed operator | (const sc_unsigned& u, const sc_signed& v);
+ friend sc_signed operator | (const sc_signed& u, const sc_unsigned& v);
+
+ friend sc_signed operator | (const sc_unsigned& u, int64 v);
+ friend sc_signed operator | (const sc_unsigned& u, long v);
+ friend sc_signed operator | (const sc_unsigned& u, int v)
+ { return operator|(u, (long) v); }
+
+ friend sc_signed operator | (int64 u, const sc_unsigned& v);
+ friend sc_signed operator | (long u, const sc_unsigned& v);
+ friend sc_signed operator | (int u, const sc_unsigned& v)
+ { return operator|((long) u, v); }
+
+ friend sc_signed operator | (const sc_signed& u, const sc_signed& v);
+ friend sc_signed operator | (const sc_signed& u, int64 v);
+ friend sc_signed operator | (const sc_signed& u, uint64 v);
+ friend sc_signed operator | (const sc_signed& u, long v);
+ friend sc_signed operator | (const sc_signed& u, unsigned long v);
+ friend sc_signed operator | (const sc_signed& u, int v)
+ { return operator|(u, (long) v); }
+ friend sc_signed operator | (const sc_signed& u, unsigned int v)
+ { return operator|(u, (unsigned long) v); }
+
+ friend sc_signed operator | (int64 u, const sc_signed& v);
+ friend sc_signed operator | (uint64 u, const sc_signed& v);
+ friend sc_signed operator | (long u, const sc_signed& v);
+ friend sc_signed operator | (unsigned long u, const sc_signed& v);
+ friend sc_signed operator | (int u, const sc_signed& v)
+ { return operator|((long) u, v); }
+ friend sc_signed operator | (unsigned int u, const sc_signed& v)
+ { return operator|((unsigned long) u, v); }
+
+ const sc_signed& operator |= (const sc_signed& v);
+ const sc_signed& operator |= (const sc_unsigned& v);
+ const sc_signed& operator |= (int64 v);
+ const sc_signed& operator |= (uint64 v);
+ const sc_signed& operator |= (long v);
+ const sc_signed& operator |= (unsigned long v);
+ const sc_signed& operator |= (int v)
+ { return operator|=((long) v); }
+ const sc_signed& operator |= (unsigned int v)
+ { return operator|=((unsigned long) v); }
+
+ friend sc_signed operator | (const sc_unsigned& u, const sc_int_base& v);
+ friend sc_signed operator | (const sc_int_base& u, const sc_unsigned& v);
+ friend sc_signed operator | (const sc_signed& u, const sc_int_base& v);
+ friend sc_signed operator | (const sc_signed& u, const sc_uint_base& v);
+ friend sc_signed operator | (const sc_int_base& u, const sc_signed& v);
+ friend sc_signed operator | (const sc_uint_base& u, const sc_signed& v);
+ const sc_signed& operator |= (const sc_int_base& v);
+ const sc_signed& operator |= (const sc_uint_base& v);
+
+ // Bitwise XOR operators:
+
+ friend sc_signed operator ^ (const sc_unsigned& u, const sc_signed& v);
+ friend sc_signed operator ^ (const sc_signed& u, const sc_unsigned& v);
+
+ friend sc_signed operator ^ (const sc_unsigned& u, int64 v);
+ friend sc_signed operator ^ (const sc_unsigned& u, long v);
+ friend sc_signed operator ^ (const sc_unsigned& u, int v)
+ { return operator^(u, (long) v); }
+
+ friend sc_signed operator ^ (int64 u, const sc_unsigned& v);
+ friend sc_signed operator ^ (long u, const sc_unsigned& v);
+ friend sc_signed operator ^ (int u, const sc_unsigned& v)
+ { return operator^((long) u, v); }
+
+ friend sc_signed operator ^ (const sc_signed& u, const sc_signed& v);
+ friend sc_signed operator ^ (const sc_signed& u, int64 v);
+ friend sc_signed operator ^ (const sc_signed& u, uint64 v);
+ friend sc_signed operator ^ (const sc_signed& u, long v);
+ friend sc_signed operator ^ (const sc_signed& u, unsigned long v);
+ friend sc_signed operator ^ (const sc_signed& u, int v)
+ { return operator^(u, (long) v); }
+ friend sc_signed operator ^ (const sc_signed& u, unsigned int v)
+ { return operator^(u, (unsigned long) v); }
+
+ friend sc_signed operator ^ (int64 u, const sc_signed& v);
+ friend sc_signed operator ^ (uint64 u, const sc_signed& v);
+ friend sc_signed operator ^ (long u, const sc_signed& v);
+ friend sc_signed operator ^ (unsigned long u, const sc_signed& v);
+ friend sc_signed operator ^ (int u, const sc_signed& v)
+ { return operator^((long) u, v); }
+ friend sc_signed operator ^ (unsigned int u, const sc_signed& v)
+ { return operator^((unsigned long) u, v); }
+
+ const sc_signed& operator ^= (const sc_signed& v);
+ const sc_signed& operator ^= (const sc_unsigned& v);
+ const sc_signed& operator ^= (int64 v);
+ const sc_signed& operator ^= (uint64 v);
+ const sc_signed& operator ^= (long v);
+ const sc_signed& operator ^= (unsigned long v);
+ const sc_signed& operator ^= (int v)
+ { return operator^=((long) v); }
+ const sc_signed& operator ^= (unsigned int v)
+ { return operator^=((unsigned long) v); }
+
+ friend sc_signed operator ^ (const sc_unsigned& u, const sc_int_base& v);
+ friend sc_signed operator ^ (const sc_int_base& u, const sc_unsigned& v);
+ friend sc_signed operator ^ (const sc_signed& u, const sc_int_base& v);
+ friend sc_signed operator ^ (const sc_signed& u, const sc_uint_base& v);
+ friend sc_signed operator ^ (const sc_int_base& u, const sc_signed& v);
+ friend sc_signed operator ^ (const sc_uint_base& u, const sc_signed& v);
+ const sc_signed& operator ^= (const sc_int_base& v);
+ const sc_signed& operator ^= (const sc_uint_base& v);
+
+ // SHIFT OPERATORS:
+
+ // LEFT SHIFT operators:
+
+ friend sc_unsigned operator << (const sc_unsigned& u, const sc_signed& v);
+ friend sc_signed operator << (const sc_signed& u, const sc_unsigned& v);
+
+ friend sc_signed operator << (const sc_signed& u, const sc_signed& v);
+ friend sc_signed operator << (const sc_signed& u, int64 v);
+ friend sc_signed operator << (const sc_signed& u, uint64 v);
+ friend sc_signed operator << (const sc_signed& u, long v);
+ friend sc_signed operator << (const sc_signed& u, unsigned long v);
+ friend sc_signed operator << (const sc_signed& u, int v)
+ { return operator<<(u, (long) v); }
+ friend sc_signed operator << (const sc_signed& u, unsigned int v)
+ { return operator<<(u, (unsigned long) v); }
+
+ const sc_signed& operator <<= (const sc_signed& v);
+ const sc_signed& operator <<= (const sc_unsigned& v);
+ const sc_signed& operator <<= (int64 v);
+ const sc_signed& operator <<= (uint64 v);
+ const sc_signed& operator <<= (long v);
+ const sc_signed& operator <<= (unsigned long v);
+ const sc_signed& operator <<= (int v)
+ { return operator<<=((long) v); }
+ const sc_signed& operator <<= (unsigned int v)
+ { return operator<<=((unsigned long) v); }
+
+ friend sc_signed operator << (const sc_signed& u, const sc_int_base& v);
+ friend sc_signed operator << (const sc_signed& u, const sc_uint_base& v);
+ const sc_signed& operator <<= (const sc_int_base& v);
+ const sc_signed& operator <<= (const sc_uint_base& v);
+
+ // RIGHT SHIFT operators:
+
+ friend sc_unsigned operator >> (const sc_unsigned& u, const sc_signed& v);
+ friend sc_signed operator >> (const sc_signed& u, const sc_unsigned& v);
+
+ friend sc_signed operator >> (const sc_signed& u, const sc_signed& v);
+ friend sc_signed operator >> (const sc_signed& u, int64 v);
+ friend sc_signed operator >> (const sc_signed& u, uint64 v);
+ friend sc_signed operator >> (const sc_signed& u, long v);
+ friend sc_signed operator >> (const sc_signed& u, unsigned long v);
+ friend sc_signed operator >> (const sc_signed& u, int v)
+ { return operator>>(u, (long) v); }
+ friend sc_signed operator >> (const sc_signed& u, unsigned int v)
+ { return operator>>(u, (unsigned long) v); }
+
+ const sc_signed& operator >>= (const sc_signed& v);
+ const sc_signed& operator >>= (const sc_unsigned& v);
+ const sc_signed& operator >>= (int64 v);
+ const sc_signed& operator >>= (uint64 v);
+ const sc_signed& operator >>= (long v);
+ const sc_signed& operator >>= (unsigned long v);
+ const sc_signed& operator >>= (int v)
+ { return operator>>=((long) v); }
+ const sc_signed& operator >>= (unsigned int v)
+ { return operator>>=((unsigned long) v); }
+
+ friend sc_signed operator >> (const sc_signed& u, const sc_int_base& v);
+ friend sc_signed operator >> (const sc_signed& u, const sc_uint_base& v);
+ const sc_signed& operator >>= (const sc_int_base& v);
+ const sc_signed& operator >>= (const sc_uint_base& v);
+
+ // Unary arithmetic operators
+ friend sc_signed operator + (const sc_signed& u);
+ friend sc_signed operator - (const sc_signed& u);
+ friend sc_signed operator - (const sc_unsigned& u);
+
+ // LOGICAL OPERATORS:
+
+ // Logical EQUAL operators:
+
+ friend bool operator == (const sc_unsigned& u, const sc_signed& v);
+ friend bool operator == (const sc_signed& u, const sc_unsigned& v);
+
+ friend bool operator == (const sc_signed& u, const sc_signed& v);
+ friend bool operator == (const sc_signed& u, int64 v);
+ friend bool operator == (const sc_signed& u, uint64 v);
+ friend bool operator == (const sc_signed& u, long v);
+ friend bool operator == (const sc_signed& u, unsigned long v);
+ friend bool operator == (const sc_signed& u, int v)
+ { return operator==(u, (long) v); }
+ friend bool operator == (const sc_signed& u, unsigned int v)
+ { return operator==(u, (unsigned long) v); }
+
+ friend bool operator == (int64 u, const sc_signed& v);
+ friend bool operator == (uint64 u, const sc_signed& v);
+ friend bool operator == (long u, const sc_signed& v);
+ friend bool operator == (unsigned long u, const sc_signed& v);
+ friend bool operator == (int u, const sc_signed& v)
+ { return operator==((long) u, v); }
+ friend bool operator == (unsigned int u, const sc_signed& v)
+ { return operator==((unsigned long) u, v); }
+
+ friend bool operator == (const sc_signed& u, const sc_int_base& v);
+ friend bool operator == (const sc_signed& u, const sc_uint_base& v);
+ friend bool operator == (const sc_int_base& u, const sc_signed& v);
+ friend bool operator == (const sc_uint_base& u, const sc_signed& v);
+
+ // Logical NOT_EQUAL operators:
+
+ friend bool operator != (const sc_unsigned& u, const sc_signed& v);
+ friend bool operator != (const sc_signed& u, const sc_unsigned& v);
+
+ friend bool operator != (const sc_signed& u, const sc_signed& v);
+ friend bool operator != (const sc_signed& u, int64 v);
+ friend bool operator != (const sc_signed& u, uint64 v);
+ friend bool operator != (const sc_signed& u, long v);
+ friend bool operator != (const sc_signed& u, unsigned long v);
+ friend bool operator != (const sc_signed& u, int v)
+ { return operator!=(u, (long) v); }
+ friend bool operator != (const sc_signed& u, unsigned int v)
+ { return operator!=(u, (unsigned long) v); }
+
+ friend bool operator != (int64 u, const sc_signed& v);
+ friend bool operator != (uint64 u, const sc_signed& v);
+ friend bool operator != (long u, const sc_signed& v);
+ friend bool operator != (unsigned long u, const sc_signed& v);
+ friend bool operator != (int u, const sc_signed& v)
+ { return operator!=((long) u, v); }
+ friend bool operator != (unsigned int u, const sc_signed& v)
+ { return operator!=((unsigned long) u, v); }
+
+ friend bool operator != (const sc_signed& u, const sc_int_base& v);
+ friend bool operator != (const sc_signed& u, const sc_uint_base& v);
+ friend bool operator != (const sc_int_base& u, const sc_signed& v);
+ friend bool operator != (const sc_uint_base& u, const sc_signed& v);
+
+ // Logical LESS_THAN operators:
+
+ friend bool operator < (const sc_unsigned& u, const sc_signed& v);
+ friend bool operator < (const sc_signed& u, const sc_unsigned& v);
+
+ friend bool operator < (const sc_signed& u, const sc_signed& v);
+ friend bool operator < (const sc_signed& u, int64 v);
+ friend bool operator < (const sc_signed& u, uint64 v);
+ friend bool operator < (const sc_signed& u, long v);
+ friend bool operator < (const sc_signed& u, unsigned long v);
+ friend bool operator < (const sc_signed& u, int v)
+ { return operator<(u, (long) v); }
+ friend bool operator < (const sc_signed& u, unsigned int v)
+ { return operator<(u, (unsigned long) v); }
+
+ friend bool operator < (int64 u, const sc_signed& v);
+ friend bool operator < (uint64 u, const sc_signed& v);
+ friend bool operator < (long u, const sc_signed& v);
+ friend bool operator < (unsigned long u, const sc_signed& v);
+ friend bool operator < (int u, const sc_signed& v)
+ { return operator<((long) u, v); }
+ friend bool operator < (unsigned int u, const sc_signed& v)
+ { return operator<((unsigned long) u, v); }
+
+ friend bool operator < (const sc_signed& u, const sc_int_base& v);
+ friend bool operator < (const sc_signed& u, const sc_uint_base& v);
+ friend bool operator < (const sc_int_base& u, const sc_signed& v);
+ friend bool operator < (const sc_uint_base& u, const sc_signed& v);
+
+ // Logical LESS_THAN_AND_EQUAL operators:
+
+ friend bool operator <= (const sc_unsigned& u, const sc_signed& v);
+ friend bool operator <= (const sc_signed& u, const sc_unsigned& v);
+
+ friend bool operator <= (const sc_signed& u, const sc_signed& v);
+ friend bool operator <= (const sc_signed& u, int64 v);
+ friend bool operator <= (const sc_signed& u, uint64 v);
+ friend bool operator <= (const sc_signed& u, long v);
+ friend bool operator <= (const sc_signed& u, unsigned long v);
+ friend bool operator <= (const sc_signed& u, int v)
+ { return operator<=(u, (long) v); }
+ friend bool operator <= (const sc_signed& u, unsigned int v)
+ { return operator<=(u, (unsigned long) v); }
+
+ friend bool operator <= (int64 u, const sc_signed& v);
+ friend bool operator <= (uint64 u, const sc_signed& v);
+ friend bool operator <= (long u, const sc_signed& v);
+ friend bool operator <= (unsigned long u, const sc_signed& v);
+ friend bool operator <= (int u, const sc_signed& v)
+ { return operator<=((long) u, v); }
+ friend bool operator <= (unsigned int u, const sc_signed& v)
+ { return operator<=((unsigned long) u, v); }
+
+ friend bool operator <= (const sc_signed& u, const sc_int_base& v);
+ friend bool operator <= (const sc_signed& u, const sc_uint_base& v);
+ friend bool operator <= (const sc_int_base& u, const sc_signed& v);
+ friend bool operator <= (const sc_uint_base& u, const sc_signed& v);
+
+ // Logical GREATER_THAN operators:
+
+ friend bool operator > (const sc_unsigned& u, const sc_signed& v);
+ friend bool operator > (const sc_signed& u, const sc_unsigned& v);
+
+ friend bool operator > (const sc_signed& u, const sc_signed& v);
+ friend bool operator > (const sc_signed& u, int64 v);
+ friend bool operator > (const sc_signed& u, uint64 v);
+ friend bool operator > (const sc_signed& u, long v);
+ friend bool operator > (const sc_signed& u, unsigned long v);
+ friend bool operator > (const sc_signed& u, int v)
+ { return operator>(u, (long) v); }
+ friend bool operator > (const sc_signed& u, unsigned int v)
+ { return operator>(u, (unsigned long) v); }
+
+ friend bool operator > (int64 u, const sc_signed& v);
+ friend bool operator > (uint64 u, const sc_signed& v);
+ friend bool operator > (long u, const sc_signed& v);
+ friend bool operator > (unsigned long u, const sc_signed& v);
+ friend bool operator > (int u, const sc_signed& v)
+ { return operator>((long) u, v); }
+ friend bool operator > (unsigned int u, const sc_signed& v)
+ { return operator>((unsigned long) u, v); }
+
+ friend bool operator > (const sc_signed& u, const sc_int_base& v);
+ friend bool operator > (const sc_signed& u, const sc_uint_base& v);
+ friend bool operator > (const sc_int_base& u, const sc_signed& v);
+ friend bool operator > (const sc_uint_base& u, const sc_signed& v);
+
+ // Logical GREATER_THAN_AND_EQUAL operators:
+
+ friend bool operator >= (const sc_unsigned& u, const sc_signed& v);
+ friend bool operator >= (const sc_signed& u, const sc_unsigned& v);
+
+ friend bool operator >= (const sc_signed& u, const sc_signed& v);
+ friend bool operator >= (const sc_signed& u, int64 v);
+ friend bool operator >= (const sc_signed& u, uint64 v);
+ friend bool operator >= (const sc_signed& u, long v);
+ friend bool operator >= (const sc_signed& u, unsigned long v);
+ friend bool operator >= (const sc_signed& u, int v)
+ { return operator>=(u, (long) v); }
+ friend bool operator >= (const sc_signed& u, unsigned int v)
+ { return operator>=(u, (unsigned long) v); }
+
+ friend bool operator >= (int64 u, const sc_signed& v);
+ friend bool operator >= (uint64 u, const sc_signed& v);
+ friend bool operator >= (long u, const sc_signed& v);
+ friend bool operator >= (unsigned long u, const sc_signed& v);
+ friend bool operator >= (int u, const sc_signed& v)
+ { return operator>=((long) u, v); }
+ friend bool operator >= (unsigned int u, const sc_signed& v)
+ { return operator>=((unsigned long) u, v); }
+
+ friend bool operator >= (const sc_signed& u, const sc_int_base& v);
+ friend bool operator >= (const sc_signed& u, const sc_uint_base& v);
+ friend bool operator >= (const sc_int_base& u, const sc_signed& v);
+ friend bool operator >= (const sc_uint_base& u, const sc_signed& v);
+
+ // Bitwise NOT operator (unary).
+ friend sc_signed operator ~ (const sc_signed& u);
+
+ // Helper functions.
+ friend sc_signed add_signed_friend(small_type us,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ small_type vs,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+ friend sc_signed sub_signed_friend(small_type us,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ small_type vs,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+ friend sc_signed mul_signed_friend(small_type s,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+ friend sc_signed div_signed_friend(small_type s,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+ friend sc_signed mod_signed_friend(small_type us,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+ friend sc_signed and_signed_friend(small_type us,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ small_type vs,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+ friend sc_signed or_signed_friend(small_type us,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ small_type vs,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+ friend sc_signed xor_signed_friend(small_type us,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ small_type vs,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+private:
+
+ small_type sgn; // Shortened as s.
+ int nbits; // Shortened as nb.
+ int ndigits; // Shortened as nd.
+
+#ifdef SC_MAX_NBITS
+ sc_digit digit[DIV_CEIL(SC_MAX_NBITS)]; // Shortened as d.
+#else
+ sc_digit *digit; // Shortened as d.
+#endif
+
+ // Private constructors:
+
+ // Create a copy of v with sign s.
+ sc_signed(const sc_signed& v, small_type s);
+ sc_signed(const sc_unsigned& v, small_type s);
+
+ // Create a signed number with the given attributes.
+ sc_signed(small_type s, int nb, int nd,
+ sc_digit *d, bool alloc = true);
+
+ // Create an unsigned number using the bits u[l..r].
+ sc_signed(const sc_signed* u, int l, int r);
+ sc_signed(const sc_unsigned* u, int l, int r);
+
+ // Private member functions. The called functions are inline functions.
+
+ small_type default_sign() const
+ { return SC_NOSIGN; }
+
+ int num_bits(int nb) const { return nb; }
+
+ bool check_if_outside(int bit_num) const;
+
+ void copy_digits(int nb, int nd, const sc_digit *d)
+ { copy_digits_signed(sgn, nbits, ndigits, digit, nb, nd, d); }
+
+ void makezero()
+ { sgn = make_zero(ndigits, digit); }
+
+ // Conversion functions between 2's complement (2C) and
+ // sign-magnitude (SM):
+ void convert_2C_to_SM()
+ { sgn = convert_signed_2C_to_SM(nbits, ndigits, digit); }
+
+ void convert_SM_to_2C_to_SM()
+ { sgn = convert_signed_SM_to_2C_to_SM(sgn, nbits, ndigits, digit); }
+
+ void convert_SM_to_2C()
+ { convert_signed_SM_to_2C(sgn, ndigits, digit); }
+
+};
+
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream&, const sc_signed& );
+
+inline
+::std::istream&
+operator >> ( ::std::istream&, sc_signed& );
+
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, const sc_signed_bitref_r& a )
+{
+ a.print( os );
+ return os;
+}
+
+
+inline
+::std::istream&
+operator >> ( ::std::istream& is, sc_signed_bitref& a )
+{
+ a.scan( is );
+ return is;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_signed_subref_r
+//
+// Proxy class for sc_signed part selection (r-value only).
+// ----------------------------------------------------------------------------
+
+
+// reduce methods
+
+inline bool sc_signed_subref_r::and_reduce() const
+{
+ const sc_signed* target_p = m_obj_p;
+ for ( int i = m_right; i <= m_left; i++ )
+ if ( !target_p->test(i) ) return false;
+ return true;
+}
+
+inline bool sc_signed_subref_r::nand_reduce() const
+{
+ return !and_reduce();
+}
+
+inline bool sc_signed_subref_r::or_reduce() const
+{
+ const sc_signed* target_p = m_obj_p;
+ for ( int i = m_right; i <= m_left; i++ )
+ if ( target_p->test(i) ) return true;
+ return false;
+}
+
+inline bool sc_signed_subref_r::nor_reduce() const
+{
+ return !or_reduce();
+}
+
+inline bool sc_signed_subref_r::xor_reduce() const
+{
+ int odd;
+ const sc_signed* target_p = m_obj_p;
+ odd = 0;
+ for ( int i = m_right; i <= m_left; i++ )
+ if ( target_p->test(i) ) odd = ~odd;
+ return odd ? true : false;
+}
+
+inline bool sc_signed_subref_r::xnor_reduce() const
+{
+ return !xor_reduce();
+}
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, const sc_signed_subref_r& a )
+{
+ a.print( os );
+ return os;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_signed_subref
+//
+// Proxy class for sc_signed part selection (r-value and l-value).
+// ----------------------------------------------------------------------------
+
+// assignment operators
+
+inline
+const sc_signed_subref&
+sc_signed_subref::operator = ( const char* a )
+{
+ sc_signed aa( length() );
+ return ( *this = aa = a );
+}
+
+
+
+
+inline
+::std::istream&
+operator >> ( ::std::istream& is, sc_signed_subref& a )
+{
+ a.scan( is );
+ return is;
+}
+
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_signed
+//
+// Arbitrary precision signed number.
+// ----------------------------------------------------------------------------
+
+template<class T>
+sc_signed::sc_signed( const sc_generic_base<T>& v )
+{
+ int nb = v->length();
+ sgn = default_sign();
+ if( nb > 0 ) {
+ nbits = num_bits( nb );
+ } else {
+ char msg[BUFSIZ];
+ std::sprintf( msg,
+ "sc_unsigned( sc_generic_base<T> ) : nb = %d is not valid", nb);
+ SC_REPORT_ERROR( sc_core::SC_ID_INIT_FAILED_, msg );
+ }
+ ndigits = DIV_CEIL(nbits);
+# ifdef SC_MAX_NBITS
+ test_bound(nb);
+# else
+ digit = new sc_digit[ndigits];
+# endif
+ makezero();
+ v->to_sc_signed(*this);
+}
+
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, const sc_signed& a )
+{
+ a.print( os );
+ return os;
+}
+
+inline
+::std::istream&
+operator >> ( ::std::istream& is, sc_signed& a )
+{
+ a.scan( is );
+ return is;
+}
+
+
+} // namespace sc_dt
+
+
+#endif
diff --git a/ext/systemc/src/sysc/datatypes/int/sc_signed_bitref.inc b/ext/systemc/src/sysc/datatypes/int/sc_signed_bitref.inc
new file mode 100644
index 000000000..46d347d94
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/int/sc_signed_bitref.inc
@@ -0,0 +1,163 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_signed_bitref.h -- Proxy class that is declared in sc_signed.h.
+
+ Original Author: Ali Dasdan, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_signed_bitref_r
+//
+// Proxy class for sc_signed bit selection (r-value only).
+// ----------------------------------------------------------------------------
+
+// implicit conversion to uint64
+
+sc_signed_bitref_r::operator uint64 () const
+{
+ return m_obj_p->test( m_index );
+}
+
+bool
+sc_signed_bitref_r::operator ! () const
+{
+ return ( ! m_obj_p->test( m_index ) );
+}
+
+bool
+sc_signed_bitref_r::operator ~ () const
+{
+ return ( ! m_obj_p->test( m_index ) );
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_signed_bitref
+//
+// Proxy class for sc_signed bit selection (r-value and l-value).
+// ----------------------------------------------------------------------------
+
+// assignment operators
+
+const sc_signed_bitref&
+sc_signed_bitref::operator = ( const sc_signed_bitref_r& b )
+{
+ m_obj_p->set( m_index, (bool) b );
+ return *this;
+}
+
+const sc_signed_bitref&
+sc_signed_bitref::operator = ( const sc_signed_bitref& b )
+{
+ m_obj_p->set( m_index, (bool) b );
+ return *this;
+}
+
+const sc_signed_bitref&
+sc_signed_bitref::operator = ( bool b )
+{
+ m_obj_p->set( m_index, b );
+ return *this;
+}
+
+
+const sc_signed_bitref&
+sc_signed_bitref::operator &= ( bool b )
+{
+ if( ! b ) {
+ m_obj_p->clear( m_index );
+ }
+ return *this;
+}
+
+const sc_signed_bitref&
+sc_signed_bitref::operator |= ( bool b )
+{
+ if( b ) {
+ m_obj_p->set( m_index );
+ }
+ return *this;
+}
+
+const sc_signed_bitref&
+sc_signed_bitref::operator ^= ( bool b )
+{
+ if( b ) {
+ m_obj_p->invert( m_index );
+ }
+ return *this;
+}
+
+// #### OPTIMIZE
+void sc_signed_bitref::concat_set(int64 src, int low_i)
+{
+ bool value = 1 & ((low_i < 64) ? (src >> low_i) : (src >> 63));
+ m_obj_p->set(low_i, value);
+}
+
+void sc_signed_bitref::concat_set(const sc_signed& src, int low_i)
+{
+ if ( low_i < src.length() )
+ m_obj_p->set(low_i, src.test(low_i));
+ else
+ m_obj_p->set(low_i, src<0);
+}
+
+void sc_signed_bitref::concat_set(const sc_unsigned& src, int low_i)
+{
+ if ( low_i < src.length() )
+ m_obj_p->set(low_i, src.test(low_i));
+ else
+ m_obj_p->set(low_i, 0);
+}
+
+void sc_signed_bitref::concat_set(uint64 src, int low_i)
+{
+ bool value = 1 & ((low_i < 64) ? (src >> low_i) : 0);
+ m_obj_p->set(low_i, value);
+}
+
+
+// other methods
+
+void
+sc_signed_bitref::scan( ::std::istream& is )
+{
+ bool b;
+ is >> b;
+ *this = b;
+}
+
+
+// End of file
diff --git a/ext/systemc/src/sysc/datatypes/int/sc_signed_subref.inc b/ext/systemc/src/sysc/datatypes/int/sc_signed_subref.inc
new file mode 100644
index 000000000..3f50210a7
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/int/sc_signed_subref.inc
@@ -0,0 +1,408 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_signed_subref.h -- Proxy class that is declared in sc_signed.h.
+
+ Original Author: Ali Dasdan, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_signed_subref_r
+//
+// Proxy class for sc_signed part selection (r-value only).
+// ----------------------------------------------------------------------------
+
+// concatenation support
+
+uint64 sc_signed_subref_r::concat_get_uint64() const
+{
+ sc_unsigned a( m_obj_p, m_left, m_right );
+ return a.to_uint64();
+}
+
+
+bool sc_signed_subref_r::concat_get_ctrl(sc_digit* dst_p, int low_i ) const
+{
+ sc_unsigned a( m_obj_p, m_left, m_right );
+ return a.concat_get_ctrl( dst_p, low_i );
+}
+
+
+bool sc_signed_subref_r::concat_get_data(sc_digit* dst_p, int low_i ) const
+{
+ sc_unsigned a( m_obj_p, m_left, m_right );
+ return a.concat_get_data( dst_p, low_i );
+}
+
+
+// implicit conversion to sc_signed
+
+sc_signed_subref_r::operator sc_unsigned () const
+{
+ return sc_unsigned( m_obj_p, m_left, m_right );
+}
+
+
+// explicit conversions
+
+int
+sc_signed_subref_r::to_int() const
+{
+ sc_unsigned a( m_obj_p, m_left, m_right );
+ return a.to_int();
+}
+
+unsigned int
+sc_signed_subref_r::to_uint() const
+{
+ sc_unsigned a( m_obj_p, m_left, m_right );
+ return a.to_uint();
+}
+
+long
+sc_signed_subref_r::to_long() const
+{
+ sc_unsigned a( m_obj_p, m_left, m_right );
+ return a.to_long();
+}
+
+unsigned long
+sc_signed_subref_r::to_ulong() const
+{
+ sc_unsigned a( m_obj_p, m_left, m_right );
+ return a.to_ulong();
+}
+
+int64
+sc_signed_subref_r::to_int64() const
+{
+ sc_unsigned a( m_obj_p, m_left, m_right );
+ return a.to_int64();
+}
+
+uint64
+sc_signed_subref_r::to_uint64() const
+{
+ sc_unsigned a( m_obj_p, m_left, m_right );
+ return a.to_uint64();
+}
+
+double
+sc_signed_subref_r::to_double() const
+{
+ sc_unsigned a( m_obj_p, m_left, m_right );
+ return a.to_double();
+}
+
+
+// explicit conversion to character string
+
+const std::string
+sc_signed_subref_r::to_string( sc_numrep numrep ) const
+{
+ sc_unsigned a( length() );
+ a = *this;
+ return a.to_string( numrep );
+}
+
+const std::string
+sc_signed_subref_r::to_string( sc_numrep numrep, bool w_prefix ) const
+{
+ sc_unsigned a( length() );
+ a = *this;
+ return a.to_string( numrep, w_prefix );
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_signed_subref
+//
+// Proxy class for sc_signed part selection (r-value and l-value).
+// ----------------------------------------------------------------------------
+
+// assignment operators
+
+const sc_signed_subref&
+sc_signed_subref::operator = ( const sc_signed_subref_r& a )
+{
+ return operator = ( (sc_unsigned)( a ) );
+}
+
+const sc_signed_subref&
+sc_signed_subref::operator = ( const sc_signed_subref& v )
+{
+ if( this == &v ) {
+ return *this;
+ }
+ return operator = ( (sc_unsigned)( v ) );
+}
+
+const sc_signed_subref&
+sc_signed_subref::operator = ( const sc_signed& v )
+{
+ int i;
+ int l = sc_min( m_left, v.nbits - 1 + m_right );
+
+ for( i = m_right; i <= l; ++ i ) m_obj_p->set( i, v.test( i - m_right ) );
+ for ( ; i <= m_left; i++ ) m_obj_p->set( i, v.test( l ) );
+
+ return *this;
+}
+
+const sc_signed_subref&
+sc_signed_subref::operator = ( const sc_unsigned_subref_r& v )
+{
+ return operator = ( (sc_unsigned)( v ) );
+}
+
+const sc_signed_subref&
+sc_signed_subref::operator = ( const sc_unsigned& v )
+{
+ int i;
+ int l = sc_min( m_left, v.nbits - 1 + m_right );
+
+ for( i = m_right; i <= l; ++ i ) m_obj_p->set( i, v.test( i - m_right ) );
+ for ( ; i <= m_left; i++ ) m_obj_p->set( i, 0 );
+ return *this;
+}
+
+const sc_signed_subref&
+sc_signed_subref::operator = ( unsigned long v )
+{
+ for( int i = m_right; i <= m_left; ++ i ) {
+ m_obj_p->set( i, static_cast<bool>( v & 1 ) );
+ v >>= 1;
+ }
+ return *this;
+}
+
+const sc_signed_subref&
+sc_signed_subref::operator = ( long v )
+{
+ unsigned long v2 = (unsigned long) v;
+ for( int i = m_right; i <= m_left; ++ i ) {
+ m_obj_p->set( i, static_cast<bool>( v2 & 1 ) );
+ v2 >>= 1;
+ }
+ return *this;
+}
+
+const sc_signed_subref&
+sc_signed_subref::operator = ( uint64 v )
+{
+ for( int i = m_right; i <= m_left; ++ i ) {
+ m_obj_p->set( i, static_cast<bool>( v & 1 ) );
+ v >>= 1;
+ }
+ return *this;
+}
+
+const sc_signed_subref&
+sc_signed_subref::operator = ( int64 v )
+{
+ uint64 v2 = (uint64) v;
+ for( int i = m_right; i <= m_left; ++ i ) {
+ m_obj_p->set( i, static_cast<bool>( v2 & 1 ) );
+ v2 >>= 1;
+ }
+ return *this;
+}
+
+const sc_signed_subref&
+sc_signed_subref::operator = ( double v )
+{
+ is_bad_double(v);
+
+ int nb = m_left - m_right + 1;
+ int nd = DIV_CEIL(nb);
+
+#ifdef SC_MAX_NBITS
+ sc_digit d[MAX_NDIGITS];
+#else
+ sc_digit *d = new sc_digit[nd];
+#endif
+
+ if (v < 0)
+ v = -v;
+
+ int i = 0;
+
+ while (floor(v) && (i < nd)) {
+#ifndef _WIN32
+ d[i++] = (sc_digit) floor(remainder(v, DIGIT_RADIX));
+#else
+ d[i++] = (sc_digit) floor(fmod(v, DIGIT_RADIX));
+#endif
+ v /= DIGIT_RADIX;
+ }
+
+ vec_zero(i, nd, d);
+
+ sc_digit val = 1; // Bit value.
+ int j = 0; // Current digit in d.
+
+ i = 0; // Current bit in d.
+
+ while (i < nb) {
+
+ m_obj_p->set(i + m_right, (bool) (d[j] & val));
+
+ ++i;
+
+ if (i % BITS_PER_DIGIT == 0) {
+ val = 1;
+ ++j;
+ }
+ else
+ val <<= 1;
+ }
+
+#ifndef SC_MAX_NBITS
+ delete [] d;
+#endif
+
+ return *this;
+}
+
+const sc_signed_subref&
+sc_signed_subref::operator = ( const sc_int_base& a )
+{
+ return operator = ( (int64) a );
+}
+
+const sc_signed_subref&
+sc_signed_subref::operator = ( const sc_uint_base& a )
+{
+ return operator = ( (uint64) a );
+}
+
+// concatenation methods
+
+
+void sc_signed_subref::concat_set( int64 src, int low_i )
+{
+ int i;
+ int l;
+ bool sign = src < 0;
+
+ if ( low_i < 64 )
+ {
+ src = src >> low_i;
+ l = sc_min( m_left, (63-low_i) + m_right );
+ for( i = m_right; i <= l; ++ i ) {
+ m_obj_p->set( i, src & 1 );
+ src = src >> 1;
+ }
+ for ( ; i <= m_left; i++ ) m_obj_p->set(i, sign);
+ }
+ else
+ {
+ for( i = m_right; i <= m_left; ++ i ) m_obj_p->set(i, sign);
+ }
+}
+
+void sc_signed_subref::concat_set( const sc_signed& src, int low_i )
+{
+ int i;
+ int l;
+ int src_i;
+ bool sign = src.test(src.nbits-1);
+ l = src.nbits - (low_i+1);
+ if ( l >= 0 )
+ {
+ l = sc_min( m_left, l + m_right );
+ src_i = low_i;
+ for( i = m_right; i <= l; ++ i, src_i++ ) {
+ m_obj_p->set( i, src.test( src_i ) );
+ }
+ for ( ; i <= m_left; i++ ) m_obj_p->set(i, sign);
+ }
+ else
+ {
+ for( i = m_right; i <= m_left; ++ i ) m_obj_p->set(i, sign);
+ }
+}
+
+void sc_signed_subref::concat_set( const sc_unsigned& src, int low_i )
+{
+ int i;
+ int l;
+ int src_i;
+ l = src.nbits - (low_i+2);
+ if ( l >= 0 )
+ {
+ l = sc_min( m_left, l + m_right );
+ src_i = low_i;
+ for( i = m_right; i <= l; ++ i, src_i++ ) {
+ m_obj_p->set( i, src.test( src_i ) );
+ }
+ for ( ; i <= m_left; i++ ) m_obj_p->set(false);
+ }
+ else
+ {
+ for( i = m_right; i <= m_left; ++ i ) m_obj_p->set(false);
+ }
+}
+
+void sc_signed_subref::concat_set( uint64 src, int low_i )
+{
+ int i;
+ int l;
+
+ if ( low_i < 64 )
+ {
+ src = src >> low_i;
+ l = sc_min( m_left, (63-low_i) + m_right );
+ for( i = m_right; i <= l; ++ i ) {
+ m_obj_p->set( i, src & 1 );
+ src = src >> 1;
+ }
+ for ( ; i <= m_left; i++ ) m_obj_p->set(false);
+ }
+ else
+ {
+ for( i = m_right; i <= m_left; ++ i ) m_obj_p->set(false);
+ }
+}
+// other methods
+
+void
+sc_signed_subref::scan( ::std::istream& is )
+{
+ std::string s;
+ is >> s;
+ *this = s.c_str();
+}
+
+
+// End of file
diff --git a/ext/systemc/src/sysc/datatypes/int/sc_uint.h b/ext/systemc/src/sysc/datatypes/int/sc_uint.h
new file mode 100644
index 000000000..90ebd7f97
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/int/sc_uint.h
@@ -0,0 +1,312 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_uint.h -- A sc_uint is an unsigned integer whose length is less than the
+ machine's native integer length. We provide two implementations
+ (i) sc_uint with length between 1 - 64, and (ii) sc_uint with
+ length between 1 - 32. Implementation (i) is the default
+ implementation, while implementation (ii) can be used only if
+ compiled with -D_32BIT_. Unlike arbitrary precision, arithmetic
+ and bitwise operations are performed using the native types
+ (hence capped at 32/64 bits). The sc_uint integer is useful
+ when the user does not need arbitrary precision and the
+ performance is superior to sc_bigint/sc_biguint.
+
+ Original Author: Amit Rao, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc.
+ Description of Modification: - Resolved ambiguity with sc_(un)signed.
+ - Merged the code for 64- and 32-bit versions
+ via the constants in sc_nbdefs.h.
+ - Eliminated redundant file inclusions.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_uint.h,v $
+// Revision 1.2 2011/02/18 20:19:15 acg
+// Andy Goodrich: updating Copyright notice.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:49:32 acg
+// Added $Log command so that CVS check in comments are reproduced in the
+// source.
+//
+
+#ifndef SC_UINT_H
+#define SC_UINT_H
+
+
+#include "sysc/datatypes/int/sc_uint_base.h"
+
+
+namespace sc_dt
+{
+
+// classes defined in this module
+template <int W> class sc_uint;
+
+
+// ----------------------------------------------------------------------------
+// CLASS TEMPLATE : sc_uint<W>
+//
+// Template class sc_uint<W> is the interface that the user sees. It
+// is derived from sc_uint_base and most of its methods are just
+// wrappers that call the corresponding method in the parent
+// class. Note that the length of sc_uint datatype is specified as a
+// template parameter.
+// ----------------------------------------------------------------------------
+
+template <int W>
+class sc_uint
+ : public sc_uint_base
+{
+public:
+
+ // constructors
+
+ sc_uint()
+ : sc_uint_base( W )
+ {}
+
+ sc_uint( uint_type v )
+ : sc_uint_base( v, W )
+ {}
+
+ sc_uint( const sc_uint<W>& a )
+ : sc_uint_base( a )
+ {}
+
+ sc_uint( const sc_uint_base& a )
+ : sc_uint_base( W )
+ { sc_uint_base::operator = ( a ); }
+
+ sc_uint( const sc_uint_subref_r& a )
+ : sc_uint_base( W )
+ { sc_uint_base::operator = ( a ); }
+
+ template< class T >
+ sc_uint( const sc_generic_base<T>& a )
+ : sc_uint_base( W )
+ { sc_uint_base::operator = ( a ); }
+
+ sc_uint( const sc_signed& a )
+ : sc_uint_base( W )
+ { sc_uint_base::operator = ( a ); }
+
+ sc_uint( const sc_unsigned& a )
+ : sc_uint_base( W )
+ { sc_uint_base::operator = ( a ); }
+
+#ifdef SC_INCLUDE_FX
+
+ explicit sc_uint( const sc_fxval& a )
+ : sc_uint_base( W )
+ { sc_uint_base::operator = ( a ); }
+
+ explicit sc_uint( const sc_fxval_fast& a )
+ : sc_uint_base( W )
+ { sc_uint_base::operator = ( a ); }
+
+ explicit sc_uint( const sc_fxnum& a )
+ : sc_uint_base( W )
+ { sc_uint_base::operator = ( a ); }
+
+ explicit sc_uint( const sc_fxnum_fast& a )
+ : sc_uint_base( W )
+ { sc_uint_base::operator = ( a ); }
+
+#endif
+
+ sc_uint( const sc_bv_base& a )
+ : sc_uint_base( W )
+ { sc_uint_base::operator = ( a ); }
+
+ sc_uint( const sc_lv_base& a )
+ : sc_uint_base( W )
+ { sc_uint_base::operator = ( a ); }
+
+ sc_uint( const char* a )
+ : sc_uint_base( W )
+ { sc_uint_base::operator = ( a ); }
+
+ sc_uint( unsigned long a )
+ : sc_uint_base( W )
+ { sc_uint_base::operator = ( a ); }
+
+ sc_uint( long a )
+ : sc_uint_base( W )
+ { sc_uint_base::operator = ( a ); }
+
+ sc_uint( unsigned int a )
+ : sc_uint_base( W )
+ { sc_uint_base::operator = ( a ); }
+
+ sc_uint( int a )
+ : sc_uint_base( W )
+ { sc_uint_base::operator = ( a ); }
+
+ sc_uint( int64 a )
+ : sc_uint_base( W )
+ { sc_uint_base::operator = ( a ); }
+
+ sc_uint( double a )
+ : sc_uint_base( W )
+ { sc_uint_base::operator = ( a ); }
+
+
+ // assignment operators
+
+ sc_uint<W>& operator = ( uint_type v )
+ { sc_uint_base::operator = ( v ); return *this; }
+
+ sc_uint<W>& operator = ( const sc_uint_base& a )
+ { sc_uint_base::operator = ( a ); return *this; }
+
+ sc_uint<W>& operator = ( const sc_uint_subref_r& a )
+ { sc_uint_base::operator = ( a ); return *this; }
+
+ sc_uint<W>& operator = ( const sc_uint<W>& a )
+ { m_val = a.m_val; return *this; }
+
+ template<class T>
+ sc_uint<W>& operator = ( const sc_generic_base<T>& a )
+ { sc_uint_base::operator = ( a ); return *this; }
+
+ sc_uint<W>& operator = ( const sc_signed& a )
+ { sc_uint_base::operator = ( a ); return *this; }
+
+ sc_uint<W>& operator = ( const sc_unsigned& a )
+ { sc_uint_base::operator = ( a ); return *this; }
+
+#ifdef SC_INCLUDE_FX
+
+ sc_uint<W>& operator = ( const sc_fxval& a )
+ { sc_uint_base::operator = ( a ); return *this; }
+
+ sc_uint<W>& operator = ( const sc_fxval_fast& a )
+ { sc_uint_base::operator = ( a ); return *this; }
+
+ sc_uint<W>& operator = ( const sc_fxnum& a )
+ { sc_uint_base::operator = ( a ); return *this; }
+
+ sc_uint<W>& operator = ( const sc_fxnum_fast& a )
+ { sc_uint_base::operator = ( a ); return *this; }
+
+#endif
+
+ sc_uint<W>& operator = ( const sc_bv_base& a )
+ { sc_uint_base::operator = ( a ); return *this; }
+
+ sc_uint<W>& operator = ( const sc_lv_base& a )
+ { sc_uint_base::operator = ( a ); return *this; }
+
+ sc_uint<W>& operator = ( const char* a )
+ { sc_uint_base::operator = ( a ); return *this; }
+
+ sc_uint<W>& operator = ( unsigned long a )
+ { sc_uint_base::operator = ( a ); return *this; }
+
+ sc_uint<W>& operator = ( long a )
+ { sc_uint_base::operator = ( a ); return *this; }
+
+ sc_uint<W>& operator = ( unsigned int a )
+ { sc_uint_base::operator = ( a ); return *this; }
+
+ sc_uint<W>& operator = ( int a )
+ { sc_uint_base::operator = ( a ); return *this; }
+
+ sc_uint<W>& operator = ( int64 a )
+ { sc_uint_base::operator = ( a ); return *this; }
+
+ sc_uint<W>& operator = ( double a )
+ { sc_uint_base::operator = ( a ); return *this; }
+
+
+ // arithmetic assignment operators
+
+ sc_uint<W>& operator += ( uint_type v )
+ { sc_uint_base::operator += ( v ); return *this; }
+
+ sc_uint<W>& operator -= ( uint_type v )
+ { sc_uint_base::operator -= ( v ); return *this; }
+
+ sc_uint<W>& operator *= ( uint_type v )
+ { sc_uint_base::operator *= ( v ); return *this; }
+
+ sc_uint<W>& operator /= ( uint_type v )
+ { sc_uint_base::operator /= ( v ); return *this; }
+
+ sc_uint<W>& operator %= ( uint_type v )
+ { sc_uint_base::operator %= ( v ); return *this; }
+
+
+ // bitwise assignment operators
+
+ sc_uint<W>& operator &= ( uint_type v )
+ { sc_uint_base::operator &= ( v ); return *this; }
+
+ sc_uint<W>& operator |= ( uint_type v )
+ { sc_uint_base::operator |= ( v ); return *this; }
+
+ sc_uint<W>& operator ^= ( uint_type v )
+ { sc_uint_base::operator ^= ( v ); return *this; }
+
+
+ sc_uint<W>& operator <<= ( uint_type v )
+ { sc_uint_base::operator <<= ( v ); return *this; }
+
+ sc_uint<W>& operator >>= ( uint_type v )
+ { sc_uint_base::operator >>= ( v ); return *this; }
+
+
+ // prefix and postfix increment and decrement operators
+
+ sc_uint<W>& operator ++ () // prefix
+ { sc_uint_base::operator ++ (); return *this; }
+
+ const sc_uint<W> operator ++ ( int ) // postfix
+ { return sc_uint<W>( sc_uint_base::operator ++ ( 0 ) ); }
+
+ sc_uint<W>& operator -- () // prefix
+ { sc_uint_base::operator -- (); return *this; }
+
+ const sc_uint<W> operator -- ( int ) // postfix
+ { return sc_uint<W>( sc_uint_base::operator -- ( 0 ) ); }
+};
+
+} // namespace sc_dt
+
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/int/sc_uint_base.cpp b/ext/systemc/src/sysc/datatypes/int/sc_uint_base.cpp
new file mode 100644
index 000000000..e3a12e4e0
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/int/sc_uint_base.cpp
@@ -0,0 +1,727 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_uint_base.cpp -- contains interface definitions between sc_uint and
+ sc_signed, sc_unsigned, and definitions for sc_uint_subref.
+
+ Original Author: Ali Dasdan, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// $Log: sc_uint_base.cpp,v $
+// Revision 1.5 2011/02/18 20:19:15 acg
+// Andy Goodrich: updating Copyright notice.
+//
+// Revision 1.4 2010/02/04 22:23:29 acg
+// Andy Goodrich: fixed bug in concatenation reads for part selections,
+// the mask being used was 32 bits and should have been 64 bits.
+//
+// Revision 1.3 2008/06/19 17:47:57 acg
+// Andy Goodrich: fixes for bugs. See 2.2.1 RELEASENOTES.
+//
+// Revision 1.2 2007/11/04 21:27:00 acg
+// Andy Goodrich: changes to make sure the proper value is returned from
+// concat_get_data().
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:49:32 acg
+// Added $Log command so that CVS check in comments are reproduced in the
+// source.
+//
+
+#include "sysc/kernel/sc_macros.h"
+#include "sysc/datatypes/int/sc_signed.h"
+#include "sysc/datatypes/int/sc_unsigned.h"
+#include "sysc/datatypes/int/sc_uint_base.h"
+#include "sysc/datatypes/int/sc_int_ids.h"
+#include "sysc/datatypes/bit/sc_bv_base.h"
+#include "sysc/datatypes/bit/sc_lv_base.h"
+#include "sysc/datatypes/misc/sc_concatref.h"
+#include "sysc/datatypes/fx/sc_ufix.h"
+#include "sysc/datatypes/fx/scfx_other_defs.h"
+
+
+namespace sc_dt
+{
+
+// to avoid code bloat in sc_uint_concat<T1,T2>
+
+void
+sc_uint_concref_invalid_length( int length )
+{
+ char msg[BUFSIZ];
+ std::sprintf( msg,
+ "sc_uint_concref<T1,T2> initialization: length = %d "
+ "violates 1 <= length <= %d",
+ length, SC_INTWIDTH );
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
+}
+
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_uint_bitref
+//
+// Proxy class for sc_uint bit selection (r-value and l-value).
+// ----------------------------------------------------------------------------
+
+sc_core::sc_vpool<sc_uint_bitref> sc_uint_bitref::m_pool(9);
+
+// concatenation methods:
+
+// #### OPTIMIZE
+void sc_uint_bitref::concat_set(int64 src, int low_i)
+{
+ sc_uint_base aa( 1 );
+ *this = aa = (low_i < 64) ? src >> low_i : src >> 63;
+}
+
+void sc_uint_bitref::concat_set(const sc_signed& src, int low_i)
+{
+ sc_uint_base aa( 1 );
+ if ( low_i < src.length() )
+ *this = aa = 1 & (src >> low_i);
+ else
+ *this = aa = (src < 0) ? (int_type)-1 : 0;
+}
+
+void sc_uint_bitref::concat_set(const sc_unsigned& src, int low_i)
+{
+ sc_uint_base aa( 1 );
+ if ( low_i < src.length() )
+ *this = aa = 1 & (src >> low_i);
+ else
+ *this = aa = 0;
+}
+
+void sc_uint_bitref::concat_set(uint64 src, int low_i)
+{
+ sc_uint_base aa( 1 );
+ *this = aa = (low_i < 64) ? src >> low_i : 0;
+}
+
+
+// other methods
+
+void
+sc_uint_bitref::scan( ::std::istream& is )
+{
+ bool b;
+ is >> b;
+ *this = b;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_uint_subref_r
+//
+// Proxy class for sc_uint part selection (l-value).
+// ----------------------------------------------------------------------------
+
+bool sc_uint_subref_r::concat_get_ctrl( sc_digit* dst_p, int low_i ) const
+{
+ int dst_i; // Word in dst_p now processing.
+ int end_i; // Highest order word in dst_p to process.
+ int left_shift; // Left shift for val.
+ uint_type mask; // Mask for bits to extract or keep.
+
+ dst_i = low_i / BITS_PER_DIGIT;
+ left_shift = low_i % BITS_PER_DIGIT;
+ end_i = (low_i + (m_left-m_right)) / BITS_PER_DIGIT;
+
+ mask = ~(-1 << left_shift);
+ dst_p[dst_i] = (sc_digit)((dst_p[dst_i] & mask));
+
+ dst_i++;
+ for ( ; dst_i <= end_i; dst_i++ ) dst_p[dst_i] = 0;
+
+ return false;
+}
+
+bool sc_uint_subref_r::concat_get_data( sc_digit* dst_p, int low_i ) const
+{
+ int dst_i; // Word in dst_p now processing.
+ int end_i; // Highest order word in dst_p to process.
+ int high_i; // Index of high order bit in dst_p to set.
+ int left_shift; // Left shift for val.
+ uint_type mask; // Mask for bits to extract or keep.
+ bool result; // True if inserting non-zero value.
+ uint_type val; // Selection value extracted from m_obj_p.
+
+ dst_i = low_i / BITS_PER_DIGIT;
+ left_shift = low_i % BITS_PER_DIGIT;
+ high_i = low_i + (m_left-m_right);
+ end_i = high_i / BITS_PER_DIGIT;
+ mask = ~mask_int[m_left][m_right];
+ val = (m_obj_p->m_val & mask) >> m_right;
+ result = val != 0;
+
+
+ // PROCESS THE FIRST WORD:
+
+ mask = ~(-1 << left_shift);
+ dst_p[dst_i] = (sc_digit)(((dst_p[dst_i] & mask)) |
+ ((val << left_shift) & DIGIT_MASK));
+
+ switch ( end_i - dst_i )
+ {
+ // BITS ARE ACROSS TWO WORDS:
+
+ case 1:
+ dst_i++;
+ val >>= (BITS_PER_DIGIT-left_shift);
+ dst_p[dst_i] = (sc_digit)val;
+ break;
+
+ // BITS ARE ACROSS THREE WORDS:
+
+ case 2:
+ dst_i++;
+ val >>= (BITS_PER_DIGIT-left_shift);
+ dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
+ val >>= BITS_PER_DIGIT;
+ dst_p[dst_i] = (sc_digit)val;
+ break;
+
+ // BITS ARE ACROSS THREE WORDS:
+
+ case 3:
+ dst_i++;
+ val >>= (BITS_PER_DIGIT-left_shift);
+ dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
+ val >>= BITS_PER_DIGIT;
+ dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
+ val >>= BITS_PER_DIGIT;
+ dst_p[dst_i] = (sc_digit)val;
+ break;
+ }
+ return result;
+}
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_uint_subref
+//
+// Proxy class for sc_uint part selection (r-value and l-value).
+// ----------------------------------------------------------------------------
+
+sc_core::sc_vpool<sc_uint_subref> sc_uint_subref::m_pool(9);
+
+// assignment operators
+
+sc_uint_subref&
+sc_uint_subref::operator = ( uint_type v )
+{
+ uint_type val = m_obj_p->m_val;
+ uint_type mask = mask_int[m_left][m_right];
+ val &= mask;
+ val |= (v << m_right) & ~mask;
+ m_obj_p->m_val = val;
+ m_obj_p->extend_sign();
+ return *this;
+}
+
+sc_uint_subref&
+sc_uint_subref::operator = ( const sc_signed& a )
+{
+ sc_uint_base aa( length() );
+ return ( *this = aa = a );
+}
+
+sc_uint_subref&
+sc_uint_subref::operator = ( const sc_unsigned& a )
+{
+ sc_uint_base aa( length() );
+ return ( *this = aa = a );
+}
+
+sc_uint_subref&
+sc_uint_subref::operator = ( const sc_bv_base& a )
+{
+ sc_uint_base aa( length() );
+ return ( *this = aa = a );
+}
+
+sc_uint_subref&
+sc_uint_subref::operator = ( const sc_lv_base& a )
+{
+ sc_uint_base aa( length() );
+ return ( *this = aa = a );
+}
+
+// concatenation methods:
+
+// #### OPTIMIZE
+void sc_uint_subref::concat_set(int64 src, int low_i)
+{
+ sc_uint_base aa( length() );
+ *this = aa = (low_i < 64) ? src >> low_i : src >> 63;
+}
+
+void sc_uint_subref::concat_set(const sc_signed& src, int low_i)
+{
+ sc_uint_base aa( length() );
+ if ( low_i < src.length() )
+ *this = aa = src >> low_i;
+ else
+ *this = aa = (src < 0) ? (int_type)-1 : 0;
+}
+
+void sc_uint_subref::concat_set(const sc_unsigned& src, int low_i)
+{
+ sc_uint_base aa( length() );
+ if ( low_i < src.length() )
+ *this = aa = src >> low_i;
+ else
+ *this = aa = 0;
+}
+
+void sc_uint_subref::concat_set(uint64 src, int low_i)
+{
+ sc_uint_base aa( length() );
+ *this = aa = (low_i < 64) ? src >> low_i : 0;
+}
+
+// other methods
+
+void
+sc_uint_subref::scan( ::std::istream& is )
+{
+ std::string s;
+ is >> s;
+ *this = s.c_str();
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_uint_base
+//
+// Base class for sc_uint.
+// ----------------------------------------------------------------------------
+
+// support methods
+
+void
+sc_uint_base::invalid_length() const
+{
+ char msg[BUFSIZ];
+ std::sprintf( msg,
+ "sc_uint[_base] initialization: length = %d violates "
+ "1 <= length <= %d",
+ m_len, SC_INTWIDTH );
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
+}
+
+void
+sc_uint_base::invalid_index( int i ) const
+{
+ char msg[BUFSIZ];
+ std::sprintf( msg,
+ "sc_uint[_base] bit selection: index = %d violates "
+ "0 <= index <= %d",
+ i, m_len - 1 );
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
+}
+
+void
+sc_uint_base::invalid_range( int l, int r ) const
+{
+ char msg[BUFSIZ];
+ std::sprintf( msg,
+ "sc_uint[_base] part selection: left = %d, right = %d violates "
+ "%d >= left >= right >= 0",
+ l, r, m_len - 1 );
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
+}
+
+
+void
+sc_uint_base::check_value() const
+{
+ uint_type limit = (~UINT_ZERO >> m_ulen);
+ if( m_val > limit ) {
+ char msg[BUFSIZ];
+ std::sprintf( msg, "sc_uint[_base]: value does not fit into a length of %d",
+ m_len );
+ SC_REPORT_WARNING( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
+ }
+}
+
+
+// constructors
+
+sc_uint_base::sc_uint_base( const sc_bv_base& v )
+ : m_val(0), m_len( v.length() ), m_ulen( SC_INTWIDTH - m_len )
+{
+ check_length();
+ *this = v;
+}
+sc_uint_base::sc_uint_base( const sc_lv_base& v )
+ : m_val(0), m_len( v.length() ), m_ulen( SC_INTWIDTH - m_len )
+{
+ check_length();
+ *this = v;
+}
+sc_uint_base::sc_uint_base( const sc_int_subref_r& v )
+ : m_val(0), m_len( v.length() ), m_ulen( SC_INTWIDTH - m_len )
+{
+ check_length();
+ *this = v.to_uint64();
+}
+sc_uint_base::sc_uint_base( const sc_signed_subref_r& v )
+ : m_val(0), m_len( v.length() ), m_ulen( SC_INTWIDTH - m_len )
+{
+ check_length();
+ *this = v.to_uint64();
+}
+sc_uint_base::sc_uint_base( const sc_unsigned_subref_r& v )
+ : m_val(0), m_len( v.length() ), m_ulen( SC_INTWIDTH - m_len )
+{
+ check_length();
+ *this = v.to_uint64();
+}
+
+sc_uint_base::sc_uint_base( const sc_signed& a )
+ : m_val( 0 ), m_len( a.length() ), m_ulen( SC_INTWIDTH - m_len )
+{
+ check_length();
+#if 0
+ for( int i = m_len - 1; i >= 0; -- i ) {
+ set( i, a.test( i ) );
+ }
+ extend_sign();
+#else
+ *this = a.to_uint64();
+#endif
+}
+
+sc_uint_base::sc_uint_base( const sc_unsigned& a )
+ : m_val( 0 ), m_len( a.length() ), m_ulen( SC_INTWIDTH - m_len )
+{
+ check_length();
+#if 0
+ for( int i = m_len - 1; i >= 0; -- i ) {
+ set( i, a.test( i ) );
+ }
+ extend_sign();
+#else
+ *this = a.to_uint64();
+#endif
+}
+
+// assignment operators
+
+sc_uint_base&
+sc_uint_base::operator = ( const sc_signed& a )
+{
+ int minlen = sc_min( m_len, a.length() );
+ int i = 0;
+ for( ; i < minlen; ++ i ) {
+ set( i, a.test( i ) );
+ }
+ bool sgn = a.sign();
+ for( ; i < m_len; ++ i ) {
+ // sign extension
+ set( i, sgn );
+ }
+ extend_sign();
+ return *this;
+}
+
+sc_uint_base&
+sc_uint_base::operator = ( const sc_unsigned& a )
+{
+ int minlen = sc_min( m_len, a.length() );
+ int i = 0;
+ for( ; i < minlen; ++ i ) {
+ set( i, a.test( i ) );
+ }
+ for( ; i < m_len; ++ i ) {
+ // zero extension
+ set( i, 0 );
+ }
+ extend_sign();
+ return *this;
+}
+
+
+sc_uint_base&
+sc_uint_base::operator = ( const sc_bv_base& a )
+{
+ int minlen = sc_min( m_len, a.length() );
+ int i = 0;
+ for( ; i < minlen; ++ i ) {
+ set( i, a.get_bit( i ) );
+ }
+ for( ; i < m_len; ++ i ) {
+ // zero extension
+ set( i, 0 );
+ }
+ extend_sign();
+ return *this;
+}
+
+sc_uint_base&
+sc_uint_base::operator = ( const sc_lv_base& a )
+{
+ int minlen = sc_min( m_len, a.length() );
+ int i = 0;
+ for( ; i < minlen; ++ i ) {
+ set( i, sc_logic( a.get_bit( i ) ).to_bool() );
+ }
+ for( ; i < m_len; ++ i ) {
+ // zero extension
+ set( i, 0 );
+ }
+ extend_sign();
+ return *this;
+}
+
+sc_uint_base&
+sc_uint_base::operator = ( const char* a )
+{
+ if( a == 0 ) {
+ SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_,
+ "character string is zero" );
+ }
+ if( *a == 0 ) {
+ SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_,
+ "character string is empty" );
+ }
+ try {
+ int len = m_len;
+ sc_ufix aa( a, len, len, SC_TRN, SC_WRAP, 0, SC_ON );
+ return this->operator = ( aa );
+ } catch( sc_core::sc_report ) {
+ char msg[BUFSIZ];
+ std::sprintf( msg, "character string '%s' is not valid", a );
+ SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
+ // never reached
+ return *this;
+ }
+}
+
+
+// explicit conversion to character string
+
+const std::string
+sc_uint_base::to_string( sc_numrep numrep ) const
+{
+ int len = m_len;
+ sc_ufix aa( *this, len, len, SC_TRN, SC_WRAP, 0, SC_ON );
+ return aa.to_string( numrep );
+}
+
+const std::string
+sc_uint_base::to_string( sc_numrep numrep, bool w_prefix ) const
+{
+ int len = m_len;
+ sc_ufix aa( *this, len, len, SC_TRN, SC_WRAP, 0, SC_ON );
+ return aa.to_string( numrep, w_prefix );
+}
+
+
+// reduce methods
+
+bool
+sc_uint_base::and_reduce() const
+{
+ return ( m_val == (~UINT_ZERO >> m_ulen) );
+}
+
+bool
+sc_uint_base::or_reduce() const
+{
+ return ( m_val != uint_type( 0 ) );
+}
+
+bool
+sc_uint_base::xor_reduce() const
+{
+ uint_type mask = ~UINT_ZERO;
+ uint_type val = m_val;
+ int n = SC_INTWIDTH;
+ do {
+ n >>= 1;
+ mask >>= n;
+ val = ((val & (mask << n)) >> n) ^ (val & mask);
+ } while( n != 1 );
+ return ( val != uint_type( 0 ) );
+}
+
+
+bool sc_uint_base::concat_get_ctrl( sc_digit* dst_p, int low_i ) const
+{
+ int dst_i; // Word in dst_p now processing.
+ int end_i; // Highest order word in dst_p to process.
+ int left_shift; // Left shift for val.
+ uint_type mask; // Mask for bits to extract or keep.
+
+ dst_i = low_i / BITS_PER_DIGIT;
+ left_shift = low_i % BITS_PER_DIGIT;
+ end_i = (low_i + (m_len-1)) / BITS_PER_DIGIT;
+
+ // PROCESS THE FIRST WORD:
+
+ mask = ~((uint_type)-1 << left_shift);
+ dst_p[dst_i] = (sc_digit)((dst_p[dst_i] & mask));
+
+ dst_i++;
+ for ( ; dst_i <= end_i; dst_i++ ) dst_p[dst_i] = 0;
+ return false;
+}
+
+//------------------------------------------------------------------------------
+//"sc_uint_base::concat_get_data"
+//
+// This method transfers the value of this object instance to the supplied
+// array of sc_unsigned digits starting with the bit specified by low_i within
+// the array of digits.
+//
+// Notes:
+// (1) we don't worry about masking the high order data we transfer since
+// concat_get_data() is called from low order bit to high order bit. So
+// the bits above where we place ours will be filled in by someone else.
+//
+// dst_p -> array of sc_unsigned digits to be filled in.
+// low_i = first bit within dst_p to be set.
+//------------------------------------------------------------------------------
+bool sc_uint_base::concat_get_data( sc_digit* dst_p, int low_i ) const
+{
+ int dst_i; // Word in dst_p now processing.
+ int end_i; // Highest order word in dst_p to process.
+ int high_i; // Index of high order bit in dst_p to set.
+ int left_shift; // Left shift for val.
+ uint_type mask; // Mask for bits to extract or keep.
+ bool result; // True if inserting non-zero value.
+ uint_type val; // Value for this object.
+
+ dst_i = low_i / BITS_PER_DIGIT;
+ left_shift = low_i % BITS_PER_DIGIT;
+ high_i = low_i + (m_len-1);
+ end_i = high_i / BITS_PER_DIGIT;
+ val = m_val;
+ result = val != 0;
+
+ // MASK OFF DATA TO BE TRANSFERRED BASE ON WIDTH:
+
+ if ( m_len < 64 )
+ {
+ mask = ~((uint_type)-1 << m_len);
+ val &= mask;
+ }
+
+ // PROCESS THE FIRST WORD:
+
+ mask = ~((uint_type)-1 << left_shift);
+ dst_p[dst_i] = (sc_digit)(((dst_p[dst_i] & mask)) |
+ ((val << left_shift) & DIGIT_MASK));
+
+ switch ( end_i - dst_i )
+ {
+ // BITS ARE ACROSS TWO WORDS:
+
+ case 1:
+ dst_i++;
+ val >>= (BITS_PER_DIGIT-left_shift);
+ dst_p[dst_i] = (sc_digit)val;
+ break;
+
+ // BITS ARE ACROSS THREE WORDS:
+
+ case 2:
+ dst_i++;
+ val >>= (BITS_PER_DIGIT-left_shift);
+ dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
+ val >>= BITS_PER_DIGIT;
+ dst_p[dst_i] = (sc_digit)val;
+ break;
+
+ // BITS ARE ACROSS FOUR WORDS:
+
+ case 3:
+ dst_i++;
+ val >>= (BITS_PER_DIGIT-left_shift);
+ dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
+ val >>= BITS_PER_DIGIT;
+ dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
+ val >>= BITS_PER_DIGIT;
+ dst_p[dst_i] = (sc_digit)val;
+ break;
+
+ }
+ return result;
+}
+
+// #### OPTIMIZE
+void sc_uint_base::concat_set(int64 src, int low_i)
+{
+ *this = (low_i < 64) ? src >> low_i : src >> 63;
+}
+
+void sc_uint_base::concat_set(const sc_signed& src, int low_i)
+{
+ if ( low_i < src.length() )
+ *this = src >> low_i;
+ else
+ *this = (src < 0) ? (int_type)-1 : 0;
+}
+
+void sc_uint_base::concat_set(const sc_unsigned& src, int low_i)
+{
+ if ( low_i < src.length() )
+ *this = src >> low_i;
+ else
+ *this = 0;
+}
+
+void sc_uint_base::concat_set(uint64 src, int low_i)
+{
+ *this = (low_i < 64) ? src >> low_i : 0;
+}
+
+
+// other methods
+
+void
+sc_uint_base::scan( ::std::istream& is )
+{
+ std::string s;
+ is >> s;
+ *this = s.c_str();
+}
+
+} // namespace sc_dt
+
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/int/sc_uint_base.h b/ext/systemc/src/sysc/datatypes/int/sc_uint_base.h
new file mode 100644
index 000000000..87fd92bc0
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/int/sc_uint_base.h
@@ -0,0 +1,1352 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_uint_base.h -- A sc_uint is an unsigned integer whose length is less than
+ the machine's native integer length. We provide two
+ implementations (i) sc_uint with length between 1 - 64, and (ii)
+ sc_uint with length between 1 - 32. Implementation (i) is the
+ default implementation, while implementation (ii) can be used
+ only if compiled with -D_32BIT_. Unlike arbitrary precision,
+ arithmetic and bitwise operations are performed using the native
+ types (hence capped at 32/64 bits). The sc_uint integer is
+ useful when the user does not need arbitrary precision and the
+ performance is superior to sc_bigint/sc_biguint.
+
+ Original Author: Amit Rao, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc.
+ Description of Modification: - Resolved ambiguity with sc_(un)signed.
+ - Merged the code for 64- and 32-bit versions
+ via the constants in sc_nbdefs.h.
+ - Eliminated redundant file inclusions.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_uint_base.h,v $
+// Revision 1.3 2011/08/24 22:05:46 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.2 2011/02/18 20:19:15 acg
+// Andy Goodrich: updating Copyright notice.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.4 2006/05/08 17:50:02 acg
+// Andy Goodrich: Added David Long's declarations for friend operators,
+// functions, and methods, to keep the Microsoft compiler happy.
+//
+// Revision 1.3 2006/01/13 18:49:32 acg
+// Added $Log command so that CVS check in comments are reproduced in the
+// source.
+//
+
+#ifndef SC_UINT_BASE_H
+#define SC_UINT_BASE_H
+
+
+#include "sysc/kernel/sc_object.h"
+#include "sysc/datatypes/misc/sc_value_base.h"
+#include "sysc/datatypes/int/sc_int_ids.h"
+#include "sysc/datatypes/int/sc_length_param.h"
+#include "sysc/datatypes/int/sc_nbdefs.h"
+#include "sysc/datatypes/fx/scfx_ieee.h"
+#include "sysc/utils/sc_iostream.h"
+#include "sysc/utils/sc_temporary.h"
+
+
+namespace sc_dt
+{
+
+class sc_concatref;
+
+// classes defined in this module
+class sc_uint_bitref_r;
+class sc_uint_bitref;
+class sc_uint_subref_r;
+class sc_uint_subref;
+class sc_uint_base;
+
+// forward class declarations
+class sc_bv_base;
+class sc_lv_base;
+class sc_int_subref_r;
+class sc_signed_subref_r;
+class sc_unsigned_subref_r;
+class sc_signed;
+class sc_unsigned;
+class sc_fxval;
+class sc_fxval_fast;
+class sc_fxnum;
+class sc_fxnum_fast;
+
+
+extern const uint_type mask_int[SC_INTWIDTH][SC_INTWIDTH];
+
+// friend operator declarations
+ inline bool operator == ( const sc_uint_base& a, const sc_uint_base& b );
+ inline bool operator != ( const sc_uint_base& a, const sc_uint_base& b );
+ inline bool operator < ( const sc_uint_base& a, const sc_uint_base& b );
+ inline bool operator <= ( const sc_uint_base& a, const sc_uint_base& b );
+ inline bool operator > ( const sc_uint_base& a, const sc_uint_base& b );
+ inline bool operator >= ( const sc_uint_base& a, const sc_uint_base& b );
+
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_uint_bitref_r
+//
+// Proxy class for sc_uint bit selection (r-value only).
+// ----------------------------------------------------------------------------
+
+class sc_uint_bitref_r : public sc_value_base
+{
+ friend class sc_uint_base;
+ friend class sc_uint_signal;
+
+
+ // constructors
+
+public:
+ sc_uint_bitref_r( const sc_uint_bitref_r& init ) :
+ sc_value_base(init), m_index(init.m_index), m_obj_p(init.m_obj_p)
+ {}
+
+protected:
+ sc_uint_bitref_r() : sc_value_base(), m_index(0), m_obj_p(0)
+ {}
+
+ // initializer for sc_core::sc_vpool:
+
+ void initialize( const sc_uint_base* obj_p, int index_ )
+ {
+ m_obj_p = (sc_uint_base*)obj_p;
+ m_index = index_;
+ }
+
+public:
+
+ // destructor
+
+ virtual ~sc_uint_bitref_r()
+ {}
+
+ // concatenation support
+
+ virtual int concat_length(bool* xz_present_p) const
+ { if ( xz_present_p ) *xz_present_p = false; return 1; }
+ virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const
+ {
+ int bit_mask = 1 << (low_i % BITS_PER_DIGIT);
+ int word_i = low_i / BITS_PER_DIGIT;
+
+ dst_p[word_i] &= ~bit_mask;
+ return false;
+ }
+ virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const
+ {
+ int bit_mask = 1 << (low_i % BITS_PER_DIGIT);
+ bool result; // True is non-zero.
+ int word_i = low_i / BITS_PER_DIGIT;
+
+ if ( operator uint64() )
+ {
+ dst_p[word_i] |= bit_mask;
+ result = true;
+ }
+ else
+ {
+ dst_p[word_i] &= ~bit_mask;
+ result = false;
+ }
+ return result;
+ }
+ virtual uint64 concat_get_uint64() const
+ { return operator uint64(); }
+
+ // capacity
+
+ int length() const
+ { return 1; }
+
+#ifdef SC_DT_DEPRECATED
+ int bitwidth() const
+ { return length(); }
+#endif
+
+
+ // implicit conversion to uint64
+
+ operator uint64 () const;
+ bool operator ! () const;
+ bool operator ~ () const;
+
+
+ // explicit conversions
+
+ uint64 value() const
+ { return operator uint64 (); }
+
+ bool to_bool() const
+ { return operator uint64 (); }
+
+
+ // other methods
+
+ void print( ::std::ostream& os = ::std::cout ) const
+ { os << to_bool(); }
+
+protected:
+
+ int m_index;
+ sc_uint_base* m_obj_p;
+
+private:
+
+ // disabled
+ sc_uint_bitref_r& operator = ( const sc_uint_bitref_r& );
+};
+
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream&, const sc_uint_bitref_r& );
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_uint_bitref
+//
+// Proxy class for sc_uint bit selection (r-value and l-value).
+// ----------------------------------------------------------------------------
+
+class sc_uint_bitref
+ : public sc_uint_bitref_r
+{
+ friend class sc_uint_base;
+ friend class sc_core::sc_vpool<sc_uint_bitref>;
+
+
+ // constructors
+
+protected:
+ sc_uint_bitref() : sc_uint_bitref_r()
+ {}
+public:
+ sc_uint_bitref( const sc_uint_bitref& init ) : sc_uint_bitref_r(init)
+ {}
+
+public:
+
+ // assignment operators
+
+ sc_uint_bitref& operator = ( const sc_uint_bitref_r& b );
+ sc_uint_bitref& operator = ( const sc_uint_bitref& b );
+ sc_uint_bitref& operator = ( bool b );
+
+ sc_uint_bitref& operator &= ( bool b );
+ sc_uint_bitref& operator |= ( bool b );
+ sc_uint_bitref& operator ^= ( bool b );
+
+ // concatenation methods
+
+ virtual void concat_set(int64 src, int low_i);
+ virtual void concat_set(const sc_signed& src, int low_i);
+ virtual void concat_set(const sc_unsigned& src, int low_i);
+ virtual void concat_set(uint64 src, int low_i);
+
+ // other methods
+
+ void scan( ::std::istream& is = ::std::cin );
+
+protected:
+ static sc_core::sc_vpool<sc_uint_bitref> m_pool;
+
+};
+
+
+
+inline
+::std::istream&
+operator >> ( ::std::istream&, sc_uint_bitref& );
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_uint_subref_r
+//
+// Proxy class for sc_uint part selection (r-value only).
+// ----------------------------------------------------------------------------
+
+class sc_uint_subref_r : public sc_value_base
+{
+ friend class sc_uint_base;
+ friend class sc_uint_subref;
+
+
+ // constructors
+
+public:
+ sc_uint_subref_r( const sc_uint_subref_r& init ) :
+ sc_value_base(init), m_left(init.m_left), m_obj_p(init.m_obj_p),
+ m_right(init.m_right)
+ {}
+
+protected:
+ sc_uint_subref_r() : sc_value_base(), m_left(0), m_obj_p(0), m_right(0)
+ {}
+
+ // initializer for sc_core::sc_vpool:
+
+ void initialize( const sc_uint_base* obj_p, int left_i, int right_i )
+ {
+ m_obj_p = (sc_uint_base*)obj_p;
+ m_left = left_i;
+ m_right = right_i;
+ }
+
+public:
+
+ // destructor
+
+ virtual ~sc_uint_subref_r()
+ {}
+
+ // capacity
+
+ int length() const
+ { return ( m_left - m_right + 1 ); }
+
+#ifdef SC_DT_DEPRECATED
+ int bitwidth() const
+ { return length(); }
+#endif
+
+ // concatenation support
+
+ virtual int concat_length(bool* xz_present_p) const
+ { if ( xz_present_p ) *xz_present_p = false; return length(); }
+ virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const;
+ virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const;
+ virtual uint64 concat_get_uint64() const
+ { return (uint64)operator uint_type(); }
+
+
+ // reduce methods
+
+ bool and_reduce() const;
+
+ bool nand_reduce() const
+ { return ( ! and_reduce() ); }
+
+ bool or_reduce() const;
+
+ bool nor_reduce() const
+ { return ( ! or_reduce() ); }
+
+ bool xor_reduce() const;
+
+ bool xnor_reduce() const
+ { return ( ! xor_reduce() ); }
+
+
+ // implicit conversion to uint_type
+
+ operator uint_type() const;
+
+
+ // explicit conversions
+
+ uint_type value() const
+ { return operator uint_type(); }
+
+
+ int to_int() const;
+ unsigned int to_uint() const;
+ long to_long() const;
+ unsigned long to_ulong() const;
+ int64 to_int64() const;
+ uint64 to_uint64() const;
+ double to_double() const;
+
+
+ // explicit conversion to character string
+
+ const std::string to_string( sc_numrep numrep = SC_DEC ) const;
+ const std::string to_string( sc_numrep numrep, bool w_prefix ) const;
+
+
+ // other methods
+
+ void print( ::std::ostream& os = ::std::cout ) const
+ { os << to_string(sc_io_base(os,SC_DEC),sc_io_show_base(os)); }
+
+protected:
+
+ int m_left;
+ sc_uint_base* m_obj_p;
+ int m_right;
+
+private:
+
+ // disabled
+ sc_uint_subref_r& operator = ( const sc_uint_subref_r& );
+};
+
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream&, const sc_uint_subref_r& );
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_uint_subref
+//
+// Proxy class for sc_uint part selection (r-value and l-value).
+// ----------------------------------------------------------------------------
+
+class sc_uint_subref
+ : public sc_uint_subref_r
+{
+ friend class sc_uint_base;
+ friend class sc_core::sc_vpool<sc_uint_subref>;
+
+
+ // constructors
+
+protected:
+ sc_uint_subref() : sc_uint_subref_r()
+ {}
+
+public:
+ sc_uint_subref( const sc_uint_subref& init ) : sc_uint_subref_r(init)
+ {}
+
+public:
+
+ // assignment operators
+
+ sc_uint_subref& operator = ( uint_type v );
+
+ sc_uint_subref& operator = ( const sc_uint_base& a );
+
+ sc_uint_subref& operator = ( const sc_uint_subref_r& a )
+ { return operator = ( a.operator uint_type() ); }
+
+ sc_uint_subref& operator = ( const sc_uint_subref& a )
+ { return operator = ( a.operator uint_type() ); }
+
+ template<class T>
+ sc_uint_subref& operator = ( const sc_generic_base<T>& a )
+ { return operator = ( a->to_uint64() ); }
+
+ sc_uint_subref& operator = ( const char* a );
+
+ sc_uint_subref& operator = ( unsigned long a )
+ { return operator = ( (uint_type) a ); }
+
+ sc_uint_subref& operator = ( long a )
+ { return operator = ( (uint_type) a ); }
+
+ sc_uint_subref& operator = ( unsigned int a )
+ { return operator = ( (uint_type) a ); }
+
+ sc_uint_subref& operator = ( int a )
+ { return operator = ( (uint_type) a ); }
+
+ sc_uint_subref& operator = ( int64 a )
+ { return operator = ( (uint_type) a ); }
+
+ sc_uint_subref& operator = ( double a )
+ { return operator = ( (uint_type) a ); }
+
+ sc_uint_subref& operator = ( const sc_signed& );
+ sc_uint_subref& operator = ( const sc_unsigned& );
+ sc_uint_subref& operator = ( const sc_bv_base& );
+ sc_uint_subref& operator = ( const sc_lv_base& );
+
+ // concatenation methods
+
+ virtual void concat_set(int64 src, int low_i);
+ virtual void concat_set(const sc_signed& src, int low_i);
+ virtual void concat_set(const sc_unsigned& src, int low_i);
+ virtual void concat_set(uint64 src, int low_i);
+
+ // other methods
+
+ void scan( ::std::istream& is = ::std::cin );
+
+protected:
+ static sc_core::sc_vpool<sc_uint_subref> m_pool;
+
+};
+
+
+
+inline
+::std::istream&
+operator >> ( ::std::istream&, sc_uint_subref& );
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_uint_base
+//
+// Base class for sc_uint.
+// ----------------------------------------------------------------------------
+
+class sc_uint_base : public sc_value_base
+{
+ friend class sc_uint_bitref_r;
+ friend class sc_uint_bitref;
+ friend class sc_uint_subref_r;
+ friend class sc_uint_subref;
+
+
+ // support methods
+
+ void invalid_length() const;
+ void invalid_index( int i ) const;
+ void invalid_range( int l, int r ) const;
+
+ void check_length() const
+ { if( m_len <= 0 || m_len > SC_INTWIDTH ) { invalid_length(); } }
+
+ void check_index( int i ) const
+ { if( i < 0 || i >= m_len ) { invalid_index( i ); } }
+
+ void check_range( int l, int r ) const
+ { if( r < 0 || l >= m_len || l < r ) { invalid_range( l, r ); } }
+
+ void check_value() const;
+
+ void extend_sign()
+ {
+#ifdef DEBUG_SYSTEMC
+ check_value();
+#endif
+ m_val &= ( ~UINT_ZERO >> m_ulen );
+ }
+
+public:
+
+ // constructors
+
+ explicit sc_uint_base( int w = sc_length_param().len() )
+ : m_val( 0 ), m_len( w ), m_ulen( SC_INTWIDTH - m_len )
+ { check_length(); }
+
+ sc_uint_base( uint_type v, int w )
+ : m_val( v ), m_len( w ), m_ulen( SC_INTWIDTH - m_len )
+ { check_length(); extend_sign(); }
+
+ sc_uint_base( const sc_uint_base& a )
+ : sc_value_base(a), m_val(a.m_val), m_len(a.m_len), m_ulen(a.m_ulen)
+ {}
+
+ explicit sc_uint_base( const sc_uint_subref_r& a )
+ : m_val( a ), m_len( a.length() ), m_ulen( SC_INTWIDTH - m_len )
+ { extend_sign(); }
+
+ template<class T>
+ explicit sc_uint_base( const sc_generic_base<T>& a )
+ : m_val( a->to_uint64() ), m_len( a->length() ),
+ m_ulen( SC_INTWIDTH - m_len )
+ { check_length(); extend_sign(); }
+
+ explicit sc_uint_base( const sc_bv_base& v );
+ explicit sc_uint_base( const sc_lv_base& v );
+ explicit sc_uint_base( const sc_int_subref_r& v );
+ explicit sc_uint_base( const sc_signed_subref_r& v );
+ explicit sc_uint_base( const sc_unsigned_subref_r& v );
+ explicit sc_uint_base( const sc_signed& a );
+ explicit sc_uint_base( const sc_unsigned& a );
+
+
+ // destructor
+
+ virtual ~sc_uint_base()
+ {}
+
+
+ // assignment operators
+
+ sc_uint_base& operator = ( uint_type v )
+ { m_val = v; extend_sign(); return *this; }
+
+ sc_uint_base& operator = ( const sc_uint_base& a )
+ { m_val = a.m_val; extend_sign(); return *this; }
+
+ sc_uint_base& operator = ( const sc_uint_subref_r& a )
+ { m_val = a; extend_sign(); return *this; }
+
+ template<class T>
+ sc_uint_base& operator = ( const sc_generic_base<T>& a )
+ { m_val = a->to_uint64(); extend_sign(); return *this; }
+
+ sc_uint_base& operator = ( const sc_signed& a );
+ sc_uint_base& operator = ( const sc_unsigned& a );
+
+#ifdef SC_INCLUDE_FX
+ sc_uint_base& operator = ( const sc_fxval& a );
+ sc_uint_base& operator = ( const sc_fxval_fast& a );
+ sc_uint_base& operator = ( const sc_fxnum& a );
+ sc_uint_base& operator = ( const sc_fxnum_fast& a );
+#endif
+
+ sc_uint_base& operator = ( const sc_bv_base& a );
+ sc_uint_base& operator = ( const sc_lv_base& a );
+
+ sc_uint_base& operator = ( const char* a );
+
+ sc_uint_base& operator = ( unsigned long a )
+ { m_val = a; extend_sign(); return *this; }
+
+ sc_uint_base& operator = ( long a )
+ { m_val = a; extend_sign(); return *this; }
+
+ sc_uint_base& operator = ( unsigned int a )
+ { m_val = a; extend_sign(); return *this; }
+
+ sc_uint_base& operator = ( int a )
+ { m_val = a; extend_sign(); return *this; }
+
+ sc_uint_base& operator = ( int64 a )
+ { m_val = a; extend_sign(); return *this; }
+
+ sc_uint_base& operator = ( double a )
+ { m_val = (uint_type) a; extend_sign(); return *this; }
+
+
+ // arithmetic assignment operators
+
+ sc_uint_base& operator += ( uint_type v )
+ { m_val += v; extend_sign(); return *this; }
+
+ sc_uint_base& operator -= ( uint_type v )
+ { m_val -= v; extend_sign(); return *this; }
+
+ sc_uint_base& operator *= ( uint_type v )
+ { m_val *= v; extend_sign(); return *this; }
+
+ sc_uint_base& operator /= ( uint_type v )
+ { m_val /= v; extend_sign(); return *this; }
+
+ sc_uint_base& operator %= ( uint_type v )
+ { m_val %= v; extend_sign(); return *this; }
+
+
+ // bitwise assignment operators
+
+ sc_uint_base& operator &= ( uint_type v )
+ { m_val &= v; extend_sign(); return *this; }
+
+ sc_uint_base& operator |= ( uint_type v )
+ { m_val |= v; extend_sign(); return *this; }
+
+ sc_uint_base& operator ^= ( uint_type v )
+ { m_val ^= v; extend_sign(); return *this; }
+
+
+ sc_uint_base& operator <<= ( uint_type v )
+ { m_val <<= v; extend_sign(); return *this; }
+
+ sc_uint_base& operator >>= ( uint_type v )
+ { m_val >>= v; /* no sign extension needed */ return *this; }
+
+
+ // prefix and postfix increment and decrement operators
+
+ sc_uint_base& operator ++ () // prefix
+ { ++ m_val; extend_sign(); return *this; }
+
+ const sc_uint_base operator ++ ( int ) // postfix
+ { sc_uint_base tmp( *this ); ++ m_val; extend_sign(); return tmp; }
+
+ sc_uint_base& operator -- () // prefix
+ { -- m_val; extend_sign(); return *this; }
+
+ const sc_uint_base operator -- ( int ) // postfix
+ { sc_uint_base tmp( *this ); -- m_val; extend_sign(); return tmp; }
+
+
+ // relational operators
+
+ friend bool operator == ( const sc_uint_base& a, const sc_uint_base& b )
+ { return a.m_val == b.m_val; }
+
+ friend bool operator != ( const sc_uint_base& a, const sc_uint_base& b )
+ { return a.m_val != b.m_val; }
+
+ friend bool operator < ( const sc_uint_base& a, const sc_uint_base& b )
+ { return a.m_val < b.m_val; }
+
+ friend bool operator <= ( const sc_uint_base& a, const sc_uint_base& b )
+ { return a.m_val <= b.m_val; }
+
+ friend bool operator > ( const sc_uint_base& a, const sc_uint_base& b )
+ { return a.m_val > b.m_val; }
+
+ friend bool operator >= ( const sc_uint_base& a, const sc_uint_base& b )
+ { return a.m_val >= b.m_val; }
+
+
+ // bit selection
+
+ sc_uint_bitref& operator [] ( int i );
+ const sc_uint_bitref_r& operator [] ( int i ) const;
+
+ sc_uint_bitref& bit( int i );
+ const sc_uint_bitref_r& bit( int i ) const;
+
+
+ // part selection
+
+ sc_uint_subref& operator () ( int left, int right );
+ const sc_uint_subref_r& operator () ( int left, int right ) const;
+
+ sc_uint_subref& range( int left, int right );
+ const sc_uint_subref_r& range( int left, int right ) const;
+
+
+ // bit access, without bounds checking or sign extension
+
+ bool test( int i ) const
+ { return ( 0 != (m_val & (UINT_ONE << i)) ); }
+
+ void set( int i )
+ { m_val |= (UINT_ONE << i); }
+
+ void set( int i, bool v )
+ { v ? m_val |= (UINT_ONE << i) : m_val &= ~(UINT_ONE << i); }
+
+
+ // capacity
+
+ int length() const
+ { return m_len; }
+
+#ifdef SC_DT_DEPRECATED
+ int bitwidth() const
+ { return length(); }
+#endif
+
+ // concatenation support
+
+ virtual int concat_length(bool* xz_present_p) const
+ { if ( xz_present_p ) *xz_present_p = false; return length(); }
+ virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const;
+ virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const;
+ virtual uint64 concat_get_uint64() const
+ { return m_val; }
+ virtual void concat_set(int64 src, int low_i);
+ virtual void concat_set(const sc_signed& src, int low_i);
+ virtual void concat_set(const sc_unsigned& src, int low_i);
+ virtual void concat_set(uint64 src, int low_i);
+
+
+ // reduce methods
+
+ bool and_reduce() const;
+
+ bool nand_reduce() const
+ { return ( ! and_reduce() ); }
+
+ bool or_reduce() const;
+
+ bool nor_reduce() const
+ { return ( ! or_reduce() ); }
+
+ bool xor_reduce() const;
+
+ bool xnor_reduce() const
+ { return ( ! xor_reduce() ); }
+
+
+ // implicit conversion to uint_type
+
+ operator uint_type() const
+ { return m_val; }
+
+
+ // explicit conversions
+
+ uint_type value() const
+ { return operator uint_type(); }
+
+
+ int to_int() const
+ { return (int) m_val; }
+
+ unsigned int to_uint() const
+ { return (unsigned int) m_val; }
+
+ long to_long() const
+ { return (long) m_val; }
+
+ unsigned long to_ulong() const
+ { return (unsigned long) m_val; }
+
+ int64 to_int64() const
+ { return (int64) m_val; }
+
+ uint64 to_uint64() const
+ { return (uint64) m_val; }
+
+ double to_double() const
+ { return uint64_to_double( m_val ); }
+
+
+#ifndef _32BIT_
+ long long_low() const
+ { return (long) (m_val & UINT64_32ONES); }
+
+ long long_high() const
+ { return (long) ((m_val >> 32) & UINT64_32ONES); }
+#endif
+
+ // explicit conversion to character string
+
+ const std::string to_string( sc_numrep numrep = SC_DEC ) const;
+ const std::string to_string( sc_numrep numrep, bool w_prefix ) const;
+
+
+ // other methods
+
+ void print( ::std::ostream& os = ::std::cout ) const
+ { os << to_string(sc_io_base(os,SC_DEC),sc_io_show_base(os)); }
+
+ void scan( ::std::istream& is = ::std::cin );
+
+protected:
+
+ uint_type m_val; // value
+ int m_len; // length
+ int m_ulen; // unused length
+};
+
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream&, const sc_uint_base& );
+
+inline
+::std::istream&
+operator >> ( ::std::istream&, sc_uint_base& );
+
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_uint_bitref_r
+//
+// Proxy class for sc_uint bit selection (r-value only).
+// ----------------------------------------------------------------------------
+
+// implicit conversion to bool
+
+inline
+sc_uint_bitref_r::operator uint64 () const
+{
+ return m_obj_p->test( m_index );
+}
+
+inline
+bool
+sc_uint_bitref_r::operator ! () const
+{
+ return ! m_obj_p->test( m_index );
+}
+
+inline
+bool
+sc_uint_bitref_r::operator ~ () const
+{
+ return ! m_obj_p->test( m_index );
+}
+
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, const sc_uint_bitref_r& a )
+{
+ a.print( os );
+ return os;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_uint_bitref
+//
+// Proxy class for sc_uint bit selection (r-value and l-value).
+// ----------------------------------------------------------------------------
+
+// assignment operators
+
+inline
+sc_uint_bitref&
+sc_uint_bitref::operator = ( const sc_uint_bitref_r& b )
+{
+ m_obj_p->set( m_index, b.to_bool() );
+ return *this;
+}
+
+inline
+sc_uint_bitref&
+sc_uint_bitref::operator = ( const sc_uint_bitref& b )
+{
+ m_obj_p->set( m_index, b.to_bool() );
+ return *this;
+}
+
+inline
+sc_uint_bitref&
+sc_uint_bitref::operator = ( bool b )
+{
+ m_obj_p->set( m_index, b );
+ return *this;
+}
+
+
+inline
+sc_uint_bitref&
+sc_uint_bitref::operator &= ( bool b )
+{
+ if( ! b ) {
+ m_obj_p->set( m_index, b );
+ }
+ return *this;
+}
+
+inline
+sc_uint_bitref&
+sc_uint_bitref::operator |= ( bool b )
+{
+ if( b ) {
+ m_obj_p->set( m_index, b );
+ }
+ return *this;
+}
+
+inline
+sc_uint_bitref&
+sc_uint_bitref::operator ^= ( bool b )
+{
+ if( b ) {
+ m_obj_p->m_val ^= (UINT_ONE << m_index);
+ }
+ return *this;
+}
+
+
+
+inline
+::std::istream&
+operator >> ( ::std::istream& is, sc_uint_bitref& a )
+{
+ a.scan( is );
+ return is;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_uint_subref_r
+//
+// Proxy class for sc_uint part selection (r-value only).
+// ----------------------------------------------------------------------------
+
+// implicit conversion to uint_type
+
+inline
+sc_uint_subref_r::operator uint_type() const
+{
+ uint_type val = m_obj_p->m_val;
+ int uleft = SC_INTWIDTH - (m_left + 1);
+ return ( (val & (~UINT_ZERO >> uleft)) >> m_right );
+}
+
+
+// reduce methods
+
+inline
+bool
+sc_uint_subref_r::and_reduce() const
+{
+ sc_uint_base a( *this );
+ return a.and_reduce();
+}
+
+inline
+bool
+sc_uint_subref_r::or_reduce() const
+{
+ sc_uint_base a( *this );
+ return a.or_reduce();
+}
+
+inline
+bool
+sc_uint_subref_r::xor_reduce() const
+{
+ sc_uint_base a( *this );
+ return a.xor_reduce();
+}
+
+
+// explicit conversions
+
+inline
+int
+sc_uint_subref_r::to_int() const
+{
+ sc_uint_base a( *this );
+ return a.to_int();
+}
+
+inline
+unsigned int
+sc_uint_subref_r::to_uint() const
+{
+ sc_uint_base a( *this );
+ return a.to_uint();
+}
+
+inline
+long
+sc_uint_subref_r::to_long() const
+{
+ sc_uint_base a( *this );
+ return a.to_long();
+}
+
+inline
+unsigned long
+sc_uint_subref_r::to_ulong() const
+{
+ sc_uint_base a( *this );
+ return a.to_ulong();
+}
+
+inline
+int64
+sc_uint_subref_r::to_int64() const
+{
+ sc_uint_base a( *this );
+ return a.to_int64();
+}
+
+inline
+uint64
+sc_uint_subref_r::to_uint64() const
+{
+ sc_uint_base a( *this );
+ return a.to_uint64();
+}
+
+inline
+double
+sc_uint_subref_r::to_double() const
+{
+ sc_uint_base a( *this );
+ return a.to_double();
+}
+
+
+// explicit conversion to character string
+
+inline
+const std::string
+sc_uint_subref_r::to_string( sc_numrep numrep ) const
+{
+ sc_uint_base a( *this );
+ return a.to_string( numrep );
+}
+
+inline
+const std::string
+sc_uint_subref_r::to_string( sc_numrep numrep, bool w_prefix ) const
+{
+ sc_uint_base a( *this );
+ return a.to_string( numrep, w_prefix );
+}
+
+
+// functional notation for the reduce methods
+
+inline
+bool
+and_reduce( const sc_uint_subref_r& a )
+{
+ return a.and_reduce();
+}
+
+inline
+bool
+nand_reduce( const sc_uint_subref_r& a )
+{
+ return a.nand_reduce();
+}
+
+inline
+bool
+or_reduce( const sc_uint_subref_r& a )
+{
+ return a.or_reduce();
+}
+
+inline
+bool
+nor_reduce( const sc_uint_subref_r& a )
+{
+ return a.nor_reduce();
+}
+
+inline
+bool
+xor_reduce( const sc_uint_subref_r& a )
+{
+ return a.xor_reduce();
+}
+
+inline
+bool
+xnor_reduce( const sc_uint_subref_r& a )
+{
+ return a.xnor_reduce();
+}
+
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, const sc_uint_subref_r& a )
+{
+ a.print( os );
+ return os;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_uint_subref
+//
+// Proxy class for sc_uint part selection (r-value and l-value).
+// ----------------------------------------------------------------------------
+
+// assignment operators
+
+inline
+sc_uint_subref&
+sc_uint_subref::operator = ( const sc_uint_base& a )
+{
+ return operator = ( a.operator uint_type() );
+}
+
+inline
+sc_uint_subref&
+sc_uint_subref::operator = ( const char* a )
+{
+ sc_uint_base aa( length() );
+ return ( *this = aa = a );
+}
+
+
+
+inline
+::std::istream&
+operator >> ( ::std::istream& is, sc_uint_subref& a )
+{
+ a.scan( is );
+ return is;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_uint_base
+//
+// Base class for sc_uint.
+// ----------------------------------------------------------------------------
+
+// bit selection
+
+inline
+sc_uint_bitref&
+sc_uint_base::operator [] ( int i )
+{
+ check_index( i );
+ sc_uint_bitref* result_p = sc_uint_bitref::m_pool.allocate();
+ result_p->initialize(this, i);
+ return *result_p;
+}
+
+inline
+const sc_uint_bitref_r&
+sc_uint_base::operator [] ( int i ) const
+{
+ check_index( i );
+ sc_uint_bitref* result_p = sc_uint_bitref::m_pool.allocate();
+ result_p->initialize(this, i);
+ return *result_p;
+}
+
+
+inline
+sc_uint_bitref&
+sc_uint_base::bit( int i )
+{
+ check_index( i );
+ sc_uint_bitref* result_p = sc_uint_bitref::m_pool.allocate();
+ result_p->initialize(this, i);
+ return *result_p;
+}
+
+inline
+const sc_uint_bitref_r&
+sc_uint_base::bit( int i ) const
+{
+ check_index( i );
+ sc_uint_bitref* result_p = sc_uint_bitref::m_pool.allocate();
+ result_p->initialize(this, i);
+ return *result_p;
+}
+
+
+// part selection
+
+inline
+sc_uint_subref&
+sc_uint_base::operator () ( int left, int right )
+{
+ check_range( left, right );
+ sc_uint_subref* result_p = sc_uint_subref::m_pool.allocate();
+ result_p->initialize(this, left, right);
+ return *result_p;
+}
+
+inline
+const sc_uint_subref_r&
+sc_uint_base::operator () ( int left, int right ) const
+{
+ check_range( left, right );
+ sc_uint_subref* result_p = sc_uint_subref::m_pool.allocate();
+ result_p->initialize(this, left, right);
+ return *result_p;
+}
+
+
+inline
+sc_uint_subref&
+sc_uint_base::range( int left, int right )
+{
+ check_range( left, right );
+ sc_uint_subref* result_p = sc_uint_subref::m_pool.allocate();
+ result_p->initialize(this, left, right);
+ return *result_p;
+}
+
+inline
+const sc_uint_subref_r&
+sc_uint_base::range( int left, int right ) const
+{
+ check_range( left, right );
+ sc_uint_subref* result_p = sc_uint_subref::m_pool.allocate();
+ result_p->initialize(this, left, right);
+ return *result_p;
+}
+
+
+// functional notation for the reduce methods
+
+inline
+bool
+and_reduce( const sc_uint_base& a )
+{
+ return a.and_reduce();
+}
+
+inline
+bool
+nand_reduce( const sc_uint_base& a )
+{
+ return a.nand_reduce();
+}
+
+inline
+bool
+or_reduce( const sc_uint_base& a )
+{
+ return a.or_reduce();
+}
+
+inline
+bool
+nor_reduce( const sc_uint_base& a )
+{
+ return a.nor_reduce();
+}
+
+inline
+bool
+xor_reduce( const sc_uint_base& a )
+{
+ return a.xor_reduce();
+}
+
+inline
+bool
+xnor_reduce( const sc_uint_base& a )
+{
+ return a.xnor_reduce();
+}
+
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, const sc_uint_base& a )
+{
+ a.print( os );
+ return os;
+}
+
+inline
+::std::istream&
+operator >> ( ::std::istream& is, sc_uint_base& a )
+{
+ a.scan( is );
+ return is;
+}
+
+} // namespace sc_dt
+
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/datatypes/int/sc_unsigned.cpp b/ext/systemc/src/sysc/datatypes/int/sc_unsigned.cpp
new file mode 100644
index 000000000..75af69deb
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/int/sc_unsigned.cpp
@@ -0,0 +1,2240 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_unsigned.cpp -- Arbitrary precision signed arithmetic.
+
+ This file includes the definitions of sc_unsigned_bitref,
+ sc_unsigned_subref, and sc_unsigned classes. The first two classes
+ are proxy classes to reference one bit and a range of bits of a
+ sc_unsigned number, respectively. This file also includes
+ sc_nbcommon.cpp and sc_nbfriends.cpp, which contain the
+ definitions shared by sc_unsigned.
+
+ Original Author: Ali Dasdan, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// $Log: sc_unsigned.cpp,v $
+// Revision 1.7 2011/02/18 20:19:15 acg
+// Andy Goodrich: updating Copyright notice.
+//
+// Revision 1.6 2008/12/10 20:38:45 acg
+// Andy Goodrich: fixed conversion of double values to the digits vector.
+// The bits above the radix were not being masked off.
+//
+// Revision 1.5 2008/06/19 17:47:57 acg
+// Andy Goodrich: fixes for bugs. See 2.2.1 RELEASENOTES.
+//
+// Revision 1.4 2008/06/19 16:57:57 acg
+// Andy Goodrich: added case for negative unsigned values to the support in
+// concate_get_data().
+//
+// Revision 1.3 2007/11/04 21:27:00 acg
+// Andy Goodrich: changes to make sure the proper value is returned from
+// concat_get_data().
+//
+// Revision 1.2 2007/02/22 21:35:05 acg
+// Andy Goodrich: cleaned up comments in concat_get_ctrl and concat_get_data.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.4 2006/08/29 23:36:54 acg
+// Andy Goodrich: fixed and_reduce and optimized or_reduce.
+//
+// Revision 1.3 2006/01/13 18:49:32 acg
+// Added $Log command so that CVS check in comments are reproduced in the
+// source.
+//
+
+#include <ctype.h>
+#include <math.h>
+
+#include "sysc/kernel/sc_cmnhdr.h"
+#include "sysc/kernel/sc_macros.h"
+#include "sysc/datatypes/int/sc_unsigned.h"
+#include "sysc/datatypes/int/sc_signed.h"
+#include "sysc/datatypes/int/sc_int_base.h"
+#include "sysc/datatypes/int/sc_uint_base.h"
+#include "sysc/datatypes/int/sc_int_ids.h"
+#include "sysc/datatypes/bit/sc_bv_base.h"
+#include "sysc/datatypes/bit/sc_lv_base.h"
+#include "sysc/datatypes/misc/sc_concatref.h"
+#include "sysc/datatypes/fx/sc_ufix.h"
+#include "sysc/datatypes/fx/scfx_other_defs.h"
+
+namespace sc_dt
+{
+
+// Pool of temporary instances:
+// The sc_unsigned pool is used by the concatenation support.
+// The bit and part reference pools allow references to be returned.
+
+sc_core::sc_vpool<sc_unsigned> sc_unsigned::m_pool(8);
+sc_core::sc_vpool<sc_unsigned_bitref> sc_unsigned_bitref::m_pool(9);
+sc_core::sc_vpool<sc_unsigned_subref> sc_unsigned_subref::m_pool(9);
+
+// -----------------------------------------------------------------------------
+// SECTION: Public members - Invalid selections.
+// -----------------------------------------------------------------------------
+
+void
+sc_unsigned::invalid_index( int i ) const
+{
+ char msg[BUFSIZ];
+ std::sprintf( msg,
+ "sc_biguint bit selection: index = %d violates "
+ "0 <= index <= %d",
+ i, nbits - 2 );
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
+}
+
+void
+sc_unsigned::invalid_range( int l, int r ) const
+{
+ char msg[BUFSIZ];
+ std::sprintf( msg,
+ "sc_biguint part selection: left = %d, right = %d \n"
+ " violates either (%d >= left >= 0) or (%d >= right >= 0)",
+ l, r, nbits-2, nbits-2 );
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
+}
+
+// ----------------------------------------------------------------------------
+// SECTION: Public members - Concatenation support.
+// ----------------------------------------------------------------------------
+
+// Most public members are included from sc_nbcommon.inc. However, some
+// concatenation support appears here to optimize between the signed and
+// unsigned cases.
+
+
+
+// Insert this object's value at the specified place in a vector of big style
+// values.
+
+bool sc_unsigned::concat_get_ctrl( sc_digit* dst_p, int low_i ) const
+{
+ int dst_i; // Index to next word to set in dst_p.
+ int end_i; // Index of high order word to set.
+ int left_shift; // Amount to shift value left.
+ sc_digit mask; // Mask for partial word sets.
+
+
+ // CALCULATE METRICS FOR DATA MOVEMENT:
+
+ dst_i = low_i / BITS_PER_DIGIT;
+ end_i = (low_i + nbits - 2) / BITS_PER_DIGIT;
+ left_shift = low_i % BITS_PER_DIGIT;
+
+
+ // MOVE FIRST WORD (IT MAY BE PARTIAL) AND THEN ANY OTHERS:
+ //
+ // We may "clobber" upper bits, but they will be written at some point
+ // anyway.
+
+ mask = ~(-1 << left_shift);
+ dst_p[dst_i] = ( dst_p[dst_i] & ~mask );
+ dst_i++;
+
+ for ( ; dst_i <= end_i; dst_i++ ) dst_p[dst_i] = 0;
+
+ return false;
+}
+
+bool sc_unsigned::concat_get_data( sc_digit* dst_p, int low_i ) const
+{
+ sc_digit carry; // Carry for negating value.
+ int dst_i; // Index to next word to set in dst_p.
+ int end_i; // Index of high order word to set.
+ int high_i; // Index w/in word of high order bit.
+ int left_shift; // Amount to shift value left.
+ sc_digit left_word; // High word component for set.
+ sc_digit mask; // Mask for partial word sets.
+ bool result; // True if inserting non-zero data.
+ int right_shift; // Amount to shift value right.
+ sc_digit right_word; // Low word component for set.
+ int real_bits; // nbits - 1.
+ int src_i; // Index to next word to get from digit.
+
+
+ // CALCULATE METRICS FOR DATA MOVEMENT:
+
+ real_bits = nbits - 1; // Remove that extra sign bit.
+ dst_i = low_i / BITS_PER_DIGIT;
+ high_i = low_i + real_bits - 1;
+ end_i = high_i / BITS_PER_DIGIT;
+ left_shift = low_i % BITS_PER_DIGIT;
+
+
+ switch ( sgn )
+ {
+
+ // POSITIVE SOURCE VALUE:
+
+ case SC_POS:
+ result = true;
+
+ // ALL DATA TO BE MOVED IS IN A SINGLE WORD:
+
+ if ( dst_i == end_i )
+ {
+ mask = ~(-1 << left_shift);
+ dst_p[dst_i] = ( ( dst_p[dst_i] & mask ) |
+ (digit[0] << left_shift) ) & DIGIT_MASK;
+ }
+
+
+ // DATA IS IN MORE THAN ONE WORD, BUT IS WORD ALIGNED:
+
+ else if ( left_shift == 0 )
+ {
+ for ( src_i = 0; dst_i < end_i; dst_i++, src_i++ )
+ {
+ dst_p[dst_i] = digit[src_i];
+ }
+ high_i = high_i % BITS_PER_DIGIT;
+ mask = ~(-2 << high_i) & DIGIT_MASK;
+ dst_p[dst_i] = digit[src_i] & mask;
+ }
+
+
+ // DATA IS IN MORE THAN ONE WORD, AND NOT WORD ALIGNED:
+
+ else
+ {
+ high_i = high_i % BITS_PER_DIGIT;
+ right_shift = BITS_PER_DIGIT - left_shift;
+ mask = ~(-1 << left_shift);
+ right_word = digit[0];
+ dst_p[dst_i] = (dst_p[dst_i] & mask) |
+ ((right_word << left_shift) & DIGIT_MASK);
+ for ( src_i = 1, dst_i++; dst_i < end_i; dst_i++, src_i++ )
+ {
+ left_word = digit[src_i];
+ dst_p[dst_i] = ((left_word << left_shift)&DIGIT_MASK) |
+ (right_word >> right_shift);
+ right_word = left_word;
+ }
+ left_word = (src_i < ndigits) ? digit[src_i] : 0;
+ mask = ~(-2 << high_i) & DIGIT_MASK;
+ dst_p[dst_i] = ((left_word << left_shift) |
+ (right_word >> right_shift)) & mask;
+ }
+ break;
+
+ // SOURCE VALUE IS NEGATIVE:
+
+ case SC_NEG:
+
+ // ALL DATA TO BE MOVED IS IN A SINGLE WORD:
+
+ result = true;
+ if ( dst_i == end_i )
+ {
+ mask = ~(-1 << nbits);
+ right_word = ((digit[0] ^ DIGIT_MASK) + 1) & mask;
+ mask = ~(-1 << left_shift);
+ dst_p[dst_i] = ( ( dst_p[dst_i] & mask ) |
+ (right_word << left_shift) ) & DIGIT_MASK;
+ }
+
+
+ // DATA IS IN MORE THAN ONE WORD, BUT IS WORD ALIGNED:
+
+ else if ( left_shift == 0 )
+ {
+ carry = 1;
+ for ( src_i = 0; dst_i < end_i; dst_i++, src_i++ )
+ {
+ right_word = (digit[src_i] ^ DIGIT_MASK) + carry;
+ dst_p[dst_i] = right_word & DIGIT_MASK;
+ carry = right_word >> BITS_PER_DIGIT;
+ }
+ high_i = high_i % BITS_PER_DIGIT;
+ mask = (~(-2 << high_i)) & DIGIT_MASK;
+ right_word = (src_i < ndigits) ?
+ (digit[src_i] ^ DIGIT_MASK) + carry : DIGIT_MASK + carry;
+ dst_p[dst_i] = right_word & mask;
+ }
+
+
+ // DATA IS IN MORE THAN ONE WORD, AND NOT WORD ALIGNED:
+
+ else
+ {
+ high_i = high_i % BITS_PER_DIGIT;
+ right_shift = BITS_PER_DIGIT - left_shift;
+ mask = ~(-1 << left_shift);
+ carry = 1;
+ right_word = (digit[0] ^ DIGIT_MASK) + carry;
+ dst_p[dst_i] = (dst_p[dst_i] & mask) |
+ ((right_word << left_shift) & DIGIT_MASK);
+ carry = right_word >> BITS_PER_DIGIT;
+ right_word &= DIGIT_MASK;
+ for ( src_i = 1, dst_i++; dst_i < end_i; dst_i++, src_i++ )
+ {
+ left_word = (digit[src_i] ^ DIGIT_MASK) + carry;
+ dst_p[dst_i] = ((left_word << left_shift)&DIGIT_MASK) |
+ (right_word >> right_shift);
+ carry = left_word >> BITS_PER_DIGIT;
+ right_word = left_word & DIGIT_MASK;
+ }
+ left_word = (src_i < ndigits) ?
+ (digit[src_i] ^ DIGIT_MASK) + carry : carry;
+ mask = ~(-2 << high_i) & DIGIT_MASK;
+ dst_p[dst_i] = ((left_word << left_shift) |
+ (right_word >> right_shift)) & mask;
+ }
+ break;
+
+
+ // VALUE IS ZERO:
+
+ default:
+ result = false;
+
+ // ALL DATA TO BE MOVED IS IN A SINGLE WORD:
+
+ if ( dst_i == end_i )
+ {
+ mask = ~(-1 << real_bits) << left_shift;
+ dst_p[dst_i] = dst_p[dst_i] & ~mask;
+ }
+
+
+ // DATA IS IN MORE THAN ONE WORD, BUT IS WORD ALIGNED:
+
+ else if ( left_shift == 0 )
+ {
+ for ( src_i = 0; dst_i < end_i; dst_i++, src_i++ )
+ {
+ dst_p[dst_i] = 0;
+ }
+ high_i = high_i % BITS_PER_DIGIT;
+ mask = ~(-2 << high_i) & DIGIT_MASK;
+ dst_p[dst_i] = 0;
+ }
+
+
+ // DATA IS IN MORE THAN ONE WORD, AND NOT WORD ALIGNED:
+
+ else
+ {
+ high_i = high_i % BITS_PER_DIGIT;
+ right_shift = BITS_PER_DIGIT - left_shift;
+ mask = ~(-1 << left_shift);
+ dst_p[dst_i] = (dst_p[dst_i] & mask);
+ for ( dst_i++; dst_i <= end_i; dst_i++ )
+ {
+ dst_p[dst_i] = 0;
+ }
+ }
+ break;
+ }
+ return result;
+}
+
+// Return this object instance's bits as a uint64 without sign extension.
+
+uint64 sc_unsigned::concat_get_uint64() const
+{
+ uint64 result;
+
+ switch ( sgn )
+ {
+ case SC_POS:
+ result = 0;
+ if ( ndigits > 2 )
+ result = digit[2];
+ if ( ndigits > 1 )
+ result = (result << BITS_PER_DIGIT) | digit[1];
+ result = (result << BITS_PER_DIGIT) | digit[0];
+ break;
+ default:
+ result = 0;
+ break;
+ }
+ return result;
+}
+
+// #### OPTIMIZE
+void sc_unsigned::concat_set(int64 src, int low_i)
+{
+ *this = (low_i < 64) ? src >> low_i : src >> 63;
+}
+
+void sc_unsigned::concat_set(const sc_signed& src, int low_i)
+{
+ if ( low_i < src.length() )
+ *this = src >> low_i;
+ else
+ *this = (src<0) ? (int_type)-1 : 0;
+}
+
+void sc_unsigned::concat_set(const sc_unsigned& src, int low_i)
+{
+ if ( low_i < src.length() )
+ *this = src >> low_i;
+ else
+ *this = 0;
+}
+
+void sc_unsigned::concat_set(uint64 src, int low_i)
+{
+ *this = (low_i < 64) ? src >> low_i : 0;
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Public members - Reduction methods.
+// ----------------------------------------------------------------------------
+
+bool sc_unsigned::and_reduce() const
+{
+ int i; // Digit examining.
+
+ if ( sgn == SC_ZERO ) return false;
+ for ( i = 0; i < ndigits-1; i++ )
+ if ( (digit[i] & DIGIT_MASK) != DIGIT_MASK ) return false;
+ if ( (digit[i] & ~(-1 << ((nbits-1) % BITS_PER_DIGIT))) ==
+ (sc_digit)~(-1 << ((nbits-1) % BITS_PER_DIGIT)))
+ return true;
+ return false;
+}
+
+bool sc_unsigned::or_reduce() const
+{
+ return ( sgn == SC_ZERO ) ? false : true;
+}
+
+bool sc_unsigned::xor_reduce() const
+{
+ int i; // Digit examining.
+ int odd; // Flag for odd number of digits.
+
+ odd = 0;
+ for ( i = 0; i < nbits-1; i++ )
+ if ( test(i) ) odd = ~odd;
+ return odd ? true : false;
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Public members - Assignment operators.
+// ----------------------------------------------------------------------------
+
+// assignment operators
+
+const sc_unsigned&
+sc_unsigned::operator = ( const char* a )
+{
+ if( a == 0 ) {
+ SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_,
+ "character string is zero" );
+ }
+ if( *a == 0 ) {
+ SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_,
+ "character string is empty" );
+ }
+ try {
+ int len = length();
+ sc_ufix aa( a, len, len, SC_TRN, SC_WRAP, 0, SC_ON );
+ return this->operator = ( aa );
+ } catch( sc_core::sc_report ) {
+ char msg[BUFSIZ];
+ std::sprintf( msg, "character string '%s' is not valid", a );
+ SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
+ // never reached
+ }
+ return *this;
+}
+
+const sc_unsigned&
+sc_unsigned::operator=(int64 v)
+{
+ sgn = get_sign(v);
+ if ( sgn == SC_ZERO ) {
+ vec_zero(ndigits, digit);
+ }
+ else {
+ from_uint(ndigits, digit, (uint64) v);
+ convert_SM_to_2C_to_SM();
+ }
+ return *this;
+}
+
+const sc_unsigned&
+sc_unsigned::operator=(uint64 v)
+{
+ if (v == 0) {
+ sgn = SC_ZERO;
+ vec_zero(ndigits, digit);
+ }
+ else {
+ sgn = SC_POS;
+ from_uint(ndigits, digit, v);
+ convert_SM_to_2C_to_SM();
+ }
+ return *this;
+}
+
+const sc_unsigned&
+sc_unsigned::operator=(long v)
+{
+ sgn = get_sign(v);
+ if ( sgn == SC_ZERO ) {
+ vec_zero(ndigits, digit);
+ }
+ else {
+ from_uint(ndigits, digit, (unsigned long) v);
+ convert_SM_to_2C_to_SM();
+ }
+ return *this;
+}
+
+const sc_unsigned&
+sc_unsigned::operator=(unsigned long v)
+{
+ if (v == 0) {
+ sgn = SC_ZERO;
+ vec_zero(ndigits, digit);
+ }
+ else {
+ sgn = SC_POS;
+ from_uint(ndigits, digit, v);
+ convert_SM_to_2C_to_SM();
+ }
+ return *this;
+}
+
+const sc_unsigned&
+sc_unsigned::operator=(double v)
+{
+ is_bad_double(v);
+ sgn = SC_POS;
+ int i = 0;
+ while (floor(v) && (i < ndigits)) {
+#ifndef _WIN32
+ digit[i++] = ((sc_digit)floor(remainder(v, DIGIT_RADIX))) & DIGIT_MASK;
+#else
+ digit[i++] = ((sc_digit)floor(fmod(v, DIGIT_RADIX))) & DIGIT_MASK;
+#endif
+ v /= DIGIT_RADIX;
+ }
+ vec_zero(i, ndigits, digit);
+ convert_SM_to_2C_to_SM();
+ return *this;
+}
+
+
+// ----------------------------------------------------------------------------
+
+const sc_unsigned&
+sc_unsigned::operator = ( const sc_bv_base& v )
+{
+ int minlen = sc_min( nbits, v.length() );
+ int i = 0;
+ for( ; i < minlen; ++ i ) {
+ safe_set( i, v.get_bit( i ), digit );
+ }
+ for( ; i < nbits; ++ i ) {
+ safe_set( i, 0, digit ); // zero-extend
+ }
+ convert_2C_to_SM();
+ return *this;
+}
+
+const sc_unsigned&
+sc_unsigned::operator = ( const sc_lv_base& v )
+{
+ int minlen = sc_min( nbits, v.length() );
+ int i = 0;
+ for( ; i < minlen; ++ i ) {
+ safe_set( i, sc_logic( v.get_bit( i ) ).to_bool(), digit );
+ }
+ for( ; i < nbits; ++ i ) {
+ safe_set( i, 0, digit ); // zero-extend
+ }
+ convert_2C_to_SM();
+ return *this;
+}
+
+
+// explicit conversion to character string
+
+const std::string
+sc_unsigned::to_string( sc_numrep numrep ) const
+{
+ int len = length();
+ sc_ufix aa( *this, len, len, SC_TRN, SC_WRAP, 0, SC_ON );
+ return aa.to_string( numrep );
+}
+
+const std::string
+sc_unsigned::to_string( sc_numrep numrep, bool w_prefix ) const
+{
+ int len = length();
+ sc_ufix aa( *this, len, len, SC_TRN, SC_WRAP, 0, SC_ON );
+ return aa.to_string( numrep, w_prefix );
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Interfacing with sc_int_base
+// ----------------------------------------------------------------------------
+
+const sc_unsigned&
+sc_unsigned::operator= (const sc_int_base& v)
+{ return operator=((int64) v); }
+
+const sc_unsigned&
+sc_unsigned::operator+=(const sc_int_base& v)
+{ return operator+=((int64) v); }
+
+const sc_unsigned&
+sc_unsigned::operator-=(const sc_int_base& v)
+{ return operator-=((int64) v); }
+
+const sc_unsigned&
+sc_unsigned::operator*=(const sc_int_base& v)
+{ return operator*=((int64) v); }
+
+const sc_unsigned&
+sc_unsigned::operator/=(const sc_int_base& v)
+{ return operator/=((int64) v); }
+
+const sc_unsigned&
+sc_unsigned::operator%=(const sc_int_base& v)
+{ return operator%=((int64) v); }
+
+const sc_unsigned&
+sc_unsigned::operator&=(const sc_int_base& v)
+{ return operator&=((int64) v); }
+
+const sc_unsigned&
+sc_unsigned::operator|=(const sc_int_base& v)
+{ return operator|=((int64) v); }
+
+const sc_unsigned&
+sc_unsigned::operator^=(const sc_int_base& v)
+{ return operator^=((int64) v); }
+
+sc_unsigned
+operator<<(const sc_unsigned& u, const sc_int_base& v)
+{ return operator<<(u, (int64) v); }
+const sc_unsigned&
+sc_unsigned::operator<<=(const sc_int_base& v)
+{ return operator<<=((int64) v); }
+
+sc_unsigned
+operator>>(const sc_unsigned& u, const sc_int_base& v)
+{ return operator>>(u, (int64) v); }
+const sc_unsigned&
+sc_unsigned::operator>>=(const sc_int_base& v)
+{ return operator>>=((int64) v); }
+
+bool
+operator==(const sc_unsigned& u, const sc_int_base& v)
+{ return operator==(u, (int64) v); }
+bool
+operator==(const sc_int_base& u, const sc_unsigned& v)
+{ return operator==((int64) u, v); }
+
+bool
+operator!=(const sc_unsigned& u, const sc_int_base& v)
+{ return operator!=(u, (int64) v); }
+bool
+operator!=(const sc_int_base& u, const sc_unsigned& v)
+{ return operator!=((int64) u, v); }
+
+bool
+operator<(const sc_unsigned& u, const sc_int_base& v)
+{ return operator<(u, (int64) v); }
+bool
+operator<(const sc_int_base& u, const sc_unsigned& v)
+{ return operator<((int64) u, v); }
+
+bool
+operator<=(const sc_unsigned& u, const sc_int_base& v)
+{ return operator<=(u, (int64) v); }
+bool
+operator<=(const sc_int_base& u, const sc_unsigned& v)
+{ return operator<=((int64) u, v); }
+
+bool
+operator>(const sc_unsigned& u, const sc_int_base& v)
+{ return operator>(u, (int64) v); }
+bool
+operator>(const sc_int_base& u, const sc_unsigned& v)
+{ return operator>((int64) u, v); }
+
+bool
+operator>=(const sc_unsigned& u, const sc_int_base& v)
+{ return operator>=(u, (int64) v); }
+bool
+operator>=(const sc_int_base& u, const sc_unsigned& v)
+{ return operator>=((int64) u, v); }
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Interfacing with sc_uint_base
+// ----------------------------------------------------------------------------
+
+const sc_unsigned&
+sc_unsigned::operator= (const sc_uint_base& v)
+{ return operator=((uint64) v); }
+
+sc_unsigned
+operator+(const sc_unsigned& u, const sc_uint_base& v)
+{ return operator+(u, (uint64) v); }
+sc_unsigned
+operator+(const sc_uint_base& u, const sc_unsigned& v)
+{ return operator+((uint64) u, v); }
+const sc_unsigned&
+sc_unsigned::operator+=(const sc_uint_base& v)
+{ return operator+=((uint64) v); }
+
+const sc_unsigned&
+sc_unsigned::operator-=(const sc_uint_base& v)
+{ return operator-=((uint64) v); }
+
+sc_unsigned
+operator*(const sc_unsigned& u, const sc_uint_base& v)
+{ return operator*(u, (uint64) v); }
+sc_unsigned
+operator*(const sc_uint_base& u, const sc_unsigned& v)
+{ return operator*((uint64) u, v); }
+const sc_unsigned&
+sc_unsigned::operator*=(const sc_uint_base& v)
+{ return operator*=((uint64) v); }
+
+sc_unsigned
+operator/(const sc_unsigned& u, const sc_uint_base& v)
+{ return operator/(u, (uint64) v); }
+sc_unsigned
+operator/(const sc_uint_base& u, const sc_unsigned& v)
+{ return operator/((uint64) u, v); }
+const sc_unsigned&
+sc_unsigned::operator/=(const sc_uint_base& v)
+{ return operator/=((uint64) v); }
+
+sc_unsigned
+operator%(const sc_unsigned& u, const sc_uint_base& v)
+{ return operator%(u, (uint64) v); }
+sc_unsigned
+operator%(const sc_uint_base& u, const sc_unsigned& v)
+{ return operator%((uint64) u, v); }
+const sc_unsigned&
+sc_unsigned::operator%=(const sc_uint_base& v)
+{ return operator%=((uint64) v); }
+
+sc_unsigned
+operator&(const sc_unsigned& u, const sc_uint_base& v)
+{ return operator&(u, (uint64) v); }
+sc_unsigned
+operator&(const sc_uint_base& u, const sc_unsigned& v)
+{ return operator&((uint64) u, v); }
+const sc_unsigned&
+sc_unsigned::operator&=(const sc_uint_base& v)
+{ return operator&=((uint64) v); }
+
+sc_unsigned
+operator|(const sc_unsigned& u, const sc_uint_base& v)
+{ return operator|(u, (uint64) v); }
+sc_unsigned
+operator|(const sc_uint_base& u, const sc_unsigned& v)
+{ return operator|((uint64) u, v); }
+const sc_unsigned&
+sc_unsigned::operator|=(const sc_uint_base& v)
+{ return operator|=((uint64) v); }
+
+sc_unsigned
+operator^(const sc_unsigned& u, const sc_uint_base& v)
+{ return operator^(u, (uint64) v); }
+sc_unsigned
+operator^(const sc_uint_base& u, const sc_unsigned& v)
+{ return operator^((uint64) u, v); }
+const sc_unsigned&
+sc_unsigned::operator^=(const sc_uint_base& v)
+{ return operator^=((uint64) v); }
+
+sc_unsigned
+operator<<(const sc_unsigned& u, const sc_uint_base& v)
+{ return operator<<(u, (uint64) v); }
+const sc_unsigned&
+sc_unsigned::operator<<=(const sc_uint_base& v)
+{ return operator<<=((uint64) v); }
+
+sc_unsigned
+operator>>(const sc_unsigned& u, const sc_uint_base& v)
+{ return operator>>(u, (uint64) v); }
+const sc_unsigned&
+sc_unsigned::operator>>=(const sc_uint_base& v)
+{ return operator>>=((uint64) v); }
+
+bool
+operator==(const sc_unsigned& u, const sc_uint_base& v)
+{ return operator==(u, (uint64) v); }
+bool
+operator==(const sc_uint_base& u, const sc_unsigned& v)
+{ return operator==((uint64) u, v); }
+
+bool
+operator!=(const sc_unsigned& u, const sc_uint_base& v)
+{ return operator!=(u, (uint64) v); }
+bool
+operator!=(const sc_uint_base& u, const sc_unsigned& v)
+{ return operator!=((uint64) u, v); }
+
+bool
+operator<(const sc_unsigned& u, const sc_uint_base& v)
+{ return operator<(u, (uint64) v); }
+bool
+operator<(const sc_uint_base& u, const sc_unsigned& v)
+{ return operator<((uint64) u, v); }
+
+bool
+operator<=(const sc_unsigned& u, const sc_uint_base& v)
+{ return operator<=(u, (uint64) v); }
+bool
+operator<=(const sc_uint_base& u, const sc_unsigned& v)
+{ return operator<=((uint64) u, v); }
+
+bool
+operator>(const sc_unsigned& u, const sc_uint_base& v)
+{ return operator>(u, (uint64) v); }
+bool
+operator>(const sc_uint_base& u, const sc_unsigned& v)
+{ return operator>((uint64) u, v); }
+
+bool
+operator>=(const sc_unsigned& u, const sc_uint_base& v)
+{ return operator>=(u, (uint64) v); }
+bool
+operator>=(const sc_uint_base& u, const sc_unsigned& v)
+{ return operator>=((uint64) u, v); }
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Input and output operators
+// ----------------------------------------------------------------------------
+
+// The operators in this section are included from sc_nbcommon.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Operator macros.
+// ----------------------------------------------------------------------------
+
+#define CONVERT_LONG(u) \
+small_type u ## s = get_sign(u); \
+sc_digit u ## d[DIGITS_PER_ULONG]; \
+from_uint(DIGITS_PER_ULONG, u ## d, (unsigned long) u);
+
+#define CONVERT_LONG_2(u) \
+sc_digit u ## d[DIGITS_PER_ULONG]; \
+from_uint(DIGITS_PER_ULONG, u ## d, (unsigned long) u);
+
+#define CONVERT_INT(u) \
+small_type u ## s = get_sign(u); \
+sc_digit u ## d[DIGITS_PER_UINT]; \
+from_uint(DIGITS_PER_UINT, u ## d, (unsigned int) u);
+
+#define CONVERT_INT_2(u) \
+sc_digit u ## d[DIGITS_PER_UINT]; \
+from_uint(DIGITS_PER_UINT, u ## d, (unsigned int) u);
+
+#define CONVERT_INT64(u) \
+small_type u ## s = get_sign(u); \
+sc_digit u ## d[DIGITS_PER_UINT64]; \
+from_uint(DIGITS_PER_UINT64, u ## d, (uint64) u);
+
+#define CONVERT_INT64_2(u) \
+sc_digit u ## d[DIGITS_PER_UINT64]; \
+from_uint(DIGITS_PER_UINT64, u ## d, (uint64) u);
+
+
+// ----------------------------------------------------------------------------
+// SECTION: PLUS operators: +, +=, ++
+// ----------------------------------------------------------------------------
+
+// Cases to consider when computing u + v:
+// 1. 0 + v = v
+// 2. u + 0 = u
+// 3. if sgn(u) == sgn(v)
+// 3.1 u + v = +(u + v) = sgn(u) * (u + v)
+// 3.2 (-u) + (-v) = -(u + v) = sgn(u) * (u + v)
+// 4. if sgn(u) != sgn(v)
+// 4.1 u + (-v) = u - v = sgn(u) * (u - v)
+// 4.2 (-u) + v = -(u - v) ==> sgn(u) * (u - v)
+//
+// Specialization of above cases for computing ++u or u++:
+// 1. 0 + 1 = 1
+// 3. u + 1 = u + 1 = sgn(u) * (u + 1)
+// 4. (-u) + 1 = -(u - 1) = sgn(u) * (u - 1)
+
+sc_unsigned
+operator+(const sc_unsigned& u, const sc_unsigned& v)
+{
+
+ if (u.sgn == SC_ZERO) // case 1
+ return sc_unsigned(v);
+
+ if (v.sgn == SC_ZERO) // case 2
+ return sc_unsigned(u);
+
+ // cases 3 and 4
+ return add_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_unsigned
+operator+(const sc_unsigned &u, uint64 v)
+{
+
+ if (v == 0) // case 2
+ return sc_unsigned(u);
+
+ CONVERT_INT64(v);
+
+ if (u.sgn == SC_ZERO) // case 1
+ return sc_unsigned(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
+
+ // cases 3 and 4
+ return add_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+
+sc_unsigned
+operator+(uint64 u, const sc_unsigned &v)
+{
+
+ if (u == 0) // case 1
+ return sc_unsigned(v);
+
+ CONVERT_INT64(u);
+
+ if (v.sgn == SC_ZERO) // case 2
+ return sc_unsigned(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
+
+ // cases 3 and 4
+
+ return add_unsigned_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_unsigned
+operator+(const sc_unsigned &u, unsigned long v)
+{
+
+ if (v == 0) // case 2
+ return sc_unsigned(u);
+
+ CONVERT_LONG(v);
+
+ if (u.sgn == SC_ZERO) // case 1
+ return sc_unsigned(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
+
+ // cases 3 and 4
+ return add_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+}
+
+
+sc_unsigned
+operator+(unsigned long u, const sc_unsigned &v)
+{
+
+ if (u == 0) // case 1
+ return sc_unsigned(v);
+
+ CONVERT_LONG(u);
+
+ if (v.sgn == SC_ZERO) // case 2
+ return sc_unsigned(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
+
+ // cases 3 and 4
+ return add_unsigned_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+// The rest of the operators in this section are included from
+// sc_nbcommon.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: MINUS operators: -, -=, --
+// ----------------------------------------------------------------------------
+
+// Cases to consider when computing u + v:
+// 1. u - 0 = u
+// 2. 0 - v = -v
+// 3. if sgn(u) != sgn(v)
+// 3.1 u - (-v) = u + v = sgn(u) * (u + v)
+// 3.2 (-u) - v = -(u + v) ==> sgn(u) * (u + v)
+// 4. if sgn(u) == sgn(v)
+// 4.1 u - v = +(u - v) = sgn(u) * (u - v)
+// 4.2 (-u) - (-v) = -(u - v) = sgn(u) * (u - v)
+//
+// Specialization of above cases for computing --u or u--:
+// 1. 0 - 1 = -1
+// 3. (-u) - 1 = -(u + 1) = sgn(u) * (u + 1)
+// 4. u - 1 = u - 1 = sgn(u) * (u - 1)
+
+// The operators in this section are included from sc_nbcommon.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: MULTIPLICATION operators: *, *=
+// ----------------------------------------------------------------------------
+
+// Cases to consider when computing u * v:
+// 1. u * 0 = 0 * v = 0
+// 2. 1 * v = v and -1 * v = -v
+// 3. u * 1 = u and u * -1 = -u
+// 4. u * v = u * v
+
+sc_unsigned
+operator*(const sc_unsigned& u, const sc_unsigned& v)
+{
+
+ small_type s = mul_signs(u.sgn, v.sgn);
+
+ if (s == SC_ZERO) // case 1
+ return sc_unsigned();
+
+ // cases 2-4
+ return mul_unsigned_friend(s, u.nbits, u.ndigits, u.digit,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_unsigned
+operator*(const sc_unsigned& u, uint64 v)
+{
+
+ small_type s = mul_signs(u.sgn, get_sign(v));
+
+ if (s == SC_ZERO) // case 1
+ return sc_unsigned();
+
+ CONVERT_INT64_2(v);
+
+ // cases 2-4
+ return mul_unsigned_friend(s, u.nbits, u.ndigits, u.digit,
+ BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+
+sc_unsigned
+operator*(uint64 u, const sc_unsigned& v)
+{
+
+ small_type s = mul_signs(v.sgn, get_sign(u));
+
+ if (s == SC_ZERO) // case 1
+ return sc_unsigned();
+
+ CONVERT_INT64_2(u);
+
+ // cases 2-4
+ return mul_unsigned_friend(s, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_unsigned
+operator*(const sc_unsigned& u, unsigned long v)
+{
+
+ small_type s = mul_signs(u.sgn, get_sign(v));
+
+ if (s == SC_ZERO) // case 1
+ return sc_unsigned();
+
+ CONVERT_LONG_2(v);
+
+ // else cases 2-4
+ return mul_unsigned_friend(s, u.nbits, u.ndigits, u.digit,
+ BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+}
+
+sc_unsigned
+operator*(unsigned long u, const sc_unsigned& v)
+{
+
+ small_type s = mul_signs(v.sgn, get_sign(u));
+
+ if (s == SC_ZERO) // case 1
+ return sc_unsigned();
+
+ CONVERT_LONG_2(u);
+
+ // cases 2-4
+ return mul_unsigned_friend(s, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+// The rest of the operators in this section are included from
+// sc_nbcommon.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: DIVISION operators: /, /=
+// ----------------------------------------------------------------------------
+
+// Cases to consider when finding the quotient q = floor(u/v):
+// Note that u = q * v + r for r < q.
+// 1. 0 / 0 or u / 0 => error
+// 2. 0 / v => 0 = 0 * v + 0
+// 3. u / v && u = v => u = 1 * u + 0 - u or v can be 1 or -1
+// 4. u / v && u < v => u = 0 * v + u - u can be 1 or -1
+// 5. u / v && u > v => u = q * v + r - v can be 1 or -1
+
+sc_unsigned
+operator/(const sc_unsigned& u, const sc_unsigned& v)
+{
+
+ small_type s = mul_signs(u.sgn, v.sgn);
+
+ if (s == SC_ZERO) {
+ div_by_zero(v.sgn); // case 1
+ return sc_unsigned(); // case 2
+ }
+
+ // other cases
+ return div_unsigned_friend(s, u.nbits, u.ndigits, u.digit,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_unsigned
+operator/(const sc_unsigned& u, uint64 v)
+{
+
+ small_type s = mul_signs(u.sgn, get_sign(v));
+
+ if (s == SC_ZERO) {
+ div_by_zero(v); // case 1
+ return sc_unsigned(); // case 2
+ }
+
+ CONVERT_INT64_2(v);
+
+ // other cases
+ return div_unsigned_friend(s, u.nbits, u.ndigits, u.digit,
+ BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+
+sc_unsigned
+operator/(uint64 u, const sc_unsigned& v)
+{
+
+ small_type s = mul_signs(v.sgn, get_sign(u));
+
+ if (s == SC_ZERO) {
+ div_by_zero(v.sgn); // case 1
+ return sc_unsigned(); // case 2
+
+ }
+
+ CONVERT_INT64_2(u);
+
+ // other cases
+ return div_unsigned_friend(s, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_unsigned
+operator/(const sc_unsigned& u, unsigned long v)
+{
+
+ small_type s = mul_signs(u.sgn, get_sign(v));
+
+ if (s == SC_ZERO) {
+ div_by_zero(v); // case 1
+ return sc_unsigned(); // case 2
+ }
+
+ CONVERT_LONG_2(v);
+
+ // other cases
+ return div_unsigned_friend(s, u.nbits, u.ndigits, u.digit,
+ BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+}
+
+
+sc_unsigned
+operator/(unsigned long u, const sc_unsigned& v)
+{
+
+ small_type s = mul_signs(v.sgn, get_sign(u));
+
+ if (s == SC_ZERO) {
+ div_by_zero(v.sgn); // case 1
+ return sc_unsigned(); // case 2
+
+ }
+
+ CONVERT_LONG_2(u);
+
+ // other cases
+ return div_unsigned_friend(s, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+// The rest of the operators in this section are included from
+// sc_nbcommon.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: MOD operators: %, %=.
+// ----------------------------------------------------------------------------
+
+// Cases to consider when finding the remainder r = u % v:
+// Note that u = q * v + r for r < q.
+// 1. 0 % 0 or u % 0 => error
+// 2. 0 % v => 0 = 0 * v + 0
+// 3. u % v && u = v => u = 1 * u + 0 - u or v can be 1 or -1
+// 4. u % v && u < v => u = 0 * v + u - u can be 1 or -1
+// 5. u % v && u > v => u = q * v + r - v can be 1 or -1
+
+sc_unsigned
+operator%(const sc_unsigned& u, const sc_unsigned& v)
+{
+
+ if ((u.sgn == SC_ZERO) || (v.sgn == SC_ZERO)) {
+ div_by_zero(v.sgn); // case 1
+ return sc_unsigned(); // case 2
+ }
+
+ // other cases
+ return mod_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ v.nbits, v.ndigits, v.digit);
+}
+
+
+sc_unsigned
+operator%(const sc_unsigned& u, uint64 v)
+{
+
+ if ((u.sgn == SC_ZERO) || (v == 0)) {
+ div_by_zero(v); // case 1
+ return sc_unsigned(); // case 2
+ }
+
+ CONVERT_INT64_2(v);
+
+ // other cases
+ return mod_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+
+sc_unsigned
+operator%(uint64 u, const sc_unsigned& v)
+{
+
+ if ((u == 0) || (v.sgn == SC_ZERO)) {
+ div_by_zero(v.sgn); // case 1
+ return sc_unsigned(); // case 2
+ }
+
+ CONVERT_INT64(u);
+
+ // other cases
+ return mod_unsigned_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_unsigned
+operator%(const sc_unsigned& u, unsigned long v)
+{
+
+ if ((u.sgn == SC_ZERO) || (v == 0)) {
+ div_by_zero(v); // case 1
+ return sc_unsigned(); // case 2
+ }
+
+ CONVERT_LONG_2(v);
+
+ // other cases
+ return mod_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+}
+
+
+sc_unsigned
+operator%(unsigned long u, const sc_unsigned& v)
+{
+
+ if ((u == 0) || (v.sgn == SC_ZERO)) {
+ div_by_zero(v.sgn); // case 1
+ return sc_unsigned(); // case 2
+ }
+
+ CONVERT_LONG(u);
+
+ // other cases
+ return mod_unsigned_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.nbits, v.ndigits, v.digit);
+
+}
+
+// The rest of the operators in this section are included from
+// sc_nbcommon.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Bitwise AND operators: &, &=
+// ----------------------------------------------------------------------------
+
+// Cases to consider when computing u & v:
+// 1. u & 0 = 0 & v = 0
+// 2. u & v => sgn = +
+// 3. (-u) & (-v) => sgn = -
+// 4. u & (-v) => sgn = +
+// 5. (-u) & v => sgn = +
+
+sc_unsigned
+operator&(const sc_unsigned& u, const sc_unsigned& v)
+{
+
+ if ((u.sgn == SC_ZERO) || (v.sgn == SC_ZERO)) // case 1
+ return sc_unsigned();
+
+ // other cases
+ return and_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_unsigned
+operator&(const sc_unsigned& u, uint64 v)
+{
+
+ if ((u.sgn == SC_ZERO) || (v == 0)) // case 1
+ return sc_unsigned();
+
+ CONVERT_INT64(v);
+
+ // other cases
+ return and_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+
+sc_unsigned
+operator&(uint64 u, const sc_unsigned& v)
+{
+
+ if ((u == 0) || (v.sgn == SC_ZERO)) // case 1
+ return sc_unsigned();
+
+ CONVERT_INT64(u);
+
+ // other cases
+ return and_unsigned_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_unsigned
+operator&(const sc_unsigned& u, unsigned long v)
+{
+
+ if ((u.sgn == SC_ZERO) || (v == 0)) // case 1
+ return sc_unsigned();
+
+ CONVERT_LONG(v);
+
+ // other cases
+ return and_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+}
+
+
+sc_unsigned
+operator&(unsigned long u, const sc_unsigned& v)
+{
+
+ if ((u == 0) || (v.sgn == SC_ZERO)) // case 1
+ return sc_unsigned();
+
+ CONVERT_LONG(u);
+
+ // other cases
+ return and_unsigned_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+// The rest of the operators in this section are included from
+// sc_nbcommon.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Bitwise OR operators: |, |=
+// ----------------------------------------------------------------------------
+
+// Cases to consider when computing u | v:
+// 1. u | 0 = u
+// 2. 0 | v = v
+// 3. u | v => sgn = +
+// 4. (-u) | (-v) => sgn = -
+// 5. u | (-v) => sgn = -
+// 6. (-u) | v => sgn = -
+
+sc_unsigned
+operator|(const sc_unsigned& u, const sc_unsigned& v)
+{
+
+ if (v.sgn == SC_ZERO) // case 1
+ return sc_unsigned(u);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_unsigned(v);
+
+ // other cases
+ return or_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_unsigned
+operator|(const sc_unsigned& u, uint64 v)
+{
+
+ if (v == 0) // case 1
+ return sc_unsigned(u);
+
+ CONVERT_INT64(v);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_unsigned(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
+
+ // other cases
+ return or_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+
+sc_unsigned
+operator|(uint64 u, const sc_unsigned& v)
+{
+
+ if (u == 0)
+ return sc_unsigned(v);
+
+ CONVERT_INT64(u);
+
+ if (v.sgn == SC_ZERO)
+ return sc_unsigned(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
+
+ // other cases
+ return or_unsigned_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_unsigned
+operator|(const sc_unsigned& u, unsigned long v)
+{
+
+ if (v == 0) // case 1
+ return sc_unsigned(u);
+
+ CONVERT_LONG(v);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_unsigned(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
+
+ // other cases
+ return or_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+}
+
+
+sc_unsigned
+operator|(unsigned long u, const sc_unsigned& v)
+{
+
+ if (u == 0)
+ return sc_unsigned(v);
+
+ CONVERT_LONG(u);
+
+ if (v.sgn == SC_ZERO)
+ return sc_unsigned(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
+
+ // other cases
+ return or_unsigned_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+// The rest of the operators in this section are included from
+// sc_nbcommon.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Bitwise XOR operators: ^, ^=
+// ----------------------------------------------------------------------------
+
+// Cases to consider when computing u ^ v:
+// Note that u ^ v = (~u & v) | (u & ~v).
+// 1. u ^ 0 = u
+// 2. 0 ^ v = v
+// 3. u ^ v => sgn = +
+// 4. (-u) ^ (-v) => sgn = -
+// 5. u ^ (-v) => sgn = -
+// 6. (-u) ^ v => sgn = +
+
+sc_unsigned
+operator^(const sc_unsigned& u, const sc_unsigned& v)
+{
+
+ if (v.sgn == SC_ZERO) // case 1
+ return sc_unsigned(u);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_unsigned(v);
+
+ // other cases
+ return xor_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_unsigned
+operator^(const sc_unsigned& u, uint64 v)
+{
+
+ if (v == 0) // case 1
+ return sc_unsigned(u);
+
+ CONVERT_INT64(v);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_unsigned(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);
+
+ // other cases
+ return xor_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
+
+}
+
+sc_unsigned
+operator^(uint64 u, const sc_unsigned& v)
+{
+ if (u == 0)
+ return sc_unsigned(v);
+
+ CONVERT_INT64(u);
+
+ if (v.sgn == SC_ZERO)
+ return sc_unsigned(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);
+
+ // other cases
+ return xor_unsigned_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+
+sc_unsigned
+operator^(const sc_unsigned& u, unsigned long v)
+{
+
+ if (v == 0) // case 1
+ return sc_unsigned(u);
+
+ CONVERT_LONG(v);
+
+ if (u.sgn == SC_ZERO) // case 2
+ return sc_unsigned(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);
+
+ // other cases
+ return xor_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
+
+}
+
+sc_unsigned
+operator^(unsigned long u, const sc_unsigned& v)
+{
+ if (u == 0)
+ return sc_unsigned(v);
+
+ CONVERT_LONG(u);
+
+ if (v.sgn == SC_ZERO)
+ return sc_unsigned(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);
+
+ // other cases
+ return xor_unsigned_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit);
+
+}
+
+// The rest of the operators in this section are included from
+// sc_nbcommon.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Bitwise NOT operator: ~
+// ----------------------------------------------------------------------------
+
+// Operators in this section are included from sc_nbcommon.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: LEFT SHIFT operators: <<, <<=
+// ----------------------------------------------------------------------------
+
+sc_unsigned
+operator<<(const sc_unsigned& u, const sc_signed& v)
+{
+ if ((v.sgn == SC_ZERO) || (v.sgn == SC_NEG))
+ return sc_unsigned(u);
+
+ return operator<<(u, v.to_ulong());
+}
+
+// The rest of the operators in this section are included from
+// sc_nbcommon.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: RIGHT SHIFT operators: >>, >>=
+// ----------------------------------------------------------------------------
+
+sc_unsigned
+operator>>(const sc_unsigned& u, const sc_signed& v)
+{
+
+ if ((v.sgn == SC_ZERO) || (v.sgn == SC_NEG))
+ return sc_unsigned(u);
+
+ return operator>>(u, v.to_long());
+
+}
+
+// The rest of the operators in this section are included from
+// sc_nbcommon.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Unary arithmetic operators.
+// ----------------------------------------------------------------------------
+
+sc_unsigned
+operator+(const sc_unsigned& u)
+{
+ return sc_unsigned(u);
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: EQUAL operator: ==
+// ----------------------------------------------------------------------------
+
+bool
+operator==(const sc_unsigned& u, const sc_unsigned& v)
+{
+ if (&u == &v)
+ return true;
+ if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
+ v.sgn, v.nbits, v.ndigits, v.digit) != 0)
+ return false;
+ return true;
+}
+
+
+bool
+operator==(const sc_unsigned& u, const sc_signed& v)
+{
+ if (v.sgn == SC_NEG)
+ return false;
+ if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
+ v.sgn, v.nbits, v.ndigits, v.digit, 0, 1) != 0)
+ return false;
+ return true;
+}
+
+
+bool
+operator==(const sc_signed& u, const sc_unsigned& v)
+{
+ if (u.sgn == SC_NEG)
+ return false;
+ if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
+ v.sgn, v.nbits, v.ndigits, v.digit, 1, 0) != 0)
+ return false;
+ return true;
+}
+
+
+bool
+operator==(const sc_unsigned& u, int64 v)
+{
+ if (v < 0)
+ return false;
+ CONVERT_INT64(v);
+ if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd) != 0)
+ return false;
+ return true;
+}
+
+
+bool
+operator==(int64 u, const sc_unsigned& v)
+{
+ if (u < 0)
+ return false;
+ CONVERT_INT64(u);
+ if (compare_unsigned(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit) != 0)
+ return false;
+ return true;
+}
+
+
+bool
+operator==(const sc_unsigned& u, uint64 v)
+{
+ CONVERT_INT64(v);
+ if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd) != 0)
+ return false;
+ return true;
+}
+
+
+bool
+operator==(uint64 u, const sc_unsigned& v)
+{
+ CONVERT_INT64(u);
+ if (compare_unsigned(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit) != 0)
+ return false;
+ return true;
+}
+
+
+bool
+operator==(const sc_unsigned& u, long v)
+{
+ if (v < 0)
+ return false;
+ CONVERT_LONG(v);
+ if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd) != 0)
+ return false;
+ return true;
+}
+
+
+bool
+operator==(long u, const sc_unsigned& v)
+{
+ if (u < 0)
+ return false;
+ CONVERT_LONG(u);
+ if (compare_unsigned(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit) != 0)
+ return false;
+ return true;
+}
+
+
+bool
+operator==(const sc_unsigned& u, unsigned long v)
+{
+ CONVERT_LONG(v);
+ if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd) != 0)
+ return false;
+ return true;
+}
+
+
+bool
+operator==(unsigned long u, const sc_unsigned& v)
+{
+ CONVERT_LONG(u);
+ if (compare_unsigned(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit) != 0)
+ return false;
+ return true;
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: NOT_EQUAL operator: !=
+// ----------------------------------------------------------------------------
+
+bool
+operator!=(const sc_unsigned& u, const sc_signed& v)
+{
+ return (! operator==(u, v));
+}
+
+
+bool
+operator!=(const sc_signed& u, const sc_unsigned& v)
+{
+ return (! operator==(u, v));
+}
+
+// The rest of the operators in this section are included from sc_nbcommon.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: LESS THAN operator: <
+// ----------------------------------------------------------------------------
+
+bool
+operator<(const sc_unsigned& u, const sc_unsigned& v)
+{
+ if (&u == &v)
+ return false;
+ if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
+ v.sgn, v.nbits, v.ndigits, v.digit) < 0)
+ return true;
+ return false;
+}
+
+
+bool
+operator<(const sc_unsigned& u, const sc_signed& v)
+{
+ if (v.sgn == SC_NEG)
+ return false;
+ if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
+ v.sgn, v.nbits, v.ndigits, v.digit, 0, 1) < 0)
+ return true;
+ return false;
+}
+
+
+bool
+operator<(const sc_signed& u, const sc_unsigned& v)
+{
+ if (u.sgn == SC_NEG)
+ return true;
+ if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
+ v.sgn, v.nbits, v.ndigits, v.digit, 1, 0) < 0)
+ return true;
+ return false;
+}
+
+
+bool
+operator<(const sc_unsigned& u, int64 v)
+{
+ if (v < 0)
+ return false;
+ CONVERT_INT64(v);
+ if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd) < 0)
+ return true;
+ return false;
+}
+
+
+bool
+operator<(int64 u, const sc_unsigned& v)
+{
+ if (u < 0)
+ return true;
+ CONVERT_INT64(u);
+ if (compare_unsigned(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit) < 0)
+ return true;
+ return false;
+}
+
+
+bool
+operator<(const sc_unsigned& u, uint64 v)
+{
+ CONVERT_INT64(v);
+ if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd) < 0)
+ return true;
+ return false;
+}
+
+
+bool
+operator<(uint64 u, const sc_unsigned& v)
+{
+ CONVERT_INT64(u);
+ if (compare_unsigned(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit) < 0)
+ return true;
+ return false;
+}
+
+
+bool
+operator<(const sc_unsigned& u, long v)
+{
+ if (v < 0)
+ return false;
+ CONVERT_LONG(v);
+ if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd) < 0)
+ return true;
+ return false;
+}
+
+
+bool
+operator<(long u, const sc_unsigned& v)
+{
+ if (u < 0)
+ return true;
+ CONVERT_LONG(u);
+ if (compare_unsigned(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit) < 0)
+ return true;
+ return false;
+}
+
+
+bool
+operator<(const sc_unsigned& u, unsigned long v)
+{
+ CONVERT_LONG(v);
+ if (compare_unsigned(u.sgn, u.nbits, u.ndigits, u.digit,
+ vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd) < 0)
+ return true;
+ return false;
+}
+
+
+bool
+operator<(unsigned long u, const sc_unsigned& v)
+{
+ CONVERT_LONG(u);
+ if (compare_unsigned(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,
+ v.sgn, v.nbits, v.ndigits, v.digit) < 0)
+ return true;
+ return false;
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: LESS THAN or EQUAL operator: <=
+// ----------------------------------------------------------------------------
+
+bool
+operator<=(const sc_unsigned& u, const sc_signed& v)
+{
+ return (operator<(u, v) || operator==(u, v));
+}
+
+
+bool
+operator<=(const sc_signed& u, const sc_unsigned& v)
+{
+ return (operator<(u, v) || operator==(u, v));
+}
+
+// The rest of the operators in this section are included from sc_nbcommon.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: GREATER THAN operator: >
+// ----------------------------------------------------------------------------
+
+bool
+operator>(const sc_unsigned& u, const sc_signed& v)
+{
+ return (! (operator<=(u, v)));
+}
+
+
+bool
+operator>(const sc_signed& u, const sc_unsigned& v)
+{
+ return (! (operator<=(u, v)));
+}
+
+// The rest of the operators in this section are included from sc_nbcommon.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: GREATER THAN or EQUAL operator: >=
+// ----------------------------------------------------------------------------
+
+bool
+operator>=(const sc_unsigned& u, const sc_signed& v)
+{
+ return (! (operator<(u, v)));
+}
+
+
+bool
+operator>=(const sc_signed& u, const sc_unsigned& v)
+{
+ return (! (operator<(u, v)));
+}
+
+// The rest of the operators in this section are included from sc_nbcommon.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Friends
+// ----------------------------------------------------------------------------
+
+// Compare u and v as unsigned and return r
+// r = 0 if u == v
+// r < 0 if u < v
+// r > 0 if u > v
+
+int
+compare_unsigned(small_type us,
+ int unb, int und, const sc_digit *ud,
+ small_type vs,
+ int vnb, int vnd, const sc_digit *vd,
+ small_type if_u_signed,
+ small_type if_v_signed)
+{
+
+ if (us == vs) {
+
+ if (us == SC_ZERO)
+ return 0;
+
+ else {
+
+ int cmp_res = vec_skip_and_cmp(und, ud, vnd, vd);
+
+ if (us == SC_POS)
+ return cmp_res;
+ else
+ return -cmp_res;
+
+ }
+ }
+ else {
+
+ if (us == SC_ZERO)
+ return -vs;
+
+ if (vs == SC_ZERO)
+ return us;
+
+ int cmp_res;
+
+ int nd = (us == SC_NEG ? und : vnd);
+
+#ifdef SC_MAX_NBITS
+ sc_digit d[MAX_NDIGITS];
+#else
+ sc_digit *d = new sc_digit[nd];
+#endif
+
+ if (us == SC_NEG) {
+
+ vec_copy(nd, d, ud);
+ vec_complement(nd, d);
+ trim(if_u_signed, unb, nd, d);
+ cmp_res = vec_skip_and_cmp(nd, d, vnd, vd);
+
+ }
+ else {
+
+ vec_copy(nd, d, vd);
+ vec_complement(nd, d);
+ trim(if_v_signed, vnb, nd, d);
+ cmp_res = vec_skip_and_cmp(und, ud, nd, d);
+
+ }
+
+#ifndef SC_MAX_NBITS
+ delete [] d;
+#endif
+
+ return cmp_res;
+
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Public members - Other utils.
+// ----------------------------------------------------------------------------
+
+bool
+sc_unsigned::iszero() const
+{
+ if (sgn == SC_ZERO)
+ return true;
+
+ else if (sgn == SC_NEG) {
+
+ // A negative unsigned number can be zero, e.g., -16 in 4 bits, so
+ // check that.
+
+#ifdef SC_MAX_NBITS
+ sc_digit d[MAX_NDIGITS];
+#else
+ sc_digit *d = new sc_digit[ndigits];
+#endif
+
+ vec_copy(ndigits, d, digit);
+ vec_complement(ndigits, d);
+ trim_unsigned(nbits, ndigits, d);
+
+ bool res = check_for_zero(ndigits, d);
+
+#ifndef SC_MAX_NBITS
+ delete [] d;
+#endif
+
+ return res;
+
+ }
+ else
+ return false;
+}
+
+// The rest of the utils in this section are included from sc_nbcommon.cpp.
+
+
+// ----------------------------------------------------------------------------
+// SECTION: Private members.
+// ----------------------------------------------------------------------------
+
+// The private members in this section are included from
+// sc_nbcommon.cpp.
+
+#define CLASS_TYPE sc_unsigned
+#define CLASS_TYPE_STR "sc_unsigned"
+
+#define ADD_HELPER add_unsigned_friend
+#define SUB_HELPER sub_unsigned_friend
+#define MUL_HELPER mul_unsigned_friend
+#define DIV_HELPER div_unsigned_friend
+#define MOD_HELPER mod_unsigned_friend
+#define AND_HELPER and_unsigned_friend
+#define OR_HELPER or_unsigned_friend
+#define XOR_HELPER xor_unsigned_friend
+
+#include "sc_nbfriends.inc"
+
+#undef SC_SIGNED
+#define SC_UNSIGNED
+#define IF_SC_SIGNED 0 // 0 = sc_unsigned
+#define CLASS_TYPE_SUBREF sc_unsigned_subref_r
+#define OTHER_CLASS_TYPE sc_signed
+#define OTHER_CLASS_TYPE_SUBREF sc_signed_subref_r
+
+#define MUL_ON_HELPER mul_on_help_unsigned
+#define DIV_ON_HELPER div_on_help_unsigned
+#define MOD_ON_HELPER mod_on_help_unsigned
+
+#include "sc_nbcommon.inc"
+
+#undef MOD_ON_HELPER
+#undef DIV_ON_HELPER
+#undef MUL_ON_HELPER
+
+#undef OTHER_CLASS_TYPE_SUBREF
+#undef OTHER_CLASS_TYPE
+#undef CLASS_TYPE_SUBREF
+#undef IF_SC_SIGNED
+#undef SC_UNSIGNED
+
+#undef XOR_HELPER
+#undef OR_HELPER
+#undef AND_HELPER
+#undef MOD_HELPER
+#undef DIV_HELPER
+#undef MUL_HELPER
+#undef SUB_HELPER
+#undef ADD_HELPER
+
+#undef CLASS_TYPE
+#undef CLASS_TYPE_STR
+
+#include "sc_unsigned_bitref.inc"
+#include "sc_unsigned_subref.inc"
+
+#undef CONVERT_LONG
+#undef CONVERT_LONG_2
+#undef CONVERT_INT64
+#undef CONVERT_INT64_2
+
+} // namespace sc_dt
+
+
+// End of file.
diff --git a/ext/systemc/src/sysc/datatypes/int/sc_unsigned.h b/ext/systemc/src/sysc/datatypes/int/sc_unsigned.h
new file mode 100644
index 000000000..4260542a3
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/int/sc_unsigned.h
@@ -0,0 +1,2191 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_unsigned.h -- Arbitrary precision unsigned arithmetic.
+
+ This file includes the definitions of sc_unsigned_bitref,
+ sc_unsigned_subref, and sc_unsigned classes. The first two classes
+ are proxy classes to reference one bit and a range of bits of a
+ sc_unsigned number, respectively.
+
+ An sc_signed number has the sign-magnitude representation
+ internally. However, its interface guarantees a 2's-complement
+ representation. The sign-magnitude representation is chosen
+ because of its efficiency: The sc_signed and sc_unsigned types are
+ optimized for arithmetic rather than bitwise operations. For
+ arithmetic operations, the sign-magnitude representation performs
+ better.
+
+ It is also important to note that an sc_unsigned number with n
+ bits is equivalent to an sc_signed non-negative number with n + 1
+ bits.
+
+ The implementations of sc_signed and sc_unsigned classes are
+ almost identical: Most of the member and friend functions are
+ defined in sc_nbcommon.cpp and sc_nbfriends.cpp so that they can
+ be shared by both of these classes. These functions are chosed by
+ defining a few macros before including them such as IF_SC_SIGNED
+ and CLASS_TYPE. Our implementation choices are mostly dictated by
+ performance considerations in that we tried to provide the most
+ efficient sc_signed and sc_unsigned types without compromising
+ their interface.
+
+ For the behavior of operators, we have two semantics: the old and
+ new. The most important difference between these two semantics is
+ that the old semantics is closer to C/C++ semantics in that the
+ result type of a binary operator on unsigned and signed arguments
+ is unsigned; the new semantics, on the other hand, requires the
+ result type be signed. The new semantics is required by the VSIA
+ C/C++ data types standard. We have implemented the new semantics.
+
+ Original Author: Ali Dasdan, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_unsigned.h,v $
+// Revision 1.4 2011/08/24 22:05:46 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.3 2011/02/18 20:19:15 acg
+// Andy Goodrich: updating Copyright notice.
+//
+// Revision 1.2 2009/02/28 00:26:26 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.5 2006/05/08 17:50:02 acg
+// Andy Goodrich: Added David Long's declarations for friend operators,
+// functions, and methods, to keep the Microsoft compiler happy.
+//
+// Revision 1.4 2006/03/13 20:25:27 acg
+// Andy Goodrich: Addition of function declarations, e.g., xor_signed_friend()
+// to keep gcc 4.x happy.
+//
+// Revision 1.3 2006/01/13 18:49:32 acg
+// Added $Log command so that CVS check in comments are reproduced in the
+// source.
+//
+
+#ifndef SC_UNSIGNED_H
+#define SC_UNSIGNED_H
+
+
+#include "sysc/kernel/sc_object.h"
+#include "sysc/datatypes/misc/sc_value_base.h"
+#include "sysc/utils/sc_iostream.h"
+#include "sysc/utils/sc_temporary.h"
+#include "sysc/datatypes/int/sc_length_param.h"
+#include "sysc/datatypes/int/sc_nbdefs.h"
+#include "sysc/datatypes/int/sc_nbutils.h"
+#include "sysc/datatypes/int/sc_nbexterns.h"
+#include "sysc/utils/sc_temporary.h"
+
+
+namespace sc_dt
+{
+
+// classes defined in this module
+class sc_unsigned_bitref_r;
+class sc_unsigned_bitref;
+class sc_unsigned_subref_r;
+class sc_unsigned_subref;
+class sc_concatref;
+class sc_unsigned;
+
+// forward class declarations
+class sc_bv_base;
+class sc_lv_base;
+class sc_int_base;
+class sc_uint_base;
+class sc_int_subref_r;
+class sc_uint_subref_r;
+class sc_signed;
+class sc_signed_subref_r;
+class sc_fxval;
+class sc_fxval_fast;
+class sc_fxnum;
+class sc_fxnum_fast;
+
+// Helper function declarions
+int compare_unsigned(small_type us,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ small_type vs,
+ int vnb,
+ int vnd,
+ const sc_digit *vd,
+ small_type if_u_signed=0,
+ small_type if_v_signed=0);
+
+sc_unsigned add_unsigned_friend(small_type us,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ small_type vs,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+sc_unsigned sub_unsigned_friend(small_type us,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ small_type vs,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+sc_unsigned mul_unsigned_friend(small_type s,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+sc_unsigned div_unsigned_friend(small_type s,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+sc_unsigned mod_unsigned_friend(small_type us,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+sc_unsigned and_unsigned_friend(small_type us,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ small_type vs,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+
+sc_unsigned or_unsigned_friend(small_type us,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ small_type vs,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+sc_unsigned xor_unsigned_friend(small_type us,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ small_type vs,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+// friend operator declarations
+ // ARITHMETIC OPERATORS:
+
+ // ADDition operators:
+
+ sc_signed operator + (const sc_unsigned& u, const sc_signed& v);
+ sc_signed operator + (const sc_signed& u, const sc_unsigned& v);
+
+ sc_unsigned operator + (const sc_unsigned& u, const sc_unsigned& v);
+ sc_signed operator + (const sc_unsigned& u, int64 v);
+ sc_unsigned operator + (const sc_unsigned& u, uint64 v);
+ sc_signed operator + (const sc_unsigned& u, long v);
+ sc_unsigned operator + (const sc_unsigned& u, unsigned long v);
+ sc_signed operator + (const sc_unsigned& u, int v);
+ inline sc_unsigned operator + (const sc_unsigned& u, unsigned int v);
+
+ sc_signed operator + (int64 u, const sc_unsigned& v);
+ sc_unsigned operator + (uint64 u, const sc_unsigned& v);
+ sc_signed operator + (long u, const sc_unsigned& v);
+ sc_unsigned operator + (unsigned long u, const sc_unsigned& v);
+ sc_signed operator + (int u, const sc_unsigned& v);
+ inline sc_unsigned operator + (unsigned int u, const sc_unsigned& v);
+
+ sc_unsigned operator + (const sc_unsigned& u, const sc_uint_base& v);
+ sc_signed operator + (const sc_unsigned& u, const sc_int_base& v);
+ sc_unsigned operator + (const sc_uint_base& u, const sc_unsigned& v);
+ sc_signed operator + (const sc_int_base& u, const sc_unsigned& v);
+
+ // SUBtraction operators:
+
+ sc_signed operator - (const sc_unsigned& u, const sc_signed& v);
+ sc_signed operator - (const sc_signed& u, const sc_unsigned& v);
+
+ sc_signed operator - (const sc_unsigned& u, const sc_unsigned& v);
+ sc_signed operator - (const sc_unsigned& u, int64 v);
+ sc_signed operator - (const sc_unsigned& u, uint64 v);
+ sc_signed operator - (const sc_unsigned& u, long v);
+ sc_signed operator - (const sc_unsigned& u, unsigned long v);
+ sc_signed operator - (const sc_unsigned& u, int v);
+ sc_signed operator - (const sc_unsigned& u, unsigned int v);
+
+ sc_signed operator - (int64 u, const sc_unsigned& v);
+ sc_signed operator - (uint64 u, const sc_unsigned& v);
+ sc_signed operator - (long u, const sc_unsigned& v);
+ sc_signed operator - (unsigned long u, const sc_unsigned& v);
+ sc_signed operator - (int u, const sc_unsigned& v);
+ sc_signed operator - (unsigned int u, const sc_unsigned& v);
+
+ sc_signed operator - (const sc_unsigned& u, const sc_uint_base& v);
+ sc_signed operator - (const sc_unsigned& u, const sc_int_base& v);
+ sc_signed operator - (const sc_uint_base& u, const sc_unsigned& v);
+ sc_signed operator - (const sc_int_base& u, const sc_unsigned& v);
+
+ // MULtiplication operators:
+
+ sc_signed operator * (const sc_unsigned& u, const sc_signed& v);
+ sc_signed operator * (const sc_signed& u, const sc_unsigned& v);
+
+ sc_unsigned operator * (const sc_unsigned& u, const sc_unsigned& v);
+ sc_signed operator * (const sc_unsigned& u, int64 v);
+ sc_unsigned operator * (const sc_unsigned& u, uint64 v);
+ sc_signed operator * (const sc_unsigned& u, long v);
+ sc_unsigned operator * (const sc_unsigned& u, unsigned long v);
+ sc_signed operator * (const sc_unsigned& u, int v);
+ inline sc_unsigned operator * (const sc_unsigned& u, unsigned int v);
+
+ sc_signed operator * (int64 u, const sc_unsigned& v);
+ sc_unsigned operator * (uint64 u, const sc_unsigned& v);
+ sc_signed operator * (long u, const sc_unsigned& v);
+ sc_unsigned operator * (unsigned long u, const sc_unsigned& v);
+ sc_signed operator * (int u, const sc_unsigned& v);
+ inline sc_unsigned operator * (unsigned int u, const sc_unsigned& v);
+
+ sc_unsigned operator * (const sc_unsigned& u, const sc_uint_base& v);
+ sc_signed operator * (const sc_unsigned& u, const sc_int_base& v);
+ sc_unsigned operator * (const sc_uint_base& u, const sc_unsigned& v);
+ sc_signed operator * (const sc_int_base& u, const sc_unsigned& v);
+
+ // DIVision operators:
+
+ sc_signed operator / (const sc_unsigned& u, const sc_signed& v);
+ sc_signed operator / (const sc_signed& u, const sc_unsigned& v);
+
+ sc_unsigned operator / (const sc_unsigned& u, const sc_unsigned& v);
+ sc_signed operator / (const sc_unsigned& u, int64 v);
+ sc_unsigned operator / (const sc_unsigned& u, uint64 v);
+ sc_signed operator / (const sc_unsigned& u, long v);
+ sc_unsigned operator / (const sc_unsigned& u, unsigned long v);
+ sc_signed operator / (const sc_unsigned& u, int v);
+ inline sc_unsigned operator / (const sc_unsigned& u, unsigned int v);
+
+ sc_signed operator / (int64 u, const sc_unsigned& v);
+ sc_unsigned operator / (uint64 u, const sc_unsigned& v);
+ sc_signed operator / (long u, const sc_unsigned& v);
+ sc_unsigned operator / (unsigned long u, const sc_unsigned& v);
+ sc_signed operator / (int u, const sc_unsigned& v);
+ inline sc_unsigned operator / (unsigned int u, const sc_unsigned& v);
+
+ sc_unsigned operator / (const sc_unsigned& u, const sc_uint_base& v);
+ sc_signed operator / (const sc_unsigned& u, const sc_int_base& v);
+ sc_unsigned operator / (const sc_uint_base& u, const sc_unsigned& v);
+ sc_signed operator / (const sc_int_base& u, const sc_unsigned& v);
+
+ // MODulo operators:
+
+ sc_signed operator % (const sc_unsigned& u, const sc_signed& v);
+ sc_signed operator % (const sc_signed& u, const sc_unsigned& v);
+
+ sc_unsigned operator % (const sc_unsigned& u, const sc_unsigned& v);
+ sc_signed operator % (const sc_unsigned& u, int64 v);
+ sc_unsigned operator % (const sc_unsigned& u, uint64 v);
+ sc_signed operator % (const sc_unsigned& u, long v);
+ sc_unsigned operator % (const sc_unsigned& u, unsigned long v);
+ sc_signed operator % (const sc_unsigned& u, int v);
+ inline sc_unsigned operator % (const sc_unsigned& u, unsigned int v);
+
+ sc_signed operator % (int64 u, const sc_unsigned& v);
+ sc_unsigned operator % (uint64 u, const sc_unsigned& v);
+ sc_signed operator % (long u, const sc_unsigned& v);
+ sc_unsigned operator % (unsigned long u, const sc_unsigned& v);
+ sc_signed operator % (int u, const sc_unsigned& v);
+ inline sc_unsigned operator % (unsigned int u, const sc_unsigned& v);
+
+ sc_unsigned operator % (const sc_unsigned& u, const sc_uint_base& v);
+ sc_signed operator % (const sc_unsigned& u, const sc_int_base& v);
+ sc_unsigned operator % (const sc_uint_base& u, const sc_unsigned& v);
+ sc_signed operator % (const sc_int_base& u, const sc_unsigned& v);
+
+ // BITWISE OPERATORS:
+
+ // Bitwise AND operators:
+
+ sc_signed operator & (const sc_unsigned& u, const sc_signed& v);
+ sc_signed operator & (const sc_signed& u, const sc_unsigned& v);
+
+ sc_unsigned operator & (const sc_unsigned& u, const sc_unsigned& v);
+ sc_signed operator & (const sc_unsigned& u, int64 v);
+ sc_unsigned operator & (const sc_unsigned& u, uint64 v);
+ sc_signed operator & (const sc_unsigned& u, long v);
+ sc_unsigned operator & (const sc_unsigned& u, unsigned long v);
+ sc_signed operator & (const sc_unsigned& u, int v);
+ inline sc_unsigned operator & (const sc_unsigned& u, unsigned int v);
+
+ sc_signed operator & (int64 u, const sc_unsigned& v);
+ sc_unsigned operator & (uint64 u, const sc_unsigned& v);
+ sc_signed operator & (long u, const sc_unsigned& v);
+ sc_unsigned operator & (unsigned long u, const sc_unsigned& v);
+ sc_signed operator & (int u, const sc_unsigned& v);
+ inline sc_unsigned operator & (unsigned int u, const sc_unsigned& v);
+
+ sc_unsigned operator & (const sc_unsigned& u, const sc_uint_base& v);
+ sc_signed operator & (const sc_unsigned& u, const sc_int_base& v);
+ sc_unsigned operator & (const sc_uint_base& u, const sc_unsigned& v);
+ sc_signed operator & (const sc_int_base& u, const sc_unsigned& v);
+
+ // Bitwise OR operators:
+
+ sc_signed operator | (const sc_unsigned& u, const sc_signed& v);
+ sc_signed operator | (const sc_signed& u, const sc_unsigned& v);
+
+ sc_unsigned operator | (const sc_unsigned& u, const sc_unsigned& v);
+ sc_signed operator | (const sc_unsigned& u, int64 v);
+ sc_unsigned operator | (const sc_unsigned& u, uint64 v);
+ sc_signed operator | (const sc_unsigned& u, long v);
+ sc_unsigned operator | (const sc_unsigned& u, unsigned long v);
+ sc_signed operator | (const sc_unsigned& u, int v);
+ inline sc_unsigned operator | (const sc_unsigned& u, unsigned int v);
+
+ sc_signed operator | (int64 u, const sc_unsigned& v);
+ sc_unsigned operator | (uint64 u, const sc_unsigned& v);
+ sc_signed operator | (long u, const sc_unsigned& v);
+ sc_unsigned operator | (unsigned long u, const sc_unsigned& v);
+ sc_signed operator | (int u, const sc_unsigned& v);
+ inline sc_unsigned operator | (unsigned int u, const sc_unsigned& v);
+
+ sc_unsigned operator | (const sc_unsigned& u, const sc_uint_base& v);
+ sc_signed operator | (const sc_unsigned& u, const sc_int_base& v);
+ sc_unsigned operator | (const sc_uint_base& u, const sc_unsigned& v);
+ sc_signed operator | (const sc_int_base& u, const sc_unsigned& v);
+
+ // Bitwise XOR operators:
+
+ sc_signed operator ^ (const sc_unsigned& u, const sc_signed& v);
+ sc_signed operator ^ (const sc_signed& u, const sc_unsigned& v);
+
+ sc_unsigned operator ^ (const sc_unsigned& u, const sc_unsigned& v);
+ sc_signed operator ^ (const sc_unsigned& u, int64 v);
+ sc_unsigned operator ^ (const sc_unsigned& u, uint64 v);
+ sc_signed operator ^ (const sc_unsigned& u, long v);
+ sc_unsigned operator ^ (const sc_unsigned& u, unsigned long v);
+ sc_signed operator ^ (const sc_unsigned& u, int v);
+ inline sc_unsigned operator ^ (const sc_unsigned& u, unsigned int v);
+
+ sc_signed operator ^ (int64 u, const sc_unsigned& v);
+ sc_unsigned operator ^ (uint64 u, const sc_unsigned& v);
+ sc_signed operator ^ (long u, const sc_unsigned& v);
+ sc_unsigned operator ^ (unsigned long u, const sc_unsigned& v);
+ sc_signed operator ^ (int u, const sc_unsigned& v);
+ inline sc_unsigned operator ^ (unsigned int u, const sc_unsigned& v);
+
+ sc_unsigned operator ^ (const sc_unsigned& u, const sc_uint_base& v);
+ sc_signed operator ^ (const sc_unsigned& u, const sc_int_base& v);
+ sc_unsigned operator ^ (const sc_uint_base& u, const sc_unsigned& v);
+ sc_signed operator ^ (const sc_int_base& u, const sc_unsigned& v);
+
+ // SHIFT OPERATORS:
+
+ // LEFT SHIFT operators:
+
+ sc_unsigned operator << (const sc_unsigned& u, const sc_signed& v);
+ sc_signed operator << (const sc_signed& u, const sc_unsigned& v);
+
+ sc_unsigned operator << (const sc_unsigned& u, const sc_unsigned& v);
+ sc_unsigned operator << (const sc_unsigned& u, int64 v);
+ sc_unsigned operator << (const sc_unsigned& u, uint64 v);
+ sc_unsigned operator << (const sc_unsigned& u, long v);
+ sc_unsigned operator << (const sc_unsigned& u, unsigned long v);
+ inline sc_unsigned operator << (const sc_unsigned& u, int v);
+ inline sc_unsigned operator << (const sc_unsigned& u, unsigned int v);
+
+ sc_unsigned operator << (const sc_unsigned& u, const sc_uint_base& v);
+ sc_unsigned operator << (const sc_unsigned& u, const sc_int_base& v);
+
+ // RIGHT SHIFT operators:
+
+ sc_unsigned operator >> (const sc_unsigned& u, const sc_signed& v);
+ sc_signed operator >> (const sc_signed& u, const sc_unsigned& v);
+
+ sc_unsigned operator >> (const sc_unsigned& u, const sc_unsigned& v);
+ sc_unsigned operator >> (const sc_unsigned& u, int64 v);
+ sc_unsigned operator >> (const sc_unsigned& u, uint64 v);
+ sc_unsigned operator >> (const sc_unsigned& u, long v);
+ sc_unsigned operator >> (const sc_unsigned& u, unsigned long v);
+ inline sc_unsigned operator >> (const sc_unsigned& u, int v);
+ inline sc_unsigned operator >> (const sc_unsigned& u, unsigned int v);
+
+ sc_unsigned operator >> ( const sc_unsigned& , const sc_uint_base& );
+ sc_unsigned operator >> ( const sc_unsigned&, const sc_int_base& );
+
+ // Unary arithmetic operators
+ sc_unsigned operator + (const sc_unsigned& u);
+ sc_signed operator - (const sc_unsigned& u);
+
+ // LOGICAL OPERATORS:
+
+ // Logical EQUAL operators:
+
+ bool operator == (const sc_unsigned& u, const sc_signed& v);
+ bool operator == (const sc_signed& u, const sc_unsigned& v);
+
+ bool operator == (const sc_unsigned& u, const sc_unsigned& v);
+ bool operator == (const sc_unsigned& u, int64 v);
+ bool operator == (const sc_unsigned& u, uint64 v);
+ bool operator == (const sc_unsigned& u, long v);
+ bool operator == (const sc_unsigned& u, unsigned long v);
+ inline bool operator == (const sc_unsigned& u, int v);
+ inline bool operator == (const sc_unsigned& u, unsigned int v);
+
+ bool operator == (int64 u, const sc_unsigned& v);
+ bool operator == (uint64 u, const sc_unsigned& v);
+ bool operator == (long u, const sc_unsigned& v);
+ bool operator == (unsigned long u, const sc_unsigned& v);
+ inline bool operator == (int u, const sc_unsigned& v);
+ inline bool operator == (unsigned int u, const sc_unsigned& v) ;
+
+ bool operator == (const sc_unsigned& u, const sc_uint_base& v);
+ bool operator == (const sc_unsigned& u, const sc_int_base& v);
+ bool operator == (const sc_uint_base& u, const sc_unsigned& v);
+ bool operator == (const sc_int_base& u, const sc_unsigned& v);
+
+ // Logical NOT_EQUAL operators:
+
+ bool operator != (const sc_unsigned& u, const sc_signed& v);
+ bool operator != (const sc_signed& u, const sc_unsigned& v);
+
+ bool operator != (const sc_unsigned& u, const sc_unsigned& v);
+ bool operator != (const sc_unsigned& u, int64 v);
+ bool operator != (const sc_unsigned& u, uint64 v);
+ bool operator != (const sc_unsigned& u, long v);
+ bool operator != (const sc_unsigned& u, unsigned long v);
+ inline bool operator != (const sc_unsigned& u, int v);
+ inline bool operator != (const sc_unsigned& u, unsigned int v);
+
+ bool operator != (int64 u, const sc_unsigned& v);
+ bool operator != (uint64 u, const sc_unsigned& v);
+ bool operator != (long u, const sc_unsigned& v);
+ bool operator != (unsigned long u, const sc_unsigned& v);
+ inline bool operator != (int u, const sc_unsigned& v);
+ inline bool operator != (unsigned int u, const sc_unsigned& v);
+
+ bool operator != (const sc_unsigned& u, const sc_uint_base& v);
+ bool operator != (const sc_unsigned& u, const sc_int_base& v);
+ bool operator != (const sc_uint_base& u, const sc_unsigned& v);
+ bool operator != (const sc_int_base& u, const sc_unsigned& v);
+
+ // Logical LESS_THAN operators:
+
+ bool operator < (const sc_unsigned& u, const sc_signed& v);
+ bool operator < (const sc_signed& u, const sc_unsigned& v);
+
+ bool operator < (const sc_unsigned& u, const sc_unsigned& v);
+ bool operator < (const sc_unsigned& u, int64 v);
+ bool operator < (const sc_unsigned& u, uint64 v);
+ bool operator < (const sc_unsigned& u, long v);
+ bool operator < (const sc_unsigned& u, unsigned long v);
+ inline bool operator < (const sc_unsigned& u, int v);
+ inline bool operator < (const sc_unsigned& u, unsigned int v);
+
+ bool operator < (int64 u, const sc_unsigned& v);
+ bool operator < (uint64 u, const sc_unsigned& v);
+ bool operator < (long u, const sc_unsigned& v);
+ bool operator < (unsigned long u, const sc_unsigned& v);
+ inline bool operator < (int u, const sc_unsigned& v);
+ inline bool operator < (unsigned int u, const sc_unsigned& v);
+
+ bool operator < (const sc_unsigned& u, const sc_uint_base& v);
+ bool operator < (const sc_unsigned& u, const sc_int_base& v);
+ bool operator < (const sc_uint_base& u, const sc_unsigned& v);
+ bool operator < (const sc_int_base& u, const sc_unsigned& v);
+
+ // Logical LESS_THAN_AND_EQUAL operators:
+
+ bool operator <= (const sc_unsigned& u, const sc_signed& v);
+ bool operator <= (const sc_signed& u, const sc_unsigned& v);
+
+ bool operator <= (const sc_unsigned& u, const sc_unsigned& v);
+ bool operator <= (const sc_unsigned& u, int64 v);
+ bool operator <= (const sc_unsigned& u, uint64 v);
+ bool operator <= (const sc_unsigned& u, long v);
+ bool operator <= (const sc_unsigned& u, unsigned long v);
+ inline bool operator <= (const sc_unsigned& u, int v);
+ inline bool operator <= (const sc_unsigned& u, unsigned int v);
+
+ bool operator <= (int64 u, const sc_unsigned& v);
+ bool operator <= (uint64 u, const sc_unsigned& v);
+ bool operator <= (long u, const sc_unsigned& v);
+ bool operator <= (unsigned long u, const sc_unsigned& v);
+ inline bool operator <= (int u, const sc_unsigned& v);
+ inline bool operator <= (unsigned int u, const sc_unsigned& v);
+
+ bool operator <= (const sc_unsigned& u, const sc_uint_base& v);
+ bool operator <= (const sc_unsigned& u, const sc_int_base& v);
+ bool operator <= (const sc_uint_base& u, const sc_unsigned& v);
+ bool operator <= (const sc_int_base& u, const sc_unsigned& v);
+
+ // Logical GREATER_THAN operators:
+
+ bool operator > (const sc_unsigned& u, const sc_signed& v);
+ bool operator > (const sc_signed& u, const sc_unsigned& v);
+
+ bool operator > (const sc_unsigned& u, const sc_unsigned& v);
+ bool operator > (const sc_unsigned& u, int64 v);
+ bool operator > (const sc_unsigned& u, uint64 v);
+ bool operator > (const sc_unsigned& u, long v);
+ bool operator > (const sc_unsigned& u, unsigned long v);
+ inline bool operator > (const sc_unsigned& u, int v);
+ inline bool operator > (const sc_unsigned& u, unsigned int v);
+
+ bool operator > (int64 u, const sc_unsigned& v);
+ bool operator > (uint64 u, const sc_unsigned& v);
+ bool operator > (long u, const sc_unsigned& v);
+ bool operator > (unsigned long u, const sc_unsigned& v);
+ inline bool operator > (int u, const sc_unsigned& v);
+ inline bool operator > (unsigned int u, const sc_unsigned& v);
+
+ bool operator > (const sc_unsigned& u, const sc_uint_base& v);
+ bool operator > (const sc_unsigned& u, const sc_int_base& v);
+ bool operator > (const sc_uint_base& u, const sc_unsigned& v);
+ bool operator > (const sc_int_base& u, const sc_unsigned& v);
+
+ // Logical GREATER_THAN_AND_EQUAL operators:
+
+ bool operator >= (const sc_unsigned& u, const sc_signed& v);
+ bool operator >= (const sc_signed& u, const sc_unsigned& v);
+
+ bool operator >= (const sc_unsigned& u, const sc_unsigned& v);
+ bool operator >= (const sc_unsigned& u, int64 v);
+ bool operator >= (const sc_unsigned& u, uint64 v);
+ bool operator >= (const sc_unsigned& u, long v);
+ bool operator >= (const sc_unsigned& u, unsigned long v);
+ inline bool operator >= (const sc_unsigned& u, int v);
+ inline bool operator >= (const sc_unsigned& u, unsigned int v);
+
+ bool operator >= (int64 u, const sc_unsigned& v);
+ bool operator >= (uint64 u, const sc_unsigned& v);
+ bool operator >= (long u, const sc_unsigned& v);
+ bool operator >= (unsigned long u, const sc_unsigned& v);
+ inline bool operator >= (int u, const sc_unsigned& v);
+ inline bool operator >= (unsigned int u, const sc_unsigned& v);
+
+ bool operator >= (const sc_unsigned& u, const sc_uint_base& v);
+ bool operator >= (const sc_unsigned& u, const sc_int_base& v);
+ bool operator >= (const sc_uint_base& u, const sc_unsigned& v);
+ bool operator >= (const sc_int_base& u, const sc_unsigned& v);
+
+ // Bitwise NOT operator (unary).
+ sc_unsigned operator ~ (const sc_unsigned& u);
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_unsigned_bitref_r
+//
+// Proxy class for sc_unsigned bit selection (r-value only).
+// ----------------------------------------------------------------------------
+
+class sc_unsigned_bitref_r : public sc_value_base
+{
+ friend class sc_unsigned;
+
+protected:
+
+ // construction and initialization:
+
+ sc_unsigned_bitref_r() : sc_value_base(), m_index(0), m_obj_p(0)
+ {}
+
+ void initialize( const sc_unsigned* obj_p, int index_ )
+ {
+ m_obj_p = CCAST<sc_unsigned*>( obj_p );
+ m_index = index_;
+ }
+
+public:
+
+ // destructor
+
+ virtual ~sc_unsigned_bitref_r()
+ {}
+
+ // copy constructor
+
+ sc_unsigned_bitref_r( const sc_unsigned_bitref_r& a )
+ : sc_value_base(a), m_index( a.m_index ), m_obj_p( a.m_obj_p )
+ {}
+
+ // capacity
+
+ int length() const
+ { return 1; }
+
+
+ // implicit conversion to bool
+
+ operator uint64 () const;
+ bool operator ! () const;
+ bool operator ~ () const;
+
+
+ // explicit conversions
+
+ uint64 value() const
+ { return operator uint64(); }
+
+ bool to_bool() const
+ { return operator uint64(); }
+
+
+ // concatenation support
+
+ virtual int concat_length(bool* xz_present_p) const
+ { if ( xz_present_p ) *xz_present_p = false; return 1; }
+ virtual uint64 concat_get_uint64() const
+ { return (uint64)operator uint64(); }
+ virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const
+ {
+ int bit_mask = 1 << (low_i % BITS_PER_DIGIT);
+ int word_i = low_i / BITS_PER_DIGIT;
+ dst_p[word_i] &= ~bit_mask;
+ return false;
+ }
+ virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const
+ {
+ int bit_mask = 1 << (low_i % BITS_PER_DIGIT);
+ bool result; // True if non-zero.
+ int word_i = low_i / BITS_PER_DIGIT;
+ if ( operator uint64() )
+ {
+ dst_p[word_i] |= bit_mask;
+ result = true;
+ }
+ else
+ {
+ dst_p[word_i] &= ~bit_mask;
+ result = false;
+ }
+ return result;
+ }
+
+ // other methods
+
+ void print( ::std::ostream& os = ::std::cout ) const
+ { os << to_bool(); }
+
+protected:
+
+ int m_index;
+ sc_unsigned* m_obj_p;
+
+private:
+
+ // disabled
+ const sc_unsigned_bitref_r& operator = ( const sc_unsigned_bitref_r& );
+};
+
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream&, const sc_unsigned_bitref_r& );
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_unsigned_bitref
+//
+// Proxy class for sc_unsigned bit selection (r-value and l-value).
+// ----------------------------------------------------------------------------
+
+class sc_unsigned_bitref
+ : public sc_unsigned_bitref_r
+{
+ friend class sc_unsigned;
+ friend class sc_core::sc_vpool<sc_unsigned_bitref>;
+
+
+protected: // construction
+
+ sc_unsigned_bitref() : sc_unsigned_bitref_r()
+ {}
+
+public:
+
+ // copy constructor
+
+ sc_unsigned_bitref( const sc_unsigned_bitref& a )
+ : sc_unsigned_bitref_r( a )
+ {}
+
+
+ // assignment operators
+
+ const sc_unsigned_bitref& operator = ( const sc_unsigned_bitref_r& );
+ const sc_unsigned_bitref& operator = ( const sc_unsigned_bitref& );
+ const sc_unsigned_bitref& operator = ( bool );
+
+ const sc_unsigned_bitref& operator &= ( bool );
+ const sc_unsigned_bitref& operator |= ( bool );
+ const sc_unsigned_bitref& operator ^= ( bool );
+
+ // concatenation methods
+
+ virtual void concat_set(int64 src, int low_i);
+ virtual void concat_set(const sc_signed& src, int low_i);
+ virtual void concat_set(const sc_unsigned& src, int low_i);
+ virtual void concat_set(uint64 src, int low_i);
+
+
+ // other methods
+
+ void scan( ::std::istream& is = ::std::cin );
+
+protected:
+ static sc_core::sc_vpool<sc_unsigned_bitref> m_pool;
+};
+
+
+
+inline
+::std::istream&
+operator >> ( ::std::istream&, sc_unsigned_bitref& );
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_unsigned_subref_r
+//
+// Proxy class for sc_unsigned part selection (r-value only).
+// ----------------------------------------------------------------------------
+
+class sc_unsigned_subref_r : public sc_value_base
+{
+ friend class sc_signed;
+ friend class sc_unsigned;
+ friend class sc_unsigned_signal;
+
+protected:
+
+ // constructor
+
+ sc_unsigned_subref_r() : sc_value_base(), m_left(0), m_obj_p(0), m_right(0)
+ {}
+
+ void initialize( const sc_unsigned* obj_p, int left_, int right_ )
+ {
+ m_obj_p = CCAST<sc_unsigned*>( obj_p );
+ m_left = left_;
+ m_right = right_;
+ }
+
+public:
+
+ // destructor
+
+ virtual ~sc_unsigned_subref_r()
+ {}
+
+
+ // copy constructor
+
+ sc_unsigned_subref_r( const sc_unsigned_subref_r& a )
+ : sc_value_base(a), m_left( a.m_left ), m_obj_p( a.m_obj_p ),
+ m_right( a.m_right )
+ {}
+
+
+ // capacity
+
+ int length() const
+ { return m_left >= m_right ? (m_left-m_right+1) : (m_right-m_left+1 ); }
+
+
+ // implicit conversion to sc_unsigned
+
+ operator sc_unsigned () const;
+
+
+ // explicit conversions
+
+ int to_int() const;
+ unsigned int to_uint() const;
+ long to_long() const;
+ unsigned long to_ulong() const;
+ int64 to_int64() const;
+ uint64 to_uint64() const;
+ double to_double() const;
+
+
+ // explicit conversion to character string
+
+ const std::string to_string( sc_numrep numrep = SC_DEC ) const;
+ const std::string to_string( sc_numrep numrep, bool w_prefix ) const;
+
+
+ // concatenation support
+
+ virtual int concat_length(bool* xz_present_p) const
+ {
+ if ( xz_present_p ) *xz_present_p = false;
+ return m_left - m_right + 1;
+ }
+ virtual uint64 concat_get_uint64() const;
+ virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const;
+ virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const;
+
+ // reduce methods
+
+ bool and_reduce() const;
+ bool nand_reduce() const;
+ bool or_reduce() const;
+ bool nor_reduce() const;
+ bool xor_reduce() const ;
+ bool xnor_reduce() const;
+
+ // other methods
+
+ void print( ::std::ostream& os = ::std::cout ) const
+ { os << to_string(sc_io_base(os,SC_DEC),sc_io_show_base(os)); }
+
+protected:
+
+ int m_left; // Left-most bit in this part selection.
+ sc_unsigned* m_obj_p; // Target of this part selection.
+ int m_right; // Right-most bit in this part selection.
+
+private:
+
+ // disabled
+ const sc_unsigned_subref_r& operator = ( const sc_unsigned_subref_r& );
+};
+
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream&, const sc_unsigned_subref_r& );
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_unsigned_subref
+//
+// Proxy class for sc_unsigned part selection (r-value and l-value).
+// ----------------------------------------------------------------------------
+
+class sc_unsigned_subref
+ : public sc_unsigned_subref_r
+{
+ friend class sc_unsigned;
+ friend class sc_core::sc_vpool<sc_unsigned_subref>;
+
+
+ // constructor
+
+protected:
+ sc_unsigned_subref() : sc_unsigned_subref_r()
+ {}
+
+public:
+
+ // copy constructor
+
+ sc_unsigned_subref( const sc_unsigned_subref& a )
+ : sc_unsigned_subref_r( a )
+ {}
+
+ // assignment operators
+
+ const sc_unsigned_subref& operator = ( const sc_unsigned_subref_r& a );
+ const sc_unsigned_subref& operator = ( const sc_unsigned_subref& a );
+ const sc_unsigned_subref& operator = ( const sc_unsigned& a );
+
+ template<class T>
+ const sc_unsigned_subref& operator = ( const sc_generic_base<T>& a );
+ const sc_unsigned_subref& operator = ( const sc_signed_subref_r& a );
+ const sc_unsigned_subref& operator = ( const sc_signed& a );
+
+ const sc_unsigned_subref& operator = ( const char* a );
+ const sc_unsigned_subref& operator = ( unsigned long a );
+ const sc_unsigned_subref& operator = ( long a );
+
+ const sc_unsigned_subref& operator = ( unsigned int a )
+ { return operator = ( (unsigned long) a ); }
+
+ const sc_unsigned_subref& operator = ( int a )
+ { return operator = ( (long) a ); }
+
+ const sc_unsigned_subref& operator = ( uint64 a );
+ const sc_unsigned_subref& operator = ( int64 a );
+ const sc_unsigned_subref& operator = ( double a );
+ const sc_unsigned_subref& operator = ( const sc_int_base& a );
+ const sc_unsigned_subref& operator = ( const sc_uint_base& a );
+
+ // concatenation methods
+
+ virtual void concat_set(int64 src, int low_i);
+ virtual void concat_set(const sc_signed& src, int low_i);
+ virtual void concat_set(const sc_unsigned& src, int low_i);
+ virtual void concat_set(uint64 src, int low_i);
+
+ // other methods
+
+ void scan( ::std::istream& is = ::std::cin );
+
+protected:
+ static sc_core::sc_vpool<sc_unsigned_subref> m_pool;
+};
+
+
+
+inline
+::std::istream&
+operator >> ( ::std::istream&, sc_unsigned_subref& );
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_unsigned
+//
+// Arbitrary precision unsigned number.
+// ----------------------------------------------------------------------------
+
+class sc_unsigned : public sc_value_base
+{
+ friend class sc_concatref;
+ friend class sc_unsigned_bitref_r;
+ friend class sc_unsigned_bitref;
+ friend class sc_unsigned_subref_r;
+ friend class sc_unsigned_subref;
+ friend class sc_signed;
+ friend class sc_signed_subref;
+ friend class sc_signed_subref_r;
+
+ // Needed for types using sc_unsigned.
+ typedef bool elemtype;
+
+public:
+
+ // constructors
+
+ explicit sc_unsigned( int nb = sc_length_param().len() );
+ sc_unsigned( const sc_unsigned& v );
+ sc_unsigned( const sc_signed& v );
+ template<class T>
+ explicit sc_unsigned( const sc_generic_base<T>& v );
+ explicit sc_unsigned( const sc_bv_base& v );
+ explicit sc_unsigned( const sc_lv_base& v );
+ explicit sc_unsigned( const sc_int_subref_r& v );
+ explicit sc_unsigned( const sc_uint_subref_r& v );
+ explicit sc_unsigned( const sc_signed_subref_r& v );
+ explicit sc_unsigned( const sc_unsigned_subref_r& v );
+
+
+
+ // assignment operators
+
+ const sc_unsigned& operator = (const sc_unsigned& v);
+ const sc_unsigned& operator = (const sc_unsigned_subref_r& a );
+
+ template<class T>
+ const sc_unsigned& operator = ( const sc_generic_base<T>& a )
+ { a->to_sc_unsigned(*this); return *this; }
+
+ const sc_unsigned& operator = (const sc_signed& v);
+ const sc_unsigned& operator = (const sc_signed_subref_r& a );
+
+ const sc_unsigned& operator = ( const char* v);
+ const sc_unsigned& operator = ( int64 v);
+ const sc_unsigned& operator = ( uint64 v);
+ const sc_unsigned& operator = ( long v);
+ const sc_unsigned& operator = ( unsigned long v);
+
+ const sc_unsigned& operator = ( int v)
+ { return operator=((long) v); }
+
+ const sc_unsigned& operator = ( unsigned int v)
+ { return operator=((unsigned long) v); }
+
+ const sc_unsigned& operator = ( double v);
+ const sc_unsigned& operator = ( const sc_int_base& v);
+ const sc_unsigned& operator = ( const sc_uint_base& v);
+
+ const sc_unsigned& operator = ( const sc_bv_base& );
+ const sc_unsigned& operator = ( const sc_lv_base& );
+
+#ifdef SC_INCLUDE_FX
+ const sc_unsigned& operator = ( const sc_fxval& );
+ const sc_unsigned& operator = ( const sc_fxval_fast& );
+ const sc_unsigned& operator = ( const sc_fxnum& );
+ const sc_unsigned& operator = ( const sc_fxnum_fast& );
+#endif
+
+
+ // destructor
+
+ virtual ~sc_unsigned()
+ {
+# ifndef SC_MAX_NBITS
+ delete [] digit;
+# endif
+ }
+
+ // Concatenation support:
+
+ sc_digit* get_raw() const { return digit; }
+ virtual int concat_length(bool* xz_present_p) const
+ { if ( xz_present_p ) *xz_present_p = false; return nbits-1; }
+ virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const;
+ virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const;
+ virtual uint64 concat_get_uint64() const;
+ virtual void concat_set(int64 src, int low_i);
+ virtual void concat_set(const sc_signed& src, int low_i);
+ virtual void concat_set(const sc_unsigned& src, int low_i);
+ virtual void concat_set(uint64 src, int low_i);
+
+ // Increment operators.
+
+ sc_unsigned& operator ++ ();
+ const sc_unsigned operator ++ (int);
+
+ // Decrement operators.
+
+ sc_unsigned& operator -- ();
+ const sc_unsigned operator -- (int);
+
+
+ // bit selection
+
+ inline void check_index( int i ) const
+ { if ( (i < 0) || (i >= nbits-1) ) invalid_index(i); }
+
+ void invalid_index( int i ) const;
+
+ sc_unsigned_bitref& operator [] ( int i )
+ {
+ check_index(i);
+ sc_unsigned_bitref* result_p =
+ sc_unsigned_bitref::m_pool.allocate();
+ result_p->initialize( this, i );
+ return *result_p;
+ }
+
+ const sc_unsigned_bitref_r& operator [] ( int i ) const
+ {
+ check_index(i);
+ sc_unsigned_bitref* result_p =
+ sc_unsigned_bitref::m_pool.allocate();
+ result_p->initialize( this, i );
+ return *result_p;
+ }
+
+ sc_unsigned_bitref& bit( int i )
+ {
+ check_index(i);
+ sc_unsigned_bitref* result_p =
+ sc_unsigned_bitref::m_pool.allocate();
+ result_p->initialize( this, i );
+ return *result_p;
+ }
+
+ const sc_unsigned_bitref_r& bit( int i ) const
+ {
+ check_index(i);
+ sc_unsigned_bitref* result_p =
+ sc_unsigned_bitref::m_pool.allocate();
+ result_p->initialize( this, i );
+ return *result_p;
+ }
+
+
+ // part selection
+
+ // Subref operators. Help access the range of bits from the ith to
+ // jth. These indices have arbitrary precedence with respect to each
+ // other, i.e., we can have i <= j or i > j. Note the equivalence
+ // between range(i, j) and operator (i, j). Also note that
+ // operator (i, i) returns an unsigned number that corresponds to the
+ // bit operator [i], so these two forms are not the same.
+
+ inline void check_range( int l, int r ) const
+ {
+ if ( l < r )
+ {
+ if ( (l < 0) || (r >= nbits-1) ) invalid_range(l,r);
+ }
+ else
+ {
+ if ( (r < 0) || (l >= nbits-1) ) invalid_range(l,r);
+ }
+ }
+
+ void invalid_range( int l, int r ) const;
+
+ sc_unsigned_subref& range( int i, int j )
+ {
+ check_range(i,j);
+ sc_unsigned_subref* result_p =
+ sc_unsigned_subref::m_pool.allocate();
+ result_p->initialize( this, i, j );
+ return *result_p;
+ }
+
+ const sc_unsigned_subref_r& range( int i, int j ) const
+ {
+ check_range(i,j);
+ sc_unsigned_subref* result_p =
+ sc_unsigned_subref::m_pool.allocate();
+ result_p->initialize( this, i, j );
+ return *result_p;
+ }
+
+ sc_unsigned_subref& operator () ( int i, int j )
+ {
+ check_range(i,j);
+ sc_unsigned_subref* result_p =
+ sc_unsigned_subref::m_pool.allocate();
+ result_p->initialize( this, i, j );
+ return *result_p;
+ }
+
+ const sc_unsigned_subref_r& operator () ( int i, int j ) const
+ {
+ check_range(i,j);
+ sc_unsigned_subref* result_p =
+ sc_unsigned_subref::m_pool.allocate();
+ result_p->initialize( this, i, j );
+ return *result_p;
+ }
+
+ // explicit conversions
+
+ int to_int() const;
+ unsigned int to_uint() const;
+ long to_long() const;
+ unsigned long to_ulong() const;
+ int64 to_int64() const;
+ uint64 to_uint64() const;
+ double to_double() const;
+
+#ifdef SC_DT_DEPRECATED
+ int to_signed() const
+ { return to_int(); }
+
+ unsigned int to_unsigned() const
+ { return to_uint(); }
+#endif
+
+ // explicit conversion to character string
+
+ const std::string to_string( sc_numrep numrep = SC_DEC ) const;
+ const std::string to_string( sc_numrep numrep, bool w_prefix ) const;
+
+ // Print functions. dump prints the internals of the class.
+
+ void print( ::std::ostream& os = ::std::cout ) const
+ { os << to_string(sc_io_base(os,SC_DEC),sc_io_show_base(os)); }
+
+ void scan( ::std::istream& is = ::std::cin );
+
+ void dump( ::std::ostream& os = ::std::cout ) const;
+
+
+ // Functions to find various properties.
+ int length() const { return nbits - 1; } // Bit width.
+ bool iszero() const; // Is the number zero?
+ bool sign() const { return 0; } // Sign.
+
+ // reduce methods
+
+ bool and_reduce() const;
+
+ bool nand_reduce() const
+ { return ( ! and_reduce() ); }
+
+ bool or_reduce() const;
+
+ bool nor_reduce() const
+ { return ( ! or_reduce() ); }
+
+ bool xor_reduce() const;
+
+ bool xnor_reduce() const
+ { return ( ! xor_reduce() ); }
+
+
+ // Functions to access individual bits.
+ bool test(int i) const; // Is the ith bit 0 or 1?
+ void set(int i); // Set the ith bit to 1.
+ void clear(int i); // Set the ith bit to 0.
+ void set(int i, bool v) // Set the ith bit to v.
+ { if (v) set(i); else clear(i); }
+ void invert(int i) // Negate the ith bit.
+ { if (test(i)) clear(i); else set(i); }
+
+ // Make the number equal to its mirror image.
+ void reverse();
+
+ // Get/set a packed bit representation of the number.
+ void get_packed_rep(sc_digit *buf) const;
+ void set_packed_rep(sc_digit *buf);
+
+ /*
+ The comparison of the old and new semantics are as follows:
+
+ Let s = sc_signed,
+ u = sc_unsigned,
+ un = { uint64, unsigned long, unsigned int },
+ sn = { int64, long, int, char* }, and
+ OP = { +, -, *, /, % }.
+
+ Old semantics: New semantics:
+ u OP u -> u u OP u -> u
+ s OP u -> u s OP u -> s
+ u OP s -> u u OP s -> s
+ s OP s -> s s OP s -> s
+
+ u OP un = un OP u -> u u OP un = un OP u -> u
+ u OP sn = sn OP u -> u u OP sn = sn OP u -> s
+
+ s OP un = un OP s -> s s OP un = un OP s -> s
+ s OP sn = sn OP s -> s s OP sn = sn OP s -> s
+
+ In the new semantics, the result is u if both operands are u; the
+ result is s otherwise. The only exception is subtraction. The result
+ of a subtraction is always s.
+
+ The old semantics is like C/C++ semantics on integer types; the
+ new semantics is due to the VSIA C/C++ data types standard.
+ */
+
+ // ARITHMETIC OPERATORS:
+
+ // ADDition operators:
+
+ friend sc_signed operator + (const sc_unsigned& u, const sc_signed& v);
+ friend sc_signed operator + (const sc_signed& u, const sc_unsigned& v);
+
+ friend sc_unsigned operator + (const sc_unsigned& u, const sc_unsigned& v);
+ friend sc_signed operator + (const sc_unsigned& u, int64 v);
+ friend sc_unsigned operator + (const sc_unsigned& u, uint64 v);
+ friend sc_signed operator + (const sc_unsigned& u, long v);
+ friend sc_unsigned operator + (const sc_unsigned& u, unsigned long v);
+ friend sc_signed operator + (const sc_unsigned& u, int v);
+ friend sc_unsigned operator + (const sc_unsigned& u, unsigned int v)
+ { return operator+(u, (unsigned long) v); }
+
+ friend sc_signed operator + (int64 u, const sc_unsigned& v);
+ friend sc_unsigned operator + (uint64 u, const sc_unsigned& v);
+ friend sc_signed operator + (long u, const sc_unsigned& v);
+ friend sc_unsigned operator + (unsigned long u, const sc_unsigned& v);
+ friend sc_signed operator + (int u, const sc_unsigned& v);
+ friend sc_unsigned operator + (unsigned int u, const sc_unsigned& v)
+ { return operator+((unsigned long) u, v); }
+
+ const sc_unsigned& operator += (const sc_signed& v);
+ const sc_unsigned& operator += (const sc_unsigned& v);
+ const sc_unsigned& operator += (int64 v);
+ const sc_unsigned& operator += (uint64 v);
+ const sc_unsigned& operator += (long v);
+ const sc_unsigned& operator += (unsigned long v);
+ const sc_unsigned& operator += (int v)
+ { return operator+=((long) v); }
+ const sc_unsigned& operator += (unsigned int v)
+ { return operator+=((unsigned long) v); }
+
+ friend sc_unsigned operator + (const sc_unsigned& u, const sc_uint_base& v);
+ friend sc_signed operator + (const sc_unsigned& u, const sc_int_base& v);
+ friend sc_unsigned operator + (const sc_uint_base& u, const sc_unsigned& v);
+ friend sc_signed operator + (const sc_int_base& u, const sc_unsigned& v);
+ const sc_unsigned& operator += (const sc_int_base& v);
+ const sc_unsigned& operator += (const sc_uint_base& v);
+
+ // SUBtraction operators:
+
+ friend sc_signed operator - (const sc_unsigned& u, const sc_signed& v);
+ friend sc_signed operator - (const sc_signed& u, const sc_unsigned& v);
+
+ friend sc_signed operator - (const sc_unsigned& u, const sc_unsigned& v);
+ friend sc_signed operator - (const sc_unsigned& u, int64 v);
+ friend sc_signed operator - (const sc_unsigned& u, uint64 v);
+ friend sc_signed operator - (const sc_unsigned& u, long v);
+ friend sc_signed operator - (const sc_unsigned& u, unsigned long v);
+ friend sc_signed operator - (const sc_unsigned& u, int v);
+ friend sc_signed operator - (const sc_unsigned& u, unsigned int v);
+
+ friend sc_signed operator - (int64 u, const sc_unsigned& v);
+ friend sc_signed operator - (uint64 u, const sc_unsigned& v);
+ friend sc_signed operator - (long u, const sc_unsigned& v);
+ friend sc_signed operator - (unsigned long u, const sc_unsigned& v);
+ friend sc_signed operator - (int u, const sc_unsigned& v);
+ friend sc_signed operator - (unsigned int u, const sc_unsigned& v);
+
+ const sc_unsigned& operator -= (const sc_signed& v);
+ const sc_unsigned& operator -= (const sc_unsigned& v);
+ const sc_unsigned& operator -= (int64 v);
+ const sc_unsigned& operator -= (uint64 v);
+ const sc_unsigned& operator -= (long v);
+ const sc_unsigned& operator -= (unsigned long v);
+ const sc_unsigned& operator -= (int v)
+ { return operator-=((long) v); }
+ const sc_unsigned& operator -= (unsigned int v)
+ { return operator-=((unsigned long) v); }
+
+ friend sc_signed operator - (const sc_unsigned& u, const sc_uint_base& v);
+ friend sc_signed operator - (const sc_unsigned& u, const sc_int_base& v);
+ friend sc_signed operator - (const sc_uint_base& u, const sc_unsigned& v);
+ friend sc_signed operator - (const sc_int_base& u, const sc_unsigned& v);
+ const sc_unsigned& operator -= (const sc_int_base& v);
+ const sc_unsigned& operator -= (const sc_uint_base& v);
+
+ // MULtiplication operators:
+
+ friend sc_signed operator * (const sc_unsigned& u, const sc_signed& v);
+ friend sc_signed operator * (const sc_signed& u, const sc_unsigned& v);
+
+ friend sc_unsigned operator * (const sc_unsigned& u, const sc_unsigned& v);
+ friend sc_signed operator * (const sc_unsigned& u, int64 v);
+ friend sc_unsigned operator * (const sc_unsigned& u, uint64 v);
+ friend sc_signed operator * (const sc_unsigned& u, long v);
+ friend sc_unsigned operator * (const sc_unsigned& u, unsigned long v);
+ friend sc_signed operator * (const sc_unsigned& u, int v);
+ friend sc_unsigned operator * (const sc_unsigned& u, unsigned int v)
+ { return operator*(u, (unsigned long) v); }
+
+ friend sc_signed operator * (int64 u, const sc_unsigned& v);
+ friend sc_unsigned operator * (uint64 u, const sc_unsigned& v);
+ friend sc_signed operator * (long u, const sc_unsigned& v);
+ friend sc_unsigned operator * (unsigned long u, const sc_unsigned& v);
+ friend sc_signed operator * (int u, const sc_unsigned& v);
+ friend sc_unsigned operator * (unsigned int u, const sc_unsigned& v)
+ { return operator*((unsigned long) u, v); }
+
+ const sc_unsigned& operator *= (const sc_signed& v);
+ const sc_unsigned& operator *= (const sc_unsigned& v);
+ const sc_unsigned& operator *= (int64 v);
+ const sc_unsigned& operator *= (uint64 v);
+ const sc_unsigned& operator *= (long v);
+ const sc_unsigned& operator *= (unsigned long v);
+ const sc_unsigned& operator *= (int v)
+ { return operator*=((long) v); }
+ const sc_unsigned& operator *= (unsigned int v)
+ { return operator*=((unsigned long) v); }
+
+ friend sc_unsigned operator * (const sc_unsigned& u, const sc_uint_base& v);
+ friend sc_signed operator * (const sc_unsigned& u, const sc_int_base& v);
+ friend sc_unsigned operator * (const sc_uint_base& u, const sc_unsigned& v);
+ friend sc_signed operator * (const sc_int_base& u, const sc_unsigned& v);
+ const sc_unsigned& operator *= (const sc_int_base& v);
+ const sc_unsigned& operator *= (const sc_uint_base& v);
+
+ // DIVision operators:
+
+ friend sc_signed operator / (const sc_unsigned& u, const sc_signed& v);
+ friend sc_signed operator / (const sc_signed& u, const sc_unsigned& v);
+
+ friend sc_unsigned operator / (const sc_unsigned& u, const sc_unsigned& v);
+ friend sc_signed operator / (const sc_unsigned& u, int64 v);
+ friend sc_unsigned operator / (const sc_unsigned& u, uint64 v);
+ friend sc_signed operator / (const sc_unsigned& u, long v);
+ friend sc_unsigned operator / (const sc_unsigned& u, unsigned long v);
+ friend sc_signed operator / (const sc_unsigned& u, int v);
+ friend sc_unsigned operator / (const sc_unsigned& u, unsigned int v)
+ { return operator/(u, (unsigned long) v); }
+
+ friend sc_signed operator / (int64 u, const sc_unsigned& v);
+ friend sc_unsigned operator / (uint64 u, const sc_unsigned& v);
+ friend sc_signed operator / (long u, const sc_unsigned& v);
+ friend sc_unsigned operator / (unsigned long u, const sc_unsigned& v);
+ friend sc_signed operator / (int u, const sc_unsigned& v);
+ friend sc_unsigned operator / (unsigned int u, const sc_unsigned& v)
+ { return operator/((unsigned long) u, v); }
+
+ const sc_unsigned& operator /= (const sc_signed& v);
+ const sc_unsigned& operator /= (const sc_unsigned& v);
+ const sc_unsigned& operator /= (int64 v);
+ const sc_unsigned& operator /= (uint64 v);
+ const sc_unsigned& operator /= (long v);
+ const sc_unsigned& operator /= (unsigned long v);
+ const sc_unsigned& operator /= (int v)
+ { return operator/=((long) v); }
+ const sc_unsigned& operator /= (unsigned int v)
+ { return operator/=((unsigned long) v); }
+
+ friend sc_unsigned operator / (const sc_unsigned& u, const sc_uint_base& v);
+ friend sc_signed operator / (const sc_unsigned& u, const sc_int_base& v);
+ friend sc_unsigned operator / (const sc_uint_base& u, const sc_unsigned& v);
+ friend sc_signed operator / (const sc_int_base& u, const sc_unsigned& v);
+ const sc_unsigned& operator /= (const sc_int_base& v);
+ const sc_unsigned& operator /= (const sc_uint_base& v);
+
+ // MODulo operators:
+
+ friend sc_signed operator % (const sc_unsigned& u, const sc_signed& v);
+ friend sc_signed operator % (const sc_signed& u, const sc_unsigned& v);
+
+ friend sc_unsigned operator % (const sc_unsigned& u, const sc_unsigned& v);
+ friend sc_signed operator % (const sc_unsigned& u, int64 v);
+ friend sc_unsigned operator % (const sc_unsigned& u, uint64 v);
+ friend sc_signed operator % (const sc_unsigned& u, long v);
+ friend sc_unsigned operator % (const sc_unsigned& u, unsigned long v);
+ friend sc_signed operator % (const sc_unsigned& u, int v);
+ friend sc_unsigned operator % (const sc_unsigned& u, unsigned int v)
+ { return operator%(u, (unsigned long) v); }
+
+ friend sc_signed operator % (int64 u, const sc_unsigned& v);
+ friend sc_unsigned operator % (uint64 u, const sc_unsigned& v);
+ friend sc_signed operator % (long u, const sc_unsigned& v);
+ friend sc_unsigned operator % (unsigned long u, const sc_unsigned& v);
+ friend sc_signed operator % (int u, const sc_unsigned& v);
+ friend sc_unsigned operator % (unsigned int u, const sc_unsigned& v)
+ { return operator%((unsigned long) u, v); }
+
+ const sc_unsigned& operator %= (const sc_signed& v);
+ const sc_unsigned& operator %= (const sc_unsigned& v);
+ const sc_unsigned& operator %= (int64 v);
+ const sc_unsigned& operator %= (uint64 v);
+ const sc_unsigned& operator %= (long v);
+ const sc_unsigned& operator %= (unsigned long v);
+ const sc_unsigned& operator %= (int v)
+ { return operator%=((long) v); }
+ const sc_unsigned& operator %= (unsigned int v)
+ { return operator%=((unsigned long) v); }
+
+ friend sc_unsigned operator % (const sc_unsigned& u, const sc_uint_base& v);
+ friend sc_signed operator % (const sc_unsigned& u, const sc_int_base& v);
+ friend sc_unsigned operator % (const sc_uint_base& u, const sc_unsigned& v);
+ friend sc_signed operator % (const sc_int_base& u, const sc_unsigned& v);
+ const sc_unsigned& operator %= (const sc_int_base& v);
+ const sc_unsigned& operator %= (const sc_uint_base& v);
+
+ // BITWISE OPERATORS:
+
+ // Bitwise AND operators:
+
+ friend sc_signed operator & (const sc_unsigned& u, const sc_signed& v);
+ friend sc_signed operator & (const sc_signed& u, const sc_unsigned& v);
+
+ friend sc_unsigned operator & (const sc_unsigned& u, const sc_unsigned& v);
+ friend sc_signed operator & (const sc_unsigned& u, int64 v);
+ friend sc_unsigned operator & (const sc_unsigned& u, uint64 v);
+ friend sc_signed operator & (const sc_unsigned& u, long v);
+ friend sc_unsigned operator & (const sc_unsigned& u, unsigned long v);
+ friend sc_signed operator & (const sc_unsigned& u, int v);
+ friend sc_unsigned operator & (const sc_unsigned& u, unsigned int v)
+ { return operator&(u, (unsigned long) v); }
+
+ friend sc_signed operator & (int64 u, const sc_unsigned& v);
+ friend sc_unsigned operator & (uint64 u, const sc_unsigned& v);
+ friend sc_signed operator & (long u, const sc_unsigned& v);
+ friend sc_unsigned operator & (unsigned long u, const sc_unsigned& v);
+ friend sc_signed operator & (int u, const sc_unsigned& v);
+ friend sc_unsigned operator & (unsigned int u, const sc_unsigned& v)
+ { return operator&((unsigned long) u, v); }
+
+ const sc_unsigned& operator &= (const sc_signed& v);
+ const sc_unsigned& operator &= (const sc_unsigned& v);
+ const sc_unsigned& operator &= (int64 v);
+ const sc_unsigned& operator &= (uint64 v);
+ const sc_unsigned& operator &= (long v);
+ const sc_unsigned& operator &= (unsigned long v);
+ const sc_unsigned& operator &= (int v)
+ { return operator&=((long) v); }
+ const sc_unsigned& operator &= (unsigned int v)
+ { return operator&=((unsigned long) v); }
+
+ friend sc_unsigned operator & (const sc_unsigned& u, const sc_uint_base& v);
+ friend sc_signed operator & (const sc_unsigned& u, const sc_int_base& v);
+ friend sc_unsigned operator & (const sc_uint_base& u, const sc_unsigned& v);
+ friend sc_signed operator & (const sc_int_base& u, const sc_unsigned& v);
+ const sc_unsigned& operator &= (const sc_int_base& v);
+ const sc_unsigned& operator &= (const sc_uint_base& v);
+
+ // Bitwise OR operators:
+
+ friend sc_signed operator | (const sc_unsigned& u, const sc_signed& v);
+ friend sc_signed operator | (const sc_signed& u, const sc_unsigned& v);
+
+ friend sc_unsigned operator | (const sc_unsigned& u, const sc_unsigned& v);
+ friend sc_signed operator | (const sc_unsigned& u, int64 v);
+ friend sc_unsigned operator | (const sc_unsigned& u, uint64 v);
+ friend sc_signed operator | (const sc_unsigned& u, long v);
+ friend sc_unsigned operator | (const sc_unsigned& u, unsigned long v);
+ friend sc_signed operator | (const sc_unsigned& u, int v);
+ friend sc_unsigned operator | (const sc_unsigned& u, unsigned int v)
+ { return operator|(u, (unsigned long) v); }
+
+ friend sc_signed operator | (int64 u, const sc_unsigned& v);
+ friend sc_unsigned operator | (uint64 u, const sc_unsigned& v);
+ friend sc_signed operator | (long u, const sc_unsigned& v);
+ friend sc_unsigned operator | (unsigned long u, const sc_unsigned& v);
+ friend sc_signed operator | (int u, const sc_unsigned& v);
+ friend sc_unsigned operator | (unsigned int u, const sc_unsigned& v)
+ { return operator|((unsigned long) u, v); }
+
+ const sc_unsigned& operator |= (const sc_signed& v);
+ const sc_unsigned& operator |= (const sc_unsigned& v);
+ const sc_unsigned& operator |= (int64 v);
+ const sc_unsigned& operator |= (uint64 v);
+ const sc_unsigned& operator |= (long v);
+ const sc_unsigned& operator |= (unsigned long v);
+ const sc_unsigned& operator |= (int v)
+ { return operator|=((long) v); }
+ const sc_unsigned& operator |= (unsigned int v)
+ { return operator|=((unsigned long) v); }
+
+ friend sc_unsigned operator | (const sc_unsigned& u, const sc_uint_base& v);
+ friend sc_signed operator | (const sc_unsigned& u, const sc_int_base& v);
+ friend sc_unsigned operator | (const sc_uint_base& u, const sc_unsigned& v);
+ friend sc_signed operator | (const sc_int_base& u, const sc_unsigned& v);
+ const sc_unsigned& operator |= (const sc_int_base& v);
+ const sc_unsigned& operator |= (const sc_uint_base& v);
+
+ // Bitwise XOR operators:
+
+ friend sc_signed operator ^ (const sc_unsigned& u, const sc_signed& v);
+ friend sc_signed operator ^ (const sc_signed& u, const sc_unsigned& v);
+
+ friend sc_unsigned operator ^ (const sc_unsigned& u, const sc_unsigned& v);
+ friend sc_signed operator ^ (const sc_unsigned& u, int64 v);
+ friend sc_unsigned operator ^ (const sc_unsigned& u, uint64 v);
+ friend sc_signed operator ^ (const sc_unsigned& u, long v);
+ friend sc_unsigned operator ^ (const sc_unsigned& u, unsigned long v);
+ friend sc_signed operator ^ (const sc_unsigned& u, int v);
+ friend sc_unsigned operator ^ (const sc_unsigned& u, unsigned int v)
+ { return operator^(u, (unsigned long) v); }
+
+ friend sc_signed operator ^ (int64 u, const sc_unsigned& v);
+ friend sc_unsigned operator ^ (uint64 u, const sc_unsigned& v);
+ friend sc_signed operator ^ (long u, const sc_unsigned& v);
+ friend sc_unsigned operator ^ (unsigned long u, const sc_unsigned& v);
+ friend sc_signed operator ^ (int u, const sc_unsigned& v);
+ friend sc_unsigned operator ^ (unsigned int u, const sc_unsigned& v)
+ { return operator^((unsigned long) u, v); }
+
+ const sc_unsigned& operator ^= (const sc_signed& v);
+ const sc_unsigned& operator ^= (const sc_unsigned& v);
+ const sc_unsigned& operator ^= (int64 v);
+ const sc_unsigned& operator ^= (uint64 v);
+ const sc_unsigned& operator ^= (long v);
+ const sc_unsigned& operator ^= (unsigned long v);
+ const sc_unsigned& operator ^= (int v)
+ { return operator^=((long) v); }
+ const sc_unsigned& operator ^= (unsigned int v)
+ { return operator^=((unsigned long) v); }
+
+ friend sc_unsigned operator ^ (const sc_unsigned& u, const sc_uint_base& v);
+ friend sc_signed operator ^ (const sc_unsigned& u, const sc_int_base& v);
+ friend sc_unsigned operator ^ (const sc_uint_base& u, const sc_unsigned& v);
+ friend sc_signed operator ^ (const sc_int_base& u, const sc_unsigned& v);
+ const sc_unsigned& operator ^= (const sc_int_base& v);
+ const sc_unsigned& operator ^= (const sc_uint_base& v);
+
+ // SHIFT OPERATORS:
+
+ // LEFT SHIFT operators:
+
+ friend sc_unsigned operator << (const sc_unsigned& u, const sc_signed& v);
+ friend sc_signed operator << (const sc_signed& u, const sc_unsigned& v);
+
+ friend sc_unsigned operator << (const sc_unsigned& u, const sc_unsigned& v);
+ friend sc_unsigned operator << (const sc_unsigned& u, int64 v);
+ friend sc_unsigned operator << (const sc_unsigned& u, uint64 v);
+ friend sc_unsigned operator << (const sc_unsigned& u, long v);
+ friend sc_unsigned operator << (const sc_unsigned& u, unsigned long v);
+ friend sc_unsigned operator << (const sc_unsigned& u, int v)
+ { return operator<<(u, (long) v); }
+ friend sc_unsigned operator << (const sc_unsigned& u, unsigned int v)
+ { return operator<<(u, (unsigned long) v); }
+
+ const sc_unsigned& operator <<= (const sc_signed& v);
+ const sc_unsigned& operator <<= (const sc_unsigned& v);
+ const sc_unsigned& operator <<= (int64 v);
+ const sc_unsigned& operator <<= (uint64 v);
+ const sc_unsigned& operator <<= (long v);
+ const sc_unsigned& operator <<= (unsigned long v);
+ const sc_unsigned& operator <<= (int v)
+ { return operator<<=((long) v); }
+ const sc_unsigned& operator <<= (unsigned int v)
+ { return operator<<=((unsigned long) v); }
+
+ friend sc_unsigned operator << (const sc_unsigned& u, const sc_uint_base& v);
+ friend sc_unsigned operator << (const sc_unsigned& u, const sc_int_base& v);
+ const sc_unsigned& operator <<= (const sc_int_base& v);
+ const sc_unsigned& operator <<= (const sc_uint_base& v);
+
+ // RIGHT SHIFT operators:
+
+ friend sc_unsigned operator >> (const sc_unsigned& u, const sc_signed& v);
+ friend sc_signed operator >> (const sc_signed& u, const sc_unsigned& v);
+
+ friend sc_unsigned operator >> (const sc_unsigned& u, const sc_unsigned& v);
+ friend sc_unsigned operator >> (const sc_unsigned& u, int64 v);
+ friend sc_unsigned operator >> (const sc_unsigned& u, uint64 v);
+ friend sc_unsigned operator >> (const sc_unsigned& u, long v);
+ friend sc_unsigned operator >> (const sc_unsigned& u, unsigned long v);
+ friend sc_unsigned operator >> (const sc_unsigned& u, int v)
+ { return operator>>(u, (long) v); }
+ friend sc_unsigned operator >> (const sc_unsigned& u, unsigned int v)
+ { return operator>>(u, (unsigned long) v); }
+
+ const sc_unsigned& operator >>= (const sc_signed& v);
+ const sc_unsigned& operator >>= (const sc_unsigned& v);
+ const sc_unsigned& operator >>= (int64 v);
+ const sc_unsigned& operator >>= (uint64 v);
+ const sc_unsigned& operator >>= (long v);
+ const sc_unsigned& operator >>= (unsigned long v);
+ const sc_unsigned& operator >>= (int v)
+ { return operator>>=((long) v); }
+ const sc_unsigned& operator >>= (unsigned int v)
+ { return operator>>=((unsigned long) v); }
+
+ friend sc_unsigned operator >> ( const sc_unsigned& , const sc_uint_base& );
+ friend sc_unsigned operator >> ( const sc_unsigned&, const sc_int_base& );
+ const sc_unsigned& operator >>= (const sc_int_base& v);
+ const sc_unsigned& operator >>= (const sc_uint_base& v);
+
+ // Unary arithmetic operators
+ friend sc_unsigned operator + (const sc_unsigned& u);
+ friend sc_signed operator - (const sc_unsigned& u);
+
+ // LOGICAL OPERATORS:
+
+ // Logical EQUAL operators:
+
+ friend bool operator == (const sc_unsigned& u, const sc_signed& v);
+ friend bool operator == (const sc_signed& u, const sc_unsigned& v);
+
+ friend bool operator == (const sc_unsigned& u, const sc_unsigned& v);
+ friend bool operator == (const sc_unsigned& u, int64 v);
+ friend bool operator == (const sc_unsigned& u, uint64 v);
+ friend bool operator == (const sc_unsigned& u, long v);
+ friend bool operator == (const sc_unsigned& u, unsigned long v);
+ friend bool operator == (const sc_unsigned& u, int v)
+ { return operator==(u, (long) v); }
+ friend bool operator == (const sc_unsigned& u, unsigned int v)
+ { return operator==(u, (unsigned long) v); }
+
+ friend bool operator == (int64 u, const sc_unsigned& v);
+ friend bool operator == (uint64 u, const sc_unsigned& v);
+ friend bool operator == (long u, const sc_unsigned& v);
+ friend bool operator == (unsigned long u, const sc_unsigned& v);
+ friend bool operator == (int u, const sc_unsigned& v)
+ { return operator==((long) u, v); }
+ friend bool operator == (unsigned int u, const sc_unsigned& v)
+ { return operator==((unsigned long) u, v); }
+
+ friend bool operator == (const sc_unsigned& u, const sc_uint_base& v);
+ friend bool operator == (const sc_unsigned& u, const sc_int_base& v);
+ friend bool operator == (const sc_uint_base& u, const sc_unsigned& v);
+ friend bool operator == (const sc_int_base& u, const sc_unsigned& v);
+
+ // Logical NOT_EQUAL operators:
+
+ friend bool operator != (const sc_unsigned& u, const sc_signed& v);
+ friend bool operator != (const sc_signed& u, const sc_unsigned& v);
+
+ friend bool operator != (const sc_unsigned& u, const sc_unsigned& v);
+ friend bool operator != (const sc_unsigned& u, int64 v);
+ friend bool operator != (const sc_unsigned& u, uint64 v);
+ friend bool operator != (const sc_unsigned& u, long v);
+ friend bool operator != (const sc_unsigned& u, unsigned long v);
+ friend bool operator != (const sc_unsigned& u, int v)
+ { return operator!=(u, (long) v); }
+ friend bool operator != (const sc_unsigned& u, unsigned int v)
+ { return operator!=(u, (unsigned long) v); }
+
+ friend bool operator != (int64 u, const sc_unsigned& v);
+ friend bool operator != (uint64 u, const sc_unsigned& v);
+ friend bool operator != (long u, const sc_unsigned& v);
+ friend bool operator != (unsigned long u, const sc_unsigned& v);
+ friend bool operator != (int u, const sc_unsigned& v)
+ { return operator!=((long) u, v); }
+ friend bool operator != (unsigned int u, const sc_unsigned& v)
+ { return operator!=((unsigned long) u, v); }
+
+ friend bool operator != (const sc_unsigned& u, const sc_uint_base& v);
+ friend bool operator != (const sc_unsigned& u, const sc_int_base& v);
+ friend bool operator != (const sc_uint_base& u, const sc_unsigned& v);
+ friend bool operator != (const sc_int_base& u, const sc_unsigned& v);
+
+ // Logical LESS_THAN operators:
+
+ friend bool operator < (const sc_unsigned& u, const sc_signed& v);
+ friend bool operator < (const sc_signed& u, const sc_unsigned& v);
+
+ friend bool operator < (const sc_unsigned& u, const sc_unsigned& v);
+ friend bool operator < (const sc_unsigned& u, int64 v);
+ friend bool operator < (const sc_unsigned& u, uint64 v);
+ friend bool operator < (const sc_unsigned& u, long v);
+ friend bool operator < (const sc_unsigned& u, unsigned long v);
+ friend bool operator < (const sc_unsigned& u, int v)
+ { return operator<(u, (long) v); }
+ friend bool operator < (const sc_unsigned& u, unsigned int v)
+ { return operator<(u, (unsigned long) v); }
+
+ friend bool operator < (int64 u, const sc_unsigned& v);
+ friend bool operator < (uint64 u, const sc_unsigned& v);
+ friend bool operator < (long u, const sc_unsigned& v);
+ friend bool operator < (unsigned long u, const sc_unsigned& v);
+ friend bool operator < (int u, const sc_unsigned& v)
+ { return operator<((long) u, v); }
+ friend bool operator < (unsigned int u, const sc_unsigned& v)
+ { return operator<((unsigned long) u, v); }
+
+ friend bool operator < (const sc_unsigned& u, const sc_uint_base& v);
+ friend bool operator < (const sc_unsigned& u, const sc_int_base& v);
+ friend bool operator < (const sc_uint_base& u, const sc_unsigned& v);
+ friend bool operator < (const sc_int_base& u, const sc_unsigned& v);
+
+ // Logical LESS_THAN_AND_EQUAL operators:
+
+ friend bool operator <= (const sc_unsigned& u, const sc_signed& v);
+ friend bool operator <= (const sc_signed& u, const sc_unsigned& v);
+
+ friend bool operator <= (const sc_unsigned& u, const sc_unsigned& v);
+ friend bool operator <= (const sc_unsigned& u, int64 v);
+ friend bool operator <= (const sc_unsigned& u, uint64 v);
+ friend bool operator <= (const sc_unsigned& u, long v);
+ friend bool operator <= (const sc_unsigned& u, unsigned long v);
+ friend bool operator <= (const sc_unsigned& u, int v)
+ { return operator<=(u, (long) v); }
+ friend bool operator <= (const sc_unsigned& u, unsigned int v)
+ { return operator<=(u, (unsigned long) v); }
+
+ friend bool operator <= (int64 u, const sc_unsigned& v);
+ friend bool operator <= (uint64 u, const sc_unsigned& v);
+ friend bool operator <= (long u, const sc_unsigned& v);
+ friend bool operator <= (unsigned long u, const sc_unsigned& v);
+ friend bool operator <= (int u, const sc_unsigned& v)
+ { return operator<=((long) u, v); }
+ friend bool operator <= (unsigned int u, const sc_unsigned& v)
+ { return operator<=((unsigned long) u, v); }
+
+ friend bool operator <= (const sc_unsigned& u, const sc_uint_base& v);
+ friend bool operator <= (const sc_unsigned& u, const sc_int_base& v);
+ friend bool operator <= (const sc_uint_base& u, const sc_unsigned& v);
+ friend bool operator <= (const sc_int_base& u, const sc_unsigned& v);
+
+ // Logical GREATER_THAN operators:
+
+ friend bool operator > (const sc_unsigned& u, const sc_signed& v);
+ friend bool operator > (const sc_signed& u, const sc_unsigned& v);
+
+ friend bool operator > (const sc_unsigned& u, const sc_unsigned& v);
+ friend bool operator > (const sc_unsigned& u, int64 v);
+ friend bool operator > (const sc_unsigned& u, uint64 v);
+ friend bool operator > (const sc_unsigned& u, long v);
+ friend bool operator > (const sc_unsigned& u, unsigned long v);
+ friend bool operator > (const sc_unsigned& u, int v)
+ { return operator>(u, (long) v); }
+ friend bool operator > (const sc_unsigned& u, unsigned int v)
+ { return operator>(u, (unsigned long) v); }
+
+ friend bool operator > (int64 u, const sc_unsigned& v);
+ friend bool operator > (uint64 u, const sc_unsigned& v);
+ friend bool operator > (long u, const sc_unsigned& v);
+ friend bool operator > (unsigned long u, const sc_unsigned& v);
+ friend bool operator > (int u, const sc_unsigned& v)
+ { return operator>((long) u, v); }
+ friend bool operator > (unsigned int u, const sc_unsigned& v)
+ { return operator>((unsigned long) u, v); }
+
+ friend bool operator > (const sc_unsigned& u, const sc_uint_base& v);
+ friend bool operator > (const sc_unsigned& u, const sc_int_base& v);
+ friend bool operator > (const sc_uint_base& u, const sc_unsigned& v);
+ friend bool operator > (const sc_int_base& u, const sc_unsigned& v);
+
+ // Logical GREATER_THAN_AND_EQUAL operators:
+
+ friend bool operator >= (const sc_unsigned& u, const sc_signed& v);
+ friend bool operator >= (const sc_signed& u, const sc_unsigned& v);
+
+ friend bool operator >= (const sc_unsigned& u, const sc_unsigned& v);
+ friend bool operator >= (const sc_unsigned& u, int64 v);
+ friend bool operator >= (const sc_unsigned& u, uint64 v);
+ friend bool operator >= (const sc_unsigned& u, long v);
+ friend bool operator >= (const sc_unsigned& u, unsigned long v);
+ friend bool operator >= (const sc_unsigned& u, int v)
+ { return operator>=(u, (long) v); }
+ friend bool operator >= (const sc_unsigned& u, unsigned int v)
+ { return operator>=(u, (unsigned long) v); }
+
+ friend bool operator >= (int64 u, const sc_unsigned& v);
+ friend bool operator >= (uint64 u, const sc_unsigned& v);
+ friend bool operator >= (long u, const sc_unsigned& v);
+ friend bool operator >= (unsigned long u, const sc_unsigned& v);
+ friend bool operator >= (int u, const sc_unsigned& v)
+ { return operator>=((long) u, v); }
+ friend bool operator >= (unsigned int u, const sc_unsigned& v)
+ { return operator>=((unsigned long) u, v); }
+
+ friend bool operator >= (const sc_unsigned& u, const sc_uint_base& v);
+ friend bool operator >= (const sc_unsigned& u, const sc_int_base& v);
+ friend bool operator >= (const sc_uint_base& u, const sc_unsigned& v);
+ friend bool operator >= (const sc_int_base& u, const sc_unsigned& v);
+
+ // Bitwise NOT operator (unary).
+ friend sc_unsigned operator ~ (const sc_unsigned& u);
+
+ // Helper functions.
+ friend int compare_unsigned(small_type us,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ small_type vs,
+ int vnb,
+ int vnd,
+ const sc_digit *vd,
+ small_type if_u_signed,
+ small_type if_v_signed);
+
+ friend sc_unsigned add_unsigned_friend(small_type us,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ small_type vs,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+ friend sc_unsigned sub_unsigned_friend(small_type us,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ small_type vs,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+ friend sc_unsigned mul_unsigned_friend(small_type s,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+ friend sc_unsigned div_unsigned_friend(small_type s,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+ friend sc_unsigned mod_unsigned_friend(small_type us,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+ friend sc_unsigned and_unsigned_friend(small_type us,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ small_type vs,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+ friend sc_unsigned or_unsigned_friend(small_type us,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ small_type vs,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+ friend sc_unsigned xor_unsigned_friend(small_type us,
+ int unb,
+ int und,
+ const sc_digit *ud,
+ small_type vs,
+ int vnb,
+ int vnd,
+ const sc_digit *vd);
+
+public:
+ static sc_core::sc_vpool<sc_unsigned> m_pool;
+
+private:
+
+ small_type sgn; // Shortened as s.
+ int nbits; // Shortened as nb.
+ int ndigits; // Shortened as nd.
+
+#ifdef SC_MAX_NBITS
+ sc_digit digit[DIV_CEIL(SC_MAX_NBITS)]; // Shortened as d.
+#else
+ sc_digit *digit; // Shortened as d.
+#endif
+
+ // Private constructors:
+
+ // Create a copy of v with sign s.
+ sc_unsigned(const sc_unsigned& v, small_type s);
+ sc_unsigned(const sc_signed& v, small_type s);
+
+ // Create an unsigned number with the given attributes.
+ sc_unsigned(small_type s, int nb, int nd,
+ sc_digit *d, bool alloc = true);
+
+ // Create an unsigned number using the bits u[l..r].
+ sc_unsigned(const sc_signed* u, int l, int r);
+ sc_unsigned(const sc_unsigned* u, int l, int r);
+
+ // Private member functions. The called functions are inline functions.
+
+ small_type default_sign() const
+ { return SC_POS; }
+
+ int num_bits(int nb) const { return nb + 1; }
+
+ bool check_if_outside(int bit_num) const;
+
+ void copy_digits(int nb, int nd, const sc_digit *d)
+ { copy_digits_unsigned(sgn, nbits, ndigits, digit, nb, nd, d); }
+
+ void makezero()
+ { sgn = make_zero(ndigits, digit); }
+
+ // Conversion functions between 2's complement (2C) and
+ // sign-magnitude (SM):
+ void convert_2C_to_SM()
+ { sgn = convert_unsigned_2C_to_SM(nbits, ndigits, digit); }
+
+ void convert_SM_to_2C_to_SM()
+ { sgn = convert_unsigned_SM_to_2C_to_SM(sgn, nbits, ndigits, digit); }
+
+ void convert_SM_to_2C()
+ { convert_unsigned_SM_to_2C(sgn, ndigits, digit); }
+
+};
+
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream&, const sc_unsigned& );
+
+inline
+::std::istream&
+operator >> ( ::std::istream&, sc_unsigned& );
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_unsigned_bitref_r
+//
+// Proxy class for sc_unsigned bit selection (r-value only).
+// ----------------------------------------------------------------------------
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, const sc_unsigned_bitref_r& a )
+{
+ a.print( os );
+ return os;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_unsigned_bitref
+//
+// Proxy class for sc_unsigned bit selection (r-value and l-value).
+// ----------------------------------------------------------------------------
+
+template<class T>
+inline const sc_unsigned_subref& sc_unsigned_subref::operator = (
+ const sc_generic_base<T>& a )
+{
+ sc_unsigned temp( length() );
+ a->to_sc_unsigned(temp);
+ return *this = temp;
+}
+
+inline
+::std::istream&
+operator >> ( ::std::istream& is, sc_unsigned_bitref& a )
+{
+ a.scan( is );
+ return is;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_unsigned_subref_r
+//
+// Proxy class for sc_unsigned part selection (r-value only).
+// ----------------------------------------------------------------------------
+
+// reduce methods
+
+inline bool sc_unsigned_subref_r::and_reduce() const
+{
+ const sc_unsigned* target_p = m_obj_p;
+ for ( int i = m_right; i <= m_left; i++ )
+ if ( !target_p->test(i) ) return false;
+ return true;
+}
+
+inline bool sc_unsigned_subref_r::nand_reduce() const
+{
+ return !and_reduce();
+}
+
+inline bool sc_unsigned_subref_r::or_reduce() const
+{
+ const sc_unsigned* target_p = m_obj_p;
+ for ( int i = m_right; i <= m_left; i++ )
+ if ( target_p->test(i) ) return true;
+ return false;
+}
+
+inline bool sc_unsigned_subref_r::nor_reduce() const
+{
+ return !or_reduce();
+}
+
+inline bool sc_unsigned_subref_r::xor_reduce() const
+{
+ int odd;
+ const sc_unsigned* target_p = m_obj_p;
+ odd = 0;
+ for ( int i = m_right; i <= m_left; i++ )
+ if ( target_p->test(i) ) odd = ~odd;
+ return odd ? true : false;
+}
+
+inline bool sc_unsigned_subref_r::xnor_reduce() const
+{
+ return !xor_reduce();
+}
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, const sc_unsigned_subref_r& a )
+{
+ a.print( os );
+ return os;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_unsigned_subref
+//
+// Proxy class for sc_unsigned part selection (r-value and l-value).
+// ----------------------------------------------------------------------------
+
+// assignment operators
+
+inline
+const sc_unsigned_subref&
+sc_unsigned_subref::operator = ( const char* a )
+{
+ sc_unsigned aa( length() );
+ return ( *this = aa = a );
+}
+
+
+inline
+::std::istream&
+operator >> ( ::std::istream& is, sc_unsigned_subref& a )
+{
+ a.scan( is );
+ return is;
+}
+
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_unsigned
+//
+// Arbitrary precision signed number.
+// ----------------------------------------------------------------------------
+
+template<class T>
+sc_unsigned::sc_unsigned( const sc_generic_base<T>& v )
+{
+ int nb = v->length();
+ sgn = default_sign();
+ if( nb > 0 ) {
+ nbits = num_bits( nb );
+ } else {
+ char msg[BUFSIZ];
+ std::sprintf( msg,
+ "sc_unsigned( sc_generic_base<T> ) : nb = %d is not valid", nb);
+ SC_REPORT_ERROR( sc_core::SC_ID_INIT_FAILED_, msg );
+ }
+ ndigits = DIV_CEIL(nbits);
+# ifdef SC_MAX_NBITS
+ test_bound(nb);
+# else
+ digit = new sc_digit[ndigits];
+# endif
+ makezero();
+ v->to_sc_unsigned(*this);
+}
+
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, const sc_unsigned& a )
+{
+ a.print( os );
+ return os;
+}
+
+inline
+::std::istream&
+operator >> ( ::std::istream& is, sc_unsigned& a )
+{
+ a.scan( is );
+ return is;
+}
+
+
+} // namespace sc_dt
+
+
+#endif
diff --git a/ext/systemc/src/sysc/datatypes/int/sc_unsigned_bitref.inc b/ext/systemc/src/sysc/datatypes/int/sc_unsigned_bitref.inc
new file mode 100644
index 000000000..c1ad02662
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/int/sc_unsigned_bitref.inc
@@ -0,0 +1,162 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_unsigned_bitref.h -- Proxy class that is declared in sc_unsigned.h.
+
+ Original Author: Ali Dasdan, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_unsigned_bitref_r
+//
+// Proxy class for sc_unsigned bit selection (r-value only).
+// ----------------------------------------------------------------------------
+
+// implicit conversion to uint64
+
+sc_unsigned_bitref_r::operator uint64 () const
+{
+ return m_obj_p->test( m_index );
+}
+
+bool
+sc_unsigned_bitref_r::operator ! () const
+{
+ return ( ! m_obj_p->test( m_index ) );
+}
+
+bool
+sc_unsigned_bitref_r::operator ~ () const
+{
+ return ( ! m_obj_p->test( m_index ) );
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_unsigned_bitref
+//
+// Proxy class for sc_unsigned bit selection (r-value and l-value).
+// ----------------------------------------------------------------------------
+
+// assignment operators
+
+const sc_unsigned_bitref&
+sc_unsigned_bitref::operator = ( const sc_unsigned_bitref_r& b )
+{
+ m_obj_p->set( m_index, (bool) b );
+ return *this;
+}
+
+const sc_unsigned_bitref&
+sc_unsigned_bitref::operator = ( const sc_unsigned_bitref& b )
+{
+ m_obj_p->set( m_index, (bool) b );
+ return *this;
+}
+
+const sc_unsigned_bitref&
+sc_unsigned_bitref::operator = ( bool b )
+{
+ m_obj_p->set( m_index, b );
+ return *this;
+}
+
+
+const sc_unsigned_bitref&
+sc_unsigned_bitref::operator &= ( bool b )
+{
+ if( ! b ) {
+ m_obj_p->clear( m_index );
+ }
+ return *this;
+}
+
+const sc_unsigned_bitref&
+sc_unsigned_bitref::operator |= ( bool b )
+{
+ if( b ) {
+ m_obj_p->set( m_index );
+ }
+ return *this;
+}
+
+const sc_unsigned_bitref&
+sc_unsigned_bitref::operator ^= ( bool b )
+{
+ if( b ) {
+ m_obj_p->invert( m_index );
+ }
+ return *this;
+}
+
+// #### OPTIMIZE
+void sc_unsigned_bitref::concat_set(int64 src, int low_i)
+{
+ bool value = 1 & ((low_i < 64) ? (src >> low_i) : (src >> 63));
+ m_obj_p->set(low_i, value);
+}
+
+void sc_unsigned_bitref::concat_set(const sc_signed& src, int low_i)
+{
+ if ( low_i < src.length() )
+ m_obj_p->set(low_i, src.test(low_i));
+ else
+ m_obj_p->set(low_i, src<0);
+}
+
+void sc_unsigned_bitref::concat_set(const sc_unsigned& src, int low_i)
+{
+ if ( low_i < src.nbits )
+ m_obj_p->set(low_i, src.test(low_i));
+ else
+ m_obj_p->set(low_i, 0);
+}
+
+void sc_unsigned_bitref::concat_set(uint64 src, int low_i)
+{
+ bool value = ((low_i < 64) ? (src >> low_i)&1 : 0);
+ m_obj_p->set(low_i, value);
+}
+
+// other methods
+
+void
+sc_unsigned_bitref::scan( ::std::istream& is )
+{
+ bool b;
+ is >> b;
+ *this = b;
+}
+
+
+// End of file
diff --git a/ext/systemc/src/sysc/datatypes/int/sc_unsigned_subref.inc b/ext/systemc/src/sysc/datatypes/int/sc_unsigned_subref.inc
new file mode 100644
index 000000000..142d6b2dc
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/int/sc_unsigned_subref.inc
@@ -0,0 +1,407 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_unsigned_subref.h -- Proxy class that is declared in sc_unsigned.h.
+
+ Original Author: Ali Dasdan, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_unsigned_subref_r
+//
+// Proxy class for sc_unsigned part selection (r-value only).
+// ----------------------------------------------------------------------------
+
+// concatenation support
+
+uint64 sc_unsigned_subref_r::concat_get_uint64() const // #### Speed up!
+{
+ sc_unsigned a( m_obj_p, m_left, m_right );
+ return a.to_uint64();
+}
+
+
+bool sc_unsigned_subref_r::concat_get_ctrl(sc_digit* dst_p, int low_i) const
+ // #### Speed up!
+{
+ sc_unsigned a( m_obj_p, m_left, m_right );
+ return a.concat_get_ctrl( dst_p, low_i );
+}
+
+bool sc_unsigned_subref_r::concat_get_data(sc_digit* dst_p, int low_i) const
+ // #### Speed up!
+{
+ sc_unsigned a( m_obj_p, m_left, m_right );
+ return a.concat_get_data( dst_p, low_i );
+}
+
+
+// implicit conversion to sc_unsigned
+
+sc_unsigned_subref_r::operator sc_unsigned () const
+{
+ return sc_unsigned( m_obj_p, m_left, m_right );
+}
+
+
+// explicit conversions
+
+int
+sc_unsigned_subref_r::to_int() const
+{
+ sc_unsigned a( m_obj_p, m_left, m_right );
+ return a.to_int();
+}
+
+unsigned int
+sc_unsigned_subref_r::to_uint() const
+{
+ sc_unsigned a( m_obj_p, m_left, m_right );
+ return a.to_uint();
+}
+
+long
+sc_unsigned_subref_r::to_long() const
+{
+ sc_unsigned a( m_obj_p, m_left, m_right );
+ return a.to_long();
+}
+
+unsigned long
+sc_unsigned_subref_r::to_ulong() const
+{
+ sc_unsigned a( m_obj_p, m_left, m_right );
+ return a.to_ulong();
+}
+
+int64
+sc_unsigned_subref_r::to_int64() const
+{
+ sc_unsigned a( m_obj_p, m_left, m_right );
+ return a.to_int64();
+}
+
+uint64
+sc_unsigned_subref_r::to_uint64() const
+{
+ sc_unsigned a( m_obj_p, m_left, m_right );
+ return a.to_uint64();
+}
+
+double
+sc_unsigned_subref_r::to_double() const
+{
+ sc_unsigned a( m_obj_p, m_left, m_right );
+ return a.to_double();
+}
+
+
+// explicit conversion to character string
+
+const std::string
+sc_unsigned_subref_r::to_string( sc_numrep numrep ) const
+{
+ sc_unsigned a( length() );
+ a = *this;
+ return a.to_string( numrep );
+}
+
+const std::string
+sc_unsigned_subref_r::to_string( sc_numrep numrep, bool w_prefix ) const
+{
+ sc_unsigned a( length() );
+ a = *this;
+ return a.to_string( numrep, w_prefix );
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_unsigned_subref
+//
+// Proxy class for sc_unsigned part selection (r-value and l-value).
+// ----------------------------------------------------------------------------
+
+// assignment operators
+
+const sc_unsigned_subref&
+sc_unsigned_subref::operator = ( const sc_unsigned_subref_r& a )
+{
+ return operator = ( (sc_unsigned)( a ) );
+}
+
+const sc_unsigned_subref&
+sc_unsigned_subref::operator = ( const sc_unsigned_subref& a )
+{
+ if( this == &a ) {
+ return *this;
+ }
+ return operator = ( (sc_unsigned)( a ) );
+}
+
+const sc_unsigned_subref&
+sc_unsigned_subref::operator = ( const sc_unsigned& v )
+{
+ int i;
+ int l = sc_min( m_left, v.nbits - 1 + m_right );
+
+ for( i = m_right; i <= l; ++ i ) m_obj_p->set( i, v.test( i - m_right ) );
+ for ( ; i <= m_left; i++ ) m_obj_p->set( i, v.test( l ) );
+ return *this;
+}
+
+const sc_unsigned_subref&
+sc_unsigned_subref::operator = ( const sc_signed_subref_r& v )
+{
+ return operator = ( (sc_unsigned)( v ) );
+}
+
+const sc_unsigned_subref&
+sc_unsigned_subref::operator = ( const sc_signed& v )
+{
+ int i;
+ int l = sc_min( m_left, v.nbits - 1 + m_right );
+
+ for( i = m_right; i <= l; ++ i ) m_obj_p->set( i, v.test( i - m_right ) );
+ for ( ; i <= m_left; i++ ) m_obj_p->set( i, 0 );
+ return *this;
+}
+
+const sc_unsigned_subref&
+sc_unsigned_subref::operator = ( unsigned long v )
+{
+ for( int i = m_right; i <= m_left; ++ i ) {
+ m_obj_p->set( i, static_cast<bool>( v & 1 ) );
+ v >>= 1;
+ }
+ return *this;
+}
+
+const sc_unsigned_subref&
+sc_unsigned_subref::operator = ( long v )
+{
+ unsigned long v2 = (unsigned long) v;
+ for( int i = m_right; i <= m_left; ++ i ) {
+ m_obj_p->set( i, static_cast<bool>( v2 & 1 ) );
+ v2 >>= 1;
+ }
+ return *this;
+}
+
+const sc_unsigned_subref&
+sc_unsigned_subref::operator = ( uint64 v )
+{
+ for( int i = m_right; i <= m_left; ++ i ) {
+ m_obj_p->set( i, static_cast<bool>( v & 1 ) );
+ v >>= 1;
+ }
+ return *this;
+}
+
+const sc_unsigned_subref&
+sc_unsigned_subref::operator = ( int64 v )
+{
+ uint64 v2 = (uint64) v;
+ for( int i = m_right; i <= m_left; ++ i ) {
+ m_obj_p->set( i, static_cast<bool>( v2 & 1 ) );
+ v2 >>= 1;
+ }
+ return *this;
+}
+
+const sc_unsigned_subref&
+sc_unsigned_subref::operator = ( double v )
+{
+ is_bad_double(v);
+
+ int nb = m_left - m_right + 1;
+ int nd = DIV_CEIL(nb);
+
+#ifdef SC_MAX_NBITS
+ sc_digit d[MAX_NDIGITS];
+#else
+ sc_digit *d = new sc_digit[nd];
+#endif
+
+ if (v < 0)
+ v = -v;
+
+ int i = 0;
+
+ while (floor(v) && (i < nd)) {
+#ifndef _WIN32
+ d[i++] = (sc_digit) floor(remainder(v, DIGIT_RADIX));
+#else
+ d[i++] = (sc_digit) floor(fmod(v, DIGIT_RADIX));
+#endif
+ v /= DIGIT_RADIX;
+ }
+
+ vec_zero(i, nd, d);
+
+ sc_digit val = 1; // Bit value.
+ int j = 0; // Current digit in d.
+
+ i = 0; // Current bit in d.
+
+ while (i < nb) {
+
+ m_obj_p->set(i + m_right, (bool) (d[j] & val));
+
+ ++i;
+
+ if (i % BITS_PER_DIGIT == 0) {
+ val = 1;
+ ++j;
+ }
+ else
+ val <<= 1;
+ }
+
+#ifndef SC_MAX_NBITS
+ delete [] d;
+#endif
+
+ return *this;
+}
+
+const sc_unsigned_subref&
+sc_unsigned_subref::operator = ( const sc_int_base& a )
+{
+ return operator = ( (int64) a );
+}
+
+const sc_unsigned_subref&
+sc_unsigned_subref::operator = ( const sc_uint_base& a )
+{
+ return operator = ( (uint64) a );
+}
+
+// concatenation methods
+
+void sc_unsigned_subref::concat_set( int64 src, int low_i )
+{
+ int i;
+ int l;
+ bool sign = src < 0;
+
+ if ( low_i < 64 )
+ {
+ src = src >> low_i;
+ l = sc_min( m_left, (63-low_i) + m_right );
+ for( i = m_right; i <= l; ++ i ) {
+ m_obj_p->set( i, src & 1 );
+ src = src >> 1;
+ }
+ for ( ; i <= m_left; i++ ) m_obj_p->set(sign);
+ }
+ else
+ {
+ for( i = m_right; i <= m_left; ++ i ) m_obj_p->set(sign);
+ }
+}
+
+void sc_unsigned_subref::concat_set( const sc_signed& src, int low_i )
+{
+ int i;
+ int l;
+ int src_i;
+ bool sign = src.test(src.nbits-1);
+ l = src.nbits - (low_i+1);
+ if ( l >= 0 )
+ {
+ src_i = low_i;
+ l = sc_min( m_left, l + m_right );
+ for( i = m_right; i <= l; ++ i, src_i++ ) {
+ m_obj_p->set( i, src.test( src_i ) );
+ }
+ for ( ; i <= m_left; i++ ) m_obj_p->set(i, sign);
+ }
+ else
+ {
+ for( i = m_right; i <= m_left; ++ i ) m_obj_p->set(i, sign);
+ }
+}
+
+void sc_unsigned_subref::concat_set( const sc_unsigned& src, int low_i )
+{
+ int i;
+ int l;
+ int src_i;
+ l = src.nbits - (low_i+2);
+ if ( l >= 0 )
+ {
+ src_i = low_i;
+ l = sc_min( m_left, l + m_right );
+ for( i = m_right; i <= l; ++ i, src_i++ ) {
+ m_obj_p->set( i, src.test( src_i ) );
+ }
+ for ( ; i <= m_left; i++ ) m_obj_p->set(i, false);
+ }
+ else
+ {
+ for( i = m_right; i <= m_left; ++ i ) m_obj_p->set(i, false);
+ }
+}
+
+void sc_unsigned_subref::concat_set( uint64 src, int low_i )
+{
+ int i;
+ int l;
+
+ if ( low_i < 64 )
+ {
+ src = src >> low_i;
+ l = sc_min( m_left, (63-low_i) + m_right );
+ for( i = m_right; i <= l; ++ i ) {
+ m_obj_p->set( i, src & 1 );
+ src = src >> 1;
+ }
+ for ( ; i <= m_left; i++ ) m_obj_p->set(false);
+ }
+ else
+ {
+ for( i = m_right; i <= m_left; ++ i ) m_obj_p->set(false);
+ }
+}
+// other methods
+
+void
+sc_unsigned_subref::scan( ::std::istream& is )
+{
+ std::string s;
+ is >> s;
+ *this = s.c_str();
+}
+
+
+// End of file
diff --git a/ext/systemc/src/sysc/datatypes/misc/sc_concatref.cpp b/ext/systemc/src/sysc/datatypes/misc/sc_concatref.cpp
new file mode 100644
index 000000000..566bee234
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/misc/sc_concatref.cpp
@@ -0,0 +1,59 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_concatref.cpp -- Concatenation support.
+
+ Original Author: Andy Goodrich, Forte Design Systems, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_concatref.cpp,v $
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:54:01 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#include "sysc/datatypes/misc/sc_concatref.h"
+#include "sysc/utils/sc_temporary.h"
+
+// STORAGE POOLS USED BY sc_concatref:
+
+namespace sc_dt {
+ sc_core::sc_vpool<sc_concat_bool> sc_concat_bool::m_pool(9);
+ sc_core::sc_vpool<sc_concatref> sc_concatref::m_pool(9);
+} // namespace sc_dt
+
+namespace sc_core {
+ sc_byte_heap sc_temp_heap(0x300000);
+} // namespace sc_core
diff --git a/ext/systemc/src/sysc/datatypes/misc/sc_concatref.h b/ext/systemc/src/sysc/datatypes/misc/sc_concatref.h
new file mode 100644
index 000000000..92dcc18ec
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/misc/sc_concatref.h
@@ -0,0 +1,855 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_concatref.h -- Concatenation support.
+
+ Original Author: Andy Goodrich, Forte Design, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ Andy Goodrich, Forte Design Systems, 17 Nov 2002
+ Creation of sc_concatref class by merging the capabilities of
+ sc_int_concref, sc_int_concref, sc_uint_concref, sc_uint_concref,
+ and implementing the capabilities of sc_signed_concref, sc_signed_concref,
+ sc_unsigned_concref, and sc_unsigned_concref. The resultant class allows
+ mixed mode concatenations on the left and right sides of an assignment.
+
+ *****************************************************************************/
+
+// $Log: sc_concatref.h,v $
+// Revision 1.6 2011/08/24 22:05:48 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.5 2009/11/17 19:58:15 acg
+// Andy Goodrich: fix of shift rhs possibilities to include "int".
+//
+// Revision 1.4 2009/02/28 00:26:29 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.3 2008/04/29 20:23:55 acg
+// Andy Goodrich: fixed the code that assigns the value of a string to
+// an sc_concatref instance.
+//
+// Revision 1.2 2008/02/14 20:57:26 acg
+// Andy Goodrich: added casts to ~0 instances to keep MSVC compiler happy.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.4 2006/10/23 19:36:59 acg
+// Andy Goodrich: changed casts for operations on concatenation values to
+// mirror those of sc_unsigned. For instance, an sc_unsigned minus a value
+// returns an sc_signed result, whereas an sc_concatref minus a value was
+// returning an sc_unsigned result. Now both sc_unsigned and sc_concatref
+// minus a value return an sc_signed result.
+//
+// Revision 1.3 2006/01/13 18:54:01 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#ifndef SC_CONCATREF_H
+#define SC_CONCATREF_H
+
+#include "sysc/kernel/sc_object.h"
+#include "sysc/datatypes/misc/sc_value_base.h"
+#include "sysc/utils/sc_temporary.h"
+#include "sysc/datatypes/bit/sc_bv.h"
+#include "sysc/datatypes/bit/sc_lv.h"
+#include "sysc/datatypes/int/sc_int_base.h"
+#include "sysc/datatypes/int/sc_uint_base.h"
+#include "sysc/datatypes/int/sc_signed.h"
+#include "sysc/datatypes/int/sc_unsigned.h"
+
+namespace sc_core {
+ extern sc_byte_heap sc_temp_heap; // Temporary storage.
+} // namespace sc_core
+
+namespace sc_dt
+{
+
+// ----------------------------------------------------------------------------
+// CLASS TEMPLATE : sc_concatref
+//
+// Proxy class for sized bit concatenation.
+// ----------------------------------------------------------------------------
+
+class sc_concatref : public sc_generic_base<sc_concatref>, public sc_value_base
+{
+public:
+ friend class sc_core::sc_vpool<sc_concatref>;
+
+ inline void initialize(
+ sc_value_base& left, sc_value_base& right )
+ {
+ bool left_xz; // True if x's and/or z's found in left.
+ bool right_xz; // True if x's and/or z's found in right.
+
+ m_left_p = (sc_value_base*)&left;
+ m_right_p = (sc_value_base*)&right;
+ m_len_r = right.concat_length(&right_xz);
+ m_len = left.concat_length(&left_xz) + m_len_r;
+ m_flags = ( left_xz || right_xz ) ? cf_xz_present : cf_none;
+ }
+
+
+ inline void initialize(
+ const sc_value_base& left, const sc_value_base& right )
+ {
+ bool left_xz; // True if x's and/or z's found in left.
+ bool right_xz; // True if x's and/or z's found in right.
+
+ m_left_p = (sc_value_base*)&left;
+ m_right_p = (sc_value_base*)&right;
+ m_len_r = right.concat_length(&right_xz);
+ m_len = left.concat_length(&left_xz) + m_len_r;
+ m_flags = ( left_xz || right_xz ) ? cf_xz_present : cf_none;
+ }
+
+ // destructor
+
+ virtual ~sc_concatref()
+ {}
+
+
+ // capacity
+
+ unsigned int length() const
+ { return m_len; }
+
+#ifdef SC_DT_DEPRECATED
+ int bitwidth() const
+ { return length(); }
+#endif
+
+ // concatenation
+
+ virtual int concat_length( bool* xz_present_p ) const
+ {
+ if ( xz_present_p )
+ *xz_present_p = m_flags & cf_xz_present ? true : false;
+ return m_len;
+ }
+
+ virtual void concat_clear_data( bool to_ones )
+ {
+ m_left_p->concat_clear_data(to_ones);
+ m_right_p->concat_clear_data(to_ones);
+ }
+
+ virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const
+ {
+ bool rnz = m_right_p->concat_get_ctrl( dst_p, low_i );
+ bool lnz = m_left_p->concat_get_ctrl( dst_p, low_i+m_len_r );
+ return rnz || lnz;
+ }
+
+ virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const
+ {
+ bool rnz = m_right_p->concat_get_data( dst_p, low_i );
+ bool lnz = m_left_p->concat_get_data( dst_p, low_i+m_len_r );
+ return rnz || lnz;
+ }
+
+ virtual uint64 concat_get_uint64() const
+ {
+ if ( m_len_r >= 64 )
+ return m_right_p->concat_get_uint64();
+ else
+ {
+ return (m_left_p->concat_get_uint64() << m_len_r) |
+ m_right_p->concat_get_uint64();
+ }
+ }
+
+ virtual void concat_set( int64 src, int low_i )
+ {
+ m_right_p->concat_set( src, low_i );
+ m_left_p->concat_set( src, low_i+m_len_r);
+ }
+
+ virtual void concat_set( const sc_signed& src, int low_i )
+ {
+ m_right_p->concat_set( src, low_i );
+ m_left_p->concat_set( src, low_i+m_len_r);
+ }
+
+ virtual void concat_set( const sc_unsigned& src, int low_i )
+ {
+ m_right_p->concat_set( src, low_i );
+ m_left_p->concat_set( src, low_i+m_len_r);
+ }
+
+ virtual void concat_set( uint64 src, int low_i )
+ {
+ m_right_p->concat_set( src, low_i );
+ m_left_p->concat_set( src, low_i+m_len_r);
+ }
+
+
+ // explicit conversions
+
+ uint64 to_uint64() const
+ {
+ uint64 mask;
+ uint64 result;
+
+ result = m_right_p->concat_get_uint64();
+ if ( m_len_r < 64 )
+ {
+ mask = (uint64)~0;
+ result = (m_left_p->concat_get_uint64() << m_len_r) |
+ (result & ~(mask << m_len_r));
+ }
+ if ( m_len < 64 )
+ {
+ mask = (uint64)~0;
+ result = result & ~(mask << m_len);
+ }
+ return result;
+ }
+
+ const sc_unsigned& value() const
+ {
+ bool left_non_zero;
+ sc_unsigned* result_p = sc_unsigned::m_pool.allocate();
+ bool right_non_zero;
+
+ result_p->nbits = result_p->num_bits(m_len);
+ result_p->ndigits = DIV_CEIL(result_p->nbits);
+ result_p->digit = (sc_digit*)sc_core::sc_temp_heap.allocate(
+ sizeof(sc_digit)*result_p->ndigits );
+#if defined(_MSC_VER)
+ // workaround spurious initialisation issue on MS Visual C++
+ memset( result_p->digit, 0, sizeof(sc_digit)*result_p->ndigits );
+#else
+ result_p->digit[result_p->ndigits-1] = 0;
+#endif
+ right_non_zero = m_right_p->concat_get_data( result_p->digit, 0 );
+ left_non_zero = m_left_p->concat_get_data(result_p->digit, m_len_r);
+ if ( left_non_zero || right_non_zero )
+ result_p->sgn = SC_POS;
+ else
+ result_p->sgn = SC_ZERO;
+ return *result_p;
+ }
+
+ int64 to_int64() const
+ {
+ return (int64)to_uint64();
+ }
+ int to_int() const
+ { return (int)to_int64(); }
+ unsigned int to_uint() const
+ { return (unsigned int)to_uint64(); }
+ long to_long() const
+ { return (long)to_int64(); }
+ unsigned long to_ulong() const
+ { return (unsigned long)to_uint64(); }
+ double to_double() const
+ { return value().to_double(); }
+
+ void to_sc_signed( sc_signed& target ) const
+ { target = value(); }
+
+ void to_sc_unsigned( sc_unsigned& target ) const
+ { target = value(); }
+
+ // implicit conversions:
+
+ operator uint64 () const
+ { return to_uint64(); }
+
+ operator const sc_unsigned& () const
+ { return value(); }
+
+ // unary operators:
+
+ sc_unsigned operator + () const
+ { return value(); }
+
+ sc_signed operator - () const
+ { return -value(); }
+
+ sc_unsigned operator ~ () const
+ { return ~value(); }
+
+ // explicit conversion to character string
+
+ const std::string to_string( sc_numrep numrep = SC_DEC ) const
+ { return value().to_string(numrep); }
+
+ const std::string to_string( sc_numrep numrep, bool w_prefix ) const
+ { return value().to_string(numrep,w_prefix); }
+
+
+
+ // assignments
+
+ inline const sc_concatref& operator = ( int v )
+ {
+ m_right_p->concat_set((int64)v, 0);
+ m_left_p->concat_set((int64)v, m_len_r);
+ return *this;
+ }
+
+ inline const sc_concatref& operator = ( long v )
+ {
+ m_right_p->concat_set((int64)v, 0);
+ m_left_p->concat_set((int64)v, m_len_r);
+ return *this;
+ }
+
+ inline const sc_concatref& operator = ( int64 v )
+ {
+ m_right_p->concat_set(v, 0);
+ m_left_p->concat_set(v, m_len_r);
+ return *this;
+ }
+
+ inline const sc_concatref& operator = ( unsigned int v )
+ {
+ m_right_p->concat_set((uint64)v, 0);
+ m_left_p->concat_set((uint64)v, m_len_r);
+ return *this;
+ }
+
+ inline const sc_concatref& operator = ( unsigned long v )
+ {
+ m_right_p->concat_set((uint64)v, 0);
+ m_left_p->concat_set((uint64)v, m_len_r);
+ return *this;
+ }
+
+ inline const sc_concatref& operator = ( uint64 v )
+ {
+ m_right_p->concat_set(v, 0);
+ m_left_p->concat_set(v, m_len_r);
+ return *this;
+ }
+
+ const sc_concatref& operator = ( const sc_concatref& v )
+ {
+ sc_unsigned temp(v.length());
+ temp = v.value();
+ m_right_p->concat_set(temp, 0);
+ m_left_p->concat_set(temp, m_len_r);
+ return *this;
+ }
+
+ const sc_concatref& operator = ( const sc_signed& v )
+ {
+ m_right_p->concat_set(v, 0);
+ m_left_p->concat_set(v, m_len_r);
+ return *this;
+ }
+
+ const sc_concatref& operator = ( const sc_unsigned& v )
+ {
+ m_right_p->concat_set(v, 0);
+ m_left_p->concat_set(v, m_len_r);
+ return *this;
+ }
+
+ const sc_concatref& operator = ( const char* v_p )
+ {
+ sc_unsigned v(m_len);
+ v = v_p;
+ m_right_p->concat_set(v, 0);
+ m_left_p->concat_set(v, m_len_r);
+ return *this;
+ }
+
+ const sc_concatref& operator = ( const sc_bv_base& v )
+ {
+ sc_unsigned temp(v.length());
+ temp = v;
+ m_right_p->concat_set(temp, 0);
+ m_left_p->concat_set(temp, m_len_r);
+ return *this;
+ }
+
+ const sc_concatref& operator = ( const sc_lv_base& v )
+ {
+ sc_unsigned data(v.length());
+ data = v;
+ m_right_p->concat_set(data, 0);
+ m_left_p->concat_set(data, m_len_r);
+ return *this;
+ }
+
+
+ // reduce methods
+
+ bool and_reduce() const
+ { return value().and_reduce(); }
+
+ bool nand_reduce() const
+ { return value().nand_reduce(); }
+
+ bool or_reduce() const
+ { return value().or_reduce(); }
+
+ bool nor_reduce() const
+ { return value().nor_reduce(); }
+
+ bool xor_reduce() const
+ { return value().xor_reduce(); }
+
+ bool xnor_reduce() const
+ { return value().xnor_reduce(); }
+
+ // other methods
+
+ void print( ::std::ostream& os = ::std::cout ) const
+ { os << this->value(); }
+
+ void scan( ::std::istream& is )
+ {
+ std::string s;
+ is >> s;
+ *this = s.c_str();
+ }
+
+public:
+ static sc_core::sc_vpool<sc_concatref> m_pool; // Pool of temporary objects.
+
+public:
+ enum concat_flags {
+ cf_none = 0, // Normal value.
+ cf_xz_present = 1 // X and/or Z values present.
+ };
+
+protected:
+ sc_value_base* m_left_p; // Left hand operand of concatenation.
+ sc_value_base* m_right_p; // Right hand operand of concatenation.
+ int m_len; // Length of concatenation.
+ int m_len_r; // Length of m_rightt_p.
+ concat_flags m_flags; // Value is read only.
+
+private:
+ sc_concatref(const sc_concatref&);
+ sc_concatref() : m_left_p(0), m_right_p(0), m_len(0), m_len_r(0), m_flags()
+ {}
+};
+
+
+// functional notation for the reduce methods
+
+inline
+bool
+and_reduce( const sc_concatref& a )
+{
+ return a.and_reduce();
+}
+
+inline
+bool
+nand_reduce( const sc_concatref& a )
+{
+ return a.nand_reduce();
+}
+
+inline
+bool
+or_reduce( const sc_concatref& a )
+{
+ return a.or_reduce();
+}
+
+inline
+bool
+nor_reduce( const sc_concatref& a )
+{
+ return a.nor_reduce();
+}
+
+inline
+bool
+xor_reduce( const sc_concatref& a )
+{
+ return a.xor_reduce();
+}
+
+inline
+bool
+xnor_reduce( const sc_concatref& a )
+{
+ return a.xnor_reduce();
+}
+
+
+// SHIFT OPERATORS FOR sc_concatref OBJECT INSTANCES:
+//
+// Because sc_concatref has implicit casts to both uint64 and sc_unsigned
+// it is necessary to disambiguate the use of the shift operators. We do
+// this in favor of sc_unsigned so that precision is not lost. To get an
+// integer-based result use a cast to uint64 before performing the shift.
+
+inline const sc_unsigned operator << (const sc_concatref& target, uint64 shift)
+{
+ return target.value() << (int)shift;
+}
+
+inline const sc_unsigned operator << (const sc_concatref& target, int64 shift)
+{
+ return target.value() << (int)shift;
+}
+
+inline const sc_unsigned operator << (
+ const sc_concatref& target, unsigned long shift )
+{
+ return target.value() << (int)shift;
+}
+
+inline const sc_unsigned operator << (
+ const sc_concatref& target, int shift )
+{
+ return target.value() << shift;
+}
+
+inline const sc_unsigned operator << (
+ const sc_concatref& target, unsigned int shift )
+{
+ return target.value() << (int)shift;
+}
+
+inline const sc_unsigned operator << ( const sc_concatref& target, long shift )
+{
+ return target.value() << (int)shift;
+}
+
+inline const sc_unsigned operator >> (const sc_concatref& target, uint64 shift)
+{
+ return target.value() >> (int)shift;
+}
+
+inline const sc_unsigned operator >> (const sc_concatref& target, int64 shift)
+{
+ return target.value() >> (int)shift;
+}
+
+inline const sc_unsigned operator >> (
+ const sc_concatref& target, unsigned long shift )
+{
+ return target.value() >> (int)shift;
+}
+
+inline const sc_unsigned operator >> (
+ const sc_concatref& target, int shift )
+{
+ return target.value() >> shift;
+}
+
+inline const sc_unsigned operator >> (
+ const sc_concatref& target, unsigned int shift )
+{
+ return target.value() >> (int)shift;
+}
+
+inline const sc_unsigned operator >> ( const sc_concatref& target, long shift )
+{
+ return target.value() >> (int)shift;
+}
+
+
+// STREAM OPERATORS FOR sc_concatref OBJECT INSTANCES:
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, const sc_concatref& v )
+{
+ return os << v.value();
+}
+
+inline
+::std::istream&
+operator >> ( ::std::istream& is, sc_concatref& a )
+{
+ sc_unsigned temp(a.concat_length(0));
+ temp.scan( is );
+ a = temp;
+ return is;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS TEMPLATE : sc_concat_bool
+//
+// Proxy class for read-only boolean values in concatenations.
+// ----------------------------------------------------------------------------
+
+class sc_concat_bool : public sc_value_base
+{
+ protected:
+ static sc_core::sc_vpool<sc_concat_bool> m_pool; // Temporaries pool.
+ bool m_value; // Value for this obj.
+
+ public:
+
+ // constructor:
+
+ sc_concat_bool()
+ : sc_value_base(), m_value()
+ {}
+
+ // destructor:
+
+ virtual ~sc_concat_bool()
+ { }
+
+ // allocation of temporary object:
+
+ static inline sc_concat_bool* allocate( bool v )
+ {
+ sc_concat_bool* result_p = m_pool.allocate();
+ result_p->m_value = v;
+ return result_p;
+ }
+
+ // concatenation:
+
+ virtual int concat_length( bool* xz_present_p ) const
+ {
+ if ( xz_present_p ) *xz_present_p = false;
+ return 1;
+ }
+
+ virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const
+ {
+ int bit = 1 << (low_i % BITS_PER_DIGIT);
+ int word_i = low_i / BITS_PER_DIGIT;
+ dst_p[word_i] &= ~bit;
+ return false;
+ }
+
+ virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const
+ {
+ int bit = 1 << (low_i % BITS_PER_DIGIT);
+ int word_i = low_i / BITS_PER_DIGIT;
+ if ( m_value )
+ dst_p[word_i] |= bit;
+ else
+ dst_p[word_i] &= ~bit;
+ return m_value;
+ }
+
+ virtual uint64 concat_get_uint64() const
+ {
+ return m_value ? 1 : 0;
+ }
+};
+
+
+// ----------------------------------------------------------------------------
+// ARITHMETIC AND LOGIC OPERATORS FOR sc_concatref
+// ----------------------------------------------------------------------------
+
+#define SC_CONCAT_OP_TYPE(RESULT,OP,OTHER_TYPE) \
+ inline RESULT operator OP ( const sc_concatref& a, OTHER_TYPE b ) \
+ { \
+ return a.value() OP b; \
+ } \
+ inline RESULT operator OP ( OTHER_TYPE a, const sc_concatref& b ) \
+ { \
+ return a OP b.value(); \
+ }
+
+
+#define SC_CONCAT_OP(RESULT,OP) \
+ inline RESULT operator OP ( const sc_concatref& a, const sc_concatref& b ) \
+ { \
+ return a.value() OP b.value(); \
+ } \
+ SC_CONCAT_OP_TYPE(const sc_signed,OP,int) \
+ SC_CONCAT_OP_TYPE(const sc_signed,OP,long) \
+ SC_CONCAT_OP_TYPE(const sc_signed,OP,int64) \
+ SC_CONCAT_OP_TYPE(RESULT,OP,unsigned int) \
+ SC_CONCAT_OP_TYPE(RESULT,OP,unsigned long) \
+ SC_CONCAT_OP_TYPE(RESULT,OP,uint64) \
+ SC_CONCAT_OP_TYPE(const sc_signed,OP,const sc_int_base&) \
+ SC_CONCAT_OP_TYPE(RESULT,OP,const sc_uint_base&) \
+ SC_CONCAT_OP_TYPE(const sc_signed,OP,const sc_signed&) \
+ SC_CONCAT_OP_TYPE(RESULT,OP,const sc_unsigned&) \
+ inline RESULT operator OP ( const sc_concatref& a, bool b ) \
+ { \
+ return a.value() OP (int)b; \
+ } \
+ inline RESULT operator OP ( bool a, const sc_concatref& b ) \
+ { \
+ return (int)a OP b.value(); \
+ }
+
+#define SC_CONCAT_BOOL_OP(OP) \
+ inline bool operator OP ( const sc_concatref& a, const sc_concatref& b ) \
+ { \
+ return a.value() OP b.value(); \
+ } \
+ SC_CONCAT_OP_TYPE(bool,OP,int) \
+ SC_CONCAT_OP_TYPE(bool,OP,long) \
+ SC_CONCAT_OP_TYPE(bool,OP,int64) \
+ SC_CONCAT_OP_TYPE(bool,OP,unsigned int) \
+ SC_CONCAT_OP_TYPE(bool,OP,unsigned long) \
+ SC_CONCAT_OP_TYPE(bool,OP,uint64) \
+ SC_CONCAT_OP_TYPE(bool,OP,const sc_int_base&) \
+ SC_CONCAT_OP_TYPE(bool,OP,const sc_uint_base&) \
+ SC_CONCAT_OP_TYPE(bool,OP,const sc_signed&) \
+ SC_CONCAT_OP_TYPE(bool,OP,const sc_unsigned&) \
+ inline bool operator OP ( const sc_concatref& a, bool b ) \
+ { \
+ return a.value() OP (int)b; \
+ } \
+ inline bool operator OP ( bool a, const sc_concatref& b ) \
+ { \
+ return (int)a OP b.value(); \
+ }
+
+SC_CONCAT_OP(const sc_unsigned,+)
+SC_CONCAT_OP(const sc_signed,-)
+SC_CONCAT_OP(const sc_unsigned,*)
+SC_CONCAT_OP(const sc_unsigned,/)
+SC_CONCAT_OP(const sc_unsigned,%)
+SC_CONCAT_OP(const sc_unsigned,&)
+SC_CONCAT_OP(const sc_unsigned,|)
+SC_CONCAT_OP(const sc_unsigned,^)
+SC_CONCAT_BOOL_OP(==)
+SC_CONCAT_BOOL_OP(<=)
+SC_CONCAT_BOOL_OP(>=)
+SC_CONCAT_BOOL_OP(!=)
+SC_CONCAT_BOOL_OP(>)
+SC_CONCAT_BOOL_OP(<)
+
+#undef SC_CONCAT_OP
+#undef SC_CONCAT_OP_TYPE
+
+
+// ----------------------------------------------------------------------------
+// CONCATENATION FUNCTION AND OPERATOR FOR STANDARD SYSTEM C DATA TYPES:
+// ----------------------------------------------------------------------------
+
+inline sc_dt::sc_concatref& concat(
+ sc_dt::sc_value_base& a, sc_dt::sc_value_base& b)
+{
+ sc_dt::sc_concatref* result_p; // Proxy for the concatenation.
+
+ result_p = sc_dt::sc_concatref::m_pool.allocate();
+ result_p->initialize( a, b );
+ return *result_p;
+}
+
+inline
+const
+sc_dt::sc_concatref& concat(
+ const sc_dt::sc_value_base& a, const sc_dt::sc_value_base& b)
+{
+ sc_dt::sc_concatref* result_p; // Proxy for the concatenation.
+
+ result_p = sc_dt::sc_concatref::m_pool.allocate();
+ result_p->initialize( a, b );
+ return *result_p;
+}
+
+inline
+const
+sc_dt::sc_concatref& concat(const sc_dt::sc_value_base& a, bool b)
+{
+ const sc_dt::sc_concat_bool* b_p; // Proxy for boolean value.
+ sc_dt::sc_concatref* result_p; // Proxy for the concatenation.
+
+ b_p = sc_dt::sc_concat_bool::allocate(b);
+ result_p = sc_dt::sc_concatref::m_pool.allocate();
+ result_p->initialize( a, *b_p );
+ return *result_p;
+}
+
+inline
+const
+sc_dt::sc_concatref& concat(bool a, const sc_dt::sc_value_base& b)
+{
+ const sc_dt::sc_concat_bool* a_p; // Proxy for boolean value.
+ sc_dt::sc_concatref* result_p; // Proxy for the concatenation.
+
+ a_p = sc_dt::sc_concat_bool::allocate(a);
+ result_p = sc_dt::sc_concatref::m_pool.allocate();
+ result_p->initialize( *a_p, b );
+ return *result_p;
+}
+
+inline sc_dt::sc_concatref& operator , (
+ sc_dt::sc_value_base& a, sc_dt::sc_value_base& b)
+{
+ sc_dt::sc_concatref* result_p; // Proxy for the concatenation.
+
+ result_p = sc_dt::sc_concatref::m_pool.allocate();
+ result_p->initialize( a, b );
+ return *result_p;
+}
+
+inline
+const
+sc_dt::sc_concatref& operator , (
+ const sc_dt::sc_value_base& a, const sc_dt::sc_value_base& b)
+{
+ sc_dt::sc_concatref* result_p; // Proxy for the concatenation.
+
+ result_p = sc_dt::sc_concatref::m_pool.allocate();
+ result_p->initialize( a, b );
+ return *result_p;
+}
+
+inline
+const
+sc_dt::sc_concatref& operator , (const sc_dt::sc_value_base& a, bool b)
+{
+ const sc_dt::sc_concat_bool* b_p; // Proxy for boolean value.
+ sc_dt::sc_concatref* result_p; // Proxy for the concatenation.
+
+ b_p = sc_dt::sc_concat_bool::allocate(b);
+ result_p = sc_dt::sc_concatref::m_pool.allocate();
+ result_p->initialize( a, *b_p );
+ return *result_p;
+}
+
+inline
+const
+sc_dt::sc_concatref& operator , (bool a, const sc_dt::sc_value_base& b)
+{
+ const sc_dt::sc_concat_bool* a_p; // Proxy for boolean value.
+ sc_dt::sc_concatref* result_p; // Proxy for the concatenation.
+
+ a_p = sc_dt::sc_concat_bool::allocate(a);
+ result_p = sc_dt::sc_concatref::m_pool.allocate();
+ result_p->initialize( *a_p, b );
+ return *result_p;
+}
+
+} // namespace sc_dt
+
+#endif // SC_CONCATREF_H
+
diff --git a/ext/systemc/src/sysc/datatypes/misc/sc_value_base.cpp b/ext/systemc/src/sysc/datatypes/misc/sc_value_base.cpp
new file mode 100644
index 000000000..5f16341a7
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/misc/sc_value_base.cpp
@@ -0,0 +1,138 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_value_base.cpp -- Base class for all SystemC data values.
+
+ Original Author: Andy Goodrich, Forte Design Systems
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+
+// $Log: sc_value_base.cpp,v $
+// Revision 1.2 2011/08/15 16:43:24 acg
+// Torsten Maehne: changes to remove unused argument warnings.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:54:01 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#include <cstdlib>
+#include <assert.h>
+#include <ctype.h>
+#include <cstdio>
+
+#include "sysc/datatypes/int/sc_int_ids.h"
+#include "sysc/datatypes/misc/sc_value_base.h"
+
+namespace sc_dt
+{
+
+void sc_value_base::concat_clear_data( bool /* to_ones */ )
+{
+ char error_message[128];
+ std::sprintf(error_message,
+ "concat_clear_data method not supported by this type");
+ SC_REPORT_ERROR( sc_core::SC_ID_OPERATION_FAILED_, error_message );
+}
+
+bool sc_value_base::concat_get_ctrl( sc_digit* /*dst_p*/, int /*low_i*/ ) const
+{
+ char error_message[128];
+ std::sprintf(error_message,
+ "concat_get_ctrl method not supported by this type");
+ SC_REPORT_ERROR( sc_core::SC_ID_OPERATION_FAILED_, error_message );
+ return false;
+}
+
+bool sc_value_base::concat_get_data( sc_digit* /*dst_p*/, int /*low_i*/ ) const
+{
+ char error_message[128];
+ std::sprintf(error_message,
+ "concat_get_data method not supported by this type");
+ SC_REPORT_ERROR( sc_core::SC_ID_OPERATION_FAILED_, error_message );
+ return false;
+}
+
+sc_dt::uint64 sc_value_base::concat_get_uint64() const
+{
+ char error_message[128];
+ std::sprintf(error_message,
+ "concat_get_uint64 method not supported by this type");
+ SC_REPORT_ERROR( sc_core::SC_ID_OPERATION_FAILED_, error_message );
+ return 0;
+}
+
+int sc_value_base::concat_length(bool* /*xz_present_p*/) const
+{
+ char error_message[128];
+ std::sprintf(error_message,
+ "concat_length method not supported by this type");
+ SC_REPORT_ERROR( sc_core::SC_ID_OPERATION_FAILED_, error_message );
+ return 0;
+}
+
+void sc_value_base::concat_set( int64 /*src*/, int /*low_i*/ )
+{
+ char error_message[128];
+ std::sprintf(error_message,
+ "concat_set(int64) method not supported by this type");
+ SC_REPORT_ERROR( sc_core::SC_ID_OPERATION_FAILED_, error_message );
+}
+
+void sc_value_base::concat_set( const sc_signed& /*src*/, int /*low_i*/ )
+{
+ char error_message[128];
+ std::sprintf(error_message,
+ "concat_set(sc_signed) method not supported by this type");
+ SC_REPORT_ERROR( sc_core::SC_ID_OPERATION_FAILED_, error_message );
+}
+
+void sc_value_base::concat_set( const sc_unsigned& /*src*/, int /*low_i*/ )
+{
+ char error_message[128];
+ std::sprintf(error_message,
+ "concat_set(sc_unsigned) method not supported by this type");
+ SC_REPORT_ERROR( sc_core::SC_ID_OPERATION_FAILED_, error_message );
+}
+
+void sc_value_base::concat_set( uint64 /*src*/, int /*low_i*/ )
+{
+ char error_message[128];
+ std::sprintf(error_message,
+ "concat_set(uint64) method not supported by this type");
+ SC_REPORT_ERROR( sc_core::SC_ID_OPERATION_FAILED_, error_message );
+}
+
+} // namespace sc_dt
diff --git a/ext/systemc/src/sysc/datatypes/misc/sc_value_base.h b/ext/systemc/src/sysc/datatypes/misc/sc_value_base.h
new file mode 100644
index 000000000..1a2c73d42
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/misc/sc_value_base.h
@@ -0,0 +1,129 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_value_base.h -- Base class for SystemC bit values.
+
+ Original Author: Andy Goodrich, Forte Design Systems
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_value_base.h,v $
+// Revision 1.4 2011/08/29 18:04:32 acg
+// Philipp A. Hartmann: miscellaneous clean ups.
+//
+// Revision 1.3 2011/08/24 22:05:48 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.2 2011/06/28 21:23:04 acg
+// Andy Goodrich: merging of SCV tree.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:54:01 acg
+// Andy Goodrich: added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#ifndef SC_VALUE_BASE_H
+#define SC_VALUE_BASE_H
+
+
+#include "sysc/datatypes/int/sc_nbdefs.h"
+
+namespace sc_dt
+{
+
+class sc_signed;
+class sc_unsigned;
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_value_base
+//
+// Abstract base class of all SystemC native variables. It provides
+// support for concatenation operations via a set of virtual methods.
+// A general description of the methods appear with their default
+// definitions in sc_object.cpp.
+// ----------------------------------------------------------------------------
+
+class sc_value_base
+{
+ friend class sc_concatref;
+ private:
+ virtual void concat_clear_data( bool to_ones=false );
+ virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const;
+ virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const;
+ virtual uint64 concat_get_uint64() const;
+ virtual int concat_length(bool* xz_present_p=0) const;
+ virtual void concat_set( int64 src, int low_i );
+ virtual void concat_set( const sc_signed& src, int low_i );
+ virtual void concat_set( const sc_unsigned& src, int low_i );
+ virtual void concat_set( uint64 src, int low_i );
+ public:
+ virtual ~sc_value_base() {}
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_generic_base
+//
+// Proxy class for user-defined value classes and other classes that
+// are defined outside of SystemC.
+// The class is utilized as a base class for the arbitrary class:
+//
+// class my_class : public sc_generic_base<my_class>
+//
+// The purpose of the class is to allow to_XXXX methods defined within that
+// class so that assignments and casts from the arbitrary class to native
+// SystemC types are possible. To interact correctly with the SystemC library
+// the class derived from sc_generic_base must implement the following
+// methods:
+// (1) uint64 to_uint64() const
+// (2) int64 to_int64() const
+// (3) void to_sc_unsigned( sc_unsigned& ) const
+// (4) void to_sc_signed( sc_signed& ) const
+// ----------------------------------------------------------------------------
+template< class T >
+class sc_generic_base {
+ public:
+ inline const T* operator-> () const
+ {
+ return (const T*)this;
+ }
+ inline T* operator-> ()
+ {
+ return (T*)this;
+ }
+};
+
+} // namespace sc_dt
+
+#endif
diff --git a/ext/systemc/src/sysc/kernel/sc_attribute.cpp b/ext/systemc/src/sysc/kernel/sc_attribute.cpp
new file mode 100644
index 000000000..de89c6adf
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_attribute.cpp
@@ -0,0 +1,191 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_attribute.cpp -- Attribute classes.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG APPEARS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include "sysc/kernel/sc_attribute.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_attr_base
+//
+// Attribute base class.
+// ----------------------------------------------------------------------------
+
+// constructors
+
+sc_attr_base::sc_attr_base( const std::string& name_ )
+: m_name( name_ )
+{}
+
+sc_attr_base::sc_attr_base( const sc_attr_base& a )
+: m_name( a.m_name )
+{}
+
+
+// destructor (does nothing)
+
+sc_attr_base::~sc_attr_base()
+{}
+
+
+// get the name
+const std::string&
+sc_attr_base::name() const
+{
+ return m_name;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_attr_cltn
+//
+// Attribute collection class. Stores pointers to attributes.
+// Note: iterate over the collection by using iterators.
+// ----------------------------------------------------------------------------
+
+// constructors
+
+sc_attr_cltn::sc_attr_cltn() : m_cltn()
+{}
+
+sc_attr_cltn::sc_attr_cltn( const sc_attr_cltn& a )
+: m_cltn( a.m_cltn )
+{}
+
+
+// destructor
+sc_attr_cltn::~sc_attr_cltn()
+{
+ remove_all();
+}
+
+
+// add attribute to the collection.
+// returns 'true' if the name of the attribute is unique,
+// returns 'false' otherwise (attribute is not added).
+
+bool
+sc_attr_cltn::push_back( sc_attr_base* attribute_ )
+{
+ if( attribute_ == 0 ) {
+ return false;
+ }
+ for( int i = m_cltn.size() - 1; i >= 0; -- i ) {
+ if( attribute_->name() == m_cltn[i]->name() ) {
+ return false;
+ }
+ }
+ m_cltn.push_back( attribute_ );
+ return true;
+}
+
+
+// get attribute by name.
+// returns pointer to attribute, or 0 if name does not exist.
+
+sc_attr_base*
+sc_attr_cltn::operator [] ( const std::string& name_ )
+{
+ for( int i = m_cltn.size() - 1; i >= 0; -- i ) {
+ if( name_ == m_cltn[i]->name() ) {
+ return m_cltn[i];
+ }
+ }
+ return 0;
+}
+
+const sc_attr_base*
+sc_attr_cltn::operator [] ( const std::string& name_ ) const
+{
+ for( int i = m_cltn.size() - 1; i >= 0; -- i ) {
+ if( name_ == m_cltn[i]->name() ) {
+ return m_cltn[i];
+ }
+ }
+ return 0;
+}
+
+
+// remove attribute by name.
+// returns pointer to attribute, or 0 if name does not exist.
+
+sc_attr_base*
+sc_attr_cltn::remove( const std::string& name_ )
+{
+ for( int i = m_cltn.size() - 1; i >= 0; -- i ) {
+ if( name_ == m_cltn[i]->name() ) {
+ sc_attr_base* attribute = m_cltn[i];
+ std::swap( m_cltn[i], m_cltn.back() );
+ m_cltn.pop_back();
+ return attribute;
+ }
+ }
+ return 0;
+}
+
+
+// remove all attributes
+
+void
+sc_attr_cltn::remove_all()
+{
+ m_cltn.clear();
+}
+
+} // namespace sc_core
+
+// $Log: sc_attribute.cpp,v $
+// Revision 1.7 2011/08/26 20:46:08 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.6 2011/08/24 22:05:50 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.5 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.4 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.3 2010/07/22 20:02:33 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.2 2008/05/22 17:06:24 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.4 2006/01/16 22:27:08 acg
+// Test of $Log comment.
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_attribute.h b/ext/systemc/src/sysc/kernel/sc_attribute.h
new file mode 100644
index 000000000..0efa70de5
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_attribute.h
@@ -0,0 +1,209 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_attribute.h -- Attribute classes.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_ATTRIBUTE_H
+#define SC_ATTRIBUTE_H
+
+#include <string>
+#include <vector>
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_attr_base
+//
+// Attribute base class.
+// ----------------------------------------------------------------------------
+
+class sc_attr_base
+{
+public:
+
+ // constructors
+ sc_attr_base( const std::string& name_ );
+ sc_attr_base( const sc_attr_base& );
+
+ // destructor (does nothing)
+ virtual ~sc_attr_base();
+
+ // get the name
+ const std::string& name() const;
+
+private:
+
+ std::string m_name;
+
+private:
+
+ // disabled
+ sc_attr_base();
+ sc_attr_base& operator = ( const sc_attr_base& );
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_attr_cltn
+//
+// Attribute collection class. Stores pointers to attributes.
+// Note: iterate over the collection by using iterators.
+// ----------------------------------------------------------------------------
+
+class sc_attr_cltn
+{
+public:
+
+ // typedefs
+ typedef sc_attr_base* elem_type;
+ typedef std::vector<elem_type>::iterator iterator;
+ typedef std::vector<elem_type>::const_iterator const_iterator;
+
+ // constructors
+ sc_attr_cltn();
+ sc_attr_cltn( const sc_attr_cltn& );
+
+ // destructor
+ ~sc_attr_cltn();
+
+ // add attribute to the collection.
+ // returns 'true' if the name of the attribute is unique,
+ // returns 'false' otherwise (attribute is not added).
+ bool push_back( sc_attr_base* );
+
+ // get attribute by name.
+ // returns pointer to attribute, or 0 if name does not exist.
+ sc_attr_base* operator [] ( const std::string& name_ );
+ const sc_attr_base* operator [] ( const std::string& name_ ) const;
+
+ // remove attribute by name.
+ // returns pointer to attribute, or 0 if name does not exist.
+ sc_attr_base* remove( const std::string& name_ );
+
+ // remove all attributes
+ void remove_all();
+
+ // get the size of the collection
+ int size() const
+ { return m_cltn.size(); }
+
+ // get the begin iterator
+ iterator begin()
+ { return m_cltn.begin(); }
+ const_iterator begin() const
+ { return m_cltn.begin(); }
+
+ // get the end iterator
+ iterator end()
+ { return m_cltn.end(); }
+ const_iterator end() const
+ { return m_cltn.end(); }
+
+private:
+ std::vector<sc_attr_base*> m_cltn;
+
+private:
+
+ // disabled
+ sc_attr_cltn& operator = ( const sc_attr_cltn& );
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_attribute<T>
+//
+// Attribute class.
+// Note: T must have a default constructor and copy constructor.
+// ----------------------------------------------------------------------------
+
+template <class T>
+class sc_attribute
+: public sc_attr_base
+{
+public:
+
+ // constructors
+
+ sc_attribute( const std::string& name_ )
+ : sc_attr_base( name_ ), value()
+ {}
+
+ sc_attribute( const std::string& name_, const T& value_ )
+ : sc_attr_base( name_ ), value( value_ )
+ {}
+
+ sc_attribute( const sc_attribute<T>& a )
+ : sc_attr_base( a.name() ), value( a.value )
+ {}
+
+
+ // destructor (does nothing)
+
+ virtual ~sc_attribute()
+ {}
+
+public:
+
+ // public data member; for easy access
+ T value;
+
+private:
+
+ // disabled
+ sc_attribute();
+ sc_attribute<T>& operator = ( const sc_attribute<T>& );
+};
+
+} // namespace sc_core
+
+// $Log: sc_attribute.h,v $
+// Revision 1.6 2011/08/26 20:46:08 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.5 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.4 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.3 2010/07/22 20:02:33 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.2 2008/05/22 17:06:24 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_boost.h b/ext/systemc/src/sysc/kernel/sc_boost.h
new file mode 100644
index 000000000..4383c21c9
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_boost.h
@@ -0,0 +1,94 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_boost.h -- Thread Semantics Provided By The Boost Library
+
+ Original Author: Stuart Swan, Cadence Design Systems, Inc
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_BOOST_H
+#define SC_BOOST_H
+
+// namespace sc_dp { This is off because of bugs with gcc 2.9x
+
+// SET THE NAME OF OBJECTS THAT THE SC_BOOST LIBRARY WILL PRODUCE AND INCLUDE IT
+
+#if defined(_MSC_VER) && !defined(__ICL) && !defined(__COMO__)
+# pragma warning(disable: 4786) // identifier truncated in debug info
+# pragma warning(disable: 4710) // function not inlined
+# pragma warning(disable: 4711) // funct. selected for auto-inline expansion
+# pragma warning(disable: 4514) // unreferenced inline removed
+#endif
+
+#include <functional>
+
+#if defined(SC_BOOST_MSVC) && (SC_BOOST_MSVC < 1300)
+# pragma warning(push, 3)
+#endif
+
+#if defined(SC_BOOST_MSVC) && (SC_BOOST_MSVC < 1300)
+# pragma warning(pop)
+#endif
+
+// } // namespace sc_dp This is off because of bugs with gcc 2.9x
+
+// macros to help avoid direct user code dependencies on boost lib
+//
+// note the use of the sc_boost namespace for the SystemC version of
+// boost. to replace the version shipped with SystemC with another boost
+// you will need to change the namespace prefix back to boost.
+
+#define sc_bind std::bind
+#define sc_ref(r) std::ref(r)
+#define sc_cref(r) std::cref(r)
+
+// $Log: sc_boost.h,v $
+// Revision 1.7 2011/08/26 20:46:09 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.6 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.5 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.4 2009/07/28 01:10:53 acg
+// Andy Goodrich: updates for 2.3 release candidate.
+//
+// Revision 1.3 2009/02/28 00:26:58 acg
+// Andy Goodrich: changed boost name space to sc_boost to allow use with
+// full boost library applications.
+//
+// Revision 1.2 2008/05/22 17:06:24 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
+
+#endif // SC_BOOST_H
diff --git a/ext/systemc/src/sysc/kernel/sc_cmnhdr.h b/ext/systemc/src/sysc/kernel/sc_cmnhdr.h
new file mode 100644
index 000000000..fcbb2f568
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_cmnhdr.h
@@ -0,0 +1,138 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_cmnhdr.h - Common header file containing handy pragmas, macros and
+ definitions common to all SystemC source files.
+
+ Original Author: Amit Rao, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_CMNHDR_H
+#define SC_CMNHDR_H
+
+#if defined(_WIN32) || defined(_MSC_VER) || defined(__BORLANDC__) || \
+ defined(__MINGW32__)
+
+// all windows 32-bit compilers should define WIN32
+#if !defined(WIN32) && !defined(WIN64) && !defined(_WIN64)
+#define WIN32
+#endif
+
+// Windows Version Build Option
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0400
+#endif
+
+// remember to later include windows.h, if needed
+#define SC_HAS_WINDOWS_H_
+
+#endif // WIN32
+
+// ----------------------------------------------------------------------------
+
+#ifdef _MSC_VER
+
+// Disable VC++ warnings that are harmless
+
+// this : used in base member initializer list
+#pragma warning(disable: 4355)
+
+// new and delete warning when exception handling is turned on
+#pragma warning(disable: 4291)
+
+// in many places implicit conversion to bool
+// from other integral types is performed
+#pragma warning(disable: 4800)
+
+// unary minus operator applied to unsigned
+#pragma warning(disable: 4146)
+
+// multiple copy constructors
+#pragma warning(disable: 4521)
+
+// identifier was truncated to '255' characters in the browser information
+#pragma warning(disable: 4786)
+
+#endif
+
+// ----------------------------------------------------------------------------
+// helper macros to aid branch prediction on GCC (compatible) compilers
+
+#ifndef __GNUC__
+# define SC_LIKELY_( x ) !!(x)
+# define SC_UNLIKELY_( x ) !!(x)
+#else
+# define SC_LIKELY_( x ) __builtin_expect( !!(x), 1 )
+# define SC_UNLIKELY_( x ) __builtin_expect( !!(x), 0 )
+#endif
+
+// ----------------------------------------------------------------------------
+
+#include <cassert>
+#include <cstdio>
+#include <cstdlib>
+
+#endif // SC_CMNHDR_H
+
+// ----------------------------------------------------------------------------
+// only include Windows.h, if explicitly requested
+// (deliberately outside of include guards to enable later effect)
+#if defined(SC_HAS_WINDOWS_H_) && defined(SC_INCLUDE_WINDOWS_H)
+# undef SC_HAS_WINDOWS_H_
+# include <Windows.h>
+#endif
+
+// $Log: sc_cmnhdr.h,v $
+// Revision 1.8 2011/08/26 20:46:09 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.7 2011/05/09 04:07:48 acg
+// Philipp A. Hartmann:
+// (1) Restore hierarchy in all phase callbacks.
+// (2) Ensure calls to before_end_of_elaboration.
+//
+// Revision 1.6 2011/05/05 17:45:27 acg
+// Philip A. Hartmann: changes in WIN64 support.
+// Andy Goodrich: additional DEBUG_MSG instances to trace process handling.
+//
+// Revision 1.5 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.4 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.3 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.2 2008/05/22 17:06:24 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_constants.h b/ext/systemc/src/sysc/kernel/sc_constants.h
new file mode 100644
index 000000000..1ff20adbd
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_constants.h
@@ -0,0 +1,82 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_constants.h -- Default constants whose values may need to be
+ changed depending on the application.
+
+ Original Author: Ali Dasdan, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_CONSTANTS_H
+#define SC_CONSTANTS_H
+
+namespace sc_core {
+
+// Maximum number of bits for arbitrary precision arithmetic. If
+// defined, the arithmetic becomes faster. If not defined, the
+// arithmetic becomes slower and the precision becomes infinite. It
+// is a good idea to define this constant as a multiple of
+// BITS_PER_DIGIT, which is defined in numeric_bit/sc_nbdefs.h.
+//#define SC_MAX_NBITS 510 // 17 * BITS_PER_DIGIT
+
+
+// deprecated in 1666-2005 and later, but kept for backwards compatibility
+// - can be set by defining SC_OVERRIDE_DEFAULT_STACK_SIZE
+// - defaults defined in sc_thread_process.cpp
+extern const int SC_DEFAULT_STACK_SIZE;
+
+
+#ifdef DEBUG_SYSTEMC
+const int SC_MAX_NUM_DELTA_CYCLES = 10000;
+#endif
+
+} // namespace sc_core
+
+// $Log: sc_constants.h,v $
+// Revision 1.7 2011/08/26 20:46:09 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.6 2011/02/18 20:33:26 acg
+// Philipp A. Hartmann: added default stack size for CYGWIN32.
+//
+// Revision 1.5 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.4 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.3 2010/03/15 18:29:25 acg
+// Andy Goodrich: Changed the default stack size to 128K from 64K.
+//
+// Revision 1.2 2008/05/22 17:06:24 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
+
+#endif
diff --git a/ext/systemc/src/sysc/kernel/sc_cor.h b/ext/systemc/src/sysc/kernel/sc_cor.h
new file mode 100644
index 000000000..49892ca7a
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_cor.h
@@ -0,0 +1,157 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_cor.h -- Coroutine abstract base classes.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-12-18
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_COR_H
+#define SC_COR_H
+
+
+#include <cassert>
+#include <cstdlib>
+
+namespace sc_core {
+
+class sc_simcontext;
+
+
+// ----------------------------------------------------------------------------
+// TYPEDEF : sc_cor_fn
+//
+// Function type for creating coroutines.
+// ----------------------------------------------------------------------------
+
+typedef void (sc_cor_fn)( void* );
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_cor
+//
+// Coroutine abstract base class.
+// ----------------------------------------------------------------------------
+
+class sc_cor
+{
+protected:
+
+ // constructor
+ sc_cor() {}
+
+public:
+
+ // destructor
+ virtual ~sc_cor() {}
+
+ // switch stack protection on/off
+ virtual void stack_protect( bool /* enable */ ) {}
+
+private:
+
+ // disabled
+ sc_cor( const sc_cor& );
+ sc_cor& operator = ( const sc_cor& );
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_cor_pkg
+//
+// Coroutine package abstract base class.
+// ----------------------------------------------------------------------------
+
+class sc_cor_pkg
+{
+public:
+
+ // constructor
+ sc_cor_pkg( sc_simcontext* simc )
+ : m_simc( simc ) { assert( simc != 0 ); }
+
+ // destructor
+ virtual ~sc_cor_pkg() {}
+
+ // create a new coroutine
+ virtual sc_cor* create(
+ std::size_t stack_size, sc_cor_fn* fn, void* arg ) = 0;
+
+ // yield to the next coroutine
+ virtual void yield( sc_cor* next_cor ) = 0;
+
+ // abort the current coroutine (and resume the next coroutine)
+ virtual void abort( sc_cor* next_cor ) = 0;
+
+ // get the main coroutine
+ virtual sc_cor* get_main() = 0;
+
+ // get the simulation context
+ sc_simcontext* simcontext()
+ { return m_simc; }
+
+private:
+
+ sc_simcontext* m_simc;
+
+private:
+
+ // disabled
+ sc_cor_pkg();
+ sc_cor_pkg( const sc_cor_pkg& );
+ sc_cor_pkg& operator = ( const sc_cor_pkg& );
+};
+
+} // namespace sc_core
+
+// $Log: sc_cor.h,v $
+// Revision 1.7 2011/08/26 20:46:09 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.6 2011/08/15 16:43:24 acg
+// Torsten Maehne: changes to remove unused argument warnings.
+//
+// Revision 1.5 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.4 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.3 2011/01/19 23:21:49 acg
+// Andy Goodrich: changes for IEEE 1666 2011
+//
+// Revision 1.2 2008/05/22 17:06:24 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_cor_fiber.cpp b/ext/systemc/src/sysc/kernel/sc_cor_fiber.cpp
new file mode 100644
index 000000000..77cec8227
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_cor_fiber.cpp
@@ -0,0 +1,224 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_cor_fiber.cpp -- Coroutine implementation with fibers.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-12-18
+
+ CHANGE LOG APPEARS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#if defined(_WIN32) || defined(WIN32) || defined(WIN64)
+
+#ifndef SC_INCLUDE_WINDOWS_H
+# define SC_INCLUDE_WINDOWS_H // include Windows.h, if needed
+#endif
+
+#include "sysc/kernel/sc_cor_fiber.h"
+#include "sysc/kernel/sc_simcontext.h"
+#if defined(__GNUC__) && __USING_SJLJ_EXCEPTIONS__
+# if (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ > 2))
+# include <unwind.h>
+# else
+ extern "C" void _Unwind_SjLj_Register (struct SjLj_Function_Context *);
+ extern "C" void _Unwind_SjLj_Unregister (struct SjLj_Function_Context *);
+# endif
+#endif
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// File static variables.
+// ----------------------------------------------------------------------------
+
+// main coroutine
+
+static sc_cor_fiber main_cor;
+#if defined(__GNUC__) && __USING_SJLJ_EXCEPTIONS__
+// current coroutine
+static sc_cor_fiber* curr_cor;
+#endif
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_cor_fiber
+//
+// Coroutine class implemented with Windows fibers.
+// ----------------------------------------------------------------------------
+
+// destructor
+
+sc_cor_fiber::~sc_cor_fiber()
+{
+ if( m_fiber != 0 ) {
+ PVOID cur_fiber = GetCurrentFiber();
+ if (m_fiber != cur_fiber)
+ DeleteFiber( m_fiber );
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_cor_pkg_fiber
+//
+// Coroutine package class implemented with QuickThreads.
+// ----------------------------------------------------------------------------
+
+int sc_cor_pkg_fiber::instance_count = 0;
+
+
+// constructor
+
+sc_cor_pkg_fiber::sc_cor_pkg_fiber( sc_simcontext* simc )
+: sc_cor_pkg( simc )
+{
+ if( ++ instance_count == 1 ) {
+ // initialize the main coroutine
+ assert( main_cor.m_fiber == 0 );
+ main_cor.m_fiber = ConvertThreadToFiber( 0 );
+
+ if( !main_cor.m_fiber && GetLastError() == ERROR_ALREADY_FIBER ) {
+ // conversion of current thread to fiber has failed, because
+ // someone else already converted the main thread to a fiber
+ // -> store current fiber
+ main_cor.m_fiber = GetCurrentFiber();
+ }
+ assert( main_cor.m_fiber != 0 );
+
+# if defined(__GNUC__) && __USING_SJLJ_EXCEPTIONS__
+ // initialize the current coroutine
+ assert( curr_cor == 0 );
+ curr_cor = &main_cor;
+# endif
+ }
+}
+
+
+// destructor
+
+sc_cor_pkg_fiber::~sc_cor_pkg_fiber()
+{
+ if( -- instance_count == 0 ) {
+ // cleanup the main coroutine
+ main_cor.m_fiber = 0;
+# if defined(__GNUC__) && __USING_SJLJ_EXCEPTIONS__
+ // cleanup the current coroutine
+ curr_cor = 0;
+# endif
+ }
+}
+
+
+// create a new coroutine
+
+sc_cor*
+sc_cor_pkg_fiber::create( std::size_t stack_size, sc_cor_fn* fn, void* arg )
+{
+ sc_cor_fiber* cor = new sc_cor_fiber;
+ cor->m_pkg = this;
+ cor->m_stack_size = stack_size;
+ cor->m_fiber = CreateFiberEx( cor->m_stack_size / 2, cor->m_stack_size, 0,
+ (LPFIBER_START_ROUTINE) fn, arg );
+ return cor;
+}
+
+
+// yield to the next coroutine
+
+void
+sc_cor_pkg_fiber::yield( sc_cor* next_cor )
+{
+ sc_cor_fiber* new_cor = SCAST<sc_cor_fiber*>( next_cor );
+# if defined(__GNUC__) && __USING_SJLJ_EXCEPTIONS__
+ // Switch SJLJ exception handling function contexts
+ _Unwind_SjLj_Register(&curr_cor->m_eh);
+ _Unwind_SjLj_Unregister(&new_cor->m_eh);
+ curr_cor = new_cor;
+# endif
+ SwitchToFiber( new_cor->m_fiber );
+}
+
+
+// abort the current coroutine (and resume the next coroutine)
+
+void
+sc_cor_pkg_fiber::abort( sc_cor* next_cor )
+{
+ sc_cor_fiber* new_cor = SCAST<sc_cor_fiber*>( next_cor );
+# if defined(__GNUC__) && __USING_SJLJ_EXCEPTIONS__
+ // Switch SJLJ exception handling function contexts
+ _Unwind_SjLj_Register(&curr_cor->m_eh);
+ _Unwind_SjLj_Unregister(&new_cor->m_eh);
+ curr_cor = new_cor;
+# endif
+ SwitchToFiber( new_cor->m_fiber );
+}
+
+
+// get the main coroutine
+
+sc_cor*
+sc_cor_pkg_fiber::get_main()
+{
+ return &main_cor;
+}
+
+} // namespace sc_core
+
+
+// $Log: sc_cor_fiber.cpp,v $
+// Revision 1.9 2011/09/08 16:12:45 acg
+// Philipp A. Hartmann: make sure we don't try to make a thread a fiber if
+// its already a fiber.
+//
+// Revision 1.8 2011/08/26 20:46:09 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.7 2011/06/25 17:08:39 acg
+// Andy Goodrich: Jerome Cornet's changes to use libtool to build the
+// library.
+//
+// Revision 1.6 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.5 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.4 2011/01/19 23:21:50 acg
+// Andy Goodrich: changes for IEEE 1666 2011
+//
+// Revision 1.3 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.2 2008/05/22 17:06:25 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_cor_fiber.h b/ext/systemc/src/sysc/kernel/sc_cor_fiber.h
new file mode 100644
index 000000000..96163f497
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_cor_fiber.h
@@ -0,0 +1,169 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_cor_fiber.h -- Coroutine implementation with fibers.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-12-18
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_COR_FIBER_H
+#define SC_COR_FIBER_H
+
+#if defined(_WIN32) || defined(WIN32) || defined(WIN64)
+
+#include "sysc/kernel/sc_cor.h"
+#include "sysc/kernel/sc_cmnhdr.h"
+
+#if defined(__GNUC__) && __USING_SJLJ_EXCEPTIONS__
+ // _Unwind_SjLj_Register() & _Unwind_SjLj_Unregister() only need first field.
+ struct SjLj_Function_Context {
+ struct SjLj_Function_Context *prev;
+ };
+#endif
+
+namespace sc_core {
+
+class sc_cor_pkg_fiber;
+typedef sc_cor_pkg_fiber sc_cor_pkg_t;
+
+#if( defined(_MSC_VER) && _MSC_VER >= 1300 )
+typedef std::size_t size_t;
+#endif
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_cor_fiber
+//
+// Coroutine class implemented with QuickThreads.
+// ----------------------------------------------------------------------------
+
+class sc_cor_fiber
+: public sc_cor
+{
+
+public:
+
+ // constructor
+ sc_cor_fiber()
+ : m_stack_size( 0 ), m_fiber( 0 ), m_pkg( 0 )
+ {
+# if defined(__GNUC__) && __USING_SJLJ_EXCEPTIONS__
+ m_eh.prev = 0;
+# endif
+ }
+
+ // destructor
+ virtual ~sc_cor_fiber();
+
+public:
+
+ std::size_t m_stack_size; // stack size
+ void* m_fiber; // fiber
+
+ sc_cor_pkg_fiber* m_pkg; // the creating coroutine package
+#if defined(__GNUC__) && __USING_SJLJ_EXCEPTIONS__
+ struct SjLj_Function_Context m_eh; // the exception handling context
+#endif
+
+
+private:
+
+ // disabled
+ sc_cor_fiber( const sc_cor_fiber& );
+ sc_cor_fiber& operator = ( const sc_cor_fiber& );
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_cor_pkg_fiber
+//
+// Coroutine package class implemented with QuickThreads.
+// ----------------------------------------------------------------------------
+
+class sc_cor_pkg_fiber
+: public sc_cor_pkg
+{
+ public:
+
+ // constructor
+ sc_cor_pkg_fiber( sc_simcontext* simc );
+
+ // destructor
+ virtual ~sc_cor_pkg_fiber();
+
+ // create a new coroutine
+ virtual sc_cor* create( std::size_t stack_size, sc_cor_fn* fn, void* arg );
+
+ // yield to the next coroutine
+ virtual void yield( sc_cor* next_cor );
+
+ // abort the current coroutine (and resume the next coroutine)
+ virtual void abort( sc_cor* next_cor );
+
+ // get the main coroutine
+ virtual sc_cor* get_main();
+
+private:
+
+ static int instance_count;
+
+private:
+
+ // disabled
+ sc_cor_pkg_fiber();
+ sc_cor_pkg_fiber( const sc_cor_pkg_fiber& );
+ sc_cor_pkg_fiber& operator = ( const sc_cor_pkg_fiber& );
+};
+
+} // namespace sc_core
+
+#endif // WIN32
+
+// $Log: sc_cor_fiber.h,v $
+// Revision 1.6 2011/08/26 20:46:09 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.5 2011/06/25 17:08:39 acg
+// Andy Goodrich: Jerome Cornet's changes to use libtool to build the
+// library.
+//
+// Revision 1.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.2 2008/05/22 17:06:25 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_cor_pthread.cpp b/ext/systemc/src/sysc/kernel/sc_cor_pthread.cpp
new file mode 100644
index 000000000..d95eca93b
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_cor_pthread.cpp
@@ -0,0 +1,313 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_cor_pthread.cpp -- Coroutine implementation with pthreads.
+
+ Original Author: Andy Goodrich, Forte Design Systems, 2002-11-10
+
+ CHANGE LOG APPEARS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#if !defined(_WIN32) && !defined(WIN32) && defined(SC_USE_PTHREADS)
+
+// ORDER OF THE INCLUDES AND namespace sc_core IS IMPORTANT!!!
+
+#include "sysc/kernel/sc_cor_pthread.h"
+#include "sysc/kernel/sc_simcontext.h"
+
+using namespace std;
+
+namespace sc_core {
+
+// MAKE SURE WE HAVE A NULL THAT WILL WORK:
+
+#if defined(__hpux)
+# define PTHREAD_NULL cma_c_null
+#else // !defined(__hpux)
+# define PTHREAD_NULL NULL
+#endif // !defined(__hpux)
+
+#define DEBUGF \
+ if (0) std::cout << "sc_cor_pthread.cpp(" << __LINE__ << ") "
+
+// ----------------------------------------------------------------------------
+// File static variables.
+//
+// (1) The thread creation mutex and the creation condition are used to
+// suspend the thread creating another one until the created thread
+// reaches its invoke_module_method. This allows us to get control of
+// thread scheduling away from the pthread package.
+// ----------------------------------------------------------------------------
+
+static sc_cor_pthread* active_cor_p=0; // Active co-routine.
+static pthread_cond_t create_condition; // See note 1 above.
+static pthread_mutex_t create_mutex; // See note 1 above.
+static sc_cor_pthread main_cor; // Main coroutine.
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_cor_pthread
+//
+// Coroutine class implemented with Posix Threads.
+// ----------------------------------------------------------------------------
+
+// constructor
+
+sc_cor_pthread::sc_cor_pthread()
+ : m_cor_fn_arg( 0 ), m_pkg_p( 0 )
+{
+ DEBUGF << this << ": sc_cor_pthread::sc_cor_pthread()" << std::endl;
+ pthread_cond_init( &m_pt_condition, PTHREAD_NULL );
+ pthread_mutex_init( &m_mutex, PTHREAD_NULL );
+}
+
+
+// destructor
+
+sc_cor_pthread::~sc_cor_pthread()
+{
+ DEBUGF << this << ": sc_cor_pthread::~sc_cor_pthread()" << std::endl;
+ pthread_cond_destroy( &m_pt_condition);
+ pthread_mutex_destroy( &m_mutex );
+}
+
+
+// This static method is a Posix Threads helper callback and invokes a thread
+// for the first time. It performs some synchronization and then invokes the
+// actual sc_cor helper function.
+// context_p -> thread to invoke module method of.
+// Result is 0 and ignored.
+
+void* sc_cor_pthread::invoke_module_method(void* context_p)
+{
+ sc_cor_pthread* p = (sc_cor_pthread*)context_p;
+ DEBUGF << p << ": sc_cor_pthread::invoke_module_method()" << std::endl;
+
+
+ // SUSPEND THE THREAD SO WE CAN GAIN CONTROL FROM THE PTHREAD PACKAGE:
+ //
+ // Since pthread_create schedules each thread behind our back for its
+ // initial execution we immediately suspend a newly created thread
+ // here so we can control when its execution will occur. We also wake
+ // up the main thread which is waiting for this thread to execute to this
+ // wait point.
+
+ pthread_mutex_lock( &create_mutex );
+ DEBUGF << p << ": child signalling main thread " << endl;
+ pthread_cond_signal( &create_condition );
+ pthread_mutex_lock( &p->m_mutex );
+ pthread_mutex_unlock( &create_mutex );
+ pthread_cond_wait( &p->m_pt_condition, &p->m_mutex );
+ pthread_mutex_unlock( &p->m_mutex );
+
+
+ // CALL THE SYSTEMC CODE THAT WILL ACTUALLY START THE THREAD OFF:
+
+ active_cor_p = p;
+ DEBUGF << p << ": about to invoke real method "
+ << active_cor_p << std::endl;
+ (p->m_cor_fn)(p->m_cor_fn_arg);
+
+ return 0;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_cor_pkg_pthread
+//
+// Coroutine package class implemented with Posix Threads.
+// ----------------------------------------------------------------------------
+
+int sc_cor_pkg_pthread::instance_count = 0;
+
+
+// constructor
+
+sc_cor_pkg_pthread::sc_cor_pkg_pthread( sc_simcontext* simc )
+: sc_cor_pkg( simc )
+{
+ // initialize the current coroutine
+ if( ++ instance_count == 1 )
+ {
+ pthread_cond_init( &create_condition, PTHREAD_NULL );
+ pthread_mutex_init( &create_mutex, PTHREAD_NULL );
+ assert( active_cor_p == 0 );
+ main_cor.m_pkg_p = this;
+ DEBUGF << &main_cor << ": is main co-routine" << std::endl;
+ active_cor_p = &main_cor;
+ }
+}
+
+
+// destructor
+
+sc_cor_pkg_pthread::~sc_cor_pkg_pthread()
+{
+ if( -- instance_count == 0 ) {
+ // cleanup the main coroutine
+ }
+}
+
+
+// create a new coroutine
+
+sc_cor*
+sc_cor_pkg_pthread::create( std::size_t stack_size, sc_cor_fn* fn, void* arg )
+{
+ sc_cor_pthread* cor_p = new sc_cor_pthread;
+ DEBUGF << &main_cor << ": sc_cor_pkg_pthread::create("
+ << cor_p << ")" << std::endl;
+
+
+ // INITIALIZE OBJECT'S FIELDS FROM ARGUMENT LIST:
+
+ cor_p->m_pkg_p = this;
+ cor_p->m_cor_fn = fn;
+ cor_p->m_cor_fn_arg = arg;
+
+
+ // SET UP THREAD CREATION ATTRIBUTES:
+ //
+ // Use default values except for stack size. If stack size is non-zero
+ // set it.
+
+ pthread_attr_t attr;
+ pthread_attr_init( &attr );
+ if ( stack_size != 0 )
+ {
+ pthread_attr_setstacksize( &attr, stack_size );
+ }
+
+
+ // ALLOCATE THE POSIX THREAD TO USE AND FORCE SEQUENTIAL EXECUTION:
+ //
+ // Because pthread_create causes the created thread to be executed,
+ // we need to let it run until we can block in the invoke_module_method.
+ // So we:
+ // (1) Lock the creation mutex before creating the new thread.
+ // (2) Sleep on the creation condition, which will be signalled by
+ // the newly created thread just before it goes to sleep in
+ // invoke_module_method.
+ // This scheme results in the newly created thread being dormant before
+ // the main thread continues execution.
+
+ pthread_mutex_lock( &create_mutex );
+ DEBUGF << &main_cor << ": about to create actual thread "
+ << cor_p << std::endl;
+ if ( pthread_create( &cor_p->m_thread, &attr,
+ &sc_cor_pthread::invoke_module_method, (void*)cor_p ) )
+ {
+ std::fprintf(stderr, "ERROR - could not create thread\n");
+ }
+
+ DEBUGF << &main_cor << ": main thread waiting for signal from "
+ << cor_p << std::endl;
+ pthread_cond_wait( &create_condition, &create_mutex );
+ DEBUGF << &main_cor << ": main thread signaled by "
+ << cor_p << endl;
+ pthread_attr_destroy( &attr );
+ pthread_mutex_unlock( &create_mutex );
+ DEBUGF << &main_cor << ": exiting sc_cor_pkg_pthread::create("
+ << cor_p << ")" << std::endl;
+
+ return cor_p;
+}
+
+
+// yield to the next coroutine
+//
+// We don't do anything after the p_thread_cond_wait since it won't
+// happen until the thread wakes up again!
+
+void
+sc_cor_pkg_pthread::yield( sc_cor* next_cor_p )
+{
+ sc_cor_pthread* from_p = active_cor_p;
+ sc_cor_pthread* to_p = (sc_cor_pthread*)next_cor_p;
+
+ DEBUGF << from_p << ": switch to " << to_p << std::endl;
+ if ( to_p != from_p )
+ {
+ pthread_mutex_lock( &to_p->m_mutex );
+ pthread_cond_signal( &to_p->m_pt_condition );
+ pthread_mutex_lock( &from_p->m_mutex );
+ pthread_mutex_unlock( &to_p->m_mutex );
+ pthread_cond_wait( &from_p->m_pt_condition, &from_p->m_mutex );
+ pthread_mutex_unlock( &from_p->m_mutex );
+ }
+
+ active_cor_p = from_p; // When we come out of wait make ourselves active.
+ DEBUGF << from_p << " restarting after yield to " << to_p << std::endl;
+}
+
+
+// abort the current coroutine (and resume the next coroutine)
+
+void
+sc_cor_pkg_pthread::abort( sc_cor* next_cor_p )
+{
+ sc_cor_pthread* n_p = (sc_cor_pthread*)next_cor_p;
+
+ DEBUGF << active_cor_p << ": aborting, switching to " << n_p << std::endl;
+ pthread_mutex_lock( &n_p->m_mutex );
+ pthread_cond_signal( &n_p->m_pt_condition );
+ pthread_mutex_unlock( &n_p->m_mutex );
+}
+
+
+// get the main coroutine
+
+sc_cor*
+sc_cor_pkg_pthread::get_main()
+{
+ return &main_cor;
+}
+
+} // namespace sc_core
+
+#endif // !defined(_WIN32) && !defined(WIN32) && defined(SC_USE_PTHREADS)
+
+
+// $Log: sc_cor_pthread.cpp,v $
+// Revision 1.6 2011/08/30 21:51:04 acg
+// Jerome Cornet: auto processing of pthread configurations.
+//
+// Revision 1.5 2011/08/26 20:46:09 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.2 2008/05/22 17:06:25 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_cor_pthread.h b/ext/systemc/src/sysc/kernel/sc_cor_pthread.h
new file mode 100644
index 000000000..f4d835de3
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_cor_pthread.h
@@ -0,0 +1,157 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_cor_pthread.h -- Coroutine implementation with pthreads.
+
+ Original Author: Andy Goodrich, Forte Design Systems, 2002-11-10
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_COR_PTHREAD_H
+#define SC_COR_PTHREAD_H
+
+
+#if defined(SC_USE_PTHREADS)
+
+#include "sysc/kernel/sc_cor.h"
+#include "sysc/kernel/sc_cmnhdr.h"
+#include <pthread.h>
+
+namespace sc_core {
+
+class sc_cor_pkg_pthread;
+typedef sc_cor_pkg_pthread sc_cor_pkg_t;
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_cor_pthread
+//
+// Coroutine class implemented with Posix Threads.
+//
+// Notes:
+// (1) The thread creation mutex and the creation condition are used to
+// suspend the thread creating another one until the created thread
+// reaches its invoke_module_method. This allows us to get control of
+// thread scheduling away from the pthread package.
+// ----------------------------------------------------------------------------
+
+class sc_cor_pthread : public sc_cor
+{
+ public:
+
+ // constructor
+ sc_cor_pthread();
+
+ // destructor
+ virtual ~sc_cor_pthread();
+
+ // module method invocator (starts thread execution)
+ static void* invoke_module_method( void* context_p );
+
+ public:
+ static sc_cor_pthread* m_active_cor_p; // Active coroutine.
+
+ public:
+ sc_cor_fn* m_cor_fn; // Core function.
+ void* m_cor_fn_arg; // Core function argument.
+ pthread_mutex_t m_mutex; // Mutex to suspend thread on.
+ sc_cor_pkg_pthread* m_pkg_p; // the creating coroutine package
+ pthread_cond_t m_pt_condition; // Condition waiting for.
+ pthread_t m_thread; // Our pthread storage.
+
+private:
+
+ // disabled
+ sc_cor_pthread( const sc_cor_pthread& );
+ sc_cor_pthread& operator = ( const sc_cor_pthread& );
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_cor_pkg_pthread
+//
+// Coroutine package class implemented with Posix Threads.
+// ----------------------------------------------------------------------------
+
+class sc_cor_pkg_pthread
+: public sc_cor_pkg
+{
+public:
+
+ // constructor
+ sc_cor_pkg_pthread( sc_simcontext* simc );
+
+ // destructor
+ virtual ~sc_cor_pkg_pthread();
+
+ // create a new coroutine
+ virtual sc_cor* create( std::size_t stack_size, sc_cor_fn* fn, void* arg );
+
+ // yield to the next coroutine
+ virtual void yield( sc_cor* next_cor );
+
+ // abort the current coroutine (and resume the next coroutine)
+ virtual void abort( sc_cor* next_cor );
+
+ // get the main coroutine
+ virtual sc_cor* get_main();
+
+private:
+
+ static int instance_count;
+
+private:
+
+ // disabled
+ sc_cor_pkg_pthread();
+ sc_cor_pkg_pthread( const sc_cor_pkg_pthread& );
+ sc_cor_pkg_pthread& operator = ( const sc_cor_pkg_pthread& );
+};
+
+} // namespace sc_core
+
+#endif
+
+// $Log: sc_cor_pthread.h,v $
+// Revision 1.5 2011/08/26 20:46:09 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.2 2008/05/22 17:06:25 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
+
+#endif // defined(SC_USE_PTHREADS)
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_cor_qt.cpp b/ext/systemc/src/sysc/kernel/sc_cor_qt.cpp
new file mode 100644
index 000000000..d42298a62
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_cor_qt.cpp
@@ -0,0 +1,271 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_cor_qt.cpp -- Coroutine implementation with QuickThreads.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-12-18
+
+ CHANGE LOG APPEARS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#if !defined(_WIN32) && !defined(WIN32) && !defined(SC_USE_PTHREADS)
+
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+
+#include "sysc/kernel/sc_cor_qt.h"
+#include "sysc/kernel/sc_simcontext.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// File static variables.
+// ----------------------------------------------------------------------------
+
+// main coroutine
+
+static sc_cor_qt main_cor;
+
+// current coroutine
+
+static sc_cor_qt* curr_cor = 0;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_cor_qt
+//
+// Coroutine class implemented with QuickThreads.
+// ----------------------------------------------------------------------------
+
+// switch stack protection on/off
+
+void
+sc_cor_qt::stack_protect( bool enable )
+{
+ // Code needs to be tested on HP-UX and disabled if it doesn't work there
+ // Code still needs to be ported to WIN32
+
+ static std::size_t pagesize;
+
+ if( pagesize == 0 ) {
+# if defined(__ppc__)
+ pagesize = getpagesize();
+# else
+ pagesize = sysconf( _SC_PAGESIZE );
+# endif
+ }
+
+ assert( pagesize != 0 );
+ assert( m_stack_size > ( 2 * pagesize ) );
+
+#ifdef QUICKTHREADS_GROW_DOWN
+ // Stacks grow from high address down to low address
+ caddr_t redzone = caddr_t( ( ( std::size_t( m_stack ) + pagesize - 1 ) /
+ pagesize ) * pagesize );
+#else
+ // Stacks grow from low address up to high address
+ caddr_t redzone = caddr_t( ( ( std::size_t( m_stack ) +
+ m_stack_size - pagesize ) /
+ pagesize ) * pagesize );
+#endif
+
+ int ret;
+
+ // Enable the red zone at the end of the stack so that references within
+ // it will cause an interrupt.
+
+ if( enable ) {
+ ret = mprotect( redzone, pagesize - 1, PROT_NONE );
+ }
+
+ // Revert the red zone to normal memory usage. Try to make it read - write -
+ // execute. If that does not work then settle for read - write
+
+ else {
+ ret = mprotect( redzone, pagesize - 1, PROT_READ|PROT_WRITE|PROT_EXEC);
+ if ( ret != 0 )
+ ret = mprotect( redzone, pagesize - 1, PROT_READ | PROT_WRITE );
+ }
+
+ assert( ret == 0 );
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_cor_pkg_qt
+//
+// Coroutine package class implemented with QuickThreads.
+// ----------------------------------------------------------------------------
+
+int sc_cor_pkg_qt::instance_count = 0;
+
+
+// support function
+
+inline
+void*
+stack_align( void* sp, int alignment, std::size_t* stack_size )
+{
+ int round_up_mask = alignment - 1;
+ *stack_size = (*stack_size + round_up_mask) & ~round_up_mask;
+ return ( (void*)(((qt_word_t) sp + round_up_mask) & ~round_up_mask) );
+}
+
+
+// constructor
+
+sc_cor_pkg_qt::sc_cor_pkg_qt( sc_simcontext* simc )
+: sc_cor_pkg( simc )
+{
+ if( ++ instance_count == 1 ) {
+ // initialize the current coroutine
+ assert( curr_cor == 0 );
+ curr_cor = &main_cor;
+ }
+}
+
+
+// destructor
+
+sc_cor_pkg_qt::~sc_cor_pkg_qt()
+{
+ if( -- instance_count == 0 ) {
+ // cleanup the current coroutine
+ curr_cor = 0;
+ }
+}
+
+
+// create a new coroutine
+
+extern "C"
+void
+sc_cor_qt_wrapper( void* arg, void* cor, qt_userf_t* fn )
+{
+ curr_cor = RCAST<sc_cor_qt*>( cor );
+ // invoke the user function
+ (*(sc_cor_fn*) fn)( arg );
+ // not reached
+}
+
+sc_cor*
+sc_cor_pkg_qt::create( std::size_t stack_size, sc_cor_fn* fn, void* arg )
+{
+ sc_cor_qt* cor = new sc_cor_qt();
+ cor->m_pkg = this;
+ cor->m_stack_size = stack_size;
+ cor->m_stack = new char[cor->m_stack_size];
+ void* sto = stack_align( cor->m_stack, QUICKTHREADS_STKALIGN,
+ &cor->m_stack_size );
+ cor->m_sp = QUICKTHREADS_SP(sto, cor->m_stack_size - QUICKTHREADS_STKALIGN);
+ cor->m_sp = QUICKTHREADS_ARGS( cor->m_sp, arg, cor, (qt_userf_t*) fn,
+ sc_cor_qt_wrapper );
+ return cor;
+}
+
+
+// yield to the next coroutine
+
+extern "C"
+void*
+sc_cor_qt_yieldhelp( qt_t* sp, void* old_cor, void* )
+{
+ RCAST<sc_cor_qt*>( old_cor )->m_sp = sp;
+ return 0;
+}
+
+void
+sc_cor_pkg_qt::yield( sc_cor* next_cor )
+{
+ sc_cor_qt* new_cor = SCAST<sc_cor_qt*>( next_cor );
+ sc_cor_qt* old_cor = curr_cor;
+ curr_cor = new_cor;
+ QUICKTHREADS_BLOCK( sc_cor_qt_yieldhelp, old_cor, 0, new_cor->m_sp );
+}
+
+
+// abort the current coroutine (and resume the next coroutine)
+
+extern "C"
+void*
+sc_cor_qt_aborthelp( qt_t*, void*, void* )
+{
+ return 0;
+}
+
+void
+sc_cor_pkg_qt::abort( sc_cor* next_cor )
+{
+ sc_cor_qt* new_cor = SCAST<sc_cor_qt*>( next_cor );
+ sc_cor_qt* old_cor = curr_cor;
+ curr_cor = new_cor;
+ QUICKTHREADS_ABORT( sc_cor_qt_aborthelp, old_cor, 0, new_cor->m_sp );
+}
+
+
+// get the main coroutine
+
+sc_cor*
+sc_cor_pkg_qt::get_main()
+{
+ return &main_cor;
+}
+
+} // namespace sc_core
+
+#endif
+
+// $Log: sc_cor_qt.cpp,v $
+// Revision 1.9 2011/08/29 18:04:32 acg
+// Philipp A. Hartmann: miscellaneous clean ups.
+//
+// Revision 1.8 2011/08/26 20:46:09 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.7 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.6 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.5 2010/08/03 16:52:14 acg
+// Andy Goodrich: line formatting.
+//
+// Revision 1.4 2008/11/11 14:03:07 acg
+// Andy Goodrich: added execute access to the release of red zone storage
+// per Ulli's suggestion.
+//
+// Revision 1.3 2008/05/22 17:06:25 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.2 2008/03/24 18:32:36 acg
+// Andy Goodrich: added include of sys/types.h to pick up the declaration
+// of caddr_t.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_cor_qt.h b/ext/systemc/src/sysc/kernel/sc_cor_qt.h
new file mode 100644
index 000000000..644d39c3f
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_cor_qt.h
@@ -0,0 +1,154 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_cor_qt.h -- Coroutine implementation with QuickThreads.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-12-18
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_COR_QT_H
+#define SC_COR_QT_H
+
+
+#if !defined(_WIN32) && !defined(WIN32) && !defined(WIN64) && !defined(SC_USE_PTHREADS)
+
+#include "sysc/kernel/sc_cor.h"
+#include "sysc/qt/qt.h"
+
+namespace sc_core {
+
+class sc_cor_pkg_qt;
+typedef sc_cor_pkg_qt sc_cor_pkg_t;
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_cor_qt
+//
+// Coroutine class implemented with QuickThreads.
+// ----------------------------------------------------------------------------
+
+class sc_cor_qt
+: public sc_cor
+{
+public:
+
+ // constructor
+ sc_cor_qt()
+ : m_stack_size( 0 ), m_stack( 0 ), m_sp( 0 ), m_pkg( 0 )
+ {}
+
+ // destructor
+ virtual ~sc_cor_qt()
+ { delete[] (char*) m_stack; }
+
+ // switch stack protection on/off
+ virtual void stack_protect( bool enable );
+
+public:
+
+ std::size_t m_stack_size; // stack size
+ void* m_stack; // stack
+ qt_t* m_sp; // stack pointer
+
+ sc_cor_pkg_qt* m_pkg; // the creating coroutine package
+
+private:
+
+ // disabled
+ sc_cor_qt( const sc_cor_qt& );
+ sc_cor_qt& operator = ( const sc_cor_qt& );
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_cor_pkg_qt
+//
+// Coroutine package class implemented with QuickThreads.
+// ----------------------------------------------------------------------------
+
+class sc_cor_pkg_qt
+: public sc_cor_pkg
+{
+public:
+
+ // constructor
+ sc_cor_pkg_qt( sc_simcontext* simc );
+
+ // destructor
+ virtual ~sc_cor_pkg_qt();
+
+ // create a new coroutine
+ virtual sc_cor* create( std::size_t stack_size, sc_cor_fn* fn, void* arg );
+
+ // yield to the next coroutine
+ virtual void yield( sc_cor* next_cor );
+
+ // abort the current coroutine (and resume the next coroutine)
+ virtual void abort( sc_cor* next_cor );
+
+ // get the main coroutine
+ virtual sc_cor* get_main();
+
+private:
+
+ static int instance_count;
+
+private:
+
+ // disabled
+ sc_cor_pkg_qt();
+ sc_cor_pkg_qt( const sc_cor_pkg_qt& );
+ sc_cor_pkg_qt& operator = ( const sc_cor_pkg_qt& );
+};
+
+} // namespace sc_core
+
+#endif
+
+// $Log: sc_cor_qt.h,v $
+// Revision 1.6 2011/08/29 18:04:32 acg
+// Philipp A. Hartmann: miscellaneous clean ups.
+//
+// Revision 1.5 2011/08/26 20:46:09 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.2 2008/05/22 17:06:25 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_cthread_process.cpp b/ext/systemc/src/sysc/kernel/sc_cthread_process.cpp
new file mode 100644
index 000000000..fef5cc8d8
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_cthread_process.cpp
@@ -0,0 +1,123 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_cthread_process.cpp -- Clocked thread implementation.
+
+ Original Author: Andy Goodrich, Forte Design Systems, 4 August 2005
+
+
+ CHANGE LOG APPEARS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include "sysc/kernel/sc_cthread_process.h"
+#include "sysc/kernel/sc_simcontext_int.h"
+
+namespace sc_core {
+
+//------------------------------------------------------------------------------
+//"sc_cthread_process::dont_initialize"
+//
+// This virtual method sets the initialization switch for this object instance.
+//------------------------------------------------------------------------------
+void sc_cthread_process::dont_initialize( bool /* dont */ )
+{
+ SC_REPORT_WARNING( SC_ID_DONT_INITIALIZE_, 0 );
+}
+
+//------------------------------------------------------------------------------
+//"sc_cthread_process::sc_cthread_process"
+//
+// This is the object instance constructor for this class.
+//------------------------------------------------------------------------------
+sc_cthread_process::sc_cthread_process( const char* name_p,
+ bool free_host, SC_ENTRY_FUNC method_p,
+ sc_process_host* host_p, const sc_spawn_options* opt_p
+):
+ sc_thread_process(name_p, free_host, method_p, host_p, opt_p)
+{
+ m_dont_init = true;
+ m_process_kind = SC_CTHREAD_PROC_;
+}
+
+//------------------------------------------------------------------------------
+//"sc_cthread_process::~sc_cthread_process"
+//
+// This is the object instance constructor for this class.
+//------------------------------------------------------------------------------
+sc_cthread_process::~sc_cthread_process()
+{
+}
+
+} // namespace sc_core
+
+// $Log: sc_cthread_process.cpp,v $
+// Revision 1.11 2011/08/26 20:46:09 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.10 2011/08/15 16:43:24 acg
+// Torsten Maehne: changes to remove unused argument warnings.
+//
+// Revision 1.9 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.8 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.7 2011/02/11 13:25:24 acg
+// Andy Goodrich: Philipp A. Hartmann's changes:
+// (1) Removal of SC_CTHREAD method overloads.
+// (2) New exception processing code.
+//
+// Revision 1.6 2011/02/01 21:00:35 acg
+// Andy Goodrich: removed throw_reset as it is now handled by parent
+// sc_thread_process::throw_reset().
+//
+// Revision 1.5 2011/01/18 20:10:44 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.4 2009/07/28 01:10:53 acg
+// Andy Goodrich: updates for 2.3 release candidate.
+//
+// Revision 1.3 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.2 2008/05/22 17:06:25 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.6 2006/04/20 17:08:16 acg
+// Andy Goodrich: 3.0 style process changes.
+//
+// Revision 1.5 2006/04/11 23:13:20 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.4 2006/01/24 20:49:04 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
diff --git a/ext/systemc/src/sysc/kernel/sc_cthread_process.h b/ext/systemc/src/sysc/kernel/sc_cthread_process.h
new file mode 100644
index 000000000..6d35ece0d
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_cthread_process.h
@@ -0,0 +1,144 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_cthread_process.h -- Clocked thread declarations
+
+ Original Author: Andy Goodrich, Forte Design Systems, 4 August 2005
+
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#if !defined(sc_cthread_process_h_INCLUDED)
+#define sc_cthread_process_h_INCLUDED
+
+#include "sysc/kernel/sc_thread_process.h"
+
+namespace sc_core {
+
+// friend function declarations:
+
+void halt( sc_simcontext* );
+void wait( int, sc_simcontext* );
+
+
+//==============================================================================
+// sc_cthread_process -
+//
+//==============================================================================
+class sc_cthread_process : public sc_thread_process {
+
+ friend class sc_module;
+ friend class sc_process_handle;
+ friend class sc_process_table;
+ friend class sc_thread_process;
+ friend class sc_simcontext;
+
+ friend void sc_cthread_cor_fn( void* );
+
+ friend void halt( sc_simcontext* );
+ friend void wait( int, sc_simcontext* );
+
+ public:
+ sc_cthread_process( const char* name_p, bool free_host,
+ SC_ENTRY_FUNC method_p, sc_process_host* host_p,
+ const sc_spawn_options* opt_p );
+
+ virtual void dont_initialize( bool dont );
+ virtual const char* kind() const
+ { return "sc_cthread_process"; }
+
+private:
+
+ sc_cthread_process( const char* nm,
+ SC_ENTRY_FUNC fn,
+ sc_process_host* host );
+
+ // may not be deleted manually (called from sc_process_b)
+ virtual ~sc_cthread_process();
+
+ bool eval_watchlist();
+ bool eval_watchlist_curr_level();
+
+ void wait_halt();
+
+};
+
+//------------------------------------------------------------------------------
+//"sc_cthread_process::wait_halt"
+//
+//------------------------------------------------------------------------------
+inline void sc_cthread_process::wait_halt()
+{
+ m_wait_cycle_n = 0;
+ suspend_me();
+ throw sc_halt();
+}
+
+} // namespace sc_core
+
+// $Log: sc_cthread_process.h,v $
+// Revision 1.8 2011/08/26 20:46:09 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.7 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.6 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.5 2011/02/11 13:25:24 acg
+// Andy Goodrich: Philipp A. Hartmann's changes:
+// (1) Removal of SC_CTHREAD method overloads.
+// (2) New exception processing code.
+//
+// Revision 1.4 2011/02/01 21:01:41 acg
+// Andy Goodrich: removed throw_reset() as it is now handled by the parent
+// method sc_thread_process::throw_reset().
+//
+// Revision 1.3 2011/01/18 20:10:44 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.2 2008/05/22 17:06:25 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.6 2006/05/08 17:57:13 acg
+// Andy Goodrich: Added David Long's forward declarations for friend functions
+// to keep the Microsoft C++ compiler happy.
+//
+// Revision 1.5 2006/04/20 17:08:16 acg
+// Andy Goodrich: 3.0 style process changes.
+//
+// Revision 1.4 2006/04/11 23:13:20 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
+
+#endif // !defined(sc_cthread_process_h_INCLUDED)
diff --git a/ext/systemc/src/sysc/kernel/sc_dynamic_processes.h b/ext/systemc/src/sysc/kernel/sc_dynamic_processes.h
new file mode 100644
index 000000000..628c3300a
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_dynamic_processes.h
@@ -0,0 +1,67 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_dynamic_process.h -- Dynamic Process Package Definitions
+
+ Original Author: Andy Goodrich, Forte Design Systems, 5 May 2003
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_DYNAMIC_PROCESSES_H
+#define SC_DYNAMIC_PROCESSES_H
+
+#include "sysc/kernel/sc_except.h"
+#include "sysc/kernel/sc_spawn.h"
+#include "sysc/kernel/sc_join.h"
+#include "sysc/kernel/sc_boost.h"
+
+// $Log: sc_dynamic_processes.h,v $
+// Revision 1.5 2011/08/26 20:46:09 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.2 2008/05/22 17:06:25 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.5 2006/04/20 17:08:16 acg
+// Andy Goodrich: 3.0 style process changes.
+//
+// Revision 1.4 2006/04/11 23:13:20 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
+
+#endif // SC_DYNAMIC_PROCESSES_H
diff --git a/ext/systemc/src/sysc/kernel/sc_event.cpp b/ext/systemc/src/sysc/kernel/sc_event.cpp
new file mode 100644
index 000000000..488210ee9
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_event.cpp
@@ -0,0 +1,759 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_event.cpp --
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG APPEARS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "sysc/kernel/sc_event.h"
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/kernel/sc_phase_callback_registry.h"
+#include "sysc/kernel/sc_process.h"
+#include "sysc/kernel/sc_process_handle.h"
+#include "sysc/kernel/sc_simcontext_int.h"
+#include "sysc/kernel/sc_object_manager.h"
+#include "sysc/utils/sc_utils_ids.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_event
+//
+// The event class.
+// ----------------------------------------------------------------------------
+
+const char*
+sc_event::basename() const
+{
+ const char* p = strrchr( m_name.c_str(), SC_HIERARCHY_CHAR );
+ return p ? (p + 1) : m_name.c_str();
+}
+
+void
+sc_event::cancel()
+{
+ // cancel a delta or timed notification
+ switch( m_notify_type ) {
+ case DELTA: {
+ // remove this event from the delta events set
+ m_simc->remove_delta_event( this );
+ m_notify_type = NONE;
+ break;
+ }
+ case TIMED: {
+ // remove this event from the timed events set
+ sc_assert( m_timed != 0 );
+ m_timed->m_event = 0;
+ m_timed = 0;
+ m_notify_type = NONE;
+ break;
+ }
+ default:
+ ;
+ }
+}
+
+
+void
+sc_event::notify()
+{
+ // immediate notification
+ if(
+ // coming from sc_prim_channel::update
+ m_simc->update_phase()
+#if SC_HAS_PHASE_CALLBACKS_
+ // coming from phase callbacks
+ || m_simc->notify_phase()
+#endif
+ )
+ {
+ SC_REPORT_ERROR( SC_ID_IMMEDIATE_NOTIFICATION_, "" );
+ return;
+ }
+ cancel();
+ trigger();
+}
+
+void
+sc_event::notify( const sc_time& t )
+{
+ if( m_notify_type == DELTA ) {
+ return;
+ }
+ if( t == SC_ZERO_TIME ) {
+# if SC_HAS_PHASE_CALLBACKS_
+ if( SC_UNLIKELY_( m_simc->get_status()
+ & (SC_END_OF_UPDATE|SC_BEFORE_TIMESTEP) ) )
+ {
+ std::stringstream msg;
+ msg << m_simc->get_status()
+ << ":\n\t delta notification of `"
+ << name() << "' ignored";
+ SC_REPORT_WARNING( SC_ID_PHASE_CALLBACK_FORBIDDEN_
+ , msg.str().c_str() );
+ return;
+ }
+# endif
+ if( m_notify_type == TIMED ) {
+ // remove this event from the timed events set
+ sc_assert( m_timed != 0 );
+ m_timed->m_event = 0;
+ m_timed = 0;
+ }
+ // add this event to the delta events set
+ m_delta_event_index = m_simc->add_delta_event( this );
+ m_notify_type = DELTA;
+ return;
+ }
+# if SC_HAS_PHASE_CALLBACKS_
+ if( SC_UNLIKELY_( m_simc->get_status()
+ & (SC_END_OF_UPDATE|SC_BEFORE_TIMESTEP) ) )
+ {
+ std::stringstream msg;
+ msg << m_simc->get_status()
+ << ":\n\t timed notification of `"
+ << name() << "' ignored";
+ SC_REPORT_WARNING( SC_ID_PHASE_CALLBACK_FORBIDDEN_
+ , msg.str().c_str() );
+ return;
+ }
+# endif
+ if( m_notify_type == TIMED ) {
+ sc_assert( m_timed != 0 );
+ if( m_timed->m_notify_time <= m_simc->time_stamp() + t ) {
+ return;
+ }
+ // remove this event from the timed events set
+ m_timed->m_event = 0;
+ m_timed = 0;
+ }
+ // add this event to the timed events set
+ sc_event_timed* et = new sc_event_timed( this, m_simc->time_stamp() + t );
+ m_simc->add_timed_event( et );
+ m_timed = et;
+ m_notify_type = TIMED;
+}
+
+static void sc_warn_notify_delayed()
+{
+ static bool warn_notify_delayed=true;
+ if ( warn_notify_delayed )
+ {
+ warn_notify_delayed = false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "notify_delayed(...) is deprecated, use notify(sc_time) instead" );
+ }
+}
+
+void
+sc_event::notify_delayed()
+{
+ sc_warn_notify_delayed();
+ if( m_notify_type != NONE ) {
+ SC_REPORT_ERROR( SC_ID_NOTIFY_DELAYED_, 0 );
+ }
+ // add this event to the delta events set
+ m_delta_event_index = m_simc->add_delta_event( this );
+ m_notify_type = DELTA;
+}
+
+void
+sc_event::notify_delayed( const sc_time& t )
+{
+ sc_warn_notify_delayed();
+ if( m_notify_type != NONE ) {
+ SC_REPORT_ERROR( SC_ID_NOTIFY_DELAYED_, 0 );
+ }
+ if( t == SC_ZERO_TIME ) {
+ // add this event to the delta events set
+ m_delta_event_index = m_simc->add_delta_event( this );
+ m_notify_type = DELTA;
+ } else {
+ // add this event to the timed events set
+ sc_event_timed* et = new sc_event_timed( this,
+ m_simc->time_stamp() + t );
+ m_simc->add_timed_event( et );
+ m_timed = et;
+ m_notify_type = TIMED;
+ }
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_event::register_event"
+// |
+// | This method sets the name of this object instance and optionally adds
+// | it to the object manager's hierarchy. The object instance will be
+// | inserted into the object manager's hierarchy if one of the following is
+// | true:
+// | (a) the leaf name is non-null and does not start with
+// | SC_KERNEL_EVENT_PREFIX.
+// | (b) the event is being created before the start of simulation.
+// |
+// | Arguments:
+// | leaf_name = leaf name of the object or NULL.
+// +----------------------------------------------------------------------------
+void sc_event::register_event( const char* leaf_name )
+{
+ sc_object_manager* object_manager = m_simc->get_object_manager();
+ m_parent_p = m_simc->active_object();
+
+ // No name provided, if we are not executing then create a name:
+
+ if( !leaf_name || !leaf_name[0] )
+ {
+ if ( sc_is_running( m_simc ) ) return;
+ leaf_name = sc_gen_unique_name("event");
+ }
+
+ // Create a hierarchichal name and place it into the object manager if
+ // its not a kernel event:
+
+ object_manager->create_name( leaf_name ).swap( m_name );
+
+ if ( strncmp( leaf_name, SC_KERNEL_EVENT_PREFIX,
+ strlen(SC_KERNEL_EVENT_PREFIX) ) )
+ {
+ object_manager->insert_event(m_name, this);
+ if ( m_parent_p )
+ m_parent_p->add_child_event( this );
+ else
+ m_simc->add_child_event( this );
+ }
+}
+
+void
+sc_event::reset()
+{
+ m_notify_type = NONE;
+ m_delta_event_index = -1;
+ m_timed = 0;
+ // clear the dynamic sensitive methods
+ m_methods_dynamic.resize(0);
+ // clear the dynamic sensitive threads
+ m_threads_dynamic.resize(0);
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_event::sc_event(name)"
+// |
+// | This is the object instance constructor for named sc_event instances.
+// | If the name is non-null or the this is during elaboration add the
+// | event to the object hierarchy.
+// |
+// | Arguments:
+// | name = name of the event.
+// +----------------------------------------------------------------------------
+sc_event::sc_event( const char* name ) :
+ m_name(),
+ m_parent_p(NULL),
+ m_simc( sc_get_curr_simcontext() ),
+ m_notify_type( NONE ),
+ m_delta_event_index( -1 ),
+ m_timed( 0 ),
+ m_methods_static(),
+ m_methods_dynamic(),
+ m_threads_static(),
+ m_threads_dynamic()
+{
+ // Skip simulator's internally defined events.
+
+ register_event( name );
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_event::sc_event(name)"
+// |
+// | This is the object instance constructor for non-named sc_event instances.
+// | If this is during elaboration add create a name and add it to the object
+// | hierarchy.
+// +----------------------------------------------------------------------------
+sc_event::sc_event() :
+ m_name(),
+ m_parent_p(NULL),
+ m_simc( sc_get_curr_simcontext() ),
+ m_notify_type( NONE ),
+ m_delta_event_index( -1 ),
+ m_timed( 0 ),
+ m_methods_static(),
+ m_methods_dynamic(),
+ m_threads_static(),
+ m_threads_dynamic()
+{
+
+ register_event( NULL );
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_event::~sc_event"
+// |
+// | This is the object instance destructor for this class. It cancels any
+// | outstanding waits and removes the event from the object manager's
+// | instance table if it has a name.
+// +----------------------------------------------------------------------------
+sc_event::~sc_event()
+{
+ cancel();
+ if ( m_name.length() != 0 )
+ {
+ sc_object_manager* object_manager_p = m_simc->get_object_manager();
+ object_manager_p->remove_event( m_name );
+ }
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_event::trigger"
+// |
+// | This method "triggers" this object instance. This consists of scheduling
+// | for execution all the processes that are schedulable and waiting on this
+// | event.
+// +----------------------------------------------------------------------------
+void
+sc_event::trigger()
+{
+ int last_i; // index of last element in vector now accessing.
+ int size; // size of vector now accessing.
+
+
+ // trigger the static sensitive methods
+
+ if( ( size = m_methods_static.size() ) != 0 )
+ {
+ sc_method_handle* l_methods_static = &m_methods_static[0];
+ int i = size - 1;
+ do {
+ sc_method_handle method_h = l_methods_static[i];
+ method_h->trigger_static();
+ } while( -- i >= 0 );
+ }
+
+ // trigger the dynamic sensitive methods
+
+
+ if( ( size = m_methods_dynamic.size() ) != 0 )
+ {
+ last_i = size - 1;
+ sc_method_handle* l_methods_dynamic = &m_methods_dynamic[0];
+ for ( int i = 0; i <= last_i; i++ )
+ {
+ sc_method_handle method_h = l_methods_dynamic[i];
+ if ( method_h->trigger_dynamic( this ) )
+ {
+ l_methods_dynamic[i] = l_methods_dynamic[last_i];
+ last_i--;
+ i--;
+ }
+ }
+ m_methods_dynamic.resize(last_i+1);
+ }
+
+
+ // trigger the static sensitive threads
+
+ if( ( size = m_threads_static.size() ) != 0 )
+ {
+ sc_thread_handle* l_threads_static = &m_threads_static[0];
+ int i = size - 1;
+ do {
+ sc_thread_handle thread_h = l_threads_static[i];
+ thread_h->trigger_static();
+ } while( -- i >= 0 );
+ }
+
+ // trigger the dynamic sensitive threads
+
+ if( ( size = m_threads_dynamic.size() ) != 0 )
+ {
+ last_i = size - 1;
+ sc_thread_handle* l_threads_dynamic = &m_threads_dynamic[0];
+ for ( int i = 0; i <= last_i; i++ )
+ {
+ sc_thread_handle thread_h = l_threads_dynamic[i];
+ if ( thread_h->trigger_dynamic( this ) )
+ {
+ l_threads_dynamic[i] = l_threads_dynamic[last_i];
+ i--;
+ last_i--;
+ }
+ }
+ m_threads_dynamic.resize(last_i+1);
+ }
+
+ m_notify_type = NONE;
+ m_delta_event_index = -1;
+ m_timed = 0;
+}
+
+
+bool
+sc_event::remove_static( sc_method_handle method_h_ ) const
+{
+ int size;
+ if ( ( size = m_methods_static.size() ) != 0 ) {
+ sc_method_handle* l_methods_static = &m_methods_static[0];
+ for( int i = size - 1; i >= 0; -- i ) {
+ if( l_methods_static[i] == method_h_ ) {
+ l_methods_static[i] = l_methods_static[size - 1];
+ m_methods_static.resize(size-1);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool
+sc_event::remove_static( sc_thread_handle thread_h_ ) const
+{
+ int size;
+ if ( ( size = m_threads_static.size() ) != 0 ) {
+ sc_thread_handle* l_threads_static = &m_threads_static[0];
+ for( int i = size - 1; i >= 0; -- i ) {
+ if( l_threads_static[i] == thread_h_ ) {
+ l_threads_static[i] = l_threads_static[size - 1];
+ m_threads_static.resize(size-1);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool
+sc_event::remove_dynamic( sc_method_handle method_h_ ) const
+{
+ int size;
+ if ( ( size = m_methods_dynamic.size() ) != 0 ) {
+ sc_method_handle* l_methods_dynamic = &m_methods_dynamic[0];
+ for( int i = size - 1; i >= 0; -- i ) {
+ if( l_methods_dynamic[i] == method_h_ ) {
+ l_methods_dynamic[i] = l_methods_dynamic[size - 1];
+ m_methods_dynamic.resize(size-1);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool
+sc_event::remove_dynamic( sc_thread_handle thread_h_ ) const
+{
+ int size;
+ if ( ( size= m_threads_dynamic.size() ) != 0 ) {
+ sc_thread_handle* l_threads_dynamic = &m_threads_dynamic[0];
+ for( int i = size - 1; i >= 0; -- i ) {
+ if( l_threads_dynamic[i] == thread_h_ ) {
+ l_threads_dynamic[i] = l_threads_dynamic[size - 1];
+ m_threads_dynamic.resize(size-1);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_event_timed
+//
+// Class for storing the time to notify a timed event.
+// ----------------------------------------------------------------------------
+
+// dedicated memory management; not MT-Safe
+
+union sc_event_timed_u
+{
+ sc_event_timed_u* next;
+ char dummy[sizeof( sc_event_timed )];
+};
+
+static
+sc_event_timed_u* free_list = 0;
+
+void*
+sc_event_timed::allocate()
+{
+ const int ALLOC_SIZE = 64;
+
+ if( free_list == 0 ) {
+ free_list = (sc_event_timed_u*) malloc( ALLOC_SIZE *
+ sizeof( sc_event_timed ) );
+ int i = 0;
+ for( ; i < ALLOC_SIZE - 1; ++ i ) {
+ free_list[i].next = &free_list[i + 1];
+ }
+ free_list[i].next = 0;
+ }
+
+ sc_event_timed_u* q = free_list;
+ free_list = free_list->next;
+ return q;
+}
+
+void
+sc_event_timed::deallocate( void* p )
+{
+ if( p != 0 ) {
+ sc_event_timed_u* q = RCAST<sc_event_timed_u*>( p );
+ q->next = free_list;
+ free_list = q;
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_event_list
+//
+// Base class for lists of events.
+// ----------------------------------------------------------------------------
+
+void
+sc_event_list::push_back( const sc_event& e )
+{
+ // make sure e is not already in the list
+ if ( m_events.size() != 0 ) {
+ const sc_event** l_events = &m_events[0];
+ for( int i = m_events.size() - 1; i >= 0; -- i ) {
+ if( &e == l_events[i] ) {
+ // event already in the list; ignore
+ return;
+ }
+ }
+ }
+ m_events.push_back( &e );
+}
+
+void
+sc_event_list::push_back( const sc_event_list& el )
+{
+ m_events.reserve( size() + el.size() );
+ for ( int i = el.m_events.size() - 1; i >= 0; --i )
+ {
+ push_back( *el.m_events[i] );
+ }
+ el.auto_delete();
+}
+
+void
+sc_event_list::add_dynamic( sc_method_handle method_h ) const
+{
+ m_busy++;
+ if ( m_events.size() != 0 ) {
+ const sc_event* const * l_events = &m_events[0];
+ for( int i = m_events.size() - 1; i >= 0; -- i ) {
+ l_events[i]->add_dynamic( method_h );
+ }
+ }
+}
+
+void
+sc_event_list::add_dynamic( sc_thread_handle thread_h ) const
+{
+ m_busy++;
+ if ( m_events.size() != 0 ) {
+ const sc_event* const* l_events = &m_events[0];
+ for( int i = m_events.size() - 1; i >= 0; -- i ) {
+ l_events[i]->add_dynamic( thread_h );
+ }
+ }
+}
+
+void
+sc_event_list::remove_dynamic( sc_method_handle method_h,
+ const sc_event* e_not ) const
+{
+ if ( m_events.size() != 0 ) {
+ const sc_event* const* l_events = &m_events[0];
+ for( int i = m_events.size() - 1; i >= 0; -- i ) {
+ const sc_event* e = l_events[i];
+ if( e != e_not ) {
+ e->remove_dynamic( method_h );
+ }
+ }
+ }
+}
+
+void
+sc_event_list::remove_dynamic( sc_thread_handle thread_h,
+ const sc_event* e_not ) const
+{
+ if ( m_events.size() != 0 ) {
+ const sc_event* const* l_events = &m_events[0];
+ for( int i = m_events.size() - 1; i >= 0; -- i ) {
+ const sc_event* e = l_events[i];
+ if( e != e_not ) {
+ e->remove_dynamic( thread_h );
+ }
+ }
+ }
+}
+
+void
+sc_event_list::report_premature_destruction() const
+{
+ // TDB: reliably detect premature destruction
+ //
+ // If an event list is used as a member of a module,
+ // its lifetime may (correctly) end, although there
+ // are processes currently waiting for it.
+ //
+ // Detecting (and ignoring) this corner-case is quite
+ // difficult for similar reasons to the sc_is_running()
+ // return value during the destruction of the module
+ // hierarchy.
+ //
+ // Ignoring the lifetime checks for now, if no process
+ // is currently running (which is only part of the story):
+
+ if( sc_get_current_process_handle().valid() ) {
+ // FIXME: improve error-handling
+ sc_assert( false && "sc_event_list prematurely destroyed" );
+ }
+
+}
+
+void
+sc_event_list::report_invalid_modification() const
+{
+ // FIXME: improve error-handling
+ sc_assert( false && "sc_event_list modfied while being waited on" );
+}
+
+// ----------------------------------------------------------------------------
+// Deprecated functional notation for notifying events.
+// ----------------------------------------------------------------------------
+
+static void sc_warn_notify()
+{
+ static bool warn_notify=true;
+ if ( warn_notify )
+ {
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "the notify() function is deprecated use sc_event::notify()" );
+ warn_notify = false;
+ }
+}
+
+void
+notify( sc_event& e )
+{
+ sc_warn_notify();
+ e.notify();
+}
+
+void
+notify( const sc_time& t, sc_event& e )
+{
+ sc_warn_notify();
+ e.notify( t );
+}
+
+void
+notify( double v, sc_time_unit tu, sc_event& e )
+{
+ sc_warn_notify();
+ e.notify( v, tu );
+}
+
+} // namespace sc_core
+
+// $Log: sc_event.cpp,v $
+// Revision 1.17 2011/08/26 20:46:09 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.16 2011/08/24 22:05:50 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.15 2011/03/12 21:07:51 acg
+// Andy Goodrich: changes to kernel generated event support.
+//
+// Revision 1.14 2011/03/06 15:55:52 acg
+// Andy Goodrich: changes for named events.
+//
+// Revision 1.13 2011/03/05 01:39:21 acg
+// Andy Goodrich: changes for named events.
+//
+// Revision 1.12 2011/02/19 08:33:25 acg
+// Andy Goodrich: remove }'s that should have been removed before.
+//
+// Revision 1.11 2011/02/19 08:30:53 acg
+// Andy Goodrich: Moved process queueing into trigger_static from
+// sc_event::notify.
+//
+// Revision 1.10 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.9 2011/02/17 19:49:51 acg
+// Andy Goodrich:
+// (1) Changed signature of trigger_dynamic() to return a bool again.
+// (2) Moved process run queue processing into trigger_dynamic().
+//
+// Revision 1.8 2011/02/16 22:37:30 acg
+// Andy Goodrich: clean up to remove need for ps_disable_pending.
+//
+// Revision 1.7 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.6 2011/02/01 21:02:28 acg
+// Andy Goodrich: new return code for trigger_dynamic() calls.
+//
+// Revision 1.5 2011/01/18 20:10:44 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.4 2011/01/06 18:04:05 acg
+// Andy Goodrich: added code to leave disabled processes on the dynamic
+// method and thread queues.
+//
+// Revision 1.3 2008/05/22 17:06:25 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.2 2007/01/17 22:44:30 acg
+// Andy Goodrich: fix for Microsoft compiler.
+//
+// Revision 1.7 2006/04/11 23:13:20 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.6 2006/01/25 00:31:19 acg
+// Andy Goodrich: Changed over to use a standard message id of
+// SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
+//
+// Revision 1.5 2006/01/24 20:59:11 acg
+// Andy Goodrich: fix up of CVS comments, new version roll.
+//
+// Revision 1.4 2006/01/24 20:48:14 acg
+// Andy Goodrich: added deprecation warnings for notify_delayed(). Added two
+// new implementation-dependent methods, notify_next_delta() & notify_internal()
+// to replace calls to notify_delayed() from within the simulator. These two
+// new methods are simpler than notify_delayed() and should speed up simulations
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_event.h b/ext/systemc/src/sysc/kernel/sc_event.h
new file mode 100644
index 000000000..9633752ce
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_event.h
@@ -0,0 +1,884 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_event.h --
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_EVENT_H
+#define SC_EVENT_H
+
+#include "sysc/kernel/sc_cmnhdr.h"
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/communication/sc_writer_policy.h"
+
+namespace sc_core {
+
+// forward declarations
+class sc_event;
+class sc_event_timed;
+class sc_event_list;
+class sc_event_or_list;
+class sc_event_and_list;
+class sc_object;
+
+// friend function declarations
+ int sc_notify_time_compare( const void*, const void* );
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_event_expr
+//
+// The event expression class.
+// ----------------------------------------------------------------------------
+
+template< typename T >
+class sc_event_expr
+{
+ friend class sc_event;
+ friend class sc_event_and_list;
+ friend class sc_event_or_list;
+
+ typedef T type;
+
+ inline sc_event_expr()
+ : m_expr( new T(true) )
+ {}
+
+public:
+
+ inline sc_event_expr( sc_event_expr const & e) // move semantics
+ : m_expr(e.m_expr)
+ {
+ e.m_expr = 0;
+ }
+
+ T const & release() const
+ {
+ sc_assert( m_expr );
+ T* expr = m_expr;
+ m_expr=0;
+ return *expr;
+ }
+
+ void push_back( sc_event const & e) const
+ {
+ sc_assert( m_expr );
+ m_expr->push_back(e);
+ }
+
+ void push_back( type const & el) const
+ {
+ sc_assert( m_expr );
+ m_expr->push_back(el);
+ }
+ operator T const &() const
+ {
+ return release();
+ }
+
+ ~sc_event_expr()
+ {
+ delete m_expr;
+ }
+
+private:
+ mutable type * m_expr;
+
+ // disabled
+ void operator=( sc_event_expr const & );
+};
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_event_list
+//
+// Base class for lists of events.
+// ----------------------------------------------------------------------------
+
+class sc_event_list
+{
+ friend class sc_process_b;
+ friend class sc_method_process;
+ friend class sc_thread_process;
+ friend void sc_thread_cor_fn( void* arg );
+
+public:
+ sc_event_list( const sc_event_list& );
+ sc_event_list& operator = ( const sc_event_list& );
+
+ int size() const;
+
+protected:
+
+ void push_back( const sc_event& );
+ void push_back( const sc_event_list& );
+
+ explicit
+ sc_event_list( bool and_list_, bool auto_delete_ = false );
+
+ sc_event_list( const sc_event&,
+ bool and_list_,
+ bool auto_delete_ = false );
+
+ ~sc_event_list();
+
+ void swap( sc_event_list& );
+ void move_from( const sc_event_list& );
+
+ bool and_list() const;
+
+ void add_dynamic( sc_method_handle ) const;
+ void add_dynamic( sc_thread_handle ) const;
+ void remove_dynamic( sc_method_handle, const sc_event* ) const;
+ void remove_dynamic( sc_thread_handle, const sc_event* ) const;
+
+ bool busy() const;
+ bool temporary() const;
+ void auto_delete() const;
+
+ void report_premature_destruction() const;
+ void report_invalid_modification() const;
+
+private:
+
+ std::vector<const sc_event*> m_events;
+ bool m_and_list;
+ bool m_auto_delete;
+ mutable unsigned m_busy;
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_event_and_list
+//
+// AND list of events.
+// ----------------------------------------------------------------------------
+
+class sc_event_and_list
+: public sc_event_list
+{
+ friend class sc_event;
+ friend class sc_event_expr<sc_event_and_list>;
+ friend class sc_process_b;
+ friend class sc_method_process;
+ friend class sc_thread_process;
+
+protected:
+
+ explicit
+ sc_event_and_list( bool auto_delete_ );
+
+public:
+
+ sc_event_and_list();
+ sc_event_and_list( const sc_event& );
+
+ void swap( sc_event_and_list& );
+ sc_event_and_list& operator &= ( const sc_event& );
+ sc_event_and_list& operator &= ( const sc_event_and_list & );
+
+ sc_event_expr<sc_event_and_list> operator & ( const sc_event& );
+ sc_event_expr<sc_event_and_list> operator & ( const sc_event_and_list& );
+};
+
+typedef sc_event_expr<sc_event_and_list> sc_event_and_expr;
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_event_or_list
+//
+// OR list of events.
+// ----------------------------------------------------------------------------
+
+class sc_event_or_list
+: public sc_event_list
+{
+ friend class sc_event;
+ friend class sc_event_expr<sc_event_or_list>;
+ friend class sc_process_b;
+ friend class sc_method_process;
+ friend class sc_thread_process;
+
+protected:
+
+ explicit
+ sc_event_or_list( bool auto_delete_ );
+
+public:
+ sc_event_or_list();
+ sc_event_or_list( const sc_event& );
+ void swap( sc_event_or_list& );
+ sc_event_or_list& operator |= ( const sc_event& );
+ sc_event_or_list& operator |= ( const sc_event_or_list & );
+ sc_event_expr<sc_event_or_list> operator | ( const sc_event& ) const;
+ sc_event_expr<sc_event_or_list> operator | ( const sc_event_or_list& ) const;
+};
+
+typedef sc_event_expr<sc_event_or_list> sc_event_or_expr;
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_event
+//
+// The event class.
+// ----------------------------------------------------------------------------
+
+class sc_event
+{
+ friend class sc_clock;
+ friend class sc_event_list;
+ friend class sc_event_timed;
+ friend class sc_simcontext;
+ friend class sc_object;
+ friend class sc_process_b;
+ friend class sc_method_process;
+ friend class sc_thread_process;
+ template<typename IF, sc_writer_policy POL> friend class sc_signal;
+ friend void sc_thread_cor_fn( void* arg );
+
+public:
+
+ sc_event();
+ sc_event( const char* name );
+ ~sc_event();
+
+ void cancel();
+
+ const char* name() const { return m_name.c_str(); }
+ const char* basename() const;
+ sc_object* get_parent_object() const { return m_parent_p; }
+ bool in_hierarchy() const { return m_name.length() != 0; }
+
+ void notify();
+ void notify( const sc_time& );
+ void notify( double, sc_time_unit );
+
+ void notify_delayed();
+ void notify_delayed( const sc_time& );
+ void notify_delayed( double, sc_time_unit );
+
+ sc_event_or_expr operator | ( const sc_event& ) const;
+ sc_event_or_expr operator | ( const sc_event_or_list& ) const;
+ sc_event_and_expr operator & ( const sc_event& ) const;
+ sc_event_and_expr operator & ( const sc_event_and_list& ) const;
+
+
+private:
+
+ void add_static( sc_method_handle ) const;
+ void add_static( sc_thread_handle ) const;
+ void add_dynamic( sc_method_handle ) const;
+ void add_dynamic( sc_thread_handle ) const;
+
+ void notify_internal( const sc_time& );
+ void notify_next_delta();
+
+ bool remove_static( sc_method_handle ) const;
+ bool remove_static( sc_thread_handle ) const;
+ bool remove_dynamic( sc_method_handle ) const;
+ bool remove_dynamic( sc_thread_handle ) const;
+
+ void register_event( const char* name );
+ void reset();
+
+ void trigger();
+
+private:
+
+ enum notify_t { NONE, DELTA, TIMED };
+
+ std::string m_name; // name of object.
+ sc_object* m_parent_p; // parent sc_object for this event.
+ sc_simcontext* m_simc;
+ notify_t m_notify_type;
+ int m_delta_event_index;
+ sc_event_timed* m_timed;
+
+ mutable std::vector<sc_method_handle> m_methods_static;
+ mutable std::vector<sc_method_handle> m_methods_dynamic;
+ mutable std::vector<sc_thread_handle> m_threads_static;
+ mutable std::vector<sc_thread_handle> m_threads_dynamic;
+
+private:
+
+ // disabled
+ sc_event( const sc_event& );
+ sc_event& operator = ( const sc_event& );
+};
+
+#define SC_KERNEL_EVENT_PREFIX "$$$$kernel_event$$$$_"
+
+extern sc_event sc_non_event; // Event that never happens.
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_event_timed
+//
+// Class for storing the time to notify a timed event.
+// ----------------------------------------------------------------------------
+
+class sc_event_timed
+{
+ friend class sc_event;
+ friend class sc_simcontext;
+
+ friend int sc_notify_time_compare( const void*, const void* );
+
+private:
+
+ sc_event_timed( sc_event* e, const sc_time& t )
+ : m_event( e ), m_notify_time( t )
+ {}
+
+ ~sc_event_timed()
+ { if( m_event != 0 ) { m_event->m_timed = 0; } }
+
+ sc_event* event() const
+ { return m_event; }
+
+ const sc_time& notify_time() const
+ { return m_notify_time; }
+
+ static void* operator new( std::size_t )
+ { return allocate(); }
+
+ static void operator delete( void* p, std::size_t )
+ { deallocate( p ); }
+
+private:
+
+ // dedicated memory management
+ static void* allocate();
+ static void deallocate( void* );
+
+private:
+
+ sc_event* m_event;
+ sc_time m_notify_time;
+
+private:
+
+ // disabled
+ sc_event_timed();
+ sc_event_timed( const sc_event_timed& );
+ sc_event_timed& operator = ( const sc_event_timed& );
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+inline
+void
+sc_event::notify( double v, sc_time_unit tu )
+{
+ notify( sc_time( v, tu, m_simc ) );
+}
+
+
+inline
+void
+sc_event::notify_internal( const sc_time& t )
+{
+ if( t == SC_ZERO_TIME ) {
+ // add this event to the delta events set
+ m_delta_event_index = m_simc->add_delta_event( this );
+ m_notify_type = DELTA;
+ } else {
+ sc_event_timed* et =
+ new sc_event_timed( this, m_simc->time_stamp() + t );
+ m_simc->add_timed_event( et );
+ m_timed = et;
+ m_notify_type = TIMED;
+ }
+}
+
+inline
+void
+sc_event::notify_next_delta()
+{
+ if( m_notify_type != NONE ) {
+ SC_REPORT_ERROR( SC_ID_NOTIFY_DELAYED_, 0 );
+ }
+ // add this event to the delta events set
+ m_delta_event_index = m_simc->add_delta_event( this );
+ m_notify_type = DELTA;
+}
+
+inline
+void
+sc_event::notify_delayed( double v, sc_time_unit tu )
+{
+ notify_delayed( sc_time( v, tu, m_simc ) );
+}
+
+
+inline
+void
+sc_event::add_static( sc_method_handle method_h ) const
+{
+ m_methods_static.push_back( method_h );
+}
+
+inline
+void
+sc_event::add_static( sc_thread_handle thread_h ) const
+{
+ m_threads_static.push_back( thread_h );
+}
+
+inline
+void
+sc_event::add_dynamic( sc_method_handle method_h ) const
+{
+ m_methods_dynamic.push_back( method_h );
+}
+
+inline
+void
+sc_event::add_dynamic( sc_thread_handle thread_h ) const
+{
+ m_threads_dynamic.push_back( thread_h );
+}
+
+
+// ----------------------------------------------------------------------------
+// Deprecated functional notation for notifying events.
+// ----------------------------------------------------------------------------
+
+extern void notify( sc_event& e );
+extern void notify( const sc_time& t, sc_event& e );
+extern void notify( double v, sc_time_unit tu, sc_event& e );
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+inline
+sc_event_list::sc_event_list( bool and_list_, bool auto_delete_ )
+ : m_events()
+ , m_and_list( and_list_ )
+ , m_auto_delete( auto_delete_ )
+ , m_busy( 0 )
+{
+}
+
+inline
+sc_event_list::sc_event_list( const sc_event& e,
+ bool and_list_,
+ bool auto_delete_ )
+ : m_events()
+ , m_and_list( and_list_ )
+ , m_auto_delete( auto_delete_ )
+ , m_busy(0)
+{
+ m_events.push_back( &e );
+}
+
+inline
+sc_event_list::sc_event_list( sc_event_list const & that )
+ : m_events()
+ , m_and_list( that.m_and_list )
+ , m_auto_delete( false )
+ , m_busy( 0 )
+{
+ move_from( that );
+ that.auto_delete(); // free automatic lists
+}
+
+inline
+sc_event_list&
+sc_event_list::operator=( sc_event_list const & that )
+{
+ if( m_busy )
+ report_invalid_modification();
+
+ move_from( that );
+ that.auto_delete(); // free automatic lists
+
+ return *this;
+}
+
+inline
+sc_event_list::~sc_event_list()
+{
+ if( m_busy )
+ report_premature_destruction();
+}
+
+inline
+void
+sc_event_list::swap( sc_event_list& that )
+{
+ if( busy() || that.busy() )
+ report_invalid_modification();
+ m_events.swap( that.m_events );
+}
+
+inline
+void
+sc_event_list::move_from( sc_event_list const& that )
+{
+ if( that.temporary() ) {
+ swap( const_cast<sc_event_list&>(that) ); // move from source
+ } else {
+ m_events = that.m_events; // copy from source
+ }
+}
+
+inline
+int
+sc_event_list::size() const
+{
+ return m_events.size();
+}
+
+inline
+bool
+sc_event_list::and_list() const
+{
+ return m_and_list;
+}
+
+
+inline
+bool
+sc_event_list::busy() const
+{
+ return m_busy != 0;
+}
+
+
+inline
+bool
+sc_event_list::temporary() const
+{
+ return m_auto_delete && ! m_busy;
+}
+
+inline
+void
+sc_event_list::auto_delete() const
+{
+ if( m_busy ) {
+ --m_busy;
+ }
+ if( ! m_busy && m_auto_delete ) {
+ delete this;
+ }
+}
+
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+inline
+sc_event_or_list::sc_event_or_list()
+ : sc_event_list( false )
+{}
+
+inline
+sc_event_or_list::sc_event_or_list( const sc_event& e )
+: sc_event_list( false )
+{
+ push_back( e );
+}
+
+inline
+sc_event_or_list::sc_event_or_list( bool auto_delete_ )
+: sc_event_list( false, auto_delete_ )
+{}
+
+inline
+sc_event_or_list&
+sc_event_or_list::operator |= ( const sc_event& e )
+{
+ if( busy() )
+ report_invalid_modification();
+
+ push_back( e );
+ return *this;
+}
+
+inline
+sc_event_or_list&
+sc_event_or_list::operator |= ( const sc_event_or_list& el )
+{
+ if( busy() )
+ report_invalid_modification();
+
+ push_back( el );
+ return *this;
+}
+
+inline
+sc_event_or_expr
+sc_event_or_list::operator | ( const sc_event& e2 ) const
+{
+ sc_event_or_expr expr;
+ expr.push_back( *this );
+ expr.push_back( e2 );
+ return expr;
+}
+
+inline
+sc_event_or_expr
+sc_event_or_list::operator | ( const sc_event_or_list& e2 ) const
+{
+ sc_event_or_expr expr;
+ expr.push_back( *this );
+ expr.push_back( e2 );
+ return expr;
+}
+
+
+// sc_event
+
+inline
+sc_event_or_expr
+sc_event::operator | ( const sc_event& e2 ) const
+{
+ sc_event_or_expr expr;
+ expr.push_back( *this );
+ expr.push_back( e2 );
+ return expr;
+}
+
+inline
+sc_event_or_expr
+sc_event::operator | ( const sc_event_or_list& e2 ) const
+{
+ sc_event_or_expr expr;
+ expr.push_back( *this );
+ expr.push_back( e2 );
+ return expr;
+}
+
+// sc_event_expr
+
+inline
+sc_event_or_expr
+operator | ( sc_event_or_expr expr, sc_event const & e )
+{
+ expr.push_back( e );
+ return expr;
+}
+
+inline
+sc_event_or_expr
+operator | ( sc_event_or_expr expr, sc_event_or_list const & el )
+{
+ expr.push_back( el );
+ return expr;
+}
+
+inline
+void
+sc_event_or_list::swap( sc_event_or_list & that )
+{
+ sc_event_list::swap( that );
+}
+
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+inline
+sc_event_and_list::sc_event_and_list()
+ : sc_event_list( true )
+{}
+
+inline
+sc_event_and_list::sc_event_and_list( const sc_event& e )
+: sc_event_list( true )
+{
+ push_back( e );
+}
+
+inline
+sc_event_and_list::sc_event_and_list( bool auto_delete_ )
+: sc_event_list( true, auto_delete_ )
+{}
+
+inline
+void
+sc_event_and_list::swap( sc_event_and_list & that )
+{
+ sc_event_list::swap( that );
+}
+
+
+inline
+sc_event_and_list&
+sc_event_and_list::operator &= ( const sc_event& e )
+{
+ if( busy() )
+ report_invalid_modification();
+
+ push_back( e );
+ return *this;
+}
+
+inline
+sc_event_and_list&
+sc_event_and_list::operator &= ( const sc_event_and_list& el )
+{
+ if( busy() )
+ report_invalid_modification();
+
+ push_back( el );
+ return *this;
+}
+
+inline
+sc_event_and_expr
+sc_event_and_list::operator & ( const sc_event& e )
+{
+ sc_event_and_expr expr;
+ expr.push_back( *this );
+ expr.push_back( e );
+ return expr;
+}
+
+inline
+sc_event_and_expr
+sc_event_and_list::operator & ( const sc_event_and_list& el )
+{
+ sc_event_and_expr expr;
+ expr.push_back( *this );
+ expr.push_back( el );
+ return expr;
+}
+
+// sc_event
+
+inline
+sc_event_and_expr
+sc_event::operator & ( const sc_event& e2 ) const
+{
+ sc_event_and_expr expr;
+ expr.push_back( *this );
+ expr.push_back( e2 );
+ return expr;
+}
+
+inline
+sc_event_and_expr
+sc_event::operator & ( const sc_event_and_list& e2 ) const
+{
+ sc_event_and_expr expr;
+ expr.push_back( *this );
+ expr.push_back( e2 );
+ return expr;
+}
+
+// sc_event_expr
+
+inline
+sc_event_and_expr
+operator & ( sc_event_and_expr expr, sc_event const & e )
+{
+ expr.push_back( e );
+ return expr;
+}
+
+inline
+sc_event_and_expr
+operator & ( sc_event_and_expr expr, sc_event_and_list const & el )
+{
+ expr.push_back( el );
+ return expr;
+}
+
+} // namespace sc_core
+
+// $Log: sc_event.h,v $
+// Revision 1.14 2011/08/29 18:04:32 acg
+// Philipp A. Hartmann: miscellaneous clean ups.
+//
+// Revision 1.13 2011/08/26 20:46:09 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.12 2011/08/24 22:05:50 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.11 2011/03/12 21:07:51 acg
+// Andy Goodrich: changes to kernel generated event support.
+//
+// Revision 1.10 2011/03/06 15:55:11 acg
+// Andy Goodrich: Changes for named events.
+//
+// Revision 1.9 2011/03/05 01:39:21 acg
+// Andy Goodrich: changes for named events.
+//
+// Revision 1.8 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.7 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.6 2011/02/01 21:03:23 acg
+// Andy Goodrich: new return codes for trigger_dynamic calls.
+//
+// Revision 1.5 2011/01/18 20:10:44 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.4 2010/12/07 20:09:11 acg
+// Andy Goodrich: writer policy fix.
+//
+// Revision 1.3 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.2 2008/05/22 17:06:25 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.8 2006/05/26 20:33:16 acg
+// Andy Goodrich: changes required by additional platform compilers (i.e.,
+// Microsoft VC++, Sun Forte, HP aCC).
+//
+// Revision 1.7 2006/05/08 17:57:51 acg
+// Andy Goodrich: added David Long's forward declarations for friend
+// functions, methods, and operators to keep the Microsoft compiler happy.
+//
+// Revision 1.6 2006/04/11 23:13:20 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.5 2006/01/24 20:56:00 acg
+// Andy Goodrich: fixed up CVS comment.
+//
+// Revision 1.4 2006/01/24 20:48:14 acg
+// Andy Goodrich: added deprecation warnings for notify_delayed(). Added two
+// new implementation-dependent methods, notify_next_delta() & notify_internal()
+// to replace calls to notify_delayed() from within the simulator. These two
+// new methods are simpler than notify_delayed() and should speed up simulations
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_except.cpp b/ext/systemc/src/sysc/kernel/sc_except.cpp
new file mode 100644
index 000000000..2699f8daf
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_except.cpp
@@ -0,0 +1,142 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_except.cpp -- kill/reset exception handling
+
+ Original Author: Philipp A. Hartmann, OFFIS
+
+ CHANGE LOG APPEARS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include "sysc/kernel/sc_cmnhdr.h"
+//
+#include "sysc/kernel/sc_except.h"
+#include "sysc/kernel/sc_process.h"
+//
+#include "sysc/utils/sc_report.h"
+
+namespace sc_core {
+
+sc_unwind_exception::sc_unwind_exception( sc_process_b* proc_p, bool is_reset )
+ : m_proc_p(proc_p), m_is_reset( is_reset )
+{
+ sc_assert( m_proc_p );
+ m_proc_p->start_unwinding();
+}
+
+bool
+sc_unwind_exception::active() const
+{
+ return m_proc_p && m_proc_p->is_unwinding();
+}
+
+void
+sc_unwind_exception::clear() const
+{
+ sc_assert( m_proc_p );
+ m_proc_p->clear_unwinding();
+}
+
+const char*
+sc_unwind_exception::what() const throw()
+{
+ return ( m_is_reset ) ? "RESET" : "KILL";
+}
+
+sc_unwind_exception::~sc_unwind_exception() throw()
+{
+ if( active() ) {
+ // can't throw an exception, since we're already throwing
+ // -> abort instead
+ SC_REPORT_FATAL( SC_ID_RETHROW_UNWINDING_, m_proc_p->name() );
+ }
+}
+
+// handle and translate uncaught exceptions here
+//
+// These exceptions can either escape from sc_main() directly,
+// indirectly from an SC_METHOD(), or are thrown from within
+// an SC_(C)THREAD()
+//
+// returns a pointer to a dynamically allocated sc_report object,
+// containing the caught message
+
+sc_report*
+sc_handle_exception()
+{
+ try {
+
+ // re-throw exception here
+ try { throw; }
+
+ catch( sc_report & ) // to be on the safe side
+ {
+ throw; // continue
+ }
+ catch( sc_unwind_exception const & )
+ {
+ sc_assert( false && "Unhandled kill/reset, should never happen" );
+ }
+ catch( std::exception const & x )
+ {
+ SC_REPORT_ERROR( SC_ID_SIMULATION_UNCAUGHT_EXCEPTION_, x.what() );
+ }
+ catch( char const * x )
+ {
+ SC_REPORT_ERROR( SC_ID_SIMULATION_UNCAUGHT_EXCEPTION_, x );
+ }
+ catch( ... )
+ {
+ SC_REPORT_ERROR( SC_ID_SIMULATION_UNCAUGHT_EXCEPTION_,
+ "UNKNOWN EXCEPTION" );
+ }
+ }
+ // everything is an sc_report now
+ catch( sc_report & rpt )
+ {
+ sc_report* rpt_p = new sc_report;
+ rpt_p->swap( rpt );
+ return rpt_p;
+ }
+ return 0;
+}
+
+} // namespace sc_core
+
+// $Log: sc_except.cpp,v $
+// Revision 1.4 2011/08/26 20:46:09 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.3 2011/05/09 04:07:48 acg
+// Philipp A. Hartmann:
+// (1) Restore hierarchy in all phase callbacks.
+// (2) Ensure calls to before_end_of_elaboration.
+//
+// Revision 1.2 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.1 2011/02/10 22:47:38 acg
+// Andy Goodrich: first check in of Philipp A. Hartmann's new exception
+// processing code.
+//
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_except.h b/ext/systemc/src/sysc/kernel/sc_except.h
new file mode 100644
index 000000000..e3bacbd9c
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_except.h
@@ -0,0 +1,178 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_except.h - Exception classes to be handled by SystemC.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_EXCEPT_H
+#define SC_EXCEPT_H
+
+#include <exception>
+
+namespace sc_core {
+
+class sc_simcontext;
+class sc_process_b;
+class sc_method_process;
+class sc_thread_process;
+void sc_thread_cor_fn( void* arg );
+
+/*
+ * These classes are intentionally empty. Their raison d'etre is for
+ * the implementation of various SystemC throws.
+ */
+
+class sc_user
+{
+ /*EMPTY*/
+public:
+ sc_user() {}
+ sc_user( const sc_user& ) {}
+};
+
+class sc_halt
+{
+public:
+ sc_halt() {}
+ sc_halt( const sc_halt& ) {}
+};
+
+class sc_kill
+{
+public:
+ sc_kill() {}
+ sc_kill( const sc_kill& ) {}
+};
+
+class sc_unwind_exception : public std::exception
+{
+ friend class sc_simcontext;
+ friend class sc_process_b;
+ friend class sc_method_process;
+ friend class sc_thread_process;
+ friend void sc_thread_cor_fn( void* arg );
+
+ public:
+ virtual bool is_reset() const { return m_is_reset; }
+ virtual const char* what() const throw();
+
+ public:
+
+ // enable catch by value
+ sc_unwind_exception( const sc_unwind_exception& );
+ virtual ~sc_unwind_exception() throw();
+
+ protected:
+ explicit
+ sc_unwind_exception( sc_process_b* target_p, bool is_reset = false );
+
+ bool active() const;
+ void clear() const;
+
+ private:
+ // disabled
+ sc_unwind_exception& operator=( const sc_unwind_exception& );
+
+ mutable sc_process_b* m_proc_p; // used to check, if caught by the kernel
+ const bool m_is_reset; // true if this is an unwind of a reset
+
+};
+
+inline
+sc_unwind_exception::sc_unwind_exception( const sc_unwind_exception& that )
+ : std::exception( that )
+ , m_proc_p( that.m_proc_p )
+ , m_is_reset( that.m_is_reset )
+{
+ that.m_proc_p = 0; // move to new instance
+}
+
+//------------------------------------------------------------------------------
+// global exception handling
+//------------------------------------------------------------------------------
+
+class sc_report;
+sc_report* sc_handle_exception();
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Gene Bushuyev. Synopsys, Inc.
+ Description of Modification: - Had to add empty public default and copy
+ constructors to satisfy VC6.0.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_except.h,v $
+// Revision 1.11 2011/08/26 21:40:26 acg
+// Philipp A. Hartmann: fix up sc_unwind_exception copy-ctor.
+//
+// Revision 1.10 2011/08/26 20:46:09 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.9 2011/08/24 22:05:50 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.8 2011/05/09 04:07:48 acg
+// Philipp A. Hartmann:
+// (1) Restore hierarchy in all phase callbacks.
+// (2) Ensure calls to before_end_of_elaboration.
+//
+// Revision 1.7 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.6 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.5 2011/02/11 13:25:24 acg
+// Andy Goodrich: Philipp A. Hartmann's changes:
+// (1) Removal of SC_CTHREAD method overloads.
+// (2) New exception processing code.
+//
+// Revision 1.4 2011/01/18 20:10:44 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.3 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.2 2008/05/22 17:06:25 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+
+#endif
diff --git a/ext/systemc/src/sysc/kernel/sc_externs.h b/ext/systemc/src/sysc/kernel/sc_externs.h
new file mode 100644
index 000000000..1d1818089
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_externs.h
@@ -0,0 +1,65 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_externs.h -- Declaration of `sc_main' and other global variables.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_EXTERNS_H
+#define SC_EXTERNS_H
+
+
+
+extern "C" int sc_main( int argc, char* argv[] );
+
+namespace sc_core {
+ extern "C" int sc_elab_and_sim( int argc, char* argv[] );
+ extern "C" int sc_argc();
+ extern "C" const char* const* sc_argv();
+
+} // namespace sc_core
+
+// $Log: sc_externs.h,v $
+// Revision 1.5 2011/08/26 20:46:09 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.2 2008/05/22 17:06:25 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
+
+#endif
diff --git a/ext/systemc/src/sysc/kernel/sc_join.cpp b/ext/systemc/src/sysc/kernel/sc_join.cpp
new file mode 100644
index 000000000..25f6f6cea
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_join.cpp
@@ -0,0 +1,143 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_join.cpp -- Join Process Synchronization Implementation
+
+ Original Author: Andy Goodrich, Forte Design Systems, 5 May 2003
+
+ CHANGE LOG APPEARS AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#include <cassert>
+#include <cstdlib>
+#include <cstddef>
+
+#include "sysc/kernel/sc_process_handle.h"
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_simcontext_int.h"
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/kernel/sc_thread_process.h"
+#include "sysc/kernel/sc_join.h"
+
+namespace sc_core {
+
+//------------------------------------------------------------------------------
+//"sc_join::sc_join"
+//
+// This is the object instance constructor for this class.
+//------------------------------------------------------------------------------
+sc_join::sc_join()
+ : m_join_event( (std::string(SC_KERNEL_EVENT_PREFIX)+"_join_event").c_str() )
+ , m_threads_n(0)
+{}
+
+//------------------------------------------------------------------------------
+//"sc_join::add_process - sc_process_b*"
+//
+// This method adds a process to this join object instance. This consists of
+// incrementing the count of processes in the join process and adding this
+// object instance to the supplied thread's monitoring queue.
+// process_p -> thread to be monitored.
+//------------------------------------------------------------------------------
+void sc_join::add_process( sc_process_b* process_p )
+{
+ sc_thread_handle handle = DCAST<sc_thread_handle>(process_p);
+ assert( handle != 0 );
+ m_threads_n++;
+ handle->add_monitor( this );
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_join::add_process - sc_process_handle"
+//
+// This method adds a process to this join object instance. This consists of
+// incrementing the count of processes in the join process and adding this
+// object instance to the supplied thread's monitoring queue.
+// process_h = handle for process to be monitored.
+//------------------------------------------------------------------------------
+void sc_join::add_process( sc_process_handle process_h )
+{
+ sc_thread_handle thread_p; // Thread within process_h.
+
+ thread_p = process_h.operator sc_thread_handle();
+ if ( thread_p )
+ {
+ m_threads_n++;
+ thread_p->add_monitor( this );
+ }
+ else
+ {
+ SC_REPORT_ERROR( SC_ID_JOIN_ON_METHOD_HANDLE_, 0 );
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_join::signal"
+//
+// This virtual method is called when a process being monitored by this object
+// instance sends a signal. If the signal type is spm_exit and the count of
+// threads that we are waiting to terminate on goes to zero we fire our join
+// event.
+// thread_p -> thread that is signalling.
+// type = type of signal being sent.
+//------------------------------------------------------------------------------
+void sc_join::signal(sc_thread_handle thread_p, int type)
+{
+ switch ( type )
+ {
+ case sc_process_monitor::spm_exit:
+ thread_p->remove_monitor(this);
+ if ( --m_threads_n == 0 ) m_join_event.notify();
+ break;
+ }
+}
+
+} // namespace sc_core
+
+// $Log: sc_join.cpp,v $
+// Revision 1.7 2011/08/26 21:45:00 acg
+// Andy Goodrich: fix internal event naming.
+//
+// Revision 1.6 2011/08/26 20:46:09 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.5 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.4 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.3 2009/07/28 01:10:53 acg
+// Andy Goodrich: updates for 2.3 release candidate.
+//
+// Revision 1.2 2008/05/22 17:06:25 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
diff --git a/ext/systemc/src/sysc/kernel/sc_join.h b/ext/systemc/src/sysc/kernel/sc_join.h
new file mode 100644
index 000000000..e240f51a2
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_join.h
@@ -0,0 +1,136 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_join.h -- Join Process Synchronization Definition
+
+ Original Author: Andy Goodrich, Forte Design Systems, 5 May 2003
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+// $Log: sc_join.h,v $
+// Revision 1.8 2011/08/26 21:45:00 acg
+// Andy Goodrich: fix internal event naming.
+//
+// Revision 1.7 2011/08/26 20:46:09 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+
+#ifndef SC_JOIN_H
+#define SC_JOIN_H
+
+#include "sysc/kernel/sc_process.h"
+#include "sysc/kernel/sc_wait.h"
+
+namespace sc_core {
+
+//==============================================================================
+// CLASS sc_join
+//
+// This class provides a way of waiting for a set of threads to complete their
+// execution. The threads whose completion is to be monitored are registered,
+// and upon their completion an event notification will occur.
+//==============================================================================
+class sc_join : public sc_process_monitor {
+ friend class sc_process_b;
+ friend class sc_process_handle;
+ public:
+ sc_join();
+ void add_process( sc_process_handle process_h );
+ inline int process_count();
+ virtual void signal(sc_thread_handle thread_p, int type);
+ inline void wait();
+ inline void wait_clocked();
+
+ protected:
+ void add_process( sc_process_b* process_p );
+
+ protected:
+ sc_event m_join_event; // Event to notify when all threads have reported.
+ int m_threads_n; // # of threads still need to wait for.
+};
+
+int sc_join::process_count() { return m_threads_n; }
+
+// suspend a thread that does not have a sensitivity list:
+
+inline void sc_join::wait() { ::sc_core::wait(m_join_event); }
+
+// suspend a thread that has a sensitivity list:
+
+inline void sc_join::wait_clocked()
+{
+ do { ::sc_core::wait(); } while (m_threads_n != 0);
+}
+
+#define SC_CJOIN \
+ }; \
+ sc_core::sc_join join; \
+ for ( unsigned int i = 0; \
+ i < sizeof(forkees)/sizeof(sc_core::sc_process_handle); \
+ i++ ) \
+ join.add_process(forkees[i]); \
+ join.wait_clocked(); \
+}
+
+#define SC_FORK \
+{ \
+ sc_core::sc_process_handle forkees[] = {
+
+#define SC_JOIN \
+ }; \
+ sc_core::sc_join join; \
+ for ( unsigned int i = 0; \
+ i < sizeof(forkees)/sizeof(sc_core::sc_process_handle); \
+ i++ ) \
+ join.add_process(forkees[i]); \
+ join.wait(); \
+}
+
+} // namespace sc_core
+
+// Revision 1.6 2011/08/24 22:05:50 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.5 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.4 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.3 2009/07/28 01:10:53 acg
+// Andy Goodrich: updates for 2.3 release candidate.
+//
+// Revision 1.2 2008/05/22 17:06:25 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.5 2006/04/28 21:38:27 acg
+// Andy Goodrich: fixed loop constraint that was using sizeof(sc_thread_handle)
+// rather than sizeof(sc_process_handle).
+//
+// Revision 1.4 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+
+#endif // SC_JOIN_H
diff --git a/ext/systemc/src/sysc/kernel/sc_kernel_ids.h b/ext/systemc/src/sysc/kernel/sc_kernel_ids.h
new file mode 100644
index 000000000..32846df12
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_kernel_ids.h
@@ -0,0 +1,321 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_kernel_ids.h -- Report ids for the kernel code.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2002-01-17
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_KERNEL_IDS_H
+#define SC_KERNEL_IDS_H
+
+
+#include "sysc/utils/sc_report.h"
+
+
+// ----------------------------------------------------------------------------
+// Report ids (kernel)
+//
+// Report ids in the range of 500-599.
+// ----------------------------------------------------------------------------
+
+#ifndef SC_DEFINE_MESSAGE
+#define SC_DEFINE_MESSAGE(id,unused1,unused2) \
+ namespace sc_core { extern const char id[]; }
+namespace sc_core {
+ extern const char SC_ID_REGISTER_ID_FAILED_[]; // in sc_report_handler.cpp
+}
+#endif
+
+SC_DEFINE_MESSAGE(SC_ID_NO_BOOL_RETURNED_ , 500,
+ "operator does not return boolean")
+SC_DEFINE_MESSAGE(SC_ID_NO_INT_RETURNED_ , 501,
+ "operator does not return int")
+SC_DEFINE_MESSAGE(SC_ID_NO_SC_LOGIC_RETURNED_ , 502,
+ "operator does not return sc_logic")
+SC_DEFINE_MESSAGE(SC_ID_OPERAND_NOT_SC_LOGIC_ , 503,
+ "operand is not sc_logic")
+SC_DEFINE_MESSAGE(SC_ID_OPERAND_NOT_BOOL_ , 504,
+ "operand is not bool")
+SC_DEFINE_MESSAGE(SC_ID_INSTANCE_EXISTS_ , 505,
+ "object already exists")
+SC_DEFINE_MESSAGE(SC_ID_ILLEGAL_CHARACTERS_ , 506,
+ "illegal characters" )
+SC_DEFINE_MESSAGE(SC_ID_VC6_PROCESS_HELPER_ , 507,
+ "internal error: sc_vc6_process_helper" )
+SC_DEFINE_MESSAGE(SC_ID_VC6_MAX_PROCESSES_EXCEEDED_ , 508,
+ "maximum number of processes per module exceeded (VC6)" )
+SC_DEFINE_MESSAGE(SC_ID_END_MODULE_NOT_CALLED_ , 509,
+ "module construction not properly completed: did "
+ "you forget to add a sc_module_name parameter to "
+ "your module constructor?" )
+SC_DEFINE_MESSAGE(SC_ID_HIER_NAME_INCORRECT_ , 510,
+ "hierarchical name as shown may be incorrect due to previous errors" )
+SC_DEFINE_MESSAGE(SC_ID_SET_STACK_SIZE_ , 511,
+ "set_stack_size() is only allowed for SC_THREADs and SC_CTHREADs" )
+SC_DEFINE_MESSAGE(SC_ID_SC_MODULE_NAME_USE_ , 512,
+ "incorrect use of sc_module_name" )
+SC_DEFINE_MESSAGE(SC_ID_SC_MODULE_NAME_REQUIRED_ , 513,
+ "an sc_module_name parameter for your constructor is required" )
+SC_DEFINE_MESSAGE(SC_ID_SET_TIME_RESOLUTION_ , 514,
+ "set time resolution failed" )
+SC_DEFINE_MESSAGE(SC_ID_SET_DEFAULT_TIME_UNIT_ , 515,
+ "set default time unit failed" )
+SC_DEFINE_MESSAGE(SC_ID_DEFAULT_TIME_UNIT_CHANGED_ , 516,
+ "default time unit changed to time resolution" )
+SC_DEFINE_MESSAGE(SC_ID_INCONSISTENT_API_CONFIG_ , 517,
+ "inconsistent library configuration detected" )
+// available message number 518
+SC_DEFINE_MESSAGE(SC_ID_WAIT_NOT_ALLOWED_ , 519,
+ "wait() is only allowed in SC_THREADs and SC_CTHREADs" )
+SC_DEFINE_MESSAGE(SC_ID_NEXT_TRIGGER_NOT_ALLOWED_ , 520,
+ "next_trigger() is only allowed in SC_METHODs" )
+SC_DEFINE_MESSAGE(SC_ID_IMMEDIATE_NOTIFICATION_ , 521,
+ "immediate notification is not allowed during the update phase" )
+SC_DEFINE_MESSAGE(SC_ID_HALT_NOT_ALLOWED_ , 522,
+ "halt() is only allowed in SC_CTHREADs" )
+SC_DEFINE_MESSAGE(SC_ID_WATCHING_NOT_ALLOWED_ , 523,
+ "watching() has been deprecated, use reset_signal_is()" )
+SC_DEFINE_MESSAGE(SC_ID_DONT_INITIALIZE_ , 524,
+ "dont_initialize() has no effect for SC_CTHREADs" )
+SC_DEFINE_MESSAGE(SC_ID_WAIT_N_INVALID_ , 525,
+ "wait(n) is only valid for n > 0" )
+SC_DEFINE_MESSAGE(SC_ID_MAKE_SENSITIVE_ , 526,
+ "make sensitive failed" )
+SC_DEFINE_MESSAGE(SC_ID_MAKE_SENSITIVE_POS_ , 527,
+ "make sensitive pos failed" )
+SC_DEFINE_MESSAGE(SC_ID_MAKE_SENSITIVE_NEG_ , 528,
+ "make sensitive neg failed" )
+SC_DEFINE_MESSAGE(SC_ID_INSERT_MODULE_ , 529,
+ "insert module failed" )
+SC_DEFINE_MESSAGE(SC_ID_REMOVE_MODULE_ , 530,
+ "remove module failed" )
+SC_DEFINE_MESSAGE(SC_ID_NOTIFY_DELAYED_ , 531,
+ "notify_delayed() cannot be called on events "
+ "that have pending notifications" )
+SC_DEFINE_MESSAGE(SC_ID_GEN_UNIQUE_NAME_ , 532,
+ "cannot generate unique name from null string" )
+SC_DEFINE_MESSAGE(SC_ID_MODULE_NAME_STACK_EMPTY_ , 533,
+ "module name stack is empty: did you forget to "
+ "add a sc_module_name parameter to your module "
+ "constructor?" )
+// available message number 534
+// available message number 535
+SC_DEFINE_MESSAGE( SC_ID_IMMEDIATE_SELF_NOTIFICATION_, 536,
+ "immediate self-notification ignored as of IEEE 1666-2011" )
+SC_DEFINE_MESSAGE( SC_ID_WAIT_DURING_UNWINDING_ , 537,
+ "wait() not allowed during unwinding" )
+SC_DEFINE_MESSAGE(SC_ID_CYCLE_MISSES_EVENTS_ , 538,
+ "the simulation contains timed-events but they are "
+ "ignored by sc_cycle() ==> the simulation will be "
+ "incorrect" )
+SC_DEFINE_MESSAGE( SC_ID_RETHROW_UNWINDING_ , 539,
+ "sc_unwind_exception not re-thrown during kill/reset" )
+SC_DEFINE_MESSAGE( SC_ID_PROCESS_ALREADY_UNWINDING_ , 540,
+ "kill/reset ignored during unwinding" )
+SC_DEFINE_MESSAGE(SC_ID_MODULE_METHOD_AFTER_START_ , 541,
+ "call to SC_METHOD in sc_module while simulation running" )
+SC_DEFINE_MESSAGE(SC_ID_MODULE_THREAD_AFTER_START_ , 542,
+ "call to SC_THREAD in sc_module while simulation running" )
+SC_DEFINE_MESSAGE(SC_ID_MODULE_CTHREAD_AFTER_START_ , 543,
+ "call to SC_CTHREAD in sc_module while simulation running" )
+SC_DEFINE_MESSAGE(SC_ID_SIMULATION_TIME_OVERFLOW_ , 544,
+ "simulation time value overflow, simulation aborted" )
+SC_DEFINE_MESSAGE(SC_ID_SIMULATION_STOP_CALLED_TWICE_ , 545,
+ "sc_stop has already been called" )
+SC_DEFINE_MESSAGE(SC_ID_SIMULATION_START_AFTER_STOP_ , 546,
+ "sc_start called after sc_stop has been called" )
+SC_DEFINE_MESSAGE(SC_ID_STOP_MODE_AFTER_START_ , 547,
+ "attempt to set sc_stop mode after start will be ignored" )
+SC_DEFINE_MESSAGE( SC_ID_SIMULATION_START_AFTER_ERROR_, 548,
+ "attempt to restart simulation after error" )
+SC_DEFINE_MESSAGE( SC_ID_SIMULATION_UNCAUGHT_EXCEPTION_, 549,
+ "uncaught exception" )
+SC_DEFINE_MESSAGE(SC_ID_PHASE_CALLBACKS_UNSUPPORTED_ , 550,
+ "simulation phase callbacks not enabled")
+SC_DEFINE_MESSAGE(SC_ID_PHASE_CALLBACK_NOT_IMPLEMENTED_, 551,
+ "empty simulation phase callback called" )
+SC_DEFINE_MESSAGE(SC_ID_PHASE_CALLBACK_REGISTER_, 552,
+ "register simulation phase callback" )
+SC_DEFINE_MESSAGE(SC_ID_PHASE_CALLBACK_FORBIDDEN_, 553,
+ "forbidden action in simulation phase callback" )
+// available message number 554
+// available message number 555
+SC_DEFINE_MESSAGE(SC_ID_THROW_IT_IGNORED_ , 556,
+ "throw_it on method/non-running process is being ignored " )
+SC_DEFINE_MESSAGE(SC_ID_NOT_EXPECTING_DYNAMIC_EVENT_NOTIFY_ , 557,
+ "dynamic event notification encountered when sensitivity is static" )
+SC_DEFINE_MESSAGE(SC_ID_DISABLE_WILL_ORPHAN_PROCESS_ , 558,
+ "disable() or dont_initialize() called on process with no static sensitivity, it will be orphaned" )
+SC_DEFINE_MESSAGE(SC_ID_PROCESS_CONTROL_CORNER_CASE_ , 559,
+ "Undefined process control interaction" )
+SC_DEFINE_MESSAGE(SC_ID_METHOD_TERMINATION_EVENT_ , 560,
+ "Attempt to get terminated event for a method process" )
+SC_DEFINE_MESSAGE(SC_ID_JOIN_ON_METHOD_HANDLE_ , 561,
+ "Attempt to register method process with sc_join object" )
+SC_DEFINE_MESSAGE(SC_ID_NO_PROCESS_SEMANTICS_ , 563,
+ "Attempt to invoke process with no semantics() method" )
+SC_DEFINE_MESSAGE(SC_ID_EVENT_ON_NULL_PROCESS_ , 564,
+ "Attempt to get an event for non-existent process" )
+// available message number 565
+SC_DEFINE_MESSAGE(SC_ID_UNKNOWN_PROCESS_TYPE_, 566,
+ "Unknown process type" )
+// available message number 567
+SC_DEFINE_MESSAGE(SC_ID_NEGATIVE_SIMULATION_TIME_, 568,
+ "negative simulation interval specified in sc_start call" )
+SC_DEFINE_MESSAGE(SC_ID_BAD_SC_MODULE_CONSTRUCTOR_ , 569,
+ "sc_module(const char*), sc_module(const std::string&) "
+ "have been deprecated, use sc_module(const sc_module_name&)" )
+SC_DEFINE_MESSAGE(SC_ID_EMPTY_PROCESS_HANDLE_ , 570,
+ "attempt to use an empty process handle ignored" )
+SC_DEFINE_MESSAGE(SC_ID_NO_SC_START_ACTIVITY_ , 571,
+ "no activity or clock movement for sc_start() invocation" )
+SC_DEFINE_MESSAGE(SC_ID_KILL_PROCESS_WHILE_UNITIALIZED_ , 572,
+ "a process may not be killed before it is initialized" )
+SC_DEFINE_MESSAGE(SC_ID_RESET_PROCESS_WHILE_NOT_RUNNING_ , 573,
+ "a process may not be asynchronously reset while the simulation is not running" )
+SC_DEFINE_MESSAGE(SC_ID_THROW_IT_WHILE_NOT_RUNNING_ , 574,
+ "throw_it not allowed unless simulation is running " )
+
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_kernel_ids.h,v $
+// Revision 1.25 2011/08/26 22:06:34 acg
+// Torsten Maehne: formating fix.
+//
+// Revision 1.24 2011/08/07 19:08:04 acg
+// Andy Goodrich: moved logs to end of file so line number synching works
+// better between versions.
+//
+// Revision 1.23 2011/07/24 11:15:47 acg
+// Philipp A. Hartmann: Improvements to error/warning messages related to
+// process control.
+//
+// Revision 1.22 2011/05/09 04:07:48 acg
+// Philipp A. Hartmann:
+// (1) Restore hierarchy in all phase callbacks.
+// (2) Ensure calls to before_end_of_elaboration.
+//
+// Revision 1.21 2011/04/19 19:15:41 acg
+// Andy Goodrich: fix so warning message is always issued for a throw_it()
+// on a method process.
+//
+// Revision 1.20 2011/04/19 15:04:27 acg
+// Philipp A. Hartmann: clean up SC_ID messages.
+//
+// Revision 1.19 2011/04/19 02:39:09 acg
+// Philipp A. Hartmann: added checks for additional throws during stack unwinds.
+//
+// Revision 1.18 2011/04/05 06:23:45 acg
+// Andy Goodrich: comments for throws while the simulator is not running.
+//
+// Revision 1.17 2011/04/01 22:30:39 acg
+// Andy Goodrich: change hard assertion to warning for trigger_dynamic()
+// getting called when there is only STATIC sensitivity. This can result
+// because of sc_process_handle::throw_it().
+//
+// Revision 1.16 2011/03/28 13:02:51 acg
+// Andy Goodrich: Changes for disable() interactions.
+//
+// Revision 1.15 2011/03/07 17:34:21 acg
+// Andy Goodrich: changed process control corner case message. Added more
+// place holders for unused message numbers.
+//
+// Revision 1.14 2011/03/06 19:57:11 acg
+// Andy Goodrich: refinements for the illegal suspend - synchronous reset
+// interaction.
+//
+// Revision 1.13 2011/03/06 15:56:29 acg
+// Andy Goodrich: added process control corner case error message, remove
+// unused messages.
+//
+// Revision 1.12 2011/03/05 19:44:20 acg
+// Andy Goodrich: changes for object and event naming and structures.
+//
+// Revision 1.11 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.10 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.9 2011/02/13 21:29:16 acg
+// Andy Goodrich: added error messages for throws that occur before
+// simulator intialization.
+//
+// Revision 1.8 2011/02/11 13:25:24 acg
+// Andy Goodrich: Philipp A. Hartmann's changes:
+// (1) Removal of SC_CTHREAD method overloads.
+// (2) New exception processing code.
+//
+// Revision 1.7 2011/02/07 19:17:20 acg
+// Andy Goodrich: changes for IEEE 1666 compatibility.
+//
+// Revision 1.6 2011/01/19 23:21:50 acg
+// Andy Goodrich: changes for IEEE 1666 2011
+//
+// Revision 1.5 2010/07/30 05:21:22 acg
+// Andy Goodrich: release 2.3 fixes.
+//
+// Revision 1.4 2009/02/28 00:26:58 acg
+// Andy Goodrich: changed boost name space to sc_boost to allow use with
+// full boost library applications.
+//
+// Revision 1.3 2008/11/17 15:57:15 acg
+// Andy Goodrich: added deprecation message for sc_module(const char*)
+//
+// Revision 1.2 2008/05/22 17:06:25 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.7 2006/08/29 23:37:13 acg
+// Andy Goodrich: Added check for negative time.
+//
+// Revision 1.6 2006/04/20 17:08:16 acg
+// Andy Goodrich: 3.0 style process changes.
+//
+// Revision 1.5 2006/01/25 00:31:19 acg
+// Andy Goodrich: Changed over to use a standard message id of
+// SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
+//
+// Revision 1.4 2006/01/24 20:49:04 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_macros.h b/ext/systemc/src/sysc/kernel/sc_macros.h
new file mode 100644
index 000000000..baa6d6e3b
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_macros.h
@@ -0,0 +1,136 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_macros.h -- Miscellaneous definitions that are needed by the headers.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_MACROS_H
+#define SC_MACROS_H
+
+
+namespace sc_dt {
+
+template <class T>
+inline
+const T
+sc_min( const T& a, const T& b )
+{
+ return ( ( a <= b ) ? a : b );
+}
+
+template <class T>
+inline
+const T
+sc_max( const T& a, const T& b )
+{
+ return ( ( a >= b ) ? a : b );
+}
+
+template <class T>
+inline
+const T
+sc_abs( const T& a )
+{
+ // return ( a >= 0 ? a : -a );
+ // the code below is functionaly the same as the code above; the
+ // difference is that the code below works for all arithmetic
+ // SystemC datatypes.
+ T z( a );
+ z = 0;
+ if( a >= z ) {
+ return a;
+ } else {
+ T c( a );
+ c = -a;
+ return c;
+ }
+}
+
+} // namespace sc_dt
+
+namespace sc_core {
+
+// token stringification
+
+#define SC_STRINGIFY_HELPER_( Arg ) \
+ SC_STRINGIFY_HELPER_DEFERRED_( Arg )
+#define SC_STRINGIFY_HELPER_DEFERRED_( Arg ) \
+ SC_STRINGIFY_HELPER_MORE_DEFERRED_( Arg )
+#define SC_STRINGIFY_HELPER_MORE_DEFERRED_( Arg ) \
+ #Arg
+
+
+// token concatenation
+
+#define SC_CONCAT_HELPER_( a, b ) \
+ SC_CONCAT_HELPER_DEFERRED_( a, b )
+#define SC_CONCAT_HELPER_DEFERRED_( a, b ) \
+ SC_CONCAT_HELPER_MORE_DEFERRED_( a,b )
+#define SC_CONCAT_HELPER_MORE_DEFERRED_( a, b ) \
+ a ## b
+#define SC_CONCAT_UNDERSCORE_( a, b ) \
+ SC_CONCAT_HELPER_( a, SC_CONCAT_HELPER_( _, b ) )
+
+/*
+ * These help debugging --
+ * -- user can find out where each process is stopped at.
+ */
+
+#define WAIT() \
+ ::sc_core::sc_set_location( __FILE__, __LINE__ ); \
+ ::sc_core::wait()
+
+#define WAITN(n) \
+ ::sc_core::sc_set_location( __FILE__, __LINE__ ); \
+ ::sc_core::wait(n)
+
+#define WAIT_UNTIL(expr) \
+ ::sc_core::sc_set_location( __FILE__, __LINE__ ); \
+ do { ::sc_core::wait(); } while( !(expr) )
+
+} // namespace sc_core
+
+// $Log: sc_macros.h,v $
+// Revision 1.5 2011/08/26 20:46:09 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.2 2008/05/22 17:06:25 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+
+#endif
diff --git a/ext/systemc/src/sysc/kernel/sc_main.cpp b/ext/systemc/src/sysc/kernel/sc_main.cpp
new file mode 100644
index 000000000..a5f780d70
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_main.cpp
@@ -0,0 +1,58 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_main.cpp - Wrapper around user's toplevel routine `sc_main'.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG APPEARS AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#include "sysc/kernel/sc_cmnhdr.h"
+#include "sysc/kernel/sc_externs.h"
+
+int
+main( int argc, char* argv[] )
+{
+ return sc_core::sc_elab_and_sim( argc, argv );
+}
+
+// $Log: sc_main.cpp,v $
+// Revision 1.5 2011/08/26 20:46:09 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.2 2008/05/22 17:06:25 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
diff --git a/ext/systemc/src/sysc/kernel/sc_main_main.cpp b/ext/systemc/src/sysc/kernel/sc_main_main.cpp
new file mode 100644
index 000000000..1cdf1eb49
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_main_main.cpp
@@ -0,0 +1,167 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_main_main.cpp - Wrapper around user's toplevel routine `sc_main'.
+
+ Original Author: Andy Goodrich, Forte Design Systems
+
+ CHANGE LOG APPEARS AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#include "sysc/kernel/sc_cmnhdr.h"
+#include "sysc/kernel/sc_externs.h"
+#include "sysc/kernel/sc_except.h"
+#include "sysc/utils/sc_iostream.h"
+#include "sysc/utils/sc_report.h"
+#include "sysc/utils/sc_report_handler.h"
+#include "sysc/utils/sc_utils_ids.h"
+#include <vector>
+
+namespace sc_core {
+
+extern void pln();
+
+static int argc_copy; // Copy of argc value passed to sc_elab_and_sim.
+static char** argv_copy; // Copy of argv value passed to sc_elab_and_sim.
+
+static
+inline
+void
+message_function( const char* s )
+{
+ ::std::cout << "\n" << s << ::std::endl;
+}
+
+bool sc_in_action = false;
+
+int sc_argc()
+{
+ return argc_copy;
+}
+
+const char* const* sc_argv()
+{
+ return argv_copy;
+}
+
+
+int
+sc_elab_and_sim( int argc, char* argv[] )
+{
+ int status = 1;
+ argc_copy = argc;
+ argv_copy = argv;
+ std::vector<char*> argv_call;
+ for ( int i = 0; i < argc; i++ )
+ argv_call.push_back(argv[i]);
+
+ try
+ {
+ pln();
+
+ // Perform initialization here
+ sc_in_action = true;
+
+ status = sc_main( argc, &argv_call[0] );
+
+ // Perform cleanup here
+ sc_in_action = false;
+ }
+ catch( const sc_report& x )
+ {
+ message_function( x.what() );
+ }
+ catch( ... )
+ {
+ // translate other escaping exceptions
+ sc_report* err_p = sc_handle_exception();
+ if( err_p ) message_function( err_p->what() );
+ delete err_p;
+ }
+
+ // IF DEPRECATION WARNINGS WERE ISSUED TELL THE USER HOW TO TURN THEM OFF
+
+ if ( sc_report_handler::get_count( SC_ID_IEEE_1666_DEPRECATION_ ) > 0 )
+ {
+ std::stringstream ss;
+
+# define MSGNL "\n "
+# define CODENL "\n "
+
+ ss <<
+ "You can turn off warnings about" MSGNL
+ "IEEE 1666 deprecated features by placing this method call" MSGNL
+ "as the first statement in your sc_main() function:\n" CODENL
+ "sc_core::sc_report_handler::set_actions( "
+ "\"" << SC_ID_IEEE_1666_DEPRECATION_ << "\"," CODENL
+ " " /* indent param */
+ "sc_core::SC_DO_NOTHING );"
+ << std::endl;
+
+ SC_REPORT_INFO( SC_ID_IEEE_1666_DEPRECATION_, ss.str().c_str() );
+ }
+
+ return status;
+}
+
+} // namespace sc_core
+
+// $Log: sc_main_main.cpp,v $
+// Revision 1.9 2011/08/26 20:46:10 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.8 2011/05/09 04:07:48 acg
+// Philipp A. Hartmann:
+// (1) Restore hierarchy in all phase callbacks.
+// (2) Ensure calls to before_end_of_elaboration.
+//
+// Revision 1.7 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.6 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.5 2010/03/15 18:29:25 acg
+// Andy Goodrich: Changed the default stack size to 128K from 64K.
+//
+// Revision 1.4 2009/10/14 19:06:48 acg
+// Andy Goodrich: changed the way the "copy" of argv is handled. It is
+// now passed to sc_main, and the original is referenced via argv_copy.
+//
+// Revision 1.3 2008/05/22 17:06:25 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.2 2008/04/11 20:41:28 acg
+// Andy Goodrich: changed the return value in sc_elab_and_sim() to be 1
+// when an exception occurs in sc_main() rather than 0.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.4 2006/01/25 00:31:19 acg
+// Andy Goodrich: Changed over to use a standard message id of
+// SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
diff --git a/ext/systemc/src/sysc/kernel/sc_method_process.cpp b/ext/systemc/src/sysc/kernel/sc_method_process.cpp
new file mode 100644
index 000000000..994e495ad
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_method_process.cpp
@@ -0,0 +1,1023 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_method_process.cpp -- Method process implementation
+
+ Original Author: Andy Goodrich, Forte Design Systems, 4 August 2005
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include "sysc/kernel/sc_method_process.h"
+#include "sysc/kernel/sc_simcontext_int.h"
+#include "sysc/kernel/sc_module.h"
+#include "sysc/kernel/sc_spawn_options.h"
+
+// DEBUGGING MACROS:
+//
+// DEBUG_MSG(NAME,P,MSG)
+// MSG = message to print
+// NAME = name that must match the process for the message to print, or
+// null if the message should be printed unconditionally.
+// P = pointer to process message is for, or NULL in which case the
+// message will not print.
+#if 0
+# define DEBUG_NAME ""
+# define DEBUG_MSG(NAME,P,MSG) \
+ { \
+ if ( P && ( (strlen(NAME)==0) || !strcmp(NAME,P->name())) ) \
+ std::cout << "**** " << sc_time_stamp() << " (" \
+ << sc_get_current_process_name() << "): " << MSG \
+ << " - " << P->name() << std::endl; \
+ }
+#else
+# define DEBUG_MSG(NAME,P,MSG)
+#endif
+
+namespace sc_core {
+
+// +----------------------------------------------------------------------------
+// |"sc_method_process::check_for_throws"
+// |
+// | This method checks to see if this method process should throw an exception
+// | or not. It is called from sc_simcontext::preempt_with() to see if the
+// | thread that was executed during the preemption did a kill or other
+// | manipulation on this object instance that requires it to throw an
+// | exception.
+// +----------------------------------------------------------------------------
+void sc_method_process::check_for_throws()
+{
+ if ( !m_unwinding )
+ {
+ switch( m_throw_status )
+ {
+ case THROW_ASYNC_RESET:
+ simcontext()->preempt_with(this);
+ break;
+ case THROW_KILL:
+ throw sc_unwind_exception( this, false );
+ default:
+ break;
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_method_process::clear_trigger"
+//
+// This method clears any pending trigger for this object instance.
+//------------------------------------------------------------------------------
+void sc_method_process::clear_trigger()
+{
+ switch( m_trigger_type ) {
+ case STATIC:
+ return;
+ case EVENT:
+ m_event_p->remove_dynamic( this );
+ m_event_p = 0;
+ break;
+ case OR_LIST:
+ m_event_list_p->remove_dynamic( this, 0 );
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ break;
+ case AND_LIST:
+ m_event_list_p->remove_dynamic( this, 0 );
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ m_event_count = 0;
+ break;
+ case TIMEOUT:
+ m_timeout_event_p->cancel();
+ m_timeout_event_p->reset();
+ break;
+ case EVENT_TIMEOUT:
+ m_timeout_event_p->cancel();
+ m_timeout_event_p->reset();
+ m_event_p->remove_dynamic( this );
+ m_event_p = 0;
+ break;
+ case OR_LIST_TIMEOUT:
+ m_timeout_event_p->cancel();
+ m_timeout_event_p->reset();
+ m_event_list_p->remove_dynamic( this, 0 );
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ break;
+ case AND_LIST_TIMEOUT:
+ m_timeout_event_p->cancel();
+ m_timeout_event_p->reset();
+ m_event_list_p->remove_dynamic( this, 0 );
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ m_event_count = 0;
+ break;
+ }
+ m_trigger_type = STATIC;
+}
+
+//------------------------------------------------------------------------------
+//"sc_method_process::disable_process"
+//
+// This virtual method disables this process and its children if requested to.
+// descendants = indicator of whether this process' children should also
+// be suspended
+//------------------------------------------------------------------------------
+void sc_method_process::disable_process(
+ sc_descendant_inclusion_info descendants )
+{
+
+ // IF NEEDED PROPOGATE THE SUSPEND REQUEST THROUGH OUR DESCENDANTS:
+
+ if ( descendants == SC_INCLUDE_DESCENDANTS )
+ {
+ const std::vector<sc_object*>& children = get_child_objects();
+ int child_n = children.size();
+
+ for ( int child_i = 0; child_i < child_n; child_i++ )
+ {
+ sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]);
+ if ( child_p ) child_p->disable_process(descendants);
+ }
+ }
+
+ // DON'T ALLOW CORNER CASE BY DEFAULT:
+
+ if ( !sc_allow_process_control_corners )
+ {
+ switch( m_trigger_type )
+ {
+ case AND_LIST_TIMEOUT:
+ case EVENT_TIMEOUT:
+ case OR_LIST_TIMEOUT:
+ case TIMEOUT:
+ report_error( SC_ID_PROCESS_CONTROL_CORNER_CASE_,
+ "attempt to disable a method with timeout wait" );
+ break;
+ default:
+ break;
+ }
+ }
+
+ // DISABLE OUR OBJECT INSTANCE:
+
+ m_state = m_state | ps_bit_disabled;
+
+ // IF THIS CALL IS BEFORE THE SIMULATION DON'T RUN THE METHOD:
+
+ if ( !sc_is_running() )
+ {
+ sc_get_curr_simcontext()->remove_runnable_method(this);
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_method_process::enable_process"
+//
+// This method enables the execution of this process, and if requested, its
+// descendants. If the process was suspended and has a resumption pending it
+// will be dispatched in the next delta cycle. Otherwise the state will be
+// adjusted to indicate it is no longer suspended, but no immediate execution
+// will occur.
+//------------------------------------------------------------------------------
+void sc_method_process::enable_process(
+ sc_descendant_inclusion_info descendants )
+{
+
+ // IF NEEDED PROPOGATE THE RESUME REQUEST THROUGH OUR DESCENDANTS:
+
+ if ( descendants == SC_INCLUDE_DESCENDANTS )
+ {
+ const std::vector<sc_object*>& children = get_child_objects();
+ int child_n = children.size();
+
+ for ( int child_i = 0; child_i < child_n; child_i++ )
+ {
+ sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]);
+ if ( child_p ) child_p->enable_process(descendants);
+ }
+ }
+
+ // ENABLE THIS OBJECT INSTANCE:
+ //
+ // If it was disabled and ready to run then put it on the run queue.
+
+ m_state = m_state & ~ps_bit_disabled;
+ if ( m_state == ps_bit_ready_to_run )
+ {
+ m_state = ps_normal;
+ if ( next_runnable() == 0 )
+ simcontext()->push_runnable_method(this);
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_method_process::kill_process"
+//
+// This method removes throws a kill for this object instance. It calls the
+// sc_process_b::kill_process() method to perform low level clean up.
+//------------------------------------------------------------------------------
+void sc_method_process::kill_process(sc_descendant_inclusion_info descendants)
+{
+
+ // IF THE SIMULATION HAS NOT BEEN INITIALIZED YET THAT IS AN ERROR:
+
+ if ( sc_get_status() == SC_ELABORATION )
+ {
+ report_error( SC_ID_KILL_PROCESS_WHILE_UNITIALIZED_ );
+ }
+
+ // IF NEEDED, PROPOGATE THE KILL REQUEST THROUGH OUR DESCENDANTS:
+
+ if ( descendants == SC_INCLUDE_DESCENDANTS )
+ {
+ const std::vector<sc_object*> children = get_child_objects();
+ int child_n = children.size();
+
+ for ( int child_i = 0; child_i < child_n; child_i++ )
+ {
+ sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]);
+ if ( child_p ) child_p->kill_process(descendants);
+ }
+ }
+
+ // IF THE PROCESS IS CURRENTLY UNWINDING OR IS ALREADY A ZOMBIE
+ // IGNORE THE KILL:
+
+ if ( m_unwinding )
+ {
+ SC_REPORT_WARNING( SC_ID_PROCESS_ALREADY_UNWINDING_, name() );
+ return;
+ }
+
+ if ( m_state & ps_bit_zombie )
+ return;
+
+
+ // REMOVE OUR PROCESS FROM EVENTS, ETC., AND IF ITS THE ACTIVE PROCESS
+ // THROW ITS KILL.
+ //
+ // Note we set the throw status to kill regardless if we throw or not.
+ // That lets check_for_throws stumble across it if we were in the call
+ // chain when the kill call occurred.
+
+ if ( next_runnable() != 0 )
+ simcontext()->remove_runnable_method( this );
+ disconnect_process();
+
+ m_throw_status = THROW_KILL;
+ if ( sc_get_current_process_b() == this )
+ {
+ throw sc_unwind_exception( this, false );
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_method_process::sc_method_process"
+//
+// This is the object instance constructor for this class.
+//------------------------------------------------------------------------------
+sc_method_process::sc_method_process( const char* name_p,
+ bool free_host, SC_ENTRY_FUNC method_p,
+ sc_process_host* host_p, const sc_spawn_options* opt_p
+):
+ sc_process_b(
+ name_p ? name_p : sc_gen_unique_name("method_p"),
+ false, free_host, method_p, host_p, opt_p),
+ m_cor(0), m_stack_size(0), m_monitor_q()
+{
+
+ // CHECK IF THIS IS AN sc_module-BASED PROCESS AND SIMUALTION HAS STARTED:
+
+ if ( DCAST<sc_module*>(host_p) != 0 && sc_is_running() )
+ {
+ report_error( SC_ID_MODULE_METHOD_AFTER_START_, "" );
+ }
+
+ // INITIALIZE VALUES:
+ //
+ // If there are spawn options use them.
+
+ m_process_kind = SC_METHOD_PROC_;
+ if (opt_p) {
+ m_dont_init = opt_p->m_dont_initialize;
+
+ // traverse event sensitivity list
+ for (unsigned int i = 0; i < opt_p->m_sensitive_events.size(); i++) {
+ sc_sensitive::make_static_sensitivity(
+ this, *opt_p->m_sensitive_events[i]);
+ }
+
+ // traverse port base sensitivity list
+ for ( unsigned int i = 0; i < opt_p->m_sensitive_port_bases.size(); i++)
+ {
+ sc_sensitive::make_static_sensitivity(
+ this, *opt_p->m_sensitive_port_bases[i]);
+ }
+
+ // traverse interface sensitivity list
+ for ( unsigned int i = 0; i < opt_p->m_sensitive_interfaces.size(); i++)
+ {
+ sc_sensitive::make_static_sensitivity(
+ this, *opt_p->m_sensitive_interfaces[i]);
+ }
+
+ // traverse event finder sensitivity list
+ for ( unsigned int i = 0; i < opt_p->m_sensitive_event_finders.size();
+ i++)
+ {
+ sc_sensitive::make_static_sensitivity(
+ this, *opt_p->m_sensitive_event_finders[i]);
+ }
+
+ // process any reset signal specification:
+
+ opt_p->specify_resets();
+ }
+
+ else
+ {
+ m_dont_init = false;
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_method_process::sc_method_process"
+//
+// This is the object instance destructor for this class.
+//------------------------------------------------------------------------------
+sc_method_process::~sc_method_process()
+{
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_method_process::suspend_process"
+//
+// This virtual method suspends this process and its children if requested to.
+// descendants = indicator of whether this process' children should also
+// be suspended
+//------------------------------------------------------------------------------
+void sc_method_process::suspend_process(
+ sc_descendant_inclusion_info descendants )
+{
+
+ // IF NEEDED PROPOGATE THE SUSPEND REQUEST THROUGH OUR DESCENDANTS:
+
+ if ( descendants == SC_INCLUDE_DESCENDANTS )
+ {
+ const std::vector<sc_object*>& children = get_child_objects();
+ int child_n = children.size();
+
+ for ( int child_i = 0; child_i < child_n; child_i++ )
+ {
+ sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]);
+ if ( child_p ) child_p->suspend_process(descendants);
+ }
+ }
+
+ // CORNER CASE CHECKS, THE FOLLOWING ARE ERRORS:
+ // (a) if this method has a reset_signal_is specification
+ // (b) if this method is in synchronous reset
+
+ if ( !sc_allow_process_control_corners && m_has_reset_signal )
+ {
+ report_error(SC_ID_PROCESS_CONTROL_CORNER_CASE_,
+ "attempt to suspend a method that has a reset signal");
+ }
+ else if ( !sc_allow_process_control_corners && m_sticky_reset )
+ {
+ report_error(SC_ID_PROCESS_CONTROL_CORNER_CASE_,
+ "attempt to suspend a method in synchronous reset");
+ }
+
+ // SUSPEND OUR OBJECT INSTANCE:
+ //
+ // (1) If we are on the runnable queue then set suspended and ready_to_run,
+ // and remove ourselves from the run queue.
+ // (2) If this is a self-suspension then a resume should cause immediate
+ // scheduling of the process.
+
+ m_state = m_state | ps_bit_suspended;
+ if ( next_runnable() != 0 )
+ {
+ m_state = m_state | ps_bit_ready_to_run;
+ simcontext()->remove_runnable_method( this );
+ }
+ if ( sc_get_current_process_b() == DCAST<sc_process_b*>(this) )
+ {
+ m_state = m_state | ps_bit_ready_to_run;
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_method_process::resume_process"
+//
+// This method resumes the execution of this process, and if requested, its
+// descendants. If the process was suspended and has a resumption pending it
+// will be dispatched in the next delta cycle. Otherwise the state will be
+// adjusted to indicate it is no longer suspended, but no immediate execution
+// will occur.
+//------------------------------------------------------------------------------
+void sc_method_process::resume_process(
+ sc_descendant_inclusion_info descendants )
+{
+
+ // IF NEEDED PROPOGATE THE RESUME REQUEST THROUGH OUR DESCENDANTS:
+
+ if ( descendants == SC_INCLUDE_DESCENDANTS )
+ {
+ const std::vector<sc_object*>& children = get_child_objects();
+ int child_n = children.size();
+
+ for ( int child_i = 0; child_i < child_n; child_i++ )
+ {
+ sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]);
+ if ( child_p ) child_p->resume_process(descendants);
+ }
+ }
+
+
+ // BY DEFAULT THE CORNER CASE IS AN ERROR:
+
+ if ( !sc_allow_process_control_corners && (m_state & ps_bit_disabled) &&
+ (m_state & ps_bit_suspended) )
+ {
+ m_state = m_state & ~ps_bit_suspended;
+ report_error( SC_ID_PROCESS_CONTROL_CORNER_CASE_,
+ "call to resume() on a disabled suspended method");
+ }
+
+ // CLEAR THE SUSPENDED BIT:
+
+ m_state = m_state & ~ps_bit_suspended;
+
+ // RESUME OBJECT INSTANCE:
+ //
+ // If this is not a self-resume and the method is ready to run then
+ // put it on the runnable queue.
+
+ if ( m_state & ps_bit_ready_to_run )
+ {
+ m_state = m_state & ~ps_bit_ready_to_run;
+ if ( next_runnable() == 0 &&
+ ( sc_get_current_process_b() != DCAST<sc_process_b*>(this) ) )
+ {
+ simcontext()->push_runnable_method(this);
+ remove_dynamic_events();
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_method_process::throw_reset"
+//
+// This virtual method is invoked to "throw" a reset.
+//
+// If the reset is synchronous this is a no-op, except for triggering the
+// reset event if it is present.
+//
+// If the reset is asynchronous we:
+// (a) cancel any dynamic waits
+// (b) if it is the active process actually throw a reset exception.
+// (c) if it was not the active process and does not have a static
+// sensitivity emit an error if corner cases are to be considered
+// errors.
+//
+// Notes:
+// (1) If the process had a reset event it will have been triggered in
+// sc_process_b::semantics()
+//
+// Arguments:
+// async = true if this is an asynchronous reset.
+//------------------------------------------------------------------------------
+void sc_method_process::throw_reset( bool async )
+{
+ // IF THE PROCESS IS CURRENTLY UNWINDING OR IS ALREADY A ZOMBIE
+ // IGNORE THE RESET:
+
+ if ( m_unwinding )
+ {
+ SC_REPORT_WARNING( SC_ID_PROCESS_ALREADY_UNWINDING_, name() );
+ return;
+ }
+
+ if ( m_state & ps_bit_zombie )
+ return;
+
+ // Set the throw status and if its an asynchronous reset throw an
+ // exception:
+
+ m_throw_status = async ? THROW_ASYNC_RESET : THROW_SYNC_RESET;
+ if ( async )
+ {
+ remove_dynamic_events();
+ if ( sc_get_current_process_b() == this )
+ {
+ DEBUG_MSG(DEBUG_NAME,this,"throw_reset: throwing exception");
+ m_throw_status = THROW_ASYNC_RESET;
+ throw sc_unwind_exception( this, true );
+ }
+ else
+ {
+ DEBUG_MSG(DEBUG_NAME,this,
+ "throw_reset: queueing this method for execution");
+ simcontext()->preempt_with(this);
+ }
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_method_process::throw_user"
+//
+// This virtual method is invoked when a user exception is to be thrown.
+// If requested it will also throw the exception to the children of this
+// object instance. Since this is a method no throw will occur for this
+// object instance. The children will be awakened from youngest child to
+// eldest.
+// helper_p -> object to use to throw the exception.
+// descendants = indicator of whether this process' children should also
+// be suspended
+//------------------------------------------------------------------------------
+void sc_method_process::throw_user( const sc_throw_it_helper& helper,
+ sc_descendant_inclusion_info descendants )
+{
+
+ // IF THE SIMULATION IS NOT ACTUALLY RUNNING THIS IS AN ERROR:
+
+ if ( sc_get_status() != SC_RUNNING )
+ {
+ report_error( SC_ID_THROW_IT_WHILE_NOT_RUNNING_ );
+ }
+
+ // IF NEEDED PROPOGATE THE THROW REQUEST THROUGH OUR DESCENDANTS:
+
+ if ( descendants == SC_INCLUDE_DESCENDANTS )
+ {
+ const std::vector<sc_object*> children = get_child_objects();
+ int child_n = children.size();
+
+ for ( int child_i = 0; child_i < child_n; child_i++ )
+ {
+ sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]);
+ if ( child_p )
+ {
+ DEBUG_MSG(DEBUG_NAME,child_p,"about to throw user on");
+ child_p->throw_user(helper, descendants);
+ }
+ }
+ }
+
+#if 0 // shouldn't we throw, if we're currently running?
+
+ if ( sc_get_current_process_b() == (sc_process_b*)this )
+ {
+ remove_dynamic_events();
+ m_throw_status = THROW_USER;
+ if ( m_throw_helper_p != 0 ) delete m_throw_helper_p;
+ m_throw_helper_p = helper.clone();
+ m_throw_helper_p->throw_it();
+ }
+
+ // throw_it HAS NO EFFECT ON A METHOD, ISSUE A WARNING:
+
+ else
+
+#endif
+ {
+ SC_REPORT_WARNING( SC_ID_THROW_IT_IGNORED_, name() );
+ }
+
+
+}
+
+//------------------------------------------------------------------------------
+//"sc_method_process::trigger_dynamic"
+//
+// This method sets up a dynamic trigger on an event.
+//
+// Notes:
+// (1) This method is identical to sc_thread_process::trigger_dynamic(),
+// but they cannot be combined as sc_process_b::trigger_dynamic()
+// because the signatures things like sc_event::remove_dynamic()
+// have different overloads for sc_method_process* and sc_thread_process*.
+// So if you change code here you'll also need to change it in
+// sc_thread_process.cpp.
+//
+// Result is true if this process should be removed from the event's list,
+// false if not.
+//
+// If the triggering process is the same process, the trigger is
+// ignored as well, unless SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS
+// is defined.
+//------------------------------------------------------------------------------
+bool sc_method_process::trigger_dynamic( sc_event* e )
+{
+ // No time outs yet, and keep gcc happy.
+
+ m_timed_out = false;
+
+ // Escape cases:
+ // (a) If this method issued the notify() don't schedule it for
+ // execution, but leave the sensitivity in place.
+ // (b) If this method is already runnable can't trigger an event.
+
+#if ! defined( SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS )
+ if( SC_UNLIKELY_( sc_get_current_process_b() == this ) )
+ {
+ report_immediate_self_notification();
+ return false;
+ }
+#endif // SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS
+
+ if( is_runnable() )
+ return true;
+
+ // If a process is disabled then we ignore any events, leaving them enabled:
+ //
+ // But if this is a time out event we need to remove both it and the
+ // event that was being waited for.
+
+ if ( m_state & ps_bit_disabled )
+ {
+ if ( e == m_timeout_event_p )
+ {
+ remove_dynamic_events( true );
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+
+ // Process based on the event type and current process state:
+ //
+ // Every case needs to set 'rc' and continue on to the end of
+ // this method to allow suspend processing to work correctly.
+
+ switch( m_trigger_type )
+ {
+ case EVENT:
+ m_event_p = 0;
+ m_trigger_type = STATIC;
+ break;
+
+ case AND_LIST:
+ -- m_event_count;
+ if ( m_event_count == 0 )
+ {
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ m_trigger_type = STATIC;
+ }
+ else
+ {
+ return true;
+ }
+ break;
+
+ case OR_LIST:
+ m_event_list_p->remove_dynamic( this, e );
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ m_trigger_type = STATIC;
+ break;
+
+ case TIMEOUT:
+ m_trigger_type = STATIC;
+ break;
+
+ case EVENT_TIMEOUT:
+ if ( e == m_timeout_event_p )
+ {
+ m_timed_out = true;
+ m_event_p->remove_dynamic( this );
+ m_event_p = 0;
+ m_trigger_type = STATIC;
+ }
+ else
+ {
+ m_timeout_event_p->cancel();
+ m_timeout_event_p->reset();
+ m_event_p = 0;
+ m_trigger_type = STATIC;
+ }
+ break;
+
+ case OR_LIST_TIMEOUT:
+ if ( e == m_timeout_event_p )
+ {
+ m_timed_out = true;
+ m_event_list_p->remove_dynamic( this, e );
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ m_trigger_type = STATIC;
+ }
+
+ else
+ {
+ m_timeout_event_p->cancel();
+ m_timeout_event_p->reset();
+ m_event_list_p->remove_dynamic( this, e );
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ m_trigger_type = STATIC;
+ }
+ break;
+
+ case AND_LIST_TIMEOUT:
+ if ( e == m_timeout_event_p )
+ {
+ m_timed_out = true;
+ m_event_list_p->remove_dynamic( this, e );
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ m_trigger_type = STATIC;
+ }
+
+ else
+ {
+ -- m_event_count;
+ if ( m_event_count == 0 )
+ {
+ m_timeout_event_p->cancel();
+ m_timeout_event_p->reset();
+ // no need to remove_dynamic
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ m_trigger_type = STATIC;
+ }
+ else
+ {
+ return true;
+ }
+ }
+ break;
+
+ case STATIC: {
+ // we should never get here, but throw_it() can make it happen.
+ SC_REPORT_WARNING(SC_ID_NOT_EXPECTING_DYNAMIC_EVENT_NOTIFY_, name());
+ return true;
+ }
+ }
+
+ // If we get here then the method has satisfied its next_trigger, if its
+ // suspended mark its state as ready to run. If its not suspended then push
+ // it onto the runnable queue.
+
+ if ( (m_state & ps_bit_suspended) )
+ {
+ m_state = m_state | ps_bit_ready_to_run;
+ }
+ else
+ {
+ simcontext()->push_runnable_method(this);
+ }
+
+ return true;
+}
+
+} // namespace sc_core
+
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_method_process.cpp,v $
+// Revision 1.49 2011/08/29 18:24:47 acg
+// Andy Goodrich: remove temporary comment flagging new preempt_with() call.
+//
+// Revision 1.48 2011/08/29 18:04:32 acg
+// Philipp A. Hartmann: miscellaneous clean ups.
+//
+// Revision 1.47 2011/08/24 22:05:50 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.46 2011/08/07 19:08:04 acg
+// Andy Goodrich: moved logs to end of file so line number synching works
+// better between versions.
+//
+// Revision 1.45 2011/07/29 22:42:45 acg
+// Andy Goodrich: added check_for_throws() to fix case where a method is
+// deleted by a process it resets or kills so that it can throw itself.
+// Philipp A. Hartmann: changes to handle case where a process control
+// invocation on a child process causes the list of child processes to change.
+//
+// Revision 1.44 2011/07/24 11:27:04 acg
+// Andy Goodrich: moved the check for unwinding processes until after the
+// descendants have been processed in throw_user and kill.
+//
+// Revision 1.43 2011/07/24 11:20:03 acg
+// Philipp A. Hartmann: process control error message improvements:
+// (1) Downgrade error to warning for re-kills of processes.
+// (2) Add process name to process messages.
+// (3) drop some superfluous colons in messages.
+//
+// Revision 1.42 2011/05/05 17:45:27 acg
+// Philip A. Hartmann: changes in WIN64 support.
+// Andy Goodrich: additional DEBUG_MSG instances to trace process handling.
+//
+// Revision 1.41 2011/04/19 19:15:41 acg
+// Andy Goodrich: fix so warning message is always issued for a throw_it()
+// on a method process.
+//
+// Revision 1.40 2011/04/19 15:04:27 acg
+// Philipp A. Hartmann: clean up SC_ID messages.
+//
+// Revision 1.39 2011/04/19 02:39:09 acg
+// Philipp A. Hartmann: added checks for additional throws during stack unwinds.
+//
+// Revision 1.38 2011/04/13 02:41:34 acg
+// Andy Goodrich: eliminate warning messages generated when the DEBUG_MSG
+// macro is used.
+//
+// Revision 1.37 2011/04/11 22:10:46 acg
+// Andy Goodrich:
+// (1) Add DEBUG_MSG macro and use it to generate a journal of method
+// throws if it is enabled.
+// (2) Trim down to the expected behavior of scheduling a method that
+// is asynchronously reset in anticipation of IEEE 1666 being revised.
+//
+// Revision 1.36 2011/04/10 22:15:29 acg
+// Andy Goodrich: change to call methods on asynchronous reset.
+//
+// Revision 1.35 2011/04/08 22:31:40 acg
+// Andy Goodrich: removed unused code.
+//
+// Revision 1.34 2011/04/08 18:24:07 acg
+// Andy Goodrich: fix asynchronous reset dispatch and when the reset_event()
+// is fired.
+//
+// Revision 1.33 2011/04/05 20:50:56 acg
+// Andy Goodrich:
+// (1) changes to make sure that event(), posedge() and negedge() only
+// return true if the clock has not moved.
+// (2) fixes for method self-resumes.
+// (3) added SC_PRERELEASE_VERSION
+// (4) removed kernel events from the object hierarchy, added
+// sc_hierarchy_name_exists().
+//
+// Revision 1.32 2011/04/01 22:30:39 acg
+// Andy Goodrich: change hard assertion to warning for trigger_dynamic()
+// getting called when there is only STATIC sensitivity. This can result
+// because of sc_process_handle::throw_it().
+//
+// Revision 1.31 2011/03/28 13:02:51 acg
+// Andy Goodrich: Changes for disable() interactions.
+//
+// Revision 1.30 2011/03/23 16:17:52 acg
+// Andy Goodrich: don't emit an error message for a resume on a disabled
+// process that is not suspended.
+//
+// Revision 1.29 2011/03/20 13:43:23 acg
+// Andy Goodrich: added async_signal_is() plus suspend() as a corner case.
+//
+// Revision 1.28 2011/03/08 20:49:30 acg
+// Andy Goodrich: implement coarse checking for synchronous reset - suspend
+// interaction.
+//
+// Revision 1.27 2011/03/08 20:32:28 acg
+// Andy Goodrich: implemented "coarse" checking for undefined process
+// control interactions.
+//
+// Revision 1.26 2011/03/07 18:25:19 acg
+// Andy Goodrich: tightening of check for resume on a disabled process to
+// only produce an error if it is ready to run.
+//
+// Revision 1.25 2011/03/07 17:38:43 acg
+// Andy Goodrich: tightening up of checks for undefined interaction between
+// synchronous reset and suspend.
+//
+// Revision 1.24 2011/03/06 23:30:13 acg
+// Andy Goodrich: refining suspend - sync reset corner case checking so that
+// the following are error situations:
+// (1) Calling suspend on a process with a reset_signal_is() specification
+// or sync_reset_on() is active.
+// (2) Calling sync_reset_on() on a suspended process.
+//
+// Revision 1.23 2011/03/06 19:57:11 acg
+// Andy Goodrich: refinements for the illegal suspend - synchronous reset
+// interaction.
+//
+// Revision 1.22 2011/03/06 16:47:09 acg
+// Andy Goodrich: changes for testing sync_reset - suspend corner cases.
+//
+// Revision 1.21 2011/03/06 15:57:08 acg
+// Andy Goodrich: added process control corner case checks.
+//
+// Revision 1.20 2011/03/05 19:44:20 acg
+// Andy Goodrich: changes for object and event naming and structures.
+//
+// Revision 1.19 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.18 2011/02/17 19:50:43 acg
+// Andy Goodrich:
+// (1) Changed signature of trigger_dynamic back to a bool.
+// (2) Added run queue processing into trigger dynamic.
+// (3) Simplified process control support.
+//
+// Revision 1.17 2011/02/16 22:37:30 acg
+// Andy Goodrich: clean up to remove need for ps_disable_pending.
+//
+// Revision 1.16 2011/02/13 23:09:58 acg
+// Andy Goodrich: only remove dynamic events for asynchronous resets.
+//
+// Revision 1.15 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.14 2011/02/13 21:31:02 acg
+// Andy Goodrich: added error messages for throws when simulator has not
+// been initialized. Added missing remove_dynamic_events() call to the
+// reset code.
+//
+// Revision 1.13 2011/02/11 13:25:24 acg
+// Andy Goodrich: Philipp A. Hartmann's changes:
+// (1) Removal of SC_CTHREAD method overloads.
+// (2) New exception processing code.
+//
+// Revision 1.12 2011/02/07 19:17:20 acg
+// Andy Goodrich: changes for IEEE 1666 compatibility.
+//
+// Revision 1.11 2011/02/04 15:27:36 acg
+// Andy Goodrich: changes for suspend-resume semantics.
+//
+// Revision 1.10 2011/02/01 23:01:53 acg
+// Andy Goodrich: removed dead code.
+//
+// Revision 1.9 2011/02/01 21:05:05 acg
+// Andy Goodrich: Changes in trigger_dynamic methods to handle new
+// process control rules about event sensitivity.
+//
+// Revision 1.8 2011/01/25 20:50:37 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.7 2011/01/18 20:10:44 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.6 2011/01/06 18:02:43 acg
+// Andy Goodrich: added check for ps_disabled to method_dynamic().
+//
+// Revision 1.5 2010/11/20 17:10:56 acg
+// Andy Goodrich: reset processing changes for new IEEE 1666 standard.
+//
+// Revision 1.4 2010/07/22 20:02:33 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.3 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.2 2008/05/22 17:06:25 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.7 2006/04/20 17:08:16 acg
+// Andy Goodrich: 3.0 style process changes.
+//
+// Revision 1.6 2006/04/11 23:13:20 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.5 2006/01/26 21:04:54 acg
+// Andy Goodrich: deprecation message changes and additional messages.
+//
+// Revision 1.4 2006/01/24 20:49:05 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
diff --git a/ext/systemc/src/sysc/kernel/sc_method_process.h b/ext/systemc/src/sysc/kernel/sc_method_process.h
new file mode 100644
index 000000000..00f6e37e7
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_method_process.h
@@ -0,0 +1,467 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_method_process.h -- Method process declarations
+
+ Original Author: Andy Goodrich, Forte Design Systems, 4 August 2005
+
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+// $Log: sc_method_process.h,v $
+// Revision 1.23 2011/09/05 21:20:22 acg
+// Andy Goodrich: result of automake invocation.
+//
+// Revision 1.22 2011/08/29 18:04:32 acg
+// Philipp A. Hartmann: miscellaneous clean ups.
+//
+// Revision 1.21 2011/08/26 20:46:10 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+
+#if !defined(sc_method_process_h_INCLUDED)
+#define sc_method_process_h_INCLUDED
+
+#include "sysc/kernel/sc_process.h"
+#include "sysc/kernel/sc_spawn_options.h"
+#include "sysc/kernel/sc_cor.h"
+#include "sysc/kernel/sc_event.h"
+#include "sysc/kernel/sc_except.h"
+
+
+// DEBUGGING MACROS:
+//
+// DEBUG_MSG(NAME,P,MSG)
+// MSG = message to print
+// NAME = name that must match the process for the message to print, or
+// null if the message should be printed unconditionally.
+// P = pointer to process message is for, or NULL in which case the
+// message will not print.
+#if 0
+# define DEBUG_NAME ""
+# define DEBUG_MSG(NAME,P,MSG) \
+ { \
+ if ( P && ( (strlen(NAME)==0) || !strcmp(NAME,P->name())) ) \
+ std::cout << "**** " << sc_time_stamp() << " (" \
+ << sc_get_current_process_name() << "): " << MSG \
+ << " - " << P->name() << std::endl; \
+ }
+#else
+# define DEBUG_MSG(NAME,P,MSG)
+#endif
+
+
+namespace sc_core {
+
+// forward function and class declarations:
+
+void sc_method_cor_fn( void* );
+void sc_cmethod_cor_fn( void* );
+void sc_set_stack_size( sc_method_handle, std::size_t );
+class sc_event;
+class sc_module;
+class sc_process_table;
+class sc_process_handle;
+class sc_simcontext;
+class sc_runnable;
+
+void next_trigger( sc_simcontext* );
+void next_trigger( const sc_event&, sc_simcontext* );
+void next_trigger( const sc_event_or_list&, sc_simcontext* );
+void next_trigger( const sc_event_and_list&, sc_simcontext* );
+void next_trigger( const sc_time&, sc_simcontext* );
+void next_trigger( const sc_time&, const sc_event&, sc_simcontext* );
+void next_trigger( const sc_time&, const sc_event_or_list&, sc_simcontext* );
+void next_trigger( const sc_time&, const sc_event_and_list&, sc_simcontext* );
+
+struct sc_invoke_method;
+//==============================================================================
+// sc_method_process -
+//
+//==============================================================================
+class sc_method_process : public sc_process_b {
+ friend struct sc_invoke_method;
+ friend void sc_method_cor_fn( void* );
+ friend void sc_cmethod_cor_fn( void* );
+ friend void sc_set_stack_size( sc_method_handle, std::size_t );
+ friend class sc_event;
+ friend class sc_module;
+ friend class sc_process_table;
+ friend class sc_process_handle;
+ friend class sc_simcontext;
+ friend class sc_runnable;
+
+ friend void next_trigger( sc_simcontext* );
+ friend void next_trigger( const sc_event&,
+ sc_simcontext* );
+ friend void next_trigger( const sc_event_or_list&,
+ sc_simcontext* );
+ friend void next_trigger( const sc_event_and_list&,
+ sc_simcontext* );
+ friend void next_trigger( const sc_time&,
+ sc_simcontext* );
+ friend void next_trigger( const sc_time&, const sc_event&,
+ sc_simcontext* );
+ friend void next_trigger( const sc_time&, const sc_event_or_list&,
+ sc_simcontext* );
+ friend void next_trigger( const sc_time&, const sc_event_and_list&,
+ sc_simcontext* );
+
+ public:
+ sc_method_process( const char* name_p, bool free_host,
+ SC_ENTRY_FUNC method_p, sc_process_host* host_p,
+ const sc_spawn_options* opt_p );
+
+ virtual const char* kind() const
+ { return "sc_method_process"; }
+
+ protected:
+ void check_for_throws();
+ virtual void disable_process(
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
+ virtual void enable_process(
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
+ inline bool run_process();
+ virtual void kill_process(
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
+ sc_method_handle next_exist();
+ sc_method_handle next_runnable();
+ void clear_trigger();
+ void next_trigger( const sc_event& );
+ void next_trigger( const sc_event_or_list& );
+ void next_trigger( const sc_event_and_list& );
+ void next_trigger( const sc_time& );
+ void next_trigger( const sc_time&, const sc_event& );
+ void next_trigger( const sc_time&, const sc_event_or_list& );
+ void next_trigger( const sc_time&, const sc_event_and_list& );
+ virtual void resume_process(
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
+ void set_next_exist( sc_method_handle next_p );
+ void set_next_runnable( sc_method_handle next_p );
+ void set_stack_size( std::size_t size );
+ virtual void suspend_process(
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
+ virtual void throw_reset( bool async );
+ virtual void throw_user( const sc_throw_it_helper& helper,
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
+ bool trigger_dynamic( sc_event* );
+ inline void trigger_static();
+
+ protected:
+ sc_cor* m_cor; // Thread's coroutine.
+ std::size_t m_stack_size; // Thread stack size.
+ std::vector<sc_process_monitor*> m_monitor_q; // Thread monitors.
+
+ private:
+ // may not be deleted manually (called from sc_process_b)
+ virtual ~sc_method_process();
+
+ private: // disabled
+ sc_method_process( const sc_method_process& );
+ const sc_method_process& operator = ( const sc_method_process& );
+
+};
+
+inline
+void
+sc_method_process::next_trigger( const sc_event& e )
+{
+ clear_trigger();
+ e.add_dynamic( this );
+ m_event_p = &e;
+ m_trigger_type = EVENT;
+}
+
+inline
+void
+sc_method_process::next_trigger( const sc_event_or_list& el )
+{
+ clear_trigger();
+ el.add_dynamic( this );
+ m_event_list_p = &el;
+ m_trigger_type = OR_LIST;
+}
+
+inline
+void
+sc_method_process::next_trigger( const sc_event_and_list& el )
+{
+ clear_trigger();
+ el.add_dynamic( this );
+ m_event_list_p = &el;
+ m_event_count = el.size();
+ m_trigger_type = AND_LIST;
+}
+
+inline
+void
+sc_method_process::next_trigger( const sc_time& t )
+{
+ clear_trigger();
+ m_timeout_event_p->notify_internal( t );
+ m_timeout_event_p->add_dynamic( this );
+ m_trigger_type = TIMEOUT;
+}
+
+inline
+void
+sc_method_process::next_trigger( const sc_time& t, const sc_event& e )
+{
+ clear_trigger();
+ m_timeout_event_p->notify_internal( t );
+ m_timeout_event_p->add_dynamic( this );
+ e.add_dynamic( this );
+ m_event_p = &e;
+ m_trigger_type = EVENT_TIMEOUT;
+}
+
+inline
+void
+sc_method_process::next_trigger( const sc_time& t, const sc_event_or_list& el )
+{
+ clear_trigger();
+ m_timeout_event_p->notify_internal( t );
+ m_timeout_event_p->add_dynamic( this );
+ el.add_dynamic( this );
+ m_event_list_p = &el;
+ m_trigger_type = OR_LIST_TIMEOUT;
+}
+
+inline
+void
+sc_method_process::next_trigger( const sc_time& t, const sc_event_and_list& el )
+{
+ clear_trigger();
+ m_timeout_event_p->notify_internal( t );
+ m_timeout_event_p->add_dynamic( this );
+ el.add_dynamic( this );
+ m_event_list_p = &el;
+ m_event_count = el.size();
+ m_trigger_type = AND_LIST_TIMEOUT;
+}
+
+inline
+void sc_method_process::set_next_exist(sc_method_handle next_p)
+{
+ m_exist_p = next_p;
+}
+
+inline
+sc_method_handle sc_method_process::next_exist()
+{
+ return (sc_method_handle)m_exist_p;
+}
+
+
+inline
+void sc_method_process::set_next_runnable(sc_method_handle next_p)
+{
+ m_runnable_p = next_p;
+}
+
+inline
+sc_method_handle sc_method_process::next_runnable()
+{
+ return (sc_method_handle)m_runnable_p;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_method_process::run_process"
+// |
+// | This method executes this object instance, including fielding exceptions.
+// |
+// | Result is false if an unfielded exception occurred, true if not.
+// +----------------------------------------------------------------------------
+inline bool sc_method_process::run_process()
+{
+ // Execute this object instance's semantics and catch any exceptions that
+ // are generated:
+
+ bool restart = false;
+ do {
+ try {
+ DEBUG_MSG(DEBUG_NAME,this,"executing method semantics");
+ semantics();
+ restart = false;
+ }
+ catch( sc_unwind_exception& ex ) {
+ DEBUG_MSG(DEBUG_NAME,this,"caught unwind exception");
+ ex.clear();
+ restart = ex.is_reset();
+ }
+ catch( ... ) {
+ sc_report* err_p = sc_handle_exception();
+ simcontext()->set_error( err_p );
+ return false;
+ }
+ } while( restart );
+
+ return true;
+}
+
+//------------------------------------------------------------------------------
+//"sc_method_process::trigger_static"
+//
+// This inline method adds the current method to the queue of runnable
+// processes, if required. This is the case if the following criteria
+// are met:
+// (1) The process is in a runnable state.
+// (2) The process is not already on the run queue.
+// (3) The process is expecting a static trigger,
+// dynamic event waits take priority.
+//
+//
+// If the triggering process is the same process, the trigger is
+// ignored as well, unless SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS
+// is defined.
+//------------------------------------------------------------------------------
+inline
+void
+sc_method_process::trigger_static()
+{
+ if ( (m_state & ps_bit_disabled) || is_runnable() ||
+ m_trigger_type != STATIC )
+ return;
+
+#if ! defined( SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS )
+ if( SC_UNLIKELY_( sc_get_current_process_b() == this ) )
+ {
+ report_immediate_self_notification();
+ return;
+ }
+#endif // SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS
+
+ // If we get here then the method is has satisfied its wait, if its
+ // suspended mark its state as ready to run. If its not suspended then
+ // push it onto the runnable queue.
+
+ if ( m_state & ps_bit_suspended )
+ {
+ m_state = m_state | ps_bit_ready_to_run;
+ }
+ else
+ {
+ simcontext()->push_runnable_method(this);
+ }
+}
+
+#undef DEBUG_MSG
+
+} // namespace sc_core
+
+// Revision 1.20 2011/08/24 22:05:50 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.19 2011/07/29 22:43:15 acg
+// Andy Goodrich: addition of check_for_throws() method.
+//
+// Revision 1.18 2011/07/24 11:18:09 acg
+// Philipp A. Hartmann: add code to restart a method process after a
+// self-reset.
+//
+// Revision 1.17 2011/05/09 04:07:48 acg
+// Philipp A. Hartmann:
+// (1) Restore hierarchy in all phase callbacks.
+// (2) Ensure calls to before_end_of_elaboration.
+//
+// Revision 1.16 2011/04/13 02:41:34 acg
+// Andy Goodrich: eliminate warning messages generated when the DEBUG_MSG
+// macro is used.
+//
+// Revision 1.15 2011/04/10 22:12:32 acg
+// Andy Goodrich: adding debugging macros.
+//
+// Revision 1.14 2011/04/08 22:31:21 acg
+// Andy Goodrich: added new inline method run_process() to hide the process
+// implementation for sc_simcontext.
+//
+// Revision 1.13 2011/04/05 20:50:56 acg
+// Andy Goodrich:
+// (1) changes to make sure that event(), posedge() and negedge() only
+// return true if the clock has not moved.
+// (2) fixes for method self-resumes.
+// (3) added SC_PRERELEASE_VERSION
+// (4) removed kernel events from the object hierarchy, added
+// sc_hierarchy_name_exists().
+//
+// Revision 1.12 2011/04/01 21:24:57 acg
+// Andy Goodrich: removed unused code.
+//
+// Revision 1.11 2011/02/19 08:30:53 acg
+// Andy Goodrich: Moved process queueing into trigger_static from
+// sc_event::notify.
+//
+// Revision 1.10 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.9 2011/02/17 19:51:34 acg
+// Andy Goodrich:
+// (1) Changed the signature of trigger_dynamic back to a bool.
+// (2) Removed ready_to_run().
+// (3) Simplified process control usage.
+//
+// Revision 1.8 2011/02/16 22:37:30 acg
+// Andy Goodrich: clean up to remove need for ps_disable_pending.
+//
+// Revision 1.7 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.6 2011/02/01 21:05:05 acg
+// Andy Goodrich: Changes in trigger_dynamic methods to handle new
+// process control rules about event sensitivity.
+//
+// Revision 1.5 2011/01/18 20:10:44 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.4 2009/07/28 01:10:53 acg
+// Andy Goodrich: updates for 2.3 release candidate.
+//
+// Revision 1.3 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.2 2008/05/22 17:06:25 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.7 2006/05/08 17:57:13 acg
+// Andy Goodrich: Added David Long's forward declarations for friend functions
+// to keep the Microsoft C++ compiler happy.
+//
+// Revision 1.6 2006/04/20 17:08:17 acg
+// Andy Goodrich: 3.0 style process changes.
+//
+// Revision 1.5 2006/04/11 23:13:21 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.4 2006/01/24 20:49:05 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+
+#endif // !defined(sc_method_process_h_INCLUDED)
diff --git a/ext/systemc/src/sysc/kernel/sc_module.cpp b/ext/systemc/src/sysc/kernel/sc_module.cpp
new file mode 100644
index 000000000..efca2a4dc
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_module.cpp
@@ -0,0 +1,846 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_module.cpp -- Base class of all sequential and combinational processes.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#include <cassert>
+#include <math.h>
+#include <stddef.h>
+#include <stdio.h>
+
+#include "sysc/kernel/sc_event.h"
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/kernel/sc_module.h"
+#include "sysc/kernel/sc_module_registry.h"
+#include "sysc/kernel/sc_name_gen.h"
+#include "sysc/kernel/sc_object_manager.h"
+#include "sysc/kernel/sc_process.h"
+#include "sysc/kernel/sc_process_handle.h"
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_simcontext_int.h"
+#include "sysc/kernel/sc_object_int.h"
+#include "sysc/kernel/sc_reset.h"
+#include "sysc/communication/sc_communication_ids.h"
+#include "sysc/communication/sc_interface.h"
+#include "sysc/communication/sc_port.h"
+#include "sysc/communication/sc_signal.h"
+#include "sysc/communication/sc_signal_ports.h"
+#include "sysc/utils/sc_utils_ids.h"
+#include "sysc/utils/sc_iostream.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_module_dynalloc_list
+//
+// Garbage collection for modules dynamically allocated with SC_NEW.
+// ----------------------------------------------------------------------------
+
+class sc_module_dynalloc_list
+{
+public:
+
+ sc_module_dynalloc_list() : m_list()
+ {}
+
+ ~sc_module_dynalloc_list();
+
+ void add( sc_module* p )
+ { m_list.push_back( p ); }
+
+private:
+
+ sc_plist<sc_module*> m_list;
+};
+
+
+//------------------------------------------------------------------------------
+//"~sc_module_dynalloc_list"
+//
+// Note we clear the m_parent field for the module being deleted. This because
+// we process the list front to back so the parent has already been deleted,
+// and we don't want ~sc_object() to try to access the parent which may
+// contain garbage.
+//------------------------------------------------------------------------------
+sc_module_dynalloc_list::~sc_module_dynalloc_list()
+{
+ sc_plist<sc_module*>::iterator it( m_list );
+ while( ! it.empty() ) {
+ (*it)->m_parent = 0;
+ delete *it;
+ it ++;
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+
+sc_module*
+sc_module_dynalloc( sc_module* module_ )
+{
+ static sc_module_dynalloc_list dynalloc_list;
+ dynalloc_list.add( module_ );
+ return module_;
+}
+
+
+// ----------------------------------------------------------------------------
+// STRUCT : sc_bind_proxy
+//
+// Struct for temporarily storing a pointer to an interface or port.
+// Used for positional binding.
+// ----------------------------------------------------------------------------
+
+sc_bind_proxy::sc_bind_proxy()
+: iface( 0 ),
+ port( 0 )
+{}
+
+sc_bind_proxy::sc_bind_proxy( sc_interface& iface_ )
+: iface( &iface_ ),
+ port( 0 )
+{}
+
+sc_bind_proxy::sc_bind_proxy( sc_port_base& port_ )
+: iface( 0 ),
+ port( &port_ )
+{}
+
+
+const sc_bind_proxy SC_BIND_PROXY_NIL;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_module
+//
+// Base class for all structural entities.
+// ----------------------------------------------------------------------------
+
+void
+sc_module::sc_module_init()
+{
+ simcontext()->get_module_registry()->insert( *this );
+ simcontext()->hierarchy_push( this );
+ m_end_module_called = false;
+ m_module_name_p = 0;
+ m_port_vec = new std::vector<sc_port_base*>;
+ m_port_index = 0;
+ m_name_gen = new sc_name_gen;
+}
+
+/*
+ * This form of the constructor assumes that the user has
+ * used an sc_module_name parameter for his/her constructor.
+ * That parameter object has been pushed onto the stack,
+ * and can be looked up by calling the
+ * top_of_module_name_stack() function of the object manager.
+ * This technique has two advantages:
+ *
+ * 1) The user no longer has to write sc_module(name) in the
+ * constructor initializer.
+ * 2) The user no longer has to call end_module() at the end
+ * of the constructor -- a common negligence.
+ *
+ * But it is important to note that sc_module_name may be used
+ * in the user's constructor's parameter. If it is used anywhere
+ * else, unexpected things will happen. The error-checking
+ * mechanism builtin here cannot hope to catch all misuses.
+ *
+ */
+
+sc_module::sc_module()
+: sc_object(::sc_core::sc_get_curr_simcontext()
+ ->get_object_manager()
+ ->top_of_module_name_stack()
+ ->operator const char*()),
+ sensitive(this),
+ sensitive_pos(this),
+ sensitive_neg(this),
+ m_end_module_called(false),
+ m_port_vec(),
+ m_port_index(0),
+ m_name_gen(0),
+ m_module_name_p(0)
+{
+ /* When this form is used, we better have a fresh sc_module_name
+ on the top of the stack */
+ sc_module_name* mod_name =
+ simcontext()->get_object_manager()->top_of_module_name_stack();
+ if (0 == mod_name || 0 != mod_name->m_module_p)
+ SC_REPORT_ERROR( SC_ID_SC_MODULE_NAME_REQUIRED_, 0 );
+ sc_module_init();
+ mod_name->set_module( this );
+ m_module_name_p = mod_name; // must come after sc_module_init call.
+}
+
+sc_module::sc_module( const sc_module_name& )
+: sc_object(::sc_core::sc_get_curr_simcontext()
+ ->get_object_manager()
+ ->top_of_module_name_stack()
+ ->operator const char*()),
+ sensitive(this),
+ sensitive_pos(this),
+ sensitive_neg(this),
+ m_end_module_called(false),
+ m_port_vec(),
+ m_port_index(0),
+ m_name_gen(0),
+ m_module_name_p(0)
+{
+ /* For those used to the old style of passing a name to sc_module,
+ this constructor will reduce the chance of making a mistake */
+
+ /* When this form is used, we better have a fresh sc_module_name
+ on the top of the stack */
+ sc_module_name* mod_name =
+ simcontext()->get_object_manager()->top_of_module_name_stack();
+ if (0 == mod_name || 0 != mod_name->m_module_p)
+ SC_REPORT_ERROR( SC_ID_SC_MODULE_NAME_REQUIRED_, 0 );
+ sc_module_init();
+ mod_name->set_module( this );
+ m_module_name_p = mod_name; // must come after sc_module_init call.
+}
+
+/* --------------------------------------------------------------------
+ *
+ * Deprecated constructors:
+ * sc_module( const char* )
+ * sc_module( const std::string& )
+ */
+sc_module::sc_module( const char* nm )
+: sc_object(nm),
+ sensitive(this),
+ sensitive_pos(this),
+ sensitive_neg(this),
+ m_end_module_called(false),
+ m_port_vec(),
+ m_port_index(0),
+ m_name_gen(0),
+ m_module_name_p(0)
+{
+ SC_REPORT_WARNING( SC_ID_BAD_SC_MODULE_CONSTRUCTOR_, nm );
+ sc_module_init();
+}
+
+sc_module::sc_module( const std::string& s )
+: sc_object( s.c_str() ),
+ sensitive(this),
+ sensitive_pos(this),
+ sensitive_neg(this),
+ m_end_module_called(false),
+ m_port_vec(),
+ m_port_index(0),
+ m_name_gen(0),
+ m_module_name_p(0)
+{
+ SC_REPORT_WARNING( SC_ID_BAD_SC_MODULE_CONSTRUCTOR_, s.c_str() );
+ sc_module_init();
+}
+
+/* -------------------------------------------------------------------- */
+
+sc_module::~sc_module()
+{
+ delete m_port_vec;
+ delete m_name_gen;
+ orphan_child_objects();
+ if ( m_module_name_p )
+ {
+ m_module_name_p->clear_module( this ); // must be before end_module()
+ end_module();
+ }
+ simcontext()->get_module_registry()->remove( *this );
+}
+
+
+const ::std::vector<sc_object*>&
+sc_module::get_child_objects() const
+{
+ return m_child_objects;
+}
+
+// set SC_THREAD asynchronous reset sensitivity
+
+void
+sc_module::async_reset_signal_is( const sc_in<bool>& port, bool level )
+{
+ sc_reset::reset_signal_is(true, port, level);
+}
+
+void
+sc_module::async_reset_signal_is( const sc_inout<bool>& port, bool level )
+{
+ sc_reset::reset_signal_is(true, port, level);
+}
+
+void
+sc_module::async_reset_signal_is( const sc_out<bool>& port, bool level )
+{
+ sc_reset::reset_signal_is(true, port, level);
+}
+
+void
+sc_module::async_reset_signal_is(const sc_signal_in_if<bool>& iface, bool level)
+{
+ sc_reset::reset_signal_is(true, iface, level);
+}
+
+void
+sc_module::end_module()
+{
+ if( ! m_end_module_called ) {
+ /* TBD: Can check here to alert the user that end_module
+ was not called for a previous module. */
+ (void)sc_get_curr_simcontext()->hierarchy_pop();
+ sc_get_curr_simcontext()->reset_curr_proc();
+ sensitive.reset();
+ sensitive_pos.reset();
+ sensitive_neg.reset();
+ m_end_module_called = true;
+ m_module_name_p = 0; // make sure we are not called in ~sc_module().
+ }
+}
+
+
+// to prevent initialization for SC_METHODs and SC_THREADs
+
+void
+sc_module::dont_initialize()
+{
+ sc_process_handle last_proc = sc_get_last_created_process_handle();
+ last_proc.dont_initialize( true );
+}
+
+// set SC_THREAD synchronous reset sensitivity
+
+void
+sc_module::reset_signal_is( const sc_in<bool>& port, bool level )
+{
+ sc_reset::reset_signal_is(false, port, level);
+}
+
+void
+sc_module::reset_signal_is( const sc_inout<bool>& port, bool level )
+{
+ sc_reset::reset_signal_is(false, port, level);
+}
+
+void
+sc_module::reset_signal_is( const sc_out<bool>& port, bool level )
+{
+ sc_reset::reset_signal_is(false, port, level);
+}
+
+void
+sc_module::reset_signal_is( const sc_signal_in_if<bool>& iface, bool level )
+{
+ sc_reset::reset_signal_is(false, iface, level);
+}
+
+// to generate unique names for objects in an MT-Safe way
+
+const char*
+sc_module::gen_unique_name( const char* basename_, bool preserve_first )
+{
+ return m_name_gen->gen_unique_name( basename_, preserve_first );
+}
+
+
+// called by construction_done
+
+void
+sc_module::before_end_of_elaboration()
+{}
+
+// We push the sc_module instance onto the stack of open objects so
+// that any objects that are created in before_end_of_elaboration have
+// the proper parent. After the call we pop the hierarchy.
+void
+sc_module::construction_done()
+{
+ hierarchy_scope scope(this);
+ before_end_of_elaboration();
+}
+
+// called by elaboration_done (does nothing by default)
+
+void
+sc_module::end_of_elaboration()
+{}
+
+
+// We push the sc_module instance onto the stack of open objects so
+// that any objects that are created in end_of_elaboration have
+// the proper parent. After the call we pop the hierarchy.
+void
+sc_module::elaboration_done( bool& error_ )
+{
+ if( ! m_end_module_called ) {
+ char msg[BUFSIZ];
+ std::sprintf( msg, "module '%s'", name() );
+ SC_REPORT_WARNING( SC_ID_END_MODULE_NOT_CALLED_, msg );
+ if( error_ ) {
+ SC_REPORT_WARNING( SC_ID_HIER_NAME_INCORRECT_, 0 );
+ }
+ error_ = true;
+ }
+ hierarchy_scope scope(this);
+ end_of_elaboration();
+}
+
+// called by start_simulation (does nothing by default)
+
+void
+sc_module::start_of_simulation()
+{}
+
+void
+sc_module::start_simulation()
+{
+ hierarchy_scope scope(this);
+ start_of_simulation();
+}
+
+// called by simulation_done (does nothing by default)
+
+void
+sc_module::end_of_simulation()
+{}
+
+void
+sc_module::simulation_done()
+{
+ hierarchy_scope scope(this);
+ end_of_simulation();
+}
+
+void
+sc_module::set_stack_size( std::size_t size )
+{
+ sc_process_handle proc_h(
+ sc_is_running() ?
+ sc_get_current_process_handle() :
+ sc_get_last_created_process_handle()
+ );
+ sc_thread_handle thread_h; // Current process as thread.
+
+
+ thread_h = (sc_thread_handle)proc_h;
+ if ( thread_h )
+ {
+ thread_h->set_stack_size( size );
+ }
+ else
+ {
+ SC_REPORT_WARNING( SC_ID_SET_STACK_SIZE_, 0 );
+ }
+}
+
+
+int
+sc_module::append_port( sc_port_base* port_ )
+{
+ int index = m_port_vec->size();
+ m_port_vec->push_back( port_ );
+ return index;
+}
+
+
+// positional binding methods
+
+static void sc_warn_arrow_arrow_bind()
+{
+ static bool warn_arrow_arrow_bind=true;
+ if ( warn_arrow_arrow_bind )
+ {
+ warn_arrow_arrow_bind = false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "positional binding using << or , is deprecated, use () instead.");
+ }
+}
+
+sc_module&
+sc_module::operator << ( sc_interface& interface_ )
+{
+ sc_warn_arrow_arrow_bind();
+ positional_bind(interface_);
+ return *this;
+}
+
+sc_module&
+sc_module::operator << ( sc_port_base& port_ )
+{
+ sc_warn_arrow_arrow_bind();
+ positional_bind(port_);
+ return *this;
+}
+
+
+void
+sc_module::positional_bind( sc_interface& interface_ )
+{
+ if( m_port_index == (int)m_port_vec->size() ) {
+ char msg[BUFSIZ];
+ if( m_port_index == 0 ) {
+ std::sprintf( msg, "module `%s' has no ports", name() );
+ } else {
+ std::sprintf( msg, "all ports of module `%s' are bound", name() );
+ }
+ SC_REPORT_ERROR( SC_ID_BIND_IF_TO_PORT_, msg );
+ }
+ int status = (*m_port_vec)[m_port_index]->pbind( interface_ );
+ if( status != 0 ) {
+ char msg[BUFSIZ];
+ switch( status ) {
+ case 1:
+ std::sprintf( msg, "port %d of module `%s' is already bound",
+ m_port_index, name() );
+ break;
+ case 2:
+ std::sprintf( msg, "type mismatch on port %d of module `%s'",
+ m_port_index, name() );
+ break;
+ default:
+ std::sprintf( msg, "unknown error" );
+ break;
+ }
+ SC_REPORT_ERROR( SC_ID_BIND_IF_TO_PORT_, msg );
+ }
+ ++ m_port_index;
+}
+
+void
+sc_module::positional_bind( sc_port_base& port_ )
+{
+ if( m_port_index == (int)m_port_vec->size() ) {
+ char msg[BUFSIZ];
+ if( m_port_index == 0 ) {
+ std::sprintf( msg, "module `%s' has no ports", name() );
+ } else {
+ std::sprintf( msg, "all ports of module `%s' are bound", name() );
+ }
+ SC_REPORT_ERROR( SC_ID_BIND_PORT_TO_PORT_, msg );
+ }
+ int status = (*m_port_vec)[m_port_index]->pbind( port_ );
+ if( status != 0 ) {
+ char msg[BUFSIZ];
+ switch( status ) {
+ case 1:
+ std::sprintf( msg, "port %d of module `%s' is already bound",
+ m_port_index, name() );
+ break;
+ case 2:
+ std::sprintf( msg, "type mismatch on port %d of module `%s'",
+ m_port_index, name() );
+ break;
+ default:
+ std::sprintf( msg, "unknown error" );
+ break;
+ }
+ SC_REPORT_ERROR( SC_ID_BIND_PORT_TO_PORT_, msg );
+ }
+ ++ m_port_index;
+}
+
+
+#define TRY_BIND( p ) \
+ if( (p).iface != 0 ) { \
+ positional_bind( *(p).iface ); \
+ } else if( (p).port != 0 ) { \
+ positional_bind( *(p).port ); \
+ } else { \
+ return; \
+ }
+
+
+void
+sc_module::operator () ( const sc_bind_proxy& p001,
+ const sc_bind_proxy& p002,
+ const sc_bind_proxy& p003,
+ const sc_bind_proxy& p004,
+ const sc_bind_proxy& p005,
+ const sc_bind_proxy& p006,
+ const sc_bind_proxy& p007,
+ const sc_bind_proxy& p008,
+ const sc_bind_proxy& p009,
+ const sc_bind_proxy& p010,
+ const sc_bind_proxy& p011,
+ const sc_bind_proxy& p012,
+ const sc_bind_proxy& p013,
+ const sc_bind_proxy& p014,
+ const sc_bind_proxy& p015,
+ const sc_bind_proxy& p016,
+ const sc_bind_proxy& p017,
+ const sc_bind_proxy& p018,
+ const sc_bind_proxy& p019,
+ const sc_bind_proxy& p020,
+ const sc_bind_proxy& p021,
+ const sc_bind_proxy& p022,
+ const sc_bind_proxy& p023,
+ const sc_bind_proxy& p024,
+ const sc_bind_proxy& p025,
+ const sc_bind_proxy& p026,
+ const sc_bind_proxy& p027,
+ const sc_bind_proxy& p028,
+ const sc_bind_proxy& p029,
+ const sc_bind_proxy& p030,
+ const sc_bind_proxy& p031,
+ const sc_bind_proxy& p032,
+ const sc_bind_proxy& p033,
+ const sc_bind_proxy& p034,
+ const sc_bind_proxy& p035,
+ const sc_bind_proxy& p036,
+ const sc_bind_proxy& p037,
+ const sc_bind_proxy& p038,
+ const sc_bind_proxy& p039,
+ const sc_bind_proxy& p040,
+ const sc_bind_proxy& p041,
+ const sc_bind_proxy& p042,
+ const sc_bind_proxy& p043,
+ const sc_bind_proxy& p044,
+ const sc_bind_proxy& p045,
+ const sc_bind_proxy& p046,
+ const sc_bind_proxy& p047,
+ const sc_bind_proxy& p048,
+ const sc_bind_proxy& p049,
+ const sc_bind_proxy& p050,
+ const sc_bind_proxy& p051,
+ const sc_bind_proxy& p052,
+ const sc_bind_proxy& p053,
+ const sc_bind_proxy& p054,
+ const sc_bind_proxy& p055,
+ const sc_bind_proxy& p056,
+ const sc_bind_proxy& p057,
+ const sc_bind_proxy& p058,
+ const sc_bind_proxy& p059,
+ const sc_bind_proxy& p060,
+ const sc_bind_proxy& p061,
+ const sc_bind_proxy& p062,
+ const sc_bind_proxy& p063,
+ const sc_bind_proxy& p064 )
+{
+ static bool warn_only_once=true;
+ if ( m_port_index > 0 && warn_only_once )
+ {
+ warn_only_once = false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "multiple () binding deprecated, use explicit port binding instead." );
+ }
+
+ TRY_BIND( p001 );
+ TRY_BIND( p002 );
+ TRY_BIND( p003 );
+ TRY_BIND( p004 );
+ TRY_BIND( p005 );
+ TRY_BIND( p006 );
+ TRY_BIND( p007 );
+ TRY_BIND( p008 );
+ TRY_BIND( p009 );
+ TRY_BIND( p010 );
+ TRY_BIND( p011 );
+ TRY_BIND( p012 );
+ TRY_BIND( p013 );
+ TRY_BIND( p014 );
+ TRY_BIND( p015 );
+ TRY_BIND( p016 );
+ TRY_BIND( p017 );
+ TRY_BIND( p018 );
+ TRY_BIND( p019 );
+ TRY_BIND( p020 );
+ TRY_BIND( p021 );
+ TRY_BIND( p022 );
+ TRY_BIND( p023 );
+ TRY_BIND( p024 );
+ TRY_BIND( p025 );
+ TRY_BIND( p026 );
+ TRY_BIND( p027 );
+ TRY_BIND( p028 );
+ TRY_BIND( p029 );
+ TRY_BIND( p030 );
+ TRY_BIND( p031 );
+ TRY_BIND( p032 );
+ TRY_BIND( p033 );
+ TRY_BIND( p034 );
+ TRY_BIND( p035 );
+ TRY_BIND( p036 );
+ TRY_BIND( p037 );
+ TRY_BIND( p038 );
+ TRY_BIND( p039 );
+ TRY_BIND( p040 );
+ TRY_BIND( p041 );
+ TRY_BIND( p042 );
+ TRY_BIND( p043 );
+ TRY_BIND( p044 );
+ TRY_BIND( p045 );
+ TRY_BIND( p046 );
+ TRY_BIND( p047 );
+ TRY_BIND( p048 );
+ TRY_BIND( p049 );
+ TRY_BIND( p050 );
+ TRY_BIND( p051 );
+ TRY_BIND( p052 );
+ TRY_BIND( p053 );
+ TRY_BIND( p054 );
+ TRY_BIND( p055 );
+ TRY_BIND( p056 );
+ TRY_BIND( p057 );
+ TRY_BIND( p058 );
+ TRY_BIND( p059 );
+ TRY_BIND( p060 );
+ TRY_BIND( p061 );
+ TRY_BIND( p062 );
+ TRY_BIND( p063 );
+ TRY_BIND( p064 );
+}
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc.
+ Description of Modification: - Implementation of operator() and operator,
+ positional connection method.
+ - Implementation of error checking in
+ operator<<'s.
+ - Implementation of the function test_module_prm.
+ - Implementation of set_stack_size().
+
+ Name, Affiliation, Date: Andy Goodrich, Forte Design Systems 20 May 2003
+ Description of Modification: Inherit from sc_process_host
+
+ Name, Affiliation, Date: Bishnupriya Bhattacharya, Cadence Design Systems,
+ 25 August, 2003
+ Description of Modification: dont_initialize() uses
+ sc_get_last_created_process_handle() instead of
+ sc_get_current_process_b()
+
+ Name, Affiliation, Date: Andy Goodrich, Forte Design Systems 25 Mar 2003
+ Description of Modification: Fixed bug in SC_NEW, see comments on
+ ~sc_module_dynalloc_list below.
+
+
+ *****************************************************************************/
+
+
+// $Log: sc_module.cpp,v $
+// Revision 1.14 2011/08/29 18:04:32 acg
+// Philipp A. Hartmann: miscellaneous clean ups.
+//
+// Revision 1.13 2011/08/26 20:46:10 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.12 2011/08/24 22:05:51 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.11 2011/03/05 19:44:20 acg
+// Andy Goodrich: changes for object and event naming and structures.
+//
+// Revision 1.10 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.9 2011/02/16 22:37:30 acg
+// Andy Goodrich: clean up to remove need for ps_disable_pending.
+//
+// Revision 1.8 2011/02/14 17:51:40 acg
+// Andy Goodrich: proper pushing an poppping of the module hierarchy for
+// start_of_simulation() and end_of_simulation.
+//
+// Revision 1.7 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.6 2011/01/25 20:50:37 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.5 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.4 2008/11/17 15:57:15 acg
+// Andy Goodrich: added deprecation message for sc_module(const char*)
+//
+// Revision 1.3 2008/05/22 17:06:25 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.2 2007/05/17 20:16:33 acg
+// Andy Goodrich: changes for beta release to LWG.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.9 2006/12/02 20:58:18 acg
+// Andy Goodrich: updates from 2.2 for IEEE 1666 support.
+//
+// Revision 1.8 2006/03/21 00:00:34 acg
+// Andy Goodrich: changed name of sc_get_current_process_base() to be
+// sc_get_current_process_b() since its returning an sc_process_b instance.
+//
+// Revision 1.7 2006/03/14 23:56:58 acg
+// Andy Goodrich: This fixes a bug when an exception is thrown in
+// sc_module::sc_module() for a dynamically allocated sc_module
+// object. We are calling sc_module::end_module() on a module that has
+// already been deleted. The scenario runs like this:
+//
+// a) the sc_module constructor is entered
+// b) the exception is thrown
+// c) the exception processor deletes the storage for the sc_module
+// d) the stack is unrolled causing the sc_module_name instance to be deleted
+// e) ~sc_module_name() calls end_module() with its pointer to the sc_module
+// f) because the sc_module has been deleted its storage is corrupted,
+// either by linking it to a free space chain, or by reuse of some sort
+// g) the m_simc field is garbage
+// h) the m_object_manager field is also garbage
+// i) an exception occurs
+//
+// This does not happen for automatic sc_module instances since the
+// storage for the module is not reclaimed its just part of the stack.
+//
+// I am fixing this by having the destructor for sc_module clear the
+// module pointer in its sc_module_name instance. That cuts things at
+// step (e) above, since the pointer will be null if the module has
+// already been deleted. To make sure the module stack is okay, I call
+// end-module() in ~sc_module in the case where there is an
+// sc_module_name pointer lying around.
+//
+// Revision 1.6 2006/01/26 21:04:54 acg
+// Andy Goodrich: deprecation message changes and additional messages.
+//
+// Revision 1.5 2006/01/25 00:31:19 acg
+// Andy Goodrich: Changed over to use a standard message id of
+// SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
+//
+// Revision 1.4 2006/01/24 20:49:05 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_module.h b/ext/systemc/src/sysc/kernel/sc_module.h
new file mode 100644
index 000000000..8a68cb049
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_module.h
@@ -0,0 +1,583 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_module.h -- Base class of all hierarchical modules and channels.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+ Martin Janssen, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_MODULE_H
+#define SC_MODULE_H
+
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/kernel/sc_process.h"
+#include "sysc/kernel/sc_module_name.h"
+#include "sysc/kernel/sc_sensitive.h"
+#include "sysc/kernel/sc_time.h"
+#include "sysc/kernel/sc_wait.h"
+#include "sysc/kernel/sc_wait_cthread.h"
+#include "sysc/kernel/sc_process.h"
+#include "sysc/kernel/sc_process_handle.h"
+#include "sysc/utils/sc_list.h"
+
+namespace sc_core {
+
+class sc_name_gen;
+template<class T> class sc_in;
+template<class T> class sc_inout;
+template<class T> class sc_out;
+
+// ----------------------------------------------------------------------------
+// STRUCT : sc_bind_proxy
+//
+// Struct for temporarily storing a pointer to an interface or port.
+// Used for positional binding.
+// ----------------------------------------------------------------------------
+
+struct sc_bind_proxy
+{
+ sc_interface* iface;
+ sc_port_base* port;
+
+ sc_bind_proxy();
+ sc_bind_proxy( sc_interface& );
+ sc_bind_proxy( sc_port_base& );
+};
+
+
+extern const sc_bind_proxy SC_BIND_PROXY_NIL;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_module
+//
+// Base class for all structural entities.
+// ----------------------------------------------------------------------------
+
+class sc_module
+: public sc_object, public sc_process_host
+{
+ friend class sc_module_name;
+ friend class sc_module_registry;
+ friend class sc_object;
+ friend class sc_port_registry;
+ friend class sc_process_b;
+ friend class sc_simcontext;
+
+public:
+
+ sc_simcontext* sc_get_curr_simcontext()
+ { return simcontext(); }
+
+ // to generate unique names for objects in an MT-Safe way
+ const char* gen_unique_name( const char* basename_, bool preserve_first );
+
+ virtual const char* kind() const
+ { return "sc_module"; }
+
+protected:
+
+ // called by construction_done
+ virtual void before_end_of_elaboration();
+
+ void construction_done();
+
+ // called by elaboration_done (does nothing by default)
+ virtual void end_of_elaboration();
+
+ void elaboration_done( bool& );
+
+ // called by start_simulation (does nothing by default)
+ virtual void start_of_simulation();
+
+ void start_simulation();
+
+ // called by simulation_done (does nothing by default)
+ virtual void end_of_simulation();
+
+ void simulation_done();
+
+ void sc_module_init();
+
+ // constructor
+ sc_module();
+ sc_module( const sc_module_name& nm ); /* for those used to old style */
+
+ /* DEPRECATED */ sc_module( const char* nm );
+ /* DEPRECATED */ sc_module( const std::string& nm );
+
+public:
+
+ // destructor
+ virtual ~sc_module();
+
+ // positional binding methods
+
+ sc_module& operator << ( sc_interface& );
+ sc_module& operator << ( sc_port_base& );
+
+ sc_module& operator , ( sc_interface& interface_ )
+ { return operator << ( interface_ ); }
+
+ sc_module& operator , ( sc_port_base& port_ )
+ { return operator << ( port_ ); }
+
+ // operator() is declared at the end of the class.
+
+ const ::std::vector<sc_object*>& get_child_objects() const;
+
+protected:
+
+ // this must be called by user-defined modules
+ void end_module();
+
+
+ // to prevent initialization for SC_METHODs and SC_THREADs
+ void dont_initialize();
+
+ // positional binding code - used by operator ()
+
+ void positional_bind( sc_interface& );
+ void positional_bind( sc_port_base& );
+
+ // set reset sensitivity for SC_xTHREADs
+ void async_reset_signal_is( const sc_in<bool>& port, bool level );
+ void async_reset_signal_is( const sc_inout<bool>& port, bool level );
+ void async_reset_signal_is( const sc_out<bool>& port, bool level );
+ void async_reset_signal_is( const sc_signal_in_if<bool>& iface, bool level);
+ void reset_signal_is( const sc_in<bool>& port, bool level );
+ void reset_signal_is( const sc_inout<bool>& port, bool level );
+ void reset_signal_is( const sc_out<bool>& port, bool level );
+ void reset_signal_is( const sc_signal_in_if<bool>& iface, bool level );
+
+ // static sensitivity for SC_THREADs and SC_CTHREADs
+
+ void wait()
+ { ::sc_core::wait( simcontext() ); }
+
+ // dynamic sensitivity for SC_THREADs and SC_CTHREADs
+
+ void wait( const sc_event& e )
+ { ::sc_core::wait( e, simcontext() ); }
+
+ void wait( const sc_event_or_list& el )
+ { ::sc_core::wait( el, simcontext() ); }
+
+ void wait( const sc_event_and_list& el )
+ { ::sc_core::wait( el, simcontext() ); }
+
+ void wait( const sc_time& t )
+ { ::sc_core::wait( t, simcontext() ); }
+
+ void wait( double v, sc_time_unit tu )
+ { ::sc_core::wait( sc_time( v, tu, simcontext() ), simcontext() ); }
+
+ void wait( const sc_time& t, const sc_event& e )
+ { ::sc_core::wait( t, e, simcontext() ); }
+
+ void wait( double v, sc_time_unit tu, const sc_event& e )
+ { ::sc_core::wait(
+ sc_time( v, tu, simcontext() ), e, simcontext() ); }
+
+ void wait( const sc_time& t, const sc_event_or_list& el )
+ { ::sc_core::wait( t, el, simcontext() ); }
+
+ void wait( double v, sc_time_unit tu, const sc_event_or_list& el )
+ { ::sc_core::wait( sc_time( v, tu, simcontext() ), el, simcontext() ); }
+
+ void wait( const sc_time& t, const sc_event_and_list& el )
+ { ::sc_core::wait( t, el, simcontext() ); }
+
+ void wait( double v, sc_time_unit tu, const sc_event_and_list& el )
+ { ::sc_core::wait( sc_time( v, tu, simcontext() ), el, simcontext() ); }
+
+
+ // static sensitivity for SC_METHODs
+
+ void next_trigger()
+ { ::sc_core::next_trigger( simcontext() ); }
+
+
+ // dynamic sensitivty for SC_METHODs
+
+ void next_trigger( const sc_event& e )
+ { ::sc_core::next_trigger( e, simcontext() ); }
+
+ void next_trigger( const sc_event_or_list& el )
+ { ::sc_core::next_trigger( el, simcontext() ); }
+
+ void next_trigger( const sc_event_and_list& el )
+ { ::sc_core::next_trigger( el, simcontext() ); }
+
+ void next_trigger( const sc_time& t )
+ { ::sc_core::next_trigger( t, simcontext() ); }
+
+ void next_trigger( double v, sc_time_unit tu )
+ { ::sc_core::next_trigger(
+ sc_time( v, tu, simcontext() ), simcontext() ); }
+
+ void next_trigger( const sc_time& t, const sc_event& e )
+ { ::sc_core::next_trigger( t, e, simcontext() ); }
+
+ void next_trigger( double v, sc_time_unit tu, const sc_event& e )
+ { ::sc_core::next_trigger(
+ sc_time( v, tu, simcontext() ), e, simcontext() ); }
+
+ void next_trigger( const sc_time& t, const sc_event_or_list& el )
+ { ::sc_core::next_trigger( t, el, simcontext() ); }
+
+ void next_trigger( double v, sc_time_unit tu, const sc_event_or_list& el )
+ { ::sc_core::next_trigger(
+ sc_time( v, tu, simcontext() ), el, simcontext() ); }
+
+ void next_trigger( const sc_time& t, const sc_event_and_list& el )
+ { ::sc_core::next_trigger( t, el, simcontext() ); }
+
+ void next_trigger( double v, sc_time_unit tu, const sc_event_and_list& el )
+ { ::sc_core::next_trigger(
+ sc_time( v, tu, simcontext() ), el, simcontext() ); }
+
+
+ // for SC_METHODs and SC_THREADs and SC_CTHREADs
+
+ bool timed_out()
+ { return ::sc_core::timed_out(); }
+
+
+ // for SC_CTHREADs
+
+ void halt()
+ { ::sc_core::halt( simcontext() ); }
+
+ void wait( int n )
+ { ::sc_core::wait( n, simcontext() ); }
+
+ void at_posedge( const sc_signal_in_if<bool>& s )
+ { ::sc_core::at_posedge( s, simcontext() ); }
+
+ void at_posedge( const sc_signal_in_if<sc_dt::sc_logic>& s )
+ { ::sc_core::at_posedge( s, simcontext() ); }
+
+ void at_negedge( const sc_signal_in_if<bool>& s )
+ { ::sc_core::at_negedge( s, simcontext() ); }
+
+ void at_negedge( const sc_signal_in_if<sc_dt::sc_logic>& s )
+ { ::sc_core::at_negedge( s, simcontext() ); }
+
+ // Catch uses of watching:
+ void watching( bool /* expr */ )
+ { SC_REPORT_ERROR(SC_ID_WATCHING_NOT_ALLOWED_,""); }
+
+ // These are protected so that user derived classes can refer to them.
+ sc_sensitive sensitive;
+ sc_sensitive_pos sensitive_pos;
+ sc_sensitive_neg sensitive_neg;
+
+ // Function to set the stack size of the current (c)thread process.
+ void set_stack_size( std::size_t );
+
+ int append_port( sc_port_base* );
+
+private:
+ sc_module( const sc_module& );
+ const sc_module& operator = ( const sc_module& );
+
+private:
+
+ bool m_end_module_called;
+ std::vector<sc_port_base*>* m_port_vec;
+ int m_port_index;
+ sc_name_gen* m_name_gen;
+ sc_module_name* m_module_name_p;
+
+public:
+
+ void defunct() { }
+
+ // positional binding methods (cont'd)
+
+ void operator () ( const sc_bind_proxy& p001,
+ const sc_bind_proxy& p002 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p003 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p004 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p005 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p006 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p007 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p008 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p009 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p010 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p011 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p012 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p013 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p014 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p015 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p016 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p017 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p018 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p019 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p020 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p021 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p022 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p023 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p024 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p025 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p026 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p027 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p028 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p029 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p030 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p031 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p032 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p033 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p034 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p035 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p036 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p037 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p038 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p039 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p040 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p041 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p042 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p043 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p044 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p045 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p046 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p047 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p048 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p049 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p050 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p051 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p052 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p053 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p054 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p055 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p056 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p057 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p058 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p059 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p060 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p061 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p062 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p063 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p064 = SC_BIND_PROXY_NIL );
+
+};
+
+extern sc_module* sc_module_dynalloc(sc_module*);
+#define SC_NEW(x) ::sc_core::sc_module_dynalloc(new x);
+
+
+// -----------------------------------------------------------------------------
+// SOME MACROS TO SIMPLIFY SYNTAX:
+// -----------------------------------------------------------------------------
+
+#define SC_MODULE(user_module_name) \
+ struct user_module_name : ::sc_core::sc_module
+
+#define SC_CTOR(user_module_name) \
+ typedef user_module_name SC_CURRENT_USER_MODULE; \
+ user_module_name( ::sc_core::sc_module_name )
+
+// the SC_HAS_PROCESS macro call must be followed by a ;
+#define SC_HAS_PROCESS(user_module_name) \
+ typedef user_module_name SC_CURRENT_USER_MODULE
+
+// The this-> construct on sensitive operators in the macros below is
+// required for gcc 4.x when a templated class has a templated parent that is
+// derived from sc_module:
+//
+// template<typename X>
+// class B : public sc_module;
+// template<typename X>
+// class A : public B<X>
+
+#define declare_method_process(handle, name, host_tag, func) \
+ { \
+ ::sc_core::sc_process_handle handle = \
+ sc_core::sc_get_curr_simcontext()->create_method_process( \
+ name, false, SC_MAKE_FUNC_PTR( host_tag, func ), \
+ this, 0 ); \
+ this->sensitive << handle; \
+ this->sensitive_pos << handle; \
+ this->sensitive_neg << handle; \
+ }
+
+#define declare_thread_process(handle, name, host_tag, func) \
+ { \
+ ::sc_core::sc_process_handle handle = \
+ sc_core::sc_get_curr_simcontext()->create_thread_process( \
+ name, false, \
+ SC_MAKE_FUNC_PTR( host_tag, func ), this, 0 ); \
+ this->sensitive << handle; \
+ this->sensitive_pos << handle; \
+ this->sensitive_neg << handle; \
+ }
+
+#define declare_cthread_process(handle, name, host_tag, func, edge) \
+ { \
+ ::sc_core::sc_process_handle handle = \
+ sc_core::sc_get_curr_simcontext()->create_cthread_process( \
+ name, false, \
+ SC_MAKE_FUNC_PTR( host_tag, func ), this, 0 ); \
+ this->sensitive.operator() ( handle, edge );\
+ }
+
+#define SC_CTHREAD(func, edge) \
+ declare_cthread_process( func ## _handle, \
+ #func, \
+ SC_CURRENT_USER_MODULE, \
+ func, \
+ edge )
+
+#define SC_METHOD(func) \
+ declare_method_process( func ## _handle, \
+ #func, \
+ SC_CURRENT_USER_MODULE, \
+ func )
+
+#define SC_THREAD(func) \
+ declare_thread_process( func ## _handle, \
+ #func, \
+ SC_CURRENT_USER_MODULE, \
+ func )
+
+
+
+// ----------------------------------------------------------------------------
+// TYPEDEFS
+// ----------------------------------------------------------------------------
+
+typedef sc_module sc_channel;
+typedef sc_module sc_behavior;
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc.
+ Description of Modification: - Implementation of operator() and operator,
+ positional connection method.
+ - Implementation of error checking in
+ operator<<'s.
+ - Implementation of the function test_module_prm.
+ - Implementation of set_stack_size().
+
+ Name, Affiliation, Date: Gene Bushuyev, Synopsys, Inc.
+ Description of Modification: - Change implementation for VC6.
+
+ Name, Affiliation, Date: Andy Godorich, Forte
+ Bishnupriya Bhattacharya, Cadence Design Systems,
+ 25 August, 2003
+ Description of Modification: inherit from sc_process_host as a part of
+ implementing dynamic processes
+
+ *****************************************************************************/
+
+// $Log: sc_module.h,v $
+// Revision 1.11 2011/08/26 20:46:10 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.10 2011/08/15 16:43:24 acg
+// Torsten Maehne: changes to remove unused argument warnings.
+//
+// Revision 1.9 2011/03/05 19:44:20 acg
+// Andy Goodrich: changes for object and event naming and structures.
+//
+// Revision 1.8 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.7 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.6 2011/01/18 20:10:44 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.5 2010/12/07 20:09:12 acg
+// Andy Goodrich: remove unused signal declaration
+//
+// Revision 1.4 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.3 2008/05/22 17:06:25 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.2 2007/01/24 20:14:40 acg
+// Andy Goodrich: improved comments about the use of this-> in the macros
+// that access sensitive.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.10 2006/12/02 20:58:18 acg
+// Andy Goodrich: updates from 2.2 for IEEE 1666 support.
+//
+// Revision 1.7 2006/04/11 23:13:21 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.6 2006/03/15 17:53:34 acg
+// Andy Goodrich, Forte Design
+// Reordered includes to pick up <cassert> for use by sc_process_name.h
+//
+// Revision 1.5 2006/03/14 23:56:58 acg
+// Andy Goodrich: This fixes a bug when an exception is thrown in
+// sc_module::sc_module() for a dynamically allocated sc_module
+// object. We are calling sc_module::end_module() on a module that has
+// already been deleted. The scenario runs like this:
+//
+// a) the sc_module constructor is entered
+// b) the exception is thrown
+// c) the exception processor deletes the storage for the sc_module
+// d) the stack is unrolled causing the sc_module_name instance to be deleted
+// e) ~sc_module_name() calls end_module() with its pointer to the sc_module
+// f) because the sc_module has been deleted its storage is corrupted,
+// either by linking it to a free space chain, or by reuse of some sort
+// g) the m_simc field is garbage
+// h) the m_object_manager field is also garbage
+// i) an exception occurs
+//
+// This does not happen for automatic sc_module instances since the
+// storage for the module is not reclaimed its just part of the stack.
+//
+// I am fixing this by having the destructor for sc_module clear the
+// module pointer in its sc_module_name instance. That cuts things at
+// step (e) above, since the pointer will be null if the module has
+// already been deleted. To make sure the module stack is okay, I call
+// end-module() in ~sc_module in the case where there is an
+// sc_module_name pointer lying around.
+//
+// Revision 1.4 2006/01/24 20:49:05 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+#endif
diff --git a/ext/systemc/src/sysc/kernel/sc_module_name.cpp b/ext/systemc/src/sysc/kernel/sc_module_name.cpp
new file mode 100644
index 000000000..a5352690f
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_module_name.cpp
@@ -0,0 +1,123 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_module_name.cpp -- An object used to help manage object names
+ and hierarchy
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include <cstdlib>
+
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/kernel/sc_module.h"
+#include "sysc/kernel/sc_module_name.h"
+#include "sysc/kernel/sc_object_manager.h"
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/utils/sc_iostream.h"
+
+namespace sc_core {
+
+sc_module_name::sc_module_name( const char* name_ )
+: m_name( name_ ),
+ m_module_p( 0 ),
+ m_next( 0 ),
+ m_simc( sc_get_curr_simcontext() ),
+ m_pushed( true )
+{
+ m_simc->get_object_manager()->push_module_name( this );
+}
+
+sc_module_name::sc_module_name( const sc_module_name& name_ )
+: m_name( name_.m_name ),
+ m_module_p( 0 ),
+ m_next( 0 ),
+ m_simc( name_.m_simc ),
+ m_pushed( false )
+{}
+
+sc_module_name::~sc_module_name()
+{
+ if( m_pushed ) {
+ sc_module_name* smn = m_simc->get_object_manager()->pop_module_name();
+ if( this != smn ) {
+ SC_REPORT_ERROR( SC_ID_SC_MODULE_NAME_USE_, 0 );
+ }
+ if ( m_module_p ) m_module_p->end_module();
+ }
+}
+
+sc_module_name::operator const char*() const
+{
+ return m_name;
+}
+
+} // namespace sc_core
+
+// $Log: sc_module_name.cpp,v $
+// Revision 1.5 2011/08/26 20:46:10 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.2 2008/05/22 17:06:26 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.4 2006/03/14 23:56:58 acg
+// Andy Goodrich: This fixes a bug when an exception is thrown in
+// sc_module::sc_module() for a dynamically allocated sc_module
+// object. We are calling sc_module::end_module() on a module that has
+// already been deleted. The scenario runs like this:
+//
+// a) the sc_module constructor is entered
+// b) the exception is thrown
+// c) the exception processor deletes the storage for the sc_module
+// d) the stack is unrolled causing the sc_module_name instance to be deleted
+// e) ~sc_module_name() calls end_module() with its pointer to the sc_module
+// f) because the sc_module has been deleted its storage is corrupted,
+// either by linking it to a free space chain, or by reuse of some sort
+// g) the m_simc field is garbage
+// h) the m_object_manager field is also garbage
+// i) an exception occurs
+//
+// This does not happen for automatic sc_module instances since the
+// storage for the module is not reclaimed its just part of the stack.
+//
+// I am fixing this by having the destructor for sc_module clear the
+// module pointer in its sc_module_name instance. That cuts things at
+// step (e) above, since the pointer will be null if the module has
+// already been deleted. To make sure the module stack is okay, I call
+// end-module() in ~sc_module in the case where there is an
+// sc_module_name pointer lying around.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+//
diff --git a/ext/systemc/src/sysc/kernel/sc_module_name.h b/ext/systemc/src/sysc/kernel/sc_module_name.h
new file mode 100644
index 000000000..a2149cc6a
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_module_name.h
@@ -0,0 +1,140 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_module_name.h -- An object used to help manage object names
+ and hierarchy.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+// $Log: sc_module_name.h,v $
+// Revision 1.5 2011/08/26 20:46:10 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+
+#ifndef SC_MODULE_NAME_H
+#define SC_MODULE_NAME_H
+
+
+namespace sc_core {
+
+class sc_module;
+class sc_simcontext;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_module_name
+//
+// Module name class.
+// ----------------------------------------------------------------------------
+
+class sc_module_name
+{
+ friend class sc_module;
+ friend class sc_object_manager;
+
+public:
+
+ sc_module_name( const char* );
+ sc_module_name( const sc_module_name& );
+
+ ~sc_module_name();
+
+ operator const char*() const;
+
+protected:
+ inline void clear_module( sc_module* module_p );
+ inline void set_module( sc_module* module_p );
+
+private:
+
+ const char* m_name;
+ sc_module* m_module_p;
+ sc_module_name* m_next;
+ sc_simcontext* m_simc;
+ bool m_pushed;
+
+private:
+
+ // disabled
+ sc_module_name();
+ sc_module_name& operator = ( const sc_module_name& );
+};
+
+inline void sc_module_name::clear_module( sc_module* module_p )
+{
+ assert( m_module_p == module_p );
+ m_module_p = 0;
+}
+
+inline void sc_module_name::set_module( sc_module* module_p )
+{
+ m_module_p = module_p;
+}
+
+} // namespace sc_core
+
+// Revision 1.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.2 2008/05/22 17:06:26 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.4 2006/03/14 23:56:58 acg
+// Andy Goodrich: This fixes a bug when an exception is thrown in
+// sc_module::sc_module() for a dynamically allocated sc_module
+// object. We are calling sc_module::end_module() on a module that has
+// already been deleted. The scenario runs like this:
+//
+// a) the sc_module constructor is entered
+// b) the exception is thrown
+// c) the exception processor deletes the storage for the sc_module
+// d) the stack is unrolled causing the sc_module_name instance to be deleted
+// e) ~sc_module_name() calls end_module() with its pointer to the sc_module
+// f) because the sc_module has been deleted its storage is corrupted,
+// either by linking it to a free space chain, or by reuse of some sort
+// g) the m_simc field is garbage
+// h) the m_object_manager field is also garbage
+// i) an exception occurs
+//
+// This does not happen for automatic sc_module instances since the
+// storage for the module is not reclaimed its just part of the stack.
+//
+// I am fixing this by having the destructor for sc_module clear the
+// module pointer in its sc_module_name instance. That cuts things at
+// step (e) above, since the pointer will be null if the module has
+// already been deleted. To make sure the module stack is okay, I call
+// end-module() in ~sc_module in the case where there is an
+// sc_module_name pointer lying around.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+#endif
diff --git a/ext/systemc/src/sysc/kernel/sc_module_registry.cpp b/ext/systemc/src/sysc/kernel/sc_module_registry.cpp
new file mode 100644
index 000000000..2d8b02c34
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_module_registry.cpp
@@ -0,0 +1,184 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_module_registry.cpp -- Registry for all modules.
+ FOR INTERNAL USE ONLY.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/kernel/sc_module.h"
+#include "sysc/kernel/sc_module_registry.h"
+#include "sysc/kernel/sc_simcontext.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_module_registry
+//
+// Registry for all modules.
+// FOR INTERNAL USE ONLY!
+// ----------------------------------------------------------------------------
+
+void
+sc_module_registry::insert( sc_module& module_ )
+{
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_INSERT_MODULE_, "simulation running" );
+ }
+
+ if( m_simc->elaboration_done() ) {
+ SC_REPORT_ERROR( SC_ID_INSERT_MODULE_, "elaboration done" );
+ }
+
+#ifdef DEBUG_SYSTEMC
+ // check if module_ is already inserted
+ for( int i = size() - 1; i >= 0; -- i ) {
+ if( &module_ == m_module_vec[i] ) {
+ SC_REPORT_ERROR( SC_ID_INSERT_MODULE_, "already inserted" );
+ }
+ }
+#endif
+
+ // insert
+ m_module_vec.push_back( &module_ );
+}
+
+void
+sc_module_registry::remove( sc_module& module_ )
+{
+ int i;
+ for( i = 0; i < size(); ++ i ) {
+ if( &module_ == m_module_vec[i] ) {
+ break;
+ }
+ }
+ if( i == size() ) {
+ SC_REPORT_ERROR( SC_ID_REMOVE_MODULE_, 0 );
+ }
+
+ // remove
+ m_module_vec[i] = m_module_vec[size() - 1];
+ m_module_vec.resize(m_module_vec.size()-1);
+}
+
+
+// constructor
+
+sc_module_registry::sc_module_registry( sc_simcontext& simc_ )
+ : m_construction_done(0), m_module_vec(), m_simc( &simc_ )
+{}
+
+
+// destructor
+
+sc_module_registry::~sc_module_registry()
+{}
+
+// called when construction is done
+
+bool
+sc_module_registry::construction_done()
+{
+ if( size() == m_construction_done )
+ // nothing has been updated
+ return true;
+
+ for( ; m_construction_done < size(); ++m_construction_done ) {
+ m_module_vec[m_construction_done]->construction_done();
+ }
+ return false;
+}
+
+// called when elaboration is done
+
+void
+sc_module_registry::elaboration_done()
+{
+ bool error = false;
+ for( int i = 0; i < size(); ++ i ) {
+ m_module_vec[i]->elaboration_done( error );
+ }
+}
+
+// called before simulation begins
+
+void
+sc_module_registry::start_simulation()
+{
+ for( int i = 0; i < size(); ++ i ) {
+ m_module_vec[i]->start_simulation();
+ }
+}
+
+// called after simulation ends
+
+void
+sc_module_registry::simulation_done()
+{
+ for( int i = 0; i < size(); ++ i ) {
+ m_module_vec[i]->simulation_done();
+ }
+}
+
+} // namespace sc_core
+
+// $Log: sc_module_registry.cpp,v $
+// Revision 1.8 2011/08/26 20:46:10 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.7 2011/08/24 22:05:51 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.6 2011/05/09 04:07:49 acg
+// Philipp A. Hartmann:
+// (1) Restore hierarchy in all phase callbacks.
+// (2) Ensure calls to before_end_of_elaboration.
+//
+// Revision 1.5 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.4 2011/02/14 17:51:40 acg
+// Andy Goodrich: proper pushing an poppping of the module hierarchy for
+// start_of_simulation() and end_of_simulation.
+//
+// Revision 1.3 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.2 2008/05/22 17:06:26 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.4 2006/01/26 21:04:54 acg
+// Andy Goodrich: deprecation message changes and additional messages.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+//
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_module_registry.h b/ext/systemc/src/sysc/kernel/sc_module_registry.h
new file mode 100644
index 000000000..3e1bb5dff
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_module_registry.h
@@ -0,0 +1,124 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_module_registry.h -- Registry for all modules.
+ FOR INTERNAL USE ONLY.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_MODULE_REGISTRY_H
+#define SC_MODULE_REGISTRY_H
+
+
+namespace sc_core {
+
+class sc_module;
+class sc_simcontext;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_module_registry
+//
+// Registry for all modules.
+// FOR INTERNAL USE ONLY!
+// ----------------------------------------------------------------------------
+
+class sc_module_registry
+{
+ friend class sc_simcontext;
+
+public:
+
+ void insert( sc_module& );
+ void remove( sc_module& );
+
+ int size() const
+ { return m_module_vec.size(); }
+
+private:
+
+ // constructor
+ explicit sc_module_registry( sc_simcontext& simc_ );
+
+ // destructor
+ ~sc_module_registry();
+
+ // called when construction is done
+ bool construction_done();
+
+ // called when elaboration is done
+ void elaboration_done();
+
+ // called before simulation begins
+ void start_simulation();
+
+ // called after simulation ends
+ void simulation_done();
+
+
+private:
+
+ int m_construction_done;
+ std::vector<sc_module*> m_module_vec;
+ sc_simcontext* m_simc;
+
+private:
+
+ // disabled
+ sc_module_registry();
+ sc_module_registry( const sc_module_registry& );
+ sc_module_registry& operator = ( const sc_module_registry& );
+};
+
+} // namespace sc_core
+
+#endif
+
+// $Log: sc_module_registry.h,v $
+// Revision 1.6 2011/08/26 20:46:10 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.5 2011/05/09 04:07:49 acg
+// Philipp A. Hartmann:
+// (1) Restore hierarchy in all phase callbacks.
+// (2) Ensure calls to before_end_of_elaboration.
+//
+// Revision 1.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.2 2008/05/22 17:06:26 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_name_gen.cpp b/ext/systemc/src/sysc/kernel/sc_name_gen.cpp
new file mode 100644
index 000000000..16f6ad78f
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_name_gen.cpp
@@ -0,0 +1,109 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_name_gen.cpp -- Unique name generator.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/kernel/sc_name_gen.h"
+#include "sysc/utils/sc_iostream.h"
+
+#if defined(_MSC_VER) && _MSC_VER >= 1310
+// "C4351: new behavior: elements of array will be default initialized"
+#pragma warning(disable: 4351)
+#endif
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_name_gen
+//
+// Unique name generator class.
+// ----------------------------------------------------------------------------
+
+sc_name_gen::sc_name_gen() : m_unique_name_map(), m_unique_name()
+{}
+
+sc_name_gen::~sc_name_gen()
+{
+ sc_strhash<int*>::iterator it( m_unique_name_map );
+ for( ; ! it.empty(); it ++ ) {
+ delete it.contents();
+ }
+ m_unique_name_map.erase();
+}
+
+
+// to generate unique names for objects in an MT-Safe way
+
+const char*
+sc_name_gen::gen_unique_name( const char* basename_, bool preserve_first )
+{
+ if( basename_ == 0 ) {
+ SC_REPORT_ERROR( SC_ID_GEN_UNIQUE_NAME_, 0 );
+ }
+ int* c = m_unique_name_map[basename_];
+ if( c == 0 ) {
+ c = new int( 0 );
+ m_unique_name_map.insert( CCAST<char*>( basename_ ), c );
+ if (preserve_first) {
+ std::sprintf( m_unique_name, "%s", basename_ );
+ } else {
+ std::sprintf( m_unique_name, "%s_%d", basename_, *c );
+ }
+ } else {
+ std::sprintf( m_unique_name, "%s_%d", basename_, ++ (*c) );
+ }
+ return m_unique_name;
+}
+
+} // namespace sc_core
+
+// $Log: sc_name_gen.cpp,v $
+// Revision 1.6 2011/08/26 20:46:10 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.5 2011/08/24 22:05:51 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.2 2008/05/22 17:06:26 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+//
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_name_gen.h b/ext/systemc/src/sysc/kernel/sc_name_gen.h
new file mode 100644
index 000000000..0910e014a
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_name_gen.h
@@ -0,0 +1,93 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_name_gen.h -- Unique name generator.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_NAME_GEN
+#define SC_NAME_GEN
+
+
+#include <cstdio>
+
+#include "sysc/utils/sc_hash.h"
+
+namespace sc_core{
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_name_gen
+//
+// Unique name generator class.
+// ----------------------------------------------------------------------------
+
+class sc_name_gen
+{
+public:
+
+ sc_name_gen();
+ ~sc_name_gen();
+
+ const char* gen_unique_name( const char* basename_,
+ bool preserve_first = false
+ );
+
+private:
+
+ sc_strhash<int*> m_unique_name_map;
+ char m_unique_name[BUFSIZ];
+
+private:
+
+ // disabled
+ sc_name_gen( const sc_name_gen& );
+ sc_name_gen& operator = ( const sc_name_gen& );
+};
+
+} // namespace sc_core
+
+// $Log: sc_name_gen.h,v $
+// Revision 1.5 2011/08/26 20:46:10 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.2 2008/05/22 17:06:26 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_object.cpp b/ext/systemc/src/sysc/kernel/sc_object.cpp
new file mode 100644
index 000000000..e624d12b5
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_object.cpp
@@ -0,0 +1,568 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_object.cpp -- Abstract base class of all SystemC objects.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#include <cstdlib>
+#include <cassert>
+#include <stddef.h>
+#include <cstdio>
+#include <string.h>
+#include <ctype.h>
+
+#include "sysc/kernel/sc_externs.h"
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/kernel/sc_module.h"
+#include "sysc/kernel/sc_object.h"
+#include "sysc/kernel/sc_object_manager.h"
+#include "sysc/kernel/sc_phase_callback_registry.h"
+#include "sysc/kernel/sc_process_handle.h"
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_event.h"
+#include "sysc/utils/sc_hash.h"
+#include "sysc/utils/sc_iostream.h"
+#include "sysc/utils/sc_list.h"
+#include "sysc/utils/sc_utils_ids.h"
+#include "sysc/utils/sc_mempool.h"
+
+namespace sc_core {
+
+typedef int (*STRCMP)(const void*, const void*);
+
+const char SC_HIERARCHY_CHAR = '.';
+
+/* This will be gotten rid after multiple-processes
+ are implemented. This is to fix some regression
+ problems. */
+bool sc_enable_name_checking = true;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_object
+//
+// Abstract base class of all SystemC `simulation' objects.
+// ----------------------------------------------------------------------------
+
+void
+sc_object::add_child_event( sc_event* event_p )
+{
+ // no check if event_p is already in the set
+ m_child_events.push_back( event_p );
+}
+
+void
+sc_object::add_child_object( sc_object* object_ )
+{
+ // no check if object_ is already in the set
+ m_child_objects.push_back( object_ );
+}
+
+const char*
+sc_object::basename() const
+{
+ size_t pos; // position of last SC_HIERARCHY_CHAR.
+ pos = m_name.rfind( (char)SC_HIERARCHY_CHAR );
+ return ( pos == m_name.npos ) ? m_name.c_str() : &(m_name.c_str()[pos+1]);
+}
+
+void
+sc_object::print(::std::ostream& os) const
+{
+ os << name();
+}
+
+void
+sc_object::dump(::std::ostream& os) const
+{
+ os << "name = " << name() << "\n";
+ os << "kind = " << kind() << "\n";
+}
+
+static int sc_object_num = 0;
+
+static std::string
+sc_object_newname()
+{
+ char buffer[64];
+ std::string result;
+
+ std::sprintf(buffer, "{%d}", sc_object_num);
+ sc_object_num++;
+ result = buffer;
+
+ return result;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object::remove_child_event"
+// |
+// | This virtual method removes the supplied event from the list of child
+// | events if it is present.
+// |
+// | Arguments:
+// | event_p -> event to be removed.
+// | Returns true if the event was present, false if not.
+// +----------------------------------------------------------------------------
+bool
+sc_object::remove_child_event( sc_event* event_p )
+{
+ int size = m_child_events.size();
+ for( int i = 0; i < size; ++ i ) {
+ if( event_p == m_child_events[i] ) {
+ m_child_events[i] = m_child_events[size - 1];
+ m_child_events.pop_back();
+ return true;
+ }
+ }
+ return false;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object::remove_child_object"
+// |
+// | This virtual method removes the supplied object from the list of child
+// | objects if it is present.
+// |
+// | Arguments:
+// | object_p -> object to be removed.
+// | Returns true if the object was present, false if not.
+// +----------------------------------------------------------------------------
+bool
+sc_object::remove_child_object( sc_object* object_p )
+{
+ int size = m_child_objects.size();
+ for( int i = 0; i < size; ++ i ) {
+ if( object_p == m_child_objects[i] ) {
+ m_child_objects[i] = m_child_objects[size - 1];
+ m_child_objects.pop_back();
+ object_p->m_parent = NULL;
+ return true;
+ }
+ }
+ return false;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object::sc_object_init"
+// |
+// | This method initializes this object instance and places it in to the
+// | object hierarchy if the supplied name is not NULL.
+// |
+// | Arguments:
+// | nm = leaf name for the object.
+// +----------------------------------------------------------------------------
+void
+sc_object::sc_object_init(const char* nm)
+{
+ // SET UP POINTERS TO OBJECT MANAGER, PARENT, AND SIMULATION CONTEXT:
+ //
+ // Make the current simcontext the simcontext for this object
+
+ m_simc = sc_get_curr_simcontext();
+ m_attr_cltn_p = 0;
+ sc_object_manager* object_manager = m_simc->get_object_manager();
+ m_parent = m_simc->active_object();
+
+ // CONSTRUCT PATHNAME TO OBJECT BEING CREATED:
+ //
+ // If there is not a leaf name generate one.
+
+ m_name = object_manager->create_name(nm ? nm : sc_object_newname().c_str());
+
+
+ // PLACE THE OBJECT INTO THE HIERARCHY
+
+ object_manager->insert_object(m_name, this);
+ if ( m_parent )
+ m_parent->add_child_object( this );
+ else
+ m_simc->add_child_object( this );
+}
+
+sc_object::sc_object() :
+ m_attr_cltn_p(0), m_child_events(), m_child_objects(), m_name(),
+ m_parent(0), m_simc(0)
+{
+ sc_object_init( sc_gen_unique_name("object") );
+}
+
+sc_object::sc_object( const sc_object& that ) :
+ m_attr_cltn_p(0), m_child_events(), m_child_objects(), m_name(),
+ m_parent(0), m_simc(0)
+{
+ sc_object_init( sc_gen_unique_name( that.basename() ) );
+}
+
+
+static bool
+object_name_illegal_char(char ch)
+{
+ return (ch == SC_HIERARCHY_CHAR) || isspace(ch);
+}
+
+sc_object::sc_object(const char* nm) :
+ m_attr_cltn_p(0), m_child_events(), m_child_objects(), m_name(),
+ m_parent(0), m_simc(0)
+{
+ int namebuf_alloc = 0;
+ char* namebuf = 0;
+ const char* p;
+
+ // null name or "" uses machine generated name.
+
+ if ( !nm || !*nm )
+ nm = sc_gen_unique_name("object");
+ p = nm;
+
+ if (nm && sc_enable_name_checking) {
+ namebuf_alloc = 1 + strlen(nm);
+ namebuf = (char*) sc_mempool::allocate(namebuf_alloc);
+ char* q = namebuf;
+ const char* r = nm;
+ bool has_illegal_char = false;
+ while (*r) {
+ if (object_name_illegal_char(*r)) {
+ has_illegal_char = true;
+ *q = '_';
+ } else {
+ *q = *r;
+ }
+ r++;
+ q++;
+ }
+ *q = '\0';
+ p = namebuf;
+ if (has_illegal_char)
+ {
+ std::string message = nm;
+ message += " substituted by ";
+ message += namebuf;
+ SC_REPORT_WARNING( SC_ID_ILLEGAL_CHARACTERS_, message.c_str());
+ }
+ }
+ sc_object_init(p);
+ sc_mempool::release( namebuf, namebuf_alloc );
+}
+
+sc_object::~sc_object()
+{
+#if SC_HAS_PHASE_CALLBACKS_
+ unregister_simulation_phase_callback( SC_STATUS_ANY );
+#endif
+ detach();
+ delete m_attr_cltn_p;
+}
+
+//------------------------------------------------------------------------------
+//"sc_object::detach"
+//
+// This method detaches this object instance from the object hierarchy.
+// It is called in two places: ~sc_object() and sc_process_b::kill_process().
+//------------------------------------------------------------------------------
+void sc_object::detach()
+{
+ if (m_simc) {
+
+ // REMOVE OBJECT FROM THE OBJECT MANAGER:
+
+ sc_object_manager* object_manager = m_simc->get_object_manager();
+ object_manager->remove_object(m_name);
+
+ // REMOVE OBJECT FROM PARENT'S LIST OF OBJECTS:
+
+ if ( m_parent )
+ m_parent->remove_child_object( this );
+ else
+ m_simc->remove_child_object( this );
+
+ // ORPHAN THIS OBJECT'S CHILDREN:
+
+#if 0 // ####
+ ::std::<sc_object*> children_p = &get_child_objects();
+ int child_n = children_p->size();
+ sc_object* parent_p;
+
+ for ( int child_i = 0; child_i < child_n; child_i++ )
+ {
+ (*children_p)[child_i]->m_parent = 0;
+ }
+#endif
+
+ }
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object::orphan_child_events"
+// |
+// | This method moves the children of this object instance to be children
+// | of the simulator.
+// +----------------------------------------------------------------------------
+void sc_object::orphan_child_events()
+{
+ std::vector< sc_event* > const & events = get_child_events();
+
+ std::vector< sc_event* >::const_iterator
+ it = events.begin(), end = events.end();
+
+ for( ; it != end; ++it )
+ {
+ (*it)->m_parent_p = NULL;
+ simcontext()->add_child_event(*it);
+ }
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object::orphan_child_objects"
+// |
+// | This method moves the children of this object instance to be children
+// | of the simulator.
+// +----------------------------------------------------------------------------
+void sc_object::orphan_child_objects()
+{
+ std::vector< sc_object* > const & children = get_child_objects();
+
+ std::vector< sc_object* >::const_iterator
+ it = children.begin(), end = children.end();
+
+ for( ; it != end; ++it )
+ {
+ (*it)->m_parent = NULL;
+ simcontext()->add_child_object(*it);
+ }
+}
+
+void
+sc_object::trace( sc_trace_file * /* unused */) const
+{
+ /* This space is intentionally left blank */
+}
+
+
+// add attribute
+
+bool
+sc_object::add_attribute( sc_attr_base& attribute_ )
+{
+ if ( !m_attr_cltn_p ) m_attr_cltn_p = new sc_attr_cltn;
+ return ( m_attr_cltn_p->push_back( &attribute_ ) );
+}
+
+
+// get attribute by name
+
+sc_attr_base*
+sc_object::get_attribute( const std::string& name_ )
+{
+ if ( !m_attr_cltn_p ) m_attr_cltn_p = new sc_attr_cltn;
+ return ( (*m_attr_cltn_p)[name_] );
+}
+
+const sc_attr_base*
+sc_object::get_attribute( const std::string& name_ ) const
+{
+ if ( !m_attr_cltn_p ) m_attr_cltn_p = new sc_attr_cltn;
+ return ( (*m_attr_cltn_p)[name_] );
+}
+
+
+// remove attribute by name
+
+sc_attr_base*
+sc_object::remove_attribute( const std::string& name_ )
+{
+ if ( m_attr_cltn_p )
+ return ( m_attr_cltn_p->remove( name_ ) );
+ else
+ return 0;
+}
+
+
+// remove all attributes
+
+void
+sc_object::remove_all_attributes()
+{
+ if ( m_attr_cltn_p )
+ m_attr_cltn_p->remove_all();
+}
+
+
+// get the number of attributes
+
+int
+sc_object::num_attributes() const
+{
+ if ( m_attr_cltn_p )
+ return ( m_attr_cltn_p->size() );
+ else
+ return 0;
+}
+
+
+// get the attribute collection
+
+sc_attr_cltn&
+sc_object::attr_cltn()
+{
+ if ( !m_attr_cltn_p ) m_attr_cltn_p = new sc_attr_cltn;
+ return *m_attr_cltn_p;
+}
+
+const sc_attr_cltn&
+sc_object::attr_cltn() const
+{
+ if ( !m_attr_cltn_p ) m_attr_cltn_p = new sc_attr_cltn;
+ return *m_attr_cltn_p;
+}
+
+sc_object*
+sc_object::get_parent() const
+{
+ static bool warn_sc_get_parent_deprecated=true;
+ if ( warn_sc_get_parent_deprecated )
+ {
+ warn_sc_get_parent_deprecated=false;
+ SC_REPORT_INFO(sc_core::SC_ID_IEEE_1666_DEPRECATION_,
+ "sc_object::get_parent() is deprecated, "
+ "use get_parent_object() instead");
+ }
+ return get_parent_object();
+}
+
+// ----------------------------------------------------------------------------
+// simulation phase callbacks
+
+
+sc_object::phase_cb_mask
+sc_object::register_simulation_phase_callback( phase_cb_mask mask )
+{
+ mask = simcontext()->m_phase_cb_registry
+ ->register_callback(*this, mask);
+ return mask;
+}
+
+
+sc_object::phase_cb_mask
+sc_object::unregister_simulation_phase_callback( phase_cb_mask mask )
+{
+ mask = simcontext()->m_phase_cb_registry
+ ->unregister_callback(*this, mask);
+ return mask;
+}
+
+
+void
+sc_object::simulation_phase_callback()
+{
+ SC_REPORT_WARNING( SC_ID_PHASE_CALLBACK_NOT_IMPLEMENTED_, name() );
+}
+
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Bishnupriya Bhattacharya, Cadence Design Systems,
+ 25 August, 2003
+ Description of Modification: if module name hierarchy is empty, sc_object
+ ctor assumes the currently executing process
+ as the parent object to support dynamic process
+ creation similar to other sc_objects
+
+ Name, Affiliation, Date: Andy Goodrich, Forte Design Systems
+ 5 September 2003
+ Description of Modification: - Made creation of attributes structure
+ conditional on its being used. This eliminates
+ 100 bytes of storage for each normal sc_object.
+
+ *****************************************************************************/
+
+
+// $Log: sc_object.cpp,v $
+// Revision 1.16 2011/08/29 18:04:32 acg
+// Philipp A. Hartmann: miscellaneous clean ups.
+//
+// Revision 1.15 2011/08/26 20:46:10 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.14 2011/08/24 22:05:51 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.13 2011/04/01 21:24:57 acg
+// Andy Goodrich: removed unused code.
+//
+// Revision 1.12 2011/03/06 15:55:11 acg
+// Andy Goodrich: Changes for named events.
+//
+// Revision 1.11 2011/03/05 19:44:20 acg
+// Andy Goodrich: changes for object and event naming and structures.
+//
+// Revision 1.10 2011/03/05 04:45:16 acg
+// Andy Goodrich: moved active process calculation to the sc_simcontext class.
+//
+// Revision 1.9 2011/03/05 01:39:21 acg
+// Andy Goodrich: changes for named events.
+//
+// Revision 1.8 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.7 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.6 2011/01/25 20:50:37 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.5 2011/01/18 20:10:44 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.4 2010/08/03 17:02:39 acg
+// Andy Goodrich: formatting changes.
+//
+// Revision 1.3 2009/02/28 00:26:58 acg
+// Andy Goodrich: changed boost name space to sc_boost to allow use with
+// full boost library applications.
+//
+// Revision 1.2 2008/05/22 17:06:26 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.5 2006/04/20 17:08:17 acg
+// Andy Goodrich: 3.0 style process changes.
+//
+// Revision 1.4 2006/03/21 00:00:34 acg
+// Andy Goodrich: changed name of sc_get_current_process_base() to be
+// sc_get_current_process_b() since its returning an sc_process_b instance.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+//
diff --git a/ext/systemc/src/sysc/kernel/sc_object.h b/ext/systemc/src/sysc/kernel/sc_object.h
new file mode 100644
index 000000000..c6e0957a8
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_object.h
@@ -0,0 +1,244 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_object.h -- Abstract base class of all SystemC `simulation' objects.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_OBJECT_H
+#define SC_OBJECT_H
+
+
+#include "sysc/utils/sc_iostream.h"
+#include "sysc/kernel/sc_attribute.h"
+
+namespace sc_core {
+
+class sc_event;
+class sc_module;
+class sc_phase_callback_registry;
+class sc_runnable;
+class sc_simcontext;
+class sc_trace_file;
+class sc_trace_file_base;
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_object
+//
+// Abstract base class of all SystemC `simulation' objects.
+// ----------------------------------------------------------------------------
+
+class sc_object
+{
+ friend class sc_event;
+ friend class sc_module;
+ friend struct sc_invoke_method;
+ friend class sc_module_dynalloc_list;
+ friend class sc_object_manager;
+ friend class sc_phase_callback_registry;
+ friend class sc_process_b;
+ friend class sc_runnable;
+ friend class sc_simcontext;
+ friend class sc_trace_file_base;
+
+public:
+ typedef unsigned phase_cb_mask;
+
+ const char* name() const
+ { return m_name.c_str(); }
+
+ const char* basename() const;
+
+ virtual void print(::std::ostream& os=::std::cout ) const;
+
+ // dump() is more detailed than print()
+ virtual void dump(::std::ostream& os=::std::cout ) const;
+
+ virtual void trace( sc_trace_file* tf ) const;
+
+ virtual const char* kind() const { return "sc_object"; }
+
+ sc_simcontext* simcontext() const
+ { return m_simc; }
+
+ // add attribute
+ bool add_attribute( sc_attr_base& );
+
+ // get attribute by name
+ sc_attr_base* get_attribute( const std::string& name_ );
+ const sc_attr_base* get_attribute( const std::string& name_ ) const;
+
+ // remove attribute by name
+ sc_attr_base* remove_attribute( const std::string& name_ );
+
+ // remove all attributes
+ void remove_all_attributes();
+
+ // get the number of attributes
+ int num_attributes() const;
+
+ // get the attribute collection
+ sc_attr_cltn& attr_cltn();
+ const sc_attr_cltn& attr_cltn() const;
+
+ virtual const std::vector<sc_event*>& get_child_events() const
+ { return m_child_events; }
+
+ virtual const std::vector<sc_object*>& get_child_objects() const
+ { return m_child_objects; }
+
+ sc_object* get_parent() const;
+ sc_object* get_parent_object() const { return m_parent; }
+
+protected:
+
+ sc_object();
+ sc_object(const char* nm);
+
+ sc_object( const sc_object& );
+ sc_object& operator=( const sc_object& );
+
+
+ virtual ~sc_object();
+
+ virtual void add_child_event( sc_event* event_p );
+ virtual void add_child_object( sc_object* object_p );
+ virtual bool remove_child_event( sc_event* event_p );
+ virtual bool remove_child_object( sc_object* object_p );
+
+ phase_cb_mask register_simulation_phase_callback( phase_cb_mask );
+ phase_cb_mask unregister_simulation_phase_callback( phase_cb_mask );
+
+ class hierarchy_scope;
+
+private:
+ void do_simulation_phase_callback();
+ virtual void simulation_phase_callback();
+
+ void detach();
+ virtual void orphan_child_events();
+ virtual void orphan_child_objects();
+ void sc_object_init(const char* nm);
+
+private:
+
+ /* Each simulation object is associated with a simulation context */
+ mutable sc_attr_cltn* m_attr_cltn_p; // attributes for this object.
+ std::vector<sc_event*> m_child_events; // list of child events.
+ std::vector<sc_object*> m_child_objects; // list of child objects.
+ std::string m_name; // name of this object.
+ sc_object* m_parent; // parent for this object.
+ sc_simcontext* m_simc; // simcontext ptr / empty indicator
+};
+
+inline
+sc_object&
+sc_object::operator=( sc_object const & )
+{
+ // deliberately do nothing
+ return *this;
+}
+
+// ----------------------------------------------------------------------------
+
+extern const char SC_HIERARCHY_CHAR;
+extern bool sc_enable_name_checking;
+
+
+inline
+sc_object* sc_get_parent( const sc_object* obj_p )
+{
+ return obj_p->get_parent_object();
+}
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Andy Goodrich, Forte Design Systems
+ 5 September 2003
+ Description of Modification: - Made creation of attributes structure
+ conditional on its being used. This eliminates
+ 100 bytes of storage for each normal sc_object.
+
+ *****************************************************************************/
+
+// $Log: sc_object.h,v $
+// Revision 1.13 2011/08/29 18:04:32 acg
+// Philipp A. Hartmann: miscellaneous clean ups.
+//
+// Revision 1.12 2011/08/26 20:46:10 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.11 2011/03/06 15:55:11 acg
+// Andy Goodrich: Changes for named events.
+//
+// Revision 1.10 2011/03/05 19:44:20 acg
+// Andy Goodrich: changes for object and event naming and structures.
+//
+// Revision 1.9 2011/03/05 01:39:21 acg
+// Andy Goodrich: changes for named events.
+//
+// Revision 1.8 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.7 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.6 2011/01/25 20:50:37 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.5 2011/01/18 20:10:44 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.4 2010/07/22 20:02:33 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.3 2009/02/28 00:26:58 acg
+// Andy Goodrich: changed boost name space to sc_boost to allow use with
+// full boost library applications.
+//
+// Revision 1.2 2008/05/22 17:06:26 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.5 2006/04/20 17:08:17 acg
+// Andy Goodrich: 3.0 style process changes.
+//
+// Revision 1.4 2006/04/11 23:13:21 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+#endif // SC_OBJECT_H
diff --git a/ext/systemc/src/sysc/kernel/sc_object_int.h b/ext/systemc/src/sysc/kernel/sc_object_int.h
new file mode 100644
index 000000000..aca230f8b
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_object_int.h
@@ -0,0 +1,99 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_object_int.h -- For inline definitions of some utility functions.
+ DO NOT EXPORT THIS INCLUDE FILE.
+
+ Original Author: Philipp A. Hartmann, OFFIS, 2013-02-10
+
+ *****************************************************************************/
+
+#ifndef SC_OBJECT_INT_H_INCLUDED_
+#define SC_OBJECT_INT_H_INCLUDED_
+
+#include "sysc/kernel/sc_object.h"
+#include "sysc/kernel/sc_module.h"
+#include "sysc/kernel/sc_simcontext_int.h"
+#include "sysc/kernel/sc_phase_callback_registry.h"
+
+namespace sc_core {
+
+class sc_object::hierarchy_scope
+{
+public:
+ explicit hierarchy_scope(sc_object* obj);
+ explicit hierarchy_scope(sc_module* mod);
+ ~hierarchy_scope();
+
+private:
+ sc_module * scope_;
+
+private:
+ hierarchy_scope( hierarchy_scope const & other ) /* = delete */;
+ hierarchy_scope& operator=(hierarchy_scope const&) /* = delete */;
+};
+
+
+inline
+sc_object::hierarchy_scope::hierarchy_scope( sc_object* obj )
+ : scope_(0)
+{
+ if( !obj ) return;
+
+ scope_ = dynamic_cast<sc_module*>(obj);
+ if( !scope_ )
+ scope_ = dynamic_cast<sc_module*>(obj->get_parent_object());
+ if( scope_ )
+ scope_->simcontext()->hierarchy_push(scope_);
+}
+
+
+inline
+sc_object::hierarchy_scope::hierarchy_scope( sc_module* mod )
+ : scope_(mod)
+{
+ if( scope_ )
+ scope_->simcontext()->hierarchy_push(scope_);
+}
+
+
+inline
+sc_object::hierarchy_scope::~hierarchy_scope()
+{
+ if( scope_ )
+ scope_->simcontext()->hierarchy_pop();
+}
+
+
+// -----------------------------------------------------------------------
+
+inline void
+sc_object::do_simulation_phase_callback()
+{
+ simulation_phase_callback();
+}
+
+// -----------------------------------------------------------------------
+
+} // namespace sc_core
+
+#endif // SC_OBJECT_INT_H_INCLUDED_
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_object_manager.cpp b/ext/systemc/src/sysc/kernel/sc_object_manager.cpp
new file mode 100644
index 000000000..e46413928
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_object_manager.cpp
@@ -0,0 +1,462 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_object_manager.cpp -- Manager of objects (naming, &c.)
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#include <stdio.h>
+#include <cstdlib>
+#include <cassert>
+#include <ctype.h>
+#include <stddef.h>
+#include <algorithm> // pick up std::sort.
+
+#include "sysc/utils/sc_iostream.h"
+#include "sysc/kernel/sc_object.h"
+#include "sysc/utils/sc_hash.h"
+#include "sysc/utils/sc_list.h"
+#include "sysc/utils/sc_mempool.h"
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_object_manager.h"
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/kernel/sc_process.h"
+#include "sysc/kernel/sc_module_name.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_object_manager
+//
+// Manager of objects.
+// ----------------------------------------------------------------------------
+
+sc_object_manager::sc_object_manager() :
+ m_event_it(),
+ m_event_walk_ok(0),
+ m_instance_table(),
+ m_module_name_stack(0),
+ m_object_it(),
+ m_object_stack(),
+ m_object_walk_ok()
+{
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::~sc_object_manager"
+// |
+// | This is the object instance destructor for this class. It goes through
+// | each sc_object instance in the instance table and sets its m_simc field
+// | to NULL.
+// +----------------------------------------------------------------------------
+sc_object_manager::~sc_object_manager()
+{
+ instance_table_t::iterator it; // instance table iterator.
+
+ for ( it = m_instance_table.begin(); it != m_instance_table.end(); it++)
+ {
+ sc_object* obj_p = it->second.m_object_p;
+ if ( obj_p ) obj_p->m_simc = 0;
+ }
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::create_name"
+// |
+// | This method creates a hierarchical name based on the name of the active
+// | object and the supplied leaf name. If the resultant name is not unique it
+// | will be made unique and a warning message issued.
+// |
+// | Arguments:
+// | leaf_name = name to use for the leaf of the hierarchy.
+// | Result is an std::string containing the name.
+// +----------------------------------------------------------------------------
+std::string sc_object_manager::create_name(const char* leaf_name)
+{
+ bool clash; // true if path name exists in obj table
+ std::string leafname_string; // string containing the leaf name.
+ std::string parentname_string; // parent path name
+ sc_object* parent_p; // parent for this instance or NULL.
+ std::string result_orig_string; // save for warning message.
+ std::string result_string; // name to return.
+
+ // CONSTRUCT PATHNAME TO THE NAME TO BE RETURNED:
+ //
+ // If there is not a leaf name generate one.
+
+ parent_p = sc_get_curr_simcontext()->active_object();
+ parentname_string = parent_p ? parent_p->name() : "";
+ leafname_string = leaf_name;
+ if (parent_p) {
+ result_string = parentname_string;
+ result_string += SC_HIERARCHY_CHAR;
+ result_string += leafname_string;
+ } else {
+ result_string = leafname_string;
+ }
+
+ // SAVE the original path name
+
+ result_orig_string = result_string;
+
+ // MAKE SURE THE ENTITY NAME IS UNIQUE:
+ //
+ // If not use unique name generator to make it unique.
+
+ clash = false;
+ for (;;)
+ {
+ instance_table_t::iterator it = m_instance_table.find(result_string);
+ if ( it == m_instance_table.end() ||
+ (it->second.m_event_p == NULL && it->second.m_object_p == NULL ) )
+ {
+ break;
+ }
+ clash = true;
+ leafname_string = sc_gen_unique_name(leafname_string.c_str(), false);
+ if (parent_p) {
+ result_string = parentname_string;
+ result_string += SC_HIERARCHY_CHAR;
+ result_string += leafname_string;
+ } else {
+ result_string = leafname_string;
+ }
+ }
+ if (clash) {
+ std::string message = result_orig_string;
+ message += ". Latter declaration will be renamed to ";
+ message += result_string;
+ SC_REPORT_WARNING( SC_ID_INSTANCE_EXISTS_, message.c_str());
+ }
+
+ return result_string;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::find_event"
+// |
+// | This method returns the sc_event with the supplied name, or a NULL if
+// | the event does not exist.
+// |
+// | Arguments:
+// | name = name of the event
+// | Result is a pointer to the event or NULL if it does not exist.
+// +----------------------------------------------------------------------------
+sc_event*
+sc_object_manager::find_event(const char* name)
+{
+ instance_table_t::iterator it;
+ it = m_instance_table.find(name);
+ return it == m_instance_table.end() ? NULL : it->second.m_event_p;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::find_object"
+// |
+// | This method returns the sc_object with the supplied name, or a NULL if
+// | the object does not exist.
+// |
+// | Arguments:
+// | name = name of the object
+// | Result is a pointer to the object or NULL if it does not exist.
+// +----------------------------------------------------------------------------
+sc_object*
+sc_object_manager::find_object(const char* name)
+{
+ instance_table_t::iterator it;
+ it = m_instance_table.find(name);
+ return it == m_instance_table.end() ? NULL : it->second.m_object_p;
+}
+
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::first_object"
+// |
+// | This method initializes the object iterator to point to the first object
+// | in the instance table, and returns its address. If there are no objects
+// | in the table a NULL value is returned.
+// +----------------------------------------------------------------------------
+sc_object*
+sc_object_manager::first_object()
+{
+ sc_object* result_p; // result to return.
+
+ m_object_walk_ok = true;
+ result_p = NULL;
+ for ( m_object_it = m_instance_table.begin();
+ m_object_it != m_instance_table.end();
+ m_object_it++ )
+ {
+ result_p = m_object_it->second.m_object_p;
+ if ( result_p ) break;
+ }
+ return result_p;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::hierarchy_curr"
+// |
+// | This method returns the current object in the object hierarchy or NULL
+// | if it does not exist.
+// +----------------------------------------------------------------------------
+sc_object*
+sc_object_manager::hierarchy_curr()
+{
+ size_t hierarchy_n; // current size of the hierarchy.
+
+ hierarchy_n = m_object_stack.size();
+ return hierarchy_n ? m_object_stack[hierarchy_n-1] : 0;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::hierarchy_pop"
+// |
+// | This method pops the current object off the object hierarchy and returns
+// | it.
+// +----------------------------------------------------------------------------
+sc_object*
+sc_object_manager::hierarchy_pop()
+{
+ size_t hierarchy_n; // current size of the hierarchy.
+ sc_object* result_p; // object to return.
+
+ hierarchy_n = m_object_stack.size();
+ if ( hierarchy_n == 0 ) return NULL;
+ hierarchy_n--;
+ result_p = m_object_stack[hierarchy_n];
+ m_object_stack.pop_back();
+ return result_p;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::hierarchy_push"
+// |
+// | This method pushes down the sc_object hierarchy to make the supplied
+// | object the current object in the hierarchy.
+// |
+// | Arguments:
+// | object_p -> object to become the new current object in the hierarchy.
+// +----------------------------------------------------------------------------
+void
+sc_object_manager::hierarchy_push(sc_object* object_p)
+{
+ m_object_stack.push_back(object_p);
+}
+
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::hierarchy_size"
+// |
+// | This method returns the current size of the object hierarchy stack.
+// +----------------------------------------------------------------------------
+int
+sc_object_manager::hierarchy_size()
+{
+ return m_object_stack.size();
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::insert_event"
+// |
+// | This method inserts the supplied sc_event instance into the instance
+// | table using the supplied name.
+// |
+// | Arguments:
+// | name = name of the event to be inserted.
+// | event_p -> event to be inserted.
+// +----------------------------------------------------------------------------
+void
+sc_object_manager::insert_event(const std::string& name, sc_event* event_p)
+{
+ m_instance_table[name].m_event_p = event_p;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::insert_object"
+// |
+// | This method inserts the supplied sc_object instance into the instance
+// | table using the supplied name.
+// |
+// | Arguments:
+// | name = name of the event to be inserted.
+// | object_p -> object to be inserted.
+// +----------------------------------------------------------------------------
+void
+sc_object_manager::insert_object(const std::string& name, sc_object* object_p)
+{
+ m_instance_table[name].m_object_p = object_p;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::next_object"
+// |
+// | This method returns the next object pointed to by the instance iterator.
+// +----------------------------------------------------------------------------
+sc_object*
+sc_object_manager::next_object()
+{
+ sc_object* result_p; // result to return.
+
+ assert( m_object_walk_ok );
+
+ if ( m_object_it == m_instance_table.end() ) return NULL;
+ m_object_it++;
+
+ for ( result_p = NULL; m_object_it != m_instance_table.end();
+ m_object_it++ )
+ {
+ result_p = m_object_it->second.m_object_p;
+ if ( result_p ) break;
+ }
+ return result_p;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::pop_module_name"
+// |
+// | This method pops an entry off the module name stack and returns it.
+// +----------------------------------------------------------------------------
+sc_module_name*
+sc_object_manager::pop_module_name()
+{
+ sc_module_name* mod_name = m_module_name_stack;
+ m_module_name_stack = m_module_name_stack->m_next;
+ mod_name->m_next = 0;
+ return mod_name;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::push_module_name"
+// |
+// | This method pushes the supplied entry onto the module name stack.
+// |
+// | Arguments:
+// | mod_name_p -> entry to push onto the module name stack.
+// +----------------------------------------------------------------------------
+void
+sc_object_manager::push_module_name(sc_module_name* mod_name_p)
+{
+ mod_name_p->m_next = m_module_name_stack;
+ m_module_name_stack = mod_name_p;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::top_of_module_name_stack"
+// |
+// | This method returns the module name that is on the top of the module
+// | name stack.
+// +----------------------------------------------------------------------------
+sc_module_name*
+sc_object_manager::top_of_module_name_stack()
+{
+ if( m_module_name_stack == 0 ) {
+ SC_REPORT_ERROR( SC_ID_MODULE_NAME_STACK_EMPTY_, 0 );
+ }
+ return m_module_name_stack;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::remove_event"
+// |
+// | This method removes the sc_event instance with the supplied name from
+// | the table of instances. Note we just clear the pointer since if the name
+// | was for an sc_object the m_event_p pointer will be null anyway.
+// |
+// | Arguments:
+// | name = name of the event to be removed.
+// +----------------------------------------------------------------------------
+void
+sc_object_manager::remove_event(const std::string& name)
+{
+ instance_table_t::iterator it; // instance table iterator.
+ it = m_instance_table.find(name);
+ if ( it != m_instance_table.end() ) it->second.m_event_p = NULL;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::remove_object"
+// |
+// | This method removes the sc_object instance with the supplied name from
+// | the table of instances. Note we just clear the pointer since if the name
+// | was for an sc_event the m_object_p pointer will be null anyway.
+// |
+// | Arguments:
+// | name = name of the object to be removed.
+// +----------------------------------------------------------------------------
+void
+sc_object_manager::remove_object(const std::string& name)
+{
+ instance_table_t::iterator it; // instance table iterator.
+ it = m_instance_table.find(name);
+ if ( it != m_instance_table.end() ) it->second.m_object_p = NULL;
+}
+
+} // namespace sc_core
+
+// $Log: sc_object_manager.cpp,v $
+// Revision 1.13 2011/08/26 20:46:10 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.12 2011/08/24 22:05:51 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.11 2011/06/25 17:08:39 acg
+// Andy Goodrich: Jerome Cornet's changes to use libtool to build the
+// library.
+//
+// Revision 1.10 2011/04/01 21:27:54 acg
+// Andy Goodrich: documentation of event and object insertion methods.
+//
+// Revision 1.9 2011/03/06 15:55:11 acg
+// Andy Goodrich: Changes for named events.
+//
+// Revision 1.8 2011/03/05 19:44:20 acg
+// Andy Goodrich: changes for object and event naming and structures.
+//
+// Revision 1.7 2011/03/05 04:45:16 acg
+// Andy Goodrich: moved active process calculation to the sc_simcontext class.
+//
+// Revision 1.6 2011/03/05 01:39:21 acg
+// Andy Goodrich: changes for named events.
+//
+// Revision 1.5 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.4 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.3 2010/07/22 20:02:33 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.2 2008/05/22 17:06:26 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+//
diff --git a/ext/systemc/src/sysc/kernel/sc_object_manager.h b/ext/systemc/src/sysc/kernel/sc_object_manager.h
new file mode 100644
index 000000000..753252c33
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_object_manager.h
@@ -0,0 +1,139 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_object_manager.h -- Manager of objects (naming, &c.)
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_OBJECT_MANAGER_H
+#define SC_OBJECT_MANAGER_H
+
+#include <map>
+#include <vector>
+
+namespace sc_core {
+
+class sc_event;
+class sc_object;
+class sc_module_name;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_object_manager
+//
+// Manager of objects.
+// ----------------------------------------------------------------------------
+
+class sc_object_manager
+{
+ friend class sc_event;
+ friend class sc_object;
+ friend class sc_simcontext;
+
+protected:
+ struct table_entry
+ {
+ table_entry() : m_event_p(NULL), m_object_p(NULL) {}
+
+ sc_event* m_event_p; // if non-null this is an sc_event.
+ sc_object* m_object_p; // if non-null this is an sc_object.
+ };
+
+public:
+ typedef std::map<std::string,table_entry> instance_table_t;
+ typedef std::vector<sc_object*> object_vector_t;
+
+ sc_object_manager();
+ ~sc_object_manager();
+
+ sc_event* find_event(const char* name);
+
+ sc_object* find_object(const char* name);
+ sc_object* first_object();
+ sc_object* next_object();
+
+ void hierarchy_push(sc_object* mdl);
+ sc_object* hierarchy_pop();
+ sc_object* hierarchy_curr();
+ int hierarchy_size();
+
+ void push_module_name(sc_module_name* mod_name);
+ sc_module_name* pop_module_name();
+ sc_module_name* top_of_module_name_stack();
+
+
+private:
+ std::string create_name( const char* leaf_name );
+ void insert_event(const std::string& name, sc_event* obj);
+ void insert_object(const std::string& name, sc_object* obj);
+ void remove_event(const std::string& name);
+ void remove_object(const std::string& name);
+
+private:
+
+ instance_table_t::iterator m_event_it; // event instance iterator.
+ bool m_event_walk_ok; // true if can walk events.
+ instance_table_t m_instance_table; // table of instances.
+ sc_module_name* m_module_name_stack; // sc_module_name stack.
+ instance_table_t::iterator m_object_it; // object instance iterator.
+ object_vector_t m_object_stack; // sc_object stack.
+ bool m_object_walk_ok; // true if can walk objects.
+};
+
+} // namespace sc_core
+
+// $Log: sc_object_manager.h,v $
+// Revision 1.9 2011/08/26 20:46:10 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.8 2011/03/06 15:55:11 acg
+// Andy Goodrich: Changes for named events.
+//
+// Revision 1.7 2011/03/05 19:44:20 acg
+// Andy Goodrich: changes for object and event naming and structures.
+//
+// Revision 1.6 2011/03/05 01:39:21 acg
+// Andy Goodrich: changes for named events.
+//
+// Revision 1.5 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.4 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.3 2010/07/22 20:02:33 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.2 2008/05/22 17:06:26 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+#endif
diff --git a/ext/systemc/src/sysc/kernel/sc_phase_callback_registry.cpp b/ext/systemc/src/sysc/kernel/sc_phase_callback_registry.cpp
new file mode 100644
index 000000000..84f15c93f
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_phase_callback_registry.cpp
@@ -0,0 +1,301 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_phase_callback_registry.cpp -- Implementation of phase callback registry
+
+ Original Author: Philipp A. Hartmann, OFFIS, 2013-02-15
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+#include "sysc/kernel/sc_object.h"
+#include "sysc/kernel/sc_phase_callback_registry.h"
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/utils/sc_report.h"
+
+#include <algorithm>
+#include <functional>
+
+namespace sc_core {
+
+#if SC_HAS_PHASE_CALLBACKS_
+
+sc_phase_callback_registry::sc_phase_callback_registry( sc_simcontext& simc )
+ : m_simc( &simc )
+#if 0
+ , m_cb_eval_vec()
+#endif
+ , m_cb_update_vec()
+ , m_cb_timestep_vec()
+{}
+
+sc_phase_callback_registry::~sc_phase_callback_registry()
+{}
+
+static const sc_phase_callback_registry::mask_type
+ SC_PHASE_CALLBACK_MASK = SC_STATUS_ANY;
+
+namespace /* anonymous */ {
+
+struct entry_match
+ : std::unary_function< sc_phase_callback_registry::entry, bool >
+{
+ typedef sc_phase_callback_registry::cb_type* ref_type;
+
+ explicit
+ entry_match( ref_type ref )
+ : ref_(ref)
+ {}
+
+ result_type operator()( argument_type e )
+ { return e.target == ref_; }
+private:
+ sc_phase_callback_registry::cb_type * ref_;
+
+}; // entry_match
+
+template< typename T >
+inline void
+erase_remove( std::vector<T>* vec, T const& t )
+{
+ vec->erase( std::remove( vec->begin(), vec->end(), t ) );
+}
+
+} // namespace anonymous
+
+
+sc_phase_callback_registry::mask_type
+sc_phase_callback_registry::validate_mask( cb_type& cb
+ , mask_type m
+ , bool warn = false )
+{
+ if( SC_UNLIKELY_(m & ~SC_PHASE_CALLBACK_MASK) )
+ {
+ if( warn )
+ {
+ std::stringstream ss;
+ ss << cb.name() << ": invalid phase callback mask: "
+ << (sc_status)m;
+ SC_REPORT_WARNING( SC_ID_PHASE_CALLBACK_REGISTER_
+ , ss.str().c_str() );
+ }
+ m &= SC_PHASE_CALLBACK_MASK;
+ }
+
+ mask_type check_mask;
+
+ // elaboration callbacks
+ check_mask = ( SC_ELABORATION
+ | SC_BEFORE_END_OF_ELABORATION
+ | SC_END_OF_ELABORATION );
+ if( SC_UNLIKELY_( (m & check_mask ) && m_simc->elaboration_done() ) )
+ {
+ if( warn )
+ {
+ std::stringstream ss;
+ ss << cb.name() << ": elaboration done\n\t "
+ << (sc_status)( m & check_mask ) << " callback(s) ignored";
+ SC_REPORT_WARNING(SC_ID_PHASE_CALLBACK_REGISTER_
+ , ss.str().c_str() );
+ }
+ m &= ~check_mask;
+ }
+
+ check_mask = (SC_BEFORE_END_OF_ELABORATION | SC_END_OF_ELABORATION);
+ if( SC_UNLIKELY_(m & SC_ELABORATION) )
+ {
+ if( warn )
+ {
+ std::stringstream ss;
+ ss << cb.name() << ": " << SC_ELABORATION
+ << ":\n\t substituted by " << (sc_status)(check_mask);
+ SC_REPORT_WARNING( SC_ID_PHASE_CALLBACK_REGISTER_
+ , ss.str().c_str() );
+ }
+ m &= ~SC_ELABORATION;
+ m |= check_mask;
+ }
+
+ check_mask = ( SC_END_OF_INITIALIZATION
+#if 0
+ | SC_END_OF_EVALUATION
+#endif
+ | SC_END_OF_UPDATE
+ | SC_BEFORE_TIMESTEP );
+ if( SC_UNLIKELY_(m & SC_RUNNING) )
+ {
+ if( warn )
+ {
+ std::stringstream ss;
+ ss << cb.name() << ": " << SC_RUNNING
+ << ":\n\t substituted by " << (sc_status)(check_mask);
+ SC_REPORT_WARNING( SC_ID_PHASE_CALLBACK_REGISTER_
+ , ss.str().c_str() );
+ }
+ m &= ~SC_RUNNING;
+ m |= check_mask;
+ }
+ return m;
+}
+
+
+sc_phase_callback_registry::mask_type
+sc_phase_callback_registry::register_callback( cb_type& cb, mask_type m )
+{
+ storage_type::iterator it =
+ find_if( m_cb_vec.begin(), m_cb_vec.end(), entry_match(&cb) );
+
+ m = validate_mask(cb, m, /* warn */ true );
+
+ mask_type diff_mask = m;
+ mask_type new_mask = m;
+
+ if( it != m_cb_vec.end() ) // update existing entry
+ {
+ // update masks
+ new_mask = (*it).mask | m;
+ diff_mask = ~(*it).mask & m;
+ (*it).mask = new_mask;
+ }
+ else // new entry
+ {
+ if( !m ) // empty, do nothing
+ return SC_UNITIALIZED;
+
+ entry new_entry = { &cb, new_mask };
+ m_cb_vec.push_back( new_entry );
+ }
+
+ // add to callback shortcut sets
+#if 0
+ if( diff_mask & SC_END_OF_EVALUATION )
+ m_cb_eval_vec.push_back( &cb );
+#endif
+ if( diff_mask & SC_END_OF_UPDATE )
+ m_cb_update_vec.push_back( &cb );
+ if( diff_mask & SC_BEFORE_TIMESTEP )
+ m_cb_timestep_vec.push_back( &cb );
+
+ return new_mask;
+}
+
+
+sc_phase_callback_registry::mask_type
+sc_phase_callback_registry::unregister_callback( cb_type& cb, mask_type m )
+{
+ storage_type::iterator it =
+ find_if( m_cb_vec.begin(), m_cb_vec.end(), entry_match(&cb) );
+
+ m = validate_mask(cb, m);
+
+ mask_type diff_mask = m;
+ mask_type new_mask = m;
+
+ if( it == m_cb_vec.end() ) { // not registered
+ return SC_UNITIALIZED;
+ }
+
+ // update masks
+ new_mask = (*it).mask & ~m;
+ diff_mask = (*it).mask & m;
+ (*it).mask = new_mask;
+
+ if( !new_mask )
+ m_cb_vec.erase(it);
+
+ // drop from callback shortcut sets
+#if 0
+ if( diff_mask & SC_END_OF_EVALUATION )
+ erase_remove( &m_cb_eval_vec, &cb );
+#endif
+ if( diff_mask & SC_END_OF_UPDATE )
+ erase_remove( &m_cb_update_vec, &cb );
+ if( diff_mask & SC_BEFORE_TIMESTEP )
+ erase_remove( &m_cb_timestep_vec, &cb );
+
+ return new_mask;
+}
+
+
+// generic implementation (for non-critical callbacks)
+// - also restores hierarchy around callback object
+void
+sc_phase_callback_registry::do_callback( sc_status s ) const
+{
+ typedef storage_type::const_iterator it_type;
+ storage_type const & vec = m_cb_vec;
+
+ for(it_type it = vec.begin(), end = vec.end(); it != end; ++it) {
+ if( s & it->mask ) {
+ sc_object::hierarchy_scope scope(it->target);
+ it->target->do_simulation_phase_callback();
+ }
+ }
+}
+
+#else // ! SC_HAS_PHASE_CALLBACKS_
+
+sc_phase_callback_registry::sc_phase_callback_registry( sc_simcontext& ){}
+sc_phase_callback_registry::~sc_phase_callback_registry(){}
+
+static inline void
+warn_phase_callbacks( sc_core::sc_object const& obj )
+{
+ static bool warned = false;
+ if (!warned)
+ {
+ std::stringstream ss;
+ ss << obj.name() << ".\n"
+ << "Please recompile SystemC with "
+ "\"SC_ENABLE_SIMULATION_PHASE_CALLBACKS\" defined.";
+ SC_REPORT_WARNING( SC_ID_PHASE_CALLBACKS_UNSUPPORTED_
+ , ss.str().c_str() );
+ }
+}
+
+sc_phase_callback_registry::mask_type
+sc_phase_callback_registry::register_callback( cb_type& cb, mask_type )
+{
+ warn_phase_callbacks( cb );
+ return SC_UNITIALIZED;
+}
+
+sc_phase_callback_registry::mask_type
+sc_phase_callback_registry::unregister_callback( cb_type& cb, mask_type )
+{
+ warn_phase_callbacks( cb );
+ return SC_UNITIALIZED;
+}
+
+#endif // ! SC_HAS_PHASE_CALLBACKS_
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_phase_callback_registry.h b/ext/systemc/src/sysc/kernel/sc_phase_callback_registry.h
new file mode 100644
index 000000000..9510c0d3f
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_phase_callback_registry.h
@@ -0,0 +1,276 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_phase_callback_registry.h -- Definition of the simulation phase callbacks
+
+ The most critical functions are defined inline in this file. Only active,
+ if SC_ENABLE_SIMULATION_PHASE_CALLBACKS[_TRACING] is defined during the
+ SystemC library build.
+
+ Original Author: Philipp A. Hartmann, OFFIS, 2013-02-15
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+#ifndef SC_PHASE_CALLBACK_REGISTRY_H_INCLUDED_
+#define SC_PHASE_CALLBACK_REGISTRY_H_INCLUDED_
+
+#if defined( SC_ENABLE_SIMULATION_PHASE_CALLBACKS ) \
+ || defined( SC_ENABLE_SIMULATION_PHASE_CALLBACKS_TRACING )
+# define SC_HAS_PHASE_CALLBACKS_ 1
+#else
+# define SC_HAS_PHASE_CALLBACKS_ 0
+#endif
+
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_object_int.h"
+#include "sysc/kernel/sc_status.h"
+
+#include <vector>
+
+namespace sc_core {
+
+class sc_simcontext;
+class sc_object;
+
+class sc_phase_callback_registry
+{
+public:
+ typedef sc_phase_callback_registry this_type;
+ typedef sc_object cb_type;
+ typedef cb_type::phase_cb_mask mask_type;
+
+ struct entry
+ {
+ cb_type* target;
+ mask_type mask;
+ };
+
+ friend class sc_simcontext;
+ friend class sc_object;
+
+private: // interface completely internal
+
+ explicit
+ sc_phase_callback_registry( sc_simcontext& simc );
+
+ ~sc_phase_callback_registry();
+
+ // --- callback forwarders
+
+ bool construction_done() const; //< returns false
+ void elaboration_done() const;
+ void initialization_done() const;
+ void start_simulation() const;
+
+ void evaluation_done() const;
+ void update_done() const;
+ void before_timestep() const;
+
+ void simulation_paused() const;
+ void simulation_stopped() const;
+ void simulation_done() const;
+
+
+ // --- callback registration and implementation
+
+ mask_type register_callback( cb_type&, mask_type mask );
+ mask_type unregister_callback( cb_type&, mask_type mask );
+
+ // generic caller
+ void do_callback( sc_status ) const;
+
+private:
+ typedef std::vector<entry> storage_type;
+ typedef std::vector<cb_type*> single_storage_type;
+
+#if SC_HAS_PHASE_CALLBACKS_
+
+ // set and restore simulation status
+ struct scoped_status
+ {
+ scoped_status( sc_status& ref, sc_status s )
+ : ref_(ref), prev_(ref) { ref_ = s;}
+ ~scoped_status() { ref_ = prev_; }
+ private:
+ sc_status& ref_;
+ sc_status prev_;
+ }; // scoped_status
+
+ mask_type validate_mask( cb_type&, mask_type, bool warn );
+
+private:
+
+ sc_simcontext* m_simc;
+ storage_type m_cb_vec; // all callbacks
+#if 0
+ single_storage_type m_cb_eval_vec; // - eval cb shortcut
+#endif
+ single_storage_type m_cb_update_vec; // - update cb shortcut
+ single_storage_type m_cb_timestep_vec; // - timestep cb shortcut
+
+#endif // SC_HAS_PHASE_CALLBACKS_
+
+private:
+ // disabled
+ sc_phase_callback_registry( const this_type& );
+ this_type& operator=(const this_type&);
+
+}; // sc_phase_callback_registry
+
+
+// -------------------- callback implementations --------------------
+// (empty, if feature is disabled)
+
+inline bool
+sc_phase_callback_registry::construction_done() const
+{
+#if SC_HAS_PHASE_CALLBACKS_
+ do_callback( SC_BEFORE_END_OF_ELABORATION );
+#endif
+ return false;
+}
+
+inline void
+sc_phase_callback_registry::elaboration_done() const
+{
+#if SC_HAS_PHASE_CALLBACKS_
+ do_callback( SC_END_OF_ELABORATION );
+#endif
+}
+
+inline void
+sc_phase_callback_registry::start_simulation() const
+{
+#if SC_HAS_PHASE_CALLBACKS_
+ do_callback( SC_START_OF_SIMULATION );
+#endif
+}
+
+inline void
+sc_phase_callback_registry::initialization_done() const
+{
+#if SC_HAS_PHASE_CALLBACKS_
+ scoped_status scope( m_simc->m_simulation_status
+ , SC_END_OF_INITIALIZATION );
+
+ do_callback( SC_END_OF_INITIALIZATION );
+#endif
+}
+
+inline void
+sc_phase_callback_registry::simulation_paused() const
+{
+#if SC_HAS_PHASE_CALLBACKS_
+ do_callback( SC_PAUSED );
+#endif
+}
+
+inline void
+sc_phase_callback_registry::simulation_stopped() const
+{
+#if SC_HAS_PHASE_CALLBACKS_
+ do_callback( SC_STOPPED );
+#endif
+}
+
+inline void
+sc_phase_callback_registry::simulation_done() const
+{
+#if SC_HAS_PHASE_CALLBACKS_
+ do_callback( SC_END_OF_SIMULATION );
+#endif
+}
+
+// -------------- specialized callback implementations --------------
+
+#if 0
+inline void
+sc_phase_callback_registry::evaluation_done() const
+{
+#if SC_HAS_PHASE_CALLBACKS_
+
+ if( !m_cb_eval_vec.size() ) return;
+
+ typedef single_storage_type::const_iterator it_type;
+ single_storage_type const & vec = m_cb_eval_vec;
+
+ scoped_status scope( m_simc->m_simulation_status
+ , SC_END_OF_EVALUATION );
+
+ for(it_type it = vec.begin(), end = vec.end(); it != end; ++it)
+ (*it)->do_simulation_phase_callback();
+#endif
+}
+#endif
+
+inline void
+sc_phase_callback_registry::update_done() const
+{
+#if SC_HAS_PHASE_CALLBACKS_
+
+ if( !m_cb_update_vec.size() ) return;
+
+ typedef single_storage_type::const_iterator it_type;
+ single_storage_type const & vec = m_cb_update_vec;
+
+ scoped_status scope( m_simc->m_simulation_status
+ , SC_END_OF_UPDATE );
+
+ for(it_type it = vec.begin(), end = vec.end(); it != end; ++it)
+ (*it)->do_simulation_phase_callback();
+#endif
+}
+
+inline void
+sc_phase_callback_registry::before_timestep() const
+{
+#if SC_HAS_PHASE_CALLBACKS_
+
+ if( !m_cb_timestep_vec.size() ) return;
+
+ typedef single_storage_type::const_iterator it_type;
+ single_storage_type const & vec = m_cb_timestep_vec;
+
+ scoped_status scope( m_simc->m_simulation_status
+ , SC_BEFORE_TIMESTEP );
+
+ for(it_type it = vec.begin(), end = vec.end(); it != end; ++it)
+ (*it)->do_simulation_phase_callback();
+#endif
+}
+
+// ------------------------------------------------------------------
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+#endif /* SC_PHASE_CALLBACK_REGISTRY_H_INCLUDED_ */
+// Taf!
+
diff --git a/ext/systemc/src/sysc/kernel/sc_process.cpp b/ext/systemc/src/sysc/kernel/sc_process.cpp
new file mode 100644
index 000000000..353eddd6a
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_process.cpp
@@ -0,0 +1,854 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_process.cpp -- Base process implementation.
+
+ Original Authors: Andy Goodrich, Forte Design Systems, 17 June 2003
+ Stuart Swan, Cadence
+ Bishnupriya Bhattacharya, Cadence Design Systems,
+ 25 August, 2003
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include "sysc/kernel/sc_name_gen.h"
+#include "sysc/kernel/sc_cthread_process.h"
+#include "sysc/kernel/sc_method_process.h"
+#include "sysc/kernel/sc_thread_process.h"
+#include "sysc/kernel/sc_sensitive.h"
+#include "sysc/kernel/sc_process_handle.h"
+#include "sysc/kernel/sc_event.h"
+#include <sstream>
+
+namespace sc_core {
+
+// sc_process_handle entities that are returned for null pointer instances:
+//
+// Note the special name for 'non_event' - this makes sure it does not
+// appear as a named event.
+
+std::vector<sc_event*> sc_process_handle::empty_event_vector;
+std::vector<sc_object*> sc_process_handle::empty_object_vector;
+sc_event sc_process_handle::non_event(SC_KERNEL_EVENT_PREFIX);
+
+// Last process that was created:
+
+sc_process_b* sc_process_b::m_last_created_process_p = 0;
+
+//------------------------------------------------------------------------------
+//"sc_process_b::add_static_event"
+//
+// This method adds an event to the list of static events, and sets the
+// event up to call back this process when it fires.
+//------------------------------------------------------------------------------
+void sc_process_b::add_static_event( const sc_event& e )
+{
+ sc_method_handle method_h; // This process as a method.
+ sc_thread_handle thread_h; // This process as a thread.
+
+
+ // CHECK TO SEE IF WE ARE ALREADY REGISTERED WITH THE EVENT:
+
+ for( int i = m_static_events.size() - 1; i >= 0; -- i ) {
+ if( &e == m_static_events[i] ) {
+ return;
+ }
+ }
+
+ // REMEMBER THE EVENT AND THEN REGISTER OUR OBJECT INSTANCE WITH IT:
+
+ m_static_events.push_back( &e );
+
+ switch ( m_process_kind )
+ {
+ case SC_THREAD_PROC_:
+ case SC_CTHREAD_PROC_:
+ thread_h = SCAST<sc_thread_handle>( this );
+ e.add_static( thread_h );
+ break;
+ case SC_METHOD_PROC_:
+ method_h = SCAST<sc_method_handle>( this );
+ e.add_static( method_h );
+ break;
+ default:
+ assert( false );
+ break;
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::disconnect_process"
+//
+// This method removes this object instance from use. It will be called by
+// the kill_process() methods of classes derived from it. This object instance
+// will be removed from any data structures it resides, other than existence.
+//------------------------------------------------------------------------------
+void sc_process_b::disconnect_process()
+{
+ int mon_n; // monitor queue size.
+ sc_thread_handle thread_h; // This process as a thread.
+
+ // IF THIS OBJECT IS PINING FOR THE FJORDS WE ARE DONE:
+
+ if ( m_state & ps_bit_zombie ) return;
+
+ // IF THIS IS A THREAD SIGNAL ANY MONITORS WAITING FOR IT TO EXIT:
+
+ switch ( m_process_kind )
+ {
+ case SC_THREAD_PROC_:
+ case SC_CTHREAD_PROC_:
+ thread_h = SCAST<sc_thread_handle>(this);
+ mon_n = thread_h->m_monitor_q.size();
+ if ( mon_n )
+ {
+ for ( int mon_i = 0; mon_i < mon_n; mon_i++ )
+ {
+ thread_h->m_monitor_q[mon_i]->signal( thread_h,
+ sc_process_monitor::spm_exit);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ // REMOVE EVENT WAITS, AND REMOVE THE PROCESS FROM ITS SC_RESET:
+
+ remove_dynamic_events();
+ remove_static_events();
+
+ for ( std::vector<sc_reset*>::size_type rst_i = 0; rst_i < m_resets.size(); rst_i++ )
+ {
+ m_resets[rst_i]->remove_process( this );
+ }
+ m_resets.resize(0);
+
+
+ // FIRE THE TERMINATION EVENT, MARK AS TERMINATED, AND DECREMENT THE COUNT:
+ //
+ // (1) We wait to set the process kind until after doing the removals
+ // above.
+ // (2) Decrementing the reference count will result in actual object
+ // deletion if we hit zero.
+
+ m_state = ps_bit_zombie;
+ if ( m_term_event_p ) m_term_event_p->notify();
+ reference_decrement();
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::delete_process"
+//
+// This method deletes the current instance, if it is not the running
+// process. Otherwise, it is put in the simcontext's process deletion
+// queue.
+//
+// The reason for the two step deletion process is that the process from which
+// reference_decrement() is called may be the running process, so we may need
+// to wait until it goes idle.
+//------------------------------------------------------------------------------
+void sc_process_b::delete_process()
+{
+ assert( m_references_n == 0 );
+
+ // Immediate deletion:
+
+ if ( this != sc_get_current_process_b() )
+ {
+ delete this;
+ }
+
+ // Deferred deletion: note we set the reference count to one for the call
+ // to reference_decrement that occurs in sc_simcontext::crunch().
+
+ else
+ {
+ m_references_n = 1;
+ detach();
+ simcontext()->mark_to_collect_process( this );
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_process_b::dont_initialize"
+//
+// This virtual method sets the initialization switch for this object instance.
+//------------------------------------------------------------------------------
+void sc_process_b::dont_initialize( bool dont )
+{
+ m_dont_init = dont;
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::dump_state"
+//
+// This method returns the process state as a string.
+//------------------------------------------------------------------------------
+std::string sc_process_b::dump_state() const
+{
+ std::string result;
+ result = "[";
+ if ( m_state == ps_normal )
+ {
+ result += " normal";
+ }
+ else
+ {
+ if ( m_state & ps_bit_disabled )
+ result += "disabled ";
+ if ( m_state & ps_bit_suspended )
+ result += "suspended ";
+ if ( m_state & ps_bit_ready_to_run )
+ result += "ready_to_run ";
+ if ( m_state & ps_bit_zombie )
+ result += "zombie ";
+ }
+ result += "]";
+ return result;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_process_b::gen_unique_name"
+//
+// This method generates a unique name within this object instance's namespace.
+//------------------------------------------------------------------------------
+const char* sc_process_b::gen_unique_name( const char* basename_,
+ bool preserve_first )
+{
+ if ( ! m_name_gen_p ) m_name_gen_p = new sc_name_gen;
+ return m_name_gen_p->gen_unique_name( basename_, preserve_first );
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::remove_dynamic_events"
+//
+// This method removes this object instance from the events in its dynamic
+// event lists.
+//
+// Arguments:
+// skip_timeout = skip cleaning up the timeout event, it will be done
+// by sc_event_notify().
+//------------------------------------------------------------------------------
+void
+sc_process_b::remove_dynamic_events( bool skip_timeout )
+{
+ sc_method_handle method_h; // This process as a method.
+ sc_thread_handle thread_h; // This process as a thread.
+
+ m_trigger_type = STATIC;
+ switch ( m_process_kind )
+ {
+ case SC_THREAD_PROC_:
+ case SC_CTHREAD_PROC_:
+ thread_h = SCAST<sc_thread_handle>(this);
+ if ( thread_h->m_timeout_event_p && !skip_timeout ) {
+ thread_h->m_timeout_event_p->remove_dynamic(thread_h);
+ thread_h->m_timeout_event_p->cancel();
+ }
+ if ( m_event_p ) m_event_p->remove_dynamic( thread_h );
+ if ( m_event_list_p )
+ {
+ m_event_list_p->remove_dynamic( thread_h, 0 );
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ }
+ break;
+ case SC_METHOD_PROC_:
+ method_h = SCAST<sc_method_handle>(this);
+ if ( method_h->m_timeout_event_p && !skip_timeout ) {
+ method_h->m_timeout_event_p->remove_dynamic(method_h);
+ method_h->m_timeout_event_p->cancel();
+ }
+ if ( m_event_p ) m_event_p->remove_dynamic( method_h );
+ if ( m_event_list_p )
+ {
+ m_event_list_p->remove_dynamic( method_h, 0 );
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ }
+ break;
+ default: // Some other type, it needs to clean up itself.
+ // std::cout << "Check " << __FILE__ << ":" << __LINE__ << std::endl;
+ break;
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::remove_static_events"
+//
+// This method removes this object instance from the events in its static
+// event list.
+//------------------------------------------------------------------------------
+void
+sc_process_b::remove_static_events()
+{
+ sc_method_handle method_h; // This process as a method.
+ sc_thread_handle thread_h; // This process as a thread.
+
+ switch ( m_process_kind )
+ {
+ case SC_THREAD_PROC_:
+ case SC_CTHREAD_PROC_:
+ thread_h = SCAST<sc_thread_handle>( this );
+ for( int i = m_static_events.size() - 1; i >= 0; -- i ) {
+ m_static_events[i]->remove_static( thread_h );
+ }
+ m_static_events.resize(0);
+ break;
+ case SC_METHOD_PROC_:
+ method_h = DCAST<sc_method_handle>( this );
+ assert( method_h != 0 );
+ for( int i = m_static_events.size() - 1; i >= 0; -- i ) {
+ m_static_events[i]->remove_static( method_h );
+ }
+ m_static_events.resize(0);
+ break;
+ default: // Some other type, it needs to clean up itself.
+ // std::cout << "Check " << __FILE__ << ":" << __LINE__ << std::endl;
+ break;
+ }
+}
+
+//------------------------------------------------------------------------------
+// "sc_process_b::report_error"
+//
+// This method can be used to issue a report from within a process.
+// The error of the given ID is reported with the given message and
+// the process' name() appended to the report.
+//------------------------------------------------------------------------------
+void
+sc_process_b::report_error( const char* msgid, const char* msg ) const
+{
+ std::stringstream sstr;
+ if( msg && msg[0] )
+ sstr << msg << ": ";
+ sstr << name();
+ SC_REPORT_ERROR( msgid, sstr.str().c_str() );
+}
+
+
+//------------------------------------------------------------------------------
+// "sc_process_b::report_immediate_self_notification"
+//
+// This method is used to report an immediate self-notification
+// that used to trigger the process before the clarification in 1666-2011.
+// The warning is only reported once.
+//------------------------------------------------------------------------------
+void
+sc_process_b::report_immediate_self_notification() const
+{
+ static bool once = false;
+ if( !once ) {
+ SC_REPORT_WARNING( SC_ID_IMMEDIATE_SELF_NOTIFICATION_, name() );
+ once = true;
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::reset_changed"
+//
+// This method is called when there is a change in the value of the
+// signal that was specified via reset_signal_is, or the value of the
+// m_sticky_reset field. We get called any time m_sticky_reset changes
+// or a signal value changes since, since we may need to throw an exception
+// or clear one. Note that this method may be called when there is no
+// active process, but rather the main simulator is executing so we must
+// check for that case.
+//
+// Arguments:
+// async = true if this is an asynchronous reset.
+// asserted = true if reset being asserted, false if being deasserted.
+//------------------------------------------------------------------------------
+void sc_process_b::reset_changed( bool async, bool asserted )
+{
+
+ // Error out on the corner case:
+
+ if ( !sc_allow_process_control_corners && !async &&
+ (m_state & ps_bit_suspended) )
+ {
+ report_error( SC_ID_PROCESS_CONTROL_CORNER_CASE_,
+ "synchronous reset changed on a suspended process" );
+ }
+
+ // IF THIS OBJECT IS PUSHING UP DAISIES WE ARE DONE:
+
+ if ( m_state & ps_bit_zombie ) return;
+
+ // Reset is being asserted:
+
+ if ( asserted )
+ {
+ // if ( m_reset_event_p ) m_reset_event_p->notify();
+ if ( async )
+ {
+ m_active_areset_n++;
+ if ( sc_is_running() ) throw_reset(true);
+ }
+ else
+ {
+ m_active_reset_n++;
+ if ( sc_is_running() ) throw_reset(false);
+ }
+ }
+
+ // Reset is being deasserted:
+
+ else
+ {
+ if ( async )
+ {
+ m_active_areset_n--;
+ }
+ else
+ {
+ m_active_reset_n--;
+ }
+ }
+
+ // Clear the throw type if there are no active resets.
+
+ if ( (m_throw_status == THROW_SYNC_RESET ||
+ m_throw_status == THROW_ASYNC_RESET) &&
+ m_active_areset_n == 0 && m_active_reset_n == 0 && !m_sticky_reset )
+ {
+ m_throw_status = THROW_NONE;
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::reset_event"
+//
+// This method returns a reference to the reset event for this object
+// instance. If no event exists one is allocated.
+//------------------------------------------------------------------------------
+sc_event& sc_process_b::reset_event()
+{
+ if ( !m_reset_event_p )
+ {
+ m_reset_event_p = new sc_event(
+ (std::string(SC_KERNEL_EVENT_PREFIX)+"_reset_event").c_str() );
+ }
+ return *m_reset_event_p;
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::reset_process"
+//
+// This inline method changes the reset state of this object instance and
+// conditionally its descendants.
+//
+// Notes:
+// (1) It is called for sync_reset_on() and sync_reset_off(). It is not used
+// for signal sensitive resets, though all reset flow ends up in
+// reset_changed().
+//
+// Arguments:
+// rt = source of the reset:
+// * reset_asynchronous - sc_process_handle::reset()
+// * reset_synchronous_off - sc_process_handle::sync_reset_off()
+// * reset_synchronous_on - sc_process_handle::sync_reset_on()
+// descendants = indication of how to process descendants.
+//------------------------------------------------------------------------------
+void sc_process_b::reset_process( reset_type rt,
+ sc_descendant_inclusion_info descendants )
+{
+
+ // PROCESS THIS OBJECT INSTANCE'S DESCENDANTS IF REQUESTED TO:
+
+ if ( descendants == SC_INCLUDE_DESCENDANTS )
+ {
+ const std::vector<sc_object*> children = get_child_objects();
+ int child_n = children.size();
+
+ for ( int child_i = 0; child_i < child_n; child_i++ )
+ {
+ sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]);
+ if ( child_p ) child_p->reset_process(rt, descendants);
+ }
+ }
+
+ // PROCESS THIS OBJECT INSTANCE:
+
+ switch (rt)
+ {
+ // One-shot asynchronous reset: remove dynamic sensitivity and throw:
+ //
+ // If this is an sc_method only throw if it is active.
+
+ case reset_asynchronous:
+ if ( sc_get_status() != SC_RUNNING )
+ {
+ report_error(SC_ID_RESET_PROCESS_WHILE_NOT_RUNNING_);
+ }
+ else
+ {
+ remove_dynamic_events();
+ throw_reset(true);
+ }
+ break;
+
+ // Turn on sticky synchronous reset: use standard reset mechanism.
+
+ case reset_synchronous_on:
+ if ( m_sticky_reset == false )
+ {
+ m_sticky_reset = true;
+ reset_changed( false, true );
+ }
+ break;
+
+ // Turn off sticky synchronous reset: use standard reset mechanism.
+
+ default:
+ if ( m_sticky_reset == true )
+ {
+ m_sticky_reset = false;
+ reset_changed( false, false );
+ }
+ break;
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::sc_process_b"
+//
+// This is the object instance constructor for this class.
+//------------------------------------------------------------------------------
+sc_process_b::sc_process_b( const char* name_p, bool is_thread, bool free_host,
+ SC_ENTRY_FUNC method_p, sc_process_host* host_p,
+ const sc_spawn_options* /* opt_p */
+) :
+ sc_object( name_p ),
+ file(0),
+ lineno(0),
+ proc_id( simcontext()->next_proc_id()),
+ m_active_areset_n(0),
+ m_active_reset_n(0),
+ m_dont_init( false ),
+ m_dynamic_proc( simcontext()->elaboration_done() ),
+ m_event_p(0),
+ m_event_count(0),
+ m_event_list_p(0),
+ m_exist_p(0),
+ m_free_host( free_host ),
+ m_has_reset_signal( false ),
+ m_has_stack(false),
+ m_is_thread(is_thread),
+ m_last_report_p(0),
+ m_name_gen_p(0),
+ m_process_kind(SC_NO_PROC_),
+ m_references_n(1),
+ m_resets(),
+ m_reset_event_p(0),
+ m_resume_event_p(0),
+ m_runnable_p(0),
+ m_semantics_host_p( host_p ),
+ m_semantics_method_p ( method_p ),
+ m_state(ps_normal),
+ m_static_events(),
+ m_sticky_reset(false),
+ m_term_event_p(0),
+ m_throw_helper_p(0),
+ m_throw_status( THROW_NONE ),
+ m_timed_out(false),
+ m_timeout_event_p(0),
+ m_trigger_type(STATIC),
+ m_unwinding(false)
+{
+
+ // THIS OBJECT INSTANCE IS NOW THE LAST CREATED PROCESS:
+
+ m_last_created_process_p = this;
+ m_timeout_event_p = new sc_event(
+ (std::string(SC_KERNEL_EVENT_PREFIX)+"_free_event").c_str() );
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::~sc_process_b"
+//
+// This is the object instance destructor for this class.
+//------------------------------------------------------------------------------
+sc_process_b::~sc_process_b()
+{
+
+ // REDIRECT ANY CHILDREN AS CHILDREN OF THE SIMULATION CONTEXT:
+
+ orphan_child_objects();
+
+
+ // DELETE SEMANTICS OBJECTS IF NEED BE:
+
+ if ( m_free_host ) delete m_semantics_host_p;
+# if !defined(SC_USE_MEMBER_FUNC_PTR) // Remove invocation object.
+ delete m_semantics_method_p;
+# endif
+
+
+ // REMOVE ANY STRUCTURES THAT MAY HAVE BEEN BUILT:
+
+ delete m_last_report_p;
+ delete m_name_gen_p;
+ delete m_reset_event_p;
+ delete m_resume_event_p;
+ delete m_term_event_p;
+ delete m_throw_helper_p;
+ delete m_timeout_event_p;
+
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::terminated_event"
+//
+// This method returns a reference to the terminated event for this object
+// instance. If no event exists one is allocated.
+//------------------------------------------------------------------------------
+sc_event& sc_process_b::terminated_event()
+{
+ if ( !m_term_event_p )
+ {
+ m_term_event_p = new sc_event(
+ (std::string(SC_KERNEL_EVENT_PREFIX)+"_term_event").c_str() );
+ }
+ return *m_term_event_p;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_process_b::trigger_reset_event"
+// |
+// | This method triggers the notify event. It exists because we can't get
+// | sc_event context in sc_process.h because the includes would be
+// | circular... sigh...
+// +----------------------------------------------------------------------------
+void sc_process_b::trigger_reset_event()
+{
+ if ( m_reset_event_p ) m_reset_event_p->notify();
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_handle::operator sc_cthread_handle"
+//
+//------------------------------------------------------------------------------
+sc_process_handle::operator sc_cthread_handle()
+{
+ return DCAST<sc_cthread_handle>(m_target_p);
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_handle::sc_method_handle"
+//
+//------------------------------------------------------------------------------
+sc_process_handle::operator sc_method_handle()
+{
+ return DCAST<sc_method_handle>(m_target_p);
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_handle::sc_thread_handle"
+//
+//------------------------------------------------------------------------------
+sc_process_handle::operator sc_thread_handle()
+{
+ return DCAST<sc_thread_handle>(m_target_p);
+}
+
+} // namespace sc_core
+
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Andy Goodrich, Forte Design Systems, 12 Aug 05
+ Description of Modification: This is the rewrite of process support. It
+ contains some code from the now-defunct
+ sc_process_b.cpp, as well as the former
+ version of sc_process_b.cpp.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_process.cpp,v $
+// Revision 1.37 2011/08/24 22:05:51 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.36 2011/08/15 16:43:24 acg
+// Torsten Maehne: changes to remove unused argument warnings.
+//
+// Revision 1.35 2011/08/07 19:08:04 acg
+// Andy Goodrich: moved logs to end of file so line number synching works
+// better between versions.
+//
+// Revision 1.34 2011/07/29 22:55:01 acg
+// Philipp A. Hartmann: add missing include.
+//
+// Revision 1.33 2011/07/29 22:43:41 acg
+// Philipp A. Hartmann: changes to handle case where a process control
+// invocation on a child process causes the list of child processes to change.
+//
+// Revision 1.32 2011/07/24 11:20:03 acg
+// Philipp A. Hartmann: process control error message improvements:
+// (1) Downgrade error to warning for re-kills of processes.
+// (2) Add process name to process messages.
+// (3) drop some superfluous colons in messages.
+//
+// Revision 1.31 2011/04/19 15:04:27 acg
+// Philipp A. Hartmann: clean up SC_ID messages.
+//
+// Revision 1.30 2011/04/14 22:33:43 acg
+// Andy Goodrich: added missing checks for a process being a zombie.
+//
+// Revision 1.29 2011/04/13 05:00:43 acg
+// Andy Goodrich: removed check for method process in termination_event()
+// since with the new IEEE 1666 2011 its legal.
+//
+// Revision 1.28 2011/04/13 02:44:26 acg
+// Andy Goodrich: added m_unwinding flag in place of THROW_NOW because the
+// throw status will be set back to THROW_*_RESET if reset is active and
+// the check for an unwind being complete was expecting THROW_NONE as the
+// clearing of THROW_NOW.
+//
+// Revision 1.27 2011/04/10 22:17:35 acg
+// Andy Goodrich: added trigger_reset_event() to allow sc_process.h to
+// contain the run_process() inline method. sc_process.h cannot have
+// sc_simcontext information because of recursive includes.
+//
+// Revision 1.26 2011/04/08 22:33:08 acg
+// Andy Goodrich: moved the semantics() method to the header file and made
+// it an inline method.
+//
+// Revision 1.25 2011/04/08 18:24:48 acg
+// Andy Goodrich: moved reset_changed() to .cpp since it needs visibility
+// to sc_simcontext.
+//
+// Revision 1.24 2011/04/05 20:50:57 acg
+// Andy Goodrich:
+// (1) changes to make sure that event(), posedge() and negedge() only
+// return true if the clock has not moved.
+// (2) fixes for method self-resumes.
+// (3) added SC_PRERELEASE_VERSION
+// (4) removed kernel events from the object hierarchy, added
+// sc_hierarchy_name_exists().
+//
+// Revision 1.23 2011/04/05 06:25:38 acg
+// Andy Goodrich: new checks for simulation running in reset_process().
+//
+// Revision 1.22 2011/03/20 13:43:23 acg
+// Andy Goodrich: added async_signal_is() plus suspend() as a corner case.
+//
+// Revision 1.21 2011/03/12 21:07:51 acg
+// Andy Goodrich: changes to kernel generated event support.
+//
+// Revision 1.20 2011/03/07 17:38:43 acg
+// Andy Goodrich: tightening up of checks for undefined interaction between
+// synchronous reset and suspend.
+//
+// Revision 1.19 2011/03/06 23:30:13 acg
+// Andy Goodrich: refining suspend - sync reset corner case checking so that
+// the following are error situations:
+// (1) Calling suspend on a process with a reset_signal_is() specification
+// or sync_reset_on() is active.
+// (2) Calling sync_reset_on() on a suspended process.
+//
+// Revision 1.18 2011/03/06 19:57:11 acg
+// Andy Goodrich: refinements for the illegal suspend - synchronous reset
+// interaction.
+//
+// Revision 1.17 2011/03/06 16:47:09 acg
+// Andy Goodrich: changes for testing sync_reset - suspend corner cases.
+//
+// Revision 1.16 2011/03/06 15:57:57 acg
+// Andy Goodrich: added process control corner case checks. Changes for
+// named events.
+//
+// Revision 1.15 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.14 2011/02/17 19:52:13 acg
+// Andy Goodrich:
+// (1) Simplfied process control usage.
+// (2) Changed dump_status() to dump_state with new signature.
+//
+// Revision 1.13 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.12 2011/02/13 21:41:34 acg
+// Andy Goodrich: get the log messages for the previous check in correct.
+//
+// Revision 1.11 2011/02/13 21:32:24 acg
+// Andy Goodrich: moved sc_process_b::reset_process() from header file
+// to cpp file. Added dump_status() to print out the status of a
+// process.
+//
+// Revision 1.10 2011/02/04 15:27:36 acg
+// Andy Goodrich: changes for suspend-resume semantics.
+//
+// Revision 1.9 2011/02/01 21:06:12 acg
+// Andy Goodrich: new layout for the process_state enum.
+//
+// Revision 1.8 2011/01/25 20:50:37 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.7 2011/01/19 23:21:50 acg
+// Andy Goodrich: changes for IEEE 1666 2011
+//
+// Revision 1.6 2011/01/18 20:10:45 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.5 2010/07/22 20:02:33 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.4 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.3 2008/05/22 17:06:26 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.2 2007/09/20 20:32:35 acg
+// Andy Goodrich: changes to the semantics of throw_it() to match the
+// specification. A call to throw_it() will immediately suspend the calling
+// thread until all the throwees have executed. At that point the calling
+// thread will be restarted before the execution of any other threads.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.6 2006/04/20 17:08:17 acg
+// Andy Goodrich: 3.0 style process changes.
+//
+// Revision 1.5 2006/04/11 23:13:21 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.4 2006/01/24 20:49:05 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+//
diff --git a/ext/systemc/src/sysc/kernel/sc_process.h b/ext/systemc/src/sysc/kernel/sc_process.h
new file mode 100644
index 000000000..298e2462f
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_process.h
@@ -0,0 +1,887 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_process.h -- Process base class support.
+
+ Original Author: Andy Goodrich, Forte Design Systems, 04 August 2005
+
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#if !defined(sc_process_h_INCLUDED)
+#define sc_process_h_INCLUDED
+
+#include <cassert>
+#include "sysc/utils/sc_iostream.h"
+#include "sysc/kernel/sc_constants.h"
+#include "sysc/kernel/sc_object.h"
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/communication/sc_export.h"
+
+namespace sc_core {
+
+// Forward declarations:
+class sc_process_handle;
+class sc_thread_process;
+class sc_reset;
+
+const char* sc_gen_unique_name( const char*, bool preserve_first );
+sc_process_handle sc_get_current_process_handle();
+void sc_thread_cor_fn( void* arg );
+bool timed_out( sc_simcontext* );
+
+extern bool sc_allow_process_control_corners; // see sc_simcontext.cpp.
+
+
+// Process handles as forward references:
+
+typedef class sc_cthread_process* sc_cthread_handle;
+typedef class sc_method_process* sc_method_handle;
+typedef class sc_thread_process* sc_thread_handle;
+
+
+// Standard process types:
+
+enum sc_curr_proc_kind
+{
+ SC_NO_PROC_,
+ SC_METHOD_PROC_,
+ SC_THREAD_PROC_,
+ SC_CTHREAD_PROC_
+};
+
+// Descendant information for process hierarchy operations:
+
+enum sc_descendant_inclusion_info {
+ SC_NO_DESCENDANTS=0,
+ SC_INCLUDE_DESCENDANTS,
+ SC_INVALID_DESCENDANTS
+};
+
+//==============================================================================
+// CLASS sc_process_host
+//
+// This is the base class for objects which may have processes defined for
+// their methods (e.g., sc_module)
+//==============================================================================
+
+class sc_process_host
+{
+ public:
+ sc_process_host() {}
+ virtual ~sc_process_host() { } // Needed for cast check for sc_module.
+ void defunct() {}
+};
+
+
+//==============================================================================
+// CLASS sc_process_monitor
+//
+// This class provides a way of monitoring a process' status (e.g., waiting
+// for a thread to complete its execution.) This class is intended to be a base
+// class for classes which need to monitor a process or processes (e.g.,
+// sc_join.) Its methods should be overloaded where notifications are desired.
+//==============================================================================
+
+class sc_process_monitor {
+ public:
+ enum {
+ spm_exit = 0
+ };
+ virtual ~sc_process_monitor() {}
+ virtual void signal(sc_thread_handle thread_p, int type);
+};
+inline void sc_process_monitor::signal(sc_thread_handle , int ) {}
+
+//------------------------------------------------------------------------------
+// PROCESS INVOCATION METHOD OR FUNCTION:
+//
+// Define SC_USE_MEMBER_FUNC_PTR if we want to use member function pointers
+// to implement process dispatch. Otherwise, we'll use a hack that involves
+// creating a templated invocation object which will invoke the member
+// function. This should not be necessary, but some compilers (e.g., VC++)
+// do not allow the conversion from `void (callback_tag::*)()' to
+// `void (sc_process_host::*)()'. This is supposed to be OK as long as the
+// dynamic type is correct. C++ Standard 5.4 "Explicit type conversion",
+// clause 7: a pointer to member of derived class type may be explicitly
+// converted to a pointer to member of an unambiguous non-virtual base class
+// type.
+//-----------------------------------------------------------------------------
+
+#if defined(_MSC_VER)
+#if ( _MSC_VER > 1200 )
+# define SC_USE_MEMBER_FUNC_PTR
+#endif
+#else
+# define SC_USE_MEMBER_FUNC_PTR
+#endif
+
+
+// COMPILER DOES SUPPORT CAST TO void (sc_process_host::*)() from (T::*)():
+
+#if defined(SC_USE_MEMBER_FUNC_PTR)
+
+ typedef void (sc_process_host::*SC_ENTRY_FUNC)();
+# define SC_DECL_HELPER_STRUCT(callback_tag, func) /*EMPTY*/
+# define SC_MAKE_FUNC_PTR(callback_tag, func) \
+ static_cast<sc_core::SC_ENTRY_FUNC>(&callback_tag::func)
+
+
+// COMPILER NOT DOES SUPPORT CAST TO void (sc_process_host::*)() from (T::*)():
+
+#else // !defined(SC_USE_MEMBER_FUNC_PTR)
+ class sc_process_call_base {
+ public:
+ inline sc_process_call_base()
+ {
+ }
+
+ virtual ~sc_process_call_base()
+ {
+ }
+
+ virtual void invoke(sc_process_host* host_p)
+ {
+ }
+ };
+ extern sc_process_call_base sc_process_defunct;
+
+ template<class T>
+ class sc_process_call : public sc_process_call_base {
+ public:
+ sc_process_call( void (T::*method_p)() ) :
+ sc_process_call_base()
+ {
+ m_method_p = method_p;
+ }
+
+ virtual ~sc_process_call()
+ {
+ }
+
+ virtual void invoke(sc_process_host* host_p)
+ {
+ (((T*)host_p)->*m_method_p)();
+ }
+
+ protected:
+ void (T::*m_method_p)(); // Method implementing the process.
+ };
+
+ typedef sc_process_call_base* SC_ENTRY_FUNC;
+# define SC_DECL_HELPER_STRUCT(callback_tag, func) /*EMPTY*/
+# define SC_MAKE_FUNC_PTR(callback_tag, func) \
+ (::sc_core::SC_ENTRY_FUNC) (new \
+ ::sc_core::sc_process_call<callback_tag>(&callback_tag::func))
+
+#endif // !defined(SC_USE_MEMBER_FUNC_PTR)
+
+
+extern void sc_set_stack_size( sc_thread_handle, std::size_t );
+
+class sc_event;
+class sc_event_list;
+class sc_name_gen;
+class sc_spawn_options;
+class sc_unwind_exception;
+
+//==============================================================================
+// CLASS sc_throw_it<EXCEPT> - ARBITRARY EXCEPTION CLASS
+//
+// This class serves as a way of throwing an execption for an aribtrary type
+// without knowing what that type is. A true virtual method in the base
+// class is used to actually throw the execption. A pointer to the base
+// class is used internally removing the necessity of knowing what the type
+// of EXCEPT is for code internal to the library.
+//
+// Note the clone() true virtual method. This is used to allow instances
+// of the sc_throw_it<EXCEPT> class to be easily garbage collected. Since
+// an exception may be propogated to more than one process knowing when
+// to garbage collect is non-trivial. So when a call is made to
+// sc_process_handle::throw_it() an instance of sc_throw_it<EXCEPT> is
+// allocated on the stack. For each process throwing the exception a copy is
+// made via clone(). That allows those objects to be deleted by the individual
+// processes when they are no longer needed (in this implementation of SystemC
+// that deletion will occur each time a new exception is thrown ( see
+// sc_thread_process::suspend_me() ).
+//==============================================================================
+class sc_throw_it_helper {
+ public:
+ virtual sc_throw_it_helper* clone() const = 0;
+ virtual void throw_it() = 0;
+ sc_throw_it_helper() {}
+ virtual ~sc_throw_it_helper() {}
+};
+
+template<typename EXCEPT>
+class sc_throw_it : public sc_throw_it_helper
+{
+ typedef sc_throw_it<EXCEPT> this_type;
+ public:
+ sc_throw_it( const EXCEPT& value ) : m_value(value) { }
+ virtual ~sc_throw_it() {}
+ virtual inline this_type* clone() const { return new this_type(m_value); }
+ virtual inline void throw_it() { throw m_value; }
+ protected:
+ EXCEPT m_value; // value to be thrown.
+};
+
+//==============================================================================
+// CLASS sc_process_b - USER INITIATED DYNAMIC PROCESS SUPPORT:
+//
+// This class implements the base class for a threaded process_base process
+// whose semantics are provided by the true virtual method semantics().
+// Classes derived from this one will provide a version of semantics which
+// implements the desired semantics. See the sc_spawn_xxx classes below.
+//
+// Notes:
+// (1) Object instances of this class maintain a reference count of
+// outstanding handles. When the handle count goes to zero the
+// object will be deleted.
+// (2) Descriptions of the methods and operators in this class appear with
+// their implementations.
+// (3) The m_sticky_reset field is used to handle synchronous resets that
+// are enabled via the sc_process_handle::sync_reset_on() method. These
+// resets are not generated by a signal, but rather are modal by
+// method call: sync_reset_on - sync_reset_off.
+//
+//==============================================================================
+class sc_process_b : public sc_object {
+ friend class sc_simcontext; // Allow static processes to have base.
+ friend class sc_cthread_process; // Child can access parent.
+ friend class sc_method_process; // Child can access parent.
+ friend class sc_process_handle; // Allow handles to modify ref. count.
+ friend class sc_thread_process; // Child can access parent.
+
+ friend class sc_object;
+ friend class sc_port_base;
+ friend class sc_runnable;
+ friend class sc_sensitive;
+ friend class sc_sensitive_pos;
+ friend class sc_sensitive_neg;
+ friend class sc_module;
+ friend class sc_report_handler;
+ friend class sc_reset;
+ friend class sc_reset_finder;
+ friend class sc_unwind_exception;
+
+ friend const char* sc_gen_unique_name( const char*, bool preserve_first );
+ friend sc_process_handle sc_get_current_process_handle();
+ friend void sc_thread_cor_fn( void* arg );
+ friend bool timed_out( sc_simcontext* );
+
+ public:
+ enum process_throw_type {
+ THROW_NONE = 0,
+ THROW_KILL,
+ THROW_USER,
+ THROW_ASYNC_RESET,
+ THROW_SYNC_RESET
+ };
+
+ enum process_state {
+ ps_bit_disabled = 1, // process is disabled.
+ ps_bit_ready_to_run = 2, // process is ready to run.
+ ps_bit_suspended = 4, // process is suspended.
+ ps_bit_zombie = 8, // process is a zombie.
+ ps_normal = 0 // must be zero.
+ };
+
+ enum reset_type { // types for sc_process_b::reset_process()
+ reset_asynchronous = 0, // asynchronous reset.
+ reset_synchronous_off, // turn off synchronous reset sticky bit.
+ reset_synchronous_on // turn on synchronous reset sticky bit.
+ };
+
+ enum trigger_t
+ {
+ STATIC,
+ EVENT,
+ OR_LIST,
+ AND_LIST,
+ TIMEOUT,
+ EVENT_TIMEOUT,
+ OR_LIST_TIMEOUT,
+ AND_LIST_TIMEOUT
+ };
+
+ public:
+ sc_process_b( const char* name_p, bool is_thread, bool free_host,
+ SC_ENTRY_FUNC method_p, sc_process_host* host_p,
+ const sc_spawn_options* opt_p );
+
+ protected:
+ // may not be deleted manually (called from destroy_process())
+ virtual ~sc_process_b();
+
+ public:
+ inline int current_state() { return m_state; }
+ bool dont_initialize() const { return m_dont_init; }
+ virtual void dont_initialize( bool dont );
+ std::string dump_state() const;
+ const ::std::vector<sc_object*>& get_child_objects() const;
+ inline sc_curr_proc_kind proc_kind() const;
+ sc_event& reset_event();
+ sc_event& terminated_event();
+
+ public:
+ static inline sc_process_handle last_created_process_handle();
+
+ protected:
+ virtual void add_child_object( sc_object* );
+ void add_static_event( const sc_event& );
+ bool dynamic() const { return m_dynamic_proc; }
+ const char* gen_unique_name( const char* basename_, bool preserve_first );
+ inline sc_report* get_last_report() { return m_last_report_p; }
+ inline bool is_disabled() const;
+ inline bool is_runnable() const;
+ static inline sc_process_b* last_created_process_base();
+ virtual bool remove_child_object( sc_object* );
+ void remove_dynamic_events( bool skip_timeout = false );
+ void remove_static_events();
+ inline void set_last_report( sc_report* last_p )
+ {
+ delete m_last_report_p;
+ m_last_report_p = last_p;
+ }
+ inline bool timed_out() const;
+ void report_error( const char* msgid, const char* msg = "" ) const;
+ void report_immediate_self_notification() const;
+
+ protected: // process control methods:
+ virtual void disable_process(
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS ) = 0;
+ void disconnect_process();
+ virtual void enable_process(
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS ) = 0;
+ inline void initially_in_reset( bool async );
+ inline bool is_unwinding() const;
+ inline bool start_unwinding();
+ inline bool clear_unwinding();
+ virtual void kill_process(
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS ) = 0;
+ void reset_changed( bool async, bool asserted );
+ void reset_process( reset_type rt,
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
+ virtual void resume_process(
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS ) = 0;
+ virtual void suspend_process(
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS ) = 0;
+ virtual void throw_user( const sc_throw_it_helper& helper,
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS ) = 0;
+ virtual void throw_reset( bool async ) = 0;
+ virtual bool terminated() const;
+ void trigger_reset_event();
+
+ private:
+ void delete_process();
+ inline void reference_decrement();
+ inline void reference_increment();
+
+ protected:
+ inline void semantics();
+
+ // debugging stuff:
+
+ public:
+ const char* file;
+ int lineno;
+ int proc_id;
+
+ protected:
+ int m_active_areset_n; // number of aresets active.
+ int m_active_reset_n; // number of resets active.
+ bool m_dont_init; // true: no initialize call.
+ bool m_dynamic_proc; // true: after elaboration.
+ const sc_event* m_event_p; // Dynamic event waiting on.
+ int m_event_count; // number of events.
+ const sc_event_list* m_event_list_p; // event list waiting on.
+ sc_process_b* m_exist_p; // process existence link.
+ bool m_free_host; // free sc_semantic_host_p.
+ bool m_has_reset_signal; // has reset_signal_is.
+ bool m_has_stack; // true is stack present.
+ bool m_is_thread; // true if this is thread.
+ sc_report* m_last_report_p; // last report this process.
+ sc_name_gen* m_name_gen_p; // subprocess name generator
+ sc_curr_proc_kind m_process_kind; // type of process.
+ int m_references_n; // outstanding handles.
+ std::vector<sc_reset*> m_resets; // resets for process.
+ sc_event* m_reset_event_p; // reset event.
+ sc_event* m_resume_event_p; // resume event.
+ sc_process_b* m_runnable_p; // sc_runnable link
+ sc_process_host* m_semantics_host_p; // host for semantics.
+ SC_ENTRY_FUNC m_semantics_method_p; // method for semantics.
+ int m_state; // process state.
+ std::vector<const sc_event*> m_static_events; // static events waiting on.
+ bool m_sticky_reset; // see note 3 above.
+ sc_event* m_term_event_p; // terminated event.
+ sc_throw_it_helper* m_throw_helper_p; // what to throw.
+ process_throw_type m_throw_status; // exception throwing status
+ bool m_timed_out; // true if we timed out.
+ sc_event* m_timeout_event_p; // timeout event.
+ trigger_t m_trigger_type; // type of trigger using.
+ bool m_unwinding; // true if unwinding stack.
+
+ protected:
+ static sc_process_b* m_last_created_process_p; // Last process created.
+};
+
+typedef sc_process_b sc_process_b; // For compatibility.
+
+
+//------------------------------------------------------------------------------
+//"sc_process_b::XXXX_child_YYYYY"
+//
+// These methods provide child object support.
+//------------------------------------------------------------------------------
+inline void
+sc_process_b::add_child_object( sc_object* object_p )
+{
+ sc_object::add_child_object( object_p );
+ reference_increment();
+}
+
+inline bool
+sc_process_b::remove_child_object( sc_object* object_p )
+{
+ if ( sc_object::remove_child_object( object_p ) ) {
+ reference_decrement();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+inline const ::std::vector<sc_object*>&
+sc_process_b::get_child_objects() const
+{
+ return m_child_objects;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_process_b::initially_in_reset"
+//
+// This inline method is a callback to indicate that a reset is active at
+// start up. This is because the signal will have been initialized before
+// a reset linkage for it is set up, so we won't get a reset_changed()
+// callback.
+// async = true if this an asynchronous reset.
+//------------------------------------------------------------------------------
+inline void sc_process_b::initially_in_reset( bool async )
+{
+ if ( async )
+ m_active_areset_n++;
+ else
+ m_active_reset_n++;
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::is_disabled"
+//
+// This method returns true if this process is disabled.
+//------------------------------------------------------------------------------
+inline bool sc_process_b::is_disabled() const
+{
+ return (m_state & ps_bit_disabled) ? true : false;
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::is_runnable"
+//
+// This method returns true if this process is runnable. That is indicated
+// by a non-zero m_runnable_p field.
+//------------------------------------------------------------------------------
+inline bool sc_process_b::is_runnable() const
+{
+ return m_runnable_p != 0;
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::is_unwinding"
+//
+// This method returns true if this process is unwinding from a kill or reset.
+//------------------------------------------------------------------------------
+inline bool sc_process_b::is_unwinding() const
+{
+ return m_unwinding;
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::start_unwinding"
+//
+// This method flags that this object instance should start unwinding if the
+// current throw status requires an unwind.
+//
+// Result is true if the flag is set, false if the flag is already set.
+//------------------------------------------------------------------------------
+inline bool sc_process_b::start_unwinding()
+{
+ if ( !m_unwinding )
+ {
+ switch( m_throw_status )
+ {
+ case THROW_KILL:
+ case THROW_ASYNC_RESET:
+ case THROW_SYNC_RESET:
+ m_unwinding = true;
+ return true;
+ case THROW_USER:
+ default:
+ break;
+ }
+ }
+ return false;
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::clear_unwinding"
+//
+// This method clears this object instance's throw status and always returns
+// true.
+//------------------------------------------------------------------------------
+inline bool sc_process_b::clear_unwinding()
+{
+ m_unwinding = false;
+ return true;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_process_b::last_created_process_base"
+//
+// This virtual method returns the sc_process_b pointer for the last
+// created process. It is only used internally by the simulator.
+//------------------------------------------------------------------------------
+inline sc_process_b* sc_process_b::last_created_process_base()
+{
+ return m_last_created_process_p;
+}
+
+
+
+//------------------------------------------------------------------------------
+//"sc_process_b::proc_kind"
+//
+// This method returns the kind of this process.
+//------------------------------------------------------------------------------
+inline sc_curr_proc_kind sc_process_b::proc_kind() const
+{
+ return m_process_kind;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_process_b::reference_decrement"
+//
+// This inline method decrements the number of outstanding references to this
+// object instance. If the number of references goes to zero, this object
+// can be deleted in "sc_process_b::delete_process()".
+//------------------------------------------------------------------------------
+inline void sc_process_b::reference_decrement()
+{
+ m_references_n--;
+ if ( m_references_n == 0 ) delete_process();
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_process_b::reference_increment"
+//
+// This inline method increments the number of outstanding references to this
+// object instance.
+//------------------------------------------------------------------------------
+inline void sc_process_b::reference_increment()
+{
+ assert(m_references_n != 0);
+ m_references_n++;
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::semantics"
+//
+// This inline method invokes the semantics for this object instance.
+// We check to see if we are initially in reset and then invoke the
+// process semantics.
+//
+// Notes:
+// (1) For a description of the process reset mechanism see the top of
+// the file sc_reset.cpp.
+//------------------------------------------------------------------------------
+struct scoped_flag
+{
+ scoped_flag( bool& b ) : ref(b){ ref = true; }
+ ~scoped_flag() { ref = false; }
+ bool& ref;
+};
+inline void sc_process_b::semantics()
+{
+
+ // within this function, the process has a stack associated
+
+ scoped_flag scoped_stack_flag( m_has_stack );
+
+ assert( m_process_kind != SC_NO_PROC_ );
+
+ // Determine the reset status of this object instance and potentially
+ // trigger its notify event:
+
+ // See if we need to trigger the notify event:
+
+ if ( m_reset_event_p &&
+ ( (m_throw_status == THROW_SYNC_RESET) ||
+ (m_throw_status == THROW_ASYNC_RESET) )
+ ) {
+ trigger_reset_event();
+ }
+
+ // Set the new reset status of this object based on the reset counts:
+
+ m_throw_status = m_active_areset_n ? THROW_ASYNC_RESET :
+ ( m_active_reset_n ? THROW_SYNC_RESET : THROW_NONE);
+
+ // Dispatch the actual semantics for the process:
+
+# ifndef SC_USE_MEMBER_FUNC_PTR
+ m_semantics_method_p->invoke( m_semantics_host_p );
+# else
+ (m_semantics_host_p->*m_semantics_method_p)();
+# endif
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_process_b::terminated"
+//
+// This inline method returns true if this object has terminated.
+//------------------------------------------------------------------------------
+inline bool sc_process_b::terminated() const
+{
+ return (m_state & ps_bit_zombie) != 0;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_process_b::timed_out"
+//
+// This inline method returns true if this object instance timed out.
+//------------------------------------------------------------------------------
+inline bool sc_process_b::timed_out() const
+{
+ return m_timed_out;
+}
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Andy Goodrich, Forte Design Systems, 12 Aug 05
+ Description of Modification: This is the rewrite of process support. It
+ contains some code from the original
+ sc_process.h by Stan Liao, and the now-defunct
+ sc_process_b.h by Stan Liao and Martin
+ Janssen, all of Synopsys, Inc., It also contains
+ code from the original sc_process_b.h by
+ Andy Goodrich of Forte Design Systems and
+ Bishnupriya Bhattacharya of Cadence Design
+ Systems.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_process.h,v $
+// Revision 1.36 2011/08/26 22:44:30 acg
+// Torsten Maehne: eliminate unused argument warning.
+//
+// Revision 1.35 2011/08/26 20:46:10 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.34 2011/08/24 22:05:51 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.33 2011/08/15 16:43:24 acg
+// Torsten Maehne: changes to remove unused argument warnings.
+//
+// Revision 1.32 2011/07/24 11:20:03 acg
+// Philipp A. Hartmann: process control error message improvements:
+// (1) Downgrade error to warning for re-kills of processes.
+// (2) Add process name to process messages.
+// (3) drop some superfluous colons in messages.
+//
+// Revision 1.31 2011/04/13 02:44:26 acg
+// Andy Goodrich: added m_unwinding flag in place of THROW_NOW because the
+// throw status will be set back to THROW_*_RESET if reset is active and
+// the check for an unwind being complete was expecting THROW_NONE as the
+// clearing of THROW_NOW.
+//
+// Revision 1.30 2011/04/11 22:07:27 acg
+// Andy Goodrich: check for reset event notification before resetting the
+// throw_status value.
+//
+// Revision 1.29 2011/04/10 22:17:36 acg
+// Andy Goodrich: added trigger_reset_event() to allow sc_process.h to
+// contain the run_process() inline method. sc_process.h cannot have
+// sc_simcontext information because of recursive includes.
+//
+// Revision 1.28 2011/04/08 22:34:06 acg
+// Andy Goodrich: moved the semantics() method to this file and made it
+// an inline method. Added reset processing to the semantics() method.
+//
+// Revision 1.27 2011/04/08 18:24:48 acg
+// Andy Goodrich: moved reset_changed() to .cpp since it needs visibility
+// to sc_simcontext.
+//
+// Revision 1.26 2011/04/01 21:24:57 acg
+// Andy Goodrich: removed unused code.
+//
+// Revision 1.25 2011/03/28 13:02:51 acg
+// Andy Goodrich: Changes for disable() interactions.
+//
+// Revision 1.24 2011/03/20 13:43:23 acg
+// Andy Goodrich: added async_signal_is() plus suspend() as a corner case.
+//
+// Revision 1.23 2011/03/12 21:07:51 acg
+// Andy Goodrich: changes to kernel generated event support.
+//
+// Revision 1.22 2011/03/08 20:49:31 acg
+// Andy Goodrich: implement coarse checking for synchronous reset - suspend
+// interaction.
+//
+// Revision 1.21 2011/03/07 17:38:43 acg
+// Andy Goodrich: tightening up of checks for undefined interaction between
+// synchronous reset and suspend.
+//
+// Revision 1.20 2011/03/06 19:57:11 acg
+// Andy Goodrich: refinements for the illegal suspend - synchronous reset
+// interaction.
+//
+// Revision 1.19 2011/03/05 19:44:20 acg
+// Andy Goodrich: changes for object and event naming and structures.
+//
+// Revision 1.18 2011/02/19 08:30:53 acg
+// Andy Goodrich: Moved process queueing into trigger_static from
+// sc_event::notify.
+//
+// Revision 1.17 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.16 2011/02/18 20:10:44 acg
+// Philipp A. Hartmann: force return expression to be a bool to keep MSVC
+// happy.
+//
+// Revision 1.15 2011/02/17 19:52:45 acg
+// Andy Goodrich:
+// (1) Simplified process control usage.
+// (2) Changed dump_status() to dump_state() with new signature.
+//
+// Revision 1.14 2011/02/16 22:37:30 acg
+// Andy Goodrich: clean up to remove need for ps_disable_pending.
+//
+// Revision 1.13 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.12 2011/02/13 21:41:34 acg
+// Andy Goodrich: get the log messages for the previous check in correct.
+//
+// Revision 1.11 2011/02/13 21:32:24 acg
+// Andy Goodrich: moved sc_process_b::reset_process() implementation
+// from header to cpp file . Added dump_status() to print out the status of a
+// process.
+//
+// Revision 1.10 2011/02/11 13:25:24 acg
+// Andy Goodrich: Philipp A. Hartmann's changes:
+// (1) Removal of SC_CTHREAD method overloads.
+// (2) New exception processing code.
+//
+// Revision 1.9 2011/02/04 15:27:36 acg
+// Andy Goodrich: changes for suspend-resume semantics.
+//
+// Revision 1.8 2011/02/01 21:06:12 acg
+// Andy Goodrich: new layout for the process_state enum.
+//
+// Revision 1.7 2011/01/25 20:50:37 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.6 2011/01/19 23:21:50 acg
+// Andy Goodrich: changes for IEEE 1666 2011
+//
+// Revision 1.5 2011/01/18 20:10:45 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.4 2010/07/22 20:02:33 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.3 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.2 2008/05/22 17:06:26 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.11 2006/05/08 17:58:10 acg
+// Andy Goodrich: added David Long's forward declarations for friend
+// functions, methods, and operators to keep the Microsoft compiler happy.
+//
+// Revision 1.10 2006/04/28 23:29:01 acg
+// Andy Goodrich: added an sc_core:: prefix to SC_FUNC_PTR in the
+// SC_MAKE_FUNC_PTR macro to allow its transpareuse outside of the sc_core
+// namespace.
+//
+// Revision 1.9 2006/04/28 21:52:57 acg
+// Andy Goodrich: changed SC_MAKE_FUNC_PTR to use a static cast to address
+// and AIX issue wrt sc_module's inherited classes.
+//
+// Revision 1.8 2006/04/20 17:08:17 acg
+// Andy Goodrich: 3.0 style process changes.
+//
+// Revision 1.7 2006/04/11 23:13:21 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.6 2006/03/13 20:26:50 acg
+// Andy Goodrich: Addition of forward class declarations, e.g.,
+// sc_reset, to keep gcc 4.x happy.
+//
+// Revision 1.5 2006/01/31 20:09:10 acg
+// Andy Goodrich: added explaination of static vs dynamic waits to
+// sc_process_b::trigger_static.
+//
+// Revision 1.4 2006/01/24 20:49:05 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+#endif // !defined(sc_process_h_INCLUDED)
diff --git a/ext/systemc/src/sysc/kernel/sc_process_handle.h b/ext/systemc/src/sysc/kernel/sc_process_handle.h
new file mode 100644
index 000000000..c219f5fad
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_process_handle.h
@@ -0,0 +1,608 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_process_handle.h -- Process access support.
+
+ Original Author: Andy Goodrich, Forte Design Systems, 17 June 2003
+
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+// $Log: sc_process_handle.h,v $
+// Revision 1.21 2011/08/26 21:54:04 acg
+// Torsten Maehne: Simplify use of dynamic_cast<> for initializing m_target.
+//
+// Revision 1.20 2011/08/26 20:46:10 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+
+#if !defined(sc_process_handle_h_INCLUDED)
+#define sc_process_handle_h_INCLUDED
+
+#include "sysc/kernel/sc_module.h"
+
+namespace sc_core {
+
+// forward operator declarations:
+
+class sc_process_handle;
+bool
+operator == ( const sc_process_handle& left, const sc_process_handle& right );
+bool
+operator != ( const sc_process_handle& left, const sc_process_handle& right );
+bool
+operator < ( const sc_process_handle& left, const sc_process_handle& right );
+
+
+
+//=============================================================================
+// CLASS sc_process_handle
+//
+// This class provides access to an sc_process_b object instance in a
+// manner which allows some persistence after the deletion of the actual
+// process.
+//=============================================================================
+class sc_simcontext;
+class sc_process_handle {
+ typedef sc_process_handle this_type;
+
+ friend bool operator == ( const this_type& left, const this_type& right );
+ friend bool operator != ( const this_type& left, const this_type& right );
+ friend bool operator < ( const this_type& left, const this_type& right );
+ friend class sc_object;
+ friend class sc_join;
+ friend class sc_module;
+ friend class sc_reset;
+ friend class sc_sensitive;
+ friend class sc_sensitive_pos;
+ friend class sc_sensitive_neg;
+ friend class sc_thread_process;
+
+ public:
+ inline sc_process_handle();
+ inline explicit sc_process_handle( sc_object* object_p );
+ inline explicit sc_process_handle( sc_process_b* process_p );
+ inline sc_process_handle( const sc_process_handle& orig );
+ inline ~sc_process_handle();
+ inline sc_process_handle& operator = ( sc_process_handle src );
+ inline void swap( sc_process_handle& other );
+
+ public:
+ inline void disable(
+ sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS );
+ inline bool dynamic() const;
+ inline void enable(
+ sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS );
+ inline const std::vector<sc_event*>& get_child_events() const;
+ inline const std::vector<sc_object*>& get_child_objects() const;
+ inline sc_object* get_parent_object() const;
+ inline sc_object* get_process_object() const;
+ inline bool is_unwinding() const;
+ inline void kill(
+ sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS );
+ inline const char* name() const;
+ inline sc_curr_proc_kind proc_kind() const;
+ inline void reset(
+ sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS );
+ inline sc_event& reset_event() const;
+ inline void resume(
+ sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS );
+ inline void suspend(
+ sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS );
+ inline void sync_reset_off(
+ sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS );
+ inline void sync_reset_on(
+ sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS );
+ inline sc_event& terminated_event();
+ inline bool terminated() const;
+ template<typename EXCEPT>
+ inline void throw_it( const EXCEPT& exception,
+ sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS );
+ inline bool valid() const;
+
+ public: // implementation specific methods:
+ inline std::string dump_state() const;
+
+ protected:
+ inline bool dont_initialize() const
+ { return m_target_p ? m_target_p->dont_initialize() : false; }
+ inline void dont_initialize( bool dont );
+
+ public:
+ operator sc_process_b* ()
+ { return m_target_p; }
+ operator sc_cthread_handle ();
+ operator sc_method_handle ();
+ operator sc_thread_handle ();
+
+ protected:
+ sc_process_b* m_target_p; // Target for this object instance.
+
+ protected:
+ static std::vector<sc_event*> empty_event_vector; // If m_target_p == 0.
+ static std::vector<sc_object*> empty_object_vector; // If m_target_p == 0.
+ static sc_event non_event; // If m_target_p == 0.
+};
+
+inline bool operator == (
+ const sc_process_handle& left, const sc_process_handle& right )
+{
+ return (left.m_target_p != 0) && (right.m_target_p != 0) &&
+ (left.m_target_p == right.m_target_p);
+}
+
+inline bool operator != (
+ const sc_process_handle& left, const sc_process_handle& right )
+{
+ return (left.m_target_p == 0) || (right.m_target_p == 0) ||
+ (left.m_target_p != right.m_target_p);
+}
+
+inline bool operator < (
+ const sc_process_handle& left, const sc_process_handle& right )
+{
+ return left.m_target_p < right.m_target_p;
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_handle::sc_process_handle - non-pointer constructor"
+//
+// This version of the object instance constructor for this class creates
+// an object instance whose target needs to be supplied via an assignment.
+//------------------------------------------------------------------------------
+inline sc_process_handle::sc_process_handle() : m_target_p(0)
+{
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_handle::sc_process_handle - pointer constructor"
+//
+// This version of the object instance constructor for this class creates
+// an object instance whose target is the supplied sc_object instance.
+// The supplied sc_object must in fact be an sc_process_b instance.
+// object_p -> sc_object instance this is handle for.
+//------------------------------------------------------------------------------
+inline sc_process_handle::sc_process_handle( sc_object* object_p ) :
+ m_target_p(DCAST<sc_process_b*>(object_p))
+{
+ if ( m_target_p ) m_target_p->reference_increment();
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_handle::sc_process_handle - pointer constructor"
+//
+// This version of the object instance constructor for this class creates
+// an object instance whose target is the supplied sc_process_b instance.
+// This saves a dynamic cast compared to the sc_object* case.
+// process_p -> process instance this is handle for.
+//------------------------------------------------------------------------------
+inline sc_process_handle::sc_process_handle( sc_process_b* process_p ) :
+ m_target_p(process_p)
+{
+ if ( m_target_p ) m_target_p->reference_increment();
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_handle::sc_process_handle - copy constructor"
+//
+// This version of the object instance constructor for this class provides
+// the copy constructor for the class. It clones the supplied original
+// handle and increments the references to its target.
+// orig = sc_process_handle object instance to be copied from.
+//------------------------------------------------------------------------------
+inline sc_process_handle::sc_process_handle( const sc_process_handle& orig ) :
+ m_target_p(orig.m_target_p)
+{
+ if ( m_target_p ) m_target_p->reference_increment();
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_process_handle::operator ="
+//
+// This assignment operator signature is call by value rather than reference.
+// This means that an sc_process_handle instance will be created and the
+// target for that instance will be incremented before the assignment is done.
+// The assignment is done using the swap() method, which simply swaps the
+// targets of 'orig' and this object instance. We don't need to increment
+// the reference count for our new target since that was done when 'orig'
+// was created. Our old target's reference count will be decremented when
+// 'orig' is deleted.
+// orig = sc_process_handle object instance to be copied from.
+// Result is a reference for this object instance.
+//------------------------------------------------------------------------------
+inline sc_process_handle&
+sc_process_handle::operator = ( sc_process_handle orig )
+{
+ swap( orig );
+ return *this;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_process_handle::~sc_process_handle"
+//
+// This is the object instance destructor for this class. It decrements
+// the reference count for its target.
+//------------------------------------------------------------------------------
+inline sc_process_handle::~sc_process_handle()
+{
+ if ( m_target_p ) m_target_p->reference_decrement();
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_handle::inline methods"
+//
+// These are short inline methods.
+//------------------------------------------------------------------------------
+
+// disable this object instance's target.
+
+inline void sc_process_handle::disable(sc_descendant_inclusion_info descendants)
+{
+ if ( m_target_p )
+ m_target_p->disable_process(descendants);
+ else
+ SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "disable()");
+}
+
+// call dont_initialize() on this object instance's target.
+
+inline void sc_process_handle::dont_initialize( bool dont )
+{
+ if ( m_target_p )
+ m_target_p->dont_initialize( dont );
+ else
+ SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "dont_initialize()");
+}
+
+// dump the status of this object instance's target:
+
+inline std::string sc_process_handle::dump_state() const
+{
+ return m_target_p ? m_target_p->dump_state() : std::string("NO TARGET");
+}
+
+// return whether this object instance's target is dynamic or not.
+
+inline bool sc_process_handle::dynamic() const
+{
+ return m_target_p ? m_target_p->dynamic() : false;
+}
+
+// enable this object instance's target.
+
+inline void sc_process_handle::enable(sc_descendant_inclusion_info descendants)
+{
+ if ( m_target_p )
+ m_target_p->enable_process(descendants);
+ else
+ SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "enable()");
+}
+
+// return the child objects for this object instance's target.
+
+inline
+const std::vector<sc_event*>& sc_process_handle::get_child_events() const
+{
+ return m_target_p ? m_target_p->get_child_events() : empty_event_vector;
+}
+
+// return the child objects for this object instance's target.
+
+inline
+const std::vector<sc_object*>& sc_process_handle::get_child_objects() const
+{
+ return m_target_p ? m_target_p->get_child_objects() : empty_object_vector;
+}
+
+// return the parent object for this object instance's target.
+
+inline sc_object* sc_process_handle::get_parent_object() const
+{
+ return m_target_p ? m_target_p->get_parent_object() : NULL;
+}
+
+// return this object instance's target.
+
+inline sc_object* sc_process_handle::get_process_object() const
+{
+ return m_target_p;
+}
+
+// return whether this object instance is unwinding or not.
+
+inline bool sc_process_handle::is_unwinding() const
+{
+ if ( m_target_p )
+ return m_target_p->is_unwinding();
+ else {
+ SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "is_unwinding()");
+ return false;
+ }
+}
+
+// kill this object instance's target.
+
+inline void sc_process_handle::kill( sc_descendant_inclusion_info descendants )
+{
+ if ( m_target_p )
+ m_target_p->kill_process( descendants );
+ else
+ SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "kill()");
+}
+
+// return the name of this object instance's target.
+
+inline const char* sc_process_handle::name() const
+{
+ return m_target_p ? m_target_p->name() : "";
+}
+
+// return the process kind for this object instance's target.
+
+inline sc_curr_proc_kind sc_process_handle::proc_kind() const
+{
+ return m_target_p ? m_target_p->proc_kind() : SC_NO_PROC_;
+}
+
+// reset this object instance's target.
+
+inline void sc_process_handle::reset( sc_descendant_inclusion_info descendants )
+{
+ if ( m_target_p )
+ m_target_p->reset_process( sc_process_b::reset_asynchronous,
+ descendants );
+ else
+ SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "reset()");
+}
+
+// return the reset event for this object instance's target.
+
+inline sc_event& sc_process_handle::reset_event() const
+{
+ if ( m_target_p )
+ return m_target_p->reset_event();
+ else
+ {
+ SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "reset()");
+ return sc_process_handle::non_event;
+ }
+}
+
+// resume this object instance's target.
+
+inline void sc_process_handle::resume(sc_descendant_inclusion_info descendants)
+{
+ if ( m_target_p )
+ m_target_p->resume_process(descendants);
+ else
+ SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "resume()");
+}
+
+// suspend this object instance's target.
+
+inline void sc_process_handle::suspend(sc_descendant_inclusion_info descendants)
+{
+ if ( m_target_p )
+ m_target_p->suspend_process(descendants);
+ else
+ SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "suspend()");
+}
+
+// swap targets of this process handle with the supplied one.
+
+inline void sc_process_handle::swap( sc_process_handle& other )
+{
+ sc_process_b* tmp = m_target_p;
+ m_target_p = other.m_target_p;
+ other.m_target_p = tmp;
+}
+
+// turn sync_reset off for this object instance's target.
+
+inline void sc_process_handle::sync_reset_off(
+ sc_descendant_inclusion_info descendants)
+{
+ if ( m_target_p )
+ m_target_p->reset_process( sc_process_b::reset_synchronous_off,
+ descendants);
+ else
+ SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "sync_reset_off()");
+}
+
+// turn sync_reset on for this object instance's target.
+
+inline void sc_process_handle::sync_reset_on(
+ sc_descendant_inclusion_info descendants)
+{
+ if ( m_target_p )
+ {
+ m_target_p->reset_process(sc_process_b::reset_synchronous_on,
+ descendants);
+ }
+ else
+ {
+ SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "sync_reset_on()");
+ }
+}
+
+// terminate this object instance's target.
+
+inline bool sc_process_handle::terminated() const
+{
+ return m_target_p ? m_target_p->terminated() : false;
+}
+
+// return the termination event for this object instance's target.
+
+inline sc_event& sc_process_handle::terminated_event()
+{
+ if ( m_target_p )
+ return m_target_p->terminated_event();
+ else
+ {
+ SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "terminated_event()");
+ return sc_process_handle::non_event;
+ }
+}
+
+// return true if this object instance has a target, false it not.
+
+inline bool sc_process_handle::valid() const
+{
+ return m_target_p ? true : false;
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_handle::sc_throw_it"
+//
+// This method throws the supplied exception to the process whose handle this
+// object instance is, and optionally to the process' descendants. Once the
+// exception is thrown the currently executed process will suspend to allow
+// the exception to be propagated. Once the propagation has occurred the
+// current process will be resumed.
+//
+// Notes:
+// (1) We allocate the helper function on the stack, see the description of
+// sc_throw_it<EXCEPT>, in sc_process.h, for why.
+//
+// Arguments:
+// exception = exception to be thrown
+// descendants = indication of whether descendant processes should also
+// receive the throw.
+//------------------------------------------------------------------------------
+template<typename EXCEPT>
+inline void sc_process_handle::throw_it( const EXCEPT& exception,
+ sc_descendant_inclusion_info descendants)
+{
+ sc_throw_it<EXCEPT> helper(exception); // helper to throw the exception.
+
+ if ( !m_target_p )
+ {
+ SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "throw_it()");
+ return;
+ }
+ m_target_p->throw_user(helper, descendants);
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_process_b::last_created_process_handle"
+//
+// This method returns the kind of this process.
+//------------------------------------------------------------------------------
+inline sc_process_handle sc_process_b::last_created_process_handle()
+{
+ return sc_process_handle(m_last_created_process_p);
+}
+
+inline sc_process_handle sc_get_last_created_process_handle()
+{
+ return sc_process_b::last_created_process_handle();
+}
+
+} // namespace sc_core
+
+// Revision 1.19 2011/08/24 22:05:51 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.18 2011/04/01 22:08:26 acg
+// Andy Goodrich: remove unused variable.
+//
+// Revision 1.17 2011/03/12 21:07:51 acg
+// Andy Goodrich: changes to kernel generated event support.
+//
+// Revision 1.16 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.15 2011/02/17 19:53:03 acg
+// Andy Goodrich: changed dump_status() to dump_state() with new signature.
+//
+// Revision 1.14 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.13 2011/02/13 21:33:30 acg
+// Andy Goodrich: added dump_status() to allow the dumping of the status
+// of a process handle's target.
+//
+// Revision 1.12 2011/02/01 23:01:53 acg
+// Andy Goodrich: removed dead code.
+//
+// Revision 1.11 2011/02/01 21:07:36 acg
+// Andy Goodrich: defering of run queue manipulations to the
+// sc_thread_process::throw_it() method.
+//
+// Revision 1.10 2011/01/25 20:50:37 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.9 2011/01/20 16:52:20 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.8 2011/01/19 23:21:50 acg
+// Andy Goodrich: changes for IEEE 1666 2011
+//
+// Revision 1.7 2011/01/18 20:10:45 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.6 2010/07/30 05:21:22 acg
+// Andy Goodrich: release 2.3 fixes.
+//
+// Revision 1.5 2010/07/22 20:02:33 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.4 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.3 2008/05/22 17:06:26 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.2 2007/09/20 20:32:35 acg
+// Andy Goodrich: changes to the semantics of throw_it() to match the
+// specification. A call to throw_it() will immediately suspend the calling
+// thread until all the throwees have executed. At that point the calling
+// thread will be restarted before the execution of any other threads.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.7 2006/05/08 17:58:24 acg
+// Andy Goodrich: added David Long's forward declarations for friend
+// functions, methods, and operators to keep the Microsoft compiler happy.
+//
+// Revision 1.6 2006/04/20 17:08:17 acg
+// Andy Goodrich: 3.0 style process changes.
+//
+// Revision 1.5 2006/04/11 23:13:21 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.4 2006/01/24 20:49:05 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+#endif // !defined(sc_spawn_h_INCLUDED)
diff --git a/ext/systemc/src/sysc/kernel/sc_reset.cpp b/ext/systemc/src/sysc/kernel/sc_reset.cpp
new file mode 100644
index 000000000..2e4bc6c6e
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_reset.cpp
@@ -0,0 +1,440 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_reset.cpp -- Support for reset.
+
+ Original Author: Andy Goodrich, Forte Design Systems
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_reset.h"
+#include "sysc/kernel/sc_process_handle.h"
+#include "sysc/communication/sc_signal.h"
+#include "sysc/communication/sc_signal_ports.h"
+
+
+// THE SYSTEMC PROOF OF CONCEPT SIMULATOR RESET SIGNAL IMPLEMENTATION:
+//
+// (1) An instance of the sc_reset class is attached to each sc_signal<bool>
+// that is used as a reset signal.
+//
+// (2) Each process that is senstive to a reset signal will be registered in the
+// sc_reset class attached to that reset signal.
+//
+// (3) When a change in the value of a reset signal occurs it invokes the
+// notify_processes() method of its sc_reset object instance. The
+// notify_processes() method will call the reset_changed() method of each
+// process that is registered with it to inform the process that
+// state of the reset signal has changed.
+//
+// (4) A process may have multiple reset signals, so counters are kept for the
+// number of active asynchronous, and synchronous, reset signals that are
+// active. Those counters are incremented and decremented in the process'
+// reset_changed() method.
+//
+// (5) When a process' semantics() method is called the current reset state is
+// checked, and a reset sequence is initiated if the process is in reset.
+// This will occur every time an SC_METHOD is dispatched. SC_CTHREAD and
+// and SC_THREAD instances, only go through the semantics() method they
+// initially start up. So the reset check is duplicated in the suspend_me()
+// method, the tail of which will execute each time the thread is
+// dispatched.
+
+namespace sc_core {
+
+class sc_reset_finder;
+static sc_reset_finder* reset_finder_q=0; // Q of reset finders to reconcile.
+
+//==============================================================================
+// sc_reset_finder - place holder class for a port reset signal until it is
+// bound and an interface class is available. When the port
+// has been bound the information in this class will be used
+// to initialize its sc_reset object instance.
+//==============================================================================
+class sc_reset_finder {
+ friend class sc_reset;
+ public:
+ sc_reset_finder( bool async, const sc_in<bool>* port_p, bool level,
+ sc_process_b* target_p);
+ sc_reset_finder( bool async, const sc_inout<bool>* port_p, bool level,
+ sc_process_b* target_p);
+ sc_reset_finder( bool async, const sc_out<bool>* port_p, bool level,
+ sc_process_b* target_p);
+
+ protected:
+ bool m_async; // True if asynchronous reset.
+ bool m_level; // Level for reset.
+ sc_reset_finder* m_next_p; // Next reset finder in list.
+ const sc_in<bool>* m_in_p; // Port for which reset is needed.
+ const sc_inout<bool>* m_inout_p; // Port for which reset is needed.
+ const sc_out<bool>* m_out_p; // Port for which reset is needed.
+ sc_process_b* m_target_p; // Process to reset.
+
+ private: // disabled
+ sc_reset_finder( const sc_reset_finder& );
+ const sc_reset_finder& operator = ( const sc_reset_finder& );
+};
+
+inline sc_reset_finder::sc_reset_finder(
+ bool async, const sc_in<bool>* port_p, bool level, sc_process_b* target_p) :
+ m_async(async), m_level(level), m_next_p(0), m_in_p(port_p), m_inout_p(0),
+ m_out_p(0), m_target_p(target_p)
+{
+ m_next_p = reset_finder_q;
+ reset_finder_q = this;
+}
+
+inline sc_reset_finder::sc_reset_finder(
+ bool async, const sc_inout<bool>* port_p, bool level, sc_process_b* target_p
+) :
+ m_async(async), m_level(level), m_next_p(0), m_in_p(0), m_inout_p(port_p),
+ m_out_p(0), m_target_p(target_p)
+{
+ m_next_p = reset_finder_q;
+ reset_finder_q = this;
+}
+
+inline sc_reset_finder::sc_reset_finder(
+ bool async, const sc_out<bool>* port_p, bool level, sc_process_b* target_p
+) :
+ m_async(async), m_level(level), m_next_p(0), m_in_p(0), m_inout_p(0),
+ m_out_p(port_p), m_target_p(target_p)
+{
+ m_next_p = reset_finder_q;
+ reset_finder_q = this;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_reset::notify_processes"
+//
+// Notify processes that there is a change in the reset signal value.
+//------------------------------------------------------------------------------
+void sc_reset::notify_processes()
+{
+ bool active; // true if reset is active.
+ sc_reset_target* entry_p; // reset entry processing.
+ std::vector<sc_reset_target>::size_type process_i; // index of process resetting.
+ std::vector<sc_reset_target>::size_type process_n; // # of processes to reset.
+ bool value; // value of our signal.
+
+ value = m_iface_p->read();
+ process_n = m_targets.size();
+ for ( process_i = 0; process_i < process_n; process_i++ )
+ {
+ entry_p = &m_targets[process_i];
+ active = ( entry_p->m_level == value );
+ entry_p->m_process_p->reset_changed( entry_p->m_async, active );
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_reset::reconcile_resets"
+//
+// This static method processes the sc_reset_finders to establish the actual
+// reset connections.
+//
+// Notes:
+// (1) If reset is asserted we tell the process that it is in reset.
+//------------------------------------------------------------------------------
+void sc_reset::reconcile_resets()
+{
+ const sc_signal_in_if<bool>* iface_p; // Interface to reset signal.
+ sc_reset_finder* next_p; // Next finder to process.
+ sc_reset_finder* now_p; // Finder currently processing.
+ sc_reset_target reset_target; // Target's reset entry.
+ sc_reset* reset_p; // Reset object to use.
+
+ for ( now_p = reset_finder_q; now_p; now_p = next_p )
+ {
+ next_p = now_p->m_next_p;
+ if ( now_p->m_in_p )
+ {
+ iface_p = DCAST<const sc_signal_in_if<bool>*>(
+ now_p->m_in_p->get_interface());
+ }
+ else if ( now_p->m_inout_p )
+ {
+ iface_p = DCAST<const sc_signal_in_if<bool>*>(
+ now_p->m_inout_p->get_interface());
+ }
+ else
+ {
+ iface_p = DCAST<const sc_signal_in_if<bool>*>(
+ now_p->m_out_p->get_interface());
+ }
+ assert( iface_p != 0 );
+ reset_p = iface_p->is_reset();
+ now_p->m_target_p->m_resets.push_back(reset_p);
+ reset_target.m_async = now_p->m_async;
+ reset_target.m_level = now_p->m_level;
+ reset_target.m_process_p = now_p->m_target_p;
+ reset_p->m_targets.push_back(reset_target);
+ if ( iface_p->read() == now_p->m_level ) // see note 1 above
+ now_p->m_target_p->initially_in_reset( now_p->m_async );
+ delete now_p;
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_reset::remove_process"
+//
+// This method removes the supplied process from the list of processes that
+// should be notified when there is a change in the value of the reset signal.
+//
+// Arguments:
+// process_p -> process to be removed.
+//------------------------------------------------------------------------------
+void sc_reset::remove_process( sc_process_b* process_p )
+{
+ int process_i; // Index of process resetting.
+ int process_n; // # of processes to reset.
+
+ process_n = m_targets.size();
+ for ( process_i = 0; process_i < process_n; )
+ {
+ if ( m_targets[process_i].m_process_p == process_p )
+ {
+ m_targets[process_i] = m_targets[process_n-1];
+ process_n--;
+ m_targets.resize(process_n);
+ }
+ else
+ {
+ process_i++;
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_reset::reset_signal_is - ports"
+//
+// These overloads of the reset_signal_is() method will register the active
+// process with the sc_reset object instance associated with the supplied port.
+// If the port does not yet have a pointer to its sc_signal<bool> instance it
+// will create an sc_reset_finder class object instance that will be used
+// to set the process' reset information when the port has been bound.
+//
+// Arguments:
+// async = true if the reset signal is asynchronous, false if not.
+// port = port for sc_signal<bool> that will provide the reset signal.
+// level = level at which reset is active, either true or false.
+//------------------------------------------------------------------------------
+void sc_reset::reset_signal_is( bool async, const sc_in<bool>& port, bool level)
+{
+ const sc_signal_in_if<bool>* iface_p;
+ sc_process_b* process_p;
+
+ process_p = (sc_process_b*)sc_get_current_process_handle();
+ assert( process_p );
+ process_p->m_has_reset_signal = true;
+ switch ( process_p->proc_kind() )
+ {
+ case SC_THREAD_PROC_:
+ case SC_METHOD_PROC_:
+ case SC_CTHREAD_PROC_:
+ iface_p = DCAST<const sc_signal_in_if<bool>*>(port.get_interface());
+ if ( iface_p )
+ reset_signal_is( async, *iface_p, level );
+ else
+ new sc_reset_finder( async, &port, level, process_p );
+ break;
+ default:
+ SC_REPORT_ERROR(SC_ID_UNKNOWN_PROCESS_TYPE_, process_p->name());
+ break;
+ }
+}
+
+void sc_reset::reset_signal_is(
+ bool async, const sc_inout<bool>& port, bool level )
+{
+ const sc_signal_in_if<bool>* iface_p;
+ sc_process_b* process_p;
+
+ process_p = (sc_process_b*)sc_get_current_process_handle();
+ assert( process_p );
+ process_p->m_has_reset_signal = true;
+ switch ( process_p->proc_kind() )
+ {
+ case SC_THREAD_PROC_:
+ case SC_METHOD_PROC_:
+ case SC_CTHREAD_PROC_:
+ iface_p = DCAST<const sc_signal_in_if<bool>*>(port.get_interface());
+ if ( iface_p )
+ reset_signal_is( async, *iface_p, level );
+ else
+ new sc_reset_finder( async, &port, level, process_p );
+ break;
+ default:
+ SC_REPORT_ERROR(SC_ID_UNKNOWN_PROCESS_TYPE_, process_p->name());
+ break;
+ }
+}
+
+void sc_reset::reset_signal_is(
+ bool async, const sc_out<bool>& port, bool level )
+{
+ const sc_signal_in_if<bool>* iface_p;
+ sc_process_b* process_p;
+
+ process_p = (sc_process_b*)sc_get_current_process_handle();
+ assert( process_p );
+ process_p->m_has_reset_signal = true;
+ switch ( process_p->proc_kind() )
+ {
+ case SC_THREAD_PROC_:
+ case SC_METHOD_PROC_:
+ case SC_CTHREAD_PROC_:
+ iface_p = DCAST<const sc_signal_in_if<bool>*>(port.get_interface());
+ if ( iface_p )
+ reset_signal_is( async, *iface_p, level );
+ else
+ new sc_reset_finder( async, &port, level, process_p );
+ break;
+ default:
+ SC_REPORT_ERROR(SC_ID_UNKNOWN_PROCESS_TYPE_, process_p->name());
+ break;
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_reset::reset_signal_is"
+//
+// This static method will register the active process instance as being
+// reset by the sc_signal<bool> whose interface has been supplied. If no
+// sc_reset object instance has been attached to the sc_signal<bool> yet, it
+// will be created and attached. The active process instance is pushed into
+// the list of processes that the sc_reset object instance should notify if
+// the value of the reset signal changes.
+//
+// Arguments:
+// async = true if the reset signal is asynchronous, false if not.
+// iface = interface for the reset signal.
+// level = is the level at which reset is active, either true or false.
+// Notes:
+// (1) If reset is asserted we tell the process that it is in reset
+// initially.
+//------------------------------------------------------------------------------
+void sc_reset::reset_signal_is(
+ bool async, const sc_signal_in_if<bool>& iface, bool level )
+{
+ sc_process_b* process_p; // process adding reset for.
+ sc_reset_target reset_target; // entry to build for the process.
+ sc_reset* reset_p; // reset object.
+
+ process_p = sc_process_b::last_created_process_base();
+ assert( process_p );
+ process_p->m_has_reset_signal = true;
+ switch ( process_p->proc_kind() )
+ {
+ case SC_METHOD_PROC_:
+ case SC_CTHREAD_PROC_:
+ case SC_THREAD_PROC_:
+ reset_p = iface.is_reset();
+ process_p->m_resets.push_back(reset_p);
+ reset_target.m_async = async;
+ reset_target.m_level = level;
+ reset_target.m_process_p = process_p;
+ reset_p->m_targets.push_back(reset_target);
+ if ( iface.read() == level ) process_p->initially_in_reset( async );
+ break;
+ default:
+ SC_REPORT_ERROR(SC_ID_UNKNOWN_PROCESS_TYPE_, process_p->name());
+ break;
+ }
+}
+
+} // namespace sc_core
+
+// $Log: sc_reset.cpp,v $
+// Revision 1.16 2011/08/26 20:46:10 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.15 2011/08/24 22:05:51 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.14 2011/04/08 22:37:34 acg
+// Andy Goodrich: documentation of the reset mechanism and additional
+// documentation of methods. Removal of check for SC_METHODs in
+// sc_reset_signal_is() that should not have been there.
+//
+// Revision 1.13 2011/03/20 15:13:01 acg
+// Andy Goodrich: set the reset flag for async_reset_signal_is to catch
+// the suspend() corner case.
+//
+// Revision 1.12 2011/03/20 13:43:23 acg
+// Andy Goodrich: added async_signal_is() plus suspend() as a corner case.
+//
+// Revision 1.11 2011/03/06 19:57:11 acg
+// Andy Goodrich: refinements for the illegal suspend - synchronous reset
+// interaction.
+//
+// Revision 1.10 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.9 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.8 2011/02/01 21:08:26 acg
+// Andy Goodrich: new multiple reset support.
+//
+// Revision 1.7 2011/01/06 18:04:38 acg
+// Andy Goodrich: removed commented out code.
+//
+// Revision 1.6 2010/12/07 20:09:13 acg
+// Andy Goodrich: removed sc_signal overloads since already have sc_signal_in_if overloads.
+//
+// Revision 1.5 2010/11/20 17:10:56 acg
+// Andy Goodrich: reset processing changes for new IEEE 1666 standard.
+//
+// Revision 1.4 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.3 2009/03/12 22:59:58 acg
+// Andy Goodrich: updates for 2.4 stuff.
+//
+// Revision 1.2 2008/05/22 17:06:26 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.7 2006/12/02 20:58:19 acg
+// Andy Goodrich: updates from 2.2 for IEEE 1666 support.
+//
+// Revision 1.5 2006/04/11 23:13:21 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.4 2006/01/24 20:49:05 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+//
diff --git a/ext/systemc/src/sysc/kernel/sc_reset.h b/ext/systemc/src/sysc/kernel/sc_reset.h
new file mode 100644
index 000000000..f0992bb16
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_reset.h
@@ -0,0 +1,164 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_reset.h -- Process reset support.
+
+ Original Author: Andy Goodrich, Forte Design Systems, 17 June 2003
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#if !defined(sc_reset_h_INCLUDED)
+#define sc_reset_h_INCLUDED
+
+#include "sysc/communication/sc_writer_policy.h"
+
+namespace sc_core {
+
+// FORWARD CLASS REFERENCES:
+
+template<typename DATA> class sc_signal_in_if;
+template<typename IF, sc_writer_policy POL> class sc_signal;
+template<typename DATA> class sc_in;
+template<typename DATA> class sc_inout;
+template<typename DATA> class sc_out;
+template<typename SOURCE> class sc_spawn_reset;
+class sc_reset;
+class sc_process_b;
+
+//==============================================================================
+// CLASS sc_reset_target - RESET ENTRY FOR AN sc_process_b TARGET
+//
+// This class describes a reset condition associated with an sc_process_b
+// instance.
+//==============================================================================
+class sc_reset_target {
+ public:
+ bool m_async; // true asynchronous reset, false synchronous.
+ bool m_level; // level for reset.
+ sc_process_b* m_process_p; // process this reset entry is for.
+};
+
+inline std::ostream& operator << ( std::ostream& os,
+ const sc_reset_target& target )
+{
+ os << "[";
+ os << target.m_async << ",";
+ os << target.m_level << ",";
+ os << target.m_process_p << ",";
+ return os;
+}
+
+//==============================================================================
+// CLASS sc_reset - RESET INFORMATION FOR A RESET SIGNAL
+//
+// See the top of sc_reset.cpp for an explaination of how the reset mechanism
+// is implemented.
+//==============================================================================
+class sc_reset {
+ friend class sc_cthread_process;
+ friend class sc_method_process;
+ friend class sc_module;
+ friend class sc_process_b;
+ friend class sc_signal<bool, SC_ONE_WRITER>;
+ friend class sc_signal<bool, SC_MANY_WRITERS>;
+ friend class sc_signal<bool, SC_UNCHECKED_WRITERS>;
+ friend class sc_simcontext;
+ template<typename SOURCE> friend class sc_spawn_reset;
+ friend class sc_thread_process;
+
+ protected:
+ static void reconcile_resets();
+ static void
+ reset_signal_is(bool async, const sc_signal_in_if<bool>& iface,
+ bool level);
+ static void
+ reset_signal_is( bool async, const sc_in<bool>& iface, bool level);
+ static void
+ reset_signal_is( bool async, const sc_inout<bool>& iface, bool level);
+ static void
+ reset_signal_is( bool async, const sc_out<bool>& iface, bool level);
+
+ protected:
+ sc_reset( const sc_signal_in_if<bool>* iface_p ) :
+ m_iface_p(iface_p), m_targets() {}
+ void notify_processes();
+ void remove_process( sc_process_b* );
+
+ protected:
+ const sc_signal_in_if<bool>* m_iface_p; // Interface to read.
+ std::vector<sc_reset_target> m_targets; // List of processes to reset.
+
+ private: // disabled
+ sc_reset( const sc_reset& );
+ const sc_reset& operator = ( const sc_reset& );
+};
+
+// $Log: sc_reset.h,v $
+// Revision 1.11 2011/08/26 20:46:10 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.10 2011/08/24 22:05:51 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.9 2011/04/08 22:38:30 acg
+// Andy Goodrich: added comment pointing to the description of how the
+// reset mechanism works that is in sc_reset.cpp.
+//
+// Revision 1.8 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.7 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.6 2011/01/06 18:00:32 acg
+// Andy Goodrich: Removed commented out code.
+//
+// Revision 1.5 2010/12/07 20:09:14 acg
+// Andy Goodrich: removed sc_signal signatures since already have sc_signal_in_if signatures.
+//
+// Revision 1.4 2010/11/20 17:10:57 acg
+// Andy Goodrich: reset processing changes for new IEEE 1666 standard.
+//
+// Revision 1.3 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.2 2008/05/22 17:06:26 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.6 2006/12/02 20:58:19 acg
+// Andy Goodrich: updates from 2.2 for IEEE 1666 support.
+//
+// Revision 1.4 2006/04/11 23:13:21 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+} // namespace sc_core
+
+#endif // !defined(sc_reset_h_INCLUDED)
diff --git a/ext/systemc/src/sysc/kernel/sc_runnable.h b/ext/systemc/src/sysc/kernel/sc_runnable.h
new file mode 100644
index 000000000..028a9b311
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_runnable.h
@@ -0,0 +1,144 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_runnable.h --
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_RUNNABLE_H
+#define SC_RUNNABLE_H
+
+
+#include "sysc/kernel/sc_process.h"
+
+namespace sc_core {
+
+//=============================================================================
+// CLASS : sc_runnable
+//
+// Class that manages the ready-to-run queues.
+//=============================================================================
+
+class sc_runnable
+{
+
+ public:
+ sc_runnable();
+ ~sc_runnable();
+
+ inline void init();
+ inline void toggle_methods();
+ inline void toggle_threads();
+
+ inline void remove_method( sc_method_handle );
+ inline void remove_thread( sc_thread_handle );
+
+ inline void execute_method_next( sc_method_handle );
+ inline void execute_thread_next( sc_thread_handle );
+
+ inline void push_back_method( sc_method_handle );
+ inline void push_back_thread( sc_thread_handle );
+ inline void push_front_method( sc_method_handle );
+ inline void push_front_thread( sc_thread_handle );
+
+ inline bool is_initialized() const;
+ inline bool is_empty() const;
+
+ inline sc_method_handle pop_method();
+ inline sc_thread_handle pop_thread();
+
+ public: // diagnostics:
+ void dump() const;
+
+ private:
+ sc_method_handle m_methods_push_head;
+ sc_method_handle m_methods_push_tail;
+ sc_method_handle m_methods_pop;
+ sc_thread_handle m_threads_push_head;
+ sc_thread_handle m_threads_push_tail;
+ sc_thread_handle m_threads_pop;
+
+ private:
+ // disabled
+ sc_runnable( const sc_runnable& );
+ sc_runnable& operator = ( const sc_runnable& );
+};
+
+} // namespace sc_core
+
+#endif
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Andy Goodrich, 30 June 2003, Forte Design Systems
+ Description of Modification: Total rewrite using linked list rather than
+ fixed vector.
+
+
+ Name, Affiliation, Date: Bishnupriya Bhattacharya, Cadence Design Systems,
+ 25 August, 2003
+ Description of Modification: Add tail pointers for m_methods_push and
+ m_threads_push to maintain the same scheduler
+ ordering as 2.0.1
+
+ *****************************************************************************/
+
+// $Log: sc_runnable.h,v $
+// Revision 1.9 2011/08/26 20:46:10 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.8 2011/04/08 18:26:07 acg
+// Andy Goodrich: added execute_method_next() to handle method dispatch
+// for asynchronous notifications that occur outside the evaluation phase.
+//
+// Revision 1.7 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.6 2011/02/13 21:47:38 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.5 2011/02/02 06:37:03 acg
+// Andy Goodrich: removed toggle() method since it is no longer used.
+//
+// Revision 1.4 2011/02/01 21:09:13 acg
+// Andy Goodrich: addition of toggle_methods() and toggle_threads() calls.
+//
+// Revision 1.3 2011/01/25 20:50:37 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.2 2008/05/22 17:06:26 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_runnable_int.h b/ext/systemc/src/sysc/kernel/sc_runnable_int.h
new file mode 100644
index 000000000..510e93758
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_runnable_int.h
@@ -0,0 +1,574 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*******************************************************************************
+
+ sc_runnable_int.h -- For inline definitions of some utility functions.
+ DO NOT EXPORT THIS INCLUDE FILE. Include this file
+ after "sc_process_int.h" so that we can get the base
+ class right.
+
+ Original Author: Bishnupriya Bhattacharya , Cadence Design, 28th July, 2003
+
+ CHANGE LOG AT THE END OF THE FILE
+ ******************************************************************************/
+
+#ifndef SC_RUNNABLE_INT_H
+#define SC_RUNNABLE_INT_H
+
+
+#include "sysc/kernel/sc_runnable.h"
+#include "sysc/kernel/sc_method_process.h"
+#include "sysc/kernel/sc_thread_process.h"
+
+// DEBUGGING MACROS:
+//
+// DEBUG_MSG(NAME,P,MSG)
+// MSG = message to print
+// NAME = name that must match the process for the message to print, or
+// null if the message should be printed unconditionally.
+// P = pointer to process message is for, or NULL in which case the
+// message will not print.
+#if 0
+# define DEBUG_NAME ""
+# define DEBUG_MSG(NAME,P,MSG) \
+ { \
+ if ( P && ( (strlen(NAME)==0) || !strcmp(NAME,P->name())) ) \
+ std::cout << "**** " << sc_time_stamp() << " (" \
+ << sc_get_current_process_name() << "): " << MSG \
+ << " - " << P->name() << std::endl; \
+ }
+#else
+# define DEBUG_MSG(NAME,P,MSG)
+#endif
+
+namespace sc_core {
+
+// The values below are used to indicate when a queue is empty. A non-zero
+// non-legal pointer value is used for this so that a zero value in the
+// m_execute_p field of an sc_process_b instance can be used to indicate
+// that is has not been queued for run. (If we did not use a non-zero
+// queue empty indicator then a sc_process_b instance that was queued
+// twice in a row might end up on the queue twice if it were the first
+// one that was queued!)
+
+#define SC_NO_METHODS ((sc_method_handle)0xdb)
+#define SC_NO_THREADS ((sc_thread_handle)0xdb)
+
+
+//------------------------------------------------------------------------------
+//"sc_runnable::dump"
+//
+// This method dumps the contents of this object instance.
+//------------------------------------------------------------------------------
+inline void sc_runnable::dump() const
+{
+ // Dump the thread queues:
+
+ std::cout << "thread pop queue: " << std::endl;
+ for ( sc_thread_handle p = m_threads_pop; p != SC_NO_THREADS;
+ p = p->next_runnable() )
+ {
+ std::cout << " " << p << std::endl;
+ }
+
+ std::cout << "thread push queue: " << std::endl;
+ for ( sc_thread_handle p = m_threads_push_head->next_runnable();
+ p != SC_NO_THREADS; p = p->next_runnable() )
+ {
+ std::cout << " " << p << std::endl;
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_runnable::execute_method_next"
+//
+// This method pushes the the supplied method to execute as the next process.
+// This is done by pushing it onto the front of the m_methods_pop.
+// method_h -> method process to add to the queue.
+//------------------------------------------------------------------------------
+inline void sc_runnable::execute_method_next( sc_method_handle method_h )
+{
+ DEBUG_MSG(DEBUG_NAME,method_h,"pushing this method to execute next");
+ method_h->set_next_runnable( m_methods_pop );
+ m_methods_pop = method_h;
+}
+
+//------------------------------------------------------------------------------
+//"sc_runnable::execute_thread_next"
+//
+// This method pushes the the supplied thread to execute as the next process.
+// This is done by pushing it onto the front of the m_threads_pop.
+// thread_h -> thread process to add to the queue.
+//------------------------------------------------------------------------------
+inline void sc_runnable::execute_thread_next( sc_thread_handle thread_h )
+{
+ DEBUG_MSG(DEBUG_NAME,thread_h,"pushing this thread to execute next");
+ thread_h->set_next_runnable( m_threads_pop );
+ m_threads_pop = thread_h;
+}
+
+//------------------------------------------------------------------------------
+//"sc_runnable::init"
+//
+// This method initializes this object instance. Note we allocate the queue
+// heads if necessary. This is done here rather than in the constructor for
+// this class to eliminate CTOR processing errors with gcc.
+//------------------------------------------------------------------------------
+inline void sc_runnable::init()
+{
+ m_methods_pop = SC_NO_METHODS;
+ if ( !m_methods_push_head )
+ {
+ m_methods_push_head = new sc_method_process("methods_push_head", true,
+ (SC_ENTRY_FUNC)0, 0, 0);
+ m_methods_push_head->dont_initialize(true);
+ m_methods_push_head->detach();
+ }
+ m_methods_push_tail = m_methods_push_head;
+ m_methods_push_head->set_next_runnable(SC_NO_METHODS);
+
+ m_threads_pop = SC_NO_THREADS;
+ if ( !m_threads_push_head )
+ {
+ m_threads_push_head = new sc_thread_process("threads_push_head", true,
+ (SC_ENTRY_FUNC)0, 0, 0);
+ m_threads_push_head->dont_initialize(true);
+ m_threads_push_head->detach();
+ }
+ m_threads_push_head->set_next_runnable(SC_NO_THREADS);
+ m_threads_push_tail = m_threads_push_head;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_runnable::is_empty"
+//
+// This method returns true if the push queue is empty, or false if not.
+//------------------------------------------------------------------------------
+inline bool sc_runnable::is_empty() const
+{
+ return m_methods_push_head->next_runnable() == SC_NO_METHODS &&
+ m_methods_pop == SC_NO_METHODS &&
+ m_threads_push_head->next_runnable() == SC_NO_THREADS &&
+ m_threads_pop == SC_NO_THREADS;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_runnable::is_initialized"
+//
+// This method returns true if the push queue is already initialized.
+//------------------------------------------------------------------------------
+inline bool sc_runnable::is_initialized() const
+{
+ return m_methods_push_head && m_threads_push_head;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_runnable::push_back_method"
+//
+// This method pushes the supplied method process onto the back of the queue of
+// runnable method processes.
+// method_h -> method process to add to the queue.
+//------------------------------------------------------------------------------
+inline void sc_runnable::push_back_method( sc_method_handle method_h )
+{
+ // assert( method_h->next_runnable() == 0 ); // Can't queue twice.
+ DEBUG_MSG(DEBUG_NAME,method_h,"pushing back method");
+ method_h->set_next_runnable(SC_NO_METHODS);
+ m_methods_push_tail->set_next_runnable(method_h);
+ m_methods_push_tail = method_h;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_runnable::push_back_thread"
+//
+// This method pushes the supplied thread process onto the back of the queue of
+// runnable thread processes.
+// thread_h -> thread process to add to the queue.
+//------------------------------------------------------------------------------
+inline void sc_runnable::push_back_thread( sc_thread_handle thread_h )
+{
+ // assert( thread_h->next_runnable() == 0 ); // Can't queue twice.
+ DEBUG_MSG(DEBUG_NAME,thread_h,"pushing back thread");
+ thread_h->set_next_runnable(SC_NO_THREADS);
+ m_threads_push_tail->set_next_runnable(thread_h);
+ m_threads_push_tail = thread_h;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_runnable::push_front_method"
+//
+// This method pushes the supplied method process onto the front of the queue of
+// runnable method processes. If the queue is empty the process is the tail
+// also.
+// method_h -> method process to add to the queue.
+//------------------------------------------------------------------------------
+inline void sc_runnable::push_front_method( sc_method_handle method_h )
+{
+ // assert( method_h->next_runnable() == 0 ); // Can't queue twice.
+ DEBUG_MSG(DEBUG_NAME,method_h,"pushing front method");
+ method_h->set_next_runnable(m_methods_push_head->next_runnable());
+ if ( m_methods_push_tail == m_methods_push_head ) // Empty queue.
+ {
+ m_methods_push_tail->set_next_runnable(method_h);
+ m_methods_push_tail = method_h;
+ }
+ else // Non-empty queue.
+ {
+ m_methods_push_head->set_next_runnable(method_h);
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_runnable::push_front_thread"
+//
+// This method pushes the supplied thread process onto the front of the queue of
+// runnable thread processes. If the queue is empty the process is the tail
+// also.
+// thread_h -> thread process to add to the queue.
+//------------------------------------------------------------------------------
+inline void sc_runnable::push_front_thread( sc_thread_handle thread_h )
+{
+ // assert( thread_h->next_runnable() == 0 ); // Can't queue twice.
+ DEBUG_MSG(DEBUG_NAME,thread_h,"pushing front thread");
+ thread_h->set_next_runnable(m_threads_push_head->next_runnable());
+ if ( m_threads_push_tail == m_threads_push_head ) // Empty queue.
+ {
+ m_threads_push_tail->set_next_runnable(thread_h);
+ m_threads_push_tail = thread_h;
+ }
+ else // Non-empty queue.
+ {
+ m_threads_push_head->set_next_runnable(thread_h);
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_runnable::pop_method"
+//
+// This method pops the next method process to be executed, or returns a null
+// if no method processes are available for execution.
+//------------------------------------------------------------------------------
+inline sc_method_handle sc_runnable::pop_method()
+{
+ sc_method_handle result_p;
+
+ result_p = m_methods_pop;
+ if ( result_p != SC_NO_METHODS )
+ {
+ m_methods_pop = result_p->next_runnable();
+ result_p->set_next_runnable(0);
+ }
+ else
+ {
+ result_p = 0;
+ }
+ DEBUG_MSG(DEBUG_NAME,result_p,"popping method");
+ return result_p;
+
+}
+
+//------------------------------------------------------------------------------
+//"sc_runnable::pop_thread"
+//
+// This method pops the next thread process to be executed, or returns a null
+// if no thread processes are available for execution.
+//------------------------------------------------------------------------------
+inline sc_thread_handle sc_runnable::pop_thread()
+{
+ sc_thread_handle result_p;
+
+ result_p = m_threads_pop;
+ if ( result_p != SC_NO_THREADS )
+ {
+ m_threads_pop = result_p->next_runnable();
+ result_p->set_next_runnable(0);
+ }
+ else
+ {
+ result_p = 0;
+ }
+ DEBUG_MSG(DEBUG_NAME,result_p,"popping thread for execution");
+ return result_p;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_runnable::remove_method"
+//
+// This method removes the supplied method process from the push queue if it is
+// present. Note we clear the method's next pointer so that it may be queued
+// again.
+// remove_p -> method process to remove from the run queue.
+//------------------------------------------------------------------------------
+inline void sc_runnable::remove_method( sc_method_handle remove_p )
+{
+ sc_method_handle now_p; // Method now checking.
+ sc_method_handle prior_p; // Method prior to now_p.
+
+ // Don't try to remove things if we have not been initialized.
+
+ if ( !is_initialized() ) return;
+
+ // Search the push queue:
+
+ prior_p = m_methods_push_head;
+ for ( now_p = m_methods_push_head; now_p!= SC_NO_METHODS;
+ now_p = now_p->next_runnable() )
+ {
+ if ( remove_p == now_p )
+ {
+ prior_p->set_next_runnable( now_p->next_runnable() );
+ if (now_p == m_methods_push_tail) {
+ m_methods_push_tail = prior_p;
+ }
+ now_p->set_next_runnable(0);
+ DEBUG_MSG(DEBUG_NAME,now_p,"removing method from push queue");
+ return;
+ }
+ prior_p = now_p;
+ }
+
+ // Search the pop queue:
+
+ prior_p = NULL;
+ for ( now_p = m_methods_pop; now_p != SC_NO_METHODS;
+ now_p = now_p->next_runnable() )
+ {
+ if ( remove_p == now_p )
+ {
+ if ( prior_p )
+ prior_p->set_next_runnable( now_p->next_runnable() );
+ else
+ m_methods_pop = now_p->next_runnable();
+ now_p->set_next_runnable(0);
+ DEBUG_MSG(DEBUG_NAME,now_p,"removing method from pop queue");
+ return;
+ }
+ prior_p = now_p;
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_runnable::remove_thread"
+//
+// This method removes the supplied thread process from the push or pop
+// queue if it is present. Note we clear the thread's next pointer so that it
+// may be queued again.
+// remove_p -> thread process to remove from the run queue.
+//------------------------------------------------------------------------------
+inline void sc_runnable::remove_thread( sc_thread_handle remove_p )
+{
+ sc_thread_handle now_p; // Thread now checking.
+ sc_thread_handle prior_p; // Thread prior to now_p.
+
+ // Don't try to remove things if we have not been initialized.
+
+ if ( !is_initialized() ) return;
+
+ // Search the push queue:
+
+ prior_p = m_threads_push_head;
+ for ( now_p = m_threads_push_head; now_p != SC_NO_THREADS;
+ now_p = now_p->next_runnable() )
+ {
+ if ( remove_p == now_p )
+ {
+ prior_p->set_next_runnable( now_p->next_runnable() );
+ if (now_p == m_threads_push_tail) {
+ m_threads_push_tail = prior_p;
+ }
+ now_p->set_next_runnable(0);
+ DEBUG_MSG(DEBUG_NAME,now_p,"removing thread from push queue");
+ return;
+ }
+ prior_p = now_p;
+ }
+
+ // Search the pop queue:
+
+ prior_p = NULL;
+ for ( now_p = m_threads_pop; now_p != SC_NO_THREADS;
+ now_p = now_p->next_runnable() )
+ {
+ if ( remove_p == now_p )
+ {
+ if ( prior_p )
+ prior_p->set_next_runnable( now_p->next_runnable() );
+ else
+ m_threads_pop = now_p->next_runnable();
+ now_p->set_next_runnable(0);
+ DEBUG_MSG(DEBUG_NAME,now_p,"removing thread from pop queue");
+ return;
+ }
+ prior_p = now_p;
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_runnable::sc_runnable"
+//
+// This is the object instance constructor for this class.
+//------------------------------------------------------------------------------
+inline sc_runnable::sc_runnable() :
+ m_methods_push_head(0), m_methods_push_tail(0), m_methods_pop(SC_NO_METHODS),
+ m_threads_push_head(0), m_threads_push_tail(0), m_threads_pop(SC_NO_THREADS)
+{}
+
+//------------------------------------------------------------------------------
+//"sc_runnable::~sc_runnable"
+//
+// This is the object instance destructor for this class.
+//------------------------------------------------------------------------------
+inline sc_runnable::~sc_runnable()
+{
+ delete m_methods_push_head;
+ delete m_threads_push_head;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_runnable::toggle_methods"
+//
+// This method moves the methods push queue to the pop queue and zeros the push
+// queue. This will only be done if the pop queue is presently empty.
+//------------------------------------------------------------------------------
+inline void sc_runnable::toggle_methods()
+{
+ if ( m_methods_pop == SC_NO_METHODS )
+ {
+ m_methods_pop = m_methods_push_head->next_runnable();
+ m_methods_push_head->set_next_runnable(SC_NO_METHODS);
+ m_methods_push_tail = m_methods_push_head;
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_runnable::toggle_threads"
+//
+// This method moves the threads push queue to the pop queue and zeros the push
+// queue. This will only be done if the pop queue is presently empty.
+//------------------------------------------------------------------------------
+inline void sc_runnable::toggle_threads()
+{
+ if ( m_threads_pop == SC_NO_THREADS )
+ {
+ m_threads_pop = m_threads_push_head->next_runnable();
+ m_threads_push_head->set_next_runnable(SC_NO_THREADS);
+ m_threads_push_tail = m_threads_push_head;
+ }
+}
+
+#undef SC_NO_METHODS
+#undef SC_NO_THREADS
+#undef DEBUG_MSG
+
+} // namespace sc_core
+
+
+/*******************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+ Andy Goodrich, Forte Design Systems, 2 September 2003
+ Changed queue heads to instances to eliminate the checks for null heads.
+
+ ******************************************************************************/
+
+// $Log: sc_runnable_int.h,v $
+// Revision 1.19 2011/08/24 22:05:51 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.18 2011/08/07 19:08:04 acg
+// Andy Goodrich: moved logs to end of file so line number synching works
+// better between versions.
+//
+// Revision 1.17 2011/04/13 02:45:11 acg
+// Andy Goodrich: eliminated warning message that occurred if the DEBUG_MSG
+// macro was used.
+//
+// Revision 1.16 2011/04/10 22:18:23 acg
+// Andy Goodrich: debugging message clean up.
+//
+// Revision 1.15 2011/04/08 18:26:07 acg
+// Andy Goodrich: added execute_method_next() to handle method dispatch
+// for asynchronous notifications that occur outside the evaluation phase.
+//
+// Revision 1.14 2011/04/01 21:31:10 acg
+// Andy Goodrich: turn off diagnostic messages by default.
+//
+// Revision 1.13 2011/04/01 21:30:02 acg
+// Andy Goodrich: inserted conditional displays for queue manipulations.
+//
+// Revision 1.12 2011/03/30 00:01:34 acg
+// Philip A. Hartmann: change break to return in remove_method() to short
+// circuit the search the way remove_thread() works.
+//
+// Revision 1.11 2011/03/28 13:02:52 acg
+// Andy Goodrich: Changes for disable() interactions.
+//
+// Revision 1.10 2011/03/06 15:58:17 acg
+// Andy Goodrich: formatting changes.
+//
+// Revision 1.9 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.8 2011/02/13 21:47:38 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.7 2011/02/02 06:37:03 acg
+// Andy Goodrich: removed toggle() method since it is no longer used.
+//
+// Revision 1.6 2011/02/01 21:09:13 acg
+// Andy Goodrich: addition of toggle_methods() and toggle_threads() calls.
+//
+// Revision 1.5 2011/01/25 20:50:37 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.4 2010/07/22 20:02:33 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.3 2009/02/28 00:26:58 acg
+// Andy Goodrich: changed boost name space to sc_boost to allow use with
+// full boost library applications.
+//
+// Revision 1.2 2008/05/22 17:06:26 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.4 2006/04/20 17:08:17 acg
+// Andy Goodrich: 3.0 style process changes.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+//
+
+#endif // SC_RUNNABLE_INT_H
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_sensitive.cpp b/ext/systemc/src/sysc/kernel/sc_sensitive.cpp
new file mode 100644
index 000000000..210c2670e
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_sensitive.cpp
@@ -0,0 +1,959 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_sensitive.cpp --
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+ Martin Janssen, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#include "sysc/kernel/sc_event.h"
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/kernel/sc_module.h"
+#include "sysc/kernel/sc_cthread_process.h"
+#include "sysc/kernel/sc_method_process.h"
+#include "sysc/kernel/sc_thread_process.h"
+#include "sysc/kernel/sc_process_handle.h"
+#include "sysc/kernel/sc_sensitive.h"
+#include "sysc/communication/sc_signal_ports.h"
+#include "sysc/utils/sc_utils_ids.h"
+
+namespace sc_core {
+
+// support functions
+
+static
+sc_method_handle
+as_method_handle( sc_process_b* handle_ )
+{
+ return DCAST<sc_method_handle>( handle_ );
+}
+
+static
+sc_thread_handle
+as_thread_handle( sc_process_b* handle_ )
+{
+ return DCAST<sc_thread_handle>( handle_ );
+}
+
+static
+void
+warn_no_parens()
+{
+ static bool warn_no_parentheses=true;
+ if ( warn_no_parentheses )
+ {
+ warn_no_parentheses=false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "use of () to specify sensitivity is deprecated, use << instead" );
+ }
+}
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_sensitive
+//
+// Static sensitivity class for events.
+// ----------------------------------------------------------------------------
+
+// constructor
+
+sc_sensitive::sc_sensitive( sc_module* module_ )
+: m_module( module_ ),
+ m_mode( SC_NONE_ ),
+ m_handle( 0 )
+{}
+
+
+// destructor
+
+sc_sensitive::~sc_sensitive()
+{}
+
+
+// changing between process handles
+
+sc_sensitive&
+sc_sensitive::operator << ( sc_process_handle handle_ )
+{
+ switch ( handle_.proc_kind() )
+ {
+ case SC_CTHREAD_PROC_:
+ case SC_THREAD_PROC_:
+ m_mode = SC_THREAD_;
+ break;
+ case SC_METHOD_PROC_:
+ m_mode = SC_METHOD_;
+ break;
+ default:
+ assert(0);
+ }
+ m_handle = (sc_process_b*)handle_;
+ return *this;
+}
+
+sc_sensitive&
+sc_sensitive::operator << ( const sc_event& event_ )
+{
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_:
+ case SC_THREAD_: {
+ m_handle->add_static_event( event_ );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+void
+sc_sensitive::make_static_sensitivity(
+ sc_process_b* handle_, const sc_event& event_)
+{
+ handle_->add_static_event( event_ );
+}
+
+
+sc_sensitive&
+sc_sensitive::operator << ( const sc_interface& interface_ )
+{
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_:
+ case SC_THREAD_: {
+ m_handle->add_static_event( interface_.default_event() );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+void
+sc_sensitive::make_static_sensitivity(
+ sc_process_b* handle_, const sc_interface& interface_)
+{
+ handle_->add_static_event( interface_.default_event() );
+}
+
+sc_sensitive&
+sc_sensitive::operator << ( const sc_port_base& port_ )
+{
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_: {
+ port_.make_sensitive( as_method_handle( m_handle ) );
+ break;
+ }
+ case SC_THREAD_: {
+ port_.make_sensitive( as_thread_handle( m_handle ) );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+void
+sc_sensitive::make_static_sensitivity(
+ sc_process_b* handle_, const sc_port_base& port_)
+{
+ sc_method_handle handle_m = as_method_handle( handle_ );
+ if ( handle_m ) {
+ port_.make_sensitive( handle_m );
+ return;
+ }
+ sc_thread_handle handle_t = as_thread_handle( handle_ );
+ // assert(handle_t);
+ port_.make_sensitive( handle_t );
+}
+
+sc_sensitive&
+sc_sensitive::operator << ( sc_event_finder& event_finder_ )
+{
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_: {
+ event_finder_.port().make_sensitive( as_method_handle( m_handle ),
+ &event_finder_ );
+ break;
+ }
+ case SC_THREAD_: {
+ event_finder_.port().make_sensitive( as_thread_handle( m_handle ),
+ &event_finder_ );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+void
+sc_sensitive::make_static_sensitivity(
+ sc_process_b* handle_, sc_event_finder& event_finder_)
+{
+ if (sc_is_running()) {
+ handle_->add_static_event( event_finder_.find_event() );
+ } else {
+ sc_method_handle handle_m = as_method_handle( handle_ );
+ if ( handle_m ) {
+ event_finder_.port().make_sensitive( handle_m, &event_finder_ );
+ return;
+ }
+ sc_thread_handle handle_t = as_thread_handle( handle_ );
+ // assert(handle_t);
+ event_finder_.port().make_sensitive( handle_t, &event_finder_);
+ }
+}
+
+
+sc_sensitive&
+sc_sensitive::operator () ( const sc_event& event_ )
+{
+ warn_no_parens();
+ return operator << ( event_ );
+}
+
+sc_sensitive&
+sc_sensitive::operator () ( const sc_interface& interface_ )
+{
+ warn_no_parens();
+ return operator << ( interface_ );
+}
+
+sc_sensitive&
+sc_sensitive::operator () ( const sc_port_base& port_ )
+{
+ warn_no_parens();
+ return operator << ( port_ );
+}
+
+sc_sensitive&
+sc_sensitive::operator () ( sc_event_finder& event_finder_ )
+{
+ warn_no_parens();
+ return operator << ( event_finder_ );
+}
+
+
+sc_sensitive&
+sc_sensitive::operator () ( sc_cthread_handle handle_,
+ sc_event_finder& event_finder_ )
+{
+ event_finder_.port().make_sensitive( handle_, &event_finder_ );
+ return *this;
+}
+
+sc_sensitive&
+sc_sensitive::operator () ( sc_cthread_handle handle_,
+ const in_if_b_type& interface_ )
+{
+ handle_->add_static_event( interface_.posedge_event() );
+ return *this;
+}
+
+sc_sensitive&
+sc_sensitive::operator () ( sc_cthread_handle handle_,
+ const in_if_l_type& interface_ )
+{
+ handle_->add_static_event( interface_.posedge_event() );
+ return *this;
+}
+
+sc_sensitive&
+sc_sensitive::operator () ( sc_cthread_handle handle_,
+ const in_port_b_type& port_ )
+{
+ port_.make_sensitive( handle_, &port_.pos() );
+ return *this;
+}
+
+sc_sensitive&
+sc_sensitive::operator () ( sc_cthread_handle handle_,
+ const in_port_l_type& port_ )
+{
+ port_.make_sensitive( handle_, &port_.pos() );
+ return *this;
+}
+
+sc_sensitive&
+sc_sensitive::operator () ( sc_cthread_handle handle_,
+ const inout_port_b_type& port_ )
+{
+ port_.make_sensitive( handle_, &port_.pos() );
+ return *this;
+}
+
+sc_sensitive&
+sc_sensitive::operator () ( sc_cthread_handle handle_,
+ const inout_port_l_type& port_ )
+{
+ port_.make_sensitive( handle_, &port_.pos() );
+ return *this;
+}
+
+void sc_sensitive::reset()
+{
+ m_mode = SC_NONE_;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_sensitive_pos
+//
+// Static sensitivity class for positive edge events.
+// ----------------------------------------------------------------------------
+
+static void sc_deprecated_sensitive_pos()
+{
+ static bool warn_sensitive_pos=true;
+ if ( warn_sensitive_pos )
+ {
+ warn_sensitive_pos=false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "sc_sensitive_pos is deprecated use sc_sensitive << with pos() instead" );
+ }
+}
+
+// constructor
+
+sc_sensitive_pos::sc_sensitive_pos( sc_module* module_ )
+: m_module( module_ ),
+ m_mode( SC_NONE_ ),
+ m_handle( 0 )
+{}
+
+
+// destructor
+
+sc_sensitive_pos::~sc_sensitive_pos()
+{}
+
+
+// changing between process handles
+
+sc_sensitive_pos&
+sc_sensitive_pos::operator << ( sc_process_handle handle_ )
+{
+ switch ( handle_.proc_kind() )
+ {
+ case SC_CTHREAD_PROC_:
+ case SC_THREAD_PROC_:
+ m_mode = SC_THREAD_;
+ break;
+ case SC_METHOD_PROC_:
+ m_mode = SC_METHOD_;
+ break;
+ default:
+ assert(0);
+ }
+ m_handle = (sc_process_b*)handle_;
+ return *this;
+}
+
+sc_sensitive_pos&
+sc_sensitive_pos::operator << ( sc_method_handle handle_ )
+{
+ m_mode = SC_METHOD_;
+ m_handle = handle_;
+ return *this;
+}
+
+sc_sensitive_pos&
+sc_sensitive_pos::operator << ( sc_thread_handle handle_ )
+{
+ m_mode = SC_THREAD_;
+ m_handle = handle_;
+ return *this;
+}
+
+
+sc_sensitive_pos&
+sc_sensitive_pos::operator << ( const in_if_b_type& interface_ )
+{
+ sc_deprecated_sensitive_pos();
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_POS_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_:
+ case SC_THREAD_: {
+ m_handle->add_static_event( interface_.posedge_event() );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+sc_sensitive_pos&
+sc_sensitive_pos::operator << ( const in_if_l_type& interface_ )
+{
+ sc_deprecated_sensitive_pos();
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_POS_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_:
+ case SC_THREAD_: {
+ m_handle->add_static_event( interface_.posedge_event() );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+sc_sensitive_pos&
+sc_sensitive_pos::operator << ( const in_port_b_type& port_ )
+{
+ sc_deprecated_sensitive_pos();
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_POS_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_: {
+ port_.make_sensitive( as_method_handle( m_handle ), &port_.pos() );
+ break;
+ }
+ case SC_THREAD_: {
+ port_.make_sensitive( as_thread_handle( m_handle ), &port_.pos() );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+sc_sensitive_pos&
+sc_sensitive_pos::operator << ( const in_port_l_type& port_ )
+{
+ sc_deprecated_sensitive_pos();
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_POS_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_: {
+ port_.make_sensitive( as_method_handle( m_handle ), &port_.pos() );
+ break;
+ }
+ case SC_THREAD_: {
+ port_.make_sensitive( as_thread_handle( m_handle ), &port_.pos() );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+sc_sensitive_pos&
+sc_sensitive_pos::operator << ( const inout_port_b_type& port_ )
+{
+ sc_deprecated_sensitive_pos();
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_POS_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_: {
+ port_.make_sensitive( as_method_handle( m_handle ), &port_.pos() );
+ break;
+ }
+ case SC_THREAD_: {
+ port_.make_sensitive( as_thread_handle( m_handle ), &port_.pos() );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+sc_sensitive_pos&
+sc_sensitive_pos::operator << ( const inout_port_l_type& port_ )
+{
+ sc_deprecated_sensitive_pos();
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_POS_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_: {
+ port_.make_sensitive( as_method_handle( m_handle ), &port_.pos() );
+ break;
+ }
+ case SC_THREAD_: {
+ port_.make_sensitive( as_thread_handle( m_handle ), &port_.pos() );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+
+sc_sensitive_pos&
+sc_sensitive_pos::operator () ( const in_if_b_type& interface_ )
+{
+ warn_no_parens();
+ return operator << ( interface_ );
+}
+
+sc_sensitive_pos&
+sc_sensitive_pos::operator () ( const in_if_l_type& interface_ )
+{
+ warn_no_parens();
+ return operator << ( interface_ );
+}
+
+sc_sensitive_pos&
+sc_sensitive_pos::operator () ( const in_port_b_type& port_ )
+{
+ warn_no_parens();
+ return operator << ( port_ );
+}
+
+sc_sensitive_pos&
+sc_sensitive_pos::operator () ( const in_port_l_type& port_ )
+{
+ warn_no_parens();
+ return operator << ( port_ );
+}
+
+sc_sensitive_pos&
+sc_sensitive_pos::operator () ( const inout_port_b_type& port_ )
+{
+ warn_no_parens();
+ return operator << ( port_ );
+}
+
+sc_sensitive_pos&
+sc_sensitive_pos::operator () ( const inout_port_l_type& port_ )
+{
+ warn_no_parens();
+ return operator << ( port_ );
+}
+
+void sc_sensitive_pos::reset()
+{
+ m_mode = SC_NONE_;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_sensitive_neg
+//
+// Static sensitivity class for negative edge events.
+// ----------------------------------------------------------------------------
+
+static void sc_deprecated_sensitive_neg()
+{
+ static bool warn_sensitive_neg=true;
+ if ( warn_sensitive_neg )
+ {
+ warn_sensitive_neg=false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "sc_sensitive_neg is deprecated use sc_sensitive << with neg() instead" );
+ }
+}
+
+// constructor
+
+sc_sensitive_neg::sc_sensitive_neg( sc_module* module_ )
+: m_module( module_ ),
+ m_mode( SC_NONE_ ),
+ m_handle( 0 )
+{}
+
+
+// destructor
+
+sc_sensitive_neg::~sc_sensitive_neg()
+{}
+
+
+// changing between process handles
+
+sc_sensitive_neg&
+sc_sensitive_neg::operator << ( sc_process_handle handle_ )
+{
+ switch ( handle_.proc_kind() )
+ {
+ case SC_CTHREAD_PROC_:
+ case SC_THREAD_PROC_:
+ m_mode = SC_THREAD_;
+ break;
+ case SC_METHOD_PROC_:
+ m_mode = SC_METHOD_;
+ break;
+ default:
+ assert(0);
+ }
+ m_handle = (sc_process_b*)handle_;
+ return *this;
+}
+
+sc_sensitive_neg&
+sc_sensitive_neg::operator << ( sc_method_handle handle_ )
+{
+ m_mode = SC_METHOD_;
+ m_handle = handle_;
+ return *this;
+}
+
+sc_sensitive_neg&
+sc_sensitive_neg::operator << ( sc_thread_handle handle_ )
+{
+ m_mode = SC_THREAD_;
+ m_handle = handle_;
+ return *this;
+}
+
+
+sc_sensitive_neg&
+sc_sensitive_neg::operator << ( const in_if_b_type& interface_ )
+{
+ sc_deprecated_sensitive_neg();
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_NEG_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_:
+ case SC_THREAD_: {
+ m_handle->add_static_event( interface_.negedge_event() );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+sc_sensitive_neg&
+sc_sensitive_neg::operator << ( const in_if_l_type& interface_ )
+{
+ sc_deprecated_sensitive_neg();
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_NEG_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_:
+ case SC_THREAD_: {
+ m_handle->add_static_event( interface_.negedge_event() );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+sc_sensitive_neg&
+sc_sensitive_neg::operator << ( const in_port_b_type& port_ )
+{
+ sc_deprecated_sensitive_neg();
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_NEG_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_: {
+ port_.make_sensitive( as_method_handle( m_handle ), &port_.neg() );
+ break;
+ }
+ case SC_THREAD_: {
+ port_.make_sensitive( as_thread_handle( m_handle ), &port_.neg() );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+sc_sensitive_neg&
+sc_sensitive_neg::operator << ( const in_port_l_type& port_ )
+{
+ sc_deprecated_sensitive_neg();
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_NEG_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_: {
+ port_.make_sensitive( as_method_handle( m_handle ), &port_.neg() );
+ break;
+ }
+ case SC_THREAD_: {
+ port_.make_sensitive( as_thread_handle( m_handle ), &port_.neg() );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+sc_sensitive_neg&
+sc_sensitive_neg::operator << ( const inout_port_b_type& port_ )
+{
+ sc_deprecated_sensitive_neg();
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_NEG_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_: {
+ port_.make_sensitive( as_method_handle( m_handle ), &port_.neg() );
+ break;
+ }
+ case SC_THREAD_: {
+ port_.make_sensitive( as_thread_handle( m_handle ), &port_.neg() );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+sc_sensitive_neg&
+sc_sensitive_neg::operator << ( const inout_port_l_type& port_ )
+{
+ sc_deprecated_sensitive_neg();
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_NEG_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_: {
+ port_.make_sensitive( as_method_handle( m_handle ), &port_.neg() );
+ break;
+ }
+ case SC_THREAD_: {
+ port_.make_sensitive( as_thread_handle( m_handle ), &port_.neg() );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+
+sc_sensitive_neg&
+sc_sensitive_neg::operator () ( const in_if_b_type& interface_ )
+{
+ warn_no_parens();
+ return operator << ( interface_ );
+}
+
+sc_sensitive_neg&
+sc_sensitive_neg::operator () ( const in_if_l_type& interface_ )
+{
+ warn_no_parens();
+ return operator << ( interface_ );
+}
+
+sc_sensitive_neg&
+sc_sensitive_neg::operator () ( const in_port_b_type& port_ )
+{
+ warn_no_parens();
+ return operator << ( port_ );
+}
+
+sc_sensitive_neg&
+sc_sensitive_neg::operator () ( const in_port_l_type& port_ )
+{
+ warn_no_parens();
+ return operator << ( port_ );
+}
+
+sc_sensitive_neg&
+sc_sensitive_neg::operator () ( const inout_port_b_type& port_ )
+{
+ warn_no_parens();
+ return operator << ( port_ );
+}
+
+sc_sensitive_neg&
+sc_sensitive_neg::operator () ( const inout_port_l_type& port_ )
+{
+ warn_no_parens();
+ return operator << ( port_ );
+}
+
+void sc_sensitive_neg::reset()
+{
+ m_mode = SC_NONE_;
+}
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Bishnupriya Bhattacharya, Cadence Design Systems,
+ 25 August, 2003
+ Description of Modification: add make_static_sensitivity() routines to support
+ dynamic method process creation with static
+ sensitivity
+
+ *****************************************************************************/
+
+// $Log: sc_sensitive.cpp,v $
+// Revision 1.5 2011/08/26 20:46:10 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:38 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.2 2008/05/22 17:06:26 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.8 2006/04/11 23:13:21 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.7 2006/01/27 17:31:24 acg
+// Andy Goodrich: removed debugging comments from << operator code for types
+// that are deprecated.
+//
+// Revision 1.6 2006/01/26 21:04:54 acg
+// Andy Goodrich: deprecation message changes and additional messages.
+//
+// Revision 1.5 2006/01/25 00:31:19 acg
+// Andy Goodrich: Changed over to use a standard message id of
+// SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
+//
+// Revision 1.4 2006/01/24 20:49:05 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+//
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_sensitive.h b/ext/systemc/src/sysc/kernel/sc_sensitive.h
new file mode 100644
index 000000000..9d07bd03a
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_sensitive.h
@@ -0,0 +1,306 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_sensitive.h -- Sensitivity classes. Requires "sc_process.h"
+ for declarations of sc_method_handle, &.c.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+ Martin Janssen, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_SENSITIVE_H
+#define SC_SENSITIVE_H
+
+#include "sysc/kernel/sc_process.h"
+
+namespace sc_dt
+{
+ class sc_logic;
+}
+
+namespace sc_core {
+
+class sc_process_handle;
+class sc_event;
+class sc_event_finder;
+class sc_interface;
+class sc_module;
+class sc_port_base;
+template <class T> class sc_in;
+template <class T> class sc_inout;
+template <class T> class sc_signal_in_if;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_sensitive
+//
+// Static sensitivity class for events.
+// ----------------------------------------------------------------------------
+
+class sc_sensitive
+{
+ friend class sc_module;
+
+public:
+
+ // typedefs
+ typedef sc_signal_in_if<bool> in_if_b_type;
+ typedef sc_signal_in_if<sc_dt::sc_logic> in_if_l_type;
+ typedef sc_in<bool> in_port_b_type;
+ typedef sc_in<sc_dt::sc_logic> in_port_l_type;
+ typedef sc_inout<bool> inout_port_b_type;
+ typedef sc_inout<sc_dt::sc_logic> inout_port_l_type;
+
+private:
+
+ // constructor
+ explicit sc_sensitive( sc_module* );
+
+ // destructor
+ ~sc_sensitive();
+
+public:
+
+ // changing between process handles
+ sc_sensitive& operator << ( sc_process_handle );
+#if 0
+ sc_sensitive& operator << ( sc_method_handle );
+ sc_sensitive& operator << ( sc_thread_handle );
+#endif // 0
+
+ sc_sensitive& operator () ( const sc_event& );
+ sc_sensitive& operator () ( const sc_interface& );
+ sc_sensitive& operator () ( const sc_port_base& );
+ sc_sensitive& operator () ( sc_event_finder& );
+
+ sc_sensitive& operator << ( const sc_event& );
+ sc_sensitive& operator << ( const sc_interface& );
+ sc_sensitive& operator << ( const sc_port_base& );
+ sc_sensitive& operator << ( sc_event_finder& );
+
+ sc_sensitive& operator () ( sc_cthread_handle, sc_event_finder& );
+ sc_sensitive& operator () ( sc_cthread_handle, const in_if_b_type& );
+ sc_sensitive& operator () ( sc_cthread_handle, const in_if_l_type& );
+ sc_sensitive& operator () ( sc_cthread_handle, const in_port_b_type& );
+ sc_sensitive& operator () ( sc_cthread_handle, const in_port_l_type& );
+ sc_sensitive& operator () ( sc_cthread_handle, const inout_port_b_type& );
+ sc_sensitive& operator () ( sc_cthread_handle, const inout_port_l_type& );
+
+ static void make_static_sensitivity( sc_process_b*, const sc_event& );
+ static void make_static_sensitivity( sc_process_b*, const sc_interface& );
+ static void make_static_sensitivity( sc_process_b*, const sc_port_base&);
+ static void make_static_sensitivity( sc_process_b*, sc_event_finder& );
+
+ void reset();
+
+private:
+
+ sc_module* m_module;
+ enum { SC_NONE_, SC_METHOD_, SC_THREAD_ } m_mode;
+ sc_process_b* m_handle;
+
+private:
+
+ // disabled
+
+ sc_sensitive();
+ sc_sensitive( const sc_sensitive& );
+ sc_sensitive& operator = ( const sc_sensitive& );
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_sensitive_pos
+//
+// Static sensitivity class for positive edge events.
+// ----------------------------------------------------------------------------
+
+class sc_sensitive_pos
+{
+ friend class sc_module;
+
+public:
+
+ // typedefs
+ typedef sc_signal_in_if<bool> in_if_b_type;
+ typedef sc_signal_in_if<sc_dt::sc_logic> in_if_l_type;
+ typedef sc_in<bool> in_port_b_type;
+ typedef sc_in<sc_dt::sc_logic> in_port_l_type;
+ typedef sc_inout<bool> inout_port_b_type;
+ typedef sc_inout<sc_dt::sc_logic> inout_port_l_type;
+
+private:
+
+ // constructor
+ explicit sc_sensitive_pos( sc_module* );
+
+ // destructor
+ ~sc_sensitive_pos();
+
+public:
+
+ // changing between process handles
+ sc_sensitive_pos& operator << ( sc_process_handle );
+ sc_sensitive_pos& operator << ( sc_method_handle );
+ sc_sensitive_pos& operator << ( sc_thread_handle );
+
+ sc_sensitive_pos& operator () ( const in_if_b_type& );
+ sc_sensitive_pos& operator () ( const in_if_l_type& );
+ sc_sensitive_pos& operator () ( const in_port_b_type& );
+ sc_sensitive_pos& operator () ( const in_port_l_type& );
+ sc_sensitive_pos& operator () ( const inout_port_b_type& );
+ sc_sensitive_pos& operator () ( const inout_port_l_type& );
+
+ sc_sensitive_pos& operator << ( const in_if_b_type& );
+ sc_sensitive_pos& operator << ( const in_if_l_type& );
+ sc_sensitive_pos& operator << ( const in_port_b_type& );
+ sc_sensitive_pos& operator << ( const in_port_l_type& );
+ sc_sensitive_pos& operator << ( const inout_port_b_type& );
+ sc_sensitive_pos& operator << ( const inout_port_l_type& );
+
+ void reset();
+
+private:
+
+ sc_module* m_module;
+ enum { SC_NONE_, SC_METHOD_, SC_THREAD_ } m_mode;
+ sc_process_b* m_handle;
+
+private:
+
+ // disabled
+ sc_sensitive_pos();
+ sc_sensitive_pos( const sc_sensitive_pos& );
+ sc_sensitive_pos& operator = ( const sc_sensitive_pos& );
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_sensitive_neg
+//
+// Static sensitivity class for negative edge events.
+// ----------------------------------------------------------------------------
+
+class sc_sensitive_neg
+{
+ friend class sc_module;
+
+public:
+
+ // typedefs
+ typedef sc_signal_in_if<bool> in_if_b_type;
+ typedef sc_signal_in_if<sc_dt::sc_logic> in_if_l_type;
+ typedef sc_in<bool> in_port_b_type;
+ typedef sc_in<sc_dt::sc_logic> in_port_l_type;
+ typedef sc_inout<bool> inout_port_b_type;
+ typedef sc_inout<sc_dt::sc_logic> inout_port_l_type;
+
+private:
+
+ // constructor
+ explicit sc_sensitive_neg( sc_module* );
+
+ // destructor
+ ~sc_sensitive_neg();
+
+public:
+
+ // changing between process handles
+ sc_sensitive_neg& operator << ( sc_process_handle );
+ sc_sensitive_neg& operator << ( sc_method_handle );
+ sc_sensitive_neg& operator << ( sc_thread_handle );
+
+ sc_sensitive_neg& operator () ( const in_if_b_type& );
+ sc_sensitive_neg& operator () ( const in_if_l_type& );
+ sc_sensitive_neg& operator () ( const in_port_b_type& );
+ sc_sensitive_neg& operator () ( const in_port_l_type& );
+ sc_sensitive_neg& operator () ( const inout_port_b_type& );
+ sc_sensitive_neg& operator () ( const inout_port_l_type& );
+
+ sc_sensitive_neg& operator << ( const in_if_b_type& );
+ sc_sensitive_neg& operator << ( const in_if_l_type& );
+ sc_sensitive_neg& operator << ( const in_port_b_type& );
+ sc_sensitive_neg& operator << ( const in_port_l_type& );
+ sc_sensitive_neg& operator << ( const inout_port_b_type& );
+ sc_sensitive_neg& operator << ( const inout_port_l_type& );
+
+ void reset();
+
+private:
+
+ sc_module* m_module;
+ enum { SC_NONE_, SC_METHOD_, SC_THREAD_ } m_mode;
+ sc_process_b* m_handle;
+
+private:
+
+ // disabled
+ sc_sensitive_neg();
+ sc_sensitive_neg( const sc_sensitive_neg& );
+ sc_sensitive_neg& operator = ( const sc_sensitive_neg& );
+};
+
+} // namespace sc_core
+
+#endif
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Bishnupriya Bhattacharya, Cadence Design Systems,
+ 25 August, 2003
+ Description of Modification: Add make_static_sensitivity() methods to enable
+ dynamic method process creation with static
+ sensitivity.
+
+ *****************************************************************************/
+
+// $Log: sc_sensitive.h,v $
+// Revision 1.5 2011/08/26 20:46:10 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:38 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.2 2008/05/22 17:06:26 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.4 2006/04/11 23:13:21 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_simcontext.cpp b/ext/systemc/src/sysc/kernel/sc_simcontext.cpp
new file mode 100644
index 000000000..104f7c984
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_simcontext.cpp
@@ -0,0 +1,2284 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_simcontext.cpp -- Provides a simulation context for use with multiple
+ simulations.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+ Martin Janssen, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include <algorithm>
+
+#define SC_DISABLE_API_VERSION_CHECK // for in-library sc_ver.h inclusion
+
+#include "sysc/kernel/sc_cor_fiber.h"
+#include "sysc/kernel/sc_cor_pthread.h"
+#include "sysc/kernel/sc_cor_qt.h"
+#include "sysc/kernel/sc_event.h"
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/kernel/sc_module.h"
+#include "sysc/kernel/sc_module_registry.h"
+#include "sysc/kernel/sc_name_gen.h"
+#include "sysc/kernel/sc_object_manager.h"
+#include "sysc/kernel/sc_cthread_process.h"
+#include "sysc/kernel/sc_method_process.h"
+#include "sysc/kernel/sc_thread_process.h"
+#include "sysc/kernel/sc_process_handle.h"
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_simcontext_int.h"
+#include "sysc/kernel/sc_reset.h"
+#include "sysc/kernel/sc_ver.h"
+#include "sysc/kernel/sc_boost.h"
+#include "sysc/kernel/sc_spawn.h"
+#include "sysc/kernel/sc_phase_callback_registry.h"
+#include "sysc/communication/sc_port.h"
+#include "sysc/communication/sc_export.h"
+#include "sysc/communication/sc_prim_channel.h"
+#include "sysc/tracing/sc_trace.h"
+#include "sysc/utils/sc_mempool.h"
+#include "sysc/utils/sc_list.h"
+#include "sysc/utils/sc_utils_ids.h"
+
+// DEBUGGING MACROS:
+//
+// DEBUG_MSG(NAME,P,MSG)
+// MSG = message to print
+// NAME = name that must match the process for the message to print, or
+// null if the message should be printed unconditionally.
+// P = pointer to process message is for, or NULL in which case the
+// message will not print.
+#if 0
+# define DEBUG_NAME ""
+# define DEBUG_MSG(NAME,P,MSG) \
+ { \
+ if ( P && ( (strlen(NAME)==0) || !strcmp(NAME,P->name())) ) \
+ std::cout << "**** " << sc_time_stamp() << " (" \
+ << sc_get_current_process_name() << "): " << MSG \
+ << " - " << P->name() << std::endl; \
+ }
+#else
+# define DEBUG_MSG(NAME,P,MSG)
+#endif
+
+#if SC_HAS_PHASE_CALLBACKS_
+# define SC_DO_PHASE_CALLBACK_( Kind ) \
+ m_phase_cb_registry->Kind()
+#else
+# define SC_DO_PHASE_CALLBACK_( Kind ) \
+ ((void)0) /* do nothing */
+#endif
+
+#if defined( SC_ENABLE_SIMULATION_PHASE_CALLBACKS_TRACING )
+// use callback based tracing
+# define SC_SIMCONTEXT_TRACING_ 0
+#else
+// enable tracing via explicit trace_cycle calls from simulator loop
+# define SC_SIMCONTEXT_TRACING_ 1
+#endif
+
+namespace sc_core {
+
+sc_stop_mode stop_mode = SC_STOP_FINISH_DELTA;
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_process_table
+//
+// Container class that keeps track of all method processes,
+// (c)thread processes.
+// ----------------------------------------------------------------------------
+
+class sc_process_table
+{
+ public:
+
+ sc_process_table();
+ ~sc_process_table();
+ void push_front( sc_method_handle );
+ void push_front( sc_thread_handle );
+ sc_method_handle method_q_head();
+ sc_method_handle remove( sc_method_handle );
+ sc_thread_handle thread_q_head();
+ sc_thread_handle remove( sc_thread_handle );
+
+
+ private:
+
+ sc_method_handle m_method_q; // Queue of existing method processes.
+ sc_thread_handle m_thread_q; // Queue of existing thread processes.
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+sc_process_table::sc_process_table() : m_method_q(0), m_thread_q(0)
+{}
+
+sc_process_table::~sc_process_table()
+{
+
+ sc_method_handle method_next_p; // Next method to delete.
+ sc_method_handle method_now_p; // Method now deleting.
+
+ for( method_now_p = m_method_q; method_now_p; method_now_p = method_next_p )
+ {
+ method_next_p = method_now_p->next_exist();
+ delete method_now_p;
+ }
+
+ if ( m_thread_q )
+ {
+ ::std::cout << ::std::endl
+ << "WATCH OUT!! In sc_process_table destructor. "
+ << "Threads and cthreads are not actually getting deleted here. "
+ << "Some memory may leak. Look at the comments here in "
+ << "kernel/sc_simcontext.cpp for more details."
+ << ::std::endl;
+ }
+
+ // don't delete threads and cthreads. If a (c)thread
+ // has died, then it has already been deleted. Only (c)threads created
+ // before simulation-start are in this table. Due to performance
+ // reasons, we don't look up the dying thread in the process table
+ // and remove it from there. simcontext::reset and ~simcontext invoke this
+ // destructor. At present none of these routines are ever invoked.
+ // We can delete threads and cthreads here if a dying thread figured out
+ // it was created before simulation-start and took itself off the
+ // process_table.
+
+#if 0
+ sc_thread_handle thread_next_p; // Next thread to delete.
+ sc_thread_handle thread_now_p; // Thread now deleting.
+
+ for( thread_now_p=m_thread_q; thread_now_p; thread_now_p=thread_next_p )
+ {
+ thread_next_p = thread_now_p->next_exist();
+ delete thread_now_p;
+ }
+#endif // 0
+}
+
+inline
+sc_method_handle
+sc_process_table::method_q_head()
+{
+ return m_method_q;
+}
+
+inline
+void
+sc_process_table::push_front( sc_method_handle handle_ )
+{
+ handle_->set_next_exist(m_method_q);
+ m_method_q = handle_;
+}
+
+inline
+void
+sc_process_table::push_front( sc_thread_handle handle_ )
+{
+ handle_->set_next_exist(m_thread_q);
+ m_thread_q = handle_;
+}
+
+sc_method_handle
+sc_process_table::remove( sc_method_handle handle_ )
+{
+ sc_method_handle now_p; // Entry now examining.
+ sc_method_handle prior_p; // Entry prior to one now examining.
+
+ prior_p = 0;
+ for ( now_p = m_method_q; now_p; now_p = now_p->next_exist() )
+ {
+ if ( now_p == handle_ )
+ {
+ if ( prior_p )
+ prior_p->set_next_exist( now_p->next_exist() );
+ else
+ m_method_q = now_p->next_exist();
+ return handle_;
+ }
+ }
+ return 0;
+}
+
+sc_thread_handle
+sc_process_table::remove( sc_thread_handle handle_ )
+{
+ sc_thread_handle now_p; // Entry now examining.
+ sc_thread_handle prior_p; // Entry prior to one now examining.
+
+ prior_p = 0;
+ for ( now_p = m_thread_q; now_p; now_p = now_p->next_exist() )
+ {
+ if ( now_p == handle_ )
+ {
+ if ( prior_p )
+ prior_p->set_next_exist( now_p->next_exist() );
+ else
+ m_thread_q = now_p->next_exist();
+ return handle_;
+ }
+ }
+ return 0;
+}
+
+inline
+sc_thread_handle
+sc_process_table::thread_q_head()
+{
+ return m_thread_q;
+}
+
+int
+sc_notify_time_compare( const void* p1, const void* p2 )
+{
+ const sc_event_timed* et1 = static_cast<const sc_event_timed*>( p1 );
+ const sc_event_timed* et2 = static_cast<const sc_event_timed*>( p2 );
+
+ const sc_time& t1 = et1->notify_time();
+ const sc_time& t2 = et2->notify_time();
+
+ if( t1 < t2 ) {
+ return 1;
+ } else if( t1 > t2 ) {
+ return -1;
+ } else {
+ return 0;
+ }
+}
+
+
+// +============================================================================
+// | CLASS sc_invoke_method - class to invoke sc_method's to support
+// | sc_simcontext::preempt_with().
+// +============================================================================
+SC_MODULE(sc_invoke_method)
+{
+ SC_CTOR(sc_invoke_method)
+ {
+ // remove from object hierarchy
+ detach();
+ }
+
+ virtual ~sc_invoke_method()
+ {
+ m_invokers.resize(0);
+ }
+
+ // Method to call to execute a method's semantics.
+
+ void invoke_method( sc_method_handle method_h )
+ {
+ sc_process_handle invoker_h; // handle for invocation thread to use.
+ std::vector<sc_process_handle>::size_type invokers_n; // number of invocation threads available.
+
+ m_method = method_h;
+
+ // There is not an invocation thread to use, so allocate one.
+
+ invokers_n = m_invokers.size();
+ if ( invokers_n == 0 )
+ {
+ sc_spawn_options options;
+ options.dont_initialize();
+ options.set_stack_size(0x100000);
+ options.set_sensitivity(&m_dummy);
+ invoker_h = sc_spawn(sc_bind(&sc_invoke_method::invoker,this),
+ sc_gen_unique_name("invoker"), &options);
+ ((sc_process_b*)invoker_h)->detach();
+ }
+
+ // There is an invocation thread to use, use the last one on the list.
+
+ else
+ {
+ invoker_h = m_invokers[invokers_n-1];
+ m_invokers.pop_back();
+ }
+
+ // Fire off the invocation thread to invoke the method's semantics,
+ // When it blocks put it onto the list of invocation threads that
+ // are available.
+
+ sc_get_curr_simcontext()->preempt_with( (sc_thread_handle)invoker_h );
+ DEBUG_MSG( DEBUG_NAME, m_method, "back from preemption" );
+ m_invokers.push_back(invoker_h);
+ }
+
+ // Thread to call method from:
+
+ void invoker()
+ {
+ sc_simcontext* csc_p = sc_get_curr_simcontext();
+ sc_process_b* me = sc_get_current_process_b();
+
+ DEBUG_MSG( DEBUG_NAME, me, "invoker initialization" );
+ for (;; )
+ {
+ DEBUG_MSG( DEBUG_NAME, m_method, "invoker executing method" );
+ csc_p->set_curr_proc( (sc_process_b*)m_method );
+ csc_p->get_active_invokers().push_back((sc_thread_handle)me);
+ m_method->run_process();
+ csc_p->set_curr_proc( me );
+ csc_p->get_active_invokers().pop_back();
+ DEBUG_MSG( DEBUG_NAME, m_method, "back from executing method" );
+ wait();
+ }
+ }
+
+ sc_event m_dummy; // dummy event to wait on.
+ sc_method_handle m_method; // method to be invoked.
+ std::vector<sc_process_handle> m_invokers; // list of invoking threads.
+};
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_simcontext
+//
+// The simulation context.
+// ----------------------------------------------------------------------------
+
+void
+sc_simcontext::init()
+{
+
+ // ALLOCATE VARIOUS MANAGERS AND REGISTRIES:
+
+ m_object_manager = new sc_object_manager;
+ m_module_registry = new sc_module_registry( *this );
+ m_port_registry = new sc_port_registry( *this );
+ m_export_registry = new sc_export_registry( *this );
+ m_prim_channel_registry = new sc_prim_channel_registry( *this );
+ m_phase_cb_registry = new sc_phase_callback_registry( *this );
+ m_name_gen = new sc_name_gen;
+ m_process_table = new sc_process_table;
+ m_current_writer = 0;
+
+
+ // CHECK FOR ENVIRONMENT VARIABLES THAT MODIFY SIMULATOR EXECUTION:
+
+ const char* write_check = std::getenv("SC_SIGNAL_WRITE_CHECK");
+ m_write_check = ( (write_check==0) || strcmp(write_check,"DISABLE") ) ?
+ true : false;
+
+
+ // FINISH INITIALIZATIONS:
+
+ reset_curr_proc();
+ m_next_proc_id = -1;
+ m_timed_events = new sc_ppq<sc_event_timed*>( 128, sc_notify_time_compare );
+ m_something_to_trace = false;
+ m_runnable = new sc_runnable;
+ m_collectable = new sc_process_list;
+ m_time_params = new sc_time_params;
+ m_curr_time = SC_ZERO_TIME;
+ m_max_time = SC_ZERO_TIME;
+ m_change_stamp = 0;
+ m_delta_count = 0;
+ m_forced_stop = false;
+ m_paused = false;
+ m_ready_to_simulate = false;
+ m_elaboration_done = false;
+ m_execution_phase = phase_initialize;
+ m_error = NULL;
+ m_cor_pkg = 0;
+ m_method_invoker_p = NULL;
+ m_cor = 0;
+ m_in_simulator_control = false;
+ m_start_of_simulation_called = false;
+ m_end_of_simulation_called = false;
+ m_simulation_status = SC_ELABORATION;
+}
+
+void
+sc_simcontext::clean()
+{
+ delete m_object_manager;
+ delete m_module_registry;
+ delete m_port_registry;
+ delete m_export_registry;
+ delete m_prim_channel_registry;
+ delete m_phase_cb_registry;
+ delete m_name_gen;
+ delete m_process_table;
+ m_child_objects.resize(0);
+ m_delta_events.resize(0);
+ delete m_timed_events;
+ for( int i = m_trace_files.size() - 1; i >= 0; -- i ) {
+ delete m_trace_files[i];
+ }
+ m_trace_files.resize(0);
+ delete m_runnable;
+ delete m_collectable;
+ delete m_time_params;
+ delete m_cor_pkg;
+ delete m_error;
+}
+
+
+sc_simcontext::sc_simcontext() :
+ m_object_manager(0), m_module_registry(0), m_port_registry(0),
+ m_export_registry(0), m_prim_channel_registry(0),
+ m_phase_cb_registry(0), m_name_gen(0),
+ m_process_table(0), m_curr_proc_info(), m_current_writer(0),
+ m_write_check(false), m_next_proc_id(-1), m_child_events(),
+ m_child_objects(), m_delta_events(), m_timed_events(0), m_trace_files(),
+ m_something_to_trace(false), m_runnable(0), m_collectable(0),
+ m_time_params(), m_curr_time(SC_ZERO_TIME), m_max_time(SC_ZERO_TIME),
+ m_change_stamp(0), m_delta_count(0), m_forced_stop(false), m_paused(false),
+ m_ready_to_simulate(false), m_elaboration_done(false),
+ m_execution_phase(phase_initialize), m_error(0),
+ m_in_simulator_control(false), m_end_of_simulation_called(false),
+ m_simulation_status(SC_ELABORATION), m_start_of_simulation_called(false),
+ m_cor_pkg(0), m_cor(0)
+{
+ init();
+}
+
+sc_simcontext::~sc_simcontext()
+{
+ clean();
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_simcontext::active_object"
+// |
+// | This method returns the currently active object with respect to
+// | additions to the hierarchy. It will be the top of the object hierarchy
+// | stack if it is non-empty, or it will be the active process, or NULL
+// | if there is no active process.
+// +----------------------------------------------------------------------------
+sc_object*
+sc_simcontext::active_object()
+{
+ sc_object* result_p; // pointer to return.
+
+ result_p = m_object_manager->hierarchy_curr();
+ if ( !result_p )
+ result_p = (sc_object*)get_curr_proc_info()->process_handle;
+ return result_p;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_simcontext::crunch"
+// |
+// | This method implements the simulator's execution of processes. It performs
+// | one or more "delta" cycles. Each delta cycle consists of an evaluation,
+// | an update phase, and a notification phase. During the evaluation phase any
+// | processes that are ready to run are executed. After all the processes have
+// | been executed the update phase is entered. During the update phase the
+// | values of any signals that have changed are updated. After the updates
+// | have been performed the notification phase is entered. During that phase
+// | any notifications that need to occur because of of signal values changes
+// | are performed. This will result in the queueing of processes for execution
+// | that are sensitive to those notifications. At that point a delta cycle
+// | is complete, and the process is started again unless 'once' is true.
+// |
+// | Arguments:
+// | once = true if only one delta cycle is to be performed.
+// +----------------------------------------------------------------------------
+inline void
+sc_simcontext::crunch( bool once )
+{
+#ifdef DEBUG_SYSTEMC
+ int num_deltas = 0; // number of delta cycles
+#endif
+
+ while ( true )
+ {
+
+ // EVALUATE PHASE
+
+ m_execution_phase = phase_evaluate;
+ bool empty_eval_phase = true;
+ while( true )
+ {
+
+ // execute method processes
+
+ m_runnable->toggle_methods();
+ sc_method_handle method_h = pop_runnable_method();
+ while( method_h != 0 ) {
+ empty_eval_phase = false;
+ if ( !method_h->run_process() )
+ {
+ goto out;
+ }
+ method_h = pop_runnable_method();
+ }
+
+ // execute (c)thread processes
+
+ m_runnable->toggle_threads();
+ sc_thread_handle thread_h = pop_runnable_thread();
+ while( thread_h != 0 ) {
+ if ( thread_h->m_cor_p != NULL ) break;
+ thread_h = pop_runnable_thread();
+ }
+
+ if( thread_h != 0 ) {
+ empty_eval_phase = false;
+ m_cor_pkg->yield( thread_h->m_cor_p );
+ }
+ if( m_error ) {
+ goto out;
+ }
+
+ // check for call(s) to sc_stop
+ if( m_forced_stop ) {
+ if ( stop_mode == SC_STOP_IMMEDIATE ) goto out;
+ }
+
+ // no more runnable processes
+
+ if( m_runnable->is_empty() ) {
+ break;
+ }
+ }
+
+ // remove finally dead zombies:
+
+ while( ! m_collectable->empty() )
+ {
+ sc_process_b* del_p = m_collectable->front();
+ m_collectable->pop_front();
+ del_p->reference_decrement();
+ }
+
+
+ // UPDATE PHASE
+ //
+ // The change stamp must be updated first so that event_occurred()
+ // will work.
+
+ m_execution_phase = phase_update;
+ if ( !empty_eval_phase )
+ {
+// SC_DO_PHASE_CALLBACK_(evaluation_done);
+ m_change_stamp++;
+ m_delta_count ++;
+ }
+ m_prim_channel_registry->perform_update();
+ SC_DO_PHASE_CALLBACK_(update_done);
+ m_execution_phase = phase_notify;
+
+#if SC_SIMCONTEXT_TRACING_
+ if( m_something_to_trace ) {
+ trace_cycle( /* delta cycle? */ true );
+ }
+#endif
+
+ // check for call(s) to sc_stop
+ if( m_forced_stop ) {
+ break;
+ }
+
+#ifdef DEBUG_SYSTEMC
+ // check for possible infinite loops
+ if( ++ num_deltas > SC_MAX_NUM_DELTA_CYCLES ) {
+ ::std::cerr << "SystemC warning: "
+ << "the number of delta cycles exceeds the limit of "
+ << SC_MAX_NUM_DELTA_CYCLES
+ << ", defined in sc_constants.h.\n"
+ << "This is a possible sign of an infinite loop.\n"
+ << "Increase the limit if this warning is invalid.\n";
+ break;
+ }
+#endif
+
+ // NOTIFICATION PHASE:
+ //
+ // Process delta notifications which will queue processes for
+ // subsequent execution.
+
+ int size = m_delta_events.size();
+ if ( size != 0 )
+ {
+ sc_event** l_events = &m_delta_events[0];
+ int i = size - 1;
+ do {
+ l_events[i]->trigger();
+ } while( -- i >= 0 );
+ m_delta_events.resize(0);
+ }
+
+ if( m_runnable->is_empty() ) {
+ // no more runnable processes
+ break;
+ }
+
+ // if sc_pause() was called we are done.
+
+ if ( m_paused ) break;
+
+ // IF ONLY DOING ONE CYCLE, WE ARE DONE. OTHERWISE EXECUTE NEW CALLBACKS
+
+ if ( once ) break;
+ }
+
+ // When this point is reached the processing of delta cycles is complete,
+ // if the completion was because of an error throw the exception specified
+ // by '*m_error'.
+out:
+ this->reset_curr_proc();
+ if( m_error ) throw *m_error; // re-throw propagated error
+}
+
+inline
+void
+sc_simcontext::cycle( const sc_time& t)
+{
+ sc_time next_event_time;
+
+ m_in_simulator_control = true;
+ crunch();
+ SC_DO_PHASE_CALLBACK_(before_timestep);
+#if SC_SIMCONTEXT_TRACING_
+ if( m_something_to_trace ) {
+ trace_cycle( /* delta cycle? */ false );
+ }
+#endif
+ m_curr_time += t;
+ if ( next_time(next_event_time) && next_event_time <= m_curr_time) {
+ SC_REPORT_WARNING(SC_ID_CYCLE_MISSES_EVENTS_, "");
+ }
+ m_in_simulator_control = false;
+ SC_DO_PHASE_CALLBACK_(simulation_paused);
+}
+
+void
+sc_simcontext::elaborate()
+{
+ if( m_elaboration_done || sim_status() != SC_SIM_OK ) {
+ return;
+ }
+
+ // Instantiate the method invocation module
+ // (not added to public object hierarchy)
+
+ m_method_invoker_p =
+ new sc_invoke_method("$$$$kernel_module$$$$_invoke_method" );
+
+ m_simulation_status = SC_BEFORE_END_OF_ELABORATION;
+ for( int cd = 0; cd != 4; /* empty */ )
+ {
+ cd = m_port_registry->construction_done();
+ cd += m_export_registry->construction_done();
+ cd += m_prim_channel_registry->construction_done();
+ cd += m_module_registry->construction_done();
+
+ // check for call(s) to sc_stop
+ if( m_forced_stop ) {
+ do_sc_stop_action();
+ return;
+ }
+
+ }
+ SC_DO_PHASE_CALLBACK_(construction_done);
+
+ // SIGNAL THAT ELABORATION IS DONE
+ //
+ // We set the switch before the calls in case someone creates a process
+ // in an end_of_elaboration callback. We need the information to flag
+ // the process as being dynamic.
+
+ m_elaboration_done = true;
+ m_simulation_status = SC_END_OF_ELABORATION;
+
+ m_port_registry->elaboration_done();
+ m_export_registry->elaboration_done();
+ m_prim_channel_registry->elaboration_done();
+ m_module_registry->elaboration_done();
+ SC_DO_PHASE_CALLBACK_(elaboration_done);
+ sc_reset::reconcile_resets();
+
+ // check for call(s) to sc_stop
+ if( m_forced_stop ) {
+ do_sc_stop_action();
+ return;
+ }
+}
+
+void
+sc_simcontext::prepare_to_simulate()
+{
+ sc_method_handle method_p; // Pointer to method process accessing.
+ sc_thread_handle thread_p; // Pointer to thread process accessing.
+
+ if( m_ready_to_simulate || sim_status() != SC_SIM_OK ) {
+ return;
+ }
+
+ // instantiate the coroutine package
+ m_cor_pkg = new sc_cor_pkg_t( this );
+ m_cor = m_cor_pkg->get_main();
+
+ // NOTIFY ALL OBJECTS THAT SIMULATION IS ABOUT TO START:
+
+ m_simulation_status = SC_START_OF_SIMULATION;
+ m_port_registry->start_simulation();
+ m_export_registry->start_simulation();
+ m_prim_channel_registry->start_simulation();
+ m_module_registry->start_simulation();
+ SC_DO_PHASE_CALLBACK_(start_simulation);
+ m_start_of_simulation_called = true;
+
+ // CHECK FOR CALL(S) TO sc_stop
+
+ if( m_forced_stop ) {
+ do_sc_stop_action();
+ return;
+ }
+
+ // PREPARE ALL (C)THREAD PROCESSES FOR SIMULATION:
+
+ for ( thread_p = m_process_table->thread_q_head();
+ thread_p; thread_p = thread_p->next_exist() )
+ {
+ thread_p->prepare_for_simulation();
+ }
+
+ m_simulation_status = SC_RUNNING;
+ m_ready_to_simulate = true;
+ m_runnable->init();
+
+ // update phase
+
+ m_execution_phase = phase_update;
+ m_prim_channel_registry->perform_update();
+ m_execution_phase = phase_notify;
+
+ int size;
+
+ // make all method processes runnable
+
+ for ( method_p = m_process_table->method_q_head();
+ method_p; method_p = method_p->next_exist() )
+ {
+ if ( ((method_p->m_state & sc_process_b::ps_bit_disabled) != 0) ||
+ method_p->dont_initialize() )
+ {
+ if ( method_p->m_static_events.size() == 0 )
+ {
+ SC_REPORT_WARNING( SC_ID_DISABLE_WILL_ORPHAN_PROCESS_,
+ method_p->name() );
+ }
+ }
+ else if ( (method_p->m_state & sc_process_b::ps_bit_suspended) == 0)
+ {
+ push_runnable_method_front( method_p );
+ }
+ else
+ {
+ method_p->m_state |= sc_process_b::ps_bit_ready_to_run;
+ }
+ }
+
+ // make thread processes runnable
+ // (cthread processes always have the dont_initialize flag set)
+
+ for ( thread_p = m_process_table->thread_q_head();
+ thread_p; thread_p = thread_p->next_exist() )
+ {
+ if ( ((thread_p->m_state & sc_process_b::ps_bit_disabled) != 0) ||
+ thread_p->dont_initialize() )
+ {
+ if ( thread_p->m_static_events.size() == 0 )
+ {
+ SC_REPORT_WARNING( SC_ID_DISABLE_WILL_ORPHAN_PROCESS_,
+ thread_p->name() );
+ }
+ }
+ else if ( (thread_p->m_state & sc_process_b::ps_bit_suspended) == 0)
+ {
+ push_runnable_thread_front( thread_p );
+ }
+ else
+ {
+ thread_p->m_state |= sc_process_b::ps_bit_ready_to_run;
+ }
+ }
+
+
+ // process delta notifications
+
+ if( ( size = m_delta_events.size() ) != 0 ) {
+ sc_event** l_delta_events = &m_delta_events[0];
+ int i = size - 1;
+ do {
+ l_delta_events[i]->trigger();
+ } while( -- i >= 0 );
+ m_delta_events.resize(0);
+ }
+
+ SC_DO_PHASE_CALLBACK_(initialization_done);
+}
+
+void
+sc_simcontext::initial_crunch( bool no_crunch )
+{
+ if( no_crunch || m_runnable->is_empty() ) {
+ return;
+ }
+
+ // run the delta cycle loop
+
+ crunch();
+ if( m_error ) {
+ return;
+ }
+
+#if SC_SIMCONTEXT_TRACING_
+ if( m_something_to_trace ) {
+ trace_cycle( false );
+ }
+#endif
+
+ // check for call(s) to sc_stop
+ if( m_forced_stop ) {
+ do_sc_stop_action();
+ }
+}
+
+void
+sc_simcontext::initialize( bool no_crunch )
+{
+ m_in_simulator_control = true;
+ elaborate();
+
+ prepare_to_simulate();
+ initial_crunch(no_crunch);
+ m_in_simulator_control = false;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_simcontext::simulate"
+// |
+// | This method runs the simulation for the specified amount of time.
+// |
+// | Notes:
+// | (1) This code always run with an SC_EXIT_ON_STARVATION starvation policy,
+// | so the simulation time on return will be the minimum of the
+// | simulation on entry plus the duration, and the maximum time of any
+// | event present in the simulation. If the simulation policy is
+// | SC_RUN_TO_TIME starvation it is implemented by the caller of this
+// | method, e.g., sc_start(), by artificially setting the simulation
+// | time forward after this method completes.
+// |
+// | Arguments:
+// | duration = amount of time to simulate.
+// +----------------------------------------------------------------------------
+void
+sc_simcontext::simulate( const sc_time& duration )
+{
+ initialize( true );
+
+ if (sim_status() != SC_SIM_OK) {
+ return;
+ }
+
+ sc_time non_overflow_time = sc_max_time() - m_curr_time;
+ if ( duration > non_overflow_time )
+ {
+ SC_REPORT_ERROR(SC_ID_SIMULATION_TIME_OVERFLOW_, "");
+ return;
+ }
+ else if ( duration < SC_ZERO_TIME )
+ {
+ SC_REPORT_ERROR(SC_ID_NEGATIVE_SIMULATION_TIME_,"");
+ }
+
+ m_in_simulator_control = true;
+ m_paused = false;
+
+ sc_time until_t = m_curr_time + duration;
+ sc_time t; // current simulaton time.
+
+ // IF DURATION WAS ZERO WE ONLY CRUNCH ONCE:
+ //
+ // We duplicate the code so that we don't add the overhead of the
+ // check to each loop in the do below.
+ if ( duration == SC_ZERO_TIME )
+ {
+ m_in_simulator_control = true;
+ crunch( true );
+ if( m_error ) {
+ m_in_simulator_control = false;
+ return;
+ }
+#if SC_SIMCONTEXT_TRACING_
+ if( m_something_to_trace )
+ trace_cycle( /* delta cycle? */ false );
+#endif
+ if( m_forced_stop ) {
+ do_sc_stop_action();
+ return;
+ }
+ // return via implicit pause
+ goto exit_pause;
+ }
+
+ // NON-ZERO DURATION: EXECUTE UP TO THAT TIME, OR UNTIL EVENT STARVATION:
+
+ do {
+
+ crunch();
+ if( m_error ) {
+ m_in_simulator_control = false;
+ return;
+ }
+#if SC_SIMCONTEXT_TRACING_
+ if( m_something_to_trace ) {
+ trace_cycle( false );
+ }
+#endif
+ // check for call(s) to sc_stop() or sc_pause().
+ if( m_forced_stop ) {
+ do_sc_stop_action();
+ return;
+ }
+ if( m_paused ) goto exit_pause; // return explicit pause
+
+ t = m_curr_time;
+
+ do {
+ // See note 1 above:
+
+ if ( !next_time(t) || (t > until_t ) ) goto exit_time;
+ if ( t > m_curr_time )
+ {
+ SC_DO_PHASE_CALLBACK_(before_timestep);
+ m_curr_time = t;
+ m_change_stamp++;
+ }
+
+ // PROCESS TIMED NOTIFICATIONS AT THE CURRENT TIME
+
+ do {
+ sc_event_timed* et = m_timed_events->extract_top();
+ sc_event* e = et->event();
+ delete et;
+ if( e != 0 ) {
+ e->trigger();
+ }
+ } while( m_timed_events->size() &&
+ m_timed_events->top()->notify_time() == t );
+
+ } while( m_runnable->is_empty() );
+ } while ( t < until_t ); // hold off on the delta for the until_t time.
+
+exit_time: // final simulation time update, if needed
+ if ( t > m_curr_time && t <= until_t )
+ {
+ SC_DO_PHASE_CALLBACK_(before_timestep);
+ m_curr_time = t;
+ m_change_stamp++;
+ }
+exit_pause: // call pause callback upon implicit or explicit pause
+ m_execution_phase = phase_evaluate;
+ m_in_simulator_control = false;
+ SC_DO_PHASE_CALLBACK_(simulation_paused);
+}
+
+void
+sc_simcontext::do_sc_stop_action()
+{
+ SC_REPORT_INFO("/OSCI/SystemC","Simulation stopped by user.");
+ if (m_start_of_simulation_called) {
+ end();
+ m_in_simulator_control = false;
+ }
+ m_simulation_status = SC_STOPPED;
+ SC_DO_PHASE_CALLBACK_(simulation_stopped);
+}
+
+void
+sc_simcontext::mark_to_collect_process( sc_process_b* zombie )
+{
+ m_collectable->push_back( zombie );
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_simcontext::stop"
+//
+// This method stops the simulator after some amount of further processing.
+// How much processing is done depends upon the value of the global variable
+// stop_mode:
+// SC_STOP_IMMEDIATE - aborts the execution phase of the current delta
+// cycle and performs whatever updates are pending.
+// SC_STOP_FINISH_DELTA - finishes the current delta cycle - both execution
+// and updates.
+// If sc_stop is called outside of the purview of the simulator kernel
+// (e.g., directly from sc_main), the end of simulation notifications
+// are performed. From within the purview of the simulator kernel, these
+// will be performed at a later time.
+//------------------------------------------------------------------------------
+
+void
+sc_simcontext::stop()
+{
+ static bool stop_warning_issued = false;
+ if (m_forced_stop)
+ {
+ if ( !stop_warning_issued )
+ {
+ stop_warning_issued = true; // This must be before the WARNING!!!
+ SC_REPORT_WARNING(SC_ID_SIMULATION_STOP_CALLED_TWICE_, "");
+ }
+ return;
+ }
+ if ( stop_mode == SC_STOP_IMMEDIATE ) m_runnable->init();
+ m_forced_stop = true;
+ if ( !m_in_simulator_control )
+ {
+ do_sc_stop_action();
+ }
+}
+
+void
+sc_simcontext::reset()
+{
+ clean();
+ init();
+}
+
+void
+sc_simcontext::end()
+{
+ m_simulation_status = SC_END_OF_SIMULATION;
+ m_ready_to_simulate = false;
+ m_port_registry->simulation_done();
+ m_export_registry->simulation_done();
+ m_prim_channel_registry->simulation_done();
+ m_module_registry->simulation_done();
+ SC_DO_PHASE_CALLBACK_(simulation_done);
+ m_end_of_simulation_called = true;
+}
+
+void
+sc_simcontext::hierarchy_push( sc_module* mod )
+{
+ m_object_manager->hierarchy_push( mod );
+}
+
+sc_module*
+sc_simcontext::hierarchy_pop()
+{
+ return static_cast<sc_module*>( m_object_manager->hierarchy_pop() );
+}
+
+sc_module*
+sc_simcontext::hierarchy_curr() const
+{
+ return static_cast<sc_module*>( m_object_manager->hierarchy_curr() );
+}
+
+sc_object*
+sc_simcontext::first_object()
+{
+ return m_object_manager->first_object();
+}
+
+sc_object*
+sc_simcontext::next_object()
+{
+ return m_object_manager->next_object();
+}
+
+sc_object*
+sc_simcontext::find_object( const char* name )
+{
+ static bool warn_find_object=true;
+ if ( warn_find_object )
+ {
+ warn_find_object = false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "sc_simcontext::find_object() is deprecated,\n" \
+ " use sc_find_object()" );
+ }
+ return m_object_manager->find_object( name );
+}
+
+// to generate unique names for objects in an MT-Safe way
+
+const char*
+sc_simcontext::gen_unique_name( const char* basename_, bool preserve_first )
+{
+ return m_name_gen->gen_unique_name( basename_, preserve_first );
+}
+
+
+sc_process_handle
+sc_simcontext::create_cthread_process(
+ const char* name_p, bool free_host, SC_ENTRY_FUNC method_p,
+ sc_process_host* host_p, const sc_spawn_options* opt_p )
+{
+ sc_thread_handle handle =
+ new sc_cthread_process(name_p, free_host, method_p, host_p, opt_p);
+ if ( m_ready_to_simulate )
+ {
+ handle->prepare_for_simulation();
+ } else {
+ m_process_table->push_front( handle );
+ }
+ return sc_process_handle(handle);
+}
+
+
+sc_process_handle
+sc_simcontext::create_method_process(
+ const char* name_p, bool free_host, SC_ENTRY_FUNC method_p,
+ sc_process_host* host_p, const sc_spawn_options* opt_p )
+{
+ sc_method_handle handle =
+ new sc_method_process(name_p, free_host, method_p, host_p, opt_p);
+ if ( m_ready_to_simulate ) { // dynamic process
+ if ( !handle->dont_initialize() )
+ {
+#ifdef SC_HAS_PHASE_CALLBACKS_
+ if( SC_UNLIKELY_( m_simulation_status
+ & (SC_END_OF_UPDATE|SC_BEFORE_TIMESTEP) ) )
+ {
+ std::stringstream msg;
+ msg << m_simulation_status
+ << ":\n\t immediate method spawning of "
+ "`" << handle->name() << "' ignored";
+ SC_REPORT_WARNING( SC_ID_PHASE_CALLBACK_FORBIDDEN_
+ , msg.str().c_str() );
+ }
+ else
+#endif // SC_HAS_PHASE_CALLBACKS_
+ {
+ push_runnable_method( handle );
+ }
+ }
+ else if ( handle->m_static_events.size() == 0 )
+ {
+ SC_REPORT_WARNING( SC_ID_DISABLE_WILL_ORPHAN_PROCESS_,
+ handle->name() );
+ }
+
+ } else {
+ m_process_table->push_front( handle );
+ }
+ return sc_process_handle(handle);
+}
+
+
+sc_process_handle
+sc_simcontext::create_thread_process(
+ const char* name_p, bool free_host, SC_ENTRY_FUNC method_p,
+ sc_process_host* host_p, const sc_spawn_options* opt_p )
+{
+ sc_thread_handle handle =
+ new sc_thread_process(name_p, free_host, method_p, host_p, opt_p);
+ if ( m_ready_to_simulate ) { // dynamic process
+ handle->prepare_for_simulation();
+ if ( !handle->dont_initialize() )
+ {
+#ifdef SC_HAS_PHASE_CALLBACKS_
+ if( SC_UNLIKELY_( m_simulation_status
+ & (SC_END_OF_UPDATE|SC_BEFORE_TIMESTEP) ) )
+ {
+ std::stringstream msg;
+ msg << m_simulation_status
+ << ":\n\t immediate thread spawning of "
+ "`" << handle->name() << "' ignored";
+ SC_REPORT_WARNING( SC_ID_PHASE_CALLBACK_FORBIDDEN_
+ , msg.str().c_str() );
+ }
+ else
+#endif // SC_HAS_PHASE_CALLBACKS_
+ {
+ push_runnable_thread( handle );
+ }
+ }
+ else if ( handle->m_static_events.size() == 0 )
+ {
+ SC_REPORT_WARNING( SC_ID_DISABLE_WILL_ORPHAN_PROCESS_,
+ handle->name() );
+ }
+
+ } else {
+ m_process_table->push_front( handle );
+ }
+ return sc_process_handle(handle);
+}
+
+void
+sc_simcontext::add_trace_file( sc_trace_file* tf )
+{
+ m_trace_files.push_back( tf );
+ m_something_to_trace = true;
+}
+
+void
+sc_simcontext::remove_trace_file( sc_trace_file* tf )
+{
+ m_trace_files.erase(
+ std::remove( m_trace_files.begin(), m_trace_files.end(), tf )
+ );
+ m_something_to_trace = ( m_trace_files.size() > 0 );
+}
+
+sc_cor*
+sc_simcontext::next_cor()
+{
+ if( m_error ) {
+ return m_cor;
+ }
+
+ sc_thread_handle thread_h = pop_runnable_thread();
+ while( thread_h != 0 ) {
+ if ( thread_h->m_cor_p != NULL ) break;
+ thread_h = pop_runnable_thread();
+ }
+
+ if( thread_h != 0 ) {
+ return thread_h->m_cor_p;
+ } else {
+ return m_cor;
+ }
+}
+
+const ::std::vector<sc_object*>&
+sc_simcontext::get_child_objects() const
+{
+ static bool warn_get_child_objects=true;
+ if ( warn_get_child_objects )
+ {
+ warn_get_child_objects = false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "sc_simcontext::get_child_objects() is deprecated,\n" \
+ " use sc_get_top_level_objects()" );
+ }
+ return m_child_objects;
+}
+
+void
+sc_simcontext::add_child_event( sc_event* event_ )
+{
+ // no check if object_ is already in the set
+ m_child_events.push_back( event_ );
+}
+
+void
+sc_simcontext::add_child_object( sc_object* object_ )
+{
+ // no check if object_ is already in the set
+ m_child_objects.push_back( object_ );
+}
+
+void
+sc_simcontext::remove_child_event( sc_event* event_ )
+{
+ int size = m_child_events.size();
+ for( int i = 0; i < size; ++ i ) {
+ if( event_ == m_child_events[i] ) {
+ m_child_events[i] = m_child_events[size - 1];
+ m_child_events.resize(size-1);
+ return;
+ }
+ }
+ // no check if event_ is really in the set
+}
+
+void
+sc_simcontext::remove_child_object( sc_object* object_ )
+{
+ int size = m_child_objects.size();
+ for( int i = 0; i < size; ++ i ) {
+ if( object_ == m_child_objects[i] ) {
+ m_child_objects[i] = m_child_objects[size - 1];
+ m_child_objects.resize(size-1);
+ return;
+ }
+ }
+ // no check if object_ is really in the set
+}
+
+sc_dt::uint64
+sc_simcontext::delta_count() const
+{
+ static bool warn_delta_count=true;
+ if ( warn_delta_count )
+ {
+ warn_delta_count = false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "sc_simcontext::delta_count() is deprecated, use sc_delta_count()" );
+ }
+ return m_delta_count;
+}
+
+bool
+sc_simcontext::is_running() const
+{
+ static bool warn_is_running=true;
+ if ( warn_is_running )
+ {
+ warn_is_running = false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "sc_simcontext::is_running() is deprecated, use sc_is_running()" );
+ }
+ return m_ready_to_simulate;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_simcontext::next_time"
+// |
+// | This method returns the time of the next event. If there are no events
+// | it returns false.
+// |
+// | Arguments:
+// | result = where to place time of the next event, if no event is
+// | found this value will not be changed.
+// | Result is true if an event is found, false if not.
+// +----------------------------------------------------------------------------
+bool
+sc_simcontext::next_time( sc_time& result ) const
+{
+ while( m_timed_events->size() ) {
+ sc_event_timed* et = m_timed_events->top();
+ if( et->event() != 0 ) {
+ result = et->notify_time();
+ return true;
+ }
+ delete m_timed_events->extract_top();
+ }
+ return false;
+}
+
+void
+sc_simcontext::remove_delta_event( sc_event* e )
+{
+ int i = e->m_delta_event_index;
+ int j = m_delta_events.size() - 1;
+ assert( i >= 0 && i <= j );
+ if( i != j ) {
+ sc_event** l_delta_events = &m_delta_events[0];
+ l_delta_events[i] = l_delta_events[j];
+ l_delta_events[i]->m_delta_event_index = i;
+ }
+ m_delta_events.resize(m_delta_events.size()-1);
+ e->m_delta_event_index = -1;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_simcontext::preempt_with"
+// |
+// | This method executes the supplied method immediately, suspending the
+// | caller. After executing the supplied method the caller's execution will
+// | be restored. It is used to allow a method to immediately throw an
+// | exception, e.g., when the method's kill_process() method was called.
+// | There are three cases to consider:
+// | (1) The caller is a method, e.g., murder by method.
+// | (2) The caller is a thread instance, e.g., murder by thread.
+// | (3) The caller is this method instance, e.g., suicide.
+// |
+// | Arguments:
+// | method_h -> method to be executed.
+// +----------------------------------------------------------------------------
+void
+sc_simcontext::preempt_with( sc_method_handle method_h )
+{
+ sc_curr_proc_info caller_info; // process info for caller.
+ sc_method_handle active_method_h; // active method or null.
+ sc_thread_handle active_thread_h; // active thread or null.
+
+ // Determine the active process and take the thread to be run off the
+ // run queue, if its there, since we will be explicitly causing its
+ // execution.
+
+ active_method_h = DCAST<sc_method_handle>(sc_get_current_process_b());
+ active_thread_h = DCAST<sc_thread_handle>(sc_get_current_process_b());
+ if ( method_h->next_runnable() != NULL )
+ remove_runnable_method( method_h );
+
+ // CALLER IS THE METHOD TO BE RUN:
+ //
+ // Should never get here, ignore it unless we are debugging.
+
+ if ( method_h == active_method_h )
+ {
+ DEBUG_MSG(DEBUG_NAME,method_h,"self preemption of active method");
+ }
+
+ // THE CALLER IS A METHOD:
+ //
+ // (a) Set the current process information to our method.
+ // (b) Invoke our method directly by-passing the run queue.
+ // (c) Restore the process info to the caller.
+ // (d) Check to see if the calling method should throw an exception
+ // because of activity that occurred during the preemption.
+
+ else if ( active_method_h != NULL )
+ {
+ caller_info = m_curr_proc_info;
+ DEBUG_MSG( DEBUG_NAME, method_h,
+ "preempting active method with method" );
+ sc_get_curr_simcontext()->set_curr_proc( (sc_process_b*)method_h );
+ method_h->run_process();
+ sc_get_curr_simcontext()->set_curr_proc((sc_process_b*)active_method_h);
+ active_method_h->check_for_throws();
+ }
+
+ // CALLER IS A THREAD:
+ //
+ // (a) Use an invocation thread to execute the method.
+
+ else if ( active_thread_h != NULL )
+ {
+ DEBUG_MSG( DEBUG_NAME, method_h,
+ "preempting active thread with method" );
+ m_method_invoker_p->invoke_method(method_h);
+ }
+
+ // CALLER IS THE SIMULATOR:
+ //
+ // That is not allowed.
+
+ else
+ {
+ caller_info = m_curr_proc_info;
+ DEBUG_MSG( DEBUG_NAME, method_h,
+ "preempting no active process with method" );
+ sc_get_curr_simcontext()->set_curr_proc( (sc_process_b*)method_h );
+ method_h->run_process();
+ m_curr_proc_info = caller_info;
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_simcontext::requeue_current_process"
+//
+// This method requeues the current process at the beginning of the run queue
+// if it is a thread. This is called by sc_process_handle::throw_it() to assure
+// that a thread that is issuing a throw will execute immediately after the
+// processes it notifies via the throw.
+//------------------------------------------------------------------------------
+void sc_simcontext::requeue_current_process()
+{
+ sc_thread_handle thread_p;
+ thread_p = DCAST<sc_thread_handle>(get_curr_proc_info()->process_handle);
+ if ( thread_p )
+ {
+ execute_thread_next( thread_p );
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_simcontext::suspend_current_process"
+//
+// This method suspends the current process if it is a thread. This is called
+// by sc_process_handle::throw_it() to allow the processes that have received
+// a throw to execute.
+//------------------------------------------------------------------------------
+void sc_simcontext::suspend_current_process()
+{
+ sc_thread_handle thread_p;
+ thread_p = DCAST<sc_thread_handle>(get_curr_proc_info()->process_handle);
+ if ( thread_p )
+ {
+ thread_p->suspend_me();
+ }
+}
+
+void
+sc_simcontext::trace_cycle( bool delta_cycle )
+{
+ int size;
+ if( ( size = m_trace_files.size() ) != 0 ) {
+ sc_trace_file** l_trace_files = &m_trace_files[0];
+ int i = size - 1;
+ do {
+ l_trace_files[i]->cycle( delta_cycle );
+ } while( -- i >= 0 );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+#if 1
+#ifdef PURIFY
+ static sc_simcontext sc_default_global_context;
+ sc_simcontext* sc_curr_simcontext = &sc_default_global_context;
+#else
+ sc_simcontext* sc_curr_simcontext = 0;
+ sc_simcontext* sc_default_global_context = 0;
+#endif
+#else
+// Not MT-safe!
+static sc_simcontext* sc_curr_simcontext = 0;
+
+
+sc_simcontext*
+sc_get_curr_simcontext()
+{
+ if( sc_curr_simcontext == 0 ) {
+#ifdef PURIFY
+ static sc_simcontext sc_default_global_context;
+ sc_curr_simcontext = &sc_default_global_context;
+#else
+ static sc_simcontext* sc_default_global_context = new sc_simcontext;
+ sc_curr_simcontext = sc_default_global_context;
+#endif
+ }
+ return sc_curr_simcontext;
+}
+#endif // 0
+
+// Generates unique names within each module.
+
+const char*
+sc_gen_unique_name( const char* basename_, bool preserve_first )
+{
+ sc_simcontext* simc = sc_get_curr_simcontext();
+ sc_module* curr_module = simc->hierarchy_curr();
+ if( curr_module != 0 ) {
+ return curr_module->gen_unique_name( basename_, preserve_first );
+ } else {
+ sc_process_b* curr_proc_p = sc_get_current_process_b();
+ if ( curr_proc_p )
+ {
+ return curr_proc_p->gen_unique_name( basename_, preserve_first );
+ }
+ else
+ {
+ return simc->gen_unique_name( basename_, preserve_first );
+ }
+ }
+}
+
+// Get a handle for the current process
+//
+// Note that this method should not be called if the current process is
+// in the act of being deleted, it will mess up the reference count management
+// of sc_process_b instance the handle represents. Instead, use the a
+// pointer to the raw sc_process_b instance, which may be acquired via
+// sc_get_current_process_b().
+
+sc_process_handle
+sc_get_current_process_handle()
+{
+ return ( sc_is_running() ) ?
+ sc_process_handle(sc_get_current_process_b()) :
+ sc_get_last_created_process_handle();
+}
+
+// THE FOLLOWING FUNCTION IS DEPRECATED IN 2.1
+sc_process_b*
+sc_get_curr_process_handle()
+{
+ static bool warn=true;
+ if ( warn )
+ {
+ warn = false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "sc_get_curr_process_handle deprecated use sc_get_current_process_handle"
+ );
+ }
+
+ return sc_get_curr_simcontext()->get_curr_proc_info()->process_handle;
+}
+
+// Return indication if there are more processes to execute in this delta phase
+
+bool
+sc_simcontext::pending_activity_at_current_time() const
+{
+ return ( m_delta_events.size() != 0) ||
+ ( m_runnable->is_initialized() && !m_runnable->is_empty() ) ||
+ m_prim_channel_registry->pending_updates();
+}
+
+// Return time of next activity.
+
+sc_time sc_time_to_pending_activity( const sc_simcontext* simc_p )
+{
+ // If there is an activity pending at the current time
+ // return a delta of zero.
+
+ sc_time result=SC_ZERO_TIME; // time of pending activity.
+
+ if ( simc_p->pending_activity_at_current_time() )
+ {
+ return result;
+ }
+
+ // Any activity will take place in the future pick up the next event's time.
+
+ else
+ {
+ result = simc_p->max_time();
+ simc_p->next_time(result);
+ result -= sc_time_stamp();
+ }
+ return result;
+}
+
+// Set the random seed for controlled randomization -- not yet implemented
+
+void
+sc_set_random_seed( unsigned int )
+{
+ SC_REPORT_WARNING( SC_ID_NOT_IMPLEMENTED_,
+ "void sc_set_random_seed( unsigned int )" );
+}
+
+
+// +----------------------------------------------------------------------------
+// |"sc_start"
+// |
+// | This function starts, or restarts, the execution of the simulator.
+// |
+// | Arguments:
+// | duration = the amount of time the simulator should execute.
+// | p = event starvation policy.
+// +----------------------------------------------------------------------------
+void
+sc_start( const sc_time& duration, sc_starvation_policy p )
+{
+ sc_simcontext* context_p; // current simulation context.
+ sc_time entry_time; // simulation time upon entry.
+ sc_time exit_time; // simulation time to set upon exit.
+ sc_dt::uint64 starting_delta; // delta count upon entry.
+ int status; // current simulation status.
+
+ // Set up based on the arguments passed to us:
+
+ context_p = sc_get_curr_simcontext();
+ starting_delta = sc_delta_count();
+ entry_time = context_p->m_curr_time;
+ if ( p == SC_RUN_TO_TIME )
+ exit_time = context_p->m_curr_time + duration;
+
+ // called with duration = SC_ZERO_TIME for the first time
+ static bool init_delta_or_pending_updates =
+ ( starting_delta == 0 && exit_time == SC_ZERO_TIME );
+
+ // If the simulation status is bad issue the appropriate message:
+
+ status = context_p->sim_status();
+ if( status != SC_SIM_OK )
+ {
+ if ( status == SC_SIM_USER_STOP )
+ SC_REPORT_ERROR(SC_ID_SIMULATION_START_AFTER_STOP_, "");
+ if ( status == SC_SIM_ERROR )
+ SC_REPORT_ERROR(SC_ID_SIMULATION_START_AFTER_ERROR_, "");
+ return;
+ }
+
+ if ( context_p->m_prim_channel_registry->pending_updates() )
+ init_delta_or_pending_updates = true;
+
+ // If the simulation status is good perform the simulation:
+
+ context_p->simulate( duration );
+
+ // Re-check the status:
+
+ status = context_p->sim_status();
+
+ // Update the current time to the exit time if that is the starvation
+ // policy:
+
+ if ( p == SC_RUN_TO_TIME && !context_p->m_paused && status == SC_SIM_OK )
+ {
+ context_p->m_curr_time = exit_time;
+ }
+
+ // If there was no activity and the simulation clock did not move warn
+ // the user, except if we're in a first sc_start(SC_ZERO_TIME) for
+ // initialisation (only) or there have been pending updates:
+
+ if ( !init_delta_or_pending_updates &&
+ starting_delta == sc_delta_count() &&
+ context_p->m_curr_time == entry_time &&
+ status == SC_SIM_OK )
+ {
+ SC_REPORT_WARNING(SC_ID_NO_SC_START_ACTIVITY_, "");
+ }
+
+ // reset init/update flag for subsequent calls
+ init_delta_or_pending_updates = false;
+}
+
+void
+sc_start()
+{
+ sc_start( sc_max_time() - sc_time_stamp(),
+ SC_EXIT_ON_STARVATION );
+}
+
+// for backward compatibility with 1.0
+#if 0
+void
+sc_start( double duration ) // in default time units
+{
+ static bool warn_sc_start=true;
+ if ( warn_sc_start )
+ {
+ warn_sc_start = false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "sc_start(double) deprecated, use sc_start(sc_time) or sc_start()");
+ }
+
+ if( duration == -1 ) // simulate forever
+ {
+ sc_start(
+ sc_time(~sc_dt::UINT64_ZERO, false) - sc_time_stamp() );
+ }
+ else
+ {
+ sc_start( sc_time( duration, true ) );
+ }
+}
+#endif //
+
+void
+sc_stop()
+{
+ sc_get_curr_simcontext()->stop();
+}
+
+
+// The following function is deprecated in favor of sc_start(SC_ZERO_TIME):
+
+void
+sc_initialize()
+{
+ static bool warning_initialize = true;
+
+ if ( warning_initialize )
+ {
+ warning_initialize = false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "sc_initialize() is deprecated: use sc_start(SC_ZERO_TIME)" );
+ }
+ sc_get_curr_simcontext()->initialize();
+}
+
+// The following function has been deprecated in favor of sc_start(duration):
+
+void
+sc_cycle( const sc_time& duration )
+{
+ static bool warning_cycle = true;
+
+ if ( warning_cycle )
+ {
+ warning_cycle = false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "sc_cycle is deprecated: use sc_start(sc_time)" );
+ }
+ sc_get_curr_simcontext()->cycle( duration );
+}
+
+sc_event* sc_find_event( const char* name )
+{
+ return sc_get_curr_simcontext()->get_object_manager()->find_event( name );
+}
+
+sc_object* sc_find_object( const char* name )
+{
+ return sc_get_curr_simcontext()->get_object_manager()->find_object( name );
+}
+
+
+const sc_time&
+sc_max_time()
+{
+ return sc_get_curr_simcontext()->max_time();
+}
+
+const sc_time&
+sc_time_stamp()
+{
+ return sc_get_curr_simcontext()->time_stamp();
+}
+
+double
+sc_simulation_time()
+{
+ static bool warn_simulation_time=true;
+ if ( warn_simulation_time )
+ {
+ warn_simulation_time=false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "sc_simulation_time() is deprecated use sc_time_stamp()" );
+ }
+ return sc_get_curr_simcontext()->time_stamp().to_default_time_units();
+}
+
+void
+sc_defunct_process_function( sc_module* )
+{
+ // This function is pointed to by defunct sc_thread_process'es and
+ // sc_cthread_process'es. In a correctly constructed world, this
+ // function should never be called; hence the assert.
+ assert( false );
+}
+
+//------------------------------------------------------------------------------
+//"sc_set_stop_mode"
+//
+// This function sets the mode of operation when sc_stop() is called.
+// mode = SC_STOP_IMMEDIATE or SC_STOP_FINISH_DELTA.
+//------------------------------------------------------------------------------
+void sc_set_stop_mode(sc_stop_mode mode)
+{
+ if ( sc_is_running() )
+ {
+ SC_REPORT_ERROR(SC_ID_STOP_MODE_AFTER_START_,"");
+ }
+ else
+ {
+ switch( mode )
+ {
+ case SC_STOP_IMMEDIATE:
+ case SC_STOP_FINISH_DELTA:
+ stop_mode = mode;
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+sc_stop_mode
+sc_get_stop_mode()
+{
+ return stop_mode;
+}
+
+bool sc_is_unwinding()
+{
+ return sc_get_current_process_handle().is_unwinding();
+}
+
+// The IEEE 1666 Standard for 2011 designates that the treatment of
+// certain process control interactions as being "implementation dependent".
+// These interactions are:
+// (1) What happens when a resume() call is performed on a disabled,
+// suspended process.
+// (2) What happens when sync_reset_on() or sync_reset_off() is called
+// on a suspended process.
+// (3) What happens when the value specified in a reset_signal_is()
+// call changes value while a process is suspended.
+//
+// By default this Proof of Concept implementation reports an error
+// for these interactions. However, the implementation also provides
+// a non-error treatment. The non-error treatment for the interactions is:
+// (1) A resume() call performed on a disabled, suspended process will
+// mark the process as no longer suspended, and if it is capable
+// of execution (not waiting on any events) it will be placed on
+// the queue of runnable processes. See the state diagram below.
+// (2) A call to sync_reset_on() or sync_reset_off() will set or clear
+// the synchronous reset flag. Whether the process is in reset or
+// not will be determined when the process actually executes by
+// looking at the flag's value at that time.
+// (3) If a suspended process has a reset_signal_is() specification
+// the value of the reset variable at the time of its next execution
+// will determine whether it is in reset or not.
+//
+// TO GET THE NON-ERROR BEHAVIOR SET THE VARIABLE BELOW TO TRUE.
+//
+// This can be done in this source before you build the library, or you
+// can use an assignment as the first statement in your sc_main() function:
+// sc_core::sc_allow_process_control_corners = true;
+
+bool sc_allow_process_control_corners = false;
+
+// The state transition diagram for the interaction of disable and suspend
+// when sc_allow_process_control_corners is true is shown below:
+//
+// ......................................................................
+// . ENABLED . DISABLED .
+// . . .
+// . +----------+ disable +----------+ .
+// . +------------>| |-------.-------->| | .
+// . | | runnable | . | runnable | .
+// . | +-------| |<------.---------| |------+ .
+// . | | +----------+ enable +----------+ | .
+// . | | | ^ . | ^ | .
+// . | | suspend | | resume . suspend | | resume | .
+// . | | V | . V | | .
+// . | | +----------+ disable +----------+ | .
+// . | | | suspend |-------.-------->| suspend | | .
+// . t | r | | | . | | | r .
+// . r | u | | ready |<------.---------| ready | | u .
+// . i | n | +----------+ enable +----------+ | n .
+// . g | / | ^ . | / .
+// . g | w | trigger| . | w .
+// . e | a | | . | a .
+// . r | i | +----------+ disable +----------+ | i .
+// . | t | | suspend |-------.-------->| suspend | | t .
+// . | | | | . | | | .
+// . | | | waiting |<------.---------| waiting | | .
+// . | | +----------+ enable +----------+ | .
+// . | | | ^ . | ^ | .
+// . | | suspend | | resume . suspend | | resume | .
+// . | | V | . V | | .
+// . | | +----------+ disable +----------+ | .
+// . | +------>| |-------.-------->| | | .
+// . | | waiting | . | waiting | | .
+// . +-------------| |<------.---------| |<-----+ .
+// . +----------+ enable +----------+ .
+// . . .
+// ......................................................................
+
+// ----------------------------------------------------------------------------
+
+static std::ostream&
+print_status_expression( std::ostream& os, sc_status s );
+
+// utility helper to print a simulation status
+std::ostream& operator << ( std::ostream& os, sc_status s )
+{
+ // print primitive values
+ switch(s)
+ {
+# define PRINT_STATUS( Status ) \
+ case Status: { os << #Status; } break
+
+ PRINT_STATUS( SC_UNITIALIZED );
+ PRINT_STATUS( SC_ELABORATION );
+ PRINT_STATUS( SC_BEFORE_END_OF_ELABORATION );
+ PRINT_STATUS( SC_END_OF_ELABORATION );
+ PRINT_STATUS( SC_START_OF_SIMULATION );
+
+ PRINT_STATUS( SC_RUNNING );
+ PRINT_STATUS( SC_PAUSED );
+ PRINT_STATUS( SC_STOPPED );
+ PRINT_STATUS( SC_END_OF_SIMULATION );
+
+ PRINT_STATUS( SC_END_OF_INITIALIZATION );
+// PRINT_STATUS( SC_END_OF_EVALUATION );
+ PRINT_STATUS( SC_END_OF_UPDATE );
+ PRINT_STATUS( SC_BEFORE_TIMESTEP );
+
+ PRINT_STATUS( SC_STATUS_ANY );
+
+# undef PRINT_STATUS
+ default:
+
+ if( s & SC_STATUS_ANY ) // combination of status bits
+ print_status_expression( os, s );
+ else // invalid number, print hex value
+ os << "0x" << std::hex << +s;
+ }
+
+ return os;
+}
+
+// pretty-print a combination of sc_status bits (i.e. a callback mask)
+static std::ostream&
+print_status_expression( std::ostream& os, sc_status s )
+{
+ std::vector<sc_status> bits;
+ unsigned is_set = SC_ELABORATION;
+
+ // collect bits
+ while( is_set <= SC_STATUS_LAST )
+ {
+ if( s & is_set )
+ bits.push_back( (sc_status)is_set );
+ is_set <<= 1;
+ }
+ if( s & ~SC_STATUS_ANY ) // remaining bits
+ bits.push_back( (sc_status)( s & ~SC_STATUS_ANY ) );
+
+ // print expression
+ std::vector<sc_status>::size_type i=0, n=bits.size();
+ if ( n>1 )
+ os << "(";
+ for( ; i<n-1; ++i )
+ os << bits[i] << "|";
+ os << bits[i];
+ if ( n>1 )
+ os << ")";
+ return os;
+}
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc.
+ Description of Modification: - Added sc_stop() detection into initial_crunch
+ and crunch. This makes it possible to exit out
+ of a combinational loop using sc_stop().
+
+ Name, Affiliation, Date: Andy Goodrich, Forte Design Systems 20 May 2003
+ Description of Modification: - sc_stop mode
+ - phase callbacks
+
+ Name, Affiliation, Date: Bishnupriya Bhattacharya, Cadence Design Systems,
+ 25 August 2003
+ Description of Modification: - support for dynamic process
+ - support for sc export registry
+ - new member methods elaborate(),
+ prepare_to_simulate(), and initial_crunch()
+ that are invoked by initialize() in that order
+ - implement sc_get_last_created_process_handle() for use
+ before simulation starts
+ - remove "set_curr_proc(handle)" from
+ register_method_process and
+ register_thread_process - led to bugs
+
+ Name, Affiliation, Date: Andy Goodrich, Forte Design Systems 04 Sep 2003
+ Description of Modification: - changed process existence structures to
+ linked lists to eliminate exponential
+ execution problem with using sc_pvector.
+ *****************************************************************************/
+// $Log: sc_simcontext.cpp,v $
+// Revision 1.37 2011/08/29 18:04:32 acg
+// Philipp A. Hartmann: miscellaneous clean ups.
+//
+// Revision 1.36 2011/08/26 20:46:10 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.35 2011/08/24 22:05:51 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.34 2011/08/04 17:15:28 acg
+// Andy Goodrich: added documentation to crunch() routine.
+//
+// Revision 1.32 2011/07/24 11:16:36 acg
+// Philipp A. Hartmann: fix reference counting on deferred deletions of
+// processes.
+//
+// Revision 1.31 2011/07/01 18:49:07 acg
+// Andy Goodrich: moved pln() from sc_simcontext.cpp to sc_ver.cpp.
+//
+// Revision 1.30 2011/05/09 04:07:49 acg
+// Philipp A. Hartmann:
+// (1) Restore hierarchy in all phase callbacks.
+// (2) Ensure calls to before_end_of_elaboration.
+//
+// Revision 1.29 2011/04/08 22:39:09 acg
+// Andy Goodrich: moved method invocation code to sc_method.h so that the
+// details are hidden from sc_simcontext.
+//
+// Revision 1.28 2011/04/05 20:50:57 acg
+// Andy Goodrich:
+// (1) changes to make sure that event(), posedge() and negedge() only
+// return true if the clock has not moved.
+// (2) fixes for method self-resumes.
+// (3) added SC_PRERELEASE_VERSION
+// (4) removed kernel events from the object hierarchy, added
+// sc_hierarchy_name_exists().
+//
+// Revision 1.27 2011/04/05 06:14:15 acg
+// Andy Goodrich: fix typo.
+//
+// Revision 1.26 2011/04/05 06:03:32 acg
+// Philipp A. Hartmann: added code to set ready to run bit for a suspended
+// process that does not have dont_initialize specified at simulation
+// start up.
+//
+// Revision 1.25 2011/04/01 21:31:55 acg
+// Andy Goodrich: make sure processes suspended before the start of execution
+// don't get scheduled for initial execution.
+//
+// Revision 1.24 2011/03/28 13:02:52 acg
+// Andy Goodrich: Changes for disable() interactions.
+//
+// Revision 1.23 2011/03/12 21:07:51 acg
+// Andy Goodrich: changes to kernel generated event support.
+//
+// Revision 1.22 2011/03/07 17:38:43 acg
+// Andy Goodrich: tightening up of checks for undefined interaction between
+// synchronous reset and suspend.
+//
+// Revision 1.21 2011/03/06 19:57:11 acg
+// Andy Goodrich: refinements for the illegal suspend - synchronous reset
+// interaction.
+//
+// Revision 1.20 2011/03/06 15:58:50 acg
+// Andy Goodrich: added escape to turn off process control corner case
+// checks.
+//
+// Revision 1.19 2011/03/05 04:45:16 acg
+// Andy Goodrich: moved active process calculation to the sc_simcontext class.
+//
+// Revision 1.18 2011/03/05 01:39:21 acg
+// Andy Goodrich: changes for named events.
+//
+// Revision 1.17 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.16 2011/02/17 19:53:28 acg
+// Andy Goodrich: eliminated use of ready_to_run() as part of process control
+// simplification.
+//
+// Revision 1.15 2011/02/13 21:47:38 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.14 2011/02/11 13:25:24 acg
+// Andy Goodrich: Philipp A. Hartmann's changes:
+// (1) Removal of SC_CTHREAD method overloads.
+// (2) New exception processing code.
+//
+// Revision 1.13 2011/02/08 08:42:50 acg
+// Andy Goodrich: fix ordering of check for stopped versus paused.
+//
+// Revision 1.12 2011/02/07 19:17:20 acg
+// Andy Goodrich: changes for IEEE 1666 compatibility.
+//
+// Revision 1.11 2011/02/02 07:18:11 acg
+// Andy Goodrich: removed toggle() calls for the new crunch() toggle usage.
+//
+// Revision 1.10 2011/02/01 23:01:53 acg
+// Andy Goodrich: removed dead code.
+//
+// Revision 1.9 2011/02/01 21:11:59 acg
+// Andy Goodrich:
+// (1) Use of new toggle_methods() and toggle_threads() run queue methods
+// to make sure the thread run queue does not execute when allow preempt_me()
+// is called from an SC_METHOD.
+// (2) Use of execute_thread_next() to allow thread execution in the current
+// delta cycle() rather than push_runnable_thread_front which executed
+// in the following cycle.
+//
+// Revision 1.8 2011/01/25 20:50:37 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.7 2011/01/19 23:21:50 acg
+// Andy Goodrich: changes for IEEE 1666 2011
+//
+// Revision 1.6 2011/01/18 20:10:45 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.5 2010/11/20 17:10:57 acg
+// Andy Goodrich: reset processing changes for new IEEE 1666 standard.
+//
+// Revision 1.4 2010/07/22 20:02:33 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.3 2008/05/22 17:06:26 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.2 2007/09/20 20:32:35 acg
+// Andy Goodrich: changes to the semantics of throw_it() to match the
+// specification. A call to throw_it() will immediately suspend the calling
+// thread until all the throwees have executed. At that point the calling
+// thread will be restarted before the execution of any other threads.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.21 2006/08/29 23:37:13 acg
+// Andy Goodrich: Added check for negative time.
+//
+// Revision 1.20 2006/05/26 20:33:16 acg
+// Andy Goodrich: changes required by additional platform compilers (i.e.,
+// Microsoft VC++, Sun Forte, HP aCC).
+//
+// Revision 1.19 2006/05/08 17:59:52 acg
+// Andy Goodrich: added a check before m_curr_time is set to make sure it
+// is not set to a time before its current value. This will treat
+// sc_event.notify( ) calls with negative times as calls with a zero time.
+//
+// Revision 1.18 2006/04/20 17:08:17 acg
+// Andy Goodrich: 3.0 style process changes.
+//
+// Revision 1.17 2006/04/11 23:13:21 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.16 2006/03/21 00:00:34 acg
+// Andy Goodrich: changed name of sc_get_current_process_base() to be
+// sc_get_current_process_b() since its returning an sc_process_b instance.
+//
+// Revision 1.15 2006/03/13 20:26:50 acg
+// Andy Goodrich: Addition of forward class declarations, e.g.,
+// sc_reset, to keep gcc 4.x happy.
+//
+// Revision 1.14 2006/02/02 23:42:41 acg
+// Andy Goodrich: implemented a much better fix to the sc_event_finder
+// proliferation problem. This new version allocates only a single event
+// finder for each port for each type of event, e.g., pos(), neg(), and
+// value_change(). The event finder persists as long as the port does,
+// which is what the LRM dictates. Because only a single instance is
+// allocated for each event type per port there is not a potential
+// explosion of storage as was true in the 2.0.1/2.1 versions.
+//
+// Revision 1.13 2006/02/02 21:29:10 acg
+// Andy Goodrich: removed the call to sc_event_finder::free_instances() that
+// was in end_of_elaboration(), leaving only the call in clean(). This is
+// because the LRM states that sc_event_finder instances are persistent as
+// long as the sc_module hierarchy is valid.
+//
+// Revision 1.12 2006/02/02 21:09:50 acg
+// Andy Goodrich: added call to sc_event_finder::free_instances in the clean()
+// method.
+//
+// Revision 1.11 2006/02/02 20:43:14 acg
+// Andy Goodrich: Added an existence linked list to sc_event_finder so that
+// the dynamically allocated instances can be freed after port binding
+// completes. This replaces the individual deletions in ~sc_bind_ef, as these
+// caused an exception if an sc_event_finder instance was used more than
+// once, due to a double freeing of the instance.
+//
+// Revision 1.10 2006/01/31 21:43:26 acg
+// Andy Goodrich: added comments in constructor to highlight environmental
+// overrides section.
+//
+// Revision 1.9 2006/01/26 21:04:54 acg
+// Andy Goodrich: deprecation message changes and additional messages.
+//
+// Revision 1.8 2006/01/25 00:31:19 acg
+// Andy Goodrich: Changed over to use a standard message id of
+// SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
+//
+// Revision 1.7 2006/01/24 20:49:05 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.6 2006/01/19 00:29:52 acg
+// Andy Goodrich: Yet another implementation for signal write checking. This
+// one uses an environment variable SC_SIGNAL_WRITE_CHECK, that when set to
+// DISABLE will disable write checking on signals.
+//
+// Revision 1.5 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+//
+// Revision 1.4 2006/01/03 23:18:44 acg
+// Changed copyright to include 2006.
+//
+// Revision 1.3 2005/12/20 22:11:10 acg
+// Fixed $Log lines.
+//
+// Revision 1.2 2005/12/20 22:02:30 acg
+// Changed where delta cycles are incremented to match IEEE 1666. Added the
+// event_occurred() method to hide how delta cycle comparisions are done within
+// sc_simcontext. Changed the boolean update_phase to an enum that shows all
+// the phases.
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_simcontext.h b/ext/systemc/src/sysc/kernel/sc_simcontext.h
new file mode 100644
index 000000000..997a3f49c
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_simcontext.h
@@ -0,0 +1,903 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_simcontext.h -- Definition of the simulation context class.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+ Martin Janssen, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_SIMCONTEXT_H
+#define SC_SIMCONTEXT_H
+
+#include "sysc/kernel/sc_cmnhdr.h"
+#include "sysc/kernel/sc_process.h"
+#include "sysc/kernel/sc_status.h"
+#include "sysc/kernel/sc_time.h"
+#include "sysc/utils/sc_hash.h"
+#include "sysc/utils/sc_pq.h"
+
+namespace sc_core {
+
+// forward declarations
+
+class sc_cor;
+class sc_cor_pkg;
+class sc_event;
+class sc_event_timed;
+class sc_export_registry;
+class sc_module;
+class sc_module_name;
+class sc_module_registry;
+class sc_name_gen;
+class sc_object;
+class sc_object_manager;
+class sc_phase_callback_registry;
+class sc_process_handle;
+class sc_port_registry;
+class sc_prim_channel_registry;
+class sc_process_table;
+class sc_signal_bool_deval;
+class sc_trace_file;
+class sc_runnable;
+class sc_process_host;
+class sc_method_process;
+class sc_cthread_process;
+class sc_thread_process;
+
+template< typename > class sc_plist;
+typedef sc_plist< sc_process_b* > sc_process_list;
+
+struct sc_curr_proc_info
+{
+ sc_process_b* process_handle;
+ sc_curr_proc_kind kind;
+ sc_curr_proc_info() : process_handle( 0 ), kind( SC_NO_PROC_ ) {}
+};
+
+typedef const sc_curr_proc_info* sc_curr_proc_handle;
+
+enum sc_stop_mode { // sc_stop modes:
+ SC_STOP_FINISH_DELTA,
+ SC_STOP_IMMEDIATE
+};
+extern void sc_set_stop_mode( sc_stop_mode mode );
+extern sc_stop_mode sc_get_stop_mode();
+
+enum sc_starvation_policy
+{
+ SC_EXIT_ON_STARVATION,
+ SC_RUN_TO_TIME
+};
+extern void sc_start();
+extern void sc_start( const sc_time& duration,
+ sc_starvation_policy p=SC_RUN_TO_TIME );
+inline void sc_start( int duration, sc_time_unit unit,
+ sc_starvation_policy p=SC_RUN_TO_TIME )
+{
+ sc_start( sc_time((double)duration,unit), p );
+}
+
+inline void sc_start( double duration, sc_time_unit unit,
+ sc_starvation_policy p=SC_RUN_TO_TIME )
+{
+ sc_start( sc_time(duration,unit), p );
+}
+
+extern void sc_stop();
+
+// friend function declarations
+
+sc_dt::uint64 sc_delta_count();
+const std::vector<sc_event*>& sc_get_top_level_events(
+ const sc_simcontext* simc_p);
+const std::vector<sc_object*>& sc_get_top_level_objects(
+ const sc_simcontext* simc_p);
+bool sc_is_running( const sc_simcontext* simc_p );
+void sc_pause();
+bool sc_end_of_simulation_invoked();
+void sc_start( const sc_time&, sc_starvation_policy );
+bool sc_start_of_simulation_invoked();
+void sc_set_time_resolution( double, sc_time_unit );
+sc_time sc_get_time_resolution();
+void sc_set_default_time_unit( double, sc_time_unit );
+sc_time sc_get_default_time_unit();
+bool sc_pending_activity_at_current_time( const sc_simcontext* );
+bool sc_pending_activity_at_future_time( const sc_simcontext* );
+sc_time sc_time_to_pending_activity( const sc_simcontext* );
+
+struct sc_invoke_method;
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_simcontext
+//
+// The simulation context.
+// ----------------------------------------------------------------------------
+
+class sc_simcontext
+{
+ friend struct sc_invoke_method;
+ friend class sc_event;
+ friend class sc_module;
+ friend class sc_object;
+ friend class sc_time;
+ friend class sc_clock;
+ friend class sc_method_process;
+ friend class sc_phase_callback_registry;
+ friend class sc_process_b;
+ friend class sc_process_handle;
+ friend class sc_prim_channel;
+ friend class sc_cthread_process;
+ friend class sc_thread_process;
+ friend sc_dt::uint64 sc_delta_count();
+ friend const std::vector<sc_event*>& sc_get_top_level_events(
+ const sc_simcontext* simc_p);
+ friend const std::vector<sc_object*>& sc_get_top_level_objects(
+ const sc_simcontext* simc_p);
+ friend bool sc_is_running( const sc_simcontext* simc_p );
+ friend void sc_pause();
+ friend bool sc_end_of_simulation_invoked();
+ friend void sc_start( const sc_time&, sc_starvation_policy );
+ friend bool sc_start_of_simulation_invoked();
+ friend void sc_thread_cor_fn(void*);
+ friend sc_time sc_time_to_pending_activity( const sc_simcontext* );
+ friend bool sc_pending_activity_at_current_time( const sc_simcontext* );
+ friend bool sc_pending_activity_at_future_time( const sc_simcontext* );
+
+
+ void init();
+ void clean();
+
+public:
+
+ sc_simcontext();
+ ~sc_simcontext();
+
+ void initialize( bool = false );
+ void cycle( const sc_time& );
+ void simulate( const sc_time& duration );
+ void stop();
+ void end();
+ void reset();
+
+ int sim_status() const;
+ bool elaboration_done() const;
+
+ std::vector<sc_thread_handle>& get_active_invokers();
+
+ sc_object_manager* get_object_manager();
+
+ inline sc_status get_status() const;
+
+ sc_object* active_object();
+
+ void hierarchy_push( sc_module* );
+ sc_module* hierarchy_pop();
+ sc_module* hierarchy_curr() const;
+ sc_object* first_object();
+ sc_object* next_object();
+ sc_object* find_object( const char* name );
+
+ sc_module_registry* get_module_registry();
+ sc_port_registry* get_port_registry();
+ sc_export_registry* get_export_registry();
+ sc_prim_channel_registry* get_prim_channel_registry();
+
+ // to generate unique names for objects in an MT-Safe way
+ const char* gen_unique_name( const char* basename_,
+ bool preserve_first = false
+ );
+
+ // process creation
+ sc_process_handle create_cthread_process(
+ const char* name_p, bool free_host, SC_ENTRY_FUNC method_p,
+ sc_process_host* host_p, const sc_spawn_options* opt_p );
+
+ sc_process_handle create_method_process(
+ const char* name_p, bool free_host, SC_ENTRY_FUNC method_p,
+ sc_process_host* host_p, const sc_spawn_options* opt_p );
+
+ sc_process_handle create_thread_process(
+ const char* name_p, bool free_host, SC_ENTRY_FUNC method_p,
+ sc_process_host* host_p, const sc_spawn_options* opt_p );
+
+ sc_curr_proc_handle get_curr_proc_info();
+ sc_object* get_current_writer() const;
+ bool write_check() const;
+ void set_curr_proc( sc_process_b* );
+ void reset_curr_proc();
+
+ int next_proc_id();
+
+ void add_trace_file( sc_trace_file* );
+ void remove_trace_file( sc_trace_file* );
+
+ friend void sc_set_time_resolution( double, sc_time_unit );
+ friend sc_time sc_get_time_resolution();
+ friend void sc_set_default_time_unit( double, sc_time_unit );
+ friend sc_time sc_get_default_time_unit();
+
+ const sc_time& max_time() const;
+ const sc_time& time_stamp() const;
+
+ sc_dt::uint64 change_stamp() const;
+ sc_dt::uint64 delta_count() const;
+ bool event_occurred( sc_dt::uint64 last_change_count ) const;
+ bool evaluation_phase() const;
+ bool is_running() const;
+ bool update_phase() const;
+ bool notify_phase() const;
+ bool get_error();
+ void set_error( sc_report* );
+
+ sc_cor_pkg* cor_pkg()
+ { return m_cor_pkg; }
+ sc_cor* next_cor();
+
+ const ::std::vector<sc_object*>& get_child_objects() const;
+
+ void elaborate();
+ void prepare_to_simulate();
+ inline void initial_crunch( bool no_crunch );
+ bool next_time( sc_time& t ) const;
+ bool pending_activity_at_current_time() const;
+
+private:
+
+ void add_child_event( sc_event* );
+ void add_child_object( sc_object* );
+ void remove_child_event( sc_event* );
+ void remove_child_object( sc_object* );
+
+ void crunch( bool once=false );
+
+ int add_delta_event( sc_event* );
+ void remove_delta_event( sc_event* );
+ void add_timed_event( sc_event_timed* );
+
+ void trace_cycle( bool delta_cycle );
+
+ const ::std::vector<sc_event*>& get_child_events_internal() const;
+ const ::std::vector<sc_object*>& get_child_objects_internal() const;
+
+ void execute_method_next( sc_method_handle );
+ void execute_thread_next( sc_thread_handle );
+
+ sc_method_handle pop_runnable_method();
+ sc_thread_handle pop_runnable_thread();
+
+ void preempt_with( sc_method_handle );
+ inline void preempt_with( sc_thread_handle );
+
+ void push_runnable_method( sc_method_handle );
+ void push_runnable_thread( sc_thread_handle );
+
+ void push_runnable_method_front( sc_method_handle );
+ void push_runnable_thread_front( sc_thread_handle );
+
+ void remove_runnable_method( sc_method_handle );
+ void remove_runnable_thread( sc_thread_handle );
+
+ void requeue_current_process();
+ void suspend_current_process();
+
+ void do_sc_stop_action();
+ void mark_to_collect_process( sc_process_b* zombie_p );
+
+private:
+
+ enum execution_phases {
+ phase_initialize = 0,
+ phase_evaluate,
+ phase_update,
+ phase_notify
+ };
+ sc_object_manager* m_object_manager;
+
+ sc_module_registry* m_module_registry;
+ sc_port_registry* m_port_registry;
+ sc_export_registry* m_export_registry;
+ sc_prim_channel_registry* m_prim_channel_registry;
+ sc_phase_callback_registry* m_phase_cb_registry;
+
+ sc_name_gen* m_name_gen;
+
+ sc_process_table* m_process_table;
+ sc_curr_proc_info m_curr_proc_info;
+ sc_object* m_current_writer;
+ bool m_write_check;
+ int m_next_proc_id;
+
+ std::vector<sc_thread_handle> m_active_invokers;
+
+ std::vector<sc_event*> m_child_events;
+ std::vector<sc_object*> m_child_objects;
+
+ std::vector<sc_event*> m_delta_events;
+ sc_ppq<sc_event_timed*>* m_timed_events;
+
+ std::vector<sc_trace_file*> m_trace_files;
+ bool m_something_to_trace;
+
+ sc_runnable* m_runnable;
+ sc_process_list* m_collectable;
+
+ sc_time_params* m_time_params;
+ sc_time m_curr_time;
+ mutable sc_time m_max_time;
+
+ sc_invoke_method* m_method_invoker_p;
+ sc_dt::uint64 m_change_stamp; // "time" change occurred.
+ sc_dt::uint64 m_delta_count;
+ bool m_forced_stop;
+ bool m_paused;
+ bool m_ready_to_simulate;
+ bool m_elaboration_done;
+ execution_phases m_execution_phase;
+ sc_report* m_error;
+ bool m_in_simulator_control;
+ bool m_end_of_simulation_called;
+ sc_status m_simulation_status;
+ bool m_start_of_simulation_called;
+
+ sc_cor_pkg* m_cor_pkg; // the simcontext's coroutine package
+ sc_cor* m_cor; // the simcontext's coroutine
+
+private:
+
+ // disabled
+ sc_simcontext( const sc_simcontext& );
+ sc_simcontext& operator = ( const sc_simcontext& );
+};
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+// Not MT safe.
+
+#if 1
+extern sc_simcontext* sc_curr_simcontext;
+extern sc_simcontext* sc_default_global_context;
+
+inline sc_simcontext*
+sc_get_curr_simcontext()
+{
+ if( sc_curr_simcontext == 0 ) {
+ sc_default_global_context = new sc_simcontext;
+ sc_curr_simcontext = sc_default_global_context;
+ }
+ return sc_curr_simcontext;
+}
+#else
+ extern sc_simcontext* sc_get_curr_simcontext();
+#endif // 0
+inline sc_status sc_get_status()
+{
+ return sc_get_curr_simcontext()->get_status();
+}
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+inline
+bool
+sc_simcontext::elaboration_done() const
+{
+ return m_elaboration_done;
+}
+
+
+inline sc_status sc_simcontext::get_status() const
+{
+ return m_simulation_status != SC_RUNNING ?
+ m_simulation_status :
+ (m_in_simulator_control ? SC_RUNNING : SC_PAUSED);
+}
+
+inline
+int
+sc_simcontext::sim_status() const
+{
+ if( m_error ) {
+ return SC_SIM_ERROR;
+ }
+ if( m_forced_stop ) {
+ return SC_SIM_USER_STOP;
+ }
+ return SC_SIM_OK;
+}
+
+
+inline
+sc_object_manager*
+sc_simcontext::get_object_manager()
+{
+ return m_object_manager;
+}
+
+inline
+sc_module_registry*
+sc_simcontext::get_module_registry()
+{
+ return m_module_registry;
+}
+
+inline
+sc_port_registry*
+sc_simcontext::get_port_registry()
+{
+ return m_port_registry;
+}
+
+inline
+sc_export_registry*
+sc_simcontext::get_export_registry()
+{
+ return m_export_registry;
+}
+
+inline
+sc_prim_channel_registry*
+sc_simcontext::get_prim_channel_registry()
+{
+ return m_prim_channel_registry;
+}
+
+
+inline
+sc_curr_proc_handle
+sc_simcontext::get_curr_proc_info()
+{
+ return &m_curr_proc_info;
+}
+
+
+inline
+int
+sc_simcontext::next_proc_id()
+{
+ return ( ++ m_next_proc_id );
+}
+
+
+inline
+const sc_time&
+sc_simcontext::max_time() const
+{
+ if ( m_max_time == SC_ZERO_TIME )
+ {
+ m_max_time = sc_time::from_value( ~sc_dt::UINT64_ZERO );
+ }
+ return m_max_time;
+}
+
+inline
+sc_dt::uint64
+sc_simcontext::change_stamp() const
+{
+ return m_change_stamp;
+}
+
+inline
+const sc_time&
+sc_simcontext::time_stamp() const
+{
+ return m_curr_time;
+}
+
+
+inline
+bool
+sc_simcontext::event_occurred(sc_dt::uint64 last_change_stamp) const
+{
+ return m_change_stamp == last_change_stamp;
+}
+
+inline
+bool
+sc_simcontext::evaluation_phase() const
+{
+ return (m_execution_phase == phase_evaluate) &&
+ m_ready_to_simulate;
+}
+
+inline
+bool
+sc_simcontext::update_phase() const
+{
+ return m_execution_phase == phase_update;
+}
+
+inline
+bool
+sc_simcontext::notify_phase() const
+{
+ return m_execution_phase == phase_notify;
+}
+
+inline
+void
+sc_simcontext::set_error( sc_report* err )
+{
+ delete m_error;
+ m_error = err;
+}
+
+
+inline
+bool
+sc_simcontext::get_error()
+{
+ return m_error != NULL;
+}
+
+inline
+int
+sc_simcontext::add_delta_event( sc_event* e )
+{
+ m_delta_events.push_back( e );
+ return ( m_delta_events.size() - 1 );
+}
+
+inline
+void
+sc_simcontext::add_timed_event( sc_event_timed* et )
+{
+ m_timed_events->insert( et );
+}
+
+inline sc_object*
+sc_simcontext::get_current_writer() const
+{
+ return m_current_writer;
+}
+
+inline bool
+sc_simcontext::write_check() const
+{
+ return m_write_check;
+}
+
+// ----------------------------------------------------------------------------
+
+class sc_process_handle;
+sc_process_handle sc_get_current_process_handle();
+
+// Get the current object hierarchy context
+//
+// Returns a pointer the the sc_object (module or process) that
+// would become the parent object of a newly created element
+// of the SystemC object hierarchy, or NULL.
+//
+inline sc_object*
+sc_get_current_object()
+{
+ return sc_get_curr_simcontext()->active_object();
+}
+
+inline
+sc_process_b*
+sc_get_current_process_b()
+{
+ return sc_get_curr_simcontext()->get_curr_proc_info()->process_handle;
+}
+
+// THE FOLLOWING FUNCTION IS DEPRECATED IN 2.1
+extern sc_process_b* sc_get_curr_process_handle();
+
+inline
+sc_curr_proc_kind
+sc_get_curr_process_kind()
+{
+ return sc_get_curr_simcontext()->get_curr_proc_info()->kind;
+}
+
+
+inline int sc_get_simulator_status()
+{
+ return sc_get_curr_simcontext()->sim_status();
+}
+
+
+// Generates unique names within each module.
+extern
+const char*
+sc_gen_unique_name( const char* basename_, bool preserve_first = false );
+
+
+// Set the random seed for controlled randomization -- not yet implemented
+extern
+void
+sc_set_random_seed( unsigned int seed_ );
+
+
+extern void sc_initialize();
+
+extern const sc_time& sc_max_time(); // Get maximum time value.
+extern const sc_time& sc_time_stamp(); // Current simulation time.
+extern double sc_simulation_time(); // Current time in default time units.
+
+inline
+const std::vector<sc_event*>& sc_get_top_level_events(
+ const sc_simcontext* simc_p = sc_get_curr_simcontext() )
+{
+ return simc_p->m_child_events;
+}
+
+inline
+const std::vector<sc_object*>& sc_get_top_level_objects(
+ const sc_simcontext* simc_p = sc_get_curr_simcontext() )
+{
+ return simc_p->m_child_objects;
+}
+
+extern sc_event* sc_find_event( const char* name );
+
+extern sc_object* sc_find_object( const char* name );
+
+inline
+sc_dt::uint64 sc_delta_count()
+{
+ return sc_get_curr_simcontext()->m_delta_count;
+}
+
+inline
+bool sc_is_running( const sc_simcontext* simc_p = sc_get_curr_simcontext() )
+{
+ return simc_p->m_ready_to_simulate;
+}
+
+bool sc_is_unwinding();
+
+inline void sc_pause()
+{
+ sc_get_curr_simcontext()->m_paused = true;
+}
+
+// Return indication if there are more processes to execute in this delta phase
+
+inline bool sc_pending_activity_at_current_time
+ ( const sc_simcontext* simc_p = sc_get_curr_simcontext() )
+{
+ return simc_p->pending_activity_at_current_time();
+}
+
+// Return indication if there are timed notifications in the future
+
+inline bool sc_pending_activity_at_future_time
+ ( const sc_simcontext* simc_p = sc_get_curr_simcontext() )
+{
+ sc_time ignored;
+ return simc_p->next_time( ignored );
+}
+
+// Return indication if there are processes to run,
+// or notifications in the future
+
+inline bool sc_pending_activity
+ ( const sc_simcontext* simc_p = sc_get_curr_simcontext() )
+{
+ return sc_pending_activity_at_current_time( simc_p )
+ || sc_pending_activity_at_future_time( simc_p );
+}
+
+sc_time
+sc_time_to_pending_activity
+ ( const sc_simcontext* simc_p = sc_get_curr_simcontext() );
+
+
+inline
+bool
+sc_end_of_simulation_invoked()
+{
+ return sc_get_curr_simcontext()->m_end_of_simulation_called;
+}
+
+inline bool sc_hierarchical_name_exists( const char* name )
+{
+ return sc_find_object(name) || sc_find_event(name);
+}
+
+inline
+bool
+sc_start_of_simulation_invoked()
+{
+ return sc_get_curr_simcontext()->m_start_of_simulation_called;
+}
+
+// The following variable controls whether process control corners should
+// be considered errors or not. See sc_simcontext.cpp for details on what
+// happens if this value is set to true.
+
+extern bool sc_allow_process_control_corners;
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Andy Goodrich, Forte Design Systems 20 May 2003
+ Description of Modification: - phase callbacks
+ - sc_stop mode
+
+ Name, Affiliation, Date: Bishnupriya Bhattacharya, Cadence Design Systems,
+ 25 August, 2003
+ Description of Modification: - support for dynamic process
+ - support for sc export registry
+ - new member methods elaborate(),
+ prepare_to_simulate(), and initial_crunch()
+ that are invoked by initialize() in that order
+ - add sc_get_last_created_process_handle() for
+ use before simulation starts
+
+ Name, Affiliation, Date: Bishnupriya Bhattacharya, Cadence Design Systems,
+ 3 March, 2004
+ Description of Modification: add sc_get_curr_process_kind()
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+// $Log: sc_simcontext.h,v $
+// Revision 1.26 2011/09/05 21:20:22 acg
+// Andy Goodrich: result of automake invocation.
+//
+// Revision 1.25 2011/09/01 15:28:10 acg
+// Andy Goodrich: the aftermath of automake.
+//
+// Revision 1.24 2011/08/29 18:04:32 acg
+// Philipp A. Hartmann: miscellaneous clean ups.
+//
+// Revision 1.23 2011/08/26 20:46:10 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.22 2011/08/24 22:05:51 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.21 2011/05/09 04:07:49 acg
+// Philipp A. Hartmann:
+// (1) Restore hierarchy in all phase callbacks.
+// (2) Ensure calls to before_end_of_elaboration.
+//
+// Revision 1.20 2011/04/08 18:26:07 acg
+// Andy Goodrich: added execute_method_next() to handle method dispatch
+// for asynchronous notifications that occur outside the evaluation phase.
+//
+// Revision 1.19 2011/04/05 20:50:57 acg
+// Andy Goodrich:
+// (1) changes to make sure that event(), posedge() and negedge() only
+// return true if the clock has not moved.
+// (2) fixes for method self-resumes.
+// (3) added SC_PRERELEASE_VERSION
+// (4) removed kernel events from the object hierarchy, added
+// sc_hierarchical_name_exists().
+//
+// Revision 1.18 2011/03/20 13:43:23 acg
+// Andy Goodrich: added async_signal_is() plus suspend() as a corner case.
+//
+// Revision 1.17 2011/03/07 18:25:19 acg
+// Andy Goodrich: tightening of check for resume on a disabled process to
+// only produce an error if it is ready to run.
+//
+// Revision 1.16 2011/03/06 15:58:50 acg
+// Andy Goodrich: added escape to turn off process control corner case
+// checks.
+//
+// Revision 1.15 2011/03/05 04:45:16 acg
+// Andy Goodrich: moved active process calculation to the sc_simcontext class.
+//
+// Revision 1.14 2011/03/05 01:39:21 acg
+// Andy Goodrich: changes for named events.
+//
+// Revision 1.13 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.12 2011/02/13 21:47:38 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.11 2011/02/13 21:34:35 acg
+// Andy Goodrich: added SC_UNITIALIZED enum value to process status so
+// its possible to detect throws before initialization.
+//
+// Revision 1.10 2011/02/11 13:25:24 acg
+// Andy Goodrich: Philipp A. Hartmann's changes:
+// (1) Removal of SC_CTHREAD method overloads.
+// (2) New exception processing code.
+//
+// Revision 1.9 2011/02/01 21:18:56 acg
+// Andy Goodrich: addition of new preempt_with() method used to immediately
+// throw exceptions from threads.
+//
+// Revision 1.8 2011/01/25 20:50:37 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.7 2011/01/19 23:21:50 acg
+// Andy Goodrich: changes for IEEE 1666 2011
+//
+// Revision 1.6 2011/01/18 20:10:45 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.5 2010/07/22 20:02:33 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.4 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.3 2008/05/22 17:06:26 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.2 2007/09/20 20:32:35 acg
+// Andy Goodrich: changes to the semantics of throw_it() to match the
+// specification. A call to throw_it() will immediately suspend the calling
+// thread until all the throwees have executed. At that point the calling
+// thread will be restarted before the execution of any other threads.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.13 2006/05/08 18:00:06 acg
+// Andy Goodrich: added David Long's forward declarations for friend
+// functions, methods, and operators to keep the Microsoft compiler happy.
+//
+// Revision 1.11 2006/04/11 23:13:21 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.10 2006/03/21 00:00:34 acg
+// Andy Goodrich: changed name of sc_get_current_process_base() to be
+// sc_get_current_process_b() since its returning an sc_process_b instance.
+//
+// Revision 1.9 2006/01/26 21:04:54 acg
+// Andy Goodrich: deprecation message changes and additional messages.
+//
+// Revision 1.8 2006/01/24 20:49:05 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.7 2006/01/19 00:29:52 acg
+// Andy Goodrich: Yet another implementation for signal write checking. This
+// one uses an environment variable SC_SIGNAL_WRITE_CHECK, that when set to
+// DISABLE will disable write checking on signals.
+//
+// Revision 1.6 2006/01/18 21:42:37 acg
+// Andy Goodrich: Changes for check writer support.
+//
+// Revision 1.5 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+//
+// Revision 1.4 2006/01/03 23:18:44 acg
+// Changed copyright to include 2006.
+//
+// Revision 1.3 2005/12/20 22:11:10 acg
+// Fixed $Log lines.
+//
+// Revision 1.2 2005/12/20 22:02:30 acg
+// Changed where delta cycles are incremented to match IEEE 1666. Added the
+// event_occurred() method to hide how delta cycle comparisions are done within
+// sc_simcontext. Changed the boolean update_phase to an enum that shows all
+// the phases.
+
+#endif
diff --git a/ext/systemc/src/sysc/kernel/sc_simcontext_int.h b/ext/systemc/src/sysc/kernel/sc_simcontext_int.h
new file mode 100644
index 000000000..039237f4a
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_simcontext_int.h
@@ -0,0 +1,365 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_simcontext_int.h -- For inline definitions of some utility functions.
+ DO NOT EXPORT THIS INCLUDE FILE. Include this file
+ after "sc_process_int.h" so that we can get the base
+ class right.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_SIMCONTEXT_INT_H
+#define SC_SIMCONTEXT_INT_H
+
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_runnable.h"
+#include "sysc/kernel/sc_runnable_int.h"
+
+// DEBUGGING MACROS:
+//
+// DEBUG_MSG(NAME,P,MSG)
+// MSG = message to print
+// NAME = name that must match the process for the message to print, or
+// null if the message should be printed unconditionally.
+// P = pointer to process message is for, or NULL in which case the
+// message will not print.
+#if 0
+# define DEBUG_NAME ""
+# define DEBUG_MSG(NAME,P,MSG) \
+ { \
+ if ( P && ( (strlen(NAME)==0) || !strcmp(NAME,P->name())) ) \
+ std::cout << "**** " << sc_time_stamp() << " (" \
+ << sc_get_current_process_name() << "): " << MSG \
+ << " - " << P->name() << std::endl; \
+ }
+#else
+# define DEBUG_MSG(NAME,P,MSG)
+#endif
+
+
+namespace sc_core {
+
+inline
+const char*
+sc_get_current_process_name()
+{
+ sc_process_b* active_p; // active process to get name of.
+ const char* result; // name of active process.
+
+ active_p = sc_get_curr_simcontext()->get_curr_proc_info()->process_handle;
+ if ( active_p )
+ result = active_p->name();
+ else
+ result = "** NONE **";
+ return result;
+}
+
+// We use m_current_writer rather than m_curr_proc_info.process_handle to
+// return the active process for sc_signal<T>::check_write since that lets
+// us turn it off a library compile time, and only incur the overhead at
+// the time of process switches rather than having to interrogate an
+// additional switch every time a signal is written.
+
+inline
+void
+sc_simcontext::set_curr_proc( sc_process_b* process_h )
+{
+ m_curr_proc_info.process_handle = process_h;
+ m_curr_proc_info.kind = process_h->proc_kind();
+ m_current_writer = m_write_check ? process_h : (sc_object*)0;
+}
+
+inline
+void
+sc_simcontext::reset_curr_proc()
+{
+ m_curr_proc_info.process_handle = 0;
+ m_curr_proc_info.kind = SC_NO_PROC_;
+ m_current_writer = 0;
+ sc_process_b::m_last_created_process_p = 0;
+}
+
+inline
+void
+sc_simcontext::execute_method_next( sc_method_handle method_h )
+{
+ m_runnable->execute_method_next( method_h );
+}
+
+inline
+void
+sc_simcontext::execute_thread_next( sc_thread_handle thread_h )
+{
+ m_runnable->execute_thread_next( thread_h );
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_simcontext::preempt_with"
+// |
+// | This method executes the supplied thread immediately, suspending the
+// | caller. After executing the supplied thread the caller's execution will
+// | be restored. It is used to allow a thread to immediately throw an
+// | exception, e.g., when the thread's kill_process() method was called.
+// | There are three cases to consider:
+// | (1) The caller is a method, e.g., murder by method.
+// | (2) The caller is another thread instance, e.g., murder by thread.
+// | (3) The caller is this thread instance, e.g., suicide.
+// |
+// | Arguments:
+// | thread_h -> thread to be executed.
+// +----------------------------------------------------------------------------
+inline
+void
+sc_simcontext::preempt_with( sc_thread_handle thread_h )
+{
+ sc_thread_handle active_p; // active thread or null.
+ sc_curr_proc_info caller_info; // process info for caller.
+
+ // Determine the active process and take the thread to be run off the
+ // run queue, if its there, since we will be explicitly causing its
+ // execution.
+
+ active_p = DCAST<sc_thread_handle>(sc_get_current_process_b());
+ if ( thread_h->next_runnable() != NULL )
+ remove_runnable_thread( thread_h );
+
+ // THE CALLER IS A METHOD:
+ //
+ // (a) Set the current process information to our thread.
+ // (b) If the method was called by an invoker thread push that thread
+ // onto the front of the run queue, this will cause the method
+ // to be resumed after this thread waits.
+ // (c) Invoke our thread directly by-passing the run queue.
+ // (d) Restore the process info to the caller.
+ // (e) Check to see if the calling method should throw an exception
+ // because of activity that occurred during the preemption.
+
+ if ( active_p == NULL )
+ {
+ std::vector<sc_thread_handle>* invokers_p; // active invokers stack.
+ sc_thread_handle invoke_thread_p; // latest invocation thread.
+ sc_method_handle method_p; // active method.
+
+ method_p = DCAST<sc_method_handle>(sc_get_current_process_b());
+ invokers_p = &get_active_invokers();
+ caller_info = m_curr_proc_info;
+ if ( invokers_p->size() != 0 )
+ {
+ invoke_thread_p = invokers_p->back();
+ DEBUG_MSG( DEBUG_NAME, invoke_thread_p,
+ "queueing invocation thread to execute next" );
+ execute_thread_next(invoke_thread_p);
+ }
+ DEBUG_MSG( DEBUG_NAME, thread_h, "preempting method with thread" );
+ set_curr_proc( (sc_process_b*)thread_h );
+ m_cor_pkg->yield( thread_h->m_cor_p );
+ m_curr_proc_info = caller_info;
+ DEBUG_MSG(DEBUG_NAME, thread_h, "back from preempting method w/thread");
+ method_p->check_for_throws();
+ }
+
+ // CALLER IS A THREAD, BUT NOT THE THREAD TO BE RUN:
+ //
+ // (a) Push the calling thread onto the front of the runnable queue
+ // so it be the first thread to be run after this thread.
+ // (b) Push the thread to be run onto the front of the runnable queue so
+ // it will execute when we suspend the calling thread.
+ // (c) Suspend the active thread.
+
+ else if ( active_p != thread_h )
+ {
+ DEBUG_MSG( DEBUG_NAME, thread_h,
+ "preempting active thread with thread" );
+ execute_thread_next( active_p );
+ execute_thread_next( thread_h );
+ active_p->suspend_me();
+ }
+
+ // CALLER IS THE THREAD TO BE RUN:
+ //
+ // (a) Push the thread to be run onto the front of the runnable queue so
+ // it will execute when we suspend the calling thread.
+ // (b) Suspend the active thread.
+
+ else
+ {
+ DEBUG_MSG(DEBUG_NAME,thread_h,"self preemption of active thread");
+ execute_thread_next( thread_h );
+ active_p->suspend_me();
+ }
+}
+
+
+inline
+void
+sc_simcontext::push_runnable_method( sc_method_handle method_h )
+{
+ m_runnable->push_back_method( method_h );
+}
+
+inline
+void
+sc_simcontext::push_runnable_method_front( sc_method_handle method_h )
+{
+ m_runnable->push_front_method( method_h );
+}
+
+inline
+void
+sc_simcontext::push_runnable_thread( sc_thread_handle thread_h )
+{
+ m_runnable->push_back_thread( thread_h );
+}
+
+inline
+void
+sc_simcontext::push_runnable_thread_front( sc_thread_handle thread_h )
+{
+ m_runnable->push_front_thread( thread_h );
+}
+
+
+inline
+sc_method_handle
+sc_simcontext::pop_runnable_method()
+{
+ sc_method_handle method_h = m_runnable->pop_method();
+ if( method_h == 0 ) {
+ reset_curr_proc();
+ return 0;
+ }
+ set_curr_proc( (sc_process_b*)method_h );
+ return method_h;
+}
+
+inline
+sc_thread_handle
+sc_simcontext::pop_runnable_thread()
+{
+ sc_thread_handle thread_h = m_runnable->pop_thread();
+ if( thread_h == 0 ) {
+ reset_curr_proc();
+ return 0;
+ }
+ set_curr_proc( (sc_process_b*)thread_h );
+ return thread_h;
+}
+
+inline
+void
+sc_simcontext::remove_runnable_method( sc_method_handle method_h )
+{
+ m_runnable->remove_method( method_h );
+}
+
+inline
+void
+sc_simcontext::remove_runnable_thread( sc_thread_handle thread_h )
+{
+ m_runnable->remove_thread( thread_h );
+}
+
+inline
+std::vector<sc_thread_handle>&
+sc_simcontext::get_active_invokers()
+{
+ return m_active_invokers;
+}
+
+// ----------------------------------------------------------------------------
+
+extern void sc_defunct_process_function( sc_module* );
+
+
+} // namespace sc_core
+
+#undef DEBUG_MSG
+#undef DEBUG_NAME
+
+// $Log: sc_simcontext_int.h,v $
+// Revision 1.14 2011/08/29 18:04:32 acg
+// Philipp A. Hartmann: miscellaneous clean ups.
+//
+// Revision 1.13 2011/08/26 20:46:11 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.12 2011/07/29 22:45:06 acg
+// Andy Goodrich: added invocation of sc_method_process::check_for_throws()
+// to the preempt_with() code to handle case where the preempting process
+// causes a throw on the invoking method process.
+//
+// Revision 1.11 2011/04/13 02:45:11 acg
+// Andy Goodrich: eliminated warning message that occurred if the DEBUG_MSG
+// macro was used.
+//
+// Revision 1.10 2011/04/11 22:05:48 acg
+// Andy Goodrich: use the DEBUG_NAME macro in DEBUG_MSG invocations.
+//
+// Revision 1.9 2011/04/10 22:12:32 acg
+// Andy Goodrich: adding debugging macros.
+//
+// Revision 1.8 2011/04/08 18:26:07 acg
+// Andy Goodrich: added execute_method_next() to handle method dispatch
+// for asynchronous notifications that occur outside the evaluation phase.
+//
+// Revision 1.7 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.6 2011/02/13 21:47:38 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.5 2011/02/08 08:17:50 acg
+// Andy Goodrich: fixed bug in preempt_with() where I was resetting the
+// process context rather than saving and restoring it.
+//
+// Revision 1.4 2011/02/01 21:12:56 acg
+// Andy Goodrich: addition of preempt_with() method to allow immediate
+// execution of threads for throws.
+//
+// Revision 1.3 2011/01/25 20:50:37 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.2 2008/05/22 17:06:26 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.6 2006/05/26 20:33:16 acg
+// Andy Goodrich: changes required by additional platform compilers (i.e.,
+// Microsoft VC++, Sun Forte, HP aCC).
+//
+// Revision 1.5 2006/01/19 00:29:52 acg
+// Andy Goodrich: Yet another implementation for signal write checking. This
+// one uses an environment variable SC_SIGNAL_WRITE_CHECK, that when set to
+// DISABLE will disable write checking on signals.
+//
+// Revision 1.4 2006/01/18 21:42:37 acg
+// Andy Goodrich: Changes for check writer support.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+#endif
diff --git a/ext/systemc/src/sysc/kernel/sc_spawn.h b/ext/systemc/src/sysc/kernel/sc_spawn.h
new file mode 100644
index 000000000..e54886929
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_spawn.h
@@ -0,0 +1,337 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_spawn.h -- Process spawning support.
+
+ Original Authors: Andy Goodrich, Forte Design Systems, 17 June 2003
+ Stuart Swan, Cadence,
+ Bishnupriya Bhattacharya, Cadence Design Systems,
+ 25 August, 2003
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#if !defined(sc_spawn_h_INCLUDED)
+#define sc_spawn_h_INCLUDED
+
+#include "sysc/kernel/sc_process_handle.h"
+#include "sysc/kernel/sc_spawn_options.h"
+
+namespace sc_core {
+
+class sc_event;
+class sc_port_base;
+class sc_interface;
+class sc_event_finder;
+class sc_process_b;
+
+//=============================================================================
+// CLASS sc_spawn_object<T>
+//
+// This templated helper class allows an object to provide the execution
+// semantics for a process via its () operator. An instance of the supplied
+// execution object will be kept to provide the semantics when the process is
+// scheduled for execution. The () operator does not return a value. An example
+// of an object that might be used for this helper function would be void
+// SC_BOOST bound function or method.
+//
+// This class is derived from sc_process_host and overloads
+// sc_process_host::semantics to provide the actual semantic content.
+//
+// sc_spawn_object(T object, const char* name, const sc_spawn_options* opt_p)
+// This is the object instance constructor for this class. It makes a
+// copy of the supplied object. The tp_call constructor is called
+// with an indication that this object instance should be reclaimed when
+// execution completes.
+// object = object whose () operator will be called to provide
+// the process semantics.
+// name_p = optional name for object instance, or zero.
+// opt_p -> spawn options or zero.
+//
+// virtual void semantics()
+// This virtual method provides the execution semantics for its process.
+// It performs a () operation on m_object.
+//=============================================================================
+template<typename T>
+class sc_spawn_object : public sc_process_host {
+ public:
+ sc_spawn_object( T object) : m_object(object)
+ {
+ }
+
+ virtual void semantics()
+ {
+ m_object();
+ }
+
+ protected:
+ T m_object;
+};
+
+
+//------------------------------------------------------------------------------
+//"sc_spawn - semantic object with no return value"
+//
+// This inline function spawns a process for execution. The execution semantics
+// for the process being spawned will be provided by the supplied object
+// instance via its () operator. (E.g., a SC_BOOST bound function)
+// After creating the process it is registered with the simulator.
+// object = object instance providing the execution semantics via its
+// () operator.
+// name_p = optional name for object instance, or zero.
+// opt_p -> optional spawn options for process, or zero for the default.
+//------------------------------------------------------------------------------
+template <typename T>
+inline sc_process_handle sc_spawn(
+ T object,
+ const char* name_p = 0,
+ const sc_spawn_options* opt_p = 0)
+{
+ sc_simcontext* context_p;
+ sc_spawn_object<T>* spawn_p;
+
+ context_p = sc_get_curr_simcontext();
+ spawn_p = new sc_spawn_object<T>(object);
+ if ( !opt_p || !opt_p->is_method() )
+ {
+ sc_process_handle thread_handle = context_p->create_thread_process(
+ name_p, true,
+ SC_MAKE_FUNC_PTR(sc_spawn_object<T>,semantics),
+ spawn_p, opt_p
+ );
+ return thread_handle;
+ }
+ else
+ {
+ sc_process_handle method_handle = context_p->create_method_process(
+ name_p, true,
+ SC_MAKE_FUNC_PTR(sc_spawn_object<T>,semantics),
+ spawn_p, opt_p
+ );
+ return method_handle;
+ }
+}
+
+//=============================================================================
+// CLASS sc_spawn_object_v<T> for all compilers except HP aCC
+// or
+// CLASS sc_spawn_object_v<T, R> for HP aCC which tries to match this
+// one template argument class when the sc_spawn() declared above is
+// invoked with 3 arguments or 2 arguments, and generates compiler errors.
+//
+// This templated helper class allows an object to provide the execution
+// semantics for a process via its () operator. An instance of the supplied
+// object will be kept to provide the semantics when the process is scheduled
+// for execution. The () operator returns a value, which will be stored at the
+// location specified by the supplied pointer. An example of an object that
+// might be used for this helper function would be valued SC_BOOST bound
+// function or method.
+//
+// sc_spawn_object_v( typename F::result_type* r_p, T f, const char* name_p,
+// const sc_spawn_options* opt_p )
+// r_p -> where to place the result of the function invocation.
+// f = information to be executed.
+// name_p = optional name for object instance, or zero.
+// opt_p -> optional spawn options for process, or zero for the default
+// This is the object instance constructor for this class. It makes a
+// copy of the supplied object. The tp_call constructor is called
+// with an indication that this object instance should be reclaimed when
+// execution completes.
+// result_p -> where to place the value of the () operator.
+// object = object whose () operator will be called to provide
+// the process semantics.
+//
+// virtual void semantics()
+// This virtual method provides the execution semantics for its process.
+// It performs a () operation on m_object, placing the result at m_result_p.
+//=============================================================================
+
+//------------------------------------------------------------------------------
+//"sc_spawn_object_v - semantic object with return value"
+//
+// This inline function spawns a process for execution. The execution semantics
+// for the process being spawned will be provided by the supplied object
+// instance via its () operator. (E.g., a SC_BOOST bound function) That
+// operator returns a value, which will be placed in the supplied return
+// location.
+// After creating the process it is registered with the simulator.
+// object = object instance providing the execution semantics via its ()
+// operator.
+// r_p -> where to place the value of the () operator.
+// name_p = optional name for object instance, or zero.
+// opt_p -> optional spawn options for process, or zero for the default.
+//------------------------------------------------------------------------------
+
+#if !defined (__HP_aCC)
+
+template<typename T>
+class sc_spawn_object_v : public sc_process_host {
+ public:
+ sc_spawn_object_v( typename T::result_type* r_p, T object ) :
+ m_object(object), m_result_p(r_p)
+ {
+ }
+
+ virtual void semantics()
+ {
+ *m_result_p = m_object();
+ }
+
+ protected:
+ T m_object;
+ typename T::result_type* m_result_p;
+};
+
+template <typename T>
+inline sc_process_handle sc_spawn(
+ typename T::result_type* r_p,
+ T object,
+ const char* name_p = 0,
+ const sc_spawn_options* opt_p = 0)
+{
+ sc_simcontext* context_p;
+ sc_spawn_object_v<T>* spawn_p;
+
+ context_p = sc_get_curr_simcontext();
+
+ spawn_p = new sc_spawn_object_v<T>(r_p, object);
+ if ( !opt_p || !opt_p->is_method() )
+ {
+ sc_process_handle thread_handle = context_p->create_thread_process(
+ name_p, true,
+ SC_MAKE_FUNC_PTR(sc_spawn_object_v<T>,semantics),
+ spawn_p, opt_p
+ );
+ return thread_handle;
+ }
+ else
+ {
+ sc_process_handle method_handle = context_p->create_method_process(
+ name_p, true,
+ SC_MAKE_FUNC_PTR(sc_spawn_object_v<T>,semantics),
+ spawn_p, opt_p
+ );
+ return method_handle;
+ }
+}
+
+#else
+// for HP aCC
+template<typename T, typename R>
+class sc_spawn_object_v : public sc_process_host {
+ public:
+ sc_spawn_object_v( R* r_p, T object) :
+ m_object(object), m_result_p(r_p)
+ {
+ }
+
+ virtual void semantics()
+ {
+ *m_result_p = m_object();
+ }
+
+ protected:
+ T m_object;
+ R* m_result_p;
+};
+
+template <typename T, typename R>
+inline sc_process_handle sc_spawn(
+ R* r_p,
+ T object,
+ const char* name_p = 0,
+ const sc_spawn_options* opt_p = 0)
+{
+ sc_simcontext* context_p;
+ sc_spawn_object_v<T,R>* spawn_p;
+
+ context_p = sc_get_curr_simcontext();
+
+ spawn_p = new sc_spawn_object_v<T,R>(r_p, object);
+ if ( !opt_p || !opt_p->is_method() )
+ {
+ sc_process_handle thread_handle = context_p->create_thread_process(
+ name_p, true,
+ static_cast<sc_core::SC_ENTRY_FUNC>(
+ &sc_spawn_object_v<T,R>::semantics),
+ spawn_p, opt_p
+ );
+ return thread_handle;
+ }
+ else
+ {
+ sc_process_handle method_handle = context_p->create_method_process(
+ name_p, true,
+ static_cast<sc_core::SC_ENTRY_FUNC>(
+ &sc_spawn_object_v<T,R>::semantics),
+ spawn_p, opt_p
+ );
+ return method_handle;
+ }
+}
+
+#endif // HP
+
+} // namespace sc_core
+
+// $Log: sc_spawn.h,v $
+// Revision 1.7 2011/08/26 20:46:11 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.6 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.5 2011/02/13 21:47:38 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.4 2011/02/01 21:14:02 acg
+// Andy Goodrich: formatting.
+//
+// Revision 1.3 2009/07/28 01:10:53 acg
+// Andy Goodrich: updates for 2.3 release candidate.
+//
+// Revision 1.2 2008/05/22 17:06:26 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.6 2006/05/26 20:33:16 acg
+// Andy Goodrich: changes required by additional platform compilers (i.e.,
+// Microsoft VC++, Sun Forte, HP aCC).
+//
+// Revision 1.5 2006/05/08 18:01:44 acg
+// Andy Goodrich: changed the HP-specific implementations of sc_spawn() to
+// use a static_cast to create their entry functions rather than the
+// SC_MAKE_FUNC_PTR macro. The HP preprocessor does not parse template
+// arguments that contain a comma properly.
+//
+// Revision 1.4 2006/04/11 23:13:21 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+#endif // !defined(sc_spawn_h_INCLUDED)
diff --git a/ext/systemc/src/sysc/kernel/sc_spawn_options.cpp b/ext/systemc/src/sysc/kernel/sc_spawn_options.cpp
new file mode 100644
index 000000000..c577f1d87
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_spawn_options.cpp
@@ -0,0 +1,124 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_spawn_options.cpp -- Process spawning options implementation.
+
+ Original Authors: Andy Goodrich, Forte Design Systems, 17 June 2003
+ Stuart Swan, Cadence,
+ Bishnupriya Bhattacharya, Cadence Design Systems,
+ 25 August, 2003
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include "sysc/kernel/sc_spawn_options.h"
+#include "sysc/kernel/sc_reset.h"
+
+namespace sc_core {
+
+// +======================================================================
+// | CLASS sc_spawn_reset_base - Class to do a generic access to an
+// | sc_spawn_rest object instance
+// +======================================================================
+class sc_spawn_reset_base
+{
+ public:
+ sc_spawn_reset_base( bool async, bool level )
+ : m_async( async ), m_level(level)
+ {}
+ virtual ~sc_spawn_reset_base() {}
+ virtual void specify_reset() = 0;
+
+ protected:
+ bool m_async; // = true if async reset.
+ bool m_level; // level indicating reset.
+};
+
+// +======================================================================
+// | CLASS sc_spawn_reset<SOURCE>
+// | - Reset specification for sc_spawn_options.
+// +======================================================================
+template<typename SOURCE>
+class sc_spawn_reset : public sc_spawn_reset_base
+{
+ public:
+ sc_spawn_reset( bool async, const SOURCE& source, bool level )
+ : sc_spawn_reset_base(async, level), m_source(source)
+ {}
+ virtual ~sc_spawn_reset() {}
+ virtual void specify_reset()
+ {
+ sc_reset::reset_signal_is( m_async, m_source, m_level );
+ }
+
+ protected:
+ const SOURCE& m_source; // source of reset signal.
+};
+
+// +======================================================================
+// | CLASS sc_spawn_options (implementation)
+// |
+// +======================================================================
+
+sc_spawn_options::~sc_spawn_options()
+{
+ std::vector<sc_spawn_reset_base*>::size_type resets_n = m_resets.size();
+ for ( std::vector<sc_spawn_reset_base*>::size_type reset_i = 0; reset_i < resets_n; reset_i++ )
+ delete m_resets[reset_i];
+}
+
+#define SC_DEFINE_RESET_SIGNALS( Port ) \
+ /* asynchronous reset */ \
+ void \
+ sc_spawn_options:: \
+ async_reset_signal_is ( const Port & port, bool level ) \
+ { \
+ m_resets.push_back( \
+ new sc_spawn_reset< Port >(true, port, level) ); \
+ } \
+ /* sync reset */ \
+ void \
+ sc_spawn_options:: \
+ reset_signal_is ( const Port & port, bool level ) \
+ { \
+ m_resets.push_back( \
+ new sc_spawn_reset< Port >(false, port, level) ); \
+ }
+
+SC_DEFINE_RESET_SIGNALS( sc_in<bool> )
+SC_DEFINE_RESET_SIGNALS( sc_inout<bool> )
+SC_DEFINE_RESET_SIGNALS( sc_out<bool> )
+SC_DEFINE_RESET_SIGNALS( sc_signal_in_if<bool> )
+
+#undef SC_DEFINE_RESET_SIGNALS
+
+void
+sc_spawn_options::specify_resets() const
+{
+ std::vector<sc_spawn_reset_base*>::size_type resets_n; // number of reset specifications to process.
+ resets_n = m_resets.size();
+ for ( std::vector<sc_spawn_reset_base*>::size_type reset_i = 0; reset_i < resets_n; reset_i++ )
+ m_resets[reset_i]->specify_reset();
+}
+
+} // namespace sc_core
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_spawn_options.h b/ext/systemc/src/sysc/kernel/sc_spawn_options.h
new file mode 100644
index 000000000..4c3f64baa
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_spawn_options.h
@@ -0,0 +1,161 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_spawn_options.h -- Process spawning options specification.
+
+ Original Authors: Andy Goodrich, Forte Design Systems, 17 June 2003
+ Stuart Swan, Cadence,
+ Bishnupriya Bhattacharya, Cadence Design Systems,
+ 25 August, 2003
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#if !defined(sc_spawn_options_h_INCLUDED)
+#define sc_spawn_options_h_INCLUDED
+
+#include <vector>
+#include "sysc/communication/sc_export.h"
+#include "sysc/communication/sc_signal_ports.h"
+
+namespace sc_core {
+
+class sc_event;
+class sc_port_base;
+class sc_interface;
+class sc_event_finder;
+class sc_process_b;
+class sc_spawn_reset_base;
+
+//=============================================================================
+// CLASS sc_spawn_options
+//
+//=============================================================================
+class sc_spawn_options {
+ friend class sc_cthread_process;
+ friend class sc_method_process;
+ friend class sc_process_b;
+ friend class sc_thread_process;
+ public:
+ sc_spawn_options() :
+ m_dont_initialize(false), m_resets(), m_sensitive_events(),
+ m_sensitive_event_finders(), m_sensitive_interfaces(),
+ m_sensitive_port_bases(), m_spawn_method(false), m_stack_size(0)
+ { }
+
+ ~sc_spawn_options();
+
+ void async_reset_signal_is( const sc_in<bool>&, bool level );
+ void async_reset_signal_is( const sc_inout<bool>&, bool level );
+ void async_reset_signal_is( const sc_out<bool>&, bool level );
+ void async_reset_signal_is( const sc_signal_in_if<bool>&, bool level );
+
+ void reset_signal_is( const sc_in<bool>&, bool level );
+ void reset_signal_is( const sc_inout<bool>&, bool level );
+ void reset_signal_is( const sc_out<bool>&, bool level );
+ void reset_signal_is( const sc_signal_in_if<bool>&, bool level );
+
+ void dont_initialize() { m_dont_initialize = true; }
+
+ bool is_method() const { return m_spawn_method; }
+
+ void set_stack_size(int stack_size) { m_stack_size = stack_size; }
+
+ void set_sensitivity(const sc_event* event)
+ { m_sensitive_events.push_back(event); }
+
+ void set_sensitivity(sc_port_base* port_base)
+ { m_sensitive_port_bases.push_back(port_base); }
+
+ void set_sensitivity(sc_interface* interface_p)
+ { m_sensitive_interfaces.push_back(interface_p); }
+
+ void set_sensitivity(sc_export_base* export_base)
+ { m_sensitive_interfaces.push_back(export_base->get_interface()); }
+
+ void set_sensitivity(sc_event_finder* event_finder)
+ { m_sensitive_event_finders.push_back(event_finder); }
+
+ void spawn_method() { m_spawn_method = true; }
+
+ protected:
+ void specify_resets() const;
+
+ private:
+ sc_spawn_options( const sc_spawn_options& );
+ const sc_spawn_options& operator = ( const sc_spawn_options& );
+
+ protected:
+ bool m_dont_initialize;
+ std::vector<sc_spawn_reset_base*> m_resets;
+ std::vector<const sc_event*> m_sensitive_events;
+ std::vector<sc_event_finder*> m_sensitive_event_finders;
+ std::vector<sc_interface*> m_sensitive_interfaces;
+ std::vector<sc_port_base*> m_sensitive_port_bases;
+ bool m_spawn_method; // Method not thread.
+ int m_stack_size; // Thread stack size.
+};
+
+} // namespace sc_core
+
+// $Log: sc_spawn_options.h,v $
+// Revision 1.11 2011/08/26 20:46:11 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.10 2011/08/24 22:05:51 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.9 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.8 2011/02/13 21:47:38 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.7 2011/02/07 19:17:20 acg
+// Andy Goodrich: changes for IEEE 1666 compatibility.
+//
+// Revision 1.6 2010/12/07 20:09:15 acg
+// Andy Goodrich: replaced sc_signal signatures with sc_signal_in_if signatures for reset methods.
+//
+// Revision 1.5 2010/11/20 17:10:57 acg
+// Andy Goodrich: reset processing changes for new IEEE 1666 standard.
+//
+// Revision 1.4 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.3 2009/02/28 00:26:58 acg
+// Andy Goodrich: changed boost name space to sc_boost to allow use with
+// full boost library applications.
+//
+// Revision 1.2 2008/05/22 17:06:26 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.4 2006/04/20 17:08:17 acg
+// Andy Goodrich: 3.0 style process changes.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+#endif // !defined(sc_spawn_options_h_INCLUDED)
diff --git a/ext/systemc/src/sysc/kernel/sc_status.h b/ext/systemc/src/sysc/kernel/sc_status.h
new file mode 100644
index 000000000..1d3b016db
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_status.h
@@ -0,0 +1,83 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_status.h -- Definition of the simulation phases
+
+ Original Author: Philipp A. Hartmann, OFFIS, 2013-02-15
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_STATUS_H_INCLUDED_
+#define SC_STATUS_H_INCLUDED_
+
+#include <iosfwd>
+
+namespace sc_core {
+
+// simulation status codes
+
+const int SC_SIM_OK = 0;
+const int SC_SIM_ERROR = 1;
+const int SC_SIM_USER_STOP = 2;
+
+enum sc_status
+{ // sc_get_status values:
+ SC_UNITIALIZED=0x00, // initialize() not called yet
+
+ SC_ELABORATION = 0x01, // during module hierarchy construction
+ SC_BEFORE_END_OF_ELABORATION = 0x02, // during before_end_of_elaboration()
+ SC_END_OF_ELABORATION = 0x04, // during end_of_elaboration()
+ SC_START_OF_SIMULATION = 0x08, // during start_of_simulation()
+
+ SC_RUNNING = 0x10, // initialization, evaluation or update
+ SC_PAUSED = 0x20, // when scheduler stopped by sc_pause()
+ SC_STOPPED = 0x40, // when scheduler stopped by sc_stop()
+ SC_END_OF_SIMULATION = 0x80, // during end_of_simulation()
+
+ // detailed simulation phases (for dynamic callbacks)
+ SC_END_OF_INITIALIZATION = 0x100, // after initialization
+// SC_END_OF_EVALUATION = 0x200, // between eval and update
+ SC_END_OF_UPDATE = 0x400, // after update/notify phase
+ SC_BEFORE_TIMESTEP = 0x800, // before next time step
+
+ SC_STATUS_LAST = SC_BEFORE_TIMESTEP,
+ SC_STATUS_ANY = 0xdff
+};
+
+// pretty-printing of sc_status values
+std::ostream& operator << ( std::ostream&, sc_status );
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+#endif /* SC_STATUS_H_INCLUDED_ */
+// Taf!
+
diff --git a/ext/systemc/src/sysc/kernel/sc_thread_process.cpp b/ext/systemc/src/sysc/kernel/sc_thread_process.cpp
new file mode 100644
index 000000000..140096c95
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_thread_process.cpp
@@ -0,0 +1,1127 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_thread_process.cpp -- Thread process implementation
+
+ Original Author: Andy Goodrich, Forte Design Systems, 4 August 2005
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include "sysc/kernel/sc_cmnhdr.h"
+#include "sysc/kernel/sc_constants.h"
+#include "sysc/kernel/sc_thread_process.h"
+#include "sysc/kernel/sc_process_handle.h"
+#include "sysc/kernel/sc_simcontext_int.h"
+#include "sysc/kernel/sc_module.h"
+#include "sysc/utils/sc_machine.h"
+
+// DEBUGGING MACROS:
+//
+// DEBUG_MSG(NAME,P,MSG)
+// MSG = message to print
+// NAME = name that must match the process for the message to print, or
+// null if the message should be printed unconditionally.
+// P = pointer to process message is for, or NULL in which case the
+// message will not print.
+#if 0
+# define DEBUG_NAME ""
+# define DEBUG_MSG(NAME,P,MSG) \
+ { \
+ if ( P && ( (strlen(NAME)==0) || !strcmp(NAME,P->name())) ) \
+ std::cout << "**** " << sc_time_stamp() << " (" \
+ << sc_get_current_process_name() << "): " << MSG \
+ << " - " << P->name() << std::endl; \
+ }
+#else
+# define DEBUG_MSG(NAME,P,MSG)
+#endif
+
+
+//------------------------------------------------------------------------------
+// user-defined default stack-size
+//------------------------------------------------------------------------------
+#if defined(SC_OVERRIDE_DEFAULT_STACK_SIZE)
+# define SC_DEFAULT_STACK_SIZE_ SC_OVERRIDE_DEFAULT_STACK_SIZE
+
+//------------------------------------------------------------------------------
+// architecture-specific default stack sizes
+//------------------------------------------------------------------------------
+#elif !defined(SC_USE_PTHREADS) && (defined(__CYGWIN32__) || defined(__CYGWIN32))
+# define SC_DEFAULT_STACK_SIZE_ 0x50000
+
+#elif defined(SC_LONG_64) || defined(__x86_64__) || defined(__LP64__) || \
+ defined(_M_X64) || defined(_M_AMD64)
+# define SC_DEFAULT_STACK_SIZE_ 0x40000
+
+#else
+# define SC_DEFAULT_STACK_SIZE_ 0x20000
+
+#endif // SC_DEFAULT_STACK_SIZE_
+
+
+//------------------------------------------------------------------------------
+// force 16-byte alignment on coroutine entry functions, needed for
+// QuickThreads (32-bit, see also fixes in qt/md/{i386,iX86_64}.[hs]),
+// and MinGW32 / Cygwin32 compilers on Windows platforms
+#if defined(__GNUC__) && !defined(__ICC) && !defined(__x86_64__) && \
+ (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ > 1 )
+# define SC_ALIGNED_STACK_ \
+ __attribute__((force_align_arg_pointer))
+#else
+# define SC_ALIGNED_STACK_ /* empty */
+#endif
+
+
+namespace sc_core {
+
+const int SC_DEFAULT_STACK_SIZE = SC_DEFAULT_STACK_SIZE_;
+#undef SC_DEFAULT_STACK_SIZE_
+#undef SC_OVERRIDE_DEFAULT_STACK_SIZE
+
+//------------------------------------------------------------------------------
+//"sc_thread_cor_fn"
+//
+// This function invokes the coroutine for the supplied object instance.
+//------------------------------------------------------------------------------
+SC_ALIGNED_STACK_
+void sc_thread_cor_fn( void* arg )
+{
+ sc_simcontext* simc_p = sc_get_curr_simcontext();
+ sc_thread_handle thread_h = RCAST<sc_thread_handle>( arg );
+
+ // PROCESS THE THREAD AND PROCESS ANY EXCEPTIONS THAT ARE THROWN:
+
+ while( true ) {
+
+ try {
+ thread_h->semantics();
+ }
+ catch( sc_user ) {
+ continue;
+ }
+ catch( sc_halt ) {
+ ::std::cout << "Terminating process "
+ << thread_h->name() << ::std::endl;
+ }
+ catch( const sc_unwind_exception& ex ) {
+ ex.clear();
+ if ( ex.is_reset() ) continue;
+ }
+ catch( ... ) {
+ sc_report* err_p = sc_handle_exception();
+ thread_h->simcontext()->set_error( err_p );
+ }
+ break;
+ }
+
+ sc_process_b* active_p = sc_get_current_process_b();
+
+ // REMOVE ALL TRACES OF OUR THREAD FROM THE SIMULATORS DATA STRUCTURES:
+
+ thread_h->disconnect_process();
+
+ // IF WE AREN'T ACTIVE MAKE SURE WE WON'T EXECUTE:
+
+ if ( thread_h->next_runnable() != 0 )
+ {
+ simc_p->remove_runnable_thread(thread_h);
+ }
+
+ // IF WE ARE THE ACTIVE PROCESS ABORT OUR EXECUTION:
+
+
+ if ( active_p == (sc_process_b*)thread_h )
+ {
+
+ sc_core::sc_cor* x = simc_p->next_cor();
+ simc_p->cor_pkg()->abort( x );
+ }
+
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::disable_process"
+//
+// This virtual method suspends this process and its children if requested to.
+// descendants = indicator of whether this process' children should also
+// be suspended
+//------------------------------------------------------------------------------
+void sc_thread_process::disable_process(
+ sc_descendant_inclusion_info descendants )
+{
+
+ // IF NEEDED PROPOGATE THE DISABLE REQUEST THROUGH OUR DESCENDANTS:
+
+ if ( descendants == SC_INCLUDE_DESCENDANTS )
+ {
+ const std::vector<sc_object*>& children = get_child_objects();
+ int child_n = children.size();
+
+ for ( int child_i = 0; child_i < child_n; child_i++ )
+ {
+ sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]);
+ if ( child_p ) child_p->disable_process(descendants);
+ }
+ }
+
+ // DON'T ALLOW CORNER CASE BY DEFAULT:
+
+ if ( !sc_allow_process_control_corners )
+ {
+ switch( m_trigger_type )
+ {
+ case AND_LIST_TIMEOUT:
+ case EVENT_TIMEOUT:
+ case OR_LIST_TIMEOUT:
+ case TIMEOUT:
+ report_error(SC_ID_PROCESS_CONTROL_CORNER_CASE_,
+ "attempt to disable a thread with timeout wait");
+ break;
+ default:
+ break;
+ }
+ }
+
+ // DISABLE OUR OBJECT INSTANCE:
+
+ m_state = m_state | ps_bit_disabled;
+
+ // IF THIS CALL IS BEFORE THE SIMULATION DON'T RUN THE THREAD:
+
+ if ( !sc_is_running() )
+ {
+ m_state = m_state | ps_bit_ready_to_run;
+ simcontext()->remove_runnable_thread(this);
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::enable_process"
+//
+// This method resumes the execution of this process, and if requested, its
+// descendants. If the process was suspended and has a resumption pending it
+// will be dispatched in the next delta cycle. Otherwise the state will be
+// adjusted to indicate it is no longer suspended, but no immediate execution
+// will occur.
+//------------------------------------------------------------------------------
+void sc_thread_process::enable_process(
+ sc_descendant_inclusion_info descendants )
+{
+
+ // IF NEEDED PROPOGATE THE ENABLE REQUEST THROUGH OUR DESCENDANTS:
+
+ if ( descendants == SC_INCLUDE_DESCENDANTS )
+ {
+ const std::vector<sc_object*>& children = get_child_objects();
+ int child_n = children.size();
+
+ for ( int child_i = 0; child_i < child_n; child_i++ )
+ {
+ sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]);
+ if ( child_p ) child_p->enable_process(descendants);
+ }
+ }
+
+ // ENABLE THIS OBJECT INSTANCE:
+ //
+ // If it was disabled and ready to run then put it on the run queue.
+
+ m_state = m_state & ~ps_bit_disabled;
+ if ( m_state == ps_bit_ready_to_run && sc_allow_process_control_corners )
+ {
+ m_state = ps_normal;
+ if ( next_runnable() == 0 )
+ simcontext()->push_runnable_thread(this);
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::kill_process"
+//
+// This method removes this object instance from use. It calls the
+// sc_process_b::kill_process() method to perform low level clean up. Then
+// it aborts this process if it is the active process.
+//------------------------------------------------------------------------------
+void sc_thread_process::kill_process(sc_descendant_inclusion_info descendants )
+{
+
+ // IF THE SIMULATION HAS NOT BEEN INITIALIZED YET THAT IS AN ERROR:
+
+ if ( !sc_is_running() )
+ {
+ report_error( SC_ID_KILL_PROCESS_WHILE_UNITIALIZED_ );
+ }
+
+ // IF NEEDED PROPOGATE THE KILL REQUEST THROUGH OUR DESCENDANTS:
+
+ if ( descendants == SC_INCLUDE_DESCENDANTS )
+ {
+ const std::vector<sc_object*> children = get_child_objects();
+ int child_n = children.size();
+
+ for ( int child_i = 0; child_i < child_n; child_i++ )
+ {
+ sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]);
+ if ( child_p ) child_p->kill_process(descendants);
+ }
+ }
+
+ // IF THE PROCESS IS CURRENTLY UNWINDING OR IS ALREADY A ZOMBIE
+ // IGNORE THE KILL:
+
+ if ( m_unwinding )
+ {
+ SC_REPORT_WARNING( SC_ID_PROCESS_ALREADY_UNWINDING_, name() );
+ return;
+ }
+
+ if ( m_state & ps_bit_zombie )
+ return;
+
+ // SET UP TO KILL THE PROCESS IF SIMULATION HAS STARTED:
+ //
+ // If the thread does not have a stack don't try the throw!
+
+ if ( sc_is_running() && m_has_stack )
+ {
+ m_throw_status = THROW_KILL;
+ m_wait_cycle_n = 0;
+ simcontext()->preempt_with(this);
+ }
+
+ // IF THE SIMULATION HAS NOT STARTED REMOVE TRACES OF OUR PROCESS FROM
+ // EVENT QUEUES, ETC.:
+
+ else
+ {
+ disconnect_process();
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::prepare_for_simulation"
+//
+// This method prepares this object instance for simulation. It calls the
+// coroutine package to create the actual thread.
+//------------------------------------------------------------------------------
+void sc_thread_process::prepare_for_simulation()
+{
+ m_cor_p = simcontext()->cor_pkg()->create( m_stack_size,
+ sc_thread_cor_fn, this );
+ m_cor_p->stack_protect( true );
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::resume_process"
+//
+// This method resumes the execution of this process, and if requested, its
+// descendants. If the process was suspended and has a resumption pending it
+// will be dispatched in the next delta cycle. Otherwise the state will be
+// adjusted to indicate it is no longer suspended, but no immediate execution
+// will occur.
+//------------------------------------------------------------------------------
+void sc_thread_process::resume_process(
+ sc_descendant_inclusion_info descendants )
+{
+
+ // IF NEEDED PROPOGATE THE RESUME REQUEST THROUGH OUR DESCENDANTS:
+
+ if ( descendants == SC_INCLUDE_DESCENDANTS )
+ {
+ const std::vector<sc_object*>& children = get_child_objects();
+ int child_n = children.size();
+
+ for ( int child_i = 0; child_i < child_n; child_i++ )
+ {
+ sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]);
+ if ( child_p ) child_p->resume_process(descendants);
+ }
+ }
+
+ // BY DEFAULT THE CORNER CASE IS AN ERROR:
+
+ if ( !sc_allow_process_control_corners && (m_state & ps_bit_disabled) &&
+ (m_state & ps_bit_suspended) )
+ {
+ m_state = m_state & ~ps_bit_suspended;
+ report_error(SC_ID_PROCESS_CONTROL_CORNER_CASE_,
+ "call to resume() on a disabled suspended thread");
+ }
+
+ // CLEAR THE SUSPENDED BIT:
+
+ m_state = m_state & ~ps_bit_suspended;
+
+ // RESUME OBJECT INSTANCE IF IT IS READY TO RUN:
+
+ if ( m_state & ps_bit_ready_to_run )
+ {
+ m_state = m_state & ~ps_bit_ready_to_run;
+ if ( next_runnable() == 0 )
+ simcontext()->push_runnable_thread(this);
+ remove_dynamic_events(); // order important.
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::sc_thread_process"
+//
+// This is the object instance constructor for this class.
+//------------------------------------------------------------------------------
+sc_thread_process::sc_thread_process( const char* name_p, bool free_host,
+ SC_ENTRY_FUNC method_p, sc_process_host* host_p,
+ const sc_spawn_options* opt_p
+):
+ sc_process_b(
+ name_p ? name_p : sc_gen_unique_name("thread_p"),
+ true, free_host, method_p, host_p, opt_p),
+ m_cor_p(0), m_monitor_q(), m_stack_size(SC_DEFAULT_STACK_SIZE),
+ m_wait_cycle_n(0)
+{
+
+ // CHECK IF THIS IS AN sc_module-BASED PROCESS AND SIMULATION HAS STARTED:
+
+ if ( DCAST<sc_module*>(host_p) != 0 && sc_is_running() )
+ {
+ report_error( SC_ID_MODULE_THREAD_AFTER_START_ );
+ }
+
+ // INITIALIZE VALUES:
+ //
+ // If there are spawn options use them.
+
+ m_process_kind = SC_THREAD_PROC_;
+
+ if (opt_p) {
+ m_dont_init = opt_p->m_dont_initialize;
+ if ( opt_p->m_stack_size ) m_stack_size = opt_p->m_stack_size;
+
+ // traverse event sensitivity list
+ for (unsigned int i = 0; i < opt_p->m_sensitive_events.size(); i++) {
+ sc_sensitive::make_static_sensitivity(
+ this, *opt_p->m_sensitive_events[i]);
+ }
+
+ // traverse port base sensitivity list
+ for ( unsigned int i = 0; i < opt_p->m_sensitive_port_bases.size(); i++)
+ {
+ sc_sensitive::make_static_sensitivity(
+ this, *opt_p->m_sensitive_port_bases[i]);
+ }
+
+ // traverse interface sensitivity list
+ for ( unsigned int i = 0; i < opt_p->m_sensitive_interfaces.size(); i++)
+ {
+ sc_sensitive::make_static_sensitivity(
+ this, *opt_p->m_sensitive_interfaces[i]);
+ }
+
+ // traverse event finder sensitivity list
+ for ( unsigned int i = 0; i < opt_p->m_sensitive_event_finders.size();
+ i++)
+ {
+ sc_sensitive::make_static_sensitivity(
+ this, *opt_p->m_sensitive_event_finders[i]);
+ }
+
+ // process any reset signal specification:
+
+ opt_p->specify_resets();
+
+ }
+
+ else
+ {
+ m_dont_init = false;
+ }
+
+}
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::~sc_thread_process"
+//
+// This is the object instance constructor for this class.
+//------------------------------------------------------------------------------
+sc_thread_process::~sc_thread_process()
+{
+
+ // DESTROY THE COROUTINE FOR THIS THREAD:
+
+ if( m_cor_p != 0 ) {
+ m_cor_p->stack_protect( false );
+ delete m_cor_p;
+ m_cor_p = 0;
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::signal_monitors"
+//
+// This methods signals the list of monitors for this object instance.
+//------------------------------------------------------------------------------
+void sc_thread_process::signal_monitors(int type)
+{
+ int mon_n; // # of monitors present.
+
+ mon_n = m_monitor_q.size();
+ for ( int mon_i = 0; mon_i < mon_n; mon_i++ )
+ m_monitor_q[mon_i]->signal(this, type);
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::suspend_process"
+//
+// This virtual method suspends this process and its children if requested to.
+// descendants = indicator of whether this process' children should also
+// be suspended
+//------------------------------------------------------------------------------
+void sc_thread_process::suspend_process(
+ sc_descendant_inclusion_info descendants )
+{
+
+ // IF NEEDED PROPOGATE THE SUSPEND REQUEST THROUGH OUR DESCENDANTS:
+
+ if ( descendants == SC_INCLUDE_DESCENDANTS )
+ {
+ const std::vector<sc_object*>& children = get_child_objects();
+ int child_n = children.size();
+
+ for ( int child_i = 0; child_i < child_n; child_i++ )
+ {
+ sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]);
+ if ( child_p ) child_p->suspend_process(descendants);
+ }
+ }
+
+ // CORNER CASE CHECKS, THE FOLLOWING ARE ERRORS:
+ // (a) if this thread has a reset_signal_is specification
+ // (b) if this thread is in synchronous reset
+
+ if ( !sc_allow_process_control_corners && m_has_reset_signal )
+ {
+ report_error(SC_ID_PROCESS_CONTROL_CORNER_CASE_,
+ "attempt to suspend a thread that has a reset signal");
+ }
+ else if ( !sc_allow_process_control_corners && m_sticky_reset )
+ {
+ report_error(SC_ID_PROCESS_CONTROL_CORNER_CASE_,
+ "attempt to suspend a thread in synchronous reset");
+ }
+
+ // SUSPEND OUR OBJECT INSTANCE:
+ //
+ // (1) If we are on the runnable queue then set suspended and ready_to_run,
+ // and remove ourselves from the run queue.
+ // (2) If this is a self-suspension then a resume should cause immediate
+ // scheduling of the process, and we need to call suspend_me() here.
+
+ m_state = m_state | ps_bit_suspended;
+ if ( next_runnable() != 0 )
+ {
+ m_state = m_state | ps_bit_ready_to_run;
+ simcontext()->remove_runnable_thread( this );
+ }
+ if ( sc_get_current_process_b() == DCAST<sc_process_b*>(this) )
+ {
+ m_state = m_state | ps_bit_ready_to_run;
+ suspend_me();
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::throw_reset"
+//
+// This virtual method is invoked when an reset is to be thrown. The
+// method will cancel any dynamic waits. If the reset is asynchronous it will
+// queue this object instance to be executed.
+//------------------------------------------------------------------------------
+void sc_thread_process::throw_reset( bool async )
+{
+ // IF THE PROCESS IS CURRENTLY UNWINDING OR IS ALREADY A ZOMBIE
+ // IGNORE THE RESET:
+
+ if ( m_unwinding )
+ {
+ SC_REPORT_WARNING( SC_ID_PROCESS_ALREADY_UNWINDING_, name() );
+ return;
+ }
+
+ if ( m_state & ps_bit_zombie )
+ return;
+
+
+ // Set the throw type and clear any pending dynamic events:
+
+ m_throw_status = async ? THROW_ASYNC_RESET : THROW_SYNC_RESET;
+ m_wait_cycle_n = 0;
+
+ // If this is an asynchronous reset:
+ //
+ // (a) Cancel any dynamic events
+ // (b) Set the thread up for execution:
+ // (i) If we are in the execution phase do it now.
+ // (ii) If we are not queue it to execute next when we hit
+ // the execution phase.
+
+ if ( async )
+ {
+ m_state = m_state & ~ps_bit_ready_to_run;
+ remove_dynamic_events();
+ if ( simcontext()->evaluation_phase() )
+ {
+ simcontext()->preempt_with( this );
+ }
+ else
+ {
+ if ( is_runnable() )
+ simcontext()->remove_runnable_thread(this);
+ simcontext()->execute_thread_next(this);
+ }
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::throw_user"
+//
+// This virtual method is invoked when a user exception is to be thrown.
+// If requested it will also throw the exception to the children of this
+// object instance. The order of dispatch for the processes that are
+// thrown the exception is from youngest child to oldest child and then
+// this process instance. This means that this instance will be pushed onto
+// the front of the simulator's runnable queue and then the children will
+// be processed recursively.
+// helper_p = helper object to use to throw the exception.
+// descendants = indicator of whether this process' children should also
+// be suspended
+//------------------------------------------------------------------------------
+void sc_thread_process::throw_user( const sc_throw_it_helper& helper,
+ sc_descendant_inclusion_info descendants )
+{
+
+ // IF THE SIMULATION IS NOT ACTAULLY RUNNING THIS IS AN ERROR:
+
+ if ( sc_get_status() != SC_RUNNING )
+ {
+ report_error( SC_ID_THROW_IT_WHILE_NOT_RUNNING_ );
+ }
+
+ // IF NEEDED PROPOGATE THE THROW REQUEST THROUGH OUR DESCENDANTS:
+
+ if ( descendants == SC_INCLUDE_DESCENDANTS )
+ {
+ const std::vector<sc_object*> children = get_child_objects();
+ int child_n = children.size();
+
+ for ( int child_i = 0; child_i < child_n; child_i++ )
+ {
+ sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]);
+ if ( child_p )
+ {
+ DEBUG_MSG(DEBUG_NAME,child_p,"about to throw user on");
+ child_p->throw_user(helper, descendants);
+ }
+ }
+ }
+
+ // IF THE PROCESS IS CURRENTLY UNWINDING IGNORE THE THROW:
+
+ if ( m_unwinding )
+ {
+ SC_REPORT_WARNING( SC_ID_PROCESS_ALREADY_UNWINDING_, name() );
+ return;
+ }
+
+ // SET UP THE THROW REQUEST FOR THIS OBJECT INSTANCE AND QUEUE IT FOR
+ // EXECUTION:
+
+ if( m_has_stack )
+ {
+ remove_dynamic_events();
+ DEBUG_MSG(DEBUG_NAME,this,"throwing user exception to");
+ m_throw_status = THROW_USER;
+ if ( m_throw_helper_p != 0 ) delete m_throw_helper_p;
+ m_throw_helper_p = helper.clone();
+ simcontext()->preempt_with( this );
+ }
+ else
+ {
+ SC_REPORT_WARNING( SC_ID_THROW_IT_IGNORED_, name() );
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::trigger_dynamic"
+//
+// This method sets up a dynamic trigger on an event.
+//
+// Notes:
+// (1) This method is identical to sc_method_process::trigger_dynamic(),
+// but they cannot be combined as sc_process_b::trigger_dynamic()
+// because the signatures things like sc_event::remove_dynamic()
+// have different overloads for sc_thread_process* and sc_method_process*.
+// So if you change code here you'll also need to change it in
+// sc_method_process.cpp.
+//
+// Result is true if this process should be removed from the event's list,
+// false if not.
+//------------------------------------------------------------------------------
+bool sc_thread_process::trigger_dynamic( sc_event* e )
+{
+ // No time outs yet, and keep gcc happy.
+
+ m_timed_out = false;
+
+ // Escape cases:
+ // (a) If this thread issued the notify() don't schedule it for
+ // execution, but leave the sensitivity in place.
+ // (b) If this thread is already runnable can't trigger an event.
+
+ // not possible for thread processes!
+#if 0 // ! defined( SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS )
+ if ( sc_get_current_process_b() == (sc_process_b*)this )
+ {
+ report_immediate_self_notification();
+ return false;
+ }
+#endif // SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS
+
+ if( is_runnable() )
+ return true;
+
+ // If a process is disabled then we ignore any events, leaving them enabled:
+ //
+ // But if this is a time out event we need to remove both it and the
+ // event that was being waited for.
+
+ if ( m_state & ps_bit_disabled )
+ {
+ if ( e == m_timeout_event_p )
+ {
+ remove_dynamic_events( true );
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+
+ // Process based on the event type and current process state:
+ //
+ // Every case needs to set 'rc' and continue on to the end of
+ // this method to allow suspend processing to work correctly.
+
+ switch( m_trigger_type )
+ {
+ case EVENT:
+ m_event_p = 0;
+ m_trigger_type = STATIC;
+ break;
+
+ case AND_LIST:
+ -- m_event_count;
+ if ( m_event_count == 0 )
+ {
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ m_trigger_type = STATIC;
+ }
+ else
+ {
+ return true;
+ }
+ break;
+
+ case OR_LIST:
+ m_event_list_p->remove_dynamic( this, e );
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ m_trigger_type = STATIC;
+ break;
+
+ case TIMEOUT:
+ m_trigger_type = STATIC;
+ break;
+
+ case EVENT_TIMEOUT:
+ if ( e == m_timeout_event_p )
+ {
+ m_timed_out = true;
+ m_event_p->remove_dynamic( this );
+ m_event_p = 0;
+ m_trigger_type = STATIC;
+ }
+ else
+ {
+ m_timeout_event_p->cancel();
+ m_timeout_event_p->reset();
+ m_event_p = 0;
+ m_trigger_type = STATIC;
+ }
+ break;
+
+ case OR_LIST_TIMEOUT:
+ if ( e == m_timeout_event_p )
+ {
+ m_timed_out = true;
+ m_event_list_p->remove_dynamic( this, e );
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ m_trigger_type = STATIC;
+ }
+
+ else
+ {
+ m_timeout_event_p->cancel();
+ m_timeout_event_p->reset();
+ m_event_list_p->remove_dynamic( this, e );
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ m_trigger_type = STATIC;
+ }
+ break;
+
+ case AND_LIST_TIMEOUT:
+ if ( e == m_timeout_event_p )
+ {
+ m_timed_out = true;
+ m_event_list_p->remove_dynamic( this, e );
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ m_trigger_type = STATIC;
+ }
+
+ else
+ {
+ -- m_event_count;
+ if ( m_event_count == 0 )
+ {
+ m_timeout_event_p->cancel();
+ m_timeout_event_p->reset();
+ // no need to remove_dynamic
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ m_trigger_type = STATIC;
+ }
+ else
+ {
+ return true;
+ }
+ }
+ break;
+
+ case STATIC: {
+ // we should never get here, but throw_it() can make it happen.
+ SC_REPORT_WARNING(SC_ID_NOT_EXPECTING_DYNAMIC_EVENT_NOTIFY_, name());
+ return true;
+ }
+ }
+
+ // If we get here then the thread is has satisfied its wait criteria, if
+ // its suspended mark its state as ready to run. If its not suspended then
+ // push it onto the runnable queue.
+
+ if ( (m_state & ps_bit_suspended) )
+ {
+ m_state = m_state | ps_bit_ready_to_run;
+ }
+ else
+ {
+ simcontext()->push_runnable_thread(this);
+ }
+
+ return true;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_set_stack_size"
+//
+//------------------------------------------------------------------------------
+void
+sc_set_stack_size( sc_thread_handle thread_h, std::size_t size )
+{
+ thread_h->set_stack_size( size );
+}
+
+#undef DEBUG_MSG
+#undef DEBUG_NAME
+
+} // namespace sc_core
+
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_thread_process.cpp,v $
+// Revision 1.57 2011/08/24 22:05:51 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.56 2011/08/07 19:08:04 acg
+// Andy Goodrich: moved logs to end of file so line number synching works
+// better between versions.
+//
+// Revision 1.55 2011/08/04 17:16:22 acg
+// Philipp A. Hartmann: fix handling of child objects in kill routine, need
+// to use a copy rather than a reference.
+//
+// Revision 1.53 2011/07/29 22:45:38 acg
+// Philipp A. Hartmann: changes to handle case where a process control
+// invocation on a child process causes the list of child processes to change.
+//
+// Revision 1.52 2011/07/24 11:27:04 acg
+// Andy Goodrich: moved the check for unwinding processes until after the
+// descendants have been processed in throw_user and kill.
+//
+// Revision 1.51 2011/07/24 11:20:03 acg
+// Philipp A. Hartmann: process control error message improvements:
+// (1) Downgrade error to warning for re-kills of processes.
+// (2) Add process name to process messages.
+// (3) drop some superfluous colons in messages.
+//
+// Revision 1.50 2011/05/09 04:07:49 acg
+// Philipp A. Hartmann:
+// (1) Restore hierarchy in all phase callbacks.
+// (2) Ensure calls to before_end_of_elaboration.
+//
+// Revision 1.49 2011/05/05 17:45:27 acg
+// Philip A. Hartmann: changes in WIN64 support.
+// Andy Goodrich: additional DEBUG_MSG instances to trace process handling.
+//
+// Revision 1.48 2011/04/19 15:04:27 acg
+// Philipp A. Hartmann: clean up SC_ID messages.
+//
+// Revision 1.47 2011/04/19 02:39:09 acg
+// Philipp A. Hartmann: added checks for additional throws during stack unwinds.
+//
+// Revision 1.46 2011/04/14 22:33:43 acg
+// Andy Goodrich: added missing checks for a process being a zombie.
+//
+// Revision 1.45 2011/04/13 02:45:11 acg
+// Andy Goodrich: eliminated warning message that occurred if the DEBUG_MSG
+// macro was used.
+//
+// Revision 1.44 2011/04/11 22:04:33 acg
+// Andy Goodrich: use the DEBUG_NAME macro for DEBUG_MSG messages.
+//
+// Revision 1.43 2011/04/10 22:12:32 acg
+// Andy Goodrich: adding debugging macros.
+//
+// Revision 1.42 2011/04/08 22:40:26 acg
+// Andy Goodrich: moved the reset event notification code out of throw_reset()
+// and into suspend_me.
+//
+// Revision 1.41 2011/04/08 18:24:07 acg
+// Andy Goodrich: fix asynchronous reset dispatch and when the reset_event()
+// is fired.
+//
+// Revision 1.40 2011/04/05 20:50:57 acg
+// Andy Goodrich:
+// (1) changes to make sure that event(), posedge() and negedge() only
+// return true if the clock has not moved.
+// (2) fixes for method self-resumes.
+// (3) added SC_PRERELEASE_VERSION
+// (4) removed kernel events from the object hierarchy, added
+// sc_hierarchy_name_exists().
+//
+// Revision 1.39 2011/04/01 22:30:39 acg
+// Andy Goodrich: change hard assertion to warning for trigger_dynamic()
+// getting called when there is only STATIC sensitivity. This can result
+// because of sc_process_handle::throw_it().
+//
+// Revision 1.38 2011/03/23 16:17:52 acg
+// Andy Goodrich: don't emit an error message for a resume on a disabled
+// process that is not suspended.
+//
+// Revision 1.37 2011/03/20 13:43:23 acg
+// Andy Goodrich: added async_signal_is() plus suspend() as a corner case.
+//
+// Revision 1.36 2011/03/08 20:49:31 acg
+// Andy Goodrich: implement coarse checking for synchronous reset - suspend
+// interaction.
+//
+// Revision 1.35 2011/03/08 20:32:28 acg
+// Andy Goodrich: implemented "coarse" checking for undefined process
+// control interactions.
+//
+// Revision 1.34 2011/03/07 18:25:19 acg
+// Andy Goodrich: tightening of check for resume on a disabled process to
+// only produce an error if it is ready to run.
+//
+// Revision 1.33 2011/03/07 17:38:44 acg
+// Andy Goodrich: tightening up of checks for undefined interaction between
+// synchronous reset and suspend.
+//
+// Revision 1.32 2011/03/06 23:30:13 acg
+// Andy Goodrich: refining suspend - sync reset corner case checking so that
+// the following are error situations:
+// (1) Calling suspend on a process with a reset_signal_is() specification
+// or sync_reset_on() is active.
+// (2) Calling sync_reset_on() on a suspended process.
+//
+// Revision 1.31 2011/03/06 19:57:11 acg
+// Andy Goodrich: refinements for the illegal suspend - synchronous reset
+// interaction.
+//
+// Revision 1.30 2011/03/06 16:47:09 acg
+// Andy Goodrich: changes for testing sync_reset - suspend corner cases.
+//
+// Revision 1.29 2011/03/06 15:59:23 acg
+// Andy Goodrich: added process control corner case checks.
+//
+// Revision 1.28 2011/03/05 19:44:20 acg
+// Andy Goodrich: changes for object and event naming and structures.
+//
+// Revision 1.27 2011/02/19 08:30:53 acg
+// Andy Goodrich: Moved process queueing into trigger_static from
+// sc_event::notify.
+//
+// Revision 1.26 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.25 2011/02/17 19:54:33 acg
+// Andy Goodrich:
+// (1) Changed signature of trigger_dynamic() back to bool, and moved
+// run queue processing into trigger_dynamic.
+// (2) Simplified process control usage.
+//
+// Revision 1.24 2011/02/16 22:37:31 acg
+// Andy Goodrich: clean up to remove need for ps_disable_pending.
+//
+// Revision 1.23 2011/02/14 17:51:40 acg
+// Andy Goodrich: proper pushing an poppping of the module hierarchy for
+// start_of_simulation() and end_of_simulation.
+//
+// Revision 1.22 2011/02/13 23:09:58 acg
+// Andy Goodrich: only remove dynamic events for asynchronous resets.
+//
+// Revision 1.21 2011/02/13 21:47:38 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.20 2011/02/13 21:37:13 acg
+// Andy Goodrich: removed temporary diagnostic. Also there is
+// remove_dynamic_events() call in reset code.
+//
+// Revision 1.19 2011/02/13 21:35:09 acg
+// Andy Goodrich: added error messages for throws before the simulator is
+// initialized.
+//
+// Revision 1.18 2011/02/11 13:25:24 acg
+// Andy Goodrich: Philipp A. Hartmann's changes:
+// (1) Removal of SC_CTHREAD method overloads.
+// (2) New exception processing code.
+//
+// Revision 1.17 2011/02/08 08:18:16 acg
+// Andy Goodrich: removed obsolete code.
+//
+// Revision 1.16 2011/02/07 19:17:20 acg
+// Andy Goodrich: changes for IEEE 1666 compatibility.
+//
+// Revision 1.15 2011/02/04 15:27:36 acg
+// Andy Goodrich: changes for suspend-resume semantics.
+//
+// Revision 1.14 2011/02/01 23:01:53 acg
+// Andy Goodrich: removed dead code.
+//
+// Revision 1.13 2011/02/01 21:16:36 acg
+// Andy Goodrich:
+// (1) New version of trigger_dynamic() to implement new return codes and
+// proper processing of events with new dynamic process rules.
+// (2) Recoding of kill_process(), throw_user() and reset support to
+// consolidate preemptive thread execution in sc_simcontext::preempt_with().
+//
+// Revision 1.12 2011/01/25 20:50:37 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.11 2011/01/20 16:52:20 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.10 2011/01/19 23:21:50 acg
+// Andy Goodrich: changes for IEEE 1666 2011
+//
+// Revision 1.9 2011/01/18 20:10:45 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.8 2011/01/06 18:02:16 acg
+// Andy Goodrich: added check for disabled thread to trigger_dynamic().
+//
+// Revision 1.7 2010/11/20 17:10:57 acg
+// Andy Goodrich: reset processing changes for new IEEE 1666 standard.
+//
+// Revision 1.6 2010/07/22 20:02:33 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.5 2009/07/28 01:10:53 acg
+// Andy Goodrich: updates for 2.3 release candidate.
+//
+// Revision 1.4 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.3 2008/05/22 17:06:06 acg
+// Andy Goodrich: formatting and comments.
+//
+// Revision 1.2 2007/09/20 20:32:35 acg
+// Andy Goodrich: changes to the semantics of throw_it() to match the
+// specification. A call to throw_it() will immediately suspend the calling
+// thread until all the throwees have executed. At that point the calling
+// thread will be restarted before the execution of any other threads.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.8 2006/04/20 17:08:17 acg
+// Andy Goodrich: 3.0 style process changes.
+//
+// Revision 1.7 2006/04/11 23:13:21 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.6 2006/03/21 00:00:34 acg
+// Andy Goodrich: changed name of sc_get_current_process_base() to be
+// sc_get_current_process_b() since its returning an sc_process_b instance.
+//
+// Revision 1.5 2006/01/26 21:04:55 acg
+// Andy Goodrich: deprecation message changes and additional messages.
+//
+// Revision 1.4 2006/01/24 20:49:05 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+//
diff --git a/ext/systemc/src/sysc/kernel/sc_thread_process.h b/ext/systemc/src/sysc/kernel/sc_thread_process.h
new file mode 100644
index 000000000..5e834506a
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_thread_process.h
@@ -0,0 +1,635 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_thread_process.h -- Thread process declarations
+
+ Original Author: Andy Goodrich, Forte Design Systems, 4 August 2005
+
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#if !defined(sc_thread_process_h_INCLUDED)
+#define sc_thread_process_h_INCLUDED
+
+#include "sysc/kernel/sc_spawn_options.h"
+#include "sysc/kernel/sc_process.h"
+#include "sysc/kernel/sc_cor.h"
+#include "sysc/kernel/sc_event.h"
+#include "sysc/kernel/sc_except.h"
+#include "sysc/kernel/sc_reset.h"
+
+// DEBUGGING MACROS:
+//
+// DEBUG_MSG(NAME,P,MSG)
+// MSG = message to print
+// NAME = name that must match the process for the message to print, or
+// null if the message should be printed unconditionally.
+// P = pointer to process message is for, or NULL in which case the
+// message will not print.
+#if 0
+# define DEBUG_NAME ""
+# define DEBUG_MSG(NAME,P,MSG) \
+ { \
+ if ( P && ( (strlen(NAME)==0) || !strcmp(NAME,P->name())) ) \
+ std::cout << "**** " << sc_time_stamp() << " (" \
+ << sc_get_current_process_name() << "): " << MSG \
+ << " - " << P->name() << std::endl; \
+ }
+#else
+# define DEBUG_MSG(NAME,P,MSG)
+#endif
+
+
+namespace sc_core {
+
+// forward references:
+class sc_event_and_list;
+class sc_event_or_list;
+class sc_reset;
+void sc_thread_cor_fn( void* );
+void sc_set_stack_size( sc_thread_handle, std::size_t );
+class sc_event;
+class sc_join;
+class sc_module;
+class sc_process_handle;
+class sc_process_table;
+class sc_simcontext;
+class sc_runnable;
+
+sc_cor* get_cor_pointer( sc_process_b* process_p );
+void sc_set_stack_size( sc_thread_handle thread_h, std::size_t size );
+void wait( sc_simcontext* );
+void wait( const sc_event&, sc_simcontext* );
+void wait( const sc_event_or_list&, sc_simcontext* );
+void wait( const sc_event_and_list&, sc_simcontext* );
+void wait( const sc_time&, sc_simcontext* );
+void wait( const sc_time&, const sc_event&, sc_simcontext* );
+void wait( const sc_time&, const sc_event_or_list&, sc_simcontext* );
+void wait( const sc_time&, const sc_event_and_list&, sc_simcontext* );
+
+//==============================================================================
+// sc_thread_process -
+//
+//==============================================================================
+class sc_thread_process : public sc_process_b {
+ friend void sc_thread_cor_fn( void* );
+ friend void sc_set_stack_size( sc_thread_handle, std::size_t );
+ friend class sc_event;
+ friend class sc_join;
+ friend class sc_module;
+ friend class sc_process_b;
+ friend class sc_process_handle;
+ friend class sc_process_table;
+ friend class sc_simcontext;
+ friend class sc_runnable;
+ friend sc_cor* get_cor_pointer( sc_process_b* process_p );
+
+ friend void wait( sc_simcontext* );
+ friend void wait( const sc_event&, sc_simcontext* );
+ friend void wait( const sc_event_or_list&, sc_simcontext* );
+ friend void wait( const sc_event_and_list&, sc_simcontext* );
+ friend void wait( const sc_time&, sc_simcontext* );
+ friend void wait( const sc_time&, const sc_event&, sc_simcontext* );
+ friend void wait( const sc_time&, const sc_event_or_list&, sc_simcontext* );
+ friend void wait( const sc_time&, const sc_event_and_list&, sc_simcontext*);
+ public:
+ sc_thread_process( const char* name_p, bool free_host,
+ SC_ENTRY_FUNC method_p, sc_process_host* host_p,
+ const sc_spawn_options* opt_p );
+
+ virtual const char* kind() const
+ { return "sc_thread_process"; }
+
+ protected:
+ // may not be deleted manually (called from sc_process_b)
+ virtual ~sc_thread_process();
+
+ virtual void disable_process(
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
+ virtual void enable_process(
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
+ virtual void kill_process(
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
+ sc_thread_handle next_exist();
+ sc_thread_handle next_runnable();
+ virtual void prepare_for_simulation();
+ virtual void resume_process(
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
+ void set_next_exist( sc_thread_handle next_p );
+ void set_next_runnable( sc_thread_handle next_p );
+
+ void set_stack_size( std::size_t size );
+ inline void suspend_me();
+ virtual void suspend_process(
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
+ virtual void throw_reset( bool async );
+ virtual void throw_user( const sc_throw_it_helper& helper,
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
+
+ bool trigger_dynamic( sc_event* );
+ inline void trigger_static();
+
+ void wait( const sc_event& );
+ void wait( const sc_event_or_list& );
+ void wait( const sc_event_and_list& );
+ void wait( const sc_time& );
+ void wait( const sc_time&, const sc_event& );
+ void wait( const sc_time&, const sc_event_or_list& );
+ void wait( const sc_time&, const sc_event_and_list& );
+ void wait_cycles( int n=1 );
+
+ protected:
+ void add_monitor( sc_process_monitor* monitor_p );
+ void remove_monitor( sc_process_monitor* monitor_p);
+ void signal_monitors( int type = 0 );
+
+ protected:
+ sc_cor* m_cor_p; // Thread's coroutine.
+ std::vector<sc_process_monitor*> m_monitor_q; // Thread monitors.
+ std::size_t m_stack_size; // Thread stack size.
+ int m_wait_cycle_n; // # of waits to be done.
+
+ private: // disabled
+ sc_thread_process( const sc_thread_process& );
+ const sc_thread_process& operator = ( const sc_thread_process& );
+
+};
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::set_stack_size"
+//
+//------------------------------------------------------------------------------
+inline void sc_thread_process::set_stack_size( std::size_t size )
+{
+ assert( size );
+ m_stack_size = size;
+}
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::suspend_me"
+//
+// This method suspends this object instance in favor of the next runnable
+// process. Upon awakening we check to see if an exception should be thrown.
+// There are two types of exceptions that can be thrown, synchronous reset
+// and asynchronous reset. At a future time there may be more asynchronous
+// exceptions. If an asynchronous reset is seen and there is not static reset
+// specified, or the static reset is not active then clear the throw
+// type for the next time this method is called.
+//
+// Notes:
+// (1) For an explanation of how the reset mechanism works see the top of
+// the file sc_reset.cpp.
+// (2) The m_sticky_reset field is used to handle synchronous resets that
+// are enabled via the sc_process_handle::sync_reset_on() method. These
+// resets are not generated by a signal, but rather are modal by
+// method call: sync_reset_on() - sync_reset_off().
+//------------------------------------------------------------------------------
+inline void sc_thread_process::suspend_me()
+{
+ // remember, if we're currently unwinding
+
+ bool unwinding_preempted = m_unwinding;
+
+ sc_simcontext* simc_p = simcontext();
+ sc_cor* cor_p = simc_p->next_cor();
+
+ // do not switch, if we're about to execute next (e.g. suicide)
+
+ if( m_cor_p != cor_p )
+ {
+ DEBUG_MSG( DEBUG_NAME , this, "suspending thread");
+ simc_p->cor_pkg()->yield( cor_p );
+ DEBUG_MSG( DEBUG_NAME , this, "resuming thread");
+ }
+
+ // IF THERE IS A THROW TO BE DONE FOR THIS PROCESS DO IT NOW:
+ //
+ // (1) Optimize THROW_NONE for speed as it is the normal case.
+ // (2) If this thread is already unwinding then suspend_me() was
+ // called from the catch clause to throw an exception on another
+ // process, so just go back to the catch clause.
+
+ if ( m_throw_status == THROW_NONE ) return;
+
+ if ( m_unwinding ) return;
+
+ switch( m_throw_status )
+ {
+ case THROW_ASYNC_RESET:
+ case THROW_SYNC_RESET:
+ DEBUG_MSG( DEBUG_NAME , this, "throwing reset for");
+ if ( m_reset_event_p ) m_reset_event_p->notify();
+ throw sc_unwind_exception( this, true );
+
+ case THROW_USER:
+ DEBUG_MSG( DEBUG_NAME, this, "invoking throw_it for");
+ m_throw_status = m_active_areset_n ? THROW_ASYNC_RESET :
+ (m_active_reset_n ? THROW_SYNC_RESET :
+ THROW_NONE);
+ m_throw_helper_p->throw_it();
+ break;
+
+ case THROW_KILL:
+ DEBUG_MSG( DEBUG_NAME, this, "throwing kill for");
+ throw sc_unwind_exception( this, false );
+
+ default: // THROWING_NOW
+ sc_assert( unwinding_preempted );
+ DEBUG_MSG( DEBUG_NAME, this, "restarting thread");
+ break;
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::wait"
+//
+//------------------------------------------------------------------------------
+inline
+void
+sc_thread_process::wait( const sc_event& e )
+{
+ if( m_unwinding )
+ SC_REPORT_ERROR( SC_ID_WAIT_DURING_UNWINDING_, name() );
+
+ m_event_p = &e; // for cleanup.
+ e.add_dynamic( this );
+ m_trigger_type = EVENT;
+ suspend_me();
+}
+
+inline
+void
+sc_thread_process::wait( const sc_event_or_list& el )
+{
+ if( m_unwinding )
+ SC_REPORT_ERROR( SC_ID_WAIT_DURING_UNWINDING_, name() );
+
+ el.add_dynamic( this );
+ m_event_list_p = &el;
+ m_trigger_type = OR_LIST;
+ suspend_me();
+}
+
+inline
+void
+sc_thread_process::wait( const sc_event_and_list& el )
+{
+ if( m_unwinding )
+ SC_REPORT_ERROR( SC_ID_WAIT_DURING_UNWINDING_, name() );
+
+ el.add_dynamic( this );
+ m_event_list_p = &el;
+ m_event_count = el.size();
+ m_trigger_type = AND_LIST;
+ suspend_me();
+}
+
+inline
+void
+sc_thread_process::wait( const sc_time& t )
+{
+ if( m_unwinding )
+ SC_REPORT_ERROR( SC_ID_WAIT_DURING_UNWINDING_, name() );
+
+ m_timeout_event_p->notify_internal( t );
+ m_timeout_event_p->add_dynamic( this );
+ m_trigger_type = TIMEOUT;
+ suspend_me();
+}
+
+inline
+void
+sc_thread_process::wait( const sc_time& t, const sc_event& e )
+{
+ if( m_unwinding )
+ SC_REPORT_ERROR( SC_ID_WAIT_DURING_UNWINDING_, name() );
+
+ m_timeout_event_p->notify_internal( t );
+ m_timeout_event_p->add_dynamic( this );
+ e.add_dynamic( this );
+ m_event_p = &e;
+ m_trigger_type = EVENT_TIMEOUT;
+ suspend_me();
+}
+
+inline
+void
+sc_thread_process::wait( const sc_time& t, const sc_event_or_list& el )
+{
+ if( m_unwinding )
+ SC_REPORT_ERROR( SC_ID_WAIT_DURING_UNWINDING_, name() );
+
+ m_timeout_event_p->notify_internal( t );
+ m_timeout_event_p->add_dynamic( this );
+ el.add_dynamic( this );
+ m_event_list_p = &el;
+ m_trigger_type = OR_LIST_TIMEOUT;
+ suspend_me();
+}
+
+inline
+void
+sc_thread_process::wait( const sc_time& t, const sc_event_and_list& el )
+{
+ if( m_unwinding )
+ SC_REPORT_ERROR( SC_ID_WAIT_DURING_UNWINDING_, name() );
+
+ m_timeout_event_p->notify_internal( t );
+ m_timeout_event_p->add_dynamic( this );
+ el.add_dynamic( this );
+ m_event_list_p = &el;
+ m_event_count = el.size();
+ m_trigger_type = AND_LIST_TIMEOUT;
+ suspend_me();
+}
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::wait_cycles"
+//
+// This method suspends this object instance for the specified number of cycles.
+// A cycle is defined as the event the thread is set up to staticly wait on.
+// The field m_wait_cycle_n is set to one less than the number of cycles to
+// be waited for, since the value is tested before being decremented in
+// the simulation kernel.
+//------------------------------------------------------------------------------
+inline
+void
+sc_thread_process::wait_cycles( int n )
+{
+ if( m_unwinding )
+ SC_REPORT_ERROR( SC_ID_WAIT_DURING_UNWINDING_, name() );
+
+ m_wait_cycle_n = n-1;
+ suspend_me();
+}
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::miscellaneous support"
+//
+//------------------------------------------------------------------------------
+inline
+void sc_thread_process::add_monitor(sc_process_monitor* monitor_p)
+{
+ m_monitor_q.push_back(monitor_p);
+}
+
+
+inline
+void sc_thread_process::remove_monitor(sc_process_monitor* monitor_p)
+{
+ int mon_n = m_monitor_q.size();
+
+ for ( int mon_i = 0; mon_i < mon_n; mon_i++ )
+ {
+ if ( m_monitor_q[mon_i] == monitor_p )
+ {
+ m_monitor_q[mon_i] = m_monitor_q[mon_n-1];
+ m_monitor_q.resize(mon_n-1);
+ }
+ }
+}
+
+inline
+void sc_thread_process::set_next_exist(sc_thread_handle next_p)
+{
+ m_exist_p = next_p;
+}
+
+inline
+sc_thread_handle sc_thread_process::next_exist()
+{
+ return (sc_thread_handle)m_exist_p;
+}
+
+inline
+void sc_thread_process::set_next_runnable(sc_thread_handle next_p)
+{
+ m_runnable_p = next_p;
+}
+
+inline
+sc_thread_handle sc_thread_process::next_runnable()
+{
+ return (sc_thread_handle)m_runnable_p;
+}
+
+inline sc_cor* get_cor_pointer( sc_process_b* process_p )
+{
+ sc_thread_handle thread_p = DCAST<sc_thread_handle>(process_p);
+ return thread_p->m_cor_p;
+}
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::trigger_static"
+//
+// This inline method adds the current thread to the queue of runnable
+// processes, if required. This is the case if the following criteria
+// are met:
+// (1) The process is in a runnable state.
+// (2) The process is not already on the run queue.
+// (3) The process is expecting a static trigger,
+// dynamic event waits take priority.
+// (4) The process' static wait count is zero.
+//
+// If the triggering process is the same process, the trigger is
+// ignored as well, unless SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS
+// is defined.
+//------------------------------------------------------------------------------
+inline
+void
+sc_thread_process::trigger_static()
+{
+ // No need to try queueing this thread if one of the following is true:
+ // (a) its disabled
+ // (b) its already queued for execution
+ // (c) its waiting on a dynamic event
+ // (d) its wait count is not satisfied
+
+ if ( (m_state & ps_bit_disabled) || is_runnable() ||
+ m_trigger_type != STATIC )
+ return;
+
+#if ! defined( SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS )
+ if( SC_UNLIKELY_( sc_get_current_process_b() == this ) )
+ {
+ report_immediate_self_notification();
+ return;
+ }
+#endif // SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS
+
+ if ( m_wait_cycle_n > 0 )
+ {
+ --m_wait_cycle_n;
+ return;
+ }
+
+ // If we get here then the thread is has satisfied its wait criteria, if
+ // its suspended mark its state as ready to run. If its not suspended then
+ // push it onto the runnable queue.
+
+ if ( m_state & ps_bit_suspended )
+ {
+ m_state = m_state | ps_bit_ready_to_run;
+ }
+ else
+ {
+ simcontext()->push_runnable_thread(this);
+ }
+}
+
+#undef DEBUG_MSG
+#undef DEBUG_NAME
+
+} // namespace sc_core
+
+// $Log: sc_thread_process.h,v $
+// Revision 1.30 2011/08/26 20:46:11 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.29 2011/08/24 23:36:12 acg
+// Andy Goodrich: removed break statements that can never be reached and
+// which causes warnings in the Greenhills C++ compiler.
+//
+// Revision 1.28 2011/04/14 22:34:27 acg
+// Andy Goodrich: removed dead code.
+//
+// Revision 1.27 2011/04/13 05:02:18 acg
+// Andy Goodrich: added missing check to the wake up code in suspend_me()
+// so that we just return if the call to suspend_me() was issued from a
+// stack unwinding.
+//
+// Revision 1.26 2011/04/13 02:44:26 acg
+// Andy Goodrich: added m_unwinding flag in place of THROW_NOW because the
+// throw status will be set back to THROW_*_RESET if reset is active and
+// the check for an unwind being complete was expecting THROW_NONE as the
+// clearing of THROW_NOW.
+//
+// Revision 1.25 2011/04/11 22:05:14 acg
+// Andy Goodrich: use the DEBUG_NAME macro in DEBUG_MSG invocations.
+//
+// Revision 1.24 2011/04/10 22:12:32 acg
+// Andy Goodrich: adding debugging macros.
+//
+// Revision 1.23 2011/04/08 22:41:28 acg
+// Andy Goodrich: added comment pointing to the description of the reset
+// mechanism in sc_reset.cpp.
+//
+// Revision 1.22 2011/04/08 18:27:33 acg
+// Andy Goodrich: added check to make sure we don't schedule a running process
+// because of it issues a notify() it is sensitive to.
+//
+// Revision 1.21 2011/04/05 06:22:38 acg
+// Andy Goodrich: expanded comment for trigger_static() initial vetting.
+//
+// Revision 1.20 2011/04/01 21:24:57 acg
+// Andy Goodrich: removed unused code.
+//
+// Revision 1.19 2011/02/19 08:30:53 acg
+// Andy Goodrich: Moved process queueing into trigger_static from
+// sc_event::notify.
+//
+// Revision 1.18 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.17 2011/02/17 19:55:58 acg
+// Andy Goodrich:
+// (1) Changed signature of trigger_dynamic() back to a bool.
+// (2) Simplified process control usage.
+// (3) Changed trigger_static() to recognize process controls and to
+// do the down-count on wait(N), allowing the elimination of
+// ready_to_run().
+//
+// Revision 1.16 2011/02/16 22:37:31 acg
+// Andy Goodrich: clean up to remove need for ps_disable_pending.
+//
+// Revision 1.15 2011/02/13 21:47:38 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.14 2011/02/13 21:35:54 acg
+// Andy Goodrich: added error for performing a wait() during unwinding.
+//
+// Revision 1.13 2011/02/11 13:25:24 acg
+// Andy Goodrich: Philipp A. Hartmann's changes:
+// (1) Removal of SC_CTHREAD method overloads.
+// (2) New exception processing code.
+//
+// Revision 1.12 2011/02/01 23:01:53 acg
+// Andy Goodrich: removed dead code.
+//
+// Revision 1.11 2011/02/01 21:18:01 acg
+// Andy Goodrich:
+// (1) Changes in throw processing for new process control rules.
+// (2) Support of new process_state enum values.
+//
+// Revision 1.10 2011/01/25 20:50:37 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.9 2011/01/19 23:21:50 acg
+// Andy Goodrich: changes for IEEE 1666 2011
+//
+// Revision 1.8 2011/01/18 20:10:45 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.7 2011/01/06 17:59:58 acg
+// Andy Goodrich: removed debugging output.
+//
+// Revision 1.6 2010/07/22 20:02:33 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.5 2009/07/28 01:10:53 acg
+// Andy Goodrich: updates for 2.3 release candidate.
+//
+// Revision 1.4 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.3 2009/03/12 22:59:58 acg
+// Andy Goodrich: updates for 2.4 stuff.
+//
+// Revision 1.2 2008/05/22 17:06:06 acg
+// Andy Goodrich: formatting and comments.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.7 2006/05/08 17:57:13 acg
+// Andy Goodrich: Added David Long's forward declarations for friend functions
+// to keep the Microsoft C++ compiler happy.
+//
+// Revision 1.6 2006/04/20 17:08:17 acg
+// Andy Goodrich: 3.0 style process changes.
+//
+// Revision 1.5 2006/04/11 23:13:21 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.4 2006/01/24 20:49:05 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+#endif // !defined(sc_thread_process_h_INCLUDED)
diff --git a/ext/systemc/src/sysc/kernel/sc_time.cpp b/ext/systemc/src/sysc/kernel/sc_time.cpp
new file mode 100644
index 000000000..e3fdd5865
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_time.cpp
@@ -0,0 +1,465 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_time.cpp --
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#include <math.h>
+#include <stdio.h>
+
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_time.h"
+#include "sysc/utils/sc_utils_ids.h"
+
+#if !defined(PRIu64)
+# if defined(_MSC_VER) || defined(__MINGW32__)
+# define PRIu64 "I64u"
+# else
+# define PRIu64 "llu"
+# endif
+#endif // PRIu64
+
+#ifdef SC_ENABLE_EARLY_MAXTIME_CREATION
+# define SC_MAXTIME_ALLOWED_ 1
+#else
+# define SC_MAXTIME_ALLOWED_ 0
+#endif
+
+namespace sc_core {
+
+static
+double time_values[] = {
+ 1, // fs
+ 1e3, // ps
+ 1e6, // ns
+ 1e9, // us
+ 1e12, // ms
+ 1e15 // s
+};
+
+static
+const char* time_units[] = {
+ "fs",
+ "ps",
+ "ns",
+ "us",
+ "ms",
+ "s"
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_time
+//
+// The time class.
+// ----------------------------------------------------------------------------
+
+// constructors
+
+sc_time::sc_time( double v, sc_time_unit tu )
+: m_value( 0 )
+{
+ if( v != 0 ) {
+ sc_time_params* time_params = sc_get_curr_simcontext()->m_time_params;
+ double scale_fac = time_values[tu] / time_params->time_resolution;
+ // linux bug workaround; don't change next two lines
+ volatile double tmp = v * scale_fac + 0.5;
+ m_value = SCAST<sc_dt::int64>( tmp );
+ time_params->time_resolution_fixed = true;
+ }
+}
+
+sc_time::sc_time( double v, sc_time_unit tu, sc_simcontext* simc )
+: m_value( 0 )
+{
+ if( v != 0 ) {
+ sc_time_params* time_params = simc->m_time_params;
+ double scale_fac = time_values[tu] / time_params->time_resolution;
+ // linux bug workaround; don't change next two lines
+ volatile double tmp = v * scale_fac + 0.5;
+ m_value = SCAST<sc_dt::int64>( tmp );
+ time_params->time_resolution_fixed = true;
+ }
+}
+
+sc_time::sc_time( double v, bool scale )
+: m_value( 0 )
+{
+ static bool warn_constructor=true;
+ if ( warn_constructor ) {
+ warn_constructor=false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "deprecated constructor: sc_time(double,bool)");
+ }
+
+ if( v != 0 ) {
+ sc_time_params* time_params = sc_get_curr_simcontext()->m_time_params;
+ if( scale ) {
+ double scale_fac = sc_dt::uint64_to_double(
+ time_params->default_time_unit );
+ // linux bug workaround; don't change next two lines
+ volatile double tmp = v * scale_fac + 0.5;
+ m_value = SCAST<sc_dt::int64>( tmp );
+ } else {
+ // linux bug workaround; don't change next two lines
+ volatile double tmp = v + 0.5;
+ m_value = SCAST<sc_dt::int64>( tmp );
+ }
+ time_params->time_resolution_fixed = true;
+ }
+}
+
+sc_time::sc_time( value_type v, bool scale )
+: m_value( 0 )
+{
+ static bool warn_constructor=true;
+ if ( warn_constructor ) {
+ warn_constructor=false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "deprecated constructor: sc_time(uint64,bool)");
+ }
+
+ if( v != 0 ) {
+ sc_time_params* time_params = sc_get_curr_simcontext()->m_time_params;
+ if( scale ) {
+ double scale_fac = sc_dt::uint64_to_double(
+ time_params->default_time_unit );
+ // linux bug workaround; don't change next two lines
+ volatile double tmp = sc_dt::uint64_to_double( v ) *
+ scale_fac + 0.5;
+ m_value = SCAST<sc_dt::int64>( tmp );
+ } else {
+ m_value = v;
+ }
+ time_params->time_resolution_fixed = true;
+ }
+}
+
+sc_time
+sc_time::from_value( value_type v )
+{
+ sc_time t;
+ if( v != 0 && !(SC_MAXTIME_ALLOWED_ && v == ~sc_dt::UINT64_ZERO) ) {
+ sc_time_params* time_params = sc_get_curr_simcontext()->m_time_params;
+ time_params->time_resolution_fixed = true;
+ }
+ t.m_value = v;
+ return t;
+}
+
+
+// conversion functions
+
+double
+sc_time::to_default_time_units() const
+{
+ sc_time_params* time_params = sc_get_curr_simcontext()->m_time_params;
+# if SC_MAXTIME_ALLOWED_
+ if( m_value == 0 )
+ return 0.0;
+ time_params->time_resolution_fixed = true;
+# endif // SC_MAXTIME_ALLOWED_
+ return ( sc_dt::uint64_to_double( m_value ) /
+ sc_dt::uint64_to_double( time_params->default_time_unit ) );
+}
+
+double
+sc_time::to_seconds() const
+{
+ sc_time_params* time_params = sc_get_curr_simcontext()->m_time_params;
+# if SC_MAXTIME_ALLOWED_
+ if( m_value == 0 )
+ return 0.0;
+ time_params->time_resolution_fixed = true;
+# endif // SC_MAXTIME_ALLOWED_
+ return ( sc_dt::uint64_to_double( m_value ) *
+ time_params->time_resolution * 1e-15 );
+}
+
+const std::string
+sc_time::to_string() const
+{
+ value_type val = m_value;
+ if( val == 0 ) {
+ return std::string( "0 s" );
+ }
+ sc_time_params* time_params = sc_get_curr_simcontext()->m_time_params;
+# if SC_MAXTIME_ALLOWED_
+ time_params->time_resolution_fixed = true;
+# endif // SC_MAXTIME_ALLOWED_
+ value_type tr = SCAST<sc_dt::int64>( time_params->time_resolution );
+ int n = 0;
+ while( ( tr % 10 ) == 0 ) {
+ tr /= 10;
+ n ++;
+ }
+ assert( tr == 1 );
+ while( ( val % 10 ) == 0 ) {
+ val /= 10;
+ n ++;
+ }
+ char buf[BUFSIZ];
+ std::sprintf( buf, "%" PRIu64, val );
+ std::string result( buf );
+ if( n >= 15 ) {
+ for( int i = n - 15; i > 0; -- i ) {
+ result += "0";
+ }
+ result += " s";
+ } else {
+ for( int i = n % 3; i > 0; -- i ) {
+ result += "0";
+ }
+ result += " ";
+ result += time_units[n / 3];
+ }
+ return result;
+}
+
+
+// print function
+
+void
+sc_time::print( ::std::ostream& os ) const
+{
+ os << to_string();
+}
+
+
+// ----------------------------------------------------------------------------
+// STRUCT : sc_time_params
+//
+// Struct that holds the time resolution and default time unit.
+// ----------------------------------------------------------------------------
+
+sc_time_params::sc_time_params()
+: time_resolution( 1000 ), // default 1 ps
+ time_resolution_specified( false ),
+ time_resolution_fixed( false ),
+ default_time_unit( 1000 ), // default 1 ns
+ default_time_unit_specified( false )
+{}
+
+sc_time_params::~sc_time_params()
+{}
+
+
+// ----------------------------------------------------------------------------
+
+// functions for accessing the time resolution and default time unit
+
+void
+sc_set_time_resolution( double v, sc_time_unit tu )
+{
+ // first perform the necessary checks
+
+ // must be positive
+ if( v < 0.0 ) {
+ SC_REPORT_ERROR( SC_ID_SET_TIME_RESOLUTION_, "value not positive" );
+ }
+
+ // must be a power of ten
+ double dummy;
+#if defined( __HP_aCC ) || defined(__ppc__)
+ // aCC seems to have a bug in modf()
+ if( modf( log10( v < 1.0 ? 1.0/v : v ), &dummy ) != 0.0 ) {
+#else
+ if( modf( log10( v ), &dummy ) != 0.0 ) {
+#endif
+ SC_REPORT_ERROR( SC_ID_SET_TIME_RESOLUTION_,
+ "value not a power of ten" );
+ }
+
+ sc_simcontext* simc = sc_get_curr_simcontext();
+
+ // can only be specified during elaboration
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_SET_TIME_RESOLUTION_, "simulation running" );
+ }
+
+ sc_time_params* time_params = simc->m_time_params;
+
+ // can be specified only once
+ if( time_params->time_resolution_specified ) {
+ SC_REPORT_ERROR( SC_ID_SET_TIME_RESOLUTION_, "already specified" );
+ }
+
+ // can only be specified before any sc_time is constructed
+ if( time_params->time_resolution_fixed ) {
+ SC_REPORT_ERROR( SC_ID_SET_TIME_RESOLUTION_,
+ "sc_time object(s) constructed" );
+ }
+
+ // must be larger than or equal to 1 fs
+ volatile double resolution = v * time_values[tu];
+ if( resolution < 1.0 ) {
+ SC_REPORT_ERROR( SC_ID_SET_TIME_RESOLUTION_,
+ "value smaller than 1 fs" );
+ }
+
+ // recalculate the default time unit
+ volatile double time_unit = sc_dt::uint64_to_double(
+ time_params->default_time_unit ) *
+ ( time_params->time_resolution / resolution );
+ if( time_unit < 1.0 ) {
+ SC_REPORT_WARNING( SC_ID_DEFAULT_TIME_UNIT_CHANGED_, 0 );
+ time_params->default_time_unit = 1;
+ } else {
+ time_params->default_time_unit = SCAST<sc_dt::int64>( time_unit );
+ }
+
+ time_params->time_resolution = resolution;
+ time_params->time_resolution_specified = true;
+}
+
+sc_time
+sc_get_time_resolution()
+{
+ return sc_time::from_value( sc_dt::UINT64_ONE );
+}
+
+
+void
+sc_set_default_time_unit( double v, sc_time_unit tu )
+{
+ static bool warn_default_time_unit=true;
+ if ( warn_default_time_unit )
+ {
+ warn_default_time_unit=false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "deprecated function: sc_set_default_time_unit");
+ }
+
+ // first perform the necessary checks
+
+ // must be positive
+ if( v < 0.0 ) {
+ SC_REPORT_ERROR( SC_ID_SET_DEFAULT_TIME_UNIT_, "value not positive" );
+ }
+
+ // must be a power of ten
+ double dummy;
+ if( modf( log10( v ), &dummy ) != 0.0 ) {
+ SC_REPORT_ERROR( SC_ID_SET_DEFAULT_TIME_UNIT_,
+ "value not a power of ten" );
+ }
+
+ sc_simcontext* simc = sc_get_curr_simcontext();
+
+ // can only be specified during elaboration
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_SET_DEFAULT_TIME_UNIT_, "simulation running" );
+ }
+
+ sc_time_params* time_params = simc->m_time_params;
+
+ // can only be specified before any sc_time is constructed
+ if( time_params->time_resolution_fixed ) {
+ SC_REPORT_ERROR( SC_ID_SET_DEFAULT_TIME_UNIT_,
+ "sc_time object(s) constructed" );
+ }
+
+ // can be specified only once
+ if( time_params->default_time_unit_specified ) {
+ SC_REPORT_ERROR( SC_ID_SET_DEFAULT_TIME_UNIT_, "already specified" );
+ }
+
+ // must be larger than or equal to the time resolution
+ volatile double time_unit = ( v * time_values[tu] ) /
+ time_params->time_resolution;
+ if( time_unit < 1.0 ) {
+ SC_REPORT_ERROR( SC_ID_SET_DEFAULT_TIME_UNIT_,
+ "value smaller than time resolution" );
+ }
+
+ time_params->default_time_unit = SCAST<sc_dt::int64>( time_unit );
+ time_params->default_time_unit_specified = true;
+}
+
+sc_time
+sc_get_default_time_unit()
+{
+ static bool warn_get_default_time_unit = true;
+ if ( warn_get_default_time_unit )
+ {
+ warn_get_default_time_unit=false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "deprecated function: sc_get_default_time_unit");
+ }
+ return sc_time::from_value(
+ sc_get_curr_simcontext()->m_time_params->default_time_unit
+ );
+}
+
+
+// ----------------------------------------------------------------------------
+
+const sc_time SC_ZERO_TIME;
+
+#undef SC_MAXTIME_ALLOWED_
+
+} // namespace sc_core
+
+// $Log: sc_time.cpp,v $
+// Revision 1.7 2011/08/26 20:46:11 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.6 2011/07/24 16:08:36 acg
+// Philipp A. Hartmann: fix C99 format specifiers for Solaris.
+//
+// Revision 1.5 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.4 2011/02/13 21:47:38 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.3 2011/01/19 23:21:50 acg
+// Andy Goodrich: changes for IEEE 1666 2011
+//
+// Revision 1.2 2008/05/22 17:06:27 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.6 2006/01/26 21:04:55 acg
+// Andy Goodrich: deprecation message changes and additional messages.
+//
+// Revision 1.5 2006/01/25 00:31:19 acg
+// Andy Goodrich: Changed over to use a standard message id of
+// SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
+//
+// Revision 1.4 2006/01/24 20:49:05 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+//
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_time.h b/ext/systemc/src/sysc/kernel/sc_time.h
new file mode 100644
index 000000000..af222dd0f
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_time.h
@@ -0,0 +1,414 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_time.h -- The time class.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_TIME_H
+#define SC_TIME_H
+
+
+#include "sysc/datatypes/int/sc_nbdefs.h"
+#include "sysc/datatypes/fx/scfx_ieee.h"
+#include "sysc/utils/sc_iostream.h"
+
+namespace sc_core {
+
+class sc_simcontext;
+
+// friend operator declarations
+
+ const sc_time operator + ( const sc_time&, const sc_time& );
+ const sc_time operator - ( const sc_time&, const sc_time& );
+ const sc_time operator * ( const sc_time&, double );
+ const sc_time operator * ( double, const sc_time& );
+ const sc_time operator / ( const sc_time&, double );
+ double operator / ( const sc_time&, const sc_time& );
+
+
+// ----------------------------------------------------------------------------
+// ENUM : sc_time_unit
+//
+// Enumeration of time units.
+// ----------------------------------------------------------------------------
+
+enum sc_time_unit
+{
+ SC_FS = 0,
+ SC_PS,
+ SC_NS,
+ SC_US,
+ SC_MS,
+ SC_SEC
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_time
+//
+// The time class.
+// ----------------------------------------------------------------------------
+
+class sc_time
+{
+public:
+
+ typedef sc_dt::uint64 value_type;
+
+ // constructors
+
+ sc_time();
+ sc_time( double, sc_time_unit );
+ sc_time( double, sc_time_unit, sc_simcontext* );
+ sc_time( const sc_time& );
+
+ static sc_time from_value( value_type );
+
+ // deprecated, use from_value(v)
+ sc_time( double, bool scale );
+ sc_time( value_type, bool scale );
+
+ // assignment operator
+
+ sc_time& operator = ( const sc_time& );
+
+
+ // conversion functions
+
+ value_type value() const; // relative to the time resolution
+ double to_double() const; // relative to the time resolution
+ double to_default_time_units() const;
+ double to_seconds() const;
+ const std::string to_string() const;
+
+
+ // relational operators
+
+ bool operator == ( const sc_time& ) const;
+ bool operator != ( const sc_time& ) const;
+ bool operator < ( const sc_time& ) const;
+ bool operator <= ( const sc_time& ) const;
+ bool operator > ( const sc_time& ) const;
+ bool operator >= ( const sc_time& ) const;
+
+
+ // arithmetic operators
+
+ sc_time& operator += ( const sc_time& );
+ sc_time& operator -= ( const sc_time& );
+
+ friend const sc_time operator + ( const sc_time&, const sc_time& );
+ friend const sc_time operator - ( const sc_time&, const sc_time& );
+
+ sc_time& operator *= ( double );
+ sc_time& operator /= ( double );
+ sc_time& operator %= ( const sc_time& );
+
+ friend const sc_time operator * ( const sc_time&, double );
+ friend const sc_time operator * ( double, const sc_time& );
+ friend const sc_time operator / ( const sc_time&, double );
+ friend double operator / ( const sc_time&, const sc_time& );
+ friend const sc_time operator % ( const sc_time&, const sc_time& );
+
+
+ // print function
+
+ void print( ::std::ostream& os = std::cout ) const;
+
+private:
+
+ value_type m_value;
+};
+
+
+// print operator
+
+inline ::std::ostream& operator << ( ::std::ostream&, const sc_time& );
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+// constructors
+
+inline
+sc_time::sc_time()
+: m_value( 0 )
+{}
+
+inline
+sc_time::sc_time( const sc_time& t )
+: m_value( t.m_value )
+{}
+
+
+// assignment operator
+
+inline
+sc_time&
+sc_time::operator = ( const sc_time& t )
+{
+ m_value = t.m_value;
+ return *this;
+}
+
+
+// conversion functions
+
+inline
+sc_time::value_type
+sc_time::value() const // relative to the time resolution
+{
+ return m_value;
+}
+
+
+inline
+double
+sc_time::to_double() const // relative to the time resolution
+{
+ return sc_dt::uint64_to_double( m_value );
+}
+
+
+// relational operators
+
+inline
+bool
+sc_time::operator == ( const sc_time& t ) const
+{
+ return ( m_value == t.m_value );
+}
+
+inline
+bool
+sc_time::operator != ( const sc_time& t ) const
+{
+ return ( m_value != t.m_value );
+}
+
+inline
+bool
+sc_time::operator < ( const sc_time& t ) const
+{
+ return ( m_value < t.m_value );
+}
+
+inline
+bool
+sc_time::operator <= ( const sc_time& t ) const
+{
+ return ( m_value <= t.m_value );
+}
+
+inline
+bool
+sc_time::operator > ( const sc_time& t ) const
+{
+ return ( m_value > t.m_value );
+}
+
+inline
+bool
+sc_time::operator >= ( const sc_time& t ) const
+{
+ return ( m_value >= t.m_value );
+}
+
+
+// arithmetic operators
+
+inline
+sc_time&
+sc_time::operator += ( const sc_time& t )
+{
+ m_value += t.m_value;
+ return *this;
+}
+
+inline
+sc_time&
+sc_time::operator -= ( const sc_time& t )
+{
+ m_value -= t.m_value;
+ return *this;
+}
+
+
+inline
+const sc_time
+operator + ( const sc_time& t1, const sc_time& t2 )
+{
+ return sc_time( t1 ) += t2;
+}
+
+inline
+const sc_time
+operator - ( const sc_time& t1, const sc_time& t2 )
+{
+ return sc_time( t1 ) -= t2;
+}
+
+
+inline
+sc_time&
+sc_time::operator *= ( double d )
+{
+ // linux bug workaround; don't change next two lines
+ volatile double tmp = sc_dt::uint64_to_double( m_value ) * d + 0.5;
+ m_value = SCAST<sc_dt::int64>( tmp );
+ return *this;
+}
+
+inline
+sc_time&
+sc_time::operator /= ( double d )
+{
+ // linux bug workaround; don't change next two lines
+ volatile double tmp = sc_dt::uint64_to_double( m_value ) / d + 0.5;
+ m_value = SCAST<sc_dt::int64>( tmp );
+ return *this;
+}
+
+inline
+sc_time&
+sc_time::operator %= ( const sc_time& t )
+{
+ m_value %= t.m_value;
+ return *this;
+}
+
+inline
+const sc_time
+operator * ( const sc_time& t, double d )
+{
+ sc_time tmp( t );
+ return tmp *= d;
+}
+
+inline
+const sc_time
+operator * ( double d, const sc_time& t )
+{
+ sc_time tmp( t );
+ return tmp *= d;
+}
+
+inline
+const sc_time
+operator / ( const sc_time& t, double d )
+{
+ sc_time tmp( t );
+ return tmp /= d;
+}
+
+inline
+double
+operator / ( const sc_time& t1, const sc_time& t2 )
+{
+ return ( t1.to_double() / t2.to_double() );
+}
+
+inline
+const sc_time
+operator % ( const sc_time& t1, const sc_time& t2 )
+{
+ sc_time tmp(t1);
+ return tmp %= t2;
+}
+
+// print operator
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, const sc_time& t )
+{
+ t.print( os );
+ return os;
+}
+
+
+// ----------------------------------------------------------------------------
+// STRUCT : sc_time_params
+//
+// Struct that holds the time resolution and default time unit.
+// ----------------------------------------------------------------------------
+
+struct sc_time_params
+{
+ double time_resolution; // in femto seconds
+ bool time_resolution_specified;
+ bool time_resolution_fixed;
+
+ sc_time::value_type default_time_unit; // in time resolution
+ bool default_time_unit_specified;
+
+ sc_time_params();
+ ~sc_time_params();
+};
+
+
+// ----------------------------------------------------------------------------
+
+extern const sc_time SC_ZERO_TIME;
+
+
+// functions for accessing the time resolution and default time unit
+
+extern void sc_set_time_resolution( double, sc_time_unit );
+extern sc_time sc_get_time_resolution();
+
+extern void sc_set_default_time_unit( double, sc_time_unit );
+extern sc_time sc_get_default_time_unit();
+
+} // namespace sc_core
+
+#endif
+
+// $Log: sc_time.h,v $
+// Revision 1.5 2011/08/26 20:46:11 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:38 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.2 2008/05/22 17:06:27 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.4 2006/05/08 18:02:06 acg
+// Andy Goodrich: added David Long's forward declarations for friend
+// functions, methods, and operators to keep the Microsoft compiler happy.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_ver.cpp b/ext/systemc/src/sysc/kernel/sc_ver.cpp
new file mode 100644
index 000000000..9883cd3bc
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_ver.cpp
@@ -0,0 +1,228 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_ver.cpp -- copyright information.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include <cstddef>
+#include <cstdlib>
+
+#define SC_DISABLE_API_VERSION_CHECK // for in-library sc_ver.h inclusion
+
+#include "sysc/kernel/sc_ver.h"
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/utils/sc_iostream.h"
+#include "sysc/utils/sc_report.h"
+
+using std::getenv;
+using std::strcmp;
+using std::cerr;
+using std::endl;
+
+namespace sc_core {
+
+
+static
+const char systemc_version[] =
+ "SystemC " SC_VERSION " --- " __DATE__ " " __TIME__;
+
+const unsigned int sc_version_major = SC_VERSION_MAJOR;
+const unsigned int sc_version_minor = SC_VERSION_MINOR;
+const unsigned int sc_version_patch = SC_VERSION_PATCH;
+const bool sc_is_prerelease = SC_IS_PRERELEASE;
+
+const std::string sc_version_originator = SC_VERSION_ORIGINATOR;
+const std::string sc_version_release_date = SC_VERSION_RELEASE_DATE;
+const std::string sc_version_prerelease = SC_VERSION_PRERELEASE;
+const std::string sc_version_string = SC_VERSION;
+const std::string sc_copyright_string = SC_COPYRIGHT;
+
+const char*
+sc_copyright()
+{
+ return SC_COPYRIGHT;
+}
+
+
+const char*
+sc_release()
+{
+ return SC_VERSION;
+}
+
+
+const char*
+sc_version()
+{
+ return systemc_version;
+}
+
+
+#if !defined(SC_DISABLE_COPYRIGHT_MESSAGE)
+# define SC_DISABLE_COPYRIGHT_MESSAGE 0
+#endif
+
+// ----------------------------------------------------------------------------
+
+void
+pln()
+{
+ static bool lnp = SC_DISABLE_COPYRIGHT_MESSAGE;
+ if ( lnp || getenv("SYSTEMC_DISABLE_COPYRIGHT_MESSAGE") != 0 )
+ lnp = true;
+ if ( const char * lnp_env = getenv("SC_COPYRIGHT_MESSAGE") ) {
+ lnp = !strcmp( lnp_env, "DISABLE" );
+ }
+ if( ! lnp ) {
+
+ static const char indent[] = " ";
+ std::string line;
+ std::stringstream copyright;
+
+ // temporary stream to print copyright line-wise with indentation
+ copyright << sc_copyright();
+
+ cerr << endl;
+ cerr << indent << sc_version() << endl;
+ while( getline( copyright, line ) )
+ cerr << indent << line << endl;
+
+ // regressions check point
+
+ if( getenv( "SYSTEMC_REGRESSION" ) != 0 ) {
+ cerr << "SystemC Simulation" << endl;
+ }
+
+ lnp = true;
+ }
+}
+
+#define SC_API_PERFORM_CHECK_( Type, Name, Symbol ) \
+ do { \
+ static bool SC_CONCAT_UNDERSCORE_( Name, config_seen ) = false; \
+ static Type SC_CONCAT_UNDERSCORE_( Name, config ); \
+ if( ! SC_CONCAT_UNDERSCORE_( Name, config_seen ) ) { \
+ SC_CONCAT_UNDERSCORE_( Name, config_seen ) = true; \
+ SC_CONCAT_UNDERSCORE_( Name, config ) = Name; \
+ } else if( SC_CONCAT_UNDERSCORE_( Name, config ) != Name ) { \
+ SC_REPORT_FATAL( SC_ID_INCONSISTENT_API_CONFIG_, Symbol ); \
+ } \
+ } while( false )
+
+// THIS CONSTRUCTOR ROOTS OUT OLD OBJECTS AT LINK TIME
+//
+// Each source file which includes sc_ver.h for this SystemC version
+// will have a static instance of the class sc_api_version_XXX defined
+// in it. That object instanciation will cause the constructor below
+// to be invoked. If the version of the SystemC being linked against
+// does not contain the constructor below a linkage error will occur.
+//
+// Some preprocessor switches need to be consistent between the application
+// and the library (e.g. if sizes of classes are affected or other parts of
+// the ABI are affected). (Some of) these are checked here at link-time as
+// well, by setting template parameters to sc_api_version_XXX, while only
+// one variant is defined here.
+//
+// Some preprocessor switches need to be consistent between different
+// translation units of an application. Those can't be easily checked
+// during link-time. Instead, perform a check during run-time by
+// passing the value to the constructor of the api_version_check object.
+
+// const int DEBUG_SYSTEMC_CHECK_ = 1;
+const int SC_DISABLE_VIRTUAL_BIND_CHECK_ = 1;
+
+template<>
+SC_API_VERSION_STRING
+<
+// & DEBUG_SYSTEMC_CHECK_,
+ & SC_DISABLE_VIRTUAL_BIND_CHECK_
+>
+::SC_API_VERSION_STRING
+(
+ sc_writer_policy default_writer_policy
+)
+{
+ SC_API_PERFORM_CHECK_( sc_writer_policy
+ , default_writer_policy
+ , "SC_DEFAULT_WRITER_POLICY" );
+}
+
+} // namespace sc_core
+
+// $Log: sc_ver.cpp,v $
+// Revision 1.14 2011/08/26 21:56:55 acg
+// Torsten Maehne: use usings rather than absolute namespace addressing.
+//
+// Revision 1.13 2011/08/26 20:46:11 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.12 2011/07/25 10:20:34 acg
+// Andy Goodrich: check in aftermath of call to automake.
+//
+// Revision 1.11 2011/07/02 12:55:19 acg
+// Andy Goodrich: automake refresh.
+//
+// Revision 1.10 2011/07/01 18:49:07 acg
+// Andy Goodrich: moved pln() from sc_simcontext.cpp to sc_ver.cpp.
+//
+// Revision 1.9 2011/07/01 18:33:08 acg
+// Andy Goodrich: changes for IEEE 1666, removal of macros and use of them.
+//
+// Revision 1.8 2011/04/08 18:27:53 acg
+// Andy Goodrich: respin of the PoC.
+//
+// Revision 1.7 2011/04/05 20:50:57 acg
+// Andy Goodrich:
+// (1) changes to make sure that event(), posedge() and negedge() only
+// return true if the clock has not moved.
+// (2) fixes for method self-resumes.
+// (3) added SC_PRERELEASE_VERSION
+// (4) removed kernel events from the object hierarchy, added
+// sc_hierarchy_name_exists().
+//
+// Revision 1.6 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.5 2011/02/13 21:47:38 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.4 2011/01/18 20:10:45 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.3 2010/11/20 17:10:57 acg
+// Andy Goodrich: reset processing changes for new IEEE 1666 standard.
+//
+// Revision 1.2 2008/05/22 17:06:27 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+//
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_ver.h b/ext/systemc/src/sysc/kernel/sc_ver.h
new file mode 100644
index 000000000..34112f9f8
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_ver.h
@@ -0,0 +1,186 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_ver.h -- Version and copyright information.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ NO AUTOMATIC CHANGE LOG IS GENERATED, EXPLICIT CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+
+#ifndef SC_VER_H
+#define SC_VER_H
+
+#include "sysc/kernel/sc_macros.h" // SC_CONCAT_UNDERSCORE_
+ // SC_STRINGIFY_HELPER_
+#include "sysc/communication/sc_writer_policy.h" // SC_DEFAULT_WRITER_POLICY
+
+#include <string>
+
+namespace sc_core {
+
+extern const char* sc_copyright();
+extern const char* sc_release();
+extern const char* sc_version();
+
+extern const unsigned int sc_version_major;
+extern const unsigned int sc_version_minor;
+extern const unsigned int sc_version_patch;
+
+extern const std::string sc_version_originator;
+extern const std::string sc_version_release_date;
+extern const std::string sc_version_prerelease;
+extern const bool sc_is_prerelease;
+extern const std::string sc_version_string;
+extern const std::string sc_copyright_string;
+
+#define SYSTEMC_2_3_1
+
+#define SYSTEMC_VERSION 20140417
+#define SC_VERSION_ORIGINATOR "Accellera"
+#define SC_VERSION_MAJOR 2
+#define SC_VERSION_MINOR 3
+#define SC_VERSION_PATCH 1
+#define SC_IS_PRERELEASE 0
+
+/// compliancy with IEEE 1666-2011 (see 8.6.5)
+#define IEEE_1666_SYSTEMC 201101L
+
+#define SC_COPYRIGHT \
+ "Copyright (c) 1996-2014 by all Contributors,\n" \
+ "ALL RIGHTS RESERVED\n"
+
+
+#define SC_VERSION_RELEASE_DATE \
+ SC_STRINGIFY_HELPER_( SYSTEMC_VERSION )
+
+#if ( SC_IS_PRERELEASE == 1 )
+# define SC_VERSION_PRERELEASE "pub_rev"
+# define SC_VERSION \
+ SC_STRINGIFY_HELPER_( SC_VERSION_MAJOR.SC_VERSION_MINOR.SC_VERSION_PATCH ) \
+ "_" SC_VERSION_PRERELEASE "_" SC_VERSION_RELEASE_DATE \
+ "-" SC_VERSION_ORIGINATOR
+#else
+# define SC_VERSION_PRERELEASE "" // nothing
+# define SC_VERSION \
+ SC_STRINGIFY_HELPER_( SC_VERSION_MAJOR.SC_VERSION_MINOR.SC_VERSION_PATCH ) \
+ "-" SC_VERSION_ORIGINATOR
+#endif
+
+// THIS CLASS AND STATIC INSTANCE BELOW DETECTS BAD REV OBJECTS AT LINK TIME
+//
+// Each source file which includes this file for the current SystemC version
+// will have a static instance of the class sc_api_version_XXX defined
+// in it. That object instance will cause the constructor below
+// to be invoked. If the version of the SystemC being linked against
+// does not contain the constructor below a linkage error will occur.
+
+#define SC_API_VERSION_STRING \
+ SC_CONCAT_UNDERSCORE_( sc_api_version, \
+ SC_CONCAT_UNDERSCORE_( SC_VERSION_MAJOR, \
+ SC_CONCAT_UNDERSCORE_( SC_VERSION_MINOR, \
+ SC_VERSION_PATCH ) ) )
+
+// explicitly avoid macro expansion
+#define SC_API_DEFINED_( Symbol ) \
+ Symbol ## _DEFINED_
+#define SC_API_UNDEFINED_( Symbol ) \
+ Symbol ## _UNDEFINED_
+
+// Some preprocessor switches need to be consistent between the application
+// and the library (e.g. if sizes of classes are affected or other parts of
+// the ABI are affected). (Some of) these are checked here at link-time as
+// well, by setting template parameters to sc_api_version_XXX, while only
+// one variant is defined in sc_ver.cpp.
+
+#if 0 // don't enforce check of DEBUG_SYSTEMC for now
+// DEBUG_SYSTEMC
+#if defined( DEBUG_SYSTEMC )
+# define DEBUG_SYSTEMC_CHECK_ \
+ SC_CONFIG_DEFINED_(DEBUG_SYSTEMC)
+#else
+# define DEBUG_SYSTEMC_CHECK_ \
+ SC_CONFIG_UNDEFINED_(DEBUG_SYSTEMC)
+#endif
+extern const int DEBUG_SYSTEMC_CHECK_;
+#endif
+
+// SC_DISABLE_VIRTUAL_BIND
+#if defined( SC_DISABLE_VIRTUAL_BIND )
+# define SC_DISABLE_VIRTUAL_BIND_CHECK_ \
+ SC_API_DEFINED_(SC_DISABLE_VIRTUAL_BIND)
+#else
+# define SC_DISABLE_VIRTUAL_BIND_CHECK_ \
+ SC_API_UNDEFINED_(SC_DISABLE_VIRTUAL_BIND)
+#endif
+extern const int SC_DISABLE_VIRTUAL_BIND_CHECK_;
+
+// Some preprocessor switches need to be consistent between different
+// translation units of an application. Those can't be easily checked
+// during link-time. Instead, perform a check during run-time by
+// passing the value to the constructor of the api_version_check object.
+
+// Note: Template and constructor parameters are not passed as default
+// values to avoid ODR violations in the check itself.
+
+template // use pointers for more verbose error messages
+<
+// const int * DebugSystemC,
+ const int * DisableVirtualBind
+>
+struct SC_API_VERSION_STRING
+{
+ SC_API_VERSION_STRING
+ (
+ // SC_DEFAULT_WRITER_POLICY
+ sc_writer_policy default_writer_policy
+ );
+};
+
+#if !defined( SC_DISABLE_API_VERSION_CHECK ) // disabled in sc_ver.cpp
+static
+SC_API_VERSION_STRING
+<
+// & DEBUG_SYSTEMC_CHECK_,
+ & SC_DISABLE_VIRTUAL_BIND_CHECK_
+>
+api_version_check
+(
+ SC_DEFAULT_WRITER_POLICY
+);
+#endif // SC_DISABLE_API_VERSION_CHECK
+
+//#undef SC_API_DEFINED_
+//#undef SC_API_UNDEFINED_
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+#endif
diff --git a/ext/systemc/src/sysc/kernel/sc_wait.cpp b/ext/systemc/src/sysc/kernel/sc_wait.cpp
new file mode 100644
index 000000000..9c9f2bdfb
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_wait.cpp
@@ -0,0 +1,446 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_wait.cpp -- Wait() and related functions.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+ Martin Janssen, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#include "sysc/kernel/sc_except.h"
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/kernel/sc_cthread_process.h"
+#include "sysc/kernel/sc_thread_process.h"
+#include "sysc/kernel/sc_simcontext_int.h"
+#include "sysc/kernel/sc_wait.h"
+#include "sysc/utils/sc_utils_ids.h"
+
+namespace sc_core {
+
+// static sensitivity for SC_THREADs and SC_CTHREADs
+
+void warn_cthread_wait()
+{
+ static bool warn_wait = true;
+ if ( warn_wait )
+ {
+ warn_wait = false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "all waits except wait() and wait(N)\n" \
+ " are deprecated for SC_CTHREAD, " \
+ "use an SC_THREAD instead");
+ }
+}
+
+void
+wait( sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ switch( cpi->kind ) {
+ case SC_THREAD_PROC_:
+ case SC_CTHREAD_PROC_: {
+ RCAST<sc_cthread_handle>( cpi->process_handle )->wait_cycles();
+ break;
+ }
+ default:
+ SC_REPORT_ERROR( SC_ID_WAIT_NOT_ALLOWED_, "\n "
+ "in SC_METHODs use next_trigger() instead" );
+ break;
+ }
+}
+
+// dynamic sensitivity for SC_THREADs and SC_CTHREADs
+
+void
+wait( const sc_event& e, sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ switch( cpi->kind ) {
+ case SC_THREAD_PROC_: {
+ RCAST<sc_thread_handle>( cpi->process_handle )->wait( e );
+ break;
+ }
+ case SC_CTHREAD_PROC_: {
+ warn_cthread_wait();
+ sc_cthread_handle cthread_h =
+ RCAST<sc_cthread_handle>( cpi->process_handle );
+ cthread_h->wait( e );
+ cthread_h->wait_cycles();
+ break;
+ }
+ default:
+ SC_REPORT_ERROR( SC_ID_WAIT_NOT_ALLOWED_, "\n "
+ "in SC_METHODs use next_trigger() instead" );
+ break;
+ }
+}
+
+void
+wait( const sc_event_or_list& el, sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ switch( cpi->kind ) {
+ case SC_THREAD_PROC_: {
+ RCAST<sc_thread_handle>( cpi->process_handle )->wait( el );
+ break;
+ }
+ case SC_CTHREAD_PROC_: {
+ warn_cthread_wait();
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "wait(event_list) is deprecated for SC_CTHREAD, use SC_THREAD");
+ sc_cthread_handle cthread_h =
+ RCAST<sc_cthread_handle>( cpi->process_handle );
+ cthread_h->wait( el );
+ cthread_h->wait_cycles();
+ break;
+ }
+ default:
+ SC_REPORT_ERROR( SC_ID_WAIT_NOT_ALLOWED_, "\n "
+ "in SC_METHODs use next_trigger() instead" );
+ break;
+ }
+}
+
+void
+wait( const sc_event_and_list& el, sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ switch( cpi->kind ) {
+ case SC_THREAD_PROC_: {
+ RCAST<sc_thread_handle>( cpi->process_handle )->wait( el );
+ break;
+ }
+ case SC_CTHREAD_PROC_: {
+ warn_cthread_wait();
+ sc_cthread_handle cthread_h =
+ RCAST<sc_cthread_handle>( cpi->process_handle );
+ cthread_h->wait( el );
+ cthread_h->wait_cycles();
+ break;
+ }
+ default:
+ SC_REPORT_ERROR( SC_ID_WAIT_NOT_ALLOWED_, "\n "
+ "in SC_METHODs use next_trigger() instead" );
+ break;
+ }
+}
+
+void
+wait( const sc_time& t, sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ switch( cpi->kind ) {
+ case SC_THREAD_PROC_: {
+ RCAST<sc_thread_handle>( cpi->process_handle )->wait( t );
+ break;
+ }
+ case SC_CTHREAD_PROC_: {
+ warn_cthread_wait();
+ sc_cthread_handle cthread_h =
+ RCAST<sc_cthread_handle>( cpi->process_handle );
+ cthread_h->wait( t );
+ cthread_h->wait_cycles();
+ break;
+ }
+ default:
+ SC_REPORT_ERROR( SC_ID_WAIT_NOT_ALLOWED_, "\n "
+ "in SC_METHODs use next_trigger() instead" );
+ break;
+ }
+}
+
+void
+wait( const sc_time& t, const sc_event& e, sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ switch( cpi->kind ) {
+ case SC_THREAD_PROC_: {
+ RCAST<sc_thread_handle>( cpi->process_handle )->wait( t, e );
+ break;
+ }
+ case SC_CTHREAD_PROC_: {
+ warn_cthread_wait();
+ sc_cthread_handle cthread_h =
+ RCAST<sc_cthread_handle>( cpi->process_handle );
+ cthread_h->wait( t, e );
+ cthread_h->wait_cycles();
+ break;
+ }
+ default:
+ SC_REPORT_ERROR( SC_ID_WAIT_NOT_ALLOWED_, "\n "
+ "in SC_METHODs use next_trigger() instead" );
+ break;
+ }
+}
+
+void
+wait( const sc_time& t, const sc_event_or_list& el, sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ switch( cpi->kind ) {
+ case SC_THREAD_PROC_: {
+ RCAST<sc_thread_handle>( cpi->process_handle )->wait( t, el );
+ break;
+ }
+ case SC_CTHREAD_PROC_: {
+ warn_cthread_wait();
+ sc_cthread_handle cthread_h =
+ RCAST<sc_cthread_handle>( cpi->process_handle );
+ cthread_h->wait( t, el );
+ cthread_h->wait_cycles();
+ break;
+ }
+ default:
+ SC_REPORT_ERROR( SC_ID_WAIT_NOT_ALLOWED_, "\n "
+ "in SC_METHODs use next_trigger() instead" );
+ break;
+ }
+}
+
+void
+wait( const sc_time& t, const sc_event_and_list& el, sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ switch( cpi->kind ) {
+ case SC_THREAD_PROC_: {
+ RCAST<sc_thread_handle>( cpi->process_handle )->wait( t, el );
+ break;
+ }
+ case SC_CTHREAD_PROC_: {
+ warn_cthread_wait();
+ sc_cthread_handle cthread_h =
+ RCAST<sc_cthread_handle>( cpi->process_handle );
+ cthread_h->wait( t, el );
+ cthread_h->wait_cycles();
+ break;
+ }
+ default:
+ SC_REPORT_ERROR( SC_ID_WAIT_NOT_ALLOWED_, "\n "
+ "in SC_METHODs use next_trigger() instead" );
+ break;
+ }
+}
+
+
+// static sensitivity for SC_METHODs
+
+void
+next_trigger( sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ if( cpi->kind == SC_METHOD_PROC_ ) {
+ RCAST<sc_method_handle>( cpi->process_handle )->clear_trigger();
+ } else {
+ SC_REPORT_ERROR( SC_ID_NEXT_TRIGGER_NOT_ALLOWED_, "\n "
+ "in SC_THREADs and SC_CTHREADs use wait() instead" );
+ }
+}
+
+
+// dynamic sensitivity for SC_METHODs
+
+void
+next_trigger( const sc_event& e, sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ if( cpi->kind == SC_METHOD_PROC_ ) {
+ RCAST<sc_method_handle>( cpi->process_handle )->next_trigger( e );
+ } else {
+ SC_REPORT_ERROR( SC_ID_NEXT_TRIGGER_NOT_ALLOWED_, "\n "
+ "in SC_THREADs and SC_CTHREADs use wait() instead" );
+ }
+}
+
+void
+next_trigger( const sc_event_or_list& el, sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ if( cpi->kind == SC_METHOD_PROC_ ) {
+ RCAST<sc_method_handle>( cpi->process_handle )->next_trigger( el );
+ } else {
+ SC_REPORT_ERROR( SC_ID_NEXT_TRIGGER_NOT_ALLOWED_, "\n "
+ "in SC_THREADs and SC_CTHREADs use wait() instead" );
+ }
+}
+
+void
+next_trigger( const sc_event_and_list& el, sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ if( cpi->kind == SC_METHOD_PROC_ ) {
+ RCAST<sc_method_handle>( cpi->process_handle )->next_trigger( el );
+ } else {
+ SC_REPORT_ERROR( SC_ID_NEXT_TRIGGER_NOT_ALLOWED_, "\n "
+ "in SC_THREADs and SC_CTHREADs use wait() instead" );
+ }
+}
+
+void
+next_trigger( const sc_time& t, sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ if( cpi->kind == SC_METHOD_PROC_ ) {
+ RCAST<sc_method_handle>( cpi->process_handle )->next_trigger( t );
+ } else {
+ SC_REPORT_ERROR( SC_ID_NEXT_TRIGGER_NOT_ALLOWED_, "\n "
+ "in SC_THREADs and SC_CTHREADs use wait() instead" );
+ }
+}
+
+void
+next_trigger( const sc_time& t, const sc_event& e, sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ if( cpi->kind == SC_METHOD_PROC_ ) {
+ RCAST<sc_method_handle>( cpi->process_handle )->next_trigger( t, e );
+ } else {
+ SC_REPORT_ERROR( SC_ID_NEXT_TRIGGER_NOT_ALLOWED_, "\n "
+ "in SC_THREADs and SC_CTHREADs use wait() instead" );
+ }
+}
+
+void
+next_trigger( const sc_time& t, const sc_event_or_list& el, sc_simcontext* simc)
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ if( cpi->kind == SC_METHOD_PROC_ ) {
+ RCAST<sc_method_handle>( cpi->process_handle )->next_trigger( t, el );
+ } else {
+ SC_REPORT_ERROR( SC_ID_NEXT_TRIGGER_NOT_ALLOWED_, "\n "
+ "in SC_THREADs and SC_CTHREADs use wait() instead" );
+ }
+}
+
+void
+next_trigger(const sc_time& t, const sc_event_and_list& el, sc_simcontext* simc)
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ if( cpi->kind == SC_METHOD_PROC_ ) {
+ RCAST<sc_method_handle>( cpi->process_handle )->next_trigger( t, el );
+ } else {
+ SC_REPORT_ERROR( SC_ID_NEXT_TRIGGER_NOT_ALLOWED_, "\n "
+ "in SC_THREADs and SC_CTHREADs use wait() instead" );
+ }
+}
+
+
+// for SC_METHODs and SC_THREADs and SC_CTHREADs
+
+bool
+timed_out( sc_simcontext* simc )
+{
+ static bool warn_timed_out=true;
+ if ( warn_timed_out )
+ {
+ warn_timed_out = false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "timed_out() function is deprecated" );
+ }
+
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ return cpi->process_handle->timed_out();
+}
+
+
+
+// misc.
+
+void
+sc_set_location( const char* file, int lineno, sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ sc_process_b* handle = cpi->process_handle;
+ handle->file = file;
+ handle->lineno = lineno;
+}
+
+} // namespace sc_core
+
+/*
+$Log: sc_wait.cpp,v $
+Revision 1.6 2011/08/26 20:46:11 acg
+ Andy Goodrich: moved the modification log to the end of the file to
+ eliminate source line number skew when check-ins are done.
+
+Revision 1.5 2011/02/18 20:27:14 acg
+ Andy Goodrich: Updated Copyrights.
+
+Revision 1.4 2011/02/13 21:47:38 acg
+ Andy Goodrich: update copyright notice.
+
+Revision 1.3 2011/01/18 20:10:45 acg
+ Andy Goodrich: changes for IEEE1666_2011 semantics.
+
+Revision 1.2 2008/05/22 17:06:27 acg
+ Andy Goodrich: updated copyright notice to include 2008.
+
+Revision 1.1.1.1 2006/12/15 20:20:05 acg
+SystemC 2.3
+
+Revision 1.7 2006/02/02 20:20:39 acg
+ Andy Goodrich: warnings for SC_THREAD waits.
+
+Revision 1.6 2006/02/01 01:36:54 acg
+ Andy Goodrich: addition of deprecation comments for SC_CTHREAD waits other
+ than wait() and wait(N).
+
+Revision 1.5 2006/01/31 22:17:40 acg
+ Andy Goodrich: added deprecation warnings for SC_CTHREAD waits other than
+ wait() and wait(N).
+
+Revision 1.4 2006/01/25 00:31:20 acg
+ Andy Goodrich: Changed over to use a standard message id of
+ SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
+
+Revision 1.3 2006/01/24 20:49:05 acg
+Andy Goodrich: changes to remove the use of deprecated features within the
+simulator, and to issue warning messages when deprecated features are used.
+
+Revision 1.2 2006/01/03 23:18:45 acg
+Changed copyright to include 2006.
+
+Revision 1.1.1.1 2005/12/19 23:16:44 acg
+First check in of SystemC 2.1 into its own archive.
+
+Revision 1.10 2005/09/02 19:03:30 acg
+Changes for dynamic processes. Removal of lambda support.
+
+Revision 1.9 2005/07/30 03:45:05 acg
+Changes from 2.1, including changes for sc_process_handle.
+
+Revision 1.8 2005/04/04 00:16:07 acg
+Changes for directory name change to sys from systemc.
+Changes for sc_string going to std::string.
+Changes for sc_pvector going to std::vector.
+Changes for reference pools for bit and part selections.
+Changes for const sc_concatref support.
+
+Revision 1.5 2004/09/27 20:49:10 acg
+Andy Goodrich, Forte Design Systems, Inc.
+ - Added a $Log comment so that CVS checkin comments appear in the
+ checkout source.
+
+*/
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_wait.h b/ext/systemc/src/sysc/kernel/sc_wait.h
new file mode 100644
index 000000000..f598cf4bb
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_wait.h
@@ -0,0 +1,277 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_wait.h -- Wait() and related functions.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+ Martin Janssen, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_WAIT_H
+#define SC_WAIT_H
+
+
+#include "sysc/kernel/sc_simcontext.h"
+
+namespace sc_core {
+
+class sc_event;
+class sc_event_and_list;
+class sc_event_or_list;
+class sc_simcontext;
+
+extern sc_simcontext* sc_get_curr_simcontext();
+
+// static sensitivity for SC_THREADs and SC_CTHREADs
+
+extern
+void
+wait( sc_simcontext* = sc_get_curr_simcontext() );
+
+
+// dynamic sensitivity for SC_THREADs and SC_CTHREADs
+
+extern
+void
+wait( const sc_event&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+extern
+void
+wait( const sc_event_or_list&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+extern
+void
+wait( const sc_event_and_list&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+extern
+void
+wait( const sc_time&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+inline
+void
+wait( double v, sc_time_unit tu,
+ sc_simcontext* simc = sc_get_curr_simcontext() )
+{
+ wait( sc_time( v, tu, simc ), simc );
+}
+
+extern
+void
+wait( const sc_time&,
+ const sc_event&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+inline
+void
+wait( double v, sc_time_unit tu,
+ const sc_event& e,
+ sc_simcontext* simc = sc_get_curr_simcontext() )
+{
+ wait( sc_time( v, tu, simc ), e, simc );
+}
+
+extern
+void
+wait( const sc_time&,
+ const sc_event_or_list&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+inline
+void
+wait( double v, sc_time_unit tu,
+ const sc_event_or_list& el,
+ sc_simcontext* simc = sc_get_curr_simcontext() )
+{
+ wait( sc_time( v, tu, simc ), el, simc );
+}
+
+extern
+void
+wait( const sc_time&,
+ const sc_event_and_list&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+inline
+void
+wait( double v, sc_time_unit tu,
+ const sc_event_and_list& el,
+ sc_simcontext* simc = sc_get_curr_simcontext() )
+{
+ wait( sc_time( v, tu, simc ), el, simc );
+}
+
+
+// static sensitivity for SC_METHODs
+
+extern
+void
+next_trigger( sc_simcontext* = sc_get_curr_simcontext() );
+
+
+// dynamic sensitivity for SC_METHODs
+
+extern
+void
+next_trigger( const sc_event&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+extern
+void
+next_trigger( const sc_event_or_list&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+extern
+void
+next_trigger( const sc_event_and_list&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+extern
+void
+next_trigger( const sc_time&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+inline
+void
+next_trigger( double v, sc_time_unit tu,
+ sc_simcontext* simc = sc_get_curr_simcontext() )
+{
+ next_trigger( sc_time( v, tu, simc ), simc );
+}
+
+extern
+void
+next_trigger( const sc_time&,
+ const sc_event&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+inline
+void
+next_trigger( double v, sc_time_unit tu,
+ const sc_event& e,
+ sc_simcontext* simc = sc_get_curr_simcontext() )
+{
+ next_trigger( sc_time( v, tu, simc ), e, simc );
+}
+
+extern
+void
+next_trigger( const sc_time&,
+ const sc_event_or_list&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+inline
+void
+next_trigger( double v, sc_time_unit tu,
+ const sc_event_or_list& el,
+ sc_simcontext* simc = sc_get_curr_simcontext() )
+{
+ next_trigger( sc_time( v, tu, simc ), el, simc );
+}
+
+extern
+void
+next_trigger( const sc_time&,
+ const sc_event_and_list&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+inline
+void
+next_trigger( double v, sc_time_unit tu,
+ const sc_event_and_list& el,
+ sc_simcontext* simc = sc_get_curr_simcontext() )
+{
+ next_trigger( sc_time( v, tu, simc ), el, simc );
+}
+
+
+// for SC_METHODs and SC_THREADs and SC_CTHREADs
+
+extern
+bool
+timed_out( sc_simcontext* = sc_get_curr_simcontext() );
+
+// misc.
+
+extern
+void
+sc_set_location( const char*,
+ int,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+} // namespace sc_core
+
+/*
+$Log: sc_wait.h,v $
+Revision 1.6 2011/08/26 20:46:11 acg
+ Andy Goodrich: moved the modification log to the end of the file to
+ eliminate source line number skew when check-ins are done.
+
+Revision 1.5 2011/02/18 20:27:14 acg
+ Andy Goodrich: Updated Copyrights.
+
+Revision 1.4 2011/02/13 21:47:38 acg
+ Andy Goodrich: update copyright notice.
+
+Revision 1.3 2011/01/18 20:10:45 acg
+ Andy Goodrich: changes for IEEE1666_2011 semantics.
+
+Revision 1.2 2008/05/22 17:06:27 acg
+ Andy Goodrich: updated copyright notice to include 2008.
+
+Revision 1.1.1.1 2006/12/15 20:20:05 acg
+SystemC 2.3
+
+Revision 1.2 2006/01/03 23:18:45 acg
+Changed copyright to include 2006.
+
+Revision 1.1.1.1 2005/12/19 23:16:44 acg
+First check in of SystemC 2.1 into its own archive.
+
+Revision 1.10 2005/07/30 03:45:05 acg
+Changes from 2.1, including changes for sc_process_handle.
+
+Revision 1.9 2005/04/04 00:16:08 acg
+Changes for directory name change to sys from systemc.
+Changes for sc_string going to std::string.
+Changes for sc_pvector going to std::vector.
+Changes for reference pools for bit and part selections.
+Changes for const sc_concatref support.
+
+Revision 1.6 2004/10/13 18:13:22 acg
+sc_ver.h - updated version number. sc_wait.h remove inclusion of
+sysc/kernel/sc_event.h because it is not necessary.
+
+Revision 1.5 2004/09/27 20:49:10 acg
+Andy Goodrich, Forte Design Systems, Inc.
+ - Added a $Log comment so that CVS checkin comments appear in the
+ checkout source.
+
+*/
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_wait_cthread.cpp b/ext/systemc/src/sysc/kernel/sc_wait_cthread.cpp
new file mode 100644
index 000000000..4dee96ed7
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_wait_cthread.cpp
@@ -0,0 +1,169 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_wait_cthread.cpp -- Wait() and related functions for SC_CTHREADs.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+ Martin Janssen, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/kernel/sc_cthread_process.h"
+#include "sysc/kernel/sc_simcontext_int.h"
+#include "sysc/kernel/sc_wait_cthread.h"
+#include "sysc/communication/sc_port.h"
+#include "sysc/kernel/sc_wait.h"
+namespace sc_core
+{
+
+// for SC_CTHREADs
+
+void
+halt( sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ switch( cpi->kind ) {
+ case SC_CTHREAD_PROC_: {
+ RCAST<sc_cthread_handle>( cpi->process_handle )->wait_halt();
+ break;
+ }
+ default:
+ SC_REPORT_ERROR( SC_ID_HALT_NOT_ALLOWED_, 0 );
+ break;
+ }
+}
+
+
+void
+wait( int n, sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ if( n <= 0 ) {
+ char msg[BUFSIZ];
+ std::sprintf( msg, "n = %d", n );
+ SC_REPORT_ERROR( SC_ID_WAIT_N_INVALID_, msg );
+ }
+ switch( cpi->kind ) {
+ case SC_THREAD_PROC_:
+ case SC_CTHREAD_PROC_:
+ RCAST<sc_cthread_handle>( cpi->process_handle )->wait_cycles( n );
+ break;
+ default:
+ SC_REPORT_ERROR( SC_ID_WAIT_NOT_ALLOWED_, "\n "
+ "in SC_METHODs use next_trigger() instead" );
+ break;
+ }
+}
+
+
+void
+at_posedge( const sc_signal_in_if<bool>& s, sc_simcontext* simc )
+{
+ if( s.read() == true )
+ do { wait(simc); } while ( s.read() == true );
+ do { wait(simc); } while ( s.read() == false );
+}
+
+void
+at_posedge( const sc_signal_in_if<sc_dt::sc_logic>& s, sc_simcontext* simc )
+{
+ if( s.read() == '1' )
+ do { wait(simc); } while ( s.read() == '1' );
+ do { wait(simc); } while ( s.read() == '0' );
+}
+
+void
+at_negedge( const sc_signal_in_if<bool>& s, sc_simcontext* simc )
+{
+ if( s.read() == false )
+ do { wait(simc); } while ( s.read() == false );
+ do { wait(simc); } while ( s.read() == true );
+}
+
+void
+at_negedge( const sc_signal_in_if<sc_dt::sc_logic>& s, sc_simcontext* simc )
+{
+ if( s.read() == '0' )
+ do { wait(simc); } while ( s.read() == '0' );
+ do { wait(simc); } while ( s.read() == '1' );
+}
+
+
+} // namespace sc_core
+
+/*
+$Log: sc_wait_cthread.cpp,v $
+Revision 1.6 2011/08/26 20:46:11 acg
+ Andy Goodrich: moved the modification log to the end of the file to
+ eliminate source line number skew when check-ins are done.
+
+Revision 1.5 2011/02/18 20:27:14 acg
+ Andy Goodrich: Updated Copyrights.
+
+Revision 1.4 2011/02/13 21:47:38 acg
+ Andy Goodrich: update copyright notice.
+
+Revision 1.3 2009/10/14 19:07:42 acg
+ Andy Goodrich: added an error message for wait(n) being called from an
+ SC_METHOD.
+
+Revision 1.2 2008/05/22 17:06:27 acg
+ Andy Goodrich: updated copyright notice to include 2008.
+
+Revision 1.1.1.1 2006/12/15 20:20:05 acg
+SystemC 2.3
+
+Revision 1.3 2006/03/13 20:26:51 acg
+ Andy Goodrich: Addition of forward class declarations, e.g.,
+ sc_reset, to keep gcc 4.x happy.
+
+Revision 1.2 2006/01/03 23:18:45 acg
+Changed copyright to include 2006.
+
+Revision 1.1.1.1 2005/12/19 23:16:44 acg
+First check in of SystemC 2.1 into its own archive.
+
+Revision 1.10 2005/09/15 23:02:18 acg
+Added std:: prefix to appropriate methods and types to get around
+issues with the Edison Front End.
+
+Revision 1.9 2005/09/02 19:03:30 acg
+Changes for dynamic processes. Removal of lambda support.
+
+Revision 1.8 2005/04/04 00:16:08 acg
+Changes for directory name change to sys from systemc.
+Changes for sc_string going to std::string.
+Changes for sc_pvector going to std::vector.
+Changes for reference pools for bit and part selections.
+Changes for const sc_concatref support.
+
+Revision 1.5 2004/09/27 20:49:10 acg
+Andy Goodrich, Forte Design Systems, Inc.
+ - Added a $Log comment so that CVS checkin comments appear in the
+ checkout source.
+
+*/
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_wait_cthread.h b/ext/systemc/src/sysc/kernel/sc_wait_cthread.h
new file mode 100644
index 000000000..a04bfecc1
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_wait_cthread.h
@@ -0,0 +1,126 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_wait_cthread.h -- Wait() and related functions for SC_CTHREADs.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+ Martin Janssen, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_WAIT_CTHREAD_H
+#define SC_WAIT_CTHREAD_H
+
+
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/datatypes/bit/sc_logic.h"
+#include "sysc/communication/sc_signal_ifs.h"
+
+
+namespace sc_core
+{
+
+// for SC_CTHREADs
+
+extern
+void
+halt( sc_simcontext* = sc_get_curr_simcontext() );
+
+
+extern
+void
+wait( int,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+
+extern
+void
+at_posedge( const sc_signal_in_if<bool>&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+extern
+void
+at_posedge( const sc_signal_in_if<sc_dt::sc_logic>&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+extern
+void
+at_negedge( const sc_signal_in_if<bool>&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+extern
+void
+at_negedge( const sc_signal_in_if<sc_dt::sc_logic>&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+
+} // namespace sc_core
+
+/*
+$Log: sc_wait_cthread.h,v $
+Revision 1.6 2011/08/26 20:46:11 acg
+ Andy Goodrich: moved the modification log to the end of the file to
+ eliminate source line number skew when check-ins are done.
+
+Revision 1.5 2011/08/24 22:05:51 acg
+ Torsten Maehne: initialization changes to remove warnings.
+
+Revision 1.4 2011/02/18 20:27:14 acg
+ Andy Goodrich: Updated Copyrights.
+
+Revision 1.3 2011/02/13 21:47:38 acg
+ Andy Goodrich: update copyright notice.
+
+Revision 1.2 2008/05/22 17:06:27 acg
+ Andy Goodrich: updated copyright notice to include 2008.
+
+Revision 1.1.1.1 2006/12/15 20:20:05 acg
+SystemC 2.3
+
+Revision 1.2 2006/01/03 23:18:45 acg
+Changed copyright to include 2006.
+
+Revision 1.1.1.1 2005/12/19 23:16:44 acg
+First check in of SystemC 2.1 into its own archive.
+
+Revision 1.10 2005/09/02 19:03:30 acg
+Changes for dynamic processes. Removal of lambda support.
+
+Revision 1.9 2005/04/04 00:16:08 acg
+Changes for directory name change to sys from systemc.
+Changes for sc_string going to std::string.
+Changes for sc_pvector going to std::vector.
+Changes for reference pools for bit and part selections.
+Changes for const sc_concatref support.
+
+Revision 1.6 2005/01/10 17:52:20 acg
+Addition of namespace specifications.
+
+Revision 1.5 2004/09/27 20:49:10 acg
+Andy Goodrich, Forte Design Systems, Inc.
+ - Added a $Log comment so that CVS checkin comments appear in the
+ checkout source.
+
+*/
+
+#endif
diff --git a/ext/systemc/src/sysc/qt/CHANGES b/ext/systemc/src/sysc/qt/CHANGES
new file mode 100644
index 000000000..1b74921ee
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/CHANGES
@@ -0,0 +1,15 @@
+QuickThreads 002: Changes since QuickThreads 001.
+
+ - Now can be used by C++ programs.
+ - Now *really* works with stacks that grow up.
+ - Supports AXP OSF 2.x cc's varargs.
+ - Supports HP Precision (HP-PA) on workstations and Convex.
+ - Supports assemblers for Intel iX86 ith only '//'-style comments.
+ - Supports Silicon Graphics Irix 5.x with dynamic linking.
+ - Supports System V and Solaris 2.x with no `_' on compiler-generated
+ identifiers; *some* platforms only.
+
+Note: not all "./config" arguments are compatible with QT 001.
+
+
+QuickThreads 001: Base version.
diff --git a/ext/systemc/src/sysc/qt/INSTALL b/ext/systemc/src/sysc/qt/INSTALL
new file mode 100644
index 000000000..5b20f5d5e
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/INSTALL
@@ -0,0 +1,81 @@
+Installation of the `QuickThreads' threads-building toolkit.
+
+* Notice
+
+QuickThreads -- Threads-building toolkit.
+Copyright (c) 1993 by David Keppel
+
+Permission to use, copy, modify and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice and this notice
+appear in all copies. This software is provided as a
+proof-of-concept and for demonstration purposes; there is no
+representation about the suitability of this software for any
+purpose.
+
+
+* Configuration
+
+Configure with
+
+ ./config *machtype*
+
+where "*machtype*" is one of the supported target machines. As of
+October 1994, the supported machines (targets) are:
+
+ axp -- All Digital Equipment Corporation AXP (DEC Alpha)
+ processors, compile with GNU CC
+ axp-osf1 -- AXP running OSF 1.x
+ axp-osf2 -- AXP running OSF 2.x
+ hppa -- HP's PA-RISC 1.1 processor
+ hppa-cnx-spp -- Convex SPP (PA-RISC 1.1 processor)
+ iX86 -- 80386, 80486, and 80586-compatible processors
+ See notes below for OS/2.
+ iX86-ss -- 'iX86 for assemblers that use slash-slash ('//')
+ comments.
+ ksr1 -- All KSR processors
+ m88k -- All members of the Motorola 88000 family
+ mips -- MIPS R2000 and R3000 processors
+ mips-irix5 -- Irix 5.xx (use `mips' for Irix 4.xx)
+ sparc-os1 -- V8-compliant SPARC processors using compilers
+ that prefix labels (e.g. "foo" appears as "_foo")
+ Includes Solaris 1 (SunOS 4.X).
+ sparc-os2 -- V8-compliant SPARC processors using compilers
+ that do not prefix labels. Includes Solaris 2.
+ vax -- All VAX processors
+
+In addition, the target `clean' will deconfigure QuickThreads.
+
+Note that a given machine target may not work on all instances of that
+machine because e.g., the assembler syntax varies from machine to
+machine.
+
+Note also that additions to a processor family may require a new
+target. So, for example, the `vax' target might not work for all
+future VAX processors if, say, new VAX processors are introduced and
+they use separate floating-point registers.
+
+For OS/2, change `ranlib' to `ar -s', `configure' to `configure.cmd'
+(or was that `config' to `config.cmd'?), and replace the soft links
+(`ln -s') with plain copies.
+
+
+* Build
+
+To build the QuickThreads library, first configure (see above) then
+type `make libqt.a' in the top-level directory.
+
+To build the demonstration threads package, SimpleThreads, type
+`make libstp.a' in the top-level directory.
+
+To build an executable ``stress-test'' and measurement program, type
+`make run' in the top-level directory. Run `time/raw' to run the
+stress tests.
+
+
+* Installation
+
+Build the QuickThreads library (see above) and then copy `libqt.a' to
+the installation library directory (e.g., /usr/local/lib) and `qt.h'
+and `qtmd.h' to the installation include directory (e.g.,
+/usr/local/include).
diff --git a/ext/systemc/src/sysc/qt/README b/ext/systemc/src/sysc/qt/README
new file mode 100644
index 000000000..b014b91bf
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/README
@@ -0,0 +1,89 @@
+This is a source code distribution for QuickThreads. QuickThreads is a
+toolkit for building threads packages; it is described in detail in the
+University of Washington CS&E Technical report #93-05-06, available via
+anonymous ftp from `ftp.cs.washington.edu' (128.95.1.4, as of Oct. '94)
+in `tr/1993/05/UW-CSE-93-05-06.PS.Z'.
+
+This distribution shows basic ideas in QuickThreads and elaborates with
+example implementations for a gaggle of machines. As of October those
+machines included:
+
+ 80386 faimly
+ 88000 faimily
+ DEC AXP (Alpha) family
+ HP-PA family
+ KSR
+ MIPS family
+ SPARC V8 family
+ VAX family
+
+Configuration, build, and installation are described in INSTALL.
+
+Be aware: that there is no varargs code for the KSR.
+
+The HP-PA port was designed to work with both HP workstations
+and Convex SPP computers. It was generously provided by Uwe Reder
+<uereder@cip.informatik.uni-erlangen.de>. It is part of the ELiTE
+(Erlangen Lightweight Thread Environment) project directed by
+Frank Bellosa <bellosa@informatik.uni-erlangen.de> at the Operating
+Systems Department of the University of Erlangen (Germany).
+
+Other contributors include: Weihaw Chuang, Richard O'Keefe,
+Laurent Perron, John Polstra, Shinji Suzuki, Assar Westerlund,
+thanks also to Peter Buhr and Dirk Grunwald.
+
+
+Here is a brief summary:
+
+QuickThreads is a toolkit for building threads packages. It is my hope
+that you'll find it easier to use QuickThreads normally than to take it
+and modify the raw cswap code to fit your application. The idea behind
+QuickThreads is that it should make it easy for you to write & retarget
+threads packages. If you want the routine `t_create' to create threads
+and `t_block' to suspend threads, you write them using the QuickThreads
+`primitive' operations `QT_SP', `QT_INIT', and `QT_BLOCK', that perform
+machine-dependent initialization and blocking, plus code you supply for
+performing the portable operatons. For example, you might write:
+
+ t_create (func, arg)
+ {
+ stk = malloc (STKSIZE);
+ stackbase = QT_SP (stk, STKSIZE);
+ sp = QT_INIT (stakcbase, func, arg);
+ qput (runq, sp);
+ }
+
+Threads block by doing something like:
+
+ t_block()
+ {
+ sp_next = qget (runq);
+ QT_BLOCK (helper, runq, sp_next);
+ // wake up again here
+ }
+
+ // called by QT_BLOCK after the old thread has blocked,
+ // puts the old thread on the queue `onq'.
+ helper (sp_old, onq)
+ {
+ qput (onq, sp_old);
+ }
+
+(Of course) it's actually a bit more complex than that, but the general
+idea is that you write portable code to allocate stacks and enqueue and
+dequeue threads. Than, to get your threads package up and running on a
+different machine, you just reconfigure QuickThreads and recompile, and
+that's it.
+
+The QuickThreads `distribution' includes a sample threads package (look
+at stp.{c,h}) that is written in terms of QuickThreads operations. The
+TR mentioned above explains the simple threads package in detail.
+
+
+
+If you do use QuickThreads, I'd like to hear both about what worked for
+you and what didn't work, problems you had, insights gleaned, etc.
+
+Let me know what you think.
+
+David Keppel <pardo@cs.washington.edu>
diff --git a/ext/systemc/src/sysc/qt/README.MISC b/ext/systemc/src/sysc/qt/README.MISC
new file mode 100644
index 000000000..d10e487cf
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/README.MISC
@@ -0,0 +1,56 @@
+Here's some machine-specific informatin for various systems:
+
+m88k on g88.sim
+
+ .g88init:
+ echo (gdb) target sim\n
+ target sim
+ echo (gdb) ecatch all\n
+ ecatch all
+ echo (gdb) break exit\n
+ break exit
+ % vi Makefile // set CC and AS
+ % setenv MEERKAT /projects/cer/meerkat
+ % set path=($MEERKAT/bin $path)
+ % make run
+ % g88.sim run
+ (g88) run run N // where `N' is the test number
+
+
+m88k on meerkats, cross compile as above (make run)
+
+ Run w/ g88:
+ %g88 run
+ (g88) source /homes/rivers/robertb/.gdbinit
+ (g88) me
+ which does
+ (g88) set $firstchars=6
+ (g88) set $resetonattach=1
+ (g88) attach /dev/pp0
+ then download
+ (g88) dl
+ and run with
+ (g88) continue
+
+ Really the way to run it is:
+ (g88) source
+ (g88) me
+ (g88) win
+ (g88) dead 1
+ (g88) dead 2
+ (g88) dead 3
+ (g88) dl
+ (g88) cont
+
+ To rerun
+ (g88) init
+ (g88) dl
+
+ To run simulated meerkat:
+ (g88) att sim
+ <<then use normal commands>>
+
+ On 4.5 g88:
+ (g88) target sim memsize
+ instead of attatch
+ (g88) ecatch all # catch exception before becomes error
diff --git a/ext/systemc/src/sysc/qt/README.PORT b/ext/systemc/src/sysc/qt/README.PORT
new file mode 100644
index 000000000..d56300923
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/README.PORT
@@ -0,0 +1,112 @@
+Date: Tue, 11 Jan 94 13:23:11 -0800
+From: "pardo@cs.washington.edu" <pardo@meitner.cs.washington.edu>
+
+>[What's needed to get `qt' on an i860-based machine?]
+
+Almost certainly "some assembly required" (pun accepted).
+
+To write a cswap port, you need to understand the context switching
+model. Turn to figure 2 in the QT TR. Here's about what the assembly
+code looks like to implement that:
+
+ qt_cswap:
+ adjust stack pointer
+ save callee-save registers on to old's stack
+ argument register <- old sp
+ sp <- new sp
+ (*helper)(args...)
+ restore callee-save registers from new's stack
+ unadjust stack pointer
+ return
+
+Once more in slow motion:
+
+ - `old' thread calls context switch routine (new, a0, a1, h)
+ - cswap routine saves registers that have useful values
+ - cswap routine switches to new stack
+ - cswap routine calls helper function (*h)(old, a0, a1)
+ - when helper returns, cswap routine restores registers
+ that were saved the last time `new' was suspended
+ - cswap routine returns to whatever `new' routine called the
+ context switch routine
+
+There's a few tricks here. First, how do you start a thread running
+for the very first time? Answer is: fake some stuff on the stack
+so it *looks* like it was called from the middle of some routine.
+When the new thread is restarted, it is treated like any other
+thread. It just so happens that it's never really run before, but
+you can't tell that because the saved state makes it look like like
+it's been run. The return pc is set to point at a little stub of
+assembly code that loads up registers with the right values and
+then calls `only'.
+
+Second, I advise you to forget about varargs routines (at least
+until you get single-arg routines up and running).
+
+Third, on most machines `qt_abort' is the same as `qt_cswap' except
+that it need not save any callee-save registers.
+
+Fourth, `qt_cswap' needs to save and restore any floating-point
+registers that are callee-save (see your processor handbook). On
+some machines, *no* floating-point registers are callee-save, so
+`qt_cswap' is exactly the same as the integer-only cswap routine.
+
+I suggest staring at the MIPS code for a few minutes. It's "mostly"
+generic RISC code, so it gets a lot of the flavor across without
+getting too bogged down in little nitty details.
+
+
+
+Now for a bit more detail: The stack is laid out to hold callee-save
+registers. On many machines, I implemented fp cswap as save fp
+regs, call integer cswap, and when integer cswap returns (when the
+thread wakes up again), restore fp regs.
+
+For thread startup, I figure out some callee-save registers that
+I use to hold parameters to the startup routine (`only'). When
+the thread is being started it doesn't have any saved registers
+that need to be restored, but I go ahead and let the integer context
+switch routine restore some registers then "return" to the stub
+code. The stub code then copies the "callee save" registers to
+argument registers and calls the startup routine. That keeps the
+stub code pretty darn simple.
+
+For each machine I need to know the machine's procedure calling
+convention before I write a port. I figure out how many callee-save
+registers are there and allocate enough stack space for those
+registers. I also figure out how parameters are passed, since I
+will need to call the helper function. On most RISC machines, I
+just need to put the old sp in the 0'th arg register and then call
+indirect through the 3rd arg register; the 1st and 2nd arg registers
+are already set up correctly. Likewise, I don't touch the return
+value register between the helper's return and the context switch
+routine's return.
+
+I have a bunch of macros set up to do the stack initialization.
+The easiest way to debug this stuff is to go ahead and write a C
+routine to do stack initialization. Once you're happy with it you
+can turn it in to a macro.
+
+In general there's a lot of ugly macros, but most of them do simple
+things like return constants, etc. Any time you're looking at it
+and it looks confusing you just need to remember "this is actually
+simple code, the only tricky thing is calling the helper between
+the stack switch and the new thread's register restore."
+
+
+You will almost certainly need to write the assembly code fragment
+that starts a thread. You might be able to do a lot of the context
+switch code with `setjmp' and `longjmp', if they *happen* to have
+the "right" implementation. But getting all the details right (the
+helper can return a value to the new thread's cswap routine caller)
+is probaby trickier than writing code that does the minimum and
+thus doesn't have any extra instructions (or generality) to cause
+problems.
+
+I don't know of any ports besides those included with the source
+code distribution. If you send me a port I will hapily add it to
+the distribution.
+
+Let me know as you have questions and/or comments.
+
+ ;-D on ( Now *that*'s a switch... ) Pardo
diff --git a/ext/systemc/src/sysc/qt/b.h b/ext/systemc/src/sysc/qt/b.h
new file mode 100644
index 000000000..49e587c77
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/b.h
@@ -0,0 +1,11 @@
+#ifndef B_H
+#define B_H "$Header: /Users/acg/CVSROOT/systemc-2.3/src/sysc/qt/b.h,v 1.1.1.1 2006/12/15 20:20:06 acg Exp $"
+
+#include "copyright.h"
+
+extern void b_call_reg (int n);
+extern void b_call_imm (int n);
+extern void b_add (int n);
+extern void b_load (int n);
+
+#endif /* ndef B_H */
diff --git a/ext/systemc/src/sysc/qt/config b/ext/systemc/src/sysc/qt/config
new file mode 100755
index 000000000..35d54647f
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/config
@@ -0,0 +1,392 @@
+#! /bin/sh
+
+# set -x
+
+: ${LN_S:="ln -s"}
+
+# rm -f Makefile Makefile.md README.md qtmd.h qtmdb.s qtmdc.c qtmds.s configuration
+rm -f qtmdc.c qtmds.s configuration
+
+case $1 in
+ axp*)
+ : "DEC AXP"
+ case $1 in
+ axp-osf1*)
+ : "Compile using /bin/cc under OSF 1.x."
+# ${LN_S} md/axp.1.Makefile Makefile.md
+ ;;
+ axp-osf2*)
+ : "Compile using /bin/cc under OSF 2.x."
+# ${LN_S} md/axp.1.Makefile Makefile.md
+ ;;
+ *)
+ : "Compile using GNU CC."
+# ${LN_S} md/axp.Makefile Makefile.md
+ ;;
+ esac
+
+# ${LN_S} md/axp.h qtmd.h
+ ${LN_S} md/axp.c qtmdc.c
+ ${LN_S} md/axp.s qtmds.s
+# ${LN_S} md/axp_b.s qtmdb.s
+# ${LN_S} md/axp.README README.md
+ iter_init=1000000000
+ iter_runone=10000000
+ iter_blockint=10000000
+ iter_blockfloat=10000000
+ iter_vainit0=10000000
+ iter_vainit2=10000000
+ iter_vainit4=10000000
+ iter_vainit8=10000000
+ iter_vastart0=10000000
+ iter_vastart2=10000000
+ iter_vastart4=10000000
+ iter_vastart8=10000000
+ iter_bench_call_reg=10000000
+ iter_bench_call_imm=10000000
+ iter_bench_add=100000000
+ iter_bench_load=100000000
+ ;;
+
+ hppa*)
+ : "HP's PA-RISC 1.1 processors."
+
+ case $1 in
+ hppa-cnx-spp*)
+ : "Convex SPP (PA-RISC 1.1 processors)."
+# ${LN_S} md/hppa-cnx.Makefile Makefile.md
+ ;;
+ *)
+# ${LN_S} md/hppa.Makefile Makefile.md
+ ;;
+ esac
+
+# ${LN_S} md/hppa.h qtmd.h
+# ${LN_S} md/null.c qtmdc.c
+ ${LN_S} md/hppa.s qtmds.s
+# ${LN_S} md/hppa_b.s qtmdb.s
+ iter_init=10000000
+ iter_runone=1000000
+ iter_blockint=1000000
+ iter_blockfloat=1000000
+ iter_vainit0=1000000
+ iter_vainit2=1000000
+ iter_vainit4=1000000
+ iter_vainit8=1000000
+ iter_vastart0=1000000
+ iter_vastart2=1000000
+ iter_vastart4=1000000
+ iter_vastart8=1000000
+ iter_bench_call_reg=10000000
+ iter_bench_call_imm=10000000
+ iter_bench_add=100000000
+ iter_bench_load=100000000
+ ;;
+
+ x86_64*)
+ case $1 in
+ iX86-ss*)
+ : "Assembler comments '//'"
+ sed 's/\/\*/\/\//' < md/i386_64.s > qtmds.s
+ ;;
+
+ *)
+ ${LN_S} md/iX86_64.s qtmds.s
+ ;;
+ esac
+ : "Intel X386 64-bit and compatibles"
+# ${LN_S} md/null.c qtmdc.c
+ iter_init=10000000
+ iter_runone=1000000
+ iter_blockint=1000000
+ iter_blockfloat=1000000
+ iter_vainit0=1000000
+ iter_vainit2=1000000
+ iter_vainit4=1000000
+ iter_vainit8=1000000
+ iter_vastart0=1000000
+ iter_vastart2=1000000
+ iter_vastart4=1000000
+ iter_vastart8=1000000
+ iter_bench_call_reg=1000000
+ iter_bench_call_imm=1000000
+ iter_bench_add=100000000
+ iter_bench_load=10000000
+ ;;
+
+ iX86*)
+ case $1 in
+ iX86-ss*)
+ : "Assembler comments '//'"
+ sed 's/\/\*/\/\//' < md/i386.s > qtmds.s
+# sed 's/\/\*/\/\//' < md/i386_b.s > qtmdb.s
+ ;;
+
+ *)
+ ${LN_S} md/i386.s qtmds.s
+# ${LN_S} md/i386_b.s qtmdb.s
+ ;;
+ esac
+ : "Intel 80386 and compatibles (not '286...)"
+# ${LN_S} md/default.Makefile Makefile.md
+# ${LN_S} md/i386.h qtmd.h
+# ${LN_S} md/null.c qtmdc.c
+# ${LN_S} md/i386.README README.md
+ iter_init=10000000
+ iter_runone=1000000
+ iter_blockint=1000000
+ iter_blockfloat=1000000
+ iter_vainit0=1000000
+ iter_vainit2=1000000
+ iter_vainit4=1000000
+ iter_vainit8=1000000
+ iter_vastart0=1000000
+ iter_vastart2=1000000
+ iter_vastart4=1000000
+ iter_vastart8=1000000
+ iter_bench_call_reg=1000000
+ iter_bench_call_imm=1000000
+ iter_bench_add=100000000
+ iter_bench_load=10000000
+ ;;
+
+
+ m68k)
+ : "Motorola 68000 family -- incomplete!"
+# ${LN_S} md/default.Makefile Makefile.md
+# ${LN_S} md/m68k.h qtmd.h
+# ${LN_S} md/null.c qtmdc.c
+ ${LN_S} md/m68k.s qtmds.s
+# ${LN_S} md/m68k_b.s qtmdb.s
+# ${LN_S} md/null.README README.md
+ ;;
+
+ m88k)
+ : "Motorola 88000 family"
+# ${LN_S} md/m88k.Makefile Makefile.md
+# ${LN_S} md/m88k.h qtmd.h
+ ${LN_S} md/m88k.c qtmdc.c
+ ${LN_S} md/m88k.s qtmds.s
+# ${LN_S} md/m88k_b.s qtmdb.s
+# ${LN_S} md/null.README README.md
+ iter_init=1000000
+ iter_runone=100000
+ iter_blockint=100000
+ iter_blockfloat=100000
+ iter_vainit0=100000
+ iter_vainit2=100000
+ iter_vainit4=100000
+ iter_vainit8=100000
+ iter_vastart0=100000
+ iter_vastart2=100000
+ iter_vastart4=100000
+ iter_vastart8=100000
+ iter_bench_call_reg=100000000
+ iter_bench_call_imm=100000000
+ iter_bench_add=1000000000
+ iter_bench_load=100000000
+ ;;
+
+ mips*)
+ : "MIPS R2000 and R3000."
+
+ case $1 in
+ mips-irix5*)
+ : "Silicon Graphics Irix with dynamic linking"
+ : "Use mips for irix4."
+ ${LN_S} md/mips-irix5.s qtmds.s
+ ;;
+ *)
+ ${LN_S} md/mips.s qtmds.s
+ ;;
+ esac
+
+# ${LN_S} md/default.Makefile Makefile.md
+# ${LN_S} md/mips.h qtmd.h
+# ${LN_S} md/null.c qtmdc.c
+# ${LN_S} md/mips_b.s qtmdb.s
+# ${LN_S} md/null.README README.md
+ iter_init=10000000
+ iter_runone=10000000
+ iter_blockint=10000000
+ iter_blockfloat=10000000
+ iter_vainit0=1000000
+ iter_vainit2=1000000
+ iter_vainit4=1000000
+ iter_vainit8=1000000
+ iter_vastart0=1000000
+ iter_vastart2=1000000
+ iter_vastart4=1000000
+ iter_vastart8=1000000
+ iter_bench_call_reg=100000000
+ iter_bench_call_imm=100000000
+ iter_bench_add=1000000000
+ iter_bench_load=100000000
+ ;;
+
+ sparc*)
+ : "SPARC processors"
+ case $1 in
+ sparc-os2*)
+ sed 's/_qt_/qt_/' md/sparc.s > qtmds.s
+# sed 's/_b_/b_/' md/sparc_b.s > qtmdb.s
+# ${LN_S} md/solaris.README README.md
+ ;;
+ *)
+ ${LN_S} md/sparc.s qtmds.s
+# ${LN_S} md/sparc_b.s qtmdb.s
+# ${LN_S} md/null.README README.md
+ ;;
+ esac
+
+ ${LN_S} md/default.Makefile Makefile.md
+# ${LN_S} md/sparc.h qtmd.h
+# ${LN_S} md/null.c qtmdc.c
+ iter_init=10000000
+ iter_runone=1000000
+ iter_blockint=1000000
+ iter_blockfloat=1000000
+ iter_vainit0=1000000
+ iter_vainit2=1000000
+ iter_vainit4=1000000
+ iter_vainit8=1000000
+ iter_vastart0=1000000
+ iter_vastart2=1000000
+ iter_vastart4=1000000
+ iter_vastart8=1000000
+ iter_bench_call_reg=10000000
+ iter_bench_call_imm=10000000
+ iter_bench_add=100000000
+ iter_bench_load=100000000
+ ;;
+
+ vax*)
+ : "DEC VAX processors."
+# ${LN_S} md/default.Makefile Makefile.md
+# ${LN_S} md/vax.h qtmd.h
+# ${LN_S} md/null.c qtmdc.c
+ ${LN_S} md/vax.s qtmds.s
+# ${LN_S} md/vax_b.s qtmdb.s
+# ${LN_S} md/null.README README.md
+ iter_init=1000000
+ iter_runone=100000
+ iter_blockint=100000
+ iter_blockfloat=100000
+ iter_vainit0=100000
+ iter_vainit2=100000
+ iter_vainit4=100000
+ iter_vainit8=100000
+ iter_vastart0=100000
+ iter_vastart2=100000
+ iter_vastart4=100000
+ iter_vastart8=100000
+ iter_bench_call_reg=10000000
+ iter_bench_call_imm=10000000
+ iter_bench_add=10000000
+ iter_bench_load=1000000
+ ;;
+
+ ksr1)
+ : "Kendall Square Research model KSR-1."
+ : "Varargs is not currently supported."
+# ${LN_S} md/ksr1.Makefile Makefile.md
+# ${LN_S} md/ksr1.h qtmd.h
+# ${LN_S} md/null.c qtmdc.c
+ ${LN_S} md/ksr1.s qtmds.s
+# ${LN_S} md/ksr1_b.s qtmdb.s
+# ${LN_S} md/null.README README.md
+ iter_init=1000000
+ iter_runone=100000
+ iter_blockint=100000
+ iter_blockfloat=100000
+ iter_vainit0=100000
+ iter_vainit2=100000
+ iter_vainit4=100000
+ iter_vainit8=100000
+ iter_vastart0=100000
+ iter_vastart2=100000
+ iter_vastart4=100000
+ iter_vastart8=100000
+ iter_bench_call_reg=10000000
+ iter_bench_call_imm=10000000
+ iter_bench_add=10000000
+ iter_bench_load=1000000
+ ;;
+
+ powerpc*)
+ : "PowerPC IBM/Motorola processors."
+
+ case $1 in
+ powerpc-apple-macosx*)
+ : "PowerPC using Mach Application Binary Interface"
+ : "NOTICE: Darwin assembler syntax is used:"
+ : " (i.e. registers are named rx not %rx)"
+ ${LN_S} md/default.Makefile Makefile.md
+# ${LN_S} md/powerpc_mach.h qtmd.h
+ ${LN_S} md/powerpc_mach.s qtmds.s
+ ;;
+ powerpc-linux*)
+ : "PowerPC using System V Application Binary Interface"
+ : " (e.g. LinuxPPC)"
+ : "Use powerpc-darwin for MacOS X and other systems based on Mac
+h ABI"
+# ${LN_S} md/powerpc_sys5.h qtmd.h
+ ${LN_S} md/powerpc_sys5.s qtmds.s
+ ;;
+ *)
+ echo "Unknown configuration"
+ echo "See md/powerpc.README for documentation"
+ echo "Use powerpc-darwin for MacOS X and other systems based on
+Mach ABI"
+ echo "Use powerpc-linux for Linux and other systems based on Sys
+tem V ABI"
+ exit 1
+ ;;
+
+ esac
+
+ ${LN_S} md/powerpc.c qtmdc.c
+ ${LN_S} md/powerpc.README README.md
+ ;;
+
+
+ pthreads*)
+ : Posix thread support rather than Quick threads.
+# ${LN_S} md/hppa.h qtmd.h
+# ${LN_S} md/null.c qtmdc.c
+# ${LN_S} md/null.s qtmds.s
+# ${LN_S} md/hppa_b.s qtmdb.s
+# cp md/pthreads.Makefile Makefile
+ exit 0
+ ;;
+
+ clean)
+ : Deconfigure
+ exit 0
+ ;;
+
+ *)
+ echo "Unknown configuration"
+ exit 1
+ ;;
+esac
+
+# cat Makefile.md Makefile.base > Makefile
+
+echo set config_machine=$1 >> configuration
+echo set config_init=$iter_init >> configuration
+echo set config_runone=$iter_runone >> configuration
+echo set config_blockint=$iter_blockint >> configuration
+echo set config_blockfloat=$iter_blockfloat >> configuration
+echo set config_vainit0=$iter_vainit0 >> configuration
+echo set config_vainit2=$iter_vainit2 >> configuration
+echo set config_vainit4=$iter_vainit4 >> configuration
+echo set config_vainit8=$iter_vainit8 >> configuration
+echo set config_vastart0=$iter_vastart0 >> configuration
+echo set config_vastart2=$iter_vastart2 >> configuration
+echo set config_vastart4=$iter_vastart4 >> configuration
+echo set config_vastart8=$iter_vastart8 >> configuration
+echo set config_bcall_reg=$iter_bench_call_reg >> configuration
+echo set config_bcall_imm=$iter_bench_call_imm >> configuration
+echo set config_b_add=$iter_bench_add >> configuration
+echo set config_b_load=$iter_bench_load >> configuration
diff --git a/ext/systemc/src/sysc/qt/copyright.h b/ext/systemc/src/sysc/qt/copyright.h
new file mode 100644
index 000000000..8a2361f9e
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/copyright.h
@@ -0,0 +1,12 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
diff --git a/ext/systemc/src/sysc/qt/md/axp.1.Makefile b/ext/systemc/src/sysc/qt/md/axp.1.Makefile
new file mode 100644
index 000000000..86ccd8f42
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/axp.1.Makefile
@@ -0,0 +1,5 @@
+
+#
+# Compiling for the DEC AXP (alpha) with GNU CC or version 1.x of OSF.
+#
+CC = cc -std1 -D__AXP__ -D__OSF1__
diff --git a/ext/systemc/src/sysc/qt/md/axp.2.Makefile b/ext/systemc/src/sysc/qt/md/axp.2.Makefile
new file mode 100644
index 000000000..268636fc9
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/axp.2.Makefile
@@ -0,0 +1,5 @@
+
+#
+# Compiling for the DEC AXP (alpha) with GNU CC or version 2.x of OSF.
+#
+CC = cc -std1 -D__AXP__ -D__OSF2__
diff --git a/ext/systemc/src/sysc/qt/md/axp.Makefile b/ext/systemc/src/sysc/qt/md/axp.Makefile
new file mode 100644
index 000000000..4e6d74da4
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/axp.Makefile
@@ -0,0 +1,5 @@
+
+#
+# GNU CC
+#
+CC = gcc -D__AXP__
diff --git a/ext/systemc/src/sysc/qt/md/axp.README b/ext/systemc/src/sysc/qt/md/axp.README
new file mode 100644
index 000000000..b6a705c07
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/axp.README
@@ -0,0 +1,10 @@
+The handling of varargs is platform-dependent. Assar Westerlund
+stared at the problem for a while and deduces the following table:
+
+vers / compiler cc gcc
+----------------------------------------------------------------------
+1.3 a0, offset __base, __offset
+2.0 _a0, _offset __base, __offset
+
+The current code should handle both cc and gcc versions, provided
+you configure for the correct compiler.
diff --git a/ext/systemc/src/sysc/qt/md/axp.c b/ext/systemc/src/sysc/qt/md/axp.c
new file mode 100644
index 000000000..268612993
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/axp.c
@@ -0,0 +1,133 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+#include <stdarg.h>
+#include "qt.h"
+
+
+/* Varargs is harder on the AXP. Parameters are saved on the stack as
+ something like (stack grows down to low memory; low at bottom of
+ picture):
+
+ | :
+ | arg6
+ +---
+ | iarg5
+ | :
+ | iarg3 <-- va_list._a0 + va_list._offset
+ | :
+ | iarg0 <-- va_list._a0
+ +---
+ | farg5
+ | :
+ | farg0
+ +---
+
+ When some of the arguments have known type, there is no need to
+ save all of them in the struct. So, for example, if the routine is
+ called
+
+ zork (int a0, float a1, int a2, ...)
+ {
+ va_list ap;
+ va_start (ap, a2);
+ qt_vargs (... &ap ...);
+ }
+
+ then offset is set to 3 * 8 (8 === sizeof machine word) = 24.
+
+ What this means for us is that the user's routine needs to be
+ called with an arg list where some of the words in the `any type'
+ parameter list have to be split and moved up in to the int/fp
+ region.
+
+ Ways in which this can fail:
+ - The user might not know the size of the pushed arguments anyway.
+ - Structures have funny promotion rules.
+ - Probably lots of other things.
+
+ All in all, we never promised varargs would work reliably. */
+
+
+
+#define QUICKTHREADS_VADJ(sp) (((char *)sp) - QUICKTHREADS_VSTKBASE)
+
+#define QUICKTHREADS_VARGS_MD0(sp, vabytes) \
+ ((qt_t *)(((char *)(sp)) - 6*2*8 - QUICKTHREADS_STKROUNDUP(vabytes)))
+
+extern void qt_vstart(void);
+#define QUICKTHREADS_VARGS_MD1(sp) (QUICKTHREADS_SPUT (sp, QUICKTHREADS_R26, qt_vstart))
+
+
+/* Different machines use different implementations for varargs.
+ Unfortunately, the code below ``looks in to'' the varargs
+ structure, `va_list', and thus depends on the conventions.
+ The following #defines try to deal with it but don't catch
+ everything. */
+
+#ifdef __GNUC__
+#define _a0 __base
+#define _offset __offset
+#else
+#ifdef __OSF1__
+#define _a0 a0
+#define _offset offset
+#endif
+#endif /* def __GNUC__ */
+
+
+ struct qt_t *
+qt_vargs (struct qt_t *qsp, int nbytes, struct va_list *vargs,
+ void *pt, qt_function_t *startup,
+ qt_function_t *vuserf, qt_function_t *cleanup)
+{
+ va_list ap;
+ int i;
+ int max; /* Maximum *words* of args to copy. */
+ int tmove; /* *Words* of args moved typed->typed. */
+ qt_word_t *sp;
+
+ ap = *(va_list *)vargs;
+ qsp = QUICKTHREADS_VARGS_MD0 (qsp, nbytes);
+ sp = (qt_word_t *)qsp;
+
+ tmove = 6 - ap._offset/sizeof(qt_word_t);
+
+ /* Copy from one typed area to the other. */
+ for (i=0; i<tmove; ++i) {
+ /* Integer args: */
+ sp[i+6] = ((qt_word_t *)(ap._a0 + ap._offset))[i];
+ /* Fp args: */
+ sp[i] = ((qt_word_t *)(ap._a0 + ap._offset))[i-6];
+ }
+
+ max = nbytes/sizeof(qt_word_t);
+
+ /* Copy from the untyped area to the typed area. Split each arg.
+ in to integer and floating-point save areas. */
+ for (; i<6 && i<max; ++i) {
+ sp[i] = sp[i+6] = ((qt_word_t *)(ap._a0 + ap._offset))[i];
+ }
+
+ /* Copy from the untyped area to the other untyped area. */
+ for (; i<max; ++i) {
+ sp[i+6] = ((qt_word_t *)(ap._a0 + ap._offset))[i];
+ }
+
+ QUICKTHREADS_VARGS_MD1 (QUICKTHREADS_VADJ(sp));
+ QUICKTHREADS_SPUT (QUICKTHREADS_VADJ(sp), QUICKTHREADS_VARGT_INDEX, pt);
+ QUICKTHREADS_SPUT (QUICKTHREADS_VADJ(sp), QUICKTHREADS_VSTARTUP_INDEX, startup);
+ QUICKTHREADS_SPUT (QUICKTHREADS_VADJ(sp), QUICKTHREADS_VUSERF_INDEX, vuserf);
+ QUICKTHREADS_SPUT (QUICKTHREADS_VADJ(sp), QUICKTHREADS_VCLEANUP_INDEX, cleanup);
+ return ((qt_t *)QUICKTHREADS_VADJ(sp));
+}
diff --git a/ext/systemc/src/sysc/qt/md/axp.h b/ext/systemc/src/sysc/qt/md/axp.h
new file mode 100644
index 000000000..3aac9ff1d
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/axp.h
@@ -0,0 +1,160 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+#ifndef QUICKTHREADS_AXP_H
+#define QUICKTHREADS_AXP_H
+
+#define QUICKTHREADS_GROW_DOWN
+
+typedef unsigned long qt_word_t;
+
+
+/* Stack layout on the Alpha:
+
+ Integer:
+
+ Caller-save: r0..r8, r22..r25, r27..r29
+ argument/caller-save: r16..r21
+ callee-save: r9..r15
+ return pc *callee-save*: r26
+ stack pointer: r30
+ zero: r31
+
+ Floating-point:
+
+ Caller-save: f0..f1, f10..f15
+ argument/caller-save: f16..f21, f22..f30
+ callee-save: f2..f9
+ zero: f31
+
+ Non-varargs:
+
+ +---
+ | padding
+ | f9
+ | f8
+ | f7
+ | f6
+ | f5
+ | f4
+ | f3
+ | f2
+ | r26
+ +---
+ | padding
+ | r29
+ | r15
+ | r14
+ | r13
+ | r12 on startup === `only'
+ | r11 on startup === `userf'
+ | r10 on startup === `qt'
+ | r9 on startup === `qu'
+ | r26 on startup === qt_start <--- qt.sp
+ +---
+
+ Conventions for varargs startup:
+
+ | :
+ | arg6
+ | iarg5
+ | :
+ | iarg0
+ | farg5
+ | :
+ | farg0
+ +---
+ | padding
+ | r29
+ | r15
+ | r14
+ | r13
+ | r12 on startup === `startup'
+ | r11 on startup === `vuserf'
+ | r10 on startup === `cleanup'
+ | r9 on startup === `qt'
+ | r26 on startup === qt_vstart <--- qt.sp
+ +---
+
+ Note: this is a pretty cheap/sleazy way to get things going,
+ but ``there must be a better way.'' For instance, some varargs
+ parameters could be loaded in to integer registers, or the return
+ address could be stored on top of the stack. */
+
+
+/* Stack must be 16-byte aligned. */
+#define QUICKTHREADS_STKALIGN (16)
+
+/* How much space is allocated to hold all the crud for
+ initialization: 7 registers times 8 bytes/register. */
+
+#define QUICKTHREADS_STKBASE (10 * 8)
+#define QUICKTHREADS_VSTKBASE QUICKTHREADS_STKBASE
+
+
+/* Offsets of various registers. */
+#define QUICKTHREADS_R26 0
+#define QUICKTHREADS_R9 1
+#define QUICKTHREADS_R10 2
+#define QUICKTHREADS_R11 3
+#define QUICKTHREADS_R12 4
+
+
+/* When a never-before-run thread is restored, the return pc points
+ to a fragment of code that starts the thread running. For
+ non-vargs functions, it just calls the client's `only' function.
+ For varargs functions, it calls the startup, user, and cleanup
+ functions.
+
+ The varargs startup routine always reads 12 8-byte arguments from
+ the stack. If fewer argumets were pushed, the startup routine
+ would read off the top of the stack. To prevent errors we always
+ allocate enough space. When there are fewer args, the preallocated
+ words are simply wasted. */
+
+extern void qt_start(void);
+#define QUICKTHREADS_ARGS_MD(sp) (QUICKTHREADS_SPUT (sp, QUICKTHREADS_R26, qt_start))
+
+
+/* The AXP uses a struct for `va_list', so pass a pointer to the
+ struct. This may break some uses of `QUICKTHREADS_VARGS', but then we never
+ claimed it was totally portable. */
+
+typedef void (qt_function_t)(void);
+
+struct qt_t;
+struct va_list;
+extern struct qt_t *qt_vargs (struct qt_t *sp, int nbytes,
+ struct va_list *vargs, void *pt,
+ qt_function_t *startup,
+ qt_function_t *vuserf,
+ qt_function_t *cleanup);
+
+#define QUICKTHREADS_VARGS(sp, nbytes, vargs, pt, startup, vuserf, cleanup) \
+ (qt_vargs (sp, nbytes, (struct va_list *)(&(vargs)), pt, \
+ (qt_function_t *) startup, (qt_function_t *)vuserf, \
+ (qt_function_t *)cleanup));
+
+
+/* The *index* (positive offset) of where to put each value. */
+#define QUICKTHREADS_ONLY_INDEX (QUICKTHREADS_R12)
+#define QUICKTHREADS_USER_INDEX (QUICKTHREADS_R11)
+#define QUICKTHREADS_ARGT_INDEX (QUICKTHREADS_R10)
+#define QUICKTHREADS_ARGU_INDEX (QUICKTHREADS_R9)
+
+#define QUICKTHREADS_VCLEANUP_INDEX (QUICKTHREADS_R10)
+#define QUICKTHREADS_VUSERF_INDEX (QUICKTHREADS_R11)
+#define QUICKTHREADS_VSTARTUP_INDEX (QUICKTHREADS_R12)
+#define QUICKTHREADS_VARGT_INDEX (QUICKTHREADS_R9)
+
+#endif /* ndef QUICKTHREADS_AXP_H */
diff --git a/ext/systemc/src/sysc/qt/md/axp.s b/ext/systemc/src/sysc/qt/md/axp.s
new file mode 100644
index 000000000..a84aab2cc
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/axp.s
@@ -0,0 +1,160 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+/* axp.s -- assembly support. */
+
+ .text
+ .align 4
+ .file 2 "axp.s"
+
+ .globl qt_block
+ .globl qt_blocki
+ .globl qt_abort
+ .globl qt_start
+ .globl qt_vstart
+
+ /*
+ ** $16: ptr to function to call once curr is suspended
+ ** and control is on r19's stack.
+ ** $17: 1'th arg to (*$16)(...).
+ ** $18: 2'th arg to (*$16)(...).
+ ** $19: sp of thread to resume.
+ **
+ ** The helper routine returns a value that is passed on as the
+ ** return value from the blocking routine. Since we don't
+ ** touch r0 between the helper's return and the end of
+ ** function, we get this behavior for free.
+ */
+
+ .ent qt_blocki
+qt_blocki:
+ subq $30,80, $30 /* Allocate save area. */
+ stq $26, 0($30) /* Save registers. */
+ stq $9, 8($30)
+ stq $10,16($30)
+ stq $11,24($30)
+ stq $12,32($30)
+ stq $13,40($30)
+ stq $14,48($30)
+ stq $15,56($30)
+ stq $29,64($30)
+ .end qt_blocki
+ .ent qt_abort
+qt_abort:
+ addq $16,$31, $27 /* Put argument function in PV. */
+ addq $30,$31, $16 /* Save stack ptr in outgoing arg. */
+ addq $19,$31, $30 /* Set new stack pointer. */
+ jsr $26,($27),0 /* Call helper function. */
+
+ ldq $26, 0($30) /* Restore registers. */
+ ldq $9, 8($30)
+ ldq $10,16($30)
+ ldq $11,24($30)
+ ldq $12,32($30)
+ ldq $13,40($30)
+ ldq $14,48($30)
+ ldq $15,56($30)
+ ldq $29,64($30)
+
+ addq $30,80, $30 /* Deallocate save area. */
+ ret $31,($26),1 /* Return, predict===RET. */
+ .end qt_abort
+
+
+ /*
+ ** Non-varargs thread startup.
+ */
+ .ent qt_start
+qt_start:
+ addq $9,$31, $16 /* Load up `qu'. */
+ addq $10,$31, $17 /* ... user function's `pt'. */
+ addq $11,$31, $18 /* ... user function's `userf'. */
+ addq $12,$31, $27 /* ... set procedure value to `only'. */
+ jsr $26,($27),0 /* Call `only'. */
+
+ jsr $26,qt_error /* `only' erroniously returned. */
+ .end qt_start
+
+
+ .ent qt_vstart:
+qt_vstart:
+ /* Call startup function. */
+ addq $9,$31, $16 /* Arg0 to `startup'. */
+ addq $12,$31, $27 /* Set procedure value. */
+ jsr $26,($27),0 /* Call `startup'. */
+
+ /* Call user function. */
+ ldt $f16, 0($30) /* Load fp arg regs. */
+ ldt $f17, 8($30)
+ ldt $f18,16($30)
+ ldt $f19,24($30)
+ ldt $f20,32($30)
+ ldt $f21,40($30)
+ ldq $16,48($30) /* And integer arg regs. */
+ ldq $17,56($30)
+ ldq $18,64($30)
+ ldq $19,72($30)
+ ldq $20,80($30)
+ ldq $21,88($30)
+ addq $30,96 $30 /* Pop 6*2*8 saved arg regs. */
+ addq $11,$31, $27 /* Set procedure value. */
+ jsr $26,($27),0 /* Call `vuserf'. */
+
+ /* Call cleanup. */
+ addq $9,$31, $16 /* Arg0 to `cleanup'. */
+ addq $0,$31, $17 /* Users's return value is arg1. */
+ addq $10,$31, $27 /* Set procedure value. */
+ jsr $26,($27),0 /* Call `cleanup'. */
+
+ jsr $26,qt_error /* Cleanup erroniously returned. */
+ .end qt_start
+
+
+ /*
+ ** Save calle-save floating-point regs $f2..$f9.
+ ** Also save return pc from whomever called us.
+ **
+ ** Return value from `qt_block' is the same as the return from
+ ** `qt_blocki'. We get that for free since we don't touch $0
+ ** between the return from `qt_blocki' and the return from
+ ** `qt_block'.
+ */
+ .ent qt_block
+qt_block:
+ subq $30,80, $30 /* Allocate a save space. */
+ stq $26, 0($30) /* Save registers. */
+ stt $f2, 8($30)
+ stt $f3,16($30)
+ stt $f4,24($30)
+ stt $f5,32($30)
+ stt $f6,40($30)
+ stt $f7,48($30)
+ stt $f8,56($30)
+ stt $f9,64($30)
+
+ jsr $26,qt_blocki /* Call helper. */
+ /* .. who will also restore $gp. */
+
+ ldq $26, 0($30) /* restore registers. */
+ ldt $f2, 8($30)
+ ldt $f3,16($30)
+ ldt $f4,24($30)
+ ldt $f5,32($30)
+ ldt $f6,40($30)
+ ldt $f7,48($30)
+ ldt $f8,56($30)
+ ldt $f9,64($30)
+
+ addq $30,80, $30 /* Deallcate save space. */
+ ret $31,($26),1 /* Return, predict===RET. */
+ .end qt_block
diff --git a/ext/systemc/src/sysc/qt/md/axp_b.s b/ext/systemc/src/sysc/qt/md/axp_b.s
new file mode 100644
index 000000000..60be726ff
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/axp_b.s
@@ -0,0 +1,111 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+ .text
+ .globl b_call_reg
+ .globl b_call_imm
+ .globl b_add
+ .globl b_load
+
+ .ent b_null
+b_null:
+ ret $31,($18),1
+ .end b_null
+
+ .ent b_call_reg
+b_call_reg:
+ lda $27,b_null
+$L0:
+ jsr $18,($27)
+ jsr $18,($27)
+ jsr $18,($27)
+ jsr $18,($27)
+ jsr $18,($27)
+
+ jsr $18,($27)
+ jsr $18,($27)
+ jsr $18,($27)
+ jsr $18,($27)
+ jsr $18,($27)
+
+ subq $16,1,$16
+ bgt $16,$L0
+
+ ret $31,($26),1
+ .end
+
+
+ .ent b_call_imm
+b_call_imm:
+$L1:
+ jsr $18,b_null
+ jsr $18,b_null
+ jsr $18,b_null
+ jsr $18,b_null
+ jsr $18,b_null
+
+ jsr $18,b_null
+ jsr $18,b_null
+ jsr $18,b_null
+ jsr $18,b_null
+ jsr $18,b_null
+
+ subq $16,1,$16
+ bgt $16,$L1
+
+ ret $31,($26),1
+ .end
+
+
+ .ent b_add
+b_add:
+$L2:
+ addq $31,$31,$31
+ addq $31,$31,$31
+ addq $31,$31,$31
+ addq $31,$31,$31
+ addq $31,$31,$31
+
+ addq $31,$31,$31
+ addq $31,$31,$31
+ addq $31,$31,$31
+ addq $31,$31,$31
+ addq $31,$31,$31
+
+ subq $16,1,$16
+ bgt $16,$L2
+
+ ret $31,($26),1
+ .end
+
+
+ .ent b_load
+b_load:
+$L3:
+ ldq $31,0($30)
+ ldq $31,8($30)
+ ldq $31,16($30)
+ ldq $31,24($30)
+ ldq $31,32($30)
+
+ ldq $31,0($30)
+ ldq $31,8($30)
+ ldq $31,16($30)
+ ldq $31,24($30)
+ ldq $31,32($30)
+
+ subq $16,1,$16
+ bgt $16,$L3
+
+ ret $31,($26),1
+ .end
diff --git a/ext/systemc/src/sysc/qt/md/default.Makefile b/ext/systemc/src/sysc/qt/md/default.Makefile
new file mode 100644
index 000000000..2f3ded151
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/default.Makefile
@@ -0,0 +1,8 @@
+
+#
+# `Normal' configuration.
+#
+CC = gcc -ansi -Wall -pedantic
+
+.o.s:
+ as -o $@ $<
diff --git a/ext/systemc/src/sysc/qt/md/hppa-cnx.Makefile b/ext/systemc/src/sysc/qt/md/hppa-cnx.Makefile
new file mode 100644
index 000000000..bff257d9f
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/hppa-cnx.Makefile
@@ -0,0 +1,9 @@
+# This file (cnx_spp.Makefile) is part of the port of QuickThreads for
+# PA-RISC 1.1 architecture on a Convex SPP. This file is a machine dependent
+# makefile for QuickThreads. It was written in 1994 by Uwe Reder
+# (`uereder@cip.informatik.uni-erlangen.de') for the Operating Systems
+# Department (IMMD4) at the University of Erlangen/Nuernberg Germany.
+
+# `Normal' configuration.
+
+CC = /usr/convex/bin/cc
diff --git a/ext/systemc/src/sysc/qt/md/hppa.Makefile b/ext/systemc/src/sysc/qt/md/hppa.Makefile
new file mode 100644
index 000000000..bf770ae3b
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/hppa.Makefile
@@ -0,0 +1,12 @@
+# This file (pa-risc.Makefile) is part of the port of QuickThreads for
+# PA-RISC 1.1 architecture. This file is a machine dependent makefile
+# for QuickThreads. It was written in 1994 by Uwe Reder
+# (`uereder@cip.informatik.uni-erlangen.de') for the Operating Systems
+# Department (IMMD4) at the University of Erlangen/Nuernberg Germany.
+
+# `Normal' configuration.
+
+CC = cc -Aa
+
+.s.o:
+ /usr/ccs/bin/as -o $@ $<
diff --git a/ext/systemc/src/sysc/qt/md/hppa.h b/ext/systemc/src/sysc/qt/md/hppa.h
new file mode 100644
index 000000000..fdb9cef93
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/hppa.h
@@ -0,0 +1,196 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+/*
+ * This file (pa-risc.h) is part of the port of QuickThreads for the
+ * PA-RISC 1.1 architecture. This file is a machine dependent header
+ * file. It was written in 1994 by Uwe Reder
+ * (`uereder@cip.informatik.uni-erlangen.de') for the Operating Systems
+ * Department (IMMD4) at the University of Erlangen/Nuernberg Germany.
+ */
+
+
+#ifndef QUICKTHREADS_PA_RISC_H
+#define QUICKTHREADS_PA_RISC_H
+
+#if 0
+#include <qt.h>
+#endif
+
+/* size of an integer-register (32 bit) */
+typedef unsigned long qt_word_t;
+
+/* PA-RISC's stack grows up */
+#define QUICKTHREADS_GROW_UP
+
+/* Stack layout on PA-RISC according to PA-RISC Procedure Calling Conventions:
+
+ Callee-save registers are: gr3-gr18, fr12-fr21.
+ Also save gr2, return pointer.
+
+ +---
+ | fr12 Each floating register is a double word (8 bytes).
+ | fr13 Floating registers are only saved if `qt_block' is
+ | fr14 called, in which case it saves the floating-point
+ | fr15 registers then calls `qt_blocki' to save the integer
+ | fr16 registers.
+ | fr17
+ | fr18
+ | fr19
+ | fr20
+ | fr21
+ | <arg word 3> fixed arguments (must be allocated; may remain unused)
+ | <arg word 2>
+ | <arg word 1>
+ | <arg word 0>
+ | <LPT> frame marker
+ | <LPT'>
+ | <RP'>
+ | <Current RP>
+ | <Static Link>
+ | <Clean Up>
+ | <RP''>
+ | <Previous SP>
+ +---
+ | gr3 word each (4 bytes)
+ | gr4
+ | gr5
+ | gr6
+ | gr7
+ | gr8
+ | gr9
+ | gr10
+ | gr11
+ | gr12
+ | gr13
+ | gr14
+ | gr15
+ | gr16
+ | gr17
+ | gr18
+ | <16 bytes filled in (sp has to be 64-bytes aligned)>
+ | <arg word 3> fixed arguments (must be allocated; may remain unused)
+ | <arg word 2>
+ | <arg word 1>
+ | <arg word 0>
+ | <LPT> frame marker
+ | <LPT'>
+ | <RP'>
+ | <Current RP>
+ | <Static Link>
+ | <Clean Up>
+ | <RP''>
+ | <Previous SP>
+ +--- <--- sp
+*/
+
+/* When a never-before-run thread is restored, the return pc points
+ to a fragment of code that starts the thread running. For
+ non-vargs functions, it just calls the client's `only' function.
+ For varargs functions, it calls the startup, user, and cleanup
+ functions. */
+
+/* Note: Procedue Labels on PA-RISC
+
+ <--2--><-------28---------><1-><1->
+ -----------------------------------
+ | SID | Adress Part | L | X |
+ -----------------------------------
+
+ On HP-UX the L field is used to flag wheather the procedure
+ label (plabel) is a pointer to an LT entry or to the entry point
+ of the procedure (PA-RISC Procedure Calling Conventions Reference
+ Manual, 5.3.2 Procedure Labels and Dynamic Calls). */
+
+#define QUICKTHREADS_PA_RISC_READ_PLABEL(plabel) \
+ ( (((int)plabel) & 2) ? \
+ ( (*((int *)(((int)plabel) & 0xfffffffc)))) : ((int)plabel) )
+
+/* Stack must be 64 bytes aligned. */
+#define QUICKTHREADS_STKALIGN (64)
+
+/* Internal helper for putting stuff on stack (negative index!). */
+#define QUICKTHREADS_SPUT(top, at, val) \
+ (((qt_word_t *)(top))[-(at)] = (qt_word_t)(val))
+
+/* Offsets of various registers which are modified on the stack.
+ rp (return-pointer) has to be stored in the frame-marker-area
+ of the "older" stack-segment. */
+
+#define QUICKTHREADS_crp (12+4+16+5)
+#define QUICKTHREADS_15 (12+4+4)
+#define QUICKTHREADS_16 (12+4+3)
+#define QUICKTHREADS_17 (12+4+2)
+#define QUICKTHREADS_18 (12+4+1)
+
+
+/** This stuff is for NON-VARARGS. **/
+
+/* Stack looks like this (2 stack frames):
+
+ <--- 64-bytes aligned --><------- 64-bytes aligned ------------>
+ | || |
+ <--16--><------48-------><----16*4-----><--16-><------48------->
+ || | || | | ||
+ ||filler|arg|frame-marker||register-save|filler|arg|frame-marker||
+ ------------------------------------------------------------------
+ */
+
+#define QUICKTHREADS_STKBASE (16+48+(16*sizeof(qt_word_t))+16+48)
+
+/* The index, relative to sp, of where to put each value. */
+#define QUICKTHREADS_ONLY_INDEX (QUICKTHREADS_15)
+#define QUICKTHREADS_USER_INDEX (QUICKTHREADS_16)
+#define QUICKTHREADS_ARGT_INDEX (QUICKTHREADS_17)
+#define QUICKTHREADS_ARGU_INDEX (QUICKTHREADS_18)
+
+extern void qt_start(void);
+#define QUICKTHREADS_ARGS_MD(sp) \
+ (QUICKTHREADS_SPUT (sp, QUICKTHREADS_crp, QUICKTHREADS_PA_RISC_READ_PLABEL(qt_start)))
+
+
+/** This is for VARARGS. **/
+
+#define QUICKTHREADS_VARGS_DEFAULT
+
+/* Stack looks like this (2 stack frames):
+
+ <------ 64-bytes aligned -------><--------- 64-bytes aligned ---------->
+ | || |
+ <---?--><--?---><16><----32-----><----16*4-----><-16--><16><----32----->
+ || | | | || | | | ||
+ ||filler|varargs|arg|frame-marker||register-save|filler|arg|frame-marker||
+ --------------------------------------------------------------------------
+ */
+
+/* Sp is moved to the end of the first stack frame. */
+#define QUICKTHREADS_VARGS_MD0(sp, vasize) \
+ ((qt_t *)(((char *)sp) + QUICKTHREADS_STKROUNDUP(vasize + 4*4 + 32)))
+
+/* To reach the arguments from the end of the first stack frame use 32
+ as a negative adjustment. */
+#define QUICKTHREADS_VARGS_ADJUST(sp) ((qt_t *)(((char *)sp) - 32))
+
+/* Offset to reach the end of the second stack frame. */
+#define QUICKTHREADS_VSTKBASE ((16*sizeof(qt_word_t)) + 16 + 4*4 + 32)
+
+extern void qt_vstart(void);
+#define QUICKTHREADS_VARGS_MD1(sp) \
+ (QUICKTHREADS_SPUT (sp, QUICKTHREADS_crp, QUICKTHREADS_PA_RISC_READ_PLABEL(qt_vstart)))
+
+#define QUICKTHREADS_VARGT_INDEX (QUICKTHREADS_15)
+#define QUICKTHREADS_VSTARTUP_INDEX (QUICKTHREADS_16)
+#define QUICKTHREADS_VUSERF_INDEX (QUICKTHREADS_17)
+#define QUICKTHREADS_VCLEANUP_INDEX (QUICKTHREADS_18)
+
+#endif /* ndef QUICKTHREADS_PA_RISC_H */
diff --git a/ext/systemc/src/sysc/qt/md/hppa.s b/ext/systemc/src/sysc/qt/md/hppa.s
new file mode 100644
index 000000000..84d8e875b
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/hppa.s
@@ -0,0 +1,237 @@
+; pa-risc.s -- assembly support.
+
+; QuickThreads -- Threads-building toolkit.
+; Copyright (c) 1993 by David Keppel
+;
+; Permission to use, copy, modify and distribute this software and
+; its documentation for any purpose and without fee is hereby
+; granted, provided that the above copyright notice and this notice
+; appear in all copies. This software is provided as a
+; proof-of-concept and for demonstration purposes; there is no
+; representation about the suitability of this software for any
+; purpose.
+
+; This file (pa-risc.s) is part of the port of QuickThreads for
+; PA-RISC 1.1 architecture. This file implements context switches
+; and thread startup. It was written in 1994 by Uwe Reder
+; (`uereder@cip.informatik.uni-erlangen.de') for the Operating
+; Systems Department (IMMD4) at the University of Erlangen/Nuernberg
+; Germany.
+
+
+; Callee saves general registers gr3..gr18,
+; floating-point registers fr12..fr21.
+
+ .CODE
+
+ .IMPORT $$dyncall, MILLICODE
+ .IMPORT qt_error, CODE
+
+ .EXPORT qt_blocki, ENTRY
+ .EXPORT qt_block, ENTRY
+ .EXPORT qt_abort, ENTRY
+ .EXPORT qt_start, ENTRY
+ .EXPORT qt_vstart, ENTRY
+
+
+; arg0: ptr to function (helper) to call once curr is suspended
+; and control is on arg3's stack.
+; arg1: 1'th arg to *arg0.
+; arg2: 2'th arg to *arg0.
+; arg3: sp of new thread.
+
+qt_blocki
+ .PROC
+ .CALLINFO CALLER, FRAME=0, SAVE_RP, ENTRY_GR=18
+ .ENTRY
+
+ stw %rp,-20(%sp) ; save rp to old frame-marker
+
+ stwm %r3,128(%sp) ; save callee-saves general registers
+ stw %r4,-124(%sp)
+ stw %r5,-120(%sp)
+ stw %r6,-116(%sp)
+ stw %r7,-112(%sp)
+ stw %r8,-108(%sp)
+ stw %r9,-104(%sp)
+ stw %r10,-100(%sp)
+ stw %r11,-96(%sp)
+ stw %r12,-92(%sp)
+ stw %r13,-88(%sp)
+ stw %r14,-84(%sp)
+ stw %r15,-80(%sp)
+ stw %r16,-76(%sp)
+ stw %r17,-72(%sp)
+ stw %r18,-68(%sp)
+
+qt_abort
+ copy %arg0,%r22 ; helper to be called by $$dyncall
+ copy %sp,%arg0 ; pass current sp as arg0 to helper
+ copy %arg3,%sp ; set new sp
+
+ .CALL
+ bl $$dyncall,%mrp ; call helper
+ copy %mrp,%rp
+
+ ldw -68(%sp),%r18 ; restore general registers
+ ldw -72(%sp),%r17
+ ldw -76(%sp),%r16
+ ldw -80(%sp),%r15
+ ldw -84(%sp),%r14
+ ldw -88(%sp),%r13
+ ldw -92(%sp),%r12
+ ldw -96(%sp),%r11
+ ldw -100(%sp),%r10
+ ldw -104(%sp),%r9
+ ldw -108(%sp),%r8
+ ldw -112(%sp),%r7
+ ldw -116(%sp),%r6
+ ldw -120(%sp),%r5
+ ldw -124(%sp),%r4
+
+ ldw -148(%sp),%rp ; restore return-pointer
+
+ bv %r0(%rp) ; return to caller
+ ldwm -128(%sp),%r3
+
+ .EXIT
+ .PROCEND
+
+
+qt_block
+ .PROC
+ .CALLINFO CALLER, FRAME=0, SAVE_RP, ENTRY_FR=21
+ .ENTRY
+
+ stw %rp,-20(%sp) ; save rp to old frame-marker
+
+ fstds,ma %fr12,8(%sp) ; save callee-saves float registers
+ fstds,ma %fr13,8(%sp)
+ fstds,ma %fr14,8(%sp)
+ fstds,ma %fr15,8(%sp)
+ fstds,ma %fr16,8(%sp)
+ fstds,ma %fr17,8(%sp)
+ fstds,ma %fr18,8(%sp)
+ fstds,ma %fr19,8(%sp)
+ fstds,ma %fr20,8(%sp)
+ fstds,ma %fr21,8(%sp)
+
+ .CALL
+ bl qt_blocki,%rp
+ ldo 48(%sp),%sp
+
+ ldo -48(%sp),%sp
+
+ fldds,mb -8(%sp),%fr21 ; restore callee-saves float registers
+ fldds,mb -8(%sp),%fr20
+ fldds,mb -8(%sp),%fr19
+ fldds,mb -8(%sp),%fr18
+ fldds,mb -8(%sp),%fr17
+ fldds,mb -8(%sp),%fr16
+ fldds,mb -8(%sp),%fr15
+ fldds,mb -8(%sp),%fr14
+ fldds,mb -8(%sp),%fr13
+
+ ldw -28(%sp),%rp ; restore return-pointer
+
+ bv %r0(%rp) ; return to caller.
+ fldds,mb -8(%sp),%fr12
+
+ .EXIT
+ .PROCEND
+
+
+qt_start
+ .PROC
+ .CALLINFO CALLER, FRAME=0
+ .ENTRY
+
+ copy %r18,%arg0 ; set user arg `pu'.
+ copy %r17,%arg1 ; ... user function pt.
+ copy %r16,%arg2 ; ... user function userf.
+ ; %r22 is a caller-saves register
+ copy %r15,%r22 ; function to be called by $$dyncall
+
+ .CALL ; in=%r22
+ bl $$dyncall,%mrp ; call `only'.
+ copy %mrp,%rp
+
+ bl,n qt_error,%r0 ; `only' erroniously returned.
+
+ .EXIT
+ .PROCEND
+
+
+; Varargs
+;
+; First, call `startup' with the `pt' argument.
+;
+; Next, call the user's function with all arguments.
+; We don't know whether arguments are integers, 32-bit floating-points or
+; even 64-bit floating-points, so we reload all the registers, possibly
+; with garbage arguments. The thread creator provided non-garbage for
+; the arguments that the callee actually uses, so the callee never gets
+; garbage.
+;
+; -48 -44 -40 -36 -32
+; | arg3 | arg2 | arg1 | arg0 |
+; -----------------------------
+; integers: arg3 arg2 arg1 arg0
+; 32-bit fps: farg3 farg2 farg1 farg0
+; 64-bit fps: <---farg3--> <---farg1-->
+;
+; Finally, call `cleanup' with the `pt' argument and with the return value
+; from the user's function. It is an error for `cleanup' to return.
+
+qt_vstart
+ .PROC
+ .CALLINFO CALLER, FRAME=0
+ .ENTRY
+
+ ; Because the startup function may damage the fixed arguments
+ ; on the stack (PA-RISC Procedure Calling Conventions Reference
+ ; Manual, 2.4 Fixed Arguments Area), we allocate a seperate
+ ; stack frame for it.
+ ldo 64(%sp),%sp
+
+ ; call: void startup(void *pt)
+
+ copy %r15,%arg0 ; `pt' is arg0 to `startup'.
+ copy %r16,%r22
+ .CALL
+ bl $$dyncall,%mrp ; Call `startup'.
+ copy %mrp,%rp
+
+ ldo -64(%sp),%sp
+
+ ; call: void *qt_vuserf_t(...)
+
+ ldw -36(%sp),%arg0 ; Load args to integer registers.
+ ldw -40(%sp),%arg1
+ ldw -44(%sp),%arg2
+ ldw -48(%sp),%arg3
+ ; Index of fld[w|d]s only ranges from -16 to 15, so we
+ ; take r22 to be our new base register.
+ ldo -32(%sp),%r22
+ fldws -4(%r22),%farg0 ; Load args to floating-point registers.
+ fldds -8(%r22),%farg1
+ fldws -12(%r22),%farg2
+ fldds -16(%r22),%farg3
+ copy %r17,%r22
+ .CALL
+ bl $$dyncall,%mrp ; Call `userf'.
+ copy %mrp,%rp
+
+ ; call: void cleanup(void *pt, void *vuserf_return)
+
+ copy %r15,%arg0 ; `pt' is arg0 to `cleanup'.
+ copy %ret0,%arg1 ; Return-value is arg1 to `cleanup'.
+ copy %r18,%r22
+ .CALL
+ bl $$dyncall,%mrp ; Call `cleanup'.
+ copy %mrp,%rp
+
+ bl,n qt_error,%r0
+
+ .EXIT
+ .PROCEND
diff --git a/ext/systemc/src/sysc/qt/md/hppa_b.s b/ext/systemc/src/sysc/qt/md/hppa_b.s
new file mode 100644
index 000000000..1b1e8264e
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/hppa_b.s
@@ -0,0 +1,203 @@
+; QuickThreads -- Threads-building toolkit.
+; Copyright (c) 1993 by David Keppel
+
+; Permission to use, copy, modify and distribute this software and
+; its documentation for any purpose and without fee is hereby
+; granted, provided that the above copyright notice and this notice
+; appear in all copies. This software is provided as a
+; proof-of-concept and for demonstration purposes; there is no
+; representation about the suitability of this software for any
+; purpose.
+
+; This file (pa-risc_b.s) is part of the port of QuickThreads for
+; PA-RISC 1.1 architecture. It contains assembly-level support for
+; raw processor performance measurement. It was written in 1994 by
+; Uwe Reder (`uereder@cip.informatik.uni-erlangen.de')
+; for the Operating Systems Department (IMMD4) at the
+; University of Erlangen/Nuernberg Germany.
+
+
+; Note that the number of instructions in the measurement-loops, differ
+; from implementation to implementation. I took eight instructions in a loop
+; for every test (execute eight instructions and loop to the start).
+
+ .CODE
+
+ .IMPORT $global$,DATA
+ .IMPORT $$dyncall,MILLICODE
+ .EXPORT b_call_reg
+ .EXPORT b_call_imm
+ .EXPORT b_add
+ .EXPORT b_load
+
+; Just do nothing, only return to caller. This procedure is called by
+; `b_call_reg' and `b_call_imm'.
+
+b_null
+ .PROC
+ .CALLINFO NO_CALLS, FRAME=0
+ .ENTRY
+
+ bv,n %r0(%rp) ; just return
+
+ .EXIT
+ .PROCEND
+
+; Call the procedure `b_null' with function pointer in a register.
+
+b_call_reg
+ .PROC
+ .CALLINFO CALLER, FRAME=0
+ .ENTRY
+
+ stwm %r3,64(%sp) ; store r3 (may be used by caller)
+ stw %rp,-20(%sp) ; save return-pointer to frame-marker
+
+ addil LR'to_call-$global$,%r27
+ ldw RR'to_call-$global$(%r1),%r3
+
+_loop0
+ copy %r3,%r22 ; copy the procedure label to r22, ...
+ .CALL ; ...this is the input to $$dyncall
+ bl $$dyncall,%mrp ; call $$dyncall (millicode function)
+ copy %mrp,%rp ; remember the return-pointer
+
+ copy %r3,%r22
+ .CALL
+ bl $$dyncall,%mrp
+ copy %mrp,%rp
+
+ copy %r3,%r22
+ .CALL
+ bl $$dyncall,%mrp
+ copy %mrp,%rp
+
+ copy %r3,%r22
+ .CALL
+ bl $$dyncall,%mrp
+ copy %mrp,%rp
+
+ copy %r3,%r22
+ .CALL
+ bl $$dyncall,%mrp
+ copy %mrp,%rp
+
+ copy %r3,%r22
+ .CALL
+ bl $$dyncall,%mrp
+ copy %mrp,%rp
+
+ copy %r3,%r22
+ .CALL
+ bl $$dyncall,%mrp
+ copy %mrp,%rp
+
+ copy %r3,%r22
+ .CALL
+ bl $$dyncall,%mrp
+ copy %mrp,%rp
+
+ addibf,<= -8,%arg0,_loop0 ; decrement counter by 8 and loop
+ nop
+
+ ldw -20(%sp),%rp ; restore return-pointer
+ bv %r0(%rp) ; return to caller
+ ldwm -64(%sp),%r3 ; resore r3 and remove stack frame
+
+ .EXIT
+ .PROCEND
+
+; Call the procedure `b_null' immediate.
+
+b_call_imm
+ .PROC
+ .CALLINFO CALLER, FRAME=0, SAVE_RP
+ .ENTRY
+
+ ldo 64(%sp),%sp ; caller needs a stack-frame
+ stw %rp,-20(%sp) ; save return-pointer to frame-marker
+
+_loop1
+ bl b_null,%rp ; call `b_null' immediate (8 times)
+ nop
+ bl b_null,%rp
+ nop
+ bl b_null,%rp
+ nop
+ bl b_null,%rp
+ nop
+ bl b_null,%rp
+ nop
+ bl b_null,%rp
+ nop
+ bl b_null,%rp
+ nop
+ bl b_null,%rp
+ nop
+
+ addibf,<= -8,%arg0,_loop1 ; decrement counter by 8 and loop
+ nop
+
+ ldw -20(%sp),%rp ; restore return-pointer
+ bv %r0(%rp) ; return to caller
+ ldo -64(%sp),%sp ; remove stack-frame
+
+ .EXIT
+ .PROCEND
+
+; Copy register-to-register.
+; On PA-RISC this is implemented with an `or'.
+; The `or' is hidden by a pseudo-operation called `copy'.
+
+b_add
+ .PROC
+ .CALLINFO NO_CALLS, FRAME=0
+ .ENTRY
+
+_loop2
+ copy %r19,%r20 ; copy register-to-register
+ copy %r20,%r21 ; use caller-saves registers
+ copy %r21,%r22
+ copy %r22,%r21
+ copy %r21,%r20
+ copy %r20,%r19
+ copy %r19,%r20
+ copy %r20,%r21
+
+ addibf,<= -8,%arg0,_loop2 ; decrement counter by 8 and loop
+ nop
+
+ bv,n %r0(%rp)
+
+ .EXIT
+ .PROCEND
+
+; Load memory to a register.
+
+b_load
+ .PROC
+ .CALLINFO NO_CALLS, FRAME=0
+ .ENTRY
+
+_loop3
+ ldw -4(%sp),%r22 ; load data from frame-marker
+ ldw -8(%sp),%r22 ; use a caller-saves register
+ ldw -12(%sp),%r22
+ ldw -16(%sp),%r22
+ ldw -20(%sp),%r22
+ ldw -24(%sp),%r22
+ ldw -28(%sp),%r22
+ ldw -32(%sp),%r22
+
+ addibf,<= -8,%arg0,_loop3 ; decrement counter by 8 and loop
+ nop
+
+ bv,n %r0(%rp)
+
+ .EXIT
+ .PROCEND
+
+
+ .ALIGN 8
+to_call
+ .WORD b_null
diff --git a/ext/systemc/src/sysc/qt/md/i386.README b/ext/systemc/src/sysc/qt/md/i386.README
new file mode 100644
index 000000000..8ffb92198
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/i386.README
@@ -0,0 +1,7 @@
+Note that some machines want labels to have leading underscores,
+while others (e.g. System V) do not. Thus, several labels appear
+duplicated except for the leading underscore, e.g.
+
+ _qt_cswap:
+ qt_cswap:
+
diff --git a/ext/systemc/src/sysc/qt/md/i386.h b/ext/systemc/src/sysc/qt/md/i386.h
new file mode 100644
index 000000000..04513857e
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/i386.h
@@ -0,0 +1,132 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+#ifndef QUICKTHREADS_386_H
+#define QUICKTHREADS_386_H
+
+typedef unsigned long qt_word_t;
+
+/* Thread's initial stack layout on the i386:
+
+ non-varargs:
+
+ +---
+ | arg[2] === `userf' on startup
+ | arg[1] === `pt' on startup
+ | arg[0] === `pu' on startup
+ +---
+ | ret pc === qt_error
+ +---
+ | ret pc === `only' on startup
+ +---
+ | %ebp
+ | %esi
+ | %edi
+ | %ebx <--- qt_t.sp
+ +---
+
+ When a non-varargs thread is started, it ``returns'' directly to
+ the client's `only' function.
+
+ varargs:
+
+ +---
+ | arg[n-1]
+ | ..
+ | arg[0]
+ +---
+ | ret pc === `qt_vstart'
+ +---
+ | %ebp === `startup'
+ | %esi === `cleanup'
+ | %edi === `pt'
+ | %ebx === `vuserf' <--- qt_t.sp
+ +---
+
+ When a varargs thread is started, it ``returns'' to the `qt_vstart'
+ startup code. The startup code calls the appropriate functions. */
+
+
+/* What to do to start a varargs thread running. */
+extern void qt_vstart (void);
+
+
+/* Hold 4 saved regs plus two return pcs (qt_error, qt_start) plus
+ three args. */
+#define QUICKTHREADS_STKBASE (13 * 4)
+
+/* Hold 4 saved regs plus one return pc (qt_vstart). */
+#define QUICKTHREADS_VSTKBASE (5 * 4)
+
+
+/* Stack must be 16-byte aligned at function call instr. (SSE data support) */
+#define QUICKTHREADS_STKALIGN (16)
+
+
+/* Where to place various arguments. */
+#define QUICKTHREADS_ONLY_INDEX (QUICKTHREADS_PC)
+#define QUICKTHREADS_USER_INDEX (QUICKTHREADS_ARG2)
+#define QUICKTHREADS_ARGT_INDEX (QUICKTHREADS_ARG1)
+#define QUICKTHREADS_ARGU_INDEX (QUICKTHREADS_ARG0)
+
+#define QUICKTHREADS_VSTARTUP_INDEX (QUICKTHREADS_EBP)
+#define QUICKTHREADS_VUSERF_INDEX (QUICKTHREADS_EBX)
+#define QUICKTHREADS_VCLEANUP_INDEX (QUICKTHREADS_ESI)
+#define QUICKTHREADS_VARGT_INDEX (QUICKTHREADS_EDI)
+
+
+#define QUICKTHREADS_EBX 0
+#define QUICKTHREADS_EDI 1
+#define QUICKTHREADS_ESI 2
+#define QUICKTHREADS_EBP 3
+#define QUICKTHREADS_POP0 4
+#define QUICKTHREADS_POP1 5
+#define QUICKTHREADS_POP2 6
+#define QUICKTHREADS_PC 7
+/* The following are defined only for non-varargs. */
+#define QUICKTHREADS_POPE 8
+#define QUICKTHREADS_ARG0 9
+#define QUICKTHREADS_ARG1 10
+#define QUICKTHREADS_ARG2 11
+#define QUICKTHREADS_RPC 12
+
+
+/* Stack grows down. The top of the stack is the first thing to
+ pop off (preincrement, postdecrement). */
+#define QUICKTHREADS_GROW_DOWN
+
+extern void qt_error (void);
+
+/* For correct 16-byte stack alignment (auto-relocatable functions) */
+extern void qt_tramp (void);
+extern void qt_align (void);
+
+/* Push on the error return address and the alignment/trampoline functions. */
+#define QUICKTHREADS_ARGS_MD(sto) \
+ (QUICKTHREADS_SPUT (sto, QUICKTHREADS_POP0, qt_align), \
+ QUICKTHREADS_SPUT (sto, QUICKTHREADS_POP1, qt_align), \
+ QUICKTHREADS_SPUT (sto, QUICKTHREADS_POP2, qt_align), \
+ QUICKTHREADS_SPUT (sto, QUICKTHREADS_POPE, qt_tramp), \
+ QUICKTHREADS_SPUT (sto, QUICKTHREADS_RPC, qt_error))
+
+
+/* When varargs are pushed, allocate space for all the args. */
+#define QUICKTHREADS_VARGS_MD0(sto, nbytes) \
+ ((qt_t *)(((char *)(sto)) - QUICKTHREADS_STKROUNDUP(nbytes)))
+
+#define QUICKTHREADS_VARGS_MD1(sto) \
+ (QUICKTHREADS_SPUT (sto, QUICKTHREADS_PC, qt_vstart))
+
+#define QUICKTHREADS_VARGS_DEFAULT
+
+#endif /* QUICKTHREADS_386_H */
diff --git a/ext/systemc/src/sysc/qt/md/i386.s b/ext/systemc/src/sysc/qt/md/i386.s
new file mode 100644
index 000000000..b5806cd27
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/i386.s
@@ -0,0 +1,119 @@
+/* i386.s -- assembly support. */
+
+/*
+// QuickThreads -- Threads-building toolkit.
+// Copyright (c) 1993 by David Keppel
+//
+// Permission to use, copy, modify and distribute this software and
+// its documentation for any purpose and without fee is hereby
+// granted, provided that the above copyright notice and this notice
+// appear in all copies. This software is provided as a
+// proof-of-concept and for demonstration purposes; there is no
+// representation about the suitability of this software for any
+// purpose. */
+
+/* NOTE: double-labeled `_name' and `name' for System V compatability. */
+/* NOTE: Mixed C/C++-style comments used. Sorry! */
+
+/* Callee-save: %esi, %edi, %ebx, %ebp
+// Caller-save: %eax, %ecx
+// Can't tell: %edx (seems to work w/o saving it.)
+//
+// Assignment:
+//
+// See ``i386.h'' for the somewhat unconventional stack layout. */
+
+
+ .text
+ .align 2
+
+ .globl _qt_abort
+ .globl qt_abort
+ .globl _qt_block
+ .globl qt_block
+ .globl _qt_blocki
+ .globl qt_blocki
+ .globl _qt_align
+ .globl qt_align
+
+/* These all have the type signature
+//
+// void *blocking (helper, arg0, arg1, new)
+//
+// On procedure entry, the helper is at 4(sp), args at 8(sp) and
+// 12(sp) and the new thread's sp at 16(sp). It *appears* that the
+// calling convention for the 8X86 requires the caller to save all
+// floating-point registers, this makes our life easy. */
+
+/* Halt the currently-running thread. Save it's callee-save regs on
+// to the stack, 32 bytes. Switch to the new stack (next == 16+32(sp))
+// and call the user function (f == 4+32(sp) with arguments: old sp
+// arg1 (8+32(sp)) and arg2 (12+32(sp)). When the user function is
+// done, restore the new thread's state and return.
+//
+// `qt_abort' is (currently) an alias for `qt_block' because most of
+// the work is shared. We could save the insns up to `qt_common' by
+// replicating, but w/o replicating we need an inital subtract (to
+// offset the stack as if it had been a qt_block) and then a jump
+// to qt_common. For the cost of a jump, we might as well just do
+// all the work.
+//
+// The helper function (4(sp)) can return a void* that is returned
+// by the call to `qt_blockk{,i}'. Since we don't touch %eax in
+// between, we get that ``for free''. */
+
+_qt_abort:
+qt_abort:
+_qt_block:
+qt_block:
+_qt_blocki:
+qt_blocki:
+ pushl %ebp /* Save callee-save, sp-=4. */
+ pushl %esi /* Save callee-save, sp-=4. */
+ pushl %edi /* Save callee-save, sp-=4. */
+ pushl %ebx /* Save callee-save, sp-=4. */
+ movl %esp, %eax /* Remember old stack pointer. */
+
+qt_common:
+ movl 32(%esp), %esp /* Move to new thread. */
+ pushl 28(%eax) /* Push arg 2. */
+ pushl 24(%eax) /* Push arg 1. */
+ pushl %eax /* Push arg 0. */
+ movl 20(%eax), %ebx /* Get function to call. */
+ call *%ebx /* Call f. */
+ addl $12, %esp /* Pop args. */
+
+ popl %ebx /* Restore callee-save, sp+=4. */
+ popl %edi /* Restore callee-save, sp+=4. */
+ popl %esi /* Restore callee-save, sp+=4. */
+ popl %ebp /* Restore callee-save, sp+=4. */
+_qt_align:
+qt_align:
+ ret /* Resume the stopped function. */
+
+ .globl _qt_tramp
+ .globl qt_tramp
+_qt_tramp:
+qt_tramp:
+ movl 12(%esp), %eax /* Load 'qt_error' address */
+ sub $4, %esp /* Align stack pointer to 16-byte boundary */
+ jmp *%eax /* call 'qt_error' */
+ hlt /* 'qt_error' never returns */
+
+/* Start a varargs thread. */
+
+ .globl _qt_vstart
+ .globl qt_vstart
+_qt_vstart:
+qt_vstart:
+ pushl %edi /* Push `pt' arg to `startup'. */
+ call *%ebp /* Call `startup'. */
+ popl %eax /* Clean up the stack. */
+
+ call *%ebx /* Call the user's function. */
+
+ pushl %eax /* Push return from user's. */
+ pushl %edi /* Push `pt' arg to `cleanup'. */
+ call *%esi /* Call `cleanup'. */
+
+ hlt /* `cleanup' never returns. */
diff --git a/ext/systemc/src/sysc/qt/md/i386_b.s b/ext/systemc/src/sysc/qt/md/i386_b.s
new file mode 100644
index 000000000..32129a5d1
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/i386_b.s
@@ -0,0 +1,30 @@
+/*
+// QuickThreads -- Threads-building toolkit.
+// Copyright (c) 1993 by David Keppel
+//
+// Permission to use, copy, modify and distribute this software and
+// its documentation for any purpose and without fee is hereby
+// granted, provided that the above copyright notice and this notice
+// appear in all copies. This software is provided as a
+// proof-of-concept and for demonstration purposes; there is no
+// representation about the suitability of this software for any
+// purpose. */
+
+ .globl _b_call_reg
+ .globl b_call_reg
+ .globl _b_call_imm
+ .globl b_call_imm
+ .globl _b_add
+ .globl b_add
+ .globl _b_load
+ .globl b_load
+
+_b_call_reg:
+b_call_reg:
+_b_call_imm:
+b_call_imm:
+_b_add:
+b_add:
+_b_load:
+b_load:
+ hlt
diff --git a/ext/systemc/src/sysc/qt/md/iX86_64.h b/ext/systemc/src/sysc/qt/md/iX86_64.h
new file mode 100644
index 000000000..97bfe39b4
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/iX86_64.h
@@ -0,0 +1,140 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+#ifndef QUICKTHREADS_X86_64_H
+#define QUICKTHREADS_X86_64_H
+
+typedef unsigned long qt_word_t;
+
+/* Thread's initial stack layout on the iX86_64:
+
+ non-varargs:
+
+ +---
+ | arg[2] === `userf' on startup
+ | arg[1] === `pt' on startup
+ | arg[0] === `pu' on startup
+ +---
+ | ret pc === qt_error
+ +---
+ | ret pc === `only' on startup
+ +---
+ | %ebp
+ | %esi
+ | %edi
+ | %ebx <--- qt_t.sp
+ +---
+
+ When a non-varargs thread is started, it ``returns'' directly to
+ the client's `only' function.
+
+ varargs:
+
+ +---
+ | arg[n-1]
+ | ..
+ | arg[0]
+ +---
+ | ret pc === `qt_vstart'
+ +---
+ | %ebp === `startup'
+ | %esi === `cleanup'
+ | %edi === `pt'
+ | %ebx === `vuserf' <--- qt_t.sp
+ +---
+
+ When a varargs thread is started, it ``returns'' to the `qt_vstart'
+ startup code. The startup code calls the appropriate functions. */
+
+
+/* What to do to start a varargs thread running. */
+extern void qt_vstart (void);
+
+
+/* Hold four return pcs (qt_error, qt_start and twice qt_align)
+ plus ten args and two qt_word_t's for correct alignment. */
+#define QUICKTHREADS_STKBASE (16 * sizeof(long))
+
+/* Hold 4 saved regs plus one return pc (qt_vstart). */
+#define QUICKTHREADS_VSTKBASE (5 * sizeof(long))
+
+
+/* Stack must be 16-byte aligned at function call instr. (SSE data support) */
+#define QUICKTHREADS_STKALIGN (16)
+
+
+/* Where to place various arguments. */
+#define QUICKTHREADS_ONLY_INDEX (QUICKTHREADS_PC)
+#define QUICKTHREADS_USER_INDEX (QUICKTHREADS_ARG2)
+#define QUICKTHREADS_ARGT_INDEX (QUICKTHREADS_ARG1)
+#define QUICKTHREADS_ARGU_INDEX (QUICKTHREADS_ARG0)
+
+#define QUICKTHREADS_VSTARTUP_INDEX (QUICKTHREADS_EBP)
+#define QUICKTHREADS_VUSERF_INDEX (QUICKTHREADS_EBX)
+#define QUICKTHREADS_VCLEANUP_INDEX (QUICKTHREADS_ESI)
+#define QUICKTHREADS_VARGT_INDEX (QUICKTHREADS_EDI)
+
+
+/* Stack layout offsets relative to stack at initial stack setup. */
+
+/* Stack alignment 15 */
+#define QUICKTHREADS_RPC 14
+#define QUICKTHREADS_POP0 13
+#define QUICKTHREADS_PC 12
+#define QUICKTHREADS_POP1 11
+#define QUICKTHREADS_RBP 10
+/* Stack alignment 9 */
+#define QUICKTHREADS_R12 8
+#define QUICKTHREADS_R13 7
+#define QUICKTHREADS_R14 6
+#define QUICKTHREADS_R15 5
+#define QUICKTHREADS_RBX 4
+#define QUICKTHREADS_RCX 3
+#define QUICKTHREADS_RDX 2
+#define QUICKTHREADS_RDI 1
+#define QUICKTHREADS_RSI 0
+
+
+/* Arguments to save stack function. */
+
+#define QUICKTHREADS_ARG0 QUICKTHREADS_RDI
+#define QUICKTHREADS_ARG1 QUICKTHREADS_RSI
+#define QUICKTHREADS_ARG2 QUICKTHREADS_RDX
+
+
+/* Stack grows down. The top of the stack is the first thing to
+ pop off (preincrement, postdecrement). */
+#define QUICKTHREADS_GROW_DOWN
+
+extern void qt_error (void);
+extern void qt_align (void); /* For correct stack alignment */
+
+/* Push on the error return address, force Frame Pointer to 0 and
+ push stack alignment trampoline function. */
+#define QUICKTHREADS_ARGS_MD(sto) \
+ (QUICKTHREADS_SPUT (sto, QUICKTHREADS_RBP, 0), \
+ QUICKTHREADS_SPUT (sto, QUICKTHREADS_POP0, qt_align), \
+ QUICKTHREADS_SPUT (sto, QUICKTHREADS_POP1, qt_align), \
+ QUICKTHREADS_SPUT (sto, QUICKTHREADS_RPC, qt_error))
+
+
+/* When varargs are pushed, allocate space for all the args. */
+#define QUICKTHREADS_VARGS_MD0(sto, nbytes) \
+ ((qt_t *)(((char *)(sto)) - QUICKTHREADS_STKROUNDUP(nbytes)))
+
+#define QUICKTHREADS_VARGS_MD1(sto) \
+ (QUICKTHREADS_SPUT (sto, QUICKTHREADS_PC, qt_vstart))
+
+#define QUICKTHREADS_VARGS_DEFAULT
+
+#endif /* QUICKTHREADS_X86_64_H */
diff --git a/ext/systemc/src/sysc/qt/md/iX86_64.s b/ext/systemc/src/sysc/qt/md/iX86_64.s
new file mode 100644
index 000000000..a8bcfcd96
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/iX86_64.s
@@ -0,0 +1,74 @@
+/* iX386_64.s -- assembly support. */
+
+/*
+// QuickThreads -- Threads-building toolkit.
+// Copyright (c) 1993 by David Keppel
+//
+// Permission to use, copy, modify and distribute this software and
+// its documentation for any purpose and without fee is hereby
+// granted, provided that the above copyright notice and this notice
+// appear in all copies. This software is provided as a
+// proof-of-concept and for demonstration purposes; there is no
+// representation about the suitability of this software for any
+// purpose. */
+
+/* 64-bit Intel Architecture Support
+// written by Andy Goodrich, Forte Design Systms, Inc. */
+
+/* NOTE: double-labeled `_name' and `name' for System V compatability. */
+/* NOTE: Mixed C/C++-style comments used. Sorry! */
+
+ .text
+ .align 2
+
+ .globl _qt_abort
+ .globl qt_abort
+ .globl _qt_block
+ .globl qt_block
+ .globl _qt_blocki
+ .globl qt_blocki
+ .globl _qt_align
+ .globl qt_align
+
+_qt_abort:
+qt_abort:
+_qt_block:
+qt_block:
+_qt_blocki:
+qt_blocki:
+ /* 11 (return address.) */
+ pushq %rbp /* 10 (push stack frame top.) */
+ movq %rsp, %rbp /* set new stack frame top. */
+ /* save registers. */
+ subq $8, %rsp /* 9 (Stack alignment) */
+ pushq %r12 /* 8 ... */
+ pushq %r13 /* 7 ... */
+ pushq %r14 /* 6 ... */
+ pushq %r15 /* 5 ... */
+ pushq %rbx /* 4 ... */
+ pushq %rcx /* 3 ... (new stack address) */
+ pushq %rdx /* 2 ... (arg) */
+ pushq %rdi /* 1 ... (address of save function.) */
+ pushq %rsi /* 0 ... (cor) */
+
+ movq %rdi, %rax /* get address of save function. */
+ movq %rsp, %rdi /* set current stack as save argument. */
+ movq %rcx, %rsp /* swap stacks. */
+ movq %rcx, %rbp /* adjust stack frame pointer. */
+ addq $10*8, %rbp /* ... */
+ call *%rax /* call function to save stack pointer. */
+
+ /* restore registers. */
+ popq %rsi /* ... */
+ popq %rdi /* ... */
+ popq %rdx /* ... */
+ popq %rcx /* ... */
+ popq %rbx /* ... */
+ popq %r15 /* restore registers from new stack. */
+ popq %r14 /* ... */
+ popq %r13 /* ... */
+ popq %r12 /* ... */
+ leave /* unwind stack. */
+_qt_align:
+qt_align:
+ ret /* return. */
diff --git a/ext/systemc/src/sysc/qt/md/ksr1.Makefile b/ext/systemc/src/sysc/qt/md/ksr1.Makefile
new file mode 100644
index 000000000..aa195839a
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/ksr1.Makefile
@@ -0,0 +1,6 @@
+
+#
+# KSR1 configuration.
+#
+CC = cc -ansi
+
diff --git a/ext/systemc/src/sysc/qt/md/ksr1.h b/ext/systemc/src/sysc/qt/md/ksr1.h
new file mode 100644
index 000000000..b3877505d
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/ksr1.h
@@ -0,0 +1,164 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+#ifndef QUICKTHREADS_KSR1_H
+#define QUICKTHREADS_KSR1_H
+
+/*
+ Stack layout:
+
+ Registers are saved in strictly low to high order, FPU regs first
+ (only if qt_block is called), CEU regs second, IPU regs next, with no
+ padding between the groups.
+
+ Callee-save: f16..f63; c15..c30; i12..i30.
+ Args passed in i2..i5.
+
+ Note: c31 is a private data pointer. It is not changed on thread
+ swaps with the assumption that it represents per-processor rather
+ than per-thread state.
+
+ Note: i31 is an instruction count register that is updated by the
+ context switch routines. Like c31, it is not changed on context
+ switches.
+
+ This is what we want on startup:
+
+
+ +------ <-- BOS: Bottom of stack (grows down)
+ | 80 (128 - 48) bytes of padding to a 128-byte boundary
+ +---
+ | only
+ | userf
+ | t
+ | u
+ | qt_start$TXT
+ | (empty) <-- qt.sp
+ +------ <-- (BOS - 128)
+
+ This is why we want this on startup:
+
+ A thread begins running when the restore procedure switches thread stacks
+ and pops a return address off of the top of the new stack (see below
+ for the reason why we explicitly store qt_start$TXT). The
+ block procedure pushes two jump addresses on a thread's stack before
+ it switches stacks. The first is the return address for the block
+ procedure, and the second is a restore address. The return address
+ is used to jump back to the thread that has been switched to; the
+ restore address is a jump within the block code to restore the registers.
+ Normally, this is just a jump to the next address. However, on thread
+ startup, this is a jump to qt_start$TXT. (The block procedure stores
+ the restore address at an offset of 8 bytes from the top of the stack,
+ which is also the offset at which qt_start$TXT is stored on the stacks
+ of new threads. Hence, when the block procedure switches to a new
+ thread stack, it will initially jump to qt_start$TXT; thereafter,
+ it jumps to the restore code.)
+
+ qt_start$TXT, after it has read the initial data on the new thread's
+ stack and placed it in registers, pops the initial stack frame
+ and gives the thread the entire stack to use for execution.
+
+ The KSR runtime system has an unusual treatment of pointers to
+ functions. From C, taking the `name' of a function yields a
+ pointer to a _constant block_ and *not* the address of the
+ function. The zero'th entry in the constant block is a pointer to
+ the function.
+
+ We have to be careful: the restore procedure expects a return
+ address on the top of the stack (pointed to by qt.sp). This is not
+ a problem when restoring a thread that has run before, since the
+ block routine would have stored the return address on top of the
+ stack. However, when ``faking up'' a thread start (bootstrapping a
+ thread stack frame), the top of the stack needs to contain a
+ pointer to the code that will start the thread running.
+
+ The pointer to the startup code is *not* `qt_start'. It is the
+ word *pointed to* by `qt_start'. Thus, we dereference `qt_start',
+ see QUICKTHREADS_ARGS_MD below.
+
+ On varargs startup (still unimplemented):
+
+ | padding to 128 byte boundary
+ | varargs <-- padded to a 128-byte-boundary
+ +---
+ | caller's frame, 16 bytes
+ | 80 bytes of padding (frame padded to a 128-byte boundary)
+ +---
+ | cleanup
+ | vuserf
+ | startup
+ | t
+ +---
+ | qt_start <-- qt.sp
+ +---
+
+ Of a suspended thread:
+
+ +---
+ | caller's frame, 16 bytes
+ | fpu registers 47 regs * 8 bytes/reg 376 bytes
+ | ceu registers 16 regs * 8 bytes/reg 128 bytes
+ | ipu registers 19 regs * 8 bytes/reg 152 bytes
+ | :
+ | 80 bytes of padding
+ | :
+ | qt_restore <-- qt.sp
+ +---
+
+ */
+
+
+#define QUICKTHREADS_STKALIGN 128
+#define QUICKTHREADS_GROW_DOWN
+typedef unsigned long qt_word_t;
+
+#define QUICKTHREADS_STKBASE QUICKTHREADS_STKALIGN
+#define QUICKTHREADS_VSTKBASE QUICKTHREADS_STKBASE
+
+extern void qt_start(void);
+/*
+ * See the discussion above for what indexing into a procedure ptr
+ * does for us (it's lovely, though, isn't it?).
+ *
+ * This assumes that the address of a procedure's code is the
+ * first word in a procedure's constant block. That's how the manual
+ * says it will be arranged.
+ */
+#define QUICKTHREADS_ARGS_MD(sp) (QUICKTHREADS_SPUT (sp, 1, ((qt_word_t *)qt_start)[0]))
+
+/*
+ * The *index* (positive offset) of where to put each value.
+ * See the picture of the stack above that explains the offsets.
+ */
+#define QUICKTHREADS_ONLY_INDEX (5)
+#define QUICKTHREADS_USER_INDEX (4)
+#define QUICKTHREADS_ARGT_INDEX (3)
+#define QUICKTHREADS_ARGU_INDEX (2)
+
+#define QUICKTHREADS_VARGS_DEFAULT
+#define QUICKTHREADS_VARGS(sp, nb, vargs, pt, startup, vuserf, cleanup) \
+ (qt_vargs (sp, nbytes, &vargs, pt, startup, vuserf, cleanup))
+
+
+#define QUICKTHREADS_VARGS_MD0(sp, vabytes) \
+ ((qt_t *)(((char *)(sp)) - 4*8 - QUICKTHREADS_STKROUNDUP(vabytes)))
+
+extern void qt_vstart(void);
+#define QUICKTHREADS_VARGS_MD1(sp) (QUICKTHREADS_SPUT (sp, 0, ((qt_word_t *)qt_vstart)[0]))
+
+#define QUICKTHREADS_VCLEANUP_INDEX (4)
+#define QUICKTHREADS_VUSERF_INDEX (3)
+#define QUICKTHREADS_VSTARTUP_INDEX (2)
+#define QUICKTHREADS_VARGT_INDEX (1)
+
+#endif /* def QUICKTHREADS_KSR1_H */
diff --git a/ext/systemc/src/sysc/qt/md/ksr1.s b/ext/systemc/src/sysc/qt/md/ksr1.s
new file mode 100644
index 000000000..d4d51a0a6
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/ksr1.s
@@ -0,0 +1,424 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+ .file "ksr1.s"
+ .def .debug; .endef
+
+ .align 128
+ .globl qt_blocki
+ .globl qt_blocki$TXT
+ .globl qt_block
+ .globl qt_block$TXT
+ .globl qt_start$TXT
+ .globl qt_start
+ .globl qt_abort$TXT
+ .globl qt_abort
+ .globl qt_vstart
+ .globl qt_vstart$TXT
+
+#
+# KSR convention: on procedure calls, load both the procedure address
+# and a pointer to a constant block. The address of function `f' is
+# `f$TXT', and the constant block address is `f'. The constant block
+# has several reserved values:
+#
+# 8 bytes fpu register save mask
+# 4 bytes ipu register save mask
+# 4 bytes ceu register save mask
+# f: f$TXT
+# ... whatever you want ... (not quite...read on)
+#
+# Note, by the way, that a pointer to a function is passed as a
+# pointer to the constant area, and the constant area has the text
+# address.
+#
+
+#
+# Procedures that do not return structures prefix their code with
+#
+# proc$TXT:
+# finop; cxnop
+# finop; cxnop
+# <proc code>
+#
+# Calls to those procedures branch to a 16 byte offset (4 instrs) in
+# to the procedure to skip those instructions.
+#
+# Procedures that return structures use a different code prefix:
+#
+# proc$TXT:
+# finop; beq.qt %rc, %rc, 24 # return value entry
+# finop; cxnop
+# finop; movi8 0, %rc # no return value entry
+# <proc code>
+#
+# Calls that want the returned structure branch directly to the
+# procedure address. Callers that don't want (or aren't expecting) a
+# return value branche 16 bytes in to the procedure, which will zero
+# %rc, telling the called procedure not to return a structure.
+#
+
+#
+# On entry:
+# %i2 -- control block of helper function to run
+# (dereference to get helper)
+# %i3 -- a1
+# %i4 -- a2
+# %i5 -- sp of new to run
+#
+
+ .data
+ .half 0x0, 0x0, 0x7ffff000, 0x7fff8000
+qt_blocki:
+qt_abort:
+ .word qt_blocki$TXT
+ .word qt_restore$TXT
+
+ .text
+qt_abort$TXT:
+qt_blocki$TXT:
+ finop ; cxnop # entry prefix
+ finop ; cxnop # entry prefix
+ add8.ntr 75,%i31,%i31 ; movi8 512,%c5 # ICR; stk adjust
+ finop ; ssub8.ntr 0,%sp,%c5,%sp
+ finop ; st8 %fp,504(%sp) # Save caller's fp
+ finop ; st8 %cp,496(%sp) # Save caller's cp
+ finop ; ld8 8(%c10),%c5 # ld qt_restore$TXT
+ finop ; st8 %c14,0(%sp) # Save special ret addr
+ finop ; mov8_8 %c10, %cp # Our cp
+ finop ; sadd8.ntr 0,%sp,%c5,%fp # Our frame ptr
+ finop ; st8 %c5,8(%sp) # st qt_restore$TXT
+#
+# CEU registers %c15-%c24, %c26-%c30 (%c14 we restore later)
+#
+ finop ; st8 %c15,456(%sp)
+ finop ; st8 %c16,448(%sp)
+ finop ; st8 %c17,440(%sp)
+ finop ; st8 %c18,432(%sp)
+ finop ; st8 %c19,424(%sp)
+ finop ; st8 %c20,416(%sp)
+ finop ; st8 %c21,408(%sp)
+ finop ; st8 %c22,400(%sp)
+ finop ; st8 %c23,392(%sp)
+ finop ; st8 %c24,384(%sp)
+#
+# %c25 is the Enclosing Frame Pointer (EFP) -- since C doesn't
+# use nested procedures, we ignore it (leaving a gap, though)
+#
+ finop ; st8 %c26,368(%sp)
+ finop ; st8 %c27,360(%sp)
+ finop ; st8 %c28,352(%sp)
+ finop ; st8 %c29,344(%sp)
+ finop ; st8 %c30,336(%sp)
+#
+# IPU registers %i12-%i30
+#
+ finop ; st8 %i12,328(%sp)
+ finop ; st8 %i13,320(%sp)
+ finop ; st8 %i14,312(%sp)
+ finop ; st8 %i15,304(%sp)
+# (gap to get alignment for st64)
+# -- Doesn't work on version 1.1.3 of the OS
+# finop ; st64 %i16,256(%sp)
+
+ finop ; st8 %i16,256(%sp)
+ finop ; st8 %i17,248(%sp)
+ finop ; st8 %i18,240(%sp)
+ finop ; st8 %i19,232(%sp)
+ finop ; st8 %i20,224(%sp)
+ finop ; st8 %i21,216(%sp)
+ finop ; st8 %i22,208(%sp)
+ finop ; st8 %i23,200(%sp)
+ finop ; st8 %i24,192(%sp)
+ finop ; st8 %i25,184(%sp)
+ finop ; st8 %i26,176(%sp)
+ finop ; st8 %i27,168(%sp)
+ finop ; st8 %i28,160(%sp)
+ finop ; st8 %i29,152(%sp)
+ finop ; st8 %i30,144(%sp)
+#
+# FPU already saved, or saving not necessary
+#
+
+#
+# Switch to the stack passed in as fourth argument to the block
+# routine (%i5) and call the helper routine passed in as the first
+# argument (%i2). Note that the address of the helper's constant
+# block is passed in, so we must derefence it to get the helper's text
+# address.
+#
+ finop ; movb8_8 %i2,%c10 # helper's ConstBlock
+ finop ; cxnop # Delay slot, fill w/
+ finop ; cxnop # .. 2 st8 from above
+ finop ; ld8 0(%c10),%c4 # load addr of helper
+ finop ; movb8_8 %sp, %i2 # 1st arg to helper
+ # is this stack; other
+ # args remain in regs
+ finop ; movb8_8 %i5,%sp # switch stacks
+ finop ; jsr %c14,16(%c4) # call helper
+ movi8 3, %i0 ; movi8 0,%c8 # nargs brain dmg
+ finop ; cxnop
+ finop ; cxnop
+#
+# Here is where behavior differs for threads being restored and threads
+# being started. Blocked threads have a pointer to qt_restore$TXT on
+# the top of their stacks; manufactured stacks have a pointer to qt_start$TXT
+# on the top of their stacks. With this setup, starting threads
+# skip the (unecessary) restore operations.
+#
+# We jump to an offset of 16 to either (1) skip past the two noop pairs
+# at the start of qt_start$TXT, or (2) skip past the two noop pairs
+# after qt_restore$TXT.
+#
+ finop ; ld8 8(%sp),%c4
+ finop ; cxnop
+ finop ; cxnop
+ finop ; jmp 16(%c4)
+qt_restore$TXT:
+ finop ; cxnop
+ finop ; cxnop
+#
+# Point of Restore:
+#
+# The helper funtion will return here. Any result it has placed in
+# a return register (most likely %i0) will not get overwritten below
+# and will consequently be the return value of the blocking routine.
+#
+
+#
+# CEU registers %c15-%c24, %c26-%c30 (%c14 we restore later)
+#
+ finop ; ld8 456(%sp),%c15
+ finop ; ld8 448(%sp),%c16
+ finop ; ld8 440(%sp),%c17
+ finop ; ld8 432(%sp),%c18
+ finop ; ld8 424(%sp),%c19
+ finop ; ld8 416(%sp),%c20
+ finop ; ld8 408(%sp),%c21
+ finop ; ld8 400(%sp),%c22
+ finop ; ld8 392(%sp),%c23
+ finop ; ld8 384(%sp),%c24
+#
+# %c25 is the Enclosing Frame Pointer (EFP) -- since C doesn't
+# use nested procedures, we ignore it (leaving a gap, though)
+#
+ finop ; ld8 368(%sp),%c26
+ finop ; ld8 360(%sp),%c27
+ finop ; ld8 352(%sp),%c28
+ finop ; ld8 344(%sp),%c29
+ finop ; ld8 336(%sp),%c30
+#
+# IPU registers %i12-%i30
+#
+ finop ; ld8 328(%sp),%i12
+ finop ; ld8 320(%sp),%i13
+ finop ; ld8 312(%sp),%i14
+ finop ; ld8 304(%sp),%i15
+# (gap to get alignment for ld64)
+# -- Doesn't work on version 1.1.3 of the OS
+# finop ; ld64 256(%sp),%i16
+
+ finop ; ld8 256(%sp),%i16
+ finop ; ld8 248(%sp),%i17
+ finop ; ld8 240(%sp),%i18
+ finop ; ld8 232(%sp),%i19
+ finop ; ld8 224(%sp),%i20
+ finop ; ld8 216(%sp),%i21
+ finop ; ld8 208(%sp),%i22
+ finop ; ld8 200(%sp),%i23
+ finop ; ld8 192(%sp),%i24
+ finop ; ld8 184(%sp),%i25
+ finop ; ld8 176(%sp),%i26
+ finop ; ld8 168(%sp),%i27
+ finop ; ld8 160(%sp),%i28
+ finop ; ld8 152(%sp),%i29
+ finop ; ld8 144(%sp),%i30
+
+#
+# FPU registers don't need to be loaded, or will be loaded by an
+# enclosing scope (e.g., if this is called by qt_block).
+#
+
+#
+# Load the special registers. We don't load the stack ptr because
+# the new stack is passed in as an argument, we don't load the EFP
+# because we don't use it, and we load the return address specially
+# off the top of the stack.
+#
+ finop ; ld8 0(%sp),%c14 # return addr
+ finop ; ld8 496(%sp),%cp
+ finop ; ld8 504(%sp),%fp
+
+ finop ; jmp 32(%c14) # jump back to thread
+ finop ; movi8 512,%c5 # stack adjust
+ finop ; sadd8.ntr 0,%sp,%c5,%sp
+
+ .data
+ .half 0x0, 0x0, 0x7ffff000, 0x7fff8000
+qt_block:
+ .word qt_block$TXT
+ .word qt_error
+ .word qt_error$TXT
+ .word qt_blocki
+#
+# Handle saving and restoring the FPU regs, relying on qt_blocki
+# to save and restore the remaining registers.
+#
+ .text
+qt_block$TXT:
+ finop ; cxnop # entry prefix
+ finop ; cxnop # entry prefix
+
+ add8.ntr 29,%i31,%i31 ; movi8 512,%c5 # ICR; stk adjust
+ finop ; ssub8.ntr 0,%sp,%c5,%sp
+ finop ; st8 %fp,504(%sp) # Save caller's fp
+ finop ; st8 %cp,496(%sp) # Save caller's cp
+ finop ; st8 %c14,488(%sp) # store ret addr
+ finop ; sadd8.ntr 0,%sp,%c5,%fp # Our frame ptr
+ finop ; mov8_8 %c10, %cp # Our cp
+
+#
+# Store 8 registers at once...destination must be a multiple of 64
+#
+ finop ; st64 %f16,384(%sp)
+ finop ; st64 %f24,320(%sp)
+ finop ; st64 %f32,256(%sp)
+ finop ; st64 %f40,192(%sp)
+ finop ; st64 %f48,128(%sp)
+ finop ; st64 %f56,64(%sp)
+
+#
+# Call the integer blocking routine, passing the arguments passed to us
+#
+ finop ; ld8 24(%cp), %c10
+ finop ; cxnop
+ finop ; jsr %c14, qt_blocki$TXT
+ finop ; cxnop
+ finop ; cxnop
+ movi8 4,%i0 ; movi8 0,%c8 # nargs brain dmg
+
+#
+# Load 8 registers at once...source must be a multiple of 64
+#
+ finop ; ld64 64(%sp),%f56
+ finop ; ld64 128(%sp),%f48
+ finop ; ld64 192(%sp),%f40
+ finop ; ld64 256(%sp),%f32
+ finop ; ld64 320(%sp),%f24
+ finop ; ld64 384(%sp),%f16
+
+ finop ; ld8 488(%sp),%c14
+ finop ; ld8 496(%sp),%cp
+ finop ; ld8 504(%sp),%fp
+ finop ; jmp 32(%c14) # jump back to thread
+ finop ; movi8 512,%c5 # stack adjust
+ finop ; sadd8.ntr 0,%sp,%c5,%sp
+
+
+ .data
+ .half 0x0, 0x0, 0x7ffff000, 0x7fff8000
+qt_start:
+ .word qt_start$TXT
+#
+# A new thread is set up to "appear" as if it were executing code at
+# the beginning of qt_start and then it called a blocking routine
+# (qt_blocki). So when a new thread starts to run, it gets unblocked
+# by the code above and "returns" to `qt_start$TXT' in the
+# restore step of the switch. Blocked threads jump to 16(qt_restore$TXT),
+# and starting threads jump to 16(qt_start$TXT).
+#
+ .text
+qt_start$TXT:
+ finop ; cxnop #
+ finop ; cxnop #
+ finop ; ld8 40(%sp),%c10 # `only' constant block
+ finop ; ld8 32(%sp),%i4 # `userf' arg.
+ finop ; ld8 24(%sp),%i3 # `t' arg.
+ finop ; ld8 0(%c10),%c4 # `only' text location
+ finop ; ld8 16(%sp),%i2 # `u' arg.
+ finop ; cxnop
+ finop ; jsr %c14,16(%c4) # call `only'
+#
+# Pop the frame used to store the thread's initial data
+#
+ finop ; sadd8.ntr 0,%sp,128,%sp
+ finop ; cxnop
+ movi8 2,%i0 ; movi8 0,%c8 # nargs brain dmg
+#
+# If we ever return, it's an error.
+#
+ finop ; jmp qt_error$TXT
+ finop ; cxnop
+ finop ; cxnop
+ movi8 0,%i0 ; movi8 0,%c8 # nargs brain dmg
+
+
+#
+# This stuff is broken
+#
+ .data
+ .half 0x0, 0x0, 0x7ffff000, 0x7fff8000
+qt_vstart:
+ .word qt_vstart$TXT
+
+ .text
+qt_vstart$TXT:
+ finop ; cxnop # entry prefix
+ finop ; cxnop # entry prefix
+ finop ; cxnop
+ finop ; cxnop
+ add8.ntr 11,%i31,%i31 ; movi8 512,%c5
+ finop ; ssub8.ntr 0,%sp,%c5,%sp # fix stack
+ finop ; ld8 8(%sp),%i2 # load `t' as arg to
+ finop ; cxnop # `startup'
+ finop ; cxnop
+ finop ; ld8 16(%sp),%c10 # `startup' const block
+ finop ; cxnop
+ finop ; cxnop
+ finop ; ld8 0(%c10),%c4 # `startup' text loc.
+ finop ; cxnop
+ finop ; cxnop
+ finop ; jsr %c14,16(%c4) # call `startup'
+ finop ; cxnop
+ finop ; cxnop
+ movi8 1, %i0 ; movi8 0,%c8 # nargs brain dmg
+#
+# finop ; sadd 0,%sp,128,%sp # alter stack
+#
+ finop ; ld8 8(%sp),%i2 # load `t' as arg to
+ finop ; ld8 8(%sp),%i2 # load `t' as arg to
+ finop ; ld8 8(%sp),%i2 # load `t' as arg to
+ finop ; ld8 8(%sp),%i2 # load `t' as arg to
+
+ finop ; ld8 32(%sp),%c10 # `only' constant block
+ finop ; ld8 8(%sp),%i2 # `u' arg.
+ finop ; ld8 16(%sp),%i3 # `t' arg.
+ finop ; ld8 0(%c10),%c4 # `only' text location
+ finop ; ld8 24(%sp),%i4 # `userf' arg.
+ finop ; cxnop
+ finop ; jsr %c4,16(%c4) # call `only'
+ finop ; cxnop
+ finop ; cxnop
+#
+# If the callee ever calls `nargs', the following instruction (pair)
+# will be executed. However, we don't know when we compile this code
+# how many args are being passed. So we give our best guess: 0.
+#
+ movi8 0,%i0 ; movi8 0,%c8 # nargs brain dmg
+#
+# If we ever return, it's an error.
+#
+ finop ; jmp qt_error$TXT
+ finop ; cxnop
+ finop ; cxnop
+ movi8 0,%i0 ; movi8 0,%c8 # nargs brain dmg
diff --git a/ext/systemc/src/sysc/qt/md/ksr1_b.s b/ext/systemc/src/sysc/qt/md/ksr1_b.s
new file mode 100644
index 000000000..80b0c59eb
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/ksr1_b.s
@@ -0,0 +1,49 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+ .file "ksr1_b.s"
+ .def .debug; .endef
+
+ .globl b_call_reg$TXT
+ .globl b_call_reg
+ .globl b_call_imm$TXT
+ .globl b_call_imm
+ .globl b_add$TXT
+ .globl b_add
+ .globl b_load$TXT
+ .globl b_load
+
+
+b_call_reg:
+b_call_imm:
+b_add:
+b_load:
+ .word b_call_reg$TXT
+ .word qt_error
+ .word qt_error$TXT
+
+
+b_call_reg$TXT:
+b_call_imm$TXT:
+b_add$TXT:
+b_load$TXT:
+ finop ; cxnop
+ finop ; cxnop
+ finop ; ld8 16(%cp),%c4
+ finop ; ld8 8(%cp),%cp
+ finop ; cxnop
+ finop ; cxnop
+ finop ; jsr %c4,0(%c4)
+ finop ; cxnop
+ finop ; cxnop
+
diff --git a/ext/systemc/src/sysc/qt/md/m88k.Makefile b/ext/systemc/src/sysc/qt/md/m88k.Makefile
new file mode 100644
index 000000000..608c70690
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/m88k.Makefile
@@ -0,0 +1,6 @@
+
+#
+# Hosted compilers for 88k for Meerkat.
+#
+CC = gcc88 -Dm88k -ansi -pedantic -Wall -fno-builtin
+AS = as88
diff --git a/ext/systemc/src/sysc/qt/md/m88k.c b/ext/systemc/src/sysc/qt/md/m88k.c
new file mode 100644
index 000000000..f2cef00a0
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/m88k.c
@@ -0,0 +1,111 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+#include <stdarg.h>
+#include "qt.h"
+
+/* Varargs is harder on the m88k. Parameters are saved on the stack as
+ something like (stack grows down to low memory; low at bottom of
+ picture):
+
+ | :
+ | arg8 <-- va_list.__va_stk
+ +---
+ | :
+ +---
+ | arg7
+ | :
+ | iarg0 <-- va_list.__va_reg
+ +---
+ | :
+ | va_list { __va_arg, __va_stk, __va_reg }
+ | :
+ +---
+
+ Here, `va_list.__va_arg' is the number of word-size arguments
+ that have already been skipped. Doubles must be double-arligned.
+
+ What this means for us is that the user's routine needs to be
+ called with an arg list where some of the words in the `__va_stk'
+ part of the parameter list have to be promoted to registers.
+
+ BUG: doubleword register arguments must be double-aligned. If
+ something is passed as an even # arg and used as an odd # arg or
+ vice-versa, the code in the called routine (in the new thread) that
+ decides how to adjust the index will get it wrong, because it will
+ be expect it to be, say, doubleword aligned and it will really be
+ singleword aligned.
+
+ I'm not sure you can solve this without knowing the types of all
+ the arguments. All in all, we never promised varargs would work
+ reliably. */
+
+
+
+#define QUICKTHREADS_VADJ(sp) (((char *)sp) - QUICKTHREADS_VSTKBASE)
+
+/* Always allocate at least enough space for 8 args; waste some space
+ at the base of the stack to ensure the startup routine doesn't read
+ off the end of the stack. */
+
+#define QUICKTHREADS_VARGS_MD0(sp, vabytes) \
+ ((qt_t *)(((char *)(sp)) - 8*4 - QUICKTHREADS_STKROUNDUP(vabytes)))
+
+extern void qt_vstart(void);
+#define QUICKTHREADS_VARGS_MD1(sp) (QUICKTHREADS_SPUT (sp, QUICKTHREADS_1, qt_vstart))
+
+
+ struct qt_t *
+qt_vargs (struct qt_t *qsp, int nbytes, void *vargs,
+ void *pt, qt_function_t *startup,
+ qt_function_t *vuserf, qt_function_t *cleanup)
+{
+ va_list ap;
+ int i;
+ int n; /* Number of words into original arg list. */
+ qt_word_t *sp;
+ int *reg; /* Where to read passed-in-reg args. */
+ int *stk; /* Where to read passed-on-stk args. */
+
+ ap = *(va_list *)vargs;
+ qsp = QUICKTHREADS_VARGS_MD0 (qsp, nbytes);
+ sp = (qt_word_t *)qsp;
+
+ reg = (ap.__va_arg < 8)
+ ? &ap.__va_reg[ap.__va_arg]
+ : 0;
+ stk = &ap.__va_stk[8];
+ n = ap.__va_arg;
+ for (i=0; i<nbytes/sizeof(qt_word_t) && n<8; ++i,++n) {
+ sp[i] = *reg++;
+ }
+ for (; i<nbytes/sizeof(qt_word_t); ++i) {
+ sp[i] = *stk++;
+ }
+
+#ifdef QUICKTHREADS_NDEF
+ for (i=0; i<nbytes/sizeof(qt_word_t); ++i) {
+ sp[i] = (n < 8)
+ ? *reg++
+ : *stk++;
+ ++n;
+ }
+#endif
+
+ QUICKTHREADS_VARGS_MD1 (QUICKTHREADS_VADJ(sp));
+ QUICKTHREADS_SPUT (QUICKTHREADS_VADJ(sp), QUICKTHREADS_VARGT_INDEX, pt);
+ QUICKTHREADS_SPUT (QUICKTHREADS_VADJ(sp), QUICKTHREADS_VSTARTUP_INDEX, startup);
+ QUICKTHREADS_SPUT (QUICKTHREADS_VADJ(sp), QUICKTHREADS_VUSERF_INDEX, vuserf);
+ QUICKTHREADS_SPUT (QUICKTHREADS_VADJ(sp), QUICKTHREADS_VCLEANUP_INDEX, cleanup);
+ return ((qt_t *)QUICKTHREADS_VADJ(sp));
+}
diff --git a/ext/systemc/src/sysc/qt/md/m88k.h b/ext/systemc/src/sysc/qt/md/m88k.h
new file mode 100644
index 000000000..f9cab5327
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/m88k.h
@@ -0,0 +1,159 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+#ifndef QUICKTHREADS_M88K_H
+#define QUICKTHREADS_M88K_H
+
+typedef unsigned long qt_word_t;
+
+#define QUICKTHREADS_GROW_DOWN
+
+/* Stack layout on the mips:
+
+ Callee-save registers are: $16-$23, $30; $f20-$f30.
+ Also save $31, return pc.
+
+ Non-varargs:
+
+ +---
+ | r30 (fp) on startup === 0
+ | r25
+ | r24
+ | r23
+ | r22
+ | r21
+ | r20
+ | r19
+ | r18
+ | r17 on startup === `only'
+ | r16 on startup === `userf'
+ | r15 on startup === `pt'
+ | r14 on startup === `pu'
+ | r1 on startup === `qt_start'
+ | 0
+ | 0
+ +---
+ | 0
+ | ... (8 regs worth === 32 bytes of homing area)
+ | 0 <--- sp
+ +---
+
+ Conventions for varargs:
+
+ | :
+ | arg8
+ +---
+ | r30 (fp) arg7
+ | r25 arg6
+ | r24 arg5
+ | r23 arg4
+ | r22 arg3
+ | r21 arg2
+ | r20 arg1
+ | r19 arg0
+ | r18
+ | r17 on startup === `startup'
+ | r16 on startup === `vuserf'
+ | r15 on startup === `pt'
+ | r14 on startup === `cleanup'
+ | r1 on startup === `qt_vstart'
+ | 0
+ | 0
+ +---
+ | 0
+ | ... (8 regs worth === 32 bytes of homing area)
+ | 0 <--- sp
+ +---
+
+ */
+
+
+/* Stack must be doubleword aligned. */
+#define QUICKTHREADS_STKALIGN (16) /* Doubleword aligned. */
+
+/* How much space is allocated to hold all the crud for
+ initialization: saved registers plus padding to keep the stack
+ aligned plus 8 words of padding to use as a `homing area' (for
+ r2-r9) when calling helper functions on the stack of the (not yet
+ started) thread. The varargs save area is small because it gets
+ overlapped with the top of the parameter list. In case the
+ parameter list is less than 8 args, QUICKTHREADS_ARGS_MD0 adds some dead
+ space at the top of the stack. */
+
+#define QUICKTHREADS_STKBASE (16*4 + 8*4)
+#define QUICKTHREADS_VSTKBASE (8*4 + 8*4)
+
+
+/* Index of various registers. */
+#define QUICKTHREADS_1 (8+2)
+#define QUICKTHREADS_14 (8+3)
+#define QUICKTHREADS_15 (8+4)
+#define QUICKTHREADS_16 (8+5)
+#define QUICKTHREADS_17 (8+6)
+#define QUICKTHREADS_30 (8+15)
+
+
+/* When a never-before-run thread is restored, the return pc points
+ to a fragment of code that starts the thread running. For
+ non-vargs functions, it sets up arguments and calls the client's
+ `only' function. For varargs functions, the startup code calls the
+ startup, user, and cleanup functions.
+
+ For non-varargs functions, we set the frame pointer to 0 to
+ null-terminate the call chain.
+
+ For varargs functions, the frame pointer register is used to hold
+ one of the arguments, so that all arguments can be laid out in
+ memory by the conventional `qt_vargs' varargs initialization
+ routine.
+
+ The varargs startup routine always reads 8 words of arguments from
+ the stack. If there are less than 8 words of arguments, then the
+ arg list could call off the top of the stack. To prevent fall-off,
+ always allocate 8 words. */
+
+extern void qt_start(void);
+#define QUICKTHREADS_ARGS_MD(sp) \
+ (QUICKTHREADS_SPUT (sp, QUICKTHREADS_1, qt_start), \
+ QUICKTHREADS_SPUT (sp, QUICKTHREADS_30, 0))
+
+
+/* The m88k uses a struct for `va_list', so pass a pointer to the
+ struct. */
+
+typedef void (qt_function_t)(void);
+
+struct qt_t;
+extern struct qt_t *qt_vargs (struct qt_t *sp, int nbytes,
+ void *vargs, void *pt,
+ qt_function_t *startup,
+ qt_function_t *vuserf,
+ qt_function_t *cleanup);
+
+#define QUICKTHREADS_VARGS(sp, nbytes, vargs, pt, startup, vuserf, cleanup) \
+ (qt_vargs (sp, nbytes, &(vargs), pt, (qt_function_t *)startup, \
+ (qt_function_t *)vuserf, (qt_function_t *)cleanup))
+
+
+/* The *index* (positive offset) of where to put each value. */
+#define QUICKTHREADS_ONLY_INDEX (QUICKTHREADS_17)
+#define QUICKTHREADS_USER_INDEX (QUICKTHREADS_16)
+#define QUICKTHREADS_ARGT_INDEX (QUICKTHREADS_15)
+#define QUICKTHREADS_ARGU_INDEX (QUICKTHREADS_14)
+
+#define QUICKTHREADS_VCLEANUP_INDEX (QUICKTHREADS_14)
+#define QUICKTHREADS_VUSERF_INDEX (QUICKTHREADS_16)
+#define QUICKTHREADS_VSTARTUP_INDEX (QUICKTHREADS_17)
+#define QUICKTHREADS_VARGT_INDEX (QUICKTHREADS_15)
+
+#endif /* ndef QUICKTHREADS_M88K_H */
diff --git a/ext/systemc/src/sysc/qt/md/m88k.s b/ext/systemc/src/sysc/qt/md/m88k.s
new file mode 100644
index 000000000..42467e8d5
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/m88k.s
@@ -0,0 +1,132 @@
+/* m88k.s -- assembly support. */
+
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+/* Callee-save r14..r25, r31(sp), r30(fp). r1 === return pc.
+ * Argument registers r2..r9, return value r2..r3.
+ *
+ * On startup, restore regs so retpc === call to a function to start.
+ *
+ * We're going to call a function (r2) from within the context switch
+ * routine. Call it on the new thread's stack on behalf of the old
+ * thread.
+ */
+
+ .globl _qt_block
+ .globl _qt_blocki
+ .globl _qt_abort
+ .globl _qt_start
+ .globl _qt_vstart
+
+ /*
+ ** r2: ptr to function to call once curr is suspended
+ ** and control is on r5's stack.
+ ** r3: 1'th arg to *r2.
+ ** r4: 2'th arg to *r2.
+ ** r5: sp of thread to suspend.
+ **
+ ** The helper routine returns a value that is passed on as the
+ ** return value from the blocking routine. Since we don't
+ ** touch r2 between the helper's return and the end of
+ ** function, we get this behavior for free.
+ **
+ ** Same entry for integer-only and floating-point, since there
+ ** are no separate integer and floating-point registers.
+ **
+ ** Each procedure call sets aside a ``home region'' of 8 regs
+ ** for r2-r9 for varargs. For context switches we don't use
+ ** the ``home region'' for varargs so use it to save regs.
+ ** Allocate 64 bytes of save space -- use 32 bytes of register
+ ** save area passed in to us plus 32 bytes we allcated, use
+ ** the other 32 bytes for save area for a save area to call
+ ** the helper function.
+ */
+_qt_block:
+_qt_blocki:
+ sub r31, r31,64 /* Allocate reg save space. */
+ st r1, r31,8+32 /* Save callee-save registers. */
+ st r14, r31,12+32
+ st.d r15, r31,16+32
+ st.d r17, r31,24+32
+ st.d r19, r31,32+32
+ st.d r21, r31,40+32
+ st.d r23, r31,48+32
+ st r25, r31,56+32
+ st r30, r31,60+32
+
+_qt_abort:
+ addu r14, r31,0 /* Remember old sp. */
+ addu r31, r5,0 /* Set new sp. */
+ jsr.n r2 /* Call helper. */
+ addu r2, r14,0 /* Pass old sp as an arg0 to helper. */
+
+ ld r1, r31,8+32 /* Restore callee-save registers. */
+ ld r14, r31,12+32
+ ld.d r15, r31,16+32
+ ld.d r17, r31,24+32
+ ld.d r19, r31,32+32
+ ld.d r21, r31,40+32
+ ld.d r23, r31,48+32
+ ld r25, r31,56+32
+ ld r30, r31,60+32
+
+ jmp.n r1 /* Return to new thread's caller. */
+ addu r31, r31,64 /* Free register save space. */
+
+
+ /*
+ ** Non-varargs thread startup.
+ ** See `m88k.h' for register use conventions.
+ */
+_qt_start:
+ addu r2, r14,0 /* Set user arg `pu'. */
+ addu r3, r15,0 /* ... user function pt. */
+ jsr.n r17 /* Call `only'. */
+ addu r4, r16,0 /* ... user function userf. */
+
+ bsr _qt_error /* `only' erroniously returned. */
+
+
+ /*
+ ** Varargs thread startup.
+ ** See `m88k.h' for register use conventions.
+ **
+ ** Call the `startup' function with just argument `pt'.
+ ** Then call `vuserf' with 8 register args plus any
+ ** stack args.
+ ** Then call `cleanup' with `pt' and the return value
+ ** from `vuserf'.
+ */
+_qt_vstart:
+ addu r18, r30,0 /* Remember arg7 to `vuserf'. */
+ addu r30, r0,0 /* Null-terminate call chain. */
+
+ jsr.n r17 /* Call `startup'. */
+ addu r2, r15,0 /* `pt' is arg0 to `startup'. */
+
+ addu r2, r19,0 /* Set arg0. */
+ addu r3, r20,0 /* Set arg1. */
+ addu r4, r21,0 /* Set arg2. */
+ addu r5, r22,0 /* Set arg3. */
+ addu r6, r23,0 /* Set arg4. */
+ addu r7, r24,0 /* Set arg5. */
+ addu r8, r25,0 /* Set arg6. */
+ jsr.n r16 /* Call `vuserf'. */
+ addu r9, r18,0 /* Set arg7. */
+
+ addu r3, r2,0 /* Ret. value is arg1 to `cleanup'. */
+ jsr.n r14 /* Call `cleanup'. */
+ addu r2, r15,0 /* `pt' is arg0 to `cleanup'. */
+
+ bsr _qt_error /* `cleanup' erroniously returned. */
diff --git a/ext/systemc/src/sysc/qt/md/m88k_b.s b/ext/systemc/src/sysc/qt/md/m88k_b.s
new file mode 100644
index 000000000..1926e6ae8
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/m88k_b.s
@@ -0,0 +1,117 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+ .text
+ .globl _b_call_reg
+ .globl _b_call_imm
+ .globl _b_add
+ .globl _b_load
+
+_b_null:
+ jmp r1
+
+_b_call_reg:
+ subu r31, r31,8 /* Alloc ret pc save space. */
+ st r1, r31,32 /* Save ret pc. */
+ or.u r3, r0,hi16(_b_null) /* Put call addr in a reg. */
+ or r3, r3,lo16(_b_null)
+ jsr r3
+L0:
+ jsr r3
+ jsr r3
+ jsr r3
+ jsr.n r3
+ subu r2, r2,5 /* Decrement #of iter to go. */
+ bcnd.n gt0,r2,L0
+ jsr r3
+
+ ld r1, r31,32
+ jmp r1
+
+
+_b_call_imm:
+ subu r31, r31,8 /* Alloc ret pc save space. */
+ st r1, r31,32 /* Save ret pc. */
+ bsr _b_null
+L1:
+ bsr _b_null
+ bsr _b_null
+ bsr _b_null
+ bsr.n _b_null
+ subu r2, r2,5 /* Decrement #of iter to go. */
+ bcnd.n gt0,r2,L1
+ bsr _b_null
+
+ ld r1, r31,32
+ jmp r1
+
+_b_add:
+ add r0, r3,r4
+L2:
+ add r3, r4,r5
+ add r4, r5,r6
+ add r5, r6,r7
+ add r8, r9,r0
+ add r0, r3,r4
+ add r3, r4,r5
+ add r4, r5,r6
+ add r5, r6,r7
+ add r8, r9,r0
+
+ add r0, r3,r4
+ add r3, r4,r5
+ add r4, r5,r6
+ add r5, r6,r7
+ add r8, r9,r0
+ add r0, r3,r4
+ add r3, r4,r5
+ add r4, r5,r6
+ add r5, r6,r7
+ add r8, r9,r0
+
+ subu r2, r2,20 /* Decrement #of iter to go. */
+ bcnd.n gt0,r2,L2
+ add r0, r3,r4
+
+ jmp r1
+
+
+_b_load:
+ ld r0, r31,0
+L3:
+ ld r3, r31,4
+ ld r4, r31,8
+ ld r5, r31,12
+ ld r6, r31,16
+ ld r0, r31,0
+ ld r3, r31,4
+ ld r4, r31,8
+ ld r5, r31,12
+ ld r6, r31,16
+
+ ld r0, r31,0
+ ld r3, r31,4
+ ld r4, r31,8
+ ld r5, r31,12
+ ld r6, r31,16
+ ld r0, r31,0
+ ld r3, r31,4
+ ld r4, r31,8
+ ld r5, r31,12
+ ld r6, r31,16
+
+ subu r2, r2,20 /* Decrement #of iter to go. */
+ bcnd.n gt0,r2,L3
+ ld r0, r31,0
+
+ jmp r1
diff --git a/ext/systemc/src/sysc/qt/md/mips-irix5.s b/ext/systemc/src/sysc/qt/md/mips-irix5.s
new file mode 100644
index 000000000..234a953ed
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/mips-irix5.s
@@ -0,0 +1,182 @@
+/* mips.s -- assembly support. */
+
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+/* Callee-save $16-$23, $30-$31.
+ *
+ * $25 is used as a procedure value pointer, used to discover constants
+ * in a callee. Thus, each caller here sets $25 before the call.
+ *
+ * On startup, restore regs so retpc === call to a function to start.
+ * We're going to call a function ($4) from within this routine.
+ * We're passing 3 args, therefore need to allocate 12 extra bytes on
+ * the stack for a save area. The start routine needs a like 16-byte
+ * save area. Must be doubleword aligned (_mips r3000 risc
+ * architecture_, gerry kane, pg d-23).
+ */
+
+/*
+ * Modified by Assar Westerlund <assar@sics.se> to support Irix 5.x
+ * calling conventions for dynamically-linked code.
+ */
+
+ /* Make this position-independent code. */
+ .option pic2
+
+ .globl qt_block
+ .globl qt_blocki
+ .globl qt_abort
+ .globl qt_start
+ .globl qt_vstart
+
+ /*
+ ** $4: ptr to function to call once curr is suspended
+ ** and control is on $7's stack.
+ ** $5: 1'th arg to $4.
+ ** $6: 2'th arg to $4
+ ** $7: sp of thread to suspend.
+ **
+ ** Totally gross hack: The MIPS calling convention reserves
+ ** 4 words on the stack for a0..a3. This routine "ought" to
+ ** allocate space for callee-save registers plus 4 words for
+ ** the helper function, but instead we use the 4 words
+ ** provided by the function that called us (we don't need to
+ ** save our argument registers). So what *appears* to be
+ ** allocating only 40 bytes is actually allocating 56, by
+ ** using the caller's 16 bytes.
+ **
+ ** The helper routine returns a value that is passed on as the
+ ** return value from the blocking routine. Since we don't
+ ** touch $2 between the helper's return and the end of
+ ** function, we get this behavior for free.
+ */
+qt_blocki:
+ sub $sp,$sp,40 /* Allocate reg save space. */
+ sw $16, 0+16($sp)
+ sw $17, 4+16($sp)
+ sw $18, 8+16($sp)
+ sw $19,12+16($sp)
+ sw $20,16+16($sp)
+ sw $21,20+16($sp)
+ sw $22,24+16($sp)
+ sw $23,28+16($sp)
+ sw $30,32+16($sp)
+ sw $31,36+16($sp)
+ add $2, $sp,$0 /* $2 <= old sp to pass to func@$4. */
+qt_abort:
+ add $sp, $7,$0 /* $sp <= new sp. */
+ .set noreorder
+ add $25, $4,$0 /* Set helper function procedure value. */
+ jal $31,$25 /* Call helper func@$4 . */
+ add $4, $2,$0 /* $a0 <= pass old sp as a parameter. */
+ .set reorder
+ lw $31,36+16($sp) /* Restore callee-save regs... */
+ lw $30,32+16($sp)
+ lw $23,28+16($sp)
+ lw $22,24+16($sp)
+ lw $21,20+16($sp)
+ lw $20,16+16($sp)
+ lw $19,12+16($sp)
+ lw $18, 8+16($sp)
+ lw $17, 4+16($sp)
+ lw $16, 0+16($sp) /* Restore callee-save */
+
+ add $sp,$sp,40 /* Deallocate reg save space. */
+ j $31 /* Return to caller. */
+
+ /*
+ ** Non-varargs thread startup.
+ ** Note: originally, 56 bytes were allocated on the stack.
+ ** The thread restore routine (_blocki/_abort) removed 40
+ ** of them, which means there is still 16 bytes for the
+ ** argument area required by the MIPS calling convention.
+ */
+qt_start:
+ add $4, $16,$0 /* Load up user function pu. */
+ add $5, $17,$0 /* ... user function pt. */
+ add $6, $18,$0 /* ... user function userf. */
+ add $25, $19,$0 /* Set `only' procedure value. */
+ jal $31,$25 /* Call `only'. */
+ la $25,qt_error /* Set `qt_error' procedure value. */
+ j $25
+
+
+ /*
+ ** Save calle-save floating-point regs $f20-$f30
+ ** See comment in `qt_block' about calling conventinos and
+ ** reserved space. Use the same trick here, but here we
+ ** actually have to allocate all the bytes since we have to
+ ** leave 4 words leftover for `qt_blocki'.
+ **
+ ** Return value from `qt_block' is the same as the return from
+ ** `qt_blocki'. We get that for free since we don't touch $2
+ ** between the return from `qt_blocki' and the return from
+ ** `qt_block'.
+ */
+qt_block:
+ sub $sp, $sp,56 /* 6 8-byte regs, saved ret pc, aligned. */
+ swc1 $f20, 0+16($sp)
+ swc1 $f22, 8+16($sp)
+ swc1 $f24, 16+16($sp)
+ swc1 $f26, 24+16($sp)
+ swc1 $f28, 32+16($sp)
+ swc1 $f30, 40+16($sp)
+ sw $31, 48+16($sp)
+ jal qt_blocki
+ lwc1 $f20, 0+16($sp)
+ lwc1 $f22, 8+16($sp)
+ lwc1 $f24, 16+16($sp)
+ lwc1 $f26, 24+16($sp)
+ lwc1 $f28, 32+16($sp)
+ lwc1 $f30, 40+16($sp)
+ lw $31, 48+16($sp)
+ add $sp, $sp,56
+ j $31
+
+
+ /*
+ ** First, call `startup' with the `pt' argument.
+ **
+ ** Next, call the user's function with all arguments.
+ ** Note that we don't know whether args were passed in
+ ** integer regs, fp regs, or on the stack (See Gerry Kane
+ ** "MIPS R2000 RISC Architecture" pg D-22), so we reload
+ ** all the registers, possibly with garbage arguments.
+ **
+ ** Finally, call `cleanup' with the `pt' argument and with
+ ** the return value from the user's function. It is an error
+ ** for `cleanup' to return.
+ */
+qt_vstart:
+ add $4, $17,$0 /* `pt' is arg0 to `startup'. */
+ add $25, $18,$0 /* Set `startup' procedure value. */
+ jal $31, $25 /* Call `startup'. */
+
+ add $sp, $sp,16 /* Free extra save space. */
+ lw $4, 0($sp) /* Load up args. */
+ lw $5, 4($sp)
+ lw $6, 8($sp)
+ lw $7, 12($sp)
+ lwc1 $f12, 0($sp) /* Load up fp args. */
+ lwc1 $f14, 8($sp)
+ add $25, $19,$0 /* Set `userf' procedure value. */
+ jal $31,$25 /* Call `userf'. */
+
+ add $4, $17,$0 /* `pt' is arg0 to `cleanup'. */
+ add $5, $2,$0 /* Ret. val is arg1 to `cleanup'. */
+ add $25, $16,$0 /* Set `cleanup' procedure value. */
+ jal $31, $25 /* Call `cleanup'. */
+
+ la $25,qt_error /* Set `qt_error' procedure value. */
+ j $25
diff --git a/ext/systemc/src/sysc/qt/md/mips.h b/ext/systemc/src/sysc/qt/md/mips.h
new file mode 100644
index 000000000..14d109461
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/mips.h
@@ -0,0 +1,134 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+#ifndef QUICKTHREADS_MIPS_H
+#define QUICKTHREADS_MIPS_H
+
+typedef unsigned long qt_word_t;
+
+#define QUICKTHREADS_GROW_DOWN
+
+/* Stack layout on the mips:
+
+ Callee-save registers are: $16-$23, $30; $f20-$f30.
+ Also save $31, return pc.
+
+ Non-varargs:
+
+ +---
+ | $f30 The first clump is only saved if `qt_block'
+ | $f28 is called, in which case it saves the fp regs
+ | $f26 then calls `qt_blocki' to save the int regs.
+ | $f24
+ | $f22
+ | $f20
+ | $31 === return pc in `qt_block'
+ +---
+ | $31 === return pc; on startup == qt_start
+ | $30
+ | $23
+ | $22
+ | $21
+ | $20
+ | $19 on startup === only
+ | $18 on startup === $a2 === userf
+ | $17 on startup === $a1 === pt
+ | $16 on startup === $a0 === pu
+ | <a3> save area req'd by MIPS calling convention
+ | <a2> save area req'd by MIPS calling convention
+ | <a1> save area req'd by MIPS calling convention
+ | <a0> save area req'd by MIPS calling convention <--- sp
+ +---
+
+ Conventions for varargs:
+
+ | args ...
+ +---
+ | :
+ | :
+ | $21
+ | $20
+ | $19 on startup === `userf'
+ | $18 on startup === `startup'
+ | $17 on startup === `pt'
+ | $16 on startup === `cleanup'
+ | <a3>
+ | <a2>
+ | <a1>
+ | <a0> <--- sp
+ +---
+
+ Note: if we wanted to, we could muck about and try to get the 4
+ argument registers loaded in to, e.g., $22, $23, $30, and $31,
+ and the return pc in, say, $20. Then, the first 4 args would
+ not need to be loaded from memory, they could just use
+ register-to-register copies. */
+
+
+/* Stack must be doubleword aligned. */
+#define QUICKTHREADS_STKALIGN (8) /* Doubleword aligned. */
+
+/* How much space is allocated to hold all the crud for
+ initialization: $16-$23, $30, $31. Just do an integer restore,
+ no need to restore floating-point. Four words are needed for the
+ argument save area for the helper function that will be called for
+ the old thread, just before the new thread starts to run. */
+
+#define QUICKTHREADS_STKBASE (14 * 4)
+#define QUICKTHREADS_VSTKBASE QUICKTHREADS_STKBASE
+
+
+/* Offsets of various registers. */
+#define QUICKTHREADS_31 (9+4)
+#define QUICKTHREADS_19 (3+4)
+#define QUICKTHREADS_18 (2+4)
+#define QUICKTHREADS_17 (1+4)
+#define QUICKTHREADS_16 (0+4)
+
+
+/* When a never-before-run thread is restored, the return pc points
+ to a fragment of code that starts the thread running. For
+ non-vargs functions, it just calls the client's `only' function.
+ For varargs functions, it calls the startup, user, and cleanup
+ functions.
+
+ The varargs startup routine always reads 4 words of arguments from
+ the stack. If there are less than 4 words of arguments, then the
+ startup routine can read off the top of the stack. To prevent
+ errors we always allocate 4 words. If there are more than 3 words
+ of arguments, the 4 preallocated words are simply wasted. */
+
+extern void qt_start(void);
+#define QUICKTHREADS_ARGS_MD(sp) (QUICKTHREADS_SPUT (sp, QUICKTHREADS_31, qt_start))
+
+#define QUICKTHREADS_VARGS_MD0(sp, vabytes) \
+ ((qt_t *)(((char *)(sp)) - 4*4 - QUICKTHREADS_STKROUNDUP(vabytes)))
+
+extern void qt_vstart(void);
+#define QUICKTHREADS_VARGS_MD1(sp) (QUICKTHREADS_SPUT (sp, QUICKTHREADS_31, qt_vstart))
+
+#define QUICKTHREADS_VARGS_DEFAULT
+
+
+/* The *index* (positive offset) of where to put each value. */
+#define QUICKTHREADS_ONLY_INDEX (QUICKTHREADS_19)
+#define QUICKTHREADS_USER_INDEX (QUICKTHREADS_18)
+#define QUICKTHREADS_ARGT_INDEX (QUICKTHREADS_17)
+#define QUICKTHREADS_ARGU_INDEX (QUICKTHREADS_16)
+
+#define QUICKTHREADS_VCLEANUP_INDEX (QUICKTHREADS_16)
+#define QUICKTHREADS_VUSERF_INDEX (QUICKTHREADS_19)
+#define QUICKTHREADS_VSTARTUP_INDEX (QUICKTHREADS_18)
+#define QUICKTHREADS_VARGT_INDEX (QUICKTHREADS_17)
+
+#endif /* ndef QUICKTHREADS_MIPS_H */
diff --git a/ext/systemc/src/sysc/qt/md/mips.s b/ext/systemc/src/sysc/qt/md/mips.s
new file mode 100644
index 000000000..b074b98dc
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/mips.s
@@ -0,0 +1,164 @@
+/* mips.s -- assembly support. */
+
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+/* Callee-save $16-$23, $30-$31.
+ *
+ * On startup, restore regs so retpc === call to a function to start.
+ * We're going to call a function ($4) from within this routine.
+ * We're passing 3 args, therefore need to allocate 12 extra bytes on
+ * the stack for a save area. The start routine needs a like 16-byte
+ * save area. Must be doubleword aligned (_mips r3000 risc
+ * architecture_, gerry kane, pg d-23).
+ */
+
+ .globl qt_block
+ .globl qt_blocki
+ .globl qt_abort
+ .globl qt_start
+ .globl qt_vstart
+
+ /*
+ ** $4: ptr to function to call once curr is suspended
+ ** and control is on $7's stack.
+ ** $5: 1'th arg to $4.
+ ** $6: 2'th arg to $4
+ ** $7: sp of thread to suspend.
+ **
+ ** Totally gross hack: The MIPS calling convention reserves
+ ** 4 words on the stack for a0..a3. This routine "ought" to
+ ** allocate space for callee-save registers plus 4 words for
+ ** the helper function, but instead we use the 4 words
+ ** provided by the function that called us (we don't need to
+ ** save our argument registers). So what *appears* to be
+ ** allocating only 40 bytes is actually allocating 56, by
+ ** using the caller's 16 bytes.
+ **
+ ** The helper routine returns a value that is passed on as the
+ ** return value from the blocking routine. Since we don't
+ ** touch $2 between the helper's return and the end of
+ ** function, we get this behavior for free.
+ */
+qt_blocki:
+ sub $sp,$sp,40 /* Allocate reg save space. */
+ sw $16, 0+16($sp)
+ sw $17, 4+16($sp)
+ sw $18, 8+16($sp)
+ sw $19,12+16($sp)
+ sw $20,16+16($sp)
+ sw $21,20+16($sp)
+ sw $22,24+16($sp)
+ sw $23,28+16($sp)
+ sw $30,32+16($sp)
+ sw $31,36+16($sp)
+ add $2, $sp,$0 /* $2 <= old sp to pass to func@$4. */
+qt_abort:
+ add $sp, $7,$0 /* $sp <= new sp. */
+ .set noreorder
+ jal $31,$4 /* Call helper func@$4 . */
+ add $4, $2,$0 /* $a0 <= pass old sp as a parameter. */
+ .set reorder
+ lw $31,36+16($sp) /* Restore callee-save regs... */
+ lw $30,32+16($sp)
+ lw $23,28+16($sp)
+ lw $22,24+16($sp)
+ lw $21,20+16($sp)
+ lw $20,16+16($sp)
+ lw $19,12+16($sp)
+ lw $18, 8+16($sp)
+ lw $17, 4+16($sp)
+ lw $16, 0+16($sp) /* Restore callee-save */
+
+ add $sp,$sp,40 /* Deallocate reg save space. */
+ j $31 /* Return to caller. */
+
+ /*
+ ** Non-varargs thread startup.
+ ** Note: originally, 56 bytes were allocated on the stack.
+ ** The thread restore routine (_blocki/_abort) removed 40
+ ** of them, which means there is still 16 bytes for the
+ ** argument area required by the MIPS calling convention.
+ */
+qt_start:
+ add $4, $16,$0 /* Load up user function pu. */
+ add $5, $17,$0 /* ... user function pt. */
+ add $6, $18,$0 /* ... user function userf. */
+ jal $31,$19 /* Call `only'. */
+ j qt_error
+
+
+ /*
+ ** Save calle-save floating-point regs $f20-$f30
+ ** See comment in `qt_block' about calling conventinos and
+ ** reserved space. Use the same trick here, but here we
+ ** actually have to allocate all the bytes since we have to
+ ** leave 4 words leftover for `qt_blocki'.
+ **
+ ** Return value from `qt_block' is the same as the return from
+ ** `qt_blocki'. We get that for free since we don't touch $2
+ ** between the return from `qt_blocki' and the return from
+ ** `qt_block'.
+ */
+qt_block:
+ sub $sp, $sp,56 /* 6 8-byte regs, saved ret pc, aligned. */
+ swc1 $f20, 0+16($sp)
+ swc1 $f22, 8+16($sp)
+ swc1 $f24, 16+16($sp)
+ swc1 $f26, 24+16($sp)
+ swc1 $f28, 32+16($sp)
+ swc1 $f30, 40+16($sp)
+ sw $31, 48+16($sp)
+ jal qt_blocki
+ lwc1 $f20, 0+16($sp)
+ lwc1 $f22, 8+16($sp)
+ lwc1 $f24, 16+16($sp)
+ lwc1 $f26, 24+16($sp)
+ lwc1 $f28, 32+16($sp)
+ lwc1 $f30, 40+16($sp)
+ lw $31, 48+16($sp)
+ add $sp, $sp,56
+ j $31
+
+
+ /*
+ ** First, call `startup' with the `pt' argument.
+ **
+ ** Next, call the user's function with all arguments.
+ ** Note that we don't know whether args were passed in
+ ** integer regs, fp regs, or on the stack (See Gerry Kane
+ ** "MIPS R2000 RISC Architecture" pg D-22), so we reload
+ ** all the registers, possibly with garbage arguments.
+ **
+ ** Finally, call `cleanup' with the `pt' argument and with
+ ** the return value from the user's function. It is an error
+ ** for `cleanup' to return.
+ */
+qt_vstart:
+ add $4, $17,$0 /* `pt' is arg0 to `startup'. */
+ jal $31, $18 /* Call `startup'. */
+
+ add $sp, $sp,16 /* Free extra save space. */
+ lw $4, 0($sp) /* Load up args. */
+ lw $5, 4($sp)
+ lw $6, 8($sp)
+ lw $7, 12($sp)
+ lwc1 $f12, 0($sp) /* Load up fp args. */
+ lwc1 $f14, 8($sp)
+ jal $31,$19 /* Call `userf'. */
+
+ add $4, $17,$0 /* `pt' is arg0 to `cleanup'. */
+ add $5, $2,$0 /* Ret. val is arg1 to `cleanup'. */
+ jal $31, $16 /* Call `cleanup'. */
+
+ j qt_error
diff --git a/ext/systemc/src/sysc/qt/md/mips_b.s b/ext/systemc/src/sysc/qt/md/mips_b.s
new file mode 100644
index 000000000..5b3740843
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/mips_b.s
@@ -0,0 +1,99 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+ .globl b_call_reg
+ .globl b_call_imm
+ .globl b_add
+ .globl b_load
+
+ .ent b_null
+b_null:
+ j $31
+ .end b_null
+
+ .ent b_call_reg
+b_call_reg:
+ la $5,b_null
+ add $6, $31,0
+$L0:
+ jal $5
+ jal $5
+ jal $5
+ jal $5
+ jal $5
+
+ sub $4, $4,5
+ bgtz $4,$L0
+ j $6
+ .end
+
+
+ .ent b_call_imm
+b_call_imm:
+ add $6, $31,0
+$L1:
+ jal b_null
+ jal b_null
+ jal b_null
+ jal b_null
+ jal b_null
+
+ sub $4, $4,5
+ bgtz $4,$L1
+ j $6
+ .end
+
+
+ .ent b_add
+b_add:
+ add $5, $0,$4
+ add $6, $0,$4
+ add $7, $0,$4
+ add $8, $0,$4
+$L2:
+ sub $4, $4,5
+ sub $5, $5,5
+ sub $6, $6,5
+ sub $7, $7,5
+ sub $8, $8,5
+
+ sub $4, $4,5
+ sub $5, $5,5
+ sub $6, $6,5
+ sub $7, $7,5
+ sub $8, $8,5
+
+ bgtz $4,$L2
+ j $31
+ .end
+
+
+ .ent b_load
+b_load:
+$L3:
+ ld $0, 0($sp)
+ ld $0, 4($sp)
+ ld $0, 8($sp)
+ ld $0, 12($sp)
+ ld $0, 16($sp)
+
+ ld $0, 20($sp)
+ ld $0, 24($sp)
+ ld $0, 28($sp)
+ ld $0, 32($sp)
+ ld $0, 36($sp)
+
+ sub $4, $4,10
+ bgtz $4,$L3
+ j $31
+ .end
diff --git a/ext/systemc/src/sysc/qt/md/null.README b/ext/systemc/src/sysc/qt/md/null.README
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/null.README
diff --git a/ext/systemc/src/sysc/qt/md/null.c b/ext/systemc/src/sysc/qt/md/null.c
new file mode 100644
index 000000000..db1a593ed
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/null.c
@@ -0,0 +1,14 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+char const qtmd_rcsid[] = "$Header: /Users/acg/CVSROOT/systemc-2.3/src/sysc/qt/md/null.c,v 1.1.1.1 2006/12/15 20:20:06 acg Exp $";
diff --git a/ext/systemc/src/sysc/qt/md/null.s b/ext/systemc/src/sysc/qt/md/null.s
new file mode 100644
index 000000000..8a2361f9e
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/null.s
@@ -0,0 +1,12 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
diff --git a/ext/systemc/src/sysc/qt/md/powerpc.README b/ext/systemc/src/sysc/qt/md/powerpc.README
new file mode 100644
index 000000000..b98da8b27
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/powerpc.README
@@ -0,0 +1,27 @@
+
+PowerPC assembly support
+
+
+1) MacOS X, Darwin, MKLinux and other systems based on Mach kernel ABI:
+
+ - Configuration command: ./config powerpc-darwin
+
+ - See documentation inside powerpc_mach.h, powerpc_mach.s, powerpc.c.
+
+
+2) LinuxPPC, and other systems based on System V ABI:
+
+ - Configuration command: ./config powerpc
+
+ - See documentation inside powerpc_sys5.h, powerpc_sys5.s, powerpc.c.
+
+
+Marco Bucci <marco.bucci@inwind.it>
+December 2002
+
+
+ * This software is largely based on the original PowerPC-Linux porting
+ * developed by Ken Aaker <kenaaker@silverbacksystems.com>
+ *
+ * Marco Bucci <marco.bucci@inwind.it>
+ * December 2002
diff --git a/ext/systemc/src/sysc/qt/md/powerpc.c b/ext/systemc/src/sysc/qt/md/powerpc.c
new file mode 100644
index 000000000..fb374f3f2
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/powerpc.c
@@ -0,0 +1,69 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+
+#include <stdarg.h>
+#include "qt.h"
+
+// This static is used to find the end of the stack for variable
+
+static void *qt_sp_bottom_save;
+
+/* We actually don't know how the compiler accomodates arguments in the
+ * va_list. In some implementation (e.g. Linux PPC) we cannot scan the
+ * list as an array. To avoid this problem, this version of "qt_varg",
+ * retrieves arguments by means of the standard "va_arg" macro defined
+ * in stdargs.h.
+ *
+ * Notice that we still suppose that the number of arguments is given
+ * by nbytes/sizeof(qt_word_t) and we load the stack of "qt_vstart"
+ * assuming that all parameters are alligned to the size of qt_word_t.
+ *
+ * Marco Bucci <marco.bucci@inwind.it>
+ * December 2002
+ */
+
+/*
+
+qt_t *qt_vargs (qt_t *sp, int nbytes, void *vargs,
+ void *pt, qt_startup_t *startup,
+ qt_vuserf_t *vuserf, qt_cleanup_t *cleanup)
+
+*/
+
+ qt_t *
+qt_vargs_stdarg (qt_t *sp, int nbytes, va_list vargs,
+ void *pt, qt_startup_t *startup,
+ qt_vuserf_t *vuserf, qt_cleanup_t *cleanup)
+
+
+
+{
+ int i;
+ qt_word_t arg;
+
+ sp = QUICKTHREADS_VARGS_MD0 (sp, nbytes);
+
+ for ( i=0;i<(int)(nbytes/sizeof(qt_word_t)); i++)
+ {
+ arg = va_arg(vargs, qt_word_t);
+ QUICKTHREADS_SPUT (QUICKTHREADS_VARGS_ADJUST(sp), i, arg);
+ }
+
+ QUICKTHREADS_VARGS_MD1 (QUICKTHREADS_VADJ(sp));
+ QUICKTHREADS_SPUT (QUICKTHREADS_VADJ(sp), QUICKTHREADS_VARGT_INDEX, pt);
+ QUICKTHREADS_SPUT (QUICKTHREADS_VADJ(sp), QUICKTHREADS_VSTARTUP_INDEX, startup);
+ QUICKTHREADS_SPUT (QUICKTHREADS_VADJ(sp), QUICKTHREADS_VUSERF_INDEX, vuserf);
+ QUICKTHREADS_SPUT (QUICKTHREADS_VADJ(sp), QUICKTHREADS_VCLEANUP_INDEX, cleanup);
+ return ((qt_t *)QUICKTHREADS_VADJ(sp));
+}
diff --git a/ext/systemc/src/sysc/qt/md/powerpc_mach.h b/ext/systemc/src/sysc/qt/md/powerpc_mach.h
new file mode 100644
index 000000000..677808c5c
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/powerpc_mach.h
@@ -0,0 +1,611 @@
+/*
+ + * QuickThreads -- Threads-building toolkit.
+ + * Copyright (c) 1993 by David Keppel
+ + *
+ + * Permission to use, copy, modify and distribute this software and
+ + * its documentation for any purpose and without fee is hereby
+ + * granted, provided that the above copyright notice and this notice
+ + * appear in all copies. This software is provided as a
+ + * proof-of-concept and for demonstration purposes; there is no
+ + * representation about the suitability of this software for any
+ + * purpose.
+ + *
+
+ + * PowerPC-Mach thread switching module.
+ + *
+ + * This software is largely based on the original PowerPC-Linux porting
+ + * developed by Ken Aaker <kenaaker@silverbacksystems.com>
+ + *
+ + * Marco Bucci <marco.bucci@inwind.it>
+ + * December 2002
+ + *
+ + */
+
+
+#ifndef QUICKTHREADS_POWERPC_H
+#define QUICKTHREADS_POWERPC_H
+
+
+/*****************************************************************************
+ *
+ * DESCRIPTION
+ *
+ * This is the QuickThreads switching module implementation for PowerPC
+ * running under Mach kernel. It was developed and tested under MacOS X, that
+ * is under Darwin (the UNIX-BSD fundation of MacOS X).
+ *
+ * Notice that the Mach PowerPC ABI (Application Binary Interface) [1] is
+ * not the same than System V ABI [2] used by most of the LINUX PowerPC
+ * implementations.
+ *
+ * IMPLEMENTATION NOTES
+ *
+ * 1) Porting on System V ABI
+ * Excluding the variant argument calling convention, Mach and System V ABI
+ * are enough similar and it could be possible to use some simple macro, to
+ * adapt the code for both the ABIs. Actually, the only relevant difference
+ * is in the linkage area structure and in the position where the Link and
+ * the Condition registers are saved. As to the calling conventions, there
+ * are differences with floating points argument passing and with variant
+ * argument lists. Notice that, on Mach, the caller's stack frame allocates
+ * space to hold all arguments ([1] p.51), while on System V, the caller's
+ * stack frame allocates space to hold just the arguments that don't fit into
+ * registers ([2] p.3.18).
+ *
+ * 2) Variant argument list implementation
+ * Variant argument calling on a RISC machine is not easy to implement since
+ * parameters are passed via registers instead of via stack. In a general
+ * variant argument implementation, the caller's stack must map the whole
+ * parameter list following the rules related to the use of the GPR and FPR
+ * parameter registers and the stack alignment ([1] p.54).
+ * This implementation is quite simple and not general. It works under the
+ * hypothesis that arguments are 4-bytes aligned integers.
+ *
+ * 3) This heather file organisation
+ * I preferred to not make confusion between macros that are needed (i.e.
+ * directly used) by QuickThreads and internal "implementation" macros. You
+ * will find QuickThreds macros in the end of this header. Sometime they just
+ * refer to an analogous "internal" macro. On the top, there are the macros
+ * that I used to make more clean (I hope) the implementation. I could include
+ * some system heather (as to stack layout definitions, prologs and epilogs,
+ * etc.), but I preferred to have a self-contained heather in order to make
+ * all more clear for mantaining and for possible porting on another ABI.
+ *
+ *
+ * REFERENCES
+ *
+ * [1] - Mach-O Runtime Architecture
+ * Runtime Concepts and Conventions for Mac OS X Programs
+ * Preliminary July 2002
+ *
+ * [2] - SYSTEM V APPLICATION BINARY INTERFACE
+ * PowerPC Processor Supplement
+ * September 1995
+ *
+ * On MacOS X, more documentation is available by installing the "Developer
+ * Tools". Useful macros and documentation can be found in the system headers
+ * files such as asm.h, asm_help.h etc. (see /usr/architecture/ppc/ or
+ * /System/Library/Frameworks/Kernel.framework/Headers/architecture/ppc/).
+
+ *****************************************************************************/
+
+/*****************************************************************************
+ *
+ * PowerPC Mach-O Stack frame (see [1])
+ *
+
+ ................
+ + +
+ | | reserved
+ + CALLER'S LINKAGE AREA +
+ | | Caller's LR
+ + +
+ | | Caller's CR
+ + +
+ backchain -> | | Caller's backchain
+ +==========================+
+ | | FPR31
+ + FPR SAVE AREA +
+ ..............
+ + +
+ | | FPRn
+ +--------------------------+
+ | | GPR31
+ + GPR SAVE AREA +
+ ..............
+ + +
+ | | GPRn
+ +--------------------------+
+ | |
+ + ALIGNMEBNT PAD +
+ ..............
+ + (if needed) +
+ | |
+ +--------------------------+
+ | |
+ + LOCAL VARIABLES AREA +
+ ..............
+ + +
+ | |
+ +--------------------------+
+ | | PAR(n)
+ + +
+ | |
+ + PARAMETER AREA +
+ ..............
+ + for FUTURE call +
+ | | PAR(1)
+ + +
+ SP + 24 -> | | PAR(0)
+ +--------------------------+
+ SP + 20 -> | | Caller's TOC
+ + +
+ SP + 16 -> | | reserved
+ + +
+ SP + 12 -> | | reserved
+ + LINKAGE AREA +
+ SP + 8 -> | | LR callee-save for FUTURE call
+ + +
+ SP + 4 -> | | CR callee-save for FUTURE call
+ + +
+ SP -> | | backchain
+ +==========================+
+ STACK TOP (lower address)
+
+ Stack grows down
+ |
+ V
+ * NOTE:
+ *
+ * 1) Parameter are allocated in the CALLER's parameter area. This area must
+ * be large enough to hold all parameters regardless if they are or not passed
+ * in registers.
+ *
+ * The caller parameter area is used:
+ * - by the caller, to store parameters to the callee that cannot fit in
+ * registers (no more parameter registers are available);
+ * - by the callee, to save parameter registers (for istance because they are
+ * needed for a further call).
+ *
+ * Obviously, the callee saves parameter registers, in the location in which
+ * they are mapped on the caller's stack frame. So, be aware that, if
+ * something else is stored in that location, it could be deleted after a call.
+ *
+ * 2) The callee saves LR and CR in the caller's linkage area. All other
+ * callee's state are saved in its own stack frame.
+ *
+
+ *****************************************************************************/
+
+
+/*****************************************************************************
+ *
+ * Stack initialization for a single argument thread
+ *
+
+
+ top + QUICKTHREADS_STKBASE -> STACK BOTTOM (higher address)
+ +==========================+
+ | |
+ + +
+ ..............
+ + +
+ | |
+ +--------------------------+
+ top + QUICKTHREADS_ONLY_INDEX * 4 -> | only param | PAR(3)
+ + +
+ top + QUICKTHREADS_USER_INDEX * 4 -> | userf param | PAR(2)
+ + +
+ top + QUICKTHREADS_ARGT_INDEX * 4 -> | t param | PAR(1)
+ + +
+ top + QUICKTHREADS_ARGU_INDEX * 4 -> | u param | PAR(0)
+ +--------------------------+
+ | |
+ + +
+ ..............
+ + +
+ top + QUICKTHREADS_RETURN_INDEX * 4 -> | qt_start | LR save
+ + +
+ ..............
+ + +
+ top + QUICKTHREADS_BLOCKI_FRAME_SIZE -> | top + QUICKTHREADS_STKBASE | backchain
+ +==========================+
+ | |
+ + +
+ ..............
+ + +
+ | |
+ +--------------------------+
+ | |
+ + +
+ ..............
+ + +
+ top -> |top + QUICKTHREADS_BLOCKI_FRAME_SIZE| backchain
+ +==========================+
+ STACK TOP (lower address)
+
+ Stack grows down
+ |
+ V
+
+ *****************************************************************************
+ *
+ * Stack initialization for a variant argument thread
+ *
+
+ bottom -> STACK BOTTOM (higher address)
+ +==========================+
+ | |
+ + +
+ ..............
+ + +
+ top + QUICKTHREADS_VSTKBASE -> | arg(0) | PAR(4)
+ +--------------------------+
+ top + QUICKTHREADS_CLEANUP_INDEX * 4 -> | cleanup param | PAR(3)
+ + +
+ top + QUICKTHREADS_USER_INDEX * 4 -> | userf param | PAR(2)
+ + +
+ top + QUICKTHREADS_VSTARTUP_INDEX * 4 ->| startup param | PAR(1)
+ + +
+ top + QUICKTHREADS_ARGT_INDEX * 4 -> | t param | PAR(0)
+ +--------------------------+
+ | |
+ + +
+ ..............
+ + +
+ top + QUICKTHREADS_RETURN_INDEX * 4 -> | qt_start | LR save
+ + +
+ ..............
+ top + QUICKTHREADS_BLOCKI_FRAME_SIZE -> | top + QUICKTHREADS_STKBASE | backchain
+ +==========================+
+ | |
+ + +
+ ..............
+ + +
+ | |
+ +--------------------------+
+ | |
+ + +
+ ..............
+ + +
+ top -> |top + QUICKTHREADS_BLOCKI_FRAME_SIZE| backchain
+ +==========================+
+ STACK TOP (lower address)
+
+ Stack grows down
+ |
+ V
+
+* NOTE:
+*
+* Parameters are passed to "qt_start" or to "qt_vstart" putting them into
+* the stack frames of "qt_start" or "qt_vstart" themselves. This not a
+* conventional parameter passing because parameters should be put into the
+* caller's stack, not into the callee's one. Actually we must consider
+* that as a preload of the parameter area that "qt_start" or "qt_vstart"
+* will use for their own calls.
+* Be aware of the fact that, during a call, the caller's parameter area is,
+* in a certain sense, volatile. In facts, the callee can save parameter
+* registers on the caller's parameter area.
+*
+ *****************************************************************************/
+
+
+/*****************************************************************************
+
+ Define PowerPC Mach-O related macros
+
+ *****************************************************************************/
+
+
+
+typedef unsigned long PPC_W;
+
+/* Stack pointer must always be a multiple of 16 */
+#define PPC_STACK_INCR 16
+#define PPC_ROUND_STACK(length) \
+ (((length)+PPC_STACK_INCR-1) & ~(PPC_STACK_INCR-1))
+
+
+#define PPC_LINKAGE_AREA 24
+#define PPC_CR_SAVE 4
+#define PPC_LR_SAVE 8
+
+#define PPC_PARAM_AREA(n) (4*(n))
+
+#define PPC_GPR_SAVE_AREA (4*19) /* GPR13-GPR31 must be saved */
+#define PPC_FPR_SAVE_AREA (8*18) /* FPR14-FPR31 must be saved */
+
+/* Define parameter offset on the stack.
+ * NOTICE: Parameters are numbered 0, 1, ..., n.
+*/
+#define PPC_PAR(i) (PPC_LINKAGE_AREA+(i)*4)
+
+/*****************************************************************************
+
+ Define stack frames
+
+ *****************************************************************************/
+
+
+/* Define the "qt_blocki" and "qt_abort" stack frame. We use the same stack
+ * frame for both.
+ *
+
+ top + S ->
+ +==========================+
+ top + S - 4 -> | | GPR31
+ + GPR SAVE AREA +
+ ..............
+ + +
+ top + S - 19 * 4 -> | | GPR13
+ +--------------------------+
+ | |
+ + ALIGNMEBNT PAD +
+ ..............
+ + (if needed) +
+ | |
+ +--------------------------+
+ | |
+ + +
+ | |
+ + PARAMETER AREA +
+ | |
+ + +
+ top + 24 -> | |
+ +--------------------------+
+ | |
+ + LINKAGE AREA +
+ top -> | |
+ +==========================+
+ */
+
+#define QUICKTHREADS_BLOCKI_FRAME_SIZE \
+ PPC_ROUND_STACK(PPC_LINKAGE_AREA+PPC_PARAM_AREA(4)+PPC_GPR_SAVE_AREA)
+
+/* Offset to the base of the GPR save area. Save from GPR13 to GPR31
+ * increasing address.
+ */
+#define QUICKTHREADS_BLOCKI_GPR_SAVE(i) (QUICKTHREADS_BLOCKI_FRAME_SIZE-4+(i-31)*4)
+
+
+
+/* Define the "qt_block" stack frame. Notice that since "qt_black" calls
+ * "qt_blocki", GPR registers are saved into "qt_blocki" stack frame.
+ *
+
+ top + S ->
+ +==========================+
+ top + S - 8 -> | | FPR31
+ + FPR SAVE AREA +
+ ..............
+ + +
+ top + S - 18 * 8 -> | | FPR14
+ +--------------------------+
+ | |
+ + ALIGNMEBNT PAD +
+ ..............
+ + (if needed) +
+ | |
+ +--------------------------+
+ | |
+ + +
+ | |
+ + PARAMETER AREA +
+ | |
+ + +
+ top + 24 -> | |
+ +--------------------------+
+ | |
+ + LINKAGE AREA +
+ top -> | |
+ +==========================+
+ */
+
+#define QUICKTHREADS_BLOCK_FRAME_SIZE \
+ PPC_ROUND_STACK(PPC_LINKAGE_AREA+PPC_PARAM_AREA(4)+PPC_FPR_SAVE_AREA)
+
+/* Offset to the location where registers are saved.
+ */
+#define QUICKTHREADS_BLOCK_FPR_SAVE(i) (QUICKTHREADS_BLOCK_FRAME_SIZE-8+(i-31)*8)
+
+
+/* Define the "qt_start" frame size. It consists just of the linkage area and
+ * the parameter area.
+ *
+
+ +==========================+
+ | |
+ + ALIGNMEBNT PAD +
+ ..............
+ + (if needed) +
+ | |
+ +--------------------------+
+ | | only par
+ + +
+ | | userf par
+ + PARAMETER AREA +
+ | | t par
+ + +
+ top + 24 -> | | u par
+ +--------------------------+
+ | |
+ + LINKAGE AREA +
+ top -> | |
+ +==========================+
+
+ */
+#define QUICKTHREADS_START_FRAME_SIZE PPC_ROUND_STACK(PPC_LINKAGE_AREA+PPC_PARAM_AREA(4))
+
+
+
+/* Define the "qt_vstart" frame. It consists of the linkage area, the fix parameter
+ * area, the variant argument list and a local variable area used in "qt_vstart"
+ * implementation.
+ *
+
+ backchain ->
+ +==========================+
+ backchain - 4 -> | |
+ + LOCAL VARIABLES AREA +
+ ..............
+ + +
+ | |
+ +--------------------------+
+ | |
+ + ALIGNMEBNT PAD +
+ ..............
+ + (if needed) +
+ | |
+ +--------------------------+
+ | | arg(n)
+ + +
+ | |
+ + VARIABLE ARGUMENT LIST +
+ ..............
+ + for userf call +
+ | | arg(1)
+ + +
+ top + 24 + 16 -> | | arg(0)
+ +--------------------------+
+ | | cleanup par
+ + +
+ | | userf par
+ + PARAMETER AREA +
+ | | startup par
+ + +
+ top + 24 -> | | t par
+ +--------------------------+
+ | |
+ + LINKAGE AREA +
+ top -> | |
+ +==========================+
+
+ */
+#define QUICKTHREADS_VARGS_LOCAL_AREA (4*4) /* local variable area */
+
+/* The offset the stack will be moved back before to call "userf(...)".
+ * The linckage area must be moved to be adiacent to the part of the variant
+ * argument list that is in the stack.
+ */
+#define QUICKTHREADS_VARGS_BKOFF PPC_PARAM_AREA(4)
+
+#define QUICKTHREADS_VSTART_FRAME_SIZE(varbytes) \
+ PPC_ROUND_STACK(PPC_LINKAGE_AREA+PPC_PARAM_AREA(4)+(varbytes)+ \
+ QUICKTHREADS_VARGS_LOCAL_AREA)
+
+/* Offset to the base of the varian argument list */
+#define QUICKTHREADS_VSTART_LIST_BASE (PPC_LINKAGE_AREA+PPC_PARAM_AREA(4))
+
+
+/* Notice that qt_start and qt_vstart have no parameters, actually their
+ * parameters are written in their stack frame during thread initialization
+ */
+extern void qt_start(void);
+extern void qt_vstart(void);
+
+
+
+/* Offset (in words) of the location where the block routine saves its return
+ * address (i.e. LR). SP points the top of the block routine stack and,
+ * following ppc calling conventions, the return address is saved in the
+ * previous (caller's) stack frame.
+ */
+#define QUICKTHREADS_RETURN_INDEX ((QUICKTHREADS_BLOCKI_FRAME_SIZE+PPC_LR_SAVE)/sizeof(PPC_W))
+
+/* static variable used to get the stack bottom in "VARGS" initialization */
+/* static void *qt_sp_bottom_save; */
+
+#define QUICKTHREADS_ARG_INDEX(i) ((QUICKTHREADS_BLOCKI_FRAME_SIZE+PPC_PAR(i))/sizeof(PPC_W))
+
+/*****************************************************************************
+
+ QuickThreads needed definitions
+
+ *****************************************************************************/
+
+
+#define QUICKTHREADS_GROW_DOWN
+#define QUICKTHREADS_STKALIGN PPC_STACK_INCR
+typedef PPC_W qt_word_t;
+
+
+/* This macro is used by "QUICKTHREADS_ARGS" to initialize a single argument thread.
+ * - set "qt_start" as the "qt_block" or "qt_blocki" return address;
+ * - set the top of the stack backchain;
+ * - set the next backchain (not needed, but just to be "clean").
+ */
+#define QUICKTHREADS_ARGS_MD(sp) \
+ (QUICKTHREADS_SPUT (sp, QUICKTHREADS_RETURN_INDEX, qt_start), \
+ QUICKTHREADS_SPUT (sp, 0, sp+QUICKTHREADS_BLOCKI_FRAME_SIZE), \
+ QUICKTHREADS_SPUT (sp, QUICKTHREADS_BLOCKI_FRAME_SIZE/sizeof(PPC_W), \
+ sp+QUICKTHREADS_BLOCKI_FRAME_SIZE+QUICKTHREADS_START_FRAME_SIZE))
+
+
+/* This macro is used by "QUICKTHREADS_VARGS" to initialize a variant argument thread.
+ * It returns the pointer to the top of the argument list.
+ * We also use it to get the stack bottom via a static variable. This is a bit
+ * "dirty", it could be better to do it in "qt_vargs", but we don't want change
+ * anything out of this file.
+ * We need the stack bottom to allocate a local variable area used by
+ * "qt_vstart".
+ */
+#define QUICKTHREADS_VARGS_MD0(sp, varbytes) \
+ ((qt_sp_bottom_save = sp), \
+ ((qt_t *)(((char *)(sp)) - \
+ (QUICKTHREADS_VSTART_FRAME_SIZE(varbytes)-QUICKTHREADS_VSTART_LIST_BASE))))
+
+
+/* This macro is used by "QUICKTHREADS_VARGS" to initialize a variant argument thread.
+ * - set "qt_start" as the "qt_block" or "qt_blocki" return address;
+ * - set the top of the stackback chain;
+ * - set the next backchain (it points the stack botton).
+ */
+#define QUICKTHREADS_VARGS_MD1(sp) \
+ (QUICKTHREADS_SPUT (sp, QUICKTHREADS_RETURN_INDEX, qt_vstart), \
+ QUICKTHREADS_SPUT (sp, 0, sp+QUICKTHREADS_BLOCKI_FRAME_SIZE), \
+ QUICKTHREADS_SPUT (sp, (QUICKTHREADS_BLOCKI_FRAME_SIZE)/sizeof(PPC_W), \
+ qt_sp_bottom_save))
+
+
+/* Activate "qt_vargs" as the initialization routine for the variant
+ * argument threads
+ */
+#define QUICKTHREADS_VARGS_DEFAULT
+
+/* Override "qt_vargs" with "qt_vargs_stdarg".
+ * On LinuxPPC "qt_vargs" doesn't work, "qt_vargs_stdarg" uses a more
+ * standard way to retrieve arguments from the variant list.
+ */
+#define QUICKTHREADS_VARGS(sp, nbytes, vargs, pt, startup, vuserf, cleanup) \
+ ((qt_t *)qt_vargs_stdarg (sp, nbytes, vargs, pt, startup, vuserf, cleanup))
+
+
+/* This macro is used by "QUICKTHREADS_ADJ(sp)" to get the stack top form the stack
+ * bottom during a single argument thread initialization.
+ * It is the space we need to allocate for a single argument thread: the stack
+ * frame for the block routine ("qt_block" or "qt_blocki") and for "qt_start".
+ */
+#define QUICKTHREADS_STKBASE \
+ (QUICKTHREADS_BLOCKI_FRAME_SIZE+QUICKTHREADS_START_FRAME_SIZE)
+
+/* This macro is used by "QUICKTHREADS_VADJ(sp)" to get the stack top from the base
+ * of the variant argument list during a variant argument thread initialization.
+ */
+#define QUICKTHREADS_VSTKBASE (QUICKTHREADS_BLOCKI_FRAME_SIZE+QUICKTHREADS_VSTART_LIST_BASE)
+
+/* The *index* (positive offset) of where to put each value. */
+
+#define QUICKTHREADS_ARGU_INDEX QUICKTHREADS_ARG_INDEX(0)
+#define QUICKTHREADS_ARGT_INDEX QUICKTHREADS_ARG_INDEX(1)
+#define QUICKTHREADS_USER_INDEX QUICKTHREADS_ARG_INDEX(2)
+#define QUICKTHREADS_ONLY_INDEX QUICKTHREADS_ARG_INDEX(3)
+
+
+#define QUICKTHREADS_VARGT_INDEX QUICKTHREADS_ARG_INDEX(0)
+#define QUICKTHREADS_VSTARTUP_INDEX QUICKTHREADS_ARG_INDEX(1)
+#define QUICKTHREADS_VUSERF_INDEX QUICKTHREADS_ARG_INDEX(2)
+#define QUICKTHREADS_VCLEANUP_INDEX QUICKTHREADS_ARG_INDEX(3)
+
+#endif /* ndef QUICKTHREADS_POWERPC_H */
+
diff --git a/ext/systemc/src/sysc/qt/md/powerpc_mach.s b/ext/systemc/src/sysc/qt/md/powerpc_mach.s
new file mode 100644
index 000000000..63414b05d
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/powerpc_mach.s
@@ -0,0 +1,641 @@
+/* powerpc_mach.s -- assembly support. */
+
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+
+
+ * PowerPC-Mach thread switching module.
+ * Darwin (MacOS X) assembly
+ *
+ * NOTICE: Syntax for register names is not the GNU one. Register are
+ * named "rx" and "fx", not "%rx" and "%fx" as usual for the GNU "as" tool.
+ * Darwin "as" tool is based on GNU "as" but follows the "official" PowerPC
+ * syntax.
+ *
+ *
+ * This software is largely based on the original PowerPC-Linux porting
+ * developed by Ken Aaker <kenaaker@silverbacksystems.com>
+ *
+ * Marco Bucci <marco.bucci@inwind.it>
+ * December 2002
+ *
+ */
+
+
+/*
+ *
+ * PowerPC Register convections:
+ *
+ * r0 volatile
+ * r1 SP
+ * r2 system reserved
+ * r3-r4 volatile for parameter passing and function return
+ * r5-r10 volatile for parameter passing
+ * r11-r12 volatile
+ * r13-r14 non volatile registers
+ * f0 volatile
+ * f1 volatile for parameter passing and function return
+ * f2-f13 volatile for parameter passing
+ * f14-f31 non volatile
+ *
+ * cr2-cr4 non volatile
+ *
+ *
+ * See on the heather file for more documentation.
+ *
+ *
+ *
+ * IMPLEMENTATION NOTES
+ *
+ *
+ * 1) Condition register saving
+ * On most machines, the condition code register is caller-save.
+ * On the PPC, the condition code register is callee-save, so the
+ * thread context switch must preserve it.
+ *
+ *
+ * 2) Floating point registers saving
+ * On resuming a thread, floating point registers are or not restored just
+ * depending on which block routine suspended the thread (i.e. regardless
+ * whether "qt_block", "qt_blocki" or "qt_abort" is used to resume it).
+ * This behaviour is obtained by implementing "qt_block" by means af a nested
+ * call to "qt_blocki". As a result, the blocking of a thread always goes
+ * and returns through "qt_blocki and, if a thread was blocked by "qt_block",
+ * its execution resumes from the floating point restoring code on exit
+ * of "qt_block".
+ *
+ * Thanks to David Keppel that explained me this "simple" trick.
+ *
+ *
+ * 3) C languace code debugging
+ * This software was developed and debugged using the Metrowerks
+ * Code Warrior PPC integrated assembler. It can be still used with the
+ * Code Warrior compiler by means of the file "powerpc_mach_asm_debug.c"
+ * that include it.
+ * In order to avoid "copy and paste" bugs, and make easyer the maintaining,
+ * I made the minimal changes, so you can find some strange code as:
+ *
+ * #if 0
+ * .if 0
+ * C code here
+ * .endif
+ * #endif
+ *
+ * This is just to embed some C code that is needed by the Code Warrior
+ * integrated assembler.
+ *
+ *
+ * 4) Assembly constants generation
+ * Constants used in the assembly code are generated by running
+ * the C code in the sequel (commented). It uses the C macros declared in
+ * the C heather in order to guarantee that the C interface and the assebly
+ * code are "aligned". I avoided the use of an assebler preprocessor since
+ * they are not so standard and moreover using macro espressions makes the
+ * assembly debugging more difficult.
+ *
+ *
+
+
+#include <iostream>
+#include "powerpc_mach.h"
+
+int main()
+{
+ using namespace std;
+
+ int i;
+
+ cout << ".set LR_SAVE, " << PPC_LR_SAVE << endl;
+ cout << ".set CR_SAVE, " << PPC_CR_SAVE << endl;
+ cout << ".set BLOCKI_FSIZE, " << QUICKTHREADS_BLOCKI_FRAME_SIZE << endl;
+ cout << ".set BLOCK_FSIZE, " << QUICKTHREADS_BLOCK_FRAME_SIZE << endl;
+
+ cout << endl;
+ for(i=0; i<12; i++)
+ cout << ".set PAR_" << i << ", " << PPC_PAR(i) << endl;
+
+ cout << endl;
+ i = 13;
+ cout << ".set GPR_SAVE_" << i << ", " << QUICKTHREADS_BLOCKI_GPR_SAVE(i) << endl;
+
+ cout << endl;
+ for(i=31; i>13; i--)
+ cout << ".set FPR_SAVE_" << i << ", " << QUICKTHREADS_BLOCK_FPR_SAVE(i) << endl;
+
+ cout << endl;
+ cout << ".set VARGS_BKOFF, " << QUICKTHREADS_VARGS_BKOFF << endl;
+
+
+ cout << endl << endl << endl;
+
+ for(i=31; i>13; i--)
+ cout << "\tstfd\tf" << i << ",FPR_SAVE_" << i << "(r1)" << endl;
+
+ cout << endl;
+ for(i=31; i>13; i--)
+ cout << "\tlfd \tf" << i << ",FPR_SAVE_" << i << "(r1)" << endl;
+
+ cout << endl << endl << endl;
+
+
+ return 0;
+}
+
+
+ *
+ *
+ *
+ */
+
+
+#if 0
+
+ .text
+ .align 4
+
+ .globl qt_block
+ .globl _qt_block
+ .globl qt_blocki
+ .globl _qt_blocki
+ .globl qt_abort
+ .globl _qt_abort
+ .globl qt_start
+ .globl _qt_start
+ .globl qt_vstart
+ .globl _qt_vstart
+
+
+.set LR_SAVE, 8
+.set CR_SAVE, 4
+.set BLOCKI_FSIZE, 128
+.set BLOCK_FSIZE, 192
+
+.set PAR_0, 24
+.set PAR_1, 28
+.set PAR_2, 32
+.set PAR_3, 36
+.set PAR_4, 40
+.set PAR_5, 44
+.set PAR_6, 48
+.set PAR_7, 52
+.set PAR_8, 56
+.set PAR_9, 60
+.set PAR_10, 64
+.set PAR_11, 68
+
+.set GPR_SAVE_13, 52
+
+.set FPR_SAVE_31, 184
+.set FPR_SAVE_30, 176
+.set FPR_SAVE_29, 168
+.set FPR_SAVE_28, 160
+.set FPR_SAVE_27, 152
+.set FPR_SAVE_26, 144
+.set FPR_SAVE_25, 136
+.set FPR_SAVE_24, 128
+.set FPR_SAVE_23, 120
+.set FPR_SAVE_22, 112
+.set FPR_SAVE_21, 104
+.set FPR_SAVE_20, 96
+.set FPR_SAVE_19, 88
+.set FPR_SAVE_18, 80
+.set FPR_SAVE_17, 72
+.set FPR_SAVE_16, 64
+.set FPR_SAVE_15, 56
+.set FPR_SAVE_14, 48
+
+
+/* various offsets used by "qt_varg" */
+.set P_T, PAR_0
+.set P_STARTUP, PAR_1
+.set P_USERF, PAR_2
+.set P_CLEANUP, PAR_3
+ /* the offset used to move back the linkage area to be adiacent to
+ * the variant argument list before calling "userf(...) */
+.set VARGS_BKOFF, 16 /* skip "t", "startup", "userf" and "cleanup" */
+
+ /* location where "t" and "cleanup" are saved (with respect of
+ * the stack frame base) */
+.set P_T_SAVE, -4
+.set P_CLEANUP_SAVE, -8
+
+#endif
+
+
+
+/* Block the current thread saving all integer non volatile registers and
+ * start a new thread.
+ */
+#if 0
+.if 0
+#endif
+void *qt_blocki (void *helper, void *a0, void *a1, void *newthread);
+asm void *qt_blocki (void *helper, void *a0, void *a1, void *newthread)
+{
+#if 0
+.endif
+#endif
+
+#if 0
+qt_blocki:
+_qt_blocki:
+#endif
+/* prolog code */
+ stwu r1,-BLOCKI_FSIZE(r1) /* allocate the stack frame */
+ mflr r0 /* return addr in r0 */
+ mfcr r11 /* CR in r11 */
+ stw r0,LR_SAVE+BLOCKI_FSIZE(r1) /* save return addr in the stack */
+ stw r11,CR_SAVE+BLOCKI_FSIZE(r1) /* save CR in the stack */
+ stmw r13,GPR_SAVE_13(r1) /* save non-volatile reg */
+
+/* call helper(qt_t *old, void *a0, void *a1) */
+ mtlr r3 /* "helper" addr in the link reg */
+ mr r3,r1 /* current thread (i.e. the SP) in arg "old" */
+ mr r1,r6 /* swap to the new thread (i.e. to its SP) */
+ blrl /* jump to "helper" */
+/* the "helper" return value is returned (since r3 is not changed) */
+
+/* epilog code: return to the new thread's "qt_blocki" caller */
+ lmw r13,GPR_SAVE_13(r1) /* restore non-volatile reg */
+ lwz r0,LR_SAVE+BLOCKI_FSIZE(r1) /* recover return addr */
+ lwz r11,CR_SAVE+BLOCKI_FSIZE(r1) /* recover CR */
+ mtlr r0 /* return address in the link reg */
+ mtcr r11 /* restore CR */
+ addi r1,r1,BLOCKI_FSIZE /* free the stack frame */
+ blr /* return */
+
+#if 0
+.if 0
+#endif
+}
+#if 0
+.endif
+#endif
+
+
+
+/* Abort the current thread and start a new thread.
+ */
+#if 0
+.if 0
+#endif
+void qt_abort (void *helper, void *a0, void *a1, void *newthread);
+asm void qt_abort (void *helper, void *a0, void *a1, void *newthread)
+{
+#if 0
+.endif
+#endif
+
+#if 0
+qt_abort:
+_qt_abort:
+#endif
+/* prolog code */
+/* there is no prolog. It will never come back */
+
+/* call helper(qt_t *old, void *a0, void *a1) */
+ mtlr r3 /* "helper" addr in the link reg */
+ mr r1,r6 /* swap to the new thread (i.e. to its SP) */
+/* we don't need to set "old", we can pass just garbage. Actually, since r3
+ is not changed, "old" is set to "helper" (don't care) */
+ blrl /* call "helper" */
+/* the "helper" return value is returned (since r3 is not changed) */
+
+/* epilog code: return to the new thread's "qt_blocki" caller */
+ lmw r13,GPR_SAVE_13(r1) /* restore non-volatile reg */
+ lwz r0,LR_SAVE+BLOCKI_FSIZE(r1) /* recover return addr */
+ lwz r11,CR_SAVE+BLOCKI_FSIZE(r1) /* recover CR */
+ mtlr r0 /* return address in the link reg */
+ mtcr r11 /* restore CR */
+ addi r1,r1,BLOCKI_FSIZE /* free the stack frame */
+ blr /* return */
+
+#if 0
+.if 0
+#endif
+}
+#if 0
+.endif
+#endif
+
+
+
+/* Block the current thread saving all non volatile registers and start
+ * a new thread.
+ */
+#if 0
+.if 0
+#endif
+void *qt_block (void *helper, void *a0, void *a1, void *newthread);
+asm void *qt_block (void *helper, void *a0, void *a1, void *newthread)
+{
+#if 0
+.endif
+#endif
+
+# if 0
+qt_block:
+_qt_block:
+#endif
+/* prolog code */
+ stwu r1,-BLOCK_FSIZE(r1) /* allocate the stack frame */
+ mflr r0 /* return addr in r0 */
+ stw r0,LR_SAVE+BLOCK_FSIZE(r1) /* save return addr in the stack */
+
+/* save non-volatile fp reg */
+ stfd f31,FPR_SAVE_31(r1)
+ stfd f30,FPR_SAVE_30(r1)
+ stfd f29,FPR_SAVE_29(r1)
+ stfd f28,FPR_SAVE_28(r1)
+ stfd f27,FPR_SAVE_27(r1)
+ stfd f26,FPR_SAVE_26(r1)
+ stfd f25,FPR_SAVE_25(r1)
+ stfd f24,FPR_SAVE_24(r1)
+ stfd f23,FPR_SAVE_23(r1)
+ stfd f22,FPR_SAVE_22(r1)
+ stfd f21,FPR_SAVE_21(r1)
+ stfd f20,FPR_SAVE_20(r1)
+ stfd f19,FPR_SAVE_19(r1)
+ stfd f18,FPR_SAVE_18(r1)
+ stfd f17,FPR_SAVE_17(r1)
+ stfd f16,FPR_SAVE_16(r1)
+ stfd f15,FPR_SAVE_15(r1)
+ stfd f14,FPR_SAVE_14(r1)
+/* block the thread */
+ bl qt_blocki
+/* the thread is going to be resumed */
+/* restore non-volatile fp reg */
+ lfd f31,FPR_SAVE_31(r1)
+ lfd f30,FPR_SAVE_30(r1)
+ lfd f29,FPR_SAVE_29(r1)
+ lfd f28,FPR_SAVE_28(r1)
+ lfd f27,FPR_SAVE_27(r1)
+ lfd f26,FPR_SAVE_26(r1)
+ lfd f25,FPR_SAVE_25(r1)
+ lfd f24,FPR_SAVE_24(r1)
+ lfd f23,FPR_SAVE_23(r1)
+ lfd f22,FPR_SAVE_22(r1)
+ lfd f21,FPR_SAVE_21(r1)
+ lfd f20,FPR_SAVE_20(r1)
+ lfd f19,FPR_SAVE_19(r1)
+ lfd f18,FPR_SAVE_18(r1)
+ lfd f17,FPR_SAVE_17(r1)
+ lfd f16,FPR_SAVE_16(r1)
+ lfd f15,FPR_SAVE_15(r1)
+ lfd f14,FPR_SAVE_14(r1)
+
+ lwz r0,LR_SAVE+BLOCK_FSIZE(r1) /* recover return addr */
+ mtlr r0 /* return address in the link reg */
+ addi r1,r1,BLOCK_FSIZE /* free the stack frame */
+ blr /* return */
+
+#if 0
+.if 0
+#endif
+}
+#if 0
+.endif
+#endif
+
+
+
+/* Start a single argument thread using parameters preloaded in the stack
+ * during thread initialization (see comments on stack initialization in the
+ * heather file).
+ *
+ * Executes:
+ *
+ * only(u, t, userf);
+ */
+#if 0
+.if 0
+#endif
+void qt_start(void);
+asm void qt_start(void)
+{
+#if 0
+.endif
+#endif
+
+#if 0
+qt_start:
+_qt_start:
+#endif
+ lwz r3,PAR_0(r1) /* "u" in r3 */
+ lwz r4,PAR_1(r1) /* "t" in r4 */
+ lwz r5,PAR_2(r1) /* "userf" in r5 */
+ lwz r6,PAR_3(r1) /* "only" in r6 */
+ mtlr r6 /* "only" address in the link reg */
+/* call only(u, t, userf) */
+ blrl /* jump to "only" */
+/* error if it returns */
+ b _qt_error
+/* dead code (some inline asm "wants" the epilog, or they genetare it) */
+ blr
+
+#if 0
+.if 0
+#endif
+}
+#if 0
+.endif
+#endif
+
+
+
+/* Start a variant argument thread using parameters preloaded in the stack
+ * during thread initialization (see comments on stack initialization in the
+ * heather file).
+ *
+ * Executes:
+ *
+ * startup(t);
+ * userf_return = userf(...);
+ * cleanup(pt, userf_return);
+ *
+
+
+ ***** Stack layout on start *****
+
+
+ backchain -> STACK BOTTOM (higher address)
+ +==========================+
+ backchain - 4 -> | |
+ + LOCAL VARIABLES AREA +
+ ..............
+ + +
+ | |
+ +--------------------------+
+ | |
+ + ALIGNMEBNT PAD +
+ ..............
+ + (if needed) +
+ | |
+ +--------------------------+
+ | | arg(n)
+ + +
+ | |
+ + VARIABLE ARGUMENT LIST +
+ ..............
+ + for userf call +
+ SP + PAR(5) -> | | arg(1)
+ + +
+ SP + PAR(4) -> | | arg(0)
+ +--------------------------+
+ SP + PAR(3) -> | | cleanup par
+ + +
+ SP + PAR(2) -> | | userf par
+ + PARAMETER AREA +
+ SP + PAR(1) -> | | startup par
+ + +
+ SP + PAR(0) -> | | t par
+ +--------------------------+
+ | |
+ + LINKAGE AREA +
+ SP -> | |
+ +==========================+
+ STACK TOP (lower address)
+
+ Stack grows down
+ |
+ V
+
+
+
+ ***** Stack layout before call userf *****
+
+
+ backchain -> STACK BOTTOM (higher address)
+ +==========================+
+ backchain - 4 -> | |
+ + LOCAL VARIABLES AREA +
+ ..............
+ + +
+ | |
+ +--------------------------+
+ | |
+ + ALIGNMEBNT PAD +
+ ..............
+ + (if needed) +
+ | |
+ +--------------------------+
+ | | arg(n)
+ + +
+ | |
+ + VARIABLE ARGUMENT LIST +
+ ..............
+ + for userf call +
+ SP + PAR(1) -> | | arg(1)
+ + +
+ SP + PAR(0) -> | | arg(0)
+ +--------------------------+
+ | |
+ + LINKAGE AREA +
+ SP -> | |
+ +==========================+
+ STACK TOP (lower address)
+
+ Stack grows down
+ |
+ V
+
+
+ * To call "userf(...)", the argument list must be adiacent to the linkage
+ * area. Instead of copy the argument list, we move back the linkage area
+ * (actually, we just increase the SP and copy the backchain). "t" and
+ * "cleanup" are saved in a local variable area in order to call
+ * cleanup(pt, userf_return).
+
+*/
+
+
+#if 0
+.if 0
+#endif
+void qt_vstart(void);
+asm void qt_vstart(void)
+{
+#if 0
+.endif
+#endif
+
+#if 0
+qt_vstart:
+_qt_vstart:
+#endif
+/* NOTICE: the callee routines could save parameter registers in the caller's
+ * stack parameter area. We put "t" in PAR(0) in such a way, if startup(t)
+ * will save "t", it will be saved on the same location thus not delething
+ * any other parameter.
+ */
+
+/* since we will move back the linckage area (to make it adiacent to the
+ * parameter list), we need to save "t" and "cleanup". We have made room for
+ * this on the bottom of the stack frame. */
+
+/* save parameters in the local variable area */
+ lwz r11,0(r1) /* get the backchain */
+ lwz r3,P_T(r1)
+ lwz r4,P_CLEANUP(r1)
+ stw r3,P_T_SAVE(r11) /* save "pt" */
+ stw r4,P_CLEANUP_SAVE(r11) /* save "cleanup" */
+
+/* call startup(t) */
+ lwz r5,P_STARTUP(r1)
+ mtlr r5
+ blrl /* call "startup" */
+
+/* call userf(...) */
+ lwz r11,0(r1) /* reload backchain (r11 is volatile) */
+ lwz r4,P_USERF(r1) /* load "userf" */
+ mtlr r4
+
+ /* first eight parameter of the variant list must be copyed in
+ * GPR3-GPR10. There is a four places offset due to "t", "startup",
+ * userf" and "cleanup" */
+
+ lwz r3,PAR_4(r1)
+ lwz r4,PAR_5(r1)
+ lwz r5,PAR_6(r1)
+ lwz r6,PAR_7(r1)
+ lwz r7,PAR_8(r1)
+ lwz r8,PAR_9(r1)
+ lwz r9,PAR_10(r1)
+ lwz r10,PAR_11(r1)
+
+
+ /* move the linkage area to be adiacent to the argument list */
+ stw r11,VARGS_BKOFF(r1) /* copy backchain */
+ addi r1,r1,VARGS_BKOFF /* move back the stack */
+
+ blrl /* call "userf" */
+
+/* call qt_cleanup(void *pt, void *vuserf_return) */
+ lwz r11,0(r1) /* reload backchain (r11 is volatile) */
+
+ mr r4,r3 /* push "userf" return as 2nd parameter */
+ lwz r3,P_T_SAVE(r11) /* reload "pt" */
+ lwz r5,P_CLEANUP_SAVE(r11) /* reload "cleanup" */
+ mtlr r5
+ blrl
+ b _qt_error
+/* dead code (some inline asm "wanst" the epilog, or they genetare it) */
+ blr
+
+#if 0
+.if 0
+#endif
+}
+#if 0
+.endif
+#endif
+
diff --git a/ext/systemc/src/sysc/qt/md/powerpc_mach_b.s b/ext/systemc/src/sysc/qt/md/powerpc_mach_b.s
new file mode 100644
index 000000000..f0fd23fcb
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/powerpc_mach_b.s
@@ -0,0 +1,290 @@
+/* speed test for basic CPU operations */
+
+
+/* Marco Bucci <marco.bucci@inwind.it> */
+
+/* This code was developed with the Code Warrior integrate ppc assembler.
+ * Macros are use to hide illegal constructs whether you are using a
+ * "normal" assembler or the "C integrated" assembler.
+ */
+
+#if 0
+
+
+ .text
+ .align 4
+
+ .globl b_call_reg
+ .globl _b_call_reg
+ .globl b_call_imm
+ .globl _b_call_imm
+ .globl b_add
+ .globl _b_add
+ .globl b_load
+ .globl _b_load
+
+.set fsize, 64
+.set lrsave, 8
+
+#else
+
+#define fsize 64
+#define lrsave 8
+
+#endif
+
+
+
+
+#if 0
+.if 0
+#endif
+asm void b_null(void)
+{
+#if 0
+.endif
+#endif
+
+#if 0
+b_null:
+#endif
+
+ blr
+
+#if 0
+.if 0
+#endif
+}
+#if 0
+.endif
+#endif
+
+
+/* actually the same as the following. How to get "b_null" address?
+ * I didnt find the right sintax or the right way.
+ * I should take the current PC, then the difference to "b_null"
+ * (making the difference beween the labels), perform the sum and go?!
+ */
+#if 0
+.if 0
+#endif
+asm void b_call_reg(long n)
+{
+#if 0
+.endif
+#endif
+
+#if 0
+b_call_reg:
+_b_call_reg:
+#endif
+
+ mflr r0
+ stw r31,-4(r1)
+ stw r30,-8(r1)
+ stw r0,lrsave(r1)
+ stwu r1,-fsize(r1)
+ mr r30,r3
+ li r31,0
+
+ b L1
+L0:
+ bl b_null
+ bl b_null
+ bl b_null
+ bl b_null
+ bl b_null
+
+ addi r31,r31,5
+L1:
+ cmpw r31,r30
+ blt L0
+
+
+ lwz r0,lrsave+fsize(r1)
+ mtlr r0
+ lwz r31,-4+fsize(r1)
+ lwz r30,-8+fsize(r1)
+ addi r1,r1,fsize
+ blr
+
+#if 0
+.if 0
+#endif
+}
+#if 0
+.endif
+#endif
+
+
+
+
+#if 0
+.if 0
+#endif
+asm void b_call_imm(long n)
+{
+#if 0
+.endif
+#endif
+
+#if 0
+b_call_imm:
+_b_call_imm:
+#endif
+
+ mflr r0
+ stw r31,-4(r1)
+ stw r30,-8(r1)
+ stw r0,lrsave(r1)
+ stwu r1,-fsize(r1)
+ mr r30,r3
+ li r31,0
+
+ b L3
+L2:
+ bl b_null
+ bl b_null
+ bl b_null
+ bl b_null
+ bl b_null
+
+ addi r31,r31,5
+L3:
+ cmpw r31,r30
+ blt L2
+
+
+ lwz r0,lrsave+fsize(r1)
+ mtlr r0
+ lwz r31,-4+fsize(r1)
+ lwz r30,-8+fsize(r1)
+ addi r1,r1,fsize
+ blr
+
+#if 0
+.if 0
+#endif
+}
+#if 0
+.endif
+#endif
+
+
+
+#if 0
+.if 0
+#endif
+asm void b_add(long n)
+{
+#if 0
+.endif
+#endif
+
+#if 0
+b_add:
+_b_add:
+#endif
+
+ mflr r0
+ stw r31,-4(r1)
+ stw r30,-8(r1)
+ stw r0,lrsave(r1)
+ stwu r1,-fsize(r1)
+ mr r30,r3
+ li r31,0
+
+ b L5
+L4:
+ addi r3,r3,5
+ addi r4,r4,5
+ addi r5,r5,5
+ addi r6,r6,5
+ addi r7,r7,5
+
+ addi r3,r3,5
+ addi r4,r4,5
+ addi r5,r5,5
+ addi r6,r6,5
+ addi r7,r7,5
+
+ addi r31,r31,10
+L5:
+ cmpw r31,r30
+ blt L4
+
+
+ lwz r0,lrsave+fsize(r1)
+ mtlr r0
+ lwz r31,-4+fsize(r1)
+ lwz r30,-8+fsize(r1)
+ addi r1,r1,fsize
+ blr
+
+#if 0
+.if 0
+#endif
+}
+#if 0
+.endif
+#endif
+
+
+
+#if 0
+.if 0
+#endif
+asm void b_load(long n)
+{
+#if 0
+.endif
+#endif
+
+#if 0
+b_load:
+_b_load:
+#endif
+
+ mflr r0
+ stw r31,-4(r1)
+ stw r30,-8(r1)
+ stw r0,lrsave(r1)
+ stwu r1,-fsize(r1)
+ mr r30,r3
+ li r31,0
+
+ b L7
+L6:
+ lwz r3,4(r1)
+ lwz r4,8(r1)
+ lwz r5,12(r1)
+ lwz r6,16(r1)
+ lwz r7,20(r1)
+
+ lwz r3,24(r1)
+ lwz r4,28(r1)
+ lwz r5,32(r1)
+ lwz r6,36(r1)
+ lwz r7,40(r1)
+
+
+ addi r31,r31,10
+L7:
+ cmpw r31,r30
+ blt L6
+
+
+ lwz r0,lrsave+fsize(r1)
+ mtlr r0
+ lwz r31,-4+fsize(r1)
+ lwz r30,-8+fsize(r1)
+ addi r1,r1,fsize
+ blr
+
+#if 0
+.if 0
+#endif
+}
+#if 0
+.endif
+#endif
diff --git a/ext/systemc/src/sysc/qt/md/powerpc_sys5.h b/ext/systemc/src/sysc/qt/md/powerpc_sys5.h
new file mode 100644
index 000000000..8c0730704
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/powerpc_sys5.h
@@ -0,0 +1,566 @@
+/*
+ + * QuickThreads -- Threads-building toolkit.
+ + * Copyright (c) 1993 by David Keppel
+ + *
+ + * Permission to use, copy, modify and distribute this software and
+ + * its documentation for any purpose and without fee is hereby
+ + * granted, provided that the above copyright notice and this notice
+ + * appear in all copies. This software is provided as a
+ + * proof-of-concept and for demonstration purposes; there is no
+ + * representation about the suitability of this software for any
+ + * purpose.
+ + *
+
+ + * PowerPC-Sys5 thread switching module.
+ + *
+ + * This software is largely based on the original PowerPC-Linux porting
+ + * developed by Ken Aaker <kenaaker@silverbacksystems.com>
+ + *
+ + * Marco Bucci <marco.bucci@inwind.it>
+ + * December 2002
+ + *
+ + */
+
+
+#ifndef QUICKTHREADS_POWERPC_H
+#define QUICKTHREADS_POWERPC_H
+
+
+/*****************************************************************************
+ *
+ * DESCRIPTION
+ *
+ * This is the QuickThreads switching module implementation for PowerPC
+ * running under System V ABI (Application Binary Interface) [2]. It was
+ * developed by porting the MacOS X version and tested under LinuxPPC.
+ *
+ * Notice that this is not the same than the PowerPC Mach ABI used by MacOSX
+ * [1].
+ *
+ * IMPLEMENTATION NOTES
+ *
+ * 1) Porting on System V ABI
+ * Excluding the variant argument calling convention, Mach and System V ABI
+ * are enough similar and it could be possible to use some simple macro, to
+ * adapt the code for both the ABIs. Actually, the only relevant difference
+ * is in the linkage area structure and in the position where the Link and
+ * the Condition registers are saved. As to the calling conventions, there
+ * are differences with floating points argument passing and with variant
+ * argument lists. Notice that, on Mach, the caller's stack frame allocates
+ * space to hold all arguments ([1] p.51), while on System V, the caller's
+ * stack frame allocates space to hold just the arguments that don't fit into
+ * registers ([2] p.3.18).
+ *
+ * 2) Variant argument list implementation
+ * Variant argument calling on a RISC machine is not easy to implement since
+ * parameters are passed via registers instead of via stack. In a general
+ * variant argument implementation, the caller's stack must map the whole
+ * parameter list following the rules related to the use of the GPR and FPR
+ * parameter registers and the stack alignment ([2] p.3-21).
+ * This implementation is quite simple and not general. It works under the
+ * hypothesis that arguments are 4-bytes aligned integers.
+ *
+ * 3) This heather file organisation
+ * I preferred to not make confusion between macros that are needed (i.e.
+ * directly used) by QuickThreads and internal "implementation" macros. You
+ * will find QuickThreds macros in the end of this header. Sometime they just
+ * refer to an analogous "internal" macro. On the top, there are the macros
+ * that I used to make more clean (I hope) the implementation. I could include
+ * some system heather (as to stack layout definitions, prologs and epilogs,
+ * etc.), but I preferred to have a self-contained heather in order to make
+ * all more clear for mantaining and for possible porting on another ABI.
+ *
+ *
+ * REFERENCES
+ *
+ * [1] - Mach-O Runtime Architecture
+ * Runtime Concepts and Conventions for Mac OS X Programs
+ * Preliminary July 2002
+ *
+ * [2] - SYSTEM V APPLICATION BINARY INTERFACE
+ * PowerPC Processor Supplement
+ * September 1995
+ *
+
+ *****************************************************************************/
+
+/*****************************************************************************
+ *
+ * PowerPC System V Stack frame (see [2])
+ *
+
+ ................
+ + +
+ | |
+ +--------------------------+
+ | | Caller's LR
+ + CALLER'S LINKAGE AREA +
+ backchain -> | | Caller's backchain
+ +==========================+
+ | | FPR31
+ + FPR SAVE AREA +
+ ..............
+ + +
+ | | FPRn
+ +--------------------------+
+ | | GPR31
+ + GPR SAVE AREA +
+ ..............
+ + +
+ | | GPRn
+ +--------------------------+
+ | |
+ + ALIGNMEBNT PAD +
+ ..............
+ + (if needed) +
+ | |
+ +--------------------------+
+ | CR SAVE |
+ +--------------------------+
+ | |
+ + LOCAL VARIABLES AREA +
+ ..............
+ + +
+ | |
+ +--------------------------+
+ | | PAR(n-7)
+ + +
+ | |
+ + PARAMETER AREA +
+ ..............
+ + for FUTURE call +
+ | | PAR(9)
+ + +
+ SP + 8 -> | | PAR(8)
+ +--------------------------+
+ SP + 4 -> | | LR callee-save for FUTURE call
+ + LINKAGE AREA +
+ SP -> | | backchain
+ +==========================+
+ STACK TOP (lower address)
+
+ Stack grows down
+ |
+ V
+
+
+ * NOTE:
+ *
+ * 1) In this figure parameter are supposed to be integer 4-bytes aligned and
+ * are numbered 0, 1, 2,... n.
+ *
+ * 2) Parameter are allocated in the CALLER's parameter area. This area must
+ * be large enough to hold all parameters that cannot fit in registers (no
+ * more parameter registers are available);
+ *
+ * 3) The callee saves LR in the caller's linkage area. CR as all other
+ * callee's state are saved in its own stack frame.
+ *
+
+ *****************************************************************************/
+
+
+/*****************************************************************************
+ *
+ * Stack initialization for a single argument thread
+ *
+
+
+ top + QUICKTHREADS_STKBASE -> STACK BOTTOM (higher address)
+ +==========================+
+ | |
+ + +
+ ..............
+ + +
+ | |
+ +--------------------------+
+ top + QUICKTHREADS_ONLY_INDEX * 4 -> | only param | PAR(3)
+ + +
+ top + QUICKTHREADS_USER_INDEX * 4 -> | userf param | PAR(2)
+ + +
+ top + QUICKTHREADS_ARGT_INDEX * 4 -> | t param | PAR(1)
+ + +
+ top + QUICKTHREADS_ARGU_INDEX * 4 -> | u param | PAR(0)
+ +--------------------------+
+ top + QUICKTHREADS_RETURN_INDEX * 4 -> | qt_start | LR save
+ + +
+ top + QUICKTHREADS_BLOCKI_FRAME_SIZE -> | top + QUICKTHREADS_STKBASE | backchain
+ +==========================+
+ | |
+ + +
+ ..............
+ + +
+ | |
+ +--------------------------+
+ | |
+ + +
+ top -> |top + QUICKTHREADS_BLOCKI_FRAME_SIZE| backchain
+ +==========================+
+ STACK TOP (lower address)
+
+ Stack grows down
+ |
+ V
+
+ *****************************************************************************
+ *
+ * Stack initialization for a variant argument thread
+ *
+
+ bottom -> STACK BOTTOM (higher address)
+ +==========================+
+ | |
+ + +
+ ..............
+ + +
+ top + QUICKTHREADS_VSTKBASE -> | arg(0) | PAR(4)
+ +--------------------------+
+ top + QUICKTHREADS_CLEANUP_INDEX * 4 -> | cleanup param | PAR(3)
+ + +
+ top + QUICKTHREADS_USER_INDEX * 4 -> | userf param | PAR(2)
+ + +
+ top + QUICKTHREADS_VSTARTUP_INDEX * 4 ->| startup param | PAR(1)
+ + +
+ top + QUICKTHREADS_ARGT_INDEX * 4 -> | t param | PAR(0)
+ +--------------------------+
+ top + QUICKTHREADS_RETURN_INDEX * 4 -> | qt_start | LR save
+ + +
+ top + QUICKTHREADS_BLOCKI_FRAME_SIZE -> | top + QUICKTHREADS_STKBASE | backchain
+ +==========================+
+ | |
+ + +
+ ..............
+ + +
+ | |
+ +--------------------------+
+ | |
+ + +
+ top -> |top + QUICKTHREADS_BLOCKI_FRAME_SIZE| backchain
+ +==========================+
+ STACK TOP (lower address)
+
+ Stack grows down
+ |
+ V
+
+* NOTE:
+*
+* Parameters are passed to "qt_start" or to "qt_vstart" putting them into
+* the stack frames of "qt_start" or "qt_vstart" themselves. This not a
+* conventional parameter passing because parameters should be put into the
+* caller's stack, not into the callee's one. Actually we must consider
+* that as a preload of the parameter area that "qt_start" or "qt_vstart"
+* will use for their own calls.
+* Be aware of the fact that, during a call, the caller's parameter area is,
+* in a certain sense, volatile. In facts, the callee can save parameter
+* registers on the caller's parameter area.
+*
+ *****************************************************************************/
+
+
+/*****************************************************************************
+
+ Define PowerPC System V related macros
+
+ *****************************************************************************/
+
+
+
+typedef unsigned long PPC_W;
+
+/* Stack pointer must always be a multiple of 16 */
+#define PPC_STACK_INCR 16
+#define PPC_ROUND_STACK(length) \
+ (((length)+PPC_STACK_INCR-1) & ~(PPC_STACK_INCR-1))
+
+
+#define PPC_LINKAGE_AREA 8
+#define PPC_LR_SAVE 4
+
+#define PPC_PARAM_AREA(n) (4*(n))
+
+#define PPC_GPR_SAVE_AREA (4*19) /* GPR13-GPR31 must be saved */
+#define PPC_FPR_SAVE_AREA (8*18) /* FPR14-FPR31 must be saved */
+
+/* Define parameter offset on the stack.
+ * NOTICE: Parameters are numbered 0, 1, ..., n.
+*/
+#define PPC_PAR(i) (PPC_LINKAGE_AREA+(i)*4)
+
+/*****************************************************************************
+
+ Define stack frames
+
+ *****************************************************************************/
+
+
+/* Define the "qt_blocki" and "qt_abort" stack frame. We use the same stack
+ * frame for both.
+ *
+
+ top + S ->
+ +==========================+
+ top + S - 4 -> | | GPR31
+ + GPR SAVE AREA +
+ ..............
+ + +
+ top + S - 19 * 4 -> | | GPR13
+ +--------------------------+
+ | |
+ + ALIGNMEBNT PAD +
+ ..............
+ + (if needed) +
+ | |
+ +--------------------------+
+ top + 8 -> | CR SAVE |
+ +--------------------------+
+ | |
+ + LINKAGE AREA +
+ top -> | |
+ +==========================+
+ */
+
+#define QUICKTHREADS_BLOCKI_FRAME_SIZE \
+ PPC_ROUND_STACK(PPC_LINKAGE_AREA+4+PPC_GPR_SAVE_AREA)
+
+#define QUICKTHREADS_BLOCKI_CR_SAVE 8
+
+/* Offset to the base of the GPR save area. Save from GPR13 to GPR31
+ * increasing address.
+ */
+#define QUICKTHREADS_BLOCKI_GPR_SAVE(i) (QUICKTHREADS_BLOCKI_FRAME_SIZE-4+(i-31)*4)
+
+
+
+/* Define the "qt_block" stack frame. Notice that since "qt_black" calls
+ * "qt_blocki", GPR registers are saved into "qt_blocki" stack frame.
+ *
+
+ top + S ->
+ +==========================+
+ top + S - 8 -> | | FPR31
+ + FPR SAVE AREA +
+ ..............
+ + +
+ top + S - 18 * 8 -> | | FPR14
+ +--------------------------+
+ | |
+ + ALIGNMEBNT PAD +
+ ..............
+ + (if needed) +
+ | |
+ +--------------------------+
+ | |
+ + LINKAGE AREA +
+ top -> | |
+ +==========================+
+ */
+
+#define QUICKTHREADS_BLOCK_FRAME_SIZE \
+ PPC_ROUND_STACK(PPC_LINKAGE_AREA+PPC_FPR_SAVE_AREA)
+
+/* Offset to the location where registers are saved.
+ */
+#define QUICKTHREADS_BLOCK_FPR_SAVE(i) (QUICKTHREADS_BLOCK_FRAME_SIZE-8+(i-31)*8)
+
+
+/* Define the "qt_start" frame size. It consists just of the linkage area and
+ * the parameter area.
+ *
+
+ +==========================+
+ | |
+ + ALIGNMEBNT PAD +
+ ..............
+ + (if needed) +
+ | |
+ +--------------------------+
+ | | only par
+ + +
+ | | userf par
+ + PARAMETER AREA +
+ | | t par
+ + +
+ top + 8 -> | | u par
+ +--------------------------+
+ | |
+ + LINKAGE AREA +
+ top -> | |
+ +==========================+
+
+ */
+#define QUICKTHREADS_START_FRAME_SIZE PPC_ROUND_STACK(PPC_LINKAGE_AREA+PPC_PARAM_AREA(4))
+
+
+
+/* Define the "qt_vstart" frame. It consists of the linkage area, the fix parameter
+ * area, the variant argument list and a local variable area used in "qt_vstart"
+ * implementation.
+ *
+
+ backchain ->
+ +==========================+
+ backchain - 4 -> | |
+ + LOCAL VARIABLES AREA +
+ ..............
+ + +
+ | |
+ +--------------------------+
+ | |
+ + ALIGNMEBNT PAD +
+ ..............
+ + (if needed) +
+ | |
+ +--------------------------+
+ | | arg(n)
+ + +
+ | |
+ + VARIABLE ARGUMENT LIST +
+ ..............
+ + for userf call +
+ | | arg(1)
+ + +
+ top + 8 + 16 -> | | arg(0)
+ +--------------------------+
+ | | cleanup par
+ + +
+ | | userf par
+ + PARAMETER AREA +
+ | | startup par
+ + +
+ top + 8 -> | | t par
+ +--------------------------+
+ | |
+ + LINKAGE AREA +
+ top -> | |
+ +==========================+
+
+ */
+#define QUICKTHREADS_VARGS_LOCAL_AREA (4*4) /* local variable area */
+
+/* The offset the stack will be moved back before to call "userf(...)".
+ * The linckage area must be moved to be adiacent to the part of the variant
+ * argument list that is in the stack. Notice that, since the first 8
+ * parameters are passed via registers, the offset is equal to the size of
+ * 4+8 parameters. */
+#define QUICKTHREADS_VARGS_BKOFF PPC_PARAM_AREA(4+8)
+
+#define QUICKTHREADS_VSTART_FRAME_SIZE(varbytes) \
+ PPC_ROUND_STACK(PPC_LINKAGE_AREA+QUICKTHREADS_VARGS_BKOFF+(varbytes)+ \
+ QUICKTHREADS_VARGS_LOCAL_AREA)
+
+/* Offset to the base of the varian argument list */
+#define QUICKTHREADS_VSTART_LIST_BASE (PPC_LINKAGE_AREA+PPC_PARAM_AREA(4))
+
+
+/* Notice that qt_start and qt_vstart have no parameters, actually their
+ * parameters are written in their stack frame during thread initialization
+ */
+extern void qt_start(void);
+extern void qt_vstart(void);
+
+
+
+/* Offset (in words) of the location where the block routine saves its return
+ * address (i.e. LR). SP points the top of the block routine stack and,
+ * following ppc calling conventions, the return address is saved in the
+ * previous (caller's) stack frame.
+ */
+#define QUICKTHREADS_RETURN_INDEX ((QUICKTHREADS_BLOCKI_FRAME_SIZE+PPC_LR_SAVE)/sizeof(PPC_W))
+
+/* static variable used to get the stack bottom in "VARGS" initialization */
+static void *qt_sp_bottom_save;
+
+#define QUICKTHREADS_ARG_INDEX(i) ((QUICKTHREADS_BLOCKI_FRAME_SIZE+PPC_PAR(i))/sizeof(PPC_W))
+
+/*****************************************************************************
+
+ QuickThreads needed definitions
+
+ *****************************************************************************/
+
+
+#define QUICKTHREADS_GROW_DOWN
+#define QUICKTHREADS_STKALIGN PPC_STACK_INCR
+typedef PPC_W qt_word_t;
+
+
+/* This macro is used by "QUICKTHREADS_ARGS" to initialize a single argument thread.
+ * - set "qt_start" as the "qt_block" or "qt_blocki" return address;
+ * - set the top of the stack backchain;
+ * - set the next backchain (not needed, but just to be "clean").
+ */
+#define QUICKTHREADS_ARGS_MD(sp) \
+ (QUICKTHREADS_SPUT (sp, QUICKTHREADS_RETURN_INDEX, qt_start), \
+ QUICKTHREADS_SPUT (sp, 0, sp+QUICKTHREADS_BLOCKI_FRAME_SIZE), \
+ QUICKTHREADS_SPUT (sp, QUICKTHREADS_BLOCKI_FRAME_SIZE/sizeof(PPC_W), \
+ sp+QUICKTHREADS_BLOCKI_FRAME_SIZE+QUICKTHREADS_START_FRAME_SIZE))
+
+
+/* This macro is used by "QUICKTHREADS_VARGS" to initialize a variant argument thread.
+ * It returns the pointer to the top of the argument list.
+ * We also use it to get the stack bottom via a static variable. This is a bit
+ * "dirty", it could be better to do it in "qt_vargs", but we don't want change
+ * anything out of this file.
+ * We need the stack bottom to allocate a local variable area used by
+ * "qt_vstart".
+ */
+#define QUICKTHREADS_VARGS_MD0(sp, varbytes) \
+ ((qt_sp_bottom_save = sp), \
+ ((qt_t *)(((char *)(sp)) - \
+ (QUICKTHREADS_VSTART_FRAME_SIZE(varbytes)-QUICKTHREADS_VSTART_LIST_BASE))))
+
+
+/* This macro is used by "QUICKTHREADS_VARGS" to initialize a variant argument thread.
+ * - set "qt_start" as the "qt_block" or "qt_blocki" return address;
+ * - set the top of the stackback chain;
+ * - set the next backchain (it points the stack botton).
+ */
+#define QUICKTHREADS_VARGS_MD1(sp) \
+ (QUICKTHREADS_SPUT (sp, QUICKTHREADS_RETURN_INDEX, qt_vstart), \
+ QUICKTHREADS_SPUT (sp, 0, sp+QUICKTHREADS_BLOCKI_FRAME_SIZE), \
+ QUICKTHREADS_SPUT (sp, (QUICKTHREADS_BLOCKI_FRAME_SIZE)/sizeof(PPC_W), \
+ qt_sp_bottom_save))
+
+
+/* Activate "qt_vargs" as the initialization routine for the variant
+ * argument threads
+ */
+#define QUICKTHREADS_VARGS_DEFAULT
+
+/* Override "qt_vargs" with "qt_vargs_stdarg".
+ * On LinuxPPC "qt_vargs" doesn't work, "qt_vargs_stdarg" uses a more
+ * standard way to retrieve arguments from the variant list.
+ */
+#define QUICKTHREADS_VARGS(sp, nbytes, vargs, pt, startup, vuserf, cleanup) \
+ ((qt_t *)qt_vargs_stdarg (sp, nbytes, vargs, pt, startup, vuserf, cleanup))
+
+
+/* This macro is used by "QUICKTHREADS_ADJ(sp)" to get the stack top form the stack
+ * bottom during a single argument thread initialization.
+ * It is the space we need to allocate for a single argument thread: the stack
+ * frame for the block routine ("qt_block" or "qt_blocki") and for "qt_start".
+ */
+#define QUICKTHREADS_STKBASE \
+ (QUICKTHREADS_BLOCKI_FRAME_SIZE+QUICKTHREADS_START_FRAME_SIZE)
+
+/* This macro is used by "QUICKTHREADS_VADJ(sp)" to get the stack top from the base
+ * of the variant argument list during a variant argument thread initialization.
+ */
+#define QUICKTHREADS_VSTKBASE (QUICKTHREADS_BLOCKI_FRAME_SIZE+QUICKTHREADS_VSTART_LIST_BASE)
+
+/* The *index* (positive offset) of where to put each value. */
+
+#define QUICKTHREADS_ARGU_INDEX QUICKTHREADS_ARG_INDEX(0)
+#define QUICKTHREADS_ARGT_INDEX QUICKTHREADS_ARG_INDEX(1)
+#define QUICKTHREADS_USER_INDEX QUICKTHREADS_ARG_INDEX(2)
+#define QUICKTHREADS_ONLY_INDEX QUICKTHREADS_ARG_INDEX(3)
+
+
+#define QUICKTHREADS_VARGT_INDEX QUICKTHREADS_ARG_INDEX(0)
+#define QUICKTHREADS_VSTARTUP_INDEX QUICKTHREADS_ARG_INDEX(1)
+#define QUICKTHREADS_VUSERF_INDEX QUICKTHREADS_ARG_INDEX(2)
+#define QUICKTHREADS_VCLEANUP_INDEX QUICKTHREADS_ARG_INDEX(3)
+
+#endif /* ndef QUICKTHREADS_POWERPC_H */
+
diff --git a/ext/systemc/src/sysc/qt/md/powerpc_sys5.s b/ext/systemc/src/sysc/qt/md/powerpc_sys5.s
new file mode 100644
index 000000000..d9dc9332d
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/powerpc_sys5.s
@@ -0,0 +1,639 @@
+/* powerpc-sys5.s -- assembly support. */
+
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+
+
+ * PowerPC-System V thread switching module.
+ *
+ * This software is largely based on the original PowerPC-Linux porting
+ * developed by Ken Aaker <kenaaker@silverbacksystems.com>
+ *
+ * Marco Bucci <marco.bucci@inwind.it>
+ * December 2002
+ *
+ */
+
+
+/*
+ *
+ * PowerPC Register convections:
+ *
+ * r0 volatile
+ * r1 SP
+ * r2 system reserved
+ * r3-r4 volatile for parameter passing and function return
+ * r5-r10 volatile for parameter passing
+ * r11-r12 volatile
+ * r13-r14 non volatile registers
+ * f0 volatile
+ * f1 volatile for parameter passing and function return
+ * f2-f13 volatile for parameter passing
+ * f14-f31 non volatile
+ *
+ * cr2-cr4 non volatile
+ *
+ *
+ * See on the heather file for more documentation.
+ *
+ *
+ *
+ * IMPLEMENTATION NOTES
+ *
+ *
+ * 1) Condition register saving
+ * On most machines, the condition code register is caller-save.
+ * On the PPC, the condition code register is callee-save, so the
+ * thread context switch must preserve it.
+ *
+ *
+ * 2) Floating point registers saving
+ * On resuming a thread, floating point registers are or not restored just
+ * depending on which block routine suspended the thread (i.e. regardless
+ * whether "qt_block", "qt_blocki" or "qt_abort" is used to resume it).
+ * This behaviour is obtained by implementing "qt_block" by means af a nested
+ * call to "qt_blocki". As a result, the blocking of a thread always goes
+ * and returns through "qt_blocki and, if a thread was blocked by "qt_block",
+ * its execution resumes from the floating point restoring code on exit
+ * of "qt_block".
+ *
+ * Thanks to David Keppel that explained me this "simple" trick.
+ *
+ *
+ * 3) C languace code debugging
+ * The original version of this software was developed and debugged under
+ * MacOS X using the Metrowerks Code Warrior PPC integrated assembler.
+ * It could be still used with a C inline assembler by means of a suitable
+ * file to include it.
+ * In order to avoid "copy and paste" bugs, and make easyer the maintaining,
+ * I made the minimal changes, so you can find some strange code as:
+ *
+ * #if 0
+ * .if 0
+ * C code here
+ * .endif
+ * #endif
+ *
+ * This is just to embed some C code that is needed by the Code Warrior
+ * integrated assembler.
+ *
+ *
+ * 4) Assembly constants generation
+ * Constants used in the assembly code are generated by running
+ * the C code in the sequel (commented). It uses the C macros declared in
+ * the C heather in order to guarantee that the C interface and the assebly
+ * code are "aligned". I avoided the use of an assebler preprocessor since
+ * they are not so standard and moreover using macro espressions makes the
+ * assembly debugging more difficult.
+ *
+ *
+
+
+#include <iostream>
+#include "powerpc_sys5.h"
+
+int main()
+{
+ using namespace std;
+
+ int i;
+
+ cout << ".set LR_SAVE, " << PPC_LR_SAVE << endl;
+ cout << ".set BLOCKI_FSIZE, " << QUICKTHREADS_BLOCKI_FRAME_SIZE << endl;
+ cout << ".set BLOCKI_CR_SAVE, " << QUICKTHREADS_BLOCKI_CR_SAVE << endl;
+ cout << ".set BLOCK_FSIZE, " << QUICKTHREADS_BLOCK_FRAME_SIZE << endl;
+
+ cout << endl;
+ for(i=0; i<12; i++)
+ cout << ".set PAR_" << i << ", " << PPC_PAR(i) << endl;
+
+ cout << endl;
+ i = 13;
+ cout << ".set GPR_SAVE_" << i << ", " << QUICKTHREADS_BLOCKI_GPR_SAVE(i) << endl;
+
+ cout << endl;
+ for(i=31; i>13; i--)
+ cout << ".set FPR_SAVE_" << i << ", " << QUICKTHREADS_BLOCK_FPR_SAVE(i) << endl;
+
+ cout << endl;
+ cout << ".set VARGS_BKOFF, " << QUICKTHREADS_VARGS_BKOFF << endl;
+
+
+ cout << endl << endl << endl;
+
+ for(i=31; i>13; i--)
+ cout << "\tstfd\tf" << i << ",FPR_SAVE_" << i << "(%r1)" << endl;
+
+ cout << endl;
+ for(i=31; i>13; i--)
+ cout << "\tlfd \tf" << i << ",FPR_SAVE_" << i << "(%r1)" << endl;
+
+ cout << endl << endl << endl;
+
+
+ return 0;
+}
+
+
+
+ *
+ *
+ *
+ */
+
+
+#if 0
+
+ .text
+ .align 4
+
+ .globl qt_block
+ .globl _qt_block
+ .globl qt_blocki
+ .globl _qt_blocki
+ .globl qt_abort
+ .globl _qt_abort
+ .globl qt_start
+ .globl _qt_start
+ .globl qt_vstart
+ .globl _qt_vstart
+
+
+.set LR_SAVE, 4
+.set BLOCKI_FSIZE, 96
+.set BLOCKI_CR_SAVE, 8 /* CR is saved into the callee's stack frame */
+.set BLOCK_FSIZE, 160
+
+.set PAR_0, 8
+.set PAR_1, 12
+.set PAR_2, 16
+.set PAR_3, 20
+.set PAR_4, 24
+.set PAR_5, 28
+.set PAR_6, 32
+.set PAR_7, 36
+.set PAR_8, 40
+.set PAR_9, 44
+.set PAR_10, 48
+.set PAR_11, 52
+
+.set GPR_SAVE_13, 20
+
+.set FPR_SAVE_31, 152
+.set FPR_SAVE_30, 144
+.set FPR_SAVE_29, 136
+.set FPR_SAVE_28, 128
+.set FPR_SAVE_27, 120
+.set FPR_SAVE_26, 112
+.set FPR_SAVE_25, 104
+.set FPR_SAVE_24, 96
+.set FPR_SAVE_23, 88
+.set FPR_SAVE_22, 80
+.set FPR_SAVE_21, 72
+.set FPR_SAVE_20, 64
+.set FPR_SAVE_19, 56
+.set FPR_SAVE_18, 48
+.set FPR_SAVE_17, 40
+.set FPR_SAVE_16, 32
+.set FPR_SAVE_15, 24
+.set FPR_SAVE_14, 16
+
+
+
+
+/* various offsets used by "qt_varg" */
+.set P_T, PAR_0
+.set P_STARTUP, PAR_1
+.set P_USERF, PAR_2
+.set P_CLEANUP, PAR_3
+ /* the offset used to move back the linkage area to be adiacent to
+ * the variant argument list before calling "userf(...).
+ * Skip "t", "startup", "userf", "cleanup" and first
+ * 8 parameters (since they are passed via registers) */
+.set VARGS_BKOFF, 48
+
+ /* location where "t" and "cleanup" are saved (with respect of
+ * the stack frame base) */
+.set P_T_SAVE, -4
+.set P_CLEANUP_SAVE, -8
+
+#endif
+
+
+
+/* Block the current thread saving all integer non volatile registers and
+ * start a new thread.
+ */
+#if 0
+.if 0
+#endif
+void *qt_blocki (void *helper, void *a0, void *a1, void *newthread);
+asm void *qt_blocki (void *helper, void *a0, void *a1, void *newthread)
+{
+#if 0
+.endif
+#endif
+
+#if 0
+qt_blocki:
+_qt_blocki:
+#endif
+/* prolog code */
+ stwu %r1,-BLOCKI_FSIZE(%r1) /* allocate the stack frame */
+ mflr %r0 /* return addr in r0 */
+ mfcr %r11 /* CR in r11 */
+ stw %r0,LR_SAVE+BLOCKI_FSIZE(%r1) /* save return addr in the stack */
+ stw %r11,BLOCKI_CR_SAVE(%r1) /* save CR in the stack */
+ stmw %r13,GPR_SAVE_13(%r1) /* save non-volatile reg */
+
+/* call helper(qt_t *old, void *a0, void *a1) */
+ mtlr %r3 /* "helper" addr in the link reg */
+ mr %r3,%r1 /* current thread (i.e. the SP) in arg "old" */
+ mr %r1,%r6 /* swap to the new thread (i.e. to its SP) */
+ blrl /* jump to "helper" */
+/* the "helper" return value is returned (since r3 is not changed) */
+
+/* epilog code: return to the new thread's "qt_blocki" caller */
+ lmw %r13,GPR_SAVE_13(%r1) /* restore non-volatile reg */
+ lwz %r0,LR_SAVE+BLOCKI_FSIZE(%r1) /* recover return addr */
+ lwz %r11,BLOCKI_CR_SAVE(%r1) /* recover CR */
+ mtlr %r0 /* return address in the link reg */
+ mtcr %r11 /* restore CR */
+ addi %r1,%r1,BLOCKI_FSIZE /* free the stack frame */
+ blr /* return */
+
+#if 0
+.if 0
+#endif
+}
+#if 0
+.endif
+#endif
+
+
+
+/* Abort the current thread and start a new thread.
+ */
+#if 0
+.if 0
+#endif
+void qt_abort (void *helper, void *a0, void *a1, void *newthread);
+asm void qt_abort (void *helper, void *a0, void *a1, void *newthread)
+{
+#if 0
+.endif
+#endif
+
+#if 0
+qt_abort:
+_qt_abort:
+#endif
+/* prolog code */
+/* there is no prolog. It will never come back */
+
+/* call helper(qt_t *old, void *a0, void *a1) */
+ mtlr %r3 /* "helper" addr in the link reg */
+ mr %r1,%r6 /* swap to the new thread (i.e. to its SP) */
+/* we don't need to set "old", we can pass just garbage. Actually, since r3
+ is not changed, "old" is set to "helper" (don't care) */
+ blrl /* call "helper" */
+/* the "helper" return value is returned (since r3 is not changed) */
+
+/* epilog code: return to the new thread's "qt_blocki" caller */
+ lmw %r13,GPR_SAVE_13(%r1) /* restore non-volatile reg */
+ lwz %r0,LR_SAVE+BLOCKI_FSIZE(%r1) /* recover return addr */
+ lwz %r11,BLOCKI_CR_SAVE(%r1) /* recover CR */
+ mtlr %r0 /* return address in the link reg */
+ mtcr %r11 /* restore CR */
+ addi %r1,%r1,BLOCKI_FSIZE /* free the stack frame */
+ blr /* return */
+
+#if 0
+.if 0
+#endif
+}
+#if 0
+.endif
+#endif
+
+
+
+/* Block the current thread saving all non volatile registers and start
+ * a new thread.
+ */
+#if 0
+.if 0
+#endif
+void *qt_block (void *helper, void *a0, void *a1, void *newthread);
+asm void *qt_block (void *helper, void *a0, void *a1, void *newthread)
+{
+#if 0
+.endif
+#endif
+
+# if 0
+qt_block:
+_qt_block:
+#endif
+/* prolog code */
+ stwu %r1,-BLOCK_FSIZE(%r1) /* allocate the stack frame */
+ mflr %r0 /* return addr in r0 */
+ stw %r0,LR_SAVE+BLOCK_FSIZE(%r1) /* save return addr in the stack */
+
+/* save non-volatile fp reg */
+ stfd %f31,FPR_SAVE_31(%r1)
+ stfd %f30,FPR_SAVE_30(%r1)
+ stfd %f29,FPR_SAVE_29(%r1)
+ stfd %f28,FPR_SAVE_28(%r1)
+ stfd %f27,FPR_SAVE_27(%r1)
+ stfd %f26,FPR_SAVE_26(%r1)
+ stfd %f25,FPR_SAVE_25(%r1)
+ stfd %f24,FPR_SAVE_24(%r1)
+ stfd %f23,FPR_SAVE_23(%r1)
+ stfd %f22,FPR_SAVE_22(%r1)
+ stfd %f21,FPR_SAVE_21(%r1)
+ stfd %f20,FPR_SAVE_20(%r1)
+ stfd %f19,FPR_SAVE_19(%r1)
+ stfd %f18,FPR_SAVE_18(%r1)
+ stfd %f17,FPR_SAVE_17(%r1)
+ stfd %f16,FPR_SAVE_16(%r1)
+ stfd %f15,FPR_SAVE_15(%r1)
+ stfd %f14,FPR_SAVE_14(%r1)
+/* block the thread */
+ bl qt_blocki
+/* the thread is going to be resumed */
+/* restore non-volatile fp reg */
+ lfd %f31,FPR_SAVE_31(%r1)
+ lfd %f30,FPR_SAVE_30(%r1)
+ lfd %f29,FPR_SAVE_29(%r1)
+ lfd %f28,FPR_SAVE_28(%r1)
+ lfd %f27,FPR_SAVE_27(%r1)
+ lfd %f26,FPR_SAVE_26(%r1)
+ lfd %f25,FPR_SAVE_25(%r1)
+ lfd %f24,FPR_SAVE_24(%r1)
+ lfd %f23,FPR_SAVE_23(%r1)
+ lfd %f22,FPR_SAVE_22(%r1)
+ lfd %f21,FPR_SAVE_21(%r1)
+ lfd %f20,FPR_SAVE_20(%r1)
+ lfd %f19,FPR_SAVE_19(%r1)
+ lfd %f18,FPR_SAVE_18(%r1)
+ lfd %f17,FPR_SAVE_17(%r1)
+ lfd %f16,FPR_SAVE_16(%r1)
+ lfd %f15,FPR_SAVE_15(%r1)
+ lfd %f14,FPR_SAVE_14(%r1)
+
+ lwz %r0,LR_SAVE+BLOCK_FSIZE(%r1) /* recover return addr */
+ mtlr %r0 /* return address in the link reg */
+ addi %r1,%r1,BLOCK_FSIZE /* free the stack frame */
+ blr /* return */
+
+#if 0
+.if 0
+#endif
+}
+#if 0
+.endif
+#endif
+
+
+
+/* Start a single argument thread using parameters preloaded in the stack
+ * during thread initialization (see comments on stack initialization in the
+ * heather file).
+ *
+ * Executes:
+ *
+ * only(u, t, userf);
+ */
+#if 0
+.if 0
+#endif
+void qt_start(void);
+asm void qt_start(void)
+{
+#if 0
+.endif
+#endif
+
+#if 0
+qt_start:
+_qt_start:
+#endif
+ lwz %r3,PAR_0(%r1) /* "u" in r3 */
+ lwz %r4,PAR_1(%r1) /* "t" in r4 */
+ lwz %r5,PAR_2(%r1) /* "userf" in r5 */
+ lwz %r6,PAR_3(%r1) /* "only" in r6 */
+ mtlr %r6 /* "only" address in the link reg */
+/* call only(u, t, userf) */
+ blrl /* jump to "only" */
+/* error if it returns */
+ b qt_error
+/* dead code (some inline asm "wants" the epilog, or they genetare it) */
+ blr
+
+#if 0
+.if 0
+#endif
+}
+#if 0
+.endif
+#endif
+
+
+
+/* Start a variant argument thread using parameters preloaded in the stack
+ * during thread initialization (see comments on stack initialization in the
+ * heather file).
+ *
+ * Executes:
+ *
+ * startup(t);
+ * userf_return = userf(...);
+ * cleanup(pt, userf_return);
+ *
+
+
+ ***** Stack layout on start *****
+
+
+ backchain -> STACK BOTTOM (higher address)
+ +==========================+
+ backchain - 4 -> | |
+ + LOCAL VARIABLES AREA +
+ ..............
+ + +
+ | |
+ +--------------------------+
+ | |
+ + ALIGNMEBNT PAD +
+ ..............
+ + (if needed) +
+ | |
+ +--------------------------+
+ | | arg(n)
+ + +
+ | |
+ + VARIABLE ARGUMENT LIST +
+ ..............
+ + for userf call +
+ SP + PAR(5) -> | | arg(1)
+ + +
+ SP + PAR(4) -> | | arg(0)
+ +--------------------------+
+ SP + PAR(3) -> | | cleanup par
+ + +
+ SP + PAR(2) -> | | userf par
+ + PARAMETER AREA +
+ SP + PAR(1) -> | | startup par
+ + +
+ SP + PAR(0) -> | | t par
+ +--------------------------+
+ | |
+ + LINKAGE AREA +
+ SP -> | |
+ +==========================+
+ STACK TOP (lower address)
+
+ Stack grows down
+ |
+ V
+
+
+
+ ***** Stack layout before call userf *****
+
+
+ backchain -> STACK BOTTOM (higher address)
+ +==========================+
+ backchain - 4 -> | |
+ + LOCAL VARIABLES AREA +
+ ..............
+ + +
+ | |
+ +--------------------------+
+ | |
+ + ALIGNMEBNT PAD +
+ ..............
+ + (if needed) +
+ | |
+ +--------------------------+
+ | | arg(n)
+ + +
+ | |
+ + VARIABLE ARGUMENT LIST +
+ ..............
+ + for userf call +
+ SP + PAR(1) -> | | arg(1)
+ + +
+ SP + PAR(0) -> | | arg(0)
+ +--------------------------+
+ | |
+ + LINKAGE AREA +
+ SP -> | |
+ +==========================+
+ STACK TOP (lower address)
+
+ Stack grows down
+ |
+ V
+
+
+ * To call "userf(...)", the argument list must be adiacent to the linkage
+ * area. Instead of copy the argument list, we move back the linkage area
+ * (actually, we just increase the SP and copy the backchain). "t" and
+ * "cleanup" are saved in a local variable area in order to call
+ * cleanup(pt, userf_return).
+
+*/
+
+
+#if 0
+.if 0
+#endif
+void qt_vstart(void);
+asm void qt_vstart(void)
+{
+#if 0
+.endif
+#endif
+
+#if 0
+qt_vstart:
+_qt_vstart:
+#endif
+/* NOTICE: the callee routines could save parameter registers in the caller's
+ * stack parameter area. We put "t" in PAR(0) in such a way, if startup(t)
+ * will save "t", it will be saved on the same location thus not delething
+ * any other parameter.
+ */
+
+/* since we will move back the linckage area (to make it adiacent to the
+ * parameter list), we need to save "t" and "cleanup". We have made room for
+ * this on the bottom of the stack frame. */
+
+/* save parameters in the local variable area */
+ lwz %r11,0(%r1) /* get the backchain */
+ lwz %r3,P_T(%r1)
+ lwz %r4,P_CLEANUP(%r1)
+ stw %r3,P_T_SAVE(%r11) /* save "pt" */
+ stw %r4,P_CLEANUP_SAVE(%r11) /* save "cleanup" */
+
+/* call startup(t) */
+ lwz %r5,P_STARTUP(%r1)
+ mtlr %r5
+ blrl /* call "startup" */
+
+/* call userf(...) */
+ lwz %r11,0(%r1) /* reload backchain (r11 is volatile) */
+ lwz %r4,P_USERF(%r1) /* load "userf" */
+ mtlr %r4
+
+ /* first eight parameter of the variant list must be copyed in
+ * GPR3-GPR10. There is a four places offset due to "t", "startup",
+ * userf" and "cleanup" */
+
+ lwz %r3,PAR_4(%r1)
+ lwz %r4,PAR_5(%r1)
+ lwz %r5,PAR_6(%r1)
+ lwz %r6,PAR_7(%r1)
+ lwz %r7,PAR_8(%r1)
+ lwz %r8,PAR_9(%r1)
+ lwz %r9,PAR_10(%r1)
+ lwz %r10,PAR_11(%r1)
+
+
+ /* move the linkage area to be adiacent to the argument list */
+ stw %r11,VARGS_BKOFF(%r1) /* copy backchain */
+ addi %r1,%r1,VARGS_BKOFF /* move back the stack */
+
+ blrl /* call "userf" */
+
+/* call qt_cleanup(void *pt, void *vuserf_return) */
+ lwz %r11,0(%r1) /* reload backchain (r11 is volatile) */
+
+ mr %r4,%r3 /* push "userf" return as 2nd parameter */
+ lwz %r3,P_T_SAVE(%r11) /* reload "pt" */
+ lwz %r5,P_CLEANUP_SAVE(%r11) /* reload "cleanup" */
+ mtlr %r5
+ blrl
+ b qt_error
+/* dead code (some inline asm "wants" the epilog, or they genetare it) */
+ blr
+
+#if 0
+.if 0
+#endif
+}
+#if 0
+.endif
+#endif
+
diff --git a/ext/systemc/src/sysc/qt/md/powerpc_sys5_b.s b/ext/systemc/src/sysc/qt/md/powerpc_sys5_b.s
new file mode 100644
index 000000000..e57a20e2e
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/powerpc_sys5_b.s
@@ -0,0 +1,290 @@
+/* speed test for basic CPU operations */
+
+
+/* Marco Bucci <marco.bucci@inwind.it> */
+
+/* This code was developed with the Code Warrior integrate ppc assembler.
+ * Macros are use to hide illegal constructs whether you are using a
+ * "normal" assembler or the "C integrated" assembler.
+ */
+
+#if 0
+
+
+ .text
+ .align 4
+
+ .globl b_call_reg
+ .globl _b_call_reg
+ .globl b_call_imm
+ .globl _b_call_imm
+ .globl b_add
+ .globl _b_add
+ .globl b_load
+ .globl _b_load
+
+.set fsize, 64
+.set lrsave, 4
+
+#else
+
+#define fsize 64
+#define lrsave 4
+
+#endif
+
+
+
+
+#if 0
+.if 0
+#endif
+asm void b_null(void)
+{
+#if 0
+.endif
+#endif
+
+#if 0
+b_null:
+#endif
+
+ blr
+
+#if 0
+.if 0
+#endif
+}
+#if 0
+.endif
+#endif
+
+
+/* actually the same as the following. How to get "b_null" address?
+ * I didnt find the right sintax or the right way.
+ * I should take the current PC, then the difference to "b_null"
+ * (making the difference beween the labels), perform the sum and go?!
+ */
+#if 0
+.if 0
+#endif
+asm void b_call_reg(long n)
+{
+#if 0
+.endif
+#endif
+
+#if 0
+b_call_reg:
+_b_call_reg:
+#endif
+
+ mflr %r0
+ stw %r31,-4(%r1)
+ stw %r30,-8(%r1)
+ stw %r0,lrsave(%r1)
+ stwu %r1,-fsize(%r1)
+ mr %r30,%r3
+ li %r31,0
+
+ b L1
+L0:
+ bl b_null
+ bl b_null
+ bl b_null
+ bl b_null
+ bl b_null
+
+ addi %r31,%r31,5
+L1:
+ cmpw %r31,%r30
+ blt L0
+
+
+ lwz %r0,lrsave+fsize(%r1)
+ mtlr %r0
+ lwz %r31,-4+fsize(%r1)
+ lwz %r30,-8+fsize(%r1)
+ addi %r1,%r1,fsize
+ blr
+
+#if 0
+.if 0
+#endif
+}
+#if 0
+.endif
+#endif
+
+
+
+
+#if 0
+.if 0
+#endif
+asm void b_call_imm(long n)
+{
+#if 0
+.endif
+#endif
+
+#if 0
+b_call_imm:
+_b_call_imm:
+#endif
+
+ mflr %r0
+ stw %r31,-4(%r1)
+ stw %r30,-8(%r1)
+ stw %r0,lrsave(%r1)
+ stwu %r1,-fsize(%r1)
+ mr %r30,%r3
+ li %r31,0
+
+ b L3
+L2:
+ bl b_null
+ bl b_null
+ bl b_null
+ bl b_null
+ bl b_null
+
+ addi %r31,%r31,5
+L3:
+ cmpw %r31,%r30
+ blt L2
+
+
+ lwz %r0,lrsave+fsize(%r1)
+ mtlr %r0
+ lwz %r31,-4+fsize(%r1)
+ lwz %r30,-8+fsize(%r1)
+ addi %r1,%r1,fsize
+ blr
+
+#if 0
+.if 0
+#endif
+}
+#if 0
+.endif
+#endif
+
+
+
+#if 0
+.if 0
+#endif
+asm void b_add(long n)
+{
+#if 0
+.endif
+#endif
+
+#if 0
+b_add:
+_b_add:
+#endif
+
+ mflr %r0
+ stw %r31,-4(%r1)
+ stw %r30,-8(%r1)
+ stw %r0,lrsave(%r1)
+ stwu %r1,-fsize(%r1)
+ mr %r30,%r3
+ li %r31,0
+
+ b L5
+L4:
+ addi %r3,%r3,5
+ addi %r4,%r4,5
+ addi %r5,%r5,5
+ addi %r6,%r6,5
+ addi %r7,%r7,5
+
+ addi %r3,%r3,5
+ addi %r4,%r4,5
+ addi %r5,%r5,5
+ addi %r6,%r6,5
+ addi %r7,%r7,5
+
+ addi %r31,%r31,10
+L5:
+ cmpw %r31,%r30
+ blt L4
+
+
+ lwz %r0,lrsave+fsize(%r1)
+ mtlr %r0
+ lwz %r31,-4+fsize(%r1)
+ lwz %r30,-8+fsize(%r1)
+ addi %r1,%r1,fsize
+ blr
+
+#if 0
+.if 0
+#endif
+}
+#if 0
+.endif
+#endif
+
+
+
+#if 0
+.if 0
+#endif
+asm void b_load(long n)
+{
+#if 0
+.endif
+#endif
+
+#if 0
+b_load:
+_b_load:
+#endif
+
+ mflr %r0
+ stw %r31,-4(%r1)
+ stw %r30,-8(%r1)
+ stw %r0,lrsave(%r1)
+ stwu %r1,-fsize(%r1)
+ mr %r30,%r3
+ li %r31,0
+
+ b L7
+L6:
+ lwz %r3,4(%r1)
+ lwz %r4,8(%r1)
+ lwz %r5,12(%r1)
+ lwz %r6,16(%r1)
+ lwz %r7,20(%r1)
+
+ lwz %r3,24(%r1)
+ lwz %r4,28(%r1)
+ lwz %r5,32(%r1)
+ lwz %r6,36(%r1)
+ lwz %r7,40(%r1)
+
+
+ addi %r31,%r31,10
+L7:
+ cmpw %r31,%r30
+ blt L6
+
+
+ lwz %r0,lrsave+fsize(%r1)
+ mtlr %r0
+ lwz %r31,-4+fsize(%r1)
+ lwz %r30,-8+fsize(%r1)
+ addi %r1,%r1,fsize
+ blr
+
+#if 0
+.if 0
+#endif
+}
+#if 0
+.endif
+#endif
diff --git a/ext/systemc/src/sysc/qt/md/pthreads.Makefile b/ext/systemc/src/sysc/qt/md/pthreads.Makefile
new file mode 100644
index 000000000..f722fbe19
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/pthreads.Makefile
@@ -0,0 +1,108 @@
+# Generated automatically from Makefile.in by configure.
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = /bin/sh
+
+all:
+
+mostlyclean-noinstLIBRARIES:
+
+clean-noinstLIBRARIES:
+
+distclean-noinstLIBRARIES:
+
+maintainer-clean-noinstLIBRARIES:
+
+mostlyclean-compile:
+
+clean-compile:
+
+distclean-compile:
+
+maintainer-clean-compile:
+
+tags:
+
+ID:
+
+TAGS:
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+
+maintainer-clean-tags:
+
+distdir:
+
+info-am:
+info:
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+install-exec: install-exec-am
+
+install-data-am: install-data-local
+install-data: install-data-am
+
+install-am: all-am
+install: install-am
+uninstall-am: uninstall-local
+uninstall: uninstall-am
+all-am:
+all-redirect:
+install-strip:
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+
+maintainer-clean-generic:
+mostlyclean-am:
+
+mostlyclean:
+
+clean-am:
+
+clean:
+
+distclean-am:
+
+distclean:
+
+maintainer-clean-am:
+
+maintainer-clean:
+
+.PHONY:
+
+
+configuration:
+
+clean:
+
+install-data-local:
+
+uninstall-local:
+
diff --git a/ext/systemc/src/sysc/qt/md/solaris.README b/ext/systemc/src/sysc/qt/md/solaris.README
new file mode 100644
index 000000000..04f855c44
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/solaris.README
@@ -0,0 +1,19 @@
+Solaris 2.x is like System V (maybe it *is* System V?) and is different
+from older versions in that it uses no leading underscore for variable
+and function names. That is, the old convention was:
+
+ foo(){}
+
+got compiled as
+
+ .globl _foo
+ _foo:
+
+and is now compiled as
+
+ .globl foo
+ foo:
+
+The `config' script should fix up the older (leading underscore) versions
+of the machine-dependent files to use the newer (no leading underscore)
+calling conventions.
diff --git a/ext/systemc/src/sysc/qt/md/sparc.h b/ext/systemc/src/sysc/qt/md/sparc.h
new file mode 100644
index 000000000..edaf5325e
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/sparc.h
@@ -0,0 +1,140 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+#ifndef QUICKTHREADS_SPARC_H
+#define QUICKTHREADS_SPARC_H
+
+typedef unsigned long qt_word_t;
+
+/* Stack layout on the sparc:
+
+ non-varargs:
+
+ +---
+ | <blank space for alignment>
+ | %o7 == return address -> qt_start
+ | %i7
+ | %i6 == frame pointer -> 0 (NULL-terminated stack frame chain)
+ | %i5 -> only
+ | %i4 -> userf
+ | %i3
+ | %i2 -> pt
+ | %i1 -> pu
+ | %i0
+ | %l7
+ | %l6
+ | %l5
+ | %l4
+ | %l3
+ | %l2
+ | %l1
+ | %l0 <--- qt_t.sp
+ +---
+
+ varargs:
+
+ | :
+ | :
+ | argument list
+ | one-word aggregate return pointer
+ +---
+ | <blank space for alignment>
+ | %o7 == return address -> qt_vstart
+ | %i7
+ | %i6 == frame pointer -> 0 (NULL-terminated stack frame chain)
+ | %i5 -> startup
+ | %i4 -> userf
+ | %i3 -> cleanup
+ | %i2 -> pt
+ | %i1
+ | %i0
+ | %l7
+ | %l6
+ | %l5
+ | %l4
+ | %l3
+ | %l2
+ | %l1
+ | %l0 <--- qt_t.sp
+ +---
+
+ */
+
+
+/* What to do to start a thread running. */
+extern void qt_start (void);
+extern void qt_vstart (void);
+
+
+/* Hold 17 saved registers + 1 word for alignment. */
+#define QUICKTHREADS_STKBASE (18 * 4)
+#define QUICKTHREADS_VSTKBASE QUICKTHREADS_STKBASE
+
+
+/* Stack must be doubleword aligned. */
+#define QUICKTHREADS_STKALIGN (8) /* Doubleword aligned. */
+
+#define QUICKTHREADS_ONLY_INDEX (QUICKTHREADS_I5)
+#define QUICKTHREADS_USER_INDEX (QUICKTHREADS_I4)
+#define QUICKTHREADS_ARGT_INDEX (QUICKTHREADS_I2)
+#define QUICKTHREADS_ARGU_INDEX (QUICKTHREADS_I1)
+
+#define QUICKTHREADS_VSTARTUP_INDEX (QUICKTHREADS_I5)
+#define QUICKTHREADS_VUSERF_INDEX (QUICKTHREADS_I4)
+#define QUICKTHREADS_VCLEANUP_INDEX (QUICKTHREADS_I3)
+#define QUICKTHREADS_VARGT_INDEX (QUICKTHREADS_I2)
+
+#define QUICKTHREADS_O7 (16)
+#define QUICKTHREADS_I6 (14)
+#define QUICKTHREADS_I5 (13)
+#define QUICKTHREADS_I4 (12)
+#define QUICKTHREADS_I3 (11)
+#define QUICKTHREADS_I2 (10)
+#define QUICKTHREADS_I1 ( 9)
+
+
+/* The thread will ``return'' to the `qt_start' routine to get things
+ going. The normal return sequence takes us to QUICKTHREADS_O7+8, so we
+ pre-subtract 8. The frame pointer chain is 0-terminated to prevent
+ the trap handler from chasing off in to random memory when flushing
+ stack windows. */
+
+#define QUICKTHREADS_ARGS_MD(top) \
+ (QUICKTHREADS_SPUT ((top), QUICKTHREADS_O7, ((void *)(((int)qt_start)-8))), \
+ QUICKTHREADS_SPUT ((top), QUICKTHREADS_I6, 0))
+
+
+/* The varargs startup routine always reads 6 words of arguments
+ (6 argument registers) from the stack, offset by one word to
+ allow for an aggregate return area pointer. If the varargs
+ routine actually pushed fewer words than that, qt_vstart could read
+ off the top of the stack. To prevent errors, we always allocate 8
+ words. The space is often just wasted. */
+
+#define QUICKTHREADS_VARGS_MD0(sp, vabytes) \
+ ((qt_t *)(((char *)(sp)) - 8*4 - QUICKTHREADS_STKROUNDUP(vabytes)))
+
+#define QUICKTHREADS_VARGS_MD1(sp) \
+ (QUICKTHREADS_SPUT (sp, QUICKTHREADS_O7, ((void *)(((int)qt_vstart)-8))))
+
+/* The SPARC has wierdo calling conventions which stores a hidden
+ parameter for returning aggregate values, so the rest of the
+ parameters are shoved up the stack by one place. */
+#define QUICKTHREADS_VARGS_ADJUST(sp) (((char *)sp)+4)
+
+#define QUICKTHREADS_VARGS_DEFAULT
+
+
+#define QUICKTHREADS_GROW_DOWN
+
+#endif /* ndef QUICKTHREADS_SPARC_H */
diff --git a/ext/systemc/src/sysc/qt/md/sparc.s b/ext/systemc/src/sysc/qt/md/sparc.s
new file mode 100644
index 000000000..d61236b54
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/sparc.s
@@ -0,0 +1,142 @@
+/* sparc.s -- assembly support for the `qt' thread building kit. */
+
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+/* #include <machine/trap.h> */
+
+ .text
+ .align 4
+ .global _qt_blocki
+ .global _qt_block
+ .global _qt_abort
+ .global _qt_start
+ .global _qt_vstart
+
+/* Register assignment:
+// %o0: incoming `helper' function to call after cswap
+// also used as outgoing sp of old thread (qt_t *)
+// %o1, %o2:
+// parameters to `helper' function called after cswap
+// %o3: sp of new thread
+// %o5: tmp used to save old thread sp, while using %o0
+// to call `helper' f() after cswap.
+//
+//
+// Aborting a thread is easy if there are no cached register window
+// frames: just switch to the new stack and away we go. If there are
+// cached register window frames they must all be written back to the
+// old stack before we move to the new stack. If we fail to do the
+// writeback then the old stack memory can be written with register
+// window contents e.g., after the stack memory has been freed and
+// reused.
+//
+// If you don't believe this, try setting the frame pointer to zero
+// once we're on the new stack. This will not affect correctnes
+// otherwise because the frame pointer will eventually get reloaded w/
+// the new thread's frame pointer. But it will be zero briefly before
+// the reload. You will eventually (100,000 cswaps later on a small
+// SPARC machine that I tried) get an illegal instruction trap from
+// the kernel trying to flush a cached window to location 0x0.
+//
+// Solution: flush windows before switching stacks, which invalidates
+// all the other register windows. We could do the trap
+// conditionally: if we're in the lowest frame of a thread, the fp is
+// zero already so we know there's nothing cached. But we expect most
+// aborts will be done from a first function that does a `save', so we
+// will rarely save anything and always pay the cost of testing to see
+// if we should flush.
+//
+// All floating-point registers are caller-save, so this routine
+// doesn't need to do anything to save and restore them.
+//
+// `qt_block' and `qt_blocki' return the same value as the value
+// returned by the helper function. We get this ``for free''
+// since we don't touch the return value register between the
+// return from the helper function and return from qt_block{,i}.
+*/
+
+_qt_block:
+_qt_blocki:
+ sub %sp, 8, %sp /* Allocate save area for return pc. */
+ st %o7, [%sp+64] /* Save return pc. */
+_qt_abort:
+ ta 0x03 /* Save locals and ins. */
+ mov %sp, %o5 /* Remember old sp w/o chng ins/locals. */
+ sub %o3, 96, %sp /* Allocate kwsa, switch stacks. */
+ call %o0, 0 /* Call `helper' routine. */
+ mov %o5, %o0 /* Pass old thread to qt_after_t() */
+ /* .. along w/ args in %o1 & %o2. */
+
+ /* Restore callee-save regs. The kwsa
+ // is on this stack, so offset all
+ // loads by sizeof(kwsa), 64 bytes.
+ */
+ ldd [%sp+ 0+96], %l0
+ ldd [%sp+ 8+96], %l2
+ ldd [%sp+16+96], %l4
+ ldd [%sp+24+96], %l6
+ ldd [%sp+32+96], %i0
+ ldd [%sp+40+96], %i2
+ ldd [%sp+48+96], %i4
+ ldd [%sp+56+96], %i6
+ ld [%sp+64+96], %o7 /* Restore return pc. */
+
+ retl /* Return to address in %o7. */
+ add %sp, 104, %sp /* Deallocate kwsa, ret pc area. */
+
+
+/* The function calling conventions say there has to be a 1-word area
+// in the caller's stack to hold a pointer to space for aggregate
+// return values. It also says there should be a 6-word area to hold
+// %o0..%o5 if the callee wants to save them (why? I don't know...)
+// Round up to 8 words to maintain alignment.
+//
+// Parameter values were stored in callee-save regs and are moved to
+// the parameter registers.
+*/
+_qt_start:
+ mov %i1, %o0 /* `pu': Set up args to `only'. */
+ mov %i2, %o1 /* `pt'. */
+ mov %i4, %o2 /* `userf'. */
+ call %i5, 0 /* Call client function. */
+ sub %sp, 32, %sp /* Allocate 6-word callee space. */
+
+ call _qt_error, 0 /* `only' erroniously returned. */
+ nop
+
+
+/* Same comments as `_qt_start' about allocating rounded-up 7-word
+// save areas. */
+
+_qt_vstart:
+ sub %sp, 32, %sp /* Allocate 7-word callee space. */
+ call %i5, 0 /* call `startup'. */
+ mov %i2, %o0 /* .. with argument `pt'. */
+
+ add %sp, 32, %sp /* Use 7-word space in varargs. */
+ ld [%sp+ 4+64], %o0 /* Load arg0 ... */
+ ld [%sp+ 8+64], %o1
+ ld [%sp+12+64], %o2
+ ld [%sp+16+64], %o3
+ ld [%sp+20+64], %o4
+ call %i4, 0 /* Call `userf'. */
+ ld [%sp+24+64], %o5
+
+ /* Use 6-word space in varargs. */
+ mov %o0, %o1 /* Pass return value from userf */
+ call %i3, 0 /* .. when call `cleanup. */
+ mov %i2, %o0 /* .. along with argument `pt'. */
+
+ call _qt_error, 0 /* `cleanup' erroniously returned. */
+ nop
diff --git a/ext/systemc/src/sysc/qt/md/sparc_b.s b/ext/systemc/src/sysc/qt/md/sparc_b.s
new file mode 100644
index 000000000..cd26672d7
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/sparc_b.s
@@ -0,0 +1,106 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+ .globl _b_call_reg
+ .globl _b_call_imm
+ .globl _b_add
+ .globl _b_load
+
+_b_null:
+ retl
+ nop
+
+_b_call_reg:
+ sethi %hi(_b_null),%o4
+ or %o4,%lo(_b_null),%o4
+ add %o7,%g0, %o3
+L0:
+ call %o4
+ nop
+ call %o4
+ nop
+ call %o4
+ nop
+ call %o4
+ nop
+ call %o4
+ nop
+
+ subcc %o0,1,%o0
+ bg L0
+ nop
+ add %o3,%g0, %o7
+ retl
+ nop
+
+_b_call_imm:
+ sethi %hi(_b_null),%o4
+ or %o4,%lo(_b_null),%o4
+ add %o7,%g0, %o3
+L1:
+ call _b_null
+ call _b_null
+ call _b_null
+ call _b_null
+ call _b_null
+
+ subcc %o0,1,%o0
+ bg L0
+ nop
+ add %o3,%g0, %o7
+ retl
+ nop
+
+
+_b_add:
+ add %o0,%g0,%o1
+ add %o0,%g0,%o2
+ add %o0,%g0,%o3
+ add %o0,%g0,%o4
+L2:
+ sub %o0,5,%o0
+ sub %o1,5,%o1
+ sub %o2,5,%o2
+ sub %o3,5,%o3
+ sub %o4,5,%o4
+
+ subcc %o0,5,%o0
+ sub %o1,5,%o1
+ sub %o2,5,%o2
+ sub %o3,5,%o3
+ sub %o4,5,%o4
+
+ bg L2
+ nop
+ retl
+ nop
+
+
+_b_load:
+ ld [%sp+ 0], %g0
+L3:
+ ld [%sp+ 4],%g0
+ ld [%sp+ 8],%g0
+ ld [%sp+12],%g0
+ ld [%sp+16],%g0
+ ld [%sp+20],%g0
+ ld [%sp+24],%g0
+ ld [%sp+28],%g0
+ ld [%sp+32],%g0
+ ld [%sp+36],%g0
+
+ subcc %o0,10,%o0
+ bg L3
+ ld [%sp+ 0],%g0
+ retl
+ nop
diff --git a/ext/systemc/src/sysc/qt/md/vax.h b/ext/systemc/src/sysc/qt/md/vax.h
new file mode 100644
index 000000000..1948c6fbd
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/vax.h
@@ -0,0 +1,130 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+#ifndef QUICKTHREADS_VAX_H
+#define QUICKTHREADS_VAX_H
+
+typedef unsigned long qt_word_t;
+
+/* Thread's initial stack layout on the VAX:
+
+ non-varargs:
+
+ +---
+ | arg[2] === `userf' on startup
+ | arg[1] === `pt' on startup
+ | arg[0] === `pu' on startup
+ | ... === `only' on startup.
+ +---
+ | ret pc === `qt_start' on startup
+ | fp === 0 on startup
+ | ap === 0 on startup
+ | <mask>
+ | 0 (handler) <--- qt_t.sp
+ +---
+
+ When a non-varargs thread is started, it ``returns'' to the start
+ routine, which calls the client's `only' function.
+
+ The varargs case is clearly bad code. The various values should be
+ stored in a save area and snarfed in to callee-save registers on
+ startup. However, it's too painful to figure out the register
+ mask (right now), so do it the slow way.
+
+ +---
+ | arg[n-1]
+ | ..
+ | arg[0]
+ | nargs
+ +---
+ | === `cleanup'
+ | === `vuserf'
+ | === `startup'
+ | === `pt'
+ +---
+ | ret pc === `qt_start' on startup
+ | fp === 0 on startup
+ | ap === 0 on startup
+ | <mask>
+ | 0 (handler) <--- qt_t.sp
+ +---
+
+ When a varargs thread is started, it ``returns'' to the `qt_vstart'
+ startup code. The startup code pops all the extra arguments, then
+ calls the appropriate functions. */
+
+
+/* What to do to start a thread running. */
+extern void qt_start (void);
+extern void qt_vstart (void);
+
+
+/* Initial call frame for non-varargs and varargs cases. */
+#define QUICKTHREADS_STKBASE (10 * 4)
+#define QUICKTHREADS_VSTKBASE (9 * 4)
+
+
+/* Stack "must be" 4-byte aligned. (Actually, no, but it's
+ easiest and probably fastest to do so.) */
+
+#define QUICKTHREADS_STKALIGN (4)
+
+
+/* Where to place various arguments. */
+#define QUICKTHREADS_ONLY_INDEX (5)
+#define QUICKTHREADS_USER_INDEX (8)
+#define QUICKTHREADS_ARGT_INDEX (7)
+#define QUICKTHREADS_ARGU_INDEX (6)
+
+#define QUICKTHREADS_VSTARTUP_INDEX (6)
+#define QUICKTHREADS_VUSERF_INDEX (7)
+#define QUICKTHREADS_VCLEANUP_INDEX (8)
+#define QUICKTHREADS_VARGT_INDEX (5)
+
+
+/* Stack grows down. The top of the stack is the first thing to
+ pop off (predecrement, postincrement). */
+#define QUICKTHREADS_GROW_DOWN
+
+
+extern void qt_error (void);
+
+#define QUICKTHREADS_VAX_GMASK_NOREGS (0)
+
+/* Push on the error return address, null termination to call chains,
+ number of arguments to `only', register save mask (save no
+ registers). */
+
+#define QUICKTHREADS_ARGS_MD(sto) \
+ (QUICKTHREADS_SPUT (sto, 0, 0), \
+ QUICKTHREADS_SPUT (sto, 1, QUICKTHREADS_VAX_GMASK_NOREGS), \
+ QUICKTHREADS_SPUT (sto, 2, 0), \
+ QUICKTHREADS_SPUT (sto, 3, 0), \
+ QUICKTHREADS_SPUT (sto, 4, qt_start))
+
+#define QUICKTHREADS_VARGS_MD0(sto, nbytes) \
+ (QUICKTHREADS_SPUT (sto, (-(nbytes)/4)-1, (nbytes)/4), \
+ ((char *)(((sto)-4) - QUICKTHREADS_STKROUNDUP(nbytes))))
+
+#define QUICKTHREADS_VARGS_ADJUST(sp) ((char *)sp + 4)
+
+#define QUICKTHREADS_VARGS_MD1(sto) \
+ (QUICKTHREADS_SPUT (sto, 0, 0), \
+ QUICKTHREADS_SPUT (sto, 1, QUICKTHREADS_VAX_GMASK_NOREGS), \
+ QUICKTHREADS_SPUT (sto, 2, 0), \
+ QUICKTHREADS_SPUT (sto, 3, 0), \
+ QUICKTHREADS_SPUT (sto, 4, qt_vstart))
+
+#define QUICKTHREADS_VARGS_DEFAULT
+
+#endif /* QUICKTHREADS_VAX_H */
diff --git a/ext/systemc/src/sysc/qt/md/vax.s b/ext/systemc/src/sysc/qt/md/vax.s
new file mode 100644
index 000000000..fed03f043
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/vax.s
@@ -0,0 +1,69 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+ .text
+
+ .globl _qt_abort
+ .globl _qt_block
+ .globl _qt_blocki
+ .globl _qt_start
+ .globl _qt_vstart
+
+
+/*
+// Calls to these routines have the signature
+//
+// void *block (func, arg1, arg2, newsp)
+//
+// Since the prologue saves 5 registers, nargs, pc, fp, ap, mask, and
+// a condition handler (at sp+0), the first argument is 40=4*10 bytes
+// offset from the stack pointer.
+*/
+_qt_block:
+_qt_blocki:
+_qt_abort:
+ .word 0x7c0 /* Callee-save mask: 5 registers. */
+ movl 56(sp),r1 /* Get stack pointer of new thread. */
+ movl 52(sp),-(r1) /* Push arg2 */
+ movl 48(sp),-(r1) /* Push arg1 */
+ movl sp,-(r1) /* Push arg0 */
+
+ movl 44(sp),r0 /* Get helper to call. */
+ movl r1,sp /* Move to new thread's stack. */
+ addl3 sp,$12,fp /* .. including the frame pointer. */
+ calls $3,(r0) /* Call helper. */
+
+ ret
+
+_qt_start:
+ movl (sp)+,r0 /* Get `only'. */
+ calls $3,(r0) /* Call `only'. */
+ calls $0,_qt_error /* `only' erroniously returned. */
+
+
+_qt_vstart:
+ movl (sp)+,r10 /* Get `pt'. */
+ movl (sp)+,r9 /* Get `startup'. */
+ movl (sp)+,r8 /* Get `vuserf'. */
+ movl (sp)+,r7 /* Get `cleanup'. */
+
+ pushl r10 /* Push `qt'. */
+ calls $1,(r9) /* Call `startup', pop `qt' on return. */
+
+ calls (sp)+,(r8) /* Call user's function. */
+
+ pushl r0 /* Push `vuserf_retval'. */
+ pushl r10 /* Push `qt'. */
+ calls $2,(r7) /* Call `cleanup', never return. */
+
+ calls $0,_qt_error /* `cleanup' erroniously returned. */
diff --git a/ext/systemc/src/sysc/qt/md/vax_b.s b/ext/systemc/src/sysc/qt/md/vax_b.s
new file mode 100644
index 000000000..2db2d4fec
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/vax_b.s
@@ -0,0 +1,92 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+ .text
+ .globl _b_call_reg
+ .globl _b_call_imm
+ .globl _b_add
+ .globl _b_load
+
+_b_null:
+ .word 0x0
+ ret
+
+_b_call_reg:
+ .word 0x0
+ movl 4(ap),r0
+ moval _b_null,r1
+L0:
+ calls $0,(r1)
+ calls $0,(r1)
+ calls $0,(r1)
+ calls $0,(r1)
+ calls $0,(r1)
+
+ subl2 $5,r0
+ bgtr L0
+ ret
+
+
+_b_call_imm:
+ .word 0x0
+ movl 4(ap),r0
+L1:
+ calls $0,_b_null
+ calls $0,_b_null
+ calls $0,_b_null
+ calls $0,_b_null
+ calls $0,_b_null
+
+ subl2 $5,r0
+ bgtr L1
+ ret
+
+
+_b_add:
+ .word 0x0
+ movl 4(ap),r0
+L2:
+ subl2 $1,r0
+ subl2 $1,r0
+ subl2 $1,r0
+ subl2 $1,r0
+ subl2 $1,r0
+
+ subl2 $1,r0
+ subl2 $1,r0
+ subl2 $1,r0
+ subl2 $1,r0
+ subl2 $1,r0
+
+ bgtr L2
+ ret
+
+
+_b_load:
+ .word 0x0
+ movl 4(ap),r0
+L3:
+ movl 0(sp),r1
+ movl 4(sp),r1
+ movl 8(sp),r1
+ movl 12(sp),r1
+ movl 16(sp),r1
+ movl 20(sp),r1
+ movl 24(sp),r1
+ movl 28(sp),r1
+ movl 32(sp),r1
+ movl 36(sp),r1
+
+ subl2 $1,r0
+ bgtr L3
+ ret
diff --git a/ext/systemc/src/sysc/qt/meas.c b/ext/systemc/src/sysc/qt/meas.c
new file mode 100644
index 000000000..3faab3c52
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/meas.c
@@ -0,0 +1,1049 @@
+/* meas.c -- measure qt stuff. */
+
+#include "copyright.h"
+
+/* Need this to get assertions under Mach on the Sequent/i386: */
+#ifdef __i386__
+#define assert(ex) \
+ do { \
+ if (!(ex)) { \
+ fprintf (stderr, "[%s:%d] Assertion " #ex " failed\n", __FILE__, __LINE__); \
+ abort(); \
+ } \
+ } while (0)
+#else
+#include <assert.h>
+#endif
+
+/* This really ought to be defined in some ANSI include file (*I*
+ think...), but it's defined here instead, which leads us to another
+ machine dependency.
+
+ The `iaddr_t' type is an integer representation of a pointer,
+ suited for doing arithmetic on addresses, e.g. to round an address
+ to an alignment boundary. */
+typedef unsigned long iaddr_t;
+
+#include <stdarg.h> /* For varargs tryout. */
+#include <stdio.h>
+#include "b.h"
+#include "qt.h"
+#include "stp.h"
+
+extern void exit (int status);
+extern int atoi (char const *s);
+extern int fprintf (FILE *out, char const *fmt, ...);
+extern int fputs (char const *s, FILE *fp);
+extern void free (void *sto);
+extern void *malloc (unsigned nbytes);
+extern void perror (char const *s);
+
+void usage (void);
+void tracer(void);
+
+/* Round `v' to be `a'-aligned, assuming `a' is a power of two. */
+#define ROUND(v, a) (((v) + (a) - 1) & ~((a)-1))
+
+typedef struct thread_t {
+ qt_t *qt; /* Pointer to thread of function... */
+ void *stk;
+ void *top; /* Set top of stack if reuse. */
+ struct thread_t *next;
+} thread_t;
+
+
+ static thread_t *
+t_alloc (void)
+{
+ thread_t *t;
+ int ssz = 0x1000;
+
+ t = malloc (sizeof(thread_t));
+ if (!t) {
+ perror ("malloc");
+ exit (1);
+ }
+ assert (ssz > QT_STKBASE);
+ t->stk = malloc (ssz);
+ t->stk = (void *)ROUND (((iaddr_t)t->stk), QT_STKALIGN);
+ if (!t->stk) {
+ perror ("malloc");
+ exit (1);
+ }
+ assert ((((iaddr_t)t->stk) & (QT_STKALIGN-1)) == 0);
+ t->top = QT_SP (t->stk, ssz - QT_STKBASE);
+
+ return (t);
+}
+
+
+ static thread_t *
+t_create (qt_only_t *starter, void *p0, qt_userf_t *f)
+{
+ thread_t *t;
+
+ t = t_alloc();
+ t->qt = QT_ARGS (t->top, p0, t, f, starter);
+ return (t);
+}
+
+
+ static void
+t_free (thread_t *t)
+{
+ free (t->stk);
+ free (t);
+}
+
+
+ static void *
+t_null (qt_t *old, void *p1, void *p2)
+{
+ /* return (garbage); */
+}
+
+
+ static void *
+t_splat (qt_t *old, void *oldp, void *null)
+{
+ *(qt_t **)oldp = old;
+ /* return (garbage); */
+}
+
+
+static char const test01_msg[] =
+ "*QT_SP(sto,sz), QT_ARGS(top,p0,p1,userf,first)";
+
+static char const *test01_descr[] = {
+ "Performs 1 QT_SP and one QT_ARGS per iteration.",
+ NULL
+};
+
+/* This test gives a guess on how long it takes to initalize
+ a thread. */
+
+ static void
+test01 (int n)
+{
+ char stack[QT_STKBASE+QT_STKALIGN];
+ char *stk;
+ qt_t *top;
+
+ stk = (char *)ROUND (((iaddr_t)stack), QT_STKALIGN);
+
+ {
+ int i;
+
+ for (i=0; i<QT_STKBASE; ++i) {
+ stk[i] = 0;
+ }
+ }
+
+ while (n>0) {
+ /* RETVALUSED */
+ top = QT_SP (stk, QT_STKBASE); QT_ARGS (top, 0, 0, 0, 0);
+#ifdef NDEF
+ top = QT_SP (stk, QT_STKBASE); QT_ARGS (top, 0, 0, 0, 0);
+ top = QT_SP (stk, QT_STKBASE); QT_ARGS (top, 0, 0, 0, 0);
+ top = QT_SP (stk, QT_STKBASE); QT_ARGS (top, 0, 0, 0, 0);
+ top = QT_SP (stk, QT_STKBASE); QT_ARGS (top, 0, 0, 0, 0);
+
+ top = QT_SP (stk, QT_STKBASE); QT_ARGS (top, 0, 0, 0, 0);
+ top = QT_SP (stk, QT_STKBASE); QT_ARGS (top, 0, 0, 0, 0);
+ top = QT_SP (stk, QT_STKBASE); QT_ARGS (top, 0, 0, 0, 0);
+ top = QT_SP (stk, QT_STKBASE); QT_ARGS (top, 0, 0, 0, 0);
+ top = QT_SP (stk, QT_STKBASE); QT_ARGS (top, 0, 0, 0, 0);
+
+ n -= 10;
+#else
+ n -= 1;
+#endif
+ }
+}
+
+
+static char const test02_msg[] = "QT_BLOCKI (0, 0, test02_aux, t->qt)";
+static qt_t *rootthread;
+
+ static void
+test02_aux1 (void *pu, void *pt, qt_userf_t *f)
+{
+ QT_ABORT (t_null, 0, 0, rootthread);
+}
+
+ static void *
+test02_aux2 (qt_t *old, void *farg1, void *farg2)
+{
+ rootthread = old;
+ /* return (garbage); */
+}
+
+ static void
+test02 (int n)
+{
+ thread_t *t;
+
+ while (n>0) {
+ t = t_create (test02_aux1, 0, 0);
+ QT_BLOCKI (test02_aux2, 0, 0, t->qt);
+ t_free (t);
+ t = t_create (test02_aux1, 0, 0);
+ QT_BLOCKI (test02_aux2, 0, 0, t->qt);
+ t_free (t);
+ t = t_create (test02_aux1, 0, 0);
+ QT_BLOCKI (test02_aux2, 0, 0, t->qt);
+ t_free (t);
+ t = t_create (test02_aux1, 0, 0);
+ QT_BLOCKI (test02_aux2, 0, 0, t->qt);
+ t_free (t);
+ t = t_create (test02_aux1, 0, 0);
+ QT_BLOCKI (test02_aux2, 0, 0, t->qt);
+ t_free (t);
+
+ n -= 5;
+ }
+}
+
+
+static char const test03_msg[] = "QT_BLOCKI (...) test vals are right.";
+
+
+/* Called by the thread function when it wants to shut down.
+ Return a value to the main thread. */
+
+ static void *
+test03_aux0 (qt_t *old_is_garbage, void *farg1, void *farg2)
+{
+ assert (farg1 == (void *)5);
+ assert (farg2 == (void *)6);
+ return ((void *)15); /* Some unlikely value. */
+}
+
+
+/* Called during new thread startup by main thread. Since the new
+ thread has never run before, return value is ignored. */
+
+ static void *
+test03_aux1 (qt_t *old, void *farg1, void *farg2)
+{
+ assert (old != NULL);
+ assert (farg1 == (void *)5);
+ assert (farg2 == (void *)6);
+ rootthread = old;
+ return ((void *)16); /* Different than `15'. */
+}
+
+ static void
+test03_aux2 (void *pu, void *pt, qt_userf_t *f)
+{
+ assert (pu == (void *)1);
+ assert (f == (qt_userf_t *)4);
+ QT_ABORT (test03_aux0, (void *)5, (void *)6, rootthread);
+}
+
+ static void
+test03 (int n)
+{
+ thread_t *t;
+ void *rv;
+
+ while (n>0) {
+ t = t_create (test03_aux2, (void *)1, (qt_userf_t *)4);
+ rv = QT_BLOCKI (test03_aux1, (void *)5, (void *)6, t->qt);
+ assert (rv == (void *)15);
+ t_free (t);
+
+ --n;
+ }
+}
+
+
+static char const test04_msg[] = "stp_start w/ no threads.";
+
+ static void
+test04 (int n)
+{
+ while (n>0) {
+ stp_init(); stp_start();
+ stp_init(); stp_start();
+ stp_init(); stp_start();
+ stp_init(); stp_start();
+ stp_init(); stp_start();
+
+ stp_init(); stp_start();
+ stp_init(); stp_start();
+ stp_init(); stp_start();
+ stp_init(); stp_start();
+ stp_init(); stp_start();
+
+ n -= 10;
+ }
+}
+
+
+static char const test05_msg[] = "stp w/ 2 yielding thread.";
+
+ static void
+test05_aux (void *null)
+{
+ stp_yield();
+ stp_yield();
+}
+
+ static void
+test05 (int n)
+{
+ while (n>0) {
+ stp_init();
+ stp_create (test05_aux, 0);
+ stp_create (test05_aux, 0);
+ stp_start();
+
+ --n;
+ }
+}
+
+
+static char const test06_msg[] = "*QT_ARGS(...), QT_BLOCKI one thread";
+
+static char const *test06_descr[] = {
+ "Does a QT_ARGS, QT_BLOCKI to a helper function that saves the",
+ "stack pointer of the main thread, calls an `only' function that",
+ "saves aborts the thread, calling a null helper function.",
+ ":: start/stop = QT_ARGS + QT_BLOCKI + QT_ABORT + 3 procedure calls.",
+ NULL
+};
+
+/* This test initializes a thread, runs it, then returns to the main
+ program, which reinitializes the thread, runs it again, etc. Each
+ iteration corresponds to 1 init, 1 abort, 1 block. */
+
+static qt_t *test06_sp;
+
+
+ static void
+test06_aux2 (void *null0a, void *null1b, void *null2b, qt_userf_t *null)
+{
+ QT_ABORT (t_null, 0, 0, test06_sp);
+}
+
+
+ static void *
+test06_aux3 (qt_t *sp, void *null0c, void *null1c)
+{
+ test06_sp = sp;
+ /* return (garbage); */
+}
+
+
+ static void
+test06 (int n)
+{
+ thread_t *t;
+
+ t = t_create (0, 0, 0);
+
+ while (n>0) {
+ /* RETVALUSED */
+ QT_ARGS (t->top, 0, 0, 0, test06_aux2);
+ QT_BLOCKI (test06_aux3, 0, 0, t->qt);
+#ifdef NDEF
+ /* RETVALUSED */
+ QT_ARGS (t->top, 0, 0, 0, test06_aux2);
+ QT_BLOCKI (test06_aux3, 0, 0, t->qt);
+
+ /* RETVALUSED */
+ QT_ARGS (t->top, 0, 0, 0, test06_aux2);
+ QT_BLOCKI (test06_aux3, 0, 0, t->qt);
+
+ /* RETVALUSED */
+ QT_ARGS (t->top, 0, 0, 0, test06_aux2);
+ QT_BLOCKI (test06_aux3, 0, 0, t->qt);
+
+ /* RETVALUSED */
+ QT_ARGS (t->top, 0, 0, 0, test06_aux2);
+ QT_BLOCKI (test06_aux3, 0, 0, t->qt);
+
+ n -= 5;
+#else
+ --n;
+#endif
+ }
+}
+
+static char test07_msg[] = "*cswap between threads";
+
+static char const *test07_descr[] = {
+ "Build a chain of threads where each thread has a fixed successor.",
+ "There is no scheduling performed. Each thread but one is a loop",
+ "that simply blocks with QT_BLOCKI, calling a helper that saves the",
+ "current stack pointer. The last thread decrements a count, and,",
+ "if zero, aborts back to the main thread. Else it continues with",
+ "the blocking chain. The count is divided by the number of threads",
+ "in the chain, so `n' is the number of integer block operations.",
+ ":: integer cswap = QT_BLOCKI + a procedure call.",
+ NULL
+};
+
+/* This test repeatedly blocks a bunch of threads.
+ Each iteration corresponds to one block operation.
+
+ The threads are arranged so that there are TEST07_N-1 of them that
+ run `test07_aux2'. Each one of those blocks saving it's sp to
+ storage owned by the preceding thread; a pointer to that storage is
+ passed in via `mep'. Each thread has a handle on it's own storage
+ for the next thread, referenced by `nxtp', and it blocks by passing
+ control to `*nxtp', telling the helper function to save its state
+ in `*mep'. The last thread in the chain decrements a count and, if
+ it's gone below zero, returns to `test07'; otherwise, it invokes
+ the first thread in the chain. */
+
+static qt_t *test07_heavy;
+
+#define TEST07_N (4)
+
+
+ static void
+test07_aux2 (void *null0, void *mep, void *nxtp, qt_userf_t *null)
+{
+ qt_t *nxt;
+
+ while (1) {
+ nxt = *(qt_t **)nxtp;
+#ifdef NDEF
+ printf ("Helper 0x%p\n", nxtp);
+#endif
+ QT_BLOCKI (t_splat, mep, 0, nxt);
+ }
+}
+
+ static void
+test07_aux3 (void *np, void *mep, void *nxtp, qt_userf_t *null)
+{
+ int n;
+
+ n = *(int *)np;
+ while (1) {
+ n -= TEST07_N;
+ if (n<0) {
+ QT_ABORT (t_splat, mep, 0, test07_heavy);
+ }
+ QT_BLOCKI (t_splat, mep, 0, *(qt_t **)nxtp);
+ }
+}
+
+
+ static void
+test07 (int n)
+{
+ int i;
+ thread_t *t[TEST07_N];
+
+ for (i=0; i<TEST07_N; ++i) {
+ t[i] = t_create (0, 0, 0);
+ }
+ for (i=0; i<TEST07_N-1; ++i) {
+ /* RETVALUSED */
+ QT_ARGS (t[i]->top, 0, &t[i]->qt, &t[i+1]->qt, test07_aux2);
+ }
+ /* RETVALUSED */
+ QT_ARGS (t[i]->top, &n, &t[TEST07_N-1]->qt, &t[0]->qt, test07_aux3);
+ QT_BLOCKI (t_splat, &test07_heavy, 0, t[0]->qt);
+}
+
+
+static char test08_msg[] = "Floating-point cswap between threads";
+
+static char const *test08_descr[] = {
+ "Measure context switch times including floating-point, use QT_BLOCK.",
+ NULL
+};
+
+static qt_t *test08_heavy;
+
+#define TEST08_N (4)
+
+
+ static void
+test08_aux2 (void *null0, void *mep, void *nxtp, qt_userf_t *null)
+{
+ qt_t *nxt;
+
+ while (1) {
+ nxt = *(qt_t **)nxtp;
+ QT_BLOCK (t_splat, mep, 0, nxt);
+ }
+}
+
+ static void
+test08_aux3 (void *np, void *mep, void *nxtp, qt_userf_t *null)
+{
+ int n;
+
+ n = *(int *)np;
+ while (1) {
+ n -= TEST08_N;
+ if (n<0) {
+ QT_ABORT (t_splat, mep, 0, test08_heavy);
+ }
+ QT_BLOCK (t_splat, mep, 0, *(qt_t **)nxtp);
+ }
+}
+
+
+ static void
+test08 (int n)
+{
+ int i;
+ thread_t *t[TEST08_N];
+
+ for (i=0; i<TEST08_N; ++i) {
+ t[i] = t_create (0, 0, 0);
+ }
+ for (i=0; i<TEST08_N-1; ++i) {
+ /* RETVALUSED */
+ QT_ARGS (t[i]->top, 0, &t[i]->qt, &t[i+1]->qt, test08_aux2);
+ }
+ /* RETVALUSED */
+ QT_ARGS (t[i]->top, &n, &t[TEST08_N-1]->qt, &t[0]->qt, test08_aux3);
+ QT_BLOCK (t_splat, &test08_heavy, 0, t[0]->qt);
+}
+
+
+/* Test the varargs procedure calling. */
+
+char const test09_msg[] = { "Start and run threads using varargs." };
+
+thread_t *test09_t0, *test09_t1, *test09_t2, *test09_main;
+
+ thread_t *
+test09_create (qt_startup_t *start, qt_vuserf_t *f,
+ qt_cleanup_t *cleanup, int nbytes, ...)
+{
+ va_list ap;
+ thread_t *t;
+
+ t = t_alloc();
+ va_start (ap, nbytes);
+ t->qt = QT_VARGS (t->top, nbytes, ap, t, start, f, cleanup);
+ va_end (ap);
+ return (t);
+}
+
+
+ static void
+test09_cleanup (void *pt, void *vuserf_retval)
+{
+ assert (vuserf_retval == (void *)17);
+ QT_ABORT (t_splat, &((thread_t *)pt)->qt, 0,
+ ((thread_t *)pt)->next->qt);
+}
+
+
+ static void
+test09_start (void *pt)
+{
+}
+
+
+ static void *
+test09_user0 (void)
+{
+ QT_BLOCKI (t_splat, &test09_t0->qt, 0, test09_t1->qt);
+ return ((void *)17);
+}
+
+ static void *
+test09_user2 (int one, int two)
+{
+ assert (one == 1);
+ assert (two == 2);
+ QT_BLOCKI (t_splat, &test09_t1->qt, 0, test09_t2->qt);
+ assert (one == 1);
+ assert (two == 2);
+ return ((void *)17);
+}
+
+ static void *
+test09_user10 (int one, int two, int three, int four, int five,
+ int six, int seven, int eight, int nine, int ten)
+{
+ assert (one == 1);
+ assert (two == 2);
+ assert (three == 3);
+ assert (four == 4);
+ assert (five == 5);
+ assert (six == 6);
+ assert (seven == 7);
+ assert (eight == 8);
+ assert (nine == 9);
+ assert (ten == 10);
+ QT_BLOCKI (t_splat, &test09_t2->qt, 0, test09_main->qt);
+ assert (one == 1);
+ assert (two == 2);
+ assert (three == 3);
+ assert (four == 4);
+ assert (five == 5);
+ assert (six == 6);
+ assert (seven == 7);
+ assert (eight == 8);
+ assert (nine == 9);
+ assert (ten == 10);
+ return ((void *)17);
+}
+
+
+ void
+test09 (int n)
+{
+ thread_t main;
+
+ test09_main = &main;
+
+ while (--n >= 0) {
+ test09_t0 = test09_create (test09_start, (qt_vuserf_t*)test09_user0,
+ test09_cleanup, 0);
+ test09_t1 = test09_create (test09_start, (qt_vuserf_t*)test09_user2,
+ test09_cleanup, 2 * sizeof(qt_word_t), 1, 2);
+ test09_t2 = test09_create (test09_start, (qt_vuserf_t*)test09_user10,
+ test09_cleanup, 10 * sizeof(qt_word_t),
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+
+ /* Chaining used by `test09_cleanup' to determine who is next. */
+ test09_t0->next = test09_t1;
+ test09_t1->next = test09_t2;
+ test09_t2->next = test09_main;
+
+ QT_BLOCKI (t_splat, &test09_main->qt, 0, test09_t0->qt);
+ QT_BLOCKI (t_splat, &test09_main->qt, 0, test09_t0->qt);
+
+ t_free (test09_t0);
+ t_free (test09_t1);
+ t_free (test09_t2);
+ }
+}
+
+
+ /* Test 10/11/12: time the cost of various number of args. */
+
+char const test10_msg[] = { "*Test varargs init & startup w/ 0 args." };
+
+char const *test10_descr[] = {
+ "Start and stop threads that use variant argument lists (varargs).",
+ "Each thread is initialized by calling a routine that calls",
+ "QT_VARARGS. Then runs the thread by calling QT_BLOCKI to hald the",
+ "main thread, a helper that saves the main thread's stack pointer,",
+ "a null startup function, a null user function, a cleanup function",
+ "that calls QT_ABORT and restarts the main thread. Copies no user",
+ "parameters.",
+ ":: varargs start/stop = QT_BLOCKI + QT_ABORT + 6 function calls.",
+ NULL
+};
+
+/* Helper function to send control back to main.
+ Don't save anything. */
+
+
+/* Helper function for starting the varargs thread. Save the stack
+ pointer of the main thread so we can get back there eventually. */
+
+
+/* Startup function for a varargs thread. */
+
+ static void
+test10_startup (void *pt)
+{
+}
+
+
+/* User function for a varargs thread. */
+
+ static void *
+test10_run (int arg0, ...)
+{
+ /* return (garbage); */
+}
+
+
+/* Cleanup function for a varargs thread. Send control
+ back to the main thread. Don't save any state from the thread that
+ is halting. */
+
+ void
+test10_cleanup (void *pt, void *vuserf_retval)
+{
+ QT_ABORT (t_null, 0, 0, ((thread_t *)pt)->qt);
+}
+
+
+ void
+test10_init (thread_t *new, thread_t *next, int nbytes, ...)
+{
+ va_list ap;
+
+ va_start (ap, nbytes);
+ new->qt = QT_VARGS (new->top, nbytes, ap, next, test10_startup,
+ test10_run, test10_cleanup);
+ va_end (ap);
+}
+
+
+ void
+test10 (int n)
+{
+ thread_t main;
+ thread_t *t;
+
+ t = t_alloc();
+ t->next = &main;
+
+ while (--n >= 0) {
+ test10_init (t, &main, 0);
+ QT_BLOCKI (t_splat, &main.qt, 0, t->qt);
+ }
+ t_free (t);
+}
+
+
+char const test11_msg[] = { "*Test varargs init & startup w/ 2 args." };
+
+char const *test11_descr[] = {
+ "Varargs initialization/run. Copies 2 user arguments.",
+ ":: varargs 2 start/stop = QT_VARGS(2 args), QT_BLOCKI, QT_ABORT, 6 f() calls.",
+ NULL
+};
+
+
+ void
+test11 (int n)
+{
+ thread_t main;
+ thread_t *t;
+
+ t = t_alloc();
+ t->next = &main;
+
+ while (--n >= 0) {
+ test10_init (t, &main, 2 * sizeof(int), 2, 1);
+ QT_BLOCKI (t_splat, &main.qt, 0, t->qt);
+ }
+ t_free (t);
+}
+
+char const test12_msg[] = { "*Test varargs init & startup w/ 4 args." };
+
+char const *test12_descr[] = {
+ "Varargs initialization/run. Copies 4 user arguments.",
+ ":: varargs 4 start/stop = QT_VARGS(4 args), QT_BLOCKI, QT_ABORT, 6 f() calls.",
+ NULL
+};
+
+
+ void
+test12 (int n)
+{
+ thread_t main;
+ thread_t *t;
+
+ t = t_alloc();
+ t->next = &main;
+
+ while (--n >= 0) {
+ test10_init (t, &main, 4 * sizeof(int), 4, 3, 2, 1);
+ QT_BLOCKI (t_splat, &main.qt, 0, t->qt);
+ }
+ t_free (t);
+}
+
+
+char const test13_msg[] = { "*Test varargs init & startup w/ 8 args." };
+
+char const *test13_descr[] = {
+ "Varargs initialization/run. Copies 8 user arguments.",
+ ":: varargs 8 start/stop = QT_VARGS(8 args), QT_BLOCKI, QT_ABORT, 6 f() calls.",
+ NULL
+};
+
+ void
+test13 (int n)
+{
+ thread_t main;
+ thread_t *t;
+
+ t = t_alloc();
+ t->next = &main;
+
+ while (--n >= 0) {
+ test10_init (t, &main, 8 * sizeof(int), 8, 7, 6, 5, 4, 3, 2, 1);
+ QT_BLOCKI (t_splat, &main.qt, 0, t->qt);
+ }
+ t_free (t);
+}
+
+
+char const test14_msg[] = { "*Test varargs initialization w/ 0 args." };
+
+char const *test14_descr[] = {
+ "Varargs initialization without running the thread. Just calls",
+ "QT_VARGS.",
+ ":: varargs 0 init = QT_VARGS()",
+ NULL
+};
+
+ void
+test14 (int n)
+{
+ thread_t main;
+ thread_t *t;
+
+ t = t_alloc();
+ t->next = &main;
+
+ while (--n >= 0) {
+ test10_init (t, &main, 0 * sizeof(int));
+ }
+ t_free (t);
+}
+
+
+char const test15_msg[] = { "*Test varargs initialization w/ 2 args." };
+
+char const *test15_descr[] = {
+ "Varargs initialization without running the thread. Just calls",
+ "QT_VARGS.",
+ ":: varargs 2 init = QT_VARGS(2 args)",
+ NULL
+};
+
+ void
+test15 (int n)
+{
+ thread_t main;
+ thread_t *t;
+
+ t = t_alloc();
+ t->next = &main;
+
+ while (--n >= 0) {
+ test10_init (t, &main, 2 * sizeof(int), 2, 1);
+ }
+ t_free (t);
+}
+
+char const test16_msg[] = { "*Test varargs initialization w/ 4 args." };
+
+char const *test16_descr[] = {
+ "Varargs initialization without running the thread. Just calls",
+ "QT_VARGS.",
+ ":: varargs 4 init = QT_VARGS(4 args)",
+ NULL
+};
+
+
+ void
+test16 (int n)
+{
+ thread_t main;
+ thread_t *t;
+
+ t = t_alloc();
+ t->next = &main;
+
+ while (--n >= 0) {
+ test10_init (t, &main, 4 * sizeof(int), 4, 3, 2, 1);
+ }
+ t_free (t);
+}
+
+
+char const test17_msg[] = { "*Test varargs initialization w/ 8 args." };
+
+char const *test17_descr[] = {
+ "Varargs initialization without running the thread. Just calls",
+ "QT_VARGS.",
+ ":: varargs 8 init = QT_VARGS(8 args)",
+ NULL
+};
+
+
+ void
+test17 (int n)
+{
+ thread_t main;
+ thread_t *t;
+
+ t = t_alloc();
+ t->next = &main;
+
+ while (--n >= 0) {
+ test10_init (t, &main, 8 * sizeof(int), 8, 7, 6, 5, 4, 3, 2, 1);
+ }
+ t_free (t);
+}
+
+ /* Test times for basic machine operations. */
+
+char const test18_msg[] = { "*Call register indirect." };
+char const *test18_descr[] = { NULL };
+
+ void
+test18 (int n)
+{
+ b_call_reg (n);
+}
+
+
+char const test19_msg[] = { "*Call immediate." };
+char const *test19_descr[] = { NULL };
+
+ void
+test19 (int n)
+{
+ b_call_imm (n);
+}
+
+
+char const test20_msg[] = { "*Add register-to-register." };
+char const *test20_descr[] = { NULL };
+
+ void
+test20 (int n)
+{
+ b_add (n);
+}
+
+
+char const test21_msg[] = { "*Load memory to a register." };
+char const *test21_descr[] = { NULL };
+
+ void
+test21 (int n)
+{
+ b_load (n);
+}
+
+ /* Driver. */
+
+typedef struct foo_t {
+ char const *msg; /* Message to print for generic help. */
+ char const **descr; /* A description of what is done by the test. */
+ void (*f)(int n);
+} foo_t;
+
+
+static foo_t foo[] = {
+ { "Usage:\n", NULL, (void(*)(int n))usage },
+ { test01_msg, test01_descr, test01 },
+ { test02_msg, NULL, test02 },
+ { test03_msg, NULL, test03 },
+ { test04_msg, NULL, test04 },
+ { test05_msg, NULL, test05 },
+ { test06_msg, test06_descr, test06 },
+ { test07_msg, test07_descr, test07 },
+ { test08_msg, test08_descr, test08 },
+ { test09_msg, NULL, test09 },
+ { test10_msg, test10_descr, test10 },
+ { test11_msg, test11_descr, test11 },
+ { test12_msg, test12_descr, test12 },
+ { test13_msg, test13_descr, test13 },
+ { test14_msg, test14_descr, test14 },
+ { test15_msg, test15_descr, test15 },
+ { test16_msg, test16_descr, test16 },
+ { test17_msg, test17_descr, test17 },
+ { test18_msg, test18_descr, test18 },
+ { test19_msg, test19_descr, test19 },
+ { test20_msg, test20_descr, test20 },
+ { test21_msg, test21_descr, test21 },
+ { 0, 0 }
+};
+
+static int tv = 0;
+
+ void
+tracer ()
+{
+
+ fprintf (stderr, "tracer\t%d\n", tv++);
+ fflush (stderr);
+}
+
+ void
+tracer2 (void *val)
+{
+ fprintf (stderr, "tracer2\t%d val=0x%p", tv++, val);
+ fflush (stderr);
+}
+
+
+ void
+describe()
+{
+ int i;
+ FILE *out = stdout;
+
+ for (i=0; foo[i].msg; ++i) {
+ if (foo[i].descr) {
+ int j;
+
+ putc ('\n', out);
+ fprintf (out, "[%d]\n", i);
+ for (j=0; foo[i].descr[j]; ++j) {
+ fputs (foo[i].descr[j], out);
+ putc ('\n', out);
+ }
+ }
+ }
+ exit (0);
+}
+
+
+ void
+usage()
+{
+ int i;
+
+ fputs (foo[0].msg, stderr);
+ for (i=1; foo[i].msg; ++i) {
+ fprintf (stderr, "%2d\t%s\n", i, foo[i].msg);
+ }
+ exit (1);
+}
+
+
+ void
+args (int *which, int *n, int argc, char **argv)
+{
+ static int nfuncs = 0;
+
+ if (argc == 2 && argv[1][0] == '-' && argv[1][1] == 'h') {
+ describe();
+ }
+
+ if (nfuncs == 0) {
+ for (nfuncs=0; foo[nfuncs].msg; ++nfuncs)
+ ;
+ }
+
+ if (argc != 2 && argc != 3) {
+ usage();
+ }
+
+ *which = atoi (argv[1]);
+ if (*which < 0 || *which >= nfuncs) {
+ usage();
+ }
+ *n = (argc == 3)
+ ? atoi (argv[2])
+ : 1;
+}
+
+
+ int
+main (int argc, char **argv)
+{
+ int which, n;
+ args (&which, &n, argc, argv);
+ (*(foo[which].f))(n);
+ exit (0);
+ return (0);
+}
diff --git a/ext/systemc/src/sysc/qt/qt.c b/ext/systemc/src/sysc/qt/qt.c
new file mode 100644
index 000000000..204d38397
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/qt.c
@@ -0,0 +1,56 @@
+#include "copyright.h"
+#include "qt.h"
+
+// static void *qt_sp_bottom_save;
+
+#ifdef QT_VARGS_DEFAULT
+
+/* If the stack grows down, `vargs' is a pointer to the lowest
+ address in the block of arguments. If the stack grows up, it is a
+ pointer to the highest address in the block. */
+
+ qt_t *
+qt_vargs (qt_t *sp, int nbytes, void *vargs,
+ void *pt, qt_startup_t *startup,
+ qt_vuserf_t *vuserf, qt_cleanup_t *cleanup)
+{
+ int i;
+
+ sp = QT_VARGS_MD0 (sp, nbytes);
+#ifdef QT_GROW_UP
+ for (i=nbytes/sizeof(qt_word_t); i>0; --i) {
+ QT_SPUT (QT_VARGS_ADJUST(sp), i, ((qt_word_t *)vargs)[-i]);
+ }
+#else
+ for (i=nbytes/sizeof(qt_word_t); i>0; --i) {
+ QT_SPUT (QT_VARGS_ADJUST(sp), i-1, ((qt_word_t *)vargs)[i-1]);
+ }
+#endif
+
+ QT_VARGS_MD1 (QT_VADJ(sp));
+ QT_SPUT (QT_VADJ(sp), QT_VARGT_INDEX, pt);
+ QT_SPUT (QT_VADJ(sp), QT_VSTARTUP_INDEX, startup);
+ QT_SPUT (QT_VADJ(sp), QT_VUSERF_INDEX, vuserf);
+ QT_SPUT (QT_VADJ(sp), QT_VCLEANUP_INDEX, cleanup);
+ return ((qt_t *)QT_VADJ(sp));
+}
+#endif /* def QT_VARGS_DEFAULT */
+
+#ifdef __cplusplus
+extern "C"
+#endif
+ void
+qt_null (void)
+{
+}
+
+#ifdef __cplusplus
+extern "C"
+#endif
+ void
+qt_error (void)
+{
+ extern void abort(void);
+
+ abort();
+}
diff --git a/ext/systemc/src/sysc/qt/qt.h b/ext/systemc/src/sysc/qt/qt.h
new file mode 100644
index 000000000..40a9f531b
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/qt.h
@@ -0,0 +1,192 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+#ifndef QUICKTHREADS_QT_H
+#define QUICKTHREADS_QT_H
+
+#if !defined(SC_USE_PTHREADS)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sysc/qt/qtmd.h>
+
+
+/* A QuickThreads thread is represented by it's current stack pointer.
+ To restart a thread, you merely need pass the current sp (qt_t*) to
+ a QuickThreads primitive. `qt_t*' is a location on the stack. To
+ improve type checking, represent it by a particular struct. */
+
+typedef struct qt_t {
+ char dummy;
+} qt_t;
+
+
+/* Alignment is guaranteed to be a power of two. */
+#ifndef QUICKTHREADS_STKALIGN
+ #error "Need to know the machine-dependent stack alignment."
+#endif
+
+#define QUICKTHREADS_STKROUNDUP(bytes) \
+ (((bytes)+QUICKTHREADS_STKALIGN) & ~(QUICKTHREADS_STKALIGN-1))
+
+
+/* Find ``top'' of the stack, space on the stack. */
+#ifndef QUICKTHREADS_SP
+#ifdef QUICKTHREADS_GROW_DOWN
+#define QUICKTHREADS_SP(sto, size) ((qt_t *)(&((char *)(sto))[(size)]))
+#endif
+#ifdef QUICKTHREADS_GROW_UP
+#define QUICKTHREADS_SP(sto, size) ((qt_t *)(sto))
+#endif
+#if !defined(QUICKTHREADS_SP)
+ #error "QUICKTHREADS_QT_H: Stack must grow up or down!"
+#endif
+#endif
+
+
+/* The type of the user function:
+ For non-varargs, takes one void* function.
+ For varargs, takes some number of arguments. */
+typedef void *(qt_userf_t)(void *pu);
+typedef void *(qt_vuserf_t)(int arg0, ...);
+
+/* For non-varargs, just call a client-supplied function,
+ it does all startup and cleanup, and also calls the user's
+ function. */
+typedef void (qt_only_t)(void *pu, void *pt, qt_userf_t *userf);
+
+/* For varargs, call `startup', then call the user's function,
+ then call `cleanup'. */
+typedef void (qt_startup_t)(void *pt);
+typedef void (qt_cleanup_t)(void *pt, void *vuserf_return);
+
+
+/* Internal helper for putting stuff on stack. */
+#ifndef QUICKTHREADS_SPUT
+#define QUICKTHREADS_SPUT(top, at, val) \
+ (((qt_word_t *)(top))[(at)] = (qt_word_t)(val))
+#endif
+
+
+/* Push arguments for the non-varargs case. */
+#ifndef QUICKTHREADS_ARGS
+
+#ifndef QUICKTHREADS_ARGS_MD
+#define QUICKTHREADS_ARGS_MD (0)
+#endif
+
+#ifndef QUICKTHREADS_STKBASE
+ #error "Need to know the machine-dependent stack allocation."
+#endif
+
+/* All things are put on the stack relative to the final value of
+ the stack pointer. */
+#ifdef QUICKTHREADS_GROW_DOWN
+#define QUICKTHREADS_ADJ(sp) (((char *)sp) - QUICKTHREADS_STKBASE)
+#else
+#define QUICKTHREADS_ADJ(sp) (((char *)sp) + QUICKTHREADS_STKBASE)
+#endif
+
+#define QUICKTHREADS_ARGS(sp, pu, pt, userf, only) \
+ (QUICKTHREADS_ARGS_MD (QUICKTHREADS_ADJ(sp)), \
+ QUICKTHREADS_SPUT (QUICKTHREADS_ADJ(sp), QUICKTHREADS_ONLY_INDEX, only), \
+ QUICKTHREADS_SPUT (QUICKTHREADS_ADJ(sp), QUICKTHREADS_USER_INDEX, userf), \
+ QUICKTHREADS_SPUT (QUICKTHREADS_ADJ(sp), QUICKTHREADS_ARGT_INDEX, pt), \
+ QUICKTHREADS_SPUT (QUICKTHREADS_ADJ(sp), QUICKTHREADS_ARGU_INDEX, pu), \
+ ((qt_t *)QUICKTHREADS_ADJ(sp)))
+
+#endif
+
+
+/* Push arguments for the varargs case.
+ Has to be a function call because initialization is an expression
+ and we need to loop to copy nbytes of stuff on to the stack.
+ But that's probably OK, it's not terribly cheap, anyway. */
+
+#ifdef QUICKTHREADS_VARGS_DEFAULT
+#ifndef QUICKTHREADS_VARGS_MD0
+#define QUICKTHREADS_VARGS_MD0(sp, vasize) (sp)
+#endif
+#ifndef QUICKTHREADS_VARGS_MD1
+#define QUICKTHREADS_VARGS_MD1(sp) do { ; } while (0)
+#endif
+
+#ifndef QUICKTHREADS_VSTKBASE
+ #error "Need base stack size for varargs functions."
+#endif
+
+/* Sometimes the stack pointer needs to munged a bit when storing
+ the list of arguments. */
+#ifndef QUICKTHREADS_VARGS_ADJUST
+#define QUICKTHREADS_VARGS_ADJUST(sp) (sp)
+#endif
+
+/* All things are put on the stack relative to the final value of
+ the stack pointer. */
+#ifdef QUICKTHREADS_GROW_DOWN
+#define QUICKTHREADS_VADJ(sp) (((char *)sp) - QUICKTHREADS_VSTKBASE)
+#else
+#define QUICKTHREADS_VADJ(sp) (((char *)sp) + QUICKTHREADS_VSTKBASE)
+#endif
+
+extern qt_t *qt_vargs (qt_t *sp, int nbytes, void *vargs,
+ void *pt, qt_startup_t *startup,
+ qt_vuserf_t *vuserf, qt_cleanup_t *cleanup);
+
+#ifndef QUICKTHREADS_VARGS
+#define QUICKTHREADS_VARGS(sp, nbytes, vargs, pt, startup, vuserf, cleanup) \
+ (qt_vargs (sp, nbytes, vargs, pt, startup, vuserf, cleanup))
+#endif
+
+#endif
+
+
+/* Save the state of the thread and call the helper function
+ using the stack of the new thread. */
+typedef void *(qt_helper_t)(qt_t *old, void *a0, void *a1);
+typedef void *(qt_block_t)(qt_helper_t *helper, void *a0, void *a1,
+ qt_t *newthread);
+
+/* Rearrange the parameters so that things passed to the helper
+ function are already in the right argument registers. */
+#ifndef QUICKTHREADS_ABORT
+extern void *qt_abort (qt_helper_t *h, void *a0, void *a1, qt_t *newthread);
+/* The following does, technically, `return' a value, but the
+ user had better not rely on it, since the function never
+ returns. */
+#define QUICKTHREADS_ABORT(h, a0, a1, newthread) \
+ do { qt_abort (h, a0, a1, newthread); } while (0)
+#endif
+
+#ifndef QUICKTHREADS_BLOCK
+extern void *qt_block (qt_helper_t *h, void *a0, void *a1,
+ qt_t *newthread);
+#define QUICKTHREADS_BLOCK(h, a0, a1, newthread) \
+ (qt_block (h, a0, a1, newthread))
+#endif
+
+#ifndef QUICKTHREADS_BLOCKI
+extern void *qt_blocki (qt_helper_t *h, void *a0, void *a1,
+ qt_t *newthread);
+#define QUICKTHREADS_BLOCKI(h, a0, a1, newthread) \
+ (qt_blocki (h, a0, a1, newthread))
+#endif
+
+#ifdef __cplusplus
+} /* Match `extern "C" {' at top. */
+#endif
+
+#endif // !defined(SC_USE_PTHREADS)
+#endif /* ndef QUICKTHREADS_H */
diff --git a/ext/systemc/src/sysc/qt/qtmd.h b/ext/systemc/src/sysc/qt/qtmd.h
new file mode 100644
index 000000000..f33203815
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/qtmd.h
@@ -0,0 +1,13 @@
+#if defined( __sparc ) || defined( __sparc__ )
+#include "sysc/qt/md/sparc.h"
+#elif defined( __hppa )
+#include "sysc/qt/md/hppa.h"
+#elif defined( __x86_64__ )
+#include "sysc/qt/md/iX86_64.h"
+#elif defined( __i386 )
+#include "sysc/qt/md/i386.h"
+#elif defined( __ppc__ )
+#include "sysc/qt/md/powerpc_mach.h"
+#elif defined( __powerpc )
+#include "sysc/qt/md/powerpc_sys5.h"
+#endif
diff --git a/ext/systemc/src/sysc/qt/stp.c b/ext/systemc/src/sysc/qt/stp.c
new file mode 100644
index 000000000..bfacc893b
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/stp.c
@@ -0,0 +1,199 @@
+#include "copyright.h"
+#include "qt.h"
+#include "stp.h"
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#define STP_STKSIZE (0x1000)
+
+/* `alignment' must be a power of 2. */
+#define STP_STKALIGN(sp, alignment) \
+ ((void *)((((qt_word_t)(sp)) + (alignment) - 1) & ~((alignment)-1)))
+
+
+/* The notion of a thread is merged with the notion of a queue.
+ Thread stuff: thread status (sp) and stuff to use during
+ (re)initialization. Queue stuff: next thread in the queue
+ (next). */
+
+struct stp_t {
+ qt_t *sp; /* QuickThreads handle. */
+ void *sto; /* `malloc'-allocated stack. */
+ struct stp_t *next; /* Next thread in the queue. */
+};
+
+
+/* A queue is a circular list of threads. The queue head is a
+ designated list element. If this is a uniprocessor-only
+ implementation we can store the `main' thread in this, but in a
+ multiprocessor there are several `heavy' threads but only one run
+ queue. A fancier implementation might have private run queues,
+ which would lead to a simpler (trivial) implementation */
+
+typedef struct stp_q_t {
+ stp_t t;
+ stp_t *tail;
+} stp_q_t;
+
+
+ /* Helper functions. */
+
+extern void *malloc (unsigned size);
+extern void perror (char const *msg);
+extern void free (void *sto);
+
+ void *
+xmalloc (unsigned size)
+{
+ void *sto;
+
+ sto = malloc (size);
+ if (!sto) {
+ perror ("malloc");
+ exit (1);
+ }
+ return (sto);
+}
+
+ /* Queue access functions. */
+
+ static void
+stp_qinit (stp_q_t *q)
+{
+ q->t.next = q->tail = &q->t;
+}
+
+
+ static stp_t *
+stp_qget (stp_q_t *q)
+{
+ stp_t *t;
+
+ t = q->t.next;
+ q->t.next = t->next;
+ if (t->next == &q->t) {
+ if (t == &q->t) { /* If it was already empty .. */
+ return (NULL); /* .. say so. */
+ }
+ q->tail = &q->t; /* Else now it is empty. */
+ }
+ return (t);
+}
+
+
+ static void
+stp_qput (stp_q_t *q, stp_t *t)
+{
+ q->tail->next = t;
+ t->next = &q->t;
+ q->tail = t;
+}
+
+
+ /* Thread routines. */
+
+static stp_q_t stp_global_runq; /* A queue of runable threads. */
+static stp_t stp_global_main; /* Thread for the process. */
+static stp_t *stp_global_curr; /* Currently-executing thread. */
+
+static void *stp_starthelp (qt_t *old, void *ignore0, void *ignore1);
+static void stp_only (void *pu, void *pt, qt_userf_t *f);
+static void *stp_aborthelp (qt_t *sp, void *old, void *null);
+static void *stp_yieldhelp (qt_t *sp, void *old, void *blockq);
+
+
+ void
+stp_init()
+{
+ stp_qinit (&stp_global_runq);
+}
+
+
+ void
+stp_start()
+{
+ stp_t *next;
+
+ while ((next = stp_qget (&stp_global_runq)) != NULL) {
+ stp_global_curr = next;
+ QT_BLOCK (stp_starthelp, 0, 0, next->sp);
+ }
+}
+
+
+ static void *
+stp_starthelp (qt_t *old, void *ignore0, void *ignore1)
+{
+ stp_global_main.sp = old;
+ stp_qput (&stp_global_runq, &stp_global_main);
+ /* return (garbage); */
+}
+
+
+ void
+stp_create (stp_userf_t *f, void *pu)
+{
+ stp_t *t;
+ void *sto;
+
+ t = xmalloc (sizeof(stp_t));
+ t->sto = xmalloc (STP_STKSIZE);
+ sto = STP_STKALIGN (t->sto, QT_STKALIGN);
+ t->sp = QT_SP (sto, STP_STKSIZE - QT_STKALIGN);
+ t->sp = QT_ARGS (t->sp, pu, t, (qt_userf_t *)f, stp_only);
+ stp_qput (&stp_global_runq, t);
+}
+
+
+ static void
+stp_only (void *pu, void *pt, qt_userf_t *f)
+{
+ stp_global_curr = (stp_t *)pt;
+ (*(stp_userf_t *)f)(pu);
+ stp_abort();
+ /* NOTREACHED */
+}
+
+
+ void
+stp_abort (void)
+{
+ stp_t *old, *newthread;
+
+ newthread = stp_qget (&stp_global_runq);
+ old = stp_global_curr;
+ stp_global_curr = newthread;
+ QT_ABORT (stp_aborthelp, old, (void *)NULL, newthread->sp);
+}
+
+
+ static void *
+stp_aborthelp (qt_t *sp, void *old, void *null)
+{
+ free (((stp_t *)old)->sto);
+ free (old);
+ /* return (garbage); */
+}
+
+
+ void
+stp_yield()
+{
+ stp_t *old, *newthread;
+
+ newthread = stp_qget (&stp_global_runq);
+ old = stp_global_curr;
+ stp_global_curr = newthread;
+ QT_BLOCK (stp_yieldhelp, old, &stp_global_runq, newthread->sp);
+}
+
+
+ static void *
+stp_yieldhelp (qt_t *sp, void *old, void *blockq)
+{
+ ((stp_t *)old)->sp = sp;
+ stp_qput ((stp_q_t *)blockq, (stp_t *)old);
+ /* return (garbage); */
+}
diff --git a/ext/systemc/src/sysc/qt/stp.h b/ext/systemc/src/sysc/qt/stp.h
new file mode 100644
index 000000000..1220e47e2
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/stp.h
@@ -0,0 +1,51 @@
+#ifndef STP_H
+#define STP_H
+
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+typedef struct stp_t stp_t;
+
+/* Each thread starts by calling a user-supplied function of this
+ type. */
+
+typedef void (stp_userf_t)(void *p0);
+
+/* Call this before any other primitives. */
+extern void stp_init();
+
+/* When one or more threads are created by the main thread,
+ the system goes multithread when this is called. It is done
+ (no more runable threads) when this returns. */
+
+extern void stp_start (void);
+
+/* Create a thread and make it runable. When the thread starts
+ running it will call `f' with arguments `p0' and `p1'. */
+
+extern void stp_create (stp_userf_t *f, void *p0);
+
+/* The current thread stops running but stays runable.
+ It is an error to call `stp_yield' before `stp_start'
+ is called or after `stp_start' returns. */
+
+extern void stp_yield (void);
+
+/* Like `stp_yield' but the thread is discarded. Any intermediate
+ state is lost. The thread can also terminate by simply
+ returning. */
+
+extern void stp_abort (void);
+
+
+#endif /* ndef STP_H */
diff --git a/ext/systemc/src/sysc/qt/time/README.time b/ext/systemc/src/sysc/qt/time/README.time
new file mode 100644
index 000000000..4bb190e18
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/time/README.time
@@ -0,0 +1,17 @@
+The program `raw', when run in `..' runs the program `run' produced
+from `meas.c'. It produces a raw output file (see `../tmp/*.raw').
+`raw' will die with an error if run in the current directory. Note
+that some versions of `time' produce output in an unexpected format;
+edit them by hand.
+
+`prim', `init', `cswap' and `go' produce formatted table entries used
+in the documentation (in `../doc'). For example, from `..',
+
+ foreach i (tmp/*.raw)
+ time/prim $i
+ end
+
+See notes in the QuickThreads document about the applicability of
+these microbenchmark measurements -- in general, you can expect all
+QuickThreads operations to be a bit slower when used in a real
+application.
diff --git a/ext/systemc/src/sysc/qt/time/assim b/ext/systemc/src/sysc/qt/time/assim
new file mode 100755
index 000000000..6c4c52183
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/time/assim
@@ -0,0 +1,42 @@
+#! /bin/awk -f
+
+BEGIN {
+ nmach = 0;
+
+ init_test = "1";
+ abort_test = "6";
+ blocki_test = "7";
+ block_test = "8";
+}
+
+{
+ mach = $1
+ test = $2
+ iter = $3
+ time = $6 + $8
+
+ if (machi[mach] == 0) {
+ machn[nmach] = mach;
+ machi[mach] = 1;
+ ++nmach;
+ }
+
+ us_per_op = time / iter * 1000000
+ times[mach "_" test] = us_per_op;
+}
+
+
+END {
+ for (i=0; i<nmach; ++i) {
+ m = machn[i];
+ init = times[m "_" init_test];
+ printf ("init %s | %f\n", m, init);
+
+ init_abort_blocki = times[m "_" abort_test];
+ abort_blocki = init_abort_blocki - init;
+ blocki = times[m "_" blocki_test];
+ abort = abort_blocki - blocki;
+ blockf = times[m "_" block_test];
+ printf ("swap %s | %f | %f | %f\n", m, abort, blocki, blockf);
+ }
+}
diff --git a/ext/systemc/src/sysc/qt/time/cswap b/ext/systemc/src/sysc/qt/time/cswap
new file mode 100755
index 000000000..0ec811bcd
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/time/cswap
@@ -0,0 +1,37 @@
+#! /bin/awk -f
+
+BEGIN {
+ purpose = "report time used by int only and int+fp cswaps";
+
+ nmach = 0;
+
+ test_int = "7";
+ test_fp = "8";
+}
+
+{
+ mach = $1
+ test = $2
+ iter = $3
+ time = $6 + $8
+
+ if (machi[mach] == 0) {
+ machn[nmach] = mach;
+ machi[mach] = 1;
+ ++nmach;
+ }
+
+ us_per_op = time / iter * 1000000
+ times[mach "_" test] = us_per_op;
+}
+
+
+END {
+ for (i=0; i<nmach; ++i) {
+ m = machn[i];
+
+ integer = times[m "_" test_int];
+ fp = times[m "_" test_fp];
+ printf ("%s|%3.1f|%3.1f\n", m, integer, fp);
+ }
+}
diff --git a/ext/systemc/src/sysc/qt/time/go b/ext/systemc/src/sysc/qt/time/go
new file mode 100755
index 000000000..489d53882
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/time/go
@@ -0,0 +1,43 @@
+#! /bin/awk -f
+
+BEGIN {
+ purpose = "report times used for init/start/stop";
+
+ nmach = 0;
+
+ test_single = "6";
+ test_v0 = "10";
+ test_v2 = "11";
+ test_v4 = "12";
+ test_v8 = "13";
+}
+
+{
+ mach = $1
+ test = $2
+ iter = $3
+ time = $6 + $8
+
+ if (machi[mach] == 0) {
+ machn[nmach] = mach;
+ machi[mach] = 1;
+ ++nmach;
+ }
+
+ us_per_op = time / iter * 1000000
+ times[mach "_" test] = us_per_op;
+}
+
+
+END {
+ for (i=0; i<nmach; ++i) {
+ m = machn[i];
+
+ single = times[m "_" test_single];
+ v0 = times[m "_" test_v0];
+ v2 = times[m "_" test_v2];
+ v4 = times[m "_" test_v4];
+ v8 = times[m "_" test_v8];
+ printf ("%s|%3.1f|%3.1f|%3.1f|%3.1f|%3.1f\n", m, single, v0, v2, v4, v8);
+ }
+}
diff --git a/ext/systemc/src/sysc/qt/time/init b/ext/systemc/src/sysc/qt/time/init
new file mode 100755
index 000000000..8bcbf3428
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/time/init
@@ -0,0 +1,42 @@
+#! /bin/awk -f
+
+BEGIN {
+ purpose = "Report time used to initialize a thread."
+ nmach = 0;
+
+ test_single = "1";
+ test_v0 = "14";
+ test_v2 = "15";
+ test_v4 = "16";
+ test_v8 = "17";
+}
+
+{
+ mach = $1
+ test = $2
+ iter = $3
+ time = $6 + $8
+
+ if (machi[mach] == 0) {
+ machn[nmach] = mach;
+ machi[mach] = 1;
+ ++nmach;
+ }
+
+ us_per_op = time / iter * 1000000
+ times[mach "_" test] = us_per_op;
+}
+
+
+END {
+ for (i=0; i<nmach; ++i) {
+ m = machn[i];
+
+ single = times[m "_" test_single];
+ v0 = times[m "_" test_v0];
+ v2 = times[m "_" test_v2];
+ v4 = times[m "_" test_v4];
+ v8 = times[m "_" test_v8];
+ printf ("%s|%3.1f|%3.1f|%3.1f|%3.1f|%3.1f\n", m, single, v0, v2, v4, v8);
+ }
+}
diff --git a/ext/systemc/src/sysc/qt/time/prim b/ext/systemc/src/sysc/qt/time/prim
new file mode 100755
index 000000000..22b323f6f
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/time/prim
@@ -0,0 +1,41 @@
+#! /bin/awk -f
+
+BEGIN {
+ purpose = "report times for microbenchmarks"
+
+ nmach = 0;
+
+ test_callind = "18";
+ test_callimm = "18";
+ test_addreg = "20";
+ test_loadreg = "21";
+}
+
+{
+ mach = $1
+ test = $2
+ iter = $3
+ time = $6 + $8
+
+ if (machi[mach] == 0) {
+ machn[nmach] = mach;
+ machi[mach] = 1;
+ ++nmach;
+ }
+
+ ns_per_op = time / iter * 1000000
+ times[mach "_" test] = ns_per_op;
+}
+
+
+END {
+ for (i=0; i<nmach; ++i) {
+ m = machn[i];
+
+ ind = times[m "_" test_callind];
+ imm = times[m "_" test_callimm];
+ add = times[m "_" test_addreg];
+ load = times[m "_" test_loadreg];
+ printf ("%s|%1.3f|%1.3f|%1.3f|%1.3f\n", m, ind, imm, add, load);
+ }
+}
diff --git a/ext/systemc/src/sysc/qt/time/raw b/ext/systemc/src/sysc/qt/time/raw
new file mode 100755
index 000000000..96ae10ad1
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/time/raw
@@ -0,0 +1,58 @@
+#! /bin/csh
+
+rm -f timed
+
+set init=1
+set runone=6
+set blockint=7
+set blockfloat=8
+set vainit0=14
+set vainit2=15
+set vainit4=16
+set vainit8=17
+set vastart0=10
+set vastart2=11
+set vastart4=12
+set vastart8=13
+set bench_regcall=18
+set bench_immcall=19
+set bench_add=20
+set bench_load=21
+
+source configuration
+
+echo -n $config_machine $init $config_init
+/bin/time run $init $config_init
+echo -n $config_machine $runone $config_runone
+/bin/time run $runone $config_runone
+echo -n $config_machine $blockint $config_blockint
+/bin/time run $blockint $config_blockint
+echo -n $config_machine $blockfloat $config_blockfloat
+/bin/time run $blockfloat $config_blockfloat
+
+echo -n $config_machine $vainit0 $config_vainit0
+/bin/time run $vainit0 $config_vainit0
+echo -n $config_machine $vainit2 $config_vainit2
+/bin/time run $vainit2 $config_vainit2
+echo -n $config_machine $vainit4 $config_vainit4
+/bin/time run $vainit4 $config_vainit4
+echo -n $config_machine $vainit8 $config_vainit8
+/bin/time run $vainit8 $config_vainit8
+
+echo -n $config_machine $vastart0 $config_vastart0
+/bin/time run $vastart0 $config_vastart0
+echo -n $config_machine $vastart2 $config_vastart2
+/bin/time run $vastart2 $config_vastart2
+echo -n $config_machine $vastart4 $config_vastart4
+/bin/time run $vastart4 $config_vastart4
+echo -n $config_machine $vastart8 $config_vastart8
+/bin/time run $vastart8 $config_vastart8
+
+echo -n $config_machine $bench_regcall $config_bcall_reg
+/bin/time run $bench_regcall $config_bcall_reg
+echo -n $config_machine $bench_immcall $config_bcall_imm
+/bin/time run $bench_immcall $config_bcall_imm
+echo -n $config_machine $bench_add $config_b_add
+/bin/time run $bench_add $config_b_add
+echo -n $config_machine $bench_load $config_b_load
+/bin/time run $bench_load $config_b_load
diff --git a/ext/systemc/src/sysc/systemc.pc.in b/ext/systemc/src/sysc/systemc.pc.in
new file mode 100644
index 000000000..63d2e3cb7
--- /dev/null
+++ b/ext/systemc/src/sysc/systemc.pc.in
@@ -0,0 +1,41 @@
+# Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+# more contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright ownership.
+# Accellera licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# -------------------------------------------------------------------------
+#
+# systemc.pc.in --
+# pkg-config definition file (template) for SystemC
+# (http://www.freedesktop.org/wiki/Software/pkg-config/)
+#
+# Author: Philipp A. Hartmann, OFFIS, 2013-05-07
+#
+# Note: The "real" definition (systemc.pc) is generated by "configure"
+# during the build configuration.
+#
+# -------------------------------------------------------------------------
+#
+TARGET_ARCH=@TARGET_ARCH@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libarchdir=@libdir@@LIB_ARCH_SUFFIX@
+includedir=@includedir@
+
+Name: @PACKAGE_NAME@
+Description: Accellera @PACKAGE_NAME@ proof-of-concept library
+Version: @PACKAGE_VERSION@
+URL: @PACKAGE_URL@
+Libs: -L${libarchdir} -l@PACKAGE@
+Libs.private: @PKGCONFIG_LDPRIV@
+Cflags: @PKGCONFIG_CFLAGS@ @PKGCONFIG_DEFINES@ -I${includedir}
diff --git a/ext/systemc/src/sysc/tracing/sc_trace.cpp b/ext/systemc/src/sysc/tracing/sc_trace.cpp
new file mode 100644
index 000000000..09a2fa3b2
--- /dev/null
+++ b/ext/systemc/src/sysc/tracing/sc_trace.cpp
@@ -0,0 +1,217 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_trace.cpp - Functions for tracing signals and variables.
+
+ Original Author: Abhijit Ghosh, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ Acknowledgement: The tracing mechanism is based on the tracing
+ mechanism developed at Infineon (formerly Siemens HL). Though this
+ code is somewhat different, the basics are identical to what was
+ originally contributed by Infineon. The contribution of Infineon
+ in the development of this tracing technology is hereby
+ acknowledged.
+
+ *****************************************************************************/
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "sysc/tracing/sc_trace.h"
+#include "sysc/tracing/sc_tracing_ids.h"
+#include "sysc/communication/sc_signal_ifs.h"
+#include "sysc/utils/sc_report.h"
+#include "sysc/utils/sc_utils_ids.h"
+
+namespace sc_core {
+
+// Trace file common functions.
+
+sc_trace_file::sc_trace_file()
+{
+ /* Intentionally blank */
+}
+
+void tprintf(sc_trace_file* tf, const char* format, ...)
+{
+ static char buffer[4096];
+ va_list ap;
+ va_start(ap, format);
+ (void) vsprintf(buffer, format, ap);
+ va_end(ap);
+ if (tf) tf->write_comment(buffer);
+}
+
+void sc_trace_file::space(int)
+{
+ /* Intentionally blank */
+}
+
+void sc_trace_file::delta_cycles(bool)
+{
+ /* Intentionally blank */
+}
+
+
+void
+sc_trace( sc_trace_file* tf,
+ const sc_signal_in_if<char>& object,
+ const std::string& name,
+ int width )
+{
+ if( tf ) {
+ tf->trace( object.read(), name, width );
+ }
+}
+
+void
+sc_trace( sc_trace_file* tf,
+ const sc_signal_in_if<short>& object,
+ const std::string& name,
+ int width )
+{
+ if( tf ) {
+ tf->trace( object.read(), name, width );
+ }
+}
+
+void
+sc_trace( sc_trace_file* tf,
+ const sc_signal_in_if<int>& object,
+ const std::string& name,
+ int width )
+{
+ if( tf ) {
+ tf->trace( object.read(), name, width );
+ }
+}
+
+void
+sc_trace( sc_trace_file* tf,
+ const sc_signal_in_if<long>& object,
+ const std::string& name,
+ int width )
+{
+ if( tf ) {
+ tf->trace( object.read(), name, width );
+ }
+}
+
+
+void
+sc_trace(sc_trace_file* /* not used */,
+ const void* /* not used */,
+ const std::string& name)
+{
+ SC_REPORT_WARNING( SC_ID_TRACING_OBJECT_IGNORED_, name.c_str() );
+}
+
+
+
+void double_to_special_int64(double in, unsigned* high, unsigned* low)
+{
+ double invar = in;
+ if(invar > 5e17) invar = 5e17; // Saturation limit
+ if(invar < 0.0) invar = 0.0;
+ invar += .5;
+ *high = (unsigned)(invar / 1e9);
+ double rest = invar - 1e9 * (*high);
+ if(rest < 0) *low = 0;
+ else *low = (unsigned)rest;
+}
+
+
+// ----------------------------------------------------------------------------
+
+#define DEFN_TRACE_FUNC_REF_A(tp) \
+void \
+sc_trace( sc_trace_file* tf, const tp& object, const std::string& name ) \
+{ \
+ if( tf ) { \
+ tf->trace( object, name ); \
+ } \
+}
+
+#define DEFN_TRACE_FUNC_PTR_A(tp) \
+void \
+sc_trace( sc_trace_file* tf, const tp* object, const std::string& name ) \
+{ \
+ if( tf ) { \
+ tf->trace( *object, name ); \
+ } \
+}
+
+#define DEFN_TRACE_FUNC_A(tp) \
+DEFN_TRACE_FUNC_REF_A(tp) \
+DEFN_TRACE_FUNC_PTR_A(tp)
+
+
+DEFN_TRACE_FUNC_A( sc_dt::sc_bit )
+DEFN_TRACE_FUNC_A( sc_dt::sc_logic )
+
+DEFN_TRACE_FUNC_A( sc_dt::sc_int_base )
+DEFN_TRACE_FUNC_A( sc_dt::sc_uint_base )
+DEFN_TRACE_FUNC_A( sc_dt::sc_signed )
+DEFN_TRACE_FUNC_A( sc_dt::sc_unsigned )
+
+DEFN_TRACE_FUNC_REF_A( sc_dt::sc_bv_base )
+DEFN_TRACE_FUNC_REF_A( sc_dt::sc_lv_base )
+
+
+#undef DEFN_TRACE_FUNC_REF_A
+#undef DEFN_TRACE_FUNC_PTR_A
+#undef DEFN_TRACE_FUNC_A
+
+
+void
+sc_trace( sc_trace_file* tf,
+ const unsigned int& object,
+ const std::string& name,
+ const char** enum_literals )
+{
+ static bool warn_sc_trace_literals=true;
+ if ( warn_sc_trace_literals )
+ {
+ warn_sc_trace_literals=false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "tracing of enumerated literals is deprecated" );
+ }
+
+ if( tf ) tf->trace( object, name, enum_literals );
+}
+
+} // namespace sc_core
+
+// Taf!
diff --git a/ext/systemc/src/sysc/tracing/sc_trace.h b/ext/systemc/src/sysc/tracing/sc_trace.h
new file mode 100644
index 000000000..256e430a7
--- /dev/null
+++ b/ext/systemc/src/sysc/tracing/sc_trace.h
@@ -0,0 +1,397 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_trace.h - Functions for tracing signals and variables.
+
+ Author: Abhijit Ghosh, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ Acknowledgement: The tracing mechanism is based on the tracing
+ mechanism developed at Infineon (formerly Siemens HL). Though this
+ code is somewhat different, the basics are identical to what was
+ originally contributed by Infineon. The contribution of Infineon
+ in the development of this tracing technology is hereby
+ acknowledged.
+
+ *****************************************************************************/
+
+#ifndef SC_TRACE_H
+#define SC_TRACE_H
+
+#include <cstdio>
+
+#include "sysc/datatypes/int/sc_nbdefs.h"
+#include "sysc/kernel/sc_time.h"
+
+// Some forward declarations
+namespace sc_dt
+{
+ class sc_bit;
+ class sc_logic;
+ class sc_bv_base;
+ class sc_lv_base;
+ class sc_signed;
+ class sc_unsigned;
+ class sc_int_base;
+ class sc_uint_base;
+ class sc_fxval;
+ class sc_fxval_fast;
+ class sc_fxnum;
+ class sc_fxnum_fast;
+}
+
+namespace sc_core {
+
+class sc_time;
+
+template <class T> class sc_signal_in_if;
+
+
+// Base class for all kinds of trace files.
+
+class sc_trace_file
+{
+ friend class sc_simcontext;
+
+public:
+
+ // Constructor
+ sc_trace_file();
+
+ // All functions are pure virtual because they need to be defined by the
+ // particular tracing mechanism
+
+
+#define DECL_TRACE_METHOD_A(tp) \
+ virtual void trace( const tp& object, \
+ const std::string& name ) = 0;
+
+#define DECL_TRACE_METHOD_B(tp) \
+ virtual void trace( const tp& object, \
+ const std::string& name, \
+ int width ) = 0;
+
+
+ DECL_TRACE_METHOD_A( bool )
+ DECL_TRACE_METHOD_A( sc_dt::sc_bit )
+ DECL_TRACE_METHOD_A( sc_dt::sc_logic )
+
+ DECL_TRACE_METHOD_B( unsigned char )
+ DECL_TRACE_METHOD_B( unsigned short )
+ DECL_TRACE_METHOD_B( unsigned int )
+ DECL_TRACE_METHOD_B( unsigned long )
+ DECL_TRACE_METHOD_B( char )
+ DECL_TRACE_METHOD_B( short )
+ DECL_TRACE_METHOD_B( int )
+ DECL_TRACE_METHOD_B( long )
+ DECL_TRACE_METHOD_B( sc_dt::int64 )
+ DECL_TRACE_METHOD_B( sc_dt::uint64 )
+
+ DECL_TRACE_METHOD_A( float )
+ DECL_TRACE_METHOD_A( double )
+ DECL_TRACE_METHOD_A( sc_dt::sc_int_base )
+ DECL_TRACE_METHOD_A( sc_dt::sc_uint_base )
+ DECL_TRACE_METHOD_A( sc_dt::sc_signed )
+ DECL_TRACE_METHOD_A( sc_dt::sc_unsigned )
+
+ DECL_TRACE_METHOD_A( sc_dt::sc_fxval )
+ DECL_TRACE_METHOD_A( sc_dt::sc_fxval_fast )
+ DECL_TRACE_METHOD_A( sc_dt::sc_fxnum )
+ DECL_TRACE_METHOD_A( sc_dt::sc_fxnum_fast )
+
+ DECL_TRACE_METHOD_A( sc_dt::sc_bv_base )
+ DECL_TRACE_METHOD_A( sc_dt::sc_lv_base )
+
+
+#undef DECL_TRACE_METHOD_A
+#undef DECL_TRACE_METHOD_B
+
+ // Trace an enumerated object - where possible output the enumeration
+ // literals in the trace file. Enum literals is a null terminated array
+ // of null terminated char* literal strings.
+ virtual void trace( const unsigned int& object,
+ const std::string& name,
+ const char** enum_literals ) = 0;
+
+ // Output a comment to the trace file
+ virtual void write_comment( const std::string& comment ) = 0;
+
+ // Set the amount of space before next column
+ // (For most formats this does nothing)
+ virtual void space( int n );
+
+ // Also trace transitions between delta cycles if flag is true.
+ virtual void delta_cycles( bool flag );
+
+ // Set time unit.
+ virtual void set_time_unit( double v, sc_time_unit tu )=0;
+
+protected:
+
+ // Write trace info for cycle
+ virtual void cycle( bool delta_cycle ) = 0;
+
+ // Flush results and close file
+ virtual ~sc_trace_file()
+ { /* Intentionally blank */ }
+};
+
+/*****************************************************************************/
+
+// Now comes all the SystemC defined tracing functions.
+// We define two sc_trace() versions for scalar types; one where the object to
+// be traced is passed as a reference and the other where a pointer to the
+// tracing object is passed.
+
+#define DECL_TRACE_FUNC_REF_A(tp) \
+void \
+sc_trace( sc_trace_file* tf, \
+ const tp& object, \
+ const std::string& name );
+
+#define DECL_TRACE_FUNC_PTR_A(tp) \
+void \
+sc_trace( sc_trace_file* tf, \
+ const tp* object, \
+ const std::string& name ); \
+
+#define DECL_TRACE_FUNC_A(tp) \
+DECL_TRACE_FUNC_REF_A(tp) \
+DECL_TRACE_FUNC_PTR_A(tp)
+
+
+DECL_TRACE_FUNC_A( sc_dt::sc_bit )
+DECL_TRACE_FUNC_A( sc_dt::sc_logic )
+
+DECL_TRACE_FUNC_A( sc_dt::sc_int_base )
+DECL_TRACE_FUNC_A( sc_dt::sc_uint_base )
+DECL_TRACE_FUNC_A( sc_dt::sc_signed )
+DECL_TRACE_FUNC_A( sc_dt::sc_unsigned )
+
+DECL_TRACE_FUNC_REF_A( sc_dt::sc_bv_base )
+DECL_TRACE_FUNC_REF_A( sc_dt::sc_lv_base )
+
+
+#undef DECL_TRACE_FUNC_REF_A
+#undef DECL_TRACE_FUNC_PTR_A
+#undef DECL_TRACE_FUNC_A
+
+
+// ----------------------------------------------------------------------------
+
+#define DEFN_TRACE_FUNC_REF_A(tp) \
+inline \
+void \
+sc_trace( sc_trace_file* tf, const tp& object, const std::string& name ) \
+{ \
+ if( tf ) { \
+ tf->trace( object, name ); \
+ } \
+}
+
+#define DEFN_TRACE_FUNC_PTR_A(tp) \
+inline \
+void \
+sc_trace( sc_trace_file* tf, const tp* object, const std::string& name ) \
+{ \
+ if( tf ) { \
+ tf->trace( *object, name ); \
+ } \
+}
+
+#define DEFN_TRACE_FUNC_A(tp) \
+DEFN_TRACE_FUNC_REF_A(tp) \
+DEFN_TRACE_FUNC_PTR_A(tp)
+
+
+#define DEFN_TRACE_FUNC_REF_B(tp) \
+inline \
+void \
+sc_trace( sc_trace_file* tf, const tp& object, const std::string& name, \
+ int width = 8 * sizeof( tp ) ) \
+{ \
+ if( tf ) { \
+ tf->trace( object, name, width ); \
+ } \
+}
+
+#define DEFN_TRACE_FUNC_PTR_B(tp) \
+inline \
+void \
+sc_trace( sc_trace_file* tf, const tp* object, const std::string& name, \
+ int width = 8 * sizeof( tp ) ) \
+{ \
+ if( tf ) { \
+ tf->trace( *object, name, width ); \
+ } \
+}
+
+
+#define DEFN_TRACE_FUNC_B(tp) \
+DEFN_TRACE_FUNC_REF_B(tp) \
+DEFN_TRACE_FUNC_PTR_B(tp)
+
+
+DEFN_TRACE_FUNC_A( bool )
+DEFN_TRACE_FUNC_A( float )
+DEFN_TRACE_FUNC_A( double )
+
+DEFN_TRACE_FUNC_B( unsigned char )
+DEFN_TRACE_FUNC_B( unsigned short )
+DEFN_TRACE_FUNC_B( unsigned int )
+DEFN_TRACE_FUNC_B( unsigned long )
+DEFN_TRACE_FUNC_B( char )
+DEFN_TRACE_FUNC_B( short )
+DEFN_TRACE_FUNC_B( int )
+DEFN_TRACE_FUNC_B( long )
+DEFN_TRACE_FUNC_B( sc_dt::int64 )
+DEFN_TRACE_FUNC_B( sc_dt::uint64 )
+
+
+#undef DEFN_TRACE_FUNC_REF_A
+#undef DEFN_TRACE_FUNC_PTR_A
+#undef DEFN_TRACE_FUNC_A
+
+#undef DEFN_TRACE_FUNC_REF_B
+#undef DEFN_TRACE_FUNC_PTR_B
+#undef DEFN_TRACE_FUNC_B
+
+
+template <class T>
+inline
+void
+sc_trace( sc_trace_file* tf,
+ const sc_signal_in_if<T>& object,
+ const std::string& name )
+{
+ sc_trace( tf, object.read(), name );
+}
+
+template< class T >
+inline
+void
+sc_trace( sc_trace_file* tf,
+ const sc_signal_in_if<T>& object,
+ const char* name )
+{
+ sc_trace( tf, object.read(), name );
+}
+
+
+// specializations for signals of type char, short, int, long
+
+void sc_trace( sc_trace_file* tf,
+ const sc_signal_in_if<char>& object,
+ const std::string& name,
+ int width );
+
+void sc_trace( sc_trace_file* tf,
+ const sc_signal_in_if<short>& object,
+ const std::string& name,
+ int width );
+
+void sc_trace( sc_trace_file* tf,
+ const sc_signal_in_if<int>& object,
+ const std::string& name,
+ int width );
+
+void sc_trace( sc_trace_file* tf,
+ const sc_signal_in_if<long>& object,
+ const std::string& name,
+ int width );
+
+
+// 1. non-template function is better than template
+// 2. more-specialized template is better than less-specialized
+// 3. no partial specialization for template functions
+
+
+// Trace an enumerated object - where possible output the enumeration literals
+// in the trace file. Enum literals is a null terminated array of null
+// terminated char* literal strings.
+
+void
+sc_trace( sc_trace_file* tf,
+ const unsigned int& object,
+ const std::string& name,
+ const char** enum_literals );
+
+
+// Dummy function for arbitrary types of value, does nothing
+
+extern void sc_trace( sc_trace_file* tf,
+ const void* object,
+ const std::string& name );
+
+
+// Turn on/off delta cycle tracing on trace file `tf'.
+// Default is to turn on delta cycle tracing.
+
+inline
+void
+sc_trace_delta_cycles( sc_trace_file* tf, bool on = true )
+{
+ if( tf ) tf->delta_cycles( on );
+}
+
+
+// Output a comment to the trace file
+
+inline
+void
+sc_write_comment( sc_trace_file* tf, const std::string& comment )
+{
+ if( tf ) tf->write_comment( comment );
+}
+
+
+// Equivalent of std::fprintf for trace files!
+
+void tprintf( sc_trace_file* tf, const char* format, ... );
+
+// ----------------------------------------------------------------------------
+// Create VCD file
+extern sc_trace_file *sc_create_vcd_trace_file(const char* name);
+extern void sc_close_vcd_trace_file( sc_trace_file* tf );
+
+
+// ----------------------------------------------------------------------------
+// Create WIF file
+extern sc_trace_file *sc_create_wif_trace_file(const char *name);
+extern void sc_close_wif_trace_file( sc_trace_file* tf );
+
+} // namespace sc_core
+
+#endif // SC_TRACE_H
+// Taf
diff --git a/ext/systemc/src/sysc/tracing/sc_trace_file_base.cpp b/ext/systemc/src/sysc/tracing/sc_trace_file_base.cpp
new file mode 100644
index 000000000..4f4345468
--- /dev/null
+++ b/ext/systemc/src/sysc/tracing/sc_trace_file_base.cpp
@@ -0,0 +1,273 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_trace_file_base.cpp - Shared internal tracing implementation
+
+ Original Author: Philipp A. Hartmann, OFFIS, 2013-11-15
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ Acknowledgement: The tracing mechanism is based on the tracing
+ mechanism developed at Infineon (formerly Siemens HL). Though this
+ code is somewhat different, and significantly enhanced, the basics
+ are identical to what was originally contributed by Infineon. The
+ contribution of Infineon in the development of this tracing
+ technology is hereby acknowledged.
+
+ *****************************************************************************/
+
+#include <ctime>
+
+#include "sysc/tracing/sc_trace_file_base.h"
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_simcontext_int.h"
+
+#if SC_TRACING_PHASE_CALLBACKS_
+# include "sysc/kernel/sc_object_int.h"
+#endif
+
+namespace sc_core {
+
+bool sc_trace_file_base::tracing_initialized_ = false;
+
+
+sc_trace_file_base::sc_trace_file_base( const char* name, const char* extension )
+ : sc_trace_file()
+#if SC_TRACING_PHASE_CALLBACKS_
+ , sc_object( sc_gen_unique_name("$$$$kernel_tracefile$$$$") )
+#endif
+ , fp(0)
+ , timescale_unit()
+ , timescale_set_by_user(false)
+ , filename_()
+ , initialized_(false)
+ , trace_delta_cycles_(false)
+{
+ if( !name || !*name ) {
+ SC_REPORT_ERROR( SC_ID_TRACING_FOPEN_FAILED_, "no name given" );
+ return;
+ } else {
+ std::stringstream ss;
+ ss << name << "." << extension;
+ ss.str().swap( filename_ );
+ }
+
+#if SC_TRACING_PHASE_CALLBACKS_ == 1
+ // remove from hierarchy
+ sc_object::detach();
+ // register regular (non-delta) callbacks
+ sc_object::register_simulation_phase_callback(
+ // Note: Usually, one would expect to dump the initial values
+ // of the traced variables at the end of the initialization
+ // phase. The "non-callback" implementation dumps those
+ // values only after the first delta cycle, though.
+ // SC_END_OF_INITIALIZATION |
+ SC_BEFORE_TIMESTEP |
+ SC_PAUSED | SC_STOPPED
+ );
+#else // explicitly register with simcontext
+ sc_get_curr_simcontext()->add_trace_file( this );
+#endif
+}
+
+sc_trace_file_base::~sc_trace_file_base()
+{
+ if( fp )
+ fclose(fp);
+
+#if SC_TRACING_PHASE_CALLBACKS_ == 0
+ // unregister from simcontext
+ sc_get_curr_simcontext()->remove_trace_file( this );
+#endif
+}
+
+/*****************************************************************************/
+// simulation phase callback based trigger
+//
+// The tracing updates are triggered
+// (- at the end of the initialization phase [disabled for now])
+// - before an update of the simulation time
+// - before returning to sc_start (via sc_pause() or sc_stop())
+// - after an update phase (if delta cycles need to be traced)
+//
+#if SC_TRACING_PHASE_CALLBACKS_
+void
+sc_trace_file_base::simulation_phase_callback()
+{
+ // delta cycle is traced at the end of an update phase
+ cycle( simcontext()->get_status() == SC_END_OF_UPDATE );
+}
+#endif // SC_TRACING_PHASE_CALLBACKS_
+
+/*****************************************************************************/
+
+bool
+sc_trace_file_base::initialize()
+{
+ if( initialized_ )
+ return false;
+
+ initialized_ = true;
+
+ if( !tracing_initialized_ ) {
+ tracing_initialized_ = true;
+ bool running_regression = ( getenv( "SYSTEMC_REGRESSION" ) != NULL );
+
+ // hide some messages during regression
+ if( running_regression ) {
+ sc_report_handler::set_actions( SC_ID_TRACING_TIMESCALE_DEFAULT_
+ , SC_INFO, SC_DO_NOTHING );
+ sc_report_handler::set_actions( SC_ID_TRACING_VCD_DUPLICATE_TIME_
+ , SC_WARNING, SC_DO_NOTHING );
+ }
+ }
+
+ // open trace file
+ if(!fp) open_fp();
+
+ // setup timescale
+ if( !timescale_set_by_user )
+ {
+ timescale_unit = sc_get_time_resolution().to_seconds();
+
+ std::stringstream ss;
+ ss << sc_get_time_resolution() << " (" << filename_ << ")";
+ SC_REPORT_INFO( SC_ID_TRACING_TIMESCALE_DEFAULT_
+ , ss.str().c_str() );
+ }
+
+ // initialize derived tracing implementation class (VCD/WIF)
+ do_initialize();
+
+ return initialized_;
+}
+
+void
+sc_trace_file_base::open_fp()
+{
+ sc_assert( !fp );
+ fp = fopen( filename(), "w" );
+ if( !fp ) {
+ SC_REPORT_ERROR( SC_ID_TRACING_FOPEN_FAILED_, filename() );
+ std::terminate(); // can't recover from here
+ }
+}
+
+void
+sc_trace_file_base::delta_cycles( bool flag )
+{
+ trace_delta_cycles_ = flag;
+#if SC_TRACING_PHASE_CALLBACKS_
+ if( trace_delta_cycles_ ) {
+ sc_object::register_simulation_phase_callback( SC_END_OF_UPDATE );
+ } else {
+ sc_object::unregister_simulation_phase_callback( SC_END_OF_UPDATE );
+ }
+#endif
+}
+
+void
+sc_trace_file_base::set_time_unit( double v, sc_time_unit tu )
+{
+ if( initialized_ )
+ {
+ std::stringstream ss;
+ ss << filename_ << "\n"
+ "\tTimescale unit cannot be changed once tracing has begun.\n"
+ "\tTo change the scale, create a new trace file.";
+ SC_REPORT_ERROR( SC_ID_TRACING_ALREADY_INITIALIZED_
+ , ss.str().c_str() );
+ return;
+ }
+
+ switch ( tu )
+ {
+ case SC_FS: v = v * 1e-15; break;
+ case SC_PS: v = v * 1e-12; break;
+ case SC_NS: v = v * 1e-9; break;
+ case SC_US: v = v * 1e-6; break;
+ case SC_MS: v = v * 1e-3; break;
+ case SC_SEC: break;
+ default: {
+ std::stringstream ss;
+ ss << "unknown time unit:" << tu
+ << " (" << filename_ << ")";
+ SC_REPORT_WARNING( SC_ID_TRACING_TIMESCALE_UNIT_
+ , ss.str().c_str() );
+ }
+ }
+
+ timescale_set_by_user = true;
+ timescale_unit = v;
+
+ // EMIT ADVISORY MESSAGE ABOUT CHANGE IN TIME SCALE:
+ {
+ std::stringstream ss;
+ ss << sc_time( timescale_unit, SC_SEC )
+ << " (" << filename_ << ")";
+ SC_REPORT_INFO( SC_ID_TRACING_TIMESCALE_UNIT_, ss.str().c_str() );
+ }
+}
+
+bool
+sc_trace_file_base::add_trace_check( const std::string & name ) const
+{
+ if( !initialized_ ) return true;
+
+ std::stringstream ss;
+ ss << "sc_trace() failed:\n"
+ "\tNo traces can be added to "
+ "'" << filename_ << "'"
+ " once trace recording has started.\n"
+ "\tTo add tracing of '" << name << "', create a new trace file.";
+
+ SC_REPORT_ERROR( SC_ID_TRACING_ALREADY_INITIALIZED_
+ , ss.str().c_str() );
+ return false;
+}
+
+// obtain formatted time string
+std::string localtime_string()
+{
+ char buf[200];
+ time_t long_time;
+ time(&long_time);
+ struct tm* p_tm = localtime(&long_time);
+ strftime(buf, 199, "%b %d, %Y %H:%M:%S", p_tm);
+ return buf;
+}
+
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+// Taf!
diff --git a/ext/systemc/src/sysc/tracing/sc_trace_file_base.h b/ext/systemc/src/sysc/tracing/sc_trace_file_base.h
new file mode 100644
index 000000000..c0217266f
--- /dev/null
+++ b/ext/systemc/src/sysc/tracing/sc_trace_file_base.h
@@ -0,0 +1,140 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_trace_file_base.h - Shared internal tracing implementation
+
+ Original Author: Philipp A. Hartmann, OFFIS, 2013-11-15
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ Acknowledgement: The tracing mechanism is based on the tracing
+ mechanism developed at Infineon (formerly Siemens HL). Though this
+ code is somewhat different, and significantly enhanced, the basics
+ are identical to what was originally contributed by Infineon. The
+ contribution of Infineon in the development of this tracing
+ technology is hereby acknowledged.
+
+ *****************************************************************************/
+
+#ifndef SC_TRACE_FILE_BASE_H_INCLUDED_
+#define SC_TRACE_FILE_BASE_H_INCLUDED_
+
+#include <cstdio>
+
+// use callback-based tracing implementation
+#if defined( SC_ENABLE_SIMULATION_PHASE_CALLBACKS_TRACING )
+# define SC_TRACING_PHASE_CALLBACKS_ 1
+# include "sysc/kernel/sc_object.h"
+#else
+# define SC_TRACING_PHASE_CALLBACKS_ 0
+#endif
+
+#include "sysc/tracing/sc_trace.h"
+#include "sysc/tracing/sc_tracing_ids.h"
+
+namespace sc_core {
+
+// shared implementation of trace files
+class sc_trace_file_base
+ : public sc_trace_file
+#if SC_TRACING_PHASE_CALLBACKS_
+ , private sc_object // to be used as callback target
+#endif
+{
+public:
+ const char* filename() const
+ { return filename_.c_str(); }
+
+ bool delta_cycles() const
+ { return trace_delta_cycles_; }
+
+ // Also trace transitions between delta cycles if flag is true.
+ virtual void delta_cycles(bool flag);
+
+ // set a user-define timescale unit for the trace file
+ virtual void set_time_unit( double v, sc_time_unit tu);
+
+protected:
+ sc_trace_file_base( const char* name, const char* extension );
+
+ // returns true, iff initialization has been performed
+ bool initialize();
+ // ensure that file has been opened (needed for early write_comment())
+ void open_fp();
+ // perform format specific initialization
+ virtual void do_initialize() = 0;
+
+ // returns true, if new trace objects can still be added
+ // (i.e. trace file is not yet initialized)
+ bool add_trace_check( const std::string& name ) const;
+
+ // Flush results and close file.
+ virtual ~sc_trace_file_base();
+
+#if SC_TRACING_PHASE_CALLBACKS_
+private:
+ virtual void simulation_phase_callback();
+#endif // SC_TRACING_PHASE_CALLBACKS_
+
+protected:
+ FILE* fp; // pointer to the trace file
+ double timescale_unit; // in seconds
+ bool timescale_set_by_user; // = true means set by user
+
+private:
+ std::string filename_; // name of the file (for reporting)
+ bool initialized_; // tracing started?
+ bool trace_delta_cycles_; // also trace delta transitions?
+
+ static bool tracing_initialized_; // shared setup of tracing implementation
+
+private: // disabled
+ sc_trace_file_base( const sc_trace_file_base& ) /* = delete */;
+ sc_trace_file_base& operator=( const sc_trace_file_base& ) /* = delete */;
+
+}; // class sc_trace_file_base
+
+// -----------------------------------------------------------------------
+
+// Convert double time to 64-bit integer
+
+void double_to_special_int64( double in, unsigned* high, unsigned* low );
+
+// obtain formatted time string
+std::string localtime_string();
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+#endif // SC_TRACE_FILE_BASE_H_INCLUDED_
+// Taf!
diff --git a/ext/systemc/src/sysc/tracing/sc_tracing_ids.h b/ext/systemc/src/sysc/tracing/sc_tracing_ids.h
new file mode 100644
index 000000000..dacdb9451
--- /dev/null
+++ b/ext/systemc/src/sysc/tracing/sc_tracing_ids.h
@@ -0,0 +1,79 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_tracing_ids.h -- Report ids for the tracing code.
+
+ Original Author: Philipp A. Hartmann, OFFIS, 2013-11-17
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+#ifndef SC_TRACING_IDS_H
+#define SC_TRACING_IDS_H
+
+// ----------------------------------------------------------------------------
+// Report ids (tracing)
+//
+// Report ids in the range of 700-799.
+// ----------------------------------------------------------------------------
+
+#ifndef SC_DEFINE_MESSAGE
+#define SC_DEFINE_MESSAGE(id,unused1,unused2) \
+ namespace sc_core { extern const char id[]; }
+#endif
+
+SC_DEFINE_MESSAGE( SC_ID_TRACING_FOPEN_FAILED_, 701,
+ "cannot open tracefile for writing" )
+
+SC_DEFINE_MESSAGE( SC_ID_TRACING_TIMESCALE_DEFAULT_, 702,
+ "default timescale unit used for tracing" )
+SC_DEFINE_MESSAGE( SC_ID_TRACING_TIMESCALE_UNIT_, 703,
+ "tracing timescale unit set" )
+SC_DEFINE_MESSAGE( SC_ID_TRACING_VCD_DELTA_CYCLE_, 704,
+ "VCD delta cycle tracing with pseudo timesteps (1 unit)" )
+/* unused IDs 705-709 */
+SC_DEFINE_MESSAGE( SC_ID_TRACING_OBJECT_IGNORED_, 710,
+ "object cannot not be traced" )
+SC_DEFINE_MESSAGE( SC_ID_TRACING_OBJECT_NAME_FILTERED_, 711,
+ "traced object name filtered" )
+SC_DEFINE_MESSAGE( SC_ID_TRACING_INVALID_ENUM_VALUE_, 712,
+ "traced value of enumerated type undefined" )
+SC_DEFINE_MESSAGE( SC_ID_TRACING_VCD_DUPLICATE_TIME_, 713,
+ "multiple VCD tracing cycles with the same time detected" )
+SC_DEFINE_MESSAGE( SC_ID_TRACING_VCD_REVERSED_TIME_, 714,
+ "VCD tracing cycle with falling time detected" )
+/* unused IDs 715-719 */
+SC_DEFINE_MESSAGE( SC_ID_TRACING_ALREADY_INITIALIZED_, 720,
+ "sc_trace_file already initialized" )
+
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+#endif // SC_TRACING_IDS_H
+// Taf!
diff --git a/ext/systemc/src/sysc/tracing/sc_vcd_trace.cpp b/ext/systemc/src/sysc/tracing/sc_vcd_trace.cpp
new file mode 100644
index 000000000..616d6274d
--- /dev/null
+++ b/ext/systemc/src/sysc/tracing/sc_vcd_trace.cpp
@@ -0,0 +1,2175 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_vcd_trace.cpp - Implementation of VCD tracing.
+
+ Original Author - Abhijit Ghosh, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc.
+ Description of Modification: - Replaced 'width' of sc_(u)int with their
+ 'bitwidth()'.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ Acknowledgement: The tracing mechanism is based on the tracing
+ mechanism developed at Infineon (formerly Siemens HL). Though this
+ code is somewhat different, and significantly enhanced, the basics
+ are identical to what was originally contributed by Infineon. The
+ contribution of Infineon in the development of this tracing
+ technology is hereby acknowledged.
+
+ *****************************************************************************/
+
+
+#include <cstdlib>
+#include <string.h>
+#include <vector>
+
+#define SC_DISABLE_API_VERSION_CHECK // for in-library sc_ver.h inclusion
+
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_ver.h"
+#include "sysc/datatypes/bit/sc_bit.h"
+#include "sysc/datatypes/bit/sc_logic.h"
+#include "sysc/datatypes/bit/sc_lv_base.h"
+#include "sysc/datatypes/int/sc_signed.h"
+#include "sysc/datatypes/int/sc_unsigned.h"
+#include "sysc/datatypes/int/sc_int_base.h"
+#include "sysc/datatypes/int/sc_uint_base.h"
+#include "sysc/datatypes/fx/fx.h"
+#include "sysc/tracing/sc_vcd_trace.h"
+
+namespace sc_core {
+
+// Forward declarations for functions that come later in the file
+// Map sc_dt::sc_logic to printable VCD
+static char map_sc_logic_state_to_vcd_state(char in_char);
+
+// Remove name problems associated with [] in vcd names
+static void remove_vcd_name_problems(vcd_trace const* vcd, std::string& name);
+
+const char* vcd_types[vcd_trace_file::VCD_LAST]={"wire","real"};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : vcd_trace
+//
+// Base class for VCD traces.
+// ----------------------------------------------------------------------------
+
+class vcd_trace
+{
+public:
+
+ vcd_trace(const std::string& name_, const std::string& vcd_name_);
+
+ // Needs to be pure virtual as has to be defined by the particular
+ // type being traced
+ virtual void write(FILE* f) = 0;
+
+ virtual void set_width();
+
+ static const char* strip_leading_bits(const char* originalbuf);
+
+ // Comparison function needs to be pure virtual too
+ virtual bool changed() = 0;
+
+ // Make this virtual as some derived classes may overwrite
+ virtual void print_variable_declaration_line(FILE* f);
+
+ void compose_data_line(char* rawdata, char* compdata);
+ std::string compose_line(const std::string& data);
+
+ virtual ~vcd_trace();
+
+ const std::string name;
+ const std::string vcd_name;
+ const char* vcd_var_typ_name;
+ int bit_width;
+};
+
+
+vcd_trace::vcd_trace(const std::string& name_, const std::string& vcd_name_)
+: name(name_), vcd_name(vcd_name_), vcd_var_typ_name(0), bit_width(0)
+{
+ /* Intentionally blank */
+}
+
+void
+vcd_trace::compose_data_line(char* rawdata, char* compdata)
+{
+ sc_assert(rawdata != compdata);
+
+ if(bit_width == 0)
+ {
+ compdata[0] = '\0';
+ }
+ else
+ {
+ if(bit_width == 1)
+ {
+ compdata[0] = rawdata[0];
+ strcpy(&(compdata[1]), vcd_name.c_str());
+ }
+ else
+ {
+ const char* effective_begin = strip_leading_bits(rawdata);
+ std::sprintf(compdata, "b%s %s", effective_begin, vcd_name.c_str());
+ }
+ }
+}
+
+// same as above but not that ugly
+std::string
+vcd_trace::compose_line(const std::string& data)
+{
+ if(bit_width == 0)
+ return "";
+ if(bit_width == 1)
+ return data + vcd_name;
+ return std::string("b")+strip_leading_bits(data.c_str())+" "+vcd_name;
+}
+
+void
+vcd_trace::print_variable_declaration_line(FILE* f)
+{
+ char buf[2000];
+
+ if ( bit_width <= 0 )
+ {
+ std::stringstream ss;
+ ss << "'" << name << "' has 0 bits";
+ SC_REPORT_ERROR( SC_ID_TRACING_OBJECT_IGNORED_
+ , ss.str().c_str() );
+ return;
+ }
+
+ std::string namecopy = name;
+ remove_vcd_name_problems(this, namecopy);
+ if ( bit_width == 1 )
+ {
+ std::sprintf(buf, "$var %s % 3d %s %s $end\n",
+ vcd_var_typ_name,
+ bit_width,
+ vcd_name.c_str(),
+ namecopy.c_str());
+ }
+ else
+ {
+ std::sprintf(buf, "$var %s % 3d %s %s [%d:0] $end\n",
+ vcd_var_typ_name,
+ bit_width,
+ vcd_name.c_str(),
+ namecopy.c_str(),
+ bit_width-1);
+ }
+ std::fputs(buf, f);
+}
+
+void
+vcd_trace::set_width()
+{
+ /* Intentionally Blank, should be defined for each type separately */
+}
+
+const char*
+vcd_trace::strip_leading_bits(const char* originalbuf)
+{
+ //*********************************************************************
+ // - Remove multiple leading 0,z,x, and replace by only one
+ // - For example,
+ // b000z100 -> b0z100
+ // b00000xxx -> b0xxx
+ // b000 -> b0
+ // bzzzzz1 -> bz1
+ // bxxxz10 -> xz10
+ // - For leading 0's followed by 1, remove all leading 0's
+ // b0000010101 -> b10101
+
+ const char* position = originalbuf;
+
+ if( strlen(originalbuf) < 2 ||
+ (originalbuf[0] != 'z' && originalbuf[0] != 'x' &&
+ originalbuf[0] != '0' ))
+ return originalbuf;
+
+ char first_char = *position;
+ while(*position == first_char)
+ {
+ position++;
+ }
+
+ if(first_char == '0' && *position == '1')
+ return position;
+ // else
+ return position-1;
+}
+
+vcd_trace::~vcd_trace()
+{
+ /* Intentionally Blank */
+}
+
+
+template <class T>
+class vcd_T_trace : public vcd_trace
+{
+ public:
+
+ vcd_T_trace( const T& object_,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ vcd_trace_file::vcd_enum type_ )
+ : vcd_trace( name_, vcd_name_ ),
+ object( object_ ),
+ old_value( object_ )
+ {
+ vcd_var_typ_name = vcd_types[type_];
+ }
+
+ void write( FILE* f )
+ {
+ std::fprintf( f, "%s", compose_line( object.to_string() ).c_str() );
+ old_value = object;
+ }
+
+ bool changed()
+ { return !(object == old_value); }
+
+ void set_width()
+ { bit_width = object.length(); }
+
+protected:
+
+ const T& object;
+ T old_value;
+};
+
+typedef vcd_T_trace<sc_dt::sc_bv_base> vcd_sc_bv_trace;
+typedef vcd_T_trace<sc_dt::sc_lv_base> vcd_sc_lv_trace;
+
+// Trace sc_dt::sc_bv_base (sc_dt::sc_bv)
+void
+vcd_trace_file::trace(
+ const sc_dt::sc_bv_base& object, const std::string& name)
+{
+ traceT(object,name);
+}
+
+// Trace sc_dt::sc_lv_base (sc_dt::sc_lv)
+void
+vcd_trace_file::trace(
+ const sc_dt::sc_lv_base& object, const std::string& name)
+{
+ traceT(object,name);
+}
+
+/*****************************************************************************/
+
+class vcd_bool_trace : public vcd_trace {
+public:
+ vcd_bool_trace(const bool& object_,
+ const std::string& name_,
+ const std::string& vcd_name_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const bool& object;
+ bool old_value;
+};
+
+vcd_bool_trace::vcd_bool_trace(const bool& object_,
+ const std::string& name_,
+ const std::string& vcd_name_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_)
+{
+ vcd_var_typ_name = "wire";
+ bit_width = 1;
+}
+
+bool
+vcd_bool_trace::changed()
+{
+ return object != old_value;
+}
+
+void
+vcd_bool_trace::write(FILE* f)
+{
+ if (object == true) std::fputc('1', f);
+ else std::fputc('0', f);
+
+ std::fprintf(f,"%s", vcd_name.c_str());
+
+ old_value = object;
+}
+
+//*****************************************************************************
+
+class vcd_sc_bit_trace : public vcd_trace {
+public:
+ vcd_sc_bit_trace(const sc_dt::sc_bit& , const std::string& ,
+ const std::string& );
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const sc_dt::sc_bit& object;
+ sc_dt::sc_bit old_value;
+};
+
+vcd_sc_bit_trace::vcd_sc_bit_trace( const sc_dt::sc_bit& object_,
+ const std::string& name,
+ const std::string& vcd_name)
+: vcd_trace(name, vcd_name), object( object_ ), old_value( object_ )
+{
+ vcd_var_typ_name = "wire";
+ bit_width = 1;
+}
+
+bool
+vcd_sc_bit_trace::changed()
+{
+ return object != old_value;
+}
+
+void
+vcd_sc_bit_trace::write(FILE* f)
+{
+ if (object == true) std::fputc('1', f);
+ else std::fputc('0', f);
+
+ std::fprintf(f,"%s", vcd_name.c_str());
+
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class vcd_sc_logic_trace : public vcd_trace {
+public:
+ vcd_sc_logic_trace(const sc_dt::sc_logic& object_,
+ const std::string& name_,
+ const std::string& vcd_name_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const sc_dt::sc_logic& object;
+ sc_dt::sc_logic old_value;
+};
+
+
+vcd_sc_logic_trace::vcd_sc_logic_trace(const sc_dt::sc_logic& object_,
+ const std::string& name_,
+ const std::string& vcd_name_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_)
+{
+ vcd_var_typ_name = "wire";
+ bit_width = 1;
+}
+
+
+bool
+vcd_sc_logic_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void
+vcd_sc_logic_trace::write(FILE* f)
+{
+ char out_char;
+ out_char = map_sc_logic_state_to_vcd_state(object.to_char());
+ std::fputc(out_char, f);
+
+ std::fprintf(f,"%s", vcd_name.c_str());
+
+ old_value = object;
+}
+
+
+/*****************************************************************************/
+
+class vcd_sc_unsigned_trace : public vcd_trace {
+public:
+ vcd_sc_unsigned_trace(const sc_dt::sc_unsigned& object,
+ const std::string& name_,
+ const std::string& vcd_name_);
+ void write(FILE* f);
+ bool changed();
+ void set_width();
+
+protected:
+ const sc_dt::sc_unsigned& object;
+ sc_dt::sc_unsigned old_value;
+};
+
+
+vcd_sc_unsigned_trace::vcd_sc_unsigned_trace(const sc_dt::sc_unsigned& object_,
+ const std::string& name_,
+ const std::string& vcd_name_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_.length())
+// The last may look strange, but is correct
+{
+ vcd_var_typ_name = "wire";
+ old_value = object;
+}
+
+bool
+vcd_sc_unsigned_trace::changed()
+{
+ return object != old_value;
+}
+
+void
+vcd_sc_unsigned_trace::write(FILE* f)
+{
+ static std::vector<char> compdata(1024), rawdata(1024);
+ typedef std::vector<char>::size_type size_t;
+
+ if ( compdata.size() < (size_t)object.length() ) {
+ size_t sz = ( (size_t)object.length() + 4096 ) & (~(size_t)(4096-1));
+ std::vector<char>( sz ).swap( compdata ); // resize without copying values
+ std::vector<char>( sz ).swap( rawdata );
+ }
+ char *rawdata_ptr = &rawdata[0];
+
+ for (int bitindex = object.length() - 1; bitindex >= 0; --bitindex) {
+ *rawdata_ptr++ = "01"[object[bitindex].to_bool()];
+ }
+ *rawdata_ptr = '\0';
+ compose_data_line(&rawdata[0], &compdata[0]);
+
+ std::fputs(&compdata[0], f);
+ old_value = object;
+}
+
+void
+vcd_sc_unsigned_trace::set_width()
+{
+ bit_width = object.length();
+}
+
+
+/*****************************************************************************/
+
+class vcd_sc_signed_trace : public vcd_trace {
+public:
+ vcd_sc_signed_trace(const sc_dt::sc_signed& object,
+ const std::string& name_,
+ const std::string& vcd_name_);
+ void write(FILE* f);
+ bool changed();
+ void set_width();
+
+protected:
+ const sc_dt::sc_signed& object;
+ sc_dt::sc_signed old_value;
+};
+
+
+vcd_sc_signed_trace::vcd_sc_signed_trace(const sc_dt::sc_signed& object_,
+ const std::string& name_,
+ const std::string& vcd_name_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_.length())
+{
+ vcd_var_typ_name = "wire";
+ old_value = object;
+}
+
+bool
+vcd_sc_signed_trace::changed()
+{
+ return object != old_value;
+}
+
+void
+vcd_sc_signed_trace::write(FILE* f)
+{
+ static std::vector<char> compdata(1024), rawdata(1024);
+ typedef std::vector<char>::size_type size_t;
+
+ if ( compdata.size() < (size_t)object.length() ) {
+ size_t sz = ( (size_t)object.length() + 4096 ) & (~(size_t)(4096-1));
+ std::vector<char>( sz ).swap( compdata ); // resize without copying values
+ std::vector<char>( sz ).swap( rawdata );
+ }
+ char *rawdata_ptr = &rawdata[0];
+
+ for (int bitindex = object.length() - 1; bitindex >= 0; --bitindex) {
+ *rawdata_ptr++ = "01"[object[bitindex].to_bool()];
+ }
+ *rawdata_ptr = '\0';
+ compose_data_line(&rawdata[0], &compdata[0]);
+
+ std::fputs(&compdata[0], f);
+ old_value = object;
+}
+
+void
+vcd_sc_signed_trace::set_width()
+{
+ bit_width = object.length();
+}
+
+/*****************************************************************************/
+
+class vcd_sc_uint_base_trace : public vcd_trace {
+public:
+ vcd_sc_uint_base_trace(const sc_dt::sc_uint_base& object,
+ const std::string& name_,
+ const std::string& vcd_name_);
+ void write(FILE* f);
+ bool changed();
+ void set_width();
+
+protected:
+ const sc_dt::sc_uint_base& object;
+ sc_dt::sc_uint_base old_value;
+};
+
+
+vcd_sc_uint_base_trace::vcd_sc_uint_base_trace(
+ const sc_dt::sc_uint_base& object_,
+ const std::string& name_,
+ const std::string& vcd_name_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_.length())
+// The last may look strange, but is correct
+{
+ vcd_var_typ_name = "wire";
+ old_value = object;
+}
+
+bool
+vcd_sc_uint_base_trace::changed()
+{
+ return object != old_value;
+}
+
+void
+vcd_sc_uint_base_trace::write(FILE* f)
+{
+ char rawdata[1000], *rawdata_ptr = rawdata;
+ char compdata[1000];
+
+ int bitindex;
+ for (bitindex = object.length()-1; bitindex >= 0; --bitindex) {
+ *rawdata_ptr++ = "01"[object[bitindex].to_bool()];
+ }
+ *rawdata_ptr = '\0';
+ compose_data_line(rawdata, compdata);
+
+ std::fputs(compdata, f);
+ old_value = object;
+}
+
+void
+vcd_sc_uint_base_trace::set_width()
+{
+ bit_width = object.length();
+}
+
+
+/*****************************************************************************/
+
+class vcd_sc_int_base_trace : public vcd_trace {
+public:
+ vcd_sc_int_base_trace(const sc_dt::sc_int_base& object,
+ const std::string& name_,
+ const std::string& vcd_name_);
+ void write(FILE* f);
+ bool changed();
+ void set_width();
+
+protected:
+ const sc_dt::sc_int_base& object;
+ sc_dt::sc_int_base old_value;
+};
+
+
+vcd_sc_int_base_trace::vcd_sc_int_base_trace(const sc_dt::sc_int_base& object_,
+ const std::string& name_,
+ const std::string& vcd_name_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_.length())
+{
+ vcd_var_typ_name = "wire";
+ old_value = object;
+}
+
+bool
+vcd_sc_int_base_trace::changed()
+{
+ return object != old_value;
+}
+
+void
+vcd_sc_int_base_trace::write(FILE* f)
+{
+ char rawdata[1000], *rawdata_ptr = rawdata;
+ char compdata[1000];
+
+ int bitindex;
+ for (bitindex = object.length()-1; bitindex >= 0; --bitindex) {
+ *rawdata_ptr++ = "01"[object[bitindex].to_bool()];
+ }
+ *rawdata_ptr = '\0';
+ compose_data_line(rawdata, compdata);
+
+ std::fputs(compdata, f);
+ old_value = object;
+}
+
+void
+vcd_sc_int_base_trace::set_width()
+{
+ bit_width = object.length();
+}
+
+
+/*****************************************************************************/
+
+class vcd_sc_fxval_trace : public vcd_trace
+{
+public:
+
+ vcd_sc_fxval_trace( const sc_dt::sc_fxval& object,
+ const std::string& name_,
+ const std::string& vcd_name_ );
+ void write( FILE* f );
+ bool changed();
+
+protected:
+
+ const sc_dt::sc_fxval& object;
+ sc_dt::sc_fxval old_value;
+
+};
+
+vcd_sc_fxval_trace::vcd_sc_fxval_trace( const sc_dt::sc_fxval& object_,
+ const std::string& name_,
+ const std::string& vcd_name_ )
+: vcd_trace( name_, vcd_name_ ),
+ object( object_ ), old_value( object_ )
+{
+ vcd_var_typ_name = "real";
+ bit_width = 1;
+}
+
+bool
+vcd_sc_fxval_trace::changed()
+{
+ return object != old_value;
+}
+
+void
+vcd_sc_fxval_trace::write( FILE* f )
+{
+ std::fprintf( f, "r%.16g %s", object.to_double(), vcd_name.c_str() );
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class vcd_sc_fxval_fast_trace : public vcd_trace
+{
+public:
+
+ vcd_sc_fxval_fast_trace( const sc_dt::sc_fxval_fast& object,
+ const std::string& name_,
+ const std::string& vcd_name_ );
+ void write( FILE* f );
+ bool changed();
+
+protected:
+
+ const sc_dt::sc_fxval_fast& object;
+ sc_dt::sc_fxval_fast old_value;
+
+};
+
+vcd_sc_fxval_fast_trace::vcd_sc_fxval_fast_trace(
+ const sc_dt::sc_fxval_fast& object_,
+ const std::string& name_,
+ const std::string& vcd_name_ )
+: vcd_trace( name_, vcd_name_ ),
+ object( object_ ), old_value( object_ )
+{
+ vcd_var_typ_name = "real";
+ bit_width = 1;
+}
+
+bool
+vcd_sc_fxval_fast_trace::changed()
+{
+ return object != old_value;
+}
+
+void
+vcd_sc_fxval_fast_trace::write( FILE* f )
+{
+ std::fprintf( f, "r%.16g %s", object.to_double(), vcd_name.c_str() );
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class vcd_sc_fxnum_trace : public vcd_trace
+{
+public:
+
+ vcd_sc_fxnum_trace( const sc_dt::sc_fxnum& object,
+ const std::string& name_,
+ const std::string& vcd_name_ );
+ void write( FILE* f );
+ bool changed();
+ void set_width();
+
+protected:
+
+ const sc_dt::sc_fxnum& object;
+ sc_dt::sc_fxnum old_value;
+
+};
+
+vcd_sc_fxnum_trace::vcd_sc_fxnum_trace( const sc_dt::sc_fxnum& object_,
+ const std::string& name_,
+ const std::string& vcd_name_ )
+: vcd_trace( name_, vcd_name_ ),
+ object( object_ ),
+ old_value( object_.m_params.type_params(),
+ object_.m_params.enc(),
+ object_.m_params.cast_switch(),
+ 0 )
+{
+ vcd_var_typ_name = "wire";
+ old_value = object;
+}
+
+bool
+vcd_sc_fxnum_trace::changed()
+{
+ return object != old_value;
+}
+
+void
+vcd_sc_fxnum_trace::write( FILE* f )
+{
+ static std::vector<char> compdata(1024), rawdata(1024);
+ typedef std::vector<char>::size_type size_t;
+
+ if ( compdata.size() < (size_t)object.wl() ) {
+ size_t sz = ( (size_t)object.wl() + 4096 ) & (~(size_t)(4096-1));
+ std::vector<char>( sz ).swap( compdata ); // resize without copying values
+ std::vector<char>( sz ).swap( rawdata );
+ }
+ char *rawdata_ptr = &rawdata[0];
+
+ for(int bitindex = object.wl() - 1; bitindex >= 0; -- bitindex )
+ {
+ *rawdata_ptr ++ = "01"[object[bitindex]];
+ }
+ *rawdata_ptr = '\0';
+ compose_data_line( &rawdata[0], &compdata[0] );
+
+ std::fputs( &compdata[0], f );
+ old_value = object;
+}
+
+void
+vcd_sc_fxnum_trace::set_width()
+{
+ bit_width = object.wl();
+}
+
+/*****************************************************************************/
+
+class vcd_sc_fxnum_fast_trace : public vcd_trace
+{
+public:
+
+ vcd_sc_fxnum_fast_trace( const sc_dt::sc_fxnum_fast& object,
+ const std::string& name_,
+ const std::string& vcd_name_ );
+ void write( FILE* f );
+ bool changed();
+ void set_width();
+
+protected:
+
+ const sc_dt::sc_fxnum_fast& object;
+ sc_dt::sc_fxnum_fast old_value;
+
+};
+
+vcd_sc_fxnum_fast_trace::vcd_sc_fxnum_fast_trace(
+ const sc_dt::sc_fxnum_fast& object_,
+ const std::string& name_,
+ const std::string& vcd_name_ )
+: vcd_trace( name_, vcd_name_ ),
+ object( object_ ),
+ old_value( object_.m_params.type_params(),
+ object_.m_params.enc(),
+ object_.m_params.cast_switch(),
+ 0 )
+{
+ vcd_var_typ_name = "wire";
+ old_value = object;
+}
+
+bool
+vcd_sc_fxnum_fast_trace::changed()
+{
+ return object != old_value;
+}
+
+void
+vcd_sc_fxnum_fast_trace::write( FILE* f )
+{
+ static std::vector<char> compdata(1024), rawdata(1024);
+ typedef std::vector<char>::size_type size_t;
+
+ if ( compdata.size() < (size_t)object.wl() ) {
+ size_t sz = ( (size_t)object.wl() + 4096 ) & (~(size_t)(4096-1));
+ std::vector<char>( sz ).swap( compdata ); // resize without copying values
+ std::vector<char>( sz ).swap( rawdata );
+ }
+ char *rawdata_ptr = &rawdata[0];
+
+ for(int bitindex = object.wl() - 1; bitindex >= 0; -- bitindex )
+ {
+ *rawdata_ptr ++ = "01"[object[bitindex]];
+ }
+ *rawdata_ptr = '\0';
+ compose_data_line( &rawdata[0], &compdata[0] );
+
+ std::fputs( &compdata[0], f );
+ old_value = object;
+}
+
+void
+vcd_sc_fxnum_fast_trace::set_width()
+{
+ bit_width = object.wl();
+}
+
+
+/*****************************************************************************/
+
+class vcd_unsigned_int_trace : public vcd_trace {
+public:
+ vcd_unsigned_int_trace(const unsigned& object,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const unsigned& object;
+ unsigned old_value;
+ unsigned mask;
+};
+
+
+vcd_unsigned_int_trace::vcd_unsigned_int_trace(
+ const unsigned& object_,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value( object_ ),
+ mask((unsigned)-1)
+{
+ bit_width = width_;
+ if (bit_width < 32) mask = ~(-1 << bit_width);
+
+ vcd_var_typ_name = "wire";
+}
+
+
+bool
+vcd_unsigned_int_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void
+vcd_unsigned_int_trace::write(FILE* f)
+{
+ char rawdata[1000];
+ char compdata[1000];
+ int bitindex;
+
+ // Check for overflow
+ if ((object & mask) != object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ rawdata[bitindex] = 'x';
+ }
+ }
+ else{
+ unsigned bit_mask = 1 << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ rawdata[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ rawdata[bitindex] = '\0';
+ compose_data_line(rawdata, compdata);
+ std::fputs(compdata, f);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class vcd_unsigned_short_trace : public vcd_trace {
+public:
+ vcd_unsigned_short_trace(const unsigned short& object,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const unsigned short& object;
+ unsigned short old_value;
+ unsigned short mask;
+};
+
+
+vcd_unsigned_short_trace::vcd_unsigned_short_trace(
+ const unsigned short& object_,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_), mask(0xffff)
+{
+ bit_width = width_;
+ if (bit_width < 16) mask = (unsigned short)~(-1 << bit_width);
+
+ vcd_var_typ_name = "wire";
+}
+
+
+bool
+vcd_unsigned_short_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void
+vcd_unsigned_short_trace::write(FILE* f)
+{
+ char rawdata[1000];
+ char compdata[1000];
+ int bitindex;
+
+ // Check for overflow
+ if ((object & mask) != object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ rawdata[bitindex] = 'x';
+ }
+ }
+ else{
+ unsigned bit_mask = 1 << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ rawdata[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ rawdata[bitindex] = '\0';
+ compose_data_line(rawdata, compdata);
+ std::fputs(compdata, f);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class vcd_unsigned_char_trace : public vcd_trace {
+public:
+ vcd_unsigned_char_trace(const unsigned char& object,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const unsigned char& object;
+ unsigned char old_value;
+ unsigned char mask;
+};
+
+
+vcd_unsigned_char_trace::vcd_unsigned_char_trace(
+ const unsigned char& object_,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_), mask(0xff)
+{
+ bit_width = width_;
+ if (bit_width < 8) mask = (unsigned char)~(-1 << bit_width);
+ vcd_var_typ_name = "wire";
+}
+
+
+bool vcd_unsigned_char_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void vcd_unsigned_char_trace::write(FILE* f)
+{
+ char rawdata[1000];
+ char compdata[1000];
+ int bitindex;
+
+ // Check for overflow
+ if ((object & mask) != object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ rawdata[bitindex] = 'x';
+ }
+ }
+ else{
+ unsigned bit_mask = 1 << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ rawdata[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ rawdata[bitindex] = '\0';
+ compose_data_line(rawdata, compdata);
+ std::fputs(compdata, f);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class vcd_unsigned_long_trace : public vcd_trace {
+public:
+ vcd_unsigned_long_trace(const unsigned long& object,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const unsigned long& object;
+ unsigned long old_value;
+ unsigned long mask;
+};
+
+
+vcd_unsigned_long_trace::vcd_unsigned_long_trace(
+ const unsigned long& object_,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_),
+ mask((unsigned long)-1)
+{
+ bit_width = width_;
+ if ( bit_width < (int)(sizeof(unsigned long)*8) )
+ mask = ~(-1L << bit_width);
+
+ vcd_var_typ_name = "wire";
+}
+
+
+bool vcd_unsigned_long_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void vcd_unsigned_long_trace::write(FILE* f)
+{
+ char rawdata[1000];
+ char compdata[1000];
+ int bitindex;
+
+ // Check for overflow
+ if ((object & mask) != object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ rawdata[bitindex] = 'x';
+ }
+ }
+ else{
+ unsigned long bit_mask = 1ul << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ rawdata[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ rawdata[bitindex] = '\0';
+ compose_data_line(rawdata, compdata);
+ std::fputs(compdata, f);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class vcd_signed_int_trace : public vcd_trace {
+public:
+ vcd_signed_int_trace(const int& object,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const int& object;
+ int old_value;
+ unsigned mask;
+};
+
+
+vcd_signed_int_trace::vcd_signed_int_trace(const signed& object_,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_),
+ mask((unsigned)-1)
+{
+ bit_width = width_;
+ if (bit_width < 32) mask = ~(-1 << bit_width);
+
+ vcd_var_typ_name = "wire";
+}
+
+
+bool vcd_signed_int_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void vcd_signed_int_trace::write(FILE* f)
+{
+ char rawdata[1000];
+ char compdata[1000];
+ int bitindex;
+
+ // Check for overflow
+ if (((unsigned) object & mask) != (unsigned) object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ rawdata[bitindex] = 'x';
+ }
+ }
+ else{
+ unsigned bit_mask = 1 << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ rawdata[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ rawdata[bitindex] = '\0';
+ compose_data_line(rawdata, compdata);
+ std::fputs(compdata, f);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class vcd_signed_short_trace : public vcd_trace {
+public:
+ vcd_signed_short_trace(const short& object,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const short& object;
+ short old_value;
+ unsigned short mask;
+};
+
+
+vcd_signed_short_trace::vcd_signed_short_trace(
+ const short& object_,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_), mask(0xffff)
+{
+ bit_width = width_;
+ if (bit_width < 16) mask = (unsigned short)~(-1 << bit_width);
+
+ vcd_var_typ_name = "wire";
+}
+
+
+bool vcd_signed_short_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void vcd_signed_short_trace::write(FILE* f)
+{
+ char rawdata[1000];
+ char compdata[1000];
+ int bitindex;
+
+ // Check for overflow
+ if (((unsigned short) object & mask) != (unsigned short) object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ rawdata[bitindex] = 'x';
+ }
+ }
+ else{
+ unsigned bit_mask = 1 << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ rawdata[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ rawdata[bitindex] = '\0';
+ compose_data_line(rawdata, compdata);
+ std::fputs(compdata, f);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class vcd_signed_char_trace : public vcd_trace {
+public:
+ vcd_signed_char_trace(const char& object,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const char& object;
+ char old_value;
+ unsigned char mask;
+};
+
+
+vcd_signed_char_trace::vcd_signed_char_trace(const char& object_,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_), mask(0xff)
+{
+ bit_width = width_;
+ if (bit_width < 8) mask = (unsigned char)~(-1 << bit_width);
+
+ vcd_var_typ_name = "wire";
+}
+
+
+bool vcd_signed_char_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void vcd_signed_char_trace::write(FILE* f)
+{
+ char rawdata[1000];
+ char compdata[1000];
+ int bitindex;
+
+ // Check for overflow
+ if (((unsigned char) object & mask) != (unsigned char) object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ rawdata[bitindex] = 'x';
+ }
+ }
+ else{
+ unsigned bit_mask = 1 << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ rawdata[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ rawdata[bitindex] = '\0';
+ compose_data_line(rawdata, compdata);
+ std::fputs(compdata, f);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class vcd_int64_trace : public vcd_trace {
+public:
+ vcd_int64_trace(const sc_dt::int64& object,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const sc_dt::int64& object;
+ sc_dt::int64 old_value;
+ sc_dt::uint64 mask;
+};
+
+
+vcd_int64_trace::vcd_int64_trace(const sc_dt::int64& object_,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_),
+ mask((sc_dt::uint64)-1)
+{
+ bit_width = width_;
+ if (bit_width < 64) mask = ~(mask << bit_width);
+ vcd_var_typ_name = "wire";
+}
+
+
+bool vcd_int64_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void vcd_int64_trace::write(FILE* f)
+{
+ char rawdata[1000];
+ char compdata[1000];
+ int bitindex;
+
+ // Check for overflow
+ if (((sc_dt::uint64) object & mask) != (sc_dt::uint64) object)
+ {
+ for (bitindex = 0; bitindex < bit_width; bitindex++)
+ {
+ rawdata[bitindex] = 'x';
+ }
+ }
+ else
+ {
+ sc_dt::uint64 bit_mask = 1;
+ bit_mask = bit_mask << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ rawdata[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ rawdata[bitindex] = '\0';
+ compose_data_line(rawdata, compdata);
+ std::fputs(compdata, f);
+ old_value = object;
+}
+
+
+/*****************************************************************************/
+
+class vcd_uint64_trace : public vcd_trace {
+public:
+ vcd_uint64_trace(const sc_dt::uint64& object,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const sc_dt::uint64& object;
+ sc_dt::uint64 old_value;
+ sc_dt::uint64 mask;
+};
+
+
+vcd_uint64_trace::vcd_uint64_trace( const sc_dt::uint64& object_,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_),
+ mask((sc_dt::uint64)-1)
+{
+ bit_width = width_;
+ if ( bit_width < 64 ) mask = ~(mask << bit_width);
+ vcd_var_typ_name = "wire";
+}
+
+
+bool vcd_uint64_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void vcd_uint64_trace::write(FILE* f)
+{
+ char rawdata[1000];
+ char compdata[1000];
+ int bitindex;
+
+ // Check for overflow
+ if ((object & mask) != object)
+ {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ rawdata[bitindex] = 'x';
+ }
+ }
+ else
+ {
+ sc_dt::uint64 bit_mask = 1;
+ bit_mask = bit_mask << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++)
+ {
+ rawdata[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ rawdata[bitindex] = '\0';
+ compose_data_line(rawdata, compdata);
+ std::fputs(compdata, f);
+ old_value = object;
+}
+
+
+/*****************************************************************************/
+
+class vcd_signed_long_trace : public vcd_trace {
+public:
+ vcd_signed_long_trace(const long& object,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const long& object;
+ long old_value;
+ unsigned long mask;
+};
+
+
+vcd_signed_long_trace::vcd_signed_long_trace(const long& object_,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_),
+ mask((unsigned long)-1)
+{
+ bit_width = width_;
+ if ( bit_width < (int)(sizeof(long)*8) )
+ mask = ~(-1L << bit_width);
+ vcd_var_typ_name = "wire";
+}
+
+
+bool vcd_signed_long_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void vcd_signed_long_trace::write(FILE* f)
+{
+ char rawdata[1000];
+ char compdata[1000];
+ int bitindex;
+
+ // Check for overflow
+ if (((unsigned long) object & mask) != (unsigned long) object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ rawdata[bitindex] = 'x';
+ }
+ }
+ else{
+ unsigned long bit_mask = 1ul << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ rawdata[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ rawdata[bitindex] = '\0';
+ compose_data_line(rawdata, compdata);
+ std::fputs(compdata, f);
+ old_value = object;
+}
+
+
+/*****************************************************************************/
+
+class vcd_float_trace : public vcd_trace {
+public:
+ vcd_float_trace(const float& object,
+ const std::string& name_,
+ const std::string& vcd_name_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const float& object;
+ float old_value;
+};
+
+vcd_float_trace::vcd_float_trace(const float& object_,
+ const std::string& name_,
+ const std::string& vcd_name_)
+: vcd_trace(name_, vcd_name_), object(object_)
+{
+ vcd_var_typ_name = "real";
+ bit_width = 1;
+ old_value = object;
+}
+
+bool vcd_float_trace::changed()
+{
+ return object != old_value;
+}
+
+void vcd_float_trace::write(FILE* f)
+{
+ std::fprintf(f, "r%.16g %s", object, vcd_name.c_str());
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class vcd_double_trace : public vcd_trace {
+public:
+ vcd_double_trace(const double& object,
+ const std::string& name_,
+ const std::string& vcd_name_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const double& object;
+ double old_value;
+};
+
+vcd_double_trace::vcd_double_trace(const double& object_,
+ const std::string& name_,
+ const std::string& vcd_name_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_)
+{
+ vcd_var_typ_name = "real";
+ bit_width = 1;
+}
+
+bool vcd_double_trace::changed()
+{
+ return object != old_value;
+}
+
+void vcd_double_trace::write(FILE* f)
+{
+ std::fprintf(f, "r%.16g %s", object, vcd_name.c_str());
+ old_value = object;
+}
+
+
+/*****************************************************************************/
+
+class vcd_enum_trace : public vcd_trace {
+public:
+ vcd_enum_trace(const unsigned& object_,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ const char** enum_literals);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const unsigned& object;
+ unsigned old_value;
+ unsigned mask;
+ const char** literals;
+ unsigned nliterals;
+};
+
+
+vcd_enum_trace::vcd_enum_trace(const unsigned& object_,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ const char** enum_literals_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_),
+ mask(0xffffffff), literals(enum_literals_), nliterals(0)
+{
+ // find number of bits required to represent enumeration literal - counting loop
+ for (nliterals = 0; enum_literals_[nliterals]; nliterals++) continue;
+
+ // Figure out number of bits required to represent the number of literals
+ bit_width = 0;
+ unsigned shifted_maxindex = nliterals-1;
+ while(shifted_maxindex != 0){
+ shifted_maxindex >>= 1;
+ bit_width++;
+ }
+
+ // Set the mask
+ if (bit_width < 32) {
+ mask = ~(-1 << bit_width);
+ } else {
+ mask = 0xffffffff;
+ }
+
+ vcd_var_typ_name = "wire";
+}
+
+bool vcd_enum_trace::changed()
+{
+ return object != old_value;
+}
+
+void vcd_enum_trace::write(FILE* f)
+{
+ char rawdata[1000];
+ char compdata[1000];
+ int bitindex;
+
+ // Check for overflow
+ if ((object & mask) != object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ rawdata[bitindex] = 'x';
+ }
+ } else {
+ unsigned long bit_mask = 1ul << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ rawdata[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ rawdata[bitindex] = '\0';
+ compose_data_line(rawdata, compdata);
+ std::fputs(compdata, f);
+ old_value = object;
+}
+
+
+/*****************************************************************************
+ vcd_trace_file functions
+ *****************************************************************************/
+
+vcd_trace_file::vcd_trace_file(const char *name)
+ : sc_trace_file_base( name, "vcd" )
+ , vcd_name_index(0)
+ , previous_time_units_low(0)
+ , previous_time_units_high(0)
+ , traces()
+{}
+
+
+void
+vcd_trace_file::do_initialize()
+{
+ char buf[2000];
+
+ //date:
+ std::fprintf(fp, "$date\n %s\n$end\n\n", localtime_string().c_str() );
+
+ //version:
+ std::fprintf(fp, "$version\n %s\n$end\n\n", sc_version());
+
+ //timescale:
+ static struct SC_TIMESCALE_TO_TEXT {
+ double unit;
+ const char* text;
+ } timescale_to_text [] = {
+ { sc_time(1, SC_FS).to_seconds(), "1 fs" },
+ { sc_time(10, SC_FS).to_seconds(), "10 fs" },
+ { sc_time(100, SC_FS).to_seconds(),"100 fs" },
+ { sc_time(1, SC_PS).to_seconds(), "1 ps" },
+ { sc_time(10, SC_PS).to_seconds(), "10 ps" },
+ { sc_time(100, SC_PS).to_seconds(),"100 ps" },
+ { sc_time(1, SC_NS).to_seconds(), "1 ns" },
+ { sc_time(10, SC_NS).to_seconds(), "10 ns" },
+ { sc_time(100, SC_NS).to_seconds(),"100 ns" },
+ { sc_time(1, SC_US).to_seconds(), "1 us" },
+ { sc_time(10, SC_US).to_seconds(), "10 us" },
+ { sc_time(100, SC_US).to_seconds(),"100 us" },
+ { sc_time(1, SC_MS).to_seconds(), "1 ms" },
+ { sc_time(10, SC_MS).to_seconds(), "10 ms" },
+ { sc_time(100, SC_MS).to_seconds(),"100 ms" },
+ { sc_time(1, SC_SEC).to_seconds(), "1 sec" },
+ { sc_time(10, SC_SEC).to_seconds(), "10 sec" },
+ { sc_time(100, SC_SEC).to_seconds(),"100 sec" }
+ };
+ static int timescale_to_text_n =
+ sizeof(timescale_to_text)/sizeof(SC_TIMESCALE_TO_TEXT);
+
+ for ( int time_i = 0; time_i < timescale_to_text_n; time_i++ )
+ {
+ if (timescale_unit == timescale_to_text[time_i].unit)
+ {
+ std::fprintf(fp,"$timescale\n %s\n$end\n\n",
+ timescale_to_text[time_i].text);
+ break;
+ }
+ }
+
+ // Create a dummy scope
+ std::fputs("$scope module SystemC $end\n", fp);
+
+ //variable definitions:
+ for (int i = 0; i < (int)traces.size(); i++) {
+ vcd_trace* t = traces[i];
+ t->set_width(); // needed for all vectors
+ t->print_variable_declaration_line(fp);
+ }
+
+ std::fputs("$upscope $end\n", fp);
+
+ std::fputs("$enddefinitions $end\n\n", fp);
+
+ // double inittime = sc_simulation_time();
+ double inittime = sc_time_stamp().to_seconds();
+
+ std::sprintf(buf,
+ "All initial values are dumped below at time "
+ "%g sec = %g timescale units.",
+ inittime, inittime/timescale_unit
+ );
+ write_comment(buf);
+
+ double_to_special_int64(inittime/timescale_unit,
+ &previous_time_units_high,
+ &previous_time_units_low );
+
+
+ std::fputs("$dumpvars\n",fp);
+ for (int i = 0; i < (int)traces.size(); i++) {
+ traces[i]->write(fp);
+ std::fputc('\n', fp);
+ }
+ std::fputs("$end\n\n", fp);
+}
+
+
+// ----------------------------------------------------------------------------
+
+#define DEFN_TRACE_METHOD(tp) \
+void \
+vcd_trace_file::trace(const tp& object_, const std::string& name_) \
+{ \
+ if( add_trace_check(name_) ) \
+ traces.push_back( new vcd_ ## tp ## _trace( object_, \
+ name_, \
+ obtain_name() ) ); \
+}
+
+DEFN_TRACE_METHOD(bool)
+DEFN_TRACE_METHOD(float)
+DEFN_TRACE_METHOD(double)
+
+#undef DEFN_TRACE_METHOD
+#define DEFN_TRACE_METHOD(tp) \
+void \
+vcd_trace_file::trace(const sc_dt::tp& object_, const std::string& name_) \
+{ \
+ if( add_trace_check(name_) ) \
+ traces.push_back( new vcd_ ## tp ## _trace( object_, \
+ name_, \
+ obtain_name() ) ); \
+}
+
+DEFN_TRACE_METHOD(sc_bit)
+DEFN_TRACE_METHOD(sc_logic)
+
+DEFN_TRACE_METHOD(sc_signed)
+DEFN_TRACE_METHOD(sc_unsigned)
+DEFN_TRACE_METHOD(sc_int_base)
+DEFN_TRACE_METHOD(sc_uint_base)
+
+DEFN_TRACE_METHOD(sc_fxval)
+DEFN_TRACE_METHOD(sc_fxval_fast)
+DEFN_TRACE_METHOD(sc_fxnum)
+DEFN_TRACE_METHOD(sc_fxnum_fast)
+
+#undef DEFN_TRACE_METHOD
+
+
+#define DEFN_TRACE_METHOD_SIGNED(tp) \
+void \
+vcd_trace_file::trace( const tp& object_, \
+ const std::string& name_, \
+ int width_ ) \
+{ \
+ if( add_trace_check(name_) ) \
+ traces.push_back( new vcd_signed_ ## tp ## _trace( object_, \
+ name_, \
+ obtain_name(), \
+ width_ ) ); \
+}
+
+#define DEFN_TRACE_METHOD_UNSIGNED(tp) \
+void \
+vcd_trace_file::trace( const unsigned tp& object_, \
+ const std::string& name_, \
+ int width_ ) \
+{ \
+ if( add_trace_check(name_) ) \
+ traces.push_back( new vcd_unsigned_ ## tp ## _trace( object_, \
+ name_, \
+ obtain_name(), \
+ width_ ) ); \
+}
+
+DEFN_TRACE_METHOD_SIGNED(char)
+DEFN_TRACE_METHOD_SIGNED(short)
+DEFN_TRACE_METHOD_SIGNED(int)
+DEFN_TRACE_METHOD_SIGNED(long)
+
+DEFN_TRACE_METHOD_UNSIGNED(char)
+DEFN_TRACE_METHOD_UNSIGNED(short)
+DEFN_TRACE_METHOD_UNSIGNED(int)
+DEFN_TRACE_METHOD_UNSIGNED(long)
+
+#undef DEFN_TRACE_METHOD_SIGNED
+#undef DEFN_TRACE_METHOD_UNSIGNED
+
+#define DEFN_TRACE_METHOD_LONG_LONG(tp) \
+void \
+vcd_trace_file::trace( const sc_dt::tp& object_, \
+ const std::string& name_, \
+ int width_ ) \
+{ \
+ if( add_trace_check(name_) ) \
+ traces.push_back( new vcd_ ## tp ## _trace( object_, \
+ name_, \
+ obtain_name(), \
+ width_ ) ); \
+}
+
+DEFN_TRACE_METHOD_LONG_LONG(int64)
+DEFN_TRACE_METHOD_LONG_LONG(uint64)
+
+#undef DEFN_TRACE_METHOD_LONG_LONG
+
+void
+vcd_trace_file::trace( const unsigned& object_,
+ const std::string& name_,
+ const char** enum_literals_ )
+{
+ if( add_trace_check(name_) )
+ traces.push_back( new vcd_enum_trace( object_,
+ name_,
+ obtain_name(),
+ enum_literals_ ) );
+}
+
+
+void
+vcd_trace_file::write_comment(const std::string& comment)
+{
+ if(!fp) open_fp();
+ //no newline in comments allowed, as some viewers may crash
+ std::fputs("$comment\n", fp);
+ std::fputs(comment.c_str(), fp);
+ std::fputs("\n$end\n\n", fp);
+}
+
+void
+vcd_trace_file::cycle(bool this_is_a_delta_cycle)
+{
+ unsigned this_time_units_high, this_time_units_low;
+
+ // Just to make g++ shut up in the optimized mode
+ this_time_units_high = this_time_units_low = 0;
+
+ // Trace delta cycles only when enabled
+ if (!delta_cycles() && this_is_a_delta_cycle) return;
+
+ // Check for initialization
+ if( initialize() ) {
+ return;
+ };
+
+
+ double now_units = sc_time_stamp().to_seconds() / timescale_unit;
+ unsigned now_units_high, now_units_low;
+ double_to_special_int64(now_units, &now_units_high, &now_units_low );
+
+ bool now_later_than_previous_time = false;
+ if( (now_units_low > previous_time_units_low
+ && now_units_high == previous_time_units_high)
+ || now_units_high > previous_time_units_high){
+ now_later_than_previous_time = true;
+ }
+
+ bool now_equals_previous_time = false;
+ if(now_later_than_previous_time){
+ this_time_units_high = now_units_high;
+ this_time_units_low = now_units_low;
+ } else {
+ if( now_units_low == previous_time_units_low
+ && now_units_high == previous_time_units_high){
+ now_equals_previous_time = true;
+ this_time_units_high = now_units_high;
+ this_time_units_low = now_units_low;
+ }
+ }
+
+ // Since VCD does not understand 0 time progression, we have to fake
+ // delta cycles with progressing time by one unit
+ if(this_is_a_delta_cycle){
+ this_time_units_high = previous_time_units_high;
+ this_time_units_low = previous_time_units_low + 1;
+ if(this_time_units_low == 1000000000){
+ this_time_units_high++;
+ this_time_units_low=0;
+ }
+ static bool warned = false;
+ if(!warned){
+ SC_REPORT_INFO( SC_ID_TRACING_VCD_DELTA_CYCLE_
+ , sc_time( timescale_unit, SC_SEC )
+ .to_string().c_str() );
+ warned = true;
+ }
+ }
+
+
+ // Not a delta cycle and time has not progressed
+ if( ! this_is_a_delta_cycle && now_equals_previous_time &&
+ ( now_units_high != 0 || now_units_low != 0 ) ) {
+ // Don't print the message at time zero
+ static bool warned = false;
+ if( ! warned ) {
+ std::stringstream ss;
+ ss << "units count: " << now_units_low << "\n"
+ "\tWaveform viewers will only show the states of the last one.\n"
+ "\tUse `tracefile->set_time_unit(double, sc_time_unit);'"
+ " to increase the time resolution.";
+ SC_REPORT_WARNING( SC_ID_TRACING_VCD_DUPLICATE_TIME_
+ , ss.str().c_str() );
+ // warned = true;
+ }
+ }
+
+ // Not a delta cycle and time has gone backward
+ // This will happen with large number of delta cycles between two real
+ // advances of time
+ if(!this_is_a_delta_cycle && !now_equals_previous_time &&
+ !now_later_than_previous_time){
+ static bool warned = false;
+ if(!warned) {
+ std::stringstream ss;
+ ss << "units count ("
+ << previous_time_units_low << "->" << now_units_low << ")\n"
+ "\tThis can occur when delta cycling is activated."
+ " Cycles with falling time are not shown.\n"
+ "\tUse `tracefile->set_time_unit(double, sc_time_unit);'"
+ " to increase the time resolution.";
+ SC_REPORT_WARNING( SC_ID_TRACING_VCD_DUPLICATE_TIME_
+ , ss.str().c_str() );
+ // warned = true;
+ }
+ // Note that we don't set this_time_units_high/low to any value only
+ // in this case because we are not going to do any tracing. In the
+ // optimized mode, the compiler complains because of this. Therefore,
+ // we include the lines at the very beginning of this function to make
+ // the compiler shut up.
+ return;
+ }
+
+ // Now do the actual printing
+ bool time_printed = false;
+ vcd_trace* const* const l_traces = &traces[0];
+ for (int i = 0; i < (int)traces.size(); i++) {
+ vcd_trace* t = l_traces[i];
+ if(t->changed()){
+ if(time_printed == false){
+ char buf[200];
+ if(this_time_units_high){
+ std::sprintf(buf, "#%u%09u", this_time_units_high, this_time_units_low);
+ }
+ else{
+ std::sprintf(buf, "#%u", this_time_units_low);
+ }
+ std::fputs(buf, fp);
+ std::fputc('\n', fp);
+ time_printed = true;
+ }
+
+ // Write the variable
+ t->write(fp);
+ std::fputc('\n', fp);
+ }
+ }
+ // Put another newline after all values are printed
+ if(time_printed) std::fputc('\n', fp);
+
+ if(time_printed){
+ // We update previous_time_units only when we print time because
+ // this field stores the previous time that was printed, not the
+ // previous time this function was called
+ previous_time_units_high = this_time_units_high;
+ previous_time_units_low = this_time_units_low;
+ }
+}
+
+#if 0
+void
+vcd_trace_file::create_vcd_name(std::string* p_destination)
+{
+ obtain_name.swap( *p_destination );
+}
+#endif
+
+// Create a VCD name for a variable
+std::string
+vcd_trace_file::obtain_name()
+{
+ const char first_type_used = 'a';
+ const int used_types_count = 'z' - 'a' + 1;
+ int result;
+
+ result = vcd_name_index;
+ char char6 = (char)(vcd_name_index % used_types_count);
+
+ result = result / used_types_count;
+ char char5 = (char)(result % used_types_count);
+
+ result = result / used_types_count;
+ char char4 = (char)(result % used_types_count);
+
+ result = result / used_types_count;
+ char char3 = (char)(result % used_types_count);
+
+ result = result / used_types_count;
+ char char2 = (char)(result % used_types_count);
+
+ char buf[20];
+ std::sprintf(buf, "%c%c%c%c%c",
+ char2 + first_type_used,
+ char3 + first_type_used,
+ char4 + first_type_used,
+ char5 + first_type_used,
+ char6 + first_type_used);
+ vcd_name_index++;
+ return std::string(buf);
+}
+
+vcd_trace_file::~vcd_trace_file()
+{
+ for( int i = 0; i < (int)traces.size(); i++ ) {
+ vcd_trace* t = traces[i];
+ delete t;
+ }
+}
+
+
+// Functions specific to VCD tracing
+
+static char
+map_sc_logic_state_to_vcd_state(char in_char)
+{
+ char out_char;
+
+ switch(in_char){
+ case 'U':
+ case 'X':
+ case 'W':
+ case 'D':
+ out_char = 'x';
+ break;
+ case '0':
+ case 'L':
+ out_char = '0';
+ break;
+ case '1':
+ case 'H':
+ out_char = '1';
+ break;
+ case 'Z':
+ out_char = 'z';
+ break;
+ default:
+ out_char = '?';
+ }
+
+ return out_char;
+}
+
+
+
+
+static
+void
+remove_vcd_name_problems(vcd_trace const* vcd, std::string& name)
+{
+ static bool warned = false;
+ bool braces_removed = false;
+ for (unsigned int i = 0; i< name.length(); i++) {
+ if (name[i] == '[') {
+ name[i] = '(';
+ braces_removed = true;
+ }
+ else if (name[i] == ']') {
+ name[i] = ')';
+ braces_removed = true;
+ }
+ }
+
+ if(braces_removed && !warned){
+ std::stringstream ss;
+ ss << vcd->name << ":\n"
+ "\tTraced objects found with name containing [], which may be\n"
+ "\tinterpreted by the waveform viewer in unexpected ways.\n"
+ "\tSo the [] is automatically replaced by ().";
+
+ SC_REPORT_WARNING( SC_ID_TRACING_OBJECT_NAME_FILTERED_
+ , ss.str().c_str() );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+sc_trace_file*
+sc_create_vcd_trace_file(const char * name)
+{
+ sc_trace_file * tf = new vcd_trace_file(name);
+ return tf;
+}
+
+void
+sc_close_vcd_trace_file( sc_trace_file* tf )
+{
+ vcd_trace_file* vcd_tf = static_cast<vcd_trace_file*>(tf);
+ delete vcd_tf;
+}
+
+} // namespace sc_core
diff --git a/ext/systemc/src/sysc/tracing/sc_vcd_trace.h b/ext/systemc/src/sysc/tracing/sc_vcd_trace.h
new file mode 100644
index 000000000..760949ffb
--- /dev/null
+++ b/ext/systemc/src/sysc/tracing/sc_vcd_trace.h
@@ -0,0 +1,228 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_vcd_trace.h - Implementation of VCD tracing.
+
+ Original Author - Abhijit Ghosh, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ Acknowledgement: The tracing mechanism is based on the tracing
+ mechanism developed at Infineon (formerly Siemens HL). Though this
+ code is somewhat different, and significantly enhanced, the basics
+ are identical to what was originally contributed by Infineon. The
+ contribution of Infineon in the development of this tracing
+ technology is hereby acknowledged.
+
+ *****************************************************************************/
+
+#ifndef SC_VCD_TRACE_H
+#define SC_VCD_TRACE_H
+
+#include "sysc/tracing/sc_trace_file_base.h"
+
+namespace sc_core {
+
+class vcd_trace; // defined in vcd_trace.cpp
+template<class T> class vcd_T_trace;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : vcd_trace_file
+//
+// ...
+// ----------------------------------------------------------------------------
+
+class vcd_trace_file
+ : public sc_trace_file_base
+{
+public:
+
+ enum vcd_enum {VCD_WIRE=0, VCD_REAL=1, VCD_LAST};
+
+ // sc_set_vcd_time_unit is deprecated.
+#if 0 // deprecated
+ inline void sc_set_vcd_time_unit(int exponent10_seconds)
+ { set_time_unit(exponent10_seconds); }
+#endif
+
+ // Create a Vcd trace file.
+ // `Name' forms the base of the name to which `.vcd' is added.
+ vcd_trace_file(const char *name);
+
+ // Flush results and close file.
+ ~vcd_trace_file();
+
+protected:
+
+ // These are all virtual functions in sc_trace_file and
+ // they need to be defined here.
+
+ // Trace a boolean object (single bit)
+ void trace(const bool& object, const std::string& name);
+
+ // Trace a sc_bit object (single bit)
+ virtual void trace( const sc_dt::sc_bit& object,
+ const std::string& name);
+
+ // Trace a sc_logic object (single bit)
+ void trace(const sc_dt::sc_logic& object, const std::string& name);
+
+ // Trace an unsigned char with the given width
+ void trace(const unsigned char& object, const std::string& name,
+ int width);
+
+ // Trace an unsigned short with the given width
+ void trace(const unsigned short& object, const std::string& name,
+ int width);
+
+ // Trace an unsigned int with the given width
+ void trace(const unsigned int& object, const std::string& name,
+ int width);
+
+ // Trace an unsigned long with the given width
+ void trace(const unsigned long& object, const std::string& name,
+ int width);
+
+ // Trace a signed char with the given width
+ void trace(const char& object, const std::string& name, int width);
+
+ // Trace a signed short with the given width
+ void trace(const short& object, const std::string& name, int width);
+
+ // Trace a signed int with the given width
+ void trace(const int& object, const std::string& name, int width);
+
+ // Trace a signed long with the given width
+ void trace(const long& object, const std::string& name, int width);
+
+ // Trace an int64 with a given width
+ void trace(const sc_dt::int64& object, const std::string& name,
+ int width);
+
+ // Trace a uint64 with a given width
+ void trace(const sc_dt::uint64& object, const std::string& name,
+ int width);
+
+ // Trace a float
+ void trace(const float& object, const std::string& name);
+
+ // Trace a double
+ void trace(const double& object, const std::string& name);
+
+ // Trace sc_dt::sc_uint_base
+ void trace (const sc_dt::sc_uint_base& object,
+ const std::string& name);
+
+ // Trace sc_dt::sc_int_base
+ void trace (const sc_dt::sc_int_base& object,
+ const std::string& name);
+
+ // Trace sc_dt::sc_unsigned
+ void trace (const sc_dt::sc_unsigned& object,
+ const std::string& name);
+
+ // Trace sc_dt::sc_signed
+ void trace (const sc_dt::sc_signed& object, const std::string& name);
+
+ // Trace sc_dt::sc_fxval
+ void trace( const sc_dt::sc_fxval& object, const std::string& name );
+
+ // Trace sc_dt::sc_fxval_fast
+ void trace( const sc_dt::sc_fxval_fast& object,
+ const std::string& name );
+
+ // Trace sc_dt::sc_fxnum
+ void trace( const sc_dt::sc_fxnum& object, const std::string& name );
+
+ // Trace sc_dt::sc_fxnum_fast
+ void trace( const sc_dt::sc_fxnum_fast& object,
+ const std::string& name );
+
+ template<class T>
+ void traceT(const T& object, const std::string& name,
+ vcd_enum type=VCD_WIRE)
+ {
+ if( add_trace_check(name) )
+ traces.push_back(new vcd_T_trace<T>( object, name
+ , obtain_name(),type) );
+ }
+
+ // Trace sc_dt::sc_bv_base (sc_dt::sc_bv)
+ virtual void trace(const sc_dt::sc_bv_base& object,
+ const std::string& name);
+
+ // Trace sc_dt::sc_lv_base (sc_dt::sc_lv)
+ virtual void trace(const sc_dt::sc_lv_base& object,
+ const std::string& name);
+ // Trace an enumerated object - where possible output the enumeration literals
+ // in the trace file. Enum literals is a null terminated array of null
+ // terminated char* literal strings.
+ void trace(const unsigned& object, const std::string& name,
+ const char** enum_literals);
+
+ // Output a comment to the trace file
+ void write_comment(const std::string& comment);
+
+ // Write trace info for cycle.
+ void cycle(bool delta_cycle);
+
+private:
+
+#if SC_TRACING_PHASE_CALLBACKS_
+ // avoid hidden overload warnings
+ virtual void trace( sc_trace_file* ) const { sc_assert(false); }
+#endif // SC_TRACING_PHASE_CALLBACKS_
+
+ // Initialize the VCD tracing
+ virtual void do_initialize();
+
+ unsigned vcd_name_index; // Number of variables traced
+
+ unsigned previous_time_units_low; // Previous time unit as 64-bit integer
+ unsigned previous_time_units_high;
+
+public:
+
+ // Array to store the variables traced
+ std::vector<vcd_trace*> traces;
+
+ // Create VCD names for each variable
+ std::string obtain_name();
+
+};
+
+} // namespace sc_core
+
+#endif // SC_VCD_TRACE_H
+// Taf!
diff --git a/ext/systemc/src/sysc/tracing/sc_wif_trace.cpp b/ext/systemc/src/sysc/tracing/sc_wif_trace.cpp
new file mode 100644
index 000000000..b2bacee7d
--- /dev/null
+++ b/ext/systemc/src/sysc/tracing/sc_wif_trace.cpp
@@ -0,0 +1,1911 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_wif_trace.cpp - Implementation of WIF tracing.
+
+ Original Author - Abhijit Ghosh, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc.
+ Description of Modification: - Replaced 'width' of sc_(u)int with their
+ 'bitwidth()'.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ Acknowledgement: The tracing mechanism is based on the tracing
+ mechanism developed at Infineon (formerly Siemens HL). Though this
+ code is somewhat different, and significantly enhanced, the basics
+ are identical to what was originally contributed by Infineon. The
+ contribution of Infineon in the development of this tracing
+ technology is hereby acknowledged.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ Instead of creating the binary WIF format, we create the ASCII
+ WIF format which can be converted to the binary format using
+ a2wif (utility that comes with VSS from Synopsys). This way,
+ a user who does not have Synopsys VSS can still create WIF
+ files, but they can only be viewed by users who have VSS.
+
+ *****************************************************************************/
+
+
+#include <cstdlib>
+#include <vector>
+
+#define SC_DISABLE_API_VERSION_CHECK // for in-library sc_ver.h inclusion
+
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_ver.h"
+#include "sysc/datatypes/bit/sc_bit.h"
+#include "sysc/datatypes/bit/sc_logic.h"
+#include "sysc/datatypes/bit/sc_lv_base.h"
+#include "sysc/datatypes/int/sc_signed.h"
+#include "sysc/datatypes/int/sc_unsigned.h"
+#include "sysc/datatypes/int/sc_int_base.h"
+#include "sysc/datatypes/int/sc_uint_base.h"
+#include "sysc/datatypes/fx/fx.h"
+#include "sysc/tracing/sc_wif_trace.h"
+
+namespace sc_core {
+
+// Forward declarations for functions that come later in the file
+static char map_sc_logic_state_to_wif_state(char in_char);
+
+const char* wif_names[wif_trace_file::WIF_LAST] = {"BIT","MVL","real"};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : wif_trace
+//
+// Base class for WIF traces.
+// ----------------------------------------------------------------------------
+
+class wif_trace
+{
+public:
+
+ wif_trace(const std::string& name_, const std::string& wif_name_);
+
+ // Needs to be pure virtual as has to be defined by the particular
+ // type being traced
+ virtual void write(FILE* f) = 0;
+
+ virtual void set_width();
+
+ // Comparison function needs to be pure virtual too
+ virtual bool changed() = 0;
+
+ // Got to declare this virtual as this will be overwritten
+ // by one base class
+ virtual void print_variable_declaration_line(FILE* f);
+
+ virtual ~wif_trace();
+
+ const std::string name; // Name of the variable
+ const std::string wif_name; // Name of the variable in WIF file
+ const char* wif_type; // WIF data type
+ int bit_width;
+};
+
+
+wif_trace::wif_trace(const std::string& name_,
+ const std::string& wif_name_)
+ : name(name_), wif_name(wif_name_), wif_type(0), bit_width(-1)
+{
+ /* Intentionally blank */
+}
+
+void
+wif_trace::print_variable_declaration_line( FILE* f )
+{
+ if( bit_width < 0 )
+ {
+ std::stringstream ss;
+ ss << "'" << name << "' has < 0 bits";
+ SC_REPORT_ERROR( SC_ID_TRACING_OBJECT_IGNORED_
+ , ss.str().c_str() );
+ return;
+ }
+
+ std::fprintf( f, "declare %s \"%s\" %s ",
+ wif_name.c_str(), name.c_str(), wif_type );
+
+ if( bit_width > 0 ) {
+ std::fprintf( f, "0 %d ", bit_width - 1 );
+ }
+ std::fprintf( f, "variable ;\n" );
+ std::fprintf( f, "start_trace %s ;\n", wif_name.c_str() );
+}
+
+void
+wif_trace::set_width()
+{
+ /* Intentionally Blank, should be defined for each type separately */
+}
+
+wif_trace::~wif_trace()
+{
+ /* Intentionally Blank */
+}
+
+// Classes for tracing individual data types
+
+/*****************************************************************************/
+
+class wif_uint64_trace: public wif_trace {
+public:
+ wif_uint64_trace(const sc_dt::uint64& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const sc_dt::uint64& object;
+ sc_dt::uint64 old_value;
+ sc_dt::uint64 mask;
+};
+
+
+wif_uint64_trace::wif_uint64_trace(const sc_dt::uint64& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_),
+ mask(static_cast<sc_dt::uint64>(-1))
+{
+ bit_width = width_;
+ if (bit_width < (int)(sizeof(sc_dt::uint64)*BITS_PER_BYTE))
+ mask = ~(mask << bit_width);
+ wif_type = "BIT";
+}
+
+
+bool wif_uint64_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void wif_uint64_trace::write(FILE* f)
+{
+ char buf[1000];
+ int bitindex;
+
+ // Check for overflow
+ if ((object & mask) != object)
+ {
+ for (bitindex = 0; bitindex < bit_width; bitindex++)
+ {
+ buf[bitindex]='0';
+ }
+ }
+ else
+ {
+ sc_dt::uint64 bit_mask = 1;
+ bit_mask = bit_mask << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++)
+ {
+ buf[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ buf[bitindex] = '\0';
+ std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class wif_int64_trace: public wif_trace {
+public:
+ wif_int64_trace(const sc_dt::int64& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const sc_dt::int64& object;
+ sc_dt::int64 old_value;
+ sc_dt::uint64 mask;
+};
+
+
+wif_int64_trace::wif_int64_trace(const sc_dt::int64& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_),
+ mask(static_cast<sc_dt::uint64>(-1))
+{
+ bit_width = width_;
+ if (bit_width < (int)(sizeof(sc_dt::int64)*BITS_PER_BYTE))
+ mask = ~(mask << bit_width);
+ wif_type = "BIT";
+}
+
+
+bool wif_int64_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void wif_int64_trace::write(FILE* f)
+{
+ char buf[1000];
+ int bitindex;
+
+ // Check for overflow
+ if ((object & mask) != (sc_dt::uint64)object)
+ {
+ for (bitindex = 0; bitindex < bit_width; bitindex++)
+ {
+ buf[bitindex]='0';
+ }
+ }
+ else
+ {
+ sc_dt::uint64 bit_mask = 1;
+ bit_mask = bit_mask << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++)
+ {
+ buf[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ buf[bitindex] = '\0';
+ std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class wif_bool_trace
+: public wif_trace
+{
+public:
+
+ wif_bool_trace( const bool& object_,
+ const std::string& name_,
+ const std::string& wif_name_ );
+ void write( FILE* f );
+ bool changed();
+
+protected:
+
+ const bool& object;
+ bool old_value;
+};
+
+wif_bool_trace::wif_bool_trace( const bool& object_,
+ const std::string& name_,
+ const std::string& wif_name_ )
+: wif_trace( name_, wif_name_ ), object( object_ ), old_value( object_ )
+{
+ bit_width = 0;
+ wif_type = "BIT";
+}
+
+bool
+wif_bool_trace::changed()
+{
+ return object != old_value;
+}
+
+void
+wif_bool_trace::write( FILE* f )
+{
+ if( object == true ) {
+ std::fprintf( f, "assign %s \'1\' ;\n", wif_name.c_str() );
+ } else {
+ std::fprintf( f, "assign %s \'0\' ;\n", wif_name.c_str() );
+ }
+ old_value = object;
+}
+
+//*****************************************************************************
+
+class wif_sc_bit_trace : public wif_trace {
+public:
+ wif_sc_bit_trace(const sc_dt::sc_bit& object_,
+ const std::string& name_,
+ const std::string& wif_name_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const sc_dt::sc_bit& object;
+ sc_dt::sc_bit old_value;
+};
+
+wif_sc_bit_trace::wif_sc_bit_trace(const sc_dt::sc_bit& object_,
+ const std::string& name_,
+ const std::string& wif_name_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_)
+{
+ bit_width = 0;
+ wif_type = "BIT";
+}
+
+bool wif_sc_bit_trace::changed()
+{
+ return object != old_value;
+}
+
+void wif_sc_bit_trace::write(FILE* f)
+{
+ if (object == true) {
+ std::fprintf(f, "assign %s \'1\' ;\n", wif_name.c_str());
+ } else {
+ std::fprintf(f, "assign %s \'0\' ;\n", wif_name.c_str());
+ }
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class wif_sc_logic_trace: public wif_trace {
+public:
+ wif_sc_logic_trace(const sc_dt::sc_logic& object_,
+ const std::string& name_,
+ const std::string& wif_name_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const sc_dt::sc_logic& object;
+ sc_dt::sc_logic old_value;
+};
+
+
+wif_sc_logic_trace::wif_sc_logic_trace(const sc_dt::sc_logic& object_,
+ const std::string& name_,
+ const std::string& wif_name_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_)
+{
+ bit_width = 0;
+ wif_type = "MVL";
+}
+
+
+bool wif_sc_logic_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void wif_sc_logic_trace::write(FILE* f)
+{
+ char wif_char;
+ std::fprintf(f, "assign %s \'", wif_name.c_str());
+ wif_char = map_sc_logic_state_to_wif_state(object.to_char());
+ std::fputc(wif_char, f);
+ std::fprintf(f,"\' ;\n");
+ old_value = object;
+}
+
+
+/*****************************************************************************/
+
+class wif_sc_unsigned_trace: public wif_trace {
+public:
+ wif_sc_unsigned_trace(const sc_dt::sc_unsigned& object_,
+ const std::string& name_,
+ const std::string& wif_name_);
+ void write(FILE* f);
+ bool changed();
+ void set_width();
+
+protected:
+ const sc_dt::sc_unsigned& object;
+ sc_dt::sc_unsigned old_value;
+};
+
+
+wif_sc_unsigned_trace::wif_sc_unsigned_trace(const sc_dt::sc_unsigned& object_,
+ const std::string& name_,
+ const std::string& wif_name_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_.length())
+{
+ old_value = object;
+ wif_type = "BIT";
+}
+
+bool wif_sc_unsigned_trace::changed()
+{
+ return object != old_value;
+}
+
+void wif_sc_unsigned_trace::write(FILE* f)
+{
+ static std::vector<char> buf(1024);
+ typedef std::vector<char>::size_type size_t;
+
+ if ( buf.size() < (size_t)object.length() ) {
+ size_t sz = ( (size_t)object.length() + 4096 ) & (~(size_t)(4096-1));
+ std::vector<char>( sz ).swap( buf ); // resize without copying values
+ }
+ char *buf_ptr = &buf[0];
+
+ for(int bitindex = object.length() - 1; bitindex >= 0; --bitindex) {
+ *buf_ptr++ = "01"[object[bitindex].to_bool()];
+ }
+ *buf_ptr = '\0';
+ std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), &buf[0]);
+ old_value = object;
+}
+
+void wif_sc_unsigned_trace::set_width()
+{
+ bit_width = object.length();
+}
+
+
+/*****************************************************************************/
+
+class wif_sc_signed_trace: public wif_trace {
+public:
+ wif_sc_signed_trace(const sc_dt::sc_signed& object_,
+ const std::string& name_,
+ const std::string& wif_name_);
+ void write(FILE* f);
+ bool changed();
+ void set_width();
+
+protected:
+ const sc_dt::sc_signed& object;
+ sc_dt::sc_signed old_value;
+};
+
+
+wif_sc_signed_trace::wif_sc_signed_trace(const sc_dt::sc_signed& object_,
+ const std::string& name_,
+ const std::string& wif_name_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_.length())
+{
+ old_value = object;
+ wif_type = "BIT";
+}
+
+bool wif_sc_signed_trace::changed()
+{
+ return object != old_value;
+}
+
+void wif_sc_signed_trace::write(FILE* f)
+{
+ static std::vector<char> buf(1024);
+ typedef std::vector<char>::size_type size_t;
+
+ if ( buf.size() < (size_t)object.length() ) {
+ size_t sz = ( (size_t)object.length() + 4096 ) & (~(size_t)(4096-1));
+ std::vector<char>( sz ).swap( buf ); // resize without copying values
+ }
+ char *buf_ptr = &buf[0];
+
+ for(int bitindex = object.length() - 1; bitindex >= 0; --bitindex) {
+ *buf_ptr++ = "01"[object[bitindex].to_bool()];
+ }
+ *buf_ptr = '\0';
+
+ std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), &buf[0]);
+ old_value = object;
+}
+
+void wif_sc_signed_trace::set_width()
+{
+ bit_width = object.length();
+}
+
+/*****************************************************************************/
+
+class wif_sc_uint_base_trace: public wif_trace {
+public:
+ wif_sc_uint_base_trace(const sc_dt::sc_uint_base& object_,
+ const std::string& name_,
+ const std::string& wif_name_);
+ void write(FILE* f);
+ bool changed();
+ void set_width();
+
+protected:
+ const sc_dt::sc_uint_base& object;
+ sc_dt::sc_uint_base old_value;
+};
+
+
+wif_sc_uint_base_trace::wif_sc_uint_base_trace(
+ const sc_dt::sc_uint_base& object_,
+ const std::string& name_,
+ const std::string& wif_name_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_.length())
+{
+ old_value = object;
+ wif_type = "BIT";
+}
+
+bool wif_sc_uint_base_trace::changed()
+{
+ return object != old_value;
+}
+
+void wif_sc_uint_base_trace::write(FILE* f)
+{
+ char buf[1000], *buf_ptr = buf;
+
+ int bitindex;
+ for(bitindex = object.length() - 1; bitindex >= 0; --bitindex) {
+ *buf_ptr++ = "01"[object[bitindex].to_bool()];
+ }
+ *buf_ptr = '\0';
+ std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
+ old_value = object;
+}
+
+void wif_sc_uint_base_trace::set_width()
+{
+ bit_width = object.length();
+}
+
+
+/*****************************************************************************/
+
+class wif_sc_int_base_trace: public wif_trace {
+public:
+ wif_sc_int_base_trace(const sc_dt::sc_int_base& object_,
+ const std::string& name_,
+ const std::string& wif_name_);
+ void write(FILE* f);
+ bool changed();
+ void set_width();
+
+protected:
+ const sc_dt::sc_int_base& object;
+ sc_dt::sc_int_base old_value;
+};
+
+
+wif_sc_int_base_trace::wif_sc_int_base_trace(const sc_dt::sc_int_base& object_,
+ const std::string& name_,
+ const std::string& wif_name_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_.length())
+{
+ old_value = object;
+ wif_type = "BIT";
+}
+
+bool wif_sc_int_base_trace::changed()
+{
+ return object != old_value;
+}
+
+void wif_sc_int_base_trace::write(FILE* f)
+{
+ char buf[1000], *buf_ptr = buf;
+
+ int bitindex;
+ for(bitindex = object.length() - 1; bitindex >= 0; --bitindex) {
+ *buf_ptr++ = "01"[object[bitindex].to_bool()];
+ }
+ *buf_ptr = '\0';
+
+ std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
+ old_value = object;
+}
+
+void wif_sc_int_base_trace::set_width()
+{
+ bit_width = object.length();
+}
+
+
+/*****************************************************************************/
+
+class wif_sc_fxval_trace: public wif_trace
+{
+public:
+
+ wif_sc_fxval_trace( const sc_dt::sc_fxval& object_,
+ const std::string& name_,
+ const std::string& wif_name_ );
+ void write( FILE* f );
+ bool changed();
+
+protected:
+
+ const sc_dt::sc_fxval& object;
+ sc_dt::sc_fxval old_value;
+
+};
+
+wif_sc_fxval_trace::wif_sc_fxval_trace( const sc_dt::sc_fxval& object_,
+ const std::string& name_,
+ const std::string& wif_name_ )
+: wif_trace( name_, wif_name_ ), object( object_ ), old_value( object_ )
+{
+ bit_width = 0;
+ wif_type = "real";
+}
+
+bool
+wif_sc_fxval_trace::changed()
+{
+ return object != old_value;
+}
+
+void
+wif_sc_fxval_trace::write( FILE* f )
+{
+ std::fprintf( f, "assign %s %f ; \n", wif_name.c_str(), object.to_double() );
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class wif_sc_fxval_fast_trace: public wif_trace
+{
+public:
+
+ wif_sc_fxval_fast_trace( const sc_dt::sc_fxval_fast& object_,
+ const std::string& name_,
+ const std::string& wif_name_ );
+ void write( FILE* f );
+ bool changed();
+
+protected:
+
+ const sc_dt::sc_fxval_fast& object;
+ sc_dt::sc_fxval_fast old_value;
+
+};
+
+wif_sc_fxval_fast_trace::wif_sc_fxval_fast_trace(
+ const sc_dt::sc_fxval_fast& object_,
+ const std::string& name_,
+ const std::string& wif_name_ )
+: wif_trace(name_, wif_name_), object( object_ ), old_value( object_ )
+{
+ bit_width = 0;
+ wif_type = "real";
+}
+
+bool
+wif_sc_fxval_fast_trace::changed()
+{
+ return object != old_value;
+}
+
+void
+wif_sc_fxval_fast_trace::write( FILE* f )
+{
+ std::fprintf( f, "assign %s %f ; \n", wif_name.c_str(), object.to_double() );
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class wif_sc_fxnum_trace: public wif_trace
+{
+public:
+
+ wif_sc_fxnum_trace( const sc_dt::sc_fxnum& object_,
+ const std::string& name_,
+ const std::string& wif_name_ );
+ void write( FILE* f );
+ bool changed();
+ void set_width();
+
+protected:
+
+ const sc_dt::sc_fxnum& object;
+ sc_dt::sc_fxnum old_value;
+
+};
+
+wif_sc_fxnum_trace::wif_sc_fxnum_trace( const sc_dt::sc_fxnum& object_,
+ const std::string& name_,
+ const std::string& wif_name_ )
+: wif_trace( name_, wif_name_ ),
+ object( object_ ),
+ old_value( object_.m_params.type_params(),
+ object_.m_params.enc(),
+ object_.m_params.cast_switch(),
+ 0 )
+{
+ old_value = object;
+ wif_type = "BIT";
+}
+
+bool
+wif_sc_fxnum_trace::changed()
+{
+ return object != old_value;
+}
+
+void
+wif_sc_fxnum_trace::write( FILE* f )
+{
+ static std::vector<char> buf(1024);
+ typedef std::vector<char>::size_type size_t;
+
+ if ( buf.size() < (size_t)object.wl() ) {
+ size_t sz = ( (size_t)object.wl() + 4096 ) & (~(size_t)(4096-1));
+ std::vector<char>( sz ).swap( buf ); // resize without copying values
+ }
+ char *buf_ptr = &buf[0];
+
+ for(int bitindex = object.wl() - 1; bitindex >= 0; --bitindex)
+ {
+ *buf_ptr ++ = "01"[object[bitindex]];
+ }
+ *buf_ptr = '\0';
+
+ std::fprintf( f, "assign %s \"%s\" ;\n", wif_name.c_str(), &buf[0]);
+ old_value = object;
+}
+
+void
+wif_sc_fxnum_trace::set_width()
+{
+ bit_width = object.wl();
+}
+
+/*****************************************************************************/
+
+class wif_sc_fxnum_fast_trace: public wif_trace
+{
+public:
+
+ wif_sc_fxnum_fast_trace( const sc_dt::sc_fxnum_fast& object_,
+ const std::string& name_,
+ const std::string& wif_name_ );
+ void write( FILE* f );
+ bool changed();
+ void set_width();
+
+protected:
+
+ const sc_dt::sc_fxnum_fast& object;
+ sc_dt::sc_fxnum_fast old_value;
+
+};
+
+wif_sc_fxnum_fast_trace::wif_sc_fxnum_fast_trace(
+ const sc_dt::sc_fxnum_fast& object_,
+ const std::string& name_,
+ const std::string& wif_name_ )
+: wif_trace( name_, wif_name_ ),
+ object( object_ ),
+ old_value( object_.m_params.type_params(),
+ object_.m_params.enc(),
+ object_.m_params.cast_switch(),
+ 0 )
+{
+ old_value = object;
+ wif_type = "BIT";
+}
+
+bool
+wif_sc_fxnum_fast_trace::changed()
+{
+ return object != old_value;
+}
+
+void
+wif_sc_fxnum_fast_trace::write( FILE* f )
+{
+ static std::vector<char> buf(1024);
+ typedef std::vector<char>::size_type size_t;
+
+ if ( buf.size() < (size_t)object.wl() ) {
+ size_t sz = ( (size_t)object.wl() + 4096 ) & (~(size_t)(4096-1));
+ std::vector<char>( sz ).swap( buf ); // resize without copying values
+ }
+ char *buf_ptr = &buf[0];
+
+ for(int bitindex = object.wl() - 1; bitindex >= 0; --bitindex)
+ {
+ *buf_ptr ++ = "01"[object[bitindex]];
+ }
+ *buf_ptr = '\0';
+
+ std::fprintf( f, "assign %s \"%s\" ;\n", wif_name.c_str(), &buf[0]);
+ old_value = object;
+}
+
+void
+wif_sc_fxnum_fast_trace::set_width()
+{
+ bit_width = object.wl();
+}
+
+
+/*****************************************************************************/
+
+class wif_unsigned_int_trace: public wif_trace {
+public:
+ wif_unsigned_int_trace(const unsigned& object_,
+ const std::string& name_,
+ const std::string& wif_name_, int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const unsigned& object;
+ unsigned old_value;
+ unsigned mask;
+};
+
+
+wif_unsigned_int_trace::wif_unsigned_int_trace(const unsigned& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_),
+ mask(0xffffffff)
+{
+ bit_width = width_;
+ if (bit_width < 32) {
+ mask = ~(-1 << bit_width);
+ }
+
+ wif_type = "BIT";
+}
+
+
+bool wif_unsigned_int_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void wif_unsigned_int_trace::write(FILE* f)
+{
+ char buf[1000];
+ int bitindex;
+
+ // Check for overflow
+ if ((object & mask) != object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ buf[bitindex] = '0';
+ }
+ }
+ else{
+ unsigned bit_mask = 1 << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ buf[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ buf[bitindex] = '\0';
+ std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
+ old_value = object;
+}
+
+
+/*****************************************************************************/
+
+class wif_unsigned_short_trace: public wif_trace {
+public:
+ wif_unsigned_short_trace(const unsigned short& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const unsigned short& object;
+ unsigned short old_value;
+ unsigned short mask;
+};
+
+
+wif_unsigned_short_trace::wif_unsigned_short_trace(
+ const unsigned short& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_), mask(0xffff)
+{
+ bit_width = width_;
+ if (bit_width < 16) {
+ mask = (unsigned short)~(-1 << bit_width);
+ }
+
+ wif_type = "BIT";
+}
+
+
+bool wif_unsigned_short_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void wif_unsigned_short_trace::write(FILE* f)
+{
+ char buf[1000];
+ int bitindex;
+
+ // Check for overflow
+ if ((object & mask) != object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ buf[bitindex]='0';
+ }
+ }
+ else{
+ unsigned bit_mask = 1 << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ buf[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ buf[bitindex] = '\0';
+ std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class wif_unsigned_char_trace: public wif_trace {
+public:
+ wif_unsigned_char_trace(const unsigned char& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const unsigned char& object;
+ unsigned char old_value;
+ unsigned char mask;
+};
+
+
+wif_unsigned_char_trace::wif_unsigned_char_trace(const unsigned char& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_), mask(0xff)
+{
+ bit_width = width_;
+ if (bit_width < 8) {
+ mask = (unsigned char)~(-1 << bit_width);
+ }
+
+ wif_type = "BIT";
+}
+
+
+bool wif_unsigned_char_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void wif_unsigned_char_trace::write(FILE* f)
+{
+ char buf[1000];
+ int bitindex;
+
+ // Check for overflow
+ if ((object & mask) != object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ buf[bitindex]='0';
+ }
+ }
+ else{
+ unsigned bit_mask = 1 << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ buf[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ buf[bitindex] = '\0';
+ std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class wif_unsigned_long_trace: public wif_trace {
+public:
+ wif_unsigned_long_trace(const unsigned long& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const unsigned long& object;
+ unsigned long old_value;
+ unsigned long mask;
+};
+
+
+wif_unsigned_long_trace::wif_unsigned_long_trace(const unsigned long& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_),
+ mask((unsigned long)-1L)
+{
+ bit_width = width_;
+ if (bit_width < (int)(sizeof(unsigned long)*BITS_PER_BYTE)) {
+ mask = ~(-1L << bit_width);
+ }
+
+ wif_type = "BIT";
+}
+
+
+bool wif_unsigned_long_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void wif_unsigned_long_trace::write(FILE* f)
+{
+ char buf[1000];
+ int bitindex;
+
+ // Check for overflow
+ if ((object & mask) != object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ buf[bitindex]='0';
+ }
+ }
+ else{
+ unsigned long bit_mask = 1ul << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ buf[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ buf[bitindex] = '\0';
+ std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class wif_signed_int_trace: public wif_trace {
+public:
+ wif_signed_int_trace(const int& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const int& object;
+ int old_value;
+ unsigned mask;
+};
+
+
+wif_signed_int_trace::wif_signed_int_trace(const signed& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_),
+ mask(0xffffffff)
+{
+ bit_width = width_;
+ if (bit_width < 32) {
+ mask = ~(-1 << bit_width);
+ }
+
+ wif_type = "BIT";
+}
+
+
+bool wif_signed_int_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void wif_signed_int_trace::write(FILE* f)
+{
+ char buf[1000];
+ int bitindex;
+
+ // Check for overflow
+ if (((unsigned) object & mask) != (unsigned) object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ buf[bitindex]='0';
+ }
+ }
+ else{
+ unsigned bit_mask = 1 << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ buf[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ buf[bitindex] = '\0';
+ std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class wif_signed_short_trace: public wif_trace {
+public:
+ wif_signed_short_trace(const short& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const short& object;
+ short old_value;
+ unsigned short mask;
+};
+
+
+wif_signed_short_trace::wif_signed_short_trace(const short& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_), mask(0xffff)
+{
+ bit_width = width_;
+ if (bit_width < 16) {
+ mask = (unsigned short)~(-1 << bit_width);
+ }
+
+ wif_type = "BIT";
+}
+
+
+bool wif_signed_short_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void wif_signed_short_trace::write(FILE* f)
+{
+ char buf[1000];
+ int bitindex;
+
+ // Check for overflow
+ if (((unsigned short) object & mask) != (unsigned short) object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ buf[bitindex]='0';
+ }
+ }
+ else{
+ unsigned bit_mask = 1 << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ buf[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ buf[bitindex] = '\0';
+ std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class wif_signed_char_trace: public wif_trace {
+public:
+ wif_signed_char_trace(const char& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const char& object;
+ char old_value;
+ unsigned char mask;
+};
+
+
+wif_signed_char_trace::wif_signed_char_trace(const char& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_), mask(0xff)
+{
+ bit_width = width_;
+ if (bit_width < 8) {
+ mask = (unsigned char)~(-1 << bit_width);
+ }
+
+ wif_type = "BIT";
+}
+
+
+bool wif_signed_char_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void wif_signed_char_trace::write(FILE* f)
+{
+ char buf[1000];
+ int bitindex;
+
+ // Check for overflow
+ if (((unsigned char) object & mask) != (unsigned char) object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ buf[bitindex]='0';
+ }
+ }
+ else{
+ unsigned bit_mask = 1 << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ buf[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ buf[bitindex] = '\0';
+ std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class wif_signed_long_trace: public wif_trace {
+public:
+ wif_signed_long_trace(const long& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const long& object;
+ long old_value;
+ unsigned long mask;
+};
+
+
+wif_signed_long_trace::wif_signed_long_trace(const long& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_),
+ mask((unsigned long)-1L)
+{
+ bit_width = width_;
+ if (bit_width < (int)(sizeof(long)*BITS_PER_BYTE)) {
+ mask = ~(-1L << bit_width);
+ }
+
+ wif_type = "BIT";
+}
+
+
+bool wif_signed_long_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void wif_signed_long_trace::write(FILE* f)
+{
+ char buf[1000];
+ int bitindex;
+
+ // Check for overflow
+ if (((unsigned long) object & mask) != (unsigned long) object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ buf[bitindex]='0';
+ }
+ } else {
+ unsigned long bit_mask = 1ul << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ buf[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ buf[bitindex] = '\0';
+ std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
+ old_value = object;
+}
+
+
+/*****************************************************************************/
+
+class wif_float_trace: public wif_trace {
+public:
+ wif_float_trace(const float& object_,
+ const std::string& name_,
+ const std::string& wif_name_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const float& object;
+ float old_value;
+};
+
+wif_float_trace::wif_float_trace(const float& object_,
+ const std::string& name_,
+ const std::string& wif_name_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_)
+{
+ bit_width = 0;
+ wif_type = "real";
+}
+
+bool wif_float_trace::changed()
+{
+ return object != old_value;
+}
+
+void wif_float_trace::write(FILE* f)
+{
+ std::fprintf(f,"assign %s %f ; \n", wif_name.c_str(), object);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class wif_double_trace: public wif_trace {
+public:
+ wif_double_trace(const double& object_,
+ const std::string& name_,
+ const std::string& wif_name_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const double& object;
+ double old_value;
+};
+
+wif_double_trace::wif_double_trace(const double& object_,
+ const std::string& name_,
+ const std::string& wif_name_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_)
+{
+ bit_width = 0;
+ wif_type = "real";
+}
+
+bool wif_double_trace::changed()
+{
+ return object != old_value;
+}
+
+void wif_double_trace::write(FILE* f)
+{
+ std::fprintf(f,"assign %s %f ; \n", wif_name.c_str(), object);
+ old_value = object;
+}
+
+
+/*****************************************************************************/
+
+class wif_enum_trace : public wif_trace {
+public:
+ wif_enum_trace(const unsigned& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ const char** enum_literals);
+ void write(FILE* f);
+ bool changed();
+ // Hides the definition of the same (virtual) function in wif_trace
+ void print_variable_declaration_line(FILE* f);
+
+protected:
+ const unsigned& object;
+ unsigned old_value;
+
+ const char** literals;
+ unsigned nliterals;
+ std::string type_name;
+
+ ~wif_enum_trace();
+};
+
+
+wif_enum_trace::wif_enum_trace(const unsigned& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ const char** enum_literals_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_),
+ literals(enum_literals_), nliterals(0), type_name(name_ + "__type__")
+{
+ // find number of enumeration literals - counting loop
+ for (nliterals = 0; enum_literals_[nliterals]; nliterals++) continue;
+
+ bit_width = 0;
+ wif_type = type_name.c_str();
+}
+
+void wif_enum_trace::print_variable_declaration_line(FILE* f)
+{
+ std::fprintf(f, "type scalar \"%s\" enum ", wif_type);
+
+ for (unsigned i = 0; i < nliterals; i++)
+ std::fprintf(f, "\"%s\", ", literals[i]);
+ std::fprintf(f, "\"SC_WIF_UNDEF\" ;\n");
+
+ std::fprintf(f, "declare %s \"%s\" \"%s\" ",
+ wif_name.c_str(), name.c_str(), wif_type);
+ std::fprintf(f, "variable ;\n");
+ std::fprintf(f, "start_trace %s ;\n", wif_name.c_str());
+}
+
+bool wif_enum_trace::changed()
+{
+ return object != old_value;
+}
+
+void wif_enum_trace::write(FILE* f)
+{
+ static bool warning_issued = false;
+ const char* lit;
+
+ if (object >= nliterals) { // Note unsigned value is always greater than 0
+ if (!warning_issued) {
+ SC_REPORT_WARNING( SC_ID_TRACING_INVALID_ENUM_VALUE_
+ , name.c_str() );
+ warning_issued = true;
+ }
+ lit = "SC_WIF_UNDEF";
+ }
+ else
+ {
+ lit = literals[object];
+ }
+ std::fprintf( f, "assign %s \"%s\" ;\n", wif_name.c_str(), lit );
+ old_value = object;
+}
+
+wif_enum_trace::~wif_enum_trace()
+{
+ /* Intentionally blank */
+}
+
+
+template <class T>
+class wif_T_trace
+: public wif_trace
+{
+public:
+
+ wif_T_trace( const T& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ wif_trace_file::wif_enum type_ )
+ : wif_trace( name_, wif_name_),
+ object( object_ ),
+ old_value( object_ )
+ { wif_type = wif_names[type_]; }
+
+ void write( FILE* f )
+ {
+ std::fprintf( f,
+ "assign %s \"%s\" ;\n",
+ wif_name.c_str(),
+ object.to_string().c_str() );
+ old_value = object;
+ }
+
+ bool changed()
+ { return !(object == old_value); }
+
+ void set_width()
+ { bit_width = object.length(); }
+
+protected:
+
+ const T& object;
+ T old_value;
+};
+
+typedef wif_T_trace<sc_dt::sc_bv_base> wif_sc_bv_trace;
+typedef wif_T_trace<sc_dt::sc_lv_base> wif_sc_lv_trace;
+
+
+//***********************************************************************
+// wif_trace_file functions
+//***********************************************************************
+
+
+wif_trace_file::wif_trace_file(const char * name)
+ : sc_trace_file_base( name, "awif" )
+ , wif_name_index(0)
+ , previous_time_units_low(0)
+ , previous_time_units_high(0)
+ , previous_time(0.0)
+ , traces()
+{}
+
+
+void wif_trace_file::do_initialize()
+{
+ char buf[2000];
+
+ // init
+ std::fprintf(fp, "init ;\n\n");
+
+ //timescale:
+ if (timescale_unit == 1e-15) std::sprintf(buf,"0");
+ else if(timescale_unit == 1e-14) std::sprintf(buf,"1");
+ else if(timescale_unit == 1e-13) std::sprintf(buf,"2");
+ else if(timescale_unit == 1e-12) std::sprintf(buf,"3");
+ else if(timescale_unit == 1e-11) std::sprintf(buf,"4");
+ else if(timescale_unit == 1e-10) std::sprintf(buf,"5");
+ else if(timescale_unit == 1e-9) std::sprintf(buf,"6");
+ else if(timescale_unit == 1e-8) std::sprintf(buf,"7");
+ else if(timescale_unit == 1e-7) std::sprintf(buf,"8");
+ else if(timescale_unit == 1e-6) std::sprintf(buf,"9");
+ else if(timescale_unit == 1e-5) std::sprintf(buf,"10");
+ else if(timescale_unit == 1e-4) std::sprintf(buf,"11");
+ else if(timescale_unit == 1e-3) std::sprintf(buf,"12");
+ else if(timescale_unit == 1e-2) std::sprintf(buf,"13");
+ else if(timescale_unit == 1e-1) std::sprintf(buf,"14");
+ else if(timescale_unit == 1e0) std::sprintf(buf,"15");
+ else if(timescale_unit == 1e1) std::sprintf(buf,"16");
+ else if(timescale_unit == 1e2) std::sprintf(buf,"17");
+ std::fprintf(fp,"header %s \"%s\" ;\n\n", buf, sc_version());
+
+ std::fprintf(fp, "comment \"ASCII WIF file produced on date: %s\" ;\n"
+ , localtime_string().c_str());
+
+ //version:
+ std::fprintf(fp, "comment \"Created by %s\" ;\n", sc_version());
+ //conversion info
+ std::fprintf(fp, "comment \"Convert this file to binary WIF format using a2wif\" ;\n\n");
+
+ // Define the two types we need to represent bool and sc_logic
+ std::fprintf(fp, "type scalar \"BIT\" enum '0', '1' ;\n");
+ std::fprintf(fp, "type scalar \"MVL\" enum '0', '1', 'X', 'Z', '?' ;\n");
+ std::fprintf(fp, "\n");
+
+ //variable definitions:
+ int i;
+ for (i = 0; i < (int)traces.size(); i++) {
+ wif_trace* t = traces[i];
+ t->set_width(); //needed for all vectors
+ t->print_variable_declaration_line(fp);
+ }
+
+ double inittime = sc_time_stamp().to_seconds();
+ previous_time = inittime/timescale_unit;
+
+ // Dump all values at initial time
+ std::sprintf(buf,
+ "All initial values are dumped below at time "
+ "%g sec = %g timescale units.",
+ inittime,
+ inittime/timescale_unit
+ );
+ write_comment(buf);
+
+ double_to_special_int64(inittime/timescale_unit,
+ &previous_time_units_high,
+ &previous_time_units_low );
+
+ for (i = 0; i < (int)traces.size(); i++) {
+ wif_trace* t = traces[i];
+ t->write(fp);
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+#define DEFN_TRACE_METHOD(tp) \
+void \
+wif_trace_file::trace( const tp& object_, const std::string& name_ ) \
+{ \
+ if( add_trace_check(name_) ) \
+ traces.push_back( new wif_ ## tp ## _trace( object_, \
+ name_, \
+ obtain_name() ) ); \
+}
+
+DEFN_TRACE_METHOD(bool)
+DEFN_TRACE_METHOD(float)
+DEFN_TRACE_METHOD(double)
+
+#undef DEFN_TRACE_METHOD
+#define DEFN_TRACE_METHOD(tp) \
+void \
+wif_trace_file::trace(const sc_dt::tp& object_, const std::string& name_) \
+{ \
+ if( add_trace_check(name_) ) \
+ traces.push_back( new wif_ ## tp ## _trace( object_, \
+ name_, \
+ obtain_name() ) ); \
+}
+
+DEFN_TRACE_METHOD(sc_bit)
+DEFN_TRACE_METHOD(sc_logic)
+
+DEFN_TRACE_METHOD(sc_signed)
+DEFN_TRACE_METHOD(sc_unsigned)
+DEFN_TRACE_METHOD(sc_int_base)
+DEFN_TRACE_METHOD(sc_uint_base)
+
+DEFN_TRACE_METHOD(sc_fxval)
+DEFN_TRACE_METHOD(sc_fxval_fast)
+DEFN_TRACE_METHOD(sc_fxnum)
+DEFN_TRACE_METHOD(sc_fxnum_fast)
+
+#undef DEFN_TRACE_METHOD
+
+
+#define DEFN_TRACE_METHOD_SIGNED(tp) \
+void \
+wif_trace_file::trace( const tp& object_, \
+ const std::string& name_, \
+ int width_ ) \
+{ \
+ if( add_trace_check(name_) ) \
+ traces.push_back( new wif_signed_ ## tp ## _trace( object_, \
+ name_, \
+ obtain_name(), \
+ width_ ) ); \
+}
+
+#define DEFN_TRACE_METHOD_UNSIGNED(tp) \
+void \
+wif_trace_file::trace( const unsigned tp& object_, \
+ const std::string& name_, \
+ int width_ ) \
+{ \
+ if( add_trace_check(name_) ) \
+ traces.push_back( new wif_unsigned_ ## tp ## _trace( object_, \
+ name_, \
+ obtain_name(), \
+ width_ ) ); \
+}
+
+DEFN_TRACE_METHOD_SIGNED(char)
+DEFN_TRACE_METHOD_SIGNED(short)
+DEFN_TRACE_METHOD_SIGNED(int)
+DEFN_TRACE_METHOD_SIGNED(long)
+
+DEFN_TRACE_METHOD_UNSIGNED(char)
+DEFN_TRACE_METHOD_UNSIGNED(short)
+DEFN_TRACE_METHOD_UNSIGNED(int)
+DEFN_TRACE_METHOD_UNSIGNED(long)
+
+#undef DEFN_TRACE_METHOD_SIGNED
+#undef DEFN_TRACE_METHOD_UNSIGNED
+
+
+#define DEFN_TRACE_METHOD_LONG_LONG(tp) \
+void \
+wif_trace_file::trace( const sc_dt::tp& object_, \
+ const std::string& name_, \
+ int width_ ) \
+{ \
+ if( add_trace_check(name_) ) \
+ traces.push_back( new wif_ ## tp ## _trace( object_, \
+ name_, \
+ obtain_name(), \
+ width_ ) ); \
+}
+
+DEFN_TRACE_METHOD_LONG_LONG(int64)
+DEFN_TRACE_METHOD_LONG_LONG(uint64)
+#undef DEFN_TRACE_METHOD_LONG_LONG
+
+void
+wif_trace_file::trace( const unsigned& object_,
+ const std::string& name_,
+ const char** enum_literals_ )
+{
+ if( add_trace_check(name_) )
+ traces.push_back( new wif_enum_trace( object_,
+ name_,
+ obtain_name(),
+ enum_literals_ ) );
+}
+
+void
+wif_trace_file::trace( const sc_dt::sc_bv_base& object_,
+ const std::string& name_ )
+{
+ traceT( object_, name_, WIF_BIT );
+}
+
+void
+wif_trace_file::trace( const sc_dt::sc_lv_base& object_,
+ const std::string& name_ )
+{
+ traceT( object_, name_, WIF_MVL );
+}
+
+
+void
+wif_trace_file::write_comment(const std::string& comment)
+{
+ if(!fp) open_fp();
+ //no newline in comments allowed
+ std::fprintf(fp, "comment \"%s\" ;\n", comment.c_str());
+}
+
+
+void
+wif_trace_file::cycle(bool this_is_a_delta_cycle)
+{
+ unsigned now_units_high, now_units_low;
+
+ // Trace delta cycles only when enabled
+ if (!delta_cycles() && this_is_a_delta_cycle) return;
+
+ // Check for initialization
+ if( initialize() ) {
+ return;
+ };
+
+ // double now_units = sc_simulation_time() / timescale_unit;
+ double now_units = sc_time_stamp().to_seconds() / timescale_unit;
+
+ double_to_special_int64(now_units, &now_units_high, &now_units_low );
+
+ // Now do the real stuff
+ unsigned delta_units_high, delta_units_low;
+ double diff_time;
+ diff_time = now_units - previous_time;
+ double_to_special_int64(diff_time, &delta_units_high, &delta_units_low);
+ if (this_is_a_delta_cycle && (diff_time == 0.0))
+ delta_units_low++; // Increment time for delta cycle simulation
+ // Note that in the last statement above, we are assuming no more
+ // than 2^32 delta cycles - seems realistic
+
+ bool time_printed = false;
+ wif_trace* const* const l_traces = &traces[0];
+ for (int i = 0; i < (int)traces.size(); i++) {
+ wif_trace* t = l_traces[i];
+ if(t->changed()){
+ if(time_printed == false){
+ if(delta_units_high){
+ std::fprintf(fp, "delta_time %u%09u ;\n", delta_units_high,
+ delta_units_low);
+ }
+ else{
+ std::fprintf(fp, "delta_time %u ;\n", delta_units_low);
+ }
+ time_printed = true;
+ }
+
+ // Write the variable
+ t->write(fp);
+ }
+ }
+
+ if(time_printed) {
+ std::fprintf(fp, "\n"); // Put another newline
+ // We update previous_time_units only when we print time because
+ // this field stores the previous time that was printed, not the
+ // previous time this function was called
+ previous_time_units_high = now_units_high;
+ previous_time_units_low = now_units_low;
+ previous_time = now_units;
+ }
+}
+
+#if 0
+void
+wif_trace_file::create_wif_name(std::string* ptr_to_str)
+{
+ obtain_name().swap(*ptr_to_str);
+}
+#endif
+
+// Create a WIF name for a variable
+std::string
+wif_trace_file::obtain_name()
+{
+ char buf[32];
+ std::sprintf( buf, "O%d", wif_name_index ++ );
+ return buf;
+}
+
+wif_trace_file::~wif_trace_file()
+{
+ for( int i = 0; i < (int)traces.size(); i++ ) {
+ wif_trace* t = traces[i];
+ delete t;
+ }
+}
+
+// Map sc_logic values to values understandable by WIF
+static char
+map_sc_logic_state_to_wif_state(char in_char)
+{
+ char out_char;
+
+ switch(in_char){
+ case 'U':
+ case 'X':
+ case 'W':
+ case 'D':
+ out_char = 'X';
+ break;
+ case '0':
+ case 'L':
+ out_char = '0';
+ break;
+ case '1':
+ case 'H':
+ out_char = '1';
+ break;
+ case 'Z':
+ out_char = 'Z';
+ break;
+ default:
+ out_char = '?';
+ }
+ return out_char;
+}
+
+// ----------------------------------------------------------------------------
+
+// Create the trace file
+sc_trace_file*
+sc_create_wif_trace_file(const char * name)
+{
+ sc_trace_file *tf = new wif_trace_file(name);
+ return tf;
+}
+
+
+void
+sc_close_wif_trace_file( sc_trace_file* tf )
+{
+ wif_trace_file* wif_tf = static_cast<wif_trace_file*>(tf);
+ delete wif_tf;
+}
+
+} // namespace sc_core
diff --git a/ext/systemc/src/sysc/tracing/sc_wif_trace.h b/ext/systemc/src/sysc/tracing/sc_wif_trace.h
new file mode 100644
index 000000000..b4de46e1b
--- /dev/null
+++ b/ext/systemc/src/sysc/tracing/sc_wif_trace.h
@@ -0,0 +1,222 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_wif_trace.h - Implementation of WIF tracing.
+
+ Original Author - Abhijit Ghosh, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ Acknowledgement: The tracing mechanism is based on the tracing
+ mechanism developed at Infineon (formerly Siemens HL). Though this
+ code is somewhat different, and significantly enhanced, the basics
+ are identical to what was originally contributed by Infineon.
+ The contribution of Infineon in the development of this tracing
+ technology is hereby acknowledged.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ Instead of creating the binary WIF format, we create the ASCII
+ WIF format which can be converted to the binary format using
+ a2wif (utility that comes with VSS from Synopsys). This way,
+ a user who does not have Synopsys VSS can still create WIF
+ files, but the files can only be viewed by users who have VSS.
+
+ *****************************************************************************/
+
+#ifndef SC_WIF_TRACE_H
+#define SC_WIF_TRACE_H
+
+#include <cstdio>
+#include "sysc/datatypes/int/sc_nbdefs.h"
+#include "sysc/tracing/sc_trace_file_base.h"
+
+namespace sc_core {
+
+class wif_trace; // defined in wif_trace.cc
+template<class T> class wif_T_trace;
+
+class wif_trace_file
+ : public sc_trace_file_base
+{
+public:
+ enum wif_enum {WIF_BIT=0, WIF_MVL=1, WIF_REAL=2, WIF_LAST};
+
+ // Create a wif trace file.
+ // `Name' forms the base of the name to which `.awif' is added.
+ explicit wif_trace_file(const char *name);
+
+ ~wif_trace_file();
+
+protected:
+ // These are all virtual functions in sc_trace_file and
+ // they need to be defined here.
+
+ // Trace a boolean object (single bit)
+ void trace(const bool& object, const std::string& name);
+
+ // Trace a sc_bit object (single bit)
+ void trace(const sc_dt::sc_bit& object, const std::string& name);
+
+ // Trace a sc_logic object (single bit)
+ void trace(const sc_dt::sc_logic& object, const std::string& name);
+
+ // Trace an unsigned char with the given width
+ void trace(const unsigned char& object, const std::string& name,
+ int width);
+
+ // Trace an unsigned short with the given width
+ void trace(const unsigned short& object, const std::string& name,
+ int width);
+
+ // Trace an unsigned int with the given width
+ void trace(const unsigned int& object, const std::string& name,
+ int width);
+
+ // Trace an unsigned long with the given width
+ void trace(const unsigned long& object, const std::string& name,
+ int width);
+
+ // Trace a signed char with the given width
+ void trace(const char& object, const std::string& name, int width);
+
+ // Trace a signed short with the given width
+ void trace(const short& object, const std::string& name, int width);
+
+ // Trace a signed int with the given width
+ void trace(const int& object, const std::string& name, int width);
+
+ // Trace a signed long with the given width
+ void trace(const long& object, const std::string& name, int width);
+
+ // Trace a signed long long with the given width
+ void trace(const sc_dt::int64& object, const std::string& name,
+ int width);
+
+ // Trace an usigned long long with the given width
+ void trace(const sc_dt::uint64& object, const std::string& name,
+ int width);
+
+ // Trace a float
+ void trace(const float& object, const std::string& name);
+
+ // Trace a double
+ void trace(const double& object, const std::string& name);
+
+ // Trace sc_unsigned
+ void trace (const sc_dt::sc_unsigned& object,
+ const std::string& name);
+
+ // Trace sc_signed
+ void trace (const sc_dt::sc_signed& object,
+ const std::string& name);
+
+ // Trace sc_uint_base
+ void trace (const sc_dt::sc_uint_base& object,
+ const std::string& name);
+
+ // Trace sc_int_base
+ void trace (const sc_dt::sc_int_base& object, const std::string& name);
+
+ // Trace sc_fxval
+ void trace( const sc_dt::sc_fxval& object, const std::string& name );
+
+ // Trace sc_fxval_fast
+ void trace( const sc_dt::sc_fxval_fast& object,
+ const std::string& name );
+
+ // Trace sc_fxnum
+ void trace( const sc_dt::sc_fxnum& object, const std::string& name );
+
+ // Trace sc_fxnum_fast
+ void trace( const sc_dt::sc_fxnum_fast& object,
+ const std::string& name );
+
+ template<class T>
+ void traceT(const T& object, const std::string& name, wif_enum type)
+ {
+ if( add_trace_check(name) )
+ traces.push_back( new wif_T_trace<T>( object, name
+ , obtain_name(),type ) );
+ }
+
+ // Trace sc_bv_base (sc_bv)
+ virtual void trace( const sc_dt::sc_bv_base& object,
+ const std::string& name );
+
+ // Trace sc_lv_base (sc_lv)
+ virtual void trace( const sc_dt::sc_lv_base& object,
+ const std::string& name );
+
+ // Trace an enumerated object - where possible output the enumeration literals
+ // in the trace file. Enum literals is a null terminated array of null
+ // terminated char* literal strings.
+ void trace(const unsigned& object, const std::string& name,
+ const char** enum_literals);
+
+ // Output a comment to the trace file
+ void write_comment(const std::string& comment);
+
+ // Write trace info for cycle.
+ void cycle(bool delta_cycle);
+
+private:
+
+#if SC_TRACING_PHASE_CALLBACKS_
+ // avoid hidden overload warnings
+ virtual void trace( sc_trace_file* ) const { sc_assert(false); }
+#endif // SC_TRACING_PHASE_CALLBACKS_
+
+ // Initialize the tracing mechanism
+ virtual void do_initialize();
+
+ unsigned wif_name_index; // Number of variables traced
+
+ unsigned previous_time_units_low; // Previous time as 64 bit integer
+ unsigned previous_time_units_high;
+ double previous_time; // Previous time as a double
+
+public:
+ // Create wif names for each variable
+ std::string obtain_name();
+
+ // Array to store the variables traced
+ std::vector<wif_trace*> traces;
+};
+
+} // namespace sc_core
+
+#endif // SC_WIF_TRACE_H
+// Taf!
diff --git a/ext/systemc/src/sysc/utils/sc_hash.cpp b/ext/systemc/src/sysc/utils/sc_hash.cpp
new file mode 100644
index 000000000..fc97fe416
--- /dev/null
+++ b/ext/systemc/src/sysc/utils/sc_hash.cpp
@@ -0,0 +1,670 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_hash.cpp -- Implementation of a chained hash table with MTF
+ (move-to-front).
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+#include <assert.h>
+#include <stdlib.h> // duplicate (c)stdlib.h headers for Solaris
+#include <cstdlib>
+#include <cstddef>
+#include <string.h>
+
+#include "sysc/kernel/sc_cmnhdr.h"
+#include "sysc/utils/sc_hash.h"
+#include "sysc/utils/sc_mempool.h"
+
+namespace sc_core {
+
+// we can't assume global availability of uintptr_t,
+// approximate it by size_t
+typedef std::size_t uintptr_t;
+
+const double PHASH_DEFAULT_GROW_FACTOR = 2.0;
+
+class sc_phash_elem {
+ friend class sc_phash_base;
+ friend class sc_phash_base_iter;
+
+private:
+ void* key;
+ void* contents;
+ sc_phash_elem* next;
+
+ sc_phash_elem( void* k, void* c, sc_phash_elem* n )
+ : key(k), contents(c), next(n) { }
+ sc_phash_elem() : key(0), contents(0), next(0) { }
+ ~sc_phash_elem() { }
+
+ static void* operator new(std::size_t sz)
+ { return sc_mempool::allocate(sz); }
+ static void operator delete(void* p, std::size_t sz)
+ { sc_mempool::release(p, sz); }
+};
+
+
+sc_phash_base::sc_phash_base(
+ void* def,
+ int size,
+ int density,
+ double grow,
+ bool reorder,
+ unsigned (*hash_fn)(const void*),
+ int (*cmp_fn)(const void*, const void*)
+) :
+ default_value(def), num_bins(0), num_entries(0), max_density(density),
+ reorder_flag(reorder), grow_factor(grow), bins(0), hash(hash_fn),
+ cmpr(cmp_fn)
+{
+ if (size <= 0)
+ size = PHASH_DEFAULT_INIT_TABLE_SIZE;
+ else if ((size % 2) == 0)
+ size += 1;
+ num_bins = size;
+ bins = new sc_phash_elem*[size];
+ for (int i = 0; i < size; ++i)
+ bins[i] = 0;
+}
+
+void
+sc_phash_base::set_cmpr_fn(cmpr_fn_t c)
+{
+ cmpr = c;
+}
+
+void
+sc_phash_base::set_hash_fn(hash_fn_t h)
+{
+ hash = h;
+}
+
+sc_phash_base::~sc_phash_base()
+{
+ sc_phash_elem* ptr;
+ sc_phash_elem* next;
+
+ for (int i = 0; i < num_bins; ++i) {
+ ptr = bins[i];
+ while (ptr != 0) {
+ next = ptr->next;
+ delete ptr;
+ ptr = next;
+ }
+ }
+ delete[] bins;
+}
+
+void
+sc_phash_base::rehash()
+{
+ sc_phash_elem* ptr;
+ sc_phash_elem* next;
+ sc_phash_elem** old_bins = bins;
+
+ int old_num_bins = num_bins;
+ unsigned hash_val;
+
+ num_bins = (int) (grow_factor * old_num_bins);
+ if (num_bins % 2 == 0)
+ ++num_bins;
+
+ num_entries = 0;
+ bins = new sc_phash_elem*[num_bins];
+ memset( bins, 0, sizeof(sc_phash_elem*) * num_bins );
+
+ for (int i = 0; i < old_num_bins; ++i) {
+ ptr = old_bins[i];
+ while (ptr != 0) {
+ next = ptr->next;
+ hash_val = do_hash(ptr->key);
+ ptr->next = bins[hash_val];
+ bins[hash_val] = ptr;
+ ++num_entries;
+ ptr = next;
+ }
+ }
+ delete[] old_bins;
+}
+
+sc_phash_elem*
+sc_phash_base::find_entry_q( unsigned hash_val, const void* key, sc_phash_elem*** plast )
+{
+ sc_phash_elem** last = &(bins[hash_val]);
+ sc_phash_elem* ptr = *last;
+
+ /* The (ptr->key != key) here is meant by the "q" */
+ while ((ptr != 0) && (ptr->key != key)) {
+ /* ^^ right here */
+ last = &(ptr->next);
+ ptr = *last;
+ }
+ if ((ptr != 0) && reorder_flag) {
+ *last = ptr->next;
+ ptr->next = bins[hash_val];
+ bins[hash_val] = ptr;
+ last = &(bins[hash_val]);
+ }
+ if (plast) *plast = last;
+ return ptr;
+}
+
+sc_phash_elem*
+sc_phash_base::find_entry_c( unsigned hash_val, const void* key, sc_phash_elem*** plast )
+{
+ sc_phash_elem** last = &(bins[hash_val]);
+ sc_phash_elem* ptr = *last;
+
+ while ((ptr != 0) && ((*cmpr)(ptr->key, key) != 0)) {
+ last = &(ptr->next);
+ ptr = *last;
+ }
+ /* Bring to front */
+ if ((ptr != 0) && reorder_flag) {
+ *last = ptr->next;
+ ptr->next = bins[hash_val];
+ bins[hash_val] = ptr;
+ last = &(bins[hash_val]);
+ }
+ if (plast) *plast = last;
+ return ptr;
+}
+
+sc_phash_elem*
+sc_phash_base::add_direct( void* key, void* contents, unsigned hash_val )
+{
+ if (num_entries / num_bins >= max_density) {
+ rehash();
+ hash_val = do_hash(key);
+ }
+
+ sc_phash_elem* new_entry = new sc_phash_elem(key, contents, bins[hash_val]);
+ bins[hash_val] = new_entry;
+ ++num_entries;
+ return new_entry;
+}
+
+void
+sc_phash_base::erase()
+{
+ for (int i = 0; i < num_bins; ++i) {
+ sc_phash_elem* ptr = bins[i];
+ while (ptr != 0) {
+ sc_phash_elem* next = ptr->next;
+ delete ptr;
+ ptr = next;
+ --num_entries;
+ }
+ bins[i] = 0;
+ }
+ assert(num_entries == 0);
+}
+
+void
+sc_phash_base::erase(void (*kfree)(void*))
+{
+ for (int i = 0; i < num_bins; ++i) {
+ sc_phash_elem* ptr = bins[i];
+ while (ptr != 0) {
+ sc_phash_elem* next = ptr->next;
+ (*kfree)(ptr->key);
+ delete ptr;
+ ptr = next;
+ --num_entries;
+ }
+ bins[i] = 0;
+ }
+ assert(num_entries == 0);
+}
+
+void
+sc_phash_base::copy( const sc_phash_base* b )
+{
+ erase();
+ iterator iter((sc_phash_base*) b); /* cast away the const */
+ for ( ; ! iter.empty(); iter++)
+ insert( iter.key(), iter.contents() );
+}
+
+void
+sc_phash_base::copy(const sc_phash_base& b, void* (*kdup)(const void*), void (*kfree)(void*))
+{
+ erase(kfree);
+ iterator iter((sc_phash_base&) b);
+ for ( ; ! iter.empty(); iter++)
+ insert( (*kdup)(iter.key()), iter.contents() );
+}
+
+int
+sc_phash_base::insert( void* k, void* c )
+{
+ unsigned hash_val = do_hash(k);
+ sc_phash_elem* ptr = find_entry( hash_val, k );
+ if (ptr == 0) {
+ (void) add_direct(k, c, hash_val);
+ return 0;
+ }
+ else {
+ ptr->contents = c;
+ return 1;
+ }
+}
+
+int
+sc_phash_base::insert( void* k, void* c, void* (*kdup)(const void*) )
+{
+ unsigned hash_val = do_hash(k);
+ sc_phash_elem* ptr = find_entry( hash_val, k );
+ if (ptr == 0) {
+ (void) add_direct((*kdup)(k), c, hash_val);
+ return 0;
+ }
+ else {
+ ptr->contents = c;
+ return 1;
+ }
+}
+
+int
+sc_phash_base::insert_if_not_exists( void* k, void* c )
+{
+ unsigned hash_val = do_hash(k);
+ sc_phash_elem* ptr = find_entry( hash_val, k );
+ if (ptr == 0) {
+ (void) add_direct( k, c, hash_val );
+ return 0;
+ }
+ else
+ return 1;
+}
+
+int
+sc_phash_base::insert_if_not_exists( void* k, void* c, void* (*kdup)(const void*) )
+{
+ unsigned hash_val = do_hash(k);
+ sc_phash_elem* ptr = find_entry( hash_val, k );
+ if (ptr == 0) {
+ (void) add_direct( (*kdup)(k), c, hash_val );
+ return 0;
+ }
+ else
+ return 1;
+}
+
+int
+sc_phash_base::remove( const void* k )
+{
+ unsigned hash_val = do_hash(k);
+ sc_phash_elem** last;
+ sc_phash_elem* ptr = find_entry( hash_val, k, &last );
+
+ if (ptr == 0)
+ return 0;
+
+ assert(*last == ptr);
+ *last = ptr->next;
+ delete ptr;
+ --num_entries;
+ return 1;
+}
+
+int
+sc_phash_base::remove( const void* k, void** pk, void** pc )
+{
+ unsigned hash_val = do_hash(k);
+ sc_phash_elem** last;
+ sc_phash_elem* ptr = find_entry( hash_val, k, &last );
+
+ if (ptr == 0) {
+ *pk = 0;
+ *pc = 0;
+ return 0;
+ }
+ else {
+ *pk = ptr->key;
+ *pc = ptr->contents;
+ }
+
+ assert(*last == ptr);
+ *last = ptr->next;
+ delete ptr;
+ --num_entries;
+ return 1;
+}
+
+int
+sc_phash_base::remove(const void* k, void (*kfree)(void*))
+{
+ void* rk;
+ void* rc;
+ if (remove(k, &rk, &rc)) {
+ (*kfree)(rk);
+ return 1;
+ }
+ else
+ return 0;
+}
+
+int
+sc_phash_base::remove_by_contents( const void* c )
+{
+ sc_phash_elem** last;
+ sc_phash_elem* ptr;
+
+ int num_removed = 0;
+ for (int i = 0; i < num_bins; ++i) {
+ last = &(bins[i]);
+ ptr = *last;
+ while (ptr != 0) {
+ if (ptr->contents != c) {
+ last = &(ptr->next);
+ ptr = *last;
+ }
+ else {
+ *last = ptr->next;
+ delete ptr;
+ ptr = *last;
+ --num_entries;
+ ++num_removed;
+ }
+ }
+ }
+ return num_removed;
+}
+
+int
+sc_phash_base::remove_by_contents( bool (*predicate)(const void* c, void* arg), void* arg )
+{
+ sc_phash_elem** last;
+ sc_phash_elem* ptr;
+
+ int num_removed = 0;
+ for (int i = 0; i < num_bins; ++i) {
+ last = &(bins[i]);
+ ptr = *last;
+ while (ptr != 0) {
+ if (! (*predicate)(ptr->contents, arg)) {
+ last = &(ptr->next);
+ ptr = *last;
+ }
+ else {
+ *last = ptr->next;
+ delete ptr;
+ ptr = *last;
+ --num_entries;
+ ++num_removed;
+ }
+ }
+ }
+ return num_removed;
+}
+
+int
+sc_phash_base::remove_by_contents( const void* c, void (*kfree)(void*) )
+{
+ sc_phash_elem** last;
+ sc_phash_elem* ptr;
+
+ int num_removed = 0;
+ for (int i = 0; i < num_bins; ++i) {
+ last = &(bins[i]);
+ ptr = *last;
+ while (ptr != 0) {
+ if (ptr->contents != c) {
+ last = &(ptr->next);
+ ptr = *last;
+ }
+ else {
+ *last = ptr->next;
+ (*kfree)(ptr->key);
+ delete ptr;
+ ptr = *last;
+ --num_entries;
+ ++num_removed;
+ }
+ }
+ }
+ return num_removed;
+}
+
+int
+sc_phash_base::remove_by_contents( bool (*predicate)(const void*, void*), void* arg, void (*kfree)(void*))
+{
+ sc_phash_elem** last;
+ sc_phash_elem* ptr;
+
+ int num_removed = 0;
+ for (int i = 0; i < num_bins; ++i) {
+ last = &(bins[i]);
+ ptr = *last;
+ while (ptr != 0) {
+ if (! (*predicate)(ptr->contents, arg)) {
+ last = &(ptr->next);
+ ptr = *last;
+ }
+ else {
+ *last = ptr->next;
+ (*kfree)(ptr->key);
+ delete ptr;
+ ptr = *last;
+ --num_entries;
+ ++num_removed;
+ }
+ }
+ }
+ return num_removed;
+}
+
+int
+sc_phash_base::lookup( const void* k, void** c_ptr ) const
+{
+ unsigned hash_val = do_hash(k);
+ sc_phash_elem* ptr = find_entry( hash_val, k );
+ if (ptr == 0) {
+ if (c_ptr != 0) *c_ptr = default_value;
+ return 0;
+ }
+ else {
+ if (c_ptr != 0) *c_ptr = ptr->contents;
+ return 1;
+ }
+}
+
+void*
+sc_phash_base::operator[]( const void* key ) const
+{
+ void* contents;
+ lookup( key, &contents );
+ return contents;
+}
+
+/***************************************************************************/
+
+void
+sc_phash_base_iter::reset( sc_phash_base* t )
+{
+ table = t;
+ index = 0;
+ entry = 0;
+ next = 0;
+
+ for (int i = index; i < table->num_bins; ++i) {
+ if (table->bins[i] != 0) {
+ index = i + 1;
+ last = &(table->bins[i]);
+ entry = *last;
+ next = entry->next;
+ break;
+ }
+ }
+}
+
+bool
+sc_phash_base_iter::empty() const
+{
+ return (entry == 0);
+}
+
+void
+sc_phash_base_iter::step()
+{
+ if (entry) {
+ last = &(entry->next);
+ }
+ entry = next;
+ if (! entry) {
+ for (int i = index; i < table->num_bins; ++i) {
+ if (table->bins[i] != 0) {
+ index = i + 1;
+ last = &(table->bins[i]);
+ entry = *last;
+ next = entry->next;
+ break;
+ }
+ }
+ }
+ else {
+ next = entry->next;
+ }
+}
+
+void
+sc_phash_base_iter::remove()
+{
+ delete entry;
+ *last = next;
+ entry = 0;
+ --table->num_entries;
+ step();
+}
+
+void
+sc_phash_base_iter::remove(void (*kfree)(void*))
+{
+ (*kfree)(entry->key);
+ delete entry;
+ *last = next;
+ entry = 0;
+ --table->num_entries;
+ step();
+}
+
+void*
+sc_phash_base_iter::key() const
+{
+ return entry->key;
+}
+
+void*
+sc_phash_base_iter::contents() const
+{
+ return entry->contents;
+}
+
+void*
+sc_phash_base_iter::set_contents( void* c )
+{
+ return entry->contents = c;
+}
+
+/****************************************************************************/
+
+unsigned
+default_ptr_hash_fn(const void* p)
+{
+ return static_cast<unsigned>(((uintptr_t)(p) >> 2) * 2654435789U);
+
+}
+
+unsigned
+default_int_hash_fn(const void* p)
+{
+ return static_cast<unsigned>((uintptr_t)(p) * 3141592661U);
+}
+
+
+unsigned
+default_str_hash_fn(const void* p)
+{
+ if (!p) return 0;
+
+ const char* x = (const char*) p;
+ unsigned int h = 0;
+ unsigned int g;
+
+ while (*x != 0) {
+ h = (h << 4) + *x++;
+ if ((g = h & 0xf0000000) != 0)
+ h = (h ^ (g >> 24)) ^ g;
+ }
+ return h;
+}
+
+int
+sc_strhash_cmp( const void* a, const void* b )
+{
+ return strcmp( (const char*) a, (const char*) b );
+}
+
+void*
+sc_strhash_kdup(const void* k)
+{
+ char* result = (char*) malloc( strlen((const char*)k)+1 );
+ strcpy(result, (const char*) k);
+ return result;
+}
+
+void
+sc_strhash_kfree(void* k)
+{
+ if (k) free((char*) k);
+}
+ } // namespace sc_core
+
+// $Log: sc_hash.cpp,v $
+// Revision 1.5 2011/08/26 20:42:30 acg
+// Andy Goodrich:
+// (1) Replaced strdup with new and strcpy to eliminate issue with the
+// Greenhills compiler.
+// (2) Moved modification log to the end of the file to eliminate line
+// skew when check-ins are done.
+//
+// Revision 1.4 2011/08/24 22:05:56 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.3 2011/05/05 17:46:04 acg
+// Philip A. Hartmann: changes in "swap" support.
+//
+// Revision 1.2 2011/02/18 20:38:43 acg
+// Andy Goodrich: Updated Copyright notice.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:06 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:10 acg
+// Andy Goodrich: Added $Log command so that CVS comments are reproduced in
+// the source.
+
+// taf
diff --git a/ext/systemc/src/sysc/utils/sc_hash.h b/ext/systemc/src/sysc/utils/sc_hash.h
new file mode 100644
index 000000000..14f8ee980
--- /dev/null
+++ b/ext/systemc/src/sysc/utils/sc_hash.h
@@ -0,0 +1,460 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_hash.cpp -- Implementation of a chained hash table with MTF
+ (move-to-front).
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+#ifndef SC_HASH_H
+#define SC_HASH_H
+
+
+namespace sc_core {
+
+extern unsigned default_int_hash_fn(const void*);
+extern unsigned default_ptr_hash_fn(const void*);
+extern unsigned default_str_hash_fn(const void*);
+
+class sc_phash_elem;
+class sc_phash_base_iter;
+template<class K, class C> //template class
+class sc_pdhash_iter; //decl. -- Amit
+
+const int PHASH_DEFAULT_MAX_DENSITY = 5;
+const int PHASH_DEFAULT_INIT_TABLE_SIZE = 11;
+extern const double PHASH_DEFAULT_GROW_FACTOR;
+const bool PHASH_DEFAULT_REORDER_FLAG = true;
+
+class sc_phash_base {
+ friend class sc_phash_base_iter;
+
+ typedef sc_phash_base_iter iterator;
+
+public:
+ typedef unsigned (*hash_fn_t)(const void*);
+ typedef int (*cmpr_fn_t)(const void*, const void*);
+
+protected:
+ void* default_value;
+ int num_bins;
+ int num_entries;
+ int max_density;
+ int reorder_flag;
+ double grow_factor;
+
+ sc_phash_elem** bins;
+
+ hash_fn_t hash;
+ cmpr_fn_t cmpr;
+
+ void rehash();
+ unsigned do_hash(const void* key) const { return (*hash)(key) % num_bins; }
+
+ sc_phash_elem* add_direct(void* key, void* contents, unsigned hash_val);
+ sc_phash_elem* find_entry_c(unsigned hv, const void* k, sc_phash_elem*** plast);
+ sc_phash_elem* find_entry_q(unsigned hv, const void* k, sc_phash_elem*** plast);
+ sc_phash_elem* find_entry(unsigned hv, const void* k, sc_phash_elem*** plast=0) const
+ {
+ /* Got rid of member func. pointer and replaced with if-else */
+ /* Amit (5/14/99) */
+ if( cmpr == 0 )
+ return ((sc_phash_base*)this)->find_entry_q( hv, k, plast );
+ else
+ return ((sc_phash_base*)this)->find_entry_c( hv, k, plast );
+ }
+
+public:
+ sc_phash_base( void* def = 0,
+ int size = PHASH_DEFAULT_INIT_TABLE_SIZE,
+ int density = PHASH_DEFAULT_MAX_DENSITY,
+ double grow = PHASH_DEFAULT_GROW_FACTOR,
+ bool reorder = PHASH_DEFAULT_REORDER_FLAG,
+ hash_fn_t hash_fn = default_ptr_hash_fn,
+ cmpr_fn_t cmpr_fn = 0 );
+ ~sc_phash_base();
+
+ void set_cmpr_fn(cmpr_fn_t);
+ void set_hash_fn(hash_fn_t);
+
+ bool empty() const { return (num_entries == 0); }
+ unsigned count() const { return num_entries; }
+
+ void erase();
+ void erase(void (*kfree)(void*));
+ void copy( const sc_phash_base* );
+ void copy( const sc_phash_base& b ) { copy(&b); }
+ void copy( const sc_phash_base& b, void* (*kdup)(const void*), void (*kfree)(void*));
+ int insert( void* k, void* c );
+ int insert( void* k ) { return insert(k, default_value); }
+ int insert( void* k, void* c, void* (*kdup)(const void*) );
+ int insert_if_not_exists(void* k, void* c);
+ int insert_if_not_exists(void* k) { return insert_if_not_exists(k, default_value); }
+ int insert_if_not_exists(void* k, void* c, void* (*kdup)(const void*));
+ int remove(const void* k);
+ int remove(const void* k, void** pk, void** pc);
+ int remove(const void* k, void (*kfree)(void*));
+ int remove_by_contents(const void* c);
+ int remove_by_contents(bool (*predicate)(const void*, void*), void* arg);
+ int remove_by_contents(const void* c, void (*kfree)(void*));
+ int remove_by_contents(bool (*predicate)(const void*, void*), void* arg, void (*kfree)(void*));
+ int lookup(const void* k, void** pc) const;
+ bool contains(const void* k) const { return (lookup(k, 0) != 0); }
+ void* operator[](const void* key) const;
+};
+
+class sc_phash_base_iter {
+protected:
+ sc_phash_base* table;
+ sc_phash_elem* entry;
+ sc_phash_elem* next;
+ sc_phash_elem** last;
+ int index;
+
+public:
+ void reset(sc_phash_base* t);
+ void reset(sc_phash_base& t) { reset(&t); }
+
+ sc_phash_base_iter(sc_phash_base* t)
+ : table(t), entry(0), next(0), last(0), index(0)
+ { reset(t); }
+ sc_phash_base_iter(sc_phash_base& t)
+ : table(&t), entry(0), next(0), last(0), index(0)
+ { reset(t); }
+ ~sc_phash_base_iter() { }
+
+ bool empty() const;
+ void step();
+ void operator++(int) { step(); }
+ void remove();
+ void remove(void (*kfree)(void*));
+ void* key() const;
+ void* contents() const;
+ void* set_contents(void* c);
+};
+
+template< class K, class C >
+class sc_phash_iter;
+
+template< class K, class C >
+class sc_phash : public sc_phash_base {
+ friend class sc_phash_iter<K,C>;
+
+public:
+ typedef sc_phash_iter<K,C> iterator;
+
+ sc_phash( C def = (C) 0,
+ int size = PHASH_DEFAULT_INIT_TABLE_SIZE,
+ int density = PHASH_DEFAULT_MAX_DENSITY,
+ double grow = PHASH_DEFAULT_GROW_FACTOR,
+ bool reorder = PHASH_DEFAULT_REORDER_FLAG,
+ hash_fn_t hash_fn = default_ptr_hash_fn,
+ cmpr_fn_t cmpr_fn = 0 )
+ : sc_phash_base((void*) def, size, density, grow, reorder, hash_fn, cmpr_fn) { }
+ ~sc_phash() { }
+
+ void copy(const sc_phash<K,C>* b) { sc_phash_base::copy(b); }
+ void copy(const sc_phash<K,C>& b) { sc_phash_base::copy(b); }
+ void copy(const sc_phash<K,C>& b, void* (*kdup)(const void*), void (*kfree)(void*)) { sc_phash_base::copy(b, kdup, kfree); }
+
+ int insert(K k, C c) { return sc_phash_base::insert((void*) k, (void*) c); }
+ int insert(K k) { return sc_phash_base::insert((void*) k, default_value); }
+ int insert(K k, C c, void* (*kdup)(const void*)) { return sc_phash_base::insert((void*) k, (void*) c, kdup); }
+ int insert_if_not_exists(K k, C c)
+ {
+ return sc_phash_base::insert_if_not_exists((void*) k, (void*) c);
+ }
+ int insert_if_not_exists(K k)
+ {
+ return sc_phash_base::insert_if_not_exists((void*) k, default_value);
+ }
+ int insert_if_not_exists(K k, C c, void* (*kdup)(const void*))
+ {
+ return sc_phash_base::insert_if_not_exists((void*) k, (void*) c, kdup);
+ }
+ int remove(K k) { return sc_phash_base::remove((const void*) k); }
+ int remove(K k, K* pk, C* pc)
+ {
+ return sc_phash_base::remove((const void*) k, (void**) pk, (void**) pc);
+ }
+ int remove(K k, void (*kfree)(void*))
+ {
+ return sc_phash_base::remove((const void*) k, kfree);
+ }
+ int remove_by_contents(C c)
+ {
+ return sc_phash_base::remove_by_contents((const void*) c);
+ }
+ int remove_by_contents(bool (*predicate)(const void*, void*), void* arg)
+ {
+ return sc_phash_base::remove_by_contents(predicate, arg);
+ }
+ int remove_by_contents(const void* c, void (*kfree)(void*))
+ {
+ return sc_phash_base::remove_by_contents(c, kfree);
+ }
+ int remove_by_contents(bool (*predicate)(const void*, void*), void* arg, void (*kfree)(void*))
+ {
+ return sc_phash_base::remove_by_contents(predicate, arg, kfree);
+ }
+ int lookup(K k, C* pc) const
+ {
+ return sc_phash_base::lookup((const void*) k, (void**) pc);
+ }
+ bool contains(K k) const
+ {
+ return sc_phash_base::contains((const void*) k);
+ }
+ C operator[](K k) const
+ {
+ return (C) sc_phash_base::operator[]((const void*) k);
+ }
+};
+
+
+template< class K, class C >
+class sc_phash_iter : public sc_phash_base_iter {
+public:
+ sc_phash_iter(sc_phash<K,C>* t) : sc_phash_base_iter(t) { }
+ sc_phash_iter(sc_phash<K,C>& t) : sc_phash_base_iter(t) { }
+ ~sc_phash_iter() { }
+
+ void reset(sc_phash<K,C>* t) { sc_phash_base_iter::reset(t); }
+ void reset(sc_phash<K,C>& t) { sc_phash_base_iter::reset(t); }
+
+ K key() const { return (K) sc_phash_base_iter::key(); }
+ C contents() const { return (C) sc_phash_base_iter::contents(); }
+ C set_contents(C c)
+ {
+ return (C) sc_phash_base_iter::set_contents((void*) c);
+ }
+};
+
+
+
+
+
+template< class K, class C >
+class sc_pdhash : public sc_phash_base {
+ friend class sc_pdhash_iter<K,C>;
+
+private:
+ void* (*kdup)(const void*); //eliminated braces around void* -- Amit
+ void (*kfree)(void*);
+
+public:
+ typedef sc_pdhash_iter<K,C> iterator;
+ sc_pdhash( C def = (C) 0,
+ int size = PHASH_DEFAULT_INIT_TABLE_SIZE,
+ int density = PHASH_DEFAULT_MAX_DENSITY,
+ double grow = PHASH_DEFAULT_GROW_FACTOR,
+ bool reorder = PHASH_DEFAULT_REORDER_FLAG,
+ hash_fn_t hash_fn = (hash_fn_t) 0, // defaults added --
+ cmpr_fn_t cmpr_fn = (cmpr_fn_t) 0, // Amit
+ void* (*kdup_fn)(const void*) = 0,
+ void (*kfree_fn)(void*) = 0 )
+ : sc_phash_base((void*) def, size, density, grow, reorder, hash_fn, cmpr_fn)
+ {
+ kdup = kdup_fn;
+ kfree = kfree_fn;
+ }
+ ~sc_pdhash()
+ {
+ erase();
+ }
+ void erase()
+ {
+ sc_phash_base::erase(kfree);
+ }
+ void copy(const sc_pdhash<K,C>& b) { sc_phash_base::copy(b, kdup, kfree); }
+ int insert(K k, C c) { return sc_phash_base::insert((void*) k, (void*) c, kdup); }
+ int insert(K k) { return sc_phash_base::insert((void*) k, default_value, kdup); }
+ int insert_if_not_exists(K k, C c)
+ {
+ return sc_phash_base::insert_if_not_exists((void*) k, (void*) c, kdup);
+ }
+ int insert_if_not_exists(K k)
+ {
+ return sc_phash_base::insert_if_not_exists((void*) k, default_value, kdup);
+ }
+ int remove(K k) { return sc_phash_base::remove((const void*) k, kfree); }
+ int remove(K k, K* pk, C* pc)
+ {
+ return sc_phash_base::remove((const void*) k, (void**) pk, (void**) pc);
+ }
+ int remove_by_contents(C c)
+ {
+ return sc_phash_base::remove_by_contents((const void*) c, kfree);
+ }
+ int remove_by_contents(bool (*predicate)(const void*, void*), void* arg)
+ {
+ return sc_phash_base::remove_by_contents(predicate, arg, kfree);
+ }
+ int lookup(K k, C* pc) const
+ {
+ return sc_phash_base::lookup((const void*) k, (void**) pc);
+ }
+ bool contains(K k) const
+ {
+ return sc_phash_base::contains((const void*) k);
+ }
+ C operator[](K k) const
+ {
+ return (C) sc_phash_base::operator[]((const void*) k);
+ }
+};
+
+template< class K, class C >
+class sc_pdhash_iter : public sc_phash_base_iter {
+public:
+ sc_pdhash_iter(sc_pdhash<K,C>* t) : sc_phash_base_iter(t) { }
+ sc_pdhash_iter(sc_pdhash<K,C>& t) : sc_phash_base_iter(t) { }
+ ~sc_pdhash_iter() { }
+
+ void reset(sc_pdhash<K,C>* t) { sc_phash_base_iter::reset(t); }
+ void reset(sc_pdhash<K,C>& t) { sc_phash_base_iter::reset(t); }
+
+ void remove() { sc_phash_base_iter::remove(((sc_pdhash<K,C>*) table)->kfree); }
+ K key() const { return (K) sc_phash_base_iter::key(); }
+ C contents() const { return (C) sc_phash_base_iter::contents(); }
+ C set_contents(C c)
+ {
+ return (C) sc_phash_base_iter::set_contents((void*) c);
+ }
+};
+
+extern int sc_strhash_cmp( const void*, const void* );
+extern void sc_strhash_kfree(void*);
+extern void* sc_strhash_kdup(const void*);
+
+template< class C > // template class decl.
+class sc_strhash_iter; // --Amit
+
+template< class C >
+class sc_strhash : public sc_phash_base {
+ friend class sc_strhash_iter<C>;
+
+public:
+ typedef sc_strhash_iter<C> iterator;
+
+ sc_strhash( C def = (C) 0,
+ int size = PHASH_DEFAULT_INIT_TABLE_SIZE,
+ int density = PHASH_DEFAULT_MAX_DENSITY,
+ double grow = PHASH_DEFAULT_GROW_FACTOR,
+ bool reorder = PHASH_DEFAULT_REORDER_FLAG,
+ unsigned (*hash_fn)(const void*) = default_str_hash_fn,
+ int (*cmpr_fn)(const void*, const void*) = sc_strhash_cmp )
+ : sc_phash_base((void*) def, size, density, grow, reorder, hash_fn, cmpr_fn)
+ {
+
+ }
+ ~sc_strhash()
+ {
+ erase();
+ }
+
+ void erase() { sc_phash_base::erase(sc_strhash_kfree); }
+ void copy(const sc_strhash<C>* b) { sc_phash_base::copy(*b, sc_strhash_kdup, sc_strhash_kfree); }
+ void copy(const sc_strhash<C>& b) { sc_phash_base::copy(b, sc_strhash_kdup, sc_strhash_kfree); }
+
+ int insert(char* k, C c) { return sc_phash_base::insert((void*) k, (void*) c, sc_strhash_kdup); }
+ int insert(char* k) { return sc_phash_base::insert((void*) k, default_value, sc_strhash_kdup); }
+ int insert_if_not_exists(char* k, C c)
+ {
+ return sc_phash_base::insert_if_not_exists((void*) k, (void*) c, sc_strhash_kdup);
+ }
+ int insert_if_not_exists(char* k)
+ {
+ return sc_phash_base::insert_if_not_exists((void*) k, default_value, sc_strhash_kdup);
+ }
+ int remove(const char* k) { return sc_phash_base::remove((const void*) k, sc_strhash_kfree); }
+ int remove(const char* k, char** pk, C* pc)
+ {
+ return sc_phash_base::remove((const void*) k, (void**) pk, (void**) pc);
+ }
+ int remove_by_contents(C c)
+ {
+ return sc_phash_base::remove_by_contents((const void*) c, sc_strhash_kfree);
+ }
+ int remove_by_contents(bool (*predicate)(const void*, void*), void* arg)
+ {
+ return sc_phash_base::remove_by_contents(predicate, arg, sc_strhash_kfree);
+ }
+ int lookup(const char* k, C* pc) const
+ {
+ return sc_phash_base::lookup((const void*) k, (void** )pc);
+ }
+ bool contains(const char* k) const
+ {
+ return sc_phash_base::contains((const void*) k);
+ }
+ C operator[](const char* k) const
+ {
+ return (C) sc_phash_base::operator[]((const void*) k);
+ }
+};
+
+template<class C>
+class sc_strhash_iter : public sc_phash_base_iter {
+public:
+ sc_strhash_iter ( sc_strhash<C>* t ) : sc_phash_base_iter(t) { }
+ sc_strhash_iter ( sc_strhash<C>& t ) : sc_phash_base_iter(t) { }
+ ~sc_strhash_iter() { }
+
+ void reset ( sc_strhash<C>* t ) { sc_phash_base_iter::reset(t); }
+ void reset ( sc_strhash<C>& t ) { sc_phash_base_iter::reset(t); }
+
+ void remove() { sc_phash_base_iter::remove(sc_strhash_kfree); }
+ const char* key() { return (const char*) sc_phash_base_iter::key(); }
+ C contents() { return (C) sc_phash_base_iter::contents(); }
+ C set_contents(C c)
+ {
+ return (C) sc_phash_base_iter::set_contents((void*) c);
+ }
+};
+
+} // namespace sc_core
+
+// $Log: sc_hash.h,v $
+// Revision 1.5 2011/08/29 18:04:32 acg
+// Philipp A. Hartmann: miscellaneous clean ups.
+//
+// Revision 1.4 2011/08/26 20:46:16 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.3 2011/08/24 22:05:56 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.2 2011/02/18 20:38:43 acg
+// Andy Goodrich: Updated Copyright notice.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:06 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:10 acg
+// Andy Goodrich: Added $Log command so that CVS comments are reproduced in
+// the source.
+
+#endif
diff --git a/ext/systemc/src/sysc/utils/sc_iostream.h b/ext/systemc/src/sysc/utils/sc_iostream.h
new file mode 100644
index 000000000..4f19d511e
--- /dev/null
+++ b/ext/systemc/src/sysc/utils/sc_iostream.h
@@ -0,0 +1,91 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_iostream.h - Portable iostream header file wrapper.
+
+ Original Author: Martin Janssen, Synopsys, Inc.
+
+ Note: Deprecated in the meantime, since all supported
+ compilers are supposed to have a working C++
+ standard library.
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+#ifndef SC_IOSTREAM_H
+#define SC_IOSTREAM_H
+
+#include <ios>
+#include <iostream>
+#include <sstream>
+#include <fstream>
+#include <cstddef>
+#include <cstring>
+
+// We use typedefs for istream and ostream here to get around some finickiness
+// from aCC:
+
+namespace sc_dt {
+
+typedef ::std::istream systemc_istream;
+typedef ::std::ostream systemc_ostream;
+
+} // namespace sc_dt
+
+// shortcuts that save some typing
+
+#ifdef CCAST
+# undef CCAST
+#endif
+#define CCAST const_cast
+
+#ifdef DCAST
+# undef DCAST
+#endif
+#define DCAST dynamic_cast
+
+#ifdef RCAST
+# undef RCAST
+#endif
+#define RCAST reinterpret_cast
+
+#ifdef SCAST
+# undef SCAST
+#endif
+#define SCAST static_cast
+
+// $Log: sc_iostream.h,v $
+// Revision 1.3 2011/08/26 20:46:18 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.2 2011/02/18 20:38:43 acg
+// Andy Goodrich: Updated Copyright notice.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:06 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:10 acg
+// Andy Goodrich: Added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#endif // !defined(SC_IOSTREAM_H)
diff --git a/ext/systemc/src/sysc/utils/sc_list.cpp b/ext/systemc/src/sysc/utils/sc_list.cpp
new file mode 100644
index 000000000..88998fbe9
--- /dev/null
+++ b/ext/systemc/src/sysc/utils/sc_list.cpp
@@ -0,0 +1,343 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_list.cpp -- Simple implementation of a doubly linked list.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+
+#include <assert.h>
+#include <cstddef>
+
+#include "sysc/kernel/sc_cmnhdr.h"
+#include "sysc/utils/sc_iostream.h"
+#include "sysc/utils/sc_list.h"
+#include "sysc/utils/sc_mempool.h"
+#include "sysc/utils/sc_report.h"
+#include "sysc/utils/sc_utils_ids.h"
+
+namespace sc_core {
+
+class sc_plist_elem {
+ friend class sc_plist_base_iter;
+ friend class sc_plist_base;
+
+private:
+ sc_plist_elem() : data(0), prev(0), next(0)
+ {}
+ sc_plist_elem( void* d, sc_plist_elem* p, sc_plist_elem* n ) :
+ data(d), prev(p), next(n)
+ {}
+ ~sc_plist_elem()
+ {}
+
+ static void* operator new(std::size_t sz) { return sc_mempool::allocate(sz); }
+ static void operator delete(void* p, std::size_t sz) { sc_mempool::release(p, sz); }
+
+ void* data;
+ sc_plist_elem* prev;
+ sc_plist_elem* next;
+};
+
+sc_plist_base::sc_plist_base() : head(0), tail(0) {}
+
+sc_plist_base::~sc_plist_base()
+{
+ handle_t p;
+ for( handle_t h = head; h != 0; h = p ) {
+ p = h->next;
+ delete h;
+ }
+}
+
+void
+sc_plist_base::erase_all()
+{
+ handle_t p;
+ for( handle_t h = head; h != 0; h = p ) {
+ p = h->next;
+ delete h;
+ }
+ head = 0;
+ tail = 0;
+}
+
+int
+sc_plist_base::size() const
+{
+ int n = 0;
+ for( handle_t h = head; h != 0; h = h->next ) {
+ n++;
+ }
+ return n;
+}
+
+sc_plist_base::handle_t
+sc_plist_base::push_back( void* d )
+{
+ handle_t q = new sc_plist_elem( d, tail, 0 );
+ if (tail) {
+ tail->next = q;
+ tail = q;
+ }
+ else {
+ head = tail = q;
+ }
+ return q;
+}
+
+sc_plist_base::handle_t
+sc_plist_base::push_front( void* d )
+{
+ handle_t q = new sc_plist_elem( d, (sc_plist_elem*) 0, head );
+ if (head) {
+ head->prev = q;
+ head = q;
+ }
+ else {
+ head = tail = q;
+ }
+ return q;
+}
+
+void*
+sc_plist_base::pop_back()
+{
+ handle_t q = tail;
+ void* d = q->data;
+ tail = tail->prev;
+ delete q;
+ if (tail != 0) {
+ tail->next = 0;
+ }
+ else {
+ head = 0;
+ }
+ return d;
+}
+
+void*
+sc_plist_base::pop_front()
+{
+ handle_t q = head;
+ void* d = q->data;
+ head = head->next;
+ delete q;
+ if (head != 0) {
+ head->prev = 0;
+ }
+ else {
+ tail = 0;
+ }
+ return d;
+}
+
+sc_plist_base::handle_t
+sc_plist_base::insert_before( handle_t h, void* d )
+{
+ if (h == 0) {
+ return push_back(d);
+ }
+ else {
+ handle_t q = new sc_plist_elem( d, h->prev, h );
+ h->prev->next = q;
+ h->prev = q;
+ return q;
+ }
+}
+
+sc_plist_base::handle_t
+sc_plist_base::insert_after( handle_t h, void* d )
+{
+ if (h == 0) {
+ return push_front(d);
+ }
+ else {
+ handle_t q = new sc_plist_elem( d, h, h->next );
+ h->next->prev = q;
+ h->next = q;
+ return q;
+ }
+}
+
+void*
+sc_plist_base::remove( handle_t h )
+{
+ if (h == head)
+ return pop_front();
+ else if (h == tail)
+ return pop_back();
+ else {
+ void* d = h->data;
+ h->prev->next = h->next;
+ h->next->prev = h->prev;
+ delete h;
+ return d;
+ }
+}
+
+void*
+sc_plist_base::get( handle_t h ) const
+{
+ return h->data;
+}
+
+void
+sc_plist_base::set( handle_t h, void* d )
+{
+ h->data = d;
+}
+
+void
+sc_plist_base::mapcar( sc_plist_map_fn f, void* arg )
+{
+ for (handle_t h = head; h != 0; h = h->next) {
+ f( h->data, arg );
+ }
+}
+
+void*
+sc_plist_base::front() const
+{
+
+ if (head) {
+ return head->data;
+ }
+ else {
+ SC_REPORT_ERROR( SC_ID_FRONT_ON_EMPTY_LIST_ , 0 );
+ // never reached
+ return 0;
+ }
+}
+
+void*
+sc_plist_base::back() const
+{
+ if (tail) {
+ return tail->data;
+ }
+ else {
+ SC_REPORT_ERROR( SC_ID_BACK_ON_EMPTY_LIST_, 0 );
+ // never reached
+ return 0;
+ }
+}
+
+
+
+sc_plist_base_iter::sc_plist_base_iter( sc_plist_base* l, bool from_tail ) :
+ lst(l), ptr( from_tail ? l->tail : l->head )
+{
+}
+
+void
+sc_plist_base_iter::reset( sc_plist_base* l, bool from_tail )
+{
+ lst = l;
+ if (from_tail) {
+ ptr = l->tail;
+ }
+ else {
+ ptr = l->head;
+ }
+}
+
+sc_plist_base_iter::~sc_plist_base_iter()
+{
+
+}
+
+bool
+sc_plist_base_iter::empty() const
+{
+ return ptr == 0;
+}
+
+void
+sc_plist_base_iter::operator++(int)
+{
+ ptr = ptr->next;
+}
+
+void
+sc_plist_base_iter::operator--(int)
+{
+ ptr = ptr->prev;
+}
+
+void*
+sc_plist_base_iter::get() const
+{
+ return ptr->data;
+}
+
+void
+sc_plist_base_iter::set( void* d )
+{
+ ptr->data = d;
+}
+
+void
+sc_plist_base_iter::remove()
+{
+ sc_plist_base::handle_t nptr = ptr->next;
+ lst->remove(ptr);
+ ptr = nptr;
+}
+
+void
+sc_plist_base_iter::remove(int direction)
+{
+ sc_plist_base::handle_t nptr = (direction == 1) ? ptr->next : ptr->prev;
+ lst->remove(ptr);
+ ptr = nptr;
+}
+
+void
+sc_plist_base_iter::set_handle( sc_plist_elem* h )
+{
+ ptr = h;
+}
+
+} // namespace sc_core
+
+// $Log: sc_list.cpp,v $
+// Revision 1.4 2011/08/26 20:46:18 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.3 2011/08/24 22:05:56 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.2 2011/02/18 20:38:43 acg
+// Andy Goodrich: Updated Copyright notice.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:06 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:10 acg
+// Andy Goodrich: Added $Log command so that CVS comments are reproduced in
+// the source.
+
+// taf
diff --git a/ext/systemc/src/sysc/utils/sc_list.h b/ext/systemc/src/sysc/utils/sc_list.h
new file mode 100644
index 000000000..40f4c92af
--- /dev/null
+++ b/ext/systemc/src/sysc/utils/sc_list.h
@@ -0,0 +1,188 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_list.h -- Simple implementation of a doubly linked list.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+
+#ifndef SC_LIST_H
+#define SC_LIST_H
+
+namespace sc_core {
+
+//Some forward declarations
+class sc_plist_elem;
+template<class T> class sc_plist_iter;
+
+typedef void (*sc_plist_map_fn)( void* data, void* arg );
+
+class sc_plist_base {
+ friend class sc_plist_base_iter;
+
+public:
+ sc_plist_base();
+ ~sc_plist_base();
+
+ typedef sc_plist_elem* handle_t;
+
+ handle_t push_back(void* d);
+ handle_t push_front(void* d);
+ void* pop_back();
+ void* pop_front();
+ handle_t insert_before(handle_t h, void* d);
+ handle_t insert_after(handle_t h, void* d);
+ void* remove(handle_t h);
+ void* get(handle_t h) const;
+ void set(handle_t h, void* d);
+ void mapcar( sc_plist_map_fn f, void* arg );
+
+ void* front() const;
+ void* back() const;
+
+ void erase_all();
+ bool empty() const { return (head == 0); }
+ int size() const;
+
+private:
+ handle_t head;
+ handle_t tail;
+};
+
+
+class sc_plist_base_iter {
+public:
+ typedef sc_plist_elem* handle_t;
+
+ sc_plist_base_iter( sc_plist_base* l, bool from_tail = false );
+ ~sc_plist_base_iter();
+
+ void reset( sc_plist_base* l, bool from_tail = false );
+ bool empty() const;
+ void operator++(int);
+ void operator--(int);
+ void* get() const;
+ void set(void* d);
+ void remove();
+ void remove(int direction);
+
+ void set_handle(handle_t h);
+ handle_t get_handle() const { return ptr; }
+
+private:
+ sc_plist_base* lst;
+ sc_plist_elem* ptr;
+};
+
+/*---------------------------------------------------------------------------*/
+
+template< class T >
+class sc_plist : public sc_plist_base {
+ friend class sc_plist_iter <T>;
+
+public:
+ typedef sc_plist_iter<T> iterator;
+
+ sc_plist() { }
+ ~sc_plist() { }
+
+ handle_t push_back(T d) { return sc_plist_base::push_back((void*)d); }
+ handle_t push_front(T d) { return sc_plist_base::push_front((void*)d); }
+ T pop_back() { return (T) sc_plist_base::pop_back(); }
+ T pop_front() { return (T) sc_plist_base::pop_front(); }
+ handle_t insert_before(handle_t h, T d)
+ {
+ return sc_plist_base::insert_before(h, (void*) d);
+ }
+ handle_t insert_after(handle_t h, T d)
+ {
+ return sc_plist_base::insert_after(h, (void*) d);
+ }
+ T remove(handle_t h)
+ {
+ return (T)sc_plist_base::remove(h);
+ }
+ T get(handle_t h) const { return (T)sc_plist_base::get(h); }
+ void set(handle_t h, T d) { sc_plist_base::set(h, (void*)d); }
+
+ T front() const { return (T)sc_plist_base::front(); }
+ T back() const { return (T)sc_plist_base::back(); }
+};
+
+template< class T >
+class sc_plist_iter : public sc_plist_base_iter {
+public:
+ sc_plist_iter( sc_plist<T>* l, bool from_tail = false )
+ : sc_plist_base_iter( l, from_tail )
+ {
+
+ }
+ sc_plist_iter( sc_plist<T>& l, bool from_tail = false )
+ : sc_plist_base_iter( &l, from_tail )
+ {
+
+ }
+ ~sc_plist_iter()
+ {
+
+ }
+
+ void reset( sc_plist<T>* l, bool from_tail = false )
+ {
+ sc_plist_base_iter::reset( l, from_tail );
+ }
+ void reset( sc_plist<T>& l, bool from_tail = false )
+ {
+ sc_plist_base_iter::reset( &l, from_tail );
+ }
+
+ T operator*() const { return (T) sc_plist_base_iter::get(); }
+ T get() const { return (T) sc_plist_base_iter::get(); }
+ void set(T d) { sc_plist_base_iter::set((void*) d); }
+};
+
+} // namespace sc_core
+
+// $Log: sc_list.h,v $
+// Revision 1.5 2011/09/01 15:16:50 acg
+// Philipp A. Hartmann: revert unnecessary virtual destructors.
+//
+// Revision 1.4 2011/08/26 20:46:18 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.3 2011/08/24 22:05:56 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.2 2011/02/18 20:38:44 acg
+// Andy Goodrich: Updated Copyright notice.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:06 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:10 acg
+// Andy Goodrich: Added $Log command so that CVS comments are reproduced in
+// the source.
+
+#endif
diff --git a/ext/systemc/src/sysc/utils/sc_machine.h b/ext/systemc/src/sysc/utils/sc_machine.h
new file mode 100644
index 000000000..1939b0c99
--- /dev/null
+++ b/ext/systemc/src/sysc/utils/sc_machine.h
@@ -0,0 +1,81 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_machine.h -- Machine-dependent Environment Settings
+
+ Original Author: Andy Goodrich, Forte Design Systems, Inc.
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+
+#ifndef SC_MACHINE_H
+#define SC_MACHINE_H
+
+#include <climits>
+//#include "sysc/packages/boost/detail/endian.hpp"
+
+// We stripped the boost include and assume a build on x86
+#define SC_BOOST_LITTLE_ENDIAN
+
+// ----------------------------------------------------------------------------
+// Little or big endian machine?
+// ----------------------------------------------------------------------------
+
+#if defined( SC_BOOST_LITTLE_ENDIAN )
+# define SC_LITTLE_ENDIAN
+#elif defined( SC_BOOST_BIG_ENDIAN )
+# define SC_BIG_ENDIAN
+#else
+# error "Could not detect the endianness of the CPU."
+#endif
+
+// ----------------------------------------------------------------------------
+// Are long data types 32-bit or 64-bit?
+// ----------------------------------------------------------------------------
+
+#if ULONG_MAX > 0xffffffffUL
+# define SC_LONG_64
+#endif
+
+// $Log: sc_machine.h,v $
+// Revision 1.5 2011/08/26 22:58:23 acg
+// Torsten Maehne: changes for endian detection.
+//
+// Revision 1.4 2011/08/26 20:46:18 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.3 2011/02/18 20:38:44 acg
+// Andy Goodrich: Updated Copyright notice.
+//
+// Revision 1.2 2010/09/06 16:35:09 acg
+// Andy Goodrich: changed i386 to __i386__ in ifdef.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:06 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:10 acg
+// Andy Goodrich: Added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#endif // !defined(SC_MACHINE_H)
diff --git a/ext/systemc/src/sysc/utils/sc_mempool.cpp b/ext/systemc/src/sysc/utils/sc_mempool.cpp
new file mode 100644
index 000000000..7369c12a0
--- /dev/null
+++ b/ext/systemc/src/sysc/utils/sc_mempool.cpp
@@ -0,0 +1,338 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_mempool.cpp - Memory pools for small objects.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+
+
+
+// <sc_mempool> is a class that manages the memory for small objects,
+// of sizes <increment>, 2 * <increment>, ..., <num_pools> *
+// <increment>. When a memory request of <k> bytes is made through
+// the memory pool, the smallest pool <j> such that <j> * <increment>
+// >= <k> is used. The default values of <increment> and <num_pools>
+// are 8 and 8, respectively. Each pool has an allocator, that
+// simply keeps a free list of cells, and allocate new blocks
+// whenever necessary. We are relying on malloc() to return a
+// properly aligned memory blocks. Note that the memory blocks
+// allocated by the mempool are never freed. Thus, if purify is
+// used, we may get MIU (memory-in-use) warnings. To disable this,
+// set the environment variable SYSTEMC_MEMPOOL_DONT_USE to 1.
+
+
+static const char* dont_use_envstring = "SYSTEMC_MEMPOOL_DONT_USE";
+static bool use_default_new = false;
+
+
+#include <stdio.h>
+#include <stdlib.h> // duplicate (c)stdlib.h headers for Solaris
+#include <cstdlib>
+#include "sysc/utils/sc_mempool.h"
+
+namespace sc_core {
+
+// An allocator is one that handles a particular size. It keeps a
+// <free_list> from which a cell may be allocated quickly if there
+// is one available. If no cell is available from <free_list>, then
+// the allocator tries to find whether space is available from the
+// most-recently-allocated block, as pointed to by <next_avail>. If
+// so, then the cell pointed to by <next_avail> is returned, while
+// <next_avail> is advanced. If <next_avail> now points beyond
+// the current block, then it's reset to 0. On the other hand,
+// if <next_avail> was 0 when a request to the block is made, then
+// a new block is allocated by calling system malloc(), and the new
+// block becomes the head of <block_list>.
+
+
+class sc_allocator {
+ friend class sc_mempool;
+
+public:
+ sc_allocator( int blksz, int cellsz );
+ ~sc_allocator();
+ void* allocate();
+ void release(void* p);
+
+ void display_statistics();
+
+private:
+ union link {
+ link* next;
+ double align; // alignment required.
+ };
+
+ int block_size; // size of each block in bytes,
+ // including the link
+ int cell_size; // size of each cell in bytes
+
+ char* block_list;
+ link* free_list;
+ char* next_avail;
+
+ int total_alloc;
+ int total_freed;
+ int free_list_alloc;
+};
+
+sc_allocator::sc_allocator( int blksz, int cellsz )
+ : block_size(sizeof(link) + (((blksz - 1) / cellsz) + 1) * cellsz),
+ cell_size(cellsz), block_list(0), free_list(0), next_avail(0),
+ total_alloc(0), total_freed(0), free_list_alloc(0)
+{}
+
+sc_allocator::~sc_allocator()
+{
+ // Shouldn't free the block_list, since global objects that use
+ // the memory pool may not have been destroyed yet ...
+ // Let it leak, let it leak, let it leak ...
+}
+
+void*
+sc_allocator::allocate()
+{
+ void* result = 0;
+ total_alloc++;
+ if (free_list != 0) {
+ free_list_alloc++;
+ result = free_list;
+ free_list = free_list->next;
+ return result;
+ }
+ else if (next_avail != 0) {
+ result = next_avail;
+ next_avail += cell_size;
+ // next_avail goes beyond the block
+ if (next_avail >= block_list + block_size)
+ next_avail = 0;
+ return result;
+ }
+ else { // (next_avail == 0)
+ link* new_block = (link*) malloc(block_size); // need alignment?
+ new_block->next = (link*) block_list;
+ block_list = (char*) new_block;
+ result = (block_list + sizeof(link));
+ // Assume that the block will hold more than one cell ... why
+ // wouldn't it?
+ next_avail = ((char*) result) + cell_size;
+ return result;
+ }
+}
+
+void
+sc_allocator::release(void* p)
+{
+ total_freed++;
+ ((link*) p)->next = free_list;
+ free_list = (link*) p;
+}
+
+void
+sc_allocator::display_statistics()
+{
+ int nblocks = 0;
+ for (link* b = (link*) block_list; b != 0; b = b->next)
+ nblocks++;
+ printf("size %3d: %2d block(s), %3d requests (%3d from free list), %3d freed.\n",
+ cell_size, nblocks, total_alloc, free_list_alloc, total_freed);
+}
+
+
+static const int cell_sizes[] = {
+/* 0 */ 0,
+/* 1 */ 8,
+/* 2 */ 16,
+/* 3 */ 24,
+/* 4 */ 32,
+/* 5 */ 48,
+/* 6 */ 64,
+/* 7 */ 80,
+/* 8 */ 96,
+/* 9 */ 128
+};
+
+static const int cell_size_to_allocator[] = {
+/* 0 */ 0,
+/* 1 */ 1,
+/* 2 */ 2,
+/* 3 */ 3,
+/* 4 */ 4,
+/* 5 */ 5,
+/* 6 */ 5,
+/* 7 */ 6,
+/* 8 */ 6,
+/* 9 */ 7,
+/* 10 */ 7,
+/* 11 */ 8,
+/* 12 */ 8,
+/* 13 */ 9,
+/* 14 */ 9,
+/* 15 */ 9,
+/* 16 */ 9
+};
+
+
+class sc_mempool_int {
+ friend class sc_mempool;
+
+public:
+ sc_mempool_int(int blksz, int npools, int incr);
+ ~sc_mempool_int();
+ void* do_allocate(std::size_t);
+ void do_release(void*, std::size_t);
+
+ void display_statistics();
+
+private:
+ sc_allocator** allocators;
+ int num_pools;
+ int increment;
+ int max_size;
+};
+
+
+static bool
+compute_use_default_new()
+{
+ const char* e = getenv(dont_use_envstring);
+ return (e != 0) && (atoi(e) != 0);
+}
+
+sc_mempool_int::sc_mempool_int(int blksz, int npools, int incr) :
+ allocators(0), num_pools(0), increment(0), max_size(0)
+{
+ use_default_new = compute_use_default_new();
+ if (! use_default_new) {
+ num_pools = npools;
+ increment = incr;
+ max_size = cell_sizes[sizeof(cell_sizes)/sizeof(cell_sizes[0]) - 1];
+ allocators = new sc_allocator*[npools + 1];
+ for (int i = 1; i <= npools; ++i)
+ allocators[i] = new sc_allocator(blksz, cell_sizes[i]);
+ allocators[0] = allocators[1];
+ }
+}
+
+sc_mempool_int::~sc_mempool_int()
+{
+ for (int i = 1; i <= num_pools; ++i)
+ delete allocators[i];
+ delete[] allocators;
+}
+
+static sc_mempool_int* the_mempool = 0;
+
+void*
+sc_mempool_int::do_allocate(std::size_t sz)
+{
+ int which_allocator = cell_size_to_allocator[(sz - 1) / increment + 1];
+ void* p = allocators[which_allocator]->allocate();
+ return p;
+}
+
+void
+sc_mempool_int::do_release(void* p, std::size_t sz)
+{
+ int which_allocator = cell_size_to_allocator[(sz - 1) / increment + 1];
+ allocators[which_allocator]->release(p);
+}
+
+void
+sc_mempool_int::display_statistics()
+{
+ printf("*** Memory Pool Statistics ***\n");
+ for (int i = 1; i <= num_pools; ++i)
+ allocators[i]->display_statistics();
+}
+
+/****************************************************************************/
+
+void*
+sc_mempool::allocate(std::size_t sz)
+{
+ if (use_default_new)
+ return ::operator new(sz);
+
+ if (the_mempool == 0) {
+ use_default_new = compute_use_default_new();
+ if (use_default_new)
+ return ::operator new(sz);
+
+ // Note that the_mempool is never freed. This is going to cause
+ // memory leaks when the program exits.
+ the_mempool = new sc_mempool_int( 1984, sizeof(cell_sizes)/sizeof(cell_sizes[0]) - 1, 8 );
+ }
+
+ if (sz > (unsigned) the_mempool->max_size)
+ return ::operator new(sz);
+
+ return the_mempool->do_allocate(sz);
+}
+
+void
+sc_mempool::release(void* p, std::size_t sz)
+{
+ if (p) {
+
+ if (use_default_new || sz > (unsigned) the_mempool->max_size) {
+ ::operator delete(p);
+ return;
+ }
+
+ the_mempool->do_release(p, sz);
+ }
+}
+
+void
+sc_mempool::display_statistics()
+{
+ if (the_mempool && !use_default_new) {
+ the_mempool->display_statistics();
+ } else {
+ printf("SystemC info: no memory allocation was done through the memory pool.\n");
+ }
+}
+
+} // namespace sc_core
+
+// $Log: sc_mempool.cpp,v $
+// Revision 1.4 2011/08/26 20:46:18 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.3 2011/08/24 22:05:56 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.2 2011/02/18 20:38:44 acg
+// Andy Goodrich: Updated Copyright notice.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:06 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:10 acg
+// Andy Goodrich: Added $Log command so that CVS comments are reproduced in
+// the source.
+
+// taf
diff --git a/ext/systemc/src/sysc/utils/sc_mempool.h b/ext/systemc/src/sysc/utils/sc_mempool.h
new file mode 100644
index 000000000..1c053ae1c
--- /dev/null
+++ b/ext/systemc/src/sysc/utils/sc_mempool.h
@@ -0,0 +1,93 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_mempool.h - Memory pools for small objects.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+#ifndef SC_MEMPOOL_H
+#define SC_MEMPOOL_H
+
+
+#include "sysc/utils/sc_iostream.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_mempool
+//
+// ...
+// ----------------------------------------------------------------------------
+
+class sc_mempool
+{
+public:
+
+ static void* allocate( std::size_t sz );
+ static void release( void* p, std::size_t sz );
+ static void display_statistics();
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_mpobject
+//
+// ...
+// ----------------------------------------------------------------------------
+
+class sc_mpobject
+{
+public:
+
+ static void* operator new( std::size_t sz )
+ { return sc_mempool::allocate( sz ); }
+
+ static void operator delete( void* p, std::size_t sz )
+ { sc_mempool::release( p, sz ); }
+
+ static void* operator new[]( std::size_t sz )
+ { return sc_mempool::allocate( sz ); }
+
+ static void operator delete[]( void* p, std::size_t sz )
+ { sc_mempool::release( p, sz ); }
+};
+
+} // namespace sc_core
+
+// $Log: sc_mempool.h,v $
+// Revision 1.3 2011/08/26 20:46:18 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.2 2011/02/18 20:38:44 acg
+// Andy Goodrich: Updated Copyright notice.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:06 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:11 acg
+// Andy Goodrich: Added $Log command so that CVS comments are reproduced in
+// the source.
+
+#endif
diff --git a/ext/systemc/src/sysc/utils/sc_pq.cpp b/ext/systemc/src/sysc/utils/sc_pq.cpp
new file mode 100644
index 000000000..d20580ca5
--- /dev/null
+++ b/ext/systemc/src/sysc/utils/sc_pq.cpp
@@ -0,0 +1,133 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_pq.cpp - Simple heap implementation of priority queue.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+// $Log: sc_pq.cpp,v $
+// Revision 1.4 2011/08/26 20:46:18 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+
+#include "sysc/utils/sc_pq.h"
+
+namespace sc_core {
+
+sc_ppq_base::sc_ppq_base( int sz, int (*cmp)( const void*, const void* ) )
+ : m_heap(0), m_size_alloc( sz ), m_heap_size( 0 ), m_compar( cmp )
+{
+ // m_size_alloc must be at least 2, otherwise resizing doesn't work
+ if( m_size_alloc < 2 ) {
+ m_size_alloc = 2;
+ }
+ // allocate
+ m_heap = new void*[m_size_alloc + 1];
+ // initialize
+ for( int i = 0; i < m_size_alloc; ++ i ) {
+ m_heap[i] = 0;
+ }
+}
+
+sc_ppq_base::~sc_ppq_base()
+{
+ delete[] m_heap;
+}
+
+void*
+sc_ppq_base::extract_top()
+{
+ assert( m_heap_size > 0 );
+ void* topelem = m_heap[1];
+ m_heap[1] = m_heap[m_heap_size];
+ m_heap_size --;
+ heapify( 1 );
+ return topelem;
+}
+
+void
+sc_ppq_base::insert( void* elem )
+{
+ m_heap_size ++;
+ int i = m_heap_size;
+
+ // resize the heap in case there's not enough memory
+ if( m_heap_size > m_size_alloc ) {
+ m_size_alloc += m_size_alloc / 2;
+ void** new_heap = new void*[m_size_alloc + 1];
+ for( int j = 1; j < m_heap_size; ++ j ) {
+ new_heap[j] = m_heap[j];
+ }
+ delete[] m_heap;
+ m_heap = new_heap;
+ }
+
+ while( (i > 1) && (m_compar( m_heap[parent( i )], elem ) < 0) ) {
+ m_heap[i] = m_heap[parent( i )];
+ i = parent( i );
+ }
+ m_heap[i] = elem;
+}
+
+void
+sc_ppq_base::heapify( int i )
+{
+ int l;
+ while( l = left( i ), l <= m_heap_size ) {
+ int largest = (m_compar( m_heap[l], m_heap[i] ) > 0) ? l : i;
+
+ int r = right( i );
+ if( (r <= m_heap_size) &&
+ (m_compar( m_heap[r], m_heap[largest] ) > 0) ) {
+ largest = r;
+ }
+
+ if( largest != i ) {
+ void* tmp = m_heap[i];
+ m_heap[i] = m_heap[largest];
+ m_heap[largest] = tmp;
+ i = largest;
+ } else {
+ break;
+ }
+ }
+}
+
+} // namespace sc_core
+
+// Revision 1.3 2011/08/24 22:05:56 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.2 2011/02/18 20:38:44 acg
+// Andy Goodrich: Updated Copyright notice.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:06 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:11 acg
+// Andy Goodrich: Added $Log command so that CVS comments are reproduced in
+// the source.
+
+// taf
diff --git a/ext/systemc/src/sysc/utils/sc_pq.h b/ext/systemc/src/sysc/utils/sc_pq.h
new file mode 100644
index 000000000..51ed54f4a
--- /dev/null
+++ b/ext/systemc/src/sysc/utils/sc_pq.h
@@ -0,0 +1,154 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_pq.h -- A simple priority queue (which can be used to model multiple
+ clocks). From Cormen-Leiserson-Rivest, Ch.7.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+#ifndef SC_PQ_H
+#define SC_PQ_H
+
+
+#include <cassert>
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_ppq_base
+//
+// Priority queue base class.
+// ----------------------------------------------------------------------------
+
+class sc_ppq_base
+{
+public:
+
+ typedef int (*compare_fn_t)( const void*, const void* );
+
+ sc_ppq_base( int sz, compare_fn_t cmp );
+
+ ~sc_ppq_base();
+
+ void* top() const
+ { return m_heap[1]; }
+
+ void* extract_top();
+
+ void insert( void* elem );
+
+ int size() const
+ { return m_heap_size; }
+
+ bool empty() const
+ { return (m_heap_size == 0); }
+
+protected:
+
+ int parent( int i ) const
+ { return i >> 1; }
+
+ int left( int i ) const
+ { return i << 1; }
+
+ int right( int i ) const
+ { return (i << 1) + 1; }
+
+ void heapify( int i );
+
+private:
+
+ void** m_heap;
+ int m_size_alloc;
+ int m_heap_size;
+ compare_fn_t m_compar;
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS TEMPLATE : sc_ppq<T>
+//
+// This class is a simple implementation of a priority queue based on
+// binary heaps. The class is templatized on its data type. A comparison
+// function needs to be supplied.
+// ----------------------------------------------------------------------------
+
+template <class T>
+class sc_ppq
+ : public sc_ppq_base
+{
+public:
+
+ // constructor - specify the maximum size of the queue and
+ // give a comparison function.
+
+ sc_ppq( int sz, compare_fn_t cmp )
+ : sc_ppq_base( sz, cmp )
+ {}
+
+ ~sc_ppq()
+ {}
+
+ // returns the value of the top element in the priority queue.
+ T top() const
+ { return (T) sc_ppq_base::top(); }
+
+ // pops the first element of the priority queue.
+
+ T extract_top()
+ { return (T) sc_ppq_base::extract_top(); }
+
+ // insert a new element to the priority queue.
+
+ void insert( T elem )
+ { sc_ppq_base::insert( (void*) elem ); }
+
+ // size() and empty() are inherited.
+};
+
+} // namespace sc_core
+
+// $Log: sc_pq.h,v $
+// Revision 1.5 2011/08/29 18:04:32 acg
+// Philipp A. Hartmann: miscellaneous clean ups.
+//
+// Revision 1.4 2011/08/26 20:46:18 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.3 2011/08/24 22:05:56 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.2 2011/02/18 20:38:44 acg
+// Andy Goodrich: Updated Copyright notice.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:06 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:11 acg
+// Andy Goodrich: Added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#endif
diff --git a/ext/systemc/src/sysc/utils/sc_pvector.h b/ext/systemc/src/sysc/utils/sc_pvector.h
new file mode 100644
index 000000000..3c0e127c9
--- /dev/null
+++ b/ext/systemc/src/sysc/utils/sc_pvector.h
@@ -0,0 +1,187 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_vector.h -- Simple implementation of a vector class.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+#ifndef SC_VECTOR_H
+#define SC_VECTOR_H
+
+#include <vector>
+
+namespace sc_core {
+
+extern "C" {
+ typedef int (*CFT)( const void*, const void* );
+}
+
+
+// #define ACCESS(I) m_vector.at(I) // index checking
+#define ACCESS(I) m_vector[I]
+#define ADDR_ACCESS(I) (m_vector.size() != 0 ? &m_vector[I] : 0 )
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_pvector<T>
+//
+// Simple vector class.
+// ----------------------------------------------------------------------------
+
+template< class T >
+class sc_pvector
+{
+public:
+
+ typedef const T* const_iterator;
+ typedef T* iterator;
+ // typedef typename ::std::vector<T>::const_iterator const_iterator;
+ // typedef typename ::std::vector<T>::iterator iterator;
+
+ sc_pvector( int alloc_n = 0 )
+ {
+ }
+
+ sc_pvector( const sc_pvector<T>& rhs )
+ : m_vector( rhs.m_vector )
+ {}
+
+ ~sc_pvector()
+ {}
+
+
+ std::size_t size() const
+ { return m_vector.size(); }
+
+
+ iterator begin()
+ { return (iterator) ADDR_ACCESS(0); }
+
+ const_iterator begin() const
+ { return (const_iterator) ADDR_ACCESS(0); }
+
+ iterator end()
+ { return static_cast<iterator> (ADDR_ACCESS(m_vector.size())); }
+
+ const_iterator end() const
+ {
+ return static_cast<const_iterator> (ADDR_ACCESS(m_vector.size()));
+ }
+
+
+ sc_pvector<T>& operator = ( const sc_pvector<T>& rhs )
+ { m_vector = rhs.m_vector; return *this; }
+
+
+ T& operator [] ( unsigned int i )
+ {
+ if ( i >= m_vector.size() ) m_vector.resize(i+1);
+ return (T&) m_vector.operator [] ( i );
+ }
+
+ const T& operator [] ( unsigned int i ) const
+ {
+ if ( i >= m_vector.size() ) m_vector.resize(i+1);
+ return (const T&) m_vector.operator [] ( i );
+ }
+
+ T& fetch( int i )
+ { return ACCESS(i); }
+
+ const T& fetch( int i ) const
+ { return (const T&) ACCESS(i); }
+
+
+ T* raw_data()
+ { return (T*) &ACCESS(0); }
+
+ const T* raw_data() const
+ { return (const T*) &ACCESS(0); }
+
+
+ operator const ::std::vector<T>& () const
+ { return m_vector; }
+
+ void push_back( T item )
+ { m_vector.push_back( item ); }
+
+
+ void erase_all()
+ { m_vector.resize(0); }
+
+ void sort( CFT compar )
+ {qsort( (void*)&m_vector[0], m_vector.size(), sizeof(void*), compar );}
+
+ /* These methods have been added from Ptr_Array */
+
+ void put( T item, int i )
+ { ACCESS(i) = item; }
+
+ void decr_count()
+ { m_vector.resize(m_vector.size()-1); }
+
+ void decr_count( int k )
+ { m_vector.resize(m_vector.size()-k); }
+
+
+
+ protected:
+ mutable ::std::vector<T> m_vector; // Actual vector of pointers.
+};
+
+#undef ACCESS
+#undef ADDR_ACCESS
+
+} // namespace sc_core
+
+// $Log: sc_pvector.h,v $
+// Revision 1.4 2011/08/26 20:46:19 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.3 2011/02/18 20:38:44 acg
+// Andy Goodrich: Updated Copyright notice.
+//
+// Revision 1.2 2011/01/20 16:52:21 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.1 2010/12/07 20:11:45 acg
+// Andy Goodrich: moved sc_pvector class to new header file to allow the
+// use of sc_vector.h for Philipp Hartmann's new sc_vector class.
+//
+// Revision 1.4 2010/08/03 17:52:15 acg
+// Andy Goodrich: fix signature for size() method of sc_pvector.
+//
+// Revision 1.3 2008/10/09 21:20:33 acg
+// Andy Goodrich: fixed the way the end() methods calculate their results.
+// I had incorrectly cut and pasted code from the begin() method.
+//
+// Revision 1.2 2007/01/17 22:44:34 acg
+// Andy Goodrich: fix for Microsoft compiler.
+//
+// Revision 1.3 2006/01/13 18:53:11 acg
+// Andy Goodrich: Added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#endif
diff --git a/ext/systemc/src/sysc/utils/sc_report.cpp b/ext/systemc/src/sysc/utils/sc_report.cpp
new file mode 100644
index 000000000..378d45cde
--- /dev/null
+++ b/ext/systemc/src/sysc/utils/sc_report.cpp
@@ -0,0 +1,330 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_report.cpp -- Run-time logging and reporting facilities
+
+ Interface design by SystemC Verification Working Group.
+ Implementation by Alex Riesen, Synopsys Inc.
+ Original implementation by Martin Janssen, Synopsys Inc.
+ Reference implementation by Cadence Design Systems, Inc., 2002-09-23:
+ Norris Ip, Dean Shea, John Rose, Jasvinder Singh, William Paulsen,
+ John Pierce, Rachida Kebichi, Ted Elkind, David Bailey.
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "sysc/kernel/sc_process.h"
+#include "sysc/kernel/sc_simcontext_int.h"
+#include "sysc/utils/sc_stop_here.h"
+#include "sysc/utils/sc_report.h"
+#include "sysc/utils/sc_utils_ids.h"
+#include <algorithm> // std::swap
+
+namespace sc_core {
+
+
+static void sc_deprecated_report_ids(const char* method)
+{
+ static bool warn_report_ids_deprecated=true;
+ if ( warn_report_ids_deprecated )
+ {
+ std::string message;
+ message = "integer report ids are deprecated, use string values: ";
+ message += method;
+ warn_report_ids_deprecated=false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_, message.c_str());
+ }
+}
+
+static char empty_str[] = "";
+static inline char * empty_dup(const char * p)
+{
+ if ( p && *p )
+ {
+ char* result;
+ result = (char*)malloc(strlen(p)+1);
+ strcpy(result, p);
+ return result;
+ }
+ else
+ {
+ return empty_str;
+ }
+}
+
+sc_report::sc_report()
+: severity(SC_INFO),
+ md(0),
+ msg(empty_dup(0)),
+ file(empty_dup(0)),
+ line(0),
+ timestamp(new sc_time(sc_time_stamp())),
+ process(0),
+ m_verbosity_level(SC_MEDIUM),
+ m_what(empty_dup(0))
+{
+}
+
+sc_report::sc_report(sc_severity severity_,
+ const sc_msg_def* md_,
+ const char* msg_,
+ const char* file_,
+ int line_,
+ int verbosity_level)
+: severity(severity_),
+ md(md_),
+ msg(empty_dup(msg_)),
+ file(empty_dup(file_)),
+ line(line_),
+ timestamp(new sc_time(sc_time_stamp())),
+ process(sc_get_current_process_b()),
+ m_verbosity_level(verbosity_level),
+ m_what( empty_dup( sc_report_compose_message(*this).c_str() ) )
+{
+}
+
+sc_report::sc_report(const sc_report& other)
+: std::exception(other),
+ severity(other.severity),
+ md(other.md),
+ msg(empty_dup(other.msg)),
+ file(empty_dup(other.file)),
+ line(other.line),
+ timestamp(new sc_time(*other.timestamp)),
+ process(other.process),
+ m_verbosity_level(other.m_verbosity_level),
+ m_what(empty_dup(other.m_what))
+{
+}
+
+sc_report & sc_report::operator=(const sc_report& other)
+{
+ sc_report copy(other);
+ swap( copy );
+ return *this;
+}
+
+void
+sc_report::swap( sc_report & that )
+{
+ using std::swap;
+ swap( severity, that.severity );
+ swap( md, that.md );
+ swap( msg, that.msg );
+ swap( file, that.file );
+ swap( line, that.line );
+ swap( timestamp, that.timestamp );
+ swap( process, that.process );
+ swap( m_verbosity_level, that.m_verbosity_level );
+ swap( m_what, that.m_what );
+}
+
+sc_report::~sc_report() throw()
+{
+ if ( file != empty_str )
+ free(file);
+ if ( msg != empty_str )
+ free(msg);
+ delete timestamp;
+ if ( m_what != empty_str )
+ free(m_what);
+}
+
+const char * sc_report::get_msg_type() const
+{
+ return md->msg_type;
+}
+
+//
+// backward compatibility with 2.0+
+//
+
+static bool warnings_are_errors = false;
+static const char unknown_id[] = "unknown id";
+
+void sc_report_handler::report(sc_severity severity_,
+ int id_,
+ const char* msg_,
+ const char* file_,
+ int line_ )
+{
+ sc_msg_def * md = sc_report_handler::mdlookup(id_);
+
+ if ( !md )
+ {
+ md = sc_report_handler::add_msg_type(unknown_id);
+ md->id = id_;
+ }
+
+ if ( severity_ == SC_WARNING && warnings_are_errors )
+ severity_ = SC_ERROR;
+
+ sc_actions actions = execute(md, severity_);
+ sc_report rep(severity_, md, msg_, file_, line_);
+
+ if ( actions & SC_CACHE_REPORT )
+ cache_report(rep);
+
+ if ( severity_ == SC_ERROR )
+ actions |= SC_THROW;
+ else if ( severity_ == SC_FATAL )
+ actions |= SC_ABORT;
+
+ handler(rep, actions);
+}
+
+void sc_report::register_id( int id, const char* msg )
+{
+ sc_deprecated_report_ids("sc_report::register_id()");
+ if( id < 0 ) {
+ SC_REPORT_ERROR( SC_ID_REGISTER_ID_FAILED_,
+ "invalid report id" );
+ }
+ if( msg == 0 ) {
+ SC_REPORT_ERROR( SC_ID_REGISTER_ID_FAILED_,
+ "invalid report message" );
+ }
+ sc_msg_def * md = sc_report_handler::mdlookup(id);
+
+ if ( !md )
+ md = sc_report_handler::add_msg_type(msg);
+
+ if ( !md ) {
+ SC_REPORT_ERROR( SC_ID_REGISTER_ID_FAILED_,
+ "report_map insertion error" );
+ }
+
+ if( md->id != -1 ) {
+ if( strcmp( msg, md->msg_type ) != 0 ) {
+ SC_REPORT_ERROR( SC_ID_REGISTER_ID_FAILED_,
+ "report id already exists" );
+ }
+ return;
+ }
+ md->id = id;
+}
+
+const char* sc_report::get_message( int id )
+{
+ sc_deprecated_report_ids("sc_report::get_message()");
+ sc_msg_def* md = sc_report_handler::mdlookup(id);
+
+ return md ? md->msg_type: unknown_id;
+}
+
+bool sc_report::is_suppressed( int id )
+{
+ sc_deprecated_report_ids("sc_report::is_suppressed()");
+ sc_msg_def* md = sc_report_handler::mdlookup(id);
+
+ return md ? md->actions == SC_DO_NOTHING: false; // only do-nothing set
+}
+
+void sc_report::suppress_id(int id_, bool suppress)
+{
+ sc_deprecated_report_ids("sc_report::suppress_id()");
+ sc_msg_def* md = sc_report_handler::mdlookup(id_);
+
+ if ( md )
+ md->actions = suppress ? SC_DO_NOTHING: SC_UNSPECIFIED;
+}
+
+void sc_report::suppress_infos(bool suppress)
+{
+ sc_deprecated_report_ids("sc_report::supress_infos");
+ sc_report_handler::sev_actions[SC_INFO] =
+ suppress ? SC_DO_NOTHING: SC_DEFAULT_INFO_ACTIONS;
+}
+
+void sc_report::suppress_warnings(bool suppress)
+{
+ sc_deprecated_report_ids("sc_report::suppress_warnings");
+ sc_report_handler::sev_actions[SC_WARNING] =
+ suppress ? SC_DO_NOTHING: SC_DEFAULT_WARNING_ACTIONS;
+}
+
+void sc_report::make_warnings_errors(bool flag)
+{
+ sc_deprecated_report_ids("sc_report::make_warnings_errors");
+ warnings_are_errors = flag;
+}
+
+int sc_report::get_id() const
+{
+ return md->id;
+}
+
+} // namespace sc_core
+
+// $Log: sc_report.cpp,v $
+// Revision 1.8 2011/08/29 18:04:32 acg
+// Philipp A. Hartmann: miscellaneous clean ups.
+//
+// Revision 1.7 2011/08/26 20:43:01 acg
+// Andy Goodrich:
+// (1) Replaced strdup with new and strcpy to eliminate issue with the
+// Greenhills compiler.
+// (2) Moved modification log to the end of the file to eliminate line
+// skew when check-ins are done.
+//
+// Revision 1.6 2011/08/24 22:05:56 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.5 2011/05/05 17:46:04 acg
+// Philip A. Hartmann: changes in "swap" support.
+//
+// Revision 1.4 2011/03/23 16:16:48 acg
+// Andy Goodrich: finish message verbosity support.
+//
+// Revision 1.3 2011/02/18 20:38:44 acg
+// Andy Goodrich: Updated Copyright notice.
+//
+// Revision 1.2 2011/02/01 23:02:05 acg
+// Andy Goodrich: IEEE 1666 2011 changes.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:06 acg
+// SystemC 2.3
+//
+// Revision 1.7 2006/03/21 00:00:37 acg
+// Andy Goodrich: changed name of sc_get_current_process_base() to be
+// sc_get_current_process_b() since its returning an sc_process_b instance.
+//
+// Revision 1.6 2006/01/25 00:31:27 acg
+// Andy Goodrich: Changed over to use a standard message id of
+// SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
+//
+// Revision 1.5 2006/01/24 22:02:30 acg
+// Andy Goodrich: switch deprecated features warnings to use a single message
+// id, SC_ID_IEEE_1666_DEPRECATION_.
+//
+// Revision 1.4 2006/01/24 20:53:41 acg
+// Andy Goodrich: added warnings indicating that use of integer ids in reports
+// is deprecated. Added tracing/sc_trace_ids.h to message list.
+//
+// Revision 1.3 2006/01/13 18:53:11 acg
+// Andy Goodrich: Added $Log command so that CVS comments are reproduced in
+// the source.
+
+// taf
diff --git a/ext/systemc/src/sysc/utils/sc_report.h b/ext/systemc/src/sysc/utils/sc_report.h
new file mode 100644
index 000000000..f76bef71f
--- /dev/null
+++ b/ext/systemc/src/sysc/utils/sc_report.h
@@ -0,0 +1,299 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_report.h -- Run-time logging and reporting facilities
+
+ Interface design by SystemC Verification Working Group.
+ Implementation by Alex Riesen, Synopsys Inc.
+ Original implementation by Martin Janssen, Synopsys Inc.
+ Reference implementation by Cadence Design Systems, Inc., 2002-09-23:
+ Norris Ip, Dean Shea, John Rose, Jasvinder Singh, William Paulsen,
+ John Pierce, Rachida Kebichi, Ted Elkind, David Bailey.
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+#ifndef SC_REPORT_H
+#define SC_REPORT_H 1
+
+#include <exception>
+#include <string>
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// ENUM : sc_severity
+//
+// Enumeration of possible exception severity levels
+// ----------------------------------------------------------------------------
+
+enum sc_severity {
+ SC_INFO = 0, // informative only
+ SC_WARNING, // indicates potentially incorrect condition
+ SC_ERROR, // indicates a definite problem
+ SC_FATAL, // indicates a problem from which we cannot recover
+ SC_MAX_SEVERITY
+};
+
+typedef unsigned sc_actions;
+
+// ----------------------------------------------------------------------------
+// ENUM : sc_verbosity
+//
+// Enumeration of message verbosity.
+// ----------------------------------------------------------------------------
+
+ enum sc_verbosity {
+ SC_NONE = 0,
+ SC_LOW = 100,
+ SC_MEDIUM = 200,
+ SC_HIGH = 300,
+ SC_FULL = 400,
+ SC_DEBUG = 500
+ };
+
+// ----------------------------------------------------------------------------
+// ENUM :
+//
+// Enumeration of actions on an exception (implementation specific)
+// ----------------------------------------------------------------------------
+
+enum {
+ SC_UNSPECIFIED = 0x0000, // look for lower-priority rule
+ SC_DO_NOTHING = 0x0001, // take no action (ignore if other bits set)
+ SC_THROW = 0x0002, // throw an exception
+ SC_LOG = 0x0004, // add report to report log
+ SC_DISPLAY = 0x0008, // display report to screen
+ SC_CACHE_REPORT = 0x0010, // save report to cache
+ SC_INTERRUPT = 0x0020, // call sc_interrupt_here(...)
+ SC_STOP = 0x0040, // call sc_stop()
+ SC_ABORT = 0x0080 // call abort()
+};
+
+class sc_object;
+class sc_time;
+struct sc_msg_def;
+class sc_report;
+class sc_report_handler;
+const std::string sc_report_compose_message( const sc_report& );
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_report
+//
+// Exception reporting
+// ----------------------------------------------------------------------------
+
+class sc_report : public std::exception
+{
+ friend class sc_report_handler;
+ friend sc_report* sc_handle_exception();
+
+ sc_report(); // used internally by sc_handle_exception
+
+public:
+
+ sc_report(const sc_report&);
+
+ sc_report & operator=(const sc_report&);
+
+ virtual ~sc_report() throw();
+
+ const char * get_msg_type() const;
+
+ const char * get_msg() const
+ { return msg; }
+
+ sc_severity get_severity() const
+ { return severity; }
+
+ const char * get_file_name() const
+ { return file; }
+
+ int get_line_number() const
+ { return line; }
+
+ const sc_time & get_time() const
+ { return *timestamp; }
+
+ const char* get_process_name() const;
+
+ int get_verbosity() const { return m_verbosity_level; }
+
+ bool valid () const
+ {
+ return process != 0;
+ }
+
+ virtual const char* what() const throw()
+ {
+ return m_what;
+ }
+
+ void swap( sc_report& );
+
+protected:
+
+ sc_report(sc_severity,
+ const sc_msg_def*,
+ const char* msg,
+ const char* file,
+ int line,
+ int verbosity_level=SC_MEDIUM);
+
+ sc_severity severity;
+ const sc_msg_def* md;
+ char* msg;
+ char* file;
+ int line;
+ sc_time* timestamp;
+ sc_object* process;
+ int m_verbosity_level;
+ char* m_what;
+
+public: // backward compatibility with 2.0+
+
+ static const char* get_message(int id);
+ static bool is_suppressed(int id);
+ static void make_warnings_errors(bool);
+ static void register_id(int id, const char* msg);
+ static void suppress_id(int id, bool); // only for info or warning
+ static void suppress_infos(bool);
+ static void suppress_warnings(bool);
+
+ int get_id() const;
+};
+typedef std::exception sc_exception;
+
+#define SC_DEFAULT_INFO_ACTIONS \
+ (::sc_core::SC_LOG | ::sc_core::SC_DISPLAY)
+#define SC_DEFAULT_WARNING_ACTIONS \
+ (::sc_core::SC_LOG | ::sc_core::SC_DISPLAY)
+#define SC_DEFAULT_ERROR_ACTIONS \
+ (::sc_core::SC_LOG | ::sc_core::SC_CACHE_REPORT | ::sc_core::SC_THROW)
+#define SC_DEFAULT_FATAL_ACTIONS \
+ (::sc_core::SC_LOG | ::sc_core::SC_DISPLAY | \
+ ::sc_core::SC_CACHE_REPORT | ::sc_core::SC_ABORT)
+
+
+// ----------------------------------------------------------------------------
+// Report macros.
+//
+// Use these macros to report an info, warning, error, or fatal.
+// ----------------------------------------------------------------------------
+
+#define SC_REPORT_INFO( msg_type, msg ) \
+ ::sc_core::sc_report_handler::report( \
+ ::sc_core::SC_INFO, msg_type, msg, __FILE__, __LINE__ )
+
+#define SC_REPORT_INFO_VERB( msg_type, msg, verbosity ) \
+ ::sc_core::sc_report_handler::report( \
+ ::sc_core::SC_INFO, msg_type, msg, verbosity, \
+ __FILE__ , __LINE__ )
+
+#define SC_REPORT_WARNING( msg_type, msg ) \
+ ::sc_core::sc_report_handler::report( \
+ ::sc_core::SC_WARNING, msg_type, msg, __FILE__, __LINE__ )
+
+#define SC_REPORT_ERROR( msg_type, msg ) \
+ ::sc_core::sc_report_handler::report( \
+ ::sc_core::SC_ERROR, msg_type, msg, __FILE__, __LINE__ )
+
+#define SC_REPORT_FATAL( msg_type, msg ) \
+ ::sc_core::sc_report_handler::report( \
+ ::sc_core::SC_FATAL, msg_type, msg, __FILE__, __LINE__ )
+
+// ----------------------------------------------------------------------------
+// MACRO : sc_assert(expr)
+//
+// Like assert(), but additionally prints the current process name
+// and simulation time, if the simulation is running.
+// ----------------------------------------------------------------------------
+
+#ifdef NDEBUG
+
+#define sc_assert(expr) \
+ ((void) 0)
+
+#else
+
+#define sc_assert(expr) \
+ ((void)((expr) ? 0 : \
+ (SC_REPORT_FATAL( ::sc_core::SC_ID_ASSERTION_FAILED_, #expr ), 0)))
+
+#endif // NDEBUG
+
+extern const char SC_ID_UNKNOWN_ERROR_[];
+extern const char SC_ID_WITHOUT_MESSAGE_[];
+extern const char SC_ID_NOT_IMPLEMENTED_[];
+extern const char SC_ID_INTERNAL_ERROR_[];
+extern const char SC_ID_ASSERTION_FAILED_[];
+extern const char SC_ID_OUT_OF_BOUNDS_[];
+
+// backward compatibility with 2.0+
+extern const char SC_ID_REGISTER_ID_FAILED_[];
+
+} // namespace sc_core
+
+#include "sysc/utils/sc_report_handler.h"
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Alex Riesen, Synopsys Inc., Jan 28, 2003
+ Description of Modification: Implementation for SytemC 2.1
+
+ *****************************************************************************/
+
+// $Log: sc_report.h,v $
+// Revision 1.8 2011/08/26 20:46:19 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.7 2011/05/05 17:46:04 acg
+// Philip A. Hartmann: changes in "swap" support.
+//
+// Revision 1.6 2011/04/19 02:39:44 acg
+// Andy Goodrich: set proper name for get_verbosity().
+//
+// Revision 1.5 2011/03/23 16:16:48 acg
+// Andy Goodrich: finish message verbosity support.
+//
+// Revision 1.4 2011/02/18 20:38:44 acg
+// Andy Goodrich: Updated Copyright notice.
+//
+// Revision 1.3 2011/02/01 23:02:05 acg
+// Andy Goodrich: IEEE 1666 2011 changes.
+//
+// Revision 1.2 2008/05/20 20:42:50 acg
+// Andy Goodrich: added sc_core namespace prefix for ID value in sc_assert()
+// macro.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:06 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:11 acg
+// Andy Goodrich: Added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#endif // SC_REPORT_H
diff --git a/ext/systemc/src/sysc/utils/sc_report_handler.cpp b/ext/systemc/src/sysc/utils/sc_report_handler.cpp
new file mode 100644
index 000000000..0de71a18b
--- /dev/null
+++ b/ext/systemc/src/sysc/utils/sc_report_handler.cpp
@@ -0,0 +1,799 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_report_handler.cpp -
+
+ Original Author: Alex Riesen, Synopsys, Inc.
+ see also sc_report.cpp
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+#include <cstdio>
+#include <stdlib.h>
+#include <string.h>
+
+#include "sysc/utils/sc_iostream.h"
+#include "sysc/kernel/sc_process.h"
+#include "sysc/kernel/sc_simcontext_int.h"
+#include "sysc/utils/sc_stop_here.h"
+#include "sysc/utils/sc_report_handler.h"
+#include "sysc/utils/sc_report.h"
+
+namespace std {}
+
+namespace sc_core {
+
+int sc_report_handler::verbosity_level = SC_MEDIUM;
+
+// not documented, but available
+const std::string sc_report_compose_message(const sc_report& rep)
+{
+ static const char * severity_names[] = {
+ "Info", "Warning", "Error", "Fatal"
+ };
+ std::string str;
+
+ str += severity_names[rep.get_severity()];
+ str += ": ";
+
+ if ( rep.get_id() >= 0 ) // backward compatibility with 2.0+
+ {
+ char idstr[64];
+ std::sprintf(idstr, "(%c%d) ",
+ "IWEF"[rep.get_severity()], rep.get_id());
+ str += idstr;
+ }
+ str += rep.get_msg_type();
+
+ if( *rep.get_msg() )
+ {
+ str += ": ";
+ str += rep.get_msg();
+ }
+ if( rep.get_severity() > SC_INFO )
+ {
+ char line_number_str[16];
+ str += "\nIn file: ";
+ str += rep.get_file_name();
+ str += ":";
+ std::sprintf(line_number_str, "%d", rep.get_line_number());
+ str += line_number_str;
+ sc_simcontext* simc = sc_get_curr_simcontext();
+
+ if( simc && sc_is_running() )
+ {
+ const char* proc_name = rep.get_process_name();
+
+ if( proc_name )
+ {
+ str += "\nIn process: ";
+ str += proc_name;
+ str += " @ ";
+ str += rep.get_time().to_string();
+ }
+ }
+ }
+
+ return str;
+}
+bool sc_report_close_default_log();
+
+static ::std::ofstream* log_stream = 0;
+static
+struct auto_close_log
+{
+ ~auto_close_log()
+ {
+ sc_report_close_default_log();
+ }
+} auto_close;
+
+const char* sc_report::get_process_name() const
+{
+ return process ? process->name() : 0;
+}
+
+
+//
+// The official handler of the exception reporting
+//
+
+void sc_report_handler::default_handler(const sc_report& rep,
+ const sc_actions& actions)
+{
+ if ( actions & SC_DISPLAY )
+ ::std::cout << ::std::endl << sc_report_compose_message(rep) <<
+ ::std::endl;
+
+ if ( (actions & SC_LOG) && get_log_file_name() )
+ {
+ if ( !log_stream )
+ log_stream = new ::std::ofstream(get_log_file_name()); // ios::trunc
+
+ *log_stream << rep.get_time() << ": "
+ << sc_report_compose_message(rep) << ::std::endl;
+ }
+ if ( actions & SC_STOP )
+ {
+ sc_stop_here(rep.get_msg_type(), rep.get_severity());
+ sc_stop();
+ }
+ if ( actions & SC_INTERRUPT )
+ sc_interrupt_here(rep.get_msg_type(), rep.get_severity());
+
+ if ( actions & SC_ABORT )
+ abort();
+
+ if ( actions & SC_THROW ) {
+ sc_process_b* proc_p = sc_get_current_process_b();
+ if( proc_p && proc_p->is_unwinding() )
+ proc_p->clear_unwinding();
+ throw rep;
+ }
+}
+
+// not documented, but available
+bool sc_report_close_default_log()
+{
+ delete log_stream;
+ sc_report_handler::set_log_file_name(NULL);
+
+ if ( !log_stream )
+ return false;
+
+ log_stream = 0;
+ return true;
+}
+
+int sc_report_handler::get_count(sc_severity severity_)
+{
+ return sev_call_count[severity_];
+}
+
+int sc_report_handler::get_count(const char* msg_type_)
+{
+ sc_msg_def * md = mdlookup(msg_type_);
+
+ if ( !md )
+ md = add_msg_type(msg_type_);
+
+ return md->call_count;
+}
+
+int sc_report_handler::get_count(const char* msg_type_, sc_severity severity_)
+{
+ sc_msg_def * md = mdlookup(msg_type_);
+
+ if ( !md )
+ md = add_msg_type(msg_type_);
+
+ return md->sev_call_count[severity_];
+}
+
+
+//
+// CLASS: sc_report_handler
+// implementation
+//
+
+sc_msg_def * sc_report_handler::mdlookup(const char * msg_type_)
+{
+ if( !msg_type_ ) // if msg_type is NULL, report unknown error
+ msg_type_ = SC_ID_UNKNOWN_ERROR_;
+
+ for ( msg_def_items * item = messages; item; item = item->next )
+ {
+ for ( int i = 0; i < item->count; ++i )
+ if ( !strcmp(msg_type_, item->md[i].msg_type) )
+ return item->md + i;
+ }
+ return 0;
+}
+
+// The calculation of actions to be executed
+sc_actions sc_report_handler::execute(sc_msg_def* md, sc_severity severity_)
+{
+ sc_actions actions = md->sev_actions[severity_]; // high prio
+
+ if ( SC_UNSPECIFIED == actions ) // middle prio
+ actions = md->actions;
+
+ if ( SC_UNSPECIFIED == actions ) // the lowest prio
+ actions = sev_actions[severity_];
+
+ actions &= ~suppress_mask; // higher than the high prio
+ actions |= force_mask; // higher than above, and the limit is the highest
+
+ unsigned * limit = 0;
+ unsigned * call_count = 0;
+
+ // just increment counters and check for overflow
+ if ( md->sev_call_count[severity_] < UINT_MAX )
+ md->sev_call_count[severity_]++;
+ if ( md->call_count < UINT_MAX )
+ md->call_count++;
+ if ( sev_call_count[severity_] < UINT_MAX )
+ sev_call_count[severity_]++;
+
+ if ( md->limit_mask & (1 << (severity_ + 1)) )
+ {
+ limit = md->sev_limit + severity_;
+ call_count = md->sev_call_count + severity_;
+ }
+ if ( !limit && (md->limit_mask & 1) )
+ {
+ limit = &md->limit;
+ call_count = &md->call_count;
+ }
+ if ( !limit )
+ {
+ limit = sev_limit + severity_;
+ call_count = sev_call_count + severity_;
+ }
+ if ( *limit == 0 )
+ {
+ // stop limit disabled
+ }
+ else if ( *limit != UINT_MAX )
+ {
+ if ( *call_count >= *limit )
+ actions |= SC_STOP; // force sc_stop()
+ }
+ return actions;
+}
+
+void sc_report_handler::report( sc_severity severity_,
+ const char* msg_type_,
+ const char* msg_,
+ int verbosity_,
+ const char* file_,
+ int line_ )
+{
+ sc_msg_def * md = mdlookup(msg_type_);
+
+ // If the severity of the report is SC_INFO and the specified verbosity
+ // level is greater than the maximum verbosity level of the simulator then
+ // return without any action.
+
+ if ( (severity_ == SC_INFO) && (verbosity_ > verbosity_level) ) return;
+
+ // Process the report:
+
+ if ( !md )
+ md = add_msg_type(msg_type_);
+
+ sc_actions actions = execute(md, severity_);
+ sc_report rep(severity_, md, msg_, file_, line_, verbosity_);
+
+ if ( actions & SC_CACHE_REPORT )
+ cache_report(rep);
+
+ handler(rep, actions);
+}
+
+void sc_report_handler::report(sc_severity severity_,
+ const char * msg_type_,
+ const char * msg_,
+ const char * file_,
+ int line_)
+{
+ sc_msg_def * md = mdlookup(msg_type_);
+
+ // If the severity of the report is SC_INFO and the maximum verbosity
+ // level is less than SC_MEDIUM return without any action.
+
+ if ( (severity_ == SC_INFO) && (SC_MEDIUM > verbosity_level) ) return;
+
+ // Process the report:
+
+
+ if ( !md )
+ md = add_msg_type(msg_type_);
+
+ sc_actions actions = execute(md, severity_);
+ sc_report rep(severity_, md, msg_, file_, line_);
+
+ if ( actions & SC_CACHE_REPORT )
+ cache_report(rep);
+
+ handler(rep, actions);
+}
+
+// The following method is never called by the simulator.
+
+void sc_report_handler::initialize()
+{
+#if 0 // actually, i do not know whether we have to reset these.
+ suppress();
+ force();
+ set_actions(SC_INFO, SC_DEFAULT_INFO_ACTIONS);
+ set_actions(SC_WARNING, SC_DEFAULT_WARNING_ACTIONS);
+ set_actions(SC_ERROR, SC_DEFAULT_ERROR_ACTIONS);
+ set_actions(SC_FATAL, SC_DEFAULT_FATAL_ACTIONS);
+#endif
+
+ sev_call_count[SC_INFO] = 0;
+ sev_call_count[SC_WARNING] = 0;
+ sev_call_count[SC_ERROR] = 0;
+ sev_call_count[SC_FATAL] = 0;
+
+ msg_def_items * items = messages;
+
+ while ( items != &msg_terminator )
+ {
+ for ( int i = 0; i < items->count; ++i )
+ {
+ items->md[i].call_count = 0;
+ items->md[i].sev_call_count[SC_INFO] = 0;
+ items->md[i].sev_call_count[SC_WARNING] = 0;
+ items->md[i].sev_call_count[SC_ERROR] = 0;
+ items->md[i].sev_call_count[SC_FATAL] = 0;
+ }
+ items = items->next;
+ }
+
+ // PROCESS ANY ENVIRONMENTAL OVERRIDES:
+
+ const char* deprecation_warn = std::getenv("SC_DEPRECATION_WARNINGS");
+ if ( (deprecation_warn!=0) && !strcmp(deprecation_warn,"DISABLE") )
+ {
+ set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING);
+ }
+}
+
+// free the sc_msg_def's allocated by add_msg_type
+// (or implicit msg_type registration: set_actions, abort_after)
+// clear last_global_report.
+void sc_report_handler::release()
+{
+ delete last_global_report;
+ last_global_report = 0;
+ sc_report_close_default_log();
+
+ msg_def_items * items = messages, * newitems = &msg_terminator;
+ messages = &msg_terminator;
+
+ while ( items != &msg_terminator )
+ {
+ for ( int i = 0; i < items->count; ++i )
+ if ( items->md[i].msg_type == items->md[i].msg_type_data )
+ free(items->md[i].msg_type_data);
+
+ msg_def_items * prev = items;
+ items = items->next;
+
+ if ( prev->allocated )
+ {
+ delete [] prev->md;
+ delete prev;
+ }
+ else
+ {
+ prev->next = newitems;
+ newitems = prev;
+ }
+ }
+ messages = newitems;
+}
+
+sc_msg_def * sc_report_handler::add_msg_type(const char * msg_type_)
+{
+ sc_msg_def * md = mdlookup(msg_type_);
+ int msg_type_len;
+
+ if ( md )
+ return md;
+
+ msg_def_items * items = new msg_def_items;
+
+ if ( !items )
+ return 0;
+
+ items->count = 1;
+ items->md = new sc_msg_def[items->count];
+
+ if ( !items->md )
+ {
+ delete items;
+ return 0;
+ }
+ memset(items->md, 0, sizeof(sc_msg_def) * items->count);
+ msg_type_len = strlen(msg_type_);
+ if ( msg_type_len > 0 )
+ {
+ items->md->msg_type_data = (char*) malloc(msg_type_len+1);
+ strcpy( items->md->msg_type_data, msg_type_ );
+ items->md->id = -1; // backward compatibility with 2.0+
+ }
+ else
+ {
+ delete items->md;
+ delete items;
+ return 0;
+ }
+ items->md->msg_type = items->md->msg_type_data;
+ add_static_msg_types(items);
+ items->allocated = true;
+
+ return items->md;
+}
+
+void sc_report_handler::add_static_msg_types(msg_def_items * items)
+{
+ items->allocated = false;
+ items->next = messages;
+ messages = items;
+}
+
+sc_actions sc_report_handler::set_actions(sc_severity severity_,
+ sc_actions actions_)
+{
+ sc_actions old = sev_actions[severity_];
+ sev_actions[severity_] = actions_;
+ return old;
+}
+
+sc_actions sc_report_handler::set_actions(const char * msg_type_,
+ sc_actions actions_)
+{
+ sc_msg_def * md = mdlookup(msg_type_);
+
+ if ( !md )
+ md = add_msg_type(msg_type_);
+
+ sc_actions old = md->actions;
+ md->actions = actions_;
+
+ return old;
+}
+
+sc_actions sc_report_handler::set_actions(const char * msg_type_,
+ sc_severity severity_,
+ sc_actions actions_)
+{
+ sc_msg_def * md = mdlookup(msg_type_);
+
+ if ( !md )
+ md = add_msg_type(msg_type_);
+
+ sc_actions old = md->sev_actions[severity_];
+ md->sev_actions[severity_] = actions_;
+
+ return old;
+}
+
+int sc_report_handler::stop_after(sc_severity severity_, int limit)
+{
+ int old = sev_limit[severity_];
+
+ sev_limit[severity_] = limit < 0 ? UINT_MAX: (unsigned) limit;
+
+ return old;
+}
+
+int sc_report_handler::stop_after(const char * msg_type_, int limit)
+{
+ sc_msg_def * md = mdlookup(msg_type_);
+
+ if ( !md )
+ md = add_msg_type(msg_type_);
+
+ int old = md->limit_mask & 1 ? md->limit: UINT_MAX;
+
+ if ( limit < 0 )
+ md->limit_mask &= ~1;
+ else
+ {
+ md->limit_mask |= 1;
+ md->limit = limit;
+ }
+ return old;
+}
+
+int sc_report_handler::stop_after(const char * msg_type_,
+ sc_severity severity_,
+ int limit)
+{
+ sc_msg_def * md = mdlookup(msg_type_);
+
+ if ( !md )
+ md = add_msg_type(msg_type_);
+
+ int mask = 1 << (severity_ + 1);
+ int old = md->limit_mask & mask ? md->sev_limit[severity_]: UINT_MAX;
+
+ if ( limit < 0 )
+ md->limit_mask &= ~mask;
+ else
+ {
+ md->limit_mask |= mask;
+ md->sev_limit[severity_] = limit;
+ }
+ return old;
+}
+
+sc_actions sc_report_handler::suppress(sc_actions mask)
+{
+ sc_actions old = suppress_mask;
+ suppress_mask = mask;
+ return old;
+}
+
+sc_actions sc_report_handler::suppress()
+{
+ return suppress(0);
+}
+
+sc_actions sc_report_handler::force(sc_actions mask)
+{
+ sc_actions old = force_mask;
+ force_mask = mask;
+ return old;
+}
+
+sc_actions sc_report_handler::force()
+{
+ return force(0);
+}
+
+sc_report_handler_proc
+sc_report_handler::set_handler(sc_report_handler_proc handler_)
+{
+ sc_report_handler_proc old = handler;
+ handler = handler_ ? handler_: &sc_report_handler::default_handler;
+ return old;
+}
+
+sc_report_handler_proc
+sc_report_handler::get_handler()
+{
+ return handler;
+}
+
+sc_report* sc_report_handler::get_cached_report()
+{
+ sc_process_b * proc = sc_get_current_process_b();
+
+ if ( proc )
+ return proc->get_last_report();
+
+ return last_global_report;
+}
+
+void sc_report_handler::clear_cached_report()
+{
+ sc_process_b * proc = sc_get_current_process_b();
+
+ if ( proc )
+ proc->set_last_report(0);
+ else
+ {
+ delete last_global_report;
+ last_global_report = 0;
+ }
+}
+
+sc_actions sc_report_handler::get_new_action_id()
+{
+ for ( sc_actions p = 1; p; p <<= 1 )
+ {
+ if ( !(p & available_actions) ) // free
+ {
+ available_actions |= p;
+ return p;
+ }
+ }
+ return SC_UNSPECIFIED;
+}
+
+bool sc_report_handler::set_log_file_name(const char* name_)
+{
+ if ( !name_ )
+ {
+ free(log_file_name);
+ log_file_name = 0;
+ return false;
+ }
+ if ( log_file_name )
+ return false;
+
+ log_file_name = (char*)malloc(strlen(name_)+1);
+ strcpy(log_file_name, name_);
+ return true;
+}
+
+const char * sc_report_handler::get_log_file_name()
+{
+ return log_file_name;
+}
+
+void sc_report_handler::cache_report(const sc_report& rep)
+{
+ sc_process_b * proc = sc_get_current_process_b();
+ if ( proc )
+ proc->set_last_report(new sc_report(rep));
+ else
+ {
+ delete last_global_report;
+ last_global_report = new sc_report(rep);
+ }
+}
+
+//
+// backward compatibility with 2.0+
+//
+
+sc_msg_def * sc_report_handler::mdlookup(int id)
+{
+ for ( msg_def_items * item = messages; item; item = item->next )
+ {
+ for ( int i = 0; i < item->count; ++i )
+ if ( id == item->md[i].id )
+ return item->md + i;
+ }
+ return 0;
+}
+
+int sc_report_handler::get_verbosity_level() { return verbosity_level; }
+
+int sc_report_handler::set_verbosity_level( int level )
+{
+ int result = verbosity_level;
+ verbosity_level = level;
+ return result;
+}
+
+//
+// CLASS: sc_report_handler
+// static variables
+//
+
+sc_actions sc_report_handler::suppress_mask = 0;
+sc_actions sc_report_handler::force_mask = 0;
+
+sc_actions sc_report_handler::sev_actions[SC_MAX_SEVERITY] =
+{
+ /* info */ SC_DEFAULT_INFO_ACTIONS,
+ /* warn */ SC_DEFAULT_WARNING_ACTIONS,
+ /* error */ SC_DEFAULT_ERROR_ACTIONS,
+ /* fatal */ SC_DEFAULT_FATAL_ACTIONS
+};
+
+// Note that SC_FATAL has a limit of 1 by default
+
+sc_actions sc_report_handler::sev_limit[SC_MAX_SEVERITY] =
+{
+ UINT_MAX, UINT_MAX, UINT_MAX, UINT_MAX
+};
+sc_actions sc_report_handler::sev_call_count[SC_MAX_SEVERITY] = { 0, 0, 0, 0 };
+
+sc_report* sc_report_handler::last_global_report = NULL;
+sc_actions sc_report_handler::available_actions =
+ SC_DO_NOTHING |
+ SC_THROW |
+ SC_LOG |
+ SC_DISPLAY |
+ SC_CACHE_REPORT |
+ SC_INTERRUPT |
+ SC_STOP |
+ SC_ABORT;
+
+sc_report_handler_proc sc_report_handler::handler =
+ &sc_report_handler::default_handler;
+
+char * sc_report_handler::log_file_name = 0;
+
+sc_report_handler::msg_def_items * sc_report_handler::messages =
+ &sc_report_handler::msg_terminator;
+
+
+//
+// predefined messages
+//
+
+const char SC_ID_REGISTER_ID_FAILED_[] = "register_id failed";
+const char SC_ID_UNKNOWN_ERROR_[] = "unknown error";
+const char SC_ID_WITHOUT_MESSAGE_[] = "";
+const char SC_ID_NOT_IMPLEMENTED_[] = "not implemented";
+const char SC_ID_INTERNAL_ERROR_[] = "internal error";
+const char SC_ID_ASSERTION_FAILED_[] = "assertion failed";
+const char SC_ID_OUT_OF_BOUNDS_[] = "out of bounds";
+
+#define DEFINE_MSG(id,n) \
+ { \
+ (id), \
+ 0u, {0u}, /* actions */ \
+ 0u, {0u}, 0u, /* limits */ \
+ 0u, {0u}, NULL, /* call counters */ \
+ n \
+ }
+
+static sc_msg_def default_msgs[] = {
+ DEFINE_MSG(SC_ID_REGISTER_ID_FAILED_, 800),
+ DEFINE_MSG(SC_ID_UNKNOWN_ERROR_, 0),
+ DEFINE_MSG(SC_ID_WITHOUT_MESSAGE_, 1),
+ DEFINE_MSG(SC_ID_NOT_IMPLEMENTED_, 2),
+ DEFINE_MSG(SC_ID_INTERNAL_ERROR_, 3),
+ DEFINE_MSG(SC_ID_ASSERTION_FAILED_, 4),
+ DEFINE_MSG(SC_ID_OUT_OF_BOUNDS_, 5)
+};
+
+sc_report_handler::msg_def_items sc_report_handler::msg_terminator =
+{
+ default_msgs,
+ sizeof(default_msgs)/sizeof(*default_msgs),
+ false,
+ NULL
+};
+
+} // namespace sc_core
+
+// $Log: sc_report_handler.cpp,v $
+// Revision 1.9 2011/08/29 18:04:32 acg
+// Philipp A. Hartmann: miscellaneous clean ups.
+//
+// Revision 1.8 2011/08/26 20:46:19 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.7 2011/08/07 19:08:08 acg
+// Andy Goodrich: moved logs to end of file so line number synching works
+// better between versions.
+//
+// Revision 1.6 2011/08/07 18:56:03 acg
+// Philipp A. Hartmann: added cast to ? : to eliminate clang warning message.
+//
+// Revision 1.5 2011/03/23 16:16:49 acg
+// Andy Goodrich: finish message verbosity support.
+//
+// Revision 1.4 2011/02/18 20:38:44 acg
+// Andy Goodrich: Updated Copyright notice.
+//
+// Revision 1.3 2011/02/11 13:25:55 acg
+// Andy Goodrich: Philipp's changes for sc_unwind_exception.
+//
+// Revision 1.2 2011/02/01 23:02:05 acg
+// Andy Goodrich: IEEE 1666 2011 changes.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:06 acg
+// SystemC 2.3
+//
+// Revision 1.7 2006/05/26 20:35:52 acg
+// Andy Goodrich: removed debug message that should not have been left in.
+//
+// Revision 1.6 2006/03/21 00:00:37 acg
+// Andy Goodrich: changed name of sc_get_current_process_base() to be
+// sc_get_current_process_b() since its returning an sc_process_b instance.
+//
+// Revision 1.5 2006/01/31 21:42:07 acg
+// Andy Goodrich: Added checks for SC_DEPRECATED_WARNINGS being defined as
+// DISABLED. If so, we turn off the /IEEE_Std_1666/deprecated message group.
+//
+// Revision 1.4 2006/01/26 21:08:17 acg
+// Andy Goodrich: conversion to use sc_is_running instead of deprecated
+// sc_simcontext::is_running()
+//
+// Revision 1.3 2006/01/13 18:53:11 acg
+// Andy Goodrich: Added $Log command so that CVS comments are reproduced in
+// the source.
+
+// Taf!
diff --git a/ext/systemc/src/sysc/utils/sc_report_handler.h b/ext/systemc/src/sysc/utils/sc_report_handler.h
new file mode 100644
index 000000000..799985a1f
--- /dev/null
+++ b/ext/systemc/src/sysc/utils/sc_report_handler.h
@@ -0,0 +1,197 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_report_handler.h -
+
+ Original Author: Alex Riesen, Synopsys, Inc.
+ see also sc_report.h
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+#ifndef SC_REPORT_HANDLER_H
+#define SC_REPORT_HANDLER_H
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// STRUCT : sc_msg_def
+//
+// Exception message definition structure
+// ----------------------------------------------------------------------------
+
+struct sc_msg_def
+{
+ const char* msg_type;
+ sc_actions actions;
+ sc_actions sev_actions[SC_MAX_SEVERITY];
+ unsigned limit;
+ unsigned sev_limit[SC_MAX_SEVERITY];
+ unsigned limit_mask; // 0 - limit, 1..4 - sev_limit
+ unsigned call_count;
+ unsigned sev_call_count[SC_MAX_SEVERITY];
+ char* msg_type_data;
+
+ int id; // backward compatibility with 2.0+
+};
+
+typedef void (* sc_report_handler_proc)(const sc_report&, const sc_actions &);
+class sc_report;
+extern bool sc_report_close_default_log();
+class sc_report_handler
+{
+public:
+ static void report(sc_severity,
+ const char* msg_type,
+ const char* msg,
+ const char* file,
+ int line);
+
+ static void report( sc_severity,
+ const char* msg_type,
+ const char* msg,
+ int verbosity,
+ const char* file,
+ int line );
+
+ static sc_actions set_actions(sc_severity,
+ sc_actions = SC_UNSPECIFIED);
+
+ static sc_actions set_actions(const char * msg_type,
+ sc_actions = SC_UNSPECIFIED);
+
+ static sc_actions set_actions(const char * msg_type,
+ sc_severity,
+ sc_actions = SC_UNSPECIFIED);
+
+ static int stop_after(sc_severity, int limit = -1);
+ static int stop_after(const char* msg_type, int limit = -1);
+ static int stop_after(const char* msg_type, sc_severity, int limit = -1);
+
+ static sc_actions suppress(sc_actions);
+ static sc_actions suppress();
+ static sc_actions force(sc_actions);
+ static sc_actions force();
+
+ static int get_count(sc_severity severity_);
+ static int get_count(const char* msg_type_);
+ static int get_count(const char* msg_type_, sc_severity severity_);
+
+ static int get_verbosity_level();
+ static int set_verbosity_level( int level );
+
+
+ static void initialize(); // just reset counters
+ static void release(); // initialize() needed for reports after it
+
+ static sc_report_handler_proc set_handler(sc_report_handler_proc);
+ static sc_report_handler_proc get_handler();
+ // use set_handler(NULL); to restore default handler
+ static void default_handler(const sc_report&, const sc_actions&);
+
+ static sc_actions get_new_action_id();
+
+ static sc_report* get_cached_report();
+ static void clear_cached_report();
+
+ // if filename is NULL, the previous log file name will be removed.
+ // The provider of a report_handler supposed to handle this.
+ // Return false if filename is not NULL and filename is already set.
+ static bool set_log_file_name(const char* filename);
+ static const char* get_log_file_name();
+
+public: // private, actually
+
+ struct msg_def_items
+ {
+ sc_msg_def* md; // have to point to sc_msg_def-s
+ int count; // set to number of items in md[]
+ bool allocated; // used internally, previous value ignored
+ msg_def_items* next; // used internally, previous value ignored
+ };
+
+ static void add_static_msg_types(msg_def_items *);
+ static sc_msg_def* add_msg_type(const char * msg_type);
+
+protected:
+
+ static void cache_report(const sc_report&);
+ static sc_actions execute(sc_msg_def*, sc_severity);
+
+ static sc_actions suppress_mask;
+ static sc_actions force_mask;
+ static sc_actions sev_actions[SC_MAX_SEVERITY];
+ static unsigned sev_limit[SC_MAX_SEVERITY];
+ static unsigned sev_call_count[SC_MAX_SEVERITY];
+ static sc_report* last_global_report;
+ static sc_actions available_actions;
+ static char* log_file_name;
+ static int verbosity_level;
+
+ static msg_def_items* messages;
+ static msg_def_items msg_terminator;
+
+ static sc_report_handler_proc handler;
+
+ static sc_msg_def* mdlookup(const char* msg_type);
+
+private: // backward compatibility with 2.0+
+
+ friend class sc_report;
+ static sc_msg_def* mdlookup(int id);
+
+public:
+
+ static void report(sc_severity,
+ int id,
+ const char* add_msg,
+ const char* file,
+ int line);
+
+};
+
+} // namespace sc_core
+
+// $Log: sc_report_handler.h,v $
+// Revision 1.5 2011/08/26 20:46:19 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.4 2011/03/23 16:16:49 acg
+// Andy Goodrich: finish message verbosity support.
+//
+// Revision 1.3 2011/02/18 20:38:44 acg
+// Andy Goodrich: Updated Copyright notice.
+//
+// Revision 1.2 2011/02/01 23:02:05 acg
+// Andy Goodrich: IEEE 1666 2011 changes.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:06 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:11 acg
+// Andy Goodrich: Added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/utils/sc_stop_here.cpp b/ext/systemc/src/sysc/utils/sc_stop_here.cpp
new file mode 100644
index 000000000..614b03dd0
--- /dev/null
+++ b/ext/systemc/src/sysc/utils/sc_stop_here.cpp
@@ -0,0 +1,124 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_stop_here.cpp -- Function provided for debugging purposes.
+ This file is always compiled in debug mode, such that
+ setting a breakpoint at this function can help locate
+ the cause of a SystemC error or warning.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-11-14
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+#include "sysc/utils/sc_stop_here.h"
+
+
+namespace sc_core {
+
+static const char* info_id = 0;
+static const char* warning_id = 0;
+static const char* error_id = 0;
+static const char* fatal_id = 0;
+
+// ----------------------------------------------------------------------------
+// FUNCTION : sc_interrupt_here
+//
+// Debugging aid for warning, error, and fatal reports.
+// This function *cannot* be inlined.
+// ----------------------------------------------------------------------------
+
+void
+sc_interrupt_here( const char* id, sc_severity severity )
+{
+ // you can set a breakpoint at some of the lines below, either to
+ // interrupt with any severity, or to interrupt with a specific severity
+
+ switch( severity ) {
+ case SC_INFO:
+ info_id = id;
+ break;
+ case SC_WARNING:
+ warning_id = id;
+ break;
+ case SC_ERROR:
+ error_id = id;
+ break;
+ default:
+ case SC_FATAL:
+ fatal_id = id;
+ break;
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// FUNCTION : sc_stop_here
+//
+// Debugging aid for warning, error, and fatal reports.
+// This function *cannot* be inlined.
+// ----------------------------------------------------------------------------
+
+void
+sc_stop_here( const char* id, sc_severity severity )
+{
+ // you can set a breakpoint at some of the lines below, either to
+ // stop with any severity, or to stop with a specific severity
+
+ switch( severity ) {
+ case SC_INFO:
+ info_id = id;
+ break;
+ case SC_WARNING:
+ warning_id = id;
+ break;
+ case SC_ERROR:
+ error_id = id;
+ break;
+ default:
+ case SC_FATAL:
+ fatal_id = id;
+ break;
+ }
+}
+
+} // namespace sc_core
+
+// $Log: sc_stop_here.cpp,v $
+// Revision 1.4 2011/08/26 21:49:08 acg
+// Philipp A. Hartmann: eliminate compiler warning by moving static variables
+// out of functions.
+//
+// Revision 1.3 2011/08/26 20:46:19 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.2 2011/02/18 20:38:44 acg
+// Andy Goodrich: Updated Copyright notice.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:06 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:11 acg
+// Andy Goodrich: Added $Log command so that CVS comments are reproduced in
+// the source.
+
+// Taf!
diff --git a/ext/systemc/src/sysc/utils/sc_stop_here.h b/ext/systemc/src/sysc/utils/sc_stop_here.h
new file mode 100644
index 000000000..8d8dca412
--- /dev/null
+++ b/ext/systemc/src/sysc/utils/sc_stop_here.h
@@ -0,0 +1,82 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_stop_here.h -- Function provided for debugging purposes.
+ This file is always compiled in debug mode, such that
+ setting a breakpoint at this function can help locate
+ the cause of a SystemC error or warning.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-11-14
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+// $Log: sc_stop_here.h,v $
+// Revision 1.3 2011/08/26 20:46:19 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+#ifndef SC_STOP_HERE_H
+#define SC_STOP_HERE_H
+
+
+#include "sysc/utils/sc_report.h"
+
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// FUNCTION : sc_interrupt_here
+//
+// Debugging aid for interrupt warning, error, and fatal reports.
+// ----------------------------------------------------------------------------
+
+extern
+void
+sc_interrupt_here( const char* id, sc_severity severity );
+
+
+// ----------------------------------------------------------------------------
+// FUNCTION : sc_stop_here
+//
+// Debugging aid for warning, error, and fatal reports.
+// ----------------------------------------------------------------------------
+
+extern
+void
+sc_stop_here( const char* id, sc_severity severity );
+
+} // namespace sc_core
+
+#endif
+
+// Revision 1.2 2011/02/18 20:38:44 acg
+// Andy Goodrich: Updated Copyright notice.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:06 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:11 acg
+// Andy Goodrich: Added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+// Taf!
diff --git a/ext/systemc/src/sysc/utils/sc_string.cpp b/ext/systemc/src/sysc/utils/sc_string.cpp
new file mode 100644
index 000000000..25c788a59
--- /dev/null
+++ b/ext/systemc/src/sysc/utils/sc_string.cpp
@@ -0,0 +1,612 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_string.cpp -- Implementation of a simple string class.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+#include <assert.h>
+#include <ctype.h>
+#include <cstdio>
+#include <stdarg.h>
+#include <string.h>
+
+#include "sysc/utils/sc_iostream.h"
+#include "sysc/utils/sc_string.h"
+#include "sysc/utils/sc_utils_ids.h"
+
+namespace sc_dt {
+
+inline static int
+sc_roundup( int n, int m )
+{
+ return ((n - 1) / m + 1) * m;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_string_rep
+//
+// Reference counting string implementation class.
+// ----------------------------------------------------------------------------
+
+class sc_string_rep
+{
+ friend class sc_string_old;
+ friend ::std::ostream& operator<<( ::std::ostream&, const sc_string_old& );
+ friend ::std::istream& operator>>( ::std::istream&, sc_string_old& );
+ friend sc_string_old operator+( const char*, const sc_string_old& );
+
+ sc_string_rep( int size = 16 ) :
+ ref_count(1), alloc( sc_roundup( size, 16 ) ), str( new char[alloc] )
+ {
+ *str = '\0';
+ }
+
+ sc_string_rep( const char* s ) : ref_count(1), alloc(0), str(0)
+ {
+ if (s) {
+ alloc = 1 + strlen(s);
+ str = strcpy( new char[alloc], s );
+ }
+ else {
+ alloc = 16;
+ str = strcpy( new char[alloc], "" );
+ }
+ }
+
+ sc_string_rep( const char* s, int n); // get first n chars from the string
+
+ ~sc_string_rep()
+ {
+ assert( ref_count == 0 );
+ delete[] str;
+ }
+
+ void resize( int new_size );
+ void set_string( const char* s );
+
+ int ref_count;
+ int alloc;
+ char* str;
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+sc_string_rep::sc_string_rep( const char* s, int n) :
+ ref_count(1), alloc(0), str(0)
+{
+ if (s && n>0) {
+ alloc = 1 + n;
+ str = strncpy( new char[alloc], s,n );
+ str[n] = 00;
+ }
+ else {
+ alloc = 16;
+ str = strcpy( new char[alloc], "" );
+ }
+}
+
+void
+sc_string_rep::resize( int new_size )
+{
+ if (new_size <= alloc) return;
+ alloc = sc_roundup( new_size, 16 );
+ char* new_str = strcpy( new char[alloc], str );
+ delete[] str;
+ str = new_str;
+}
+
+void
+sc_string_rep::set_string( const char* s )
+{
+ int len = strlen(s);
+ resize( len + 1 );
+ strcpy( str, s );
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_string_old
+//
+// String class (yet another).
+// ----------------------------------------------------------------------------
+
+// constructors
+
+sc_string_old::sc_string_old( int size ) : rep( new sc_string_rep(size) )
+{
+}
+
+sc_string_old::sc_string_old( const char* s ) : rep( new sc_string_rep(s) )
+{
+}
+
+sc_string_old::sc_string_old( const char* s, int n ) :
+ rep( new sc_string_rep( s, n ) )
+{
+}
+
+sc_string_old::sc_string_old( const sc_string_old& s ) : rep( s.rep )
+{
+ rep->ref_count ++;
+}
+
+sc_string_old::sc_string_old( sc_string_rep* r ) : rep(r)
+{
+}
+
+
+// destructor
+
+sc_string_old::~sc_string_old()
+{
+ if( -- (rep->ref_count) == 0 ) {
+ delete rep;
+ }
+}
+
+
+int
+sc_string_old::length() const
+{
+ return strlen(rep->str);
+}
+
+sc_string_old
+sc_string_old::operator+( const char* s ) const
+{
+ int len = length();
+ sc_string_rep* r = new sc_string_rep( len + strlen(s) + 1 );
+ strcpy( r->str, rep->str );
+ strcpy( r->str + len, s );
+ return sc_string_old(r);
+}
+
+sc_string_old sc_string_old::operator+(char c) const
+{
+ int len = length();
+ sc_string_rep* r = new sc_string_rep( len + 2 );
+ strcpy( r->str, rep->str );
+ r->str[len] = c;
+ r->str[len+1] = 00;
+ return sc_string_old(r);
+}
+
+sc_string_old
+operator+( const char* s, const sc_string_old& t )
+{
+ int len = strlen(s);
+ sc_string_rep* r = new sc_string_rep( len + t.length() + 1 );
+ strcpy( r->str, s );
+ strcpy( r->str + len, t );
+ return sc_string_old(r);
+}
+
+sc_string_old
+sc_string_old::operator+( const sc_string_old& s ) const
+{
+ int len = length();
+ sc_string_rep* r = new sc_string_rep( len + s.length() + 1 );
+ strcpy( r->str, rep->str );
+ strcpy( r->str + len, s.rep->str );
+ return sc_string_old(r);
+}
+
+sc_string_old&
+sc_string_old::operator=( const char* s )
+{
+ if (rep->ref_count > 1) {
+ --rep->ref_count;
+ rep = new sc_string_rep(s);
+ }
+ else {
+ rep->set_string(s);
+ }
+ return *this;
+}
+
+sc_string_old&
+sc_string_old::operator=( const sc_string_old& s )
+{
+ if (&s == this)
+ return *this;
+ if (--(rep->ref_count) == 0)
+ delete rep;
+ rep = s.rep;
+ rep->ref_count++;
+ return *this;
+}
+
+sc_string_old&
+sc_string_old::operator+=( const char* s )
+{
+ int oldlen = length();
+ int slen = strlen(s);
+ if (rep->ref_count > 1) {
+ sc_string_rep* oldrep = rep;
+ --rep->ref_count;
+ rep = new sc_string_rep( oldlen + slen + 1 );
+ strcpy( rep->str, oldrep->str );
+ strcpy( rep->str + oldlen, s );
+ }
+ else {
+ rep->resize( oldlen + slen + 1 );
+ strcpy( rep->str + oldlen, s );
+ }
+ return *this;
+}
+
+sc_string_old& sc_string_old::operator+=(char c)
+{
+ int oldlen = length();
+ if (rep->ref_count > 1) {
+ sc_string_rep* oldrep = rep;
+ --rep->ref_count;
+ rep = new sc_string_rep( oldlen + 2 );
+ strcpy( rep->str, oldrep->str );
+ rep->str[oldlen]=c;
+ rep->str[oldlen+1]=00;
+ }
+ else {
+ rep->resize( oldlen + 2 );
+ rep->str[oldlen]=c;
+ rep->str[oldlen+1]=00;
+ }
+ return *this;
+}
+
+sc_string_old&
+sc_string_old::operator+=( const sc_string_old& s )
+{
+ return this->operator+=( s.rep->str );
+}
+
+int
+sc_string_old::cmp( const char* s ) const
+{
+ return strcmp( rep->str, s );
+}
+
+int
+sc_string_old::cmp( const sc_string_old& s ) const
+{
+ return strcmp( rep->str, s.rep->str );
+}
+
+const char* sc_string_old::c_str() const
+{
+ return rep->str;
+}
+
+// get substring
+sc_string_old sc_string_old::substr(int first,int last) const
+{
+ if(first<0 || last<0 || first>last || first>=length() || last>=length())
+ return "";
+ return sc_string_old(rep->str+first, last-first+1);
+}
+
+
+sc_string_old sc_string_old::make_str(long n) // convert integer to string
+{
+ char buf[32];
+ ::std::sprintf(buf,"%ld",n);
+ return sc_string_old(buf);
+}
+
+
+#define DEFINE_RELOP(op) \
+bool sc_string_old::operator op( const char* s ) const \
+{ \
+ return strcmp( rep->str, s ) op 0; \
+} \
+bool sc_string_old::operator op( const sc_string_old& s ) const \
+{ \
+ return strcmp( rep->str, s.rep->str ) op 0; \
+}
+
+DEFINE_RELOP(==)
+DEFINE_RELOP(!=)
+DEFINE_RELOP(<)
+DEFINE_RELOP(<=)
+DEFINE_RELOP(>)
+DEFINE_RELOP(>=)
+
+sc_string_old::operator const char*() const
+{
+ return rep->str;
+}
+
+char
+sc_string_old::operator[]( int i ) const
+{
+ return rep->str[i];
+}
+
+char& sc_string_old::operator[]( int i )
+{
+ if (rep->ref_count > 1) {
+ rep->ref_count--;
+ rep = new sc_string_rep(rep->str);
+ }
+ return rep->str[i];
+}
+
+void
+sc_string_old::set( int i, char c )
+{
+ if (rep->ref_count > 1) {
+ rep->ref_count--;
+ rep = new sc_string_rep(rep->str);
+ }
+ rep->str[i] = c;
+}
+
+#if defined(_MSC_VER)
+ // Windows provides safer implementation
+# define sc_vsnprintf _vsnprintf
+#else
+# define sc_vsnprintf vsnprintf
+#endif
+
+sc_string_old sc_string_old::to_string(const char* format, ...)
+{
+ va_list argptr;
+ sc_string_old result;
+ char buffer[1024]; // static string buffer
+ buffer[1023]=000;
+
+ va_start(argptr, format);
+ int cnt = sc_vsnprintf(buffer, 1024, format, argptr);
+ if(cnt>1023) // string too long
+ {
+ int buf_size = 1024;
+ const int max_size = 65000;
+ char* buf = 0; // dynamic string buffer
+ do
+ {
+ delete[] buf;
+ buf_size*=2;
+ buf = new char[buf_size];
+ cnt = sc_vsnprintf(buf, buf_size, format, argptr);
+ }
+ while( buf_size<max_size && cnt>=buf_size);
+ if(cnt>=buf_size)
+ {
+ // string is longer the the maximum buffer size (max_size)
+ SC_REPORT_WARNING( sc_core::SC_ID_STRING_TOO_LONG_, "truncated" );
+ buf[buf_size-1] = 000;
+ }
+ result = buf;
+ delete[] buf;
+ }
+ else
+ result = buffer;
+
+ va_end(argptr);
+
+ return result;
+}
+
+void
+sc_string_old::print( ::std::ostream& os ) const
+{
+ os << rep->str;
+}
+
+void sc_string_old::test(int position)const
+{
+ if(position<0 || position>=length())
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, "sc_string_old::test" );
+}
+
+// TODO: conveniece formatting functions for common types
+// e.g. sc_string_old("a=%d, s is %s").fmt(1).fmt("string")
+// should produce a=1, s is string
+// it should be safe: if less arguments specified
+// it should print %specifier; extra arguments should be ignored
+// if the type of the argument is incompatible with format
+// specifier it should be ignored
+//
+
+unsigned
+sc_string_old::fmt_length()const
+{
+ unsigned result=0;
+ if((*this)[0]!='%')
+ return 0;
+ else
+ result++;
+ if(is_delimiter("-+0 #",result)) // flags
+ result++;
+ while(is_delimiter("0123456789*",result)) // width
+ result++;
+ if(rep->str[result]=='.') // precision
+ {
+ result++;
+ unsigned old_result = result;
+ while(is_delimiter("0123456789*",result)) result++;
+ if(old_result == result) //error in format
+ return 0;
+ }
+ if(is_delimiter("hlL",result)) result++; // I64 is not supported
+ if(is_delimiter("cCdiouxXeEfgGnpsS",result))
+ result++;
+ else // error in format
+ return 0;
+ return result;
+}
+
+sc_string_old&
+sc_string_old::fmt(const sc_string_old& s)
+{
+ return fmt(s.c_str());
+}
+
+int
+sc_string_old::pos( const sc_string_old& sub_string ) const
+{
+ int sub_len = sub_string.length();
+ if( sub_len == 0 ) {
+ return 0; // empty string always matches
+ }
+ int ind = 0;
+ int len = length();
+ bool found = false;
+ while( ind < len && ! found )
+ {
+ found = ( sub_string == substr( ind, ind + sub_len - 1 ) );
+ ++ ind;
+ }
+ if( found ) {
+ return -- ind;
+ } else {
+ return -1;
+ }
+}
+
+sc_string_old&
+sc_string_old::remove(unsigned index, unsigned length)
+{
+ test((int)index);
+ if(length!=0)
+ (*this) = substr(0,index-1) + substr(index+length,this->length()-1);
+ return *this;
+}
+
+sc_string_old&
+sc_string_old::insert(const sc_string_old& sub_string, unsigned index)
+{
+ if(index>(unsigned)length())
+ SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, "sc_string_old::insert" );
+ return (*this) = substr(0,index-1)+sub_string+substr(index,length()-1);
+}
+
+bool
+sc_string_old::is_delimiter(const sc_string_old& str, unsigned index)const
+{
+ test((int)index);
+ return str.contains(rep->str[index]);
+}
+
+bool
+sc_string_old::contains(char c)const
+{
+ int len = length();
+ int i=0;
+ bool found = false;
+ while(!found && i<len)
+ found = rep->str[i++]==c;
+ return found;
+}
+
+sc_string_old
+sc_string_old::uppercase()const
+{
+ int len = length();
+ sc_string_old temp(*this);
+ for(int i=0; i<len; i++)
+ {
+ char c = temp.rep->str[i];
+ if(c>='a' && c<='z')
+ temp.rep->str[i] = static_cast<char>( c-32 );
+ }
+ return temp;
+}
+
+sc_string_old
+sc_string_old::lowercase()const
+{
+ int len = length();
+ sc_string_old temp(*this);
+ for(int i=0; i<len; i++)
+ {
+ char c = temp.rep->str[i];
+ if(c>='A' && c<='Z')
+ temp.rep->str[i] = static_cast<char>( c+32 );
+ }
+ return temp;
+}
+
+
+// ----------------------------------------------------------------------------
+
+::std::istream&
+operator >> ( ::std::istream& is, sc_string_old& s )
+{
+ if( s.rep->ref_count > 1 ) {
+ -- s.rep->ref_count;
+ s.rep = new sc_string_rep;
+ }
+
+ int i = 0;
+ char* p = s.rep->str;
+ char c;
+
+ // skip white spaces
+ while( is.get( c ) && isspace( c ) )
+ ;
+
+ for( ; is.good() && ! isspace( c ); is.get( c ) ) {
+ if( i > s.rep->alloc - 2 ) {
+ s.rep->str[i] = '\0';
+ s.rep->resize( (int) (s.rep->alloc * 1.5) );
+ p = s.rep->str + i;
+ }
+ *p ++ = c;
+ i ++;
+ }
+ *p = '\0';
+
+ return is;
+}
+ } // namespace sc_dt
+
+// $Log: sc_string.cpp,v $
+// Revision 1.6 2011/08/29 18:04:32 acg
+// Philipp A. Hartmann: miscellaneous clean ups.
+//
+// Revision 1.5 2011/08/26 22:49:42 acg
+// Torsten Maehne: remove redudant assignment.
+//
+// Revision 1.4 2011/08/26 20:46:19 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.3 2011/08/24 22:05:56 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.2 2011/02/18 20:38:44 acg
+// Andy Goodrich: Updated Copyright notice.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:06 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:11 acg
+// Andy Goodrich: Added $Log command so that CVS comments are reproduced in
+// the source.
+
+// taf
diff --git a/ext/systemc/src/sysc/utils/sc_string.h b/ext/systemc/src/sysc/utils/sc_string.h
new file mode 100644
index 000000000..cf225ef1e
--- /dev/null
+++ b/ext/systemc/src/sysc/utils/sc_string.h
@@ -0,0 +1,254 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_string.h -- Implementation of a simple string class.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+// $Log: sc_string.h,v $
+// Revision 1.3 2011/08/26 20:46:19 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+#ifndef SC_STRING_H
+#define SC_STRING_H
+
+
+#include "sysc/utils/sc_iostream.h"
+#include "sysc/utils/sc_report.h"
+
+namespace sc_dt {
+ class sc_string_old;
+}
+
+#ifdef SC_USE_SC_STRING_OLD
+ typedef sc_dt::sc_string_old sc_string;
+#endif
+#ifdef SC_USE_STD_STRING
+ typedef ::std::string sc_string;
+#endif
+
+namespace sc_dt {
+
+// forward class declarations
+class sc_string_rep;
+
+// friend operator declarations
+sc_string_old operator + ( const char* s, const sc_string_old& t );
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_string
+//
+// String class (yet another).
+// ----------------------------------------------------------------------------
+
+class sc_string_old
+{
+ friend systemc_ostream& operator << (systemc_ostream& os, const sc_string_old& a);
+ friend systemc_istream& operator >> ( systemc_istream& is, sc_string_old& a );
+
+public:
+
+ // constructors
+
+ explicit sc_string_old( int size = 16 );
+ sc_string_old( const char* s );
+ sc_string_old( const char* s, int n ); // get first n chars from the string
+ sc_string_old( const sc_string_old& s );
+
+
+ // destructor
+
+ ~sc_string_old();
+
+
+ // concatenation and assignment
+
+ sc_string_old& operator = ( const char* s );
+ sc_string_old& operator = ( const sc_string_old& s );
+
+ sc_string_old& operator += ( const char* s );
+ sc_string_old& operator += ( char c );
+ sc_string_old& operator += ( const sc_string_old& s );
+
+ sc_string_old operator + ( const char* s ) const;
+ sc_string_old operator + ( char c ) const;
+ sc_string_old operator + ( const sc_string_old& s ) const;
+
+ friend sc_string_old operator + ( const char* s, const sc_string_old& t );
+
+
+ // returns substring [first,last]
+
+ sc_string_old substr( int first, int last ) const;
+
+
+ // string comparison operators
+
+ bool operator == ( const char* s ) const;
+ bool operator != ( const char* s ) const;
+ bool operator < ( const char* s ) const;
+ bool operator <= ( const char* s ) const;
+ bool operator > ( const char* s ) const;
+ bool operator >= ( const char* s ) const;
+ bool operator == ( const sc_string_old& s ) const;
+ bool operator != ( const sc_string_old& s ) const;
+ bool operator < ( const sc_string_old& s ) const;
+ bool operator <= ( const sc_string_old& s ) const;
+ bool operator > ( const sc_string_old& s ) const;
+ bool operator >= ( const sc_string_old& s ) const;
+
+ //
+ // returns length of the string (excluding trailing \0)
+ //
+ int length() const;
+
+ //
+ // returns c-style string
+ //
+ const char* c_str() const;
+ //
+ // returns c-style string
+ //
+ operator const char*() const;
+ //
+ // returns character at "index" position
+ //
+ char operator[](int index) const;
+ //
+ // l-value subscript
+ //
+ char& operator[](int index);
+
+ // formatted string (see printf description)
+ static sc_string_old to_string(const char* format, ...);
+ //
+ // conveniece formatting functions for common types
+ // e.g. sc_string_old("a=%d, s is %s").fmt(1).fmt("string")
+ // should produce: a=1, s is string
+ // it should be safe: if less arguments specified
+ // it should print %specifier; extra arguments should be ignored
+ // TODO: if the type of the argument is incompatible with format
+ // specifier it should be ignored
+ //
+ // must have it inlined because of some compilers
+ template<class T> sc_string_old& fmt(const T& t)
+ {
+ // search %
+ int index;
+ int last_char = length()-1;
+ sc_string_old temp(*this);
+ do
+ {
+ index = temp.pos("%");
+ if(index == last_char)
+ return *this;
+ temp = substr(index,last_char);
+ } while(temp[0] != '%');
+ int f_len = (int)temp.fmt_length(); // length of format field
+ temp = to_string(substr(0,index+f_len-1).c_str(),t);
+ return (*this) = temp + substr(index+f_len,last_char);
+ }
+ sc_string_old& fmt(const sc_string_old& s);
+ //
+ // find position of substring in this string
+ // returns -1 if not found
+ //
+ int pos(const sc_string_old& sub_string)const;
+ //
+ // remove "count" characters from "index"
+ //
+ sc_string_old& remove(unsigned index, unsigned length);
+ //
+ // insert "substring" before "index"
+ //
+ sc_string_old& insert(const sc_string_old& sub_string, unsigned index);
+ //
+ // returns true if the character at byte index in this string matches
+ // any character in the delimiters string
+ //
+ bool is_delimiter(const sc_string_old& str, unsigned index)const;
+ //
+ // returns true if string contains the character
+ //
+ bool contains(char c)const;
+ //
+ // produce upper case string from this one
+ //
+ sc_string_old uppercase()const;
+ //
+ // produce lower case string from this one
+ //
+ sc_string_old lowercase()const;
+ //
+ // legacy methods
+ //
+ static sc_string_old make_str(long n);
+ void set( int index, char c );
+ int cmp( const char* s ) const;
+ int cmp( const sc_string_old& s ) const;
+
+
+ void print( systemc_ostream& os = ::std::cout ) const;
+
+private:
+
+ sc_string_old( sc_string_rep* r );
+
+ sc_string_rep* rep;
+
+ void test(int position)const;
+ unsigned fmt_length()const;
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+inline
+systemc_ostream&
+operator << ( systemc_ostream& os, const sc_string_old& a )
+{
+ a.print( os );
+ return os;
+}
+
+} // namespace sc_dt
+
+// Revision 1.2 2011/02/18 20:38:44 acg
+// Andy Goodrich: Updated Copyright notice.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:06 acg
+// SystemC 2.3
+//
+// Revision 1.4 2006/05/08 17:50:51 acg
+// Andy Goodrich: added David Long's forward declarations for friend
+// functions, methods, and operators to keep the Microsoft compiler happy.
+//
+// Revision 1.3 2006/01/13 18:53:11 acg
+// Andy Goodrich: Added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#endif
diff --git a/ext/systemc/src/sysc/utils/sc_temporary.h b/ext/systemc/src/sysc/utils/sc_temporary.h
new file mode 100644
index 000000000..321994aad
--- /dev/null
+++ b/ext/systemc/src/sysc/utils/sc_temporary.h
@@ -0,0 +1,228 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_temporary.h -- Temporary value pool classes.
+
+ Original Author: Andy Goodrich, Forte Design Systems, Inc.
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+#ifndef SC_TEMPORARY_H
+#define SC_TEMPORARY_H
+
+#include <cstddef> // std::size_t
+
+namespace sc_core {
+
+//------------------------------------------------------------------------------
+// sc_byte_heap - CLASS MANAGING A TEMPORARY HEAP OF BYTES
+//
+// This facility implements a heap of temporary byte allocations. Once an
+// request has been allocated it is not freed. However the entire heap
+// wraps and the storage is reused. This means that no allocations should
+// be assumed as permanent. Allocations are double-word aligned. This is
+// raw storage, so objects which contain virtual methods cannot be allocated
+// with this object. See the sc_vpool object for that type of storage
+// allocation.
+//
+// char* allocate( int size )
+// This method returns a pointer to block of size bytes. The block
+// returned is the next available one in the heap. If the current heap
+// cannot fullfil the request it will be rewound and storage allocated from
+// its start. All allocations start on an 8-byte boundary.
+// size = number of bytes to be allocated.
+//
+// void initialize( int heap_size=0x100000 )
+// This method allocates the storage to be managed. If there is already
+// a block of storage under management it is freed. If no argument is
+// provided for the heap size, a megabyte will be allocated.
+// heap_size = number of bytes to allocate for the heap.
+//
+// unsigned int length()
+// This method returns the size of this object's heap in bytes.
+//
+// sc_byte_heap()
+// This is the non-initialized object instance constructor. It does not
+// allocate the heap storage, that is done by the initialize() method.
+//
+// sc_byte_heap(int)
+// This is the initializing object instance constructor. It does allocates
+// a heap of the specified number of bytes.
+// heap_size = number of bytes to allocate for the heap.
+//------------------------------------------------------------------------------
+class sc_byte_heap {
+ public:
+ char* m_bgn_p; // Beginning of heap storage.
+ char* m_end_p; // End of heap storage.
+ char* m_next_p; // Next heap location to be allocated.
+
+ inline char* allocate( std::size_t bytes_n )
+ {
+ char* result_p;
+ bytes_n = (bytes_n + 7) & ((std::size_t)(-8));
+ result_p = m_next_p;
+ m_next_p += bytes_n;
+ if ( m_next_p >= m_end_p )
+ {
+ result_p = m_bgn_p;
+ m_next_p = m_bgn_p + bytes_n;
+ }
+ return result_p;
+ }
+
+ inline void initialize( std::size_t heap_size=0x100000 )
+ {
+ delete [] m_bgn_p;
+ m_bgn_p = new char[heap_size];
+ m_end_p = &m_bgn_p[heap_size];
+ m_next_p = m_bgn_p;
+ }
+
+ inline std::size_t length()
+ {
+ return (std::size_t)(m_end_p - m_bgn_p);
+ }
+
+ inline sc_byte_heap() :
+ m_bgn_p(0), m_end_p(0), m_next_p(0)
+ {
+ }
+
+ inline sc_byte_heap( std::size_t heap_size ) :
+ m_bgn_p(0), m_end_p(0), m_next_p(0)
+ {
+ initialize( heap_size );
+ }
+
+ inline ~sc_byte_heap()
+ {
+ delete [] m_bgn_p;
+ }
+
+};
+
+
+//------------------------------------------------------------------------------
+// sc_vpool<T> - CLASS MANAGING A TEMPORARY VECTOR OF CLASS T INSTANCES
+//
+// This class implements a fixed pool of objects contained in a vector. These
+// objects are allocated via the allocate() method. An index, m_pool_i,
+// indicates the next object to be allocated. The vector is a power of 2 in
+// size, and this fact is used to wrap the list when m_pool_i reaches the
+// end of the vector.
+//
+// sc_vpool( int log2, T* pool_p=0 )
+// This is the object instance constructor for this class. It configures
+// the object to manage a vector of 2**log2 entries. If a vector is
+// not supplied one will be allocated.
+// log2 = the log base two of the size of the vector.
+// pool_p -> vector of 2**log2 entries to be managed or 0.
+//
+// ~sc_vpool()
+// This is the object instance destructor for this class. It frees the
+// block of storage which was being managed.
+//
+// T* allocate()
+// This method returns the address of the next entry in the vector, m_pool_p,
+// pointed to by the index, m_pool_i, and updates that index. The index
+// update consists of adding 1 to m_pool_i and masking it by m_wrap.
+//
+// void reset()
+// This method resets the allocation index, m_pool_i, to point to the start
+// of the vector of objects under management. This call is not usually made
+// since there are a fixed number of entries and the index wraps. However,
+// for diagnostics tests it is convenient to be able to reset to the start
+// of the vector.
+//
+// int size()
+// This method returns the number of object instances contained in the
+// vector being managed by this object instance.
+//------------------------------------------------------------------------------
+template<class T>
+class sc_vpool {
+ protected:
+ std::size_t m_pool_i; // Index of next entry to m_pool_m to provide.
+ T* m_pool_p; // Vector of temporaries.
+ std::size_t m_wrap; // Mask to wrap vector index.
+
+ public:
+ inline sc_vpool( int log2, T* pool_p=0 );
+ inline ~sc_vpool();
+ inline T* allocate();
+ inline void reset();
+ inline std::size_t size();
+};
+
+template<class T> sc_vpool<T>::sc_vpool( int log2, T* pool_p )
+ : m_pool_i( 0 )
+ , m_pool_p( pool_p ? pool_p : new T[static_cast<std::size_t>(1) << log2] )
+ , m_wrap( ~(static_cast<std::size_t>(-1) << log2) )
+{
+ // if ( log2 > 32 ) SC_REPORT_ERROR(SC_ID_POOL_SIZE_, "");
+}
+
+template<class T> sc_vpool<T>::~sc_vpool()
+{
+ // delete [] m_pool_p;
+}
+
+template<class T> T* sc_vpool<T>::allocate()
+{
+ T* result_p; // Entry to return.
+
+ result_p = &m_pool_p[m_pool_i];
+ m_pool_i = (m_pool_i + 1) & m_wrap;
+ return result_p;
+}
+
+template<class T> void sc_vpool<T>::reset()
+{
+ m_pool_i = 0;
+}
+
+template<class T> std::size_t sc_vpool<T>::size()
+{
+ return m_wrap + 1;
+}
+
+} // namespace sc_core
+
+// $Log: sc_temporary.h,v $
+// Revision 1.4 2011/08/26 20:46:19 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.3 2011/08/24 22:05:56 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.2 2011/02/18 20:38:44 acg
+// Andy Goodrich: Updated Copyright notice.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:06 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:53:11 acg
+// Andy Goodrich: Added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#endif // SC_TEMPORARY_H
diff --git a/ext/systemc/src/sysc/utils/sc_utils_ids.cpp b/ext/systemc/src/sysc/utils/sc_utils_ids.cpp
new file mode 100644
index 000000000..3492692b3
--- /dev/null
+++ b/ext/systemc/src/sysc/utils/sc_utils_ids.cpp
@@ -0,0 +1,147 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_utils_ids.cpp -- Report ids for the utils code.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2002-01-17
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+
+#include <cstdlib>
+#include <cstring>
+
+#include "sysc/utils/sc_report.h"
+
+
+namespace sc_core {
+#define SC_DEFINE_MESSAGE(id,unused,text) extern const char id[] = text;
+#include "sysc/utils/sc_utils_ids.h"
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/communication/sc_communication_ids.h"
+#include "sysc/datatypes/bit/sc_bit_ids.h"
+#include "sysc/datatypes/fx/sc_fx_ids.h"
+#include "sysc/datatypes/int/sc_int_ids.h"
+#include "sysc/tracing/sc_tracing_ids.h"
+#undef SC_DEFINE_MESSAGE
+
+
+static sc_msg_def texts[] = {
+#define SC_DEFINE_MESSAGE(id,n,unused) \
+ { (id), 0u, {0u}, 0u, {0u}, 0u, 0u, {0u}, 0, n },
+
+#undef SC_UTILS_IDS_H
+#include "sysc/utils/sc_utils_ids.h"
+
+#undef SC_KERNEL_IDS_H
+#include "sysc/kernel/sc_kernel_ids.h"
+
+#undef SC_COMMUNICATION_IDS_H
+#include "sysc/communication/sc_communication_ids.h"
+
+#undef SC_BIT_IDS_H
+#include "sysc/datatypes/bit/sc_bit_ids.h"
+
+#undef SC_FX_IDS_H
+#include "sysc/datatypes/fx/sc_fx_ids.h"
+
+#undef SC_INT_IDS_H
+#include "sysc/datatypes/int/sc_int_ids.h"
+
+#undef SC_TRACING_IDS_H
+#include "sysc/tracing/sc_tracing_ids.h"
+
+#undef SC_DEFINE_MESSAGE
+};
+static sc_report_handler::msg_def_items items = {
+ texts, sizeof(texts)/sizeof(*texts), false, 0
+};
+
+static
+int initialize()
+{
+ sc_report_handler::add_static_msg_types(&items);
+
+ // PROCESS ANY ENVIRONMENTAL OVERRIDES:
+
+ const char* deprecation_warn = std::getenv("SC_DEPRECATION_WARNINGS");
+ if ( (deprecation_warn!=0) && !std::strcmp(deprecation_warn,"DISABLE") )
+ {
+ sc_report_handler::set_actions( SC_ID_IEEE_1666_DEPRECATION_
+ , SC_DO_NOTHING);
+ }
+ return 42;
+}
+
+static int forty_two = initialize();
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ Alex Riesen, Synopsys, Inc., 2003-02-02
+ ported to SystemC 2.1 exception reporting.
+
+ *****************************************************************************/
+
+
+// $Log: sc_utils_ids.cpp,v $
+// Revision 1.5 2011/08/26 20:46:19 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.4 2011/02/18 20:38:44 acg
+// Andy Goodrich: Updated Copyright notice.
+//
+// Revision 1.3 2009/02/28 00:27:57 acg
+// Andy Goodrich: includes for C++ library types to keep compiler happy.
+//
+// Revision 1.2 2008/05/20 20:43:21 acg
+// Andy Goodrich: Added includes <cstdlib> and <cstring> to pick up their
+// declarations.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:06 acg
+// SystemC 2.3
+//
+// Revision 1.6 2006/01/31 21:42:07 acg
+// Andy Goodrich: Added checks for SC_DEPRECATED_WARNINGS being defined as
+// DISABLED. If so, we turn off the /IEEE_Std_1666/deprecated message group.
+//
+// Revision 1.5 2006/01/24 21:59:59 acg
+// Andy Goodrich: removed sc_trace_ids.h since its only message has been
+// replaced by SC_ID_IEEE_1666_DEPRECATION_ message.
+//
+// Revision 1.4 2006/01/24 20:53:41 acg
+// Andy Goodrich: added warnings indicating that use of integer ids in reports
+// is deprecated. Added tracing/sc_trace_ids.h to message list.
+//
+// Revision 1.3 2006/01/13 18:53:11 acg
+// Andy Goodrich: Added $Log command so that CVS comments are reproduced in
+// the source.
+
+// Taf!
diff --git a/ext/systemc/src/sysc/utils/sc_utils_ids.h b/ext/systemc/src/sysc/utils/sc_utils_ids.h
new file mode 100644
index 000000000..811878280
--- /dev/null
+++ b/ext/systemc/src/sysc/utils/sc_utils_ids.h
@@ -0,0 +1,113 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_utils_ids.h -- Report ids for the utils code.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2002-01-17
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+#ifndef SC_UTILS_IDS_H
+#define SC_UTILS_IDS_H
+
+// ----------------------------------------------------------------------------
+// Report ids (utils)
+//
+// Report ids in the range of 800-899.
+// ----------------------------------------------------------------------------
+
+#ifndef SC_DEFINE_MESSAGE
+#define SC_DEFINE_MESSAGE(id,unused1,unused2) \
+ namespace sc_core { extern const char id[]; }
+namespace sc_core {
+ extern const char SC_ID_REGISTER_ID_FAILED_[]; // in sc_report_handler.cpp
+}
+#endif
+
+SC_DEFINE_MESSAGE(SC_ID_STRING_TOO_LONG_,
+ 801, "string is too long")
+SC_DEFINE_MESSAGE(SC_ID_FRONT_ON_EMPTY_LIST_,
+ 802, "attempt to take front() on an empty list")
+SC_DEFINE_MESSAGE(SC_ID_BACK_ON_EMPTY_LIST_,
+ 803, "attempt to take back() on an empty list")
+SC_DEFINE_MESSAGE(SC_ID_IEEE_1666_DEPRECATION_,
+ 804, "/IEEE_Std_1666/deprecated" )
+SC_DEFINE_MESSAGE(SC_ID_VECTOR_INIT_CALLED_TWICE_,
+ 805, "sc_vector::init has already been called" )
+SC_DEFINE_MESSAGE(SC_ID_VECTOR_INIT_INVALID_CONTEXT_,
+ 806, "sc_vector::init called from invalid object context" )
+SC_DEFINE_MESSAGE(SC_ID_VECTOR_BIND_EMPTY_,
+ 807, "sc_vector::bind called with empty range" )
+SC_DEFINE_MESSAGE(SC_ID_VECTOR_NONOBJECT_ELEMENTS_,
+ 808, "sc_vector::get_elements called for element type "
+ "not derived from sc_object" )
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ Alex Riesen, Synopsys, Inc., 2003-02-02
+ ported to SystemC 2.1 exception reporting.
+
+ *****************************************************************************/
+
+// $Log: sc_utils_ids.h,v $
+// Revision 1.5 2011/08/26 20:46:20 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.4 2011/02/18 20:38:44 acg
+// Andy Goodrich: Updated Copyright notice.
+//
+// Revision 1.3 2011/02/14 17:54:25 acg
+// Andy Goodrich: Philipp's addition of early bind checks.
+//
+// Revision 1.2 2010/12/07 20:10:19 acg
+// Andy Goodrich: messages for new sc_vector class.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:06 acg
+// SystemC 2.3
+//
+// Revision 1.6 2006/01/25 00:31:27 acg
+// Andy Goodrich: Changed over to use a standard message id of
+// SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
+//
+// Revision 1.5 2006/01/24 22:01:35 acg
+// Andy Goodrich: consolidated all IEEE 1666 compliance messages to use the
+// SC_ID_IEEE_1666_DEPRECATION_ message type.
+//
+// Revision 1.4 2006/01/24 20:53:41 acg
+// Andy Goodrich: added warnings indicating that use of integer ids in reports
+// is deprecated. Added tracing/sc_trace_ids.h to message list.
+//
+// Revision 1.3 2006/01/13 18:53:11 acg
+// Andy Goodrich: Added $Log command so that CVS comments are reproduced in
+// the source.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/utils/sc_vector.cpp b/ext/systemc/src/sysc/utils/sc_vector.cpp
new file mode 100644
index 000000000..e42fba02e
--- /dev/null
+++ b/ext/systemc/src/sysc/utils/sc_vector.cpp
@@ -0,0 +1,178 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_vector.cpp - A vector of named (SystemC) objects (modules, ports, channels)
+
+ Original Author: Philipp A. Hartmann, OFFIS
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+
+#include "sc_vector.h"
+
+#include "sysc/utils/sc_hash.h"
+#include "sysc/utils/sc_list.h"
+#include "sysc/utils/sc_utils_ids.h"
+
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_object_manager.h"
+
+#include <sstream>
+
+namespace sc_core {
+
+sc_vector_base::sc_vector_base()
+ : sc_object( sc_gen_unique_name("vector") )
+ , vec_()
+ , objs_vec_()
+{}
+
+std::vector< sc_object* > const &
+sc_vector_base::get_elements() const
+{
+ if( !objs_vec_ )
+ objs_vec_ = new std::vector< sc_object* >;
+
+ if( objs_vec_->size() || !size() )
+ return *objs_vec_;
+
+ objs_vec_->reserve( size() );
+ for( const_iterator it=begin(); it != end(); ++it )
+ if( sc_object* obj = object_cast(*it) )
+ objs_vec_->push_back( obj );
+
+ return *objs_vec_;
+}
+
+sc_object*
+sc_vector_base::implicit_cast( ... ) const
+{
+ SC_REPORT_ERROR( SC_ID_VECTOR_NONOBJECT_ELEMENTS_, name() );
+ return NULL;
+}
+
+void
+sc_vector_base::check_index( size_type i ) const
+{
+ if( i>=size() )
+ {
+ std::stringstream str;
+ str << name()
+ << "[" << i << "] >= size() = " << size();
+ SC_REPORT_ERROR( SC_ID_OUT_OF_BOUNDS_, str.str().c_str() );
+ }
+}
+
+bool
+sc_vector_base::check_init( size_type n ) const
+{
+ if ( !n )
+ return false;
+
+ if( size() ) // already filled
+ {
+ std::stringstream str;
+ str << name()
+ << ", size=" << size()
+ << ", requested size=" << n;
+ SC_REPORT_ERROR( SC_ID_VECTOR_INIT_CALLED_TWICE_
+ , str.str().c_str() );
+ return false;
+ }
+
+ sc_simcontext* simc = simcontext();
+ sc_assert( simc == sc_get_curr_simcontext() );
+
+ sc_object* parent_p = simc->active_object();
+ if( parent_p != get_parent_object() )
+ {
+ std::stringstream str;
+ str << name() << ": expected "
+ << ( get_parent_object()
+ ? get_parent_object()->name() : "<top-level>" )
+ << ", got "
+ << ( parent_p ? parent_p->name() : "<top-level>" );
+
+ SC_REPORT_ERROR( SC_ID_VECTOR_INIT_INVALID_CONTEXT_
+ , str.str().c_str() );
+ return false;
+ }
+
+ return true;
+}
+
+void
+sc_vector_base::report_empty_bind( const char* kind_, bool dst_empty_ ) const
+{
+ std::stringstream str;
+
+ str << "target `" << name() << "' "
+ << "(" << kind_ << ") ";
+
+ if( !size() ) {
+ str << "not initialised yet";
+ } else if ( dst_empty_ ) {
+ str << "empty range given";
+ } else {
+ str << "empty destination range given";
+ }
+
+ SC_REPORT_WARNING( SC_ID_VECTOR_BIND_EMPTY_, str.str().c_str() );
+}
+
+std::string
+sc_vector_base::make_name( const char* prefix, size_type /* idx */ )
+{
+ // TODO: How to handle name clashes due to interleaved vector
+ // creation and init()?
+ // sc_vector< foo > v1, v2;
+ // v1.name() == "vector", v2.name() == "vector_0"
+ // v1.init( 1 ); -> v1[0].name() == "vector_0" -> clash
+ return sc_gen_unique_name( prefix );
+}
+
+} // namespace sc_core
+
+// $Log: sc_vector.cpp,v $
+// Revision 1.6 2011/08/26 20:46:20 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.5 2011/04/01 22:35:19 acg
+// Andy Goodrich: spelling fix.
+//
+// Revision 1.4 2011/03/28 13:03:09 acg
+// Andy Goodrich: Philipp's latest update.
+//
+// Revision 1.3 2011/03/23 16:16:28 acg
+// Philipp A. Hartmann: rebase implementation on void*
+// - supports virtual inheritance from sc_object again
+// - build up get_elements result on demand
+// - still requires element type to be derived from sc_object
+//
+// Revision 1.2 2011/02/14 17:54:25 acg
+// Andy Goodrich: Philipp's addition of early bind checks.
+//
+// Revision 1.1 2011/02/13 21:54:14 acg
+// Andy Goodrich: turn on embedding of cvs log records.
+
+// Taf!
diff --git a/ext/systemc/src/sysc/utils/sc_vector.h b/ext/systemc/src/sysc/utils/sc_vector.h
new file mode 100644
index 000000000..2afbaf45e
--- /dev/null
+++ b/ext/systemc/src/sysc/utils/sc_vector.h
@@ -0,0 +1,724 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_vector.h - A vector of named (SystemC) objects (modules, ports, channels)
+
+ Original Author: Philipp A. Hartmann, OFFIS
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+#ifndef SC_VECTOR_H_INCLUDED_
+#define SC_VECTOR_H_INCLUDED_
+
+#include <vector>
+#include <iterator>
+#include <string>
+#include <algorithm> // std::swap
+
+#include "sysc/kernel/sc_object.h"
+#include <type_traits>
+
+//#define SC_VECTOR_HEADER_ONLY_
+
+namespace sc_core {
+namespace sc_meta {
+
+ using ::std::enable_if;
+ using ::std::remove_const;
+ using ::std::is_same;
+ using ::std::is_const;
+
+ template< typename CT, typename T >
+ struct is_more_const {
+ static constexpr bool value
+ = ( is_same< typename remove_const<CT>::type
+ , typename remove_const<T>::type
+ >::value
+ && ( is_const<CT>::value >= is_const<T>::value ) );
+ };
+
+} // namespace sc_meta
+
+// forward declarations
+template< typename T > class sc_vector;
+template< typename T, typename MT > class sc_vector_assembly;
+template< typename T, typename MT > class sc_vector_iter;
+
+// implementation-defined
+template< typename Container, typename ArgumentIterator >
+typename Container::iterator
+sc_vector_do_bind( Container & cont
+ , ArgumentIterator first
+ , ArgumentIterator last
+ , typename Container::iterator from );
+
+// implementation-defined
+template< typename Container, typename ArgumentIterator >
+typename Container::iterator
+sc_vector_do_operator_paren( Container & cont
+ , ArgumentIterator first
+ , ArgumentIterator last
+ , typename Container::iterator from );
+
+class sc_vector_base
+ : public sc_object
+{
+
+ template<typename,typename> friend class sc_vector_assembly;
+ template<typename,typename> friend class sc_vector_iter;
+
+public:
+
+ typedef std::vector< void* > storage_type;
+ typedef storage_type::size_type size_type;
+ typedef storage_type::difference_type difference_type;
+
+ const char * kind() const { return "sc_vector"; }
+
+ std::vector<sc_object*> const & get_elements() const;
+
+ size_type size() const
+ { return vec_.size(); }
+
+protected:
+
+ // begin implementation defined
+
+ typedef storage_type::iterator iterator;
+ typedef storage_type::const_iterator const_iterator;
+
+ sc_vector_base();
+
+ sc_vector_base( const char* prefix )
+ : sc_object( prefix )
+ , vec_()
+ , objs_vec_(0)
+ {}
+
+ ~sc_vector_base()
+ { delete objs_vec_; }
+
+ void * & at( size_type i )
+ { return vec_[i]; }
+
+ void const * at( size_type i ) const
+ { return vec_[i]; }
+
+ void reserve( size_type n )
+ { vec_.reserve(n); }
+
+ void clear()
+ { vec_.clear(); }
+
+ void push_back( void* item )
+ { vec_.push_back(item); }
+
+ void check_index( size_type i ) const;
+ bool check_init( size_type n ) const;
+
+ static std::string make_name( const char* prefix, size_type index );
+
+ iterator begin() { return vec_.begin(); }
+ iterator end() { return vec_.end(); }
+
+ const_iterator begin() const { return vec_.begin(); }
+ const_iterator end() const { return vec_.end(); }
+
+ virtual sc_object* object_cast( void* ) const = 0;
+
+ sc_object* implicit_cast( sc_object* p ) const { return p; }
+ sc_object* implicit_cast( ... /* incompatible */ ) const;
+
+public:
+
+ void report_empty_bind( const char* kind_, bool dst_range_ ) const;
+
+private:
+ storage_type vec_;
+ mutable std::vector< sc_object* >* objs_vec_;
+
+ // disabled
+ sc_vector_base( const sc_vector_base& );
+ sc_vector_base& operator=( const sc_vector_base& );
+
+}; // sc_vector_base
+
+// iterator access adapters
+template< typename ElementType >
+struct sc_direct_access
+{
+ typedef ElementType element_type;
+ typedef element_type type;
+ typedef typename sc_meta::remove_const<type>::type plain_type;
+
+ typedef sc_direct_access< type > policy;
+ typedef sc_direct_access< plain_type > non_const_policy;
+ typedef sc_direct_access< const plain_type > const_policy;
+
+ sc_direct_access(){}
+ sc_direct_access( const non_const_policy& ) {}
+ // convert from any policy to (const) direct policy
+ template <typename U>
+ sc_direct_access(const U&,
+ typename sc_meta::enable_if<sc_meta::is_more_const<
+ type,
+ typename U::policy::element_type>::value>::type* = NULL)
+ {}
+
+ type* get( type* this_ ) const
+ { return this_; }
+};
+
+// iterator access adapters
+template< typename ElementType
+ , typename AccessType >
+class sc_member_access
+{
+ public:
+ template< typename, typename > friend class sc_member_access;
+
+ typedef ElementType element_type;
+ typedef AccessType access_type;
+ typedef access_type (ElementType::*member_type);
+ typedef access_type type;
+ typedef typename sc_meta::remove_const<type>::type plain_type;
+ typedef typename sc_meta::remove_const<ElementType>::type plain_elem_type;
+
+ typedef sc_member_access< element_type, access_type > policy;
+ typedef sc_member_access< plain_elem_type, plain_type >
+ non_const_policy;
+ typedef sc_member_access< const plain_elem_type, const plain_type >
+ const_policy;
+
+ sc_member_access( member_type ptr )
+ : ptr_(ptr) {}
+
+ sc_member_access( const non_const_policy& other )
+ : ptr_(other.ptr_)
+ {}
+
+ access_type * get( element_type* this_ ) const
+ { return &(this_->*ptr_); }
+
+ private:
+ member_type ptr_;
+}; // sc_member_access
+
+
+template< typename ElementType
+ , typename AccessPolicy = sc_direct_access<ElementType> >
+class sc_vector_iter
+ : public std::iterator< std::random_access_iterator_tag
+ , typename AccessPolicy::type >
+ , private AccessPolicy
+{
+ typedef ElementType element_type;
+ typedef typename AccessPolicy::policy access_policy;
+ typedef typename AccessPolicy::non_const_policy non_const_policy;
+ typedef typename AccessPolicy::const_policy const_policy;
+ typedef typename access_policy::type access_type;
+
+ typedef typename sc_meta::remove_const<ElementType>::type plain_type;
+ typedef const plain_type const_plain_type;
+
+ friend class sc_vector< plain_type >;
+ template< typename, typename > friend class sc_vector_assembly;
+ template< typename, typename > friend class sc_vector_iter;
+
+ typedef std::iterator< std::random_access_iterator_tag, access_type > base_type;
+ typedef sc_vector_iter this_type;
+ typedef sc_vector<plain_type> vector_type;
+ typedef sc_vector_base::storage_type storage_type;
+
+ // select correct base-type iterator
+ template< typename U > struct select_iter
+ { typedef typename storage_type::iterator type; };
+ template< typename U > struct select_iter< const U >
+ { typedef typename storage_type::const_iterator type; };
+
+ typedef typename select_iter<ElementType>::type raw_iterator;
+ typedef sc_vector_iter< const_plain_type, const_policy > const_iterator;
+
+ // underlying vector iterator
+
+ raw_iterator it_;
+
+ sc_vector_iter( raw_iterator it, access_policy acc = access_policy() )
+ : access_policy(acc), it_(it) {}
+
+ access_policy const & get_policy() const { return *this; }
+
+public:
+ // interface for Random Access Iterator category,
+ // see ISO/IEC 14882:2003(E), 24.1 [lib.iterator.requirements]
+
+ typedef typename base_type::difference_type difference_type;
+ typedef typename base_type::reference reference;
+ typedef typename base_type::pointer pointer;
+
+ sc_vector_iter() : access_policy(), it_() {}
+
+ // iterator conversions to more const, and/or direct iterators
+ template< typename OtherElement, typename OtherPolicy >
+ sc_vector_iter( const sc_vector_iter<OtherElement, OtherPolicy>& it
+ , typename sc_meta::enable_if<sc_meta::is_more_const<
+ element_type,
+ typename OtherPolicy::element_type>::value>::type* = NULL)
+ : access_policy( it.get_policy() ), it_( it.it_ )
+ {}
+
+ // step
+ this_type& operator++(){ ++it_; return *this; }
+ this_type& operator--(){ --it_; return *this; }
+ this_type operator++(int){ this_type old(*this); ++it_; return old; }
+ this_type operator--(int){ this_type old(*this); --it_; return old; }
+
+ // advance
+ this_type operator+( difference_type n ) const
+ { return this_type( it_ + n, get_policy()); }
+ this_type operator-( difference_type n ) const
+ { return this_type( it_ - n, get_policy()); }
+
+ this_type& operator+=( difference_type n ) { it_+=n; return *this; }
+ this_type& operator-=( difference_type n ) { it_-=n; return *this; }
+
+ // relations
+ bool operator== ( const this_type& that ) const { return it_ == that.it_; }
+ bool operator!= ( const this_type& that ) const { return it_ != that.it_; }
+ bool operator<= ( const this_type& that ) const { return it_ <= that.it_; }
+ bool operator>= ( const this_type& that ) const { return it_ >= that.it_; }
+ bool operator< ( const this_type& that ) const { return it_ < that.it_; }
+ bool operator> ( const this_type& that ) const { return it_ > that.it_; }
+
+ // dereference
+ reference operator*() const
+ { return *access_policy::get( static_cast<element_type*>(*it_) ); }
+ pointer operator->() const
+ { return access_policy::get( static_cast<element_type*>(*it_) ); }
+ reference operator[]( difference_type n ) const
+ { return *access_policy::get( static_cast<element_type*>(it_[n]) ); }
+
+ // distance
+ difference_type operator-( this_type const& that ) const
+ { return it_-that.it_; }
+
+}; // sc_vector_iter
+
+template< typename T >
+class sc_vector
+ : public sc_vector_base
+{
+ typedef sc_vector_base base_type;
+ typedef sc_vector<T> this_type;
+
+public:
+ typedef T element_type;
+ typedef sc_vector_iter< element_type > iterator;
+ typedef sc_vector_iter< const element_type > const_iterator;
+
+ sc_vector(){}
+
+ explicit sc_vector( const char* prefix )
+ : base_type( prefix )
+ {}
+
+ explicit sc_vector( const char* prefix, size_type n )
+ : base_type( prefix )
+ { init(n); }
+
+ template< typename Creator >
+ sc_vector( const char* prefix, size_type n, Creator creator )
+ : base_type( prefix )
+ {
+ init( n, creator );
+ }
+
+ virtual ~sc_vector();
+
+ element_type& operator[]( size_type i )
+ { return *static_cast<element_type*>( base_type::at(i) ); }
+
+ element_type& at( size_type i )
+ { check_index(i); return (*this)[i]; }
+
+ const element_type& operator[]( size_type i ) const
+ { return *static_cast<element_type const *>( base_type::at(i) ); }
+
+ const element_type& at( size_type i ) const
+ { check_index(i); return (*this)[i]; }
+
+ void init( size_type n )
+ { init( n, &this_type::create_element ); }
+
+ template< typename Creator >
+ void init( size_type n, Creator c );
+
+ static element_type * create_element( const char* prefix, size_type index );
+
+ iterator begin() { return base_type::begin(); }
+ iterator end() { return base_type::end(); }
+
+ const_iterator begin() const { return base_type::begin(); }
+ const_iterator end() const { return base_type::end(); }
+
+ const_iterator cbegin() const { return base_type::begin(); }
+ const_iterator cend() const { return base_type::end(); }
+
+ template< typename ContainerType, typename ArgumentType >
+ iterator bind( sc_vector_assembly<ContainerType,ArgumentType> c )
+ { return bind( c.begin(), c.end() ); }
+
+ template< typename BindableContainer >
+ iterator bind( BindableContainer & c )
+ { return bind( c.begin(), c.end() ); }
+
+ template< typename BindableIterator >
+ iterator bind( BindableIterator first, BindableIterator last )
+ { return bind( first, last, this->begin() ); }
+
+ template< typename BindableIterator >
+ iterator bind( BindableIterator first, BindableIterator last
+ , iterator from )
+ { return sc_vector_do_bind( *this, first, last, from ); }
+
+ template< typename ContainerType, typename ArgumentType >
+ iterator operator()( sc_vector_assembly<ContainerType,ArgumentType> c )
+ { return operator()( c.begin(), c.end() ); }
+
+ template< typename ArgumentContainer >
+ iterator operator()( ArgumentContainer & c )
+ { return operator()( c.begin(), c.end() ); }
+
+ template< typename ArgumentIterator >
+ iterator operator()( ArgumentIterator first, ArgumentIterator last )
+ { return operator()( first, last, this->begin() ); }
+
+ template< typename ArgumentIterator >
+ iterator operator()( ArgumentIterator first, ArgumentIterator last
+ , iterator from )
+ { return sc_vector_do_operator_paren( *this, first, last, from ); }
+
+ // member-wise access
+
+ template< typename MT >
+ sc_vector_assembly<T,MT> assemble( MT (T::*member_ptr) )
+ { return sc_vector_assembly<T,MT>( *this, member_ptr ); }
+
+protected:
+
+ void clear();
+
+ virtual sc_object* object_cast( void* p ) const
+ { return implicit_cast( static_cast<element_type*>(p) ); }
+
+};
+
+template< typename T, typename MT >
+class sc_vector_assembly
+{
+ template< typename U > friend class sc_vector;
+
+public:
+
+ typedef sc_vector<T> base_type;
+
+ typedef sc_vector_iter< T, sc_member_access<T, MT> > iterator;
+ typedef sc_vector_iter< const T
+ , sc_member_access<const T, const MT> > const_iterator;
+
+ typedef T element_type;
+ typedef MT access_type;
+
+ typedef typename base_type::size_type size_type;
+ typedef typename base_type::difference_type difference_type;
+ typedef typename iterator::reference reference;
+ typedef typename iterator::pointer pointer;
+ typedef typename const_iterator::reference const_reference;
+ typedef typename const_iterator::pointer const_pointer;
+
+
+ typedef access_type (T::*member_type);
+
+ const char* name() const { return vec_->name(); }
+ const char* kind() const { return "sc_vector_assembly"; }
+
+ iterator begin()
+ { return iterator( (*vec_).begin().it_, ptr_ ); }
+ iterator end()
+ { return iterator( (*vec_).end().it_, ptr_ ); }
+
+ const_iterator cbegin() const
+ { return const_iterator( (*vec_).cbegin().it_, ptr_ ); }
+ const_iterator cend() const
+ { return const_iterator( (*vec_).cend().it_, ptr_ ); }
+
+ const_iterator begin() const
+ { return const_iterator( (*vec_).begin().it_, ptr_ ); }
+ const_iterator end() const
+ { return const_iterator( (*vec_).end().it_, ptr_ ); }
+
+ size_type size() const { return vec_->size(); }
+ const std::vector< sc_object* > & get_elements() const;
+
+ reference operator[]( size_type idx )
+ { return (*vec_)[idx].*ptr_; }
+ reference at( size_type idx )
+ { return vec_->at(idx).*ptr_; }
+ const_reference operator[]( size_type idx ) const
+ { return (*vec_)[idx].*ptr_; }
+ const_reference at( size_type idx ) const
+ { return vec_->at(idx).*ptr_; }
+
+ template< typename ContainerType, typename ArgumentType >
+ iterator bind( sc_vector_assembly<ContainerType,ArgumentType> c )
+ { return bind( c.begin(), c.end() ); }
+
+ template< typename BindableContainer >
+ iterator bind( BindableContainer & c )
+ { return bind( c.begin(), c.end() ); }
+
+ template< typename BindableIterator >
+ iterator bind( BindableIterator first, BindableIterator last )
+ { return bind( first, last, this->begin() ); }
+
+ template< typename BindableIterator >
+ iterator bind( BindableIterator first, BindableIterator last
+ , iterator from )
+ { return sc_vector_do_bind( *this, first, last, from ); }
+
+ template< typename BindableIterator >
+ iterator bind( BindableIterator first, BindableIterator last
+ , typename base_type::iterator from )
+ { return bind( first, last, iterator(from.it_, ptr_) ); }
+
+ template< typename ContainerType, typename ArgumentType >
+ iterator operator()( sc_vector_assembly<ContainerType,ArgumentType> c )
+ { return operator()( c.begin(), c.end() ); }
+
+ template< typename ArgumentContainer >
+ iterator operator()( ArgumentContainer & c )
+ { return operator()( c.begin(), c.end() ); }
+
+ template< typename ArgumentIterator >
+ iterator operator()( ArgumentIterator first, ArgumentIterator last )
+ { return operator()( first, last, this->begin() ); }
+
+ template< typename ArgumentIterator >
+ iterator operator()( ArgumentIterator first, ArgumentIterator last
+ , iterator from )
+ { return sc_vector_do_operator_paren( *this, first, last, from ); }
+
+ template< typename ArgumentIterator >
+ iterator operator()( ArgumentIterator first, ArgumentIterator last
+ , typename base_type::iterator from )
+ { return operator()( first, last, iterator(from.it_, ptr_) ); }
+
+ sc_vector_assembly( const sc_vector_assembly & other )
+ : vec_( other.vec_ )
+ , ptr_( other.ptr_ )
+ , child_vec_(0)
+ {}
+
+ sc_vector_assembly& operator=( sc_vector_assembly other_copy )
+ {
+ swap( other_copy );
+ return *this;
+ }
+
+ void swap( sc_vector_assembly & that )
+ {
+ using std::swap;
+ swap( vec_, that.vec_ );
+ swap( ptr_, that.ptr_ );
+ swap( child_vec_, that.child_vec_ );
+ }
+
+ void report_empty_bind( const char* kind_, bool dst_empty_ ) const
+ { vec_->report_empty_bind( kind_, dst_empty_ ); }
+
+ ~sc_vector_assembly()
+ { delete child_vec_; }
+
+private:
+
+ sc_vector_assembly( base_type & v, member_type ptr )
+ : vec_(&v)
+ , ptr_(ptr)
+ , child_vec_(0)
+ {}
+
+ sc_object* object_cast( pointer p ) const
+ { return vec_->implicit_cast( p ); }
+
+ base_type * vec_;
+ member_type ptr_;
+
+ mutable std::vector< sc_object* >* child_vec_;
+};
+
+template< typename T, typename MT >
+sc_vector_assembly<T,MT>
+sc_assemble_vector( sc_vector<T> & vec, MT (T::*ptr) )
+{
+ return vec.assemble( ptr );
+}
+
+template< typename T >
+typename sc_vector<T>::element_type *
+sc_vector<T>::create_element( const char* name, size_type /* idx */ )
+{
+ return new T( name );
+}
+
+template< typename T >
+template< typename Creator >
+void
+sc_vector<T>::init( size_type n, Creator c )
+{
+ if ( base_type::check_init(n) )
+ {
+ base_type::reserve( n );
+ try
+ {
+ for ( size_type i = 0; i<n; ++i )
+ {
+ // this workaround is needed for SystemC 2.2/2.3 sc_bind
+ std::string name = make_name( basename(), i );
+ const char* cname = name.c_str();
+
+ void* p = c( cname, i ) ; // call Creator
+ base_type::push_back(p);
+ }
+ }
+ catch ( ... )
+ {
+ clear();
+ throw;
+ }
+ }
+}
+
+template< typename T >
+void
+sc_vector<T>::clear()
+{
+ size_type i = size();
+ while ( i --> 0 )
+ {
+ delete &( (*this)[i] );
+ base_type::at(i) = 0;
+ }
+ base_type::clear();
+}
+
+template< typename Container, typename ArgumentIterator >
+typename Container::iterator
+sc_vector_do_bind( Container & cont
+ , ArgumentIterator first
+ , ArgumentIterator last
+ , typename Container::iterator from )
+{
+ typename Container::iterator end = cont.end();
+
+ if( !cont.size() || from == end || first == last )
+ cont.report_empty_bind( cont.kind(), from == end );
+
+ while( from!=end && first != last )
+ (*from++).bind( *first++ );
+ return from;
+}
+
+template< typename Container, typename ArgumentIterator >
+typename Container::iterator
+sc_vector_do_operator_paren( Container& cont
+ , ArgumentIterator first
+ , ArgumentIterator last
+ , typename Container::iterator from )
+{
+ typename Container::iterator end = cont.end();
+
+ if( !cont.size() || from == end || first == last )
+ cont.report_empty_bind( cont.kind(), from == end );
+
+ while( from!=end && first != last )
+ (*from++)( *first++ );
+ return from;
+}
+
+template< typename T >
+sc_vector<T>::~sc_vector()
+{
+ clear();
+}
+
+template< typename T, typename MT >
+std::vector< sc_object* > const &
+sc_vector_assembly<T,MT>::get_elements() const
+{
+ if( !child_vec_ )
+ child_vec_ = new std::vector< sc_object* >;
+
+ if( child_vec_->size() || !size() )
+ return *child_vec_;
+
+ child_vec_->reserve( size() );
+ for( const_iterator it=begin(); it != end(); ++it )
+ if( sc_object * obj = object_cast( const_cast<MT*>(&*it) ) )
+ child_vec_->push_back( obj );
+
+ return *child_vec_;
+}
+
+} // namespace sc_core
+#undef SC_RPTYPE_
+#undef SC_ENABLE_IF_
+
+// $Log: sc_vector.h,v $
+// Revision 1.17 2011/08/26 20:46:20 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.16 2011/07/25 10:21:17 acg
+// Andy Goodrich: check in aftermath of call to automake.
+//
+// Revision 1.15 2011/04/02 00:04:32 acg
+// Philipp A. Hartmann: fix distance from member iterators, and
+// add iterator conversions.
+//
+// Revision 1.14 2011/04/01 22:35:19 acg
+// Andy Goodrich: spelling fix.
+//
+// Revision 1.13 2011/03/28 13:03:09 acg
+// Andy Goodrich: Philipp's latest update.
+//
+// Revision 1.12 2011/03/23 16:16:28 acg
+// Philipp A. Hartmann: rebase implementation on void*
+// - supports virtual inheritance from sc_object again
+// - build up get_elements result on demand
+// - still requires element type to be derived from sc_object
+//
+// Revision 1.11 2011/02/19 16:46:36 acg
+// Andy Goodrich: finally get the update from Philipp correct!
+//
+
+#endif // SC_VECTOR_H_INCLUDED_
+// Taf!
diff --git a/ext/systemc/src/systemc b/ext/systemc/src/systemc
new file mode 100644
index 000000000..ec37d6a3c
--- /dev/null
+++ b/ext/systemc/src/systemc
@@ -0,0 +1,128 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ systemc - Top-level namespace-based include file for the SystemC library.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Andy Goodrich, Forte Design Systems, 31 Mar 2005
+ Description of Modification: This is the old systemc.h without usings.
+
+ *****************************************************************************/
+
+// $Log: systemc,v $
+// Revision 1.6 2011/08/04 17:12:07 acg
+// Andy Goodrich: moved systemc and systemc.h back to src level because
+// of MSVC not doing an install.
+//
+// Revision 1.1 2011/07/02 13:26:48 acg
+// Andy Goodrich: moved header files up one level.
+//
+// Revision 1.4 2011/02/18 20:28:27 acg
+// Andy Goodrich: Updated Copyright.
+//
+// Revision 1.3 2011/01/20 16:52:09 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.2 2009/11/17 19:57:51 acg
+// Andy Goodrich: changes for boost.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:04 acg
+// SystemC 2.3
+//
+// Revision 1.5 2006/04/11 23:11:16 acg
+// Andy Goodrich: remove inclusions that exposed sc_method_process,
+// sc_thread_process, and sc_cthread_process internals.
+//
+// Revision 1.4 2006/01/25 00:48:29 acg
+// Andy Goodrich: added capture of CVS logging messages in the source.
+//
+
+#ifndef SYSTEMC_INCLUDED
+#define SYSTEMC_INCLUDED
+
+// include this file first
+#include "sysc/kernel/sc_cmnhdr.h"
+
+#include "sysc/kernel/sc_externs.h"
+#include "sysc/kernel/sc_except.h"
+#include "sysc/kernel/sc_module.h"
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_process_handle.h"
+#include "sysc/kernel/sc_ver.h"
+
+#include "sysc/communication/sc_buffer.h"
+#include "sysc/communication/sc_clock.h"
+#include "sysc/communication/sc_clock_ports.h"
+#include "sysc/communication/sc_event_queue.h"
+#include "sysc/communication/sc_export.h"
+#include "sysc/communication/sc_fifo.h"
+#include "sysc/communication/sc_fifo_ports.h"
+#include "sysc/communication/sc_mutex.h"
+#include "sysc/communication/sc_semaphore.h"
+#include "sysc/communication/sc_signal.h"
+#include "sysc/communication/sc_signal_ports.h"
+
+#include "sysc/communication/sc_signal_resolved.h"
+#include "sysc/communication/sc_signal_resolved_ports.h"
+#include "sysc/communication/sc_signal_rv.h"
+#include "sysc/communication/sc_signal_rv_ports.h"
+
+#include "sysc/datatypes/bit/sc_bit.h"
+#include "sysc/datatypes/bit/sc_logic.h"
+#include "sysc/datatypes/bit/sc_bv.h"
+#include "sysc/datatypes/bit/sc_lv.h"
+
+#include "sysc/datatypes/int/sc_bigint.h"
+#include "sysc/datatypes/int/sc_biguint.h"
+#include "sysc/datatypes/int/sc_int.h"
+#include "sysc/datatypes/int/sc_uint.h"
+
+#include "sysc/datatypes/misc/sc_concatref.h"
+
+#ifdef SC_INCLUDE_FX
+# include "sysc/datatypes/fx/fx.h"
+#endif // SC_INCLUDE_FX
+
+#include "sysc/tracing/sc_trace.h"
+
+#include "sysc/utils/sc_iostream.h"
+#include "sysc/utils/sc_utils_ids.h"
+
+#include "sysc/utils/sc_pvector.h"
+#include "sysc/utils/sc_vector.h"
+
+#endif // !defined(SYSTEMC_INCLUDED)
+
+#ifdef SC_INCLUDE_DYNAMIC_PROCESSES
+# include "sysc/kernel/sc_dynamic_processes.h"
+#endif // SC_INCLUDE_DYNAMIC_PROCESSES
+
+#ifdef SC_USE_SC_STRING_OLD
+# include "sysc/utils/sc_string.h"
+#endif // SC_USE_SC_STRING_OLD
diff --git a/ext/systemc/src/systemc.h b/ext/systemc/src/systemc.h
new file mode 100644
index 000000000..ccc1285eb
--- /dev/null
+++ b/ext/systemc/src/systemc.h
@@ -0,0 +1,348 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ systemc.h - Top-level include file for the SystemC library with usings.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Andy Goodrich, Forte Design Systems, 31 Mar 2005
+ Description of Modification: Changes for namespace support.
+
+ *****************************************************************************/
+
+#ifndef SYSTEMC_H
+#define SYSTEMC_H
+
+// INCLUDE SYSTEM (std) DEFINITIONS:
+
+#include <cassert>
+#include <climits>
+#include <cmath> // math.h?
+#include <cstddef>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <exception>
+#include <fstream>
+#include <iostream>
+#include <memory>
+#include <string>
+#if defined(__sun) || defined(__sun__)
+# include <inttypes.h>
+#elif !defined(WIN32) && !defined(_WIN32)
+# include <stdint.h>
+#endif
+#include <typeinfo>
+#include <utility>
+#include <vector>
+
+// USINGS FOR I/O STREAM SUPPORT:
+
+ using std::ios;
+ using std::streambuf;
+ using std::streampos;
+ using std::streamsize;
+ using std::iostream;
+ using std::istream;
+ using std::ostream;
+ using std::cin;
+ using std::cout;
+ using std::cerr;
+ using std::endl;
+ using std::flush;
+ using std::dec;
+ using std::hex;
+ using std::oct;
+ using std::noshowbase;
+ using std::showbase;
+
+ using std::fstream;
+ using std::ifstream;
+ using std::ofstream;
+
+// from <cstdio>:
+
+ using std::size_t;
+ using std::FILE;
+ using std::fpos_t;
+ using std::fclose;
+ using std::clearerr;
+
+ using std::remove;
+ using std::rename;
+ using std::tmpfile;
+ using std::tmpnam;
+ using std::fflush;
+ using std::fopen;
+ using std::freopen;
+ using std::setbuf;
+ using std::setvbuf;
+ using std::fprintf;
+ using std::fscanf;
+ using std::printf;
+ using std::scanf;
+ using std::sprintf;
+ using std::sscanf;
+ using std::vfprintf;
+ using std::vprintf;
+ using std::vsprintf;
+ using std::fgetc;
+ using std::fgets;
+ using std::fputc;
+ using std::fputs;
+ using std::getc;
+ using std::getchar;
+ using std::gets;
+ using std::putc;
+ using std::putchar;
+ using std::puts;
+ using std::ungetc;
+ using std::fread;
+ using std::fwrite;
+ using std::fgetpos;
+ using std::fseek;
+ using std::fsetpos;
+ using std::ftell;
+ using std::rewind;
+ using std::feof;
+ using std::ferror;
+ using std::perror;
+
+// from <cstdlib>:
+
+ using std::div_t;
+ using std::ldiv_t;
+
+ using std::atof;
+ using std::atoi;
+ using std::atol;
+ using std::strtod;
+ using std::strtol;
+ using std::strtoul;
+ using std::rand;
+ using std::srand;
+ using std::calloc;
+ using std::free;
+ using std::malloc;
+ using std::realloc;
+ using std::abort;
+ using std::atexit;
+ using std::exit;
+ using std::getenv;
+ using std::system;
+ using std::bsearch;
+ using std::qsort;
+ using std::abs;
+ using std::div;
+ using std::labs;
+ using std::ldiv;
+ using std::mblen;
+ using std::mbtowc;
+ using std::mbstowcs;
+#if !defined(__CYGWIN__) && !defined(__CYGWIN32)
+ using std::wctomb;
+ using std::wcstombs;
+#endif
+
+// from <cstring>:
+
+ using std::memcpy;
+ using std::memmove;
+ using std::strcpy;
+ using std::strncpy;
+ using std::strcat;
+ using std::strncat;
+ using std::memcmp;
+ using std::strcmp;
+ using std::strcoll;
+ using std::strncmp;
+ using std::strxfrm;
+ using std::memchr;
+ using std::strchr;
+ using std::strcspn;
+ using std::strpbrk;
+ using std::strrchr;
+ using std::strspn;
+ using std::strstr;
+ using std::strtok;
+ using std::memset;
+ using std::strerror;
+ using std::strlen;
+
+// deprecated strstream support
+#if defined( SC_INCLUDE_STRSTREAM )
+#include <strstream>
+
+ using std::strstream;
+ using std::strstreambuf;
+ using std::istrstream;
+ using std::ostrstream;
+
+#endif // SC_INCLUDE_STRSTREAM
+
+// INCLUDE SYSTEMC DEFINITIONS for sc_dt AND sc_core NAMESPACES:
+
+#include "systemc"
+
+// USINGS FOR THE sc_dt NAMESPACE:
+
+using sc_dt::SC_BIN;
+using sc_dt::SC_BIN_SM;
+using sc_dt::SC_BIN_US;
+using sc_dt::SC_CSD;
+using sc_dt::SC_DEC;
+using sc_dt::SC_HEX;
+using sc_dt::SC_HEX_SM;
+using sc_dt::SC_HEX_US;
+using sc_dt::SC_LOGIC_0;
+using sc_dt::SC_LOGIC_1;
+using sc_dt::SC_LOGIC_X;
+using sc_dt::SC_LOGIC_Z;
+using sc_dt::SC_NOBASE;
+using sc_dt::SC_OCT;
+using sc_dt::SC_OCT_SM;
+using sc_dt::SC_OCT_US;
+using sc_dt::int64;
+using sc_dt::sc_abs;
+using sc_dt::sc_bigint;
+using sc_dt::sc_biguint;
+using sc_dt::sc_bit;
+using sc_dt::sc_bv;
+using sc_dt::sc_bv_base;
+using sc_dt::sc_digit;
+using sc_dt::sc_int;
+using sc_dt::sc_int_base;
+using sc_dt::sc_io_show_base;
+using sc_dt::sc_length_context;
+using sc_dt::sc_length_param;
+using sc_dt::sc_logic;
+using sc_dt::sc_lv;
+using sc_dt::sc_lv_base;
+using sc_dt::sc_max;
+using sc_dt::sc_min;
+using sc_dt::sc_numrep;
+using sc_dt::sc_signed;
+using sc_dt::sc_uint;
+using sc_dt::sc_uint_base;
+using sc_dt::sc_unsigned;
+using sc_dt::uint64;
+// #ifdef SC_DT_DEPRECATED
+using sc_dt::sc_logic_0;
+using sc_dt::sc_logic_1;
+using sc_dt::sc_logic_Z;
+using sc_dt::sc_logic_X;
+// #endif
+
+#ifdef SC_INCLUDE_FX
+ using sc_dt::sc_fxnum;
+ using sc_dt::sc_fxnum_bitref;
+ using sc_dt::sc_fxnum_fast;
+ using sc_dt::sc_fix;
+ using sc_dt::sc_fix_fast;
+ using sc_dt::sc_ufix;
+ using sc_dt::sc_ufix_fast;
+ using sc_dt::sc_fixed;
+ using sc_dt::sc_fixed_fast;
+ using sc_dt::sc_ufixed;
+ using sc_dt::sc_ufixed_fast;
+ using sc_dt::sc_fxval;
+ using sc_dt::sc_fxval_fast;
+ using sc_dt::sc_fxcast_switch;
+ using sc_dt::sc_fxcast_context;
+ using sc_dt::sc_fxtype_params;
+ using sc_dt::sc_fxtype_context;
+ using sc_dt::sc_q_mode;
+ using sc_dt::SC_RND;
+ using sc_dt::SC_RND_ZERO;
+ using sc_dt::SC_RND_MIN_INF;
+ using sc_dt::SC_RND_INF;
+ using sc_dt::SC_RND_CONV;
+ using sc_dt::SC_TRN;
+ using sc_dt::SC_TRN_ZERO;
+ using sc_dt::sc_o_mode;
+ using sc_dt::SC_SAT;
+ using sc_dt::SC_SAT_ZERO;
+ using sc_dt::SC_SAT_SYM;
+ using sc_dt::SC_WRAP;
+ using sc_dt::SC_WRAP_SM;
+ using sc_dt::sc_switch;
+ using sc_dt::SC_OFF;
+ using sc_dt::SC_ON;
+ using sc_dt::sc_fmt;
+ using sc_dt::SC_F;
+ using sc_dt::SC_E;
+ using sc_dt::sc_context_begin;
+ using sc_dt::SC_NOW;
+ using sc_dt::SC_LATER;
+#endif // SC_INCLUDE_FX
+
+#if 0 // defined( _MSC_VER ) // supported versions of MSVC should support ADL
+
+ using sc_dt::equal;
+ using sc_dt::not_equal;
+ using sc_dt::b_not;
+ using sc_dt::b_and;
+ using sc_dt::b_or;
+ using sc_dt::b_xor;
+ using sc_dt::lrotate;
+ using sc_dt::rrotate;
+ using sc_dt::reverse;
+ using sc_dt::concat;
+ using sc_dt::and_reduce;
+ using sc_dt::or_reduce;
+ using sc_dt::xor_reduce;
+ using sc_dt::nand_reduce;
+ using sc_dt::nor_reduce;
+ using sc_dt::xnor_reduce;
+
+#endif // defined( _MSC_VER )
+
+
+// USINGS FOR sc_core:
+//
+// The explicit using for ::sc_core::wait is to remove an ambiguity with
+// the constructor for the system's union wait on Unix and Linux. This
+// causes problems with aCC, so users of aCC should explicitly select
+// the SystemC wait functions using ::sc_core::wait(...). This is actually
+// a good idea for SystemC programmers in general.
+
+using namespace sc_core;
+
+#if !defined( __HP_aCC )
+ using ::sc_core::wait;
+#endif // !defined( __HP_aCC )
+
+#ifdef SC_USE_SC_STRING_OLD
+ using sc_dt::sc_string_old;
+ typedef sc_dt::sc_string_old sc_string;
+#endif
+#ifdef SC_USE_STD_STRING
+ typedef ::std::string sc_string;
+#endif
+
+#endif
diff --git a/ext/systemc/src/tlm b/ext/systemc/src/tlm
new file mode 100644
index 000000000..b4fb9fe70
--- /dev/null
+++ b/ext/systemc/src/tlm
@@ -0,0 +1,33 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#ifndef __TLM_HEADER__
+#define __TLM_HEADER__
+
+#include <systemc> // main SystemC header
+
+#include "tlm_core/tlm_2/tlm_version.h"
+#include "tlm_core/tlm_1/tlm_analysis/tlm_analysis.h"
+#include "tlm_core/tlm_1/tlm_req_rsp/tlm_req_rsp.h"
+#include "tlm_core/tlm_2/tlm_2_interfaces/tlm_2_interfaces.h"
+#include "tlm_core/tlm_2/tlm_generic_payload/tlm_generic_payload.h"
+#include "tlm_core/tlm_2/tlm_sockets/tlm_sockets.h"
+#include "tlm_core/tlm_2/tlm_quantum/tlm_quantum.h"
+
+#endif /* TLM_HEADER_INCLUDED_ */
diff --git a/ext/systemc/src/tlm.h b/ext/systemc/src/tlm.h
new file mode 100644
index 000000000..36d6263ea
--- /dev/null
+++ b/ext/systemc/src/tlm.h
@@ -0,0 +1,22 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+// kept for backwards compatibility
+
+#include "tlm"
diff --git a/ext/systemc/src/tlm_core/tlm.pc.in b/ext/systemc/src/tlm_core/tlm.pc.in
new file mode 100644
index 000000000..2d3e55c7a
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm.pc.in
@@ -0,0 +1,38 @@
+# Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+# more contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright ownership.
+# Accellera licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# -------------------------------------------------------------------------
+#
+# tlm.pc.in --
+# pkg-config definition file (template) for TLM-2.0
+# (http://www.freedesktop.org/wiki/Software/pkg-config/)
+#
+# Author: Philipp A. Hartmann, OFFIS, 2013-05-07
+#
+# Note: The "real" definition (tlm.pc) is generated by "configure"
+# during the build configuration.
+#
+# -------------------------------------------------------------------------
+#
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+includedir=@includedir@
+
+Name: TLM-2.0
+Description: Accellera TLM-2.0 proof-of-concept library
+Version: @TLM_PACKAGE_VERSION@
+URL: @PACKAGE_URL@
+Requires: systemc >= 2.1.v1
+Cflags: -I${includedir}
diff --git a/ext/systemc/src/tlm_core/tlm_1/README.txt b/ext/systemc/src/tlm_core/tlm_1/README.txt
new file mode 100644
index 000000000..c7e1c5e1f
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_1/README.txt
@@ -0,0 +1,97 @@
+TLM-1.0 header files
+====================
+
+Dir: include/tlm_core/tlm_1/
+
+SubDirs: tlm_analysis/
+ tlm_req_rsp/
+
+Files: README.txt
+
+
+Comments
+========
+
+User code should only #include the tlm or tlm.h header file in the include/
+directory and avoid including any of the include files in this directory
+directly. All objects defined in this file hierarchy are in the tlm namespace.
+
+The header files are organizated, by subdirectory, as follows:
+
+
+tlm_analysis/
+--------------
+
+This contains the analysis interfaces, ports, and fifos. These files were not
+part of the original TLM-1.0 release, but have been grouped with TLM-1.0 in this
+release of TLM-2.0
+
+Files:
+ tlm_analysis.h (includes the other header files in this directory )
+ tlm_analysis_fifo.h (defines tlm_analysis_fifo )
+ tlm_analysis_if.h (defines tlm_analysis_if and tlm_delayed_analysis_if )
+ tlm_analysis_port.h (defines tlm_analysis_port )
+ tlm_analysis_triple.h (defines tlm_analysis_triple )
+ tlm_write_if.h (defines tlm_write_if and tlm_delayed_write_if )
+
+
+tlm_req_rsp/
+------------
+
+This provides support for TLM modeling based on a request/response pair that
+are passed by value. This is the original TLM 1.0 standard, with the addition
+of an overloading of the blocking transport method with pass-by-reference arguments.
+
+Files:
+ tlm_req_rsp.h (includes the key header files from the other directories)
+
+ tlm_1_interfaces/
+ tlm_core_ifs.h (defines the TLM 1.0 core interfaces:
+ tlm_transport_if
+ tlm_blocking_get_if
+ tlm_blocking_put_if
+ tlm_nonblocking_get_if
+ tlm_nonblocking_put_if
+ tlm_get_if
+ tlm_put_if
+ tlm_blocking_peek_if
+ tlm_nonblocking_peek_if
+ tlm_peek_if
+ tlm_blocking_get_peek_if
+ tlm_nonblocking_get_peek_if
+ tlm_get_peek_if )
+ tlm_fifo_ifs.h ( defines the TLM1.0 fifo interfaces:
+ tlm_fifo_debug_if
+ tlm_fifo_put_if
+ tlm_fifo_get_if
+ tlm_fifo_config_size_if )
+ tlm_master_slave_ifs.h ( defines the TLM1.0 master slave interfaces:
+ tlm_blocking_master_if
+ tlm_blocking_slave_if
+ tlm_nonblocking_master_if
+ tlm_nonblocking_slave_if
+ tlm_master_if
+ tlm_slave_if )
+ tlm_tag.h ( defines tlm_tag )
+
+ tlm_ports/
+ tlm_nonblocking_port.h (defines tlm_nonblocking_put_port,
+ tlm_nonblocking_get_port and
+ tlm_nonblocking_peek_port )
+ tlm_event_finder.h (defines tlm_event_finder_t )
+
+ tlm_channels/
+ tlm_fifo/
+ tlm_fifo.h (defines tlm_fifo, includes the other files )
+ tlm_fifo_peek.h (defines peek and poke interfaces for tlm_fifo )
+ tlm_fifo_put_get.h (defines put and get interfaces for tlm_fifo )
+ tlm_fifo_resize.h (defines expand, reduce, bound and unbound
+ interfaces for tlm_fifo )
+ circular_buffer.h (defines circular buffer used by tlm_fifo )
+ tlm_req_rsp_channels/
+ tlm_req_rsp_channels.h (defines tlm_req_rsp_channel and
+ tlm_transport_channel )
+ tlm_put_get_imp.h (contains implementatins used by the channels)
+
+ tlm_adapters/
+ tlm_adapters.h (defines transport_to_master and tlm_slave_to_transport)
diff --git a/ext/systemc/src/tlm_core/tlm_1/tlm_analysis/tlm_analysis.h b/ext/systemc/src/tlm_core/tlm_1/tlm_analysis/tlm_analysis.h
new file mode 100644
index 000000000..777f7141a
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_1/tlm_analysis/tlm_analysis.h
@@ -0,0 +1,33 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#ifndef __TLM_ANALYSIS_H__
+#define __TLM_ANALYSIS_H__
+
+
+#include "tlm_core/tlm_1/tlm_analysis/tlm_write_if.h"
+#include "tlm_core/tlm_1/tlm_analysis/tlm_analysis_if.h"
+
+#include "tlm_core/tlm_1/tlm_analysis/tlm_analysis_triple.h"
+#include "tlm_core/tlm_1/tlm_analysis/tlm_analysis_port.h"
+#include "tlm_core/tlm_1/tlm_analysis/tlm_analysis_fifo.h"
+
+#endif
+
+
diff --git a/ext/systemc/src/tlm_core/tlm_1/tlm_analysis/tlm_analysis_fifo.h b/ext/systemc/src/tlm_core/tlm_1/tlm_analysis/tlm_analysis_fifo.h
new file mode 100644
index 000000000..1f01b2a8e
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_1/tlm_analysis/tlm_analysis_fifo.h
@@ -0,0 +1,54 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#ifndef __TLM_ANALYSIS_FIFO_H__
+#define __TLM_ANALYSIS_FIFO_H__
+
+#include "tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo.h"
+#include "tlm_core/tlm_1/tlm_analysis/tlm_analysis_if.h"
+#include "tlm_core/tlm_1/tlm_analysis/tlm_analysis_triple.h"
+
+namespace tlm {
+
+template< typename T >
+class tlm_analysis_fifo :
+ public tlm_fifo< T > ,
+ public virtual tlm_analysis_if< T > ,
+ public virtual tlm_analysis_if< tlm_analysis_triple< T > > {
+
+ public:
+
+ // analysis fifo is an unbounded tlm_fifo
+
+ tlm_analysis_fifo( const char *nm ) : tlm_fifo<T>( nm , -16 ) {}
+ tlm_analysis_fifo() : tlm_fifo<T>( -16 ) {}
+
+ void write( const tlm_analysis_triple<T> &t ) {
+ nb_put( t );
+ }
+
+ void write( const T &t ) {
+ nb_put( t );
+ }
+
+};
+
+} // namespace tlm
+
+#endif
diff --git a/ext/systemc/src/tlm_core/tlm_1/tlm_analysis/tlm_analysis_if.h b/ext/systemc/src/tlm_core/tlm_1/tlm_analysis/tlm_analysis_if.h
new file mode 100644
index 000000000..bc24fee54
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_1/tlm_analysis/tlm_analysis_if.h
@@ -0,0 +1,39 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#ifndef __TLM_ANALYSIS_IF_H__
+#define __TLM_ANALYSIS_IF_H__
+
+#include "tlm_core/tlm_1/tlm_analysis/tlm_write_if.h"
+
+namespace tlm {
+
+template < typename T >
+class tlm_analysis_if : public virtual tlm_write_if<T>
+{
+};
+
+template < typename T >
+class tlm_delayed_analysis_if : public virtual tlm_delayed_write_if<T>
+{
+};
+
+} // namespace tlm
+
+#endif
diff --git a/ext/systemc/src/tlm_core/tlm_1/tlm_analysis/tlm_analysis_port.h b/ext/systemc/src/tlm_core/tlm_1/tlm_analysis/tlm_analysis_port.h
new file mode 100644
index 000000000..999092538
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_1/tlm_analysis/tlm_analysis_port.h
@@ -0,0 +1,84 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#ifndef __TLM_ANALYSIS_PORT_H__
+#define __TLM_ANALYSIS_PORT_H__
+
+#include "tlm_core/tlm_1/tlm_analysis/tlm_analysis_if.h"
+#include <deque>
+#include <algorithm>
+
+namespace tlm {
+
+
+template < typename T>
+class tlm_analysis_port :
+ public sc_core::sc_object ,
+ public virtual tlm_analysis_if< T >
+{
+ public:
+ tlm_analysis_port() : sc_core::sc_object() {}
+ tlm_analysis_port( const char *nm ) : sc_core::sc_object( nm ) {}
+
+ // bind and () work for both interfaces and analysis ports, since
+ // analysis ports implement the analysis interface
+
+ virtual void bind( tlm_analysis_if<T> &_if ) {
+ m_interfaces.push_back( &_if );
+ }
+
+ void operator() ( tlm_analysis_if<T> &_if ) { bind( _if ); }
+
+ virtual bool unbind( tlm_analysis_if<T> &_if ) {
+
+ typename std::deque< tlm_analysis_if<T> * >::iterator i
+ = std::remove( m_interfaces.begin(), m_interfaces.end(), &_if );
+
+ if( i != m_interfaces.end() ) {
+ m_interfaces.erase(i, m_interfaces.end() );
+ return 1;
+ }
+
+ return 0;
+
+ }
+
+ void write( const T &t ) {
+ typename std::deque< tlm_analysis_if<T> * >::iterator i;
+
+ for( i = m_interfaces.begin();
+ i != m_interfaces.end();
+ i++ ) {
+
+ (*i)->write( t );
+
+ }
+
+ }
+
+ private:
+ std::deque< tlm_analysis_if<T> * > m_interfaces;
+
+};
+
+} // namespace tlm
+
+#endif
+
+
diff --git a/ext/systemc/src/tlm_core/tlm_1/tlm_analysis/tlm_analysis_triple.h b/ext/systemc/src/tlm_core/tlm_1/tlm_analysis/tlm_analysis_triple.h
new file mode 100644
index 000000000..f65a25a2e
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_1/tlm_analysis/tlm_analysis_triple.h
@@ -0,0 +1,53 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#ifndef __TLM_ANALYSIS_TRIPLE_H__
+#define __TLM_ANALYSIS_TRIPLE_H__
+
+//#include <systemc>
+
+namespace tlm {
+
+template< typename T>
+struct tlm_analysis_triple {
+
+ sc_core::sc_time start_time;
+ T transaction;
+ sc_core::sc_time end_time;
+
+ tlm_analysis_triple() {}
+
+ tlm_analysis_triple( const tlm_analysis_triple &triple ) {
+ start_time = triple.start_time;
+ transaction = triple.transaction;
+ end_time = triple.end_time;
+ }
+
+ tlm_analysis_triple( const T &t ) {
+ transaction = t;
+ }
+
+ operator T() { return transaction; }
+ operator const T &() const { return transaction; }
+
+};
+
+} // namespace tlm
+
+#endif
diff --git a/ext/systemc/src/tlm_core/tlm_1/tlm_analysis/tlm_write_if.h b/ext/systemc/src/tlm_core/tlm_1/tlm_analysis/tlm_write_if.h
new file mode 100644
index 000000000..b66a591bc
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_1/tlm_analysis/tlm_write_if.h
@@ -0,0 +1,42 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#ifndef __TLM_WRITE_IF_H__
+#define __TLM_WRITE_IF_H__
+
+#include <systemc>
+
+namespace tlm {
+
+template <typename T>
+class tlm_write_if : public virtual sc_core::sc_interface {
+public:
+ virtual void write(const T& t) = 0;
+};
+
+template <typename T>
+class tlm_delayed_write_if : public virtual sc_core::sc_interface {
+public:
+ virtual void write(const T& t, const sc_core::sc_time& time) = 0;
+};
+
+} // namespace tlm
+
+
+#endif
diff --git a/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_core_ifs.h b/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_core_ifs.h
new file mode 100644
index 000000000..4c1340338
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_core_ifs.h
@@ -0,0 +1,149 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+//
+// Note to the LRM writer : This is the core of the TLM standard
+//
+
+
+#ifndef __TLM_CORE_IFS_H__
+#define __TLM_CORE_IFS_H__
+
+//#include <systemc>
+
+#include "tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_tag.h"
+
+namespace tlm {
+
+// bidirectional blocking interfaces
+
+template < typename REQ , typename RSP >
+class tlm_transport_if : public virtual sc_core::sc_interface
+{
+public:
+ virtual RSP transport( const REQ & ) = 0;
+
+ virtual void transport( const REQ &req , RSP &rsp ) {
+ rsp = transport( req );
+ }
+
+};
+
+
+// uni-directional blocking interfaces
+
+template < typename T >
+class tlm_blocking_get_if : public virtual sc_core::sc_interface
+{
+public:
+ virtual T get( tlm_tag<T> *t = 0 ) = 0;
+ virtual void get( T &t ) { t = get(); }
+
+};
+
+template < typename T >
+class tlm_blocking_put_if : public virtual sc_core::sc_interface
+{
+public:
+ virtual void put( const T &t ) = 0;
+};
+
+// uni-directional non blocking interfaces
+
+template < typename T >
+class tlm_nonblocking_get_if : public virtual sc_core::sc_interface
+{
+public:
+ virtual bool nb_get( T &t ) = 0;
+ virtual bool nb_can_get( tlm_tag<T> *t = 0 ) const = 0;
+ virtual const sc_core::sc_event &ok_to_get( tlm_tag<T> *t = 0 ) const = 0;
+};
+
+template < typename T >
+class tlm_nonblocking_put_if : public virtual sc_core::sc_interface
+{
+public:
+ virtual bool nb_put( const T &t ) = 0;
+ virtual bool nb_can_put( tlm_tag<T> *t = 0 ) const = 0;
+ virtual const sc_core::sc_event &ok_to_put( tlm_tag<T> *t = 0 ) const = 0;
+};
+
+
+// combined uni-directional blocking and non blocking
+
+template < typename T >
+class tlm_get_if :
+ public virtual tlm_blocking_get_if< T > ,
+ public virtual tlm_nonblocking_get_if< T > {};
+
+template < typename T >
+class tlm_put_if :
+ public virtual tlm_blocking_put_if< T > ,
+ public virtual tlm_nonblocking_put_if< T > {};
+
+
+// peek interfaces
+
+template < typename T >
+class tlm_blocking_peek_if : public virtual sc_core::sc_interface
+{
+public:
+ virtual T peek( tlm_tag<T> *t = 0 ) const = 0;
+ virtual void peek( T &t ) const { t = peek(); }
+
+};
+
+template < typename T >
+class tlm_nonblocking_peek_if : public virtual sc_core::sc_interface
+{
+public:
+ virtual bool nb_peek( T &t ) const = 0;
+ virtual bool nb_can_peek( tlm_tag<T> *t = 0 ) const = 0;
+ virtual const sc_core::sc_event &ok_to_peek( tlm_tag<T> *t = 0 ) const = 0;
+};
+
+template < typename T >
+class tlm_peek_if :
+ public virtual tlm_blocking_peek_if< T > ,
+ public virtual tlm_nonblocking_peek_if< T > {};
+
+// get_peek interfaces
+
+template < typename T >
+class tlm_blocking_get_peek_if :
+ public virtual tlm_blocking_get_if<T> ,
+ public virtual tlm_blocking_peek_if<T> {};
+
+template < typename T >
+class tlm_nonblocking_get_peek_if :
+ public virtual tlm_nonblocking_get_if<T> ,
+ public virtual tlm_nonblocking_peek_if<T> {};
+
+
+template < typename T >
+class tlm_get_peek_if :
+ public virtual tlm_get_if<T> ,
+ public virtual tlm_peek_if<T> ,
+ public virtual tlm_blocking_get_peek_if<T> ,
+ public virtual tlm_nonblocking_get_peek_if<T>
+ {};
+
+} // namespace tlm
+
+#endif
diff --git a/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_fifo_ifs.h b/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_fifo_ifs.h
new file mode 100644
index 000000000..d9b2b985b
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_fifo_ifs.h
@@ -0,0 +1,85 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+//
+// Note to the LRM writer : These interfaces are channel specific interfaces
+// useful in the context of tlm_fifo.
+//
+
+#ifndef __TLM_FIFO_IFS_H__
+#define __TLM_FIFO_IFS_H__
+
+#include "tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_core_ifs.h"
+
+namespace tlm {
+
+//
+// Fifo specific interfaces
+//
+
+// Fifo Debug Interface
+
+template< typename T >
+class tlm_fifo_debug_if : public virtual sc_core::sc_interface
+{
+public:
+ virtual int used() const = 0;
+ virtual int size() const = 0;
+ virtual void debug() const = 0;
+
+ //
+ // non blocking peek and poke - no notification
+ //
+ // n is index of data :
+ // 0 <= n < size(), where 0 is most recently written, and size() - 1
+ // is oldest ie the one about to be read.
+ //
+
+ virtual bool nb_peek( T & , int n ) const = 0;
+ virtual bool nb_poke( const T & , int n = 0 ) = 0;
+
+};
+
+// fifo interfaces = extended + debug
+
+template < typename T >
+class tlm_fifo_put_if :
+ public virtual tlm_put_if<T> ,
+ public virtual tlm_fifo_debug_if<T> {};
+
+template < typename T >
+class tlm_fifo_get_if :
+ public virtual tlm_get_peek_if<T> ,
+ public virtual tlm_fifo_debug_if<T> {};
+
+class tlm_fifo_config_size_if : public virtual sc_core::sc_interface
+{
+public:
+ virtual void nb_expand( unsigned int n = 1 ) = 0;
+ virtual void nb_unbound( unsigned int n = 16 ) = 0;
+
+ virtual bool nb_reduce( unsigned int n = 1 ) = 0;
+ virtual bool nb_bound( unsigned int n ) = 0;
+
+};
+
+} // namespace tlm
+
+#endif
+
diff --git a/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_master_slave_ifs.h b/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_master_slave_ifs.h
new file mode 100644
index 000000000..5bac3c877
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_master_slave_ifs.h
@@ -0,0 +1,73 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#ifndef __TLM_MASTER_SLAVE_IFS_H__
+#define __TLM_MASTER_SLAVE_IFS_H__
+
+#include "tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_core_ifs.h"
+
+namespace tlm {
+
+//
+// req/rsp combined interfaces
+//
+
+// blocking
+
+template < typename REQ , typename RSP>
+class tlm_blocking_master_if :
+ public virtual tlm_blocking_put_if< REQ > ,
+ public virtual tlm_blocking_get_peek_if< RSP > {};
+
+template < typename REQ , typename RSP>
+class tlm_blocking_slave_if :
+ public virtual tlm_blocking_put_if< RSP > ,
+ public virtual tlm_blocking_get_peek_if< REQ > {};
+
+// nonblocking
+
+template < typename REQ , typename RSP >
+class tlm_nonblocking_master_if :
+ public virtual tlm_nonblocking_put_if< REQ > ,
+ public virtual tlm_nonblocking_get_peek_if< RSP > {};
+
+template < typename REQ , typename RSP >
+class tlm_nonblocking_slave_if :
+ public virtual tlm_nonblocking_put_if< RSP > ,
+ public virtual tlm_nonblocking_get_peek_if< REQ > {};
+
+// combined
+
+template < typename REQ , typename RSP >
+class tlm_master_if :
+ public virtual tlm_put_if< REQ > ,
+ public virtual tlm_get_peek_if< RSP > ,
+ public virtual tlm_blocking_master_if< REQ , RSP > ,
+ public virtual tlm_nonblocking_master_if< REQ , RSP > {};
+
+template < typename REQ , typename RSP >
+class tlm_slave_if :
+ public virtual tlm_put_if< RSP > ,
+ public virtual tlm_get_peek_if< REQ > ,
+ public virtual tlm_blocking_slave_if< REQ , RSP > ,
+ public virtual tlm_nonblocking_slave_if< REQ , RSP > {};
+
+} // namespace tlm
+
+#endif
diff --git a/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_tag.h b/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_tag.h
new file mode 100644
index 000000000..230b77d17
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_tag.h
@@ -0,0 +1,31 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+//
+// Note to the LRM writer : This is part of the core TLM standard
+//
+
+#ifndef __TLM_TAG_H__
+#define __TLM_TAG_H__
+
+namespace tlm {
+template<class T> class tlm_tag {};
+}
+
+#endif
diff --git a/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_adapters/tlm_adapters.h b/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_adapters/tlm_adapters.h
new file mode 100644
index 000000000..13207187a
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_adapters/tlm_adapters.h
@@ -0,0 +1,105 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#ifndef __TLM_ADAPTERS_H__
+#define __TLM_ADAPTERS_H__
+
+#include "tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_master_slave_ifs.h"
+
+namespace tlm {
+
+template< typename REQ , typename RSP >
+class tlm_transport_to_master :
+ public sc_core::sc_module ,
+ public virtual tlm_transport_if< REQ , RSP >
+{
+public:
+ sc_core::sc_export< tlm_transport_if< REQ , RSP > > target_export;
+ sc_core::sc_port< tlm_master_if< REQ , RSP > > master_port;
+
+ tlm_transport_to_master( sc_core::sc_module_name nm ) :
+ sc_core::sc_module( nm ) {
+
+ target_export( *this );
+
+ }
+
+ tlm_transport_to_master() :
+ sc_core::sc_module( sc_core::sc_module_name( sc_core::sc_gen_unique_name( "transport_to_master" ) ) ){
+
+ target_export( *this );
+
+ }
+
+ RSP transport( const REQ &req ) {
+
+ mutex.lock();
+
+ master_port->put( req );
+ rsp = master_port->get();
+
+ mutex.unlock();
+ return rsp;
+
+ }
+
+private:
+ sc_core::sc_mutex mutex;
+ RSP rsp;
+
+};
+
+template< typename REQ , typename RSP >
+class tlm_slave_to_transport : public sc_core::sc_module
+{
+public:
+
+ SC_HAS_PROCESS( tlm_slave_to_transport );
+
+ sc_core::sc_port< tlm_slave_if< REQ , RSP > > slave_port;
+ sc_core::sc_port< tlm_transport_if< REQ , RSP > > initiator_port;
+
+ tlm_slave_to_transport( sc_core::sc_module_name nm ) : sc_core::sc_module( nm )
+ {}
+
+ tlm_slave_to_transport() :
+ sc_core::sc_module( sc_core::sc_module_name( sc_core::sc_gen_unique_name("slave_to_transport") ) )
+ {}
+
+private:
+ void run() {
+
+ REQ req;
+ RSP rsp;
+
+ while( true ) {
+
+ slave_port->get( req );
+ rsp = initiator_port->transport( req );
+ slave_port->put( rsp );
+
+ }
+
+ }
+
+};
+
+} // namespace tlm
+
+#endif
diff --git a/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/circular_buffer.h b/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/circular_buffer.h
new file mode 100644
index 000000000..68c3c2c1f
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/circular_buffer.h
@@ -0,0 +1,268 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+//
+// To the LRM writer : this class is purely an artifact of the implementation.
+//
+
+#ifndef __CIRCULAR_BUFFER_H__
+#define __CIRCULAR_BUFFER_H__
+
+#include <iostream>
+
+namespace tlm {
+
+template < typename T >
+class circular_buffer
+{
+public:
+
+ explicit
+ circular_buffer( int size = 0 );
+ ~circular_buffer();
+
+ void resize( int size );
+ void clear();
+
+ T read();
+ void write( const T & );
+
+ bool is_empty() const { return used() == 0; }
+ bool is_full() const { return free() == 0; }
+
+ int size() const { return m_size; }
+ int used() const { return m_used; }
+ int free() const { return m_free; }
+
+ const T& read_data() const
+ { return buf_read( m_buf, m_ri ); }
+
+ const T& peek_data( int i ) const
+ { return buf_read( m_buf, (m_ri + i) % size() ); }
+
+ T & poke_data( int i )
+ { return buf_read( m_buf , (m_wi + i) % size() ); }
+
+ void debug() const;
+
+private:
+ void increment_write_pos( int i = 1 );
+ void increment_read_pos( int i = 1 );
+
+ void init();
+
+ circular_buffer( const circular_buffer<T> &b ); // disabled
+ circular_buffer<T> &operator=( const circular_buffer<T> & ); // disabled
+
+ void* buf_alloc( int size );
+ void buf_free( void*& buf );
+ void buf_write( void* buf, int n, const T & t );
+ T& buf_read( void* buf, int n ) const;
+ void buf_clear( void* buf, int n );
+
+private:
+ int m_size; // size of the buffer
+ void* m_buf; // the buffer
+ int m_free; // number of free spaces
+ int m_used; // number of used spaces
+ int m_ri; // index of next read
+ int m_wi; // index of next write
+
+};
+
+template< typename T >
+void
+circular_buffer<T>::debug() const
+{
+
+ std::cout << "Buffer debug" << std::endl;
+ std::cout << "Size : " << size() << std::endl;
+ std::cout << "Free/Used " << free() << "/" << used() << std::endl;
+ std::cout << "Indices : r/w = " << m_ri << "/" << m_wi << std::endl;
+
+ if( is_empty() ) {
+
+ std::cout << "empty" << std::endl;
+
+ }
+
+ if( is_full() ) {
+
+ std::cout << "full" << std::endl;
+
+ }
+
+ std::cout << "Data : " << std::endl;
+ for( int i = 0; i < used(); i++ ) {
+
+ std::cout << peek_data( i ) << std::endl;
+
+ }
+
+
+}
+
+template < typename T >
+circular_buffer<T>::circular_buffer( int size )
+ : m_size(size)
+ , m_buf(0)
+{
+ init();
+
+}
+
+template < typename T >
+void
+circular_buffer<T>::clear()
+{
+ for( int i=0; i < used(); i++ ) {
+ buf_clear( m_buf, i );
+ }
+ m_free = m_size;
+ m_used = m_ri = m_wi = 0;
+}
+
+template < typename T >
+circular_buffer<T>::~circular_buffer()
+{
+ clear();
+ buf_free( m_buf );
+}
+
+template < typename T >
+void
+circular_buffer<T>::resize( int size )
+{
+
+ int i;
+ void * new_buf = buf_alloc(size);
+
+ for( i = 0; i < size && i < used(); i++ ) {
+
+ buf_write( new_buf, i, peek_data( i ) );
+ buf_clear( m_buf, (m_ri + i) % m_size );
+
+ }
+
+ buf_free( m_buf );
+
+ m_size = size;
+ m_ri = 0;
+ m_wi = i % m_size;
+ m_used = i;
+ m_free = m_size - m_used;
+
+ m_buf = new_buf;
+}
+
+
+template < typename T >
+void
+circular_buffer<T>::init() {
+
+ if( m_size > 0 ) {
+ m_buf = buf_alloc( m_size );
+ }
+
+ m_free = m_size;
+ m_used = 0;
+ m_ri = 0;
+ m_wi = 0;
+
+}
+
+template < typename T >
+T
+circular_buffer<T>::read()
+{
+ T t = read_data();
+
+ buf_clear( m_buf, m_ri );
+ increment_read_pos();
+
+ return t;
+}
+
+template < typename T >
+void
+circular_buffer<T>::write( const T &t )
+{
+ buf_write( m_buf, m_wi, t );
+ increment_write_pos();
+}
+
+
+template < typename T >
+void
+circular_buffer<T>::increment_write_pos( int i ) {
+
+ m_wi = ( m_wi + i ) % m_size;
+ m_used += i;
+ m_free -= i;
+
+}
+
+template < typename T >
+void
+circular_buffer<T>::increment_read_pos( int i ) {
+
+ m_ri = ( m_ri + i ) % m_size;
+ m_used -= i;
+ m_free += i;
+
+}
+
+template < typename T >
+inline void*
+circular_buffer<T>::buf_alloc( int size )
+ { return new unsigned char[ size * sizeof(T) ]; }
+
+template < typename T >
+inline void
+circular_buffer<T>::buf_free( void* & buf )
+ { delete [] static_cast<unsigned char*>(buf); buf = 0; }
+
+template < typename T >
+inline void
+circular_buffer<T>::buf_write( void* buf, int n, const T & t )
+{
+ T* p = static_cast<T*>(buf) + n;
+ new (p) T(t);
+}
+
+template < typename T >
+inline T&
+circular_buffer<T>::buf_read( void* buf, int n ) const
+{
+ T* p = static_cast<T*>(buf) + n;
+ return *p;
+}
+
+template < typename T >
+inline void
+circular_buffer<T>::buf_clear( void* buf, int n )
+{
+ T* p = static_cast<T*>(buf) + n;
+ p->~T();
+}
+
+} // namespace tlm
+
+#endif
+
diff --git a/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo.h b/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo.h
new file mode 100644
index 000000000..7b44a32ee
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo.h
@@ -0,0 +1,263 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#ifndef __TLM_FIFO_H__
+#define __TLM_FIFO_H__
+
+//
+// This implements put, get and peek
+//
+// It also implements 0 and infinite size fifos - but the size
+// zero fifos aren't rendezvous like zero length fifos, they simply are both
+// full and empty at the same time.
+//
+// The size can be dynamically changed using the resize interface
+//
+// To get an infinite fifo use a -ve size in the constructor.
+// The absolute value of the size is taken as the starting size of the
+// actual physical buffer.
+//
+
+//#include <systemc>
+
+#include "tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_fifo_ifs.h"
+#include "tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/circular_buffer.h"
+
+namespace tlm {
+
+template <typename T>
+class tlm_fifo :
+ public virtual tlm_fifo_get_if<T>,
+ public virtual tlm_fifo_put_if<T>,
+ public sc_core::sc_prim_channel
+{
+public:
+
+ // constructors
+
+ explicit tlm_fifo( int size_ = 1 )
+ : sc_core::sc_prim_channel( sc_core::sc_gen_unique_name( "fifo" ) ) {
+
+ init( size_ );
+
+ }
+
+ explicit tlm_fifo( const char* name_, int size_ = 1 )
+ : sc_core::sc_prim_channel( name_ ) {
+
+ init( size_ );
+
+ }
+
+ // destructor
+
+ virtual ~tlm_fifo() {}
+
+ // tlm get interface
+
+ T get( tlm_tag<T> * = 0 );
+
+ bool nb_get( T& );
+ bool nb_can_get( tlm_tag<T> * = 0 ) const;
+ const sc_core::sc_event &ok_to_get( tlm_tag<T> * = 0 ) const {
+ return m_data_written_event;
+ }
+
+ // tlm peek interface
+
+ T peek( tlm_tag<T> * = 0 ) const;
+
+ bool nb_peek( T& ) const;
+ bool nb_can_peek( tlm_tag<T> * = 0 ) const;
+ const sc_core::sc_event &ok_to_peek( tlm_tag<T> * = 0 ) const {
+ return m_data_written_event;
+ }
+
+ // tlm put interface
+
+ void put( const T& );
+
+ bool nb_put( const T& );
+ bool nb_can_put( tlm_tag<T> * = 0 ) const;
+
+ const sc_core::sc_event& ok_to_put( tlm_tag<T> * = 0 ) const {
+ return m_data_read_event;
+ }
+
+ // resize if
+
+ void nb_expand( unsigned int n = 1 );
+ void nb_unbound( unsigned int n = 16 );
+
+ bool nb_reduce( unsigned int n = 1 );
+ bool nb_bound( unsigned int n );
+
+ // debug interface
+
+ bool nb_peek( T & , int n ) const;
+ bool nb_poke( const T & , int n = 0 );
+
+ int used() const {
+ return m_num_readable - m_num_read;
+ }
+
+ int size() const {
+ return m_size;
+ }
+
+ void debug() const {
+
+ if( is_empty() ) std::cout << "empty" << std::endl;
+ if( is_full() ) std::cout << "full" << std::endl;
+
+ std::cout << "size " << size() << " - " << used() << " used "
+ << std::endl;
+ std::cout << "readable " << m_num_readable
+ << std::endl;
+ std::cout << "written/read " << m_num_written << "/" << m_num_read
+ << std::endl;
+
+ }
+
+ // support functions
+
+ static const char* const kind_string;
+
+ const char* kind() const
+ { return kind_string; }
+
+
+protected:
+ sc_core::sc_event &read_event( tlm_tag<T> * = 0 ) {
+ return m_data_read_event;
+ }
+
+protected:
+
+ void update();
+
+ // support methods
+
+ void init( int );
+
+protected:
+
+ circular_buffer<T> buffer;
+
+ int m_size; // logical size of fifo
+
+ int m_num_readable; // #samples readable
+ int m_num_read; // #samples read during this delta cycle
+ int m_num_written; // #samples written during this delta cycle
+ bool m_expand; // has an expand occurred during this delta cycle ?
+ int m_num_read_no_notify; // #samples read without notify during this delta cycle
+
+ sc_core::sc_event m_data_read_event;
+ sc_core::sc_event m_data_written_event;
+
+private:
+
+ // disabled
+ tlm_fifo( const tlm_fifo<T>& );
+ tlm_fifo& operator = ( const tlm_fifo<T>& );
+
+ //
+ // use nb_can_get() and nb_can_put() rather than the following two
+ // private functions
+ //
+
+ bool is_empty() const {
+ return used() == 0;
+ }
+
+ bool is_full() const {
+ //return size() == m_num_readable + m_num_written; // Old buggy code
+ if( size() < 0 )
+ return false;
+ else
+ return size() <= m_num_readable + m_num_written;
+ }
+
+};
+
+template <typename T>
+const char* const tlm_fifo<T>::kind_string = "tlm_fifo";
+
+
+/******************************************************************
+//
+// init and update
+//
+******************************************************************/
+
+template< typename T >
+inline
+void
+tlm_fifo<T>::init( int size_ ) {
+
+ if( size_ > 0 ) {
+ buffer.resize( size_ );
+ }
+
+ else if( size_ < 0 ) {
+ buffer.resize( -size_ );
+ }
+
+ else {
+ buffer.resize( 16 );
+ }
+
+ m_size = size_;
+ m_num_readable = 0;
+ m_num_read = 0;
+ m_num_written = 0;
+ m_expand = false;
+ m_num_read_no_notify = false;
+
+}
+
+template < typename T>
+inline
+void
+tlm_fifo<T>::update()
+{
+ if( m_num_read > m_num_read_no_notify || m_expand ) {
+ m_data_read_event.notify( sc_core::SC_ZERO_TIME );
+ }
+
+ if( m_num_written > 0 ) {
+ m_data_written_event.notify( sc_core::SC_ZERO_TIME );
+ }
+
+ m_expand = false;
+ m_num_read = 0;
+ m_num_written = 0;
+ m_num_readable = buffer.used();
+ m_num_read_no_notify = 0;
+
+}
+
+} // namespace tlm
+
+#include "tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_put_get.h"
+#include "tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_peek.h"
+#include "tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_resize.h"
+
+#endif
+
diff --git a/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_peek.h b/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_peek.h
new file mode 100644
index 000000000..e856c5657
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_peek.h
@@ -0,0 +1,98 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#ifndef __TLM_FIFO_PEEK_H__
+#define __TLM_FIFO_PEEK_H__
+
+namespace tlm {
+
+template < typename T>
+inline
+T
+tlm_fifo<T>::peek( tlm_tag<T> * ) const {
+
+ while( is_empty() ) {
+
+ // call free-standing sc_core::wait(),
+ // since sc_prim_channel::wait(.) is not const
+
+ sc_core::wait( m_data_written_event );
+ }
+
+ return buffer.read_data();
+
+}
+
+template < typename T>
+inline
+bool
+tlm_fifo<T>::nb_peek( T &t ) const {
+
+ if( used() < 1 ) {
+ return false;
+ }
+
+ t = buffer.peek_data( 0 );
+ return true;
+
+}
+
+template < typename T>
+inline
+bool
+tlm_fifo<T>::nb_peek( T &t , int n ) const {
+
+ if( n >= used() || n < -1 ) {
+ return false;
+ }
+
+ if( n == -1 ) {
+ n = used() - 1;
+ }
+
+ t = buffer.peek_data( n );
+ return true;
+
+}
+
+template< typename T >
+inline
+bool
+tlm_fifo<T>::nb_can_peek( tlm_tag<T> * ) const
+{
+ return !is_empty();
+}
+
+template < typename T>
+inline
+bool
+tlm_fifo<T>::nb_poke( const T &t , int n ) {
+
+ if( n >= used() || n < 0 ) {
+ return false;
+ }
+
+ buffer.poke_data( n ) = t;
+ return true;
+
+}
+
+} // namespace tlm
+
+#endif
diff --git a/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_put_get.h b/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_put_get.h
new file mode 100644
index 000000000..2728e0394
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_put_get.h
@@ -0,0 +1,140 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#ifndef __TLM_FIFO_PUT_GET_IF_H__
+#define __TLM_FIFO_PUT_GET_IF_H__
+
+namespace tlm {
+
+/******************************************************************
+//
+// get interface
+//
+******************************************************************/
+
+template <typename T>
+inline
+T
+tlm_fifo<T>::get( tlm_tag<T> * )
+{
+
+ while( is_empty() ) {
+ wait( m_data_written_event );
+ }
+
+ m_num_read ++;
+ request_update();
+
+ return buffer.read();
+
+}
+
+// non-blocking read
+
+template <typename T>
+inline
+bool
+tlm_fifo<T>::nb_get( T& val_ )
+{
+
+ if( is_empty() ) {
+ return false;
+ }
+
+ m_num_read ++;
+ request_update();
+
+ val_ = buffer.read();
+
+ return true;
+
+}
+
+template <typename T>
+inline
+bool
+tlm_fifo<T>::nb_can_get( tlm_tag<T> * ) const {
+
+ return !is_empty();
+
+}
+
+
+/******************************************************************
+//
+// put interface
+//
+******************************************************************/
+
+template <typename T>
+inline
+void
+tlm_fifo<T>::put( const T& val_ )
+{
+ while( is_full() ) {
+ wait( m_data_read_event );
+ }
+
+ if( buffer.is_full() ) {
+
+ buffer.resize( buffer.size() * 2 );
+
+ }
+
+ m_num_written ++;
+ buffer.write( val_ );
+
+ request_update();
+}
+
+template <typename T>
+inline
+bool
+tlm_fifo<T>::nb_put( const T& val_ )
+{
+
+ if( is_full() ) {
+ return false;
+ }
+
+ if( buffer.is_full() ) {
+
+ buffer.resize( buffer.size() * 2 );
+
+ }
+
+ m_num_written ++;
+ buffer.write( val_ );
+ request_update();
+
+ return true;
+}
+
+template < typename T >
+inline
+bool
+tlm_fifo<T>::nb_can_put( tlm_tag<T> * ) const {
+
+ return !is_full();
+
+}
+
+} // namespace tlm
+
+#endif
diff --git a/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_resize.h b/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_resize.h
new file mode 100644
index 000000000..39932fea1
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo_resize.h
@@ -0,0 +1,93 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#ifndef __TLM_FIFO_RESIZE_H__
+#define __TLM_FIFO_RESIZE_H__
+
+/******************************************************************
+//
+// resize interface
+//
+******************************************************************/
+
+namespace tlm {
+
+template < typename T>
+inline
+void
+tlm_fifo<T>::nb_expand( unsigned int n ) {
+
+ if( m_size >= 0 ) {
+ m_expand = true;
+ m_size += n;
+ request_update();
+ }
+}
+
+template < typename T>
+inline
+void
+tlm_fifo<T>::nb_unbound( unsigned int n ) {
+
+ m_expand = true;
+ m_size = -n;
+
+ if( buffer.size() < static_cast<int>( n ) ) {
+ buffer.resize( n );
+ }
+
+ request_update();
+
+}
+
+template < typename T>
+inline
+bool
+tlm_fifo<T>::nb_reduce( unsigned int n ) {
+
+ if( m_size < 0 ) {
+ return false;
+ }
+
+ return nb_bound( size() - n );
+
+}
+
+template < typename T>
+inline
+bool
+tlm_fifo<T>::nb_bound( unsigned int new_size ) {
+
+ bool ret = true;
+
+ if( static_cast<int>( new_size ) < used() ) {
+
+ new_size = used();
+ ret = false;
+
+ }
+
+ m_size = new_size;
+ return ret;
+
+}
+
+} // namespace tlm
+
+#endif
diff --git a/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_req_rsp_channels/tlm_put_get_imp.h b/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_req_rsp_channels/tlm_put_get_imp.h
new file mode 100644
index 000000000..36dbd21d6
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_req_rsp_channels/tlm_put_get_imp.h
@@ -0,0 +1,114 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+//
+// To the LRM writer : these classes are purely artifacts of the implementation.
+//
+
+#ifndef __TLM_PUT_GET_IMP_H__
+#define __TLM_PUT_GET_IMP_H__
+
+#include "tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_master_slave_ifs.h"
+
+namespace tlm {
+
+template < typename PUT_DATA , typename GET_DATA>
+class tlm_put_get_imp :
+ private virtual tlm_put_if< PUT_DATA > ,
+ private virtual tlm_get_peek_if< GET_DATA >
+{
+public:
+ tlm_put_get_imp( tlm_put_if<PUT_DATA> &p ,
+ tlm_get_peek_if<GET_DATA> &g ) :
+ put_fifo( p ) , get_fifo( g ) {}
+
+ // put interface
+
+ void put( const PUT_DATA &t ) { put_fifo.put( t ); }
+
+ bool nb_put( const PUT_DATA &t ) { return put_fifo.nb_put( t ); }
+ bool nb_can_put( tlm_tag<PUT_DATA> *t = 0 ) const {
+ return put_fifo.nb_can_put( t );
+ }
+ const sc_core::sc_event &ok_to_put( tlm_tag<PUT_DATA> *t = 0 ) const {
+ return put_fifo.ok_to_put( t );
+ }
+
+ // get interface
+
+ GET_DATA get( tlm_tag<GET_DATA> * = 0 ) { return get_fifo.get(); }
+
+ bool nb_get( GET_DATA &t ) { return get_fifo.nb_get( t ); }
+
+ bool nb_can_get( tlm_tag<GET_DATA> *t = 0 ) const {
+ return get_fifo.nb_can_get( t );
+ }
+
+ virtual const sc_core::sc_event &ok_to_get( tlm_tag<GET_DATA> *t = 0 ) const {
+ return get_fifo.ok_to_get( t );
+ }
+
+ // peek interface
+
+ GET_DATA peek( tlm_tag<GET_DATA> * = 0 ) const { return get_fifo.peek(); }
+
+ bool nb_peek( GET_DATA &t ) const { return get_fifo.nb_peek( t ); }
+
+ bool nb_can_peek( tlm_tag<GET_DATA> *t = 0 ) const {
+ return get_fifo.nb_can_peek( t );
+ }
+
+ virtual const sc_core::sc_event &ok_to_peek( tlm_tag<GET_DATA> *t = 0 ) const {
+ return get_fifo.ok_to_peek( t );
+ }
+
+private:
+ tlm_put_if<PUT_DATA> &put_fifo;
+ tlm_get_peek_if<GET_DATA> &get_fifo;
+};
+
+template < typename REQ , typename RSP >
+class tlm_master_imp :
+ private tlm_put_get_imp< REQ , RSP > ,
+ public virtual tlm_master_if< REQ , RSP >
+{
+public:
+
+ tlm_master_imp( tlm_put_if<REQ> &req ,
+ tlm_get_peek_if<RSP> &rsp ) :
+ tlm_put_get_imp<REQ,RSP>( req , rsp ) {}
+
+};
+
+template < typename REQ , typename RSP >
+class tlm_slave_imp :
+ private tlm_put_get_imp< RSP , REQ > ,
+ public virtual tlm_slave_if< REQ , RSP >
+{
+public:
+
+ tlm_slave_imp( tlm_get_peek_if<REQ> &req ,
+ tlm_put_if<RSP> &rsp ) :
+ tlm_put_get_imp<RSP,REQ>( rsp , req ) {}
+
+};
+
+} // namespace tlm
+
+#endif
diff --git a/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_req_rsp_channels/tlm_req_rsp_channels.h b/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_req_rsp_channels/tlm_req_rsp_channels.h
new file mode 100644
index 000000000..7bd5652f7
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_req_rsp_channels/tlm_req_rsp_channels.h
@@ -0,0 +1,155 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#ifndef __TLM_REQ_RSP_CHANNELS_H__
+#define __TLM_REQ_RSP_CHANNELS_H__
+
+#include "tlm_core/tlm_1/tlm_req_rsp/tlm_adapters/tlm_adapters.h"
+#include "tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/tlm_fifo.h"
+#include "tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_req_rsp_channels/tlm_put_get_imp.h"
+
+namespace tlm {
+
+template < typename REQ , typename RSP ,
+ typename REQ_CHANNEL = tlm_fifo<REQ> ,
+ typename RSP_CHANNEL = tlm_fifo<RSP> >
+
+class tlm_req_rsp_channel : public sc_core::sc_module
+{
+public:
+ // uni-directional slave interface
+
+ sc_core::sc_export< tlm_fifo_get_if< REQ > > get_request_export;
+ sc_core::sc_export< tlm_fifo_put_if< RSP > > put_response_export;
+
+ // uni-directional master interface
+
+ sc_core::sc_export< tlm_fifo_put_if< REQ > > put_request_export;
+ sc_core::sc_export< tlm_fifo_get_if< RSP > > get_response_export;
+
+ // master / slave interfaces
+
+ sc_core::sc_export< tlm_master_if< REQ , RSP > > master_export;
+ sc_core::sc_export< tlm_slave_if< REQ , RSP > > slave_export;
+
+
+ tlm_req_rsp_channel( int req_size = 1 , int rsp_size = 1 ) :
+ sc_core::sc_module( sc_core::sc_module_name( sc_core::sc_gen_unique_name("tlm_req_rsp_channel") ) ) ,
+ request_fifo( req_size ) ,
+ response_fifo( rsp_size ) ,
+ master( request_fifo , response_fifo ) ,
+ slave( request_fifo , response_fifo )
+ {
+
+ bind_exports();
+
+ }
+
+ tlm_req_rsp_channel( sc_core::sc_module_name module_name ,
+ int req_size = 1 , int rsp_size = 1 ) :
+ sc_core::sc_module( module_name ) ,
+ request_fifo( req_size ) ,
+ response_fifo( rsp_size ) ,
+ master( request_fifo , response_fifo ) ,
+ slave( request_fifo , response_fifo )
+ {
+
+ bind_exports();
+
+ }
+
+private:
+ void bind_exports() {
+
+ put_request_export( request_fifo );
+ get_request_export( request_fifo );
+
+ put_response_export( response_fifo );
+ get_response_export( response_fifo );
+
+ master_export( master );
+ slave_export( slave );
+
+ }
+
+protected:
+ REQ_CHANNEL request_fifo;
+ RSP_CHANNEL response_fifo;
+
+ tlm_master_imp< REQ , RSP > master;
+ tlm_slave_imp< REQ , RSP > slave;
+};
+
+template < typename REQ , typename RSP ,
+ typename REQ_CHANNEL = tlm_fifo<REQ> ,
+ typename RSP_CHANNEL = tlm_fifo<RSP> >
+class tlm_transport_channel : public sc_core::sc_module
+{
+public:
+
+ // master transport interface
+
+ sc_core::sc_export< tlm_transport_if< REQ , RSP > > target_export;
+
+ // slave interfaces
+
+ sc_core::sc_export< tlm_fifo_get_if< REQ > > get_request_export;
+ sc_core::sc_export< tlm_fifo_put_if< RSP > > put_response_export;
+
+ sc_core::sc_export< tlm_slave_if< REQ , RSP > > slave_export;
+
+ tlm_transport_channel() :
+ sc_core::sc_module( sc_core::sc_module_name( sc_core::sc_gen_unique_name("transport_channel" ) ) ) ,
+ target_export("target_export") ,
+ req_rsp( "req_rsp" , 1 , 1 ) ,
+ t2m("ts2m")
+ {
+ do_binding();
+ }
+
+ tlm_transport_channel( sc_core::sc_module_name nm ) :
+ sc_core::sc_module( nm ) ,
+ target_export("target_export") ,
+ req_rsp( "req_rsp" , 1 , 1 ) ,
+ t2m("tsm" )
+ {
+ do_binding();
+ }
+
+private:
+ void do_binding() {
+
+ target_export( t2m.target_export );
+
+ t2m.master_port( req_rsp.master_export );
+
+ get_request_export( req_rsp.get_request_export );
+ put_response_export( req_rsp.put_response_export );
+ slave_export( req_rsp.slave_export );
+
+ }
+
+ tlm_req_rsp_channel< REQ , RSP , REQ_CHANNEL , RSP_CHANNEL > req_rsp;
+ tlm_transport_to_master< REQ , RSP > t2m;
+
+};
+
+} // namespace tlm
+
+#endif
diff --git a/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_ports/tlm_event_finder.h b/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_ports/tlm_event_finder.h
new file mode 100644
index 000000000..60874ce91
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_ports/tlm_event_finder.h
@@ -0,0 +1,94 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#ifndef __TLM_EVENT_FINDER_H__
+#define __TLM_EVENT_FINDER_H__
+
+//#include <systemc>
+
+#include "tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_tag.h"
+
+namespace tlm {
+
+template <class IF , class T>
+class tlm_event_finder_t
+: public sc_core::sc_event_finder
+{
+public:
+
+ // constructor
+
+ tlm_event_finder_t( const sc_core::sc_port_base& port_,
+ const sc_core::sc_event& (IF::*event_method_) ( tlm_tag<T> * ) const )
+ : sc_core::sc_event_finder( port_ ), m_event_method( event_method_ )
+ {}
+
+ // destructor (does nothing)
+
+ virtual ~tlm_event_finder_t()
+ {}
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+ virtual const sc_core::sc_event& find_event( sc_core::sc_interface* if_p = 0 ) const;
+#else
+ virtual const sc_core::sc_event& find_event() const;
+#endif
+
+private:
+
+ const sc_core::sc_event& (IF::*m_event_method) ( tlm_tag<T> * ) const;
+
+private:
+
+ // disabled
+ tlm_event_finder_t();
+ tlm_event_finder_t( const tlm_event_finder_t<IF,T>& );
+ tlm_event_finder_t<IF,T>& operator = ( const tlm_event_finder_t<IF,T>& );
+};
+
+
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+template <class IF , class T>
+inline
+const sc_core::sc_event&
+tlm_event_finder_t<IF,T>::find_event( sc_core::sc_interface* if_p ) const
+{
+ const IF* iface = ( if_p ) ? dynamic_cast<const IF*>( if_p ) :
+ dynamic_cast<const IF*>( port().get_interface() );
+ if( iface == 0 ) {
+ report_error( sc_core::SC_ID_FIND_EVENT_, "port is not bound" );
+ }
+ return (const_cast<IF*>( iface )->*m_event_method) ( 0 );
+}
+#else
+template <class IF , class T>
+inline
+const sc_core::sc_event&
+tlm_event_finder_t<IF,T>::find_event() const
+{
+ const IF* iface = dynamic_cast<const IF*>( port().get_interface() );
+ if( iface == 0 ) {
+ report_error( sc_core::SC_ID_FIND_EVENT_, "port is not bound" );
+ }
+ return (const_cast<IF*>( iface )->*m_event_method) ( 0 );
+}
+#endif
+
+} // namespace tlm
+
+#endif
diff --git a/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_ports/tlm_nonblocking_port.h b/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_ports/tlm_nonblocking_port.h
new file mode 100644
index 000000000..0af1e3487
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_ports/tlm_nonblocking_port.h
@@ -0,0 +1,91 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#ifndef __TLM_NONBLOCKING_PORT_H__
+#define __TLM_NONBLOCKING_PORT_H__
+
+#include "tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_core_ifs.h"
+#include "tlm_core/tlm_1/tlm_req_rsp/tlm_ports/tlm_event_finder.h"
+
+namespace tlm {
+
+template < typename T >
+class tlm_nonblocking_get_port :
+public sc_core::sc_port< tlm_nonblocking_get_if< T > , 1 >
+{
+public:
+ typedef tlm_nonblocking_get_if<T> get_if_type;
+
+ tlm_nonblocking_get_port( const char *port_name ) :
+ sc_core::sc_port< tlm_nonblocking_get_if< T > , 1 >( port_name ) {}
+
+ sc_core::sc_event_finder& ok_to_get() const {
+
+ return *new tlm_event_finder_t< get_if_type , T >(
+ *this,
+ &get_if_type::ok_to_get );
+
+ }
+
+};
+
+template < typename T >
+class tlm_nonblocking_peek_port :
+public sc_core::sc_port< tlm_nonblocking_peek_if< T > , 1 >
+{
+public:
+ typedef tlm_nonblocking_peek_if<T> peek_if_type;
+
+ tlm_nonblocking_peek_port( const char *port_name ) :
+ sc_core::sc_port< tlm_nonblocking_peek_if< T > , 1 >( port_name ) {}
+
+ sc_core::sc_event_finder& ok_to_peek() const {
+
+ return *new tlm_event_finder_t< peek_if_type , T >(
+ *this,
+ &peek_if_type::ok_to_peek );
+
+ }
+
+};
+
+
+template < typename T >
+class tlm_nonblocking_put_port :
+public sc_core::sc_port< tlm_nonblocking_put_if< T > , 1 >
+{
+public:
+ typedef tlm_nonblocking_put_if<T> put_if_type;
+
+ tlm_nonblocking_put_port( const char *port_name ) :
+ sc_core::sc_port< tlm_nonblocking_put_if< T > , 1 >( port_name ) {}
+
+ sc_core::sc_event_finder& ok_to_put() const {
+
+ return *new tlm_event_finder_t< put_if_type , T >(
+ *this,
+ &put_if_type::ok_to_put );
+
+ }
+
+};
+
+} // namespace tlm
+
+#endif
diff --git a/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_req_rsp.h b/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_req_rsp.h
new file mode 100644
index 000000000..88f1d0e8c
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_1/tlm_req_rsp/tlm_req_rsp.h
@@ -0,0 +1,37 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#ifndef __TLM_REQ_RSP_H__
+#define __TLM_REQ_RSP_H__
+
+// The unannotated TLM interfaces
+
+#include "tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_core_ifs.h"
+#include "tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_master_slave_ifs.h"
+
+// The channels : tlm_fifo, tlm_transport_channel and tlm_req_rsp_channel
+
+#include "tlm_core/tlm_1/tlm_req_rsp/tlm_channels/tlm_req_rsp_channels/tlm_req_rsp_channels.h"
+
+// Some non blocking ports to provide static sensitivity
+
+#include "tlm_core/tlm_1/tlm_req_rsp/tlm_ports/tlm_nonblocking_port.h"
+
+
+#endif /* __TLM_REQ_RSP_H__ */
diff --git a/ext/systemc/src/tlm_core/tlm_2/README.txt b/ext/systemc/src/tlm_core/tlm_2/README.txt
new file mode 100644
index 000000000..cb02af2d8
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_2/README.txt
@@ -0,0 +1,111 @@
+TLM-2.0 interoperability layer header files
+===========================================
+
+Dir: include/tlm_core/tlm_2/
+
+SubDirs: tlm_2_interfaces/
+ tlm_generic_payload/
+ tlm_quantum/
+ tlm_sockets
+
+Files: README.txt
+ tlm_version.h
+
+
+Comments
+========
+
+User code should only #include the tlm or tlm.h header file in the include/
+directory and avoid including any of the include files in this directory
+directly. All objects defined in this file hierarchy are in the tlm namespace.
+
+tlm_version.h contains the definitions for the version string and integer values
+
+The header files are organizated, by subdirectory, as follows:
+
+
+tlm_2_interfaces/
+-----------------
+
+Contains the TLM-2.0 core interfaces
+
+Files:
+ tlm_2_interfaces.h (includes the other header files in this directory )
+ tlm_fw_bw_ifs.h (defines the TLM 2.0 interface API's:
+ tlm_fw_nonblocking_transport_if
+ tlm_bw_nonblocking_transport_if
+ tlm_blocking_transport_if
+ tlm_fw_direct_mem_if
+ tlm_bw_direct_mem_if
+ tlm_transport_dbg_if
+ the enumeration type
+ tlm_sync_enum
+ and the TLM 2.0 standard interfaces using the API's
+ tlm_fw_transport_if
+ tlm_bw_transport_if )
+ tlm_dmi.h (defines tlm_dmi)
+
+
+tlm_generic_payload/
+--------------------
+
+Contains the TLM-2.0 generic payload and associated classes and helper functions
+
+Files:
+ tlm_generic_payload.h ( includes the other header files in this directory)
+ tlm_gp.h (defines the TLM 2.0 generic payload classes:
+ tlm_generic_payload
+ tlm_extension
+ tlm_extension_base
+ tlm_mm_interface
+ and the enumeration types
+ tlm_command
+ tlm_response_status )
+ tlm_array.h (defines array class used by the extention
+ mechanism )
+ tlm_endian_conv.h (defines the implementation for the endianness
+ helper functions:
+ tlm_to_hostendian_generic()
+ tlm_from_hostendian_generic()
+ tlm_to_hostendian_word()
+ tlm_from_hostendian_word()
+ tlm_to_hostendian_aligned()
+ tlm_from_hostendian_aligned()
+ tlm_to_hostendian_single()
+ tlm_from_hostendian_single() )
+
+ tlm_helpers.h (defines the helper functions to determine the
+ hostendianness:
+ get_host_endianness()
+ host_has_little_endianness()
+ has_host_endianness()
+ and defines the enumeration type:
+ tlm_endianness
+ tlm_phase.h (defines tlm_phase as an extendable enum type)
+
+
+tlm_sockets/
+------------
+
+Contains the standard TLM-2.0 initiator and target sockets (which are used as
+the base classes for the convenience sockets in tlm_utils)
+
+Files:
+ tlm_sockets.h (includes the other header files in this directory)
+ tlm_initiator_socket.h (defines the initiator sockets:
+ tlm_initiator_socket_base
+ tlm_initiator_socket_b
+ tlm_initiator_socket
+ tlm_target_socket.h (defines the target sockets:
+ tlm_target_socket_base
+ tlm_target_socket_b
+ tlm_target_socket
+
+
+tlm_quantum/
+------------
+This contains the global quantum. (The quantum keeper is in tlm_utils)
+
+Files:
+ tlm_quantum.h ( includes the other header file in this directory )
+ tlm_global_quantum.h ( defines tlm_global_quantum )
diff --git a/ext/systemc/src/tlm_core/tlm_2/tlm_2_interfaces/tlm_2_interfaces.h b/ext/systemc/src/tlm_core/tlm_2/tlm_2_interfaces/tlm_2_interfaces.h
new file mode 100644
index 000000000..8a0c543c8
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_2/tlm_2_interfaces/tlm_2_interfaces.h
@@ -0,0 +1,27 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#ifndef __TLM_2_INTERFACES_H__
+#define __TLM_2_INTERFACES_H__
+
+#include "tlm_core/tlm_2/tlm_2_interfaces/tlm_dmi.h"
+#include "tlm_core/tlm_2/tlm_2_interfaces/tlm_fw_bw_ifs.h"
+
+#endif
+
diff --git a/ext/systemc/src/tlm_core/tlm_2/tlm_2_interfaces/tlm_dmi.h b/ext/systemc/src/tlm_core/tlm_2/tlm_2_interfaces/tlm_dmi.h
new file mode 100644
index 000000000..d7c3304eb
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_2/tlm_2_interfaces/tlm_dmi.h
@@ -0,0 +1,114 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#ifndef __TLM_DMI_H__
+#define __TLM_DMI_H__
+
+#include <systemc>
+
+namespace tlm {
+
+class tlm_dmi
+{
+ public:
+
+ // Enum for indicating the access granted to the initiator.
+ // The initiator uses gp.m_command to indicate it intention (read/write)
+ // The target is allowed to promote DMI_ACCESS_READ or DMI_ACCESS_WRITE
+ // requests to dmi_access_read_write.
+
+ enum dmi_access_e
+ { DMI_ACCESS_NONE = 0x00 // no access
+ , DMI_ACCESS_READ = 0x01 // read access
+ , DMI_ACCESS_WRITE = 0x02 // write access
+ , DMI_ACCESS_READ_WRITE = DMI_ACCESS_READ | DMI_ACCESS_WRITE // read/write access
+ };
+
+ tlm_dmi (void)
+ {
+ init();
+ }
+
+ void init (void)
+ {
+ m_dmi_ptr = 0x0;
+ m_dmi_start_address = 0x0;
+ m_dmi_end_address = (sc_dt::uint64)(-1);
+ m_dmi_access = DMI_ACCESS_NONE;
+ m_dmi_read_latency = sc_core::SC_ZERO_TIME;
+ m_dmi_write_latency = sc_core::SC_ZERO_TIME;
+ }
+
+ unsigned char* get_dmi_ptr (void) const {return m_dmi_ptr;}
+ sc_dt::uint64 get_start_address (void) const {return m_dmi_start_address;}
+ sc_dt::uint64 get_end_address (void) const {return m_dmi_end_address;}
+ sc_core::sc_time get_read_latency (void) const {return m_dmi_read_latency;}
+ sc_core::sc_time get_write_latency (void) const {return m_dmi_write_latency;}
+ dmi_access_e get_granted_access (void) const {return m_dmi_access;}
+ bool is_none_allowed (void) const {return m_dmi_access == DMI_ACCESS_NONE;}
+ bool is_read_allowed (void) const {return (m_dmi_access & DMI_ACCESS_READ) == DMI_ACCESS_READ;}
+ bool is_write_allowed (void) const {return (m_dmi_access & DMI_ACCESS_WRITE) == DMI_ACCESS_WRITE;}
+ bool is_read_write_allowed (void) const {return (m_dmi_access & DMI_ACCESS_READ_WRITE) == DMI_ACCESS_READ_WRITE;}
+
+ void set_dmi_ptr (unsigned char* p) {m_dmi_ptr = p;}
+ void set_start_address (sc_dt::uint64 addr) {m_dmi_start_address = addr;}
+ void set_end_address (sc_dt::uint64 addr) {m_dmi_end_address = addr;}
+ void set_read_latency (sc_core::sc_time t) {m_dmi_read_latency = t;}
+ void set_write_latency (sc_core::sc_time t) {m_dmi_write_latency = t;}
+ void set_granted_access (dmi_access_e a) {m_dmi_access = a;}
+ void allow_none (void) {m_dmi_access = DMI_ACCESS_NONE;}
+ void allow_read (void) {m_dmi_access = DMI_ACCESS_READ;}
+ void allow_write (void) {m_dmi_access = DMI_ACCESS_WRITE;}
+ void allow_read_write (void) {m_dmi_access = DMI_ACCESS_READ_WRITE;}
+
+ private:
+
+ // If the forward call is successful, the target returns the dmi_ptr,
+ // which must point to the data element corresponding to the
+ // dmi_start_address. The data is organized as a byte array with the
+ // endianness of the target (endianness member of the tlm_dmi struct).
+
+ unsigned char* m_dmi_ptr;
+
+ // The absolute start and end addresses of the DMI region. If the decoder
+ // logic in the interconnect changes the address field e.g. by masking, the
+ // interconnect is responsible to transform the relative address back to an
+ // absolute address again.
+
+ sc_dt::uint64 m_dmi_start_address;
+ sc_dt::uint64 m_dmi_end_address;
+
+ // Granted access
+
+ dmi_access_e m_dmi_access;
+
+ // These members define the latency of read/write transactions. The
+ // initiator must initialize these members to zero before requesting a
+ // dmi pointer, because both the interconnect as well as the target can
+ // add to the total transaction latency.
+ // Depending on the 'type' attribute only one, or both of these attributes
+ // will be valid.
+
+ sc_core::sc_time m_dmi_read_latency;
+ sc_core::sc_time m_dmi_write_latency;
+};
+
+} // namespace tlm
+
+#endif /* TLM_DMI_HEADER */
diff --git a/ext/systemc/src/tlm_core/tlm_2/tlm_2_interfaces/tlm_fw_bw_ifs.h b/ext/systemc/src/tlm_core/tlm_2/tlm_2_interfaces/tlm_fw_bw_ifs.h
new file mode 100644
index 000000000..59e81c658
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_2/tlm_2_interfaces/tlm_fw_bw_ifs.h
@@ -0,0 +1,223 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#ifndef __TLM_FW_BW_IFS_H__
+#define __TLM_FW_BW_IFS_H__
+
+#include <systemc>
+#include "tlm_core/tlm_2/tlm_generic_payload/tlm_generic_payload.h"
+#include "tlm_core/tlm_2/tlm_2_interfaces/tlm_dmi.h"
+
+namespace tlm {
+
+enum tlm_sync_enum { TLM_ACCEPTED, TLM_UPDATED, TLM_COMPLETED };
+
+////////////////////////////////////////////////////////////////////////////
+// Basic interfaces
+////////////////////////////////////////////////////////////////////////////
+template <typename TRANS = tlm_generic_payload,
+ typename PHASE = tlm_phase>
+class tlm_fw_nonblocking_transport_if : public virtual sc_core::sc_interface {
+public:
+ virtual tlm_sync_enum nb_transport_fw(TRANS& trans,
+ PHASE& phase,
+ sc_core::sc_time& t) = 0;
+};
+
+template <typename TRANS = tlm_generic_payload,
+ typename PHASE = tlm_phase>
+class tlm_bw_nonblocking_transport_if : public virtual sc_core::sc_interface {
+public:
+ virtual tlm_sync_enum nb_transport_bw(TRANS& trans,
+ PHASE& phase,
+ sc_core::sc_time& t) = 0;
+};
+
+template <typename TRANS = tlm_generic_payload>
+class tlm_blocking_transport_if : public virtual sc_core::sc_interface {
+public:
+ virtual void b_transport(TRANS& trans,
+ sc_core::sc_time& t) = 0;
+};
+
+//////////////////////////////////////////////////////////////////////////
+// DMI interfaces for getting and invalidating DMI pointers:
+//////////////////////////////////////////////////////////////////////////
+
+// The semantics of the forward interface are as follows:
+//
+// - An initiator that wants to get direct access to a target's memory region
+// can call the get_direct_mem_ptr method with the 'trans' parameter set to
+// the address that it wants to gain access to. It sets the trans.m_command
+// to specify if the initiator intended use (read or write)
+// to the target's DMI region. The initiator is responsible for calling the
+// method with a freshly initialized tlm_dmi object either by using a newly
+// constructed object, or by calling an existing object's init() method.
+// - Although a reference to a complete 'TRANS' type is passed to the get_
+// direct_mem_ptr call, only the address command, and extension fields are of
+// interest in most cases.
+// - Read and write ranges are not necessarily identical. If they are, a target
+// can specify that the range is valid for all accesses with the tlm_data
+// m_type attribute in the.
+// - The interconnect, if any, needs to decode the address and forward the
+// call to the corresponding target. It needs to handle the address exactly
+// as the target would expect on a transaction call, e.g. mask the address
+// according to the target's address width.
+// - If the target supports DMI access for the given address, it sets the
+// data fields in the DMI struct and returns true.
+// - If a target does not support DMI access it needs to return false.
+// The target can either set the correct address range in the DMI struct
+// to indicate the memory region where DMI is disallowed, or it can specify
+// the complete address range if it doesn't know it's memory range. In this
+// case the interconnect is responsible for clipping the address range to
+// the correct range that the target serves.
+// - The interconnect must always translate the addresses to the initiator's
+// address space. This must be the inverse operation of what the
+// interconnect needed to do when forwarding the call. In case the
+// component wants to change any member of the tlm_dmi object, e.g. for
+// its own latency to the target's latency, it must only do so *after* the
+// target has been called. The target is always allowed to overwrite all
+// values in the tlm_dmi object.
+// - In case the slave returned with an invalid region the bus/interconnect
+// must fill in the complete address region for the particular slave in the
+// DMI data structure.
+//
+// DMI hint optimization:
+//
+// Initiators may use the DMI hint in the tlm_generic_payload to avoid
+// unnecessary DMI attempts. The recommended sequence of interface
+// method calls would be:
+//
+// - The initiator first tries to check if it has a valid DMI region for the
+// address that it wants to access next.
+// - If not, it performs a normal transaction.
+// - If the DMI hint in this transaction is true, the initiator can try and
+// get the DMI region.
+//
+// Note that the DMI hint optimization is completely optional and every
+// initiator model is free to ignore the DMI hint. However, a target is
+// required to set the DMI hint to true if a DMI request on the given address
+// with the given transaction type (read or write) would have succeeded.
+
+template <typename TRANS = tlm_generic_payload>
+class tlm_fw_direct_mem_if : public virtual sc_core::sc_interface
+{
+public:
+ virtual bool get_direct_mem_ptr(TRANS& trans,
+ tlm_dmi& dmi_data) = 0;
+};
+
+// The semantics of the backwards call is as follows:
+//
+// - An interconnect component or a target is required to invalidate all
+// affected DMI regions whenever any change in the regions take place.
+// The exact rule is that a component must invalidate all those DMI regions
+// that it already reported, if it would answer the same DMI request
+// with any member of the tlm_dmi data structure set differently.
+// - An interconnect component must forward the invalidate_direct_mem_ptr call
+// to all initiators that could potentially have a DMI pointer to the region
+// specified in the method arguments. A safe implementation is to call
+// every attached initiator.
+// - An interconnect component must transform the address region of an
+// incoming invalidate_direct_mem_ptr to the corresponding address space
+// for the initiators. Basically, this is the same address transformation
+// that the interconnect does on the DMI ranges on the forward direction.
+// - Each initiator must check if it has a pointer to the given region and
+// throw this away. It is recommended that the initiator throws away all DMI
+// regions that have any overlap with the given regions, but this is not a
+// hard requirement.
+//
+// - A full DMI pointer invalidation, e.g. for a bus remap can be signaled
+// by setting the range: 0x0 - 0xffffffffffffffffull = (sc_dt::uint64)-1
+// - An initiator must throw away all DMI pointers in this case.
+//
+// - Under no circumstances a model is allowed to call the get_direct_mem_ptr
+// from within the invalidate_direct_mem_ptr method, directly or indirectly.
+//
+class tlm_bw_direct_mem_if : public virtual sc_core::sc_interface
+{
+public:
+ virtual void invalidate_direct_mem_ptr(sc_dt::uint64 start_range,
+ sc_dt::uint64 end_range) = 0;
+};
+
+/////////////////////////////////////////////////////////////////////
+// debug interface for memory access
+/////////////////////////////////////////////////////////////////////
+//
+// This interface can be used to gain access to a targets memory or registers
+// in a non-intrusive manner. No side effects, waits or event notifications
+// must happen in the course of the method.
+//
+// Semantics:
+// - The initiator calls the transport_dbg method with transaction 'trans' as
+// argument. The commonly used parts of trans for debug are:
+// . address: The start address that it wants to peek or poke.
+// . length: The number of bytes that it requests to read or write.
+// . command: Indicates a read or write access.
+// . data: A pointer to the initiator-allocated data buffer, which must
+// be at least num_bytes large. The data is always organized in
+// the endianness of the machine.
+// . extensions: Any extension that could affect the transaction.
+// - The interconnect, if any, will decode the address and forward the call to
+// the appropriate target.
+// - The target must return the number of successfully transmitted bytes, where
+// this number must be <= num_bytes. Thus, a target can safely return 0 if it
+// does not support debug transactions.
+//
+template <typename TRANS = tlm_generic_payload>
+class tlm_transport_dbg_if : public virtual sc_core::sc_interface
+{
+public:
+ // The return value of defines the number of bytes successfully
+ // transferred.
+ virtual unsigned int transport_dbg(TRANS& trans) = 0;
+};
+
+////////////////////////////////////////////////////////////////////////////
+// Combined interfaces
+////////////////////////////////////////////////////////////////////////////
+
+struct tlm_base_protocol_types
+{
+ typedef tlm_generic_payload tlm_payload_type;
+ typedef tlm_phase tlm_phase_type;
+};
+
+// The forward interface:
+template <typename TYPES = tlm_base_protocol_types>
+class tlm_fw_transport_if
+ : public virtual tlm_fw_nonblocking_transport_if<typename TYPES::tlm_payload_type,
+ typename TYPES::tlm_phase_type>
+ , public virtual tlm_blocking_transport_if<typename TYPES::tlm_payload_type>
+ , public virtual tlm_fw_direct_mem_if<typename TYPES::tlm_payload_type>
+ , public virtual tlm_transport_dbg_if<typename TYPES::tlm_payload_type>
+{};
+
+// The backward interface:
+template <typename TYPES = tlm_base_protocol_types>
+class tlm_bw_transport_if
+ : public virtual tlm_bw_nonblocking_transport_if<typename TYPES::tlm_payload_type,
+ typename TYPES::tlm_phase_type>
+ , public virtual tlm_bw_direct_mem_if
+{};
+
+} // namespace tlm
+
+#endif /* __TLM_FW_BW_IFS_H__ */
diff --git a/ext/systemc/src/tlm_core/tlm_2/tlm_generic_payload/tlm_array.h b/ext/systemc/src/tlm_core/tlm_2/tlm_generic_payload/tlm_array.h
new file mode 100644
index 000000000..297dd3fe4
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_2/tlm_generic_payload/tlm_array.h
@@ -0,0 +1,125 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#ifndef __TLM_ARRAY_H__
+#define __TLM_ARRAY_H__
+
+#include <systemc>
+#include <exception>
+// unused for the time being: #include <cassert>
+
+namespace tlm {
+
+//
+// To the LRM writer: the below class is an artifact of the tlm_generic_payload
+// implementation and not part of the core TLM standard
+//
+
+
+// This implements a lean and fast array class that supports array expansion on
+// request. The class is primarily used in the tlm_generic_payload class for
+// storing the pointers to the extensions.
+//
+// Individual array elements can be accessed through the [] operators, and the
+// array length is returned by the size() method.
+//
+// The size can be dynamically expanded using the expand(uint) method. There
+// is no shrinking mechanism implemented, because the extension mechanism
+// does not require this feature. Bear in mind that calling the expand method
+// may invalidate all direct pointers into the array.
+
+
+//the tlm_array shall always be used with T=tlm_extension_base*
+template <typename T>
+class tlm_array
+ : private std::vector<T>
+{
+ typedef std::vector<T> base_type;
+ typedef typename base_type::size_type size_type;
+public:
+
+ // constructor:
+ tlm_array(size_type size = 0, T const & default_value = T() )
+ : base_type(size,default_value)
+ , m_entries()
+ , m_default(default_value)
+ {
+ //m_entries.reserve(size); // optional
+ }
+
+ // copy constructor:
+ // tlm_array(const tlm_array& orig) = default;
+
+ // destructor:
+ // ~tlm_array() = default;
+
+ // operators for dereferencing:
+ using base_type::operator[];
+
+ // array size:
+ using base_type::size;
+
+ // expand the array if needed:
+ void expand(size_type new_size)
+ {
+ if (new_size > size())
+ {
+ base_type::resize(new_size);
+ //m_entries.reserve(new_size); // optional
+ }
+ }
+
+ static const char* const kind_string;
+ const char* kind() const { return kind_string; }
+
+ //this function shall get a pointer to a array slot
+ // it stores this slot in a cache of active slots
+ void insert_in_cache(T* p)
+ {
+ //assert( (p-&(*this)[0]) < size() );
+ m_entries.push_back( p-&(*this)[0] );
+ }
+
+ //this functions clears all active slots of the array
+ void free_entire_cache()
+ {
+ while(m_entries.size())
+ {
+ if ((*this)[m_entries.back()]) //we make sure no one cleared the slot manually
+ (*this)[m_entries.back()]->free();//...and then we call free on the content of the slot
+ (*this)[m_entries.back()]=0; //afterwards we set the slot to NULL
+ m_entries.pop_back();
+ }
+ }
+
+protected:
+ std::vector<size_type> m_entries;
+ T m_default;
+
+ // disabled:
+ tlm_array& operator=(const tlm_array<T>&);
+};
+
+
+template <typename T>
+const char* const tlm_array<T>::kind_string = "tlm_array";
+
+} // namespace tlm
+
+#endif /* __TLM_ARRAY_H__ */
diff --git a/ext/systemc/src/tlm_core/tlm_2/tlm_generic_payload/tlm_endian_conv.h b/ext/systemc/src/tlm_core/tlm_2/tlm_generic_payload/tlm_endian_conv.h
new file mode 100644
index 000000000..648115554
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_2/tlm_generic_payload/tlm_endian_conv.h
@@ -0,0 +1,792 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+
+#ifndef __TLM_ENDIAN_CONV_H__
+#define __TLM_ENDIAN_CONV_H__
+
+#include <systemc>
+#include "tlm_core/tlm_2/tlm_generic_payload/tlm_gp.h"
+
+
+namespace tlm {
+
+
+/*
+Tranaction-Level Modelling
+Endianness Helper Functions
+
+DESCRIPTION
+A set of functions for helping users to get the endianness
+right in their TLM models of system initiators. These functions are
+for use within an initiator. They can not be used as-is outside
+an initiator because the extension used to store context will not work
+if cascaded, and they do not respect the generic payload mutability
+rules. However this code may be easily copied and adapted for use
+in bridges, etc..
+
+These functions are not compulsory. There are other legitimate ways to
+achieve the same functionality. If extra information is available at
+compile time about the nature of an initiator's transactions, this can
+be exploited to accelerate simulations by creating further functions
+similar to those in this file. In general a functional transaction can be
+described in more than one way by a TLM-2 GP object.
+
+The functions convert the endianness of a GP object, either on request or
+response. They should only be used when the initiator's endianness
+does not match the host's endianness. They assume 'arithmetic mode'
+meaning that within a data word the byte order is always host-endian.
+For non-arithmetic mode initiators they can be used with a data word
+size of 1 byte.
+
+All the functions are templates, for example:
+
+template<class DATAWORD> inline void
+ to_hostendian_generic(tlm_generic_payload *txn, int sizeof_databus)
+
+The template parameter provides the data word width. Having this as a class
+makes it easy to use it for copy and swap operations within the functions.
+If the assignment operator for this class is overloaded, the endianness
+conversion function may not have the desired effect.
+
+All the functions have the same signature except for different names.
+
+The principle is that a function to_hostendian_convtype() is called when the
+initiator-endian transaction is created, and the matching function
+from_hostendian_convtype() is called when the transaction is completed, for
+example before read data can be used. In some cases the from_ function is
+redundant but an empty function is provided anyway. It is strongly
+recommended that the from_ function is called, in case it ceases to be
+redundant in future versions of this code.
+
+No context needs to be managed outside the two functions, except that they
+must be called with the same template parameter and the same bus width.
+
+For initiator models that can not easily manage this context information,
+a single entry point for the from_ function is provided, which will be
+a little slower than calling the correct from_ function directly, as
+it can not be inlined.
+
+All functions assume power-of-2 bus and data word widths.
+
+Functions offered:
+
+0) A pair of functions that work for almost all TLM2 GP transactions. The
+only limitations are that data and bus widths should be powers of 2, and that
+the data length should be an integer number of streaming widths and that the
+streaming width should be an integer number of data words.
+These functions always allocate new data and byte enable buffers and copy
+data one byte at a time.
+ tlm_to_hostendian_generic(tlm_generic_payload *txn, int sizeof_databus)
+ tlm_from_hostendian_generic(tlm_generic_payload *txn, int sizeof_databus)
+
+1) A pair of functions that work for all transactions regardless of data and
+bus data sizes and address alignment except for the the following
+limitations:
+- byte-enables are supported only when byte-enable granularity is no finer
+than the data word (every data word is wholly enabled or wholly disabled)
+- byte-enable-length is not supported (if byte enables are present, the byte
+enable length must be equal to the data length).
+- streaming width is not supported
+- data word wider than bus word is not supported
+A new data buffer and a new byte enable buffer are always allocated. Byte
+enables are assumed to be needed even if not required for the original
+(unconverted) transaction. Data is copied to the new buffer on request
+(for writes) or on response (for reads). Copies are done word-by-word
+where possible.
+ tlm_to_hostendian_word(tlm_generic_payload *txn, int sizeof_databus)
+ tlm_from_hostendian_word(tlm_generic_payload *txn, int sizeof_databus)
+
+2) If the original transaction is both word and bus-aligned then this pair of
+functions can be used. It will complete faster than the generic function
+because the data reordering function is much simpler and no address
+conversion is required.
+The following limitations apply:
+- byte-enables are supported only when byte-enable granularity is no finer
+than the data word (every data word is wholly enabled or wholly disabled)
+- byte-enable-length is not supported (if byte enables are present, the byte
+enable length must be equal to the data length).
+- streaming width is not supported
+- data word wider than bus word is not supported
+- the transaction must be an integer number of bus words
+- the address must be aligned to the bus width
+ tlm_to_hostendian_aligned(tlm_generic_payload *txn, int sizeof_databus)
+ tlm_from_hostendian_aligned(tlm_generic_payload *txn, int sizeof_databus)
+
+3) For single word transactions that don't cross a bus word boundary it
+is always safe to work in-place and the conversion is very simple. Again,
+streaming width and byte-enable length are not supported, and byte-enables
+may not changes within a data word.
+ tlm_to_hostendian_single(tlm_generic_payload *txn, int sizeof_databus)
+ tlm_from_hostendian_single(tlm_generic_payload *txn, int sizeof_databus)
+
+4) A single entry point for accessing the correct from_ function without
+needing to store context.
+ tlm_from_hostendian(tlm_generic_payload *txn)
+*/
+
+
+
+#ifndef uchar
+#define uchar unsigned char
+#else
+#define TLM_END_CONV_DONT_UNDEF_UCHAR
+#endif
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Generic Utilities
+
+class tlm_endian_context;
+class tlm_endian_context_pool {
+ public:
+ tlm_endian_context *first;
+ inline tlm_endian_context_pool();
+ inline ~tlm_endian_context_pool();
+ inline tlm_endian_context *pop();
+ inline void push(tlm_endian_context *c);
+};
+static tlm_endian_context_pool global_tlm_endian_context_pool;
+
+// an extension to keep the information needed for reconversion of response
+class tlm_endian_context : public tlm_extension<tlm_endian_context> {
+ public:
+ tlm_endian_context() : dbuf_size(0), bebuf_size(0) {}
+ ~tlm_endian_context() {
+ if(dbuf_size > 0) delete [] new_dbuf;
+ if(bebuf_size > 0) delete [] new_bebuf;
+ }
+
+ sc_dt::uint64 address; // used by generic, word
+ sc_dt::uint64 new_address; // used by generic
+ uchar *data_ptr; // used by generic, word, aligned
+ uchar *byte_enable; // used by word
+ int length; // used by generic, word
+ int stream_width; // used by generic
+
+ // used by common entry point on response
+ void (*from_f)(tlm_generic_payload *txn, unsigned int sizeof_databus);
+ int sizeof_databus;
+
+ // reordering buffers for data and byte-enables
+ uchar *new_dbuf, *new_bebuf;
+ int dbuf_size, bebuf_size;
+ void establish_dbuf(int len) {
+ if(len <= dbuf_size) return;
+ if(dbuf_size > 0) delete [] new_dbuf;
+ new_dbuf = new uchar[len];
+ dbuf_size = len;
+ }
+ void establish_bebuf(int len) {
+ if(len <= bebuf_size) return;
+ if(bebuf_size > 0) delete [] new_bebuf;
+ new_bebuf = new uchar[len];
+ bebuf_size = len;
+ }
+
+ // required for extension management
+ void free() {
+ global_tlm_endian_context_pool.push(this);
+ }
+ tlm_extension_base* clone() const {return 0;}
+ void copy_from(tlm_extension_base const &) {return;}
+
+ // for pooling
+ tlm_endian_context *next;
+};
+// Assumptions about transaction contexts:
+// 1) only the address attribute of a transaction
+// is mutable. all other attributes are unchanged from the request to
+// response side conversion.
+// 2) the conversion functions in this file do not respect the mutability
+// rules and do not put the transaction back into its original state after
+// completion. so if the initiator has any cleaning up to do (eg of byte
+// enable buffers), it needs to store its own context. the transaction
+// returned to the initiator may contain pointers to data and byte enable
+// that can/must not be deleted.
+// 3) the conversion functions in this file use an extension to store
+// context information. they do not remove this extension. the initiator
+// should not remove it unless it deletes the generic payload
+// object.
+
+inline tlm_endian_context *establish_context(tlm_generic_payload *txn) {
+ tlm_endian_context *tc = txn->get_extension<tlm_endian_context>();
+ if(tc == 0) {
+ tc = global_tlm_endian_context_pool.pop();
+ txn->set_extension(tc);
+ }
+ return tc;
+}
+
+inline tlm_endian_context_pool::tlm_endian_context_pool() : first(0) {}
+
+inline tlm_endian_context_pool::~tlm_endian_context_pool() {
+ while(first != 0) {
+ tlm_endian_context *next = first->next;
+ delete first;
+ first = next;
+ }
+}
+
+tlm_endian_context *tlm_endian_context_pool::pop() {
+ if(first == 0) return new tlm_endian_context;
+ tlm_endian_context *r = first;
+ first = first->next;
+ return r;
+}
+
+void tlm_endian_context_pool::push(tlm_endian_context *c) {
+ c->next = first;
+ first = c;
+}
+
+
+// a set of constants for efficient filling of byte enables
+template<class D> class tlm_bool {
+ public:
+ static D TLM_TRUE;
+ static D TLM_FALSE;
+ static D make_uchar_array(uchar c) {
+ D d;
+ uchar *tmp = (uchar *)(&d);
+ for(ptrdiff_t i=0; i!=sizeof(D); i++) tmp[i] = c; // 64BITFIX negligable risk but easy fix //
+ return d;
+ }
+ // also provides an syntax-efficient tester, using a
+ // copy constuctor and an implicit cast to boolean
+ tlm_bool(D &d) : b(*((uchar*)&d) != TLM_BYTE_DISABLED) {}
+ operator bool() const {return b;}
+ private:
+ bool b;
+};
+
+template<class D> D tlm_bool<D>::TLM_TRUE
+ = tlm_bool<D>::make_uchar_array(TLM_BYTE_ENABLED);
+template<class D> D tlm_bool<D>::TLM_FALSE
+ = tlm_bool<D>::make_uchar_array(TLM_BYTE_DISABLED);
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// function set (0): Utilities
+inline void copy_db0(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2) {
+ *dest1 = *src1;
+ *dest2 = *src2;
+}
+
+inline void copy_dbtrue0(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2) {
+ *dest1 = *src1;
+ *dest2 = TLM_BYTE_ENABLED;
+}
+
+inline void copy_btrue0(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2) {
+ *dest2 = TLM_BYTE_ENABLED;
+}
+
+inline void copy_b0(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2) {
+ *dest2 = *src2;
+}
+
+inline void copy_dbyb0(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2) {
+ if(*dest2 == TLM_BYTE_ENABLED) *src1 = *dest1;
+}
+
+
+template<class D,
+ void COPY(uchar *he_d, uchar *he_b, uchar *ie_d, uchar *ie_b)>
+inline void loop_generic0(int new_len, int new_stream_width,
+ int orig_stream_width, int sizeof_databus,
+ sc_dt::uint64 orig_start_address, sc_dt::uint64 new_start_address, int be_length,
+ uchar *ie_data, uchar *ie_be, uchar *he_data, uchar *he_be) {
+
+ for(int orig_sword = 0, new_sword = 0; new_sword < new_len;
+ new_sword += new_stream_width, orig_sword += orig_stream_width) {
+
+ sc_dt::uint64 ie_addr = orig_start_address;
+ for(int orig_dword = orig_sword;
+ orig_dword < orig_sword + orig_stream_width; orig_dword += sizeof(D)) {
+
+ for(int curr_byte = orig_dword + sizeof(D) - 1;
+ curr_byte >= orig_dword; curr_byte--) {
+
+ ptrdiff_t he_index = ((ie_addr++) ^ (sizeof_databus - 1))
+ - new_start_address + new_sword; // 64BITFIX //
+ COPY(ie_data+curr_byte,
+ ie_be+(curr_byte % be_length), // 64BITRISK no risk of overflow, always positive //
+ he_data+he_index, he_be+he_index);
+ }
+ }
+ }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// function set (0): Response
+template<class DATAWORD> inline void
+tlm_from_hostendian_generic(tlm_generic_payload *txn, unsigned int sizeof_databus) {
+ if(txn->is_read()) {
+ tlm_endian_context *tc = txn->template get_extension<tlm_endian_context>();
+ loop_generic0<DATAWORD, &copy_dbyb0>(txn->get_data_length(),
+ txn->get_streaming_width(), tc->stream_width, sizeof_databus, tc->address,
+ tc->new_address, txn->get_data_length(), tc->data_ptr, 0, txn->get_data_ptr(),
+ txn->get_byte_enable_ptr());
+ }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// function set (0): Request
+template<class DATAWORD> inline void
+tlm_to_hostendian_generic(tlm_generic_payload *txn, unsigned int sizeof_databus) {
+ tlm_endian_context *tc = establish_context(txn);
+ tc->from_f = &(tlm_from_hostendian_generic<DATAWORD>);
+ tc->sizeof_databus = sizeof_databus;
+
+ // calculate new size: nr stream words multiplied by big enough stream width
+ int s_width = txn->get_streaming_width();
+ int length = txn->get_data_length();
+ if(s_width >= length) s_width = length;
+ int nr_stream_words = length/s_width;
+
+ // find out in which bus word the stream word starts and ends
+ sc_dt::uint64 new_address = (txn->get_address() & ~(sizeof_databus - 1));
+ sc_dt::uint64 end_address = ((txn->get_address() + s_width - 1)
+ & ~(sizeof_databus - 1));
+
+ int new_stream_width = end_address - new_address + sizeof_databus;
+ int new_length = new_stream_width * nr_stream_words;
+
+ // store context
+ tc->data_ptr = txn->get_data_ptr();
+ tc->address = txn->get_address();
+ tc->new_address = new_address;
+ tc->stream_width = s_width;
+ uchar *orig_be = txn->get_byte_enable_ptr();
+ int orig_be_length = txn->get_byte_enable_length();
+
+ // create data and byte-enable buffers
+ txn->set_address(new_address);
+ tc->establish_dbuf(new_length);
+ txn->set_data_ptr(tc->new_dbuf);
+ tc->establish_bebuf(new_length);
+ txn->set_byte_enable_ptr(tc->new_bebuf);
+ memset(txn->get_byte_enable_ptr(), TLM_BYTE_DISABLED, new_length);
+ txn->set_streaming_width(new_stream_width);
+ txn->set_data_length(new_length);
+ txn->set_byte_enable_length(new_length);
+
+ // copy data and/or byte enables
+ if(txn->is_write()) {
+ if(orig_be == 0) {
+ loop_generic0<DATAWORD, &copy_dbtrue0>(new_length,
+ new_stream_width, s_width, sizeof_databus, tc->address,
+ new_address, new_length, tc->data_ptr, 0, txn->get_data_ptr(),
+ txn->get_byte_enable_ptr());
+ } else {
+ loop_generic0<DATAWORD, &copy_db0>(new_length,
+ new_stream_width, s_width, sizeof_databus, tc->address,
+ new_address, orig_be_length, tc->data_ptr, orig_be, txn->get_data_ptr(),
+ txn->get_byte_enable_ptr());
+ }
+ } else { // read transaction
+ if(orig_be == 0) {
+ loop_generic0<DATAWORD, &copy_btrue0>(new_length,
+ new_stream_width, s_width, sizeof_databus, tc->address,
+ new_address, new_length, tc->data_ptr, 0, txn->get_data_ptr(),
+ txn->get_byte_enable_ptr());
+ } else {
+ loop_generic0<DATAWORD, &copy_b0>(new_length,
+ new_stream_width, s_width, sizeof_databus, tc->address,
+ new_address, orig_be_length, tc->data_ptr, orig_be, txn->get_data_ptr(),
+ txn->get_byte_enable_ptr());
+ }
+ }
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// function set (1): Utilities
+template<class D>
+inline void copy_d1(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2) {
+ *((D *)dest1) = *((D *)src1);
+ *((D *)dest2) = tlm_bool<D>::TLM_TRUE;
+}
+
+template<class D>
+inline void copy_db1(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2) {
+ *((D *)dest1) = *((D *)src1);
+ *((D *)dest2) = *((D *)src2);
+}
+
+template<class D>
+inline void true_b1(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2) {
+ *((D *)dest2) = tlm_bool<D>::TLM_TRUE;
+}
+
+template<class D>
+inline void copy_b1(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2) {
+ *((D *)dest2) = *((D *)src2);
+}
+
+template<class D>
+inline void copy_dbyb1(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2) {
+ if(*src2 != TLM_BYTE_DISABLED) *((D *)src1) = *((D *)dest1);
+}
+
+template<class D>
+inline void copy_dbytrue1(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2) {
+ *((D *)src1) = *((D *)dest1);
+}
+
+template<class D> inline void false_b1(uchar *dest1) {
+ *((D *)dest1) = tlm_bool<D>::TLM_FALSE;
+}
+
+template<class D> inline void no_b1(uchar *dest1) {
+}
+
+template<class D,
+ void COPY(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2),
+ void COPYuchar(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2),
+ void FILLFALSE(uchar *dest1), void FILLFALSEuchar(uchar *dest1)>
+inline int loop_word1(
+ int bytes_left, int len0, int lenN, int sizeof_databus,
+ uchar *start, uchar *end, uchar *src, uchar *bsrc, uchar *dest, uchar *bdest) {
+ ptrdiff_t d2b_src = bsrc - src; // 64BITFIX was int //
+ ptrdiff_t d2b_dest = bdest - dest; // 64BITFIX was int //
+ uchar *original_dest = dest;
+
+ while(true) {
+ // len0 bytes at start of a bus word
+ if((src >= start) && (src < end)) {
+ for(int i=0; i<len0; i++) {
+ COPYuchar(src, src+d2b_src, dest, dest+d2b_dest);
+ src++;
+ dest++;
+ }
+ bytes_left -= len0;
+ if(bytes_left <= 0) return int(dest - original_dest);
+ } else {
+ for(int i=0; i<len0; i++) {
+ FILLFALSEuchar(dest+d2b_dest);
+ src++;
+ dest++;
+ }
+ }
+ src -= 2 * sizeof(D);
+
+ // sequence of full data word fragments
+ for(unsigned int i=1; i<sizeof_databus/sizeof(D); i++) {
+ if((src >= start) && (src < end)) {
+ COPY(src, src+d2b_src, dest, dest+d2b_dest);
+ bytes_left -= sizeof(D);
+ } else {
+ FILLFALSE(dest+d2b_dest);
+ }
+ dest += sizeof(D);
+ if(bytes_left <= 0) return int(dest - original_dest);
+ src -= sizeof(D);
+ }
+
+ // lenN bytes at end of bus word
+ if((src >= start) && (src < end)) {
+ for(int i=0; i<lenN; i++) {
+ COPYuchar(src, src+d2b_src, dest, dest+d2b_dest);
+ src++;
+ dest++;
+ }
+ bytes_left -= lenN;
+ if(bytes_left <= 0) return int(dest - original_dest);
+ } else {
+ for(int i=0; i<lenN; i++) {
+ FILLFALSEuchar(dest+d2b_dest);
+ src++;
+ dest++;
+ }
+ }
+ src += 2 * sizeof_databus;
+ }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// function set (1): Response
+template<class DATAWORD> inline void
+tlm_from_hostendian_word(tlm_generic_payload *txn, unsigned int sizeof_databus) {
+ if(txn->is_read()) {
+ tlm_endian_context *tc = txn->template get_extension<tlm_endian_context>();
+ sc_dt::uint64 b_mask = sizeof_databus - 1;
+ int d_mask = sizeof(DATAWORD) - 1;
+ int a_offset = static_cast<int>(tc->address & b_mask);
+ int len0 = (sizeof_databus - a_offset) & d_mask;
+ int lenN = sizeof(DATAWORD) - len0;
+ uchar *d_start = tc->data_ptr;
+ uchar *d_end = ptrdiff_t(tc->length) + d_start; // 64BITFIX probably redundant //
+ uchar *d = ptrdiff_t(((sizeof_databus - a_offset) & ~d_mask) + lenN) + d_start; // 64BITFIX probably redundant //
+
+ // iterate over transaction copying data qualified by byte-enables
+ if(tc->byte_enable == 0) {
+ loop_word1<DATAWORD, &copy_dbytrue1<DATAWORD>,
+ &copy_dbytrue1<uchar>, &no_b1<DATAWORD>, &no_b1<uchar> >(
+ tc->length, len0, lenN, sizeof_databus, d_start, d_end, d,
+ 0, txn->get_data_ptr(), 0);
+ } else {
+ loop_word1<DATAWORD, &copy_dbyb1<DATAWORD>,
+ &copy_dbyb1<uchar>, &no_b1<DATAWORD>, &no_b1<uchar> >(
+ tc->length, len0, lenN, sizeof_databus, d_start, d_end, d,
+ tc->byte_enable - d_start + d, txn->get_data_ptr(), 0);
+ }
+ }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// function set (1): Request
+template<class DATAWORD> inline void
+tlm_to_hostendian_word(tlm_generic_payload *txn, unsigned int sizeof_databus) {
+ tlm_endian_context *tc = establish_context(txn);
+ tc->from_f = &(tlm_from_hostendian_word<DATAWORD>);
+ tc->sizeof_databus = sizeof_databus;
+
+ sc_dt::uint64 b_mask = sizeof_databus - 1;
+ int d_mask = sizeof(DATAWORD) - 1;
+ sc_dt::uint64 a_aligned = txn->get_address() & ~b_mask;
+ int a_offset = static_cast<int>(txn->get_address() & b_mask);
+ int len0 = (sizeof_databus - a_offset) & d_mask;
+ int lenN = sizeof(DATAWORD) - len0;
+ uchar *d_start = txn->get_data_ptr();
+ uchar *d_end = ptrdiff_t(txn->get_data_length()) + d_start; // 64BITFIX probably redundant //
+ uchar *d = ptrdiff_t(((sizeof_databus - a_offset) & ~d_mask) + lenN) + d_start; // 64BITFIX probably redundant //
+
+ // create new data and byte enable buffers
+ int long_enough = txn->get_data_length() + 2 * sizeof_databus;
+ tc->establish_dbuf(long_enough);
+ uchar *new_data = tc->new_dbuf;
+ tc->establish_bebuf(long_enough);
+ uchar *new_be = tc->new_bebuf;
+
+ if(txn->is_read()) {
+ tc->data_ptr = d_start;
+ tc->address = txn->get_address();
+ tc->byte_enable = txn->get_byte_enable_ptr();
+ tc->length = txn->get_data_length();
+ if(txn->get_byte_enable_ptr() == 0) {
+ // iterate over transaction creating new byte enables from all-true
+ txn->set_data_length(loop_word1<DATAWORD, &true_b1<DATAWORD>,
+ &true_b1<uchar>, &false_b1<DATAWORD>, &false_b1<uchar> >(
+ txn->get_data_length(), len0, lenN, sizeof_databus,
+ d_start, d_end, d, 0, new_data, new_be));
+ } else {
+ // iterate over transaction copying byte enables
+ txn->set_data_length(loop_word1<DATAWORD, &copy_b1<DATAWORD>,
+ &copy_b1<uchar>, &false_b1<DATAWORD>, &false_b1<uchar> >(
+ txn->get_data_length(), len0, lenN, sizeof_databus, d_start, d_end,
+ d, txn->get_byte_enable_ptr() - d_start + d, new_data, new_be));
+ }
+ } else {
+ // WRITE
+ if(txn->get_byte_enable_ptr() == 0) {
+ // iterate over transaction copying data and creating new byte-enables
+ txn->set_data_length(loop_word1<DATAWORD, &copy_d1<DATAWORD>,
+ &copy_d1<uchar>, &false_b1<DATAWORD>, &false_b1<uchar> >(
+ txn->get_data_length(), len0, lenN, sizeof_databus,
+ d_start, d_end, d, 0, new_data, new_be));
+ } else {
+ // iterate over transaction copying data and byte-enables
+ txn->set_data_length(loop_word1<DATAWORD, &copy_db1<DATAWORD>,
+ &copy_db1<uchar>, &false_b1<DATAWORD>, &false_b1<uchar> >(
+ txn->get_data_length(), len0, lenN, sizeof_databus, d_start, d_end,
+ d, txn->get_byte_enable_ptr() - d_start + d, new_data, new_be));
+ }
+ }
+ txn->set_byte_enable_length(txn->get_data_length());
+ txn->set_streaming_width(txn->get_data_length());
+ txn->set_data_ptr(new_data);
+ txn->set_byte_enable_ptr(new_be);
+ txn->set_address(a_aligned);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// function set (2): Utilities
+template<class D> inline void copy_d2(D *src1, D *src2, D *dest1, D *dest2) {
+ *dest1 = *src1;
+}
+
+template<class D> inline void copy_db2(D *src1, D *src2, D *dest1, D *dest2) {
+ *dest1 = *src1;
+ *dest2 = *src2;
+}
+
+template<class D>
+inline void copy_dbyb2(D *src1, D *src2, D *dest1, D *dest2) {
+ if(tlm_bool<D>(*src2)) *dest1 = *src1;
+}
+
+template<class D, void COPY(D *src1, D *src2, D *dest1, D *dest2)>
+inline void loop_aligned2(D *src1, D *src2, D *dest1, D *dest2,
+ int words, int words_per_bus) {
+ ptrdiff_t src1to2 = (char *)src2 - (char *)src1; // 64BITFIX was int and operands were cast to int //
+ ptrdiff_t dest1to2 = (char *)dest2 - (char *)dest1; // 64BITFIX was int and operands were cast to int //
+
+ D *done = src1 + ptrdiff_t(words); // 64BITFIX //
+ D *bus_start = src1;
+ src1 += ptrdiff_t(words_per_bus - 1); // 64BITFIX //
+
+ while(true) {
+ COPY(src1, (D *)(src1to2+(char *)src1), dest1, (D *)(dest1to2+(char *)dest1)); // 64BITFIX //
+ dest1++;
+ if((--src1) < bus_start) {
+ bus_start += ptrdiff_t(words_per_bus); // 64BITFIX //
+ if(bus_start == done) break;
+ src1 = bus_start + ptrdiff_t(words_per_bus - 1); // 64BITFIX //
+ }
+ }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// function set (2): Response
+template<class DATAWORD> inline void
+tlm_from_hostendian_aligned(tlm_generic_payload *txn, unsigned int sizeof_databus) {
+ int words_per_bus = sizeof_databus/sizeof(DATAWORD);
+ if(words_per_bus == 1) return;
+ int words = (txn->get_data_length())/sizeof(DATAWORD);
+ tlm_endian_context *tc = txn->template get_extension<tlm_endian_context>();
+
+ if(txn->get_byte_enable_ptr() == 0) {
+ // no byte enables
+ if(txn->is_read()) {
+ // RD without byte enables. Copy data to original buffer
+ loop_aligned2<DATAWORD, &copy_d2<DATAWORD> >(
+ (DATAWORD *)(txn->get_data_ptr()),
+ 0, (DATAWORD *)(tc->data_ptr), 0, words, words_per_bus);
+ }
+ } else {
+ // byte enables present
+ if(txn->is_read()) {
+ // RD with byte enables. Copy data qualified by byte-enables
+ loop_aligned2<DATAWORD, &copy_dbyb2<DATAWORD> >(
+ (DATAWORD *)(txn->get_data_ptr()),
+ (DATAWORD *)(txn->get_byte_enable_ptr()),
+ (DATAWORD *)(tc->data_ptr), 0, words, words_per_bus);
+ }
+ }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// function set (2): Request
+template<class DATAWORD> inline void
+tlm_to_hostendian_aligned(tlm_generic_payload *txn, unsigned int sizeof_databus) {
+ tlm_endian_context *tc = establish_context(txn);
+ tc->from_f = &(tlm_from_hostendian_aligned<DATAWORD>);
+ tc->sizeof_databus = sizeof_databus;
+
+ int words_per_bus = sizeof_databus/sizeof(DATAWORD);
+ if(words_per_bus == 1) return;
+ int words = (txn->get_data_length())/sizeof(DATAWORD);
+
+ DATAWORD *original_be = (DATAWORD *)(txn->get_byte_enable_ptr());
+ DATAWORD *original_data = (DATAWORD *)(txn->get_data_ptr());
+
+ // always allocate a new data buffer
+ tc->establish_dbuf(txn->get_data_length());
+ txn->set_data_ptr(tc->new_dbuf);
+
+ if(original_be == 0) {
+ // no byte enables
+ if(txn->is_write()) {
+ // WR no byte enables. Copy data
+ loop_aligned2<DATAWORD, &copy_d2<DATAWORD> >(original_data, 0,
+ (DATAWORD *)(txn->get_data_ptr()), 0,
+ words, words_per_bus);
+ } else {
+ // RD no byte enables. Save original data pointer
+ tc->data_ptr = (uchar *)original_data;
+ }
+ } else {
+ // byte enables present
+ // allocate a new buffer for them
+ tc->establish_bebuf(txn->get_data_length());
+ txn->set_byte_enable_ptr(tc->new_bebuf);
+ txn->set_byte_enable_length(txn->get_data_length());
+
+ if(txn->is_write()) {
+ // WR with byte enables. Copy data and BEs
+ loop_aligned2<DATAWORD, &copy_db2<DATAWORD> >(original_data, original_be,
+ (DATAWORD *)(txn->get_data_ptr()),
+ (DATAWORD *)(txn->get_byte_enable_ptr()), words, words_per_bus);
+ } else {
+ // RD with byte enables. Save original data pointer
+ tc->data_ptr = (uchar *)original_data;
+ // Copy byte enables to new buffer
+ loop_aligned2<DATAWORD, &copy_d2<DATAWORD> >(original_be, 0,
+ (DATAWORD *)(txn->get_byte_enable_ptr()), 0,
+ words, words_per_bus);
+ }
+ }
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// function set (3): Response
+template<class DATAWORD> inline void
+tlm_from_hostendian_single(tlm_generic_payload *txn, unsigned int sizeof_databus) {
+ // nothing needs to be done here
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// function set (3): Request
+template<class DATAWORD> inline void
+tlm_to_hostendian_single(tlm_generic_payload *txn, unsigned int sizeof_databus) {
+ tlm_endian_context *tc = establish_context(txn);
+ tc->from_f = &(tlm_from_hostendian_single<DATAWORD>);
+ tc->sizeof_databus = sizeof_databus;
+
+ // only need to change the address, always safe to work in-place
+ sc_dt::uint64 mask = sizeof_databus-1;
+ sc_dt::uint64 a = txn->get_address();
+ txn->set_address((a & ~mask) |
+ (sizeof_databus - (a & mask) - sizeof(DATAWORD)));
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// helper function which works for all responses
+inline void tlm_from_hostendian(tlm_generic_payload *txn) {
+ tlm_endian_context *tc = txn->get_extension<tlm_endian_context>();
+ (*(tc->from_f))(txn, tc->sizeof_databus);
+}
+
+
+#ifndef TLM_END_CONV_DONT_UNDEF_UCHAR
+#undef uchar
+#endif
+
+} // namespace tlm
+
+
+#endif // multiple-inclusion protection
+
diff --git a/ext/systemc/src/tlm_core/tlm_2/tlm_generic_payload/tlm_generic_payload.h b/ext/systemc/src/tlm_core/tlm_2/tlm_generic_payload/tlm_generic_payload.h
new file mode 100644
index 000000000..3e25e56f2
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_2/tlm_generic_payload/tlm_generic_payload.h
@@ -0,0 +1,29 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#ifndef __TLM_GENERIC_PAYLOAD_H__
+#define __TLM_GENERIC_PAYLOAD_H__
+
+#include "tlm_core/tlm_2/tlm_generic_payload/tlm_helpers.h"
+#include "tlm_core/tlm_2/tlm_generic_payload/tlm_phase.h"
+#include "tlm_core/tlm_2/tlm_generic_payload/tlm_gp.h"
+#include "tlm_core/tlm_2/tlm_generic_payload/tlm_endian_conv.h"
+
+#endif
+
diff --git a/ext/systemc/src/tlm_core/tlm_2/tlm_generic_payload/tlm_gp.h b/ext/systemc/src/tlm_core/tlm_2/tlm_generic_payload/tlm_gp.h
new file mode 100644
index 000000000..965e059ab
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_2/tlm_generic_payload/tlm_gp.h
@@ -0,0 +1,642 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+// 12-Jan-2009 John Aynsley Bug fix. has_mm() and get_ref_count() should both be const
+// 23-Mar-2009 John Aynsley Add method update_original_from()
+// 20-Apr-2009 John Aynsley Bug fix for 64-bit machines: unsigned long int -> unsigned int
+// 5-May-2011 JA and Philipp Hartmann Add tlm_gp_option, set_gp_option, get_gp_option
+// 11-May-2011 John Aynsley Add run-time check to release()
+
+
+#ifndef __TLM_GP_H__
+#define __TLM_GP_H__
+
+#include <systemc>
+#include "tlm_core/tlm_2/tlm_generic_payload/tlm_array.h"
+
+namespace tlm {
+
+class
+tlm_generic_payload;
+
+class tlm_mm_interface {
+public:
+ virtual void free(tlm_generic_payload*) = 0;
+ virtual ~tlm_mm_interface() {}
+};
+
+//---------------------------------------------------------------------------
+// Classes and helper functions for the extension mechanism
+//---------------------------------------------------------------------------
+// Helper function:
+inline unsigned int max_num_extensions(bool increment=false)
+{
+ static unsigned int max_num = 0;
+ if (increment) ++max_num;
+ return max_num;
+}
+
+// This class can be used for storing pointers to the extension classes, used
+// in tlm_generic_payload:
+class tlm_extension_base
+{
+public:
+ virtual tlm_extension_base* clone() const = 0;
+ virtual void free() { delete this; }
+ virtual void copy_from(tlm_extension_base const &) = 0;
+protected:
+ virtual ~tlm_extension_base() {}
+ static unsigned int register_extension()
+ {
+ return (max_num_extensions(true) - 1);
+ };
+};
+
+// Base class for all extension classes, derive your extension class in
+// the following way:
+// class my_extension : public tlm_extension<my_extension> { ...
+// This triggers proper extension registration during C++ static
+// contruction time. my_extension::ID will hold the unique index in the
+// tlm_generic_payload::m_extensions array.
+template <typename T>
+class tlm_extension : public tlm_extension_base
+{
+public:
+ virtual tlm_extension_base* clone() const = 0;
+ virtual void copy_from(tlm_extension_base const &ext) = 0; //{assert(typeid(this)==typeid(ext)); assert(ID === ext.ID); assert(0);}
+ virtual ~tlm_extension() {}
+ const static unsigned int ID;
+};
+
+template <typename T>
+const
+unsigned int tlm_extension<T>::ID = tlm_extension_base::register_extension();
+
+//---------------------------------------------------------------------------
+// enumeration types
+//---------------------------------------------------------------------------
+enum tlm_command {
+ TLM_READ_COMMAND,
+ TLM_WRITE_COMMAND,
+ TLM_IGNORE_COMMAND
+};
+
+enum tlm_response_status {
+ TLM_OK_RESPONSE = 1,
+ TLM_INCOMPLETE_RESPONSE = 0,
+ TLM_GENERIC_ERROR_RESPONSE = -1,
+ TLM_ADDRESS_ERROR_RESPONSE = -2,
+ TLM_COMMAND_ERROR_RESPONSE = -3,
+ TLM_BURST_ERROR_RESPONSE = -4,
+ TLM_BYTE_ENABLE_ERROR_RESPONSE = -5
+};
+
+enum tlm_gp_option {
+ TLM_MIN_PAYLOAD,
+ TLM_FULL_PAYLOAD,
+ TLM_FULL_PAYLOAD_ACCEPTED
+};
+
+#define TLM_BYTE_DISABLED 0x0
+#define TLM_BYTE_ENABLED 0xff
+
+//---------------------------------------------------------------------------
+// The generic payload class:
+//---------------------------------------------------------------------------
+class tlm_generic_payload {
+
+public:
+ //---------------
+ // Constructors
+ //---------------
+
+ // Default constructor
+ tlm_generic_payload()
+ : m_address(0)
+ , m_command(TLM_IGNORE_COMMAND)
+ , m_data(0)
+ , m_length(0)
+ , m_response_status(TLM_INCOMPLETE_RESPONSE)
+ , m_dmi(false)
+ , m_byte_enable(0)
+ , m_byte_enable_length(0)
+ , m_streaming_width(0)
+ , m_gp_option(TLM_MIN_PAYLOAD)
+ , m_extensions(max_num_extensions())
+ , m_mm(0)
+ , m_ref_count(0)
+ {
+ }
+
+ explicit tlm_generic_payload(tlm_mm_interface* mm)
+ : m_address(0)
+ , m_command(TLM_IGNORE_COMMAND)
+ , m_data(0)
+ , m_length(0)
+ , m_response_status(TLM_INCOMPLETE_RESPONSE)
+ , m_dmi(false)
+ , m_byte_enable(0)
+ , m_byte_enable_length(0)
+ , m_streaming_width(0)
+ , m_gp_option(TLM_MIN_PAYLOAD)
+ , m_extensions(max_num_extensions())
+ , m_mm(mm)
+ , m_ref_count(0)
+ {
+ }
+
+ void acquire(){assert(m_mm != 0); m_ref_count++;}
+ void release(){assert(m_mm != 0 && m_ref_count > 0); if (--m_ref_count==0) m_mm->free(this);}
+ int get_ref_count() const {return m_ref_count;}
+ void set_mm(tlm_mm_interface* mm) { m_mm = mm; }
+ bool has_mm() const { return m_mm != 0; }
+
+ void reset(){
+ //should the other members be reset too?
+ m_gp_option = TLM_MIN_PAYLOAD;
+ m_extensions.free_entire_cache();
+ };
+
+
+private:
+ //disabled copy ctor and assignment operator.
+ // Copy constructor
+ tlm_generic_payload(const tlm_generic_payload& x)
+ : m_address(x.get_address())
+ , m_command(x.get_command())
+ , m_data(x.get_data_ptr())
+ , m_length(x.get_data_length())
+ , m_response_status(x.get_response_status())
+ , m_dmi(x.is_dmi_allowed())
+ , m_byte_enable(x.get_byte_enable_ptr())
+ , m_byte_enable_length(x.get_byte_enable_length())
+ , m_streaming_width(x.get_streaming_width())
+ , m_gp_option(x.m_gp_option)
+ , m_extensions(max_num_extensions())
+ {
+ // copy all extensions
+ for(unsigned int i=0; i<m_extensions.size(); i++)
+ {
+ m_extensions[i] = x.get_extension(i);
+ }
+ }
+
+ // Assignment operator
+ tlm_generic_payload& operator= (const tlm_generic_payload& x)
+ {
+ m_command = x.get_command();
+ m_address = x.get_address();
+ m_data = x.get_data_ptr();
+ m_length = x.get_data_length();
+ m_response_status = x.get_response_status();
+ m_byte_enable = x.get_byte_enable_ptr();
+ m_byte_enable_length = x.get_byte_enable_length();
+ m_streaming_width = x.get_streaming_width();
+ m_gp_option = x.get_gp_option();
+ m_dmi = x.is_dmi_allowed();
+
+ // extension copy: all extension arrays must be of equal size by
+ // construction (i.e. it must either be constructed after C++
+ // static construction time, or the resize_extensions() method must
+ // have been called prior to using the object)
+ for(unsigned int i=0; i<m_extensions.size(); i++)
+ {
+ m_extensions[i] = x.get_extension(i);
+ }
+ return (*this);
+ }
+public:
+ // non-virtual deep-copying of the object
+ void deep_copy_from(const tlm_generic_payload & other)
+ {
+ m_command = other.get_command();
+ m_address = other.get_address();
+ m_length = other.get_data_length();
+ m_response_status = other.get_response_status();
+ m_byte_enable_length = other.get_byte_enable_length();
+ m_streaming_width = other.get_streaming_width();
+ m_gp_option = other.get_gp_option();
+ m_dmi = other.is_dmi_allowed();
+
+ // deep copy data
+ // there must be enough space in the target transaction!
+ if(m_data && other.m_data)
+ {
+ memcpy(m_data, other.m_data, m_length);
+ }
+ // deep copy byte enables
+ // there must be enough space in the target transaction!
+ if(m_byte_enable && other.m_byte_enable)
+ {
+ memcpy(m_byte_enable, other.m_byte_enable, m_byte_enable_length);
+ }
+ // deep copy extensions (sticky and non-sticky)
+ for(unsigned int i=0; i<other.m_extensions.size(); i++)
+ {
+ if(other.m_extensions[i])
+ { //original has extension i
+ if(!m_extensions[i])
+ { //We don't: clone.
+ tlm_extension_base *ext = other.m_extensions[i]->clone();
+ if(ext) //extension may not be clonable.
+ {
+ if(has_mm())
+ { //mm can take care of removing cloned extensions
+ set_auto_extension(i, ext);
+ }
+ else
+ { // no mm, user will call free_all_extensions().
+ set_extension(i, ext);
+ }
+ }
+ }
+ else
+ { //We already have such extension. Copy original over it.
+ m_extensions[i]->copy_from(*other.m_extensions[i]);
+ }
+ }
+ }
+ }
+
+ // To update the state of the original generic payload from a deep copy
+ // Assumes that "other" was created from the original by calling deep_copy_from
+ // Argument use_byte_enable_on_read determines whether to use or ignores byte enables
+ // when copying back the data array on a read command
+
+ void update_original_from(const tlm_generic_payload & other,
+ bool use_byte_enable_on_read = true)
+ {
+ // Copy back extensions that are present on the original
+ update_extensions_from(other);
+
+ // Copy back the response status and DMI hint attributes
+ m_response_status = other.get_response_status();
+ m_dmi = other.is_dmi_allowed();
+
+ // Copy back the data array for a read command only
+ // deep_copy_from allowed null pointers, and so will we
+ // We assume the arrays are the same size
+ // We test for equal pointers in case the original and the copy share the same array
+
+ if(is_read() && m_data && other.m_data && m_data != other.m_data)
+ {
+ if (m_byte_enable && use_byte_enable_on_read)
+ {
+ if (m_byte_enable_length == 8 && m_length % 8 == 0 )
+ {
+ // Optimized implementation copies 64-bit words by masking
+ for (unsigned int i = 0; i < m_length; i += 8)
+ {
+ typedef sc_dt::uint64* u;
+ *reinterpret_cast<u>(&m_data[i]) &= ~*reinterpret_cast<u>(m_byte_enable);
+ *reinterpret_cast<u>(&m_data[i]) |= *reinterpret_cast<u>(&other.m_data[i]) &
+ *reinterpret_cast<u>(m_byte_enable);
+ }
+ }
+ else if (m_byte_enable_length == 4 && m_length % 4 == 0 )
+ {
+ // Optimized implementation copies 32-bit words by masking
+ for (unsigned int i = 0; i < m_length; i += 4)
+ {
+ typedef unsigned int* u;
+ *reinterpret_cast<u>(&m_data[i]) &= ~*reinterpret_cast<u>(m_byte_enable);
+ *reinterpret_cast<u>(&m_data[i]) |= *reinterpret_cast<u>(&other.m_data[i]) &
+ *reinterpret_cast<u>(m_byte_enable);
+ }
+ }
+ else
+ // Unoptimized implementation
+ for (unsigned int i = 0; i < m_length; i++)
+ if ( m_byte_enable[i % m_byte_enable_length] )
+ m_data[i] = other.m_data[i];
+ }
+ else
+ memcpy(m_data, other.m_data, m_length);
+ }
+ }
+
+ void update_extensions_from(const tlm_generic_payload & other)
+ {
+ // deep copy extensions that are already present
+ for(unsigned int i=0; i<other.m_extensions.size(); i++)
+ {
+ if(other.m_extensions[i])
+ { //original has extension i
+ if(m_extensions[i])
+ { //We have it too. copy.
+ m_extensions[i]->copy_from(*other.m_extensions[i]);
+ }
+ }
+ }
+ }
+
+ // Free all extensions. Useful when reusing a cloned transaction that doesn't have memory manager.
+ // normal and sticky extensions are freed and extension array cleared.
+ void free_all_extensions()
+ {
+ m_extensions.free_entire_cache();
+ for(unsigned int i=0; i<m_extensions.size(); i++)
+ {
+ if(m_extensions[i])
+ {
+ m_extensions[i]->free();
+ m_extensions[i] = 0;
+ }
+ }
+ }
+ //--------------
+ // Destructor
+ //--------------
+ virtual ~tlm_generic_payload() {
+ for(unsigned int i=0; i<m_extensions.size(); i++)
+ if(m_extensions[i]) m_extensions[i]->free();
+ }
+
+ //----------------
+ // API (including setters & getters)
+ //---------------
+
+ // Command related method
+ bool is_read() const {return (m_command == TLM_READ_COMMAND);}
+ void set_read() {m_command = TLM_READ_COMMAND;}
+ bool is_write() const {return (m_command == TLM_WRITE_COMMAND);}
+ void set_write() {m_command = TLM_WRITE_COMMAND;}
+ tlm_command get_command() const {return m_command;}
+ void set_command(const tlm_command command) {m_command = command;}
+
+ // Address related methods
+ sc_dt::uint64 get_address() const {return m_address;}
+ void set_address(const sc_dt::uint64 address) {m_address = address;}
+
+ // Data related methods
+ unsigned char* get_data_ptr() const {return m_data;}
+ void set_data_ptr(unsigned char* data) {m_data = data;}
+
+ // Transaction length (in bytes) related methods
+ unsigned int get_data_length() const {return m_length;}
+ void set_data_length(const unsigned int length) {m_length = length;}
+
+ // Response status related methods
+ bool is_response_ok() const {return (m_response_status > 0);}
+ bool is_response_error() const {return (m_response_status <= 0);}
+ tlm_response_status get_response_status() const {return m_response_status;}
+ void set_response_status(const tlm_response_status response_status)
+ {m_response_status = response_status;}
+ std::string get_response_string() const
+ {
+ switch(m_response_status)
+ {
+ case TLM_OK_RESPONSE: return "TLM_OK_RESPONSE";
+ case TLM_INCOMPLETE_RESPONSE: return "TLM_INCOMPLETE_RESPONSE";
+ case TLM_GENERIC_ERROR_RESPONSE: return "TLM_GENERIC_ERROR_RESPONSE";
+ case TLM_ADDRESS_ERROR_RESPONSE: return "TLM_ADDRESS_ERROR_RESPONSE";
+ case TLM_COMMAND_ERROR_RESPONSE: return "TLM_COMMAND_ERROR_RESPONSE";
+ case TLM_BURST_ERROR_RESPONSE: return "TLM_BURST_ERROR_RESPONSE";
+ case TLM_BYTE_ENABLE_ERROR_RESPONSE: return "TLM_BYTE_ENABLE_ERROR_RESPONSE";
+ }
+ return "TLM_UNKNOWN_RESPONSE";
+ }
+
+ // Streaming related methods
+ unsigned int get_streaming_width() const {return m_streaming_width;}
+ void set_streaming_width(const unsigned int streaming_width) {m_streaming_width = streaming_width; }
+
+ // Byte enable related methods
+ unsigned char* get_byte_enable_ptr() const {return m_byte_enable;}
+ void set_byte_enable_ptr(unsigned char* byte_enable){m_byte_enable = byte_enable;}
+ unsigned int get_byte_enable_length() const {return m_byte_enable_length;}
+ void set_byte_enable_length(const unsigned int byte_enable_length){m_byte_enable_length = byte_enable_length;}
+
+ // This is the "DMI-hint" a slave can set this to true if it
+ // wants to indicate that a DMI request would be supported:
+ void set_dmi_allowed(bool dmi_allowed) { m_dmi = dmi_allowed; }
+ bool is_dmi_allowed() const { return m_dmi; }
+
+ // Use full set of attributes in DMI/debug?
+ tlm_gp_option get_gp_option() const { return m_gp_option; }
+ void set_gp_option( const tlm_gp_option gp_opt ) { m_gp_option = gp_opt; }
+
+private:
+
+ /* --------------------------------------------------------------------- */
+ /* Generic Payload attributes: */
+ /* --------------------------------------------------------------------- */
+ /* - m_command : Type of transaction. Three values supported: */
+ /* - TLM_WRITE_COMMAND */
+ /* - TLM_READ_COMMAND */
+ /* - TLM_IGNORE_COMMAND */
+ /* - m_address : Transaction base address (byte-addressing). */
+ /* - m_data : When m_command = TLM_WRITE_COMMAND contains a */
+ /* pointer to the data to be written in the target.*/
+ /* When m_command = TLM_READ_COMMAND contains a */
+ /* pointer where to copy the data read from the */
+ /* target. */
+ /* - m_length : Total number of bytes of the transaction. */
+ /* - m_response_status : This attribute indicates whether an error has */
+ /* occurred during the transaction. */
+ /* Values supported are: */
+ /* - TLM_OK_RESP */
+ /* - TLM_INCOMPLETE_RESP */
+ /* - TLM_GENERIC_ERROR_RESP */
+ /* - TLM_ADDRESS_ERROR_RESP */
+ /* - TLM_COMMAND_ERROR_RESP */
+ /* - TLM_BURST_ERROR_RESP */
+ /* - TLM_BYTE_ENABLE_ERROR_RESP */
+ /* */
+ /* - m_byte_enable : It can be used to create burst transfers where */
+ /* the address increment between each beat is greater */
+ /* than the word length of each beat, or to place */
+ /* words in selected byte lanes of a bus. */
+ /* - m_byte_enable_length : For a read or a write command, the target */
+ /* interpret the byte enable length attribute as the */
+ /* number of elements in the bytes enable array. */
+ /* - m_streaming_width : */
+ /* --------------------------------------------------------------------- */
+
+ sc_dt::uint64 m_address;
+ tlm_command m_command;
+ unsigned char* m_data;
+ unsigned int m_length;
+ tlm_response_status m_response_status;
+ bool m_dmi;
+ unsigned char* m_byte_enable;
+ unsigned int m_byte_enable_length;
+ unsigned int m_streaming_width;
+ tlm_gp_option m_gp_option;
+
+public:
+
+ /* --------------------------------------------------------------------- */
+ /* Dynamic extension mechanism: */
+ /* --------------------------------------------------------------------- */
+ /* The extension mechanism is intended to enable initiator modules to */
+ /* optionally and transparently add data fields to the */
+ /* tlm_generic_payload. Target modules are free to check for extensions */
+ /* and may or may not react to the data in the extension fields. The */
+ /* definition of the extensions' semantics is solely in the */
+ /* responsibility of the user. */
+ /* */
+ /* The following rules apply: */
+ /* */
+ /* - Every extension class must be derived from tlm_extension, e.g.: */
+ /* class my_extension : public tlm_extension<my_extension> { ... } */
+ /* */
+ /* - A tlm_generic_payload object should be constructed after C++ */
+ /* static initialization time. This way it is guaranteed that the */
+ /* extension array is of sufficient size to hold all possible */
+ /* extensions. Alternatively, the initiator module can enforce a valid */
+ /* extension array size by calling the resize_extensions() method */
+ /* once before the first transaction with the payload object is */
+ /* initiated. */
+ /* */
+ /* - Initiators should use the the set_extension(e) or clear_extension(e)*/
+ /* methods for manipulating the extension array. The type of the */
+ /* argument must be a pointer to the specific registered extension */
+ /* type (my_extension in the above example) and is used to */
+ /* automatically locate the appropriate index in the array. */
+ /* */
+ /* - Targets can check for a specific extension by calling */
+ /* get_extension(e). e will point to zero if the extension is not */
+ /* present. */
+ /* */
+ /* --------------------------------------------------------------------- */
+
+ // Stick the pointer to an extension into the vector, return the
+ // previous value:
+ template <typename T> T* set_extension(T* ext)
+ {
+ return static_cast<T*>(set_extension(T::ID, ext));
+ }
+
+ // non-templatized version with manual index:
+ tlm_extension_base* set_extension(unsigned int index,
+ tlm_extension_base* ext)
+ {
+ tlm_extension_base* tmp = m_extensions[index];
+ m_extensions[index] = ext;
+ return tmp;
+ }
+
+ // Stick the pointer to an extension into the vector, return the
+ // previous value and schedule its release
+ template <typename T> T* set_auto_extension(T* ext)
+ {
+ return static_cast<T*>(set_auto_extension(T::ID, ext));
+ }
+
+ // non-templatized version with manual index:
+ tlm_extension_base* set_auto_extension(unsigned int index,
+ tlm_extension_base* ext)
+ {
+ tlm_extension_base* tmp = m_extensions[index];
+ m_extensions[index] = ext;
+ if (!tmp) m_extensions.insert_in_cache(&m_extensions[index]);
+ assert(m_mm != 0);
+ return tmp;
+ }
+
+ // Check for an extension, ext will point to 0 if not present
+ template <typename T> void get_extension(T*& ext) const
+ {
+ ext = get_extension<T>();
+ }
+ template <typename T> T* get_extension() const
+ {
+ return static_cast<T*>(get_extension(T::ID));
+ }
+ // Non-templatized version with manual index:
+ tlm_extension_base* get_extension(unsigned int index) const
+ {
+ return m_extensions[index];
+ }
+
+ //this call just removes the extension from the txn but does not
+ // call free() or tells the MM to do so
+ // it return false if there was active MM so you are now in an unsafe situation
+ // recommended use: when 100% sure there is no MM
+ template <typename T> void clear_extension(const T* ext)
+ {
+ clear_extension<T>();
+ }
+
+ //this call just removes the extension from the txn but does not
+ // call free() or tells the MM to do so
+ // it return false if there was active MM so you are now in an unsafe situation
+ // recommended use: when 100% sure there is no MM
+ template <typename T> void clear_extension()
+ {
+ clear_extension(T::ID);
+ }
+
+ //this call removes the extension from the txn and does
+ // call free() or tells the MM to do so when the txn is finally done
+ // recommended use: when not sure there is no MM
+ template <typename T> void release_extension(T* ext)
+ {
+ release_extension<T>();
+ }
+
+ //this call removes the extension from the txn and does
+ // call free() or tells the MM to do so when the txn is finally done
+ // recommended use: when not sure there is no MM
+ template <typename T> void release_extension()
+ {
+ release_extension(T::ID);
+ }
+
+private:
+ // Non-templatized version with manual index
+ void clear_extension(unsigned int index)
+ {
+ m_extensions[index] = static_cast<tlm_extension_base*>(0);
+ }
+ // Non-templatized version with manual index
+ void release_extension(unsigned int index)
+ {
+ if (m_mm)
+ {
+ m_extensions.insert_in_cache(&m_extensions[index]);
+ }
+ else
+ {
+ m_extensions[index]->free();
+ m_extensions[index] = static_cast<tlm_extension_base*>(0);
+ }
+ }
+
+public:
+ // Make sure the extension array is large enough. Can be called once by
+ // an initiator module (before issuing the first transaction) to make
+ // sure that the extension array is of correct size. This is only needed
+ // if the initiator cannot guarantee that the generic payload object is
+ // allocated after C++ static construction time.
+ void resize_extensions()
+ {
+ m_extensions.expand(max_num_extensions());
+ }
+
+private:
+ tlm_array<tlm_extension_base*> m_extensions;
+ tlm_mm_interface* m_mm;
+ unsigned int m_ref_count;
+};
+
+} // namespace tlm
+
+#endif /* __TLM_GP_H__ */
diff --git a/ext/systemc/src/tlm_core/tlm_2/tlm_generic_payload/tlm_helpers.h b/ext/systemc/src/tlm_core/tlm_2/tlm_generic_payload/tlm_helpers.h
new file mode 100644
index 000000000..da3abb4f9
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_2/tlm_generic_payload/tlm_helpers.h
@@ -0,0 +1,80 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/* ---------------------------------------------------------------------------------------
+ @file tlm_helpers.h
+
+ @brief
+
+ Original Authors:
+ Charles Wilson, ESLX
+
+--------------------------------------------------------------------------------------- */
+
+#ifndef __TLM_HELPERS_H__
+#define __TLM_HELPERS_H__
+
+//#include <sys/param.h>
+//#include <cstring>
+
+namespace tlm {
+
+enum tlm_endianness { TLM_UNKNOWN_ENDIAN, TLM_LITTLE_ENDIAN, TLM_BIG_ENDIAN };
+
+inline tlm_endianness get_host_endianness(void)
+{
+ static tlm_endianness host_endianness = TLM_UNKNOWN_ENDIAN;
+
+ if (host_endianness == TLM_UNKNOWN_ENDIAN) {
+ unsigned int number = 1;
+ unsigned char *p_msb_or_lsb = (unsigned char*)&number;
+
+ host_endianness = (p_msb_or_lsb[0] == 0) ? TLM_BIG_ENDIAN : TLM_LITTLE_ENDIAN;
+ }
+ return host_endianness;
+}
+
+inline bool host_has_little_endianness(void)
+{
+ static tlm_endianness host_endianness = TLM_UNKNOWN_ENDIAN;
+ static bool host_little_endian = false;
+
+ if (host_endianness == TLM_UNKNOWN_ENDIAN) {
+ unsigned int number = 1;
+ unsigned char *p_msb_or_lsb = (unsigned char*)&number;
+
+ host_little_endian = (p_msb_or_lsb[0] == 0) ? false : true;
+ }
+
+ return host_little_endian;
+}
+
+inline bool has_host_endianness(tlm_endianness endianness)
+{
+ if (host_has_little_endianness()) {
+ return endianness == TLM_LITTLE_ENDIAN;
+
+ } else {
+ return endianness == TLM_BIG_ENDIAN;
+ }
+}
+
+} // namespace tlm
+
+#endif /* __TLM_HELPERS_H__ */
diff --git a/ext/systemc/src/tlm_core/tlm_2/tlm_generic_payload/tlm_phase.h b/ext/systemc/src/tlm_core/tlm_2/tlm_generic_payload/tlm_phase.h
new file mode 100644
index 000000000..af0a278c9
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_2/tlm_generic_payload/tlm_phase.h
@@ -0,0 +1,87 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#ifndef __TLM_PHASE_H__
+#define __TLM_PHASE_H__
+
+#include <string>
+#include <iostream>
+#include <vector>
+
+namespace tlm {
+
+//enum tlm_phase { BEGIN_REQ, END_REQ, BEGIN_RESP, END_RESP };
+
+enum tlm_phase_enum { UNINITIALIZED_PHASE=0, BEGIN_REQ=1, END_REQ, BEGIN_RESP, END_RESP };
+
+inline unsigned int create_phase_number(){
+ static unsigned int number=END_RESP+1;
+ return number++;
+}
+
+inline std::vector<const char*>& get_phase_name_vec(){
+ static std::vector<const char*> phase_name_vec(END_RESP+1, (const char*)NULL);
+ return phase_name_vec;
+}
+
+class tlm_phase{
+public:
+ tlm_phase(): m_id(0) {}
+ tlm_phase(unsigned int id): m_id(id){}
+ tlm_phase(const tlm_phase_enum& standard): m_id((unsigned int) standard){}
+ tlm_phase& operator=(const tlm_phase_enum& standard){m_id=(unsigned int)standard; return *this;}
+ operator unsigned int() const{return m_id;}
+
+private:
+ unsigned int m_id;
+};
+
+inline
+std::ostream& operator<<(std::ostream& s, const tlm_phase& p){
+ switch ((unsigned int)p){
+ case UNINITIALIZED_PHASE: s<<"UNINITIALIZED_PHASE"; break;
+ case BEGIN_REQ: s<<"BEGIN_REQ"; break;
+ case END_REQ: s<<"END_REQ"; break;
+ case BEGIN_RESP: s<<"BEGIN_RESP"; break;
+ case END_RESP: s<<"END_RESP"; break;
+ default:
+ s<<get_phase_name_vec()[(unsigned int)p]; return s;
+ }
+ return s;
+}
+
+#define TLM_DECLARE_EXTENDED_PHASE(name_arg) \
+class tlm_phase_##name_arg:public tlm::tlm_phase{ \
+public:\
+static const tlm_phase_##name_arg& get_phase(){static tlm_phase_##name_arg tmp; return tmp;}\
+private:\
+tlm_phase_##name_arg():tlm::tlm_phase(tlm::create_phase_number()){tlm::get_phase_name_vec().push_back(get_char_##name_arg());};\
+tlm_phase_##name_arg(const tlm_phase_##name_arg&); \
+tlm_phase_##name_arg& operator=(const tlm_phase_##name_arg&); \
+static inline const char* get_char_##name_arg(){static const char* tmp=#name_arg; return tmp;} \
+}; \
+static const tlm_phase_##name_arg& name_arg=tlm_phase_##name_arg::get_phase()
+
+// for backwards-compatibility
+#define DECLARE_EXTENDED_PHASE(NameArg) \
+ TLM_DECLARE_EXTENDED_PHASE( NameArg )
+
+} // namespace tlm
+
+#endif /* TLM_PHASE_HEADER */
diff --git a/ext/systemc/src/tlm_core/tlm_2/tlm_quantum/tlm_global_quantum.h b/ext/systemc/src/tlm_core/tlm_2/tlm_quantum/tlm_global_quantum.h
new file mode 100644
index 000000000..eb36a898e
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_2/tlm_quantum/tlm_global_quantum.h
@@ -0,0 +1,97 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#ifndef __TLM_GLOBAL_QUANTUM_H__
+#define __TLM_GLOBAL_QUANTUM_H__
+
+#include <systemc>
+
+namespace tlm {
+
+//
+// tlm_global_quantum class
+//
+// The global quantum is the maximum time an initiator can run ahead of
+// systemC time. All initiators should synchronize on timingpoints that
+// are multiples of the global quantum value.
+//
+// sc_set_time_resolution can only be called before the first
+// sc_time object is created. This means that after setting the
+// global quantum it will not be possible to call sc_set_time_resolution.
+// If sc_set_time_resolution must be called this must be done before
+// the global quantum is set.
+//
+
+class tlm_global_quantum
+{
+public:
+ //
+ // Returns a reference to the tlm_global_quantum singleton
+ //
+ static tlm_global_quantum& instance()
+ {
+ static tlm_global_quantum instance_;
+ return instance_;
+ }
+
+public:
+
+ //
+ // Setter/getter for the global quantum
+ //
+ void set(const sc_core::sc_time& t)
+ {
+ m_global_quantum = t;
+ }
+
+ const sc_core::sc_time& get() const
+ {
+ return m_global_quantum;
+ }
+
+ //
+ // This function will calculate the maximum value for the next local
+ // quantum for an initiator. All initiators should synchronize on
+ // integer multiples of the global quantum value. The value for the
+ // local quantum of an initiator can be smaller, but should never be
+ // greater than the value returned by this method.
+ //
+ sc_core::sc_time compute_local_quantum()
+ {
+ if (m_global_quantum != sc_core::SC_ZERO_TIME) {
+ const sc_core::sc_time current = sc_core::sc_time_stamp();
+ const sc_core::sc_time g_quant = m_global_quantum;
+ return g_quant - (current % g_quant);
+ } else {
+ return sc_core::SC_ZERO_TIME;
+ }
+ }
+
+protected:
+ tlm_global_quantum() : m_global_quantum(sc_core::SC_ZERO_TIME)
+ {
+ }
+
+protected:
+ sc_core::sc_time m_global_quantum;
+};
+
+} // namespace tlm
+
+#endif
diff --git a/ext/systemc/src/tlm_core/tlm_2/tlm_quantum/tlm_quantum.h b/ext/systemc/src/tlm_core/tlm_2/tlm_quantum/tlm_quantum.h
new file mode 100644
index 000000000..c5138ab06
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_2/tlm_quantum/tlm_quantum.h
@@ -0,0 +1,25 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#ifndef __TLM_QUANTUM_H__
+#define __TLM_QUANTUM_H__
+
+#include "tlm_core/tlm_2/tlm_quantum/tlm_global_quantum.h"
+
+#endif
diff --git a/ext/systemc/src/tlm_core/tlm_2/tlm_sockets/tlm_initiator_socket.h b/ext/systemc/src/tlm_core/tlm_2/tlm_sockets/tlm_initiator_socket.h
new file mode 100644
index 000000000..3dd42e806
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_2/tlm_sockets/tlm_initiator_socket.h
@@ -0,0 +1,252 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#ifndef __TLM_INITIATOR_SOCKET_H__
+#define __TLM_INITIATOR_SOCKET_H__
+
+//#include <systemc>
+#include "tlm_core/tlm_2/tlm_2_interfaces/tlm_fw_bw_ifs.h"
+
+namespace tlm {
+
+
+template <unsigned int BUSWIDTH = 32,
+ typename FW_IF = tlm_fw_transport_if<>,
+ typename BW_IF = tlm_bw_transport_if<> >
+class tlm_base_initiator_socket_b
+{
+public:
+ virtual ~tlm_base_initiator_socket_b() {}
+
+ virtual sc_core::sc_port_b<FW_IF> & get_base_port() = 0;
+ virtual sc_core::sc_port_b<FW_IF> const & get_base_port() const = 0;
+ virtual BW_IF & get_base_interface() = 0;
+ virtual BW_IF const & get_base_interface() const = 0;
+ virtual sc_core::sc_export<BW_IF> & get_base_export() = 0;
+ virtual sc_core::sc_export<BW_IF> const & get_base_export() const = 0;
+};
+
+
+template <unsigned int BUSWIDTH,
+ typename FW_IF,
+ typename BW_IF> class tlm_base_target_socket_b;
+
+template <unsigned int BUSWIDTH,
+ typename FW_IF,
+ typename BW_IF,
+ int N
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+ ,sc_core::sc_port_policy POL
+#endif
+ > class tlm_base_target_socket;
+
+template <unsigned int BUSWIDTH = 32,
+ typename FW_IF = tlm_fw_transport_if<>,
+ typename BW_IF = tlm_bw_transport_if<>,
+ int N = 1
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+ ,sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND
+#endif
+ >
+class tlm_base_initiator_socket : public tlm_base_initiator_socket_b<BUSWIDTH, FW_IF, BW_IF>,
+ public sc_core::sc_port<FW_IF, N
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+ , POL
+#endif
+ >
+
+{
+public:
+ typedef FW_IF fw_interface_type;
+ typedef BW_IF bw_interface_type;
+ typedef sc_core::sc_port<fw_interface_type, N
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+ , POL
+#endif
+ > port_type;
+
+ typedef sc_core::sc_export<bw_interface_type> export_type;
+
+ typedef tlm_base_target_socket_b<BUSWIDTH,
+ fw_interface_type,
+ bw_interface_type> base_target_socket_type;
+ typedef tlm_base_initiator_socket_b<BUSWIDTH,
+ fw_interface_type,
+ bw_interface_type> base_type;
+
+ template <unsigned int, typename, typename, int
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+ ,sc_core::sc_port_policy
+#endif
+ >
+ friend class tlm_base_target_socket;
+
+public:
+ tlm_base_initiator_socket()
+ : port_type(sc_core::sc_gen_unique_name("tlm_base_initiator_socket"))
+ , m_export(sc_core::sc_gen_unique_name("tlm_base_initiator_socket_export"))
+ {
+ }
+
+ explicit tlm_base_initiator_socket(const char* name)
+ : port_type(name)
+ , m_export(sc_core::sc_gen_unique_name((std::string(name) + "_export").c_str()))
+ {
+ }
+
+ virtual const char* kind() const
+ {
+ return "tlm_base_initiator_socket";
+ }
+
+ unsigned int get_bus_width() const
+ {
+ return BUSWIDTH;
+ }
+
+ //
+ // Bind initiator socket to target socket
+ // - Binds the port of the initiator socket to the export of the target
+ // socket
+ // - Binds the port of the target socket to the export of the initiator
+ // socket
+ //
+ virtual void bind(base_target_socket_type& s)
+ {
+ // initiator.port -> target.export
+ (get_base_port())(s.get_base_interface());
+ // target.port -> initiator.export
+ (s.get_base_port())(get_base_interface());
+ }
+
+ void operator() (base_target_socket_type& s)
+ {
+ bind(s);
+ }
+
+ //
+ // Bind initiator socket to initiator socket (hierarchical bind)
+ // - Binds both the export and the port
+ //
+ virtual void bind(base_type& s)
+ {
+ // port
+ (get_base_port())(s.get_base_port());
+ // export
+ (s.get_base_export())(get_base_export());
+ }
+
+ void operator() (base_type& s)
+ {
+ bind(s);
+ }
+
+ //
+ // Bind interface to socket
+ // - Binds the interface to the export of this socket
+ //
+ virtual void bind(bw_interface_type& ifs)
+ {
+ (get_base_export())(ifs);
+ }
+
+ void operator() (bw_interface_type& s)
+ {
+ bind(s);
+ }
+
+ // Implementation of pure virtual functions of base class
+ virtual sc_core::sc_port_b<FW_IF> & get_base_port()
+ { return *this; }
+ virtual sc_core::sc_port_b<FW_IF> const & get_base_port() const
+ { return *this; }
+
+ virtual BW_IF & get_base_interface()
+ { return m_export; }
+ virtual BW_IF const & get_base_interface() const
+#if !( defined(IEEE_1666_SYSTEMC) && IEEE_1666_SYSTEMC >= 201101L )
+ { return const_cast<export_type &>(m_export); }
+#else
+ { return m_export; }
+#endif
+
+ virtual sc_core::sc_export<BW_IF> & get_base_export()
+ { return m_export; }
+ virtual sc_core::sc_export<BW_IF> const & get_base_export() const
+ { return m_export; }
+
+protected:
+ export_type m_export;
+};
+
+//
+// Convenience socket classes
+//
+
+template <unsigned int BUSWIDTH = 32,
+ typename TYPES = tlm_base_protocol_types,
+ int N = 1
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+ ,sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND
+#endif
+ >
+class tlm_initiator_socket :
+ public tlm_base_initiator_socket <BUSWIDTH,
+ tlm_fw_transport_if<TYPES>,
+ tlm_bw_transport_if<TYPES>,
+ N
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+ ,POL
+#endif
+ >
+{
+public:
+ tlm_initiator_socket() :
+ tlm_base_initiator_socket<BUSWIDTH,
+ tlm_fw_transport_if<TYPES>,
+ tlm_bw_transport_if<TYPES>,
+ N
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+ ,POL
+#endif
+ >()
+ {
+ }
+
+ explicit tlm_initiator_socket(const char* name) :
+ tlm_base_initiator_socket<BUSWIDTH,
+ tlm_fw_transport_if<TYPES>,
+ tlm_bw_transport_if<TYPES>,
+ N
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+ ,POL
+#endif
+ >(name)
+ {
+ }
+
+ virtual const char* kind() const
+ {
+ return "tlm_initiator_socket";
+ }
+};
+
+} // namespace tlm
+
+#endif
diff --git a/ext/systemc/src/tlm_core/tlm_2/tlm_sockets/tlm_sockets.h b/ext/systemc/src/tlm_core/tlm_2/tlm_sockets/tlm_sockets.h
new file mode 100644
index 000000000..013e29286
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_2/tlm_sockets/tlm_sockets.h
@@ -0,0 +1,26 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#ifndef __TLM_SOCKETS_H__
+#define __TLM_SOCKETS_H__
+
+#include "tlm_core/tlm_2/tlm_sockets/tlm_initiator_socket.h"
+#include "tlm_core/tlm_2/tlm_sockets/tlm_target_socket.h"
+
+#endif /* __TLM_SOCKETS_H__ */
diff --git a/ext/systemc/src/tlm_core/tlm_2/tlm_sockets/tlm_target_socket.h b/ext/systemc/src/tlm_core/tlm_2/tlm_sockets/tlm_target_socket.h
new file mode 100644
index 000000000..4ed29f62a
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_2/tlm_sockets/tlm_target_socket.h
@@ -0,0 +1,275 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#ifndef __TLM_TARGET_SOCKET_H__
+#define __TLM_TARGET_SOCKET_H__
+
+//#include <systemc>
+#include "tlm_core/tlm_2/tlm_2_interfaces/tlm_fw_bw_ifs.h"
+
+
+namespace tlm {
+
+template <unsigned int BUSWIDTH = 32,
+ typename FW_IF = tlm_fw_transport_if<>,
+ typename BW_IF = tlm_bw_transport_if<> >
+class tlm_base_target_socket_b
+{
+public:
+ virtual ~tlm_base_target_socket_b() {}
+
+ virtual sc_core::sc_port_b<BW_IF> & get_base_port() = 0;
+ virtual sc_core::sc_export<FW_IF> & get_base_export() = 0;
+ virtual FW_IF & get_base_interface() = 0;
+};
+
+template <unsigned int BUSWIDTH,
+ typename FW_IF,
+ typename BW_IF> class tlm_base_initiator_socket_b;
+
+template <unsigned int BUSWIDTH,
+ typename FW_IF,
+ typename BW_IF,
+ int N
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+ ,sc_core::sc_port_policy POL
+#endif
+ > class tlm_base_initiator_socket;
+
+template <unsigned int BUSWIDTH = 32,
+ typename FW_IF = tlm_fw_transport_if<>,
+ typename BW_IF = tlm_bw_transport_if<>,
+ int N = 1
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+ ,sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND
+#endif
+ >
+class tlm_base_target_socket : public tlm_base_target_socket_b<BUSWIDTH, FW_IF, BW_IF>,
+ public sc_core::sc_export<FW_IF>
+{
+public:
+ typedef FW_IF fw_interface_type;
+ typedef BW_IF bw_interface_type;
+ typedef sc_core::sc_port<bw_interface_type, N
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+ , POL
+#endif
+ > port_type;
+
+ typedef sc_core::sc_export<fw_interface_type> export_type;
+ typedef tlm_base_initiator_socket_b<BUSWIDTH,
+ fw_interface_type,
+ bw_interface_type> base_initiator_socket_type;
+
+ typedef tlm_base_target_socket_b<BUSWIDTH,
+ fw_interface_type,
+ bw_interface_type> base_type;
+
+ template <unsigned int, typename, typename, int
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+ ,sc_core::sc_port_policy
+#endif
+
+ >
+ friend class tlm_base_initiator_socket;
+
+public:
+ tlm_base_target_socket()
+ : export_type(sc_core::sc_gen_unique_name("tlm_base_target_socket"))
+ , m_port(sc_core::sc_gen_unique_name("tlm_base_target_socket_port"))
+ {
+ }
+
+ explicit tlm_base_target_socket(const char* name)
+ : export_type(name)
+ , m_port(sc_core::sc_gen_unique_name((std::string(name) + "_port").c_str()))
+ {
+ }
+
+ virtual const char* kind() const
+ {
+ return "tlm_base_target_socket";
+ }
+
+ unsigned int get_bus_width() const
+ {
+ return BUSWIDTH;
+ }
+
+ //
+ // Bind target socket to initiator socket
+ // - Binds the port of the initiator socket to the export of the target
+ // socket
+ // - Binds the port of the target socket to the export of the initiator
+ // socket
+ //
+ virtual void bind(base_initiator_socket_type& s)
+ {
+ // initiator.port -> target.export
+ (s.get_base_port())(get_base_interface());
+ // target.port -> initiator.export
+ get_base_port()(s.get_base_interface());
+ }
+
+ void operator() (base_initiator_socket_type& s)
+ {
+ bind(s);
+ }
+
+ //
+ // Bind target socket to target socket (hierarchical bind)
+ // - Binds both the export and the port
+ //
+ virtual void bind(base_type& s)
+ {
+ // export
+ (get_base_export())(s.get_base_export());
+ // port
+ (s.get_base_port())(get_base_port());
+ }
+
+ void operator() (base_type& s)
+ {
+ bind(s);
+ }
+
+ //
+ // Bind interface to socket
+ // - Binds the interface to the export
+ //
+ virtual void bind(fw_interface_type& ifs)
+ {
+ export_type* exp = &get_base_export();
+ if( this == exp ) {
+ export_type::bind( ifs ); // non-virtual function call
+ } else {
+ exp->bind( ifs );
+ }
+ }
+
+ void operator() (fw_interface_type& s)
+ {
+ bind(s);
+ }
+
+ //
+ // Forward to 'size()' of port class
+ //
+ int size() const
+ {
+ return m_port.size();
+ }
+
+ //
+ // Forward to 'operator->()' of port class
+ //
+ bw_interface_type* operator->()
+ {
+ return m_port.operator->();
+ }
+
+ //
+ // Forward to 'operator[]()' of port class
+ //
+ bw_interface_type* operator[](int i)
+ {
+ return m_port.operator[](i);
+ }
+
+ // Implementation of pure virtual functions of base class
+
+ virtual sc_core::sc_port_b<BW_IF> & get_base_port()
+ { return m_port; }
+ virtual sc_core::sc_port_b<BW_IF> const & get_base_port() const
+ { return m_port; }
+
+ virtual FW_IF & get_base_interface()
+ { return *this; }
+ virtual FW_IF const & get_base_interface() const
+#if !( defined(IEEE_1666_SYSTEMC) && IEEE_1666_SYSTEMC >= 201101L )
+ { return *const_cast<export_type*>(static_cast<export_type const*>(this)); }
+#else
+ { return *this; }
+#endif
+
+ virtual sc_core::sc_export<FW_IF> & get_base_export()
+ { return *this; }
+ virtual sc_core::sc_export<FW_IF> const & get_base_export() const
+ { return *this; }
+
+protected:
+ port_type m_port;
+};
+
+
+//
+// Convenience blocking and non-blocking socket classes
+//
+
+template <unsigned int BUSWIDTH = 32,
+ typename TYPES = tlm_base_protocol_types,
+ int N = 1
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+ ,sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND
+#endif
+ >
+class tlm_target_socket :
+ public tlm_base_target_socket <BUSWIDTH,
+ tlm_fw_transport_if<TYPES>,
+ tlm_bw_transport_if<TYPES>,
+ N
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+ ,POL
+#endif
+ >
+{
+public:
+ tlm_target_socket() :
+ tlm_base_target_socket<BUSWIDTH,
+ tlm_fw_transport_if<TYPES>,
+ tlm_bw_transport_if<TYPES>,
+ N
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+ ,POL
+#endif
+ >()
+ {
+ }
+
+ explicit tlm_target_socket(const char* name) :
+ tlm_base_target_socket<BUSWIDTH,
+ tlm_fw_transport_if<TYPES>,
+ tlm_bw_transport_if<TYPES>,
+ N
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+ ,POL
+#endif
+ >(name)
+ {
+ }
+
+ virtual const char* kind() const
+ {
+ return "tlm_target_socket";
+ }
+};
+
+} // namespace tlm
+
+#endif
diff --git a/ext/systemc/src/tlm_core/tlm_2/tlm_version.h b/ext/systemc/src/tlm_core/tlm_2/tlm_version.h
new file mode 100644
index 000000000..e9b7a6569
--- /dev/null
+++ b/ext/systemc/src/tlm_core/tlm_2/tlm_version.h
@@ -0,0 +1,180 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/* ---------------------------------------------------------------------------------------
+ @file tlm_version.h
+
+ @brief TLM version header
+
+ Original Author:
+ Charles Wilson, XtremeEDA Corporation
+
+ @description
+ This header contains preprocessor and compiler symbols to allow for the determination
+ of the TLM version information. This conforms to IEEE 1666-2005 section 8.5.5 - 8.5.7
+ .
+ The following are provided:
+ .
+ preprocessor: TLM_VERSION_MAJOR numeric
+ TLM_VERSION_MINOR numeric
+ TLM_VERSION_PATCH numeric
+ TLM_VERSION_ORIGINATOR string ([A-Z][a-z][0-9]_)
+ TLM_VERSION_RELEASE_DATE ISO8601 date (YYYYMMDD)
+ TLM_VERSION_PRERELEASE string ([A-Z][a-z][0-9]_)
+ TLM_IS_PRERELEASE bool (1,0)
+ TLM_VERSION string {2.0.0_DR3-TLMWG}
+ TLM_COPYRIGHT string
+ .
+ compiler: tlm_version_major const unsigned int
+ tlm_version_minor const unsigned int
+ tlm_version_patch const unsigned int
+ tlm_version_originator const std::string
+ tlm_version_release_date const std::string
+ tlm_version_prerelease const std::string
+ tlm_is_prerelease const bool
+ tlm_version const string
+ tlm_copyright const string
+ .
+ accessors: inline const char* tlm_release (void)
+ inline const char* tlm_version (void)
+ inline const char* tlm_copyright (void)
+
+--------------------------------------------------------------------------------------- */
+
+#ifndef __TLM_VERSION_H__
+#define __TLM_VERSION_H__
+
+namespace tlm
+{
+
+#define TLM_VERSION_MAJOR 2 ///< version major level ( numeric )
+#define TLM_VERSION_MINOR 0 ///< version minor level ( numeric )
+#define TLM_VERSION_PATCH 3 ///< version patch level ( numeric )
+#define TLM_VERSION_ORIGINATOR "Accellera" ///< TLM creator string
+#define TLM_VERSION_SEPARATOR "." ///< version string separator
+
+#define TLM_IS_PRERELEASE 0 ///< pre-release flag ( 1 / 0 )
+
+#if TLM_IS_PRERELEASE
+# define TLM_VERSION_PRERELEASE "pub_rev" ///< pre-release version string
+#else
+# define TLM_VERSION_PRERELEASE "" ///< pre-release version string
+#endif
+
+#define TLM_VERSION_RELEASE_YEAR "2013" ///< release year ( YYYY )
+#define TLM_VERSION_RELEASE_MONTH "12" ///< release month ( MM )
+#define TLM_VERSION_RELEASE_DAY "15" ///< release day ( DD )
+
+#define TLM_COPYRIGHT \
+ "Copyright (c) 1996-" TLM_VERSION_RELEASE_YEAR " by all Contributors\n" \
+ "ALL RIGHTS RESERVED"
+
+/************************** do not modify below this line *******************************/
+
+/******************************* preprocessor symbols ***********************************/
+
+#define TLM_VERSION_RELEASE_DATE TLM_VERSION_RELEASE_YEAR \
+ TLM_VERSION_RELEASE_MONTH \
+ TLM_VERSION_RELEASE_DAY
+
+#define TLM_VERSION_STR(x) TLM_VERSION_STR_HELPER(x)
+#define TLM_VERSION_STR_HELPER(x) #x
+
+#define TLM_VERSION_STRING_MAJOR TLM_VERSION_STR(TLM_VERSION_MAJOR)
+#define TLM_VERSION_STRING_MINOR TLM_VERSION_STR(TLM_VERSION_MINOR)
+#define TLM_VERSION_STRING_PATCH TLM_VERSION_STR(TLM_VERSION_PATCH)
+
+#define TLM_VERSION_STRING_MMP TLM_VERSION_STRING_MAJOR TLM_VERSION_SEPARATOR \
+ TLM_VERSION_STRING_MINOR TLM_VERSION_SEPARATOR \
+ TLM_VERSION_STRING_PATCH
+
+#define TLM_VERSION_STRING_PRE_START "_"
+#define TLM_VERSION_STRING_PRE_END "-"
+
+#if ( TLM_IS_PRERELEASE == 1 )
+
+#define TLM_VERSION_STRING_PRERELEASE TLM_VERSION_PRERELEASE
+#define TLM_VERSION_STRING_RELEASE_DATE ""
+
+#else /* TLM_IS_PRERELEASE == 1 */
+
+#define TLM_VERSION_STRING_PRERELEASE ""
+#define TLM_VERSION_STRING_RELEASE_DATE TLM_VERSION_RELEASE_DATE
+
+#endif /* TLM_IS_PRERELEASE == 1 */
+
+#define TLM_VERSION_STRING TLM_VERSION_STRING_MMP \
+ TLM_VERSION_STRING_PRE_START \
+ TLM_VERSION_STRING_PRERELEASE \
+ TLM_VERSION_STRING_PRE_END \
+ TLM_VERSION_ORIGINATOR
+
+#define TLM_VERSION_STRING_2 "TLM " \
+ TLM_VERSION_STRING_MMP \
+ " --- " \
+ TLM_VERSION_RELEASE_YEAR \
+ "-" \
+ TLM_VERSION_RELEASE_MONTH \
+ "-" \
+ TLM_VERSION_RELEASE_DAY
+
+#define TLM_VERSION TLM_VERSION_STRING
+
+/********************************* compiler symbols **************************************/
+
+const unsigned int tlm_version_major ( TLM_VERSION_MAJOR );
+const unsigned int tlm_version_minor ( TLM_VERSION_MINOR );
+const unsigned int tlm_version_patch ( TLM_VERSION_PATCH );
+
+const bool tlm_is_prerelease ( TLM_IS_PRERELEASE );
+
+const std::string tlm_version_string ( TLM_VERSION_STRING );
+const std::string tlm_version_originator ( TLM_VERSION_ORIGINATOR );
+const std::string tlm_version_prerelease ( TLM_VERSION_PRERELEASE );
+const std::string tlm_version_release_date ( TLM_VERSION_STRING_RELEASE_DATE );
+const std::string tlm_copyright_string ( TLM_COPYRIGHT );
+const std::string tlm_version_string_2 ( TLM_VERSION_STRING_2 );
+
+inline const char*
+tlm_release
+( void
+)
+{
+ return tlm_version_string.c_str ();
+}
+
+inline const char*
+tlm_version
+( void
+)
+{
+ return tlm_version_string_2.c_str ();
+}
+
+inline const char*
+tlm_copyright
+( void
+)
+{
+ return tlm_copyright_string.c_str ();
+}
+
+} // namespace tlm
+
+#endif /* __TLM_VERSION_H__ */
diff --git a/ext/systemc/src/tlm_utils/README.txt b/ext/systemc/src/tlm_utils/README.txt
new file mode 100644
index 000000000..8be587bdf
--- /dev/null
+++ b/ext/systemc/src/tlm_utils/README.txt
@@ -0,0 +1,85 @@
+
+TLM-2.0 standard utilities
+==========================
+
+Dir: include/tlm_utils
+
+SubDirs:
+
+Files: README.txt
+ instance_specific_extensions.h
+ multi_passthrough_initiator_socket.h
+ multi_passthrough_target_socket.h
+ multi_socket_bases.h
+ peq_with_get.h
+ simple_initiator_socket.h
+ simple_target_socket.h
+ peq_with_cb_and_phase.h
+ passthrough_target_socket.h
+ tlm_quantumkeeper.h
+
+
+Comments
+========
+
+This directory contains a number of ease-of-use and convenience implementations
+for the interoperability standard. All objects defined in the header files of
+this directory are contained in the tlm_util namespace.
+There is no tlm_utils.h header files containing all includes in order to avoid
+additional dependencies for TLM 2.0
+
+Files:
+ simple_initiator_socket.h
+ version of an initiator socket that has a default implementation of all
+ interfaces and allows to register an implementation for any of the
+ interfaces to the socket, either unique interfaces or tagged interfaces
+ (carrying an additional id)
+
+ simple_target_socket.h
+ version of a target socket that has a default implementation of all
+ interfaces and allows to register an implementation for any of the
+ interfaces to the socket, either unique interfaces or tagged interfaces
+ (carrying an additional id)
+ This socket allows to register only 1 of the transport interfaces
+ (blocking or non-blocking) and implements a conversion in case the
+ socket is used on the other interface
+
+ passthrough_target_socket.h
+ version of a target socket that has a default implementation of all
+ interfaces and allows to register an implementation for any of the
+ interfaces to the socket.
+
+ multi_passthrough_initiator_socket.h
+ an implementation of a socket that allows to bind multiple targets to the
+ same initiator socket. Implements a mechanism to allow to identify in the
+ backward path through which index of the socket the call passed through
+
+ multi_passthrough_target_socket.h
+ an implementation of a socket that allows to bind multiple initiators to
+ the same target socket. Implements a mechanism to allow to identify in the
+ forward path through which index of the socket the call passed through
+
+ multi_socket_bases.h
+ contains base class definitions used by the multi_passthrough sockets
+
+ peq_with_get.h
+ payload event queue (PEQ) implementation using a pull interface.
+ Has a get_next_transaction API that returns the transaction that is
+ scheduled in the event queue
+
+ peq_with_cb_and_phase.h
+ another payload event queue, this one with a push interface (callback
+ mechanism ). Allows to register a callback that will be called whenever
+ the event in the event queue is triggered, the callback gets transaction
+ and phase as arguments
+
+ instance_specific_extensions.h
+ is an implementation for adding extentions in the generic payload that
+ are specific to an instance along the path of a transaction, to allow that
+ extentions of the same type can be used by the different blocks along
+ the path of the transaction
+
+ tlm_quantumkeeper.h
+ is an convenience object used to keep track of the local time in
+ an initiator (how much it has run ahead of the SystemC time), to
+ synchronize with SystemC time etc.
diff --git a/ext/systemc/src/tlm_utils/instance_specific_extensions.h b/ext/systemc/src/tlm_utils/instance_specific_extensions.h
new file mode 100644
index 000000000..b17b86219
--- /dev/null
+++ b/ext/systemc/src/tlm_utils/instance_specific_extensions.h
@@ -0,0 +1,306 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*
+Instance specific extensions, are extension that only a single instance of a module
+may access. They are invisible to all other modules; they are private to this
+instance so to speak.
+
+As they are only of value to a certain instance, this instance knows very well
+when it needs them and when it does not need them any longer (usually when
+a transaction passes through a module for the last time).
+It does not have to care if anyone else in the system may still have a
+reference to the transaction as this one is not able to access the extension
+anyway.
+Therefore the instance is obliged to call set_extension when it wants to add a
+private extension and clear_extension when it does not need it any more.
+
+To get access to an instance specifc extension the module must own a so called
+instance_specific_extension_accessor that provides the exclusive access rights.
+Assuming the instance_specific_extension_accessor of a given module is called m_accessor
+and the transaction of which the private extension is about to be accessed
+is called txn, then the calls have to be
+
+m_accessor(txn).set_extension(...);
+or
+m_accessor(txn).clear_extension(...);
+
+The owner of the private extension is responsible to allocate/deallocate
+the extension before/after setting/clearing the extension.
+*/
+
+#ifndef __INSTANCE_SPECIFIC_EXTENSIONS_H__
+#define __INSTANCE_SPECIFIC_EXTENSIONS_H__
+
+#include <tlm>
+
+namespace tlm_utils {
+
+//Helper to do the numbering of private extension accessors
+inline unsigned int max_num_ispex_accessors(bool increment=false)
+{
+ static unsigned int max_num = 0;
+ if (increment) ++max_num;
+ return max_num;
+}
+
+//Helper to do the index generation for private extensions
+inline unsigned int max_num_ispex(bool increment=false)
+{
+ static unsigned int max_num = 0;
+ if (increment) ++max_num;
+ return max_num;
+}
+
+//The private extension base. Similar to normal extension base, but without clone and free
+class ispex_base
+{
+public:
+ virtual ~ispex_base() {}
+protected:
+ static unsigned int register_private_extension()
+ {
+ return (max_num_ispex(true) - 1);
+ };
+};
+
+//The templated private extension. Similar to normal extension
+template <typename T>
+class
+instance_specific_extension : public ispex_base{
+public:
+ virtual ~instance_specific_extension() {}
+ const static unsigned int priv_id;
+};
+
+template <typename T>
+const
+unsigned int instance_specific_extension<T>::priv_id = ispex_base::register_private_extension();
+
+
+//this thing is basically a snippet of the generic_payload
+// it contains all the extension specific code (the extension API so to speak)
+// the differences are:
+// - it calls back to its owner whenever a real (==non-NULL) extension gets set for the first time
+// - it calls back to its owner whenever a living (==non-NULL) extension gets cleared
+template<typename U>
+class instance_specific_extensions_per_accessor{
+public:
+
+ typedef void (U::*cb)();
+
+ instance_specific_extensions_per_accessor(U* container, cb inc, cb dec): m_container(container), m_inc(inc), m_dec(dec){
+ }
+
+ template <typename T> T* set_extension(T* ext)
+ {
+ resize_extensions();
+ T* tmp = static_cast<T*>(m_extensions[T::priv_id]);
+ m_extensions[T::priv_id] = static_cast<ispex_base*>(ext);
+ if (!tmp && ext) (m_container->*m_inc)();
+ return tmp;
+ }
+ // non-templatized version with manual index:
+ ispex_base* set_extension(unsigned int index,
+ ispex_base* ext)
+ {
+ resize_extensions();
+ ispex_base* tmp = m_extensions[index];
+ m_extensions[index] = ext;
+ if (!tmp && ext) (m_container->*m_inc)();
+ return tmp;
+ }
+
+ // Check for an extension, ext will point to 0 if not present
+ template <typename T> void get_extension(T*& ext) const
+ {
+ ext = static_cast<T*>(m_extensions[T::priv_id]);
+ }
+ // Non-templatized version:
+ ispex_base* get_extension(unsigned int index) const
+ {
+ return m_extensions[index];
+ }
+
+ // Clear extension, the argument is needed to find the right index:
+ template <typename T> void clear_extension(const T* ext)
+ {
+ resize_extensions();
+ if (m_extensions[T::priv_id]) (m_container->*m_dec)();
+ m_extensions[T::priv_id] = static_cast<ispex_base*>(0);
+ }
+ // Non-templatized version with manual index
+ void clear_extension(unsigned int index)
+ {
+ if (index < m_extensions.size())
+ {
+ if (m_extensions[index]) (m_container->*m_dec)();
+ m_extensions[index] = static_cast<ispex_base*>(0);
+ }
+ }
+
+ // Make sure the extension array is large enough. Can be called once by
+ // an initiator module (before issuing the first transaction) to make
+ // sure that the extension array is of correct size. This is only needed
+ // if the initiator cannot guarantee that the generic payload object is
+ // allocated after C++ static construction time.
+ void resize_extensions()
+ {
+ m_extensions.expand(max_num_ispex());
+ }
+
+private:
+ tlm::tlm_array<ispex_base*> m_extensions;
+ U* m_container;
+ cb m_inc, m_dec;
+
+};
+
+class instance_specific_extension_container;
+
+
+//the pool for the container, plain as can be
+class instance_specific_extension_container_pool{
+ friend class instance_specific_extension_carrier;
+ friend class instance_specific_extension_container;
+ instance_specific_extension_container_pool() : unused(NULL){}
+ inline ~instance_specific_extension_container_pool();
+ inline static instance_specific_extension_container_pool& get_ispexcont_pool(){ static instance_specific_extension_container_pool tmp; return tmp;}
+ inline instance_specific_extension_container* create();
+ inline void free(instance_specific_extension_container*);
+
+ instance_specific_extension_container* unused;
+};
+
+class instance_specific_extension_carrier;
+
+//this thing contains the vector of extensions per accessor
+//which can be really large so this one should be pool allocated
+// therefore it keeps a use_count of itself to automatically free itself
+// - to this end it provides callbacks to the extensions per accessor
+// to increment and decrement the use_count
+class instance_specific_extension_container{
+ friend class instance_specific_extension_container_pool;
+ friend class instance_specific_extension_accessor;
+ friend class instance_specific_extension_carrier;
+
+ instance_specific_extension_container(): use_count(0), next(NULL){resize();}
+
+ void resize(){
+ m_ispex_per_accessor.resize(max_num_ispex_accessors());
+ for (unsigned int i=0; i<m_ispex_per_accessor.size(); i++) {
+ m_ispex_per_accessor[i]=new instance_specific_extensions_per_accessor<instance_specific_extension_container>(this,
+ &instance_specific_extension_container::inc_use_count,
+ &instance_specific_extension_container::dec_use_count
+ );
+ m_ispex_per_accessor[i]->resize_extensions();
+ }
+ }
+
+ ~instance_specific_extension_container(){
+ for (unsigned int i=0; i<m_ispex_per_accessor.size(); i++) delete m_ispex_per_accessor[i];
+ }
+
+ void inc_use_count(){use_count++;}
+ inline void dec_use_count();
+
+ std::vector<instance_specific_extensions_per_accessor<instance_specific_extension_container>* > m_ispex_per_accessor;
+ unsigned int use_count;
+ tlm::tlm_generic_payload* my_txn;
+ instance_specific_extension_carrier* my_carrier;
+ instance_specific_extension_container* next; //for pooling
+};
+
+
+inline instance_specific_extension_container_pool::~instance_specific_extension_container_pool(){
+ while(unused) { instance_specific_extension_container* tmp=unused; unused=unused->next; delete tmp;}
+}
+
+instance_specific_extension_container* instance_specific_extension_container_pool::create(){
+ if (!unused) {unused=new instance_specific_extension_container();}
+ instance_specific_extension_container* tmp=unused;
+ unused=unused->next;
+ return tmp;
+}
+
+void instance_specific_extension_container_pool::free(instance_specific_extension_container* cont){
+ cont->next=unused;
+ unused=cont;
+}
+
+//This is the class that actually sits in the extension array
+//we keep this small since that one gets allocated and deallocated all the times
+class instance_specific_extension_carrier: public tlm::tlm_extension<instance_specific_extension_carrier>{
+ friend class instance_specific_extension_accessor;
+
+public:
+ instance_specific_extension_carrier(){
+ m_container=instance_specific_extension_container_pool::get_ispexcont_pool().create();
+ m_container->my_carrier=this;
+ }
+
+ virtual tlm::tlm_extension_base* clone() const {
+ //we don't clone since private info is instance specific and associated to a given txn (the original)
+ //so the deep copied txn will be virgin in terms of private info
+ return NULL;
+ }
+ void copy_from(tlm::tlm_extension_base const &){return;}
+ void free(){return;}
+private:
+ instance_specific_extension_container* m_container;
+};
+
+inline void instance_specific_extension_container::dec_use_count(){
+ if ((--use_count)==0) { //if this container isn't used any more
+ instance_specific_extension_container_pool::get_ispexcont_pool().free(this); //we send it back to our pool
+ //we have to do that manually, as we cannot rely on the fact that there is MM in the txn
+ my_txn->clear_extension(my_carrier); //and remove it from the transaction's extension array
+ delete my_carrier;
+ }
+}
+
+
+//This class 'hides' all the instance specific extension stuff from the user
+// he instantiates one of those (e.g. instance_specific_extension_accessor extAcc;) and can then access
+// the private extensions
+// extAcc(txn).extensionAPIFnCall()
+// where extensionAPIFnCall is set_extension, get_extension, clear_extension,...
+class instance_specific_extension_accessor{
+public:
+ instance_specific_extension_accessor(): m_index(max_num_ispex_accessors(true)-1){}
+
+ template<typename T>
+ inline instance_specific_extensions_per_accessor<instance_specific_extension_container>& operator()(T& txn){
+ instance_specific_extension_carrier* carrier;
+ txn.get_extension(carrier);
+ if (!carrier){
+ carrier=new instance_specific_extension_carrier();
+ carrier->m_container->my_txn=&txn;
+ txn.set_extension(carrier);
+ }
+ return *(carrier->m_container->m_ispex_per_accessor[m_index]);
+ }
+
+protected:
+ unsigned int m_index;
+};
+
+}
+
+#endif
diff --git a/ext/systemc/src/tlm_utils/multi_passthrough_initiator_socket.h b/ext/systemc/src/tlm_utils/multi_passthrough_initiator_socket.h
new file mode 100644
index 000000000..6404d84bb
--- /dev/null
+++ b/ext/systemc/src/tlm_utils/multi_passthrough_initiator_socket.h
@@ -0,0 +1,299 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+#ifndef __MULTI_PASSTHROUGH_INITIATOR_SOCKET_H__
+#define __MULTI_PASSTHROUGH_INITIATOR_SOCKET_H__
+
+#include "multi_socket_bases.h"
+
+namespace tlm_utils {
+
+/*
+This class implements a trivial multi initiator socket.
+The triviality refers to the fact that the socket does not
+do blocking to non-blocking or non-blocking to blocking conversions.
+
+It allows to connect multiple targets to this socket.
+The user has to register callbacks for the bw interface methods
+he likes to use. The callbacks are basically equal to the bw interface
+methods but carry an additional integer that indicates to which
+index of this socket the calling target is connected.
+*/
+template <typename MODULE,
+ unsigned int BUSWIDTH = 32,
+ typename TYPES = tlm::tlm_base_protocol_types,
+ unsigned int N=0
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+ ,sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND
+#endif
+ >
+class multi_passthrough_initiator_socket: public multi_init_base< BUSWIDTH,
+ TYPES,
+ N
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+ ,POL
+#endif
+ >
+{
+
+public:
+
+ //typedefs
+ // tlm 2.0 types for nb_transport
+ typedef typename TYPES::tlm_payload_type transaction_type;
+ typedef typename TYPES::tlm_phase_type phase_type;
+ typedef tlm::tlm_sync_enum sync_enum_type;
+
+ // typedefs to keep the fn ptr notations short
+ typedef sync_enum_type (MODULE::*nb_cb)(int,
+ transaction_type&,
+ phase_type&,
+ sc_core::sc_time&);
+ typedef void (MODULE::*dmi_cb)(int, sc_dt::uint64, sc_dt::uint64);
+
+ typedef multi_init_base<BUSWIDTH,
+ TYPES,
+ N
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+ ,POL
+#endif
+ > base_type;
+
+ typedef typename base_type::base_target_socket_type base_target_socket_type;
+
+ //CTOR
+ multi_passthrough_initiator_socket()
+ : base_type(sc_core::sc_gen_unique_name("multi_passthrough_initiator_socket"))
+ , m_hierarch_bind(0)
+ , m_beoe_disabled(false)
+ , m_dummy(42)
+ {
+ }
+
+ //CTOR
+ multi_passthrough_initiator_socket(const char* name)
+ : base_type(name)
+ , m_hierarch_bind(0)
+ , m_beoe_disabled(false)
+ , m_dummy(42)
+ {
+ }
+
+ ~multi_passthrough_initiator_socket(){
+ //clean up everything allocated by 'new'
+ for (unsigned int i=0; i<m_binders.size(); i++) delete m_binders[i];
+ }
+
+ //simple helpers for warnings an errors to shorten in code notation
+ void display_warning(const std::string& text) const {
+ std::stringstream s;
+ s<<"WARNING in instance "<<base_type::name()<<": "<<text;
+ SC_REPORT_WARNING("/OSCI_TLM-2/multi_socket", s.str().c_str());
+ }
+
+ void display_error(const std::string& text) const {
+ std::stringstream s;
+ s<<"ERROR in instance "<<base_type::name()<<": "<<text;
+ SC_REPORT_ERROR("/OSCI_TLM-2/multi_socket", s.str().c_str());
+ }
+
+
+ //register callback for nb transport of bw interface
+ void register_nb_transport_bw(MODULE* mod,
+ sync_enum_type (MODULE::*cb)(int,
+ transaction_type&,
+ phase_type&,
+ sc_core::sc_time&))
+ {
+ //warn if there already is a callback
+ if (!m_nb_f.empty()){
+ display_warning("NBTransport_bw callback already registered.");
+ return;
+ }
+
+ //set the functor
+ m_nb_f.set_function(mod, cb);
+ }
+
+ //register callback for dmi function of bw interface
+ void register_invalidate_direct_mem_ptr(MODULE* mod,
+ void (MODULE::*cb)(int, sc_dt::uint64, sc_dt::uint64))
+ {
+ //warn if there already is a callback
+ if (!m_dmi_f.empty()){
+ display_warning("InvalidateDMI callback already registered.");
+ return;
+ }
+
+ //set the functor
+ m_dmi_f.set_function(mod, cb);
+ }
+
+ //Override virtual functions of the tlm_initiator_socket:
+ // this function is called whenever an sc_port (as part of a target socket)
+ // wants to bind to the export of the underlying tlm_initiator_socket
+ //At this time a callback binder is created an returned to the sc_port
+ // of the target socket, so that it binds to the callback binder
+ virtual tlm::tlm_bw_transport_if<TYPES>& get_base_interface()
+ {
+ m_binders.push_back(new callback_binder_bw<TYPES>(m_binders.size()));
+ return *m_binders[m_binders.size()-1];
+ }
+
+ // const overload not allowed for multi-sockets
+ virtual const tlm::tlm_bw_transport_if<TYPES>& get_base_interface() const
+ {
+ display_error("'get_base_interface()' const not allowed for multi-sockets.");
+ return base_type::get_base_interface();
+ }
+
+ //Override virtual functions of the tlm_initiator_socket:
+ // this function is called whenever an sc_export (as part of a initiator socket)
+ // wants to bind to the export of the underlying tlm_initiator_socket
+ // i.e. a hierarchical bind takes place
+ virtual sc_core::sc_export<tlm::tlm_bw_transport_if<TYPES> >& get_base_export()
+ {
+ if (!m_beoe_disabled) //we are not bound hierarchically
+ base_type::m_export.bind(m_dummy); //so we bind the dummy to avoid a SystemC error
+ return base_type::get_base_export(); //and then return our own export so that the hierarchical binding is set up properly
+ }
+
+ virtual const sc_core::sc_export<tlm::tlm_bw_transport_if<TYPES> >& get_base_export() const
+ {
+ return base_type::get_base_export();
+ }
+
+ //bind against a target socket
+ virtual void bind(base_target_socket_type& s)
+ {
+ //error if this socket is already bound hierarchically
+ if (m_hierarch_bind)
+ display_error("Already hierarchically bound.");
+
+ base_type::bind(s); //satisfy systemC, leads to a call to get_base_interface()
+
+ //try to cast the target socket into a fw interface
+ sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >* p_ex_s=dynamic_cast<sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >*>(&s);
+ if (!p_ex_s) display_error("Multi socket not bound to tlm_socket.");
+
+ //try a cast into a multi sockets
+ multi_to_multi_bind_base<TYPES>* test=dynamic_cast<multi_to_multi_bind_base<TYPES>*> (p_ex_s);
+ if (test) //did we just do a multi-multi bind??
+ //if that is the case the multi target socket must have just created a callback binder
+ // which we want to get from it.
+ //Moreover, we also just created one, which we will pass to it.
+ m_sockets.push_back(test->get_last_binder(m_binders[m_binders.size()-1]));
+ else{ // if not just bind normally
+ sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >& ex_s=*p_ex_s;
+ m_sockets.push_back(&((tlm::tlm_fw_transport_if<TYPES>&)ex_s)); //store the interface we are bound against
+ }
+ }
+
+ //operator notation for direct bind
+ void operator() (base_target_socket_type& s)
+ {
+ bind(s);
+ }
+
+ //SystemC standard callback before end of elaboration
+ void before_end_of_elaboration(){
+ //if our export hasn't been bound yet (due to a hierarch binding)
+ // we bind it now to avoid a SystemC error.
+ //We must do that, because it is legal not to register a callback on this socket
+ // as the user might only use b_transport
+ if (!base_type::m_export.get_interface()){
+ base_type::m_export.bind(m_dummy);
+ }
+
+ //'break' here if the socket was told not to do callback binding
+ if (m_beoe_disabled) return;
+
+ //get the callback binders of the top of the hierachical bind chain
+ // NOTE: this could be the same socket if there is no hierachical bind
+ std::vector<callback_binder_bw<TYPES>* >& binders=get_hierarch_bind()->get_binders();
+
+ //get the interfaces bound to the top of the hierachical bind chain
+ // NOTE: this could be the same socket if there is no hierachical bind
+ m_used_sockets=get_hierarch_bind()->get_sockets();
+
+ //register the callbacks of this socket with the callback binders
+ // we just got from the top of the hierachical bind chain
+ for (unsigned int i=0; i<binders.size(); i++) {
+ binders[i]->set_callbacks(m_nb_f, m_dmi_f);
+ }
+ }
+
+ //
+ // Bind multi initiator socket to multi initiator socket (hierarchical bind)
+ //
+ virtual void bind(base_type& s)
+ {
+ if (m_binders.size()) //a multi socket is either bound hierarchically or directly
+ display_error("Socket already directly bound.");
+ if (m_hierarch_bind){
+ display_warning("Socket already bound hierarchically. Bind attempt ignored.");
+ return;
+ }
+
+ //remember to which socket we are hierarchically bound and disable it,
+ // so that it won't try to register callbacks itself
+ s.disable_cb_bind();
+ m_hierarch_bind=&s;
+ base_type::bind(s); //satisfy SystemC
+ }
+
+ //operator notation for hierarchical bind
+ void operator() (base_type& s)
+ {
+ bind(s);
+ }
+
+ //get access to sub port
+ tlm::tlm_fw_transport_if<TYPES>* operator[](int i){return m_used_sockets[i];}
+
+ //get the number of bound targets
+ // NOTE: this is only valid at end of elaboration!
+ unsigned int size() {return get_hierarch_bind()->get_sockets().size();}
+
+protected:
+ //implementation of base class interface
+ base_type* get_hierarch_bind(){if (m_hierarch_bind) return m_hierarch_bind->get_hierarch_bind(); else return this;}
+ void disable_cb_bind(){ m_beoe_disabled=true;}
+ std::vector<callback_binder_bw<TYPES>* >& get_binders(){return m_binders;}
+ std::vector<tlm::tlm_fw_transport_if<TYPES>*>& get_sockets(){return m_sockets;}
+ //vector of connected sockets
+ std::vector<tlm::tlm_fw_transport_if<TYPES>*> m_sockets;
+ std::vector<tlm::tlm_fw_transport_if<TYPES>*> m_used_sockets;
+ //vector of binders that convert untagged interface into tagged interface
+ std::vector<callback_binder_bw<TYPES>*> m_binders;
+
+ base_type* m_hierarch_bind; //pointer to hierarchical bound multi port
+ bool m_beoe_disabled; // bool that remembers whether this socket shall bind callbacks or not
+ callback_binder_bw<TYPES> m_dummy; //a callback binder that is bound to the underlying export
+ // in case there was no real bind
+
+ //callbacks as functors
+ // (allows to pass the callback to another socket that does not know the type of the module that owns
+ // the callbacks)
+ typename callback_binder_bw<TYPES>::nb_func_type m_nb_f;
+ typename callback_binder_bw<TYPES>::dmi_func_type m_dmi_f;
+};
+
+}
+
+#endif
diff --git a/ext/systemc/src/tlm_utils/multi_passthrough_target_socket.h b/ext/systemc/src/tlm_utils/multi_passthrough_target_socket.h
new file mode 100644
index 000000000..03270f7a1
--- /dev/null
+++ b/ext/systemc/src/tlm_utils/multi_passthrough_target_socket.h
@@ -0,0 +1,340 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+#ifndef __MULTI_PASSTHROUGH_TARGET_SOCKET_H__
+#define __MULTI_PASSTHROUGH_TARGET_SOCKET_H__
+
+#include "tlm_utils/multi_socket_bases.h"
+#include <sstream>
+
+namespace tlm_utils {
+
+/*
+This class implements a trivial multi target socket.
+The triviality refers to the fact that the socket does not
+do blocking to non-blocking or non-blocking to blocking conversions.
+
+It allows to connect multiple initiators to this socket.
+The user has to register callbacks for the fw interface methods
+he likes to use. The callbacks are basically equal to the fw interface
+methods but carry an additional integer that indicates to which
+index of this socket the calling initiator is connected.
+*/
+template <typename MODULE,
+ unsigned int BUSWIDTH = 32,
+ typename TYPES = tlm::tlm_base_protocol_types,
+ unsigned int N=0
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+ ,sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND
+#endif
+ >
+class multi_passthrough_target_socket: public multi_target_base< BUSWIDTH,
+ TYPES,
+ N
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+ ,POL
+#endif
+ >
+ , public multi_to_multi_bind_base<TYPES>
+{
+
+public:
+
+ //typedefs
+ // tlm 2.0 types for nb_transport
+ typedef typename TYPES::tlm_payload_type transaction_type;
+ typedef typename TYPES::tlm_phase_type phase_type;
+ typedef tlm::tlm_sync_enum sync_enum_type;
+
+ // typedefs to keep the fn ptr notations short
+ typedef sync_enum_type (MODULE::*nb_cb)(int, transaction_type&, phase_type&, sc_core::sc_time&);
+ typedef void (MODULE::*b_cb)(int, transaction_type&, sc_core::sc_time&);
+ typedef unsigned int (MODULE::*dbg_cb)(int, transaction_type& txn);
+ typedef bool (MODULE::*dmi_cb)(int, transaction_type& txn, tlm::tlm_dmi& dmi);
+
+ typedef multi_target_base<BUSWIDTH,
+ TYPES,
+ N
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+ ,POL
+#endif
+ > base_type;
+
+ typedef typename base_type::base_initiator_socket_type base_initiator_socket_type;
+
+ //CTOR
+ multi_passthrough_target_socket()
+ : base_type(sc_core::sc_gen_unique_name("multi_passthrough_target_socket"))
+ , m_hierarch_bind(0)
+ , m_eoe_disabled(false)
+ , m_export_callback_created(false)
+ {
+ }
+
+ //CTOR
+ multi_passthrough_target_socket(const char* name)
+ : base_type(name)
+ , m_hierarch_bind(0)
+ , m_eoe_disabled(false)
+ , m_export_callback_created(false)
+ {
+ }
+
+ ~multi_passthrough_target_socket(){
+ //clean up everything allocated by 'new'
+ for (unsigned int i=0; i<m_binders.size(); i++) delete m_binders[i];
+ }
+
+ //simple helpers for warnings an errors to shorten in code notation
+ void display_warning(const std::string& text) const {
+ std::stringstream s;
+ s<<"WARNING in instance "<<base_type::name()<<": "<<text;
+ SC_REPORT_WARNING("/OSCI_TLM-2/multi_socket", s.str().c_str());
+ }
+
+ void display_error(const std::string& text) const {
+ std::stringstream s;
+ s<<"ERROR in instance "<<base_type::name()<<": "<<text;
+ SC_REPORT_ERROR("/OSCI_TLM-2/multi_socket", s.str().c_str());
+ }
+
+ void check_export_binding()
+ {
+ //if our export hasn't been bound yet (due to a hierarch binding)
+ // we bind it now.
+ //We do that here as the user of the target port HAS to bind at least on callback,
+ //otherwise the socket was useless. Nevertheless, the target socket may still
+ // stay unbound afterwards.
+ if (!sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >::get_interface())
+ {
+ // We bind to a callback_binder that will be used as the first interface
+ // i.e. calls to the sc_export will have the same ID as calls from the first initator
+ // socket bound
+ callback_binder_fw<TYPES> * binder;
+
+ if (m_binders.size() == 0)
+ {
+ binder = new callback_binder_fw<TYPES>(m_binders.size());
+ m_binders.push_back(binder);
+ m_export_callback_created = true;
+ }
+ else
+ {
+ binder = m_binders[0];
+ }
+
+ sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >::bind(*binder);
+ }
+ }
+
+ //register callback for nb transport of fw interface
+ void register_nb_transport_fw(MODULE* mod,
+ nb_cb cb)
+ {
+ check_export_binding();
+
+ //warn if there already is a callback
+ if (!m_nb_f.empty()){
+ display_warning("NBTransport_bw callback already registered.");
+ return;
+ }
+
+ //set the functor
+ m_nb_f.set_function(mod, cb);
+ }
+
+ //register callback for b transport of fw interface
+ void register_b_transport(MODULE* mod,
+ b_cb cb)
+ {
+ check_export_binding();
+
+ //warn if there already is a callback
+ if (!m_b_f.empty()){
+ display_warning("BTransport callback already registered.");
+ return;
+ }
+
+ //set the functor
+ m_b_f.set_function(mod, cb);
+ }
+
+ //register callback for debug transport of fw interface
+ void register_transport_dbg(MODULE* mod,
+ dbg_cb cb)
+ {
+ check_export_binding();
+
+ //warn if there already is a callback
+ if (!m_dbg_f.empty()){
+ display_warning("DebugTransport callback already registered.");
+ return;
+ }
+
+ //set the functor
+ m_dbg_f.set_function(mod, cb);
+ }
+
+ //register callback for DMI of fw interface
+ void register_get_direct_mem_ptr(MODULE* mod,
+ dmi_cb cb)
+ {
+ check_export_binding();
+
+ //warn if there already is a callback
+ if (!m_dmi_f.empty()){
+ display_warning("DMI callback already registered.");
+ return;
+ }
+
+ //set the functor
+ m_dmi_f.set_function(mod, cb);
+ }
+
+
+ //Override virtual functions of the tlm_target_socket:
+ // this function is called whenever an sc_port (as part of a init socket)
+ // wants to bind to the export of the underlying tlm_target_socket
+ //At this time a callback binder is created an returned to the sc_port
+ // of the init socket, so that it binds to the callback binder
+ virtual tlm::tlm_fw_transport_if<TYPES>& get_base_interface()
+ {
+ //error if this socket is already bound hierarchically
+ if (m_hierarch_bind) display_error("Socket already bound hierarchically.");
+
+ if (!m_export_callback_created)
+ m_binders.push_back(new callback_binder_fw<TYPES>(m_binders.size()));
+ else
+ m_export_callback_created = false;
+
+ return *m_binders[m_binders.size()-1];
+ }
+
+ // const overload not allowed for multi-sockets
+ virtual const tlm::tlm_fw_transport_if<TYPES>& get_base_interface() const
+ {
+ display_error("'get_base_interface()' const not allowed for multi-sockets.");
+ return base_type::get_base_interface();
+ }
+
+ //just return the export of the underlying tlm_target_socket in case of a hierarchical bind
+ virtual sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >& get_base_export()
+ {
+ return *this;
+ }
+
+ //just return the export of the underlying tlm_target_socket in case of a hierarchical bind
+ virtual const sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >& get_base_export() const
+ {
+ return base_type::get_base_export();
+ }
+
+ //the standard end of elaboration callback
+ void end_of_elaboration(){
+ //'break' here if the socket was told not to do callback binding
+ if (m_eoe_disabled) return;
+
+ //get the callback binders and the multi binds of the top of the hierachical bind chain
+ // NOTE: this could be the same socket if there is no hierachical bind
+ std::vector<callback_binder_fw<TYPES>* >& binders=get_hierarch_bind()->get_binders();
+ std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES>*>& multi_binds=get_hierarch_bind()->get_multi_binds();
+
+ //iterate over all binders
+ for (unsigned int i=0; i<binders.size(); i++) {
+ binders[i]->set_callbacks(m_nb_f, m_b_f, m_dmi_f, m_dbg_f); //set the callbacks for the binder
+ if (multi_binds.find(i)!=multi_binds.end()) //check if this connection is multi-multi
+ //if so remember the interface
+ m_sockets.push_back(multi_binds[i]);
+ else{ //if we are bound to a normal socket
+ //get the calling port and try to cast it into a tlm socket base
+ base_initiator_socket_type* test=dynamic_cast<base_initiator_socket_type*>(binders[i]->get_other_side());
+ if (!test){display_error("Not bound to tlm_socket.");}
+ m_sockets.push_back(&test->get_base_interface()); //remember the interface
+ }
+ }
+ }
+
+ //
+ // Bind multi target socket to multi target socket (hierarchical bind)
+ //
+ virtual void bind(base_type& s)
+ {
+ //warn if already bound hierarchically
+ if (m_eoe_disabled){
+ display_warning("Socket already bound hierarchically. Bind attempt ignored.");
+ return;
+ }
+
+ //disable our own end of elaboration call
+ disable_cb_bind();
+
+ //inform the bound target socket that it is bound hierarchically now
+ s.set_hierarch_bind((base_type*)this);
+ base_type::bind(s); //satisfy SystemC
+ }
+
+ //operator notation for hierarchical bind
+ void operator() (base_type& s)
+ {
+ bind(s);
+ }
+
+ //get access to sub port
+ tlm::tlm_bw_transport_if<TYPES>* operator[](int i){return m_sockets[i];}
+
+ //get number of bound initiators
+ // NOTE: this is only valid at end of elaboration!
+ unsigned int size(){return get_hierarch_bind()->get_binders().size();}
+
+protected:
+ //implementation of base class interface
+ base_type* get_hierarch_bind(){if (m_hierarch_bind) return m_hierarch_bind->get_hierarch_bind(); else return this;}
+ std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES>*>& get_multi_binds(){return m_multi_binds;}
+ void set_hierarch_bind(base_type* h){m_hierarch_bind=h;}
+ tlm::tlm_fw_transport_if<TYPES>* get_last_binder(tlm::tlm_bw_transport_if<TYPES>* other){
+ m_multi_binds[m_binders.size()-1]=other;
+ return m_binders[m_binders.size()-1];
+ }
+
+ //map that stores to which index a multi init socket is connected
+ // and the interface of the multi init socket
+ std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES>*> m_multi_binds;
+
+ void disable_cb_bind(){ m_eoe_disabled=true;}
+ std::vector<callback_binder_fw<TYPES>* >& get_binders(){return m_binders;}
+ //vector of connected sockets
+ std::vector<tlm::tlm_bw_transport_if<TYPES>*> m_sockets;
+ //vector of binders that convert untagged interface into tagged interface
+ std::vector<callback_binder_fw<TYPES>*> m_binders;
+
+ base_type* m_hierarch_bind; //pointer to hierarchical bound multi port
+ bool m_eoe_disabled; //bool that diables callback bindings at end of elaboration
+ bool m_export_callback_created; // bool to indicate that a callback has already been created for export binding
+
+ //callbacks as functors
+ // (allows to pass the callback to another socket that does not know the type of the module that owns
+ // the callbacks)
+ typename callback_binder_fw<TYPES>::nb_func_type m_nb_f;
+ typename callback_binder_fw<TYPES>::b_func_type m_b_f;
+ typename callback_binder_fw<TYPES>::debug_func_type m_dbg_f;
+ typename callback_binder_fw<TYPES>::dmi_func_type m_dmi_f;
+};
+
+}
+
+#endif
diff --git a/ext/systemc/src/tlm_utils/multi_socket_bases.h b/ext/systemc/src/tlm_utils/multi_socket_bases.h
new file mode 100644
index 000000000..457398495
--- /dev/null
+++ b/ext/systemc/src/tlm_utils/multi_socket_bases.h
@@ -0,0 +1,418 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#ifndef __MULTI_SOCKET_BASES_H__
+#define __MULTI_SOCKET_BASES_H__
+
+#include <systemc>
+#include <tlm>
+
+#include <map>
+#include <sstream>
+
+namespace tlm_utils {
+
+template <typename signature>
+struct fn_container{
+ signature function;
+};
+
+#define TLM_DEFINE_FUNCTOR(name) \
+template <typename MODULE, typename TRAITS> \
+inline TLM_RET_VAL static_##name( void* mod \
+ , void* fn \
+ , int index \
+ , TLM_FULL_ARG_LIST) \
+{ \
+ typedef fn_container<TLM_RET_VAL (MODULE::*)(int, TLM_FULL_ARG_LIST)> fn_container_type; \
+ MODULE* tmp_mod=static_cast<MODULE*>(mod); \
+ fn_container_type* tmp_cb =static_cast<fn_container_type*> (fn); \
+ return (tmp_mod->*(tmp_cb->function))(index, TLM_ARG_LIST_WITHOUT_TYPES); \
+}\
+\
+template <typename MODULE, typename TRAITS> \
+inline void delete_fn_container_of_##name(void* fn) \
+{ \
+ typedef fn_container<TLM_RET_VAL (MODULE::*)(int, TLM_FULL_ARG_LIST)> fn_container_type; \
+ fn_container_type* tmp_cb =static_cast<fn_container_type*> (fn); \
+ if (tmp_cb) delete tmp_cb;\
+} \
+\
+template <typename TRAITS> \
+class name##_functor{ \
+public: \
+ typedef typename TRAITS::tlm_payload_type payload_type; \
+ typedef typename TRAITS::tlm_phase_type phase_type; \
+ typedef TLM_RET_VAL (*call_fn)(void*,void*, int, TLM_FULL_ARG_LIST); \
+ typedef void (*del_fn)(void*); \
+\
+ name##_functor(): m_fn(0), m_del_fn(0), m_mod(0), m_mem_fn(0){} \
+ ~name##_functor(){if (m_del_fn) (*m_del_fn)(m_mem_fn);} \
+\
+ template <typename MODULE> \
+ void set_function(MODULE* mod, TLM_RET_VAL (MODULE::*cb)(int, TLM_FULL_ARG_LIST)){ \
+ typedef fn_container<TLM_RET_VAL (MODULE::*)(int, TLM_FULL_ARG_LIST)> fn_container_type; \
+ m_fn=&static_##name<MODULE,TRAITS>;\
+ m_del_fn=&delete_fn_container_of_##name<MODULE,TRAITS>;\
+ m_del_fn(m_mem_fn); \
+ fn_container_type* tmp= new fn_container_type(); \
+ tmp->function=cb; \
+ m_mod=static_cast<void*>(mod); \
+ m_mem_fn=static_cast<void*>(tmp); \
+ } \
+ \
+ TLM_RET_VAL operator()(int index, TLM_FULL_ARG_LIST){ \
+ return m_fn(m_mod,m_mem_fn, index, TLM_ARG_LIST_WITHOUT_TYPES); \
+ } \
+\
+ bool empty(){return (m_mod==0 || m_mem_fn==0 || m_fn==0);}\
+\
+protected: \
+ call_fn m_fn;\
+ del_fn m_del_fn; \
+ void* m_mod; \
+ void* m_mem_fn; \
+private: \
+ name##_functor& operator=(const name##_functor&); \
+}
+
+
+#define TLM_RET_VAL tlm::tlm_sync_enum
+#define TLM_FULL_ARG_LIST typename TRAITS::tlm_payload_type& txn, typename TRAITS::tlm_phase_type& ph, sc_core::sc_time& t
+#define TLM_ARG_LIST_WITHOUT_TYPES txn,ph,t
+TLM_DEFINE_FUNCTOR(nb_transport);
+#undef TLM_RET_VAL
+#undef TLM_FULL_ARG_LIST
+#undef TLM_ARG_LIST_WITHOUT_TYPES
+
+#define TLM_RET_VAL void
+#define TLM_FULL_ARG_LIST typename TRAITS::tlm_payload_type& txn, sc_core::sc_time& t
+#define TLM_ARG_LIST_WITHOUT_TYPES txn,t
+TLM_DEFINE_FUNCTOR(b_transport);
+#undef TLM_RET_VAL
+#undef TLM_FULL_ARG_LIST
+#undef TLM_ARG_LIST_WITHOUT_TYPES
+
+#define TLM_RET_VAL unsigned int
+#define TLM_FULL_ARG_LIST typename TRAITS::tlm_payload_type& txn
+#define TLM_ARG_LIST_WITHOUT_TYPES txn
+TLM_DEFINE_FUNCTOR(debug_transport);
+#undef TLM_RET_VAL
+#undef TLM_FULL_ARG_LIST
+#undef TLM_ARG_LIST_WITHOUT_TYPES
+
+#define TLM_RET_VAL bool
+#define TLM_FULL_ARG_LIST typename TRAITS::tlm_payload_type& txn, tlm::tlm_dmi& dmi
+#define TLM_ARG_LIST_WITHOUT_TYPES txn,dmi
+TLM_DEFINE_FUNCTOR(get_dmi_ptr);
+#undef TLM_RET_VAL
+#undef TLM_FULL_ARG_LIST
+#undef TLM_ARG_LIST_WITHOUT_TYPES
+
+#define TLM_RET_VAL void
+#define TLM_FULL_ARG_LIST sc_dt::uint64 l, sc_dt::uint64 u
+#define TLM_ARG_LIST_WITHOUT_TYPES l,u
+TLM_DEFINE_FUNCTOR(invalidate_dmi);
+#undef TLM_RET_VAL
+#undef TLM_FULL_ARG_LIST
+#undef TLM_ARG_LIST_WITHOUT_TYPES
+
+#undef TLM_DEFINE_FUNCTOR
+
+/*
+This class implements the fw interface.
+It allows to register a callback for each of the fw interface methods.
+The callbacks simply forward the fw interface call, but add the id (an int)
+of the callback binder to the signature of the call.
+*/
+template <typename TYPES>
+class callback_binder_fw: public tlm::tlm_fw_transport_if<TYPES>{
+ public:
+ //typedefs according to the used TYPES class
+ typedef typename TYPES::tlm_payload_type transaction_type;
+ typedef typename TYPES::tlm_phase_type phase_type;
+ typedef tlm::tlm_sync_enum sync_enum_type;
+
+ //typedefs for the callbacks
+ typedef nb_transport_functor<TYPES> nb_func_type;
+ typedef b_transport_functor<TYPES> b_func_type;
+ typedef debug_transport_functor<TYPES> debug_func_type;
+ typedef get_dmi_ptr_functor<TYPES> dmi_func_type;
+
+ //ctor: an ID is needed to create a callback binder
+ callback_binder_fw(int id): m_id(id), m_nb_f(0), m_b_f(0), m_dbg_f(0), m_dmi_f(0), m_caller_port(0) {
+ }
+
+ //the nb_transport method of the fw interface
+ sync_enum_type nb_transport_fw(transaction_type& txn,
+ phase_type& p,
+ sc_core::sc_time& t){
+ //check if a callback is registered
+ if ((m_nb_f == 0) || (m_nb_f && m_nb_f->empty())) {
+ //std::cerr<<"No function registered"<<std::endl;
+ SC_REPORT_ERROR("/OSCI_TLM-2/multi_socket","Call to nb_transport_fw without a registered callback for nb_transport_fw.");
+ }
+ else
+ return (*m_nb_f)(m_id, txn, p, t); //do the callback
+ return tlm::TLM_ACCEPTED; //unreachable
+ }
+
+ //the b_transport method of the fw interface
+ void b_transport(transaction_type& trans,sc_core::sc_time& t){
+ //check if a callback is registered
+ if ((m_b_f == 0) || (m_b_f && m_b_f->empty())) {
+ SC_REPORT_ERROR("/OSCI_TLM-2/multi_socket","Call to b_transport without a registered callback for b_transport.");
+ }
+ else
+ (*m_b_f)(m_id, trans,t); //do the callback
+ }
+
+ //the DMI method of the fw interface
+ bool get_direct_mem_ptr(transaction_type& trans, tlm::tlm_dmi& dmi_data){
+ //check if a callback is registered
+ if ((m_dmi_f == 0) && (m_dmi_f && m_dmi_f->empty())) {
+ dmi_data.allow_none();
+ dmi_data.set_start_address(0x0);
+ dmi_data.set_end_address((sc_dt::uint64)-1);
+ return false;
+ }
+ else
+ return (*m_dmi_f)(m_id, trans,dmi_data); //do the callback
+ }
+
+ //the debug method of the fw interface
+ unsigned int transport_dbg(transaction_type& trans){
+ //check if a callback is registered
+ if ((m_dbg_f == 0) || (m_dbg_f && m_dbg_f->empty())) {
+ return 0;
+ }
+ else
+ return (*m_dbg_f)(m_id, trans); //do the callback
+ }
+
+ //the SystemC standard callback register_port:
+ // - called when a port if bound to the interface
+ // - allowd to find out who is bound to that callback binder
+ void register_port(sc_core::sc_port_base& b, const char* name){
+ m_caller_port=&b;
+ }
+
+ //register callbacks for all fw interface methods at once
+ void set_callbacks(nb_func_type& cb1, b_func_type& cb2, dmi_func_type& cb3, debug_func_type& cb4){
+ m_nb_f=&cb1;
+ m_b_f=&cb2;
+ m_dmi_f=&cb3;
+ m_dbg_f=&cb4;
+ }
+
+ //getter method to get the port that is bound to that callback binder
+ // NOTE: this will only return a valid value at end of elaboration
+ // (but not before end of elaboration!)
+ sc_core::sc_port_base* get_other_side(){return m_caller_port;}
+
+ private:
+ //the ID of the callback binder
+ int m_id;
+
+ //the callbacks
+ nb_func_type* m_nb_f;
+ b_func_type* m_b_f;
+ debug_func_type* m_dbg_f;
+ dmi_func_type* m_dmi_f;
+
+ //the port bound to that callback binder
+ sc_core::sc_port_base* m_caller_port;
+};
+
+/*
+This class implements the bw interface.
+It allows to register a callback for each of the bw interface methods.
+The callbacks simply forward the bw interface call, but add the id (an int)
+of the callback binder to the signature of the call.
+*/
+template <typename TYPES>
+class callback_binder_bw: public tlm::tlm_bw_transport_if<TYPES>{
+ public:
+ //typedefs according to the used TYPES class
+ typedef typename TYPES::tlm_payload_type transaction_type;
+ typedef typename TYPES::tlm_phase_type phase_type;
+ typedef tlm::tlm_sync_enum sync_enum_type;
+
+ //typedefs for the callbacks
+ typedef nb_transport_functor<TYPES> nb_func_type;
+ typedef invalidate_dmi_functor<TYPES> dmi_func_type;
+
+ //ctor: an ID is needed to create a callback binder
+ callback_binder_bw(int id): m_id(id), m_nb_f(0), m_dmi_f(0) {
+ }
+
+ //the nb_transport method of the bw interface
+ sync_enum_type nb_transport_bw(transaction_type& txn,
+ phase_type& p,
+ sc_core::sc_time& t){
+ //check if a callback is registered
+ if ((m_nb_f == 0) || (m_nb_f && m_nb_f->empty())) {
+ SC_REPORT_ERROR("/OSCI_TLM-2/multi_socket","Call to nb_transport_bw without a registered callback for nb_transport_bw");
+ }
+ else
+ return (*m_nb_f)(m_id, txn, p, t); //do the callback
+ return tlm::TLM_ACCEPTED; //unreachable
+ }
+
+ //the DMI method of the bw interface
+ void invalidate_direct_mem_ptr(sc_dt::uint64 l, sc_dt::uint64 u){
+ //check if a callback is registered
+ if ((m_dmi_f == 0) || (m_dmi_f && m_dmi_f->empty())) {
+ return;
+ }
+ else
+ (*m_dmi_f)(m_id,l,u); //do the callback
+ }
+
+ //register callbacks for all bw interface methods at once
+ void set_callbacks(nb_func_type& cb1, dmi_func_type& cb2){
+ m_nb_f=&cb1;
+ m_dmi_f=&cb2;
+ }
+
+ private:
+ //the ID of the callback binder
+ int m_id;
+ //the callbacks
+ nb_func_type* m_nb_f;
+ dmi_func_type* m_dmi_f;
+};
+
+
+/*
+This class forms the base for multi initiator sockets.
+It enforces a multi initiator socket to implement all functions
+needed to do hierarchical bindings.
+*/
+template <unsigned int BUSWIDTH = 32,
+ typename TYPES = tlm::tlm_base_protocol_types,
+ unsigned int N=0
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+ ,sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND
+#endif
+ >
+class multi_init_base: public tlm::tlm_initiator_socket<BUSWIDTH,
+ TYPES,
+ N
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+ ,POL
+#endif
+ >{
+public:
+ //typedef for the base type: the standard tlm initiator socket
+ typedef tlm::tlm_initiator_socket<BUSWIDTH,
+ TYPES,
+ N
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+ ,POL
+#endif
+ > base_type;
+
+ //this method shall disable the code that does the callback binding
+ // that registers callbacks to binders
+ virtual void disable_cb_bind()=0;
+
+ //this method shall return the multi_init_base to which the
+ // multi_init_base is bound hierarchically
+ // If the base is not bound hierarchically it shall return a pointer to itself
+ virtual multi_init_base* get_hierarch_bind()=0;
+
+ //this method shall return a vector of the callback binders of multi initiator socket
+ virtual std::vector<callback_binder_bw<TYPES>* >& get_binders()=0;
+
+ //this method shall return a vector of all target interfaces bound to this multi init socket
+ virtual std::vector<tlm::tlm_fw_transport_if<TYPES>*>& get_sockets()=0;
+
+ //ctor and dtor
+ virtual ~multi_init_base(){}
+ multi_init_base():base_type(sc_core::sc_gen_unique_name("multi_init_base")){}
+ multi_init_base(const char* name):base_type(name){}
+};
+
+/*
+This class forms the base for multi target sockets.
+It enforces a multi target socket to implement all functions
+needed to do hierarchical bindings.
+*/
+template <unsigned int BUSWIDTH = 32,
+ typename TYPES = tlm::tlm_base_protocol_types,
+ unsigned int N=0
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+ ,sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND
+#endif
+ >
+class multi_target_base: public tlm::tlm_target_socket<BUSWIDTH,
+ TYPES,
+ N
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+ ,POL
+#endif
+ >{
+public:
+ //typedef for the base type: the standard tlm target socket
+ typedef tlm::tlm_target_socket<BUSWIDTH,
+ TYPES,
+ N
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+ ,POL
+#endif
+ > base_type;
+
+ //this method shall return the multi_init_base to which the
+ // multi_init_base is bound hierarchically
+ // If the base is not bound hierarchically it shall return a pointer to itself
+ virtual multi_target_base* get_hierarch_bind()=0;
+
+ //this method shall inform the multi target socket that it is bound
+ // hierarchically and to which other multi target socket it is bound hierarchically
+ virtual void set_hierarch_bind(multi_target_base*)=0;
+
+ //this method shall return a vector of the callback binders of multi initiator socket
+ virtual std::vector<callback_binder_fw<TYPES>* >& get_binders()=0;
+
+ //this method shall return a map of all multi initiator sockets that are bound to this multi target
+ // the key of the map is the index at which the multi initiator i bound, while the value
+ // is the interface of the multi initiator socket that is bound at that index
+ virtual std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES>*>& get_multi_binds()=0;
+
+ //ctor and dtor
+ virtual ~multi_target_base(){}
+ multi_target_base():base_type(sc_core::sc_gen_unique_name("multi_target_base")){}
+ multi_target_base(const char* name):base_type(name){}
+};
+
+/*
+All multi sockets must additionally derive from this class.
+It enforces a multi socket to implement a function
+needed to do multi init to multi target bindings.
+*/
+template <typename TYPES>
+class multi_to_multi_bind_base{
+public:
+ virtual ~multi_to_multi_bind_base(){}
+ virtual tlm::tlm_fw_transport_if<TYPES>* get_last_binder(tlm::tlm_bw_transport_if<TYPES>*)=0;
+};
+
+}
+#endif
diff --git a/ext/systemc/src/tlm_utils/passthrough_target_socket.h b/ext/systemc/src/tlm_utils/passthrough_target_socket.h
new file mode 100644
index 000000000..1a3b14df7
--- /dev/null
+++ b/ext/systemc/src/tlm_utils/passthrough_target_socket.h
@@ -0,0 +1,479 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#ifndef __PASSTHROUGH_TARGET_SOCKET_H__
+#define __PASSTHROUGH_TARGET_SOCKET_H__
+
+#include <tlm>
+#include <sstream>
+
+namespace tlm_utils {
+
+template <typename MODULE,
+ unsigned int BUSWIDTH = 32,
+ typename TYPES = tlm::tlm_base_protocol_types>
+class passthrough_target_socket :
+ public tlm::tlm_target_socket<BUSWIDTH, TYPES>
+{
+public:
+ typedef typename TYPES::tlm_payload_type transaction_type;
+ typedef typename TYPES::tlm_phase_type phase_type;
+ typedef tlm::tlm_sync_enum sync_enum_type;
+ typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type;
+ typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type;
+ typedef tlm::tlm_target_socket<BUSWIDTH, TYPES> base_type;
+
+public:
+ passthrough_target_socket() :
+ base_type(sc_core::sc_gen_unique_name("passthrough_target_socket")),
+ m_process(this->name())
+ {
+ bind(m_process);
+ }
+
+ explicit passthrough_target_socket(const char* n) :
+ base_type(n),
+ m_process(this->name())
+ {
+ bind(m_process);
+ }
+
+ using tlm::tlm_target_socket<BUSWIDTH, TYPES>::bind;
+
+ // REGISTER_XXX
+ void register_nb_transport_fw(MODULE* mod,
+ sync_enum_type (MODULE::*cb)(transaction_type&,
+ phase_type&,
+ sc_core::sc_time&))
+ {
+ m_process.set_nb_transport_ptr(mod, cb);
+ }
+
+ void register_b_transport(MODULE* mod,
+ void (MODULE::*cb)(transaction_type&,
+ sc_core::sc_time&))
+ {
+ m_process.set_b_transport_ptr(mod, cb);
+ }
+
+ void register_transport_dbg(MODULE* mod,
+ unsigned int (MODULE::*cb)(transaction_type&))
+ {
+ m_process.set_transport_dbg_ptr(mod, cb);
+ }
+
+ void register_get_direct_mem_ptr(MODULE* mod,
+ bool (MODULE::*cb)(transaction_type&,
+ tlm::tlm_dmi&))
+ {
+ m_process.set_get_direct_mem_ptr(mod, cb);
+ }
+
+private:
+ class process : public tlm::tlm_fw_transport_if<TYPES>
+ {
+ public:
+ typedef sync_enum_type (MODULE::*NBTransportPtr)(transaction_type&,
+ phase_type&,
+ sc_core::sc_time&);
+ typedef void (MODULE::*BTransportPtr)(transaction_type&,
+ sc_core::sc_time&);
+ typedef unsigned int (MODULE::*TransportDbgPtr)(transaction_type&);
+ typedef bool (MODULE::*GetDirectMem_ptr)(transaction_type&,
+ tlm::tlm_dmi&);
+
+ process(const std::string& name) :
+ m_name(name),
+ m_mod(0),
+ m_nb_transport_ptr(0),
+ m_b_transport_ptr(0),
+ m_transport_dbg_ptr(0),
+ m_get_direct_mem_ptr(0)
+ {
+ }
+
+ void set_nb_transport_ptr(MODULE* mod, NBTransportPtr p)
+ {
+ if (m_nb_transport_ptr) {
+ std::stringstream s;
+ s << m_name << ": non-blocking callback allready registered";
+ SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
+
+ } else {
+ assert(!m_mod || m_mod == mod);
+ m_mod = mod;
+ m_nb_transport_ptr = p;
+ }
+ }
+
+ void set_b_transport_ptr(MODULE* mod, BTransportPtr p)
+ {
+ if (m_b_transport_ptr) {
+ std::stringstream s;
+ s << m_name << ": blocking callback allready registered";
+ SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
+ } else {
+ assert(!m_mod || m_mod == mod);
+ m_mod = mod;
+ m_b_transport_ptr = p;
+ }
+ }
+
+ void set_transport_dbg_ptr(MODULE* mod, TransportDbgPtr p)
+ {
+ if (m_transport_dbg_ptr) {
+ std::stringstream s;
+ s << m_name << ": debug callback allready registered";
+ SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
+ } else {
+ assert(!m_mod || m_mod == mod);
+ m_mod = mod;
+ m_transport_dbg_ptr = p;
+ }
+ }
+
+ void set_get_direct_mem_ptr(MODULE* mod, GetDirectMem_ptr p)
+ {
+ if (m_get_direct_mem_ptr) {
+ std::stringstream s;
+ s << m_name << ": get DMI pointer callback allready registered";
+ SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
+ } else {
+ assert(!m_mod || m_mod == mod);
+ m_mod = mod;
+ m_get_direct_mem_ptr = p;
+ }
+ }
+
+ sync_enum_type nb_transport_fw(transaction_type& trans,
+ phase_type& phase,
+ sc_core::sc_time& t)
+ {
+ if (m_nb_transport_ptr) {
+ // forward call
+ assert(m_mod);
+ return (m_mod->*m_nb_transport_ptr)(trans, phase, t);
+
+ } else {
+ std::stringstream s;
+ s << m_name << ": no non-blocking callback registered";
+ SC_REPORT_ERROR("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
+ }
+ return tlm::TLM_ACCEPTED; ///< unreachable code
+ }
+
+ void b_transport(transaction_type& trans, sc_core::sc_time& t)
+ {
+ if (m_b_transport_ptr) {
+ // forward call
+ assert(m_mod);
+ return (m_mod->*m_b_transport_ptr)(trans, t);
+
+ } else {
+ std::stringstream s;
+ s << m_name << ": no blocking callback registered";
+ SC_REPORT_ERROR("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
+ }
+ }
+
+ unsigned int transport_dbg(transaction_type& trans)
+ {
+ if (m_transport_dbg_ptr) {
+ // forward call
+ assert(m_mod);
+ return (m_mod->*m_transport_dbg_ptr)(trans);
+
+ } else {
+ // No debug support
+ return 0;
+ }
+ }
+
+ bool get_direct_mem_ptr(transaction_type& trans,
+ tlm::tlm_dmi& dmi_data)
+ {
+ if (m_get_direct_mem_ptr) {
+ // forward call
+ assert(m_mod);
+ return (m_mod->*m_get_direct_mem_ptr)(trans, dmi_data);
+
+ } else {
+ // No DMI support
+ dmi_data.allow_read_write();
+ dmi_data.set_start_address(0x0);
+ dmi_data.set_end_address((sc_dt::uint64)-1);
+ return false;
+ }
+ }
+
+ private:
+ const std::string m_name;
+ MODULE* m_mod;
+ NBTransportPtr m_nb_transport_ptr;
+ BTransportPtr m_b_transport_ptr;
+ TransportDbgPtr m_transport_dbg_ptr;
+ GetDirectMem_ptr m_get_direct_mem_ptr;
+ };
+
+private:
+ process m_process;
+};
+
+//ID Tagged version
+template <typename MODULE,
+ unsigned int BUSWIDTH = 32,
+ typename TYPES = tlm::tlm_base_protocol_types>
+class passthrough_target_socket_tagged :
+ public tlm::tlm_target_socket<BUSWIDTH, TYPES>
+{
+public:
+ typedef typename TYPES::tlm_payload_type transaction_type;
+ typedef typename TYPES::tlm_phase_type phase_type;
+ typedef tlm::tlm_sync_enum sync_enum_type;
+ typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type;
+ typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type;
+ typedef tlm::tlm_target_socket<BUSWIDTH, TYPES> base_type;
+
+public:
+ passthrough_target_socket_tagged() :
+ base_type(sc_core::sc_gen_unique_name("passthrough_target_socket_tagged")),
+ m_process(this->name())
+ {
+ bind(m_process);
+ }
+
+ explicit passthrough_target_socket_tagged(const char* n) :
+ base_type(n),
+ m_process(this->name())
+ {
+ bind(m_process);
+ }
+
+ using tlm::tlm_target_socket<BUSWIDTH, TYPES>::bind;
+
+ // REGISTER_XXX
+ void register_nb_transport_fw(MODULE* mod,
+ sync_enum_type (MODULE::*cb)(int id,
+ transaction_type&,
+ phase_type&,
+ sc_core::sc_time&),
+ int id)
+ {
+ m_process.set_nb_transport_ptr(mod, cb);
+ m_process.set_nb_transport_user_id(id);
+ }
+
+ void register_b_transport(MODULE* mod,
+ void (MODULE::*cb)(int id,
+ transaction_type&,
+ sc_core::sc_time&),
+ int id)
+ {
+ m_process.set_b_transport_ptr(mod, cb);
+ m_process.set_b_transport_user_id(id);
+ }
+
+ void register_transport_dbg(MODULE* mod,
+ unsigned int (MODULE::*cb)(int id,
+ transaction_type&),
+ int id)
+ {
+ m_process.set_transport_dbg_ptr(mod, cb);
+ m_process.set_transport_dbg_user_id(id);
+ }
+
+ void register_get_direct_mem_ptr(MODULE* mod,
+ bool (MODULE::*cb)(int id,
+ transaction_type&,
+ tlm::tlm_dmi&),
+ int id)
+ {
+ m_process.set_get_direct_mem_ptr(mod, cb);
+ m_process.set_get_dmi_user_id(id);
+ }
+
+private:
+ class process : public tlm::tlm_fw_transport_if<TYPES>
+ {
+ public:
+ typedef sync_enum_type (MODULE::*NBTransportPtr)(int id,
+ transaction_type&,
+ phase_type&,
+ sc_core::sc_time&);
+ typedef void (MODULE::*BTransportPtr)(int id,
+ transaction_type&,
+ sc_core::sc_time&);
+ typedef unsigned int (MODULE::*TransportDbgPtr)(int id,
+ transaction_type&);
+ typedef bool (MODULE::*GetDirectMem_ptr)(int id,
+ transaction_type&,
+ tlm::tlm_dmi&);
+
+ process(const std::string& name) :
+ m_name(name),
+ m_mod(0),
+ m_nb_transport_ptr(0),
+ m_b_transport_ptr(0),
+ m_transport_dbg_ptr(0),
+ m_get_direct_mem_ptr(0),
+ m_nb_transport_user_id(0),
+ m_b_transport_user_id(0),
+ m_transport_dbg_user_id(0),
+ m_get_dmi_user_id(0)
+ {
+ }
+
+ void set_nb_transport_user_id(int id) { m_nb_transport_user_id = id; }
+ void set_b_transport_user_id(int id) { m_b_transport_user_id = id; }
+ void set_transport_dbg_user_id(int id) { m_transport_dbg_user_id = id; }
+ void set_get_dmi_user_id(int id) { m_get_dmi_user_id = id; }
+
+ void set_nb_transport_ptr(MODULE* mod, NBTransportPtr p)
+ {
+ if (m_nb_transport_ptr) {
+ std::stringstream s;
+ s << m_name << ": non-blocking callback allready registered";
+ SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
+ } else {
+ assert(!m_mod || m_mod == mod);
+ m_mod = mod;
+ m_nb_transport_ptr = p;
+ }
+ }
+
+ void set_b_transport_ptr(MODULE* mod, BTransportPtr p)
+ {
+ if (m_b_transport_ptr) {
+ std::stringstream s;
+ s << m_name << ": blocking callback allready registered";
+ SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
+ } else {
+ assert(!m_mod || m_mod == mod);
+ m_mod = mod;
+ m_b_transport_ptr = p;
+ }
+ }
+
+ void set_transport_dbg_ptr(MODULE* mod, TransportDbgPtr p)
+ {
+ if (m_transport_dbg_ptr) {
+ std::stringstream s;
+ s << m_name << ": debug callback allready registered";
+ SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
+ } else {
+ assert(!m_mod || m_mod == mod);
+ m_mod = mod;
+ m_transport_dbg_ptr = p;
+ }
+ }
+
+ void set_get_direct_mem_ptr(MODULE* mod, GetDirectMem_ptr p)
+ {
+ if (m_get_direct_mem_ptr) {
+ std::stringstream s;
+ s << m_name << ": get DMI pointer callback allready registered";
+ SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
+ } else {
+ assert(!m_mod || m_mod == mod);
+ m_mod = mod;
+ m_get_direct_mem_ptr = p;
+ }
+ }
+
+ sync_enum_type nb_transport_fw(transaction_type& trans,
+ phase_type& phase,
+ sc_core::sc_time& t)
+ {
+ if (m_nb_transport_ptr) {
+ // forward call
+ assert(m_mod);
+ return (m_mod->*m_nb_transport_ptr)(m_nb_transport_user_id, trans, phase, t);
+
+ } else {
+ std::stringstream s;
+ s << m_name << ": no non-blocking callback registered";
+ SC_REPORT_ERROR("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
+ }
+ return tlm::TLM_ACCEPTED; ///< unreachable code
+ }
+
+ void b_transport(transaction_type& trans, sc_core::sc_time& t)
+ {
+ if (m_b_transport_ptr) {
+ // forward call
+ assert(m_mod);
+ return (m_mod->*m_b_transport_ptr)(m_b_transport_user_id, trans, t);
+
+ } else {
+ std::stringstream s;
+ s << m_name << ": no blocking callback registered";
+ SC_REPORT_ERROR("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
+ }
+ }
+
+ unsigned int transport_dbg(transaction_type& trans)
+ {
+ if (m_transport_dbg_ptr) {
+ // forward call
+ assert(m_mod);
+ return (m_mod->*m_transport_dbg_ptr)(m_transport_dbg_user_id, trans);
+
+ } else {
+ // No debug support
+ return 0;
+ }
+ }
+
+ bool get_direct_mem_ptr(transaction_type& trans,
+ tlm::tlm_dmi& dmi_data)
+ {
+ if (m_get_direct_mem_ptr) {
+ // forward call
+ assert(m_mod);
+ return (m_mod->*m_get_direct_mem_ptr)(m_get_dmi_user_id, trans, dmi_data);
+
+ } else {
+ // No DMI support
+ dmi_data.allow_read_write();
+ dmi_data.set_start_address(0x0);
+ dmi_data.set_end_address((sc_dt::uint64)-1);
+ return false;
+ }
+ }
+
+ private:
+ const std::string m_name;
+ MODULE* m_mod;
+ NBTransportPtr m_nb_transport_ptr;
+ BTransportPtr m_b_transport_ptr;
+ TransportDbgPtr m_transport_dbg_ptr;
+ GetDirectMem_ptr m_get_direct_mem_ptr;
+ int m_nb_transport_user_id;
+ int m_b_transport_user_id;
+ int m_transport_dbg_user_id;
+ int m_get_dmi_user_id;
+ };
+
+private:
+ process m_process;
+};
+
+}
+
+#endif
diff --git a/ext/systemc/src/tlm_utils/peq_with_cb_and_phase.h b/ext/systemc/src/tlm_utils/peq_with_cb_and_phase.h
new file mode 100644
index 000000000..60f96e6bd
--- /dev/null
+++ b/ext/systemc/src/tlm_utils/peq_with_cb_and_phase.h
@@ -0,0 +1,301 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+// 12-Jan-2009 John Aynsley Bug fix. Phase argument to notify should be const
+// 20-Mar-2009 John Aynsley Add cancel_all() method
+
+
+#ifndef __PEQ_WITH_CB_AND_PHASE_H__
+#define __PEQ_WITH_CB_AND_PHASE_H__
+
+#ifndef SC_INCLUDE_DYNAMIC_PROCESSES // needed for sc_spawn
+# define SC_INCLUDE_DYNAMIC_PROCESSES
+#endif
+
+#include <vector>
+#include <systemc>
+#include <tlm>
+
+namespace tlm_utils {
+
+template <typename PAYLOAD>
+class time_ordered_list
+{
+public:
+ struct element
+ {
+ struct element *next;
+ PAYLOAD p;
+ sc_core::sc_time t;
+ sc_dt::uint64 d;
+ element(PAYLOAD& p, sc_core::sc_time t, sc_dt::uint64 d): p(p),t(t),d(d) {}
+ element(){}
+ };
+
+ element *nill;
+ element *empties;
+ element *list;
+ unsigned int size;
+
+ time_ordered_list()
+ : nill(new element()),
+ empties(NULL),
+ list(nill),
+ size(0)
+ {
+ }
+
+ ~time_ordered_list() {
+ reset();
+ while(empties){
+ struct element *e=empties->next;
+ delete empties;
+ empties=e;
+ }
+ delete nill;
+ }
+
+ void reset() {
+ while(size) {
+ delete_top();
+ }
+ }
+
+ void insert(const PAYLOAD& p, sc_core::sc_time t) {
+ if (!empties) {
+ empties=new struct element();
+ empties->next=NULL;
+ }
+
+ struct element *e=empties;
+ empties=empties->next;
+ e->p=p;
+ e->t=t;
+ e->d=sc_core::sc_delta_count();
+
+ struct element * ancestor=nill;
+ struct element * iterator=list;
+ while (iterator!=nill && iterator->t<=t){
+ ancestor=iterator;
+ iterator=iterator->next;
+ }
+ if (ancestor==nill){
+ e->next=list;
+ list=e;
+ }
+ else {
+ e->next=iterator;
+ ancestor->next=e;
+ }
+ size++;
+ }
+
+ void delete_top(){
+ if (list != nill) {
+ struct element *e=list;
+ list=list->next;
+ e->next=empties;
+ empties=e;
+ size--;
+ }
+ }
+
+ unsigned int get_size()
+ {
+ return size;
+ }
+
+ PAYLOAD &top()
+ {
+ return list->p;
+ }
+ sc_core::sc_time top_time()
+ {
+ return list->t;
+ }
+
+ sc_dt::uint64& top_delta()
+ {
+ return list->d;
+ }
+
+ sc_core::sc_time next_time()
+ {
+ return list->next->t;
+ }
+};
+
+//---------------------------------------------------------------------------
+/**
+ * An event queue that can contain any number of pending
+ * notifications. Each notification have an associate payload.
+ */
+//---------------------------------------------------------------------------
+template<typename OWNER,typename TYPES=tlm::tlm_base_protocol_types>
+class peq_with_cb_and_phase:
+ public sc_core::sc_object
+{
+
+ typedef typename TYPES::tlm_payload_type tlm_payload_type;
+ typedef typename TYPES::tlm_phase_type tlm_phase_type;
+ typedef std::pair<tlm_payload_type*, tlm_phase_type> PAYLOAD;
+ typedef void (OWNER::*cb)(tlm_payload_type&, const tlm_phase_type&);
+
+ class delta_list{
+ public:
+ delta_list(){
+ reset();
+ entries.resize(100);
+ }
+
+ inline void insert(const PAYLOAD& p){
+ if (size==entries.size()){
+ entries.resize(entries.size()*2);
+ }
+ entries[size++]=p;
+ }
+
+ inline PAYLOAD& get(){
+ return entries[out++];
+ }
+
+ inline bool next(){
+ return out<size;
+ }
+
+ inline void reset(){
+ size=0;
+ out=0;
+ }
+ public:
+ unsigned int size;
+ private:
+ std::vector<PAYLOAD> entries;
+ unsigned int out;
+ };
+
+public:
+
+ peq_with_cb_and_phase(OWNER* _owner, cb _cb)
+ :sc_core::sc_object( sc_core::sc_gen_unique_name( "peq_with_cb_and_phase" ) )
+ ,m_owner(_owner)
+ ,m_cb(_cb)
+ {
+ sc_core::sc_spawn_options opts;
+ opts.spawn_method();
+ opts.set_sensitivity(&m_e);
+ opts.dont_initialize();
+ sc_core::sc_spawn(sc_bind(&peq_with_cb_and_phase::fec, this),
+ sc_core::sc_gen_unique_name("fec"), &opts);
+ }
+
+ peq_with_cb_and_phase(const char* _name, OWNER* _owner,cb _cb)
+ : sc_core::sc_object( _name )
+ ,m_owner(_owner)
+ ,m_cb(_cb)
+ {
+ sc_core::sc_spawn_options opts;
+ opts.spawn_method();
+ opts.set_sensitivity(&m_e);
+ opts.dont_initialize();
+ sc_core::sc_spawn(sc_bind(&peq_with_cb_and_phase::fec, this),
+ sc_core::sc_gen_unique_name("fec"), &opts);
+ }
+
+ ~peq_with_cb_and_phase(){}
+
+ void notify (tlm_payload_type& t, const tlm_phase_type& p, const sc_core::sc_time& when){
+ //t.aquire();
+ if (when==sc_core::SC_ZERO_TIME) {
+ if (sc_core::sc_delta_count() & (sc_dt::uint64)0x1) //uneven delta cycle so delta delay is for even cylce
+ m_even_delta.insert(PAYLOAD(&t,p));
+ else
+ m_uneven_delta.insert(PAYLOAD(&t,p)); //even delta cycle so delta delay is for uneven delta
+ m_e.notify(sc_core::SC_ZERO_TIME);
+ }
+ else {
+ m_ppq.insert(PAYLOAD(&t,p), when + sc_core::sc_time_stamp() );
+ m_e.notify(when); // note, this will only over-right the "newest" event.
+ }
+ }
+
+ void notify (tlm_payload_type& t, const tlm_phase_type& p){
+ m_immediate_yield.insert(PAYLOAD(&t,p));
+ m_e.notify(); // immediate notification
+ }
+
+ // Cancel all events from the event queue
+ void cancel_all() {
+ m_ppq.reset();
+ m_uneven_delta.reset();
+ m_even_delta.reset();
+ m_immediate_yield.reset();
+ m_e.cancel();
+ }
+
+private:
+
+ void fec(){
+ //immediate yield notifications
+ while(m_immediate_yield.next()) {PAYLOAD& tmp=m_immediate_yield.get(); (m_owner->*m_cb)(*tmp.first, tmp.second);} //tmp.first->release();}
+ m_immediate_yield.reset();
+
+ //delta notifications
+ if (sc_core::sc_delta_count() & (sc_dt::uint64) 0x1) {//uneven delta so put out all payloads for uneven delta
+ while (m_uneven_delta.next()) {PAYLOAD& tmp=m_uneven_delta.get(); (m_owner->*m_cb)(*tmp.first, tmp.second);} //tmp.first->release();}
+ m_uneven_delta.reset();
+ if (m_even_delta.size) m_e.notify(sc_core::SC_ZERO_TIME);
+ }
+ else {
+ while (m_even_delta.next()) {PAYLOAD& tmp=m_even_delta.get(); (m_owner->*m_cb)(*tmp.first, tmp.second);} //tmp.first->release();}
+ m_even_delta.reset();
+ if (m_uneven_delta.size) m_e.notify(sc_core::SC_ZERO_TIME);
+ }
+ if (!m_ppq.get_size()) return; //there were only delta notification
+
+ //timed notifications
+ const sc_core::sc_time now=sc_core::sc_time_stamp();
+ sc_core::sc_time top=m_ppq.top_time();
+
+ while(m_ppq.get_size() && top==now) { // push all active ones into target
+ PAYLOAD& tmp=m_ppq.top();
+ (m_owner->*m_cb)(*tmp.first, tmp.second); //tmp.first->release();}
+ m_ppq.delete_top();
+ top=m_ppq.top_time();
+ }
+ if ( m_ppq.get_size()) {
+ m_e.notify( top - now) ;
+ }
+
+ }
+
+ OWNER* m_owner;
+ cb m_cb;
+
+ time_ordered_list<PAYLOAD> m_ppq;
+ delta_list m_uneven_delta;
+ delta_list m_even_delta;
+ delta_list m_immediate_yield;
+
+ sc_core::sc_event m_e; // default event
+};
+
+}
+
+#endif // __PEQ_WITH_CB_AND_PHASE_H__
diff --git a/ext/systemc/src/tlm_utils/peq_with_get.h b/ext/systemc/src/tlm_utils/peq_with_get.h
new file mode 100644
index 000000000..5c85f25d5
--- /dev/null
+++ b/ext/systemc/src/tlm_utils/peq_with_get.h
@@ -0,0 +1,94 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+// 12-Jan-2009 John Aynsley Bug fix. sc_time argument to notify should be const
+// 20-Mar-2009 John Aynsley Add cancel_all() method
+
+
+#ifndef __PEQ_WITH_GET_H__
+#define __PEQ_WITH_GET_H__
+
+#include <systemc>
+//#include <tlm>
+#include <map>
+
+namespace tlm_utils {
+
+template <class PAYLOAD>
+class peq_with_get : public sc_core::sc_object
+{
+public:
+ typedef PAYLOAD transaction_type;
+ typedef std::pair<const sc_core::sc_time, transaction_type*> pair_type;
+
+public:
+ peq_with_get(const char* name) : sc_core::sc_object(name)
+ {
+ }
+
+ void notify(transaction_type& trans, const sc_core::sc_time& t)
+ {
+ m_scheduled_events.insert(pair_type(t + sc_core::sc_time_stamp(), &trans));
+ m_event.notify(t);
+ }
+
+ void notify(transaction_type& trans)
+ {
+ m_scheduled_events.insert(pair_type(sc_core::sc_time_stamp(), &trans));
+ m_event.notify(); // immediate notification
+ }
+
+ // needs to be called until it returns 0
+ transaction_type* get_next_transaction()
+ {
+ if (m_scheduled_events.empty()) {
+ return 0;
+ }
+
+ sc_core::sc_time now = sc_core::sc_time_stamp();
+ if (m_scheduled_events.begin()->first <= now) {
+ transaction_type* trans = m_scheduled_events.begin()->second;
+ m_scheduled_events.erase(m_scheduled_events.begin());
+ return trans;
+ }
+
+ m_event.notify(m_scheduled_events.begin()->first - now);
+
+ return 0;
+ }
+
+ sc_core::sc_event& get_event()
+ {
+ return m_event;
+ }
+
+ // Cancel all events from the event queue
+ void cancel_all() {
+ m_scheduled_events.clear();
+ m_event.cancel();
+ }
+
+private:
+ std::multimap<const sc_core::sc_time, transaction_type*> m_scheduled_events;
+ sc_core::sc_event m_event;
+};
+
+}
+
+#endif
diff --git a/ext/systemc/src/tlm_utils/simple_initiator_socket.h b/ext/systemc/src/tlm_utils/simple_initiator_socket.h
new file mode 100644
index 000000000..4609fd885
--- /dev/null
+++ b/ext/systemc/src/tlm_utils/simple_initiator_socket.h
@@ -0,0 +1,292 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+#ifndef __SIMPLE_INITIATOR_SOCKET_H__
+#define __SIMPLE_INITIATOR_SOCKET_H__
+
+#include <tlm>
+#include <sstream>
+
+namespace tlm_utils {
+
+template <typename MODULE,
+ unsigned int BUSWIDTH = 32,
+ typename TYPES = tlm::tlm_base_protocol_types>
+class simple_initiator_socket :
+ public tlm::tlm_initiator_socket<BUSWIDTH, TYPES>
+{
+public:
+ typedef typename TYPES::tlm_payload_type transaction_type;
+ typedef typename TYPES::tlm_phase_type phase_type;
+ typedef tlm::tlm_sync_enum sync_enum_type;
+ typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type;
+ typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type;
+ typedef tlm::tlm_initiator_socket<BUSWIDTH, TYPES> base_type;
+
+public:
+ simple_initiator_socket() :
+ base_type(sc_core::sc_gen_unique_name("simple_initiator_socket")),
+ m_process(this->name())
+ {
+ this->m_export.bind(m_process);
+ }
+
+ explicit simple_initiator_socket(const char* n) :
+ base_type(n),
+ m_process(this->name())
+ {
+ this->m_export.bind(m_process);
+ }
+
+ void register_nb_transport_bw(MODULE* mod,
+ sync_enum_type (MODULE::*cb)(transaction_type&,
+ phase_type&,
+ sc_core::sc_time&))
+ {
+ m_process.set_transport_ptr(mod, cb);
+ }
+
+ void register_invalidate_direct_mem_ptr(MODULE* mod,
+ void (MODULE::*cb)(sc_dt::uint64, sc_dt::uint64))
+ {
+ m_process.set_invalidate_direct_mem_ptr(mod, cb);
+ }
+
+private:
+ class process : public tlm::tlm_bw_transport_if<TYPES>
+ {
+ public:
+ typedef sync_enum_type (MODULE::*TransportPtr)(transaction_type&,
+ phase_type&,
+ sc_core::sc_time&);
+ typedef void (MODULE::*InvalidateDirectMemPtr)(sc_dt::uint64,
+ sc_dt::uint64);
+
+ process(const std::string& name) :
+ m_name(name),
+ m_mod(0),
+ m_transport_ptr(0),
+ m_invalidate_direct_mem_ptr(0)
+ {
+ }
+
+ void set_transport_ptr(MODULE* mod, TransportPtr p)
+ {
+ if (m_transport_ptr) {
+ std::stringstream s;
+ s << m_name << ": non-blocking callback allready registered";
+ SC_REPORT_WARNING("/OSCI_TLM-2/simple_socket",s.str().c_str());
+ } else {
+ assert(!m_mod || m_mod == mod);
+ m_mod = mod;
+ m_transport_ptr = p;
+ }
+ }
+
+ void set_invalidate_direct_mem_ptr(MODULE* mod, InvalidateDirectMemPtr p)
+ {
+ if (m_invalidate_direct_mem_ptr) {
+ std::stringstream s;
+ s << m_name << ": invalidate DMI callback allready registered";
+ SC_REPORT_WARNING("/OSCI_TLM-2/simple_socket",s.str().c_str());
+ } else {
+ assert(!m_mod || m_mod == mod);
+ m_mod = mod;
+ m_invalidate_direct_mem_ptr = p;
+ }
+ }
+
+ sync_enum_type nb_transport_bw(transaction_type& trans, phase_type& phase, sc_core::sc_time& t)
+ {
+ if (m_transport_ptr) {
+ // forward call
+ assert(m_mod);
+ return (m_mod->*m_transport_ptr)(trans, phase, t);
+
+ } else {
+ std::stringstream s;
+ s << m_name << ": no transport callback registered";
+ SC_REPORT_ERROR("/OSCI_TLM-2/simple_socket",s.str().c_str());
+ }
+ return tlm::TLM_ACCEPTED; ///< unreachable code
+ }
+
+ void invalidate_direct_mem_ptr(sc_dt::uint64 start_range,
+ sc_dt::uint64 end_range)
+ {
+ if (m_invalidate_direct_mem_ptr) {
+ // forward call
+ assert(m_mod);
+ (m_mod->*m_invalidate_direct_mem_ptr)(start_range, end_range);
+ }
+ }
+
+ private:
+ const std::string m_name;
+ MODULE* m_mod;
+ TransportPtr m_transport_ptr;
+ InvalidateDirectMemPtr m_invalidate_direct_mem_ptr;
+ };
+
+private:
+ process m_process;
+};
+
+// Tagged version
+
+template <typename MODULE,
+ unsigned int BUSWIDTH = 32,
+ typename TYPES = tlm::tlm_base_protocol_types>
+class simple_initiator_socket_tagged :
+ public tlm::tlm_initiator_socket<BUSWIDTH, TYPES>
+{
+public:
+ typedef typename TYPES::tlm_payload_type transaction_type;
+ typedef typename TYPES::tlm_phase_type phase_type;
+ typedef tlm::tlm_sync_enum sync_enum_type;
+ typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type;
+ typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type;
+ typedef tlm::tlm_initiator_socket<BUSWIDTH, TYPES> base_type;
+
+public:
+ simple_initiator_socket_tagged() :
+ base_type(sc_core::sc_gen_unique_name("simple_initiator_socket_tagged")),
+ m_process(this->name())
+ {
+ this->m_export.bind(m_process);
+ }
+
+ explicit simple_initiator_socket_tagged(const char* n) :
+ base_type(n),
+ m_process(this->name())
+ {
+ this->m_export.bind(m_process);
+ }
+
+ void register_nb_transport_bw(MODULE* mod,
+ sync_enum_type (MODULE::*cb)(int,
+ transaction_type&,
+ phase_type&,
+ sc_core::sc_time&),
+ int id)
+ {
+ m_process.set_transport_ptr(mod, cb);
+ m_process.set_transport_user_id(id);
+ }
+
+ void register_invalidate_direct_mem_ptr(MODULE* mod,
+ void (MODULE::*cb)(int, sc_dt::uint64, sc_dt::uint64),
+ int id)
+ {
+ m_process.set_invalidate_direct_mem_ptr(mod, cb);
+ m_process.set_invalidate_dmi_user_id(id);
+ }
+
+private:
+ class process : public tlm::tlm_bw_transport_if<TYPES>
+ {
+ public:
+ typedef sync_enum_type (MODULE::*TransportPtr)(int,
+ transaction_type&,
+ phase_type&,
+ sc_core::sc_time&);
+ typedef void (MODULE::*InvalidateDirectMemPtr)(int,
+ sc_dt::uint64,
+ sc_dt::uint64);
+
+ process(const std::string& name) :
+ m_name(name),
+ m_mod(0),
+ m_transport_ptr(0),
+ m_invalidate_direct_mem_ptr(0),
+ m_transport_user_id(0),
+ m_invalidate_direct_mem_user_id(0)
+ {
+ }
+
+ void set_transport_user_id(int id) { m_transport_user_id = id; }
+ void set_invalidate_dmi_user_id(int id) { m_invalidate_direct_mem_user_id = id; }
+
+ void set_transport_ptr(MODULE* mod, TransportPtr p)
+ {
+ if (m_transport_ptr) {
+ std::stringstream s;
+ s << m_name << ": non-blocking callback allready registered";
+ SC_REPORT_WARNING("/OSCI_TLM-2/simple_socket",s.str().c_str());
+ } else {
+ assert(!m_mod || m_mod == mod);
+ m_mod = mod;
+ m_transport_ptr = p;
+ }
+ }
+
+ void set_invalidate_direct_mem_ptr(MODULE* mod, InvalidateDirectMemPtr p)
+ {
+ if (m_invalidate_direct_mem_ptr) {
+ std::stringstream s;
+ s << m_name << ": invalidate DMI callback allready registered";
+ SC_REPORT_WARNING("/OSCI_TLM-2/simple_socket",s.str().c_str());
+ } else {
+ assert(!m_mod || m_mod == mod);
+ m_mod = mod;
+ m_invalidate_direct_mem_ptr = p;
+ }
+ }
+
+ sync_enum_type nb_transport_bw(transaction_type& trans, phase_type& phase, sc_core::sc_time& t)
+ {
+ if (m_transport_ptr) {
+ // forward call
+ assert(m_mod);
+ return (m_mod->*m_transport_ptr)(m_transport_user_id, trans, phase, t);
+
+ } else {
+ std::stringstream s;
+ s << m_name << ": no transport callback registered";
+ SC_REPORT_ERROR("/OSCI_TLM-2/simple_socket",s.str().c_str());
+ }
+ return tlm::TLM_ACCEPTED; ///< unreachable code
+ }
+
+ void invalidate_direct_mem_ptr(sc_dt::uint64 start_range,
+ sc_dt::uint64 end_range)
+ {
+ if (m_invalidate_direct_mem_ptr) {
+ // forward call
+ assert(m_mod);
+ (m_mod->*m_invalidate_direct_mem_ptr)(m_invalidate_direct_mem_user_id, start_range, end_range);
+ }
+ }
+
+ private:
+ const std::string m_name;
+ MODULE* m_mod;
+ TransportPtr m_transport_ptr;
+ InvalidateDirectMemPtr m_invalidate_direct_mem_ptr;
+ int m_transport_user_id;
+ int m_invalidate_direct_mem_user_id;
+ };
+
+private:
+ process m_process;
+};
+
+}
+
+#endif
diff --git a/ext/systemc/src/tlm_utils/simple_target_socket.h b/ext/systemc/src/tlm_utils/simple_target_socket.h
new file mode 100644
index 000000000..34ed1a7f4
--- /dev/null
+++ b/ext/systemc/src/tlm_utils/simple_target_socket.h
@@ -0,0 +1,1114 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+// *****************************************************************************
+// Modified by John Aynsley, Doulos, Feb 2009,
+// Fix a bug in simple_target_socket and simple_target_socket_tagged
+// with the addition of one new line of code in each: wait(*e);
+// *****************************************************************************
+
+// *****************************************************************************
+// Modified by John Aynsley on behalf of Robert Guenzel, May 2011,
+// Fix a bug in simple_target_socket and simple_target_socket_tagged
+// with the addition of one new line of code in each: wait(t);
+// *****************************************************************************
+
+
+#ifndef __SIMPLE_TARGET_SOCKET_H__
+#define __SIMPLE_TARGET_SOCKET_H__
+
+#ifndef SC_INCLUDE_DYNAMIC_PROCESSES // needed for sc_spawn
+# define SC_INCLUDE_DYNAMIC_PROCESSES
+#endif
+
+#include <systemc>
+#include <tlm>
+#include "tlm_utils/peq_with_get.h"
+#include <sstream>
+
+namespace tlm_utils {
+
+template <typename MODULE,
+ unsigned int BUSWIDTH = 32,
+ typename TYPES = tlm::tlm_base_protocol_types>
+class simple_target_socket :
+ public tlm::tlm_target_socket<BUSWIDTH, TYPES>
+{
+ friend class fw_process;
+ friend class bw_process;
+public:
+ typedef typename TYPES::tlm_payload_type transaction_type;
+ typedef typename TYPES::tlm_phase_type phase_type;
+ typedef tlm::tlm_sync_enum sync_enum_type;
+ typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type;
+ typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type;
+ typedef tlm::tlm_target_socket<BUSWIDTH, TYPES> base_type;
+
+public:
+ simple_target_socket() :
+ base_type(sc_core::sc_gen_unique_name("simple_target_socket")),
+ m_fw_process(this),
+ m_bw_process(this)
+ {
+ bind(m_fw_process);
+ }
+
+ explicit simple_target_socket(const char* n) :
+ base_type(n),
+ m_fw_process(this),
+ m_bw_process(this)
+ {
+ bind(m_fw_process);
+ }
+
+ using tlm::tlm_target_socket<BUSWIDTH, TYPES>::bind;
+
+ // bw transport must come thru us.
+ tlm::tlm_bw_transport_if<TYPES> * operator ->() {return &m_bw_process;}
+
+ // REGISTER_XXX
+ void register_nb_transport_fw(MODULE* mod,
+ sync_enum_type (MODULE::*cb)(transaction_type&,
+ phase_type&,
+ sc_core::sc_time&))
+ {
+ assert(!sc_core::sc_get_curr_simcontext()->elaboration_done());
+ m_fw_process.set_nb_transport_ptr(mod, cb);
+ }
+
+ void register_b_transport(MODULE* mod,
+ void (MODULE::*cb)(transaction_type&,
+ sc_core::sc_time&))
+ {
+ assert(!sc_core::sc_get_curr_simcontext()->elaboration_done());
+ m_fw_process.set_b_transport_ptr(mod, cb);
+ }
+
+ void register_transport_dbg(MODULE* mod,
+ unsigned int (MODULE::*cb)(transaction_type&))
+ {
+ assert(!sc_core::sc_get_curr_simcontext()->elaboration_done());
+ m_fw_process.set_transport_dbg_ptr(mod, cb);
+ }
+
+ void register_get_direct_mem_ptr(MODULE* mod,
+ bool (MODULE::*cb)(transaction_type&,
+ tlm::tlm_dmi&))
+ {
+ assert(!sc_core::sc_get_curr_simcontext()->elaboration_done());
+ m_fw_process.set_get_direct_mem_ptr(mod, cb);
+ }
+
+private:
+ //make call on bw path.
+ sync_enum_type bw_nb_transport(transaction_type &trans, phase_type &phase, sc_core::sc_time &t)
+ {
+ return base_type::operator ->()->nb_transport_bw(trans, phase, t);
+ }
+
+ void bw_invalidate_direct_mem_ptr(sc_dt::uint64 s,sc_dt::uint64 e)
+ {
+ base_type::operator ->()->invalidate_direct_mem_ptr(s, e);
+ }
+
+ //Helper class to handle bw path calls
+ // Needed to detect transaction end when called from b_transport.
+ class bw_process : public tlm::tlm_bw_transport_if<TYPES>
+ {
+ public:
+ bw_process(simple_target_socket *p_own) : m_owner(p_own)
+ {
+ }
+
+ sync_enum_type nb_transport_bw(transaction_type &trans, phase_type &phase, sc_core::sc_time &t)
+ {
+ typename std::map<transaction_type*, sc_core::sc_event *>::iterator it;
+
+ it = m_owner->m_pending_trans.find(&trans);
+ if(it == m_owner->m_pending_trans.end()) {
+ // Not a blocking call, forward.
+ return m_owner->bw_nb_transport(trans, phase, t);
+
+ } else {
+ if (phase == tlm::END_REQ) {
+ m_owner->m_end_request.notify(sc_core::SC_ZERO_TIME);
+ return tlm::TLM_ACCEPTED;
+
+ } else if (phase == tlm::BEGIN_RESP) {
+ if (m_owner->m_current_transaction == &trans) {
+ m_owner->m_end_request.notify(sc_core::SC_ZERO_TIME);
+ }
+ //TODO: add response-accept delay?
+ it->second->notify(t);
+ m_owner->m_pending_trans.erase(it);
+ return tlm::TLM_COMPLETED;
+
+ } else {
+ assert(0); exit(1);
+ }
+
+// return tlm::TLM_COMPLETED; //Should not reach here
+ }
+ }
+
+ void invalidate_direct_mem_ptr(sc_dt::uint64 s,sc_dt::uint64 e)
+ {
+ return m_owner->bw_invalidate_direct_mem_ptr(s, e);
+ }
+
+ private:
+ simple_target_socket *m_owner;
+ };
+
+ class fw_process : public tlm::tlm_fw_transport_if<TYPES>,
+ public tlm::tlm_mm_interface
+ {
+ public:
+ typedef sync_enum_type (MODULE::*NBTransportPtr)(transaction_type&,
+ phase_type&,
+ sc_core::sc_time&);
+ typedef void (MODULE::*BTransportPtr)(transaction_type&,
+ sc_core::sc_time&);
+ typedef unsigned int (MODULE::*TransportDbgPtr)(transaction_type&);
+ typedef bool (MODULE::*GetDirectMemPtr)(transaction_type&,
+ tlm::tlm_dmi&);
+
+ fw_process(simple_target_socket *p_own) :
+ m_name(p_own->name()),
+ m_owner(p_own),
+ m_mod(0),
+ m_nb_transport_ptr(0),
+ m_b_transport_ptr(0),
+ m_transport_dbg_ptr(0),
+ m_get_direct_mem_ptr(0),
+ m_peq(sc_core::sc_gen_unique_name("m_peq")),
+ m_response_in_progress(false)
+ {
+ sc_core::sc_spawn_options opts;
+ opts.set_sensitivity(&m_peq.get_event());
+ sc_core::sc_spawn(sc_bind(&fw_process::b2nb_thread, this),
+ sc_core::sc_gen_unique_name("b2nb_thread"), &opts);
+ }
+
+ void set_nb_transport_ptr(MODULE* mod, NBTransportPtr p)
+ {
+ if (m_nb_transport_ptr) {
+ std::stringstream s;
+ s << m_name << ": non-blocking callback allready registered";
+ SC_REPORT_WARNING("/OSCI_TLM-2/simple_socket",s.str().c_str());
+ } else {
+ assert(!m_mod || m_mod == mod);
+ m_mod = mod;
+ m_nb_transport_ptr = p;
+ }
+ }
+
+ void set_b_transport_ptr(MODULE* mod, BTransportPtr p)
+ {
+ if (m_b_transport_ptr) {
+ std::stringstream s;
+ s << m_name << ": blocking callback allready registered";
+ SC_REPORT_WARNING("/OSCI_TLM-2/simple_socket",s.str().c_str());
+ } else {
+ assert(!m_mod || m_mod == mod);
+ m_mod = mod;
+ m_b_transport_ptr = p;
+ }
+ }
+
+ void set_transport_dbg_ptr(MODULE* mod, TransportDbgPtr p)
+ {
+ if (m_transport_dbg_ptr) {
+ std::stringstream s;
+ s << m_name << ": debug callback allready registered";
+ SC_REPORT_WARNING("/OSCI_TLM-2/simple_socket",s.str().c_str());
+ } else {
+ assert(!m_mod || m_mod == mod);
+ m_mod = mod;
+ m_transport_dbg_ptr = p;
+ }
+ }
+
+ void set_get_direct_mem_ptr(MODULE* mod, GetDirectMemPtr p)
+ {
+ if (m_get_direct_mem_ptr) {
+ std::stringstream s;
+ s << m_name << ": get DMI pointer callback allready registered";
+ SC_REPORT_WARNING("/OSCI_TLM-2/simple_socket",s.str().c_str());
+ } else {
+ assert(!m_mod || m_mod == mod);
+ m_mod = mod;
+ m_get_direct_mem_ptr = p;
+ }
+ }
+// Interface implementation
+ sync_enum_type nb_transport_fw(transaction_type& trans,
+ phase_type& phase,
+ sc_core::sc_time& t)
+ {
+ if (m_nb_transport_ptr) {
+ // forward call
+ assert(m_mod);
+ return (m_mod->*m_nb_transport_ptr)(trans, phase, t);
+
+ } else if (m_b_transport_ptr) {
+ if (phase == tlm::BEGIN_REQ) {
+ // prepare thread to do blocking call
+ process_handle_class * ph = m_process_handle.get_handle(&trans);
+
+ if (!ph) { // create new dynamic process
+ ph = new process_handle_class(&trans);
+ m_process_handle.put_handle(ph);
+
+ sc_core::sc_spawn_options opts;
+ opts.dont_initialize();
+ opts.set_sensitivity(&ph->m_e);
+
+ sc_core::sc_spawn(sc_bind(&fw_process::nb2b_thread,this, ph),
+ sc_core::sc_gen_unique_name("nb2b_thread"), &opts);
+ }
+
+ ph->m_e.notify(t);
+ return tlm::TLM_ACCEPTED;
+
+ } else if (phase == tlm::END_RESP) {
+ m_response_in_progress = false;
+ m_end_response.notify(t);
+ return tlm::TLM_COMPLETED;
+
+ } else {
+ assert(0); exit(1);
+// return tlm::TLM_COMPLETED; ///< unreachable code
+ }
+
+ } else {
+ std::stringstream s;
+ s << m_name << ": no non-blocking transport callback registered";
+ SC_REPORT_ERROR("/OSCI_TLM-2/simple_socket",s.str().c_str());
+ }
+ return tlm::TLM_ACCEPTED; ///< unreachable code
+ }
+
+ void b_transport(transaction_type& trans, sc_core::sc_time& t)
+ {
+ if (m_b_transport_ptr) {
+ // forward call
+ assert(m_mod);
+ (m_mod->*m_b_transport_ptr)(trans, t);
+ return;
+
+ } else if (m_nb_transport_ptr) {
+ m_peq.notify(trans, t);
+ t = sc_core::SC_ZERO_TIME;
+
+ mm_end_event_ext mm_ext;
+ const bool mm_added = !trans.has_mm();
+
+ if (mm_added) {
+ trans.set_mm(this);
+ trans.set_auto_extension(&mm_ext);
+ trans.acquire();
+ }
+
+ // wait until transaction is finished
+ sc_core::sc_event end_event;
+ m_owner->m_pending_trans[&trans] = &end_event;
+ sc_core::wait(end_event);
+
+ if (mm_added) {
+ // release will not delete the transaction, it will notify mm_ext.done
+ trans.release();
+ if (trans.get_ref_count()) {
+ sc_core::wait(mm_ext.done);
+ }
+ trans.set_mm(0);
+ }
+
+ } else {
+ std::stringstream s;
+ s << m_name << ": no blocking transport callback registered";
+ SC_REPORT_ERROR("/OSCI_TLM-2/simple_socket",s.str().c_str());
+ }
+ }
+
+ unsigned int transport_dbg(transaction_type& trans)
+ {
+ if (m_transport_dbg_ptr) {
+ // forward call
+ assert(m_mod);
+ return (m_mod->*m_transport_dbg_ptr)(trans);
+
+ } else {
+ // No debug support
+ return 0;
+ }
+ }
+
+ bool get_direct_mem_ptr(transaction_type& trans,
+ tlm::tlm_dmi& dmi_data)
+ {
+ if (m_get_direct_mem_ptr) {
+ // forward call
+ assert(m_mod);
+ return (m_mod->*m_get_direct_mem_ptr)(trans, dmi_data);
+
+ } else {
+ // No DMI support
+ dmi_data.allow_read_write();
+ dmi_data.set_start_address(0x0);
+ dmi_data.set_end_address((sc_dt::uint64)-1);
+ return false;
+ }
+ }
+
+ private:
+
+// dynamic process handler for nb2b conversion
+
+ class process_handle_class {
+ public:
+ explicit process_handle_class(transaction_type * trans)
+ : m_trans(trans),m_suspend(false) {}
+
+ transaction_type* m_trans;
+ sc_core::sc_event m_e;
+ bool m_suspend;
+ };
+
+ class process_handle_list {
+ public:
+ process_handle_list() {}
+
+ ~process_handle_list() {
+ for( typename std::vector<process_handle_class*>::iterator
+ it=v.begin(), end = v.end(); it != end; ++it )
+ delete *it;
+ }
+
+ process_handle_class* get_handle(transaction_type *trans)
+ {
+ typename std::vector<process_handle_class*>::iterator it;
+
+ for(it = v.begin(); it != v.end(); it++) {
+ if ((*it)->m_suspend) { // found suspended dynamic process, re-use it
+ (*it)->m_trans = trans; // replace to new one
+ (*it)->m_suspend = false;
+ return *it;
+ }
+ }
+ return NULL; // no suspended process
+ }
+
+ void put_handle(process_handle_class* ph)
+ {
+ v.push_back(ph);
+ }
+
+ private:
+ std::vector<process_handle_class*> v;
+ };
+
+ process_handle_list m_process_handle;
+
+
+ void nb2b_thread(process_handle_class* h)
+ {
+
+ while(1) {
+ transaction_type *trans = h->m_trans;
+ sc_core::sc_time t = sc_core::SC_ZERO_TIME;
+
+ // forward call
+ assert(m_mod);
+ (m_mod->*m_b_transport_ptr)(*trans, t);
+
+ sc_core::wait(t);
+
+ // return path
+ while (m_response_in_progress) {
+ sc_core::wait(m_end_response);
+ }
+ t = sc_core::SC_ZERO_TIME;
+ phase_type phase = tlm::BEGIN_RESP;
+ sync_enum_type sync = m_owner->bw_nb_transport(*trans, phase, t);
+ if ( !(sync == tlm::TLM_COMPLETED ||
+ (sync == tlm::TLM_UPDATED && phase == tlm::END_RESP)) ) {
+ m_response_in_progress = true;
+ }
+
+ // suspend until next transaction
+ h->m_suspend = true;
+ sc_core::wait();
+ }
+ }
+
+ void b2nb_thread()
+ {
+ while (true) {
+ sc_core::wait(m_peq.get_event());
+
+ transaction_type* trans;
+ while ((trans = m_peq.get_next_transaction())!=0) {
+ assert(m_mod);
+ assert(m_nb_transport_ptr);
+ phase_type phase = tlm::BEGIN_REQ;
+ sc_core::sc_time t = sc_core::SC_ZERO_TIME;
+
+ switch ((m_mod->*m_nb_transport_ptr)(*trans, phase, t)) {
+ case tlm::TLM_COMPLETED:
+ {
+ // notify transaction is finished
+ typename std::map<transaction_type*, sc_core::sc_event *>::iterator it =
+ m_owner->m_pending_trans.find(trans);
+ assert(it != m_owner->m_pending_trans.end());
+ it->second->notify(t);
+ m_owner->m_pending_trans.erase(it);
+ break;
+ }
+
+ case tlm::TLM_ACCEPTED:
+ case tlm::TLM_UPDATED:
+ switch (phase) {
+ case tlm::BEGIN_REQ:
+ m_owner->m_current_transaction = trans;
+ sc_core::wait(m_owner->m_end_request);
+ m_owner->m_current_transaction = 0;
+ break;
+
+ case tlm::END_REQ:
+ sc_core::wait(t);
+ break;
+
+ case tlm::BEGIN_RESP:
+ {
+ phase = tlm::END_RESP;
+ sc_core::wait(t); // This line is a bug fix added in TLM-2.0.2
+ t = sc_core::SC_ZERO_TIME;
+ (m_mod->*m_nb_transport_ptr)(*trans, phase, t);
+
+ // notify transaction is finished
+ typename std::map<transaction_type*, sc_core::sc_event *>::iterator it =
+ m_owner->m_pending_trans.find(trans);
+ assert(it != m_owner->m_pending_trans.end());
+ it->second->notify(t);
+ m_owner->m_pending_trans.erase(it);
+ break;
+ }
+
+ default:
+ assert(0); exit(1);
+ };
+ break;
+
+ default:
+ assert(0); exit(1);
+ };
+ }
+ }
+ }
+
+ void free(tlm::tlm_generic_payload* trans)
+ {
+ mm_end_event_ext* ext = trans->template get_extension<mm_end_event_ext>();
+ assert(ext);
+ // notif event first before freeing extensions (reset)
+ ext->done.notify();
+ trans->reset();
+ }
+
+ private:
+ struct mm_end_event_ext : public tlm::tlm_extension<mm_end_event_ext>
+ {
+ tlm::tlm_extension_base* clone() const { return NULL; }
+ void free() {}
+ void copy_from(tlm::tlm_extension_base const &) {}
+ sc_core::sc_event done;
+ };
+
+ private:
+ const std::string m_name;
+ simple_target_socket *m_owner;
+ MODULE* m_mod;
+ NBTransportPtr m_nb_transport_ptr;
+ BTransportPtr m_b_transport_ptr;
+ TransportDbgPtr m_transport_dbg_ptr;
+ GetDirectMemPtr m_get_direct_mem_ptr;
+ peq_with_get<transaction_type> m_peq;
+ bool m_response_in_progress;
+ sc_core::sc_event m_end_response;
+ };
+
+private:
+ fw_process m_fw_process;
+ bw_process m_bw_process;
+ std::map<transaction_type*, sc_core::sc_event *> m_pending_trans;
+ sc_core::sc_event m_end_request;
+ transaction_type* m_current_transaction;
+};
+
+//ID Tagged version
+template <typename MODULE,
+ unsigned int BUSWIDTH = 32,
+ typename TYPES = tlm::tlm_base_protocol_types>
+class simple_target_socket_tagged :
+ public tlm::tlm_target_socket<BUSWIDTH, TYPES>
+{
+ friend class fw_process;
+ friend class bw_process;
+public:
+ typedef typename TYPES::tlm_payload_type transaction_type;
+ typedef typename TYPES::tlm_phase_type phase_type;
+ typedef tlm::tlm_sync_enum sync_enum_type;
+ typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type;
+ typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type;
+ typedef tlm::tlm_target_socket<BUSWIDTH, TYPES> base_type;
+
+public:
+ simple_target_socket_tagged() :
+ base_type(sc_core::sc_gen_unique_name("simple_target_socket_tagged")),
+ m_fw_process(this),
+ m_bw_process(this)
+ {
+ bind(m_fw_process);
+ }
+
+ explicit simple_target_socket_tagged(const char* n) :
+ base_type(n),
+ m_fw_process(this),
+ m_bw_process(this)
+ {
+ bind(m_fw_process);
+ }
+
+ using tlm::tlm_target_socket<BUSWIDTH, TYPES>::bind;
+
+ // bw transport must come thru us.
+ tlm::tlm_bw_transport_if<TYPES> * operator ->() {return &m_bw_process;}
+
+ // REGISTER_XXX
+ void register_nb_transport_fw(MODULE* mod,
+ sync_enum_type (MODULE::*cb)(int id,
+ transaction_type&,
+ phase_type&,
+ sc_core::sc_time&),
+ int id)
+ {
+ assert(!sc_core::sc_get_curr_simcontext()->elaboration_done());
+ m_fw_process.set_nb_transport_ptr(mod, cb);
+ m_fw_process.set_nb_transport_user_id(id);
+ }
+
+ void register_b_transport(MODULE* mod,
+ void (MODULE::*cb)(int id,
+ transaction_type&,
+ sc_core::sc_time&),
+ int id)
+ {
+ assert(!sc_core::sc_get_curr_simcontext()->elaboration_done());
+ m_fw_process.set_b_transport_ptr(mod, cb);
+ m_fw_process.set_b_transport_user_id(id);
+ }
+
+ void register_transport_dbg(MODULE* mod,
+ unsigned int (MODULE::*cb)(int id,
+ transaction_type&),
+ int id)
+ {
+ assert(!sc_core::sc_get_curr_simcontext()->elaboration_done());
+ m_fw_process.set_transport_dbg_ptr(mod, cb);
+ m_fw_process.set_transport_dbg_user_id(id);
+ }
+
+ void register_get_direct_mem_ptr(MODULE* mod,
+ bool (MODULE::*cb)(int id,
+ transaction_type&,
+ tlm::tlm_dmi&),
+ int id)
+ {
+ assert(!sc_core::sc_get_curr_simcontext()->elaboration_done());
+ m_fw_process.set_get_direct_mem_ptr(mod, cb);
+ m_fw_process.set_get_dmi_user_id(id);
+ }
+
+private:
+ //make call on bw path.
+ sync_enum_type bw_nb_transport(transaction_type &trans, phase_type &phase, sc_core::sc_time &t)
+ {
+ return base_type::operator ->()->nb_transport_bw(trans, phase, t);
+ }
+
+ void bw_invalidate_direct_mem_ptr(sc_dt::uint64 s,sc_dt::uint64 e)
+ {
+ base_type::operator ->()->invalidate_direct_mem_ptr(s, e);
+ }
+
+ //Helper class to handle bw path calls
+ // Needed to detect transaction end when called from b_transport.
+ class bw_process : public tlm::tlm_bw_transport_if<TYPES>
+ {
+ public:
+ bw_process(simple_target_socket_tagged *p_own) : m_owner(p_own)
+ {
+ }
+
+ sync_enum_type nb_transport_bw(transaction_type &trans, phase_type &phase, sc_core::sc_time &t)
+ {
+ typename std::map<transaction_type*, sc_core::sc_event *>::iterator it;
+
+ it = m_owner->m_pending_trans.find(&trans);
+ if(it == m_owner->m_pending_trans.end()) {
+ // Not a blocking call, forward.
+ return m_owner->bw_nb_transport(trans, phase, t);
+
+ } else {
+ if (phase == tlm::END_REQ) {
+ m_owner->m_end_request.notify(sc_core::SC_ZERO_TIME);
+ return tlm::TLM_ACCEPTED;
+
+ } else if (phase == tlm::BEGIN_RESP) {
+ if (m_owner->m_current_transaction == &trans) {
+ m_owner->m_end_request.notify(sc_core::SC_ZERO_TIME);
+ }
+ //TODO: add response-accept delay?
+ it->second->notify(t);
+ m_owner->m_pending_trans.erase(it);
+ return tlm::TLM_COMPLETED;
+
+ } else {
+ assert(0); exit(1);
+ }
+
+// return tlm::TLM_COMPLETED; //Should not reach here
+ }
+ }
+
+ void invalidate_direct_mem_ptr(sc_dt::uint64 s,sc_dt::uint64 e)
+ {
+ return m_owner->bw_invalidate_direct_mem_ptr(s, e);
+ }
+
+ private:
+ simple_target_socket_tagged *m_owner;
+ };
+
+ class fw_process : public tlm::tlm_fw_transport_if<TYPES>,
+ public tlm::tlm_mm_interface
+ {
+ public:
+ typedef sync_enum_type (MODULE::*NBTransportPtr)(int id,
+ transaction_type&,
+ phase_type&,
+ sc_core::sc_time&);
+ typedef void (MODULE::*BTransportPtr)(int id,
+ transaction_type&,
+ sc_core::sc_time&);
+ typedef unsigned int (MODULE::*TransportDbgPtr)(int id,
+ transaction_type&);
+ typedef bool (MODULE::*GetDirectMemPtr)(int id,
+ transaction_type&,
+ tlm::tlm_dmi&);
+
+ fw_process(simple_target_socket_tagged *p_own) :
+ m_name(p_own->name()),
+ m_owner(p_own),
+ m_mod(0),
+ m_nb_transport_ptr(0),
+ m_b_transport_ptr(0),
+ m_transport_dbg_ptr(0),
+ m_get_direct_mem_ptr(0),
+ m_nb_transport_user_id(0),
+ m_b_transport_user_id(0),
+ m_transport_dbg_user_id(0),
+ m_get_dmi_user_id(0),
+ m_peq(sc_core::sc_gen_unique_name("m_peq")),
+ m_response_in_progress(false)
+ {
+ sc_core::sc_spawn_options opts;
+ opts.set_sensitivity(&m_peq.get_event());
+ sc_core::sc_spawn(sc_bind(&fw_process::b2nb_thread, this),
+ sc_core::sc_gen_unique_name("b2nb_thread"), &opts);
+ }
+
+ void set_nb_transport_user_id(int id) { m_nb_transport_user_id = id; }
+ void set_b_transport_user_id(int id) { m_b_transport_user_id = id; }
+ void set_transport_dbg_user_id(int id) { m_transport_dbg_user_id = id; }
+ void set_get_dmi_user_id(int id) { m_get_dmi_user_id = id; }
+
+ void set_nb_transport_ptr(MODULE* mod, NBTransportPtr p)
+ {
+ if (m_nb_transport_ptr) {
+ std::stringstream s;
+ s << m_name << ": non-blocking callback allready registered";
+ SC_REPORT_WARNING("/OSCI_TLM-2/simple_socket",s.str().c_str());
+ } else {
+ assert(!m_mod || m_mod == mod);
+ m_mod = mod;
+ m_nb_transport_ptr = p;
+ }
+ }
+
+ void set_b_transport_ptr(MODULE* mod, BTransportPtr p)
+ {
+ if (m_b_transport_ptr) {
+ std::stringstream s;
+ s << m_name << ": blocking callback allready registered";
+ SC_REPORT_WARNING("/OSCI_TLM-2/simple_socket",s.str().c_str());
+ } else {
+ assert(!m_mod || m_mod == mod);
+ m_mod = mod;
+ m_b_transport_ptr = p;
+ }
+ }
+
+ void set_transport_dbg_ptr(MODULE* mod, TransportDbgPtr p)
+ {
+ if (m_transport_dbg_ptr) {
+ std::stringstream s;
+ s << m_name << ": debug callback allready registered";
+ SC_REPORT_WARNING("/OSCI_TLM-2/simple_socket",s.str().c_str());
+ } else {
+ assert(!m_mod || m_mod == mod);
+ m_mod = mod;
+ m_transport_dbg_ptr = p;
+ }
+ }
+
+ void set_get_direct_mem_ptr(MODULE* mod, GetDirectMemPtr p)
+ {
+ if (m_get_direct_mem_ptr) {
+ std::stringstream s;
+ s << m_name << ": get DMI pointer callback allready registered";
+ SC_REPORT_WARNING("/OSCI_TLM-2/simple_socket",s.str().c_str());
+ } else {
+ assert(!m_mod || m_mod == mod);
+ m_mod = mod;
+ m_get_direct_mem_ptr = p;
+ }
+ }
+// Interface implementation
+ sync_enum_type nb_transport_fw(transaction_type& trans,
+ phase_type& phase,
+ sc_core::sc_time& t)
+ {
+ if (m_nb_transport_ptr) {
+ // forward call
+ assert(m_mod);
+ return (m_mod->*m_nb_transport_ptr)(m_nb_transport_user_id, trans, phase, t);
+
+ } else if (m_b_transport_ptr) {
+ if (phase == tlm::BEGIN_REQ) {
+
+ // prepare thread to do blocking call
+ process_handle_class * ph = m_process_handle.get_handle(&trans);
+
+ if (!ph) { // create new dynamic process
+ ph = new process_handle_class(&trans);
+ m_process_handle.put_handle(ph);
+
+ sc_core::sc_spawn_options opts;
+ opts.dont_initialize();
+ opts.set_sensitivity(&ph->m_e);
+
+ sc_core::sc_spawn(sc_bind(&fw_process::nb2b_thread, this, ph),
+ sc_core::sc_gen_unique_name("nb2b_thread"), &opts);
+ }
+
+ ph->m_e.notify(t);
+ return tlm::TLM_ACCEPTED;
+
+ } else if (phase == tlm::END_RESP) {
+ m_response_in_progress = false;
+ m_end_response.notify(t);
+ return tlm::TLM_COMPLETED;
+
+ } else {
+ assert(0); exit(1);
+// return tlm::TLM_COMPLETED; ///< unreachable code
+ }
+
+ } else {
+ std::stringstream s;
+ s << m_name << ": no non-blocking transport callback registered";
+ SC_REPORT_ERROR("/OSCI_TLM-2/simple_socket",s.str().c_str());
+ }
+ return tlm::TLM_ACCEPTED; ///< unreachable code
+ }
+
+ void b_transport(transaction_type& trans, sc_core::sc_time& t)
+ {
+ if (m_b_transport_ptr) {
+ // forward call
+ assert(m_mod);
+ (m_mod->*m_b_transport_ptr)(m_b_transport_user_id, trans, t);
+ return;
+
+ } else if (m_nb_transport_ptr) {
+ m_peq.notify(trans, t);
+ t = sc_core::SC_ZERO_TIME;
+
+ mm_end_event_ext mm_ext;
+ const bool mm_added = !trans.has_mm();
+
+ if (mm_added){
+ trans.set_mm(this);
+ trans.set_auto_extension(&mm_ext);
+ trans.acquire();
+ }
+
+ // wait until transaction is finished
+ sc_core::sc_event end_event;
+ m_owner->m_pending_trans[&trans] = &end_event;
+ sc_core::wait(end_event);
+
+ if (mm_added) {
+ // release will not delete the transaction, it will notify mm_ext.done
+ trans.release();
+ if (trans.get_ref_count()) {
+ sc_core::wait(mm_ext.done);
+ }
+ trans.set_mm(0);
+ }
+
+ } else {
+ std::stringstream s;
+ s << m_name << ": no transport callback registered";
+ SC_REPORT_ERROR("/OSCI_TLM-2/simple_socket",s.str().c_str());
+ }
+ }
+
+ unsigned int transport_dbg(transaction_type& trans)
+ {
+ if (m_transport_dbg_ptr) {
+ // forward call
+ assert(m_mod);
+ return (m_mod->*m_transport_dbg_ptr)(m_transport_dbg_user_id, trans);
+
+ } else {
+ // No debug support
+ return 0;
+ }
+ }
+
+ bool get_direct_mem_ptr(transaction_type& trans,
+ tlm::tlm_dmi& dmi_data)
+ {
+ if (m_get_direct_mem_ptr) {
+ // forward call
+ assert(m_mod);
+ return (m_mod->*m_get_direct_mem_ptr)(m_get_dmi_user_id, trans, dmi_data);
+
+ } else {
+ // No DMI support
+ dmi_data.allow_read_write();
+ dmi_data.set_start_address(0x0);
+ dmi_data.set_end_address((sc_dt::uint64)-1);
+ return false;
+ }
+ }
+
+ private:
+// dynamic process handler for nb2b conversion
+
+ class process_handle_class {
+ public:
+ explicit process_handle_class(transaction_type * trans)
+ : m_trans(trans),m_suspend(false){}
+
+ transaction_type* m_trans;
+ sc_core::sc_event m_e;
+ bool m_suspend;
+ };
+
+ class process_handle_list {
+ public:
+ process_handle_list() {}
+
+ ~process_handle_list() {
+ for( typename std::vector<process_handle_class*>::iterator
+ it=v.begin(), end = v.end(); it != end; ++it )
+ delete *it;
+ }
+
+ process_handle_class* get_handle(transaction_type *trans)
+ {
+ typename std::vector<process_handle_class*>::iterator it;
+
+ for(it = v.begin(); it != v.end(); it++) {
+ if ((*it)->m_suspend) { // found suspended dynamic process, re-use it
+ (*it)->m_trans = trans; // replace to new one
+ (*it)->m_suspend = false;
+ return *it;
+ }
+ }
+ return NULL; // no suspended process
+ }
+
+ void put_handle(process_handle_class* ph)
+ {
+ v.push_back(ph);
+ }
+
+ private:
+ std::vector<process_handle_class*> v;
+ };
+
+ process_handle_list m_process_handle;
+
+ void nb2b_thread(process_handle_class* h)
+ {
+
+ while(1) {
+ transaction_type * trans = h->m_trans;
+ sc_core::sc_time t = sc_core::SC_ZERO_TIME;
+
+ // forward call
+ assert(m_mod);
+ (m_mod->*m_b_transport_ptr)(m_b_transport_user_id, *trans, t);
+
+ sc_core::wait(t);
+
+ // return path
+ while (m_response_in_progress) {
+ sc_core::wait(m_end_response);
+ }
+ t = sc_core::SC_ZERO_TIME;
+ phase_type phase = tlm::BEGIN_RESP;
+ sync_enum_type sync = m_owner->bw_nb_transport(*trans, phase, t);
+ if ( !(sync == tlm::TLM_COMPLETED ||
+ (sync == tlm::TLM_UPDATED && phase == tlm::END_RESP)) ) {
+ m_response_in_progress = true;
+ }
+
+ // suspend until next transaction
+ h->m_suspend = true;
+ sc_core::wait();
+ }
+ }
+
+ void b2nb_thread()
+ {
+ while (true) {
+ sc_core::wait(m_peq.get_event());
+
+ transaction_type* trans;
+ while ((trans = m_peq.get_next_transaction())!=0) {
+ assert(m_mod);
+ assert(m_nb_transport_ptr);
+ phase_type phase = tlm::BEGIN_REQ;
+ sc_core::sc_time t = sc_core::SC_ZERO_TIME;
+
+ switch ((m_mod->*m_nb_transport_ptr)(m_nb_transport_user_id, *trans, phase, t)) {
+ case tlm::TLM_COMPLETED:
+ {
+ // notify transaction is finished
+ typename std::map<transaction_type*, sc_core::sc_event *>::iterator it =
+ m_owner->m_pending_trans.find(trans);
+ assert(it != m_owner->m_pending_trans.end());
+ it->second->notify(t);
+ m_owner->m_pending_trans.erase(it);
+ break;
+ }
+
+ case tlm::TLM_ACCEPTED:
+ case tlm::TLM_UPDATED:
+ switch (phase) {
+ case tlm::BEGIN_REQ:
+ m_owner->m_current_transaction = trans;
+ sc_core::wait(m_owner->m_end_request);
+ m_owner->m_current_transaction = 0;
+ break;
+
+ case tlm::END_REQ:
+ sc_core::wait(t);
+ break;
+
+ case tlm::BEGIN_RESP:
+ {
+ phase = tlm::END_RESP;
+ sc_core::wait(t); // This line is a bug fix added in TLM-2.0.2
+ t = sc_core::SC_ZERO_TIME;
+ (m_mod->*m_nb_transport_ptr)(m_nb_transport_user_id, *trans, phase, t);
+
+ // notify transaction is finished
+ typename std::map<transaction_type*, sc_core::sc_event *>::iterator it =
+ m_owner->m_pending_trans.find(trans);
+ assert(it != m_owner->m_pending_trans.end());
+ it->second->notify(t);
+ m_owner->m_pending_trans.erase(it);
+ break;
+ }
+
+ default:
+ assert(0); exit(1);
+ };
+ break;
+
+ default:
+ assert(0); exit(1);
+ };
+ }
+ }
+ }
+
+ void free(tlm::tlm_generic_payload* trans)
+ {
+ mm_end_event_ext* ext = trans->template get_extension<mm_end_event_ext>();
+ assert(ext);
+ // notif event first before freeing extensions (reset)
+ ext->done.notify();
+ trans->reset();
+ }
+
+ private:
+ struct mm_end_event_ext : public tlm::tlm_extension<mm_end_event_ext>
+ {
+ tlm::tlm_extension_base* clone() const { return NULL; }
+ void free() {}
+ void copy_from(tlm::tlm_extension_base const &) {}
+ sc_core::sc_event done;
+ };
+
+ private:
+ const std::string m_name;
+ simple_target_socket_tagged *m_owner;
+ MODULE* m_mod;
+ NBTransportPtr m_nb_transport_ptr;
+ BTransportPtr m_b_transport_ptr;
+ TransportDbgPtr m_transport_dbg_ptr;
+ GetDirectMemPtr m_get_direct_mem_ptr;
+ int m_nb_transport_user_id;
+ int m_b_transport_user_id;
+ int m_transport_dbg_user_id;
+ int m_get_dmi_user_id;
+ peq_with_get<transaction_type> m_peq;
+ bool m_response_in_progress;
+ sc_core::sc_event m_end_response;
+ };
+
+private:
+ fw_process m_fw_process;
+ bw_process m_bw_process;
+ std::map<transaction_type*, sc_core::sc_event *> m_pending_trans;
+ sc_core::sc_event m_end_request;
+ transaction_type* m_current_transaction;
+};
+
+}
+
+#endif
diff --git a/ext/systemc/src/tlm_utils/tlm2_base_protocol_checker.h b/ext/systemc/src/tlm_utils/tlm2_base_protocol_checker.h
new file mode 100755
index 000000000..3dbca9e49
--- /dev/null
+++ b/ext/systemc/src/tlm_utils/tlm2_base_protocol_checker.h
@@ -0,0 +1,1055 @@
+
+// Filename: tlm2_base_protocol_checker.h
+
+//----------------------------------------------------------------------
+// Copyright (c) 2008-2013 by Doulos Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//----------------------------------------------------------------------
+
+// Author: John Aynsley, Doulos
+
+// Version 1, 11 July 2008
+// Version 2, 16 July 2008 Only generate ref_count > 1 warning from 1st checker of path
+// Version 3, 17 July 2008 Support compilation under SystemC 2.1.v1
+// Version 4, 12 Aug 2008 Add header #include <map>
+// Version 5, 08 Sep 2008 Fix bugs in message text
+// Version 6, 01 Aug 2010 Update messages to refer to OSCI TLM-2.0 LRM of July 2009
+// Version 7, 25 Oct 2011 Minor bug fix for certain compilers: replace u_char with uchar_t
+// Version 8, 02 Nov 2011 Support the endianness conversion functions by excluding the
+// tlm_endian_context extension from the protocol checks
+// Version 9, 17 Aug 2012 Fix LRM reference on line 805 (should be 8.2.11 a) [NOT YET RELEASED]
+// Version 10, 3 Jan 2013 Updated messages to refer to IEEE Std 1666-2011, the combined SystemC + TLM-2.0 LRM
+// Added checks related to the generic payload option attribute
+// Version 11, 14 Mar 2016 Fix minor bug - start_phase should be a copy, not a reference
+
+// TLM-2.0 Base Protocol Compliance Checker
+
+/*
+Instantiate this checker module in-line between initiator and target, initiator and interconnect,
+or interconnect and target by binding the target_socket and initiator_socket
+Binding two checkers either side of an interconnect component, or interleaving a series of
+checkers with interconnect components, will enable some deeper checks as against having just
+a single checker
+
+For example
+
+ Initiator *initiator;
+ Bus *bus;
+ Memory *memory;
+ ...
+ initiator->socket.bind(bus->target_socket);
+ bus->initiator_socket.bind(memory->socket);
+
+might become
+
+ tlm_utils::tlm2_base_protocol_checker<32> *checker1;
+ tlm_utils::tlm2_base_protocol_checker<32> *checker2;
+ ...
+ initiator->socket.bind(checker1->target_socket);
+ checker1->initiator_socket.bind(bus->target_socket);
+ bus->initiator_socket.bind(checker2->target_socket);
+ checker2->initiator_socket.bind(memory->socket);
+
+
+GENERAL FEATURES OF THE BASE PROTOCOL CHECKER
+
+The checks are relatively expensive, hence by default the number of checks is limited.
+A maximum number can be set explicitly by calling set_num_checks(max)
+Checking can be deactivated at any time by calling set_num_checks(0)
+All checkers decrement a single global count, because having some checkers running and
+others not can cause bogus violation reports
+It is not permitted to turn checks on by calling set_num_checks() once checking has been
+deactivated, because this could cause bogus violation reports
+
+The DMI and debug checks are unaffected by the num_checks count (because they are cheap)
+
+The error messages contain User Manual references
+
+The checker is designed to be used with a transaction pool: otherwise it could consume
+a lot of memory. The checker keeps a local copy of each transaction object
+Failures are reported with a severity of SC_ERROR. The actions may be overridden by calling:
+ sc_report_handler::set_actions("tlm2_protocol_checker", ...);
+
+SPECIFIC CHECKS
+
+nb_transport: phase sequence BEGIN_REQ -> END_REQ -> BEGIN_RESP -> END_RESP
+Must not have two outstanding requests or responses (exclusion rules)
+Must not have decreasing timing annotations on calls to or returns from nb_transport_fw/bw
+Phase extensions permitted and ignored
+Must not call b_transport during nb_transport phase sequence and vice-versa
+
+nb_transport: memory manager must be set
+nb_transport: reference count must be non-zero
+First checker in BEGIN_REQ path should see ref_count == 1 (warning only)
+An interconnect component that sets a memory manager should also clear it
+An interconnect component that sets extensions with no memory manager should also clear them
+(Does not bother with these memory manager checks for DMI and debug)
+
+Transaction object must be properly initialized
+Many generic payload attributes must not be modified during the transaction lifetime
+Transaction object must not be re-allocated for a new transaction while still in use
+DMI descriptor must be properly initialized
+Debug transaction must be properly initialized
+Debug byte count must be less than data_length
+
+Checks that require multiple checkers to be instantiated along a transaction path:
+The BEGIN_RESP path must be the reverse of the BEGIN_REQ path
+Transaction object must not be sent with BEGIN_REQ while participating in a previous response
+Interconnect component must not set response status attribute to TLM_OK_RESPONSE
+Interconnect component must not modify data array on the response path
+
+Generic payload option attribute (IEEE Std 1666-2011, SystemC 2.3.x)
+gp_option must be properly initialized and only used for DMI and debug transport
+When gp_option is used, other gp attributes must be initalized and used as per the transport interfaces
+*/
+
+
+// ******************** PREAMBLE ********************
+
+
+#ifndef __tlm2_base_protocol_checker__
+#define __tlm2_base_protocol_checker__
+
+#include "systemc"
+using std::cout;
+using std::endl;
+using std::dec;
+using std::hex;
+
+#include "tlm.h"
+#include <sstream>
+#include <map>
+
+
+namespace tlm_utils {
+
+
+// Number of checks remaining
+const sc_dt::uint64 default_num_checks = 100000;
+static sc_dt::uint64 num_checks = default_num_checks;
+
+
+// Types used when building a trace of the transaction path
+typedef unsigned char uchar_t;
+typedef std::deque<sc_core::sc_module*> deque_t;
+
+struct path_t {
+ path_t () { response_in_progress = false; ok_response = false; resp_data_ptr = 0; }
+
+ bool response_in_progress;
+ bool ok_response;
+ deque_t path;
+ uchar_t* resp_data_ptr; // Copy of data on response path
+};
+
+// Global variable used for checks involving multiple checkers along a transaction path
+static std::map<tlm::tlm_generic_payload*, path_t> shared_map;
+
+
+// ******************** CLASS DEFINITION ********************
+
+
+template <unsigned int BUSWIDTH = 32>
+class tlm2_base_protocol_checker
+
+: public sc_core::sc_module
+, public tlm::tlm_fw_transport_if<tlm::tlm_base_protocol_types>
+, public tlm::tlm_bw_transport_if<tlm::tlm_base_protocol_types>
+{
+public:
+
+ // Instantiate and bind checker inline between an existing pair of initiator and target sockets
+
+ tlm::tlm_target_socket <BUSWIDTH, tlm::tlm_base_protocol_types, 1> target_socket;
+ tlm::tlm_initiator_socket<BUSWIDTH, tlm::tlm_base_protocol_types, 1> initiator_socket;
+
+ SC_CTOR(tlm2_base_protocol_checker)
+ : m_request_in_progress(0), m_response_in_progress(0)
+ {
+ target_socket .bind( *this );
+ initiator_socket.bind( *this );
+ }
+
+
+ // Access methods for num_checks count
+
+ static void set_num_checks(sc_dt::uint64 n) {
+ if (num_checks == 0)
+ SC_REPORT_FATAL("tlm2_protocol_checker", "Method set_num_checks called after checking has stopped due to maximum number of checks being reached");
+ num_checks = n;
+ }
+
+ static sc_dt::uint64 get_num_checks() { return num_checks; }
+
+
+ // TLM-2.0 interface methods for initiator and target sockets, instrumented with checks
+
+ virtual tlm::tlm_sync_enum nb_transport_fw(
+ tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay)
+ {
+ tlm::tlm_phase start_phase = phase;
+
+ if (num_checks)
+ nb_transport_fw_pre_checks( trans, phase, delay );
+
+ tlm::tlm_sync_enum status;
+ status = initiator_socket->nb_transport_fw( trans, phase, delay );
+
+ if (num_checks)
+ nb_transport_fw_post_checks( trans, start_phase, phase, delay, status );
+
+ return status;
+ }
+
+ virtual tlm::tlm_sync_enum nb_transport_bw(
+ tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay)
+ {
+ if (num_checks)
+ nb_transport_bw_pre_checks( trans, phase, delay );
+
+ tlm::tlm_sync_enum status;
+ status = target_socket->nb_transport_bw( trans, phase, delay );
+
+ if (num_checks)
+ nb_transport_bw_post_checks( trans, phase, delay, status );
+
+ return status;
+ }
+
+ virtual void b_transport( tlm::tlm_generic_payload& trans, sc_core::sc_time& delay )
+ {
+ if (num_checks)
+ b_transport_pre_checks( trans, delay );
+
+ initiator_socket->b_transport( trans, delay );
+
+ if (num_checks)
+ b_transport_post_checks( trans, delay );
+ }
+
+ virtual bool get_direct_mem_ptr(tlm::tlm_generic_payload& trans,
+ tlm::tlm_dmi& dmi_data)
+ {
+ get_direct_mem_ptr_pre_checks( trans, dmi_data );
+
+ bool status;
+ status = initiator_socket->get_direct_mem_ptr( trans, dmi_data );
+
+ get_direct_mem_ptr_post_checks( trans, dmi_data );
+ return status;
+ }
+
+ virtual void invalidate_direct_mem_ptr(sc_dt::uint64 start_range,
+ sc_dt::uint64 end_range)
+ {
+ target_socket->invalidate_direct_mem_ptr(start_range, end_range);
+ }
+
+ virtual unsigned int transport_dbg(tlm::tlm_generic_payload& trans)
+ {
+ transport_dbg_pre_checks( trans );
+
+ unsigned int count;
+ count = initiator_socket->transport_dbg( trans );
+
+ transport_dbg_post_checks( trans, count );
+ return count;
+ }
+
+
+private:
+ void b_transport_pre_checks( tlm::tlm_generic_payload& trans, sc_core::sc_time& delay);
+
+ void b_transport_post_checks( tlm::tlm_generic_payload& trans, sc_core::sc_time& delay);
+
+ void nb_transport_fw_pre_checks(
+ tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay);
+
+ void nb_transport_fw_post_checks(
+ tlm::tlm_generic_payload& trans, tlm::tlm_phase& start_phase, tlm::tlm_phase& phase,
+ sc_core::sc_time& delay, tlm::tlm_sync_enum status);
+
+ void nb_transport_bw_pre_checks(
+ tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay);
+
+ void nb_transport_bw_post_checks(
+ tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay,
+ tlm::tlm_sync_enum status);
+
+ void nb_transport_response_checks(
+ tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay,
+ const char* txt2, const char* txt3, const char* txt4);
+
+ void check_initial_state( tlm::tlm_generic_payload& trans, const char* txt2 );
+ void check_trans_not_modified( tlm::tlm_generic_payload& trans, const char* txt2 );
+ void check_response_path( tlm::tlm_generic_payload& trans, const char* txt2 );
+ void remember_gp_option( tlm::tlm_generic_payload& trans );
+
+ void get_direct_mem_ptr_pre_checks( tlm::tlm_generic_payload& trans, tlm::tlm_dmi& dmi_data );
+
+ void get_direct_mem_ptr_post_checks( tlm::tlm_generic_payload& trans, tlm::tlm_dmi& dmi_data );
+
+ void transport_dbg_pre_checks( tlm::tlm_generic_payload& trans );
+
+ void transport_dbg_post_checks( tlm::tlm_generic_payload& trans, unsigned int count );
+
+ void tlm2error( tlm::tlm_generic_payload& trans, const char* ref, bool warning = false );
+
+private:
+
+ struct state_t {
+ state_t() { b_call = 0; ph = tlm::UNINITIALIZED_PHASE; gp = 0; }
+
+ bool has_mm;
+ unsigned int b_call; // Number of b_transport calls in progress
+ tlm::tlm_phase ph;
+ sc_core::sc_time time; // Current time + annotated delay
+ tlm::tlm_generic_payload* gp; // Points to new data and byte enable buffers
+ uchar_t* data_ptr; // Stores original pointers
+ uchar_t* byte_enable_ptr;
+ };
+
+ // Transaction state for the specific hop where this checker is inlined
+ std::map<tlm::tlm_generic_payload*, state_t> m_map;
+
+ // Flags for exclusion rules
+ tlm::tlm_generic_payload* m_request_in_progress;
+ tlm::tlm_generic_payload* m_response_in_progress;
+
+ std::ostringstream txt;
+
+};
+
+
+
+// ******************** MEMBER FUNCTION DEFINITIONS ********************
+
+
+#define BOILERPLATE \
+template <unsigned int BUSWIDTH> \
+void tlm2_base_protocol_checker<BUSWIDTH>::
+
+
+BOILERPLATE
+b_transport_pre_checks(
+ tlm::tlm_generic_payload& trans, sc_core::sc_time& delay)
+{
+ ++ m_map[&trans].b_call;
+
+ if ( trans.has_mm() && trans.get_ref_count() == 0)
+ {
+ txt << "Transaction passed to b_transport with memory manager and reference count of 0";
+ tlm2error(trans, "14.5 t)");
+ }
+ check_initial_state(trans, "b_transport");
+
+#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
+ if (sc_core::sc_get_current_process_handle().proc_kind() == sc_core::SC_METHOD_PROC_)
+ {
+ txt << "b_transport called from method process";
+ tlm2error(trans, "11.1.1.4 b)");
+ }
+#endif
+
+ if (m_map[&trans].ph > 0 && m_map[&trans].ph < 4)
+ {
+ txt << "b_transport called during a sequence of nb_transport calls";
+ tlm2error(trans, "15.2.10 c)");
+ }
+}
+
+
+BOILERPLATE
+b_transport_post_checks(
+ tlm::tlm_generic_payload& trans, sc_core::sc_time& delay)
+{
+ check_response_path(trans, "b_transport");
+ check_trans_not_modified(trans, "b_transport");
+ -- m_map[&trans].b_call;
+}
+
+
+BOILERPLATE
+nb_transport_fw_pre_checks(
+ tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay)
+{
+ if ( !trans.has_mm() )
+ {
+ txt << "Transaction passed to nb_transport_fw with no memory manager set";
+ tlm2error(trans, "14.5 i)");
+ }
+ if ( trans.get_ref_count() == 0)
+ {
+ txt << "Transaction passed to nb_transport_fw with reference count of 0";
+ tlm2error(trans, "14.5 t)");
+ }
+
+ switch (phase)
+ {
+ case tlm::BEGIN_REQ:
+ check_initial_state(trans, "nb_transport_fw");
+
+ if (m_map[&trans].ph > 0 && m_map[&trans].ph < 4) // END_RESP -> BEGIN_REQ is legal
+ {
+ txt << "Phase " << phase << " sent out-of-sequence on forward path, detected in nb_transport_fw";
+ tlm2error(trans, "15.2.4");
+ }
+
+ if (m_request_in_progress)
+ {
+ txt << "Transaction violates BEGIN_REQ exclusion rule, detected in nb_transport_fw";
+ tlm2error(trans, "15.2.6 e)");
+ }
+ m_request_in_progress = &trans;
+
+ if (m_map[&trans].b_call)
+ {
+ txt << "nb_transport_fw called during a b_transport call";
+ tlm2error(trans, "15.2.10 c)");
+ }
+ break;
+
+ case tlm::END_REQ:
+ case tlm::BEGIN_RESP:
+ case tlm::UNINITIALIZED_PHASE:
+ txt << "Phase " << phase << " sent on forward path, detected in nb_transport_fw";
+ tlm2error(trans, " 15.2.3 c)");
+ break;
+
+ case tlm::END_RESP:
+ if (m_map[&trans].ph != tlm::BEGIN_RESP)
+ {
+ txt << "Phase " << phase << " sent out-of-sequence on forward path, detected in nb_transport_fw";
+ tlm2error(trans, "15.2.4");
+ }
+ m_response_in_progress = 0;
+ break;
+ }
+
+ if (phase < 5) // Ignore extended phases
+ m_map[&trans].ph = phase;
+
+ if (sc_core::sc_time_stamp() + delay < m_map[&trans].time)
+ {
+ txt << "nb_transport_fw called with decreasing timing annotation:"
+ << " delay = " << delay
+ << ", sc_time_stamp() + delay from previous call = " << m_map[&trans].time;
+ tlm2error(trans, "15.2.7 c)");
+ }
+ m_map[&trans].time = sc_core::sc_time_stamp() + delay;
+}
+
+
+BOILERPLATE
+nb_transport_fw_post_checks(
+ tlm::tlm_generic_payload& trans, tlm::tlm_phase& start_phase, tlm::tlm_phase& phase,
+ sc_core::sc_time& delay, tlm::tlm_sync_enum status)
+{
+ if (status == tlm::TLM_UPDATED)
+ {
+ nb_transport_response_checks(
+ trans, phase, delay, "(forward) return", "Return from nb_transport_fw", "nb_transport_fw");
+ }
+ else if (status == tlm::TLM_COMPLETED)
+ {
+ if (start_phase == tlm::BEGIN_REQ)
+ check_response_path(trans, "nb_transport_fw");
+ m_request_in_progress = 0;
+ m_map[&trans].ph = tlm::UNINITIALIZED_PHASE;
+ }
+
+ // Transaction object should not be re-allocated, even during the END_RESP phase
+ //if (phase != tlm::END_RESP)
+ {
+ std::ostringstream txt;
+ txt << "nb_transport_fw, phase = " << phase;
+ check_trans_not_modified(trans, txt.str().c_str());
+ }
+}
+
+
+BOILERPLATE
+nb_transport_bw_pre_checks(
+ tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay)
+{
+ if ( !trans.has_mm() )
+ {
+ txt << "Transaction passed to nb_transport_bw with no memory manager set";
+ tlm2error(trans, "14.5 i)");
+ }
+ if ( trans.get_ref_count() == 0)
+ {
+ txt << "Transaction passed to nb_transport_bw with reference count of 0";
+ tlm2error(trans, "14.5 t)");
+ }
+ nb_transport_response_checks(
+ trans, phase, delay, "backward", "nb_transport_bw called", "nb_transport_bw");
+}
+
+
+BOILERPLATE
+nb_transport_bw_post_checks(
+ tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay,
+ tlm::tlm_sync_enum status)
+{
+ if (status == tlm::TLM_UPDATED)
+ {
+ switch (phase)
+ {
+ case tlm::BEGIN_REQ:
+ txt << "Phase " << phase << " sent out-of-sequence on (backward) return path, detected in nb_transport_bw";
+ tlm2error(trans, "15.2.4");
+ break;
+
+ case tlm::END_REQ:
+ case tlm::BEGIN_RESP:
+ case tlm::UNINITIALIZED_PHASE:
+ txt << "Phase " << phase << " sent on (backward) return path, detected in nb_transport_bw";
+ tlm2error(trans, "15.2.3 c)");
+ break;
+
+ case tlm::END_RESP:
+ if (m_map[&trans].ph != tlm::BEGIN_RESP)
+ {
+ txt << "Phase " << phase << " sent out-of-sequence on (backward) return path, detected in nb_transport_bw";
+ tlm2error(trans, "15.2.4");
+ }
+
+ m_response_in_progress = 0;
+ break;
+ }
+
+ if (phase < 5) // Ignore extended phases
+ m_map[&trans].ph = phase;
+
+ if (sc_core::sc_time_stamp() + delay < m_map[&trans].time)
+ {
+ txt << "Return from nb_transport_bw with decreasing timing annotation:"
+ << " delay = " << delay
+ << ", sc_time_stamp() + delay from previous call = " << m_map[&trans].time;
+ tlm2error(trans, "15.2.7 c)");
+ }
+ m_map[&trans].time = sc_core::sc_time_stamp() + delay;
+ }
+ else if (status == tlm::TLM_COMPLETED)
+ {
+ m_response_in_progress = 0;
+ m_map[&trans].ph = tlm::UNINITIALIZED_PHASE;
+ }
+
+ // Transaction object should not be re-allocated, even during the END_RESP phase
+ //if (phase != tlm::END_RESP)
+ {
+ std::ostringstream txt;
+ txt << "nb_transport_bw, phase = " << phase;
+ check_trans_not_modified(trans, txt.str().c_str());
+ }
+}
+
+
+BOILERPLATE
+nb_transport_response_checks(
+ tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay,
+ const char* txt2, const char* txt3, const char* txt4)
+{
+ if (trans.is_response_ok())
+ if (shared_map[&trans].response_in_progress && !shared_map[&trans].ok_response)
+ {
+ txt << "Interconnect component sets response status attribute to TLM_OK_RESPONSE"
+ << ", detected in " << txt4;
+ tlm2error(trans, "14.7");
+
+ }
+
+ switch (phase)
+ {
+ case tlm::BEGIN_REQ:
+ case tlm::END_RESP:
+ case tlm::UNINITIALIZED_PHASE:
+ txt << "Phase " << phase << " sent on " << txt2 << " path"
+ << ", detected in " << txt4;
+ tlm2error(trans, "15.2.3 c)");
+ break;
+
+ case tlm::END_REQ:
+ if (m_map[&trans].ph != tlm::BEGIN_REQ)
+ {
+ txt << "Phase " << phase << " sent out-of-sequence on " << txt2 << " path"
+ << ", detected in " << txt4;
+ tlm2error(trans, "15.2.4");
+ }
+
+ m_request_in_progress = 0;
+ break;
+
+ case tlm::BEGIN_RESP:
+ if (m_map[&trans].ph != tlm::BEGIN_REQ && m_map[&trans].ph != tlm::END_REQ)
+ {
+ txt << "Phase " << phase << " sent out-of-sequence on " << txt2 << " path"
+ << ", detected in " << txt4;
+ tlm2error(trans, "15.2.4");
+ }
+
+ if (&trans == m_request_in_progress)
+ m_request_in_progress = 0;
+
+ if (m_response_in_progress)
+ {
+ txt << "Transaction violates BEGIN_RESP exclusion rule"
+ << ", detected in " << txt4;
+ tlm2error(trans, "15.2.6 f)");
+ }
+ m_response_in_progress = &trans;
+
+ check_response_path(trans, txt4);
+ break;
+ }
+
+ if (phase < 5) // Ignore extended phases
+ m_map[&trans].ph = phase;
+
+ if (sc_core::sc_time_stamp() + delay < m_map[&trans].time)
+ {
+ txt << txt3 << " with decreasing timing annotation:"
+ << " delay = " << delay
+ << ", sc_time_stamp() + delay from previous call = " << m_map[&trans].time;
+ tlm2error(trans, "15.2.7 c)");
+ }
+ m_map[&trans].time = sc_core::sc_time_stamp() + delay;
+}
+
+
+BOILERPLATE
+check_initial_state(
+ tlm::tlm_generic_payload& trans, const char* txt2 )
+{
+ if (num_checks > 0)
+ {
+ --num_checks;
+ if (num_checks == 0)
+ SC_REPORT_INFO("tlm2_protocol_checker", "Checkers deactivated after executing the set number of checks");
+ }
+
+ if ( trans.has_mm() && trans.get_ref_count() > 1 && shared_map[&trans].path.empty() )
+ {
+ txt << "New transaction passed to " << txt2 << " with reference count = "
+ << trans.get_ref_count();
+ tlm2error(trans, "14.5 t)", true);
+ }
+ if (trans.get_data_ptr() == 0 && trans.get_command() != tlm::TLM_IGNORE_COMMAND)
+ {
+ txt << "Transaction not properly initialized: data_ptr == 0, detected in " << txt2;
+ tlm2error(trans, "14.11 e)");
+ }
+ if (trans.get_data_length() == 0 && trans.get_command() != tlm::TLM_IGNORE_COMMAND)
+ {
+ txt << "Transaction not properly initialized: data_langth == 0, detected in " << txt2;
+ tlm2error(trans, "14.12 d)");
+ }
+ if (trans.get_byte_enable_ptr() != 0 && trans.get_byte_enable_length() == 0)
+ {
+ txt << "Transaction not properly initialized: "
+ << "byte_enable_ptr != 0 and byte_enable_length == 0, detected in " << txt2;
+ tlm2error(trans, "14.14 f)");
+ }
+ if (trans.get_streaming_width() == 0)
+ {
+ txt << "Transaction not properly initialized: streaming_width == 0, detected in " << txt2;
+ tlm2error(trans, "14.15 f)");
+ }
+ if (trans.is_dmi_allowed())
+ {
+ txt << "Transaction not properly initialized: dmi_allowed == true, detected in " << txt2;
+ tlm2error(trans, "14.16");
+ }
+ if (trans.get_response_status() != tlm::TLM_INCOMPLETE_RESPONSE)
+ {
+ txt << "Transaction not properly initialized: response_status != TLM_INCOMPLETE_RESPONSE, detected in " << txt2;
+ tlm2error(trans, "14.17 e)");
+ }
+ if (trans.get_gp_option() != tlm::TLM_MIN_PAYLOAD)
+ {
+ txt << "Transaction not properly initialized: gp_option != TLM_MIN_PAYLOAD, detected in " << txt2;
+ tlm2error(trans, "14.8 g)");
+ }
+
+ // Setup clones of transaction and buffers in map
+ tlm::tlm_generic_payload* gp = m_map[&trans].gp;
+ if (gp == 0)
+ gp = new tlm::tlm_generic_payload; // Memory leak: transactions are never cleared from map
+ else
+ {
+ delete [] gp->get_data_ptr();
+ gp->free_all_extensions();
+ }
+ gp->set_data_ptr( new uchar_t[trans.get_data_length()] );
+ m_map[&trans].data_ptr = trans.get_data_ptr();
+
+ if (gp->get_byte_enable_ptr())
+ delete [] gp->get_byte_enable_ptr();
+ if (trans.get_byte_enable_ptr())
+ gp->set_byte_enable_ptr( new uchar_t[trans.get_byte_enable_length()] );
+ else
+ gp->set_byte_enable_ptr(0);
+ m_map[&trans].byte_enable_ptr = trans.get_byte_enable_ptr();
+
+ gp->deep_copy_from(trans);
+ m_map[&trans].gp = gp;
+ m_map[&trans].time = sc_core::SC_ZERO_TIME;
+ m_map[&trans].has_mm = trans.has_mm();
+
+ // Store request path checker sequence
+ if (shared_map[&trans].resp_data_ptr)
+ {
+ delete [] shared_map[&trans].resp_data_ptr;
+ shared_map[&trans].resp_data_ptr = 0;
+ }
+ if (shared_map[&trans].response_in_progress)
+ {
+ txt << "Transaction object sent with BEGIN_REQ while still being used on a previous response path, detected in " << txt2;
+ tlm2error(trans, "14.5 x)");
+ }
+ shared_map[&trans].ok_response = false;
+ shared_map[&trans].path.push_back(this);
+}
+
+
+BOILERPLATE
+remember_gp_option(
+ tlm::tlm_generic_payload& trans)
+{
+ // Setup clone of transaction in map in order to check gp_option only
+ tlm::tlm_generic_payload* gp = m_map[&trans].gp;
+ if (gp == 0)
+ gp = new tlm::tlm_generic_payload; // Memory leak: transactions are never cleared from map
+ gp->set_gp_option( trans.get_gp_option() );
+ m_map[&trans].gp = gp;
+}
+
+
+BOILERPLATE
+check_trans_not_modified(
+ tlm::tlm_generic_payload& trans, const char* txt2 )
+{
+ tlm::tlm_generic_payload* init = m_map[&trans].gp;
+
+ if (trans.get_command() != init->get_command())
+ {
+ txt << "Command attribute modified during transaction lifetime, detected in " << txt2;
+ tlm2error(trans, "14.7");
+ }
+ if (trans.get_data_ptr() != m_map[&trans].data_ptr)
+ {
+ txt << "Data pointer attribute modified during transaction lifetime, detected in " << txt2;
+ tlm2error(trans, "14.7");
+ }
+ if (trans.get_data_length() != init->get_data_length())
+ {
+ txt << "Data length attribute modified during transaction lifetime, detected in " << txt2;
+ tlm2error(trans, "14.7");
+ }
+ if (trans.get_command() == tlm::TLM_WRITE_COMMAND)
+ for (unsigned int i = 0; i < init->get_data_length(); i++)
+ if (trans.get_data_ptr()[i] != init->get_data_ptr()[i])
+ {
+ txt << "Data array modified during transaction lifetime, detected in " << txt2;
+ tlm2error(trans, "14.7");
+ }
+ if (trans.get_byte_enable_ptr() != m_map[&trans].byte_enable_ptr)
+ {
+ txt << "Byte enable pointer attribute modified during transaction lifetime, detected in " << txt2;
+ tlm2error(trans, "14.7");
+ }
+ if (trans.get_byte_enable_length() != init->get_byte_enable_length())
+ {
+ txt << "Byte enable length attribute modified during transaction lifetime, detected in " << txt2;
+ tlm2error(trans, "14.7");
+ }
+ if (trans.get_byte_enable_ptr())
+ for (unsigned int i = 0; i < init->get_byte_enable_length(); i++)
+ if (trans.get_byte_enable_ptr()[i] != init->get_byte_enable_ptr()[i])
+ {
+ txt << "Byte enable array modified during transaction lifetime, detected in " << txt2;
+ tlm2error(trans, "14.7");
+ }
+ if (trans.get_streaming_width() != init->get_streaming_width())
+ {
+ txt << "Streaming width attribute modified during transaction lifetime, detected in " << txt2;
+ tlm2error(trans, "14.7");
+ }
+ if (init->get_gp_option() == tlm::TLM_MIN_PAYLOAD && trans.get_gp_option() != tlm::TLM_MIN_PAYLOAD)
+ {
+ txt << "Generic payload option attribute modified during transaction lifetime, detected in " << txt2;
+ tlm2error(trans, "14.8 g)");
+ }
+ if ( !m_map[&trans].has_mm )
+ {
+ if (trans.has_mm())
+ {
+ txt << "Interconnect component sets a memory manager, but does not clear it on return, detected in " << txt2;
+ tlm2error(trans, "14.5 aa)");
+ }
+
+ for (unsigned int i = 0; i < tlm::max_num_extensions(); i++)
+ // Exclude tlm_endian_context extension from the check because it is not cloned in m_map
+ if (i != tlm::tlm_endian_context::ID)
+ if (trans.get_extension(i))
+ if ( !m_map[&trans].gp->get_extension(i) )
+ {
+ txt << "Extension set (index = " << i << ") without also being deleted in the absence of a memory manager, detected in " << txt2;
+ tlm2error(trans, "14.5 aa)");
+ }
+ }
+
+ uchar_t* resp_data_ptr = shared_map[&trans].resp_data_ptr;
+ if (resp_data_ptr)
+ for (unsigned int i = 0; i < trans.get_data_length(); i++)
+ if (trans.get_data_ptr()[i] != resp_data_ptr[i])
+ {
+ txt << "Transaction data array modified in interconnect component on response path, detected in " << txt2;
+ tlm2error(trans, "14.7");
+ }
+}
+
+
+BOILERPLATE
+check_response_path(
+ tlm::tlm_generic_payload& trans, const char* txt2 )
+{
+ if ( !shared_map[&trans].path.empty() )
+ {
+ if ( this != shared_map[&trans].path.back() )
+ {
+ txt << "BEGIN_RESP path is not the reverse of the BEGIN_REQ path.";
+ txt << "\nBEGIN_REQ path includes these checkers: -> ";
+ deque_t path = shared_map[&trans].path;
+ for (deque_t::iterator i = path.begin(); i < path.end(); i++)
+ txt << (*i)->name() << " -> ";
+ txt << "\nDetected in " << txt2;
+ tlm2error(trans, "15.2.11 a)");
+ }
+ shared_map[&trans].path.pop_back();
+ shared_map[&trans].response_in_progress = !shared_map[&trans].path.empty();
+ shared_map[&trans].ok_response = trans.is_response_ok();
+
+ // Create a copy of the data array for comparison on the response path
+ if ( !shared_map[&trans].resp_data_ptr )
+ {
+ shared_map[&trans].resp_data_ptr = new uchar_t[trans.get_data_length()];
+ memcpy(shared_map[&trans].resp_data_ptr, trans.get_data_ptr(), trans.get_data_length());
+ }
+ }
+}
+
+
+BOILERPLATE
+get_direct_mem_ptr_pre_checks(
+ tlm::tlm_generic_payload& trans, tlm::tlm_dmi& dmi_data )
+{
+ remember_gp_option(trans);
+
+ if (dmi_data.get_dmi_ptr() != 0)
+ {
+ txt << "DMI descriptor not properly initialized: dmi_ptr != 0";
+ tlm2error(trans, "11.2.5 f)");
+ }
+ if (!dmi_data.is_none_allowed())
+ {
+ txt << "DMI descriptor not properly initialized: granted_access != DMI_ACCESS_NONE";
+ tlm2error(trans, "11.2.5 a)");
+ }
+ if (dmi_data.get_start_address() != 0)
+ {
+ txt << "DMI descriptor not properly initialized: start_address != 0";
+ tlm2error(trans, "11.2.5 u)");
+ }
+ if (dmi_data.get_end_address() != (sc_dt::uint64)(-1))
+ {
+ txt << "DMI descriptor not properly initialized: end_address != 0";
+ tlm2error(trans, "11.2.5 u)");
+ }
+ if (dmi_data.get_read_latency() != sc_core::SC_ZERO_TIME)
+ {
+ txt << "DMI descriptor not properly initialized: read_latency != SC_ZERO_TIME";
+ tlm2error(trans, "11.2.5 ac)");
+ }
+ if (dmi_data.get_write_latency() != sc_core::SC_ZERO_TIME)
+ {
+ txt << "DMI descriptor not properly initialized: write_latency != SC_ZERO_TIME";
+ tlm2error(trans, "11.2.5 ac)");
+ }
+
+ if (trans.get_gp_option() == tlm::TLM_FULL_PAYLOAD)
+ {
+ /*
+ if (trans.is_dmi_allowed()) // Would be rather brutal to flag dmi_allowed as an arror for a DMI transaction!
+ {
+ txt << "DMI transaction not properly initialized: dmi_allowed == true";
+ tlm2error(trans, "14.8 e) & 14.16");
+ }
+ */
+ if (trans.get_response_status() != tlm::TLM_INCOMPLETE_RESPONSE)
+ {
+ txt << "DMI transaction not properly initialized: response_status != TLM_INCOMPLETE_RESPONSE";
+ tlm2error(trans, "14.8 e) & 14.17 e)");
+ }
+ }
+ else if (trans.get_gp_option() == tlm::TLM_FULL_PAYLOAD_ACCEPTED)
+ {
+ txt << "DMI transaction not properly initialized: gp_option == TLM_FULL_PAYLOAD_ACCEPTED";
+ tlm2error(trans, "14.8 c) & e) & j)");
+ }
+}
+
+
+BOILERPLATE
+get_direct_mem_ptr_post_checks( tlm::tlm_generic_payload& trans, tlm::tlm_dmi& dmi_data )
+{
+ tlm::tlm_generic_payload* init = m_map[&trans].gp;
+
+ if (init->get_gp_option() == tlm::TLM_MIN_PAYLOAD && trans.get_gp_option() != tlm::TLM_MIN_PAYLOAD)
+ {
+ txt << "DMI transaction gp_option attribute value TLM_MIN_PAYLOAD modified during transaction lifetime";
+ tlm2error(trans, "14.8 h)");
+ }
+ else if (init->get_gp_option() == tlm::TLM_FULL_PAYLOAD && trans.get_gp_option() == tlm::TLM_MIN_PAYLOAD)
+ {
+ txt << "DMI transaction gp_option attribute value changed from TLM_FULL_PAYLOAD to TLM_MIN_PAYLOAD";
+ tlm2error(trans, "14.8 j)");
+ }
+}
+
+
+BOILERPLATE
+transport_dbg_pre_checks( tlm::tlm_generic_payload& trans )
+{
+ remember_gp_option(trans);
+
+ if (trans.get_data_length() > 0 && trans.get_data_ptr() == 0)
+ {
+ txt << "Debug transaction has data_ptr == 0";
+ tlm2error(trans, "11.3.4 l)");
+ }
+
+ if (trans.get_gp_option() == tlm::TLM_FULL_PAYLOAD)
+ {
+ if (trans.get_byte_enable_ptr() != 0 && trans.get_byte_enable_length() == 0)
+ {
+ txt << "Debug transaction not properly initialized: "
+ << "byte_enable_ptr != 0 and byte_enable_length == 0";
+ tlm2error(trans, "14.8 f) & 14.14 f)");
+ }
+ if (trans.get_streaming_width() == 0)
+ {
+ txt << "Debug transaction not properly initialized: streaming_width == 0";
+ tlm2error(trans, "14.8 f) & 14.15 f)");
+ }
+ if (trans.is_dmi_allowed())
+ {
+ txt << "Debug transaction not properly initialized: dmi_allowed == true";
+ tlm2error(trans, "14.8 f) & 14.16");
+ }
+ if (trans.get_response_status() != tlm::TLM_INCOMPLETE_RESPONSE)
+ {
+ txt << "Debug transaction not properly initialized: response_status != TLM_INCOMPLETE_RESPONSE";
+ tlm2error(trans, "14.8 f) & 14.17 e)");
+ }
+ }
+ else if (trans.get_gp_option() == tlm::TLM_FULL_PAYLOAD_ACCEPTED)
+ {
+ txt << "Debug transaction not properly initialized: gp_option == TLM_FULL_PAYLOAD_ACCEPTED";
+ tlm2error(trans, "14.8 c) & f) & l)");
+ }}
+
+
+BOILERPLATE
+transport_dbg_post_checks( tlm::tlm_generic_payload& trans, unsigned int count )
+{
+ tlm::tlm_generic_payload* init = m_map[&trans].gp;
+
+ if (trans.get_data_length() > 0 && trans.get_data_ptr() == 0)
+ {
+ txt << "Debug transaction has data_ptr == 0";
+ tlm2error(trans, "11.3.4 l)");
+ }
+ if (count > trans.get_data_length())
+ {
+ txt << "Count returned from transport_dbg is greater than data_length";
+ tlm2error(trans, "11.3.4 s)");
+ }
+
+ if (init->get_gp_option() == tlm::TLM_MIN_PAYLOAD && trans.get_gp_option() != tlm::TLM_MIN_PAYLOAD)
+ {
+ txt << "Debug transaction gp_option attribute value TLM_MIN_PAYLOAD modified during transaction lifetime";
+ tlm2error(trans, "14.8 h)");
+ }
+ else if (init->get_gp_option() == tlm::TLM_FULL_PAYLOAD && trans.get_gp_option() == tlm::TLM_MIN_PAYLOAD)
+ {
+ txt << "Debug transaction gp_option attribute value changed from TLM_FULL_PAYLOAD to TLM_MIN_PAYLOAD";
+ tlm2error(trans, "14.8 l)");
+ }}
+
+
+BOILERPLATE
+tlm2error( tlm::tlm_generic_payload& trans, const char* ref, bool warning )
+{
+ txt << "\n\nRefer to IEEE Std 1666-2011, clause " << ref;
+ txt << "\n\nChecker instance: " << this->name();
+ txt << "\n\nTransaction details:";
+ txt << "\n has_mm = " << dec << trans.has_mm() << " (bool)";
+ txt << "\n ref_count = " << dec << trans.get_ref_count() << " (int)";
+ txt << "\n\n gp_option = " <<
+ (trans.get_gp_option() == tlm::TLM_MIN_PAYLOAD ? "TLM_MIN_PAYLOAD"
+ :trans.get_gp_option() == tlm::TLM_FULL_PAYLOAD ? "TLM_FULL_PAYLOAD"
+ : "TLM_FULL_PAYLOAD_ACCEPTED");
+ txt << "\n command = " <<
+ (trans.get_command() == tlm::TLM_READ_COMMAND ? "TLM_READ_COMMAND"
+ :trans.get_command() == tlm::TLM_WRITE_COMMAND ? "TLM_WRITE_COMMAND"
+ : "TLM_IGNORE_COMMAND");
+ txt << "\n address = " << hex << trans.get_address() << " (hex)";
+ txt << "\n data_ptr = " << hex
+ << reinterpret_cast<int*>(trans.get_data_ptr()) << " (hex)";
+ txt << "\n data_length = " << hex << trans.get_data_length() << " (hex)";
+ txt << "\n streaming_width = " << hex << trans.get_streaming_width() << " (hex)";
+ txt << "\n byte_enable_ptr = " << hex
+ << reinterpret_cast<int*>(trans.get_byte_enable_ptr()) << " (hex)";
+ txt << "\n byte_enable_length = " << hex << trans.get_byte_enable_length() << " (hex)";
+ txt << "\n dmi_allowed = " << dec << trans.is_dmi_allowed() << " (bool)";
+ txt << "\n response_status = " << trans.get_response_string();
+
+ bool extensions_present = false;
+ for (unsigned int i = 0; i < tlm::max_num_extensions(); i++)
+ {
+ tlm::tlm_extension_base* ext = trans.get_extension(i);
+ if (ext)
+ {
+ if (!extensions_present)
+ txt << "\n\n extensions:";
+ txt << "\n index = " << i << " type = " << typeid(*ext).name();
+ extensions_present = true;
+ }
+ }
+
+ txt << "\n\n";
+ if (warning)
+ SC_REPORT_WARNING("tlm2_protocol_checker", txt.str().c_str());
+ else
+ SC_REPORT_ERROR("tlm2_protocol_checker", txt.str().c_str());
+}
+
+
+
+} // namespace tlm_utils
+
+#endif // __tlm2_base_protocol_checker__
diff --git a/ext/systemc/src/tlm_utils/tlm_quantumkeeper.h b/ext/systemc/src/tlm_utils/tlm_quantumkeeper.h
new file mode 100644
index 000000000..ed211665f
--- /dev/null
+++ b/ext/systemc/src/tlm_utils/tlm_quantumkeeper.h
@@ -0,0 +1,172 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+// 20-Mar-2009 John Aynsley Add set_and_sync() method
+
+
+#ifndef __TLM_QUANTUMKEEPER_H__
+#define __TLM_QUANTUMKEEPER_H__
+
+#include "tlm_core/tlm_2/tlm_quantum/tlm_global_quantum.h"
+
+namespace tlm_utils {
+
+ //
+ // tlm_quantumkeeper class
+ //
+ // The tlm_quantumkeeper class is used to keep track of the local time in
+ // an initiator (how much it has run ahead of the SystemC time), to
+ // synchronize with SystemC time etc.
+ //
+ class tlm_quantumkeeper
+ {
+ public:
+ //
+ // Static setters/getters for the global quantum value.
+ //
+ // The global quantum is the maximum time an initiator can run ahead of
+ // systemC time. All initiators will synchronize on timingpoints that are
+ // multiples of the global quantum value.
+ //
+ static void set_global_quantum(const sc_core::sc_time& t)
+ {
+ tlm::tlm_global_quantum::instance().set(t);
+ }
+
+ static const sc_core::sc_time& get_global_quantum()
+ {
+ return tlm::tlm_global_quantum::instance().get();
+ }
+
+ public:
+ tlm_quantumkeeper() :
+ m_next_sync_point(sc_core::SC_ZERO_TIME),
+ m_local_time(sc_core::SC_ZERO_TIME)
+ {
+ }
+
+ virtual ~tlm_quantumkeeper() {}
+
+ //
+ // Increment the local time (the time the initiator is ahead of the
+ // systemC time) After incrementing the local time an initiator should
+ // check (with the need_sync method) if a sync is required.
+ //
+ virtual void inc(const sc_core::sc_time& t)
+ {
+ m_local_time += t;
+ }
+
+ //
+ // Sets the local time (the time the initiator is ahead of the
+ // systemC time) After changing the local time an initiator should
+ // check (with the need_sync method) if a sync is required.
+ //
+ virtual void set(const sc_core::sc_time& t)
+ {
+ m_local_time = t;
+ }
+
+ //
+ // Checks if a sync to systemC is required for this initiator. This will
+ // be the case if the local time becomes greater than the local (current)
+ // quantum value for this initiator.
+ //
+ virtual bool need_sync() const
+ {
+ return sc_core::sc_time_stamp() + m_local_time >= m_next_sync_point;
+ }
+
+ //
+ // Synchronize to systemC. This call will do a wait for the time the
+ // initiator was running ahead of systemC time and reset the
+ // tlm_quantumkeeper.
+ //
+ virtual void sync()
+ {
+ sc_core::wait(m_local_time);
+ reset();
+ }
+
+ //
+ // Non-virtual convenience method to set the local time and sync only if needed
+ //
+ void set_and_sync(const sc_core::sc_time& t)
+ {
+ set(t);
+ if (need_sync())
+ sync();
+ }
+
+ //
+ // Resets the local time to SC_ZERO_TIME and computes the value of the
+ // next local quantum. This method should be called by an initiator after
+ // a wait because of a synchronization request by a target (TLM_ACCEPTED,
+ // or TLM_UPDATED).
+ //
+ virtual void reset()
+ {
+ m_local_time = sc_core::SC_ZERO_TIME;
+ m_next_sync_point = sc_core::sc_time_stamp() + compute_local_quantum();
+ }
+
+ //
+ // Helper function to get the current systemC time, taken the local time
+ // into account. The current systemC time is calculated as the time
+ // returned by sc_time_stamp incremeneted with the time the initiator is
+ // running ahead.
+ //
+ virtual sc_core::sc_time get_current_time() const
+ {
+ return sc_core::sc_time_stamp() + m_local_time;
+ }
+
+ //
+ // Helper functions to get the time the initiator is running ahead of
+ // systenC (local time). This time should be passed to a target in the
+ // nb_transport call
+ //
+ virtual sc_core::sc_time get_local_time() const
+ {
+ return m_local_time;
+ }
+
+ protected:
+ //
+ // Calculate the next local quantum for this initiator.
+ //
+ // The method can be overloaded in a derived object if an initiator wants
+ // to use another local quantum. This derived object should also take the
+ // global quantum into account. It's local quantum should not be set to a
+ // value that is larger than the quantum returned by the
+ // compute_local_quantum of the tlm_global_quantum singleton.
+ //
+ virtual sc_core::sc_time compute_local_quantum()
+ {
+ return tlm::tlm_global_quantum::instance().compute_local_quantum();
+ }
+
+ protected:
+ sc_core::sc_time m_next_sync_point;
+ sc_core::sc_time m_local_time;
+ };
+
+} // namespace tlm
+
+#endif