Example #1
0
void queue_t::on_pre_save()
{
	netlist().log().debug("on_pre_save\n");
	m_qsize = this->count();
	netlist().log().debug("current time {1} qsize {2}\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();
		pstring p = this->listptr()[i].object()->name();
		int n = p.len();
		n = std::min(63, n);
		std::strncpy(m_names[i].m_buf, p.cstr(), n);
		m_names[i].m_buf[n] = 0;
	}
}
Example #2
0
void detail::queue_t::on_pre_save()
{
	netlist().log().debug("on_pre_save\n");
	m_qsize = this->size();
	netlist().log().debug("current time {1} qsize {2}\n", netlist().time().as_double(), m_qsize);
	for (std::size_t i = 0; i < m_qsize; i++ )
	{
		m_times[i] =  this->listptr()[i].m_exec_time.as_raw();
		pstring p = this->listptr()[i].m_object->name();
		std::size_t n = p.len();
		if (n > 63) n = 63;
		std::strncpy(m_names[i].m_buf, p.cstr(), n);
		m_names[i].m_buf[n] = 0;
	}
}
Example #3
0
void mymain(int argc, _TCHAR *argv[])
{
    string infile;

    if(argc != 2)
    {
        cout << "Usage: placement input_file" << endl;
        cout << "Using default input file: input.ap" << endl;
        infile = "input.ap";
    }
	else
	{
		infile = argv[1];
	}

	output.open((infile+".out").c_str(), ios_base::out);

    NetList netlist(infile.c_str());
    netlist.print();

	AnalyticForm aform(netlist);
	aform.print();

	UmfpackHelper umfpack(aform.m, aform.n, aform.A, aform.bx, aform.by);
	umfpack.print();
}
Example #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 (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
	}
}
Example #5
0
ATTR_COLD void netlist_device_t::register_sub(const pstring &name, netlist_device_t &dev)
{
	dev.init(netlist(), this->name() + "." + name);
	// FIXME: subdevices always first inherit the logic family of the parent
	dev.set_logic_family(this->logic_family());
	dev.start_dev();
}
Example #6
0
ATTR_COLD double netlist_param_model_t::model_value(const pstring &entity, const 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);
		double factor = 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 != 1.0)
			tmp = tmp.left(tmp.len() - 1);
		return atof(tmp.cstr()) * factor;
	}
	else
		return defval;
}
Example #7
0
ATTR_HOT void netlist_net_t::dec_active(netlist_core_terminal_t &term)
{
	m_active--;
	m_list_active.remove(term);
	if (m_active == 0 && netlist().use_deactivate())
			railterminal().netdev().dec_active();
}
Example #8
0
void matrix_solver_t::solve_base(C *p)
{
	m_stat_vsolver_calls++;
	if (is_dynamic())
	{
		int this_resched;
		int newton_loops = 0;
		do
		{
			update_dynamic();
			// Gauss-Seidel will revert to Gaussian elemination if steps exceeded.
			this_resched = p->vsolve_non_dynamic(true);
			newton_loops++;
		} while (this_resched > 1 && newton_loops < m_params.m_nr_loops);

		m_stat_newton_raphson += newton_loops;
		// reschedule ....
		if (this_resched > 1 && !m_Q_sync.net().is_queued())
		{
			netlist().warning("NEWTON_LOOPS exceeded on net %s... reschedule", this->name().cstr());
			m_Q_sync.net().reschedule_in_queue(m_params.m_nt_sync_delay);
		}
	}
	else
	{
		p->vsolve_non_dynamic(false);
	}
}
Example #9
0
void queue_t::register_state(pstate_manager_t &manager, const pstring &module)
{
	netlist().log().debug("register_state\n");
	manager.save_item(m_qsize, this, module + "." + "qsize");
	manager.save_item(&m_times[0], this, module + "." + "times", m_times.size());
	manager.save_item(&(m_names[0].m_buf[0]), this, module + "." + "names", m_names.size() * sizeof(names_t));
}
Example #10
0
logic_input_t::logic_input_t(core_device_t &dev, const pstring &aname)
		: logic_t(dev, aname, INPUT)
{
	set_state(STATE_INP_ACTIVE);
	set_logic_family(dev.logic_family());
	netlist().setup().register_term(*this);
}
Example #11
0
ATTR_COLD void netlist_core_device_t::start_dev()
{
#if (NL_KEEP_STATISTICS)
	netlist().m_started_devices.add(this, false);
#endif
	start();
}
Example #12
0
ATTR_HOT void net_t::dec_active(core_terminal_t &term)
{
	m_active--;
	nl_assert(m_active >= 0);
	m_list_active.remove(term);
	if (m_active == 0 && netlist().use_deactivate())
			railterminal().device().dec_active();
}
Example #13
0
terminal_t::terminal_t(core_device_t &dev, const pstring &aname)
: analog_t(dev, aname, TERMINAL)
, m_otherterm(nullptr)
, m_Idr1(*this, "m_Idr1", nullptr)
, m_go1(*this, "m_go1", nullptr)
, m_gt1(*this, "m_gt1", nullptr)
{
	netlist().setup().register_term(*this);
}
Example #14
0
param_template_t<C, T>::param_template_t(device_t &device, const pstring name, const C val)
: param_t(T, device, device.name() + "." + name)
, m_param(val)
{
	/* pstrings not yet supported, these need special logic */
	if (T != param_t::STRING && T != param_t::MODEL)
		netlist().save(*this, m_param, "m_param");
	device.setup().register_and_set_param(device.name() + "." + name, *this);
}
Example #15
0
logic_output_t::logic_output_t(core_device_t &dev, const pstring &aname)
	: logic_t(dev, aname, OUTPUT)
	, m_my_net(dev.netlist(), name() + ".net", this)
{
	set_state(STATE_OUT);
	this->set_net(&m_my_net);
	set_logic_family(dev.logic_family());
	netlist().setup().register_term(*this);
}
Example #16
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);
}
Example #17
0
	nld_d_to_a_proxy::nld_d_to_a_proxy(netlist_t &anetlist, const pstring &name, logic_output_t *out_proxied)
	: nld_base_d_to_a_proxy(anetlist, name, out_proxied, m_RV.m_P)
	, m_GNDHack(*this, "_Q")
	, m_RV(*this, "RV")
	, m_last_state(*this, "m_last_var", -1)
	, m_is_timestep(false)
	{
		const pstring power_syms[3][2] ={ {"VCC", "VEE"}, {"VCC", "GND"}, {"VDD", "VSS"}};
		//register_sub(m_RV);
		//register_term("1", m_RV.m_P);
		//register_term("2", m_RV.m_N);

		register_subalias("Q", m_RV.m_P);

		connect(m_RV.m_N, m_GNDHack);
		bool f = false;
		for (int i = 0; i < 3; i++)
		{
			pstring devname = out_proxied->device().name();
			auto tp = netlist().setup().find_terminal(devname + "." + power_syms[i][0],
					detail::terminal_type::INPUT, false);
			auto tn = netlist().setup().find_terminal(devname + "." + power_syms[i][1],
					detail::terminal_type::INPUT, false);
			if (tp != nullptr && tn != nullptr)
			{
				/* alternative logic */
				f = true;
			}
		}
		if (!f)
			log().warning(MW_1_NO_POWER_TERMINALS_ON_DEVICE_1, out_proxied->device().name());
		else
			log().verbose("D/A Proxy: Found power terminals on device {1}", out_proxied->device().name());
#if (0)
		printf("%s %s\n", out_proxied->name().c_str(), out_proxied->device().name().c_str());
		auto x = netlist().setup().find_terminal(out_proxied->name(), detail::device_object_t::terminal_type::OUTPUT, false);
		if (x) printf("==> %s\n", x->name().c_str());
#endif
	}
Example #18
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;
	}
}
Example #19
0
void detail::net_t::inc_active(core_terminal_t &term)
{
	m_active++;
	m_list_active.push_front(&term);
	nl_assert(m_active <= static_cast<int>(num_cons()));
	if (m_active == 1)
	{
		railterminal().device().do_inc_active();
		if (m_in_queue == 0)
		{
			if (m_time > netlist().time())
			{
				m_in_queue = 1;     /* pending */
				netlist().push_to_queue(*this, m_time);
			}
			else
			{
				m_cur_Q = m_new_Q;
				m_in_queue = 2;
			}
		}
	}
}
Example #20
0
const netlist_time matrix_solver_t::solve()
{
	const netlist_time now = netlist().time();
	const netlist_time delta = now - m_last_step;

	// We are already up to date. Avoid oscillations.
	// FIXME: Make this a parameter!
	if (delta < netlist_time::quantum())
		return netlist_time::zero();

	/* update all terminals for new time step */
	m_last_step = now;
	step(delta);
	solve_base();
	const netlist_time next_time_step = compute_next_timestep(delta.as_double());

	update_inputs();

	return next_time_step;
}
Example #21
0
netlist_time matrix_solver_t::solve()
{
	const netlist_time now = netlist().time();
	const netlist_time delta = now - m_last_step;

	// We are already up to date. Avoid oscillations.
	// FIXME: Make this a parameter!
	if (delta < netlist_time::from_nsec(1)) // 20000
		return netlist_time::from_nsec(0);

	/* update all terminals for new time step */
	m_last_step = now;
	m_cur_ts = delta.as_double();

	step(delta);

	const netlist_time next_time_step = solve_base();

	update_inputs();
	return next_time_step;
}
Example #22
0
matrix_solver_t * NETLIB_NAME(solver)::create_solver(int size, const bool use_specific)
{
	if (use_specific && m_N == 1)
		return palloc(matrix_solver_direct1_t(&m_params));
	else if (use_specific && m_N == 2)
		return palloc(matrix_solver_direct2_t(&m_params));
	else
	{
		if (size >= m_gs_threshold)
		{
			if (pstring("SOR_MAT").equals(m_iterative_solver))
			{
				typedef matrix_solver_SOR_mat_t<m_N,_storage_N> solver_mat;
				return palloc(solver_mat(&m_params, size));
			}
			else if (pstring("SOR").equals(m_iterative_solver))
			{
				typedef matrix_solver_SOR_t<m_N,_storage_N> solver_GS;
				return palloc(solver_GS(&m_params, size));
			}
			else if (pstring("GMRES").equals(m_iterative_solver))
			{
				typedef matrix_solver_GMRES_t<m_N,_storage_N> solver_GMRES;
				return palloc(solver_GMRES(&m_params, size));
			}
			else
			{
				netlist().log().fatal("Unknown solver type: {1}\n", m_iterative_solver.Value());
				return NULL;
			}
		}
		else
		{
			typedef matrix_solver_direct_t<m_N,_storage_N> solver_D;
			return palloc(solver_D(&m_params, size));
		}
	}
}
Example #23
0
void NETLIB_NAME(solver)::post_start()
{
	std::vector<analog_net_t::list_t> groups;
	const bool use_specific = true;

	m_params.m_pivot = m_pivot();
	m_params.m_accuracy = m_accuracy();
	/* FIXME: Throw when negative */
	m_params.m_gs_loops = static_cast<unsigned>(m_gs_loops());
	m_params.m_nr_loops = static_cast<unsigned>(m_nr_loops());
	m_params.m_nt_sync_delay = netlist_time::from_double(m_sync_delay());
	m_params.m_lte = m_lte();
	m_params.m_sor = m_sor();

	m_params.m_min_timestep = m_min_timestep();
	m_params.m_dynamic = (m_dynamic() == 1 ? true : false);
	m_params.m_max_timestep = netlist_time::from_double(1.0 / m_freq()).as_double();

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

	//m_params.m_max_timestep = std::max(m_params.m_max_timestep, m_params.m_max_timestep::)

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

	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");
			/* Must be an analog net */
			analog_net_t *n = static_cast<analog_net_t *>(net.get());
			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)
	{
		std::unique_ptr<matrix_solver_t> ms;
		unsigned net_count = static_cast<unsigned>(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}", 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;
		}

		// FIXME ...
		ms->set_delegate_pointer();
		ms->setup(grp);

		netlist().log().verbose("Solver {1}", ms->name());
		netlist().log().verbose("       ==> {2} nets", grp.size());
		netlist().log().verbose("       has {1} elements", ms->has_dynamic_devices() ? "dynamic" : "no dynamic");
		netlist().log().verbose("       has {1} elements", ms->has_timestep_devices() ? "timestep" : "no timestep");
		for (auto &n : grp)
		{
			netlist().log().verbose("Net {1}", n->name());
			for (const auto &pcore : n->m_core_terms)
			{
				netlist().log().verbose("   {1}", pcore->name());
			}
		}

		m_mat_solvers.push_back(std::move(ms));
	}
}
Example #24
0
std::unique_ptr<matrix_solver_t> NETLIB_NAME(solver)::create_solver(unsigned size, const bool use_specific)
{
	pstring solvername = plib::pfmt("Solver_{1}")(m_mat_solvers.size());
	if (use_specific && m_N == 1)
		return plib::make_unique<matrix_solver_direct1_t>(netlist(), solvername, &m_params);
	else if (use_specific && m_N == 2)
		return plib::make_unique<matrix_solver_direct2_t>(netlist(), solvername, &m_params);
	else
	{
		if (static_cast<int>(size) >= m_gs_threshold())
		{
			if (pstring("SOR_MAT").equals(m_iterative_solver()))
			{
				typedef matrix_solver_SOR_mat_t<m_N,storage_N> solver_sor_mat;
				return plib::make_unique<solver_sor_mat>(netlist(), solvername, &m_params, size);
			}
			else if (pstring("MAT_CR").equals(m_iterative_solver()))
			{
				typedef matrix_solver_GCR_t<m_N,storage_N> solver_mat;
				return plib::make_unique<solver_mat>(netlist(), solvername, &m_params, size);
			}
			else if (pstring("MAT").equals(m_iterative_solver()))
			{
				typedef matrix_solver_direct_t<m_N,storage_N> solver_mat;
				return plib::make_unique<solver_mat>(netlist(), solvername, &m_params, size);
			}
			else if (pstring("SM").equals(m_iterative_solver()))
			{
				/* Sherman-Morrison Formula */
				typedef matrix_solver_sm_t<m_N,storage_N> solver_mat;
				return plib::make_unique<solver_mat>(netlist(), solvername, &m_params, size);
			}
			else if (pstring("W").equals(m_iterative_solver()))
			{
				/* Woodbury Formula */
				typedef matrix_solver_w_t<m_N,storage_N> solver_mat;
				return plib::make_unique<solver_mat>(netlist(), solvername, &m_params, size);
			}
			else if (pstring("SOR").equals(m_iterative_solver()))
			{
				typedef matrix_solver_SOR_t<m_N,storage_N> solver_GS;
				return plib::make_unique<solver_GS>(netlist(), solvername, &m_params, size);
			}
			else if (pstring("GMRES").equals(m_iterative_solver()))
			{
				typedef matrix_solver_GMRES_t<m_N,storage_N> solver_GMRES;
				return plib::make_unique<solver_GMRES>(netlist(), solvername, &m_params, size);
			}
			else
			{
				netlist().log().fatal("Unknown solver type: {1}\n", m_iterative_solver());
				return nullptr;
			}
		}
		else
		{
			typedef matrix_solver_direct_t<m_N,storage_N> solver_D;
			return plib::make_unique<solver_D>(netlist(), solvername, &m_params, size);
		}
	}
}
Example #25
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());
			}
		}
	}
}
Example #26
0
matrix_solver_t * NETLIB_NAME(solver)::create_solver(int size, const bool use_specific)
{
	pstring solvername = pfmt("Solver_{1}")(m_mat_solvers.size());
	if (use_specific && m_N == 1)
		return palloc(matrix_solver_direct1_t(netlist(), solvername, &m_params));
	else if (use_specific && m_N == 2)
		return palloc(matrix_solver_direct2_t(netlist(), solvername, &m_params));
	else
	{
		if (size >= m_gs_threshold)
		{
			if (pstring("SOR_MAT").equals(m_iterative_solver))
			{
				typedef matrix_solver_SOR_mat_t<m_N,_storage_N> solver_sor_mat;
				return palloc(solver_sor_mat(netlist(), solvername, &m_params, size));
			}
			else if (pstring("MAT_CR").equals(m_iterative_solver))
			{
				typedef matrix_solver_GCR_t<m_N,_storage_N> solver_mat;
				return palloc(solver_mat(netlist(), solvername, &m_params, size));
			}
			else if (pstring("MAT").equals(m_iterative_solver))
			{
				typedef matrix_solver_direct_t<m_N,_storage_N> solver_mat;
				return palloc(solver_mat(netlist(), solvername, &m_params, size));
			}
			else if (pstring("SM").equals(m_iterative_solver))
			{
				/* Sherman-Morrison Formula */
				typedef matrix_solver_sm_t<m_N,_storage_N> solver_mat;
				return palloc(solver_mat(netlist(), solvername, &m_params, size));
			}
			else if (pstring("W").equals(m_iterative_solver))
			{
				/* Woodbury Formula */
				typedef matrix_solver_w_t<m_N,_storage_N> solver_mat;
				return palloc(solver_mat(netlist(), solvername, &m_params, size));
			}
			else if (pstring("SOR").equals(m_iterative_solver))
			{
				typedef matrix_solver_SOR_t<m_N,_storage_N> solver_GS;
				return palloc(solver_GS(netlist(), solvername, &m_params, size));
			}
			else if (pstring("GMRES").equals(m_iterative_solver))
			{
				typedef matrix_solver_GMRES_t<m_N,_storage_N> solver_GMRES;
				return palloc(solver_GMRES(netlist(), solvername, &m_params, size));
			}
			else
			{
				netlist().log().fatal("Unknown solver type: {1}\n", m_iterative_solver.Value());
				return nullptr;
			}
		}
		else
		{
			typedef matrix_solver_direct_t<m_N,_storage_N> solver_D;
			return palloc(solver_D(netlist(), solvername, &m_params, size));
		}
	}
}
Example #27
0
ATTR_COLD netlist_net_t::~netlist_net_t()
{
	if (isInitialized())
		netlist().remove_save_items(this);
}
Example #28
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());
			}
		}
	}
}
Example #29
0
ATTR_COLD netlist_setup_t &netlist_device_t::setup()
{
	return netlist().setup();
}
Example #30
0
ATTR_COLD const pstring &netlist_object_t::name() const
{
	if (m_name == "")
		netlist().error("object not initialized");
	return m_name;
}