/// <summary> /// Constructor /// </summary> /// <param name="dev">The spice device</param> public SpiceDefinitions(SpiceDevice dev, SpiceSetup setup) { // Get the variable string var = setup.StatesVariable; string code; // Open the definitions file using (StreamReader sr = new StreamReader(Path.Combine(dev.Folder, dev.Def))) code = sr.ReadToEnd(); // Find all the states Dictionary <string, int> list = new Dictionary <string, int>(); Regex r = new Regex($@"#define\s*(?<name>\w+)\s*{setup.StatesVariable}\s*\+\s*(?<offset>\d+)"); var ms = r.Matches(code); int max = 0; foreach (Match m in ms) { int offset = Convert.ToInt32(m.Groups["offset"].Value); list.Add(m.Groups["name"].Value, offset); max = Math.Max(offset + 1, max); StateNames.Add(m.Groups["name"].Value); } // Store the ordered states States = new string[max]; foreach (var s in list) { States[s.Value] = s.Key; } }
/// <summary> /// Update methods /// </summary> /// <param name="ckt">The circuit</param> /// <param name="setup"></param> public void UpdateMethods(SpiceDevice dev, SpiceSetup setup, string ckt = "ckt") { // Get-set string[] keys = Declarations.Keys.ToArray(); foreach (var key in keys) { string code = Regex.Replace(Declarations[key], $@"get\s*\{{\s*value\s*\=\s*\w+\s*\-\>\s*(?<var>\w+)\s*;\s*\}}", (Match m) => $"get => {m.Groups["var"].Value};", RegexOptions.Multiline); Declarations[key] = code; } // Methods for (int i = 0; i < Methods.Count; i++) { string code = Regex.Replace(Methods[i], $@"\*\s*\(\s*{ckt}\s*\-\>\s*CKTstate(?<state>\d+)\s*\+\s*(?<node>\w+)\s*\)", (Match m) => $"ckt.State.States[{m.Groups["state"].Value}][{setup.StatesVariable} + {m.Groups["node"].Value}]"); code = Regex.Replace(code, dev.DeviceName + "_", "", RegexOptions.IgnoreCase); code = Regex.Replace(code, $@"\*\s*\(\s*{ckt}\s*\-\>\s*CKTrhsOld\s*\+\s*(?<node>\w+)\s*\)", (Match m) => $"ckt.State.Real.Solution[{m.Groups["node"].Value}]"); // If it just a simple setter, then use the shorthand notation Regex simpleset = new Regex(@"\s*\{\s*value\s*\=\s*(?<value>[^;]+);(\s*return\s*\(\s*OK\s*\)\s*;)?\s*\}\s*$"); code = simpleset.Replace(code, (Match m) => $" => {m.Groups["value"].Value};"); Methods[i] = code; } }
/// <summary> /// Main program /// </summary> /// <param name="args">Arguments</param> public static void Main(string[] args) { SpiceDevice dev = new SpiceDevice(); dev.Folder = @"D:\Visual Studio\Info\SpiceSharp\spice3f5\src\lib\dev\mes"; dev.ITF = @"mesitf.h"; dev.Def = @"mesdefs.h"; dev.Defined.AddRange(new string[] { "AN_pz", "AN_noise", "NOBYPASS", "NEWTRUNC", "NEWCONV", "PREDICTOR", "DEV_mes" }); // Generate SpiceClassGenerator scg = new SpiceClassGenerator(dev); scg.ExportModel("model.cs"); scg.ExportDevice("device.cs"); foreach (var msg in ConverterWarnings.Warnings) { Console.WriteLine("Warning: " + msg); } Console.WriteLine("Conversion finished"); Console.ReadKey(); }
/// <summary> /// Constructor /// </summary> /// <param name="dev">The device</param> public SpiceTemperature(SpiceDevice dev) { // Get the string content = dev.GetMethod(SpiceDevice.Methods.Temperature); ReadMethod(content); }
/// <summary> /// Constructor /// </summary> /// <param name="dev">Device</param> public SpiceTruncate(SpiceDevice dev, SpiceSetup setup) { string content = dev.GetMethod(SpiceDevice.Methods.Trunc); ReadMethod(content); // Copy the matrix nodes states = setup.StatesVariable; }
/// <summary> /// Extract the parameters /// </summary> /// <param name="dev">The spice device</param> public void Extract(SpiceDevice dev) { // Get the device parameters string param = dev.GetVariable("IFparm", dev.ParameterVariable); StoreParameters(param, Device); // Get the model parameters param = dev.GetVariable("IFparm", dev.ModelParameterVariable); StoreParameters(param, Model); }
/// <summary> /// Constructor /// </summary> /// <param name="dev">The Spice device</param> public SpiceAcLoad(SpiceDevice dev, SpiceSetup setup) { string content = dev.GetMethod(SpiceDevice.Methods.AcLoad); ReadMethod(content); // Copy the matrix nodes foreach (string n in setup.MatrixNodes.Keys) { matrixnodes.Add(n, setup.MatrixNodes[n]); } states = setup.StatesVariable; }
/// <summary> /// Constructor /// </summary> /// <param name="dev">The device</param> public SpiceSetup(SpiceDevice dev) { // Get the string content = dev.GetMethod(SpiceDevice.Methods.Setup); // Get the parameters List <string> p = new List <string>(); Code.GetMethodParameters(content, p, dev.GetMethodName(SpiceDevice.Methods.Setup)); states = p[3]; ReadMethod(content); }
/// <summary> /// Constructor /// </summary> /// <param name="dev">The device</param> public SpiceParam(SpiceDevice dev, Dictionary <string, ParameterExtractor.DeviceParameter> dp, SpiceDevice.Methods p, SpiceDevice.Methods a) { // Get the param method string content = dev.GetMethod(p); Code.GetSwitchCases(content, param); Code.GetMethodParameters(content, par_parameters, dev.GetMethodName(p)); // Get the "here" variable var m = Regex.Match(content, $@"(\w+)\s*\*\s*(?<var>\w+)\s*\=\s*\(\s*\1\s*\*\s*\)\s*{par_parameters[2]}"); if (m.Success) { par_here = m.Groups["var"].Value; } else { throw new Exception("Could not find 'here' parameter"); } par_value = par_parameters[1]; // Get the ask method content = dev.GetMethod(a); Code.GetSwitchCases(content, ask); Code.GetMethodParameters(content, ask_parameters, dev.GetMethodName(a)); // Get the "here" variable m = Regex.Match(content, $@"(\w+)\s*\*\s*(?<var>\w+)\s*\=\s*\(\s*\1\s*\*\s*\)\s*{ask_parameters[1]}"); if (m.Success) { ask_here = m.Groups["var"].Value; } else { throw new Exception("Could not find 'here' parameter"); } ask_value = ask_parameters[3]; BuildParameters(dp); }
/// <summary> /// Constructor /// </summary> /// <param name="dev">The spice device</param> public SpiceDefinitions(SpiceDevice dev, SpiceSetup setup) { // Get the variable string var = setup.StatesVariable; string code; Count = 0; // Open the definitions file using (StreamReader sr = new StreamReader(Path.Combine(dev.Folder, dev.Def))) code = sr.ReadToEnd(); // Find all the states Regex r = new Regex($@"#define\s*(?<name>\w+)\s*{setup.StatesVariable}\s*\+\s*(?<offset>\d+)"); var ms = r.Matches(code); foreach (Match m in ms) { int offset = Convert.ToInt32(m.Groups["offset"].Value); States.Add(new Tuple <int, string>(offset, m.Groups["name"].Value)); StateNames.Add(m.Groups["name"].Value); Count = Math.Max(Count, offset + 1); } }
/// <summary> /// Read a device /// </summary> /// <param name="dev"></param> public SpiceClassGenerator(SpiceDevice dev, Methods export = Methods.All) { // Get all model and device methods dev.BuildMethodTable(); name = dev.DeviceName.ToUpper(); // Extract the parameters paramExtr = new ParameterExtractor(); paramExtr.Extract(dev); // Get all parameters paramMod = new SpiceParam(dev, paramExtr.Model, SpiceDevice.Methods.ModelParam, SpiceDevice.Methods.ModelAsk); paramDev = new SpiceParam(dev, paramExtr.Device, SpiceDevice.Methods.Param, SpiceDevice.Methods.Ask); // Extract the setup if (export.HasFlag(Methods.Setup)) { setup = new SpiceSetup(dev); setupDev = setup.ExportDevice(paramMod, paramDev); setupMod = setup.ExportModel(paramMod); foreach (var v in setup.SharedLocalVariables) { shared.Add(v.Key, v.Value); } foreach (var v in setup.ModelVariablesExtra) { modelextra.Add(v); } foreach (var v in setup.DeviceVariablesExtra) { deviceextra.Add(v); } // Update the methods paramMod.UpdateMethods(dev, setup); paramDev.UpdateMethods(dev, setup); } // Extract the state definitions if (setup != null) { definitions = new SpiceDefinitions(dev, setup); foreach (var v in definitions.StateNames) { paramDev.Variables.Add(v); } } // Temperature-dependent calculations if (export.HasFlag(Methods.Temperature)) { temp = new SpiceTemperature(dev); tempDev = temp.ExportDevice(paramMod, paramDev); tempMod = temp.ExportModel(paramMod); foreach (var v in temp.SharedLocalVariables) { if (shared.ContainsKey(v.Key) && shared[v.Key] != v.Value) { throw new Exception($"Cannot share variable {v.Key}"); } shared.Add(v.Key, v.Value); } foreach (var v in temp.ModelVariablesExtra) { modelextra.Add(v); } foreach (var v in temp.DeviceVariablesExtra) { deviceextra.Add(v); } } // Loading if (export.HasFlag(Methods.Load) && setup != null) { load = new SpiceLoad(dev, setup); loadDev = load.ExportDevice(paramMod, paramDev); loadMod = load.ExportModel(paramMod); foreach (var v in load.SharedLocalVariables) { if (shared.ContainsKey(v.Key) && shared[v.Key] != v.Value) { throw new Exception($"Cannot share variable {v.Key}"); } shared.Add(v.Key, v.Value); } foreach (var v in load.ModelVariablesExtra) { modelextra.Add(v); } foreach (var v in load.DeviceVariablesExtra) { deviceextra.Add(v); } } // AC loading if (export.HasFlag(Methods.AcLoad) && setup != null) { acload = new SpiceAcLoad(dev, setup); acloadDev = acload.ExportDevice(paramMod, paramDev); acloadMod = acload.ExportModel(paramMod); foreach (var v in acload.SharedLocalVariables) { if (shared.ContainsKey(v.Key) && shared[v.Key] != v.Value) { throw new Exception($"Cannot share variable {v.Key}"); } shared.Add(v.Key, v.Value); } foreach (var v in acload.ModelVariablesExtra) { modelextra.Add(v); } foreach (var v in acload.DeviceVariablesExtra) { deviceextra.Add(v); } } // PZ loading if (export.HasFlag(Methods.PzLoad)) { pzload = new SpicePzLoad(dev, setup); pzloadDev = pzload.ExportDevice(paramMod, paramDev); pzloadMod = pzload.ExportModel(paramMod); foreach (var v in pzload.SharedLocalVariables) { if (shared.ContainsKey(v.Key) && shared[v.Key] != v.Value) { throw new Exception($"Cannot share variable {v.Key}"); } shared.Add(v.Key, v.Value); } foreach (var v in pzload.ModelVariablesExtra) { modelextra.Add(v); } foreach (var v in pzload.DeviceVariablesExtra) { deviceextra.Add(v); } } // Truncation if (export.HasFlag(Methods.Truncate)) { trunc = new SpiceTruncate(dev, setup); truncDev = trunc.ExportDevice(paramMod, paramDev); truncMod = trunc.ExportModel(paramMod); foreach (var v in trunc.SharedLocalVariables) { if (shared.ContainsKey(v.Key) && shared[v.Key] != v.Value) { throw new Exception($"Cannot share variable {v.Key}"); } shared.Add(v.Key, v.Value); } foreach (var v in trunc.ModelVariablesExtra) { modelextra.Add(v); } foreach (var v in trunc.DeviceVariablesExtra) { deviceextra.Add(v); } } // Apply default values! string[] names = paramMod.Declarations.Keys.ToArray(); foreach (string n in names) { // Find out if the name of the variable with this ID if (setup.ModelDefaultValues.ContainsKey(n)) { paramMod.Declarations[n] = Regex.Replace(paramMod.Declarations[n], @"\(\);", $"({setup.ModelDefaultValues[n]});"); } } names = paramDev.Declarations.Keys.ToArray(); foreach (string n in names) { // Find out if the name of the variable with this ID if (setup.DeviceDefaultValues.ContainsKey(n)) { paramDev.Declarations[n] = Regex.Replace(paramDev.Declarations[n], @"\(\);", $"({setup.DeviceDefaultValues[n]});"); } } }