示例#1
0
        internal static void VisitSimCmd(VCDLexer lexer, IDToVarDef idToVariable, SimPass pass, BitAllocator bitAlloc)
        {
            ReadOnlyMemory <byte> declWordMem = lexer.NextWordAsMem();
            ReadOnlySpan <byte>   declWord    = declWordMem.Span;

            ReadOnlySpan <byte> endToken      = new byte[] { (byte)'$', (byte)'e', (byte)'n', (byte)'d' };
            ReadOnlySpan <byte> commentToken  = new byte[] { (byte)'$', (byte)'c', (byte)'o', (byte)'m', (byte)'m', (byte)'e', (byte)'n', (byte)'t' };
            ReadOnlySpan <byte> dumpAllToken  = new byte[] { (byte)'$', (byte)'d', (byte)'u', (byte)'m', (byte)'p', (byte)'a', (byte)'l', (byte)'l' };
            ReadOnlySpan <byte> dumpOffToken  = new byte[] { (byte)'$', (byte)'d', (byte)'u', (byte)'m', (byte)'p', (byte)'o', (byte)'f', (byte)'f' };
            ReadOnlySpan <byte> dumpOnToken   = new byte[] { (byte)'$', (byte)'d', (byte)'u', (byte)'m', (byte)'p', (byte)'o', (byte)'n' };
            ReadOnlySpan <byte> dumpVarsToken = new byte[] { (byte)'$', (byte)'d', (byte)'u', (byte)'m', (byte)'p', (byte)'v', (byte)'a', (byte)'r', (byte)'s' };
            ReadOnlySpan <byte> hashtagToken  = new byte[] { (byte)'#' };

            //It may be the case that it's first discovered now that
            // the end of the file has been reached.
            if (declWord.Length == 0)
            {
                if (lexer.IsWordsRemaining())
                {
                    throw new Exception("Invalid simulation command.");
                }

                return;
            }

            if (declWord.SequenceEqual(commentToken))
            {
                string text = lexer.NextUntil(endToken).ToCharString();

                lexer.ExpectNextWord(endToken);
                pass.SimCmd = new Comment(text);
            }
            else if (declWord.SequenceEqual(dumpAllToken))
            {
                pass.SimCmd = new DumpAll(VisitValueChangeStream(lexer, idToVariable, pass, bitAlloc));
            }
            else if (declWord.SequenceEqual(dumpOffToken))
            {
                pass.SimCmd = new DumpOff(VisitValueChangeStream(lexer, idToVariable, pass, bitAlloc));
            }
            else if (declWord.SequenceEqual(dumpOnToken))
            {
                pass.SimCmd = new DumpOn(VisitValueChangeStream(lexer, idToVariable, pass, bitAlloc));
            }
            else if (declWord.SequenceEqual(dumpVarsToken))
            {
                pass.SimCmd = new DumpVars(VisitValueChangeStream(lexer, idToVariable, pass, bitAlloc));
            }
            else if (declWord.StartsWith(hashtagToken))
            {
                pass.SimCmd = VisitSimTime(declWord);
            }
            else
            {
                VisitValueChange(lexer, declWordMem, idToVariable, pass, bitAlloc);
            }
        }
示例#2
0
        public VCDTimeline(VCD vcd)
        {
            this.TimeScale = vcd.Time;

            var          simCommands = vcd.GetSimulationCommands();
            SimPass      firstCmd    = simCommands.First();
            CircuitState segmentStartState;

            if (firstCmd.SimCmd is DumpVars initDump)
            {
                segmentStartState = new CircuitState(initDump);
            }
            else
            {
                segmentStartState = new CircuitState(vcd.Variables.ToList());
                simCommands       = simCommands.Prepend(firstCmd);
            }
            CircuitState followState = segmentStartState.Copy();

            ulong                  startTime            = 0;
            const int              maxChangesPerSegment = 100_000;
            List <BinaryVarValue>  binChanges           = new List <BinaryVarValue>(maxChangesPerSegment);
            List <TimeStepChanges> stepChanges          = new List <TimeStepChanges>();
            int currTimeStepStart  = 0;
            int currTimeStepLength = 0;


            foreach (var simCmd in simCommands)
            {
                if (simCmd.SimCmd is SimTime time)
                {
                    if (currTimeStepLength > 0)
                    {
                        StateCount++;
                        TimeStepChanges timeStep = new TimeStepChanges(startTime, currTimeStepStart, currTimeStepLength);
                        currTimeStepStart += currTimeStepLength;
                        currTimeStepLength = 0;

                        stepChanges.Add(timeStep);

                        //If segment is full then store the segment and
                        //prepare for the next segment
                        if (binChanges.Count > maxChangesPerSegment)
                        {
                            TimeSpan tSpan = new TimeSpan(stepChanges.First().Time, time.Time);
                            SegmentChanges.Add(new TimeSegmentChanges(tSpan, segmentStartState, binChanges.ToArray(), stepChanges));
                            currTimeStepStart  = 0;
                            currTimeStepLength = 0;

                            segmentStartState = followState;
                            followState       = segmentStartState.Copy();

                            binChanges.Clear();
                            stepChanges = new List <TimeStepChanges>();
                        }
                    }
                    startTime = time.Time;
                }
                else if (simCmd.BinValue.HasValue)
                {
                    followState.AddChange(simCmd.BinValue.Value);
                    binChanges.Add(simCmd.BinValue.Value);
                    currTimeStepLength++;
                }
            }

            //Add last segment if it's not empty.
            //Segment isn't added by above loop if the vcd file doesn't
            //end with a simulation time command.
            if (currTimeStepLength > 0)
            {
                stepChanges.Add(new TimeStepChanges(startTime, currTimeStepStart, currTimeStepLength));
            }
            if (stepChanges.Count > 0)
            {
                TimeSpan tSpan = new TimeSpan(stepChanges.First().Time, stepChanges.Last().Time + 1);
                SegmentChanges.Add(new TimeSegmentChanges(tSpan, segmentStartState, binChanges.ToArray(), stepChanges));
            }

            this.TimeInterval = new TimeSpan(SegmentChanges.First().TimeInterval.StartInclusive, SegmentChanges.Last().TimeInterval.EndExclusive);
        }
示例#3
0
        internal static void VisitScalarValueChange(ReadOnlyMemory <byte> text, IDToVarDef idToVariable, SimPass pass, BitAllocator bitAlloc)
        {
            UnsafeMemory <BitState> bits = bitAlloc.GetBits(1);
            BitState bit = ToBitState(text.Span[0]);
            var      id  = text.Slice(1);

            bits.Span[0] = bit;

            if (idToVariable.TryGetValue(id, out List <VarDef>?variable))
            {
                pass.BinValue = new BinaryVarValue(bits, variable, ((int)bit & 0b10) == 0);
            }
            else
            {
                throw new Exception($"Unknown variable identifier: {id}");
            }
        }
示例#4
0
        internal static void VisitRealVectorValueChange(VCDLexer lexer, ReadOnlySpan <byte> valueText, IDToVarDef idToVariable, SimPass pass, BitAllocator bitAlloc)
        {
            Span <char> chars = stackalloc char[valueText.Length];

            valueText.CopyToCharArray(chars);

            double value = double.Parse(chars, NumberStyles.Float, CultureInfo.InvariantCulture);
            var    id    = lexer.NextWordAsMem();

            if (idToVariable.TryGetValue(id, out List <VarDef>?variable))
            {
                pass.RealValue = new RealVarValue(value, variable);
            }
            else
            {
                throw new Exception($"Unknown variable identifier: {id}");
            }
        }
示例#5
0
        internal static void VisitBinaryVectorValueChange(VCDLexer lexer, ReadOnlySpan <byte> valueText, IDToVarDef idToVariable, SimPass pass, BitAllocator bitAlloc)
        {
            (UnsafeMemory <BitState> bits, bool isValidBinary) = ToBitStates(valueText, bitAlloc);
            var id = lexer.NextWordAsMem();

            if (idToVariable.TryGetValue(id, out List <VarDef>?variables))
            {
                pass.BinValue = new BinaryVarValue(bits, variables, isValidBinary);
            }
            else
            {
                throw new Exception($"Unknown variable identifier: {id}");
            }
        }
示例#6
0
        internal static void VisitValueChange(VCDLexer lexer, ReadOnlyMemory <byte> text, IDToVarDef idToVariable, SimPass pass, BitAllocator bitAlloc)
        {
            if (text.Length < 2)
            {
                throw new Exception($"Invalid value change: {text.ToString()}");
            }

            ReadOnlySpan <byte> textSpan = text.Span;

            if (textSpan[0] == 'b' || textSpan[0] == 'B')
            {
                VisitBinaryVectorValueChange(lexer, textSpan.Slice(1), idToVariable, pass, bitAlloc);
            }
            else if (textSpan[0] == 'r' || textSpan[0] == 'R')
            {
                VisitRealVectorValueChange(lexer, textSpan.Slice(1), idToVariable, pass, bitAlloc);
            }
            else
            {
                VisitScalarValueChange(text, idToVariable, pass, bitAlloc);
            }
        }
示例#7
0
        internal static List <VarValue> VisitValueChangeStream(VCDLexer lexer, IDToVarDef idToVariable, SimPass pass, BitAllocator bitAlloc)
        {
            List <VarValue> changes = new List <VarValue>();

            while (!lexer.IsEmpty())
            {
                ReadOnlyMemory <byte> text     = lexer.NextWordAsMem();
                ReadOnlySpan <byte>   endToken = new byte[] { (byte)'$', (byte)'e', (byte)'n', (byte)'d' };
                if (text.Span.SequenceEqual(endToken))
                {
                    break;
                }

                VisitValueChange(lexer, text, idToVariable, pass, bitAlloc);
                if (pass.BinValue.HasValue)
                {
                    changes.Add(pass.BinValue);
                }
                else if (pass.RealValue.HasValue)
                {
                    changes.Add(pass.RealValue);
                }
                else
                {
                    throw new Exception("Expected to read a value change but found none.");
                }
            }

            pass.Reset();
            return(changes);
        }