private string GenerateCommandArgs(TestBench Testbench_obj) { string commandArgs = ""; var icg = Testbench_obj.Parameters.FirstOrDefault(p => p.Name.Equals("interChipSpace")); // in mm var eg = Testbench_obj.Parameters.FirstOrDefault(p => p.Name.Equals("boardEdgeSpace")); // in mm var maxRetries = Testbench_obj.Parameters.FirstOrDefault(p => p.Name.Equals("maxRetries")); var maxThreads = Testbench_obj.Parameters.FirstOrDefault(p => p.Name.Equals("maxThreads")); // MOT-729 if (Testbench_obj.Impl.Children.ComponentAssemblyCollection.Where(ca => string.IsNullOrEmpty(((GME.MGA.IMgaFCO)ca.Impl).RegistryValue["layoutFile"]) == false).Count() > 0) { // there is a layoutFile for the SUT. The layout.json takes up the whole board commandArgs += " -e 0 -i 0"; } else { if (icg != null) { commandArgs += " -i " + icg.Value; } if (eg != null) { commandArgs += " -e " + eg.Value; } } if (maxRetries != null) { commandArgs += " -s " + maxRetries.Value; } if (maxThreads != null) { commandArgs += " -t " + maxThreads.Value; // MOT-729 } return(commandArgs); }
public override void visit(TestBench obj) { // Create a sheet for the testbench var sheet_obj = new Eagle.sheet(); schematic_obj.sheets.sheet.Add(sheet_obj); }
private void CommonTraversal(TestBench TestBench_obj) { // 1. A first traversal maps CyPhy objects to a corresponding but significantly lighter weight object network that only includes a // small set of concepts/classes : TestBench, ComponentAssembly, Component, Parameter, Port, Connection // 2. Second and third traversal passes compute the layout of the graph in schematic // 3. Forth traversal wires the object network // the object network is hierarchical, but the wiring is direct and skips hierarchy. The dependency on CyPhy is largely localized to the // traversal/visitor code (CyPhyVisitors.cs) TestBench_obj.accept(new CyPhyBuildVisitor(this.mainParameters.ProjectDirectory, this.mode, Traceability, mgaIdToDomainIDs, selectedSpiceModels) { Logger = Logger }); if (mode == Mode.EDA) { TestBench_obj.accept(new CyPhyLayoutVisitor() { Logger = Logger }); TestBench_obj.accept(new CyPhyLayout2Visitor() { Logger = Logger }); } TestBench_obj.accept(new CyPhyConnectVisitor(this.mode) { Logger = Logger }); }
private List <Component> CollectGroundNodes(TestBench obj) { var gnds = obj.TestComponents.Where(t => Grounds.Any(GetSpiceType(t).Item2.Contains) ).ToList(); var cgnds = obj.ComponentAssemblies.SelectMany(ca => CollectGroundNodes(ca)).ToList(); return(gnds.Union(cgnds).ToList()); }
private void CopyResourceFromTestBench(TestBench Testbench_obj, string param, string destFileName = null) { var par = Testbench_obj.Parameters.Where(p => p.Name.Equals(param)).FirstOrDefault(); if (par == null) { return; } if (String.IsNullOrWhiteSpace(destFileName)) { destFileName = Path.GetFileName(par.Value); } String pathSrcFile = Path.Combine(Testbench_obj.Impl.Impl.Project.GetRootDirectoryPath(), par.Value); try { CopyFile(par.Value, destFileName); } catch (FileNotFoundException) { Logger.WriteError("This test bench specifies a {0} file, {1}, that cannot be found.", param, par.Value); throw; } catch (DirectoryNotFoundException) { // If the directory of the source file doesn't exist, throw this error. if (!Directory.Exists(Path.Combine(this.mainParameters.ProjectDirectory, Path.GetDirectoryName(par.Value)))) { Logger.WriteError("This test bench specifies a {0} file, {1}, that cannot be found.", param, par.Value); throw; } else { // The destination directory must not exist. Logger.WriteError("The output directory, {0}, does not exist.", this.mainParameters.OutputDirectory); throw; } } }
private void GenerateReferenceDesignatorMappingTable(TestBench Testbench_obj) { using (var sw = new StreamWriter(Path.Combine(this.mainParameters.OutputDirectory, "reference_designator_mapping_table.html"))) { // Get all nested assemblies using an interative approach. var assemblies = new List <ComponentAssembly>(); assemblies.AddRange(Testbench_obj.ComponentAssemblies); for (int i = 0; i < assemblies.Count; i++) { var assembly = assemblies[i]; assemblies.AddRange(assembly.ComponentAssemblyInstances); } // Get all instances from everywhere. var componentInstances = assemblies.SelectMany(a => a.ComponentInstances).ToList(); componentInstances.AddRange(Testbench_obj.TestComponents); // Build mapping table List <XrefItem> xrefTable = new List <XrefItem>(); foreach (var ci in componentInstances) { String path = ci.Impl.Path; String refDes = ci.Name; XrefItem row = new XrefItem() { ReferenceDesignator = refDes, GmePath = path }; xrefTable.Add(row); } // Convert it to HTML string html = Xref2Html.makeHtmlFile( "", xrefTable, ""); // Write mapping table to file sw.Write(html); } }
private Eagle.eagle GenerateSchematicCode(TestBench TestBench_obj) { // load schematic library Eagle.eagle eagle = null; try { eagle = Eagle.eagle.Deserialize(CyPhy2Schematic.Properties.Resources.schematicTemplate); Logger.WriteInfo("Parsed Eagle Library schema version: " + eagle.version); } catch (Exception e) { eagle = new Eagle.eagle(); // create an empty eagle object network Logger.WriteError("Error parsing XML: " + e.Message + "<br>Inner: " + e.InnerException + "<br>Stack: " + e.StackTrace); } // 2. The second traversal walks the lighter weight (largely CyPhy independent) object network and maps to the eagle XML object network // the classes of this object network are automatically derived from the eagle XSD using the XSD2Code tool in the META repo // an important step of this traversal is the routing which is implemented currently as a simple rats nest routing, // the traversal and visitor code is localized in (SchematicTraversal.cs) TestBench_obj.accept(new EdaVisitor(this) { eagle_obj = eagle, Logger = Logger }); // 2.5 Finally a serializer (XSD generated code), walks the object network and generates the XML file System.IO.Directory.CreateDirectory(this.mainParameters.OutputDirectory); String outFile = Path.Combine(this.mainParameters.OutputDirectory, "schema.sch"); try { eagle.SaveToFile(outFile); } catch (Exception ex) { Logger.WriteError("Error Saving Schema File: {0}<br> Exception: {1}<br> Trace: {2}", outFile, ex.Message, ex.StackTrace); } return(eagle); }
public override void visit(TestBench obj) { if (obj.SolverParameters.ContainsKey("SpiceAnalysis")) { circuit_obj.analysis = obj.SolverParameters["SpiceAnalysis"]; } var tracesParam = obj.Parameters.Where(p => p.Name.Equals("Traces")).FirstOrDefault(); if (tracesParam != null) { SigIntegrityTraces = tracesParam.Value.Split(new char[] { ' ', ',' }); } // process all ground nets first before they get assigned another number var gnds = CollectGroundNodes(obj); var gports = gnds.SelectMany(g => g.Ports).ToList(); foreach (var gp in gports) { visit(gp, "0"); } }
private void GenerateSpiceCommandFile(TestBench Testbench_obj) { var spiceBat = new StreamWriter(Path.Combine(this.mainParameters.OutputDirectory, "runspice.bat")); spiceBat.Write(CyPhy2Schematic.Properties.Resources.runspice); // find a voltage source test component var voltageSrc = Testbench_obj.Impl.Children .TestComponentCollection .FirstOrDefault(c => c.Children.SPICEModelCollection .Select(x => x.Attributes.Class) .Contains("V")); if (voltageSrc != null) { // add a call to spice post process spiceBat.Write("if exist \"schema.raw\" (\n"); spiceBat.Write("\t\"%META_PATH%\\bin\\python27\\scripts\\python.exe\" -E -m SpiceVisualizer.post_process -m {0} schema.raw\n", voltageSrc.Name); spiceBat.Write(")\n"); } spiceBat.Close(); }
private void CopyBoardFilesSpecifiedInPcbComponent(TestBench tb_obj) { // Look to see if there is a PCB component in the top level assembly var compImpl = tb_obj.ComponentAssemblies .SelectMany(c => c.ComponentInstances) .Select(i => i.Impl) .FirstOrDefault(j => (j as Tonka.Component).Attributes .Classifications .Contains("pcb_board") || (j as Tonka.Component).Attributes .Classifications .Contains("template.pcb_template")); var comp = (compImpl != null) ? compImpl as Tonka.Component : null; if (comp == null) { return; } CopyResourceFromComp(comp, "boardTemplate"); CopyResourceFromComp(comp, "designRules"); CopyResourceFromComp(comp, "autoRouterConfig", "autoroute.ctl"); }
private void GenerateSpiceCode(TestBench TestBench_obj) { var circuit = new Spice.Circuit() { name = TestBench_obj.Name }; var siginfo = new Spice.SignalContainer() { name = TestBench_obj.Name, objectToNetId = new Dictionary <CyPhy2SchematicInterpreter.IDs, string>() }; // now traverse the object network with Spice Visitor to build the spice and siginfo object network TestBench_obj.accept(new SpiceVisitor(Traceability, mgaIdToDomainIDs, this) { circuit_obj = circuit, siginfo_obj = siginfo, mode = this.mode }); String spiceTemplateFile = Path.Combine(this.mainParameters.OutputDirectory, "schema.cir.template"); circuit.Serialize(spiceTemplateFile); String siginfoFile = Path.Combine(this.mainParameters.OutputDirectory, "siginfo.json"); siginfo.Serialize(siginfoFile); }
public override void visit(TestBench obj) { Logger.WriteDebug("CyPhyBuildVisitor::visit({0})", obj.Impl.Path); var testBench = obj.Impl; var ca = testBench.Children.ComponentAssemblyCollection.FirstOrDefault(); if (ca == null) { Logger.WriteFailed("No valid component assembly in testbench {0}", obj.Name); return; } var componentAssembly_obj = new ComponentAssembly(ca); obj.ComponentAssemblies.Add(componentAssembly_obj); this.systemUnderTest = componentAssembly_obj.SystemUnderTest = componentAssembly_obj; componentAssembly_obj.selectedSpiceModels = selectedSpiceModels; var tcs = testBench.Children.TestComponentCollection; foreach (var tc in tcs) { var component_obj = new Component(tc); component_obj.SystemUnderTest = this.systemUnderTest; obj.TestComponents.Add(component_obj); CyPhyBuildVisitor.Components.Add(tc.ID, component_obj); // Add to global component list, are these instance ID-s or component type ID-s? } foreach (var param in testBench.Children.ParameterCollection) { var param_obj = new Parameter() { Name = param.Name, Value = param.Attributes.Value }; obj.Parameters.Add(param_obj); } // solver parameters - currently using Dymola Solver object var solver = testBench.Children.SolverSettingsCollection.FirstOrDefault(); if (solver != null) { obj.SolverParameters.Add("SpiceAnalysis", solver.Attributes.ToolSpecificAnnotations); } Dictionary <string, string> properties = testBench.Children.PropertyCollection.ToDictionary(param => param.Name, param => param.Attributes.Value); string spiceAnalysisType; if (properties.TryGetValue("Spice Analysis Type", out spiceAnalysisType)) { if (spiceAnalysisType == "Transient Analysis") { string stepSize = "0.0001"; properties.TryGetValue("Spice Step Size", out stepSize); string endTime = "1"; properties.TryGetValue("Spice End Time", out endTime); string startTime = "0"; properties.TryGetValue("Spice Start Time", out startTime); obj.SolverParameters["SpiceAnalysis"] = String.Format(".TRAN {0} {1} {2}", stepSize, endTime, startTime); } else { throw new ApplicationException(string.Format("Unsupported Spice Analysis Type '{0}'", spiceAnalysisType)); } } }
public Result GenerateCode() { Result result = new Result(); // map the root testbench obj var testbench = TonkaClasses.TestBench.Cast(this.mainParameters.CurrentFCO); if (testbench == null) { Logger.WriteError("Invalid context of invocation <{0}>, invoke the interpreter from a Testbench model", this.mainParameters.CurrentFCO.Name); return(result); } var TestBench_obj = new TestBench(testbench); BasePath = testbench.Path; CommonTraversal(TestBench_obj); GenerateReferenceDesignatorMappingTable(TestBench_obj); switch (mode) { case Mode.EDA: var eagleSch = GenerateSchematicCode(TestBench_obj); CopyBoardFilesSpecifiedInPcbComponent(TestBench_obj); CopyBoardFilesSpecifiedInTestBench(TestBench_obj); // copy DRU/board template file if the testbench has it specified GenerateLayoutCodeResult glcResult = GenerateLayoutCode(eagleSch, TestBench_obj); // MOT-782 result.bonesFound = glcResult.bonesFound; var layout = glcResult.boardLayout; GenerateChipFitCommandFile(); GenerateShowChipFitResultsCommandFile(); GeneratePlacementCommandFile(); GeneratePlaceOnlyCommandFile(); GenerateLayoutReimportFiles(layout); result.runCommandArgs = GenerateCommandArgs(TestBench_obj); break; case Mode.SPICE_SI: // parse and map the nets to ports signalIntegrityLayout = new Layout.LayoutParser("layout.json", Logger, this) { mode = this.mode }; signalIntegrityLayout.BuildMaps(); // spice code generator uses the mapped traces // to generate subcircuits for traces and inserts them appropriately GenerateSpiceCode(TestBench_obj); GenerateSpiceCommandFile(TestBench_obj); break; case Mode.SPICE: GeneratePopulateTemplateScriptFile(); GenerateSpiceCode(TestBench_obj); GenerateSpiceCommandFile(TestBench_obj); GenerateSpiceViewerLauncher(); break; default: throw new NotSupportedException(String.Format("Mode {0} is not supported", mode.ToString())); } return(result); }
private void CopyBoardFilesSpecifiedInTestBench(TestBench Testbench_obj) { CopyResourceFromTestBench(Testbench_obj, "designRules"); CopyResourceFromTestBench(Testbench_obj, "boardTemplate"); CopyResourceFromTestBench(Testbench_obj, "autorouterConfig", "autoroute.ctl"); }
public virtual void upVisit(TestBench obj) { }