Пример #1
0
        private void GenerateSpice(DesignEntity de, Tonka.SPICEModel spiceObj)
        {
            var ancestor = de.Parent;

            while (ancestor != null)
            {
                if (ComponentNodeMap.ContainsKey(ancestor))
                {
                    return;
                }
                ancestor = ancestor.Parent;
            }

            var nodes     = circuit_obj.nodes;
            var spiceType = GetSpiceType(de);

            if (Grounds.Any(spiceType.Item2.Contains))  // is a ground node skip it
            {
                return;
            }

            var node = new Spice.Node();

            node.name      = de.Name;
            node.type      = spiceType.Item1;
            node.classType = spiceType.Item2;

            // error checking
            if (node.type == (char)0)
            {
                CodeGenerator.Logger.WriteWarning("Missing Spice Type for component {0}", de.Name);
            }
            if (node.type == 'X' && node.classType == "")
            {
                CodeGenerator.Logger.WriteWarning("Missing Subcircuit Type for component {0}, should be X.<subckt-type>", de.Name);
            }

            if (node.classType != "" && !circuit_obj.subcircuits.ContainsKey(node.classType))
            {
                circuit_obj.subcircuits.Add(node.classType, de.SpiceLib);
            }

            foreach (var par in spiceObj.Children.SPICEModelParameterCollection)
            {
                if (node.parameters.ContainsKey(par.Name))
                {
                    CodeGenerator.Logger.WriteError("Duplicate Parameter: {0}: in Component <a href=\"mga:{2}\">{1}</a>",
                                                    par.Name,
                                                    de.Name,
                                                    de.Impl.ID);
                }
                else
                {
                    node.parameters.Add(par.Name, FindTestBenchParameter(par) ?? par.Attributes.Value.Replace("$", "$$"));
                }
            }

            nodes.Add(node);
            ComponentNodeMap[de] = node;
        }
        public override void visit(Port obj)
        {
            CodeGenerator.Logger.WriteDebug(
                    "SpiceVisitor::visit({0}, dest connections: {1})",
                    obj.Name, obj.DstConnections.Count);

            if (!ComponentNodeMap.ContainsKey(obj.Parent)) // parent is a ground node
            {
                return;
            }

            var parentNode = ComponentNodeMap[obj.Parent];  // parent node
            var siginfo_parent = this.siginfo_obj;
            if (ObjectSiginfoMap.ContainsKey(obj.Parent))
            {
                siginfo_parent = ObjectSiginfoMap[obj.Parent] as Spice.SignalContainer;
            }

            int index = 0;
            try
            {
                index = obj.Impl.Attributes.SPICEPortNumber;
                if (index >= 0 && parentNode.nets.ContainsKey(index))
                {
                    CodeGenerator.Logger.WriteError("Duplicate SPICE Port Number: {0}: for Port <a href=\"mga:{2}\">{1}</a>",
                        index, obj.Name, obj.Impl.ID);
                    return;
                }
            }
            catch (System.FormatException ex)
            {
                index = -1;     // missing index
                CodeGenerator.Logger.WriteWarning("Invalid SPICE Port Number: {0}: for Port: <a href=\"mga:{2}\">{1}</a>",
                                                  obj.Impl.Attributes.SPICEPortNumber,
                                                  obj.Name, obj.Impl.ID);
            }

            if (PortNetMap.ContainsKey(obj))// port already mapped to a net object - no need to visit further
            {
                if (index >= 0) parentNode.nets.Add(index, PortNetMap[obj]);
                // spice signal info
                var siginfo_obj = new Spice.Signal()
                {
                    name = obj.Name,
                    gmeid = obj.Impl.ID,
                    spicePort = obj.Impl.Attributes.SPICEPortNumber,
                    net = PortNetMap[obj]
                };
                siginfo_parent.signals.Add(siginfo_obj);

                return;
            }

            // create a new net, 
            string net_obj = string.Format("{0}", ++netCount);
            if (!parentNode.nets.ContainsKey(index))
            {
                if (index >= 0) parentNode.nets.Add(index, net_obj);
                // spice signal info
                var siginfo_obj = new Spice.Signal()
                {
                    name = obj.Name,
                    gmeid = obj.Impl.ID,
                    spicePort = obj.Impl.Attributes.SPICEPortNumber,
                    net = net_obj
                };
                siginfo_parent.signals.Add(siginfo_obj);
            }
            else
            {
                CodeGenerator.Logger.WriteWarning("Invalid SpiceOrder attribute for schematic port: <a href=\"mga:{0}\">{1}</a>",
                                                  obj.Impl.ID,
                                                  obj.Name);
            }

            // if we are in the signal integrity mode and the port has an associated parsed trace
            if (mode == CodeGenerator.Mode.SPICE_SI && 
                CodeGenerator.signalIntegrityLayout.portTraceMap.ContainsKey(obj))
            {
                var trace = CodeGenerator.signalIntegrityLayout.portTraceMap[obj];
                if (SigIntegrityTraces.Contains(trace.name))
                {
                    CodeGenerator.Logger.WriteInfo("Generating Trace Subcircuit for {0} on Port {1}.{2}", trace.name, obj.Parent.Name, obj.Name);
                    // insert a subckt to model a trace
                    var traceNode = new Spice.Node();
                    traceNode.name = trace.name;
                    traceNode.type = 'X';
                    traceNode.classType = string.Format("Trace_{0}", trace.name);
                    traceNode.nets.Add(0, net_obj);
                    // create a new net to replace the original net and carry that wire further
                    net_obj = string.Format("{0}", ++netCount);
                    traceNode.nets.Add(1, net_obj);
                    circuit_obj.nodes.Add(traceNode);
                    // generate the subckt
                    GenerateTraceSubckt(trace);
                }
            }
            else if (CodeGenerator.verbose)
                CodeGenerator.Logger.WriteWarning("Port {0} has no Trace", obj.Impl.Path); 



            // assign to all connected ports - some nets may not have any connection
            visit(obj, net_obj);
        }
        public override void visit(Component obj)
        {
            CodeGenerator.Logger.WriteDebug(
                    "SpiceVisitor::visit({0})",
                    obj.Name);

            // create a signal container for this component
            var siginfo_obj = new Spice.SignalContainer()
            {
                name = obj.Name,
                gmeid = obj.Impl.ID
            };
            ObjectSiginfoMap.Add(obj, siginfo_obj);
            var siginfo_parent = this.siginfo_obj;
            if (obj.Parent != null && ObjectSiginfoMap.ContainsKey(obj.Parent))
            {
                siginfo_parent = ObjectSiginfoMap[obj.Parent] as Spice.SignalContainer;
            }
            siginfo_parent.signals.Add(siginfo_obj);

            var nodes = circuit_obj.nodes;
            var spiceObj = obj.Impl.Children.SPICEModelCollection.FirstOrDefault();
            if (spiceObj == null) // no spice model in this component, skip from generating 
            {
                return;
            }

            var spiceType = GetSpiceType(obj);

            if (Grounds.Any(spiceType.Item2.Contains))  // is a ground node skip it
            {
                return;
            }

            var node = new Spice.Node();
            node.name = obj.Name;
            node.type = spiceType.Item1;
            node.classType = spiceType.Item2;

            // error checking 
            if (node.type == (char)0)
            {
                CodeGenerator.Logger.WriteWarning("Missing Spice Type for component {0}", obj.Name);
            }
            if (node.type == 'X' && node.classType == "")
            {
                CodeGenerator.Logger.WriteWarning("Missing Subcircuit Type for component {0}, should be X.<subckt-type>", obj.Name);
            }

            if (node.classType != "" && !circuit_obj.subcircuits.ContainsKey(node.classType))
            {
                circuit_obj.subcircuits.Add(node.classType, obj.SpiceLib);
            }

            foreach (var par in spiceObj.Children.SPICEModelParameterCollection)
            {
                if (node.parameters.ContainsKey(par.Name))
                {
                    CodeGenerator.Logger.WriteError("Duplicate Parameter: {0}: in Component <a href=\"mga:{2}\">{1}</a>",
                        par.Name,
                        obj.Name,
                        obj.Impl.ID);
                }
                else
                {
                    node.parameters.Add(par.Name, par.Attributes.Value);
                }
            }

            nodes.Add(node);
            ComponentNodeMap[obj] = node;
        }
Пример #4
0
        public override void visit(Port obj)
        {
            CodeGenerator.Logger.WriteDebug(
                "SpiceVisitor::visit({0}, dest connections: {1})",
                obj.Name, obj.DstConnections.Count);

            if (!ComponentNodeMap.ContainsKey(obj.Parent)) // parent is a ground node
            {
                return;
            }

            var parentNode     = ComponentNodeMap[obj.Parent]; // parent node
            var siginfo_parent = this.siginfo_obj;

            if (ObjectSiginfoMap.ContainsKey(obj.Parent))
            {
                siginfo_parent = ObjectSiginfoMap[obj.Parent] as Spice.SignalContainer;
            }

            int index = 0;

            try
            {
                index = obj.Impl.Attributes.SPICEPortNumber;
                if (index >= 0 && parentNode.nets.ContainsKey(index))
                {
                    CodeGenerator.Logger.WriteError("Duplicate SPICE Port Number: {0}: for Port <a href=\"mga:{2}\">{1}</a>",
                                                    index, obj.Name, obj.Impl.ID);
                    return;
                }
            }
            catch (System.FormatException ex)
            {
                index = -1;     // missing index
                CodeGenerator.Logger.WriteWarning("Invalid SPICE Port Number: {0}: for Port: <a href=\"mga:{2}\">{1}</a>",
                                                  obj.Impl.Attributes.SPICEPortNumber,
                                                  obj.Name, obj.Impl.ID);
            }

            if (PortNetMap.ContainsKey(obj))// port already mapped to a net object - no need to visit further
            {
                if (index >= 0)
                {
                    parentNode.nets.Add(index, PortNetMap[obj]);
                }
                // spice signal info
                var siginfo_obj = new Spice.Signal()
                {
                    name      = obj.Name,
                    gmeid     = obj.Impl.ID,
                    spicePort = obj.Impl.Attributes.SPICEPortNumber,
                    net       = PortNetMap[obj]
                };
                siginfo_parent.signals.Add(siginfo_obj);

                return;
            }

            // create a new net,
            string net_obj = string.Format("{0}", ++netCount);

            if (!parentNode.nets.ContainsKey(index))
            {
                if (index >= 0)
                {
                    parentNode.nets.Add(index, net_obj);
                }
                // spice signal info
                var siginfo_obj = new Spice.Signal()
                {
                    name      = obj.Name,
                    gmeid     = obj.Impl.ID,
                    spicePort = obj.Impl.Attributes.SPICEPortNumber,
                    net       = net_obj
                };
                siginfo_parent.signals.Add(siginfo_obj);

                AddNetToSiginfoTraceability(obj, net_obj);
            }
            else
            {
                CodeGenerator.Logger.WriteWarning("Invalid SpiceOrder attribute for schematic port: <a href=\"mga:{0}\">{1}</a>",
                                                  obj.Impl.ID,
                                                  obj.Name);
            }

            // if we are in the signal integrity mode and the port has an associated parsed trace
            if (mode == CodeGenerator.Mode.SPICE_SI &&
                CodeGenerator.signalIntegrityLayout.portTraceMap.ContainsKey(obj))
            {
                var trace = CodeGenerator.signalIntegrityLayout.portTraceMap[obj];
                if (SigIntegrityTraces.Contains(trace.name))
                {
                    CodeGenerator.Logger.WriteInfo("Generating Trace Subcircuit for {0} on Port {1}.{2}", trace.name, obj.Parent.Name, obj.Name);
                    // insert a subckt to model a trace
                    var traceNode = new Spice.Node();
                    traceNode.name      = trace.name;
                    traceNode.type      = 'X';
                    traceNode.classType = string.Format("Trace_{0}", trace.name);
                    traceNode.nets.Add(0, net_obj);
                    // create a new net to replace the original net and carry that wire further
                    net_obj = string.Format("{0}", ++netCount);
                    traceNode.nets.Add(1, net_obj);
                    circuit_obj.nodes.Add(traceNode);
                    // generate the subckt
                    GenerateTraceSubckt(trace);
                }
            }
            else if (CodeGenerator.verbose)
            {
                CodeGenerator.Logger.WriteWarning("Port {0} has no Trace", obj.Impl.Path);
            }



            // assign to all connected ports - some nets may not have any connection
            visit(obj, net_obj);
        }