Exemplo n.º 1
0
ATTR_COLD nl_double netlist_param_model_t::model_value(const pstring &entity, const nl_double defval) const
{
	pstring tmp = this->Value();
	// .model 1N914 D(Is=2.52n Rs=.568 N=1.752 Cjo=4p M=.4 tt=20n Iave=200m Vpk=75 mfg=OnSemi type=silicon)
	int p = tmp.ucase().find(entity.ucase() + "=");
	if (p>=0)
	{
		int pblank = tmp.find(" ", p);
		if (pblank < 0) pblank = tmp.len() + 1;
		tmp = tmp.substr(p, pblank - p);
		int pequal = tmp.find("=", 0);
		if (pequal < 0)
			netlist().error("parameter %s misformat in model %s temp %s\n", entity.cstr(), Value().cstr(), tmp.cstr());
		tmp = tmp.substr(pequal+1);
		nl_double factor = NL_FCONST(1.0);
		switch (*(tmp.right(1).cstr()))
		{
			case 'm': factor = 1e-3; break;
			case 'u': factor = 1e-6; break;
			case 'n': factor = 1e-9; break;
			case 'p': factor = 1e-12; break;
			case 'f': factor = 1e-15; break;
			case 'a': factor = 1e-18; break;

		}
		if (factor != NL_FCONST(1.0))
			tmp = tmp.left(tmp.len() - 1);
		return (nl_double) atof(tmp.cstr()) * factor;
	}
	else
	{
		netlist().log("Entity %s not found in model %s\n", entity.cstr(), tmp.cstr());
		return defval;
	}
}
Exemplo n.º 2
0
ATTR_COLD analog_output_t::analog_output_t()
	: analog_t(OUTPUT), m_proxied_net(nullptr)
{
	this->set_net(m_my_net);
	set_state(STATE_OUT);

	net().m_cur_Analog = NL_FCONST(0.99);
}
Exemplo n.º 3
0
void nld_d_to_a_proxy::reset()
{
	m_Q.initial(0.0);
	m_last_state = -1;
	m_RV.do_reset();
	m_is_timestep = m_RV.m_P.net().as_analog().solver()->is_timestep();
	m_RV.set(NL_FCONST(1.0) / logic_family().m_R_low, logic_family().m_low_V, 0.0);
}
Exemplo n.º 4
0
ATTR_COLD analog_output_t::analog_output_t()
	: netlist_analog_t(OUTPUT), m_proxied_net(NULL)
{
	this->set_net(m_my_net);
	set_state(STATE_OUT);

	net().as_analog().m_cur_Analog = NL_FCONST(0.99);
}
Exemplo n.º 5
0
netlist_time matrix_solver_t::compute_next_timestep(const double cur_ts)
{
	nl_double new_solver_timestep = m_params.m_max_timestep;

	if (m_params.m_dynamic)
	{
		/*
		 * FIXME: We should extend the logic to use either all nets or
		 *        only output nets.
		 */
		for (std::size_t k = 0, iN=m_terms.size(); k < iN; k++)
		{
			analog_net_t *n = m_nets[k];
			terms_t *t = m_terms[k];

			const nl_double DD_n = (n->Q_Analog() - t->m_last_V);
			const nl_double hn = cur_ts;

			nl_double DD2 = (DD_n / hn - t->m_DD_n_m_1 / t->m_h_n_m_1) / (hn + t->m_h_n_m_1);
			nl_double new_net_timestep;

			t->m_h_n_m_1 = hn;
			t->m_DD_n_m_1 = DD_n;
			if (std::fabs(DD2) > NL_FCONST(1e-60)) // avoid div-by-zero
				new_net_timestep = std::sqrt(m_params.m_lte / std::fabs(NL_FCONST(0.5)*DD2));
			else
				new_net_timestep = m_params.m_max_timestep;

			if (new_net_timestep < new_solver_timestep)
				new_solver_timestep = new_net_timestep;

			t->m_last_V = n->Q_Analog();
		}
		if (new_solver_timestep < m_params.m_min_timestep)
			new_solver_timestep = m_params.m_min_timestep;
	}
	//if (new_solver_timestep > 10.0 * hn)
	//    new_solver_timestep = 10.0 * hn;
	/*
	 * FIXME: Factor 2 below is important. Without, we get timing issues. This must be a bug elsewhere.
	 */
	return std::max(netlist_time::from_double(new_solver_timestep), netlist_time::quantum() * 2);
}
Exemplo n.º 6
0
analog_output_t::analog_output_t(core_device_t &dev, const pstring &aname)
	: analog_t(dev, aname, OUTPUT)
	, m_my_net(dev.netlist(), name() + ".net", this)
{
	this->set_net(&m_my_net);
	set_state(STATE_OUT);

	net().m_cur_Analog = NL_FCONST(0.0);
	netlist().setup().register_term(*this);
}
Exemplo n.º 7
0
ATTR_COLD analog_output_t::analog_output_t(core_device_t &dev, const pstring &aname)
	: analog_t(OUTPUT), m_proxied_net(nullptr)
{
	this->set_net(m_my_net);
	set_state(STATE_OUT);

	net().m_cur_Analog = NL_FCONST(0.99);

	analog_t::init_object(dev, aname);
	net().init_object(dev.netlist(), aname + ".net");
	net().register_railterminal(*this);
}
Exemplo n.º 8
0
netlist_time matrix_solver_t::compute_next_timestep()
{
	nl_double new_solver_timestep = m_params.m_max_timestep;

	if (m_params.m_dynamic)
	{
		/*
		 * FIXME: We should extend the logic to use either all nets or
		 *        only output nets.
		 */
		for (unsigned k = 0, iN=m_terms.size(); k < iN; k++)
		{
			analog_net_t *n = m_nets[k];
			terms_t *t = m_terms[k];

			const nl_double DD_n = (n->Q_Analog() - t->m_last_V);
			const nl_double hn = current_timestep();

			nl_double DD2 = (DD_n / hn - t->m_DD_n_m_1 / t->m_h_n_m_1) / (hn + t->m_h_n_m_1);
			nl_double new_net_timestep;

			t->m_h_n_m_1 = hn;
			t->m_DD_n_m_1 = DD_n;
			if (nl_math::abs(DD2) > NL_FCONST(1e-30)) // avoid div-by-zero
				new_net_timestep = nl_math::sqrt(m_params.m_lte / nl_math::abs(NL_FCONST(0.5)*DD2));
			else
				new_net_timestep = m_params.m_max_timestep;

			if (new_net_timestep < new_solver_timestep)
				new_solver_timestep = new_net_timestep;

			t->m_last_V = n->Q_Analog();
		}
		if (new_solver_timestep < m_params.m_min_timestep)
			new_solver_timestep = m_params.m_min_timestep;
	}
	//if (new_solver_timestep > 10.0 * hn)
	//    new_solver_timestep = 10.0 * hn;
	return netlist_time::from_double(new_solver_timestep);
}
Exemplo n.º 9
0
	void nld_d_to_a_proxy::reset()
	{
		// FIXME: Variable voltage
		double supply_V = logic_family().fixed_V();
		if (supply_V == 0.0) supply_V = 5.0;

		//m_Q.initial(0.0);
		m_last_state = -1;
		m_RV.do_reset();
		m_is_timestep = m_RV.m_P.net().solver()->has_timestep_devices();
		m_RV.set(NL_FCONST(1.0) / logic_family().R_low(),
				logic_family().low_V(0.0, supply_V), 0.0);
	}
Exemplo n.º 10
0
ATTR_HOT void nld_d_to_a_proxy::update()
{
	const int state = INPLOGIC(m_I);
	if (state != m_last_state)
	{
		m_last_state = state;
		const nl_double R = state ? logic_family().m_R_high : logic_family().m_R_low;
		const nl_double V = state ? logic_family().m_high_V : logic_family().m_low_V;

		// We only need to update the net first if this is a time stepping net
		if (m_is_timestep)
		{
			m_RV.update_dev();
		}
		m_RV.set(NL_FCONST(1.0) / R, V, 0.0);
		m_RV.m_P.schedule_after(NLTIME_FROM_NS(1));
	}
}
Exemplo n.º 11
0
ATTR_COLD void netlist_analog_output_t::initial(const nl_double val)
{
	// FIXME: Really necessary?
	net().as_analog().m_cur_Analog = val * NL_FCONST(0.99);
}
Exemplo n.º 12
0
ATTR_COLD void NETLIB_NAME(solver)::post_start()
{
	pvector_t<analog_net_t::list_t> groups;
	const bool use_specific = true;

	m_params.m_pivot = m_pivot.Value();
	m_params.m_accuracy = m_accuracy.Value();
	m_params.m_gs_loops = m_gs_loops.Value();
	m_params.m_nr_loops = m_nr_loops.Value();
	m_params.m_nt_sync_delay = netlist_time::from_double(m_sync_delay.Value());
	m_params.m_lte = m_lte.Value();
	m_params.m_sor = m_sor.Value();

	m_params.m_min_timestep = m_min_timestep.Value();
	m_params.m_dynamic = (m_dynamic.Value() == 1 ? true : false);
	m_params.m_max_timestep = netlist_time::from_hz(m_freq.Value()).as_double();

	if (m_params.m_dynamic)
	{
		m_params.m_max_timestep *= NL_FCONST(1000.0);
	}
	else
	{
		m_params.m_min_timestep = m_params.m_max_timestep;
	}

	// Override log statistics
	pstring p = nl_util::environment("NL_STATS");
	if (p != "")
		m_params.m_log_stats = (bool) p.as_long();
	else
		m_params.m_log_stats = (bool) m_log_stats.Value();

	netlist().log().verbose("Scanning net groups ...");
	// determine net groups
	for (auto & net : netlist().m_nets)
	{
		netlist().log().debug("processing {1}\n", net->name());
		if (!net->isRailNet())
		{
			netlist().log().debug("   ==> not a rail net\n");
			analog_net_t *n = &net->as_analog();
			if (!n->already_processed(groups))
			{
				groups.push_back(analog_net_t::list_t());
				n->process_net(groups);
			}
		}
	}

	// setup the solvers
	netlist().log().verbose("Found {1} net groups in {2} nets\n", groups.size(), netlist().m_nets.size());
	for (auto & grp : groups)
	{
		matrix_solver_t *ms;
		std::size_t net_count = grp.size();

		switch (net_count)
		{
			case 1:
				ms = create_solver<1,1>(1, use_specific);
				break;
			case 2:
				ms = create_solver<2,2>(2, use_specific);
				break;
			case 3:
				ms = create_solver<3,3>(3, use_specific);
				break;
			case 4:
				ms = create_solver<4,4>(4, use_specific);
				break;
			case 5:
				ms = create_solver<5,5>(5, use_specific);
				break;
			case 6:
				ms = create_solver<6,6>(6, use_specific);
				break;
			case 7:
				ms = create_solver<7,7>(7, use_specific);
				break;
			case 8:
				ms = create_solver<8,8>(8, use_specific);
				break;
			case 10:
				ms = create_solver<10,10>(10, use_specific);
				break;
			case 11:
				ms = create_solver<11,11>(11, use_specific);
				break;
			case 12:
				ms = create_solver<12,12>(12, use_specific);
				break;
			case 15:
				ms = create_solver<15,15>(15, use_specific);
				break;
			case 31:
				ms = create_solver<31,31>(31, use_specific);
				break;
			case 49:
				ms = create_solver<49,49>(49, use_specific);
				break;
#if 0
			case 87:
				ms = create_solver<87,87>(87, use_specific);
				break;
#endif
			default:
				netlist().log().warning("No specific solver found for netlist of size {1}", (unsigned) net_count);
				if (net_count <= 16)
				{
					ms = create_solver<0,16>(net_count, use_specific);
				}
				else if (net_count <= 32)
				{
					ms = create_solver<0,32>(net_count, use_specific);
				}
				else if (net_count <= 64)
				{
					ms = create_solver<0,64>(net_count, use_specific);
				}
				else
					if (net_count <= 128)
				{
					ms = create_solver<0,128>(net_count, use_specific);
				}
				else
				{
					netlist().log().fatal("Encountered netgroup with > 128 nets");
					ms = nullptr; /* tease compilers */
				}

				break;
		}

		register_sub(*ms);

		ms->setup(grp);

		m_mat_solvers.push_back(ms);

		netlist().log().verbose("Solver {1}", ms->name());
		netlist().log().verbose("       ==> {2} nets", grp.size());
		netlist().log().verbose("       has {1} elements", ms->is_dynamic() ? "dynamic" : "no dynamic");
		netlist().log().verbose("       has {1} elements", ms->is_timestep() ? "timestep" : "no timestep");
		for (net_t *n : grp)
		{
			netlist().log().verbose("Net {1}", n->name());
			for (const core_terminal_t *pcore : n->m_core_terms)
			{
				netlist().log().verbose("   {1}", pcore->name());
			}
		}
	}
}
Exemplo n.º 13
0
ATTR_COLD void NETLIB_NAME(solver)::post_start()
{
	analog_net_t::list_t groups[256];
	int cur_group = -1;
	const bool use_specific = true;

	m_params.m_accuracy = m_accuracy.Value();
	m_params.m_gs_loops = m_gs_loops.Value();
	m_params.m_nr_loops = m_nr_loops.Value();
	m_params.m_nt_sync_delay = m_sync_delay.Value();
	m_params.m_lte = m_lte.Value();
	m_params.m_sor = m_sor.Value();

	m_params.m_min_timestep = m_min_timestep.Value();
	m_params.m_dynamic = (m_dynamic.Value() == 1 ? true : false);
	m_params.m_max_timestep = netlist_time::from_hz(m_freq.Value()).as_double();

	if (m_params.m_dynamic)
	{
		m_params.m_max_timestep *= NL_FCONST(1000.0);
	}
	else
	{
		m_params.m_min_timestep = m_params.m_max_timestep;
	}

	// Override log statistics
	pstring p = nl_util::environment("NL_STATS");
	if (p != "")
		m_params.m_log_stats = (bool) p.as_long();
	else
		m_params.m_log_stats = (bool) m_log_stats.Value();

	netlist().log("Scanning net groups ...");
	// determine net groups
	for (std::size_t i=0; i<netlist().m_nets.size(); i++)
	{
		SOLVER_VERBOSE_OUT(("processing %s\n", netlist().m_nets[i]->name().cstr()));
		if (!netlist().m_nets[i]->isRailNet())
		{
			SOLVER_VERBOSE_OUT(("   ==> not a rail net\n"));
			analog_net_t *n = &netlist().m_nets[i]->as_analog();
			if (!n->already_processed(groups, cur_group))
			{
				cur_group++;
				n->process_net(groups, cur_group);
			}
		}
	}

	// setup the solvers
	netlist().log("Found %d net groups in %" SIZETFMT " nets\n", cur_group + 1, SIZET_PRINTF(netlist().m_nets.size()));
	for (int i = 0; i <= cur_group; i++)
	{
		matrix_solver_t *ms;
		std::size_t net_count = groups[i].size();

		switch (net_count)
		{
			case 1:
				ms = create_solver<1,1>(1, use_specific);
				break;
			case 2:
				ms = create_solver<2,2>(2, use_specific);
				break;
			case 3:
				ms = create_solver<3,3>(3, use_specific);
				break;
			case 4:
				ms = create_solver<4,4>(4, use_specific);
				break;
			case 5:
				ms = create_solver<5,5>(5, use_specific);
				break;
			case 6:
				ms = create_solver<6,6>(6, use_specific);
				break;
			case 7:
				ms = create_solver<7,7>(7, use_specific);
				break;
			case 8:
				ms = create_solver<8,8>(8, use_specific);
				break;
			case 12:
				ms = create_solver<12,12>(12, use_specific);
				break;
			case 87:
				ms = create_solver<87,87>(87, use_specific);
				break;
			default:
				if (net_count <= 16)
				{
					ms = create_solver<0,16>(net_count, use_specific);
				}
				else if (net_count <= 32)
				{
					ms = create_solver<0,32>(net_count, use_specific);
				}
				else if (net_count <= 64)
				{
					ms = create_solver<0,64>(net_count, use_specific);
				}
				else
					if (net_count <= 128)
				{
					ms = create_solver<0,128>(net_count, use_specific);
				}
				else
				{
					netlist().error("Encountered netgroup with > 128 nets");
					ms = NULL; /* tease compilers */
				}

				break;
		}

		register_sub(pstring::sprintf("Solver_%" SIZETFMT,SIZET_PRINTF(m_mat_solvers.size())), *ms);

		ms->vsetup(groups[i]);

		m_mat_solvers.add(ms);

		netlist().log("Solver %s", ms->name().cstr());
		netlist().log("       # %d ==> %" SIZETFMT " nets", i, SIZET_PRINTF(groups[i].size())); //, (*(*groups[i].first())->m_core_terms.first())->name().cstr());
		netlist().log("       has %s elements", ms->is_dynamic() ? "dynamic" : "no dynamic");
		netlist().log("       has %s elements", ms->is_timestep() ? "timestep" : "no timestep");
		for (std::size_t j=0; j<groups[i].size(); j++)
		{
			netlist().log("Net %" SIZETFMT ": %s", SIZET_PRINTF(j), groups[i][j]->name().cstr());
			net_t *n = groups[i][j];
			for (std::size_t k = 0; k < n->m_core_terms.size(); k++)
			{
				const core_terminal_t *p = n->m_core_terms[k];
				netlist().log("   %s", p->name().cstr());
			}
		}
	}
}