HDLRuby 2.11.4 → 2.11.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/hruby_sim/hruby_rcsim_build.c +87 -48
- data/ext/hruby_sim/hruby_sim.h +67 -1
- data/ext/hruby_sim/hruby_sim_calc.c +211 -28
- data/ext/hruby_sim/hruby_sim_core.c +140 -52
- data/ext/hruby_sim/hruby_sim_mute.c +65 -0
- data/ext/hruby_sim/hruby_sim_stack_calc.c +10 -0
- data/ext/hruby_sim/hruby_sim_tree_calc.c +36 -9
- data/ext/hruby_sim/hruby_sim_vcd.c +41 -23
- data/lib/HDLRuby/hdr_samples/arith_bench.rb +92 -0
- data/lib/HDLRuby/hdr_samples/constant_prop_bench.rb +58 -0
- data/lib/HDLRuby/hdrcc.rb +15 -6
- data/lib/HDLRuby/hruby_bstr.rb +15 -3
- data/lib/HDLRuby/hruby_high.rb +8 -4
- data/lib/HDLRuby/hruby_low.rb +14 -5
- data/lib/HDLRuby/hruby_low2c.rb +184 -68
- data/lib/HDLRuby/hruby_low_without_connection.rb +6 -2
- data/lib/HDLRuby/hruby_rcsim.rb +25 -15
- data/lib/HDLRuby/hruby_rsim.rb +201 -85
- data/lib/HDLRuby/hruby_rsim_mute.rb +35 -0
- data/lib/HDLRuby/hruby_rsim_vcd.rb +168 -12
- data/lib/HDLRuby/hruby_values.rb +19 -2
- data/lib/HDLRuby/hruby_verilog.rb +67 -17
- data/lib/HDLRuby/std/fsm.rb +3 -3
- data/lib/HDLRuby/version.rb +1 -1
- metadata +6 -2
| @@ -35,6 +35,15 @@ static List touched_signals_seq = &touched_signals_seq_content; | |
| 35 35 | 
             
            static ListS activate_codes_content = { NULL, NULL }; 
         | 
| 36 36 | 
             
            static List activate_codes = &activate_codes_content;
         | 
| 37 37 |  | 
| 38 | 
            +
             | 
| 39 | 
            +
            /** The number of behavior to run for initialization (not the timed ones!). */
         | 
| 40 | 
            +
            static int num_init_behaviors = 0;
         | 
| 41 | 
            +
            /** The capacity of teh behavior to run for initialization. */
         | 
| 42 | 
            +
            static int cap_init_behaviors = 0;
         | 
| 43 | 
            +
            /** The behaviors to run for initialization (not the timed ones!). */
         | 
| 44 | 
            +
            static Behavior* init_behaviors = 0;
         | 
| 45 | 
            +
             | 
| 46 | 
            +
             | 
| 38 47 | 
             
            /** The number of timed behaviors. */
         | 
| 39 48 | 
             
            static int num_timed_behaviors = 0;
         | 
| 40 49 | 
             
            /** The capacity of the timed behaviors. */
         | 
| @@ -62,7 +71,8 @@ static pthread_cond_t hruby_beh_cond = PTHREAD_COND_INITIALIZER; | |
| 62 71 | 
             
            static pthread_cond_t hruby_sim_cond = PTHREAD_COND_INITIALIZER;
         | 
| 63 72 |  | 
| 64 73 | 
             
            /** Flags for the simulation. */
         | 
| 65 | 
            -
            static int  | 
| 74 | 
            +
            static int sim_single_flag = 0; /* Run in single timed behavior mode. */
         | 
| 75 | 
            +
            static int sim_end_flag = 0;    /* Ending the simulation. */
         | 
| 66 76 |  | 
| 67 77 | 
             
            /** Adds a timed behavior for processing. 
         | 
| 68 78 | 
             
             *  @param behavior the timed behavior to register */
         | 
| @@ -87,12 +97,33 @@ void register_timed_behavior(Behavior behavior) { | |
| 87 97 | 
             
            }
         | 
| 88 98 |  | 
| 89 99 |  | 
| 100 | 
            +
            /** Adds a behavior for initialization (not timed!).
         | 
| 101 | 
            +
             *  @param beh the behavior to register. */
         | 
| 102 | 
            +
            void register_init_behavior(Behavior beh) {
         | 
| 103 | 
            +
                if (num_init_behaviors == cap_init_behaviors) {
         | 
| 104 | 
            +
                    if (cap_init_behaviors == 0) {
         | 
| 105 | 
            +
                        /* Need to create the array containing the behaviors. */
         | 
| 106 | 
            +
                        cap_init_behaviors = 100;
         | 
| 107 | 
            +
                        init_behaviors = calloc(cap_init_behaviors,sizeof(Behavior));
         | 
| 108 | 
            +
                    } else {
         | 
| 109 | 
            +
                        /* Need to increase the capacity. */
         | 
| 110 | 
            +
                        Behavior* new_behs = calloc(cap_init_behaviors*2,sizeof(Behavior));
         | 
| 111 | 
            +
                        memcpy(new_behs,init_behaviors,sizeof(Behavior[cap_init_behaviors]));
         | 
| 112 | 
            +
                        cap_init_behaviors *= 2;
         | 
| 113 | 
            +
                        init_behaviors=new_behs;
         | 
| 114 | 
            +
                    }
         | 
| 115 | 
            +
                }
         | 
| 116 | 
            +
                /* Add the behavior. */
         | 
| 117 | 
            +
                init_behaviors[num_init_behaviors++] = beh;
         | 
| 118 | 
            +
            }
         | 
| 119 | 
            +
             | 
| 120 | 
            +
             | 
| 90 121 | 
             
            /** Adds a signal for global processing. 
         | 
| 91 122 | 
             
             *  @param signal the signal to register  */
         | 
| 92 123 | 
             
            void register_signal(SignalI signal) {
         | 
| 93 124 | 
             
                if (num_all_signals == cap_all_signals) {
         | 
| 94 125 | 
             
                    if (cap_all_signals == 0) {
         | 
| 95 | 
            -
                        /* Need to create the array containing the  | 
| 126 | 
            +
                        /* Need to create the array containing the signals. */
         | 
| 96 127 | 
             
                        cap_all_signals = 100;
         | 
| 97 128 | 
             
                        all_signals = calloc(cap_all_signals,sizeof(SignalI));
         | 
| 98 129 | 
             
                    } else {
         | 
| @@ -109,6 +140,24 @@ void register_signal(SignalI signal) { | |
| 109 140 | 
             
            }
         | 
| 110 141 |  | 
| 111 142 |  | 
| 143 | 
            +
             | 
| 144 | 
            +
            /** Initial run of the behaviors to init. */
         | 
| 145 | 
            +
            void run_init_behaviors() {
         | 
| 146 | 
            +
                int i;
         | 
| 147 | 
            +
                for(i = 0; i<num_init_behaviors; ++i) {
         | 
| 148 | 
            +
                    Behavior beh = init_behaviors[i];
         | 
| 149 | 
            +
            #ifdef RCSIM
         | 
| 150 | 
            +
                    // printf("Going to initialize behavior=%p with block=%p\n",beh,beh->block);fflush(stdout);
         | 
| 151 | 
            +
                    execute_statement((Statement)(beh->block),0,beh);
         | 
| 152 | 
            +
            #else
         | 
| 153 | 
            +
                    beh->block->function();
         | 
| 154 | 
            +
            #endif
         | 
| 155 | 
            +
                }
         | 
| 156 | 
            +
            }
         | 
| 157 | 
            +
             | 
| 158 | 
            +
             | 
| 159 | 
            +
             | 
| 160 | 
            +
             | 
| 112 161 | 
             
            /** Recursively update the signals until no (untimed) behavior are
         | 
| 113 162 | 
             
             *  activated. */
         | 
| 114 163 | 
             
            void hruby_sim_update_signals() {
         | 
| @@ -303,6 +352,8 @@ void hruby_sim_advance_time() { | |
| 303 352 | 
             
                    if (timed_behaviors[i]->timed == 1)
         | 
| 304 353 | 
             
                        if (beh_time < next_time) next_time = beh_time;
         | 
| 305 354 | 
             
                }
         | 
| 355 | 
            +
                /* Mark again all the signals as fading. */
         | 
| 356 | 
            +
                for(i=0; i<num_all_signals; ++i) all_signals[i]->fading = 1;
         | 
| 306 357 | 
             
                // printf("hruby_sim_time=%llu next_time=%llu\n",hruby_sim_time,next_time);
         | 
| 307 358 | 
             
                /* Sets the new activation time. */
         | 
| 308 359 | 
             
                hruby_sim_time = next_time;
         | 
| @@ -422,6 +473,20 @@ void* behavior_run(void* arg) { | |
| 422 473 | 
             
                pthread_exit(NULL);
         | 
| 423 474 | 
             
            }
         | 
| 424 475 |  | 
| 476 | 
            +
            /** Starts a signle timed behavior to run without the multi-threaded engine. */
         | 
| 477 | 
            +
            void hruby_sim_start_single_timed_behavior() {
         | 
| 478 | 
            +
                // printf("hruby_sim_start_single_timed_behaviors\n");fflush(stdout);
         | 
| 479 | 
            +
                /* Set in mono-thread mode. */
         | 
| 480 | 
            +
                sim_single_flag = 1;
         | 
| 481 | 
            +
                Behavior behavior = timed_behaviors[0];
         | 
| 482 | 
            +
                /* Simply run the timed behavior. */
         | 
| 483 | 
            +
            #ifdef RCSIM
         | 
| 484 | 
            +
                    execute_statement((Statement)(behavior->block),0,behavior);
         | 
| 485 | 
            +
            #else
         | 
| 486 | 
            +
                    behavior->block->function();
         | 
| 487 | 
            +
            #endif
         | 
| 488 | 
            +
            }
         | 
| 489 | 
            +
             | 
| 425 490 |  | 
| 426 491 | 
             
            /** Starts the timed behaviors.
         | 
| 427 492 | 
             
             *  @note create a thread per timed behavior. */
         | 
| @@ -473,37 +538,51 @@ void hruby_sim_core(char* name, void (*init_vizualizer)(char*), | |
| 473 538 | 
             
                /* Initialize the time to 0. */
         | 
| 474 539 | 
             
                hruby_sim_time = 0;
         | 
| 475 540 |  | 
| 476 | 
            -
                 | 
| 477 | 
            -
             | 
| 478 | 
            -
                // /* Activate the timed behavior that are on time. */
         | 
| 479 | 
            -
                // hruby_sim_activate_behaviors_on_time();
         | 
| 480 | 
            -
             | 
| 481 | 
            -
                /* Run while there are active behaviors and the time limit is not 
         | 
| 482 | 
            -
                 * reached */
         | 
| 483 | 
            -
                while(hruby_sim_time<limit) {
         | 
| 484 | 
            -
                    int i;
         | 
| 485 | 
            -
                    // printf("num_active_behaviors = %d\n",num_active_behaviors);
         | 
| 486 | 
            -
                    /* Wait for the active timed behaviors to perform their computations. */
         | 
| 487 | 
            -
                    hruby_sim_wait_behaviors();
         | 
| 488 | 
            -
                    /* Update the signal values (recursively executing blocks locked
         | 
| 489 | 
            -
                     * on the signals). */
         | 
| 541 | 
            +
                if (num_timed_behaviors == 1) {
         | 
| 542 | 
            +
                    /* Initialize and touch all the signals. */
         | 
| 490 543 | 
             
                    hruby_sim_update_signals(); 
         | 
| 491 | 
            -
                     | 
| 492 | 
            -
             | 
| 493 | 
            -
             | 
| 494 | 
            -
                     | 
| 495 | 
            -
             | 
| 496 | 
            -
                     | 
| 497 | 
            -
                    /*  | 
| 498 | 
            -
                     | 
| 544 | 
            +
                    // each_all_signal(&touch_signal);
         | 
| 545 | 
            +
                    run_init_behaviors();
         | 
| 546 | 
            +
                    /* Only one timed behavior, no need of the multi-threaded engine. */
         | 
| 547 | 
            +
                    hruby_sim_start_single_timed_behavior();
         | 
| 548 | 
            +
                } else {
         | 
| 549 | 
            +
                    /* Use the multi-threaded engine. */
         | 
| 550 | 
            +
                    /* Initialize and touch all the signals. */
         | 
| 551 | 
            +
                    hruby_sim_update_signals(); 
         | 
| 552 | 
            +
                    // each_all_signal(&touch_signal);
         | 
| 553 | 
            +
                    run_init_behaviors();
         | 
| 554 | 
            +
                    /* Start all the timed behaviors. */
         | 
| 555 | 
            +
                    hruby_sim_start_timed_behaviors();
         | 
| 556 | 
            +
                    // /* Activate the timed behavior that are on time. */
         | 
| 557 | 
            +
                    // hruby_sim_activate_behaviors_on_time();
         | 
| 558 | 
            +
             | 
| 559 | 
            +
                    /* Run while there are active behaviors and the time limit is not 
         | 
| 560 | 
            +
                     * reached */
         | 
| 561 | 
            +
                    while(hruby_sim_time<limit) {
         | 
| 562 | 
            +
                        int i;
         | 
| 563 | 
            +
                        // printf("num_active_behaviors = %d\n",num_active_behaviors);
         | 
| 564 | 
            +
                        /* Wait for the active timed behaviors to perform their computations. */
         | 
| 565 | 
            +
                        hruby_sim_wait_behaviors();
         | 
| 566 | 
            +
                        /* Update the signal values (recursively executing blocks locked
         | 
| 567 | 
            +
                         * on the signals). */
         | 
| 568 | 
            +
                        hruby_sim_update_signals(); 
         | 
| 569 | 
            +
                        if (hruby_sim_time == 0) {
         | 
| 570 | 
            +
                            /* Initially touch all the signals. */
         | 
| 571 | 
            +
                            each_all_signal(&touch_signal);
         | 
| 572 | 
            +
                        }
         | 
| 573 | 
            +
                        // printf("num_run_behavior=%d\n",num_run_behaviors);
         | 
| 574 | 
            +
                        if (num_run_behaviors <= 0) break;
         | 
| 575 | 
            +
                        /* Advance time to next timestep. */
         | 
| 576 | 
            +
                        hruby_sim_advance_time();
         | 
| 577 | 
            +
             | 
| 578 | 
            +
                        /* Mark the signals as fading. */
         | 
| 579 | 
            +
                        for(i=0; i<num_all_signals; ++i) {
         | 
| 580 | 
            +
                            all_signals[i]->fading = 1;
         | 
| 581 | 
            +
                        }
         | 
| 499 582 |  | 
| 500 | 
            -
             | 
| 501 | 
            -
             | 
| 502 | 
            -
                        all_signals[i]->fading = 1;
         | 
| 583 | 
            +
                        /* Activate the timed behavior that are on time. */
         | 
| 584 | 
            +
                        hruby_sim_activate_behaviors_on_time();
         | 
| 503 585 | 
             
                    }
         | 
| 504 | 
            -
             | 
| 505 | 
            -
                    /* Activate the timed behavior that are on time. */
         | 
| 506 | 
            -
                    hruby_sim_activate_behaviors_on_time();
         | 
| 507 586 | 
             
                }
         | 
| 508 587 | 
             
            }
         | 
| 509 588 |  | 
| @@ -521,29 +600,38 @@ void hruby_sim_core(char* name, void (*init_vizualizer)(char*), | |
| 521 600 | 
             
             *  @param delay the delay to wait in ps.
         | 
| 522 601 | 
             
             *  @param behavior the current behavior. */
         | 
| 523 602 | 
             
            void hw_wait(unsigned long long delay, Behavior behavior) {
         | 
| 524 | 
            -
                /*  | 
| 525 | 
            -
                if ( | 
| 526 | 
            -
                     | 
| 527 | 
            -
             | 
| 528 | 
            -
             | 
| 529 | 
            -
             | 
| 530 | 
            -
                 | 
| 531 | 
            -
             | 
| 532 | 
            -
             | 
| 533 | 
            -
             | 
| 534 | 
            -
             | 
| 535 | 
            -
             | 
| 536 | 
            -
                pthread_cond_signal(&hruby_sim_cond);
         | 
| 537 | 
            -
                /* Wait for being reactivated. */
         | 
| 538 | 
            -
                while(behavior->active_time > hruby_sim_time) {
         | 
| 603 | 
            +
                /* Is it in single timed behavior mode? */
         | 
| 604 | 
            +
                if (sim_single_flag) {
         | 
| 605 | 
            +
                    /* Yes, simply update signals and advance time. */
         | 
| 606 | 
            +
                    behavior->active_time += delay;
         | 
| 607 | 
            +
                    hruby_sim_update_signals(); 
         | 
| 608 | 
            +
                    hruby_sim_advance_time();
         | 
| 609 | 
            +
                } else {
         | 
| 610 | 
            +
                    /* No, handle the multi-threading. */
         | 
| 611 | 
            +
                    /* Maybe the thread is to end immediatly. */
         | 
| 612 | 
            +
                    if (sim_end_flag)
         | 
| 613 | 
            +
                        pthread_exit(NULL);
         | 
| 614 | 
            +
                    /* No go on with the wait procedure. */
         | 
| 539 615 | 
             
                    pthread_mutex_lock(&hruby_sim_mutex);
         | 
| 540 | 
            -
                     | 
| 541 | 
            -
             | 
| 542 | 
            -
             | 
| 543 | 
            -
             | 
| 544 | 
            -
             | 
| 545 | 
            -
                     | 
| 616 | 
            +
                    /* Indicate the behavior finished current execution. */
         | 
| 617 | 
            +
                    num_active_behaviors -= 1;
         | 
| 618 | 
            +
                    // printf("!!num_active_behaviors=%d\n",num_active_behaviors);
         | 
| 619 | 
            +
                    // pthread_cond_signal(&hruby_sim_cond);
         | 
| 620 | 
            +
                    /* Update the behavior's time. */
         | 
| 621 | 
            +
                    behavior->active_time += delay;
         | 
| 546 622 | 
             
                    pthread_mutex_unlock(&hruby_sim_mutex);
         | 
| 623 | 
            +
                    pthread_cond_signal(&hruby_sim_cond);
         | 
| 624 | 
            +
                    /* Wait for being reactivated. */
         | 
| 625 | 
            +
                    while(behavior->active_time > hruby_sim_time) {
         | 
| 626 | 
            +
                        pthread_mutex_lock(&hruby_sim_mutex);
         | 
| 627 | 
            +
                        while(!behaviors_can_run) {
         | 
| 628 | 
            +
                            // printf("!1\n");
         | 
| 629 | 
            +
                            // pthread_cond_wait(&compute_cond, &hruby_sim_mutex);
         | 
| 630 | 
            +
                            pthread_cond_wait(&hruby_beh_cond, &hruby_sim_mutex);
         | 
| 631 | 
            +
                            // printf("!2\n");
         | 
| 632 | 
            +
                        }
         | 
| 633 | 
            +
                        pthread_mutex_unlock(&hruby_sim_mutex);
         | 
| 634 | 
            +
                    }
         | 
| 547 635 | 
             
                }
         | 
| 548 636 | 
             
            }
         | 
| 549 637 |  | 
| @@ -563,6 +651,7 @@ void touch_signal(SignalI signal) { | |
| 563 651 | 
             
             *  @param value the value to transmit
         | 
| 564 652 | 
             
             *  @param signal the signal to transmit the value to. */
         | 
| 565 653 | 
             
            void transmit_to_signal(Value value, SignalI signal) {
         | 
| 654 | 
            +
                // printf("Tansmit to signal: %s(%p)\n",signal->name,signal);
         | 
| 566 655 | 
             
                /* Copy the content. */
         | 
| 567 656 | 
             
                if (signal->fading)
         | 
| 568 657 | 
             
                    signal->f_value = copy_value(value,signal->f_value);
         | 
| @@ -684,7 +773,6 @@ unsigned long long make_delay(int value, Unit unit) { | |
| 684 773 |  | 
| 685 774 |  | 
| 686 775 |  | 
| 687 | 
            -
             | 
| 688 776 | 
             
            /** Iterates over all the signals.
         | 
| 689 777 | 
             
             *  @param func function to applie on each signal. */
         | 
| 690 778 | 
             
            void each_all_signal(void (*func)(SignalI)) {
         | 
| @@ -0,0 +1,65 @@ | |
| 1 | 
            +
            #include <stdio.h>
         | 
| 2 | 
            +
            #include <string.h>
         | 
| 3 | 
            +
            #include <time.h>
         | 
| 4 | 
            +
            #include <stdarg.h>
         | 
| 5 | 
            +
            #include "hruby_sim.h"
         | 
| 6 | 
            +
             | 
| 7 | 
            +
             | 
| 8 | 
            +
            /**
         | 
| 9 | 
            +
             *  The HDLRuby simulation mute output engine, to be used with C code
         | 
| 10 | 
            +
             *  generated by the csim engine or by the rcsim engine. 
         | 
| 11 | 
            +
             **/
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            /* Global variables storing the configuration of the vcd generation. */
         | 
| 14 | 
            +
             | 
| 15 | 
            +
             | 
| 16 | 
            +
             | 
| 17 | 
            +
            /* Low-end print functions. */
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            /** Prints the time.
         | 
| 20 | 
            +
             *  @param time the time to show (given in ps). */
         | 
| 21 | 
            +
            static void mute_print_time(unsigned long long time) {
         | 
| 22 | 
            +
            }
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            /** Prints the name of an object without its hierarchy.
         | 
| 25 | 
            +
             *  @param object the object to print the name. */
         | 
| 26 | 
            +
            static void mute_print_name(Object object) {
         | 
| 27 | 
            +
            }
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            /** Prints the full name of an object without its hierarchy.
         | 
| 30 | 
            +
             *  @param object the object to print the name. */
         | 
| 31 | 
            +
            static void mute_print_full_name(Object object) {
         | 
| 32 | 
            +
            }
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            /** Prints a value.
         | 
| 35 | 
            +
             *  @param value the value to print */
         | 
| 36 | 
            +
            static void mute_print_value(Value value) {
         | 
| 37 | 
            +
            }
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            /** Prints a signal with its future value if any.
         | 
| 40 | 
            +
             *  @param signal the signal to show */
         | 
| 41 | 
            +
            static void mute_print_signal_fvalue(SignalI signal) {
         | 
| 42 | 
            +
            }
         | 
| 43 | 
            +
             | 
| 44 | 
            +
            /** Prints a signal with its current value if any
         | 
| 45 | 
            +
             *  @param signal the signal to show */
         | 
| 46 | 
            +
            static void mute_print_signal_cvalue(SignalI signal) {
         | 
| 47 | 
            +
            }
         | 
| 48 | 
            +
             | 
| 49 | 
            +
             | 
| 50 | 
            +
             | 
| 51 | 
            +
            /* The configuration and initialization of the vcd vizualizer. */
         | 
| 52 | 
            +
             | 
| 53 | 
            +
             | 
| 54 | 
            +
            /** Sets up the mute vizualization engine.
         | 
| 55 | 
            +
             *  @param name the name of the vizualization. */
         | 
| 56 | 
            +
            extern void init_mute_visualizer(char* name) {
         | 
| 57 | 
            +
                /* Initialize the vizualizer printer engine. */
         | 
| 58 | 
            +
                init_visualizer(&mute_print_time,
         | 
| 59 | 
            +
                                &mute_print_full_name,
         | 
| 60 | 
            +
                                &mute_print_value,
         | 
| 61 | 
            +
                                &mute_print_signal_fvalue,
         | 
| 62 | 
            +
                                &default_print_string,
         | 
| 63 | 
            +
                                &default_print_name,
         | 
| 64 | 
            +
                                &default_print_value);
         | 
| 65 | 
            +
            }
         | 
| @@ -106,6 +106,16 @@ Value binary(Value (*oper)(Value,Value,Value)) { | |
| 106 106 | 
             
                return oper(l,r,peek());
         | 
| 107 107 | 
             
            }
         | 
| 108 108 |  | 
| 109 | 
            +
            /** Selection calculation.
         | 
| 110 | 
            +
             * @param num the number of choices to select within. */
         | 
| 111 | 
            +
            Value select(unsigned int num) {
         | 
| 112 | 
            +
                Value* vals = alloca(num*sizeof(Value));
         | 
| 113 | 
            +
                int i;
         | 
| 114 | 
            +
                /* Get the values to concat from the stack. */
         | 
| 115 | 
            +
                for(i=1;i<=num;++i) vals[num-i] = pop();
         | 
| 116 | 
            +
                return select_valueP(pop(),peek(),num,vals);
         | 
| 117 | 
            +
            }
         | 
| 118 | 
            +
             | 
| 109 119 | 
             
            /** Cast calculation.
         | 
| 110 120 | 
             
             *  @param typ the type to cast to.
         | 
| 111 121 | 
             
             *  @return the destination.
         | 
| @@ -46,11 +46,38 @@ Value calc_expression(Expression expr, Value res) { | |
| 46 46 | 
             
                            Value right = get_value();
         | 
| 47 47 | 
             
                            left = calc_expression(bexpr->left,left);
         | 
| 48 48 | 
             
                            right = calc_expression(bexpr->right,right);
         | 
| 49 | 
            +
                            // printf("left=%.*s\n",left->capacity,left->data_str);
         | 
| 50 | 
            +
                            // printf("right=%.*s\n",right->capacity,right->data_str);
         | 
| 49 51 | 
             
                            res = bexpr->oper(left,right,res);
         | 
| 50 52 | 
             
                            free_value();
         | 
| 51 53 | 
             
                            free_value();
         | 
| 52 54 | 
             
                            break;
         | 
| 53 55 | 
             
                        }
         | 
| 56 | 
            +
                    case SELECT:
         | 
| 57 | 
            +
                        {
         | 
| 58 | 
            +
                            Select sexpr = (Select)expr;
         | 
| 59 | 
            +
                            /* Calculate the selection expression. */
         | 
| 60 | 
            +
                            Value selV = get_value();
         | 
| 61 | 
            +
                            selV = calc_expression(sexpr->select,selV);
         | 
| 62 | 
            +
                            /* Is the selection defined? */
         | 
| 63 | 
            +
                            if (is_defined_value(selV)) {
         | 
| 64 | 
            +
                                /* Yes, can perform the selection. */
         | 
| 65 | 
            +
                                long long sel = value2integer(selV);
         | 
| 66 | 
            +
                                if (sel >= 0 && sel < sexpr->num_choices) {
         | 
| 67 | 
            +
                                    /* Possible choice, proceed the computation. */
         | 
| 68 | 
            +
                                    res = calc_expression(sexpr->choices[sel],res);
         | 
| 69 | 
            +
                                }
         | 
| 70 | 
            +
                            } else {
         | 
| 71 | 
            +
                                /* Cannot compute, simply undefines the destination. */
         | 
| 72 | 
            +
                                /* First ensure res has the right shape. */
         | 
| 73 | 
            +
                                res->type = sexpr->choices[0]->type;
         | 
| 74 | 
            +
                                resize_value(res,type_width(res->type));
         | 
| 75 | 
            +
                                /* Then make it undefined. */
         | 
| 76 | 
            +
                                set_undefined_bitstring(res);
         | 
| 77 | 
            +
                            }
         | 
| 78 | 
            +
                            free_value();
         | 
| 79 | 
            +
                            break;
         | 
| 80 | 
            +
                        }
         | 
| 54 81 | 
             
                    case CONCAT:
         | 
| 55 82 | 
             
                        {
         | 
| 56 83 | 
             
                            Concat cexpr = (Concat)expr;
         | 
| @@ -70,7 +97,9 @@ Value calc_expression(Expression expr, Value res) { | |
| 70 97 | 
             
                            Cast cexpr = (Cast)expr;
         | 
| 71 98 | 
             
                            Value child = get_value();
         | 
| 72 99 | 
             
                            child = calc_expression(cexpr->child,child);
         | 
| 100 | 
            +
                            // printf("going to cast value of numeric=%d and width=%llu to width=%llu\n",child->numeric,type_width(child->type),type_width(cexpr->type));
         | 
| 73 101 | 
             
                            res = cast_value(child,cexpr->type,res);
         | 
| 102 | 
            +
                            // printf("result is numeric=%d\n",res->numeric);
         | 
| 74 103 | 
             
                            free_value();
         | 
| 75 104 | 
             
                            break;
         | 
| 76 105 | 
             
                        }
         | 
| @@ -157,16 +186,15 @@ void execute_statement(Statement stmnt, int mode, Behavior behavior) { | |
| 157 186 | 
             
                    case TRANSMIT: 
         | 
| 158 187 | 
             
                        {
         | 
| 159 188 | 
             
                            Transmit trans = (Transmit)stmnt;
         | 
| 160 | 
            -
                            // printf("trans=%p trans->left=%p trans->left->kind=%d\n",trans,trans->left,trans->left->kind);
         | 
| 161 189 | 
             
                            /* Compute the right value. */
         | 
| 162 | 
            -
                            // Value right = calc_expression(trans->right);
         | 
| 163 190 | 
             
                            Value right = get_value();
         | 
| 164 191 | 
             
                            right = calc_expression(trans->right,right);
         | 
| 192 | 
            +
                            // printf("transmit to left=%p with kind=%d and right=%p with kind=%d\n",trans->left,trans->left->kind,trans->right,trans->right->kind);fflush(stdout);
         | 
| 165 193 | 
             
                            /* Depending on the left value. */
         | 
| 166 194 | 
             
                            switch (trans->left->kind) {
         | 
| 167 195 | 
             
                                case SIGNALI:
         | 
| 168 196 | 
             
                                    // printf("left->name=%s\n",((SignalI)(trans->left))->name);
         | 
| 169 | 
            -
                                    fflush(stdout);
         | 
| 197 | 
            +
                                    // fflush(stdout);
         | 
| 170 198 | 
             
                                    /* Simple transmission. */
         | 
| 171 199 | 
             
                                    if (mode)
         | 
| 172 200 | 
             
                                        transmit_to_signal_seq(right,(SignalI)(trans->left));
         | 
| @@ -178,7 +206,6 @@ void execute_statement(Statement stmnt, int mode, Behavior behavior) { | |
| 178 206 | 
             
                                        /* Transmission to sub element. */
         | 
| 179 207 | 
             
                                        RefIndex refi = (RefIndex)(trans->left);
         | 
| 180 208 | 
             
                                        /* Compute the index. */
         | 
| 181 | 
            -
                                        // Value indexV = calc_expression(refi->index);
         | 
| 182 209 | 
             
                                        Value indexV = get_value();
         | 
| 183 210 | 
             
                                        indexV = calc_expression(refi->index,indexV);
         | 
| 184 211 | 
             
                                        long long index = value2integer(indexV);
         | 
| @@ -231,8 +258,9 @@ void execute_statement(Statement stmnt, int mode, Behavior behavior) { | |
| 231 258 | 
             
                                        /* For each sub reference. */
         | 
| 232 259 | 
             
                                        for(int i=0; i < refc->num_refs; ++i) {
         | 
| 233 260 | 
             
                                            /* Set up the transmit. */
         | 
| 234 | 
            -
                                            subtrans.left = refc->refs[i];
         | 
| 235 | 
            -
                                            long long size = type_width(subtrans.left->type);
         | 
| 261 | 
            +
                                            subtrans.left = refc->refs[refc->num_refs-i-1];
         | 
| 262 | 
            +
                                            unsigned long long size = type_width(subtrans.left->type);
         | 
| 263 | 
            +
                                            // printf("i=%i left=%p left->type=%p &left->type=%p right->kind=%i pos=%llu size=%llu\n",i,subtrans.left,subtrans.left->type,&(subtrans.left->type),right->kind,pos,size,size);fflush(stdout);
         | 
| 236 264 | 
             
                                            subtrans.right = (Expression)get_value();
         | 
| 237 265 | 
             
                                            subtrans.right = (Expression)read_range(
         | 
| 238 266 | 
             
                                                    right,pos,pos+size-1,
         | 
| @@ -244,6 +272,7 @@ void execute_statement(Statement stmnt, int mode, Behavior behavior) { | |
| 244 272 | 
             
                                            free_value();
         | 
| 245 273 | 
             
                                            pos += size;
         | 
| 246 274 | 
             
                                        }
         | 
| 275 | 
            +
                                        break;
         | 
| 247 276 | 
             
                                    }
         | 
| 248 277 | 
             
                                default:
         | 
| 249 278 | 
             
                                    perror("Invalid kind for a reference.");
         | 
| @@ -279,7 +308,6 @@ void execute_statement(Statement stmnt, int mode, Behavior behavior) { | |
| 279 308 | 
             
                        {
         | 
| 280 309 | 
             
                            HIf hif = (HIf)stmnt;
         | 
| 281 310 | 
             
                            /* Calculation the condition. */
         | 
| 282 | 
            -
                            // Value condition = calc_expression(hif->condition);
         | 
| 283 311 | 
             
                            Value condition = get_value();
         | 
| 284 312 | 
             
                            condition = calc_expression(hif->condition,condition);
         | 
| 285 313 | 
             
                            /* Is it true? */
         | 
| @@ -290,7 +318,6 @@ void execute_statement(Statement stmnt, int mode, Behavior behavior) { | |
| 290 318 | 
             
                                /* No, maybe an alternate condition is met. */
         | 
| 291 319 | 
             
                                int met = 0;/* Tell if an alternate condition has been met.*/
         | 
| 292 320 | 
             
                                for(int i=0; i<hif->num_noifs; ++i) {
         | 
| 293 | 
            -
                                    // Value subcond = calc_expression(hif->noconds[i]);
         | 
| 294 321 | 
             
                                    Value subcond = get_value();
         | 
| 295 322 | 
             
                                    subcond = calc_expression(hif->noconds[i],subcond);
         | 
| 296 323 | 
             
                                    if (is_defined_value(subcond) && value2integer(subcond)){
         | 
| @@ -305,7 +332,7 @@ void execute_statement(Statement stmnt, int mode, Behavior behavior) { | |
| 305 332 | 
             
                                    free_value();
         | 
| 306 333 | 
             
                                }
         | 
| 307 334 | 
             
                                /* Where there a sub condition met? */
         | 
| 308 | 
            -
                                if (!met) {
         | 
| 335 | 
            +
                                if (!met && hif->no) {
         | 
| 309 336 | 
             
                                    /* No, execute the no statement. */
         | 
| 310 337 | 
             
                                    execute_statement(hif->no,mode,behavior);
         | 
| 311 338 | 
             
                                }
         | 
| @@ -7,7 +7,7 @@ | |
| 7 7 |  | 
| 8 8 | 
             
            /**
         | 
| 9 9 | 
             
             *  The HDLRuby simulation vcd format genertion engine, to be used with C code
         | 
| 10 | 
            -
             *  generated by  | 
| 10 | 
            +
             *  generated by the csim engine or by the rcsim engine.
         | 
| 11 11 | 
             
             **/
         | 
| 12 12 |  | 
| 13 13 | 
             
            /* Global variables storing the configuration of the vcd generation. */
         | 
| @@ -74,20 +74,24 @@ static void vcd_print_name(Object object) { | |
| 74 74 | 
             
                    case SCOPE:
         | 
| 75 75 | 
             
                    case SYSTEMI:
         | 
| 76 76 | 
             
                    case BLOCK:
         | 
| 77 | 
            -
                         | 
| 78 | 
            -
             | 
| 79 | 
            -
             | 
| 80 | 
            -
             | 
| 81 | 
            -
             | 
| 82 | 
            -
             | 
| 83 | 
            -
                             | 
| 84 | 
            -
             | 
| 85 | 
            -
             | 
| 86 | 
            -
             | 
| 87 | 
            -
             | 
| 88 | 
            -
             | 
| 77 | 
            +
                        {
         | 
| 78 | 
            +
                            /* Print the name if name. */
         | 
| 79 | 
            +
                            /* Trick: SystemT, Block, Scope and SystemI have the
         | 
| 80 | 
            +
                             * field name at the same place. */
         | 
| 81 | 
            +
                            char* namep = object->kind == SIGNALI ? 
         | 
| 82 | 
            +
                                ((SignalI)object)->name : ((Block)object)->name;
         | 
| 83 | 
            +
                            if (namep!=NULL &&
         | 
| 84 | 
            +
                                    strlen(namep)>0) {
         | 
| 85 | 
            +
                                char name[256];
         | 
| 86 | 
            +
                                strncpy(name,namep,256);
         | 
| 87 | 
            +
                                replace_char(name,':','$');
         | 
| 88 | 
            +
                                vcd_print("%s",name);
         | 
| 89 | 
            +
                            } else {
         | 
| 90 | 
            +
                                /* No name, use the address of the object as name generator.*/
         | 
| 91 | 
            +
                                vcd_print("x$%p",(void*)object);
         | 
| 92 | 
            +
                            }
         | 
| 93 | 
            +
                            break;
         | 
| 89 94 | 
             
                        }
         | 
| 90 | 
            -
                        break;
         | 
| 91 95 | 
             
                    default: /* Nothing to do */
         | 
| 92 96 | 
             
                        break;
         | 
| 93 97 | 
             
                }
         | 
| @@ -98,7 +102,6 @@ static void vcd_print_name(Object object) { | |
| 98 102 | 
             
             *  @param object the object to print the name. */
         | 
| 99 103 | 
             
            static void vcd_print_full_name(Object object) {
         | 
| 100 104 | 
             
                /* Recurse on the owner if any. */
         | 
| 101 | 
            -
                // printf("owner=%p\n",object->owner);
         | 
| 102 105 | 
             
                if (object->owner != NULL) {
         | 
| 103 106 | 
             
                    vcd_print_full_name(object->owner);
         | 
| 104 107 | 
             
                    vcd_print("$");
         | 
| @@ -107,12 +110,23 @@ static void vcd_print_full_name(Object object) { | |
| 107 110 | 
             
                vcd_print_name(object);
         | 
| 108 111 | 
             
            }
         | 
| 109 112 |  | 
| 113 | 
            +
            /** Prints the id of a signal in vcd indentifier format.
         | 
| 114 | 
            +
             *  @param signal the signal to print the id. */
         | 
| 115 | 
            +
            static void vcd_print_signal_id(SignalI signal) {
         | 
| 116 | 
            +
                size_t id = signal->id;
         | 
| 117 | 
            +
                do {
         | 
| 118 | 
            +
                    vcd_print("%c",(id % (127-33)) + 33);
         | 
| 119 | 
            +
                    id = id / (127-33);
         | 
| 120 | 
            +
                } while (id > 0);
         | 
| 121 | 
            +
            }
         | 
| 122 | 
            +
             | 
| 110 123 | 
             
            /** Prints a value.
         | 
| 111 124 | 
             
             *  @param value the value to print */
         | 
| 112 125 | 
             
            static void vcd_print_value(Value value) {
         | 
| 113 | 
            -
                 | 
| 126 | 
            +
                unsigned long long width = type_width(value->type);
         | 
| 127 | 
            +
                if (width > 1) vcd_print("b");
         | 
| 114 128 | 
             
                if (value->numeric) {
         | 
| 115 | 
            -
                    unsigned long long width = type_width(value->type);
         | 
| 129 | 
            +
                    // unsigned long long width = type_width(value->type);
         | 
| 116 130 | 
             
                    unsigned long long mask = 1ULL << (width-1);
         | 
| 117 131 | 
             
                    for(; mask > 0; mask >>= 1) {
         | 
| 118 132 | 
             
                        vcd_print("%d",(value->data_int & mask) != 0);
         | 
| @@ -120,7 +134,7 @@ static void vcd_print_value(Value value) { | |
| 120 134 | 
             
                } else {
         | 
| 121 135 | 
             
                    /* Display a bitstring value. */
         | 
| 122 136 | 
             
                    unsigned long long i;
         | 
| 123 | 
            -
                    unsigned long long width = type_width(value->type);
         | 
| 137 | 
            +
                    // unsigned long long width = type_width(value->type);
         | 
| 124 138 | 
             
                    char* data = value->data_str;
         | 
| 125 139 | 
             
                    if (value->capacity == 0) {
         | 
| 126 140 | 
             
                        /* The value is empty, therefore undefined. */
         | 
| @@ -135,13 +149,15 @@ static void vcd_print_value(Value value) { | |
| 135 149 | 
             
                        } 
         | 
| 136 150 | 
             
                    }
         | 
| 137 151 | 
             
                }
         | 
| 152 | 
            +
                if (width > 1) vcd_print(" ");
         | 
| 138 153 | 
             
            }
         | 
| 139 154 |  | 
| 140 155 | 
             
            /** Prints a signal declaration.
         | 
| 141 156 | 
             
             *  @param signal the signal to declare */
         | 
| 142 157 | 
             
            static void vcd_print_var(SignalI signal) {
         | 
| 143 158 | 
             
                vcd_print("$var wire %d ",type_width(signal->type));
         | 
| 144 | 
            -
                vcd_print_full_name((Object)signal);
         | 
| 159 | 
            +
                // vcd_print_full_name((Object)signal);
         | 
| 160 | 
            +
                vcd_print_signal_id(signal);
         | 
| 145 161 | 
             
                vcd_print(" ");
         | 
| 146 162 | 
             
                vcd_print_name((Object)signal);
         | 
| 147 163 | 
             
                vcd_print(" $end\n");
         | 
| @@ -153,8 +169,9 @@ static void vcd_print_var(SignalI signal) { | |
| 153 169 | 
             
            static void vcd_print_signal_fvalue(SignalI signal) {
         | 
| 154 170 | 
             
                if (signal->f_value) {
         | 
| 155 171 | 
             
                    vcd_print_value(signal->f_value);
         | 
| 156 | 
            -
                    vcd_print(" ");
         | 
| 157 | 
            -
                    vcd_print_full_name((Object)signal);
         | 
| 172 | 
            +
                    // vcd_print(" ");
         | 
| 173 | 
            +
                    // vcd_print_full_name((Object)signal);
         | 
| 174 | 
            +
                    vcd_print_signal_id(signal);
         | 
| 158 175 | 
             
                    vcd_print("\n");
         | 
| 159 176 | 
             
                }
         | 
| 160 177 | 
             
            }
         | 
| @@ -165,8 +182,9 @@ static void vcd_print_signal_fvalue(SignalI signal) { | |
| 165 182 | 
             
            static void vcd_print_signal_cvalue(SignalI signal) {
         | 
| 166 183 | 
             
                if (signal->c_value) {
         | 
| 167 184 | 
             
                    vcd_print_value(signal->c_value);
         | 
| 168 | 
            -
                    vcd_print(" ");
         | 
| 169 | 
            -
                    vcd_print_full_name((Object)signal);
         | 
| 185 | 
            +
                    // vcd_print(" ");
         | 
| 186 | 
            +
                    // vcd_print_full_name((Object)signal);
         | 
| 187 | 
            +
                    vcd_print_signal_id(signal);
         | 
| 170 188 | 
             
                    vcd_print("\n");
         | 
| 171 189 | 
             
                }
         | 
| 172 190 | 
             
            }
         |