def diode(self, p, n, r_on=1, r_off=1e9, vf=0.9): # internal node x = self.tmp_var_name() # diode on/off control signal ctl = self.model.add_digital_state(self.tmp_var_name()) # compute forward voltage vf_name = self.tmp_var_name() vf_signal = self.model.bind_name(vf_name, if_(ctl, vf * (1 - r_on / r_off), 0)) # model topology curr = self.voltage(p=p, n=x, value=vf_signal) self.switch(p=x, n=n, ctl=ctl, r_on=r_on, r_off=r_off) # set up circuit monitoring volt = AnalogSignal(p) - AnalogSignal(n) self.extra_outputs += [curr, AnalogSignal(p), AnalogSignal(n)] # logic to determine when the diode is on or off DIODE_OFF = 0 DIODE_ON = 1 self.model.set_next_cycle( ctl, if_(ctl == DIODE_OFF, if_(volt > 0, DIODE_ON, DIODE_OFF), if_(curr < 0, DIODE_OFF, DIODE_ON)))
def switch(self, p, n, ctl, r_on=1, r_off=1e9): # add variable names as necessary self.add_var_names(p, n) # add related equations cond = eqn_case([1 / r_off, 1 / r_on], [ctl]) self.two_pin_kcl(p, n, (AnalogSignal(p) - AnalogSignal(n)) * cond)
def main(): x = AnalogSignal('x') y = AnalogSignal('y') eqn_sys = EqnSys() eqn_sys.add_eqn(Deriv(y) == 0.1 * (x - y)) lds = eqn_sys.to_lds(inputs=[x], states=[y]) print(lds)
def inductor(self, p, n, value, current_range): # add variable names if necessary self.add_var_names(p, n) # add state variable current = self.model.add_analog_state(self.tmp_var_name(), range_=current_range) # add related equations+ self.add_eqn(Deriv(current) == (AnalogSignal(p) - AnalogSignal(n)) / value) self.two_pin_kcl(p, n, current) return current
def transformer(self, pri_p, pri_n, sec_p, sec_n, ratio): # add variable names as necessary self.add_var_names(pri_p, pri_n, sec_p, sec_n) # define current variables pri_curr = AnalogSignal(self.tmp_var_name()) sec_curr = AnalogSignal(self.tmp_var_name()) # add related equations self.add_eqn(AnalogSignal(sec_p)-AnalogSignal(sec_n) == ratio*(AnalogSignal(pri_p)-AnalogSignal(pri_n))) self.add_eqn(sec_curr == -pri_curr/ratio) self.two_pin_kcl(pri_p, pri_n, pri_curr) self.two_pin_kcl(sec_p, sec_n, sec_curr)
def main(): # equation display print(EqnList([AnalogSignal('a') == AnalogSignal('b')])) print() # signal extraction print(signal_names(EqnList([AnalogSignal('a') == AnalogSignal('b')]).get_all_signals())) print(signal_names(EqnList([AnalogSignal('a') == Deriv(AnalogSignal('b'))]).get_derivs())) print(signal_names(EqnList([AnalogSignal('a') == Deriv(AnalogSignal('b'))]).get_states())) print(signal_names(EqnList([AnalogSignal('a') == EqnCase([1, 2], [DigitalSignal('s')])]).get_sel_bits()))
def voltage(self, p, n, value): # TODO: handle cases when value is (1) constant or (2) expression # add variable names if necessary self.add_var_names(p, n) # create variable for current through voltage source current = AnalogSignal(self.tmp_var_name()) # add related equations self.two_pin_kcl(p, n, current) self.add_eqn(AnalogSignal(p) - AnalogSignal(n) == value) # return the current through the voltage source return current
def make_ground(self): ground = self.tmp_var_name() self.add_eqn(AnalogSignal(ground) == 0) self.grounds.add(ground) return ground
def capacitor(self, p, n, value, voltage_range): # add variable names if necessary self.add_var_names(p, n) # add state variable voltage = self.model.add_analog_state(self.tmp_var_name(), range_=voltage_range) # create variable for capacitor current current = AnalogSignal(self.tmp_var_name()) # add related equations self.add_eqn(Deriv(voltage) == current / value) self.add_eqn(AnalogSignal(p) - AnalogSignal(n) == voltage) self.two_pin_kcl(p, n, current) return voltage
def main(): from msdsl.eqn.deriv import Deriv from msdsl.eqn.cases import eqn_case from msdsl.expr.signals import DigitalSignal model = MixedSignalModel('test', AnalogInput('x'), dt=1) y = AnalogSignal('y') z = model.add_signal(AnalogSignal('z', 10)) s = model.add_signal(DigitalSignal('s')) eqn_sys = EqnSys( [y == model.x + 1, Deriv(z) == (y - z) * eqn_case([2, 3], [s])]) inputs, states, outputs, sel_bits = model.get_equation_io(eqn_sys) print('inputs:', signal_names(inputs)) print('states:', signal_names(states)) print('outputs:', signal_names(outputs)) print('sel_bits:', signal_names(sel_bits))
def main(): from msdsl.expr.signals import AnalogSignal a = AnalogSignal('a') b = AnalogSignal('b') c = AnalogSignal('c') d = AnalogSignal('d') e = AnalogSignal('e') print(distribute_mult(1 * a + 2 * b + 3 * (4 + 5 * (6 + 7 * c)))) pairs, others = extract_coeffs(a + 2 * b + 3 * c) print('pairs: ' + str({k: v.name for k, v in pairs})) print('others: ' + str([str(other) for other in others])) def simplify(expr): return collect_terms(distribute_mult(expr)) print(simplify(1 * a + 2 * b + 3 * c + 4 * d + 7 * (c + (d + e) * (4 + 5)))) print(simplify((2 * a + 2 * b) / 2)) print(simplify(a / 2 + (a + 2 * b) / 2)) print(simplify(a + b - b)) print(simplify(a + 2 * (1 - b) + 1 * (2 * b - a) - 2))
def resistor(self, p, n, value): # add variable names if necessary self.add_var_names(p, n) # add related equations self.two_pin_kcl(p, n, (AnalogSignal(p) - AnalogSignal(n)) / value)
def main(): x = AnalogSignal('x') y = AnalogSignal('y') print(Deriv(x) + y + 1)