static void add_lut(int doall, int lut_size) { /* Adds a LUT (.names) currently being parsed to the block array. Adds * * its pins to the nets data structure by calling add_net. If doall is * * zero this is a counting pass; if it is 1 this is the final (loading) * * pass. */ char* ptr, saved_names[MAXLUT + 2][BUFSIZE], buf[BUFSIZE]; int i, j, len; num_blocks++; /* Count # nets connecting */ i = 0; while ((ptr = my_strtok(NULL, TOKENS, blif, buf)) != NULL) { if (i == MAXLUT + 1) { fprintf(stderr, "Error: LUT #%d has %d inputs. Increase MAXLUT or" " check the netlist, line %d.\n", num_blocks - 1, i - 1, linenum); exit(1); } strcpy(saved_names[i], ptr); i++; } if (!doall) { /* Counting pass only ... */ for (j = 0; j < i; j++) { add_net(saved_names[j], RECEIVER, num_blocks - 1, doall); } return; } block[num_blocks - 1].num_nets = i; block[num_blocks - 1].type = LUT; for (i = 0; i < block[num_blocks - 1].num_nets - 1; i++) /* Do inputs */ block[num_blocks - 1].nets[i + 1] = add_net(saved_names[i], RECEIVER, num_blocks - 1, doall); block[num_blocks - 1].nets[0] = add_net( saved_names[block[num_blocks - 1].num_nets - 1], DRIVER, num_blocks - 1, doall); for (i = block[num_blocks - 1].num_nets; i < lut_size + 2; i++) { block[num_blocks - 1].nets[i] = OPEN; } len = strlen(saved_names[block[num_blocks - 1].num_nets - 1]); block[num_blocks - 1].name = (char*) my_malloc((len + 1) * sizeof(char)); strcpy(block[num_blocks - 1].name, saved_names[block[num_blocks - 1].num_nets - 1]); num_luts++; }
static char *add_clb (int doall, FILE *fp_net, char *buf) { /* Adds the clb (.clb) currently being parsed to the block array. Adds * * its pins to the nets data structure by calling add_net. If doall is * * zero this is a counting pass; if it is 1 this is the final (loading) * * pass. */ char *ptr; int pin_index, iclass, inet; enum e_pin_type type; num_blocks++; parse_name_and_pinlist (doall, fp_net, buf); num_clbs++; if (doall) block[num_blocks - 1].type = CLB; pin_index = -1; ptr = my_strtok(NULL,TOKENS,fp_net,buf); while (ptr != NULL) { pin_index++; if (pin_index >= pins_per_clb) { printf("Error in add_clb on line %d of netlist file.\n",linenum); printf("Too many pins on this clb. Expected %d.\n",pins_per_clb); exit (1); } iclass = clb_pin_class[pin_index]; type = class_inf[iclass].type; /* DRIVER or RECEIVER */ if (strcmp(ptr,"open") != 0) { /* Pin is connected. */ inet = add_net (ptr, type, num_blocks-1, pin_index, doall); if (doall) /* Loading pass only */ block[num_blocks - 1].nets[pin_index] = inet; } else { /* Pin is unconnected (open) */ if (doall) block[num_blocks - 1].nets[pin_index] = OPEN; } ptr = my_strtok(NULL,TOKENS,fp_net,buf); } if (pin_index != pins_per_clb - 1) { printf("Error in add_clb on line %d of netlist file.\n",linenum); printf("Expected %d pins on clb, got %d.\n", pins_per_clb, pin_index + 1); exit (1); } ptr = parse_subblocks (doall, fp_net, buf, num_blocks-1); return (ptr); }
static void io_line(int in_or_out, int doall) { /* Adds an input or output block to the block data structures. * * in_or_out: DRIVER for input, RECEIVER for output. * * doall: 1 for final pass when structures are loaded. 0 for * * first pass when hash table is built and pins, nets, etc. are counted. */ char* ptr; char buf2[BUFSIZE]; int nindex, len; while (1) { ptr = my_strtok(NULL, TOKENS, blif, buf2); if (ptr == NULL) { return; } num_blocks++; nindex = add_net(ptr, in_or_out, num_blocks - 1, doall); /* zero offset indexing */ if (!doall) { continue; /* Just counting things when doall == 0 */ } len = strlen(ptr); if (in_or_out == RECEIVER) { /* output pads need out: prefix to make names unique from LUTs */ block[num_blocks - 1].name = (char*) my_malloc((len + 1 + 4) * sizeof(char)); /* Space for out: at start */ strcpy(block[num_blocks - 1].name, "out:"); strcat(block[num_blocks - 1].name, ptr); } else { block[num_blocks - 1].name = (char*) my_malloc((len + 1) * sizeof(char)); strcpy(block[num_blocks - 1].name, ptr); } block[num_blocks - 1].num_nets = 1; block[num_blocks - 1].nets[0] = nindex; /* Put in driver position for */ /* OUTPAD, since it has only one pin (even though it's a receiver */ if (in_or_out == DRIVER) { /* processing .inputs line */ num_p_inputs++; block[num_blocks - 1].type = INPAD; } else { /* processing .outputs line */ num_p_outputs++; block[num_blocks - 1].type = OUTPAD; } } }
static void add_latch(int doall, int lut_size) { /* Adds the flipflop (.latch) currently being parsed to the block array. * * Adds its pins to the nets data structure by calling add_net. If doall * * is zero this is a counting pass; if it is 1 this is the final * * (loading) pass. Blif format for a latch is: * * .latch <input> <output> <type (latch on)> <control (clock)> <init_val> * * The latch pins are in .nets 0 to 2 in the order: Q D CLOCK. */ char* ptr, buf[BUFSIZE], saved_names[6][BUFSIZE]; int i, len; num_blocks++; /* Count # parameters, making sure we don't go over 6 (avoids memory corr.) */ /* Note that we can't rely on the tokens being around unless we copy them. */ for (i = 0; i < 6; i++) { ptr = my_strtok(NULL, TOKENS, blif, buf); if (ptr == NULL) { break; } strcpy(saved_names[i], ptr); } if (i != 5) { fprintf(stderr, "Error: .latch does not have 5 parameters.\n" "check the netlist, line %d.\n", linenum); exit(1); } if (!doall) { /* If only a counting pass ... */ add_net(saved_names[0], RECEIVER, num_blocks - 1, doall); /* D */ add_net(saved_names[1], DRIVER, num_blocks - 1, doall); /* Q */ add_net(saved_names[3], RECEIVER, num_blocks - 1, doall); /* Clock */ return; } block[num_blocks - 1].num_nets = 3; block[num_blocks - 1].type = LATCH; block[num_blocks - 1].nets[0] = add_net(saved_names[1], DRIVER, num_blocks - 1, doall); /* Q */ block[num_blocks - 1].nets[1] = add_net(saved_names[0], RECEIVER, num_blocks - 1, doall); /* D */ block[num_blocks - 1].nets[lut_size + 1] = add_net(saved_names[3], RECEIVER, num_blocks - 1, doall); /* Clock */ for (i = 2; i < lut_size + 1; i++) { block[num_blocks - 1].nets[i] = OPEN; } len = strlen(saved_names[1]); block[num_blocks - 1].name = (char*) my_malloc((len + 1) * sizeof(char)); strcpy(block[num_blocks - 1].name, saved_names[1]); num_latches++; }
bool module::read_module(string buff, map<string, module*> &map_module, map<string, cell*> &map_cell) { try { string buff_s = buff; string input_line, output_line, wire_line, instance_line; std::regex e; std::smatch sm; std::regex_iterator<std::string::iterator> rit; std::regex_iterator<std::string::iterator> rend; e = "module ([\\\\\\._a-zA-Z0-9]+)"; std::regex_search(buff, sm, e); sModuleName = sm[1]; cout << "module_name: " << sModuleName << endl; e = "input\\s+([^;]+;)"; string buff_input = buff; while (std::regex_search(buff_input, sm, e)) { input_line = sm[1]; std::regex e_input_line("([\\\\\\w]+)"); rit = std::regex_iterator<std::string::iterator>(input_line.begin(), input_line.end(), e_input_line); while (rit != rend) { add_net(rit->str()); set_input(get_net(rit->str()), true); rit++; } buff_input = sm.suffix().str(); } e = "output\\s+([^;]+;)"; string buff_output = buff; while (std::regex_search(buff_output, sm, e)) { output_line = sm[1]; std::regex e_output_line("([\\\\\\w]+)"); rit = std::regex_iterator<std::string::iterator>(output_line.begin(), output_line.end(), e_output_line); while (rit != rend) { add_net(rit->str()); set_output(get_net(rit->str()), true); rit++; } buff_output = sm.suffix().str(); } e = "wire\\s+([^;]+;)"; string buff_wire = buff; while (std::regex_search(buff_wire, sm, e)) { wire_line = sm[1]; std::regex e_wire_line("([\\\\\\w]+)"); rit = std::regex_iterator<std::string::iterator>(wire_line.begin(), wire_line.end(), e_wire_line); while (rit != rend) { add_net(rit->str()); rit++; } buff_wire = sm.suffix().str(); } e = "([\\\\\\.\\w]+)\\s+([\\\\\\.\\w]+)\\s*\\((?:.|\\s)*?\\);"; rit = std::regex_iterator<std::string::iterator>(buff_s.begin(), buff_s.end(), e); while (rit != rend) { instance_line = rit->str(); std::regex e_instance_line("([\\\\\\.\\w]+)\\s+([\\\\\\.\\w]+)\\s*\\(((?:.|\\s)*?)\\);"); if (std::regex_match(instance_line, sm, e_instance_line)) { string gate_type = sm[1]; string instance_name = sm[2]; string port_info = sm[3]; if (gate_type != "module") { node* new_node = add_node(instance_name, gate_type, map_module, map_cell); vector<string> pin_list; vector<string> wire_list; std::regex e_port_info("\\.([\\\\\\[\\]\\w]+)\\(\\s*([\\\\\\[\\]\\w]+)\\s*\\)"); std::regex_iterator<std::string::iterator> it_port_info(port_info.begin(), port_info.end(), e_port_info); while (it_port_info != rend) { string single_port = it_port_info->str(); smatch sm_single_port; if (std::regex_match(single_port, sm_single_port, e_port_info)) { connect_wire(get_net(sm_single_port[2]), new_node, sm_single_port[1]); } it_port_info++; } } } rit++; } commit(); } catch (std::exception &e) { cerr << "reading module faild. (read_module)\n"; cerr << "description: " << e.what(); destroy(); return false; } return true; }
static void add_io (int doall, int block_type, FILE *fp_net, char *buf) { /* Adds the INPAD or OUTPAD (specified by block_type) currently being * * parsed to the block array. Adds its pin to the nets data structure * * by calling add_net. If doall is zero this is a counting pass; if it * * is 1 this is the final (loading) pass. */ char *ptr; int inet, pin_index, i; enum e_pin_type type; num_blocks++; if (doall == 0) set_subblock_count (num_blocks-1, 0); /* No subblocks for IO */ parse_name_and_pinlist (doall, fp_net, buf); if (block_type == INPAD) { num_p_inputs++; type = DRIVER; } else { num_p_outputs++; type = RECEIVER; } if (doall) block[num_blocks - 1].type = block_type; pin_index = -1; ptr = my_strtok(NULL,TOKENS,fp_net,buf); while (ptr != NULL) { pin_index++; if (pin_index >= 1) { printf("Error in add_io on line %d of netlist file.\n",linenum); printf("Too many pins on this io. Expected 1.\n"); exit (1); } if (strcmp(ptr,"open") == 0) { /* Pin unconnected. */ printf("Error in add_io, line %d of netlist file.\n",linenum); printf("Inputs and Outputs cannot have open pins.\n"); exit (1); } /* Note the dummy pin number for IO pins. Change this if necessary. I set * * them to OPEN because I want the code to crash if I try to look up the * * class of an I/O pin (since I/O pins don't have classes). */ inet = add_net (ptr, type, num_blocks-1, OPEN, doall); if (doall) /* Loading pass only */ block[num_blocks - 1].nets[pin_index] = inet; ptr = my_strtok(NULL,TOKENS,fp_net,buf); } if (pin_index != 0) { printf("Error in add_io on line %d of netlist file.\n",linenum); printf("Expected 1 pin on pad, got %d.\n", pin_index + 1); exit (1); } if (doall) { for (i=1;i<pins_per_clb;i++) block[num_blocks-1].nets[i] = OPEN; } }