codegen.h File Reference

Contains functions for generating Verilog code from expression trees. More...

#include "defines.h"

Go to the source code of this file.

Functions

void codegen_gen_expr (expression *expr, exp_op_type parent_op, char ***code, unsigned int *code_depth, func_unit *funit)
 Creates Verilog code string from specified expression tree.

Detailed Description

Contains functions for generating Verilog code from expression trees.

Author:
Trevor Williams (phase1geo@gmail.com)
Date:
4/11/2002

Function Documentation

void codegen_gen_expr ( expression expr,
exp_op_type  parent_op,
char ***  code,
unsigned int *  code_depth,
func_unit funit 
)

Creates Verilog code string from specified expression tree.

Parameters:
expr Pointer to root of expression tree to generate.
parent_op Operation of parent. If our op is the same, no surrounding parenthesis is needed.
code Pointer to array of strings that will contain code lines for the supplied expression.
code_depth Pointer to number of strings contained in code array.
funit Pointer to functional unit containing the specified expression.

Generates Verilog code from specified expression tree. This Verilog snippet is used by the verbose coverage reporting functions for showing Verilog examples that were missed during simulation. This code handles multi-line Verilog output by storing its information into the code and code_depth parameters.

Parameters:
expr Pointer to root of expression tree to generate
parent_op Operation of parent. If our op is the same, no surrounding parenthesis is needed
code Pointer to array of strings that will contain code lines for the supplied expression
code_depth Pointer to number of strings contained in code array
funit Pointer to functional unit containing the specified expression

References codegen_create_expr(), codegen_gen_expr(), vsuppl_u::data_type, DECIMAL, expression_s::elem, ESUPPL_IS_ROOT, ESUPPL_STATIC_BASE, ESUPPL_WAS_SWAPPED, EXP_OP_ADD, EXP_OP_ADD_A, EXP_OP_AEDGE, EXP_OP_ALS_A, EXP_OP_ALSHIFT, EXP_OP_ALWAYS_COMB, EXP_OP_ALWAYS_LATCH, EXP_OP_AND, EXP_OP_AND_A, EXP_OP_ARS_A, EXP_OP_ARSHIFT, EXP_OP_ASSIGN, EXP_OP_BASSIGN, EXP_OP_CASE, EXP_OP_CASEX, EXP_OP_CASEZ, EXP_OP_CEQ, EXP_OP_CNE, EXP_OP_CONCAT, EXP_OP_COND, EXP_OP_COND_SEL, EXP_OP_DASSIGN, EXP_OP_DEFAULT, EXP_OP_DELAY, EXP_OP_DIM, EXP_OP_DISABLE, EXP_OP_DIV_A, EXP_OP_DIVIDE, EXP_OP_DLY_ASSIGN, EXP_OP_DLY_OP, EXP_OP_EOR, EXP_OP_EQ, EXP_OP_EXPAND, EXP_OP_EXPONENT, EXP_OP_FORK, EXP_OP_FUNC_CALL, EXP_OP_GE, EXP_OP_GT, EXP_OP_IDEC, EXP_OP_IF, EXP_OP_IINC, EXP_OP_JOIN, EXP_OP_LAND, EXP_OP_LAST, EXP_OP_LE, EXP_OP_LIST, EXP_OP_LOR, EXP_OP_LS_A, EXP_OP_LSHIFT, EXP_OP_LT, EXP_OP_MBIT_NEG, EXP_OP_MBIT_POS, EXP_OP_MBIT_SEL, EXP_OP_MLT_A, EXP_OP_MOD, EXP_OP_MOD_A, EXP_OP_MULTIPLY, EXP_OP_NAND, EXP_OP_NASSIGN, EXP_OP_NB_CALL, EXP_OP_NE, EXP_OP_NEDGE, EXP_OP_NEGATE, EXP_OP_NOR, EXP_OP_NXOR, EXP_OP_OR, EXP_OP_OR_A, EXP_OP_PARAM, EXP_OP_PARAM_MBIT, EXP_OP_PARAM_MBIT_NEG, EXP_OP_PARAM_MBIT_POS, EXP_OP_PARAM_SBIT, EXP_OP_PASSIGN, EXP_OP_PDEC, EXP_OP_PEDGE, EXP_OP_PINC, EXP_OP_PLIST, EXP_OP_RASSIGN, EXP_OP_REPEAT, EXP_OP_RPT_DLY, EXP_OP_RS_A, EXP_OP_RSHIFT, EXP_OP_SASSIGN, EXP_OP_SB2R, EXP_OP_SB2SR, EXP_OP_SBIT_SEL, EXP_OP_SCLOG2, EXP_OP_SI2R, EXP_OP_SIG, EXP_OP_SLIST, EXP_OP_SR2B, EXP_OP_SR2I, EXP_OP_SRANDOM, EXP_OP_SSIGNED, EXP_OP_SSR2B, EXP_OP_SSRANDOM, EXP_OP_STATIC, EXP_OP_STESTARGS, EXP_OP_STIME, EXP_OP_SUB_A, EXP_OP_SUBTRACT, EXP_OP_SUNSIGNED, EXP_OP_SURAND_RANGE, EXP_OP_SURANDOM, EXP_OP_SVALARGS, EXP_OP_TASK_CALL, EXP_OP_TRIGGER, EXP_OP_UAND, EXP_OP_UINV, EXP_OP_UNAND, EXP_OP_UNOR, EXP_OP_UNOT, EXP_OP_UNXOR, EXP_OP_UOR, EXP_OP_UXOR, EXP_OP_WAIT, EXP_OP_WHILE, EXP_OP_XOR, EXP_OP_XOR_A, expr_stmt_u::expr, FALSE, free_safe, expression_s::funit, expression_s::left, expression_s::line, malloc_safe, func_unit_s::name, expression_s::name, expression_s::op, expression_s::parent, esuppl_u::parenthesis, esuppl_u::part, vsuppl_u::part, PROFILE, QSTRING, vector_s::r32, vector_s::r64, expression_s::right, scope_extract_back(), scope_gen_printable(), expression_s::sig, rv32_s::str, rv64_s::str, strdup_safe, expression_s::suppl, vector_s::suppl, user_msg, vector_s::value, expression_s::value, VDATA_R32, VDATA_R64, vector_to_int(), and vector_to_string().

Referenced by codegen_gen_expr(), combination_display_verbose(), combination_get_expression(), fsm_display_verbose(), fsm_get_coverage(), and line_display_verbose().

00334   { PROFILE(CODEGEN_GEN_EXPR);
00335 
00336   char**       right_code;               /* Pointer to the code that is generated by the right side of the expression */
00337   char**       left_code;                /* Pointer to the code that is generated by the left side of the expression */
00338   unsigned int left_code_depth  = 0;     /* Depth of left code string array */
00339   unsigned int right_code_depth = 0;     /* Depth of right code string array */
00340   char         code_format[20];          /* Format for creating my_code string */
00341   char*        tmpstr;                   /* Temporary string holder */
00342   char*        before;                   /* String before operation */
00343   char*        after;                    /* String after operation */
00344   func_unit*   tfunit;                   /* Temporary pointer to functional unit */
00345   char*        pname            = NULL;  /* Printable version of signal name */
00346   unsigned int rv;                       /* Return value from calls to snprintf */
00347 
00348   if( expr != NULL ) {
00349 
00350     /* Only traverse left and right expression trees if we are not an SLIST-type */
00351     if( (expr->op != EXP_OP_SLIST) && (expr->op != EXP_OP_ALWAYS_COMB) && (expr->op != EXP_OP_ALWAYS_LATCH) ) {
00352 
00353       codegen_gen_expr( expr->left,  expr->op, &left_code,  &left_code_depth,  funit );
00354       codegen_gen_expr( expr->right, expr->op, &right_code, &right_code_depth, funit );
00355 
00356     }
00357 
00358     if( (expr->op == EXP_OP_LAST) || (expr->op == EXP_OP_NB_CALL) || (expr->op == EXP_OP_JOIN) || (expr->op == EXP_OP_FORK) ||
00359         ((parent_op == EXP_OP_REPEAT) && (expr->parent->expr->left == expr)) ) {
00360 
00361       /* Do nothing. */
00362       *code_depth = 0;
00363 
00364     } else if( expr->op == EXP_OP_STATIC ) {
00365 
00366       unsigned int data_type = expr->value->suppl.part.data_type;
00367 
00368       *code       = (char**)malloc_safe( sizeof( char* ) );
00369       *code_depth = 1;
00370 
00371       if( data_type == VDATA_R64 ) {
00372 
00373         assert( expr->value->value.r64->str != NULL );
00374         (*code)[0] = strdup_safe( expr->value->value.r64->str );
00375 
00376       } else if( data_type == VDATA_R32 ) {
00377 
00378         assert( expr->value->value.r32->str != NULL );
00379         (*code)[0] = strdup_safe( expr->value->value.r32->str );
00380 
00381       } else {
00382 
00383         if( ESUPPL_STATIC_BASE( expr->suppl ) == DECIMAL ) {
00384 
00385           rv = snprintf( code_format, 20, "%d", vector_to_int( expr->value ) );
00386           assert( rv < 20 );
00387           if( (strlen( code_format ) == 1) && (expr->parent->expr->op == EXP_OP_NEGATE) ) {
00388             strcat( code_format, " " );
00389           }
00390           (*code)[0] = strdup_safe( code_format );
00391 
00392         } else if( ESUPPL_STATIC_BASE( expr->suppl ) == QSTRING ) {
00393 
00394           unsigned int slen;
00395           tmpstr = vector_to_string( expr->value, QSTRING, FALSE, 0 );
00396           slen   = strlen( tmpstr ) + 3;
00397           (*code)[0] = (char*)malloc_safe( slen );
00398           rv = snprintf( (*code)[0], slen, "\"%s\"", tmpstr );
00399           assert( rv < slen );
00400           free_safe( tmpstr, (strlen( tmpstr ) + 1) );
00401 
00402         } else { 
00403 
00404           (*code)[0] = vector_to_string( expr->value, ESUPPL_STATIC_BASE( expr->suppl ), FALSE, 0 );
00405 
00406         }
00407    
00408       }
00409 
00410     } else if( (expr->op == EXP_OP_SIG) || (expr->op == EXP_OP_PARAM) ) {
00411 
00412       tmpstr = scope_gen_printable( expr->name );
00413 
00414       switch( strlen( tmpstr ) ) {
00415         case 0 :  assert( strlen( tmpstr ) > 0 );  break;
00416         case 1 :
00417           *code       = (char**)malloc_safe( sizeof( char* ) );
00418           (*code)[0]  = (char*)malloc_safe( 4 );
00419           *code_depth = 1;
00420           rv = snprintf( (*code)[0], 4, " %s ", tmpstr );
00421           assert( rv < 4 );
00422           break;
00423         case 2 :
00424           *code       = (char**)malloc_safe( sizeof( char* ) );
00425           (*code)[0]  = (char*)malloc_safe( 4 );
00426           *code_depth = 1;
00427           rv = snprintf( (*code)[0], 4, " %s", tmpstr );
00428           assert( rv < 4 );
00429           break;
00430         default :
00431           *code       = (char**)malloc_safe( sizeof( char* ) );
00432           (*code)[0]  = strdup_safe( tmpstr );
00433           *code_depth = 1;
00434           break;
00435       }
00436 
00437       free_safe( tmpstr, (strlen( tmpstr ) + 1) );
00438 
00439     } else if( (expr->op == EXP_OP_SBIT_SEL) || (expr->op == EXP_OP_PARAM_SBIT) ) {
00440 
00441       if( (ESUPPL_IS_ROOT( expr->suppl ) == 0) &&
00442           (expr->parent->expr->op == EXP_OP_DIM) &&
00443           (expr->parent->expr->right == expr) ) {
00444         tmpstr = (char*)malloc_safe( 2 );
00445         rv = snprintf( tmpstr, 2, "[" );
00446         assert( rv < 2 );
00447       } else {
00448         unsigned int slen;
00449         pname  = scope_gen_printable( expr->name );
00450         slen   = strlen( pname ) + 2;
00451         tmpstr = (char*)malloc_safe( slen );
00452         rv = snprintf( tmpstr, slen, "%s[", pname );
00453         assert( rv < slen );
00454       }
00455 
00456       codegen_create_expr( code, code_depth, expr->line, tmpstr, left_code, left_code_depth,
00457                            expr->left, "]", NULL, 0, NULL, NULL );
00458 
00459       free_safe( tmpstr, (strlen( tmpstr ) + 1) );
00460       free_safe( pname, (strlen( pname ) + 1) );
00461 
00462     } else if( (expr->op == EXP_OP_MBIT_SEL) || (expr->op == EXP_OP_PARAM_MBIT) ) {
00463 
00464       if( (ESUPPL_IS_ROOT( expr->suppl ) == 0) &&
00465           (expr->parent->expr->op == EXP_OP_DIM) &&
00466           (expr->parent->expr->right == expr) ) {
00467         tmpstr = (char*)malloc_safe( 2 );
00468         rv = snprintf( tmpstr, 2, "[" );
00469         assert( rv < 2 );
00470       } else {
00471         unsigned int slen;
00472         pname  = scope_gen_printable( expr->name );
00473         slen   = strlen( pname ) + 2;
00474         tmpstr = (char*)malloc_safe( slen );
00475         rv = snprintf( tmpstr, slen, "%s[", pname );
00476         assert( rv < slen );
00477       }
00478 
00479       if( ESUPPL_WAS_SWAPPED( expr->suppl ) ) {
00480         codegen_create_expr( code, code_depth, expr->line, tmpstr,
00481                              right_code, right_code_depth, expr->right, ":",
00482                              left_code, left_code_depth, expr->left, "]" );
00483       } else {
00484         codegen_create_expr( code, code_depth, expr->line, tmpstr,
00485                              left_code, left_code_depth, expr->left, ":",
00486                              right_code, right_code_depth, expr->right, "]" );
00487       }
00488 
00489       free_safe( tmpstr, (strlen( tmpstr ) + 1) );
00490       free_safe( pname, (strlen( pname ) + 1) );
00491 
00492     } else if( (expr->op == EXP_OP_MBIT_POS) || (expr->op == EXP_OP_PARAM_MBIT_POS) ) {
00493 
00494       if( (ESUPPL_IS_ROOT( expr->suppl ) == 0) &&
00495           (expr->parent->expr->op == EXP_OP_DIM) &&
00496           (expr->parent->expr->right == expr) ) {
00497         tmpstr = (char*)malloc_safe( 2 );
00498         rv = snprintf( tmpstr, 2, "[" );
00499         assert( rv < 2 );
00500       } else {
00501         unsigned int slen;
00502         pname  = scope_gen_printable( expr->name );
00503         slen   = strlen( pname ) + 2;
00504         tmpstr = (char*)malloc_safe( slen );
00505         rv = snprintf( tmpstr, slen, "%s[", pname );
00506         assert( rv < slen );
00507       }
00508 
00509       codegen_create_expr( code, code_depth, expr->line, tmpstr, left_code, left_code_depth, expr->left, "+:",
00510                            right_code, right_code_depth, expr->right, "]" );
00511 
00512       free_safe( tmpstr, (strlen( tmpstr ) + 1) );
00513       free_safe( pname, (strlen( pname ) + 1) );
00514 
00515     } else if( (expr->op == EXP_OP_MBIT_NEG) || (expr->op == EXP_OP_PARAM_MBIT_NEG) ) {
00516 
00517       if( (ESUPPL_IS_ROOT( expr->suppl ) == 0) &&
00518           (expr->parent->expr->op == EXP_OP_DIM) &&
00519           (expr->parent->expr->right == expr) ) {
00520         tmpstr = (char*)malloc_safe( 2 );
00521         rv = snprintf( tmpstr, 2, "[" );
00522         assert( rv < 2 );
00523       } else {
00524         unsigned int slen;
00525         pname  = scope_gen_printable( expr->name );
00526         slen   = strlen( pname ) + 2;
00527         tmpstr = (char*)malloc_safe( slen );
00528         rv = snprintf( tmpstr, slen, "%s[", pname );
00529         assert( rv < slen );
00530       }
00531 
00532       codegen_create_expr( code, code_depth, expr->line, tmpstr, left_code, left_code_depth, expr->left, "-:",
00533                            right_code, right_code_depth, expr->right, "]" );
00534 
00535       free_safe( tmpstr, (strlen( tmpstr ) + 1) );
00536       free_safe( pname, (strlen( pname ) + 1) );
00537 
00538     } else if( (expr->op == EXP_OP_FUNC_CALL) || (expr->op == EXP_OP_TASK_CALL) ) {
00539 
00540       assert( expr->elem.funit != NULL );
00541 
00542       tfunit = expr->elem.funit;
00543       after = (char*)malloc_safe( strlen( tfunit->name ) + 1 );
00544       scope_extract_back( tfunit->name, after, user_msg );
00545       pname = scope_gen_printable( after );
00546       if( (expr->op == EXP_OP_TASK_CALL) && (expr->left == NULL) ) {
00547         *code       = (char**)malloc_safe( sizeof( char* ) );
00548         (*code)[0]  = strdup_safe( pname );
00549         *code_depth = 1;
00550       } else {
00551         unsigned int slen;
00552         tmpstr = (char*)malloc_safe( strlen( pname ) + 3 );
00553         slen   = strlen( pname ) + 3;
00554         rv = snprintf( tmpstr, slen, "%s( ", pname );
00555         assert( rv < slen );
00556         codegen_create_expr( code, code_depth, expr->line, tmpstr, left_code, left_code_depth, expr->left, " )", NULL, 0, NULL, NULL );
00557         free_safe( tmpstr, (strlen( tmpstr ) + 1) );
00558       }
00559       free_safe( after, (strlen( tfunit->name ) + 1) );
00560       free_safe( pname, (strlen( pname ) + 1) );
00561 
00562     } else if( expr->op == EXP_OP_TRIGGER ) {
00563       unsigned int slen;
00564       assert( expr->sig != NULL );
00565       pname  = scope_gen_printable( expr->name );
00566       slen   = strlen( pname ) + 3;
00567       tmpstr = (char*)malloc_safe( slen );
00568       rv = snprintf( tmpstr, slen, "->%s", pname );
00569       assert( rv < slen );
00570 
00571       *code       = (char**)malloc_safe( sizeof( char* ) );
00572       (*code)[0]  = strdup_safe( tmpstr );
00573       *code_depth = 1;
00574 
00575       free_safe( tmpstr, (strlen( tmpstr ) + 1) );
00576       free_safe( pname, (strlen( pname ) + 1) );
00577 
00578     } else if( expr->op == EXP_OP_DISABLE ) {
00579       unsigned int slen;
00580       assert( expr->elem.funit != NULL );
00581       pname  = scope_gen_printable( expr->name );
00582       slen   = strlen( pname ) + 9;
00583       tmpstr = (char*)malloc_safe( slen );
00584       rv = snprintf( tmpstr, slen, "disable %s", pname );
00585       assert( rv < slen );
00586 
00587       *code       = (char**)malloc_safe( sizeof( char* ) );
00588       (*code)[0]  = strdup_safe( tmpstr );
00589       *code_depth = 1;
00590 
00591       free_safe( tmpstr, (strlen( tmpstr ) + 1) );
00592       free_safe( pname, (strlen( pname ) + 1) );
00593 
00594     } else if( expr->op == EXP_OP_DEFAULT ) {
00595 
00596       *code       = (char**)malloc_safe( sizeof( char* ) );
00597       (*code)[0]  = strdup_safe( "default :" );
00598       *code_depth = 1;
00599 
00600     } else if( expr->op == EXP_OP_SLIST ) {
00601 
00602       *code       = (char**)malloc_safe( sizeof( char* ) );
00603       (*code)[0]  = strdup_safe( "@*" );
00604       *code_depth = 1;
00605 
00606     } else if( expr->op == EXP_OP_ALWAYS_COMB ) {
00607  
00608       *code       = (char**)malloc_safe( sizeof( char* ) );
00609       (*code)[0]  = strdup_safe( "always_comb" );
00610       *code_depth = 1;
00611 
00612     } else if( expr->op == EXP_OP_ALWAYS_LATCH ) {
00613 
00614       *code       = (char**)malloc_safe( sizeof( char* ) );
00615       (*code)[0]  = strdup_safe( "always_latch" );
00616       *code_depth = 1;
00617 
00618     } else if( expr->op == EXP_OP_STIME ) {
00619    
00620       *code       = (char**)malloc_safe( sizeof( char* ) );
00621       (*code)[0]  = strdup_safe( "$time" );
00622       *code_depth = 1;
00623 
00624     } else if( (expr->op == EXP_OP_SRANDOM) && (expr->left == NULL) ) {
00625 
00626       *code       = (char**)malloc_safe( sizeof( char* ) );
00627       (*code)[0]  = strdup_safe( "$random" );
00628       *code_depth = 1;
00629 
00630     } else if( (expr->op == EXP_OP_SURANDOM) && (expr->left == NULL) ) {
00631  
00632       *code       = (char**)malloc_safe( sizeof( char* ) );
00633       (*code)[0]  = strdup_safe( "$urandom" );
00634       *code_depth = 1;
00635 
00636     } else {
00637 
00638       if( expr->suppl.part.parenthesis ) {
00639         before = strdup_safe( "(" );
00640         after  = strdup_safe( ")" );
00641       } else {
00642         before = NULL;
00643         after  = NULL;
00644       }
00645 
00646       switch( expr->op ) {
00647         case EXP_OP_XOR      :
00648           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " ^ ",
00649                                right_code, right_code_depth, expr->right, after );
00650           break;
00651         case EXP_OP_XOR_A    :
00652           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " ^= ",
00653                                right_code, right_code_depth, expr->right, after );
00654           break;
00655         case EXP_OP_MULTIPLY :
00656           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " * ",
00657                                right_code, right_code_depth, expr->right, after );
00658           break;
00659         case EXP_OP_MLT_A    :
00660           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " *= ",
00661                                right_code, right_code_depth, expr->right, after );
00662           break;
00663         case EXP_OP_DIVIDE   :
00664           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " / ",
00665                                right_code, right_code_depth, expr->right, after );
00666           break;
00667         case EXP_OP_DIV_A    :
00668           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " /= ",
00669                                right_code, right_code_depth, expr->right, after );
00670           break;
00671         case EXP_OP_MOD      :
00672           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " % ",
00673                                right_code, right_code_depth, expr->right, after );
00674           break;
00675         case EXP_OP_MOD_A    :
00676           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " %= ",
00677                                right_code, right_code_depth, expr->right, after );
00678           break;
00679         case EXP_OP_ADD      :
00680           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " + ",
00681                                right_code, right_code_depth, expr->right, after );
00682           break;
00683         case EXP_OP_ADD_A    :
00684           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " += ",
00685                                right_code, right_code_depth, expr->right, after );
00686           break;
00687         case EXP_OP_SUBTRACT :
00688           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " - ",
00689                                right_code, right_code_depth, expr->right, after );
00690           break;
00691         case EXP_OP_SUB_A    :
00692           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " -= ",
00693                                right_code, right_code_depth, expr->right, after );
00694           break;
00695         case EXP_OP_EXPONENT :
00696           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " ** ",
00697                                right_code, right_code_depth, expr->right, after );
00698           break;
00699         case EXP_OP_AND      :
00700           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " & ",
00701                                right_code, right_code_depth, expr->right, after );
00702           break;
00703         case EXP_OP_AND_A    :
00704           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " &= ",
00705                                right_code, right_code_depth, expr->right, after );
00706           break;
00707         case EXP_OP_OR       :
00708           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " | ",
00709                                right_code, right_code_depth, expr->right, after );
00710           break;
00711         case EXP_OP_OR_A     :
00712           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " |= ",
00713                                right_code, right_code_depth, expr->right, after );
00714           break;
00715         case EXP_OP_NAND     :
00716           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " ~& ",
00717                                right_code, right_code_depth, expr->right, after );
00718           break;
00719         case EXP_OP_NOR      :
00720           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " ~| ",
00721                                right_code, right_code_depth, expr->right, after );
00722           break;
00723         case EXP_OP_NXOR     :
00724           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " ~^ ",
00725                                right_code, right_code_depth, expr->right, after );
00726           break;
00727         case EXP_OP_LT       :
00728           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " < ",
00729                                right_code, right_code_depth, expr->right, after );
00730           break;
00731         case EXP_OP_GT       :
00732           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " > ",
00733                                right_code, right_code_depth, expr->right, after );
00734           break;
00735         case EXP_OP_LSHIFT   :
00736           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " << ",
00737                                right_code, right_code_depth, expr->right, after );
00738           break;
00739         case EXP_OP_LS_A     :
00740           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " <<= ",
00741                                right_code, right_code_depth, expr->right, after );
00742           break;
00743         case EXP_OP_ALSHIFT  :
00744           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " <<< ",
00745                                right_code, right_code_depth, expr->right, after );
00746           break;
00747         case EXP_OP_ALS_A    :
00748           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " <<<= ",
00749                                right_code, right_code_depth, expr->right, after );
00750           break;
00751         case EXP_OP_RSHIFT   :
00752           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " >> ",
00753                                right_code, right_code_depth, expr->right, after );
00754           break;
00755         case EXP_OP_RS_A     :
00756           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " >>= ",
00757                                right_code, right_code_depth, expr->right, after );
00758           break;
00759         case EXP_OP_ARSHIFT  :
00760           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " >>> ",
00761                                right_code, right_code_depth, expr->right, after );
00762           break;
00763         case EXP_OP_ARS_A    :
00764           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " >>>= ",
00765                                right_code, right_code_depth, expr->right, after );
00766           break;
00767         case EXP_OP_EQ       :
00768           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " == ",
00769                                right_code, right_code_depth, expr->right, after );
00770           break;
00771         case EXP_OP_CEQ      :
00772           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " === ",
00773                                right_code, right_code_depth, expr->right, after );
00774           break;
00775         case EXP_OP_LE       :
00776           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " <= ",
00777                                right_code, right_code_depth, expr->right, after );
00778           break;
00779         case EXP_OP_GE       :
00780           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " >= ",
00781                                right_code, right_code_depth, expr->right, after );
00782           break;
00783         case EXP_OP_NE       :
00784           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " != ",
00785                                right_code, right_code_depth, expr->right, after );
00786           break;
00787         case EXP_OP_CNE      :
00788           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " !== ",
00789                                right_code, right_code_depth, expr->right, after );
00790           break;
00791         case EXP_OP_LOR      :
00792           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " || ",
00793                                right_code, right_code_depth, expr->right, after );
00794           break;
00795         case EXP_OP_LAND     :
00796           codegen_create_expr( code, code_depth, expr->line, before, left_code, left_code_depth, expr->left, " && ",
00797                                right_code, right_code_depth, expr->right, after );
00798           break;
00799         case EXP_OP_COND     :
00800           codegen_create_expr( code, code_depth, expr->line, NULL, left_code, left_code_depth, expr->left, " ? ",
00801                                right_code, right_code_depth, expr->right, NULL );
00802           break;
00803         case EXP_OP_COND_SEL :
00804           codegen_create_expr( code, code_depth, expr->line, NULL, left_code, left_code_depth, expr->left, " : ",
00805                                right_code, right_code_depth, expr->right, NULL );
00806           break;
00807         case EXP_OP_UINV     :
00808           codegen_create_expr( code, code_depth, expr->line, (expr->suppl.part.parenthesis ? "(~" : "~"), right_code, right_code_depth, expr->right, after,
00809                                NULL, 0, NULL, NULL );
00810           break;
00811         case EXP_OP_UAND     :
00812           codegen_create_expr( code, code_depth, expr->line, (expr->suppl.part.parenthesis ? "(&" : "&"), right_code, right_code_depth, expr->right, after,
00813                                NULL, 0, NULL, NULL );
00814           break;
00815         case EXP_OP_UNOT     :
00816           codegen_create_expr( code, code_depth, expr->line, (expr->suppl.part.parenthesis ? "(!" : "!"), right_code, right_code_depth, expr->right, after,
00817                                NULL, 0, NULL, NULL );
00818           break;
00819         case EXP_OP_UOR      :
00820           codegen_create_expr( code, code_depth, expr->line, (expr->suppl.part.parenthesis ? "(|" : "|"), right_code, right_code_depth, expr->right, after,
00821                                NULL, 0, NULL, NULL );
00822           break;
00823         case EXP_OP_UXOR     :
00824           codegen_create_expr( code, code_depth, expr->line, (expr->suppl.part.parenthesis ? "(^" : "^"), right_code, right_code_depth, expr->right, after,
00825                                NULL, 0, NULL, NULL );
00826           break;
00827         case EXP_OP_UNAND    :
00828           codegen_create_expr( code, code_depth, expr->line, (expr->suppl.part.parenthesis ? "(~&" : "~&"), right_code, right_code_depth, expr->right, after,
00829                                NULL, 0, NULL, NULL );
00830           break;
00831         case EXP_OP_UNOR     :
00832           codegen_create_expr( code, code_depth, expr->line, (expr->suppl.part.parenthesis ? "(~|" : "~|"), right_code, right_code_depth, expr->right, after,
00833                                NULL, 0, NULL, NULL );
00834           break;
00835         case EXP_OP_UNXOR    :
00836           codegen_create_expr( code, code_depth, expr->line, (expr->suppl.part.parenthesis ? "(~^" : "~^"), right_code, right_code_depth, expr->right, after,
00837                                NULL, 0, NULL, NULL );
00838           break;
00839         case EXP_OP_EXPAND   :
00840           codegen_create_expr( code, code_depth, expr->line, "{", left_code, left_code_depth, expr->left, "{",
00841                                right_code, right_code_depth, expr->right, "}}" );
00842           break;
00843         case EXP_OP_LIST     :
00844         case EXP_OP_PLIST    :
00845           codegen_create_expr( code, code_depth, expr->line, NULL, left_code, left_code_depth, expr->left, ", ",
00846                                right_code, right_code_depth, expr->right, NULL );
00847           break;
00848         case EXP_OP_CONCAT   :
00849           codegen_create_expr( code, code_depth, expr->line, "{", right_code, right_code_depth, expr->right, "}",
00850                                NULL, 0, NULL, NULL );
00851           break;
00852         case EXP_OP_PEDGE    :
00853           if( (ESUPPL_IS_ROOT( expr->suppl ) == 1)       ||
00854               (expr->parent->expr->op == EXP_OP_RPT_DLY) || 
00855               (expr->parent->expr->op == EXP_OP_DLY_OP) ) {
00856             codegen_create_expr( code, code_depth, expr->line, "@(posedge ", right_code, right_code_depth, expr->right, ")",
00857                                  NULL, 0, NULL, NULL );
00858           } else {
00859             codegen_create_expr( code, code_depth, expr->line, "posedge ", right_code, right_code_depth, expr->right, NULL,
00860                                  NULL, 0, NULL, NULL );
00861           }
00862           break;
00863         case EXP_OP_NEDGE    :
00864           if( (ESUPPL_IS_ROOT( expr->suppl ) == 1)       ||
00865               (expr->parent->expr->op == EXP_OP_RPT_DLY) ||
00866               (expr->parent->expr->op == EXP_OP_DLY_OP) ) {
00867             codegen_create_expr( code, code_depth, expr->line, "@(negedge ", right_code, right_code_depth, expr->right, ")",
00868                                  NULL, 0, NULL, NULL );
00869           } else {
00870             codegen_create_expr( code, code_depth, expr->line, "negedge ", right_code, right_code_depth, expr->right, NULL,
00871                                  NULL, 0, NULL, NULL );
00872           }
00873           break;
00874         case EXP_OP_AEDGE    :
00875           if( (ESUPPL_IS_ROOT( expr->suppl ) == 1)       ||
00876               (expr->parent->expr->op == EXP_OP_RPT_DLY) ||
00877               (expr->parent->expr->op == EXP_OP_DLY_OP) ) {
00878             codegen_create_expr( code, code_depth, expr->line, "@(", right_code, right_code_depth, expr->right, ")",
00879                                  NULL, 0, NULL, NULL );
00880           } else {
00881             codegen_create_expr( code, code_depth, expr->line, NULL, right_code, right_code_depth, expr->right, NULL,
00882                                  NULL, 0, NULL, NULL );
00883           }
00884           break;
00885         case EXP_OP_EOR      :
00886           if( (ESUPPL_IS_ROOT( expr->suppl ) == 1)       ||
00887               (expr->parent->expr->op == EXP_OP_RPT_DLY) ||
00888               (expr->parent->expr->op == EXP_OP_DLY_OP) ) {
00889             codegen_create_expr( code, code_depth, expr->line, "@(", left_code, left_code_depth, expr->left, " or ",
00890                                  right_code, right_code_depth, expr->right, ")" );
00891           } else {
00892             codegen_create_expr( code, code_depth, expr->line, NULL, left_code, left_code_depth, expr->left, " or ",
00893                                  right_code, right_code_depth, expr->right, NULL );
00894           }
00895           break;
00896         case EXP_OP_CASE     :
00897           codegen_create_expr( code, code_depth, expr->line, "case( ", left_code, left_code_depth, expr->left, " ) ",
00898                                right_code, right_code_depth, expr->right, " :" );
00899           break;
00900         case EXP_OP_CASEX    :
00901           codegen_create_expr( code, code_depth, expr->line, "casex( ", left_code, left_code_depth, expr->left, " ) ",
00902                                right_code, right_code_depth, expr->right, " :" );
00903           break;
00904         case EXP_OP_CASEZ    :
00905           codegen_create_expr( code, code_depth, expr->line, "casez( ", left_code, left_code_depth, expr->left, " ) ",
00906                                right_code, right_code_depth, expr->right, " :" );
00907           break;
00908         case EXP_OP_DELAY    :
00909           codegen_create_expr( code, code_depth, expr->line, "#(", right_code, right_code_depth, expr->right, ")",
00910                                NULL, 0, NULL, NULL );
00911           break;
00912         case EXP_OP_ASSIGN   :
00913           codegen_create_expr( code, code_depth, expr->line, "assign ", left_code, left_code_depth, expr->left, " = ",
00914                                right_code, right_code_depth, expr->right, NULL );
00915           break;
00916         case EXP_OP_DASSIGN  :
00917         case EXP_OP_RASSIGN  :
00918         case EXP_OP_BASSIGN  :
00919           codegen_create_expr( code, code_depth, expr->line, NULL, left_code, left_code_depth, expr->left, " = ",
00920                                right_code, right_code_depth, expr->right, NULL );
00921           break;
00922         case EXP_OP_NASSIGN  :
00923           codegen_create_expr( code, code_depth, expr->line, NULL, left_code, left_code_depth, expr->left, " <= ",
00924                                right_code, right_code_depth, expr->right, NULL );
00925           break;
00926         case EXP_OP_PASSIGN  :
00927         case EXP_OP_SASSIGN  :
00928           *code            = right_code;
00929           *code_depth      = right_code_depth;
00930           right_code_depth = 0;
00931           break;
00932         case EXP_OP_DLY_ASSIGN :
00933           codegen_create_expr( code, code_depth, expr->line, NULL, left_code, left_code_depth, expr->left, " = ",
00934                                right_code, right_code_depth, expr->right, NULL );
00935           break;
00936         case EXP_OP_DLY_OP   :
00937         case EXP_OP_RPT_DLY  :
00938           codegen_create_expr( code, code_depth, expr->line, NULL, left_code, left_code_depth, expr->left, " ",
00939                                right_code, right_code_depth, expr->right, NULL );
00940           break;
00941         case EXP_OP_IF       :
00942           codegen_create_expr( code, code_depth, expr->line, "if( ", right_code, right_code_depth, expr->right, " )",
00943                                NULL, 0, NULL, NULL );
00944           break;
00945         case EXP_OP_REPEAT   :
00946           codegen_create_expr( code, code_depth, expr->line, "repeat( ", right_code, right_code_depth, expr->right, " )",
00947                                NULL, 0, NULL, NULL );
00948           break;
00949         case EXP_OP_WHILE    :
00950           codegen_create_expr( code, code_depth, expr->line, "while( ", right_code, right_code_depth, expr->right, " )",
00951                                NULL, 0, NULL, NULL );
00952           break;
00953         case EXP_OP_WAIT     :
00954           codegen_create_expr( code, code_depth, expr->line, "wait( ", right_code, right_code_depth, expr->right, " )",
00955                                NULL, 0, NULL, NULL );
00956           break;
00957         case EXP_OP_NEGATE   :
00958           codegen_create_expr( code, code_depth, expr->line, "-", right_code, right_code_depth, expr->right, NULL,
00959                                NULL, 0, NULL, NULL );
00960           break;
00961         case EXP_OP_IINC     :
00962           codegen_create_expr( code, code_depth, expr->line, "++", left_code, left_code_depth, expr->left, NULL,
00963                                NULL, 0, NULL, NULL );
00964           break;
00965         case EXP_OP_PINC     :
00966           codegen_create_expr( code, code_depth, expr->line, NULL, left_code, left_code_depth, expr->left, "++",
00967                                NULL, 0, NULL, NULL );
00968           break;
00969         case EXP_OP_IDEC     :
00970           codegen_create_expr( code, code_depth, expr->line, "--", left_code, left_code_depth, expr->left, NULL,
00971                                NULL, 0, NULL, NULL );
00972           break;
00973         case EXP_OP_PDEC     :
00974           codegen_create_expr( code, code_depth, expr->line, NULL, left_code, left_code_depth, expr->left, "--",
00975                                NULL, 0, NULL, NULL );
00976           break;
00977         case EXP_OP_DIM      :
00978           codegen_create_expr( code, code_depth, expr->line, NULL, left_code, left_code_depth, expr->left, "",
00979                                right_code, right_code_depth, expr->right, NULL );
00980           break;
00981         case EXP_OP_SSIGNED  :
00982           codegen_create_expr( code, code_depth, expr->line, "$signed( ", left_code, left_code_depth, expr->left, " )",
00983                                NULL, 0, NULL, NULL );
00984           break;
00985         case EXP_OP_SUNSIGNED  :
00986           codegen_create_expr( code, code_depth, expr->line, "$unsigned( ", left_code, left_code_depth, expr->left, " )",
00987                                NULL, 0, NULL, NULL );
00988           break;
00989         case EXP_OP_SCLOG2 :
00990           codegen_create_expr( code, code_depth, expr->line, "$clog2( ", left_code, left_code_depth, expr->left, " )",
00991                                NULL, 0, NULL, NULL );
00992           break;
00993         case EXP_OP_SRANDOM  :
00994           codegen_create_expr( code, code_depth, expr->line, "$random( ", left_code, left_code_depth, expr->left, " )",
00995                                NULL, 0, NULL, NULL );
00996           break;
00997         case EXP_OP_SURANDOM :
00998           codegen_create_expr( code, code_depth, expr->line, "$urandom( ", left_code, left_code_depth, expr->left, " )",
00999                                NULL, 0, NULL, NULL );
01000           break;
01001         case EXP_OP_SURAND_RANGE :
01002           codegen_create_expr( code, code_depth, expr->line, "$urandom_range( ", left_code, left_code_depth, expr->left, " )",
01003                                NULL, 0, NULL, NULL );
01004           break;
01005         case EXP_OP_SSRANDOM :
01006           codegen_create_expr( code, code_depth, expr->line, "$srandom( ", left_code, left_code_depth, expr->left, " )",
01007                                NULL, 0, NULL, NULL );
01008           break;
01009         case EXP_OP_SB2R :
01010           codegen_create_expr( code, code_depth, expr->line, "$bitstoreal( ", left_code, left_code_depth, expr->left, " )",
01011                                NULL, 0, NULL, NULL );
01012           break;
01013         case EXP_OP_SR2B :
01014           codegen_create_expr( code, code_depth, expr->line, "$realtobits( ", left_code, left_code_depth, expr->left, " )",
01015                                NULL, 0, NULL, NULL );
01016           break;
01017         case EXP_OP_SI2R :
01018           codegen_create_expr( code, code_depth, expr->line, "$itor( ", left_code, left_code_depth, expr->left, " )",
01019                                NULL, 0, NULL, NULL );
01020           break;
01021         case EXP_OP_SR2I :
01022           codegen_create_expr( code, code_depth, expr->line, "$rtoi( ", left_code, left_code_depth, expr->left, " )",
01023                                NULL, 0, NULL, NULL );
01024           break;
01025         case EXP_OP_SSR2B :
01026           codegen_create_expr( code, code_depth, expr->line, "$shortrealtobits( ", left_code, left_code_depth, expr->left, " )",
01027                                NULL, 0, NULL, NULL );
01028           break;
01029         case EXP_OP_SB2SR :
01030           codegen_create_expr( code, code_depth, expr->line, "$bitstoshortreal( ", left_code, left_code_depth, expr->left, " )",
01031                                NULL, 0, NULL, NULL );
01032           break;
01033         case EXP_OP_STESTARGS :
01034           codegen_create_expr( code, code_depth, expr->line, "$test$plusargs( ", left_code, left_code_depth, expr->left, " )",
01035                                NULL, 0, NULL, NULL );
01036           break;
01037         case EXP_OP_SVALARGS :
01038           codegen_create_expr( code, code_depth, expr->line, "$value$plusargs( ", left_code, left_code_depth, expr->left, " )",
01039                                NULL, 0, NULL, NULL );
01040           break;
01041         default:  break;
01042       }
01043 
01044       /* Deallocate before and after strings */
01045       free_safe( before, (strlen( before ) + 1) );
01046       free_safe( after, (strlen( after ) + 1) );
01047 
01048     }
01049 
01050     if( right_code_depth > 0 ) {
01051       free_safe( right_code, (sizeof( char* ) * right_code_depth) );
01052     }
01053 
01054     if( left_code_depth > 0 ) {
01055       free_safe( left_code, (sizeof( char* ) * left_code_depth) );
01056     }
01057 
01058   }
01059 
01060 }

Generated on Sun Nov 21 00:55:37 2010 for Covered by  doxygen 1.6.3