/// <summary> /// Generate the mosfet instance /// </summary> /// <param name="type">Type</param> /// <param name="name">Name</param> /// <param name="parameters">Parameters</param> /// <param name="netlist">Netlist</param> /// <returns></returns> protected override ICircuitObject Generate(string type, CircuitIdentifier name, List <Token> parameters, Netlist netlist) { // Errors switch (parameters.Count) { case 0: throw new ParseException($"Node expected for component {name}"); case 1: case 2: case 3: throw new ParseException(parameters[parameters.Count - 1], "Node expected", false); case 4: throw new ParseException(parameters[3], "Model name expected"); } // Get the model and generate a component for it ICircuitObject model = netlist.Path.FindModel <ICircuitObject>(netlist.Circuit.Objects, new CircuitIdentifier(parameters[4].image)); ICircuitComponent mosfet = null; if (Mosfets.ContainsKey(model.GetType())) { mosfet = Mosfets[model.GetType()].Invoke(name, model); } else { throw new ParseException(parameters[4], "Invalid model"); } // The rest is all just parameters mosfet.ReadNodes(netlist.Path, parameters); netlist.ReadParameters((IParameterized)mosfet, parameters, 4); return(mosfet); }
/// <summary> /// Read /// </summary> /// <param name="name">Name</param> /// <param name="parameters">Parameters</param> /// <param name="netlist">Netlist</param> /// <returns></returns> public override bool Read(string type, Statement st, Netlist netlist) { var model = GenerateModel(new CircuitIdentifier(st.Name.image), type); netlist.ReadParameters((IParameterized)model, st.Parameters); // Output netlist.Circuit.Objects.Add(model); Generated = model; return(true); }
/// <summary> /// Generate a capacitor /// </summary> /// <param name="name">Name</param> /// <param name="parameters">Parameters</param> /// <param name="netlist">Netlist</param> /// <returns></returns> protected ICircuitObject GenerateCap(CircuitIdentifier name, List <Token> parameters, Netlist netlist) { Capacitor cap = new Capacitor(name); cap.ReadNodes(netlist.Path, parameters); // Search for a parameter IC, which is common for both types of capacitors for (int i = 3; i < parameters.Count; i++) { if (parameters[i].kind == ASSIGNMENT) { AssignmentToken at = parameters[i] as AssignmentToken; if (at.Name.image.ToLower() == "ic") { double ic = netlist.ParseDouble(at.Value); cap.CAPinitCond.Set(ic); parameters.RemoveAt(i); break; } } } // The rest is just dependent on the number of parameters if (parameters.Count == 3) { cap.CAPcapac.Set(netlist.ParseDouble(parameters[2])); } else { cap.SetModel(netlist.FindModel <CapacitorModel>(parameters[2])); switch (parameters[2].kind) { case WORD: case IDENTIFIER: cap.SetModel(netlist.Path.FindModel <CapacitorModel>(netlist.Circuit.Objects, new CircuitIdentifier(parameters[2].image))); break; default: throw new ParseException(parameters[2], "Model name expected"); } netlist.ReadParameters(cap, parameters, 2); if (!cap.CAPlength.Given) { throw new ParseException(parameters[1], "L needs to be specified", false); } } return(cap); }
/// <summary> /// Generate an inductor /// </summary> /// <param name="name">Name</param> /// <param name="parameters">Parameters</param> /// <param name="netlist">Netlist</param> /// <returns></returns> protected ICircuitObject GenerateInd(CircuitIdentifier name, List <Token> parameters, Netlist netlist) { Inductor ind = new Inductor(name); ind.ReadNodes(netlist.Path, parameters); // Read the value if (parameters.Count < 3) { throw new ParseException(parameters[1], "Inductance expected", false); } ind.INDinduct.Set(netlist.ParseDouble(parameters[2])); // Read initial conditions netlist.ReadParameters(ind, parameters, 3); return(ind); }
/// <summary> /// Generate a resistor /// </summary> /// <param name="name">Name</param> /// <param name="parameters">Parameters</param> /// <param name="netlist">Netlist</param> /// <returns></returns> protected ICircuitObject GenerateRes(CircuitIdentifier name, List <Token> parameters, Netlist netlist) { Resistor res = new Resistor(name); res.ReadNodes(netlist.Path, parameters); // We have two possible formats: // Normal: RXXXXXXX N1 N2 VALUE if (parameters.Count == 3) { res.RESresist.Set(netlist.ParseDouble(parameters[2])); } else { // Read the model res.SetModel(netlist.FindModel <ResistorModel>(parameters[2])); netlist.ReadParameters(res, parameters, 3); if (!res.RESlength.Given) { throw new ParseException(parameters[parameters.Count - 1], "L needs to be specified", false); } } return(res); }
/// <summary> /// Read a transistor model /// </summary> /// <param name="type">Type</param> /// <param name="st">Statement</param> /// <param name="netlist">Netlist</param> /// <returns></returns> public override bool Read(string type, Statement st, Netlist netlist) { // Errors switch (st.Parameters.Count) { case 0: throw new ParseException(st.Name, "Model name and type expected", false); } // The model depends on the model level, find the model statement int level = 0; string version = null; int lindex = -1, vindex = -1; for (int i = 0; i < st.Parameters.Count; i++) { if (st.Parameters[i].kind == ASSIGNMENT) { AssignmentToken at = st.Parameters[i] as AssignmentToken; if (at.Name.image.ToLower() == "level") { lindex = i; level = (int)Math.Round(netlist.ParseDouble(at.Value)); } if (at.Name.image.ToLower() == "version") { vindex = i; version = at.Value.image.ToLower(); } if (vindex >= 0 && lindex >= 0) { break; } } } if (lindex >= 0) { st.Parameters.RemoveAt(lindex); } if (vindex >= 0) { st.Parameters.RemoveAt(vindex < lindex ? vindex : vindex - 1); } // Generate the model ICircuitObject model = null; if (Levels.ContainsKey(level)) { model = Levels[level].Invoke(new CircuitIdentifier(st.Name.image), type, version); } else { throw new ParseException(st.Name, $"Unknown mosfet model level {level}"); } // Read all the parameters netlist.ReadParameters((IParameterized)model, st.Parameters); // Output netlist.Circuit.Objects.Add(model); Generated = model; return(true); }