// Parse the blif file and build the circuit void Circuit::parse_blif(string filename) { string latch_str= "1 1\n"; ifile.open(filename.c_str()); if (!ifile) { throw Error("Cannot open file"); } while (true) { int type; string token; type= get_blif_token(token); if (type == 2) { break; } else if (type == 4) { if (token == ".inputs" || token == ".outputs") { int type= 0; if (token == ".outputs") { type= 1; } while (get_blif_token(token) != 1) { // create wire Wire* nwire= new Wire(token); ++num_wires; sym_table[token]= nwire; // create instance string instname = token; instname += type == 0 ? "_input" : "_output"; Inst* ninst= new Inst(instname, true); ++num_insts; sym_table[instname]= ninst; // create port Port* nport= new Port(token); ++num_ports; nport->set_inst(ninst); nport->set_wire(nwire); if (type == 0) { // input, connect port as output ninst->add_output(nport); nwire->set_driver(nport); input_wires.push_back(nwire); } else { ninst->add_input(nport); nwire->add_output_port(nport); output_wires.push_back(nwire); } } } else if (token == ".latch") { // .latch input output [<type> <control>] [<init-val>] // only need input and output string input, output; get_blif_token(input); get_blif_token(output); // Exhaust other token until end-of-line while (get_blif_token(token) != 1); // create instance string inst_name = input + "_" + output + "_latch"; Inst* ninst= new Inst(inst_name, false, true); ++num_insts; sym_table[inst_name]= ninst; // handle input port Port* nport= new Port(input); ++num_ports; nport->set_inst(ninst); // create/find wire Wire* nwire= find_wire_insert(input); nwire->add_output_port(nport); output_wires.push_back(nwire); ninst->add_input(nport); // handle output port nport= new Port(output); ++num_ports; nport->set_inst(ninst); // create/find wire nwire = find_wire_insert(output); if (nwire->get_driver() != 0) { cout << "Warning, wire " << output << " has multipler drivers."<<endl; } input_wires.push_back(nwire); nwire->set_driver(nport); ninst->add_output(nport); // latch always has only one input lib_cell* cell = library->create_libcell(latch_str, 1); ninst->add_lib_cell(cell); } else if (token == ".names") { // .names <in-1> <in-2> ... <in-n> <output> vector<string> strvec; int i; string inst_name; Inst* ninst; Port* nport; Wire* nwire; while (get_blif_token(token) != 1) { strvec.push_back(token); inst_name= inst_name + token + "_"; } char chr_temp= ifile.get(); ifile.putback(chr_temp); if (chr_temp == '.') { cout<<"Warning, instance "<<inst_name<<" has no truth table."<<endl; if(strvec.size() == 1) { zero_list.insert(strvec[0]); nwire = find_wire_insert(strvec[0]); throw Error("Found a constant 0"); constants_list.push_back(nwire); } continue; } if(strvec.size() == 1) { cout << "Warning, constant wire " << inst_name << endl; one_list.insert(strvec[0]); nwire= find_wire_insert(strvec[0]); throw Error("Found a constant 1"); constants_list.push_back(nwire); continue; } // set instance inst_name= inst_name + "name"; ninst= new Inst(inst_name); lib_insts.push_back(ninst); ++num_insts; ++num_gates; sym_table[inst_name]= ninst; // first n-1 names are inputs for (i= 0; i < int(strvec.size()) - 1; i++) { nport= new Port(strvec[i]); ++num_ports; nwire= find_wire_insert(strvec[i]); nwire->add_output_port(nport); ninst->add_input(nport); nport->set_inst(ninst); } // last name is output int size= strvec.size(); nport= new Port(strvec[size-1]); ++num_ports; nport->set_inst(ninst); nwire= find_wire_insert(strvec[size-1]); ninst->add_output(nport); if (nwire->get_driver() != 0) { cout<<"Warning, wire "<<strvec[size - 1]<<" has multiple drivers."<<endl; } nwire->set_driver(nport); // next one should be truth-table if (get_blif_ttable(token) == 1) { cout<<"Warning, instance "<<inst_name<<" has no truth table."<<endl; } lib_cell* cell = library->create_libcell(token, ninst->num_inputs()); ninst->add_lib_cell(cell); } else { // Not handled. Skip everything until end of line while (get_blif_token(token) != 1) ; } } } ifile.close(); sort(output_wires.begin(), output_wires.end(), sort_wire); sort(input_wires.begin(), input_wires.end(), sort_wire); }