Exemple #1
0
        /// <summary>
        /// Generate a mutual inductance
        /// </summary>
        /// <param name="name">Name</param>
        /// <param name="parameters">Parameters</param>
        /// <param name="netlist">Netlist</param>
        /// <returns></returns>
        protected ICircuitObject GenerateMut(CircuitIdentifier name, List <Token> parameters, Netlist netlist)
        {
            MutualInductance mut = new MutualInductance(name);

            switch (parameters.Count)
            {
            case 0: throw new ParseException($"Inductor name expected for mutual inductance \"{name}\"");

            case 1: throw new ParseException(parameters[0], "Inductor name expected", false);

            case 2: throw new ParseException(parameters[1], "Coupling factor expected", false);
            }

            // Read two inductors
            if (!ReaderExtension.IsName(parameters[0]))
            {
                throw new ParseException(parameters[0], "Component name expected");
            }
            mut.MUTind1 = new CircuitIdentifier(parameters[0].image);
            if (!ReaderExtension.IsName(parameters[1]))
            {
                throw new ParseException(parameters[1], "Component name expected");
            }
            mut.MUTind2 = new CircuitIdentifier(parameters[1].image);
            mut.MUTcoupling.Set(netlist.ParseDouble(parameters[2]));
            return(mut);
        }
        /// <summary>
        /// Generate a current source
        /// </summary>
        /// <param name="name">Name</param>
        /// <param name="parameters">Parameters</param>
        /// <param name="netlist">Netlist</param>
        /// <returns></returns>
        protected ICircuitObject GenerateISRC(CircuitIdentifier name, List <Token> parameters, Netlist netlist)
        {
            Currentsource isrc = new Currentsource(name);

            isrc.ReadNodes(netlist.Path, parameters);

            // We can have a value or just DC
            for (int i = 2; i < parameters.Count; i++)
            {
                // DC specification
                if (i == 2 && parameters[i].image.ToLower() == "dc")
                {
                    i++;
                    isrc.ISRCdcValue.Set(netlist.ParseDouble(parameters[i]));
                }
                else if (i == 2 && ReaderExtension.IsValue(parameters[i]))
                {
                    isrc.ISRCdcValue.Set(netlist.ParseDouble(parameters[i]));
                }

                // AC specification
                else if (parameters[i].image.ToLower() == "ac")
                {
                    i++;
                    isrc.ISRCacMag.Set(netlist.ParseDouble(parameters[i]));

                    // Look forward for one more value
                    if (i + 1 < parameters.Count && ReaderExtension.IsValue(parameters[i + 1]))
                    {
                        i++;
                        isrc.ISRCacPhase.Set(netlist.ParseDouble(parameters[i]));
                    }
                }

                // Waveforms
                else if (parameters[i].kind == BRACKET)
                {
                    // Find the reader
                    BracketToken bt = parameters[i] as BracketToken;
                    Statement    st = new Statement(StatementType.Waveform, bt.Name, bt.Parameters);
                    isrc.ISRCwaveform = (IWaveform)netlist.Readers.Read(st, netlist);
                }
                else
                {
                    throw new ParseException(parameters[i], "Unrecognized parameter");
                }
            }

            return(isrc);
        }
        /// <summary>
        /// Generate a CCCS
        /// </summary>
        /// <param name="name">Name</param>
        /// <param name="parameters">Parameters</param>
        /// <param name="netlist">Netlist</param>
        /// <returns></returns>
        protected ICircuitObject GenerateCCCS(CircuitIdentifier name, List <Token> parameters, Netlist netlist)
        {
            CurrentControlledCurrentsource cccs = new CurrentControlledCurrentsource(name);

            cccs.ReadNodes(netlist.Path, parameters);
            switch (parameters.Count)
            {
            case 2: throw new ParseException(parameters[1], "Voltage source expected", false);

            case 3: throw new ParseException(parameters[2], "Value expected", false);
            }

            if (!ReaderExtension.IsName(parameters[2]))
            {
                throw new ParseException(parameters[2], "Component name expected");
            }
            cccs.CCCScontName = new CircuitIdentifier(parameters[2].image);
            cccs.CCCScoeff.Set(netlist.ParseDouble(parameters[3]));
            return(cccs);
        }
Exemple #4
0
        /// <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)
        {
            // Only assignments are possible
            for (int i = 0; i < st.Parameters.Count; i++)
            {
                switch (st.Parameters[i].kind)
                {
                case ASSIGNMENT:
                    AssignmentToken at = st.Parameters[i] as AssignmentToken;
                    switch (at.Name.kind)
                    {
                    case BRACKET:
                        BracketToken bt = at.Name as BracketToken;
                        if (bt.Name.image.ToLower() == "v" && bt.Parameters.Length == 1 && ReaderExtension.IsNode(bt.Parameters[0]))
                        {
                            netlist.Circuit.Nodes.Nodeset.Add(new CircuitIdentifier(bt.Parameters[0].image), netlist.ParseDouble(at.Value));
                        }
                        else
                        {
                            throw new ParseException(st.Parameters[i], "Invalid format, v(<node>)=<ic> expected");
                        }
                        break;

                    default:
                        if (ReaderExtension.IsNode(at.Name))
                        {
                            netlist.Circuit.Nodes.Nodeset.Add(new CircuitIdentifier(at.Name.image), netlist.ParseDouble(at.Value));
                        }
                        else
                        {
                            throw new ParseException(st.Parameters[i], "Invalid format, <node>=<ic> expected");
                        }
                        break;
                    }
                    break;
                }
            }
            return(true);
        }
        /// <summary>
        /// Read subcircuit definitions
        /// </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)
        {
            if (st.Parameters.Count < 2)
            {
                throw new ParseException(st.Name, "Subcircuit name expected", false);
            }

            // Create the identifier of the subcircuit definition
            CircuitIdentifier name = new CircuitIdentifier(st.Parameters[0].image);

            if (netlist.Path.DefinitionPath != null)
            {
                name = netlist.Path.DefinitionPath.Grow(name);
            }

            // Extract the subcircuit definition statements
            StatementsToken      body       = (StatementsToken)st.Parameters[st.Parameters.Count - 1];
            SubcircuitDefinition definition = new SubcircuitDefinition(name, body);

            // Parse nodes and parameters
            bool mode = true; // true = nodes, false = parameters

            for (int i = 1; i < st.Parameters.Count - 1; i++)
            {
                if (mode)
                {
                    // After this, only parameters will follow
                    if (st.Parameters[i].image.ToLower() == "params:")
                    {
                        mode = false;
                    }

                    // Parameters have started, so we will keep reading parameters
                    else if (st.Parameters[i].kind == ASSIGNMENT)
                    {
                        mode = false;
                        AssignmentToken at = st.Parameters[i] as AssignmentToken;
                        definition.Defaults.Add(new CircuitIdentifier(at.Name.image), at.Value);
                    }

                    // Still reading nodes
                    else if (ReaderExtension.IsNode(st.Parameters[i]))
                    {
                        definition.Pins.Add(new CircuitIdentifier(st.Parameters[i].image));
                    }
                }
                else if (st.Parameters[i].kind == ASSIGNMENT)
                {
                    AssignmentToken at = st.Parameters[i] as AssignmentToken;
                    definition.Defaults.Add(new CircuitIdentifier(at.Name.image), at.Value);
                }
            }

            // Create a new subcircuit path
            SubcircuitPath orig = netlist.Path;

            netlist.Path = new SubcircuitPath(orig, definition);
            foreach (var s in definition.Body.Statements(StatementType.Subcircuit))
            {
                netlist.Readers.Read(s, netlist);
            }

            // Restore
            netlist.Path = orig;

            // Return values
            netlist.Definitions.Add(definition.Name, definition);
            Generated = definition;
            return(true);
        }
        /// <summary>
        /// Read
        /// </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)
        {
            // Initialize
            List <CircuitIdentifier> instancepins = new List <CircuitIdentifier>();
            Dictionary <CircuitIdentifier, Token> instanceparameters = new Dictionary <CircuitIdentifier, Token>();
            CircuitIdentifier definition = null;

            // Get the name
            CircuitIdentifier name;

            if (netlist.Path.InstancePath != null)
            {
                name = netlist.Path.InstancePath.Grow(st.Name.image);
            }
            else
            {
                name = new CircuitIdentifier(st.Name.image);
            }

            // Format: <NAME> <NODES>* <SUBCKT> <PAR1>=<VAL1> ...
            // Or: <NAME> <NODES>* <SUBCKT> params: <PAR1>=<VAL1> ...
            bool mode = true; // true = nodes, false = parameters

            for (int i = 0; i < st.Parameters.Count; i++)
            {
                // Reading nodes
                if (mode)
                {
                    if (ReaderExtension.IsNode(st.Parameters[i]))
                    {
                        instancepins.Add(definition = new CircuitIdentifier(st.Parameters[i].image));
                    }
                    else
                    {
                        instancepins.RemoveAt(instancepins.Count - 1);
                        mode = false;
                    }
                }

                // Reading parameters
                // Don't use ELSE! We still need to read the last parameter
                if (!mode)
                {
                    if (st.Parameters[i].kind == ASSIGNMENT)
                    {
                        AssignmentToken at = st.Parameters[i] as AssignmentToken;
                        switch (at.Name.kind)
                        {
                        case WORD:
                        case IDENTIFIER:
                            instanceparameters.Add(new CircuitIdentifier(at.Name.image), at.Value);
                            break;

                        default:
                            throw new ParseException(at.Name, "Parameter name expected");
                        }
                    }
                }
            }

            // If there are only node-like tokens, then the last one is the definition by default
            if (mode)
            {
                instancepins.RemoveAt(instancepins.Count - 1);
            }

            // Modify the instancepins to be local or use the nodemap
            for (int i = 0; i < instancepins.Count; i++)
            {
                if (netlist.Path.NodeMap.TryGetValue(instancepins[i], out CircuitIdentifier node))
                {
                    instancepins[i] = node;
                }
                else if (netlist.Path.InstancePath != null)
                {
                    instancepins[i] = netlist.Path.InstancePath.Grow(instancepins[i].Name);
                }
            }

            // Find the subcircuit definition
            if (netlist.Path.DefinitionPath != null)
            {
                definition = netlist.Path.DefinitionPath.Grow(definition);
            }
            SubcircuitDefinition subcktdef = netlist.Path.FindDefinition(netlist.Definitions, definition) ??
                                             throw new ParseException(st.Parameters[st.Parameters.Count - 1], "Cannot find subcircuit definition");
            Subcircuit subckt = new Subcircuit(subcktdef, name, instancepins, instanceparameters);

            SubcircuitPath orig = netlist.Path;

            netlist.Path = new SubcircuitPath(netlist, orig, subckt);

            // Read all control statements
            foreach (var s in subcktdef.Body.Statements(StatementType.Control))
            {
                netlist.Readers.Read(s, netlist);
            }

            // Read all model statements
            foreach (var s in subcktdef.Body.Statements(StatementType.Model))
            {
                netlist.Readers.Read(s, netlist);
            }

            // Read all component statements
            foreach (var s in subcktdef.Body.Statements(StatementType.Component))
            {
                netlist.Readers.Read(s, netlist);
            }

            // Restore
            netlist.Path = orig;
            Generated    = subckt;
            return(true);
        }