internal override void RemoveListener(SignalBase c) { if (c is SignalCollection <bool> ) { c.Changed -= delegate { this.Value = Convert(((SignalCollection <bool>)c).Read()); }; } else { base.AddListener(c); } }
/// <summary> /// Disconnect this signal from another signal /// </summary> /// <param name="c">Signal to remove</param> public void DisConnect(SignalBase c) { if (left.Contains(c)) { left.Remove(c); } if (c.right.Contains(this)) { c.right.Remove(c); } RemoveListener(c); }
/// <summary> /// Add a listener /// </summary> /// <param name="c"></param> internal override void AddListener(SignalBase c) { //Cast c SignalCollection <T> sc = c as SignalCollection <T>; //Add listeners between the signals for (int i = 0; i < signals.Count; i++) { if (i < sc.signals.Count) { signals[i].AddListener(sc.signals[i]); } } }
/// <summary> /// Writes definitions of the signals to be recorded /// </summary> /// <param name="cs">Signals</param> public void WriteNames(List <SystemDotNet.SignalBase> cs) { i1 = i2 = i3 = 0; filewriter.WriteLine("$scope module SystemDotNet $end"); for (int i = 0; i < cs.Count; i++) { SignalBase c = cs[i]; if (c is Signal <bool> ) { filewriter.WriteLine("$var wire 1 " + GetLabel() + " " + c.FullName + " $end"); } else if (c is BitVectorUnsigned) { BitVectorUnsigned bvu = (BitVectorUnsigned)c; filewriter.WriteLine("$var reg " + bvu.Bits + " " + GetLabel() + " " + c.FullName + " [" + (bvu.Bits - 1) + ": 0 ] $end"); } else if (c is SignalCollection <bool> ) { SignalCollection <bool> sc = c as SignalCollection <bool>; for (int j = 0; j < sc.Count; j++) { filewriter.WriteLine("$var reg " + sc.Count + " " + GetLabel() + " " + c.FullName + "(" + j + ")" + " [" + (sc.Count - 1) + ": 0 ] $end"); } } else if (c is SignalCollection <double> ) { SignalCollection <double> sc = c as SignalCollection <double>; for (int j = 0; j < sc.Count; j++) { filewriter.WriteLine("$var real 1 " + GetLabel() + " " + sc.FullName + "(" + j + ")" + " $end"); } } else if (c is SignalCollection <ulong> ) { SignalCollection <ulong> sc = c as SignalCollection <ulong>; filewriter.WriteLine("$var reg " + sc.Count + " " + GetLabel() + " " + c.FullName + " [" + (sc.Count - 1) + ": 0 ] $end"); } else { filewriter.WriteLine("$var real 1 " + GetLabel() + " " + c.FullName + " $end"); } } filewriter.WriteLine(); filewriter.WriteLine("$upscope $end"); filewriter.WriteLine("$enddefinitions $end"); filewriter.WriteLine(); }
/// <summary> /// Connects this signal to another signal /// </summary> /// <param name="c">Signal that this signal should listen too</param> public void Connect(SignalBase c) { if (c == null) { throw new ArgumentException(this.GetType() + ": Cannot connect,SignalBase is null"); } bool inheritanceok = false; if (c.GetType().IsSubclassOf(this.GetType()) || this.GetType().IsSubclassOf(c.GetType())) { inheritanceok = true; } bool typeok = false; foreach (Type t in AllowedTypes) { if (t.Equals(c.GetType())) { typeok = true; } } if (c.GetType() != this.GetType() && (!inheritanceok && !typeok)) { throw new ArgumentException("SignalBase " + c.FullName + " is of type " + c.GetType().ToString() + " while I'm " + this.GetType()); } if (c == this) { throw new Exception("You're trying to connect a channel to itself, that is not allowed! " + c.GetType()); } if (!left.Contains(c)) { left.Add(c); } if (!c.right.Contains(this)) { c.right.Add(this); } AddListener(c); }
/// <summary> /// Determines if this object is equal to another object. Uses the UniqueID to determine this. /// </summary> /// <param name="obj"></param> /// <returns></returns> public override bool Equals(object obj) { if (!(obj is SignalBase)) { return(false); } else { SignalBase b = (SignalBase)obj; if (b.UniqueID.Equals(this.UniqueID)) { return(true); } else { return(false); } } }
/// <summary> /// Remove listener for a signal /// </summary> /// <param name="c"></param> internal abstract void RemoveListener(SignalBase c);
/// <summary> /// Add listener for a signal /// </summary> /// <param name="c"></param> internal abstract void AddListener(SignalBase c);
/// <summary> /// Initializes the module. Loads all modules and signals /// </summary> /// <returns></returns> public void Initialize() { //Instance of the simulator Simulator sim = Simulator.GetInstance(); //Used for errors, false if errors bool ok = true; if (Parent != null) { Parent.Children.Add(this); this.name = Parent.Name + "." + this.name; int i = 0; foreach (ModuleBase mb in Parent.Children) { if (mb.name.StartsWith(this.name)) { i++; } } this.name += i.ToString(); } //Initialize arrays sigs = new List <SignalBase>(); //Add handler for simulator first step sim.FirstStep += new EmptyHandler(First); //Add handler for simulator before stop sim.OnStop += new EmptyHandler(OnStop); //Add handler for simulator after loading sim.Load += new EmptyHandler(OnLoad); //Add module to simulator // sim.AddModule(this); //Holder for signals found Dictionary <string, SignalBase> signals = new Dictionary <string, SignalBase>(); //All fields in this class FieldInfo[] fis = this.GetType().GetFields(); //Find all signals in this module and store them foreach (FieldInfo fi in fis) { Type t = fi.FieldType; //Check if the type is a subclass of Signalbase if (t.IsSubclassOf(typeof(SignalBase))) { //Get the value of the filed object o = this.GetType().InvokeMember(fi.Name, BindingFlags.GetField, null, this, new object[] { }); //If the value is null there is something if (o == null) { sim.SendError(this.GetType() + ": Connection Error: " + fi.Name + " has no instance."); ok = false; continue; } //Cast to signalBase SignalBase c = (SignalBase)o; //Sets the fullname of the signal if (this.Name == null) { c.FullName = fi.Name; } else { c.FullName = this.Name + "." + fi.Name; } //Sets the name of the signal c.Name = fi.Name; //Adds the signal to the module Signals.Add(c); //Stores the signals signals.Add(fi.Name, c); } } //Find all signals that are properties and store them PropertyInfo[] pis = this.GetType().GetProperties(); foreach (PropertyInfo pi in pis) { Type t = pi.PropertyType; //Check if the type is a subclass of Signalbase if (t.IsSubclassOf(typeof(SignalBase))) { //Get the value of the filed object o = pi.GetValue(this, new object[] { }); //If the value is null there is something if (o == null) { sim.SendError(this.GetType() + ": Connection Error: " + pi.Name + " has no instance."); ok = false; continue; } //Cast to signalBase SignalBase c = (SignalBase)o; if (Signals.Contains(c)) { continue; } //Sets the fullname of the signal if (this.Name == null) { c.FullName = pi.Name; } else { c.FullName = this.Name + "." + pi.Name; } //Sets the name of the signal c.Name = pi.Name; //Adds the signal to the module Signals.Add(c); //Stores the signals signals.Add(pi.Name, c); } } //Get all methods MethodInfo[] mis = this.GetType().GetMethods(); //EmptyHandler eh; ProcessWorker pw; foreach (MethodInfo mi in mis) { object[] o = mi.GetCustomAttributes(typeof(ProcessAttribute), true); //If the method uses the process attribute if (o.Length > 0) { //Run through all sensitive attributes foreach (ProcessAttribute sa in o) { //Run through all signal names in process attribute foreach (string name in sa.SignalNames) { if (signals.ContainsKey(name)) { //If the method is sensitive to the signal add it to the signals list of methods to run signals[name].SensType = sa.SensType; //eh = (EmptyHandler)Delegate.CreateDelegate(typeof(EmptyHandler), this, mi.Name); pw = new ProcessWorker(this, mi); signals[name].Changed += new EmptyHandler(pw.Run); } else { //If the signal was not found call an error sim.SendError(this.GetType() + ": Senstitivity Error: Could not find signal " + name + " that is needed by " + mi.Name); ok = false; } } } } } if (!ok) { throw new CommandException("Initialize of " + this.Name + " failed"); } InitComplete = true; }
/// <summary> /// Removes listener from signal /// </summary> /// <param name="c"></param> internal override void RemoveListener(SignalBase c) { ((Signal <T>)c).Changed -= delegate { this.Value = ((Signal <T>)c).Value; }; }
/// <summary> /// Remove trace on a signal /// </summary> /// <param name="sig">Signal to remove</param> public void UnTrace(SignalBase sig) { this.signalsToWrite.Remove(sig); }
/// <summary> /// Trace a signal /// </summary> /// <param name="sig">Signal to trace</param> public void Trace(SignalBase sig) { this.signalsToWrite.Add(sig); }
/// <summary> /// Writes signal changes to the file /// </summary> /// <param name="cs">Signals</param> /// <param name="time">Time</param> public void WriteSignals(List <SystemDotNet.SignalBase> cs, long time) { //Reset indexes for asci array i1 = i2 = i3 = 0; //Holds output StringBuilder sb = new StringBuilder(); //Holds label string clabel = ""; //Prev holds previous value. This checks that prev has the right length if (cs.Count != prev.Length) { prev = new string[cs.Count]; } //Foreach signal for (int i = 0; i < cs.Count; i++) { //Get labe. Note that if the number of signals changes between WriteNames //WriteSignals the label will be wrong. clabel = GetLabel(); //Get signal SignalBase c = cs[i]; //Check signal type if (c is Signal <bool> ) { //If it is bool; convert to string (0 or 1) and check if it has changed. If it has changed append it to the string builder bool b = ((Signal <bool>)c).Read(); string sbool = "0"; if (b) { sbool = "1"; } if (prev[i] != sbool) { sb.Append(sbool + clabel + '\n'); } prev[i] = sbool; } else if (c is SignalCollection <bool> ) { //If it is bool[]; convert to string (i.e 00010) and check if it has changed. If it has changed append it to the string builder string val; SignalCollection <bool> .Convert(((SignalCollection <bool>)c).Read(), out val); if (prev[i] != val) { sb.Append("b" + val + " " + clabel + '\n'); } prev[i] = val; } else if (c is SignalCollection <ulong> ) { SignalCollection <ulong> sc = c as SignalCollection <ulong>; for (int j = 0; j < sc.Count; j++) { BitVectorUnsigned bc = new BitVectorUnsigned(64); bc.Value = sc[j].Value; string val = ((BitVectorUnsigned)bc).ToBinaryString(); if (prev[i] != val) { sb.Append("b" + val + " " + GetLabel() + '\n'); } prev[i] = val; } // //If it is bool[]; convert to string (i.e 00010) and check if it has changed. If it has changed append it to the string builder // string val; // BitVectorUnsigned bc = new BitVectorUnsigned(); // bc.Value = // SignalCollection<bool>.Convert(((SignalCollection<bool>)c).Read(), out val); // // if (prev[i] != val) // sb.Append("b" + val + " " + clabel + '\n'); // prev[i] = val; } else if (c is BitVectorUnsigned) { string val = ((BitVectorUnsigned)c).ToBinaryString(); if (prev[i] != val) { sb.Append("b" + val + " " + clabel + '\n'); } prev[i] = val; } else if (c is Signal <Enum> ) { //If it is enum; convert to string (i.e Add) and check if it has changed. If it has changed append it to the string builder string senum = ((Signal <Enum>)c).Read().ToString(); if (prev[i] != senum) { sb.Append("s" + senum + " " + clabel + '\n'); } prev[i] = senum; } else if (c is Signal <double> ) { //If it is double; convert to string (i.e 0.1) and check if it has changed. If it has changed append it to the string builder string sreal = ((Signal <double>)c).Read().ToString(); if (prev[i] != sreal) { sb.Append("r" + sreal + " " + clabel + '\n'); } prev[i] = sreal; } else if (c is SignalCollection <double> ) { StringBuilder sb1 = new StringBuilder(); SignalCollection <double> sc = c as SignalCollection <double>; sb1.Append("r" + sc[0].Read().ToString() + " " + clabel + '\n'); for (int j = 1; j < sc.Count; j++) { sb1.Append("r" + sc[j].Read().ToString() + " " + GetLabel() + '\n'); } string screal = sb1.ToString(); if (prev[i] != screal) { sb.Append(screal); } prev[i] = screal; // }else if (c is SignalCollection<ulong>){ // foreach(Signal<ulong> in } else { //If it is otherwise; convert to string and check if it has changed. If it has changed append it to the string builder. string sobj = c.ToString(); if (prev[i] != sobj) { sb.Append("r" + sobj + " " + clabel + '\n'); } prev[i] = sobj; } } //If any signals changed write them to the file if (sb.ToString().Length > 0) { filewriter.WriteLine("#" + time); filewriter.Write(sb.ToString()); filewriter.WriteLine(); } }