コード例 #1
0
        //NETLIB_HANDLERI(control)
        void control()
        {
            nl_fptype sup       = (m_supply.VCC().Q_Analog() - m_supply.GND().Q_Analog());
            nl_fptype in_       = m_control.op() - m_supply.GND().Q_Analog();
            nl_fptype rON       = m_base_r.op() * nlconst.magic(5.0) / sup;
            nl_fptype R         = -nlconst.one();
            nl_fptype low       = nlconst.magic(0.45) * sup;
            nl_fptype high      = nlconst.magic(0.55) * sup;
            bool      new_state = false;

            if (in_ < low)
            {
                R = plib.pg.reciprocal(exec().gmin());
            }
            else if (in_ > high)
            {
                R         = rON;
                new_state = true;
            }

            if (R > nlconst.zero() && (m_last.op != new_state))
            {
                m_last.op = new_state;
                m_R.change_state(() => { this.m_R.set_R(R); });  //m_R.change_state([this, &R]() -> void { this->m_R.set_R(R);});
            }
        }
コード例 #2
0
        //NETLIB_HANDLERI(in)
        void in_()
        {
            nl_fptype cur = m_in.op();

            if (plib.pg.abs(cur - m_last.op) > m_threshold)
            {
                m_last.op = cur;
                m_func(this, cur);
            }
        }
コード例 #3
0
        //NETLIB_HANDLERI(inputs)
        void inputs()
        {
            // FIXME: assumes GND is connected to 0V.

            var reset = m_RESET.op();

            nl_fptype vthresh = clamp_hl(m_R2.P().op(), nlconst.magic(0.7), nlconst.magic(1.4));
            nl_fptype vtrig   = clamp_hl(m_R2.N().op(), nlconst.magic(0.7), nlconst.magic(1.4));

            // avoid artificial oscillation due to overshoot compensation when
            // the control input is used.
            var ovlimit = std.min(m_ovlimit, std.max(0.0, (vthresh - vtrig) / 3.0));

            if (reset == 0 && m_last_reset.op)
            {
                m_ff.op = false;
            }
            else
            {
#if (NL_USE_BACKWARD_EULER)
                bool bthresh = (m_THRES.op() + m_overshoot.op > vthresh);
                bool btrig   = (m_TRIG.op() - m_overshoot.op > vtrig);
#else
                const bool bthresh = (m_THRES() + m_overshoot > vthresh);
                const bool btrig   = (m_TRIG() - m_undershoot > vtrig);
#endif
                if (!btrig)
                {
                    m_ff.op = true;
                }
                else if (bthresh)
                {
                    m_ff.op = false;
                }
            }

            bool out_ = (reset == 0 ? false : m_ff.op);

            if (m_last_out.op && !out_)
            {
#if (NL_USE_BACKWARD_EULER)
                m_overshoot.op += ((m_THRES.op() - vthresh)) * 2.0;
#else
                m_overshoot += ((m_THRES() - vthresh));
#endif
                m_overshoot.op = plib.pg.clamp(m_overshoot.op, nlconst.zero(), ovlimit);
                //if (this->name() == "IC6_2")
                //  printf("%f %s %f %f %f\n", exec().time().as_double(), this->name().c_str(), m_overshoot(), m_R2.P()(), m_THRES());
                m_RDIS.change_state(() =>
                {
                    m_RDIS.set_R(nlconst.magic(R_ON));
                });
                m_OUT.push(m_R3.N().op());
            }
            else if (!m_last_out.op && out_)
            {
#if (NL_USE_BACKWARD_EULER)
                m_overshoot.op += (vtrig - m_TRIG.op()) * 2.0;
                m_overshoot.op  = plib.pg.clamp(m_overshoot.op, nlconst.zero(), ovlimit);
#else
                m_undershoot += (vtrig - m_TRIG());
                m_undershoot  = plib::clamp(m_undershoot(), nlconst::zero(), ovlimit);
#endif
                m_RDIS.change_state(() =>
                {
                    m_RDIS.set_R(nlconst.magic(R_OFF));
                });
                // FIXME: Should be delayed by 100ns
                m_OUT.push(m_R1.P().op());
            }

            m_last_reset.op = reset != 0;
            m_last_out.op   = out_;
        }