예제 #1
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);
        }
예제 #2
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);
            }
        }
예제 #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 (List <IDeclCmd> declarations, IDToVarDef idToVariable) VisitDeclCmdStream(VCDLexer lexer)
        {
            List <IDeclCmd> declarations = new List <IDeclCmd>();
            IDToVarDef      idToVariable = new IDToVarDef();
            Stack <Scope>   scopes       = new Stack <Scope>();

            while (!lexer.IsEmpty())
            {
                IDeclCmd?decl = VisitDeclCmd(lexer, idToVariable, scopes);
                if (decl == null)
                {
                    break;
                }
                declarations.Add(decl);
            }

            if (scopes.Count != 0)
            {
                throw new Exception("Not all declaration scopes were closed.");
            }

            return(declarations, idToVariable);
        }
예제 #5
0
        internal static IDeclCmd?VisitDeclCmd(VCDLexer lexer, IDToVarDef idToVariable, Stack <Scope> scopes)
        {
            ReadOnlySpan <byte> declWord = lexer.NextWord();
            Span <char>         chars    = stackalloc char[declWord.Length];

            declWord.CopyToCharArray(chars);

            ReadOnlySpan <byte> endToken   = new byte[] { (byte)'$', (byte)'e', (byte)'n', (byte)'d' };
            ReadOnlySpan <byte> dollarSign = new byte[] { (byte)'$' };

            if (chars.SequenceEqual("$comment"))
            {
                string text = lexer.NextUntil(endToken).ToCharString();

                lexer.ExpectNextWord(endToken);
                return(new Comment(text));
            }
            else if (chars.SequenceEqual("$date"))
            {
                string text = lexer.NextUntil(endToken).ToCharString();

                lexer.ExpectNextWord(endToken);
                return(new Date(text));
            }
            else if (chars.SequenceEqual("$scope"))
            {
                ScopeType type = VisitScopeType(lexer);
                string    id   = lexer.NextWord().ToCharString();

                Scope scope = new Scope(type, id);
                scopes.Push(scope);

                lexer.ExpectNextWord(endToken);
                return(scope);
            }
            else if (chars.SequenceEqual("$timescale"))
            {
                int      scale = VisitTimeNumber(lexer);
                TimeUnit unit  = VisitTimeUnit(lexer);

                lexer.ExpectNextWord(endToken);
                return(new TimeScale(scale, unit));
            }
            else if (chars.SequenceEqual("$upscope"))
            {
                scopes.Pop();

                lexer.ExpectNextWord(endToken);
                return(new UpScope());
            }
            else if (chars.SequenceEqual("$var"))
            {
                VarType type      = VisitVarType(lexer);
                int     size      = VisitSize(lexer);
                string  id        = lexer.NextWord().ToCharString();
                string  reference = lexer.NextWord().ToCharString();

                VarDef variable = new VarDef(type, size, id, reference, scopes.Reverse().ToArray());
                idToVariable.AddVariable(variable);

                //Skip this stuff because it's not currently supported
                char nextChar = lexer.PeekNextChar();
                if (nextChar == '[')
                {
                    ReadOnlySpan <byte> endBracket = new byte[] { (byte)']' };
                    lexer.NextUntil(endBracket);
                    lexer.SkipChar();
                }

                lexer.ExpectNextWord(endToken);
                return(variable);
            }
            else if (chars.SequenceEqual("$version"))
            {
                string versionTxt       = lexer.NextUntil(dollarSign).ToCharString();
                string systemTaskString = string.Empty;

                ReadOnlySpan <byte> systemTask = lexer.PeekNextWord().Span;
                if (systemTask.StartsWith(dollarSign) && !systemTask.SequenceEqual(endToken))
                {
                    lexer.SkipWord(systemTask);
                    systemTaskString = systemTask.ToCharString();
                }

                lexer.ExpectNextWord(endToken);
                return(new Version(versionTxt, systemTaskString));
            }
            else if (chars.SequenceEqual("$enddefinitions"))
            {
                lexer.ExpectNextWord(endToken);
                return(null);
            }
            else
            {
                throw new Exception($"Invalid declaration command: {declWord.ToCharString()}\nBuffer: {lexer.BufferToString()}");
            }
        }
예제 #6
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}");
            }
        }
예제 #7
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}");
            }
        }
예제 #8
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);
            }
        }