diff --git a/himbaechel/uarch/ng-ultra/csv.cc b/himbaechel/uarch/ng-ultra/csv.cc index 50619db0..9b07db3c 100644 --- a/himbaechel/uarch/ng-ultra/csv.cc +++ b/himbaechel/uarch/ng-ultra/csv.cc @@ -91,109 +91,139 @@ void NgUltraImpl::parse_csv(const std::string &filename) if (arguments.size()!=15) log_error("number of parameters in line %d must be 15\n", lineno); - if (!(boost::starts_with(arguments.at(1), "IOB") && boost::contains(arguments.at(1),"_D"))) - log_error("invalid location name '%s' must start with 'IOB' in line %d\n", arguments.at(1).c_str(), lineno); + std::string arg_iobname = arguments.at(0); + std::string arg_location = arguments.at(1); + std::string arg_standard = arguments.at(2); + std::string arg_drive = arguments.at(3); + std::string arg_slewRate = arguments.at(4); + std::string arg_inputDelayLine = arguments.at(5); + std::string arg_outputDelayLine = arguments.at(6); + std::string arg_differential = arguments.at(7); + std::string arg_weakTermination = arguments.at(8); + std::string arg_termination = arguments.at(9); + std::string arg_terminationReference = arguments.at(10); + std::string arg_turbo = arguments.at(11); + std::string arg_inputSignalSlope = arguments.at(12); + std::string arg_outputCapacity = arguments.at(13); + std::string arg_registered = arguments.at(14); + + // TODO: Remove this block + const char* weak_values_check[] = { "None", "PullDown", "PullUp", "Keeper" }; + auto it2 = std::find(std::begin(weak_values_check),std::end(weak_values_check), arguments.at(4)); + if (it2 != std::end(weak_values_check)) { + log_warning("Old CSV format detected. Please update file.\n"); + arg_weakTermination = arguments.at(4); + arg_slewRate = arguments.at(5); + arg_termination = arguments.at(6); + arg_inputDelayLine = arguments.at(7); + arg_outputDelayLine = arguments.at(8); + arg_differential = arguments.at(9); + } + // End of block + + if (!(boost::starts_with(arg_location, "IOB") && boost::contains(arg_location,"_D"))) + log_error("invalid location name '%s' must start with 'IOB' in line %d\n", arg_location.c_str(), lineno); const char* standard_values[] = { "LVDS", "LVCMOS", "SSTL", "HSTL" }; // , "POD" - auto it = std::find(std::begin(standard_values),std::end(standard_values), arguments.at(2)); + auto it = std::find(std::begin(standard_values),std::end(standard_values), arg_standard); if (it == std::end(standard_values)) - log_error("unknown standard value '%s' in line %d\n", arguments.at(2).c_str(), lineno); + log_error("unknown standard value '%s' in line %d\n", arg_standard.c_str(), lineno); const char* drive_values[] = { "2mA", "4mA", "8mA", "16mA", "CatI", "CatII", "Undefined" }; // "6mA", "12mA", - it = std::find(std::begin(drive_values),std::end(drive_values), arguments.at(3)); + it = std::find(std::begin(drive_values),std::end(drive_values), arg_drive); if (it == std::end(drive_values)) - log_error("unknown drive value '%s' in line %d\n", arguments.at(3).c_str(), lineno); + log_error("unknown drive value '%s' in line %d\n", arg_drive.c_str(), lineno); const char* slew_values[] = { "Slow", "Medium", "Fast" }; - it = std::find(std::begin(slew_values),std::end(slew_values), arguments.at(4)); + it = std::find(std::begin(slew_values),std::end(slew_values), arg_slewRate); if (it == std::end(slew_values)) - log_error("unknown weak termination value '%s' in line %d\n", arguments.at(4).c_str(), lineno); + log_error("unknown weak termination value '%s' in line %d\n", arg_slewRate.c_str(), lineno); - if (!arguments.at(5).empty() && !is_number(arguments.at(5))) { - log_error("input delay must be number, value '%s' in line %d\n", arguments.at(5).c_str(), lineno); - int delay = std::stoi(arguments.at(5)); + if (!arg_inputDelayLine.empty() && !is_number(arg_inputDelayLine)) { + log_error("input delay must be number, value '%s' in line %d\n", arg_inputDelayLine.c_str(), lineno); + int delay = std::stoi(arg_inputDelayLine); if (delay<0 || delay >63) log_error("input delay value must be in range from 0 to 63 in line %d\n", lineno); } - if (!arguments.at(6).empty() && !is_number(arguments.at(6))) { - log_error("output delay must be number, value '%s' in line %d\n", arguments.at(6).c_str(), lineno); - int delay = std::stoi(arguments.at(6)); + if (!arg_outputDelayLine.empty() && !is_number(arg_outputDelayLine)) { + log_error("output delay must be number, value '%s' in line %d\n", arg_outputDelayLine.c_str(), lineno); + int delay = std::stoi(arg_outputDelayLine); if (delay<0 || delay >63) log_error("output delay value must be in range from 0 to 63 in line %d\n", lineno); } - if (!arguments.at(7).empty() && arguments.at(7) != "True" && arguments.at(7) != "False") - log_error("differential must be boolean, value '%s' in line %d\n", arguments.at(7).c_str(), lineno); + if (!arg_differential.empty() && arg_differential != "True" && arg_differential != "False") + log_error("differential must be boolean, value '%s' in line %d\n", arg_differential.c_str(), lineno); const char* weak_values[] = { "None", "PullDown", "PullUp", "Keeper" }; - it = std::find(std::begin(weak_values),std::end(weak_values), arguments.at(8)); + it = std::find(std::begin(weak_values),std::end(weak_values), arg_weakTermination); if (it == std::end(weak_values)) - log_error("unknown weak termination value '%s' in line %d\n", arguments.at(8).c_str(), lineno); + log_error("unknown weak termination value '%s' in line %d\n", arg_weakTermination.c_str(), lineno); - if (!arguments.at(9).empty() && !is_number(arguments.at(9))) { - log_error("termination must be string containing int, value '%s' in line %d\n", arguments.at(9).c_str(), lineno); - int termination = std::stoi(arguments.at(9)); + if (!arg_termination.empty() && !is_number(arg_termination)) { + log_error("termination must be string containing int, value '%s' in line %d\n", arg_termination.c_str(), lineno); + int termination = std::stoi(arg_termination); if (termination<30 || termination >80) log_error("termination value must be in range from 30 to 80 in line %d\n", lineno); } const char* termref_values[] = { "Floating", "VT" }; - it = std::find(std::begin(termref_values),std::end(termref_values), arguments.at(10)); + it = std::find(std::begin(termref_values),std::end(termref_values), arg_terminationReference); if (it == std::end(termref_values)) - log_error("unknown termination reference value '%s' in line %d\n", arguments.at(10).c_str(), lineno); + log_error("unknown termination reference value '%s' in line %d\n", arg_terminationReference.c_str(), lineno); - if (!arguments.at(11).empty() && arguments.at(11) != "True" && arguments.at(11) != "False") - log_error("turbo must be boolean, value '%s' in line %d\n", arguments.at(11).c_str(), lineno); + if (!arg_turbo.empty() && arg_turbo != "True" && arg_turbo != "False") + log_error("turbo must be boolean, value '%s' in line %d\n", arg_turbo.c_str(), lineno); - if (!arguments.at(12).empty() && !is_number(arguments.at(12))) - log_error("signal slope must be number, value '%s' in line %d\n", arguments.at(12).c_str(), lineno); - if (!arguments.at(13).empty() && !is_number(arguments.at(13))) - log_error("output capacity must be number, value '%s' in line %d\n", arguments.at(13).c_str(), lineno); + if (!arg_inputSignalSlope.empty() && !is_number(arg_inputSignalSlope)) + log_error("signal slope must be number, value '%s' in line %d\n", arg_inputSignalSlope.c_str(), lineno); + if (!arg_outputCapacity.empty() && !is_number(arg_outputCapacity)) + log_error("output capacity must be number, value '%s' in line %d\n", arg_outputCapacity.c_str(), lineno); const char* registered_values[] = { "Auto", "I", "IC", "O", "OC", "IO", "IOC" }; - it = std::find(std::begin(registered_values),std::end(registered_values), arguments.at(14)); + it = std::find(std::begin(registered_values),std::end(registered_values), arg_registered); if (it == std::end(registered_values)) - log_error("unknown registered value '%s' in line %d\n", arguments.at(14).c_str(), lineno); + log_error("unknown registered value '%s' in line %d\n", arg_registered.c_str(), lineno); - if (arguments.at(2)=="LVDS" && arguments.at(3)!="Undefined") + if (arg_standard=="LVDS" && arg_drive!="Undefined") log_error("for port in line %d when standard is 'LVDS' drive must be 'Undefined'\n", lineno); - if (arguments.at(2)=="LVCMOS" && !boost::ends_with(arguments.at(3),"mA")) + if (arg_standard=="LVCMOS" && !boost::ends_with(arg_drive,"mA")) log_error("for port in line %d when standard is 'LVCMOS' drive current must be in mA\n", lineno); - if ((arguments.at(2)=="SSTL" || arguments.at(2)=="HSTL") && !boost::starts_with(arguments.at(3),"Cat")) + if ((arg_standard=="SSTL" || arg_standard=="HSTL") && !boost::starts_with(arg_drive,"Cat")) log_error("for port in line %d when standard is 'SSTL' or 'HSTL' drive current must be in 'CatI' or 'CatII'\n", lineno); - if (arguments.at(10)=="Floating") { - if (!(arguments.at(7) == "True" && arguments.at(8) == "None")) { + if (arg_terminationReference=="Floating") { + if (!(arg_differential == "True" && arg_weakTermination == "None")) { log_error("for floating termination, differential myst be 'True' and weakTermination must be 'None' in line %d\n", lineno); } } - std::vector dest = get_cells(arguments.at(0)); + std::vector dest = get_cells(arg_iobname); for (auto c : dest) { - c->params[ctx->id("iobname")] = arguments.at(0); - c->params[ctx->id("location")] = arguments.at(1); - c->params[ctx->id("standard")] = arguments.at(2); - c->params[ctx->id("drive")] = arguments.at(3); - c->params[ctx->id("slewRate")] = arguments.at(4); - c->params[ctx->id("inputDelayLine")] = arguments.at(5); - c->params[ctx->id("outputDelayLine")] = arguments.at(6); - c->params[ctx->id("inputDelayOn")] = std::string((std::stoi(arguments.at(5))!=0) ? "True" : "False"); - c->params[ctx->id("outputDelayOn")] = std::string((std::stoi(arguments.at(6))!=0) ? "True" : "False"); - c->params[ctx->id("differential")] = arguments.at(7); - c->params[ctx->id("weakTermination")] = arguments.at(8); - if (!arguments.at(9).empty()) { - c->params[ctx->id("termination")] = arguments.at(9); - c->params[ctx->id("terminationReference")] = arguments.at(10); + c->params[ctx->id("iobname")] = arg_iobname; + c->params[ctx->id("location")] = arg_location; + c->params[ctx->id("standard")] = arg_standard; + c->params[ctx->id("drive")] = arg_drive; + c->params[ctx->id("slewRate")] = arg_slewRate; + c->params[ctx->id("inputDelayLine")] = arg_inputDelayLine; + c->params[ctx->id("outputDelayLine")] = arg_outputDelayLine; + c->params[ctx->id("inputDelayOn")] = std::string((std::stoi(arg_inputDelayLine)!=0) ? "True" : "False"); + c->params[ctx->id("outputDelayOn")] = std::string((std::stoi(arg_outputDelayLine)!=0) ? "True" : "False"); + c->params[ctx->id("differential")] = arg_differential; + c->params[ctx->id("weakTermination")] = arg_weakTermination; + if (!arg_termination.empty()) { + c->params[ctx->id("termination")] = arg_termination; + c->params[ctx->id("terminationReference")] = arg_terminationReference; } - c->params[ctx->id("turbo")] = arguments.at(11); - c->params[ctx->id("inputSignalSlope")] = arguments.at(12); - c->params[ctx->id("outputCapacity")] = arguments.at(13); - c->params[ctx->id("registered")] = arguments.at(14); + c->params[ctx->id("turbo")] = arg_turbo; + c->params[ctx->id("inputSignalSlope")] = arg_inputSignalSlope; + c->params[ctx->id("outputCapacity")] = arg_outputCapacity; + c->params[ctx->id("registered")] = arg_registered; } if (dest.size()==0) - log_warning("Pad with name '%s' not found in netlist.\n", arguments.at(0).c_str()); + log_warning("Pad with name '%s' not found in netlist.\n", arg_iobname.c_str()); - std::string bank_name = arguments.at(1).substr(0,arguments.at(1).find_first_of('_')); + std::string bank_name = arg_location.substr(0,arg_location.find_first_of('_')); banks_used.emplace(bank_name); } break;