00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #ifndef SC_LAMBDA_H
00037 #define SC_LAMBDA_H
00038
00039
00040 #include <cassert>
00041
00042 #include "sysc/kernel/sc_cmnhdr.h"
00043 #include "sysc/kernel/sc_macros.h"
00044 #include "sysc/communication/sc_signal_ifs.h"
00045 #include "sysc/datatypes/bit/sc_logic.h"
00046 #include "sysc/utils/sc_mempool.h"
00047
00048 namespace sc_core {
00049
00050 class sc_port_registry;
00051
00052
00053
00054 class sc_lambda;
00055 class sc_lambda_ptr;
00056 class sc_lambda_rand;
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 enum sc_lambda_rator_e
00073 {
00074 SC_LAMBDA_FALSE = 0x00000000,
00075 SC_LAMBDA_TRUE,
00076
00077
00078 SC_LAMBDA_AND,
00079 SC_LAMBDA_OR,
00080 SC_LAMBDA_NOT,
00081
00082 SC_LAMBDA_BOOL,
00083 SC_LAMBDA_BOOL_EQ,
00084 SC_LAMBDA_BOOL_NE,
00085
00086
00087 SC_LAMBDA_SUL_EQ,
00088 SC_LAMBDA_SUL_NE,
00089
00090
00091 SC_LAMBDA_INT_EQ,
00092 SC_LAMBDA_INT_NE,
00093 SC_LAMBDA_INT_LE,
00094 SC_LAMBDA_INT_GE,
00095 SC_LAMBDA_INT_LT,
00096 SC_LAMBDA_INT_GT,
00097
00098
00099 SC_LAMBDA_SUL_BITAND,
00100 SC_LAMBDA_SUL_BITOR,
00101 SC_LAMBDA_SUL_BITNOT,
00102 SC_LAMBDA_SUL_BITXOR,
00103
00104
00105 SC_LAMBDA_INT_ADD,
00106 SC_LAMBDA_INT_SUB,
00107 SC_LAMBDA_INT_MUL,
00108 SC_LAMBDA_INT_DIV,
00109 SC_LAMBDA_INT_REM,
00110
00111
00112 SC_LAMBDA_INT_BITAND,
00113 SC_LAMBDA_INT_BITOR,
00114 SC_LAMBDA_INT_BITNOT,
00115 SC_LAMBDA_INT_BITXOR
00116 };
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 class sc_lambda
00135 {
00136 friend class sc_lambda_ptr;
00137 friend class sc_lambda_rand;
00138 friend class sc_port_registry;
00139
00140 #include "sysc/kernel/sc_lambda_friends.h"
00141
00142 public:
00143
00144 static void* operator new( size_t sz )
00145 { return sc_mempool::allocate( sz ); }
00146
00147 static void operator delete( void* p, size_t sz )
00148 { sc_mempool::release( p, sz ); }
00149
00150
00151 explicit sc_lambda( const sc_signal_in_if<bool>& );
00152
00153
00154 bool eval() const;
00155
00156
00157 ~sc_lambda();
00158
00159 private:
00160
00161
00162 sc_lambda( sc_lambda_rator_e op,
00163 sc_lambda_rand* o1 = 0, sc_lambda_rand* o2 = 0 );
00164
00165
00166 int int_eval() const;
00167
00168
00169 sc_dt::sc_logic sc_logic_eval() const;
00170
00171
00172 bool is_bool() const
00173 {
00174 return ( ( SC_LAMBDA_AND <= rator_ty ) &&
00175 ( rator_ty <= SC_LAMBDA_INT_GT ) );
00176 }
00177
00178
00179 bool is_int() const
00180 {
00181 return ( ( SC_LAMBDA_INT_ADD <= rator_ty ) &&
00182 ( rator_ty <= SC_LAMBDA_INT_BITXOR ) );
00183 }
00184
00185
00186 bool is_sc_logic() const
00187 {
00188 return ( ( SC_LAMBDA_SUL_BITAND <= rator_ty ) &&
00189 ( rator_ty <= SC_LAMBDA_SUL_BITXOR ) );
00190 }
00191
00192 void replace_ports( void (*fn)( sc_port_registry*, sc_lambda_rand* ),
00193 sc_port_registry* );
00194
00195 private:
00196
00197 sc_lambda_rator_e rator_ty;
00198 sc_lambda_rand* op1;
00199 sc_lambda_rand* op2;
00200 int ref_count;
00201
00202 private:
00203
00204 sc_lambda();
00205
00206 static sc_lambda dummy_lambda;
00207 };
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 class sc_lambda_ptr
00225 {
00226 friend class sc_cthread_process;
00227 friend class sc_lambda;
00228 friend class sc_lambda_rand;
00229 friend class sc_port_registry;
00230
00231 #include "sysc/kernel/sc_lambda_friends.h"
00232
00233 public:
00234
00235 static void* operator new( size_t sz )
00236 { return sc_mempool::allocate( sz ); }
00237
00238 static void* operator new( size_t, void* p )
00239 { return p; }
00240
00241 static void operator delete( void* p, size_t sz )
00242 { sc_mempool::release( p, sz ); }
00243
00244
00245
00246 sc_lambda_ptr()
00247 : ptr( &sc_lambda::dummy_lambda )
00248 {
00249 ptr->ref_count ++;
00250 }
00251
00252 sc_lambda_ptr( const sc_lambda_ptr& p )
00253 : ptr( p.ptr )
00254 {
00255 ptr->ref_count ++;
00256 }
00257
00258 explicit sc_lambda_ptr( const sc_signal_bool_deval& b )
00259 : ptr( new sc_lambda( RCAST<const sc_signal_in_if<bool>&>( b ) ) )
00260 {
00261 ptr->ref_count ++;
00262 }
00263
00264
00265 ~sc_lambda_ptr()
00266 {
00267 if( -- ( ptr->ref_count ) == 0 )
00268 delete ptr;
00269 }
00270
00271
00272 sc_lambda_ptr& operator = ( const sc_lambda_ptr& p )
00273 {
00274 if( &p == this )
00275 return *this;
00276
00277 if (--(ptr->ref_count) == 0)
00278 delete ptr;
00279 ptr = p.ptr;
00280
00281 ptr->ref_count++;
00282 return *this;
00283 }
00284
00285 operator bool() const
00286 {
00287
00288
00289
00290
00291
00292 return ptr->eval();
00293 }
00294
00295 private:
00296
00297 sc_lambda* ptr;
00298 sc_lambda_ptr( sc_lambda* p )
00299 : ptr(p)
00300 {
00301
00302 ptr->ref_count++;
00303 }
00304 sc_lambda_ptr& operator=( sc_lambda* p )
00305 {
00306
00307 if (--(ptr->ref_count) == 0)
00308 delete ptr;
00309 ptr = p;
00310 ptr->ref_count++;
00311 return *this;
00312 }
00313 sc_lambda* operator->() const { return ptr; }
00314 };
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331 enum sc_lambda_rand_e
00332 {
00333 SC_LAMBDA_RAND_LAMBDA,
00334 SC_LAMBDA_RAND_SIGNAL_INT,
00335 SC_LAMBDA_RAND_SIGNAL_SUL,
00336 SC_LAMBDA_RAND_SIGNAL_BOOL,
00337 SC_LAMBDA_RAND_INT,
00338 SC_LAMBDA_RAND_SUL,
00339 SC_LAMBDA_RAND_BOOL
00340 };
00341
00342
00343 class sc_lambda_rand
00344 {
00345 friend class sc_lambda;
00346 friend class sc_port_registry;
00347
00348 public:
00349
00350 static void* operator new( size_t sz )
00351 { return sc_mempool::allocate( sz ); }
00352
00353 static void operator delete( void* p, size_t sz )
00354 { sc_mempool::release( p, sz ); }
00355
00356 #include "sysc/kernel/sc_lambda_friends.h"
00357
00358 private:
00359
00360 sc_lambda_rand_e rand_ty;
00361 union {
00362 char lamb_space[sizeof(sc_lambda_ptr)];
00363 char ch_space[sizeof(sc_dt::sc_logic)];
00364 const sc_signal_in_if<sc_dt::sc_logic>* sul_sig;
00365 const sc_signal_in_if<int>* int_sig;
00366 const sc_signal_in_if<bool>* edgy_sig;
00367 int val;
00368 };
00369
00370 sc_lambda_rand( int i )
00371 : rand_ty( SC_LAMBDA_RAND_INT )
00372 {
00373 val = i;
00374 }
00375 sc_lambda_rand( bool b )
00376 : rand_ty( SC_LAMBDA_RAND_BOOL )
00377 {
00378 val = int(b);
00379 }
00380 sc_lambda_rand( const sc_dt::sc_logic& c )
00381 : rand_ty( SC_LAMBDA_RAND_SUL )
00382 {
00383 (void) new(ch_space) sc_dt::sc_logic(c);
00384 }
00385 sc_lambda_rand( const sc_signal_logic_deval& s )
00386 : rand_ty( SC_LAMBDA_RAND_SIGNAL_SUL )
00387 {
00388 sul_sig = RCAST<const sc_signal_in_if<sc_dt::sc_logic>*>( &s );
00389 }
00390 sc_lambda_rand( const sc_signal_in_if<int>& s )
00391 : rand_ty( SC_LAMBDA_RAND_SIGNAL_INT )
00392 {
00393 int_sig = &s;
00394 }
00395 sc_lambda_rand( const sc_signal_in_if<bool>& s )
00396 : rand_ty( SC_LAMBDA_RAND_SIGNAL_BOOL )
00397 {
00398 edgy_sig = &s;
00399 }
00400 sc_lambda_rand( const sc_signal_bool_deval& s )
00401 : rand_ty( SC_LAMBDA_RAND_SIGNAL_BOOL )
00402 {
00403 edgy_sig = RCAST<const sc_signal_in_if<bool>*>( &s );
00404 }
00405
00406 sc_lambda_rand( const sc_lambda_ptr& l )
00407 : rand_ty( SC_LAMBDA_RAND_LAMBDA )
00408 {
00409 (void) new(lamb_space) sc_lambda_ptr(l);
00410 }
00411
00412 ~sc_lambda_rand();
00413
00414 int int_read() const;
00415 sc_dt::sc_logic sc_logic_read() const;
00416 bool bool_read() const;
00417
00418 void replace_ports( void (*fn)(sc_port_registry*, sc_lambda_rand* ),
00419 sc_port_registry* );
00420 };
00421
00422
00423
00424
00425 #include "sysc/kernel/sc_lambda_defs.h"
00426
00427 }
00428
00429 #endif