Esempio n. 1
0
ATTR_COLD void netlist_net_t::merge_net(netlist_net_t *othernet)
{
	NL_VERBOSE_OUT(("merging nets ...\n"));
	if (othernet == NULL)
		return; // Nothing to do

	if (this->isRailNet() && othernet->isRailNet())
		netlist().error("Trying to merge to rail nets\n");

	if (othernet->isRailNet())
	{
		NL_VERBOSE_OUT(("othernet is railnet\n"));
		othernet->merge_net(this);
	}
	else
	{
		netlist_core_terminal_t *p = othernet->m_head;
		while (p != NULL)
		{
			netlist_core_terminal_t *pn = p->m_update_list_next;
			register_con(*p);
			p = pn;
		}

		othernet->m_head = NULL; // FIXME: othernet needs to be free'd from memory
	}
}
Esempio n. 2
0
void netlist_parser::netdev_device(const pstring &dev_type, const pstring &default_param, bool isString)
{
	netlist_device_t *dev;

	skipws();
	pstring devname = getname2(',', ')');
	pstring defparam = devname + "." + default_param;
	dev = m_setup.factory().new_device_by_name(dev_type, m_setup);
	m_setup.register_dev(dev, devname);
	NL_VERBOSE_OUT(("Parser: IC: %s\n", devname.cstr()));
	if (getc() != ')')
	{
		// have a default param
		skipws();
		if (isString)
		{
			pstring val = getname(')');
			ungetc();
			NL_VERBOSE_OUT(("Parser: Default param: %s %s\n", defparam.cstr(), val.cstr()));
			m_setup.register_param(defparam, val);
		}
		else
		{
			double val = eval_param();
			NL_VERBOSE_OUT(("Parser: Default param: %s %f\n", defparam.cstr(), val));
			m_setup.register_param(defparam, val);
		}
	}
	check_char(')');
}
Esempio n. 3
0
ATTR_COLD void netlist_base_t::start()
{
	/* find the main clock and solver ... */

	NL_VERBOSE_OUT(("Searching for mainclock and solver ...\n"));

	m_mainclock = get_single_device<NETLIB_NAME(mainclock)>("mainclock");
	m_solver = get_single_device<NETLIB_NAME(solver)>("solver");
	m_gnd = get_single_device<NETLIB_NAME(gnd)>("gnd");
	m_params = get_single_device<NETLIB_NAME(netlistparams)>("parameter");

	/* make sure the solver and parameters are started first! */

	if (m_solver != NULL)
		m_solver->start_dev();

	if (m_params != NULL)
	{
		m_params->start_dev();
	}

	m_use_deactivate = (m_params->m_use_deactivate.Value() ? true : false);

	NL_VERBOSE_OUT(("Initializing devices ...\n"));
	for (netlist_device_t * const * entry = m_devices.first(); entry != NULL; entry = m_devices.next(entry))
	{
		netlist_device_t *dev = *entry;
		if (dev != m_solver && dev != m_params)
			dev->start_dev();
	}

}
Esempio n. 4
0
ATTR_COLD void netlist_net_t::merge_net(netlist_net_t *othernet)
{
	NL_VERBOSE_OUT(("merging nets ...\n"));
	if (othernet == NULL)
		return; // Nothing to do

	if (othernet == this)
	{
		netlist().warning("Connecting %s to itself. This may be right, though\n", this->name().cstr());
		return; // Nothing to do
	}

	if (this->isRailNet() && othernet->isRailNet())
		netlist().error("Trying to merge two rail nets: %s and %s\n", this->name().cstr(), othernet->name().cstr());

	if (othernet->isRailNet())
	{
		NL_VERBOSE_OUT(("othernet is railnet\n"));
		othernet->merge_net(this);
	}
	else
	{
		othernet->move_connections(this);
	}
}
Esempio n. 5
0
void netlist_parser::netdev_device(const pstring &dev_type)
{
	pstring devname;
	netlist_device_t *dev;
	int cnt;

	skipws();
	devname = getname2(',', ')');
	dev = m_setup.factory().new_device_by_name(dev_type, m_setup);
	m_setup.register_dev(dev, devname);
	NL_VERBOSE_OUT(("Parser: IC: %s\n", devname.cstr()));
	cnt = 0;
	while (getc() != ')')
	{
		skipws();
		pstring output_name = getname2(',', ')');
		pstring alias = pstring::sprintf("%s.[%d]", devname.cstr(), cnt);
		NL_VERBOSE_OUT(("Parser: ID: %s %s\n", output_name.cstr(), alias.cstr()));
		m_setup.register_link(alias, output_name);
		skipws();
		cnt++;
	}
/*
    if (cnt != dev->m_terminals.count() && !dev->variable_input_count())
        fatalerror("netlist: input count mismatch for %s - expected %d found %d\n", devname.cstr(), dev->m_terminals.count(), cnt);
    if (dev->variable_input_count())
    {
        NL_VERBOSE_OUT(("variable inputs %s: %d\n", dev->name().cstr(), cnt));
    }
    */
}
Esempio n. 6
0
void netlist_queue_t::on_post_load()
{
	this->clear();
	NL_VERBOSE_OUT(("current time %f qsize %d\n", m_netlist->time().as_double(), qsize));
	for (int i = 0; i < m_qsize; i++ )
	{
		netlist_net_t *n = m_netlist.find_net(&(m_name[i][0]));
		NL_VERBOSE_OUT(("Got %s ==> %p\n", qtemp[i].m_name, n));
		NL_VERBOSE_OUT(("schedule time %f (%f)\n", n->time().as_double(), qtemp[i].m_time.as_double()));
		this->push(netlist_queue_t::entry_t(netlist_time::from_raw(m_times[i]), n));
	}
}
Esempio n. 7
0
void netlist_parser::device(const pstring &dev_type)
{
	pstring devname;
	net_device_t_base_factory *f = m_setup.factory().factory_by_name(dev_type, m_setup);
	netlist_device_t *dev;
	nl_util::pstring_list termlist = f->term_param_list();
	nl_util::pstring_list def_params = f->def_params();

	std::size_t cnt;

	devname = get_identifier();

	dev = f->Create();
	m_setup.register_dev(dev, devname);

	NL_VERBOSE_OUT(("Parser: IC: %s\n", devname.cstr()));

	cnt = 0;
	while (cnt < def_params.size())
	{
		pstring paramfq = devname + "." + def_params[cnt];

		NL_VERBOSE_OUT(("Defparam: %s\n", paramfq.cstr()));
		require_token(m_tok_comma);
		token_t tok = get_token();
		if (tok.is_type(STRING))
		{
			m_setup.register_param(paramfq, tok.str());
		}
		else
		{
			nl_double val = eval_param(tok);
			m_setup.register_param(paramfq, val);
		}
		cnt++;
	}

	token_t tok = get_token();
	cnt = 0;
	while (tok.is(m_tok_comma) && cnt < termlist.size())
	{
		pstring output_name = get_identifier();

		m_setup.register_link(devname + "." + termlist[cnt], output_name);

		cnt++;
		tok = get_token();
	}
	if (cnt != termlist.size())
		m_setup.netlist().error("netlist: input count mismatch for %s - expected %" SIZETFMT " found %" SIZETFMT "\n", devname.cstr(), termlist.size(), cnt);
	require_token(tok, m_tok_param_right);
}
Esempio n. 8
0
void netlist_parser::netdev_device(const pstring &dev_type)
{
	pstring devname;
	net_device_t_base_factory *f = m_setup.factory().factory_by_name(dev_type, m_setup);
	netlist_device_t *dev;
	nl_util::pstring_list termlist = f->term_param_list();
	pstring def_param = f->def_param();

	int cnt;

	skipws();
	devname = getname2(',', ')');
	dev = f->Create();
	m_setup.register_dev(dev, devname);

	NL_VERBOSE_OUT(("Parser: IC: %s\n", devname.cstr()));

	if (def_param != "")
	{
        pstring paramfq = devname + "." + def_param;
	    NL_VERBOSE_OUT(("Defparam: %s\n", def_param.cstr()));
        check_char(',');
	    skipws();
	    if (peekc() == '"')
	    {
            pstring val = getstring();
            m_setup.register_param(paramfq, val);
	    }
	    else
	    {
	        double val = eval_param();
	        m_setup.register_param(paramfq, val);
	    }
	    if (termlist.count() > 0)
	        check_char(',');
	}

	cnt = 0;
	while (getc() != ')' && cnt < termlist.count())
	{
		skipws();
		pstring output_name = getname2(',', ')');

		m_setup.register_link(devname + "." + termlist[cnt], output_name);

		skipws();
		cnt++;
	}
    if (cnt != termlist.count())
        fatalerror("netlist: input count mismatch for %s - expected %d found %d\n", devname.cstr(), termlist.count(), cnt);
}
Esempio n. 9
0
void netlist_queue_t::on_pre_save()
{
	NL_VERBOSE_OUT(("on_pre_save\n"));
	m_qsize = this->count();
	NL_VERBOSE_OUT(("current time %f qsize %d\n", netlist().time().as_double(), m_qsize));
	for (int i = 0; i < m_qsize; i++ )
	{
		m_times[i] =  this->listptr()[i].exec_time().as_raw();
		const char *p = this->listptr()[i].object()->name().cstr();
		int n = MIN(63, strlen(p));
		strncpy(&(m_name[i][0]), p, n);
		m_name[i][n] = 0;
	}
}
Esempio n. 10
0
void netlist_queue_t::register_state(pstate_manager_t &manager, const pstring &module)
{
	NL_VERBOSE_OUT(("register_state\n"));
	manager.save_item(m_qsize, this, module + "." + "qsize");
	manager.save_item(m_times, this, module + "." + "times");
	manager.save_item(&(m_name[0][0]), this, module + "." + "names", sizeof(m_name));
}
Esempio n. 11
0
void netlist_parser::parse(const char *buf)
{
	m_px = buf;

	while (!eof())
	{
		pstring n;
		skipws();
		if (eof()) break;
		n = getname('(');
		NL_VERBOSE_OUT(("Parser: Device: %s\n", n.cstr()));
		if (n == "NET_ALIAS")
			net_alias();
		else if (n == "NET_C")
			net_c();
		else if (n == "NETDEV_PARAM")
			netdev_param();
		else if (n == "NETDEV_R")
			netdev_device(n, "R");
		else if (n == "NETDEV_C")
			netdev_device(n, "C");
		else if (n == "NETDEV_POT")
			netdev_device(n, "R");
		else if (n == "NETDEV_D")
			netdev_device(n, "model", true);
		else if ((n == "NETDEV_TTL_CONST") || (n == "NETDEV_ANALOG_CONST"))
			netdev_const(n);
		else
			netdev_device(n);
	}
}
Esempio n. 12
0
void netlist_parser::parse_netlist(ATTR_UNUSED const pstring &nlname)
{
	while (true)
	{
		token_t token = get_token();

		if (token.is_type(ENDOFFILE))
			return;

		require_token(m_tok_param_left);
		NL_VERBOSE_OUT(("Parser: Device: %s\n", token.str().cstr()));

		if (token.is(m_tok_ALIAS))
			net_alias();
		else if (token.is(m_tok_NET_C))
			net_c();
		else if (token.is(m_tok_PARAM))
			netdev_param();
		else if (token.is(m_tok_NET_MODEL))
			net_model();
		else if (token.is(m_tok_SUBMODEL))
			net_submodel();
		else if (token.is(m_tok_INCLUDE))
			net_include();
		else if (token.is(m_tok_NETLIST_END))
		{
			netdev_netlist_end();
			return;
		}
		else
			device(token.str());
	}
}
Esempio n. 13
0
void netlist_parser::parse(const char *buf)
{
	m_px = buf;
	m_line_ptr = buf;
	m_line = 1;

	while (!eof())
	{
		pstring n;
		skipws();
		if (eof()) break;
		n = getname('(');
		NL_VERBOSE_OUT(("Parser: Device: %s\n", n.cstr()));
		if (n == "NET_ALIAS")
			net_alias();
		else if (n == "NET_C")
			net_c();
		else if (n == "NETDEV_PARAM")
			netdev_param();
		else if ((n == "NET_MODEL"))
		    net_model();
		else if (n == "NETLIST_START")
		    netdev_netlist_start();
        else if (n == "NETLIST_END")
            netdev_netlist_end();
		else
			netdev_device(n);
	}
}
Esempio n. 14
0
void parser_t::netdev_param()
{
	pstring param;
	param = get_identifier();
	require_token(m_tok_comma);
	token_t tok = get_token();
	if (tok.is_type(STRING))
	{
		NL_VERBOSE_OUT(("Parser: Param: %s %s\n", param.cstr(), tok.str().cstr()));
		m_setup.register_param(param, tok.str());
	}
	else
	{
		nl_double val = eval_param(tok);
	NL_VERBOSE_OUT(("Parser: Param: %s %f\n", param.cstr(), val));
	m_setup.register_param(param, val);
	}
	require_token(m_tok_param_right);
}
Esempio n. 15
0
void netlist_parser::net_c()
{
	pstring t1;
	pstring t2;
	skipws();
	t1 = getname(',');
	skipws();
	t2 = getname(')');
	NL_VERBOSE_OUT(("Parser: Connect: %s %s\n", t1.cstr(), t2.cstr()));
	m_setup.register_link(t1 , t2);
}
Esempio n. 16
0
 void log_setup()
 {
     NL_VERBOSE_OUT(("Creating dynamic logs ...\n"));
     pstring_list_t ll(m_logs, ":");
     for (int i=0; i < ll.size(); i++)
     {
         pstring name = "log_" + ll[i];
         /*netlist_device_t *nc = */ m_setup->register_dev("nld_log", name);
         m_setup->register_link(name + ".I", ll[i]);
     }
 }
Esempio n. 17
0
void netlist_parser::netdev_param()
{
	pstring param;
	nl_double val;
	param = get_identifier();
	require_token(m_tok_comma);
	val = eval_param(get_token());
	NL_VERBOSE_OUT(("Parser: Param: %s %f\n", param.cstr(), val));
	m_setup.register_param(param, val);
	require_token(m_tok_param_right);
}
Esempio n. 18
0
void netlist_parser::net_alias()
{
	pstring alias;
	pstring out;
	skipws();
	alias = getname(',');
	skipws();
	out = getname(')');
	NL_VERBOSE_OUT(("Parser: Alias: %s %s\n", alias.cstr(), out.cstr()));
	m_setup.register_alias(alias, out);
}
Esempio n. 19
0
void netlist_parser::netdev_param()
{
	pstring param;
	double val;
	skipws();
	param = getname(',');
	skipws();
	val = eval_param();
	NL_VERBOSE_OUT(("Parser: Param: %s %f\n", param.cstr(), val));
	m_setup.register_param(param, val);
	check_char(')');
}
Esempio n. 20
0
ATTR_COLD void netlist_base_t::stop()
{
	/* find the main clock and solver ... */

	NL_VERBOSE_OUT(("Stopping all devices ...\n"));

	// Step all devices once !
	for (int i = 0; i < m_devices.count(); i++)
	{
		m_devices[i]->stop_dev();
	}
}
Esempio n. 21
0
	void log_setup()
	{
		NL_VERBOSE_OUT(("Creating dynamic logs ...\n"));
		nl_util::pstring_list ll = nl_util::split(m_logs, ":");
		for (int i=0; i < ll.count(); i++)
		{
			netlist_device_t *nc = m_setup->factory().new_device_by_classname("nld_log", *m_setup);
			pstring name = "log_" + ll[i];
			m_setup->register_dev(nc, name);
			m_setup->register_link(name + ".I", ll[i]);
		}
	}
Esempio n. 22
0
void parser_t::net_alias()
{
	pstring alias = get_identifier_or_number();

	require_token(m_tok_comma);

	pstring out = get_identifier();

	require_token(m_tok_param_right);

	NL_VERBOSE_OUT(("Parser: Alias: %s %s\n", alias.cstr(), out.cstr()));
	m_setup.register_alias(alias, out);
}
Esempio n. 23
0
ATTR_COLD void netlist_base_t::start()
{
    /* find the main clock and solver ... */

    m_mainclock = get_single_device<NETLIB_NAME(mainclock)>("mainclock");
    m_solver = get_single_device<NETLIB_NAME(solver)>("solver");
    m_gnd = get_single_device<NETLIB_NAME(gnd)>("gnd");

    NL_VERBOSE_OUT(("Initializing devices ...\n"));
    for (tagmap_devices_t::entry_t *entry = m_devices.first(); entry != NULL; entry = m_devices.next(entry))
    {
        netlist_device_t *dev = entry->object();
        dev->start_dev();
    }

}
Esempio n. 24
0
void parser_t::parse_netlist(ATTR_UNUSED const pstring &nlname)
{
	while (true)
	{
		token_t token = get_token();

		if (token.is_type(ENDOFFILE))
			return;

		require_token(m_tok_param_left);
		NL_VERBOSE_OUT(("Parser: Device: %s\n", token.str().cstr()));

		if (token.is(m_tok_ALIAS))
			net_alias();
		else if (token.is(m_tok_DIPPINS))
			dippins();
		else if (token.is(m_tok_NET_C))
			net_c();
		else if (token.is(m_tok_FRONTIER))
			frontier();
		else if (token.is(m_tok_PARAM))
			netdev_param();
		else if (token.is(m_tok_NET_MODEL))
			net_model();
		else if (token.is(m_tok_SUBMODEL))
			net_submodel();
		else if (token.is(m_tok_INCLUDE))
			net_include();
		else if (token.is(m_tok_LOCAL_SOURCE))
			net_local_source();
		else if (token.is(m_tok_TRUTHTABLE_START))
			net_truthtable_start();
		else if (token.is(m_tok_LOCAL_LIB_ENTRY))
		{
			m_setup.register_lib_entry(get_identifier());
			require_token(m_tok_param_right);
		}
		else if (token.is(m_tok_NETLIST_END))
		{
			netdev_netlist_end();
			return;
		}
		else
			device(token.str());
	}
}
Esempio n. 25
0
ATTR_COLD void pstate_manager_t::save_state_ptr(const pstring &stname, const pstate_data_type_e dt, const void *owner, const int size, const int count, void *ptr)
{
	pstring fullname = stname;
	ATTR_UNUSED  pstring ts[] = {
			"NOT_SUPPORTED",
			"DT_CUSTOM",
			"DT_DOUBLE",
			"DT_INT64",
			"DT_INT16",
			"DT_INT8",
			"DT_INT",
			"DT_BOOLEAN"
	};

	NL_VERBOSE_OUT(("SAVE: <%s> %s(%d) %p\n", fullname.cstr(), ts[dt].cstr(), size, ptr));
	pstate_entry_t *p = new pstate_entry_t(stname, dt, owner, size, count, ptr);
	m_save.add(p);
}
Esempio n. 26
0
void parser_t::net_c()
{
	pstring first = get_identifier();
	require_token(m_tok_comma);

	while (true)
	{
		pstring t1 = get_identifier();
		m_setup.register_link(first , t1);
		NL_VERBOSE_OUT(("Parser: Connect: %s %s\n", first.cstr(), t1.cstr()));
		token_t n = get_token();
		if (n.is(m_tok_param_right))
			break;
		if (!n.is(m_tok_comma))
			error("expected a comma, found <%s>", n.str().cstr());
	}

}
Esempio n. 27
0
void netlist_parser::netdev_const(const pstring &dev_name)
{
	pstring name;
	netlist_device_t *dev;
	pstring paramfq;
	double val;

	skipws();
	name = getname(',');
	dev = m_setup.factory().new_device_by_name(dev_name, m_setup);
	m_setup.register_dev(dev, name);
	skipws();
	val = eval_param();
	paramfq = name + ".CONST";
	NL_VERBOSE_OUT(("Parser: Const: %s %f\n", name.cstr(), val));
	check_char(')');
	m_setup.register_param(paramfq, val);
}
Esempio n. 28
0
ATTR_COLD void matrix_solver_t::setup(analog_net_t::list_t &nets)
{
	NL_VERBOSE_OUT(("New solver setup\n"));

	m_nets.clear();

	for (std::size_t k = 0; k < nets.size(); k++)
	{
		m_nets.add(nets[k]);
	}

	for (std::size_t k = 0; k < nets.size(); k++)
	{
		NL_VERBOSE_OUT(("setting up net\n"));

		analog_net_t *net = nets[k];

		net->m_solver = this;

		for (std::size_t i = 0; i < net->m_core_terms.size(); i++)
		{
			core_terminal_t *p = net->m_core_terms[i];
			NL_VERBOSE_OUT(("%s %s %d\n", p->name().cstr(), net->name().cstr(), (int) net->isRailNet()));
			switch (p->type())
			{
				case terminal_t::TERMINAL:
					switch (p->device().family())
					{
						case device_t::CAPACITOR:
							if (!m_step_devices.contains(&p->device()))
								m_step_devices.add(&p->device());
							break;
						case device_t::BJT_EB:
						case device_t::DIODE:
						case device_t::LVCCS:
						case device_t::BJT_SWITCH:
							NL_VERBOSE_OUT(("found BJT/Diode/LVCCS\n"));
							if (!m_dynamic_devices.contains(&p->device()))
								m_dynamic_devices.add(&p->device());
							break;
						default:
							break;
					}
					{
						terminal_t *pterm = dynamic_cast<terminal_t *>(p);
						add_term(k, pterm);
					}
					NL_VERBOSE_OUT(("Added terminal\n"));
					break;
				case terminal_t::INPUT:
					{
						analog_output_t *net_proxy_output = NULL;
						for (std::size_t i = 0; i < m_inps.size(); i++)
							if (m_inps[i]->m_proxied_net == &p->net().as_analog())
							{
								net_proxy_output = m_inps[i];
								break;
							}

						if (net_proxy_output == NULL)
						{
							net_proxy_output = palloc(analog_output_t);
							net_proxy_output->init_object(*this, this->name() + "." + pstring::sprintf("m%" SIZETFMT, SIZET_PRINTF(m_inps.size())));
							m_inps.add(net_proxy_output);
							net_proxy_output->m_proxied_net = &p->net().as_analog();
						}
						net_proxy_output->net().register_con(*p);
						// FIXME: repeated
						net_proxy_output->net().rebuild_list();
						NL_VERBOSE_OUT(("Added input\n"));
					}
					break;
				default:
					netlist().error("unhandled element found\n");
					break;
			}
		}
		NL_VERBOSE_OUT(("added net with %" SIZETFMT " populated connections\n", net->m_core_terms.size()));
	}

}