Esempio n. 1
0
void nl_convert_spice_t::convert(const pstring &contents)
{
	pstring_vector_t spnl(contents, "\n");

	// Add gnd net

	// FIXME: Parameter
	out("NETLIST_START(dummy)\n");
	add_term("0", "GND");

	pstring line = "";

	for (std::size_t i=0; i < spnl.size(); i++)
	{
		// Basic preprocessing
		pstring inl = spnl[i].trim().ucase();
		if (inl.startsWith("+"))
			line = line + inl.substr(1);
		else
		{
			process_line(line);
			line = inl;
		}
	}
	process_line(line);
	dump_nl();
	// FIXME: Parameter
	out("NETLIST_END()\n");
}
Esempio n. 2
0
void nl_convert_spice_t::convert(const pstring &contents)
{
	std::vector<pstring> spnl(plib::psplit(contents, "\n"));

	// Add gnd net

	// FIXME: Parameter
	out("NETLIST_START(dummy)\n");
	add_term("0", "GND");

	pstring line = "";

	for (const auto &i : spnl)
	{
		// Basic preprocessing
		pstring inl = plib::ucase(plib::trim(i));
		if (plib::startsWith(inl, "+"))
			line = line + inl.substr(1);
		else
		{
			process_line(line);
			line = inl;
		}
	}
	process_line(line);
	dump_nl();
	// FIXME: Parameter
	out("NETLIST_END()\n");
}
Esempio n. 3
0
//FIXME: should accept a stream as well
void nl_convert_eagle_t::convert(const pstring &contents)
{
	pistringstream istrm(contents);
	eagle_tokenizer tok(*this, istrm);

	out("NETLIST_START(dummy)\n");
	add_term("GND", "GND");
	add_term("VCC", "VCC");
	eagle_tokenizer::token_t token = tok.get_token();
	while (true)
	{
		if (token.is_type(eagle_tokenizer::ENDOFFILE))
		{
			dump_nl();
			// FIXME: Parameter
			out("NETLIST_END()\n");
			return;
		}
		else if (token.is(tok.m_tok_SEMICOLON))
		{
			/* ignore empty statements */
			token = tok.get_token();
		}
		else if (token.is(tok.m_tok_ADD))
		{
			pstring name = tok.get_string();
			/* skip to semicolon */
			do
			{
				token = tok.get_token();
			} while (!token.is(tok.m_tok_SEMICOLON));
			token = tok.get_token();
			pstring sval = "";
			if (token.is(tok.m_tok_VALUE))
			{
				pstring vname = tok.get_string();
				sval = tok.get_string();
				tok.require_token(tok.m_tok_SEMICOLON);
				token = tok.get_token();
			}
			switch (name.code_at(0))
			{
				case 'Q':
				{
					add_device("QBJT", name, sval);
				}
					break;
				case 'R':
					{
						double val = get_sp_val(sval);
						add_device("RES", name, val);
					}
					break;
				case 'C':
					{
						double val = get_sp_val(sval);
						add_device("CAP", name, val);
					}
					break;
				case 'P':
					if (sval.ucase() == "HIGH")
						add_device("TTL_INPUT", name, 1);
					else if (sval.ucase() == "LOW")
						add_device("TTL_INPUT", name, 0);
					else
						add_device("ANALOG_INPUT", name, sval.as_double());
					add_pin_alias(name, "1", "Q");
					break;
				case 'D':
					/* Pin 1 = Anode, Pin 2 = Cathode */
					add_device("DIODE", name, sval);
					add_pin_alias(name, "1", "A");
					add_pin_alias(name, "2", "K");
					break;
				case 'U':
				case 'X':
				{
					pstring tname = "TTL_" + sval + "_DIP";
					add_device(tname, name);
					break;
				}
				default:
					tok.error("// IGNORED " + name);
			}

		}
		else if (token.is(tok.m_tok_SIGNAL))
		{
			pstring netname = tok.get_string();
			token = tok.get_token();
			while (!token.is(tok.m_tok_SEMICOLON))
			{
				/* fixme: should check for string */
				pstring devname = token.str();
				pstring pin = tok.get_string();
				add_term(netname, devname + "." + pin);
				token = tok.get_token();                }
		}
		else
		{
			out("Unexpected {}\n", token.str().cstr());
			return;
		}
	}

}
Esempio n. 4
0
void nl_convert_spice_t::process_line(const pstring &line)
{
	if (line != "")
	{
		pstring_vector_t tt(line, " ", true);
		double val = 0.0;
		switch (tt[0].code_at(0))
		{
			case ';':
				out("// {}\n", line.substr(1).cstr());
				break;
			case '*':
				out("// {}\n", line.substr(1).cstr());
				break;
			case '.':
				if (tt[0].equals(".SUBCKT"))
				{
					out("NETLIST_START({})\n", tt[1].cstr());
					for (std::size_t i=2; i<tt.size(); i++)
						add_ext_alias(tt[i]);
				}
				else if (tt[0].equals(".ENDS"))
				{
					dump_nl();
					out("NETLIST_END()\n");
				}
				else
					out("// {}\n", line.cstr());
				break;
			case 'Q':
			{
				bool cerr = false;
				/* check for fourth terminal ... should be numeric net
				 * including "0" or start with "N" (ltspice)
				 */
				ATTR_UNUSED int nval =tt[4].as_long(&cerr);
				pstring model;
				pstring pins ="CBE";

				if ((!cerr || tt[4].startsWith("N")) && tt.size() > 5)
					model = tt[5];
				else
					model = tt[4];
				pstring_vector_t m(model,"{");
				if (m.size() == 2)
				{
					if (m[1].len() != 4)
						fprintf(stderr, "error with model desc %s\n", model.cstr());
					pins = m[1].left(3);
				}
				add_device("QBJT_EB", tt[0], m[0]);
				add_term(tt[1], tt[0] + "." + pins.code_at(0));
				add_term(tt[2], tt[0] + "." + pins.code_at(1));
				add_term(tt[3], tt[0] + "." + pins.code_at(2));
			}
				break;
			case 'R':
				if (tt[0].startsWith("RV"))
				{
					val = get_sp_val(tt[4]);
					add_device("POT", tt[0], val);
					add_term(tt[1], tt[0] + ".1");
					add_term(tt[2], tt[0] + ".2");
					add_term(tt[3], tt[0] + ".3");
				}
				else
				{
					val = get_sp_val(tt[3]);
					add_device("RES", tt[0], val);
					add_term(tt[1], tt[0] + ".1");
					add_term(tt[2], tt[0] + ".2");
				}
				break;
			case 'C':
				val = get_sp_val(tt[3]);
				add_device("CAP", tt[0], val);
				add_term(tt[1], tt[0] + ".1");
				add_term(tt[2], tt[0] + ".2");
				break;
			case 'V':
				// just simple Voltage sources ....
				if (tt[2].equals("0"))
				{
					val = get_sp_val(tt[3]);
					add_device("ANALOG_INPUT", tt[0], val);
					add_term(tt[1], tt[0] + ".Q");
					//add_term(tt[2], tt[0] + ".2");
				}
				else
					fprintf(stderr, "Voltage Source %s not connected to GND\n", tt[0].cstr());
				break;
			case 'I': // Input pin special notation
				{
					val = get_sp_val(tt[2]);
					add_device("ANALOG_INPUT", tt[0], val);
					add_term(tt[1], tt[0] + ".Q");
				}
				break;
			case 'D':
				add_device("DIODE", tt[0], tt[3]);
				/* FIXME ==> does Kicad use different notation from LTSPICE */
				add_term(tt[1], tt[0] + ".K");
				add_term(tt[2], tt[0] + ".A");
				break;
			case 'U':
			case 'X':
			{
				// FIXME: specific code for KICAD exports
				//        last element is component type
				// FIXME: Parameter

				pstring xname = tt[0].replace(".", "_");
				pstring tname = "TTL_" + tt[tt.size()-1] + "_DIP";
				add_device(tname, xname);
				for (std::size_t i=1; i < tt.size() - 1; i++)
				{
					pstring term = pfmt("{1}.{2}")(xname)(i);
					add_term(tt[i], term);
				}
				break;
			}
			default:
				out("// IGNORED {}: {}\n", tt[0].cstr(), line.cstr());
		}
	}
}
Esempio n. 5
0
void nl_convert_rinf_t::convert(const pstring &contents)
{
	tokenizer tok(*this, plib::putf8_reader(plib::pistringstream(contents)));
	auto lm = read_lib_map(s_lib_map);

	out("NETLIST_START(dummy)\n");
	add_term("GND", "GND");
	add_term("VCC", "VCC");
	tokenizer::token_t token = tok.get_token();
	while (true)
	{
		if (token.is_type(tokenizer::ENDOFFILE) || token.is(tok.m_tok_END))
		{
			dump_nl();
			// FIXME: Parameter
			out("NETLIST_END()\n");
			return;
		}
		else if (token.is(tok.m_tok_HEA))
		{
			/* seems to be start token - ignore */
			token = tok.get_token();
		}
		else if (token.is(tok.m_tok_APP))
		{
			/* version string */
			pstring app = tok.get_string();
			out("// APP: {}\n", app);
			token = tok.get_token();
		}
		else if (token.is(tok.m_tok_TIM))
		{
			/* time */
			out("// TIM:");
			for (int i=0; i<6; i++)
			{
				long x = tok.get_number_long();
				out(" {}", x);
			}
			out("\n");
			token = tok.get_token();
		}
		else if (token.is(tok.m_tok_TYP))
		{
			pstring id(tok.get_identifier());
			out("// TYP: {}\n", id);
			token = tok.get_token();
		}
		else if (token.is(tok.m_tok_ADDC))
		{
			std::unordered_map<pstring, pstring> attr;
			pstring id = tok.get_identifier();
			pstring s1 = tok.get_string();
			pstring s2 = tok.get_string();

			token = tok.get_token();
			while (token.is(tok.m_tok_ATTC))
			{
				pstring tid = tok.get_identifier();
				if (tid != id)
				{
					out("Error: found {} expected {} in {}\n", tid, id, token.str());
					return;
				}
				pstring at = tok.get_string();
				pstring val = tok.get_string();
				attr[at] = val;
				token = tok.get_token();
			}
			pstring sim = attr["Simulation"];
			pstring val = attr["Value"];
			pstring com = attr["Comment"];
			if (val == "")
				val = com;

			if (sim == "CAP")
			{
				add_device("CAP", id, get_sp_val(val));
			}
			else if (sim == "RESISTOR")
			{
				add_device("RES", id, get_sp_val(val));
			}
			else
			{
				pstring lib = attr["Library Reference"];
				auto f = lm.find(lib);
				if (f != lm.end())
					add_device(f->second.dev, id);
				else
					add_device(lib, id);
			}
		}
		else if (token.is(tok.m_tok_NET))
		{
			pstring dev = tok.get_identifier();
			pstring pin = tok.get_identifier_or_number();
			pstring net = tok.get_string();
			add_term(net, dev + "." + pin);
			token = tok.get_token();
			if (token.is(tok.m_tok_TER))
			{
				token = tok.get_token();
				while (token.is_type(plib::ptokenizer::IDENTIFIER))
				{
					pin = tok.get_identifier_or_number();
					add_term(net, token.str() + "." + pin);
					token = tok.get_token();
				}
			}
		}
#if 0
			token = tok.get_token();
			/* skip to semicolon */
			do
			{
				token = tok.get_token();
			} while (!token.is(tok.m_tok_SEMICOLON));
			token = tok.get_token();
			pstring sval = "";
			if (token.is(tok.m_tok_VALUE))
			{
				pstring vname = tok.get_string();
				sval = tok.get_string();
				tok.require_token(tok.m_tok_SEMICOLON);
				token = tok.get_token();
			}
			switch (name.code_at(0))
			{
				case 'Q':
				{
					add_device("QBJT", name, sval);
				}
					break;
				case 'R':
					{
						double val = get_sp_val(sval);
						add_device("RES", name, val);
					}
					break;
				case 'C':
					{
						double val = get_sp_val(sval);
						add_device("CAP", name, val);
					}
					break;
				case 'P':
					if (sval.ucase() == "HIGH")
						add_device("TTL_INPUT", name, 1);
					else if (sval.ucase() == "LOW")
						add_device("TTL_INPUT", name, 0);
					else
						add_device("ANALOG_INPUT", name, sval.as_double());
					add_pin_alias(name, "1", "Q");
					break;
				case 'D':
					/* Pin 1 = Anode, Pin 2 = Cathode */
					add_device("DIODE", name, sval);
					add_pin_alias(name, "1", "A");
					add_pin_alias(name, "2", "K");
					break;
				case 'U':
				case 'X':
				{
					pstring tname = "TTL_" + sval + "_DIP";
					add_device(tname, name);
					break;
				}
				default:
					tok.error("// IGNORED " + name);
			}

		}
		else if (token.is(tok.m_tok_SIGNAL))
Esempio n. 6
0
void nl_convert_spice_t::process_line(const pstring &line)
{
	if (line != "")
	{
		//printf("// %s\n", line.c_str());
		std::vector<pstring> tt(plib::psplit(line, " ", true));
		double val = 0.0;
		switch (tt[0].at(0))
		{
			case ';':
				out("// {}\n", line.substr(1));
				break;
			case '*':
				out("// {}\n", line.substr(1).c_str());
				break;
			case '.':
				if (tt[0] == ".SUBCKT")
				{
					m_subckt = tt[1] + "_";
					out("NETLIST_START({})\n", tt[1]);
					for (std::size_t i=2; i<tt.size(); i++)
						add_ext_alias(tt[i]);
				}
				else if (tt[0] == ".ENDS")
				{
					dump_nl();
					out("NETLIST_END()\n");
					m_subckt = "";
				}
				else if (tt[0] == ".MODEL")
				{
					out("NET_MODEL(\"{} {}\")\n", m_subckt + tt[1], rem(tt,2));
				}
				else
					out("// {}\n", line.c_str());
				break;
			case 'Q':
			{
				/* check for fourth terminal ... should be numeric net
				 * including "0" or start with "N" (ltspice)
				 */
				pstring model;
				pstring pins ="CBE";
				bool err;
				auto nval = plib::pstonum_ne<long, true>(tt[4], err);
				plib::unused_var(nval);

				if ((!err || plib::startsWith(tt[4], "N")) && tt.size() > 5)
					model = tt[5];
				else
					model = tt[4];
				std::vector<pstring> m(plib::psplit(model,"{"));
				if (m.size() == 2)
				{
					if (m[1].length() != 4)
						plib::perrlogger("error with model desc {}\n", model);
					pins = plib::left(m[1], 3);
				}
				add_device("QBJT_EB", tt[0], m_subckt + m[0]);
				add_term(tt[1], tt[0] + "." + pins.at(0));
				add_term(tt[2], tt[0] + "." + pins.at(1));
				add_term(tt[3], tt[0] + "." + pins.at(2));
			}
				break;
			case 'R':
				if (plib::startsWith(tt[0], "RV"))
				{
					val = get_sp_val(tt[4]);
					add_device("POT", tt[0], val);
					add_term(tt[1], tt[0] + ".1");
					add_term(tt[2], tt[0] + ".2");
					add_term(tt[3], tt[0] + ".3");
				}
				else
				{
					val = get_sp_val(tt[3]);
					add_device("RES", tt[0], val);
					add_term(tt[1], tt[0] + ".1");
					add_term(tt[2], tt[0] + ".2");
				}
				break;
			case 'C':
				val = get_sp_val(tt[3]);
				add_device("CAP", tt[0], val);
				add_term(tt[1], tt[0] + ".1");
				add_term(tt[2], tt[0] + ".2");
				break;
			case 'B':  // arbitrary behavioural current source - needs manual work afterwords
				add_device("CS", tt[0], "/*" + rem(tt, 3) + "*/");
				add_term(tt[1], tt[0] + ".P");
				add_term(tt[2], tt[0] + ".N");
				break;
			case 'E':
				add_device("VCVS", tt[0]);
				add_term(tt[1], tt[0] + ".OP");
				add_term(tt[2], tt[0] + ".ON");
				add_term(tt[3], tt[0] + ".IP");
				add_term(tt[4], tt[0] + ".IN");
				out("PARAM({}, {})\n", tt[0] + ".G", tt[5]);
				break;
			case 'V':
				// just simple Voltage sources ....
				if (tt[2] == "0")
				{
					val = get_sp_val(tt[3]);
					add_device("ANALOG_INPUT", tt[0], val);
					add_term(tt[1], tt[0] + ".Q");
					//add_term(tt[2], tt[0] + ".2");
				}
				else
					plib::perrlogger("Voltage Source {} not connected to GND\n", tt[0]);
				break;
#if 0
			// This is wrong ... Need to use something else for inputs!
			case 'I': // Input pin special notation
				{
					val = get_sp_val(tt[2]);
					add_device("ANALOG_INPUT", tt[0], val);
					add_term(tt[1], tt[0] + ".Q");
				}
				break;
#else
			case 'I':
				{
					val = get_sp_val(tt[3]);
					add_device("CS", tt[0], val);
					add_term(tt[1], tt[0] + ".1");
					add_term(tt[2], tt[0] + ".2");
				}
				break;
#endif
			case 'D':
				add_device("DIODE", tt[0], tt[3]);
				/* FIXME ==> does Kicad use different notation from LTSPICE */
				add_term(tt[1], tt[0] + ".K");
				add_term(tt[2], tt[0] + ".A");
				break;
			case 'U':
			case 'X':
			{
				// FIXME: specific code for KICAD exports
				//        last element is component type
				// FIXME: Parameter

				pstring xname = plib::replace_all(tt[0], pstring("."), pstring("_"));
				pstring tname = "TTL_" + tt[tt.size()-1] + "_DIP";
				add_device(tname, xname);
				for (std::size_t i=1; i < tt.size() - 1; i++)
				{
					pstring term = plib::pfmt("{1}.{2}")(xname)(i);
					add_term(tt[i], term);
				}
				break;
			}
			default:
				out("// IGNORED {}: {}\n", tt[0].c_str(), line.c_str());
		}
	}
}