예제 #1
0
        private static void ProcessPortsAndSetSubnets(SimulationModel.Key key, Subnet net)
        {
            List <Port> readers = new List <Port>();
            List <Port> drivers = new List <Port>();

            foreach (Node node in net.nodes)
            {
                node.SetSubnet(key, net);
                Port port = node as Port;
                if (port != null)
                {
                    if (port.IsInput)
                    {
                        readers.Add(port);
                    }
                    if (port.IsOutput)
                    {
                        drivers.Add(port);
                    }
                }
            }
            readers.TrimExcess();
            drivers.TrimExcess();
            net.readers = readers;
            net.drivers = drivers;
        }
예제 #2
0
        public void Step(SimulationModel.Key key, ISimulationAccess access)
        {
            long now = curTime + 1;

            curTime = now;
            if (Debug)
            {
                Console.WriteLine("step simulation {0}", now);
            }

            ClearDirty(key, access);

            while (events.Count > 0 && events.Peek().when == now)
            {
                SetEvent evnt = events.Dequeue();
                Port     p    = evnt.port;
                Value    cur  = p.GetDrivenValue(key);
                if (Debug)
                {
                    Console.WriteLine("  {0}: drive {1} onto {2}, mark {3}", evnt.when, evnt.value, evnt.port, p.Subnet);
                }
                if (!cur.Equals(evnt.value))
                {
                    p.SetDrivenValue(key, evnt.value);
                    dirtyNets.Add(p.Subnet);
                }
            }

            ClearDirty(key, access);

            anyDirty = events.Count > 0 || dirtyNets.Count > 0 || dirtyInstances.Count > 0;
        }
예제 #3
0
 public void SetValue(SimulationModel.Key key, Value value)
 {
     if (key == null)
     {
         throw new ArgumentException("key needed");
     }
     this.value = value;
 }
예제 #4
0
 public Value GetValue(SimulationModel.Key key)
 {
     if (key == null)
     {
         throw new ArgumentException("key needed");
     }
     return(value);
 }
예제 #5
0
        private void ClearDirty(SimulationModel.Key key, ISimulationAccess access)
        {
            HashSet <Subnet>   nets      = dirtyNets;
            HashSet <Instance> instances = dirtyInstances;

            if (nets != null && nets.Count > 0)
            {
                dirtyNets = new HashSet <Subnet>();
                foreach (Subnet net in nets)
                {
                    if (Debug)
                    {
                        Console.Write("  net {0} /", net);
                    }
                    Value v = null;
                    foreach (Port p in net.Drivers)
                    {
                        Value u = p.GetDrivenValue(key);
                        if (Debug)
                        {
                            Console.Write("{0}/", u);
                        }
                        v = v == null ? u : v.Resolve(u);
                    }
                    if (Debug)
                    {
                        Console.WriteLine("-> {0}", v);
                    }
                    if (v == null)
                    {
                        int w = net.Width;
                        v = Value.Create(Value.U, w == 0 ? 1 : w);
                    }
                    net.SetValue(key, v);
                    foreach (Port p in net.Readers)
                    {
                        instances.Add(p.Instance);
                    }
                }
            }

            if (instances != null && instances.Count > 0)
            {
                InstanceEvent evnt   = new InstanceEvent(InstanceEvent.Types.InstanceDirty);
                InstanceState iState = new InstanceState(access, null);
                dirtyInstances = new HashSet <Instance>();
                foreach (Instance instance in instances)
                {
                    if (Debug)
                    {
                        Console.WriteLine("  propagate instance {0}", instance);
                    }
                    iState.Instance = instance;
                    instance.HandleEvent(evnt, iState);
                }
            }
        }
예제 #6
0
 public void SetTempSubnet(SimulationModel.Key key, Subnet value)
 {
     if (key == null)
     {
         throw new InvalidOperationException("need key");
     }
     else
     {
         this.TempSubnet = value;
     }
 }
예제 #7
0
 public void AddLink(SimulationModel.Key key, Link value)
 {
     if (key == null)
     {
         throw new InvalidOperationException("need key");
     }
     else
     {
         List <Link> links = this.links;
         if (links == EmptyLinks)
         {
             links          = new List <Link>();
             this.links     = links;
             this.linksView = links.AsReadOnly();
         }
         links.Add(value);
     }
 }
예제 #8
0
 public void AddToUseCount(SimulationModel.Key key, int delta)
 {
     if (key == null)
     {
         throw new InvalidOperationException("need key");
     }
     else
     {
         int newVal = baseUseCount + delta;
         if (newVal < 0)
         {
             baseUseCount = 0;
             throw new ArgumentException("count cannot go negative");
         }
         else
         {
             baseUseCount = newVal;
         }
     }
 }
예제 #9
0
 public bool RemoveLink(SimulationModel.Key key, Link value)
 {
     if (key == null)
     {
         throw new InvalidOperationException("need key");
     }
     else
     {
         List <Link> links   = this.links;
         bool        removed = links.Remove(value);
         if (removed)
         {
             if (links.Count == 0)
             {
                 this.links     = EmptyLinks;
                 this.linksView = EmptyLinksView;
             }
         }
         return(removed);
     }
 }
예제 #10
0
        private static Subnet FindSubnetFrom(SimulationModel.Key key, Node start)
        {
            int id = lastIdAllocated + 1;

            lastIdAllocated = id;
            Subnet      net   = new Subnet(id);
            List <Node> found = net.nodes;

            start.SetTempSubnet(key, net);
            found.Add(start);
            for (int i = 0; i < found.Count; i++)
            {
                Node u = found[i];
                foreach (Node v in u.Neighbors)
                {
                    if (v.TempSubnet == null)
                    {
                        v.SetTempSubnet(key, net);
                        found.Add(v);
                    }
                }
            }
            return(net);
        }
예제 #11
0
        public static List <Subnet> UpdateNets(SimulationModel.Key key, ISimulationAccess model, List <Subnet> oldNets)
        {
            if (key == null)
            {
                throw new ArgumentException("key needed");
            }

            if (Debug)
            {
                Console.WriteLine("Update subnets");
            }

            foreach (Node node in model.Nodes)
            {
                node.SetTempSubnet(key, null);
            }

            List <Subnet> sortedNets = new List <Subnet>(oldNets);

            sortedNets.Sort((n0, n1) => n1.nodes.Count - n0.nodes.Count);
            List <Subnet> allNewNets = new List <Subnet>();

            foreach (Subnet oldNet in sortedNets)
            {
                List <Subnet> newNets     = new List <Subnet>();
                int           largestSize = 0;
                Subnet        largestNet  = null;
                foreach (Node node in oldNet.nodes)
                {
                    if (node.TempSubnet == null)
                    {
                        Subnet net = FindSubnetFrom(key, node);
                        newNets.Add(net);
                        int netSize = net.nodes.Count;
                        if (netSize > largestSize)
                        {
                            largestSize = netSize;
                            largestNet  = net;
                        }
                    }
                }
                if (largestNet == null)
                {
                    // no nets identified, so nothing to do
                    if (Debug)
                    {
                        Console.WriteLine("   {0} deleted", oldNet);
                    }
                }
                else if (newNets.Count == 1 && EqualsListsShallow(oldNet.nodes, newNets[0].nodes))
                {
                    if (Debug)
                    {
                        Console.WriteLine("   {0} unchanged: drivers {1} readers {2} nodes {3}", oldNet,
                                          ",".JoinObjectStrings(oldNet.drivers), ",".JoinObjectStrings(oldNet.readers),
                                          ",".JoinObjectStrings(oldNet.nodes));
                    }
                    allNewNets.Add(oldNet); // just keep the old net, since they're identical
                }
                else
                {
                    oldNet.nodes = largestNet.nodes;
                    foreach (Subnet rawNet in newNets)
                    {
                        Subnet newNet = rawNet == largestNet ? oldNet : rawNet;
                        allNewNets.Add(newNet);
                        ProcessPortsAndSetSubnets(key, newNet);
                        key.Engine.AddDirtyNet(newNet);
                        if (Debug)
                        {
                            Console.WriteLine("   {0} to {1}: drivers {2} readers {3} nodes {4}", oldNet, newNet,
                                              ",".JoinObjectStrings(newNet.drivers), ",".JoinObjectStrings(newNet.readers),
                                              ",".JoinObjectStrings(newNet.nodes));
                        }
                    }
                }
            }
            foreach (Node node in model.Nodes)
            {
                if (node.TempSubnet == null)
                {
                    Subnet net = FindSubnetFrom(key, node);
                    allNewNets.Add(net);
                    ProcessPortsAndSetSubnets(key, net);
                    if (Debug)
                    {
                        Console.WriteLine("dflt net {0}: drivers {1}, readers {2}, nodes {3}", net,
                                          ",".JoinObjectStrings(net.drivers), ",".JoinObjectStrings(net.readers),
                                          ",".JoinObjectStrings(net.nodes));
                    }
                }
            }

            return(allNewNets);
        }