00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <string.h>
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 #include <stdarg.h>
00028 #include <time.h>
00029 #include <dlfcn.h>
00030 #include "sim_block.h"
00031 #include "types.h"
00032 #include "globals.h"
00033 #include "errors.h"
00034 #include "netlist_utils.h"
00035 #include "odin_util.h"
00036 #include "outputs.h"
00037 #include "util.h"
00038 #include "multipliers.h"
00039 #include "hard_blocks.h"
00040 #include "simulate_blif.h"
00041 #include "types.h"
00042 #include "queue.h"
00043
00044 #define BUFFER_MAX_SIZE 1024
00045
00046
00047
00048
00049 #define CLOCK_PORT_NAME_1 "clock"
00050 #define CLOCK_PORT_NAME_2 "clk"
00051 #define RESET_PORT_NAME "reset_n"
00052
00053 #define SINGLE_PORT_MEMORY_NAME "single_port_ram"
00054 #define DUAL_PORT_MEMORY_NAME "dual_port_ram"
00055
00056 void simulate_cycle(netlist_t *netlist, int cycle);
00057 void store_value_in_line(char *token, line_t *line, int cycle);
00058 void assign_node_to_line(nnode_t *node, line_t **lines, int lines_size, int type);
00059 line_t** read_test_vector_headers(FILE *out, int *lines_size, int max_lines_size);
00060 long int get_value_from_string(char *token);
00061 int is_node_top_level(netlist_t *netlist, nnode_t *node);
00062 void compute_and_store_value(nnode_t *node, int cycle);
00063 void free_lines(line_t **lines, int lines_size);
00064 void assign_input_vector_to_lines(line_t **lines, char *buffer, int cycle);
00065 void assign_random_vector_to_input_lines(line_t **lines, int lines_size, int cycle);
00066 void write_vectors_to_file(line_t **lines, int lines_size, FILE *file, int type, int cycle);
00067 line_t **create_test_vector_lines(int *lines_size, netlist_t *netlist);
00068 int verify_output_vectors(netlist_t *netlist, line_t **lines, int lines_size, int cycle);
00069 line_t *create_line(char *name);
00070 int has_node_been_computed_for_cycle(nnode_t *node, int cycle);
00071 void write_vector_headers(FILE *iv, FILE *outv, line_t **lines, int lines_size);
00072
00073 void set_constant_pin_values(netlist_t *netlist, int cycle);
00074 void update_pin_value(npin_t *pin, int value, int cycle);
00075
00076 int *multiply_arrays(int *a, int a_length, int *b, int b_length);
00077 void compute_memory(npin_t **inputs, npin_t **outputs,
00078 int data_width, npin_t **addr, int addr_width, int we, int clock, int cycle, int *data);
00079
00080 void instantiate_memory(nnode_t *node, int **memory, int data_width, int addr_width);
00081
00082 void free_blocks();
00083
00084 simulation_type sim_type;
00085 int sim_result;
00086 FILE *modelsim_out;
00087
00088 queue_t *blocks;
00089
00090
00091
00092
00093
00094
00095 void simulate_blif (char *test_vector_file_name, netlist_t *netlist)
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;
00104 modelsim_out = NULL;
00105 blocks = create_queue();
00106
00107
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
00115 lines = read_test_vector_headers(in, &lines_size, netlist->num_top_input_nodes + netlist->num_top_output_nodes);
00116
00117
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
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
00137 cycle = 0;
00138 while (fgets(buffer, BUFFER_MAX_SIZE, in) != NULL)
00139 {
00140
00141 #ifdef DEBUG_SIMULATOR
00142 printf("Cycle: %d\nRead in from file: %s", cycle, buffer);
00143 #endif
00144
00145
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
00163 verify_output_vectors(netlist, lines, lines_size, cycle);
00164
00165 cycle++;
00166 }
00167
00168
00169
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 }
00180
00181
00182
00183
00184
00185
00186
00187 void simulate_new_vectors (int num_test_vectors, netlist_t *netlist)
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
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
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
00233
00234
00235 write_vector_headers(iv, outv, lines, lines_size);
00236
00237
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 }
00281
00282 int has_node_been_computed_for_cycle(nnode_t *node, int cycle)
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 }
00294
00295
00296
00297
00298 void simulate_cycle(netlist_t *netlist, int cycle)
00299 {
00300 int i;
00301 queue_t *q;
00302 q = create_queue();
00303
00304 #ifndef DEBUG_SIMULATOR
00305 printf(".");
00306 #endif
00307
00308
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
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
00352
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
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
00367 else
00368 {
00369 update_pin_value(node->output_pins[0], node->input_pins[0]->sim_state->prev_value, cycle);
00370 }
00371
00372
00373
00374
00375
00376
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
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
00409 for (i = 0; i < node->num_input_pins; i++)
00410 {
00411
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
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
00439
00440
00441
00442
00443
00444
00445
00446
00447
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
00463 for (i = 0; i < node->num_output_pins; i++)
00464 {
00465 int j;
00466 nnet_t *net;
00467
00468
00469 net = node->output_pins[i]->net;
00470 if (NULL == net)
00471 {
00472
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
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
00489 destroy_queue(q);
00490 }
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500 void compute_and_store_value(nnode_t *node, int cycle)
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
00516
00517
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
00545
00546
00547 switch(node->type)
00548 {
00549 case LT:
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:
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:
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:
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
00838
00839
00840
00841
00842
00843
00844
00845
00846
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
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();
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
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
01036 (node->simulate_block_cycle)(cycle, node->num_input_pins, input_pins, node->num_output_pins, output_pins);
01037
01038
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
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
01082 result = multiply_arrays(a, node->input_port_sizes[0], b, node->input_port_sizes[1]);
01083
01084
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
01091 free(result);
01092 free(a);
01093 free(b);
01094 return;
01095 }
01096
01097
01098 case GENERIC :
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
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
01205 error_message(SIMULATION_ERROR, -1, -1, "Node should have been converted to softer version: %s", node->name);
01206 }
01207 }
01208
01209 int is_node_top_level(netlist_t *netlist, nnode_t *node)
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 }
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230 void store_value_in_line(char *token, line_t *line, int cycle)
01231 {
01232 int i, j, k;
01233 oassert(token != NULL);
01234 oassert(strlen(token) != 0);
01235
01236
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
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
01260
01261
01262 if (token[0] == '0' && (token[1] == 'x' || token[1] == 'X'))
01263 {
01264 int token_length;
01265
01266 token += 2;
01267 token_length = strlen(token);
01268
01269
01270
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
01282 for (i = 0; i < token_length; i++)
01283 {
01284 int value;
01285 char temp[2];
01286
01287
01288 temp[0] = token[i];
01289 temp[1] = '\0';
01290
01291 value = strtol(temp, NULL, 16);
01292
01293
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
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 {
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 }
01322
01323
01324
01325
01326
01327 void assign_node_to_line(nnode_t *node, line_t **lines, int lines_size, int type)
01328 {
01329 int j, found;
01330 int pin_number;
01331 char *port_name;
01332 char *tilde;
01333
01334
01335 port_name = (char *)malloc(sizeof(char)*strlen(node->name));
01336
01337
01338 strcpy(port_name, strchr(node->name, '^') + 1);
01339
01340 tilde = strchr(port_name, '~');
01341
01342 if (tilde == FALSE)
01343 {
01344 found = FALSE;
01345
01346
01347
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
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
01376
01377
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
01396 pin_number = atoi(tilde+1);
01397 *tilde = '\0';
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
01414
01415
01416 if (lines[j]->max_number_of_pins < 0)
01417 {
01418
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
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
01436
01437
01438
01439 if (node->num_output_pins == 0)
01440 {
01441
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 }
01451
01452
01453
01454
01455
01456
01457
01458 line_t **create_test_vector_lines(int *lines_size, netlist_t *netlist)
01459 {
01460 line_t **lines;
01461 int i, j, current_line, pin_number, found;
01462 char *port_name, *tilde;
01463
01464
01465 current_line = 0;
01466
01467 lines = (line_t **)malloc(sizeof(line_t*)*(netlist->num_top_input_nodes + netlist->num_top_output_nodes));
01468
01469
01470 port_name = NULL;
01471
01472 for (i = 0; i < netlist->num_top_input_nodes; i++)
01473 {
01474
01475 if (NULL != port_name)
01476 free(port_name);
01477
01478
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
01483 tilde = strchr(port_name, '~');
01484 if (NULL == tilde)
01485 {
01486
01487 if (strcmp(port_name, CLOCK_PORT_NAME_1) == 0 ||
01488 strcmp(port_name, CLOCK_PORT_NAME_2) == 0)
01489
01490 continue;
01491
01492
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
01506
01507
01508
01509
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
01520
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--;
01534
01535
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
01543
01544
01545
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
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
01564
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)
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;
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
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
01627
01628
01629
01630
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 }
01651
01652
01653
01654
01655
01656
01657 void write_vector_headers(FILE *iv, FILE *outv, line_t **lines, int lines_size)
01658 {
01659 int i, first_in, first_out;
01660
01661 first_in = TRUE;
01662 first_out = TRUE;
01663
01664
01665
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
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 }
01692
01693
01694
01695
01696
01697 line_t** read_test_vector_headers(FILE *in, int *lines_size, int max_lines_size)
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
01712 next = fgetc(in);
01713 while (TRUE)
01714 {
01715
01716 if (next == ' ' || next == '\t' || next == '\n')
01717 {
01718
01719
01720 if (buffer_length == 0)
01721 {
01722
01723 if (next == '\n')
01724 break;
01725 continue;
01726 }
01727
01728
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 }
01748
01749
01750
01751
01752 line_t *create_line(char *name)
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 }
01766
01767
01768
01769
01770 void free_lines(line_t **lines, int lines_size)
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 }
01781
01782
01783
01784
01785
01786
01787 void assign_input_vector_to_lines(line_t **lines, char *buffer, int cycle)
01788 {
01789 const char *delim;
01790 int length, line_count;
01791 char *token;
01792
01793 delim = " \t";
01794 length = strlen(buffer);
01795
01796
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 }
01813
01814
01815
01816
01817
01818
01819
01820 void assign_random_vector_to_input_lines(line_t **lines, int lines_size, int cycle)
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 }
01859
01860
01861
01862
01863
01864 void write_vectors_to_file(line_t **lines, int lines_size, FILE *file, int type, int cycle)
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
01876 if (first)
01877 first = FALSE;
01878 else
01879 fprintf(file, " ");
01880
01881 if (lines[i]->number_of_pins == 1)
01882 {
01883 npin_t *pin;
01884
01885
01886
01887
01888 if (type == INPUT)
01889 pin = lines[i]->pins[0];
01890 else
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
01903 {
01904 int j, value, unknown;
01905
01906 value = 0;
01907 unknown = FALSE;
01908
01909 if (type == INPUT)
01910 {
01911
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
01929
01930 for (j = lines[i]->number_of_pins - 1; j >= 0 ; j--)
01931 {
01932 npin_t *pin;
01933
01934
01935 if (type == INPUT)
01936 pin = lines[i]->pins[j];
01937 else
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
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
01959 for (j = lines[i]->number_of_pins - 1; j >= 0; j--)
01960 {
01961 npin_t *pin;
01962
01963
01964
01965
01966 if (type == INPUT)
01967 pin = lines[i]->pins[j];
01968 else
01969 pin = lines[i]->pins[j]->node->input_pins[lines[i]->pins[j]->pin_node_idx];
01970
01971
01972 if (pin->sim_state->value > 0)
01973 value += my_power(2, j % 4);
01974
01975
01976
01977
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 }
01997
01998
01999
02000
02001
02002
02003
02004
02005 int verify_output_vectors(netlist_t *netlist, line_t **lines, int lines_size, int cycle)
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
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
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
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
02049 if (problems)
02050 sim_result = FALSE;
02051
02052 return !problems;
02053 }
02054
02055
02056
02057
02058
02059 void set_constant_pin_values(netlist_t *netlist, int cycle)
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
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
02089
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
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
02114
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 }
02129
02130
02131
02132
02133 void update_pin_value(npin_t *pin, int value, int cycle)
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
02146 pin->sim_state->prev_value = pin->sim_state->value;
02147 pin->sim_state->value = value;
02148 pin->sim_state->cycle = cycle;
02149
02150
02151 if (NULL == pin->net)
02152 {
02153
02154 return;
02155 }
02156 for (i = 0; i < pin->net->num_fanout_pins; i++)
02157 {
02158 npin_t *fanout_pin;
02159
02160
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 }
02171
02172
02173
02174
02175
02176
02177
02178
02179 int *multiply_arrays(int *a, int a_length, int *b, int b_length)
02180 {
02181 int *result, i, j;
02182 int result_size;
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206 result_size = a_length + b_length;
02207 result = (int *)calloc(sizeof(int), result_size);
02208
02209
02210 for (i = 0; i < a_length; i++)
02211 {
02212 if (a[i] == 1)
02213 {
02214
02215 for (j = 0; j < b_length; j++)
02216 {
02217 result[i+j] += b[j];
02218 }
02219 }
02220 }
02221
02222
02223 for (i = 0; i < result_size; i++)
02224 {
02225
02226
02227 while (result[i] > 1)
02228 {
02229 result[i] -= 2;
02230 result[i+1]++;
02231 }
02232 }
02233
02234 return result;
02235 }
02236
02237 void compute_memory(npin_t **inputs,
02238 npin_t **outputs,
02239 int data_width,
02240 npin_t **addr,
02241 int addr_width,
02242 int we,
02243 int clock,
02244 int cycle,
02245 int *data)
02246 {
02247 int address;
02248 int i;
02249
02250
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
02263
02264
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 }
02288
02289
02290
02291
02292
02293
02294
02295 void instantiate_memory(nnode_t *node, int **memory, int data_width, int addr_width)
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
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
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
02347 for (i = 0; i < data_width; i++)
02348 {
02349
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
02355 }
02356 }
02357
02358 fclose(mif);
02359 }
02360
02361 void free_blocks()
02362 {
02363 while (!is_empty(blocks))
02364 {
02365 void *handle;
02366
02367 handle= dequeue_item(blocks);
02368
02369 dlclose(handle);
02370 }
02371 }