示例#1
0
            netlist_time compute_next_timestep(double cur_ts)
            {
                nl_double new_solver_timestep = m_params.m_max_timestep;

                if (m_params.m_dynamic_ts)
                {
                    for (int k = 0, iN = m_terms.size(); k < iN; k++)
                    {
                        analog_net_t    n = m_nets[k];
                        terms_for_net_t t = m_terms[k].get();

                        nl_double DD_n = (n.Q_Analog() - t.last_V);
                        nl_double hn   = cur_ts;

                        //printf("%f %f %f %f\n", DD_n, t->m_DD_n_m_1, hn, t->m_h_n_m_1);
                        nl_double DD2 = (DD_n / hn - t.DD_n_m_1 / t.h_n_m_1) / (hn + t.h_n_m_1);
                        nl_double new_net_timestep;

                        t.h_n_m_1  = hn;
                        t.DD_n_m_1 = DD_n;
                        if (Math.Abs(DD2) > nl_config_global.NL_FCONST(1e-60)) // avoid div-by-zero
                        {
                            new_net_timestep = Math.Sqrt(m_params.m_dynamic_lte / Math.Abs(nl_config_global.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.last_V = n.Q_Analog();
                    }
                    if (new_solver_timestep < m_params.m_min_timestep)
                    {
                        //log().warning("Dynamic timestep below min timestep. Consider decreasing MIN_TIMESTEP: {1} us", new_solver_timestep*1.0e6);
                        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(netlist_time.Max(netlist_time.from_double(new_solver_timestep), netlist_time.quantum() * 2));
            }
示例#2
0
 bool already_processed(analog_net_t n)
 {
     if (n.isRailNet())
     {
         return(true);
     }
     foreach (var grp in groups)
     {
         if (grp.Contains(n))  //plib::container::contains(grp, n))
         {
             return(true);
         }
     }
     return(false);
 }
示例#3
0
 bool already_processed(analog_net_t n)
 {
     // no need to process rail nets - these are known variables
     if (n.is_rail_net())
     {
         return(true);
     }
     // if it's already processed - no need to continue
     foreach (var grp in groups)
     {
         if (plib.container.contains(grp, n))
         {
             return(true);
         }
     }
     return(false);
 }
示例#4
0
 public void run(netlist_base_t netlist)
 {
     foreach (var net in netlist.nets())
     {
         netlist.log().debug.op("processing {0}\n", net.name());
         if (!net.isRailNet() && net.num_cons() > 0)
         {
             netlist.log().debug.op("   ==> not a rail net\n");
             /* Must be an analog net */
             analog_net_t n = (analog_net_t)net;
             if (!already_processed(n))
             {
                 groups.push_back(new analog_net_t_list_t());
                 process_net(n);
             }
         }
     }
 }
示例#5
0
 void process_net(analog_net_t n)
 {
     if (n.num_cons() == 0)
     {
         return;
     }
     /* add the net */
     groups.back().push_back(n);
     foreach (var p in n.core_terms)
     {
         if (p.is_type(detail.terminal_type.TERMINAL))
         {
             terminal_t   pt        = (terminal_t)p;
             analog_net_t other_net = pt.otherterm.net();
             if (!already_processed(other_net))
             {
                 process_net(other_net);
             }
         }
     }
 }
示例#6
0
            bool check_if_processed_and_join(analog_net_t n)
            {
                // no need to process rail nets - these are known variables
                if (n.is_rail_net())
                {
                    return(true);
                }

                // First check if it is in a previous group.
                // In this case we need to merge this group into the current group
                if (groupspre.size() > 1)
                {
                    for (size_t i = 0; i < groupspre.size() - 1; i++)
                    {
                        if (plib.container.contains(groupspre[i], n))
                        {
                            // copy all nets
                            foreach (var cn in groupspre[i])
                            {
                                if (!plib.container.contains(groupspre.back(), cn))
                                {
                                    groupspre.back().push_back(cn);
                                }
                            }

                            // clear
                            groupspre[i].clear();
                            return(true);
                        }
                    }
                }

                // if it's already processed - no need to continue
                if (!groupspre.empty() && plib.container.contains(groupspre.back(), n))
                {
                    return(true);
                }

                return(false);
            }
示例#7
0
            void process_net(netlist_state_t nlstate, analog_net_t n)
            {
                // ignore empty nets. FIXME: print a warning message
                nlstate.log().verbose.op("Net {0}", n.name());
                if (!nlstate.core_terms(n).empty())
                {
                    // add the net
                    groupspre.back().push_back(n);
                    // process all terminals connected to this net
                    foreach (var term in nlstate.core_terms(n))
                    {
                        nlstate.log().verbose.op("Term {0} {1}", term.name(), (int)term.type());
                        // only process analog terminals
                        if (term.is_type(detail.terminal_type.TERMINAL))
                        {
                            var pt = (terminal_t)term;  //auto &pt = dynamic_cast<terminal_t &>(*term);
                            // check the connected terminal
                            var connected_terminals = nlstate.setup().get_connected_terminals(pt);
                            foreach (var ct in connected_terminals)  //for (auto ct = connected_terminals->begin(); *ct != nullptr; ct++)
                            {
                                if (ct == default)
                                {
                                    continue;
                                }

                                analog_net_t connected_net = ct.net();
                                nlstate.log().verbose.op("  Connected net {0}", connected_net.name());
                                if (!check_if_processed_and_join(connected_net))
                                {
                                    process_net(nlstate, connected_net);
                                }
                            }
                        }
                    }
                }
            }
示例#8
0
            /* return number of floating point operations for solve */
            //std::size_t ops() { return m_ops; }


            protected void setup_base(analog_net_t_list_t nets)
            {
                log().debug.op("New solver setup\n");

                m_nets.clear();
                m_terms.clear();

                foreach (var net in nets)
                {
                    m_nets.push_back(net);
                    m_terms.push_back(new terms_for_net_t());
                    m_rails_temp.push_back(new terms_for_net_t());
                }

                for (UInt32 k = 0; k < nets.size(); k++)
                {
                    analog_net_t net = nets[k];

                    log().debug.op("setting up net\n");

                    net.set_solver(this);

                    foreach (var p in net.core_terms)
                    {
                        log().debug.op("{0} {1} {2}\n", p.name(), net.name(), net.isRailNet());

                        switch (p.type())
                        {
                        case detail.terminal_type.TERMINAL:
                            if (p.device().is_timestep())
                            {
                                if (!m_step_devices.Contains(p.device()))      //(!plib::container::contains(m_step_devices, &p->device()))
                                {
                                    m_step_devices.push_back(p.device());
                                }
                            }

                            if (p.device().is_dynamic())
                            {
                                if (!m_dynamic_devices.Contains(p.device()))      //if (!plib::container::contains(m_dynamic_devices, &p->device()))
                                {
                                    m_dynamic_devices.push_back(p.device());
                                }
                            }

                            {
                                terminal_t pterm = (terminal_t)p;
                                add_term(k, pterm);
                            }

                            log().debug.op("Added terminal {0}\n", p.name());
                            break;

                        case detail.terminal_type.INPUT:
                        {
                            proxied_analog_output_t net_proxy_output = null;
                            foreach (var input in m_inps)
                            {
                                if (input.proxied_net == p.net())
                                {
                                    net_proxy_output = input;
                                    break;
                                }
                            }

                            if (net_proxy_output == null)
                            {
                                string nname = this.name() + "." + new plib.pfmt("m{0}").op(m_inps.size());
                                var    net_proxy_output_u = new proxied_analog_output_t(this, nname);
                                net_proxy_output = net_proxy_output_u;
                                m_inps.push_back(net_proxy_output_u);
                                nl_base_global.nl_assert(p.net().is_analog());
                                net_proxy_output.proxied_net = (analog_net_t)p.net();
                            }

                            net_proxy_output.net().add_terminal(p);

                            // FIXME: repeated calling - kind of brute force
                            net_proxy_output.net().rebuild_list();

                            log().debug.op("Added input\n");
                        }
                        break;

                        case detail.terminal_type.OUTPUT:
                            log().fatal.op(nl_errstr_global.MF_1_UNHANDLED_ELEMENT_1_FOUND, p.name());
                            break;
                        }
                    }

                    log().debug.op("added net with {0} populated connections\n", net.core_terms.size());
                }

                /* now setup the matrix */
                setup_matrix();
            }
示例#9
0
            analog_net_t m_proxied_net; // only for proxy nets in analog input logic


            public proxied_analog_output_t(core_device_t dev, string aname)
                : base(dev, aname)
            {
                m_proxied_net = null;
            }