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); }
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); } }
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}"); } }
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}"); } }