/************************************************************************** NAME cubes.h PURPOSE This file contains the declarations for all the structures needed to contain the cubes and the pointers for all the program. Also all the variables that will be accessible by the main program and shared with the subroutines for cubes processing are defined as external. For all the files containing part of the program, the functions will be declared. COORDINATES McGill University Electrical Engineering VLSI lab MONTREAL CANADA 12 june 1984 AUTHOR Michel DAGENAIS ***************************************************************************/ #include #define LEAF 1 #define SUBTREE 2 #define BASIC 1 #define NOT_BASIC 254 #define DONT_CARE 128 #define _0_ 2 #define _1_ 1 #define _X_ 3 #define INFINITY 32000 /* STRUCTURES we first define the structures that will be used all around in the program */ /* Each cube will be a node in a graph, the structure node contains a cube plus different pointers to other nodes adjacents in the graph. */ struct node { struct node *next_node; /* point to next node in the list */ struct parent *ancestors; /* point to the list of ancestors */ struct parent *descendants; /* point to the list of descendant */ struct cube_list *uncovered; /* part of node uncovered by retained nodes */ short int status; /* a short word for status information */ short int cost; /* number of non x input in the cube */ long int count; /* pass count when the node was last visited */ long int cube[2]; /* cube of length to determine on allocation */ }; /* When we want to determine which part of a cube is covered, we sharp a certain number of other cubes and the result is a list of cubes describing the uncovered part of the original cube. The structure cube_list holds one such cube plus a pointer to the next cube in the list */ struct cube_list { struct cube_list *next_cube;/* point to next cube in the list */ long int cube[2]; /* cube of length to determine on allocation */ }; /* For the merging of impicants a new tree is used. The leaves of this tree are the node structures holding the cubes. The tree is composed of branches that point to leaves or to other branches. Each branch is for a certain input variable, all the cubes in that branch are directed depending on their value for that input to the 0 or 1 subtree. */ union cube_node { struct node *leaf; /* only one cube in this subtree so it is a leaf */ struct binary *subtree; /* there are more than one cube in the subtree we point to another binary node. */ }; struct branch { union cube_node _; short int status; }; struct binary { struct branch is0; /* status and pointer to the 0 subtree or cube*/ struct branch is1; /* status and pointer to the 1 subtree */ struct node *isx; /* pointer to the list of merged cubes */ short int var; /* number of the input variable considered */ }; /* The cubes in the graph are linked. Each node has a list of ancestors and descendants. Each element in this list is a structure parent containing a pointer to a related node plus a pointer to the next element in the ancestor or descendant list. */ struct parent { struct node *parent; /* point to a parent node */ struct parent *next_parent; /* point to the next parent in the list */ }; /* COMMON VARIABLES the variables described below will be used everywhere in the program and are listed file by file. */ /* Alloc.c */ struct node *alloc_node(); /* allocates a node */ int free_node(), /* release a node */ flush_node(), /* release all the nodes */ free_list_of_nodes(); /* release a list of nodes */ struct cube_list *alloc_cube_list(); /* allocates a cube_list structure */ int free_cube_list(), /* release a cube */ flush_cube_list(), /* release all the cubes */ free_list_of_cubes(); /* release a list of cubes */ struct binary *alloc_binary(); /* allocates a binary structure */ int free_binary(), /* release a binary structure */ flush_binary(); /* release them all */ struct parent *alloc_parent(); /* allocates a parent structure */ int free_parent(), /* release a parent structure */ flush_parent(), /* release all the parents */ free_list_of_parents(); /* release a list of parents */ extern int nb_alloc_parent, nb_alloc_cube_list, nb_alloc_binary, nb_alloc_nodes; /* Messages.c */ int fatal_user_error(), /* user made a terrible mistake */ fatal_system_error(), /* you should buy a new computer */ fatal_program_error(), /* an assertion of the program got false */ warning_user_error(), /* tells the user he did a mistake */ send_user_message(), /* prints a message on the console */ send_file_message(), /* puts a comment in the output file */ send_user_dtime(), /* prints the cpu time since last call */ send_file_dtime(), /* same but to the output file */ send_user_etime(), /* total cpu time sent to terminal */ send_file_etime(); /* same but to the output file */ /* Inputcube.c */ extern int input_length, /* number of long int to store input */ output_length, /* number of long int to store output */ total_length, /* number of long int to store a cube */ input_number, /* number of input var */ output_number, /* number of output var */ total_number; /* number of input and output var */ extern unsigned node_size, /* number of bytes to store a node structure */ cube_list_size; /* number of bytes to store a cube_list struct*/ extern char error_buffer[132], /* buffer to hold messages */ input_literal[4], /* literal accepted for input part */ output_literal[4]; /* literal accepted for output part */ extern long int input_code[4], /* internal codes corresponding to input lit. */ output_code[4]; /* internal code for output literals */ extern struct node *spare_node; /* a node is kept allocated for temp usage */ char ffind_car(); /* finds a character in a string */ int fread_bit_string(), /* reads a part of a cube */ fread_nodes(); /* reads a list of cubes */ /* Outputcube.c */ int foutput_node_list(), /* prints a list of nodes */ foutput_node_vector(), /* prints nodes in a vector */ foutput_graph_list(), /* prints cubes and links for a list of nodes */ foutput_graph_vector(), /* prints cubes and links for vector of nodes */ foutput_cube(), /* prints a cube */ foutput_cube_list(), /* prints a list of cubes */ foutput_cube_and_links(), /* prints a cube and the links of the node */ foutput_bit_string(); /* prints a part of a cube */ /* init.c */ int init_mask_and_codes(); /* set constants which are machine dependant */ extern int var_per_word, /* number of variables in a long int */ log2_var_per_word; /* log2 (var_per_word) */ extern long int mask_bit_index, /* mask the bits for var. pos in a word */ mask00, /* 000000000000 */ mask01, /* 01010101010101... */ mask10, /* 10101010101010... */ mask11; /* 111111111111 */ /* Incubesop.c */ int star_product(), /* merge to cubes to form the biggest cube */ covers(), /* see if a cube covers another one */ absorb(), /* tells if a cube absorbs another */ covers_list(), /* see if a list is covered by a cube */ intersect(), /* see if two cubes intersects */ intersect_list(), /* see if a cube intersects with a list */ disjoint_sharp(); /* substracts a cube from a list */ /* outcubesop.c */ int set_output_word(), /* change the output part of a cube */ or_output(), /* or the output part of two cubes */ and_output(); /* and the output part of two cubes */ /* Setvar.c */ extern int current_var, /* current variable */ current_bit_index, /* number of shift to extract the current var */ current_word_index; /* number of long int to skip to reach cur var*/ extern long int current_mask11, /* contains 11 for current var and 0 else */ current_mask10; /* contains 10 for current var and 0 else */ int define_current_var(), /* change the current variable */ extract_current_var(), /* returns the value of current var of a cube */ extract_var(), /* returns value of a var for a cube */ set_current_var(); /* change the current var of a cube */ /* Detect.c */ int count_code_in_cube(), /* returns the number of times a code occurs */ input_cost(), /* returns the number of non-x code at input */ output_cost(), /* returns the number of 1 at output */ detect_dont_care(), /* see if dont care present at output */ remove_dont_care(), /* change dont care to 0 at output */ detect_do_care(), /* see if 1 present at output */ remove_do_care(), /* changes 1 into 0 at output */ change_dont_to_do_care(); /* changes dont care to 1 at output */ /* Lists.c */ struct node *merge_node_lists(), /* links two node lists together */ *copy_and_alloc_node(); /* duplicates a node */ struct cube_list *copy_and_alloc_cube_list(), /* duplicates a cube_list structure */ *duplicate_cube_list(); /* duplicates a list of cubes */ int copy_cube(); /* copy a cube */ /* Buildgraph.c */ struct node *merge_and_link(); /* place a new node in the graph */ int pass_ancestors(), /* change the address of ancestors */ pass_descendants(), /* change the address of descendants */ remove_ancestors(), /* remove the links from the graph */ absorb_and_unlink(); /* remove a node from the graph */ /* Select.c */ int max(), /* returns the max value of 2 int */ select_input(), /* using heuristic select an input */ put_in_dont_care_list(), /* put the dont care part of a node in a list*/ put_in_common_list(); /* change a tree structure into a list */ /* Prime.c */ extern struct node *common_list, /* convenient place to build a list */ *dont_care_list, /* holds the dont care cover of the function */ **point_to_merge, /* common pointer to a node to merge */ *node_to_merge; /* node that we currently try to merge */ extern struct binary *common_binary; /* branch at which we are merging now */ extern int *nb0_at_input, /* vector to count the 0 for each var */ *nb1_at_input, /* vector to count the 1 for each var */ *nbx_at_input, /* vector to count the x for each var */ *unused_input, /* vector containing the input not partitioned*/ nbinput; /* number of inputs not selected for part. */ struct node *prime_implicants_by_recursive_partitioning(); /* generate PIs */ int recursive_prime_implicants(), /* find PIs of a subtree */ scan_node_to_merge(), /* merge all nodes of is0 with is1 */ merge_with_rest(); /* try merge a node with all in is1 */ /* Solve.c */ #define COVERED 2 #define RETAINED 4 #define DECIDED 8 #define AFFECTED 48 #define AFFECTED_RETAINED 16 #define UNAFFECTED_RETAINED 239 #define AFFECTED_UNRETAIN 32 #define UNAFFECTED_UNRETAIN 223 #define DECIDED_RETAINED 14 #define DECIDED_COVERED 10 #define DECIDED_INFERIOR 8 #define PRIME_ESSENTIAL 64 int recursive_find_covering(), /* find the best set of cubes */ essential_prime_implicants(); /* find the essential prime imp. */ extern struct node **prime_nodes, /* vector containing pointer to all cubes */ **retained_nodes, /* pointer to end of retained nodes */ **unretain_nodes, /* pointer to start of unretained covered node*/ **end_prime, /* pointer to end of prime vector */ **start_stack, /* pointer to start of stack */ **end_stack, /* pointer to end of stack */ **current_in_stack; /* after last node entered in stack */ extern struct cube_list *scanned_cube; /* uncovered part of cube currently processed */ extern struct node *scanned_node, /* node currently processed */ *current_node; /* node in the graph reached by the scan */ extern int undecided_count, /* number of undecided nodes remaining */ scan_count, /* number of nodes scanned for a partition */ prime_count, /* number of cubes in prime nodes vector */ branching_depth; /* depth in recursion while branching */ extern unsigned long int ONE, /* a constant 1 unsigned long int */ odd_pass_counter, /* pass counter + 1 to identify scanning dir.*/ pass_counter; /* counts the number of scanning pass */ /* Place.c */ int retain_node(), /* retain a node and scan nodes affected */ unretain_inferior_node(), /* unretain an inf. node and scan affected */ place_nodes_in_vector(), /* order the nodes in a vector by status */ select_node(), /* upon cycle choose a node to retain */ increment_pass_count(), /* increment the pass counter */ init_pass_count(), /* when pass counter overflows reinit all */ push(); /* place an affected node on the stack */ struct node *pop(); /* take next node from the stack */ /* Scan.c */ int scan_affected_retained_ancestors(), /* recursive routines to scan */ scan_sffected_retained_descendants(), /* nodes in the graph */ scan_affected_inferior_ancestors(), scan_affected_inferior_descendants(), scan_inferior_descendants(), scan_inferior_ancestors(), scan_essential_descendants(), scan_essential_ancestors(), scan_partition(), scan_sparse_ancestors(), scan_sparse_descendants(); /* Mcboole.c */ extern FILE *output_file; /* file on which we print the result */ extern int EPI_LIST, DISJOINT_REQUIRED, /* nodes at input should be disjoint */ VERBOSIS, /* give plenty of messages to user */ VERY_VERBOSIS, /* even more messages */ DONT_MIN_LITERAL, /* minimize only the number of product term */ max_branching_depth, /* deepest braching depth reached */ depth_limit; /* depth limit allowed */ extern char read_interminator, /* character that ends input part for reading*/ read_outterminator, /* character that ends the cube when reading */ *print_interminator, /* string printed after input part */ *print_outterminator; /* string printed after output part */ /* EXTERNAL FUNCTIONS CALLED all the system functions having a special type are defined here. */ #ifdef UNIX char *calloc(), /* routine to allocate space */ *sprintf(); /* routine to write in a string */ #endif