simulate_blif.c File Reference

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <time.h>
#include <dlfcn.h>
#include "sim_block.h"
#include "types.h"
#include "globals.h"
#include "errors.h"
#include "netlist_utils.h"
#include "odin_util.h"
#include "outputs.h"
#include "util.h"
#include "multipliers.h"
#include "hard_blocks.h"
#include "simulate_blif.h"
#include "queue.h"
Include dependency graph for simulate_blif.c:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Defines

#define BUFFER_MAX_SIZE   1024
#define CLOCK_PORT_NAME_1   "clock"
#define CLOCK_PORT_NAME_2   "clk"
#define RESET_PORT_NAME   "reset_n"
#define SINGLE_PORT_MEMORY_NAME   "single_port_ram"
#define DUAL_PORT_MEMORY_NAME   "dual_port_ram"

Functions

void simulate_cycle (netlist_t *netlist, int cycle)
void store_value_in_line (char *token, line_t *line, int cycle)
void assign_node_to_line (nnode_t *node, line_t **lines, int lines_size, int type)
line_t ** read_test_vector_headers (FILE *out, int *lines_size, int max_lines_size)
long int get_value_from_string (char *token)
int is_node_top_level (netlist_t *netlist, nnode_t *node)
void compute_and_store_value (nnode_t *node, int cycle)
void free_lines (line_t **lines, int lines_size)
void assign_input_vector_to_lines (line_t **lines, char *buffer, int cycle)
void assign_random_vector_to_input_lines (line_t **lines, int lines_size, int cycle)
void write_vectors_to_file (line_t **lines, int lines_size, FILE *file, int type, int cycle)
line_t ** create_test_vector_lines (int *lines_size, netlist_t *netlist)
int verify_output_vectors (netlist_t *netlist, line_t **lines, int lines_size, int cycle)
line_t * create_line (char *name)
int has_node_been_computed_for_cycle (nnode_t *node, int cycle)
void write_vector_headers (FILE *iv, FILE *outv, line_t **lines, int lines_size)
void set_constant_pin_values (netlist_t *netlist, int cycle)
void update_pin_value (npin_t *pin, int value, int cycle)
int * multiply_arrays (int *a, int a_length, int *b, int b_length)
void compute_memory (npin_t **inputs, npin_t **outputs, int data_width, npin_t **addr, int addr_width, int we, int clock, int cycle, int *data)
void instantiate_memory (nnode_t *node, int **memory, int data_width, int addr_width)
void free_blocks ()
void simulate_blif (char *test_vector_file_name, netlist_t *netlist)
void simulate_new_vectors (int num_test_vectors, netlist_t *netlist)

Variables

simulation_type sim_type
int sim_result
FILE * modelsim_out
queue_t * blocks

Define Documentation

#define BUFFER_MAX_SIZE   1024

Definition at line 44 of file simulate_blif.c.

#define CLOCK_PORT_NAME_1   "clock"

Definition at line 49 of file simulate_blif.c.

#define CLOCK_PORT_NAME_2   "clk"

Definition at line 50 of file simulate_blif.c.

#define DUAL_PORT_MEMORY_NAME   "dual_port_ram"

Definition at line 54 of file simulate_blif.c.

#define RESET_PORT_NAME   "reset_n"

Definition at line 51 of file simulate_blif.c.

#define SINGLE_PORT_MEMORY_NAME   "single_port_ram"

Definition at line 53 of file simulate_blif.c.


Function Documentation

void assign_input_vector_to_lines ( line_t **  lines,
char *  buffer,
int  cycle 
)

Definition at line 1787 of file simulate_blif.c.

01788 {
01789         const char *delim;
01790         int length, line_count;
01791         char *token;
01792 
01793         delim = " \t";
01794         length = strlen(buffer);
01795 
01796         //handle this. Not sure if we need to be so careful, but it can't hurt.
01797         if(buffer[length-2] == '\r' || buffer[length-2] == '\n')
01798                 buffer[length-2] = '\0';
01799         if(buffer[length-1] == '\r' || buffer[length-1] == '\n')
01800                 buffer[length-1] = '\0';
01801 
01802         line_count = 0;
01803         token = strtok(buffer, delim);
01804 
01805         while (token != NULL)
01806         {
01807                 store_value_in_line(token, lines[line_count], cycle);
01808 
01809                 token = strtok(NULL, delim);
01810                 line_count++;
01811         }
01812 }

Here is the call graph for this function:

Here is the caller graph for this function:

void assign_node_to_line ( nnode_t node,
line_t **  lines,
int  lines_size,
int  type 
)

Definition at line 1327 of file simulate_blif.c.

01328 {
01329         int j, found;
01330         int pin_number;         //only used in multi-pin
01331         char *port_name;
01332         char *tilde;
01333 
01334         //this is larger than we need, but we'll free it later
01335         port_name = (char *)malloc(sizeof(char)*strlen(node->name));
01336 
01337         //copy the port name from the node's name, starting at the node's hat character
01338         strcpy(port_name, strchr(node->name, '^') + 1);
01339         //find the tilde, or NULL if it's not present
01340         tilde = strchr(port_name, '~');
01341 
01342         if (tilde == FALSE)             //single-bit width input
01343         {
01344                 found = FALSE;
01345                 //look for a line that's already there.
01346                 //These are guaranteed to be here because we map lines from top level nodes.
01347                 //this shouldn't be necessary, but it can't hurt
01348                 for (j = 0; j < lines_size; j++)
01349                 {
01350                         if (strcmp(lines[j]->name, port_name) == 0)
01351                         {
01352                                 found = TRUE;
01353                                 break;
01354                         }
01355                 }
01356 
01357                 if (found == FALSE)
01358                 {
01359                          if (strcmp(port_name, CLOCK_PORT_NAME_1) == 0 ||
01360                                         strcmp(port_name, CLOCK_PORT_NAME_2) == 0)
01361                          {
01362                                  return;
01363                          }
01364 //                      if (strcmp(port_name, RESET_PORT_NAME) == 0)
01365 
01366                         if (node->type == GND_NODE ||
01367                                 node->type == VCC_NODE ||
01368                                 node->type == PAD_NODE ||
01369                                 node->type == CLOCK_NODE)
01370                                 return;
01371                                 
01372                         warning_message(SIMULATION_ERROR, -1, -1, "Could not map single-bit top-level input node '%s' to input vector", node->name);
01373                         return;
01374                 }
01375                 //j is equal to the index of the correct line
01376 
01377                 //we may need to allocate pins if this is a top_output_nodes[] member
01378                 if (node->num_output_pins == 0)
01379                 {
01380                         npin_t *pin = allocate_npin();
01381                         allocate_more_node_output_pins(node, 1);
01382                         add_a_output_pin_to_node_spot_idx(node, pin, 0);
01383                 }
01384 
01385                 lines[j]->number_of_pins = 1;
01386                 lines[j]->max_number_of_pins = 1;
01387                 lines[j]->pins = (npin_t **)malloc(sizeof(npin_t *));
01388                 lines[j]->pins[0] = node->output_pins[0];
01389                 lines[j]->type = type;
01390 #ifdef DEBUG_SIMULATOR
01391                 printf("connecting %s only pin to %s\n", port_name, node->name);
01392 #endif
01393                 return;
01394         }
01395         //multi-bit width input
01396         pin_number = atoi(tilde+1);     //the string directly after the ~
01397         *tilde = '\0';  //change the tilde to \0 so we can use string library functions on port_name
01398 
01399         found = FALSE;
01400         for (j = 0; j < lines_size; j++)
01401         {
01402                 if (strcmp(lines[j]->name, port_name) == 0)
01403                 {
01404                         found = TRUE;
01405                         break;
01406                 }
01407         }
01408         if (found == FALSE)
01409         {
01410                 warning_message(SIMULATION_ERROR, -1, -1, "Could not map multi-bit top-level input node '%s' to input vector", node->name);
01411                 return;
01412         }
01413         //j is equal to the index of the correct line
01414 
01415         //expand out number of pins in this line_t* if necessary
01416         if (lines[j]->max_number_of_pins < 0)
01417         {
01418                 // this is the first time we've added a pin
01419                 lines[j]->max_number_of_pins = 8;
01420                 lines[j]->pins = (npin_t **)malloc(sizeof(npin_t*)*lines[j]->max_number_of_pins);
01421         }
01422         if (lines[j]->max_number_of_pins <= pin_number)
01423         {
01424                 //if we run out, then increase them by 64. Why not.
01425                 while (lines[j]->max_number_of_pins <= pin_number)
01426                         lines[j]->max_number_of_pins += 64;
01427                 lines[j]->pins = (npin_t **)realloc(lines[j]->pins, sizeof(npin_t*)*lines[j]->max_number_of_pins);
01428         }
01429 
01430 #ifdef DEBUG_SIMULATOR
01431         printf("connecting %s pin %d to %s\n", port_name, pin_number, node->name);
01432 #endif
01433 
01434         /*
01435          * always assign to output pin; if it's an input line, then this is
01436          * where it should go. if it's an output line, then we'll compare
01437          * that node's input pins to output pins to verify the simulation
01438          */
01439         if (node->num_output_pins == 0)
01440         {
01441                 //an output node only has input pins, so add one.
01442                 npin_t *pin = allocate_npin();
01443                 allocate_more_node_output_pins(node, 1);
01444                 add_a_output_pin_to_node_spot_idx(node, pin, 0);
01445         }
01446 
01447         lines[j]->pins[pin_number] = node->output_pins[0];
01448         lines[j]->type = type;
01449         lines[j]->number_of_pins++;
01450 }

Here is the call graph for this function:

Here is the caller graph for this function:

void assign_random_vector_to_input_lines ( line_t **  lines,
int  lines_size,
int  cycle 
)

Definition at line 1820 of file simulate_blif.c.

01821 {
01822         int i;
01823 
01824         for (i = 0; i < lines_size; i++)
01825         {
01826                 int j;
01827 
01828                 if (lines[i]->type == OUTPUT)
01829                         continue;
01830                 if (strcmp(lines[i]->name, CLOCK_PORT_NAME_1) == 0 ||
01831                                 strcmp(lines[i]->name, CLOCK_PORT_NAME_2) == 0)
01832                 {
01833                         update_pin_value(lines[i]->pins[0], cycle%2, cycle);
01834                         continue;
01835                 }
01836                 if (strcmp(lines[i]->name, RESET_PORT_NAME) == 0 ||
01837                                 lines[i]->type == GND_NODE ||
01838                                 lines[i]->type == PAD_NODE)
01839                 {
01840                         if (cycle == 0)
01841                                 update_pin_value(lines[i]->pins[0], 1, cycle);
01842                         else
01843                                 update_pin_value(lines[i]->pins[0], 0, cycle);
01844                         continue;
01845                 }
01846                 if (lines[i]->type == VCC_NODE)
01847                 {
01848                         update_pin_value(lines[i]->pins[0], 1, cycle);
01849                         continue;
01850                 }
01851 
01852                 for (j = 0; j < lines[i]->number_of_pins; j++)
01853                 {
01854                         int r = rand();
01855                         update_pin_value(lines[i]->pins[j], r % 2, cycle);
01856                 }
01857         }
01858 }

Here is the call graph for this function:

Here is the caller graph for this function:

void compute_and_store_value ( nnode_t node,
int  cycle 
)

Definition at line 500 of file simulate_blif.c.

00501 {
00502         int i, unknown;
00503 
00504         unknown = FALSE;
00505 
00506         char *temp1 = (char *)malloc(sizeof(char)*(strlen(node->name) + 4));
00507         char *temp2 = (char *)malloc(sizeof(char)*(strlen(node->name) + 4));
00508 
00509         sprintf(temp1, "top^%s", CLOCK_PORT_NAME_1);
00510         sprintf(temp2, "top^%s", CLOCK_PORT_NAME_2);
00511 
00512         if (strcmp(node->name, temp1) == 0 || strcmp(node->name, temp2) == 0)
00513         {
00514                 /*
00515                  * ODIN doesn't list clocks as type CLOCK_NODE, and we don't pick them
00516                  * up when we're assigning top-level inputs to lines[], so we
00517                  * need to check them here.
00518                  */
00519                 for (i = 0; i < node->num_output_pins; i++)
00520                         update_pin_value(node->output_pins[i], cycle % 2, cycle);
00521                 free(temp1);
00522                 free(temp2);
00523                 return;
00524         }
00525         
00526         if (strcmp(node->name, RESET_PORT_NAME) == 0)
00527         {
00528                 for (i = 0; i < node->num_output_pins; i++)
00529                 {
00530                         update_pin_value(node->output_pins[i], 0, cycle);
00531                 }
00532         }
00533 
00534         free(temp1);
00535         free(temp2);
00536 #ifdef DEBUG_SIMULATOR
00537         if (node->type == FF_NODE)
00538         {
00539                 printf("*** Computing a Flip Flop %s on cycle %d\n", node->name, cycle);
00540         }
00541 #endif
00542 
00543         /*
00544          * The behaviour defined in these case statements reflect
00545          * the logic in the output_blif.c file.
00546          */
00547         switch(node->type)
00548         {
00549                 case LT:                                // < 010 1
00550                 {
00551                         oassert(node->num_input_port_sizes == 3);
00552                         oassert(node->num_output_port_sizes == 1);
00553 
00554                         if (node->input_pins[0]->sim_state->value < 0 ||
00555                                         node->input_pins[1]->sim_state->value < 0 ||
00556                                         node->input_pins[2]->sim_state->value < 0)
00557                         {
00558                                 update_pin_value(node->output_pins[0], -1, cycle);
00559                                 return;
00560                         }
00561 
00562                         if (node->input_pins[0]->sim_state->value == 0 &&
00563                                         node->input_pins[1]->sim_state->value == 1 &&
00564                                         node->input_pins[2]->sim_state->value == 0)
00565                         {
00566                                 update_pin_value(node->output_pins[0], 1, cycle);
00567                                 return;
00568                         }
00569                         update_pin_value(node->output_pins[0], 0, cycle);
00570                         return;
00571                 }
00572                 case GT:                                // > 100 1
00573                 {
00574                         oassert(node->num_input_port_sizes == 3);
00575                         oassert(node->num_output_port_sizes == 1);
00576 
00577                         if (node->input_pins[0]->sim_state->value < 0 ||
00578                                         node->input_pins[1]->sim_state->value < 0 ||
00579                                         node->input_pins[2]->sim_state->value < 0)
00580                         {
00581                                 update_pin_value(node->output_pins[0], -1, cycle);
00582                                 return;
00583                         }
00584 
00585                         if (node->input_pins[0]->sim_state->value == 1 &&
00586                                         node->input_pins[1]->sim_state->value == 0 &&
00587                                         node->input_pins[2]->sim_state->value == 0)
00588                         {
00589                                 update_pin_value(node->output_pins[0], 1, cycle);
00590                                 return;
00591                         }
00592                         update_pin_value(node->output_pins[0], 0, cycle);
00593                         return;
00594                 }
00595                 case ADDER_FUNC:                // 001 1\n010 1\n100 1\n111 1
00596                 {
00597                         oassert(node->num_input_port_sizes == 3);
00598                         oassert(node->num_output_port_sizes == 1);
00599 
00600                         if (node->input_pins[0]->sim_state->value < 0 ||
00601                                         node->input_pins[1]->sim_state->value < 0 ||
00602                                         node->input_pins[2]->sim_state->value < 0)
00603                         {
00604                                 update_pin_value(node->output_pins[0], -1, cycle);
00605                                 return;
00606                         }
00607 
00608                         if ((node->input_pins[0]->sim_state->value == 0 &&
00609                                         node->input_pins[1]->sim_state->value == 0 &&
00610                                         node->input_pins[2]->sim_state->value == 1) ||
00611                                 (node->input_pins[0]->sim_state->value == 0 &&
00612                                         node->input_pins[1]->sim_state->value == 1 &&
00613                                         node->input_pins[2]->sim_state->value == 0) ||
00614                                 (node->input_pins[0]->sim_state->value == 1 &&
00615                                         node->input_pins[1]->sim_state->value == 0 &&
00616                                         node->input_pins[2]->sim_state->value == 0) ||
00617                                 (node->input_pins[0]->sim_state->value == 1 &&
00618                                         node->input_pins[1]->sim_state->value == 1 &&
00619                                         node->input_pins[2]->sim_state->value == 1))
00620                         {
00621                                 update_pin_value(node->output_pins[0], 1, cycle);
00622                                 return;
00623                         }
00624                         update_pin_value(node->output_pins[0], 0, cycle);
00625                         return;
00626                 }
00627                 case CARRY_FUNC:                // 011 1\n100 1\n110 1\n111 1
00628                 {
00629                         oassert(node->num_input_port_sizes == 3);
00630                         oassert(node->num_output_port_sizes == 1);
00631 
00632                         if ((node->input_pins[0]->sim_state->value == 1 &&
00633                                         node->input_pins[1]->sim_state->value == 0 &&
00634                                         node->input_pins[2]->sim_state->value == 0) ||
00635                                 (node->input_pins[0]->sim_state->value == 1 &&
00636                                         node->input_pins[1]->sim_state->value == 1 &&
00637                                         node->input_pins[2]->sim_state->value == 0) ||
00638                                 (node->input_pins[1]->sim_state->value == 1 &&
00639                                         node->input_pins[2]->sim_state->value == 1))
00640                         {
00641                                 update_pin_value(node->output_pins[0], 1, cycle);
00642                                 return;
00643                         }
00644 
00645                         if (node->input_pins[0]->sim_state->value < 0 ||
00646                                         node->input_pins[1]->sim_state->value < 0 ||
00647                                         node->input_pins[2]->sim_state->value < 0)
00648                         {
00649                                 update_pin_value(node->output_pins[0], -1, cycle);
00650                                 return;
00651                         }
00652 
00653                         update_pin_value(node->output_pins[0], 0, cycle);
00654                         return;
00655                 }
00656                 case BITWISE_NOT:               //
00657                 {
00658                         oassert(node->num_input_pins == 1);
00659                         oassert(node->num_output_pins == 1);
00660                         if (node->input_pins[0]->sim_state->value < 0)
00661                                 update_pin_value(node->output_pins[0], -1, cycle);
00662                         else if (node->input_pins[0]->sim_state->value == 1)
00663                                 update_pin_value(node->output_pins[0], 0, cycle);
00664                         else
00665                                 update_pin_value(node->output_pins[0], 1, cycle);
00666                         return;
00667                 }
00668                 case LOGICAL_AND:               // &&
00669                 {
00670                         oassert(node->num_output_pins == 1);
00671 
00672                         for (i = 0; i < node->num_input_pins; i++)
00673                         {
00674                                 if (node->input_pins[i]->sim_state->value < 0)
00675                                 {
00676                                         update_pin_value(node->output_pins[0], -1, cycle);
00677                                         return;
00678                                 }
00679                                 if (node->input_pins[i]->sim_state->value == 0)
00680                                 {
00681                                         update_pin_value(node->output_pins[0], 0, cycle);
00682                                         return;
00683                                 }
00684                         }
00685                         update_pin_value(node->output_pins[0], 1, cycle);
00686                         return;
00687                 }
00688                 case LOGICAL_OR:                // ||
00689                 {
00690                         oassert(node->num_output_pins == 1);
00691                         for (i = 0; i < node->num_input_pins; i++)
00692                         {
00693                                 if (node->input_pins[i]->sim_state->value < 0)
00694                                         unknown = TRUE;
00695                                 if (node->input_pins[i]->sim_state->value == 1)
00696                                 {
00697                                         update_pin_value(node->output_pins[0], 1, cycle);
00698                                         return;
00699                                 }
00700                         }
00701 
00702                         if (unknown)
00703                                 update_pin_value(node->output_pins[0], -1, cycle);
00704                         else
00705                                 update_pin_value(node->output_pins[0], 0, cycle);
00706                         return;
00707                 }
00708                 case LOGICAL_NAND:              // !&&
00709                 {
00710                         int retVal;
00711                         oassert(node->num_output_pins == 1);
00712 
00713                         retVal = 0;
00714                         for (i = 0; i < node->num_input_pins; i++)
00715                         {
00716                                 if (node->input_pins[i]->sim_state->value < 0)
00717                                 {
00718                                         update_pin_value(node->output_pins[0], -1, cycle);
00719                                         return;
00720                                 }
00721                                 if (node->input_pins[i]->sim_state->value == 0)
00722                                 {
00723                                         retVal = 1;
00724                                 }
00725                         }
00726 
00727                         update_pin_value(node->output_pins[0], retVal, cycle);
00728                         return;
00729                 }
00730                 case LOGICAL_NOT:               // !
00731                 case LOGICAL_NOR:               // !|
00732                 {
00733                         oassert(node->num_output_pins == 1);
00734 
00735                         for (i = 0; i < node->num_input_pins; i++)
00736                         {
00737                                 if (node->input_pins[i]->sim_state->value < 0)
00738                                 {
00739                                         update_pin_value(node->output_pins[0], -1, cycle);
00740                                         return;
00741                                 }
00742                                 if (node->input_pins[i]->sim_state->value == 1)
00743                                 {
00744                                         update_pin_value(node->output_pins[0], 0, cycle);
00745                                         return;
00746                                 }
00747                         }
00748                         update_pin_value(node->output_pins[0], 1, cycle);
00749                         return;
00750                 }
00751                 case LOGICAL_EQUAL:             // ==
00752                 case LOGICAL_XOR:               // ^
00753                 {
00754                         long long ones;
00755 
00756                         oassert(node->num_output_pins == 1);
00757 
00758                         ones = 0;
00759                         for (i = 0; i < node->num_input_pins; i++)
00760                         {
00761                                 if (node->input_pins[i]->sim_state->value < 0)
00762                                         unknown = TRUE;
00763                                 if (node->input_pins[i]->sim_state->value == 1)
00764                                         ones++;
00765                         }
00766                         if (unknown)
00767                                 update_pin_value(node->output_pins[0], -1, cycle);
00768                         else
00769                         {
00770                                 if (ones % 2 == 1)
00771                                         update_pin_value(node->output_pins[0], 1, cycle);
00772                                 else
00773                                         update_pin_value(node->output_pins[0], 0, cycle);
00774                         }
00775                         return;
00776                 }
00777                 case NOT_EQUAL:                 // !=
00778                 case LOGICAL_XNOR:              // !^
00779                 {
00780                         long long ones;
00781 
00782                         oassert(node->num_output_pins == 1);
00783 
00784                         ones = 0;
00785                         for (i = 0; i < node->num_input_pins; i++)
00786                         {
00787                                 if (node->input_pins[i]->sim_state->value < 0)
00788                                         unknown = TRUE;
00789                                 if (node->input_pins[i]->sim_state->value == 1)
00790                                         ones++;
00791                         }
00792 
00793                         if (unknown)
00794                                 update_pin_value(node->output_pins[0], -1, cycle);
00795                         else
00796                         {
00797                                 if (ones % 2 == 0)
00798                                         update_pin_value(node->output_pins[0], 1, cycle);
00799                                 else
00800                                         update_pin_value(node->output_pins[0], 0, cycle);
00801                         }
00802                         return;
00803                 }
00804                 case MUX_2:
00805                 {
00806                         oassert(node->num_output_pins == 1);
00807                         oassert(node->num_input_port_sizes >= 2);
00808                         oassert(node->input_port_sizes[0] == node->input_port_sizes[1]);
00809 
00810                         for (i = 0; i < node->input_port_sizes[0]; i++)
00811                         {
00812                                 if (node->input_pins[i]->sim_state->value < 0)
00813                                         unknown = TRUE;
00814                                 if (node->input_pins[i]->sim_state->value == 1 &&
00815                                                 node->input_pins[i]->sim_state->value ==
00816                                                 node->input_pins[i+node->input_port_sizes[0]]->sim_state->value)
00817                                 {
00818                                         update_pin_value(node->output_pins[0], 1, cycle);
00819                                         return;
00820                                 }
00821                         }
00822 
00823                         if (unknown)
00824                                 update_pin_value(node->output_pins[0], -1, cycle);
00825                         else
00826                                 update_pin_value(node->output_pins[0], 0, cycle);
00827 
00828                         return;
00829                 }
00830                 case FF_NODE:
00831                 {
00832                         oassert(node->num_output_pins == 1);
00833                         oassert(node->num_input_pins == 2);
00834                         
00835                         
00836                         /*
00837                         if (node->input_pins[1]->sim_state->value % 2 == 1)     //rising edge of clock
00838                                 update_pin_value(node->output_pins[0], node->input_pins[0]->sim_state->value, cycle);
00839                         else//falling edge of clock
00840                         {
00841                                 int prev;
00842 
00843                                 prev = node->output_pins[0]->sim_state->prev_value;
00844                                 
00845                                 update_pin_value(node->output_pins[0], node->output_pins[0]->sim_state->value, cycle);
00846                                 node->output_pins[0]->sim_state->prev_value = prev;
00847                         }
00848                         */
00849                         return;
00850                 }
00851                 case MEMORY:
00852                 {
00853                         int i;
00854 
00855                         char *clock_name = "clk";
00856 
00857                         char *we_name = "we";
00858                         char *addr_name = "addr";
00859                         char *data_name = "data";
00860 
00861                         char *we_name1 = "we1";
00862                         char *addr_name1 = "addr1";
00863                         char *data_name1 = "data1";
00864                         char *we_name2 = "we2";
00865                         char *addr_name2 = "addr2";
00866                         char *data_name2 = "data2";
00867                         char *out_name1 = "out1";
00868                         char *out_name2 = "out2";
00869 
00870                         oassert(strcmp(node->related_ast_node->children[0]->types.identifier, 
00871                                                 SINGLE_PORT_MEMORY_NAME) == 0 ||
00872                                         strcmp(node->related_ast_node->children[0]->types.identifier, 
00873                                                 DUAL_PORT_MEMORY_NAME) == 0);
00874                         
00875                         if (strcmp(node->related_ast_node->children[0]->types.identifier, 
00876                                                 SINGLE_PORT_MEMORY_NAME) == 0)
00877                         {
00878                                 int we;
00879                                 int clock;
00880                                 int data_width = 0;
00881                                 int addr_width = 0;
00882                                 npin_t **addr = NULL;
00883                                 npin_t **data = NULL;
00884                                 npin_t **out = NULL;
00885                                 
00886                                 for (i = 0; i < node->num_input_pins; i++)
00887                                 {
00888                                         if (strcmp(node->input_pins[i]->mapping, we_name) == 0)
00889                                                 we = node->input_pins[i]->sim_state->value;
00890                                         else if (strcmp(node->input_pins[i]->mapping, addr_name) == 0)
00891                                         {
00892                                                 if (addr == NULL)
00893                                                         addr = &node->input_pins[i];
00894                                                 addr_width++;
00895                                         }
00896                                         else if (strcmp(node->input_pins[i]->mapping, data_name) == 0)
00897                                         {
00898                                                 if (data == NULL)
00899                                                         data = &node->input_pins[i];
00900                                                 data_width++;
00901                                         }
00902                                         else if (strcmp(node->input_pins[i]->mapping, clock_name) == 0)
00903                                                 clock = node->input_pins[i]->sim_state->value;
00904                                 }
00905                                 out = node->output_pins;
00906 
00907                                 if (node->type == MEMORY &&
00908                                                 node->memory_data == NULL)
00909                                 {
00910                                         instantiate_memory(node, &(node->memory_data), data_width, addr_width);
00911                                 }
00912 
00913                                 compute_memory(data, out, data_width, addr, addr_width, 
00914                                                 we, clock, cycle, node->memory_data);
00915                         }
00916                         else
00917                         {
00918                                 int clock;
00919                                 int we1;
00920                                 int data_width1 = 0;
00921                                 int addr_width1 = 0;
00922                                 npin_t **addr1 = NULL;
00923                                 npin_t **data1 = NULL;
00924                                 npin_t **out1 = NULL;
00925                                 int we2;
00926                                 int data_width2 = 0;
00927                                 int addr_width2 = 0;
00928                                 npin_t **addr2 = NULL;
00929                                 npin_t **data2 = NULL;
00930                                 npin_t **out2 = NULL;
00931 
00932                                 for (i = 0; i < node->num_input_pins; i++)
00933                                 {
00934                                         if (strcmp(node->input_pins[i]->mapping, we_name1) == 0)
00935                                                 we1 = node->input_pins[i]->sim_state->value;
00936                                         else if (strcmp(node->input_pins[i]->mapping, we_name2) == 0)
00937                                                 we2 = node->input_pins[i]->sim_state->value;
00938                                         else if (strcmp(node->input_pins[i]->mapping, addr_name1) == 0)
00939                                         {
00940                                                 if (addr1 == NULL)
00941                                                         addr1 = &node->input_pins[i];
00942                                                 addr_width1++;
00943                                         }
00944                                         else if (strcmp(node->input_pins[i]->mapping, addr_name2) == 0)
00945                                         {
00946                                                 if (addr2 == NULL)
00947                                                         addr2 = &node->input_pins[i];
00948                                                 addr_width2++;
00949                                         }
00950                                         else if (strcmp(node->input_pins[i]->mapping, data_name1) == 0)
00951                                         {
00952                                                 if (data1 == NULL)
00953                                                         data1 = &node->input_pins[i];
00954                                                 data_width1++;
00955                                         }
00956                                         else if (strcmp(node->input_pins[i]->mapping, data_name2) == 0)
00957                                         {
00958                                                 if (data2 == NULL)
00959                                                         data2 = &node->input_pins[i];
00960                                                 data_width2++;
00961                                         }
00962                                         else if (strcmp(node->input_pins[i]->mapping, clock_name) == 0)
00963                                                 clock = node->input_pins[i]->sim_state->value;
00964                                 }
00965                                 for (i = 0; i < node->num_output_pins; i++)
00966                                 {
00967                                         if (strcmp(node->output_pins[i]->mapping, out_name1) == 0)
00968                                         {
00969                                                 if (out1 == NULL)
00970                                                         out1 = &node->output_pins[i];
00971                                         }
00972                                         else if (strcmp(node->output_pins[i]->mapping, out_name2) == 0)
00973                                         {
00974                                                 if (out2 == NULL)
00975                                                         out2 = &node->output_pins[i];
00976                                         }
00977                                 }
00978 
00979                                 if (node->memory_data == NULL)
00980                                 {
00981                                         instantiate_memory(node, &(node->memory_data), data_width2, addr_width2);
00982                                 }
00983 
00984                                 compute_memory(data1, out1, data_width1, addr1, addr_width1, we1, clock, cycle, node->memory_data);
00985                                 compute_memory(data2, out2, data_width2, addr2, addr_width2, we2, clock, cycle, node->memory_data);
00986                         }
00987 
00988                         return;
00989                 }
00990                 case HARD_IP:
00991                 {
00992                         int k;
00993                         int *input_pins = (int *)malloc(sizeof(int)*node->num_input_pins);
00994                         int *output_pins = (int *)malloc(sizeof(int)*node->num_output_pins);
00995                         
00996                         oassert(node->input_port_sizes[0] > 0);
00997                         oassert(node->output_port_sizes[0] > 0);
00998 
00999                         if (node->simulate_block_cycle == NULL)
01000                         {
01001                                 void *handle;
01002                                 char *error;
01003                                 void (*func_pointer)(int, int, int*, int, int*);
01004                                 char *filename = (char *)malloc(sizeof(char)*strlen(node->name));
01005                                 
01006                                 if (index(node->name, '.') == NULL)
01007                                         error_message(SIMULATION_ERROR, -1, -1, "Couldn't extract the name of a shared library for hard-block simulation");
01008                                 
01009                                 //we're extracting "hardblocktype+instancename.so" from "module.hardblocktype+instancename"
01010                                 snprintf(filename, sizeof(char)*strlen(node->name), "%s.so", index(node->name, '.')+1);
01011                                 
01012                                 handle = dlopen(filename, RTLD_LAZY);
01013                                 if (!handle)
01014                                 {
01015                                         error_message(SIMULATION_ERROR, -1, -1, "Couldn't open a shared library for hard-block simulation: %s", dlerror());
01016                                 }
01017                                 dlerror();//clear any existing errors
01018                                 func_pointer = (void(*)(int, int, int*, int, int*))dlsym(handle, "simulate_block_cycle");
01019                                 if ((error = dlerror()) != NULL)
01020                                 {
01021                                         error_message(SIMULATION_ERROR, -1, -1, "Couldn't load a shared library method for hard-block simulation: %s", error);
01022                                 }
01023 
01024                                 node->simulate_block_cycle = func_pointer;
01025                                 enqueue_item(blocks, handle);
01026                                 free(filename);
01027                         }
01028                         
01029                         //extract values of input pins into int array
01030                         for (k = 0; k < node->num_input_pins; k++)
01031                         {
01032                                 input_pins[k] = node->input_pins[k]->sim_state->value;
01033                         }
01034                         
01035                         //invoke hardblock simulation call
01036                         (node->simulate_block_cycle)(cycle, node->num_input_pins, input_pins, node->num_output_pins, output_pins);
01037                         
01038                         //extra values of output array into output pins.
01039                         for (k = 0; k < node->num_output_pins; k++)
01040                         {
01041                                 update_pin_value(node->output_pins[k], output_pins[k], cycle);
01042                         }
01043                         
01044                         free(input_pins);
01045                         free(output_pins);
01046 
01047                         return;
01048                 }
01049                 case MULTIPLY:
01050                 {
01051                         int *a, *b, *result;
01052 
01053                         oassert(node->num_input_port_sizes >= 2);
01054                         oassert(node->num_output_port_sizes == 1);
01055 
01056                         a = (int *)malloc(sizeof(int)*node->input_port_sizes[0]);
01057                         b = (int *)malloc(sizeof(int)*node->input_port_sizes[1]);
01058 
01059                         //get our input arrays ready
01060                         for (i = 0; i < node->input_port_sizes[0]; i++)
01061                         {
01062                                 a[i] = node->input_pins[i]->sim_state->value;
01063                                 if (a[i] < 0)
01064                                         unknown = TRUE;
01065                         }
01066                         for (i = 0; i < node->input_port_sizes[1]; i++)
01067                         {
01068                                 b[i] = node->input_pins[node->input_port_sizes[0] + i]->sim_state->value;
01069                                 if (b[i] < 0)
01070                                         unknown = TRUE;
01071                         }
01072 
01073                         if (unknown)
01074                         {
01075                                 for (i = 0; i < node->num_output_pins; i++)
01076                                 {
01077                                         update_pin_value(node->output_pins[i], -1, cycle);
01078                                 }
01079                         }
01080 
01081                         //multiply our values
01082                         result = multiply_arrays(a, node->input_port_sizes[0], b, node->input_port_sizes[1]);
01083 
01084                         //get our output values from result[]
01085                         for (i = 0; i < node->num_output_pins; i++)
01086                         {
01087                                 update_pin_value(node->output_pins[i], result[i], cycle);
01088                         }
01089 
01090                         //free memory
01091                         free(result);
01092                         free(a);
01093                         free(b);
01094                         return;
01095                 }
01096                 
01097                 /* adding new node type GENERIC for simulation reading the bit map */
01098                 case GENERIC : // simulate using the bit map reading
01099                 {
01100 
01101 #ifdef DEBUG_GENERIC_MODE_SIMULATION                    
01102 printf(" Generic type detected \n");
01103 #endif
01104                         
01105                         int lut_size=0;
01106                         int i,j,found=0;
01107                         int line_count_bitmap=node->bit_map_line_count;
01108                         char **bit_map=node->bit_map;
01109                         while(bit_map[0][lut_size]!='\0')
01110                         lut_size++;
01111 #ifdef DEBUG_GENERIC_MODE_SIMULATION                    
01112 printf("lut_size:%d \n",lut_size);
01113 for(i=0;i<lut_size;i++)
01114 printf("%d",node->input_pins[i]->sim_state->value);
01115 printf("\n"); 
01116 #endif                  
01117                         for(i=0;i<line_count_bitmap && (!found);i++)
01118                         {
01119                           for(j=0;j<lut_size;j++)
01120                           {                     
01121                                 if(node->input_pins[j]->sim_state->value <0 )
01122                                 {
01123                                   update_pin_value(node->output_pins[0], -1, cycle);
01124                                   return;
01125                                 }
01126         
01127                                 if(bit_map[i][j]=='-')
01128                                 continue;
01129                                 else if(bit_map[i][j]-'0'==node->input_pins[j]->sim_state->value)
01130                                 continue;
01131                                 else 
01132                                 break;
01133                           }
01134 
01135 #ifdef DEBUG_GENERIC_MODE_SIMULATION            
01136 printf("\nj: %d\n",j);
01137 #endif
01138                           if(j==lut_size)
01139                           found=1;
01140                         }       
01141 
01142 #ifdef DEBUG_GENERIC_MODE_SIMULATION                    
01143 printf("found:%d \n",found);
01144 #endif                                  
01145                         if(found==1)
01146                         update_pin_value(node->output_pins[0], 1, cycle);
01147                         else
01148                         update_pin_value(node->output_pins[0], 0, cycle);
01149 
01150 #ifdef DEBUG_GENERIC_MODE_SIMULATION
01151 printf(" printing the detected bit map \n");
01152 printf(" line_count_bitmap : %d \n",line_count_bitmap);
01153 for(i=0;i<line_count_bitmap;i++)
01154 printf("\t %s \n",node->bit_map[i]);
01155 #endif
01156 
01157 
01158 #ifdef DEBUG_GENERIC_MODE_SIMULATION                            
01159 printf("Exiting the generic type \n");
01160 #endif
01161 
01162                         return;
01163                 }
01164 
01165 
01166                 case INPUT_NODE:
01167                 case OUTPUT_NODE:
01168                         return;
01169                 case PAD_NODE:
01170                 case CLOCK_NODE:
01171                         return;
01172                 case GND_NODE:
01173                 {
01174                                         
01175                         update_pin_value(node->output_pins[0], 0, cycle);
01176                         return;
01177                 }
01178                 case VCC_NODE:
01179                 {
01180                                                 
01181                         update_pin_value(node->output_pins[0], 1, cycle);
01182                         return;
01183                 }
01184                 /* These should have already been converted to softer versions. */
01185                 case BITWISE_AND:
01186                 case BITWISE_NAND:
01187                 case BITWISE_NOR:
01188                 case BITWISE_XNOR:
01189                 case BITWISE_XOR:
01190                 case BITWISE_OR:
01191                 case BUF_NODE:
01192                 case MULTI_PORT_MUX:
01193                 case SL:
01194                 case SR:
01195                 case CASE_EQUAL:
01196                 case CASE_NOT_EQUAL:
01197                 case DIVIDE:
01198                 case MODULO:
01199                 case GTE:
01200                 case LTE:
01201                 case ADD:
01202                 case MINUS:
01203                 default:
01204                         /* these nodes should have been converted to softer versions */
01205                         error_message(SIMULATION_ERROR, -1, -1, "Node should have been converted to softer version: %s", node->name);
01206         }
01207 }

Here is the call graph for this function:

Here is the caller graph for this function:

void compute_memory ( npin_t **  inputs,
npin_t **  outputs,
int  data_width,
npin_t **  addr,
int  addr_width,
int  we,
int  clock,
int  cycle,
int *  data 
)

Definition at line 2237 of file simulate_blif.c.

02246 {
02247         int address;
02248         int i;
02249 
02250         //if (clock == 0)
02251         {
02252                 int i; 
02253                 for (i = 0; i < data_width; i++)
02254                 {
02255                         update_pin_value(outputs[i], outputs[i]->sim_state->value, cycle);
02256                 }
02257                 return;
02258         }
02259         
02260         address = 0;
02261         /*
02262          * The idea here is that we have an array of pins representing an address.
02263          * The pins are arranged from MSB to LSB. These pins represent a number
02264          * which is our address. We're going to iterate over them to get it.
02265          */
02266         for (i = 0; i < addr_width; i++)
02267         {
02268                 address += 1 << (addr_width - 1 - i);
02269         }
02270         if (we)
02271         {
02272                 for (i = 0; i < data_width; i++)
02273                 {
02274                         int write_address = i + (address * data_width);
02275                         data[write_address] = inputs[i]->sim_state->value;
02276                         update_pin_value(outputs[i], data[write_address], cycle);
02277                 }
02278         }
02279         else
02280         {
02281                 for (i = 0; i < data_width; i++)
02282                 {
02283                         int read_address = i + (address * data_width);
02284                         update_pin_value(outputs[i], data[read_address], cycle);
02285                 }
02286         }
02287 }

Here is the call graph for this function:

Here is the caller graph for this function:

line_t * create_line ( char *  name  ) 

Definition at line 1752 of file simulate_blif.c.

01753 {
01754         line_t *line;
01755 
01756         line = (line_t *)malloc(sizeof(line_t));
01757         line->number_of_pins = 0;
01758         line->max_number_of_pins = -1;
01759         line->pins = NULL;
01760         line->type = -1;
01761         line->name = (char *)malloc(sizeof(char)*(strlen(name)+1));
01762         strcpy(line->name, name);
01763 
01764         return line;
01765 }

Here is the caller graph for this function:

line_t ** create_test_vector_lines ( int *  lines_size,
netlist_t netlist 
)

Definition at line 1458 of file simulate_blif.c.

01459 {
01460         line_t **lines;
01461         int i, j, current_line, pin_number, found;
01462         char *port_name, *tilde;
01463 
01464         //start with no lines
01465         current_line = 0;
01466         //malloc the absolute largest array possible (each top-level node is one pin)
01467         lines = (line_t **)malloc(sizeof(line_t*)*(netlist->num_top_input_nodes + netlist->num_top_output_nodes));
01468 
01469         //used when freeing memory
01470         port_name = NULL;
01471 
01472         for (i = 0; i < netlist->num_top_input_nodes; i++)
01473         {
01474                 //make sure to free memory!
01475                 if (NULL != port_name)
01476                         free(port_name);
01477 
01478                 //this is larger than we need, but we'll free the rest anyways
01479                 port_name = (char *)malloc(sizeof(char)*strlen(netlist->top_input_nodes[i]->name));
01480                 strcpy(port_name, strchr(netlist->top_input_nodes[i]->name, '^') + 1);
01481 
01482                 //look for a ~
01483                 tilde = strchr(port_name, '~');
01484                 if (NULL == tilde)      //single-bit
01485                 {
01486                         //skip the clock and reset port - not sure why netlist->clock_node doesn't map correctly
01487                         if (strcmp(port_name, CLOCK_PORT_NAME_1) == 0 ||
01488                                         strcmp(port_name, CLOCK_PORT_NAME_2) == 0)// ||
01489 //                                      strcmp(port_name, RESET_PORT_NAME) == 0)
01490                                 continue;
01491 
01492                         //create the port
01493                         lines[current_line] = create_line(port_name);
01494                         lines[current_line]->number_of_pins = 1;
01495                         lines[current_line]->max_number_of_pins = 1;
01496                         lines[current_line]->pins = (npin_t **)malloc(sizeof(npin_t *));
01497                         lines[current_line]->pins[0] = netlist->top_input_nodes[i]->output_pins[0];
01498                         lines[current_line]->type = INPUT;
01499 #ifdef DEBUG_SIMULATOR
01500                         printf("connecting %s only pin to %s\n", lines[current_line]->name, netlist->top_input_nodes[i]->name);
01501 #endif
01502                         current_line++;
01503                         continue;
01504                 }
01505                 //means we have multiple pins. The node->name is "top^port_name~pin#", so
01506                 //take the string from one after the tilde to get the pin number. Then,
01507                 //we can change the ~ to a '\0', letting use use the port_name as it's own
01508                 //string. This doesn't change the node's reference, since we copied
01509                 //our own port name
01510 
01511                 pin_number = atoi(tilde+1);
01512                 *tilde = '\0';
01513 
01514                 if (strcmp(port_name, CLOCK_PORT_NAME_1) == 0 ||
01515                                 strcmp(port_name, CLOCK_PORT_NAME_2) == 0 ||
01516                                 strcmp(port_name, RESET_PORT_NAME) == 0)
01517                         continue;
01518 
01519                 //we need to look for a port that already exists that has the name we're
01520                 //looking for. If we can't find it, it means we're the first
01521                 found = FALSE;
01522                 for (j = 0; j < current_line && found == FALSE; j++)
01523                 {
01524                         if (strcmp(lines[j]->name, port_name) == 0)
01525                                 found = TRUE;
01526                 }
01527 
01528                 if (found == FALSE)
01529                 {
01530                         lines[current_line] = create_line(port_name);
01531                         current_line++;
01532                 }
01533                 else j--;       //if we found it, then j is equal to one more than the correct reference
01534 
01535                 //this is done the first time
01536                 if (lines[j]->max_number_of_pins < 0)
01537                 {
01538                         lines[j]->max_number_of_pins = 8;
01539                         lines[j]->pins = (npin_t **)malloc(sizeof(npin_t*)*lines[j]->max_number_of_pins);
01540                 }
01541 
01542                 //expand out number of pins in this line_t* if necessary
01543                 //this is necessary because we might find pin 9 before, say,
01544                 //pin 2. So we keep a max number of pins, and hope that the
01545                 //the array is eventually filled out
01546                 if (lines[j]->max_number_of_pins <= pin_number)
01547                 {
01548                         while (lines[j]->max_number_of_pins <= pin_number)
01549                                 lines[j]->max_number_of_pins += 64;
01550                         lines[j]->pins = (npin_t **)realloc(lines[j]->pins, sizeof(npin_t*)*lines[j]->max_number_of_pins);
01551                 }
01552 
01553                 //we're going to assume that a node has only one pin
01554                 lines[j]->pins[pin_number] = netlist->top_input_nodes[i]->output_pins[0];
01555                 lines[j]->type = INPUT;
01556                 lines[j]->number_of_pins++;
01557 
01558 #ifdef DEBUG_SIMULATOR
01559                 printf("connecting %s pin %d to %s\n", port_name, pin_number, netlist->top_input_nodes[i]->name);
01560 #endif
01561         }
01562 
01563         //this loop is almost identical to the one above it, with a few keep differences
01564         //pointed out in the comments
01565         for (i = 0; i < netlist->num_top_output_nodes; i++)
01566         {
01567                 if (port_name != NULL)
01568                         free(port_name);
01569 
01570                 port_name = (char *)malloc(sizeof(char)*strlen(netlist->top_output_nodes[i]->name));
01571                 strcpy(port_name, strchr(netlist->top_output_nodes[i]->name, '^') + 1);
01572 
01573                 tilde = strchr(port_name, '~');
01574                 if (NULL == tilde)      //single-bit
01575                 {
01576                         if (netlist->top_output_nodes[i]->num_output_pins == 0)
01577                         {
01578                                 npin_t *pin = allocate_npin();
01579                                 allocate_more_node_output_pins(netlist->top_output_nodes[i], 1);
01580                                 add_a_output_pin_to_node_spot_idx(netlist->top_output_nodes[i], pin, 0);
01581                         }
01582 
01583                         lines[current_line] = create_line(port_name);
01584                         lines[current_line]->number_of_pins = 1;
01585                         lines[current_line]->max_number_of_pins = 1;
01586                         lines[current_line]->pins = (npin_t **)malloc(sizeof(npin_t *));
01587                         lines[current_line]->pins[0] = netlist->top_output_nodes[i]->output_pins[0];
01588                         lines[current_line]->type = OUTPUT; //difference: a different type of pin
01589 #ifdef DEBUG_SIMULATOR
01590                         printf("connecting %s only pin to %s\n", lines[current_line]->name, netlist->top_output_nodes[i]->name);
01591 #endif
01592                         current_line++;
01593                         continue;
01594                 }
01595 
01596                 pin_number = atoi(tilde+1);
01597                 *tilde = '\0';
01598                 found = FALSE;
01599                 for (j = 0; j < current_line && found == FALSE; j++)
01600                 {
01601                         if (strcmp(lines[j]->name, port_name) == 0)
01602                                 found = TRUE;
01603                 }
01604                 if (found == FALSE)
01605                 {
01606                         lines[current_line] = create_line(port_name);
01607                         current_line++;
01608                 }
01609                 else j--;
01610 
01611 
01612                 if (lines[j]->max_number_of_pins < 0)
01613                 {
01614                         lines[j]->max_number_of_pins = 8;
01615                         lines[j]->pins = (npin_t **)malloc(sizeof(npin_t*)*lines[j]->max_number_of_pins);
01616                 }
01617 
01618                 //expand out number of pins in this line_t* if necessary
01619                 if (lines[j]->max_number_of_pins <= pin_number)
01620                 {
01621                         while (lines[j]->max_number_of_pins <= pin_number)
01622                                 lines[j]->max_number_of_pins += 64;
01623                         lines[j]->pins = (npin_t **)realloc(lines[j]->pins, sizeof(npin_t*)*lines[j]->max_number_of_pins);
01624                 }
01625 
01626                 //difference:
01627                 //top-level output nodes don't have output pins; they only have an input pin.
01628                 //we're going to add output pins here. Then, in order to verify test vector
01629                 //simulation, we'll store the expected value in the output pin, simulate,
01630                 //and compare the input and output pins to see if they match.
01631                 if (netlist->top_output_nodes[i]->num_output_pins == 0)
01632                 {
01633                         npin_t *pin = allocate_npin();
01634                         allocate_more_node_output_pins(netlist->top_output_nodes[i], 1);
01635                         add_a_output_pin_to_node_spot_idx(netlist->top_output_nodes[i], pin, 0);
01636                 }
01637 
01638                 lines[j]->pins[pin_number] = netlist->top_output_nodes[i]->output_pins[0];
01639                 lines[j]->type = OUTPUT;
01640                 lines[j]->number_of_pins++;
01641 #ifdef DEBUG_SIMULATOR
01642                 printf("connecting %s pin %d to %s\n", port_name, pin_number, netlist->top_output_nodes[i]->name);
01643 #endif
01644         }
01645         if (port_name != NULL)
01646                 free(port_name);
01647 
01648         *lines_size = current_line;
01649         return lines;
01650 }

Here is the call graph for this function:

Here is the caller graph for this function:

void free_blocks (  ) 

Definition at line 2361 of file simulate_blif.c.

02362 {
02363         while (!is_empty(blocks))
02364         {
02365                 void *handle;
02366 
02367                 handle= dequeue_item(blocks);
02368 
02369                 dlclose(handle);
02370         }
02371 }

Here is the call graph for this function:

Here is the caller graph for this function:

void free_lines ( line_t **  lines,
int  lines_size 
)

Definition at line 1770 of file simulate_blif.c.

01771 {
01772         int i;
01773         for (i = 0; i < lines_size; i++)
01774         {
01775                 free(lines[i]->name);
01776                 free(lines[i]->pins);
01777                 free(lines[i]);
01778         }
01779         free(lines);
01780 }

Here is the caller graph for this function:

long int get_value_from_string ( char *  token  ) 
int has_node_been_computed_for_cycle ( nnode_t node,
int  cycle 
)

Definition at line 282 of file simulate_blif.c.

00283 {
00284         int i;
00285 
00286         for (i = 0; i < node->num_output_pins; i++)
00287         {
00288                 if (node->output_pins[i] != NULL)
00289                         if (node->output_pins[i]->sim_state->cycle < cycle)
00290                                 return FALSE;
00291         }
00292         return TRUE;
00293 }

void instantiate_memory ( nnode_t node,
int **  memory,
int  data_width,
int  addr_width 
)

Definition at line 2295 of file simulate_blif.c.

02296 {
02297         long long int max_address;      
02298         FILE *mif = NULL;
02299         char *filename = node->name;
02300         char *input = (char *)malloc(sizeof(char)*BUFFER_MAX_SIZE);
02301         
02302         oassert (*memory == NULL);
02303 
02304         max_address = my_power(2, addr_width);
02305 
02306         *memory = (int *)malloc(sizeof(int)*max_address*data_width);
02307         memset(*memory, 0, sizeof(int)*max_address*data_width);
02308         filename = strrchr(filename, '+') + 1;
02309         strcat(filename, ".mif");
02310         if (filename == NULL)
02311         {
02312                 error_message(SIMULATION_ERROR, -1, -1, "Couldn't parse node name");
02313         }
02314         if (!(mif = fopen(filename, "r")))
02315         {
02316                 char *msg = (char *)malloc(sizeof(char)*100);
02317                 strcat(msg, "Couldn't open MIF file ");
02318                 strcat(msg, filename);
02319                 warning_message(SIMULATION_ERROR, -1, -1, msg);
02320                 free(msg);
02321                 return;
02322         }
02323 
02324         //Advance to content begin
02325         while (fgets(input, BUFFER_MAX_SIZE, mif))
02326                 if (strcmp(input, "Content\n") == 0) break;
02327         while (fgets(input, BUFFER_MAX_SIZE, mif))
02328         {
02329                 int i;
02330                 long long int addr_val, data_val;
02331                 char *colon;
02332                 char *semicolon;
02333                 char *addr = (char *)malloc(sizeof(char)*BUFFER_MAX_SIZE);
02334                 char *data = (char *)malloc(sizeof(char)*BUFFER_MAX_SIZE);
02335                 if (strcmp(input, "Begin\n") == 0) continue;
02336                 if (strcmp(input, "End;") == 0 ||
02337                         strcmp(input, "End;\n") == 0) continue;
02338                 colon = strchr(input, ':');
02339                 //copy into address string
02340                 strncpy(addr, input, (colon-input));
02341                 colon++; colon++;
02342                 semicolon = strchr(input, ';');
02343                 strncpy(data, colon, (semicolon-colon));
02344                 addr_val = strtol(addr, NULL, 10);
02345                 data_val = strtol(data, NULL, 16);
02346                 //printf("%d: %lld\n", addr_val, data_val);
02347                 for (i = 0; i < data_width; i++)
02348                 {
02349                         //extract binary value for position i out of data_val
02350                         int mask = (1 << ((data_width - 1) - i));
02351                         int val = (mask & data_val) > 0 ? 1 : 0;
02352                         int write_address = i + (addr_val * data_width);
02353                         data[write_address] = val;
02354                         //printf("Addr: %d; i: %d; val: %d; (mask: %d)\n", addr_val, i, val, mask);
02355                 }
02356         }
02357         
02358         fclose(mif);
02359 }

Here is the call graph for this function:

Here is the caller graph for this function:

int is_node_top_level ( netlist_t netlist,
nnode_t node 
)

Definition at line 1209 of file simulate_blif.c.

01210 {
01211         int i;
01212 
01213         for (i = 0; i < netlist->num_top_input_nodes; i++)
01214                 if (node == netlist->top_input_nodes[i])
01215                         return TRUE;
01216         for (i = 0; i < netlist->num_top_output_nodes; i++)
01217                 if (node == netlist->top_output_nodes[i])
01218                         return TRUE;
01219         return FALSE;
01220 }

Here is the caller graph for this function:

int * multiply_arrays ( int *  a,
int  a_length,
int *  b,
int  b_length 
)

Definition at line 2179 of file simulate_blif.c.

02180 {
02181         int *result, i, j;
02182         int result_size;
02183 
02184         /*
02185          * This is a confusing algorithm to understand; it is so because we could
02186          * be multiplying arbitrarily-long bit lengths, so we can't rely on storing
02187          * these values in a C data type. This is really just a shift-and-add algorithm
02188          *
02189          * Instead, we're going to take our two arrays, a and b. For each bit i in a,
02190          * if a[i] is a one, then we're going to add b to our result so far, but shifted
02191          * over i to the left.
02192          *
02193          * However, I don't want to deal with the addition of two binary numbers in the
02194          * middle of this for loop, so our result might look something like 1212111 for
02195          * values of a=1011 and b=1011. So, we need to fix that to be 10100111.
02196          *
02197          * We can loop through the result array from the LSB (0) to the MSB and, everytime
02198          * we encounter a non-binary value, subtract two until it's either zero or one.
02199          * Whenever we subtract two from it, add one to the value to our left (since two
02200          * at position i is equal to 1 in the position i+1). This essentially puts of
02201          * dealing with the carries until the very end; it adds all the carries up, then
02202          * deals with them all at once.
02203          */
02204 
02205         //initialize our result
02206         result_size = a_length + b_length;
02207         result = (int *)calloc(sizeof(int), result_size);
02208 
02209         //check for 1's in a
02210         for (i = 0; i < a_length; i++)
02211         {
02212                 if (a[i] == 1)
02213                 {
02214                         //for each one we find, add b << i to result
02215                         for (j = 0; j < b_length; j++)
02216                         {
02217                                 result[i+j] += b[j];
02218                         }
02219                 }
02220         }
02221 
02222         //deal with all of our carries
02223         for (i = 0; i < result_size; i++)
02224         {
02225                 //keep subtracting until we're binary at position i. We'll deal with position
02226                 //i+1 later, until we deal with everything.
02227                 while (result[i] > 1)
02228                 {
02229                         result[i] -= 2;
02230                         result[i+1]++;
02231                 }
02232         }
02233 
02234         return result;
02235 }

Here is the caller graph for this function:

line_t ** read_test_vector_headers ( FILE *  out,
int *  lines_size,
int  max_lines_size 
)

Definition at line 1697 of file simulate_blif.c.

01698 {
01699         char buffer [BUFFER_MAX_SIZE];
01700         char next;
01701         int buffer_length;
01702         int current_line;
01703         line_t **lines;
01704 
01705         lines = (line_t **)malloc(sizeof(line_t*)*max_lines_size);
01706 
01707         current_line = 0;
01708         buffer[0] = '\0';
01709         buffer_length = 0;
01710 
01711         //get our next character
01712         next = fgetc(in);
01713         while (TRUE)
01714         {
01715                 //if the next character is a space, tab or newline, then it's the end of our old token
01716                 if (next == ' ' || next == '\t' || next == '\n')
01717                 {
01718                         //if we haven't been reading in a token, we're either at the end of the
01719                         //line or we are in a space between tokens
01720                         if (buffer_length == 0)
01721                         {
01722                                 //newline means we've read this vector
01723                                 if (next == '\n')
01724                                         break;
01725                                 continue;
01726                         }
01727 
01728                         //if we get here, it's because we finished reading in a token
01729                         lines[current_line] = create_line(buffer);
01730 
01731                         current_line++;
01732                         buffer_length = 0;
01733 
01734                         if (next == '\n')
01735                                 break;
01736                 }
01737                 else
01738                 {
01739                         buffer[buffer_length] = next;
01740                         buffer_length++;
01741                         buffer[buffer_length] = '\0';
01742                 }
01743                 next = fgetc(in);
01744         }
01745         *lines_size = current_line;
01746         return lines;
01747 }

Here is the call graph for this function:

Here is the caller graph for this function:

void set_constant_pin_values ( netlist_t netlist,
int  cycle 
)

Definition at line 2059 of file simulate_blif.c.

02060 {       
02061         int i,j;
02062         nnode_t* temp_node;
02063         nnet_t * temp_net;
02064         npin_t * temp_pin;
02065         for (i = 0; i < netlist->num_clocks; i++)
02066         {
02067                 update_pin_value(netlist->clocks[i]->output_pins[0], cycle%2, cycle);
02068         }
02069         for (i = 0; i < netlist->gnd_node->num_input_pins; i++)
02070         {
02071                 update_pin_value(netlist->gnd_node->input_pins[i], 0, cycle);
02072         }
02073         for (i = 0; i < netlist->gnd_node->num_output_pins; i++)
02074         {                       
02075                 update_pin_value(netlist->gnd_node->output_pins[i], 0, cycle);  
02076                 // code added, for multiple gnd node that appears in ABC 
02077                 temp_net=netlist->gnd_node->output_pins[i]->net;
02078                 for(j=0;j<temp_net->num_fanout_pins;j++)
02079                 {
02080                         if(temp_net->fanout_pins[j]==NULL)
02081                         continue;                       
02082                         temp_node=temp_net->fanout_pins[j]->node;
02083                         if(temp_node ==NULL)
02084                         continue;
02085                         if(temp_node->type==GND_NODE)
02086                         {
02087         
02088                           //printf("gnd node detected\n");
02089                           //printf("node name :%s\n",temp_node->name); 
02090                           update_pin_value(temp_node->input_pins[0], 0, cycle);
02091                           update_pin_value(temp_node->output_pins[0], 0, cycle);
02092                         }
02093                 }
02094         }
02095         for (i = 0; i < netlist->vcc_node->num_input_pins; i++)
02096         {
02097                 update_pin_value(netlist->vcc_node->input_pins[i], 1, cycle);
02098         }       
02099         for (i = 0; i < netlist->vcc_node->num_output_pins; i++)
02100         {
02101                 update_pin_value(netlist->vcc_node->output_pins[i], 1, cycle);
02102                 // code added, for multiple VCC node that appears in ABC 
02103                 temp_net=netlist->gnd_node->output_pins[i]->net;
02104                 for(j=0;j<temp_net->num_fanout_pins;j++)
02105                 {
02106                         if(temp_net->fanout_pins[j]==NULL)
02107                         continue;
02108                         temp_node=temp_net->fanout_pins[j]->node;
02109                         if(temp_node ==NULL)
02110                         continue;
02111                         if(temp_node->type==VCC_NODE)
02112                         {
02113                           //printf("vcc node detected\n");
02114                           //printf("node name :%s\n",temp_node->name);
02115                           update_pin_value(temp_node->input_pins[0], 1, cycle);
02116                           update_pin_value(temp_node->output_pins[0], 1, cycle);
02117                         }
02118                 }
02119         }
02120         for (i = 0; i < netlist->pad_node->num_input_pins; i++)
02121         {
02122                 update_pin_value(netlist->pad_node->input_pins[i], 0, cycle);
02123         }
02124         for (i = 0; i < netlist->pad_node->num_output_pins; i++)
02125         {
02126                 update_pin_value(netlist->pad_node->output_pins[i], 0, cycle);
02127         }
02128 }

Here is the call graph for this function:

Here is the caller graph for this function:

void simulate_blif ( char *  test_vector_file_name,
netlist_t netlist 
)

Definition at line 95 of file simulate_blif.c.

00096 {
00097         FILE *in;
00098         char buffer[BUFFER_MAX_SIZE];
00099         int cycle, i, lines_size;
00100         line_t **lines;
00101 
00102         sim_type = TEST_EXISTING_VECTORS;
00103         sim_result = TRUE;              //we're going to assume that everything goes OK for now
00104         modelsim_out = NULL;
00105         blocks = create_queue();
00106 
00107         //open our file
00108         in = fopen(test_vector_file_name, "r");
00109         if (in == NULL)
00110         {
00111                 error_message(SIMULATION_ERROR, -1, -1, "Could not open input vectors file %s\n", test_vector_file_name);
00112         }
00113 
00114         //lines is an array of line_t structs that store a name and an array of pins
00115         lines = read_test_vector_headers(in, &lines_size, netlist->num_top_input_nodes + netlist->num_top_output_nodes);
00116 
00117         //for each top input node, map it to a line
00118         for (i = 0; i < netlist->num_top_input_nodes; i++)
00119                 assign_node_to_line(netlist->top_input_nodes[i], lines, lines_size, INPUT);
00120         //for each top output node, map it to a line
00121         for (i = 0; i < netlist->num_top_output_nodes; i++)
00122                 assign_node_to_line(netlist->top_output_nodes[i], lines, lines_size, OUTPUT);
00123 
00124         for (i = 0; i < lines_size; i++)
00125         {
00126                 int j;
00127                 for (j = 0; j < lines[i]->number_of_pins; j++)
00128                 {
00129                         if (NULL == lines[i]->pins[j])
00130                         {
00131                                 warning_message(SIMULATION_ERROR, -1, -1, "A line has a NULL pin. This may cause a segfault. This can be caused when registers are declared as reg [X:Y], where Y is greater than zero.");
00132                         }
00133                 }
00134         }
00135 
00136         //get a line from our input vectors file and do stuff with it
00137         cycle = 0;
00138         while (fgets(buffer, BUFFER_MAX_SIZE, in) != NULL)
00139         {
00140                 //continues while we can still read lines from the test vector file
00141 #ifdef DEBUG_SIMULATOR
00142                 printf("Cycle: %d\nRead in from file: %s", cycle, buffer);
00143 #endif
00144 
00145                 //assigns the test values for the input lines ONLY
00146                 assign_input_vector_to_lines(lines, buffer, cycle);
00147 
00148 #ifdef DEBUG_SIMULATOR
00149                 int m,n;
00150                 for (m = 0; m < lines_size; m++)
00151                 {
00152                         printf("Line %s pin values %d through 0: ", lines[m]->name, lines[m]->number_of_pins-1);
00153                         for (n = lines[m]->number_of_pins -1; n >= 0; n--)
00154                         {
00155                                 printf("%d", lines[m]->pins[n]->sim_state->value);
00156                         }
00157                         printf("\n");
00158                 }
00159 #endif
00160 
00161                 simulate_cycle(netlist, cycle);
00162                 //checks that the output test values match what we simulated
00163                 verify_output_vectors(netlist, lines, lines_size, cycle);
00164 
00165                 cycle++;
00166         }
00167 
00168         //if something went wrong, let the user know. They'll have to search the output
00169         //for specifics
00170         if (!sim_result)
00171         {
00172                 printf("\nSimulation Error\n");
00173                 fprintf(stderr, "Simulation produced invalid data against the test vectors. Please see stderr output for details.");
00174         }
00175 
00176         fclose(in);
00177         free_lines(lines, lines_size);
00178         free_blocks();
00179 }

Here is the call graph for this function:

Here is the caller graph for this function:

void simulate_cycle ( netlist_t netlist,
int  cycle 
)

Definition at line 298 of file simulate_blif.c.

00299 {
00300         int i;
00301         queue_t *q;
00302         q = create_queue();
00303 
00304 #ifndef DEBUG_SIMULATOR
00305         printf(".");
00306 #endif
00307 
00308         //we're going to assign out constant pin values and enqueue those nodes
00309         set_constant_pin_values(netlist, cycle);
00310         enqueue_item(q, (void *)netlist->gnd_node);
00311         enqueue_item(q, (void *)netlist->pad_node);
00312         enqueue_item(q, (void *)netlist->vcc_node);
00313         //we're assuming that the top_input_nodes have had their values updated.
00314         for (i = 0; i < netlist->num_top_input_nodes; i++)
00315         {
00316                 enqueue_item(q, (void *)netlist->top_input_nodes[i]);
00317         }
00318 
00319 
00320         for (i = 0; i < netlist->gnd_node->num_output_pins; i++)
00321         {
00322                 int j;
00323                 if (netlist->gnd_node->output_pins[i] == NULL ||
00324                                 netlist->gnd_node->output_pins[i]->net == NULL)
00325                         continue;
00326                 for (j = 0; j < netlist->gnd_node->output_pins[i]->net->num_fanout_pins; j++)
00327                 {
00328                         if (netlist->gnd_node->output_pins[i]->net->fanout_pins[j] == NULL ||
00329                                         netlist->gnd_node->output_pins[i]->net->fanout_pins[j]->node == NULL)
00330                                 continue;
00331                         enqueue_item(q, (void *)netlist->gnd_node->output_pins[i]->net->fanout_pins[j]->node);
00332                 }
00333         }
00334 
00335         for (i = 0; i < netlist->vcc_node->num_output_pins; i++)
00336         {
00337                 int j;
00338                 if (netlist->vcc_node->output_pins[i] == NULL ||
00339                                 netlist->vcc_node->output_pins[i]->net == NULL)
00340                         continue;
00341                 for (j = 0; j < netlist->vcc_node->output_pins[i]->net->num_fanout_pins; j++)
00342                 {
00343                         if (netlist->vcc_node->output_pins[i]->net->fanout_pins[j] == NULL ||
00344                                         netlist->vcc_node->output_pins[i]->net->fanout_pins[j]->node == NULL)
00345                                 continue;
00346                         enqueue_item(q, (void *)netlist->vcc_node->output_pins[i]->net->fanout_pins[j]->node);
00347                 }
00348         }
00349         
00350         
00351         //We're going to go through all of our flip flops before the rest of our circuit in order to 
00352         //update their values first
00353         for (i = 0; i < netlist->num_ff_nodes; i++)
00354         {
00355                 nnode_t *node;
00356                 
00357                 node = netlist->ff_nodes[i];
00358                 
00359                 oassert(node->num_output_pins == 1);
00360                 oassert(node->num_input_pins == 2);
00361                 //If we get our inpt directly from input pins, then ouput that input's current (updated) value
00362                 if (is_node_top_level(netlist, node->input_pins[0]->net->driver_pin->node))
00363                 {
00364                         update_pin_value(node->output_pins[0], node->input_pins[0]->sim_state-> value, cycle);
00365                 }
00366                 //If we get our input from another node, then output that inpput's previous value
00367                 else
00368                 {
00369                         update_pin_value(node->output_pins[0], node->input_pins[0]->sim_state->prev_value, cycle);
00370                 }
00371                 
00372                 /*
00373                 Here's the problem: we're updating the input pins and we need, on the subsequent cycle,
00374                 to output that value. Right now, we're outputing that input node's _previous_ value.
00375                 We're doing this because values that come directly from input pins need to be handled.
00376                 What we need to do is actually check if the node is directly under an input pin.
00377                 */
00378         }
00379 
00380         while (!is_empty(q))
00381         {
00382                 nnode_t *node;
00383                 int try_again_later, already_calculated;
00384 
00385                 try_again_later = FALSE;
00386                 already_calculated = FALSE;
00387 
00388                 node = (nnode_t *)dequeue_item(q);
00389 
00390                 if (NULL == node)
00391                 {
00392                         warning_message(SIMULATION_ERROR, -1, -1, "Dequeued NULL node\n");
00393                 }
00394 
00395                 //Check if we've already calculated it's new value
00396                 for (i = 0; i < node->num_output_pins; i++)
00397                 {
00398                         if (NULL != node->output_pins[i])
00399                                 if (node->output_pins[i]->sim_state->cycle >= cycle)
00400                                         already_calculated = TRUE;
00401                 }
00402                 if (already_calculated
00403                                 && !is_node_top_level(netlist, node)
00404                                 && node->type != FF_NODE)
00405                 {
00406                                 continue;
00407                 }
00408                 //Check if we're ready to calculate it's new value
00409                 for (i = 0; i < node->num_input_pins; i++)
00410                 {
00411                         //have we computed everything we need to for the inputs?
00412                         if (node->input_pins[i]->sim_state->cycle < cycle)
00413                         {
00414                                 if (node->input_pins[i]->net->driver_pin->node->type == GND_NODE 
00415                                         ||      strcmp(node->input_pins[i]->net->driver_pin->node->name, RESET_PORT_NAME) == 0)
00416                                 {
00417                                         update_pin_value(node->input_pins[i], node->input_pins[i]->sim_state->value, cycle);
00418                                 }
00419                                 else if (node->input_pins[i]->net->driver_pin->node->type == VCC_NODE ||
00420                                                 node->input_pins[i]->net->driver_pin->node->type == PAD_NODE)
00421                                 {
00422                                         update_pin_value(node->input_pins[i], node->input_pins[i]->sim_state->value, cycle);
00423                                 }
00424                                 else
00425                                 {
00426                                         try_again_later = TRUE;
00427                                         //enqueue_item(q, node->input_pins[i]->net->driver_pin->node);
00428 #ifdef DEBUG_SIMULATOR
00429                                         printf("%s still needs %s to be calculated. Re-enqueing. \n", node->name, node->input_pins[i]->net->driver_pin->node->name);
00430                                         printf("queue size: %d \n", q->count);
00431 #endif
00432                                 }
00433 
00434                         }
00435                 }
00436 
00437                 /*
00438                 if (try_again_later == TRUE &&
00439                                                 node->type == FF_NODE)
00440                 {
00441                         //check and see if the clock value is updated
00442                         if (node->input_pins[1]->sim_state->cycle == cycle)
00443                                 try_again_later = FALSE;
00444                 }
00445                 */
00446 
00447                 //On the first clock cycle, let memories be computed so that output values stabilize
00448                 if (try_again_later == TRUE &&
00449                                                 node->type == MEMORY && cycle == 0)
00450                 {
00451                         try_again_later = FALSE;
00452                 }
00453 
00454                 if (try_again_later == TRUE)
00455                 {
00456                         enqueue_item(q, node);
00457                         continue;
00458                 }
00459 
00460                 compute_and_store_value(node, cycle);
00461 
00462                 //enqueue each child node for computation
00463                 for (i = 0; i < node->num_output_pins; i++)
00464                 {
00465                         int j;
00466                         nnet_t *net;
00467 
00468                         //follow the output pins to their net, and follow its fanout pins to the nodes
00469                         net = node->output_pins[i]->net;
00470                         if (NULL == net)
00471                         {
00472                                 //this happens because top-level output nodes have outpins pins w/o nets
00473                                 continue;
00474                         }
00475 
00476                         for (j = 0; j < net->num_fanout_pins; j++)
00477                         {
00478                                 if (NULL == net->fanout_pins[j])
00479                                         continue;
00480                                 //both of these subsequent checks are absolutely necessary, because either is possible
00481                                 if (net->fanout_pins[j]->type == INPUT)
00482                                         if (net->fanout_pins[j]->node != NULL)
00483                                                 enqueue_item(q, net->fanout_pins[j]->node);
00484                         }
00485                 }
00486         }
00487 
00488         //free our memory
00489         destroy_queue(q);
00490 }

Here is the call graph for this function:

Here is the caller graph for this function:

void simulate_new_vectors ( int  num_test_vectors,
netlist_t netlist 
)

Definition at line 187 of file simulate_blif.c.

00188 {
00189         FILE *iv, *outv;
00190         int cycle, lines_size;
00191         line_t **lines;
00192         int i;
00193 
00194         sim_type = GENERATE_VECTORS;
00195 
00196         blocks = create_queue();
00197 
00198         //open the input and output vector files
00199         iv = fopen(INPUT_VECTOR_FILE_NAME, "w");
00200         if (NULL == iv)
00201         {
00202                 error_message(SIMULATION_ERROR, -1, -1, "Could not write to input vectors file %s\n", INPUT_VECTOR_FILE_NAME);
00203         }
00204         outv = fopen(OUTPUT_VECTOR_FILE_NAME, "w");
00205         if (NULL == outv)
00206         {
00207                 error_message(SIMULATION_ERROR, -1, -1, "Could not write to output vectors file %s\n", OUTPUT_VECTOR_FILE_NAME);
00208         }
00209         modelsim_out = fopen("test.do", "w");
00210         if (NULL == modelsim_out)
00211         {
00212                 error_message(SIMULATION_ERROR, -1, -1, "Could not write to modelsim output file\n");
00213         }
00214 
00215         fprintf(modelsim_out, "force clock 1 0, 0 50 -repeat 100\n");
00216 
00217         //lines will be an array representing the I/O lines of our netlist
00218         lines = create_test_vector_lines(&lines_size, netlist);
00219 
00220         for (i = 0; i < lines_size; i++)
00221         {
00222                 int j;
00223                 for (j = 0; j < lines[i]->number_of_pins; j++)
00224                 {
00225                         if (NULL == lines[i]->pins[j])
00226                         {
00227                                 warning_message(SIMULATION_ERROR, -1, -1, "A line has a NULL pin. This may cause a segfault.This can be caused when registers are declared as reg [X:Y], where Y is greater than zero.");
00228                         }
00229                 }
00230         }
00231 
00232         //write the headers (names of I/O lines) to vector files
00233         //this is the same format that we're expecting to read in to verify
00234         //these later
00235         write_vector_headers(iv, outv, lines, lines_size);
00236 
00237         //used to generate random test vectors
00238         srand((unsigned)(time(0)));
00239         
00240         for (cycle = 0; cycle < num_test_vectors; cycle++)
00241         {
00242 #ifdef DEBUG_SIMULATOR
00243                 int i;
00244 #endif
00245                 
00246                 assign_random_vector_to_input_lines(lines, lines_size, cycle);
00247 
00248 #ifdef DEBUG_SIMULATOR
00249                 printf("Cycle: %d\n", cycle);
00250                 for (i = 0; i < lines_size; i++)
00251                 {
00252                         int j;
00253 
00254                         if (lines[i]->type == OUTPUT)
00255                                 continue;
00256 
00257                         printf("Values for line %s from %d to 0: ", lines[i]->name, lines[i]->number_of_pins);
00258 
00259                         for (j = 0; j < lines[i]->number_of_pins; j++)
00260                         {
00261                                 printf("%d", lines[i]->pins[j]->sim_state->value);
00262                         }
00263 
00264                         printf("\n");
00265                 }
00266 #endif
00267 
00268                 write_vectors_to_file(lines, lines_size, iv, INPUT, cycle);
00269                 simulate_cycle(netlist, cycle);
00270                 write_vectors_to_file(lines, lines_size, outv, OUTPUT, cycle);
00271         }
00272 
00273         fprintf(modelsim_out, "run %d\n", cycle*101);
00274 
00275         fclose(iv);
00276         fclose(outv);
00277         fclose(modelsim_out);
00278         free_lines(lines, lines_size);
00279         free_blocks();
00280 }

Here is the call graph for this function:

Here is the caller graph for this function:

void store_value_in_line ( char *  token,
line_t *  line,
int  cycle 
)

Definition at line 1230 of file simulate_blif.c.

01231 {
01232         int i, j, k;
01233         oassert(token != NULL);
01234         oassert(strlen(token) != 0);
01235 
01236         //This shouldn't happen because lines are mapped *from* the top_input/output_nodes
01237         if (line->number_of_pins < 1)
01238         {
01239                 warning_message(SIMULATION_ERROR, -1, -1, "Found a line '%s' with no pins.", line->name);
01240                 return;
01241         }
01242 
01243         if (strlen(token) == 1)
01244         {
01245                 /*
01246                  * means that there is only one pin, so we can assume the only input is either 0 or 1
01247                  */
01248                 if (token[0] == '0')
01249                         update_pin_value(line->pins[0], 0, cycle);
01250                 else if (token[0] == '1')
01251                         update_pin_value(line->pins[0], 1, cycle);
01252                 else
01253                         update_pin_value(line->pins[0], -1, cycle);
01254 
01255                 return;
01256         }
01257 
01258         /*
01259          * means that we have more than one pin
01260          * token may be a string of 0's and 1's or a hex value
01261          */
01262         if (token[0] == '0' && (token[1] == 'x' || token[1] == 'X'))
01263         {       //this is a hex string
01264                 int token_length;
01265 
01266                 token += 2;     //gets rid of the 0x prefix
01267                 token_length = strlen(token);
01268 
01269                 //we're reversing the token, so "0x9A6" becomes "6A9"
01270                 //this makes processing this value and storing it easier
01271                 i = 0, j = token_length - 1;
01272                 while(i < j)
01273                 {
01274                         char temp;
01275                         temp = token[i];
01276                         token[i] = token [j];
01277                         token[j] = temp;
01278                         i++; j--;
01279                 }
01280 
01281                 //from the least-significant character in the hex string to the most significant
01282                 for (i = 0; i < token_length; i++)
01283                 {
01284                         int value;
01285                         char temp[2];
01286 
01287                         //store our character in it's own 'string'
01288                         temp[0] = token[i];
01289                         temp[1] = '\0';
01290 
01291                         value = strtol(temp, NULL, 16);
01292 
01293                         //value is a int between 0 and 15 whose binary representation is the vaue for 4 pins
01294                         for (k = 0; k < 4 && k + (i*4) < line->number_of_pins; k++)
01295                         {
01296                                 int pin_value;
01297 
01298                                 pin_value = (value & (1 << k)) > 0 ? 1 : 0;
01299                                 update_pin_value(line->pins[k + (i*4)], pin_value, cycle);
01300                         }
01301                 }
01302 
01303                 //this ensures every pin that wasn't updated already is updated, for this cycle
01304                 for (; k + (i*4) < line->number_of_pins; k++)
01305                         update_pin_value(line->pins[k + (i*4)], line->pins[k + (i*4)]->sim_state->value, cycle);
01306         }
01307         else
01308         {       //this is a string of 1's and 0's
01309                 for (i = strlen(token) - 1, j = 0; i >= 0 && j < line->number_of_pins; i--, j++)
01310                 {
01311                         if (token[i] == '0')
01312                                 update_pin_value(line->pins[j], 0, cycle);
01313                         else if (token[i] == '1')
01314                                 update_pin_value(line->pins[j], 1, cycle);
01315                         else
01316                                 update_pin_value(line->pins[j], -1, cycle);
01317                 }
01318                 for (; j < line->number_of_pins; j++)
01319                         update_pin_value(line->pins[j], -1, cycle);
01320         }
01321 }

Here is the call graph for this function:

Here is the caller graph for this function:

void update_pin_value ( npin_t pin,
int  value,
int  cycle 
)

Definition at line 2133 of file simulate_blif.c.

02134 {
02135         int i;
02136 
02137         oassert(pin != NULL);
02138 
02139         if (pin->sim_state->cycle == cycle)
02140         {
02141                 oassert(pin->sim_state->value == value);
02142         }
02143 
02144 
02145         //update the sim state of THIS pin
02146         pin->sim_state->prev_value = pin->sim_state->value;
02147         pin->sim_state->value = value;
02148         pin->sim_state->cycle = cycle;
02149 
02150         //if this pin drives a net, we need to update that net's fanout pins
02151         if (NULL == pin->net)
02152         {
02153                 //we're updating an output pin of an output node, most likely
02154                 return;
02155         }
02156         for (i = 0; i < pin->net->num_fanout_pins; i++)
02157         {
02158                 npin_t *fanout_pin;
02159 
02160                 //sometimes, fanout pins of nets are NULL
02161                 if (NULL == pin->net->fanout_pins[i])
02162                         continue;
02163 
02164                 fanout_pin = pin->net->fanout_pins[i];
02165 
02166                 fanout_pin->sim_state->prev_value = fanout_pin->sim_state->value;
02167                 fanout_pin->sim_state->value = value;
02168                 fanout_pin->sim_state->cycle = cycle;
02169         }
02170 }

Here is the caller graph for this function:

int verify_output_vectors ( netlist_t netlist,
line_t **  lines,
int  lines_size,
int  cycle 
)

Definition at line 2005 of file simulate_blif.c.

02006 {
02007         int i, j;
02008         int problems = FALSE;
02009 
02010         for (i = 0; i < lines_size; i++)
02011         {
02012                 if (lines[i]->type == INPUT)
02013                         continue;
02014 
02015                 //typically, we'll only have one pin, but I want to check
02016                 for (j = 0; j < lines[i]->number_of_pins; j++)
02017                 {
02018                         npin_t *input_pin, *output_pin;
02019 
02020                         output_pin = lines[i]->pins[j];
02021                         input_pin = output_pin->node->input_pins[output_pin->pin_node_idx];
02022 
02023                         //check if we have the same value
02024                         if (input_pin->sim_state->value != output_pin->sim_state->value)
02025                         {
02026                                 fprintf(stderr, "Simulation Value mismatch at node %s. Expected %d but encountered %d on cycle %d.\n",
02027                                                 output_pin->node->name,
02028                                                 output_pin->sim_state->value,
02029                                                 input_pin->sim_state->value,
02030                                                 cycle);
02031                                 problems = TRUE;
02032                         }
02033 
02034                         //check if we're all at the same cycle
02035                         if (input_pin->sim_state->cycle != output_pin->sim_state->cycle ||
02036                                         input_pin->sim_state->cycle != cycle)
02037                         {
02038                                 fprintf(stderr, "Simulation cycle mismatch at node %s. Expected cycle %d but encountered cycle %d on actual cycle %d.\n",
02039                                                 output_pin->node->name,
02040                                                 output_pin->sim_state->cycle,
02041                                                 input_pin->sim_state->cycle,
02042                                                 cycle);
02043                                 problems = TRUE;
02044                         }
02045                 }
02046         }
02047 
02048         //update gobal flag
02049         if (problems)
02050                 sim_result = FALSE;
02051 
02052         return !problems;
02053 }

Here is the caller graph for this function:

void write_vector_headers ( FILE *  iv,
FILE *  outv,
line_t **  lines,
int  lines_size 
)

Definition at line 1657 of file simulate_blif.c.

01658 {
01659         int i, first_in, first_out;
01660 
01661         first_in = TRUE;
01662         first_out = TRUE;
01663 
01664         //the first time, we print out the name; subsequently, we print
01665         //out a space, then the name, so the output files can be re-read
01666         for (i = 0; i < lines_size; i++)
01667         {
01668                 if (lines[i]->type == INPUT)
01669                 {
01670                         if (first_in == TRUE)
01671                         {
01672                                 fprintf(iv, "%s", lines[i]->name);
01673                                 first_in = FALSE;
01674                                 continue;
01675                         }
01676                         fprintf(iv, " %s", lines[i]->name);
01677                 }
01678                 else    //lines[i]->type == OUTPUT
01679                 {
01680                         if (first_out == TRUE)
01681                         {
01682                                 fprintf(outv, "%s", lines[i]->name);
01683                                 first_out = FALSE;
01684                                 continue;
01685                         }
01686                         fprintf(outv, " %s", lines[i]->name);
01687                 }
01688         }
01689         fprintf(iv, "\n");
01690         fprintf(outv, "\n");
01691 }

Here is the caller graph for this function:

void write_vectors_to_file ( line_t **  lines,
int  lines_size,
FILE *  file,
int  type,
int  cycle 
)

Definition at line 1864 of file simulate_blif.c.

01865 {
01866         int i, first;
01867 
01868         first = TRUE;
01869 
01870         for (i = 0; i < lines_size; i++)
01871         {
01872                 if (lines[i]->type != type)
01873                         continue;
01874 
01875                 //the first vector is printed alone, the rest are prefixed by a space
01876                 if (first)
01877                         first = FALSE;
01878                 else
01879                         fprintf(file, " ");
01880 
01881                 if (lines[i]->number_of_pins == 1)      //single-bit
01882                 {
01883                         npin_t *pin;
01884 
01885                         //we make this distinction because sometimes extra padding, say,
01886                         //with mutlipliers, will overwrite values on OUTPUT nodes. This gets
01887                         //the true value from the net that drives this pin
01888                         if (type == INPUT)
01889                                 pin = lines[i]->pins[0];
01890                         else //type == OUTPUT
01891                                 pin = lines[i]->pins[0]->node->input_pins[lines[i]->pins[0]->pin_node_idx];
01892 
01893                         if (pin->sim_state->value < 0)
01894                                 fprintf(file, "x");
01895                         else
01896                                 fprintf(file, "%d", pin->sim_state->value);
01897                         if (type == INPUT && NULL != modelsim_out)
01898                         {
01899                                 fprintf(modelsim_out, "force %s %d %d\n", lines[i]->name,pin->sim_state->value, cycle * 100 + 95);
01900                         }
01901                 }
01902                 else //multi-bit
01903                 {
01904                         int j, value, unknown;
01905 
01906                         value = 0;
01907                         unknown = FALSE;
01908 
01909                         if (type == INPUT)
01910                         {
01911                                 //check to see if we have any unknown values
01912                                 for (j = 0; j < lines[i]->number_of_pins; j++)
01913                                         if (lines[i]->pins[j]->sim_state->value < 0)
01914                                                 unknown = TRUE;
01915                         }
01916                         else
01917                         {
01918                                 for (j = 0; j < lines[i]->number_of_pins; j++)
01919                                 {
01920                                         if (lines[i]->pins[j]->node->input_pins[lines[i]->pins[j]->pin_node_idx]->sim_state->value < 0)
01921                                                 unknown = TRUE;
01922                                 }
01923                         }
01924 
01925                         if (unknown)
01926                         {
01927                                 /*
01928                                  * Since we have at least one 'unknown' bit, we can't print this out in hex.
01929                                  */
01930                                 for (j = lines[i]->number_of_pins - 1; j >= 0 ; j--)
01931                                 {
01932                                         npin_t *pin;
01933 
01934                                         //see above comment
01935                                         if (type == INPUT)
01936                                                 pin = lines[i]->pins[j];
01937                                         else //type == OUTPUT
01938                                                 pin = lines[i]->pins[j]->node->input_pins[lines[i]->pins[j]->pin_node_idx];
01939 
01940                                         if (pin->sim_state->value < 0)
01941                                                 fprintf(file, "x");
01942                                         else
01943                                                 fprintf(file, "%d", pin->sim_state->value);
01944                                         if (type == INPUT)
01945                                                 warning_message(SIMULATION_ERROR, -1, -1, "Tried to write an unknown value to the modelsim script. It's likely unreliable. \n");
01946                                 }
01947                                 continue;
01948                         }
01949 
01950                         //we're in hex
01951                         fprintf(file, "0x");
01952 
01953                         if (type == INPUT && NULL != modelsim_out)
01954                         {
01955                                 fprintf(modelsim_out, "force %s 16#", lines[i]->name);
01956                         }
01957 
01958                         //start at MSB-side of hex string
01959                         for (j = lines[i]->number_of_pins - 1; j >= 0; j--)
01960                         {
01961                                 npin_t *pin;
01962 
01963                                 //we make this distinction because sometimes extra padding, say,
01964                                 //with mutlipliers, will overwrite values on OUTPUT nodes. This gets
01965                                 //the true value from the net that drives this pin
01966                                 if (type == INPUT)
01967                                         pin = lines[i]->pins[j];
01968                                 else //type == OUTPUT
01969                                         pin = lines[i]->pins[j]->node->input_pins[lines[i]->pins[j]->pin_node_idx];
01970 
01971                                 //if we're a one, shift over by our place in the int
01972                                 if (pin->sim_state->value > 0)
01973                                         value += my_power(2, j % 4);
01974 
01975                                 //at each fourth bit (counting from the LSB-side of the array!!!
01976                                 //this is the opposite of our list traversal!!!), reset our value,
01977                                 //since 4 bits = hex character
01978                                 if (j % 4 == 0)
01979                                 {
01980                                         fprintf(file, "%X", value);
01981                                         if (type == INPUT && NULL != modelsim_out)
01982                                         {
01983                                                 fprintf(modelsim_out, "%X", value);
01984                                         }
01985                                         value = 0;
01986                                 }
01987                         }
01988                         if (type == INPUT && NULL != modelsim_out)
01989                         {
01990                                 fprintf(modelsim_out, " %d\n", cycle * 100 + 95);
01991                         }
01992                 }
01993         }
01994 
01995         fprintf(file, "\n");
01996 }

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

queue_t* blocks

Definition at line 88 of file simulate_blif.c.

FILE* modelsim_out

Definition at line 86 of file simulate_blif.c.

Definition at line 85 of file simulate_blif.c.

Definition at line 84 of file simulate_blif.c.

Generated on Tue Aug 2 10:43:49 2011 for ODIN_II by  doxygen 1.6.3