bool output_syntax(char *argv[], evl_module &module, evl_wires &wires, evl_components &components, evl_endmodule &endmodule) { std::string output_file_name = std::string(argv[1]) + ".syntax"; std::ofstream output_file(output_file_name.c_str()); if (!output_file) { std::cerr << "I can't write " << argv[1] << ".tokens ." << std::endl; return false; } if (!module.type.empty())//if .evl has a module, output its name { output_file << "module " << module.type << std::endl; } if (!wires.empty())//if .evl has wires, output names { output_file << "wires " << wires.size() << std::endl; for (evl_wires::iterator i = wires.begin(); i != wires.end(); ++i) { evl_wire wire = *i; output_file << " wire " << wire.name << " " << wire.width << std::endl; } } if (!components.empty())//if .evl has components, output pins, types and names { output_file << "components " << components.size() << std::endl; for (evl_components::iterator i = components.begin(); i != components.end(); ++i) { evl_component component = *i; output_file << " component " << component.type << " "; if (component.name != "")// component name is optional output_file << component.name << " "; output_file << component.pins.size() << std::endl; for (evl_pins::iterator j = component.pins.begin(); j != component.pins.end(); ++j) { evl_pin pin = *j; output_file << " pin " << pin.name; if (pin.bus_msb >= 0) { output_file << " " << pin.bus_msb; } if (pin.bus_lsb >= 0) { output_file << " " << pin.bus_lsb; } output_file << std::endl; } } } if (!endmodule.name.empty())//if .evl has endmodule, output it { output_file << "endmodule" << std::endl; } return true; }
evl_wires_table make_wires_table(const evl_wires &wires) { evl_wires_table wires_table; for (evl_wires::const_iterator it = wires.begin(); it != wires.end(); ++it) { std::pair<std::string, int> _pair=std::make_pair(it->name, it->width); wires_table.insert(_pair); } return wires_table; }
bool netlist::create_nets(const evl_wires &wires) { for (evl_wires::const_iterator iter = wires.begin(); iter != wires.end(); ++iter) { if ((*iter).width == 1) { create_net((*iter).name); } else { for (int i = 0; i < (*iter).width; ++i) { create_net(make_net_name((*iter).name, i)); } } } return true; }
bool netlist::create_nets(const evl_wires &wires) { for(evl_wires::const_iterator w=wires.begin(); w!=wires.end();++w) { if (w->width == 1) { create_net(w->name); } else { for (int i = 0; i < w->width; ++i) { std::string net_name = make_net_name(w->name, i); create_net(net_name); } } } return true; }
bool process_wire_statement(evl_wires &wires, evl_statement &s) { enum state_type { INIT, WIRE, DONE, WIRES, WIRE_NAME, BUS, BUS_MSB, BUS_COLON, BUS_LSB, BUS_DONE }; state_type state = INIT; int width = 1;//set default width for (; !s.tokens.empty() && (state != DONE); s.tokens.pop_front()) { evl_token t = s.tokens.front(); // use branches here to compute state transitions if (state == INIT) { if (t.str == "wire") { state = WIRE; } else { std::cerr << "Need 'wire' but found '" << t.str << "' on line " << t.line_no << std::endl; return false; } } else if (state == WIRE) { if (t.type == evl_token::NAME) { evl_wire wire; wire.name = t.str; wire.width = width; wires.push_back(wire); state = WIRE_NAME; } else if (t.str == "[") { state = BUS; } else { std::cerr << "Need NAME but found '" << t.str << "' on line " << t.line_no << std::endl; return false; } } else if (state == WIRES) { if (t.type == evl_token::NAME) { evl_wire wire; wire.name = t.str; wire.width = width; wires.push_back(wire); state = WIRE_NAME; } else { std::cerr << "Need NAME but found '" << t.str << "' on line " << t.line_no << std::endl; return false; } } else if (state == WIRE_NAME) { if (t.str == ",") { state = WIRES; } else if (t.str == ";") { state = DONE; } else { std::cerr << "Need ',' or ';' but found '" << t.str << "' on line " << t.line_no << std::endl; return false; } } else if (state == BUS) { if (t.type == evl_token::NUMBER) { width = atoi(t.str.c_str()); width++; } else { std::cerr << "Need Width but found '" << t.str << "' on line " << t.line_no << std::endl; return false; } state = BUS_MSB; } else if (state == BUS_MSB) { if (t.str != ":") { std::cerr << "Need ':' but found '" << t.str << "' on line " << t.line_no << std::endl; return false; } state = BUS_COLON; } else if (state == BUS_COLON) { if (t.str != "0") { std::cerr << "Need '0' but found '" << t.str << "' on line " << t.line_no << std::endl; return false; } state = BUS_LSB; } else if (state == BUS_LSB) { if (t.str != "]") { std::cerr << "Need ']' but found '" << t.str << "' on line " << t.line_no << std::endl; return false; } state = BUS_DONE; } else if (state == BUS_DONE) { evl_wire wire; wire.name = t.str; wire.width = width; wires.push_back(wire); state = WIRE_NAME; } else if (state == DONE) { break; } else { std::cerr << "Wire State Machine is Wrong" << std::endl; return false; } } if (!s.tokens.empty() || (state != DONE)) { std::cerr << "something wrong with the statement" << std::endl; return false; } return true; }
bool process_components_statement(evl_components &cp, evl_statement &s, const evl_wires &wires) { assert(s.type == evl_statement::COMPONENT); enum state_type {INIT, TYPE, NAME, PIN_NAME, PINS, PINS_DONE, DONE, BUS, BUS_MSB, BUS_COLON, BUS_LSB, BUS_DONE}; state_type STATE = INIT; evl_component component; evl_pin pin; for (evl_tokens::const_iterator iter = s.tokens.begin(); (iter != s.tokens.end()) && (STATE != DONE); ++iter,s.tokens.pop_front()) { evl_token t = s.tokens.front(); if (STATE == INIT) { if (t.type == evl_token::NAME) { component.type = t.name; component.name = "NONE"; STATE = TYPE; } else { cerr << "Need a name but found "<< t.name <<" on line "<< t.lineNumber<< "STATE == INIT" << endl; return false; } } else if (STATE == TYPE) { if (t.type == evl_token::NAME) { component.name = t.name; STATE = NAME; } else if ((t.type == evl_token::SINGLE) && (t.name == "(")) { STATE = PINS; } else { cerr << "Need NAME or '(' but found "<< t.name << " on line "<<t.lineNumber << "STATE == TYPE" << endl; return false; } } else if (STATE == NAME) { if ((t.type == evl_token::SINGLE) && (t.name == "(")) { STATE = PINS; } else { cerr << "Need '(' but found "<< t.name << " on line "<<t.lineNumber << "STATE == NAME" << endl; return false; } } else if (STATE == PINS) { if (t.type == evl_token::NAME) { evl_wires::const_iterator it = wires.find(t.name); if (it == wires.end()) { cerr << "Wire '" << t.name << "' is not defined" << endl; return false; } pin.name = t.name; pin.msb = -1; pin.lsb = -1; if (wire_is_BUS(it->second)) { pin.msb = (it->second)-1; pin.lsb = 0; } STATE = PIN_NAME; } else { cerr << "Need NAME but found "<< t.name << "on line "<<t.lineNumber << "STATE == PINS" << endl; return false; } } else if (STATE == PIN_NAME) { if (t.type == evl_token::SINGLE && t.name == ",") { component.pins.push_back(pin); STATE = PINS; } else if (t.type == evl_token::SINGLE && t.name == ")") { component.pins.push_back(pin); STATE = PINS_DONE; } else if (t.type == evl_token::SINGLE && t.name == "[") { STATE = BUS; } else { cerr << "Need ’,’ or ’)’ or '[' but found ’" << t.name << "’ on line " << t.lineNumber << "STATE == PIN_NAME" << std::endl; return false; } } else if(STATE == BUS) { if (t.type == evl_token::NUMBER) { int msb = atoi(t.name.c_str()); if (!(pin.msb >= msb && msb >= 0)) { cerr << "Pin is not within wire range!"<<endl; return false; } pin.msb = msb; STATE = BUS_MSB; } else { cerr << "Need a NUMBER but found ’" << t.name << "’ on line " << t.lineNumber << "STATE == BUS" << std::endl; return false; } } else if (STATE == BUS_MSB) { if (t.type == evl_token::SINGLE && t.name == ":") { STATE = BUS_COLON; } else if(t.type == evl_token::SINGLE && t.name == "]") { pin.lsb = pin.msb; STATE = BUS_DONE; } else { cerr << "Need ’:’ or ']' but found ’" << t.name << "’ on line " << t.lineNumber << std::endl; return false; } } else if (STATE == BUS_COLON ) { if (t.type == evl_token::NUMBER) { int lsb = atoi(t.name.c_str()); if (!(pin.msb >= lsb && lsb >= 0)) { cerr << "Pin is not within wire range!"<<endl; return false; } pin.lsb = lsb; STATE = BUS_LSB; } else { cerr << "Need a NUMBER but found ’" << t.name << "’ on line " << t.lineNumber << std::endl; return false; } } else if (STATE == BUS_LSB) { if (t.type == evl_token::SINGLE && t.name == "]") { STATE = BUS_DONE; } else { cerr << "Need ’]’ but found ’" << t.name << "’ on line " << t.lineNumber << std::endl; return false; } } else if (STATE == BUS_DONE) { if (t.type == evl_token::SINGLE && t.name == ")") { component.pins.push_back(pin); STATE = PINS_DONE; } else if(t.type == evl_token::SINGLE && t.name == ",") { component.pins.push_back(pin); STATE = PINS; } else { cerr << "Need ')' or ',' but found "<< t.name << "on line "<<t.lineNumber << endl; return false; } } else if(STATE == PINS_DONE) { if (t.type == evl_token::SINGLE && t.name == ";") { cp.push_back(component); STATE = DONE; } } else { assert(false); } } if (!s.tokens.empty() || (STATE != DONE)) { cerr << "There is something wrong with the statement" << endl; return false; } return true; }
bool process_component_statements(evl_components &components, evl_statement &s, evl_wires &wires, evl_checkpoints &check) { //assert(s.type == evl_statement::COMPONENT); enum state_type {INIT, TYPE, NAME, PINS, PIN_NAME, PINS_DONE, BUS, BUS_MSB, BUS_COLON, BUS_LSB, BUS_DONE, DONE}; std::string comp_type = ""; std::string comp_name = "NONE"; std::string pin_name = ""; int bus_msb = -1; int bus_lsb = -1; int count = 0; int count_2; state_type state = INIT; for(; !s.tokens.empty() && (state != DONE); s.tokens.pop_front()){ evl_token t = s.tokens.front(); if (state == INIT) { if(t.type == evl_token::NAME) { comp_type = t.str; state = TYPE; } else { state = TYPE; } } else if (state == TYPE){ if (t.type == evl_token::SINGLE && t.str == "(") { state = PINS; } else { std::cerr << "Need a NAME or a '(' but found '" << t.str << "' at line " << t.line_no << std::endl; return false; } evl_component component; component.type = comp_type; component.name = comp_name; components.push_back(component); count_2 = 0; } else if (state == PINS) { //int count = 0; if (t.type == evl_token::NAME) { evl_wires::iterator it = wires.find(t.str); if (it == wires.end()) { std::cerr << "Wire '" << t.str << "' on line " << t.line_no << " is not defined" << std::endl; return false; } count = it->second + count_2; it->second = ++count; pin_name = t.str; } state = PIN_NAME; } else if (state == PIN_NAME) { bus_msb = -1; bus_lsb = -1; //int count = 0; if (t.str == ")"){ evl_wires::iterator it = wires.find(pin_name); count = it->second + count_2; it->second = ++count; //if (it->second >= 2) { // bus_msb = it->second-1; // bus_lsb = 0; //} evl_pin pins; pins.lsb = bus_lsb; pins.msb = bus_msb; pins.pin_name = pin_name; components.back().comp_pins.push_back(pins); state = DONE; } else if (t.str == ","){ evl_wires::iterator it = wires.find(pin_name); //if (it->second >= 2) { // bus_msb = it->second-1; // bus_lsb = 0; //} count = it->second + count_2; it->second = ++count; evl_pin pins; pins.lsb = bus_lsb; pins.msb = bus_msb; pins.pin_name = pin_name; components.back().comp_pins.push_back(pins); state = PINS; } else { std::cerr << "Need ',' or ')' or '[' but found '" << t.str << "' on line " << t.line_no <<std::endl; return false; } } else { assert(false); //never should get here } } if (!s.tokens.empty() || (state != DONE)) { std::cerr << "something wrong with the statement in Comp" << std::endl; return false; } return true; }
bool process_wire_statements(evl_wires &wires, evl_statement &s) { assert(s.type == evl_statement::WIRE); enum state_type {INIT, WIRE,IO, WIRES, WIRE_NAME, BUS, BUS_MSB, BUS_COLON, BUS_LSB, BUS_DONE, DONE}; state_type state = INIT; int bus_width = 1; for (; !s.tokens.empty() && (state != DONE); s.tokens.pop_front()) { evl_token t = s.tokens.front(); if (state == INIT) { if ((t.str == "INPUT") || (t.str == "OUTPUT")) { state = IO; } else { if (t.type == evl_token::NAME) { evl_wires::iterator it = wires.find(t.str); if(it != wires.end()) { std::cerr << "Wire '" << t.str << "' on line " << t.line_no << " is already defined" << std::endl; return false; } wires.insert(std::make_pair(t.str, bus_width)); state = WIRE_NAME; } } } else if (state == IO) { if (t.type == evl_token::SINGLE) { if(t.str != "("){ std::cerr << "Need a '(' but found '" << t.str << "' on line" << t.line_no << std::endl; return false; } state = WIRE; } else { std::cerr << "Need Input or Output designation but found '" << t.str << "' on line " << t.line_no << std::endl; return false; } } else if (state == WIRE) { if (t.type == evl_token::NAME) { evl_wires::iterator it = wires.find(t.str); if(it != wires.end()) { std::cerr << "Wire '" << t.str << "' on line " << t.line_no << " is already defined" << std::endl; return false; } wires.insert(std::make_pair(t.str, bus_width)); state = WIRE_NAME; } else { std::cerr << "Need 'wire' but found '" << t.str << "' on line " << t.line_no << std::endl; return false; } } else if (state == WIRE_NAME) { if ((t.str == ")") || (t.str == "=")) { state = DONE; } else { std::cerr << "Need ',' or ';' but found '" << t.str << "' on line " << t.line_no << std::endl; return false; } } else { assert(false); //never should get here } } if (!s.tokens.empty() || (state != DONE)) { std::cerr << "something wrong with the statement in wires" << std::endl; return false; } return true; }
bool process_component_statements(evl_components &components, evl_statement &s, const evl_wires &wires) { assert(s.type == evl_statement::COMPONENT); enum state_type {INIT, TYPE, NAME, PINS, PIN_NAME, PINS_DONE, BUS, BUS_MSB, BUS_COLON, BUS_LSB, BUS_DONE, DONE}; std::string comp_type = ""; std::string comp_name = "NONE"; std::string pin_name = ""; int bus_msb = -1; int bus_lsb = -1; state_type state = INIT; for(; !s.tokens.empty() && (state != DONE); s.tokens.pop_front()){ evl_token t = s.tokens.front(); if (state == INIT) { if(t.type == evl_token::NAME) { comp_type = t.str; state = TYPE; } else { state = TYPE; } } else if (state == TYPE){ if (t.type == evl_token::NAME) { comp_name = t.str; state = NAME; } else if (t.type == evl_token::SINGLE && t.str == "(") { state = PINS; } else { std::cerr << "Need a NAME or a '(' but found '" << t.str << "' at line " << t.line_no << std::endl; return false; } evl_component component; component.type = comp_type; component.name = comp_name; components.push_back(component); } else if (state == NAME) { if (t.type == evl_token::SINGLE && t.str == "("){ state = PINS; } else { std::cerr << "Need '(' but found '" << t.str << "' at line " << t.line_no << std::endl; return false; } } else if (state == PINS) { if (t.type == evl_token::NAME) { evl_wires::const_iterator it = wires.find(t.str); if (it == wires.end()) { std::cerr << "Wire '" << t.str << "' on line " << t.line_no << " is not defined" << std::endl; return false; } pin_name = t.str; } state = PIN_NAME; } else if (state == PIN_NAME) { bus_msb = -1; bus_lsb = -1; if (t.str == ")"){ evl_wires::const_iterator it = wires.find(pin_name); if (it->second >= 2) { bus_msb = it->second-1; bus_lsb = 0; } evl_pin pins; pins.lsb = bus_lsb; pins.msb = bus_msb; pins.pin_name = pin_name; components.back().comp_pins.push_back(pins); state = PINS_DONE; } else if (t.str == ","){ evl_wires::const_iterator it = wires.find(pin_name); if (it->second >= 2) { bus_msb = it->second-1; bus_lsb = 0; } evl_pin pins; pins.lsb = bus_lsb; pins.msb = bus_msb; pins.pin_name = pin_name; components.back().comp_pins.push_back(pins); state = PINS; } else if (t.str == "[") { state = BUS; } else { std::cerr << "Need ',' or ')' or '[' but found '" << t.str << "' on line " << t.line_no <<std::endl; return false; } } else if (state == BUS) { if(t.type == evl_token::NUMBER) { bus_msb = atoi(t.str.c_str()); } else { std::cerr << "Need 'number' but found '" << t.str << "' on line " << t.line_no << std::endl; return false; } state = BUS_MSB; } else if (state == BUS_MSB) { if (t.str == "]") { evl_wires::const_iterator it = wires.find(pin_name); int found_wire_msb = it->second-1; if (bus_msb > found_wire_msb){ std::cerr << "Bus MSB of value: " << bus_msb << " must be greater than or equal to the wire bus msb of value: " << found_wire_msb << std::endl; return false; } if (bus_msb < 0) { std::cerr << "Bus MSB of value: " << bus_msb << " must be greater than 0." << std::cout; } bus_lsb = bus_msb; state = BUS_DONE; } else if (t.str == ":") { state = BUS_COLON; } else { std::cerr << "Need ']' or ':' but found '" << t.str << "' on line " << t.line_no <<std::endl; return false; } } else if (state == BUS_COLON) { evl_wires::const_iterator it = wires.find(pin_name); int found_wire_msb = it->second-1; if (t.type == evl_token::NUMBER) { bus_lsb = atoi(t.str.c_str()); } else { std::cerr << "Need 'number' but found '" << t.str << "' on line " << t.line_no << std::endl; return false; } if (bus_msb < bus_lsb) { std::cerr << "Bus msb: " << bus_msb << " can not be less than Bus lsb " << bus_lsb << std::endl; return false; } if (bus_msb > found_wire_msb) { std::cerr << "Bus msb is: " << bus_msb << ". Needs to less than or equal to wire bus msb: " << found_wire_msb << std::endl; return false; } if (bus_lsb < 0) { std::cerr << "Bus lsb is: " << bus_lsb << ". Needs to be greater than 0" << std::endl; return false; } state = BUS_LSB; } else if (state == BUS_LSB) { if (!(t.str == "]")) { std::cerr << "Need ']' but found '" << t.str << "' on line " << t.line_no << std::endl; return false; } state = BUS_DONE; } else if (state == BUS_DONE) { if (t.str == ")") { evl_pin pins; pins.lsb = bus_lsb; pins.msb = bus_msb; pins.pin_name = pin_name; components.back().comp_pins.push_back(pins); state = PINS_DONE; } else if (t.str == ",") { evl_pin pins; pins.lsb = bus_lsb; pins.msb = bus_msb; pins.pin_name = pin_name; components.back().comp_pins.push_back(pins); state = PINS; } } else if (state == PINS_DONE) { if (t.str == ";") { state = DONE; } else { std::cerr << "Need ';' but found '" << t.str << "' on line " << t.line_no << std::endl; return false; } } else { assert(false); //never should get here } } if (!s.tokens.empty() || (state != DONE)) { std::cerr << "something wrong with the statement in Comp" << std::endl; return false; } return true; }
bool process_wire_statements(evl_wires &wires, evl_statement &s) { assert(s.type == evl_statement::WIRE); enum state_type {INIT, WIRE, WIRES, WIRE_NAME, BUS, BUS_MSB, BUS_COLON, BUS_LSB, BUS_DONE, DONE}; state_type state = INIT; int bus_width = 1; for (; !s.tokens.empty() && (state != DONE); s.tokens.pop_front()) { evl_token t = s.tokens.front(); if (state == INIT) { if (t.str == "wire") { state = WIRE; } else { std::cerr << "Need 'wire' but found '" << t.str << "' on line " << t.line_no << std::endl; return false; } } else if (state == WIRE) { if (t.type == evl_token::NAME) { evl_wires::iterator it = wires.find(t.str); if(it != wires.end()) { std::cerr << "Wire '" << t.str << "' on line " << t.line_no << " is already defined" << std::endl; return false; } wires.insert(std::make_pair(t.str, bus_width)); state = WIRE_NAME; } else if (t.type == evl_token::SINGLE) { if(t.str != "["){ std::cerr << "Need a '[' buf found '" << t.str << "' on line" << t.line_no << std::endl; return false; } state = BUS; } else { std::cerr << "Need 'wire' but found '" << t.str << "' on line " << t.line_no << std::endl; return false; } } else if (state == WIRES) { if (t.type == evl_token::NAME) { evl_wires::iterator it = wires.find(t.str); if(it != wires.end()) { std::cerr << "Wire '" << t.str << "' on line " << t.line_no << " is already defined" << std::endl; return false; } wires.insert(std::make_pair(t.str, bus_width)); state = WIRE_NAME; } } else if (state == BUS){ if(t.type == evl_token::NUMBER) { bus_width = atoi(t.str.c_str())+1; if(bus_width < 2) { std::cerr << "Bus width entered is " << bus_width << " but needs a bus width of at least 2. Line No: " << t.line_no << std::endl; return false; } } else { std::cerr << "Need 'number' but found '" << t.str << "' on line " << t.line_no << std::endl; return false; } state = BUS_MSB; } else if (state == BUS_MSB) { if(t.str != ":") { std::cerr << "Need a ':' buf found '" << t.str << "' on line " << t.line_no << std::endl; return false; } state = BUS_COLON; } else if (state == BUS_COLON) { if(t.type == evl_token::NUMBER) { if(t.str != "0"){ std::cerr << "Need a '0' buf found '" << t.str << "' on line " << t.line_no << std::endl; return false; } state = BUS_LSB; } } else if (state == BUS_LSB) { if(t.type == evl_token::SINGLE) { if (t.str != "]") { std::cerr << "Need a ']' buf found '" << t.str << "' on line" << t.line_no << std::endl; return false; } state = BUS_DONE; } } else if (state == BUS_DONE) { wires.insert(std::make_pair(t.str, bus_width)); state = WIRE_NAME; } else if (state == WIRE_NAME) { if (t.str == ",") { state = WIRES; } else if (t.str == ";") { state = DONE; } else { std::cerr << "Need ',' or ';' but found '" << t.str << "' on line " << t.line_no << std::endl; return false; } } else { assert(false); //never should get here } } if (!s.tokens.empty() || (state != DONE)) { std::cerr << "something wrong with the statement in wires" << std::endl; return false; } return true; }