20 #define MAX_ATOM_PARSE 200000000
48 static int add_vpack_net(
char *ptr,
int type,
int bnum,
int bport,
int bpin,
50 static void get_blif_tok(
char *buffer,
int doall,
boolean *done,
51 boolean *add_truth_table,
INP t_model* inpad_model,
55 static void check_net(
boolean sweep_hanging_nets_and_inputs);
67 static void read_blif(
char *blif_file,
boolean sweep_hanging_nets_and_inputs,
69 boolean read_activity_file,
char * activity_file);
77 static void read_blif(
char *blif_file,
boolean sweep_hanging_nets_and_inputs,
79 boolean read_activity_file,
char * activity_file) {
83 boolean add_truth_table;
84 t_model *inpad_model, *outpad_model, *logic_model, *latch_model;
87 blif = fopen(blif_file,
"r");
89 vpr_printf(TIO_MESSAGE_ERROR,
"Failed to open blif file '%s'.\n",
94 &logic_model, &latch_model);
97 for (doall = 0; doall <= 1; doall++) {
103 #ifdef CLOCKS_PER_SEC
105 "Loop for doall = %d, init_parse took %g seconds.\n", doall,
106 (
float) (end - begin) / CLOCKS_PER_SEC);
108 vpr_printf(TIO_MESSAGE_INFO,
"Loop for doall = %d, init_parse took %g seconds.\n", doall, (
float)(end - begin) / CLK_PER_SEC);
114 add_truth_table =
FALSE;
117 get_blif_tok(buffer, doall, &done, &add_truth_table, inpad_model,
118 outpad_model, logic_model, latch_model, user_models);
123 #ifdef CLOCKS_PER_SEC
124 vpr_printf(TIO_MESSAGE_INFO,
"Loop for doall = %d took %g seconds.\n",
125 doall, (
float) (end - begin) / CLOCKS_PER_SEC);
127 vpr_printf(TIO_MESSAGE_INFO,
"Loop for doall = %d took %g seconds.\n", doall, (
float)(end - begin) / CLK_PER_SEC);
138 check_net(sweep_hanging_nets_and_inputs);
141 if (read_activity_file) {
162 sizeof(
struct s_net));
188 h_ptr = blif_hash[i];
189 while (h_ptr != NULL ) {
191 h_ptr->
count *
sizeof(
int));
193 h_ptr->
count *
sizeof(
int));
195 h_ptr->
count *
sizeof(
int));
203 #ifdef PRINT_PIN_NETS
204 vpr_printf(TIO_MESSAGE_INFO,
"i\ttemp_num_pins\n");
208 vpr_printf(TIO_MESSAGE_INFO,
"num_logical_nets %d\n", num_logical_nets);
228 boolean *add_truth_table,
INP t_model* inpad_model,
235 #define BLIF_TOKENS " \t\n"
244 if (*add_truth_table) {
245 if (ptr[0] ==
'0' || ptr[0] ==
'1' || ptr[0] ==
'-') {
250 if (!ptr || strlen(ptr) != 1) {
251 if (strlen(fn) == 1) {
256 sprintf((
char*) (data->
data_vptr),
" %s", fn);
261 "Unknown truth table data %s %s.\n", fn, ptr);
267 sprintf((
char*) data->
data_vptr,
"%s %s", fn, ptr);
273 if (strcmp(ptr,
".names") == 0) {
274 *add_truth_table =
FALSE;
275 *add_truth_table =
add_lut(doall, logic_model);
279 if (strcmp(ptr,
".latch") == 0) {
280 *add_truth_table =
FALSE;
285 if (strcmp(ptr,
".model") == 0) {
286 *add_truth_table =
FALSE;
316 if (strcmp(ptr,
".inputs") == 0) {
317 *add_truth_table =
FALSE;
328 if (strcmp(ptr,
".outputs") == 0) {
329 *add_truth_table =
FALSE;
340 if (strcmp(ptr,
".end") == 0) {
341 *add_truth_table =
FALSE;
348 if (strcmp(ptr,
".subckt") == 0) {
349 *add_truth_table =
FALSE;
373 char *ptr, **saved_names, buf[
BUFSIZE];
374 int i, j, output_net_index;
386 "[LINE %d] .names %s ... %s has a LUT size that exceeds the maximum LUT size (%d) of the architecture.\n",
391 strcpy(saved_names[i], ptr);
394 output_net_index = i - 1;
395 if (strcmp(saved_names[output_net_index],
"unconn") == 0) {
403 for (j = 0; j <= output_net_index; j++)
413 if (output_net_index > logic_model->
inputs->
size) {
415 "LUT size of %d in .blif file is too big for FPGA which has a maximum LUT size of %d.\n",
435 for (i = 0; i < output_net_index; i++)
443 for (i = output_net_index; i < logic_model->
inputs->
size; i++)
447 saved_names[output_net_index]);
452 return (
boolean) doall;
472 for (i = 0; i < 6; i++) {
476 strcpy(saved_names[i], ptr);
480 vpr_printf(TIO_MESSAGE_ERROR,
".latch does not have 5 parameters.\n");
481 vpr_printf(TIO_MESSAGE_ERROR,
"Check netlist, line %d.\n",
530 int subckt_index_signals = 0;
531 char **subckt_signal_name = NULL;
532 char *port_name, *pin_number;
533 char **circuit_signal_name = NULL;
534 char *subckt_logical_block_name = NULL;
536 int input_net_count, output_net_count, input_port_count, output_port_count;
539 boolean found_subckt_signal;
554 if (ptr == NULL && toggle == 0)
556 else if (ptr == NULL && toggle == 1) {
558 "subckt %s formed incorrectly with signal=signal at %s.\n",
561 }
else if (toggle == 0) {
564 subckt_signal_name = (
char**)
my_realloc(subckt_signal_name,
565 (subckt_index_signals + 1) *
sizeof(
char**));
566 circuit_signal_name = (
char**)
my_realloc(circuit_signal_name,
567 (subckt_index_signals + 1) *
sizeof(
char**));
570 subckt_signal_name[subckt_index_signals] =
my_strdup(ptr);
573 }
else if (toggle == 1) {
575 circuit_signal_name[subckt_index_signals] =
my_strdup(ptr);
583 subckt_index_signals++;
593 output_net_count = 0;
598 cur_model = user_models;
599 while (cur_model != NULL ) {
600 if (strcmp(cur_model->
name, subckt_name) == 0) {
603 cur_model = cur_model->
next;
605 if (cur_model == NULL ) {
607 "Did not find matching model to subckt %s.\n", subckt_name);
619 input_port_count = 0;
628 input_port_count *
sizeof(
int *));
637 assert(port->
size >= 0);
640 for (j = 0; j < port->
size; j++) {
646 assert(port == NULL || (port->
is_clock && port->
next == NULL));
649 output_port_count = 0;
656 output_port_count *
sizeof(
int *));
660 assert(port->
size >= 0);
663 for (j = 0; j < port->
size; j++) {
669 assert(port == NULL);
680 for (i = 0; i < subckt_index_signals; i++) {
681 found_subckt_signal =
FALSE;
683 port_name =
my_strdup(subckt_signal_name[i]);
684 pin_number = strrchr(port_name,
'[');
685 if (pin_number == NULL ) {
691 close_bracket = pin_number;
692 while (*close_bracket !=
'\0' && *close_bracket !=
']') {
695 *close_bracket =
'\0';
700 if (strcmp(port_name, port->
name) == 0) {
701 if (found_subckt_signal) {
703 "Two instances of %s subckt signal found in subckt %s.\n",
704 subckt_signal_name[i], subckt_name);
706 found_subckt_signal =
TRUE;
710 assert(
my_atoi(pin_number) == 0);
729 if (strcmp(port_name, port->
name) == 0) {
730 if (found_subckt_signal) {
732 "Two instances of %s subckt signal found in subckt %s.\n",
733 subckt_signal_name[i], subckt_name);
735 found_subckt_signal =
TRUE;
740 if (subckt_logical_block_name == NULL
741 && circuit_signal_name[i] != NULL ) {
742 subckt_logical_block_name = circuit_signal_name[i];
752 subckt_logical_block_name);
755 if (!found_subckt_signal) {
756 vpr_printf(TIO_MESSAGE_ERROR,
"Unknown subckt port %s.\n",
757 subckt_signal_name[i]);
764 for (i = 0; i < subckt_index_signals; i++) {
765 free(subckt_signal_name[i]);
766 free(circuit_signal_name[i]);
768 free(subckt_signal_name);
769 free(circuit_signal_name);
787 int nindex, len, iparse;
812 (len + 1 + 4) *
sizeof(char));
821 assert(in_or_out ==
DRIVER);
823 (len + 1) *
sizeof(char));
832 if (in_or_out ==
DRIVER) {
854 if (fgetpos(
blif, &start_pos) != 0) {
856 "in file pointer read - read_blif.c\n");
861 user_model = user_models;
863 if (0 == strcmp(model_name, user_model->
name)) {
866 user_model = user_model->
next;
868 if (user_model == NULL ) {
870 "No corresponding model %s in architecture description.\n",
879 static int add_vpack_net(
char *ptr,
int type,
int bnum,
int bport,
int bpin,
889 struct s_hash *h_ptr, *prev_ptr;
890 int index, j, nindex;
892 if (strcmp(ptr,
"open") == 0) {
894 "net name \"open\" is a reserved keyword in VPR.");
898 if (strcmp(ptr,
"unconn") == 0) {
904 if (type ==
RECEIVER && !is_global) {
906 }
else if (type ==
DRIVER) {
911 h_ptr = blif_hash[
index];
914 while (h_ptr != NULL ) {
915 if (strcmp(h_ptr->
name, ptr) == 0) {
916 nindex = h_ptr->
index;
930 "Number of drivers for net #%d (%s) has %d drivers.\n",
940 "Net #%d (%s) has no driver and will cause memory corruption.\n",
959 "in add_vpack_net: The second (load) pass could not find vpack_net %s in the symbol table.\n",
968 if (prev_ptr == NULL ) {
969 blif_hash[
index] = h_ptr;
971 prev_ptr->
next = h_ptr;
977 return (h_ptr->
index);
992 int *lut_distribution;
993 int num_absorbable_latch;
996 cur = library_models;
997 logic_model = latch_model = NULL;
1011 num_absorbable_latch = 0;
1014 if (logic_model == NULL )
1016 for (j = 0; j < logic_model->
inputs[0].
size; j++) {
1021 lut_distribution[j]++;
1023 if (latch_model == NULL )
1029 num_absorbable_latch++;
1034 vpr_printf(TIO_MESSAGE_INFO,
"Input netlist file: '%s', model: %s\n",
1036 vpr_printf(TIO_MESSAGE_INFO,
"Primary inputs: %d, primary outputs: %d\n",
1038 vpr_printf(TIO_MESSAGE_INFO,
"LUTs: %d, latches: %d, subckts: %d\n",
1040 vpr_printf(TIO_MESSAGE_INFO,
"# standard absorbable latches: %d\n",
1041 num_absorbable_latch);
1043 for (i = 0; i < logic_model->
inputs[0].
size + 1; i++) {
1046 vpr_printf(TIO_MESSAGE_DIRECT,
"LUT size %d = %d", i,
1047 lut_distribution[i]);
1050 vpr_printf(TIO_MESSAGE_INFO,
"Total blocks: %d, total nets: %d\n",
1055 fprintf(fp,
"Input netlist file: '%s', model: %s\n", blif_file,
model);
1057 "num_p_inputs: %d, num_p_outputs: %d, num_luts: %d, num_latches: %d\n",
1059 fprintf(fp,
"num_logical_blocks: %d, num_logical_nets: %d\n",
1062 fprintf(fp,
"\nNet\tName\t\t#Pins\tDriver\tRecvs.\n");
1067 fprintf(fp,
"%d",
vpack_net[i].num_sinks + 1);
1069 fprintf(fp,
"\t(%d,%d,%d)",
vpack_net[i].node_block[j],
1074 fprintf(fp,
"\n\nBlocks\t\tBlock type legend:\n");
1087 fprintf(fp,
"\tinput port: %s \t", port->
name);
1088 for (j = 0; j < port->
size; j++) {
1090 fprintf(fp,
"OPEN ");
1101 fprintf(fp,
"\toutput port: %s \t", port->
name);
1102 for (j = 0; j < port->
size; j++) {
1104 fprintf(fp,
"OPEN ");
1114 fprintf(fp,
"\tclock net: %d\n",
logical_block[i].clock_net);
1124 cur_model = library_models;
1125 *inpad_model = *outpad_model = *logic_model = *latch_model = NULL;
1128 assert(cur_model->
inputs == NULL);
1131 *inpad_model = cur_model;
1133 assert(cur_model->
outputs == NULL);
1136 *outpad_model = cur_model;
1141 *logic_model = cur_model;
1145 *latch_model = cur_model;
1149 cur_model = cur_model->
next;
1153 static void check_net(
boolean sweep_hanging_nets_and_inputs) {
1157 int i, j, k, error, iblk, ipin, iport, inet, L_check_net;
1159 int count_inputs, count_outputs;
1160 int explicit_vpack_models;
1164 int count_unconn_blocks;
1171 if (
ilines != explicit_vpack_models) {
1172 vpr_printf(TIO_MESSAGE_ERROR,
"Found %d .inputs lines; expected %d.\n",
1173 ilines, explicit_vpack_models);
1177 if (
olines != explicit_vpack_models) {
1178 vpr_printf(TIO_MESSAGE_ERROR,
"Found %d .outputs lines; expected %d.\n",
1179 olines, explicit_vpack_models);
1184 vpr_printf(TIO_MESSAGE_ERROR,
"Found %d .model lines; expected %d.\n",
1189 if (
endlines != explicit_vpack_models) {
1190 vpr_printf(TIO_MESSAGE_ERROR,
"Found %d .end lines; expected %d.\n",
1198 "vpack_net %s has %d signals driving it.\n",
1219 if (sweep_hanging_nets_and_inputs) {
1228 "vpack_net %s has no fanout.\n",
vpack_net[i].name);
1234 if (strcmp(
vpack_net[i].name,
"open") == 0
1235 || strcmp(
vpack_net[i].name,
"unconn") == 0) {
1237 "vpack_net #%d has the reserved name %s.\n", i,
1249 if (L_check_net != i) {
1251 "Clock net for block %s #%d is net %s #%d but connecting net is %s #%d.\n",
1253 vpack_net[L_check_net].name, L_check_net,
1261 if (L_check_net != i) {
1263 "Output net for block %s #%d is net %s #%d but connecting net is %s #%d.\n",
1265 vpack_net[L_check_net].name, L_check_net,
1276 if (L_check_net != i) {
1278 "Input net for block %s #%d is net %s #%d but connecting net is %s #%d.\n",
1280 vpack_net[L_check_net].name, L_check_net,
1288 vpr_printf(TIO_MESSAGE_INFO,
"Swept away %d nets with no fanout.\n",
1290 count_unconn_blocks = 0;
1296 "logical_block %s #%d has no fanout.\n",
1298 if (sweep_hanging_nets_and_inputs
1301 vpr_printf(TIO_MESSAGE_INFO,
"Removing input.\n");
1309 count_unconn_blocks++;
1311 "Sweep hanging nodes in your logic synthesis tool because VPR can not do this yet.\n");
1323 for (j = 0; j < port->
size; j++) {
1330 if (
vpack_net[inet].node_block[k] == i) {
1332 if (
vpack_net[inet].node_block_pin[k] == j) {
1338 assert(found ==
TRUE);
1347 for (j = 0; j < port->
size; j++) {
1357 "Net is a constant generator: %s.\n",
1362 if (
vpack_net[inet].node_block[0] == i) {
1364 if (
vpack_net[inet].node_block_pin[0] == j) {
1369 assert(found ==
TRUE);
1378 "Latch #%d with output %s has %d input pin(s), expected one (D).\n",
1384 "Latch #%d with output %s has %d output pin(s), expected one (Q).\n",
1391 "Latch #%d with output %s has no clock.\n", i,
1400 "IO inpad logical_block #%d name %s of type %d" "has %d input pins.\n",
1407 "IO inpad logical_block #%d name %s of type %d" "has %d output pins.\n",
1414 "IO inpad #%d with output %s has clock.\n", i,
1421 "io outpad logical_block #%d name %s of type %d" "has %d input pins.\n",
1428 "io outpad logical_block #%d name %s of type %d" "has %d output pins.\n",
1435 "io outpad #%d with name %s has clock.\n", i,
1442 "logical_block #%d with output %s has only %d pin.\n",
1450 "Block contains output -- may be a constant generator.\n");
1453 "Block contains no output.\n");
1461 "Logical_block #%d name %s of model %s has %d output pins instead of 1.\n",
1469 "Unknown type for logical_block #%d %s.\n", i,
1473 vpr_printf(TIO_MESSAGE_INFO,
"%d unconnected blocks in input netlist.\n", count_unconn_blocks);
1477 "Found %d fatal errors in the input netlist.\n", error);
1487 struct s_hash *h_ptr, *temp_ptr;
1490 h_ptr = blif_hash[i];
1491 while (h_ptr != NULL ) {
1492 free((
void *) h_ptr->
name);
1493 temp_ptr = h_ptr->
next;
1494 free((
void *) h_ptr);
1499 free((
void *) blif_hash);
1506 int bnum, in_blk, out_blk, ipin, out_net, in_net;
1539 assert(in_net !=
OPEN);
1540 assert(out_net !=
OPEN);
1541 assert(out_blk !=
OPEN);
1542 assert(in_blk !=
OPEN);
1545 if (
vpack_net[out_net].num_sinks == 1) {
1548 if (
vpack_net[in_net].node_block[ipin] == bnum) {
1552 assert(ipin <=
vpack_net[in_net].num_sinks);
1576 assert(
vpack_net[out_net].node_block[ipin] != bnum);
1584 vpr_printf(TIO_MESSAGE_INFO,
"Removed %d LUT buffers.\n", removed);
1596 int inet, iblk,
index, ipin, new_num_nets, new_num_blocks, i;
1597 int *net_remap, *block_remap;
1609 net_remap[inet] = new_num_nets;
1612 net_remap[inet] =
OPEN;
1618 block_remap[iblk] = new_num_blocks;
1621 block_remap[iblk] =
OPEN;
1625 if (new_num_nets != num_logical_nets
1626 || new_num_blocks != num_logical_blocks) {
1630 index = net_remap[inet];
1644 num_logical_nets = new_num_nets;
1646 num_logical_nets *
sizeof(
struct s_net));
1650 index = block_remap[iblk];
1651 if (index != iblk) {
1659 for (ipin = 0; ipin < port->
size; ipin++) {
1662 port->
size == 1 && port->
index == 0 && ipin == 0);
1681 for (ipin = 0; ipin < port->
size; ipin++) {
1726 while (tvptr != NULL ) {
1736 vpr_printf(TIO_MESSAGE_INFO,
"Sweeped away %d nodes.\n",
1737 num_logical_blocks - new_num_blocks);
1739 num_logical_blocks = new_num_blocks;
1766 boolean sweep_hanging_nets_and_inputs,
t_model *user_models,
1767 t_model *library_models,
boolean read_activity_file,
char * activity_file) {
1770 read_blif(blif_file, sweep_hanging_nets_and_inputs, user_models,
1771 library_models, read_activity_file, activity_file);
1810 int num_model_stats;
1813 int i, j, iblk, ipin, num_pins;
1814 int *num_lut_of_size;
1817 num_model_stats = 0;
1819 cur = library_models;
1834 num_model_stats = 0;
1837 cur = library_models;
1839 model_stats[num_model_stats].
model = cur;
1840 if (strcmp(cur->
name,
"names") == 0) {
1841 lut_model = &model_stats[num_model_stats];
1849 model_stats[num_model_stats].
model = cur;
1862 num_lut_of_size = (
int*)
my_calloc(MAX_LUT_INPUTS + 1,
sizeof(
int));
1865 for (j = 0; j < num_model_stats; j++) {
1870 assert(j < num_model_stats);
1871 model_stats[j].
count++;
1872 if (&model_stats[j] == lut_model) {
1880 num_lut_of_size[num_pins]++;
1886 vpr_printf(TIO_MESSAGE_INFO,
"BLIF circuit stats:\n");
1888 for (i = 0; i <= MAX_LUT_INPUTS; i++) {
1889 vpr_printf(TIO_MESSAGE_INFO,
"\t%d LUTs of size %d\n",
1890 num_lut_of_size[i], i);
1892 for (i = 0; i < num_model_stats; i++) {
1893 vpr_printf(TIO_MESSAGE_INFO,
"\t%d of type %s\n", model_stats[i].
count,
1894 model_stats[i].
model->name);
1898 free(num_lut_of_size);
1910 FILE * act_file_hdl;
1913 printf(
"Error reading activity file. Must read netlist first\n");
1926 if (act_file_hdl == NULL ) {
1927 printf(
"Error: could not open activity file: %s\n", activity_file);
1933 while (ptr != NULL ) {
1934 word1 = strtok(buf,
TOKENS);
1935 word2 = strtok(NULL,
TOKENS);
1936 word3 = strtok(NULL,
TOKENS);
1942 fclose(act_file_hdl);
1947 ||
vpack_net[net_idx].net_power->probability < 0.0
1949 printf(
"Error: Activity file does not contain signal %s\n",
1961 int hash_idx, net_idx;
1965 h_ptr = blif_hash[hash_idx];
1967 while (h_ptr != NULL ) {
1968 if (strcmp(h_ptr->
name, net_name) == 0) {
1969 net_idx = h_ptr->
index;
1974 h_ptr = h_ptr->
next;
1978 "Error: net %s found in activity file, but it does not exist in the .blif file.\n",
static int * logical_block_input_count
static int * temp_num_pins
struct s_net_power t_net_power
FILE * my_fopen(const char *fname, const char *flag, int prompt)
static void init_parse(int doall)
static void get_blif_tok(char *buffer, int doall, boolean *done, boolean *add_truth_table, INP t_model *inpad_model, INP t_model *outpad_model, INP t_model *logic_model, INP t_model *latch_model, INP t_model *user_models)
void ** alloc_matrix(int nrmin, int nrmax, int ncmin, int ncmax, size_t elsize)
static void read_blif(char *blif_file, boolean sweep_hanging_nets_and_inputs, t_model *user_models, t_model *library_models, boolean read_activity_file, char *activity_file)
struct s_linked_vptr * circuit_p_io_removed
static void read_activity(char *activity_file)
static void compress_netlist(void)
void free_matrix(void *vptr, int nrmin, int nrmax, int ncmin, size_t elsize)
static int add_vpack_net(char *ptr, int type, int bnum, int bport, int bpin, boolean is_global, int doall)
void dum_parse(char *buf)
static void show_blif_stats(t_model *user_models, t_model *library_models)
int hash_value(char *name)
static boolean add_lut(int doall, t_model *logic_model)
static int num_blif_models
static void free_parse(void)
void * my_calloc(size_t nelem, size_t size)
struct s_model_ports * next
struct s_linked_vptr * truth_table
static int * logical_block_output_count
boolean getEchoEnabled(void)
static void load_default_models(INP t_model *library_models, OUTP t_model **inpad_model, OUTP t_model **outpad_model, OUTP t_model **logic_model, OUTP t_model **latch_model)
static void * my_malloc(int ibytes)
static void check_net(boolean sweep_hanging_nets_and_inputs)
static void add_latch(int doall, INP t_model *latch_model)
void read_and_process_blif(char *blif_file, boolean sweep_hanging_nets_and_inputs, t_model *user_models, t_model *library_models, boolean read_activity_file, char *activity_file)
static void add_subckt(int doall, INP t_model *user_models)
boolean isEchoFileEnabled(enum e_echo_files echo_option)
static bool add_activity_to_net(char *net_name, float probability, float density)
char * my_strtok(char *ptr, const char *tokens, FILE *fp, char *buf)
struct s_linked_vptr * next
void echo_input(char *blif_file, char *echo_file, t_model *library_models)
enum logical_block_types type
static void check_and_count_models(int doall, const char *model_name, t_model *user_models)
static void * my_realloc(void *memblk, int ibytes)
char * my_fgets(char *buf, int max_size, FILE *fp)
char * getEchoFileName(enum e_echo_files echo_option)
static void io_line(int in_or_out, int doall, t_model *io_model)
static struct s_hash ** blif_hash
int my_atoi(const char *str)
static void absorb_buffer_luts(void)
char * my_strdup(const char *str)
struct s_logical_block * logical_block
void get_hash_stats(struct s_hash **hash_table, char *hash_table_name)