#include "acc_user.h" #include "veriuser.h" #include #include struct myCounter { handle count; handle enable; handle reset; handle clk; char *count_value; char *enable_value; char *reset_value; char *clk_value; char *clk_last_value; int checker_count; int count_width; int error; int error_time; }; // Multi-bit vector to integer conversion. int pliConv (char *in_string, int no_bits, int sim_time) { int conv = 0; int i = 0; int j = 0; int bin = 0; for ( i = no_bits-1; i >= 0; i = i - 1) { if (*(in_string + i) == 49) { bin = 1; } else if (*(in_string + i) == 120) { io_printf ("%d counterMonitor : WARNING : X detected\n", sim_time); bin = 0; } else if (*(in_string + i) == 122) { io_printf ("%d counterMonitor : WARNING : Z detected\n", sim_time); bin = 0; } else { bin = 0; } conv = conv + (1 << j)*bin; j ++; } return conv; } void counterModel (struct myCounter *counter) { int current_value ; int time = tf_gettime(); // Our model checks only at posedge if ((strcmp(counter->clk_value,"1") == 0) && (strcmp(counter->clk_last_value,"0") == 0)) { // Conver the current count value current_value = pliConv(counter->count_value,counter->count_width,time); // Check input control signal to floating or UnKnown if (strcmp(counter->reset_value,"x") == 0) { io_printf("%d counterMonitor : WARNING : reset is x\n", time); } if (strcmp(counter->reset_value,"z") == 0) { io_printf("%d counterMonitor : WARNING : reset is z\n", time); } if (strcmp(counter->enable_value,"x") == 0) { io_printf("%d counterMonitor : WARNING : enable is x\n", time); } if (strcmp(counter->enable_value,"z") == 0) { io_printf("%d counterMonitor : WARNING : enable is z\n", time); } // Increment monitor counter and compare only if // enable is 1 and reset is not active if (strcmp(counter->enable_value,"1") == 0 && strcmp(counter->reset_value,"0") == 0) { if (counter->checker_count != current_value) { io_printf ("%d counterMonitor : ERROR : Current value of monitor is %d dut is %d\n", time, counter->checker_count, current_value); counter->error ++; if (counter->error == 1) counter->error_time = time; } else { io_printf ("%d counterMonitor : INFO : Current value of monitor is %d dut is %d\n", time, counter->checker_count, current_value); } counter->checker_count = (counter->checker_count == 15) ? 0 : counter->checker_count + 1; // Reset monitor counter if reset is active } else if (strcmp(counter->reset_value,"1") == 0) { io_printf("%d counterMonitor : INFO : Reset is asserted\n", time); counter->checker_count = 0; } } // Update the clock state strcpy(counter->clk_last_value,counter->clk_value); } // misctf void counterMonitor(int data, int reason, int paramvc) { struct myCounter *counter = (struct myCounter *) tf_igetworkarea(tf_getinstance()); if ((reason == reason_paramvc) || (reason == reason_paramdrc)) { tf_synchronize( ); } else if (reason == reason_synch) { counter->clk = acc_handle_tfarg(1); counter->reset = acc_handle_tfarg(2); counter->enable = acc_handle_tfarg(3); counter->count = acc_handle_tfarg(4); // Get the values counter->clk_value = acc_fetch_value(counter->clk, "%b", 0); counter->reset_value = acc_fetch_value(counter->reset, "%b", 0); counter->enable_value = acc_fetch_value(counter->enable, "%b", 0); counter->count_value = acc_fetch_value(counter->count, "%b", 0); counter->count_width = acc_fetch_size (counter->count); // Call the counter model counterModel (counter); } // Print simulation stats when $finish is called if (reason == reason_finish) { io_printf("=========================================\n"); if (counter->error != 0) { io_printf (" Simulation : FAILED\n"); io_printf (" Mismatched %d\n",counter->error); io_printf (" First Mismatch at time %d\n", counter->error_time); } else { io_printf (" Simulation : PASSED\n"); } io_printf("=========================================\n"); } } // calltf() void initCounter(int data, int reason) { struct myCounter *counter; // Allocate memory for all variables necessary to manage a // single instance of the model. counter = (struct myCounter *) malloc (sizeof(struct myCounter)); // Initialize this instance of the model. counter->clk = acc_handle_tfarg(1); counter->reset = acc_handle_tfarg(2); counter->enable = acc_handle_tfarg(3); counter->count = acc_handle_tfarg(4); // Save a copy of the present clk value. counter->clk_last_value = acc_fetch_value(counter->clk, "%b", 0); // Enable callback of `counter_monitor` whenever // any argument to `$counter_monitor` changes. tf_asynchon(); // Set initial counter value to 0. counter->checker_count = 0; counter->error = 0; counter-> error_time = 0; // Save the model data with this instance of `$counterMonitor`. tf_setworkarea((char *)counter); }