#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"
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 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.
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
queue_t* blocks |
Definition at line 88 of file simulate_blif.c.
FILE* modelsim_out |
Definition at line 86 of file simulate_blif.c.
int sim_result |
Definition at line 85 of file simulate_blif.c.
Definition at line 84 of file simulate_blif.c.