def gen_model(cap=0.16e-6, ind=0.16e-6, res=0.1, dt=0.01e-6, real_type=RealType.FixedPoint): # declare model m = MixedSignalModel('model', dt=dt, real_type=real_type) m.add_analog_input('v_in') m.add_analog_output('v_out') m.add_digital_input('clk') m.add_digital_input('rst') # declare system of equations m.add_analog_state('i_ind', 10) # TODO: can this be tightened down a bit? v_l = AnalogSignal('v_l') v_r = AnalogSignal('v_r') eqns = [ Deriv(m.i_ind) == v_l / ind, Deriv(m.v_out) == m.i_ind / cap, v_r == m.i_ind * res, m.v_in == m.v_out + v_l + v_r ] m.add_eqn_sys(eqns, clk=m.clk, rst=m.rst) BUILD_DIR.mkdir(parents=True, exist_ok=True) model_file = BUILD_DIR / 'model.sv' m.compile_to_file(VerilogGenerator(), filename=model_file) return model_file
def test_simplify(): a = AnalogSignal('a') b = AnalogSignal('b') c = AnalogSignal('c') d = AnalogSignal('d') e = a - (b - 12 * (c - d)) + b + 34 * c + 46.5 * d print('Original expression:') print(e) print('') f = distribute_mult(e) print('Flattened expresion:') print(f) print('') coeffs, others = extract_coeffs(f) print('Extracted coefficients (may contain repeats):') print([(coeff, signal.name) for coeff, signal in coeffs]) print('') # make sure there are no unhandled terms assert len(others) == 0 # sum up all of the coefficients for each signal signals = {} for coeff, signal in coeffs: if signal.name not in signals: signals[signal.name] = 0 signals[signal.name] += coeff # check results print('Signal coefficients:') print(signals) assert signals == {'a': 1, 'b': 0, 'c': 46, 'd': 34.5}
def gen_model(r_off=2.6e3, current_range=100, real_type=RealType.FixedPoint): # declare model m = MixedSignalModel('model', dt=1e-9, real_type=real_type) m.add_analog_input('v_in') m.add_analog_output('v_out') m.add_digital_input('sw1') m.add_digital_input('sw2') m.add_digital_input('clk') m.add_digital_input('rst') # create test circuit c = m.make_circuit(clk=m.clk, rst=m.rst) gnd = c.make_ground() c.voltage('net_v_in', gnd, m.v_in) c.switch('net_v_in', 'net_v_x', m.sw1, r_off=r_off) c.switch('net_v_x', gnd, m.sw2, r_off=r_off) c.inductor('net_v_in', 'net_v_x', 1.0, current_range=current_range) c.add_eqns(AnalogSignal('net_v_x') == m.v_out) # compile to a file BUILD_DIR.mkdir(parents=True, exist_ok=True) model_file = BUILD_DIR / 'model.sv' m.compile_to_file(VerilogGenerator(), filename=model_file) # return file location return model_file
def gen_model(rp1, rn1, rp2, rn2, real_type, dt=0.1e-6): # declare model m = MixedSignalModel('model', dt=dt, real_type=real_type) # declare I/O m.add_analog_input('v_in') m.add_analog_output('v_out') m.add_digital_input('sw1') m.add_digital_input('sw2') # declare switch circuit c = m.make_circuit() gnd = c.make_ground() c.voltage('net_v_in', gnd, m.v_in) c.switch('net_v_in', 'net_v_x', m.sw1, r_on=rp1, r_off=rn1) c.switch('net_v_x', gnd, m.sw2, r_on=rp2, r_off=rn2) c.add_eqns(AnalogSignal('net_v_x') == m.v_out) # compile to a file BUILD_DIR.mkdir(parents=True, exist_ok=True) model_file = BUILD_DIR / 'model.sv' m.compile_to_file(VerilogGenerator(), filename=model_file) # return file location return model_file
def __init__(self, name='buck', dt=0.1e-6, ind=2.2e-6, c_load=10e-6, r_load=5.5, r_snub=300, c_snub=100e-12, r_sw_on=1.0, r_sw_off=10e3): # call the super constructor super().__init__(name, dt=dt) self.add_digital_input('hs') self.add_digital_input('ls') self.add_analog_input('v_in') self.add_analog_output('v_out') self.add_analog_output('i_ind') # define the circuit c = self.make_circuit() gnd = c.make_ground() # input voltage c.voltage('net_v_in', gnd, self.v_in) # switches c.switch('net_v_in', 'net_v_sw', self.hs, r_on=r_sw_on, r_off=r_sw_off) c.switch('net_v_sw', gnd, self.ls, r_on=r_sw_on, r_off=r_sw_off) # snubber network v_snub = c.capacitor('net_v_sw', 'net_v_x', c_snub, voltage_range=10 * RangeOf(self.v_out)) c.resistor('net_v_x', gnd, r_snub) self.bind_name('v_snub', v_snub) self.add_probe(self.v_snub) # inductor + current measurement c.inductor('net_v_sw', 'net_v_l', ind, current_range=RangeOf(self.i_ind)) i_ind = c.voltage('net_v_l', 'net_v_out', 0) # output load c.capacitor('net_v_out', gnd, c_load, voltage_range=RangeOf(self.v_out)) c.resistor('net_v_out', gnd, r_load) # assign outputs c.add_eqns(self.v_out == AnalogSignal('net_v_out'), self.i_ind == i_ind)
def test_distribute_mult(): a = AnalogSignal('a') b = AnalogSignal('b') c = AnalogSignal('c') d = AnalogSignal('d') e = a + 3.4 * (b + 5.6 * (c + 7.8 * d)) print('Original expression:') print(e) print('') f = distribute_mult(e) print('Flattened expresion:') print(f) print('') v = VerilogGenerator() v.text = '' v.expr_to_signal(f) print('Compiled expression:') print(v.text) print('') # check that the flattened expression is OK assert (isinstance(f, Sum)) res = {} for op in f.operands: if isinstance(op, Product): subops = op.operands sig = subops[0] if isinstance(subops[0], AnalogSignal) else subops[1] val = subops[1] if isinstance(subops[0], AnalogSignal) else subops[0] res[sig.name] = val.value elif isinstance(op, AnalogSignal): res[op.name] = 1.0 print('Dictionary mapping signal names to coefficients:') print(res) assert len(res) == 4 assert isclose(res['a'], 1) assert isclose(res['b'], 3.4) assert isclose(res['c'], 3.4 * 5.6) assert isclose(res['d'], 3.4 * 5.6 * 7.8)
def main(): a = AnalogSignal('a') b = AnalogSignal('b') c = AnalogSignal('c') d = AnalogSignal('d') e = 1.2 * (a + 3.4 * (b + 5.6 * (c + 7.8 * d))) print('Original expression:') print(e) print('') print('Expression after flattening:') print(distribute_mult(e)) print('') print('Compiled expression') v = VerilogGenerator() v.text = '' v.expr_to_signal(distribute_mult(e)) print(v.text)
def main(): dt = 0.01e-6 cap = 0.16e-6 ind = 0.16e-6 res = 0.1 model = MixedSignalModel('model', dt=dt) model.add_analog_input('v_in') model.add_analog_output('v_out') model.add_analog_state('i_ind', 100) v_l = AnalogSignal('v_l') v_r = AnalogSignal('v_r') eqns = [ Deriv(model.i_ind) == v_l / ind, Deriv(model.v_out) == model.i_ind / cap, v_r == model.i_ind * res, model.v_in == model.v_out + v_l + v_r ] model.add_eqn_sys(eqns) model.compile_and_print(VerilogGenerator())
def main(cap=0.16e-6, ind=0.16e-6, res=0.1): print('Running model generator...') # parse command line arguments parser = ArgumentParser() parser.add_argument('-o', '--output', type=str) parser.add_argument('--dt', type=float) args = parser.parse_args() # create the model model = MixedSignalModel('rlc', AnalogInput('v_in'), AnalogOutput('v_out'), dt=args.dt) model.add_analog_state('i_ind', 100) # internal variables v_l = AnalogSignal('v_l') v_r = AnalogSignal('v_r') # define dynamics eqns = [ Deriv(model.i_ind) == v_l / ind, Deriv(model.v_out) == model.i_ind / cap, v_r == model.i_ind * res, model.v_in == model.v_out + v_l + v_r ] model.add_eqn_sys(eqns) # define probes #model.add_probe(model.i_ind) # determine the output filename filename = os.path.join(get_full_path(args.output), f'{model.module_name}.sv') print('Model will be written to: ' + filename) # generate the model model.compile_to_file(VerilogGenerator(), filename)
def __init__(self, name='filter', res=1e3, cap=1e-9, dt=0.1e-6): # call the super constructor super().__init__(name, dt=dt) # define I/O self.add_analog_input('v_in') self.add_analog_output('v_out') c = self.make_circuit() gnd = c.make_ground() c.capacitor('net_v_out', gnd, cap, voltage_range=RangeOf(self.v_out)) c.resistor('net_v_in', 'net_v_out', res) c.voltage('net_v_in', gnd, self.v_in) c.add_eqns(AnalogSignal('net_v_out') == self.v_out)
def main(): dt = 0.1e-6 res = 1e3 cap = 1e-9 m = MixedSignalModel('model', dt=dt) m.add_analog_input('v_in') m.add_analog_output('v_out') c = m.make_circuit() gnd = c.make_ground() c.capacitor('net_v_out', gnd, cap, voltage_range=RangeOf(m.v_out)) c.resistor('net_v_in', 'net_v_out', res) c.voltage('net_v_in', gnd, m.v_in) c.add_eqns(AnalogSignal('net_v_out') == m.v_out) m.compile_and_print(VerilogGenerator())
def gen_model(res=1e3, cap=1e-9, dt=0.1e-6, real_type=RealType.FixedPoint): m = MixedSignalModel('model', dt=dt, real_type=real_type) m.add_analog_input('v_in') m.add_analog_output('v_out') m.add_digital_input('clk') m.add_digital_input('rst') c = m.make_circuit(clk=m.clk, rst=m.rst) gnd = c.make_ground() c.capacitor('net_v_out', gnd, cap, voltage_range=RangeOf(m.v_out)) c.resistor('net_v_in', 'net_v_out', res) c.voltage('net_v_in', gnd, m.v_in) c.add_eqns(AnalogSignal('net_v_out') == m.v_out) BUILD_DIR.mkdir(parents=True, exist_ok=True) model_file = BUILD_DIR / 'model.sv' m.compile_to_file(VerilogGenerator(), filename=model_file) return model_file
def main(cap=1e-12, res=600): ctrl = ExampleControl() # define ports m = MixedSignalModel('current_switch', dt=ctrl.dt) m.add_digital_input('ctrl') m.add_analog_input('v_in') m.add_analog_output('v_out') # define the circuit c = m.make_circuit() gnd = c.make_ground() c.switch('net_v_in', 'net_v_out', m.ctrl, r_on=res, r_off=10e3 * res) c.capacitor('net_v_out', gnd, cap, voltage_range=RangeOf(m.v_out)) c.voltage('net_v_in', gnd, m.v_in) c.add_eqns(m.v_out == AnalogSignal('net_v_out')) # write model ctrl.write_model(m)
def main(): dt = 0.1e-6 m = MixedSignalModel('model', dt=dt) m.add_analog_input('v_in') m.add_analog_output('v_out') m.add_digital_input('sw1') m.add_digital_input('sw2') c = m.make_circuit() gnd = c.make_ground() c.voltage('net_v_in', gnd, m.v_in) c.switch('net_v_in', 'net_v_x', m.sw1, r_on=1.0, r_off=2.0) c.switch('net_v_x', gnd, m.sw2, r_on=3.0, r_off=4.0) c.add_eqns( AnalogSignal('net_v_x') == m.v_out ) m.compile_and_print(VerilogGenerator())
def main(): dt = 1e-9 m = MixedSignalModel('model', dt=dt) m.add_analog_input('v_in') m.add_analog_output('v_out') m.add_digital_input('sw1') m.add_digital_input('sw2') c = m.make_circuit() gnd = c.make_ground() c.voltage('net_v_in', gnd, m.v_in) c.switch('net_v_in', 'net_v_x', m.sw1) c.switch('net_v_x', gnd, m.sw2) c.inductor('net_v_in', 'net_v_x', 1, current_range=100) c.add_eqns(AnalogSignal('net_v_x') == m.v_out) m.compile_and_print(VerilogGenerator())
def __init__(self, name='filter', dt=0.1e-6): # call the super constructor super().__init__(name, dt=dt) self.add_analog_input('v_in') self.add_analog_output('v_out') self.add_digital_input('sw1') self.add_digital_input('sw2') c = self.make_circuit() gnd = c.make_ground() c.voltage('net_v_in', gnd, self.v_in) c.switch('net_v_in', 'net_v_x', self.sw1) c.switch('net_v_x', gnd, self.sw2) c.capacitor('net_v_x', gnd, 1e-12, 100) c.inductor('net_v_in', 'net_v_x', 1e-6, current_range=100.0) c.add_eqns( AnalogSignal('net_v_x') == self.v_out )