Example #1
0
// 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);
}